比较提交

..
10 次代码提交
修改 109 个文件,包含 1608021 行新增916 行删除
+2
查看文件
@@ -251,3 +251,5 @@ ModelManifest.xml
/tem3dfdtd/PostProcessFileList.dat /tem3dfdtd/PostProcessFileList.dat
/tem3dfdtd/HzCoordinate.dat /tem3dfdtd/HzCoordinate.dat
/tem3dfdtd/Ground-Line=081.dat /tem3dfdtd/Ground-Line=081.dat
tem3dfdtd/fort.5141
.vscode/settings.json
+634 -70
查看文件
@@ -1,127 +1,691 @@
木兰宽松许可证, 第2版 tem3dfdtd is a 3D forward modeling program of transient electromagnetic.
木兰宽松许可证, 第2版 Copyright (C) 2026 Laboratory of Earth Electromagnetic Exploration, Shandong University
2020年1月 http://license.coscl.org.cn/MulanPSL2
This program is free software: you can redistribute it and/or modify
it under the terms of the GNU General Public License as published by
the Free Software Foundation, either version 3 of the License, or
(at your option) any later version.
您对“软件”的复制、使用、修改及分发受木兰宽松许可证,第2版(“本许可证”)的如下条款的约束: This program is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
GNU General Public License for more details.
0. 定义 You should have received a copy of the GNU General Public License Version 3
along with this program. If not, see <https://www.gnu.org/licenses/>.
“软件”是指由“贡献”构成的许可在“本许可证”下的程序和相关文档的集合。 GNU GENERAL PUBLIC LICENSE
Version 3, 29 June 2007
“贡献”是指由任一“贡献者”许可在“本许可证”下的受版权法保护的作品。 Copyright (C) 2007 Free Software Foundation, Inc. <https://fsf.org/>
Everyone is permitted to copy and distribute verbatim copies
of this license document, but changing it is not allowed.
“贡献者”是指将受版权法保护的作品许可在“本许可证”下的自然人或“法人实体”。 Preamble
“法人实体”是指提交贡献的机构及其“关联实体”。 The GNU General Public License is a free, copyleft license for
software and other kinds of works.
“关联实体”是指,对“本许可证”下的行为方而言,控制、受控制或与其共同受控制的机构,此处的控制是指有受控方或共同受控方至少50%直接或间接的投票权、资金或其他有价证券。 The licenses for most software and other practical works are designed
to take away your freedom to share and change the works. By contrast,
the GNU General Public License is intended to guarantee your freedom to
share and change all versions of a program--to make sure it remains free
software for all its users. We, the Free Software Foundation, use the
GNU General Public License for most of our software; it applies also to
any other work released this way by its authors. You can apply it to
your programs, too.
1. 授予版权许可 When we speak of free software, we are referring to freedom, not
price. Our General Public Licenses are designed to make sure that you
have the freedom to distribute copies of free software (and charge for
them if you wish), that you receive source code or can get it if you
want it, that you can change the software or use pieces of it in new
free programs, and that you know you can do these things.
每个“贡献者”根据“本许可证”授予您永久性的、全球性的、免费的、非独占的、不可撤销的版权许可,您可以复制、使用、修改、分发其“贡献”,不论修改与否。 To protect your rights, we need to prevent others from denying you
these rights or asking you to surrender the rights. Therefore, you have
certain responsibilities if you distribute copies of the software, or if
you modify it: responsibilities to respect the freedom of others.
2. 授予专利许可 For example, if you distribute copies of such a program, whether
gratis or for a fee, you must pass on to the recipients the same
freedoms that you received. You must make sure that they, too, receive
or can get the source code. And you must show them these terms so they
know their rights.
每个“贡献者”根据“本许可证”授予您永久性的、全球性的、免费的、非独占的、不可撤销的(根据本条规定撤销除外)专利许可,供您制造、委托制造、使用、许诺销售、销售、进口其“贡献”或以其他方式转移其“贡献”。前述专利许可仅限于“贡献者”现在或将来拥有或控制的其“贡献”本身或其“贡献”与许可“贡献”时的“软件”结合而将必然会侵犯的专利权利要求,不包括对“贡献”的修改或包含“贡献”的其他结合。如果您或您的“关联实体”直接或间接地,就“软件”或其中的“贡献”对任何人发起专利侵权诉讼(包括反诉或交叉诉讼)或其他专利维权行动,指控其侵犯专利权,则“本许可证”授予您对“软件”的专利许可自您提起诉讼或发起维权行动之日终止。 Developers that use the GNU GPL protect your rights with two steps:
(1) assert copyright on the software, and (2) offer you this License
giving you legal permission to copy, distribute and/or modify it.
3. 无商标许可 For the developers' and authors' protection, the GPL clearly explains
that there is no warranty for this free software. For both users' and
authors' sake, the GPL requires that modified versions be marked as
changed, so that their problems will not be attributed erroneously to
authors of previous versions.
“本许可证”不提供对“贡献者”的商品名称、商标、服务标志或产品名称的商标许可,但您为满足第4条规定的声明义务而必须使用除外。 Some devices are designed to deny users access to install or run
modified versions of the software inside them, although the manufacturer
can do so. This is fundamentally incompatible with the aim of
protecting users' freedom to change the software. The systematic
pattern of such abuse occurs in the area of products for individuals to
use, which is precisely where it is most unacceptable. Therefore, we
have designed this version of the GPL to prohibit the practice for those
products. If such problems arise substantially in other domains, we
stand ready to extend this provision to those domains in future versions
of the GPL, as needed to protect the freedom of users.
4. 分发限制 Finally, every program is threatened constantly by software patents.
States should not allow patents to restrict development and use of
software on general-purpose computers, but in those that do, we wish to
avoid the special danger that patents applied to a free program could
make it effectively proprietary. To prevent this, the GPL assures that
patents cannot be used to render the program non-free.
您可以在任何媒介中将“软件”以源程序形式或可执行形式重新分发,不论修改与否,但您必须向接收者提供“本许可证”的副本,并保留“软件”中的版权、商标、专利及免责声明。 The precise terms and conditions for copying, distribution and
modification follow.
5. 免责声明与责任限制 TERMS AND CONDITIONS
“软件”及其中的“贡献”在提供时不带任何明示或默示的担保。在任何情况下,“贡献者”或版权所有者不对任何人因使用“软件”或其中的“贡献”而引发的任何直接或间接损失承担责任,不论因何种原因导致或者基于何种法律理论,即使其曾被建议有此种损失的可能性。 0. Definitions.
6. 语言 "This License" refers to version 3 of the GNU General Public License.
“本许可证”以中英文双语表述,中英文版本具有同等法律效力。如果中英文版本存在任何冲突不一致,以中文版为准。
条款结束 "Copyright" also means copyright-like laws that apply to other kinds of
works, such as semiconductor masks.
如何将木兰宽松许可证,第2版,应用到您的软件 "The Program" refers to any copyrightable work licensed under this
License. Each licensee is addressed as "you". "Licensees" and
"recipients" may be individuals or organizations.
如果您希望将木兰宽松许可证,第2版,应用到您的新软件,为了方便接收者查阅,建议您完成如下三步: To "modify" a work means to copy from or adapt all or part of the work
in a fashion requiring copyright permission, other than the making of an
exact copy. The resulting work is called a "modified version" of the
earlier work or a work "based on" the earlier work.
1, 请您补充如下声明中的空白,包括软件名、软件的首次发表年份以及您作为版权人的名字; A "covered work" means either the unmodified Program or a work based
on the Program.
2, 请您在软件包的一级目录下创建以“LICENSE”为名的文件,将整个许可证文本放入该文件中; To "propagate" a work means to do anything with it that, without
permission, would make you directly or secondarily liable for
infringement under applicable copyright law, except executing it on a
computer or modifying a private copy. Propagation includes copying,
distribution (with or without modification), making available to the
public, and in some countries other activities as well.
3, 请将如下声明文本放入每个源文件的头部注释中。 To "convey" a work means any kind of propagation that enables other
parties to make or receive copies. Mere interaction with a user through
a computer network, with no transfer of a copy, is not conveying.
Copyright (c) [2023] [LEEE@SDU] An interactive user interface displays "Appropriate Legal Notices"
[Software Name] is licensed under Mulan PSL v2. to the extent that it includes a convenient and prominently visible
You can use this software according to the terms and conditions of the Mulan PSL v2. feature that (1) displays an appropriate copyright notice, and (2)
You may obtain a copy of Mulan PSL v2 at: tells the user that there is no warranty for the work (except to the
http://license.coscl.org.cn/MulanPSL2 extent that warranties are provided), that licensees may convey the
THIS SOFTWARE IS PROVIDED ON AN "AS IS" BASIS, WITHOUT WARRANTIES OF ANY KIND, EITHER EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO NON-INFRINGEMENT, MERCHANTABILITY OR FIT FOR A PARTICULAR PURPOSE. work under this License, and how to view a copy of this License. If
See the Mulan PSL v2 for more details. the interface presents a list of user commands or options, such as a
menu, a prominent item in the list meets this criterion.
1. Source Code.
Mulan Permissive Software License,Version 2 The "source code" for a work means the preferred form of the work
for making modifications to it. "Object code" means any non-source
form of a work.
Mulan Permissive Software License,Version 2 (Mulan PSL v2) A "Standard Interface" means an interface that either is an official
January 2020 http://license.coscl.org.cn/MulanPSL2 standard defined by a recognized standards body, or, in the case of
interfaces specified for a particular programming language, one that
is widely used among developers working in that language.
Your reproduction, use, modification and distribution of the Software shall be subject to Mulan PSL v2 (this License) with the following terms and conditions: The "System Libraries" of an executable work include anything, other
than the work as a whole, that (a) is included in the normal form of
packaging a Major Component, but which is not part of that Major
Component, and (b) serves only to enable use of the work with that
Major Component, or to implement a Standard Interface for which an
implementation is available to the public in source code form. A
"Major Component", in this context, means a major essential component
(kernel, window system, and so on) of the specific operating system
(if any) on which the executable work runs, or a compiler used to
produce the work, or an object code interpreter used to run it.
0. Definition The "Corresponding Source" for a work in object code form means all
the source code needed to generate, install, and (for an executable
work) run the object code and to modify the work, including scripts to
control those activities. However, it does not include the work's
System Libraries, or general-purpose tools or generally available free
programs which are used unmodified in performing those activities but
which are not part of the work. For example, Corresponding Source
includes interface definition files associated with source files for
the work, and the source code for shared libraries and dynamically
linked subprograms that the work is specifically designed to require,
such as by intimate data communication or control flow between those
subprograms and other parts of the work.
Software means the program and related documents which are licensed under this License and comprise all Contribution(s). The Corresponding Source need not include anything that users
can regenerate automatically from other parts of the Corresponding
Source.
Contribution means the copyrightable work licensed by a particular Contributor under this License. The Corresponding Source for a work in source code form is that
same work.
Contributor means the Individual or Legal Entity who licenses its copyrightable work under this License. 2. Basic Permissions.
Legal Entity means the entity making a Contribution and all its Affiliates. All rights granted under this License are granted for the term of
copyright on the Program, and are irrevocable provided the stated
conditions are met. This License explicitly affirms your unlimited
permission to run the unmodified Program. The output from running a
covered work is covered by this License only if the output, given its
content, constitutes a covered work. This License acknowledges your
rights of fair use or other equivalent, as provided by copyright law.
Affiliates means entities that control, are controlled by, or are under common control with the acting entity under this License, ‘control’ means direct or indirect ownership of at least fifty percent (50%) of the voting power, capital or other securities of controlled or commonly controlled entity. You may make, run and propagate covered works that you do not
convey, without conditions so long as your license otherwise remains
in force. You may convey covered works to others for the sole purpose
of having them make modifications exclusively for you, or provide you
with facilities for running those works, provided that you comply with
the terms of this License in conveying all material for which you do
not control copyright. Those thus making or running the covered works
for you must do so exclusively on your behalf, under your direction
and control, on terms that prohibit them from making any copies of
your copyrighted material outside their relationship with you.
1. Grant of Copyright License Conveying under any other circumstances is permitted solely under
the conditions stated below. Sublicensing is not allowed; section 10
makes it unnecessary.
Subject to the terms and conditions of this License, each Contributor hereby grants to you a perpetual, worldwide, royalty-free, non-exclusive, irrevocable copyright license to reproduce, use, modify, or distribute its Contribution, with modification or not. 3. Protecting Users' Legal Rights From Anti-Circumvention Law.
2. Grant of Patent License No covered work shall be deemed part of an effective technological
measure under any applicable law fulfilling obligations under article
11 of the WIPO copyright treaty adopted on 20 December 1996, or
similar laws prohibiting or restricting circumvention of such
measures.
Subject to the terms and conditions of this License, each Contributor hereby grants to you a perpetual, worldwide, royalty-free, non-exclusive, irrevocable (except for revocation under this Section) patent license to make, have made, use, offer for sale, sell, import or otherwise transfer its Contribution, where such patent license is only limited to the patent claims owned or controlled by such Contributor now or in future which will be necessarily infringed by its Contribution alone, or by combination of the Contribution with the Software to which the Contribution was contributed. The patent license shall not apply to any modification of the Contribution, and any other combination which includes the Contribution. If you or your Affiliates directly or indirectly institute patent litigation (including a cross claim or counterclaim in a litigation) or other patent enforcement activities against any individual or entity by alleging that the Software or any Contribution in it infringes patents, then any patent license granted to you under this License for the Software shall terminate as of the date such litigation or activity is filed or taken. When you convey a covered work, you waive any legal power to forbid
circumvention of technological measures to the extent such circumvention
is effected by exercising rights under this License with respect to
the covered work, and you disclaim any intention to limit operation or
modification of the work as a means of enforcing, against the work's
users, your or third parties' legal rights to forbid circumvention of
technological measures.
3. No Trademark License 4. Conveying Verbatim Copies.
No trademark license is granted to use the trade names, trademarks, service marks, or product names of Contributor, except as required to fulfill notice requirements in Section 4. You may convey verbatim copies of the Program's source code as you
receive it, in any medium, provided that you conspicuously and
appropriately publish on each copy an appropriate copyright notice;
keep intact all notices stating that this License and any
non-permissive terms added in accord with section 7 apply to the code;
keep intact all notices of the absence of any warranty; and give all
recipients a copy of this License along with the Program.
4. Distribution Restriction You may charge any price or no price for each copy that you convey,
and you may offer support or warranty protection for a fee.
You may distribute the Software in any medium with or without modification, whether in source or executable forms, provided that you provide recipients with a copy of this License and retain copyright, patent, trademark and disclaimer statements in the Software. 5. Conveying Modified Source Versions.
5. Disclaimer of Warranty and Limitation of Liability You may convey a work based on the Program, or the modifications to
produce it from the Program, in the form of source code under the
terms of section 4, provided that you also meet all of these conditions:
THE SOFTWARE AND CONTRIBUTION IN IT ARE PROVIDED WITHOUT WARRANTIES OF ANY KIND, EITHER EXPRESS OR IMPLIED. IN NO EVENT SHALL ANY CONTRIBUTOR OR COPYRIGHT HOLDER BE LIABLE TO YOU FOR ANY DAMAGES, INCLUDING, BUT NOT LIMITED TO ANY DIRECT, OR INDIRECT, SPECIAL OR CONSEQUENTIAL DAMAGES ARISING FROM YOUR USE OR INABILITY TO USE THE SOFTWARE OR THE CONTRIBUTION IN IT, NO MATTER HOW IT’S CAUSED OR BASED ON WHICH LEGAL THEORY, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGES. a) The work must carry prominent notices stating that you modified
it, and giving a relevant date.
6. Language b) The work must carry prominent notices stating that it is
released under this License and any conditions added under section
7. This requirement modifies the requirement in section 4 to
"keep intact all notices".
THIS LICENSE IS WRITTEN IN BOTH CHINESE AND ENGLISH, AND THE CHINESE VERSION AND ENGLISH VERSION SHALL HAVE THE SAME LEGAL EFFECT. IN THE CASE OF DIVERGENCE BETWEEN THE CHINESE AND ENGLISH VERSIONS, THE CHINESE VERSION SHALL PREVAIL. c) You must license the entire work, as a whole, under this
License to anyone who comes into possession of a copy. This
License will therefore apply, along with any applicable section 7
additional terms, to the whole of the work, and all its parts,
regardless of how they are packaged. This License gives no
permission to license the work in any other way, but it does not
invalidate such permission if you have separately received it.
END OF THE TERMS AND CONDITIONS d) If the work has interactive user interfaces, each must display
Appropriate Legal Notices; however, if the Program has interactive
interfaces that do not display Appropriate Legal Notices, your
work need not make them do so.
How to Apply the Mulan Permissive Software License,Version 2 (Mulan PSL v2) to Your Software A compilation of a covered work with other separate and independent
works, which are not by their nature extensions of the covered work,
and which are not combined with it such as to form a larger program,
in or on a volume of a storage or distribution medium, is called an
"aggregate" if the compilation and its resulting copyright are not
used to limit the access or legal rights of the compilation's users
beyond what the individual works permit. Inclusion of a covered work
in an aggregate does not cause this License to apply to the other
parts of the aggregate.
To apply the Mulan PSL v2 to your work, for easy identification by recipients, you are suggested to complete following three steps: 6. Conveying Non-Source Forms.
i Fill in the blanks in following statement, including insert your software name, the year of the first publication of your software, and your name identified as the copyright owner; You may convey a covered work in object code form under the terms
of sections 4 and 5, provided that you also convey the
machine-readable Corresponding Source under the terms of this License,
in one of these ways:
ii Create a file named “LICENSE” which contains the whole context of this License in the first directory of your software package; a) Convey the object code in, or embodied in, a physical product
(including a physical distribution medium), accompanied by the
Corresponding Source fixed on a durable physical medium
customarily used for software interchange.
iii Attach the statement to the appropriate annotated syntax at the beginning of each source file. b) Convey the object code in, or embodied in, a physical product
(including a physical distribution medium), accompanied by a
written offer, valid for at least three years and valid for as
long as you offer spare parts or customer support for that product
model, to give anyone who possesses the object code either (1) a
copy of the Corresponding Source for all the software in the
product that is covered by this License, on a durable physical
medium customarily used for software interchange, for a price no
more than your reasonable cost of physically performing this
conveying of source, or (2) access to copy the
Corresponding Source from a network server at no charge.
c) Convey individual copies of the object code with a copy of the
written offer to provide the Corresponding Source. This
alternative is allowed only occasionally and noncommercially, and
only if you received the object code with such an offer, in accord
with subsection 6b.
Copyright (c) [2023] [LEEE@SDU] d) Convey the object code by offering access from a designated
[Software Name] is licensed under Mulan PSL v2. place (gratis or for a charge), and offer equivalent access to the
You can use this software according to the terms and conditions of the Mulan PSL v2. Corresponding Source in the same way through the same place at no
You may obtain a copy of Mulan PSL v2 at: further charge. You need not require recipients to copy the
http://license.coscl.org.cn/MulanPSL2 Corresponding Source along with the object code. If the place to
THIS SOFTWARE IS PROVIDED ON AN "AS IS" BASIS, WITHOUT WARRANTIES OF ANY KIND, EITHER EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO NON-INFRINGEMENT, MERCHANTABILITY OR FIT FOR A PARTICULAR PURPOSE. copy the object code is a network server, the Corresponding Source
See the Mulan PSL v2 for more details. may be on a different server (operated by you or a third party)
that supports equivalent copying facilities, provided you maintain
clear directions next to the object code saying where to find the
Corresponding Source. Regardless of what server hosts the
Corresponding Source, you remain obligated to ensure that it is
available for as long as needed to satisfy these requirements.
e) Convey the object code using peer-to-peer transmission, provided
you inform other peers where the object code and Corresponding
Source of the work are being offered to the general public at no
charge under subsection 6d.
A separable portion of the object code, whose source code is excluded
from the Corresponding Source as a System Library, need not be
included in conveying the object code work.
A "User Product" is either (1) a "consumer product", which means any
tangible personal property which is normally used for personal, family,
or household purposes, or (2) anything designed or sold for incorporation
into a dwelling. In determining whether a product is a consumer product,
doubtful cases shall be resolved in favor of coverage. For a particular
product received by a particular user, "normally used" refers to a
typical or common use of that class of product, regardless of the status
of the particular user or of the way in which the particular user
actually uses, or expects or is expected to use, the product. A product
is a consumer product regardless of whether the product has substantial
commercial, industrial or non-consumer uses, unless such uses represent
the only significant mode of use of the product.
"Installation Information" for a User Product means any methods,
procedures, authorization keys, or other information required to install
and execute modified versions of a covered work in that User Product from
a modified version of its Corresponding Source. The information must
suffice to ensure that the continued functioning of the modified object
code is in no case prevented or interfered with solely because
modification has been made.
If you convey an object code work under this section in, or with, or
specifically for use in, a User Product, and the conveying occurs as
part of a transaction in which the right of possession and use of the
User Product is transferred to the recipient in perpetuity or for a
fixed term (regardless of how the transaction is characterized), the
Corresponding Source conveyed under this section must be accompanied
by the Installation Information. But this requirement does not apply
if neither you nor any third party retains the ability to install
modified object code on the User Product (for example, the work has
been installed in ROM).
The requirement to provide Installation Information does not include a
requirement to continue to provide support service, warranty, or updates
for a work that has been modified or installed by the recipient, or for
the User Product in which it has been modified or installed. Access to a
network may be denied when the modification itself materially and
adversely affects the operation of the network or violates the rules and
protocols for communication across the network.
Corresponding Source conveyed, and Installation Information provided,
in accord with this section must be in a format that is publicly
documented (and with an implementation available to the public in
source code form), and must require no special password or key for
unpacking, reading or copying.
7. Additional Terms.
"Additional permissions" are terms that supplement the terms of this
License by making exceptions from one or more of its conditions.
Additional permissions that are applicable to the entire Program shall
be treated as though they were included in this License, to the extent
that they are valid under applicable law. If additional permissions
apply only to part of the Program, that part may be used separately
under those permissions, but the entire Program remains governed by
this License without regard to the additional permissions.
When you convey a copy of a covered work, you may at your option
remove any additional permissions from that copy, or from any part of
it. (Additional permissions may be written to require their own
removal in certain cases when you modify the work.) You may place
additional permissions on material, added by you to a covered work,
for which you have or can give appropriate copyright permission.
Notwithstanding any other provision of this License, for material you
add to a covered work, you may (if authorized by the copyright holders of
that material) supplement the terms of this License with terms:
a) Disclaiming warranty or limiting liability differently from the
terms of sections 15 and 16 of this License; or
b) Requiring preservation of specified reasonable legal notices or
author attributions in that material or in the Appropriate Legal
Notices displayed by works containing it; or
c) Prohibiting misrepresentation of the origin of that material, or
requiring that modified versions of such material be marked in
reasonable ways as different from the original version; or
d) Limiting the use for publicity purposes of names of licensors or
authors of the material; or
e) Declining to grant rights under trademark law for use of some
trade names, trademarks, or service marks; or
f) Requiring indemnification of licensors and authors of that
material by anyone who conveys the material (or modified versions of
it) with contractual assumptions of liability to the recipient, for
any liability that these contractual assumptions directly impose on
those licensors and authors.
All other non-permissive additional terms are considered "further
restrictions" within the meaning of section 10. If the Program as you
received it, or any part of it, contains a notice stating that it is
governed by this License along with a term that is a further
restriction, you may remove that term. If a license document contains
a further restriction but permits relicensing or conveying under this
License, you may add to a covered work material governed by the terms
of that license document, provided that the further restriction does
not survive such relicensing or conveying.
If you add terms to a covered work in accord with this section, you
must place, in the relevant source files, a statement of the
additional terms that apply to those files, or a notice indicating
where to find the applicable terms.
Additional terms, permissive or non-permissive, may be stated in the
form of a separately written license, or stated as exceptions;
the above requirements apply either way.
8. Termination.
You may not propagate or modify a covered work except as expressly
provided under this License. Any attempt otherwise to propagate or
modify it is void, and will automatically terminate your rights under
this License (including any patent licenses granted under the third
paragraph of section 11).
However, if you cease all violation of this License, then your
license from a particular copyright holder is reinstated (a)
provisionally, unless and until the copyright holder explicitly and
finally terminates your license, and (b) permanently, if the copyright
holder fails to notify you of the violation by some reasonable means
prior to 60 days after the cessation.
Moreover, your license from a particular copyright holder is
reinstated permanently if the copyright holder notifies you of the
violation by some reasonable means, this is the first time you have
received notice of violation of this License (for any work) from that
copyright holder, and you cure the violation prior to 30 days after
your receipt of the notice.
Termination of your rights under this section does not terminate the
licenses of parties who have received copies or rights from you under
this License. If your rights have been terminated and not permanently
reinstated, you do not qualify to receive new licenses for the same
material under section 10.
9. Acceptance Not Required for Having Copies.
You are not required to accept this License in order to receive or
run a copy of the Program. Ancillary propagation of a covered work
occurring solely as a consequence of using peer-to-peer transmission
to receive a copy likewise does not require acceptance. However,
nothing other than this License grants you permission to propagate or
modify any covered work. These actions infringe copyright if you do
not accept this License. Therefore, by modifying or propagating a
covered work, you indicate your acceptance of this License to do so.
10. Automatic Licensing of Downstream Recipients.
Each time you convey a covered work, the recipient automatically
receives a license from the original licensors, to run, modify and
propagate that work, subject to this License. You are not responsible
for enforcing compliance by third parties with this License.
An "entity transaction" is a transaction transferring control of an
organization, or substantially all assets of one, or subdividing an
organization, or merging organizations. If propagation of a covered
work results from an entity transaction, each party to that
transaction who receives a copy of the work also receives whatever
licenses to the work the party's predecessor in interest had or could
give under the previous paragraph, plus a right to possession of the
Corresponding Source of the work from the predecessor in interest, if
the predecessor has it or can get it with reasonable efforts.
You may not impose any further restrictions on the exercise of the
rights granted or affirmed under this License. For example, you may
not impose a license fee, royalty, or other charge for exercise of
rights granted under this License, and you may not initiate litigation
(including a cross-claim or counterclaim in a lawsuit) alleging that
any patent claim is infringed by making, using, selling, offering for
sale, or importing the Program or any portion of it.
11. Patents.
A "contributor" is a copyright holder who authorizes use under this
License of the Program or a work on which the Program is based. The
work thus licensed is called the contributor's "contributor version".
A contributor's "essential patent claims" are all patent claims
owned or controlled by the contributor, whether already acquired or
hereafter acquired, that would be infringed by some manner, permitted
by this License, of making, using, or selling its contributor version,
but do not include claims that would be infringed only as a
consequence of further modification of the contributor version. For
purposes of this definition, "control" includes the right to grant
patent sublicenses in a manner consistent with the requirements of
this License.
Each contributor grants you a non-exclusive, worldwide, royalty-free
patent license under the contributor's essential patent claims, to
make, use, sell, offer for sale, import and otherwise run, modify and
propagate the contents of its contributor version.
In the following three paragraphs, a "patent license" is any express
agreement or commitment, however denominated, not to enforce a patent
(such as an express permission to practice a patent or covenant not to
sue for patent infringement). To "grant" such a patent license to a
party means to make such an agreement or commitment not to enforce a
patent against the party.
If you convey a covered work, knowingly relying on a patent license,
and the Corresponding Source of the work is not available for anyone
to copy, free of charge and under the terms of this License, through a
publicly available network server or other readily accessible means,
then you must either (1) cause the Corresponding Source to be so
available, or (2) arrange to deprive yourself of the benefit of the
patent license for this particular work, or (3) arrange, in a manner
consistent with the requirements of this License, to extend the patent
license to downstream recipients. "Knowingly relying" means you have
actual knowledge that, but for the patent license, your conveying the
covered work in a country, or your recipient's use of the covered work
in a country, would infringe one or more identifiable patents in that
country that you have reason to believe are valid.
If, pursuant to or in connection with a single transaction or
arrangement, you convey, or propagate by procuring conveyance of, a
covered work, and grant a patent license to some of the parties
receiving the covered work authorizing them to use, propagate, modify
or convey a specific copy of the covered work, then the patent license
you grant is automatically extended to all recipients of the covered
work and works based on it.
A patent license is "discriminatory" if it does not include within
the scope of its coverage, prohibits the exercise of, or is
conditioned on the non-exercise of one or more of the rights that are
specifically granted under this License. You may not convey a covered
work if you are a party to an arrangement with a third party that is
in the business of distributing software, under which you make payment
to the third party based on the extent of your activity of conveying
the work, and under which the third party grants, to any of the
parties who would receive the covered work from you, a discriminatory
patent license (a) in connection with copies of the covered work
conveyed by you (or copies made from those copies), or (b) primarily
for and in connection with specific products or compilations that
contain the covered work, unless you entered into that arrangement,
or that patent license was granted, prior to 28 March 2007.
Nothing in this License shall be construed as excluding or limiting
any implied license or other defenses to infringement that may
otherwise be available to you under applicable patent law.
12. No Surrender of Others' Freedom.
If conditions are imposed on you (whether by court order, agreement or
otherwise) that contradict the conditions of this License, they do not
excuse you from the conditions of this License. If you cannot convey a
covered work so as to satisfy simultaneously your obligations under this
License and any other pertinent obligations, then as a consequence you may
not convey it at all. For example, if you agree to terms that obligate you
to collect a royalty for further conveying from those to whom you convey
the Program, the only way you could satisfy both those terms and this
License would be to refrain entirely from conveying the Program.
13. Use with the GNU Affero General Public License.
Notwithstanding any other provision of this License, you have
permission to link or combine any covered work with a work licensed
under version 3 of the GNU Affero General Public License into a single
combined work, and to convey the resulting work. The terms of this
License will continue to apply to the part which is the covered work,
but the special requirements of the GNU Affero General Public License,
section 13, concerning interaction through a network will apply to the
combination as such.
14. Revised Versions of this License.
The Free Software Foundation may publish revised and/or new versions of
the GNU General Public License from time to time. Such new versions will
be similar in spirit to the present version, but may differ in detail to
address new problems or concerns.
Each version is given a distinguishing version number. If the
Program specifies that a certain numbered version of the GNU General
Public License "or any later version" applies to it, you have the
option of following the terms and conditions either of that numbered
version or of any later version published by the Free Software
Foundation. If the Program does not specify a version number of the
GNU General Public License, you may choose any version ever published
by the Free Software Foundation.
If the Program specifies that a proxy can decide which future
versions of the GNU General Public License can be used, that proxy's
public statement of acceptance of a version permanently authorizes you
to choose that version for the Program.
Later license versions may give you additional or different
permissions. However, no additional obligations are imposed on any
author or copyright holder as a result of your choosing to follow a
later version.
15. Disclaimer of Warranty.
THERE IS NO WARRANTY FOR THE PROGRAM, TO THE EXTENT PERMITTED BY
APPLICABLE LAW. EXCEPT WHEN OTHERWISE STATED IN WRITING THE COPYRIGHT
HOLDERS AND/OR OTHER PARTIES PROVIDE THE PROGRAM "AS IS" WITHOUT WARRANTY
OF ANY KIND, EITHER EXPRESSED OR IMPLIED, INCLUDING, BUT NOT LIMITED TO,
THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
PURPOSE. THE ENTIRE RISK AS TO THE QUALITY AND PERFORMANCE OF THE PROGRAM
IS WITH YOU. SHOULD THE PROGRAM PROVE DEFECTIVE, YOU ASSUME THE COST OF
ALL NECESSARY SERVICING, REPAIR OR CORRECTION.
16. Limitation of Liability.
IN NO EVENT UNLESS REQUIRED BY APPLICABLE LAW OR AGREED TO IN WRITING
WILL ANY COPYRIGHT HOLDER, OR ANY OTHER PARTY WHO MODIFIES AND/OR CONVEYS
THE PROGRAM AS PERMITTED ABOVE, BE LIABLE TO YOU FOR DAMAGES, INCLUDING ANY
GENERAL, SPECIAL, INCIDENTAL OR CONSEQUENTIAL DAMAGES ARISING OUT OF THE
USE OR INABILITY TO USE THE PROGRAM (INCLUDING BUT NOT LIMITED TO LOSS OF
DATA OR DATA BEING RENDERED INACCURATE OR LOSSES SUSTAINED BY YOU OR THIRD
PARTIES OR A FAILURE OF THE PROGRAM TO OPERATE WITH ANY OTHER PROGRAMS),
EVEN IF SUCH HOLDER OR OTHER PARTY HAS BEEN ADVISED OF THE POSSIBILITY OF
SUCH DAMAGES.
17. Interpretation of Sections 15 and 16.
If the disclaimer of warranty and limitation of liability provided
above cannot be given local legal effect according to their terms,
reviewing courts shall apply local law that most closely approximates
an absolute waiver of all civil liability in connection with the
Program, unless a warranty or assumption of liability accompanies a
copy of the Program in return for a fee.
END OF TERMS AND CONDITIONS
How to Apply These Terms to Your New Programs
If you develop a new program, and you want it to be of the greatest
possible use to the public, the best way to achieve this is to make it
free software which everyone can redistribute and change under these terms.
To do so, attach the following notices to the program. It is safest
to attach them to the start of each source file to most effectively
state the exclusion of warranty; and each file should have at least
the "copyright" line and a pointer to where the full notice is found.
<one line to give the program's name and a brief idea of what it does.>
Copyright (C) <year> <name of author>
This program is free software: you can redistribute it and/or modify
it under the terms of the GNU General Public License as published by
the Free Software Foundation, either version 3 of the License, or
(at your option) any later version.
This program is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
GNU General Public License for more details.
You should have received a copy of the GNU General Public License
along with this program. If not, see <https://www.gnu.org/licenses/>.
Also add information on how to contact you by electronic and paper mail.
If the program does terminal interaction, make it output a short
notice like this when it starts in an interactive mode:
<program> Copyright (C) <year> <name of author>
This program comes with ABSOLUTELY NO WARRANTY; for details type `show w'.
This is free software, and you are welcome to redistribute it
under certain conditions; type `show c' for details.
The hypothetical commands `show w' and `show c' should show the appropriate
parts of the General Public License. Of course, your program's commands
might be different; for a GUI interface, you would use an "about box".
You should also get your employer (if you work as a programmer) or school,
if any, to sign a "copyright disclaimer" for the program, if necessary.
For more information on this, and how to apply and follow the GNU GPL, see
<https://www.gnu.org/licenses/>.
The GNU General Public License does not permit incorporating your program
into proprietary programs. If your program is a subroutine library, you
may consider it more useful to permit linking proprietary applications with
the library. If this is what you want to do, use the GNU Lesser General
Public License instead of this License. But first, please read
<https://www.gnu.org/licenses/why-not-lgpl.html>.
+544 -3
查看文件
@@ -1,4 +1,545 @@
# tem3dfdtd-open # tem3dfdtd
#### Description [中文](./README.md) | [English](./README.en.md)
Please visit https://em3d.cn for more information.
[!NOTE]
> All contents of this document are automatically translated by AI without human verification. Please refer to the original Chinese version if you need accurate information.
# 3D Transient Electromagnetic FDTD Forward Modeling Program (tem3dfdtd)
This program performs forward modeling of three-dimensional transient electromagnetic (TEM) responses based on the **FDTD (finite-difference time-domain) method**. The core algorithm adopts the Du Fort–Frankel method improved by Wang–Hohmann (1993): it iteratively solves the magnetic field H on a Yee grid, and ensures the time stability of the explicit iteration by introducing a **fictitious permittivity**. It uses **conformal grid techniques** to handle undulating terrain and arbitrarily shaped anomalous bodies (described by surface triangular meshes). It supports a rectangular loop source and can compute ground TEM, semi-airborne (SATEM), and airborne (ATEM) modes.
The overall framework and the three core techniques are derived from the following works:
- **Overall framework and core iterative algorithm** (loop-source TEM three-dimensional finite-difference time-domain forward modeling considering the turn-off time, the Wang–Hohmann improved Du Fort–Frankel method, the fictitious permittivity, and the source waveform including the turn-off time); for the theoretical details, see reference [1];
- **CPML absorbing boundary** (the CPML absorbing boundary for the low-frequency-approximated Maxwell equations in transient electromagnetics and its application method); for the theoretical details, see reference [2];
- **Conformal grid technique** (introducing arbitrarily complex-shaped structures into the Yee grid computation via a ray-tracing method); for the theoretical details, see reference [3].
The specific principles, formula derivations, and implementation details of each method are given in references [1]–[3]. The authors of these papers are all people who have made outstanding contributions to this open-source project.
Code structure: `main.f90` (main program), `module/` (global parameters and modules), `lib/` (functional subroutines).
---
## Table of Contents
- [tem3dfdtd](#tem3dfdtd)
- [3D Transient Electromagnetic FDTD Forward Modeling Program (tem3dfdtd)](#3d-transient-electromagnetic-fdtd-forward-modeling-program-tem3dfdtd)
- [Table of Contents](#table-of-contents)
- [1. Environment and Compilation](#1-environment-and-compilation)
- [1.1 Environment Requirements](#11-environment-requirements)
- [1.2 Build and Run with VS2019 (Recommended)](#12-build-and-run-with-vs2019-recommended)
- [1.3 Command-Line Compilation (Optional, Not Recommended on Windows)](#13-command-line-compilation-optional-not-recommended-on-windows)
- [1.4 Linux Environment Compilation (makefile)](#14-linux-environment-compilation-makefile)
- [2. Program Flow and Module Structure](#2-program-flow-and-module-structure)
- [Module 1: Program Control and Parameter Input](#module-1-program-control-and-parameter-input)
- [Module 2: Yee Grid Generation](#module-2-yee-grid-generation)
- [Module 3: Electrical Parameter Construction](#module-3-electrical-parameter-construction)
- [Module 4: Excitation Source and Time Series](#module-4-excitation-source-and-time-series)
- [Module 5: FDTD Electromagnetic Field Computation](#module-5-fdtd-electromagnetic-field-computation)
- [Module 6: Output](#module-6-output)
- [3. Input File Formats](#3-input-file-formats)
- [3.1 Parameter Control File input.dat](#31-parameter-control-file-inputdat)
- [3.2 Terrain Mesh File Complex_Terrain](#32-terrain-mesh-file-complex_terrain)
- [3.3 Anomalous Body Mesh File Complex_anomalous](#33-anomalous-body-mesh-file-complex_anomalous)
- [3.4 Modeling Notes](#34-modeling-notes)
- [4. CPML Absorbing Boundary](#4-cpml-absorbing-boundary)
- [4.1 Implementation Location](#41-implementation-location)
- [4.2 Parameters and Their Meanings](#42-parameters-and-their-meanings)
- [4.3 Usage Notes](#43-usage-notes)
- [4.4 Comparison with the Dirichlet Boundary](#44-comparison-with-the-dirichlet-boundary)
- [5. Output File Description](#5-output-file-description)
- [6. Quick Decay-Curve Plotting (TEM_decay_plot.py)](#6-quick-decay-curve-plotting-tem_decay_plotpy)
- [6.1 Usage](#61-usage)
- [6.2 Main Adjustable Parameters (the "User parameters" section at the top of the script)](#62-main-adjustable-parameters-the-user-parameters-section-at-the-top-of-the-script)
- [7. Quick Start (the example bundled in this directory)](#7-quick-start-the-example-bundled-in-this-directory)
- [8. FAQ](#8-faq)
- [9. References](#9-references)
- [10. Contributors](#10-contributors)
- [11. Statement](#11-statement)
---
## 1. Environment and Compilation
### 1.1 Environment Requirements
| Item | Requirement |
| ---------------- | -------------------------------------------------------------------------------------------------------------------------------- |
| Operating system | Windows 10/11 (64-bit) or Linux (x86_64); the domestic operating system deepin 25 is especially recommended |
| IDE | Windows: Visual Studio 2019 or later; Linux/deepin: make; |
| Fortran compiler | Intel oneAPI Fortran (ifort/ifx); |
| Parallel support | OpenMP (multi-core CPU acceleration); additional GPU support is provided in the commercial version, please visit https://em3d.cn |
### 1.2 Build and Run with VS2019 (Recommended)
1. Install Visual Studio 2019 (select the "Desktop development with C++" workload) and Intel oneAPI (select the "Visual Studio integration for Intel Fortran Compiler" during installation).
2. Double-click to open the project file **`tem3dfdtd.sln`** (an Intel Fortran project, corresponding to
`tem3dfdtd.vfproj`). The project already includes all source files. Configuration notes:
- `Debug | x64` / `Release | x64`: use the **ifx** compiler (oneAPI default), **recommended**;
- `Debug | Win32` / `Release | Win32`: use the ifort compiler.
3. Select the **`Release | x64`** configuration and click **Build → Build Solution**.
4. Preparation before running: the program looks for `input.dat` and the mesh files in the working directory, so place
`input.dat`, `Complex_Terrain.dat/.stl`, and `Complex_anomalous.dat/.stl` in the
**tem3dfdtd-open\tem3dfdtd** directory (or specify it via "Project Properties → Debugging → Working Directory").
5. Run `tem3dfdtd.exe` directly, or press F5 to debug-run.
> **Note**: the program uses OpenMP and requires Intel's runtime library `libiomp5md.dll` at run time
> (located in the Intel oneAPI installation directory `bin/`). If you get a missing-DLL error, copy it next to
> the exe (a copy is already placed in this directory), or add its directory to the system PATH.
### 1.3 Command-Line Compilation (Optional, Not Recommended on Windows)
In an "Intel oneAPI Command Prompt" environment:
```bat
ifx -c -O2 -Qopenmp module\*.f90
ifx -c -O2 -Qopenmp -Qopenmp lib\*.f90 main.f90
ifx -O2 -Qopenmp *.obj -o tem3dfdtd.exe
```
(Linking requires MSVC's link.exe and the Windows SDK libraries; it is recommended to use VS's "Developer Command Prompt"
and add Intel oneAPI's `bin` directory to PATH.)
### 1.4 Linux Environment Compilation (makefile)
To compile under Linux you need to write a `makefile`. Please write the makefile yourself according to your operating system's configuration and requirements, and compile with `make` (using the makefile).
**Notes and cautions**
- Differences from the Windows version: under Linux the executable name is custom; if not specified it defaults to `main.exe`. The working directory must likewise contain
`input.dat` and the `Complex_Terrain.*`, `Complex_anomalous.*` mesh files.
---
## 2. Program Flow and Module Structure
Main program execution order (`main.f90`):
```
GETDATA → CHECKPARAMETERS → MEMORY_USE_ESTIMATION → ALLOCATEMEMORY
→ GET_NON_UNIFORMGRID → ZERO → GET_COORDINATES
→ Get_Receiver_Gridlabel → RES_CONFIGURE → TIME_SERIOUS
→ Get_eps_r → (if Logic_PML=1) Get_pml_parameters → Get_mstop
→ GetSourcePosition → Iteration → FREE_MEMORY
```
By function, it is divided into the following 6 modules:
### Module 1: Program Control and Parameter Input
| File | Function |
| ------------------------------- | ------------------------------------------------------------------------------------------------------------------------------------ |
| `main.f90` | Main program, controls the whole computation flow |
| `lib/getdata.f90` | Reads the parameter control file `input.dat`; detects the existence of terrain/anomalous-body mesh files and selects the read format |
| `lib/checkparameters.f90` | Echoes the read-in computation parameters to `logfile.log` for manual checking |
| `lib/memory-use-estimation.f90` | Estimates the required memory based on the grid size and prints a hint |
### Module 2: Yee Grid Generation
| File | Function |
| ----------------------------- | ---------------------------------------------------------------------------------------------------------------------------------------------- |
| `lib/allocatememory.f90` | Dynamically allocates all global arrays according to the input parameters (including the CPML memory-variable arrays, only when `Logic_PML=1`) |
| `lib/get_non_uniformgrid.f90` | Generates the non-uniform grid in the x/y/z directions (uniform in the core area + expanded outward by a factor of 1.3) |
| `lib/get_coordinates.f90` | Computes the coordinates of all grid nodes (including Yee nodes); coordinates take the source center as origin |
| `lib/zero.f90` | Initializes all electromagnetic field arrays to 0; sets den\_\* to 1, c_h_zz to 0, and clears the CPML memory variables |
### Module 3: Electrical Parameter Construction
| File | Function |
| ----------------------------------- | ----------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- |
| `lib/resistivity-configuration.f90` | Builds the model conductivity: without terrain, assigns background conductivity + block-shaped anomalous bodies; with terrain, calls the conformal mesh; finally distributes the conductivity onto edges in the x/y/z directions and writes `conductivity.vtk` |
| `lib/Terrain_conformal.f90` | **Terrain conformal mesh**: reads the terrain triangular mesh from `Complex_Terrain.dat/.stl`, fills the equivalent conductivity of each edge along the x/y/z directions using ray–triangle intersection (Möller–Trumbore algorithm), handling undulating terrain and the air/stratum interface |
| `lib/Anomalous_conformal.f90` | **Anomalous-body conformal mesh**: reads the anomalous-body surface mesh from `Complex_anomalous.dat/.stl`, and fills the anomalous-body conductivity (`tao_abnormal`) onto edges using the same ray-intersection method |
> **Note**: when a terrain file exists, in the terrain branch the air conductivity is `AIR_CONDUCTIVITY = 1e-6 S/m`,
> and the stratum conductivity is the **2nd conductivity in the block-shaped anomalous body parameters** `TAR_CONDUCTIVITY(2)` (see the second group of data from line 9 of input.dat). In this case the block-shaped anomalous bodies in input.dat do not take effect directly; instead the anomalous body is described by the `Complex_anomalous`
> mesh file and assigned its conductivity via `tao_abnormal`.
### Module 4: Excitation Source and Time Series
| File | Function |
| ----------------------------- | ----------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- |
| `lib/time-serious.f90` | Generates the time series for the whole computation (including the source waveform), and corrects the iteration step count `NSTOP` according to `MAX_OFF_TIME`; writes `CTIME_TIXING_UPCOS.DAT` |
| `lib/tixing-source-upcos.f90` | Source waveform: **trapezoidal + cosine-ramp** turn-off current waveform (commonly used, `SOURCE_TYPE = 'TIXING_UPCOS'`) |
| `lib/tixing-source.f90` | Pure trapezoidal waveform source (`TIXING_RAMP`) |
| `lib/sin-source.f90` | Half-sine waveform source (`HALF_SIN`) |
| `lib/triangle-source.f90` | Triangular waveform source (`TRIANGLE`) |
| `lib/get-eps-r.f90` | Computes the fictitious permittivity `EPS_R = 3·(Δt/Δx)²/μ₀` and the iteration coefficients, ensuring the stability of the explicit FDTD |
| `lib/get-mstop.f90` | Splits the total iteration into several "computation segments", each with its own cache allocation, for memory management |
### Module 5: FDTD Electromagnetic Field Computation
| File | Function |
| --------------------------- | -------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- |
| `lib/GetSourcePosition.f90` | Determines the loop source's position in the grid and marks the source edges (the current assignment region) |
| `lib/Iteration.f90` | **Core iteration subroutine**: advances the time steps segment by segment, updates the Ex/Ey/Ez and Hz fields, and loads current according to the source waveform; at the end of each segment it computes Hz for each receiver point (obtained by weighted differencing of the Ex, Ey of the 8 nodes surrounding that point) and writes it to the result file. The boundary condition switches via `Logic_PML`: `1` adds the CPML memory-variable correction in each field update, `0` restores the original Dirichlet (zero-field) boundary |
| `module/pml-parameters.f90` | **CPML absorbing boundary module** (Roden–Gedney convolutional PML): declares the σ/α/κ polynomial scaling parameters (ma=3, mb=1), the 26 memory-variable ψ arrays, the b*e/c_e convolution-coefficient arrays, and the den*\*(=1/κ) scaling arrays |
| `lib/get-pml-paramters.f90` | Builds the σ/α/κ distributions on the six x/y/z boundary faces (polynomial decay from the boundary inward, E/H staggered sampling) and the den\_\* scaling arrays; called by main only when `Logic_PML=1` |
### Module 6: Output
| File | Function |
| ------------------------------------------------- | --------------------------------------------------------------------------------- |
| `lib/Iteration.f90` (output part) | Writes the response files `dBzdt_1.txt`, `dBzdt_2.txt`, … for each receiver point |
| `lib/resistivity-configuration.f90` (output part) | Writes the model conductivity distribution `conductivity.vtk` |
| `lib/time-serious.f90` (output part) | Writes the time series `CTIME_TIXING_UPCOS.DAT` |
| `lib/free-memory.f90` | Releases all dynamic memory after computation |
---
## 3. Input File Formats
The program requires the following files (all placed in the exe's working directory):
| File | Required? | Description |
| --------------------------------- | --------------------- | ----------------------------------------------------------------------------------------------- |
| `input.dat` | **Required** | Computation parameter control file |
| `Complex_anomalous.dat` or `.stl` | Optional (either one) | Anomalous-body surface triangular mesh; if absent, the model is treated as a uniform background |
| `Complex_Terrain.dat` or `.stl` | Optional (either one) | Terrain surface triangular mesh; if absent, no undulating terrain is considered |
### 3.1 Parameter Control File input.dat
**Free-format reading**, read line by line in order; a value may be followed by a `!` comment (whole-line or end-of-line comments). The following explains each line using the `input.dat` bundled in this directory as an example:
| Line | Example | Meaning |
| ----- | -------------- | ----------------------------------------------------------------------------------------------------------------------------------------- |
| 1 | `1` | Computation mode `CAL_TYPE`: `1` = ground TEM, `2` = semi-airborne (SATEM) |
| 2 | `500` | Transmitting loop side length `SourceLength` (m) |
| 3 | `101,101,100` | Number of grids in the x, y, z directions `NX,NY,NZ` |
| 4 | `1` | **Boundary condition switch `Logic_PML`**: `1` = CPML absorbing boundary, `0` = original non-uniform-grid Dirichlet (zero-field) boundary |
| 5 | `10,10,10` | **PML layer count `PML_X,PML_Y,PML_Z`** (x, y, z directions; effective only when the switch = 1; ≥ 5 layers recommended) |
| 6 | `25,25` | x direction: core uniform-grid start/end interval indices `UniGridNumX1,UniGridNumX2` |
| 7 | `25,25` | y direction: core uniform-grid interval indices `UniGridNumY1,UniGridNumY2` |
| 8 | `20,30` | z direction: core uniform-grid interval indices `UniGridNumZ1,UniGridNumZ2` |
| 9 | `20` | Core-area uniform grid size `GridSize` (m) |
| 10 | `0.01` | Background medium conductivity `BACKGROUND_CONDUCTIVITY` (S/m) |
| 11 | `2` | Number of block-shaped anomalous bodies `TEMP_II` (filled as prisms when no terrain; set 0 for a uniform model) |
| 12–15 | see below | **Parameters of the 1st block-shaped anomalous body**, 4 lines in total |
| 16–19 | see below | **Parameters of the 2nd block-shaped anomalous body**, 4 lines in total |
| 20 | `4000000` | Maximum number of iterations `NSTOP` |
| 21 | `90.101` | Maximum computation time `MAX_OFF_TIME` (**unit: ms**) |
| 22 | `1e-6,1e-9` | Rising-edge duration and time step `RAISETIME, RAISESTEP` (s) |
| 23 | `60000e-6` | Plateau-stage duration `WAVE` (s, i.e. 60 ms) |
| 24 | `1e-7,1e-9` | Falling-edge duration and time step `RAMP, RAMPSTEP` (s) |
| 25 | `1e-9` | Initial time step `TIMESTEP` (s) |
| 26 | `1` | Transmitting current amplitude `AMP` (A) |
| 27 | `4.0` | Anomalous-body conductivity `tao_abnormal` (S/m, used with the `Complex_anomalous` file) |
| 28 | `TIXING_UPCOS` | Source type `SOURCE_TYPE`: `TIXING_UPCOS` / `TIXING_RAMP` / `HALF_SIN` / `TRIANGLE` |
| 29 | `1` | Number of receiver points `Point_Num` |
| 30 | `1` | Index of the 1st receiver point |
| 31 | `0,0,0` | Coordinates of the 1st receiver point (relative to the source center, m) |
| 32–33 | `2` / `x,y,z` | (if there are extra measurement points) the 2nd receiver point (index + coordinates) |
Each **block-shaped anomalous body** consists of 4 consecutive lines:
| Line | Example | Meaning |
| ---- | ------- | --------------------------------------------------- |
| ① | `1,101` | x-direction grid start/end indices `TAR_X1, TAR_X2` |
| ② | `1,101` | y-direction grid start/end indices `TAR_Y1, TAR_Y2` |
| ③ | `1,50` | z-direction grid start/end indices `TAR_Z1, TAR_Z2` |
| ④ | `1e-5` | Conductivity of this block `TAR_CONDUCTIVITY` (S/m) |
> This example uses two "anomalous bodies" to assemble a half-space: block 1 z=1~50 (air, 1e-5 S/m) + block 2
> z=51~100 (stratum, 1e-2 S/m). After the receiver count `Point_Num`, each measurement point occupies 2 lines
> (index + coordinates relative to the source center).
### 3.2 Terrain Mesh File Complex_Terrain
The terrain is described by a **surface triangular
mesh**, supported in two formats; keep **only one of them** in the folder;
if both exist at the same time, the program takes `.dat` as the priority and warns that `.stl` is ignored.
**Format 1: `Complex_Terrain.dat` (original text format)**
```
Number of Nodes and Elements:
10039 ← total number of nodes n_point
5426 ← total number of triangular elements n_face
Nodes Coordinates:
1 -21000.0 -21000.0 224.08 ← n_point lines: node index, X, Y, Z
2 -21000.0 -20001.8 224.08
... (a `!` comment may appear in a line)
END Nodes Coordinates
NormalAreaElements:
1 1 2 10039 ← n_face lines: element index, node1, node2, node3
...
END NormalAreaElements
```
| Line | Content |
| -------------------------- | -------------------------------------------------------------------------------------------------------------- |
| Line 1 | Title line, arbitrary |
| Line 2 | Total number of nodes `n_point` |
| Line 3 | Total number of triangular elements `n_face` |
| Line 4 | Title line, arbitrary |
| Lines 5 ~ 4+n_point | One line per node: `node index, X, Y, Z` |
| The following 1 line | Section end marker `END Nodes Coordinates` (skipped by the program as a title line) |
| The following 1 line | Face-section title `NormalAreaElements:` (skipped by the program as a title line) |
| The following n_face lines | One line per element: `element index, node1 index, node2 index, node3 index` (nodes in counterclockwise order) |
| The last 1 line | End marker `END NormalAreaElements` (not read by the program) |
> The two section-marker lines after the node section (GiD export) are in the same position as the "2 title lines" of the old format;
> the program always skips them as title lines, so both notations are compatible.
**Format 2: `Complex_Terrain.stl` (ASCII STL format)**
The STL file format is a file format used to describe the surface geometry of three-dimensional objects, widely used in rapid prototyping, 3D printing, and computer-aided manufacturing (CAM).
An STL file subdivides an object's surface into a series of small triangles, each defined by a normal vector and three vertex coordinates.
STL files have two formats: text format (ASCII) and binary format.
Standard ASCII STL uses the `facet`/`endfacet` element keywords,
with nodes represented by `vertex` lines, for example in the following format:
```
facet normal nx ny nz
outer loop
vertex v1x v1y v1z
vertex v2x v2y v2z
vertex v3x v3y v3z
endloop
endfacet
```
Users can create and edit STL files with common CAD software (such as AutoCAD, Blender, FreeCAD, MeshLab, SketchUp, Gid, Maya, 3ds Max, etc.).
The program automatically handles two things when reading (no user action needed):
1. **Vertex deduplication/merging**: in STL, each face writes its vertices independently; duplicate vertices (tolerance 1e-5) are automatically merged into a unique node table;
2. **Orientation correction**: compare each face's cross-product direction with the `facet normal` in the file; if opposite, swap the face's 2nd and 3rd
nodes to guarantee that the normal-direction convention is consistent with the `.dat` format.
### 3.3 Anomalous Body Mesh File Complex_anomalous
Exactly the same as the terrain file: either the `.dat` or `.stl` format (when both exist, `.dat` takes priority),
with the same reading, deduplication, and orientation-correction rules; the `.dat` section marker lines (`END Nodes Coordinates`,
`NormalAreaElements:`, `END NormalAreaElements`) are the same as the terrain file and are likewise compatible with the program.
The `Complex_anomalous.dat` / `.stl` in this directory describe **a complex three-dimensional anomalous body under undulating terrain**
(2663 nodes, 5322 triangular elements; extent x ≈ -302 ~ 248 m, y ≈ -197 ~ 176 m,
z ≈ 51 ~ 285 m, embedded near the terrain surface).
Its conductivity is specified by line 27 of `input.dat`,
`tao_abnormal = 4.0` (a low-resistivity body).
> Mesh generation suggestion: use professional preprocessing software to build the terrain surface / anomalous-body surface triangular mesh and export it,
> or choose "Export → STL" to generate an ASCII STL file.
### 3.4 Modeling Notes
1. **The number of grids in the x and y directions is recommended to be odd**, so that the model center (the source center) falls exactly at the center of a Yee grid face;
since the magnetic induction intensity B is defined at the grid-face center, the `dBz/dt` measurement point should **preferably be placed at the center of a Yee grid face**,
to guarantee the correspondence between the measurement-point response and the field definition.
2. **The transmitting loop side length should be an odd multiple of the grid size**, so that the loop center falls on a Yee grid edge, ensuring strict alignment between the source-current edges and the grid edges.
3. **When using the Dirichlet boundary (`Logic_PML=0`)**, the grid refinement region (core uniform area) should **cover the transmitting source,
the receiver points, and the anomalous body**, to guarantee the computational accuracy of the above region; the outer large grids are used to extend the computational domain and reduce
the influence of the zero-field boundary on the result.
4. **The z-direction position of the transmitting source is by default at `NZS+1`** (`NZS=NZ/2`, i.e. the middle of the grid), determined automatically by the program,
and does not need to be specified in the input file.
5. **Airborne (TEM) simulation**: the program also supports airborne scenarios — set the upper region to air, and
add several more layers of air grids below the source plane, so that both the transmitting source and the receiver points are in the air.
---
## 4. CPML Absorbing Boundary
When `Logic_PML=1`, the program uses **CPML (Convolutional Perfectly Matched Layer, Roden & Gedney 2000)**
as the absorbing boundary, absorbing the outward-propagating electromagnetic field at the periphery of the computational region to simulate an "infinite earth stratum"
and avoid boundary reflections contaminating the late-time response.
### 4.1 Implementation Location
| File | Function |
| ----------------------------------------------- | ---------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- |
| `module/pml-parameters.f90` | Parameter declaration: σ/α/κ maxima, PML layer count, the 26 memory-variable ψ arrays, the convolution coefficients `b_e/c_e`, the scaling arrays `den_*(=1/κ)`, and the z-direction recursive coefficient `c_h_zz` for Hz |
| `lib/get-pml-paramters.f90` | Builds the spatial distributions of σ/α/κ on the six x/y/z boundary faces (polynomial increasing from inside to outside, E/H staggered sampling), the `den_*` scaling arrays, and the convolution coefficients; called only when `Logic_PML=1` |
| `lib/Iteration.f90` (subroutine Iteration_cpml) | In the field-update main loop, **embeds** the recurrence and correction terms of the memory variables ψ (24 ψ for Ex/Ey/Ez and Hx/Hy); the z direction of Hz uses a recursive convolution based on `c_h_zz` (not ψ) |
### 4.2 Parameters and Their Meanings
| Parameter | Default value | Meaning |
| ------------------- | ------------------------------------------- | --------------------------------------------------------------------------------------------- |
| `PML_X,PML_Y,PML_Z` | line 5 of input.dat (≥5 layers recommended) | PML layer count in the three directions |
| `ma` | 3 | Polynomial order of σ along the thickness direction (power-law growth from inside to outside) |
| `mb` | 1 | Polynomial order of α along the thickness direction |
| `sig_max` | 1.0e2 | Maximum conductivity at the outer side of the PML (determines absorption strength) |
| `alpha_max` | **1.0e-1** | Maximum value of the complex-frequency-shift factor |
| `kappa_max` | 1.0 | Maximum value of the coordinate-stretching factor (1 means no stretching) |
The spatial distributions of σ and α along the thickness (taking the lower side of the x direction as an example; the other boundaries are symmetric):
```
σ(i) = sig_max · ((Li)/(L1))^ma
α(i) = alpha_max · ((i1)/(L1))^mb
```
The E field is sampled over whole layers and the H field over half layers (staggered), so the H-direction σ/α/κ are constructed with a half-layer offset
(`i0.5`), staggered with respect to the E direction.
### 4.3 Usage Notes
1. In `input.dat`, set line 4 `Logic_PML=1`, and give the PML layer counts for the three directions in line 5
(e.g. `15,15,15`); the grid size inside the PML layers should be consistent with the core area (kept uniform).
2. **Taking α_max = 0.1 is the key tuning parameter**: α (the complex-frequency-shift factor) is responsible for absorbing the low-frequency diffusion field.
If it is too small (e.g. 0.01), the low-frequency reflected field in the late-time stage cannot decay in time and will bounce back and forth across the boundary,
causing exponential divergence on the order of 10⁻⁵ s after turn-off (the result becomes NaN) — this is
the most common source of instability in the CPML version, so be sure to keep α_max = 1.0e-1.
3. To switch back to the original boundary: change line 4 to `0`; the behavior is exactly the same as the old version, no recompilation needed.
### 4.4 Comparison with the Dirichlet Boundary
| | CPML (`Logic_PML=1`) | Dirichlet (`Logic_PML=0`) |
| ------------------ | ---------------------------------------------------------- | ----------------------------------------------------------- |
| Boundary handling | Absorbing layer, simulates an unbounded space | Field is zero at the boundary |
| Late-time accuracy | Absorbs reflections, decay curve is flat | Boundary reflections may contaminate the late-time response |
| Computational cost | 24 extra memory-variable recurrences per step (about +30%) | No extra overhead |
| Grid requirement | Uniform grid required inside the PML layers | No special requirement |
| Stability | Stable when parameters are tuned correctly | Stable |
> **Consistency verification**: in a uniform half-space example (81×81×80 grid, 15 PML layers, 1 ms plateau,
> compared after turn-off), the CPML and Dirichlet boundaries give consistent response curves in the early stage after turn-off (when the field has not yet reached the boundary),
> with a difference < 0.2% (arising from floating-point rounding accumulation due to the different loop orderings in the two versions,
> not a physical difference), proving that the CPML implementation is equivalent to and correct with respect to the main iteration.
---
## 5. Output File Description
| File | Content |
| ------------------------------- | ----------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- |
| `dBzdt_1.txt`, `dBzdt_2.txt`, … | One file per receiver point. The first 2 lines of the header are descriptions (point index, point coordinates); each subsequent line has 3 columns: iteration step, time after turn-off (s), and the magnetic-field response value at that time |
| `CTIME_TIXING_UPCOS.DAT` | Computation time series; each line has 3 columns: cumulative time, time step, source current amplitude (waveform) |
| `conductivity.vtk` | Model conductivity distribution (regular-grid VTK format), can be opened with ParaView/Tecplot etc. to check that the model was built correctly |
| `logfile.log` | Run log: parameter echo, format-selection hints, run errors, etc. |
| `fort.5141` | Debug output of the conformal mesh computation process |
| `TEM_decay_curve.png` | Decay-curve figure (generated by `TEM_decay_plot.py` in [Section 6](#6-quick-decay-curve-plotting-tem_decay_plotpy)) |
At the end of the run the screen prints the iteration progress of each segment and the total computation time; on normal completion, the end of `logfile.log`
shows `Computation finished!`.
---
## 6. Quick Decay-Curve Plotting (TEM_decay_plot.py)
The `TEM_decay_plot.py` in the program directory is used to quickly plot the forward-modeling results `dBzdt_*.txt` as
**decay voltage curves** (log-log coordinates).
### 6.1 Usage
```bash
# requires numpy and matplotlib
pip install numpy matplotlib
# run in the directory where the computation output files (dBzdt_*.txt) are located
python TEM_decay_plot.py
```
The script automatically searches for all `dBzdt_*.txt` files in the same directory, draws one curve per receiver point,
and automatically annotates the point index and coordinates in the legend; by default it outputs a high-resolution image **`TEM_decay_curve.png`**
(dpi=600) and pops it up.
### 6.2 Main Adjustable Parameters (the "User parameters" section at the top of the script)
| Parameter | Default value | Description |
| ---------------------- | --------------------- | ------------------------------------------------------------------------------------------------------------------------- |
| `file_pattern` | `dBzdt_*.txt` | Pattern for matching result files |
| `xmin, xmax` | `1e-6, 1e-1` | Display range of the horizontal axis (time, s) |
| `ymin, ymax` | `None, None` | Display range of the vertical axis (response); `None` means automatic |
| `use_abs` | `True` | `True` plots \|dBz/dt\| (positive response), `False` plots the signed value; the vertical-axis label switches accordingly |
| `savefig` | `True` | Whether to save the figure |
| `save_name` | `TEM_decay_curve.png` | Saved file name |
| `dpi` | `600` | Image resolution |
| `label_fontsize`, etc. | 18/15/15 | Font sizes for labels, ticks, and legend |
| `linewidth` | `2.5` | Curve line width |
When there are more than 8 curves, a sequential blue-gradient colormap is automatically used, so colors are not recycled.
> Curve value rule: only points with `time > 0` and response value > 0 are plotted (negative/zero values cannot be displayed in log-log coordinates).
---
## 7. Quick Start (the example bundled in this directory)
This directory bundles an example: **a complex three-dimensional anomalous body under undulating terrain** (model 101×101×100 grids, grid size
20 m, source side length 500 m, background 0.01 S/m, the anomalous body is a low-resistivity body of 4.0 S/m, 1 measurement point (directly below
the source center); anomalous-body mesh 2663 nodes/5322 elements, terrain mesh 10039 nodes/5426 elements).
Run steps:
1. Confirm that the directory contains: `input.dat`, `Complex_anomalous.dat` (and `.stl`, describing the same anomalous body),
`Complex_Terrain.dat` (and `.stl`, describing the same terrain). When the `.dat` and `.stl` of the same kind
both exist, the program takes `.dat` as the priority and gives a hint.
2. Open `tem3dfdtd.sln` in VS2019 → select `Release | x64` → build.
3. Copy the generated exe to this directory (or put the input files in the exe directory) and run.
4. Observe the screen output; the normal flow is:
```
Both Complex_anomalous.dat and Complex_anomalous.stl exist! The .dat format takes precedence, the .stl file is ignored.
Both Complex_Terrain.dat and Complex_Terrain.stl exist! The .dat format takes precedence, the .stl file is ignored.
The number of grids in the core area is odd
At least 320M memory is needed!
...
Conformal mesh of terrain is complete!
Ray tracing computation of terrain is complete!
Conformal mesh of terrain is finished
Start conformal processing of the anomalous body
...
Now computing fraction: 1
50 steps have just finished
...
```
5. After the computation finishes, check the output files `dBzdt_1.txt` and `conductivity.vtk`.
6. (Optional) Run `python TEM_decay_plot.py` to generate the decay-curve figure `TEM_decay_curve.png`
(see [Section 6](#6-quick-decay-curve-plotting-tem_decay_plotpy)).
---
## 8. FAQ
**Q1: Running reports `libiomp5md.dll` not found**
The OpenMP runtime library is missing. Copy Intel oneAPI's `bin/libiomp5md.dll` next to the exe
(or add it to PATH).
**Q2: The prompt `Both Complex_Terrain.dat and Complex_Terrain.stl exist! ...` appears**
Both format files are present. The program gives `.dat` priority. If you want to use STL, move the `.dat` file away or rename it.
**Q3: The computation is very slow / out of memory**
Reduce `NX,NY,NZ` or increase `GridSize`; control `NSTOP`; `MAX_OFF_TIME` determines the actual number of iteration steps,
and the program uses the smaller of the two. Before running, the required memory estimate is printed.
**Q4: How to compute only a uniform half-space (no anomalous body, no terrain)?**
A half-space model should contain two parts: "air + earth". Move `Complex_anomalous.*` and
`Complex_Terrain.*` away, and set `TEMP_II = 2` in `input.dat`: set block 1 to the upper part
(air, conductivity e.g. `1e-5`), block 2 to the lower part (earth, conductivity e.g. `0.01`), which forms a
uniform half-space. Note: **when `TEMP_II = 0`, the whole model is filled only with the background conductivity (a whole-space uniform medium,
without an air layer)**.
**Q5: How to write the receiver coordinates?**
The coordinates are **local coordinates relative to the loop-source center** (unit: m), with positive/negative directions consistent with the coordinate axes.
**Q6: How to choose between the CPML absorbing boundary and the original Dirichlet boundary?**
Line 4 of `input.dat` is the switch `Logic_PML`: `1` enables the CPML absorbing boundary (line 5
`10,10,10` is the PML layer count in the three directions, which you can adjust), which effectively absorbs boundary reflections and gives a flatter late-time
(large-offset / late-time) decay curve; `0` uses the original non-uniform-grid Dirichlet (zero-field)
boundary. Switching does not require recompilation.
---
## 9. References
[1] Sun Huaifeng, Li Xiu, Li Shucai, et al. Three-dimensional FDTD forward modeling of loop-source TEM considering the turn-off time [J]. Chinese Journal of Geophysics, 2013, 56(3): 1049-1064.
[2] Liu Shangbin, Li Xuefeng, Lan Riyan, et al. CPML absorbing boundary for the low-frequency-approximated Maxwell equations in transient electromagnetics and its application method [J]. Chinese Journal of Geophysics, 2022, 65(4): 1472-1481.
[3] Li X, Zhao Q, Hu S, et al. Introducing complex geometries to Yee cells in FDTD for transient electromagnetic forward modeling[J]. Geophysics, 2025, 91(2): F1-F12.
## 10. Contributors
The entire project was carried out under the leadership of Professor Sun Huaifeng of Shandong University. The main contributors are already noted in the code comments and references. To contact us, please visit https://faculty.sdu.edu.cn/sun/
In addition to this open-source code repository, we also provide a commercial-version software or dedicated solver that supports efficient GPU computation. If needed, please visit https://em3d.cn for more information.
## 11. Statement
- For contact, please use sunhuaifeng@email.sdu.edu.cn, and do not continue using the gmail address noted in the code, because that gmail address often has sending/receiving problems. Thank you.
- The tdem.org listed in the code cannot be maintained for the time being due to limited energy.
- All code is maintained and released through the git repository https://git.em3d.cn/
+538 -3
查看文件
@@ -1,5 +1,540 @@
# tem3dfdtd-open # 三维瞬变电磁 FDTD 正演程序 (tem3dfdtd)
#### 介绍 [中文](./README.md) | [English](./README.en.md)
请访问https://em3d.cn/ 获取更多信息。
本程序基于 **FDTD(时域有限差分)方法**对三维瞬变电磁(TEM)响应进行正演模拟。核心算法采用 Wang–Hohmann (1993)改进的 Du Fort–Frankel 方法:在 Yee 网格上对磁场 H 迭代求解,通过引入**虚介电常数**保证显式迭代的时间稳定性;采用**共形网格技术**处理起伏地形与任意形状异常体(以表面三角网格描述);支持矩形回线源,可计算地面 TEM 、半航空(SATEM)全航空(ATEM)等模式。
程序的整体框架与三大核心技术分别源于以下工作:
- **整体框架与核心迭代算法**(考虑关断时间的回线源激发 TEM 三维时域有限差分正演,Wang–Hohmann 改进的 Du Fort–Frankel 方法、虚介电常数、含关断时间的源波形),理论内容请见参考文献[1];
- **CPML 吸收边界**(瞬变电磁低频近似 Maxwell 方程的 CPML 吸收边界及施加方法),理论内容请见参考文献[2];
- **共形网格技术**(通过射线追踪方法将任意复杂形状的结构引入到Yee网格计算中),理论内容请见参考文献[3]。
各方法的具体原理、公式推导与实现细节详见文献 [1]–[3],这些文献的作者都是对本开源项目做出突出贡献的人员。
代码结构:`main.f90`(主程序)、`module/`(全局参数与模块)、`lib/`(各功能子程序)。
---
## 目录
- [三维瞬变电磁 FDTD 正演程序 (tem3dfdtd)](#三维瞬变电磁-fdtd-正演程序-tem3dfdtd)
- [目录](#目录)
- [1. 运行环境与编译](#1-运行环境与编译)
- [1.1 环境要求](#11-环境要求)
- [1.2 用 VS2019 编译运行(推荐)](#12-用-vs2019-编译运行推荐)
- [1.3 命令行编译(可选,不建议在Windows下使用)](#13-命令行编译可选不建议在windows下使用)
- [1.4 Linux 环境编译(makefile)](#14-linux-环境编译makefile)
- [2. 程序流程与模块结构](#2-程序流程与模块结构)
- [模块 1:程序控制与参数输入](#模块-1程序控制与参数输入)
- [模块 2:Yee 网格生成](#模块-2yee-网格生成)
- [模块 3:电性参数构建](#模块-3电性参数构建)
- [模块 4:激励源与时间序列](#模块-4激励源与时间序列)
- [模块 5:FDTD 电磁场计算](#模块-5fdtd-电磁场计算)
- [模块 6:输出](#模块-6输出)
- [3. 输入文件格式](#3-输入文件格式)
- [3.1 参数控制文件 input.dat](#31-参数控制文件-inputdat)
- [3.2 地形网格文件 Complex_Terrain](#32-地形网格文件-complex_terrain)
- [3.3 异常体网格文件 Complex_anomalous](#33-异常体网格文件-complex_anomalous)
- [3.4 建模注意事项](#34-建模注意事项)
- [4. CPML 吸收边界](#4-cpml-吸收边界)
- [4.1 实现位置](#41-实现位置)
- [4.2 参数与含义](#42-参数与含义)
- [4.3 使用说明](#43-使用说明)
- [4.4 与 Dirichlet 边界的对比](#44-与-dirichlet-边界的对比)
- [5. 输出文件说明](#5-输出文件说明)
- [6. 衰减曲线快速成图(TEM_decay_plot.py)](#6-衰减曲线快速成图tem_decay_plotpy)
- [6.1 使用方式](#61-使用方式)
- [6.2 主要可调参数(脚本顶部"User parameters"区)](#62-主要可调参数脚本顶部user-parameters区)
- [7. 快速上手(本目录自带算例)](#7-快速上手本目录自带算例)
- [8. 常见问题](#8-常见问题)
- [9. 参考文献](#9-参考文献)
- [10.贡献人员](#10贡献人员)
- [11.声明](#11声明)
---
## 1. 运行环境与编译
### 1.1 环境要求
| 项目 | 要求 |
| -------------- | ------------------------------------------------------------------------ |
| 操作系统 | Windows 10/11(64 位)或 Linux(x86_64),特别推荐使用国产操作系统 deepin 25 |
| 集成环境 | Windows:Visual Studio 2019及以上;Linux/deepin:make; |
| Fortran 编译器 | Intel oneAPI Fortran(ifort/ifx); |
| 并行支持 | OpenMP(多核 CPU 加速);额外的GPU支持在商业版中提供,请访问https://em3d.cn |
### 1.2 用 VS2019 编译运行(推荐)
1. 安装 Visual Studio 2019(勾选"C++ 桌面开发"工作负载)与 Intel oneAPI(安装时勾选
"Intel Fortran Compiler 的 Visual Studio 集成")。
2. 双击打开工程文件 **`tem3dfdtd.sln`**(Intel Fortran 工程,对应
`tem3dfdtd.vfproj`)。工程已包含全部源文件,配置说明:
- `Debug | x64` / `Release | x64`:使用 **ifx** 编译器(oneAPI 默认),**推荐**;
- `Debug | Win32` / `Release | Win32`:使用 ifort 编译器。
3. 选择 **`Release | x64`** 配置,点击 **生成 → 生成解决方案**
4. 运行前准备:程序在工作目录中查找 `input.dat` 及网格文件,因此请将
`input.dat``Complex_Terrain.dat/.stl``Complex_anomalous.dat/.stl` 放到
**tem3dfdtd-open\tem3dfdtd**目录中(或通过"项目属性 → 调试 → 工作目录"指定)。
5. 直接运行 `tem3dfdtd.exe`,或按 F5 调试运行。
> **注意**:程序使用 OpenMP,运行时需要 Intel 的运行时库 `libiomp5md.dll`
> (位于 Intel oneAPI 安装目录 `bin/` 下)。若提示缺少该 DLL,可将它复制到
> exe 同目录(本目录已放置一份),或将其所在目录加入系统 PATH。
### 1.3 命令行编译(可选,不建议在Windows下使用)
在"Intel oneAPI 命令行"环境(oneAPI Command Prompt)下:
```bat
ifx -c -O2 -Qopenmp module\*.f90
ifx -c -O2 -Qopenmp -Qopenmp lib\*.f90 main.f90
ifx -O2 -Qopenmp *.obj -o tem3dfdtd.exe
```
(链接时需要 MSVC 的 link.exe 与 Windows SDK 库,建议直接使用 VS 的"开发人员命令提示符",
并在 PATH 中加入 Intel oneAPI 的 `bin` 目录。)
### 1.4 Linux 环境编译(makefile)
在Linux下编译需要编写 `makefile`文件,请根据操作系统的配置和要求自行编写makefile,并使用make makefile进行编译。
**说明与注意事项**
- 与 Windows 版的差异:Linux 下可执行文件名为自定义,如果没有指定则默认为 `main.exe`,工作目录中同样需要
`input.dat``Complex_Terrain.*``Complex_anomalous.*` 网格文件。
---
## 2. 程序流程与模块结构
主程序执行顺序(`main.f90`):
```
GETDATA → CHECKPARAMETERS → MEMORY_USE_ESTIMATION → ALLOCATEMEMORY
→ GET_NON_UNIFORMGRID → ZERO → GET_COORDINATES
→ Get_Receiver_Gridlabel → RES_CONFIGURE → TIME_SERIOUS
→ Get_eps_r → (Logic_PML=1 时) Get_pml_parameters → Get_mstop
→ GetSourcePosition → Iteration → FREE_MEMORY
```
按功能划分为以下 6 个模块:
### 模块 1:程序控制与参数输入
| 文件 | 功能 |
| ------------------------------- | -------------------------------------------------------------------------- |
| `main.f90` | 主程序,控制整个计算流程 |
| `lib/getdata.f90` | 读取参数控制文件 `input.dat`;检测地形/异常体网格文件的存在性并选择读取格式 |
| `lib/checkparameters.f90` | 将读入的计算参数回显到 `logfile.log`,便于人工检查 |
| `lib/memory-use-estimation.f90` | 根据网格规模估算所需内存并打印提示 |
### 模块 2:Yee 网格生成
| 文件 | 功能 |
| ----------------------------- | -------------------------------------------------------------------------- |
| `lib/allocatememory.f90` | 根据输入参数动态分配所有全局数组(含 CPML 记忆变量数组,仅 `Logic_PML=1` 时) |
| `lib/get_non_uniformgrid.f90` | 生成 x/y/z 三方向的非均匀网格(核心区均匀 + 外围按 1.3 倍递增扩展) |
| `lib/get_coordinates.f90` | 计算各网格节点(含 Yee 节点)的坐标,坐标以源中心为原点 |
| `lib/zero.f90` | 将所有电磁场数组初始化为 0;den\_\* 置 1、c_h_zz 置 0、CPML 记忆变量清零 |
### 模块 3:电性参数构建
| 文件 | 功能 |
| ----------------------------------- | ------------------------------------------------------------------------------------------------------------------------------------------------------------------------------ |
| `lib/resistivity-configuration.f90` | 构建模型电导率:无地形时按背景电导率 + 块状异常体赋值;有地形时调用共形网格;最后将电导率分配到 x/y/z 三个方向的棱边并写出 `conductivity.vtk` |
| `lib/Terrain_conformal.f90` | **地形共形网格**:从 `Complex_Terrain.dat/.stl` 读入地形三角网格,用射线–三角形求交(Möller–Trumbore 算法)沿 x/y/z 三个方向填充每个棱边的等效电导率,处理起伏地形与空气/地层的分界 |
| `lib/Anomalous_conformal.f90` | **异常体共形网格**:从 `Complex_anomalous.dat/.stl` 读入异常体表面网格,采用同样的射线求交方法将异常体电导率(`tao_abnormal`)填充到棱边 |
> **说明**:存在地形文件时,地形分支中空气电导率取 `AIR_CONDUCTIVITY = 1e-6 S/m`,
> 地层电导率取**块状异常体参数中的第 2 个电导率** `TAR_CONDUCTIVITY(2)`(见 input.dat
> 第 9 行起的第二组数据);此时 input.dat 中块状异常体本身不直接生效,而是以 `Complex_anomalous`
> 网格文件描述异常体、以 `tao_abnormal` 赋予其电导率。
### 模块 4:激励源与时间序列
| 文件 | 功能 |
| ----------------------------- | --------------------------------------------------------------------------------------------------------- |
| `lib/time-serious.f90` | 生成整个计算的时间序列(含源波形),并根据 `MAX_OFF_TIME` 校正迭代步数 `NSTOP`;写出 `CTIME_TIXING_UPCOS.DAT` |
| `lib/tixing-source-upcos.f90` | 源波形:**梯形 + 余弦上升**的关断电流波形(常用,`SOURCE_TYPE = 'TIXING_UPCOS'`) |
| `lib/tixing-source.f90` | 纯梯形波形源(`TIXING_RAMP`) |
| `lib/sin-source.f90` | 半正弦波形源(`HALF_SIN`) |
| `lib/triangle-source.f90` | 三角波形源(`TRIANGLE`) |
| `lib/get-eps-r.f90` | 计算虚介电常数 `EPS_R = 3·(Δt/Δx)²/μ₀` 及迭代系数,保证显式 FDTD 稳定 |
| `lib/get-mstop.f90` | 将总迭代过程切成若干"计算分段",每段独立分配缓存,便于内存管理 |
### 模块 5:FDTD 电磁场计算
| 文件 | 功能 |
| --------------------------- | ------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- |
| `lib/GetSourcePosition.f90` | 确定回线源在网格中的位置,标记源所在的棱边(电流赋值区域) |
| `lib/Iteration.f90` | **核心迭代子程序**:按分段循环推进时间步,更新 Ex/Ey/Ez、Hz 场,按源波形加载电流;在每个分段末尾对各接收点计算 Hz(由环绕该点的 8 个节点 Ex、Ey 差商加权得到)并写入结果文件。边界条件按 `Logic_PML` 开关切换:`1` 时在每个场更新中附加 CPML 记忆变量修正,`0` 时恢复原始 Dirichlet(零场)边界 |
| `module/pml-parameters.f90` | **CPML 吸收边界模块**(Roden–Gedney 卷积 PML):σ/α/κ 多项式缩放参数(ma=3、mb=1)、26 个记忆变量 ψ 数组、b*e/c_e 卷积系数数组与 den*\*(=1/κ)缩放数组的声明 |
| `lib/get-pml-paramters.f90` | 构建 x/y/z 六个边界面的 σ/α/κ 分布(多项式从边界向内衰减,E/H 交错采样)及 den\_\* 缩放数组;仅在 `Logic_PML=1` 时由 main 调用 |
### 模块 6:输出
| 文件 | 功能 |
| --------------------------------------------- | --------------------------------------------------- |
| `lib/Iteration.f90`(输出部分) | 写出各接收点响应文件 `dBzdt_1.txt``dBzdt_2.txt` … |
| `lib/resistivity-configuration.f90`(输出部分) | 写出模型电导率分布 `conductivity.vtk` |
| `lib/time-serious.f90`(输出部分) | 写出时间序列 `CTIME_TIXING_UPCOS.DAT` |
| `lib/free-memory.f90` | 计算结束后释放所有动态内存 |
---
## 3. 输入文件格式
程序运行需要以下文件(全部放在 exe 的工作目录中):
| 文件 | 是否必须 | 说明 |
| --------------------------------- | -------------- | ----------------------------------------- |
| `input.dat` | **必须** | 计算参数控制文件 |
| `Complex_anomalous.dat``.stl` | 可选(任选其一) | 异常体表面三角网格;缺省时模型视为均匀背景 |
| `Complex_Terrain.dat``.stl` | 可选(任选其一) | 地形表面三角网格;缺省时不考虑起伏地形 |
### 3.1 参数控制文件 input.dat
**自由格式读取**,按行顺序读取;数值后可加 `!` 注释(可整行注释或行尾注释)。
下面以本目录自带的 `input.dat` 为例逐行说明:
| 行号 | 示例 | 含义 |
| ----- | -------------- | ----------------------------------------------------------------------------------------- |
| 1 | `1` | 计算模式 `CAL_TYPE`:`1` = 地面 TEM,`2` = 半航空(SATEM) |
| 2 | `500` | 发射回线边长 `SourceLength`(m) |
| 3 | `101,101,100` | x、y、z 三个方向的网格数 `NX,NY,NZ` |
| 4 | `1` | **边界条件开关 `Logic_PML`**:`1` = CPML 吸收边界,`0` = 原始非均匀网格 Dirichlet(零场)边界 |
| 5 | `10,10,10` | **PML 层数 `PML_X,PML_Y,PML_Z`**(x、y、z 方向,仅开关=1 时有效;建议 ≥ 5 层) |
| 6 | `25,25` | x 方向:核心均匀网格起始/结束区间编号 `UniGridNumX1,UniGridNumX2` |
| 7 | `25,25` | y 方向:核心均匀网格区间编号 `UniGridNumY1,UniGridNumY2` |
| 8 | `20,30` | z 方向:核心均匀网格区间编号 `UniGridNumZ1,UniGridNumZ2` |
| 9 | `20` | 核心区均匀网格尺寸 `GridSize`(m) |
| 10 | `0.01` | 背景介质电导率 `BACKGROUND_CONDUCTIVITY`(S/m) |
| 11 | `2` | 块状异常体数量 `TEMP_II`(无地形时按棱柱体填充;设 0 表示均匀模型) |
| 12–15 | 见下 | **第 1 个块状异常体参数**,共 4 行 |
| 16–19 | 见下 | **第 2 个块状异常体参数**,共 4 行 |
| 20 | `4000000` | 最大迭代次数 `NSTOP` |
| 21 | `90.101` | 最大计算时间 `MAX_OFF_TIME`(**单位 ms**) |
| 22 | `1e-6,1e-9` | 上升沿持续时间与时间步 `RAISETIME, RAISESTEP`(s) |
| 23 | `60000e-6` | 平台阶段持续时间 `WAVE`(s,即 60 ms) |
| 24 | `1e-7,1e-9` | 下降沿持续时间与时间步 `RAMP, RAMPSTEP`(s) |
| 25 | `1e-9` | 初始时间步 `TIMESTEP`(s) |
| 26 | `1` | 发射电流幅度 `AMP`(A) |
| 27 | `4.0` | 异常体电导率 `tao_abnormal`(S/m,配合 `Complex_anomalous` 文件使用) |
| 28 | `TIXING_UPCOS` | 源类型 `SOURCE_TYPE`:`TIXING_UPCOS` / `TIXING_RAMP` / `HALF_SIN` / `TRIANGLE` |
| 29 | `1` | 接收点数 `Point_Num` |
| 30 | `1` | 第 1 个接收点的编号 |
| 31 | `0,0,0` | 第 1 个接收点坐标(相对源中心,m) |
| 32–33 | `2` / `x,y,z` | (如有多余测点)第 2 个接收点(编号 + 坐标) |
每个**块状异常体**由连续的 4 行组成:
| 行 | 示例 | 含义 |
| --- | ------- | ----------------------------------- |
| ① | `1,101` | x 方向网格起止编号 `TAR_X1, TAR_X2` |
| ② | `1,101` | y 方向网格起止编号 `TAR_Y1, TAR_Y2` |
| ③ | `1,50` | z 方向网格起止编号 `TAR_Z1, TAR_Z2` |
| ④ | `1e-5` | 该块电导率 `TAR_CONDUCTIVITY`(S/m) |
> 本算例用两块"异常体"拼出半空间:第 1 块 z=1~50(空气,1e-5 S/m)+ 第 2 块
> z=51~100(地层,1e-2 S/m)。接收点个数 `Point_Num` 后按每个测点 2 行排列
> (编号 + 相对源中心坐标)。
### 3.2 地形网格文件 Complex_Terrain
地形由**表面三角网格**描述,支持两种格式,文件夹中**只保留其中一个**;
若两个同时存在,程序以 `.dat` 为优先并提示 `.stl` 被忽略。
**格式 1:`Complex_Terrain.dat`(原始文本格式)**
```
Number of Nodes and Elements:
10039 ← 节点总数 n_point
5426 ← 三角形单元总数 n_face
Nodes Coordinates:
1 -21000.0 -21000.0 224.08 ← n_point 行:节点编号, X, Y, Z
2 -21000.0 -20001.8 224.08
... (行中可带 ! 注释)
END Nodes Coordinates
NormalAreaElements:
1 1 2 10039 ← n_face 行:单元编号, 节点1, 节点2, 节点3
...
END NormalAreaElements
```
| 行 | 内容 |
| ------------------- | -------------------------------------------------------------------------- |
| 第 1 行 | 标题行,可任意 |
| 第 2 行 | 节点总数 `n_point` |
| 第 3 行 | 三角形单元总数 `n_face` |
| 第 4 行 | 标题行,可任意 |
| 第 5 ~ 4+n_point 行 | 每个节点一行:`节点编号, X, Y, Z` |
| 其后 1 行 | 区段结束标记 `END Nodes Coordinates`(程序按标题行跳过) |
| 其后 1 行 | 面区标题 `NormalAreaElements:`(程序按标题行跳过) |
| 其后 n_face 行 | 每个单元一行:`单元编号, 节点1编号, 节点2编号, 节点3编号`(节点按逆时针绕向) |
| 末尾 1 行 | 结束标记 `END NormalAreaElements`(程序不读取) |
> 节点区后的两个区段标记行(GiD 导出)与老版本格式的"2 行标题行"位置一致,
> 程序一律按标题行跳过,因此两种写法均兼容。
**格式 2:`Complex_Terrain.stl`(ASCII STL 格式)**
STL文件格式是一种用于描述三维物体表面几何形状的文件格式,广泛应用于快速成型、3D打印和计算机辅助制造(CAM)领域。
STL文件将物体表面细分为一系列小三角形,每个三角形由一个法线向量和三个顶点坐标来定义。
STL文件有两种格式:文本格式(ASCII)和二进制格式。
标准 ASCII STL,单元关键字为 `facet`/`endfacet`,
节点用 `vertex` 行表示,例如下面的格式:
```
facet normal nx ny nz
outer loop
vertex v1x v1y v1z
vertex v2x v2y v2z
vertex v3x v3y v3z
endloop
endfacet
```
用户可以使用常用的CAD软件(如AutoCAD Blender FreeCAD MeshLab SketchUp Gid Maya、3ds Max等)创建和编辑STL文件。
程序读取时自动处理两点(无需用户操作):
1. **顶点去重合并**:STL 中每个面独立写顶点,重复顶点(容差 1e-5)自动合并为唯一节点表;
2. **方向校正**:比较每个面的叉积方向与文件中的 `facet normal`,若相反则交换该面第 2、3
个节点,保证法线方向约定与 `.dat` 格式一致。
### 3.3 异常体网格文件 Complex_anomalous
与地形文件完全相同:`.dat` / `.stl` 两种格式任选其一(同时存在时 `.dat` 优先),
读取方式、去重与方向校正规则均一致;`.dat` 的区段标记行(`END Nodes Coordinates`
`NormalAreaElements:``END NormalAreaElements`)与地形文件一致,同样与程序兼容。
本目录的 `Complex_anomalous.dat` / `.stl` 描述的是**起伏地形下的一个复杂三维异常体**
(2663 个节点、5322 个三角形单元;范围 x ≈ -302 ~ 248 m、y ≈ -197 ~ 176 m、
z ≈ 51 ~ 285 m,嵌入地形面附近)。其电导率由 `input.dat` 第 27 行
`tao_abnormal = 4.0` 指定(低阻体)。
> 网格生成建议:用专业前处理软件建立地形面/异常体表面三角形网格后导出,
> 或选择"导出 → STL"生成 ASCII STL 文件。
### 3.4 建模注意事项
1. **x、y 方向网格数建议设为奇数**,使模型中心(源中心)恰好落在 Yee 网格面中心;
由于磁感应强度 B 定义于网格面中心,`dBz/dt` 测点应**优先布置在 Yee 网格面中心位置**,
以保证测点响应与场定义的对应关系。
2. **发射回线边长应为网格尺寸的奇数倍**,使回线中心落在 Yee 网格棱边位置,保证
源电流棱边与网格棱边严格对位。
3. **采用 Dirichlet 边界(`Logic_PML=0`)时**,网格加密区域(核心均匀区)应**覆盖发射源、
接收测点与异常体范围**,保证上述区域的计算精度,外围大网格用于扩展计算域、减弱
零场边界对结果的影响。
4. **发射源的 z 方向位置默认在 `NZS+1` 处**(`NZS=NZ/2`,即网格中部),由程序自动
确定,无需在输入文件中指定。
5. **全航空(TEM)模拟**:本程序同样支持全航空场景——将上半区设置为空气,并在
源平面以下再多布置若干层空气网格,即可保证发射源与接收测点均处于空气中。
---
## 4. CPML 吸收边界
本程序在 `Logic_PML=1` 时采用 **CPML(卷积完美匹配层, Roden & Gedney 2000)**
作为吸收边界,在计算区域外围吸收向外传播的电磁场,模拟"无限大地层",
避免边界反射污染晚时响应。
### 4.1 实现位置
| 文件 | 作用 |
| ------------------------------------------ | ------------------------------------------------------------------------------------------------------------------------------- |
| `module/pml-parameters.f90` | 参数声明:σ/α/κ 最大值、PML 层数、26 个记忆变量 ψ 数组、卷积系数 `b_e/c_e`、缩放数组 `den_*(=1/κ)`、Hz 的 z 向递归系数 `c_h_zz` |
| `lib/get-pml-paramters.f90` | 构建 x/y/z 六个边界面内 σ/α/κ 的空间分布(多项式由内向外递增,E/H 交错采样)、`den_*` 缩放数组与卷积系数;仅在 `Logic_PML=1` 时调用 |
| `lib/Iteration.f90`(子程序 Iteration_cpml) | 场更新主循环内**内嵌**记忆变量 ψ 的递推与修正项(Ex/Ey/Ez 与 Hx/Hy 共 24 个 ψ);Hz 的 z 方向采用基于 `c_h_zz` 的递归卷积(非 ψ) |
### 4.2 参数与含义
| 参数 | 默认值 | 含义 |
| ------------------- | ----------------------------- | ------------------------------------------ |
| `PML_X,PML_Y,PML_Z` | input.dat 第 5 行(建议 ≥5 层) | 三个方向的 PML 层数 |
| `ma` | 3 | σ 沿厚度方向的多项式阶数(由内向外幂律增长) |
| `mb` | 1 | α 沿厚度方向的多项式阶数 |
| `sig_max` | 1.0e2 | PML 外侧最大电导率(决定吸收强度) |
| `alpha_max` | **1.0e-1** | 复频移因子最大值 |
| `kappa_max` | 1.0 | 坐标拉伸系数最大值(1 表示不拉伸) |
σ、α 沿厚度的空间分布(以 x 方向下层为例,其余边界对称):
```
σ(i) = sig_max · ((Li)/(L1))^ma
α(i) = alpha_max · ((i1)/(L1))^mb
```
E 场采样在整层、H 场采样在半层(交错),因此 H 方向的 σ/α/κ 按半层偏移
(`i0.5`)构造,与 E 方向错开。
### 4.3 使用说明
1. `input.dat` 第 4 行 `Logic_PML=1`,第 5 行给出三个方向的 PML 层数
(如 `15,15,15`);PML 层内网格尺寸应与核心区一致(保持均匀)。
2. **α_max 取 0.1 是关键调参**:α(复频移因子)负责吸收低频扩散场。
若取值过小(如 0.01),晚时段的低频反射场不能及时衰减,会在边界往返
叠加,导致关断后约 10⁻⁵ s 量级出现指数发散(结果为 NaN)——这是
CPML 版最常见的不稳定来源,务必保持 α_max=1.0e-1。
3. 切换回原始边界:第 4 行改为 `0` 即可,行为与旧版本完全一致,无需重新编译。
### 4.4 与 Dirichlet 边界的对比
| | CPML(`Logic_PML=1`) | Dirichlet(`Logic_PML=0`) |
| -------- | --------------------------------- | ------------------------ |
| 边界处理 | 吸收层,模拟无界空间 | 边界处场直接为零 |
| 晚时精度 | 吸收反射,衰减曲线平直 | 边界反射可能污染晚时响应 |
| 计算量 | 每步多 24 个记忆变量递推(约 +30%) | 无额外开销 |
| 网格要求 | PML 层内需均匀网格 | 无特殊要求 |
| 稳定性 | 调参正确时稳定 | 稳定 |
> **一致性验证**:均匀半空间算例(81×81×80 网格、PML 15 层、1 ms 平台、
> 关断后对比)中,CPML 与 Dirichlet 两种边界在关断后早期(场尚未到达边界
> 时)的响应曲线一致,差异 <0.2%(源自两版循环次序不同导致的浮点舍入累积,
> 非物理差异),证明 CPML 实现与主迭代等价、正确。
---
## 5. 输出文件说明
| 文件 | 内容 |
| ------------------------------- | ----------------------------------------------------------------------------------------------------------------- |
| `dBzdt_1.txt`, `dBzdt_2.txt`, … | 每个接收点一个文件。文件头 2 行为说明(测点编号、测点坐标),其后每行 3 列:迭代步数、关断后时间(s)、该时刻磁场响应值 |
| `CTIME_TIXING_UPCOS.DAT` | 计算时间序列,每行 3 列:累计时间、时间步长、源电流幅值(波形) |
| `conductivity.vtk` | 模型电导率分布(规则网格 VTK 格式),可用 ParaView/Tecplot 等打开,检查模型是否正确构建 |
| `logfile.log` | 运行日志:参数回显、格式选择提示、运行错误等 |
| `fort.5141` | 共形网格计算过程的调试输出 |
| `TEM_decay_curve.png` | 衰减曲线图(由第 [6 节](#6-衰减曲线快速成图tem_decay_plotpy)的 `TEM_decay_plot.py` 生成) |
运行结束时屏幕会打印各分段的迭代进度、总计算耗时;正常完成后 `logfile.log`
末尾出现 `Computation finished!`
---
## 6. 衰减曲线快速成图(TEM_decay_plot.py)
程序目录下的 `TEM_decay_plot.py` 用于将正演结果 `dBzdt_*.txt` 快速绘制为
**衰减电压曲线图**(双对数坐标)。
### 6.1 使用方式
```bash
# 需要 numpy 与 matplotlib
pip install numpy matplotlib
# 在计算输出文件(dBzdt_*.txt)所在目录运行
python TEM_decay_plot.py
```
脚本自动搜索脚本同目录下所有 `dBzdt_*.txt` 文件,每个接收点画一条曲线,
测点编号与坐标自动标注在图例中;默认输出高分辨率图片 **`TEM_decay_curve.png`**
(dpi=600)并弹窗显示。
### 6.2 主要可调参数(脚本顶部"User parameters"区)
| 参数 | 默认值 | 说明 |
| ------------------- | --------------------- | ---------------------------------------------------------------- |
| `file_pattern` | `dBzdt_*.txt` | 匹配的结果文件模式 |
| `xmin, xmax` | `1e-6, 1e-1` | 横轴(时间, s)显示范围 |
| `ymin, ymax` | `None, None` | 纵轴(响应)显示范围,`None` 表示自动 |
| `use_abs` | `True` | `True` 画 \|dBz/dt\|(正响应),`False` 画带符号值;纵轴标签随之切换 |
| `savefig` | `True` | 是否保存图片 |
| `save_name` | `TEM_decay_curve.png` | 保存文件名 |
| `dpi` | `600` | 图片分辨率 |
| `label_fontsize` 等 | 18/15/15 | 标签、刻度、图例字号 |
| `linewidth` | `2.5` | 曲线线宽 |
超过 8 条曲线时自动改用顺序蓝色渐变配色,不会循环重复颜色。
> 曲线取值规则:仅绘制 `时间 > 0` 且响应值 > 0 的点(双对数坐标下负值/零值无法显示)。
---
## 7. 快速上手(本目录自带算例)
本目录自带算例:**起伏地形下的复杂三维异常体**(模型 101×101×100 网格、网格尺寸
20 m、源边长 500 m、背景 0.01 S/m、异常体为低阻体 4.0 S/m、1 个测点(源中心正
下方);异常体网格 2663 节点/5322 单元,地形网格 10039 节点/5426 单元)。
运行步骤:
1. 确认目录下存在:`input.dat``Complex_anomalous.dat`(及 `.stl`,描述同一异常体)、
`Complex_Terrain.dat`(及 `.stl`,描述同一地形)。两类文件 `.dat``.stl`
同时存在时,程序以 `.dat` 优先并给出提示。
2. VS2019 打开 `tem3dfdtd.sln` → 选择 `Release | x64` → 生成。
3. 将生成的 exe 复制到本目录(或把输入文件放入 exe 目录)后运行。
4. 观察屏幕输出,正常流程为:
```
Both Complex_anomalous.dat and Complex_anomalous.stl exist! The .dat format takes precedence, the .stl file is ignored.
Both Complex_Terrain.dat and Complex_Terrain.stl exist! The .dat format takes precedence, the .stl file is ignored.
The number of grids in the core area is odd
At least 320M memory is needed!
...
Conformal mesh of terrain is complete!
Ray tracing computation of terrain is complete!
Conformal mesh of terrain is finished
Start conformal processing of the anomalous body
...
Now computing fraction: 1
50 steps have just finished
...
```
5. 计算完成后检查输出文件 `dBzdt_1.txt` 、`conductivity.vtk`。
6. (可选)运行 `python TEM_decay_plot.py` 生成衰减曲线图 `TEM_decay_curve.png`
(见第 [6 节](#6-衰减曲线快速成图tem_decay_plotpy))。
---
## 8. 常见问题
**Q1:运行提示 `libiomp5md.dll` 找不到**
OpenMP 运行时库缺失。将 Intel oneAPI 安装目录 `bin/libiomp5md.dll` 复制到 exe 旁
(或加入 PATH)。
**Q2:提示 `Both Complex_Terrain.dat and Complex_Terrain.stl exist! ...`**
两个格式文件都在。程序以 `.dat` 优先。若想用 STL,请将 `.dat` 文件移走或改名。
**Q3:计算很慢 / 内存不足**
减少 `NX,NY,NZ` 或增大 `GridSize`;控制 `NSTOP`;`MAX_OFF_TIME` 决定实际迭代步数,
程序会以两者中的较小者为准。运行前会打印所需内存估算。
**Q4:如何只算均匀半空间(无异常体、无地形)?**
半空间模型应包含"空气 + 大地"两部分。将 `Complex_anomalous.*` 与
`Complex_Terrain.*` 移走,并在 `input.dat` 中设 `TEMP_II = 2`:第 1 块设为上半部分
(空气,电导率如 `1e-5`),第 2 块设为下半部分(大地,电导率如 `0.01`),即构成
均匀半空间。注意:**`TEMP_II = 0` 时整个模型只填充背景电导率(全空间均匀介质,
不含空气层)**。
**Q5:接收点坐标怎么写?**
坐标是**相对回线源中心**的局部坐标(单位 m),正负方向与坐标轴一致。
**Q6:CPML 吸收边界与原始 Dirichlet 边界怎么选?**
`input.dat` 第 4 行开关 `Logic_PML`:`1` 启用 CPML 吸收边界(第 5 行
`10,10,10` 为三个方向的 PML 层数,可自行调整),能有效吸收边界反射,晚时
(大偏移/晚时间)衰减曲线更平直;`0` 使用原始非均匀网格 Dirichlet(零场)
边界。切换开关无需重新编译。
---
## 9. 参考文献
[1] 孙怀凤, 李貅, 李术才, 等. 考虑关断时间的回线源激发TEM三维时域有限差分正演[J]. 地球物理学报, 2013, 56(3): 1049-1064.
[2] 柳尚斌, 李雪峰, 蓝日彦, 等. 瞬变电磁低频近似Maxwell方程的CPML吸收边界及施加方法[J]. 地球物理学报, 2022, 65(4): 1472-1481.
[3] Li X, Zhao Q, Hu S, et al. Introducing complex geometries to Yee cells in FDTD for transient electromagnetic forward modeling[J]. Geophysics, 2025, 91(2): F1-F12.
## 10.贡献人员
整个项目是在山东大学孙怀凤教授的领导下开展的,主要贡献人员在代码注释、参考文献中已经写明。如需联系请访问 https://faculty.sdu.edu.cn/sun/
除了本开源代码库之外,我们还提供支持GPU高效计算的商业版本软件软件或专用求解器,如果需要,请访问 https://em3d.cn 获取更多信息。
## 11.声明
- 如需联系,请使用sunhuaifeng@email.sdu.edu.cn,不要继续使用代码中标注的gmail邮箱了,因为gmail邮箱经常会出现收发问题,谢谢。
- 代码中列出的tdem.org 由于精力原因暂时无法维护
- 所有代码均通过git仓库进行维护和发布https://git.em3d.cn/
+15 -12
查看文件
@@ -1,9 +1,9 @@
Microsoft Visual Studio Solution File, Format Version 12.00 Microsoft Visual Studio Solution File, Format Version 12.00
# Visual Studio 14 # Visual Studio Version 16
VisualStudioVersion = 14.0.25420.1 VisualStudioVersion = 16.0.35826.135
MinimumVisualStudioVersion = 10.0.40219.1 MinimumVisualStudioVersion = 10.0.40219.1
Project("{6989167D-11E4-40FE-8C1A-2192A86A7E90}") = "tem3dfdtd", "tem3dfdtd\tem3dfdtd.vfproj", "{94A7F592-24DB-4139-B709-699C1B4A8B1A}" Project("{6989167D-11E4-40FE-8C1A-2192A86A7E90}") = "tem3dfdtd", "tem3dfdtd\tem3dfdtd.vfproj", "{3DBB6368-535A-40E7-9413-DBCE77919799}"
EndProject EndProject
Global Global
GlobalSection(SolutionConfigurationPlatforms) = preSolution GlobalSection(SolutionConfigurationPlatforms) = preSolution
@@ -13,16 +13,19 @@ Global
Release|x86 = Release|x86 Release|x86 = Release|x86
EndGlobalSection EndGlobalSection
GlobalSection(ProjectConfigurationPlatforms) = postSolution GlobalSection(ProjectConfigurationPlatforms) = postSolution
{94A7F592-24DB-4139-B709-699C1B4A8B1A}.Debug|x64.ActiveCfg = Debug|x64 {3DBB6368-535A-40E7-9413-DBCE77919799}.Debug|x64.ActiveCfg = Debug|x64
{94A7F592-24DB-4139-B709-699C1B4A8B1A}.Debug|x64.Build.0 = Debug|x64 {3DBB6368-535A-40E7-9413-DBCE77919799}.Debug|x64.Build.0 = Debug|x64
{94A7F592-24DB-4139-B709-699C1B4A8B1A}.Debug|x86.ActiveCfg = Debug|Win32 {3DBB6368-535A-40E7-9413-DBCE77919799}.Debug|x86.ActiveCfg = Debug|Win32
{94A7F592-24DB-4139-B709-699C1B4A8B1A}.Debug|x86.Build.0 = Debug|Win32 {3DBB6368-535A-40E7-9413-DBCE77919799}.Debug|x86.Build.0 = Debug|Win32
{94A7F592-24DB-4139-B709-699C1B4A8B1A}.Release|x64.ActiveCfg = Release|x64 {3DBB6368-535A-40E7-9413-DBCE77919799}.Release|x64.ActiveCfg = Release|x64
{94A7F592-24DB-4139-B709-699C1B4A8B1A}.Release|x64.Build.0 = Release|x64 {3DBB6368-535A-40E7-9413-DBCE77919799}.Release|x64.Build.0 = Release|x64
{94A7F592-24DB-4139-B709-699C1B4A8B1A}.Release|x86.ActiveCfg = Release|Win32 {3DBB6368-535A-40E7-9413-DBCE77919799}.Release|x86.ActiveCfg = Release|Win32
{94A7F592-24DB-4139-B709-699C1B4A8B1A}.Release|x86.Build.0 = Release|Win32 {3DBB6368-535A-40E7-9413-DBCE77919799}.Release|x86.Build.0 = Release|Win32
EndGlobalSection EndGlobalSection
GlobalSection(SolutionProperties) = preSolution GlobalSection(SolutionProperties) = preSolution
HideSolutionNode = FALSE HideSolutionNode = FALSE
EndGlobalSection EndGlobalSection
GlobalSection(ExtensibilityGlobals) = postSolution
SolutionGuid = {7B2BB207-05E9-4A6D-AE34-B78A5A03B2D7}
EndGlobalSection
EndGlobal EndGlobal
文件差异内容过多而无法显示 加载差异
文件差异内容过多而无法显示 加载差异
文件差异内容过多而无法显示 加载差异
文件差异内容过多而无法显示 加载差异
-2
查看文件
@@ -1,2 +0,0 @@
!Copyright (c) 2013 by tdem.org under guide of Xiu Li(lixiu@chd.edu.cn)
!written by Huaifeng Sun(sunhuaifeng@gmail.com) and Xushan Lu(luxushan@gmail.com)
+114
查看文件
@@ -0,0 +1,114 @@
import os
import glob
import numpy as np
import matplotlib.pyplot as plt
from matplotlib.colors import LinearSegmentedColormap
# ==========================
# User parameters
# ==========================
# Read all files matching this pattern in the same directory as this script
file_pattern = "dBzdt_*.txt"
label_fontsize = 18
tick_fontsize = 15
legend_fontsize = 15
linewidth = 2.5
xmin = 1e-6
xmax = 1e-1
ymin = None
ymax = None
use_abs = True
figsize = (8, 6)
savefig = True
save_name = "TEM_decay_curve.png"
dpi = 600
# ==========================
# Colors
# ==========================
# Fixed-order categorical palette (colorblind-safe, validated).
# For more than 8 series, a sequential blue ramp is used instead of cycling.
PALETTE = ["#2a78d6", "#eb6834", "#1baf7a", "#eda100",
"#e87ba4", "#008300", "#4a3aa7", "#e34948"]
RAMP_HEX = ["#86b6ef", "#5598e7", "#3987e5", "#2a78d6",
"#256abf", "#1c5cab", "#184f95", "#104281"]
def series_color(i, n):
"""Color for the i-th series of n (fixed order, never cycled)."""
if n <= len(PALETTE):
return PALETTE[i]
cmap = LinearSegmentedColormap.from_list("seq_blue", RAMP_HEX)
return cmap(i / (n - 1))
# ==========================
# Read data
# ==========================
script_dir = os.path.dirname(os.path.abspath(__file__))
files = sorted(glob.glob(os.path.join(script_dir, file_pattern)))
if not files:
raise FileNotFoundError(
f"No files matching '{file_pattern}' in {script_dir}")
if use_abs:
ylabel = r"$|dB_z/dt|$ (V/A)"
else:
ylabel = r"$dB_z/dt$ (V/A)"
plt.figure(figsize=figsize)
for i, filename in enumerate(files):
# Header: line 1 = point name, line 2 = receiver coordinates (x, y, z)
with open(filename) as f:
point_name = f.readline().strip()
coords = [float(v) for v in f.readline().split()]
x, y, z = coords
label = f"{point_name} ({x:g}, {y:g}, {z:g}) m"
data = np.loadtxt(filename, skiprows=2)
time = data[:, 1]
dbdt = data[:, 2]
if use_abs:
dbdt_plot = np.abs(dbdt)
else:
dbdt_plot = dbdt
mask = (time > 0) & (dbdt_plot > 0)
plt.loglog(time[mask], dbdt_plot[mask], linewidth=linewidth,
color=series_color(i, len(files)), label=label)
# ==========================
# Plot
# ==========================
plt.xlabel("Time (s)", fontsize=label_fontsize)
plt.ylabel(ylabel, fontsize=label_fontsize)
plt.xticks(fontsize=tick_fontsize)
plt.yticks(fontsize=tick_fontsize)
plt.grid(True, which="both", linestyle="--", alpha=0.4)
if xmin is not None or xmax is not None:
plt.xlim(xmin, xmax)
if ymin is not None or ymax is not None:
plt.ylim(ymin, ymax)
plt.legend(fontsize=legend_fontsize)
plt.tight_layout()
if savefig:
plt.savefig(os.path.join(script_dir, save_name), dpi=dpi)
plt.show()
文件差异内容过多而无法显示 加载差异
+2
查看文件
@@ -0,0 +1,2 @@
point_1
0.000000000000000E+000 0.000000000000000E+000 0.000000000000000E+000
+17
查看文件
@@ -1 +1,18 @@
this folder is used to store the examples! this folder is used to store the examples!
# 专门为开源地球物理学校准备的算例:
- ex1 均匀半空间模型
- ex2 均匀半空间中包含一个低阻球体模型
- ex3 起伏地形下包含复杂异常体的模型
## 在每个算例文件夹下的:
| 文件 | 内容 |
| ------------------------------------------- | -------------------------------------------------------------------------------------------------------------------------------------------------------------------- |
| input???.dat | 代表输入文件,其中Dirichlet代表采用Dirichlet边界条件,PML代表采用PML吸收边界条件,运行时将输入文件放入**tem3dfdtd-open\tem3dfdtd**目录中,并将文件名修改为 input.dat |
| Complex_anomalous.dat Complex_anomalous.stl | 代表复杂异常体文件 |
| Complex_Terrain.txt Complex_Terrain.stl | 代表复杂地形体文件 |
| 文件夹 | 代表计算结果 |
> 所有算例请参考使用
文件差异内容过多而无法显示 加载差异
@@ -0,0 +1,940 @@
# vtk DataFile Version 3.0
Version 3.0 VTK file
ASCII
DATASET UNSTRUCTURED_GRID
POINTS 330 double
1.0000000000000000 1.0000000000000000 1.0000000000000000
2.0000000000000000 1.0000000000000000 1.0000000000000000
3.0000000000000000 1.0000000000000000 1.0000000000000000
4.0000000000000000 1.0000000000000000 1.0000000000000000
5.0000000000000000 1.0000000000000000 1.0000000000000000
1.0000000000000000 2.0000000000000000 1.0000000000000000
2.0000000000000000 2.0000000000000000 1.0000000000000000
3.0000000000000000 2.0000000000000000 1.0000000000000000
4.0000000000000000 2.0000000000000000 1.0000000000000000
5.0000000000000000 2.0000000000000000 1.0000000000000000
1.0000000000000000 3.0000000000000000 1.0000000000000000
2.0000000000000000 3.0000000000000000 1.0000000000000000
3.0000000000000000 3.0000000000000000 1.0000000000000000
4.0000000000000000 3.0000000000000000 1.0000000000000000
5.0000000000000000 3.0000000000000000 1.0000000000000000
1.0000000000000000 4.0000000000000000 1.0000000000000000
2.0000000000000000 4.0000000000000000 1.0000000000000000
3.0000000000000000 4.0000000000000000 1.0000000000000000
4.0000000000000000 4.0000000000000000 1.0000000000000000
5.0000000000000000 4.0000000000000000 1.0000000000000000
1.0000000000000000 5.0000000000000000 1.0000000000000000
2.0000000000000000 5.0000000000000000 1.0000000000000000
3.0000000000000000 5.0000000000000000 1.0000000000000000
4.0000000000000000 5.0000000000000000 1.0000000000000000
5.0000000000000000 5.0000000000000000 1.0000000000000000
1.0000000000000000 6.0000000000000000 1.0000000000000000
2.0000000000000000 6.0000000000000000 1.0000000000000000
3.0000000000000000 6.0000000000000000 1.0000000000000000
4.0000000000000000 6.0000000000000000 1.0000000000000000
5.0000000000000000 6.0000000000000000 1.0000000000000000
1.0000000000000000 1.0000000000000000 2.0000000000000000
2.0000000000000000 1.0000000000000000 2.0000000000000000
3.0000000000000000 1.0000000000000000 2.0000000000000000
4.0000000000000000 1.0000000000000000 2.0000000000000000
5.0000000000000000 1.0000000000000000 2.0000000000000000
1.0000000000000000 2.0000000000000000 2.0000000000000000
2.0000000000000000 2.0000000000000000 2.0000000000000000
3.0000000000000000 2.0000000000000000 2.0000000000000000
4.0000000000000000 2.0000000000000000 2.0000000000000000
5.0000000000000000 2.0000000000000000 2.0000000000000000
1.0000000000000000 3.0000000000000000 2.0000000000000000
2.0000000000000000 3.0000000000000000 2.0000000000000000
3.0000000000000000 3.0000000000000000 2.0000000000000000
4.0000000000000000 3.0000000000000000 2.0000000000000000
5.0000000000000000 3.0000000000000000 2.0000000000000000
1.0000000000000000 4.0000000000000000 2.0000000000000000
2.0000000000000000 4.0000000000000000 2.0000000000000000
3.0000000000000000 4.0000000000000000 2.0000000000000000
4.0000000000000000 4.0000000000000000 2.0000000000000000
5.0000000000000000 4.0000000000000000 2.0000000000000000
1.0000000000000000 5.0000000000000000 2.0000000000000000
2.0000000000000000 5.0000000000000000 2.0000000000000000
3.0000000000000000 5.0000000000000000 2.0000000000000000
4.0000000000000000 5.0000000000000000 2.0000000000000000
5.0000000000000000 5.0000000000000000 2.0000000000000000
1.0000000000000000 6.0000000000000000 2.0000000000000000
2.0000000000000000 6.0000000000000000 2.0000000000000000
3.0000000000000000 6.0000000000000000 2.0000000000000000
4.0000000000000000 6.0000000000000000 2.0000000000000000
5.0000000000000000 6.0000000000000000 2.0000000000000000
1.0000000000000000 1.0000000000000000 3.0000000000000000
2.0000000000000000 1.0000000000000000 3.0000000000000000
3.0000000000000000 1.0000000000000000 3.0000000000000000
4.0000000000000000 1.0000000000000000 3.0000000000000000
5.0000000000000000 1.0000000000000000 3.0000000000000000
1.0000000000000000 2.0000000000000000 3.0000000000000000
2.0000000000000000 2.0000000000000000 3.0000000000000000
3.0000000000000000 2.0000000000000000 3.0000000000000000
4.0000000000000000 2.0000000000000000 3.0000000000000000
5.0000000000000000 2.0000000000000000 3.0000000000000000
1.0000000000000000 3.0000000000000000 3.0000000000000000
2.0000000000000000 3.0000000000000000 3.0000000000000000
3.0000000000000000 3.0000000000000000 3.0000000000000000
4.0000000000000000 3.0000000000000000 3.0000000000000000
5.0000000000000000 3.0000000000000000 3.0000000000000000
1.0000000000000000 4.0000000000000000 3.0000000000000000
2.0000000000000000 4.0000000000000000 3.0000000000000000
3.0000000000000000 4.0000000000000000 3.0000000000000000
4.0000000000000000 4.0000000000000000 3.0000000000000000
5.0000000000000000 4.0000000000000000 3.0000000000000000
1.0000000000000000 5.0000000000000000 3.0000000000000000
2.0000000000000000 5.0000000000000000 3.0000000000000000
3.0000000000000000 5.0000000000000000 3.0000000000000000
4.0000000000000000 5.0000000000000000 3.0000000000000000
5.0000000000000000 5.0000000000000000 3.0000000000000000
1.0000000000000000 6.0000000000000000 3.0000000000000000
2.0000000000000000 6.0000000000000000 3.0000000000000000
3.0000000000000000 6.0000000000000000 3.0000000000000000
4.0000000000000000 6.0000000000000000 3.0000000000000000
5.0000000000000000 6.0000000000000000 3.0000000000000000
1.0000000000000000 1.0000000000000000 4.0000000000000000
2.0000000000000000 1.0000000000000000 4.0000000000000000
3.0000000000000000 1.0000000000000000 4.0000000000000000
4.0000000000000000 1.0000000000000000 4.0000000000000000
5.0000000000000000 1.0000000000000000 4.0000000000000000
1.0000000000000000 2.0000000000000000 4.0000000000000000
2.0000000000000000 2.0000000000000000 4.0000000000000000
3.0000000000000000 2.0000000000000000 4.0000000000000000
4.0000000000000000 2.0000000000000000 4.0000000000000000
5.0000000000000000 2.0000000000000000 4.0000000000000000
1.0000000000000000 3.0000000000000000 4.0000000000000000
2.0000000000000000 3.0000000000000000 4.0000000000000000
3.0000000000000000 3.0000000000000000 4.0000000000000000
4.0000000000000000 3.0000000000000000 4.0000000000000000
5.0000000000000000 3.0000000000000000 4.0000000000000000
1.0000000000000000 4.0000000000000000 4.0000000000000000
2.0000000000000000 4.0000000000000000 4.0000000000000000
3.0000000000000000 4.0000000000000000 4.0000000000000000
4.0000000000000000 4.0000000000000000 4.0000000000000000
5.0000000000000000 4.0000000000000000 4.0000000000000000
1.0000000000000000 5.0000000000000000 4.0000000000000000
2.0000000000000000 5.0000000000000000 4.0000000000000000
3.0000000000000000 5.0000000000000000 4.0000000000000000
4.0000000000000000 5.0000000000000000 4.0000000000000000
5.0000000000000000 5.0000000000000000 4.0000000000000000
1.0000000000000000 6.0000000000000000 4.0000000000000000
2.0000000000000000 6.0000000000000000 4.0000000000000000
3.0000000000000000 6.0000000000000000 4.0000000000000000
4.0000000000000000 6.0000000000000000 4.0000000000000000
5.0000000000000000 6.0000000000000000 4.0000000000000000
1.0000000000000000 1.0000000000000000 5.0000000000000000
2.0000000000000000 1.0000000000000000 5.0000000000000000
3.0000000000000000 1.0000000000000000 5.0000000000000000
4.0000000000000000 1.0000000000000000 5.0000000000000000
5.0000000000000000 1.0000000000000000 5.0000000000000000
1.0000000000000000 2.0000000000000000 5.0000000000000000
2.0000000000000000 2.0000000000000000 5.0000000000000000
3.0000000000000000 2.0000000000000000 5.0000000000000000
4.0000000000000000 2.0000000000000000 5.0000000000000000
5.0000000000000000 2.0000000000000000 5.0000000000000000
1.0000000000000000 3.0000000000000000 5.0000000000000000
2.0000000000000000 3.0000000000000000 5.0000000000000000
3.0000000000000000 3.0000000000000000 5.0000000000000000
4.0000000000000000 3.0000000000000000 5.0000000000000000
5.0000000000000000 3.0000000000000000 5.0000000000000000
1.0000000000000000 4.0000000000000000 5.0000000000000000
2.0000000000000000 4.0000000000000000 5.0000000000000000
3.0000000000000000 4.0000000000000000 5.0000000000000000
4.0000000000000000 4.0000000000000000 5.0000000000000000
5.0000000000000000 4.0000000000000000 5.0000000000000000
1.0000000000000000 5.0000000000000000 5.0000000000000000
2.0000000000000000 5.0000000000000000 5.0000000000000000
3.0000000000000000 5.0000000000000000 5.0000000000000000
4.0000000000000000 5.0000000000000000 5.0000000000000000
5.0000000000000000 5.0000000000000000 5.0000000000000000
1.0000000000000000 6.0000000000000000 5.0000000000000000
2.0000000000000000 6.0000000000000000 5.0000000000000000
3.0000000000000000 6.0000000000000000 5.0000000000000000
4.0000000000000000 6.0000000000000000 5.0000000000000000
5.0000000000000000 6.0000000000000000 5.0000000000000000
1.0000000000000000 1.0000000000000000 6.0000000000000000
2.0000000000000000 1.0000000000000000 6.0000000000000000
3.0000000000000000 1.0000000000000000 6.0000000000000000
4.0000000000000000 1.0000000000000000 6.0000000000000000
5.0000000000000000 1.0000000000000000 6.0000000000000000
1.0000000000000000 2.0000000000000000 6.0000000000000000
2.0000000000000000 2.0000000000000000 6.0000000000000000
3.0000000000000000 2.0000000000000000 6.0000000000000000
4.0000000000000000 2.0000000000000000 6.0000000000000000
5.0000000000000000 2.0000000000000000 6.0000000000000000
1.0000000000000000 3.0000000000000000 6.0000000000000000
2.0000000000000000 3.0000000000000000 6.0000000000000000
3.0000000000000000 3.0000000000000000 6.0000000000000000
4.0000000000000000 3.0000000000000000 6.0000000000000000
5.0000000000000000 3.0000000000000000 6.0000000000000000
1.0000000000000000 4.0000000000000000 6.0000000000000000
2.0000000000000000 4.0000000000000000 6.0000000000000000
3.0000000000000000 4.0000000000000000 6.0000000000000000
4.0000000000000000 4.0000000000000000 6.0000000000000000
5.0000000000000000 4.0000000000000000 6.0000000000000000
1.0000000000000000 5.0000000000000000 6.0000000000000000
2.0000000000000000 5.0000000000000000 6.0000000000000000
3.0000000000000000 5.0000000000000000 6.0000000000000000
4.0000000000000000 5.0000000000000000 6.0000000000000000
5.0000000000000000 5.0000000000000000 6.0000000000000000
1.0000000000000000 6.0000000000000000 6.0000000000000000
2.0000000000000000 6.0000000000000000 6.0000000000000000
3.0000000000000000 6.0000000000000000 6.0000000000000000
4.0000000000000000 6.0000000000000000 6.0000000000000000
5.0000000000000000 6.0000000000000000 6.0000000000000000
1.0000000000000000 1.0000000000000000 7.0000000000000000
2.0000000000000000 1.0000000000000000 7.0000000000000000
3.0000000000000000 1.0000000000000000 7.0000000000000000
4.0000000000000000 1.0000000000000000 7.0000000000000000
5.0000000000000000 1.0000000000000000 7.0000000000000000
1.0000000000000000 2.0000000000000000 7.0000000000000000
2.0000000000000000 2.0000000000000000 7.0000000000000000
3.0000000000000000 2.0000000000000000 7.0000000000000000
4.0000000000000000 2.0000000000000000 7.0000000000000000
5.0000000000000000 2.0000000000000000 7.0000000000000000
1.0000000000000000 3.0000000000000000 7.0000000000000000
2.0000000000000000 3.0000000000000000 7.0000000000000000
3.0000000000000000 3.0000000000000000 7.0000000000000000
4.0000000000000000 3.0000000000000000 7.0000000000000000
5.0000000000000000 3.0000000000000000 7.0000000000000000
1.0000000000000000 4.0000000000000000 7.0000000000000000
2.0000000000000000 4.0000000000000000 7.0000000000000000
3.0000000000000000 4.0000000000000000 7.0000000000000000
4.0000000000000000 4.0000000000000000 7.0000000000000000
5.0000000000000000 4.0000000000000000 7.0000000000000000
1.0000000000000000 5.0000000000000000 7.0000000000000000
2.0000000000000000 5.0000000000000000 7.0000000000000000
3.0000000000000000 5.0000000000000000 7.0000000000000000
4.0000000000000000 5.0000000000000000 7.0000000000000000
5.0000000000000000 5.0000000000000000 7.0000000000000000
1.0000000000000000 6.0000000000000000 7.0000000000000000
2.0000000000000000 6.0000000000000000 7.0000000000000000
3.0000000000000000 6.0000000000000000 7.0000000000000000
4.0000000000000000 6.0000000000000000 7.0000000000000000
5.0000000000000000 6.0000000000000000 7.0000000000000000
1.0000000000000000 1.0000000000000000 8.0000000000000000
2.0000000000000000 1.0000000000000000 8.0000000000000000
3.0000000000000000 1.0000000000000000 8.0000000000000000
4.0000000000000000 1.0000000000000000 8.0000000000000000
5.0000000000000000 1.0000000000000000 8.0000000000000000
1.0000000000000000 2.0000000000000000 8.0000000000000000
2.0000000000000000 2.0000000000000000 8.0000000000000000
3.0000000000000000 2.0000000000000000 8.0000000000000000
4.0000000000000000 2.0000000000000000 8.0000000000000000
5.0000000000000000 2.0000000000000000 8.0000000000000000
1.0000000000000000 3.0000000000000000 8.0000000000000000
2.0000000000000000 3.0000000000000000 8.0000000000000000
3.0000000000000000 3.0000000000000000 8.0000000000000000
4.0000000000000000 3.0000000000000000 8.0000000000000000
5.0000000000000000 3.0000000000000000 8.0000000000000000
1.0000000000000000 4.0000000000000000 8.0000000000000000
2.0000000000000000 4.0000000000000000 8.0000000000000000
3.0000000000000000 4.0000000000000000 8.0000000000000000
4.0000000000000000 4.0000000000000000 8.0000000000000000
5.0000000000000000 4.0000000000000000 8.0000000000000000
1.0000000000000000 5.0000000000000000 8.0000000000000000
2.0000000000000000 5.0000000000000000 8.0000000000000000
3.0000000000000000 5.0000000000000000 8.0000000000000000
4.0000000000000000 5.0000000000000000 8.0000000000000000
5.0000000000000000 5.0000000000000000 8.0000000000000000
1.0000000000000000 6.0000000000000000 8.0000000000000000
2.0000000000000000 6.0000000000000000 8.0000000000000000
3.0000000000000000 6.0000000000000000 8.0000000000000000
4.0000000000000000 6.0000000000000000 8.0000000000000000
5.0000000000000000 6.0000000000000000 8.0000000000000000
1.0000000000000000 1.0000000000000000 9.0000000000000000
2.0000000000000000 1.0000000000000000 9.0000000000000000
3.0000000000000000 1.0000000000000000 9.0000000000000000
4.0000000000000000 1.0000000000000000 9.0000000000000000
5.0000000000000000 1.0000000000000000 9.0000000000000000
1.0000000000000000 2.0000000000000000 9.0000000000000000
2.0000000000000000 2.0000000000000000 9.0000000000000000
3.0000000000000000 2.0000000000000000 9.0000000000000000
4.0000000000000000 2.0000000000000000 9.0000000000000000
5.0000000000000000 2.0000000000000000 9.0000000000000000
1.0000000000000000 3.0000000000000000 9.0000000000000000
2.0000000000000000 3.0000000000000000 9.0000000000000000
3.0000000000000000 3.0000000000000000 9.0000000000000000
4.0000000000000000 3.0000000000000000 9.0000000000000000
5.0000000000000000 3.0000000000000000 9.0000000000000000
1.0000000000000000 4.0000000000000000 9.0000000000000000
2.0000000000000000 4.0000000000000000 9.0000000000000000
3.0000000000000000 4.0000000000000000 9.0000000000000000
4.0000000000000000 4.0000000000000000 9.0000000000000000
5.0000000000000000 4.0000000000000000 9.0000000000000000
1.0000000000000000 5.0000000000000000 9.0000000000000000
2.0000000000000000 5.0000000000000000 9.0000000000000000
3.0000000000000000 5.0000000000000000 9.0000000000000000
4.0000000000000000 5.0000000000000000 9.0000000000000000
5.0000000000000000 5.0000000000000000 9.0000000000000000
1.0000000000000000 6.0000000000000000 9.0000000000000000
2.0000000000000000 6.0000000000000000 9.0000000000000000
3.0000000000000000 6.0000000000000000 9.0000000000000000
4.0000000000000000 6.0000000000000000 9.0000000000000000
5.0000000000000000 6.0000000000000000 9.0000000000000000
1.0000000000000000 1.0000000000000000 10.0000000000000000
2.0000000000000000 1.0000000000000000 10.0000000000000000
3.0000000000000000 1.0000000000000000 10.0000000000000000
4.0000000000000000 1.0000000000000000 10.0000000000000000
5.0000000000000000 1.0000000000000000 10.0000000000000000
1.0000000000000000 2.0000000000000000 10.0000000000000000
2.0000000000000000 2.0000000000000000 10.0000000000000000
3.0000000000000000 2.0000000000000000 10.0000000000000000
4.0000000000000000 2.0000000000000000 10.0000000000000000
5.0000000000000000 2.0000000000000000 10.0000000000000000
1.0000000000000000 3.0000000000000000 10.0000000000000000
2.0000000000000000 3.0000000000000000 10.0000000000000000
3.0000000000000000 3.0000000000000000 10.0000000000000000
4.0000000000000000 3.0000000000000000 10.0000000000000000
5.0000000000000000 3.0000000000000000 10.0000000000000000
1.0000000000000000 4.0000000000000000 10.0000000000000000
2.0000000000000000 4.0000000000000000 10.0000000000000000
3.0000000000000000 4.0000000000000000 10.0000000000000000
4.0000000000000000 4.0000000000000000 10.0000000000000000
5.0000000000000000 4.0000000000000000 10.0000000000000000
1.0000000000000000 5.0000000000000000 10.0000000000000000
2.0000000000000000 5.0000000000000000 10.0000000000000000
3.0000000000000000 5.0000000000000000 10.0000000000000000
4.0000000000000000 5.0000000000000000 10.0000000000000000
5.0000000000000000 5.0000000000000000 10.0000000000000000
1.0000000000000000 6.0000000000000000 10.0000000000000000
2.0000000000000000 6.0000000000000000 10.0000000000000000
3.0000000000000000 6.0000000000000000 10.0000000000000000
4.0000000000000000 6.0000000000000000 10.0000000000000000
5.0000000000000000 6.0000000000000000 10.0000000000000000
1.0000000000000000 1.0000000000000000 11.0000000000000000
2.0000000000000000 1.0000000000000000 11.0000000000000000
3.0000000000000000 1.0000000000000000 11.0000000000000000
4.0000000000000000 1.0000000000000000 11.0000000000000000
5.0000000000000000 1.0000000000000000 11.0000000000000000
1.0000000000000000 2.0000000000000000 11.0000000000000000
2.0000000000000000 2.0000000000000000 11.0000000000000000
3.0000000000000000 2.0000000000000000 11.0000000000000000
4.0000000000000000 2.0000000000000000 11.0000000000000000
5.0000000000000000 2.0000000000000000 11.0000000000000000
1.0000000000000000 3.0000000000000000 11.0000000000000000
2.0000000000000000 3.0000000000000000 11.0000000000000000
3.0000000000000000 3.0000000000000000 11.0000000000000000
4.0000000000000000 3.0000000000000000 11.0000000000000000
5.0000000000000000 3.0000000000000000 11.0000000000000000
1.0000000000000000 4.0000000000000000 11.0000000000000000
2.0000000000000000 4.0000000000000000 11.0000000000000000
3.0000000000000000 4.0000000000000000 11.0000000000000000
4.0000000000000000 4.0000000000000000 11.0000000000000000
5.0000000000000000 4.0000000000000000 11.0000000000000000
1.0000000000000000 5.0000000000000000 11.0000000000000000
2.0000000000000000 5.0000000000000000 11.0000000000000000
3.0000000000000000 5.0000000000000000 11.0000000000000000
4.0000000000000000 5.0000000000000000 11.0000000000000000
5.0000000000000000 5.0000000000000000 11.0000000000000000
1.0000000000000000 6.0000000000000000 11.0000000000000000
2.0000000000000000 6.0000000000000000 11.0000000000000000
3.0000000000000000 6.0000000000000000 11.0000000000000000
4.0000000000000000 6.0000000000000000 11.0000000000000000
5.0000000000000000 6.0000000000000000 11.0000000000000000
CELLS 200 1800
8 0 1 5 6 30 31 35 36
8 1 2 6 7 31 32 36 37
8 2 3 7 8 32 33 37 38
8 3 4 8 9 33 34 38 39
8 5 6 10 11 35 36 40 41
8 6 7 11 12 36 37 41 42
8 7 8 12 13 37 38 42 43
8 8 9 13 14 38 39 43 44
8 10 11 15 16 40 41 45 46
8 11 12 16 17 41 42 46 47
8 12 13 17 18 42 43 47 48
8 13 14 18 19 43 44 48 49
8 15 16 20 21 45 46 50 51
8 16 17 21 22 46 47 51 52
8 17 18 22 23 47 48 52 53
8 18 19 23 24 48 49 53 54
8 20 21 25 26 50 51 55 56
8 21 22 26 27 51 52 56 57
8 22 23 27 28 52 53 57 58
8 23 24 28 29 53 54 58 59
8 30 31 35 36 60 61 65 66
8 31 32 36 37 61 62 66 67
8 32 33 37 38 62 63 67 68
8 33 34 38 39 63 64 68 69
8 35 36 40 41 65 66 70 71
8 36 37 41 42 66 67 71 72
8 37 38 42 43 67 68 72 73
8 38 39 43 44 68 69 73 74
8 40 41 45 46 70 71 75 76
8 41 42 46 47 71 72 76 77
8 42 43 47 48 72 73 77 78
8 43 44 48 49 73 74 78 79
8 45 46 50 51 75 76 80 81
8 46 47 51 52 76 77 81 82
8 47 48 52 53 77 78 82 83
8 48 49 53 54 78 79 83 84
8 50 51 55 56 80 81 85 86
8 51 52 56 57 81 82 86 87
8 52 53 57 58 82 83 87 88
8 53 54 58 59 83 84 88 89
8 60 61 65 66 90 91 95 96
8 61 62 66 67 91 92 96 97
8 62 63 67 68 92 93 97 98
8 63 64 68 69 93 94 98 99
8 65 66 70 71 95 96 100 101
8 66 67 71 72 96 97 101 102
8 67 68 72 73 97 98 102 103
8 68 69 73 74 98 99 103 104
8 70 71 75 76 100 101 105 106
8 71 72 76 77 101 102 106 107
8 72 73 77 78 102 103 107 108
8 73 74 78 79 103 104 108 109
8 75 76 80 81 105 106 110 111
8 76 77 81 82 106 107 111 112
8 77 78 82 83 107 108 112 113
8 78 79 83 84 108 109 113 114
8 80 81 85 86 110 111 115 116
8 81 82 86 87 111 112 116 117
8 82 83 87 88 112 113 117 118
8 83 84 88 89 113 114 118 119
8 90 91 95 96 120 121 125 126
8 91 92 96 97 121 122 126 127
8 92 93 97 98 122 123 127 128
8 93 94 98 99 123 124 128 129
8 95 96 100 101 125 126 130 131
8 96 97 101 102 126 127 131 132
8 97 98 102 103 127 128 132 133
8 98 99 103 104 128 129 133 134
8 100 101 105 106 130 131 135 136
8 101 102 106 107 131 132 136 137
8 102 103 107 108 132 133 137 138
8 103 104 108 109 133 134 138 139
8 105 106 110 111 135 136 140 141
8 106 107 111 112 136 137 141 142
8 107 108 112 113 137 138 142 143
8 108 109 113 114 138 139 143 144
8 110 111 115 116 140 141 145 146
8 111 112 116 117 141 142 146 147
8 112 113 117 118 142 143 147 148
8 113 114 118 119 143 144 148 149
8 120 121 125 126 150 151 155 156
8 121 122 126 127 151 152 156 157
8 122 123 127 128 152 153 157 158
8 123 124 128 129 153 154 158 159
8 125 126 130 131 155 156 160 161
8 126 127 131 132 156 157 161 162
8 127 128 132 133 157 158 162 163
8 128 129 133 134 158 159 163 164
8 130 131 135 136 160 161 165 166
8 131 132 136 137 161 162 166 167
8 132 133 137 138 162 163 167 168
8 133 134 138 139 163 164 168 169
8 135 136 140 141 165 166 170 171
8 136 137 141 142 166 167 171 172
8 137 138 142 143 167 168 172 173
8 138 139 143 144 168 169 173 174
8 140 141 145 146 170 171 175 176
8 141 142 146 147 171 172 176 177
8 142 143 147 148 172 173 177 178
8 143 144 148 149 173 174 178 179
8 150 151 155 156 180 181 185 186
8 151 152 156 157 181 182 186 187
8 152 153 157 158 182 183 187 188
8 153 154 158 159 183 184 188 189
8 155 156 160 161 185 186 190 191
8 156 157 161 162 186 187 191 192
8 157 158 162 163 187 188 192 193
8 158 159 163 164 188 189 193 194
8 160 161 165 166 190 191 195 196
8 161 162 166 167 191 192 196 197
8 162 163 167 168 192 193 197 198
8 163 164 168 169 193 194 198 199
8 165 166 170 171 195 196 200 201
8 166 167 171 172 196 197 201 202
8 167 168 172 173 197 198 202 203
8 168 169 173 174 198 199 203 204
8 170 171 175 176 200 201 205 206
8 171 172 176 177 201 202 206 207
8 172 173 177 178 202 203 207 208
8 173 174 178 179 203 204 208 209
8 180 181 185 186 210 211 215 216
8 181 182 186 187 211 212 216 217
8 182 183 187 188 212 213 217 218
8 183 184 188 189 213 214 218 219
8 185 186 190 191 215 216 220 221
8 186 187 191 192 216 217 221 222
8 187 188 192 193 217 218 222 223
8 188 189 193 194 218 219 223 224
8 190 191 195 196 220 221 225 226
8 191 192 196 197 221 222 226 227
8 192 193 197 198 222 223 227 228
8 193 194 198 199 223 224 228 229
8 195 196 200 201 225 226 230 231
8 196 197 201 202 226 227 231 232
8 197 198 202 203 227 228 232 233
8 198 199 203 204 228 229 233 234
8 200 201 205 206 230 231 235 236
8 201 202 206 207 231 232 236 237
8 202 203 207 208 232 233 237 238
8 203 204 208 209 233 234 238 239
8 210 211 215 216 240 241 245 246
8 211 212 216 217 241 242 246 247
8 212 213 217 218 242 243 247 248
8 213 214 218 219 243 244 248 249
8 215 216 220 221 245 246 250 251
8 216 217 221 222 246 247 251 252
8 217 218 222 223 247 248 252 253
8 218 219 223 224 248 249 253 254
8 220 221 225 226 250 251 255 256
8 221 222 226 227 251 252 256 257
8 222 223 227 228 252 253 257 258
8 223 224 228 229 253 254 258 259
8 225 226 230 231 255 256 260 261
8 226 227 231 232 256 257 261 262
8 227 228 232 233 257 258 262 263
8 228 229 233 234 258 259 263 264
8 230 231 235 236 260 261 265 266
8 231 232 236 237 261 262 266 267
8 232 233 237 238 262 263 267 268
8 233 234 238 239 263 264 268 269
8 240 241 245 246 270 271 275 276
8 241 242 246 247 271 272 276 277
8 242 243 247 248 272 273 277 278
8 243 244 248 249 273 274 278 279
8 245 246 250 251 275 276 280 281
8 246 247 251 252 276 277 281 282
8 247 248 252 253 277 278 282 283
8 248 249 253 254 278 279 283 284
8 250 251 255 256 280 281 285 286
8 251 252 256 257 281 282 286 287
8 252 253 257 258 282 283 287 288
8 253 254 258 259 283 284 288 289
8 255 256 260 261 285 286 290 291
8 256 257 261 262 286 287 291 292
8 257 258 262 263 287 288 292 293
8 258 259 263 264 288 289 293 294
8 260 261 265 266 290 291 295 296
8 261 262 266 267 291 292 296 297
8 262 263 267 268 292 293 297 298
8 263 264 268 269 293 294 298 299
8 270 271 275 276 300 301 305 306
8 271 272 276 277 301 302 306 307
8 272 273 277 278 302 303 307 308
8 273 274 278 279 303 304 308 309
8 275 276 280 281 305 306 310 311
8 276 277 281 282 306 307 311 312
8 277 278 282 283 307 308 312 313
8 278 279 283 284 308 309 313 314
8 280 281 285 286 310 311 315 316
8 281 282 286 287 311 312 316 317
8 282 283 287 288 312 313 317 318
8 283 284 288 289 313 314 318 319
8 285 286 290 291 315 316 320 321
8 286 287 291 292 316 317 321 322
8 287 288 292 293 317 318 322 323
8 288 289 293 294 318 319 323 324
8 290 291 295 296 320 321 325 326
8 291 292 296 297 321 322 326 327
8 292 293 297 298 322 323 327 328
8 293 294 298 299 323 324 328 329
CELL_TYPES 200
11
11
11
11
11
11
11
11
11
11
11
11
11
11
11
11
11
11
11
11
11
11
11
11
11
11
11
11
11
11
11
11
11
11
11
11
11
11
11
11
11
11
11
11
11
11
11
11
11
11
11
11
11
11
11
11
11
11
11
11
11
11
11
11
11
11
11
11
11
11
11
11
11
11
11
11
11
11
11
11
11
11
11
11
11
11
11
11
11
11
11
11
11
11
11
11
11
11
11
11
11
11
11
11
11
11
11
11
11
11
11
11
11
11
11
11
11
11
11
11
11
11
11
11
11
11
11
11
11
11
11
11
11
11
11
11
11
11
11
11
11
11
11
11
11
11
11
11
11
11
11
11
11
11
11
11
11
11
11
11
11
11
11
11
11
11
11
11
11
11
11
11
11
11
11
11
11
11
11
11
11
11
11
11
11
11
11
11
11
11
11
11
11
11
11
11
11
11
11
11
CELL_DATA 200
SCALARS conductivity double 1
LOOKUP_TABLE Table
0.0000100000000000
0.0000100000000000
0.0000100000000000
0.0000100000000000
0.0000100000000000
0.0000100000000000
0.0000100000000000
0.0000100000000000
0.0000100000000000
0.0000100000000000
0.0000100000000000
0.0000100000000000
0.0000100000000000
0.0000100000000000
0.0000100000000000
0.0000100000000000
0.0000100000000000
0.0000100000000000
0.0000100000000000
0.0000100000000000
0.0000100000000000
0.0000100000000000
0.0000100000000000
0.0000100000000000
0.0000100000000000
0.0000100000000000
0.0000100000000000
0.0000100000000000
0.0000100000000000
0.0000100000000000
0.0000100000000000
0.0000100000000000
0.0000100000000000
0.0000100000000000
0.0000100000000000
0.0000100000000000
0.0000100000000000
0.0000100000000000
0.0000100000000000
0.0000100000000000
0.0050050000000000
0.0050050000000000
0.0050050000000000
0.0050050000000000
0.0050050000000000
0.0050050000000000
0.0050050000000000
0.0050050000000000
0.0050050000000000
0.0050050000000000
0.0050050000000000
0.0050050000000000
0.0050050000000000
0.0050050000000000
0.0050050000000000
0.0050050000000000
0.0050050000000000
0.0050050000000000
0.0050050000000000
0.0050050000000000
0.0100000000000000
0.0100000000000000
0.0100000000000000
0.0100000000000000
0.0100000000000000
0.0100000000000000
0.0100000000000000
0.0100000000000000
0.0100000000000000
0.0100000000000000
0.0100000000000000
0.0100000000000000
0.0100000000000000
0.0100000000000000
0.0100000000000000
0.0100000000000000
0.0100000000000000
0.0100000000000000
0.0100000000000000
0.0100000000000000
0.0100000000000000
0.0100000000000000
0.0100000000000000
0.0100000000000000
0.0100000000000000
0.0100000000000000
0.0100000000000000
0.0100000000000000
0.0100000000000000
0.0100000000000000
0.0100000000000000
0.0100000000000000
0.0100000000000000
0.0100000000000000
0.0100000000000000
0.0100000000000000
0.0100000000000000
0.0100000000000000
0.0100000000000000
0.0100000000000000
0.0100000000000000
0.0100000000000000
0.0100000000000000
0.0100000000000000
0.0100000000000000
0.0100000000000000
0.0100000000000000
0.0100000000000000
0.0100000000000000
0.0100000000000000
0.0100000000000000
0.0100000000000000
0.0100000000000000
0.0100000000000000
0.0100000000000000
0.0100000000000000
0.0100000000000000
0.0100000000000000
0.0100000000000000
0.0100000000000000
0.0100000000000000
0.0100000000000000
0.0100000000000000
0.0100000000000000
0.0100000000000000
0.0100000000000000
0.0100000000000000
0.0100000000000000
0.0100000000000000
0.0100000000000000
0.0100000000000000
0.0100000000000000
0.0100000000000000
0.0100000000000000
0.0100000000000000
0.0100000000000000
0.0100000000000000
0.0100000000000000
0.0100000000000000
0.0100000000000000
0.0100000000000000
0.0100000000000000
0.0100000000000000
0.0100000000000000
0.0100000000000000
0.0100000000000000
0.0100000000000000
0.0100000000000000
0.0100000000000000
0.0100000000000000
0.0100000000000000
0.0100000000000000
0.0100000000000000
0.0100000000000000
0.0100000000000000
0.0100000000000000
0.0100000000000000
0.0100000000000000
0.0100000000000000
0.0100000000000000
0.0100000000000000
0.0100000000000000
0.0100000000000000
0.0100000000000000
0.0100000000000000
0.0100000000000000
0.0100000000000000
0.0100000000000000
0.0100000000000000
0.0100000000000000
0.0100000000000000
0.0100000000000000
0.0100000000000000
0.0100000000000000
0.0100000000000000
0.0100000000000000
0.0100000000000000
0.0100000000000000
0.0100000000000000
0.0100000000000000
0.0100000000000000
0.0100000000000000
0.0100000000000000
0.0100000000000000
0.0100000000000000
0.0100000000000000
0.0100000000000000
0.0100000000000000
0.0100000000000000
0.0100000000000000
0.0100000000000000
0.0100000000000000
0.0100000000000000
0.0100000000000000
0.0100000000000000
0.0100000000000000
0.0100000000000000
0.0100000000000000
0.0100000000000000
0.0100000000000000
文件差异内容过多而无法显示 加载差异
文件差异内容过多而无法显示 加载差异
@@ -0,0 +1,33 @@
1 ! 1-Ground TEM;2-SATEM
500 ! 回线源尺寸
101,101,100 ! x、y、z网格数量
0 ! 边界条件开关:1=CPML吸收边界,0=原始非均匀网格Dirichlet边界
10,10,10 ! PML层数(x、y、z方向,仅开关=1时有效)
25,25 ! x方向均匀核心区域范围/数量
25,25 ! y方向均匀核心区域范围/数量
25,25 ! z方向均匀核心区域范围/数量
20 ! 核心均匀网格尺寸
0.01 ! 背景介质电导率(S/m)
2 ! 介质数量
1,101
1,101
1,50
1e-5
1,101
1,101
51,100
1e-2
4000000 ! 最大迭代次数
90.101 ! 最大计算时间
1e-6,1e-9 ! 上升沿时间及时间步
60000e-6 ! 平台阶段持续时间
1e-7,1e-9 ! 下降沿时间及时间步
1e-9 ! 初始时间步
1 ! AMP
2.0 ! The conductivity of abnormal body (When the file Complex_anomalous.dat exists)
TIXING_UPCOS ! source type
2 ! 接收测点数量
1
0,0,0
2
0,0,-20
@@ -0,0 +1,61 @@
0.200000E+02
0.200000E+02
0.200000E+02
0.200000E+02
0.200000E+02
0.200000E+02
0.200000E+02
0.200000E+02
0.200000E+02
0.200000E+02
0.200000E+02
0.200000E+02
0.200000E+02
0.200000E+02
0.200000E+02
0.200000E+02
0.200000E+02
0.200000E+02
0.200000E+02
0.200000E+02
0.200000E+02
0.200000E+02
0.200000E+02
0.200000E+02
0.200000E+02
0.200000E+02
0.200000E+02
0.200000E+02
0.200000E+02
0.200000E+02
0.200000E+02
0.200000E+02
0.200000E+02
0.200000E+02
0.200000E+02
0.200000E+02
0.200000E+02
0.200000E+02
0.200000E+02
0.200000E+02
0.200000E+02
0.200000E+02
0.200000E+02
0.200000E+02
0.200000E+02
0.200000E+02
0.200000E+02
0.200000E+02
0.200000E+02
0.200000E+02
0.200000E+02
0.200000E+02
0.200000E+02
0.200000E+02
0.200000E+02
0.200000E+02
0.200000E+02
0.200000E+02
0.200000E+02
0.200000E+02
0.200000E+02
@@ -0,0 +1,61 @@
0.200000E+02
0.200000E+02
0.200000E+02
0.200000E+02
0.200000E+02
0.200000E+02
0.200000E+02
0.200000E+02
0.200000E+02
0.200000E+02
0.200000E+02
0.200000E+02
0.200000E+02
0.200000E+02
0.200000E+02
0.200000E+02
0.200000E+02
0.200000E+02
0.200000E+02
0.200000E+02
0.200000E+02
0.200000E+02
0.200000E+02
0.200000E+02
0.200000E+02
0.200000E+02
0.200000E+02
0.200000E+02
0.200000E+02
0.200000E+02
0.200000E+02
0.200000E+02
0.200000E+02
0.200000E+02
0.200000E+02
0.200000E+02
0.200000E+02
0.200000E+02
0.200000E+02
0.200000E+02
0.200000E+02
0.200000E+02
0.200000E+02
0.200000E+02
0.200000E+02
0.200000E+02
0.200000E+02
0.200000E+02
0.200000E+02
0.200000E+02
0.200000E+02
0.200000E+02
0.200000E+02
0.200000E+02
0.200000E+02
0.200000E+02
0.200000E+02
0.200000E+02
0.200000E+02
0.200000E+02
0.200000E+02
@@ -0,0 +1,60 @@
0.200000E+02
0.200000E+02
0.200000E+02
0.200000E+02
0.200000E+02
0.200000E+02
0.200000E+02
0.200000E+02
0.200000E+02
0.200000E+02
0.200000E+02
0.200000E+02
0.200000E+02
0.200000E+02
0.200000E+02
0.200000E+02
0.200000E+02
0.200000E+02
0.200000E+02
0.200000E+02
0.200000E+02
0.200000E+02
0.200000E+02
0.200000E+02
0.200000E+02
0.200000E+02
0.200000E+02
0.200000E+02
0.200000E+02
0.200000E+02
0.200000E+02
0.200000E+02
0.200000E+02
0.200000E+02
0.200000E+02
0.200000E+02
0.200000E+02
0.200000E+02
0.200000E+02
0.200000E+02
0.200000E+02
0.200000E+02
0.200000E+02
0.200000E+02
0.200000E+02
0.200000E+02
0.200000E+02
0.200000E+02
0.200000E+02
0.200000E+02
0.200000E+02
0.200000E+02
0.200000E+02
0.200000E+02
0.200000E+02
0.200000E+02
0.200000E+02
0.200000E+02
0.200000E+02
0.200000E+02
文件差异内容过多而无法显示 加载差异
二进制文件未显示。
@@ -0,0 +1,940 @@
# vtk DataFile Version 3.0
Version 3.0 VTK file
ASCII
DATASET UNSTRUCTURED_GRID
POINTS 330 double
1.0000000000000000 1.0000000000000000 1.0000000000000000
2.0000000000000000 1.0000000000000000 1.0000000000000000
3.0000000000000000 1.0000000000000000 1.0000000000000000
4.0000000000000000 1.0000000000000000 1.0000000000000000
5.0000000000000000 1.0000000000000000 1.0000000000000000
1.0000000000000000 2.0000000000000000 1.0000000000000000
2.0000000000000000 2.0000000000000000 1.0000000000000000
3.0000000000000000 2.0000000000000000 1.0000000000000000
4.0000000000000000 2.0000000000000000 1.0000000000000000
5.0000000000000000 2.0000000000000000 1.0000000000000000
1.0000000000000000 3.0000000000000000 1.0000000000000000
2.0000000000000000 3.0000000000000000 1.0000000000000000
3.0000000000000000 3.0000000000000000 1.0000000000000000
4.0000000000000000 3.0000000000000000 1.0000000000000000
5.0000000000000000 3.0000000000000000 1.0000000000000000
1.0000000000000000 4.0000000000000000 1.0000000000000000
2.0000000000000000 4.0000000000000000 1.0000000000000000
3.0000000000000000 4.0000000000000000 1.0000000000000000
4.0000000000000000 4.0000000000000000 1.0000000000000000
5.0000000000000000 4.0000000000000000 1.0000000000000000
1.0000000000000000 5.0000000000000000 1.0000000000000000
2.0000000000000000 5.0000000000000000 1.0000000000000000
3.0000000000000000 5.0000000000000000 1.0000000000000000
4.0000000000000000 5.0000000000000000 1.0000000000000000
5.0000000000000000 5.0000000000000000 1.0000000000000000
1.0000000000000000 6.0000000000000000 1.0000000000000000
2.0000000000000000 6.0000000000000000 1.0000000000000000
3.0000000000000000 6.0000000000000000 1.0000000000000000
4.0000000000000000 6.0000000000000000 1.0000000000000000
5.0000000000000000 6.0000000000000000 1.0000000000000000
1.0000000000000000 1.0000000000000000 2.0000000000000000
2.0000000000000000 1.0000000000000000 2.0000000000000000
3.0000000000000000 1.0000000000000000 2.0000000000000000
4.0000000000000000 1.0000000000000000 2.0000000000000000
5.0000000000000000 1.0000000000000000 2.0000000000000000
1.0000000000000000 2.0000000000000000 2.0000000000000000
2.0000000000000000 2.0000000000000000 2.0000000000000000
3.0000000000000000 2.0000000000000000 2.0000000000000000
4.0000000000000000 2.0000000000000000 2.0000000000000000
5.0000000000000000 2.0000000000000000 2.0000000000000000
1.0000000000000000 3.0000000000000000 2.0000000000000000
2.0000000000000000 3.0000000000000000 2.0000000000000000
3.0000000000000000 3.0000000000000000 2.0000000000000000
4.0000000000000000 3.0000000000000000 2.0000000000000000
5.0000000000000000 3.0000000000000000 2.0000000000000000
1.0000000000000000 4.0000000000000000 2.0000000000000000
2.0000000000000000 4.0000000000000000 2.0000000000000000
3.0000000000000000 4.0000000000000000 2.0000000000000000
4.0000000000000000 4.0000000000000000 2.0000000000000000
5.0000000000000000 4.0000000000000000 2.0000000000000000
1.0000000000000000 5.0000000000000000 2.0000000000000000
2.0000000000000000 5.0000000000000000 2.0000000000000000
3.0000000000000000 5.0000000000000000 2.0000000000000000
4.0000000000000000 5.0000000000000000 2.0000000000000000
5.0000000000000000 5.0000000000000000 2.0000000000000000
1.0000000000000000 6.0000000000000000 2.0000000000000000
2.0000000000000000 6.0000000000000000 2.0000000000000000
3.0000000000000000 6.0000000000000000 2.0000000000000000
4.0000000000000000 6.0000000000000000 2.0000000000000000
5.0000000000000000 6.0000000000000000 2.0000000000000000
1.0000000000000000 1.0000000000000000 3.0000000000000000
2.0000000000000000 1.0000000000000000 3.0000000000000000
3.0000000000000000 1.0000000000000000 3.0000000000000000
4.0000000000000000 1.0000000000000000 3.0000000000000000
5.0000000000000000 1.0000000000000000 3.0000000000000000
1.0000000000000000 2.0000000000000000 3.0000000000000000
2.0000000000000000 2.0000000000000000 3.0000000000000000
3.0000000000000000 2.0000000000000000 3.0000000000000000
4.0000000000000000 2.0000000000000000 3.0000000000000000
5.0000000000000000 2.0000000000000000 3.0000000000000000
1.0000000000000000 3.0000000000000000 3.0000000000000000
2.0000000000000000 3.0000000000000000 3.0000000000000000
3.0000000000000000 3.0000000000000000 3.0000000000000000
4.0000000000000000 3.0000000000000000 3.0000000000000000
5.0000000000000000 3.0000000000000000 3.0000000000000000
1.0000000000000000 4.0000000000000000 3.0000000000000000
2.0000000000000000 4.0000000000000000 3.0000000000000000
3.0000000000000000 4.0000000000000000 3.0000000000000000
4.0000000000000000 4.0000000000000000 3.0000000000000000
5.0000000000000000 4.0000000000000000 3.0000000000000000
1.0000000000000000 5.0000000000000000 3.0000000000000000
2.0000000000000000 5.0000000000000000 3.0000000000000000
3.0000000000000000 5.0000000000000000 3.0000000000000000
4.0000000000000000 5.0000000000000000 3.0000000000000000
5.0000000000000000 5.0000000000000000 3.0000000000000000
1.0000000000000000 6.0000000000000000 3.0000000000000000
2.0000000000000000 6.0000000000000000 3.0000000000000000
3.0000000000000000 6.0000000000000000 3.0000000000000000
4.0000000000000000 6.0000000000000000 3.0000000000000000
5.0000000000000000 6.0000000000000000 3.0000000000000000
1.0000000000000000 1.0000000000000000 4.0000000000000000
2.0000000000000000 1.0000000000000000 4.0000000000000000
3.0000000000000000 1.0000000000000000 4.0000000000000000
4.0000000000000000 1.0000000000000000 4.0000000000000000
5.0000000000000000 1.0000000000000000 4.0000000000000000
1.0000000000000000 2.0000000000000000 4.0000000000000000
2.0000000000000000 2.0000000000000000 4.0000000000000000
3.0000000000000000 2.0000000000000000 4.0000000000000000
4.0000000000000000 2.0000000000000000 4.0000000000000000
5.0000000000000000 2.0000000000000000 4.0000000000000000
1.0000000000000000 3.0000000000000000 4.0000000000000000
2.0000000000000000 3.0000000000000000 4.0000000000000000
3.0000000000000000 3.0000000000000000 4.0000000000000000
4.0000000000000000 3.0000000000000000 4.0000000000000000
5.0000000000000000 3.0000000000000000 4.0000000000000000
1.0000000000000000 4.0000000000000000 4.0000000000000000
2.0000000000000000 4.0000000000000000 4.0000000000000000
3.0000000000000000 4.0000000000000000 4.0000000000000000
4.0000000000000000 4.0000000000000000 4.0000000000000000
5.0000000000000000 4.0000000000000000 4.0000000000000000
1.0000000000000000 5.0000000000000000 4.0000000000000000
2.0000000000000000 5.0000000000000000 4.0000000000000000
3.0000000000000000 5.0000000000000000 4.0000000000000000
4.0000000000000000 5.0000000000000000 4.0000000000000000
5.0000000000000000 5.0000000000000000 4.0000000000000000
1.0000000000000000 6.0000000000000000 4.0000000000000000
2.0000000000000000 6.0000000000000000 4.0000000000000000
3.0000000000000000 6.0000000000000000 4.0000000000000000
4.0000000000000000 6.0000000000000000 4.0000000000000000
5.0000000000000000 6.0000000000000000 4.0000000000000000
1.0000000000000000 1.0000000000000000 5.0000000000000000
2.0000000000000000 1.0000000000000000 5.0000000000000000
3.0000000000000000 1.0000000000000000 5.0000000000000000
4.0000000000000000 1.0000000000000000 5.0000000000000000
5.0000000000000000 1.0000000000000000 5.0000000000000000
1.0000000000000000 2.0000000000000000 5.0000000000000000
2.0000000000000000 2.0000000000000000 5.0000000000000000
3.0000000000000000 2.0000000000000000 5.0000000000000000
4.0000000000000000 2.0000000000000000 5.0000000000000000
5.0000000000000000 2.0000000000000000 5.0000000000000000
1.0000000000000000 3.0000000000000000 5.0000000000000000
2.0000000000000000 3.0000000000000000 5.0000000000000000
3.0000000000000000 3.0000000000000000 5.0000000000000000
4.0000000000000000 3.0000000000000000 5.0000000000000000
5.0000000000000000 3.0000000000000000 5.0000000000000000
1.0000000000000000 4.0000000000000000 5.0000000000000000
2.0000000000000000 4.0000000000000000 5.0000000000000000
3.0000000000000000 4.0000000000000000 5.0000000000000000
4.0000000000000000 4.0000000000000000 5.0000000000000000
5.0000000000000000 4.0000000000000000 5.0000000000000000
1.0000000000000000 5.0000000000000000 5.0000000000000000
2.0000000000000000 5.0000000000000000 5.0000000000000000
3.0000000000000000 5.0000000000000000 5.0000000000000000
4.0000000000000000 5.0000000000000000 5.0000000000000000
5.0000000000000000 5.0000000000000000 5.0000000000000000
1.0000000000000000 6.0000000000000000 5.0000000000000000
2.0000000000000000 6.0000000000000000 5.0000000000000000
3.0000000000000000 6.0000000000000000 5.0000000000000000
4.0000000000000000 6.0000000000000000 5.0000000000000000
5.0000000000000000 6.0000000000000000 5.0000000000000000
1.0000000000000000 1.0000000000000000 6.0000000000000000
2.0000000000000000 1.0000000000000000 6.0000000000000000
3.0000000000000000 1.0000000000000000 6.0000000000000000
4.0000000000000000 1.0000000000000000 6.0000000000000000
5.0000000000000000 1.0000000000000000 6.0000000000000000
1.0000000000000000 2.0000000000000000 6.0000000000000000
2.0000000000000000 2.0000000000000000 6.0000000000000000
3.0000000000000000 2.0000000000000000 6.0000000000000000
4.0000000000000000 2.0000000000000000 6.0000000000000000
5.0000000000000000 2.0000000000000000 6.0000000000000000
1.0000000000000000 3.0000000000000000 6.0000000000000000
2.0000000000000000 3.0000000000000000 6.0000000000000000
3.0000000000000000 3.0000000000000000 6.0000000000000000
4.0000000000000000 3.0000000000000000 6.0000000000000000
5.0000000000000000 3.0000000000000000 6.0000000000000000
1.0000000000000000 4.0000000000000000 6.0000000000000000
2.0000000000000000 4.0000000000000000 6.0000000000000000
3.0000000000000000 4.0000000000000000 6.0000000000000000
4.0000000000000000 4.0000000000000000 6.0000000000000000
5.0000000000000000 4.0000000000000000 6.0000000000000000
1.0000000000000000 5.0000000000000000 6.0000000000000000
2.0000000000000000 5.0000000000000000 6.0000000000000000
3.0000000000000000 5.0000000000000000 6.0000000000000000
4.0000000000000000 5.0000000000000000 6.0000000000000000
5.0000000000000000 5.0000000000000000 6.0000000000000000
1.0000000000000000 6.0000000000000000 6.0000000000000000
2.0000000000000000 6.0000000000000000 6.0000000000000000
3.0000000000000000 6.0000000000000000 6.0000000000000000
4.0000000000000000 6.0000000000000000 6.0000000000000000
5.0000000000000000 6.0000000000000000 6.0000000000000000
1.0000000000000000 1.0000000000000000 7.0000000000000000
2.0000000000000000 1.0000000000000000 7.0000000000000000
3.0000000000000000 1.0000000000000000 7.0000000000000000
4.0000000000000000 1.0000000000000000 7.0000000000000000
5.0000000000000000 1.0000000000000000 7.0000000000000000
1.0000000000000000 2.0000000000000000 7.0000000000000000
2.0000000000000000 2.0000000000000000 7.0000000000000000
3.0000000000000000 2.0000000000000000 7.0000000000000000
4.0000000000000000 2.0000000000000000 7.0000000000000000
5.0000000000000000 2.0000000000000000 7.0000000000000000
1.0000000000000000 3.0000000000000000 7.0000000000000000
2.0000000000000000 3.0000000000000000 7.0000000000000000
3.0000000000000000 3.0000000000000000 7.0000000000000000
4.0000000000000000 3.0000000000000000 7.0000000000000000
5.0000000000000000 3.0000000000000000 7.0000000000000000
1.0000000000000000 4.0000000000000000 7.0000000000000000
2.0000000000000000 4.0000000000000000 7.0000000000000000
3.0000000000000000 4.0000000000000000 7.0000000000000000
4.0000000000000000 4.0000000000000000 7.0000000000000000
5.0000000000000000 4.0000000000000000 7.0000000000000000
1.0000000000000000 5.0000000000000000 7.0000000000000000
2.0000000000000000 5.0000000000000000 7.0000000000000000
3.0000000000000000 5.0000000000000000 7.0000000000000000
4.0000000000000000 5.0000000000000000 7.0000000000000000
5.0000000000000000 5.0000000000000000 7.0000000000000000
1.0000000000000000 6.0000000000000000 7.0000000000000000
2.0000000000000000 6.0000000000000000 7.0000000000000000
3.0000000000000000 6.0000000000000000 7.0000000000000000
4.0000000000000000 6.0000000000000000 7.0000000000000000
5.0000000000000000 6.0000000000000000 7.0000000000000000
1.0000000000000000 1.0000000000000000 8.0000000000000000
2.0000000000000000 1.0000000000000000 8.0000000000000000
3.0000000000000000 1.0000000000000000 8.0000000000000000
4.0000000000000000 1.0000000000000000 8.0000000000000000
5.0000000000000000 1.0000000000000000 8.0000000000000000
1.0000000000000000 2.0000000000000000 8.0000000000000000
2.0000000000000000 2.0000000000000000 8.0000000000000000
3.0000000000000000 2.0000000000000000 8.0000000000000000
4.0000000000000000 2.0000000000000000 8.0000000000000000
5.0000000000000000 2.0000000000000000 8.0000000000000000
1.0000000000000000 3.0000000000000000 8.0000000000000000
2.0000000000000000 3.0000000000000000 8.0000000000000000
3.0000000000000000 3.0000000000000000 8.0000000000000000
4.0000000000000000 3.0000000000000000 8.0000000000000000
5.0000000000000000 3.0000000000000000 8.0000000000000000
1.0000000000000000 4.0000000000000000 8.0000000000000000
2.0000000000000000 4.0000000000000000 8.0000000000000000
3.0000000000000000 4.0000000000000000 8.0000000000000000
4.0000000000000000 4.0000000000000000 8.0000000000000000
5.0000000000000000 4.0000000000000000 8.0000000000000000
1.0000000000000000 5.0000000000000000 8.0000000000000000
2.0000000000000000 5.0000000000000000 8.0000000000000000
3.0000000000000000 5.0000000000000000 8.0000000000000000
4.0000000000000000 5.0000000000000000 8.0000000000000000
5.0000000000000000 5.0000000000000000 8.0000000000000000
1.0000000000000000 6.0000000000000000 8.0000000000000000
2.0000000000000000 6.0000000000000000 8.0000000000000000
3.0000000000000000 6.0000000000000000 8.0000000000000000
4.0000000000000000 6.0000000000000000 8.0000000000000000
5.0000000000000000 6.0000000000000000 8.0000000000000000
1.0000000000000000 1.0000000000000000 9.0000000000000000
2.0000000000000000 1.0000000000000000 9.0000000000000000
3.0000000000000000 1.0000000000000000 9.0000000000000000
4.0000000000000000 1.0000000000000000 9.0000000000000000
5.0000000000000000 1.0000000000000000 9.0000000000000000
1.0000000000000000 2.0000000000000000 9.0000000000000000
2.0000000000000000 2.0000000000000000 9.0000000000000000
3.0000000000000000 2.0000000000000000 9.0000000000000000
4.0000000000000000 2.0000000000000000 9.0000000000000000
5.0000000000000000 2.0000000000000000 9.0000000000000000
1.0000000000000000 3.0000000000000000 9.0000000000000000
2.0000000000000000 3.0000000000000000 9.0000000000000000
3.0000000000000000 3.0000000000000000 9.0000000000000000
4.0000000000000000 3.0000000000000000 9.0000000000000000
5.0000000000000000 3.0000000000000000 9.0000000000000000
1.0000000000000000 4.0000000000000000 9.0000000000000000
2.0000000000000000 4.0000000000000000 9.0000000000000000
3.0000000000000000 4.0000000000000000 9.0000000000000000
4.0000000000000000 4.0000000000000000 9.0000000000000000
5.0000000000000000 4.0000000000000000 9.0000000000000000
1.0000000000000000 5.0000000000000000 9.0000000000000000
2.0000000000000000 5.0000000000000000 9.0000000000000000
3.0000000000000000 5.0000000000000000 9.0000000000000000
4.0000000000000000 5.0000000000000000 9.0000000000000000
5.0000000000000000 5.0000000000000000 9.0000000000000000
1.0000000000000000 6.0000000000000000 9.0000000000000000
2.0000000000000000 6.0000000000000000 9.0000000000000000
3.0000000000000000 6.0000000000000000 9.0000000000000000
4.0000000000000000 6.0000000000000000 9.0000000000000000
5.0000000000000000 6.0000000000000000 9.0000000000000000
1.0000000000000000 1.0000000000000000 10.0000000000000000
2.0000000000000000 1.0000000000000000 10.0000000000000000
3.0000000000000000 1.0000000000000000 10.0000000000000000
4.0000000000000000 1.0000000000000000 10.0000000000000000
5.0000000000000000 1.0000000000000000 10.0000000000000000
1.0000000000000000 2.0000000000000000 10.0000000000000000
2.0000000000000000 2.0000000000000000 10.0000000000000000
3.0000000000000000 2.0000000000000000 10.0000000000000000
4.0000000000000000 2.0000000000000000 10.0000000000000000
5.0000000000000000 2.0000000000000000 10.0000000000000000
1.0000000000000000 3.0000000000000000 10.0000000000000000
2.0000000000000000 3.0000000000000000 10.0000000000000000
3.0000000000000000 3.0000000000000000 10.0000000000000000
4.0000000000000000 3.0000000000000000 10.0000000000000000
5.0000000000000000 3.0000000000000000 10.0000000000000000
1.0000000000000000 4.0000000000000000 10.0000000000000000
2.0000000000000000 4.0000000000000000 10.0000000000000000
3.0000000000000000 4.0000000000000000 10.0000000000000000
4.0000000000000000 4.0000000000000000 10.0000000000000000
5.0000000000000000 4.0000000000000000 10.0000000000000000
1.0000000000000000 5.0000000000000000 10.0000000000000000
2.0000000000000000 5.0000000000000000 10.0000000000000000
3.0000000000000000 5.0000000000000000 10.0000000000000000
4.0000000000000000 5.0000000000000000 10.0000000000000000
5.0000000000000000 5.0000000000000000 10.0000000000000000
1.0000000000000000 6.0000000000000000 10.0000000000000000
2.0000000000000000 6.0000000000000000 10.0000000000000000
3.0000000000000000 6.0000000000000000 10.0000000000000000
4.0000000000000000 6.0000000000000000 10.0000000000000000
5.0000000000000000 6.0000000000000000 10.0000000000000000
1.0000000000000000 1.0000000000000000 11.0000000000000000
2.0000000000000000 1.0000000000000000 11.0000000000000000
3.0000000000000000 1.0000000000000000 11.0000000000000000
4.0000000000000000 1.0000000000000000 11.0000000000000000
5.0000000000000000 1.0000000000000000 11.0000000000000000
1.0000000000000000 2.0000000000000000 11.0000000000000000
2.0000000000000000 2.0000000000000000 11.0000000000000000
3.0000000000000000 2.0000000000000000 11.0000000000000000
4.0000000000000000 2.0000000000000000 11.0000000000000000
5.0000000000000000 2.0000000000000000 11.0000000000000000
1.0000000000000000 3.0000000000000000 11.0000000000000000
2.0000000000000000 3.0000000000000000 11.0000000000000000
3.0000000000000000 3.0000000000000000 11.0000000000000000
4.0000000000000000 3.0000000000000000 11.0000000000000000
5.0000000000000000 3.0000000000000000 11.0000000000000000
1.0000000000000000 4.0000000000000000 11.0000000000000000
2.0000000000000000 4.0000000000000000 11.0000000000000000
3.0000000000000000 4.0000000000000000 11.0000000000000000
4.0000000000000000 4.0000000000000000 11.0000000000000000
5.0000000000000000 4.0000000000000000 11.0000000000000000
1.0000000000000000 5.0000000000000000 11.0000000000000000
2.0000000000000000 5.0000000000000000 11.0000000000000000
3.0000000000000000 5.0000000000000000 11.0000000000000000
4.0000000000000000 5.0000000000000000 11.0000000000000000
5.0000000000000000 5.0000000000000000 11.0000000000000000
1.0000000000000000 6.0000000000000000 11.0000000000000000
2.0000000000000000 6.0000000000000000 11.0000000000000000
3.0000000000000000 6.0000000000000000 11.0000000000000000
4.0000000000000000 6.0000000000000000 11.0000000000000000
5.0000000000000000 6.0000000000000000 11.0000000000000000
CELLS 200 1800
8 0 1 5 6 30 31 35 36
8 1 2 6 7 31 32 36 37
8 2 3 7 8 32 33 37 38
8 3 4 8 9 33 34 38 39
8 5 6 10 11 35 36 40 41
8 6 7 11 12 36 37 41 42
8 7 8 12 13 37 38 42 43
8 8 9 13 14 38 39 43 44
8 10 11 15 16 40 41 45 46
8 11 12 16 17 41 42 46 47
8 12 13 17 18 42 43 47 48
8 13 14 18 19 43 44 48 49
8 15 16 20 21 45 46 50 51
8 16 17 21 22 46 47 51 52
8 17 18 22 23 47 48 52 53
8 18 19 23 24 48 49 53 54
8 20 21 25 26 50 51 55 56
8 21 22 26 27 51 52 56 57
8 22 23 27 28 52 53 57 58
8 23 24 28 29 53 54 58 59
8 30 31 35 36 60 61 65 66
8 31 32 36 37 61 62 66 67
8 32 33 37 38 62 63 67 68
8 33 34 38 39 63 64 68 69
8 35 36 40 41 65 66 70 71
8 36 37 41 42 66 67 71 72
8 37 38 42 43 67 68 72 73
8 38 39 43 44 68 69 73 74
8 40 41 45 46 70 71 75 76
8 41 42 46 47 71 72 76 77
8 42 43 47 48 72 73 77 78
8 43 44 48 49 73 74 78 79
8 45 46 50 51 75 76 80 81
8 46 47 51 52 76 77 81 82
8 47 48 52 53 77 78 82 83
8 48 49 53 54 78 79 83 84
8 50 51 55 56 80 81 85 86
8 51 52 56 57 81 82 86 87
8 52 53 57 58 82 83 87 88
8 53 54 58 59 83 84 88 89
8 60 61 65 66 90 91 95 96
8 61 62 66 67 91 92 96 97
8 62 63 67 68 92 93 97 98
8 63 64 68 69 93 94 98 99
8 65 66 70 71 95 96 100 101
8 66 67 71 72 96 97 101 102
8 67 68 72 73 97 98 102 103
8 68 69 73 74 98 99 103 104
8 70 71 75 76 100 101 105 106
8 71 72 76 77 101 102 106 107
8 72 73 77 78 102 103 107 108
8 73 74 78 79 103 104 108 109
8 75 76 80 81 105 106 110 111
8 76 77 81 82 106 107 111 112
8 77 78 82 83 107 108 112 113
8 78 79 83 84 108 109 113 114
8 80 81 85 86 110 111 115 116
8 81 82 86 87 111 112 116 117
8 82 83 87 88 112 113 117 118
8 83 84 88 89 113 114 118 119
8 90 91 95 96 120 121 125 126
8 91 92 96 97 121 122 126 127
8 92 93 97 98 122 123 127 128
8 93 94 98 99 123 124 128 129
8 95 96 100 101 125 126 130 131
8 96 97 101 102 126 127 131 132
8 97 98 102 103 127 128 132 133
8 98 99 103 104 128 129 133 134
8 100 101 105 106 130 131 135 136
8 101 102 106 107 131 132 136 137
8 102 103 107 108 132 133 137 138
8 103 104 108 109 133 134 138 139
8 105 106 110 111 135 136 140 141
8 106 107 111 112 136 137 141 142
8 107 108 112 113 137 138 142 143
8 108 109 113 114 138 139 143 144
8 110 111 115 116 140 141 145 146
8 111 112 116 117 141 142 146 147
8 112 113 117 118 142 143 147 148
8 113 114 118 119 143 144 148 149
8 120 121 125 126 150 151 155 156
8 121 122 126 127 151 152 156 157
8 122 123 127 128 152 153 157 158
8 123 124 128 129 153 154 158 159
8 125 126 130 131 155 156 160 161
8 126 127 131 132 156 157 161 162
8 127 128 132 133 157 158 162 163
8 128 129 133 134 158 159 163 164
8 130 131 135 136 160 161 165 166
8 131 132 136 137 161 162 166 167
8 132 133 137 138 162 163 167 168
8 133 134 138 139 163 164 168 169
8 135 136 140 141 165 166 170 171
8 136 137 141 142 166 167 171 172
8 137 138 142 143 167 168 172 173
8 138 139 143 144 168 169 173 174
8 140 141 145 146 170 171 175 176
8 141 142 146 147 171 172 176 177
8 142 143 147 148 172 173 177 178
8 143 144 148 149 173 174 178 179
8 150 151 155 156 180 181 185 186
8 151 152 156 157 181 182 186 187
8 152 153 157 158 182 183 187 188
8 153 154 158 159 183 184 188 189
8 155 156 160 161 185 186 190 191
8 156 157 161 162 186 187 191 192
8 157 158 162 163 187 188 192 193
8 158 159 163 164 188 189 193 194
8 160 161 165 166 190 191 195 196
8 161 162 166 167 191 192 196 197
8 162 163 167 168 192 193 197 198
8 163 164 168 169 193 194 198 199
8 165 166 170 171 195 196 200 201
8 166 167 171 172 196 197 201 202
8 167 168 172 173 197 198 202 203
8 168 169 173 174 198 199 203 204
8 170 171 175 176 200 201 205 206
8 171 172 176 177 201 202 206 207
8 172 173 177 178 202 203 207 208
8 173 174 178 179 203 204 208 209
8 180 181 185 186 210 211 215 216
8 181 182 186 187 211 212 216 217
8 182 183 187 188 212 213 217 218
8 183 184 188 189 213 214 218 219
8 185 186 190 191 215 216 220 221
8 186 187 191 192 216 217 221 222
8 187 188 192 193 217 218 222 223
8 188 189 193 194 218 219 223 224
8 190 191 195 196 220 221 225 226
8 191 192 196 197 221 222 226 227
8 192 193 197 198 222 223 227 228
8 193 194 198 199 223 224 228 229
8 195 196 200 201 225 226 230 231
8 196 197 201 202 226 227 231 232
8 197 198 202 203 227 228 232 233
8 198 199 203 204 228 229 233 234
8 200 201 205 206 230 231 235 236
8 201 202 206 207 231 232 236 237
8 202 203 207 208 232 233 237 238
8 203 204 208 209 233 234 238 239
8 210 211 215 216 240 241 245 246
8 211 212 216 217 241 242 246 247
8 212 213 217 218 242 243 247 248
8 213 214 218 219 243 244 248 249
8 215 216 220 221 245 246 250 251
8 216 217 221 222 246 247 251 252
8 217 218 222 223 247 248 252 253
8 218 219 223 224 248 249 253 254
8 220 221 225 226 250 251 255 256
8 221 222 226 227 251 252 256 257
8 222 223 227 228 252 253 257 258
8 223 224 228 229 253 254 258 259
8 225 226 230 231 255 256 260 261
8 226 227 231 232 256 257 261 262
8 227 228 232 233 257 258 262 263
8 228 229 233 234 258 259 263 264
8 230 231 235 236 260 261 265 266
8 231 232 236 237 261 262 266 267
8 232 233 237 238 262 263 267 268
8 233 234 238 239 263 264 268 269
8 240 241 245 246 270 271 275 276
8 241 242 246 247 271 272 276 277
8 242 243 247 248 272 273 277 278
8 243 244 248 249 273 274 278 279
8 245 246 250 251 275 276 280 281
8 246 247 251 252 276 277 281 282
8 247 248 252 253 277 278 282 283
8 248 249 253 254 278 279 283 284
8 250 251 255 256 280 281 285 286
8 251 252 256 257 281 282 286 287
8 252 253 257 258 282 283 287 288
8 253 254 258 259 283 284 288 289
8 255 256 260 261 285 286 290 291
8 256 257 261 262 286 287 291 292
8 257 258 262 263 287 288 292 293
8 258 259 263 264 288 289 293 294
8 260 261 265 266 290 291 295 296
8 261 262 266 267 291 292 296 297
8 262 263 267 268 292 293 297 298
8 263 264 268 269 293 294 298 299
8 270 271 275 276 300 301 305 306
8 271 272 276 277 301 302 306 307
8 272 273 277 278 302 303 307 308
8 273 274 278 279 303 304 308 309
8 275 276 280 281 305 306 310 311
8 276 277 281 282 306 307 311 312
8 277 278 282 283 307 308 312 313
8 278 279 283 284 308 309 313 314
8 280 281 285 286 310 311 315 316
8 281 282 286 287 311 312 316 317
8 282 283 287 288 312 313 317 318
8 283 284 288 289 313 314 318 319
8 285 286 290 291 315 316 320 321
8 286 287 291 292 316 317 321 322
8 287 288 292 293 317 318 322 323
8 288 289 293 294 318 319 323 324
8 290 291 295 296 320 321 325 326
8 291 292 296 297 321 322 326 327
8 292 293 297 298 322 323 327 328
8 293 294 298 299 323 324 328 329
CELL_TYPES 200
11
11
11
11
11
11
11
11
11
11
11
11
11
11
11
11
11
11
11
11
11
11
11
11
11
11
11
11
11
11
11
11
11
11
11
11
11
11
11
11
11
11
11
11
11
11
11
11
11
11
11
11
11
11
11
11
11
11
11
11
11
11
11
11
11
11
11
11
11
11
11
11
11
11
11
11
11
11
11
11
11
11
11
11
11
11
11
11
11
11
11
11
11
11
11
11
11
11
11
11
11
11
11
11
11
11
11
11
11
11
11
11
11
11
11
11
11
11
11
11
11
11
11
11
11
11
11
11
11
11
11
11
11
11
11
11
11
11
11
11
11
11
11
11
11
11
11
11
11
11
11
11
11
11
11
11
11
11
11
11
11
11
11
11
11
11
11
11
11
11
11
11
11
11
11
11
11
11
11
11
11
11
11
11
11
11
11
11
11
11
11
11
11
11
11
11
11
11
11
11
CELL_DATA 200
SCALARS conductivity double 1
LOOKUP_TABLE Table
0.0000100000000000
0.0000100000000000
0.0000100000000000
0.0000100000000000
0.0000100000000000
0.0000100000000000
0.0000100000000000
0.0000100000000000
0.0000100000000000
0.0000100000000000
0.0000100000000000
0.0000100000000000
0.0000100000000000
0.0000100000000000
0.0000100000000000
0.0000100000000000
0.0000100000000000
0.0000100000000000
0.0000100000000000
0.0000100000000000
0.0000100000000000
0.0000100000000000
0.0000100000000000
0.0000100000000000
0.0000100000000000
0.0000100000000000
0.0000100000000000
0.0000100000000000
0.0000100000000000
0.0000100000000000
0.0000100000000000
0.0000100000000000
0.0000100000000000
0.0000100000000000
0.0000100000000000
0.0000100000000000
0.0000100000000000
0.0000100000000000
0.0000100000000000
0.0000100000000000
0.0050050000000000
0.0050050000000000
0.0050050000000000
0.0050050000000000
0.0050050000000000
0.0050050000000000
0.0050050000000000
0.0050050000000000
0.0050050000000000
0.0050050000000000
0.0050050000000000
0.0050050000000000
0.0050050000000000
0.0050050000000000
0.0050050000000000
0.0050050000000000
0.0050050000000000
0.0050050000000000
0.0050050000000000
0.0050050000000000
0.0100000000000000
0.0100000000000000
0.0100000000000000
0.0100000000000000
0.0100000000000000
0.0100000000000000
0.0100000000000000
0.0100000000000000
0.0100000000000000
0.0100000000000000
0.0100000000000000
0.0100000000000000
0.0100000000000000
0.0100000000000000
0.0100000000000000
0.0100000000000000
0.0100000000000000
0.0100000000000000
0.0100000000000000
0.0100000000000000
0.0100000000000000
0.0100000000000000
0.0100000000000000
0.0100000000000000
0.0100000000000000
0.0100000000000000
0.0100000000000000
0.0100000000000000
0.0100000000000000
0.0100000000000000
0.0100000000000000
0.0100000000000000
0.0100000000000000
0.0100000000000000
0.0100000000000000
0.0100000000000000
0.0100000000000000
0.0100000000000000
0.0100000000000000
0.0100000000000000
0.0100000000000000
0.0100000000000000
0.0100000000000000
0.0100000000000000
0.0100000000000000
0.0100000000000000
0.0100000000000000
0.0100000000000000
0.0100000000000000
0.0100000000000000
0.0100000000000000
0.0100000000000000
0.0100000000000000
0.0100000000000000
0.0100000000000000
0.0100000000000000
0.0100000000000000
0.0100000000000000
0.0100000000000000
0.0100000000000000
0.0100000000000000
0.0100000000000000
0.0100000000000000
0.0100000000000000
0.0100000000000000
0.0100000000000000
0.0100000000000000
0.0100000000000000
0.0100000000000000
0.0100000000000000
0.0100000000000000
0.0100000000000000
0.0100000000000000
0.0100000000000000
0.0100000000000000
0.0100000000000000
0.0100000000000000
0.0100000000000000
0.0100000000000000
0.0100000000000000
0.0100000000000000
0.0100000000000000
0.0100000000000000
0.0100000000000000
0.0100000000000000
0.0100000000000000
0.0100000000000000
0.0100000000000000
0.0100000000000000
0.0100000000000000
0.0100000000000000
0.0100000000000000
0.0100000000000000
0.0100000000000000
0.0100000000000000
0.0100000000000000
0.0100000000000000
0.0100000000000000
0.0100000000000000
0.0100000000000000
0.0100000000000000
0.0100000000000000
0.0100000000000000
0.0100000000000000
0.0100000000000000
0.0100000000000000
0.0100000000000000
0.0100000000000000
0.0100000000000000
0.0100000000000000
0.0100000000000000
0.0100000000000000
0.0100000000000000
0.0100000000000000
0.0100000000000000
0.0100000000000000
0.0100000000000000
0.0100000000000000
0.0100000000000000
0.0100000000000000
0.0100000000000000
0.0100000000000000
0.0100000000000000
0.0100000000000000
0.0100000000000000
0.0100000000000000
0.0100000000000000
0.0100000000000000
0.0100000000000000
0.0100000000000000
0.0100000000000000
0.0100000000000000
0.0100000000000000
0.0100000000000000
0.0100000000000000
0.0100000000000000
0.0100000000000000
0.0100000000000000
0.0100000000000000
0.0100000000000000
文件差异内容过多而无法显示 加载差异
文件差异内容过多而无法显示 加载差异
@@ -0,0 +1,33 @@
1 ! 1-Ground TEM;2-SATEM
500 ! 回线源尺寸
61,61,60 ! x、y、z网格数量
1 ! 边界条件开关:1=CPML吸收边界,0=原始非均匀网格Dirichlet边界
10,10,10 ! PML层数(x、y、z方向,仅开关=1时有效)
25,25 ! x方向均匀核心区域范围/数量
25,25 ! y方向均匀核心区域范围/数量
25,25 ! z方向均匀核心区域范围/数量
20 ! 核心均匀网格尺寸
0.01 ! 背景介质电导率(S/m)
2 ! 介质数量
1,61
1,61
1,30
1e-5
1,61
1,61
31,60
1e-2
4000000 ! 最大迭代次数
90.101 ! 最大计算时间
1e-6,1e-9 ! 上升沿时间及时间步
60000e-6 ! 平台阶段持续时间
1e-7,1e-9 ! 下降沿时间及时间步
1e-9 ! 初始时间步
1 ! AMP
2.0 ! The conductivity of abnormal body (When the file Complex_anomalous.dat exists)
TIXING_UPCOS ! source type
2 ! 接收测点数量
1
0,0,0
2
0,0,-20
@@ -0,0 +1,33 @@
1 ! 1-Ground TEM;2-SATEM
500 ! 回线源尺寸
101,101,100 ! x、y、z网格数量
0 ! 边界条件开关:1=CPML吸收边界,0=原始非均匀网格Dirichlet边界
10,10,10 ! PML层数(x、y、z方向,仅开关=1时有效)
25,25 ! x方向均匀核心区域范围/数量
25,25 ! y方向均匀核心区域范围/数量
25,25 ! z方向均匀核心区域范围/数量
20 ! 核心均匀网格尺寸
0.01 ! 背景介质电导率(S/m)
2 ! 介质数量
1,101
1,101
1,50
1e-5
1,101
1,101
51,100
1e-2
4000000 ! 最大迭代次数
90.101 ! 最大计算时间
1e-6,1e-9 ! 上升沿时间及时间步
60000e-6 ! 平台阶段持续时间
1e-7,1e-9 ! 下降沿时间及时间步
1e-9 ! 初始时间步
1 ! AMP
4.0 ! The conductivity of abnormal body (When the file Complex_anomalous.dat exists)
TIXING_UPCOS ! source type
2 ! 接收测点数量
1
0,0,0
2
0,0,-20
@@ -0,0 +1,33 @@
1 ! 1-Ground TEM;2-SATEM
500 ! 回线源尺寸
61,61,60 ! x、y、z网格数量
1 ! 边界条件开关:1=CPML吸收边界,0=原始非均匀网格Dirichlet边界
10,10,10 ! PML层数(x、y、z方向,仅开关=1时有效)
25,25 ! x方向均匀核心区域范围/数量
25,25 ! y方向均匀核心区域范围/数量
25,25 ! z方向均匀核心区域范围/数量
20 ! 核心均匀网格尺寸
0.01 ! 背景介质电导率(S/m)
2 ! 介质数量
1,61
1,61
1,30
1e-5
1,61
1,61
31,60
1e-2
4000000 ! 最大迭代次数
90.101 ! 最大计算时间
1e-6,1e-9 ! 上升沿时间及时间步
60000e-6 ! 平台阶段持续时间
1e-7,1e-9 ! 下降沿时间及时间步
1e-9 ! 初始时间步
1 ! AMP
4.0 ! The conductivity of abnormal body (When the file Complex_anomalous.dat exists)
TIXING_UPCOS ! source type
2 ! 接收测点数量
1
0,0,0
2
0,0,-20
文件差异内容过多而无法显示 加载差异
文件差异内容过多而无法显示 加载差异
@@ -0,0 +1,114 @@
import os
import glob
import numpy as np
import matplotlib.pyplot as plt
from matplotlib.colors import LinearSegmentedColormap
# ==========================
# User parameters
# ==========================
# Read all files matching this pattern in the same directory as this script
file_pattern = "dBzdt_*.txt"
label_fontsize = 18
tick_fontsize = 15
legend_fontsize = 15
linewidth = 2.5
xmin = 1e-6
xmax = 1e-1
ymin = None
ymax = None
use_abs = True
figsize = (8, 6)
savefig = True
save_name = "TEM_decay_curve.png"
dpi = 600
# ==========================
# Colors
# ==========================
# Fixed-order categorical palette (colorblind-safe, validated).
# For more than 8 series, a sequential blue ramp is used instead of cycling.
PALETTE = ["#2a78d6", "#eb6834", "#1baf7a", "#eda100",
"#e87ba4", "#008300", "#4a3aa7", "#e34948"]
RAMP_HEX = ["#86b6ef", "#5598e7", "#3987e5", "#2a78d6",
"#256abf", "#1c5cab", "#184f95", "#104281"]
def series_color(i, n):
"""Color for the i-th series of n (fixed order, never cycled)."""
if n <= len(PALETTE):
return PALETTE[i]
cmap = LinearSegmentedColormap.from_list("seq_blue", RAMP_HEX)
return cmap(i / (n - 1))
# ==========================
# Read data
# ==========================
script_dir = os.path.dirname(os.path.abspath(__file__))
files = sorted(glob.glob(os.path.join(script_dir, file_pattern)))
if not files:
raise FileNotFoundError(
f"No files matching '{file_pattern}' in {script_dir}")
if use_abs:
ylabel = r"$|dB_z/dt|$ (V/A)"
else:
ylabel = r"$dB_z/dt$ (V/A)"
plt.figure(figsize=figsize)
for i, filename in enumerate(files):
# Header: line 1 = point name, line 2 = receiver coordinates (x, y, z)
with open(filename) as f:
point_name = f.readline().strip()
coords = [float(v) for v in f.readline().split()]
x, y, z = coords
label = f"{point_name} ({x:g}, {y:g}, {z:g}) m"
data = np.loadtxt(filename, skiprows=2)
time = data[:, 1]
dbdt = data[:, 2]
if use_abs:
dbdt_plot = np.abs(dbdt)
else:
dbdt_plot = dbdt
mask = (time > 0) & (dbdt_plot > 0)
plt.loglog(time[mask], dbdt_plot[mask], linewidth=linewidth,
color=series_color(i, len(files)), label=label)
# ==========================
# Plot
# ==========================
plt.xlabel("Time (s)", fontsize=label_fontsize)
plt.ylabel(ylabel, fontsize=label_fontsize)
plt.xticks(fontsize=tick_fontsize)
plt.yticks(fontsize=tick_fontsize)
plt.grid(True, which="both", linestyle="--", alpha=0.4)
if xmin is not None or xmax is not None:
plt.xlim(xmin, xmax)
if ymin is not None or ymax is not None:
plt.ylim(ymin, ymax)
plt.legend(fontsize=legend_fontsize)
plt.tight_layout()
if savefig:
plt.savefig(os.path.join(script_dir, save_name), dpi=dpi)
plt.show()
文件差异内容过多而无法显示 加载差异
文件差异内容过多而无法显示 加载差异
文件差异内容过多而无法显示 加载差异
@@ -0,0 +1,35 @@
1 ! 1-Ground TEM;2-SATEM
210 ! 回线源尺寸
121,121,120 ! x、y、z网格数量
0 ! 边界条件开关:1=CPML吸收边界,0=原始非均匀网格Dirichlet边界
10,10,10 ! PML层数(x、y、z方向,仅开关=1时有效)
30,30 ! x方向均匀核心区域范围/数量
30,30 ! y方向均匀核心区域范围/数量
20,30 ! z方向均匀核心区域范围/数量
10 ! 核心均匀网格尺寸
0.01 ! 背景介质电导率(S/m)
2 ! 介质数量
1,121
1,121
1,60
1e-5
1,121
1,121
61,120
1e-2
4000000 ! 最大迭代次数
90.101 ! 最大计算时间
1e-6,1e-9 ! 上升沿时间及时间步
60000e-6 ! 平台阶段持续时间
1e-7,1e-9 ! 下降沿时间及时间步
1e-9 ! 初始时间步
1 ! AMP
2.0 ! The conductivity of abnormal body (When the file Complex_anomalous.dat exists)
TIXING_UPCOS ! source type
3 ! 接收测点数量
1 ! 测点1编号
-60,0,0 ! 测点1坐标
2
-30,0,0
3
0,0,0
文件差异内容过多而无法显示 加载差异
@@ -0,0 +1,61 @@
0.100000E+02
0.100000E+02
0.100000E+02
0.100000E+02
0.100000E+02
0.100000E+02
0.100000E+02
0.100000E+02
0.100000E+02
0.100000E+02
0.100000E+02
0.100000E+02
0.100000E+02
0.100000E+02
0.100000E+02
0.100000E+02
0.100000E+02
0.100000E+02
0.100000E+02
0.100000E+02
0.100000E+02
0.100000E+02
0.100000E+02
0.100000E+02
0.100000E+02
0.100000E+02
0.100000E+02
0.100000E+02
0.100000E+02
0.100000E+02
0.100000E+02
0.100000E+02
0.100000E+02
0.100000E+02
0.100000E+02
0.100000E+02
0.100000E+02
0.100000E+02
0.100000E+02
0.100000E+02
0.100000E+02
0.100000E+02
0.100000E+02
0.100000E+02
0.100000E+02
0.100000E+02
0.100000E+02
0.100000E+02
0.100000E+02
0.100000E+02
0.100000E+02
0.100000E+02
0.100000E+02
0.100000E+02
0.100000E+02
0.100000E+02
0.100000E+02
0.100000E+02
0.100000E+02
0.100000E+02
0.100000E+02
@@ -0,0 +1,61 @@
0.100000E+02
0.100000E+02
0.100000E+02
0.100000E+02
0.100000E+02
0.100000E+02
0.100000E+02
0.100000E+02
0.100000E+02
0.100000E+02
0.100000E+02
0.100000E+02
0.100000E+02
0.100000E+02
0.100000E+02
0.100000E+02
0.100000E+02
0.100000E+02
0.100000E+02
0.100000E+02
0.100000E+02
0.100000E+02
0.100000E+02
0.100000E+02
0.100000E+02
0.100000E+02
0.100000E+02
0.100000E+02
0.100000E+02
0.100000E+02
0.100000E+02
0.100000E+02
0.100000E+02
0.100000E+02
0.100000E+02
0.100000E+02
0.100000E+02
0.100000E+02
0.100000E+02
0.100000E+02
0.100000E+02
0.100000E+02
0.100000E+02
0.100000E+02
0.100000E+02
0.100000E+02
0.100000E+02
0.100000E+02
0.100000E+02
0.100000E+02
0.100000E+02
0.100000E+02
0.100000E+02
0.100000E+02
0.100000E+02
0.100000E+02
0.100000E+02
0.100000E+02
0.100000E+02
0.100000E+02
0.100000E+02
@@ -0,0 +1,60 @@
0.100000E+02
0.100000E+02
0.100000E+02
0.100000E+02
0.100000E+02
0.100000E+02
0.100000E+02
0.100000E+02
0.100000E+02
0.100000E+02
0.100000E+02
0.100000E+02
0.100000E+02
0.100000E+02
0.100000E+02
0.100000E+02
0.100000E+02
0.100000E+02
0.100000E+02
0.100000E+02
0.100000E+02
0.100000E+02
0.100000E+02
0.100000E+02
0.100000E+02
0.100000E+02
0.100000E+02
0.100000E+02
0.100000E+02
0.100000E+02
0.100000E+02
0.100000E+02
0.100000E+02
0.100000E+02
0.100000E+02
0.100000E+02
0.100000E+02
0.100000E+02
0.100000E+02
0.100000E+02
0.100000E+02
0.100000E+02
0.100000E+02
0.100000E+02
0.100000E+02
0.100000E+02
0.100000E+02
0.100000E+02
0.100000E+02
0.100000E+02
0.100000E+02
0.100000E+02
0.100000E+02
0.100000E+02
0.100000E+02
0.100000E+02
0.100000E+02
0.100000E+02
0.100000E+02
0.100000E+02
文件差异内容过多而无法显示 加载差异
@@ -0,0 +1,114 @@
import os
import glob
import numpy as np
import matplotlib.pyplot as plt
from matplotlib.colors import LinearSegmentedColormap
# ==========================
# User parameters
# ==========================
# Read all files matching this pattern in the same directory as this script
file_pattern = "dBzdt_*.txt"
label_fontsize = 18
tick_fontsize = 15
legend_fontsize = 15
linewidth = 2.5
xmin = 1e-6
xmax = 1e-1
ymin = None
ymax = None
use_abs = True
figsize = (8, 6)
savefig = True
save_name = "TEM_decay_curve.png"
dpi = 600
# ==========================
# Colors
# ==========================
# Fixed-order categorical palette (colorblind-safe, validated).
# For more than 8 series, a sequential blue ramp is used instead of cycling.
PALETTE = ["#2a78d6", "#eb6834", "#1baf7a", "#eda100",
"#e87ba4", "#008300", "#4a3aa7", "#e34948"]
RAMP_HEX = ["#86b6ef", "#5598e7", "#3987e5", "#2a78d6",
"#256abf", "#1c5cab", "#184f95", "#104281"]
def series_color(i, n):
"""Color for the i-th series of n (fixed order, never cycled)."""
if n <= len(PALETTE):
return PALETTE[i]
cmap = LinearSegmentedColormap.from_list("seq_blue", RAMP_HEX)
return cmap(i / (n - 1))
# ==========================
# Read data
# ==========================
script_dir = os.path.dirname(os.path.abspath(__file__))
files = sorted(glob.glob(os.path.join(script_dir, file_pattern)))
if not files:
raise FileNotFoundError(
f"No files matching '{file_pattern}' in {script_dir}")
if use_abs:
ylabel = r"$|dB_z/dt|$ (V/A)"
else:
ylabel = r"$dB_z/dt$ (V/A)"
plt.figure(figsize=figsize)
for i, filename in enumerate(files):
# Header: line 1 = point name, line 2 = receiver coordinates (x, y, z)
with open(filename) as f:
point_name = f.readline().strip()
coords = [float(v) for v in f.readline().split()]
x, y, z = coords
label = f"{point_name} ({x:g}, {y:g}, {z:g}) m"
data = np.loadtxt(filename, skiprows=2)
time = data[:, 1]
dbdt = data[:, 2]
if use_abs:
dbdt_plot = np.abs(dbdt)
else:
dbdt_plot = dbdt
mask = (time > 0) & (dbdt_plot > 0)
plt.loglog(time[mask], dbdt_plot[mask], linewidth=linewidth,
color=series_color(i, len(files)), label=label)
# ==========================
# Plot
# ==========================
plt.xlabel("Time (s)", fontsize=label_fontsize)
plt.ylabel(ylabel, fontsize=label_fontsize)
plt.xticks(fontsize=tick_fontsize)
plt.yticks(fontsize=tick_fontsize)
plt.grid(True, which="both", linestyle="--", alpha=0.4)
if xmin is not None or xmax is not None:
plt.xlim(xmin, xmax)
if ymin is not None or ymax is not None:
plt.ylim(ymin, ymax)
plt.legend(fontsize=legend_fontsize)
plt.tight_layout()
if savefig:
plt.savefig(os.path.join(script_dir, save_name), dpi=dpi)
plt.show()
文件差异内容过多而无法显示 加载差异
文件差异内容过多而无法显示 加载差异
文件差异内容过多而无法显示 加载差异
文件差异内容过多而无法显示 加载差异
@@ -0,0 +1,35 @@
1 ! 1-Ground TEM;2-SATEM
210 ! 回线源尺寸
61,61,60 ! x、y、z网格数量
1 ! 边界条件开关:1=CPML吸收边界,0=原始非均匀网格Dirichlet边界
10,10,10 ! PML层数(x、y、z方向,仅开关=1时有效)
30,30 ! x方向均匀核心区域范围/数量
30,30 ! y方向均匀核心区域范围/数量
20,30 ! z方向均匀核心区域范围/数量
10 ! 核心均匀网格尺寸
0.01 ! 背景介质电导率(S/m)
2 ! 介质数量
1,61
1,61
1,30
1e-5
1,61
1,61
31,60
1e-2
4000000 ! 最大迭代次数
90.101 ! 最大计算时间
1e-6,1e-9 ! 上升沿时间及时间步
60000e-6 ! 平台阶段持续时间
1e-7,1e-9 ! 下降沿时间及时间步
1e-9 ! 初始时间步
1 ! AMP
2.0 ! The conductivity of abnormal body (When the file Complex_anomalous.dat exists)
TIXING_UPCOS ! source type
3 ! 接收测点数量
1 ! 测点1编号
-60,0,0 ! 测点1坐标
2
-30,0,0
3
0,0,0
@@ -0,0 +1,35 @@
1 ! 1-Ground TEM;2-SATEM
210 ! 回线源尺寸
121,121,120 ! x、y、z网格数量
0 ! 边界条件开关:1=CPML吸收边界,0=原始非均匀网格Dirichlet边界
10,10,10 ! PML层数(x、y、z方向,仅开关=1时有效)
30,30 ! x方向均匀核心区域范围/数量
30,30 ! y方向均匀核心区域范围/数量
20,30 ! z方向均匀核心区域范围/数量
10 ! 核心均匀网格尺寸
0.01 ! 背景介质电导率(S/m)
2 ! 介质数量
1,121
1,121
1,60
1e-5
1,121
1,121
61,120
1e-2
4000000 ! 最大迭代次数
90.101 ! 最大计算时间
1e-6,1e-9 ! 上升沿时间及时间步
60000e-6 ! 平台阶段持续时间
1e-7,1e-9 ! 下降沿时间及时间步
1e-9 ! 初始时间步
1 ! AMP
2.0 ! The conductivity of abnormal body (When the file Complex_anomalous.dat exists)
TIXING_UPCOS ! source type
3 ! 接收测点数量
1 ! 测点1编号
-60,0,0 ! 测点1坐标
2
-30,0,0
3
0,0,0
@@ -0,0 +1,35 @@
1 ! 1-Ground TEM;2-SATEM
210 ! 回线源尺寸
61,61,60 ! x、y、z网格数量
1 ! 边界条件开关:1=CPML吸收边界,0=原始非均匀网格Dirichlet边界
10,10,10 ! PML层数(x、y、z方向,仅开关=1时有效)
30,30 ! x方向均匀核心区域范围/数量
30,30 ! y方向均匀核心区域范围/数量
20,30 ! z方向均匀核心区域范围/数量
10 ! 核心均匀网格尺寸
0.01 ! 背景介质电导率(S/m)
2 ! 介质数量
1,61
1,61
1,30
1e-5
1,61
1,61
31,60
1e-2
4000000 ! 最大迭代次数
90.101 ! 最大计算时间
1e-6,1e-9 ! 上升沿时间及时间步
60000e-6 ! 平台阶段持续时间
1e-7,1e-9 ! 下降沿时间及时间步
1e-9 ! 初始时间步
1 ! AMP
2.0 ! The conductivity of abnormal body (When the file Complex_anomalous.dat exists)
TIXING_UPCOS ! source type
3 ! 接收测点数量
1 ! 测点1编号
-60,0,0 ! 测点1坐标
2
-30,0,0
3
0,0,0
文件差异内容过多而无法显示 加载差异
文件差异内容过多而无法显示 加载差异
文件差异内容过多而无法显示 加载差异
文件差异内容过多而无法显示 加载差异
文件差异内容过多而无法显示 加载差异
文件差异内容过多而无法显示 加载差异
@@ -0,0 +1,31 @@
1 ! 1-Ground TEM;2-SATEM
500 ! 回线源尺寸
101,101,100 ! x、y、z网格数量
0 ! 边界条件开关:1=CPML吸收边界,0=原始非均匀网格Dirichlet边界
10,10,10 ! PML层数(x、y、z方向,仅开关=1时有效)
25,25 ! x方向均匀核心区域范围/数量
25,25 ! y方向均匀核心区域范围/数量
25,25 ! z方向均匀核心区域范围/数量
20 ! 核心均匀网格尺寸
0.01 ! 背景介质电导率(S/m)
2 ! 介质数量
1,101
1,101
1,50
1e-5
1,101
1,101
51,100
1e-2
4000000 ! 最大迭代次数
90.101 ! 最大计算时间
1e-6,1e-9 ! 上升沿时间及时间步
60000e-6 ! 平台阶段持续时间
1e-7,1e-9 ! 下降沿时间及时间步
1e-9 ! 初始时间步
1 ! AMP
4.0 ! The conductivity of abnormal body (When the file Complex_anomalous.dat exists)
TIXING_UPCOS ! source type
1 ! 接收测点数量
1
0,0,0
文件差异内容过多而无法显示 加载差异
@@ -0,0 +1,31 @@
1 ! 1-Ground TEM;2-SATEM
500 ! 回线源尺寸
101,101,100 ! x、y、z网格数量
0 ! 边界条件开关:1=CPML吸收边界,0=原始非均匀网格Dirichlet边界
10,10,10 ! PML层数(x、y、z方向,仅开关=1时有效)
25,25 ! x方向均匀核心区域范围/数量
25,25 ! y方向均匀核心区域范围/数量
25,25 ! z方向均匀核心区域范围/数量
20 ! 核心均匀网格尺寸
0.01 ! 背景介质电导率(S/m)
2 ! 介质数量
1,101
1,101
1,50
1e-5
1,101
1,101
51,100
1e-2
4000000 ! 最大迭代次数
300.101 ! 最大计算时间
1e-6,1e-9 ! 上升沿时间及时间步
200000e-6 ! 平台阶段持续时间
1e-7,1e-9 ! 下降沿时间及时间步
1e-9 ! 初始时间步
1 ! AMP
4.0 ! The conductivity of abnormal body (When the file Complex_anomalous.dat exists)
TIXING_UPCOS ! source type
1 ! 接收测点数量
1
0,0,0
-64
查看文件
@@ -1,64 +0,0 @@
!the standard input file for TEM calculation.Version 2.0 start to creat @2016-10-30 by Huaifeng Sun
!finishe to creat @
!this is the configuration type for the modeling
!airborne, semi-airborne, ground, surface-borehole, tunnel, marine are the options
#configuration_type:
SEMI
!source length
#source-parameters:
3
!cell numbers in x,y,z directions
!minumun grid size in uniform parts
#cell-parameters:
161,161,160
0.5
!background resistivity
!number if abnormal bodies
!the numbered abnormal body cell range in x diretion,y diretion,z diretion,resistivity
#resistivity-parameters:
0.01
6
1,161,1,161,1,80,1e-4
1,161,1,161,80,81,0.002
1,161,1,161,81,83,0.0033
76,86,76,86,86,92,0.02
76,86,76,86,92,98,0.033
76,86,76,86,98,106,0.05
#n-stop:
3500000
!The maximum computation time, unit of which is ms
!the raise time and its step
!the wave length time
!the ramp time and its step
!timestep
!current in amper
!waveform-type
#waveform-parameters:
30.002
1e-6,1e-9
10000e-6
1e-6,1e-9
1e-7
1
TIXING_UPCOS
!number of flight hight
!flight hight
#flight-parameters:
2
0.5,1
!HE stands for horizontal value,HZ stands for vertical value
!number of survey lines
!start and stop point cell number
#receiver-parameters:
HE
1
66,96
-43
查看文件
@@ -1,43 +0,0 @@
SEMI
3
161,161,160
0.5
0.01
6
1,161
1,161
1,80
1e-4
1,161
1,161
80,81
0.002
1,161
1,161
81,83
0.0033
76,86
76,86
86,92
0.02
76,86
76,86
92,98
0.033
76,86
76,86
98,106
0.05
3500000
30.002
1e-6,1e-9
10000e-6
1e-6,1e-9
1e-7
1
2
0.5,1
TIXING_UPCOS
HE
1
66,96
-99
查看文件
@@ -1,99 +0,0 @@
<?xml version="1.0" encoding="utf-8"?>
<!-- Version 1.0-->
<model>
<!--!this is the configuration type for the modeling-->
<!--!airborne, semi-airborne, ground, surface-borehole,
tunnel, marine are the options-->
<configuration>SEMI</configuration>
<source>
<source_length>3</source_length>
<source_type>loop</source_type>
<current>1.0</current>
<Tx_waveform>TIXING_UPCOS</Tx_waveform>
</source>
<cell>
<x>161</x>
<y>161</y>
<z>160</z>
<mini_size>0.5</mini_size>
</cell>
<!--This is the time parameters in the iteration. -->
<!--the total_time corresponds to the computation time from 0 to the end-->
<time>
<total_time>30.002</total_time >
<raise_time>1e-6,1e-9</raise_time >
<ramp_time>1e-6,1e-9</ramp_time>
<on_time>1.0e-2</on_time>
<off_time_step_max>1.0e-7</off_time_step_max>
<max_stop_iteration>3500000</max_stop_iteration>
</time>
<Rx_parameters>
<num_record_height>2</num_record_height>
<heights>0.5,1</heights>
<rec_flag>HE</rec_flag>
<Rx_lines_num>1</Rx_lines_num>
<Rx_range>66,96</Rx_range>
</Rx_parameters>
<resistivity_parameters>
<background>0.01</background>
<abnormal>
<number>6</number>
<block1>
<x_range>1,161</x_range>
<y_range>1,161</y_range>
<z_range>1,80</z_range>
<conductivity>1e-4</conductivity>
</block1>
<block2>
<x_range>1,161</x_range>
<y_range>1,161</y_range>
<z_range>80,81</z_range>
<conductivity>0.002</conductivity>
</block2>
<block3>
<x_range>1,161</x_range>
<y_range>1,161</y_range>
<z_range>81,83</z_range>
<conductivity>0.0033</conductivity>
</block3>
<block4>
<x_range>76,86</x_range>
<y_range>76,86</y_range>
<z_range>86,92</z_range>
<conductivity>0.02</conductivity>
</block4>
<block5>
<x_range>76,86</x_range>
<y_range>76,86</y_range>
<z_range>82,98</z_range>
<conductivity>0.033</conductivity>
</block5>
<block6>
<x_range>76,86</x_range>
<y_range>76,86</y_range>
<z_range>98,106</z_range>
<conductivity>0.05</conductivity>
</block6>
</abnormal>
</resistivity_parameters>
</model>
+31
查看文件
@@ -0,0 +1,31 @@
1 ! 1-Ground TEM;2-SATEM
500 ! 回线源尺寸
101,101,100 ! x、y、z网格数量
0 ! 边界条件开关:1=CPML吸收边界,0=原始非均匀网格Dirichlet边界
10,10,10 ! PML层数(x、y、z方向,仅开关=1时有效)
25,25 ! x方向均匀核心区域范围/数量
25,25 ! y方向均匀核心区域范围/数量
25,25 ! z方向均匀核心区域范围/数量
20 ! 核心均匀网格尺寸
0.01 ! 背景介质电导率(S/m)
2 ! 介质数量
1,101
1,101
1,50
1e-5
1,101
1,101
51,100
1e-2
4000000 ! 最大迭代次数
300.101 ! 最大计算时间
1e-6,1e-9 ! 上升沿时间及时间步
200000e-6 ! 平台阶段持续时间
1e-7,1e-9 ! 下降沿时间及时间步
1e-9 ! 初始时间步
1 ! AMP
4.0 ! The conductivity of abnormal body (When the file Complex_anomalous.dat exists)
TIXING_UPCOS ! source type
1 ! 接收测点数量
1
0,0,0
+765
查看文件
@@ -0,0 +1,765 @@
!Copyright (c) 2022 by LEEE under guide of Huaifeng Sun(sunhuaifeng@email.sdu.edu.cn)
!written by Xinyu Li(202335098@mail.sdu.edu.cn) and Qi Zhao(zhaoqi_326326@163.com)
SUBROUTINE anomalous_conformal
!This procedure is used to compute anomalous body conformal
USE RES_MODEL_PARAMETER
USE CONSTANTPARAMETERS
use omp_lib
IMPLICIT NONE
CHARACTER(200) FinenameOfAnomalous
CHARACTER(200) print_vert0,print_vert1,print_vert2,Complex_Inclusion_x,Complex_Inclusion_y,Complex_Inclusion_z,temp
CHARACTER(300) :: line !used to read one line of the ASCII STL file
INTEGER(KIND=4)::i,j,k,t,ii,jj,kk,n,i1,i2,i3,j1,j2,j3,k1,k2,k3,l1,l2,l3,i0
INTEGER(KIND=4):: ios_stl,i_face,iv_face,nv_tmp,idx_v,ip_stl
INTEGER(KIND=4), DIMENSION(:,:), ALLOCATABLE :: tmp_face
REAL(KIND=8), DIMENSION(:,:), ALLOCATABLE :: tmp_vert,tmp_norm
REAL(KIND=8):: vx,vy,vz
REAL(KIND=8):: ex1x,ex1y,ex1z,ex2x,ex2y,ex2z,crossx,crossy,crossz
INTEGER(KIND=4)::iz,jz,kz,ix,jx,kx,iy,jy,ky,iii,jjj,kkk
INTEGER(KIND=4)::index_z,index_x,index_y,dex_z,dex_x,dex_y
INTEGER(KIND=4)::num_z,num_x,num_y,dex_dd_z,dex_dd_x,dex_dd_y,dex_max_z,dex_max_x,dex_max_y,dex_d_z,dex_d_x,dex_d_y
REAL(KIND=8)::dist_d_z,dist_d_x,dist_d_y,dist_z,dist_x,dist_y,threshold
INTEGER(KIND=4), DIMENSION(:), ALLOCATABLE :: XX_min,XX_max,YY_min,YY_max,ZZ_min,ZZ_max
REAL(KIND=8), DIMENSION(:), ALLOCATABLE :: coor_z_max,coor_z_min,coor_x_max,coor_x_min,coor_y_max,coor_y_min
TYPE Triangular_Coordinates
INTEGER(KIND=4)::point_number
REAL(KIND=8):: Coord_X,Coord_Y,Coord_Z
END TYPE Triangular_Coordinates
TYPE face
INTEGER(KIND=4)::node_face
TYPE(Triangular_Coordinates) ::node_point1
TYPE(Triangular_Coordinates) ::node_point2
TYPE(Triangular_Coordinates) ::node_point3
END TYPE face
TYPE(face), DIMENSION(:), ALLOCATABLE :: Triangular_face_element
TYPE(Triangular_Coordinates), DIMENSION(:), ALLOCATABLE :: Vert
print*,'Start conformal processing of the anomalous body'
mmx = 0
mmy = 0
mmz = 0
X_max=1
X_min=NXB
Y_max=1
Y_min=NYB
Z_max=1
Z_min=NZB
threshold=1.0e-8
!===============================Read triangle face element information====================================
IF(Logic_AnomalousDat)THEN
!>Original .dat format:
!! Line 1 : "Number of Nodes and Elements:"
!! Line 2 : n_point (number of nodes)
!! Line 3 : n_face (number of triangular elements)
!! Line 4 : "Nodes Coordinates:"
!! next n_point lines : label, Coord_X, Coord_Y, Coord_Z
!! then 2 title lines, then n_face lines : label, node1, node2, node3
FinenameOfAnomalous='Complex_anomalous.dat'
OPEN(20240506,FILE=FinenameOfAnomalous,STATUS='OLD')
Read(20240506, *) temp
Read(20240506, *) n_point !get total number of Node
Read(20240506, *) n_face !get total number of Element
Read(20240506, *) temp
ALLOCATE(Triangular_face_element(n_face))
ALLOCATE(Vert(n_point))
DO j=1,n_point
READ(20240506,*)Vert(j)%point_number,Vert(j)%Coord_X,Vert(j)%Coord_Y,Vert(j)%Coord_Z
ENDDO
Read(20240506,*) temp
Read(20240506,*) temp
DO i=1,n_face
READ(20240506,*)Triangular_face_element(i)%node_face,Triangular_face_element(i)%node_point1%point_number,Triangular_face_element(i)%node_point2%point_number,Triangular_face_element(i)%node_point3%point_number
ENDDO
CLOSE(20240506)
ELSEIF(Logic_AnomalousStl)THEN
!>ASCII STL format:
!! solid <name>
!! facet normal nx ny nz
!! outer loop
!! vertex x y z
!! vertex x y z
!! vertex x y z
!! endloop
!! endfacet
!! ...
!! endsolid <name>
!!In an STL file the vertices are written once per facet, so the duplicated
!!vertices are merged into unique nodes before filling Vert/Triangular_face_element.
!!The vertex order of each facet is also checked against the facet normal so that
!!the normal direction convention is the same as the .dat format.
FinenameOfAnomalous='Complex_anomalous.stl'
OPEN(20240506,FILE=FinenameOfAnomalous,STATUS='OLD')
!>First pass: count the number of facets.
n_face=0
DO
READ(20240506,'(A)',IOSTAT=ios_stl) line
IF(ios_stl/=0) EXIT
!>convert the line into lower case for keyword matching
DO ii=1,LEN_TRIM(line)
IF(line(ii:ii)>='A'.AND.line(ii:ii)<='Z') line(ii:ii)=ACHAR(IACHAR(line(ii:ii))+32)
ENDDO
IF(INDEX(line,'facet')>0 .AND. INDEX(line,'endfacet')==0) n_face=n_face+1
ENDDO
IF(n_face==0)THEN
WRITE(*,*)'Error: no facet is found in Complex_anomalous.stl!'
STOP
ENDIF
REWIND(20240506)
ALLOCATE(tmp_face(3,n_face),tmp_norm(3,n_face),tmp_vert(3,3*n_face))
nv_tmp=0
i_face=0
iv_face=0
DO
READ(20240506,'(A)',IOSTAT=ios_stl) line
IF(ios_stl/=0) EXIT
DO ii=1,LEN_TRIM(line)
IF(line(ii:ii)>='A'.AND.line(ii:ii)<='Z') line(ii:ii)=ACHAR(IACHAR(line(ii:ii))+32)
ENDDO
IF(INDEX(line,'facet')>0 .AND. INDEX(line,'endfacet')==0)THEN
!>a new facet begins
i_face=i_face+1
iv_face=0
IF(INDEX(line,'normal')>0)THEN
READ(line(INDEX(line,'normal')+6:),*,IOSTAT=ios_stl) tmp_norm(1,i_face),tmp_norm(2,i_face),tmp_norm(3,i_face)
IF(ios_stl/=0)THEN
WRITE(*,*)'Error: failed to read the facet normal line in Complex_anomalous.stl!'
STOP
ENDIF
ENDIF
ELSEIF(INDEX(line,'endfacet')>0)THEN
!>a facet is finished, check that it has exactly 3 vertices
IF(iv_face/=3)THEN
WRITE(*,*)'Error: a facet with',iv_face,'vertices (instead of 3) is found in Complex_anomalous.stl!'
STOP
ENDIF
ELSEIF(INDEX(line,'vertex')>0)THEN
iv_face=iv_face+1
IF(iv_face>3)THEN
WRITE(*,*)'Error: a facet with more than 3 vertices is found in Complex_anomalous.stl!'
STOP
ENDIF
READ(line(INDEX(line,'vertex')+6:),*,IOSTAT=ios_stl) vx,vy,vz
IF(ios_stl/=0)THEN
WRITE(*,*)'Error: failed to read a vertex line in Complex_anomalous.stl!'
STOP
ENDIF
!>merge the duplicated vertices
idx_v=0
DO ip_stl=1,nv_tmp
IF(ABS(tmp_vert(1,ip_stl)-vx)<threshold.AND.ABS(tmp_vert(2,ip_stl)-vy)<threshold.AND.ABS(tmp_vert(3,ip_stl)-vz)<threshold)THEN
idx_v=ip_stl
EXIT
ENDIF
ENDDO
IF(idx_v==0)THEN
nv_tmp=nv_tmp+1
tmp_vert(1,nv_tmp)=vx
tmp_vert(2,nv_tmp)=vy
tmp_vert(3,nv_tmp)=vz
idx_v=nv_tmp
ENDIF
tmp_face(iv_face,i_face)=idx_v
ENDIF
ENDDO
!>Correct the vertex order of each facet: compare the cross-product normal
!!with the facet normal stored in the STL file, swap node2/node3 if they
!!point in opposite directions, so that the normal direction convention
!!is the same as in the .dat format.
DO i=1,n_face
ex1x=tmp_vert(1,tmp_face(2,i))-tmp_vert(1,tmp_face(1,i))
ex1y=tmp_vert(2,tmp_face(2,i))-tmp_vert(2,tmp_face(1,i))
ex1z=tmp_vert(3,tmp_face(2,i))-tmp_vert(3,tmp_face(1,i))
ex2x=tmp_vert(1,tmp_face(3,i))-tmp_vert(1,tmp_face(1,i))
ex2y=tmp_vert(2,tmp_face(3,i))-tmp_vert(2,tmp_face(1,i))
ex2z=tmp_vert(3,tmp_face(3,i))-tmp_vert(3,tmp_face(1,i))
crossx=ex1y*ex2z-ex1z*ex2y
crossy=ex1z*ex2x-ex1x*ex2z
crossz=ex1x*ex2y-ex1y*ex2x
IF(crossx*tmp_norm(1,i)+crossy*tmp_norm(2,i)+crossz*tmp_norm(3,i)<0.0D0)THEN
idx_v=tmp_face(2,i)
tmp_face(2,i)=tmp_face(3,i)
tmp_face(3,i)=idx_v
ENDIF
ENDDO
n_point=nv_tmp
ALLOCATE(Triangular_face_element(n_face))
ALLOCATE(Vert(n_point))
DO j=1,n_point
Vert(j)%point_number=j
Vert(j)%Coord_X=tmp_vert(1,j)
Vert(j)%Coord_Y=tmp_vert(2,j)
Vert(j)%Coord_Z=tmp_vert(3,j)
ENDDO
DO i=1,n_face
Triangular_face_element(i)%node_face=i
Triangular_face_element(i)%node_point1%point_number=tmp_face(1,i)
Triangular_face_element(i)%node_point2%point_number=tmp_face(2,i)
Triangular_face_element(i)%node_point3%point_number=tmp_face(3,i)
ENDDO
CLOSE(20240506)
DEALLOCATE(tmp_face,tmp_norm,tmp_vert)
WRITE(*,*)'Complex_anomalous.stl read: n_point=',n_point,' n_face=',n_face
ELSE
WRITE(*,*)'Error: neither Complex_anomalous.dat nor Complex_anomalous.stl exists, anomalous_conformal can not run!'
RETURN
ENDIF
!=========================================================================================================
!=====================================The first range reduction===========================================
!Find out the maximum and minimum values of the abnormal volume triangular mesh in the three ranges.
max_coord_x=maxval(Vert(:)%Coord_X)
min_coord_x=minval(Vert(:)%Coord_X)
max_coord_y=maxval(Vert(:)%Coord_Y)
min_coord_y=minval(Vert(:)%Coord_Y)
max_coord_z=maxval(Vert(:)%Coord_Z)
min_coord_z=minval(Vert(:)%Coord_Z)
!The anomalous volume is delimited in the hexahedron.
DO ii=1,NX
IF(coordinates_x(ii)>min_coord_x)THEN
X_min=ii-1
EXIT
ENDIF
ENDDO
DO ii=1,NX
IF(coordinates_x(ii)>max_coord_x)THEN
X_max=ii
EXIT
ENDIF
ENDDO
DO jj=1,NY
IF(coordinates_y(jj)>min_coord_y)THEN
Y_min=jj-1
EXIT
ENDIF
ENDDO
DO jj=1,NY
IF(coordinates_y(jj)>max_coord_y)THEN
Y_max=jj
EXIT
ENDIF
ENDDO
DO kk=1,NZ
IF(coordinates_z(kk)>min_coord_z)THEN
Z_min=kk-1
EXIT
ENDIF
ENDDO
DO kk=1,NZ
IF(coordinates_z(kk)>max_coord_z)THEN
Z_max=kk
EXIT
ENDIF
ENDDO
!=========================================================================================================
ALLOCATE(orig_z(3,NXB*NYB),orig_y(3,NXB*NZB),orig_x(3,NXB*NZB))
ALLOCATE(vert0(3,n_face),vert1(3,n_face),vert2(3,n_face),edge1(3,n_face),edge2(3,n_face))
ALLOCATE(det_z(NXB*NYB),det_x(NYB*NZB),det_y(NXB*NZB))
ALLOCATE(u_z(NXB*NYB),u_x(NYB*NZB),u_y(NXB*NZB))
ALLOCATE(v_z(NXB*NYB),v_x(NYB*NZB),v_y(NXB*NZB))
ALLOCATE(t_z(NXB*NYB),t_x(NYB*NZB),t_y(NXB*NZB))
ALLOCATE(coor_z(NXB,NYB,n_face),coor_y(NXB,NZB,n_face),coor_x(NYB,NZB,n_face))
ALLOCATE(pvec_z(3,NXB*NYB),pvec_y(3,NXB*NZB),pvec_x(3,NYB*NZB))
ALLOCATE(tvec_z(3,NXB*NYB),tvec_y(3,NXB*NZB),tvec_x(3,NYB*NZB))
ALLOCATE(ZZ_min(X_max),ZZ_max(X_max),XX_min(Y_max),XX_max(Y_max),YY_min(Z_max),YY_max(Z_max))
ALLOCATE(coor_z_min(X_max),coor_z_max(X_max),coor_x_min(Y_max),coor_x_max(Y_max),coor_y_min(Z_max),coor_y_max(Z_max))
ALLOCATE(mmz_per(NXB*NYB),mmy_per(NXB*NZB),mmx_per(NYB*NZB))
ALLOCATE(crosspoint_ZZ(X_max,NXB*NYB),crosspoint_YY(X_max,NXB*NZB),crosspoint_XX(Y_max,NYB*NZB))
ALLOCATE( Face_Triangle_NormVect(3,n_face))
orig_z=0.0D0
orig_y=0.0D0
orig_x=0.0D0
vert0=0.0D0
vert1=0.0D0
vert2=0.0D0
edge1=0.0D0
edge2=0.0D0
det_z=0.0D0
det_x=0.0D0
det_y=0.0D0
u_z=0.0D0
u_x=0.0D0
u_y=0.0D0
v_z=0.0D0
v_x=0.0D0
v_y=0.0D0
t_z=0.0D0
t_x=0.0D0
t_y=0.0D0
pvec_z=0.0D0
pvec_x=0.0D0
pvec_y=0.0D0
tvec_z=0.0D0
tvec_x=0.0D0
tvec_y=0.0D0
mmz=0
mmx=0
mmy=0
mmz_per=0
mmx_per=0
mmy_per=0
dir_z = [0.D0,0.D0,1.D0]
dir_y = [0.D0,1.D0,0.D0]
dir_x = [1.D0,0.D0,0.D0]
!=====================================Möller-Trumbore algorithm===========================================
vert0(1,:) = Vert(Triangular_face_element(:)%node_point1%point_number)%Coord_X
vert0(2,:) = Vert(Triangular_face_element(:)%node_point1%point_number)%Coord_Y
vert0(3,:) = Vert(Triangular_face_element(:)%node_point1%point_number)%Coord_Z
vert1(1,:) = Vert(Triangular_face_element(:)%node_point2%point_number)%Coord_X
vert1(2,:) = Vert(Triangular_face_element(:)%node_point2%point_number)%Coord_Y
vert1(3,:) = Vert(Triangular_face_element(:)%node_point2%point_number)%Coord_Z
vert2(1,:) = Vert(Triangular_face_element(:)%node_point3%point_number)%Coord_X
vert2(2,:) = Vert(Triangular_face_element(:)%node_point3%point_number)%Coord_Y
vert2(3,:) = Vert(Triangular_face_element(:)%node_point3%point_number)%Coord_Z
edge1 = vert1 - vert0
edge2 = vert2 - vert0
DO i0=1,n_face
Face_Triangle_NormVect(1,i0)=edge1(2,i0) * edge2(3,i0)-edge1(3,i0) * edge2(2,i0)
Face_Triangle_NormVect(2,i0)=edge1(3,i0) * edge2(1,i0)-edge1(1,i0) * edge2(3,i0)
Face_Triangle_NormVect(3,i0)=edge1(1,i0) * edge2(2,i0)-edge1(2,i0) * edge2(1,i0)
ENDDO
print*,'Ray tracing begins'
!call OMP_SET_NUM_THREADS(16)
!$OMP PARALLEL DO PRIVATE(i0,j1,i1,Rz,kk,kkk,verts_Dotmultp)
!get the intersaction of ray and z-face and save it into "crosspoint_z"
Do j1=Y_min,Y_max
Do i1=X_min,X_max
Rz=(j1-1)*NXB+i1
DO i0=1,n_face
orig_z(1,Rz)=coordinates_x(i1)
orig_z(2,Rz)=coordinates_y(j1)
orig_z(3,Rz)=coordinates_z(1)
tvec_z(1:3,Rz) = orig_z(1:3,Rz) - vert0(1:3,i0)
pvec_z(1,Rz) = dir_z(2)*edge2(3,i0) - dir_z(3)*edge2(2,i0)
pvec_z(2,Rz) = dir_z(3)*edge2(1,i0) - dir_z(1)*edge2(3,i0)
pvec_z(3,Rz) = dir_z(1)*edge2(2,i0) - dir_z(2)*edge2(1,i0)
det_z(Rz)=edge1(1,i0)*pvec_z(1,Rz)+edge1(2,i0)*pvec_z(2,Rz)+edge1(3,i0)*pvec_z(3,Rz)
IF (abs(det_z(Rz)) < eps105) THEN
CYCLE
ENDIF
u_z(Rz) = (tvec_z(1,Rz)*pvec_z(1,Rz)+tvec_z(2,Rz)*pvec_z(2,Rz)+tvec_z(3,Rz)*pvec_z(3,Rz))/det_z(Rz)
IF (u_z(Rz) < 0.0 .or. u_z(Rz) > 1.0) THEN
CYCLE
ENDIF
pvec_z(1,Rz) = tvec_z(2,Rz)*edge1(3,i0) - tvec_z(3,Rz)*edge1(2,i0)
pvec_z(2,Rz) = tvec_z(3,Rz)*edge1(1,i0) - tvec_z(1,Rz)*edge1(3,i0)
pvec_z(3,Rz) = tvec_z(1,Rz)*edge1(2,i0) - tvec_z(2,Rz)*edge1(1,i0)
v_z(Rz) = (dir_z(1)*pvec_z(1,Rz)+dir_z(2)*pvec_z(2,Rz)+dir_z(3)*pvec_z(3,Rz))/det_z(Rz)
IF (v_z(Rz) < 0.0 .or. u_z(Rz) + v_z(Rz) > 1.0) THEN
CYCLE
ENDIF
t_z(Rz)=(edge2(1,i0)*pvec_z(1,Rz)+edge2(2,i0)*pvec_z(2,Rz)+edge2(3,i0)*pvec_z(3,Rz))/det_z(Rz)
coor_z(i1,j1,i0)%Global_Coord%Coord_X = orig_z(1,Rz) + t_z(Rz) * dir_z(1)
coor_z(i1,j1,i0)%Global_Coord%Coord_Y = orig_z(2,Rz) + t_z(Rz) * dir_z(2)
coor_z(i1,j1,i0)%Global_Coord%Coord_Z = orig_z(3,Rz) + t_z(Rz) * dir_z(3)
mmz_per(Rz) = mmz_per(Rz) + 1 !The number of z-direction intersections of each facet element is stored
crosspoint_ZZ(mmz_per(Rz),Rz)%Global_Coord%Coord_X = coor_z(i1,j1,i0)%Global_Coord%Coord_X
crosspoint_ZZ(mmz_per(Rz),Rz)%Global_Coord%Coord_Y = coor_z(i1,j1,i0)%Global_Coord%Coord_Y
crosspoint_ZZ(mmz_per(Rz),Rz)%Global_Coord%Coord_Z = coor_z(i1,j1,i0)%Global_Coord%Coord_Z
IF(mmz_per(Rz)>1)THEN
IF(ABS(crosspoint_ZZ(mmz_per(Rz),Rz)%Global_Coord%Coord_Z-crosspoint_ZZ((mmz_per(Rz)-1),Rz)%Global_Coord%Coord_Z)<eps105)THEN
mmz_per(Rz) = mmz_per(Rz) - 1
CYCLE
ENDIF
ENDIF
!*********************************Determine the intersection_Z attribute*******************************
verts_Dotmultp = dir_z(1) * Face_Triangle_NormVect(1,i0) + dir_z(2) * Face_Triangle_NormVect(2,i0) + dir_z(3) * Face_Triangle_NormVect(3,i0)
if(verts_Dotmultp > 0.D0) THEN
crosspoint_ZZ(mmz_per(Rz),Rz)%Log_In=.TRUE.
ELSE
crosspoint_ZZ(mmz_per(Rz),Rz)%Log_In=.FALSE.
ENDIF
ENDDO
IF(mmz_per(Rz)>1)THEN
DO kk=2,mmz_per(Rz)
DO kkk=1,kk-1
IF(crosspoint_ZZ(kk,Rz)%Global_Coord%Coord_Z<crosspoint_ZZ(kkk,Rz)%Global_Coord%Coord_Z)THEN
CALL SWAP(crosspoint_ZZ(kk,Rz), crosspoint_ZZ(kkk,Rz))
ENDIF
ENDDO
ENDDO
ENDIF
ENDDO
ENDDO
!$OMP END PARALLEL DO
!get the intersaction of ray and y-face and save it into "crosspoint_y"
!=======================================================================================================
!$OMP PARALLEL DO PRIVATE(i0,k2,i2,Ry,jj,jjj,verts_Dotmultp)
Do i2=X_min,X_max
Do k2=Z_min,Z_max
Ry=(i2-1)*NZB+k2
DO i0=1,n_face
orig_y(1,Ry)=coordinates_x(i2)
orig_y(2,Ry)=coordinates_y(1)
orig_y(3,Ry)=coordinates_z(k2)
tvec_y(1:3,Ry) = orig_y(1:3,Ry) - vert0(1:3,i0)
pvec_y(1,Ry) = dir_y(2)*edge2(3,i0) - dir_y(3)*edge2(2,i0)
pvec_y(2,Ry) = dir_y(3)*edge2(1,i0) - dir_y(1)*edge2(3,i0)
pvec_y(3,Ry) = dir_y(1)*edge2(2,i0) - dir_y(2)*edge2(1,i0)
det_y(Ry)=edge1(1,i0)*pvec_y(1,Ry)+edge1(2,i0)*pvec_y(2,Ry)+edge1(3,i0)*pvec_y(3,Ry)
IF (abs(det_y(Ry)) < eps105) THEN
CYCLE
END IF
u_y(Ry) = (tvec_y(1,Ry)*pvec_y(1,Ry)+tvec_y(2,Ry)*pvec_y(2,Ry)+tvec_y(3,Ry)*pvec_y(3,Ry))/det_y(Ry)
IF (u_y(Ry) < 0.0 .or. u_y(Ry) > 1.0) THEN
CYCLE
END IF
pvec_y(1,Ry) = tvec_y(2,Ry)*edge1(3,i0) - tvec_y(3,Ry)*edge1(2,i0)
pvec_y(2,Ry) = tvec_y(3,Ry)*edge1(1,i0) - tvec_y(1,Ry)*edge1(3,i0)
pvec_y(3,Ry) = tvec_y(1,Ry)*edge1(2,i0) - tvec_y(2,Ry)*edge1(1,i0)
v_y(Ry) = (dir_y(1)*pvec_y(1,Ry)+dir_y(2)*pvec_y(2,Ry)+dir_y(3)*pvec_y(3,Ry))/det_y(Ry)
IF (v_y(Ry) < 0.0 .or. u_y(Ry) + v_y(Ry) > 1.0) THEN
CYCLE
END IF
t_y(Ry)=(edge2(1,i0)*pvec_y(1,Ry)+edge2(2,i0)*pvec_y(2,Ry)+edge2(3,i0)*pvec_y(3,Ry))/det_y(Ry)
coor_y(i2,k2,i0)%Global_Coord%Coord_X = orig_y(1,Ry) + t_y(Ry) * dir_y(1)
coor_y(i2,k2,i0)%Global_Coord%Coord_Y = orig_y(2,Ry) + t_y(Ry) * dir_y(2)
coor_y(i2,k2,i0)%Global_Coord%Coord_Z = orig_y(3,Ry) + t_y(Ry) * dir_y(3)
mmy_per(Ry) = mmy_per(Ry) + 1 !The number of y-direction intersections of each facet element is stored
crosspoint_YY(mmy_per(Ry),Ry)%Global_Coord%Coord_X = coor_y(i2,k2,i0)%Global_Coord%Coord_X
crosspoint_YY(mmy_per(Ry),Ry)%Global_Coord%Coord_Y = coor_y(i2,k2,i0)%Global_Coord%Coord_Y
crosspoint_YY(mmy_per(Ry),Ry)%Global_Coord%Coord_Z = coor_y(i2,k2,i0)%Global_Coord%Coord_Z
IF(mmy_per(Ry)>1)THEN
IF(ABS(crosspoint_YY(mmy_per(Ry),Ry)%Global_Coord%Coord_Y-crosspoint_YY((mmy_per(Ry)-1),Ry)%Global_Coord%Coord_Y)<eps105)THEN
mmy_per(Ry) = mmy_per(Ry) - 1
CYCLE
ENDIF
ENDIF
!*********************************Determine the intersection_Y attribute*******************************
verts_Dotmultp = dir_y(1) * Face_Triangle_NormVect(1,i0) + dir_y(2) * Face_Triangle_NormVect(2,i0) + dir_y(3) * Face_Triangle_NormVect(3,i0)
if(verts_Dotmultp > 0.D0)THEN
crosspoint_YY(mmy_per(Ry),Ry)%Log_In=.TRUE.
ELSE
crosspoint_YY(mmy_per(Ry),Ry)%Log_In=.FALSE.
ENDIF
ENDDO
IF(mmy_per(Ry)>1)THEN
DO jj=2,mmy_per(Ry)
DO jjj=1,jj-1
IF(crosspoint_YY(jj,Ry)%Global_Coord%Coord_Y<crosspoint_YY(jjj,Ry)%Global_Coord%Coord_Y)THEN
CALL SWAP(crosspoint_YY(jj,Ry), crosspoint_YY(jjj,Ry))
ENDIF
ENDDO
ENDDO
ENDIF
ENDDO
ENDDO
!$OMP END PARALLEL DO
!get the intersaction of ray and y-face and save it into "crosspoint_x"
!=======================================================================================================
!$OMP PARALLEL DO PRIVATE(i0,k3,j3,ii,iii,Rx,verts_Dotmultp)
Do k3=Z_min,Z_max
Do j3=Y_min,Y_max
Rx=(k3-1)*NYB+j3
DO i0=1,n_face
orig_x(1,Rx)=coordinates_x(1)
orig_x(2,Rx)=coordinates_y(j3)
orig_x(3,Rx)=coordinates_z(k3)
tvec_x(1:3,Rx) = orig_x(1:3,Rx) - vert0(1:3,i0)
pvec_x(1,Rx) = dir_x(2)*edge2(3,i0) - dir_x(3)*edge2(2,i0)
pvec_x(2,Rx) = dir_x(3)*edge2(1,i0) - dir_x(1)*edge2(3,i0)
pvec_x(3,Rx) = dir_x(1)*edge2(2,i0) - dir_x(2)*edge2(1,i0)
det_x(Rx)=edge1(1,i0)*pvec_x(1,Rx)+edge1(2,i0)*pvec_x(2,Rx)+edge1(3,i0)*pvec_x(3,Rx)
IF (abs(det_x(Rx)) < eps105) THEN
CYCLE
END IF
u_x(Rx) = (tvec_x(1,Rx)*pvec_x(1,Rx)+tvec_x(2,Rx)*pvec_x(2,Rx)+tvec_x(3,Rx)*pvec_x(3,Rx))/det_x(Rx)
IF (u_x(Rx) < 0.0 .or. u_x(Rx) > 1.0) THEN
CYCLE
END IF
pvec_x(1,Rx) = tvec_x(2,Rx)*edge1(3,i0) - tvec_x(3,Rx)*edge1(2,i0)
pvec_x(2,Rx) = tvec_x(3,Rx)*edge1(1,i0) - tvec_x(1,Rx)*edge1(3,i0)
pvec_x(3,Rx) = tvec_x(1,Rx)*edge1(2,i0) - tvec_x(2,Rx)*edge1(1,i0)
v_x(Rx) = (dir_x(1)*pvec_x(1,Rx)+dir_x(2)*pvec_x(2,Rx)+dir_x(3)*pvec_x(3,Rx))/det_x(Rx)
IF (v_x(Rx) < 0.0 .or. u_x(Rx) + v_x(Rx) > 1.0) THEN
CYCLE
END IF
t_x(Rx)=(edge2(1,i0)*pvec_x(1,Rx)+edge2(2,i0)*pvec_x(2,Rx)+edge2(3,i0)*pvec_x(3,Rx))/det_x(Rx)
coor_x(j3,k3,i0)%Global_Coord%Coord_X = orig_x(1,Rx) + t_x(Rx) * dir_x(1)
coor_x(j3,k3,i0)%Global_Coord%Coord_Y = orig_x(2,Rx) + t_x(Rx) * dir_x(2)
coor_x(j3,k3,i0)%Global_Coord%Coord_Z = orig_x(3,Rx) + t_x(Rx) * dir_x(3)
mmx_per(Rx) = mmx_per(Rx) + 1 !The number of x-direction intersections of each facet element is stored
crosspoint_XX(mmx_per(Rx),Rx)%Global_Coord%Coord_X = coor_x(j3,k3,i0)%Global_Coord%Coord_X
crosspoint_XX(mmx_per(Rx),Rx)%Global_Coord%Coord_Y = coor_x(j3,k3,i0)%Global_Coord%Coord_Y
crosspoint_XX(mmx_per(Rx),Rx)%Global_Coord%Coord_Z = coor_x(j3,k3,i0)%Global_Coord%Coord_Z
IF(mmx_per(Rx)>1)THEN
IF(ABS(crosspoint_XX(mmx_per(Rx),Rx)%Global_Coord%Coord_X-crosspoint_XX((mmx_per(Rx)-1),Rx)%Global_Coord%Coord_X)<eps105)THEN
mmx_per(Rx) = mmx_per(Rx) - 1
CYCLE
ENDIF
ENDIF
!*********************************Determine the intersection_X attribute*******************************
verts_Dotmultp = dir_x(1) * Face_Triangle_NormVect(1,i0) + dir_x(2) * Face_Triangle_NormVect(2,i0) + dir_x(3) * Face_Triangle_NormVect(3,i0)
if(verts_Dotmultp > 0.D0)THEN
crosspoint_XX(mmx_per(Rx),Rx)%Log_In=.TRUE.
ELSE
crosspoint_XX(mmx_per(Rx),Rx)%Log_In=.FALSE.
ENDIF
ENDDO
IF(mmx_per(Rx)>1)THEN
DO ii=2,mmx_per(Rx)
DO iii=1,mmx_per(Rx)-1
IF(crosspoint_XX(ii,Rx)%Global_Coord%Coord_X<crosspoint_XX(iii,Rx)%Global_Coord%Coord_X)THEN
CALL SWAP(crosspoint_XX(ii,Rx), crosspoint_XX(iii,Rx))
ENDIF
ENDDO
ENDDO
ENDIF
ENDDO
ENDDO
!$OMP END PARALLEL DO
!=======================================================================================================
!=========================================================================================================
!$OMP PARALLEL
!$OMP DO PRIVATE(ii)
Do j1=Y_min,Y_max
coor_x_min(j1)=minval(coor_x(j1,:,:)%Global_Coord%Coord_X)
coor_x_max(j1)=maxval(coor_x(j1,:,:)%Global_Coord%Coord_X)
XX_min(j1) = -1
XX_max(j1) = -1
DO ii=1,NX
IF(coordinates_x(ii)>=coor_x_min(j1).and.XX_min(j1) == -1)THEN
XX_min(j1)=ii-1
ENDIF
IF(coordinates_x(ii)>=coor_x_max(j1).and.XX_max(j1) == -1)THEN
XX_max(j1)=ii
EXIT
ENDIF
ENDDO
ENDDO
!$OMP END DO
!'Calculate the projection of the anomalous volume on the y-plane'
!$OMP DO PRIVATE(kk)
Do i2=X_min,X_max
coor_z_min(i2)=minval(coor_z(i2,:,:)%Global_Coord%Coord_Z)
coor_z_max(i2)=maxval(coor_z(i2,:,:)%Global_Coord%Coord_Z)
ZZ_min(i2) = -1
ZZ_max(i2) = -1
DO kk=1,NZ
IF(coordinates_z(kk)>=coor_z_min(i2).and.ZZ_min(i2) == -1)THEN
ZZ_min(i2)=kk-1
ENDIF
IF(coordinates_z(kk)>=coor_z_max(i2).and.ZZ_max(i2) == -1)THEN
ZZ_max(i2)=kk
EXIT
ENDIF
ENDDO
ENDDO
!$OMP END DO
!'Calculate the projection of the anomalous volume on the x-plane'
!$OMP DO PRIVATE(jj)
DO k3=Z_min,Z_max
coor_y_min(k3)=minval(coor_y(:,k3,:)%Global_Coord%Coord_Y)
coor_y_max(k3)=maxval(coor_y(:,k3,:)%Global_Coord%Coord_Y)
YY_min(k3) = -1
YY_max(k3) = -1
DO jj=1,NY
IF(coordinates_y(jj)>=coor_y_min(k3).and.YY_min(k3) == -1)THEN
YY_min(k3)=jj-1
ENDIF
IF(coordinates_y(jj)>=coor_y_max(k3).and.YY_max(k3) == -1)THEN
YY_max(k3)=jj
EXIT
ENDIF
ENDDO
ENDDO
!$OMP END DO
!$OMP END PARALLEL
print*,'The projection calculation of the model in three directions is completed.'
!=========================================================================================================
!=====================================Calculate the electric conductivity===========================================
!Calculate the electric conductivity of z-dection
DO j=Y_min,Y_max
DO i=XX_min(j),XX_max(j)
Rz=(j-1)*NXB+i
IF (mod(mmz_per(Rz),2)==0 .and. mmz_per(Rz)/=0) THEN !The case of an even number of intersection points
idx_start=0
idx_end=0
Logic_1=.false.
Logic_2=.false.
DO KK=1,mmz_per(Rz)
IF(crosspoint_ZZ(KK,Rz)%Log_In)THEN !The intersection point is the entry point
idx_start=KK
ELSEIF(.NOT.crosspoint_ZZ(KK,Rz)%Log_In)THEN !The intersection point is the exit point
idx_end=KK
ENDIF
IF((idx_start>0).AND.(idx_end>0))THEN !There are both entry and exit points on the ray simultaneously
DO k=1,NZ
Logic_1=((coordinates_z(k)<=crosspoint_ZZ(idx_start,Rz)%Global_Coord%Coord_Z).AND.&
&(coordinates_z(k+1)>=crosspoint_ZZ(idx_start,Rz)%Global_Coord%Coord_Z))
Logic_2=((coordinates_z(k)<=crosspoint_ZZ(idx_end,Rz)%Global_Coord%Coord_Z).AND.&
&(coordinates_z(k+1)>=crosspoint_ZZ(idx_end,Rz)%Global_Coord%Coord_Z))
IF(Logic_1) KIdx_1=k
IF(Logic_2) KIdx_2=k
IF(Logic_1.and.Logic_2) EXIT
ENDDO
IF(idx_start<idx_end) THEN !The ray first penetrate the stratum and enter the anomalous body
IF(KIdx_1==KIdx_2) THEN
LenRatio_CCSIGZ(i,j,KIdx_1) = (crosspoint_ZZ(idx_end,Rz)%Global_Coord%Coord_Z-crosspoint_ZZ(idx_start,Rz)%Global_Coord%Coord_Z)/Cdelz(KIdx_1)
CCSIGZ(i,j,KIdx_1) = tao_abnormal * LenRatio_CCSIGZ(i,j,KIdx_1)+TAR_CONDUCTIVITY(2)*(1-LenRatio_CCSIGZ(i,j,KIdx_1))
ELSEIF(KIdx_2 > KIdx_1)THEN
LenRatio_CCSIGZ(i,j,KIdx_1) = (crosspoint_ZZ(idx_start,Rz)%Global_Coord%Coord_Z-coordinates_z(KIdx_1))/Cdelz(KIdx_1)
LenRatio_CCSIGZ(i,j,KIdx_2) = (crosspoint_ZZ(idx_end,Rz)%Global_Coord%Coord_Z-coordinates_z(KIdx_2))/Cdelz(KIdx_2)
CCSIGZ(i,j,KIdx_1) = TAR_CONDUCTIVITY(2) * LenRatio_CCSIGZ(i,j,KIdx_1) + tao_abnormal * (1-LenRatio_CCSIGZ(i,j,KIdx_1))
CCSIGZ(i,j,(KIdx_1+1):(KIdx_2-1)) = tao_abnormal
CCSIGZ(i,j,KIdx_2) = tao_abnormal * LenRatio_CCSIGZ(i,j,KIdx_2)+TAR_CONDUCTIVITY(2) * (1-LenRatio_CCSIGZ(i,j,KIdx_2))
ENDIF
ELSE !The ray first emerges from the anomaly and penetrates the stratum
IF(KIdx_1==KIdx_2) THEN
LenRatio_CCSIGZ(i,j,KIdx_1) = (crosspoint_ZZ(idx_start,Rz)%Global_Coord%Coord_Z-crosspoint_ZZ(idx_end,Rz)%Global_Coord%Coord_Z)/Cdelz(KIdx_1)
CCSIGZ(i,j,KIdx_1) = tao_abnormal * LenRatio_CCSIGZ(i,j,KIdx_1)+TAR_CONDUCTIVITY(2)*(1-LenRatio_CCSIGZ(i,j,KIdx_1))
ELSEIF(KIdx_2 < KIdx_1)THEN
LenRatio_CCSIGZ(i,j,KIdx_1) = (coordinates_z(KIdx_1+1)-crosspoint_ZZ(idx_start,Rz)%Global_Coord%Coord_Z)/Cdelz(KIdx_1)
LenRatio_CCSIGZ(i,j,KIdx_2) = (crosspoint_ZZ(idx_end,Rz)%Global_Coord%Coord_Z-coordinates_z(KIdx_2))/Cdelz(KIdx_2)
ENDIF
CCSIGZ(i,j,KIdx_2) = LenRatio_CCSIGZ(i,j,KIdx_2)*tao_abnormal+(1-LenRatio_CCSIGZ(i,j,KIdx_2))*TAR_CONDUCTIVITY(2)
CCSIGZ(i,j,(KIdx_2+1):(KIdx_1-1)) = TAR_CONDUCTIVITY(2)
CCSIGZ(i,j,KIdx_1) = TAR_CONDUCTIVITY(2)*LenRatio_CCSIGZ(i,j,KIdx_1)+(1-LenRatio_CCSIGZ(i,j,KIdx_1))*tao_abnormal
ENDIF
ENDIF
ENDDO
ELSEIF(mod(mmz_per(Rz),2)==1)THEN
print*,'z-dection!!!ERROR!!!ERROR!!!ERROR!!!'
print*,i,j
ENDIF
ENDDO
ENDDO
print*,'The equivalent conductivity calculation in the z direction is completed!'
!Calculate the electric conductivity of x-dection
DO k=Z_min,Z_max
DO j=YY_min(k),YY_max(k)
Rx=(k-1)*NYB+j
IF (mod(mmx_per(Rx),2)==0.and.mmx_per(Rx)/=0) THEN !The case of an even number of intersection points
idx_start=0
idx_end=0
Logic_1=.false.
Logic_2=.false.
DO II=1,mmx_per(Rx)
IF(crosspoint_XX(II,Rx)%Log_In)THEN !The intersection point is the entry point
idx_start=II
ELSEIF(.NOT.crosspoint_XX(II,Rx)%Log_In)THEN !The intersection point is the exit point
idx_end=II
ENDIF
IF((idx_start>0).AND.(idx_end>0))THEN !There are both entry and exit points on the ray simultaneously
DO i=1,NX
Logic_1=((coordinates_x(i)<=crosspoint_XX(idx_start,Rx)%Global_Coord%Coord_X).AND.&
&(coordinates_x(i+1)>=crosspoint_XX(idx_start,Rx)%Global_Coord%Coord_X))
Logic_2=((coordinates_x(i)<=crosspoint_XX(idx_end,Rx)%Global_Coord%Coord_X).AND.&
&(coordinates_x(i+1)>=crosspoint_XX(idx_end,Rx)%Global_Coord%Coord_X))
IF(Logic_1) KIdx_1=i
IF(Logic_2) KIdx_2=i
IF(Logic_1.and.Logic_2) EXIT
ENDDO
IF(idx_start<idx_end) THEN !The ray first penetrate the stratum and enter the anomalous body
IF(KIdx_1==KIdx_2) THEN
LenRatio_CCSIGX(KIdx_1,j,k) = (crosspoint_XX(idx_end,Rx)%Global_Coord%Coord_X-crosspoint_XX(idx_start,Rx)%Global_Coord%Coord_X)/Cdelx(KIdx_1)
CCSIGX(KIdx_1,j,k) = tao_abnormal * LenRatio_CCSIGX(KIdx_1,j,k)+TAR_CONDUCTIVITY(2)*(1-LenRatio_CCSIGX(KIdx_1,j,k))
ELSEIF(KIdx_2 > KIdx_1)THEN
LenRatio_CCSIGX(KIdx_1,j,k) = (crosspoint_XX(idx_start,Rx)%Global_Coord%Coord_X-coordinates_x(KIdx_1))/Cdelx(KIdx_1)
LenRatio_CCSIGX(KIdx_2,j,k) = (crosspoint_XX(idx_end,Rx)%Global_Coord%Coord_X-coordinates_x(KIdx_2))/Cdelx(KIdx_2)
CCSIGX(KIdx_1,j,k) = TAR_CONDUCTIVITY(2) * LenRatio_CCSIGX(KIdx_1,j,k) + tao_abnormal * (1-LenRatio_CCSIGX(KIdx_1,j,k))
CCSIGX((KIdx_1+1):(KIdx_2-1),j,k) = tao_abnormal
CCSIGX(KIdx_2,j,k) = tao_abnormal * LenRatio_CCSIGX(KIdx_2,j,k)+TAR_CONDUCTIVITY(2) * (1-LenRatio_CCSIGX(KIdx_2,j,k))
ENDIF
ELSE !The ray first emerges from the anomaly and penetrates the stratum
IF(KIdx_1==KIdx_2) THEN
LenRatio_CCSIGX(KIdx_1,j,k) = (crosspoint_XX(idx_start,Rx)%Global_Coord%Coord_X-crosspoint_XX(idx_end,Rx)%Global_Coord%Coord_X)/Cdelx(KIdx_1)
CCSIGX(KIdx_1,j,k) = tao_abnormal * LenRatio_CCSIGX(KIdx_1,j,k)+TAR_CONDUCTIVITY(2)*(1-LenRatio_CCSIGX(KIdx_1,j,k))
ELSEIF(KIdx_2 < KIdx_1)THEN
LenRatio_CCSIGX(KIdx_1,j,k) = (coordinates_x(KIdx_1+1)-crosspoint_XX(idx_start,Rx)%Global_Coord%Coord_X)/Cdelx(KIdx_1)
LenRatio_CCSIGX(KIdx_2,j,k) = (crosspoint_XX(idx_end,Rx)%Global_Coord%Coord_X-coordinates_x(KIdx_2))/Cdelx(KIdx_2)
ENDIF
CCSIGX(KIdx_2,j,k) = tao_abnormal*LenRatio_CCSIGX(KIdx_2,j,k)+TAR_CONDUCTIVITY(2)*(1-LenRatio_CCSIGX(KIdx_2,j,k))
CCSIGX((KIdx_2+1):(KIdx_1-1),j,k) = TAR_CONDUCTIVITY(2)
CCSIGX(KIdx_1,j,k) = TAR_CONDUCTIVITY(2)*LenRatio_CCSIGX(KIdx_1,j,k)+tao_abnormal*(1-LenRatio_CCSIGX(KIdx_1,j,k))
ENDIF
ENDIF
ENDDO
ELSEIF(mod(mmx_per(Rx),2)==1)THEN
print*,'x-dection!!!ERROR!!!ERROR!!!ERROR!!!'
print*,j,k,coordinates_y(j),coordinates_z(k)
ENDIF
ENDDO
ENDDO
print*,'The equivalent conductivity calculation in the x direction is completed!'
!===========================================================================================================================================================
!Calculate the electric conductivity of y-dection
DO i=X_min,X_max
DO k=ZZ_min(i),ZZ_max(i)
Ry=(i-1)*NZB+k
IF (mod(mmy_per(Ry),2)==0.and. mmy_per(Ry)/=0) THEN !The case of an even number of intersection points
idx_start=0
idx_end=0
Logic_1=.false.
Logic_2=.false.
DO JJ=1,mmy_per(Ry)
IF(crosspoint_YY(JJ,Ry)%Log_In)THEN !The intersection point is the entry point
idx_start=JJ
ELSEIF(.NOT.crosspoint_YY(JJ,Ry)%Log_In)THEN !The intersection point is the exit point
idx_end=JJ
ENDIF
IF((idx_start>0).AND.(idx_end>0))THEN !There are both entry and exit points on the ray simultaneously
DO j=1,NY
Logic_1=((coordinates_y(j)<=crosspoint_YY(idx_start,Ry)%Global_Coord%Coord_Y).AND.&
&(coordinates_y(j+1)>=crosspoint_YY(idx_start,Ry)%Global_Coord%Coord_Y))
Logic_2=((coordinates_y(j)<=crosspoint_YY(idx_end,Ry)%Global_Coord%Coord_Y).AND.&
&(coordinates_y(j+1)>=crosspoint_YY(idx_end,Ry)%Global_Coord%Coord_Y))
IF(Logic_1) KIdx_1=j
IF(Logic_2) KIdx_2=j
IF(Logic_1.and.Logic_2) EXIT
ENDDO
IF(idx_start<idx_end) THEN !The ray first penetrate the stratum and enter the anomalous body
IF(KIdx_1==KIdx_2) THEN
LenRatio_CCSIGY(i,KIdx_1,k) = (crosspoint_YY(idx_end,Ry)%Global_Coord%Coord_Y-crosspoint_YY(idx_start,Ry)%Global_Coord%Coord_Y)/Cdely(KIdx_1)
CCSIGY(i,KIdx_1,k) = tao_abnormal * LenRatio_CCSIGY(i,KIdx_1,k)+TAR_CONDUCTIVITY(2)*(1-LenRatio_CCSIGY(i,KIdx_1,k))
ELSEIF(KIdx_2 > KIdx_1)THEN
LenRatio_CCSIGY(i,KIdx_1,k) = (crosspoint_YY(idx_start,Ry)%Global_Coord%Coord_Y-coordinates_y(KIdx_1))/Cdely(KIdx_1)
LenRatio_CCSIGY(i,KIdx_2,k) = (crosspoint_YY(idx_end,Ry)%Global_Coord%Coord_Y-coordinates_y(KIdx_2))/Cdely(KIdx_2)
CCSIGY(i,KIdx_1,k) = TAR_CONDUCTIVITY(2) * LenRatio_CCSIGY(i,KIdx_1,k) + tao_abnormal * (1-LenRatio_CCSIGY(i,KIdx_1,k))
CCSIGY(i,(KIdx_1+1):(KIdx_2-1),k) = tao_abnormal
CCSIGY(i,KIdx_2,k) = tao_abnormal * LenRatio_CCSIGY(i,KIdx_2,k)+TAR_CONDUCTIVITY(2) * (1-LenRatio_CCSIGY(i,KIdx_2,k))
ENDIF
ELSE !The ray first emerges from the anomaly and penetrates the stratum
IF(KIdx_1==KIdx_2) THEN
LenRatio_CCSIGY(i,KIdx_1,k) = (crosspoint_YY(idx_start,Ry)%Global_Coord%Coord_Y-crosspoint_YY(idx_end,Ry)%Global_Coord%Coord_Y)/Cdely(KIdx_1)
CCSIGY(i,KIdx_1,k) = tao_abnormal * LenRatio_CCSIGY(i,KIdx_1,k)+TAR_CONDUCTIVITY(2)*(1-LenRatio_CCSIGY(i,KIdx_1,k))
ELSEIF(KIdx_2 < KIdx_1)THEN
LenRatio_CCSIGY(i,KIdx_1,k) = (coordinates_y(KIdx_1+1)-crosspoint_YY(idx_start,Ry)%Global_Coord%Coord_Y)/Cdely(KIdx_1)
LenRatio_CCSIGY(i,KIdx_2,k) = (crosspoint_YY(idx_end,Ry)%Global_Coord%Coord_Y-coordinates_y(KIdx_2))/Cdely(KIdx_2)
ENDIF
CCSIGY(i,KIdx_2,k) = tao_abnormal*LenRatio_CCSIGY(i,KIdx_2,k)+TAR_CONDUCTIVITY(2)*(1-LenRatio_CCSIGY(i,KIdx_2,k))
CCSIGY(i,(KIdx_2+1):(KIdx_1-1),k) = TAR_CONDUCTIVITY(2)
CCSIGY(i,KIdx_1,k) = TAR_CONDUCTIVITY(2)*LenRatio_CCSIGY(i,KIdx_1,k)+tao_abnormal*(1-LenRatio_CCSIGY(i,KIdx_1,k))
ENDIF
ENDIF
ENDDO
ELSEIF(mod(mmy_per(Ry),2)==1)THEN
print*,'y-dection!!!ERROR!!!ERROR!!!ERROR!!!'
print*,i,k,coordinates_x(i),coordinates_z(k)
ENDIF
ENDDO
ENDDO
print*,'The equivalent conductivity calculation in the y direction is completed!'
DEALLOCATE(orig_z,orig_y,orig_x)
DEALLOCATE(vert0,vert1,vert2,edge1,edge2)
DEALLOCATE(det_z,det_x,det_y)
DEALLOCATE(u_z,u_x,u_y)
DEALLOCATE(v_z,v_x,v_y)
DEALLOCATE(t_z,t_x,t_y)
DEALLOCATE(coor_z,coor_y,coor_x)
DEALLOCATE(pvec_z,pvec_y,pvec_x)
DEALLOCATE(tvec_z,tvec_y,tvec_x)
DEALLOCATE(ZZ_min,ZZ_max,XX_min,XX_max,YY_min,YY_max)
DEALLOCATE(coor_z_min,coor_z_max,coor_x_min,coor_x_max,coor_y_min,coor_y_max)
DEALLOCATE(mmz_per,mmy_per,mmx_per)
DEALLOCATE(crosspoint_ZZ,crosspoint_YY,crosspoint_XX)
RETURN
END SUBROUTINE anomalous_conformal
+3 -3
查看文件
@@ -1,6 +1,6 @@
!Copyright (c) 2013 by tdem.org under guide of Xiu Li(lixiu@chd.edu.cn) !Copyright (c) 2013 by https://git.em3d.cn/ under guide of Xiu Li(lixiu@chd.edu.cn)
!written by Huaifeng Sun(sunhuaifeng@gmail.com) and Xushan Lu(luxushan@gmail.com) !written by Huaifeng Sun(sunhuaifeng@email.sdu.edu.cn) and Xushan Lu(luxushan@gmail.com)
!Code distribution @ tdem.org or sunhuaifeng.com !Code distribution @ https://git.em3d.cn/
!function description !function description
!this suboutine is used to select and call some suboutine to close some !this suboutine is used to select and call some suboutine to close some
+15 -3
查看文件
@@ -1,6 +1,6 @@
!Copyright (c) 2013 by tdem.org under guide of Xiu Li(lixiu@chd.edu.cn) !Copyright (c) 2013 by https://git.em3d.cn/ under guide of Xiu Li(lixiu@chd.edu.cn)
!written by Huaifeng Sun(sunhuaifeng@gmail.com) and Xushan Lu(luxushan@gmail.com) !written by Huaifeng Sun(sunhuaifeng@email.sdu.edu.cn) and Xushan Lu(luxushan@gmail.com)
!Code distribution @ tdem.org or sunhuaifeng.com !Code distribution @ https://git.em3d.cn/
subroutine GetSourcePosition subroutine GetSourcePosition
! This subroutine initialize the value of array is_ex_in_source which is used when judging whether the grid contains the source ! This subroutine initialize the value of array is_ex_in_source which is used when judging whether the grid contains the source
@@ -9,6 +9,7 @@ subroutine GetSourcePosition
IMPLICIT NONE IMPLICIT NONE
INTEGER ii,jj INTEGER ii,jj
is_ex_in_source=0; is_ey_in_source=0 is_ex_in_source=0; is_ey_in_source=0
IF(Logi_Sourcelenth) THEN !The number of grids occupied by the source is odd
do ii=nxs-(SourceGridNum-1)/2,nxs+(SourceGridNum-1)/2,1 do ii=nxs-(SourceGridNum-1)/2,nxs+(SourceGridNum-1)/2,1
is_ex_in_source(ii,nys-(SourceGridNum-1)/2)=1 is_ex_in_source(ii,nys-(SourceGridNum-1)/2)=1
is_ex_in_source(ii,nys+(SourceGridNum+1)/2)=-1 is_ex_in_source(ii,nys+(SourceGridNum+1)/2)=-1
@@ -18,5 +19,16 @@ subroutine GetSourcePosition
is_ey_in_source(nxs-(SourceGridNum-1)/2,ii)=-1 is_ey_in_source(nxs-(SourceGridNum-1)/2,ii)=-1
is_ey_in_source(nxs+(SourceGridNum+1)/2,ii)=1 is_ey_in_source(nxs+(SourceGridNum+1)/2,ii)=1
end do end do
ELSE !The number of grids occupied by the source is even
do ii=nxs-SourceGridNum/2+1,nxs+SourceGridNum/2+1,1
is_ex_in_source(ii,nys-(SourceGridNum)/2+1)=1
is_ex_in_source(ii,nys+(SourceGridNum)/2+1)=-1
end do
! Aware that the value of source has both positive and negative parts, or they will cancel each other out.
do ii=nys-SourceGridNum/2+1,nys+SourceGridNum/2+1,1
is_ey_in_source(nxs-(SourceGridNum)/2+1,ii)=-1
is_ey_in_source(nxs+(SourceGridNum)/2+1,ii)=1
end do
ENDIF
end subroutine GetSourcePosition end subroutine GetSourcePosition
+101
查看文件
@@ -0,0 +1,101 @@
!Copyright (c) 2022 by LEEE under guide of Huaifeng Sun(sunhuaifeng@email.sdu.edu.cn)
!written by Shangbin Liu(lsbin87@126.com)
SUBROUTINE Get_Receiver_Gridlabel
!This subroutine is used to calculate the global coordinates and grid dispersion at the receiving point
USE CONSTANTPARAMETERS
USE OMP_LIB
IMPLICIT NONE
INTEGER ii,i,j,k
INTEGER(KIND=4) ::x_pined,y_pined,z_pined
REAL(KIND=8) ::volu(8),volu_total
! -------------------------points_observer_gridlabel-------------------------------------------!
!$OMP PARALLEL DO PRIVATE(i,j,k,x_pined,y_pined,z_pined,volu,volu_total)
DO ii=1,point_num
DO i=1,NX
IF(Points_Observer(ii)%Local_Coord_To_Source%Coord_X < Coord_HZ_X(i))THEN
x_pined = i-1
EXIT !Find the corresponding grid
ENDIF
ENDDO
x_pined = MAX(1,MIN(x_pined,NX-1)) !clamp: keep the index in [1,NX-1] even if the receiver is outside the grid
DO j=1,NY
IF(Points_Observer(ii)%Local_Coord_To_Source%Coord_Y < Coord_HZ_Y(j))THEN
y_pined = j-1
EXIT
ENDIF
ENDDO
y_pined = MAX(1,MIN(y_pined,NY-1)) !clamp
DO k=1,NZB
IF(Points_Observer(ii)%Local_Coord_To_Source%Coord_Z < Coord_HZ_Z(k))THEN
z_pined = k-1
EXIT
ENDIF
ENDDO
z_pined = MAX(1,MIN(z_pined,NZB-1)) !clamp
!The position of the first HZ corresponding to the observation point
Points_Observer(ii)%Global_Coordmesh(1)%Coordmesh_X = x_pined
Points_Observer(ii)%Global_Coordmesh(1)%Coordmesh_Y = y_pined
Points_Observer(ii)%Global_Coordmesh(1)%Coordmesh_Z = z_pined
!The position of the second HZ corresponding to the observation point
Points_Observer(ii)%Global_Coordmesh(2)%Coordmesh_X = x_pined + 1
Points_Observer(ii)%Global_Coordmesh(2)%Coordmesh_Y = y_pined
Points_Observer(ii)%Global_Coordmesh(2)%Coordmesh_Z = z_pined
!The position of the 3th HZ corresponding to the observation point
Points_Observer(ii)%Global_Coordmesh(3)%Coordmesh_X = x_pined
Points_Observer(ii)%Global_Coordmesh(3)%Coordmesh_Y = y_pined + 1
Points_Observer(ii)%Global_Coordmesh(3)%Coordmesh_Z = z_pined
!The position of the 4th HZ corresponding to the observation point
Points_Observer(ii)%Global_Coordmesh(4)%Coordmesh_X = x_pined + 1
Points_Observer(ii)%Global_Coordmesh(4)%Coordmesh_Y = y_pined + 1
Points_Observer(ii)%Global_Coordmesh(4)%Coordmesh_Z = z_pined
!The position of the 5th HZ corresponding to the observation point
Points_Observer(ii)%Global_Coordmesh(5)%Coordmesh_X = x_pined
Points_Observer(ii)%Global_Coordmesh(5)%Coordmesh_Y = y_pined
Points_Observer(ii)%Global_Coordmesh(5)%Coordmesh_Z = z_pined + 1
!The position of the 6th HZ corresponding to the observation point
Points_Observer(ii)%Global_Coordmesh(6)%Coordmesh_X = x_pined + 1
Points_Observer(ii)%Global_Coordmesh(6)%Coordmesh_Y = y_pined
Points_Observer(ii)%Global_Coordmesh(6)%Coordmesh_Z = z_pined + 1
!The position of the 7th HZ corresponding to the observation point
Points_Observer(ii)%Global_Coordmesh(7)%Coordmesh_X = x_pined
Points_Observer(ii)%Global_Coordmesh(7)%Coordmesh_Y = y_pined + 1
Points_Observer(ii)%Global_Coordmesh(7)%Coordmesh_Z = z_pined + 1
!The position of the 8th HZ corresponding to the observation point
Points_Observer(ii)%Global_Coordmesh(8)%Coordmesh_X = x_pined + 1
Points_Observer(ii)%Global_Coordmesh(8)%Coordmesh_Y = y_pined + 1
Points_Observer(ii)%Global_Coordmesh(8)%Coordmesh_Z = z_pined + 1
volu(1) = (Points_Observer(ii)%Local_Coord_To_Source%Coord_X - Coord_HZ_X(x_pined)) * (Points_Observer(ii)%Local_Coord_To_Source%Coord_Y- Coord_HZ_Y(y_pined)) *&
(Points_Observer(ii)%Local_Coord_To_Source%Coord_Z - Coord_HZ_Z(z_pined))
volu(2) = (Coord_HZ_X(x_pined+1) - Points_Observer(ii)%Local_Coord_To_Source%Coord_X) * (Points_Observer(ii)%Local_Coord_To_Source%Coord_Y- Coord_HZ_Y(y_pined)) *&
(Points_Observer(ii)%Local_Coord_To_Source%Coord_Z - Coord_HZ_Z(z_pined))
volu(3) = (Points_Observer(ii)%Local_Coord_To_Source%Coord_X - Coord_HZ_X(x_pined)) * (Coord_HZ_Y(y_pined+1) - Points_Observer(ii)%Local_Coord_To_Source%Coord_Y) *&
(Points_Observer(ii)%Local_Coord_To_Source%Coord_Z - Coord_HZ_Z(z_pined))
volu(4) = (Coord_HZ_X(x_pined+1) - Points_Observer(ii)%Local_Coord_To_Source%Coord_X) * (Coord_HZ_Y(y_pined+1) - Points_Observer(ii)%Local_Coord_To_Source%Coord_Y) *&
(Points_Observer(ii)%Local_Coord_To_Source%Coord_Z - Coord_HZ_Z(z_pined))
volu(5) = (Points_Observer(ii)%Local_Coord_To_Source%Coord_X - Coord_HZ_X(x_pined)) * (Points_Observer(ii)%Local_Coord_To_Source%Coord_Y- Coord_HZ_Y(y_pined)) *&
(Coord_HZ_Z(z_pined+1) - Points_Observer(ii)%Local_Coord_To_Source%Coord_Z)
volu(6) = (Coord_HZ_X(x_pined+1) - Points_Observer(ii)%Local_Coord_To_Source%Coord_X) * (Points_Observer(ii)%Local_Coord_To_Source%Coord_Y- Coord_HZ_Y(y_pined)) *&
(Coord_HZ_Z(z_pined+1) - Points_Observer(ii)%Local_Coord_To_Source%Coord_Z)
volu(7) = (Points_Observer(ii)%Local_Coord_To_Source%Coord_X - Coord_HZ_X(x_pined)) * (Coord_HZ_Y(y_pined+1) - Points_Observer(ii)%Local_Coord_To_Source%Coord_Y) *&
(Coord_HZ_Z(z_pined+1) - Points_Observer(ii)%Local_Coord_To_Source%Coord_Z)
volu(8) = (Coord_HZ_X(x_pined+1) - Points_Observer(ii)%Local_Coord_To_Source%Coord_X) * (Coord_HZ_Y(y_pined+1) - Points_Observer(ii)%Local_Coord_To_Source%Coord_Y) *&
(Coord_HZ_Z(z_pined+1) - Points_Observer(ii)%Local_Coord_To_Source%Coord_Z)
volu_total = (Coord_HZ_X(x_pined+1) - Coord_HZ_X(x_pined)) * (Coord_HZ_Y(y_pined+1) - Coord_HZ_Y(y_pined)) * (Coord_HZ_Z(z_pined+1) - Coord_HZ_Z(z_pined))
Points_Observer(ii)%Coeff(1) = volu(8)/volu_total
Points_Observer(ii)%Coeff(2) = volu(7)/volu_total
Points_Observer(ii)%Coeff(3) = volu(6)/volu_total
Points_Observer(ii)%Coeff(4) = volu(5)/volu_total
Points_Observer(ii)%Coeff(5) = volu(4)/volu_total
Points_Observer(ii)%Coeff(6) = volu(3)/volu_total
Points_Observer(ii)%Coeff(7) = volu(2)/volu_total
Points_Observer(ii)%Coeff(8) = volu(1)/volu_total
ENDDO
!$OMP END PARALLEL DO
!------------------------------------------------------------------------------------------!
RETURN
ENDSUBROUTINE Get_Receiver_Gridlabel
+615 -174
查看文件
@@ -1,21 +1,49 @@
!Copyright (c) 2013 by tdem.org under guide of Xiu Li(lixiu@chd.edu.cn) !Copyright (c) 2013 by https://git.em3d.cn/ under guide of Xiu Li(lixiu@chd.edu.cn)
!written by Huaifeng Sun(sunhuaifeng@gmail.com) and Xushan Lu(luxushan@gmail.com) !written by Huaifeng Sun(sunhuaifeng@email.sdu.edu.cn) and Xushan Lu(luxushan@gmail.com)
!Code distribution @ tdem.org or sunhuaifeng.com !Code distribution @ https://git.em3d.cn/
! --------------------------------Subroutine part---------------------------------------------! ! --------------------------------Subroutine part---------------------------------------------!
subroutine Iteration subroutine Iteration_cpml
use constantparameters use constantparameters
USE CONSTANTPARAMETERS USE CONSTANTPARAMETERS
USE ELECTROMAGNETIC_VARIABLES USE ELECTROMAGNETIC_VARIABLES
USE RES_MODEL_PARAMETER USE RES_MODEL_PARAMETER
USE TIME_PARAMETER USE TIME_PARAMETER
USE PML_PARAMETER
implicit none implicit none
real::t1,t2,t !t1 denotes original cpu time at the beginning of each computation fraction, t2 denotes the end cpu time and t=t2-t1 real::t1,t2,t,t_start,t_end,t_total !t1 denotes original cpu time at the beginning of each computation fraction, t2 denotes the end cpu time and t=t2-t1
REAL*8 CA,CB,DELX1,DELY1,DELZ1 !ca, cb, delx1, dely1, delz1 are all middle variables used in the computation of EM field REAL*8 CA,CB,DELX1,DELY1,DELZ1 !ca, cb, delx1, dely1, delz1 are all middle variables used in the computation of EM field
REAL*8 TEMP_SIG,temp_cacb !Temp_sig and temp_cacb are middle variables used in the computation of EM field REAL*8 TEMP_SIG,temp_cacb,data_rec(point_num) !Temp_sig and temp_cacb are middle variables used in the computation of EM field
REAL*8 DELY2,DELZ2,delx2 !They are all middle variables as above ones. REAL*8 DELY2,DELZ2,delx2 !They are all middle variables as above ones.
integer num,i,j,k,ii !num is the number of computation fraction integer num,i,j,k,ii,iii,jj,kk,idx_write,x_pos_observer(8),y_pos_observer(8),z_pos_observer(8) !num is the number of computation fraction
integer :: N_hight=0
real*8,allocatable::Meps_r(:),Mdelt(:),Msource(:),Mcq(:) !They are local substitution of eps_r, delt and cq real*8,allocatable::Meps_r(:),Mdelt(:),Msource(:),Mcq(:) !They are local substitution of eps_r, delt and cq
REAL*8 hz_observer(8)
CHARACTER*20::string,str_num
WRITE(*,*)'[Iteration_cpml] Boundary condition: CPML absorbing boundary (PML = unbounded absorbing layer, uniform grid required)'
WRITE(*,*)'[Iteration_cpml] Iteration starts .. .. .. ..'
!Create output files
idx_start=12000
do iii=1,point_num
idx_write=idx_start+iii
IF(iii<10) THEN
write(str_num,"(I1)")iii
ELSEif(iii<100) THEN
write(str_num,"(I2)")iii
ELSEif(iii<1000) THEN
write(str_num,"(I3)")iii
ENDIF
string='dBzdt'//"_"//trim(str_num)//'.txt'
open(idx_write,file=string)
write(idx_write,*)"point_"//trim(str_num)
write(idx_write,*)Points_observer(iii)%local_coord_to_source%coord_x,Points_observer(iii)%local_coord_to_source%coord_y,&
Points_observer(iii)%local_coord_to_source%coord_z
enddo
call cpu_time(t_start)
!OPEN(20250220,file='dBzdt.txt')
do num=1,num_fra_com,1 !The outer loop which begins from the first fraction ends at the last fraction do num=1,num_fra_com,1 !The outer loop which begins from the first fraction ends at the last fraction
call cpu_time(t1) !Record the cpu time at the beginning of each computing fraction call cpu_time(t1) !Record the cpu time at the beginning of each computing fraction
allocate(mdelt(0:mstop(num)),meps_r(mstop(num)),mcq(mstop(num)),msource(mstop(num))) allocate(mdelt(0:mstop(num)),meps_r(mstop(num)),mcq(mstop(num)),msource(mstop(num)))
@@ -28,237 +56,650 @@ subroutine Iteration
end do end do
print*,'Now computing fraction:',num print*,'Now computing fraction:',num
mdelt(0)=mdelt(1) mdelt(0)=mdelt(1)
!$acc data copy(Ex(1:nx,1:nyb,1:nzb),Ey(1:nxb,1:ny,1:nzb),Ez(1:nxb,1:nyb,1:nz))&
!$acc copy(Hx(1:nxb,1:ny,0:nz),Hy(1:nx,1:nyb,0:nz),Hz(1:nx,1:ny,1:nzb)),copyin(cdelx(1:nx))&
!$acc copyin(ccsig(1:nx,1:ny,1:nz),mdelt(0:mstop(num)),cdely(1:ny),cdelz(1:nz),mcq(1:mstop(num)),meps_r(1:mstop(num)))&
!$acc copyin(is_ex_in_source(1:nx,2:nyb-1),is_ey_in_source(2:nx,1:ny),msource(1:mstop(num)))
! OpenACC directive, copy in and out of Ex,Ey,Ez,Hx,Hy,Hz, copy in ccsig, mdelt, cdelz, mcq, meps_r, is_ex_in_source, is_ey_in_source
do loop=1,mstop(num),1 do loop=1,mstop(num),1
! --------------------------------update the value of Ex and Ey in source area---------------------------------------! ! --------------------------------CPML coefficients b/c of the current time step-------------------------------!
!$acc parallel async(1) ! b = exp(-(sig/kappa+alpha)*delt/eps0), c = sig*(b-1)/(sig+kappa*alpha)/kappa
!$acc loop gang ! They are recomputed at every step because MDELT changes between the raise, wave, ramp and off phases.
! The sigma/alpha/kappa profiles are built once by Get_pml_parameters.
! When Logic_PML=0 this whole block is skipped and the original Dirichlet boundary scheme is used.
DO i=1,PML_X1
b_e_x1(i)=DEXP(-(sig_PML_e_x1(i)/kappa_PML_e_x1(i)+alpha_PML_e_x1(i))*MDELT(LOOP-1)/EPS0)
IF(sig_PML_e_x1(i)==0.0 .AND. alpha_PML_e_x1(i)==0.0 .AND. i==PML_X1)THEN
c_e_x1(i)=0.0
ELSE
c_e_x1(i)=sig_PML_e_x1(i)*(b_e_x1(i)-1.0)/(sig_PML_e_x1(i)+kappa_PML_e_x1(i)*alpha_PML_e_x1(i))/kappa_PML_e_x1(i)
ENDIF
ENDDO
DO ii=1,PML_X1-1
b_h_x1(ii)=DEXP(-(sig_PML_h_x1(ii)/kappa_PML_h_x1(ii)+alpha_PML_h_x1(ii))*MDELT(LOOP-1)/EPS0)
c_h_x1(ii)=sig_PML_h_x1(ii)*(b_h_x1(ii)-1.0)/(sig_PML_h_x1(ii)+kappa_PML_h_x1(ii)*alpha_PML_h_x1(ii))/kappa_PML_h_x1(ii)
ENDDO
DO i=1,PML_X2
b_e_x2(i)=DEXP(-(sig_PML_e_x2(i)/kappa_PML_e_x2(i)+alpha_PML_e_x2(i))*MDELT(LOOP-1)/EPS0)
IF(sig_PML_e_x2(i)==0.0 .AND. alpha_PML_e_x2(i)==0.0 .AND. i==PML_X2)THEN
c_e_x2(i)=0.0
ELSE
c_e_x2(i)=sig_PML_e_x2(i)*(b_e_x2(i)-1.0)/(sig_PML_e_x2(i)+kappa_PML_e_x2(i)*alpha_PML_e_x2(i))/kappa_PML_e_x2(i)
ENDIF
ENDDO
DO ii=1,PML_X2-1
b_h_x2(ii)=DEXP(-(sig_PML_h_x2(ii)/kappa_PML_h_x2(ii)+alpha_PML_h_x2(ii))*MDELT(LOOP-1)/EPS0)
c_h_x2(ii)=sig_PML_h_x2(ii)*(b_h_x2(ii)-1.0)/(sig_PML_h_x2(ii)+kappa_PML_h_x2(ii)*alpha_PML_h_x2(ii))/kappa_PML_h_x2(ii)
ENDDO
DO j=1,PML_Y1
b_e_y1(j)=DEXP(-(sig_PML_e_y1(j)/kappa_PML_e_y1(j)+alpha_PML_e_y1(j))*MDELT(LOOP-1)/EPS0)
IF(sig_PML_e_y1(j)==0.0 .AND. alpha_PML_e_y1(j)==0.0 .AND. j==PML_Y1)THEN
c_e_y1(j)=0.0
ELSE
c_e_y1(j)=sig_PML_e_y1(j)*(b_e_y1(j)-1.0)/(sig_PML_e_y1(j)+kappa_PML_e_y1(j)*alpha_PML_e_y1(j))/kappa_PML_e_y1(j)
ENDIF
ENDDO
DO jj=1,PML_Y1-1
b_h_y1(jj)=DEXP(-(sig_PML_h_y1(jj)/kappa_PML_h_y1(jj)+alpha_PML_h_y1(jj))*MDELT(LOOP-1)/EPS0)
c_h_y1(jj)=sig_PML_h_y1(jj)*(b_h_y1(jj)-1.0)/(sig_PML_h_y1(jj)+kappa_PML_h_y1(jj)*alpha_PML_h_y1(jj))/kappa_PML_h_y1(jj)
ENDDO
DO j=1,PML_Y2
b_e_y2(j)=DEXP(-(sig_PML_e_y2(j)/kappa_PML_e_y2(j)+alpha_PML_e_y2(j))*MDELT(LOOP-1)/EPS0)
IF(sig_PML_e_y2(j)==0.0 .AND. alpha_PML_e_y2(j)==0.0 .AND. j==PML_Y2)THEN
c_e_y2(j)=0.0
ELSE
c_e_y2(j)=sig_PML_e_y2(j)*(b_e_y2(j)-1.0)/(sig_PML_e_y2(j)+kappa_PML_e_y2(j)*alpha_PML_e_y2(j))/kappa_PML_e_y2(j)
ENDIF
ENDDO
DO jj=1,PML_Y2-1
b_h_y2(jj)=DEXP(-(sig_PML_h_y2(jj)/kappa_PML_h_y2(jj)+alpha_PML_h_y2(jj))*MDELT(LOOP-1)/EPS0)
c_h_y2(jj)=sig_PML_h_y2(jj)*(b_h_y2(jj)-1.0)/(sig_PML_h_y2(jj)+kappa_PML_h_y2(jj)*alpha_PML_h_y2(jj))/kappa_PML_h_y2(jj)
ENDDO
DO k=1,PML_Z1
b_e_z1(k)=DEXP(-(sig_PML_e_z1(k)/kappa_PML_e_z1(k)+alpha_PML_e_z1(k))*MDELT(LOOP-1)/EPS0)
IF(sig_PML_e_z1(k)==0.0 .AND. alpha_PML_e_z1(k)==0.0 .AND. k==PML_Z1)THEN
c_e_z1(k)=0.0
ELSE
c_e_z1(k)=sig_PML_e_z1(k)*(b_e_z1(k)-1.0)/(sig_PML_e_z1(k)+kappa_PML_e_z1(k)*alpha_PML_e_z1(k))/kappa_PML_e_z1(k)
ENDIF
ENDDO
DO kk=1,PML_Z1-1
b_h_z1(kk)=DEXP(-(sig_PML_h_z1(kk)/kappa_PML_h_z1(kk)+alpha_PML_h_z1(kk))*MDELT(LOOP-1)/EPS0)
c_h_z1(kk)=sig_PML_h_z1(kk)*(b_h_z1(kk)-1.0)/(sig_PML_h_z1(kk)+kappa_PML_h_z1(kk)*alpha_PML_h_z1(kk))/kappa_PML_h_z1(kk)
ENDDO
DO k=1,PML_Z2
b_e_z2(k)=DEXP(-(sig_PML_e_z2(k)/kappa_PML_e_z2(k)+alpha_PML_e_z2(k))*MDELT(LOOP-1)/EPS0)
IF(sig_PML_e_z2(k)==0.0 .AND. alpha_PML_e_z2(k)==0.0 .AND. k==PML_Z2)THEN
c_e_z2(k)=0.0
ELSE
c_e_z2(k)=sig_PML_e_z2(k)*(b_e_z2(k)-1.0)/(sig_PML_e_z2(k)+kappa_PML_e_z2(k)*alpha_PML_e_z2(k))/kappa_PML_e_z2(k)
ENDIF
ENDDO
DO kk=1,PML_Z2-1
b_h_z2(kk)=DEXP(-(sig_PML_h_z2(kk)/kappa_PML_h_z2(kk)+alpha_PML_h_z2(kk))*MDELT(LOOP-1)/EPS0)
c_h_z2(kk)=sig_PML_h_z2(kk)*(b_h_z2(kk)-1.0)/(sig_PML_h_z2(kk)+kappa_PML_h_z2(kk)*alpha_PML_h_z2(kk))/kappa_PML_h_z2(kk)
ENDDO
!Assemble c_h_zz used by the Hz recursion in the z direction.
DO k=1,PML_Z1-1
c_h_zz(k)=c_h_z1(k)
ENDDO
DO k=NZ+2-PML_Z2,NZ
c_h_zz(k)=c_h_z2(NZ+1-k)
ENDDO
!Precompute the inverse denominator of the Hz recursion once per step
!(bit-for-bit neutral when Logic_PML=0: inv_hz_den stays 1.0 from ZERO).
DO k=1,NZ
inv_hz_den(k)=1.0D0/(den_hz(k)+c_h_zz(k))
ENDDO
! --------------------------------update the value of Ex ---------------------------------------!
! 忠实移植自参考版 tem3dfdtd_第二版(孙师兄版):psi 内嵌在场更新循环内,
! 循环结构 DO I / DO K / DO J;源项仅在源平面 K=NZS+1 施加(当前项目 2D 掩码,
! 等价参考版 3D 掩码在非源平面层为 0)。
DO I=1,NX
DO K=2,NZB-1
DO J=2,NYB-1 DO J=2,NYB-1
!$acc loop vector
DO I=1,NX
K=NZ/2+1
DELY1=(CDELY(J-1)+CDELY(J))/2.0D0
DELZ1=CDELZ(NZ/2+1)
TEMP_SIG=CCSIG(I,J-1,K-1)*CDELY(J-1)*CDELZ(K-1)&
&+CCSIG(I,J-1,K)*CDELY(J-1)*CDELZ(K)&
&+CCSIG(I,J,K-1)*CDELY(J)*CDELZ(K-1)&
&+CCSIG(I,J,K)*CDELY(J)*CDELZ(K)
TEMP_SIG=TEMP_SIG/(4.0D0*DELY1*DELZ1)
CA=(2.0D0*Meps_r(loop)-Mdelt(LOOP-1)*TEMP_SIG)/(2.0*Meps_r(loop)+Mdelt(LOOP-1)*TEMP_SIG)
CB=(2.0D0*MDELT(LOOP-1))/(2.0*Meps_r(loop)+MDELT(LOOP-1)*TEMP_SIG)
EX(I,J,K)=CA*EX(I,J,K)+CB*((HZ(I,J,K)-HZ(I,J-1,K))/DELY1-(HY(I,J,K)-HY(I,J,K-1))/DELZ1)-cb*Msource(loop)*is_ex_in_source(i,j)
ENDDO
ENDDO
!$acc end parallel
! end of updating Ex while k=Nzs+1
! update the value of Ey while k=Nzs+1
!$acc parallel async(2)
!$acc loop gang
DO J=1,NY
!$acc loop vector
DO I=2,NX
K=NZ/2+1
DELX1=(CDELX(I-1)+CDELX(I))/2.0
DELZ1=CDELZ(NZ/2+1)
TEMP_SIG=CCSIG(I-1,J,K-1)*CDELX(I-1)*CDELZ(K-1)&
&+CCSIG(I-1,J,K)*CDELX(I-1)*CDELZ(K)&
&+CCSIG(I,J,K-1)*CDELX(I)*CDELZ(K-1)&
&+CCSIG(I,J,K)*CDELX(I)*CDELZ(K)
TEMP_SIG=TEMP_SIG/(4.0D0*DELX1*DELZ1)
CA=(2.0D0*Meps_r(loop)-MDELT(LOOP-1)*TEMP_SIG)/(2.0D0*Meps_r(loop)+MDELT(LOOP-1)*TEMP_SIG)
CB=(2.0D0*MDELT(LOOP-1))/(2.0D0*Meps_r(loop)+MDELT(LOOP-1)*TEMP_SIG)
EY(I,J,K)=CA*EY(I,J,K)+CB*((HX(I,J,K)-HX(I,J,K-1))/DELZ1-(HZ(I,J,K)-HZ(I-1,J,K))/DELX1)-cb*Msource(loop)*is_ey_in_source(i,j)
ENDDO
ENDDO
!$acc end parallel
! end of uptating Ey while k=Nzs+1
! ---------------------------------------------------Ex Part-------------------------------------------------------------!
!$acc parallel async(3)
!$acc loop gang
DO K=NZ/2+2,NZ
!$acc loop worker
DO J=2,NY
!$acc loop vector
DO I=1,NX
DELY1=(CDELY(J-1)+CDELY(J))/2.0D0 DELY1=(CDELY(J-1)+CDELY(J))/2.0D0
DELZ1=(CDELZ(K-1)+CDELZ(K))/2.0D0 DELZ1=(CDELZ(K-1)+CDELZ(K))/2.0D0
TEMP_SIG=CCSIG(I,J-1,K-1)*CDELY(J-1)*CDELZ(K-1)& CA=(2.0D0*Meps_r(loop)-Mdelt(LOOP-1)*CCSIGX(I,J,K))/(2.0D0*Meps_r(loop)+Mdelt(LOOP-1)*CCSIGX(I,J,K))
&+CCSIG(I,J-1,K)*CDELY(J-1)*CDELZ(K)& CB=(2.0D0*MDELT(LOOP-1))/(2.0D0*Meps_r(loop)+MDELT(LOOP-1)*CCSIGX(I,J,K))
&+CCSIG(I,J,K-1)*CDELY(J)*CDELZ(K-1)& EX(I,J,K)=CA*EX(I,J,K)+CB*((HZ(I,J,K)-HZ(I,J-1,K))*den_ey(J)/DELY1&
&+CCSIG(I,J,K)*CDELY(J)*CDELZ(K) &-(HY(I,J,K)-HY(I,J,K-1))*den_ez(K)/DELZ1)
TEMP_SIG=TEMP_SIG/(4.0D0*DELY1*DELZ1) IF(K==NZS+1)THEN
CA=(2.0D0*Meps_r(loop)-MDELT(LOOP-1)*TEMP_SIG)/(2.0D0*Meps_r(loop)+MDELT(LOOP-1)*TEMP_SIG) EX(I,J,K)=EX(I,J,K)-CB*Msource(loop)*is_ex_in_source(I,J)
CB=(2.0D0*MDELT(LOOP-1))/(2.0D0*Meps_r(loop)+MDELT(LOOP-1)*TEMP_SIG) ENDIF
EX(I,J,K)=CA*EX(I,J,K)+CB*((HZ(I,J,K)-HZ(I,J-1,K))/DELY1-(HY(I,J,K)-HY(I,J,K-1))/DELZ1) ! PML for Ex, y-direction
IF(J<=PML_Y1)THEN
psi_Exy_1(I,J,K)=b_e_y1(J)*psi_Exy_1(I,J,K)+c_e_y1(J)*(HZ(I,J,K)-HZ(I,J-1,K))/DELY1
EX(I,J,K)=EX(I,J,K)+CB*psi_Exy_1(I,J,K)
ELSEIF(J>=NY+2-PML_Y2)THEN
psi_Exy_2(I,NY+2-J,K)=b_e_y2(NY+2-J)*psi_Exy_2(I,NY+2-J,K)+c_e_y2(NY+2-J)*(HZ(I,J,K)-HZ(I,J-1,K))/DELY1
EX(I,J,K)=EX(I,J,K)+CB*psi_Exy_2(I,NY+2-J,K)
ENDIF
! PML for Ex, z-direction
IF(K<=PML_Z1)THEN
psi_Exz_1(I,J,K)=b_e_z1(K)*psi_Exz_1(I,J,K)+c_e_z1(K)*(HY(I,J,K)-HY(I,J,K-1))/DELZ1
EX(I,J,K)=EX(I,J,K)-CB*psi_Exz_1(I,J,K)
ELSEIF(K>=NZ+2-PML_Z2)THEN
psi_Exz_2(I,J,NZ+2-K)=b_e_z2(NZ+2-K)*psi_Exz_2(I,J,NZ+2-K)+c_e_z2(NZ+2-K)*(HY(I,J,K)-HY(I,J,K-1))/DELZ1
EX(I,J,K)=EX(I,J,K)-CB*psi_Exz_2(I,J,NZ+2-K)
ENDIF
ENDDO ENDDO
ENDDO ENDDO
ENDDO ENDDO
!$acc end parallel !===============end of updating Ex=========================!
!$acc parallel async(4) ! --------------------------------update the value of Ey ---------------------------------------!
!$acc loop gang
DO K=2,NZ/2
!$acc loop worker
DO J=2,NY
!$acc loop vector
DO I=1,NX
DELY1=(CDELY(J-1)+CDELY(J))/2.0D0
DELZ1=(CDELZ(K-1)+CDELZ(K))/2.0D0
TEMP_SIG=CCSIG(I,J-1,K-1)*CDELY(J-1)*CDELZ(K-1)&
&+CCSIG(I,J-1,K)*CDELY(J-1)*CDELZ(K)&
&+CCSIG(I,J,K-1)*CDELY(J)*CDELZ(K-1)&
&+CCSIG(I,J,K)*CDELY(J)*CDELZ(K)
TEMP_SIG=TEMP_SIG/(4.0D0*DELY1*DELZ1)
CA=(2.0D0*Meps_r(loop)-MDELT(LOOP-1)*TEMP_SIG)/(2.0D0*Meps_r(loop)+MDELT(LOOP-1)*TEMP_SIG)
CB=(2.0D0*MDELT(LOOP-1))/(2.0D0*Meps_r(loop)+MDELT(LOOP-1)*TEMP_SIG)
EX(I,J,K)=CA*EX(I,J,K)+CB*((HZ(I,J,K)-HZ(I,J-1,K))/DELY1-(HY(I,J,K)-HY(I,J,K-1))/DELZ1)
ENDDO
ENDDO
ENDDO
!$acc end parallel
! ================end of updating Ex==================!
! -----------------------------------------update the value of Ey--------------------------------!
!$acc parallel async(5)
!$acc loop gang
DO K=NZ/2+2,NZ
!$acc loop worker
DO J=1,NY DO J=1,NY
!$acc loop vector DO K=2,NZB-1
DO I=2,NX
DELX1=(CDELX(I-1)+CDELX(I))/2.0D0
DELZ1=(CDELZ(K-1)+CDELZ(K))/2.0D0
TEMP_SIG=CCSIG(I-1,J,K-1)*CDELX(I-1)*CDELZ(K-1)&
&+CCSIG(I-1,J,K)*CDELX(I-1)*CDELZ(K)&
&+CCSIG(I,J,K-1)*CDELX(I)*CDELZ(K-1)&
&+CCSIG(I,J,K)*CDELX(I)*CDELZ(K)
TEMP_SIG=TEMP_SIG/(4.0D0*DELX1*DELZ1)
CA=(2.0D0*Meps_r(loop)-MDELT(LOOP-1)*TEMP_SIG)/(2.0D0*Meps_r(loop)+MDELT(LOOP-1)*TEMP_SIG)
CB=(2.0D0*MDELT(LOOP-1))/(2.0D0*Meps_r(loop)+MDELT(LOOP-1)*TEMP_SIG)
EY(I,J,K)=CA*EY(I,J,K)+CB*((HX(I,J,K)-HX(I,J,K-1))/DELZ1-(HZ(I,J,K)-HZ(I-1,J,K))/DELX1)
ENDDO
ENDDO
ENDDO
!$acc end parallel
!$acc parallel async(6)
!$acc loop gang
DO K=2,NZ/2
!$acc loop worker
DO J=1,NY
!$acc loop vector
DO I=2,NXB-1 DO I=2,NXB-1
DELX1=(CDELX(I-1)+CDELX(I))/2.0D0 DELX1=(CDELX(I-1)+CDELX(I))/2.0D0
DELZ1=(CDELZ(K-1)+CDELZ(K))/2.0D0 DELZ1=(CDELZ(K-1)+CDELZ(K))/2.0D0
TEMP_SIG=CCSIG(I-1,J,K-1)*CDELX(I-1)*CDELZ(K-1)& CA=(2.0D0*Meps_r(loop)-MDELT(LOOP-1)*CCSIGY(I,J,K))/(2.0D0*Meps_r(loop)+MDELT(LOOP-1)*CCSIGY(I,J,K))
&+CCSIG(I-1,J,K)*CDELX(I-1)*CDELZ(K)& CB=(2.0D0*MDELT(LOOP-1))/(2.0D0*Meps_r(loop)+MDELT(LOOP-1)*CCSIGY(I,J,K))
&+CCSIG(I,J,K-1)*CDELX(I)*CDELZ(K-1)& EY(I,J,K)=CA*EY(I,J,K)+CB*((HX(I,J,K)-HX(I,J,K-1))*den_ez(K)/DELZ1&
&+CCSIG(I,J,K)*CDELX(I)*CDELZ(K) &-(HZ(I,J,K)-HZ(I-1,J,K))*den_ex(I)/DELX1)
TEMP_SIG=TEMP_SIG/(4.0D0*DELX1*DELZ1) IF(K==NZS+1)THEN
CA=(2.0D0*Meps_r(loop)-MDELT(LOOP-1)*TEMP_SIG)/(2.0D0*Meps_r(loop)+MDELT(LOOP-1)*TEMP_SIG) EY(I,J,K)=EY(I,J,K)-CB*Msource(loop)*is_ey_in_source(I,J)
CB=(2.0D0*MDELT(LOOP-1))/(2.0D0*Meps_r(loop)+MDELT(LOOP-1)*TEMP_SIG) ENDIF
EY(I,J,K)=CA*EY(I,J,K)+CB*((HX(I,J,K)-HX(I,J,K-1))/DELZ1-(HZ(I,J,K)-HZ(I-1,J,K))/DELX1) ! PML for Ey, z-direction
IF(K<=PML_Z1)THEN
psi_Eyz_1(I,J,K)=b_e_z1(K)*psi_Eyz_1(I,J,K)+c_e_z1(K)*(HX(I,J,K)-HX(I,J,K-1))/DELZ1
EY(I,J,K)=EY(I,J,K)+CB*psi_Eyz_1(I,J,K)
ELSEIF(K>=NZ+2-PML_Z2)THEN
psi_Eyz_2(I,J,NZ+2-K)=b_e_z2(NZ+2-K)*psi_Eyz_2(I,J,NZ+2-K)+c_e_z2(NZ+2-K)*(HX(I,J,K)-HX(I,J,K-1))/DELZ1
EY(I,J,K)=EY(I,J,K)+CB*psi_Eyz_2(I,J,NZ+2-K)
ENDIF
! PML for Ey, x-direction
IF(I<=PML_X1)THEN
psi_Eyx_1(I,J,K)=b_e_x1(I)*psi_Eyx_1(I,J,K)+c_e_x1(I)*(HZ(I,J,K)-HZ(I-1,J,K))/DELX1
EY(I,J,K)=EY(I,J,K)-CB*psi_Eyx_1(I,J,K)
ELSEIF(I>=NX+2-PML_X2)THEN
psi_Eyx_2(NX+2-I,J,K)=b_e_x2(NX+2-I)*psi_Eyx_2(NX+2-I,J,K)+c_e_x2(NX+2-I)*(HZ(I,J,K)-HZ(I-1,J,K))/DELX1
EY(I,J,K)=EY(I,J,K)-CB*psi_Eyx_2(NX+2-I,J,K)
ENDIF
ENDDO ENDDO
ENDDO ENDDO
ENDDO ENDDO
!$acc end parallel
!===============end of updating Ey===================! !===============end of updating Ey===================!
! -------------------------------------update the value of Ez--------------------------------------! ! -------------------------------------update the value of Ez--------------------------------------!
!$acc parallel async(7)
!$acc loop gang
DO K=1,NZ DO K=1,NZ
!$acc loop worker
DO J=2,NYB-1 DO J=2,NYB-1
!$acc loop vector
DO I=2,NXB-1 DO I=2,NXB-1
DELX1=(CDELX(I-1)+CDELX(I))/2.0D0 DELX1=(CDELX(I-1)+CDELX(I))/2.0D0
DELY1=(CDELY(J-1)+CDELY(J))/2.0D0 DELY1=(CDELY(J-1)+CDELY(J))/2.0D0
TEMP_SIG=CCSIG(I-1,J-1,K)*CDELX(I-1)*CDELY(J-1)& TEMP_CACB=2.0D0*Meps_r(loop)+MDELT(LOOP-1)*CCSIGZ(I,J,K)
&+CCSIG(I-1,J,K)*CDELX(I-1)*CDELY(J)& CA=(2.0D0*Meps_r(loop)-MDELT(LOOP-1)*CCSIGZ(I,J,K))/TEMP_CACB
&+CCSIG(I,J-1,K)*CDELX(I)*CDELY(J-1)&
&+CCSIG(I,J,K)*CDELX(I)*CDELY(J)
TEMP_SIG=TEMP_SIG/(4.0D0*DELX1*DELY1)
TEMP_CACB=2.0D0*Meps_r(loop)+MDELT(LOOP-1)*TEMP_SIG
CA=(2.0D0*Meps_r(loop)-MDELT(LOOP-1)*TEMP_SIG)/TEMP_CACB
CB=(2.0D0*MDELT(LOOP-1))/TEMP_CACB CB=(2.0D0*MDELT(LOOP-1))/TEMP_CACB
EZ(I,J,K)=CA*EZ(I,J,K)+CB*((HY(I,J,K)-HY(I-1,J,K))/DELX1-(HX(I,J,K)-HX(I,J-1,K))/DELY1) EZ(I,J,K)=CA*EZ(I,J,K)+CB*((HY(I,J,K)-HY(I-1,J,K))*den_ex(I)/DELX1&
&-(HX(I,J,K)-HX(I,J-1,K))*den_ey(J)/DELY1)
! PML for Ez, x-direction
IF(I<=PML_X1)THEN
psi_Ezx_1(I,J,K)=b_e_x1(I)*psi_Ezx_1(I,J,K)+c_e_x1(I)*(HY(I,J,K)-HY(I-1,J,K))/DELX1
EZ(I,J,K)=EZ(I,J,K)+CB*psi_Ezx_1(I,J,K)
ELSEIF(I>=NX+2-PML_X2)THEN
psi_Ezx_2(NX+2-I,J,K)=b_e_x2(NX+2-I)*psi_Ezx_2(NX+2-I,J,K)+c_e_x2(NX+2-I)*(HY(I,J,K)-HY(I-1,J,K))/DELX1
EZ(I,J,K)=EZ(I,J,K)+CB*psi_Ezx_2(NX+2-I,J,K)
ENDIF
! PML for Ez, y-direction
IF(J<=PML_Y1)THEN
psi_Ezy_1(I,J,K)=b_e_y1(J)*psi_Ezy_1(I,J,K)+c_e_y1(J)*(HX(I,J,K)-HX(I,J-1,K))/DELY1
EZ(I,J,K)=EZ(I,J,K)-CB*psi_Ezy_1(I,J,K)
ELSEIF(J>=NY+2-PML_Y2)THEN
psi_Ezy_2(I,NY+2-J,K)=b_e_y2(NY+2-J)*psi_Ezy_2(I,NY+2-J,K)+c_e_y2(NY+2-J)*(HX(I,J,K)-HX(I,J-1,K))/DELY1
EZ(I,J,K)=EZ(I,J,K)-CB*psi_Ezy_2(I,NY+2-J,K)
ENDIF
ENDDO
ENDDO
ENDDO
!===============end of updating Ez=========================!
! ------------------------------------update the value of Hx-----------------------------------------------!
DO I=1,NXB
DO K=1,NZ
DO J=1,NY
HX(I,J,K)=HX(I,J,K)-MCQ(LOOP)*((EZ(I,J+1,K)-EZ(I,J,K))*den_hy(J))/CDELY(J)&
&+MCQ(LOOP)*((EY(I,J,K+1)-EY(I,J,K))*den_hz(K))/CDELZ(K)
! PML for Hx, y-direction
IF(J<=PML_Y1-1)THEN
psi_Hxy_1(I,J,K)=b_h_y1(J)*psi_Hxy_1(I,J,K)+c_h_y1(J)*(EZ(I,J+1,K)-EZ(I,J,K))/CDELY(J)
HX(I,J,K)=HX(I,J,K)-MCQ(LOOP)*psi_Hxy_1(I,J,K)
ELSEIF(J>=NY+2-PML_Y2)THEN
psi_Hxy_2(I,NY+1-J,K)=b_h_y2(NY+1-J)*psi_Hxy_2(I,NY+1-J,K)+c_h_y2(NY+1-J)*(EZ(I,J+1,K)-EZ(I,J,K))/CDELY(J)
HX(I,J,K)=HX(I,J,K)-MCQ(LOOP)*psi_Hxy_2(I,NY+1-J,K)
ENDIF
! PML for Hx, z-direction
IF(K<=PML_Z1-1)THEN
psi_Hxz_1(I,J,K)=b_h_z1(K)*psi_Hxz_1(I,J,K)+c_h_z1(K)*(EY(I,J,K+1)-EY(I,J,K))/CDELZ(K)
HX(I,J,K)=HX(I,J,K)+MCQ(LOOP)*psi_Hxz_1(I,J,K)
ELSEIF(K>=NZ+2-PML_Z2)THEN
psi_Hxz_2(I,J,NZ+1-K)=b_h_z2(NZ+1-K)*psi_Hxz_2(I,J,NZ+1-K)+c_h_z2(NZ+1-K)*(EY(I,J,K+1)-EY(I,J,K))/CDELZ(K)
HX(I,J,K)=HX(I,J,K)+MCQ(LOOP)*psi_Hxz_2(I,J,NZ+1-K)
ENDIF
ENDDO
ENDDO
ENDDO
!================end of updating Hx=======================!
! -------------------------------------update the value of Hy---------------------------------------------!
DO J=1,NYB
DO K=1,NZ
DO I=1,NX
HY(I,J,K)=HY(I,J,K)-MCQ(LOOP)*((EX(I,J,K+1)-EX(I,J,K))*den_hz(K))/CDELZ(K)&
&+MCQ(LOOP)*((EZ(I+1,J,K)-EZ(I,J,K))*den_hx(I))/CDELX(I)
! PML for Hy, x-direction
IF(I<=PML_X1-1)THEN
psi_Hyx_1(I,J,K)=b_h_x1(I)*psi_Hyx_1(I,J,K)+c_h_x1(I)*(EZ(I+1,J,K)-EZ(I,J,K))/CDELX(I)
HY(I,J,K)=HY(I,J,K)+MCQ(LOOP)*psi_Hyx_1(I,J,K)
ELSEIF(I>=NX+2-PML_X2)THEN
psi_Hyx_2(NX+1-I,J,K)=b_h_x2(NX+1-I)*psi_Hyx_2(NX+1-I,J,K)+c_h_x2(NX+1-I)*(EZ(I+1,J,K)-EZ(I,J,K))/CDELX(I)
HY(I,J,K)=HY(I,J,K)+MCQ(LOOP)*psi_Hyx_2(NX+1-I,J,K)
ENDIF
! PML for Hy, z-direction
IF(K<=PML_Z1-1)THEN
psi_Hyz_1(I,J,K)=b_h_z1(K)*psi_Hyz_1(I,J,K)+c_h_z1(K)*(EX(I,J,K+1)-EX(I,J,K))/CDELZ(K)
HY(I,J,K)=HY(I,J,K)-MCQ(LOOP)*psi_Hyz_1(I,J,K)
ELSEIF(K>=NZ+2-PML_Z2)THEN
psi_Hyz_2(I,J,NZ+1-K)=b_h_z2(NZ+1-K)*psi_Hyz_2(I,J,NZ+1-K)+c_h_z2(NZ+1-K)*(EX(I,J,K+1)-EX(I,J,K))/CDELZ(K)
HY(I,J,K)=HY(I,J,K)-MCQ(LOOP)*psi_Hyz_2(I,J,NZ+1-K)
ENDIF
ENDDO
ENDDO
ENDDO
!===============end of updating Hy========================!
!-------------------------------------update the value of Hz----------------------------------------------!
! 上扫 k=1..NZS-1(参考版原样):HZ(I,J,K+1) 由 HZ(I,J,K) 推出,psi 修正内嵌。
DO K=1,NZs-1
DO I=1,NX
DO J=1,NY
HZ(I,J,K+1)=HZ(I,J,K)-((CDELZ(K)*den_hx(I))/(den_hz(K)+c_h_zz(K)))*((HX(I+1,J,K)-HX(I,J,K))/CDELX(I))&
&-((CDELZ(K)*den_hy(J))/(den_hz(K)+c_h_zz(K)))*((HY(I,J+1,K)-HY(I,J,K))/CDELY(J))
! PML for Hz up, x-direction
IF(I<=PML_X1-1)THEN
psi_Hzx_1(I,J,K)=b_h_x1(I)*psi_Hzx_1(I,J,K)+c_h_x1(I)*((HX(I+1,J,K)-HX(I,J,K))/CDELX(I))
HZ(I,J,K+1)=HZ(I,J,K+1)-((CDELZ(K))/(den_hz(K)+c_h_zz(K)))*psi_Hzx_1(I,J,K)
ELSEIF(I>=NX+2-PML_X2)THEN
psi_Hzx_2(NX+1-I,J,K)=b_h_x2(NX+1-I)*psi_Hzx_2(NX+1-I,J,K)+c_h_x2(NX+1-I)*((HX(I+1,J,K)-HX(I,J,K))/CDELX(I))
HZ(I,J,K+1)=HZ(I,J,K+1)-((CDELZ(K))/(den_hz(K)+c_h_zz(K)))*psi_Hzx_2(NX+1-I,J,K)
ENDIF
! PML for Hz up, y-direction
IF(J<=PML_Y1-1)THEN
psi_Hzy_1(I,J,K)=b_h_y1(J)*psi_Hzy_1(I,J,K)+c_h_y1(J)*((HY(I,J+1,K)-HY(I,J,K))/CDELY(J))
HZ(I,J,K+1)=HZ(I,J,K+1)-((CDELZ(K))/(den_hz(K)+c_h_zz(K)))*psi_Hzy_1(I,J,K)
ELSEIF(J>=NY+2-PML_Y2)THEN
psi_Hzy_2(I,NY+1-J,K)=b_h_y2(NY+1-J)*psi_Hzy_2(I,NY+1-J,K)+c_h_y2(NY+1-J)*((HY(I,J+1,K)-HY(I,J,K))/CDELY(J))
HZ(I,J,K+1)=HZ(I,J,K+1)-((CDELZ(K))/(den_hz(K)+c_h_zz(K)))*psi_Hzy_2(I,NY+1-J,K)
ENDIF
ENDDO
ENDDO
ENDDO
! 下扫 k=NZ..NZS+1(参考版原样):HZ(I,J,K) 由 HZ(I,J,K+1) 推出(HZ(NZ+1) 保持 0),psi 修正内嵌。
DO K=NZ,NZs+1,-1
DO I=1,NX
DO J=1,NY
HZ(I,J,K)=HZ(I,J,K+1)+((CDELZ(K)*den_hx(I))/(den_hz(K)+c_h_zz(K)))*((HX(I+1,J,K)-HX(I,J,K))/CDELX(I))&
&+((CDELZ(K)*den_hy(J))/(den_hz(K)+c_h_zz(K)))*((HY(I,J+1,K)-HY(I,J,K))/CDELY(J))
! PML for Hz down, x-direction
IF(I<=PML_X1-1)THEN
psi_Hzx_1(I,J,K)=b_h_x1(I)*psi_Hzx_1(I,J,K)+c_h_x1(I)*((HX(I+1,J,K)-HX(I,J,K))/CDELX(I))
HZ(I,J,K)=HZ(I,J,K)+((CDELZ(K))/(den_hz(K)+c_h_zz(K)))*psi_Hzx_1(I,J,K)
ELSEIF(I>=NX+2-PML_X2)THEN
psi_Hzx_2(NX+1-I,J,K)=b_h_x2(NX+1-I)*psi_Hzx_2(NX+1-I,J,K)+c_h_x2(NX+1-I)*((HX(I+1,J,K)-HX(I,J,K))/CDELX(I))
HZ(I,J,K)=HZ(I,J,K)+((CDELZ(K))/(den_hz(K)+c_h_zz(K)))*psi_Hzx_2(NX+1-I,J,K)
ENDIF
! PML for Hz down, y-direction
IF(J<=PML_Y1-1)THEN
psi_Hzy_1(I,J,K)=b_h_y1(J)*psi_Hzy_1(I,J,K)+c_h_y1(J)*((HY(I,J+1,K)-HY(I,J,K))/CDELY(J))
HZ(I,J,K)=HZ(I,J,K)+((CDELZ(K))/(den_hz(K)+c_h_zz(K)))*psi_Hzy_1(I,J,K)
ELSEIF(J>=NY+2-PML_Y2)THEN
psi_Hzy_2(I,NY+1-J,K)=b_h_y2(NY+1-J)*psi_Hzy_2(I,NY+1-J,K)+c_h_y2(NY+1-J)*((HY(I,J+1,K)-HY(I,J,K))/CDELY(J))
HZ(I,J,K)=HZ(I,J,K)+((CDELZ(K))/(den_hz(K)+c_h_zz(K)))*psi_Hzy_2(I,NY+1-J,K)
ENDIF
ENDDO
ENDDO
ENDDO
!===================end of updating Hz==========================!
DO i=1,point_num
!=================================point1=======================================
x_pos_observer(1)=Points_observer(i)%global_coordmesh(1)%coordmesh_x
y_pos_observer(1)=Points_observer(i)%global_coordmesh(1)%coordmesh_y
z_pos_observer(1)=Points_observer(i)%global_coordmesh(1)%coordmesh_z
hz_observer(1)=(EX(x_pos_observer(1),y_pos_observer(1)+1,z_pos_observer(1))-EX(x_pos_observer(1),y_pos_observer(1),z_pos_observer(1)))/CDELY(y_pos_observer(1))-&
(EY(x_pos_observer(1)+1,y_pos_observer(1),z_pos_observer(1))-EY(x_pos_observer(1),y_pos_observer(1),z_pos_observer(1)))/CDELX(x_pos_observer(1))
!=================================point2=======================================
x_pos_observer(2)=Points_observer(i)%global_coordmesh(2)%coordmesh_x
y_pos_observer(2)=Points_observer(i)%global_coordmesh(2)%coordmesh_y
z_pos_observer(2)=Points_observer(i)%global_coordmesh(2)%coordmesh_z
hz_observer(2)=(EX(x_pos_observer(2),y_pos_observer(2)+1,z_pos_observer(2))-EX(x_pos_observer(2),y_pos_observer(2),z_pos_observer(2)))/CDELY(y_pos_observer(2))-&
(EY(x_pos_observer(2)+1,y_pos_observer(2),z_pos_observer(2))-EY(x_pos_observer(2),y_pos_observer(2),z_pos_observer(2)))/CDELX(x_pos_observer(2))
!=================================point3=======================================
x_pos_observer(3)=Points_observer(i)%global_coordmesh(3)%coordmesh_x
y_pos_observer(3)=Points_observer(i)%global_coordmesh(3)%coordmesh_y
z_pos_observer(3)=Points_observer(i)%global_coordmesh(3)%coordmesh_z
hz_observer(3)=(EX(x_pos_observer(3),y_pos_observer(3)+1,z_pos_observer(3))-EX(x_pos_observer(3),y_pos_observer(3),z_pos_observer(3)))/CDELY(y_pos_observer(3))-&
(EY(x_pos_observer(3)+1,y_pos_observer(3),z_pos_observer(3))-EY(x_pos_observer(3),y_pos_observer(3),z_pos_observer(3)))/CDELX(x_pos_observer(3))
!=================================point4=======================================
x_pos_observer(4)=Points_observer(i)%global_coordmesh(4)%coordmesh_x
y_pos_observer(4)=Points_observer(i)%global_coordmesh(4)%coordmesh_y
z_pos_observer(4)=Points_observer(i)%global_coordmesh(4)%coordmesh_z
hz_observer(4)=(EX(x_pos_observer(4),y_pos_observer(4)+1,z_pos_observer(4))-EX(x_pos_observer(4),y_pos_observer(4),z_pos_observer(4)))/CDELY(y_pos_observer(4))-&
(EY(x_pos_observer(4)+1,y_pos_observer(4),z_pos_observer(4))-EY(x_pos_observer(4),y_pos_observer(4),z_pos_observer(4)))/CDELX(x_pos_observer(4))
!=================================point5=======================================
x_pos_observer(5)=Points_observer(i)%global_coordmesh(5)%coordmesh_x
y_pos_observer(5)=Points_observer(i)%global_coordmesh(5)%coordmesh_y
z_pos_observer(5)=Points_observer(i)%global_coordmesh(5)%coordmesh_z
hz_observer(5)=(EX(x_pos_observer(5),y_pos_observer(5)+1,z_pos_observer(5))-EX(x_pos_observer(5),y_pos_observer(5),z_pos_observer(5)))/CDELY(y_pos_observer(5))-&
(EY(x_pos_observer(5)+1,y_pos_observer(5),z_pos_observer(5))-EY(x_pos_observer(5),y_pos_observer(5),z_pos_observer(5)))/CDELX(x_pos_observer(5))
!=================================point6=======================================
x_pos_observer(6)=Points_observer(i)%global_coordmesh(6)%coordmesh_x
y_pos_observer(6)=Points_observer(i)%global_coordmesh(6)%coordmesh_y
z_pos_observer(6)=Points_observer(i)%global_coordmesh(6)%coordmesh_z
hz_observer(6)=(EX(x_pos_observer(6),y_pos_observer(6)+1,z_pos_observer(6))-EX(x_pos_observer(6),y_pos_observer(6),z_pos_observer(6)))/CDELY(y_pos_observer(6))-&
(EY(x_pos_observer(6)+1,y_pos_observer(6),z_pos_observer(6))-EY(x_pos_observer(6),y_pos_observer(6),z_pos_observer(6)))/CDELX(x_pos_observer(6))
!=================================point7=======================================
x_pos_observer(7)=Points_observer(i)%global_coordmesh(7)%coordmesh_x
y_pos_observer(7)=Points_observer(i)%global_coordmesh(7)%coordmesh_y
z_pos_observer(7)=Points_observer(i)%global_coordmesh(7)%coordmesh_z
hz_observer(7)=(EX(x_pos_observer(7),y_pos_observer(7)+1,z_pos_observer(7))-EX(x_pos_observer(7),y_pos_observer(7),z_pos_observer(7)))/CDELY(y_pos_observer(7))-&
(EY(x_pos_observer(7)+1,y_pos_observer(7),z_pos_observer(7))-EY(x_pos_observer(7),y_pos_observer(7),z_pos_observer(7)))/CDELX(x_pos_observer(7))
!=================================point8=======================================
x_pos_observer(8)=Points_observer(i)%global_coordmesh(8)%coordmesh_x
y_pos_observer(8)=Points_observer(i)%global_coordmesh(8)%coordmesh_y
z_pos_observer(8)=Points_observer(i)%global_coordmesh(8)%coordmesh_z
hz_observer(8)=(EX(x_pos_observer(8),y_pos_observer(8)+1,z_pos_observer(8))-EX(x_pos_observer(8),y_pos_observer(8),z_pos_observer(8)))/CDELY(y_pos_observer(8))-&
(EY(x_pos_observer(8)+1,y_pos_observer(8),z_pos_observer(8))-EY(x_pos_observer(8),y_pos_observer(8),z_pos_observer(8)))/CDELX(x_pos_observer(8))
data_rec(i) = hz_observer(1) * Points_observer(i)%coeff(1) + hz_observer(2) * Points_observer(i)%coeff(2) +&
hz_observer(3) * Points_observer(i)%coeff(3) + hz_observer(4) * Points_observer(i)%coeff(4) +&
hz_observer(5) * Points_observer(i)%coeff(5) + hz_observer(6) * Points_observer(i)%coeff(6) +&
hz_observer(7) * Points_observer(i)%coeff(7) + hz_observer(8) * Points_observer(i)%coeff(8)
ENDDO
enddo
deallocate(meps_r,mcq,msource,mdelt)
print*,mstop(num),'steps have just finished'
IF(Ctime(mstart(num)+mstop(num)-1)>(RAISETIME+WAVE+RAMP))THEN
DO i=1,point_num
idx_write=idx_start+i
WRITE(idx_write,*)mstart(num)+mstop(num)-1,Ctime(mstart(num)+mstop(num)-1)-(RAISETIME+WAVE+RAMP),data_rec(i)
ENDDO
write(*,'(a,i8,a,i8,a,f6.2,a)') 'Progress: [', num, '/', num_fra_com, '] (',100.0*num/num_fra_com, '%)'
ENDIF
ENDDO
call cpu_time(t_end)
t_total=t_end-t_start
print*,'The computing time is:', t_total
end subroutine Iteration_cpml
!===============================================================================================!
! ITERATION (below): original Dirichlet boundary iteration (Logic_PML=0).
! ITERATION_CPML (above): CPML absorbing boundary iteration (Logic_PML=1).
! main.f90 dispatches to either one according to Logic_PML read from input.dat.
!===============================================================================================!
! --------------------------------Subroutine part---------------------------------------------!
subroutine Iteration
use constantparameters
USE CONSTANTPARAMETERS
USE ELECTROMAGNETIC_VARIABLES
USE RES_MODEL_PARAMETER
USE TIME_PARAMETER
USE PML_PARAMETER
implicit none
real::t1,t2,t,t_start,t_end,t_total !t1 denotes original cpu time at the beginning of each computation fraction, t2 denotes the end cpu time and t=t2-t1
REAL*8 CA,CB,DELX1,DELY1,DELZ1 !ca, cb, delx1, dely1, delz1 are all middle variables used in the computation of EM field
REAL*8 TEMP_SIG,temp_cacb,data_rec(point_num) !Temp_sig and temp_cacb are middle variables used in the computation of EM field
REAL*8 DELY2,DELZ2,delx2 !They are all middle variables as above ones.
integer num,i,j,k,ii,iii,jj,kk,idx_write,x_pos_observer(8),y_pos_observer(8),z_pos_observer(8) !num is the number of computation fraction
integer :: N_hight=0
real*8,allocatable::Meps_r(:),Mdelt(:),Msource(:),Mcq(:) !They are local substitution of eps_r, delt and cq
REAL*8 hz_observer(8)
CHARACTER*20::string,str_num
WRITE(*,*)'[Iteration] Boundary condition: Dirichlet (zero-field) boundary (field fixed to zero at the outer grid faces)'
WRITE(*,*)'[Iteration] Iteration starts .. .. .. ..'
!Create output files
idx_start=12000
do iii=1,point_num
idx_write=idx_start+iii
IF(iii<10) THEN
write(str_num,"(I1)")iii
ELSEif(iii<100) THEN
write(str_num,"(I2)")iii
ELSEif(iii<1000) THEN
write(str_num,"(I3)")iii
ENDIF
string='dBzdt'//"_"//trim(str_num)//'.txt'
open(idx_write,file=string)
write(idx_write,*)"point_"//trim(str_num)
write(idx_write,*)Points_observer(iii)%local_coord_to_source%coord_x,Points_observer(iii)%local_coord_to_source%coord_y,&
Points_observer(iii)%local_coord_to_source%coord_z
enddo
call cpu_time(t_start)
!OPEN(20250220,file='dBzdt.txt')
do num=1,num_fra_com,1 !The outer loop which begins from the first fraction ends at the last fraction
call cpu_time(t1) !Record the cpu time at the beginning of each computing fraction
allocate(mdelt(0:mstop(num)),meps_r(mstop(num)),mcq(mstop(num)),msource(mstop(num)))
! The memory of mdelt, meps_r, mcq and msource are allocated at the begining of fraction
do ii=mstart(num),mstart(num)+mstop(num)-1,1
mdelt(ii-mstart(num)+1)=delt(ii)
meps_r(ii-mstart(num)+1)=eps_r(ii)
mcq(ii-mstart(num)+1)=cq(ii)
msource(ii-mstart(num)+1)=source(ii) !Link the local value of mdelt, meps_r, mcq and msorce to the global value of delt, eps_r, cq and source array.
end do
print*,'Now computing fraction:',num
mdelt(0)=mdelt(1)
do loop=1,mstop(num),1
! --------------------------------update the value of Ex and Ey in source area---------------------------------------!
DO J=2,NYB-1
DO I=1,NX
K=NZS+1-N_hight
DELY1=(CDELY(J-1)+CDELY(J))/2.0D0
DELZ1=CDELZ(NZ/2+1)
CA=(2.0D0*Meps_r(loop)-Mdelt(LOOP-1)*CCSIGX(I,J,K))/(2.0*Meps_r(loop)+Mdelt(LOOP-1)*CCSIGX(I,J,K))
CB=(2.0D0*MDELT(LOOP-1))/(2.0*Meps_r(loop)+MDELT(LOOP-1)*CCSIGX(I,J,K))
EX(I,J,K)=CA*EX(I,J,K)+CB*((HZ(I,J,K)-HZ(I,J-1,K))*den_ey(J)/DELY1&
&-(HY(I,J,K)-HY(I,J,K-1))*den_ez(K)/DELZ1)-cb*Msource(loop)*is_ex_in_source(i,j)
ENDDO
ENDDO
! end of updating Ex while k=Nzs+1
! update the value of Ey while k=Nzs+1
DO J=1,NY
DO I=2,NX
K=NZS+1-N_hight
DELX1=(CDELX(I-1)+CDELX(I))/2.0
DELZ1=CDELZ(NZ/2+1)
CA=(2.0D0*Meps_r(loop)-MDELT(LOOP-1)*CCSIGY(I,J,K))/(2.0D0*Meps_r(loop)+MDELT(LOOP-1)*CCSIGY(I,J,K))
CB=(2.0D0*MDELT(LOOP-1))/(2.0D0*Meps_r(loop)+MDELT(LOOP-1)*CCSIGY(I,J,K))
EY(I,J,K)=CA*EY(I,J,K)+CB*((HX(I,J,K)-HX(I,J,K-1))*den_ez(K)/DELZ1&
&-(HZ(I,J,K)-HZ(I-1,J,K))*den_ex(I)/DELX1)-cb*Msource(loop)*is_ey_in_source(i,j)
ENDDO
ENDDO
! end of uptating Ey while k=Nzs+1
! ---------------------------------------------------Ex Part-------------------------------------------------------------!
DO K=NZS+2-N_hight,NZ
DO J=2,NY
DO I=1,NX
DELY1=(CDELY(J-1)+CDELY(J))/2.0D0
DELZ1=(CDELZ(K-1)+CDELZ(K))/2.0D0
CA=(2.0D0*Meps_r(loop)-MDELT(LOOP-1)*CCSIGX(I,J,K))/(2.0D0*Meps_r(loop)+MDELT(LOOP-1)*CCSIGX(I,J,K))
CB=(2.0D0*MDELT(LOOP-1))/(2.0D0*Meps_r(loop)+MDELT(LOOP-1)*CCSIGX(I,J,K))
EX(I,J,K)=CA*EX(I,J,K)+CB*((HZ(I,J,K)-HZ(I,J-1,K))*den_ey(J)/DELY1&
&-(HY(I,J,K)-HY(I,J,K-1))*den_ez(K)/DELZ1)
ENDDO
ENDDO
ENDDO
DO K=2,NZS-N_hight
DO J=2,NY
DO I=1,NX
DELY1=(CDELY(J-1)+CDELY(J))/2.0D0
DELZ1=(CDELZ(K-1)+CDELZ(K))/2.0D0
CA=(2.0D0*Meps_r(loop)-MDELT(LOOP-1)*CCSIGX(I,J,K))/(2.0D0*Meps_r(loop)+MDELT(LOOP-1)*CCSIGX(I,J,K))
CB=(2.0D0*MDELT(LOOP-1))/(2.0D0*Meps_r(loop)+MDELT(LOOP-1)*CCSIGX(I,J,K))
EX(I,J,K)=CA*EX(I,J,K)+CB*((HZ(I,J,K)-HZ(I,J-1,K))*den_ey(J)/DELY1&
&-(HY(I,J,K)-HY(I,J,K-1))*den_ez(K)/DELZ1)
ENDDO
ENDDO
ENDDO
! ================end of updating Ex==================!
! -----------------------------------------update the value of Ey--------------------------------!
DO K=NZS+2-N_hight,NZ
DO J=1,NY
DO I=2,NX
DELX1=(CDELX(I-1)+CDELX(I))/2.0D0
DELZ1=(CDELZ(K-1)+CDELZ(K))/2.0D0
CA=(2.0D0*Meps_r(loop)-MDELT(LOOP-1)*CCSIGY(I,J,K))/(2.0D0*Meps_r(loop)+MDELT(LOOP-1)*CCSIGY(I,J,K))
CB=(2.0D0*MDELT(LOOP-1))/(2.0D0*Meps_r(loop)+MDELT(LOOP-1)*CCSIGY(I,J,K))
EY(I,J,K)=CA*EY(I,J,K)+CB*((HX(I,J,K)-HX(I,J,K-1))*den_ez(K)/DELZ1&
&-(HZ(I,J,K)-HZ(I-1,J,K))*den_ex(I)/DELX1)
ENDDO
ENDDO
ENDDO
DO K=2,NZS-N_hight
DO J=1,NY
DO I=2,NXB-1
DELX1=(CDELX(I-1)+CDELX(I))/2.0D0
DELZ1=(CDELZ(K-1)+CDELZ(K))/2.0D0
CA=(2.0D0*Meps_r(loop)-MDELT(LOOP-1)*CCSIGY(I,J,K))/(2.0D0*Meps_r(loop)+MDELT(LOOP-1)*CCSIGY(I,J,K))
CB=(2.0D0*MDELT(LOOP-1))/(2.0D0*Meps_r(loop)+MDELT(LOOP-1)*CCSIGY(I,J,K))
EY(I,J,K)=CA*EY(I,J,K)+CB*((HX(I,J,K)-HX(I,J,K-1))*den_ez(K)/DELZ1&
&-(HZ(I,J,K)-HZ(I-1,J,K))*den_ex(I)/DELX1)
ENDDO
ENDDO
ENDDO
!===============end of updating Ey===================!
! -------------------------------------update the value of Ez--------------------------------------!
DO K=1,NZ
DO J=2,NYB-1
DO I=2,NXB-1
DELX1=(CDELX(I-1)+CDELX(I))/2.0D0
DELY1=(CDELY(J-1)+CDELY(J))/2.0D0
TEMP_CACB=2.0D0*Meps_r(loop)+MDELT(LOOP-1)*CCSIGZ(I,J,K)
CA=(2.0D0*Meps_r(loop)-MDELT(LOOP-1)*CCSIGZ(I,J,K))/TEMP_CACB
CB=(2.0D0*MDELT(LOOP-1))/TEMP_CACB
EZ(I,J,K)=CA*EZ(I,J,K)+CB*((HY(I,J,K)-HY(I-1,J,K))*den_ex(I)/DELX1&
&-(HX(I,J,K)-HX(I,J-1,K))*den_ey(J)/DELY1)
ENDDO ENDDO
ENDDO ENDDO
ENDDO ENDDO
!$acc end parallel
!$acc wait
!===============end of updating Ez=========================! !===============end of updating Ez=========================!
! ------------------------------------update the value of Hx-----------------------------------------------! ! ------------------------------------update the value of Hx-----------------------------------------------!
!$acc parallel async(8)
!$acc loop gang
DO K=1,NZ DO K=1,NZ
!$acc loop worker
DO J=1,NY DO J=1,NY
!$acc loop vector
DO I=1,NXB DO I=1,NXB
DELY2=CDELY(J) DELY2=CDELY(J)
DELZ2=CDELZ(K) DELZ2=CDELZ(K)
HX(I,J,K)=HX(I,J,K)-MCQ(LOOP)*((EZ(I,J+1,K)-EZ(I,J,K))/DELY2-(EY(I,J,K+1)-EY(I,J,K))/DELZ2) HX(I,J,K)=HX(I,J,K)-MCQ(LOOP)*((EZ(I,J+1,K)-EZ(I,J,K))*den_hy(J)/DELY2&
&-(EY(I,J,K+1)-EY(I,J,K))*den_hz(K)/DELZ2)
ENDDO ENDDO
ENDDO ENDDO
ENDDO ENDDO
!$acc end parallel
!================end of updating Hx=======================! !================end of updating Hx=======================!
! -------------------------------------update the value of Hy---------------------------------------------! ! -------------------------------------update the value of Hy---------------------------------------------!
!$acc parallel async(9)
!$acc loop gang
DO K=1,NZ DO K=1,NZ
!$acc loop worker
DO J=1,NYB DO J=1,NYB
!$acc loop vector
DO I=1,NX DO I=1,NX
DELZ2=CDELZ(K) DELZ2=CDELZ(K)
DELX2=CDELX(I) DELX2=CDELX(I)
HY(I,J,K)=HY(I,J,K)-MCQ(LOOP)*((EX(I,J,K+1)-EX(I,J,K))/DELZ2-(EZ(I+1,J,K)-EZ(I,J,K))/DELX2) HY(I,J,K)=HY(I,J,K)-MCQ(LOOP)*((EX(I,J,K+1)-EX(I,J,K))*den_hz(K)/DELZ2&
&-(EZ(I+1,J,K)-EZ(I,J,K))*den_hx(I)/DELX2)
ENDDO ENDDO
ENDDO ENDDO
ENDDO ENDDO
!$acc end parallel
!$acc wait
!===============end of updating Hy========================! !===============end of updating Hy========================!
!-------------------------------------update the value of Hz----------------------------------------------! !-------------------------------------update the value of Hz----------------------------------------------!
!$acc kernels async(10)
DO J=1,NY DO J=1,NY
DO I=1,NX DO I=1,NX
DO K=NZ,NZ/2+1,-1 !NZ,2,-1 ! DO K=NZ,NZS+1,-1
DELX2=CDELX(I) DELX2=CDELX(I)
DELY2=CDELY(J) DELY2=CDELY(J)
DELZ2=CDELZ(K) DELZ2=CDELZ(K)
HZ(I,J,K)=HZ(I,J,K+1)+DELZ2*((HX(I+1,J,K)-HX(I,J,K))/DELX2+(HY(I,J+1,K)-HY(I,J,K))/DELY2) HZ(I,J,K)=HZ(I,J,K+1)+DELZ2*((HX(I+1,J,K)-HX(I,J,K))*den_hx(I)/DELX2&
&+(HY(I,J+1,K)-HY(I,J,K))*den_hy(J)/DELY2)*inv_hz_den(K)
ENDDO ENDDO
ENDDO ENDDO
ENDDO ENDDO
!$acc end kernels DO K=1,NZS-1
!$acc kernels async(11)
DO K=1,NZ/2-1
DO J=1,NY DO J=1,NY
DO I=1,NX DO I=1,NX
DELX2=CDELX(I) DELX2=CDELX(I)
DELY2=CDELY(J) DELY2=CDELY(J)
DELZ2=CDELZ(K) DELZ2=CDELZ(K)
HZ(I,J,K+1)=HZ(I,J,K)-DELZ2*((HX(I+1,J,K)-HX(I,J,K))/DELX2+(HY(I,J+1,K)-HY(I,J,K))/DELY2) HZ(I,J,K+1)=HZ(I,J,K)-DELZ2*((HX(I+1,J,K)-HX(I,J,K))*den_hx(I)/DELX2&
&+(HY(I,J+1,K)-HY(I,J,K))*den_hy(J)/DELY2)*inv_hz_den(K)
ENDDO ENDDO
ENDDO ENDDO
ENDDO ENDDO
!$acc end kernels
!$acc wait
!===================end of updating Hz==========================! !===================end of updating Hz==========================!
enddo DO i=1,point_num
!$acc end data !=================================point1=======================================
call cpu_time(t2) x_pos_observer(1)=Points_observer(i)%global_coordmesh(1)%coordmesh_x
t=t2-t1 y_pos_observer(1)=Points_observer(i)%global_coordmesh(1)%coordmesh_y
print*,'The computing time for this fraction is:', t z_pos_observer(1)=Points_observer(i)%global_coordmesh(1)%coordmesh_z
deallocate(meps_r,mcq,msource,mdelt) hz_observer(1)=(EX(x_pos_observer(1),y_pos_observer(1)+1,z_pos_observer(1))-EX(x_pos_observer(1),y_pos_observer(1),z_pos_observer(1)))/CDELY(y_pos_observer(1))-&
call WriteRecFiles(num) (EY(x_pos_observer(1)+1,y_pos_observer(1),z_pos_observer(1))-EY(x_pos_observer(1),y_pos_observer(1),z_pos_observer(1)))/CDELX(x_pos_observer(1))
write(*,'(1x,e20.10e3,3x,e20.10e3)')Hz(nxs,nys+2,Nzs_air(1)),Hz(Nxs,Nys+2,Nz/2+1) !=================================point2=======================================
write(*,*)'Now loop is:',mstart(num)+mstop(num)-1 x_pos_observer(2)=Points_observer(i)%global_coordmesh(2)%coordmesh_x
print*,mstop(num),'steps have just finished' y_pos_observer(2)=Points_observer(i)%global_coordmesh(2)%coordmesh_y
z_pos_observer(2)=Points_observer(i)%global_coordmesh(2)%coordmesh_z
hz_observer(2)=(EX(x_pos_observer(2),y_pos_observer(2)+1,z_pos_observer(2))-EX(x_pos_observer(2),y_pos_observer(2),z_pos_observer(2)))/CDELY(y_pos_observer(2))-&
(EY(x_pos_observer(2)+1,y_pos_observer(2),z_pos_observer(2))-EY(x_pos_observer(2),y_pos_observer(2),z_pos_observer(2)))/CDELX(x_pos_observer(2))
!=================================point3=======================================
x_pos_observer(3)=Points_observer(i)%global_coordmesh(3)%coordmesh_x
y_pos_observer(3)=Points_observer(i)%global_coordmesh(3)%coordmesh_y
z_pos_observer(3)=Points_observer(i)%global_coordmesh(3)%coordmesh_z
hz_observer(3)=(EX(x_pos_observer(3),y_pos_observer(3)+1,z_pos_observer(3))-EX(x_pos_observer(3),y_pos_observer(3),z_pos_observer(3)))/CDELY(y_pos_observer(3))-&
(EY(x_pos_observer(3)+1,y_pos_observer(3),z_pos_observer(3))-EY(x_pos_observer(3),y_pos_observer(3),z_pos_observer(3)))/CDELX(x_pos_observer(3))
!=================================point4=======================================
x_pos_observer(4)=Points_observer(i)%global_coordmesh(4)%coordmesh_x
y_pos_observer(4)=Points_observer(i)%global_coordmesh(4)%coordmesh_y
z_pos_observer(4)=Points_observer(i)%global_coordmesh(4)%coordmesh_z
hz_observer(4)=(EX(x_pos_observer(4),y_pos_observer(4)+1,z_pos_observer(4))-EX(x_pos_observer(4),y_pos_observer(4),z_pos_observer(4)))/CDELY(y_pos_observer(4))-&
(EY(x_pos_observer(4)+1,y_pos_observer(4),z_pos_observer(4))-EY(x_pos_observer(4),y_pos_observer(4),z_pos_observer(4)))/CDELX(x_pos_observer(4))
!=================================point5=======================================
x_pos_observer(5)=Points_observer(i)%global_coordmesh(5)%coordmesh_x
y_pos_observer(5)=Points_observer(i)%global_coordmesh(5)%coordmesh_y
z_pos_observer(5)=Points_observer(i)%global_coordmesh(5)%coordmesh_z
hz_observer(5)=(EX(x_pos_observer(5),y_pos_observer(5)+1,z_pos_observer(5))-EX(x_pos_observer(5),y_pos_observer(5),z_pos_observer(5)))/CDELY(y_pos_observer(5))-&
(EY(x_pos_observer(5)+1,y_pos_observer(5),z_pos_observer(5))-EY(x_pos_observer(5),y_pos_observer(5),z_pos_observer(5)))/CDELX(x_pos_observer(5))
!=================================point6=======================================
x_pos_observer(6)=Points_observer(i)%global_coordmesh(6)%coordmesh_x
y_pos_observer(6)=Points_observer(i)%global_coordmesh(6)%coordmesh_y
z_pos_observer(6)=Points_observer(i)%global_coordmesh(6)%coordmesh_z
hz_observer(6)=(EX(x_pos_observer(6),y_pos_observer(6)+1,z_pos_observer(6))-EX(x_pos_observer(6),y_pos_observer(6),z_pos_observer(6)))/CDELY(y_pos_observer(6))-&
(EY(x_pos_observer(6)+1,y_pos_observer(6),z_pos_observer(6))-EY(x_pos_observer(6),y_pos_observer(6),z_pos_observer(6)))/CDELX(x_pos_observer(6))
!=================================point7=======================================
x_pos_observer(7)=Points_observer(i)%global_coordmesh(7)%coordmesh_x
y_pos_observer(7)=Points_observer(i)%global_coordmesh(7)%coordmesh_y
z_pos_observer(7)=Points_observer(i)%global_coordmesh(7)%coordmesh_z
hz_observer(7)=(EX(x_pos_observer(7),y_pos_observer(7)+1,z_pos_observer(7))-EX(x_pos_observer(7),y_pos_observer(7),z_pos_observer(7)))/CDELY(y_pos_observer(7))-&
(EY(x_pos_observer(7)+1,y_pos_observer(7),z_pos_observer(7))-EY(x_pos_observer(7),y_pos_observer(7),z_pos_observer(7)))/CDELX(x_pos_observer(7))
!=================================point8=======================================
x_pos_observer(8)=Points_observer(i)%global_coordmesh(8)%coordmesh_x
y_pos_observer(8)=Points_observer(i)%global_coordmesh(8)%coordmesh_y
z_pos_observer(8)=Points_observer(i)%global_coordmesh(8)%coordmesh_z
hz_observer(8)=(EX(x_pos_observer(8),y_pos_observer(8)+1,z_pos_observer(8))-EX(x_pos_observer(8),y_pos_observer(8),z_pos_observer(8)))/CDELY(y_pos_observer(8))-&
(EY(x_pos_observer(8)+1,y_pos_observer(8),z_pos_observer(8))-EY(x_pos_observer(8),y_pos_observer(8),z_pos_observer(8)))/CDELX(x_pos_observer(8))
data_rec(i) = hz_observer(1) * Points_observer(i)%coeff(1) + hz_observer(2) * Points_observer(i)%coeff(2) +&
hz_observer(3) * Points_observer(i)%coeff(3) + hz_observer(4) * Points_observer(i)%coeff(4) +&
hz_observer(5) * Points_observer(i)%coeff(5) + hz_observer(6) * Points_observer(i)%coeff(6) +&
hz_observer(7) * Points_observer(i)%coeff(7) + hz_observer(8) * Points_observer(i)%coeff(8)
ENDDO ENDDO
enddo
deallocate(meps_r,mcq,msource,mdelt)
print*,mstop(num),'steps have just finished'
IF(Ctime(mstart(num)+mstop(num)-1)>(RAISETIME+WAVE+RAMP))THEN
DO i=1,point_num
idx_write=idx_start+i
WRITE(idx_write,*)mstart(num)+mstop(num)-1,Ctime(mstart(num)+mstop(num)-1)-(RAISETIME+WAVE+RAMP),data_rec(i)
ENDDO
write(*,'(a,i8,a,i8,a,f6.2,a)') 'Progress: [', num, '/', num_fra_com, '] (',100.0*num/num_fra_com, '%)'
ENDIF
ENDDO
call cpu_time(t_end)
t_total=t_end-t_start
print*,'The computing time is:', t_total
end subroutine Iteration end subroutine Iteration
+3 -3
查看文件
@@ -1,6 +1,6 @@
!Copyright (c) 2013 by tdem.org under guide of Xiu Li(lixiu@chd.edu.cn) !Copyright (c) 2013 by https://git.em3d.cn/ under guide of Xiu Li(lixiu@chd.edu.cn)
!written by Huaifeng Sun(sunhuaifeng@gmail.com) and Xushan Lu(luxushan@gmail.com) !written by Huaifeng Sun(sunhuaifeng@email.sdu.edu.cn) and Xushan Lu(luxushan@gmail.com)
!Code distribution @ tdem.org or sunhuaifeng.com !Code distribution @ https://git.em3d.cn/
subroutine OpenRecFiles subroutine OpenRecFiles
! This subroutine opens all the files needed to record data of interests ! This subroutine opens all the files needed to record data of interests
+3 -3
查看文件
@@ -1,6 +1,6 @@
!Copyright (c) 2013 by tdem.org under guide of Xiu Li(lixiu@chd.edu.cn) !Copyright (c) 2013 by https://git.em3d.cn/ under guide of Xiu Li(lixiu@chd.edu.cn)
!written by Huaifeng Sun(sunhuaifeng@gmail.com) and Xushan Lu(luxushan@gmail.com) !written by Huaifeng Sun(sunhuaifeng@email.sdu.edu.cn) and Xushan Lu(luxushan@gmail.com)
!Code distribution @ tdem.org or sunhuaifeng.com !Code distribution @ https://git.em3d.cn/
subroutine SubCloseRecFiles(Flag) subroutine SubCloseRecFiles(Flag)
use constantparameters use constantparameters
+4 -4
查看文件
@@ -1,6 +1,6 @@
!Copyright (c) 2013 by tdem.org under guide of Xiu Li(lixiu@chd.edu.cn) !Copyright (c) 2013 by https://git.em3d.cn/ under guide of Xiu Li(lixiu@chd.edu.cn)
!written by Huaifeng Sun(sunhuaifeng@gmail.com) and Xushan Lu(luxushan@gmail.com) !written by Huaifeng Sun(sunhuaifeng@email.sdu.edu.cn) and Xushan Lu(luxushan@gmail.com)
!Code distribution @ tdem.org or sunhuaifeng.com !Code distribution @ https://git.em3d.cn/
subroutine SubOpenRecFiles(Flag) subroutine SubOpenRecFiles(Flag)
use constantparameters use constantparameters
@@ -72,7 +72,7 @@ subroutine SubOpenRecFiles(Flag)
end select end select
! ------------------------------------end of File name Distribution---------------------------------------------! ! ------------------------------------end of File name Distribution---------------------------------------------!
! --------------------------------------open file code-------------------------------------------! ! --------------------------------------open file code-------------------------------------------!
! if the compiler reports the error: 'Too Many Open FIles!', you can come to tdem.org website and find the solutions. ! if the compiler reports the error: 'Too Many Open FIles!', you can come to https://git.em3d.cn/ website and find the solutions.
! -----------------------------------------------------------------------------------------------------! ! -----------------------------------------------------------------------------------------------------!
do ii=1,NumRecHeights+1,1 do ii=1,NumRecHeights+1,1
do jj=1,NumRecLines,1 do jj=1,NumRecLines,1
+3 -3
查看文件
@@ -1,6 +1,6 @@
!Copyright (c) 2013 by tdem.org under guide of Xiu Li(lixiu@chd.edu.cn) !Copyright (c) 2013 by https://git.em3d.cn/ under guide of Xiu Li(lixiu@chd.edu.cn)
!written by Huaifeng Sun(sunhuaifeng@gmail.com) and Xushan Lu(luxushan@gmail.com) !written by Huaifeng Sun(sunhuaifeng@email.sdu.edu.cn) and Xushan Lu(luxushan@gmail.com)
!Code distribution @ tdem.org or sunhuaifeng.com !Code distribution @ https://git.em3d.cn/
subroutine SubWriteRecFiles(Flag,num) subroutine SubWriteRecFiles(Flag,num)
! This subroutine writes all the data of intersted recording points from different recording plane which are given in the input.dat file. ! This subroutine writes all the data of intersted recording points from different recording plane which are given in the input.dat file.
+772
查看文件
@@ -0,0 +1,772 @@
!Copyright (c) 2022 by LEEE under guide of Huaifeng Sun(sunhuaifeng@email.sdu.edu.cn)
!written by Xinyu Li(202335098@mail.sdu.edu.cn) and Qi Zhao(zhaoqi_326326@163.com)
SUBROUTINE terrain_conformal
USE CONSTANTPARAMETERS
USE ELECTROMAGNETIC_VARIABLES
USE RES_MODEL_PARAMETER
USE TIME_PARAMETER
USE OMP_LIB
IMPLICIT NONE
INTEGER :: i,ii,j,jj,k,kk,i0,j1,i1,k2,i2,k3,j3,l1,l2,l3,iii,jjj,kkk
INTEGER :: index, recorder
logical :: JudgmentValue,LOGICAL_1,LOGICAL_2,LOGICAL_3,LOGICAL_4,LOGICAL_5,LOGICAL_6
CHARACTER*255 :: temp, FineNameOfTerrain
REAL(KIND=8), DIMENSION(:), ALLOCATABLE :: Normal_temp
CHARACTER(300) :: line !used to read one line of the ASCII STL file
INTEGER(KIND=4) :: ios_stl,i_face,iv_face,nv_tmp,idx_v,ip_stl
INTEGER(KIND=4), DIMENSION(:,:), ALLOCATABLE :: tmp_face
REAL(KIND=8), DIMENSION(:,:), ALLOCATABLE :: tmp_vert,tmp_norm
REAL(KIND=8) :: vx,vy,vz
REAL(KIND=8) :: ex1x,ex1y,ex1z,ex2x,ex2y,ex2z,crossx,crossy,crossz
!>The terrain mesh file can be Complex_Terrain.dat (the original text format) or
!!Complex_Terrain.stl (the ASCII STL format). Which one is used was decided in
!!GETDATA, and here only the corresponding reading branch is entered. The variables
!!filled below (Node_Label, CoordinatesX/Y/Z, Element_Label, Element_Node1/2/3,
!!n_point, n_face) keep the same names in both formats.
IF(Logic_TerrainDat)THEN
!>Original .dat format:
!! Line 1 : "Number of Nodes and Elements:"
!! Line 2 : n_point (number of nodes)
!! Line 3 : n_face (number of triangular elements)
!! Line 4 : "Nodes Coordinates:"
!! next n_point lines : label, Coord_X, Coord_Y, Coord_Z
!! then 2 title lines, then n_face lines : label, node1, node2, node3
FineNameOfTerrain = "Complex_Terrain.dat"
OPEN( 520, FILE = FinenameOfTerrain )
Read(520, *) temp
Read(520, *) n_point !get total number of Node
Read(520, *) n_face !get total number of Element
Read(520,*) temp
ALLOCATE( Normal(n_face,3) )
ALLOCATE( Normal_temp(n_face) )
ALLOCATE( Node_Label(n_point), CoordinatesX(n_point), CoordinatesY(n_point), CoordinatesZ(n_point) )
ALLOCATE( Element_Label(n_face), Element_Node1(n_face),Element_Node2(n_face), Element_Node3(n_face) )
ALLOCATE( vert0(3,n_face), vert1(3,n_face), vert2(3,n_face), edge1(3,n_face), edge2(3,n_face))
ALLOCATE( Face_Triangle_NormVect(3,n_face))
DO i =1, n_point
Read(520,*) Node_Label(i), CoordinatesX(i), CoordinatesY(i), CoordinatesZ(i) ! get the label of Node; get the coordinates of X, Y, Z connecting the Node
ENDDO
Read(520,*) temp
Read(520,*) temp
DO i =1, n_face
Read(520,*) Element_Label(i), Element_Node1(i),Element_Node2(i), Element_Node3(i) ! get the label of Element; get the Label of Node connecting the Node
vert0(1,i)=CoordinatesX( Element_Node1(i) )
vert0(2,i)=CoordinatesY( Element_Node1(i) )
vert0(3,i)=CoordinatesZ( Element_Node1(i) )
vert1(1,i)=CoordinatesX( Element_Node2(i) )
vert1(2,i)=CoordinatesY( Element_Node2(i) )
vert1(3,i)=CoordinatesZ( Element_Node2(i) )
vert2(1,i)=CoordinatesX( Element_Node3(i) )
vert2(2,i)=CoordinatesY( Element_Node3(i) )
vert2(3,i)=CoordinatesZ( Element_Node3(i) )
ENDDO
CLOSE(520)
ELSEIF(Logic_TerrainStl)THEN
!>ASCII STL format:
!! solid <name>
!! facet normal nx ny nz
!! outer loop
!! vertex x y z
!! vertex x y z
!! vertex x y z
!! endloop
!! endfacet
!! ...
!! endsolid <name>
!!In an STL file the vertices are written once per facet, so the duplicated
!!vertices are merged into unique nodes before filling the global arrays.
!!The vertex order of each facet is also checked against the facet normal so
!!that the normal direction convention is the same as the .dat format.
OPEN(520,FILE='Complex_Terrain.stl',STATUS='OLD')
!>First pass: count the number of facets.
n_face=0
DO
READ(520,'(A)',IOSTAT=ios_stl) line
IF(ios_stl/=0) EXIT
!>convert the line into lower case for keyword matching
DO ii=1,LEN_TRIM(line)
IF(line(ii:ii)>='A'.AND.line(ii:ii)<='Z') line(ii:ii)=ACHAR(IACHAR(line(ii:ii))+32)
ENDDO
IF(INDEX(line,'facet')>0 .AND. INDEX(line,'endfacet')==0) n_face=n_face+1
ENDDO
IF(n_face==0)THEN
WRITE(*,*)'Error: no facet is found in Complex_Terrain.stl!'
STOP
ENDIF
REWIND(520)
ALLOCATE(tmp_face(3,n_face),tmp_norm(3,n_face),tmp_vert(3,3*n_face))
nv_tmp=0
i_face=0
iv_face=0
DO
READ(520,'(A)',IOSTAT=ios_stl) line
IF(ios_stl/=0) EXIT
DO ii=1,LEN_TRIM(line)
IF(line(ii:ii)>='A'.AND.line(ii:ii)<='Z') line(ii:ii)=ACHAR(IACHAR(line(ii:ii))+32)
ENDDO
IF(INDEX(line,'facet')>0 .AND. INDEX(line,'endfacet')==0)THEN
!>a new facet begins
i_face=i_face+1
iv_face=0
IF(INDEX(line,'normal')>0)THEN
READ(line(INDEX(line,'normal')+6:),*,IOSTAT=ios_stl) tmp_norm(1,i_face),tmp_norm(2,i_face),tmp_norm(3,i_face)
IF(ios_stl/=0)THEN
WRITE(*,*)'Error: failed to read the facet normal line in Complex_Terrain.stl!'
STOP
ENDIF
ENDIF
ELSEIF(INDEX(line,'endfacet')>0)THEN
!>a facet is finished, check that it has exactly 3 vertices
IF(iv_face/=3)THEN
WRITE(*,*)'Error: a facet with',iv_face,'vertices (instead of 3) is found in Complex_Terrain.stl!'
STOP
ENDIF
ELSEIF(INDEX(line,'vertex')>0)THEN
iv_face=iv_face+1
IF(iv_face>3)THEN
WRITE(*,*)'Error: a facet with more than 3 vertices is found in Complex_Terrain.stl!'
STOP
ENDIF
READ(line(INDEX(line,'vertex')+6:),*,IOSTAT=ios_stl) vx,vy,vz
IF(ios_stl/=0)THEN
WRITE(*,*)'Error: failed to read a vertex line in Complex_Terrain.stl!'
STOP
ENDIF
!>merge the duplicated vertices
idx_v=0
DO ip_stl=1,nv_tmp
IF(ABS(tmp_vert(1,ip_stl)-vx)<eps105.AND.ABS(tmp_vert(2,ip_stl)-vy)<eps105.AND.ABS(tmp_vert(3,ip_stl)-vz)<eps105)THEN
idx_v=ip_stl
EXIT
ENDIF
ENDDO
IF(idx_v==0)THEN
nv_tmp=nv_tmp+1
tmp_vert(1,nv_tmp)=vx
tmp_vert(2,nv_tmp)=vy
tmp_vert(3,nv_tmp)=vz
idx_v=nv_tmp
ENDIF
tmp_face(iv_face,i_face)=idx_v
ENDIF
ENDDO
!>Correct the vertex order of each facet: compare the cross-product normal
!!with the facet normal stored in the STL file, swap node2/node3 if they
!!point in opposite directions, so that the normal direction convention
!!is the same as in the .dat format.
DO i=1,n_face
ex1x=tmp_vert(1,tmp_face(2,i))-tmp_vert(1,tmp_face(1,i))
ex1y=tmp_vert(2,tmp_face(2,i))-tmp_vert(2,tmp_face(1,i))
ex1z=tmp_vert(3,tmp_face(2,i))-tmp_vert(3,tmp_face(1,i))
ex2x=tmp_vert(1,tmp_face(3,i))-tmp_vert(1,tmp_face(1,i))
ex2y=tmp_vert(2,tmp_face(3,i))-tmp_vert(2,tmp_face(1,i))
ex2z=tmp_vert(3,tmp_face(3,i))-tmp_vert(3,tmp_face(1,i))
crossx=ex1y*ex2z-ex1z*ex2y
crossy=ex1z*ex2x-ex1x*ex2z
crossz=ex1x*ex2y-ex1y*ex2x
IF(crossx*tmp_norm(1,i)+crossy*tmp_norm(2,i)+crossz*tmp_norm(3,i)<0.0D0)THEN
idx_v=tmp_face(2,i)
tmp_face(2,i)=tmp_face(3,i)
tmp_face(3,i)=idx_v
ENDIF
ENDDO
n_point=nv_tmp
ALLOCATE( Normal(n_face,3) )
ALLOCATE( Normal_temp(n_face) )
ALLOCATE( Node_Label(n_point), CoordinatesX(n_point), CoordinatesY(n_point), CoordinatesZ(n_point) )
ALLOCATE( Element_Label(n_face), Element_Node1(n_face),Element_Node2(n_face), Element_Node3(n_face) )
ALLOCATE( vert0(3,n_face), vert1(3,n_face), vert2(3,n_face), edge1(3,n_face), edge2(3,n_face))
ALLOCATE( Face_Triangle_NormVect(3,n_face))
DO j=1,n_point
Node_Label(j)=j
CoordinatesX(j)=tmp_vert(1,j)
CoordinatesY(j)=tmp_vert(2,j)
CoordinatesZ(j)=tmp_vert(3,j)
ENDDO
DO i=1,n_face
Element_Label(i)=i
Element_Node1(i)=tmp_face(1,i)
Element_Node2(i)=tmp_face(2,i)
Element_Node3(i)=tmp_face(3,i)
vert0(1,i)=CoordinatesX( Element_Node1(i) )
vert0(2,i)=CoordinatesY( Element_Node1(i) )
vert0(3,i)=CoordinatesZ( Element_Node1(i) )
vert1(1,i)=CoordinatesX( Element_Node2(i) )
vert1(2,i)=CoordinatesY( Element_Node2(i) )
vert1(3,i)=CoordinatesZ( Element_Node2(i) )
vert2(1,i)=CoordinatesX( Element_Node3(i) )
vert2(2,i)=CoordinatesY( Element_Node3(i) )
vert2(3,i)=CoordinatesZ( Element_Node3(i) )
ENDDO
CLOSE(520)
DEALLOCATE(tmp_face,tmp_norm,tmp_vert)
WRITE(*,*)'Complex_Terrain.stl read: n_point=',n_point,' n_face=',n_face
ELSE
WRITE(*,*)'Error: neither Complex_Terrain.dat nor Complex_Terrain.stl exists, terrain_conformal can not run!'
RETURN
ENDIF
!============================================================================================================================================================
!Find out the maximum and minimum values of the abnormal volume triangular mesh in z-axis.
max_coord_z=maxval(CoordinatesZ)
min_coord_z=minval(CoordinatesZ)
DO kk=1,NZ
IF(coordinates_z(kk)>min_coord_z)THEN
Z_min=kk-1
EXIT
ENDIF
ENDDO
DO kk=1,NZ
IF(coordinates_z(kk)>max_coord_z)THEN
Z_max=kk
EXIT
ENDIF
ENDDO
ALLOCATE(orig_z(3,NXB*NYB),orig_y(3,NXB*NZB),orig_x(3,NXB*NZB))
ALLOCATE(det_z(NXB*NYB),det_x(NYB*NZB),det_y(NXB*NZB))
ALLOCATE(u_z(NXB*NYB),u_x(NYB*NZB),u_y(NXB*NZB))
ALLOCATE(v_z(NXB*NYB),v_x(NYB*NZB),v_y(NXB*NZB))
ALLOCATE(t_z(NXB*NYB),t_x(NYB*NZB),t_y(NXB*NZB))
ALLOCATE(pvec_z(3,NXB*NYB),pvec_y(3,NXB*NZB),pvec_x(3,NYB*NZB))
ALLOCATE(tvec_z(3,NXB*NYB),tvec_y(3,NXB*NZB),tvec_x(3,NYB*NZB))
ALLOCATE(crosspoint_ZZ(50,NXB*NYB),crosspoint_YY(50,NXB*NZB),crosspoint_XX(50,NYB*NZB))
ALLOCATE(mmz_per(NXB*NYB),mmy_per(NXB*NZB),mmx_per(NYB*NZB))
!Vector of the Triangle
edge1 = vert1 - vert0
edge2 = vert2 - vert0
dir_z = [0.D0,0.D0,1.D0]
dir_y = [0.D0,1.D0,0.D0]
dir_x = [1.D0,0.D0,0.D0]
mmx_per=0
mmy_per=0
mmz_per=0
DO i0=1,n_face
Face_Triangle_NormVect(1,i0)=edge1(2,i0) * edge2(3,i0)-edge1(3,i0) * edge2(2,i0)
Face_Triangle_NormVect(2,i0)=edge1(3,i0) * edge2(1,i0)-edge1(1,i0) * edge2(3,i0)
Face_Triangle_NormVect(3,i0)=edge1(1,i0) * edge2(2,i0)-edge1(2,i0) * edge2(1,i0)
ENDDO
!CALL OMP_SET_NUM_THREADS(16)
!$OMP PARALLEL DO PRIVATE(i0,j1,i1,Rz,verts_Dotmultp,LOGICAL_1,LOGICAL_2,LOGICAL_3,LOGICAL_4,LOGICAL_5,LOGICAL_6)
!get the intersaction of ray and z-face and save it into "coor_z_terrain"
Do j1=1,NYB
Do i1=1,NXB
Rz=(j1-1)*NXB+i1
DO i0=1,n_face
orig_z(1,Rz)=coordinates_x(i1)
orig_z(2,Rz)=coordinates_y(j1)
orig_z(3,Rz)=coordinates_z(1)
tvec_z(1:3,Rz) = orig_z(1:3,Rz) - vert0(1:3,i0)
pvec_z(1,Rz) = dir_z(2)*edge2(3,i0) - dir_z(3)*edge2(2,i0)
pvec_z(2,Rz) = dir_z(3)*edge2(1,i0) - dir_z(1)*edge2(3,i0)
pvec_z(3,Rz) = dir_z(1)*edge2(2,i0) - dir_z(2)*edge2(1,i0)
det_z(Rz)=edge1(1,i0)*pvec_z(1,Rz)+edge1(2,i0)*pvec_z(2,Rz)+edge1(3,i0)*pvec_z(3,Rz)
IF (abs(det_z(Rz)) < eps105) THEN
CYCLE
END IF
u_z(Rz) = (tvec_z(1,Rz)*pvec_z(1,Rz)+tvec_z(2,Rz)*pvec_z(2,Rz)+tvec_z(3,Rz)*pvec_z(3,Rz))/det_z(Rz)
IF (u_z(Rz) < 0.D0 .or. u_z(Rz) > 1.D0) THEN
CYCLE
END IF
pvec_z(1,Rz) = tvec_z(2,Rz)*edge1(3,i0) - tvec_z(3,Rz)*edge1(2,i0)
pvec_z(2,Rz) = tvec_z(3,Rz)*edge1(1,i0) - tvec_z(1,Rz)*edge1(3,i0)
pvec_z(3,Rz) = tvec_z(1,Rz)*edge1(2,i0) - tvec_z(2,Rz)*edge1(1,i0)
v_z(Rz) = (dir_z(1)*pvec_z(1,Rz)+dir_z(2)*pvec_z(2,Rz)+dir_z(3)*pvec_z(3,Rz))/det_z(Rz)
IF (v_z(Rz) < 0.D0 .or. u_z(Rz) + v_z(Rz) > 1.D0) THEN
CYCLE
END IF
t_z(Rz)=(edge2(1,i0)*pvec_z(1,Rz)+edge2(2,i0)*pvec_z(2,Rz)+edge2(3,i0)*pvec_z(3,Rz))/det_z(Rz)
mmz_per(Rz) = mmz_per(Rz) + 1
crosspoint_ZZ(mmz_per(Rz),Rz)%Global_Coord%Coord_X = orig_z(1,Rz) + t_z(Rz) * dir_z(1)
crosspoint_ZZ(mmz_per(Rz),Rz)%Global_Coord%Coord_Y = orig_z(2,Rz) + t_z(Rz) * dir_z(2)
crosspoint_ZZ(mmz_per(Rz),Rz)%Global_Coord%Coord_Z = orig_z(3,Rz) + t_z(Rz) * dir_z(3)
LOGICAL_1=crosspoint_ZZ(mmz_per(Rz),Rz)%Global_Coord%Coord_X<coordinates_x(1)
LOGICAL_2=crosspoint_ZZ(mmz_per(Rz),Rz)%Global_Coord%Coord_X>coordinates_x(NXB)
LOGICAL_3=crosspoint_ZZ(mmz_per(Rz),Rz)%Global_Coord%Coord_Y<coordinates_y(1)
LOGICAL_4=crosspoint_ZZ(mmz_per(Rz),Rz)%Global_Coord%Coord_Y>coordinates_y(NYB)
LOGICAL_5=crosspoint_ZZ(mmz_per(Rz),Rz)%Global_Coord%Coord_Z<coordinates_z(1)
LOGICAL_6=crosspoint_ZZ(mmz_per(Rz),Rz)%Global_Coord%Coord_Z>coordinates_z(NZB)
IF(LOGICAL_1 .OR. LOGICAL_2 .OR.LOGICAL_3 .OR.LOGICAL_4 .OR.LOGICAL_5 .OR.LOGICAL_6)THEN
mmz_per(Rz) = mmz_per(Rz) - 1
CYCLE
ENDIF
!*********************************Determine the intersection_Z attribute*******************************
verts_Dotmultp = dir_z(1) * Face_Triangle_NormVect(1,i0) + dir_z(2) * Face_Triangle_NormVect(2,i0) + dir_z(3) * Face_Triangle_NormVect(3,i0)
IF(verts_Dotmultp > 0.D0)THEN
crosspoint_ZZ(mmz_per(Rz),Rz)%Log_In=.TRUE.
ELSE
crosspoint_ZZ(mmz_per(Rz),Rz)%Log_In=.FALSE.
ENDIF
ENDDO
IF(mmz_per(Rz)>1)THEN
DO kk=2,mmz_per(Rz)
DO kkk=1,kk-1
IF(crosspoint_ZZ(kk,Rz)%Global_Coord%Coord_X<crosspoint_ZZ(kkk,Rz)%Global_Coord%Coord_X)THEN
CALL SWAP(crosspoint_ZZ(kk,Rz), crosspoint_ZZ(kkk,Rz))
ENDIF
ENDDO
ENDDO
ENDIF
ENDDO
ENDDO
!$OMP END PARALLEL DO
!$OMP PARALLEL DO PRIVATE(i0,k2,i2,Ry,verts_Dotmultp,LOGICAL_1,LOGICAL_2,LOGICAL_3,LOGICAL_4,LOGICAL_5,LOGICAL_6)
!get the intersaction of ray and y-face and save it into "coor_y_terrain"
DO k2=1,NZB
DO i2=1,NXB
Ry=(k2-1)*NXB+i2
DO i0=1,n_face
orig_y(1,Ry)=coordinates_x(i2)
orig_y(2,Ry)=coordinates_y(1)
orig_y(3,Ry)=coordinates_z(k2)
tvec_y(1:3,Ry) = orig_y(1:3,Ry) - vert0(1:3,i0)
pvec_y(1,Ry) = dir_y(2)*edge2(3,i0) - dir_y(3)*edge2(2,i0)
pvec_y(2,Ry) = dir_y(3)*edge2(1,i0) - dir_y(1)*edge2(3,i0)
pvec_y(3,Ry) = dir_y(1)*edge2(2,i0) - dir_y(2)*edge2(1,i0)
det_y(Ry)=edge1(1,i0)*pvec_y(1,Ry)+edge1(2,i0)*pvec_y(2,Ry)+edge1(3,i0)*pvec_y(3,Ry)
IF (abs(det_y(Ry)) < eps105) THEN
CYCLE
END IF
u_y(Ry) = (tvec_y(1,Ry)*pvec_y(1,Ry)+tvec_y(2,Ry)*pvec_y(2,Ry)+tvec_y(3,Ry)*pvec_y(3,Ry))/det_y(Ry)
IF (u_y(Ry) < 0.0 .or. u_y(Ry) > 1.0) THEN
CYCLE
END IF
pvec_y(1,Ry) = tvec_y(2,Ry)*edge1(3,i0) - tvec_y(3,Ry)*edge1(2,i0)
pvec_y(2,Ry) = tvec_y(3,Ry)*edge1(1,i0) - tvec_y(1,Ry)*edge1(3,i0)
pvec_y(3,Ry) = tvec_y(1,Ry)*edge1(2,i0) - tvec_y(2,Ry)*edge1(1,i0)
v_y(Ry) = (dir_y(1)*pvec_y(1,Ry)+dir_y(2)*pvec_y(2,Ry)+dir_y(3)*pvec_y(3,Ry))/det_y(Ry)
IF (v_y(Ry) < 0.0 .or. u_y(Ry) + v_y(Ry) > 1.0) THEN
CYCLE
END IF
t_y(Ry)=(edge2(1,i0)*pvec_y(1,Ry)+edge2(2,i0)*pvec_y(2,Ry)+edge2(3,i0)*pvec_y(3,Ry))/det_y(Ry)
mmy_per(Ry) = mmy_per(Ry) + 1
crosspoint_YY(mmy_per(Ry),Ry)%Global_Coord%Coord_X=orig_y(1,Ry) + t_y(Ry) * dir_y(1)
crosspoint_YY(mmy_per(Ry),Ry)%Global_Coord%Coord_Y=orig_y(2,Ry) + t_y(Ry) * dir_y(2)
crosspoint_YY(mmy_per(Ry),Ry)%Global_Coord%Coord_Z=orig_y(3,Ry) + t_y(Ry) * dir_y(3)
LOGICAL_1=crosspoint_YY(mmy_per(Ry),Ry)%Global_Coord%Coord_X<coordinates_x(1)
LOGICAL_2=crosspoint_YY(mmy_per(Ry),Ry)%Global_Coord%Coord_X>coordinates_x(NXB)
LOGICAL_3=crosspoint_YY(mmy_per(Ry),Ry)%Global_Coord%Coord_Y<coordinates_y(1)
LOGICAL_4=crosspoint_YY(mmy_per(Ry),Ry)%Global_Coord%Coord_Y>coordinates_y(NYB)
LOGICAL_5=crosspoint_YY(mmy_per(Ry),Ry)%Global_Coord%Coord_Z<coordinates_z(1)
LOGICAL_6=crosspoint_YY(mmy_per(Ry),Ry)%Global_Coord%Coord_Z>coordinates_z(NZB)
IF(LOGICAL_1 .OR. LOGICAL_2 .OR.LOGICAL_3 .OR.LOGICAL_4 .OR.LOGICAL_5 .OR.LOGICAL_6)THEN
mmy_per(Ry) = mmy_per(Ry) - 1
CYCLE
ENDIF
!*********************************Determine the intersection_Y attribute*******************************
verts_Dotmultp = dir_y(1) * Face_Triangle_NormVect(1,i0) + dir_y(2) * Face_Triangle_NormVect(2,i0) + dir_y(3) * Face_Triangle_NormVect(3,i0)
if(verts_Dotmultp > 0.D0)THEN
crosspoint_YY(mmy_per(Ry),Ry)%Log_In=.TRUE.
ELSE
crosspoint_YY(mmy_per(Ry),Ry)%Log_In=.FALSE.
ENDIF
ENDDO
IF(mmy_per(Ry)>1)THEN
DO jj=2,mmy_per(Ry)
DO jjj=1,jj-1
IF(crosspoint_YY(jj,Ry)%Global_Coord%Coord_Y<crosspoint_YY(jjj,Ry)%Global_Coord%Coord_Y)THEN
CALL SWAP(crosspoint_YY(jj,Ry), crosspoint_YY(jjj,Ry))
ENDIF
ENDDO
ENDDO
ENDIF
ENDDO
ENDDO
!$OMP END PARALLEL DO
!$OMP PARALLEL DO PRIVATE(i0,Rx,verts_Dotmultp,LOGICAL_1,LOGICAL_2,LOGICAL_3,LOGICAL_4,LOGICAL_5,LOGICAL_6)
!get the intersaction of ray and x-face and save it into "coor_x_terrain"
Do k3=1,NZB
Do j3=1,NYB
Rx=(k3-1)*NYB+j3
DO i0=1,n_face
orig_x(1,Rx)=coordinates_x(1)
orig_x(2,Rx)=coordinates_y(j3)
orig_x(3,Rx)=coordinates_z(k3)
tvec_x(1:3,Rx) = orig_x(1:3,Rx) - vert0(1:3,i0)
pvec_x(1,Rx) = dir_x(2)*edge2(3,i0) - dir_x(3)*edge2(2,i0)
pvec_x(2,Rx) = dir_x(3)*edge2(1,i0) - dir_x(1)*edge2(3,i0)
pvec_x(3,Rx) = dir_x(1)*edge2(2,i0) - dir_x(2)*edge2(1,i0)
det_x(Rx)=edge1(1,i0)*pvec_x(1,Rx)+edge1(2,i0)*pvec_x(2,Rx)+edge1(3,i0)*pvec_x(3,Rx)
IF (abs(det_x(Rx)) < eps105) THEN
CYCLE
END IF
u_x(Rx) = (tvec_x(1,Rx)*pvec_x(1,Rx)+tvec_x(2,Rx)*pvec_x(2,Rx)+tvec_x(3,Rx)*pvec_x(3,Rx))/det_x(Rx)
IF (u_x(Rx) < 0.0 .or. u_x(Rx) > 1.0) THEN
CYCLE
END IF
pvec_x(1,Rx) = tvec_x(2,Rx)*edge1(3,i0) - tvec_x(3,Rx)*edge1(2,i0)
pvec_x(2,Rx) = tvec_x(3,Rx)*edge1(1,i0) - tvec_x(1,Rx)*edge1(3,i0)
pvec_x(3,Rx) = tvec_x(1,Rx)*edge1(2,i0) - tvec_x(2,Rx)*edge1(1,i0)
v_x(Rx) = (dir_x(1)*pvec_x(1,Rx)+dir_x(2)*pvec_x(2,Rx)+dir_x(3)*pvec_x(3,Rx))/det_x(Rx)
IF (v_x(Rx) < 0.0 .or. u_x(Rx) + v_x(Rx) > 1.0) THEN
CYCLE
END IF
t_x(Rx)=(edge2(1,i0)*pvec_x(1,Rx)+edge2(2,i0)*pvec_x(2,Rx)+edge2(3,i0)*pvec_x(3,Rx))/det_x(Rx)
mmx_per(Rx) = mmx_per(Rx) + 1
crosspoint_XX(mmx_per(Rx),Rx)%Global_Coord%Coord_X= orig_x(1,Rx) + t_x(Rx) * dir_x(1)
crosspoint_XX(mmx_per(Rx),Rx)%Global_Coord%Coord_Y= orig_x(2,Rx) + t_x(Rx) * dir_x(2)
crosspoint_XX(mmx_per(Rx),Rx)%Global_Coord%Coord_Z= orig_x(3,Rx) + t_x(Rx) * dir_x(3)
LOGICAL_1=crosspoint_XX(mmx_per(Rx),Rx)%Global_Coord%Coord_X<coordinates_x(1)
LOGICAL_2=crosspoint_XX(mmx_per(Rx),Rx)%Global_Coord%Coord_X>coordinates_x(NXB)
LOGICAL_3=crosspoint_XX(mmx_per(Rx),Rx)%Global_Coord%Coord_Y<coordinates_y(1)
LOGICAL_4=crosspoint_XX(mmx_per(Rx),Rx)%Global_Coord%Coord_Y>coordinates_y(NYB)
LOGICAL_5=crosspoint_XX(mmx_per(Rx),Rx)%Global_Coord%Coord_Z<coordinates_z(1)
LOGICAL_6=crosspoint_XX(mmx_per(Rx),Rx)%Global_Coord%Coord_Z>coordinates_z(NZB)
IF(LOGICAL_1 .OR. LOGICAL_2 .OR.LOGICAL_3 .OR.LOGICAL_4 .OR.LOGICAL_5 .OR.LOGICAL_6)THEN
mmx_per(Rx) = mmx_per(Rx) - 1
CYCLE
ENDIF
!*********************************Determine the intersection_X attribute*******************************
verts_Dotmultp = dir_x(1) * Face_Triangle_NormVect(1,i0) + dir_x(2) * Face_Triangle_NormVect(2,i0) + dir_x(3) * Face_Triangle_NormVect(3,i0)
if(verts_Dotmultp > 0.D0)THEN
crosspoint_XX(mmx_per(Rx),Rx)%Log_In=.TRUE.
ELSE
crosspoint_XX(mmx_per(Rx),Rx)%Log_In=.FALSE.
ENDIF
ENDDO
IF(mmx_per(Rx)>1)THEN
DO ii=2,mmx_per(Rx)
DO iii=1,mmx_per(Rx)-1
IF(crosspoint_XX(ii,Rx)%Global_Coord%Coord_X<crosspoint_XX(iii,Rx)%Global_Coord%Coord_X)THEN
CALL SWAP(crosspoint_XX(ii,Rx), crosspoint_XX(iii,Rx))
ENDIF
ENDDO
ENDDO
ENDIF
ENDDO
ENDDO
!$OMP END PARALLEL DO
PRINT*,'Ray tracing computation of terrain is complete!'
!=========================================================================================================
WRITE(5141,*)"========================== This is the SUBROUTINE CONFORMALGRID =========================="
!=========================================Terrain conformal in the x-direction==========================================
!>The x-conductivity is being treated
DO k=1, Z_min-1
DO j=1, NYB
DO i=1,NX
CCSIGX(I,J,K)=AIR_CONDUCTIVITY
ENDDO
ENDDO
ENDDO
DO k=Z_max+1, NZB
DO j=1, NYB
DO i=1,NX
CCSIGX(I,J,K)=TAR_CONDUCTIVITY(2)
ENDDO
ENDDO
ENDDO
DO k=Z_min, Z_max
DO j=1, NYB
Rx=(k-1)*NYB+j
IF(mmx_per(Rx)==1)THEN !The case with only one intersection point
IF (crosspoint_XX(1,Rx)%Log_In) THEN !The intersection point is the penetration point, that is, the air penetrates into the stratum
DO i=1,NX
Logic_1=(crosspoint_XX(mmx_per(Rx),Rx)%Global_Coord%Coord_X > coordinates_x(i)).AND. &
& (crosspoint_XX(mmx_per(Rx),Rx)%Global_Coord%Coord_X < coordinates_x(i+1))
IF(Logic_1) THEN
KIdx_1=i
EXIT
ENDIF
ENDDO
LenRatio_CCSIGX(KIdx_1,J,K) = ABS((crosspoint_XX(1,Rx)%Global_Coord%Coord_X-coordinates_x(KIdx_1)))/Cdelx(KIdx_1)
CCSIGX(1:(KIdx_1-1),J,K) = AIR_CONDUCTIVITY
CCSIGX(KIdx_1,J,K) = LenRatio_CCSIGX(KIdx_1,J,K)*AIR_CONDUCTIVITY+(1-LenRatio_CCSIGX(KIdx_1,J,K))*TAR_CONDUCTIVITY(2)
CCSIGX((KIdx_1+1):NX,J,K) = TAR_CONDUCTIVITY(2)
ELSE !The intersection point is the exit point, that is, it penetrates into the air from the stratum
DO i=1,NX
Logic_1=(crosspoint_XX(mmx_per(Rx),Rx)%Global_Coord%Coord_X > coordinates_x(i)).AND. &
& (crosspoint_XX(mmx_per(Rx),Rx)%Global_Coord%Coord_X < coordinates_x(i+1))
IF(Logic_1) THEN
KIdx_1=i
EXIT
ENDIF
ENDDO
LenRatio_CCSIGX(KIdx_1,J,K) = ABS((crosspoint_XX(1,Rx)%Global_Coord%Coord_X-coordinates_x(KIdx_1)))/Cdelx(KIdx_1)
CCSIGX(1:(KIdx_1-1),J,K) = TAR_CONDUCTIVITY(2)
CCSIGX(KIdx_1,J,K) = LenRatio_CCSIGX(KIdx_1,J,K)*TAR_CONDUCTIVITY(2)+(1-LenRatio_CCSIGX(KIdx_1,J,K))*AIR_CONDUCTIVITY
CCSIGX((KIdx_1+1):NX,J,K) = AIR_CONDUCTIVITY
ENDIF
ELSEIF(mmx_per(Rx)>1)THEN !There are intersection points and the number is greater than one
idx_start=0;idx_end=0
DO ii=1,mmx_per(Rx)
IF (ii==1)THEN !First, determine the first intersection point
IF(crosspoint_XX(ii,Rx)%Log_In)THEN
idx_start=ii
ELSEIF(.NOT.crosspoint_XX(ii,Rx)%Log_In)THEN
idx_end=ii
ENDIF
IF (crosspoint_XX(ii,Rx)%Log_In) THEN !The intersection point is the penetration point, that is, the air penetrates into the stratum
DO i=1,NX
Logic_1=(crosspoint_XX(ii,Rx)%Global_Coord%Coord_X > coordinates_x(i)).AND. &
& (crosspoint_XX(ii,Rx)%Global_Coord%Coord_X < coordinates_x(i+1))
IF(Logic_1) THEN
KIdx_1=i
EXIT
ENDIF
ENDDO
CCSIGX(1:(KIdx_1-1),J,K) = AIR_CONDUCTIVITY
ELSE !The intersection point is the exit point, that is, it penetrates into the air from the stratum
DO i=1,NX
Logic_1=(crosspoint_XX(ii,Rx)%Global_Coord%Coord_X > coordinates_x(i)).AND. &
& (crosspoint_XX(ii,Rx)%Global_Coord%Coord_X < coordinates_x(i+1))
IF(Logic_1) THEN
KIdx_1=i
EXIT
ENDIF
ENDDO
CCSIGX(1:(KIdx_1-1),J,K) = TAR_CONDUCTIVITY(2)
ENDIF
ENDIF
IF(crosspoint_XX(ii,Rx)%Log_In)THEN
idx_start=ii
ELSEIF(.NOT.crosspoint_XX(ii,Rx)%Log_In)THEN
idx_end=ii
ENDIF
IF((idx_start>0).AND.(idx_end>0))THEN
DO i=1,NX
Logic_1=(crosspoint_XX(idx_start,Rx)%Global_Coord%Coord_X > coordinates_x(i)).AND. &
& (crosspoint_XX(idx_start,Rx)%Global_Coord%Coord_X < coordinates_x(i+1))
Logic_2=(crosspoint_XX(idx_end,Rx)%Global_Coord%Coord_X > coordinates_x(i)).AND. &
& (crosspoint_XX(idx_end,Rx)%Global_Coord%Coord_X < coordinates_x(i+1))
IF(Logic_1) KIdx_1=i
IF(Logic_2) KIdx_2=i
IF(Logic_1.and.Logic_2) EXIT
ENDDO
IF(idx_start<idx_end) THEN !First, break through the air and enter the stratum
IF(KIdx_1==KIdx_2) THEN
LenRatio_CCSIGX(KIdx_1,J,K) = ABS((crosspoint_XX(idx_end,Rx)%Global_Coord%Coord_X-crosspoint_XX(idx_start,Rx)%Global_Coord%Coord_X))/Cdelx(KIdx_1)
CCSIGX(KIdx_1,J,K) =AIR_CONDUCTIVITY * (1-LenRatio_CCSIGX(KIdx_1,J,K)) + TAR_CONDUCTIVITY(2) * LenRatio_CCSIGX(KIdx_1,J,K)
ELSEIF(KIdx_2 > KIdx_1)THEN
LenRatio_CCSIGX(KIdx_1,J,K) = ABS((crosspoint_XX(idx_start,Rx)%Global_Coord%Coord_X-coordinates_x(KIdx_1)))/Cdelx(KIdx_1)
LenRatio_CCSIGX(KIdx_2,J,K) = ABS((crosspoint_XX(idx_end,Rx)%Global_Coord%Coord_X-coordinates_x(KIdx_2)))/Cdelx(KIdx_2)
CCSIGX(KIdx_1,J,K) = AIR_CONDUCTIVITY * LenRatio_CCSIGX(KIdx_1,J,K) + TAR_CONDUCTIVITY(2) * (1-LenRatio_CCSIGX(KIdx_1,J,K))
CCSIGX((KIdx_1+1):(KIdx_2-1),J,K) = TAR_CONDUCTIVITY(2)
CCSIGX(KIdx_2,J,K) = TAR_CONDUCTIVITY(2) * LenRatio_CCSIGX(KIdx_2,J,K) + AIR_CONDUCTIVITY * (1-LenRatio_CCSIGX(KIdx_2,J,K))
ENDIF
ELSE !First, break through the stratum and enter the air
IF(KIdx_1==KIdx_2) THEN
LenRatio_CCSIGX(KIdx_1,J,K) = ABS((crosspoint_XX(idx_start,Rx)%Global_Coord%Coord_X-crosspoint_XX(idx_end,Rx)%Global_Coord%Coord_X))/Cdelx(KIdx_1)
CCSIGX(KIdx_1,J,K) = CCSIGX(KIdx_1,J,K)+TAR_CONDUCTIVITY(2) * LenRatio_CCSIGX(KIdx_1,J,K)
ELSEIF(KIdx_2 < KIdx_1)THEN
LenRatio_CCSIGX(KIdx_1,J,K) = ABS((coordinates_x(KIdx_1+1)-crosspoint_XX(idx_start,Rx)%Global_Coord%Coord_X))/Cdelx(KIdx_1)
LenRatio_CCSIGX(KIdx_2,J,K) = ABS((crosspoint_XX(idx_end,Rx)%Global_Coord%Coord_X-coordinates_x(KIdx_2)))/Cdelx(KIdx_2)
CCSIGX(KIdx_2,J,K) = TAR_CONDUCTIVITY(2) * LenRatio_CCSIGX(KIdx_2,J,K) + AIR_CONDUCTIVITY * (1-LenRatio_CCSIGX(KIdx_2,J,K))
CCSIGX((KIdx_2+1):(KIdx_1-1),J,K) = AIR_CONDUCTIVITY
CCSIGX(KIdx_1,J,K) = AIR_CONDUCTIVITY * LenRatio_CCSIGX(KIdx_1,J,K) + TAR_CONDUCTIVITY(2) * (1-LenRatio_CCSIGX(KIdx_1,J,K))
ENDIF
ENDIF
ENDIF
IF(ii==mmx_per(Rx))THEN !The last intersection point
IF(crosspoint_XX(ii,Rx)%Log_In)THEN
idx_start=ii
ELSEIF(.NOT.crosspoint_XX(ii,Rx)%Log_In)THEN
idx_end=ii
ENDIF
IF (crosspoint_XX(ii,Rx)%Log_In) THEN !The intersection point is the penetration point, that is, the air penetrates into the stratum
DO i=1,NX
Logic_1=(crosspoint_XX(mmx_per(Rx),Rx)%Global_Coord%Coord_X > coordinates_x(i)).AND. &
& (crosspoint_XX(mmx_per(Rx),Rx)%Global_Coord%Coord_X < coordinates_x(i+1))
IF(Logic_1) THEN
KIdx_1=i
EXIT
ENDIF
ENDDO
CCSIGX((KIdx_1+1):NX,J,K) = TAR_CONDUCTIVITY(2)
ELSE !The intersection point is the exit point, that is, it penetrates into the air from the stratum
DO i=1,NX
Logic_1=(crosspoint_XX(ii,Rx)%Global_Coord%Coord_X > coordinates_x(i)).AND. &
& (crosspoint_XX(ii,Rx)%Global_Coord%Coord_X < coordinates_x(i+1))
IF(Logic_1) THEN
KIdx_1=i
EXIT
ENDIF
ENDDO
CCSIGX((KIdx_1+1):NX,J,K) = AIR_CONDUCTIVITY
ENDIF
ENDIF
ENDDO
ELSEIF(mmx_per(Rx)==0)THEN !In the absence of an intersection point, directly compare the Z-direction positional relationship between the ray and the z-intersection point on the plane
IF(coordinates_z(k)>crosspoint_ZZ(1,(j-1)*NXB+2)%Global_Coord%Coord_Z) THEN
CCSIGX(:,J,K) = TAR_CONDUCTIVITY(2)
ELSE
CCSIGX(:,J,K) = AIR_CONDUCTIVITY
ENDIF
ENDIF
ENDDO
ENDDO
!=========================================Terrain conformal in the y-direction==========================================
!>The y-conductivity is being treated
DO k=1, Z_min-1
DO j=1, NY
DO i=1,NXB
CCSIGY(I,J,K)=AIR_CONDUCTIVITY
ENDDO
ENDDO
ENDDO
DO k=Z_max+1, NZB
DO j=1, NY
DO i=1,NXB
CCSIGY(I,J,K)=TAR_CONDUCTIVITY(2)
ENDDO
ENDDO
ENDDO
DO k=Z_min, Z_max
DO i=1, NXB
Ry=(k-1)*NXB+i
IF(mmy_per(Ry)==1)THEN !The case with only one intersection point
IF (crosspoint_YY(1,Ry)%Log_In) THEN !The intersection point is the penetration point, that is, the air penetrates into the stratum
DO j=1,NY
Logic_1=(crosspoint_YY(mmy_per(Ry),Ry)%Global_Coord%Coord_Y > coordinates_y(j)).AND. &
& (crosspoint_YY(mmy_per(Ry),Ry)%Global_Coord%Coord_Y < coordinates_y(j+1))
IF(Logic_1) THEN
KIdx_1=j
EXIT
ENDIF
ENDDO
LenRatio_CCSIGY(i,KIdx_1,k) = ABS((crosspoint_YY(1,Ry)%Global_Coord%Coord_Y-coordinates_y(KIdx_1)))/Cdely(KIdx_1)
CCSIGY(i,1:(KIdx_1-1),k) = AIR_CONDUCTIVITY
CCSIGY(i,KIdx_1,k) = LenRatio_CCSIGY(i,KIdx_1,k)*AIR_CONDUCTIVITY+(1-LenRatio_CCSIGY(i,KIdx_1,k))*TAR_CONDUCTIVITY(2)
CCSIGY(i,(KIdx_1+1):NY,k) = TAR_CONDUCTIVITY(2)
ELSE !The intersection point is the exit point, that is, it penetrates into the air from the stratum
DO j=1,NY
Logic_1=(crosspoint_YY(mmy_per(Ry),Ry)%Global_Coord%Coord_Y > coordinates_y(j)).AND. &
& (crosspoint_YY(mmy_per(Ry),Ry)%Global_Coord%Coord_Y < coordinates_y(j+1))
IF(Logic_1) THEN
KIdx_1=j
EXIT
ENDIF
ENDDO
LenRatio_CCSIGY(i,KIdx_1,k) = ABS((crosspoint_YY(1,Ry)%Global_Coord%Coord_Y-coordinates_y(KIdx_1)))/Cdely(KIdx_1)
CCSIGY(i,1:(KIdx_1-1),k) = TAR_CONDUCTIVITY(2)
CCSIGY(i,KIdx_1,K) = LenRatio_CCSIGY(i,KIdx_1,K)*TAR_CONDUCTIVITY(2)+(1-LenRatio_CCSIGY(i,KIdx_1,k))*AIR_CONDUCTIVITY
CCSIGY(i,(KIdx_1+1):NY,k) = AIR_CONDUCTIVITY
ENDIF
ELSEIF(mmy_per(Ry)>1)THEN !There are intersection points and the number is greater than one
idx_start=0;idx_end=0
DO ii=1,mmy_per(Ry)
IF (ii==1)THEN !First, determine the first intersection point
IF (crosspoint_YY(ii,Ry)%Log_In) THEN !The intersection point is the penetration point, that is, the air penetrates into the stratum
DO j=1,NY
Logic_1=(crosspoint_YY(ii,Ry)%Global_Coord%Coord_Y > coordinates_y(j)).AND. &
& (crosspoint_YY(ii,Ry)%Global_Coord%Coord_Y < coordinates_y(j+1))
IF(Logic_1) THEN
KIdx_1=j
EXIT
ENDIF
ENDDO
CCSIGY(i,1:(KIdx_1-1),k) = AIR_CONDUCTIVITY
ELSE !The intersection point is the exit point, that is, it penetrates into the air from the stratum
DO j=1,NY
Logic_1=(crosspoint_YY(ii,Ry)%Global_Coord%Coord_Y > coordinates_y(j)).AND. &
& (crosspoint_YY(ii,Ry)%Global_Coord%Coord_Y < coordinates_y(j+1))
IF(Logic_1) THEN
KIdx_1=j
EXIT
ENDIF
ENDDO
CCSIGY(i,1:(KIdx_1-1),k) = TAR_CONDUCTIVITY(2)
ENDIF
ENDIF
IF(crosspoint_YY(ii,Ry)%Log_In)THEN
idx_start=ii
ELSEIF(.NOT.crosspoint_YY(ii,Ry)%Log_In)THEN
idx_end=ii
ENDIF
IF((idx_start>0).AND.(idx_end>0))THEN
DO j=1,NY
Logic_1=(crosspoint_YY(idx_start,Ry)%Global_Coord%Coord_Y > coordinates_y(j)).AND. &
& (crosspoint_YY(idx_start,Ry)%Global_Coord%Coord_Y < coordinates_y(j+1))
Logic_2=(crosspoint_YY(idx_end,Ry)%Global_Coord%Coord_Y > coordinates_y(j)).AND. &
& (crosspoint_YY(idx_end,Ry)%Global_Coord%Coord_Y < coordinates_y(j+1))
IF(Logic_1) KIdx_1=j
IF(Logic_2) KIdx_2=j
IF(Logic_1.and.Logic_2) EXIT
ENDDO
IF(idx_start<idx_end) THEN !The ray first penetrate the air and enter the stratum
IF(KIdx_1==KIdx_2) THEN
LenRatio_CCSIGY(i,KIdx_1,k) = ABS((crosspoint_YY(idx_end,Ry)%Global_Coord%Coord_Y-crosspoint_YY(idx_start,Ry)%Global_Coord%Coord_Y))/Cdely(KIdx_1)
CCSIGY(i,KIdx_1,k) = AIR_CONDUCTIVITY * (1-LenRatio_CCSIGY(i,KIdx_1,K))+TAR_CONDUCTIVITY(2) * LenRatio_CCSIGY(i,KIdx_1,k)
ELSEIF(KIdx_2 > KIdx_1)THEN
LenRatio_CCSIGY(i,KIdx_1,k) = ABS((crosspoint_YY(idx_start,Ry)%Global_Coord%Coord_Y-coordinates_y(KIdx_1)))/Cdely(KIdx_1)
LenRatio_CCSIGY(i,KIdx_2,k) = ABS((crosspoint_YY(idx_end,Ry)%Global_Coord%Coord_Y-coordinates_y(KIdx_2)))/Cdely(KIdx_2)
CCSIGY(i,KIdx_1,k) = AIR_CONDUCTIVITY * LenRatio_CCSIGY(i,KIdx_1,k) + TAR_CONDUCTIVITY(2) * (1-LenRatio_CCSIGY(i,KIdx_1,k))
CCSIGY(i,(KIdx_1+1):(KIdx_2-1),K) = TAR_CONDUCTIVITY(2)
CCSIGY(i,KIdx_2,k) = TAR_CONDUCTIVITY(2) * LenRatio_CCSIGY(i,KIdx_2,k) + AIR_CONDUCTIVITY * (1-LenRatio_CCSIGY(i,KIdx_2,k))
ENDIF
ELSE !The ray first penetrate the stratum and enter the air
IF(KIdx_1==KIdx_2) THEN
LenRatio_CCSIGY(i,KIdx_1,k) = ABS((crosspoint_YY(idx_start,Ry)%Global_Coord%Coord_Y-crosspoint_YY(idx_end,Ry)%Global_Coord%Coord_Y))/Cdely(KIdx_1)
CCSIGY(i,KIdx_1,k) = TAR_CONDUCTIVITY(2) * (1-LenRatio_CCSIGY(i,KIdx_1,K))+AIR_CONDUCTIVITY * LenRatio_CCSIGY(i,KIdx_1,k)
ELSEIF(KIdx_2 < KIdx_1)THEN
LenRatio_CCSIGY(i,KIdx_1,k) = ABS((coordinates_y(KIdx_1+1)-crosspoint_YY(idx_start,Ry)%Global_Coord%Coord_Y))/Cdely(KIdx_1)
LenRatio_CCSIGY(i,KIdx_2,k) = ABS((crosspoint_YY(idx_end,Ry)%Global_Coord%Coord_Y-coordinates_y(KIdx_2)))/Cdely(KIdx_2)
CCSIGY(i,KIdx_2,k) = TAR_CONDUCTIVITY(2) * LenRatio_CCSIGY(i,KIdx_2,K) + AIR_CONDUCTIVITY * (1-LenRatio_CCSIGY(i,KIdx_2,k))
CCSIGY(i,(KIdx_2+1):(KIdx_1-1),k) = AIR_CONDUCTIVITY
CCSIGY(i,KIdx_1,k) = AIR_CONDUCTIVITY * LenRatio_CCSIGX(i,KIdx_1,K)+TAR_CONDUCTIVITY(2)*(1-LenRatio_CCSIGY(i,KIdx_1,k))
ENDIF
ENDIF
ENDIF
IF(ii==mmy_per(Ry))THEN !The last intersection point
IF (crosspoint_YY(ii,Ry)%Log_In) THEN !The intersection point is the penetration point, that is, the air penetrates into the stratum
DO j=1,Ny
Logic_1=(crosspoint_YY(mmy_per(Ry),Ry)%Global_Coord%Coord_Y > coordinates_y(j)).AND. &
& (crosspoint_YY(mmy_per(Ry),Ry)%Global_Coord%Coord_Y < coordinates_y(j+1))
IF(Logic_1) THEN
KIdx_1=j
EXIT
ENDIF
ENDDO
CCSIGY(i,(KIdx_1+1):NY,k) = TAR_CONDUCTIVITY(2)
ELSE !The intersection point is the exit point, that is, it penetrates into the air from the stratum
DO j=1,Ny
Logic_1=(crosspoint_YY(mmy_per(Ry),Ry)%Global_Coord%Coord_Y > coordinates_y(j)).AND. &
& (crosspoint_YY(mmy_per(Ry),Ry)%Global_Coord%Coord_Y < coordinates_y(j+1))
IF(Logic_1) THEN
KIdx_1=j
EXIT
ENDIF
ENDDO
CCSIGY(i,(KIdx_1+1):NY,k) = AIR_CONDUCTIVITY
ENDIF
ENDIF
ENDDO
ELSEIF(mmy_per(Ry)==0)THEN !In the absence of an intersection point, directly compare the Z-direction positional relationship between the ray and the z-intersection point on the plane
IF(coordinates_z(k)>crosspoint_ZZ(1,(i-1)*NXB+2)%Global_Coord%Coord_Z) THEN
CCSIGY(i,:,k) = TAR_CONDUCTIVITY(2)
ELSE
CCSIGY(i,:,k) = AIR_CONDUCTIVITY
ENDIF
ENDIF
ENDDO
ENDDO
!=========================================Terrain conformal in the z-direction==========================================
!>The z-conductivity is being treated
DO j=1, NYB
DO i=1, NXB
Rz=(j-1)*NXB+i
IF(mmz_per(Rz)>0)THEN
DO k=1,NZ
Logic_1=(crosspoint_ZZ(mmz_per(Rz),Rz)%Global_Coord%Coord_Z > coordinates_z(k)).AND. &
& (crosspoint_ZZ(mmz_per(Rz),Rz)%Global_Coord%Coord_Z < coordinates_z(k+1))
IF(Logic_1) THEN
KIdx_1=k
EXIT
ENDIF
ENDDO
ENDIF
LenRatio_CCSIGZ(i,j,KIdx_1) = (crosspoint_ZZ(1,Rz)%Global_Coord%Coord_Z-coordinates_z(KIdx_1))/Cdelz(KIdx_1)
CCSIGZ(i,j,1:(KIdx_1-1)) = AIR_CONDUCTIVITY
CCSIGZ(i,j,KIdx_1) = LenRatio_CCSIGZ(i,j,KIdx_1)*AIR_CONDUCTIVITY+(1-LenRatio_CCSIGZ(i,j,KIdx_1))*TAR_CONDUCTIVITY(2)
CCSIGZ(i,j,(KIdx_1+1):NZ) = TAR_CONDUCTIVITY(2)
ENDDO
ENDDO
END SUBROUTINE terrain_conformal
+63 -9
查看文件
@@ -1,6 +1,6 @@
!Copyright (c) 2013 by tdem.org under guide of Xiu Li(lixiu@chd.edu.cn) !Copyright (c) 2013 by https://git.em3d.cn/ under guide of Xiu Li(lixiu@chd.edu.cn)
!written by Huaifeng Sun(sunhuaifeng@gmail.com) and Xushan Lu(luxushan@gmail.com) !written by Huaifeng Sun(sunhuaifeng@email.sdu.edu.cn) and Xushan Lu(luxushan@gmail.com)
!Code distribution @ tdem.org or sunhuaifeng.com !Code distribution @ https://git.em3d.cn/
!function description !function description
!this subroutine is used to allocate dynamic memory to the selected array. !this subroutine is used to allocate dynamic memory to the selected array.
@@ -13,15 +13,22 @@ SUBROUTINE ALLOCATEMEMORY
USE ELECTROMAGNETIC_VARIABLES USE ELECTROMAGNETIC_VARIABLES
USE RES_MODEL_PARAMETER USE RES_MODEL_PARAMETER
USE TIME_PARAMETER USE TIME_PARAMETER
USE PML_PARAMETER
IMPLICIT NONE IMPLICIT NONE
INTEGER ERR INTEGER ERR
!分配ELECTROMAGNETIC_VARIABLES中的数组
WRITE(*,*)'Allocating memory... ...' WRITE(*,*)'Allocating memory... ...'
!>Allocate the arrays in ELECTROMAGNETIC_VARIABLES
!! Allocate electric field components EX, EY, EZ
!! Allocate magnetic field components HX, HY, HZ
ALLOCATE(EX(NX,NYB,NZB), EY(NXB,NY,NZB), EZ(NXB,NYB,NZ), STAT=ERR) ALLOCATE(EX(NX,NYB,NZB), EY(NXB,NY,NZB), EZ(NXB,NYB,NZ), STAT=ERR)
ALLOCATE(HX(NXB,NY,0:NZ), HY(NX,NYB,0:NZ), HZ(NX,NY,NZB), STAT=ERR) ALLOCATE(HX(NXB,NY,0:NZ), HY(NX,NYB,0:NZ), HZ(NX,NY,NZB), STAT=ERR)
!分配RES_MODEL_PARAMETER中的数组 !>Allocate the array in RES_MODEL_PARAMETER
ALLOCATE(CCSIG(NX,NY,NZ), STAT=ERR) !! Allocate conductivity arrays
!分配TIME_PARAMETER中的数组 ALLOCATE(CCSIG(NX,NY,NZ))
ALLOCATE(CCSIGX(NX,NYB,NZB), CCSIGY(NXB,NY,NZB), CCSIGZ(NXB,NYB,NZ))
ALLOCATE(LenRatio_CCSIGX(NX,NYB,NZB), LenRatio_CCSIGY(NXB,NY,NZB), LenRatio_CCSIGZ(NXB,NYB,NZ))
allocate(Coordix(NX),Coordiy(NY),Coordiz(NZ))
!>Allocate the array in TIME_PARAMETER
ALLOCATE(CTIME(NSTOP), STAT=ERR) ALLOCATE(CTIME(NSTOP), STAT=ERR)
ALLOCATE(DELT(0:NSTOP), STAT=ERR) ALLOCATE(DELT(0:NSTOP), STAT=ERR)
allocate(Eps_r(nstop),Cq(nstop)) allocate(Eps_r(nstop),Cq(nstop))
@@ -30,8 +37,55 @@ SUBROUTINE ALLOCATEMEMORY
allocate(RecFile(NumRecHeights+1,NumRecLines),RecFilePid(NumRecHeights+1,NumRecLines)) allocate(RecFile(NumRecHeights+1,NumRecLines),RecFilePid(NumRecHeights+1,NumRecLines))
allocate(RecHzFilePid(NumRecHeights+1,NumRecLines),RecHEFilePid(NumRecHeights+1,NumRecLines)) allocate(RecHzFilePid(NumRecHeights+1,NumRecLines),RecHEFilePid(NumRecHeights+1,NumRecLines))
allocate(Height(NumRecHeights)) allocate(Height(NumRecHeights))
allocate(Coordix3(Nx),Coordiy3(Ny),Coordiz3(Nzb)) !>THIS IS THE ARRAY FOR NON-UNIFORM GRID
!THIS IS THE ARRAY FOR NON-UNIFORM GRID
ALLOCATE(CDELX(NX),CDELY(NY),CDELZ(NZ),STAT=ERR) ALLOCATE(CDELX(NX),CDELY(NY),CDELZ(NZ),STAT=ERR)
!>Arrays of the CPML absorbing boundary
!! den_* = 1/kappa_* scaling arrays: always allocated; they are initialized to
!! 1.0 in ZERO, and overwritten by Get_pml_parameters only when Logic_PML=1.
!! So the iteration loop always multiplies the curl terms by den_*, and the
!! scheme degenerates exactly to the original Dirichlet-boundary version
!! (den=1, psi never updated) when the CPML boundary is disabled.
ALLOCATE(den_ex(NX),den_hx(NX),den_ey(NY),den_hy(NY),den_ez(NZ),den_hz(NZ))
ALLOCATE(c_h_zz(NZ))
ALLOCATE(inv_hz_den(NZ))
IF(Logic_PML==1)THEN
ALLOCATE(psi_Exy_1(NX,PML_Y1,NZB), psi_Exy_2(NX,PML_Y2,NZB), &
psi_Exz_1(NX,NYB,PML_Z1), psi_Exz_2(NX,NYB,PML_Z2), &
psi_Eyx_1(PML_X1,NY,NZB), psi_Eyx_2(PML_X2,NY,NZB), &
psi_Eyz_1(NXB,NY,PML_Z1), psi_Eyz_2(NXB,NY,PML_Z2), &
psi_Ezx_1(PML_X1,NYB,NZ), psi_Ezx_2(PML_X2,NYB,NZ), &
psi_Ezy_1(NXB,PML_Y1,NZ), psi_Ezy_2(NXB,PML_Y2,NZ), &
psi_Hxy_1(NXB,PML_Y1-1,NZ), psi_Hxy_2(NXB,PML_Y2-1,NZ),&
psi_Hxz_1(NXB,NY,PML_Z1-1), psi_Hxz_2(NXB,NY,PML_Z2-1),&
psi_Hyx_1(PML_X1-1,NYB,NZ), psi_Hyx_2(PML_X2-1,NYB,NZ),&
psi_Hyz_1(NX,NYB,PML_Z1-1), psi_Hyz_2(NX,NYB,PML_Z2-1),&
psi_Hzx_1(PML_X1-1,NY,NZB), psi_Hzx_2(PML_X2-1,NY,NZB),&
psi_Hzy_1(NX,PML_Y1-1,NZB), psi_Hzy_2(NX,PML_Y2-1,NZB),&
psi_Hzz_1(NX,NY,PML_Z1-1), psi_Hzz_2(NX,NY,PML_Z2-1),STAT=ERR)
ALLOCATE(b_e_x1(PML_X1),c_e_x1(PML_X1),&
alpha_PML_e_x1(PML_X1),sig_PML_e_x1(PML_X1),kappa_PML_e_x1(PML_X1))
ALLOCATE(b_h_x1(PML_X1-1),c_h_x1(PML_X1-1),&
alpha_PML_h_x1(PML_X1-1),sig_PML_h_x1(PML_X1-1),kappa_PML_h_x1(PML_X1-1))
ALLOCATE(b_e_x2(PML_X2),c_e_x2(PML_X2),&
alpha_PML_e_x2(PML_X2),sig_PML_e_x2(PML_X2),kappa_PML_e_x2(PML_X2))
ALLOCATE(b_h_x2(PML_X2-1),c_h_x2(PML_X2-1),&
alpha_PML_h_x2(PML_X2-1),sig_PML_h_x2(PML_X2-1),kappa_PML_h_x2(PML_X2-1))
ALLOCATE(b_e_y1(PML_Y1),c_e_y1(PML_Y1),&
alpha_PML_e_y1(PML_Y1),sig_PML_e_y1(PML_Y1),kappa_PML_e_y1(PML_Y1))
ALLOCATE(b_h_y1(PML_Y1-1),c_h_y1(PML_Y1-1),&
alpha_PML_h_y1(PML_Y1-1),sig_PML_h_y1(PML_Y1-1),kappa_PML_h_y1(PML_Y1-1))
ALLOCATE(b_e_y2(PML_Y2),c_e_y2(PML_Y2),&
alpha_PML_e_y2(PML_Y2),sig_PML_e_y2(PML_Y2),kappa_PML_e_y2(PML_Y2))
ALLOCATE(b_h_y2(PML_Y2-1),c_h_y2(PML_Y2-1),&
alpha_PML_h_y2(PML_Y2-1),sig_PML_h_y2(PML_Y2-1),kappa_PML_h_y2(PML_Y2-1))
ALLOCATE(b_e_z1(PML_Z1),c_e_z1(PML_Z1),&
alpha_PML_e_z1(PML_Z1),sig_PML_e_z1(PML_Z1),kappa_PML_e_z1(PML_Z1))
ALLOCATE(b_h_z1(PML_Z1-1),c_h_z1(PML_Z1-1),&
alpha_PML_h_z1(PML_Z1-1),sig_PML_h_z1(PML_Z1-1),kappa_PML_h_z1(PML_Z1-1))
ALLOCATE(b_e_z2(PML_Z2),c_e_z2(PML_Z2),&
alpha_PML_e_z2(PML_Z2),sig_PML_e_z2(PML_Z2),kappa_PML_e_z2(PML_Z2))
ALLOCATE(b_h_z2(PML_Z2-1),c_h_z2(PML_Z2-1),&
alpha_PML_h_z2(PML_Z2-1),sig_PML_h_z2(PML_Z2-1),kappa_PML_h_z2(PML_Z2-1))
ENDIF
RETURN RETURN
ENDSUBROUTINE ALLOCATEMEMORY ENDSUBROUTINE ALLOCATEMEMORY
+18 -11
查看文件
@@ -1,6 +1,6 @@
!Copyright (c) 2013 by tdem.org under guide of Xiu Li(lixiu@chd.edu.cn) !Copyright (c) 2013 by https://git.em3d.cn/ under guide of Xiu Li(lixiu@chd.edu.cn)
!written by Huaifeng Sun(sunhuaifeng@gmail.com) and Xushan Lu(luxushan@gmail.com) !written by Huaifeng Sun(sunhuaifeng@email.sdu.edu.cn) and Xushan Lu(luxushan@gmail.com)
!Code distribution @ tdem.org or sunhuaifeng.com !Code distribution @ https://git.em3d.cn/
!function description !function description
!this suboutine is used to write out the readed calculation parameters for !this suboutine is used to write out the readed calculation parameters for
@@ -11,19 +11,26 @@ SUBROUTINE CHECKPARAMETERS
USE CONSTANTPARAMETERS USE CONSTANTPARAMETERS
IMPLICIT NONE IMPLICIT NONE
integer i integer i
WRITE(10005,*)'请检查计算参数: ' WRITE(10005,*)'Please check the calculation parameters: '
WRITE(10005,*)'矩形回线边长为:',SourceLength WRITE(10005,*)'Side length of rectangular source loop:',SourceLength
WRITE(10005,*)'X,Y,Z方向的网格数分别为:',NX,NY,NZ WRITE(10005,*)'Number of grid cells in X, Y, Z directions:',NX,NY,NZ
WRITE(10005,*)'线圈中心所处的网格为: ',NXS,NYS,NZS WRITE(10005,*)'Grid indices of the coil center: ',NXS,NYS,NZS
WRITE(10005,*)'输入的最大迭代次数为: ',NSTOP WRITE(10005,*)'Maximum number of iterations specified: ',NSTOP
WRITE(10005,*) WRITE(10005,*)
WRITE(10005,*)'X,Y,Z方向最小晶格尺寸分别为:' WRITE(10005,*)'Minimum grid spacing in X, Y, Z directions:'
WRITE(10005,*)'DELTA_X=',GridSize WRITE(10005,*)'DELTA_X=',GridSize
WRITE(10005,*)'DELTA_Y=',GridSize WRITE(10005,*)'DELTA_Y=',GridSize
WRITE(10005,*)'DELTA_Z=',GridSize WRITE(10005,*)'DELTA_Z=',GridSize
WRITE(10005,*)'背景电导率',BACKGROUND_CONDUCTIVITY WRITE(10005,*)'Background conductivity:',BACKGROUND_CONDUCTIVITY
WRITE(10005,*) WRITE(10005,*)
WRITE(10005,*)'异常体参数' IF(Logic_PML==1)THEN
WRITE(10005,*)'Boundary condition: CPML absorbing boundary'
WRITE(10005,*)'PML thickness in X, Y, Z directions:',PML_X1,PML_Y1,PML_Z1
ELSE
WRITE(10005,*)'Boundary condition: original Dirichlet (zero field) boundary'
ENDIF
WRITE(10005,*)
WRITE(10005,*)'Anomalous body parameters'
WRITE(10005,*)'NO X1 X2 Y1 Y2 Z1 Z2 CONDUCTIVITY' WRITE(10005,*)'NO X1 X2 Y1 Y2 Z1 Z2 CONDUCTIVITY'
DO I=1,SIZE(TAR_X1) DO I=1,SIZE(TAR_X1)
WRITE(10005,'(I3,6I5,ES15.6)')I,TAR_X1(I),TAR_X2(I),TAR_Y1(I),TAR_Y2(I),TAR_Z1(I),TAR_Z2(I),TAR_CONDUCTIVITY(I) WRITE(10005,'(I3,6I5,ES15.6)')I,TAR_X1(I),TAR_X2(I),TAR_Y1(I),TAR_Y2(I),TAR_Z1(I),TAR_Z2(I),TAR_CONDUCTIVITY(I)
@@ -1,6 +1,6 @@
!Copyright (c) 2013 by tdem.org under guide of Xiu Li(lixiu@chd.edu.cn) !Copyright (c) 2013 by https://git.em3d.cn/ under guide of Xiu Li(lixiu@chd.edu.cn)
!written by Huaifeng Sun(sunhuaifeng@gmail.com) and Xushan Lu(luxushan@gmail.com) !written by Huaifeng Sun(sunhuaifeng@email.sdu.edu.cn) and Xushan Lu(luxushan@gmail.com)
!Code distribution @ tdem.org or sunhuaifeng.com !Code distribution @ https://git.em3d.cn/
!function description !function description
!this suboutine is used to close #5300 file. !this suboutine is used to close #5300 file.
+28 -3
查看文件
@@ -1,12 +1,13 @@
!Copyright (c) 2013 by tdem.org under guide of Xiu Li(lixiu@chd.edu.cn) !Copyright (c) 2013 by https://git.em3d.cn/ under guide of Xiu Li(lixiu@chd.edu.cn)
!written by Huaifeng Sun(sunhuaifeng@gmail.com) and Xushan Lu(luxushan@gmail.com) !written by Huaifeng Sun(sunhuaifeng@email.sdu.edu.cn) and Xushan Lu(luxushan@gmail.com)
!Code distribution @ tdem.org or sunhuaifeng.com !Code distribution @ https://git.em3d.cn/
SUBROUTINE FREE_MEMORY SUBROUTINE FREE_MEMORY
USE CONSTANTPARAMETERS USE CONSTANTPARAMETERS
USE ELECTROMAGNETIC_VARIABLES USE ELECTROMAGNETIC_VARIABLES
USE RES_MODEL_PARAMETER USE RES_MODEL_PARAMETER
USE TIME_PARAMETER USE TIME_PARAMETER
USE PML_PARAMETER
IMPLICIT NONE IMPLICIT NONE
INTEGER ERR INTEGER ERR
DEALLOCATE(EX, EY, EZ, STAT=ERR) DEALLOCATE(EX, EY, EZ, STAT=ERR)
@@ -15,5 +16,29 @@ SUBROUTINE FREE_MEMORY
DEALLOCATE(CTIME, STAT=ERR) DEALLOCATE(CTIME, STAT=ERR)
DEALLOCATE(DELT, STAT=ERR) DEALLOCATE(DELT, STAT=ERR)
DEALLOCATE(CDELX,CDELY,CDELZ,STAT=ERR) DEALLOCATE(CDELX,CDELY,CDELZ,STAT=ERR)
IF(Logic_PML==1)THEN
DEALLOCATE(psi_Exy_1, psi_Exy_2, psi_Exz_1, psi_Exz_2, &
psi_Eyx_1, psi_Eyx_2, psi_Eyz_1, psi_Eyz_2, &
psi_Ezx_1, psi_Ezx_2, psi_Ezy_1, psi_Ezy_2, &
psi_Hxy_1, psi_Hxy_2, psi_Hxz_1, psi_Hxz_2, &
psi_Hyx_1, psi_Hyx_2, psi_Hyz_1, psi_Hyz_2, &
psi_Hzx_1, psi_Hzx_2, psi_Hzy_1, psi_Hzy_2, &
psi_Hzz_1, psi_Hzz_2, STAT=ERR)
DEALLOCATE(b_e_x1,c_e_x1,alpha_PML_e_x1,sig_PML_e_x1,kappa_PML_e_x1)
DEALLOCATE(b_h_x1,c_h_x1,alpha_PML_h_x1,sig_PML_h_x1,kappa_PML_h_x1)
DEALLOCATE(b_e_x2,c_e_x2,alpha_PML_e_x2,sig_PML_e_x2,kappa_PML_e_x2)
DEALLOCATE(b_h_x2,c_h_x2,alpha_PML_h_x2,sig_PML_h_x2,kappa_PML_h_x2)
DEALLOCATE(b_e_y1,c_e_y1,alpha_PML_e_y1,sig_PML_e_y1,kappa_PML_e_y1)
DEALLOCATE(b_h_y1,c_h_y1,alpha_PML_h_y1,sig_PML_h_y1,kappa_PML_h_y1)
DEALLOCATE(b_e_y2,c_e_y2,alpha_PML_e_y2,sig_PML_e_y2,kappa_PML_e_y2)
DEALLOCATE(b_h_y2,c_h_y2,alpha_PML_h_y2,sig_PML_h_y2,kappa_PML_h_y2)
DEALLOCATE(b_e_z1,c_e_z1,alpha_PML_e_z1,sig_PML_e_z1,kappa_PML_e_z1)
DEALLOCATE(b_h_z1,c_h_z1,alpha_PML_h_z1,sig_PML_h_z1,kappa_PML_h_z1)
DEALLOCATE(b_e_z2,c_e_z2,alpha_PML_e_z2,sig_PML_e_z2,kappa_PML_e_z2)
DEALLOCATE(b_h_z2,c_h_z2,alpha_PML_h_z2,sig_PML_h_z2,kappa_PML_h_z2)
ENDIF
DEALLOCATE(den_ex,den_hx,den_ey,den_hy,den_ez,den_hz)
DEALLOCATE(c_h_zz)
DEALLOCATE(inv_hz_den)
RETURN RETURN
ENDSUBROUTINE FREE_MEMORY ENDSUBROUTINE FREE_MEMORY
+3 -3
查看文件
@@ -1,6 +1,6 @@
!Copyright (c) 2013 by tdem.org under guide of Xiu Li(lixiu@chd.edu.cn) !Copyright (c) 2013 by https://git.em3d.cn/ under guide of Xiu Li(lixiu@chd.edu.cn)
!written by Huaifeng Sun(sunhuaifeng@gmail.com) and Xushan Lu(luxushan@gmail.com) !written by Huaifeng Sun(sunhuaifeng@email.sdu.edu.cn) and Xushan Lu(luxushan@gmail.com)
!Code distribution @ tdem.org or sunhuaifeng.com !Code distribution @ https://git.em3d.cn/
subroutine Get_eps_r subroutine Get_eps_r
use constantparameters use constantparameters
+3 -3
查看文件
@@ -1,6 +1,6 @@
!Copyright (c) 2013 by tdem.org under guide of Xiu Li(lixiu@chd.edu.cn) !Copyright (c) 2013 by https://git.em3d.cn/ under guide of Xiu Li(lixiu@chd.edu.cn)
!written by Huaifeng Sun(sunhuaifeng@gmail.com) and Xushan Lu(luxushan@gmail.com) !written by Huaifeng Sun(sunhuaifeng@email.sdu.edu.cn) and Xushan Lu(luxushan@gmail.com)
!Code distribution @ tdem.org or sunhuaifeng.com !Code distribution @ https://git.em3d.cn/
subroutine Get_mstop subroutine Get_mstop
! if the value of plus is too small, it will cause array bounds exceeded because the array bonds of Mstop and Mstart is set to 10000. ! if the value of plus is too small, it will cause array bounds exceeded because the array bonds of Mstop and Mstart is set to 10000.
+148
查看文件
@@ -0,0 +1,148 @@
!Copyright (c) 2013 by https://git.em3d.cn/ under guide of Xiu Li(lixiu@chd.edu.cn)
!written by Huaifeng Sun(sunhuaifeng@email.sdu.edu.cn) and Xushan Lu(luxushan@gmail.com)
!Code distribution @ https://git.em3d.cn/
subroutine Get_pml_parameters
use constantparameters
USE PML_PARAMETER
implicit none
integer i,j,k,II,JJ,KK
DO i = 1,PML_X1
sig_PML_e_x1(i) = sig_x_max * ( (PML_X1 - i) / (PML_X1 - 1.0) )**ma
alpha_PML_e_x1(i) = alpha_x_max*((i-1.0)/(PML_X1-1.0))**mb
kappa_PML_e_x1(i) = 1.0+(kappa_x_max-1.0)*((PML_X1 - i) / (PML_X1 - 1.0))**ma
ENDDO
DO i = 1,PML_X1-1
sig_PML_h_x1(i) = sig_x_max * ( (PML_X1 - i - 0.5)/(PML_X1-1.0))**ma
alpha_PML_h_x1(i) = alpha_x_max*((i-0.5)/(PML_X1-1.0))**mb
kappa_PML_h_x1(i) = 1.0+(kappa_x_max-1.0)*((PML_X1 - i - 0.5) / (PML_X1 - 1.0))**ma
ENDDO
DO i = 1,PML_X2
sig_PML_e_x2(i) = sig_x_max * ( (PML_X2 - i) / (PML_X2 - 1.0) )**ma
alpha_PML_e_x2(i) = alpha_x_max*((i-1.0)/(PML_X2-1.0))**mb
kappa_PML_e_x2(i) = 1.0+(kappa_x_max-1.0)*((PML_X2 - i) / (PML_X2 - 1.0))**ma
ENDDO
DO i = 1,PML_X2-1
sig_PML_h_x2(i) = sig_x_max * ( (PML_X2 - i - 0.5)/(PML_X2-1.0))**ma
alpha_PML_h_x2(i) = alpha_x_max*((i-0.5)/(PML_X2-1.0))**mb
kappa_PML_h_x2(i) = 1.0+(kappa_x_max-1.0)*((PML_X2 - i - 0.5) / (PML_X2 - 1.0))**ma
ENDDO
!*************************************************************************************************
!y方向pml参数的求解
DO j = 1,PML_Y1
sig_PML_e_y1(j) = sig_y_max * ( (PML_Y1 - j ) / (PML_Y1 - 1.0) )**ma
alpha_PML_e_y1(j) = alpha_y_max*((j-1)/(PML_Y1-1.0))**mb
kappa_PML_e_y1(j) = 1.0+(kappa_y_max-1.0)*((PML_Y1 - j) / (PML_Y1 - 1.0))**ma
ENDDO
DO j = 1,PML_Y1-1
sig_PML_h_y1(j) = sig_y_max * ( (PML_Y1 - j - 0.5)/(PML_Y1-1.0))**ma
alpha_PML_h_y1(j) = alpha_y_max*((j-0.5)/(PML_Y1-1.0))**mb
kappa_PML_h_y1(j) = 1.0+(kappa_y_max-1.0)*((PML_Y1 - j - 0.5) / (PML_Y1 - 1.0))**ma
ENDDO
DO j = 1,PML_Y2
sig_PML_e_y2(j) = sig_y_max * ( (PML_Y2 - j ) / (PML_Y2 - 1.0) )**ma
alpha_PML_e_y2(j) = alpha_y_max*((j-1)/(PML_Y2-1.0))**mb
kappa_PML_e_y2(j) = 1.0+(kappa_y_max-1.0)*((PML_Y2 - j) / (PML_Y2 - 1.0))**ma
ENDDO
DO j = 1,PML_Y2-1
sig_PML_h_y2(j) = sig_y_max * ( (PML_Y2 - j - 0.5)/(PML_Y2-1.0))**ma
alpha_PML_h_y2(j) = alpha_y_max*((j-0.5)/(PML_Y2-1.0))**mb
kappa_PML_h_y2(j) = 1.0+(kappa_y_max-1.0)*((PML_Y2 - j - 0.5) / (PML_Y2 - 1.0))**ma
ENDDO
!*************************************************************************************************
!Z方向pml参数的求解
DO k = 1,PML_Z1
sig_PML_e_z1(k) = sig_z_max * ( (PML_Z1 - k ) / (PML_Z1 - 1.0) )**ma
alpha_PML_e_z1(k) = alpha_z_max*((k-1)/(PML_Z1-1.0))**mb
kappa_PML_e_z1(k) = 1.0+(kappa_z_max-1.0)*((PML_Z1 - k) / (PML_Z1 - 1.0))**ma
ENDDO
DO k = 1,PML_Z1-1
sig_PML_h_z1(k) = sig_z_max * ( (PML_Z1 - k - 0.5)/(PML_Z1-1.0))**ma
alpha_PML_h_z1(k) = alpha_z_max*((k-0.5)/(PML_Z1-1.0))**mb
kappa_PML_h_z1(k) = 1.0+(kappa_z_max-1.0)*((PML_Z1 - k - 0.5) / (PML_Z1 - 1.0))**ma
ENDDO
DO k = 1,PML_Z2
sig_PML_e_z2(k) = sig_z_max * ( (PML_Z2 - k ) / (PML_Z2 - 1.0) )**ma
alpha_PML_e_z2(k) = alpha_z_max*((k-1)/(PML_Z2-1.0))**mb
kappa_PML_e_z2(k) = 1.0+(kappa_z_max-1.0)*((PML_Z2 - k) / (PML_Z2 - 1.0))**ma
ENDDO
DO k = 1,PML_Z2-1
sig_PML_h_z2(k) = sig_z_max * ( (PML_Z2 - k - 0.5)/(PML_Z2-1.0))**ma
alpha_PML_h_z2(k) = alpha_z_max*((k-0.5)/(PML_Z2-1.0))**mb
kappa_PML_h_z2(k) = 1.0+(kappa_z_max-1.0)*((PML_Z2 - k - 0.5) / (PML_Z2 - 1.0))**ma
ENDDO
!求解den
!x方向
ii =PML_X2
DO i = 1,NX
if (i <= PML_X1) then
den_ex(i) = 1.0/kappa_PML_e_x1(i)
elseif (i >= NX+2-PML_X2) then
den_ex(i) = 1.0/kappa_PML_e_x2(ii)
ii = ii-1
else
den_ex(i) = 1.0
endif
ENDDO
ii =PML_X2-1
DO i = 1,NX
if (i <= PML_X1-1) then
den_hx(i) = 1.0/kappa_PML_h_x1(i)
elseif (i >= NX+2-PML_X2) then
den_hx(i) = 1.0/kappa_PML_h_x2(ii)
ii = ii-1
else
den_hx(i) = 1.0
endif
ENDDO
!y方向
jj = PML_Y2
DO j = 1,NY
if (j <= PML_Y1) then
den_ey(j) = 1.0/kappa_PML_e_y1(j)
elseif (j >= NY+2-PML_Y2) then
den_ey(j) = 1.0/kappa_PML_e_y2(jj)
jj = jj-1
else
den_ey(j) = 1.0
endif
ENDDO
jj =PML_Y2-1
DO j = 1,NY
if (j <= PML_Y1-1) then
den_hy(j) = 1.0/kappa_PML_h_y1(j)
elseif (j >= NY+2-PML_Y2) then
den_hy(j) = 1.0/kappa_PML_h_y2(jj)
jj = jj-1
else
den_hy(j) = 1.0
endif
ENDDO
!z方向
kk =PML_Z2
DO k = 1,NZ
if (k <= PML_Z1) then
den_ez(k) = 1.0/kappa_PML_e_z1(k)
elseif (k >= NZ+2-PML_Z2) then
den_ez(k) = 1.0/kappa_PML_e_z2(kk)
kk = kk - 1
else
den_ez(k) = 1.0
endif
ENDDO
kk =PML_Z2-1
DO k = 1,NZ
if (k <= PML_Z1-1) then
den_hz(k) = 1.0/kappa_PML_h_z1(k)
elseif (k >= NZ+2-PML_Z2) then
den_hz(k) = 1.0/kappa_PML_h_z2(kk)
kk = kk - 1
else
den_hz(k) = 1.0
endif
ENDDO
end subroutine Get_pml_parameters
+40 -30
查看文件
@@ -1,35 +1,45 @@
!Copyright (c) 2013 by tdem.org under guide of Xiu Li(lixiu@chd.edu.cn) !Copyright (c) 2013 by https://git.em3d.cn/ under guide of Xiu Li(lixiu@chd.edu.cn)
!written by Huaifeng Sun(sunhuaifeng@gmail.com) and Xushan Lu(luxushan@gmail.com) !written by Huaifeng Sun(sunhuaifeng@email.sdu.edu.cn) and Xushan Lu(luxushan@gmail.com)
!Code distribution @ tdem.org or sunhuaifeng.com !Code distribution @ https://git.em3d.cn/
!SUBROUTINE GET_SYS_TIMEDATA(OUTPUT)
! ! The original subroutien written by Huaifeng Sun can not work in PGI compiler, so I change it into what it looks like here.
! IMPLICIT NONE
! CHARACTER*4 TEMP1,TEMP2,TEMP3,TEMP4,TEMP5,TEMP6
! CHARACTER*20 OUTPUT
! integer*4 FortranDate(3),FortranTime(3)
! INTEGER(4) TMPDAY, TMPMONTH, TMPYEAR
! INTEGER(4) TMPHOUR, TMPMINUTE, TMPSECOND
! CALL idate(FortranDate)
! CALL itime(FortranTime)
! tmpday=FortranDate(2); tmpmonth=FortranDate(1); tmpyear=FortranDate(3)
! tmphour=FortranTime(1); tmpminute=FortranTime(2); tmpsecond=FortranTime(3)
! WRITE(TEMP1,'(I4)')TMPYEAR
! WRITE(TEMP2,'(I2)')TMPMONTH
! WRITE(TEMP3,'(I2)')TMPDAY
! WRITE(TEMP4,'(I4)')TMPHOUR
! WRITE(TEMP5,'(I4)')TMPMINUTE
! WRITE(TEMP6,'(I4)')TMPSECOND
! OUTPUT=TRIM(ADJUSTL(TEMP1))//'-'//TRIM(ADJUSTL(TEMP2))//'-'//TRIM(ADJUSTL(TEMP3))//' '//TRIM(ADJUSTL(TEMP4))//':'//TRIM(ADJUSTL(TEMP5))//':'//TRIM(ADJUSTL(TEMP6))
! OUTPUT=TRIM(ADJUSTL(OUTPUT))
! RETURN
! ENDSUBROUTINE GET_SYS_TIMEDATA
SUBROUTINE GET_SYS_TIMEDATA(OUTPUT) SUBROUTINE GET_SYS_TIMEDATA(OUTPUT)
! The original subroutien written by Huaifeng Sun can not work in PGI compiler, so I change it into what it looks like here.
IMPLICIT NONE IMPLICIT NONE
CHARACTER*4 TEMP1,TEMP2,TEMP3,TEMP4,TEMP5,TEMP6
CHARACTER*20 OUTPUT
integer*4 FortranDate(3),FortranTime(3)
INTEGER(4) TMPDAY, TMPMONTH, TMPYEAR
INTEGER(4) TMPHOUR, TMPMINUTE, TMPSECOND
!the following code is optimized by hfsun@2017-5-29 to modify an warning on the use of idate CHARACTER(LEN=20) :: OUTPUT
!I also replace the function idate with idate4 to get a 4 digital year. CHARACTER(LEN=8) :: DATE
!But I received errors when use CALL idate4(FortranDate), so I use the temp solution idate4(tmpmonth,tmpday,tmpyear) CHARACTER(LEN=10) :: TIME
!CALL idate4(FortranDate) CALL DATE_AND_TIME(DATE,TIME)
CALL itime(FortranTime)
!tmpday=FortranDate(2); tmpmonth=FortranDate(1); tmpyear=FortranDate(3) OUTPUT = DATE(1:4)//'-'// &
tmphour=FortranTime(1); tmpminute=FortranTime(2); tmpsecond=FortranTime(3) DATE(5:6)//'-'// &
CALL idate4(tmpmonth,tmpday,tmpyear) DATE(7:8)//' '// &
!CALL itime(tmphour,tmpminute,tmpsecond) TIME(1:2)//':'// &
!tmpday=FortranDate(2); tmpmonth=FortranDate(1); tmpyear=FortranDate(3) TIME(3:4)//':'// &
!tmphour=FortranTime(1); tmpminute=FortranTime(2); tmpsecond=FortranTime(3) TIME(5:6)
WRITE(TEMP1,'(I4)')TMPYEAR
WRITE(TEMP2,'(I2)')TMPMONTH END SUBROUTINE GET_SYS_TIMEDATA
WRITE(TEMP3,'(I2)')TMPDAY
WRITE(TEMP4,'(I4)')TMPHOUR
WRITE(TEMP5,'(I4)')TMPMINUTE
WRITE(TEMP6,'(I4)')TMPSECOND
OUTPUT=TRIM(ADJUSTL(TEMP1))//'-'//TRIM(ADJUSTL(TEMP2))//'-'//TRIM(ADJUSTL(TEMP3))//' '//TRIM(ADJUSTL(TEMP4))//':'//TRIM(ADJUSTL(TEMP5))//':'//TRIM(ADJUSTL(TEMP6))
OUTPUT=TRIM(ADJUSTL(OUTPUT))
RETURN
ENDSUBROUTINE GET_SYS_TIMEDATA
+92
查看文件
@@ -0,0 +1,92 @@
!Copyright (c) 2013 by https://git.em3d.cn/ under guide of Xiu Li(lixiu@chd.edu.cn)
!written by Huaifeng Sun(sunhuaifeng@email.sdu.edu.cn) and Xushan Lu(luxushan@gmail.com)
!Code distribution @ https://git.em3d.cn/
SUBROUTINE GET_COORDINATES
!> @brief This subroutine calculates the coordinates of each grid node in the 3D domain,
!>including the Yee grid nodes and the source-centered coordinate system.
USE CONSTANTPARAMETERS
IMPLICIT NONE
INTEGER(KIND=4) :: ii,jj,kk
!================================================
Coordiz(NZS) = -Cdelz(NZS)/2
!>In the Coordiz coordinate system, the coordinates are on the grid edge
!! Coordinates are defined at cell centers relative to source location
do kk=NZS-1,1,-1
Coordiz(kk)=Coordiz(kk+1)-(Cdelz(kk+1)+Cdelz(kk))/2
end do
do kk=NZS+1,NZ,1
Coordiz(kk)=Coordiz(kk-1)+(Cdelz(kk-1)+Cdelz(kk))/2
end do
!> Initialize X and Y coordinates based on source grid length being odd or even
IF(Logi_Sourcelenth) THEN
!> For odd source grid length, origin is at the grid center
Coordix(NXS)=0
do ii=NXS-1,1,-1
Coordix(ii)=Coordix(ii+1)-(Cdelx(ii)+Cdelx(ii+1))/2
end do
do ii=NXS+1,NX,1
Coordix(ii)=Coordix(ii-1)+(Cdelx(ii-1)+Cdelx(ii))/2
end do
Coordiy(NYS)=0
do jj=NYS-1,1,-1
Coordiy(jj)=Coordiy(jj+1)-(Cdely(jj)+Cdely(jj+1))/2
end do
do jj=NYS+1,NY,1
Coordiy(jj)=Coordiy(jj-1)+(Cdely(jj)+Cdely(jj-1))/2
end do
ELSE
!> For even source grid length, origin spans between two grid centers
Coordix(NXS)=-GridSize/2.0
Coordix(NXS+1)=GridSize/2.0
do ii=NXS-1,1,-1
Coordix(ii)=Coordix(ii+1)-(Cdelx(ii)+Cdelx(ii+1))/2
end do
do ii=NXS+2,nx,1
Coordix(ii)=Coordix(ii-1)+(Cdelx(ii-1)+Cdelx(ii))/2
end do
Coordiy(NYS)=-GridSize/2.0
Coordiy(NYS+1)=GridSize/2.0
do jj=NYS-1,1,-1
Coordiy(jj)=Coordiy(jj+1)-(Cdely(jj)+Cdely(jj+1))/2
end do
do jj=NYS+2,ny,1
Coordiy(jj)=Coordiy(jj-1)+(Cdely(jj)+Cdely(jj-1))/2
end do
ENDIF
!===============================Calculate the Yee node coordinates========================================
!> Allocate and calculate Yee grid node coordinates
ALLOCATE(coordinates_x(NXB),coordinates_y(NYB),coordinates_z(NZB))
DO ii=1,NX
coordinates_x(ii)=Coordix(ii)-Cdelx(ii)/2.0
ENDDO
coordinates_x(NXB)=Coordix(NX)+Cdelx(NX)/2.0
DO jj=1,NY
coordinates_y(jj)=Coordiy(jj)-Cdely(jj)/2.0
ENDDO
coordinates_y(NYB)=Coordiy(NY)+Cdely(NY)/2.0
DO kk=1,NZ
coordinates_z(kk)=Coordiz(kk)-Cdelz(kk)/2
ENDDO
coordinates_z(NZB)=coordinates_z(NZ)+Cdelz(NZ)
!---------------------Create a global coordinate system about HZ-----------------------!
! The HZ grid planes are located at the Yee nodes, whose source-centered
! coordinates are stored in coordinates_x/y/z (origin at the loop source /
! ground surface). The receiver coordinates read from input.dat are also
! source-centered, so Coord_HZ_* must use the SAME origin, otherwise the
! receiver-to-grid search in Get_Receiver_Gridlabel yields index 0 (or an
! uninitialized value) and the observer interpolation in Iteration.f90 reads
! out-of-bounds EX/EY/CDELX/CDELY entries -> NaN in the dBzdt output files.
ALLOCATE(Coord_HZ_X(Nx),Coord_HZ_Y(NY),Coord_HZ_Z(NZB))
Coord_HZ_X(1:NX) = coordinates_x(1:NX) !Record the HZ coordinate information in the x direction.
Coord_HZ_Y(1:NY) = coordinates_y(1:NY) !Record the HZ coordinate information in the y direction.
Coord_HZ_Z(1:NZB) = coordinates_z(1:NZB) !Record the HZ coordinate information in the z direction.
END SUBROUTINE
+146 -84
查看文件
@@ -1,6 +1,6 @@
!Copyright (c) 2013 by tdem.org under guide of Xiu Li(lixiu@chd.edu.cn) !Copyright (c) 2013 by https://git.em3d.cn/ under guide of Xiu Li(lixiu@chd.edu.cn)
!written by Huaifeng Sun(sunhuaifeng@gmail.com) and Xushan Lu(luxushan@gmail.com) !written by Huaifeng Sun(sunhuaifeng@email.sdu.edu.cn) and Xushan Lu(luxushan@gmail.com)
!Code distribution @ tdem.org or sunhuaifeng.com !Code distribution @ https://git.em3d.cn/
SUBROUTINE GET_NON_UNIFORMGRID SUBROUTINE GET_NON_UNIFORMGRID
USE CONSTANTPARAMETERS USE CONSTANTPARAMETERS
@@ -9,154 +9,216 @@ SUBROUTINE GET_NON_UNIFORMGRID
INTEGER II INTEGER II
INTEGER MID_P,LEFT_P,RIGHT_P,UP_P,DOWN_P INTEGER MID_P,LEFT_P,RIGHT_P,UP_P,DOWN_P
REAL(KIND=8) CDELX_LENGTH,CDELY_LENGTH,CDELZ_LENGTH REAL(KIND=8) CDELX_LENGTH,CDELY_LENGTH,CDELZ_LENGTH
WRITE(*,*)'Non-uniform grid meshing: core cells = ',GridSize,' m, expansion ratio SCALE_PAR = ',SCALE_PAR
! -------------------------mesh-z-------------------------------------------! ! -------------------------mesh-z-------------------------------------------!
Coordiz3(nzs)=-GridSize; Coordiz3(nzs+1)=0 GridSize_MAX=GridSize*MAX_RATIO
do ii=nzs-20,nzs+20,1 do ii=nzs-UniGridNumZ1,nzs+UniGridNumZ2,1
Cdelz(ii)=GridSize Cdelz(ii)=GridSize
end do !Uniform mesh in an area equal to source length end do !Uniform mesh in an area equal to source length
do ii=nzs-21,1,-1 do ii=nzs-UniGridNumZ1-1,1,-1
Cdelz(ii)=Cdelz(ii+1)*scale_par Cdelz(ii)=Cdelz(ii+1)*scale_par
if(Cdelz(ii).gt.200)then if(Cdelz(ii).gt.GridSize_MAX)then
Cdelz(ii)=200 Cdelz(ii)=GridSize_MAX
end if end if
end do !Ununiform mesh in the air. end do !Ununiform mesh in the air.
do ii=nzs+21,nz,1 do ii=nzs+UniGridNumZ2+1,nz,1
Cdelz(ii)=Cdelz(ii-1)*scale_par Cdelz(ii)=Cdelz(ii-1)*scale_par
if(Cdelz(ii).gt.200)then if(Cdelz(ii).gt.GridSize_MAX)then
Cdelz(ii)=200 Cdelz(ii)=GridSize_MAX
end if end if
end do !Ununiform mesh underground end do !Ununiform mesh underground
do ii=nzs-1,1,-1
Coordiz3(ii)=Coordiz3(ii+1)-Cdelz(ii)
end do
do ii=nzs+2,nz,1
Coordiz3(ii)=Coordiz3(ii-1)+Cdelz(ii)
end do !Record the coordination information of each grid.
! ----------------------------end of mesh------------------------------------! ! ----------------------------end of mesh------------------------------------!
! -------------------------------mesh x----------------------------------------! ! -------------------------------mesh x----------------------------------------!
if(SourceLength/GridSize.gt.51)then IF(Logi_Sourcelenth) THEN !The number of grids occupied by the source is odd
do ii=nxs-(SourceLength/GridSize-1)/2,nxs+(SourceLength/GridSize-1)/2,1 if(SourceGridNum.gt.51)then
do ii=nxs-(SourceGridNum-1)/2,nxs+(SourceGridNum-1)/2,1
Cdelx(ii)=GridSize Cdelx(ii)=GridSize
end do end do
do ii=nxs-(SourceLength/GridSize-1)/2-1,1,-1 do ii=nxs-(SourceGridNum-1)/2-1,1,-1
Cdelx(ii)=Cdelx(ii+1)*scale_par Cdelx(ii)=Cdelx(ii+1)*scale_par
if(Cdelx(ii).gt.200)then if(Cdelx(ii).gt.GridSize_MAX)then
Cdelx(ii)=200 Cdelx(ii)=GridSize_MAX
end if end if
end do end do
do ii=nxs+(SourceLength/GridSize-1)/2+1,nx,1 do ii=nxs+(SourceGridNum-1)/2+1,nx,1
Cdelx(ii)=Cdelx(ii-1)*scale_par Cdelx(ii)=Cdelx(ii-1)*scale_par
if(Cdelx(ii).gt.200)then if(Cdelx(ii).gt.GridSize_MAX)then
Cdelx(ii)=200 Cdelx(ii)=GridSize_MAX
end if end if
end do end do
else else
do ii=nxs-50,nxs+50,1 do ii=nxs-UniGridNumX1,nxs+UniGridNumX2,1
Cdelx(ii)=GridSize Cdelx(ii)=GridSize
end do end do
do ii=nxs-51,1,-1 do ii=nxs-UniGridNumX1-1,1,-1
Cdelx(ii)=Cdelx(ii+1)*scale_par Cdelx(ii)=Cdelx(ii+1)*scale_par
if(Cdelx(ii).gt.200)then if(Cdelx(ii).gt.GridSize_MAX)then
Cdelx(ii)=200 Cdelx(ii)=GridSize_MAX
end if end if
end do end do
do ii=nxs+51,nx,1 do ii=nxs+UniGridNumX2+1,nx,1
Cdelx(ii)=Cdelx(ii-1)*scale_par Cdelx(ii)=Cdelx(ii-1)*scale_par
if(Cdelx(ii).gt.200)then if(Cdelx(ii).gt.GridSize_MAX)then
Cdelx(ii)=200 Cdelx(ii)=GridSize_MAX
endif endif
end do end do
ENDIF
ELSE !The number of grids occupied by the source is even
if(SourceGridNum.gt.51)then
do ii=nxs-(SourceGridNum-1)/2,nxs+1+(SourceGridNum-1)/2,1
Cdelx(ii)=GridSize
end do
do ii=nxs-(SourceGridNum-1)/2-1,1,-1
Cdelx(ii)=Cdelx(ii+1)*scale_par
if(Cdelx(ii).gt.GridSize_MAX)then
Cdelx(ii)=GridSize_MAX
end if end if
Coordix3(nxs)=0
do ii=nxs-1,1,-1
Coordix3(ii)=Coordix3(ii+1)-(Cdelx(ii)+Cdelx(ii+1))/2
end do end do
do ii=nxs+1,nx,1 do ii=nxs+(SourceGridNum-1)/2+2,nx,1
Coordix3(ii)=Coordix3(ii-1)+(Cdelx(ii-1)+Cdelx(ii))/2 Cdelx(ii)=Cdelx(ii-1)*scale_par
if(Cdelx(ii).gt.GridSize_MAX)then
Cdelx(ii)=GridSize_MAX
end if
end do end do
else
do ii=nxs-UniGridNumX1-1,nxs+UniGridNumX2,1
Cdelx(ii)=GridSize
end do
do ii=nxs-UniGridNumX1,1,-1
Cdelx(ii)=Cdelx(ii+1)*scale_par
if(Cdelx(ii).gt.GridSize_MAX)then
Cdelx(ii)=GridSize_MAX
end if
end do
do ii=nxs+UniGridNumX2+1,nx,1
Cdelx(ii)=Cdelx(ii-1)*scale_par
if(Cdelx(ii).gt.GridSize_MAX)then
Cdelx(ii)=GridSize_MAX
endif
end do
ENDIF
ENDIF
! -----------------------------end of mesh------------------------------------! ! -----------------------------end of mesh------------------------------------!
! --------------------------------mesh y----------------------------------------! ! --------------------------------mesh y----------------------------------------!
if(SourceLength/GridSize.gt.51)then IF(Logi_Sourcelenth) THEN !The number of grids occupied by the source is odd
do ii=nys-(SourceLength/GridSize-1)/2,nys+(SourceLength/GridSize-1)/2,1 IF(SourceGridNum.gt.51)then
do ii=nys-(SourceGridNum-1)/2,nys+(SourceGridNum-1)/2,1
Cdely(ii)=GridSize Cdely(ii)=GridSize
enddo enddo
do ii=nys-(SourceLength/GridSize-1)/2-1,1,-1 do ii=nys-(SourceGridNum-1)/2-1,1,-1
Cdely(ii)=Cdely(ii+1)*scale_par Cdely(ii)=Cdely(ii+1)*scale_par
if(Cdely(ii).gt.200)then if(Cdely(ii).gt.GridSize_MAX)then
Cdely(ii)=200 Cdely(ii)=GridSize_MAX
end if end if
end do end do
do ii=nys+(SourceLength/GridSize-1)/2+1,ny,1 do ii=nys+(SourceGridNum-1)/2+1,ny,1
Cdely(ii)=Cdely(ii-1)*scale_par Cdely(ii)=Cdely(ii-1)*scale_par
if(Cdely(ii).gt.200)then if(Cdely(ii).gt.GridSize_MAX)then
Cdely(ii)=200 Cdely(ii)=GridSize_MAX
endif endif
end do end do
else else
do ii=nys-25,nys+25,1 do ii=nys-UniGridNumY1,nys+UniGridNumY2,1
Cdely(ii)=GridSize Cdely(ii)=GridSize
end do end do
do ii=nys-26,1,-1 do ii=nys-UniGridNumY1-1,1,-1
Cdely(ii)=Cdely(ii+1)*scale_par Cdely(ii)=Cdely(ii+1)*scale_par
if(Cdely(ii).gt.200)then if(Cdely(ii).gt.GridSize_MAX)then
Cdely(ii)=200 Cdely(ii)=GridSize_MAX
end if end if
end do end do
do ii=nys+26,ny,1 do ii=nys+UniGridNumY2+1,ny,1
Cdely(ii)=Cdely(ii-1)*scale_par Cdely(ii)=Cdely(ii-1)*scale_par
if(Cdely(ii).gt.200)then if(Cdely(ii).gt.GridSize_MAX)then
Cdely(ii)=200 Cdely(ii)=GridSize_MAX
end if end if
end do end do
end if end if
Coordiy3(nys)=-(GridSize/2); Coordiy3(nys+1)=GridSize/2 ELSE !The number of grids occupied by the source is even
do ii=nys-1,1,-1 IF(SourceGridNum.gt.51)then
Coordiy3(ii)=Coordiy3(ii+1)-(Cdely(ii)+Cdely(ii+1))/2 do ii=nys-(SourceGridNum-1)/2,nys+1+(SourceGridNum-1)/2,1
Cdely(ii)=GridSize
enddo
do ii=nys-(SourceGridNum-1)/2-1,1,-1
Cdely(ii)=Cdely(ii+1)*scale_par
if(Cdely(ii).gt.GridSize_MAX)then
Cdely(ii)=GridSize_MAX
end if
end do end do
do ii=nys+1,ny,1 do ii=nys+(SourceGridNum-1)/2+2,ny,1
Coordiy3(ii)=Coordiy3(ii-1)+(Cdely(ii)+Cdely(ii-1))/2 Cdely(ii)=Cdely(ii-1)*scale_par
if(Cdely(ii).gt.GridSize_MAX)then
Cdely(ii)=GridSize_MAX
endif
end do end do
else
do ii=nys-UniGridNumY1-1,nys+UniGridNumY2,1
Cdely(ii)=GridSize
end do
do ii=nys-UniGridNumY1,1,-1
Cdely(ii)=Cdely(ii+1)*scale_par
if(Cdely(ii).gt.GridSize_MAX)then
Cdely(ii)=GridSize_MAX
end if
end do
do ii=nys+UniGridNumY2+1,ny,1
Cdely(ii)=Cdely(ii-1)*scale_par
if(Cdely(ii).gt.GridSize_MAX)then
Cdely(ii)=GridSize_MAX
end if
end do
end if
ENDIF
! ------------------------------end of mesh-----------------------------------! ! ------------------------------end of mesh-----------------------------------!
! ------------------------------record coordinate----------------------------!
open(10006,file='HzCoordinate.dat') !You can find the coordination information of each grid in this file.
write(10006,*)nx,ny,nz
write(10006,*)'!---------------------------------X part--------------------------------!'
do ii=1,nx,1
write(10006,*)ii,Coordix3(ii)
end do
write(10006,*)'!----------------------------end of X part----------------------------!'
write(10006,*)'!---------------------------------Y part---------------------------------!'
do ii=1,ny,1
write(10006,*)ii,Coordiy3(ii)
end do
write(10006,*)'!----------------------------end of Y part----------------------------!'
write(10006,*)'!---------------------------------Z part---------------------------------!'
do ii=1,nz,1
write(10006,*)ii,Coordiz3(ii)
end do
write(10006,*)'!----------------------------end of Z part----------------------------!'
close(10006)
!----------------------------end of recording-------------------------------!
CDELX_LENGTH=SUM(CDELX) CDELX_LENGTH=SUM(CDELX)
CDELY_LENGTH=SUM(CDELY) CDELY_LENGTH=SUM(CDELY)
CDELZ_LENGTH=SUM(CDELZ) CDELZ_LENGTH=SUM(CDELZ)
WRITE(10005,*)'设置的模型尺寸为:' WRITE(10005,*)'õģͳߴΪ'
WRITE(10005,*)'SUM_X=',CDELX_LENGTH WRITE(10005,*)'SUM_X=',CDELX_LENGTH
WRITE(10005,*)'SUM_Y=',CDELY_LENGTH WRITE(10005,*)'SUM_Y=',CDELY_LENGTH
WRITE(10005,*)'SUM_Z=',CDELZ_LENGTH WRITE(10005,*)'SUM_Z=',CDELZ_LENGTH
WRITE(10005,*)'相邻网格放大系数=',SCALE_PAR WRITE(10005,*)'Ŵϵ=',SCALE_PAR
WRITE(10005,*)'最大网格尺寸与最小网格尺寸之比<=',MAX_RATIO WRITE(10005,*)'ߴСߴ֮<=',MAX_RATIO
WRITE(10005,*)'X方向的非均匀网格尺寸为:' WRITE(10005,*)'XķǾߴΪ'
WRITE(10005,'(5F18.8)')CDELX WRITE(10005,'(5F18.8)')CDELX
WRITE(10005,*)'Y方向的非均匀网格尺寸为:' WRITE(10005,*)'YķǾߴΪ'
WRITE(10005,'(5F18.8)')CDELY WRITE(10005,'(5F18.8)')CDELY
WRITE(10005,*)'Z方向的非均匀网格尺寸为:' WRITE(10005,*)'ZķǾߴΪ'
WRITE(10005,'(5F18.8)')CDELZ WRITE(10005,'(5F18.8)')CDELZ
WRITE(*,*)'Model size:',CDELX_LENGTH,CDELY_LENGTH,CDELZ_LENGTH WRITE(*,*)'Model size:',CDELX_LENGTH,CDELY_LENGTH,CDELZ_LENGTH
ENDSUBROUTINE GET_NON_UNIFORMGRID
!===============================================================================================!
! GET_UNIFORM_GRID: 均匀网格剖分,用于 CPML 吸收边界。
! 参考实现(tem3dfdtd_第二版)中 CPML 采用的是均匀网格(SCALE_PAR=1.0,
! 扩展循环全部注释),因此这里按 Logic_PML 分流:Logic_PML=1 时调用本子程序
! (均匀网格 + CPML),Logic_PML=0 时调用 GET_NON_UNIFORMGRID(非均匀网格 + Dirichlet)。
!===============================================================================================!
SUBROUTINE GET_UNIFORM_GRID
USE CONSTANTPARAMETERS
IMPLICIT NONE
INTEGER II
REAL(KIND=8) CDELX_LENGTH,CDELY_LENGTH,CDELZ_LENGTH
WRITE(*,*)'Uniform grid meshing: all cells = ',GridSize,' m (required by the CPML absorbing boundary)'
! 均匀网格:所有网格尺寸均等于 GridSize
Cdelx=GridSize
Cdely=GridSize
Cdelz=GridSize
CDELX_LENGTH=SUM(CDELX)
CDELY_LENGTH=SUM(CDELY)
CDELZ_LENGTH=SUM(CDELZ)
WRITE(10005,*)'采用均匀网格剖分(配合 CPML 吸收边界):'
WRITE(10005,*)'SUM_X=',CDELX_LENGTH
WRITE(10005,*)'SUM_Y=',CDELY_LENGTH
WRITE(10005,*)'SUM_Z=',CDELZ_LENGTH
WRITE(10005,*)'均匀网格尺寸=',GridSize
WRITE(*,*)'Model size:',CDELX_LENGTH,CDELY_LENGTH,CDELZ_LENGTH
OPEN(400,FILE='CDELX.DAT',STATUS='UNKNOWN') OPEN(400,FILE='CDELX.DAT',STATUS='UNKNOWN')
DO II=1,NX DO II=1,NX
@@ -173,4 +235,4 @@ SUBROUTINE GET_NON_UNIFORMGRID
WRITE(400,'(E13.6)')CDELZ(II) WRITE(400,'(E13.6)')CDELZ(II)
ENDDO ENDDO
CLOSE(400) CLOSE(400)
ENDSUBROUTINE GET_NON_UNIFORMGRID ENDSUBROUTINE GET_UNIFORM_GRID
+134 -57
查看文件
@@ -1,50 +1,60 @@
!Copyright (c) 2013 by tdem.org under guide of Xiu Li(lixiu@chd.edu.cn) !Copyright (c) 2013 by https://git.em3d.cn/ under guide of Xiu Li(lixiu@chd.edu.cn)
!written by Huaifeng Sun(sunhuaifeng@gmail.com) and Xushan Lu(luxushan@gmail.com) !written by Huaifeng Sun(sunhuaifeng@email.sdu.edu.cn) and Xushan Lu(luxushan@gmail.com)
!Code distribution @ tdem.org or sunhuaifeng.com !Code distribution @ https://git.em3d.cn/
SUBROUTINE GETDATA SUBROUTINE GETDATA
USE CONSTANTPARAMETERS USE CONSTANTPARAMETERS
!this line is added by Huaifeng Sun to get the dir 2016-10-30 !this line is added by Huaifeng Sun to get the dir 2016-10-30
USE IFPORT
IMPLICIT NONE IMPLICIT NONE
LOGICAL ALIVE LOGICAL ALIVE
INTEGER TEMP_II,III INTEGER III,JJJ
!this following lines 10-21 are added by Huaifeng Sun to get the dir 2016-10-30 !this following lines 10-21 are added by Huaifeng Sun to get the dir 2016-10-30
CHARACTER(255) dir
CHARACTER(255) InputFileName CHARACTER(255) InputFileName
INTEGER(4) length
length = GETDRIVEDIRQQ(dir) InputFileName='input.dat'
IF (length .GT. 0) THEN
!WRITE (*,*) 'Current directory is: '
!WRITE (*,*) dir
InputFileName=trim(dir)//'//example//input.dat'
ELSE
WRITE (*,*) 'Failed to get current directory'
pause
END IF
!the following inputfilename type are modified by HFSun 2016-10-30
!INQUIRE(FILE='input.dat', EXIST=ALIVE)
INQUIRE(FILE=InputFileName, EXIST=ALIVE) INQUIRE(FILE=InputFileName, EXIST=ALIVE)
IF(.NOT. ALIVE) THEN IF(.NOT. ALIVE) THEN
WRITE(10005,*) "input.dat DOES NOT EXIST." WRITE(10005,*) "input.dat DOES NOT EXIST."
STOP STOP
ELSE ELSE
!OPEN(234,FILE='example/input.dat',STATUS='OLD')
OPEN(234,FILE=InputFileName,STATUS='OLD') OPEN(234,FILE=InputFileName,STATUS='OLD')
READ(234,'(a4)')CAL_TYPE !This is the calculation type, possible values are shown below. READ(234,*)CAL_TYPE !This is the calculation type, possible values are shown below.
IF(CAL_TYPE=='TUNNEL' .OR. CAL_TYPE=='tunnel')THEN ! IF(CAL_TYPE=='TUNNEL' .OR. CAL_TYPE=='tunnel')THEN
WRITE(10005,*)'隧道模型计算开关设置正确!' ! WRITE(10005,*)'The tunnel model calculation switch is set correctly!'
ELSEIF(CAL_TYPE=='SEMI' .OR. CAL_TYPE=='semi')THEN ! ELSEIF(CAL_TYPE=='SEMI' .OR. CAL_TYPE=='semi')THEN
WRITE(10005,*)'SEMI-AIRBORNE计算开关设置正确!' ! WRITE(10005,*)'The SEMI-AIRBORNE compute switch is set correctly!'
ELSEIF(CAL_TYPE=='GROUND' .OR. CAL_TYPE=='ground')THEN IF(CAL_TYPE==1)THEN
WRITE(10005,*)'地面模型计算开关设置正确!' WRITE(10005,*)'The ground model calculation switch is set correctly!'
ELSEIF(CAL_TYPE==2)THEN
WRITE(10005,*)'The SEMI-AIRBORNE compute switch is set correctly!'
! ELSEIF(CAL_TYPE==3)THEN
! WRITE(10005,*)'The tunnel model calculation switch is set correctly!'
ELSE ELSE
WRITE(10005,*)'模型计算开关设置不正确,请确定采用地面模型还是隧道模型!' WRITE(10005,*)'The model calculation switch is not set correctly. Please determine whether to use the ground model or the tunnel model!'
STOP STOP
ENDIF ENDIF
READ(234,*)SourceLength READ(234,*)SourceLength
!The length of source, unit of which is meter, and you are supposed to set SourceLengh/GridSize as an odd number for the consideration of there will exist a central point within the source loop. !The length of source, unit of which is meter, and you are supposed to set SourceLengh/GridSize as an odd number for the consideration of there will exist a central point within the source loop.
READ(234,*)NX,NY,NZ !The value of Nx, Ny and Nz varies from model to model. READ(234,*)NX,NY,NZ !The value of Nx, Ny and Nz varies from model to model.
READ(234,*)Logic_PML !Boundary condition switch: 1=CPML absorbing boundary, 0=original Dirichlet (zero field) boundary on the non-uniform grid
READ(234,*)PML_X,PML_Y,PML_Z !PML thickness in x, y and z directions, only valid when Logic_PML=1
IF(Logic_PML==1)THEN
IF(PML_X<1 .OR. PML_Y<1 .OR. PML_Z<1)THEN
WRITE(10005,*)'Error: PML thickness must be at least 1 when the CPML boundary is enabled!'
WRITE(*,*)'Error: PML thickness must be at least 1 when the CPML boundary is enabled!'
STOP
ENDIF
PML_X1=PML_X; PML_X2=PML_X
PML_Y1=PML_Y; PML_Y2=PML_Y
PML_Z1=PML_Z; PML_Z2=PML_Z
ELSE
PML_X1=0; PML_X2=0
PML_Y1=0; PML_Y2=0
PML_Z1=0; PML_Z2=0
ENDIF
READ(234,*)UniGridNumX1,UniGridNumX2
READ(234,*)UniGridNumY1,UniGridNumY2
READ(234,*)UniGridNumZ1,UniGridNumZ2
READ(234,*)GridSize !Most commonly used value is 10m READ(234,*)GridSize !Most commonly used value is 10m
READ(234,*)BACKGROUND_CONDUCTIVITY !Most commonly used value is 1e-2 READ(234,*)BACKGROUND_CONDUCTIVITY !Most commonly used value is 1e-2
READ(234,*)TEMP_II !It depends on your model, and it should be set to 0 if you are doing homogeneous model calculation. READ(234,*)TEMP_II !It depends on your model, and it should be set to 0 if you are doing homogeneous model calculation.
@@ -68,44 +78,111 @@ SUBROUTINE GETDATA
READ(234,*)RAMP,RAMPSTEP !Most commonly used value is: Ramp=1e-6, Rampstep=1e-9 READ(234,*)RAMP,RAMPSTEP !Most commonly used value is: Ramp=1e-6, Rampstep=1e-9
READ(234,*)TIMESTEP !Most commonly used value is 1e-7 READ(234,*)TIMESTEP !Most commonly used value is 1e-7
READ(234,*)AMP !It denotes the value of amplitude of transmitting source. READ(234,*)AMP !It denotes the value of amplitude of transmitting source.
read(234,*)NumRecHeights !It is determined by your recording configuration READ(234,*)tao_abnormal !The electrical conductivity of the abnormal body
allocate(FlightHeight(NumRecHeights),GridNumHeight(NumRecHeights),Nzs_Air(NumRecHeights)) !read(234,*)NumRecHeights !It is determined by your recording configuration
READ(234,*)(FlightHeight(iii),iii=1,NumRecHeights) !allocate(FlightHeight(NumRecHeights),GridNumHeight(NumRecHeights),Nzs_Air(NumRecHeights))
!READ(234,*)(FlightHeight(iii),iii=1,NumRecHeights)
READ(234,'(a12)')SOURCE_TYPE !Currently the only possible value of Source_type is 'TIXING_UPCOS' READ(234,'(a12)')SOURCE_TYPE !Currently the only possible value of Source_type is 'TIXING_UPCOS'
read(234,'(a2)')RecFlag !Possible values are 'HE' and 'Hz' READ(234,*)Point_Num !It depends on your problem, Number of measured points
READ(234,*)NumRecLines IF(Point_Num>0) THEN
read(234,*)RecPointMin,RecPointMax ALLOCATE(Points_Observer(Point_Num))
NumRecPoints=RecPointMax-RecPointMin+1 DO JJJ=1,Point_Num
IF(NumRecLines .EQ. 0)THEN READ(234,*)Points_Observer(JJJ)%Idx_Num
WRITE(10005,*)'没有设置额外的接收点,程序继续运行!' READ(234,*)Points_Observer(JJJ)%Local_Coord_To_Source%Coord_X,Points_Observer(JJJ)%Local_Coord_To_Source%Coord_Y,&
ELSEIF(NumRecLines .GT. 0)THEN Points_Observer(JJJ)%Local_Coord_To_Source%Coord_Z !What is read here is the coordinates of the observation point with respect to the center of the source, and the positive and negative values are related to the positive direction of the axis
ALLOCATE(RecLine(NumRecLines),RecPoint(NumRecPoints)) ENDDO
ELSE
WRITE(10005,*)'额外接收点设置错误,请参阅输入数据文件格式说明,程序异常终止!'
STOP
ENDIF ENDIF
!read(234,'(a2)')RecFlag !Possible values are 'HE' and 'Hz'
!READ(234,*)NumRecLines
!read(234,*)RecPointMin,RecPointMax
!NumRecPoints=RecPointMax-RecPointMin+1
! IF(NumRecLines .EQ. 0)THEN
! WRITE(10005,*)'No additional receiving points were set, and the program continued to run'
! ELSEIF(NumRecLines .GT. 0)THEN
! ALLOCATE(RecLine(NumRecLines),RecPoint(NumRecPoints))
! ELSE
! WRITE(10005,*)'Extra reception point settings are incorrect. Please refer to the input data file format description. Program terminated abnormally'
! STOP
! ENDIF
CLOSE(234) CLOSE(234)
ENDIF ENDIF
do iii=1,NumRecHeights !>Detect the anomalous body surface mesh file. Two input formats are supported:
GridNumHeight(iii)=FlightHeight(iii)/GridSize !! 1. Complex_anomalous.dat - the original text format used by this program;
end do !! 2. Complex_anomalous.stl - the ASCII STL format (e.g. exported from GiD).
do iii=1,NumRecPoints,1 !! Only one of the two files should exist in the working folder, and the reading
RecPoint(iii)=iii+RecPointMin-1 !! mode is chosen here. The variables filled later (Vert, Triangular_face_element,
end do !! n_point, n_face) keep the same names in both formats.
!计算CONSTANTPARAMETERS中的其他常数 INQUIRE(FILE='Complex_anomalous.dat', EXIST=Logic_AnomalousDat)
INQUIRE(FILE='Complex_anomalous.stl', EXIST=Logic_AnomalousStl)
IF(Logic_AnomalousDat .AND. Logic_AnomalousStl)THEN
WRITE(10005,*)'Both Complex_anomalous.dat and Complex_anomalous.stl exist! The .dat format takes precedence, the .stl file is ignored.'
WRITE(*,*)'Both Complex_anomalous.dat and Complex_anomalous.stl exist! The .dat format takes precedence, the .stl file is ignored.'
ELSEIF(Logic_AnomalousStl)THEN
WRITE(10005,*)'Complex_anomalous.stl found, the anomalous body will be read in STL format.'
WRITE(*,*)'Complex_anomalous.stl found, the anomalous body will be read in STL format.'
ELSEIF(Logic_AnomalousDat)THEN
WRITE(10005,*)'Complex_anomalous.dat found, the anomalous body will be read in the original format.'
WRITE(*,*)'Complex_anomalous.dat found, the anomalous body will be read in the original format.'
ELSE
WRITE(10005,*)'Warning: no anomalous body mesh file (Complex_anomalous.dat / Complex_anomalous.stl) is found! The model is treated as homogeneous.'
WRITE(*,*)'Warning: no anomalous body mesh file (Complex_anomalous.dat / Complex_anomalous.stl) is found! The model is treated as homogeneous.'
ENDIF
!>Detect the terrain surface mesh file. Two input formats are supported:
!! 1. Complex_Terrain.dat - the original text format used by this program;
!! 2. Complex_Terrain.stl - the ASCII STL format (e.g. exported from GiD).
!! Only one of the two files should exist in the working folder, and the reading
!! mode is chosen here. The variables filled later (Node_Label, CoordinatesX/Y/Z,
!! Element_Label, Element_Node1/2/3, n_point, n_face) keep the same names in both formats.
INQUIRE(FILE='Complex_Terrain.dat', EXIST=Logic_TerrainDat)
INQUIRE(FILE='Complex_Terrain.stl', EXIST=Logic_TerrainStl)
IF(Logic_TerrainDat .AND. Logic_TerrainStl)THEN
WRITE(10005,*)'Both Complex_Terrain.dat and Complex_Terrain.stl exist! The .dat format takes precedence, the .stl file is ignored.'
WRITE(*,*)'Both Complex_Terrain.dat and Complex_Terrain.stl exist! The .dat format takes precedence, the .stl file is ignored.'
ELSEIF(Logic_TerrainStl)THEN
WRITE(10005,*)'Complex_Terrain.stl found, the terrain will be read in STL format.'
WRITE(*,*)'Complex_Terrain.stl found, the terrain will be read in STL format.'
ELSEIF(Logic_TerrainDat)THEN
WRITE(10005,*)'Complex_Terrain.dat found, the terrain will be read in the original format.'
WRITE(*,*)'Complex_Terrain.dat found, the terrain will be read in the original format.'
ELSE
WRITE(10005,*)'Warning: no terrain mesh file (Complex_Terrain.dat / Complex_Terrain.stl) is found! The model is treated as without terrain.'
WRITE(*,*)'Warning: no terrain mesh file (Complex_Terrain.dat / Complex_Terrain.stl) is found! The model is treated as without terrain.'
ENDIF
! do iii=1,NumRecHeights
! GridNumHeight(iii)=FlightHeight(iii)/GridSize
! end do
! do iii=1,NumRecPoints,1
! RecPoint(iii)=iii+RecPointMin-1
! end do
!Calculate other constants in CONSTANTPARAMETERS.
NXB=NX+1 NXB=NX+1
NYB=NY+1 NYB=NY+1
NZB=NZ+1 NZB=NZ+1
NXS=NX/2+1
NYS=NY/2+1 SourceGridNum=NINT(SourceLength/GridSize)
IF(ABS(MOD(SourceGridNum,2))==1) THEN
Logi_Sourcelenth=.TRUE. !The number of grids occupied by the source is odd
print*,'The number of grids in the core area is odd'
ELSE
Logi_Sourcelenth=.FALSE. !The number of grids occupied by the source is even
print*,'The number of grids in the core area is even'
ENDIF
IF(Logi_Sourcelenth) THEN
NXS=(NX+1)/2
NYS=(NY+1)/2
NZS=NZ/2 NZS=NZ/2
do iii=1,NumRecHeights ELSE
NZS_AIR(iii)=NZS-GridNumHeight(iii) NXS=NX/2
end do NYS=NY/2
do iii=1,NumRecLines,1 NZS=NZ/2
RecLine(iii)=nxs-(NumRecLines-1)/2+iii-1 ENDIF
end do ! do iii=1,NumRecHeights
!将电流转换成电流密度 ! NZS_AIR(iii)=NZS-GridNumHeight(iii)
! end do
! do iii=1,NumRecLines,1
! RecLine(iii)=nxs-(NumRecLines-1)/2+iii-1
! end do
!Convert current into current density
AMP=AMP/(GridSize*GridSize) AMP=AMP/(GridSize*GridSize)
SourceGridNum=int(SourceLength/GridSize) SourceGridNum=int(SourceLength/GridSize)
ALLOCATE(SOURCE(NSTOP)) ALLOCATE(SOURCE(NSTOP))
+3 -3
查看文件
@@ -1,6 +1,6 @@
!Copyright (c) 2013 by tdem.org under guide of Xiu Li(lixiu@chd.edu.cn) !Copyright (c) 2013 by https://git.em3d.cn/ under guide of Xiu Li(lixiu@chd.edu.cn)
!written by Huaifeng Sun(sunhuaifeng@gmail.com) and Xushan Lu(luxushan@gmail.com) !written by Huaifeng Sun(sunhuaifeng@email.sdu.edu.cn) and Xushan Lu(luxushan@gmail.com)
!Code distribution @ tdem.org or sunhuaifeng.com !Code distribution @ https://git.em3d.cn/
!this subroutine is writen by Huaifeng Sun from May 29, 2017 !this subroutine is writen by Huaifeng Sun from May 29, 2017
subroutine getxmldata subroutine getxmldata
+9 -9
查看文件
@@ -1,6 +1,6 @@
!Copyright (c) 2013 by tdem.org under guide of Xiu Li(lixiu@chd.edu.cn) !Copyright (c) 2013 by https://git.em3d.cn/ under guide of Xiu Li(lixiu@chd.edu.cn)
!written by Huaifeng Sun(sunhuaifeng@gmail.com) and Xushan Lu(luxushan@gmail.com) !written by Huaifeng Sun(sunhuaifeng@email.sdu.edu.cn) and Xushan Lu(luxushan@gmail.com)
!Code distribution @ tdem.org or sunhuaifeng.com !Code distribution @ https://git.em3d.cn/
SUBROUTINE MEMORY_USE_ESTIMATION SUBROUTINE MEMORY_USE_ESTIMATION
!This subroutine is written by Huaifeng Sun, and it has not been modified since the last ice age, so it can not reveal the real consumption of memory now. !This subroutine is written by Huaifeng Sun, and it has not been modified since the last ice age, so it can not reveal the real consumption of memory now.
@@ -11,17 +11,17 @@ SUBROUTINE MEMORY_USE_ESTIMATION
CHARACTER(LEN=40) XSTRING CHARACTER(LEN=40) XSTRING
INTEGER(KIND=1) CONTD INTEGER(KIND=1) CONTD
TUSE=0.0 TUSE=0.0
TUSE=TUSE+NX*NYB*NZB+NXB*NY*NZB+NXB*NYB*NZ !电场E使用内存 TUSE=TUSE+NX*NYB*NZB+NXB*NY*NZB+NXB*NYB*NZ !糡Eʹڴ
TUSE=TUSE+NXB*NY*(NZ+1)+NX*NYB*(NZ+1)+NX*NY*NZB !磁场H使用内存 TUSE=TUSE+NXB*NY*(NZ+1)+NX*NYB*(NZ+1)+NX*NY*NZB !ųHʹڴ
TUSE=TUSE+4*NY*NZB+4*NYB*NZ+NX*4*NZB+NXB*4*NZ+NX*NYB*4+NXB*NY*4 !边界条件使用内存 TUSE=TUSE+4*NY*NZB+4*NYB*NZ+NX*4*NZB+NXB*4*NZ+NX*NYB*4+NXB*NY*4 !߽ʹڴ
TUSE=TUSE+4*NY*NZB+4*NYB*NZ+NX*4*NZB+NXB*4*NZ+NX*NYB*4+NXB*NY*4 !边界条件使用内存 TUSE=TUSE+4*NY*NZB+4*NYB*NZ+NX*4*NZB+NXB*4*NZ+NX*NYB*4+NXB*NY*4 !߽ʹڴ
TUSE=TUSE+NXB*NYB*NZB !模型使用内存 TUSE=TUSE+NXB*NYB*NZB !ģʹڴ
TUSE=TUSE+NSTOP*2 TUSE=TUSE+NSTOP*2
TUSE=TUSE/1024 TUSE=TUSE/1024
TUSE=TUSE/1024 TUSE=TUSE/1024
TUSE=TUSE*16 TUSE=TUSE*16
WRITE (XSTRING,'(I40)') TUSE WRITE (XSTRING,'(I40)') TUSE
XSTRING = 'At least '//TRIM(ADJUSTL(XSTRING))//'M memory is needed!' !拼接为要求的FORMAT格式 XSTRING = 'At least '//TRIM(ADJUSTL(XSTRING))//'M memory is needed!' !ƴΪҪFORMATʽ
XSTRING = TRIM(ADJUSTL(XSTRING)) XSTRING = TRIM(ADJUSTL(XSTRING))
WRITE(*,*)XSTRING WRITE(*,*)XSTRING
RETURN RETURN
+185 -9
查看文件
@@ -1,16 +1,67 @@
!Copyright (c) 2013 by tdem.org under guide of Xiu Li(lixiu@chd.edu.cn) !Copyright (c) 2022 by LEEE under guide of Huaifeng Sun(sunhuaifeng@email.sdu.edu.cn)
!written by Huaifeng Sun(sunhuaifeng@gmail.com) and Xushan Lu(luxushan@gmail.com) !written by Xinyu Li(202335098@mail.sdu.edu.cn) and Qi Zhao(zhaoqi_326326@163.com)
!Code distribution @ tdem.org or sunhuaifeng.com
SUBROUTINE RES_CONFIGURE SUBROUTINE RES_CONFIGURE
!本子程序用于设置模型的电阻率参数 !This subroutine is used to set the resistivity parameters of the model
USE CONSTANTPARAMETERS USE CONSTANTPARAMETERS
USE ELECTROMAGNETIC_VARIABLES USE ELECTROMAGNETIC_VARIABLES
USE RES_MODEL_PARAMETER USE RES_MODEL_PARAMETER
USE TIME_PARAMETER USE TIME_PARAMETER
USE OMP_LIB USE OMP_LIB
USE VTK_Fortran, ONLY: Struct_grid
USE Precision, ONLY : i4k, r8k
IMPLICIT NONE IMPLICIT NONE
INTEGER II,III,i,j,k
INTEGER :: i,ii,j,jj,k,kk,III
REAL(KIND=8) :: TEMP_SIG,DELX1,DELY1,DELZ1
REAL*8 :: D
INTEGER :: IRR_Terrain,IRR_Anomalous
INTEGER(i4k), DIMENSION(3) :: dims
INTEGER :: RANGEX,RANGEXB,RANGEY,RANGEYB,RANGEZ,RANGEZB,RangeStartX,RangeStartY,RangeStartZ
REAL(r8k), DIMENSION(:), ALLOCATABLE :: temp_Coordix, temp_Coordiy, temp_Coordiz
REAL(r8k), DIMENSION(:,:,:), ALLOCATABLE :: CCSIG_temp
REAL*8 :: V0_1,V0_2,V0_3,V1_1,V1_2,V1_3,V2_1,V2_2,V2_3
REAL*8 :: u,w,E
REAL*8 :: dot00, dot01, dot02, dot11, dot12, divisor
TYPE (Struct_grid) :: hexahedron !It is used to write a .vtk file
!>The terrain mesh file can be Complex_Terrain.dat or Complex_Terrain.stl.
!!Which file is used was decided in GETDATA, here only the existence flag is checked.
IF(Logic_TerrainDat .OR. Logic_TerrainStl)THEN
IRR_Terrain=1
ELSE
IRR_Terrain=0
ENDIF
!>The anomalous body mesh file can be Complex_anomalous.dat or Complex_anomalous.stl.
!!Which file is used was decided in GETDATA, here only the existence flag is checked.
IF(Logic_AnomalousDat .OR. Logic_AnomalousStl)THEN
IRR_Anomalous=1
ELSE
IRR_Anomalous=0
ENDIF
!======================================Get the coordinates of all terrain elements=============================================
IF (IRR_Terrain /= 0) then
PRINT*,'Conformal mesh of terrain is complete!'
CALL terrain_conformal
print*,'Conformal mesh of terrain is finished'
DEALLOCATE(orig_z,orig_y,orig_x)
DEALLOCATE(vert0,vert1,vert2,edge1,edge2)
DEALLOCATE(det_z,det_x,det_y)
DEALLOCATE(u_z,u_x,u_y)
DEALLOCATE(v_z,v_x,v_y)
DEALLOCATE(t_z,t_x,t_y)
DEALLOCATE(pvec_z,pvec_y,pvec_x)
DEALLOCATE(tvec_z,tvec_y,tvec_x)
DEALLOCATE(crosspoint_ZZ,crosspoint_XX,crosspoint_YY)
DEALLOCATE(mmz_per,mmx_per,mmy_per)
DEALLOCATE(Face_Triangle_NormVect)
SIGMA_MIN = MIN(MINVAL(CCSIGX),MINVAL(CCSIGY),MINVAL(CCSIGZ))
!=========================================================================================================
ELSE
print*,"*************This calculation does not consider undulating terrain.************"
!> No terrain file found, assign uniform background conductivity and anomalies
DO K=1,NZ DO K=1,NZ
DO J=1,NY DO J=1,NY
DO I=1,NX DO I=1,NX
@@ -18,8 +69,8 @@ SUBROUTINE RES_CONFIGURE
ENDDO ENDDO
ENDDO ENDDO
ENDDO ENDDO
II=SIZE(TAR_X1)
DO III=1,II DO III=1,TEMP_II
DO K=TAR_Z1(III),TAR_Z2(III) DO K=TAR_Z1(III),TAR_Z2(III)
DO J=TAR_Y1(III),TAR_Y2(III) DO J=TAR_Y1(III),TAR_Y2(III)
DO I=TAR_X1(III),TAR_X2(III) DO I=TAR_X1(III),TAR_X2(III)
@@ -28,7 +79,132 @@ SUBROUTINE RES_CONFIGURE
ENDDO ENDDO
ENDDO ENDDO
ENDDO ENDDO
write(*,*)"*********************************"
write(*,*)"The Non-undulating terrain is used"
write(*,*)"*********************************"
SIGMA_MIN=MINVAL(CCSIG) SIGMA_MIN=MINVAL(CCSIG)
!print*,'SIGMA_MIN',SIGMA_MIN
!======================================Transfer the conductivity into all edges=============================================
!>assign conductivity values to all edges
DO I=1,NX
DO J=2,NYB-1
DO K=2,NZB-1
DELY1=(CDELY(J-1)+CDELY(J))/2.0D0
DELZ1=(CDELZ(K-1)+CDELZ(K))/2.0D0
TEMP_SIG=CCSIG(I,J-1,K-1)*CDELY(J-1)*CDELZ(K-1)&
&+CCSIG(I,J-1,K)*CDELY(J-1)*CDELZ(K)&
&+CCSIG(I,J,K-1)*CDELY(J)*CDELZ(K-1)&
&+CCSIG(I,J,K)*CDELY(J)*CDELZ(K)
CCSIGX( I,J,K )=TEMP_SIG/(4.0D0*DELY1*DELZ1)
ENDDO
ENDDO
ENDDO
DO I=2,NXB-1
DO J=1,NY
DO K=2,NZB-1
DELX1=(CDELX(I-1)+CDELX(I))/2.0D0
DELZ1=(CDELZ(K-1)+CDELZ(K))/2.0D0
TEMP_SIG=CCSIG(I-1,J,K-1)*CDELX(I-1)*CDELZ(K-1)&
&+CCSIG(I-1,J,K)*CDELX(I-1)*CDELZ(K)&
&+CCSIG(I,J,K-1)*CDELX(I)*CDELZ(K-1)&
&+CCSIG(I,J,K)*CDELX(I)*CDELZ(K)
CCSIGY( I,J,K )=TEMP_SIG/(4.0D0*DELX1*DELZ1)
ENDDO
ENDDO
ENDDO
DO J=2,NYB-1
DO I=2,NXB-1
DO K=1,NZ
DELX1=(CDELX(I-1)+CDELX(I))/2.0D0
DELY1=(CDELY(J-1)+CDELY(J))/2.0D0
TEMP_SIG=CCSIG(I-1,J-1,K)*CDELX(I-1)*CDELY(J-1)&
&+CCSIG(I-1,J,K)*CDELX(I-1)*CDELY(J)&
&+CCSIG(I,J-1,K)*CDELX(I)*CDELY(J-1)&
&+CCSIG(I,J,K)*CDELX(I)*CDELY(J)
CCSIGZ( I,J,K )=TEMP_SIG/(4.0D0*DELX1*DELY1)
ENDDO
ENDDO
ENDDO
ENDIF
IF (IRR_Anomalous /= 0) then
PRINT*,'Conformal mesh of anomalous body is complete!'
CALL anomalous_conformal
print*,'Conformal mesh of anomalous body is finished'
ENDIF
!===============================Write a .vtk file with the model conductivity==============================
!===============================print conductivity_Z=======================================================
RANGEX=X_max-X_min+5-1
RANGEXB=RANGEX+1
RANGEY=Y_max-Y_min+5
RANGEYB=RANGEY+1
RANGEZ=Z_max-Z_min+10
RANGEZB=RANGEZ+1
ALLOCATE(temp_Coordix(RANGEXB),temp_Coordiy(RANGEYB),temp_Coordiz(RANGEZB))
ALLOCATE(CCSIG_temp(RANGEX, RANGEY, RANGEZ))
dims = [ RANGEX, RANGEY, RANGEZ ]
ii=0
jj=0
kk=0
RangeStartX=NXS-INT(RANGEX/2)
RangeStartY=NYS-INT(RANGEY/2)
RangeStartZ=NZS-2
DO ii=1,RANGEX
DO jj=1,RANGEY
DO kk=1,RANGEZ
CCSIG_temp(ii,jj,kk)=CCSIGX(ii+RangeStartX,jj+RangeStartY,kk+RangeStartZ)
! Choose edge conductivity for output:
! CCSIGZ: z-direction edge conductivity
! CCSIGY: y-direction edge conductivity
! CCSIGX: x-direction edge conductivity
ENDDO
ENDDO
ENDDO
DO ii=1,RANGEXB
temp_Coordix(ii) = ii
ENDDO
DO jj=1,RANGEYB
temp_Coordiy(jj) = jj
ENDDO
DO kk=1,RANGEZB
temp_Coordiz(kk) = kk
ENDDO
CALL hexahedron%init( filename = "conductivity.vtk", dims = dims, Coord_x = temp_Coordix, Coord_y = temp_Coordiy, Coord_z = temp_Coordiz )
CALL hexahedron%write
CALL hexahedron%add( names = "conductivity",values=CCSIG_temp )
CALL hexahedron%close
DEALLOCATE(temp_Coordix,temp_Coordiy,temp_Coordiz,CCSIG_temp)
!=========================================================================================
RETURN RETURN
ENDSUBROUTINE RES_CONFIGURE ENDSUBROUTINE Res_Configure
!------------------------ !-------------------------------------------------------------------------------
! @brief Swap two crosspoint properties
! @param[in,out] crosspoint_A first crosspoint
! @param[in,out] crosspoint_B second crosspoint
!-------------------------------------------------------------------------------
SUBROUTINE SWAP(crosspoint_A,crosspoint_B)
USE CONSTANTPARAMETERS
TYPE(CrossPoint_Property),intent(inout) :: crosspoint_A, crosspoint_B
TYPE(CrossPoint_Property) :: TEMP
TEMP%Global_Coord%Coord_X=crosspoint_A%Global_Coord%Coord_X
TEMP%Global_Coord%Coord_Y=crosspoint_A%Global_Coord%Coord_Y
TEMP%Global_Coord%Coord_Z=crosspoint_A%Global_Coord%Coord_Z
TEMP%Log_In=crosspoint_A%Log_In
crosspoint_A%Global_Coord%Coord_X=crosspoint_B%Global_Coord%Coord_X
crosspoint_A%Global_Coord%Coord_Y=crosspoint_B%Global_Coord%Coord_Y
crosspoint_A%Global_Coord%Coord_Z=crosspoint_B%Global_Coord%Coord_Z
crosspoint_A%Log_In=crosspoint_B%Log_In
crosspoint_B%Global_Coord%Coord_X=TEMP%Global_Coord%Coord_X
crosspoint_B%Global_Coord%Coord_Y=TEMP%Global_Coord%Coord_Y
crosspoint_B%Global_Coord%Coord_Z=TEMP%Global_Coord%Coord_Z
crosspoint_B%Log_In=TEMP%Log_In
END SUBROUTINE
+4 -4
查看文件
@@ -1,6 +1,6 @@
!Copyright (c) 2013 by tdem.org under guide of Xiu Li(lixiu@chd.edu.cn) !Copyright (c) 2013 by https://git.em3d.cn/ under guide of Xiu Li(lixiu@chd.edu.cn)
!written by Huaifeng Sun(sunhuaifeng@gmail.com) and Xushan Lu(luxushan@gmail.com) !written by Huaifeng Sun(sunhuaifeng@email.sdu.edu.cn) and Xushan Lu(luxushan@gmail.com)
!Code distribution @ tdem.org or sunhuaifeng.com !Code distribution @ https://git.em3d.cn/
SUBROUTINE SIN_SOURCE SUBROUTINE SIN_SOURCE
@@ -25,6 +25,6 @@ SUBROUTINE SIN_SOURCE
WRITE(9,'(3E24.16)')CTIME(I),DELT(I),SOURCE(I) WRITE(9,'(3E24.16)')CTIME(I),DELT(I),SOURCE(I)
ENDDO ENDDO
CLOSE(9) CLOSE(9)
WRITE(10005,*)'半正弦发射波形时间序列已经写入文件CTIME_SIN_SOURCE.DAT' WRITE(10005,*)'ҷʱѾдļCTIME_SIN_SOURCE.DAT'
RETURN RETURN
ENDSUBROUTINE SIN_SOURCE ENDSUBROUTINE SIN_SOURCE
+9 -9
查看文件
@@ -1,6 +1,6 @@
!Copyright (c) 2013 by tdem.org under guide of Xiu Li(lixiu@chd.edu.cn) !Copyright (c) 2013 by https://git.em3d.cn/ under guide of Xiu Li(lixiu@chd.edu.cn)
!written by Huaifeng Sun(sunhuaifeng@gmail.com) and Xushan Lu(luxushan@gmail.com) !written by Huaifeng Sun(sunhuaifeng@email.sdu.edu.cn) and Xushan Lu(luxushan@gmail.com)
!Code distribution @ tdem.org or sunhuaifeng.com !Code distribution @ https://git.em3d.cn/
SUBROUTINE TIME_SERIOUS SUBROUTINE TIME_SERIOUS
USE CONSTANTPARAMETERS USE CONSTANTPARAMETERS
@@ -8,7 +8,7 @@ SUBROUTINE TIME_SERIOUS
USE RES_MODEL_PARAMETER USE RES_MODEL_PARAMETER
USE TIME_PARAMETER USE TIME_PARAMETER
USE OMP_LIB USE OMP_LIB
!本子程序将计算初始时间和时间序列 !ӳ򽫼ʼʱʱ
IMPLICIT NONE IMPLICIT NONE
INTEGER NSTOP_TEMP,i,j,k INTEGER NSTOP_TEMP,i,j,k
TIME_MAX=100*GridSize*SQRT(EPS0*MU0/3.0) !Time_max can be set to larger value if the value of GridSize if less than 1m, otherwise you will spend a much longer time in calculation. TIME_MAX=100*GridSize*SQRT(EPS0*MU0/3.0) !Time_max can be set to larger value if the value of GridSize if less than 1m, otherwise you will spend a much longer time in calculation.
@@ -42,27 +42,27 @@ SUBROUTINE TIME_SERIOUS
ENDDO !This subroutine computes the value of Nstop which satisfies the requirement of Max_off_time ENDDO !This subroutine computes the value of Nstop which satisfies the requirement of Max_off_time
IF(NSTOP_TEMP .LT. NSTOP)THEN IF(NSTOP_TEMP .LT. NSTOP)THEN
NSTOP=NSTOP_TEMP !Change the value of Nstop to a smaller value according to the above computation NSTOP=NSTOP_TEMP !Change the value of Nstop to a smaller value according to the above computation
WRITE(10005,*)'NSTOP改变为',NSTOP WRITE(10005,*)'NSTOPıΪ',NSTOP
OPEN(9,FILE='CTIME_TIXING_UPCOS.DAT',STATUS='UNKNOWN') OPEN(9,FILE='CTIME_TIXING_UPCOS.DAT',STATUS='UNKNOWN')
DO I=1,NSTOP DO I=1,NSTOP
WRITE(9,'(3E24.16)')CTIME(I),DELT(I),SOURCE(I) WRITE(9,'(3E24.16)')CTIME(I),DELT(I),SOURCE(I)
ENDDO ENDDO
CLOSE(9) CLOSE(9)
WRITE(10005,*)'采用升余弦函数和降余弦函数处理的梯形波发射波形时间序列已经写入文件CTIME_TIXING_UPCOS.DAT' WRITE(10005,*)'ҺͽҺβʱѾдļCTIME_TIXING_UPCOS.DAT'
ELSEIF(NSTOP_TEMP .EQ. NSTOP)THEN ELSEIF(NSTOP_TEMP .EQ. NSTOP)THEN
NSTOP=NSTOP_TEMP NSTOP=NSTOP_TEMP
WRITE(10005,*)'NSTOP没有改变,可能无法满足最大最大延时设置,请重新设置NSTOP.' WRITE(10005,*)'NSTOPûиı䣬޷ʱãNSTOP.'
OPEN(9,FILE='CTIME_TIXING_UPCOS.DAT',STATUS='UNKNOWN') OPEN(9,FILE='CTIME_TIXING_UPCOS.DAT',STATUS='UNKNOWN')
DO I=1,NSTOP DO I=1,NSTOP
WRITE(9,'(3E24.16)')CTIME(I),DELT(I),SOURCE(I) WRITE(9,'(3E24.16)')CTIME(I),DELT(I),SOURCE(I)
ENDDO ENDDO
CLOSE(9) CLOSE(9)
WRITE(10005,*)'采用升余弦函数和降余弦函数处理的梯形波发射波形时间序列已经写入文件CTIME_TIXING_UPCOS.DAT' WRITE(10005,*)'ҺͽҺβʱѾдļCTIME_TIXING_UPCOS.DAT'
ELSE ELSE
WRITE(10005,*)'The number of iteration steps exceeds the range given in the input.dat, please change it. now the Nstop value is determined by Max_off_time.' WRITE(10005,*)'The number of iteration steps exceeds the range given in the input.dat, please change it. now the Nstop value is determined by Max_off_time.'
print*,'The number of iteration steps exceeds the range given in the input.dat, please change it. now the Nstop value is determined by Max_off_time.' print*,'The number of iteration steps exceeds the range given in the input.dat, please change it. now the Nstop value is determined by Max_off_time.'
print*,'I give you a pause here, you should decide to continue or to quit' print*,'I give you a pause here, you should decide to continue or to quit'
pause READ(*,*)
Nstop=Nstop_temp Nstop=Nstop_temp
ENDIF ENDIF
RETURN RETURN
+7 -7
查看文件
@@ -1,8 +1,8 @@
!Copyright (c) 2013 by tdem.org under guide of Xiu Li(lixiu@chd.edu.cn) !Copyright (c) 2013 by https://git.em3d.cn/ under guide of Xiu Li(lixiu@chd.edu.cn)
!written by Huaifeng Sun(sunhuaifeng@gmail.com) and Xushan Lu(luxushan@gmail.com) !written by Huaifeng Sun(sunhuaifeng@email.sdu.edu.cn) and Xushan Lu(luxushan@gmail.com)
!Code distribution @ tdem.org or sunhuaifeng.com !Code distribution @ https://git.em3d.cn/
!梯形波电流激发,采用升余弦开关函数和降余弦开关函数 !βҿغͽҿغ
SUBROUTINE TIXING_SOURCE_UPCOS SUBROUTINE TIXING_SOURCE_UPCOS
USE CONSTANTPARAMETERS USE CONSTANTPARAMETERS
USE ELECTROMAGNETIC_VARIABLES USE ELECTROMAGNETIC_VARIABLES
@@ -20,16 +20,16 @@ SUBROUTINE TIXING_SOURCE_UPCOS
SOURCE(1)=AMP*0.5*(1-COS(PI*CTIME(1)/RAISETIME)) !AMP*CTIME(1)/RAISETIME SOURCE(1)=AMP*0.5*(1-COS(PI*CTIME(1)/RAISETIME)) !AMP*CTIME(1)/RAISETIME
DO I=2,NSTOP DO I=2,NSTOP
CTIME(I)=CTIME(I-1)+DELT(I-1) CTIME(I)=CTIME(I-1)+DELT(I-1)
IF(CTIME(I) .LT. RAISETIME)THEN IF(CTIME(I) .LT. RAISETIME)THEN !Сraistime
DELT(I)=RAISESTEP DELT(I)=RAISESTEP
SOURCE(I)=AMP*0.5*(1-COS(PI*CTIME(I)/RAISETIME)) !AMP*CTIME(I)/RAISETIME SOURCE(I)=AMP*0.5*(1-COS(PI*CTIME(I)/RAISETIME)) !AMP*CTIME(I)/RAISETIME
ELSEIF(CTIME(I) .GE. RAISETIME .AND. CTIME(I) .LT. RAISETIME+WAVE-TIME_RAMP2WAVE_SUM)THEN ELSEIF(CTIME(I) .GE. RAISETIME .AND. CTIME(I) .LT. RAISETIME+WAVE-TIME_RAMP2WAVE_SUM)THEN !RAISETIMEСڵCTIME(I)<RAISETIME+WAVE-TIME_RAMP2WAVE_SUM
DELT(I)=DELT(I-1)*1.0005 DELT(I)=DELT(I-1)*1.0005
IF(DELT(I) .GE. WAVESTEP)THEN IF(DELT(I) .GE. WAVESTEP)THEN
DELT(I)=WAVESTEP DELT(I)=WAVESTEP
ENDIF ENDIF
SOURCE(I)=AMP !1.0D0 SOURCE(I)=AMP !1.0D0
ELSEIF(CTIME(I) .GE. RAISETIME+WAVE-TIME_RAMP2WAVE_SUM .AND. CTIME(I) .LT. RAISETIME+WAVE)THEN ELSEIF(CTIME(I) .GE. RAISETIME+WAVE-TIME_RAMP2WAVE_SUM .AND. CTIME(I) .LT. RAISETIME+WAVE)THEN !RAISETIME+WAVE-TIME_RAMP2WAVE_SUMСڵCTIME(I)<RAISETIME+WAVE
DELT(I)=DELT(I-1)*0.9995 DELT(I)=DELT(I-1)*0.9995
IF(DELT(I) .LE. RAMPSTEP)THEN IF(DELT(I) .LE. RAMPSTEP)THEN
DELT(I)=RAMPSTEP DELT(I)=RAMPSTEP
+4 -4
查看文件
@@ -1,6 +1,6 @@
!Copyright (c) 2013 by tdem.org under guide of Xiu Li(lixiu@chd.edu.cn) !Copyright (c) 2013 by https://git.em3d.cn/ under guide of Xiu Li(lixiu@chd.edu.cn)
!written by Huaifeng Sun(sunhuaifeng@gmail.com) and Xushan Lu(luxushan@gmail.com) !written by Huaifeng Sun(sunhuaifeng@email.sdu.edu.cn) and Xushan Lu(luxushan@gmail.com)
!Code distribution @ tdem.org or sunhuaifeng.com !Code distribution @ https://git.em3d.cn/
SUBROUTINE TIXING_SOURCE SUBROUTINE TIXING_SOURCE
USE CONSTANTPARAMETERS USE CONSTANTPARAMETERS
@@ -47,6 +47,6 @@ SUBROUTINE TIXING_SOURCE
WRITE(9,'(3E24.16E3)')CTIME(I),DELT(I),SOURCE(I) WRITE(9,'(3E24.16E3)')CTIME(I),DELT(I),SOURCE(I)
ENDDO ENDDO
CLOSE(9) CLOSE(9)
WRITE(10005,*)'梯形波发射波形时间序列已经写入文件CTIME_TIXING.DAT' WRITE(10005,*)'βʱѾдļCTIME_TIXING.DAT'
RETURN RETURN
ENDSUBROUTINE TIXING_SOURCE ENDSUBROUTINE TIXING_SOURCE
+4 -4
查看文件
@@ -1,6 +1,6 @@
!Copyright (c) 2013 by tdem.org under guide of Xiu Li(lixiu@chd.edu.cn) !Copyright (c) 2013 by https://git.em3d.cn/ under guide of Xiu Li(lixiu@chd.edu.cn)
!written by Huaifeng Sun(sunhuaifeng@gmail.com) and Xushan Lu(luxushan@gmail.com) !written by Huaifeng Sun(sunhuaifeng@email.sdu.edu.cn) and Xushan Lu(luxushan@gmail.com)
!Code distribution @ tdem.org or sunhuaifeng.com !Code distribution @ https://git.em3d.cn/
SUBROUTINE TRIANGLE_SOURCE SUBROUTINE TRIANGLE_SOURCE
USE CONSTANTPARAMETERS USE CONSTANTPARAMETERS
@@ -26,6 +26,6 @@ SUBROUTINE TRIANGLE_SOURCE
WRITE(9,'(3E24.16)')CTIME(I),DELT(I),SOURCE(I) WRITE(9,'(3E24.16)')CTIME(I),DELT(I),SOURCE(I)
ENDDO ENDDO
CLOSE(9) CLOSE(9)
WRITE(10005,*)'三角发射波形时间序列已经写入文件CTIME_TRIANGLE_SOURCE.DAT' WRITE(10005,*)'ǷʱѾдļCTIME_TRIANGLE_SOURCE.DAT'
RETURN RETURN
ENDSUBROUTINE TRIANGLE_SOURCE ENDSUBROUTINE TRIANGLE_SOURCE
+3 -3
查看文件
@@ -1,6 +1,6 @@
!Copyright (c) 2013 by tdem.org under guide of Xiu Li(lixiu@chd.edu.cn) !Copyright (c) 2013 by https://git.em3d.cn/ under guide of Xiu Li(lixiu@chd.edu.cn)
!written by Huaifeng Sun(sunhuaifeng@gmail.com) and Xushan Lu(luxushan@gmail.com) !written by Huaifeng Sun(sunhuaifeng@email.sdu.edu.cn) and Xushan Lu(luxushan@gmail.com)
!Code distribution @ tdem.org or sunhuaifeng.com !Code distribution @ https://git.em3d.cn/
subroutine WriteRecFiles(num) subroutine WriteRecFiles(num)
use constantparameters use constantparameters
+47 -4
查看文件
@@ -1,21 +1,64 @@
!Copyright (c) 2013 by tdem.org under guide of Xiu Li(lixiu@chd.edu.cn) !Copyright (c) 2013 by https://git.em3d.cn/ under guide of Xiu Li(lixiu@chd.edu.cn)
!written by Huaifeng Sun(sunhuaifeng@gmail.com) and Xushan Lu(luxushan@gmail.com) !written by Huaifeng Sun(sunhuaifeng@email.sdu.edu.cn) and Xushan Lu(luxushan@gmail.com)
!Code distribution @ tdem.org or sunhuaifeng.com !Code distribution @ https://git.em3d.cn/
SUBROUTINE ZERO SUBROUTINE ZERO
USE CONSTANTPARAMETERS USE CONSTANTPARAMETERS
USE ELECTROMAGNETIC_VARIABLES USE ELECTROMAGNETIC_VARIABLES
USE RES_MODEL_PARAMETER USE RES_MODEL_PARAMETER
USE TIME_PARAMETER USE TIME_PARAMETER
USE PML_PARAMETER
USE OMP_LIB USE OMP_LIB
!本子程序将计算中的数组赋0值进行初始化 !>This subroutine will initialize the array in the calculation by setting all its elements to zero.
IMPLICIT NONE IMPLICIT NONE
CCSIG=0.0D0 CCSIG=0.0D0
CCSIGX=0.0D0
CCSIGY=0.0D0
CCSIGZ=0.0D0
EX=0.0D0 EX=0.0D0
EY=0.0D0 EY=0.0D0
EZ=0.0D0 EZ=0.0D0
HX=0.0D0 HX=0.0D0
HY=0.0D0 HY=0.0D0
HZ=0.0D0 HZ=0.0D0
!>CPML arrays: den_* is always initialized to 1.0 (neutral value), so the
!! iteration loop can always multiply the curl terms by den_*; the scheme
!! degenerates exactly to the original version when Logic_PML=0.
den_ex=1.0D0
den_ey=1.0D0
den_ez=1.0D0
den_hx=1.0D0
den_hy=1.0D0
den_hz=1.0D0
c_h_zz=0.0D0
inv_hz_den=1.0D0
IF(Logic_PML==1)THEN
psi_Eyx_1=0.0D0
psi_Eyx_2=0.0D0
psi_Ezx_1=0.0D0
psi_Ezx_2=0.0D0
psi_Ezy_1=0.0D0
psi_Ezy_2=0.0D0
psi_Exy_1=0.0D0
psi_Exy_2=0.0D0
psi_Exz_1=0.0D0
psi_Exz_2=0.0D0
psi_Eyz_1=0.0D0
psi_Eyz_2=0.0D0
psi_Hyx_1=0.0D0
psi_Hyx_2=0.0D0
psi_Hzx_1=0.0D0
psi_Hzx_2=0.0D0
psi_Hxy_1=0.0D0
psi_Hxy_2=0.0D0
psi_Hzy_1=0.0D0
psi_Hzy_2=0.0D0
psi_Hxz_1=0.0D0
psi_Hxz_2=0.0D0
psi_Hyz_1=0.0D0
psi_Hyz_2=0.0D0
psi_Hzz_1=0.0D0
psi_Hzz_2=0.0D0
ENDIF
RETURN RETURN
ENDSUBROUTINE ZERO ENDSUBROUTINE ZERO
+30 -15
查看文件
@@ -1,20 +1,20 @@
!Copyright (c) 2013 by tdem.org under guide of Xiu Li(lixiu@chd.edu.cn) !Copyright (c) 2013 by https://git.em3d.cn/ under guide of Xiu Li(lixiu@chd.edu.cn)
!written by Huaifeng Sun(sunhuaifeng@gmail.com) and Xushan Lu(luxushan@gmail.com) !written by Huaifeng Sun(sunhuaifeng@email.sdu.edu.cn) and Xushan Lu(luxushan@gmail.com)
!Code distribution @ tdem.org or sunhuaifeng.com !Code distribution @ https://git.em3d.cn/
! This is a finite difference time domain (FDTD) code for the simulation of transient electromagnetic (TEM); ! This is a finite difference time domain (FDTD) code for the simulation of transient electromagnetic (TEM);
! This code is designed to be used in semi_airborne TEM with a loop source; ! This code is designed to be used in semi_airborne TEM with a loop source;
! This code is written by Huaifeng Sun (sunhuaifeng@gmail.com) and Xushan Lu (luxushan@gmail.com); ! This code is written by Huaifeng Sun (sunhuaifeng@email.sdu.edu.cn) and Xushan Lu (luxushan@gmail.com), The conformal mesh part is written by Xinyu Li (202335098@mail.sdu.edu.cn) and Qi Zhao(zhaoqi_326326@163.com);
! OpenACC API is used in this code for the acceleration with GPU device; therefore, you are recommended to compile this code with -- ! OpenACC API is used in this code for the acceleration with GPU device; therefore, you are recommended to compile this code with --
! --PGI Accelerator Fortran Workstation compiler. A Nvidia GPU card with CUDA capability is required if you want to run this code in parallel mode. ! --PGI Accelerator Fortran Workstation compiler. A Nvidia GPU card with CUDA capability is required if you want to run this code in parallel mode.
! Nobody is allowed to copy or distribute this code to people outside of TDEM.org group without the permission from Prof. Xiu Li (lixiu@chd.edu.cn)-- ! Nobody is allowed to copy or distribute this code to people outside of https://git.em3d.cn/ group without the permission from Prof. Xiu Li (lixiu@chd.edu.cn)--
! --or you will be ! --or you will be
! Contact the author for more detailed information. ! Contact the author for more detailed information.
!------------------------------------------------Instruction part--------------------------------------------------! !------------------------------------------------Instruction part--------------------------------------------------!
! This module is used to declare most of the parameters which are used in the entire code. ! This module is used to declare most of the parameters which are used in the entire code.
!-----------------------------------------------------------------------------------------------------------------------! !-----------------------------------------------------------------------------------------------------------------------!
!==========================Ö÷³ÌÐò¿ªÊ¼============================== !==========================The main program begins==============================
PROGRAM MAIN PROGRAM MAIN
USE OMP_LIB USE OMP_LIB
USE CONSTANTPARAMETERS USE CONSTANTPARAMETERS
@@ -25,7 +25,7 @@ PROGRAM MAIN
CHARACTER*20, XSTRING CHARACTER*20, XSTRING
CHARACTER*20, SYS_TIME CHARACTER*20, SYS_TIME
OPEN(10005,FILE='logfile.log',STATUS='UNKNOWN') OPEN(10005,FILE='logfile.log',STATUS='UNKNOWN')
CALL GET_SYS_TIMEDATA(SYS_TIME) !CALL GET_SYS_TIMEDATA(SYS_TIME)
WRITE(10005,*)'----------------------',SYS_TIME,'----------------------' WRITE(10005,*)'----------------------',SYS_TIME,'----------------------'
CALL GETDATA !This subroutine is used to input all the needed parameter of each calculation from 'input.dat' file. CALL GETDATA !This subroutine is used to input all the needed parameter of each calculation from 'input.dat' file.
CALL CHECKPARAMETERS !This subroutine is used to chech the correctness of input CALL CHECKPARAMETERS !This subroutine is used to chech the correctness of input
@@ -34,28 +34,43 @@ PROGRAM MAIN
XSTRING = TRIM(ADJUSTL(XSTRING)) XSTRING = TRIM(ADJUSTL(XSTRING))
CALL MEMORY_USE_ESTIMATION !This subroutine is used to estimate the total memory usage according to the input, CALL MEMORY_USE_ESTIMATION !This subroutine is used to estimate the total memory usage according to the input,
CALL ALLOCATEMEMORY !This subroutine is used to allocate the memory in Host. CALL ALLOCATEMEMORY !This subroutine is used to allocate the memory in Host.
WRITE(*,*)'Preparing the non-uniform grid.. .. .. ..' WRITE(*,*)'Preparing the grid.. .. .. ..'
CALL GET_NON_UNIFORMGRID !This subroutine is used to mesh the non-uniform grid model. IF(Logic_PML==1)THEN
WRITE(*,*)'Boundary condition: CPML absorbing boundary -> uniform grid meshing'
CALL GET_UNIFORM_GRID !CPML 吸收边界:采用均匀网格剖分(与参考实现 tem3dfdtd_第二版 的组合一致)
ELSE
WRITE(*,*)'Boundary condition: Dirichlet (zero-field) boundary -> non-uniform grid meshing'
CALL GET_NON_UNIFORMGRID !Dirichlet 边界:采用非均匀网格剖分(原版方式)
ENDIF
WRITE(*,*)'Initializing the parameters.. .. ..' WRITE(*,*)'Initializing the parameters.. .. ..'
CALL ZERO !This subroutine is used to initialize the value of array. CALL ZERO !This subroutine is used to initialize the value of array.
WRITE(*,*)'Creating resistivity model.. .. ..' WRITE(*,*)'Creating resistivity model.. .. ..'
CALL GET_COORDINATES
CALL Get_Receiver_Gridlabel !This subroutine is used to calculate the global coordinates and grid dispersion at the receiving point
CALL RES_CONFIGURE !This subroutine is used to distribute the resistivity (or conductivity) of the geology model to each grid CALL RES_CONFIGURE !This subroutine is used to distribute the resistivity (or conductivity) of the geology model to each grid
WRITE(*,*)'Creating computing time series.. .. ..' WRITE(*,*)'Creating computing time series.. .. ..'
CALL TIME_SERIOUS !This subroutine is used to creat the time series of the entire computation CALL TIME_SERIOUS !This subroutine is used to creat the time series of the entire computation
WRITE(*,*)'Preparing array receiver points.. .. ..' WRITE(*,*)'Preparing array receiver points.. .. ..'
WRITE(*,*)'Starting computing.. .. ..' WRITE(*,*)'Starting computing.. .. ..'
CALL GET_SYS_TIMEDATA(SYS_TIME) !CALL GET_SYS_TIMEDATA(SYS_TIME)
WRITE(10005,*)'----------------------',SYS_TIME,'----------------------' WRITE(10005,*)'----------------------',SYS_TIME,'----------------------'
call Get_eps_r !This subroutine is used to get the fictitious dielectric constant call Get_eps_r !This subroutine is used to get the fictitious dielectric constant
IF(Logic_PML==1)THEN
call Get_pml_parameters !This subroutine is used to get the CPML sigma/alpha/kappa profiles and the den_* scaling arrays
ENDIF
call Get_mstop !This subroutine is used to cut the entire computation process into computation fractions call Get_mstop !This subroutine is used to cut the entire computation process into computation fractions
call GetSourcePosition !This subroutine is used to get the source position in the model. call GetSourcePosition !This subroutine is used to get the source position in the model.
call OpenRecFiles !This subroutine is used to open all the files for the record of simulation data. IF(Logic_PML==1)THEN
call Iteration !This subroutine is the iteration subroutine of EM filed WRITE(*,*)'Starting CPML iteration (Iteration_cpml) .. .. .. ..'
call CloseRecFiles !This subroutine is used to close all the opened recording files call Iteration_cpml !CPML 吸收边界迭代子程序
ELSE
WRITE(*,*)'Starting Dirichlet iteration (Iteration) .. .. .. ..'
call Iteration !Dirichlet 边界迭代子程序(原版)
ENDIF
CALL FREE_MEMORY !This subroutine is used to deallocate all the memory allocated before iteration CALL FREE_MEMORY !This subroutine is used to deallocate all the memory allocated before iteration
CALL GET_SYS_TIMEDATA(SYS_TIME) !CALL GET_SYS_TIMEDATA(SYS_TIME)
WRITE(10005,*)'----------------------',SYS_TIME,'----------------------' WRITE(10005,*)'----------------------',SYS_TIME,'----------------------'
WRITE(10005,*)'Computation finished£¡' WRITE(10005,*)'Computation finished'
CLOSE(10005) CLOSE(10005)
END PROGRAM MAIN END PROGRAM MAIN

某些文件未显示,因为此 diff 中更改的文件太多 显示更多