diff options
author | Sebastián Barschkis <sebbas@sebbas.org> | 2019-12-16 17:51:02 +0300 |
---|---|---|
committer | Sebastián Barschkis <sebbas@sebbas.org> | 2019-12-16 18:37:57 +0300 |
commit | 7bd3d2be080720a5b40b6898e6588e937497201f (patch) | |
tree | 087b9996b14a9e5aa1c5ddadeab2aec8f566056b /intern/elbeem | |
parent | d27ccf990c2b957a10f4676e3153f907829a4b22 (diff) |
Mantaflow [Part 5]: Update other /intern packages
Cycles needs some smaller updates so that the up-res smoke wavelet noise and the liquid mesh speed vector export work correctly.
Reviewed By: mont29
Maniphest Tasks: T59995
Differential Revision: https://developer.blender.org/D3854
Diffstat (limited to 'intern/elbeem')
56 files changed, 0 insertions, 29399 deletions
diff --git a/intern/elbeem/CMakeLists.txt b/intern/elbeem/CMakeLists.txt deleted file mode 100644 index 63a6af84323..00000000000 --- a/intern/elbeem/CMakeLists.txt +++ /dev/null @@ -1,130 +0,0 @@ -# ***** BEGIN GPL LICENSE BLOCK ***** -# -# 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 2 -# 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, write to the Free Software Foundation, -# Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. -# -# The Original Code is Copyright (C) 2006, Blender Foundation -# All rights reserved. -# ***** END GPL LICENSE BLOCK ***** - -set(INC - extern - ../guardedalloc -) - -set(INC_SYS - ${PNG_INCLUDE_DIRS} - ${ZLIB_INCLUDE_DIRS} -) - -set(SRC - intern/attributes.cpp - intern/controlparticles.cpp - intern/elbeem.cpp - intern/elbeem_control.cpp - intern/isosurface.cpp - intern/mvmcoords.cpp - intern/ntl_blenderdumper.cpp - intern/ntl_bsptree.cpp - intern/ntl_geometrymodel.cpp - intern/ntl_geometryobject.cpp - intern/ntl_lighting.cpp - intern/ntl_ray.cpp - intern/ntl_world.cpp - intern/parametrizer.cpp - intern/particletracer.cpp - intern/simulation_object.cpp - intern/solver_adap.cpp - intern/solver_control.cpp - intern/solver_init.cpp - intern/solver_interface.cpp - intern/solver_main.cpp - intern/solver_util.cpp - intern/utilities.cpp - - extern/LBM_fluidsim.h - extern/elbeem.h - intern/attributes.h - intern/controlparticles.h - intern/elbeem_control.h - intern/isosurface.h - intern/loop_tools.h - intern/mcubes_tables.h - intern/mvmcoords.h - intern/ntl_blenderdumper.h - intern/ntl_bsptree.h - intern/ntl_geometryclass.h - intern/ntl_geometrymodel.h - intern/ntl_geometryobject.h - intern/ntl_geometryshader.h - intern/ntl_lighting.h - intern/ntl_matrices.h - intern/ntl_ray.h - intern/ntl_vector3dim.h - intern/ntl_world.h - intern/paraloopend.h - intern/parametrizer.h - intern/particletracer.h - intern/simulation_object.h - intern/solver_class.h - intern/solver_control.h - intern/solver_interface.h - intern/solver_relax.h - intern/utilities.h - intern/globals.h -) - -set(LIB -) - -# elbeem has some harmless UNUSED warnings -remove_strict_flags() - -add_definitions( - -DNOGUI - -DELBEEM_BLENDER=1 -) - -# not essential but quiet gcc's -Wundef -add_definitions( - -DLBM_PRECISION=1 - -DLBM_INCLUDE_TESTSOLVERS=0 - -DFSGR_STRICT_DEBUG=0 - -DELBEEM_MPI=0 - -DNEWDIRVELMOTEST=0 -) - -if(WIN32) - # We need BLI_gzopen on win32 for unicode paths - add_definitions( - -DLBM_GZIP_OVERRIDE_H="${CMAKE_SOURCE_DIR}/source/blender/blenlib/BLI_fileops.h" - -D LBM_GZIP_OPEN_FN="\(gzFile\)BLI_gzopen" - ) -endif() - -if(WITH_OPENMP) - add_definitions(-DPARALLEL=1) -else() - add_definitions(-DPARALLEL=0) -endif() - -# Work around hang with GCC and ASAN. -if(WITH_COMPILER_ASAN) - if(CMAKE_COMPILER_IS_GNUCC OR CMAKE_C_COMPILER_ID MATCHES "Clang") - set(CMAKE_CXX_FLAGS_RELWITHDEBINFO "${CMAKE_CXX_FLAGS_RELWITHDEBINFO} -fno-sanitize=vptr") - set(CMAKE_CXX_FLAGS_DEBUG "${CMAKE_CXX_FLAGS_DEBUG} -fno-sanitize=vptr") - endif() -endif() - -blender_add_lib_nolist(bf_intern_elbeem "${SRC}" "${INC}" "${INC_SYS}" "${LIB}") diff --git a/intern/elbeem/COPYING b/intern/elbeem/COPYING deleted file mode 100644 index 2600c731161..00000000000 --- a/intern/elbeem/COPYING +++ /dev/null @@ -1,358 +0,0 @@ - All code distributed as part of El'Beem is covered by the following - version of the GNU General Public License. - - 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 2 - 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. - - Copyright (c) 2003-2005 Nils Thuerey. All rights reserved. - - - - - GNU GENERAL PUBLIC LICENSE - Version 2, June 1991 - - Copyright (C) 1989, 1991 Free Software Foundation, Inc. - 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA - Everyone is permitted to copy and distribute verbatim copies - of this license document, but changing it is not allowed. - - Preamble - - The licenses for most software are designed to take away your -freedom to share and change it. By contrast, the GNU General Public -License is intended to guarantee your freedom to share and change free -software--to make sure the software is free for all its users. This -General Public License applies to most of the Free Software -Foundation's software and to any other program whose authors commit to -using it. (Some other Free Software Foundation software is covered by -the GNU Library General Public License instead.) You can apply it to -your programs, too. - - 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 -this service 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 make restrictions that forbid -anyone to deny you these rights or to ask you to surrender the rights. -These restrictions translate to certain responsibilities for you if you -distribute copies of the software, or if you modify it. - - For example, if you distribute copies of such a program, whether -gratis or for a fee, you must give the recipients all the rights that -you have. 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. - - We protect your rights with two steps: (1) copyright the software, and -(2) offer you this license which gives you legal permission to copy, -distribute and/or modify the software. - - Also, for each author's protection and ours, we want to make certain -that everyone understands that there is no warranty for this free -software. If the software is modified by someone else and passed on, we -want its recipients to know that what they have is not the original, so -that any problems introduced by others will not reflect on the original -authors' reputations. - - Finally, any free program is threatened constantly by software -patents. We wish to avoid the danger that redistributors of a free -program will individually obtain patent licenses, in effect making the -program proprietary. To prevent this, we have made it clear that any -patent must be licensed for everyone's free use or not licensed at all. - - The precise terms and conditions for copying, distribution and -modification follow. - - GNU GENERAL PUBLIC LICENSE - TERMS AND CONDITIONS FOR COPYING, DISTRIBUTION AND MODIFICATION - - 0. This License applies to any program or other work which contains -a notice placed by the copyright holder saying it may be distributed -under the terms of this General Public License. The "Program", below, -refers to any such program or work, and a "work based on the Program" -means either the Program or any derivative work under copyright law: -that is to say, a work containing the Program or a portion of it, -either verbatim or with modifications and/or translated into another -language. (Hereinafter, translation is included without limitation in -the term "modification".) Each licensee is addressed as "you". - -Activities other than copying, distribution and modification are not -covered by this License; they are outside its scope. The act of -running the Program is not restricted, and the output from the Program -is covered only if its contents constitute a work based on the -Program (independent of having been made by running the Program). -Whether that is true depends on what the Program does. - - 1. You may copy and distribute 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 and disclaimer of warranty; keep intact all the -notices that refer to this License and to the absence of any warranty; -and give any other recipients of the Program a copy of this License -along with the Program. - -You may charge a fee for the physical act of transferring a copy, and -you may at your option offer warranty protection in exchange for a fee. - - 2. You may modify your copy or copies of the Program or any portion -of it, thus forming a work based on the Program, and copy and -distribute such modifications or work under the terms of Section 1 -above, provided that you also meet all of these conditions: - - a) You must cause the modified files to carry prominent notices - stating that you changed the files and the date of any change. - - b) You must cause any work that you distribute or publish, that in - whole or in part contains or is derived from the Program or any - part thereof, to be licensed as a whole at no charge to all third - parties under the terms of this License. - - c) If the modified program normally reads commands interactively - when run, you must cause it, when started running for such - interactive use in the most ordinary way, to print or display an - announcement including an appropriate copyright notice and a - notice that there is no warranty (or else, saying that you provide - a warranty) and that users may redistribute the program under - these conditions, and telling the user how to view a copy of this - License. (Exception: if the Program itself is interactive but - does not normally print such an announcement, your work based on - the Program is not required to print an announcement.) - -These requirements apply to the modified work as a whole. If -identifiable sections of that work are not derived from the Program, -and can be reasonably considered independent and separate works in -themselves, then this License, and its terms, do not apply to those -sections when you distribute them as separate works. But when you -distribute the same sections as part of a whole which is a work based -on the Program, the distribution of the whole must be on the terms of -this License, whose permissions for other licensees extend to the -entire whole, and thus to each and every part regardless of who wrote it. - -Thus, it is not the intent of this section to claim rights or contest -your rights to work written entirely by you; rather, the intent is to -exercise the right to control the distribution of derivative or -collective works based on the Program. - -In addition, mere aggregation of another work not based on the Program -with the Program (or with a work based on the Program) on a volume of -a storage or distribution medium does not bring the other work under -the scope of this License. - - 3. You may copy and distribute the Program (or a work based on it, -under Section 2) in object code or executable form under the terms of -Sections 1 and 2 above provided that you also do one of the following: - - a) Accompany it with the complete corresponding machine-readable - source code, which must be distributed under the terms of Sections - 1 and 2 above on a medium customarily used for software interchange; or, - - b) Accompany it with a written offer, valid for at least three - years, to give any third party, for a charge no more than your - cost of physically performing source distribution, a complete - machine-readable copy of the corresponding source code, to be - distributed under the terms of Sections 1 and 2 above on a medium - customarily used for software interchange; or, - - c) Accompany it with the information you received as to the offer - to distribute corresponding source code. (This alternative is - allowed only for noncommercial distribution and only if you - received the program in object code or executable form with such - an offer, in accord with Subsection b above.) - -The source code for a work means the preferred form of the work for -making modifications to it. For an executable work, complete source -code means all the source code for all modules it contains, plus any -associated interface definition files, plus the scripts used to -control compilation and installation of the executable. However, as a -special exception, the source code distributed need not include -anything that is normally distributed (in either source or binary -form) with the major components (compiler, kernel, and so on) of the -operating system on which the executable runs, unless that component -itself accompanies the executable. - -If distribution of executable or object code is made by offering -access to copy from a designated place, then offering equivalent -access to copy the source code from the same place counts as -distribution of the source code, even though third parties are not -compelled to copy the source along with the object code. - - 4. You may not copy, modify, sublicense, or distribute the Program -except as expressly provided under this License. Any attempt -otherwise to copy, modify, sublicense or distribute the Program is -void, and will automatically terminate your rights under this License. -However, parties who have received copies, or rights, from you under -this License will not have their licenses terminated so long as such -parties remain in full compliance. - - 5. You are not required to accept this License, since you have not -signed it. However, nothing else grants you permission to modify or -distribute the Program or its derivative works. These actions are -prohibited by law if you do not accept this License. Therefore, by -modifying or distributing the Program (or any work based on the -Program), you indicate your acceptance of this License to do so, and -all its terms and conditions for copying, distributing or modifying -the Program or works based on it. - - 6. Each time you redistribute the Program (or any work based on the -Program), the recipient automatically receives a license from the -original licensor to copy, distribute or modify the Program subject to -these terms and conditions. You may not impose any further -restrictions on the recipients' exercise of the rights granted herein. -You are not responsible for enforcing compliance by third parties to -this License. - - 7. If, as a consequence of a court judgment or allegation of patent -infringement or for any other reason (not limited to patent issues), -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 -distribute so as to satisfy simultaneously your obligations under this -License and any other pertinent obligations, then as a consequence you -may not distribute the Program at all. For example, if a patent -license would not permit royalty-free redistribution of the Program by -all those who receive copies directly or indirectly through you, then -the only way you could satisfy both it and this License would be to -refrain entirely from distribution of the Program. - -If any portion of this section is held invalid or unenforceable under -any particular circumstance, the balance of the section is intended to -apply and the section as a whole is intended to apply in other -circumstances. - -It is not the purpose of this section to induce you to infringe any -patents or other property right claims or to contest validity of any -such claims; this section has the sole purpose of protecting the -integrity of the free software distribution system, which is -implemented by public license practices. Many people have made -generous contributions to the wide range of software distributed -through that system in reliance on consistent application of that -system; it is up to the author/donor to decide if he or she is willing -to distribute software through any other system and a licensee cannot -impose that choice. - -This section is intended to make thoroughly clear what is believed to -be a consequence of the rest of this License. - - 8. If the distribution and/or use of the Program is restricted in -certain countries either by patents or by copyrighted interfaces, the -original copyright holder who places the Program under this License -may add an explicit geographical distribution limitation excluding -those countries, so that distribution is permitted only in or among -countries not thus excluded. In such case, this License incorporates -the limitation as if written in the body of this License. - - 9. The Free Software Foundation may publish revised and/or new versions -of the 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 a version number of this License which applies to it and "any -later version", you have the option of following the terms and conditions -either of that version or of any later version published by the Free -Software Foundation. If the Program does not specify a version number of -this License, you may choose any version ever published by the Free Software -Foundation. - - 10. If you wish to incorporate parts of the Program into other free -programs whose distribution conditions are different, write to the author -to ask for permission. For software which is copyrighted by the Free -Software Foundation, write to the Free Software Foundation; we sometimes -make exceptions for this. Our decision will be guided by the two goals -of preserving the free status of all derivatives of our free software and -of promoting the sharing and reuse of software generally. - - NO WARRANTY - - 11. BECAUSE THE PROGRAM IS LICENSED FREE OF CHARGE, 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. - - 12. IN NO EVENT UNLESS REQUIRED BY APPLICABLE LAW OR AGREED TO IN WRITING -WILL ANY COPYRIGHT HOLDER, OR ANY OTHER PARTY WHO MAY MODIFY AND/OR -REDISTRIBUTE 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. - - 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 -convey 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 2 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, write to the Free Software - Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA - - -Also add information on how to contact you by electronic and paper mail. - -If the program is interactive, make it output a short notice like this -when it starts in an interactive mode: - - Gnomovision version 69, Copyright (C) year name of author - Gnomovision 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, the commands you use may -be called something other than `show w' and `show c'; they could even be -mouse-clicks or menu items--whatever suits your program. - -You should also get your employer (if you work as a programmer) or your -school, if any, to sign a "copyright disclaimer" for the program, if -necessary. Here is a sample; alter the names: - - Yoyodyne, Inc., hereby disclaims all copyright interest in the program - `Gnomovision' (which makes passes at compilers) written by James Hacker. - - <signature of Ty Coon>, 1 April 1989 - Ty Coon, President of Vice - -This 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 Library General -Public License instead of this License. diff --git a/intern/elbeem/COPYING_trimesh2 b/intern/elbeem/COPYING_trimesh2 deleted file mode 100644 index a214195fd60..00000000000 --- a/intern/elbeem/COPYING_trimesh2 +++ /dev/null @@ -1,303 +0,0 @@ -This distribution includes source to "miniball", "freeGLUT", -and "GLUI", which are covered under their own licenses. - -All other code distributed as part of trimesh2 is covered -by the following license: - - -Copyright (c) 2004 Szymon Rusinkiewicz. -All rights reserved. - -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 2 -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. - - - - - GNU GENERAL PUBLIC LICENSE - Version 2, June 1991 - - Copyright (C) 1989, 1991 Free Software Foundation, Inc. - 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA - Everyone is permitted to copy and distribute verbatim copies - of this license document, but changing it is not allowed. - - Preamble - - The licenses for most software are designed to take away your -freedom to share and change it. By contrast, the GNU General Public -License is intended to guarantee your freedom to share and change free -software--to make sure the software is free for all its users. This -General Public License applies to most of the Free Software -Foundation's software and to any other program whose authors commit to -using it. (Some other Free Software Foundation software is covered by -the GNU Library General Public License instead.) You can apply it to -your programs, too. - - 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 -this service 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 make restrictions that forbid -anyone to deny you these rights or to ask you to surrender the rights. -These restrictions translate to certain responsibilities for you if you -distribute copies of the software, or if you modify it. - - For example, if you distribute copies of such a program, whether -gratis or for a fee, you must give the recipients all the rights that -you have. 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. - - We protect your rights with two steps: (1) copyright the software, and -(2) offer you this license which gives you legal permission to copy, -distribute and/or modify the software. - - Also, for each author's protection and ours, we want to make certain -that everyone understands that there is no warranty for this free -software. If the software is modified by someone else and passed on, we -want its recipients to know that what they have is not the original, so -that any problems introduced by others will not reflect on the original -authors' reputations. - - Finally, any free program is threatened constantly by software -patents. We wish to avoid the danger that redistributors of a free -program will individually obtain patent licenses, in effect making the -program proprietary. To prevent this, we have made it clear that any -patent must be licensed for everyone's free use or not licensed at all. - - The precise terms and conditions for copying, distribution and -modification follow. - - GNU GENERAL PUBLIC LICENSE - TERMS AND CONDITIONS FOR COPYING, DISTRIBUTION AND MODIFICATION - - 0. This License applies to any program or other work which contains -a notice placed by the copyright holder saying it may be distributed -under the terms of this General Public License. The "Program", below, -refers to any such program or work, and a "work based on the Program" -means either the Program or any derivative work under copyright law: -that is to say, a work containing the Program or a portion of it, -either verbatim or with modifications and/or translated into another -language. (Hereinafter, translation is included without limitation in -the term "modification".) Each licensee is addressed as "you". - -Activities other than copying, distribution and modification are not -covered by this License; they are outside its scope. The act of -running the Program is not restricted, and the output from the Program -is covered only if its contents constitute a work based on the -Program (independent of having been made by running the Program). -Whether that is true depends on what the Program does. - - 1. You may copy and distribute 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 and disclaimer of warranty; keep intact all the -notices that refer to this License and to the absence of any warranty; -and give any other recipients of the Program a copy of this License -along with the Program. - -You may charge a fee for the physical act of transferring a copy, and -you may at your option offer warranty protection in exchange for a fee. - - 2. You may modify your copy or copies of the Program or any portion -of it, thus forming a work based on the Program, and copy and -distribute such modifications or work under the terms of Section 1 -above, provided that you also meet all of these conditions: - - a) You must cause the modified files to carry prominent notices - stating that you changed the files and the date of any change. - - b) You must cause any work that you distribute or publish, that in - whole or in part contains or is derived from the Program or any - part thereof, to be licensed as a whole at no charge to all third - parties under the terms of this License. - - c) If the modified program normally reads commands interactively - when run, you must cause it, when started running for such - interactive use in the most ordinary way, to print or display an - announcement including an appropriate copyright notice and a - notice that there is no warranty (or else, saying that you provide - a warranty) and that users may redistribute the program under - these conditions, and telling the user how to view a copy of this - License. (Exception: if the Program itself is interactive but - does not normally print such an announcement, your work based on - the Program is not required to print an announcement.) - -These requirements apply to the modified work as a whole. If -identifiable sections of that work are not derived from the Program, -and can be reasonably considered independent and separate works in -themselves, then this License, and its terms, do not apply to those -sections when you distribute them as separate works. But when you -distribute the same sections as part of a whole which is a work based -on the Program, the distribution of the whole must be on the terms of -this License, whose permissions for other licensees extend to the -entire whole, and thus to each and every part regardless of who wrote it. - -Thus, it is not the intent of this section to claim rights or contest -your rights to work written entirely by you; rather, the intent is to -exercise the right to control the distribution of derivative or -collective works based on the Program. - -In addition, mere aggregation of another work not based on the Program -with the Program (or with a work based on the Program) on a volume of -a storage or distribution medium does not bring the other work under -the scope of this License. - - 3. You may copy and distribute the Program (or a work based on it, -under Section 2) in object code or executable form under the terms of -Sections 1 and 2 above provided that you also do one of the following: - - a) Accompany it with the complete corresponding machine-readable - source code, which must be distributed under the terms of Sections - 1 and 2 above on a medium customarily used for software interchange; or, - - b) Accompany it with a written offer, valid for at least three - years, to give any third party, for a charge no more than your - cost of physically performing source distribution, a complete - machine-readable copy of the corresponding source code, to be - distributed under the terms of Sections 1 and 2 above on a medium - customarily used for software interchange; or, - - c) Accompany it with the information you received as to the offer - to distribute corresponding source code. (This alternative is - allowed only for noncommercial distribution and only if you - received the program in object code or executable form with such - an offer, in accord with Subsection b above.) - -The source code for a work means the preferred form of the work for -making modifications to it. For an executable work, complete source -code means all the source code for all modules it contains, plus any -associated interface definition files, plus the scripts used to -control compilation and installation of the executable. However, as a -special exception, the source code distributed need not include -anything that is normally distributed (in either source or binary -form) with the major components (compiler, kernel, and so on) of the -operating system on which the executable runs, unless that component -itself accompanies the executable. - -If distribution of executable or object code is made by offering -access to copy from a designated place, then offering equivalent -access to copy the source code from the same place counts as -distribution of the source code, even though third parties are not -compelled to copy the source along with the object code. - - 4. You may not copy, modify, sublicense, or distribute the Program -except as expressly provided under this License. Any attempt -otherwise to copy, modify, sublicense or distribute the Program is -void, and will automatically terminate your rights under this License. -However, parties who have received copies, or rights, from you under -this License will not have their licenses terminated so long as such -parties remain in full compliance. - - 5. You are not required to accept this License, since you have not -signed it. However, nothing else grants you permission to modify or -distribute the Program or its derivative works. These actions are -prohibited by law if you do not accept this License. Therefore, by -modifying or distributing the Program (or any work based on the -Program), you indicate your acceptance of this License to do so, and -all its terms and conditions for copying, distributing or modifying -the Program or works based on it. - - 6. Each time you redistribute the Program (or any work based on the -Program), the recipient automatically receives a license from the -original licensor to copy, distribute or modify the Program subject to -these terms and conditions. You may not impose any further -restrictions on the recipients' exercise of the rights granted herein. -You are not responsible for enforcing compliance by third parties to -this License. - - 7. If, as a consequence of a court judgment or allegation of patent -infringement or for any other reason (not limited to patent issues), -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 -distribute so as to satisfy simultaneously your obligations under this -License and any other pertinent obligations, then as a consequence you -may not distribute the Program at all. For example, if a patent -license would not permit royalty-free redistribution of the Program by -all those who receive copies directly or indirectly through you, then -the only way you could satisfy both it and this License would be to -refrain entirely from distribution of the Program. - -If any portion of this section is held invalid or unenforceable under -any particular circumstance, the balance of the section is intended to -apply and the section as a whole is intended to apply in other -circumstances. - -It is not the purpose of this section to induce you to infringe any -patents or other property right claims or to contest validity of any -such claims; this section has the sole purpose of protecting the -integrity of the free software distribution system, which is -implemented by public license practices. Many people have made -generous contributions to the wide range of software distributed -through that system in reliance on consistent application of that -system; it is up to the author/donor to decide if he or she is willing -to distribute software through any other system and a licensee cannot -impose that choice. - -This section is intended to make thoroughly clear what is believed to -be a consequence of the rest of this License. - - 8. If the distribution and/or use of the Program is restricted in -certain countries either by patents or by copyrighted interfaces, the -original copyright holder who places the Program under this License -may add an explicit geographical distribution limitation excluding -those countries, so that distribution is permitted only in or among -countries not thus excluded. In such case, this License incorporates -the limitation as if written in the body of this License. - - 9. The Free Software Foundation may publish revised and/or new versions -of the 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 a version number of this License which applies to it and "any -later version", you have the option of following the terms and conditions -either of that version or of any later version published by the Free -Software Foundation. If the Program does not specify a version number of -this License, you may choose any version ever published by the Free Software -Foundation. - - 10. If you wish to incorporate parts of the Program into other free -programs whose distribution conditions are different, write to the author -to ask for permission. For software which is copyrighted by the Free -Software Foundation, write to the Free Software Foundation; we sometimes -make exceptions for this. Our decision will be guided by the two goals -of preserving the free status of all derivatives of our free software and -of promoting the sharing and reuse of software generally. - - NO WARRANTY - - 11. BECAUSE THE PROGRAM IS LICENSED FREE OF CHARGE, 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. - - 12. IN NO EVENT UNLESS REQUIRED BY APPLICABLE LAW OR AGREED TO IN WRITING -WILL ANY COPYRIGHT HOLDER, OR ANY OTHER PARTY WHO MAY MODIFY AND/OR -REDISTRIBUTE 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. - - END OF TERMS AND CONDITIONS diff --git a/intern/elbeem/extern/LBM_fluidsim.h b/intern/elbeem/extern/LBM_fluidsim.h deleted file mode 100644 index 256d8c59daa..00000000000 --- a/intern/elbeem/extern/LBM_fluidsim.h +++ /dev/null @@ -1,35 +0,0 @@ -/* - * 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 2 - * 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, write to the Free Software Foundation, - * Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. - * - * The Original Code is Copyright (C) Blender Foundation. - * All rights reserved. - */ - -/** \file - * \ingroup elbeem - */ - -#ifndef LBM_FLUIDSIM_H -#define LBM_FLUIDSIM_H - -/* note; elbeem.h was exported all over, should only expose LBM_fluidsim.h */ -#include "elbeem.h" - -/* run simulation with given config file */ -// implemented in intern/elbeem/blendercall.cpp -int performElbeemSimulation(char *cfgfilename); - - -#endif diff --git a/intern/elbeem/extern/elbeem.h b/intern/elbeem/extern/elbeem.h deleted file mode 100644 index 073055cf562..00000000000 --- a/intern/elbeem/extern/elbeem.h +++ /dev/null @@ -1,273 +0,0 @@ -/** \file - * \ingroup elbeem - */ -/****************************************************************************** - * - * El'Beem - Free Surface Fluid Simulation with the Lattice Boltzmann Method - * All code distributed as part of El'Beem is covered by the version 2 of the - * GNU General Public License. See the file COPYING for details. - * Copyright 2003-2006 Nils Thuerey - * - * API header - */ -#ifndef ELBEEM_API_H -#define ELBEEM_API_H - - -// simulation run callback function type (elbeemSimulationSettings->runsimCallback) -// best use with FLUIDSIM_CBxxx defines below. -// >parameters -// return values: 0=continue, 1=stop, 2=abort -// data pointer: user data pointer from elbeemSimulationSettings->runsimUserData -// status integer: 1=running simulation, 2=new frame saved -// frame integer: if status is 1, contains current frame number -typedef int (*elbeemRunSimulationCallback)(void *data, int status, int frame); -#define FLUIDSIM_CBRET_CONTINUE 0 -#define FLUIDSIM_CBRET_STOP 1 -#define FLUIDSIM_CBRET_ABORT 2 -#define FLUIDSIM_CBSTATUS_STEP 1 -#define FLUIDSIM_CBSTATUS_NEWFRAME 2 - - -// global settings for the simulation -typedef struct elbeemSimulationSettings { - /* version number */ - short version; - /* id number of simulation domain, needed if more than a - * single domain should be simulated */ - short domainId; // unused within blender - - /* geometrical extent */ - float geoStart[3], geoSize[3]; - - /* resolutions */ - short resolutionxyz; - short previewresxyz; - /* size of the domain in real units (meters along largest resolution x,y,z extent) */ - float realsize; - - /* fluid properties */ - double viscosity; - /* gravity strength */ - float gravity[3]; - /* anim start end time */ - float animStart, aniFrameTime; - /* no. of frames to simulate & output */ - short noOfFrames; - /* g star param (LBM compressibility) */ - float gstar; - /* activate refinement? */ - short maxRefine; - /* probability for surface particle generation (0.0=off) */ - float generateParticles; - /* amount of tracer particles to generate (0=off) */ - int numTracerParticles; - - /* store output path, and file prefix for baked fluid surface */ - char outputPath[160+80]; - - /* channel for frame time, visc & gravity animations */ - int channelSizeFrameTime; - float *channelFrameTime; - int channelSizeViscosity; - float *channelViscosity; - int channelSizeGravity; - float *channelGravity; // vector - - /* boundary types and settings for domain walls */ - short domainobsType; - float domainobsPartslip; - - /* what surfaces to generate */ - int mFsSurfGenSetting; - - /* generate speed vectors for vertices (e.g. for image based motion blur)*/ - short generateVertexVectors; - /* strength of surface smoothing */ - float surfaceSmoothing; - /* no. of surface subdivisions */ - int surfaceSubdivs; - - /* global transformation to apply to fluidsim mesh */ - float surfaceTrafo[4*4]; - - /* development variables, testing for upcoming releases...*/ - float farFieldSize; - - /* callback function to notify calling program of performed simulation steps - * or newly available frame data, if NULL it is ignored */ - elbeemRunSimulationCallback runsimCallback; - /* pointer passed to runsimCallback for user data storage */ - void* runsimUserData; - /* simulation threads used by omp */ - int threads; - -} elbeemSimulationSettings; - - -// defines for elbeemMesh->type below -/* please keep in sync with DNA_object_fluidsim_types.h */ -#define OB_FLUIDSIM_FLUID 4 -#define OB_FLUIDSIM_OBSTACLE 8 -#define OB_FLUIDSIM_INFLOW 16 -#define OB_FLUIDSIM_OUTFLOW 32 -#define OB_FLUIDSIM_PARTICLE 64 -#define OB_FLUIDSIM_CONTROL 128 - -// defines for elbeemMesh->obstacleType below (low bits) high bits (>=64) are reserved for mFsSurfGenSetting flags which are defined in solver_class.h -#define FLUIDSIM_OBSTACLE_NOSLIP 1 -#define FLUIDSIM_OBSTACLE_PARTSLIP 2 -#define FLUIDSIM_OBSTACLE_FREESLIP 3 -#define FLUIDSIM_FSSG_NOOBS 64 - - -#define OB_VOLUMEINIT_VOLUME 1 -#define OB_VOLUMEINIT_SHELL 2 -#define OB_VOLUMEINIT_BOTH (OB_VOLUMEINIT_SHELL|OB_VOLUMEINIT_VOLUME) - -// a single mesh object -typedef struct elbeemMesh { - /* obstacle,fluid or inflow or control ... */ - short type; - /* id of simulation domain it belongs to */ - short parentDomainId; - - /* vertices */ - int numVertices; - float *vertices; // = float[n][3]; - /* animated vertices */ - int channelSizeVertices; - float *channelVertices; // = float[channelSizeVertices* (n*3+1) ]; - - /* triangles */ - int numTriangles; - int *triangles; // = int[][3]; - - /* animation channels */ - int channelSizeTranslation; - float *channelTranslation; - int channelSizeRotation; - float *channelRotation; - int channelSizeScale; - float *channelScale; - - /* active channel */ - int channelSizeActive; - float *channelActive; - /* initial velocity channel (e.g. for inflow) */ - int channelSizeInitialVel; - float *channelInitialVel; // vector - /* use initial velocity in object coordinates? (e.g. for rotation) */ - short localInivelCoords; - /* boundary types and settings */ - short obstacleType; - float obstaclePartslip; - /* amount of force transfer from fluid to obj, 0=off, 1=normal */ - float obstacleImpactFactor; - /* init volume, shell or both? use OB_VOLUMEINIT_xxx defines above */ - short volumeInitType; - - /* name of the mesh, mostly for debugging */ - const char *name; - - /* fluid control settings */ - float cpsTimeStart; - float cpsTimeEnd; - float cpsQuality; - - int channelSizeAttractforceStrength; - float *channelAttractforceStrength; - int channelSizeAttractforceRadius; - float *channelAttractforceRadius; - int channelSizeVelocityforceStrength; - float *channelVelocityforceStrength; - int channelSizeVelocityforceRadius; - float *channelVelocityforceRadius; -} elbeemMesh; - -// API functions - -#ifdef __cplusplus -extern "C" { -#endif // __cplusplus - - -// reset elbeemSimulationSettings struct with defaults -void elbeemResetSettings(struct elbeemSimulationSettings*); - -// start fluidsim init (returns !=0 upon failure) -int elbeemInit(void); - -// frees fluidsim -int elbeemFree(void); - -// start fluidsim init (returns !=0 upon failure) -int elbeemAddDomain(struct elbeemSimulationSettings*); - -// get failure message during simulation or init -// if an error occured (the string is copied into buffer, -// max. length = 256 chars ) -void elbeemGetErrorString(char *buffer); - -// reset elbeemMesh struct with zeroes -void elbeemResetMesh(struct elbeemMesh*); - -// add mesh as fluidsim object -int elbeemAddMesh(struct elbeemMesh*); - -// do the actual simulation -int elbeemSimulate(void); - -// continue a previously stopped simulation -int elbeemContinueSimulation(void); - - -// helper functions - -// simplify animation channels -// returns if the channel and its size changed -int elbeemSimplifyChannelFloat(float *channel, int *size); -int elbeemSimplifyChannelVec3(float *channel, int *size); - -// helper functions implemented in utilities.cpp - -/* set elbeem debug output level (0=off to 10=full on) */ -void elbeemSetDebugLevel(int level); -/* elbeem debug output function, prints if debug level >0 */ -void elbeemDebugOut(char *msg); - -/* estimate how much memory a given setup will require */ -double elbeemEstimateMemreq(int res, - float sx, float sy, float sz, - int refine, char *retstr); - - - -#ifdef __cplusplus -} -#endif // __cplusplus - - - -/******************************************************************************/ -// internal defines, do not use for initializing elbeemMesh -// structs, for these use OB_xxx defines above - -/*! fluid geometry init types */ -// type "int" used, so max is 8 -#define FGI_FLAGSTART 16 -#define FGI_FLUID (1<<(FGI_FLAGSTART+ 0)) -#define FGI_NO_FLUID (1<<(FGI_FLAGSTART+ 1)) -#define FGI_BNDNO (1<<(FGI_FLAGSTART+ 2)) -#define FGI_BNDFREE (1<<(FGI_FLAGSTART+ 3)) -#define FGI_BNDPART (1<<(FGI_FLAGSTART+ 4)) -#define FGI_NO_BND (1<<(FGI_FLAGSTART+ 5)) -#define FGI_MBNDINFLOW (1<<(FGI_FLAGSTART+ 6)) -#define FGI_MBNDOUTFLOW (1<<(FGI_FLAGSTART+ 7)) -#define FGI_CONTROL (1<<(FGI_FLAGSTART+ 8)) - -// all boundary types at once -#define FGI_ALLBOUNDS ( FGI_BNDNO | FGI_BNDFREE | FGI_BNDPART | FGI_MBNDINFLOW | FGI_MBNDOUTFLOW ) - - -#endif // ELBEEM_API_H diff --git a/intern/elbeem/intern/attributes.cpp b/intern/elbeem/intern/attributes.cpp deleted file mode 100644 index beebc459c1a..00000000000 --- a/intern/elbeem/intern/attributes.cpp +++ /dev/null @@ -1,362 +0,0 @@ -/** \file - * \ingroup elbeem - */ -/****************************************************************************** - * - * El'Beem - Free Surface Fluid Simulation with the Lattice Boltzmann Method - * Copyright 2003-2006 Nils Thuerey - * - * DEPRECATED - replaced by elbeem API, only channels are still used - * - *****************************************************************************/ - -#include "attributes.h" -#include "ntl_matrices.h" -#include "elbeem.h" - - - -/****************************************************************************** - * attribute conversion functions - *****************************************************************************/ - -bool Attribute::initChannel(int elemSize) { - elemSize=0; // remove warning - return false; -} -string Attribute::getAsString(bool debug) { - debug=false; // remove warning - return string(""); -} -int Attribute::getAsInt() { - return 0; -} -bool Attribute::getAsBool() { - return false; -} -double Attribute::getAsFloat() { - return 0.; -} -ntlVec3d Attribute::getAsVec3d() { - return ntlVec3d(0.); -} -void Attribute::getAsMat4Gfx(ntlMat4Gfx *mat) { - mat=NULL; // remove warning -} -string Attribute::getCompleteString() { - return string(""); -} - - -/****************************************************************************** - * channel returns - *****************************************************************************/ - -AnimChannel<double> Attribute::getChannelFloat() { - return AnimChannel<double>(); -} -AnimChannel<int> Attribute::getChannelInt() { - return AnimChannel<int>(); -} -AnimChannel<ntlVec3d> Attribute::getChannelVec3d() { - return AnimChannel<ntlVec3d>(); -} -AnimChannel<ntlSetVec3f> -Attribute::getChannelSetVec3f() { - return AnimChannel<ntlSetVec3f>(); -} - -/****************************************************************************** - * check if there were unknown params - *****************************************************************************/ -bool AttributeList::checkUnusedParams() { - return false; -} -void AttributeList::setAllUsed() { -} - -/****************************************************************************** - * Attribute list read functions - *****************************************************************************/ -int AttributeList::readInt(string name, int defaultValue, string source,string target, bool needed) { - name=source=target=string(""); needed=false; // remove warning - return defaultValue; -} -bool AttributeList::readBool(string name, bool defaultValue, string source,string target, bool needed) { - name=source=target=string(""); needed=false; // remove warning - return defaultValue; -} -double AttributeList::readFloat(string name, double defaultValue, string source,string target, bool needed) { - name=source=target=string(""); needed=false; // remove warning - return defaultValue; -} -string AttributeList::readString(string name, string defaultValue, string source,string target, bool needed) { - name=source=target=string(""); needed=false; // remove warning - return defaultValue; -} -ntlVec3d AttributeList::readVec3d(string name, ntlVec3d defaultValue, string source,string target, bool needed) { - name=source=target=string(""); needed=false; // remove warning - return defaultValue; -} - -void AttributeList::readMat4Gfx(string name, ntlMat4Gfx defaultValue, string source,string target, bool needed, ntlMat4Gfx *mat) { - *mat = defaultValue; - name=source=target=string(""); needed=false; mat=NULL; // remove warning -} - -// set that a parameter can be given, and will be ignored... -bool AttributeList::ignoreParameter(string name, string source) { - name = source = (""); - return false; -} - -// read channels -AnimChannel<int> AttributeList::readChannelInt(string name, int defaultValue, string source, string target, bool needed) { - name=source=target=string(""); needed=false; // remove warning - return AnimChannel<int>(defaultValue); -} -AnimChannel<double> AttributeList::readChannelFloat(string name, double defaultValue, string source, string target, bool needed ) { - name=source=target=string(""); needed=false; // remove warning - return AnimChannel<double>(defaultValue); -} -AnimChannel<ntlVec3d> AttributeList::readChannelVec3d(string name, ntlVec3d defaultValue, string source, string target, bool needed ) { - name=source=target=string(""); needed=false; // remove warning - return AnimChannel<ntlVec3d>(defaultValue); -} -AnimChannel<ntlSetVec3f> AttributeList::readChannelSetVec3f(string name, ntlSetVec3f defaultValue, string source, string target, bool needed) { - name=source=target=string(""); needed=false; // remove warning - return AnimChannel<ntlSetVec3f>(defaultValue); -} -AnimChannel<float> AttributeList::readChannelSinglePrecFloat(string name, float defaultValue, string source, string target, bool needed ) { - name=source=target=string(""); needed=false; // remove warning - return AnimChannel<float>(defaultValue); -} -AnimChannel<ntlVec3f> AttributeList::readChannelVec3f(string name, ntlVec3f defaultValue, string source, string target, bool needed) { - name=source=target=string(""); needed=false; // remove warning - return AnimChannel<ntlVec3f>(defaultValue); -} - -/****************************************************************************** - * destructor - *****************************************************************************/ -AttributeList::~AttributeList() { -}; - - -/****************************************************************************** - * debugging - *****************************************************************************/ - -//! debug function, prints value -void Attribute::print() { -} - -//! debug function, prints all attribs -void AttributeList::print() { -} - - -/****************************************************************************** - * import attributes from other attribute list - *****************************************************************************/ -void AttributeList::import(AttributeList *oal) { - oal=NULL; // remove warning -} - - -/****************************************************************************** - * channel max finding - *****************************************************************************/ -ntlVec3f channelFindMaxVf (AnimChannel<ntlVec3f> channel) { - ntlVec3f ret(0.0); - float maxLen = 0.0; - for(size_t i=0; i<channel.accessValues().size(); i++) { - float nlen = normNoSqrt(channel.accessValues()[i]); - if(nlen>maxLen) { ret=channel.accessValues()[i]; maxLen=nlen; } - } - return ret; -} -ntlVec3d channelFindMaxVd (AnimChannel<ntlVec3d> channel) { - ntlVec3d ret(0.0); - float maxLen = 0.0; - for(size_t i=0; i<channel.accessValues().size(); i++) { - float nlen = normNoSqrt(channel.accessValues()[i]); - if(nlen>maxLen) { ret=channel.accessValues()[i]; maxLen=nlen; } - } - return ret; -} -int channelFindMaxi (AnimChannel<float > channel) { - int ret = 0; - float maxLen = 0.0; - for(size_t i=0; i<channel.accessValues().size(); i++) { - float nlen = ABS(channel.accessValues()[i]); - if(nlen>maxLen) { ret= (int)channel.accessValues()[i]; maxLen=nlen; } - } - return ret; -} -float channelFindMaxf (AnimChannel<float > channel) { - float ret = 0.0; - float maxLen = 0.0; - for(size_t i=0; i<channel.accessValues().size(); i++) { - float nlen = ABS(channel.accessValues()[i]); - if(nlen>maxLen) { ret=channel.accessValues()[i]; maxLen=nlen; } - } - return ret; -} -double channelFindMaxd (AnimChannel<double > channel) { - double ret = 0.0; - float maxLen = 0.0; - for(size_t i=0; i<channel.accessValues().size(); i++) { - float nlen = ABS(channel.accessValues()[i]); - if(nlen>maxLen) { ret=channel.accessValues()[i]; maxLen=nlen; } - } - return ret; -} - -/****************************************************************************** - // unoptimized channel simplification functions, use elbeem.cpp functions - // warning - currently only with single precision - *****************************************************************************/ - -template<class SCALAR> -static bool channelSimplifyScalarT(AnimChannel<SCALAR> &channel) { - int size = channel.getSize(); - if(size<=1) return false; - float *nchannel = new float[2*size]; - // convert to array - for(size_t i=0; i<channel.accessValues().size(); i++) { - nchannel[i*2 + 0] = (float)channel.accessValues()[i]; - nchannel[i*2 + 1] = (float)channel.accessTimes()[i]; - } - bool ret = elbeemSimplifyChannelFloat(nchannel, &size); - if(ret) { - vector<SCALAR> vals; - vector<double> times; - for(int i=0; i<size; i++) { - vals.push_back( (SCALAR)(nchannel[i*2 + 0]) ); - times.push_back( (double)(nchannel[i*2 + 1]) ); - } - channel = AnimChannel<SCALAR>(vals, times); - } - delete [] nchannel; - return ret; -} -bool channelSimplifyi (AnimChannel<int > &channel) { return channelSimplifyScalarT<int>(channel); } -bool channelSimplifyf (AnimChannel<float> &channel) { return channelSimplifyScalarT<float>(channel); } -bool channelSimplifyd (AnimChannel<double > &channel) { return channelSimplifyScalarT<double>(channel); } -template<class VEC> -static bool channelSimplifyVecT(AnimChannel<VEC> &channel) { - int size = channel.getSize(); - if(size<=1) return false; - float *nchannel = new float[4*size]; - // convert to array - for(size_t i=0; i<channel.accessValues().size(); i++) { - nchannel[i*4 + 0] = (float)channel.accessValues()[i][0]; - nchannel[i*4 + 1] = (float)channel.accessValues()[i][1]; - nchannel[i*4 + 2] = (float)channel.accessValues()[i][2]; - nchannel[i*4 + 3] = (float)channel.accessTimes()[i]; - } - bool ret = elbeemSimplifyChannelVec3(nchannel, &size); - if(ret) { - vector<VEC> vals; - vector<double> times; - for(int i=0; i<size; i++) { - vals.push_back( VEC(nchannel[i*4 + 0], nchannel[i*4 + 1], nchannel[i*4 + 2] ) ); - times.push_back( (double)(nchannel[i*4 + 3]) ); - } - channel = AnimChannel<VEC>(vals, times); - } - delete [] nchannel; - return ret; -} -bool channelSimplifyVf (AnimChannel<ntlVec3f> &channel) { - return channelSimplifyVecT<ntlVec3f>(channel); -} -bool channelSimplifyVd (AnimChannel<ntlVec3d> &channel) { - return channelSimplifyVecT<ntlVec3d>(channel); -} - -//! debug function, prints channel as string -template<class Scalar> -string AnimChannel<Scalar>::printChannel() { - std::ostringstream ostr; - ostr << " CHANNEL #"<< mValue.size() <<" = { "; - for(size_t i=0;i<mValue.size();i++) { - ostr <<"'"<< mValue[i]<<"' "; - ostr << "@"<<mTimes[i]<<"; "; - } - ostr << " } "; - return ostr.str(); -} // */ - -// is now in header file: debugPrintChannel() -// hack to force instantiation -void __forceAnimChannelInstantiation() { - AnimChannel< float > tmp1; - AnimChannel< double > tmp2; - AnimChannel< string > tmp3; - AnimChannel< ntlVector3Dim<float> > tmp4; - AnimChannel< ntlVector3Dim<double> > tmp5; - tmp1.debugPrintChannel(); - tmp2.debugPrintChannel(); - tmp3.debugPrintChannel(); - tmp4.debugPrintChannel(); - tmp5.debugPrintChannel(); -} - - -ntlSetVec3f::ntlSetVec3f(double v ) { - mVerts.clear(); - mVerts.push_back( ntlVec3f(v) ); -} -const ntlSetVec3f& -ntlSetVec3f::operator=(double v ) { - mVerts.clear(); - mVerts.push_back( ntlVec3f(v) ); - return *this; -} - -std::ostream& operator<<( std::ostream& os, const ntlSetVec3f& vs ) { - os<< "{"; - for(int j=0;j<(int)vs.mVerts.size();j++) os<<vs.mVerts[j]; - os<< "}"; - return os; -} - -ntlSetVec3f& -ntlSetVec3f::operator+=( double v ) -{ - for(int j=0;j<(int)(mVerts.size()) ;j++) { - mVerts[j] += v; - } - return *this; -} - -ntlSetVec3f& -ntlSetVec3f::operator+=( const ntlSetVec3f &v ) -{ - for(int j=0;j<(int)MIN(mVerts.size(),v.mVerts.size()) ;j++) { - mVerts[j] += v.mVerts[j]; - } - return *this; -} - -ntlSetVec3f& -ntlSetVec3f::operator*=( double v ) -{ - for(int j=0;j<(int)(mVerts.size()) ;j++) { - mVerts[j] *= v; - } - return *this; -} - -ntlSetVec3f& -ntlSetVec3f::operator*=( const ntlSetVec3f &v ) -{ - for(int j=0;j<(int)MIN(mVerts.size(),v.mVerts.size()) ;j++) { - mVerts[j] *= v.mVerts[j]; - } - return *this; -} - - diff --git a/intern/elbeem/intern/attributes.h b/intern/elbeem/intern/attributes.h deleted file mode 100644 index 2d3b85887f5..00000000000 --- a/intern/elbeem/intern/attributes.h +++ /dev/null @@ -1,248 +0,0 @@ -/** \file - * \ingroup elbeem - */ -/****************************************************************************** - * - * El'Beem - Free Surface Fluid Simulation with the Lattice Boltzmann Method - * Copyright 2003-2006 Nils Thuerey - * - * DEPRECATED - replaced by elbeem API, only channels are still used - * - *****************************************************************************/ - - -#ifndef NTL_ATTRIBUTES_H - -#include "utilities.h" - -#ifdef WITH_CXX_GUARDEDALLOC -# include "MEM_guardedalloc.h" -#endif - -template<class T> class ntlMatrix4x4; -class ntlSetVec3f; -std::ostream& operator<<( std::ostream& os, const ntlSetVec3f& i ); - - - -//! An animated attribute channel -template<class Scalar> -class AnimChannel -{ - public: - // default constructor - AnimChannel() : - mValue(), mTimes() { mInited = false; debugPrintChannel(); } - - // null init constructor - AnimChannel(Scalar null) : - mValue(1), mTimes(1) { mValue[0]=null; mTimes[0]=0.0; mInited = true; debugPrintChannel(); } - - // proper init - AnimChannel(vector<Scalar> &v, vector<double> &t) : - mValue(v), mTimes(t) { mInited = true; debugPrintChannel(); } - - // desctructor, nothing to do - ~AnimChannel() { }; - - // get interpolated value at time t - Scalar get(double t) const { - if(!mInited) { Scalar null; null=(Scalar)(0.0); return null; } - if(t<=mTimes[0]) { return mValue[0]; } - if(t>=mTimes[mTimes.size()-1]) { return mValue[mTimes.size()-1]; } - for(size_t i=0; i<mTimes.size()-1; i++) { - // find first time thats in between - if((mTimes[i]<=t)&&(mTimes[i+1]>t)) { - // interpolate - double d = mTimes[i+1]-mTimes[i]; - double f = (t-mTimes[i])/d; - //return (Scalar)(mValue[i] * (1.0-f) + mValue[i+1] * f); - Scalar ret,tmp; - ret = mValue[i]; - ret *= 1.-f; - tmp = mValue[i+1]; - tmp *= f; - ret += tmp; - return ret; - } - } - // whats this...? - return mValue[0]; - }; - - // get uninterpolated value at time t - Scalar getConstant(double t) const { - //errMsg("DEBB","getc"<<t<<" "); - if(!mInited) { Scalar null; null=(Scalar)0.0; return null; } - if(t<=mTimes[0]) { return mValue[0]; } - if(t>=mTimes[mTimes.size()-1]) { return mValue[mTimes.size()-1]; } - for(size_t i=0; i<mTimes.size()-1; i++) { - //errMsg("DEBB","getc i"<<i<<" "<<mTimes[i]); - // find first time thats in between - if((mTimes[i]<=t)&&(mTimes[i+1]>t)) { return mValue[i]; } - } - // whats this...? - return mValue[0]; - }; - - // reset to null value - void reset(Scalar null) { - mValue.clear(); - mTimes.clear(); - mValue.push_back(null); - mTimes.push_back(0.0); - } - - //! debug function, prints channel as string - string printChannel(); - //! debug function, prints to stdout if DEBUG_CHANNELS flag is enabled, used in constructors - void debugPrintChannel(); - //! valid init? - bool isInited() const { return mInited; } - - //! get number of entries (value and time sizes have to be equal) - int getSize() const { return mValue.size(); }; - //! raw access of value vector - vector<Scalar> &accessValues() { return mValue; } - //! raw access of time vector - vector<double> &accessTimes() { return mTimes; } - - protected: - - /*! inited at least once? */ - bool mInited; - /*! anim channel attribute values */ - vector<Scalar> mValue; - /*! anim channel attr times */ - vector<double> mTimes; - -private: -#ifdef WITH_CXX_GUARDEDALLOC - MEM_CXX_CLASS_ALLOC_FUNCS("ELBEEM:AnimChannel") -#endif -}; - - -// helper class (not templated) for animated meshes -class ntlSetVec3f { - public: - ntlSetVec3f(): mVerts() {}; - ntlSetVec3f(double v); - ntlSetVec3f(vector<ntlVec3f> &v) { mVerts = v; }; - - const ntlSetVec3f& operator=(double v ); - ntlSetVec3f& operator+=( double v ); - ntlSetVec3f& operator+=( const ntlSetVec3f &v ); - ntlSetVec3f& operator*=( double v ); - ntlSetVec3f& operator*=( const ntlSetVec3f &v ); - - vector<ntlVec3f> mVerts; - -private: -#ifdef WITH_CXX_GUARDEDALLOC - MEM_CXX_CLASS_ALLOC_FUNCS("ELBEEM:ntlSetVec3f") -#endif -}; - - -// warning: DEPRECATED - replaced by elbeem API -class Attribute -{ - public: - Attribute(string mn, vector<string> &value, int setline,bool channel) { - mn = string(""); setline=0; channel=false; value.clear(); // remove warnings - }; - Attribute(Attribute &a) { a.getCompleteString(); }; - ~Attribute() { }; - - void setUsed(bool set){ set=false; } - bool getUsed() { return true; } - void setIsChannel(bool set){ set=false; } - bool getIsChannel() { return false; } - - string getAsString(bool debug=false); - int getAsInt(); - bool getAsBool(); - double getAsFloat(); - ntlVec3d getAsVec3d(); - void getAsMat4Gfx(ntlMatrix4x4<gfxReal> *mat); - - AnimChannel<int> getChannelInt(); - AnimChannel<double> getChannelFloat(); - AnimChannel<ntlVec3d> getChannelVec3d(); - AnimChannel<ntlSetVec3f> getChannelSetVec3f(); - - string getCompleteString(); - void print(); - - protected: - - bool initChannel(int elemSize); - -private: -#ifdef WITH_CXX_GUARDEDALLOC - MEM_CXX_CLASS_ALLOC_FUNCS("ELBEEM:Attribute") -#endif -}; - - -// warning: DEPRECATED - replaced by elbeem API -//! The list of configuration attributes -class AttributeList -{ - public: - AttributeList(string name) { name=string(""); }; - ~AttributeList(); - void addAttr(string name, vector<string> &value, int line, bool isChannel) { - name=string(""); value.clear(); line=0; isChannel=false; // remove warnings - }; - bool exists(string name) { name=string(""); return false; } - void setAllUsed(); - bool checkUnusedParams(); - void import(AttributeList *oal); - int readInt(string name, int defaultValue, string source,string target, bool needed); - bool readBool(string name, bool defaultValue, string source,string target, bool needed); - double readFloat(string name, double defaultValue, string source,string target, bool needed); - string readString(string name, string defaultValue, string source,string target, bool needed); - ntlVec3d readVec3d(string name, ntlVec3d defaultValue, string source,string target, bool needed); - void readMat4Gfx(string name, ntlMatrix4x4<gfxReal> defaultValue, string source,string target, bool needed, ntlMatrix4x4<gfxReal> *mat); - AnimChannel<int> readChannelInt( string name, int defaultValue=0, string source=string("src"), string target=string("dst"), bool needed=false ); - AnimChannel<double> readChannelFloat( string name, double defaultValue=0, string source=string("src"), string target=string("dst"), bool needed=false ); - AnimChannel<ntlVec3d> readChannelVec3d( string name, ntlVec3d defaultValue=ntlVec3d(0.), string source=string("src"), string target=string("dst"), bool needed=false ); - AnimChannel<ntlSetVec3f> readChannelSetVec3f(string name, ntlSetVec3f defaultValue=ntlSetVec3f(0.), string source=string("src"), string target=string("dst"), bool needed=false ); - AnimChannel<ntlVec3f> readChannelVec3f( string name, ntlVec3f defaultValue=ntlVec3f(0.), string source=string("src"), string target=string("dst"), bool needed=false ); - AnimChannel<float> readChannelSinglePrecFloat( string name, float defaultValue=0., string source=string("src"), string target=string("dst"), bool needed=false ); - bool ignoreParameter(string name, string source); - void print(); - protected: - -private: -#ifdef WITH_CXX_GUARDEDALLOC - MEM_CXX_CLASS_ALLOC_FUNCS("ELBEEM:AttributeList") -#endif -}; - -ntlVec3f channelFindMaxVf (AnimChannel<ntlVec3f> channel); -ntlVec3d channelFindMaxVd (AnimChannel<ntlVec3d> channel); -int channelFindMaxi (AnimChannel<int > channel); -float channelFindMaxf (AnimChannel<float > channel); -double channelFindMaxd (AnimChannel<double > channel); - -// unoptimized channel simplification functions, use elbeem.cpp functions -bool channelSimplifyVf (AnimChannel<ntlVec3f> &channel); -bool channelSimplifyVd (AnimChannel<ntlVec3d> &channel); -bool channelSimplifyi (AnimChannel<int > &channel); -bool channelSimplifyf (AnimChannel<float > &channel); -bool channelSimplifyd (AnimChannel<double > &channel); - -//! output channel values? on=1/off=0 -#define DEBUG_PCHANNELS 0 - -//! debug function, prints to stdout if DEBUG_PCHANNELS flag is enabled, used in constructors -template<class Scalar> -void AnimChannel<Scalar>::debugPrintChannel() { } - - -#define NTL_ATTRIBUTES_H -#endif - diff --git a/intern/elbeem/intern/controlparticles.cpp b/intern/elbeem/intern/controlparticles.cpp deleted file mode 100644 index efecb354890..00000000000 --- a/intern/elbeem/intern/controlparticles.cpp +++ /dev/null @@ -1,1465 +0,0 @@ -/** \file - * \ingroup elbeem - */ -// -------------------------------------------------------------------------- -// -// El'Beem - the visual lattice boltzmann freesurface simulator -// All code distributed as part of El'Beem is covered by the version 2 of the -// GNU General Public License. See the file COPYING for details. -// -// Copyright 2008 Nils Thuerey , Richard Keiser, Mark Pauly, Ulrich Ruede -// -// implementation of control particle handling -// -// -------------------------------------------------------------------------- - -// indicator for LBM inclusion -#include "ntl_geometrymodel.h" -#include "ntl_world.h" -#include "solver_class.h" -#include "controlparticles.h" -#include "mvmcoords.h" -#include <zlib.h> - -#ifndef sqrtf -#define sqrtf sqrt -#endif - -// brute force circle test init in initTimeArray -// replaced by mDebugInit -//#define CP_FORCECIRCLEINIT 0 - - -void ControlParticles::initBlenderTest() { - mPartSets.clear(); - - ControlParticleSet cps; - mPartSets.push_back(cps); - int setCnt = mPartSets.size()-1; - ControlParticle p; - - // set for time zero - mPartSets[setCnt].time = 0.; - - // add single particle - p.reset(); - p.pos = LbmVec(0.5, 0.5, -0.5); - mPartSets[setCnt].particles.push_back(p); - - // add second set for animation - mPartSets.push_back(cps); - setCnt = mPartSets.size()-1; - mPartSets[setCnt].time = 0.15; - - // insert new position - p.reset(); - p.pos = LbmVec(-0.5, -0.5, 0.5); - mPartSets[setCnt].particles.push_back(p); - - // applyTrafos(); - initTime(0. , 1.); -} - -// blender control object gets converted to mvm flui control object -int ControlParticles::initFromObject(ntlGeometryObjModel *model) { - vector<ntlTriangle> triangles; - vector<ntlVec3Gfx> vertices; - vector<ntlVec3Gfx> normals; - - /* - model->loadBobjModel(string(infile)); - - model->setLoaded(true); - - model->setGeoInitId(gid); - - - printf("a animated? %d\n", model->getIsAnimated()); - printf("b animated? %d\n", model->getMeshAnimated()); - */ - - model->setGeoInitType(FGI_FLUID); - - model->getTriangles(mCPSTimeStart, &triangles, &vertices, &normals, 1 ); - // model->applyTransformation(mCPSTimeStart, &vertices, &normals, 0, vertices.size(), true); - - // valid mesh? - if(triangles.size() <= 0) { - return 0; - } - - ntlRenderGlobals *glob = new ntlRenderGlobals; - ntlScene *genscene = new ntlScene( glob, false ); - genscene->addGeoClass(model); - genscene->addGeoObject(model); - genscene->buildScene(0., false); - char treeFlag = (1<<(4+model->getGeoInitId())); - - ntlTree *tree = new ntlTree( - 15, 8, // TREEwarning - fixed values for depth & maxtriangles here... - genscene, treeFlag ); - - // TODO? use params - ntlVec3Gfx start,end; - model->getExtends(start,end); - /* - printf("start - x: %f, y: %f, z: %f\n", start[0], start[1], start[2]); - printf("end - x: %f, y: %f, z: %f\n", end[0], end[1], end[2]); - printf("mCPSWidth: %f\n"); -*/ - LbmFloat width = mCPSWidth; - if(width<=LBM_EPSILON) { errMsg("ControlParticles::initFromMVMCMesh","Invalid mCPSWidth! "<<mCPSWidth); width=mCPSWidth=0.1; } - ntlVec3Gfx org = start+ntlVec3Gfx(width*0.5); - gfxReal distance = -1.; - vector<ntlVec3Gfx> inspos; - - // printf("distance: %f, width: %f\n", distance, width); - - while(org[2]<end[2]) { - while(org[1]<end[1]) { - while(org[0]<end[0]) { - if(checkPointInside(tree, org, distance)) { - inspos.push_back(org); - } - // TODO optimize, use distance - org[0] += width; - } - org[1] += width; - org[0] = start[0]; - } - org[2] += width; - org[1] = start[1]; - } - - // printf("inspos.size(): %d\n", inspos.size()); - - MeanValueMeshCoords mvm; - mvm.calculateMVMCs(vertices,triangles, inspos, mCPSWeightFac); - vector<ntlVec3Gfx> ninspos; - mvm.transfer(vertices, ninspos); - - // init first set, check dist - ControlParticleSet firstcps; //T - mPartSets.push_back(firstcps); - mPartSets[mPartSets.size()-1].time = mCPSTimeStart; - vector<bool> useCP; - - for(int i=0; i<(int)inspos.size(); i++) { - ControlParticle p; p.reset(); - p.pos = vec2L(inspos[i]); - - bool usecpv = true; - - mPartSets[mPartSets.size()-1].particles.push_back(p); - useCP.push_back(usecpv); - } - - // init further sets, temporal mesh sampling - double tsampling = mCPSTimestep; - // printf("tsampling: %f, ninspos.size(): %d, mCPSTimeEnd: %f\n", tsampling, ninspos.size(), mCPSTimeEnd); - - int tcnt=0; - for(double t=mCPSTimeStart+tsampling; ((t<mCPSTimeEnd) && (ninspos.size()>0.)); t+=tsampling) { - ControlParticleSet nextcps; //T - mPartSets.push_back(nextcps); - mPartSets[mPartSets.size()-1].time = (gfxReal)t; - - vertices.clear(); triangles.clear(); normals.clear(); - model->getTriangles(t, &triangles, &vertices, &normals, 1 ); - mvm.transfer(vertices, ninspos); - - tcnt++; - for(size_t i=0; i < ninspos.size(); i++) { - - if(useCP[i]) { - ControlParticle p; p.reset(); - p.pos = vec2L(ninspos[i]); - mPartSets[mPartSets.size()-1].particles.push_back(p); - } - } - } - - model->setGeoInitType(FGI_CONTROL); - - delete tree; - delete genscene; - delete glob; - - // do reverse here - if(model->getGeoPartSlipValue()) - { - mirrorTime(); - } - - return 1; -} - - -// init all zero / defaults for a single particle -void ControlParticle::reset() { - pos = LbmVec(0.,0.,0.); - vel = LbmVec(0.,0.,0.); - influence = 1.; - size = 1.; -#ifndef LBMDIM -#ifdef MAIN_2D - rotaxis = LbmVec(0.,1.,0.); // SPH xz -#else // MAIN_2D - // 3d - roate in xy plane, vortex - rotaxis = LbmVec(0.,0.,1.); - // 3d - rotate for wave - //rotaxis = LbmVec(0.,1.,0.); -#endif // MAIN_2D -#else // LBMDIM - rotaxis = LbmVec(0.,1.,0.); // LBM xy , is swapped afterwards -#endif // LBMDIM - - density = 0.; - densityWeight = 0.; - avgVelAcc = avgVel = LbmVec(0.); - avgVelWeight = 0.; -} - - -// default preset/empty init -ControlParticles::ControlParticles() : - _influenceTangential(0.f), - _influenceAttraction(0.f), - _influenceVelocity(0.f), - _influenceMaxdist(0.f), - _radiusAtt(1.0f), - _radiusVel(1.0f), - _radiusMinMaxd(2.0f), - _radiusMaxd(3.0f), - _currTime(-1.0), _currTimestep(1.), - _initTimeScale(1.), - _initPartOffset(0.), _initPartScale(1.), - _initLastPartOffset(0.), _initLastPartScale(1.), - _initMirror(""), - _fluidSpacing(1.), _kernelWeight(-1.), - _charLength(1.), _charLengthInv(1.), - mvCPSStart(-10000.), mvCPSEnd(10000.), - mCPSWidth(0.1), mCPSTimestep(0.02), // was 0.05 - mCPSTimeStart(0.), mCPSTimeEnd(0.5), mCPSWeightFac(1.), - mDebugInit(0) -{ - _radiusAtt = 0.15f; - _radiusVel = 0.15f; - _radiusMinMaxd = 0.16f; - _radiusMaxd = 0.3; - - _influenceAttraction = 0.f; - _influenceTangential = 0.f; - _influenceVelocity = 0.f; - // 3d tests */ -} - - - -ControlParticles::~ControlParticles() { - // nothing to do... -} - -LbmFloat ControlParticles::getControlTimStart() { - if(mPartSets.size()>0) { return mPartSets[0].time; } - return -1000.; -} -LbmFloat ControlParticles::getControlTimEnd() { - if(mPartSets.size()>0) { return mPartSets[mPartSets.size()-1].time; } - return -1000.; -} - -// calculate for delta t -void ControlParticles::setInfluenceVelocity(LbmFloat set, LbmFloat dt) { - const LbmFloat dtInter = 0.01; - LbmFloat facFv = 1.-set; //cparts->getInfluenceVelocity(); - // mLevel[mMaxRefine].timestep - LbmFloat facNv = (LbmFloat)( 1.-pow( (double)facFv, (double)(dt/dtInter)) ); - //errMsg("vwcalc","ts:"<<dt<< " its:"<<(dt/dtInter) <<" fv"<<facFv<<" nv"<<facNv<<" test:"<< pow( (double)(1.-facNv),(double)(dtInter/dt)) ); - _influenceVelocity = facNv; -} - -int ControlParticles::initExampleSet() -{ - // unused - return 0; -} - -int ControlParticles::getTotalSize() -{ - int s=0; - for(int i=0; i<(int)mPartSets.size(); i++) { - s+= mPartSets[i].particles.size(); - } - return s; -} - -// -------------------------------------------------------------------------- -// load positions & timing from text file -// WARNING - make sure file has unix format, no win/dos linefeeds... -#define LINE_LEN 100 -int ControlParticles::initFromTextFile(string filename) -{ - /* - const bool debugRead = false; - char line[LINE_LEN]; - line[LINE_LEN-1] = '\0'; - mPartSets.clear(); - if(filename.size()<2) return 0; - - // HACK , use "cparts" suffix as old - // e.g. "cpart2" as new - if(filename[ filename.size()-1 ]=='s') { - return initFromTextFileOld(filename); - } - - FILE *infile = fopen(filename.c_str(), "r"); - if(!infile) { - errMsg("ControlParticles::initFromTextFile","unable to open '"<<filename<<"' " ); - // try to open as gz sequence - if(initFromBinaryFile(filename)) { return 1; } - // try mesh MVCM generation - if(initFromMVCMesh(filename)) { return 1; } - // failed... - return 0; - } - - int haveNo = false; - int haveScale = false; - int haveTime = false; - int noParts = -1; - int partCnt = 0; - int setCnt = 0; - //ControlParticle p; p.reset(); - // scale times by constant factor while reading - LbmFloat timeScale= 1.0; - int lineCnt = 0; - bool abortParse = false; -#define LASTCP mPartSets[setCnt].particles[ mPartSets[setCnt].particles.size()-1 ] - - while( (!feof(infile)) && (!abortParse)) { - lineCnt++; - fgets(line, LINE_LEN, infile); - - //if(debugRead) printf("\nDEBUG%d r '%s'\n",lineCnt, line); - if(!line) continue; - size_t len = strlen(line); - - // skip empty lines and comments (#,//) - if(len<1) continue; - if( (line[0]=='#') || (line[0]=='\n') ) continue; - if((len>1) && (line[0]=='/' && line[1]=='/')) continue; - - // debug remove newline - if((len>=1)&&(line[len-1]=='\n')) line[len-1]='\0'; - - switch(line[0]) { - - case 'N': { // total number of particles, more for debugging... - noParts = atoi(line+2); - if(noParts<=0) { - errMsg("ControlParticles::initFromTextFile","file '"<<filename<<"' - invalid no of particles "<<noParts); - mPartSets.clear(); fclose(infile); return 0; - } - if(debugRead) printf("CPDEBUG%d no parts '%d'\n",lineCnt, noParts ); - haveNo = true; - } break; - - case 'T': { // global time scale - timeScale *= (LbmFloat)atof(line+2); - if(debugRead) printf("ControlParticles::initFromTextFile - line %d , set timescale '%f', org %f\n",lineCnt, timeScale , _initTimeScale); - if(timeScale==0.) { fprintf(stdout,"ControlParticles::initFromTextFile - line %d ,error: timescale = 0.! reseting to 1 ...\n",lineCnt); timeScale=1.; } - haveScale = true; - } break; - - case 'I': { // influence settings, overrides others as of now... - float val = (LbmFloat)atof(line+3); - const char *setvar = "[invalid]"; - switch(line[1]) { - //case 'f': { _influenceFalloff = val; setvar = "falloff"; } break; - case 't': { _influenceTangential = val; setvar = "tangential"; } break; - case 'a': { _influenceAttraction = val; setvar = "attraction"; } break; - case 'v': { _influenceVelocity = val; setvar = "velocity"; } break; - case 'm': { _influenceMaxdist = val; setvar = "maxdist"; } break; - default: - fprintf(stdout,"ControlParticles::initFromTextFile (%s) - line %d , invalid influence setting %c, %f\n",filename.c_str() ,lineCnt, line[1], val); - } - if(debugRead) printf("CPDEBUG%d set influence '%s'=%f \n",lineCnt, setvar, val); - } break; - - case 'R': { // radius settings, overrides others as of now... - float val = (LbmFloat)atof(line+3); - const char *setvar = "[invalid]"; - switch(line[1]) { - case 'a': { _radiusAtt = val; setvar = "r_attraction"; } break; - case 'v': { _radiusVel = val; setvar = "r_velocity"; } break; - case 'm': { _radiusMaxd = val; setvar = "r_maxdist"; } break; - default: - fprintf(stdout,"ControlParticles::initFromTextFile (%s) - line %d , invalid influence setting %c, %f\n",filename.c_str() ,lineCnt, line[1], val); - } - if(debugRead) printf("CPDEBUG%d set influence '%s'=%f \n",lineCnt, setvar, val); - } break; - - case 'S': { // new particle set at time T - ControlParticleSet cps; - mPartSets.push_back(cps); - setCnt = (int)mPartSets.size()-1; - - LbmFloat val = (LbmFloat)atof(line+2); - mPartSets[setCnt].time = val * timeScale; - if(debugRead) printf("CPDEBUG%d new set, time '%f', %d\n",lineCnt, mPartSets[setCnt].time, setCnt ); - haveTime = true; - partCnt = -1; - } break; - - case 'P': // new particle with pos - case 'n': { // new particle without pos - if((!haveTime)||(setCnt<0)) { fprintf(stdout,"ControlParticles::initFromTextFile - line %d ,error: set missing!\n",lineCnt); abortParse=true; break; } - partCnt++; - if(partCnt>=noParts) { - if(debugRead) printf("CPDEBUG%d partset done \n",lineCnt); - haveTime = false; - } else { - ControlParticle p; p.reset(); - mPartSets[setCnt].particles.push_back(p); - } - } - // only new part, or new with pos? - if(line[0] == 'n') break; - - // particle properties - - case 'p': { // new particle set at time T - if((!haveTime)||(setCnt<0)||(mPartSets[setCnt].particles.size()<1)) { fprintf(stdout,"ControlParticles::initFromTextFile - line %d ,error|p: particle missing!\n",lineCnt); abortParse=true; break; } - float px=0.,py=0.,pz=0.; - if( sscanf(line+2,"%f %f %f",&px,&py,&pz) != 3) { - fprintf(stdout,"CPDEBUG%d, unable to parse position!\n",lineCnt); abortParse=true; break; - } - if(!(finite(px)&&finite(py)&&finite(pz))) { px=py=pz=0.; } - LASTCP.pos[0] = px; - LASTCP.pos[1] = py; - LASTCP.pos[2] = pz; - if(debugRead) printf("CPDEBUG%d part%d,%d: position %f,%f,%f \n",lineCnt,setCnt,partCnt, px,py,pz); - } break; - - case 's': { // particle size - if((!haveTime)||(setCnt<0)||(mPartSets[setCnt].particles.size()<1)) { fprintf(stdout,"ControlParticles::initFromTextFile - line %d ,error|s: particle missing!\n",lineCnt); abortParse=true; break; } - float ps=1.; - if( sscanf(line+2,"%f",&ps) != 1) { - fprintf(stdout,"CPDEBUG%d, unable to parse size!\n",lineCnt); abortParse=true; break; - } - if(!(finite(ps))) { ps=0.; } - LASTCP.size = ps; - if(debugRead) printf("CPDEBUG%d part%d,%d: size %f \n",lineCnt,setCnt,partCnt, ps); - } break; - - case 'i': { // particle influence - if((!haveTime)||(setCnt<0)||(mPartSets[setCnt].particles.size()<1)) { fprintf(stdout,"ControlParticles::initFromTextFile - line %d ,error|i: particle missing!\n",lineCnt); abortParse=true; break; } - float pinf=1.; - if( sscanf(line+2,"%f",&pinf) != 1) { - fprintf(stdout,"CPDEBUG%d, unable to parse size!\n",lineCnt); abortParse=true; break; - } - if(!(finite(pinf))) { pinf=0.; } - LASTCP.influence = pinf; - if(debugRead) printf("CPDEBUG%d part%d,%d: influence %f \n",lineCnt,setCnt,partCnt, pinf); - } break; - - case 'a': { // rotation axis - if((!haveTime)||(setCnt<0)||(mPartSets[setCnt].particles.size()<1)) { fprintf(stdout,"ControlParticles::initFromTextFile - line %d ,error|a: particle missing!\n",lineCnt); abortParse=true; break; } - float px=0.,py=0.,pz=0.; - if( sscanf(line+2,"%f %f %f",&px,&py,&pz) != 3) { - fprintf(stdout,"CPDEBUG%d, unable to parse rotaxis!\n",lineCnt); abortParse=true; break; - } - if(!(finite(px)&&finite(py)&&finite(pz))) { px=py=pz=0.; } - LASTCP.rotaxis[0] = px; - LASTCP.rotaxis[1] = py; - LASTCP.rotaxis[2] = pz; - if(debugRead) printf("CPDEBUG%d part%d,%d: rotaxis %f,%f,%f \n",lineCnt,setCnt,partCnt, px,py,pz); - } break; - - - default: - if(debugRead) printf("CPDEBUG%d ignored: '%s'\n",lineCnt, line ); - break; - } - } - if(debugRead && abortParse) printf("CPDEBUG aborted parsing after set... %d\n",(int)mPartSets.size() ); - - // sanity check - for(int i=0; i<(int)mPartSets.size(); i++) { - if( (int)mPartSets[i].particles.size()!=noParts) { - fprintf(stdout,"ControlParticles::initFromTextFile (%s) - invalid no of particles in set %d, is:%d, shouldbe:%d \n",filename.c_str() ,i,(int)mPartSets[i].particles.size(), noParts); - mPartSets.clear(); - fclose(infile); - return 0; - } - } - - // print stats - printf("ControlParticles::initFromTextFile (%s): Read %d sets, each %d particles\n",filename.c_str() , - (int)mPartSets.size(), noParts ); - if(mPartSets.size()>0) { - printf("ControlParticles::initFromTextFile (%s): Time: %f,%f\n",filename.c_str() ,mPartSets[0].time, mPartSets[mPartSets.size()-1].time ); - } - - // done... - fclose(infile); - applyTrafos(); - */ - return 1; -} - - -int ControlParticles::initFromTextFileOld(string filename) -{ - /* - const bool debugRead = false; - char line[LINE_LEN]; - line[LINE_LEN-1] = '\0'; - mPartSets.clear(); - if(filename.size()<1) return 0; - - FILE *infile = fopen(filename.c_str(), "r"); - if(!infile) { - fprintf(stdout,"ControlParticles::initFromTextFileOld - unable to open '%s'\n",filename.c_str() ); - return 0; - } - - int haveNo = false; - int haveScale = false; - int haveTime = false; - int noParts = -1; - int coordCnt = 0; - int partCnt = 0; - int setCnt = 0; - ControlParticle p; p.reset(); - // scale times by constant factor while reading - LbmFloat timeScale= 1.0; - int lineCnt = 0; - - while(!feof(infile)) { - lineCnt++; - fgets(line, LINE_LEN, infile); - - if(debugRead) printf("\nDEBUG%d r '%s'\n",lineCnt, line); - - if(!line) continue; - size_t len = strlen(line); - - // skip empty lines and comments (#,//) - if(len<1) continue; - if( (line[0]=='#') || (line[0]=='\n') ) continue; - if((len>1) && (line[0]=='/' && line[1]=='/')) continue; - - // debug remove newline - if((len>=1)&&(line[len-1]=='\n')) line[len-1]='\0'; - - // first read no. of particles - if(!haveNo) { - noParts = atoi(line); - if(noParts<=0) { - fprintf(stdout,"ControlParticles::initFromTextFileOld - invalid no of particles %d\n",noParts); - mPartSets.clear(); - fclose(infile); - return 0; - } - if(debugRead) printf("DEBUG%d noparts '%d'\n",lineCnt, noParts ); - haveNo = true; - } - - // then read time scale - else if(!haveScale) { - timeScale *= (LbmFloat)atof(line); - if(debugRead) printf("DEBUG%d tsc '%f', org %f\n",lineCnt, timeScale , _initTimeScale); - haveScale = true; - } - - // then get set time - else if(!haveTime) { - ControlParticleSet cps; - mPartSets.push_back(cps); - setCnt = (int)mPartSets.size()-1; - - LbmFloat val = (LbmFloat)atof(line); - mPartSets[setCnt].time = val * timeScale; - if(debugRead) printf("DEBUG%d time '%f', %d\n",lineCnt, mPartSets[setCnt].time, setCnt ); - haveTime = true; - } - - // default read all parts - else { - LbmFloat val = (LbmFloat)atof(line); - if(debugRead) printf("DEBUG: l%d s%d,particle%d '%f' %d,%d/%d\n",lineCnt,(int)mPartSets.size(),(int)mPartSets[setCnt].particles.size(), val ,coordCnt,partCnt,noParts); - p.pos[coordCnt] = val; - coordCnt++; - if(coordCnt>=3) { - mPartSets[setCnt].particles.push_back(p); - p.reset(); - coordCnt=0; - partCnt++; - } - if(partCnt>=noParts) { - partCnt = 0; - haveTime = false; - } - //if(debugRead) printf("DEBUG%d par2 %d,%d/%d\n",lineCnt, coordCnt,partCnt,noParts); - } - //read pos, vel ... - } - - // sanity check - for(int i=0; i<(int)mPartSets.size(); i++) { - if( (int)mPartSets[i].particles.size()!=noParts) { - fprintf(stdout,"ControlParticles::initFromTextFileOld - invalid no of particles in set %d, is:%d, shouldbe:%d \n",i,(int)mPartSets[i].particles.size(), noParts); - mPartSets.clear(); - fclose(infile); - return 0; - } - } - // print stats - printf("ControlParticles::initFromTextFileOld: Read %d sets, each %d particles\n", - (int)mPartSets.size(), noParts ); - if(mPartSets.size()>0) { - printf("ControlParticles::initFromTextFileOld: Time: %f,%f\n",mPartSets[0].time, mPartSets[mPartSets.size()-1].time ); - } - - // done... - fclose(infile); - applyTrafos(); - */ - return 1; -} - -// load positions & timing from gzipped binary file -int ControlParticles::initFromBinaryFile(string filename) { - mPartSets.clear(); - if(filename.size()<1) return 0; - int fileNotFound=0; - int fileFound=0; - char ofile[256]; - - for(int set=0; ((set<10000)&&(fileNotFound<10)); set++) { - snprintf(ofile,256,"%s%04d.gz",filename.c_str(),set); - //errMsg("ControlParticle::initFromBinaryFile","set"<<set<<" notf"<<fileNotFound<<" ff"<<fileFound); - - gzFile gzf; - gzf = gzopen(ofile, "rb"); - if (!gzf) { - //errMsg("ControlParticles::initFromBinaryFile","Unable to open file for reading '"<<ofile<<"' "); - fileNotFound++; - continue; - } - fileNotFound=0; - fileFound++; - - ControlParticleSet cps; - mPartSets.push_back(cps); - int setCnt = (int)mPartSets.size()-1; - //LbmFloat val = (LbmFloat)atof(line+2); - mPartSets[setCnt].time = (gfxReal)set; - - int totpart = 0; - gzread(gzf, &totpart, sizeof(totpart)); - - for(int a=0; a<totpart; a++) { - int ptype=0; - float psize=0.0; - ntlVec3Gfx ppos,pvel; - gzread(gzf, &ptype, sizeof(ptype)); - gzread(gzf, &psize, sizeof(float)); - - for (int j=0; j<3; j++) { gzread(gzf, &ppos[j], sizeof(float)); } - for (int j=0; j<3; j++) { gzread(gzf, &pvel[j], sizeof(float)); } - - ControlParticle p; - p.reset(); - p.pos = vec2L(ppos); - mPartSets[setCnt].particles.push_back(p); - } - - gzclose(gzf); - //errMsg("ControlParticle::initFromBinaryFile","Read set "<<ofile<<", #"<<mPartSets[setCnt].particles.size() ); // DEBUG - } // sets - - if(fileFound==0) return 0; - applyTrafos(); - return 1; -} - -int globCPIProblems =0; -bool ControlParticles::checkPointInside(ntlTree *tree, ntlVec3Gfx org, gfxReal &distance) { - // warning - stripped down version of geoInitCheckPointInside - const int globGeoInitDebug = 0; - const int flags = FGI_FLUID; - org += ntlVec3Gfx(0.0001); - ntlVec3Gfx dir = ntlVec3Gfx(1.0, 0.0, 0.0); - int OId = -1; - ntlRay ray(org, dir, 0, 1.0, NULL); - bool done = false; - bool inside = false; - int mGiObjInside = 0; - LbmFloat mGiObjDistance = -1.0; - LbmFloat giObjFirstHistSide = 0; - - // if not inside, return distance to first hit - gfxReal firstHit=-1.0; - int firstOId = -1; - if(globGeoInitDebug) errMsg("IIIstart"," isect "<<org); - - while(!done) { - // find first inside intersection - ntlTriangle *triIns = NULL; - distance = -1.0; - ntlVec3Gfx normal(0.0); - tree->intersectX(ray,distance,normal, triIns, flags, true); - if(triIns) { - ntlVec3Gfx norg = ray.getOrigin() + ray.getDirection()*distance; - LbmFloat orientation = dot(normal, dir); - OId = triIns->getObjectId(); - if(orientation<=0.0) { - // outside hit - normal *= -1.0; - mGiObjInside++; - if(giObjFirstHistSide==0) giObjFirstHistSide = 1; - if(globGeoInitDebug) errMsg("IIO"," oid:"<<OId<<" org"<<org<<" norg"<<norg<<" orient:"<<orientation); - } else { - // inside hit - mGiObjInside++; - if(mGiObjDistance<0.0) mGiObjDistance = distance; - if(globGeoInitDebug) errMsg("III"," oid:"<<OId<<" org"<<org<<" norg"<<norg<<" orient:"<<orientation); - if(giObjFirstHistSide==0) giObjFirstHistSide = -1; - } - norg += normal * getVecEpsilon(); - ray = ntlRay(norg, dir, 0, 1.0, NULL); - // remember first hit distance, in case we're not - // inside anything - if(firstHit<0.0) { - firstHit = distance; - firstOId = OId; - } - } else { - // no more intersections... return false - done = true; - } - } - - distance = -1.0; - if(mGiObjInside>0) { - bool mess = false; - if((mGiObjInside%2)==1) { - if(giObjFirstHistSide != -1) mess=true; - } else { - if(giObjFirstHistSide != 1) mess=true; - } - if(mess) { - // ? - //errMsg("IIIproblem","At "<<org<<" obj inside:"<<mGiObjInside<<" firstside:"<<giObjFirstHistSide ); - globCPIProblems++; - mGiObjInside++; // believe first hit side... - } - } - - if(globGeoInitDebug) errMsg("CHIII"," ins="<<mGiObjInside<<" t"<<mGiObjDistance<<" d"<<distance); - if(((mGiObjInside%2)==1)&&(mGiObjDistance>0.0)) { - if( (distance<0.0) || // first intersection -> good - ((distance>0.0)&&(distance>mGiObjDistance)) // more than one intersection -> use closest one - ) { - distance = mGiObjDistance; - OId = 0; - inside = true; - } - } - - if(!inside) { - distance = firstHit; - OId = firstOId; - } - if(globGeoInitDebug) errMsg("CHIII","ins"<<inside<<" fh"<<firstHit<<" fo"<<firstOId<<" - h"<<distance<<" o"<<OId); - - return inside; -} -int ControlParticles::initFromMVCMesh(string filename) { - myTime_t mvmstart = getTime(); - ntlGeometryObjModel *model = new ntlGeometryObjModel(); - int gid=1; - char infile[256]; - vector<ntlTriangle> triangles; - vector<ntlVec3Gfx> vertices; - vector<ntlVec3Gfx> normals; - snprintf(infile,256,"%s.bobj.gz", filename.c_str() ); - model->loadBobjModel(string(infile)); - model->setLoaded(true); - model->setGeoInitId(gid); - model->setGeoInitType(FGI_FLUID); - debMsgStd("ControlParticles::initFromMVMCMesh",DM_MSG,"infile:"<<string(infile) ,4); - - //getTriangles(double t, vector<ntlTriangle> *triangles, vector<ntlVec3Gfx> *vertices, vector<ntlVec3Gfx> *normals, int objectId ); - model->getTriangles(mCPSTimeStart, &triangles, &vertices, &normals, 1 ); - debMsgStd("ControlParticles::initFromMVMCMesh",DM_MSG," tris:"<<triangles.size()<<" verts:"<<vertices.size()<<" norms:"<<normals.size() , 2); - - // valid mesh? - if(triangles.size() <= 0) { - return 0; - } - - ntlRenderGlobals *glob = new ntlRenderGlobals; - ntlScene *genscene = new ntlScene( glob, false ); - genscene->addGeoClass(model); - genscene->addGeoObject(model); - genscene->buildScene(0., false); - char treeFlag = (1<<(4+gid)); - - ntlTree *tree = new ntlTree( - 15, 8, // TREEwarning - fixed values for depth & maxtriangles here... - genscene, treeFlag ); - - // TODO? use params - ntlVec3Gfx start,end; - model->getExtends(start,end); - - LbmFloat width = mCPSWidth; - if(width<=LBM_EPSILON) { errMsg("ControlParticles::initFromMVMCMesh","Invalid mCPSWidth! "<<mCPSWidth); width=mCPSWidth=0.1; } - ntlVec3Gfx org = start+ntlVec3Gfx(width*0.5); - gfxReal distance = -1.; - vector<ntlVec3Gfx> inspos; - int approxmax = (int)( ((end[0]-start[0])/width)*((end[1]-start[1])/width)*((end[2]-start[2])/width) ); - - debMsgStd("ControlParticles::initFromMVMCMesh",DM_MSG,"start"<<start<<" end"<<end<<" w="<<width<<" maxp:"<<approxmax, 5); - while(org[2]<end[2]) { - while(org[1]<end[1]) { - while(org[0]<end[0]) { - if(checkPointInside(tree, org, distance)) { - inspos.push_back(org); - //inspos.push_back(org+ntlVec3Gfx(width)); - //inspos.push_back(start+end*0.5); - } - // TODO optimize, use distance - org[0] += width; - } - org[1] += width; - org[0] = start[0]; - } - org[2] += width; - org[1] = start[1]; - } - debMsgStd("ControlParticles::initFromMVMCMesh",DM_MSG,"points: "<<inspos.size()<<" initproblems: "<<globCPIProblems,5 ); - - MeanValueMeshCoords mvm; - mvm.calculateMVMCs(vertices,triangles, inspos, mCPSWeightFac); - vector<ntlVec3Gfx> ninspos; - mvm.transfer(vertices, ninspos); - - // init first set, check dist - ControlParticleSet firstcps; //T - mPartSets.push_back(firstcps); - mPartSets[mPartSets.size()-1].time = (gfxReal)0.; - vector<bool> useCP; - bool debugPos=false; - - for(int i=0; i<(int)inspos.size(); i++) { - ControlParticle p; p.reset(); - p.pos = vec2L(inspos[i]); - //errMsg("COMP "," "<<inspos[i]<<" vs "<<ninspos[i] ); - double cpdist = norm(inspos[i]-ninspos[i]); - bool usecpv = true; - if(debugPos) errMsg("COMP "," "<<cpdist<<usecpv); - - mPartSets[mPartSets.size()-1].particles.push_back(p); - useCP.push_back(usecpv); - } - - // init further sets, temporal mesh sampling - double tsampling = mCPSTimestep; - int totcnt = (int)( (mCPSTimeEnd-mCPSTimeStart)/tsampling ), tcnt=0; - for(double t=mCPSTimeStart+tsampling; ((t<mCPSTimeEnd) && (ninspos.size()>0.)); t+=tsampling) { - ControlParticleSet nextcps; //T - mPartSets.push_back(nextcps); - mPartSets[mPartSets.size()-1].time = (gfxReal)t; - - vertices.clear(); triangles.clear(); normals.clear(); - model->getTriangles(t, &triangles, &vertices, &normals, 1 ); - mvm.transfer(vertices, ninspos); - if(tcnt%(totcnt/10)==1) debMsgStd("MeanValueMeshCoords::calculateMVMCs",DM_MSG,"Transferring animation, frame: "<<tcnt<<"/"<<totcnt,5 ); - tcnt++; - for(int i=0; i<(int)ninspos.size(); i++) { - if(debugPos) errMsg("COMP "," "<<norm(inspos[i]-ninspos[i]) ); - if(useCP[i]) { - ControlParticle p; p.reset(); - p.pos = vec2L(ninspos[i]); - mPartSets[mPartSets.size()-1].particles.push_back(p); - } - } - } - - applyTrafos(); - - myTime_t mvmend = getTime(); - debMsgStd("ControlParticle::initFromMVMCMesh",DM_MSG,"t:"<<getTimeString(mvmend-mvmstart)<<" ",7 ); - delete tree; - delete genscene; - delete glob; -//exit(1); // DEBUG - return 1; -} - -#define TRISWAP(v,a,b) { LbmFloat tmp = (v)[b]; (v)[b]=(v)[a]; (v)[a]=tmp; } -#define TRISWAPALL(v,a,b) { \ - TRISWAP( (v).pos ,a,b ); \ - TRISWAP( (v).vel ,a,b ); \ - TRISWAP( (v).rotaxis ,a,b ); } - -// helper function for LBM 2D -> swap Y and Z components everywhere -void ControlParticles::swapCoords(int a, int b) { - //return; - for(int i=0; i<(int)mPartSets.size(); i++) { - for(int j=0; j<(int)mPartSets[i].particles.size(); j++) { - TRISWAPALL( mPartSets[i].particles[j],a,b ); - } - } -} - -// helper function for LBM 2D -> mirror time -void ControlParticles::mirrorTime() { - LbmFloat maxtime = mPartSets[mPartSets.size()-1].time; - const bool debugTimeswap = false; - - for(int i=0; i<(int)mPartSets.size(); i++) { - mPartSets[i].time = maxtime - mPartSets[i].time; - } - - for(int i=0; i<(int)mPartSets.size()/2; i++) { - ControlParticleSet cps = mPartSets[i]; - if(debugTimeswap) errMsg("TIMESWAP", " s"<<i<<","<<mPartSets[i].time<<" and s"<<(mPartSets.size()-1-i)<<","<< mPartSets[mPartSets.size()-1-i].time <<" mt:"<<maxtime ); - mPartSets[i] = mPartSets[mPartSets.size()-1-i]; - mPartSets[mPartSets.size()-1-i] = cps; - } - - for(int i=0; i<(int)mPartSets.size(); i++) { - if(debugTimeswap) errMsg("TIMESWAP", "done: s"<<i<<","<<mPartSets[i].time<<" "<<mPartSets[i].particles.size() ); - } -} - -// apply init transformations -void ControlParticles::applyTrafos() { - // apply trafos - for(int i=0; i<(int)mPartSets.size(); i++) { - mPartSets[i].time *= _initTimeScale; - /*for(int j=0; j<(int)mPartSets[i].particles.size(); j++) { - for(int k=0; k<3; k++) { - mPartSets[i].particles[j].pos[k] *= _initPartScale[k]; - mPartSets[i].particles[j].pos[k] += _initPartOffset[k]; - } - } now done in initarray */ - } - - // mirror coords... - for(int l=0; l<(int)_initMirror.length(); l++) { - switch(_initMirror[l]) { - case 'X': - case 'x': - //printf("ControlParticles::applyTrafos - mirror x\n"); - swapCoords(1,2); - break; - case 'Y': - case 'y': - //printf("ControlParticles::applyTrafos - mirror y\n"); - swapCoords(0,2); - break; - case 'Z': - case 'z': - //printf("ControlParticles::applyTrafos - mirror z\n"); - swapCoords(0,1); - break; - case 'T': - case 't': - //printf("ControlParticles::applyTrafos - mirror time\n"); - mirrorTime(); - break; - case ' ': - case '-': - case '\n': - break; - default: - //printf("ControlParticles::applyTrafos - mirror unknown %c !?\n", _initMirror[l] ); - break; - } - } - - // reset 2d positions -#if (CP_PROJECT2D==1) && ( defined(MAIN_2D) || LBMDIM==2 ) - for(size_t j=0; j<mPartSets.size(); j++) - for(size_t i=0; i<mPartSets[j].particles.size(); i++) { - // DEBUG - mPartSets[j].particles[i].pos[1] = 0.f; - } -#endif - -#if defined(LBMDIM) - //? if( (getenv("ELBEEM_CPINFILE")) || (getenv("ELBEEM_CPOUTFILE")) ){ - // gui control test, don swap... - //? } else { - //? swapCoords(1,2); // LBM 2D -> swap Y and Z components everywhere - //? } -#endif - - initTime(0.f, 0.f); -} - -#undef TRISWAP - -// -------------------------------------------------------------------------- -// init for a given time -void ControlParticles::initTime(LbmFloat t, LbmFloat dt) -{ - //fprintf(stdout, "CPINITTIME init %f\n",t); - _currTime = t; - if(mPartSets.size()<1) return; - - // init zero velocities - initTimeArray(t, _particles); - - // calculate velocities from prev. timestep? - if(dt>0.) { - _currTimestep = dt; - std::vector<ControlParticle> prevparts; - initTimeArray(t-dt, prevparts); - LbmFloat invdt = 1.0/dt; - for(size_t j=0; j<_particles.size(); j++) { - ControlParticle &p = _particles[j]; - ControlParticle &prevp = prevparts[j]; - for(int k=0; k<3; k++) { - p.pos[k] *= _initPartScale[k]; - p.pos[k] += _initPartOffset[k]; - prevp.pos[k] *= _initLastPartScale[k]; - prevp.pos[k] += _initLastPartOffset[k]; - } - p.vel = (p.pos - prevp.pos)*invdt; - } - - if(0) { - LbmVec avgvel(0.); - for(size_t j=0; j<_particles.size(); j++) { - avgvel += _particles[j].vel; - } - avgvel /= (LbmFloat)_particles.size(); - //fprintf(stdout," AVGVEL %f,%f,%f \n",avgvel[0],avgvel[1],avgvel[2]); // DEBUG - } - } -} - -// helper, init given array -void ControlParticles::initTimeArray(LbmFloat t, std::vector<ControlParticle> &parts) { - if(mPartSets.size()<1) return; - - if(parts.size()!=mPartSets[0].particles.size()) { - //fprintf(stdout,"PRES \n"); - parts.resize(mPartSets[0].particles.size()); - // TODO reset all? - for(size_t j=0; j<parts.size(); j++) { - parts[j].reset(); - } - } - if(parts.size()<1) return; - - // debug inits - if(mDebugInit==1) { - // hard coded circle init - for(size_t j=0; j<mPartSets[0].particles.size(); j++) { - ControlParticle p = mPartSets[0].particles[j]; - // remember old - p.density = parts[j].density; - p.densityWeight = parts[j].densityWeight; - p.avgVel = parts[j].avgVel; - p.avgVelAcc = parts[j].avgVelAcc; - p.avgVelWeight = parts[j].avgVelWeight; - LbmVec ppos(0.); { // DEBUG - const float tscale=10.; - const float tprevo = 0.33; - const LbmVec toff(50,50,0); - const LbmVec oscale(30,30,0); - ppos[0] = cos(tscale* t - tprevo*(float)j + M_PI -0.1) * oscale[0] + toff[0]; - ppos[1] = -sin(tscale* t - tprevo*(float)j + M_PI -0.1) * oscale[1] + toff[1]; - ppos[2] = toff[2]; } // DEBUG - p.pos = ppos; - parts[j] = p; - //errMsg("ControlParticle::initTimeArray","j:"<<j<<" p:"<<parts[j].pos ); - } - return; - } - else if(mDebugInit==2) { - // hard coded spiral init - const float tscale=-10.; - const float tprevo = 0.33; - LbmVec toff(50,0,-50); - const LbmVec oscale(20,20,0); - toff[2] += 30. * t +30.; - for(size_t j=0; j<mPartSets[0].particles.size(); j++) { - ControlParticle p = mPartSets[0].particles[j]; - // remember old - p.density = parts[j].density; - p.densityWeight = parts[j].densityWeight; - p.avgVel = parts[j].avgVel; - p.avgVelAcc = parts[j].avgVelAcc; - p.avgVelWeight = parts[j].avgVelWeight; - LbmVec ppos(0.); - ppos[1] = toff[2]; - LbmFloat zscal = (ppos[1]+100.)/200.; - ppos[0] = cos(tscale* t - tprevo*(float)j + M_PI -0.1) * oscale[0]*zscal + toff[0]; - ppos[2] = -sin(tscale* t - tprevo*(float)j + M_PI -0.1) * oscale[1]*zscal + toff[1]; - p.pos = ppos; - parts[j] = p; - - toff[2] += 0.25; - } - return; - } - - // use first set - if((t<=mPartSets[0].time)||(mPartSets.size()==1)) { - //fprintf(stdout,"PINI %f \n", t); - //parts = mPartSets[0].particles; - const int i=0; - for(size_t j=0; j<mPartSets[i].particles.size(); j++) { - ControlParticle p = mPartSets[i].particles[j]; - // remember old - p.density = parts[j].density; - p.densityWeight = parts[j].densityWeight; - p.avgVel = parts[j].avgVel; - p.avgVelAcc = parts[j].avgVelAcc; - p.avgVelWeight = parts[j].avgVelWeight; - parts[j] = p; - } - return; - } - - for(int i=0; i<(int)mPartSets.size()-1; i++) { - if((mPartSets[i].time<=t) && (mPartSets[i+1].time>t)) { - LbmFloat d = mPartSets[i+1].time-mPartSets[i].time; - LbmFloat f = (t-mPartSets[i].time)/d; - LbmFloat omf = 1.0f - f; - - for(size_t j=0; j<mPartSets[i].particles.size(); j++) { - ControlParticle *src1=&mPartSets[i ].particles[j]; - ControlParticle *src2=&mPartSets[i+1].particles[j]; - ControlParticle &p = parts[j]; - // do linear interpolation - p.pos = src1->pos * omf + src2->pos *f; - p.vel = LbmVec(0.); // reset, calculated later on src1->vel * omf + src2->vel *f; - p.rotaxis = src1->rotaxis * omf + src2->rotaxis *f; - p.influence = src1->influence * omf + src2->influence *f; - p.size = src1->size * omf + src2->size *f; - // dont modify: density, densityWeight - } - } - } - - // after last? - if(t>=mPartSets[ mPartSets.size() -1 ].time) { - //parts = mPartSets[ mPartSets.size() -1 ].particles; - const int i= (int)mPartSets.size() -1; - for(size_t j=0; j<mPartSets[i].particles.size(); j++) { - ControlParticle p = mPartSets[i].particles[j]; - // restore - p.density = parts[j].density; - p.densityWeight = parts[j].densityWeight; - p.avgVel = parts[j].avgVel; - p.avgVelAcc = parts[j].avgVelAcc; - p.avgVelWeight = parts[j].avgVelWeight; - parts[j] = p; - } - } -} - - - - -// -------------------------------------------------------------------------- - -#define DEBUG_MODVEL 0 - -// recalculate -void ControlParticles::calculateKernelWeight() { - const bool debugKernel = true; - - // calculate kernel area with respect to particlesize/cellsize - LbmFloat kernelw = -1.; - LbmFloat kernelnorm = -1.; - LbmFloat krad = (_radiusAtt*0.75); // FIXME use real cone approximation...? - //krad = (_influenceFalloff*1.); -#if (CP_PROJECT2D==1) && (defined(MAIN_2D) || LBMDIM==2) - kernelw = CP_PI*krad*krad; - kernelnorm = 1.0 / (_fluidSpacing * _fluidSpacing); -#else // 2D - kernelw = CP_PI*krad*krad*krad* (4./3.); - kernelnorm = 1.0 / (_fluidSpacing * _fluidSpacing * _fluidSpacing); -#endif // MAIN_2D - - if(debugKernel) debMsgStd("ControlParticles::calculateKernelWeight",DM_MSG,"kw"<<kernelw<<", norm"<< - kernelnorm<<", w*n="<<(kernelw*kernelnorm)<<", rad"<<krad<<", sp"<<_fluidSpacing<<" ", 7); - LbmFloat kernelws = kernelw*kernelnorm; - _kernelWeight = kernelws; - if(debugKernel) debMsgStd("ControlParticles::calculateKernelWeight",DM_MSG,"influence f="<<_radiusAtt<<" t="<< - _influenceTangential<<" a="<<_influenceAttraction<<" v="<<_influenceVelocity<<" kweight="<<_kernelWeight, 7); - if(_kernelWeight<=0.) { - errMsg("ControlParticles::calculateKernelWeight", "invalid kernel! "<<_kernelWeight<<", resetting"); - _kernelWeight = 1.; - } -} - -void -ControlParticles::prepareControl(LbmFloat simtime, LbmFloat dt, ControlParticles *motion) { - debMsgStd("ControlParticle::prepareControl",DM_MSG," simtime="<<simtime<<" dt="<<dt<<" ", 5); - - //fprintf(stdout,"PREPARE \n"); - LbmFloat avgdw = 0.; - for(size_t i=0; i<_particles.size(); i++) { - ControlParticle *cp = &_particles[i]; - - if(this->getInfluenceAttraction()<0.) { - cp->density= - cp->densityWeight = 1.0; - continue; - } - - // normalize by kernel - //cp->densityWeight = (1.0 - (cp->density / _kernelWeight)); // store last -#if (CP_PROJECT2D==1) && (defined(MAIN_2D) || LBMDIM==2) - cp->densityWeight = (1.0 - (cp->density / (_kernelWeight*cp->size*cp->size) )); // store last -#else // 2D - cp->densityWeight = (1.0 - (cp->density / (_kernelWeight*cp->size*cp->size*cp->size) )); // store last -#endif // MAIN_2D - - if(i<10) debMsgStd("ControlParticle::prepareControl",DM_MSG,"kernelDebug i="<<i<<" densWei="<<cp->densityWeight<<" 1/kw"<<(1.0/_kernelWeight)<<" cpdensity="<<cp->density, 9 ); - if(cp->densityWeight<0.) cp->densityWeight=0.; - if(cp->densityWeight>1.) cp->densityWeight=1.; - - avgdw += cp->densityWeight; - // reset for next step - cp->density = 0.; - - if(cp->avgVelWeight>0.) { - cp->avgVel = cp->avgVelAcc/cp->avgVelWeight; - cp->avgVelWeight = 0.; - cp->avgVelAcc = LbmVec(0.,0.,0.); - } - } - //if(debugKernel) for(size_t i=0; i<_particles.size(); i++) { ControlParticle *cp = &_particles[i]; fprintf(stdout,"A %f,%f \n",cp->density,cp->densityWeight); } - avgdw /= (LbmFloat)(_particles.size()); - //if(motion) { printf("ControlParticle::kernel: avgdw:%f, kw%f, sp%f \n", avgdw, _kernelWeight, _fluidSpacing); } - - //if((simtime>=0.) && (simtime != _currTime)) - initTime(simtime, dt); - - if((motion) && (motion->getSize()>0)){ - ControlParticle *motionp = motion->getParticle(0); - //printf("ControlParticle::prepareControl motion: pos[%f,%f,%f] vel[%f,%f,%f] \n", motionp->pos[0], motionp->pos[1], motionp->pos[2], motionp->vel[0], motionp->vel[1], motionp->vel[2] ); - for(size_t i=0; i<_particles.size(); i++) { - ControlParticle *cp = &_particles[i]; - cp->pos = cp->pos + motionp->pos; - cp->vel = cp->vel + motionp->vel; - cp->size = cp->size * motionp->size; - cp->influence = cp->size * motionp->influence; - } - } - - // reset to radiusAtt by default - if(_radiusVel==0.) _radiusVel = _radiusAtt; - if(_radiusMinMaxd==0.) _radiusMinMaxd = _radiusAtt; - if(_radiusMaxd==0.) _radiusMaxd = 2.*_radiusAtt; - // has to be radiusVel<radiusAtt<radiusMinMaxd<radiusMaxd - if(_radiusVel>_radiusAtt) _radiusVel = _radiusAtt; - if(_radiusAtt>_radiusMinMaxd) _radiusAtt = _radiusMinMaxd; - if(_radiusMinMaxd>_radiusMaxd) _radiusMinMaxd = _radiusMaxd; - - //printf("ControlParticle::radii vel:%f att:%f min:%f max:%f \n", _radiusVel,_radiusAtt,_radiusMinMaxd,_radiusMaxd); - // prepareControl done -} - -void ControlParticles::finishControl(std::vector<ControlForces> &forces, LbmFloat iatt, LbmFloat ivel, LbmFloat imaxd) { - - //const LbmFloat iatt = this->getInfluenceAttraction() * this->getCurrTimestep(); - //const LbmFloat ivel = this->getInfluenceVelocity(); - //const LbmFloat imaxd = this->getInfluenceMaxdist() * this->getCurrTimestep(); - // prepare for usage - iatt *= this->getCurrTimestep(); - ivel *= 1.; // not necessary! - imaxd *= this->getCurrTimestep(); - - // skip when size=0 - for(int i=0; i<(int)forces.size(); i++) { - if(DEBUG_MODVEL) fprintf(stdout, "CPFORGF %d , wf:%f,f:%f,%f,%f , v:%f,%f,%f \n",i, forces[i].weightAtt, forces[i].forceAtt[0],forces[i].forceAtt[1],forces[i].forceAtt[2], forces[i].forceVel[0], forces[i].forceVel[1], forces[i].forceVel[2] ); - LbmFloat cfweight = forces[i].weightAtt; // always normalize - if((cfweight!=0.)&&(iatt!=0.)) { - // multiple kernels, normalize - note this does not normalize in d>r/2 region - if(ABS(cfweight)>1.) { cfweight = 1.0/cfweight; } - // multiply iatt afterwards to allow stronger force - cfweight *= iatt; - forces[i].forceAtt *= cfweight; - } else { - forces[i].weightAtt = 0.; - forces[i].forceAtt = LbmVec(0.); - } - - if( (cfweight==0.) && (imaxd>0.) && (forces[i].maxDistance>0.) ) { - forces[i].forceMaxd *= imaxd; - } else { - forces[i].maxDistance= 0.; - forces[i].forceMaxd = LbmVec(0.); - } - - LbmFloat cvweight = forces[i].weightVel; // always normalize - if(cvweight>0.) { - forces[i].forceVel /= cvweight; - forces[i].compAv /= cvweight; - // now modify cvweight, and write back - // important, cut at 1 - otherwise strong vel. influences... - if(cvweight>1.) { cvweight = 1.; } - // thus cvweight is in the range of 0..influenceVelocity, currently not normalized by numCParts - cvweight *= ivel; - if(cvweight<0.) cvweight=0.; - if(cvweight>1.) cvweight=1.; - // LBM, FIXME todo use relaxation factor - //pvel = (cvel*0.5 * cvweight) + (pvel * (1.0-cvweight)); - forces[i].weightVel = cvweight; - - //errMsg("COMPAV","i"<<i<<" compav"<<forces[i].compAv<<" forcevel"<<forces[i].forceVel<<" "); - } else { - forces[i].weightVel = 0.; - if(forces[i].maxDistance==0.) forces[i].forceVel = LbmVec(0.); - forces[i].compAvWeight = 0.; - forces[i].compAv = LbmVec(0.); - } - if(DEBUG_MODVEL) fprintf(stdout, "CPFINIF %d , wf:%f,f:%f,%f,%f , v:%f,%f,%f \n",i, forces[i].weightAtt, forces[i].forceAtt[0],forces[i].forceAtt[1],forces[i].forceAtt[2], forces[i].forceVel[0],forces[i].forceVel[1],forces[i].forceVel[2] ); - } - - // unused... - if(DEBUG_MODVEL) fprintf(stdout,"MFC iatt:%f,%f ivel:%f,%f ifmd:%f,%f \n", iatt,_radiusAtt, ivel,_radiusVel, imaxd, _radiusMaxd); - //for(size_t i=0; i<_particles.size(); i++) { ControlParticle *cp = &_particles[i]; fprintf(stdout," %f,%f,%f ",cp->density,cp->densityWeight, (1.0 - (12.0*cp->densityWeight))); } - //fprintf(stdout,"\n\nCP DONE \n\n\n"); -} - - -// -------------------------------------------------------------------------- -// calculate forces at given position, and modify velocity -// according to timestep -void ControlParticles::calculateCpInfluenceOpt(ControlParticle *cp, LbmVec fluidpos, LbmVec fluidvel, ControlForces *force, LbmFloat fillFactor) { - // dont reset, only add... - // test distance, simple squared distance reject - const LbmFloat cpfo = _radiusAtt*cp->size; - - LbmVec posDelta; - if(DEBUG_MODVEL) fprintf(stdout, "CP at %f,%f,%f bef fw:%f, f:%f,%f,%f , vw:%f, v:%f,%f,%f \n",fluidpos[0],fluidpos[1],fluidpos[2], force->weightAtt, force->forceAtt[0], force->forceAtt[1], force->forceAtt[2], force->weightVel, force->forceVel[0], force->forceVel[1], force->forceVel[2]); - posDelta = cp->pos - fluidpos; -#if LBMDIM==2 && (CP_PROJECT2D==1) - posDelta[2] = 0.; // project to xy plane, z-velocity should already be gone... -#endif - - const LbmFloat distsqr = posDelta[0]*posDelta[0]+posDelta[1]*posDelta[1]+posDelta[2]*posDelta[2]; - if(DEBUG_MODVEL) fprintf(stdout, " Pd at %f,%f,%f d%f \n",posDelta[0],posDelta[1],posDelta[2], distsqr); - // cut at influence=0.5 , scaling not really makes sense - if(cpfo*cpfo < distsqr) { - /*if(cp->influence>0.5) { - if(force->weightAtt == 0.) { - if(force->maxDistance*force->maxDistance > distsqr) { - const LbmFloat dis = sqrtf((float)distsqr); - const LbmFloat sc = dis-cpfo; - force->maxDistance = dis; - force->forceMaxd = (posDelta)*(sc/dis); - } - } } */ - return; - } - force->weightAtt += 1e-6; // for distance - force->maxDistance = 0.; // necessary for SPH? - - const LbmFloat pdistance = MAGNITUDE(posDelta); - LbmFloat pdistinv = 0.; - if(ABS(pdistance)>0.) pdistinv = 1./pdistance; - posDelta *= pdistinv; - - LbmFloat falloffAtt = 0.; //CPKernel::kernel(cpfo * 1.0, pdistance); - const LbmFloat qac = pdistance / cpfo ; - if (qac < 1.0){ // return 0.; - if(qac < 0.5) falloffAtt = 1.0f; - else falloffAtt = (1.0f - qac) * 2.0f; - } - - // vorticity force: - // - //LbmVec forceVort; - // - //CROSS(forceVort, posDelta, cp->rotaxis); - // - //NORMALIZE(forceVort); - // - if(falloffAtt>1.0) falloffAtt=1.0; - -#if (CP_PROJECT2D==1) && (defined(MAIN_2D) || LBMDIM==2) - // fillFactor *= 2.0 *0.75 * pdistance; // 2d>3d sampling -#endif // (CP_PROJECT2D==1) && (defined(MAIN_2D) || LBMDIM==2) - - LbmFloat signum = getInfluenceAttraction() > 0.0 ? 1.0 : -1.0; - cp->density += falloffAtt * fillFactor; - force->forceAtt += posDelta *cp->densityWeight *cp->influence *signum; - force->weightAtt += falloffAtt*cp->densityWeight *cp->influence; - - LbmFloat falloffVel = 0.; //CPKernel::kernel(cpfo * 1.0, pdistance); - const LbmFloat cpfv = _radiusVel*cp->size; - if(cpfv*cpfv < distsqr) { return; } - const LbmFloat qvc = pdistance / cpfo ; - //if (qvc < 1.0){ - //if(qvc < 0.5) falloffVel = 1.0f; - //else falloffVel = (1.0f - qvc) * 2.0f; - //} - falloffVel = 1.-qvc; - - LbmFloat pvWeight; // = (1.0-cp->densityWeight) * _currTimestep * falloffVel; - pvWeight = falloffVel *cp->influence; // std, without density influence - //pvWeight *= (1.0-cp->densityWeight); // use inverse density weight - //pvWeight *= cp->densityWeight; // test, use density weight - LbmVec modvel(0.); - modvel += cp->vel * pvWeight; - //pvWeight = 1.; modvel = partVel; // DEBUG!? - - if(pvWeight>0.) { - force->forceVel += modvel; - force->weightVel += pvWeight; - - cp->avgVelWeight += falloffVel; - cp->avgVel += fluidvel; - } - if(DEBUG_MODVEL) fprintf(stdout, "CP at %f,%f,%f aft fw:%f, f:%f,%f,%f , vw:%f, v:%f,%f,%f \n",fluidpos[0],fluidpos[1],fluidpos[2], force->weightAtt, force->forceAtt[0], force->forceAtt[1], force->forceAtt[2], force->weightVel, force->forceVel[0], force->forceVel[1], force->forceVel[2]); - return; -} - -void ControlParticles::calculateMaxdForce(ControlParticle *cp, LbmVec fluidpos, ControlForces *force) { - if(force->weightAtt != 0.) return; // maxd force off - if(cp->influence <= 0.5) return; // ignore - - LbmVec posDelta; - //if(DEBUG_MODVEL) fprintf(stdout, "CP at %f,%f,%f bef fw:%f, f:%f,%f,%f , vw:%f, v:%f,%f,%f \n",fluidpos[0],fluidpos[1],fluidpos[2], force->weightAtt, force->forceAtt[0], force->forceAtt[1], force->forceAtt[2], force->weightVel, force->forceVel[0], force->forceVel[1], force->forceVel[2]); - posDelta = cp->pos - fluidpos; -#if LBMDIM==2 && (CP_PROJECT2D==1) - posDelta[2] = 0.; // project to xy plane, z-velocity should already be gone... -#endif - - // dont reset, only add... - // test distance, simple squared distance reject - const LbmFloat distsqr = posDelta[0]*posDelta[0]+posDelta[1]*posDelta[1]+posDelta[2]*posDelta[2]; - - // closer cp found - if(force->maxDistance*force->maxDistance < distsqr) return; - - const LbmFloat dmin = _radiusMinMaxd*cp->size; - if(distsqr<dmin*dmin) return; // inside min - const LbmFloat dmax = _radiusMaxd*cp->size; - if(distsqr>dmax*dmax) return; // outside - - - if(DEBUG_MODVEL) fprintf(stdout, " Pd at %f,%f,%f d%f \n",posDelta[0],posDelta[1],posDelta[2], distsqr); - // cut at influence=0.5 , scaling not really makes sense - const LbmFloat dis = sqrtf((float)distsqr); - //const LbmFloat sc = dis - dmin; - const LbmFloat sc = (dis-dmin)/(dmax-dmin); // scale from 0-1 - force->maxDistance = dis; - force->forceMaxd = (posDelta/dis) * sc; - //debug errMsg("calculateMaxdForce","pos"<<fluidpos<<" dis"<<dis<<" sc"<<sc<<" dmin"<<dmin<<" maxd"<< force->maxDistance <<" fmd"<<force->forceMaxd ); - return; -} - diff --git a/intern/elbeem/intern/controlparticles.h b/intern/elbeem/intern/controlparticles.h deleted file mode 100644 index 37b694f7cf2..00000000000 --- a/intern/elbeem/intern/controlparticles.h +++ /dev/null @@ -1,327 +0,0 @@ -/** \file - * \ingroup elbeem - */ -// -------------------------------------------------------------------------- -// -// El'Beem - the visual lattice boltzmann freesurface simulator -// All code distributed as part of El'Beem is covered by the version 2 of the -// GNU General Public License. See the file COPYING for details. -// -// Copyright 2008 Nils Thuerey , Richard Keiser, Mark Pauly, Ulrich Ruede -// -// control particle classes -// -// -------------------------------------------------------------------------- - -#ifndef CONTROLPARTICLES_H -#define CONTROLPARTICLES_H - -#include "ntl_geometrymodel.h" - -#ifdef WITH_CXX_GUARDEDALLOC -# include "MEM_guardedalloc.h" -#endif - -// indicator for LBM inclusion -//#ifndef LBMDIM - -//#include <NxFoundation.h> -//#include <vector> -//class MultisphGUI; -//#define NORMALIZE(a) a.normalize() -//#define MAGNITUDE(a) a.magnitude() -//#define CROSS(a,b,c) a.cross(b,c) -//#define ABS(a) (a>0. ? (a) : -(a)) -//#include "cpdefines.h" - -//#else // LBMDIM - -// use compatibility defines -//#define NORMALIZE(a) normalize(a) -//#define MAGNITUDE(a) norm(a) -//#define CROSS(a,b,c) a=cross(b,c) - -//#endif // LBMDIM - -#define MAGNITUDE(a) norm(a) - -// math.h compatibility -#define CP_PI ((LbmFloat)3.14159265358979323846) - -// project 2d test cases onto plane? -// if not, 3d distance is used for 2d sim as well -#define CP_PROJECT2D 1 - - -// default init for mincpdist, ControlForces::maxDistance -#define CPF_MAXDINIT 10000. - -// storage of influence for a fluid cell/particle in lbm/sph -class ControlForces -{ -public: - ControlForces() { }; - ~ControlForces() {}; - - // attraction force - LbmFloat weightAtt; - LbmVec forceAtt; - // velocity influence - LbmFloat weightVel; - LbmVec forceVel; - // maximal distance influence, - // first is max. distance to first control particle - // second attraction strength - LbmFloat maxDistance; - LbmVec forceMaxd; - - LbmFloat compAvWeight; - LbmVec compAv; - - void resetForces() { - weightAtt = weightVel = 0.; - maxDistance = CPF_MAXDINIT; - forceAtt = forceVel = forceMaxd = LbmVec(0.,0.,0.); - compAvWeight=0.; compAv=LbmVec(0.); - }; - -private: -#ifdef WITH_CXX_GUARDEDALLOC - MEM_CXX_CLASS_ALLOC_FUNCS("ELBEEM:ControlForces") -#endif -}; - - -// single control particle -class ControlParticle -{ -public: - ControlParticle() { reset(); }; - ~ControlParticle() {}; - - // control parameters - - // position - LbmVec pos; - // size (influences influence radius) - LbmFloat size; - // overall strength of influence - LbmFloat influence; - // rotation axis - LbmVec rotaxis; - - // computed values - - // velocity - LbmVec vel; - // computed density - LbmFloat density; - LbmFloat densityWeight; - - LbmVec avgVel; - LbmVec avgVelAcc; - LbmFloat avgVelWeight; - - // init all zero / defaults - void reset(); - -private: -#ifdef WITH_CXX_GUARDEDALLOC - MEM_CXX_CLASS_ALLOC_FUNCS("ELBEEM:ControlParticle") -#endif -}; - - -// container for a particle configuration at time t -class ControlParticleSet -{ -public: - - // time of particle set - LbmFloat time; - // particle positions - std::vector<ControlParticle> particles; - -private: -#ifdef WITH_CXX_GUARDEDALLOC - MEM_CXX_CLASS_ALLOC_FUNCS("ELBEEM:ControlParticleSet") -#endif -}; - - -// container & management of control particles -class ControlParticles -{ -public: - ControlParticles(); - ~ControlParticles(); - - // reset datastructures for next influence step - // if motion object is given, particle 1 of second system is used for overall - // position and speed offset - void prepareControl(LbmFloat simtime, LbmFloat dt, ControlParticles *motion); - // post control operations - void finishControl(std::vector<ControlForces> &forces, LbmFloat iatt, LbmFloat ivel, LbmFloat imaxd); - // recalculate - void calculateKernelWeight(); - - // calculate forces at given position, and modify velocity - // according to timestep (from initControl) - void calculateCpInfluenceOpt (ControlParticle *cp, LbmVec fluidpos, LbmVec fluidvel, ControlForces *force, LbmFloat fillFactor); - void calculateMaxdForce (ControlParticle *cp, LbmVec fluidpos, ControlForces *force); - - // no. of particles - inline int getSize() { return (int)_particles.size(); } - int getTotalSize(); - // get particle [i] - inline ControlParticle* getParticle(int i){ return &_particles[i]; } - - // set influence parameters - void setInfluenceTangential(LbmFloat set) { _influenceTangential=set; } - void setInfluenceAttraction(LbmFloat set) { _influenceAttraction=set; } - void setInfluenceMaxdist(LbmFloat set) { _influenceMaxdist=set; } - // calculate for delta t - void setInfluenceVelocity(LbmFloat set, LbmFloat dt); - // get influence parameters - inline LbmFloat getInfluenceAttraction() { return _influenceAttraction; } - inline LbmFloat getInfluenceTangential() { return _influenceTangential; } - inline LbmFloat getInfluenceVelocity() { return _influenceVelocity; } - inline LbmFloat getInfluenceMaxdist() { return _influenceMaxdist; } - inline LbmFloat getCurrTimestep() { return _currTimestep; } - - void setRadiusAtt(LbmFloat set) { _radiusAtt=set; } - inline LbmFloat getRadiusAtt() { return _radiusAtt; } - void setRadiusVel(LbmFloat set) { _radiusVel=set; } - inline LbmFloat getRadiusVel() { return _radiusVel; } - void setRadiusMaxd(LbmFloat set) { _radiusMaxd=set; } - inline LbmFloat getRadiusMaxd() { return _radiusMaxd; } - void setRadiusMinMaxd(LbmFloat set) { _radiusMinMaxd=set; } - inline LbmFloat getRadiusMinMaxd() { return _radiusMinMaxd; } - - LbmFloat getControlTimStart(); - LbmFloat getControlTimEnd(); - - // set/get characteristic length (and inverse) - void setCharLength(LbmFloat set) { _charLength=set; _charLengthInv=1./_charLength; } - inline LbmFloat getCharLength() { return _charLength;} - inline LbmFloat getCharLengthInv() { return _charLengthInv;} - - // set init parameters - void setInitTimeScale(LbmFloat set) { _initTimeScale = set; }; - void setInitMirror(string set) { _initMirror = set; }; - string getInitMirror() { return _initMirror; }; - - void setLastOffset(LbmVec set) { _initLastPartOffset = set; }; - void setLastScale(LbmVec set) { _initLastPartScale = set; }; - void setOffset(LbmVec set) { _initPartOffset = set; }; - void setScale(LbmVec set) { _initPartScale = set; }; - - // set/get cps params - void setCPSWith(LbmFloat set) { mCPSWidth = set; }; - void setCPSTimestep(LbmFloat set) { mCPSTimestep = set; }; - void setCPSTimeStart(LbmFloat set) { mCPSTimeStart = set; }; - void setCPSTimeEnd(LbmFloat set) { mCPSTimeEnd = set; }; - void setCPSMvmWeightFac(LbmFloat set) { mCPSWeightFac = set; }; - - LbmFloat getCPSWith() { return mCPSWidth; }; - LbmFloat getCPSTimestep() { return mCPSTimestep; }; - LbmFloat getCPSTimeStart() { return mCPSTimeStart; }; - LbmFloat getCPSTimeEnd() { return mCPSTimeEnd; }; - LbmFloat getCPSMvmWeightFac() { return mCPSWeightFac; }; - - void setDebugInit(int set) { mDebugInit = set; }; - - // set init parameters - void setFluidSpacing(LbmFloat set) { _fluidSpacing = set; }; - - // load positions & timing from text file - int initFromTextFile(string filename); - int initFromTextFileOld(string filename); - // load positions & timing from gzipped binary file - int initFromBinaryFile(string filename); - int initFromMVCMesh(string filename); - // init an example test case - int initExampleSet(); - - // init for a given time - void initTime(LbmFloat t, LbmFloat dt); - - // blender test init - void initBlenderTest(); - - int initFromObject(ntlGeometryObjModel *model); - -protected: - // sets influence params - friend class MultisphGUI; - - // tangential and attraction influence - LbmFloat _influenceTangential, _influenceAttraction; - // direct velocity influence - LbmFloat _influenceVelocity; - // maximal distance influence - LbmFloat _influenceMaxdist; - - // influence radii - LbmFloat _radiusAtt, _radiusVel, _radiusMinMaxd, _radiusMaxd; - - // currently valid time & timestep - LbmFloat _currTime, _currTimestep; - // all particles - std::vector<ControlParticle> _particles; - - // particle sets - std::vector<ControlParticleSet> mPartSets; - - // additional parameters for initing particles - LbmFloat _initTimeScale; - LbmVec _initPartOffset; - LbmVec _initPartScale; - LbmVec _initLastPartOffset; - LbmVec _initLastPartScale; - // mirror particles for loading? - string _initMirror; - - // row spacing paramter, e.g. use for approximation of kernel area/volume - LbmFloat _fluidSpacing; - // save current kernel weight - LbmFloat _kernelWeight; - // charateristic length in world coordinates for normalizatioon of forces - LbmFloat _charLength, _charLengthInv; - - - /*! do ani mesh CPS */ - void calculateCPS(string filename); - //! ani mesh cps params - ntlVec3Gfx mvCPSStart, mvCPSEnd; - gfxReal mCPSWidth, mCPSTimestep; - gfxReal mCPSTimeStart, mCPSTimeEnd; - gfxReal mCPSWeightFac; - - int mDebugInit; - - -protected: - // apply init transformations - void applyTrafos(); - - // helper function for init -> swap components everywhere - void swapCoords(int a,int b); - // helper function for init -> mirror time - void mirrorTime(); - - // helper, init given array - void initTimeArray(LbmFloat t, std::vector<ControlParticle> &parts); - - bool checkPointInside(ntlTree *tree, ntlVec3Gfx org, gfxReal &distance); - -private: -#ifdef WITH_CXX_GUARDEDALLOC - MEM_CXX_CLASS_ALLOC_FUNCS("ELBEEM:ControlParticles") -#endif -}; - - - -#endif - diff --git a/intern/elbeem/intern/elbeem.cpp b/intern/elbeem/intern/elbeem.cpp deleted file mode 100644 index 01e4801fed2..00000000000 --- a/intern/elbeem/intern/elbeem.cpp +++ /dev/null @@ -1,430 +0,0 @@ -/** \file - * \ingroup elbeem - */ -/****************************************************************************** - * - * El'Beem - Free Surface Fluid Simulation with the Lattice Boltzmann Method - * All code distributed as part of El'Beem is covered by the version 2 of the - * GNU General Public License. See the file COPYING for details. - * Copyright 2003-2006 Nils Thuerey - * - * Main program functions - */ - -#include "elbeem.h" -#include "ntl_blenderdumper.h" -extern "C" void elbeemCheckDebugEnv(void); - -#include "ntl_world.h" -#include "ntl_geometrymodel.h" - -/*****************************************************************************/ -// region of interest global vars -// currently used by e.g. fsgr solver -double guiRoiSX = 0.0; -double guiRoiSY = 0.0; -double guiRoiSZ = 0.0; -double guiRoiEX = 1.0; -double guiRoiEY = 1.0; -double guiRoiEZ = 1.0; -int guiRoiMaxLev=6, guiRoiMinLev=0; - -//! global raytracer pointer (=world) -ntlWorld *gpWorld = NULL; - - - -// API - -// reset elbeemSimulationSettings struct with defaults -extern "C" -void elbeemResetSettings(elbeemSimulationSettings *set) { - if(!set) return; - set->version = 3; - set->domainId = 0; - for(int i=0 ; i<3; i++) set->geoStart[i] = 0.0; - for(int i=0 ; i<3; i++) set->geoSize[i] = 1.0; - set->resolutionxyz = 64; - set->previewresxyz = 24; - set->realsize = 1.0; - set->viscosity = 0.000001; - - for(int i=0 ; i<2; i++) set->gravity[i] = 0.0; - set->gravity[2] = -9.81; - - set->animStart = 0; - set->aniFrameTime = 0.01; - set->noOfFrames = 10; - set->gstar = 0.005; - set->maxRefine = -1; - set->generateParticles = 0.0; - set->numTracerParticles = 0; - strcpy(set->outputPath,"./elbeemdata_"); - - set->channelSizeFrameTime=0; - set->channelFrameTime=NULL; - set->channelSizeViscosity=0; - set->channelViscosity=NULL; - set->channelSizeGravity=0; - set->channelGravity=NULL; - - set->domainobsType= FLUIDSIM_OBSTACLE_NOSLIP; - set->domainobsPartslip= 0.; - set->generateVertexVectors = 0; - set->surfaceSmoothing = 1.; - set->surfaceSubdivs = 1; - - set->farFieldSize = 0.; - set->runsimCallback = NULL; - set->runsimUserData = NULL; - - // init identity - for(int i=0; i<16; i++) set->surfaceTrafo[i] = 0.0; - for(int i=0; i<4; i++) set->surfaceTrafo[i*4+i] = 1.0; -} - -// start fluidsim init -extern "C" -int elbeemInit() { - setElbeemState( SIMWORLD_INITIALIZING ); - setElbeemErrorString("[none]"); - resetGlobalColorSetting(); - - elbeemCheckDebugEnv(); - debMsgStd("performElbeemSimulation",DM_NOTIFY,"El'Beem Simulation Init Start as Plugin, debugLevel:"<<gDebugLevel<<" ...\n", 2); - - // create world object with initial settings - ntlBlenderDumper *elbeem = new ntlBlenderDumper(); - gpWorld = elbeem; - return 0; -} - -// fluidsim end -extern "C" -int elbeemFree() { - - return 0; -} - -// start fluidsim init -extern "C" -int elbeemAddDomain(elbeemSimulationSettings *settings) { - // has to be inited... - if((getElbeemState() == SIMWORLD_INVALID) && (!gpWorld)) { elbeemInit(); } - if(getElbeemState() != SIMWORLD_INITIALIZING) { errFatal("elbeemAddDomain","Unable to init simulation world",SIMWORLD_INITERROR); } - // create domain with given settings - gpWorld->addDomain(settings); - return 0; -} - -// error message access -extern "C" -void elbeemGetErrorString(char *buffer) { - if(!buffer) return; - strncpy(buffer,getElbeemErrorString(),256); -} - -// reset elbeemMesh struct with zeroes -extern "C" -void elbeemResetMesh(elbeemMesh *mesh) { - if(!mesh) return; - // init typedef struct elbeemMesh - mesh->type = 0; - - mesh->parentDomainId = 0; - - /* vertices */ - mesh->numVertices = 0; - mesh->vertices = NULL; - - mesh->channelSizeVertices = 0; - mesh->channelVertices = NULL; - - /* triangles */ - mesh->numTriangles = 0; - mesh->triangles = NULL; - - /* animation channels */ - mesh->channelSizeTranslation = 0; - mesh->channelTranslation = NULL; - mesh->channelSizeRotation = 0; - mesh->channelRotation = NULL; - mesh->channelSizeScale = 0; - mesh->channelScale = NULL; - - /* active channel */ - mesh->channelSizeActive = 0; - mesh->channelActive = NULL; - - mesh->channelSizeInitialVel = 0; - mesh->channelInitialVel = NULL; - - mesh->localInivelCoords = 0; - - mesh->obstacleType= FLUIDSIM_OBSTACLE_NOSLIP; - mesh->obstaclePartslip= 0.; - mesh->obstacleImpactFactor= 1.; - - mesh->volumeInitType= OB_VOLUMEINIT_VOLUME; - - /* name of the mesh, mostly for debugging */ - mesh->name = "[unnamed]"; - - /* fluid control settings */ - mesh->cpsTimeStart = 0; - mesh->cpsTimeEnd = 0; - mesh->cpsQuality = 0; - - mesh->channelSizeAttractforceStrength = 0; - mesh->channelAttractforceStrength = NULL; - mesh->channelSizeAttractforceRadius = 0; - mesh->channelAttractforceRadius = NULL; - mesh->channelSizeVelocityforceStrength = 0; - mesh->channelVelocityforceStrength = NULL; - mesh->channelSizeVelocityforceRadius = 0; - mesh->channelVelocityforceRadius = NULL; -} - -int globalMeshCounter = 1; -// add mesh as fluidsim object -extern "C" -int elbeemAddMesh(elbeemMesh *mesh) { - int initType; - if(getElbeemState() != SIMWORLD_INITIALIZING) { errFatal("elbeemAddMesh","World and domain not initialized, call elbeemInit and elbeemAddDomain before...", SIMWORLD_INITERROR); } - - switch(mesh->type) { - case OB_FLUIDSIM_OBSTACLE: - if (mesh->obstacleType==FLUIDSIM_OBSTACLE_PARTSLIP) initType = FGI_BNDPART; - else if(mesh->obstacleType==FLUIDSIM_OBSTACLE_FREESLIP) initType = FGI_BNDFREE; - else /*if(mesh->obstacleType==FLUIDSIM_OBSTACLE_NOSLIP)*/ initType = FGI_BNDNO; - break; - case OB_FLUIDSIM_FLUID: initType = FGI_FLUID; break; - case OB_FLUIDSIM_INFLOW: initType = FGI_MBNDINFLOW; break; - case OB_FLUIDSIM_OUTFLOW: initType = FGI_MBNDOUTFLOW; break; - case OB_FLUIDSIM_CONTROL: initType = FGI_CONTROL; break; - default: return 1; // invalid type - } - - ntlGeometryObjModel *obj = new ntlGeometryObjModel( ); - gpWorld->getRenderGlobals()->getSimScene()->addGeoClass( obj ); - gpWorld->getRenderGlobals()->getRenderScene()->addGeoClass(obj); - obj->initModel( - mesh->numVertices, mesh->vertices, mesh->numTriangles, mesh->triangles, - mesh->channelSizeVertices, mesh->channelVertices ); - if(mesh->name) obj->setName(string(mesh->name)); - else { - char meshname[100]; - snprintf(meshname,100,"mesh%04d",globalMeshCounter); - obj->setName(string(meshname)); - } - globalMeshCounter++; - obj->setGeoInitId( mesh->parentDomainId+1 ); - obj->setGeoInitIntersect(true); - obj->setGeoInitType(initType); - - // abuse partslip value for control fluid: reverse control keys or not - if(initType == FGI_CONTROL) - obj->setGeoPartSlipValue(mesh->obstacleType); - else - obj->setGeoPartSlipValue(mesh->obstaclePartslip); - - obj->setGeoImpactFactor(mesh->obstacleImpactFactor); - - /* fluid control features */ - obj->setCpsTimeStart(mesh->cpsTimeStart); - obj->setCpsTimeEnd(mesh->cpsTimeEnd); - obj->setCpsQuality(mesh->cpsQuality); - - if((mesh->volumeInitType<VOLUMEINIT_VOLUME)||(mesh->volumeInitType>VOLUMEINIT_BOTH)) mesh->volumeInitType = VOLUMEINIT_VOLUME; - obj->setVolumeInit(mesh->volumeInitType); - // use channel instead, obj->setInitialVelocity( ntlVec3Gfx(mesh->iniVelocity[0], mesh->iniVelocity[1], mesh->iniVelocity[2]) ); - - obj->initChannels( - mesh->channelSizeTranslation, mesh->channelTranslation, - mesh->channelSizeRotation, mesh->channelRotation, - mesh->channelSizeScale, mesh->channelScale, - mesh->channelSizeActive, mesh->channelActive, - mesh->channelSizeInitialVel, mesh->channelInitialVel, - mesh->channelSizeAttractforceStrength, mesh->channelAttractforceStrength, - mesh->channelSizeAttractforceRadius, mesh->channelAttractforceRadius, - mesh->channelSizeVelocityforceStrength, mesh->channelVelocityforceStrength, - mesh->channelSizeVelocityforceRadius, mesh->channelVelocityforceRadius - ); - obj->setLocalCoordInivel( mesh->localInivelCoords ); - - debMsgStd("elbeemAddMesh",DM_MSG,"Added elbeem mesh: "<<obj->getName()<<" type="<<initType<<" "<<obj->getIsAnimated(), 9 ); - return 0; -} - -// do the actual simulation -extern "C" -int elbeemSimulate(void) { - if(!gpWorld) return 1; - - gpWorld->finishWorldInit(); - if( isSimworldOk() ) { - myTime_t timestart = getTime(); - gpWorld->renderAnimation(); - myTime_t timeend = getTime(); - - if(getElbeemState() != SIMWORLD_STOP) { - // ok, we're done... - delete gpWorld; - - gpWorld = NULL; - debMsgStd("elbeemSimulate",DM_NOTIFY, "El'Beem simulation done, time: "<<getTimeString(timeend-timestart)<<".\n", 2 ); - } else { - debMsgStd("elbeemSimulate",DM_NOTIFY, "El'Beem simulation stopped, time so far: "<<getTimeString(timeend-timestart)<<".", 2 ); - } - return 0; - } - - // failure... - return 1; -} - - -// continue a previously stopped simulation -extern "C" -int elbeemContinueSimulation(void) { - - if(getElbeemState() != SIMWORLD_STOP) { - errMsg("elbeemContinueSimulation","No running simulation found! Aborting..."); - if(gpWorld) delete gpWorld; - return 1; - } - - myTime_t timestart = getTime(); - gpWorld->renderAnimation(); - myTime_t timeend = getTime(); - - if(getElbeemState() != SIMWORLD_STOP) { - // ok, we're done... - delete gpWorld; - gpWorld = NULL; - debMsgStd("elbeemContinueSimulation",DM_NOTIFY, "El'Beem simulation done, time: "<<getTimeString(timeend-timestart)<<".\n", 2 ); - } else { - debMsgStd("elbeemContinueSimulation",DM_NOTIFY, "El'Beem simulation stopped, time so far: "<<getTimeString(timeend-timestart)<<".", 2 ); - } - return 0; -} - - -// global vector to flag values to remove -vector<int> gKeepVal; - -#define SIMPLIFY_FLOAT_EPSILON (1e-6f) -#define SIMPLIFY_DOUBLE_EPSILON (1e-12f) -#define SFLOATEQ(x,y) (ABS((x)-(y)) < SIMPLIFY_FLOAT_EPSILON) -#define SDOUBLEEQ(x,y) (ABS((x)-(y)) < SIMPLIFY_DOUBLE_EPSILON) -#define SVECFLOATEQ(x,y) ( \ - (ABS((x)[0]-(y)[0]) < SIMPLIFY_FLOAT_EPSILON) && \ - (ABS((x)[1]-(y)[1]) < SIMPLIFY_FLOAT_EPSILON) && \ - (ABS((x)[2]-(y)[2]) < SIMPLIFY_FLOAT_EPSILON) ) - -// helper function - simplify animation channels -extern "C" -int elbeemSimplifyChannelFloat(float *channel, int* size) { - bool changed = false; - int nsize = *size; - int orgsize = *size; - if(orgsize<1) return false; - gKeepVal.resize( orgsize ); - for(int i=0; i<orgsize; i++) { gKeepVal[i] = true; } - const bool debugSF = false; - - float last = channel[0 + 0]; - for(int i=1; i<orgsize; i++) { - float curr = channel[2*i + 0]; - bool remove = false; - if(SFLOATEQ(curr,last)) remove = true; - // dont remove if next value is different - if((remove)&&(i<orgsize-1)) { - float next = channel[2*(i+1)+0]; - if(!SFLOATEQ(next,curr)) remove = false; - } - if(remove) { - changed = true; - gKeepVal[i] = false; - nsize--; - } - if(debugSF) errMsg("elbeemSimplifyChannelFloat","i"<<i<<"/"<<orgsize<<" v"<<channel[ (i*2) + 0 ]<<" t"<<channel[ (i*2) + 1 ]<<" nsize="<<nsize<<" r"<<remove ); - last = curr; - } - - if(changed) { - nsize = 1; - for(int i=1; i<orgsize; i++) { - if(gKeepVal[i]) { - channel[ (nsize*2) + 0 ] = channel[ (i*2) + 0 ]; - channel[ (nsize*2) + 1 ] = channel[ (i*2) + 1 ]; - nsize++; - } - } - *size = nsize; - } - - if(debugSF) for(int i=1; i<nsize; i++) { - errMsg("elbeemSimplifyChannelFloat","n i"<<i<<"/"<<nsize<<" v"<<channel[ (i*2) + 0 ]<<" t"<<channel[ (i*2) + 1 ] ); - } - - return changed; -} - -extern "C" -int elbeemSimplifyChannelVec3(float *channel, int* size) { - bool changed = false; - int nsize = *size; - int orgsize = *size; - if(orgsize<1) return false; - gKeepVal.resize( orgsize ); - for(int i=0; i<orgsize; i++) { gKeepVal[i] = true; } - const bool debugVF = false; - - ntlVec3f last( channel[0 + 0], channel[0 + 1], channel[0 + 2] ); - for(int i=1; i<orgsize; i++) { - ntlVec3f curr( channel[4*i + 0], channel[4*i + 1], channel[4*i + 2]); - bool remove = false; - if(SVECFLOATEQ(curr,last)) remove = true; - // dont remove if next value is different - if((remove)&&(i<orgsize-1)) { - ntlVec3f next( channel[4*(i+1)+0], channel[4*(i+1)+1], channel[4*(i+1)+2]); - if(!SVECFLOATEQ(next,curr)) remove = false; - } - if(remove) { - changed = true; - gKeepVal[i] = false; - nsize--; - } - if(debugVF) errMsg("elbeemSimplifyChannelVec3","i"<<i<<"/"<<orgsize<<" v"<< - channel[ (i*4) + 0 ]<<","<< channel[ (i*4) + 1 ]<<","<< channel[ (i*4) + 2 ]<< - " t"<<channel[ (i*4) + 3 ]<<" nsize="<<nsize<<" r"<<remove ); - last = curr; - } - - if(changed) { - nsize = 1; - for(int i=1; i<orgsize; i++) { - if(gKeepVal[i]) { - for(int j=0; j<4; j++){ channel[ (nsize*4) + j ] = channel[ (i*4) + j ]; } - nsize++; - } - } - *size = nsize; - } - - if(debugVF) for(int i=1; i<nsize; i++) { - errMsg("elbeemSimplifyChannelVec3","n i"<<i<<"/"<<nsize<<" v"<< - channel[ (i*4) + 0 ]<<","<< channel[ (i*4) + 1 ]<<","<< channel[ (i*4) + 2 ]<< - " t"<<channel[ (i*4) + 3 ] ); - } - - return changed; -} - - -#undef SIMPLIFY_FLOAT_EPSILON -#undef SIMPLIFY_DOUBLE_EPSILON -#undef SFLOATEQ -#undef SDOUBLEEQ - diff --git a/intern/elbeem/intern/elbeem_control.cpp b/intern/elbeem/intern/elbeem_control.cpp deleted file mode 100644 index d033f535979..00000000000 --- a/intern/elbeem/intern/elbeem_control.cpp +++ /dev/null @@ -1,28 +0,0 @@ -/** \file - * \ingroup elbeem - */ -/****************************************************************************** - * - * El'Beem - Free Surface Fluid Simulation with the Lattice Boltzmann Method - * All code distributed as part of El'Beem is covered by the version 2 of the - * GNU General Public License. See the file COPYING for details. - * Copyright 2003-2006 Nils Thuerey - * - * Control API header - */ - -#include "elbeem.h" -#include "elbeem_control.h" - -// add mesh as fluidsim object -int elbeemControlAddSet(struct elbeemControl*) { - - return 0; -} - -int elbeemControlComputeMesh(struct elbeemMesh*) { - - - return 0; -} - diff --git a/intern/elbeem/intern/elbeem_control.h b/intern/elbeem/intern/elbeem_control.h deleted file mode 100644 index f8bb9798fc5..00000000000 --- a/intern/elbeem/intern/elbeem_control.h +++ /dev/null @@ -1,65 +0,0 @@ -/** \file - * \ingroup elbeem - */ -/****************************************************************************** - * - * El'Beem - Free Surface Fluid Simulation with the Lattice Boltzmann Method - * All code distributed as part of El'Beem is covered by the version 2 of the - * GNU General Public License. See the file COPYING for details. - * Copyright 2003-2006 Nils Thuerey - * - * Control API header - */ -#ifndef ELBEEMCONTROL_API_H -#define ELBEEMCONTROL_API_H - -// a single control particle set -typedef struct elbeemControl { - /* influence forces */ - float influenceAttraction; - float *channelInfluenceAttraction; - float channelSizeInfluenceAttraction; - - float influenceVelocity; - float *channelInfluenceVelocity; - float channelSizeInfluenceVelocity; - - float influenceMaxdist; - float *channelInfluenceMaxdist; - float channelSizeInfluenceMaxdist; - - /* influence force radii */ - float radiusAttraction; - float *channelRadiusAttraction; - float channelSizeRadiusAttraction; - - float radiusVelocity; - float *channelRadiusVelocity; - float channelSizeRadiusVelocity; - - float radiusMindist; - float *channelRadiusMindist; - float channelSizeRadiusMindist; - float radiusMaxdist; - float *channelRadiusMaxdist; - float channelSizeRadiusMaxdist; - - /* control particle positions/scale */ - float offset[3]; - float *channelOffset; - float channelSizeOffset; - - float scale[3]; - float *channelScale; - float channelSizeScale; - -} elbeemControl; - - -// add mesh as fluidsim object -int elbeemControlAddSet(struct elbeemControl*); - -// sample & track mesh control particles, TODO add return type... -int elbeemControlComputeMesh(struct elbeemMesh*); - -#endif // ELBEEMCONTROL_API_H diff --git a/intern/elbeem/intern/globals.h b/intern/elbeem/intern/globals.h deleted file mode 100644 index 3e8e2691942..00000000000 --- a/intern/elbeem/intern/globals.h +++ /dev/null @@ -1,10 +0,0 @@ -/** \file - * \ingroup elbeem - */ - -// required globals - -extern bool glob_mpactive; - -extern int glob_mpnum; -extern int glob_mpindex; diff --git a/intern/elbeem/intern/isosurface.cpp b/intern/elbeem/intern/isosurface.cpp deleted file mode 100644 index b270073a362..00000000000 --- a/intern/elbeem/intern/isosurface.cpp +++ /dev/null @@ -1,1122 +0,0 @@ -/** \file - * \ingroup elbeem - */ -/****************************************************************************** - * - * El'Beem - Free Surface Fluid Simulation with the Lattice Boltzmann Method - * Copyright 2003-2006 Nils Thuerey - * - * Marching Cubes surface mesh generation - * - *****************************************************************************/ - -#include "isosurface.h" -#include "mcubes_tables.h" -#include "particletracer.h" -#include <algorithm> -#include <stdio.h> -#include <cmath> - -#ifdef sun -#include "ieeefp.h" -#endif - -// just use default rounding for platforms where its not available -#ifndef round -#define round(x) (x) -#endif - -using std::isfinite; - -/****************************************************************************** - * Constructor - *****************************************************************************/ -IsoSurface::IsoSurface(double iso) : - ntlGeometryObject(), - mSizex(-1), mSizey(-1), mSizez(-1), - mpData(NULL), - mIsoValue( iso ), - mPoints(), - mUseFullEdgeArrays(false), - mpEdgeVerticesX(NULL), mpEdgeVerticesY(NULL), mpEdgeVerticesZ(NULL), - mEdgeArSize(-1), - mIndices(), - - mStart(0.0), mEnd(0.0), mDomainExtent(0.0), - mInitDone(false), - mSmoothSurface(0.0), mSmoothNormals(0.0), - mAcrossEdge(), mAdjacentFaces(), - mCutoff(-1), mCutArray(NULL), // off by default - mpIsoParts(NULL), mPartSize(0.), mSubdivs(0), - mFlagCnt(1), - mSCrad1(0.), mSCrad2(0.), mSCcenter(0.) -{ -} - - -/****************************************************************************** - * The real init... - *****************************************************************************/ -void IsoSurface::initializeIsosurface(int setx, int sety, int setz, ntlVec3Gfx extent) -{ - // range 1-10 (max due to subd array in triangulate) - if(mSubdivs<1) mSubdivs=1; - if(mSubdivs>10) mSubdivs=10; - - // init solver and size - mSizex = setx; - mSizey = sety; - if(setz == 1) {// 2D, create thin 2D surface - setz = 5; - } - mSizez = setz; - mDomainExtent = extent; - - /* check triangulation size (for raytraing) */ - if( ( mStart[0] >= mEnd[0] ) && ( mStart[1] >= mEnd[1] ) && ( mStart[2] >= mEnd[2] ) ){ - // extent was not set, use normalized one from parametrizer - mStart = ntlVec3Gfx(0.0) - extent*0.5; - mEnd = ntlVec3Gfx(0.0) + extent*0.5; - } - - // init - mIndices.clear(); - mPoints.clear(); - - int nodes = mSizez*mSizey*mSizex; - mpData = new float[nodes]; - for(int i=0;i<nodes;i++) { mpData[i] = 0.0; } - - // allocate edge arrays (last slices are never used...) - int initsize = -1; - if(mUseFullEdgeArrays) { - mEdgeArSize = nodes; - mpEdgeVerticesX = new int[nodes]; - mpEdgeVerticesY = new int[nodes]; - mpEdgeVerticesZ = new int[nodes]; - initsize = 3*nodes; - } else { - int sliceNodes = 2*mSizex*mSizey*mSubdivs*mSubdivs; - mEdgeArSize = sliceNodes; - mpEdgeVerticesX = new int[sliceNodes]; - mpEdgeVerticesY = new int[sliceNodes]; - mpEdgeVerticesZ = new int[sliceNodes]; - initsize = 3*sliceNodes; - } - for(int i=0;i<mEdgeArSize;i++) { mpEdgeVerticesX[i] = mpEdgeVerticesY[i] = mpEdgeVerticesZ[i] = -1; } - // WARNING - make sure this is consistent with calculateMemreqEstimate - - // marching cubes are ready - mInitDone = true; - debMsgStd("IsoSurface::initializeIsosurface",DM_MSG,"Inited, edgenodes:"<<initsize<<" subdivs:"<<mSubdivs<<" fulledg:"<<mUseFullEdgeArrays , 10); -} - - - -/*! Reset all values */ -void IsoSurface::resetAll(gfxReal val) { - int nodes = mSizez*mSizey*mSizex; - for(int i=0;i<nodes;i++) { mpData[i] = val; } -} - - -/****************************************************************************** - * Destructor - *****************************************************************************/ -IsoSurface::~IsoSurface( void ) -{ - if(mpData) delete [] mpData; - if(mpEdgeVerticesX) delete [] mpEdgeVerticesX; - if(mpEdgeVerticesY) delete [] mpEdgeVerticesY; - if(mpEdgeVerticesZ) delete [] mpEdgeVerticesZ; -} - - - - - -/****************************************************************************** - * triangulate the scalar field given by pointer - *****************************************************************************/ -void IsoSurface::triangulate( void ) -{ - double gsx,gsy,gsz; // grid spacing in x,y,z direction - double px,py,pz; // current position in grid in x,y,z direction - IsoLevelCube cubie; // struct for a small subcube - myTime_t tritimestart = getTime(); - - if(!mpData) { - errFatal("IsoSurface::triangulate","no LBM object, and no scalar field...!",SIMWORLD_INITERROR); - return; - } - - // get grid spacing (-2 to have same spacing as sim) - gsx = (mEnd[0]-mStart[0])/(double)(mSizex-2.0); - gsy = (mEnd[1]-mStart[1])/(double)(mSizey-2.0); - gsz = (mEnd[2]-mStart[2])/(double)(mSizez-2.0); - - // clean up previous frame - mIndices.clear(); - mPoints.clear(); - - // reset edge vertices - for(int i=0;i<mEdgeArSize;i++) { - mpEdgeVerticesX[i] = -1; - mpEdgeVerticesY[i] = -1; - mpEdgeVerticesZ[i] = -1; - } - - ntlVec3Gfx pos[8]; - float value[8]; - int cubeIndex; // index entry of the cube - int triIndices[12]; // vertex indices - int *eVert[12]; - IsoLevelVertex ilv; - - // edges between which points? - const int mcEdges[24] = { - 0,1, 1,2, 2,3, 3,0, - 4,5, 5,6, 6,7, 7,4, - 0,4, 1,5, 2,6, 3,7 }; - - const int cubieOffsetX[8] = { - 0,1,1,0, 0,1,1,0 }; - const int cubieOffsetY[8] = { - 0,0,1,1, 0,0,1,1 }; - const int cubieOffsetZ[8] = { - 0,0,0,0, 1,1,1,1 }; - - const int coAdd=2; - // let the cubes march - if(mSubdivs<=1) { - - pz = mStart[2]-gsz*0.5; - for(int k=1;k<(mSizez-2);k++) { - pz += gsz; - py = mStart[1]-gsy*0.5; - for(int j=1;j<(mSizey-2);j++) { - py += gsy; - px = mStart[0]-gsx*0.5; - for(int i=1;i<(mSizex-2);i++) { - px += gsx; - - value[0] = *getData(i ,j ,k ); - value[1] = *getData(i+1,j ,k ); - value[2] = *getData(i+1,j+1,k ); - value[3] = *getData(i ,j+1,k ); - value[4] = *getData(i ,j ,k+1); - value[5] = *getData(i+1,j ,k+1); - value[6] = *getData(i+1,j+1,k+1); - value[7] = *getData(i ,j+1,k+1); - - // check intersections of isosurface with edges, and calculate cubie index - cubeIndex = 0; - if (value[0] < mIsoValue) cubeIndex |= 1; - if (value[1] < mIsoValue) cubeIndex |= 2; - if (value[2] < mIsoValue) cubeIndex |= 4; - if (value[3] < mIsoValue) cubeIndex |= 8; - if (value[4] < mIsoValue) cubeIndex |= 16; - if (value[5] < mIsoValue) cubeIndex |= 32; - if (value[6] < mIsoValue) cubeIndex |= 64; - if (value[7] < mIsoValue) cubeIndex |= 128; - - // No triangles to generate? - if (mcEdgeTable[cubeIndex] == 0) { - continue; - } - - // where to look up if this point already exists - int edgek = 0; - if(mUseFullEdgeArrays) edgek=k; - const int baseIn = ISOLEVEL_INDEX( i+0, j+0, edgek+0); - eVert[ 0] = &mpEdgeVerticesX[ baseIn ]; - eVert[ 1] = &mpEdgeVerticesY[ baseIn + 1 ]; - eVert[ 2] = &mpEdgeVerticesX[ ISOLEVEL_INDEX( i+0, j+1, edgek+0) ]; - eVert[ 3] = &mpEdgeVerticesY[ baseIn ]; - - eVert[ 4] = &mpEdgeVerticesX[ ISOLEVEL_INDEX( i+0, j+0, edgek+1) ]; - eVert[ 5] = &mpEdgeVerticesY[ ISOLEVEL_INDEX( i+1, j+0, edgek+1) ]; - eVert[ 6] = &mpEdgeVerticesX[ ISOLEVEL_INDEX( i+0, j+1, edgek+1) ]; - eVert[ 7] = &mpEdgeVerticesY[ ISOLEVEL_INDEX( i+0, j+0, edgek+1) ]; - - eVert[ 8] = &mpEdgeVerticesZ[ baseIn ]; - eVert[ 9] = &mpEdgeVerticesZ[ ISOLEVEL_INDEX( i+1, j+0, edgek+0) ]; - eVert[10] = &mpEdgeVerticesZ[ ISOLEVEL_INDEX( i+1, j+1, edgek+0) ]; - eVert[11] = &mpEdgeVerticesZ[ ISOLEVEL_INDEX( i+0, j+1, edgek+0) ]; - - // grid positions - pos[0] = ntlVec3Gfx(px ,py ,pz); - pos[1] = ntlVec3Gfx(px+gsx,py ,pz); - pos[2] = ntlVec3Gfx(px+gsx,py+gsy,pz); - pos[3] = ntlVec3Gfx(px ,py+gsy,pz); - pos[4] = ntlVec3Gfx(px ,py ,pz+gsz); - pos[5] = ntlVec3Gfx(px+gsx,py ,pz+gsz); - pos[6] = ntlVec3Gfx(px+gsx,py+gsy,pz+gsz); - pos[7] = ntlVec3Gfx(px ,py+gsy,pz+gsz); - - // check all edges - for(int e=0;e<12;e++) { - if (mcEdgeTable[cubeIndex] & (1<<e)) { - // is the vertex already calculated? - if(*eVert[ e ] < 0) { - // interpolate edge - const int e1 = mcEdges[e*2 ]; - const int e2 = mcEdges[e*2+1]; - const ntlVec3Gfx p1 = pos[ e1 ]; // scalar field pos 1 - const ntlVec3Gfx p2 = pos[ e2 ]; // scalar field pos 2 - const float valp1 = value[ e1 ]; // scalar field val 1 - const float valp2 = value[ e2 ]; // scalar field val 2 - const float mu = (mIsoValue - valp1) / (valp2 - valp1); - - // init isolevel vertex - ilv.v = p1 + (p2-p1)*mu; - ilv.n = getNormal( i+cubieOffsetX[e1], j+cubieOffsetY[e1], k+cubieOffsetZ[e1]) * (1.0-mu) + - getNormal( i+cubieOffsetX[e2], j+cubieOffsetY[e2], k+cubieOffsetZ[e2]) * ( mu) ; - mPoints.push_back( ilv ); - - triIndices[e] = (mPoints.size()-1); - // store vertex - *eVert[ e ] = triIndices[e]; - } else { - // retrieve from vert array - triIndices[e] = *eVert[ e ]; - } - } // along all edges - } - - if( (i<coAdd+mCutoff) || (j<coAdd+mCutoff) || - ((mCutoff>0) && (k<coAdd)) ||// bottom layer - (i>mSizex-2-coAdd-mCutoff) || - (j>mSizey-2-coAdd-mCutoff) ) { - if(mCutArray) { - if(k < mCutArray[j*this->mSizex+i]) continue; - } else { continue; } - } - - // Create the triangles... - for(int e=0; mcTriTable[cubeIndex][e]!=-1; e+=3) { - mIndices.push_back( triIndices[ mcTriTable[cubeIndex][e+0] ] ); - mIndices.push_back( triIndices[ mcTriTable[cubeIndex][e+1] ] ); - mIndices.push_back( triIndices[ mcTriTable[cubeIndex][e+2] ] ); - } - - }//i - }// j - - // copy edge arrays - if(!mUseFullEdgeArrays) { - for(int j=0;j<(mSizey-0);j++) - for(int i=0;i<(mSizex-0);i++) { - //int edgek = 0; - const int dst = ISOLEVEL_INDEX( i+0, j+0, 0); - const int src = ISOLEVEL_INDEX( i+0, j+0, 1); - mpEdgeVerticesX[ dst ] = mpEdgeVerticesX[ src ]; - mpEdgeVerticesY[ dst ] = mpEdgeVerticesY[ src ]; - mpEdgeVerticesZ[ dst ] = mpEdgeVerticesZ[ src ]; - mpEdgeVerticesX[ src ]=-1; - mpEdgeVerticesY[ src ]=-1; - mpEdgeVerticesZ[ src ]=-1; - } - } // */ - - } // k - - // precalculate normals using an approximation of the scalar field gradient - for(int ni=0;ni<(int)mPoints.size();ni++) { normalize( mPoints[ni].n ); } - - } else { // subdivs - -#define EDGEAR_INDEX(Ai,Aj,Ak, Bi,Bj) ((mSizex*mSizey*mSubdivs*mSubdivs*(Ak))+\ - (mSizex*mSubdivs*((Aj)*mSubdivs+(Bj)))+((Ai)*mSubdivs)+(Bi)) - -#define ISOTRILININT(fi,fj,fk) ( \ - (1.-(fi))*(1.-(fj))*(1.-(fk))*orgval[0] + \ - ( (fi))*(1.-(fj))*(1.-(fk))*orgval[1] + \ - ( (fi))*( (fj))*(1.-(fk))*orgval[2] + \ - (1.-(fi))*( (fj))*(1.-(fk))*orgval[3] + \ - (1.-(fi))*(1.-(fj))*( (fk))*orgval[4] + \ - ( (fi))*(1.-(fj))*( (fk))*orgval[5] + \ - ( (fi))*( (fj))*( (fk))*orgval[6] + \ - (1.-(fi))*( (fj))*( (fk))*orgval[7] ) - - // use subdivisions - gfxReal subdfac = 1./(gfxReal)(mSubdivs); - gfxReal orgGsx = gsx; - gfxReal orgGsy = gsy; - gfxReal orgGsz = gsz; - gsx *= subdfac; - gsy *= subdfac; - gsz *= subdfac; - if(mUseFullEdgeArrays) { - errMsg("IsoSurface::triangulate","Disabling mUseFullEdgeArrays!"); - } - - // subdiv local arrays - gfxReal orgval[8]; - gfxReal subdAr[2][11][11]; // max 10 subdivs! - ParticleObject* *arppnt = new ParticleObject*[mSizez*mSizey*mSizex]; - - // construct pointers - // part test - int pInUse = 0; - int pUsedTest = 0; - // reset particles - // reset list array - for(int k=0;k<(mSizez);k++) - for(int j=0;j<(mSizey);j++) - for(int i=0;i<(mSizex);i++) { - arppnt[ISOLEVEL_INDEX(i,j,k)] = NULL; - } - if(mpIsoParts) { - for(vector<ParticleObject>::iterator pit= mpIsoParts->getParticlesBegin(); - pit!= mpIsoParts->getParticlesEnd(); pit++) { - if( (*pit).getActive()==false ) continue; - if( (*pit).getType()!=PART_DROP) continue; - (*pit).setNext(NULL); - } - // build per node lists - for(vector<ParticleObject>::iterator pit= mpIsoParts->getParticlesBegin(); - pit!= mpIsoParts->getParticlesEnd(); pit++) { - if( (*pit).getActive()==false ) continue; - if( (*pit).getType()!=PART_DROP) continue; - // check lifetime ignored here - ParticleObject *p = &(*pit); - const ntlVec3Gfx ppos = p->getPos(); - const int pi= (int)round(ppos[0])+0; - const int pj= (int)round(ppos[1])+0; - int pk= (int)round(ppos[2])+0;// no offset necessary - // 2d should be handled by solver. if(LBMDIM==2) { pk = 0; } - - if(pi<0) continue; - if(pj<0) continue; - if(pk<0) continue; - if(pi>mSizex-1) continue; - if(pj>mSizey-1) continue; - if(pk>mSizez-1) continue; - ParticleObject* &pnt = arppnt[ISOLEVEL_INDEX(pi,pj,pk)]; - if(pnt) { - // append - ParticleObject* listpnt = pnt; - while(listpnt) { - if(!listpnt->getNext()) { - listpnt->setNext(p); listpnt = NULL; - } else { - listpnt = listpnt->getNext(); - } - } - } else { - // start new list - pnt = p; - } - pInUse++; - } - } // mpIsoParts - - debMsgStd("IsoSurface::triangulate",DM_MSG,"Starting. Parts in use:"<<pInUse<<", Subdivs:"<<mSubdivs, 9); - pz = mStart[2]-(double)(0.*gsz)-0.5*orgGsz; - for(int ok=1;ok<(mSizez-2)*mSubdivs;ok++) { - pz += gsz; - const int k = ok/mSubdivs; - if(k<=0) continue; // skip zero plane - for(int j=1;j<(mSizey-2);j++) { - for(int i=1;i<(mSizex-2);i++) { - - orgval[0] = *getData(i ,j ,k ); - orgval[1] = *getData(i+1,j ,k ); - orgval[2] = *getData(i+1,j+1,k ); // with subdivs - orgval[3] = *getData(i ,j+1,k ); - orgval[4] = *getData(i ,j ,k+1); - orgval[5] = *getData(i+1,j ,k+1); - orgval[6] = *getData(i+1,j+1,k+1); // with subdivs - orgval[7] = *getData(i ,j+1,k+1); - - // prebuild subsampled array slice - const int sdkOffset = ok-k*mSubdivs; - for(int sdk=0; sdk<2; sdk++) - for(int sdj=0; sdj<mSubdivs+1; sdj++) - for(int sdi=0; sdi<mSubdivs+1; sdi++) { - subdAr[sdk][sdj][sdi] = ISOTRILININT(sdi*subdfac, sdj*subdfac, (sdkOffset+sdk)*subdfac); - } - - const int poDistOffset=2; - for(int pok=-poDistOffset; pok<1+poDistOffset; pok++) { - if(k+pok<0) continue; - if(k+pok>=mSizez-1) continue; - for(int poj=-poDistOffset; poj<1+poDistOffset; poj++) { - if(j+poj<0) continue; - if(j+poj>=mSizey-1) continue; - for(int poi=-poDistOffset; poi<1+poDistOffset; poi++) { - if(i+poi<0) continue; - if(i+poi>=mSizex-1) continue; - ParticleObject *p; - p = arppnt[ISOLEVEL_INDEX(i+poi,j+poj,k+pok)]; - while(p) { // */ - /* - for(vector<ParticleObject>::iterator pit= mpIsoParts->getParticlesBegin(); - pit!= mpIsoParts->getParticlesEnd(); pit++) { { { { - // debug test! , full list slow! - if(( (*pit).getActive()==false ) || ( (*pit).getType()!=PART_DROP)) continue; - ParticleObject *p; - p = &(*pit); // */ - - pUsedTest++; - ntlVec3Gfx ppos = p->getPos(); - const int spi= (int)round( (ppos[0]+1.-(gfxReal)i) *(gfxReal)mSubdivs-1.5); - const int spj= (int)round( (ppos[1]+1.-(gfxReal)j) *(gfxReal)mSubdivs-1.5); - const int spk= (int)round( (ppos[2]+1.-(gfxReal)k) *(gfxReal)mSubdivs-1.5)-sdkOffset; // why -2? - // 2d should be handled by solver. if(LBMDIM==2) { spk = 0; } - - gfxReal pfLen = p->getSize()*1.5*mPartSize; // test, was 1.1 - const gfxReal minPfLen = subdfac*0.8; - if(pfLen<minPfLen) pfLen = minPfLen; - //errMsg("ISOPPP"," at "<<PRINT_IJK<<" pp"<<ppos<<" sp"<<PRINT_VEC(spi,spj,spk)<<" pflen"<<pfLen ); - //errMsg("ISOPPP"," subdfac="<<subdfac<<" size"<<p->getSize()<<" ps"<<mPartSize ); - const int icellpsize = (int)(1.*pfLen*(gfxReal)mSubdivs)+1; - for(int swk=-icellpsize; swk<=icellpsize; swk++) { - if(spk+swk< 0) { continue; } - if(spk+swk> 1) { continue; } // */ - for(int swj=-icellpsize; swj<=icellpsize; swj++) { - if(spj+swj< 0) { continue; } - if(spj+swj>mSubdivs+0) { continue; } // */ - for(int swi=-icellpsize; swi<=icellpsize; swi++) { - if(spi+swi< 0) { continue; } - if(spi+swi>mSubdivs+0) { continue; } // */ - ntlVec3Gfx cellp = ntlVec3Gfx( - (1.5+(gfxReal)(spi+swi)) *subdfac + (gfxReal)(i-1), - (1.5+(gfxReal)(spj+swj)) *subdfac + (gfxReal)(j-1), - (1.5+(gfxReal)(spk+swk)+sdkOffset) *subdfac + (gfxReal)(k-1) - ); - //if(swi==0 && swj==0 && swk==0) subdAr[spk][spj][spi] = 1.; // DEBUG - // clip domain boundaries again - if(cellp[0]<1.) { continue; } - if(cellp[1]<1.) { continue; } - if(cellp[2]<1.) { continue; } - if(cellp[0]>(gfxReal)mSizex-3.) { continue; } - if(cellp[1]>(gfxReal)mSizey-3.) { continue; } - if(cellp[2]>(gfxReal)mSizez-3.) { continue; } - gfxReal len = norm(cellp-ppos); - gfxReal isoadd = 0.; - const gfxReal baseIsoVal = mIsoValue*1.1; - if(len<pfLen) { - isoadd = baseIsoVal*1.; - } else { - // falloff linear with pfLen (kernel size=2pfLen - isoadd = baseIsoVal*(1. - (len-pfLen)/(pfLen)); - } - if(isoadd<0.) { continue; } - //errMsg("ISOPPP"," at "<<PRINT_IJK<<" sp"<<PRINT_VEC(spi+swi,spj+swj,spk+swk)<<" cellp"<<cellp<<" pp"<<ppos << " l"<< len<< " add"<< isoadd); - const gfxReal arval = subdAr[spk+swk][spj+swj][spi+swi]; - if(arval>1.) { continue; } - subdAr[spk+swk][spj+swj][spi+swi] = arval + isoadd; - } } } - - p = p->getNext(); - } - } } } // poDist loops */ - - py = mStart[1]+(((double)j-0.5)*orgGsy)-gsy; - for(int sj=0;sj<mSubdivs;sj++) { - py += gsy; - px = mStart[0]+(((double)i-0.5)*orgGsx)-gsx; - for(int si=0;si<mSubdivs;si++) { - px += gsx; - value[0] = subdAr[0+0][sj+0][si+0]; - value[1] = subdAr[0+0][sj+0][si+1]; - value[2] = subdAr[0+0][sj+1][si+1]; - value[3] = subdAr[0+0][sj+1][si+0]; - value[4] = subdAr[0+1][sj+0][si+0]; - value[5] = subdAr[0+1][sj+0][si+1]; - value[6] = subdAr[0+1][sj+1][si+1]; - value[7] = subdAr[0+1][sj+1][si+0]; - - // check intersections of isosurface with edges, and calculate cubie index - cubeIndex = 0; - if (value[0] < mIsoValue) cubeIndex |= 1; - if (value[1] < mIsoValue) cubeIndex |= 2; // with subdivs - if (value[2] < mIsoValue) cubeIndex |= 4; - if (value[3] < mIsoValue) cubeIndex |= 8; - if (value[4] < mIsoValue) cubeIndex |= 16; - if (value[5] < mIsoValue) cubeIndex |= 32; // with subdivs - if (value[6] < mIsoValue) cubeIndex |= 64; - if (value[7] < mIsoValue) cubeIndex |= 128; - - if (mcEdgeTable[cubeIndex] > 0) { - - // where to look up if this point already exists - const int edgek = 0; - const int baseIn = EDGEAR_INDEX( i+0, j+0, edgek+0, si,sj); - eVert[ 0] = &mpEdgeVerticesX[ baseIn ]; - eVert[ 1] = &mpEdgeVerticesY[ baseIn + 1 ]; - eVert[ 2] = &mpEdgeVerticesX[ EDGEAR_INDEX( i, j, edgek+0, si+0,sj+1) ]; - eVert[ 3] = &mpEdgeVerticesY[ baseIn ]; - - eVert[ 4] = &mpEdgeVerticesX[ EDGEAR_INDEX( i, j, edgek+1, si+0,sj+0) ]; - eVert[ 5] = &mpEdgeVerticesY[ EDGEAR_INDEX( i, j, edgek+1, si+1,sj+0) ]; // with subdivs - eVert[ 6] = &mpEdgeVerticesX[ EDGEAR_INDEX( i, j, edgek+1, si+0,sj+1) ]; - eVert[ 7] = &mpEdgeVerticesY[ EDGEAR_INDEX( i, j, edgek+1, si+0,sj+0) ]; - - eVert[ 8] = &mpEdgeVerticesZ[ baseIn ]; - eVert[ 9] = &mpEdgeVerticesZ[ EDGEAR_INDEX( i, j, edgek+0, si+1,sj+0) ]; // with subdivs - eVert[10] = &mpEdgeVerticesZ[ EDGEAR_INDEX( i, j, edgek+0, si+1,sj+1) ]; - eVert[11] = &mpEdgeVerticesZ[ EDGEAR_INDEX( i, j, edgek+0, si+0,sj+1) ]; - - // grid positions - pos[0] = ntlVec3Gfx(px ,py ,pz); - pos[1] = ntlVec3Gfx(px+gsx,py ,pz); - pos[2] = ntlVec3Gfx(px+gsx,py+gsy,pz); // with subdivs - pos[3] = ntlVec3Gfx(px ,py+gsy,pz); - pos[4] = ntlVec3Gfx(px ,py ,pz+gsz); - pos[5] = ntlVec3Gfx(px+gsx,py ,pz+gsz); - pos[6] = ntlVec3Gfx(px+gsx,py+gsy,pz+gsz); // with subdivs - pos[7] = ntlVec3Gfx(px ,py+gsy,pz+gsz); - - // check all edges - for(int e=0;e<12;e++) { - if (mcEdgeTable[cubeIndex] & (1<<e)) { - // is the vertex already calculated? - if(*eVert[ e ] < 0) { - // interpolate edge - const int e1 = mcEdges[e*2 ]; - const int e2 = mcEdges[e*2+1]; - const ntlVec3Gfx p1 = pos[ e1 ]; // scalar field pos 1 - const ntlVec3Gfx p2 = pos[ e2 ]; // scalar field pos 2 - const float valp1 = value[ e1 ]; // scalar field val 1 - const float valp2 = value[ e2 ]; // scalar field val 2 - const float mu = (mIsoValue - valp1) / (valp2 - valp1); - - // init isolevel vertex - ilv.v = p1 + (p2-p1)*mu; // with subdivs - mPoints.push_back( ilv ); - triIndices[e] = (mPoints.size()-1); - // store vertex - *eVert[ e ] = triIndices[e]; - } else { - // retrieve from vert array - triIndices[e] = *eVert[ e ]; - } - } // along all edges - } - // removed cutoff treatment... - - // Create the triangles... - for(int e=0; mcTriTable[cubeIndex][e]!=-1; e+=3) { - mIndices.push_back( triIndices[ mcTriTable[cubeIndex][e+0] ] ); - mIndices.push_back( triIndices[ mcTriTable[cubeIndex][e+1] ] ); // with subdivs - mIndices.push_back( triIndices[ mcTriTable[cubeIndex][e+2] ] ); - //errMsg("TTT"," i1"<<mIndices[mIndices.size()-3]<<" "<< " i2"<<mIndices[mIndices.size()-2]<<" "<< " i3"<<mIndices[mIndices.size()-1]<<" "<< mIndices.size() ); - } - - } // triangles in edge table? - - }//si - }// sj - - }//i - }// j - - // copy edge arrays - for(int j=0;j<(mSizey-0)*mSubdivs;j++) - for(int i=0;i<(mSizex-0)*mSubdivs;i++) { - //int edgek = 0; - const int dst = EDGEAR_INDEX( 0, 0, 0, i,j); - const int src = EDGEAR_INDEX( 0, 0, 1, i,j); - mpEdgeVerticesX[ dst ] = mpEdgeVerticesX[ src ]; - mpEdgeVerticesY[ dst ] = mpEdgeVerticesY[ src ]; // with subdivs - mpEdgeVerticesZ[ dst ] = mpEdgeVerticesZ[ src ]; - mpEdgeVerticesX[ src ]=-1; - mpEdgeVerticesY[ src ]=-1; // with subdivs - mpEdgeVerticesZ[ src ]=-1; - } - // */ - - } // ok, k subdiv loop - - //delete [] subdAr; - delete [] arppnt; - computeNormals(); - } // with subdivs - - // perform smoothing - float smoSubdfac = 1.; - if(mSubdivs>0) { - //smoSubdfac = 1./(float)(mSubdivs); - smoSubdfac = pow(0.55,(double)mSubdivs); // slightly stronger - } - if(mSmoothSurface>0. || mSmoothNormals>0.) debMsgStd("IsoSurface::triangulate",DM_MSG,"Smoothing...",10); - if(mSmoothSurface>0.0) { - smoothSurface(mSmoothSurface*smoSubdfac, (mSmoothNormals<=0.0) ); - } - if(mSmoothNormals>0.0) { - smoothNormals(mSmoothNormals*smoSubdfac); - } - - myTime_t tritimeend = getTime(); - debMsgStd("IsoSurface::triangulate",DM_MSG,"took "<< getTimeString(tritimeend-tritimestart)<<", S("<<mSmoothSurface<<","<<mSmoothNormals<<"),"<< - " verts:"<<mPoints.size()<<" tris:"<<(mIndices.size()/3)<<" subdivs:"<<mSubdivs - , 10 ); - if(mpIsoParts) debMsgStd("IsoSurface::triangulate",DM_MSG,"parts:"<<mpIsoParts->getNumParticles(), 10); -} - - - - - -/****************************************************************************** - * Get triangles for rendering - *****************************************************************************/ -void IsoSurface::getTriangles(double t, vector<ntlTriangle> *triangles, - vector<ntlVec3Gfx> *vertices, - vector<ntlVec3Gfx> *normals, int objectId ) -{ - if(!mInitDone) { - debugOut("IsoSurface::getTriangles warning: Not initialized! ", 10); - return; - } - t = 0.; - //return; // DEBUG - - /* triangulate field */ - triangulate(); - //errMsg("TRIS"," "<<mIndices.size() ); - - // new output with vertice reuse - int iniVertIndex = (*vertices).size(); - int iniNormIndex = (*normals).size(); - if(iniVertIndex != iniNormIndex) { - errFatal("getTriangles Error","For '"<<mName<<"': Vertices and normal array sizes to not match!!!",SIMWORLD_GENERICERROR); - return; - } - //errMsg("NM"," ivi"<<iniVertIndex<<" ini"<<iniNormIndex<<" vs"<<vertices->size()<<" ns"<<normals->size()<<" ts"<<triangles->size() ); - //errMsg("NM"," ovs"<<mVertices.size()<<" ons"<<mVertNormals.size()<<" ots"<<mIndices.size() ); - - for(int i=0;i<(int)mPoints.size();i++) { - vertices->push_back( mPoints[i].v ); - } - for(int i=0;i<(int)mPoints.size();i++) { - normals->push_back( mPoints[i].n ); - } - - //errMsg("N2"," ivi"<<iniVertIndex<<" ini"<<iniNormIndex<<" vs"<<vertices->size()<<" ns"<<normals->size()<<" ts"<<triangles->size() ); - //errMsg("N2"," ovs"<<mVertices.size()<<" ons"<<mVertNormals.size()<<" ots"<<mIndices.size() ); - - for(int i=0;i<(int)mIndices.size();i+=3) { - const int smooth = 1; - int t1 = mIndices[i]; - int t2 = mIndices[i+1]; - int t3 = mIndices[i+2]; - //errMsg("NM"," tri"<<t1<<" "<<t2<<" "<<t3 ); - - ntlTriangle tri; - - tri.getPoints()[0] = t1+iniVertIndex; - tri.getPoints()[1] = t2+iniVertIndex; - tri.getPoints()[2] = t3+iniVertIndex; - - /* init flags */ - int flag = 0; - if(getVisible()){ flag |= TRI_GEOMETRY; } - if(getCastShadows() ) { - flag |= TRI_CASTSHADOWS; } - - /* init geo init id */ - int geoiId = getGeoInitId(); - if(geoiId > 0) { - flag |= (1<< (geoiId+4)); - flag |= mGeoInitType; - } - - tri.setFlags( flag ); - - /* triangle normal missing */ - tri.setNormal( ntlVec3Gfx(0.0) ); - tri.setSmoothNormals( smooth ); - tri.setObjectId( objectId ); - triangles->push_back( tri ); - } - //errMsg("N3"," ivi"<<iniVertIndex<<" ini"<<iniNormIndex<<" vs"<<vertices->size()<<" ns"<<normals->size()<<" ts"<<triangles->size() ); - return; -} - - - -inline ntlVec3Gfx IsoSurface::getNormal(int i, int j,int k) { - // WARNING - this requires a security boundary layer... - ntlVec3Gfx ret(0.0); - ret[0] = *getData(i-1,j ,k ) - - *getData(i+1,j ,k ); - ret[1] = *getData(i ,j-1,k ) - - *getData(i ,j+1,k ); - ret[2] = *getData(i ,j ,k-1 ) - - *getData(i ,j ,k+1 ); - return ret; -} - - - - -/****************************************************************************** - * - * Surface improvement, inspired by trimesh2 library - * (http://www.cs.princeton.edu/gfx/proj/trimesh2/) - * - *****************************************************************************/ - -void IsoSurface::setSmoothRad(float radi1, float radi2, ntlVec3Gfx mscc) { - mSCrad1 = radi1*radi1; - mSCrad2 = radi2*radi2; - mSCcenter = mscc; -} - -// compute normals for all generated triangles -void IsoSurface::computeNormals() { - for(int i=0;i<(int)mPoints.size();i++) { - mPoints[i].n = ntlVec3Gfx(0.); - } - - for(int i=0;i<(int)mIndices.size();i+=3) { - const int t1 = mIndices[i]; - const int t2 = mIndices[i+1]; - const int t3 = mIndices[i+2]; - const ntlVec3Gfx p1 = mPoints[t1].v; - const ntlVec3Gfx p2 = mPoints[t2].v; - const ntlVec3Gfx p3 = mPoints[t3].v; - const ntlVec3Gfx n1=p1-p2; - const ntlVec3Gfx n2=p2-p3; - const ntlVec3Gfx n3=p3-p1; - const gfxReal len1 = normNoSqrt(n1); - const gfxReal len2 = normNoSqrt(n2); - const gfxReal len3 = normNoSqrt(n3); - const ntlVec3Gfx norm = cross(n1,n2); - mPoints[t1].n += norm * (1./(len1*len3)); - mPoints[t2].n += norm * (1./(len1*len2)); - mPoints[t3].n += norm * (1./(len2*len3)); - } - - for(int i=0;i<(int)mPoints.size();i++) { - normalize(mPoints[i].n); - } -} - -// Diffuse a vector field at 1 vertex, weighted by -// a gaussian of width 1/sqrt(invsigma2) -bool IsoSurface::diffuseVertexField(ntlVec3Gfx *field, const int pointerScale, int src, float invsigma2, ntlVec3Gfx &target) -{ - if((neighbors[src].size()<1) || (pointareas[src]<=0.0)) return 0; - const ntlVec3Gfx srcp = mPoints[src].v; - const ntlVec3Gfx srcn = mPoints[src].n; - if(mSCrad1>0.0 && mSCrad2>0.0) { - ntlVec3Gfx dp = mSCcenter-srcp; dp[2] = 0.0; // only xy-plane - float rd = normNoSqrt(dp); - if(rd > mSCrad2) { - return 0; - } else if(rd > mSCrad1) { - // optimize? - float org = 1.0/sqrt(invsigma2); - org *= (1.0- (rd-mSCrad1) / (mSCrad2-mSCrad1)); - invsigma2 = 1.0/(org*org); - //errMsg("TRi","p"<<srcp<<" rd:"<<rd<<" r1:"<<mSCrad1<<" r2:"<<mSCrad2<<" org:"<<org<<" is:"<<invsigma2); - } else { - } - } - target = ntlVec3Gfx(0.0); - target += *(field+pointerScale*src) *pointareas[src]; - float smstrSum = pointareas[src]; - - int flag = mFlagCnt; - mFlagCnt++; - flags[src] = flag; - mDboundary = neighbors[src]; - while (!mDboundary.empty()) { - const int bbn = mDboundary.back(); - mDboundary.pop_back(); - if(flags[bbn]==flag) continue; - flags[bbn] = flag; - - // normal check - const float nvdot = dot(srcn, mPoints[bbn].n); // faster than before d2 calc? - if(nvdot <= 0.0f) continue; - - // gaussian weight of width 1/sqrt(invsigma2) - const float d2 = invsigma2 * normNoSqrt(mPoints[bbn].v - srcp); - if(d2 >= 9.0f) continue; - - // aggressive smoothing factor - float smstr = nvdot * pointareas[bbn]; - // Accumulate weight times field at neighbor - target += *(field+pointerScale*bbn)*smstr; - smstrSum += smstr; - - for(int i = 0; i < (int)neighbors[bbn].size(); i++) { - const int nn = neighbors[bbn][i]; - if (flags[nn] == flag) continue; - mDboundary.push_back(nn); - } - } - target /= smstrSum; - return 1; -} - - -// perform smoothing of the surface (and possible normals) -void IsoSurface::smoothSurface(float sigma, bool normSmooth) -{ - int nv = mPoints.size(); - if ((int)flags.size() != nv) flags.resize(nv); - int nf = mIndices.size()/3; - - { // need neighbors - vector<int> numneighbors(mPoints.size()); - int i; - for (i = 0; i < (int)mIndices.size()/3; i++) { - numneighbors[mIndices[i*3+0]]++; - numneighbors[mIndices[i*3+1]]++; - numneighbors[mIndices[i*3+2]]++; - } - - neighbors.clear(); - neighbors.resize(mPoints.size()); - for (i = 0; i < (int)mPoints.size(); i++) { - neighbors[i].clear(); - neighbors[i].reserve(numneighbors[i]+2); // Slop for boundaries - } - - for (i = 0; i < (int)mIndices.size()/3; i++) { - for (int j = 0; j < 3; j++) { - vector<int> &me = neighbors[ mIndices[i*3+j]]; - int n1 = mIndices[i*3+((j+1)%3)]; - int n2 = mIndices[i*3+((j+2)%3)]; - if (std::find(me.begin(), me.end(), n1) == me.end()) - me.push_back(n1); - if (std::find(me.begin(), me.end(), n2) == me.end()) - me.push_back(n2); - } - } - } // need neighbor - - { // need pointarea - pointareas.clear(); - pointareas.resize(nv); - cornerareas.clear(); - cornerareas.resize(nf); - - for (int i = 0; i < nf; i++) { - // Edges - ntlVec3Gfx e[3] = { - mPoints[mIndices[i*3+2]].v - mPoints[mIndices[i*3+1]].v, - mPoints[mIndices[i*3+0]].v - mPoints[mIndices[i*3+2]].v, - mPoints[mIndices[i*3+1]].v - mPoints[mIndices[i*3+0]].v }; - - // Compute corner weights - float area = 0.5f * norm( cross(e[0], e[1])); - float l2[3] = { normNoSqrt(e[0]), normNoSqrt(e[1]), normNoSqrt(e[2]) }; - float ew[3] = { l2[0] * (l2[1] + l2[2] - l2[0]), - l2[1] * (l2[2] + l2[0] - l2[1]), - l2[2] * (l2[0] + l2[1] - l2[2]) }; - if (ew[0] <= 0.0f) { - cornerareas[i][1] = -0.25f * l2[2] * area / - dot(e[0] , e[2]); - cornerareas[i][2] = -0.25f * l2[1] * area / - dot(e[0] , e[1]); - cornerareas[i][0] = area - cornerareas[i][1] - - cornerareas[i][2]; - } else if (ew[1] <= 0.0f) { - cornerareas[i][2] = -0.25f * l2[0] * area / - dot(e[1] , e[0]); - cornerareas[i][0] = -0.25f * l2[2] * area / - dot(e[1] , e[2]); - cornerareas[i][1] = area - cornerareas[i][2] - - cornerareas[i][0]; - } else if (ew[2] <= 0.0f) { - cornerareas[i][0] = -0.25f * l2[1] * area / - dot(e[2] , e[1]); - cornerareas[i][1] = -0.25f * l2[0] * area / - dot(e[2] , e[0]); - cornerareas[i][2] = area - cornerareas[i][0] - - cornerareas[i][1]; - } else { - float ewscale = 0.5f * area / (ew[0] + ew[1] + ew[2]); - for (int j = 0; j < 3; j++) - cornerareas[i][j] = ewscale * (ew[(j+1)%3] + - ew[(j+2)%3]); - } - - // FIX T50887: ensure pointareas are finite - if (!isfinite(cornerareas[i][0])) cornerareas[i][0] = 1e-6; - if (!isfinite(cornerareas[i][1])) cornerareas[i][1] = 1e-6; - if (!isfinite(cornerareas[i][2])) cornerareas[i][2] = 1e-6; - - pointareas[mIndices[i*3+0]] += cornerareas[i][0]; - pointareas[mIndices[i*3+1]] += cornerareas[i][1]; - pointareas[mIndices[i*3+2]] += cornerareas[i][2]; - } - - } // need pointarea - // */ - - float invsigma2 = 1.0f / (sigma*sigma); - - vector<ntlVec3Gfx> dflt(nv); - for (int i = 0; i < nv; i++) { - if(diffuseVertexField( &mPoints[0].v, 2, - i, invsigma2, dflt[i])) { - // Just keep the displacement - dflt[i] -= mPoints[i].v; - } else { dflt[i] = 0.0; } //?mPoints[i].v; } - } - - // Slightly better small-neighborhood approximation - for (int i = 0; i < nf; i++) { - ntlVec3Gfx c = mPoints[mIndices[i*3+0]].v + - mPoints[mIndices[i*3+1]].v + - mPoints[mIndices[i*3+2]].v; - c /= 3.0f; - for (int j = 0; j < 3; j++) { - int v = mIndices[i*3+j]; - ntlVec3Gfx d =(c - mPoints[v].v) * 0.5f; - dflt[v] += d * (cornerareas[i][j] / - pointareas[mIndices[i*3+j]] * - exp(-0.5f * invsigma2 * normNoSqrt(d)) ); - } - } - - // Filter displacement field - vector<ntlVec3Gfx> dflt2(nv); - for (int i = 0; i < nv; i++) { - if(diffuseVertexField( &dflt[0], 1, - i, invsigma2, dflt2[i])) { } - else { /*mPoints[i].v=0.0;*/ dflt2[i] = 0.0; }//dflt2[i]; } - } - - // Update vertex positions - for (int i = 0; i < nv; i++) { - mPoints[i].v += dflt[i] - dflt2[i]; // second Laplacian - } - - // when normals smoothing off, this cleans up quite well - // costs ca. 50% additional time though - float nsFac = 1.5f; - if(normSmooth) { float ninvsigma2 = 1.0f / (nsFac*nsFac*sigma*sigma); - for (int i = 0; i < nv; i++) { - if( diffuseVertexField( &mPoints[0].n, 2, i, ninvsigma2, dflt[i]) ) { - normalize(dflt[i]); - } else { - dflt[i] = mPoints[i].n; - } - } - for (int i = 0; i < nv; i++) { - mPoints[i].n = dflt[i]; - } - } // smoothNormals copy */ - - //errMsg("SMSURF","done v:"<<sigma); // DEBUG -} - -// only smoothen the normals -void IsoSurface::smoothNormals(float sigma) { - // reuse from smoothSurface - if(neighbors.size() != mPoints.size()) { - // need neighbor - vector<int> numneighbors(mPoints.size()); - int i; - for (i = 0; i < (int)mIndices.size()/3; i++) { - numneighbors[mIndices[i*3+0]]++; - numneighbors[mIndices[i*3+1]]++; - numneighbors[mIndices[i*3+2]]++; - } - - neighbors.clear(); - neighbors.resize(mPoints.size()); - for (i = 0; i < (int)mPoints.size(); i++) { - neighbors[i].clear(); - neighbors[i].reserve(numneighbors[i]+2); // Slop for boundaries - } - - for (i = 0; i < (int)mIndices.size()/3; i++) { - for (int j = 0; j < 3; j++) { - vector<int> &me = neighbors[ mIndices[i*3+j]]; - int n1 = mIndices[i*3+((j+1)%3)]; - int n2 = mIndices[i*3+((j+2)%3)]; - if (std::find(me.begin(), me.end(), n1) == me.end()) - me.push_back(n1); - if (std::find(me.begin(), me.end(), n2) == me.end()) - me.push_back(n2); - } - } - } // need neighbor - - { // need pointarea - int nf = mIndices.size()/3, nv = mPoints.size(); - pointareas.clear(); - pointareas.resize(nv); - cornerareas.clear(); - cornerareas.resize(nf); - - for (int i = 0; i < nf; i++) { - // Edges - ntlVec3Gfx e[3] = { - mPoints[mIndices[i*3+2]].v - mPoints[mIndices[i*3+1]].v, - mPoints[mIndices[i*3+0]].v - mPoints[mIndices[i*3+2]].v, - mPoints[mIndices[i*3+1]].v - mPoints[mIndices[i*3+0]].v }; - - // Compute corner weights - float area = 0.5f * norm( cross(e[0], e[1])); - float l2[3] = { normNoSqrt(e[0]), normNoSqrt(e[1]), normNoSqrt(e[2]) }; - float ew[3] = { l2[0] * (l2[1] + l2[2] - l2[0]), - l2[1] * (l2[2] + l2[0] - l2[1]), - l2[2] * (l2[0] + l2[1] - l2[2]) }; - if (ew[0] <= 0.0f) { - cornerareas[i][1] = -0.25f * l2[2] * area / - dot(e[0] , e[2]); - cornerareas[i][2] = -0.25f * l2[1] * area / - dot(e[0] , e[1]); - cornerareas[i][0] = area - cornerareas[i][1] - - cornerareas[i][2]; - } else if (ew[1] <= 0.0f) { - cornerareas[i][2] = -0.25f * l2[0] * area / - dot(e[1] , e[0]); - cornerareas[i][0] = -0.25f * l2[2] * area / - dot(e[1] , e[2]); - cornerareas[i][1] = area - cornerareas[i][2] - - cornerareas[i][0]; - } else if (ew[2] <= 0.0f) { - cornerareas[i][0] = -0.25f * l2[1] * area / - dot(e[2] , e[1]); - cornerareas[i][1] = -0.25f * l2[0] * area / - dot(e[2] , e[0]); - cornerareas[i][2] = area - cornerareas[i][0] - - cornerareas[i][1]; - } else { - float ewscale = 0.5f * area / (ew[0] + ew[1] + ew[2]); - for (int j = 0; j < 3; j++) - cornerareas[i][j] = ewscale * (ew[(j+1)%3] + - ew[(j+2)%3]); - } - - // FIX T50887: ensure pointareas are finite - if (!isfinite(cornerareas[i][0])) cornerareas[i][0] = 1e-6; - if (!isfinite(cornerareas[i][1])) cornerareas[i][1] = 1e-6; - if (!isfinite(cornerareas[i][2])) cornerareas[i][2] = 1e-6; - - pointareas[mIndices[i*3+0]] += cornerareas[i][0]; - pointareas[mIndices[i*3+1]] += cornerareas[i][1]; - pointareas[mIndices[i*3+2]] += cornerareas[i][2]; - } - - } // need pointarea - - int nv = mPoints.size(); - if ((int)flags.size() != nv) flags.resize(nv); - float invsigma2 = 1.0f / (sigma*sigma); - - vector<ntlVec3Gfx> nflt(nv); - for (int i = 0; i < nv; i++) { - if(diffuseVertexField( &mPoints[0].n, 2, i, invsigma2, nflt[i])) { - normalize(nflt[i]); - } else { nflt[i]=mPoints[i].n; } - } - - // copy results - for (int i = 0; i < nv; i++) { mPoints[i].n = nflt[i]; } -} - - diff --git a/intern/elbeem/intern/isosurface.h b/intern/elbeem/intern/isosurface.h deleted file mode 100644 index 93ea5ecb108..00000000000 --- a/intern/elbeem/intern/isosurface.h +++ /dev/null @@ -1,244 +0,0 @@ -/** \file - * \ingroup elbeem - */ -/****************************************************************************** - * - * El'Beem - Free Surface Fluid Simulation with the Lattice Boltzmann Method - * Copyright 2003-2006 Nils Thuerey - * - * Marching Cubes "displayer" - * - *****************************************************************************/ - -#ifndef ISOSURFACE_H - -#include "ntl_geometryobject.h" -#include "ntl_bsptree.h" - -#ifdef WITH_CXX_GUARDEDALLOC -# include "MEM_guardedalloc.h" -#endif - -#define ISO_STRICT_DEBUG 0 -#define ISOSTRICT_EXIT *((int *)0)=0; - -/* access some 3d array */ -#define ISOLEVEL_INDEX(ii,ij,ik) ((mSizex*mSizey*(ik))+(mSizex*(ij))+((ii))) - -class ParticleTracer; - -/* struct for a small cube in the scalar field */ -typedef struct { - ntlVec3Gfx pos[8]; - double value[8]; - int i,j,k; -} IsoLevelCube; - - -typedef struct { - ntlVec3Gfx v; // vertex - ntlVec3Gfx n; // vertex normal -} IsoLevelVertex; - -//! class to triangulate a scalar field, e.g. for -// the fluid surface, templated by scalar field access object -class IsoSurface : - public ntlGeometryObject //, public S -{ - - public: - - /*! Constructor */ - IsoSurface(double iso); - /*! Destructor */ - virtual ~IsoSurface(); - - /*! Init ararys etc. */ - virtual void initializeIsosurface(int setx, int sety, int setz, ntlVec3Gfx extent); - - /*! Reset all values */ - void resetAll(gfxReal val); - - /*! triangulate the scalar field given by pointer*/ - void triangulate( void ); - - /*! set particle pointer */ - void setParticles(ParticleTracer *pnt,float psize){ mpIsoParts = pnt; mPartSize=psize; }; - /*! set # of subdivisions, this has to be done before init! */ - void setSubdivs(int s) { - if(mInitDone) errFatal("IsoSurface::setSubdivs","Changing subdivs after init!", SIMWORLD_INITERROR); - if(s<1) s=1; - if(s>10) s=10; - mSubdivs = s; - } - int getSubdivs() { return mSubdivs;} - /*! set full edge settings, this has to be done before init! */ - void setUseFulledgeArrays(bool set) { - if(mInitDone) errFatal("IsoSurface::setUseFulledgeArrays","Changing usefulledge after init!", SIMWORLD_INITERROR); - mUseFullEdgeArrays = set;} - - protected: - - /* variables ... */ - - //! size - int mSizex, mSizey, mSizez; - - //! data pointer - float *mpData; - - //! Level of the iso surface - double mIsoValue; - - //! Store all the triangles vertices - vector<IsoLevelVertex> mPoints; - - //! use full arrays? (not for farfield) - bool mUseFullEdgeArrays; - //! Store indices of calculated points along the cubie edges - int *mpEdgeVerticesX; - int *mpEdgeVerticesY; - int *mpEdgeVerticesZ; - int mEdgeArSize; - - - //! vector for all the triangles (stored as 3 indices) - vector<unsigned int> mIndices; - - //! start and end vectors for the triangulation region to create triangles in - ntlVec3Gfx mStart, mEnd; - - //! normalized domain extent from parametrizer/visualizer - ntlVec3Gfx mDomainExtent; - - //! initialized? - bool mInitDone; - - //! amount of surface smoothing - float mSmoothSurface; - //! amount of normal smoothing - float mSmoothNormals; - - //! grid data - vector<int> mAcrossEdge; - vector< vector<int> > mAdjacentFaces; - - //! cutoff border area - int mCutoff; - //! cutoff height values - int *mCutArray; - //! particle pointer - ParticleTracer *mpIsoParts; - //! particle size - float mPartSize; - //! no of subdivisions - int mSubdivs; - - //! trimesh vars - vector<int> flags; - int mFlagCnt; - vector<ntlVec3Gfx> cornerareas; - vector<float> pointareas; - vector< vector<int> > neighbors; - - public: - // miscelleanous access functions - - //! set geometry start (for renderer) - void setStart(ntlVec3Gfx set) { mStart = set; }; - ntlVec3Gfx getStart() { return mStart; }; - //! set geometry end (for renderer) - void setEnd(ntlVec3Gfx set) { mEnd = set; }; - ntlVec3Gfx getEnd() { return mEnd; }; - //! set iso level value for surface reconstruction - inline void setIsolevel(double set) { mIsoValue = set; }; - //! set loop subdiv num - inline void setSmoothSurface(float set) { mSmoothSurface = set; }; - inline void setSmoothNormals(float set) { mSmoothNormals = set; }; - inline float getSmoothSurface() { return mSmoothSurface; } - inline float getSmoothNormals() { return mSmoothNormals; } - - // geometry object functions - virtual void getTriangles(double t, vector<ntlTriangle> *triangles, - vector<ntlVec3Gfx> *vertices, - vector<ntlVec3Gfx> *normals, int objectId ); - - //! for easy GUI detection get start of axis aligned bounding box, return NULL of no BB - virtual inline ntlVec3Gfx *getBBStart() { return &mStart; } - virtual inline ntlVec3Gfx *getBBEnd() { return &mEnd; } - - //! access data array - inline float* getData(){ return mpData; } - inline float* getData(int ii, int jj, int kk){ -#if ISO_STRICT_DEBUG==1 - if(ii<0){ errMsg("IsoStrict"," invX- |"<<ii<<","<<jj<<","<<kk); ISOSTRICT_EXIT; } - if(jj<0){ errMsg("IsoStrict"," invY- |"<<ii<<","<<jj<<","<<kk); ISOSTRICT_EXIT; } - if(kk<0){ errMsg("IsoStrict"," invZ- |"<<ii<<","<<jj<<","<<kk); ISOSTRICT_EXIT; } - if(ii>mSizex-1){ errMsg("IsoStrict"," invX+ |"<<ii<<","<<jj<<","<<kk); ISOSTRICT_EXIT; } - if(jj>mSizey-1){ errMsg("IsoStrict"," invY+ |"<<ii<<","<<jj<<","<<kk); ISOSTRICT_EXIT; } - if(kk>mSizez-1){ errMsg("IsoStrict"," invZ+ |"<<ii<<","<<jj<<","<<kk); ISOSTRICT_EXIT; } - return mpData + ISOLEVEL_INDEX(ii, jj, kk); -#else //ISO_STRICT_DEBUG==1 - return mpData + ISOLEVEL_INDEX(ii, jj, kk); -#endif - } - inline float* lbmGetData(int ii, int jj, int kk){ -#if ISO_STRICT_DEBUG==1 - ii++; jj++; kk++; - if(ii<0){ errMsg("IsoStrict"," invX- |"<<ii<<","<<jj<<","<<kk); ISOSTRICT_EXIT; } - if(jj<0){ errMsg("IsoStrict"," invY- |"<<ii<<","<<jj<<","<<kk); ISOSTRICT_EXIT; } - if(kk<0){ errMsg("IsoStrict"," invZ- |"<<ii<<","<<jj<<","<<kk); ISOSTRICT_EXIT; } - if(ii>mSizex-1){ errMsg("IsoStrict"," invX+ |"<<ii<<","<<jj<<","<<kk); ISOSTRICT_EXIT; } - if(jj>mSizey-1){ errMsg("IsoStrict"," invY+ |"<<ii<<","<<jj<<","<<kk); ISOSTRICT_EXIT; } - if(kk>mSizez-1){ errMsg("IsoStrict"," invZ+ |"<<ii<<","<<jj<<","<<kk); ISOSTRICT_EXIT; } - return mpData + ISOLEVEL_INDEX(ii, jj, kk); -#else //ISO_STRICT_DEBUG==1 - return mpData + ISOLEVEL_INDEX(ii+1,jj+1,kk+1); -#endif - } - //! set cut off border - inline void setCutoff(int set) { mCutoff = set; }; - //! set cut off border - inline void setCutArray(int *set) { mCutArray = set; }; - - //! OpenGL viz "interface" - unsigned int getIsoVertexCount() { - return mPoints.size(); - } - unsigned int getIsoIndexCount() { - return mIndices.size(); - } - char* getIsoVertexArray() { - return (char *) &(mPoints[0]); - } - unsigned int *getIsoIndexArray() { - return &(mIndices[0]); - } - - // surface smoothing functions - void setSmoothRad(float radi1, float radi2, ntlVec3Gfx mscc); - void smoothSurface(float val, bool smoothNorm); - void smoothNormals(float val); - void computeNormals(); - - protected: - - //! compute normal - inline ntlVec3Gfx getNormal(int i, int j,int k); - //! smoothing helper function - bool diffuseVertexField(ntlVec3Gfx *field, int pointerScale, int v, float invsigma2, ntlVec3Gfx &flt); - vector<int> mDboundary; - float mSCrad1, mSCrad2; - ntlVec3Gfx mSCcenter; - -private: -#ifdef WITH_CXX_GUARDEDALLOC - MEM_CXX_CLASS_ALLOC_FUNCS("ELBEEM:IsoSurface") -#endif -}; - - -#define ISOSURFACE_H -#endif - - diff --git a/intern/elbeem/intern/loop_tools.h b/intern/elbeem/intern/loop_tools.h deleted file mode 100644 index d1ef03d6667..00000000000 --- a/intern/elbeem/intern/loop_tools.h +++ /dev/null @@ -1,186 +0,0 @@ -/** \file - * \ingroup elbeem - */ - -// advance pointer in main loop -#define ADVANCE_POINTERS(p) \ - ccel += (QCELLSTEP*(p)); \ - tcel += (QCELLSTEP*(p)); \ - pFlagSrc+= (p); \ - pFlagDst+= (p); \ - i+= (p); - -#define MAX_CALC_ARR 4 - -// >>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>> -// init region vars -#define GRID_REGION_INIT() \ - const int istart = -1+gridLoopBound; \ - const int iend = mLevel[mMaxRefine].lSizex-1-gridLoopBound; \ - LbmFloat calcCurrentMass=0; \ - LbmFloat calcCurrentVolume=0; \ - int calcCellsFilled=0; \ - int calcCellsEmptied=0; \ - int calcNumUsedCells=0; \ - /* This is a generic macro, and now all it's users are using all variables. */ \ - (void)calcCurrentMass; \ - (void)calcCellsFilled \ - - - - -// ----------------------------------------------------------------------------------- -// serial stuff -#if PARALLEL!=1 - -#define PERFORM_USQRMAXCHECK USQRMAXCHECK(usqr,ux,uy,uz, mMaxVlen, mMxvx,mMxvy,mMxvz); -#define LIST_EMPTY(x) mListEmpty.push_back( x ); -#define LIST_FULL(x) mListFull.push_back( x ); -#define FSGR_ADDPART(x) mpParticles->addFullParticle( x ); - -// >>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>> -#define GRID_REGION_START() \ - { /* main_region */ \ - int kstart=getForZMinBnd(), kend=getForZMaxBnd(mMaxRefine); \ - if(gridLoopBound>0){ kstart=getForZMin1(), kend=getForZMax1(mMaxRefine); } \ - int kdir = 1; \ - int jstart = gridLoopBound; \ - int jend = mLevel[mMaxRefine].lSizey-gridLoopBound; \ - const int id=0; \ - LbmFloat *ccel = NULL, *tcel = NULL; \ - CellFlagType *pFlagSrc=NULL, *pFlagDst=NULL; \ - if(mLevel[mMaxRefine].setCurr==1) { \ - kdir = -1; \ - int temp = kend; \ - kend = kstart-1; \ - kstart = temp-1; \ - temp = id; /* dummy remove warning */ \ - } \ - - - - - -// ----------------------------------------------------------------------------------- -#else // PARALLEL==1 - -//#include "paraloop.h" -#define PERFORM_USQRMAXCHECK USQRMAXCHECK(usqr,ux,uy,uz, calcMaxVlen, calcMxvx,calcMxvy,calcMxvz); -#define LIST_EMPTY(x) calcListEmpty.push_back( x ); -#define LIST_FULL(x) calcListFull.push_back( x ); -#define FSGR_ADDPART(x) calcListParts.push_back( x ); - - -// parallel region -//was: # pragma omp parallel default(shared) -#if COMPRESSGRIDS!=1 - // requires compressed grids...! - ERROR! -#endif - -// loop start -#define GRID_REGION_START() \ - { \ - \ - \ - if(mSizez<2) { \ - mPanic = 1; \ - errFatal("ParaLoop::2D","Not valid...!", SIMWORLD_GENERICERROR); \ - } \ - \ - \ - vector<LbmPoint> calcListFull; \ - vector<LbmPoint> calcListEmpty; \ - vector<ParticleObject> calcListParts; \ - LbmFloat calcMxvx, calcMxvy, calcMxvz, calcMaxVlen; \ - calcMxvx = calcMxvy = calcMxvz = calcMaxVlen = 0.0; \ - calcListEmpty.reserve(mListEmpty.capacity() / omp_get_num_threads() ); \ - calcListFull.reserve( mListFull.capacity() / omp_get_num_threads() ); \ - calcListParts.reserve(mSizex); \ - \ - \ - const int id = omp_get_thread_num(); \ - const int Nthrds = omp_get_num_threads(); \ - \ - \ - \ - \ - \ - int kdir = 1; \ - \ - int kstart=getForZMinBnd(), kend=getForZMaxBnd(mMaxRefine); \ - if(gridLoopBound>0){ kstart=getForZMin1(); kend=getForZMax1(mMaxRefine); } \ - LbmFloat *ccel = NULL, *tcel = NULL; \ - CellFlagType *pFlagSrc=NULL, *pFlagDst=NULL; \ - \ - \ - if(mLevel[mMaxRefine].setCurr==1) { \ - kdir = -1; \ - int temp = kend; \ - kend = kstart-1; \ - kstart = temp-1; \ - } \ - \ - const int Nj = mLevel[mMaxRefine].lSizey; \ - int jstart = 0+( (id * Nj ) / Nthrds ); \ - int jend = 0+(((id+1) * Nj ) / Nthrds ); \ - if( ((Nj/Nthrds) *Nthrds) != Nj) { \ - errMsg("LbmFsgrSolver","Invalid domain size Nj="<<Nj<<" Nthrds="<<Nthrds); \ - } \ - \ - if(jstart<gridLoopBound) jstart = gridLoopBound; \ - if(jend>mLevel[mMaxRefine].lSizey-gridLoopBound) jend = mLevel[mMaxRefine].lSizey-gridLoopBound; \ - \ - debMsgStd("ParaLoop::OMP",DM_MSG,"Thread:"<<id<<" i:"<<istart<<"-"<<iend<<" j:"<<jstart<<"-"<<jend<<", k:"<<kstart<<"-"<<kend<<" ", 1); \ - \ - - - - -// para GRID LOOP END is parainc3 - -#endif // PARALLEL==1 - - -// ----------------------------------------------------------------------------------- - -// >>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>> -#define GRID_LOOP_START() \ - for(int k=kstart;k!=kend;k+=kdir) { \ - pFlagSrc = &RFLAG(lev, istart, jstart, k, SRCS(lev)); \ - pFlagDst = &RFLAG(lev, istart, jstart, k, TSET(lev)); \ - ccel = RACPNT(lev, istart, jstart, k, SRCS(lev)); \ - tcel = RACPNT(lev, istart, jstart, k, TSET(lev)); \ - for(int j=jstart;j!=jend;++j) { \ - /* for(int i=0;i<mLevel[lev].lSizex-2; ) { */ \ - for(int i=istart;i!=iend; ) { \ - ADVANCE_POINTERS(1); \ - - - - -// >>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>> -#define GRID_LOOPREG_END() \ - \ - } /* i */ \ - int i=0; \ - ADVANCE_POINTERS(2*gridLoopBound); \ - } /* j */ \ - /* COMPRESSGRIDS!=1 */ \ - /* int i=0; */ \ - /* ADVANCE_POINTERS(mLevel[lev].lSizex*2); */ \ - } /* all cell loop k,j,i */ \ - if(doReduce) { } /* dummy remove warning */ \ - } /* main_region */ \ - \ - - - - -// old loop for COMPRESSGRIDS==0 -#define old__GRID_LOOP_START() \ - for(int k=kstart;k<kend;++k) { \ - for(int j=1;j<mLevel[lev].lSizey-1;++j) { \ - for(int i=0;i<mLevel[lev].lSizex-2; ) { - - diff --git a/intern/elbeem/intern/mcubes_tables.h b/intern/elbeem/intern/mcubes_tables.h deleted file mode 100644 index df83578d176..00000000000 --- a/intern/elbeem/intern/mcubes_tables.h +++ /dev/null @@ -1,300 +0,0 @@ -/** \file - * \ingroup elbeem - */ - -/* which edges are needed ? */ -/* cf. http://astronomy.swin.edu.au/~pbourke/modelling/polygonise/ */ -static const short mcEdgeTable[256]={ - 0x0 , 0x109, 0x203, 0x30a, 0x406, 0x50f, 0x605, 0x70c, - 0x80c, 0x905, 0xa0f, 0xb06, 0xc0a, 0xd03, 0xe09, 0xf00, - 0x190, 0x99 , 0x393, 0x29a, 0x596, 0x49f, 0x795, 0x69c, - 0x99c, 0x895, 0xb9f, 0xa96, 0xd9a, 0xc93, 0xf99, 0xe90, - 0x230, 0x339, 0x33 , 0x13a, 0x636, 0x73f, 0x435, 0x53c, - 0xa3c, 0xb35, 0x83f, 0x936, 0xe3a, 0xf33, 0xc39, 0xd30, - 0x3a0, 0x2a9, 0x1a3, 0xaa , 0x7a6, 0x6af, 0x5a5, 0x4ac, - 0xbac, 0xaa5, 0x9af, 0x8a6, 0xfaa, 0xea3, 0xda9, 0xca0, - 0x460, 0x569, 0x663, 0x76a, 0x66 , 0x16f, 0x265, 0x36c, - 0xc6c, 0xd65, 0xe6f, 0xf66, 0x86a, 0x963, 0xa69, 0xb60, - 0x5f0, 0x4f9, 0x7f3, 0x6fa, 0x1f6, 0xff , 0x3f5, 0x2fc, - 0xdfc, 0xcf5, 0xfff, 0xef6, 0x9fa, 0x8f3, 0xbf9, 0xaf0, - 0x650, 0x759, 0x453, 0x55a, 0x256, 0x35f, 0x55 , 0x15c, - 0xe5c, 0xf55, 0xc5f, 0xd56, 0xa5a, 0xb53, 0x859, 0x950, - 0x7c0, 0x6c9, 0x5c3, 0x4ca, 0x3c6, 0x2cf, 0x1c5, 0xcc , - 0xfcc, 0xec5, 0xdcf, 0xcc6, 0xbca, 0xac3, 0x9c9, 0x8c0, - 0x8c0, 0x9c9, 0xac3, 0xbca, 0xcc6, 0xdcf, 0xec5, 0xfcc, - 0xcc , 0x1c5, 0x2cf, 0x3c6, 0x4ca, 0x5c3, 0x6c9, 0x7c0, - 0x950, 0x859, 0xb53, 0xa5a, 0xd56, 0xc5f, 0xf55, 0xe5c, - 0x15c, 0x55 , 0x35f, 0x256, 0x55a, 0x453, 0x759, 0x650, - 0xaf0, 0xbf9, 0x8f3, 0x9fa, 0xef6, 0xfff, 0xcf5, 0xdfc, - 0x2fc, 0x3f5, 0xff , 0x1f6, 0x6fa, 0x7f3, 0x4f9, 0x5f0, - 0xb60, 0xa69, 0x963, 0x86a, 0xf66, 0xe6f, 0xd65, 0xc6c, - 0x36c, 0x265, 0x16f, 0x66 , 0x76a, 0x663, 0x569, 0x460, - 0xca0, 0xda9, 0xea3, 0xfaa, 0x8a6, 0x9af, 0xaa5, 0xbac, - 0x4ac, 0x5a5, 0x6af, 0x7a6, 0xaa , 0x1a3, 0x2a9, 0x3a0, - 0xd30, 0xc39, 0xf33, 0xe3a, 0x936, 0x83f, 0xb35, 0xa3c, - 0x53c, 0x435, 0x73f, 0x636, 0x13a, 0x33 , 0x339, 0x230, - 0xe90, 0xf99, 0xc93, 0xd9a, 0xa96, 0xb9f, 0x895, 0x99c, - 0x69c, 0x795, 0x49f, 0x596, 0x29a, 0x393, 0x99 , 0x190, - 0xf00, 0xe09, 0xd03, 0xc0a, 0xb06, 0xa0f, 0x905, 0x80c, - 0x70c, 0x605, 0x50f, 0x406, 0x30a, 0x203, 0x109, 0x0 }; - -/* triangles for the 256 intersection possibilities */ -/* cf. http://astronomy.swin.edu.au/~pbourke/modelling/polygonise/ */ -static const short mcTriTable[256][16] = { - {-1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1}, - {0, 8, 3, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1}, - {0, 1, 9, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1}, - {1, 8, 3, 9, 8, 1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1}, - {1, 2, 10, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1}, - {0, 8, 3, 1, 2, 10, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1}, - {9, 2, 10, 0, 2, 9, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1}, - {2, 8, 3, 2, 10, 8, 10, 9, 8, -1, -1, -1, -1, -1, -1, -1}, - {3, 11, 2, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1}, - {0, 11, 2, 8, 11, 0, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1}, - {1, 9, 0, 2, 3, 11, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1}, - {1, 11, 2, 1, 9, 11, 9, 8, 11, -1, -1, -1, -1, -1, -1, -1}, - {3, 10, 1, 11, 10, 3, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1}, - {0, 10, 1, 0, 8, 10, 8, 11, 10, -1, -1, -1, -1, -1, -1, -1}, - {3, 9, 0, 3, 11, 9, 11, 10, 9, -1, -1, -1, -1, -1, -1, -1}, - {9, 8, 10, 10, 8, 11, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1}, - {4, 7, 8, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1}, - {4, 3, 0, 7, 3, 4, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1}, - {0, 1, 9, 8, 4, 7, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1}, - {4, 1, 9, 4, 7, 1, 7, 3, 1, -1, -1, -1, -1, -1, -1, -1}, - {1, 2, 10, 8, 4, 7, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1}, - {3, 4, 7, 3, 0, 4, 1, 2, 10, -1, -1, -1, -1, -1, -1, -1}, - {9, 2, 10, 9, 0, 2, 8, 4, 7, -1, -1, -1, -1, -1, -1, -1}, - {2, 10, 9, 2, 9, 7, 2, 7, 3, 7, 9, 4, -1, -1, -1, -1}, - {8, 4, 7, 3, 11, 2, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1}, - {11, 4, 7, 11, 2, 4, 2, 0, 4, -1, -1, -1, -1, -1, -1, -1}, - {9, 0, 1, 8, 4, 7, 2, 3, 11, -1, -1, -1, -1, -1, -1, -1}, - {4, 7, 11, 9, 4, 11, 9, 11, 2, 9, 2, 1, -1, -1, -1, -1}, - {3, 10, 1, 3, 11, 10, 7, 8, 4, -1, -1, -1, -1, -1, -1, -1}, - {1, 11, 10, 1, 4, 11, 1, 0, 4, 7, 11, 4, -1, -1, -1, -1}, - {4, 7, 8, 9, 0, 11, 9, 11, 10, 11, 0, 3, -1, -1, -1, -1}, - {4, 7, 11, 4, 11, 9, 9, 11, 10, -1, -1, -1, -1, -1, -1, -1}, - {9, 5, 4, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1}, - {9, 5, 4, 0, 8, 3, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1}, - {0, 5, 4, 1, 5, 0, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1}, - {8, 5, 4, 8, 3, 5, 3, 1, 5, -1, -1, -1, -1, -1, -1, -1}, - {1, 2, 10, 9, 5, 4, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1}, - {3, 0, 8, 1, 2, 10, 4, 9, 5, -1, -1, -1, -1, -1, -1, -1}, - {5, 2, 10, 5, 4, 2, 4, 0, 2, -1, -1, -1, -1, -1, -1, -1}, - {2, 10, 5, 3, 2, 5, 3, 5, 4, 3, 4, 8, -1, -1, -1, -1}, - {9, 5, 4, 2, 3, 11, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1}, - {0, 11, 2, 0, 8, 11, 4, 9, 5, -1, -1, -1, -1, -1, -1, -1}, - {0, 5, 4, 0, 1, 5, 2, 3, 11, -1, -1, -1, -1, -1, -1, -1}, - {2, 1, 5, 2, 5, 8, 2, 8, 11, 4, 8, 5, -1, -1, -1, -1}, - {10, 3, 11, 10, 1, 3, 9, 5, 4, -1, -1, -1, -1, -1, -1, -1}, - {4, 9, 5, 0, 8, 1, 8, 10, 1, 8, 11, 10, -1, -1, -1, -1}, - {5, 4, 0, 5, 0, 11, 5, 11, 10, 11, 0, 3, -1, -1, -1, -1}, - {5, 4, 8, 5, 8, 10, 10, 8, 11, -1, -1, -1, -1, -1, -1, -1}, - {9, 7, 8, 5, 7, 9, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1}, - {9, 3, 0, 9, 5, 3, 5, 7, 3, -1, -1, -1, -1, -1, -1, -1}, - {0, 7, 8, 0, 1, 7, 1, 5, 7, -1, -1, -1, -1, -1, -1, -1}, - {1, 5, 3, 3, 5, 7, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1}, - {9, 7, 8, 9, 5, 7, 10, 1, 2, -1, -1, -1, -1, -1, -1, -1}, - {10, 1, 2, 9, 5, 0, 5, 3, 0, 5, 7, 3, -1, -1, -1, -1}, - {8, 0, 2, 8, 2, 5, 8, 5, 7, 10, 5, 2, -1, -1, -1, -1}, - {2, 10, 5, 2, 5, 3, 3, 5, 7, -1, -1, -1, -1, -1, -1, -1}, - {7, 9, 5, 7, 8, 9, 3, 11, 2, -1, -1, -1, -1, -1, -1, -1}, - {9, 5, 7, 9, 7, 2, 9, 2, 0, 2, 7, 11, -1, -1, -1, -1}, - {2, 3, 11, 0, 1, 8, 1, 7, 8, 1, 5, 7, -1, -1, -1, -1}, - {11, 2, 1, 11, 1, 7, 7, 1, 5, -1, -1, -1, -1, -1, -1, -1}, - {9, 5, 8, 8, 5, 7, 10, 1, 3, 10, 3, 11, -1, -1, -1, -1}, - {5, 7, 0, 5, 0, 9, 7, 11, 0, 1, 0, 10, 11, 10, 0, -1}, - {11, 10, 0, 11, 0, 3, 10, 5, 0, 8, 0, 7, 5, 7, 0, -1}, - {11, 10, 5, 7, 11, 5, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1}, - {10, 6, 5, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1}, - {0, 8, 3, 5, 10, 6, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1}, - {9, 0, 1, 5, 10, 6, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1}, - {1, 8, 3, 1, 9, 8, 5, 10, 6, -1, -1, -1, -1, -1, -1, -1}, - {1, 6, 5, 2, 6, 1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1}, - {1, 6, 5, 1, 2, 6, 3, 0, 8, -1, -1, -1, -1, -1, -1, -1}, - {9, 6, 5, 9, 0, 6, 0, 2, 6, -1, -1, -1, -1, -1, -1, -1}, - {5, 9, 8, 5, 8, 2, 5, 2, 6, 3, 2, 8, -1, -1, -1, -1}, - {2, 3, 11, 10, 6, 5, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1}, - {11, 0, 8, 11, 2, 0, 10, 6, 5, -1, -1, -1, -1, -1, -1, -1}, - {0, 1, 9, 2, 3, 11, 5, 10, 6, -1, -1, -1, -1, -1, -1, -1}, - {5, 10, 6, 1, 9, 2, 9, 11, 2, 9, 8, 11, -1, -1, -1, -1}, - {6, 3, 11, 6, 5, 3, 5, 1, 3, -1, -1, -1, -1, -1, -1, -1}, - {0, 8, 11, 0, 11, 5, 0, 5, 1, 5, 11, 6, -1, -1, -1, -1}, - {3, 11, 6, 0, 3, 6, 0, 6, 5, 0, 5, 9, -1, -1, -1, -1}, - {6, 5, 9, 6, 9, 11, 11, 9, 8, -1, -1, -1, -1, -1, -1, -1}, - {5, 10, 6, 4, 7, 8, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1}, - {4, 3, 0, 4, 7, 3, 6, 5, 10, -1, -1, -1, -1, -1, -1, -1}, - {1, 9, 0, 5, 10, 6, 8, 4, 7, -1, -1, -1, -1, -1, -1, -1}, - {10, 6, 5, 1, 9, 7, 1, 7, 3, 7, 9, 4, -1, -1, -1, -1}, - {6, 1, 2, 6, 5, 1, 4, 7, 8, -1, -1, -1, -1, -1, -1, -1}, - {1, 2, 5, 5, 2, 6, 3, 0, 4, 3, 4, 7, -1, -1, -1, -1}, - {8, 4, 7, 9, 0, 5, 0, 6, 5, 0, 2, 6, -1, -1, -1, -1}, - {7, 3, 9, 7, 9, 4, 3, 2, 9, 5, 9, 6, 2, 6, 9, -1}, - {3, 11, 2, 7, 8, 4, 10, 6, 5, -1, -1, -1, -1, -1, -1, -1}, - {5, 10, 6, 4, 7, 2, 4, 2, 0, 2, 7, 11, -1, -1, -1, -1}, - {0, 1, 9, 4, 7, 8, 2, 3, 11, 5, 10, 6, -1, -1, -1, -1}, - {9, 2, 1, 9, 11, 2, 9, 4, 11, 7, 11, 4, 5, 10, 6, -1}, - {8, 4, 7, 3, 11, 5, 3, 5, 1, 5, 11, 6, -1, -1, -1, -1}, - {5, 1, 11, 5, 11, 6, 1, 0, 11, 7, 11, 4, 0, 4, 11, -1}, - {0, 5, 9, 0, 6, 5, 0, 3, 6, 11, 6, 3, 8, 4, 7, -1}, - {6, 5, 9, 6, 9, 11, 4, 7, 9, 7, 11, 9, -1, -1, -1, -1}, - {10, 4, 9, 6, 4, 10, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1}, - {4, 10, 6, 4, 9, 10, 0, 8, 3, -1, -1, -1, -1, -1, -1, -1}, - {10, 0, 1, 10, 6, 0, 6, 4, 0, -1, -1, -1, -1, -1, -1, -1}, - {8, 3, 1, 8, 1, 6, 8, 6, 4, 6, 1, 10, -1, -1, -1, -1}, - {1, 4, 9, 1, 2, 4, 2, 6, 4, -1, -1, -1, -1, -1, -1, -1}, - {3, 0, 8, 1, 2, 9, 2, 4, 9, 2, 6, 4, -1, -1, -1, -1}, - {0, 2, 4, 4, 2, 6, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1}, - {8, 3, 2, 8, 2, 4, 4, 2, 6, -1, -1, -1, -1, -1, -1, -1}, - {10, 4, 9, 10, 6, 4, 11, 2, 3, -1, -1, -1, -1, -1, -1, -1}, - {0, 8, 2, 2, 8, 11, 4, 9, 10, 4, 10, 6, -1, -1, -1, -1}, - {3, 11, 2, 0, 1, 6, 0, 6, 4, 6, 1, 10, -1, -1, -1, -1}, - {6, 4, 1, 6, 1, 10, 4, 8, 1, 2, 1, 11, 8, 11, 1, -1}, - {9, 6, 4, 9, 3, 6, 9, 1, 3, 11, 6, 3, -1, -1, -1, -1}, - {8, 11, 1, 8, 1, 0, 11, 6, 1, 9, 1, 4, 6, 4, 1, -1}, - {3, 11, 6, 3, 6, 0, 0, 6, 4, -1, -1, -1, -1, -1, -1, -1}, - {6, 4, 8, 11, 6, 8, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1}, - {7, 10, 6, 7, 8, 10, 8, 9, 10, -1, -1, -1, -1, -1, -1, -1}, - {0, 7, 3, 0, 10, 7, 0, 9, 10, 6, 7, 10, -1, -1, -1, -1}, - {10, 6, 7, 1, 10, 7, 1, 7, 8, 1, 8, 0, -1, -1, -1, -1}, - {10, 6, 7, 10, 7, 1, 1, 7, 3, -1, -1, -1, -1, -1, -1, -1}, - {1, 2, 6, 1, 6, 8, 1, 8, 9, 8, 6, 7, -1, -1, -1, -1}, - {2, 6, 9, 2, 9, 1, 6, 7, 9, 0, 9, 3, 7, 3, 9, -1}, - {7, 8, 0, 7, 0, 6, 6, 0, 2, -1, -1, -1, -1, -1, -1, -1}, - {7, 3, 2, 6, 7, 2, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1}, - {2, 3, 11, 10, 6, 8, 10, 8, 9, 8, 6, 7, -1, -1, -1, -1}, - {2, 0, 7, 2, 7, 11, 0, 9, 7, 6, 7, 10, 9, 10, 7, -1}, - {1, 8, 0, 1, 7, 8, 1, 10, 7, 6, 7, 10, 2, 3, 11, -1}, - {11, 2, 1, 11, 1, 7, 10, 6, 1, 6, 7, 1, -1, -1, -1, -1}, - {8, 9, 6, 8, 6, 7, 9, 1, 6, 11, 6, 3, 1, 3, 6, -1}, - {0, 9, 1, 11, 6, 7, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1}, - {7, 8, 0, 7, 0, 6, 3, 11, 0, 11, 6, 0, -1, -1, -1, -1}, - {7, 11, 6, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1}, - {7, 6, 11, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1}, - {3, 0, 8, 11, 7, 6, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1}, - {0, 1, 9, 11, 7, 6, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1}, - {8, 1, 9, 8, 3, 1, 11, 7, 6, -1, -1, -1, -1, -1, -1, -1}, - {10, 1, 2, 6, 11, 7, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1}, - {1, 2, 10, 3, 0, 8, 6, 11, 7, -1, -1, -1, -1, -1, -1, -1}, - {2, 9, 0, 2, 10, 9, 6, 11, 7, -1, -1, -1, -1, -1, -1, -1}, - {6, 11, 7, 2, 10, 3, 10, 8, 3, 10, 9, 8, -1, -1, -1, -1}, - {7, 2, 3, 6, 2, 7, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1}, - {7, 0, 8, 7, 6, 0, 6, 2, 0, -1, -1, -1, -1, -1, -1, -1}, - {2, 7, 6, 2, 3, 7, 0, 1, 9, -1, -1, -1, -1, -1, -1, -1}, - {1, 6, 2, 1, 8, 6, 1, 9, 8, 8, 7, 6, -1, -1, -1, -1}, - {10, 7, 6, 10, 1, 7, 1, 3, 7, -1, -1, -1, -1, -1, -1, -1}, - {10, 7, 6, 1, 7, 10, 1, 8, 7, 1, 0, 8, -1, -1, -1, -1}, - {0, 3, 7, 0, 7, 10, 0, 10, 9, 6, 10, 7, -1, -1, -1, -1}, - {7, 6, 10, 7, 10, 8, 8, 10, 9, -1, -1, -1, -1, -1, -1, -1}, - {6, 8, 4, 11, 8, 6, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1}, - {3, 6, 11, 3, 0, 6, 0, 4, 6, -1, -1, -1, -1, -1, -1, -1}, - {8, 6, 11, 8, 4, 6, 9, 0, 1, -1, -1, -1, -1, -1, -1, -1}, - {9, 4, 6, 9, 6, 3, 9, 3, 1, 11, 3, 6, -1, -1, -1, -1}, - {6, 8, 4, 6, 11, 8, 2, 10, 1, -1, -1, -1, -1, -1, -1, -1}, - {1, 2, 10, 3, 0, 11, 0, 6, 11, 0, 4, 6, -1, -1, -1, -1}, - {4, 11, 8, 4, 6, 11, 0, 2, 9, 2, 10, 9, -1, -1, -1, -1}, - {10, 9, 3, 10, 3, 2, 9, 4, 3, 11, 3, 6, 4, 6, 3, -1}, - {8, 2, 3, 8, 4, 2, 4, 6, 2, -1, -1, -1, -1, -1, -1, -1}, - {0, 4, 2, 4, 6, 2, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1}, - {1, 9, 0, 2, 3, 4, 2, 4, 6, 4, 3, 8, -1, -1, -1, -1}, - {1, 9, 4, 1, 4, 2, 2, 4, 6, -1, -1, -1, -1, -1, -1, -1}, - {8, 1, 3, 8, 6, 1, 8, 4, 6, 6, 10, 1, -1, -1, -1, -1}, - {10, 1, 0, 10, 0, 6, 6, 0, 4, -1, -1, -1, -1, -1, -1, -1}, - {4, 6, 3, 4, 3, 8, 6, 10, 3, 0, 3, 9, 10, 9, 3, -1}, - {10, 9, 4, 6, 10, 4, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1}, - {4, 9, 5, 7, 6, 11, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1}, - {0, 8, 3, 4, 9, 5, 11, 7, 6, -1, -1, -1, -1, -1, -1, -1}, - {5, 0, 1, 5, 4, 0, 7, 6, 11, -1, -1, -1, -1, -1, -1, -1}, - {11, 7, 6, 8, 3, 4, 3, 5, 4, 3, 1, 5, -1, -1, -1, -1}, - {9, 5, 4, 10, 1, 2, 7, 6, 11, -1, -1, -1, -1, -1, -1, -1}, - {6, 11, 7, 1, 2, 10, 0, 8, 3, 4, 9, 5, -1, -1, -1, -1}, - {7, 6, 11, 5, 4, 10, 4, 2, 10, 4, 0, 2, -1, -1, -1, -1}, - {3, 4, 8, 3, 5, 4, 3, 2, 5, 10, 5, 2, 11, 7, 6, -1}, - {7, 2, 3, 7, 6, 2, 5, 4, 9, -1, -1, -1, -1, -1, -1, -1}, - {9, 5, 4, 0, 8, 6, 0, 6, 2, 6, 8, 7, -1, -1, -1, -1}, - {3, 6, 2, 3, 7, 6, 1, 5, 0, 5, 4, 0, -1, -1, -1, -1}, - {6, 2, 8, 6, 8, 7, 2, 1, 8, 4, 8, 5, 1, 5, 8, -1}, - {9, 5, 4, 10, 1, 6, 1, 7, 6, 1, 3, 7, -1, -1, -1, -1}, - {1, 6, 10, 1, 7, 6, 1, 0, 7, 8, 7, 0, 9, 5, 4, -1}, - {4, 0, 10, 4, 10, 5, 0, 3, 10, 6, 10, 7, 3, 7, 10, -1}, - {7, 6, 10, 7, 10, 8, 5, 4, 10, 4, 8, 10, -1, -1, -1, -1}, - {6, 9, 5, 6, 11, 9, 11, 8, 9, -1, -1, -1, -1, -1, -1, -1}, - {3, 6, 11, 0, 6, 3, 0, 5, 6, 0, 9, 5, -1, -1, -1, -1}, - {0, 11, 8, 0, 5, 11, 0, 1, 5, 5, 6, 11, -1, -1, -1, -1}, - {6, 11, 3, 6, 3, 5, 5, 3, 1, -1, -1, -1, -1, -1, -1, -1}, - {1, 2, 10, 9, 5, 11, 9, 11, 8, 11, 5, 6, -1, -1, -1, -1}, - {0, 11, 3, 0, 6, 11, 0, 9, 6, 5, 6, 9, 1, 2, 10, -1}, - {11, 8, 5, 11, 5, 6, 8, 0, 5, 10, 5, 2, 0, 2, 5, -1}, - {6, 11, 3, 6, 3, 5, 2, 10, 3, 10, 5, 3, -1, -1, -1, -1}, - {5, 8, 9, 5, 2, 8, 5, 6, 2, 3, 8, 2, -1, -1, -1, -1}, - {9, 5, 6, 9, 6, 0, 0, 6, 2, -1, -1, -1, -1, -1, -1, -1}, - {1, 5, 8, 1, 8, 0, 5, 6, 8, 3, 8, 2, 6, 2, 8, -1}, - {1, 5, 6, 2, 1, 6, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1}, - {1, 3, 6, 1, 6, 10, 3, 8, 6, 5, 6, 9, 8, 9, 6, -1}, - {10, 1, 0, 10, 0, 6, 9, 5, 0, 5, 6, 0, -1, -1, -1, -1}, - {0, 3, 8, 5, 6, 10, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1}, - {10, 5, 6, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1}, - {11, 5, 10, 7, 5, 11, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1}, - {11, 5, 10, 11, 7, 5, 8, 3, 0, -1, -1, -1, -1, -1, -1, -1}, - {5, 11, 7, 5, 10, 11, 1, 9, 0, -1, -1, -1, -1, -1, -1, -1}, - {10, 7, 5, 10, 11, 7, 9, 8, 1, 8, 3, 1, -1, -1, -1, -1}, - {11, 1, 2, 11, 7, 1, 7, 5, 1, -1, -1, -1, -1, -1, -1, -1}, - {0, 8, 3, 1, 2, 7, 1, 7, 5, 7, 2, 11, -1, -1, -1, -1}, - {9, 7, 5, 9, 2, 7, 9, 0, 2, 2, 11, 7, -1, -1, -1, -1}, - {7, 5, 2, 7, 2, 11, 5, 9, 2, 3, 2, 8, 9, 8, 2, -1}, - {2, 5, 10, 2, 3, 5, 3, 7, 5, -1, -1, -1, -1, -1, -1, -1}, - {8, 2, 0, 8, 5, 2, 8, 7, 5, 10, 2, 5, -1, -1, -1, -1}, - {9, 0, 1, 5, 10, 3, 5, 3, 7, 3, 10, 2, -1, -1, -1, -1}, - {9, 8, 2, 9, 2, 1, 8, 7, 2, 10, 2, 5, 7, 5, 2, -1}, - {1, 3, 5, 3, 7, 5, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1}, - {0, 8, 7, 0, 7, 1, 1, 7, 5, -1, -1, -1, -1, -1, -1, -1}, - {9, 0, 3, 9, 3, 5, 5, 3, 7, -1, -1, -1, -1, -1, -1, -1}, - {9, 8, 7, 5, 9, 7, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1}, - {5, 8, 4, 5, 10, 8, 10, 11, 8, -1, -1, -1, -1, -1, -1, -1}, - {5, 0, 4, 5, 11, 0, 5, 10, 11, 11, 3, 0, -1, -1, -1, -1}, - {0, 1, 9, 8, 4, 10, 8, 10, 11, 10, 4, 5, -1, -1, -1, -1}, - {10, 11, 4, 10, 4, 5, 11, 3, 4, 9, 4, 1, 3, 1, 4, -1}, - {2, 5, 1, 2, 8, 5, 2, 11, 8, 4, 5, 8, -1, -1, -1, -1}, - {0, 4, 11, 0, 11, 3, 4, 5, 11, 2, 11, 1, 5, 1, 11, -1}, - {0, 2, 5, 0, 5, 9, 2, 11, 5, 4, 5, 8, 11, 8, 5, -1}, - {9, 4, 5, 2, 11, 3, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1}, - {2, 5, 10, 3, 5, 2, 3, 4, 5, 3, 8, 4, -1, -1, -1, -1}, - {5, 10, 2, 5, 2, 4, 4, 2, 0, -1, -1, -1, -1, -1, -1, -1}, - {3, 10, 2, 3, 5, 10, 3, 8, 5, 4, 5, 8, 0, 1, 9, -1}, - {5, 10, 2, 5, 2, 4, 1, 9, 2, 9, 4, 2, -1, -1, -1, -1}, - {8, 4, 5, 8, 5, 3, 3, 5, 1, -1, -1, -1, -1, -1, -1, -1}, - {0, 4, 5, 1, 0, 5, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1}, - {8, 4, 5, 8, 5, 3, 9, 0, 5, 0, 3, 5, -1, -1, -1, -1}, - {9, 4, 5, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1}, - {4, 11, 7, 4, 9, 11, 9, 10, 11, -1, -1, -1, -1, -1, -1, -1}, - {0, 8, 3, 4, 9, 7, 9, 11, 7, 9, 10, 11, -1, -1, -1, -1}, - {1, 10, 11, 1, 11, 4, 1, 4, 0, 7, 4, 11, -1, -1, -1, -1}, - {3, 1, 4, 3, 4, 8, 1, 10, 4, 7, 4, 11, 10, 11, 4, -1}, - {4, 11, 7, 9, 11, 4, 9, 2, 11, 9, 1, 2, -1, -1, -1, -1}, - {9, 7, 4, 9, 11, 7, 9, 1, 11, 2, 11, 1, 0, 8, 3, -1}, - {11, 7, 4, 11, 4, 2, 2, 4, 0, -1, -1, -1, -1, -1, -1, -1}, - {11, 7, 4, 11, 4, 2, 8, 3, 4, 3, 2, 4, -1, -1, -1, -1}, - {2, 9, 10, 2, 7, 9, 2, 3, 7, 7, 4, 9, -1, -1, -1, -1}, - {9, 10, 7, 9, 7, 4, 10, 2, 7, 8, 7, 0, 2, 0, 7, -1}, - {3, 7, 10, 3, 10, 2, 7, 4, 10, 1, 10, 0, 4, 0, 10, -1}, - {1, 10, 2, 8, 7, 4, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1}, - {4, 9, 1, 4, 1, 7, 7, 1, 3, -1, -1, -1, -1, -1, -1, -1}, - {4, 9, 1, 4, 1, 7, 0, 8, 1, 8, 7, 1, -1, -1, -1, -1}, - {4, 0, 3, 7, 4, 3, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1}, - {4, 8, 7, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1}, - {9, 10, 8, 10, 11, 8, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1}, - {3, 0, 9, 3, 9, 11, 11, 9, 10, -1, -1, -1, -1, -1, -1, -1}, - {0, 1, 10, 0, 10, 8, 8, 10, 11, -1, -1, -1, -1, -1, -1, -1}, - {3, 1, 10, 11, 3, 10, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1}, - {1, 2, 11, 1, 11, 9, 9, 11, 8, -1, -1, -1, -1, -1, -1, -1}, - {3, 0, 9, 3, 9, 11, 1, 2, 9, 2, 11, 9, -1, -1, -1, -1}, - {0, 2, 11, 8, 0, 11, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1}, - {3, 2, 11, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1}, - {2, 3, 8, 2, 8, 10, 10, 8, 9, -1, -1, -1, -1, -1, -1, -1}, - {9, 10, 2, 0, 9, 2, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1}, - {2, 3, 8, 2, 8, 10, 0, 1, 8, 1, 10, 8, -1, -1, -1, -1}, - {1, 10, 2, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1}, - {1, 3, 8, 9, 1, 8, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1}, - {0, 9, 1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1}, - {0, 3, 8, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1}, - {-1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1}, -}; diff --git a/intern/elbeem/intern/mvmcoords.cpp b/intern/elbeem/intern/mvmcoords.cpp deleted file mode 100644 index 407a1b426f3..00000000000 --- a/intern/elbeem/intern/mvmcoords.cpp +++ /dev/null @@ -1,205 +0,0 @@ -/** \file - * \ingroup elbeem - */ -/****************************************************************************** - * -// El'Beem - the visual lattice boltzmann freesurface simulator -// All code distributed as part of El'Beem is covered by the version 2 of the -// GNU General Public License. See the file COPYING for details. -// -// Copyright 2008 Nils Thuerey , Richard Keiser, Mark Pauly, Ulrich Ruede -// - * - * Mean Value Mesh Coords class - * - *****************************************************************************/ - -#include "mvmcoords.h" -#include <algorithm> -#include <cmath> - -#if defined(_MSC_VER) && _MSC_VER > 1600 -// std::greater -#include <functional> -#endif - - -using std::vector; -using std::isfinite; - -void MeanValueMeshCoords::clear() -{ - mVertices.resize(0); - mNumVerts = 0; -} - -void MeanValueMeshCoords::calculateMVMCs(vector<ntlVec3Gfx> &reference_vertices, vector<ntlTriangle> &tris, - vector<ntlVec3Gfx> &points, gfxReal numweights) -{ - clear(); - mvmTransferPoint tds; - int mem = 0; - int i = 0; - - mNumVerts = (int)reference_vertices.size(); - - for (vector<ntlVec3Gfx>::iterator iter = points.begin(); iter != points.end(); ++iter, ++i) { - /* - if(i%(points.size()/10)==1) debMsgStd("MeanValueMeshCoords::calculateMVMCs",DM_MSG,"Computing weights, points: "<<i<<"/"<<points.size(),5 ); - */ - tds.lastpos = *iter; - tds.weights.resize(0); // clear - computeWeights(reference_vertices, tris, tds, numweights); - mem += (int)tds.weights.size(); - mVertices.push_back(tds); - } - int mbmem = mem * sizeof(mvmFloat) / (1024*1024); - debMsgStd("MeanValueMeshCoords::calculateMVMCs",DM_MSG,"vertices:"<<mNumVerts<<" points:"<<points.size()<<" weights:"<<mem<<", wmem:"<<mbmem<<"MB ",7 ); -} - -// from: mean value coordinates for closed triangular meshes -// attention: fails if a point is exactly (or very close) to a vertex -void MeanValueMeshCoords::computeWeights(vector<ntlVec3Gfx> &reference_vertices, vector<ntlTriangle>& tris, - mvmTransferPoint& tds, gfxReal numweights) -{ - const bool mvmFullDebug=false; - //const ntlVec3Gfx cEPS = 1.0e-6; - const mvmFloat cEPS = 1.0e-14; - - //mvmFloat d[3], s[3], phi[3],c[3]; - ntlVec3d u[3],c,d,s,phi; - int indices[3]; - - for (int i = 0; i < (int)reference_vertices.size(); ++i) { - tds.weights.push_back(mvmIndexWeight(i, 0.0)); - } - - // for each triangle - //for (vector<ntlTriangle>::iterator iter = tris.begin(); iter != tris.end();) { - for(int t=0; t<(int)tris.size(); t++) { - - for (int i = 0; i < 3; ++i) { //, ++iter) { - indices[i] = tris[t].getPoints()[i]; - u[i] = vec2D(reference_vertices[ indices[i] ]-tds.lastpos); - d[i] = normalize(u[i]); //.normalize(); - //assert(d[i] != 0.); - if(mvmFullDebug) errMsg("MeanValueMeshCoords::computeWeights","t"<<t<<" i"<<indices[i] //<<" lp"<<tds.lastpos - <<" v"<<reference_vertices[indices[i]]<<" u"<<u[i]<<" "); - // on vertex! - //? if(d[i]<=0.) continue; - } - //for (int i = 0; i < 3; ++i) { errMsg("III"," "<<i <<" i"<<indices[i]<<reference_vertices[ indices[i] ] ); } - - // arcsin is not needed, see paper - phi[0] = 2.*asin( (mvmFloat)(0.5* norm(u[1]-u[2]) ) ); - phi[1] = 2.*asin( (mvmFloat)(0.5* norm(u[0]-u[2]) ) ); - phi[2] = 2.*asin( (mvmFloat)(0.5* norm(u[0]-u[1]) ) ); - mvmFloat h = (phi[0] + phi[1] + phi[2])*0.5; - if (M_PI-h < cEPS) { - if(mvmFullDebug) errMsg("MeanValueMeshCoords::computeWeights","point on triangle"); - tds.weights.resize(0); - tds.weights.push_back( mvmIndexWeight(indices[0], sin(phi[0])*d[1]*d[2])); - tds.weights.push_back( mvmIndexWeight(indices[1], sin(phi[1])*d[0]*d[2])); - tds.weights.push_back( mvmIndexWeight(indices[2], sin(phi[2])*d[1]*d[0])); - break; - } - mvmFloat sinh = 2.*sin(h); - c[0] = (sinh*sin(h-phi[0]))/(sin(phi[1])*sin(phi[2]))-1.; - c[1] = (sinh*sin(h-phi[1]))/(sin(phi[0])*sin(phi[2]))-1.; - c[2] = (sinh*sin(h-phi[2]))/(sin(phi[0])*sin(phi[1]))-1.; - if(mvmFullDebug) errMsg("MeanValueMeshCoords::computeWeights","c="<<c<<" phi="<<phi<<" d="<<d); - //if (c[0] > 1. || c[0] < 0. || c[1] > 1. || c[1] < 0. || c[2] > 1. || c[2] < 0.) continue; - - s[0] = sqrt((float)(1.-c[0]*c[0])); - s[1] = sqrt((float)(1.-c[1]*c[1])); - s[2] = sqrt((float)(1.-c[2]*c[2])); - - if(mvmFullDebug) errMsg("MeanValueMeshCoords::computeWeights","s"); - if (s[0] <= cEPS || s[1] <= cEPS || s[2] <= cEPS) { - //MSG("position lies outside the triangle on the same plane -> ignore it"); - continue; - } - const mvmFloat u0x = u[0][0]; - const mvmFloat u0y = u[0][1]; - const mvmFloat u0z = u[0][2]; - const mvmFloat u1x = u[1][0]; - const mvmFloat u1y = u[1][1]; - const mvmFloat u1z = u[1][2]; - const mvmFloat u2x = u[2][0]; - const mvmFloat u2y = u[2][1]; - const mvmFloat u2z = u[2][2]; - mvmFloat det = u0x*u1y*u2z - u0x*u1z*u2y + u0y*u1z*u2x - u0y*u1x*u2z + u0z*u1x*u2y - u0z*u1y*u2x; - //assert(det != 0.); - if (det < 0.) { - s[0] = -s[0]; - s[1] = -s[1]; - s[2] = -s[2]; - } - - tds.weights[indices[0]].weight += (phi[0]-c[1]*phi[2]-c[2]*phi[1])/(d[0]*sin(phi[1])*s[2]); - tds.weights[indices[1]].weight += (phi[1]-c[2]*phi[0]-c[0]*phi[2])/(d[1]*sin(phi[2])*s[0]); - tds.weights[indices[2]].weight += (phi[2]-c[0]*phi[1]-c[1]*phi[0])/(d[2]*sin(phi[0])*s[1]); - if(mvmFullDebug) { errMsg("MeanValueMeshCoords::computeWeights","i"<<indices[0]<<" o"<<tds.weights[indices[0]].weight); - errMsg("MeanValueMeshCoords::computeWeights","i"<<indices[1]<<" o"<<tds.weights[indices[1]].weight); - errMsg("MeanValueMeshCoords::computeWeights","i"<<indices[2]<<" o"<<tds.weights[indices[2]].weight); - errMsg("MeanValueMeshCoords::computeWeights","\n\n\n"); } - } - - //sort weights - if((numweights>0.)&& (numweights<1.) ) { - //if( ((int)tds.weights.size() > maxNumWeights) && (maxNumWeights > 0) ) { - int maxNumWeights = (int)(tds.weights.size()*numweights); - if(maxNumWeights<=0) maxNumWeights = 1; - std::sort(tds.weights.begin(), tds.weights.end(), std::greater<mvmIndexWeight>()); - // only use maxNumWeights-th largest weights - tds.weights.resize(maxNumWeights); - } - - // normalize weights - mvmFloat totalWeight = 0.; - for (vector<mvmIndexWeight>::const_iterator witer = tds.weights.begin(); - witer != tds.weights.end(); ++witer) { - totalWeight += witer->weight; - } - mvmFloat invTotalWeight; - if (totalWeight == 0.) { - if(mvmFullDebug) errMsg("MeanValueMeshCoords::computeWeights","totalWeight == 0"); - invTotalWeight = 0.0; - } else { - invTotalWeight = 1.0/totalWeight; - } - - for (vector<mvmIndexWeight>::iterator viter = tds.weights.begin(); - viter != tds.weights.end(); ++viter) { - viter->weight *= invTotalWeight; - //assert(isfinite(viter->weight) != 0); - if(!isfinite(viter->weight)) viter->weight=0.; - } -} - -void MeanValueMeshCoords::transfer(vector<ntlVec3Gfx> &vertices, vector<ntlVec3Gfx>& displacements) -{ - displacements.resize(0); - - //debMsgStd("MeanValueMeshCoords::transfer",DM_MSG,"vertices:"<<mNumVerts<<" curr_verts:"<<vertices.size()<<" ",7 ); - if((int)vertices.size() != mNumVerts) { - errMsg("MeanValueMeshCoords::transfer","Different no of verts: "<<vertices.size()<<" vs "<<mNumVerts); - return; - } - - for (vector<mvmTransferPoint>::iterator titer = mVertices.begin(); titer != mVertices.end(); ++titer) { - mvmTransferPoint &tds = *titer; - ntlVec3Gfx newpos(0.0); - - for (vector<mvmIndexWeight>::iterator witer = tds.weights.begin(); - witer != tds.weights.end(); ++witer) { - newpos += vertices[witer->index] * witer->weight; - //errMsg("transfer","np"<<newpos<<" v"<<vertices[witer->index]<<" w"<< witer->weight); - } - - displacements.push_back(newpos); - //displacements.push_back(newpos - tds.lastpos); - //tds.lastpos = newpos; - } -} - diff --git a/intern/elbeem/intern/mvmcoords.h b/intern/elbeem/intern/mvmcoords.h deleted file mode 100644 index d00215ebd0e..00000000000 --- a/intern/elbeem/intern/mvmcoords.h +++ /dev/null @@ -1,108 +0,0 @@ -/** \file - * \ingroup elbeem - */ -/****************************************************************************** - * -// El'Beem - the visual lattice boltzmann freesurface simulator -// All code distributed as part of El'Beem is covered by the version 2 of the -// GNU General Public License. See the file COPYING for details. -// -// Copyright 2008 Nils Thuerey , Richard Keiser, Mark Pauly, Ulrich Ruede -// - * - * Mean Value Mesh Coords class - * - *****************************************************************************/ - -#ifndef MVMCOORDS_H -#define MVMCOORDS_H - -#include "utilities.h" -#include "ntl_ray.h" -#include <vector> -#define mvmFloat double - -#ifdef WIN32 -#include "float.h" -#define isnan(n) _isnan(n) -#define finite _finite -#endif - -#ifdef sun -#include "ieeefp.h" -#endif - -#ifdef WITH_CXX_GUARDEDALLOC -# include "MEM_guardedalloc.h" -#endif - -// weight and triangle index -class mvmIndexWeight { - public: - - mvmIndexWeight() : weight(0.0) {} - - mvmIndexWeight(int const& i, mvmFloat const& w) : - weight(w), index(i) {} - - // for sorting - bool operator> (mvmIndexWeight const& w) const { return this->weight > w.weight; } - bool operator< (mvmIndexWeight const& w) const { return this->weight < w.weight; } - - mvmFloat weight; - int index; - -private: -#ifdef WITH_CXX_GUARDEDALLOC - MEM_CXX_CLASS_ALLOC_FUNCS("ELBEEM:mvmIndexWeight") -#endif -}; - -// transfer point with weights -class mvmTransferPoint { - public: - //! position of transfer point - ntlVec3Gfx lastpos; - //! triangle weights - std::vector<mvmIndexWeight> weights; - -private: -#ifdef WITH_CXX_GUARDEDALLOC - MEM_CXX_CLASS_ALLOC_FUNCS("ELBEEM:mvmTransferPoint") -#endif -}; - - -//! compute mvmcs -class MeanValueMeshCoords { - - public: - - MeanValueMeshCoords() {} - ~MeanValueMeshCoords() { - clear(); - } - - void clear(); - - void calculateMVMCs(std::vector<ntlVec3Gfx> &reference_vertices, - std::vector<ntlTriangle> &tris, std::vector<ntlVec3Gfx> &points, gfxReal numweights); - - void transfer(std::vector<ntlVec3Gfx> &vertices, std::vector<ntlVec3Gfx>& displacements); - - protected: - - void computeWeights(std::vector<ntlVec3Gfx> &reference_vertices, - std::vector<ntlTriangle> &tris, mvmTransferPoint& tds, gfxReal numweights); - - std::vector<mvmTransferPoint> mVertices; - int mNumVerts; - -private: -#ifdef WITH_CXX_GUARDEDALLOC - MEM_CXX_CLASS_ALLOC_FUNCS("ELBEEM:MeanValueMeshCoords") -#endif -}; - -#endif - diff --git a/intern/elbeem/intern/ntl_blenderdumper.cpp b/intern/elbeem/intern/ntl_blenderdumper.cpp deleted file mode 100644 index eca184ae717..00000000000 --- a/intern/elbeem/intern/ntl_blenderdumper.cpp +++ /dev/null @@ -1,270 +0,0 @@ -/** \file - * \ingroup elbeem - */ -/****************************************************************************** - * - * El'Beem - Free Surface Fluid Simulation with the Lattice Boltzmann Method - * Copyright 2003-2006 Nils Thuerey - * - * Replaces std. raytracer, and only dumps time dep. objects to disc - * - *****************************************************************************/ - -#include <fstream> -#include <sys/types.h> - -#include "utilities.h" -#include "ntl_matrices.h" -#include "ntl_blenderdumper.h" -#include "ntl_world.h" -#include "solver_interface.h" -#include "globals.h" - -#include <zlib.h> - -#ifdef LBM_GZIP_OVERRIDE_H -# include LBM_GZIP_OVERRIDE_H -#else -# define LBM_GZIP_OPEN_FN(a, b) gzopen(a, b) -#endif - -/****************************************************************************** - * Constructor - *****************************************************************************/ -ntlBlenderDumper::ntlBlenderDumper() : ntlWorld() -{ - // same as normal constructor here -} -ntlBlenderDumper::ntlBlenderDumper(string filename, bool commandlineMode) : - ntlWorld(filename,commandlineMode) -{ - // init world -} - - - -/****************************************************************************** - * Destructor - *****************************************************************************/ -ntlBlenderDumper::~ntlBlenderDumper() -{ - debMsgStd("ntlBlenderDumper",DM_NOTIFY, "ntlBlenderDumper done", 10); -} - -/****************************************************************************** - * Only dump time dep. objects to file - *****************************************************************************/ -int ntlBlenderDumper::renderScene( void ) -{ - char nrStr[5]; /* nr conversion */ - ntlRenderGlobals *glob = mpGlob; - ntlScene *scene = mpGlob->getSimScene(); - bool debugOut = false; - bool debugRender = false; -#if ELBEEM_PLUGIN==1 - debugOut = false; -#endif // ELBEEM_PLUGIN==1 - - vector<string> gmName; // gm names - vector<string> gmMat; // materials for gm - int numGMs = 0; // no. of .obj models created - - if(debugOut) debMsgStd("ntlBlenderDumper::renderScene",DM_NOTIFY,"Dumping geometry data", 1); - long startTime = getTime(); - snprintf(nrStr, 5, "%04d", glob->getAniCount() ); - - // local scene vars - vector<ntlTriangle> Triangles; - vector<ntlVec3Gfx> Vertices; - vector<ntlVec3Gfx> VertNormals; - - // check geo objects - int idCnt = 0; // give IDs to objects - for (vector<ntlGeometryClass*>::iterator iter = scene->getGeoClasses()->begin(); - iter != scene->getGeoClasses()->end(); iter++) { - if(!(*iter)->getVisible()) continue; - int tid = (*iter)->getTypeId(); - - if(tid & GEOCLASSTID_OBJECT) { - // normal geom. objects -> ignore - } - if(tid & GEOCLASSTID_SHADER) { - ntlGeometryShader *geoshad = (ntlGeometryShader*)(*iter); //dynamic_cast<ntlGeometryShader*>(*iter); - string outname = geoshad->getOutFilename(); - if(outname.length()<1) outname = mpGlob->getOutFilename(); - geoshad->notifyShaderOfDump(DUMP_FULLGEOMETRY, glob->getAniCount(),nrStr,outname); - - for (vector<ntlGeometryObject*>::iterator siter = geoshad->getObjectsBegin(); - siter != geoshad->getObjectsEnd(); - siter++) { - if(debugOut) debMsgStd("ntlBlenderDumper::BuildScene",DM_MSG,"added shader geometry "<<(*siter)->getName(), 8); - - (*siter)->notifyOfDump(DUMP_FULLGEOMETRY, glob->getAniCount(),nrStr,outname, this->mSimulationTime); - bool doDump = false; - bool isPreview = false; - // only dump final&preview surface meshes - if( (*siter)->getName().find( "final" ) != string::npos) { - doDump = true; - } else if( (*siter)->getName().find( "preview" ) != string::npos) { - doDump = true; - isPreview = true; - } - if(!doDump) continue; - - // dont quit, some objects need notifyOfDump call - if((glob_mpactive) && (glob_mpindex>0)) { - continue; //return 0; - } - - // only dump geo shader objects - Triangles.clear(); - Vertices.clear(); - VertNormals.clear(); - (*siter)->initialize( mpGlob ); - (*siter)->getTriangles(this->mSimulationTime, &Triangles, &Vertices, &VertNormals, idCnt); - idCnt ++; - - // WARNING - this is dirty, but simobjs are the only geoshaders right now - SimulationObject *sim = (SimulationObject *)geoshad; - LbmSolverInterface *lbm = sim->getSolver(); - - - // always dump mesh, even empty ones... - - // dump to binary file - std::ostringstream boutfilename(""); - //boutfilename << ecrpath.str() << outname <<"_"<< (*siter)->getName() <<"_" << nrStr << ".obj"; - boutfilename << outname <<"_"<< (*siter)->getName() <<"_" << nrStr; - if(debugOut) debMsgStd("ntlBlenderDumper::renderScene",DM_MSG,"B-Dumping: "<< (*siter)->getName() - <<", triangles:"<<Triangles.size()<<", vertices:"<<Vertices.size()<< - " to "<<boutfilename.str() , 7); - gzFile gzf; - - // output velocities if desired - if((!isPreview) && (lbm->getDumpVelocities())) { - std::ostringstream bvelfilename; - bvelfilename << boutfilename.str(); - bvelfilename << ".bvel.gz"; - /* wraps gzopen */ - gzf = LBM_GZIP_OPEN_FN(bvelfilename.str().c_str(), "wb9"); - if(gzf) { - int numVerts; - if(sizeof(numVerts)!=4) { errMsg("ntlBlenderDumper::renderScene","Invalid int size"); return 1; } - numVerts = Vertices.size(); - gzwrite(gzf, &numVerts, sizeof(numVerts)); - for(size_t i=0; i<Vertices.size(); i++) { - // returns smoothed velocity, scaled by frame time - ntlVec3Gfx v = lbm->getVelocityAt( Vertices[i][0], Vertices[i][1], Vertices[i][2] ); - // translation not necessary, test rotation & scaling? - for(int j=0; j<3; j++) { - float vertp = v[j]; - //if(i<20) errMsg("ntlBlenderDumper","DUMP_VEL final "<<i<<" = "<<v); - gzwrite(gzf, &vertp, sizeof(vertp)); } - } - gzclose( gzf ); - } - } - - // compress all bobj's - boutfilename << ".bobj.gz"; - /* wraps gzopen */ - gzf = LBM_GZIP_OPEN_FN(boutfilename.str().c_str(), "wb1"); // wb9 is slow for large meshes! - if (!gzf) { - errMsg("ntlBlenderDumper::renderScene","Unable to open output '" + boutfilename.str() + "' "); - return 1; } - - // dont transform velocity output, this is handled in blender - // current transform matrix - ntlMatrix4x4<gfxReal> *trafo; - trafo = lbm->getDomainTrafo(); - if(trafo) { - // transform into source space - for(size_t i=0; i<Vertices.size(); i++) { - Vertices[i] = (*trafo) * Vertices[i]; - } - } - // rotate vertnormals - ntlMatrix4x4<gfxReal> rottrafo; - rottrafo.initId(); - if(lbm->getDomainTrafo()) { - // dont modifiy original! - rottrafo = *lbm->getDomainTrafo(); - ntlVec3Gfx rTrans,rScale,rRot,rShear; - rottrafo.decompose(rTrans,rScale,rRot,rShear); - rottrafo.initRotationXYZ(rRot[0],rRot[1],rRot[2]); - // only rotate here... - for(size_t i=0; i<Vertices.size(); i++) { - VertNormals[i] = rottrafo * VertNormals[i]; - normalize(VertNormals[i]); // remove scaling etc. - } - } - - - // write to file - int numVerts; - if(sizeof(numVerts)!=4) { errMsg("ntlBlenderDumper::renderScene","Invalid int size"); return 1; } - numVerts = Vertices.size(); - gzwrite(gzf, &numVerts, sizeof(numVerts)); - for(size_t i=0; i<Vertices.size(); i++) { - for(int j=0; j<3; j++) { - float vertp = Vertices[i][j]; - gzwrite(gzf, &vertp, sizeof(vertp)); } - } - - // should be the same as Vertices.size - if(VertNormals.size() != (size_t)numVerts) { - errMsg("ntlBlenderDumper::renderScene","Normals have to have same size as vertices!"); - VertNormals.resize( Vertices.size() ); - } - gzwrite(gzf, &numVerts, sizeof(numVerts)); - for(size_t i=0; i<VertNormals.size(); i++) { - for(int j=0; j<3; j++) { - float normp = VertNormals[i][j]; - gzwrite(gzf, &normp, sizeof(normp)); } - } - - int numTris = Triangles.size(); - gzwrite(gzf, &numTris, sizeof(numTris)); - for(size_t i=0; i<Triangles.size(); i++) { - for(int j=0; j<3; j++) { - int triIndex = Triangles[i].getPoints()[j]; - gzwrite(gzf, &triIndex, sizeof(triIndex)); } - } - gzclose( gzf ); - debMsgStd("ntlBlenderDumper::renderScene",DM_NOTIFY," Wrote: '"<<boutfilename.str()<<"' ", 2); - numGMs++; - } - } - - } - - // output ecr config file - if(numGMs>0) { - if(debugOut) debMsgStd("ntlBlenderDumper::renderScene",DM_MSG,"Objects dumped: "<<numGMs, 10); - } else { - if((glob_mpactive) && (glob_mpindex>0)) { - // ok, nothing to do anyway... - } else { - errFatal("ntlBlenderDumper::renderScene","No objects to dump! Aborting...",SIMWORLD_INITERROR); - return 1; - } - } - - // debug timing - long stopTime = getTime(); - debMsgStd("ntlBlenderDumper::renderScene",DM_MSG,"Scene #"<<nrStr<<" dump time: "<< getTimeString(stopTime-startTime) <<" ", 10); - - // still render for preview... - if(debugRender) { - debMsgStd("ntlBlenderDumper::renderScene",DM_NOTIFY,"Performing preliminary render", 1); - ntlWorld::renderScene(); } - else { - // next frame - glob->setAniCount( glob->getAniCount() +1 ); - } - - return 0; -} - - - diff --git a/intern/elbeem/intern/ntl_blenderdumper.h b/intern/elbeem/intern/ntl_blenderdumper.h deleted file mode 100644 index e3c0e3df12b..00000000000 --- a/intern/elbeem/intern/ntl_blenderdumper.h +++ /dev/null @@ -1,42 +0,0 @@ -/** \file - * \ingroup elbeem - */ -/****************************************************************************** - * - * El'Beem - Free Surface Fluid Simulation with the Lattice Boltzmann Method - * Copyright 2003-2006 Nils Thuerey - * - * Replaces std. raytracer, and only dumps time dep. objects to disc, header - * - *****************************************************************************/ -#ifndef NTL_BLENDERDUMPER_H -#include "ntl_world.h" - -#ifdef WITH_CXX_GUARDEDALLOC -# include "MEM_guardedalloc.h" -#endif - -class ntlBlenderDumper : - public ntlWorld -{ -public: - /*! Constructor */ - ntlBlenderDumper(); - ntlBlenderDumper(string filename, bool commandlineMode); - /*! Destructor */ - virtual ~ntlBlenderDumper( void ); - - /*! render scene (a single pictures) */ - virtual int renderScene( void ); - -protected: - -private: -#ifdef WITH_CXX_GUARDEDALLOC - MEM_CXX_CLASS_ALLOC_FUNCS("ELBEEM:ntlBlenderDumper") -#endif -}; - -#define NTL_BLENDERDUMPER_H -#endif - diff --git a/intern/elbeem/intern/ntl_bsptree.cpp b/intern/elbeem/intern/ntl_bsptree.cpp deleted file mode 100644 index 8d589e50cb4..00000000000 --- a/intern/elbeem/intern/ntl_bsptree.cpp +++ /dev/null @@ -1,945 +0,0 @@ -/** \file - * \ingroup elbeem - */ -/****************************************************************************** - * - * El'Beem - Free Surface Fluid Simulation with the Lattice Boltzmann Method - * Copyright 2003-2006 Nils Thuerey - * - * Tree container for fast triangle intersects - * - *****************************************************************************/ - - -#include "ntl_bsptree.h" -#include "utilities.h" - -#include <algorithm> - -/*! Static global variable for sorting direction */ -int globalSortingAxis; -/*! Access to points array for sorting */ -vector<ntlVec3Gfx> *globalSortingPoints; - -#define TREE_DOUBLEI 300 - -/* try axis selection? */ -bool chooseAxis = 0; -/* do median search? */ -int doSort = 0; - - -//! struct for a single node in the bsp tree -class BSPNode { - public: - BSPNode() {}; - - ntlVec3Gfx min,max; /* AABB for node */ - vector<ntlTriangle *> *members; /* stored triangles */ - BSPNode *child[2]; /* pointer to children nodes */ - char axis; /* division axis */ - char cloneVec; /* is this vector a clone? */ - - //! check if node is a leaf - inline bool isLeaf() const { - return (child[0] == NULL); - } -}; - - -//! an element node stack -class BSPStackElement { - public: - //! tree node - BSPNode *node; - //! min and maximum distance along axis - gfxReal mindist, maxdist; -}; - -//! bsp tree stack -class BSPStack { - public: - //! current stack element - int stackPtr; - //! stack storage - BSPStackElement elem[ BSP_STACK_SIZE ]; -}; - -//! triangle bounding box for quick tree subdivision -class TriangleBBox { - public: - //! start and end of triangle bounding box - ntlVec3Gfx start, end; -}; - - -/****************************************************************************** - * calculate tree statistics - *****************************************************************************/ -void calcStats(BSPNode *node, int depth, int &noLeafs, gfxReal &avgDepth, gfxReal &triPerLeaf,int &totalTris) -{ - if(node->members != NULL) { - totalTris += node->members->size(); - } - //depth = 15; // DBEUG! - - if( (node->child[0]==NULL) && (node->child[1]==NULL) ) { - // leaf - noLeafs++; - avgDepth += depth; - triPerLeaf += node->members->size(); - } else { - for(int i=0;i<2;i++) - calcStats(node->child[i], depth+1, noLeafs, avgDepth, triPerLeaf, totalTris); - } -} - - - -/****************************************************************************** - * triangle comparison function for median search - *****************************************************************************/ -bool lessTriangleAverage(const ntlTriangle *x, const ntlTriangle *y) -{ - return x->getAverage(globalSortingAxis) < y->getAverage(globalSortingAxis); -} - - -/****************************************************************************** - * triangle AABB intersection - *****************************************************************************/ -bool ntlTree::checkAABBTriangle(ntlVec3Gfx &min, ntlVec3Gfx &max, ntlTriangle *tri) -{ - // test only BB of triangle - TriangleBBox *bbox = &mpTBB[ tri->getBBoxId() ]; - if( bbox->end[0] < min[0] ) return false; - if( bbox->start[0] > max[0] ) return false; - if( bbox->end[1] < min[1] ) return false; - if( bbox->start[1] > max[1] ) return false; - if( bbox->end[2] < min[2] ) return false; - if( bbox->start[2] > max[2] ) return false; - return true; -} - - - - - - - -/****************************************************************************** - * Default constructor - *****************************************************************************/ -ntlTree::ntlTree() : - mStart(0.0), mEnd(0.0), mMaxDepth( 5 ), mMaxListLength( 5 ), mpRoot( NULL) , - mpNodeStack( NULL), mpVertices( NULL ), mpVertNormals( NULL ), mpTriangles( NULL ), - mCurrentDepth(0), mCurrentNodes(0), mTriDoubles(0) -{ - errFatal( "ntlTree","Uninitialized BSP Tree!\n",SIMWORLD_INITERROR ); - return; -} - - -/****************************************************************************** - * Constructor with init - *****************************************************************************/ -//ntlTree::ntlTree(int depth, int objnum, vector<ntlVec3Gfx> *vertices, vector<ntlVec3Gfx> *normals, vector<ntlTriangle> *trilist) : -ntlTree::ntlTree(int depth, int objnum, ntlScene *scene, int triFlagMask) : - mStart(0.0), mEnd(0.0), mMaxDepth( depth ), mMaxListLength( objnum ), mpRoot( NULL) , - mpNodeStack( NULL), mpTBB( NULL ), - mTriangleMask( 0xFFFF ), - mCurrentDepth(0), mCurrentNodes(0), mTriDoubles(0) -{ - // init scene data pointers - mpVertices = scene->getVertexPointer(); - mpVertNormals = scene->getVertexNormalPointer(); - mpTriangles = scene->getTrianglePointer(); - mTriangleMask = triFlagMask; - - if(mpTriangles == NULL) { - errFatal( "ntlTree Cons","no triangle list!\n",SIMWORLD_INITERROR); - return; - } - if(mpTriangles->size() == 0) { - warnMsg( "ntlTree::ntlTree","No triangles ("<< mpTriangles->size() <<")!\n"); - mStart = mEnd = ntlVec3Gfx(0,0,0); - return; - } - if(depth>=BSP_STACK_SIZE) { - errFatal( "ntlTree::ntlTree","Depth to high ("<< mMaxDepth <<")!\n", SIMWORLD_INITERROR ); - return; - } - - /* check triangles (a bit inefficient, but we dont know which vertices belong - to this tree), and generate bounding boxes */ - mppTriangles = new vector<ntlTriangle *>; - int noOfTriangles = mpTriangles->size(); - mpTBB = new TriangleBBox[ noOfTriangles ]; - int bbCount = 0; - mStart = mEnd = (*mpVertices)[ mpTriangles->front().getPoints()[0] ]; - //errMsg("TreeDebug","Start"); - for (vector<ntlTriangle>::iterator iter = mpTriangles->begin(); - iter != mpTriangles->end(); - iter++ ) { - //errorOut(" d "<< convertFlags2String((int)(*iter).getFlags()) <<" "<< convertFlags2String( (int)mTriangleMask)<<" add? "<<( ((int)(*iter).getFlags() & (int)mTriangleMask) != 0 ) ); - // discard triangles that dont match mask - if( ((int)(*iter).getFlags() & (int)mTriangleMask) == 0 ) { - continue; - } - - // test? TODO - ntlVec3Gfx tnormal = (*mpVertNormals)[ (*iter).getPoints()[0] ]+ - (*mpVertNormals)[ (*iter).getPoints()[1] ]+ - (*mpVertNormals)[ (*iter).getPoints()[2] ]; - ntlVec3Gfx triangleNormal = (*iter).getNormal(); - if( equal(triangleNormal, ntlVec3Gfx(0.0)) ) continue; - if( equal( tnormal, ntlVec3Gfx(0.0)) ) continue; - // */ - - ntlVec3Gfx bbs, bbe; - //errMsg("TreeDebug","Triangle"); - for(int i=0;i<3;i++) { - int index = (*iter).getPoints()[i]; - ntlVec3Gfx tp = (*mpVertices)[ index ]; - //errMsg("TreeDebug"," Point "<<i<<" = "<<tp<<" "); - if(tp[0] < mStart[0]) mStart[0]= tp[0]; - if(tp[0] > mEnd[0]) mEnd[0]= tp[0]; - if(tp[1] < mStart[1]) mStart[1]= tp[1]; - if(tp[1] > mEnd[1]) mEnd[1]= tp[1]; - if(tp[2] < mStart[2]) mStart[2]= tp[2]; - if(tp[2] > mEnd[2]) mEnd[2]= tp[2]; - if(i==0) { - bbs = bbe = tp; - } else { - if( tp[0] < bbs[0] ) bbs[0] = tp[0]; - if( tp[0] > bbe[0] ) bbe[0] = tp[0]; - if( tp[1] < bbs[1] ) bbs[1] = tp[1]; - if( tp[1] > bbe[1] ) bbe[1] = tp[1]; - if( tp[2] < bbs[2] ) bbs[2] = tp[2]; - if( tp[2] > bbe[2] ) bbe[2] = tp[2]; - } - } - mppTriangles->push_back( &(*iter) ); - //errMsg("TreeDebug","Triangle "<<(*mpVertices)[(*iter).getPoints()[0]]<<" "<<(*mpVertices)[(*iter).getPoints()[1]]<<" "<<(*mpVertices)[(*iter).getPoints()[2]]<<" "); - - // add BB - mpTBB[ bbCount ].start = bbs; - mpTBB[ bbCount ].end = bbe; - (*iter).setBBoxId( bbCount ); - bbCount++; - } - - - - /* slighlty enlarge bounding tolerance for tree - to avoid problems with triangles paralell to slabs */ - mStart -= ntlVec3Gfx( getVecEpsilon() ); - mEnd += ntlVec3Gfx( getVecEpsilon() ); - - /* init root node and stack */ - mpNodeStack = new BSPStack; - mpRoot = new BSPNode; - mpRoot->min = mStart; - mpRoot->max = mEnd; - mpRoot->axis = AXIS_X; - mpRoot->members = mppTriangles; - mpRoot->child[0] = mpRoot->child[1] = NULL; - mpRoot->cloneVec = 0; - globalSortingPoints = mpVertices; - mpTriDist = new char[ mppTriangles->size() ]; - mNumNodes = 1; - mAbortSubdiv = 0; - - /* create tree */ - debugOutInter( "Generating BSP Tree... (Nodes "<< mCurrentNodes << - ", Depth "<<mCurrentDepth<< ") ", 2, 2000 ); - subdivide(mpRoot, 0, AXIS_X); - debMsgStd("ntlTree::ntlTree",DM_MSG,"Generated Tree: Nodes "<< mCurrentNodes << - ", Depth "<<mCurrentDepth<< " with "<<noOfTriangles<<" triangles", 2 ); - - delete [] mpTriDist; - delete [] mpTBB; - mpTriDist = NULL; - mpTBB = NULL; - - /* calculate some stats about tree */ - int noLeafs = 0; - gfxReal avgDepth = 0.0; - gfxReal triPerLeaf = 0.0; - int totalTris = 0; - - calcStats(mpRoot,0, noLeafs, avgDepth, triPerLeaf, totalTris); - avgDepth /= (gfxReal)noLeafs; - triPerLeaf /= (gfxReal)noLeafs; - debMsgStd("ntlTree::ntlTree",DM_MSG,"Tree ("<<doSort<<","<<chooseAxis<<") Stats: Leafs:"<<noLeafs<<", avgDepth:"<<avgDepth<< - ", triPerLeaf:"<<triPerLeaf<<", triDoubles:"<<mTriDoubles<<", totalTris:"<<totalTris - <<" nodes:"<<mNumNodes - //<<" T"<< (totalTris%3) // 0=ich, 1=f, 2=a - , 2 ); - - if(mAbortSubdiv) { - errMsg("ntlTree::ntlTree","Aborted... "<<mNumNodes); - deleteNode(mpRoot); - mpRoot = NULL; - } -} - -/****************************************************************************** - * Destructor - *****************************************************************************/ -ntlTree::~ntlTree() -{ - /* delete tree, and all members except for the root node */ - deleteNode(mpRoot); - if(mpNodeStack) delete mpNodeStack; -} - - -/****************************************************************************** - * subdivide tree - *****************************************************************************/ -void ntlTree::subdivide(BSPNode *node, int depth, int axis) -{ - int nextAxis=0; /* next axis to partition */ - int allTriDistSet = (1<<0)|(1<<1); // all mpTriDist flags set? - //errorOut(" "<<node<<" depth:"<<depth<<" m:"<<node->members->size() <<" "<<node->min<<" - "<<node->max ); - - if(depth>mCurrentDepth) mCurrentDepth = depth; - node->child[0] = node->child[1] = NULL; - if( ( (int)node->members->size() > mMaxListLength) && - (depth < mMaxDepth ) - && (node->cloneVec<10) - && (!mAbortSubdiv) - ) { - - gfxReal planeDiv = 0.499999; // position of plane division - - // determine next subdivision axis - int newaxis = 0; - gfxReal extX = node->max[0]-node->min[0]; - gfxReal extY = node->max[1]-node->min[1]; - gfxReal extZ = node->max[2]-node->min[2]; - - if( extY>extX ) { - if( extZ>extY ) { - newaxis = 2; - } else { - newaxis = 1; - } - } else { - if( extZ>extX ) { - newaxis = 2; - } else { - newaxis = 0; - } - } - axis = node->axis = newaxis; - - // init child nodes - for( int i=0; i<2; i++) { - /* status output */ - mCurrentNodes++; - if(mCurrentNodes % 13973 ==0) { - debugOutInter( "NTL Generating BSP Tree ("<<doSort<<","<<chooseAxis<<") ... (Nodes "<< mCurrentNodes << - ", Depth "<<mCurrentDepth<< ") " , 2, 2000); - } - - /* create new node */ - node->child[i] = new BSPNode; - node->child[i]->min = node->min; - node->child[i]->max = node->max; - node->child[i]->max = node->max; - node->child[i]->child[0] = NULL; - node->child[i]->child[1] = NULL; - node->child[i]->members = NULL; - nextAxis = (axis+1)%3; - node->child[i]->axis = nextAxis; - mNumNodes++; - // abort when using 256MB only for tree... - if(mNumNodes*sizeof(BSPNode)> 1024*1024*512) mAbortSubdiv = 1; - - /* current division plane */ - if(!i) { - node->child[i]->min[axis] = node->min[axis]; - node->child[i]->max[axis] = node->min[axis] + planeDiv* - (node->max[axis]-node->min[axis]); - } else { - node->child[i]->min[axis] = node->min[axis] + planeDiv* - (node->max[axis]-node->min[axis]); - node->child[i]->max[axis] = node->max[axis]; - } - } - - - /* process the two children */ - int thisTrisFor[2] = {0,0}; - int thisTriDoubles[2] = {0,0}; - for(int t=0;t<(int)node->members->size();t++) mpTriDist[t] = 0; - for( int i=0; i<2; i++) { - /* distribute triangles */ - int t = 0; - for (vector<ntlTriangle *>::iterator iter = node->members->begin(); - iter != node->members->end(); iter++ ) { - - /* add triangle, check bounding box axis */ - TriangleBBox *bbox = &mpTBB[ (*iter)->getBBoxId() ]; - bool isintersect = true; - if( bbox->end[axis] < node->child[i]->min[axis] ) isintersect = false; - else if( bbox->start[axis] > node->child[i]->max[axis] ) isintersect = false; - if(isintersect) { - // add flag to vector - mpTriDist[t] |= (1<<i); - // count no. of triangles for vector init - thisTrisFor[i]++; - } - - if(mpTriDist[t] == allTriDistSet) { - thisTriDoubles[i]++; - mTriDoubles++; // TODO check for small geo tree?? - } - t++; - } /* end of loop over all triangles */ - } // i - - /* distribute triangles */ - bool haveCloneVec[2] = {false, false}; - for( int i=0; i<2; i++) { - node->child[i]->members = new vector<ntlTriangle *>( thisTrisFor[i] ); - node->child[i]->cloneVec = 0; - } - - int tind0 = 0; - int tind1 = 0; - if( (!haveCloneVec[0]) || (!haveCloneVec[1]) ){ - int t = 0; // triangle index counter - for (vector<ntlTriangle *>::iterator iter = node->members->begin(); - iter != node->members->end(); iter++ ) { - if(!haveCloneVec[0]) { - if( (mpTriDist[t] & 1) == 1) { - (*node->child[0]->members)[tind0] = (*iter); // dont use push_back for preinited size! - tind0++; - } - } - if(!haveCloneVec[1]) { - if( (mpTriDist[t] & 2) == 2) { - (*node->child[1]->members)[tind1] = (*iter); // dont use push_back for preinited size! - tind1++; - } - } - t++; - } /* end of loop over all triangles */ - } - - // subdivide children - for( int i=0; i<2; i++) { - /* recurse */ - subdivide( node->child[i], depth+1, nextAxis ); - } - - /* if we are here, this are childs, so we dont need the members any more... */ - /* delete unecessary members */ - if( (!haveCloneVec[0]) && (!haveCloneVec[1]) && (node->cloneVec == 0) ){ - delete node->members; - } - node->members = NULL; - - } /* subdivision necessary */ -} - -/****************************************************************** - * triangle intersection with triangle pointer, - * returns t,u,v by references - */ -#if GFX_PRECISION==1 -// float values -//! the minimal triangle determinant length -#define RAY_TRIANGLE_EPSILON (1e-07) - -#else -// double values -//! the minimal triangle determinant length -#define RAY_TRIANGLE_EPSILON (1e-15) - -#endif - - -/****************************************************************************** - * intersect ray with BSPtree - *****************************************************************************/ -inline void ntlRay::intersectTriangle(vector<ntlVec3Gfx> *mpV, ntlTriangle *tri, gfxReal &t, gfxReal &u, gfxReal &v) const -{ - /* (cf. moeller&haines, page 305) */ - t = GFX_REAL_MAX; - ntlVec3Gfx e0 = (*mpV)[ tri->getPoints()[0] ]; - ntlVec3Gfx e1 = (*mpV)[ tri->getPoints()[1] ] - e0; - ntlVec3Gfx e2 = (*mpV)[ tri->getPoints()[2] ] - e0; - ntlVec3Gfx p = cross( mDirection, e2 ); - gfxReal divisor = dot(e1, p); - if((divisor > -RAY_TRIANGLE_EPSILON)&&(divisor < RAY_TRIANGLE_EPSILON)) return; - - gfxReal invDivisor = 1/divisor; - ntlVec3Gfx s = mOrigin - e0; - u = invDivisor * dot(s, p); - if( (u<0.0-RAY_TRIANGLE_EPSILON) || (u>1.0+RAY_TRIANGLE_EPSILON) ) return; - - ntlVec3Gfx q = cross( s,e1 ); - v = invDivisor * dot(mDirection, q); - if( (v<0.0-RAY_TRIANGLE_EPSILON) || ((u+v)>1.0+RAY_TRIANGLE_EPSILON) ) return; - - t = invDivisor * dot(e2, q); -} -void ntlTree::intersect(const ntlRay &ray, gfxReal &distance, - ntlVec3Gfx &normal, - ntlTriangle *&tri, - int flags, bool forceNonsmooth) const -{ - gfxReal mint = GFX_REAL_MAX; /* current minimal t */ - ntlVec3Gfx retnormal; /* intersection (interpolated) normal */ - gfxReal mintu=0.0, mintv=0.0; /* u,v for min t intersection */ - - BSPNode *curr, *nearChild, *farChild; /* current node and children */ - gfxReal planedist, mindist, maxdist; - ntlVec3Gfx pos; - - ntlTriangle *hit = NULL; - tri = NULL; - - ray.intersectCompleteAABB(mStart,mEnd,mindist,maxdist); - - if((maxdist < 0.0) || - (!mpRoot) || - (mindist == GFX_REAL_MAX) || - (maxdist == GFX_REAL_MAX) ) { - distance = -1.0; - return; - } - mindist -= getVecEpsilon(); - maxdist += getVecEpsilon(); - - /* stack init */ - mpNodeStack->elem[0].node = NULL; - mpNodeStack->stackPtr = 1; - - curr = mpRoot; - mint = GFX_REAL_MAX; - while(curr != NULL) { - - while( !curr->isLeaf() ) { - planedist = distanceToPlane(curr, curr->child[0]->max, ray ); - getChildren(curr, ray.getOrigin(), nearChild, farChild ); - - // check ray direction for small plane distances - if( (planedist>-getVecEpsilon() )&&(planedist< getVecEpsilon() ) ) { - // ray origin on intersection plane - planedist = 0.0; - if(ray.getDirection()[curr->axis]>getVecEpsilon() ) { - // larger coords - curr = curr->child[1]; - } else if(ray.getDirection()[curr->axis]<-getVecEpsilon() ) { - // smaller coords - curr = curr->child[0]; - } else { - // paralell, order doesnt really matter are min/max/plane ok? - mpNodeStack->elem[ mpNodeStack->stackPtr ].node = curr->child[0]; - mpNodeStack->elem[ mpNodeStack->stackPtr ].mindist = planedist; - mpNodeStack->elem[ mpNodeStack->stackPtr ].maxdist = maxdist; - (mpNodeStack->stackPtr)++; - curr = curr->child[1]; - maxdist = planedist; - } - } else { - // normal ray - if( (planedist>maxdist) || (planedist<0.0-getVecEpsilon() ) ) { - curr = nearChild; - } else if(planedist < mindist) { - curr = farChild; - } else { - mpNodeStack->elem[ mpNodeStack->stackPtr ].node = farChild; - mpNodeStack->elem[ mpNodeStack->stackPtr ].mindist = planedist; - mpNodeStack->elem[ mpNodeStack->stackPtr ].maxdist = maxdist; - (mpNodeStack->stackPtr)++; - - curr = nearChild; - maxdist = planedist; - } - } - } - - - /* intersect with current node */ - for (vector<ntlTriangle *>::iterator iter = curr->members->begin(); - iter != curr->members->end(); iter++ ) { - - /* check for triangle flags before intersecting */ - if((!flags) || ( ((*iter)->getFlags() & flags) > 0 )) { - - if( ((*iter)->getLastRay() == ray.getID() )&&((*iter)->getLastRay()>0) ) { - // was already intersected... - } else { - // we still need to intersect this triangle - gfxReal u=0.0,v=0.0, t=-1.0; - ray.intersectTriangle( mpVertices, (*iter), t,u,v); - (*iter)->setLastRay( ray.getID() ); - - if( (t > 0.0) && (t<mint) ) { - mint = t; - hit = (*iter); - mintu = u; mintv = v; - } - } - - } // flags check - } - - /* check if intersection is valid */ - if( (mint>0.0) && (mint < GFX_REAL_MAX) ) { - pos = ray.getOrigin() + ray.getDirection()*mint; - - if( (pos[0] >= curr->min[0]) && (pos[0] <= curr->max[0]) && - (pos[1] >= curr->min[1]) && (pos[1] <= curr->max[1]) && - (pos[2] >= curr->min[2]) && (pos[2] <= curr->max[2]) ) - { - - if(forceNonsmooth) { - // calculate triangle normal - ntlVec3Gfx e0,e1,e2; - e0 = (*mpVertices)[ hit->getPoints()[0] ]; - e1 = (*mpVertices)[ hit->getPoints()[1] ]; - e2 = (*mpVertices)[ hit->getPoints()[2] ]; - retnormal = cross( -(e2-e0), (e1-e0) ); - } else { - // calculate interpolated normal - retnormal = (*mpVertNormals)[ hit->getPoints()[0] ] * (1.0-mintu-mintv)+ - (*mpVertNormals)[ hit->getPoints()[1] ]*mintu + - (*mpVertNormals)[ hit->getPoints()[2] ]*mintv; - } - normalize(retnormal); - normal = retnormal; - distance = mint; - tri = hit; - return; - } - } - - (mpNodeStack->stackPtr)--; - curr = mpNodeStack->elem[ mpNodeStack->stackPtr ].node; - mindist = mpNodeStack->elem[ mpNodeStack->stackPtr ].mindist; - maxdist = mpNodeStack->elem[ mpNodeStack->stackPtr ].maxdist; - } /* traverse tree */ - - if(mint == GFX_REAL_MAX) { - distance = -1.0; - } else { - // intersection outside the BSP bounding volumes might occur due to roundoff... - //retnormal = (*mpVertNormals)[ hit->getPoints()[0] ] * (1.0-mintu-mintv)+ (*mpVertNormals)[ hit->getPoints()[1] ]*mintu + (*mpVertNormals)[ hit->getPoints()[2] ]*mintv; - if(forceNonsmooth) { - // calculate triangle normal - ntlVec3Gfx e0,e1,e2; - e0 = (*mpVertices)[ hit->getPoints()[0] ]; - e1 = (*mpVertices)[ hit->getPoints()[1] ]; - e2 = (*mpVertices)[ hit->getPoints()[2] ]; - retnormal = cross( -(e2-e0), (e1-e0) ); - } else { - // calculate interpolated normal - retnormal = (*mpVertNormals)[ hit->getPoints()[0] ] * (1.0-mintu-mintv)+ - (*mpVertNormals)[ hit->getPoints()[1] ]*mintu + - (*mpVertNormals)[ hit->getPoints()[2] ]*mintv; - } - - normalize(retnormal); - normal = retnormal; - distance = mint; - tri = hit; - } - return; -} - -inline void ntlRay::intersectTriangleX(vector<ntlVec3Gfx> *mpV, ntlTriangle *tri, gfxReal &t, gfxReal &u, gfxReal &v) const -{ - /* (cf. moeller&haines, page 305) */ - t = GFX_REAL_MAX; - ntlVec3Gfx e0 = (*mpV)[ tri->getPoints()[0] ]; - ntlVec3Gfx e1 = (*mpV)[ tri->getPoints()[1] ] - e0; - ntlVec3Gfx e2 = (*mpV)[ tri->getPoints()[2] ] - e0; - - //ntlVec3Gfx p = cross( mDirection, e2 ); - //ntlVector3Dim<Scalar> cp( (-), (- (1.0 *v[2])), ((1.0 *v[1]) -) ); - ntlVec3Gfx p(0.0, -e2[2], e2[1]); - - gfxReal divisor = dot(e1, p); - if((divisor > -RAY_TRIANGLE_EPSILON)&&(divisor < RAY_TRIANGLE_EPSILON)) return; - - gfxReal invDivisor = 1/divisor; - ntlVec3Gfx s = mOrigin - e0; - u = invDivisor * dot(s, p); - if( (u<0.0-RAY_TRIANGLE_EPSILON) || (u>1.0+RAY_TRIANGLE_EPSILON) ) return; - - ntlVec3Gfx q = cross( s,e1 ); - //v = invDivisor * dot(mDirection, q); - v = invDivisor * q[0]; - if( (v<0.0-RAY_TRIANGLE_EPSILON) || ((u+v)>1.0+RAY_TRIANGLE_EPSILON) ) return; - - t = invDivisor * dot(e2, q); -} -void ntlTree::intersectX(const ntlRay &ray, gfxReal &distance, - ntlVec3Gfx &normal, - ntlTriangle *&tri, - int flags, bool forceNonsmooth) const -{ - gfxReal mint = GFX_REAL_MAX; /* current minimal t */ - ntlVec3Gfx retnormal; /* intersection (interpolated) normal */ - gfxReal mintu=0.0, mintv=0.0; /* u,v for min t intersection */ - - BSPNode *curr, *nearChild, *farChild; /* current node and children */ - gfxReal planedist, mindist, maxdist; - ntlVec3Gfx pos; - - ntlTriangle *hit = NULL; - tri = NULL; - - ray.intersectCompleteAABB(mStart,mEnd,mindist,maxdist); // +X - - if((maxdist < 0.0) || - (!mpRoot) || - (mindist == GFX_REAL_MAX) || - (maxdist == GFX_REAL_MAX) ) { - distance = -1.0; - return; - } - mindist -= getVecEpsilon(); - maxdist += getVecEpsilon(); - - /* stack init */ - mpNodeStack->elem[0].node = NULL; - mpNodeStack->stackPtr = 1; - - curr = mpRoot; - mint = GFX_REAL_MAX; - while(curr != NULL) { // +X - - while( !curr->isLeaf() ) { - planedist = distanceToPlane(curr, curr->child[0]->max, ray ); - getChildren(curr, ray.getOrigin(), nearChild, farChild ); - - // check ray direction for small plane distances - if( (planedist>-getVecEpsilon() )&&(planedist< getVecEpsilon() ) ) { - // ray origin on intersection plane - planedist = 0.0; - if(ray.getDirection()[curr->axis]>getVecEpsilon() ) { - // larger coords - curr = curr->child[1]; - } else if(ray.getDirection()[curr->axis]<-getVecEpsilon() ) { - // smaller coords - curr = curr->child[0]; - } else { - // paralell, order doesnt really matter are min/max/plane ok? - mpNodeStack->elem[ mpNodeStack->stackPtr ].node = curr->child[0]; - mpNodeStack->elem[ mpNodeStack->stackPtr ].mindist = planedist; - mpNodeStack->elem[ mpNodeStack->stackPtr ].maxdist = maxdist; - (mpNodeStack->stackPtr)++; - curr = curr->child[1]; - maxdist = planedist; - } - } else { - // normal ray - if( (planedist>maxdist) || (planedist<0.0-getVecEpsilon() ) ) { - curr = nearChild; - } else if(planedist < mindist) { - curr = farChild; - } else { - mpNodeStack->elem[ mpNodeStack->stackPtr ].node = farChild; - mpNodeStack->elem[ mpNodeStack->stackPtr ].mindist = planedist; - mpNodeStack->elem[ mpNodeStack->stackPtr ].maxdist = maxdist; - (mpNodeStack->stackPtr)++; - - curr = nearChild; - maxdist = planedist; - } - } - } // +X - - - /* intersect with current node */ - for (vector<ntlTriangle *>::iterator iter = curr->members->begin(); - iter != curr->members->end(); iter++ ) { - - /* check for triangle flags before intersecting */ - if((!flags) || ( ((*iter)->getFlags() & flags) > 0 )) { - - if( ((*iter)->getLastRay() == ray.getID() )&&((*iter)->getLastRay()>0) ) { - // was already intersected... - } else { - // we still need to intersect this triangle - gfxReal u=0.0,v=0.0, t=-1.0; - ray.intersectTriangleX( mpVertices, (*iter), t,u,v); - (*iter)->setLastRay( ray.getID() ); - - if( (t > 0.0) && (t<mint) ) { - mint = t; - hit = (*iter); - mintu = u; mintv = v; - } - } - - } // flags check - } // +X - - /* check if intersection is valid */ - if( (mint>0.0) && (mint < GFX_REAL_MAX) ) { - pos = ray.getOrigin() + ray.getDirection()*mint; - - if( (pos[0] >= curr->min[0]) && (pos[0] <= curr->max[0]) && - (pos[1] >= curr->min[1]) && (pos[1] <= curr->max[1]) && - (pos[2] >= curr->min[2]) && (pos[2] <= curr->max[2]) ) - { - - if(forceNonsmooth) { - // calculate triangle normal - ntlVec3Gfx e0,e1,e2; - e0 = (*mpVertices)[ hit->getPoints()[0] ]; - e1 = (*mpVertices)[ hit->getPoints()[1] ]; - e2 = (*mpVertices)[ hit->getPoints()[2] ]; - retnormal = cross( -(e2-e0), (e1-e0) ); - } else { - // calculate interpolated normal - retnormal = (*mpVertNormals)[ hit->getPoints()[0] ] * (1.0-mintu-mintv)+ - (*mpVertNormals)[ hit->getPoints()[1] ]*mintu + - (*mpVertNormals)[ hit->getPoints()[2] ]*mintv; - } - normalize(retnormal); - normal = retnormal; - distance = mint; - tri = hit; - return; - } - } // +X - - (mpNodeStack->stackPtr)--; - curr = mpNodeStack->elem[ mpNodeStack->stackPtr ].node; - mindist = mpNodeStack->elem[ mpNodeStack->stackPtr ].mindist; - maxdist = mpNodeStack->elem[ mpNodeStack->stackPtr ].maxdist; - } /* traverse tree */ - - if(mint == GFX_REAL_MAX) { - distance = -1.0; - } else { - - // intersection outside the BSP bounding volumes might occur due to roundoff... - if(forceNonsmooth) { - // calculate triangle normal - ntlVec3Gfx e0,e1,e2; - e0 = (*mpVertices)[ hit->getPoints()[0] ]; - e1 = (*mpVertices)[ hit->getPoints()[1] ]; - e2 = (*mpVertices)[ hit->getPoints()[2] ]; - retnormal = cross( -(e2-e0), (e1-e0) ); - } else { - // calculate interpolated normal - retnormal = (*mpVertNormals)[ hit->getPoints()[0] ] * (1.0-mintu-mintv)+ - (*mpVertNormals)[ hit->getPoints()[1] ]*mintu + - (*mpVertNormals)[ hit->getPoints()[2] ]*mintv; - } - - normalize(retnormal); - normal = retnormal; - distance = mint; - tri = hit; - } // +X - return; -} - - - -/****************************************************************************** - * distance to plane function for nodes - *****************************************************************************/ -gfxReal ntlTree::distanceToPlane(BSPNode *curr, ntlVec3Gfx plane, ntlRay ray) const -{ - return ( (plane[curr->axis]-ray.getOrigin()[curr->axis]) / ray.getDirection()[curr->axis] ); -} - - -/****************************************************************************** - * return ordering of children nodes relatice to origin point - *****************************************************************************/ -void ntlTree::getChildren(BSPNode *curr, ntlVec3Gfx origin, BSPNode *&node_near, BSPNode *&node_far) const -{ - if(curr->child[0]->max[ curr->axis ] >= origin[ curr->axis ]) { - node_near = curr->child[0]; - node_far = curr->child[1]; - } else { - node_near = curr->child[1]; - node_far = curr->child[0]; - } -} - - -/****************************************************************************** - * delete a node of the tree with all sub nodes - * dont delete root members - *****************************************************************************/ -void ntlTree::deleteNode(BSPNode *curr) -{ - if(!curr) return; - - if(curr->child[0] != NULL) - deleteNode(curr->child[0]); - if(curr->child[1] != NULL) - deleteNode(curr->child[1]); - - if(curr->members != NULL) delete curr->members; - delete curr; -} - - - -/****************************************************************** - * intersect only front or backsides - * currently unused - */ -inline void ntlRay::intersectTriangleFront(vector<ntlVec3Gfx> *mpV, ntlTriangle *tri, gfxReal &t, gfxReal &u, gfxReal &v) const -{ - t = GFX_REAL_MAX; - ntlVec3Gfx e0 = (*mpV)[ tri->getPoints()[0] ]; - ntlVec3Gfx e1 = (*mpV)[ tri->getPoints()[1] ] - e0; - ntlVec3Gfx e2 = (*mpV)[ tri->getPoints()[2] ] - e0; - ntlVec3Gfx p = cross( mDirection, e2 ); - gfxReal a = dot(e1, p); - //if((a > -RAY_TRIANGLE_EPSILON)&&(a < RAY_TRIANGLE_EPSILON)) return; - if(a < RAY_TRIANGLE_EPSILON) return; // cull backsides - - gfxReal f = 1/a; - ntlVec3Gfx s = mOrigin - e0; - u = f * dot(s, p); - if( (u<0.0-RAY_TRIANGLE_EPSILON) || (u>1.0+RAY_TRIANGLE_EPSILON) ) return; - - ntlVec3Gfx q = cross( s,e1 ); - v = f * dot(mDirection, q); - if( (v<0.0-RAY_TRIANGLE_EPSILON) || ((u+v)>1.0+RAY_TRIANGLE_EPSILON) ) return; - - t = f * dot(e2, q); -} -inline void ntlRay::intersectTriangleBack(vector<ntlVec3Gfx> *mpV, ntlTriangle *tri, gfxReal &t, gfxReal &u, gfxReal &v) const -{ - t = GFX_REAL_MAX; - ntlVec3Gfx e0 = (*mpV)[ tri->getPoints()[0] ]; - ntlVec3Gfx e1 = (*mpV)[ tri->getPoints()[1] ] - e0; - ntlVec3Gfx e2 = (*mpV)[ tri->getPoints()[2] ] - e0; - ntlVec3Gfx p = cross( mDirection, e2 ); - gfxReal a = dot(e1, p); - //if((a > -RAY_TRIANGLE_EPSILON)&&(a < RAY_TRIANGLE_EPSILON)) return; - if(a > -RAY_TRIANGLE_EPSILON) return; // cull frontsides - - gfxReal f = 1/a; - ntlVec3Gfx s = mOrigin - e0; - u = f * dot(s, p); - if( (u<0.0-RAY_TRIANGLE_EPSILON) || (u>1.0+RAY_TRIANGLE_EPSILON) ) return; - - ntlVec3Gfx q = cross( s,e1 ); - v = f * dot(mDirection, q); - if( (v<0.0-RAY_TRIANGLE_EPSILON) || ((u+v)>1.0+RAY_TRIANGLE_EPSILON) ) return; - - t = f * dot(e2, q); -} - - - diff --git a/intern/elbeem/intern/ntl_bsptree.h b/intern/elbeem/intern/ntl_bsptree.h deleted file mode 100644 index f6eaee069a9..00000000000 --- a/intern/elbeem/intern/ntl_bsptree.h +++ /dev/null @@ -1,135 +0,0 @@ -/** \file - * \ingroup elbeem - */ -/****************************************************************************** - * - * El'Beem - Free Surface Fluid Simulation with the Lattice Boltzmann Method - * Copyright 2003-2006 Nils Thuerey - * - * Tree container for fast triangle intersects - * - *****************************************************************************/ -#ifndef NTL_TREE_H -#define NTL_TREE_H - -#include "ntl_vector3dim.h" -#include "ntl_ray.h" - - -#define AXIS_X 0 -#define AXIS_Y 1 -#define AXIS_Z 2 - -#define BSP_STACK_SIZE 50 - -#ifdef WITH_CXX_GUARDEDALLOC -# include "MEM_guardedalloc.h" -#endif - -//! bsp tree stack classes, defined in ntl_bsptree.cpp, -// detailed definition unnecesseary here -class BSPNode; -class BSPStackElement; -class BSPStack; -class TriangleBBox; -class ntlScene; -class ntlTriangle; - - -//! Class for a bsp tree for triangles -class ntlTree -{ - public: - - //! Default constructor - ntlTree(); - //! Constructor with init - ntlTree(int depth, int objnum, ntlScene *scene, int triFlagMask); - //! Destructor - ~ntlTree(); - - //! subdivide tree - void subdivide(BSPNode *node, int depth, int axis); - - //! intersect ray with BSPtree - void intersect(const ntlRay &ray, gfxReal &distance, ntlVec3Gfx &normal, ntlTriangle *&tri, int flags, bool forceNonsmooth) const; - //! intersect along +X ray - void intersectX(const ntlRay &ray, gfxReal &distance, ntlVec3Gfx &normal, ntlTriangle *&tri, int flags, bool forceNonsmooth) const; - - //! Returns number of nodes - int getCurrentNodes( void ) { return mCurrentNodes; } - - protected: - - // check if a triangle is in a node - bool checkAABBTriangle(ntlVec3Gfx &min, ntlVec3Gfx &max, ntlTriangle *tri); - - - // VARs - - //! distance to plane function for nodes - gfxReal distanceToPlane(BSPNode *curr, ntlVec3Gfx plane, ntlRay ray) const; - - //! return ordering of children nodes relatice to origin point - void getChildren(BSPNode *curr, ntlVec3Gfx origin, BSPNode *&node_near, BSPNode *&node_far) const; - - //! delete a node of the tree with all sub nodes, dont delete root members - void deleteNode(BSPNode *curr); - - //inline bool isLeaf(BSPNode *node) const { return (node->child[0] == NULL); } - - - //! AABB for tree - ntlVec3Gfx mStart,mEnd; - - //! maximum depth of tree - int mMaxDepth; - - //! maximum number of objects in one node - int mMaxListLength; - - //! root node pointer - BSPNode *mpRoot; - //! count no. of node - int mNumNodes; - int mAbortSubdiv; - - //! stack for the node pointers - BSPStack *mpNodeStack; - //stack<BSPNode *> nodestack; - - //! pointer to vertex array - vector<ntlVec3Gfx> *mpVertices; - - //! pointer to vertex array - vector<ntlVec3Gfx> *mpVertNormals; - - //! vector for all the triangles - vector<ntlTriangle> *mpTriangles; - vector<ntlTriangle *> *mppTriangles; - - //! temporary array for triangle distribution to nodes - char *mpTriDist; - - //! temporary array for triangle bounding boxes - TriangleBBox *mpTBB; - - //! triangle mask - include only triangles that match mask - int mTriangleMask; - - //! Status vars (max depth, # of current nodes) - int mCurrentDepth, mCurrentNodes; - - //! duplicated triangles, inited during subdivide - int mTriDoubles; - -private: -#ifdef WITH_CXX_GUARDEDALLOC - MEM_CXX_CLASS_ALLOC_FUNCS("ELBEEM:ntlTree") -#endif -}; - - -#endif - - diff --git a/intern/elbeem/intern/ntl_geometryclass.h b/intern/elbeem/intern/ntl_geometryclass.h deleted file mode 100644 index a5d44ad477a..00000000000 --- a/intern/elbeem/intern/ntl_geometryclass.h +++ /dev/null @@ -1,127 +0,0 @@ -/** \file - * \ingroup elbeem - */ -/****************************************************************************** - * - * El'Beem - Free Surface Fluid Simulation with the Lattice Boltzmann Method - * Copyright 2003-2006 Nils Thuerey - * - * Base class for geometry shaders and objects - * - *****************************************************************************/ - - -#ifndef NTL_GEOMETRYCLASS_H -#define NTL_GEOMETRYCLASS_H - -#include "attributes.h" - -#ifdef WITH_CXX_GUARDEDALLOC -# include "MEM_guardedalloc.h" -#endif - -//! geometry class type ids -#define GEOCLASSTID_OBJECT 1 -#define GEOCLASSTID_SHADER 2 -#define GEOCLASSTID_BOX (GEOCLASSTID_OBJECT| 4) -#define GEOCLASSTID_OBJMODEL (GEOCLASSTID_OBJECT| 8) -#define GEOCLASSTID_SPHERE (GEOCLASSTID_OBJECT| 16) - -class ntlGeometryClass -{ - - public: - - //! Default constructor - inline ntlGeometryClass() : - mVisible( 1 ), mName( "[ObjNameUndef]" ), - mObjectId(-1), mpAttrs( NULL ), mGeoInitId(-1) - { - mpAttrs = new AttributeList("objAttrs"); - mpSwsAttrs = new AttributeList("swsAttrs"); - }; - - //! Default destructor - virtual ~ntlGeometryClass() { - delete mpAttrs; - delete mpSwsAttrs; - }; - - //! Return type id - virtual int getTypeId() = 0; - - /*! Set the object name */ - inline void setName(string set) { mName = set; } - /*! Get the object name */ - inline string getName( void ) { return mName; } - - /*! Sets the visibility attribute - * visibility can be determined at shader _and_ object level , hiding a shader - * means comepletely decativating it */ - inline void setVisible(int set) { mVisible=set; } - /*! Returns the visibility attribute */ - inline int getVisible() const { return mVisible; } - - /*! Sets the attribute list pointer */ - inline void setAttributeList(AttributeList *set) { mpAttrs=set; } - /*! Returns the attribute list pointer */ - inline AttributeList *getAttributeList() { return mpAttrs; } - - /*! Get/Sets the attribute list pointer */ - inline void setSwsAttributeList(AttributeList *set) { mpSwsAttrs=set; } - inline AttributeList *getSwsAttributeList() { return mpSwsAttrs; } - - /*! for easy GUI detection get start of axis aligned bounding box, return NULL of no BB */ - virtual inline ntlVec3Gfx *getBBStart() { return NULL; } - virtual inline ntlVec3Gfx *getBBEnd() { return NULL; } - - /*! Set/get the object id*/ - inline void setObjectId(int set) { mObjectId=set; } - inline int getObjectId() const { return mObjectId; } - - /*! GUI - this function is called for selected objects to display debugging information with OpenGL */ - virtual void drawDebugDisplay() { /* do nothing by default */ } - /*! GUI - this function is called for selected objects to display interactive information with OpenGL */ - virtual void drawInteractiveDisplay() { /* do nothing by default */ } - /*! GUI - handle mouse movement for selection */ - virtual void setMousePos(int ,int , ntlVec3Gfx , ntlVec3Gfx ) { /* do nothing by default */ } - /*! GUI - notify object that mouse was clicked at last pos */ - virtual void setMouseClick() { /* do nothing by default */ } - - /*! Returns the geo init id */ - inline void setGeoInitId(int set) { mGeoInitId=set; } - /*! Returns the geo init id */ - inline int getGeoInitId() const { return mGeoInitId; } - - protected: - - /*! Object visible on/off */ - int mVisible; - - /*! Name of this object */ - string mName; - - /*! global scene object id */ - int mObjectId; - - /*! configuration attributes */ - AttributeList *mpAttrs; - /*! sws configuration attributes */ - AttributeList *mpSwsAttrs; - - /* fluid init data */ - /*! id of fluid init (is used in solver initialization), additional data stored only for objects */ - int mGeoInitId; - - private: - -private: -#ifdef WITH_CXX_GUARDEDALLOC - MEM_CXX_CLASS_ALLOC_FUNCS("ELBEEM:ntlGeometryClass") -#endif -}; - - - -#endif - diff --git a/intern/elbeem/intern/ntl_geometrymodel.cpp b/intern/elbeem/intern/ntl_geometrymodel.cpp deleted file mode 100644 index 989fcac599b..00000000000 --- a/intern/elbeem/intern/ntl_geometrymodel.cpp +++ /dev/null @@ -1,477 +0,0 @@ -/** \file - * \ingroup elbeem - */ -/****************************************************************************** - * - * El'Beem - Free Surface Fluid Simulation with the Lattice Boltzmann Method - * Copyright 2003-2006 Nils Thuerey - * - * A simple box object - * - *****************************************************************************/ - -#include "ntl_geometrymodel.h" -#include "ntl_ray.h" -#include "ntl_world.h" -#include "zlib.h" - -#ifdef WIN32 -#ifndef strncasecmp -#define strncasecmp(a,b,c) strcmp(a,b) -#endif -#endif // WIN32 - - -/****************************************************************************** - * Default Constructor - *****************************************************************************/ -ntlGeometryObjModel::ntlGeometryObjModel( void ) : - ntlGeometryObject(), - mvStart( 0.0 ), mvEnd( 1.0 ), - mLoaded( false ), - mTriangles(), mVertices(), mNormals(), - mcAniVerts(), mcAniNorms(), - mcAniTimes(), mAniTimeScale(1.), mAniTimeOffset(0.) -{ -} - -/****************************************************************************** - * Destructor - *****************************************************************************/ -ntlGeometryObjModel::~ntlGeometryObjModel() -{ - if(!mLoaded) { - errMsg("ntlGeometryObjModel","delete obj..."); - } -} - - -/*! is the mesh animated? */ -bool ntlGeometryObjModel::getMeshAnimated() { - const bool ret = (mcAniVerts.getSize()>1); - //errMsg("getMeshAnimated","ret="<<ret<<", size="<<mcAniVerts.getSize() ); - return ret; -} - -/*! calculate max extends of (ani) mesh */ -void ntlGeometryObjModel::getExtends(ntlVec3Gfx &sstart, ntlVec3Gfx &send) { - bool ini=false; - ntlVec3Gfx start(0.),end(0.); - for(int s=0; s<=(int)mcAniVerts.accessValues().size(); s++) { - vector<ntlVec3f> *sverts; - if(mcAniVerts.accessValues().size()>0) { - if(s==(int)mcAniVerts.accessValues().size()) continue; - sverts = &(mcAniVerts.accessValues()[s].mVerts); - } else sverts = &mVertices; - - for(int i=0; i<(int)sverts->size(); i++) { - - if(!ini) { - start=(*sverts)[i]; - end=(*sverts)[i]; - //errMsg("getExtends","ini "<<s<<","<<i<<" "<<start<<","<<end); - ini=true; - } else { - for(int j=0; j<3; j++) { - if(start[j] > (*sverts)[i][j]) { start[j]= (*sverts)[i][j]; } - if(end[j] < (*sverts)[i][j]) { end[j] = (*sverts)[i][j]; } - } - //errMsg("getExtends","check "<<s<<","<<i<<" "<<start<<","<<end<<" "<< (*sverts)[i]); - } - - } - } - sstart=start; - send=end; -} - - -/*****************************************************************************/ -/* Init attributes etc. of this object */ -/*****************************************************************************/ -void ntlGeometryObjModel::initialize(ntlRenderGlobals *glob) -{ - // perhaps the model is already inited from initModel below? - if(mLoaded==1) { - // init default material - searchMaterial( glob->getMaterials() ); - return; - } - - ntlGeometryObject::initialize(glob); - mFilename = mpAttrs->readString("filename", mFilename,"ntlGeometryObjModel", "mFilename", true); - - if(mFilename == "") { - errMsg("ntlGeometryObjModel::initialize","Filename not given!"); - return; - } - - const char *suffix = strrchr(mFilename.c_str(), '.'); - if (suffix) { - if (!strncasecmp(suffix, ".obj", 4)) { - errMsg("ntlGeometryObjModel::initialize",".obj files not supported!"); - return; - } else if (!strncasecmp(suffix, ".gz", 3)) { - //mType = 1; // assume its .bobj.gz - } else if (!strncasecmp(suffix, ".bobj", 5)) { - //mType = 1; - } - } - - if(getAttributeList()->exists("ani_times") || (!mcAniTimes.isInited()) ) { - mcAniTimes = mpAttrs->readChannelFloat("ani_times"); - } - mAniTimeScale = mpAttrs->readFloat("ani_timescale", mAniTimeScale,"ntlGeometryObjModel", "mAniTimeScale", false); - mAniTimeOffset = mpAttrs->readFloat("ani_timeoffset", mAniTimeOffset,"ntlGeometryObjModel", "mAniTimeOffset", false); - - // continue with standard obj - if(loadBobjModel(mFilename)==0) mLoaded=1; - if(!mLoaded) { - debMsgStd("ntlGeometryObjModel",DM_WARNING,"Unable to load object file '"<<mFilename<<"' !", 0); - } - if(getMeshAnimated()) { - this->mIsAnimated = true; - } -} - -/****************************************************************************** - * init model from given vertex and triangle arrays - *****************************************************************************/ - -int ntlGeometryObjModel::initModel(int numVertices, float *vertices, int numTriangles, int *triangles, - int channelSize, float *channelVertices) -{ - mVertices.clear(); - mVertices.resize( numVertices ); - mNormals.resize( numVertices ); - for(int i=0; i<numVertices; i++) { - mVertices[i] = ntlVec3Gfx(vertices[i*3+0],vertices[i*3+1],vertices[i*3+2]); - mNormals[i] = ntlVec3Gfx(1.0); // unused, set to !=0.0 - } - - mTriangles.clear(); - mTriangles.resize( 3*numTriangles ); - int triangleErrs=0; - for(int i=0; i<numTriangles; i++) { - for(int j=0;j<3;j++) { - mTriangles[3*i+j] = triangles[i*3+j]; - if(mTriangles[3*i+j]<0) { mTriangles[3*i+j]=0; triangleErrs++; } - if(mTriangles[3*i+j]>=numVertices) { mTriangles[3*i+j]=0; triangleErrs++; } - } - } - if(triangleErrs>0) { - errMsg("ntlGeometryObjModel::initModel","Triangle errors occurred ("<<triangleErrs<<")!"); - } - - //fprintf(stderr,"initModel DEBUG %d \n",channelSize); - debMsgStd("ntlGeometryObjModel::initModel",DM_MSG, "Csize:"<<channelSize<<", Cvert:"<<(size_t)(channelVertices) ,10); - if(channelVertices && (channelSize>0)) { - vector<ntlSetVec3f> aniverts; - vector<ntlSetVec3f> aninorms; - vector<double> anitimes; - aniverts.clear(); - aninorms.clear(); - anitimes.clear(); - for(int frame=0; frame<channelSize; frame++) { - ntlSetVec3f averts; averts.mVerts.clear(); - ntlSetVec3f anorms; anorms.mVerts.clear(); - int setsize = (3*numVertices+1); - - ntlVec3Gfx p(0.),n(1.); - for(int i=0; i<numVertices; i++) { - for(int j=0; j<3; j++) p[j] = channelVertices[frame*setsize+ 3*i +j]; - averts.mVerts.push_back(p); - anorms.mVerts.push_back(p); - //debMsgStd("ntlGeometryObjModel::initModel",DM_MSG, "Frame:"<<frame<<",i:"<<i<<" "<<p,10); - } - if( ((int)averts.mVerts.size()==numVertices) && - ((int)anorms.mVerts.size()==numVertices) ) { - aniverts.push_back(averts); - aninorms.push_back(anorms); - double time = (double)channelVertices[frame*setsize+ setsize-1]; - anitimes.push_back(time); - } else { - errMsg("ntlGeometryObjModel::initModel","Invalid mesh, obj="<<this->getName()<<" frame="<<frame<<" verts="<<averts.mVerts.size()<<"/"<<numVertices<<". Skipping..."); - } - //debMsgStd("ntlGeometryObjModel::initModel",DM_MSG, "Frame:"<<frame<<" at t="<<time,10); - } - - mcAniVerts = AnimChannel<ntlSetVec3f>(aniverts,anitimes); - mcAniNorms = AnimChannel<ntlSetVec3f>(aninorms,anitimes); - debMsgStd("ntlGeometryObjModel::initModel",DM_MSG, "Ani sets inited: "<< mcAniVerts.accessValues().size() <<","<<mcAniNorms.accessValues().size() <<" ", 1 ); - } - if(getMeshAnimated()) { - this->mIsAnimated = true; - } - - // inited, no need to parse attribs etc. - mLoaded = 1; - return 0; -} - -/*! init triangle divisions */ -void ntlGeometryObjModel::calcTriangleDivs(vector<ntlVec3Gfx> &verts, vector<ntlTriangle> &tris, gfxReal fsTri) { - // warning - copied from geomobj calc! - errMsg("ntlGeometryObjModel","calcTriangleDivs special!"); - mTriangleDivs1.resize( tris.size() ); - mTriangleDivs2.resize( tris.size() ); - for(size_t i=0; i<tris.size(); i++) { - ntlVec3Gfx p0 = verts[ tris[i].getPoints()[0] ]; - ntlVec3Gfx p1 = verts[ tris[i].getPoints()[1] ]; - ntlVec3Gfx p2 = verts[ tris[i].getPoints()[2] ]; - ntlVec3Gfx side1 = p1 - p0; - ntlVec3Gfx side2 = p2 - p0; - ntlVec3Gfx side3 = p1 - p2; - int divs1=0, divs2=0; - if(normNoSqrt(side1) > fsTri*fsTri) { divs1 = (int)(norm(side1)/fsTri); } - if(normNoSqrt(side2) > fsTri*fsTri) { divs2 = (int)(norm(side2)/fsTri); } - - // special handling - // warning, requires objmodel triangle treatment (no verts dups) - if(getMeshAnimated()) { - vector<ntlSetVec3f> &sverts = mcAniVerts.accessValues(); - for(int s=0; s<(int)sverts.size(); s++) { - p0 = sverts[s].mVerts[ tris[i].getPoints()[0] ]; - p1 = sverts[s].mVerts[ tris[i].getPoints()[1] ]; - p2 = sverts[s].mVerts[ tris[i].getPoints()[2] ]; - side1 = p1 - p0; side2 = p2 - p0; side3 = p1 - p2; - int tdivs1=0, tdivs2=0; - if(normNoSqrt(side1) > fsTri*fsTri) { tdivs1 = (int)(norm(side1)/fsTri); } - if(normNoSqrt(side2) > fsTri*fsTri) { tdivs2 = (int)(norm(side2)/fsTri); } - if(tdivs1>divs1) divs1=tdivs1; - if(tdivs2>divs2) divs2=tdivs2; - } - } // */ - mTriangleDivs1[i] = divs1; - mTriangleDivs2[i] = divs2; - } -} - - -/****************************************************************************** - * load model from .obj file - *****************************************************************************/ - -int ntlGeometryObjModel::loadBobjModel(string filename) -{ - bool haveAniSets=false; - vector<ntlSetVec3f> aniverts; - vector<ntlSetVec3f> aninorms; - vector<double> anitimes; - - const bool debugPrint=false; - const bool debugPrintFull=false; - gzFile gzf; - gzf = gzopen(filename.c_str(), "rb"); - if (!gzf) { - errFatal("ntlGeometryObjModel::loadBobjModel","Reading GZ_BOBJ, Unable to open '"<< filename <<"'...\n", SIMWORLD_INITERROR ); - return 1; - } - - int numVerts; - if(sizeof(numVerts)!=4) { // paranoia check - errMsg("Reading GZ_BOBJ"," Invalid int size, check compiler settings: int has to be 4 byte long"); - goto gzreaderror; - } - gzread(gzf, &numVerts, sizeof(numVerts) ); - if(numVerts<0 || numVerts>1e9) { - errMsg("Reading GZ_BOBJ"," invalid num vertices "<< numVerts); - goto gzreaderror; - } - mVertices.clear(); - mVertices.resize( numVerts ); - for(int i=0; i<numVerts; i++) { - float x[3]; - for(int j=0; j<3; j++) { - gzread(gzf, &(x[j]), sizeof( (x[j]) ) ); - } - mVertices[i] = ntlVec3Gfx(x[0],x[1],x[2]); - if(debugPrintFull) errMsg("FULLV"," "<<i<<" "<< mVertices[i] ); - } - if(debugPrint) errMsg("NV"," "<<numVerts<<" "<< mVertices.size() ); - - // should be the same as Vertices.size - gzread(gzf, &numVerts, sizeof(numVerts) ); - if(numVerts<0 || numVerts>1e9) { - errMsg("Reading GZ_BOBJ","invalid num normals "<< numVerts); - goto gzreaderror; - } - mNormals.clear(); - mNormals.resize( numVerts ); - for(int i=0; i<numVerts; i++) { - float n[3]; - for(int j=0; j<3; j++) { - gzread(gzf, &(n[j]), sizeof( (n[j]) ) ); - } - mNormals[i] = ntlVec3Gfx(n[0],n[1],n[2]); - if(debugPrintFull) errMsg("FULLN"," "<<i<<" "<< mNormals[i] ); - } - if(debugPrint) errMsg("NN"," "<<numVerts<<" "<< mNormals.size() ); - - int numTris; - gzread(gzf, &numTris, sizeof(numTris) ); - if(numTris<0 || numTris>1e9) { - errMsg("Reading GZ_BOBJ","invalid num normals "<< numTris); - goto gzreaderror; - } - mTriangles.resize( 3*numTris ); - for(int i=0; i<numTris; i++) { - int tri[3]; - for(int j=0; j<3; j++) { - gzread(gzf, &(tri[j]), sizeof( (tri[j]) ) ); - } - mTriangles[3*i+0] = tri[0]; - mTriangles[3*i+1] = tri[1]; - mTriangles[3*i+2] = tri[2]; - } - if(debugPrint) errMsg("NT"," "<<numTris<<" "<< mTriangles.size() ); - - debMsgStd("ntlGeometryObjModel::loadBobjModel",DM_MSG, "File '"<<filename<<"' loaded, #Vertices: "<<mVertices.size()<<", #Normals: "<<mNormals.size()<<", #Triangles: "<<(mTriangles.size()/3)<<" ", 1 ); - - // try to load animated mesh - aniverts.clear(); - aninorms.clear(); - anitimes.clear(); - while(1) { - //ntlVec3Gfx check; - float x[3]; - float frameTime=0.; - int bytesRead = 0; - int numNorms2=-1, numVerts2=-1; - //for(int j=0; j<3; j++) { - //x[j] = 0.; - //bytesRead += gzread(gzf, &(x[j]), sizeof(float) ); - //} - //check = ntlVec3Gfx(x[0],x[1],x[2]); - //if(debugPrint) errMsg("ANI_NV1"," "<<check<<" "<<" bytes:"<<bytesRead ); - bytesRead += gzread(gzf, &frameTime, sizeof(frameTime) ); - //if(bytesRead!=3*sizeof(float)) { - if(bytesRead!=sizeof(float)) { - debMsgStd("ntlGeometryObjModel::loadBobjModel",DM_MSG, "File '"<<filename<<"' end of gzfile. ", 10 ); - if(anitimes.size()>0) { - // finally init channels and stop reading file - mcAniVerts = AnimChannel<ntlSetVec3f>(aniverts,anitimes); - mcAniNorms = AnimChannel<ntlSetVec3f>(aninorms,anitimes); - } - goto gzreaddone; - } - bytesRead += gzread(gzf, &numVerts2, sizeof(numVerts2) ); - haveAniSets=true; - // continue to read new set - vector<ntlVec3Gfx> vertset; - vector<ntlVec3Gfx> normset; - vertset.resize(numVerts); - normset.resize(numVerts); - //vertset[0] = check; - if(debugPrintFull) errMsg("FUL1V"," "<<0<<" "<< vertset[0] ); - - for(int i=0; i<numVerts; i++) { // start at one! - for(int j=0; j<3; j++) { - bytesRead += gzread(gzf, &(x[j]), sizeof( (x[j]) ) ); - } - vertset[i] = ntlVec3Gfx(x[0],x[1],x[2]); - if(debugPrintFull) errMsg("FUL2V"," "<<i<<" "<< vertset[i] ); - } - if(debugPrint) errMsg("ANI_VV"," "<<numVerts<<" "<< vertset.size()<<" bytes:"<<bytesRead ); - - bytesRead += gzread(gzf, &numNorms2, sizeof(numNorms2) ); - for(int i=0; i<numVerts; i++) { - for(int j=0; j<3; j++) { - bytesRead += gzread(gzf, &(x[j]), sizeof( (x[j]) ) ); - } - normset[i] = ntlVec3Gfx(x[0],x[1],x[2]); - if(debugPrintFull) errMsg("FUL2N"," "<<i<<" "<< normset[i] ); - } - if(debugPrint) errMsg("ANI_NV"," "<<numVerts<<","<<numVerts2<<","<<numNorms2<<","<< normset.size()<<" bytes:"<<bytesRead ); - - // set ok - if(bytesRead== (int)( (numVerts*2*3+1) *sizeof(float)+2*sizeof(int) ) ) { - if(aniverts.size()==0) { - // TODO, ignore first mesh? - double anitime = (double)(frameTime-1.); // start offset!? anitimes.size(); - // get for current frame entry - if(mcAniTimes.getSize()>1) anitime = mcAniTimes.get(anitime); - anitime = anitime*mAniTimeScale+mAniTimeOffset; - - anitimes.push_back( anitime ); - aniverts.push_back( ntlSetVec3f(mVertices) ); - aninorms.push_back( ntlSetVec3f(mNormals) ); - if(debugPrint) errMsg("ANI_NV","new set "<<mVertices.size()<<","<< mNormals.size()<<" time:"<<anitime ); - } - double anitime = (double)(frameTime); //anitimes.size(); - // get for current frame entry - if(mcAniTimes.getSize()>1) anitime = mcAniTimes.get(anitime); - anitime = anitime*mAniTimeScale+mAniTimeOffset; - - anitimes.push_back( anitime ); - aniverts.push_back( ntlSetVec3f(vertset) ); - aninorms.push_back( ntlSetVec3f(normset) ); - if(debugPrint) errMsg("ANI_NV","new set "<<vertset.size()<<","<< normset.size()<<" time:"<<anitime ); - } else { - errMsg("ntlGeometryObjModel::loadBobjModel","Malformed ani set! Aborting... ("<<bytesRead<<") "); - goto gzreaddone; - } - } // anim sets */ - -gzreaddone: - - if(haveAniSets) { - debMsgStd("ntlGeometryObjModel::loadBobjModel",DM_MSG, "File '"<<filename<<"' ani sets loaded: "<< mcAniVerts.accessValues().size() <<","<<mcAniNorms.accessValues().size() <<" ", 1 ); - } - gzclose( gzf ); - return 0; - -gzreaderror: - mTriangles.clear(); - mVertices.clear(); - mNormals.clear(); - gzclose( gzf ); - errFatal("ntlGeometryObjModel::loadBobjModel","Reading GZ_BOBJ, Unable to load '"<< filename <<"', exiting...\n", SIMWORLD_INITERROR ); - return 1; -} - - -/****************************************************************************** - * - *****************************************************************************/ -void -ntlGeometryObjModel::getTriangles(double t, vector<ntlTriangle> *triangles, - vector<ntlVec3Gfx> *vertices, - vector<ntlVec3Gfx> *normals, int objectId ) -{ - if(!mLoaded) { // invalid type... - return; - } - if(mcAniVerts.getSize()>1) { mVertices = mcAniVerts.get(t).mVerts; } - if(mcAniNorms.getSize()>1) { mNormals = mcAniNorms.get(t).mVerts; } - - int startvert = vertices->size(); - vertices->resize( vertices->size() + mVertices.size() ); - normals->resize( normals->size() + mVertices.size() ); - for(int i=0; i<(int)mVertices.size(); i++) { - (*vertices)[startvert+i] = mVertices[i]; - (*normals)[startvert+i] = mNormals[i]; - } - - triangles->reserve(triangles->size() + mTriangles.size()/3 ); - for(int i=0; i<(int)mTriangles.size(); i+=3) { - int trip[3]; - trip[0] = startvert+mTriangles[i+0]; - trip[1] = startvert+mTriangles[i+1]; - trip[2] = startvert+mTriangles[i+2]; - - //sceneAddTriangle( - //mVertices[trip[0]], mVertices[trip[1]], mVertices[trip[2]], - //mNormals[trip[0]], mNormals[trip[1]], mNormals[trip[2]], - //ntlVec3Gfx(0.0), 1 , triangles,vertices,normals ); /* normal unused */ - sceneAddTriangleNoVert( trip, ntlVec3Gfx(0.0), 1 , triangles ); /* normal unused */ - } - objectId = -1; // remove warning - // bobj - return; -} - - - - - diff --git a/intern/elbeem/intern/ntl_geometrymodel.h b/intern/elbeem/intern/ntl_geometrymodel.h deleted file mode 100644 index a5f26ba17b8..00000000000 --- a/intern/elbeem/intern/ntl_geometrymodel.h +++ /dev/null @@ -1,104 +0,0 @@ -/** \file - * \ingroup elbeem - */ -/****************************************************************************** - * - * El'Beem - Free Surface Fluid Simulation with the Lattice Boltzmann Method - * Copyright 2003-2006 Nils Thuerey - * - * A model laoded from Wavefront .obj file - * - *****************************************************************************/ -#ifndef NTL_GEOMODEL_H -#define NTL_GEOMODEL_H - -#include "ntl_geometryobject.h" - -#ifdef WITH_CXX_GUARDEDALLOC -# include "MEM_guardedalloc.h" -#endif - -/*! A simple box object generatedd by 12 triangles */ -class ntlGeometryObjModel : public ntlGeometryObject -{ - public: - /* Init constructor */ - ntlGeometryObjModel( void ); - /* Init constructor */ - //ntlGeometryObjModel( ntlVec3Gfx start, ntlVec3Gfx end ); - /* Destructor */ - virtual ~ntlGeometryObjModel( void ); - - //! Return type id - virtual int getTypeId() { return GEOCLASSTID_OBJMODEL; } - - /*! Filename setting etc. */ - virtual void initialize(ntlRenderGlobals *glob); - - /*! is the mesh animated? */ - virtual bool getMeshAnimated(); - - /* create triangles from obj */ - virtual void getTriangles(double t, vector<ntlTriangle> *triangles, - vector<ntlVec3Gfx> *vertices, - vector<ntlVec3Gfx> *normals, int objectId ); - - /*! load model from .bobj file, returns !=0 upon error */ - int loadBobjModel(string filename); - /*! init model from given vertex and triangle arrays */ - int initModel(int numVertices, float *vertices, int numTriangles, int *triangles, - int channelSize, float *channelVertices); - /*! init triangle divisions */ - virtual void calcTriangleDivs(vector<ntlVec3Gfx> &verts, vector<ntlTriangle> &tris, gfxReal fsTri); - - /*! calculate max extends of (ani) mesh */ - void getExtends(ntlVec3Gfx &start, ntlVec3Gfx &end); - - private: - - /*! Start and end points of box */ - ntlVec3Gfx mvStart, mvEnd; - - /*! was the model loaded? */ - bool mLoaded; - - /*! filename of the obj file */ - string mFilename; - - /*! for bobj models */ - vector<int> mTriangles; - vector<ntlVec3Gfx> mVertices; - vector<ntlVec3Gfx> mNormals; - - /*! animated channels for vertices, if given will override getris by default */ - AnimChannel<ntlSetVec3f> mcAniVerts; - AnimChannel<ntlSetVec3f> mcAniNorms; - /*! map entrie of anim mesh to sim times */ - AnimChannel<double> mcAniTimes; - /*! timing mapping & offset for config files */ - double mAniTimeScale, mAniTimeOffset; - - public: - - /* Access methods */ - /*! Access start vector */ - inline ntlVec3Gfx getStart( void ){ return mvStart; } - inline void setStart( const ntlVec3Gfx &set ){ mvStart = set; } - /*! Access end vector */ - inline ntlVec3Gfx getEnd( void ){ return mvEnd; } - inline void setEnd( const ntlVec3Gfx &set ){ mvEnd = set; } - - inline bool getLoaded( void ){ return mLoaded; } - inline void setLoaded( bool set ){ mLoaded = set; } - - /*! set data file name */ - inline void setFilename(string set) { mFilename = set; } - -private: -#ifdef WITH_CXX_GUARDEDALLOC - MEM_CXX_CLASS_ALLOC_FUNCS("ELBEEM:ntlGeometryObjModel") -#endif -}; - -#endif - diff --git a/intern/elbeem/intern/ntl_geometryobject.cpp b/intern/elbeem/intern/ntl_geometryobject.cpp deleted file mode 100644 index 7eb2df4ad3f..00000000000 --- a/intern/elbeem/intern/ntl_geometryobject.cpp +++ /dev/null @@ -1,806 +0,0 @@ -/** \file - * \ingroup elbeem - */ -/****************************************************************************** - * - * El'Beem - Free Surface Fluid Simulation with the Lattice Boltzmann Method - * Copyright 2003-2006 Nils Thuerey - * - * a geometry object - * all other geometry objects are derived from this one - * - *****************************************************************************/ - - -#include "ntl_geometryobject.h" -#include "ntl_world.h" -#include "ntl_matrices.h" - -// for FGI -#include "elbeem.h" - -#define TRI_UVOFFSET (1./4.) -//#define TRI_UVOFFSET (1./3.) - - -/*****************************************************************************/ -/* Default constructor */ -/*****************************************************************************/ -ntlGeometryObject::ntlGeometryObject() : - mIsInitialized(false), mpMaterial( NULL ), - mMaterialName( "default" ), - mCastShadows( 1 ), mReceiveShadows( 1 ), - mGeoInitType( 0 ), - mInitialVelocity(0.0), mcInitialVelocity(0.0), mLocalCoordInivel(false), - mGeoInitIntersect(false), - mGeoPartSlipValue(0.0), - mcGeoImpactFactor(1.), - mVolumeInit(VOLUMEINIT_VOLUME), - mInitialPos(0.), - mcTrans(0.), mcRot(0.), mcScale(1.), - mIsAnimated(false), - mMovPoints(), mMovNormals(), - mHaveCachedMov(false), - mCachedMovPoints(), mCachedMovNormals(), - mTriangleDivs1(), mTriangleDivs2(), - mMovPntsInited(-100.0), mMaxMovPnt(-1), - mcGeoActive(1.), - mCpsTimeStart(0.), mCpsTimeEnd(1.0), mCpsQuality(10.), - mcAttrFStr(0.),mcAttrFRad(0.), mcVelFStr(0.), mcVelFRad(0.) -{ -}; - - -/*****************************************************************************/ -/* Default destructor */ -/*****************************************************************************/ -ntlGeometryObject::~ntlGeometryObject() -{ -} - -/*! is the mesh animated? */ -bool ntlGeometryObject::getMeshAnimated() { - // off by default, on for e.g. ntlGeometryObjModel - return false; -} - -/*! init object anim flag */ -bool ntlGeometryObject::checkIsAnimated() { - if( (mcTrans.accessValues().size()>1) // VALIDATE - || (mcRot.accessValues().size()>1) - || (mcScale.accessValues().size()>1) - || (mcGeoActive.accessValues().size()>1) - // mcGeoImpactFactor only needed when moving - || (mcInitialVelocity.accessValues().size()>1) - ) { - mIsAnimated = true; - } - - // fluid objects always have static init! - if(mGeoInitType==FGI_FLUID) { - mIsAnimated=false; - } - //errMsg("ntlGeometryObject::checkIsAnimated","obj="<<getName()<<" debug: trans:"<<mcTrans.accessValues().size()<<" rot:"<<mcRot.accessValues().size()<<" scale:"<<mcScale.accessValues().size()<<" active:"<<mcGeoActive.accessValues().size()<<" inivel:"<<mcInitialVelocity.accessValues().size()<<". isani?"<<mIsAnimated ); // DEBUG - return mIsAnimated; -} - -/*****************************************************************************/ -/* Init attributes etc. of this object */ -/*****************************************************************************/ -#define GEOINIT_STRINGS 10 -static const char *initStringStrs[GEOINIT_STRINGS] = { - "fluid", - "bnd_no","bnd_noslip", - "bnd_free","bnd_freeslip", - "bnd_part","bnd_partslip", - "inflow", "outflow", "control", -}; -static int initStringTypes[GEOINIT_STRINGS] = { - FGI_FLUID, - FGI_BNDNO, FGI_BNDNO, - FGI_BNDFREE, FGI_BNDFREE, - FGI_BNDPART, FGI_BNDPART, - FGI_MBNDINFLOW, FGI_MBNDOUTFLOW, - FGI_CONTROL -}; -void ntlGeometryObject::initialize(ntlRenderGlobals *glob) -{ - //debugOut("ntlGeometryObject::initialize: '"<<getName()<<"' ", 10); - // initialize only once... - if(mIsInitialized) return; - - // init material, always necessary - searchMaterial( glob->getMaterials() ); - - this->mGeoInitId = mpAttrs->readInt("geoinitid", this->mGeoInitId,"ntlGeometryObject", "mGeoInitId", false); - mGeoInitIntersect = mpAttrs->readInt("geoinit_intersect", mGeoInitIntersect,"ntlGeometryObject", "mGeoInitIntersect", false); - string ginitStr = mpAttrs->readString("geoinittype", "", "ntlGeometryObject", "mGeoInitType", false); - if(this->mGeoInitId>=0) { - bool gotit = false; - for(int i=0; i<GEOINIT_STRINGS; i++) { - if(ginitStr== initStringStrs[i]) { - gotit = true; - mGeoInitType = initStringTypes[i]; - } - } - - if(!gotit) { - errFatal("ntlGeometryObject::initialize","Obj '"<<mName<<"', Unknown 'geoinittype' value: '"<< ginitStr <<"' ", SIMWORLD_INITERROR); - return; - } - } - - int geoActive = mpAttrs->readInt("geoinitactive", 1,"ntlGeometryObject", "geoActive", false); - if(!geoActive) { - // disable geo init again... - this->mGeoInitId = -1; - } - mInitialVelocity = vec2G( mpAttrs->readVec3d("initial_velocity", vec2D(mInitialVelocity),"ntlGeometryObject", "mInitialVelocity", false)); - if(getAttributeList()->exists("initial_velocity") || (!mcInitialVelocity.isInited()) ) { - mcInitialVelocity = mpAttrs->readChannelVec3f("initial_velocity"); - } - // always use channel - if(!mcInitialVelocity.isInited()) { mcInitialVelocity = AnimChannel<ntlVec3Gfx>(mInitialVelocity); } - mLocalCoordInivel = mpAttrs->readBool("geoinit_localinivel", mLocalCoordInivel,"ntlGeometryObject", "mLocalCoordInivel", false); - - mGeoPartSlipValue = mpAttrs->readFloat("geoinit_partslip", mGeoPartSlipValue,"ntlGeometryObject", "mGeoPartSlipValue", false); - bool mOnlyThinInit = false; // deprecated! - mOnlyThinInit = mpAttrs->readBool("geoinit_onlythin", mOnlyThinInit,"ntlGeometryObject", "mOnlyThinInit", false); - if(mOnlyThinInit) mVolumeInit = VOLUMEINIT_SHELL; - mVolumeInit = mpAttrs->readInt("geoinit_volumeinit", mVolumeInit,"ntlGeometryObject", "mVolumeInit", false); - if((mVolumeInit<VOLUMEINIT_VOLUME)||(mVolumeInit>VOLUMEINIT_BOTH)) mVolumeInit = VOLUMEINIT_VOLUME; - - // moving obs correction factor - float impactfactor=1.; - impactfactor = (float)mpAttrs->readFloat("impactfactor", impactfactor,"ntlGeometryObject", "impactfactor", false); - if(getAttributeList()->exists("impactfactor") || (!mcGeoImpactFactor.isInited()) ) { - mcGeoImpactFactor = mpAttrs->readChannelSinglePrecFloat("impactfactor"); - } - - // override cfg types - mVisible = mpAttrs->readBool("visible", mVisible,"ntlGeometryObject", "mVisible", false); - mReceiveShadows = mpAttrs->readBool("recv_shad", mReceiveShadows,"ntlGeometryObject", "mReceiveShadows", false); - mCastShadows = mpAttrs->readBool("cast_shad", mCastShadows,"ntlGeometryObject", "mCastShadows", false); - - // read mesh animation channels - ntlVec3d translation(0.0); - translation = mpAttrs->readVec3d("translation", translation,"ntlGeometryObject", "translation", false); - if(getAttributeList()->exists("translation") || (!mcTrans.isInited()) ) { - mcTrans = mpAttrs->readChannelVec3f("translation"); - } - ntlVec3d rotation(0.0); - rotation = mpAttrs->readVec3d("rotation", rotation,"ntlGeometryObject", "rotation", false); - if(getAttributeList()->exists("rotation") || (!mcRot.isInited()) ) { - mcRot = mpAttrs->readChannelVec3f("rotation"); - } - ntlVec3d scale(1.0); - scale = mpAttrs->readVec3d("scale", scale,"ntlGeometryObject", "scale", false); - if(getAttributeList()->exists("scale") || (!mcScale.isInited()) ) { - mcScale = mpAttrs->readChannelVec3f("scale"); - } - - float geoactive=1.; - geoactive = (float)mpAttrs->readFloat("geoactive", geoactive,"ntlGeometryObject", "geoactive", false); - if(getAttributeList()->exists("geoactive") || (!mcGeoActive.isInited()) ) { - mcGeoActive = mpAttrs->readChannelSinglePrecFloat("geoactive"); - } - // always use channel - if(!mcGeoActive.isInited()) { mcGeoActive = AnimChannel<float>(geoactive); } - - checkIsAnimated(); - - mIsInitialized = true; - debMsgStd("ntlGeometryObject::initialize",DM_MSG,"GeoObj '"<<this->getName()<<"': visible="<<this->mVisible<<" gid="<<this->mGeoInitId<<" gtype="<<mGeoInitType<<","<<ginitStr<< - " gvel="<<mInitialVelocity<<" gisect="<<mGeoInitIntersect, 10); // debug -} - -/*! notify object that dump is in progress (e.g. for particles) */ -// default action - do nothing... -void ntlGeometryObject::notifyOfDump(int dumtp, int frameNr,char *frameNrStr,string outfilename, double simtime) { - bool debugOut=false; - if(debugOut) debMsgStd("ntlGeometryObject::notifyOfDump",DM_MSG," dt:"<<dumtp<<" obj:"<<this->getName()<<" frame:"<<frameNrStr<<","<<frameNr<<",t"<<simtime<<" to "<<outfilename, 10); // DEBUG -} - -/*****************************************************************************/ -/* Search the material for this object from the material list */ -/*****************************************************************************/ -void ntlGeometryObject::searchMaterial(vector<ntlMaterial *> *mat) -{ - /* search the list... */ - int i=0; - for (vector<ntlMaterial*>::iterator iter = mat->begin(); - iter != mat->end(); iter++) { - if( mMaterialName == (*iter)->getName() ) { - //warnMsg("ntlGeometryObject::searchMaterial","for obj '"<<getName()<<"' found - '"<<(*iter)->getName()<<"' "<<i); // DEBUG - mpMaterial = (*iter); - return; - } - i++; - } - errFatal("ntlGeometryObject::searchMaterial","Unknown material '"<<mMaterialName<<"' ! ", SIMWORLD_INITERROR); - mpMaterial = new ntlMaterial(); - return; -} - -/****************************************************************************** - * static add triangle function - *****************************************************************************/ -void ntlGeometryObject::sceneAddTriangle( - ntlVec3Gfx p1,ntlVec3Gfx p2,ntlVec3Gfx p3, - ntlVec3Gfx pn1,ntlVec3Gfx pn2,ntlVec3Gfx pn3, - ntlVec3Gfx trin, bool smooth, - vector<ntlTriangle> *triangles, - vector<ntlVec3Gfx> *vertices, - vector<ntlVec3Gfx> *normals) { - ntlTriangle tri; - int tempVert; - - if(normals->size() != vertices->size()) { - errFatal("ntlGeometryObject::sceneAddTriangle","For '"<<this->mName<<"': Vertices and normals sizes to not match!!!",SIMWORLD_GENERICERROR); - - } else { - - vertices->push_back( p1 ); - normals->push_back( pn1 ); - tempVert = normals->size()-1; - tri.getPoints()[0] = tempVert; - - vertices->push_back( p2 ); - normals->push_back( pn2 ); - tempVert = normals->size()-1; - tri.getPoints()[1] = tempVert; - - vertices->push_back( p3 ); - normals->push_back( pn3 ); - tempVert = normals->size()-1; - tri.getPoints()[2] = tempVert; - - - /* init flags from ntl_ray.h */ - int flag = 0; - if(getVisible()){ flag |= TRI_GEOMETRY; } - if(getCastShadows() ) { - flag |= TRI_CASTSHADOWS; } - - /* init geo init id */ - int geoiId = getGeoInitId(); - //if((geoiId > 0) && (mVolumeInit&VOLUMEINIT_VOLUME) && (!mIsAnimated)) { - if((geoiId > 0) && (mVolumeInit&VOLUMEINIT_VOLUME)) { - flag |= (1<< (geoiId+4)); - flag |= mGeoInitType; - } - /*errMsg("ntlScene::addTriangle","DEBUG flag="<<convertFlags2String(flag) ); */ - tri.setFlags( flag ); - - /* triangle normal missing */ - tri.setNormal( trin ); - tri.setSmoothNormals( smooth ); - tri.setObjectId( this->mObjectId ); - triangles->push_back( tri ); - } /* normals check*/ -} - -void ntlGeometryObject::sceneAddTriangleNoVert(int *trips, - ntlVec3Gfx trin, bool smooth, - vector<ntlTriangle> *triangles) { - ntlTriangle tri; - - tri.getPoints()[0] = trips[0]; - tri.getPoints()[1] = trips[1]; - tri.getPoints()[2] = trips[2]; - - // same as normal sceneAddTriangle - - /* init flags from ntl_ray.h */ - int flag = 0; - if(getVisible()){ flag |= TRI_GEOMETRY; } - if(getCastShadows() ) { - flag |= TRI_CASTSHADOWS; } - - /* init geo init id */ - int geoiId = getGeoInitId(); - if((geoiId > 0) && (mVolumeInit&VOLUMEINIT_VOLUME)) { - flag |= (1<< (geoiId+4)); - flag |= mGeoInitType; - } - /*errMsg("ntlScene::addTriangle","DEBUG flag="<<convertFlags2String(flag) ); */ - tri.setFlags( flag ); - - /* triangle normal missing */ - tri.setNormal( trin ); - tri.setSmoothNormals( smooth ); - tri.setObjectId( this->mObjectId ); - triangles->push_back( tri ); -} - - -/******************************************************************************/ -/* Init channels from float arrays (for elbeem API) */ -/******************************************************************************/ - -#define ADD_CHANNEL_VEC(dst,nvals,val) \ - vals.clear(); time.clear(); elbeemSimplifyChannelVec3(val,&nvals); \ - for(int i=0; i<(nvals); i++) { \ - vals.push_back(ntlVec3Gfx((val)[i*4+0], (val)[i*4+1],(val)[i*4+2] )); \ - time.push_back( (val)[i*4+3] ); \ - } \ - (dst) = AnimChannel< ntlVec3Gfx >(vals,time); - -#define ADD_CHANNEL_FLOAT(dst,nvals,val) \ - valsfloat.clear(); time.clear(); elbeemSimplifyChannelFloat(val,&nvals); \ - for(int i=0; i<(nvals); i++) { \ - valsfloat.push_back( (val)[i*2+0] ); \ - time.push_back( (val)[i*2+1] ); \ - } \ - (dst) = AnimChannel< float >(valsfloat,time); - -void ntlGeometryObject::initChannels( - int nTrans, float *trans, int nRot, float *rot, int nScale, float *scale, - int nAct, float *act, int nIvel, float *ivel, - int nAttrFStr, float *attrFStr, - int nAttrFRad, float *attrFRad, - int nVelFStr, float *velFStr, - int nVelFRad, float *velFRad - ) { - const bool debugInitc=true; - if(debugInitc) { debMsgStd("ntlGeometryObject::initChannels",DM_MSG,"nt:"<<nTrans<<" nr:"<<nRot<<" ns:"<<nScale, 10); - debMsgStd("ntlGeometryObject::initChannels",DM_MSG,"na:"<<nAct<<" niv:"<<nIvel<<" ", 10); } - vector<ntlVec3Gfx> vals; - vector<float> valsfloat; - vector<double> time; - if((trans)&&(nTrans>0)) { ADD_CHANNEL_VEC(mcTrans, nTrans, trans); } - if((rot)&&(nRot>0)) { ADD_CHANNEL_VEC(mcRot, nRot, rot); } - if((scale)&&(nScale>0)) { ADD_CHANNEL_VEC(mcScale, nScale, scale); } - if((act)&&(nAct>0)) { ADD_CHANNEL_FLOAT(mcGeoActive, nAct, act); } - if((ivel)&&(nIvel>0)) { ADD_CHANNEL_VEC(mcInitialVelocity, nIvel, ivel); } - - /* fluid control channels */ - if((attrFStr)&&(nAttrFStr>0)) { ADD_CHANNEL_FLOAT(mcAttrFStr, nAttrFStr, attrFStr); } - if((attrFRad)&&(nAttrFRad>0)) { ADD_CHANNEL_FLOAT(mcAttrFRad, nAttrFRad, attrFRad); } - if((velFStr)&&(nVelFStr>0)) { ADD_CHANNEL_FLOAT(mcVelFStr, nAct, velFStr); } - if((velFRad)&&(nVelFRad>0)) { ADD_CHANNEL_FLOAT(mcVelFRad, nVelFRad, velFRad); } - - checkIsAnimated(); - - if(debugInitc) { - debMsgStd("ntlGeometryObject::initChannels",DM_MSG,getName()<< - " nt:"<<mcTrans.accessValues().size()<<" nr:"<<mcRot.accessValues().size()<< - " ns:"<<mcScale.accessValues().size()<<" isAnim:"<<mIsAnimated, 10); } - - if(debugInitc) { - std::ostringstream ostr; - ostr << "trans: "; - for(size_t i=0; i<mcTrans.accessValues().size(); i++) { - ostr<<" "<<mcTrans.accessValues()[i]<<"@"<<mcTrans.accessTimes()[i]<<" "; - } ostr<<"; "; - ostr<<"rot: "; - for(size_t i=0; i<mcRot.accessValues().size(); i++) { - ostr<<" "<<mcRot.accessValues()[i]<<"@"<<mcRot.accessTimes()[i]<<" "; - } ostr<<"; "; - ostr<<"scale: "; - for(size_t i=0; i<mcScale.accessValues().size(); i++) { - ostr<<" "<<mcScale.accessValues()[i]<<"@"<<mcScale.accessTimes()[i]<<" "; - } ostr<<"; "; - ostr<<"act: "; - for(size_t i=0; i<mcGeoActive.accessValues().size(); i++) { - ostr<<" "<<mcGeoActive.accessValues()[i]<<"@"<<mcGeoActive.accessTimes()[i]<<" "; - } ostr<<"; "; - ostr<<"ivel: "; - for(size_t i=0; i<mcInitialVelocity.accessValues().size(); i++) { - ostr<<" "<<mcInitialVelocity.accessValues()[i]<<"@"<<mcInitialVelocity.accessTimes()[i]<<" "; - } ostr<<"; "; - debMsgStd("ntlGeometryObject::initChannels",DM_MSG,"Inited "<<ostr.str(),10); - } -} -#undef ADD_CHANNEL - - -/*****************************************************************************/ -/* apply object translation at time t*/ -/*****************************************************************************/ -void ntlGeometryObject::applyTransformation(double t, vector<ntlVec3Gfx> *verts, vector<ntlVec3Gfx> *norms, int vstart, int vend, int forceTrafo) { - if( (mcTrans.accessValues().size()>1) // VALIDATE - || (mcRot.accessValues().size()>1) - || (mcScale.accessValues().size()>1) - || (forceTrafo) - || (!mHaveCachedMov) - ) { - // transformation is animated, continue - ntlVec3Gfx pos = getTranslation(t); - ntlVec3Gfx scale = mcScale.get(t); - ntlVec3Gfx rot = mcRot.get(t); - ntlMat4Gfx rotMat; - rotMat.initRotationXYZ(rot[0],rot[1],rot[2]); - pos += mInitialPos; - errMsg("ntlGeometryObject::applyTransformation","obj="<<getName()<<" t"<<pos<<" r"<<rot<<" s"<<scale); - for(int i=vstart; i<vend; i++) { - (*verts)[i] *= scale; - (*verts)[i] = rotMat * (*verts)[i]; - (*verts)[i] += pos; - //if(i<10) errMsg("ntlGeometryObject::applyTransformation"," v"<<i<<"/"<<vend<<"="<<(*verts)[i]); - } - if(norms) { - for(int i=vstart; i<vend; i++) { - (*norms)[i] = rotMat * (*norms)[i]; - } - } - } else { - // not animated, cached points were already returned - errMsg ("ntlGeometryObject::applyTransformation","Object "<<getName()<<" used cached points "); - } -} - -/*! init triangle divisions */ -void ntlGeometryObject::calcTriangleDivs(vector<ntlVec3Gfx> &verts, vector<ntlTriangle> &tris, gfxReal fsTri) { - mTriangleDivs1.resize( tris.size() ); - mTriangleDivs2.resize( tris.size() ); - - //fsTri *= 2.; // DEBUG! , wrong init! - - for(size_t i=0; i<tris.size(); i++) { - const ntlVec3Gfx p0 = verts[ tris[i].getPoints()[0] ]; - const ntlVec3Gfx p1 = verts[ tris[i].getPoints()[1] ]; - const ntlVec3Gfx p2 = verts[ tris[i].getPoints()[2] ]; - const ntlVec3Gfx side1 = p1 - p0; - const ntlVec3Gfx side2 = p2 - p0; - int divs1=0, divs2=0; - if(normNoSqrt(side1) > fsTri*fsTri) { divs1 = (int)(norm(side1)/fsTri); } - if(normNoSqrt(side2) > fsTri*fsTri) { divs2 = (int)(norm(side2)/fsTri); } - - mTriangleDivs1[i] = divs1; - mTriangleDivs2[i] = divs2; - } -} - -/*! Prepare points for moving objects */ -void ntlGeometryObject::initMovingPoints(double time, gfxReal featureSize) { - if((mMovPntsInited==featureSize)&&(!getMeshAnimated())) return; - const bool debugMoinit=false; - - vector<ntlTriangle> triangles; - vector<ntlVec3Gfx> vertices; - vector<ntlVec3Gfx> vnormals; - int objectId = 1; - this->getTriangles(time, &triangles,&vertices,&vnormals,objectId); - - mMovPoints.clear(); - mMovNormals.clear(); - if(debugMoinit) errMsg("ntlGeometryObject::initMovingPoints","Object "<<getName()<<" has v:"<<vertices.size()<<" t:"<<triangles.size() ); - // no points? - if(vertices.size()<1) { - mMaxMovPnt=-1; - return; - } - ntlVec3f maxscale = channelFindMaxVf(mcScale); - float maxpart = ABS(maxscale[0]); - if(ABS(maxscale[1])>maxpart) maxpart = ABS(maxscale[1]); - if(ABS(maxscale[2])>maxpart) maxpart = ABS(maxscale[2]); - float scaleFac = 1.0/(maxpart); - // TODO - better reinit from time to time? - const gfxReal fsTri = featureSize*0.5 *scaleFac; - if(debugMoinit) errMsg("ntlGeometryObject::initMovingPoints","maxscale:"<<maxpart<<" featureSize:"<<featureSize<<" fsTri:"<<fsTri ); - - if(mTriangleDivs1.size()!=triangles.size()) { - calcTriangleDivs(vertices,triangles,fsTri); - } - - // debug: count points to init - /*if(debugMoinit) { - errMsg("ntlGeometryObject::initMovingPoints","Object "<<getName()<<" estimating..."); - int countp=vertices.size()*2; - for(size_t i=0; i<triangles.size(); i++) { - ntlVec3Gfx p0 = vertices[ triangles[i].getPoints()[0] ]; - ntlVec3Gfx side1 = vertices[ triangles[i].getPoints()[1] ] - p0; - ntlVec3Gfx side2 = vertices[ triangles[i].getPoints()[2] ] - p0; - int divs1=0, divs2=0; - if(normNoSqrt(side1) > fsTri*fsTri) { divs1 = (int)(norm(side1)/fsTri); } - if(normNoSqrt(side2) > fsTri*fsTri) { divs2 = (int)(norm(side2)/fsTri); } - errMsg("ntlGeometryObject::initMovingPoints","tri:"<<i<<" p:"<<p0<<" s1:"<<side1<<" s2:"<<side2<<" -> "<<divs1<<","<<divs2 ); - if(divs1+divs2 > 0) { - for(int u=0; u<=divs1; u++) { - for(int v=0; v<=divs2; v++) { - const gfxReal uf = (gfxReal)(u+TRI_UVOFFSET) / (gfxReal)(divs1+0.0); - const gfxReal vf = (gfxReal)(v+TRI_UVOFFSET) / (gfxReal)(divs2+0.0); - if(uf+vf>1.0) continue; - countp+=2; - } - } - } - } - errMsg("ntlGeometryObject::initMovingPoints","Object "<<getName()<<" requires:"<<countp*2); - } // */ - - bool discardInflowBack = false; - if( (mGeoInitType==FGI_MBNDINFLOW) && (mcInitialVelocity.accessValues().size()<1) ) discardInflowBack = true; - discardInflowBack = false; // DEBUG disable for now - - - // init std points - for(size_t i=0; i<vertices.size(); i++) { - ntlVec3Gfx p = vertices[ i ]; - ntlVec3Gfx n = vnormals[ i ]; - // discard inflow backsides - //if( (mGeoInitType==FGI_MBNDINFLOW) && (!mIsAnimated)) { - if(discardInflowBack) { //if( (mGeoInitType==FGI_MBNDINFLOW) && (!mIsAnimated)) { - if(dot(mInitialVelocity,n)<0.0) continue; - } - mMovPoints.push_back(p); - mMovNormals.push_back(n); - if(debugMoinit) errMsg("ntlGeometryObject::initMovingPoints","std"<<i<<" p"<<p<<" n"<<n<<" "); - } - // init points & refine... - for(size_t i=0; i<triangles.size(); i++) { - int *trips = triangles[i].getPoints(); - const ntlVec3Gfx p0 = vertices[ trips[0] ]; - const ntlVec3Gfx side1 = vertices[ trips[1] ] - p0; - const ntlVec3Gfx side2 = vertices[ trips[2] ] - p0; - int divs1=mTriangleDivs1[i], divs2=mTriangleDivs2[i]; - - const ntlVec3Gfx trinormOrg = getNormalized(cross(side1,side2)); - const ntlVec3Gfx trinorm = trinormOrg*0.25*featureSize; - if(discardInflowBack) { - if(dot(mInitialVelocity,trinorm)<0.0) continue; - } - if(debugMoinit) errMsg("ntlGeometryObject::initMovingPoints","Tri1 "<<vertices[trips[0]]<<","<<vertices[trips[1]]<<","<<vertices[trips[2]]<<" "<<divs1<<","<<divs2 ); - if(divs1+divs2 > 0) { - for(int u=0; u<=divs1; u++) { - for(int v=0; v<=divs2; v++) { - const gfxReal uf = (gfxReal)(u+TRI_UVOFFSET) / (gfxReal)(divs1+0.0); - const gfxReal vf = (gfxReal)(v+TRI_UVOFFSET) / (gfxReal)(divs2+0.0); - if(uf+vf>1.0) continue; - ntlVec3Gfx p = - vertices[ trips[0] ] * (1.0-uf-vf)+ - vertices[ trips[1] ] * uf + - vertices[ trips[2] ] * vf; - //ntlVec3Gfx n = vnormals[ - //trips[0] ] * (1.0-uf-vf)+ - //vnormals[ trips[1] ]*uf + - //vnormals[ trips[2] ]*vf; - //normalize(n); - // discard inflow backsides - - mMovPoints.push_back(p + trinorm); // NEW!? - mMovPoints.push_back(p - trinorm); - mMovNormals.push_back(trinormOrg); - mMovNormals.push_back(trinormOrg); - //errMsg("TRINORM","p"<<p<<" n"<<n<<" trin"<<trinorm); - } - } - } - } - - // find max point - mMaxMovPnt = 0; - gfxReal dist = normNoSqrt(mMovPoints[0]); - for(size_t i=0; i<mMovPoints.size(); i++) { - if(normNoSqrt(mMovPoints[i])>dist) { - mMaxMovPnt = i; - dist = normNoSqrt(mMovPoints[0]); - } - } - - if( (this->getMeshAnimated()) - || (mcTrans.accessValues().size()>1) // VALIDATE - || (mcRot.accessValues().size()>1) - || (mcScale.accessValues().size()>1) - ) { - // also do trafo... - } else { - mCachedMovPoints = mMovPoints; - mCachedMovNormals = mMovNormals; - //applyTransformation(time, &mCachedMovPoints, &mCachedMovNormals, 0, mCachedMovPoints.size(), true); - applyTransformation(time, &mCachedMovPoints, NULL, 0, mCachedMovPoints.size(), true); - mHaveCachedMov = true; - debMsgStd("ntlGeometryObject::initMovingPoints",DM_MSG,"Object "<<getName()<<" cached points ", 7); - } - - mMovPntsInited = featureSize; - debMsgStd("ntlGeometryObject::initMovingPoints",DM_MSG,"Object "<<getName()<<" inited v:"<<vertices.size()<<"->"<<mMovPoints.size() , 5); -} -/*! Prepare points for animated objects, - * init both sets, never used cached points - * discardInflowBack ignore */ -void ntlGeometryObject::initMovingPointsAnim( - double srctime, vector<ntlVec3Gfx> &srcmovPoints, - double dsttime, vector<ntlVec3Gfx> &dstmovPoints, - vector<ntlVec3Gfx> *dstmovNormals, - gfxReal featureSize, - ntlVec3Gfx geostart, ntlVec3Gfx geoend - ) { - const bool debugMoinit=false; - - vector<ntlTriangle> srctriangles; - vector<ntlVec3Gfx> srcvertices; - vector<ntlVec3Gfx> unused_normals; - vector<ntlTriangle> dsttriangles; - vector<ntlVec3Gfx> dstvertices; - vector<ntlVec3Gfx> dstnormals; - int objectId = 1; - // TODO optimize? , get rid of normals? - unused_normals.clear(); - this->getTriangles(srctime, &srctriangles,&srcvertices,&unused_normals,objectId); - unused_normals.clear(); - this->getTriangles(dsttime, &dsttriangles,&dstvertices,&dstnormals,objectId); - - srcmovPoints.clear(); - dstmovPoints.clear(); - if(debugMoinit) errMsg("ntlGeometryObject::initMovingPointsAnim","Object "<<getName()<<" has srcv:"<<srcvertices.size()<<" srct:"<<srctriangles.size() ); - if(debugMoinit) errMsg("ntlGeometryObject::initMovingPointsAnim","Object "<<getName()<<" has dstv:"<<dstvertices.size()<<" dstt:"<<dsttriangles.size() ); - // no points? - if(srcvertices.size()<1) { - mMaxMovPnt=-1; - return; - } - if((srctriangles.size() != dsttriangles.size()) || - (srcvertices.size() != dstvertices.size()) ) { - errMsg("ntlGeometryObject::initMovingPointsAnim","Invalid triangle numbers! Aborting..."); - return; - } - ntlVec3f maxscale = channelFindMaxVf(mcScale); - float maxpart = ABS(maxscale[0]); - if(ABS(maxscale[1])>maxpart) maxpart = ABS(maxscale[1]); - if(ABS(maxscale[2])>maxpart) maxpart = ABS(maxscale[2]); - float scaleFac = 1.0/(maxpart); - // TODO - better reinit from time to time? - const gfxReal fsTri = featureSize*0.5 *scaleFac; - if(debugMoinit) errMsg("ntlGeometryObject::initMovingPointsAnim","maxscale:"<<maxpart<<" featureSize:"<<featureSize<<" fsTri:"<<fsTri ); - - if(mTriangleDivs1.size()!=srctriangles.size()) { - calcTriangleDivs(srcvertices,srctriangles,fsTri); - } - - - // init std points - for(size_t i=0; i<srcvertices.size(); i++) { - srcmovPoints.push_back(srcvertices[i]); - //srcmovNormals.push_back(srcnormals[i]); - } - for(size_t i=0; i<dstvertices.size(); i++) { - dstmovPoints.push_back(dstvertices[i]); - if(dstmovNormals) (*dstmovNormals).push_back(dstnormals[i]); - } - if(debugMoinit) errMsg("ntlGeometryObject::initMovingPointsAnim","stats src:"<<srcmovPoints.size()<<" dst:"<<dstmovPoints.size()<<" " ); - // init points & refine... - for(size_t i=0; i<srctriangles.size(); i++) { - const int divs1=mTriangleDivs1[i]; - const int divs2=mTriangleDivs2[i]; - if(divs1+divs2 > 0) { - int *srctrips = srctriangles[i].getPoints(); - int *dsttrips = dsttriangles[i].getPoints(); - const ntlVec3Gfx srcp0 = srcvertices[ srctrips[0] ]; - const ntlVec3Gfx srcside1 = srcvertices[ srctrips[1] ] - srcp0; - const ntlVec3Gfx srcside2 = srcvertices[ srctrips[2] ] - srcp0; - const ntlVec3Gfx dstp0 = dstvertices[ dsttrips[0] ]; - const ntlVec3Gfx dstside1 = dstvertices[ dsttrips[1] ] - dstp0; - const ntlVec3Gfx dstside2 = dstvertices[ dsttrips[2] ] - dstp0; - const ntlVec3Gfx src_trinorm = getNormalized(cross(srcside1,srcside2))*0.25*featureSize; - const ntlVec3Gfx dst_trinormOrg = getNormalized(cross(dstside1,dstside2)); - const ntlVec3Gfx dst_trinorm = dst_trinormOrg *0.25*featureSize; - //errMsg("ntlGeometryObject::initMovingPointsAnim","Tri1 "<<srcvertices[srctrips[0]]<<","<<srcvertices[srctrips[1]]<<","<<srcvertices[srctrips[2]]<<" "<<divs1<<","<<divs2 ); - for(int u=0; u<=divs1; u++) { - for(int v=0; v<=divs2; v++) { - const gfxReal uf = (gfxReal)(u+TRI_UVOFFSET) / (gfxReal)(divs1+0.0); - const gfxReal vf = (gfxReal)(v+TRI_UVOFFSET) / (gfxReal)(divs2+0.0); - if(uf+vf>1.0) continue; - ntlVec3Gfx srcp = - srcvertices[ srctrips[0] ] * (1.0-uf-vf)+ - srcvertices[ srctrips[1] ] * uf + - srcvertices[ srctrips[2] ] * vf; - ntlVec3Gfx dstp = - dstvertices[ dsttrips[0] ] * (1.0-uf-vf)+ - dstvertices[ dsttrips[1] ] * uf + - dstvertices[ dsttrips[2] ] * vf; - - // cutoffDomain - if((srcp[0]<geostart[0]) && (dstp[0]<geostart[0])) continue; - if((srcp[1]<geostart[1]) && (dstp[1]<geostart[1])) continue; - if((srcp[2]<geostart[2]) && (dstp[2]<geostart[2])) continue; - if((srcp[0]>geoend[0] ) && (dstp[0]>geoend[0] )) continue; - if((srcp[1]>geoend[1] ) && (dstp[1]>geoend[1] )) continue; - if((srcp[2]>geoend[2] ) && (dstp[2]>geoend[2] )) continue; - - srcmovPoints.push_back(srcp+src_trinorm); // SURFENHTEST - srcmovPoints.push_back(srcp-src_trinorm); - - dstmovPoints.push_back(dstp+dst_trinorm); // SURFENHTEST - dstmovPoints.push_back(dstp-dst_trinorm); - if(dstmovNormals) { - (*dstmovNormals).push_back(dst_trinormOrg); - (*dstmovNormals).push_back(dst_trinormOrg); } - } - } - } - } - - // find max point not necessary - debMsgStd("ntlGeometryObject::initMovingPointsAnim",DM_MSG,"Object "<<getName()<<" inited v:"<<srcvertices.size()<<"->"<<srcmovPoints.size()<<","<<dstmovPoints.size() , 5); -} - -/*! Prepare points for moving objects */ -void ntlGeometryObject::getMovingPoints(vector<ntlVec3Gfx> &ret, vector<ntlVec3Gfx> *norms) { - if(mHaveCachedMov) { - ret = mCachedMovPoints; - if(norms) { - *norms = mCachedMovNormals; - //errMsg("ntlGeometryObject","getMovingPoints - Normals currently unused!"); - } - //errMsg ("ntlGeometryObject::getMovingPoints","Object "<<getName()<<" used cached points "); // DEBUG - return; - } - - ret = mMovPoints; - if(norms) { - //errMsg("ntlGeometryObject","getMovingPoints - Normals currently unused!"); - *norms = mMovNormals; - } -} - - -/*! Calculate max. velocity on object from t1 to t2 */ -ntlVec3Gfx ntlGeometryObject::calculateMaxVel(double t1, double t2) { - ntlVec3Gfx vel(0.); - if(mMaxMovPnt<0) return vel; - - vector<ntlVec3Gfx> verts1,verts2; - verts1.push_back(mMovPoints[mMaxMovPnt]); - verts2 = verts1; - applyTransformation(t1,&verts1,NULL, 0,verts1.size(), true); - applyTransformation(t2,&verts2,NULL, 0,verts2.size(), true); - - vel = (verts2[0]-verts1[0]); // /(t2-t1); - //errMsg("ntlGeometryObject::calculateMaxVel","t1="<<t1<<" t2="<<t2<<" p1="<<verts1[0]<<" p2="<<verts2[0]<<" v="<<vel); - return vel; -} - -/*! get translation at time t*/ -ntlVec3Gfx ntlGeometryObject::getTranslation(double t) { - ntlVec3Gfx pos = mcTrans.get(t); - // DEBUG CP_FORCECIRCLEINIT 1 - /*if( - (mName.compare(string("0__ts1"))==0) || - (mName.compare(string("1__ts1"))==0) || - (mName.compare(string("2__ts1"))==0) || - (mName.compare(string("3__ts1"))==0) || - (mName.compare(string("4__ts1"))==0) || - (mName.compare(string("5__ts1"))==0) || - (mName.compare(string("6__ts1"))==0) || - (mName.compare(string("7__ts1"))==0) || - (mName.compare(string("8__ts1"))==0) || - (mName.compare(string("9__ts1"))==0) - ) { int j=mName[0]-'0'; - ntlVec3Gfx ppos(0.); { // DEBUG - const float tscale=10.; - const float tprevo = 0.33; - const ntlVec3Gfx toff(50,50,0); - const ntlVec3Gfx oscale(30,30,0); - ppos[0] = cos(tscale* t - tprevo*(float)j + M_PI -0.1) * oscale[0] + toff[0]; - ppos[1] = -sin(tscale* t - tprevo*(float)j + M_PI -0.1) * oscale[1] + toff[1]; - ppos[2] = toff[2]; } // DEBUG - pos = ppos; - pos[2] = 0.15; - } - // DEBUG CP_FORCECIRCLEINIT 1 */ - return pos; -} -/*! get active flag time t*/ -float ntlGeometryObject::getGeoActive(double t) { - float act = (mcGeoActive.get(t) >= 1.) ? 1.0 : 0.0; - return act; -} - -void ntlGeometryObject::setInitialVelocity(ntlVec3Gfx set) { - mInitialVelocity=set; - mcInitialVelocity = AnimChannel<ntlVec3Gfx>(set); -} -ntlVec3Gfx ntlGeometryObject::getInitialVelocity(double t) { - ntlVec3Gfx v = mcInitialVelocity.get(t); //return mInitialVelocity; - if(!mLocalCoordInivel) return v; - - ntlVec3Gfx rot = mcRot.get(t); - ntlMat4Gfx rotMat; - rotMat.initRotationXYZ(rot[0],rot[1],rot[2]); - v = rotMat * v; - return v; -} - - diff --git a/intern/elbeem/intern/ntl_geometryobject.h b/intern/elbeem/intern/ntl_geometryobject.h deleted file mode 100644 index 7e5e90d6493..00000000000 --- a/intern/elbeem/intern/ntl_geometryobject.h +++ /dev/null @@ -1,255 +0,0 @@ -/** \file - * \ingroup elbeem - */ -/****************************************************************************** - * - * El'Beem - Free Surface Fluid Simulation with the Lattice Boltzmann Method - * Copyright 2003-2006 Nils Thuerey - * - * a geometry object - * all other geometry objects are derived from this one - * - *****************************************************************************/ -#ifndef NTL_GEOMETRYOBJECT_H -#define NTL_GEOMETRYOBJECT_H - -#include "ntl_geometryclass.h" -#include "ntl_lighting.h" -#include "ntl_ray.h" - -#ifdef WITH_CXX_GUARDEDALLOC -# include "MEM_guardedalloc.h" -#endif - -class ntlRenderGlobals; -class ntlTriangle; - -#define DUMP_FULLGEOMETRY 1 -#define DUMP_PARTIAL 2 - -#define VOLUMEINIT_VOLUME 1 -#define VOLUMEINIT_SHELL 2 -#define VOLUMEINIT_BOTH (VOLUMEINIT_SHELL|VOLUMEINIT_VOLUME) - -class ntlGeometryObject : public ntlGeometryClass -{ - - public: - //! Default constructor - ntlGeometryObject(); - //! Default destructor - virtual ~ntlGeometryObject(); - - //! Return type id - virtual int getTypeId() { return GEOCLASSTID_OBJECT; } - - /*! Init attributes etc. of this object */ - virtual void initialize(ntlRenderGlobals *glob); - - /*! Get the triangles from this object */ - virtual void getTriangles(double t, vector<ntlTriangle> *triangles, - vector<ntlVec3Gfx> *vertices, - vector<ntlVec3Gfx> *normals, int objectId ) = 0; - - /*! notify object that dump is in progress (e.g. for particles) */ - virtual void notifyOfDump(int dumptype, int frameNr,char *frameNrStr,string outfilename, double simtime); - - /*! Search the material for this object from the material list */ - void searchMaterial(vector<ntlMaterial *> *mat); - - /* Acces methods */ - /*! Set the property of this object */ - inline void setMaterial(ntlMaterial *p) { mpMaterial = p; } - /*! Get the surface property of this object */ - inline ntlMaterial *getMaterial( void ) { return mpMaterial; } - /*! Set the object property name */ - inline void setMaterialName(string set) { mMaterialName = set; } - /*! Get the object property name */ - inline string getMaterialName( void ) { return mMaterialName; } - - /*! Sets the receive shadows attribute */ - inline void setReceiveShadows(int set) { mReceiveShadows=set; } - /*! Returns the receive shadows attribute */ - inline int getReceiveShadows() const { return mReceiveShadows; } - - /*! Sets the cast shadows attribute */ - inline void setCastShadows(int set) { mCastShadows=set; } - /*! Returns the cast shadows attribute */ - inline int getCastShadows() const { return mCastShadows; } - - /*! Returns the geo init typ */ - inline void setGeoInitType(int set) { mGeoInitType=set; } - /*! Returns the geo init typ */ - inline int getGeoInitType() const { return mGeoInitType; } - - /*! Set/get the intersect init flag */ - inline bool getGeoInitIntersect() const { return mGeoInitIntersect; } - inline void setGeoInitIntersect(bool set) { mGeoInitIntersect=set; } - - /*! Set/get the part slip value*/ - inline float getGeoPartSlipValue() const { return mGeoPartSlipValue; } - inline void setGeoPartSlipValue(float set) { mGeoPartSlipValue=set; } - - /*! Set/get the impact corr factor channel */ - inline float getGeoImpactFactor(double t) { return mcGeoImpactFactor.get(t); } - inline void setGeoImpactFactor(float set) { mcGeoImpactFactor = AnimChannel<float>(set); } - - /*! Set/get the part slip value*/ - inline int getVolumeInit() const { return mVolumeInit; } - inline void setVolumeInit(int set) { mVolumeInit=set; } - - /*! Set/get the cast initial veocity attribute */ - void setInitialVelocity(ntlVec3Gfx set); - ntlVec3Gfx getInitialVelocity(double t); - - /*! Set/get the local inivel coords flag */ - inline bool getLocalCoordInivel() const { return mLocalCoordInivel; } - inline void setLocalCoordInivel(bool set) { mLocalCoordInivel=set; } - - /****************************************/ - /* fluid control features */ - /****************************************/ - /*! Set/get the particle control set attract force strength */ - inline float getCpsTimeStart() const { return mCpsTimeStart; } - inline void setCpsTimeStart(float set) { mCpsTimeStart=set; } - - /*! Set/get the particle control set attract force strength */ - inline float getCpsTimeEnd() const { return mCpsTimeEnd; } - inline void setCpsTimeEnd(float set) { mCpsTimeEnd=set; } - - /*! Set/get the particle control set quality */ - inline float getCpsQuality() const { return mCpsQuality; } - inline void setCpsQuality(float set) { mCpsQuality=set; } - - inline AnimChannel<float> getCpsAttrFStr() const { return mcAttrFStr; } - inline AnimChannel<float> getCpsAttrFRad() const { return mcAttrFRad; } - inline AnimChannel<float> getCpsVelFStr() const { return mcVelFStr; } - inline AnimChannel<float> getCpsVelFRad() const { return mcVelFRad; } - - /****************************************/ - - /*! Init channels from float arrays (for elbeem API) */ - void initChannels( - int nTrans, float *trans, int nRot, float *rot, int nScale, float *scale, - int nAct, float *act, int nIvel, float *ivel, - int nAttrFStr, float *attrFStr, - int nAttrFRad, float *attrFRad, - int nVelFStr, float *velFStr, - int nVelFRad, float *velFRad - ); - - /*! is the object animated? */ - inline bool getIsAnimated() const { return mIsAnimated; } - /*! init object anim flag */ - bool checkIsAnimated(); - /*! is the mesh animated? */ - virtual bool getMeshAnimated(); - /*! init triangle divisions */ - virtual void calcTriangleDivs(vector<ntlVec3Gfx> &verts, vector<ntlTriangle> &tris, gfxReal fsTri); - - /*! apply object translation at time t*/ - void applyTransformation(double t, vector<ntlVec3Gfx> *verts, vector<ntlVec3Gfx> *norms, int vstart, int vend, int forceTrafo); - - /*! Prepare points for moving objects */ - void initMovingPoints(double time, gfxReal featureSize); - /*! Prepare points for animated objects */ - void initMovingPointsAnim( - double srctime, vector<ntlVec3Gfx> &srcpoints, - double dsttime, vector<ntlVec3Gfx> &dstpoints, - vector<ntlVec3Gfx> *dstnormals, - gfxReal featureSize, ntlVec3Gfx geostart, ntlVec3Gfx geoend ); - /*! Prepare points for moving objects (copy into ret) */ - void getMovingPoints(vector<ntlVec3Gfx> &ret, vector<ntlVec3Gfx> *norms = NULL); - /*! Calculate max. velocity on object from t1 to t2 */ - ntlVec3Gfx calculateMaxVel(double t1, double t2); - /*! get translation at time t*/ - ntlVec3Gfx getTranslation(double t); - /*! get active flag time t*/ - float getGeoActive(double t); - - /*! add triangle to scene and init flags */ - // helper function for getTriangles - void sceneAddTriangle( - ntlVec3Gfx p1,ntlVec3Gfx p2,ntlVec3Gfx p3, - ntlVec3Gfx pn1,ntlVec3Gfx pn2,ntlVec3Gfx pn3, - ntlVec3Gfx trin, bool smooth, - vector<ntlTriangle> *triangles, - vector<ntlVec3Gfx> *vertices, - vector<ntlVec3Gfx> *vertNormals); - void sceneAddTriangleNoVert(int *trips, - ntlVec3Gfx trin, bool smooth, - vector<ntlTriangle> *triangles); - - protected: - - /* initialized for scene? */ - bool mIsInitialized; - - /*! Point to a property object describing the surface of this object */ - ntlMaterial *mpMaterial; - - /*! Name of the surcace property */ - string mMaterialName; - - /*! Cast shadows on/off */ - int mCastShadows; - /*! REceive shadows on/off */ - int mReceiveShadows; - - /* fluid init data */ - /*! fluid object type (fluid, obstacle, accelerator etc.) */ - int mGeoInitType; - /*! initial velocity for fluid objects */ - ntlVec3Gfx mInitialVelocity; - AnimChannel<ntlVec3Gfx> mcInitialVelocity; - /*! use object local inflow? */ - bool mLocalCoordInivel; - /*! perform more accurate intersecting geo init for this object? */ - bool mGeoInitIntersect; - /*! part slip bc value */ - float mGeoPartSlipValue; - /*! obstacle impact correction factor */ - AnimChannel<float> mcGeoImpactFactor; - /*! only init as thin object, dont fill? */ - int mVolumeInit; - - /*! initial offset for rot/scale */ - ntlVec3Gfx mInitialPos; - /*! animated channels for postition, rotation and scale */ - AnimChannel<ntlVec3Gfx> mcTrans, mcRot, mcScale; - /*! easy check for animation */ - bool mIsAnimated; - - /*! moving point/normal storage */ - vector<ntlVec3Gfx> mMovPoints; - vector<ntlVec3Gfx> mMovNormals; - /*! cached points for non moving objects/timeslots */ - bool mHaveCachedMov; - vector<ntlVec3Gfx> mCachedMovPoints; - vector<ntlVec3Gfx> mCachedMovNormals; - /*! precomputed triangle divisions */ - vector<int> mTriangleDivs1,mTriangleDivs2; - /*! inited? */ - float mMovPntsInited; - /*! point with max. distance from center */ - int mMaxMovPnt; - - /*! animated channels for in/outflow on/off */ - AnimChannel<float> mcGeoActive; - - /* fluid control settings */ - float mCpsTimeStart; - float mCpsTimeEnd; - float mCpsQuality; - AnimChannel<float> mcAttrFStr, mcAttrFRad, mcVelFStr, mcVelFRad; - - public: - -private: -#ifdef WITH_CXX_GUARDEDALLOC - MEM_CXX_CLASS_ALLOC_FUNCS("ELBEEM:ntlGeometryObject") -#endif -}; - -#endif - diff --git a/intern/elbeem/intern/ntl_geometryshader.h b/intern/elbeem/intern/ntl_geometryshader.h deleted file mode 100644 index 5400e05a27a..00000000000 --- a/intern/elbeem/intern/ntl_geometryshader.h +++ /dev/null @@ -1,73 +0,0 @@ -/** \file - * \ingroup elbeem - */ -/****************************************************************************** - * - * El'Beem - Free Surface Fluid Simulation with the Lattice Boltzmann Method - * Copyright 2003-2006 Nils Thuerey - * - * Interface for a geometry shader - * - *****************************************************************************/ -#ifndef NTL_GEOMETRYSHADER_H -#define NTL_GEOMETRYSHADER_H - -#include "ntl_geometryclass.h" - -#ifdef WITH_CXX_GUARDEDALLOC -# include "MEM_guardedalloc.h" -#endif - -class ntlGeometryObject; -class ntlRenderGlobals; - -class ntlGeometryShader : - public ntlGeometryClass -{ - - public: - - //! Default constructor - inline ntlGeometryShader() : - ntlGeometryClass(), mOutFilename("") - {}; - //! Default destructor - virtual ~ntlGeometryShader() {}; - - //! Return type id - virtual int getTypeId() { return GEOCLASSTID_SHADER; } - - /*! Initialize object, should return !=0 upon error */ - virtual int initializeShader() = 0; - - /*! Do further object initialization after all geometry has been constructed, should return !=0 upon error */ - virtual int postGeoConstrInit(ntlRenderGlobals *glob) { glob=NULL; /*unused*/ return 0; }; - - /*! Get start iterator for all objects */ - virtual vector<ntlGeometryObject *>::iterator getObjectsBegin() { return mObjects.begin(); } - /*! Get end iterator for all objects */ - virtual vector<ntlGeometryObject *>::iterator getObjectsEnd() { return mObjects.end(); } - - /*! notify object that dump is in progress (e.g. for field dump) */ - virtual void notifyShaderOfDump(int dumptype, int frameNr,char *frameNrStr,string outfilename) = 0; - - /*! get output filename, returns global render outfile if empty */ - string getOutFilename( void ) { return mOutFilename; } - - protected: - - //! vector for the objects - vector<ntlGeometryObject *> mObjects; - - - /*! surface output name for this simulation */ - string mOutFilename; - -private: -#ifdef WITH_CXX_GUARDEDALLOC - MEM_CXX_CLASS_ALLOC_FUNCS("ELBEEM:ntlGeometryShader") -#endif -}; - -#endif - diff --git a/intern/elbeem/intern/ntl_lighting.cpp b/intern/elbeem/intern/ntl_lighting.cpp deleted file mode 100644 index aef06f8f490..00000000000 --- a/intern/elbeem/intern/ntl_lighting.cpp +++ /dev/null @@ -1,184 +0,0 @@ -/** \file - * \ingroup elbeem - */ -/****************************************************************************** - * - * El'Beem - Free Surface Fluid Simulation with the Lattice Boltzmann Method - * Copyright 2003-2006 Nils Thuerey - * - * a light object - * - *****************************************************************************/ - - -#include "ntl_lighting.h" -#include "ntl_ray.h" -#include "ntl_world.h" - - -/****************************************************************************** - * Default Constructor - *****************************************************************************/ -ntlLightObject::ntlLightObject(ntlRenderGlobals *glob) : - mpGlob( glob ), - mActive( 1 ), - mCastShadows( 1 ), - mcColor( ntlColor(1.0) ), - mvPosition( ntlVec3Gfx(0.0) ) -{ - // nothing to do... -} - - -/****************************************************************************** - * Constructor with parameters - *****************************************************************************/ -ntlLightObject::ntlLightObject(ntlRenderGlobals *glob, const ntlColor& col) : - mpGlob( glob ), - mActive( 1 ), - mCastShadows( 1 ), - mcColor( col ) -{ - // nothing to do... -} - - - -/****************************************************************************** - * Destructor - *****************************************************************************/ -ntlLightObject::~ntlLightObject() -{ - // nothing to do... -} - - - -/****************************************************************************** - * Determine color contribution of a lightsource (Phong model) - * Specular part is returned in seperate parameter and added later - *****************************************************************************/ -const ntlColor -ntlLightObject::getShadedColor(const ntlRay &reflectedRay, const ntlVec3Gfx lightDir, - ntlMaterial *surf, ntlColor &highlight) const -{ - gfxReal ldot = dot(lightDir, reflectedRay.getNormal()); /* equals cos( angle(L,N) ) */ - ntlColor reflected_color = ntlColor(0.0); /* adds up to total reflected color */ - if(mpGlob->getDebugOut() > 5) errorOut("Lighting dir:"<<lightDir<<" norm:"<<reflectedRay.getNormal()<<" "<<ldot ); - - /* lambertian reflection model */ - if (ldot > 0.0) { - //ldot *= -1.0; - reflected_color += surf->getDiffuseRefl() * (getColor() * ldot ); - - /* specular part */ - /* specular reflection only makes sense, when the light is facing the surface, - as the highlight is supposed to be a reflection of the lightsource, it cannot - be reflected on surfaces with ldot<=0, as this means the arc between light - and normal is more than 90 degrees. If this isn't done, ugly moiree patterns appear - in the highlights, and refractions have strange patterns due to highlights on the - inside of the surface */ - gfxReal spec = dot(reflectedRay.getDirection(), lightDir); // equals cos( angle(R,L) ) - if((spec > 0.0) && (surf->getSpecular()>0)) { - spec = pow( spec, surf->getSpecExponent() ); /* phong exponent */ - highlight += getColor() * surf->getSpecular() * spec; - //errorOut( " "<< surf->getName() <<" S "<<highlight<<" "<<spec<<" "<<surf->getSpecular()<<" "<<surf->getSpecExponent() ); - } - - } - - return ntlColor(reflected_color); -} - - -// omni light implementation - - -/****************************************************************************** - *! prepare shadow maps if necessary - *****************************************************************************/ -void ntlLightObject::prepare( bool doCaustics ) -{ - doCaustics = false; // unused - if(!mActive) { return; } -} - - -/****************************************************************************** - * Illuminate the given point on an object - *****************************************************************************/ -ntlColor ntlLightObject::illuminatePoint(ntlRay &reflectedRay, ntlGeometryObject *closest, - ntlColor &highlight ) -{ - /* is this light active? */ - if(!mActive) { return ntlColor(0.0); } - - gfxReal visibility = 1.0; // how much of light is visible - ntlVec3Gfx intersectionPos = reflectedRay.getOrigin(); - ntlColor current_color = ntlColor(0.0); - ntlMaterial *clossurf = closest->getMaterial(); - - ntlVec3Gfx lightDir = (mvPosition - intersectionPos); - gfxReal lightDirNorm = normalize(lightDir); - - // where is the lightsource ? - ntlRay rayOfLight(intersectionPos, lightDir, 0, 1.0, mpGlob ); - - if( (1) && (mCastShadows)&&(closest->getReceiveShadows()) ) { - ntlTriangle *tri; - ntlVec3Gfx triNormal; - gfxReal trit; - mpGlob->getRenderScene()->intersectScene(rayOfLight, trit, triNormal, tri, TRI_CASTSHADOWS); - if(( trit>0 )&&( trit<lightDirNorm )) visibility = 0.0; - if(mpGlob->getDebugOut() > 5) errorOut("Omni lighting with "<<visibility ); - } - - /* is light partly visible ? */ -//? visibility=1.; - if (visibility>0.0) { - ntlColor highTemp(0.0); // temporary highlight color to multiply highTemp with offFac - current_color = getShadedColor(reflectedRay, lightDir, clossurf, highTemp) * visibility; - highlight += highTemp * visibility; - if(mpGlob->getDebugOut() > 5) errorOut("Omni lighting color "<<current_color ); - } - return current_color; -} - - - -/****************************************************************************** - * Default constructor - *****************************************************************************/ -ntlMaterial::ntlMaterial( void ) : - mName( "default" ), - mDiffuseRefl(0.5,0.5,0.5), mAmbientRefl(0.0,0.0,0.0), - mSpecular(0.0), mSpecExponent(0.0), mMirror(0.0), - mTransparence(0.0), mRefracIndex(1.05), mTransAdditive(0.0), mTransAttCol(0.0), - mFresnel( 0 ) { - // just do default init... -} - - - -/****************************************************************************** - * Init constructor - *****************************************************************************/ -ntlMaterial::ntlMaterial( string name, - const ntlColor& Ref, const ntlColor& Amb, - gfxReal Spec, gfxReal SpecEx, gfxReal Mirr, - gfxReal Trans, gfxReal Refrac, gfxReal TAdd, - const ntlColor& Att, int fres) -{ - mName = name; - mDiffuseRefl = Ref; - mAmbientRefl = Amb; - mSpecular = Spec; - mSpecExponent = SpecEx; - mMirror = Mirr; - mTransparence = Trans; - mRefracIndex = Refrac; - mTransAdditive = TAdd; - mTransAttCol = Att; - mFresnel = fres; -} - diff --git a/intern/elbeem/intern/ntl_lighting.h b/intern/elbeem/intern/ntl_lighting.h deleted file mode 100644 index b046ccfae57..00000000000 --- a/intern/elbeem/intern/ntl_lighting.h +++ /dev/null @@ -1,254 +0,0 @@ -/** \file - * \ingroup elbeem - */ -/****************************************************************************** - * - * El'Beem - Free Surface Fluid Simulation with the Lattice Boltzmann Method - * Copyright 2003-2006 Nils Thuerey - * - * a light object - * default omni light implementation - * - *****************************************************************************/ -#ifndef NTL_LIGHTING_H -#define NTL_LIGHTING_H - -#include "ntl_vector3dim.h" - -#ifdef WITH_CXX_GUARDEDALLOC -# include "MEM_guardedalloc.h" -#endif - -class ntlMaterial; -class ntlRay; -class ntlRenderGlobals; -class ntlGeometryObject; - - - -/* shadow map directions */ -#define LSM_RIGHT 0 -#define LSM_LEFT 1 -#define LSM_UP 2 -#define LSM_DOWN 3 -#define LSM_FRONT 4 -#define LSM_BACK 5 - -/*! Basic object for lights, all other light are derived from this one */ -class ntlLightObject -{ -public: - /* CONSTRUCTORS */ - /*! Default constructor */ - ntlLightObject(ntlRenderGlobals *glob); - /*! Constructor with parameters */ - ntlLightObject(ntlRenderGlobals *glob, const ntlColor& col); - /*! Destructor */ - virtual ~ntlLightObject(); - - /*! prepare light for rendering (for example shadow maps) */ - virtual void prepare( bool ); - - /*! do the illumination... */ - virtual ntlColor illuminatePoint(ntlRay &reflectedRay, - ntlGeometryObject *closest, - ntlColor &highlight); - /*! shade the point */ - const ntlColor - getShadedColor(const ntlRay &reflectedray, ntlVec3Gfx lightDir, - ntlMaterial *surf, ntlColor &highlight) const; - - - /* access methods */ - /*! Access the active flag */ - inline void setActive(bool set) { mActive = set; } - inline bool getActive() const { return mActive; } - /*! Access the shadow flag */ - inline void setCastShadows(bool set) { mCastShadows = set; } - inline bool getCastShadows() const { return mCastShadows; } - /*! Access the light color */ - inline void setColor(ntlColor set) { mcColor = set; } - inline ntlColor getColor() const { return mcColor; } - - /*! Access the omni light position */ - void setPosition(ntlVec3Gfx set) { mvPosition = set; } - ntlVec3Gfx getPosition() const { return mvPosition; } - - -protected: - /*! render globals */ - ntlRenderGlobals *mpGlob; - - /*! is this light acitve? */ - bool mActive; - - /*! does it cast shadows? */ - bool mCastShadows; - - /*! color of this light */ - ntlColor mcColor; - - /*! light position */ - ntlVec3Gfx mvPosition; - -private: - -private: -#ifdef WITH_CXX_GUARDEDALLOC - MEM_CXX_CLASS_ALLOC_FUNCS("ELBEEM:ntlLightObject") -#endif -}; - - -//! Properties of an geo object, describing the reflection properties of the surface -class ntlMaterial -{ -public: - // CONSTRUCTORS - //! Default constructor - ntlMaterial( void ); - //! Constructor with parameters - /*! Sets reflectance, ambient reflection, specular intensity - * specular exponent, mirror intensity - * transparency, refraction index */ - ntlMaterial( string name, - const ntlColor& Ref, const ntlColor& Amb, - gfxReal Spec, gfxReal Exp, gfxReal Mirror, - gfxReal Trans, gfxReal Refrac, gfxReal TAdd, - const ntlColor& Att, int fres); - //! Desctructor - ~ntlMaterial() {}; - - //! Calculate reflectance and refratance from Fresnel's law - inline void calculateFresnel(const ntlVec3Gfx &dir, const ntlVec3Gfx &normal, gfxReal refIndex, - gfxReal &refl, gfxReal &trans ); - -protected: - - /* name of the material */ - string mName; - - //! Vector for reflectance of each color component (used in shade() of ray object) - ntlColor mDiffuseRefl; - //! Ambient reflectance - ntlColor mAmbientRefl; - //! Specular reflection intensity - gfxReal mSpecular; - //! Specular phong exponent - gfxReal mSpecExponent; - //! Mirror intensity - gfxReal mMirror; - - //! Transparence - gfxReal mTransparence; - //! Refraction index, nu(Air) is assumed 1 - gfxReal mRefracIndex; - //! Should transparence be additive? - gfxReal mTransAdditive; - //! Color dependent transparency attentuation factors (negative logarithm stored) - ntlColor mTransAttCol; - //! Should the transparence and reflectivity be determined by fresnel? - int mFresnel; - - -public: - // access methods - - //! Returns the material name - inline string getName() { return mName; } - //! Returns the reflectance - inline ntlColor getDiffuseRefl() const { return ntlColor(mDiffuseRefl); } - //! Returns the ambience - inline ntlColor getAmbientRefl() const { return ntlColor(mAmbientRefl); } - //! Returns the specular component - inline gfxReal getSpecular() const { return mSpecular; } - //! Returns the specular exponent component - inline gfxReal getSpecExponent() const { return mSpecExponent; } - //! Returns the mirror component - inline gfxReal getMirror() const { return mMirror; } - //! Returns the transparence component - inline gfxReal getTransparence() const { return mTransparence; } - //! Returns the refraction index component - inline gfxReal getRefracIndex() const { return mRefracIndex; } - //! Returns the transparency additive factor component - inline gfxReal getTransAdditive() const { return mTransAdditive; } - //! Returns the transparency attentuation - inline ntlColor getTransAttCol() const { return mTransAttCol; } - //! Get Fresnel flag - inline int getFresnel( void ) { return mFresnel; } - - - - //! Returns the mat name - inline void setName(string set) { mName = set; } - //! Returns the reflectance - inline void setDiffuseRefl(ntlColor set) { mDiffuseRefl=set; } - //! Returns the ambience - inline void setAmbientRefl(ntlColor set) { mAmbientRefl=set; } - //! Returns the specular component - inline void setSpecular(gfxReal set) { mSpecular=set; } - //! Returns the specular exponent component - inline void setSpecExponent(gfxReal set) { mSpecExponent=set; } - //! Returns the mirror component - inline void setMirror(gfxReal set) { mMirror=set; } - //! Returns the transparence component - inline void setTransparence(gfxReal set) { mTransparence=set; } - //! Returns the refraction index component - inline void setRefracIndex(gfxReal set) { mRefracIndex=set; } - //! Returns the transparency additive factor component - inline void setTransAdditive(gfxReal set) { mTransAdditive=set; } - //! Returns the transparency attentuation - inline void setTransAttCol(ntlColor set) { - ntlColor setlog = ntlColor( -log(set[0]), -log(set[1]), -log(set[2]) ); - mTransAttCol=setlog; } - //! Set Fresnel on/off - inline void setFresnel(int set) { mFresnel = set; } - -private: -#ifdef WITH_CXX_GUARDEDALLOC - MEM_CXX_CLASS_ALLOC_FUNCS("ELBEEM:ntlMaterial") -#endif -}; - - -/****************************************************************************** - * Macro to define the default surface properties for a newly created object - *****************************************************************************/ -#define GET_GLOBAL_DEFAULT_MATERIAL new ntlMaterial( "default",\ - ntlColor( 0.5 ), ntlColor(0.0), \ - 1.0, 5.0, 0.0, \ - /*0.0 test:*/ 0.5 , 1.0, 0.0, \ - ntlColor( 0.0 ), 0 ); - - - -/****************************************************************************** - * Calculate reflectance and refratance from Fresnel's law - * cf. Glassner p. 46 - *****************************************************************************/ -inline void -ntlMaterial::calculateFresnel(const ntlVec3Gfx &dir, const ntlVec3Gfx &normal, gfxReal refIndex, - gfxReal &refl, gfxReal &trans) -{ - gfxReal c = -dot(dir, normal); - if(c<0) { - refl = 0.0; trans = 0.0; return; - //c = 0.0; - } - - gfxReal r0 = ((refIndex-1.0)*(refIndex-1.0)) / - ((refIndex+1.0)*(refIndex+1.0)); - gfxReal omc = (1.0-c); - gfxReal r =r0 + (1.0 - r0) * omc*omc*omc*omc*omc; - - //mMirror = r; - //mTransparence = (1.0 - r); - refl = r; - trans = (1.0 - r); - //errorOut(" fres "); -} - - -#endif - - diff --git a/intern/elbeem/intern/ntl_matrices.h b/intern/elbeem/intern/ntl_matrices.h deleted file mode 100644 index d3551f1a682..00000000000 --- a/intern/elbeem/intern/ntl_matrices.h +++ /dev/null @@ -1,790 +0,0 @@ -/** \file - * \ingroup elbeem - */ - -/****************************************************************************** - * - * El'Beem - Free Surface Fluid Simulation with the Lattice Boltzmann Method - * Copyright 2003-2006 Nils Thuerey - * - * Basic matrix utility include file - * - *****************************************************************************/ -#ifndef NTL_MATRICES_H - -#include "ntl_vector3dim.h" - -#ifdef WITH_CXX_GUARDEDALLOC -# include "MEM_guardedalloc.h" -#endif - -// The basic vector class -template<class Scalar> -class ntlMatrix4x4 -{ -public: - // Constructor - inline ntlMatrix4x4(void ); - // Copy-Constructor - inline ntlMatrix4x4(const ntlMatrix4x4<Scalar> &v ); - // construct a vector from one Scalar - inline ntlMatrix4x4(Scalar); - // construct a vector from three Scalars - inline ntlMatrix4x4(Scalar, Scalar, Scalar); - - // Assignment operator - inline const ntlMatrix4x4<Scalar>& operator= (const ntlMatrix4x4<Scalar>& v); - // Assignment operator - inline const ntlMatrix4x4<Scalar>& operator= (Scalar s); - // Assign and add operator - inline const ntlMatrix4x4<Scalar>& operator+= (const ntlMatrix4x4<Scalar>& v); - // Assign and add operator - inline const ntlMatrix4x4<Scalar>& operator+= (Scalar s); - // Assign and sub operator - inline const ntlMatrix4x4<Scalar>& operator-= (const ntlMatrix4x4<Scalar>& v); - // Assign and sub operator - inline const ntlMatrix4x4<Scalar>& operator-= (Scalar s); - // Assign and mult operator - inline const ntlMatrix4x4<Scalar>& operator*= (const ntlMatrix4x4<Scalar>& v); - // Assign and mult operator - inline const ntlMatrix4x4<Scalar>& operator*= (Scalar s); - // Assign and div operator - inline const ntlMatrix4x4<Scalar>& operator/= (const ntlMatrix4x4<Scalar>& v); - // Assign and div operator - inline const ntlMatrix4x4<Scalar>& operator/= (Scalar s); - - - // unary operator - inline ntlMatrix4x4<Scalar> operator- () const; - - // binary operator add - inline ntlMatrix4x4<Scalar> operator+ (const ntlMatrix4x4<Scalar>&) const; - // binary operator add - inline ntlMatrix4x4<Scalar> operator+ (Scalar) const; - // binary operator sub - inline ntlMatrix4x4<Scalar> operator- (const ntlMatrix4x4<Scalar>&) const; - // binary operator sub - inline ntlMatrix4x4<Scalar> operator- (Scalar) const; - // binary operator mult - inline ntlMatrix4x4<Scalar> operator* (const ntlMatrix4x4<Scalar>&) const; - // binary operator mult - inline ntlVector3Dim<Scalar> operator* (const ntlVector3Dim<Scalar>&) const; - // binary operator mult - inline ntlMatrix4x4<Scalar> operator* (Scalar) const; - // binary operator div - inline ntlMatrix4x4<Scalar> operator/ (Scalar) const; - - // init function - //! init identity matrix - inline void initId(); - //! init rotation matrix - inline void initTranslation(Scalar x, Scalar y, Scalar z); - //! init rotation matrix - inline void initRotationX(Scalar rot); - inline void initRotationY(Scalar rot); - inline void initRotationZ(Scalar rot); - inline void initRotationXYZ(Scalar rotx,Scalar roty, Scalar rotz); - //! init scaling matrix - inline void initScaling(Scalar scale); - inline void initScaling(Scalar x, Scalar y, Scalar z); - //! from 16 value array (init id if all 0) - inline void initArrayCheck(Scalar *array); - - //! decompose matrix - void decompose(ntlVector3Dim<Scalar> &trans,ntlVector3Dim<Scalar> &scale,ntlVector3Dim<Scalar> &rot,ntlVector3Dim<Scalar> &shear); - - //! public to avoid [][] operators - Scalar value[4][4]; //< Storage of vector values - - -protected: - -private: -#ifdef WITH_CXX_GUARDEDALLOC - MEM_CXX_CLASS_ALLOC_FUNCS("ELBEEM:ntlMatrix4x4") -#endif -}; - - - -//------------------------------------------------------------------------------ -// TYPEDEFS -//------------------------------------------------------------------------------ - -// a 3D vector for graphics output, typically float? -//typedef ntlMatrix4x4<float> ntlVec3Gfx; - -//typedef ntlMatrix4x4<double> ntlMat4d; -typedef ntlMatrix4x4<double> ntlMat4d; - -// a 3D vector with single precision -typedef ntlMatrix4x4<float> ntlMat4f; - -// a 3D vector with grafix precision -typedef ntlMatrix4x4<gfxReal> ntlMat4Gfx; - -// a 3D integer vector -typedef ntlMatrix4x4<int> ntlMat4i; - - - - - -//------------------------------------------------------------------------------ -// STREAM FUNCTIONS -//------------------------------------------------------------------------------ - - - -/************************************************************************* - Outputs the object in human readable form using the format - [x,y,z] - */ -template<class Scalar> -std::ostream& -operator<<( std::ostream& os, const ntlMatrix4x4<Scalar>& m ) -{ - for(int i=0; i<4; i++) { - os << '|' << m.value[i][0] << ", " << m.value[i][1] << ", " << m.value[i][2] << ", " << m.value[i][3] << '|'; - } - return os; -} - - - -/************************************************************************* - Reads the contents of the object from a stream using the same format - as the output operator. - */ -template<class Scalar> -std::istream& -operator>>( std::istream& is, ntlMatrix4x4<Scalar>& m ) -{ - char c; - char dummy[3]; - - for(int i=0; i<4; i++) { - is >> c >> m.value[i][0] >> dummy >> m.value[i][1] >> dummy >> m.value[i][2] >> dummy >> m.value[i][3] >> c; - } - return is; -} - - -//------------------------------------------------------------------------------ -// VECTOR inline FUNCTIONS -//------------------------------------------------------------------------------ - - - -/************************************************************************* - Constructor. - */ -template<class Scalar> -inline ntlMatrix4x4<Scalar>::ntlMatrix4x4( void ) -{ -#ifdef MATRIX_INIT_ZERO - for(int i=0; i<4; i++) { - for(int j=0; j<4; j++) { - value[i][j] = 0.0; - } - } -#endif -} - - - -/************************************************************************* - Copy-Constructor. - */ -template<class Scalar> -inline ntlMatrix4x4<Scalar>::ntlMatrix4x4( const ntlMatrix4x4<Scalar> &v ) -{ - value[0][0] = v.value[0][0]; value[0][1] = v.value[0][1]; value[0][2] = v.value[0][2]; value[0][3] = v.value[0][3]; - value[1][0] = v.value[1][0]; value[1][1] = v.value[1][1]; value[1][2] = v.value[1][2]; value[1][3] = v.value[1][3]; - value[2][0] = v.value[2][0]; value[2][1] = v.value[2][1]; value[2][2] = v.value[2][2]; value[2][3] = v.value[2][3]; - value[3][0] = v.value[3][0]; value[3][1] = v.value[3][1]; value[3][2] = v.value[3][2]; value[3][3] = v.value[3][3]; -} - - - -/************************************************************************* - Constructor for a vector from a single Scalar. All components of - the vector get the same value. - \param s The value to set - \return The new vector - */ -template<class Scalar> -inline ntlMatrix4x4<Scalar>::ntlMatrix4x4(Scalar s ) -{ - for(int i=0; i<4; i++) { - for(int j=0; j<4; j++) { - value[i][j] = s; - } - } -} - - - -/************************************************************************* - Copy a ntlMatrix4x4 componentwise. - \param v vector with values to be copied - \return Reference to self - */ -template<class Scalar> -inline const ntlMatrix4x4<Scalar>& -ntlMatrix4x4<Scalar>::operator=( const ntlMatrix4x4<Scalar> &v ) -{ - value[0][0] = v.value[0][0]; value[0][1] = v.value[0][1]; value[0][2] = v.value[0][2]; value[0][3] = v.value[0][3]; - value[1][0] = v.value[1][0]; value[1][1] = v.value[1][1]; value[1][2] = v.value[1][2]; value[1][3] = v.value[1][3]; - value[2][0] = v.value[2][0]; value[2][1] = v.value[2][1]; value[2][2] = v.value[2][2]; value[2][3] = v.value[2][3]; - value[3][0] = v.value[3][0]; value[3][1] = v.value[3][1]; value[3][2] = v.value[3][2]; value[3][3] = v.value[3][3]; - return *this; -} - - -/************************************************************************* - Copy a Scalar to each component. - \param s The value to copy - \return Reference to self - */ -template<class Scalar> -inline const ntlMatrix4x4<Scalar>& -ntlMatrix4x4<Scalar>::operator=(Scalar s) -{ - for(int i=0; i<4; i++) { - for(int j=0; j<4; j++) { - value[i][j] = s; - } - } - return *this; -} - - -/************************************************************************* - Add another ntlMatrix4x4 componentwise. - \param v vector with values to be added - \return Reference to self - */ -template<class Scalar> -inline const ntlMatrix4x4<Scalar>& -ntlMatrix4x4<Scalar>::operator+=( const ntlMatrix4x4<Scalar> &v ) -{ - value[0][0] += v.value[0][0]; value[0][1] += v.value[0][1]; value[0][2] += v.value[0][2]; value[0][3] += v.value[0][3]; - value[1][0] += v.value[1][0]; value[1][1] += v.value[1][1]; value[1][2] += v.value[1][2]; value[1][3] += v.value[1][3]; - value[2][0] += v.value[2][0]; value[2][1] += v.value[2][1]; value[2][2] += v.value[2][2]; value[2][3] += v.value[2][3]; - value[3][0] += v.value[3][0]; value[3][1] += v.value[3][1]; value[3][2] += v.value[3][2]; value[3][3] += v.value[3][3]; - return *this; -} - - -/************************************************************************* - Add a Scalar value to each component. - \param s Value to add - \return Reference to self - */ -template<class Scalar> -inline const ntlMatrix4x4<Scalar>& -ntlMatrix4x4<Scalar>::operator+=(Scalar s) -{ - for(int i=0; i<4; i++) { - for(int j=0; j<4; j++) { - value[i][j] += s; - } - } - return *this; -} - - -/************************************************************************* - Subtract another vector componentwise. - \param v vector of values to subtract - \return Reference to self - */ -template<class Scalar> -inline const ntlMatrix4x4<Scalar>& -ntlMatrix4x4<Scalar>::operator-=( const ntlMatrix4x4<Scalar> &v ) -{ - value[0][0] -= v.value[0][0]; value[0][1] -= v.value[0][1]; value[0][2] -= v.value[0][2]; value[0][3] -= v.value[0][3]; - value[1][0] -= v.value[1][0]; value[1][1] -= v.value[1][1]; value[1][2] -= v.value[1][2]; value[1][3] -= v.value[1][3]; - value[2][0] -= v.value[2][0]; value[2][1] -= v.value[2][1]; value[2][2] -= v.value[2][2]; value[2][3] -= v.value[2][3]; - value[3][0] -= v.value[3][0]; value[3][1] -= v.value[3][1]; value[3][2] -= v.value[3][2]; value[3][3] -= v.value[3][3]; - return *this; -} - - -/************************************************************************* - Subtract a Scalar value from each component. - \param s Value to subtract - \return Reference to self - */ -template<class Scalar> -inline const ntlMatrix4x4<Scalar>& -ntlMatrix4x4<Scalar>::operator-=(Scalar s) -{ - for(int i=0; i<4; i++) { - for(int j=0; j<4; j++) { - value[i][j] -= s; - } - } - return *this; -} - - -/************************************************************************* - Multiply with another vector componentwise. - \param v vector of values to multiply with - \return Reference to self - */ -template<class Scalar> -inline const ntlMatrix4x4<Scalar>& -ntlMatrix4x4<Scalar>::operator*=( const ntlMatrix4x4<Scalar> &v ) -{ - ntlMatrix4x4<Scalar> nv(0.0); - for(int i=0; i<4; i++) { - for(int j=0; j<4; j++) { - - for(int k=0;k<4;k++) - nv.value[i][j] += (value[i][k] * v.value[k][j]); - } - } - *this = nv; - return *this; -} - - -/************************************************************************* - Multiply each component with a Scalar value. - \param s Value to multiply with - \return Reference to self - */ -template<class Scalar> -inline const ntlMatrix4x4<Scalar>& -ntlMatrix4x4<Scalar>::operator*=(Scalar s) -{ - for(int i=0; i<4; i++) { - for(int j=0; j<4; j++) { - value[i][j] *= s; - } - } - return *this; -} - - - -/************************************************************************* - Divide each component by a Scalar value. - \param s Value to divide by - \return Reference to self - */ -template<class Scalar> -inline const ntlMatrix4x4<Scalar>& -ntlMatrix4x4<Scalar>::operator/=(Scalar s) -{ - for(int i=0; i<4; i++) { - for(int j=0; j<4; j++) { - value[i][j] /= s; - } - } - return *this; -} - - -//------------------------------------------------------------------------------ -// unary operators -//------------------------------------------------------------------------------ - - -/************************************************************************* - Build componentwise the negative this vector. - \return The new (negative) vector - */ -template<class Scalar> -inline ntlMatrix4x4<Scalar> -ntlMatrix4x4<Scalar>::operator-() const -{ - ntlMatrix4x4<Scalar> nv; - for(int i=0; i<4; i++) { - for(int j=0; j<4; j++) { - nv[i][j] = -value[i][j]; - } - } - return nv; -} - - - -//------------------------------------------------------------------------------ -// binary operators -//------------------------------------------------------------------------------ - - -/************************************************************************* - Build a vector with another vector added componentwise. - \param v The second vector to add - \return The sum vector - */ -template<class Scalar> -inline ntlMatrix4x4<Scalar> -ntlMatrix4x4<Scalar>::operator+( const ntlMatrix4x4<Scalar> &v ) const -{ - ntlMatrix4x4<Scalar> nv; - for(int i=0; i<4; i++) { - for(int j=0; j<4; j++) { - nv[i][j] = value[i][j] + v.value[i][j]; - } - } - return nv; -} - - -/************************************************************************* - Build a vector with a Scalar value added to each component. - \param s The Scalar value to add - \return The sum vector - */ -template<class Scalar> -inline ntlMatrix4x4<Scalar> -ntlMatrix4x4<Scalar>::operator+(Scalar s) const -{ - ntlMatrix4x4<Scalar> nv; - for(int i=0; i<4; i++) { - for(int j=0; j<4; j++) { - nv[i][j] = value[i][j] + s; - } - } - return nv; -} - - -/************************************************************************* - Build a vector with another vector subtracted componentwise. - \param v The second vector to subtract - \return The difference vector - */ -template<class Scalar> -inline ntlMatrix4x4<Scalar> -ntlMatrix4x4<Scalar>::operator-( const ntlMatrix4x4<Scalar> &v ) const -{ - ntlMatrix4x4<Scalar> nv; - for(int i=0; i<4; i++) { - for(int j=0; j<4; j++) { - nv[i][j] = value[i][j] - v.value[i][j]; - } - } - return nv; -} - - -/************************************************************************* - Build a vector with a Scalar value subtracted componentwise. - \param s The Scalar value to subtract - \return The difference vector - */ -template<class Scalar> -inline ntlMatrix4x4<Scalar> -ntlMatrix4x4<Scalar>::operator-(Scalar s ) const -{ - ntlMatrix4x4<Scalar> nv; - for(int i=0; i<4; i++) { - for(int j=0; j<4; j++) { - nv[i][j] = value[i][j] - s; - } - } - return nv; -} - - - -/************************************************************************* - Build a ntlMatrix4x4 with a Scalar value multiplied to each component. - \param s The Scalar value to multiply with - \return The product vector - */ -template<class Scalar> -inline ntlMatrix4x4<Scalar> -ntlMatrix4x4<Scalar>::operator*(Scalar s) const -{ - ntlMatrix4x4<Scalar> nv; - for(int i=0; i<4; i++) { - for(int j=0; j<4; j++) { - nv[i][j] = value[i][j] * s; - } - } - return nv; -} - - - - -/************************************************************************* - Build a vector divided componentwise by a Scalar value. - \param s The Scalar value to divide by - \return The ratio vector - */ -template<class Scalar> -inline ntlMatrix4x4<Scalar> -ntlMatrix4x4<Scalar>::operator/(Scalar s) const -{ - ntlMatrix4x4<Scalar> nv; - for(int i=0; i<4; i++) { - for(int j=0; j<4; j++) { - nv[i][j] = value[i][j] / s; - } - } - return nv; -} - - - - - -/************************************************************************* - Build a vector with another vector multiplied by componentwise. - \param v The second vector to muliply with - \return The product vector - */ -template<class Scalar> -inline ntlMatrix4x4<Scalar> -ntlMatrix4x4<Scalar>::operator*( const ntlMatrix4x4<Scalar>& v) const -{ - ntlMatrix4x4<Scalar> nv(0.0); - for(int i=0; i<4; i++) { - for(int j=0; j<4; j++) { - - for(int k=0;k<4;k++) - nv.value[i][j] += (value[i][k] * v.value[k][j]); - } - } - return nv; -} - - -template<class Scalar> -inline ntlVector3Dim<Scalar> -ntlMatrix4x4<Scalar>::operator*( const ntlVector3Dim<Scalar>& v) const -{ - ntlVector3Dim<Scalar> nvec(0.0); - for(int i=0; i<3; i++) { - for(int j=0; j<3; j++) { - nvec[i] += (v[j] * value[i][j]); - } - } - // assume normalized w coord - for(int i=0; i<3; i++) { - nvec[i] += (1.0 * value[i][3]); - } - return nvec; -} - - - -//------------------------------------------------------------------------------ -// Other helper functions -//------------------------------------------------------------------------------ - -//! init identity matrix -template<class Scalar> -inline void ntlMatrix4x4<Scalar>::initId() -{ - (*this) = (Scalar)(0.0); - value[0][0] = - value[1][1] = - value[2][2] = - value[3][3] = (Scalar)(1.0); -} - -//! init rotation matrix -template<class Scalar> -inline void ntlMatrix4x4<Scalar>::initTranslation(Scalar x, Scalar y, Scalar z) -{ - //(*this) = (Scalar)(0.0); - this->initId(); - value[0][3] = x; - value[1][3] = y; - value[2][3] = z; -} - -//! init rotation matrix -template<class Scalar> -inline void -ntlMatrix4x4<Scalar>::initRotationX(Scalar rot) -{ - double drot = (double)(rot/360.0*2.0*M_PI); - //? while(drot < 0.0) drot += (M_PI*2.0); - - this->initId(); - value[1][1] = (Scalar) cos(drot); - value[1][2] = (Scalar) sin(drot); - value[2][1] = (Scalar)(-sin(drot)); - value[2][2] = (Scalar) cos(drot); -} -template<class Scalar> -inline void -ntlMatrix4x4<Scalar>::initRotationY(Scalar rot) -{ - double drot = (double)(rot/360.0*2.0*M_PI); - //? while(drot < 0.0) drot += (M_PI*2.0); - - this->initId(); - value[0][0] = (Scalar) cos(drot); - value[0][2] = (Scalar)(-sin(drot)); - value[2][0] = (Scalar) sin(drot); - value[2][2] = (Scalar) cos(drot); -} -template<class Scalar> -inline void -ntlMatrix4x4<Scalar>::initRotationZ(Scalar rot) -{ - double drot = (double)(rot/360.0*2.0*M_PI); - //? while(drot < 0.0) drot += (M_PI*2.0); - - this->initId(); - value[0][0] = (Scalar) cos(drot); - value[0][1] = (Scalar) sin(drot); - value[1][0] = (Scalar)(-sin(drot)); - value[1][1] = (Scalar) cos(drot); -} -template<class Scalar> -inline void -ntlMatrix4x4<Scalar>::initRotationXYZ( Scalar rotx, Scalar roty, Scalar rotz) -{ - ntlMatrix4x4<Scalar> val; - ntlMatrix4x4<Scalar> rot; - this->initId(); - - // org - /*rot.initRotationX(rotx); - (*this) *= rot; - rot.initRotationY(roty); - (*this) *= rot; - rot.initRotationZ(rotz); - (*this) *= rot; - // org */ - - // blender - rot.initRotationZ(rotz); - (*this) *= rot; - rot.initRotationY(roty); - (*this) *= rot; - rot.initRotationX(rotx); - (*this) *= rot; - // blender */ -} - -//! init scaling matrix -template<class Scalar> -inline void -ntlMatrix4x4<Scalar>::initScaling(Scalar scale) -{ - this->initId(); - value[0][0] = scale; - value[1][1] = scale; - value[2][2] = scale; -} -//! init scaling matrix -template<class Scalar> -inline void -ntlMatrix4x4<Scalar>::initScaling(Scalar x, Scalar y, Scalar z) -{ - this->initId(); - value[0][0] = x; - value[1][1] = y; - value[2][2] = z; -} - - -//! from 16 value array (init id if all 0) -template<class Scalar> -inline void -ntlMatrix4x4<Scalar>::initArrayCheck(Scalar *array) -{ - bool allZero = true; - for(int i=0; i<4; i++) { - for(int j=0; j<4; j++) { - value[i][j] = array[i*4+j]; - if(array[i*4+j]!=0.0) allZero=false; - } - } - if(allZero) this->initId(); -} - -//! decompose matrix -template<class Scalar> -void -ntlMatrix4x4<Scalar>::decompose(ntlVector3Dim<Scalar> &trans,ntlVector3Dim<Scalar> &scale,ntlVector3Dim<Scalar> &rot,ntlVector3Dim<Scalar> &shear) { - ntlVec3Gfx row[3],temp; - - for(int i = 0; i < 3; i++) { - trans[i] = this->value[3][i]; - } - - for(int i = 0; i < 3; i++) { - row[i][0] = this->value[i][0]; - row[i][1] = this->value[i][1]; - row[i][2] = this->value[i][2]; - } - - scale[0] = norm(row[0]); - normalize (row[0]); - - shear[0] = dot(row[0], row[1]); - row[1][0] = row[1][0] - shear[0]*row[0][0]; - row[1][1] = row[1][1] - shear[0]*row[0][1]; - row[1][2] = row[1][2] - shear[0]*row[0][2]; - - scale[1] = norm(row[1]); - normalize (row[1]); - - if(scale[1] != 0.0) - shear[0] /= scale[1]; - - shear[1] = dot(row[0], row[2]); - row[2][0] = row[2][0] - shear[1]*row[0][0]; - row[2][1] = row[2][1] - shear[1]*row[0][1]; - row[2][2] = row[2][2] - shear[1]*row[0][2]; - - shear[2] = dot(row[1], row[2]); - row[2][0] = row[2][0] - shear[2]*row[1][0]; - row[2][1] = row[2][1] - shear[2]*row[1][1]; - row[2][2] = row[2][2] - shear[2]*row[1][2]; - - scale[2] = norm(row[2]); - normalize (row[2]); - - if(scale[2] != 0.0) { - shear[1] /= scale[2]; - shear[2] /= scale[2]; - } - - temp = cross(row[1], row[2]); - if(dot(row[0], temp) < 0.0) { - for(int i = 0; i < 3; i++) { - scale[i] *= -1.0; - row[i][0] *= -1.0; - row[i][1] *= -1.0; - row[i][2] *= -1.0; - } - } - - if(row[0][2] < -1.0) row[0][2] = -1.0; - if(row[0][2] > +1.0) row[0][2] = +1.0; - - rot[1] = asin(-row[0][2]); - - if(fabs(cos(rot[1])) > VECTOR_EPSILON) { - rot[0] = atan2 (row[1][2], row[2][2]); - rot[2] = atan2 (row[0][1], row[0][0]); - } - else { - rot[0] = atan2 (row[1][0], row[1][1]); - rot[2] = 0.0; - } - - rot[0] = (180.0/M_PI)*rot[0]; - rot[1] = (180.0/M_PI)*rot[1]; - rot[2] = (180.0/M_PI)*rot[2]; -} - -#define NTL_MATRICES_H -#endif - diff --git a/intern/elbeem/intern/ntl_ray.cpp b/intern/elbeem/intern/ntl_ray.cpp deleted file mode 100644 index 1acc8cdca12..00000000000 --- a/intern/elbeem/intern/ntl_ray.cpp +++ /dev/null @@ -1,915 +0,0 @@ -/** \file - * \ingroup elbeem - */ -/****************************************************************************** - * - * El'Beem - Free Surface Fluid Simulation with the Lattice Boltzmann Method - * Copyright 2003-2006 Nils Thuerey - * - * main renderer class - * - *****************************************************************************/ - - -#include "utilities.h" -#include "ntl_ray.h" -#include "ntl_world.h" -#include "ntl_geometryobject.h" -#include "ntl_geometryshader.h" - - -/* Minimum value for refl/refr to be traced */ -#define RAY_THRESHOLD 0.001 - -#if GFX_PRECISION==1 -// float values -//! Minimal contribution for rays to be traced on -#define RAY_MINCONTRIB (1e-04) - -#else -// double values -//! Minimal contribution for rays to be traced on -#define RAY_MINCONTRIB (1e-05) - -#endif - - - - - -/****************************************************************************** - * Constructor - *****************************************************************************/ -ntlRay::ntlRay( void ) - : mOrigin(0.0) - , mDirection(0.0) - , mvNormal(0.0) - , mDepth(0) - , mpGlob(NULL) - , mIsRefracted(0) -{ - errFatal("ntlRay::ntlRay()","Don't use uninitialized rays !", SIMWORLD_GENERICERROR); - return; -} - - -/****************************************************************************** - * Copy - Constructor - *****************************************************************************/ -ntlRay::ntlRay( const ntlRay &r ) -{ - // copy it! initialization is not enough! - mOrigin = r.mOrigin; - mDirection = r.mDirection; - mvNormal = r.mvNormal; - mDepth = r.mDepth; - mIsRefracted = r.mIsRefracted; - mIsReflected = r.mIsReflected; - mContribution = r.mContribution; - mpGlob = r.mpGlob; - - // get new ID - if(mpGlob) { - mID = mpGlob->getCounterRays()+1; - mpGlob->setCounterRays( mpGlob->getCounterRays()+1 ); - } else { - mID = 0; - } -} - - -/****************************************************************************** - * Constructor with explicit parameters and global render object - *****************************************************************************/ -ntlRay::ntlRay(const ntlVec3Gfx &o, const ntlVec3Gfx &d, unsigned int i, gfxReal contrib, ntlRenderGlobals *glob) - : mOrigin( o ) - , mDirection( d ) - , mvNormal(0.0) - , mDepth( i ) - , mContribution( contrib ) - , mpGlob( glob ) - , mIsRefracted( 0 ) - , mIsReflected( 0 ) -{ - // get new ID - if(mpGlob) { - mID = mpGlob->getCounterRays()+1; - mpGlob->setCounterRays( mpGlob->getCounterRays()+1 ); - } else { - mID = 0; - } -} - - - -/****************************************************************************** - * Destructor - *****************************************************************************/ -ntlRay::~ntlRay() -{ - /* nothing to do... */ -} - - - -/****************************************************************************** - * AABB - *****************************************************************************/ -/* for AABB intersect */ -#define NUMDIM 3 -#define RIGHT 0 -#define LEFT 1 -#define MIDDLE 2 - -//! intersect ray with AABB -#ifndef ELBEEM_PLUGIN -void ntlRay::intersectFrontAABB(ntlVec3Gfx mStart, ntlVec3Gfx mEnd, gfxReal &t, ntlVec3Gfx &retnormal,ntlVec3Gfx &retcoord) const -{ - char inside = true; /* inside box? */ - char hit = false; /* ray hits box? */ - int whichPlane; /* intersection plane */ - gfxReal candPlane[NUMDIM]; /* candidate plane */ - gfxReal quadrant[NUMDIM]; /* quadrants */ - gfxReal maxT[NUMDIM]; /* max intersection T for planes */ - ntlVec3Gfx coord; /* intersection point */ - ntlVec3Gfx dir = mDirection; - ntlVec3Gfx origin = mOrigin; - ntlVec3Gfx normal(0.0, 0.0, 0.0); - - t = GFX_REAL_MAX; - - /* check intersection planes for AABB */ - for(int i=0;i<NUMDIM;i++) { - if(origin[i] < mStart[i]) { - quadrant[i] = LEFT; - candPlane [i] = mStart[i]; - inside = false; - } else if(origin[i] > mEnd[i]) { - quadrant[i] = RIGHT; - candPlane[i] = mEnd[i]; - inside = false; - } else { - quadrant[i] = MIDDLE; - } - } - - /* inside AABB? */ - if(!inside) { - /* get t distances to planes */ - /* treat too small direction components as paralell */ - for(int i=0;i<NUMDIM;i++) { - if((quadrant[i] != MIDDLE) && (fabs(dir[i]) > getVecEpsilon()) ) { - maxT[i] = (candPlane[i] - origin[i]) / dir[i]; - } else { - maxT[i] = -1; - } - } - - /* largest max t */ - whichPlane = 0; - for(int i=1;i<NUMDIM;i++) { - if(maxT[whichPlane] < maxT[i]) whichPlane = i; - } - - /* check final candidate */ - hit = true; - if(maxT[whichPlane] >= 0.0) { - - for(int i=0;i<NUMDIM;i++) { - if(whichPlane != i) { - coord[i] = origin[i] + maxT[whichPlane] * dir[i]; - if( (coord[i] < mStart[i]-getVecEpsilon() ) || - (coord[i] > mEnd[i] +getVecEpsilon() ) ) { - /* no hit... */ - hit = false; - } - } - else { - coord[i] = candPlane[i]; - } - } - - /* AABB hit... */ - if( hit ) { - t = maxT[whichPlane]; - if(quadrant[whichPlane]==RIGHT) normal[whichPlane] = 1.0; - else normal[whichPlane] = -1.0; - } - } - - - } else { - /* inside AABB... */ - t = 0.0; - coord = origin; - return; - } - - if(t == GFX_REAL_MAX) t = -1.0; - retnormal = normal; - retcoord = coord; -} - -//! intersect ray with AABB -void ntlRay::intersectBackAABB(ntlVec3Gfx mStart, ntlVec3Gfx mEnd, gfxReal &t, ntlVec3Gfx &retnormal,ntlVec3Gfx &retcoord) const -{ - char hit = false; /* ray hits box? */ - int whichPlane; /* intersection plane */ - gfxReal candPlane[NUMDIM]; /* candidate plane */ - gfxReal quadrant[NUMDIM]; /* quadrants */ - gfxReal maxT[NUMDIM]; /* max intersection T for planes */ - ntlVec3Gfx coord; /* intersection point */ - ntlVec3Gfx dir = mDirection; - ntlVec3Gfx origin = mOrigin; - ntlVec3Gfx normal(0.0, 0.0, 0.0); - - t = GFX_REAL_MAX; - for(int i=0;i<NUMDIM;i++) { - if(origin[i] < mStart[i]) { - quadrant[i] = LEFT; - candPlane [i] = mEnd[i]; - } else if(origin[i] > mEnd[i]) { - quadrant[i] = RIGHT; - candPlane[i] = mStart[i]; - } else { - if(dir[i] > 0) { - quadrant[i] = LEFT; - candPlane [i] = mEnd[i]; - } else - if(dir[i] < 0) { - quadrant[i] = RIGHT; - candPlane[i] = mStart[i]; - } else { - quadrant[i] = MIDDLE; - } - } - } - - - /* get t distances to planes */ - /* treat too small direction components as paralell */ - for(int i=0;i<NUMDIM;i++) { - if((quadrant[i] != MIDDLE) && (fabs(dir[i]) > getVecEpsilon()) ) { - maxT[i] = (candPlane[i] - origin[i]) / dir[i]; - } else { - maxT[i] = GFX_REAL_MAX; - } - } - - /* largest max t */ - whichPlane = 0; - for(int i=1;i<NUMDIM;i++) { - if(maxT[whichPlane] > maxT[i]) whichPlane = i; - } - - /* check final candidate */ - hit = true; - if(maxT[whichPlane] != GFX_REAL_MAX) { - - for(int i=0;i<NUMDIM;i++) { - if(whichPlane != i) { - coord[i] = origin[i] + maxT[whichPlane] * dir[i]; - if( (coord[i] < mStart[i]-getVecEpsilon() ) || - (coord[i] > mEnd[i] +getVecEpsilon() ) ) { - /* no hit... */ - hit = false; - } - } - else { - coord[i] = candPlane[i]; - } - } - - /* AABB hit... */ - if( hit ) { - t = maxT[whichPlane]; - - if(quadrant[whichPlane]==RIGHT) normal[whichPlane] = 1.0; - else normal[whichPlane] = -1.0; - } - } - - - if(t == GFX_REAL_MAX) t = -1.0; - retnormal = normal; - retcoord = coord; -} -#endif // ELBEEM_PLUGIN - -//! intersect ray with AABB -void ntlRay::intersectCompleteAABB(ntlVec3Gfx mStart, ntlVec3Gfx mEnd, gfxReal &tmin, gfxReal &tmax) const -{ - // char inside = true; /* inside box? */ /* UNUSED */ - char hit = false; /* ray hits box? */ - int whichPlane; /* intersection plane */ - gfxReal candPlane[NUMDIM]; /* candidate plane */ - gfxReal quadrant[NUMDIM]; /* quadrants */ - gfxReal maxT[NUMDIM]; /* max intersection T for planes */ - ntlVec3Gfx coord; /* intersection point */ - ntlVec3Gfx dir = mDirection; - ntlVec3Gfx origin = mOrigin; - gfxReal t = GFX_REAL_MAX; - - /* check intersection planes for AABB */ - for(int i=0;i<NUMDIM;i++) { - if(origin[i] < mStart[i]) { - quadrant[i] = LEFT; - candPlane [i] = mStart[i]; - // inside = false; - } else if(origin[i] > mEnd[i]) { - quadrant[i] = RIGHT; - candPlane[i] = mEnd[i]; - // inside = false; - } else { - /* intersect with backside */ - if(dir[i] > 0) { - quadrant[i] = LEFT; - candPlane [i] = mStart[i]; - } else - if(dir[i] < 0) { - quadrant[i] = RIGHT; - candPlane[i] = mEnd[i]; - } else { - quadrant[i] = MIDDLE; - } - } - } - - /* get t distances to planes */ - for(int i=0;i<NUMDIM;i++) { - if((quadrant[i] != MIDDLE) && (fabs(dir[i]) > getVecEpsilon()) ) { - maxT[i] = (candPlane[i] - origin[i]) / dir[i]; - } else { - maxT[i] = GFX_REAL_MAX; - } - } - - /* largest max t */ - whichPlane = 0; - for(int i=1;i<NUMDIM;i++) { - if( ((maxT[whichPlane] < maxT[i])&&(maxT[i]!=GFX_REAL_MAX)) || - (maxT[whichPlane]==GFX_REAL_MAX) ) - whichPlane = i; - } - - /* check final candidate */ - hit = true; - if(maxT[whichPlane]<GFX_REAL_MAX) { - for(int i=0;i<NUMDIM;i++) { - if(whichPlane != i) { - coord[i] = origin[i] + maxT[whichPlane] * dir[i]; - if( (coord[i] < mStart[i]-getVecEpsilon() ) || - (coord[i] > mEnd[i] +getVecEpsilon() ) ) { - /* no hit... */ - hit = false; - } - } - else { coord[i] = candPlane[i]; } - } - - /* AABB hit... */ - if( hit ) { - t = maxT[whichPlane]; - } - } - tmin = t; - - /* now the backside */ - t = GFX_REAL_MAX; - for(int i=0;i<NUMDIM;i++) { - if(origin[i] < mStart[i]) { - quadrant[i] = LEFT; - candPlane [i] = mEnd[i]; - } else if(origin[i] > mEnd[i]) { - quadrant[i] = RIGHT; - candPlane[i] = mStart[i]; - } else { - if(dir[i] > 0) { - quadrant[i] = LEFT; - candPlane [i] = mEnd[i]; - } else - if(dir[i] < 0) { - quadrant[i] = RIGHT; - candPlane[i] = mStart[i]; - } else { - quadrant[i] = MIDDLE; - } - } - } - - - /* get t distances to planes */ - for(int i=0;i<NUMDIM;i++) { - if((quadrant[i] != MIDDLE) && (fabs(dir[i]) > getVecEpsilon()) ) { - maxT[i] = (candPlane[i] - origin[i]) / dir[i]; - } else { - maxT[i] = GFX_REAL_MAX; - } - } - - /* smallest max t */ - whichPlane = 0; - for(int i=1;i<NUMDIM;i++) { - if(maxT[whichPlane] > maxT[i]) whichPlane = i; - } - - /* check final candidate */ - hit = true; - if(maxT[whichPlane] != GFX_REAL_MAX) { - - for(int i=0;i<NUMDIM;i++) { - if(whichPlane != i) { - coord[i] = origin[i] + maxT[whichPlane] * dir[i]; - if( (coord[i] < mStart[i]-getVecEpsilon() ) || - (coord[i] > mEnd[i] +getVecEpsilon() ) ) { - /* no hit... */ - hit = false; - } - } - else { - coord[i] = candPlane[i]; - } - } - - /* AABB hit... */ - if( hit ) { - t = maxT[whichPlane]; - } - } - - tmax = t; -} - - - -/****************************************************************************** - * Determine color of this ray by tracing through the scene - *****************************************************************************/ -const ntlColor ntlRay::shade() //const -{ -#ifndef ELBEEM_PLUGIN - ntlGeometryObject *closest = NULL; - gfxReal minT = GFX_REAL_MAX; - vector<ntlLightObject*> *lightlist = mpGlob->getLightList(); - mpGlob->setCounterShades( mpGlob->getCounterShades()+1 ); - bool intersectionInside = 0; - if(mpGlob->getDebugOut() > 5) errorOut(std::endl<<"New Ray: depth "<<mDepth<<", org "<<mOrigin<<", dir "<<mDirection ); - - /* check if this ray contributes enough */ - if(mContribution <= RAY_MINCONTRIB) { - //return ntlColor(0.0); - } - - /* find closes object that intersects */ - ntlTriangle *tri = NULL; - ntlVec3Gfx normal; - mpGlob->getRenderScene()->intersectScene(*this, minT, normal, tri, 0); - if(minT>0) { - closest = mpGlob->getRenderScene()->getObject( tri->getObjectId() ); - } - - /* object hit... */ - if (closest != NULL) { - - ntlVec3Gfx triangleNormal = tri->getNormal(); - if( equal(triangleNormal, ntlVec3Gfx(0.0)) ) errorOut("ntlRay warning: trinagle normal= 0 "); // DEBUG - /* intersection on inside faces? if yes invert normal afterwards */ - gfxReal valDN; // = mDirection | normal; - valDN = dot(mDirection, triangleNormal); - if( valDN > 0.0) { - intersectionInside = 1; - normal = normal * -1.0; - triangleNormal = triangleNormal * -1.0; - } - - /* ... -> do reflection */ - ntlVec3Gfx intersectionPosition(mOrigin + (mDirection * (minT)) ); - ntlMaterial *clossurf = closest->getMaterial(); - /*if(mpGlob->getDebugOut() > 5) { - errorOut("Ray hit: at "<<intersectionPosition<<" n:"<<normal<<" dn:"<<valDN<<" ins:"<<intersectionInside<<" cl:"<<((unsigned int)closest) ); - errorOut(" t1:"<<mpGlob->getRenderScene()->getVertex(tri->getPoints()[0])<<" t2:"<<mpGlob->getRenderScene()->getVertex(tri->getPoints()[1])<<" t3:"<<mpGlob->getScene()->getVertex(tri->getPoints()[2]) ); - errorOut(" trin:"<<tri->getNormal() ); - } // debug */ - - /* current transparence and reflectivity */ - gfxReal currTrans = clossurf->getTransparence(); - gfxReal currRefl = clossurf->getMirror(); - - /* correct intersectopm position */ - intersectionPosition += ( triangleNormal*getVecEpsilon() ); - /* reflection at normal */ - ntlVec3Gfx reflectedDir = getNormalized( reflectVector(mDirection, normal) ); - int badRefl = 0; - if(dot(reflectedDir, triangleNormal)<0.0 ) { - badRefl = 1; - if(mpGlob->getDebugOut() > 5) { errorOut("Ray Bad reflection...!"); } - } - - /* refraction direction, depending on in/outside hit */ - ntlVec3Gfx refractedDir; - int refRefl = 0; - /* refraction at normal is handled by inverting normal before */ - gfxReal myRefIndex = 1.0; - if((currTrans>RAY_THRESHOLD)||(clossurf->getFresnel())) { - if(intersectionInside) { - myRefIndex = 1.0/clossurf->getRefracIndex(); - } else { - myRefIndex = clossurf->getRefracIndex(); - } - - refractedDir = refractVector(mDirection, normal, myRefIndex , (gfxReal)(1.0) /* global ref index */, refRefl); - } - - /* calculate fresnel? */ - if(clossurf->getFresnel()) { - // for total reflection, just set trans to 0 - if(refRefl) { - currRefl = 1.0; currTrans = 0.0; - } else { - // calculate fresnel coefficients - clossurf->calculateFresnel( mDirection, normal, myRefIndex, currRefl,currTrans ); - } - } - - ntlRay reflectedRay(intersectionPosition, reflectedDir, mDepth+1, mContribution*currRefl, mpGlob); - reflectedRay.setNormal( normal ); - ntlColor currentColor(0.0); - ntlColor highlightColor(0.0); - - /* first add reflected ambient color */ - currentColor += (clossurf->getAmbientRefl() * mpGlob->getAmbientLight() ); - - /* calculate lighting, not on the insides of objects... */ - if(!intersectionInside) { - for (vector<ntlLightObject*>::iterator iter = lightlist->begin(); - iter != lightlist->end(); - iter++) { - - /* let light illuminate point */ - currentColor += (*iter)->illuminatePoint( reflectedRay, closest, highlightColor ); - - } // for all lights - } - - // recurse ? - if ((mDepth < mpGlob->getRayMaxDepth() )&&(currRefl>RAY_THRESHOLD)) { - - if(badRefl) { - ntlVec3Gfx intersectionPosition2; - ntlGeometryObject *closest2 = NULL; - gfxReal minT2 = GFX_REAL_MAX; - ntlTriangle *tri2 = NULL; - ntlVec3Gfx normal2; - - ntlVec3Gfx refractionPosition2(mOrigin + (mDirection * minT) ); - refractionPosition2 -= (triangleNormal*getVecEpsilon() ); - - ntlRay reflectedRay2 = ntlRay(refractionPosition2, reflectedDir, mDepth+1, mContribution*currRefl, mpGlob); - mpGlob->getRenderScene()->intersectScene(reflectedRay2, minT2, normal2, tri2, 0); - if(minT2>0) { - closest2 = mpGlob->getRenderScene()->getObject( tri2->getObjectId() ); - } - - /* object hit... */ - if (closest2 != NULL) { - ntlVec3Gfx triangleNormal2 = tri2->getNormal(); - gfxReal valDN2; - valDN2 = dot(reflectedDir, triangleNormal2); - if( valDN2 > 0.0) { - triangleNormal2 = triangleNormal2 * -1.0; - intersectionPosition2 = ntlVec3Gfx(intersectionPosition + (reflectedDir * (minT2)) ); - /* correct intersection position and create new reflected ray */ - intersectionPosition2 += ( triangleNormal2*getVecEpsilon() ); - reflectedRay = ntlRay(intersectionPosition2, reflectedDir, mDepth+1, mContribution*currRefl, mpGlob); - } else { - // ray seems to work, continue normally ? - } - - } - - } - - // add mirror color multiplied by mirror factor of surface - if(mpGlob->getDebugOut() > 5) errorOut("Reflected ray from depth "<<mDepth<<", dir "<<reflectedDir ); - ntlColor reflectedColor = reflectedRay.shade() * currRefl; - currentColor += reflectedColor; - } - - /* Trace another ray on for transparent objects */ - if(currTrans > RAY_THRESHOLD) { - /* position at the other side of the surface, along ray */ - ntlVec3Gfx refraction_position(mOrigin + (mDirection * minT) ); - refraction_position += (mDirection * getVecEpsilon()); - refraction_position -= (triangleNormal*getVecEpsilon() ); - ntlColor refracCol(0.0); /* refracted color */ - - /* trace refracted ray */ - ntlRay transRay(refraction_position, refractedDir, mDepth+1, mContribution*currTrans, mpGlob); - transRay.setRefracted(1); - transRay.setNormal( normal ); - if(mDepth < mpGlob->getRayMaxDepth() ) { - // full reflection should make sure refracindex&fresnel are on... - if((0)||(!refRefl)) { - if(mpGlob->getDebugOut() > 5) errorOut("Refracted ray from depth "<<mDepth<<", dir "<<refractedDir ); - refracCol = transRay.shade(); - } else { - //we shouldnt reach this! - if(mpGlob->getDebugOut() > 5) errorOut("Fully reflected ray from depth "<<mDepth<<", dir "<<reflectedDir ); - refracCol = reflectedRay.shade(); - } - } - //errMsg("REFMIR","t"<<currTrans<<" thres"<<RAY_THRESHOLD<<" mirr"<<currRefl<<" refRefl"<<refRefl<<" md"<<mDepth); - - /* calculate color */ - // use transadditive setting!? - /* additive transparency "light amplification" */ - //? ntlColor add_col = currentColor + refracCol * currTrans; - /* mix additive and subtractive */ - //? add_col += sub_col; - //? currentColor += (refracCol * currTrans); - - /* subtractive transparency, more realistic */ - ntlColor sub_col = (refracCol * currTrans) + ( currentColor * (1.0-currTrans) ); - currentColor = sub_col; - - } - - /* add highlights (should not be affected by transparence as the diffuse reflections */ - currentColor += highlightColor; - - /* attentuate as a last step*/ - /* check if we're on the inside or outside */ - if(intersectionInside) { - gfxReal kr,kg,kb; /* attentuation */ - /* calculate attentuation */ - ntlColor attCol = clossurf->getTransAttCol(); - kr = exp( attCol[0] * minT ); - kg = exp( attCol[1] * minT ); - kb = exp( attCol[2] * minT ); - currentColor = currentColor * ntlColor(kr,kg,kb); - } - - /* done... */ - if(mpGlob->getDebugOut() > 5) { errorOut("Ray "<<mDepth<<" color "<<currentColor ); } - return ntlColor(currentColor); - } - -#endif // ELBEEM_PLUGIN - /* no object hit -> ray goes to infinity */ - return mpGlob->getBackgroundCol(); -} - - - -/****************************************************************************** - ****************************************************************************** - ****************************************************************************** - * scene implementation - ****************************************************************************** - ****************************************************************************** - *****************************************************************************/ - - - -/****************************************************************************** - * Constructor - *****************************************************************************/ -ntlScene::ntlScene( ntlRenderGlobals *glob, bool del ) : - mpGlob( glob ), mSceneDel(del), - mpTree( NULL ), - mSceneBuilt( false ), mFirstInitDone( false ) -{ -} - - -/****************************************************************************** - * Destructor - *****************************************************************************/ -ntlScene::~ntlScene() -{ - if(mpTree != NULL) delete mpTree; - - // cleanup lists, only if this is the rendering cleanup scene - if(mSceneDel) - { - for (vector<ntlGeometryClass*>::iterator iter = mGeos.begin(); - iter != mGeos.end(); iter++) { - //errMsg("ntlScene::~ntlScene","Deleting obj "<<(*iter)->getName() ); - delete (*iter); - } - for (vector<ntlLightObject*>::iterator iter = mpGlob->getLightList()->begin(); - iter != mpGlob->getLightList()->end(); iter++) { - delete (*iter); - } - for (vector<ntlMaterial*>::iterator iter = mpGlob->getMaterials()->begin(); - iter != mpGlob->getMaterials()->end(); iter++) { - delete (*iter); - } - } - errMsg("ntlScene::~ntlScene","Deleted, ObjFree:"<<mSceneDel); -} - - -/****************************************************************************** - * Build the scene arrays (obj, tris etc.) - *****************************************************************************/ -void ntlScene::buildScene(double time,bool firstInit) -{ - const bool buildInfo=true; - - if(firstInit) { - mObjects.clear(); - /* init geometry array, first all standard objects */ - for (vector<ntlGeometryClass*>::iterator iter = mGeos.begin(); - iter != mGeos.end(); iter++) { - bool geoinit = false; - int tid = (*iter)->getTypeId(); - if(tid & GEOCLASSTID_OBJECT) { - ntlGeometryObject *geoobj = (ntlGeometryObject*)(*iter); - geoinit = true; - mObjects.push_back( geoobj ); - if(buildInfo) debMsgStd("ntlScene::BuildScene",DM_MSG,"added GeoObj "<<geoobj->getName()<<" Id:"<<geoobj->getObjectId(), 5 ); - } - //if(geoshad) { - if(tid & GEOCLASSTID_SHADER) { - ntlGeometryShader *geoshad = (ntlGeometryShader*)(*iter); - geoinit = true; - if(!mFirstInitDone) { - // only on first init - geoshad->initializeShader(); - } - for (vector<ntlGeometryObject*>::iterator siter = geoshad->getObjectsBegin(); - siter != geoshad->getObjectsEnd(); - siter++) { - if(buildInfo) debMsgStd("ntlScene::BuildScene",DM_MSG,"added shader geometry "<<(*siter)->getName()<<" Id:"<<(*siter)->getObjectId(), 5 ); - mObjects.push_back( (*siter) ); - } - } - - if(!geoinit) { - errFatal("ntlScene::BuildScene","Invalid geometry class!", SIMWORLD_INITERROR); - return; - } - } - } - - // collect triangles - mTriangles.clear(); - mVertices.clear(); - mVertNormals.clear(); - - /* for test mode deactivate transparencies etc. */ - if( mpGlob->getTestMode() ) { - debugOut("ntlScene::buildScene : Test Mode activated!", 2); - // assign random colors to dark materials - int matCounter = 0; - ntlColor stdCols[] = { ntlColor(0,0,1.0), ntlColor(0,1.0,0), ntlColor(1.0,0.7,0) , ntlColor(0.7,0,0.6) }; - int stdColNum = 4; - for (vector<ntlMaterial*>::iterator iter = mpGlob->getMaterials()->begin(); - iter != mpGlob->getMaterials()->end(); iter++) { - (*iter)->setTransparence(0.0); - (*iter)->setMirror(0.0); - (*iter)->setFresnel(false); - // too dark? - if( norm((*iter)->getDiffuseRefl()) <0.01) { - (*iter)->setDiffuseRefl( stdCols[matCounter] ); - matCounter ++; - matCounter = matCounter%stdColNum; - } - } - - // restrict output file size to 400 - float downscale = 1.0; - if(mpGlob->getResX() > 400){ downscale = 400.0/(float)mpGlob->getResX(); } - if(mpGlob->getResY() > 400){ - float downscale2 = 400.0/(float)mpGlob->getResY(); - if(downscale2<downscale) downscale=downscale2; - } - mpGlob->setResX( (int)(mpGlob->getResX() * downscale) ); - mpGlob->setResY( (int)(mpGlob->getResY() * downscale) ); - - } - - /* collect triangles from objects */ - int idCnt = 0; // give IDs to objects - bool debugTriCollect = false; - if(debugTriCollect) debMsgStd("ntlScene::buildScene",DM_MSG,"Start...",5); - for (vector<ntlGeometryObject*>::iterator iter = mObjects.begin(); - iter != mObjects.end(); - iter++) { - /* only add visible objects */ - if(firstInit) { - if(debugTriCollect) debMsgStd("ntlScene::buildScene",DM_MSG,"Collect init of "<<(*iter)->getName()<<" idCnt:"<<idCnt, 4 ); - (*iter)->initialize( mpGlob ); } - if(debugTriCollect) debMsgStd("ntlScene::buildScene",DM_MSG,"Collecting tris from "<<(*iter)->getName(), 4 ); - - int vstart = mVertNormals.size(); - (*iter)->setObjectId(idCnt); - (*iter)->getTriangles(time, &mTriangles, &mVertices, &mVertNormals, idCnt); - (*iter)->applyTransformation(time, &mVertices, &mVertNormals, vstart, mVertices.size(), false ); - - if(debugTriCollect) debMsgStd("ntlScene::buildScene",DM_MSG,"Done with "<<(*iter)->getName()<<" totTris:"<<mTriangles.size()<<" totVerts:"<<mVertices.size()<<" totNorms:"<<mVertNormals.size(), 4 ); - idCnt ++; - } - if(debugTriCollect) debMsgStd("ntlScene::buildScene",DM_MSG,"End",5); - - - /* calculate triangle normals, and initialize flags */ - for (vector<ntlTriangle>::iterator iter = mTriangles.begin(); - iter != mTriangles.end(); - iter++) { - - // calculate normal from triangle points - ntlVec3Gfx normal = - cross( (ntlVec3Gfx)( (mVertices[(*iter).getPoints()[2]] - mVertices[(*iter).getPoints()[0]]) *-1.0), // BLITZ minus sign right?? - (ntlVec3Gfx)(mVertices[(*iter).getPoints()[1]] - mVertices[(*iter).getPoints()[0]]) ); - normalize(normal); - (*iter).setNormal( normal ); - } - - - - // scene geometry built - mSceneBuilt = true; - - // init shaders that require complete geometry - if(!mFirstInitDone) { - // only on first init - for (vector<ntlGeometryClass*>::iterator iter = mGeos.begin(); - iter != mGeos.end(); iter++) { - if( (*iter)->getTypeId() & GEOCLASSTID_SHADER ) { - ntlGeometryShader *geoshad = (ntlGeometryShader*)(*iter); - if(geoshad->postGeoConstrInit( mpGlob )) { - errFatal("ntlScene::buildScene","Init failed for object '"<< (*iter)->getName() <<"' !", SIMWORLD_INITERROR ); - return; - } - } - } - mFirstInitDone = true; - } - - // check unused attributes (for classes and objects!) - for (vector<ntlGeometryObject*>::iterator iter = mObjects.begin(); iter != mObjects.end(); iter++) { - if((*iter)->getAttributeList()->checkUnusedParams()) { - (*iter)->getAttributeList()->print(); // DEBUG - errFatal("ntlScene::buildScene","Unused params for object '"<< (*iter)->getName() <<"' !", SIMWORLD_INITERROR ); - return; - } - } - for (vector<ntlGeometryClass*>::iterator iter = mGeos.begin(); iter != mGeos.end(); iter++) { - if((*iter)->getAttributeList()->checkUnusedParams()) { - (*iter)->getAttributeList()->print(); // DEBUG - errFatal("ntlScene::buildScene","Unused params for object '"<< (*iter)->getName() <<"' !", SIMWORLD_INITERROR ); - return; - } - } - -} - -/****************************************************************************** - * Prepare the scene triangles and maps for raytracing - *****************************************************************************/ -void ntlScene::prepareScene(double time) -{ - /* init triangles... */ - buildScene(time, false); - // what for currently not used ??? - if(mpTree != NULL) delete mpTree; - mpTree = new ntlTree( -# if FSGR_STRICT_DEBUG!=1 - mpGlob->getTreeMaxDepth(), mpGlob->getTreeMaxTriangles(), -# else - mpGlob->getTreeMaxDepth()/3*2, mpGlob->getTreeMaxTriangles()*2, -# endif - this, TRI_GEOMETRY ); - - //debMsgStd("ntlScene::prepareScene",DM_MSG,"Stats - tris:"<< (int)mTriangles.size()<<" verts:"<<mVertices.size()<<" vnorms:"<<mVertNormals.size(), 5 ); -} -/****************************************************************************** - * Do some memory cleaning, when frame is finished - *****************************************************************************/ -void ntlScene::cleanupScene( void ) -{ - mTriangles.clear(); - mVertices.clear(); - mVertNormals.clear(); - - if(mpTree != NULL) delete mpTree; - mpTree = NULL; -} - - -/****************************************************************************** - * Intersect a ray with the scene triangles - *****************************************************************************/ -void ntlScene::intersectScene(const ntlRay &r, gfxReal &distance, ntlVec3Gfx &normal, ntlTriangle *&tri,int flags) const -{ - distance = -1.0; - mpGlob->setCounterSceneInter( mpGlob->getCounterSceneInter()+1 ); - mpTree->intersect(r, distance, normal, tri, flags, false); -} - - - - - diff --git a/intern/elbeem/intern/ntl_ray.h b/intern/elbeem/intern/ntl_ray.h deleted file mode 100644 index 064fce27059..00000000000 --- a/intern/elbeem/intern/ntl_ray.h +++ /dev/null @@ -1,438 +0,0 @@ -/** \file - * \ingroup elbeem - */ -/****************************************************************************** - * - * El'Beem - Free Surface Fluid Simulation with the Lattice Boltzmann Method - * Copyright 2003-2006 Nils Thuerey - * - * ray class - * - *****************************************************************************/ -#ifndef NTL_RAY_H -#define NTL_RAY_H - -#include <sstream> -#include "ntl_vector3dim.h" -#include "ntl_lighting.h" -#include "ntl_geometryobject.h" -#include "ntl_bsptree.h" - -#ifdef WITH_CXX_GUARDEDALLOC -# include "MEM_guardedalloc.h" -#endif - -class ntlTriangle; -class ntlRay; -class ntlTree; -class ntlScene; -class ntlRenderGlobals; -class ntlGeometryObject; - -//! store data for an intersection of a ray and a triangle -// NOT YET USED -class ntlIntersection { - public: - - ntlIntersection() : - distance(-1.0), normal(0.0), - ray(NULL), tri(NULL), flags(0) { }; - - gfxReal distance; - ntlVec3Gfx normal; - ntlRay *ray; - ntlTriangle *tri; - char flags; - -private: -#ifdef WITH_CXX_GUARDEDALLOC - MEM_CXX_CLASS_ALLOC_FUNCS("ELBEEM:ntlIntersection") -#endif -}; - -//! the main ray class -class ntlRay -{ -public: - // CONSTRUCTORS - //! Initialize ray memebers, prints error message - ntlRay(); - //! Copy constructor, copy all members - ntlRay(const ntlRay &r); - //! Explicitly init member variables with global render object - ntlRay(const ntlVec3Gfx &o, const ntlVec3Gfx &d, unsigned int i, gfxReal contrib, ntlRenderGlobals *glob); - //! Destructor - ~ntlRay(); - - //! Set the refraction flag for refracted rays - inline void setRefracted(unsigned char set) { mIsRefracted = set; } - inline void setReflected(unsigned char set) { mIsReflected = set; } - - //! main ray recursion function - /*! - * First get closest object intersection, return background color if nothing - * was hit, else calculate shading and reflection components - * and return mixed color */ - const ntlColor shade() /*const*/; - - /*! Trace a photon through the scene */ - void tracePhoton(ntlColor) const; - - //! intersect ray with AABB - void intersectFrontAABB(ntlVec3Gfx mStart, ntlVec3Gfx mEnd, gfxReal &t, ntlVec3Gfx &normal, ntlVec3Gfx &retcoord) const; - void intersectBackAABB(ntlVec3Gfx mStart, ntlVec3Gfx mEnd, gfxReal &t, ntlVec3Gfx &normal, ntlVec3Gfx &retcoord) const; - void intersectCompleteAABB(ntlVec3Gfx mStart, ntlVec3Gfx mEnd, gfxReal &tmin, gfxReal &tmax) const; - // intersection routines in bsptree.cpp - //! optimized intersect ray with triangle - inline void intersectTriangle(vector<ntlVec3Gfx> *mpV, ntlTriangle *tri, gfxReal &t, gfxReal &u, gfxReal &v) const; - //! optimized intersect ray with triangle along +X axis dir - inline void intersectTriangleX(vector<ntlVec3Gfx> *mpV, ntlTriangle *tri, gfxReal &t, gfxReal &u, gfxReal &v) const; - //! intersect only with front side - inline void intersectTriangleFront(vector<ntlVec3Gfx> *mpV, ntlTriangle *tri, gfxReal &t, gfxReal &u, gfxReal &v) const; - //! intersect ray only with backsides - inline void intersectTriangleBack(vector<ntlVec3Gfx> *mpV, ntlTriangle *tri, gfxReal &t, gfxReal &u, gfxReal &v) const; - - // access methods - //! Returns the ray origin - inline ntlVec3Gfx getOrigin() const { return ntlVec3Gfx(mOrigin); } - //! Returns the ray direction - inline ntlVec3Gfx getDirection() const { return ntlVec3Gfx(mDirection); } - /*! Returns the ray relfection normal */ - inline ntlVec3Gfx getNormal() const { return ntlVec3Gfx(mvNormal); } - //! Is this ray refracted? - inline unsigned char getRefracted() const { return mIsRefracted; } - inline unsigned char getReflected() const { return mIsReflected; } - /*! Get position along ray */ - inline ntlVec3Gfx getPositionAt(gfxReal t) const { return (mOrigin+(mDirection*t)); } - /*! Get render globals pointer of this ray */ - inline ntlRenderGlobals *getRenderglobals( void ) const { return mpGlob; } - /*! get this ray's ID */ - inline int getID( void ) const { return mID; } - - /*! Set origin of this ray */ - inline void setOrigin(ntlVec3Gfx set) { mOrigin = set; } - /*! Set direction of this ray */ - inline void setDirection(ntlVec3Gfx set) { mDirection = set; } - /*! Set normal of this ray */ - inline void setNormal(ntlVec3Gfx set) { mvNormal = set; } - -protected: - /* Calulates the Lambertian and Specular color for - * the given reflection and returns it */ - const ntlColor getShadedColor(ntlLightObject *light, const ntlRay &reflectedray, - const ntlVec3Gfx &normal, ntlMaterial *surf) const; - -private: - /*! Origin of ray */ - ntlVec3Gfx mOrigin; - /*! Normalized direction vector of ray */ - ntlVec3Gfx mDirection; - /*! For reflected/refracted rays, the normal is stored here */ - ntlVec3Gfx mvNormal; - /*! recursion depth */ - unsigned int mDepth; - /*! How much does this ray contribute to the surface color? abort if too small */ - gfxReal mContribution; - - /*! Global rendering settings */ - ntlRenderGlobals *mpGlob; - - /*! If this ray is a refracted one, this flag has to be set - * This is necessary to for example also give the background color - * to refracted rays. Otherwise things may look strange... - */ - unsigned char mIsRefracted; - unsigned char mIsReflected; - - /*! ID of this ray (from renderglobals */ - int mID; - -private: -#ifdef WITH_CXX_GUARDEDALLOC - MEM_CXX_CLASS_ALLOC_FUNCS("ELBEEM:ntlRay") -#endif -}; - - -/****************************************************************************** - * - * a single triangle - * - *****************************************************************************/ - -// triangle intersection code in bsptree.cpp -// intersectTriangle(vector<ntlVec3Gfx> *mpV, ntlTriangle *tri, gfxReal &t, gfxReal &u, gfxReal &v); - -/*! Triangle flag defines */ -#define TRI_GEOMETRY (1<<0) -#define TRI_CASTSHADOWS (1<<1) - - -class ntlTriangle -{ -public: - /* CONSTRUCTORS */ - /*! Default constructor */ - inline ntlTriangle( void ); - /*! Constructor with parameters */ - inline ntlTriangle(int *p, bool smooth, int obj, ntlVec3Gfx norm, int setflags); - /*! Copy - Constructor */ - inline ntlTriangle(const ntlTriangle &tri); - /*! Destructor */ - inline ~ntlTriangle() {} - - /* Access methods */ - - /*! Acces to points of triangle */ - inline int *getPoints( void ) { return mPoints; } - /*! Acces normal smoothing */ - inline bool getSmoothNormals( void ) const { return mSmoothNormals; } - inline void setSmoothNormals( bool set){ mSmoothNormals = set; } - /*! Access object */ - inline int getObjectId( void ) const { return mObjectId; } - inline void setObjectId( int set) { mObjectId = set; } - /*! Acces normal index */ - inline ntlVec3Gfx getNormal( void ) const { return mNormal; } - inline void setNormal( ntlVec3Gfx set ) { mNormal = set; } - /*! Acces flags */ - inline int getFlags( void ) const { return mFlags; } - inline void setFlags( int set ) { mFlags = set; } - /*! Access last intersection ray ID */ - inline int getLastRay( void ) const { return mLastRay; } - inline void setLastRay( int set ) { mLastRay = set; } - /*! Acces bbox id */ - inline int getBBoxId( void ) const { return mBBoxId; } - inline void setBBoxId( int set ) { mBBoxId = set; } - - /*! Get average of the three points for this axis */ - inline gfxReal getAverage( int axis ) const; - - /*! operator < for sorting, uses global sorting axis */ - inline friend bool operator<(const ntlTriangle &lhs, const ntlTriangle &rhs); - /*! operator > for sorting, uses global sorting axis */ - inline friend bool operator>(const ntlTriangle &lhs, const ntlTriangle &rhs); - -protected: - -private: - - /*! indices to the three points of the triangle */ - int mPoints[3]; - - /*! bounding box id (for tree generation), -1 if invalid */ - int mBBoxId; - - /*! Should the normals of this triangle get smoothed? */ - bool mSmoothNormals; - - /*! Id of parent object */ - int mObjectId; - - /*! Index to normal (for not smooth triangles) */ - //int mNormalIndex; ?? - ntlVec3Gfx mNormal; - - /*! Flags for object attributes cast shadows */ - int mFlags; - - /*! ID of last ray that an intersection was calculated for */ - int mLastRay; - -private: -#ifdef WITH_CXX_GUARDEDALLOC - MEM_CXX_CLASS_ALLOC_FUNCS("ELBEEM:ntlTriangle") -#endif -}; - - - - -/****************************************************************************** - * Default Constructor - *****************************************************************************/ -ntlTriangle::ntlTriangle( void ) : - mBBoxId(-1), - mLastRay( 0 ) -{ - mPoints[0] = mPoints[1] = mPoints[2] = 0; - mSmoothNormals = 0; - mObjectId = 0; - mNormal = ntlVec3Gfx(0.0); - mFlags = 0; -} - - -/****************************************************************************** - * Constructor - *****************************************************************************/ -ntlTriangle::ntlTriangle(int *p, bool smooth, int obj, ntlVec3Gfx norm, int setflags) : - mBBoxId(-1), - mLastRay( 0 ) -{ - mPoints[0] = p[0]; - mPoints[1] = p[1]; - mPoints[2] = p[2]; - mSmoothNormals = smooth; - mObjectId = obj; - mNormal = norm; - mFlags = setflags; -} - - -/****************************************************************************** - * Copy Constructor - *****************************************************************************/ -ntlTriangle::ntlTriangle(const ntlTriangle &tri) : - mBBoxId(-1), - mLastRay( 0 ) -{ - mPoints[0] = tri.mPoints[0]; - mPoints[1] = tri.mPoints[1]; - mPoints[2] = tri.mPoints[2]; - mSmoothNormals = tri.mSmoothNormals; - mObjectId = tri.mObjectId; - mNormal = tri.mNormal; - mFlags = tri.mFlags; -} - - - - -/****************************************************************************** - * Triangle sorting functions - *****************************************************************************/ - -/* variables imported from ntl_bsptree.cc, necessary for using the stl sort funtion */ -/* Static global variable for sorting direction */ -extern int globalSortingAxis; -/* Access to points array for sorting */ -extern vector<ntlVec3Gfx> *globalSortingPoints; - - -gfxReal ntlTriangle::getAverage( int axis ) const -{ - return ( ( (*globalSortingPoints)[ mPoints[0] ][axis] + - (*globalSortingPoints)[ mPoints[1] ][axis] + - (*globalSortingPoints)[ mPoints[2] ][axis] )/3.0); -} - -bool operator<(const ntlTriangle &lhs,const ntlTriangle &rhs) -{ - return ( lhs.getAverage(globalSortingAxis) < - rhs.getAverage(globalSortingAxis) ); -} - -bool operator>(const ntlTriangle &lhs,const ntlTriangle &rhs) -{ - return ( lhs.getAverage(globalSortingAxis) > - rhs.getAverage(globalSortingAxis) ); -} - - - -/****************************************************************************** - * - * Scene object, that contains and manages all geometry objects - * - *****************************************************************************/ - - - -class ntlScene -{ -public: - /* CONSTRUCTORS */ - /*! Default constructor */ - ntlScene( ntlRenderGlobals *glob, bool del=true ); - /*! Default destructor */ - ~ntlScene(); - - /*! Add an object to the scene */ - inline void addGeoClass(ntlGeometryClass *geo) { - mGeos.push_back( geo ); - geo->setObjectId(mGeos.size()); - } - /*! Add a geo object to the scene, warning - only needed for hand init */ - inline void addGeoObject(ntlGeometryObject *geo) { mObjects.push_back( geo ); } - - /*! Acces a certain object */ - inline ntlGeometryObject *getObject(int id) { - if(!mSceneBuilt) { errFatal("ntlScene::getObject","Scene not inited!", SIMWORLD_INITERROR); } - return mObjects[id]; } - - /*! Acces object array */ - inline vector<ntlGeometryObject*> *getObjects() { - if(!mSceneBuilt) { errFatal("ntlScene::getObjects[]","Scene not inited!", SIMWORLD_INITERROR); } - return &mObjects; } - - /*! Acces geo class array */ - inline vector<ntlGeometryClass*> *getGeoClasses() { - if(!mSceneBuilt) { errFatal("ntlScene::getGeoClasses[]","Scene not inited!", SIMWORLD_INITERROR); } - return &mGeos; } - - /*! draw scene with opengl */ - //void draw(); - - /*! Build/first init the scene arrays */ - void buildScene(double time, bool firstInit); - - //! Prepare the scene triangles and maps for raytracing - void prepareScene(double time); - //! Do some memory cleaning, when frame is finished - void cleanupScene( void ); - - /*! Intersect a ray with the scene triangles */ - void intersectScene(const ntlRay &r, gfxReal &distance, ntlVec3Gfx &normal, ntlTriangle *&tri, int flags) const; - - /*! return a vertex */ - ntlVec3Gfx getVertex(int index) { return mVertices[index]; } - - // for tree generation - /*! return pointer to vertices vector */ - vector<ntlVec3Gfx> *getVertexPointer( void ) { return &mVertices; } - /*! return pointer to vertices vector */ - vector<ntlVec3Gfx> *getVertexNormalPointer( void ) { return &mVertNormals; } - /*! return pointer to vertices vector */ - vector<ntlTriangle> *getTrianglePointer( void ) { return &mTriangles; } - -private: - - /*! Global settings */ - ntlRenderGlobals *mpGlob; - - /*! free objects? (only necessary for render scene, which contains all) */ - bool mSceneDel; - - /*! List of geometry classes */ - vector<ntlGeometryClass *> mGeos; - - /*! List of geometry objects */ - vector<ntlGeometryObject *> mObjects; - - /*! List of triangles */ - vector<ntlTriangle> mTriangles; - /*! List of vertices */ - vector<ntlVec3Gfx> mVertices; - /*! List of normals */ - vector<ntlVec3Gfx> mVertNormals; - /*! List of triangle normals */ - vector<ntlVec3Gfx> mTriangleNormals; - - /*! Tree to store quickly intersect triangles */ - ntlTree *mpTree; - - /*! was the scene successfully built? only then getObject(i) requests are valid */ - bool mSceneBuilt; - - /*! shader/obj initializations are only done on first init */ - bool mFirstInitDone; - -private: -#ifdef WITH_CXX_GUARDEDALLOC - MEM_CXX_CLASS_ALLOC_FUNCS("ELBEEM:ntlScene") -#endif -}; - - -#endif - diff --git a/intern/elbeem/intern/ntl_vector3dim.h b/intern/elbeem/intern/ntl_vector3dim.h deleted file mode 100644 index 51e03e30dc8..00000000000 --- a/intern/elbeem/intern/ntl_vector3dim.h +++ /dev/null @@ -1,1105 +0,0 @@ -/** \file - * \ingroup elbeem - */ -/****************************************************************************** - * - * El'Beem - Free Surface Fluid Simulation with the Lattice Boltzmann Method - * Copyright 2003-2006 Nils Thuerey - * - * Basic vector class used everywhere, either blitz or inlined GRAPA class - * - *****************************************************************************/ -#ifndef NTL_VECTOR3DIM_H -#define NTL_VECTOR3DIM_H - -// this serves as the main include file -// for all kinds of stuff that might be required -// under windows there seem to be strange -// errors when including the STL header too -// late... - -#ifdef _MSC_VER -#define _USE_MATH_DEFINES 1 -#endif - -#include <iostream> -#include <map> -#include <vector> -#include <string> -#include <sstream> -#include <math.h> -#include <string.h> -#include <stdio.h> -#include <stdlib.h> - -#ifdef WITH_CXX_GUARDEDALLOC -# include "MEM_guardedalloc.h" -#endif - -/* absolute value */ -template < class T > -inline T -ABS( T a ) -{ return (0 < a) ? a : -a ; } - -// hack for MSVC6.0 compiler -#ifdef _MSC_VER -#if _MSC_VER < 1300 -#define for if(false); else for -#define map std::map -#define vector std::vector -#define string std::string -// use this define for MSVC6 stuff hereafter -#define USE_MSVC6FIXES -#else // _MSC_VER < 1300 , 7.0 or higher -using std::map; -using std::vector; -using std::string; -#endif -#else // not MSVC6 -// for proper compilers... -using std::map; -using std::vector; -using std::string; -#endif // MSVC6 - -#ifdef __APPLE_CC__ -// apple -#else -#ifdef WIN32 - -// windows values missing, see below -#ifndef snprintf -#define snprintf _snprintf -#endif - -#ifdef _MSC_VER -#if _MSC_VER >= 1300 -#include <float.h> -#endif -#endif - -#else // WIN32 - -// floating point limits for linux,*bsd etc... -#include <float.h> - -#endif // WIN32 -#endif // __APPLE_CC__ - -// windows, hardcoded limits for now... -// for e.g. MSVC compiler... -// some of these defines can be needed -// for linux systems as well (e.g. FLT_MAX) -#ifndef __FLT_MAX__ -# ifdef FLT_MAX // try to use it instead -# define __FLT_MAX__ FLT_MAX -# else // FLT_MAX -# define __FLT_MAX__ 3.402823466e+38f -# endif // FLT_MAX -#endif // __FLT_MAX__ -#ifndef __DBL_MAX__ -# ifdef DBL_MAX // try to use it instead -# define __DBL_MAX__ DBL_MAX -# else // DBL_MAX -# define __DBL_MAX__ 1.7976931348623158e+308 -# endif // DBL_MAX -#endif // __DBL_MAX__ - -#ifndef M_PI -#define M_PI 3.1415926536 -#endif - -#ifndef M_E -#define M_E 2.7182818284 -#endif - -// make sure elbeem plugin def is valid -#if ELBEEM_BLENDER==1 -#ifndef ELBEEM_PLUGIN -#define ELBEEM_PLUGIN 1 -#endif // !ELBEEM_PLUGIN -#endif // ELBEEM_BLENDER==1 - -// make sure GUI support is disabled for plugin use -#if ELBEEM_PLUGIN==1 -#ifndef NOGUI -#define NOGUI 1 -#endif // !NOGUI -#endif // ELBEEM_PLUGIN==1 - - -// basic inlined vector class -template<class Scalar> -class ntlVector3Dim -{ -public: - // Constructor - inline ntlVector3Dim(void ); - // Copy-Constructor - inline ntlVector3Dim(const ntlVector3Dim<Scalar> &v ); - inline ntlVector3Dim(const float *); - inline ntlVector3Dim(const double *); - // construct a vector from one Scalar - inline ntlVector3Dim(Scalar); - // construct a vector from three Scalars - inline ntlVector3Dim(Scalar, Scalar, Scalar); - - // get address of array for OpenGL - Scalar *getAddress() { return value; } - - // Assignment operator - inline const ntlVector3Dim<Scalar>& operator= (const ntlVector3Dim<Scalar>& v); - // Assignment operator - inline const ntlVector3Dim<Scalar>& operator= (Scalar s); - // Assign and add operator - inline const ntlVector3Dim<Scalar>& operator+= (const ntlVector3Dim<Scalar>& v); - // Assign and add operator - inline const ntlVector3Dim<Scalar>& operator+= (Scalar s); - // Assign and sub operator - inline const ntlVector3Dim<Scalar>& operator-= (const ntlVector3Dim<Scalar>& v); - // Assign and sub operator - inline const ntlVector3Dim<Scalar>& operator-= (Scalar s); - // Assign and mult operator - inline const ntlVector3Dim<Scalar>& operator*= (const ntlVector3Dim<Scalar>& v); - // Assign and mult operator - inline const ntlVector3Dim<Scalar>& operator*= (Scalar s); - // Assign and div operator - inline const ntlVector3Dim<Scalar>& operator/= (const ntlVector3Dim<Scalar>& v); - // Assign and div operator - inline const ntlVector3Dim<Scalar>& operator/= (Scalar s); - - - // unary operator - inline ntlVector3Dim<Scalar> operator- () const; - - // binary operator add - inline ntlVector3Dim<Scalar> operator+ (const ntlVector3Dim<Scalar>&) const; - // binary operator add - inline ntlVector3Dim<Scalar> operator+ (Scalar) const; - // binary operator sub - inline ntlVector3Dim<Scalar> operator- (const ntlVector3Dim<Scalar>&) const; - // binary operator sub - inline ntlVector3Dim<Scalar> operator- (Scalar) const; - // binary operator mult - inline ntlVector3Dim<Scalar> operator* (const ntlVector3Dim<Scalar>&) const; - // binary operator mult - inline ntlVector3Dim<Scalar> operator* (Scalar) const; - // binary operator div - inline ntlVector3Dim<Scalar> operator/ (const ntlVector3Dim<Scalar>&) const; - // binary operator div - inline ntlVector3Dim<Scalar> operator/ (Scalar) const; - - // Projection normal to a vector - inline ntlVector3Dim<Scalar> getOrthogonalntlVector3Dim() const; - // Project into a plane - inline const ntlVector3Dim<Scalar>& projectNormalTo(const ntlVector3Dim<Scalar> &v); - - // minimize - inline const ntlVector3Dim<Scalar> &minimize(const ntlVector3Dim<Scalar> &); - // maximize - inline const ntlVector3Dim<Scalar> &maximize(const ntlVector3Dim<Scalar> &); - - // access operator - inline Scalar& operator[](unsigned int i); - // access operator - inline const Scalar& operator[](unsigned int i) const; - -protected: - -private: - Scalar value[3]; //< Storage of vector values - -private: -#ifdef WITH_CXX_GUARDEDALLOC - MEM_CXX_CLASS_ALLOC_FUNCS("ELBEEM:ntlVector3Dim") -#endif -}; - - - - -//------------------------------------------------------------------------------ -// STREAM FUNCTIONS -//------------------------------------------------------------------------------ - - - -//! global string for formatting vector output in utilities.cpp -extern const char *globVecFormatStr; - -/************************************************************************* - Outputs the object in human readable form using the format - [x,y,z] - */ -template<class Scalar> -std::ostream& -operator<<( std::ostream& os, const ntlVector3Dim<Scalar>& i ) -{ - char buf[256]; - snprintf(buf,256,globVecFormatStr,i[0],i[1],i[2]); - os << string(buf); - //os << '[' << i[0] << ", " << i[1] << ", " << i[2] << ']'; - return os; -} - - - -/************************************************************************* - Reads the contents of the object from a stream using the same format - as the output operator. - */ -template<class Scalar> -std::istream& -operator>>( std::istream& is, ntlVector3Dim<Scalar>& i ) -{ - char c; - char dummy[3]; - is >> c >> i[0] >> dummy >> i[1] >> dummy >> i[2] >> c; - return is; -} - - -//------------------------------------------------------------------------------ -// VECTOR inline FUNCTIONS -//------------------------------------------------------------------------------ - - - -/************************************************************************* - Constructor. - */ -template<class Scalar> -inline ntlVector3Dim<Scalar>::ntlVector3Dim( void ) -{ - value[0] = value[1] = value[2] = 0; -} - - - -/************************************************************************* - Copy-Constructor. - */ -template<class Scalar> -inline ntlVector3Dim<Scalar>::ntlVector3Dim( const ntlVector3Dim<Scalar> &v ) -{ - value[0] = v.value[0]; - value[1] = v.value[1]; - value[2] = v.value[2]; -} -template<class Scalar> -inline ntlVector3Dim<Scalar>::ntlVector3Dim( const float *fvalue) -{ - value[0] = (Scalar)fvalue[0]; - value[1] = (Scalar)fvalue[1]; - value[2] = (Scalar)fvalue[2]; -} -template<class Scalar> -inline ntlVector3Dim<Scalar>::ntlVector3Dim( const double *fvalue) -{ - value[0] = (Scalar)fvalue[0]; - value[1] = (Scalar)fvalue[1]; - value[2] = (Scalar)fvalue[2]; -} - - - -/************************************************************************* - Constructor for a vector from a single Scalar. All components of - the vector get the same value. - \param s The value to set - \return The new vector - */ -template<class Scalar> -inline ntlVector3Dim<Scalar>::ntlVector3Dim(Scalar s ) -{ - value[0]= s; - value[1]= s; - value[2]= s; -} - - -/************************************************************************* - Constructor for a vector from three Scalars. - \param s1 The value for the first vector component - \param s2 The value for the second vector component - \param s3 The value for the third vector component - \return The new vector - */ -template<class Scalar> -inline ntlVector3Dim<Scalar>::ntlVector3Dim(Scalar s1, Scalar s2, Scalar s3) -{ - value[0]= s1; - value[1]= s2; - value[2]= s3; -} - - -/************************************************************************* - Compute the vector product of two 3D vectors - \param v Second vector to compute the product with - \return A new vector with the product values - */ -/*template<class Scalar> -inline ntlVector3Dim<Scalar> -ntlVector3Dim<Scalar>::operator^( const ntlVector3Dim<Scalar> &v ) const -{ - return ntlVector3Dim<Scalar>(value[1]*v.value[2] - value[2]*v.value[1], - value[2]*v.value[0] - value[0]*v.value[2], - value[0]*v.value[1] - value[1]*v.value[0]); -}*/ - - -/************************************************************************* - Copy a ntlVector3Dim componentwise. - \param v vector with values to be copied - \return Reference to self - */ -template<class Scalar> -inline const ntlVector3Dim<Scalar>& -ntlVector3Dim<Scalar>::operator=( const ntlVector3Dim<Scalar> &v ) -{ - value[0] = v.value[0]; - value[1] = v.value[1]; - value[2] = v.value[2]; - return *this; -} - - -/************************************************************************* - Copy a Scalar to each component. - \param s The value to copy - \return Reference to self - */ -template<class Scalar> -inline const ntlVector3Dim<Scalar>& -ntlVector3Dim<Scalar>::operator=(Scalar s) -{ - value[0] = s; - value[1] = s; - value[2] = s; - return *this; -} - - -/************************************************************************* - Add another ntlVector3Dim componentwise. - \param v vector with values to be added - \return Reference to self - */ -template<class Scalar> -inline const ntlVector3Dim<Scalar>& -ntlVector3Dim<Scalar>::operator+=( const ntlVector3Dim<Scalar> &v ) -{ - value[0] += v.value[0]; - value[1] += v.value[1]; - value[2] += v.value[2]; - return *this; -} - - -/************************************************************************* - Add a Scalar value to each component. - \param s Value to add - \return Reference to self - */ -template<class Scalar> -inline const ntlVector3Dim<Scalar>& -ntlVector3Dim<Scalar>::operator+=(Scalar s) -{ - value[0] += s; - value[1] += s; - value[2] += s; - return *this; -} - - -/************************************************************************* - Subtract another vector componentwise. - \param v vector of values to subtract - \return Reference to self - */ -template<class Scalar> -inline const ntlVector3Dim<Scalar>& -ntlVector3Dim<Scalar>::operator-=( const ntlVector3Dim<Scalar> &v ) -{ - value[0] -= v.value[0]; - value[1] -= v.value[1]; - value[2] -= v.value[2]; - return *this; -} - - -/************************************************************************* - Subtract a Scalar value from each component. - \param s Value to subtract - \return Reference to self - */ -template<class Scalar> -inline const ntlVector3Dim<Scalar>& -ntlVector3Dim<Scalar>::operator-=(Scalar s) -{ - value[0]-= s; - value[1]-= s; - value[2]-= s; - return *this; -} - - -/************************************************************************* - Multiply with another vector componentwise. - \param v vector of values to multiply with - \return Reference to self - */ -template<class Scalar> -inline const ntlVector3Dim<Scalar>& -ntlVector3Dim<Scalar>::operator*=( const ntlVector3Dim<Scalar> &v ) -{ - value[0] *= v.value[0]; - value[1] *= v.value[1]; - value[2] *= v.value[2]; - return *this; -} - - -/************************************************************************* - Multiply each component with a Scalar value. - \param s Value to multiply with - \return Reference to self - */ -template<class Scalar> -inline const ntlVector3Dim<Scalar>& -ntlVector3Dim<Scalar>::operator*=(Scalar s) -{ - value[0] *= s; - value[1] *= s; - value[2] *= s; - return *this; -} - - -/************************************************************************* - Divide by another ntlVector3Dim componentwise. - \param v vector of values to divide by - \return Reference to self - */ -template<class Scalar> -inline const ntlVector3Dim<Scalar>& -ntlVector3Dim<Scalar>::operator/=( const ntlVector3Dim<Scalar> &v ) -{ - value[0] /= v.value[0]; - value[1] /= v.value[1]; - value[2] /= v.value[2]; - return *this; -} - - -/************************************************************************* - Divide each component by a Scalar value. - \param s Value to divide by - \return Reference to self - */ -template<class Scalar> -inline const ntlVector3Dim<Scalar>& -ntlVector3Dim<Scalar>::operator/=(Scalar s) -{ - value[0] /= s; - value[1] /= s; - value[2] /= s; - return *this; -} - - -//------------------------------------------------------------------------------ -// unary operators -//------------------------------------------------------------------------------ - - -/************************************************************************* - Build componentwise the negative this vector. - \return The new (negative) vector - */ -template<class Scalar> -inline ntlVector3Dim<Scalar> -ntlVector3Dim<Scalar>::operator-() const -{ - return ntlVector3Dim<Scalar>(-value[0], -value[1], -value[2]); -} - - - -//------------------------------------------------------------------------------ -// binary operators -//------------------------------------------------------------------------------ - - -/************************************************************************* - Build a vector with another vector added componentwise. - \param v The second vector to add - \return The sum vector - */ -template<class Scalar> -inline ntlVector3Dim<Scalar> -ntlVector3Dim<Scalar>::operator+( const ntlVector3Dim<Scalar> &v ) const -{ - return ntlVector3Dim<Scalar>(value[0]+v.value[0], - value[1]+v.value[1], - value[2]+v.value[2]); -} - - -/************************************************************************* - Build a vector with a Scalar value added to each component. - \param s The Scalar value to add - \return The sum vector - */ -template<class Scalar> -inline ntlVector3Dim<Scalar> -ntlVector3Dim<Scalar>::operator+(Scalar s) const -{ - return ntlVector3Dim<Scalar>(value[0]+s, - value[1]+s, - value[2]+s); -} - - -/************************************************************************* - Build a vector with another vector subtracted componentwise. - \param v The second vector to subtract - \return The difference vector - */ -template<class Scalar> -inline ntlVector3Dim<Scalar> -ntlVector3Dim<Scalar>::operator-( const ntlVector3Dim<Scalar> &v ) const -{ - return ntlVector3Dim<Scalar>(value[0]-v.value[0], - value[1]-v.value[1], - value[2]-v.value[2]); -} - - -/************************************************************************* - Build a vector with a Scalar value subtracted componentwise. - \param s The Scalar value to subtract - \return The difference vector - */ -template<class Scalar> -inline ntlVector3Dim<Scalar> -ntlVector3Dim<Scalar>::operator-(Scalar s ) const -{ - return ntlVector3Dim<Scalar>(value[0]-s, - value[1]-s, - value[2]-s); -} - - - -/************************************************************************* - Build a vector with another vector multiplied by componentwise. - \param v The second vector to muliply with - \return The product vector - */ -template<class Scalar> -inline ntlVector3Dim<Scalar> -ntlVector3Dim<Scalar>::operator*( const ntlVector3Dim<Scalar>& v) const -{ - return ntlVector3Dim<Scalar>(value[0]*v.value[0], - value[1]*v.value[1], - value[2]*v.value[2]); -} - - -/************************************************************************* - Build a ntlVector3Dim with a Scalar value multiplied to each component. - \param s The Scalar value to multiply with - \return The product vector - */ -template<class Scalar> -inline ntlVector3Dim<Scalar> -ntlVector3Dim<Scalar>::operator*(Scalar s) const -{ - return ntlVector3Dim<Scalar>(value[0]*s, value[1]*s, value[2]*s); -} - - -/************************************************************************* - Build a vector divided componentwise by another vector. - \param v The second vector to divide by - \return The ratio vector - */ -template<class Scalar> -inline ntlVector3Dim<Scalar> -ntlVector3Dim<Scalar>::operator/(const ntlVector3Dim<Scalar>& v) const -{ - return ntlVector3Dim<Scalar>(value[0]/v.value[0], - value[1]/v.value[1], - value[2]/v.value[2]); -} - - - -/************************************************************************* - Build a vector divided componentwise by a Scalar value. - \param s The Scalar value to divide by - \return The ratio vector - */ -template<class Scalar> -inline ntlVector3Dim<Scalar> -ntlVector3Dim<Scalar>::operator/(Scalar s) const -{ - return ntlVector3Dim<Scalar>(value[0]/s, - value[1]/s, - value[2]/s); -} - - - - - -/************************************************************************* - Get a particular component of the vector. - \param i Number of Scalar to get - \return Reference to the component - */ -template<class Scalar> -inline Scalar& -ntlVector3Dim<Scalar>::operator[]( unsigned int i ) -{ - return value[i]; -} - - -/************************************************************************* - Get a particular component of a constant vector. - \param i Number of Scalar to get - \return Reference to the component - */ -template<class Scalar> -inline const Scalar& -ntlVector3Dim<Scalar>::operator[]( unsigned int i ) const -{ - return value[i]; -} - - - -//------------------------------------------------------------------------------ -// BLITZ compatibility functions -//------------------------------------------------------------------------------ - - - -/************************************************************************* - Compute the scalar product with another vector. - \param v The second vector to work with - \return The value of the scalar product - */ -template<class Scalar> -inline Scalar dot(const ntlVector3Dim<Scalar> &t, const ntlVector3Dim<Scalar> &v ) -{ - //return t.value[0]*v.value[0] + t.value[1]*v.value[1] + t.value[2]*v.value[2]; - return ((t[0]*v[0]) + (t[1]*v[1]) + (t[2]*v[2])); -} - - -/************************************************************************* - Calculate the cross product of this and another vector - */ -template<class Scalar> -inline ntlVector3Dim<Scalar> cross(const ntlVector3Dim<Scalar> &t, const ntlVector3Dim<Scalar> &v) -{ - ntlVector3Dim<Scalar> cp( - ((t[1]*v[2]) - (t[2]*v[1])), - ((t[2]*v[0]) - (t[0]*v[2])), - ((t[0]*v[1]) - (t[1]*v[0])) ); - return cp; -} - - - - -/************************************************************************* - Compute a vector that is orthonormal to self. Nothing else can be assumed - for the direction of the new vector. - \return The orthonormal vector - */ -template<class Scalar> -ntlVector3Dim<Scalar> -ntlVector3Dim<Scalar>::getOrthogonalntlVector3Dim() const -{ - // Determine the component with max. absolute value - int max= (fabs(value[0]) > fabs(value[1])) ? 0 : 1; - max= (fabs(value[max]) > fabs(value[2])) ? max : 2; - - /************************************************************************* - Choose another axis than the one with max. component and project - orthogonal to self - */ - ntlVector3Dim<Scalar> vec(0.0); - vec[(max+1)%3]= 1; - vec.normalize(); - vec.projectNormalTo(this->getNormalized()); - return vec; -} - - -/************************************************************************* - Projects the vector into a plane normal to the given vector, which must - have unit length. Self is modified. - \param v The plane normal - \return The projected vector - */ -template<class Scalar> -inline const ntlVector3Dim<Scalar>& -ntlVector3Dim<Scalar>::projectNormalTo(const ntlVector3Dim<Scalar> &v) -{ - Scalar sprod = dot(*this,v); - value[0]= value[0] - v.value[0] * sprod; - value[1]= value[1] - v.value[1] * sprod; - value[2]= value[2] - v.value[2] * sprod; - return *this; -} - - - -//------------------------------------------------------------------------------ -// Other helper functions -//------------------------------------------------------------------------------ - - - -/************************************************************************* - Minimize the vector, i.e. set each entry of the vector to the minimum - of both values. - \param pnt The second vector to compare with - \return Reference to the modified self - */ -template<class Scalar> -inline const ntlVector3Dim<Scalar> & -ntlVector3Dim<Scalar>::minimize(const ntlVector3Dim<Scalar> &pnt) -{ - for (unsigned int i = 0; i < 3; i++) - value[i] = MIN(value[i],pnt[i]); - return *this; -} - - - -/************************************************************************* - Maximize the vector, i.e. set each entry of the vector to the maximum - of both values. - \param pnt The second vector to compare with - \return Reference to the modified self - */ -template<class Scalar> -inline const ntlVector3Dim<Scalar> & -ntlVector3Dim<Scalar>::maximize(const ntlVector3Dim<Scalar> &pnt) -{ - for (unsigned int i = 0; i < 3; i++) - value[i] = MAX(value[i],pnt[i]); - return *this; -} - - - - -// ---- - -// a 3D vector with double precision -typedef ntlVector3Dim<double> ntlVec3d; - -// a 3D vector with single precision -typedef ntlVector3Dim<float> ntlVec3f; - -// a 3D integer vector -typedef ntlVector3Dim<int> ntlVec3i; - -// Color uses single precision fp values -typedef ntlVec3f ntlColor; - -/* convert a float to double vector */ -template<class T> inline ntlVec3d vec2D(T v) { return ntlVec3d(v[0],v[1],v[2]); } -template<class T> inline ntlVec3f vec2F(T v) { return ntlVec3f(v[0],v[1],v[2]); } -template<class T> inline ntlColor vec2Col(T v) { return ntlColor(v[0],v[1],v[2]); } - - - -/************************************************************************/ -// graphics vector typing - - -// use which fp-precision for raytracing? 1=float, 2=double - -/* VECTOR_EPSILON is the minimal vector length - In order to be able to discriminate floating point values near zero, and - to be sure not to fail a comparison because of roundoff errors, use this - value as a threshold. */ - -// use which fp-precision for graphics? 1=float, 2=double -#ifdef PRECISION_GFX_SINGLE -#define GFX_PRECISION 1 -#else -#ifdef PRECISION_GFX_DOUBLE -#define GFX_PRECISION 2 -#else -// standard precision for graphics -#ifndef GFX_PRECISION -#define GFX_PRECISION 1 -#endif -#endif -#endif - -#if GFX_PRECISION==1 -typedef float gfxReal; -#define GFX_REAL_MAX __FLT_MAX__ -//#define vecF2Gfx(x) (x) -//#define vecGfx2F(x) (x) -//#define vecD2Gfx(x) vecD2F(x) -//#define vecGfx2D(x) vecF2D(x) -#define VECTOR_EPSILON (1e-5f) -#else -typedef double gfxReal; -#define GFX_REAL_MAX __DBL_MAX__ -//#define vecF2Gfx(x) vecD2F(x) -//#define vecGfx2F(x) vecF2D(x) -//#define vecD2Gfx(x) (x) -//#define vecGfx2D(x) (x) -#define VECTOR_EPSILON (1e-10) -#endif - -/* fixed double prec. type, for epxlicitly double values */ -typedef double gfxDouble; - -// a 3D vector for graphics output, typically float? -typedef ntlVector3Dim<gfxReal> ntlVec3Gfx; - -template<class T> inline ntlVec3Gfx vec2G(T v) { return ntlVec3Gfx(v[0],v[1],v[2]); } - -/* get minimal vector length value that can be discriminated. */ -//inline double getVecEpsilon() { return (double)VECTOR_EPSILON; } -inline gfxReal getVecEpsilon() { return (gfxReal)VECTOR_EPSILON; } - -#define HAVE_GFXTYPES - - - - -/************************************************************************/ -// HELPER FUNCTIONS, independent of implementation -/************************************************************************/ - -#define VECTOR_TYPE ntlVector3Dim<Scalar> - - -/************************************************************************* - Compute the length (norm) of the vector. - \return The value of the norm - */ -template<class Scalar> -inline Scalar norm( const VECTOR_TYPE &v) -{ - Scalar l = v[0]*v[0] + v[1]*v[1] + v[2]*v[2]; - return (fabs(l-1.) < VECTOR_EPSILON*VECTOR_EPSILON) ? 1. : sqrt(l); -} - - -/************************************************************************* - Same as getNorm but doesnt sqrt - */ -template<class Scalar> -inline Scalar normNoSqrt( const VECTOR_TYPE &v) -{ - return v[0]*v[0] + v[1]*v[1] + v[2]*v[2]; -} - - -/************************************************************************* - Compute a normalized vector based on this vector. - \return The new normalized vector - */ -template<class Scalar> -inline VECTOR_TYPE getNormalized( const VECTOR_TYPE &v) -{ - Scalar l = v[0]*v[0] + v[1]*v[1] + v[2]*v[2]; - if (fabs(l-1.) < VECTOR_EPSILON*VECTOR_EPSILON) - return v; /* normalized "enough"... */ - else if (l > VECTOR_EPSILON*VECTOR_EPSILON) - { - Scalar fac = 1./sqrt(l); - return VECTOR_TYPE(v[0]*fac, v[1]*fac, v[2]*fac); - } - else - return VECTOR_TYPE((Scalar)0); -} - - -/************************************************************************* - Compute the norm of the vector and normalize it. - \return The value of the norm - */ -template<class Scalar> -inline Scalar normalize( VECTOR_TYPE &v) -{ - Scalar norm; - Scalar l = v[0]*v[0] + v[1]*v[1] + v[2]*v[2]; - if (fabs(l-1.) < VECTOR_EPSILON*VECTOR_EPSILON) { - norm = 1.; - } else if (l > VECTOR_EPSILON*VECTOR_EPSILON) { - norm = sqrt(l); - Scalar fac = 1./norm; - v[0] *= fac; - v[1] *= fac; - v[2] *= fac; - } else { - v[0]= v[1]= v[2]= 0; - norm = 0.; - } - return (Scalar)norm; -} - - -/************************************************************************* - Compute a vector, that is self (as an incoming - vector) reflected at a surface with a distinct normal vector. Note - that the normal is reversed, if the scalar product with it is positive. - \param n The surface normal - \return The new reflected vector - */ -template<class Scalar> -inline VECTOR_TYPE reflectVector(const VECTOR_TYPE &t, const VECTOR_TYPE &n) -{ - VECTOR_TYPE nn= (dot(t, n) > 0.0) ? (n*-1.0) : n; - return ( t - nn * (2.0 * dot(nn, t)) ); -} - - - -/************************************************************************* - * My own refraction calculation - * Taken from Glassner's book, section 5.2 (Heckberts method) - */ -template<class Scalar> -inline VECTOR_TYPE refractVector(const VECTOR_TYPE &t, const VECTOR_TYPE &normal, Scalar nt, Scalar nair, int &refRefl) -{ - Scalar eta = nair / nt; - Scalar n = -dot(t, normal); - Scalar tt = 1.0 + eta*eta* (n*n-1.0); - if(tt<0.0) { - // we have total reflection! - refRefl = 1; - } else { - // normal reflection - tt = eta*n - sqrt(tt); - return( t*eta + normal*tt ); - } - return t; -} - /*double eta = nair / nt; - double n = -((*this) | normal); - double t = 1.0 + eta*eta* (n*n-1.0); - if(t<0.0) { - // we have total reflection! - refRefl = 1; - } else { - // normal reflection - t = eta*n - sqrt(t); - return( (*this)*eta + normal*t ); - } - return (*this);*/ - - -/************************************************************************* - Test two ntlVector3Dims for equality based on the equality of their - values within a small threshold. - \param c The second vector to compare - \return TRUE if both are equal - \sa getEpsilon() - */ -template<class Scalar> -inline bool equal(const VECTOR_TYPE &v, const VECTOR_TYPE &c) -{ - return (ABS(v[0]-c[0]) + - ABS(v[1]-c[1]) + - ABS(v[2]-c[2]) < VECTOR_EPSILON); -} - - -/************************************************************************* - * Assume this vector is an RGB color, and convert it to HSV - */ -template<class Scalar> -inline void rgbToHsv( VECTOR_TYPE &V ) -{ - Scalar h=0,s=0,v=0; - Scalar maxrgb, minrgb, delta; - // convert to hsv... - maxrgb = V[0]; - int maxindex = 1; - if(V[2] > maxrgb){ maxrgb = V[2]; maxindex = 2; } - if(V[1] > maxrgb){ maxrgb = V[1]; maxindex = 3; } - minrgb = V[0]; - if(V[2] < minrgb) minrgb = V[2]; - if(V[1] < minrgb) minrgb = V[1]; - - v = maxrgb; - delta = maxrgb-minrgb; - - if(maxrgb > 0) s = delta/maxrgb; - else s = 0; - - h = 0; - if(s > 0) { - if(maxindex == 1) { - h = ((V[1]-V[2])/delta) + 0.0; } - if(maxindex == 2) { - h = ((V[2]-V[0])/delta) + 2.0; } - if(maxindex == 3) { - h = ((V[0]-V[1])/delta) + 4.0; } - h *= 60.0; - if(h < 0.0) h += 360.0; - } - - V[0] = h; - V[1] = s; - V[2] = v; -} - -/************************************************************************* - * Assume this vector is HSV and convert to RGB - */ -template<class Scalar> -inline void hsvToRgb( VECTOR_TYPE &V ) -{ - Scalar h = V[0], s = V[1], v = V[2]; - Scalar r=0,g=0,b=0; - Scalar p,q,t, fracth; - int floorh; - // ...and back to rgb - if(s == 0) { - r = g = b = v; } - else { - h /= 60.0; - floorh = (int)h; - fracth = h - floorh; - p = v * (1.0 - s); - q = v * (1.0 - (s * fracth)); - t = v * (1.0 - (s * (1.0 - fracth))); - switch (floorh) { - case 0: r = v; g = t; b = p; break; - case 1: r = q; g = v; b = p; break; - case 2: r = p; g = v; b = t; break; - case 3: r = p; g = q; b = v; break; - case 4: r = t; g = p; b = v; break; - case 5: r = v; g = p; b = q; break; - } - } - - V[0] = r; - V[1] = g; - V[2] = b; -} - - - - -#endif /* NTL_VECTOR3DIM_HH */ diff --git a/intern/elbeem/intern/ntl_world.cpp b/intern/elbeem/intern/ntl_world.cpp deleted file mode 100644 index 5f3d6e36b3b..00000000000 --- a/intern/elbeem/intern/ntl_world.cpp +++ /dev/null @@ -1,934 +0,0 @@ -/** \file - * \ingroup elbeem - */ -/****************************************************************************** - * - * El'Beem - Free Surface Fluid Simulation with the Lattice Boltzmann Method - * Copyright 2003-2006 Nils Thuerey - * - * Main renderer class - * - *****************************************************************************/ - - -#include <sys/stat.h> -#include <sstream> -#include "utilities.h" -#include "ntl_world.h" -#include "parametrizer.h" - -// for non-threaded renderViz -#ifndef NOGUI -#include "../gui/ntl_openglrenderer.h" -#include "../gui/guifuncs.h" -#include "../gui/frame.h" -#endif - - -/* external parser functions from cfgparser.cxx */ -#ifndef ELBEEM_PLUGIN -/* parse given file as config file */ -void parseFile(string filename); -/* set pointers for parsing */ -void setPointers( ntlRenderGlobals *setglob); -#endif // ELBEEM_PLUGIN - - -/****************************************************************************** - * Constructor - *****************************************************************************/ - -ntlWorld::ntlWorld() { - initDefaults(); -} - -ntlWorld::ntlWorld(string filename, bool commandlineMode) -{ -#ifndef ELBEEM_PLUGIN - - initDefaults(); -# ifdef NOGUI - commandlineMode = true; // remove warning... -# endif // NOGUI - - // load config - setPointers( getRenderGlobals() ); - parseFile( filename.c_str() ); -# ifndef NOGUI - // setup opengl display, save first animation step for start time - // init after parsing file... - if(!commandlineMode) { - mpOpenGLRenderer = new ntlOpenGLRenderer( mpGlob ); - } -# endif // NOGUI - finishWorldInit(); - -#else // ELBEEM_PLUGIN - errFatal("ntlWorld::init","Cfg file parsing not supported for API version! "<<filename<<" "<<commandlineMode, SIMWORLD_INITERROR); -#endif // ELBEEM_PLUGIN -} - - -int globalDomainCounter = 1; -int ntlWorld::addDomain(elbeemSimulationSettings *settings) -{ - // create domain obj - SimulationObject *sim = new SimulationObject(); - char simname[100]; - snprintf(simname,100,"domain%04d",globalDomainCounter); - globalDomainCounter++; - sim->setName(string(simname)); - mpGlob->getSims()->push_back( sim ); - - // important - add to both, only render scene objects are free'd - mpGlob->getRenderScene()->addGeoClass( sim ); - mpGlob->getSimScene()->addGeoClass( sim ); - sim->setGeoStart(ntlVec3Gfx(settings->geoStart[0],settings->geoStart[1],settings->geoStart[2])); - sim->setGeoEnd(ntlVec3Gfx( - settings->geoStart[0]+settings->geoSize[0], - settings->geoStart[1]+settings->geoSize[1], - settings->geoStart[2]+settings->geoSize[2] )); - // further init in postGeoConstrInit/initializeLbmSimulation of SimulationObject - sim->copyElbeemSettings(settings); - - Parametrizer *param = sim->getParametrizer(); - param->setSize( settings->resolutionxyz ); - param->setDomainSize( settings->realsize ); - param->setAniStart( settings->animStart ); - param->setNormalizedGStar( settings->gstar ); - - // init domain channels - vector<ParamFloat> valf; - vector<ParamVec> valv; - vector<double> time; - -#define INIT_CHANNEL_FLOAT(channel,size) \ - valf.clear(); time.clear(); elbeemSimplifyChannelFloat(channel,&size); \ - for(int i=0; i<size; i++) { valf.push_back( channel[2*i+0] ); time.push_back( channel[2*i+1] ); } -#define INIT_CHANNEL_VEC(channel,size) \ - valv.clear(); time.clear(); elbeemSimplifyChannelVec3(channel,&size); \ - for(int i=0; i<size; i++) { valv.push_back( ParamVec(channel[4*i+0],channel[4*i+1],channel[4*i+2]) ); time.push_back( channel[4*i+3] ); } - - param->setViscosity( settings->viscosity ); - if((settings->channelViscosity)&&(settings->channelSizeViscosity>0)) { - INIT_CHANNEL_FLOAT(settings->channelViscosity, settings->channelSizeViscosity); - param->initViscosityChannel(valf,time); } - - param->setGravity( ParamVec(settings->gravity[0], settings->gravity[1], settings->gravity[2]) ); - if((settings->channelGravity)&&(settings->channelSizeGravity>0)) { - INIT_CHANNEL_VEC(settings->channelGravity, settings->channelSizeGravity); - param->initGravityChannel(valv,time); } - - param->setAniFrameTimeChannel( settings->aniFrameTime ); - if((settings->channelFrameTime)&&(settings->channelSizeFrameTime>0)) { - INIT_CHANNEL_FLOAT(settings->channelFrameTime, settings->channelSizeFrameTime); - param->initAniFrameTimeChannel(valf,time); } - -#undef INIT_CHANNEL_FLOAT -#undef INIT_CHANNEL_VEC - - // might be set by previous domain - if(mpGlob->getAniFrames() < settings->noOfFrames) mpGlob->setAniFrames( settings->noOfFrames ); - // set additionally to SimulationObject->mOutFilename - mpGlob->setOutFilename( settings->outputPath ); - - return 0; -} - -void ntlWorld::initDefaults() -{ - mStopRenderVisualization = false; - mThreadRunning = false; - mSimulationTime = 0.0; - mFirstSim = 1; - mSingleStepDebug = false; - mFrameCnt = 0; - mSimFrameCnt = 0; - mpOpenGLRenderer = NULL; - - /* create scene storage */ - mpGlob = new ntlRenderGlobals(); - mpLightList = new vector<ntlLightObject*>; - mpPropList = new vector<ntlMaterial*>; - mpSims = new vector<SimulationObject*>; - - mpGlob->setLightList(mpLightList); - mpGlob->setMaterials(mpPropList); - mpGlob->setSims(mpSims); - - /* init default material */ - ntlMaterial *def = GET_GLOBAL_DEFAULT_MATERIAL; - mpPropList->push_back( def ); - - /* init the scene object */ - ntlScene *renderscene = new ntlScene( mpGlob, true ); - mpGlob->setRenderScene( renderscene ); - // sim scene shouldnt delete objs, may only contain subset - ntlScene *simscene = new ntlScene( mpGlob, false ); - mpGlob->setSimScene( simscene ); -} - -void ntlWorld::finishWorldInit() -{ - if(! isSimworldOk() ) return; - - // init the scene for the first time - long sstartTime = getTime(); - - // first init sim scene for geo setup - mpGlob->getSimScene()->buildScene(0.0, true); - if(! isSimworldOk() ) return; - mpGlob->getRenderScene()->buildScene(0.0, true); - if(! isSimworldOk() ) return; - long sstopTime = getTime(); - debMsgStd("ntlWorld::ntlWorld",DM_MSG,"Scene build time: "<< getTimeString(sstopTime-sstartTime) <<" ", 10); - - // TODO check simulations, run first steps - mFirstSim = -1; - if(mpSims->size() > 0) { - - // use values from first simulation as master time scale - long startTime = getTime(); - - // remember first active sim - for(size_t i=0;i<mpSims->size();i++) { - if(!(*mpSims)[i]->getVisible()) continue; - if((*mpSims)[i]->getPanic()) continue; - - // check largest timestep - if(mFirstSim>=0) { - if( (*mpSims)[i]->getTimestep() > (*mpSims)[mFirstSim]->getTimestep() ) { - mFirstSim = i; - debMsgStd("ntlWorld::ntlWorld",DM_MSG,"First Sim changed: "<<i ,10); - } - } - // check any valid sim - if(mFirstSim<0) { - mFirstSim = i; - debMsgStd("ntlWorld::ntlWorld",DM_MSG,"First Sim: "<<i ,10); - } - } - - if(mFirstSim>=0) { - debMsgStd("ntlWorld::ntlWorld",DM_MSG,"Anistart Time: "<<(*mpSims)[mFirstSim]->getStartTime() ,10); - while(mSimulationTime < (*mpSims)[mFirstSim]->getStartTime() ) { - debMsgStd("ntlWorld::ntlWorld",DM_MSG,"Anistart Time: "<<(*mpSims)[mFirstSim]->getStartTime()<<" simtime:"<<mSimulationTime ,10); - advanceSims(-1); - } - long stopTime = getTime(); - - debMsgStd("ntlWorld::ntlWorld",DM_MSG,"Time for start-sims:"<< getTimeString(stopTime-startTime) , 1); -#ifndef NOGUI - guiResetSimulationTimeRange( mSimulationTime ); -#endif - } else { - if(!mpGlob->getSingleFrameMode()) debMsgStd("ntlWorld::ntlWorld",DM_WARNING,"No active simulations!", 1); - } - } - - if(! isSimworldOk() ) return; - setElbeemState( SIMWORLD_INITED ); -} - - - -/****************************************************************************** - * Destructor - *****************************************************************************/ -ntlWorld::~ntlWorld() -{ - delete mpGlob->getRenderScene(); - delete mpGlob->getSimScene(); - - delete mpGlob; - - - // these get assigned to mpGlob but not freed there - delete mpLightList; - delete mpPropList; // materials - delete mpSims; - -#ifndef NOGUI - if(mpOpenGLRenderer) delete mpOpenGLRenderer; -#endif // NOGUI - debMsgStd("ntlWorld",DM_NOTIFY, "ntlWorld done", 10); -} - -/******************************************************************************/ -/*! set single frame rendering to filename */ -void ntlWorld::setSingleFrameOut(string singleframeFilename) { - mpGlob->setSingleFrameMode(true); - mpGlob->setSingleFrameFilename(singleframeFilename); -} - -/****************************************************************************** - * render a whole animation (command line mode) - *****************************************************************************/ - -int ntlWorld::renderAnimation( void ) -{ - // only single pic currently - //debMsgStd("ntlWorld::renderAnimation : Warning only simulating...",1); - if(mpGlob->getAniFrames() < 0) { - debMsgStd("ntlWorld::renderAnimation",DM_NOTIFY,"No frames to render... ",1); - return 1; - } - - if(mFirstSim<0) { - debMsgStd("ntlWorld::renderAnimation",DM_NOTIFY,"No reference animation found...",1); - return 1; - } - - mThreadRunning = true; // not threaded, but still use the same flags - if(getElbeemState() == SIMWORLD_INITED) { - renderScene(); - } else if(getElbeemState() == SIMWORLD_STOP) { - // dont render now, just continue - setElbeemState( SIMWORLD_INITED ); - mFrameCnt--; // counted one too many from last abort... - } else { - debMsgStd("ntlWorld::renderAnimation",DM_NOTIFY,"Not properly inited, stopping...",1); - return 1; - } - - if(mpSims->size() <= 0) { - debMsgStd("ntlWorld::renderAnimation",DM_NOTIFY,"No simulations found, stopping...",1); - return 1; - } - - bool simok = true; - for( ; ((mFrameCnt<mpGlob->getAniFrames()) && (!getStopRenderVisualization() ) && (simok)); mFrameCnt++) { - if(!advanceSims(mFrameCnt)) { - renderScene(); - } // else means sim panicked, so dont render... - else { simok=false; } - } - mThreadRunning = false; - return 0; -} - -/****************************************************************************** - * render a whole animation (visualization mode) - * this function is run in another thread, and communicates - * with the parent thread via a mutex - *****************************************************************************/ -int ntlWorld::renderVisualization( bool multiThreaded ) -{ -#ifndef NOGUI - if(getElbeemState() != SIMWORLD_INITED) { return 0; } - - if(multiThreaded) mThreadRunning = true; - // TODO, check global state? - while(!getStopRenderVisualization()) { - - if(mpSims->size() <= 0) { - debMsgStd("ntlWorld::renderVisualization",DM_NOTIFY,"No simulations found, stopping...",1); - stopSimulationThread(); - break; - } - - // determine stepsize - if(!mSingleStepDebug) { - long startTime = getTime(); - advanceSims(mFrameCnt); - mFrameCnt++; - long stopTime = getTime(); - debMsgStd("ntlWorld::renderVisualization",DM_MSG,"Time for t="<<mSimulationTime<<": "<< getTimeString(stopTime-startTime) <<" ", 10); - } else { - double targetTime = mSimulationTime + (*mpSims)[mFirstSim]->getTimestep(); - singleStepSims(targetTime); - - // check paniced sims (normally done by advanceSims - bool allPanic = true; - for(size_t i=0;i<mpSims->size();i++) { - if(!(*mpSims)[i]->getPanic()) allPanic = false; - } - if(allPanic) { - warnMsg("ntlWorld::advanceSims","All sims panicked... stopping thread" ); - setStopRenderVisualization( true ); - } - if(! isSimworldOk() ) { - warnMsg("ntlWorld::advanceSims","World state error... stopping" ); - setStopRenderVisualization( true ); - } - } - - // save frame - if(mpOpenGLRenderer) mpOpenGLRenderer->saveAnimationFrame( mSimulationTime ); - - // for non-threaded check events - if(!multiThreaded) { - Fl::check(); - gpElbeemFrame->SceneDisplay->doOnlyForcedRedraw(); - } - - } - mThreadRunning = false; - stopSimulationRestoreGui(); -#else - multiThreaded = false; // remove warning -#endif - return 0; -} -/*! render a single step for viz mode */ -int ntlWorld::singleStepVisualization( void ) -{ - mThreadRunning = true; - double targetTime = mSimulationTime + (*mpSims)[mFirstSim]->getTimestep(); - singleStepSims(targetTime); - mSimulationTime = (*mpSims)[0]->getCurrentTime(); - -#ifndef NOGUI - if(mpOpenGLRenderer) mpOpenGLRenderer->saveAnimationFrame( mSimulationTime ); - Fl::check(); - gpElbeemFrame->SceneDisplay->doOnlyForcedRedraw(); - mThreadRunning = false; - stopSimulationRestoreGui(); -#else - mThreadRunning = false; -#endif // NOGUI - return 0; -} - -// dont use LBM_EPSILON here, time is always double-precision! -#define LBM_TIME_EPSILON 1e-10 - -/****************************************************************************** - * advance simulations by time t - *****************************************************************************/ -int ntlWorld::advanceSims(int framenum) -{ - bool done = false; - bool allPanic = true; - - // stop/quit (abort), dont display/render - if(!isSimworldOk()) { - return 1; - } - - for(size_t i=0;i<mpSims->size();i++) { (*mpSims)[i]->setFrameNum(framenum); } - - // time stopped? nothing else to do... - if( (*mpSims)[mFirstSim]->getFrameTime(framenum) <= 0.0 ){ - done=true; allPanic=false; - - /* DG: Need to check for user cancel here (fix for [#30298]) */ - (*mpSims)[mFirstSim]->checkCallerStatus(FLUIDSIM_CBSTATUS_STEP, 0); - } - - // Prevent bug [#29186] Object contribute to fluid sim animation start earlier than keyframe - // Was: double targetTime = mSimulationTime + (*mpSims)[mFirstSim]->getFrameTime(framenum); - DG - double totalTime = 0.0, targetTime = 0.0; - for(size_t i = 0; i < mSimFrameCnt; i++) - { - /* We need an intermediate array "mSimFrameValue" because - otherwise if we don't start with starttime = 0, - the sim gets out of sync - DG */ - totalTime += (*mpSims)[mFirstSim]->getFrameTime(mSimFrameValue[i]); - } - targetTime = totalTime + (*mpSims)[mFirstSim]->getFrameTime(framenum); - - int gstate = 0; - myTime_t advsstart = getTime(); - - // step all the sims, and check for panic - debMsgStd("ntlWorld::advanceSims",DM_MSG, " sims "<<mpSims->size()<<" t"<<targetTime<<" done:"<<done<<" panic:"<<allPanic<<" gstate:"<<gstate, 10); // debug // timedebug - while(!done) { - double nextTargetTime = (*mpSims)[mFirstSim]->getCurrentTime() + (*mpSims)[mFirstSim]->getTimestep(); - singleStepSims(nextTargetTime); - - // check target times - done = true; - allPanic = false; - - if((*mpSims)[mFirstSim]->getTimestep() <1e-9 ) { - // safety check, avoid timesteps that are too small - errMsg("ntlWorld::advanceSims","Invalid time step, causing panic! curr:"<<(*mpSims)[mFirstSim]->getCurrentTime()<<" next:"<<nextTargetTime<<", stept:"<< (*mpSims)[mFirstSim]->getTimestep() ); - allPanic = true; - } else { - for(size_t i=0;i<mpSims->size();i++) { - if(!(*mpSims)[i]->getVisible()) continue; - if((*mpSims)[i]->getPanic()) allPanic = true; // do any panic now!? - debMsgStd("ntlWorld::advanceSims",DM_MSG, "Sim "<<i<<", currt:"<<(*mpSims)[i]->getCurrentTime()<<", nt:"<<nextTargetTime<<", panic:"<<(*mpSims)[i]->getPanic()<<", targett:"<<targetTime, 10); // debug // timedebug - } - } - if( (targetTime - (*mpSims)[mFirstSim]->getCurrentTime()) > LBM_TIME_EPSILON) done=false; - if(allPanic) done = true; - } - - if(allPanic) { - warnMsg("ntlWorld::advanceSims","All sims panicked... stopping thread" ); - setStopRenderVisualization( true ); - return 1; - } - - myTime_t advsend = getTime(); - debMsgStd("ntlWorld::advanceSims",DM_MSG,"Overall steps so far took:"<< getTimeString(advsend-advsstart)<<" for sim time "<<targetTime, 4); - - // finish step - for(size_t i=0;i<mpSims->size();i++) { - SimulationObject *sim = (*mpSims)[i]; - if(!sim->getVisible()) continue; - if(sim->getPanic()) continue; - sim->prepareVisualization(); - } - - mSimFrameValue.push_back(framenum); - mSimFrameCnt++; - - return 0; -} - -/* advance simulations by a single step */ -/* dont check target time, if *targetTime==NULL */ -void ntlWorld::singleStepSims(double targetTime) { - const bool debugTime = false; - //double targetTime = mSimulationTime + (*mpSims)[mFirstSim]->getTimestep(); - if(debugTime) errMsg("ntlWorld::singleStepSims","Target time: "<<targetTime); - - for(size_t i=0;i<mpSims->size();i++) { - SimulationObject *sim = (*mpSims)[i]; - if(!sim->getVisible()) continue; - if(sim->getPanic()) continue; - bool done = false; - while(!done) { - // try to prevent round off errs - if(debugTime) errMsg("ntlWorld::singleStepSims","Test sim "<<i<<" curt:"<< sim->getCurrentTime()<<" target:"<<targetTime<<" delta:"<<(targetTime - sim->getCurrentTime())<<" stept:"<<sim->getTimestep()<<" leps:"<<LBM_TIME_EPSILON ); // timedebug - if( (targetTime - sim->getCurrentTime()) > LBM_TIME_EPSILON) { - if(debugTime) errMsg("ntlWorld::singleStepSims","Stepping sim "<<i<<" t:"<< sim->getCurrentTime()); // timedebug - sim->step(); - } else { - done = true; - } - } - } - - mSimulationTime = (*mpSims)[mFirstSim]->getCurrentTime(); -#ifndef NOGUI - if(mpOpenGLRenderer) mpOpenGLRenderer->notifyOfNextStep(mSimulationTime); -#endif // NOGUI -} - - - -/****************************************************************************** - * Render the current scene - * uses the global variables from the parser - *****************************************************************************/ -int ntlWorld::renderScene( void ) -{ -#ifndef ELBEEM_PLUGIN - char nrStr[5]; // nr conversion - std::ostringstream outfn_conv(""); // converted ppm with other suffix - ntlRenderGlobals *glob; // storage for global rendering parameters - myTime_t timeStart,totalStart,timeEnd; // measure user running time - myTime_t rendStart,rendEnd; // measure user rendering time - glob = mpGlob; - - // deactivate for all with index!=0 - if((glob_mpactive)&&(glob_mpindex>0)) return(0); - - /* check if picture already exists... */ - if(!glob->getSingleFrameMode() ) { - snprintf(nrStr, 5, "%04d", glob->getAniCount() ); - - if(glob_mpactive) { - outfn_conv << glob->getOutFilename() <<"_"<<glob_mpindex<<"_" << nrStr << ".png"; /// DEBUG! - } else { - // ORG - outfn_conv << glob->getOutFilename() <<"_" << nrStr << ".png"; - } - - //if((mpGlob->getDisplayMode() == DM_RAY)&&(mpGlob->getFrameSkip())) { - if(mpGlob->getFrameSkip()) { - struct stat statBuf; - if(stat(outfn_conv.str().c_str(),&statBuf) == 0) { - errorOut("ntlWorld::renderscene Warning: file "<<outfn_conv.str()<<" already exists - skipping frame..."); - glob->setAniCount( glob->getAniCount() +1 ); - return(2); - } - } // RAY mode - } else { - // single frame rendering, overwrite if necessary... - outfn_conv << glob->getSingleFrameFilename(); - } - - /* start program */ - timeStart = getTime(); - - /* build scene geometry, calls buildScene(t,false) */ - glob->getRenderScene()->prepareScene(mSimulationTime); - - /* start program */ - totalStart = getTime(); - - - /* view parameters are currently not animated */ - /* calculate rays through projection plane */ - ntlVec3Gfx direction = glob->getLookat() - glob->getEye(); - /* calculate width of screen using perpendicular triangle diven by - * viewing direction and screen plane */ - gfxReal screenWidth = norm(direction)*tan( (glob->getFovy()*0.5/180.0)*M_PI ); - - /* calculate vector orthogonal to up and viewing direction */ - ntlVec3Gfx upVec = glob->getUpVec(); - ntlVec3Gfx rightVec( cross(upVec,direction) ); - normalize(rightVec); - - /* calculate screen plane up vector, perpendicular to viewdir and right vec */ - upVec = ntlVec3Gfx( cross(rightVec,direction) ); - normalize(upVec); - - /* check if vectors are valid */ - if( (equal(upVec,ntlVec3Gfx(0.0))) || (equal(rightVec,ntlVec3Gfx(0.0))) ) { - errMsg("ntlWorld::renderScene","Invalid viewpoint vectors! up="<<upVec<<" right="<<rightVec); - return(1); - } - - /* length from center to border of screen plane */ - rightVec *= (screenWidth*glob->getAspect() * -1.0); - upVec *= (screenWidth * -1.0); - - /* screen traversal variables */ - ntlVec3Gfx screenPos; /* current position on virtual screen */ - int Xres = glob->getResX(); /* X resolution */ - int Yres = glob->getResY(); /* Y resolution */ - ntlVec3Gfx rightStep = (rightVec/(Xres/2.0)); /* one step right for a pixel */ - ntlVec3Gfx upStep = (upVec/(Yres/2.0)); /* one step up for a pixel */ - - - /* anti alias init */ - char showAAPic = 0; - int aaDepth = glob->getAADepth(); - int aaLength; - if(aaDepth>=0) aaLength = (2<<aaDepth); - else aaLength = 0; - float aaSensRed = 0.1; - float aaSensGreen = 0.1; - float aaSensBlue = 0.1; - int aaArrayX = aaLength*Xres+1; - int aaArrayY = ( aaLength+1 ); - ntlColor *aaCol = new ntlColor[ aaArrayX*aaArrayY ]; - char *aaUse = new char[ aaArrayX*aaArrayY ]; - - /* picture storage */ - int picX = Xres; - int picY = Yres; - if(showAAPic) { - picX = Xres *aaLength+1; - picY = Yres *aaLength+1; - } - ntlColor *finalPic = new ntlColor[picX * picY]; - - - /* reset picture vars */ - for(int j=0;j<aaArrayY;j++) { - for(int i=0;i<aaArrayX;i++) { - aaCol[j*aaArrayX+i] = ntlColor(0.0, 0.0, 0.0); - aaUse[j*aaArrayX+i] = 0; - } - } - for(int j=0;j<picY;j++) { - for(int i=0;i<picX;i++) { - finalPic[j*picX+i] = ntlColor(0.0, 0.0, 0.0); - } - } - - /* loop over all y lines in screen, from bottom to top because - * ppm format wants 0,0 top left */ - rendStart = getTime(); - glob->setCounterShades(0); - glob->setCounterSceneInter(0); - for (int scanline=Yres ; scanline > 0 ; --scanline) { - - debugOutInter( "ntlWorld::renderScene: Line "<<scanline<< - " ("<< ((Yres-scanline)*100/Yres) <<"%) ", 2, 2000 ); - screenPos = glob->getLookat() + upVec*((2.0*scanline-Yres)/Yres) - - rightVec; - - /* loop over all pixels in line */ - for (int sx=0 ; sx < Xres ; ++sx) { - - if((sx==glob->getDebugPixelX())&&(scanline==(Yres-glob->getDebugPixelY()) )) { - // DEBUG!!! - glob->setDebugOut(10); - } else glob->setDebugOut(0); - - /* compute ray from eye through current pixel into scene... */ - ntlColor col; - if(aaDepth<0) { - ntlVec3Gfx dir(screenPos - glob->getEye()); - ntlRay the_ray(glob->getEye(), getNormalized(dir), 0, 1.0, glob ); - - /* ...and trace it */ - col = the_ray.shade(); - } else { - /* anti alias */ - int ai,aj; /* position in grid */ - int aOrg = sx*aaLength; /* grid offset x */ - int currStep = aaLength; /* step size */ - char colDiff = 1; /* do colors still differ too much? */ - ntlColor minCol,maxCol; /* minimum and maximum Color Values */ - minCol = ntlColor(1.0,1.0,1.0); - maxCol = ntlColor(0.0,0.0,0.0); - - while((colDiff) && (currStep>0)) { - colDiff = 0; - - for(aj = 0;aj<=aaLength;aj+= currStep) { - for(ai = 0;ai<=aaLength;ai+= currStep) { - - /* shade pixel if not done */ - if(aaUse[aj*aaArrayX +ai +aOrg] == 0) { - aaUse[aj*aaArrayX +ai +aOrg] = 1; - ntlVec3Gfx aaPos( screenPos + - (rightStep * (ai- aaLength/2)/(gfxReal)aaLength ) + - (upStep * (aj- aaLength/2)/(gfxReal)aaLength ) ); - - ntlVec3Gfx dir(aaPos - glob->getEye()); - ntlRay the_ray(glob->getEye(), getNormalized(dir), 0, 1.0, glob ); - - /* ...and trace it */ - ntlColor newCol= the_ray.shade(); - aaCol[aj*aaArrayX +ai +aOrg]= newCol; - } /* not used? */ - - } - } - - /* check color differences */ - for(aj = 0;aj<aaLength;aj+= currStep) { - for(ai = 0;ai<aaLength;ai+= currStep) { - - char thisColDiff = 0; - if( - (fabs(aaCol[aj*aaArrayX +ai +aOrg][0] - - aaCol[(aj+0)*aaArrayX +(ai+currStep) +aOrg][0])> aaSensRed ) || - (fabs(aaCol[aj*aaArrayX +ai +aOrg][1] - - aaCol[(aj+0)*aaArrayX +(ai+currStep) +aOrg][1])> aaSensGreen ) || - (fabs(aaCol[aj*aaArrayX +ai +aOrg][2] - - aaCol[(aj+0)*aaArrayX +(ai+currStep) +aOrg][2])> aaSensBlue ) ) { - thisColDiff = 1; - } else - if( - (fabs(aaCol[aj*aaArrayX +ai +aOrg][0] - - aaCol[(aj+currStep)*aaArrayX +(ai+0) +aOrg][0])> aaSensRed ) || - (fabs(aaCol[aj*aaArrayX +ai +aOrg][1] - - aaCol[(aj+currStep)*aaArrayX +(ai+0) +aOrg][1])> aaSensGreen ) || - (fabs(aaCol[aj*aaArrayX +ai +aOrg][2] - - aaCol[(aj+currStep)*aaArrayX +(ai+0) +aOrg][2])> aaSensBlue ) ) { - thisColDiff = 1; - } else - if( - (fabs(aaCol[aj*aaArrayX +ai +aOrg][0] - - aaCol[(aj+currStep)*aaArrayX +(ai+currStep) +aOrg][0])> aaSensRed ) || - (fabs(aaCol[aj*aaArrayX +ai +aOrg][1] - - aaCol[(aj+currStep)*aaArrayX +(ai+currStep) +aOrg][1])> aaSensGreen ) || - (fabs(aaCol[aj*aaArrayX +ai +aOrg][2] - - aaCol[(aj+currStep)*aaArrayX +(ai+currStep) +aOrg][2])> aaSensBlue ) ) { - thisColDiff = 1; - } - - //colDiff =1; - if(thisColDiff) { - /* set diff flag */ - colDiff = thisColDiff; - for(int bj=aj;bj<=aj+currStep;bj++) { - for(int bi=ai;bi<=ai+currStep;bi++) { - if(aaUse[bj*aaArrayX +bi +aOrg]==2) { - //if(showAAPic) - aaUse[bj*aaArrayX +bi +aOrg] = 0; - } - } - } - } else { - /* set all values */ - ntlColor avgCol = ( - aaCol[(aj+0 )*aaArrayX +(ai+0 ) +aOrg] + - aaCol[(aj+0 )*aaArrayX +(ai+currStep) +aOrg] + - aaCol[(aj+currStep)*aaArrayX +(ai+0 ) +aOrg] + - aaCol[(aj+currStep)*aaArrayX +(ai+currStep) +aOrg] ) *0.25; - for(int bj=aj;bj<=aj+currStep;bj++) { - for(int bi=ai;bi<=ai+currStep;bi++) { - if(aaUse[bj*aaArrayX +bi +aOrg]==0) { - aaCol[bj*aaArrayX +bi +aOrg] = avgCol; - aaUse[bj*aaArrayX +bi +aOrg] = 2; - } - } - } - } /* smaller values set */ - - } - } - - /* half step size */ - currStep /= 2; - - } /* repeat until diff not too big */ - - /* get average color */ - gfxReal colNum = 0.0; - col = ntlColor(0.0, 0.0, 0.0); - for(aj = 0;aj<=aaLength;aj++) { - for(ai = 0;ai<=aaLength;ai++) { - col += aaCol[aj*aaArrayX +ai +aOrg]; - colNum += 1.0; - } - } - col /= colNum; - - } - - /* mark pixels with debugging */ - if( glob->getDebugOut() > 0) col = ntlColor(0,1,0); - - /* store pixel */ - if(!showAAPic) { - finalPic[(scanline-1)*picX+sx] = col; - } - screenPos += rightStep; - - } /* foreach x */ - - /* init aa array */ - if(showAAPic) { - for(int j=0;j<=aaArrayY-1;j++) { - for(int i=0;i<=aaArrayX-1;i++) { - if(aaUse[j*aaArrayX +i]==1) finalPic[((scanline-1)*aaLength +j)*picX+i][0] = 1.0; - } - } - } - - for(int i=0;i<aaArrayX;i++) { - aaCol[(aaArrayY-1)*aaArrayX+i] = aaCol[0*aaArrayX+i]; - aaUse[(aaArrayY-1)*aaArrayX+i] = aaUse[0*aaArrayX+i]; - } - for(int j=0;j<aaArrayY-1;j++) { - for(int i=0;i<aaArrayX;i++) { - aaCol[j*aaArrayX+i] = ntlColor(0.0, 0.0, 0.0); - aaUse[j*aaArrayX+i] = 0; - } - } - - } /* foreach y */ - rendEnd = getTime(); - - - /* write png file */ - { - int w = picX; - int h = picY; - - unsigned rowbytes = w*4; - unsigned char *screenbuf, **rows; - screenbuf = (unsigned char*)malloc( h*rowbytes ); - rows = (unsigned char**)malloc( h*sizeof(unsigned char*) ); - unsigned char *filler = screenbuf; - - // cutoff color values 0..1 - for(int j=0;j<h;j++) { - for(int i=0;i<w;i++) { - ntlColor col = finalPic[j*w+i]; - for (unsigned int cc=0; cc<3; cc++) { - if(col[cc] <= 0.0) col[cc] = 0.0; - if(col[cc] >= 1.0) col[cc] = 1.0; - } - *filler = (unsigned char)( col[0]*255.0 ); - filler++; - *filler = (unsigned char)( col[1]*255.0 ); - filler++; - *filler = (unsigned char)( col[2]*255.0 ); - filler++; - *filler = (unsigned char)( 255.0 ); - filler++; // alpha channel - } - } - - for(int i = 0; i < h; i++) rows[i] = &screenbuf[ (h - i - 1)*rowbytes ]; - writePng(outfn_conv.str().c_str(), rows, w, h); - } - - - // next frame - glob->setAniCount( glob->getAniCount() +1 ); - - // done - timeEnd = getTime(); - - char resout[1024]; - snprintf(resout,1024, "NTL Done %s, frame %d/%d (took %s scene, %s raytracing, %s total, %d shades, %d i.s.'s)!\n", - outfn_conv.str().c_str(), (glob->getAniCount()), (glob->getAniFrames()+1), - getTimeString(totalStart-timeStart).c_str(), getTimeString(rendEnd-rendStart).c_str(), getTimeString(timeEnd-timeStart).c_str(), - glob->getCounterShades(), - glob->getCounterSceneInter() ); - debMsgStd("ntlWorld::renderScene",DM_MSG, resout, 1 ); - - /* clean stuff up */ - delete [] aaCol; - delete [] aaUse; - delete [] finalPic; - glob->getRenderScene()->cleanupScene(); - - if(mpGlob->getSingleFrameMode() ) { - debMsgStd("ntlWorld::renderScene",DM_NOTIFY, "Single frame mode done...", 1 ); - return 1; - } -#endif // ELBEEM_PLUGIN - return 0; -} - - -/****************************************************************************** - * renderglobals - *****************************************************************************/ - - -/*****************************************************************************/ -/* Constructor with standard value init */ -ntlRenderGlobals::ntlRenderGlobals() : - mpRenderScene(NULL), mpSimScene(NULL), - mpLightList( NULL ), mpMaterials( NULL ), mpSims( NULL ), - mResX(320), mResY(200), mAADepth(-1), mMaxColVal(255), - mRayMaxDepth( 5 ), - mvEye(0.0,0.0,5.0), mvLookat(0.0,0.0,0.0), mvUpvec(0.0,1.0,0.0), - mAspect(320.0/200.0), - mFovy(45), mcBackgr(0.0,0.0,0.0), mcAmbientLight(0.0,0.0,0.0), - mDebugOut( 0 ), - mAniStart(0), mAniFrames( -1 ), mAniCount( 0 ), - mFrameSkip( 0 ), - mCounterRays( 0 ), mCounterShades( 0 ), mCounterSceneInter( 0 ), - mOutFilename( "pic" ), - mTreeMaxDepth( 30 ), mTreeMaxTriangles( 30 ), - mpOpenGlAttr(NULL), - mpBlenderAttr(NULL), - mTestSphereEnabled( false ), - mDebugPixelX( -1 ), mDebugPixelY( -1 ), mTestMode(false), - mSingleFrameMode(false), mSingleFrameFilename("") - //,mpRndDirections( NULL ), mpRndRoulette( NULL ) -{ - // create internal attribute list for opengl renderer - mpOpenGlAttr = new AttributeList("__ntlOpenGLRenderer"); - mpBlenderAttr = new AttributeList("__ntlBlenderAttr"); -}; - - -/*****************************************************************************/ -/* Destructor */ -ntlRenderGlobals::~ntlRenderGlobals() { - if(mpOpenGlAttr) delete mpOpenGlAttr; - if(mpBlenderAttr) delete mpBlenderAttr; - - -} - - -/*****************************************************************************/ -//! get the next random photon direction -//ntlVec3Gfx ntlRenderGlobals::getRandomDirection( void ) { - //return ntlVec3Gfx( - //(mpRndDirections->getGfxReal()-0.5), - //(mpRndDirections->getGfxReal()-0.5), - //(mpRndDirections->getGfxReal()-0.5) ); -//} - - diff --git a/intern/elbeem/intern/ntl_world.h b/intern/elbeem/intern/ntl_world.h deleted file mode 100644 index 7851b783225..00000000000 --- a/intern/elbeem/intern/ntl_world.h +++ /dev/null @@ -1,411 +0,0 @@ -/** \file - * \ingroup elbeem - */ -/****************************************************************************** - * - * El'Beem - Free Surface Fluid Simulation with the Lattice Boltzmann Method - * Copyright 2003-2006 Nils Thuerey - * - * Main renderer class - * - *****************************************************************************/ -#ifndef NTL_RAYTRACER_HH -#define NTL_RAYTRACER_HH - -#include "ntl_vector3dim.h" -#include "ntl_ray.h" -#include "ntl_lighting.h" -#include "ntl_geometryobject.h" -#include "simulation_object.h" -#include "elbeem.h" - -#ifdef WITH_CXX_GUARDEDALLOC -# include "MEM_guardedalloc.h" -#endif - -class ntlOpenGLRenderer; -class ntlScene; -class SimulationObject; -class ntlRandomStream; - -class ntlWorld -{ - public: - /*! Constructor for API init */ - ntlWorld(); - /*! Constructor */ - ntlWorld(string filename, bool commandlineMode); - /*! Destructor */ - virtual ~ntlWorld( void ); - /*! default init for all contructors */ - void initDefaults(); - /*! common world contruction stuff once the scene is set up */ - void finishWorldInit(); - /*! add domain for API init */ - int addDomain(elbeemSimulationSettings *simSettings); - - /*! render a whole animation (command line mode) */ - int renderAnimation( void ); - /*! render a whole animation (visualization mode) */ - int renderVisualization( bool ); - /*! render a single step for viz mode */ - int singleStepVisualization( void ); - /*! advance simulations by time frame time */ - int advanceSims(int framenum); - /*! advance simulations by a single step */ - void singleStepSims(double targetTime); - - /*! set stop rend viz flag */ - void setStopRenderVisualization(bool set) { mStopRenderVisualization = set; } - /*! should the rendering viz thread be stopped? */ - bool getStopRenderVisualization() { return mStopRenderVisualization; } - - /*! render scene (a single pictures) */ - virtual int renderScene( void ); - - /*! set single frame rendering to filename */ - void setSingleFrameOut( string singleframeFilename ); - - /* access functions */ - - /*! set&get render globals */ - inline void setRenderGlobals( ntlRenderGlobals *set) { mpGlob = set; } - inline ntlRenderGlobals *getRenderGlobals( void ) { return mpGlob; } - - /*! set&get render globals */ - inline void setSimulationTime( double set) { mSimulationTime = set; } - inline double getSimulationTime( void ) { return mSimulationTime; } - - /*! set&get single step debug mode */ - inline void setSingleStepDebug( bool set) { mSingleStepDebug = set; } - inline bool getSingleStepDebug( void ) { return mSingleStepDebug; } - - /*! &get simulation object vector (debugging) */ - inline vector<SimulationObject*> *getSimulations( void ) { return mpSims; } - - /*! get opengl renderer */ - inline ntlOpenGLRenderer *getOpenGLRenderer() { return mpOpenGLRenderer; } - - private: - - protected: - - /*! global render settings needed almost everywhere */ - ntlRenderGlobals *mpGlob; - - /*! a list of lights in the scene (geometry is store in ntl_scene) */ - vector<ntlLightObject*> *mpLightList; - /*! surface materials */ - vector<ntlMaterial*> *mpPropList; - /*! sims list */ - vector<SimulationObject*> *mpSims; - - /*! opengl display */ - ntlOpenGLRenderer *mpOpenGLRenderer; - - /*! stop rend viz? */ - bool mStopRenderVisualization; - - /*! rend viz thread currently running? */ - bool mThreadRunning; - - /*! remember the current simulation time */ - double mSimulationTime; - - /*! first simulation that is valid */ - int mFirstSim; - - /*! single step mode for debugging */ - bool mSingleStepDebug; - - /*! count no. of frame for viz render */ - int mFrameCnt; - - /*! count no. of frame for correct sim time */ - int mSimFrameCnt; - vector<int> mSimFrameValue; - -private: -#ifdef WITH_CXX_GUARDEDALLOC - MEM_CXX_CLASS_ALLOC_FUNCS("ELBEEM:ntlWorld") -#endif -}; - - -//! Class that handles global rendering parameters -class ntlRenderGlobals -{ - public: - //! Standard constructor - ntlRenderGlobals(); - //! Destructor - ~ntlRenderGlobals(); - - //! Returns the renderscene manager (scene changes for each frame) - inline ntlScene *getRenderScene(void) { return mpRenderScene; } - //! Set the renderscene manager - inline void setRenderScene(ntlScene *set) { mpRenderScene = set;} - - //! Returns the simulation scene manager (static scene with sim objects) - inline ntlScene *getSimScene(void) { return mpSimScene; } - //! Set the simulation scene manager - inline void setSimScene(ntlScene *set) { mpSimScene = set;} - - //! Returns the light object list - inline vector<ntlLightObject*> *getLightList(void) { return mpLightList; } - //! Set the light list - inline void setLightList(vector<ntlLightObject*> *set) { mpLightList = set;} - - //! Returns the property object list - inline vector<ntlMaterial*> *getMaterials(void) { return mpMaterials; } - //! Set the property list - inline void setMaterials(vector<ntlMaterial*> *set) { mpMaterials = set;} - - //! Returns the list of simulations - inline vector<SimulationObject*> *getSims(void) { return mpSims; } - //! Set the pointer to the list of simulations - inline void setSims(vector<SimulationObject*> *set) { mpSims = set;} - - //! Set the x resolution - inline void setResX(unsigned int set) { mResX = set; } - //! Set the y resolution - inline void setResY(unsigned int set) { mResY = set; } - //! Set the anti-aliasing depth - inline void setAADepth(int set) { mAADepth = set; } - //! Set the max color value - inline void setMaxColVal(unsigned int set) { mMaxColVal = set; } - //! Set the maximum ray recursion - inline void setRayMaxDepth(unsigned int set) { mRayMaxDepth = set; } - //! Set the eye point - inline void setEye(ntlVec3Gfx set) { mvEye = set; } - //! Set the look at vector - inline void setLookat(ntlVec3Gfx set) { mvLookat = set; } - //! Set the up vector - inline void setUpVec(ntlVec3Gfx set) { mvUpvec = set; } - //! Set the image aspect - inline void setAspect(float set) { mAspect = set; } - //! Set the field of view - inline void setFovy(float set) { mFovy = set; } - //! Set the background color - inline void setBackgroundCol(ntlColor set) { mcBackgr = set; } - //! Set the ambient lighting color - inline void setAmbientLight(ntlColor set) { mcAmbientLight = set; } - //! Set the debug output var - inline void setDebugOut(int set) { mDebugOut = set; } - - //! Set the animation start time - inline void setAniStart(int set) { mAniStart = set; } - //! Set the animation number of frames - inline void setAniFrames(int set) { mAniFrames = set; } - //! Set the animation - inline void setAniCount(int set) { mAniCount = set; } - //! Set the ray counter - inline void setCounterRays(int set) { mCounterRays = set; } - //! Set the ray shades counter - inline void setCounterShades(int set) { mCounterShades = set; } - //! Set the scenen intersection counter - inline void setCounterSceneInter(int set) { mCounterSceneInter = set; } - //! Set if existing frames should be skipped - inline void setFrameSkip(int set) { mFrameSkip = set; } - - //! Set the outfilename - inline void setOutFilename(string set) { mOutFilename = set; } - - //! get Maximum depth for BSP tree - inline void setTreeMaxDepth( int set ) { mTreeMaxDepth = set; } - //! get Maxmimum nr of triangles per BSP tree node - inline void setTreeMaxTriangles( int set ) { mTreeMaxTriangles = set; } - - //! set the enable flag of the test sphere - inline void setTestSphereEnabled( bool set ) { mTestSphereEnabled = set; } - //! set the center of the test sphere - inline void setTestSphereCenter( ntlVec3Gfx set ) { mTestSphereCenter = set; } - //! set the radius of the test sphere - inline void setTestSphereRadius( gfxReal set ) { mTestSphereRadius = set; } - //! set the material name of the test sphere - inline void setTestSphereMaterialName( char* set ) { mTestSphereMaterialName = set; } - //! set debugging pixel coordinates - inline void setDebugPixel( int setx, int sety ) { mDebugPixelX = setx; mDebugPixelY = sety; } - //! set test mode flag - inline void setTestMode( bool set ) { mTestMode = set; } - //! set single frame mode flag - inline void setSingleFrameMode(bool set) {mSingleFrameMode = set; }; - //! set single frame mode filename - inline void setSingleFrameFilename(string set) {mSingleFrameFilename = set; }; - - - //! Return the x resolution - inline unsigned int getResX(void) { return mResX; } - //! Return the y resolution - inline unsigned int getResY(void) { return mResY; } - //! Return the anti-aliasing depth - inline int getAADepth(void) { return mAADepth; } - //! Return the max color value for ppm - inline unsigned int getMaxColVal(void) { return mMaxColVal; } - //! Return the maximum ray recursion - inline unsigned int getRayMaxDepth(void) { return mRayMaxDepth; } - //! Return the eye point - inline ntlVec3Gfx getEye(void) { return mvEye; } - //! Return the look at vector - inline ntlVec3Gfx getLookat(void) { return mvLookat; } - //! Return the up vector - inline ntlVec3Gfx getUpVec(void) { return mvUpvec; } - //! Return the image aspect - inline float getAspect(void) { return mAspect; } - //! Return the field of view - inline float getFovy(void) { return mFovy; } - //! Return the background color - inline ntlColor getBackgroundCol(void) { return mcBackgr; } - //! Return the ambient color - inline ntlColor getAmbientLight(void) { return mcAmbientLight; } - //! Return the debug mode setting - inline int getDebugOut(void) { return mDebugOut; } - - //! Return the animation start time - inline int getAniStart(void) { return mAniStart; } - //! Return the animation frame number - inline int getAniFrames(void) { return mAniFrames; } - //! Return the animation counter - inline int getAniCount(void) { return mAniCount; } - //! Return the ray counter - inline int getCounterRays(void) { return mCounterRays; } - //! Return the ray shades counter - inline int getCounterShades(void) { return mCounterShades; } - //! Return the scene intersection counter - inline int getCounterSceneInter(void) { return mCounterSceneInter; } - //! Check if existing frames should be skipped - inline int getFrameSkip( void ) { return mFrameSkip; } - - - //! Return the outfilename - inline string getOutFilename(void) { return mOutFilename; } - - //! get Maximum depth for BSP tree - inline int getTreeMaxDepth( void ) { return mTreeMaxDepth; } - //! get Maxmimum nr of triangles per BSP tree node - inline int getTreeMaxTriangles( void ) { return mTreeMaxTriangles; } - - //! get open gl attribute list - inline AttributeList* getOpenGlAttributes( void ) { return mpOpenGlAttr; } - //! get blender output attribute list - inline AttributeList* getBlenderAttributes( void ) { return mpBlenderAttr; } - - //! is the test sphere enabled? - inline bool getTestSphereEnabled( void ) { return mTestSphereEnabled; } - //! get the center of the test sphere - inline ntlVec3Gfx getTestSphereCenter( void ) { return mTestSphereCenter; } - //! get the radius of the test sphere - inline gfxReal getTestSphereRadius( void) { return mTestSphereRadius; } - //! get the materialname of the test sphere - inline char *getTestSphereMaterialName( void) { return mTestSphereMaterialName; } - //! get the debug pixel coordinate - inline int getDebugPixelX( void ) { return mDebugPixelX; } - //! get the debug pixel coordinate - inline int getDebugPixelY( void ) { return mDebugPixelY; } - //! get test mode flag - inline bool getTestMode( void ) { return mTestMode; } - //! set single frame mode flag - inline bool getSingleFrameMode() { return mSingleFrameMode; }; - //! set single frame mode filename - inline string getSingleFrameFilename() { return mSingleFrameFilename; }; - - -private: - - /*! Scene storage (dynamic rendering scene) */ - ntlScene *mpRenderScene; - /*! Scene storage (static sim scene, inited only once) */ - ntlScene *mpSimScene; - - //! List of light objects - vector<ntlLightObject*> *mpLightList; - //! List of surface properties - vector<ntlMaterial*> *mpMaterials; - /*! storage for simulations */ - vector<SimulationObject*> *mpSims; - - //! resolution of the picture - unsigned int mResX, mResY; - //! Anti-Aliasing depth - int mAADepth; - //! max color value for ppm - unsigned int mMaxColVal; - /* Maximal ray recursion depth */ - int mRayMaxDepth; - //! The eye point - ntlVec3Gfx mvEye; - //! The look at point - ntlVec3Gfx mvLookat; - //! The up vector - ntlVec3Gfx mvUpvec; - //! The image aspect = Xres/Yres - float mAspect; - //! The horizontal field of view - float mFovy; - //! The background color - ntlColor mcBackgr; - //! The ambient color - ntlColor mcAmbientLight; - //! how much debug output is needed? off by default - char mDebugOut; - - - //! animation properties, start time - int mAniStart; - //! animation properties, number of frames to render - int mAniFrames; - //! animation status, current frame number - int mAniCount; - /*! Should existing picture frames be skipped? */ - int mFrameSkip; - - - //! count the total number of rays created (also used for ray ID's) - int mCounterRays; - //! count the total number of rays shaded - int mCounterShades; - //! count the total number of scene intersections - int mCounterSceneInter; - - /*! filename of output pictures (without suffix or numbers) */ - string mOutFilename; - - //! get Maximum depth for BSP tree - int mTreeMaxDepth; - //! get Maxmimum nr of triangles per BSP tree node - int mTreeMaxTriangles; - - //! attribute list for opengl renderer - AttributeList *mpOpenGlAttr; - //! attribute list for blender output - AttributeList *mpBlenderAttr; - - - //! Enable test sphere? - bool mTestSphereEnabled; - //! Center of the test sphere - ntlVec3Gfx mTestSphereCenter; - //! Radius of the test sphere - gfxReal mTestSphereRadius; - //! Materialname of the test sphere - char *mTestSphereMaterialName; - //! coordinates of the debugging pixel - int mDebugPixelX, mDebugPixelY; - - //! test mode for quick rendering activated?, inited in ntl_scene::buildScene - bool mTestMode; - - //! single frame flag - bool mSingleFrameMode; - //! filename for single frame mode - string mSingleFrameFilename; - -private: -#ifdef WITH_CXX_GUARDEDALLOC - MEM_CXX_CLASS_ALLOC_FUNCS("ELBEEM:ntlRenderGlobals") -#endif -}; - - - -#endif diff --git a/intern/elbeem/intern/paraloopend.h b/intern/elbeem/intern/paraloopend.h deleted file mode 100644 index 6f321cd68b1..00000000000 --- a/intern/elbeem/intern/paraloopend.h +++ /dev/null @@ -1,45 +0,0 @@ -/** \file - * \ingroup elbeem - */ - -// same as grid loop_end + barrier - - } // i - int i=0; //dummy - ADVANCE_POINTERS(2*gridLoopBound); - } // j - -# if COMPRESSGRIDS==1 -# if PARALLEL==1 - //frintf(stderr," (id=%d k=%d) ",id,k); -#pragma omp barrier -# endif // PARALLEL==1 -# else // COMPRESSGRIDS==1 - int i=0; //dummy - ADVANCE_POINTERS(mLevel[lev].lSizex*2); -# endif // COMPRESSGRIDS==1 - -} // all cell loop k,j,i - -#pragma omp critical -{ - if(doReduce) { - // synchronize global vars - for(size_t j=0; j<calcListFull.size() ; j++) mListFull.push_back( calcListFull[j] ); - for(size_t j=0; j<calcListEmpty.size(); j++) mListEmpty.push_back( calcListEmpty[j] ); - for(size_t j=0; j<calcListParts.size(); j++) mpParticles->addFullParticle( calcListParts[j] ); - if(calcMaxVlen>mMaxVlen) { - mMxvx = calcMxvx; - mMxvy = calcMxvy; - mMxvz = calcMxvz; - mMaxVlen = calcMaxVlen; - } - if(0) {debMsgStd("OMP_CRIT",DM_MSG, "reduce id"<<id<<" curr: "<<mMaxVlen<<"|"<<mMxvx<<","<<mMxvy<<","<<mMxvz<< - " calc[ "<<calcMaxVlen<<"|"<<calcMxvx<<","<<calcMxvy<<","<<calcMxvz<<"] " ,4 ); } - } -} // critical - - -} /* main_region */ - //?lobOutstrForce = true; - diff --git a/intern/elbeem/intern/parametrizer.cpp b/intern/elbeem/intern/parametrizer.cpp deleted file mode 100644 index 889b8b85c4d..00000000000 --- a/intern/elbeem/intern/parametrizer.cpp +++ /dev/null @@ -1,597 +0,0 @@ -/** \file - * \ingroup elbeem - */ -/****************************************************************************** - * - * El'Beem - Free Surface Fluid Simulation with the Lattice Boltzmann Method - * Copyright 2003-2006 Nils Thuerey - * - * Parameter calculator for the LBM Solver class - * - *****************************************************************************/ - -#include <sstream> -#include "parametrizer.h" - -// debug output flag, has to be off for win32 for some reason... -#define DEBUG_PARAMCHANNELS 0 - -/*! param seen debug string array */ -const char *ParamStrings[] = { - "RelaxTime", - "Reynolds", - "Viscosity", - "SoundSpeed", - "DomainSize", - "GravityForce", - "TimeLength", - "Timestep", - "Size", - "TimeFactor", - "AniFrames", - "AniFrameTime", - "AniStart", - "SurfaceTension", - "Density", - "CellSize", - "GStar", - "MaxSpeed", - "SimMaxSpeed", - "FluidVolHeight", - "NormalizedGStar", - "PSERR", "PSERR", "PSERR", "PSERR" -}; - - - -/****************************************************************************** - * Default constructor - *****************************************************************************/ -Parametrizer::Parametrizer( void ) : - mcViscosity( 8.94e-7 ), - mSoundSpeed( 1500 ), - mDomainSize( 0.1 ), mCellSize( 0.01 ), - mcGravity( ParamVec(0.0) ), - mTimestep(0.0001), mDesiredTimestep(-1.0), - mMaxTimestep(-1.0), - mMinTimestep(-1.0), - mSizex(50), mSizey(50), mSizez(50), - mTimeFactor( 1.0 ), - mcAniFrameTime(0.0001), - mTimeStepScale(1.0), - mAniStart(0.0), - //mExtent(1.0, 1.0, 1.0), //mSurfaceTension( 0.0 ), - mDensity(1000.0), mGStar(0.0001), mFluidVolumeHeight(0.0), - mSimulationMaxSpeed(0.0), - mTadapMaxOmega(2.0), mTadapMaxSpeed(0.1), mTadapLevels(1), - mFrameNum(0), - mSeenValues( 0 ), mCalculatedValues( 0 ) -{ -} - - -/****************************************************************************** - * Destructor - *****************************************************************************/ -Parametrizer::~Parametrizer() -{ - /* not much to do... */ -} - -/****************************************************************************** - * Init from attr list - *****************************************************************************/ -void Parametrizer::parseAttrList() -{ - if(!mpAttrs) { - errFatal("Parametrizer::parseAttrList", "mpAttrs pointer not initialized!", SIMWORLD_INITERROR); - return; - } - - // unused - string mSetupType = ""; - mSetupType = mpAttrs->readString("p_setup",mSetupType, "Parametrizer","mSetupType", false); - - // real params - if(getAttributeList()->exists("p_viscosity")) { - mcViscosity = mpAttrs->readChannelFloat("p_viscosity"); seenThis( PARAM_VISCOSITY ); } - - mSoundSpeed = mpAttrs->readFloat("p_soundspeed",mSoundSpeed, "Parametrizer","mSoundSpeed", false); - if(getAttributeList()->exists("p_soundspeed")) seenThis( PARAM_SOUNDSPEED ); - - mDomainSize = mpAttrs->readFloat("p_domainsize",mDomainSize, "Parametrizer","mDomainSize", false); - if(getAttributeList()->exists("p_domainsize")) seenThis( PARAM_DOMAINSIZE ); - if(mDomainSize<=0.0) { - errMsg("Parametrizer::parseAttrList","Invalid real world domain size:"<<mDomainSize<<", resetting to 0.1"); - mDomainSize = 0.1; - } - - if(getAttributeList()->exists("p_gravity")) { // || (!mcGravity.isInited()) ) { - mcGravity = mpAttrs->readChannelVec3d("p_gravity"); seenThis( PARAM_GRAVITY ); - } - - mTimestep = mpAttrs->readFloat("p_steptime",mTimestep, "Parametrizer","mTimestep", false); - if(getAttributeList()->exists("p_steptime")) seenThis( PARAM_STEPTIME ); - - mTimeFactor = mpAttrs->readFloat("p_timefactor",mTimeFactor, "Parametrizer","mTimeFactor", false); - if(getAttributeList()->exists("p_timefactor")) seenThis( PARAM_TIMEFACTOR ); - - if(getAttributeList()->exists("p_aniframetime")) { //|| (!mcAniFrameTime.isInited()) ) { - mcAniFrameTime = mpAttrs->readChannelFloat("p_aniframetime");seenThis( PARAM_ANIFRAMETIME ); - } - mTimeStepScale = mpAttrs->readFloat("p_timestepscale",mTimeStepScale, "Parametrizer","mTimeStepScale", false); - - mAniStart = mpAttrs->readFloat("p_anistart",mAniStart, "Parametrizer","mAniStart", false); - if(getAttributeList()->exists("p_anistart")) seenThis( PARAM_ANISTART ); - if(mAniStart<0.0) { - errMsg("Parametrizer::parseAttrList","Invalid start time:"<<mAniStart<<", resetting to 0.0"); - mAniStart = 0.0; - } - - //mSurfaceTension = mpAttrs->readFloat("p_surfacetension",mSurfaceTension, "Parametrizer","mSurfaceTension", false); - //if(getAttributeList()->exists("p_surfacetension")) seenThis( PARAM_SURFACETENSION ); - - mDensity = mpAttrs->readFloat("p_density",mDensity, "Parametrizer","mDensity", false); - if(getAttributeList()->exists("p_density")) seenThis( PARAM_DENSITY ); - - ParamFloat cellSize = 0.0; // unused, deprecated - cellSize = mpAttrs->readFloat("p_cellsize",cellSize, "Parametrizer","cellSize", false); - - mGStar = mpAttrs->readFloat("p_gstar",mGStar, "Parametrizer","mGStar", false); - if(getAttributeList()->exists("p_gstar")) seenThis( PARAM_GSTAR ); - - mNormalizedGStar = mpAttrs->readFloat("p_normgstar",mNormalizedGStar, "Parametrizer","mNormalizedGStar", false); - if(getAttributeList()->exists("p_normgstar")) seenThis( PARAM_NORMALIZEDGSTAR ); - - mTadapMaxOmega = mpAttrs->readFloat("p_tadapmaxomega",mTadapMaxOmega, "Parametrizer","mTadapMaxOmega", false); - mTadapMaxSpeed = mpAttrs->readFloat("p_tadapmaxspeed",mTadapMaxSpeed, "Parametrizer","mTadapMaxSpeed", false); -} - -/****************************************************************************** - *! advance to next render/output frame - *****************************************************************************/ -void Parametrizer::setFrameNum(int frame) { - mFrameNum = frame; -#if DEBUG_PARAMCHANNELS>0 - errMsg("DEBUG_PARAMCHANNELS","setFrameNum frame-num="<<mFrameNum); -#endif // DEBUG_PARAMCHANNELS>0 -} -/*! get time of an animation frame (renderer) */ -// also used by: mpParam->getCurrentAniFrameTime() , e.g. for velocity dump -ParamFloat Parametrizer::getAniFrameTime( int frame ) { - double frametime = (double)frame; - ParamFloat anift = mcAniFrameTime.get(frametime); - if(anift<0.0) { - ParamFloat resetv = 0.; - errMsg("Parametrizer::setFrameNum","Invalid frame time:"<<anift<<" at frame "<<frame<<", resetting to "<<resetv); - anift = resetv; - } -#if DEBUG_PARAMCHANNELS>0 - if((0)|| (DEBUG_PARAMCHANNELS)) errMsg("DEBUG_PARAMCHANNELS","getAniFrameTime frame="<<frame<<", frametime="<<anift<<" "); -#endif // DEBUG_PARAMCHANNELS>0 - return anift; -} - -/****************************************************************************** - * scale a given speed vector in m/s to lattice values - *****************************************************************************/ -ParamVec Parametrizer::calculateAddForce(ParamVec vec, string usage) -{ - ParamVec ret = vec * (mTimestep*mTimestep) /mCellSize; - debMsgStd("Parametrizer::calculateVector", DM_MSG, "scaled vector = "<<ret<<" for '"<<usage<<"', org = "<<vec<<" dt="<<mTimestep ,10); - return ret; -} - - -/****************************************************************************** - * calculate size of a single cell - *****************************************************************************/ -ParamFloat Parametrizer::calculateCellSize(void) -{ - int maxsize = mSizex; // get max size - if(mSizey>maxsize) maxsize = mSizey; - if(mSizez>maxsize) maxsize = mSizez; - maxsize = mSizez; // take along gravity dir for now! - ParamFloat cellSize = 1.0 / (ParamFloat)maxsize; - return cellSize; -} - - -/*****************************************************************************/ -/* simple calulation functions */ -/*****************************************************************************/ - -/*! get omega for LBM from channel */ -ParamFloat Parametrizer::calculateOmega( double time ) { - ParamFloat viscStar = calculateLatticeViscosity(time); - ParamFloat relaxTime = (6.0 * viscStar + 1) * 0.5; -#if DEBUG_PARAMCHANNELS>0 - errMsg("DEBUG_PARAMCHANNELS","calculateOmega viscStar="<<viscStar<<" relaxtime="<<relaxTime); -#endif // DEBUG_PARAMCHANNELS>0 - return (1.0/relaxTime); -} - -/*! get external force x component */ -ParamVec Parametrizer::calculateGravity( double time ) { - ParamVec grav = mcGravity.get(time); - ParamFloat forceFactor = (mTimestep *mTimestep)/mCellSize; - ParamVec latticeGravity = grav * forceFactor; -#if DEBUG_PARAMCHANNELS>0 - errMsg("DEBUG_PARAMCHANNELS","calculateGravity grav="<<grav<<" ff"<<forceFactor<<" lattGrav="<<latticeGravity); -#endif // DEBUG_PARAMCHANNELS>0 - return latticeGravity; -} - -/*! calculate the lattice viscosity */ -ParamFloat Parametrizer::calculateLatticeViscosity( double time ) { - // check seen values - int reqValues = PARAM_VISCOSITY | PARAM_STEPTIME; - if(!checkSeenValues( reqValues ) ){ - errMsg("Parametrizer::calculateLatticeViscosity"," Missing arguments!"); - } - ParamFloat viscStar = mcViscosity.get(time) * mTimestep / (mCellSize*mCellSize); -#if DEBUG_PARAMCHANNELS>0 - errMsg("DEBUG_PARAMCHANNELS","calculateLatticeViscosity viscStar="<<viscStar); -#endif // DEBUG_PARAMCHANNELS>0 - return viscStar; -} - -/*! get no of steps for the given length in seconds */ -int Parametrizer::calculateStepsForSecs( ParamFloat s ) { - return (int)(s/mTimestep); -} - -/*! get start time of animation */ -int Parametrizer::calculateAniStart( void ) { - return (int)(mAniStart/mTimestep); -} - -/*! get no of steps for a single animation frame */ -int Parametrizer::calculateAniStepsPerFrame(int frame) { - if(!checkSeenValues(PARAM_ANIFRAMETIME)) { - errFatal("Parametrizer::calculateAniStepsPerFrame", "Missing ani frame time argument!", SIMWORLD_INITERROR); - return 1; - } - int value = (int)(getAniFrameTime(frame)/mTimestep); - if((value<0) || (value>1000000)) { - errFatal("Parametrizer::calculateAniStepsPerFrame", "Invalid step-time (="<<value<<") <> ani-frame-time ("<<mTimestep<<") settings, aborting...", SIMWORLD_INITERROR); - return 1; - } - return value; -} - -/*! get no. of timesteps for LBM */ -int Parametrizer::calculateNoOfSteps( ParamFloat timelen ) { - return (int)(timelen/mTimestep); -} - -/*! get extent of the domain = (1,1,1) if parametrizer not used, (x,y,z) [m] otherwise */ -//ParamVec Parametrizer::calculateExtent( void ) { - //return mExtent; -//} - -/*! get (scaled) surface tension */ -//ParamFloat Parametrizer::calculateSurfaceTension( void ) { return mSurfaceTension; } - -/*! get the length of a single time step */ -// explicity scaled by time factor for refinement -ParamFloat Parametrizer::getTimestep( void ) { - return mTimestep; -} - -/*! calculate lattice velocity from real world value [m/s] */ -ParamVec Parametrizer::calculateLattVelocityFromRw( ParamVec ivel ) { - ParamVec velvec = ivel; - velvec /= mCellSize; - velvec *= mTimestep; - return velvec; -} -/*! calculate real world [m/s] velocity from lattice value */ -ParamVec Parametrizer::calculateRwVelocityFromLatt( ParamVec ivel ) { - ParamVec velvec = ivel; - velvec *= mCellSize; - velvec /= mTimestep; - return velvec; -} - - -/*! get g star value with fhvol calculations */ -ParamFloat Parametrizer::getCurrentGStar( void ) { - ParamFloat gStar = mGStar; // check? TODO get from mNormalizedGStar? - if(mFluidVolumeHeight>0.0) { gStar = mGStar/mFluidVolumeHeight; } - return gStar; -} - -/****************************************************************************** - * function that tries to calculate all the missing values from the given ones - * prints errors and returns false if thats not possible - *****************************************************************************/ -bool Parametrizer::calculateAllMissingValues( double time, bool silent ) -{ - bool init = false; // did we init correctly? - int valuesChecked = 0; - int reqValues; - - // we always need the sizes - reqValues = PARAM_SIZE; - valuesChecked |= reqValues; - if(!checkSeenValues(reqValues)) { - errMsg("Parametrizer::calculateAllMissingValues"," Missing size argument!"); - return false; - } - - if(!checkSeenValues(PARAM_DOMAINSIZE)) { - errMsg("Parametrizer::calculateAllMissingValues"," Missing domain size argument!"); - return false; - } - int maxsize = mSizex; // get max size - if(mSizey>maxsize) maxsize = mSizey; - if(mSizez>maxsize) maxsize = mSizez; - maxsize = mSizez; // take along gravity dir for now! - mCellSize = ( mDomainSize * calculateCellSize() ); // sets mCellSize - if(!silent) debMsgStd("Parametrizer::calculateAllMissingValues",DM_MSG," max domain resolution="<<(maxsize)<<" cells , cellsize="<<mCellSize ,10); - - - /* Carolin init , see DA for details */ - ParamFloat maxDeltaT = 0.0; - - /* normalized gstar init */ - reqValues = PARAM_NORMALIZEDGSTAR; - valuesChecked |= reqValues; - if(checkSeenValues( reqValues ) ){ - //if(checkSeenValues( PARAM_GSTAR ) ){ if(!silent) debMsgStd("Parametrizer::calculateAllMissingValues",DM_WARNING," g star value override by normalizedGStar!",1); } - const ParamFloat normgstarReset = 0.005; - if(mNormalizedGStar<=1e-6) { - errMsg("Parametrizer::calculateAllMissingValues","Invalid NormGstar: "<<mNormalizedGStar<<"... resetting to "<<normgstarReset); - mNormalizedGStar = normgstarReset; - } - - mGStar = mNormalizedGStar/maxsize; - -// TODO FIXME add use testdata check! -mGStar = mNormalizedGStar/mSizez; -errMsg("Warning","Used z-dir for gstar!"); - - if(!silent) debMsgStd("Parametrizer::calculateAllMissingValues",DM_MSG," g star set to "<<mGStar<<" from normalizedGStar="<<mNormalizedGStar ,1); - seenThis(PARAM_GSTAR); - } - - reqValues = PARAM_GSTAR | PARAM_VISCOSITY; - if((checkSeenValues(PARAM_SURFACETENSION))) reqValues |= PARAM_DENSITY; // surface tension optional now... - valuesChecked |= reqValues; - if(checkSeenValues( reqValues ) ){ - const ParamFloat gstarReset = 0.0005; - if(getCurrentGStar()<=1e-6) { - errMsg("Parametrizer::calculateAllMissingValues","Invalid Gstar: "<<getCurrentGStar()<<" (set to "<<mGStar<<") ... resetting to "<<gstarReset); - mGStar = gstarReset; - } - - ParamFloat gStar = getCurrentGStar(); // mGStar - if(mFluidVolumeHeight>0.0) { - debMsgStd("Parametrizer::calculateAllMissingValues",DM_MSG," height"<<mFluidVolumeHeight<<" resGStar = "<<gStar, 10); - } - if(!silent) debMsgStd("Parametrizer::calculateAllMissingValues",DM_MSG," g star = "<<gStar, 10); - - ParamFloat forceStrength = 0.0; - //if(checkSeenValues(PARAM_GRAVITY)) { forceStrength = norm( calculateGravity(time) ); } - if(checkSeenValues(PARAM_GRAVITY)) { forceStrength = norm( mcGravity.get(time) ); } - - // determine max. delta density per timestep trough gravity force - if(forceStrength>0.0) { - maxDeltaT = sqrt( gStar*mCellSize *mTimeStepScale /forceStrength ); - } else { - // use 1 lbm setp = 1 anim step as max - maxDeltaT = getAniFrameTime(0); - } - - if(!silent) debMsgStd("Parametrizer::calculateAllMissingValues",DM_MSG," targeted step time = "<<maxDeltaT, 10); - - //ParamFloat viscStarFac = mViscosity/(mCellSize*mCellSize); - //if(!silent) debMsgStd("Parametrizer::calculateAllMissingValues",DM_MSG," viscStarFac = "<<viscStarFac<<" viscosity:"<<mViscosity, 10); - - // time step adaptivty, only for caro with max sim speed - ParamFloat setDeltaT = maxDeltaT; - if(mDesiredTimestep>0.0) { - // explicitly set step time according to max velocity in sim - setDeltaT = mDesiredTimestep; - if(!silent) debMsgStd("Parametrizer::calculateAllMissingValues",DM_MSG," desired step time = "<<setDeltaT, 10); - mDesiredTimestep = -1.0; - } else { - // just use max delta t as current - } - - // and once for init determine minimal delta t by omega max. - if((mMinTimestep<0.0) || (mMaxTimestep<0.0)) { - ParamFloat minDeltaT; - ParamFloat maxOmega = mTadapMaxOmega; - ParamFloat minRelaxTime = 1.0/maxOmega; - for(int lev=1; lev<mTadapLevels; lev++) { - // make minRelaxTime larger for each level that exists... - minRelaxTime = 2.0 * (minRelaxTime-0.5) + 0.5; - } - maxOmega = 1.0/minRelaxTime; - if(!silent) debMsgStd("Parametrizer::calculateAllMissingValues",DM_MSG," maxOmega="<<maxOmega<<" minRelaxTime="<<minRelaxTime<<" levels="<<mTadapLevels, 1); - // visc-star for min relax time to calculate min delta ta - if(mcViscosity.get(time)>0.0) { - minDeltaT = ((2.0*minRelaxTime-1.0)/6.0) * mCellSize * mCellSize / mcViscosity.get(time); - } else { - // visc=0, this is not physical, but might happen - minDeltaT = 0.0; - } - if(!silent) debMsgStd("Parametrizer::calculateAllMissingValues",DM_MSG," min delta t = "<<minDeltaT<<" , range = " << (maxDeltaT/minDeltaT) ,1); - - // sim speed + accel shouldnt exceed 0.1? - mMaxTimestep = maxDeltaT; - mMinTimestep = minDeltaT; - // only use once... - } - - setTimestep( setDeltaT ); // set mTimestep to new value - init = true; - } - - // finish init - if(init) { - if(!silent) debMsgStd("Parametrizer::calculateAllMissingValues",DM_MSG," omega = "<<calculateOmega(0.0)<<", delt="<<mTimestep,1); - - if(checkSeenValues(PARAM_GRAVITY)) { - ParamFloat forceFactor = (mTimestep *mTimestep)/mCellSize; // only used for printing... - if(!silent) debMsgStd("Parametrizer::calculateAllMissingValues",DM_MSG," gravity force = "<<PRINT_NTLVEC(mcGravity.get(time))<<", scaled with "<<forceFactor<<" to "<<calculateGravity(time),1); - } - - //mExtent = ParamVec( mCellSize*mSizex, mCellSize*mSizey, mCellSize*mSizez ); - //if(!silent) debMsgStd("Parametrizer::calculateAllMissingValues",DM_MSG," domain extent = "<<PRINT_NTLVEC(mExtent)<<"m , gs:"<<PRINT_VEC(mSizex,mSizey,mSizez)<<" cs:"<<mCellSize,1); - - if(!checkSeenValues(PARAM_ANIFRAMETIME)) { - errFatal("Parametrizer::calculateAllMissingValues"," Warning no ani frame time given!", SIMWORLD_INITERROR); - setAniFrameTimeChannel( mTimestep ); - } - - if(!silent) debMsgStd("Parametrizer::calculateAllMissingValues",DM_MSG," ani frame steps = "<<calculateAniStepsPerFrame(mFrameNum)<<" for frame "<<mFrameNum, 1); - - if((checkSeenValues(PARAM_ANISTART))&&(calculateAniStart()>0)) { - if(!silent) debMsgStd("Parametrizer::calculateAllMissingValues",DM_MSG," ani start steps = "<<calculateAniStart()<<" ",1); - } - - if(! isSimworldOk() ) return false; - // everything ok - return true; - } - - // init failed ... failure: - errMsg("Parametrizer::calculateAllMissingValues "," invalid configuration!"); - if(!silent) debMsgStd("Parametrizer::calculateAllMissingValues ",DM_WARNING, " values seen:", 1); - for(int i=0;i<PARAM_NUMIDS;i++) { - if(checkSeenValues( 1<<i )) { - if(!silent) debMsgStd(" ",DM_NOTIFY, ParamStrings[i], 1); - } - } - if(!silent) debMsgStd("Parametrizer::calculateAllMissingValues ",DM_WARNING, "values checked but missing:", 1); - for(int i=0;i<PARAM_NUMIDS;i++) { - if((!checkSeenValues( 1<<i ))&& - ( (valuesChecked&(1<<i))==(1<<i)) ) { - debMsgStd(" ",DM_IMPORTANT, ParamStrings[i], 1); - } - } - - // print values? - return false; -} - - -/****************************************************************************** - * init debug functions - *****************************************************************************/ - - -/*! set kinematic viscosity */ -void Parametrizer::setViscosity(ParamFloat set) { - mcViscosity = AnimChannel<ParamFloat>(set); - seenThis( PARAM_VISCOSITY ); -#if DEBUG_PARAMCHANNELS>0 - { errMsg("DebugChannels","Parametrizer::mcViscosity set = "<< mcViscosity.printChannel() ); } -#endif // DEBUG_PARAMCHANNELS>0 -} -void Parametrizer::initViscosityChannel(vector<ParamFloat> val, vector<double> time) { - mcViscosity = AnimChannel<ParamFloat>(val,time); - seenThis( PARAM_VISCOSITY ); -#if DEBUG_PARAMCHANNELS>0 - { errMsg("DebugChannels","Parametrizer::mcViscosity initc = "<< mcViscosity.printChannel() ); } -#endif // DEBUG_PARAMCHANNELS>0 -} - -/*! set the external force */ -void Parametrizer::setGravity(ParamFloat setx, ParamFloat sety, ParamFloat setz) { - mcGravity = AnimChannel<ParamVec>(ParamVec(setx,sety,setz)); - seenThis( PARAM_GRAVITY ); -#if DEBUG_PARAMCHANNELS>0 - { errMsg("DebugChannels","Parametrizer::mcGravity set = "<< mcGravity.printChannel() ); } -#endif // DEBUG_PARAMCHANNELS>0 -} -void Parametrizer::setGravity(ParamVec set) { - mcGravity = AnimChannel<ParamVec>(set); - seenThis( PARAM_GRAVITY ); -#if DEBUG_PARAMCHANNELS>0 - { errMsg("DebugChannels","Parametrizer::mcGravity set = "<< mcGravity.printChannel() ); } -#endif // DEBUG_PARAMCHANNELS>0 -} -void Parametrizer::initGravityChannel(vector<ParamVec> val, vector<double> time) { - mcGravity = AnimChannel<ParamVec>(val,time); - seenThis( PARAM_GRAVITY ); -#if DEBUG_PARAMCHANNELS>0 - { errMsg("DebugChannels","Parametrizer::mcGravity initc = "<< mcGravity.printChannel() ); } -#endif // DEBUG_PARAMCHANNELS>0 -} - -/*! set time of an animation frame (renderer) */ -void Parametrizer::setAniFrameTimeChannel(ParamFloat set) { - mcAniFrameTime = AnimChannel<ParamFloat>(set); - seenThis( PARAM_ANIFRAMETIME ); -#if DEBUG_PARAMCHANNELS>0 - { errMsg("DebugChannels","Parametrizer::mcAniFrameTime set = "<< mcAniFrameTime.printChannel() ); } -#endif // DEBUG_PARAMCHANNELS>0 -} -void Parametrizer::initAniFrameTimeChannel(vector<ParamFloat> val, vector<double> time) { - mcAniFrameTime = AnimChannel<ParamFloat>(val,time); - seenThis( PARAM_ANIFRAMETIME ); -#if DEBUG_PARAMCHANNELS>0 - { errMsg("DebugChannels","Parametrizer::mcAniFrameTime initc = "<< mcAniFrameTime.printChannel() ); } -#endif // DEBUG_PARAMCHANNELS>0 -} - -// OLD interface stuff -// reactivate at some point? - - /*! surface tension, [kg/s^2] */ - //ParamFloat mSurfaceTension; - /*! set starting time of the animation (renderer) */ - //void setSurfaceTension(ParamFloat set) { mSurfaceTension = set; seenThis( PARAM_SURFACETENSION ); } - /*! get starting time of the animation (renderer) */ - //ParamFloat getSurfaceTension( void ) { return mSurfaceTension; } - /*if((checkSeenValues(PARAM_SURFACETENSION))&&(mSurfaceTension>0.0)) { - ParamFloat massDelta = 1.0; - ParamFloat densityStar = 1.0; - massDelta = mDensity / densityStar *mCellSize*mCellSize*mCellSize; - if(!silent) debMsgStd("Parametrizer::calculateAllMissingValues",DM_MSG," massDelta = "<<massDelta, 10); - - mSurfaceTension = mSurfaceTension*mTimestep*mTimestep/massDelta; - if(!silent) debMsgStd("Parametrizer::calculateAllMissingValues",DM_MSG," surface tension = "<<mSurfaceTension<<" ",1); - } // */ - -// probably just delete: - - /*! reynolds number (calculated from domain length and max. speed [dimensionless] */ - //ParamFloat mReynolds; - - /*! set relaxation time */ - //void setRelaxTime(ParamFloat set) { mRelaxTime = set; seenThis( PARAM_RELAXTIME ); } - /*! get relaxation time */ - //ParamFloat getRelaxTime( void ) { return mRelaxTime; } - /*! set reynolds number */ - //void setReynolds(ParamFloat set) { mReynolds = set; seenThis( PARAM_REYNOLDS ); } - /*! get reynolds number */ - //ParamFloat getReynolds( void ) { return mReynolds; } - - // calculate reynolds number - /*if(mViscosity>0.0) { - ParamFloat maxSpeed = 1.0/6.0; // for rough reynolds approx - ParamFloat reynoldsApprox = -1.0; - ParamFloat gridSpeed = (maxSpeed*mCellSize/mTimestep); - reynoldsApprox = (mDomainSize*gridSpeed) / mViscosity; - if(!silent) debMsgStd("Parametrizer::calculateAllMissingValues",DM_MSG," reynolds number (D="<<mDomainSize<<", assuming V="<<gridSpeed<<")= "<<reynoldsApprox<<" ", 1); - } // */ - - //? mRelaxTime = mpAttrs->readFloat("p_relaxtime",mRelaxTime, "Parametrizer","mRelaxTime", false); - //if(getAttributeList()->exists("p_relaxtime")) seenThis( PARAM_RELAXTIME ); - //? mReynolds = mpAttrs->readFloat("p_reynolds",mReynolds, "Parametrizer","mReynolds", false); - //if(getAttributeList()->exists("p_reynolds")) seenThis( PARAM_REYNOLDS ); - - //mViscosity = mpAttrs->readFloat("p_viscosity",mViscosity, "Parametrizer","mViscosity", false); - //if(getAttributeList()->exists("p_viscosity") || (!mcViscosity.isInited()) ) { } - //if(getAttributeList()->exists("p_viscosity")) - - - //ParamFloat viscStar = calculateLatticeViscosity(time); - //RelaxTime = (6.0 * viscStar + 1) * 0.5; - - diff --git a/intern/elbeem/intern/parametrizer.h b/intern/elbeem/intern/parametrizer.h deleted file mode 100644 index bd7377b9fbd..00000000000 --- a/intern/elbeem/intern/parametrizer.h +++ /dev/null @@ -1,322 +0,0 @@ -/** \file - * \ingroup elbeem - */ -/****************************************************************************** - * - * El'Beem - Free Surface Fluid Simulation with the Lattice Boltzmann Method - * Copyright 2003-2006 Nils Thuerey - * - * Parameter calculator for the LBM Solver class - * - *****************************************************************************/ -#ifndef MFFSLBM_PARAMETRIZER -#define MFFSLBM_PARAMETRIZER - - -/* LBM Files */ -#include "utilities.h" -#include "attributes.h" - -#ifdef WITH_CXX_GUARDEDALLOC -# include "MEM_guardedalloc.h" -#endif - -/* parametrizer accuracy */ -typedef double ParamFloat; -typedef ntlVec3d ParamVec; - -/*! flags to check which values are known */ -#define PARAM_RELAXTIME (1<< 0) -#define PARAM_REYNOLDS (1<< 1) -#define PARAM_VISCOSITY (1<< 2) -#define PARAM_SOUNDSPEED (1<< 3) -#define PARAM_DOMAINSIZE (1<< 4) -#define PARAM_GRAVITY (1<< 5) -#define PARAM_STEPTIME (1<< 7) -#define PARAM_SIZE (1<< 8) -#define PARAM_TIMEFACTOR (1<< 9) -#define PARAM_ANIFRAMETIME (1<<11) -#define PARAM_ANISTART (1<<12) -#define PARAM_SURFACETENSION (1<<13) -#define PARAM_DENSITY (1<<14) -#define PARAM_GSTAR (1<<16) -#define PARAM_SIMMAXSPEED (1<<18) -#define PARAM_FLUIDVOLHEIGHT (1<<19) -#define PARAM_NORMALIZEDGSTAR (1<<20) -#define PARAM_NUMIDS 21 - -//! output parameter debug message? -//#define PARAM_DEBUG 1 - - - -/*! Parameter calculator for the LBM Solver class */ -class Parametrizer { - - public: - /*! default contructor */ - Parametrizer(); - - /*! destructor */ - ~Parametrizer(); - - /*! Initilize variables fom attribute list */ - void parseAttrList( void ); - - /*! function that tries to calculate all the missing values from the given ones - * prints errors and returns false if thats not possible - * currently needs time value as well */ - bool calculateAllMissingValues( double time, bool silent ); - /*! is the parametrizer used at all? */ - bool isUsed() { return true; } - - /*! add this flag to the seen values */ - void seenThis(int seen) { mSeenValues = (mSeenValues | seen); -#ifdef PARAM_DEBUG - errorOut(" seen "<<seen<<endl); -#endif - } - - /*! set the flags integer */ - void setSeenValues(int set) { mSeenValues = set; } - /*! check if the flags are set in the values int */ - bool checkSeenValues(int check) { /*errorOut( " b"<<((mSeenValues&check)==check) );*/ return ((mSeenValues&check)==check); } - - /*! add this flag to the calculated values */ - void calculatedThis(int cac) { mCalculatedValues = (mCalculatedValues | cac); /*errorOut(" a "<<seen);*/ } - /*! set the calculated flags integer */ - void setCalculatedValues(int set) { mCalculatedValues = set; } - /*! check if the calculated flags are set in the values int */ - bool checkCalculatedValues(int check) { /*errorOut( " b"<<((mSeenValues&check)==check) );*/ return ((mCalculatedValues&check)==check); } - /*! advance to next render/output frame */ - void setFrameNum(int frame); - ParamFloat getAniFrameTime(int frame); - ParamFloat getCurrentAniFrameTime(){ return getAniFrameTime(mFrameNum); }; - - /*! scale a given speed vector in m/s to lattice values - * usage string is only needed for debugging */ - ParamVec calculateAddForce(ParamVec vec, string usage); - - /* simple calulation functions */ - /*! get omega for LBM */ - ParamFloat calculateOmega( double time ); - /*! get no. of timesteps for LBM */ - int calculateNoOfSteps( ParamFloat timelen ); - /*! get external force x component */ - ParamVec calculateGravity( double time ); - /*! get no of steps for the given length in seconds */ - int calculateStepsForSecs( ParamFloat s ); - /*! get no of steps for a singel animation frame */ - int calculateAniStepsPerFrame(int frame); - /*! get start time of animation */ - int calculateAniStart( void ); - /*! get extent of the domain = (1,1,1) if parametrizer not used, (x,y,z) [m] otherwise */ - //ParamVec calculateExtent( void ); - /*! get (scaled) surface tension */ - ParamFloat calculateSurfaceTension( void ); - /*! get time step size for lbm (equals mTimeFactor) */ - // unused ParamFloat calculateTimestep( void ); - /*! calculate size of a single cell */ - ParamFloat calculateCellSize(void); - /*! calculate the lattice viscosity */ - ParamFloat calculateLatticeViscosity( double time ); - - /*! calculate lattice velocity from real world value [m/s] */ - ParamVec calculateLattVelocityFromRw( ParamVec ivel ); - /*! calculate real world [m/s] velocity from lattice value */ - ParamVec calculateRwVelocityFromLatt( ParamVec ivel ); - - /*! set speed of sound */ - void setSoundSpeed(ParamFloat set) { mSoundSpeed = set; seenThis( PARAM_SOUNDSPEED ); } - /*! get speed of sound */ - ParamFloat getSoundSpeed( void ) { return mSoundSpeed; } - - /*! set kinematic viscosity */ - void setViscosity(ParamFloat set); - void initViscosityChannel(vector<ParamFloat> val, vector<double> time); - - /*! set the external force */ - void setGravity(ParamFloat setx, ParamFloat sety, ParamFloat setz); - void setGravity(ParamVec set); - void initGravityChannel(vector<ParamVec> val, vector<double> time); - ParamVec getGravity(double time) { return mcGravity.get( time ); } - - /*! set time of an animation frame (renderer) */ - void setAniFrameTimeChannel(ParamFloat set); - void initAniFrameTimeChannel(vector<ParamFloat> val, vector<double> time); - - /*! set the length of a single time step */ - void setTimestep(ParamFloat set) { mTimestep = set; seenThis( PARAM_STEPTIME ); } - /*! get the length of a single time step */ - ParamFloat getTimestep( void); - /*! set a desired step time for rescaling/adaptive timestepping */ - void setDesiredTimestep(ParamFloat set) { mDesiredTimestep = set; } - /*! get the length of a single time step */ - ParamFloat getMaxTimestep( void ) { return mMaxTimestep; } - /*! get the length of a single time step */ - ParamFloat getMinTimestep( void ) { return mMinTimestep; } - - /*! set the time scaling factor */ - void setTimeFactor(ParamFloat set) { mTimeFactor = set; seenThis( PARAM_TIMEFACTOR ); } - /*! get the time scaling factor */ - ParamFloat getTimeFactor( void ) { return mTimeFactor; } - - /*! init domain resoultion */ - void setSize(int ijk) { mSizex = ijk; mSizey = ijk; mSizez = ijk; seenThis( PARAM_SIZE ); } - void setSize(int i,int j, int k) { mSizex = i; mSizey = j; mSizez = k; seenThis( PARAM_SIZE ); } - - /*! set starting time of the animation (renderer) */ - void setAniStart(ParamFloat set) { mAniStart = set; seenThis( PARAM_ANISTART ); } - /*! get starting time of the animation (renderer) */ - ParamFloat getAniStart( void ) { return mAniStart; } - - /*! set fluid density */ - void setDensity(ParamFloat set) { mDensity = set; seenThis( PARAM_DENSITY ); } - /*! get fluid density */ - ParamFloat getDensity( void ) { return mDensity; } - - /*! set g star value */ - void setGStar(ParamFloat set) { mGStar = set; seenThis( PARAM_GSTAR ); } - /*! get g star value */ - ParamFloat getGStar( void ) { return mGStar; } - /*! get g star value with fhvol calculations */ - ParamFloat getCurrentGStar( void ); - /*! set normalized g star value */ - void setNormalizedGStar(ParamFloat set) { mNormalizedGStar = set; seenThis( PARAM_NORMALIZEDGSTAR ); } - /*! get normalized g star value */ - ParamFloat getNormalizedGStar( void ) { return mNormalizedGStar; } - - /*! set g star value */ - void setFluidVolumeHeight(ParamFloat set) { mFluidVolumeHeight = set; seenThis( PARAM_FLUIDVOLHEIGHT ); } - /*! get g star value */ - ParamFloat getFluidVolumeHeight( void ) { return mFluidVolumeHeight; } - - /*! set the size of a single lbm cell */ - void setDomainSize(ParamFloat set) { mDomainSize = set; seenThis( PARAM_DOMAINSIZE ); } - /*! get the size of a single lbm cell */ - ParamFloat getDomainSize( void ) { return mDomainSize; } - - /*! set the size of a single lbm cell (dont use, normally set by domainsize and resolution) */ - void setCellSize(ParamFloat set) { mCellSize = set; } - /*! get the size of a single lbm cell */ - ParamFloat getCellSize( void ) { return mCellSize; } - - /*! set active flag for parametrizer */ - //void setActive(bool set) { mActive = set; } - - /*! set attr list pointer */ - void setAttrList(AttributeList *set) { mpAttrs = set; } - /*! Returns the attribute list pointer */ - inline AttributeList *getAttributeList() { return mpAttrs; } - - /*! set maximum allowed speed for maxspeed setup */ - void setSimulationMaxSpeed(ParamFloat set) { mSimulationMaxSpeed = set; seenThis( PARAM_SIMMAXSPEED ); } - /*! get maximum allowed speed for maxspeed setup */ - ParamFloat getSimulationMaxSpeed( void ) { return mSimulationMaxSpeed; } - - /*! set maximum allowed omega for time adaptivity */ - void setTadapMaxOmega(ParamFloat set) { mTadapMaxOmega = set; } - /*! get maximum allowed omega for time adaptivity */ - ParamFloat getTadapMaxOmega( void ) { return mTadapMaxOmega; } - - /*! set maximum allowed speed for time adaptivity */ - void setTadapMaxSpeed(ParamFloat set) { mTadapMaxSpeed = set; } - /*! get maximum allowed speed for time adaptivity */ - ParamFloat getTadapMaxSpeed( void ) { return mTadapMaxSpeed; } - - /*! set maximum allowed omega for time adaptivity */ - void setTadapLevels(int set) { mTadapLevels = set; } - /*! get maximum allowed omega for time adaptivity */ - int getTadapLevels( void ) { return mTadapLevels; } - - /*! set */ - // void set(ParamFloat set) { m = set; seenThis( PARAM_ ); } - /*! get */ - // ParamFloat get( void ) { return m; } - - - - private: - - /*! kinematic viscosity of the fluid [m^2/s] */ - AnimChannel<ParamFloat> mcViscosity; - - /*! speed of sound of the fluid [m/s] */ - ParamFloat mSoundSpeed; - - /*! size of the domain [m] */ - ParamFloat mDomainSize; - - /*! size of a single cell in the grid [m] */ - ParamFloat mCellSize; - - /*! time step length [s] */ - ParamFloat mTimeStep; - - /*! external force as acceleration [m/s^2] */ - AnimChannel<ParamVec> mcGravity; - - /*! length of one time step in the simulation */ - ParamFloat mTimestep; - /*! desired step time for rescaling/adaptive timestepping, only regarded if >0.0, reset after usage */ - ParamFloat mDesiredTimestep; - /*! minimal and maximal step times for current setup */ - ParamFloat mMaxTimestep, mMinTimestep; - - /*! domain resoultion, the same values as in lbmsolver */ - int mSizex, mSizey, mSizez; - - /*! time scaling factor (auto calc from accel, or set), equals the delta t in LBM */ - ParamFloat mTimeFactor; - - /*! for renderer - length of an animation step [s] */ - AnimChannel<ParamFloat> mcAniFrameTime; - /*! time step scaling factor for testing/debugging */ - ParamFloat mTimeStepScale; - - /*! for renderer - start time of the animation [s] */ - ParamFloat mAniStart; - - /*! extent of the domain in meters */ - //ParamVec mExtent; - - /*! fluid density [kg/m^3], default 1.0 g/cm^3 */ - ParamFloat mDensity; - - /*! max difference due to gravity (for caro setup) */ - ParamFloat mGStar; - /*! set gstar normalized! */ - ParamFloat mNormalizedGStar; - /*! fluid volume/height multiplier for GStar */ - ParamFloat mFluidVolumeHeight; - - /*! current max speed of the simulation (for adaptive time steps) */ - ParamFloat mSimulationMaxSpeed; - /*! maximum omega (for adaptive time steps) */ - ParamFloat mTadapMaxOmega; - /*! maximum allowed speed in lattice units e.g. 0.1 (for adaptive time steps, not directly used in parametrizer) */ - ParamFloat mTadapMaxSpeed; - /*! no. of levels for max omega (set by fsgr, not in cfg file) */ - int mTadapLevels; - - /*! remember current frame number */ - int mFrameNum; - - /*! values that are seen for this simulation */ - int mSeenValues; - - /*! values that are calculated from the seen ones for this simulation */ - int mCalculatedValues; - - /*! pointer to the attribute list */ - AttributeList *mpAttrs; - -private: -#ifdef WITH_CXX_GUARDEDALLOC - MEM_CXX_CLASS_ALLOC_FUNCS("ELBEEM:Parametrizer") -#endif -}; - - -#endif - diff --git a/intern/elbeem/intern/particletracer.cpp b/intern/elbeem/intern/particletracer.cpp deleted file mode 100644 index 7a0005f67ce..00000000000 --- a/intern/elbeem/intern/particletracer.cpp +++ /dev/null @@ -1,470 +0,0 @@ -/** \file - * \ingroup elbeem - */ -/****************************************************************************** - * - * El'Beem - Free Surface Fluid Simulation with the Lattice Boltzmann Method - * Copyright 2003-2006 Nils Thuerey - * - * Particle Viewer/Tracer - * - *****************************************************************************/ - -#include <stdio.h> -//#include "../libs/my_gl.h" -//#include "../libs/my_glu.h" - -/* own lib's */ -#include "particletracer.h" -#include "ntl_matrices.h" -#include "ntl_ray.h" -#include "ntl_matrices.h" -#include "globals.h" - -#include <zlib.h> - - -// particle object id counter -int ParticleObjectIdCnt = 1; - -/****************************************************************************** - * Standard constructor - *****************************************************************************/ -ParticleTracer::ParticleTracer() : - ntlGeometryObject(), - mParts(), - //mTrailLength(1), mTrailInterval(1),mTrailIntervalCounter(0), - mPartSize(0.01), - mStart(-1.0), mEnd(1.0), - mSimStart(-1.0), mSimEnd(1.0), - mPartScale(0.1) , mPartHeadDist( 0.1 ), mPartTailDist( -0.1 ), mPartSegments( 4 ), - mValueScale(0), - mValueCutoffTop(0.0), mValueCutoffBottom(0.0), - mDumpParts(0), //mDumpText(0), - mDumpTextFile(""), - mDumpTextInterval(0.), mDumpTextLastTime(0.), mDumpTextCount(0), - mShowOnly(0), - mNumInitialParts(0), mpTrafo(NULL), - mInitStart(-1.), mInitEnd(-1.), - mPrevs(), mTrailTimeLast(0.), mTrailInterval(-1.), mTrailLength(0) -{ - debMsgStd("ParticleTracer::ParticleTracer",DM_MSG,"inited",10); -}; - -ParticleTracer::~ParticleTracer() { - debMsgStd("ParticleTracer::~ParticleTracer",DM_MSG,"destroyed",10); - if(mpTrafo) delete mpTrafo; -} - -/*****************************************************************************/ -//! parse settings from attributes (dont use own list!) -/*****************************************************************************/ -void ParticleTracer::parseAttrList(AttributeList *att) -{ - AttributeList *tempAtt = mpAttrs; - mpAttrs = att; - - mNumInitialParts = mpAttrs->readInt("particles",mNumInitialParts, "ParticleTracer","mNumInitialParts", false); - //errMsg(" NUMP"," "<<mNumInitialParts); - mPartScale = mpAttrs->readFloat("part_scale",mPartScale, "ParticleTracer","mPartScale", false); - mPartHeadDist = mpAttrs->readFloat("part_headdist",mPartHeadDist, "ParticleTracer","mPartHeadDist", false); - mPartTailDist = mpAttrs->readFloat("part_taildist",mPartTailDist, "ParticleTracer","mPartTailDist", false); - mPartSegments = mpAttrs->readInt ("part_segments",mPartSegments, "ParticleTracer","mPartSegments", false); - mValueScale = mpAttrs->readInt ("part_valscale",mValueScale, "ParticleTracer","mValueScale", false); - mValueCutoffTop = mpAttrs->readFloat("part_valcutofftop",mValueCutoffTop, "ParticleTracer","mValueCutoffTop", false); - mValueCutoffBottom = mpAttrs->readFloat("part_valcutoffbottom",mValueCutoffBottom, "ParticleTracer","mValueCutoffBottom", false); - - mDumpParts = mpAttrs->readInt ("part_dump",mDumpParts, "ParticleTracer","mDumpParts", false); - // mDumpText deprecatd, use mDumpTextInterval>0. instead - mShowOnly = mpAttrs->readInt ("part_showonly",mShowOnly, "ParticleTracer","mShowOnly", false); - mDumpTextFile= mpAttrs->readString("part_textdumpfile",mDumpTextFile, "ParticleTracer","mDumpTextFile", false); - mDumpTextInterval= mpAttrs->readFloat("part_textdumpinterval",mDumpTextInterval, "ParticleTracer","mDumpTextInterval", false); - - string matPart; - matPart = mpAttrs->readString("material_part", "default", "ParticleTracer","material", false); - setMaterialName( matPart ); - - mInitStart = mpAttrs->readFloat("part_initstart",mInitStart, "ParticleTracer","mInitStart", false); - mInitEnd = mpAttrs->readFloat("part_initend", mInitEnd, "ParticleTracer","mInitEnd", false); - - // unused... - //int mTrailLength = 0; // UNUSED - //int mTrailInterval= 0; // UNUSED - mTrailLength = mpAttrs->readInt("traillength",mTrailLength, "ParticleTracer","mTrailLength", false); - mTrailInterval= mpAttrs->readFloat("trailinterval",mTrailInterval, "ParticleTracer","mTrailInterval", false); - - // restore old list - mpAttrs = tempAtt; -} - -/****************************************************************************** - * draw the particle array - *****************************************************************************/ -void ParticleTracer::draw() -{ -} - -/****************************************************************************** - * init trafo matrix - *****************************************************************************/ -void ParticleTracer::initTrafoMatrix() { - ntlVec3Gfx scale = ntlVec3Gfx( - (mEnd[0]-mStart[0])/(mSimEnd[0]-mSimStart[0]), - (mEnd[1]-mStart[1])/(mSimEnd[1]-mSimStart[1]), - (mEnd[2]-mStart[2])/(mSimEnd[2]-mSimStart[2]) - ); - ntlVec3Gfx trans = mStart; - if(!mpTrafo) mpTrafo = new ntlMat4Gfx(0.0); - mpTrafo->initId(); - for(int i=0; i<3; i++) { mpTrafo->value[i][i] = scale[i]; } - for(int i=0; i<3; i++) { mpTrafo->value[i][3] = trans[i]; } -} - -/****************************************************************************** - * adapt time step by rescaling velocities - *****************************************************************************/ -void ParticleTracer::adaptPartTimestep(float factor) { - for(size_t i=0; i<mParts.size(); i++) { - mParts[i].setVel( mParts[i].getVel() * factor ); - } -} - - -/****************************************************************************** - * add a particle at this position - *****************************************************************************/ -void ParticleTracer::addParticle(float x, float y, float z) { - ntlVec3Gfx p(x,y,z); - ParticleObject part( p ); - mParts.push_back( part ); -} -void ParticleTracer::addFullParticle(ParticleObject &np) { - mParts.push_back( np ); -} - - -void ParticleTracer::cleanup() { - // cleanup - int last = (int)mParts.size()-1; - if(mDumpTextInterval>0.) { errMsg("ParticleTracer::cleanup","Skipping cleanup due to text dump..."); return; } - - for(int i=0; i<=last; i++) { - if( mParts[i].getActive()==false ) { - ParticleObject *p = &mParts[i]; - ParticleObject *p2 = &mParts[last]; - *p = *p2; last--; mParts.pop_back(); - } - } -} - -/****************************************************************************** - *! dump particles if desired - *****************************************************************************/ -void ParticleTracer::notifyOfDump(int dumptype, int frameNr,char *frameNrStr,string outfilename, double simtime) { - debMsgStd("ParticleTracer::notifyOfDump",DM_MSG,"obj:"<<this->getName()<<" frame:"<<frameNrStr<<" dumpp"<<mDumpParts<<" t"<<simtime, 10); // DEBUG - - if( - (dumptype==DUMP_FULLGEOMETRY)&& - (mDumpParts>0)) { - // dump to binary file - std::ostringstream boutfilename(""); - boutfilename << outfilename <<"_particles_" << frameNrStr; - if(glob_mpactive) { - if(glob_mpindex>0) { boutfilename << "mp"<<glob_mpindex; } - } - boutfilename << ".gz"; - debMsgStd("ParticleTracer::notifyOfDump",DM_MSG,"B-Dumping: "<< this->getName() <<", particles:"<<mParts.size()<<" "<< " to "<<boutfilename.str()<<" #"<<frameNr , 7); - //debMsgStd("ParticleTracer::notifyOfDump",DM_MSG,"B-Dumping: partgeodeb sim:"<<mSimStart<<","<<mSimEnd<<" geosize:"<<mStart<<","<<mEnd,2 ); - - // output to zipped file - gzFile gzf; - gzf = gzopen(boutfilename.str().c_str(), "wb1"); - if(gzf) { - int numParts; - if(sizeof(numParts)!=4) { errMsg("ParticleTracer::notifyOfDump","Invalid int size"); return; } - // only dump active particles - numParts = 0; - for(size_t i=0; i<mParts.size(); i++) { - if(!mParts[i].getActive()) continue; - numParts++; - } - gzwrite(gzf, &numParts, sizeof(numParts)); - for(size_t i=0; i<mParts.size(); i++) { - if(!mParts[i].getActive()) { continue; } - ParticleObject *p = &mParts[i]; - //int type = p->getType(); // export whole type info - int type = p->getFlags(); // debug export whole type & status info - ntlVec3Gfx pos = p->getPos(); - float size = p->getSize(); - - if(type&PART_FLOAT) { // WARNING same handling for dump! - // add one gridcell offset - //pos[2] += 1.0; - } - // display as drop for now externally - //else if(type&PART_TRACER) { type |= PART_DROP; } - - pos = (*mpTrafo) * pos; - - ntlVec3Gfx v = p->getVel(); - v[0] *= mpTrafo->value[0][0]; - v[1] *= mpTrafo->value[1][1]; - v[2] *= mpTrafo->value[2][2]; - // FIXME check: pos = (*mpTrafo) * pos; - gzwrite(gzf, &type, sizeof(type)); - gzwrite(gzf, &size, sizeof(size)); - for(int j=0; j<3; j++) { gzwrite(gzf, &pos[j], sizeof(float)); } - for(int j=0; j<3; j++) { gzwrite(gzf, &v[j], sizeof(float)); } - } - gzclose( gzf ); - } - } // dump? -} - -void ParticleTracer::checkDumpTextPositions(double simtime) { - // dfor partial & full dump - if(mDumpTextInterval>0.) { - debMsgStd("ParticleTracer::checkDumpTextPositions",DM_MSG,"t="<<simtime<<" last:"<<mDumpTextLastTime<<" inter:"<<mDumpTextInterval,7); - } - - if((mDumpTextInterval>0.) && (simtime>mDumpTextLastTime+mDumpTextInterval)) { - // dump to binary file - std::ostringstream boutfilename(""); - if(mDumpTextFile.length()>1) { - boutfilename << mDumpTextFile << ".cpart2"; - } else { - boutfilename << "_particles" << ".cpart2"; - } - debMsgStd("ParticleTracer::checkDumpTextPositions",DM_MSG,"T-Dumping: "<< this->getName() <<", particles:"<<mParts.size()<<" "<< " to "<<boutfilename.str()<<" " , 7); - - int numParts = 0; - // only dump bubble particles - for(size_t i=0; i<mParts.size(); i++) { - //if(!mParts[i].getActive()) continue; - //if(!(mParts[i].getType()&PART_BUBBLE)) continue; - numParts++; - } - - // output to text file - //gzFile gzf; - FILE *stf; - if(mDumpTextCount==0) { - //gzf = gzopen(boutfilename.str().c_str(), "w0"); - stf = fopen(boutfilename.str().c_str(), "w"); - - fprintf( stf, "\n\n# cparts generated by elbeem \n# no. of parts \nN %d \n\n",numParts); - // fixed time scale for now - fprintf( stf, "T %f \n\n", 1.0); - } else { - //gzf = gzopen(boutfilename.str().c_str(), "a+0"); - stf = fopen(boutfilename.str().c_str(), "a+"); - } - - // add current set - if(stf) { - fprintf( stf, "\n\n# new set at frame %d,t%f,p%d --------------------------------- \n\n", mDumpTextCount, simtime, numParts ); - fprintf( stf, "S %f \n\n", simtime ); - - for(size_t i=0; i<mParts.size(); i++) { - ParticleObject *p = &mParts[i]; - ntlVec3Gfx pos = p->getPos(); - float size = p->getSize(); - float infl = 1.; - //if(!mParts[i].getActive()) { size=0.; } // switch "off" - if(!mParts[i].getActive()) { infl=0.; } // switch "off" - if(!mParts[i].getInFluid()) { infl=0.; } // switch "off" - if(mParts[i].getLifeTime()<0.) { infl=0.; } // not yet active... - - pos = (*mpTrafo) * pos; - ntlVec3Gfx v = p->getVel(); - v[0] *= mpTrafo->value[0][0]; - v[1] *= mpTrafo->value[1][1]; - v[2] *= mpTrafo->value[2][2]; - - fprintf( stf, "P %f %f %f \n", pos[0],pos[1],pos[2] ); - if(size!=1.0) fprintf( stf, "s %f \n", size ); - if(infl!=1.0) fprintf( stf, "i %f \n", infl ); - fprintf( stf, "\n" ); - } - - fprintf( stf, "# %d end ", mDumpTextCount ); - //gzclose( gzf ); - fclose( stf ); - - mDumpTextCount++; - } - - mDumpTextLastTime += mDumpTextInterval; - } - -} - - -void ParticleTracer::checkTrails(double time) { - if(mTrailLength<1) return; - if(time-mTrailTimeLast > mTrailInterval) { - - if( (int)mPrevs.size() < mTrailLength) mPrevs.resize( mTrailLength ); - for(int i=mPrevs.size()-1; i>0; i--) { - mPrevs[i] = mPrevs[i-1]; - //errMsg("TRAIL"," from "<<i<<" to "<<(i-1) ); - } - mPrevs[0] = mParts; - - mTrailTimeLast += mTrailInterval; - } -} - - -/****************************************************************************** - * Get triangles for rendering - *****************************************************************************/ -void ParticleTracer::getTriangles(double time, vector<ntlTriangle> *triangles, - vector<ntlVec3Gfx> *vertices, - vector<ntlVec3Gfx> *normals, int objectId ) -{ -#ifdef ELBEEM_PLUGIN - // suppress warnings... - vertices = NULL; triangles = NULL; - normals = NULL; objectId = 0; - time = 0.; -#else // ELBEEM_PLUGIN - int pcnt = 0; - // currently not used in blender - objectId = 0; // remove, deprecated - if(mDumpParts>1) { - return; // only dump, no tri-gen - } - - const bool debugParts = false; - int tris = 0; - int segments = mPartSegments; - ntlVec3Gfx scale = ntlVec3Gfx( (mEnd[0]-mStart[0])/(mSimEnd[0]-mSimStart[0]), (mEnd[1]-mStart[1])/(mSimEnd[1]-mSimStart[1]), (mEnd[2]-mStart[2])/(mSimEnd[2]-mSimStart[2])); - ntlVec3Gfx trans = mStart; - time = 0.; // doesnt matter - - for(size_t t=0; t<mPrevs.size()+1; t++) { - vector<ParticleObject> *dparts; - if(t==0) { - dparts = &mParts; - } else { - dparts = &mPrevs[t-1]; - } - //errMsg("TRAILT","prevs"<<t<<"/"<<mPrevs.size()<<" parts:"<<dparts->size() ); - - gfxReal partscale = mPartScale; - if(t>1) { - partscale *= (gfxReal)(mPrevs.size()+1-t) / (gfxReal)(mPrevs.size()+1); - } - gfxReal partNormSize = 0.01 * partscale; - //for(size_t i=0; i<mParts.size(); i++) { - for(size_t i=0; i<dparts->size(); i++) { - ParticleObject *p = &( (*dparts)[i] ); // mParts[i]; - - if(mShowOnly!=10) { - // 10=show only deleted - if( p->getActive()==false ) continue; - } else { - if( p->getActive()==true ) continue; - } - int type = p->getType(); - if(mShowOnly>0) { - switch(mShowOnly) { - case 1: if(!(type&PART_BUBBLE)) continue; break; - case 2: if(!(type&PART_DROP)) continue; break; - case 3: if(!(type&PART_INTER)) continue; break; - case 4: if(!(type&PART_FLOAT)) continue; break; - case 5: if(!(type&PART_TRACER)) continue; break; - } - } else { - // by default dont display inter - if(type&PART_INTER) continue; - } - - pcnt++; - ntlVec3Gfx pnew = p->getPos(); - if(type&PART_FLOAT) { // WARNING same handling for dump! - if(p->getStatus()&PART_IN) { pnew[2] += 0.8; } // offset for display - // add one gridcell offset - //pnew[2] += 1.0; - } -#if LBMDIM==2 - pnew[2] += 0.001; // DEBUG - pnew[2] += 0.009; // DEBUG -#endif - - ntlVec3Gfx pdir = p->getVel(); - gfxReal plen = normalize( pdir ); - if( plen < 1e-05) pdir = ntlVec3Gfx(-1.0 ,0.0 ,0.0); - ntlVec3Gfx pos = (*mpTrafo) * pnew; - gfxReal partsize = 0.0; - if(debugParts) errMsg("DebugParts"," i"<<i<<" new"<<pnew<<" vel"<<pdir<<" pos="<<pos ); - //if(i==0 &&(debugParts)) errMsg("DebugParts"," i"<<i<<" new"<<pnew[0]<<" pos="<<pos[0]<<" scale="<<scale[0]<<" t="<<trans[0] ); - - // value length scaling? - if(mValueScale==1) { - partsize = partscale * plen; - } else if(mValueScale==2) { - // cut off scaling - if(plen > mValueCutoffTop) continue; - if(plen < mValueCutoffBottom) continue; - partsize = partscale * plen; - } else { - partsize = partscale; // no length scaling - } - //if(type&(PART_DROP|PART_BUBBLE)) - partsize *= p->getSize()/5.0; - - ntlVec3Gfx pstart( mPartHeadDist *partsize, 0.0, 0.0 ); - ntlVec3Gfx pend ( mPartTailDist *partsize, 0.0, 0.0 ); - gfxReal phi = 0.0; - gfxReal phiD = 2.0*M_PI / (gfxReal)segments; - - ntlMat4Gfx cvmat; - cvmat.initId(); - pdir *= -1.0; - ntlVec3Gfx cv1 = pdir; - ntlVec3Gfx cv2 = ntlVec3Gfx(pdir[1], -pdir[0], 0.0); - ntlVec3Gfx cv3 = cross( cv1, cv2); - //? for(int l=0; l<3; l++) { cvmat.value[l][0] = cv1[l]; cvmat.value[l][1] = cv2[l]; cvmat.value[l][2] = cv3[l]; } - pstart = (cvmat * pstart); - pend = (cvmat * pend); - - for(int s=0; s<segments; s++) { - ntlVec3Gfx p1( 0.0 ); - ntlVec3Gfx p2( 0.0 ); - - gfxReal radscale = partNormSize; - radscale = (partsize+partNormSize)*0.5; - p1[1] += cos(phi) * radscale; - p1[2] += sin(phi) * radscale; - p2[1] += cos(phi + phiD) * radscale; - p2[2] += sin(phi + phiD) * radscale; - ntlVec3Gfx n1 = ntlVec3Gfx( 0.0, cos(phi), sin(phi) ); - ntlVec3Gfx n2 = ntlVec3Gfx( 0.0, cos(phi + phiD), sin(phi + phiD) ); - ntlVec3Gfx ns = n1*0.5 + n2*0.5; - - p1 = (cvmat * p1); - p2 = (cvmat * p2); - - sceneAddTriangle( pos+pstart, pos+p1, pos+p2, - ns,n1,n2, ntlVec3Gfx(0.0), 1, triangles,vertices,normals ); - sceneAddTriangle( pos+pend , pos+p2, pos+p1, - ns,n2,n1, ntlVec3Gfx(0.0), 1, triangles,vertices,normals ); - - phi += phiD; - tris += 2; - } - } - - } // t - - debMsgStd("ParticleTracer::getTriangles",DM_MSG,"Dumped "<<pcnt<<"/"<<mParts.size()<<" parts, tris:"<<tris<<", showonly:"<<mShowOnly,10); - return; // DEBUG - -#endif // ELBEEM_PLUGIN -} - - - - diff --git a/intern/elbeem/intern/particletracer.h b/intern/elbeem/intern/particletracer.h deleted file mode 100644 index 10b37406f8c..00000000000 --- a/intern/elbeem/intern/particletracer.h +++ /dev/null @@ -1,296 +0,0 @@ -/** \file - * \ingroup elbeem - */ -/****************************************************************************** - * - * El'Beem - Free Surface Fluid Simulation with the Lattice Boltzmann Method - * Copyright 2003-2006 Nils Thuerey - * - * Particle Viewer/Tracer - * - *****************************************************************************/ -#ifndef NTL_PARTICLETRACER_H - -#include "ntl_geometryobject.h" - -#ifdef WITH_CXX_GUARDEDALLOC -# include "MEM_guardedalloc.h" -#endif - -template<class Scalar> class ntlMatrix4x4; - -// particle types -#define PART_BUBBLE (1<< 1) -#define PART_DROP (1<< 2) -#define PART_INTER (1<< 3) -#define PART_FLOAT (1<< 4) -#define PART_TRACER (1<< 5) - -// particle state -#define PART_IN (1<< 8) -#define PART_OUT (1<< 9) -#define PART_INACTIVE (1<<10) -#define PART_OUTFLUID (1<<11) - -// defines for particle movement -#define MOVE_FLOATS 1 -#define FLOAT_JITTER 0.03 -//#define FLOAT_JITTER 0.0 - -extern int ParticleObjectIdCnt; - -//! A single particle -class ParticleObject -{ - public: - //! Standard constructor - inline ParticleObject(ntlVec3Gfx mp) : - mPos(mp),mVel(0.0), mSize(1.0), mStatus(0),mLifeTime(0),mpNext(NULL) - { mId = ParticleObjectIdCnt++; }; - //! Copy constructor - inline ParticleObject(const ParticleObject &a) : - mPos(a.mPos), mVel(a.mVel), mSize(a.mSize), - mStatus(a.mStatus), - mLifeTime(a.mLifeTime), mpNext(NULL) - { mId = ParticleObjectIdCnt++; }; - //! Destructor - inline ~ParticleObject() { /* empty */ }; - - //! add vector to position - inline void advance(float vx, float vy, float vz) { - mPos[0] += vx; mPos[1] += vy; mPos[2] += vz; } - inline void advanceVec(ntlVec3Gfx v) { - mPos[0] += v[0]; mPos[1] += v[1]; mPos[2] += v[2]; } - //! advance with own velocity - inline void advanceVel() { mPos += mVel; } - //! add acceleration to velocity - inline void addToVel(ntlVec3Gfx acc) { mVel += acc; } - - //! get/set vector to position - inline ntlVec3Gfx getPos() { return mPos; } - inline void setPos(ntlVec3Gfx set) { mPos=set; } - //! set velocity - inline void setVel(ntlVec3Gfx set) { mVel = set; } - //! set velocity - inline void setVel(gfxReal x, gfxReal y, gfxReal z) { mVel = ntlVec3Gfx(x,y,z); } - //! get velocity - inline ntlVec3Gfx getVel() { return mVel; } - - //! get/set size value - inline gfxReal getSize() { return mSize; } - inline void setSize(gfxReal set) { mSize=set; } - - //! get/set next pointer - inline ParticleObject* getNext() { return mpNext; } - inline void setNext(ParticleObject* set) { mpNext=set; } - - //! get whole flags - inline int getFlags() const { return mStatus; } - //! get status (higher byte) - inline int getStatus() const { return (mStatus&0xFF00); } - //! set status (higher byte) - inline void setStatus(int set) { mStatus = set|(mStatus&0x00FF); } - //! get type (lower byte) - inline int getType() const { return (mStatus&0x00FF); } - //! set type (lower byte) - inline void setType(int set) { mStatus = set|(mStatus&0xFF00); } - //! get active flag - inline bool getActive() const { return ((mStatus&PART_INACTIVE)==0); } - //! set active flag - inline void setActive(bool set) { - if(set) mStatus &= (~PART_INACTIVE); - else mStatus |= PART_INACTIVE; - } - //! get influid flag - inline bool getInFluid() const { return ((mStatus&PART_OUTFLUID)==0); } - //! set influid flag - inline void setInFluid(bool set) { - if(set) mStatus &= (~PART_OUTFLUID); - else mStatus |= PART_OUTFLUID; - } - //! get/set lifetime - inline float getLifeTime() const { return mLifeTime; } - //! set type (lower byte) - inline void setLifeTime(float set) { mLifeTime = set; } - - inline int getId() const { return mId; } - - static inline float getMass(float size) { - return 4.0/3.0 * M_PI* (size)*(size)*(size); // mass: 4/3 pi r^3 rho - } - - protected: - - /*! only for debugging */ - int mId; - /*! the particle position */ - ntlVec3Gfx mPos; - /*! the particle velocity */ - ntlVec3Gfx mVel; - /*! size / mass of particle */ - gfxReal mSize; - /*! particle status */ - int mStatus; - /*! count survived time steps */ - float mLifeTime; - - /* for list constructions */ - ParticleObject *mpNext; - -private: -#ifdef WITH_CXX_GUARDEDALLOC - MEM_CXX_CLASS_ALLOC_FUNCS("ELBEEM:ParticleObject") -#endif -}; - - -//! A whole particle array -class ParticleTracer : - public ntlGeometryObject -{ - public: - //! Standard constructor - ParticleTracer(); - //! Destructor - ~ParticleTracer(); - - //! add a particle at this position - void addParticle(float x, float y, float z); - //! add/copy a particle from inited struct - void addFullParticle(ParticleObject &np); - - //! draw the particle array - void draw(); - - //! parse settings from attributes (dont use own list!) - void parseAttrList( AttributeList *att ); - - //! adapt time step by rescaling velocities - void adaptPartTimestep(float factor); - - // access funcs - - //! get the number of particles - inline int getNumParticles() { return mParts.size(); } - //! set/get the number of particles - inline void setNumInitialParticles(int set) { mNumInitialParts=set; } - inline int getNumInitialParticles() { return mNumInitialParts; } - - //! iterate over all newest particles (for advancing positions) - inline vector<ParticleObject>::iterator getParticlesBegin() { return mParts.begin(); } - //! end iterator for newest particles - inline vector<ParticleObject>::iterator getParticlesEnd() { return mParts.end(); } - //! end iterator for newest particles - inline ParticleObject* getLast() { return &(mParts[ mParts.size()-1 ]); } - - /*! set geometry start (for renderer) */ - inline void setStart(ntlVec3Gfx set) { mStart = set; initTrafoMatrix(); } - /*! set geometry end (for renderer) */ - inline void setEnd(ntlVec3Gfx set) { mEnd = set; initTrafoMatrix(); } - /*! get values */ - inline ntlVec3Gfx getStart() { return mStart; } - /*! set geometry end (for renderer) */ - inline ntlVec3Gfx getEnd() { return mEnd; } - - /*! set simulation domain start */ - inline void setSimStart(ntlVec3Gfx set) { mSimStart = set; initTrafoMatrix(); } - /*! set simulation domain end */ - inline void setSimEnd(ntlVec3Gfx set) { mSimEnd = set; initTrafoMatrix(); } - - /*! set/get dump flag */ - inline void setDumpParts(bool set) { mDumpParts = set; } - inline bool getDumpParts() { return mDumpParts; } - /*! set/get dump text file */ - inline void setDumpTextFile(string set) { mDumpTextFile = set; } - inline string getDumpTextFile() { return mDumpTextFile; } - /*! set/get dump text interval */ - inline void setDumpTextInterval(float set) { mDumpTextInterval = set; } - inline float getDumpTextInterval() { return mDumpTextInterval; } - /*! set/get init times */ - inline void setInitStart(float set) { mInitStart = set; } - inline float getInitStart() { return mInitStart; } - inline void setInitEnd(float set) { mInitEnd = set; } - inline float getInitEnd() { return mInitEnd; } - - //! set the particle scaling factor - inline void setPartScale(float set) { mPartScale = set; } - - //! called after each frame to check if positions should be dumped - void checkDumpTextPositions(double simtime); - - // NTL geometry implementation - /*! Get the triangles from this object */ - virtual void getTriangles(double t, vector<ntlTriangle> *triangles, - vector<ntlVec3Gfx> *vertices, - vector<ntlVec3Gfx> *normals, int objectId ); - - virtual void notifyOfDump(int dumptype, int frameNr,char *frameNrStr,string outfilename,double simtime); - - // notify of next step for trails - void checkTrails(double time); - // free deleted particles - void cleanup(); - - protected: - - /*! the particle array (for multiple timesteps) */ - vector<ParticleObject> mParts; - - /*! size of the particles to display */ - float mPartSize; - - /*! start and end vectors for the triangulation region to create particles in */ - ntlVec3Gfx mStart, mEnd; - - /*! start and end vectors of the simulation domain */ - ntlVec3Gfx mSimStart, mSimEnd; - - /*! scaling param for particles */ - float mPartScale; - /*! head and tail distance for particle shapes */ - float mPartHeadDist, mPartTailDist; - /*! no of segments for particle cone */ - int mPartSegments; - /*! use length/absval of values to scale particles? */ - int mValueScale; - /*! value length maximal cutoff value, for mValueScale==2 */ - float mValueCutoffTop; - /*! value length minimal cutoff value, for mValueScale==2 */ - float mValueCutoffBottom; - - /*! dump particles (or certain types of) to disk? */ - int mDumpParts; - /*! text dump output file */ - string mDumpTextFile; - /*! text dump interval, start at t=0, dumping active if >0 */ - float mDumpTextInterval; - float mDumpTextLastTime; - int mDumpTextCount; - /*! show only a certain type (debugging) */ - int mShowOnly; - /*! no. of particles to init */ - int mNumInitialParts; - - //! transform matrix - ntlMatrix4x4<gfxReal> *mpTrafo; - /*! init sim/pos transformation */ - void initTrafoMatrix(); - - //! init time distribution start/end - float mInitStart, mInitEnd; - - /*! the particle array (for multiple timesteps) */ - vector< vector<ParticleObject> > mPrevs; - /* prev pos save interval */ - float mTrailTimeLast, mTrailInterval; - int mTrailLength; - -private: -#ifdef WITH_CXX_GUARDEDALLOC - MEM_CXX_CLASS_ALLOC_FUNCS("ELBEEM:ParticleTracer") -#endif -}; - -#define NTL_PARTICLETRACER_H -#endif - diff --git a/intern/elbeem/intern/simulation_object.cpp b/intern/elbeem/intern/simulation_object.cpp deleted file mode 100644 index bba202300e9..00000000000 --- a/intern/elbeem/intern/simulation_object.cpp +++ /dev/null @@ -1,471 +0,0 @@ -/** \file - * \ingroup elbeem - */ -/****************************************************************************** - * - * El'Beem - Free Surface Fluid Simulation with the Lattice Boltzmann Method - * Copyright 2003-2006 Nils Thuerey - * - * Basic interface for all simulation modules - * - *****************************************************************************/ - -#include "simulation_object.h" -#include "solver_interface.h" -#include "ntl_bsptree.h" -#include "ntl_ray.h" -#include "ntl_world.h" -#include "solver_interface.h" -#include "particletracer.h" -#include "elbeem.h" - -#if PARALLEL==1 -#include <omp.h> -#endif - -#ifdef _WIN32 -#else -#include <sys/time.h> -#endif - - -//! lbm factory functions -LbmSolverInterface* createSolver(); - -/****************************************************************************** - * Constructor - *****************************************************************************/ -SimulationObject::SimulationObject() : - ntlGeometryShader(), - mGeoStart(-100.0), mGeoEnd(100.0), - mpGiTree(NULL), mpGiObjects(NULL), - mpGlob(NULL), - mPanic( false ), - mDebugType( 1 /* =FLUIDDISPNothing*/ ), - mpLbm(NULL), mpParam( NULL ), - mShowSurface(true), mShowParticles(false), - mSelectedCid( NULL ), - mpElbeemSettings( NULL ) - -{ - mpParam = new Parametrizer(); - //for(int i=0; i<MAX_DEBDISPSET; i++) { mDebDispSet[i].type = (i); mDebDispSet[i].on = false; mDebDispSet[i].scale = 1.0; } - - // reset time - mTime = 0.0; -} - - -/****************************************************************************** - * Destructor - *****************************************************************************/ -SimulationObject::~SimulationObject() -{ - if(mpGiTree) delete mpGiTree; - if(mpElbeemSettings) delete mpElbeemSettings; - if(mpLbm) delete mpLbm; - if(mpParam) delete mpParam; - if(mpParts) delete mpParts; - debMsgStd("SimulationObject",DM_MSG,"El'Beem Done!\n",10); -} - - - -/*****************************************************************************/ -/*! init tree for certain geometry init */ -/*****************************************************************************/ -void SimulationObject::initGeoTree() { - // unused!! overriden by solver interface - if(mpGlob == NULL) { - errFatal("SimulationObject::initGeoTree error","Requires globals!", SIMWORLD_INITERROR); - return; - } - ntlScene *scene = mpGlob->getSimScene(); - mpGiObjects = scene->getObjects(); - - if(mpGiTree != NULL) delete mpGiTree; - char treeFlag = (1<<(mGeoInitId+4)); - mpGiTree = new ntlTree( 20, 4, // warning - fixed values for depth & maxtriangles here... - scene, treeFlag ); - // unused!! overriden by solver interface -} - -/*****************************************************************************/ -/*! destroy tree etc. when geometry init done */ -/*****************************************************************************/ -void SimulationObject::freeGeoTree() { - if(mpGiTree != NULL) delete mpGiTree; -} - - - -// copy & remember settings for later use -void SimulationObject::copyElbeemSettings(elbeemSimulationSettings *settings) { - mpElbeemSettings = new elbeemSimulationSettings; - *mpElbeemSettings = *settings; - - mGeoInitId = settings->domainId+1; - debMsgStd("SimulationObject",DM_MSG,"mGeoInitId="<<mGeoInitId<<", domainId="<<settings->domainId, 8); -} - -/****************************************************************************** - * simluation interface: initialize simulation using the given configuration file - *****************************************************************************/ -extern int glob_mpnum; -int SimulationObject::initializeLbmSimulation(ntlRenderGlobals *glob) -{ - if(! isSimworldOk() ) return 1; - - // already inited? - if(mpLbm) return 0; - - mpGlob = glob; - if(!getVisible()) { - mpAttrs->setAllUsed(); - return 0; - } - - - mGeoInitId = mpAttrs->readInt("geoinitid", mGeoInitId,"LbmSolverInterface", "mGeoInitId", false); - //mDimension, mSolverType are deprecated - string mSolverType(""); - mSolverType = mpAttrs->readString("solver", mSolverType, "SimulationObject","mSolverType", false ); - - mpLbm = createSolver(); - /* check lbm pointer */ - if(mpLbm == NULL) { - errFatal("SimulationObject::initializeLbmSimulation","Unable to init LBM solver! ", SIMWORLD_INITERROR); - return 2; - } - debMsgStd("SimulationObject::initialized",DM_MSG,"IdStr:"<<mpLbm->getIdString() <<" LBM solver! ", 2); - - mpParts = new ParticleTracer(); - - // for non-param simulations - mpLbm->setParametrizer( mpParam ); - mpParam->setAttrList( getAttributeList() ); - // not needed.. done in solver_init: mpParam->setSize ... in solver_interface - mpParam->parseAttrList(); - - mpLbm->setAttrList( getAttributeList() ); - mpLbm->setSwsAttrList( getSwsAttributeList() ); - mpLbm->parseAttrList(); - mpParts->parseAttrList( getAttributeList() ); - - if(! isSimworldOk() ) return 3; - mpParts->setName( getName() + "_part" ); - mpParts->initialize( glob ); - if(! isSimworldOk() ) return 4; - - // init material settings - string matMc("default"); - matMc = mpAttrs->readString("material_surf", matMc, "SimulationObject","matMc", false ); - mShowSurface = mpAttrs->readInt("showsurface", mShowSurface, "SimulationObject","mShowSurface", false ); - mShowParticles = mpAttrs->readInt("showparticles", mShowParticles, "SimulationObject","mShowParticles", false ); - - checkBoundingBox( mGeoStart, mGeoEnd, "SimulationObject::initializeSimulation" ); - mpLbm->setLbmInitId( mGeoInitId ); - mpLbm->setGeoStart( mGeoStart ); - mpLbm->setGeoEnd( mGeoEnd ); - mpLbm->setRenderGlobals( mpGlob ); - mpLbm->setName( getName() + "_lbm" ); - mpLbm->setParticleTracer( mpParts ); - if(mpElbeemSettings) { - // set further settings from API struct init - this->mOutFilename = string(mpElbeemSettings->outputPath); - mpLbm->initDomainTrafo( mpElbeemSettings->surfaceTrafo ); - mpLbm->setSmoothing(1.0 * mpElbeemSettings->surfaceSmoothing, 1.0 * mpElbeemSettings->surfaceSmoothing); - mpLbm->setIsoSubdivs(mpElbeemSettings->surfaceSubdivs); -#if PARALLEL==1 - mpLbm->setNumOMPThreads(mpElbeemSettings->threads); -#endif - mpLbm->setSizeX(mpElbeemSettings->resolutionxyz); - mpLbm->setSizeY(mpElbeemSettings->resolutionxyz); - mpLbm->setSizeZ(mpElbeemSettings->resolutionxyz); - mpLbm->setPreviewSize(mpElbeemSettings->previewresxyz); - mpLbm->setRefinementDesired(mpElbeemSettings->maxRefine); - mpLbm->setGenerateParticles(mpElbeemSettings->generateParticles); - // set initial particles - mpParts->setNumInitialParticles(mpElbeemSettings->numTracerParticles); - - // surface generation flag - mpLbm->setSurfGenSettings(mpElbeemSettings->mFsSurfGenSetting); - - string dinitType = string("no"); - if (mpElbeemSettings->domainobsType==FLUIDSIM_OBSTACLE_PARTSLIP) dinitType = string("part"); - else if(mpElbeemSettings->domainobsType==FLUIDSIM_OBSTACLE_FREESLIP) dinitType = string("free"); - else /*if(mpElbeemSettings->domainobsType==FLUIDSIM_OBSTACLE_NOSLIP)*/ dinitType = string("no"); - mpLbm->setDomainBound(dinitType); - mpLbm->setDomainPartSlip(mpElbeemSettings->domainobsPartslip); - mpLbm->setDumpVelocities(mpElbeemSettings->generateVertexVectors); - mpLbm->setFarFieldSize(mpElbeemSettings->farFieldSize); - debMsgStd("SimulationObject::initialize",DM_MSG,"Added domain bound: "<<dinitType<<" ps="<<mpElbeemSettings->domainobsPartslip<<" vv"<<mpElbeemSettings->generateVertexVectors<<","<<mpLbm->getDumpVelocities(), 9 ); - - debMsgStd("SimulationObject::initialize",DM_MSG,"Set ElbeemSettings values "<<mpLbm->getGenerateParticles(),10); - } - - if(! mpLbm->initializeSolverMemory() ) { errMsg("SimulationObject::initialize","initializeSolverMemory failed"); mPanic=true; return 10; } - if(checkCallerStatus(FLUIDSIM_CBSTATUS_STEP, 0)) { errMsg("SimulationObject::initialize","initializeSolverMemory status"); mPanic=true; return 11; } - if(! mpLbm->initializeSolverGrids() ) { errMsg("SimulationObject::initialize","initializeSolverGrids failed"); mPanic=true; return 12; } - if(checkCallerStatus(FLUIDSIM_CBSTATUS_STEP, 0)) { errMsg("SimulationObject::initialize","initializeSolverGrids status"); mPanic=true; return 13; } - if(! mpLbm->initializeSolverPostinit() ) { errMsg("SimulationObject::initialize","initializeSolverPostin failed"); mPanic=true; return 14; } - if(checkCallerStatus(FLUIDSIM_CBSTATUS_STEP, 0)) { errMsg("SimulationObject::initialize","initializeSolverPostin status"); mPanic=true; return 15; } - - // print cell type stats - bool printStats = true; - if(glob_mpnum>0) printStats=false; // skip in this case - if(printStats) { - const int jmax = sizeof(CellFlagType)*8; - int totalCells = 0; - int flagCount[jmax]; - for(int j=0; j<jmax ; j++) flagCount[j] = 0; - int diffInits = 0; - LbmSolverInterface::CellIdentifier cid = mpLbm->getFirstCell(); - for(; mpLbm->noEndCell( cid ); - mpLbm->advanceCell( cid ) ) { - int flag = mpLbm->getCellFlag(cid,0); - int flag2 = mpLbm->getCellFlag(cid,1); - if(flag != flag2) { - diffInits++; - } - for(int j=0; j<jmax ; j++) { - if( flag&(1<<j) ) flagCount[j]++; - } - totalCells++; - } - mpLbm->deleteCellIterator( &cid ); - - char charNl = '\n'; - debugOutNnl("SimulationObject::initializeLbmSimulation celltype stats: " <<charNl, 5); - debugOutNnl("no. of cells = "<<totalCells<<", "<<charNl ,5); - for(int j=0; j<jmax ; j++) { - std::ostringstream out; - if(flagCount[j]>0) { - out<<"\t" << flagCount[j] <<" x "<< convertCellFlagType2String( (CellFlagType)(1<<j) ) <<", " << charNl; - debugOutNnl(out.str(), 5); - } - } - // compute dist. of empty/bnd - fluid - if - // cfEmpty = (1<<0), cfBnd = (1<< 2), cfFluid = (1<<10), cfInter = (1<<11), - if(1){ - std::ostringstream out; - out.precision(2); out.width(4); - int totNum = flagCount[1]+flagCount[2]+flagCount[7]+flagCount[8]; - double ebFrac = (double)(flagCount[1]+flagCount[2]) / totNum; - double flFrac = (double)(flagCount[7]) / totNum; - double ifFrac = (double)(flagCount[8]) / totNum; - //??? - out<<"\tFractions: [empty/bnd - fluid - interface - ext. if] = [" << ebFrac<<" - " << flFrac<<" - " << ifFrac<<"] "<< charNl; - - if(diffInits > 0) { - debMsgStd("SimulationObject::initializeLbmSimulation",DM_MSG,"celltype Warning: Diffinits="<<diffInits<<"!" , 5); - } - debugOutNnl(out.str(), 5); - } - } // cellstats - - // might be modified by mpLbm - //mpParts->setStart( mGeoStart );? mpParts->setEnd( mGeoEnd );? - mpParts->setStart( mpLbm->getGeoStart() ); - mpParts->setEnd( mpLbm->getGeoEnd() ); - mpParts->setCastShadows( false ); - mpParts->setReceiveShadows( false ); - mpParts->searchMaterial( glob->getMaterials() ); - - // this has to be inited here - before, the values might be unknown - IsoSurface *surf = mpLbm->getSurfaceGeoObj(); - if(surf) { - surf->setName( "final" ); // final surface mesh - // warning - this might cause overwriting effects for multiple sims and geom dump... - surf->setCastShadows( true ); - surf->setReceiveShadows( false ); - surf->searchMaterial( glob->getMaterials() ); - if(mShowSurface) mObjects.push_back( surf ); - } - -#ifdef ELBEEM_PLUGIN - mShowParticles=1; // for e.g. dumping -#endif // ELBEEM_PLUGIN - if((mpLbm->getGenerateParticles()>0.0)||(mpParts->getNumInitialParticles()>0)) { - mShowParticles=1; - mpParts->setDumpParts(true); - } - //debMsgStd("SimulationObject::init",DM_NOTIFY,"Using envvar ELBEEM_DUMPPARTICLE to set mShowParticles, DEBUG!",1); - //} // DEBUG ENABLE!!!!!!!!!! - if(mShowParticles) { - mObjects.push_back(mpParts); - } - - // add objects to display for debugging (e.g. levelset particles) - vector<ntlGeometryObject *> debugObjs = mpLbm->getDebugObjects(); - for(size_t i=0;i<debugObjs.size(); i++) { - debugObjs[i]->setCastShadows( false ); - debugObjs[i]->setReceiveShadows( false ); - debugObjs[i]->searchMaterial( glob->getMaterials() ); - mObjects.push_back( debugObjs[i] ); - debMsgStd("SimulationObject::init",DM_NOTIFY,"Added debug obj "<<debugObjs[i]->getName(), 10 ); - } - return 0; -} - -/*! set current frame */ -void SimulationObject::setFrameNum(int num) { - // advance parametrizer - mpParam->setFrameNum(num); -} - -/****************************************************************************** - * simluation interface: advance simulation another step (whatever delta time that might be) - *****************************************************************************/ -void SimulationObject::step( void ) -{ - if(mpParam->getCurrentAniFrameTime()>0.0) { - // dont advance for stopped time - mpLbm->step(); - mTime += mpParam->getTimestep(); - //if(mTime>0.001) { errMsg("DEBUG!!!!!!!!","quit mlsu..."); xit(1); } // PROFILE DEBUG TEST! - } - if(mpLbm->getPanic()) mPanic = true; - - checkCallerStatus(FLUIDSIM_CBSTATUS_STEP, 0); - //if((mpElbeemSettings)&&(mpElbeemSettings->runsimCallback)) { - //int ret = (mpElbeemSettings->runsimCallback)(mpElbeemSettings->runsimUserData, FLUIDSIM_CBSTATUS_STEP, 0); - //errMsg("runSimulationCallback cbtest1"," "<<this->getName()<<" ret="<<ret); - //} - //debMsgStd("SimulationObject::step",DM_MSG," Sim '"<<mName<<"' stepped to "<<mTime<<" (stept="<<(mpParam->getTimestep())<<", framet="<<getFrameTime()<<") ", 10); -} -/*! prepare visualization of simulation for e.g. raytracing */ -void SimulationObject::prepareVisualization( void ) { - if(mPanic) return; - mpLbm->prepareVisualization(); -} - - -/******************************************************************************/ -/* get current start simulation time */ -double SimulationObject::getStartTime( void ) { - //return mpParam->calculateAniStart(); - return mpParam->getAniStart(); -} -/* get time for a single animation frame */ -double SimulationObject::getFrameTime( int frame ) { - return mpParam->getAniFrameTime(frame); -} -/* get time for a single time step */ -double SimulationObject::getTimestep( void ) { - return mpParam->getTimestep(); -} - - -/****************************************************************************** - * return a pointer to the geometry object of this simulation - *****************************************************************************/ -//ntlGeometryObject *SimulationObject::getGeometry() { return mpMC; } -vector<ntlGeometryObject *>::iterator -SimulationObject::getObjectsBegin() -{ - return mObjects.begin(); -} -vector<ntlGeometryObject *>::iterator -SimulationObject::getObjectsEnd() -{ - return mObjects.end(); -} - - - - - -/****************************************************************************** - * GUI - display debug info - *****************************************************************************/ - -void SimulationObject::drawDebugDisplay() { -#ifndef NOGUI - if(!getVisible()) return; - - //if( mDebugType > (MAX_DEBDISPSET-1) ){ errFatal("SimulationObject::drawDebugDisplay","Invalid debug type!", SIMWORLD_GENERICERROR); return; } - //mDebDispSet[ mDebugType ].on = true; - //errorOut( mDebugType <<"//"<< mDebDispSet[mDebugType].type ); - mpLbm->debugDisplay( mDebugType ); - - //::lbmMarkedCellDisplay<>( mpLbm ); - mpLbm->lbmMarkedCellDisplay(); -#endif -} - -/* GUI - display interactive info */ -void SimulationObject::drawInteractiveDisplay() -{ -#ifndef NOGUI - if(!getVisible()) return; - if(mSelectedCid) { - // in debugDisplayNode if dispset is on is ignored... - mpLbm->debugDisplayNode( FLUIDDISPGrid, mSelectedCid ); - } -#endif -} - - -/*******************************************************************************/ -// GUI - handle mouse movement for selection -/*******************************************************************************/ -void SimulationObject::setMousePos(int x,int y, ntlVec3Gfx org, ntlVec3Gfx dir) -{ - normalize( dir ); - // assume 2D sim is in XY plane... - - double zplane = (mGeoEnd[2]-mGeoStart[2])*0.5; - double zt = (zplane-org[2]) / dir[2]; - ntlVec3Gfx pos( - org[0]+ dir[0] * zt, - org[1]+ dir[1] * zt, 0.0); - - mSelectedCid = mpLbm->getCellAt( pos ); - //errMsg("SMP ", mName<< x<<" "<<y<<" - "<<dir ); - x = y = 0; // remove warning -} - - -void SimulationObject::setMouseClick() -{ - if(mSelectedCid) { - //::debugPrintNodeInfo<>( mpLbm, mSelectedCid, mpLbm->getNodeInfoString() ); - mpLbm->debugPrintNodeInfo( mSelectedCid ); - } -} - -/*! notify object that dump is in progress (e.g. for field dump) */ -void SimulationObject::notifyShaderOfDump(int dumptype, int frameNr,char *frameNrStr,string outfilename) { - if(!mpLbm) return; - - mpLbm->notifySolverOfDump(dumptype, frameNr,frameNrStr,outfilename); - checkCallerStatus(FLUIDSIM_CBSTATUS_NEWFRAME, frameNr); -} - -/*! check status (e.g. stop/abort) from calling program, returns !=0 if sth. happened... */ -int SimulationObject::checkCallerStatus(int status, int frame) { - //return 0; // DEBUG - int ret = 0; - if((mpElbeemSettings)&&(mpElbeemSettings->runsimCallback)) { - ret = (mpElbeemSettings->runsimCallback)(mpElbeemSettings->runsimUserData, status,frame); - if(ret!=FLUIDSIM_CBRET_CONTINUE) { - if(ret==FLUIDSIM_CBRET_STOP) { - debMsgStd("SimulationObject::notifySolverOfDump",DM_NOTIFY,"Got stop signal from caller",1); - setElbeemState( SIMWORLD_STOP ); - } - else if(ret==FLUIDSIM_CBRET_ABORT) { - errFatal("SimulationObject::notifySolverOfDump","Got abort signal from caller, aborting...", SIMWORLD_GENERICERROR ); - mPanic = 1; - } - else { - errMsg("SimulationObject::notifySolverOfDump","Invalid callback return value: "<<ret<<", ignoring... "); - } - } - } - - //debMsgStd("SimulationObject::checkCallerStatus",DM_MSG, "s="<<status<<",f="<<frame<<" "<<this->getName()<<" ret="<<ret); - if(isSimworldOk()) return 0; - return 1; -} - diff --git a/intern/elbeem/intern/simulation_object.h b/intern/elbeem/intern/simulation_object.h deleted file mode 100644 index b35482f2098..00000000000 --- a/intern/elbeem/intern/simulation_object.h +++ /dev/null @@ -1,206 +0,0 @@ -/** \file - * \ingroup elbeem - */ -/****************************************************************************** - * - * El'Beem - Free Surface Fluid Simulation with the Lattice Boltzmann Method - * Copyright 2003-2006 Nils Thuerey - * - * Basic interface for all simulation modules - * - *****************************************************************************/ - -#ifndef SIMULATION_OBJECT_H -#define SIMULATION_OBJECT_H - - -#define USE_GLUTILITIES -#include "ntl_geometryshader.h" -#include "parametrizer.h" - -#ifdef WITH_CXX_GUARDEDALLOC -# include "MEM_guardedalloc.h" -#endif - -class LbmSolverInterface; -class CellIdentifierInterface; -class ntlTree; -class ntlRenderGlobals; -class ntlRenderGlobals; -class ParticleTracer; -struct elbeemSimulationSettings; - - -//! type fluid geometry init -// warning : should match typeslbm.h values! -const int cFgiFlagstart = 16; -typedef enum { - fgiFluid = (1<<(cFgiFlagstart+0)), - fgiNoFluid = (1<<(cFgiFlagstart+1)), - fgiSlipNo = (1<<(cFgiFlagstart+2)), - fgiSlipFree = (1<<(cFgiFlagstart+3)), - fgiNoBnd = (1<<(cFgiFlagstart+4)), - fgiAcc = (1<<(cFgiFlagstart+5)), - fgiNoAcc = (1<<(cFgiFlagstart+6)), - - fgiBndAll = (fgiSlipNo | fgiSlipFree) -} FgiFlagType; - - -/*! interface for different simluation models to visualize */ -class SimulationObject : - public ntlGeometryShader { - - public: - - /*! Constructor */ - SimulationObject(); - /*! Destructor */ - virtual ~SimulationObject(); - /*! for init from API */ - void copyElbeemSettings(elbeemSimulationSettings *settings); - - - /*! init tree for certain geometry init */ - void initGeoTree(); - /*! destroy tree etc. when geometry init done */ - void freeGeoTree(); - /*! get fluid init type at certain position */ - int geoInitGetPointType(ntlVec3Gfx org, int &OId); - /*! check for a certain flag type at position org */ - bool geoInitCheckPointInside(ntlVec3Gfx org, int flags, int &OId); - - // access functions - - /*! get current (max) simulation time */ - double getCurrentTime( void ) { return mTime; } - /*! set geometry generation start point */ - virtual void setGeoStart(ntlVec3Gfx set) { mGeoStart = set; } - /*! set geometry generation end point */ - virtual void setGeoEnd(ntlVec3Gfx set) { mGeoEnd = set; } - - /*! set sim panic flag */ - void setPanic(bool set) { mPanic = set; } - /*! get sim panic flag */ - bool getPanic( void ) { return mPanic; } - - /*! simluation interface: initialize simulation */ - int initializeLbmSimulation(ntlRenderGlobals *glob); - - /*! set current frame */ - void setFrameNum(int num); - - /*! Do geo etc. init */ - virtual int postGeoConstrInit(ntlRenderGlobals *glob) { return initializeLbmSimulation(glob); }; - virtual int initializeShader() { /* ... */ return true; }; - /*! notify object that dump is in progress (e.g. for field dump) */ - virtual void notifyShaderOfDump(int dumptype, int frameNr,char *frameNrStr,string outfilename); - /*! simluation interface: draw the simulation with OpenGL */ - virtual void draw( void ) {}; - virtual vector<ntlGeometryObject *>::iterator getObjectsBegin(); - virtual vector<ntlGeometryObject *>::iterator getObjectsEnd(); - - - /*! simluation interface: advance simulation another step (whatever delta time that might be) */ - virtual void step( void ); - /*! prepare visualization of simulation for e.g. raytracing */ - virtual void prepareVisualization( void ); - - /*! GUI - display debug info */ - virtual void drawDebugDisplay(); - /*! GUI - display interactive info */ - virtual void drawInteractiveDisplay(); - /*! GUI - handle mouse movement for selection */ - virtual void setMousePos(int x,int y, ntlVec3Gfx org, ntlVec3Gfx dir); - virtual void setMouseClick(); - - /*! get current start simulation time */ - double getStartTime( void ); - /*! get time for a single animation frame */ - double getFrameTime( int frame ); - /*! get time for a single time step in the simulation */ - double getTimestep( void ); - - //! access solver - LbmSolverInterface *getSolver(){ return mpLbm; } - - protected: - - /*! current time in the simulation */ - double mTime; - - /*! for display - start and end vectors for geometry */ - ntlVec3Gfx mGeoStart, mGeoEnd; - - /*! geometry init id */ - //? int mGeoInitId; - /*! tree object for geomerty initialization */ - ntlTree *mpGiTree; - /*! object vector for geo init */ - vector<ntlGeometryObject*> *mpGiObjects; - /*! remember globals */ - ntlRenderGlobals *mpGlob; - - /*! simulation panic on/off */ - bool mPanic; - - /*! debug info to display */ - int mDebugType; - - /*! pointer to the lbm solver */ - LbmSolverInterface *mpLbm; - - /*! parametrizer for lbm solver */ - Parametrizer *mpParam; - - /*! particle tracing object */ - ParticleTracer *mpParts; - - /*! show parts of the simulation toggles */ - bool mShowSurface; - bool mShowParticles; - - /*! debug display settings */ - int mDebDispSetting; - - /*! pointer to identifier of selected node */ - CellIdentifierInterface *mSelectedCid; - - /*! storage of API settings */ - elbeemSimulationSettings *mpElbeemSettings; - - public: - - // debug display setting funtions - - /*! set type of info to display */ - inline void setDebugDisplay(int disp) { mDebugType = disp; } - inline int getDebugDisplay() { return mDebugType; } - - /* miscelleanous access functions */ - - /*! init parametrizer for anim step length */ - void initParametrizer(Parametrizer *set) { mpParam = set; } - /*! init parametrizer for anim step length */ - Parametrizer *getParametrizer() { return mpParam; } - - /*! check status (e.g. stop/abort) from calling program, returns !=0 if sth. happened... */ - // parameters same as elbeem runsimCallback - int checkCallerStatus(int status, int frame); - - /*! get bounding box of fluid for GUI */ - virtual inline ntlVec3Gfx *getBBStart() { return &mGeoStart; } - virtual inline ntlVec3Gfx *getBBEnd() { return &mGeoEnd; } - - -private: -#ifdef WITH_CXX_GUARDEDALLOC - MEM_CXX_CLASS_ALLOC_FUNCS("ELBEEM:SimulationObject") -#endif -}; - - -#endif - - - diff --git a/intern/elbeem/intern/solver_adap.cpp b/intern/elbeem/intern/solver_adap.cpp deleted file mode 100644 index 9e5619ca4a5..00000000000 --- a/intern/elbeem/intern/solver_adap.cpp +++ /dev/null @@ -1,1281 +0,0 @@ -/** \file - * \ingroup elbeem - */ -/****************************************************************************** - * - * El'Beem - Free Surface Fluid Simulation with the Lattice Boltzmann Method - * Copyright 2003-2006 Nils Thuerey - * - * Adaptivity functions - * - *****************************************************************************/ - -#include "solver_class.h" -#include "solver_relax.h" -#include "particletracer.h" - -#include <cmath> - -using std::isfinite; - -/*****************************************************************************/ -//! coarse step functions -/*****************************************************************************/ - - - -void LbmFsgrSolver::coarseCalculateFluxareas(int lev) -{ - FSGR_FORIJK_BOUNDS(lev) { - if( RFLAG(lev, i,j,k,mLevel[lev].setCurr) & CFFluid) { - if( RFLAG(lev+1, i*2,j*2,k*2,mLevel[lev+1].setCurr) & CFGrFromCoarse) { - LbmFloat totArea = mFsgrCellArea[0]; // for l=0 - for(int l=1; l<this->cDirNum; l++) { - int ni=(2*i)+this->dfVecX[l], nj=(2*j)+this->dfVecY[l], nk=(2*k)+this->dfVecZ[l]; - if(RFLAG(lev+1, ni,nj,nk, mLevel[lev+1].setCurr)& - (CFGrFromCoarse|CFUnused|CFEmpty) //? (CFBnd|CFEmpty|CFGrFromCoarse|CFUnused) - ) { - totArea += mFsgrCellArea[l]; - } - } // l - QCELL(lev, i,j,k,mLevel[lev].setCurr, dFlux) = totArea; - //continue; - } else - if( RFLAG(lev+1, i*2,j*2,k*2,mLevel[lev+1].setCurr) & (CFEmpty|CFUnused)) { - QCELL(lev, i,j,k,mLevel[lev].setCurr, dFlux) = 1.0; - //continue; - } else { - QCELL(lev, i,j,k,mLevel[lev].setCurr, dFlux) = 0.0; - } - //errMsg("DFINI"," at l"<<lev<<" "<<PRINT_IJK<<" v:"<<QCELL(lev, i,j,k,mLevel[lev].setCurr, dFlux) ); - } - } // } TEST DEBUG - if(!this->mSilent){ debMsgStd("coarseCalculateFluxareas",DM_MSG,"level "<<lev<<" calculated", 7); } -} - -void LbmFsgrSolver::coarseAdvance(int lev) -{ - LbmFloat calcCurrentMass = 0.0; - LbmFloat calcCurrentVolume = 0.0; - - LbmFloat *ccel = NULL; - LbmFloat *tcel = NULL; - LbmFloat m[LBM_DFNUM]; - LbmFloat rho, ux, uy, uz, tmp, usqr, lcsmqo; -#if OPT3D==1 - LbmFloat lcsmqadd, lcsmeq[LBM_DFNUM], lcsmomega; -#endif // OPT3D==true - m[0] = tmp = usqr = 0.0; - - coarseCalculateFluxareas(lev); - // copied from fineAdv. - CellFlagType *pFlagSrc = &RFLAG(lev, 1,1,getForZMin1(),SRCS(lev)); - CellFlagType *pFlagDst = &RFLAG(lev, 1,1,getForZMin1(),TSET(lev)); - pFlagSrc -= 1; - pFlagDst -= 1; - ccel = RACPNT(lev, 1,1,getForZMin1() ,SRCS(lev)); // QTEST - ccel -= QCELLSTEP; - tcel = RACPNT(lev, 1,1,getForZMin1() ,TSET(lev)); // QTEST - tcel -= QCELLSTEP; - //if(strstr(this->getName().c_str(),"Debug")){ errMsg("DEBUG","DEBUG!!!!!!!!!!!!!!!!!!!!!!!"); } - - for(int k= getForZMin1(); k< getForZMax1(lev); ++k) { - for(int j=1;j<mLevel[lev].lSizey-1;++j) { - for(int i=1;i<mLevel[lev].lSizex-1;++i) { -#if FSGR_STRICT_DEBUG==1 - rho = ux = uy = uz = tmp = usqr = -100.0; // DEBUG -#endif - pFlagSrc++; - pFlagDst++; - ccel += QCELLSTEP; - tcel += QCELLSTEP; - - // from coarse cells without unused nbs are not necessary...! -> remove - if( ((*pFlagSrc) & (CFGrFromCoarse)) ) { - bool invNb = false; - FORDF1 { if(RFLAG_NB(lev, i, j, k, SRCS(lev), l) & CFUnused) { invNb = true; } } - if(!invNb) { - // WARNING - this modifies source flag array... - *pFlagSrc = CFFluid|CFGrNorm; -#if ELBEEM_PLUGIN!=1 - errMsg("coarseAdvance","FC2NRM_CHECK Converted CFGrFromCoarse to Norm at "<<lev<<" "<<PRINT_IJK); -#endif // ELBEEM_PLUGIN!=1 - // move to perform coarsening? - } - } // */ - -#if FSGR_STRICT_DEBUG==1 - *pFlagDst = *pFlagSrc; // always set other set... -#else - *pFlagDst = (*pFlagSrc & (~CFGrCoarseInited)); // always set other set... , remove coarse inited flag -#endif - - // old INTCFCOARSETEST==1 - if((*pFlagSrc) & CFGrFromCoarse) { // interpolateFineFromCoarse test! - if(( this->mStepCnt & (1<<(mMaxRefine-lev)) ) ==1) { - FORDF0 { RAC(tcel,l) = RAC(ccel,l); } - } else { - interpolateCellFromCoarse( lev, i,j,k, TSET(lev), 0.0, CFFluid|CFGrFromCoarse, false); - this->mNumUsedCells++; - } - continue; // interpolateFineFromCoarse test! - } // interpolateFineFromCoarse test! old INTCFCOARSETEST==1 - - if( ((*pFlagSrc) & (CFFluid)) ) { - ccel = RACPNT(lev, i,j,k ,SRCS(lev)); - tcel = RACPNT(lev, i,j,k ,TSET(lev)); - - if( ((*pFlagSrc) & (CFGrFromFine)) ) { - FORDF0 { RAC(tcel,l) = RAC(ccel,l); } // always copy...? - continue; // comes from fine grid - } - // also ignore CFGrFromCoarse - else if( ((*pFlagSrc) & (CFGrFromCoarse)) ) { - FORDF0 { RAC(tcel,l) = RAC(ccel,l); } // always copy...? - continue; - } - - OPTIMIZED_STREAMCOLLIDE; - *pFlagDst |= CFNoBndFluid; // test? - calcCurrentVolume += RAC(ccel,dFlux); - calcCurrentMass += RAC(ccel,dFlux)*rho; - //ebugMarkCell(lev+1, 2*i+1,2*j+1,2*k ); -#if FSGR_STRICT_DEBUG==1 - if(rho<-1.0){ debugMarkCell(lev, i,j,k ); - errMsg("INVRHOCELL_CHECK"," l"<<lev<<" "<< PRINT_IJK<<" rho:"<<rho ); - CAUSE_PANIC; - } -#endif // FSGR_STRICT_DEBUG==1 - this->mNumUsedCells++; - - } - } - pFlagSrc+=2; // after x - pFlagDst+=2; // after x - ccel += (QCELLSTEP*2); - tcel += (QCELLSTEP*2); - } - pFlagSrc+= mLevel[lev].lSizex*2; // after y - pFlagDst+= mLevel[lev].lSizex*2; // after y - ccel += (QCELLSTEP*mLevel[lev].lSizex*2); - tcel += (QCELLSTEP*mLevel[lev].lSizex*2); - } // all cell loop k,j,i - - - //errMsg("coarseAdvance","level "<<lev<<" stepped from "<<mLevel[lev].setCurr<<" to "<<mLevel[lev].setOther); - if(!this->mSilent){ errMsg("coarseAdvance","level "<<lev<<" stepped from "<<SRCS(lev)<<" to "<<TSET(lev)); } - // */ - - // update other set - mLevel[lev].setOther = mLevel[lev].setCurr; - mLevel[lev].setCurr ^= 1; - mLevel[lev].lsteps++; - mLevel[lev].lmass = calcCurrentMass * mLevel[lev].lcellfactor; - mLevel[lev].lvolume = calcCurrentVolume * mLevel[lev].lcellfactor; -#if ELBEEM_PLUGIN!=1 - debMsgStd("LbmFsgrSolver::coarseAdvance",DM_NOTIFY, "mass: lev="<<lev<<" m="<<mLevel[lev].lmass<<" c="<<calcCurrentMass<<" lcf="<< mLevel[lev].lcellfactor, 8 ); - debMsgStd("LbmFsgrSolver::coarseAdvance",DM_NOTIFY, "volume: lev="<<lev<<" v="<<mLevel[lev].lvolume<<" c="<<calcCurrentVolume<<" lcf="<< mLevel[lev].lcellfactor, 8 ); -#endif // ELBEEM_PLUGIN -} - -/*****************************************************************************/ -//! multi level functions -/*****************************************************************************/ - - -// get dfs from level (lev+1) to (lev) coarse border nodes -void LbmFsgrSolver::coarseRestrictFromFine(int lev) -{ - if((lev<0) || ((lev+1)>mMaxRefine)) return; -#if FSGR_STRICT_DEBUG==1 - // reset all unused cell values to invalid - int unuCnt = 0; - for(int k= getForZMin1(); k< getForZMax1(lev); ++k) { - for(int j=1;j<mLevel[lev].lSizey-1;++j) { - for(int i=1;i<mLevel[lev].lSizex-1;++i) { - CellFlagType *pFlagSrc = &RFLAG(lev, i,j,k,mLevel[lev].setCurr); - if( ((*pFlagSrc) & (CFFluid|CFGrFromFine)) == (CFFluid|CFGrFromFine) ) { - FORDF0{ QCELL(lev, i,j,k,mLevel[lev].setCurr, l) = -10000.0; } - unuCnt++; - // set here - } else if( ((*pFlagSrc) & (CFFluid|CFGrNorm)) == (CFFluid|CFGrNorm) ) { - // simulated... - } else { - // reset in interpolation - //errMsg("coarseRestrictFromFine"," reset l"<<lev<<" "<<PRINT_IJK); - } - if( ((*pFlagSrc) & (CFEmpty|CFUnused)) ) { // test, also reset? - FORDF0{ QCELL(lev, i,j,k,mLevel[lev].setCurr, l) = -10000.0; } - } // test - } } } - errMsg("coarseRestrictFromFine"," reset l"<<lev<<" fluid|coarseBorder cells: "<<unuCnt); -#endif // FSGR_STRICT_DEBUG==1 - const int srcSet = mLevel[lev+1].setCurr; - const int dstSet = mLevel[lev].setCurr; - - //restrict - for(int k= getForZMin1(); k< getForZMax1(lev); ++k) { - for(int j=1;j<mLevel[lev].lSizey-1;++j) { - for(int i=1;i<mLevel[lev].lSizex-1;++i) { - CellFlagType *pFlagSrc = &RFLAG(lev, i,j,k,dstSet); - if((*pFlagSrc) & (CFFluid)) { - if( ((*pFlagSrc) & (CFFluid|CFGrFromFine)) == (CFFluid|CFGrFromFine) ) { - // do resctriction - mNumInterdCells++; - coarseRestrictCell(lev, i,j,k,srcSet,dstSet); - - this->mNumUsedCells++; - } // from fine & fluid - else { - if(RFLAG(lev+1, 2*i,2*j,2*k,srcSet) & CFGrFromCoarse) { - RFLAG(lev, i,j,k,dstSet) |= CFGrToFine; - } else { - RFLAG(lev, i,j,k,dstSet) &= (~CFGrToFine); - } - } - } // & fluid - }}} - if(!this->mSilent){ errMsg("coarseRestrictFromFine"," from l"<<(lev+1)<<",s"<<mLevel[lev+1].setCurr<<" to l"<<lev<<",s"<<mLevel[lev].setCurr); } -} - -bool LbmFsgrSolver::adaptGrid(int lev) { - if((lev<0) || ((lev+1)>mMaxRefine)) return false; - bool change = false; - { // refinement, PASS 1-3 - - //bool nbsok; - // FIXME remove TIMEINTORDER ? - LbmFloat interTime = 0.0; - // update curr from other, as streaming afterwards works on curr - // thus read only from srcSet, modify other - const int srcSet = mLevel[lev].setOther; - const int dstSet = mLevel[lev].setCurr; - const int srcFineSet = mLevel[lev+1].setCurr; - const bool debugRefinement = false; - - // use //template functions for 2D/3D - /*if(strstr(this->getName().c_str(),"Debug")) - if(lev+1==mMaxRefine) { // mixborder - for(int l=0;((l<this->cDirNum) && (!removeFromFine)); l++) { // FARBORD - int ni=2*i+2*this->dfVecX[l], nj=2*j+2*this->dfVecY[l], nk=2*k+2*this->dfVecZ[l]; - if(RFLAG(lev+1, ni,nj,nk, srcFineSet)&CFBnd) { // NEWREFT - removeFromFine=true; - } - } - } // FARBORD */ - for(int k= getForZMin1(); k< getForZMax1(lev); ++k) { - for(int j=1;j<mLevel[lev].lSizey-1;++j) { - for(int i=1;i<mLevel[lev].lSizex-1;++i) { - - if(RFLAG(lev, i,j,k, srcSet) & CFGrFromFine) { - bool removeFromFine = false; - const CellFlagType notAllowed = (CFInter|CFGrFromFine|CFGrToFine); - CellFlagType reqType = CFGrNorm; - if(lev+1==mMaxRefine) reqType = CFNoBndFluid; - - if( (RFLAG(lev+1, (2*i),(2*j),(2*k), srcFineSet) & reqType) && - (!(RFLAG(lev+1, (2*i),(2*j),(2*k), srcFineSet) & (notAllowed)) ) ){ // ok - } else { - removeFromFine=true; - } - - if(removeFromFine) { - // dont turn CFGrFromFine above interface cells into CFGrNorm - //errMsg("performRefinement","Removing CFGrFromFine on lev"<<lev<<" " <<PRINT_IJK<<" srcflag:"<<convertCellFlagType2String(RFLAG(lev+1, (2*i),(2*j),(2*k), srcFineSet)) <<" set:"<<dstSet ); - RFLAG(lev, i,j,k, dstSet) = CFEmpty; -#if FSGR_STRICT_DEBUG==1 - // for interpolation later on during fine grid fixing - // these cells are still correctly inited - RFLAG(lev, i,j,k, dstSet) |= CFGrCoarseInited; // remove later on? FIXME? -#endif // FSGR_STRICT_DEBUG==1 - //RFLAG(lev, i,j,k, mLevel[lev].setOther) = CFEmpty; // FLAGTEST - if((LBMDIM==2)&&(debugRefinement)) debugMarkCell(lev,i,j,k); - change=true; - mNumFsgrChanges++; - for(int l=1; l<this->cDirNum; l++) { - int ni=i+this->dfVecX[l], nj=j+this->dfVecY[l], nk=k+this->dfVecZ[l]; - //errMsg("performRefinement","On lev:"<<lev<<" check: "<<PRINT_VEC(ni,nj,nk)<<" set:"<<dstSet<<" = "<<convertCellFlagType2String(RFLAG(lev, ni,nj,nk, srcSet)) ); - if( ( RFLAG(lev, ni,nj,nk, srcSet)&CFFluid ) && - (!(RFLAG(lev, ni,nj,nk, srcSet)&CFGrFromFine)) ) { // dont change status of nb. from fine cells - // tag as inited for debugging, cell contains fluid DFs anyway - RFLAG(lev, ni,nj,nk, dstSet) = CFFluid|CFGrFromFine|CFGrCoarseInited; - //errMsg("performRefinement","On lev:"<<lev<<" set to from fine: "<<PRINT_VEC(ni,nj,nk)<<" set:"<<dstSet); - //if((LBMDIM==2)&&(debugRefinement)) debugMarkCell(lev,ni,nj,nk); - } - } // l - - // FIXME fix fine level? - } - - // recheck from fine flag - } - }}} // TEST - // PASS 1 */ - - - /*if( ((*pFlagSrc) & (CFGrFromCoarse)) ) { - bool invNb = false; - FORDF1 { - if(RFLAG_NB(lev, i, j, k, SRCS(lev), l) & CFUnused) { invNb = true; } - } - if(!invNb) { - *pFlagSrc = CFFluid|CFGrNorm; - errMsg("coarseAdvance","FC2NRM_CHECK Converted CFGrFromCoarse to Norm at "<<lev<<" "<<PRINT_IJK); - } - } // */ - for(int k= getForZMin1(); k< getForZMax1(lev); ++k) { // TEST - for(int j=1;j<mLevel[lev].lSizey-1;++j) { // TEST - for(int i=1;i<mLevel[lev].lSizex-1;++i) { // TEST - - // test from coarseAdvance - // from coarse cells without unused nbs are not necessary...! -> remove - - if(RFLAG(lev, i,j,k, srcSet) & CFGrFromCoarse) { - - // from coarse cells without unused nbs are not necessary...! -> remove - bool invNb = false; - bool fluidNb = false; - for(int l=1; l<this->cDirNum; l++) { - if(RFLAG_NB(lev, i, j, k, srcSet, l) & CFUnused) { invNb = true; } - if(RFLAG_NB(lev, i, j, k, srcSet, l) & (CFGrNorm)) { fluidNb = true; } - } - if(!invNb) { - // no unused cells around -> calculate normally from now on - RFLAG(lev, i,j,k, dstSet) = CFFluid|CFGrNorm; - if((LBMDIM==2)&&(debugRefinement)) debugMarkCell(lev, i, j, k); - change=true; - mNumFsgrChanges++; - } // from advance - if(!fluidNb) { - // no fluid cells near -> no transfer necessary - RFLAG(lev, i,j,k, dstSet) = CFUnused; - //RFLAG(lev, i,j,k, mLevel[lev].setOther) = CFUnused; // FLAGTEST - if((LBMDIM==2)&&(debugRefinement)) debugMarkCell(lev, i, j, k); - change=true; - mNumFsgrChanges++; - } // from advance - - - // dont allow double transfer - // this might require fixing the neighborhood - if(RFLAG(lev+1, 2*i,2*j,2*k, srcFineSet)&(CFGrFromCoarse)) { - // dont turn CFGrFromFine above interface cells into CFGrNorm - //errMsg("performRefinement","Removing CFGrFromCoarse on lev"<<lev<<" " <<PRINT_IJK<<" due to finer from coarse cell " ); - RFLAG(lev, i,j,k, dstSet) = CFFluid|CFGrNorm; - if(lev>0) RFLAG(lev-1, i/2,j/2,k/2, mLevel[lev-1].setCurr) &= (~CFGrToFine); // TODO add more of these? - if((LBMDIM==2)&&(debugRefinement)) debugMarkCell(lev, i, j, k); - change=true; - mNumFsgrChanges++; - for(int l=1; l<this->cDirNum; l++) { - int ni=i+this->dfVecX[l], nj=j+this->dfVecY[l], nk=k+this->dfVecZ[l]; - if(RFLAG(lev, ni,nj,nk, srcSet)&(CFGrNorm)) { //ok - for(int m=1; m<this->cDirNum; m++) { - int mi= ni +this->dfVecX[m], mj= nj +this->dfVecY[m], mk= nk +this->dfVecZ[m]; - if(RFLAG(lev, mi, mj, mk, srcSet)&CFUnused) { - // norm cells in neighborhood with unused nbs have to be new border... - RFLAG(lev, ni,nj,nk, dstSet) = CFFluid|CFGrFromCoarse; - if((LBMDIM==2)&&(debugRefinement)) debugMarkCell(lev,ni,nj,nk); - } - } - // these alreay have valid values... - } - else if(RFLAG(lev, ni,nj,nk, srcSet)&(CFUnused)) { //ok - // this should work because we have a valid neighborhood here for now - interpolateCellFromCoarse(lev, ni, nj, nk, dstSet, interTime, CFFluid|CFGrFromCoarse, false); - if((LBMDIM==2)&&(debugRefinement)) debugMarkCell(lev,ni,nj,nk); - mNumFsgrChanges++; - } - } // l - } // double transer - - } // from coarse - - } } } - // PASS 2 */ - - - // fix dstSet from fine cells here - // warning - checks CFGrFromFine on dstset changed before! - for(int k= getForZMin1(); k< getForZMax1(lev); ++k) { // TEST - for(int j=1;j<mLevel[lev].lSizey-1;++j) { // TEST - for(int i=1;i<mLevel[lev].lSizex-1;++i) { // TEST - - //if(RFLAG(lev, i,j,k, srcSet) & CFGrFromFine) { - if(RFLAG(lev, i,j,k, dstSet) & CFGrFromFine) { - // modify finer level border - if((RFLAG(lev+1, 2*i,2*j,2*k, srcFineSet)&(CFGrFromCoarse))) { - //errMsg("performRefinement","Removing CFGrFromCoarse on lev"<<(lev+1)<<" from l"<<lev<<" " <<PRINT_IJK ); - CellFlagType setf = CFFluid; - if(lev+1 < mMaxRefine) setf = CFFluid|CFGrNorm; - RFLAG(lev+1, 2*i,2*j,2*k, srcFineSet)=setf; - change=true; - mNumFsgrChanges++; - for(int l=1; l<this->cDirNum; l++) { - int bi=(2*i)+this->dfVecX[l], bj=(2*j)+this->dfVecY[l], bk=(2*k)+this->dfVecZ[l]; - if(RFLAG(lev+1, bi, bj, bk, srcFineSet)&(CFGrFromCoarse)) { - //errMsg("performRefinement","Removing CFGrFromCoarse on lev"<<(lev+1)<<" "<<PRINT_VEC(bi,bj,bk) ); - RFLAG(lev+1, bi, bj, bk, srcFineSet) = setf; - if((LBMDIM==2)&&(debugRefinement)) debugMarkCell(lev+1,bi,bj,bk); - } - else if(RFLAG(lev+1, bi, bj, bk, srcFineSet)&(CFUnused )) { - //errMsg("performRefinement","Removing CFUnused on lev"<<(lev+1)<<" "<<PRINT_VEC(bi,bj,bk) ); - interpolateCellFromCoarse(lev+1, bi, bj, bk, srcFineSet, interTime, setf, false); - if((LBMDIM==2)&&(debugRefinement)) debugMarkCell(lev+1,bi,bj,bk); - mNumFsgrChanges++; - } - } - for(int l=1; l<this->cDirNum; l++) { - int bi=(2*i)+this->dfVecX[l], bj=(2*j)+this->dfVecY[l], bk=(2*k)+this->dfVecZ[l]; - if( (RFLAG(lev+1, bi, bj, bk, srcFineSet)&CFFluid ) && - (!(RFLAG(lev+1, bi, bj, bk, srcFineSet)&CFGrFromCoarse)) ) { - // all unused nbs now of coarse have to be from coarse - for(int m=1; m<this->cDirNum; m++) { - int mi= bi +this->dfVecX[m], mj= bj +this->dfVecY[m], mk= bk +this->dfVecZ[m]; - if(RFLAG(lev+1, mi, mj, mk, srcFineSet)&CFUnused) { - //errMsg("performRefinement","Changing CFUnused on lev"<<(lev+1)<<" "<<PRINT_VEC(mi,mj,mk) ); - interpolateCellFromCoarse(lev+1, mi, mj, mk, srcFineSet, interTime, CFFluid|CFGrFromCoarse, false); - if((LBMDIM==2)&&(debugRefinement)) debugMarkCell(lev+1,mi,mj,mk); - mNumFsgrChanges++; - } - } - // nbs prepared... - } - } - } - - } // convert regions of from fine - }}} // TEST - // PASS 3 */ - - if(!this->mSilent){ errMsg("performRefinement"," for l"<<lev<<" done ("<<change<<") " ); } - } // PASS 1-3 - // refinement done - - //LbmFsgrSolver::performCoarsening(int lev) { - { // PASS 4,5 - bool nbsok; - // WARNING - // now work on modified curr set - const int srcSet = mLevel[lev].setCurr; - const int dstlev = lev+1; - const int dstFineSet = mLevel[dstlev].setCurr; - const bool debugCoarsening = false; - - // PASS 5 test DEBUG - /*if(this->mInitDone) { - for(int k= getForZMin1(); k< getForZMax1(lev); ++k) { - for(int j=1;j<mLevel[lev].lSizey-1;++j) { - for(int i=1;i<mLevel[lev].lSizex-1;++i) { - if(RFLAG(lev, i,j,k, srcSet) & CFEmpty) { - // check empty -> from fine conversion - bool changeToFromFine = false; - const CellFlagType notAllowed = (CFInter|CFGrFromFine|CFGrToFine); - CellFlagType reqType = CFGrNorm; - if(lev+1==mMaxRefine) reqType = CFNoBndFluid; - if( (RFLAG(lev+1, (2*i),(2*j),(2*k), dstFineSet) & reqType) && - (!(RFLAG(lev+1, (2*i),(2*j),(2*k), dstFineSet) & (notAllowed)) ) ){ - changeToFromFine=true; } - if(changeToFromFine) { - change = true; - mNumFsgrChanges++; - RFLAG(lev, i,j,k, srcSet) = CFFluid|CFGrFromFine; - if((LBMDIM==2)&&(debugCoarsening)) debugMarkCell(lev,i,j,k); - // same as restr from fine func! not necessary ?! - // coarseRestrictFromFine part - coarseRestrictCell(lev, i,j,k,srcSet, dstFineSet); - } - } // only check empty cells - }}} // TEST! - } // PASS 5 */ - - // use //template functions for 2D/3D - /*if(strstr(this->getName().c_str(),"Debug")) - if((nbsok)&&(lev+1==mMaxRefine)) { // mixborder - for(int l=0;((l<this->cDirNum) && (nbsok)); l++) { // FARBORD - int ni=2*i+2*this->dfVecX[l], nj=2*j+2*this->dfVecY[l], nk=2*k+2*this->dfVecZ[l]; - if(RFLAG(lev+1, ni,nj,nk, dstFineSet)&CFBnd) { // NEWREFT - nbsok=false; - } - } - } // FARBORD */ - for(int k= getForZMin1(); k< getForZMax1(lev); ++k) { - for(int j=1;j<mLevel[lev].lSizey-1;++j) { - for(int i=1;i<mLevel[lev].lSizex-1;++i) { - - // from coarse cells without unused nbs are not necessary...! -> remove - // perform check from coarseAdvance here? - if(RFLAG(lev, i,j,k, srcSet) & CFGrFromFine) { - // remove from fine cells now that are completely in fluid - // FIXME? check that new from fine in performRefinement never get deleted here afterwards? - // or more general, one cell never changed more than once? - const CellFlagType notAllowed = (CFInter|CFGrFromFine|CFGrToFine); - //const CellFlagType notNbAllowed = (CFInter|CFBnd|CFGrFromFine); unused - CellFlagType reqType = CFGrNorm; - if(lev+1==mMaxRefine) reqType = CFNoBndFluid; - - nbsok = true; - for(int l=0; l<this->cDirNum && nbsok; l++) { - int ni=(2*i)+this->dfVecX[l], nj=(2*j)+this->dfVecY[l], nk=(2*k)+this->dfVecZ[l]; - if( (RFLAG(lev+1, ni,nj,nk, dstFineSet) & reqType) && - (!(RFLAG(lev+1, ni,nj,nk, dstFineSet) & (notAllowed)) ) ){ - // ok - } else { - nbsok=false; - } - // FARBORD - } - // dont turn CFGrFromFine above interface cells into CFGrNorm - // now check nbs on same level - for(int l=1; l<this->cDirNum && nbsok; l++) { - int ni=i+this->dfVecX[l], nj=j+this->dfVecY[l], nk=k+this->dfVecZ[l]; - if(RFLAG(lev, ni,nj,nk, srcSet)&(CFFluid)) { //ok - } else { - nbsok = false; - } - } // l - - if(nbsok) { - // conversion to coarse fluid cell - change = true; - mNumFsgrChanges++; - RFLAG(lev, i,j,k, srcSet) = CFFluid|CFGrNorm; - // dfs are already ok... - //if(this->mInitDone) errMsg("performCoarsening","CFGrFromFine changed to CFGrNorm at lev"<<lev<<" " <<PRINT_IJK ); - if((LBMDIM==2)&&(debugCoarsening)) debugMarkCell(lev,i,j,k); - - // only check complete cubes - for(int dx=-1;dx<=1;dx+=2) { - for(int dy=-1;dy<=1;dy+=2) { - for(int dz=-1*(LBMDIM&1);dz<=1*(LBMDIM&1);dz+=2) { // 2d/3d - // check for norm and from coarse, as the coarse level might just have been refined... - if( - // we now the flag of the current cell! ( RFLAG(lev, i , j , k , srcSet)&(CFGrNorm)) && - ( RFLAG(lev, i+dx, j , k , srcSet)&(CFGrNorm|CFGrFromCoarse)) && - ( RFLAG(lev, i , j+dy, k , srcSet)&(CFGrNorm|CFGrFromCoarse)) && - ( RFLAG(lev, i , j , k+dz, srcSet)&(CFGrNorm|CFGrFromCoarse)) && - - ( RFLAG(lev, i+dx, j+dy, k , srcSet)&(CFGrNorm|CFGrFromCoarse)) && - ( RFLAG(lev, i+dx, j , k+dz, srcSet)&(CFGrNorm|CFGrFromCoarse)) && - ( RFLAG(lev, i , j+dy, k+dz, srcSet)&(CFGrNorm|CFGrFromCoarse)) && - ( RFLAG(lev, i+dx, j+dy, k+dz, srcSet)&(CFGrNorm|CFGrFromCoarse)) - ) { - // middle source node on higher level - int dstx = (2*i)+dx; - int dsty = (2*j)+dy; - int dstz = (2*k)+dz; - - mNumFsgrChanges++; - RFLAG(dstlev, dstx,dsty,dstz, dstFineSet) = CFUnused; - RFLAG(dstlev, dstx,dsty,dstz, mLevel[dstlev].setOther) = CFUnused; // FLAGTEST - //if(this->mInitDone) errMsg("performCoarsening","CFGrFromFine subcube init center unused set l"<<dstlev<<" at "<<PRINT_VEC(dstx,dsty,dstz) ); - - for(int l=1; l<this->cDirNum; l++) { - int dstni=dstx+this->dfVecX[l], dstnj=dsty+this->dfVecY[l], dstnk=dstz+this->dfVecZ[l]; - if(RFLAG(dstlev, dstni,dstnj,dstnk, dstFineSet)&(CFFluid)) { - RFLAG(dstlev, dstni,dstnj,dstnk, dstFineSet) = CFFluid|CFGrFromCoarse; - } - if(RFLAG(dstlev, dstni,dstnj,dstnk, dstFineSet)&(CFInter)) { - //if(this->mInitDone) errMsg("performCoarsening","CFGrFromFine subcube init CHECK Warning - deleting interface cell..."); - this->mFixMass += QCELL( dstlev, dstni,dstnj,dstnk, dstFineSet, dMass); - RFLAG(dstlev, dstni,dstnj,dstnk, dstFineSet) = CFFluid|CFGrFromCoarse; - } - } // l - - // again check nb flags of all surrounding cells to see if any from coarse - // can be convted to unused - for(int l=1; l<this->cDirNum; l++) { - int dstni=dstx+this->dfVecX[l], dstnj=dsty+this->dfVecY[l], dstnk=dstz+this->dfVecZ[l]; - // have to be at least from coarse here... - //errMsg("performCoarsening","CFGrFromFine subcube init unused check l"<<dstlev<<" at "<<PRINT_VEC(dstni,dstnj,dstnk)<<" "<< convertCellFlagType2String(RFLAG(dstlev, dstni,dstnj,dstnk, dstFineSet)) ); - if(!(RFLAG(dstlev, dstni,dstnj,dstnk, dstFineSet)&(CFUnused) )) { - bool delok = true; - // careful long range here... check domain bounds? - for(int m=1; m<this->cDirNum; m++) { - int chkni=dstni+this->dfVecX[m], chknj=dstnj+this->dfVecY[m], chknk=dstnk+this->dfVecZ[m]; - if(RFLAG(dstlev, chkni,chknj,chknk, dstFineSet)&(CFUnused|CFGrFromCoarse)) { - // this nb cell is ok for deletion - } else { - delok=false; // keep it! - } - //errMsg("performCoarsening"," CHECK "<<PRINT_VEC(dstni,dstnj,dstnk)<<" to "<<PRINT_VEC( chkni,chknj,chknk )<<" f:"<< convertCellFlagType2String( RFLAG(dstlev, chkni,chknj,chknk, dstFineSet))<<" nbsok"<<delok ); - } - //errMsg("performCoarsening","CFGrFromFine subcube init unused check l"<<dstlev<<" at "<<PRINT_VEC(dstni,dstnj,dstnk)<<" ok"<<delok ); - if(delok) { - mNumFsgrChanges++; - RFLAG(dstlev, dstni,dstnj,dstnk, dstFineSet) = CFUnused; - RFLAG(dstlev, dstni,dstnj,dstnk, mLevel[dstlev].setOther) = CFUnused; // FLAGTEST - if((LBMDIM==2)&&(debugCoarsening)) debugMarkCell(dstlev,dstni,dstnj,dstnk); - } - } - } // l - // treat subcube - //ebugMarkCell(lev,i+dx,j+dy,k+dz); - //if(this->mInitDone) errMsg("performCoarsening","CFGrFromFine subcube init, dir:"<<PRINT_VEC(dx,dy,dz) ); - } - } } } - - } // ? - } // convert regions of from fine - }}} // TEST! - // PASS 4 */ - - // reinit cell area value - /*if( RFLAG(lev, i,j,k,srcSet) & CFFluid) { - if( RFLAG(lev+1, i*2,j*2,k*2,dstFineSet) & CFGrFromCoarse) { - LbmFloat totArea = mFsgrCellArea[0]; // for l=0 - for(int l=1; l<this->cDirNum; l++) { - int ni=(2*i)+this->dfVecX[l], nj=(2*j)+this->dfVecY[l], nk=(2*k)+this->dfVecZ[l]; - if(RFLAG(lev+1, ni,nj,nk, dstFineSet)& - (CFGrFromCoarse|CFUnused|CFEmpty) //? (CFBnd|CFEmpty|CFGrFromCoarse|CFUnused) - //(CFUnused|CFEmpty) //? (CFBnd|CFEmpty|CFGrFromCoarse|CFUnused) - ) { - //LbmFloat area = 0.25; if(this->dfVecX[l]!=0) area *= 0.5; if(this->dfVecY[l]!=0) area *= 0.5; if(this->dfVecZ[l]!=0) area *= 0.5; - totArea += mFsgrCellArea[l]; - } - } // l - QCELL(lev, i,j,k,mLevel[lev].setOther, dFlux) = - QCELL(lev, i,j,k,srcSet, dFlux) = totArea; - } else { - QCELL(lev, i,j,k,mLevel[lev].setOther, dFlux) = - QCELL(lev, i,j,k,srcSet, dFlux) = 1.0; - } - //errMsg("DFINI"," at l"<<lev<<" "<<PRINT_IJK<<" v:"<<QCELL(lev, i,j,k,srcSet, dFlux) ); - } - // */ - - - // PASS 5 org - /*if(strstr(this->getName().c_str(),"Debug")) - if((changeToFromFine)&&(lev+1==mMaxRefine)) { // mixborder - for(int l=0;((l<this->cDirNum) && (changeToFromFine)); l++) { // FARBORD - int ni=2*i+2*this->dfVecX[l], nj=2*j+2*this->dfVecY[l], nk=2*k+2*this->dfVecZ[l]; - if(RFLAG(lev+1, ni,nj,nk, dstFineSet)&CFBnd) { // NEWREFT - changeToFromFine=false; } - } - }// FARBORD */ - //if(!this->mInitDone) { - for(int k= getForZMin1(); k< getForZMax1(lev); ++k) { - for(int j=1;j<mLevel[lev].lSizey-1;++j) { - for(int i=1;i<mLevel[lev].lSizex-1;++i) { - - - if(RFLAG(lev, i,j,k, srcSet) & CFEmpty) { - // check empty -> from fine conversion - bool changeToFromFine = false; - const CellFlagType notAllowed = (CFInter|CFGrFromFine|CFGrToFine); - CellFlagType reqType = CFGrNorm; - if(lev+1==mMaxRefine) reqType = CFNoBndFluid; - - if( (RFLAG(lev+1, (2*i),(2*j),(2*k), dstFineSet) & reqType) && - (!(RFLAG(lev+1, (2*i),(2*j),(2*k), dstFineSet) & (notAllowed)) ) ){ - // DEBUG - changeToFromFine=true; - } - - // FARBORD - - if(changeToFromFine) { - change = true; - mNumFsgrChanges++; - RFLAG(lev, i,j,k, srcSet) = CFFluid|CFGrFromFine; - if((LBMDIM==2)&&(debugCoarsening)) debugMarkCell(lev,i,j,k); - // same as restr from fine func! not necessary ?! - // coarseRestrictFromFine part - } - } // only check empty cells - - }}} // TEST! - //} // init done - // PASS 5 */ - } // coarsening, PASS 4,5 - - if(!this->mSilent){ errMsg("adaptGrid"," for l"<<lev<<" done " ); } - return change; -} - -/*****************************************************************************/ -//! cell restriction and prolongation -/*****************************************************************************/ - -void LbmFsgrSolver::coarseRestrictCell(int lev, int i,int j,int k, int srcSet, int dstSet) -{ - LbmFloat *ccel = RACPNT(lev+1, 2*i,2*j,2*k,srcSet); - LbmFloat *tcel = RACPNT(lev , i,j,k ,dstSet); - - LbmFloat rho=0.0, ux=0.0, uy=0.0, uz=0.0; - //LbmFloat *ccel = NULL; - //LbmFloat *tcel = NULL; -#if OPT3D==1 - LbmFloat m[LBM_DFNUM]; - // for macro add - LbmFloat usqr; - //LbmFloat *addfcel, *dstcell; - LbmFloat lcsmqadd, lcsmqo, lcsmeq[LBM_DFNUM]; - LbmFloat lcsmDstOmega, lcsmSrcOmega, lcsmdfscale; -#else // OPT3D==true - LbmFloat df[LBM_DFNUM]; - LbmFloat omegaDst, omegaSrc; - LbmFloat feq[LBM_DFNUM]; - LbmFloat dfScale = mDfScaleUp; -#endif // OPT3D==true - -# if OPT3D==0 - // add up weighted dfs - FORDF0{ df[l] = 0.0;} - for(int n=0;(n<this->cDirNum); n++) { - int ni=2*i+1*this->dfVecX[n], nj=2*j+1*this->dfVecY[n], nk=2*k+1*this->dfVecZ[n]; - ccel = RACPNT(lev+1, ni,nj,nk,srcSet);// CFINTTEST - const LbmFloat weight = mGaussw[n]; - FORDF0{ - LbmFloat cdf = weight * RAC(ccel,l); -# if FSGR_STRICT_DEBUG==1 - if( cdf<-1.0 ){ errMsg("INVDFCREST_DFCHECK", PRINT_IJK<<" s"<<dstSet<<" from "<<PRINT_VEC(2*i,2*j,2*k)<<" s"<<srcSet<<" df"<<l<<":"<< df[l]); } -# endif - //errMsg("INVDFCREST_DFCHECK", PRINT_IJK<<" s"<<dstSet<<" from "<<PRINT_VEC(2*i,2*j,2*k)<<" s"<<srcSet<<" df"<<l<<":"<< df[l]<<" = "<<cdf<<" , w"<<weight); - df[l] += cdf; - } - } - - // calc rho etc. from weighted dfs - rho = ux = uy = uz = 0.0; - FORDF0{ - LbmFloat cdf = df[l]; - rho += cdf; - ux += (this->dfDvecX[l]*cdf); - uy += (this->dfDvecY[l]*cdf); - uz += (this->dfDvecZ[l]*cdf); - } - - FORDF0{ feq[l] = this->getCollideEq(l, rho,ux,uy,uz); } - if(mLevel[lev ].lcsmago>0.0) { - const LbmFloat Qo = this->getLesNoneqTensorCoeff(df,feq); - omegaDst = this->getLesOmega(mLevel[lev ].omega,mLevel[lev ].lcsmago,Qo); - omegaSrc = this->getLesOmega(mLevel[lev+1].omega,mLevel[lev+1].lcsmago,Qo); - } else { - omegaDst = mLevel[lev+0].omega; /* NEWSMAGOT*/ - omegaSrc = mLevel[lev+1].omega; - } - dfScale = (mLevel[lev ].timestep/mLevel[lev+1].timestep)* (1.0/omegaDst-1.0)/ (1.0/omegaSrc-1.0); // yu - FORDF0{ - RAC(tcel, l) = feq[l]+ (df[l]-feq[l])*dfScale; - } -# else // OPT3D - // similar to OPTIMIZED_STREAMCOLLIDE_UNUSED - - //rho = ux = uy = uz = 0.0; - MSRC_C = CCELG_C(0) ; - MSRC_N = CCELG_N(0) ; - MSRC_S = CCELG_S(0) ; - MSRC_E = CCELG_E(0) ; - MSRC_W = CCELG_W(0) ; - MSRC_T = CCELG_T(0) ; - MSRC_B = CCELG_B(0) ; - MSRC_NE = CCELG_NE(0); - MSRC_NW = CCELG_NW(0); - MSRC_SE = CCELG_SE(0); - MSRC_SW = CCELG_SW(0); - MSRC_NT = CCELG_NT(0); - MSRC_NB = CCELG_NB(0); - MSRC_ST = CCELG_ST(0); - MSRC_SB = CCELG_SB(0); - MSRC_ET = CCELG_ET(0); - MSRC_EB = CCELG_EB(0); - MSRC_WT = CCELG_WT(0); - MSRC_WB = CCELG_WB(0); - for(int n=1;(n<this->cDirNum); n++) { - ccel = RACPNT(lev+1, 2*i+1*this->dfVecX[n], 2*j+1*this->dfVecY[n], 2*k+1*this->dfVecZ[n] ,srcSet); - MSRC_C += CCELG_C(n) ; - MSRC_N += CCELG_N(n) ; - MSRC_S += CCELG_S(n) ; - MSRC_E += CCELG_E(n) ; - MSRC_W += CCELG_W(n) ; - MSRC_T += CCELG_T(n) ; - MSRC_B += CCELG_B(n) ; - MSRC_NE += CCELG_NE(n); - MSRC_NW += CCELG_NW(n); - MSRC_SE += CCELG_SE(n); - MSRC_SW += CCELG_SW(n); - MSRC_NT += CCELG_NT(n); - MSRC_NB += CCELG_NB(n); - MSRC_ST += CCELG_ST(n); - MSRC_SB += CCELG_SB(n); - MSRC_ET += CCELG_ET(n); - MSRC_EB += CCELG_EB(n); - MSRC_WT += CCELG_WT(n); - MSRC_WB += CCELG_WB(n); - } - rho = MSRC_C + MSRC_N + MSRC_S + MSRC_E + MSRC_W + MSRC_T - + MSRC_B + MSRC_NE + MSRC_NW + MSRC_SE + MSRC_SW + MSRC_NT - + MSRC_NB + MSRC_ST + MSRC_SB + MSRC_ET + MSRC_EB + MSRC_WT + MSRC_WB; - ux = MSRC_E - MSRC_W + MSRC_NE - MSRC_NW + MSRC_SE - MSRC_SW - + MSRC_ET + MSRC_EB - MSRC_WT - MSRC_WB; - uy = MSRC_N - MSRC_S + MSRC_NE + MSRC_NW - MSRC_SE - MSRC_SW - + MSRC_NT + MSRC_NB - MSRC_ST - MSRC_SB; - uz = MSRC_T - MSRC_B + MSRC_NT - MSRC_NB + MSRC_ST - MSRC_SB - + MSRC_ET - MSRC_EB + MSRC_WT - MSRC_WB; - usqr = 1.5 * (ux*ux + uy*uy + uz*uz); \ - \ - lcsmeq[dC] = EQC ; \ - COLL_CALCULATE_DFEQ(lcsmeq); \ - COLL_CALCULATE_NONEQTENSOR(lev+0, MSRC_ )\ - COLL_CALCULATE_CSMOMEGAVAL(lev+0, lcsmDstOmega); \ - COLL_CALCULATE_CSMOMEGAVAL(lev+1, lcsmSrcOmega); \ - \ - lcsmdfscale = (mLevel[lev+0].timestep/mLevel[lev+1].timestep)* (1.0/lcsmDstOmega-1.0)/ (1.0/lcsmSrcOmega-1.0); \ - RAC(tcel, dC ) = (lcsmeq[dC ] + (MSRC_C -lcsmeq[dC ] )*lcsmdfscale); - RAC(tcel, dN ) = (lcsmeq[dN ] + (MSRC_N -lcsmeq[dN ] )*lcsmdfscale); - RAC(tcel, dS ) = (lcsmeq[dS ] + (MSRC_S -lcsmeq[dS ] )*lcsmdfscale); - RAC(tcel, dE ) = (lcsmeq[dE ] + (MSRC_E -lcsmeq[dE ] )*lcsmdfscale); - RAC(tcel, dW ) = (lcsmeq[dW ] + (MSRC_W -lcsmeq[dW ] )*lcsmdfscale); - RAC(tcel, dT ) = (lcsmeq[dT ] + (MSRC_T -lcsmeq[dT ] )*lcsmdfscale); - RAC(tcel, dB ) = (lcsmeq[dB ] + (MSRC_B -lcsmeq[dB ] )*lcsmdfscale); - RAC(tcel, dNE) = (lcsmeq[dNE] + (MSRC_NE-lcsmeq[dNE] )*lcsmdfscale); - RAC(tcel, dNW) = (lcsmeq[dNW] + (MSRC_NW-lcsmeq[dNW] )*lcsmdfscale); - RAC(tcel, dSE) = (lcsmeq[dSE] + (MSRC_SE-lcsmeq[dSE] )*lcsmdfscale); - RAC(tcel, dSW) = (lcsmeq[dSW] + (MSRC_SW-lcsmeq[dSW] )*lcsmdfscale); - RAC(tcel, dNT) = (lcsmeq[dNT] + (MSRC_NT-lcsmeq[dNT] )*lcsmdfscale); - RAC(tcel, dNB) = (lcsmeq[dNB] + (MSRC_NB-lcsmeq[dNB] )*lcsmdfscale); - RAC(tcel, dST) = (lcsmeq[dST] + (MSRC_ST-lcsmeq[dST] )*lcsmdfscale); - RAC(tcel, dSB) = (lcsmeq[dSB] + (MSRC_SB-lcsmeq[dSB] )*lcsmdfscale); - RAC(tcel, dET) = (lcsmeq[dET] + (MSRC_ET-lcsmeq[dET] )*lcsmdfscale); - RAC(tcel, dEB) = (lcsmeq[dEB] + (MSRC_EB-lcsmeq[dEB] )*lcsmdfscale); - RAC(tcel, dWT) = (lcsmeq[dWT] + (MSRC_WT-lcsmeq[dWT] )*lcsmdfscale); - RAC(tcel, dWB) = (lcsmeq[dWB] + (MSRC_WB-lcsmeq[dWB] )*lcsmdfscale); -# endif // OPT3D==0 -} - -void LbmFsgrSolver::interpolateCellFromCoarse(int lev, int i, int j,int k, int dstSet, LbmFloat t, CellFlagType flagSet, bool markNbs) { - LbmFloat rho=0.0, ux=0.0, uy=0.0, uz=0.0; - LbmFloat intDf[19] = { 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0 }; - -#if OPT3D==1 - // for macro add - LbmFloat addDfFacT, addVal, usqr; - LbmFloat *addfcel, *dstcell; - LbmFloat lcsmqadd, lcsmqo, lcsmeq[LBM_DFNUM]; - LbmFloat lcsmDstOmega, lcsmSrcOmega, lcsmdfscale; -#endif // OPT3D==true - - // SET required nbs to from coarse (this might overwrite flag several times) - // this is not necessary for interpolateFineFromCoarse - if(markNbs) { - FORDF1{ - int ni=i+this->dfVecX[l], nj=j+this->dfVecY[l], nk=k+this->dfVecZ[l]; - if(RFLAG(lev,ni,nj,nk,dstSet)&CFUnused) { - // parents have to be inited! - interpolateCellFromCoarse(lev, ni, nj, nk, dstSet, t, CFFluid|CFGrFromCoarse, false); - } - } } - - // change flag of cell to be interpolated - RFLAG(lev,i,j,k, dstSet) = flagSet; - mNumInterdCells++; - - // interpolation lines... - int betx = i&1; - int bety = j&1; - int betz = k&1; - - if((!betx) && (!bety) && (!betz)) { - ADD_INT_DFS(lev-1, i/2 ,j/2 ,k/2 , 0.0, 1.0); - } - else if(( betx) && (!bety) && (!betz)) { - ADD_INT_DFS(lev-1, (i/2) ,(j/2) ,(k/2) , t, WO1D1); - ADD_INT_DFS(lev-1, (i/2)+1,(j/2) ,(k/2) , t, WO1D1); - } - else if((!betx) && ( bety) && (!betz)) { - ADD_INT_DFS(lev-1, (i/2) ,(j/2) ,(k/2) , t, WO1D1); - ADD_INT_DFS(lev-1, (i/2) ,(j/2)+1,(k/2) , t, WO1D1); - } - else if((!betx) && (!bety) && ( betz)) { - ADD_INT_DFS(lev-1, (i/2) ,(j/2) ,(k/2) , t, WO1D1); - ADD_INT_DFS(lev-1, (i/2) ,(j/2) ,(k/2)+1, t, WO1D1); - } - else if(( betx) && ( bety) && (!betz)) { - ADD_INT_DFS(lev-1, (i/2) ,(j/2) ,(k/2) , t, WO1D2); - ADD_INT_DFS(lev-1, (i/2)+1,(j/2) ,(k/2) , t, WO1D2); - ADD_INT_DFS(lev-1, (i/2) ,(j/2)+1,(k/2) , t, WO1D2); - ADD_INT_DFS(lev-1, (i/2)+1,(j/2)+1,(k/2) , t, WO1D2); - } - else if((!betx) && ( bety) && ( betz)) { - ADD_INT_DFS(lev-1, (i/2) ,(j/2) ,(k/2) , t, WO1D2); - ADD_INT_DFS(lev-1, (i/2) ,(j/2) ,(k/2)+1, t, WO1D2); - ADD_INT_DFS(lev-1, (i/2) ,(j/2)+1,(k/2) , t, WO1D2); - ADD_INT_DFS(lev-1, (i/2) ,(j/2)+1,(k/2)+1, t, WO1D2); - } - else if(( betx) && (!bety) && ( betz)) { - ADD_INT_DFS(lev-1, (i/2) ,(j/2) ,(k/2) , t, WO1D2); - ADD_INT_DFS(lev-1, (i/2)+1,(j/2) ,(k/2) , t, WO1D2); - ADD_INT_DFS(lev-1, (i/2) ,(j/2) ,(k/2)+1, t, WO1D2); - ADD_INT_DFS(lev-1, (i/2)+1,(j/2) ,(k/2)+1, t, WO1D2); - } - else if(( betx) && ( bety) && ( betz)) { - ADD_INT_DFS(lev-1, (i/2) ,(j/2) ,(k/2) , t, WO1D3); - ADD_INT_DFS(lev-1, (i/2)+1,(j/2) ,(k/2) , t, WO1D3); - ADD_INT_DFS(lev-1, (i/2) ,(j/2) ,(k/2)+1, t, WO1D3); - ADD_INT_DFS(lev-1, (i/2)+1,(j/2) ,(k/2)+1, t, WO1D3); - ADD_INT_DFS(lev-1, (i/2) ,(j/2)+1,(k/2) , t, WO1D3); - ADD_INT_DFS(lev-1, (i/2)+1,(j/2)+1,(k/2) , t, WO1D3); - ADD_INT_DFS(lev-1, (i/2) ,(j/2)+1,(k/2)+1, t, WO1D3); - ADD_INT_DFS(lev-1, (i/2)+1,(j/2)+1,(k/2)+1, t, WO1D3); - } - else { - CAUSE_PANIC; - errFatal("interpolateCellFromCoarse","Invalid!?", SIMWORLD_GENERICERROR); - } - - IDF_WRITEBACK; - return; -} - - - -#define MPTADAP_INTERV 4 - -/*****************************************************************************/ -/*! change the size of the LBM time step */ -/*****************************************************************************/ -void LbmFsgrSolver::adaptTimestep() { - LbmFloat massTOld=0.0, massTNew=0.0; - LbmFloat volTOld=0.0, volTNew=0.0; - - bool rescale = false; // do any rescale at all? - LbmFloat scaleFac = -1.0; // timestep scaling - if(mPanic) return; - - LbmFloat levOldOmega[FSGR_MAXNOOFLEVELS]; - LbmFloat levOldStepsize[FSGR_MAXNOOFLEVELS]; - for(int lev=mMaxRefine; lev>=0 ; lev--) { - levOldOmega[lev] = mLevel[lev].omega; - levOldStepsize[lev] = mLevel[lev].timestep; - } - - const LbmFloat reduceFac = 0.8; // modify time step by 20%, TODO? do multiple times for large changes? - LbmFloat diffPercent = 0.05; // dont scale if less than 5% - LbmFloat allowMax = mpParam->getTadapMaxSpeed(); // maximum allowed velocity - LbmFloat nextmax = mpParam->getSimulationMaxSpeed() + norm(mLevel[mMaxRefine].gravity); - - // sync nextmax -#if LBM_INCLUDE_TESTSOLVERS==1 - if(glob_mpactive) { - if(mLevel[mMaxRefine].lsteps % MPTADAP_INTERV != MPTADAP_INTERV-1) { - debMsgStd("LbmFsgrSolver::TAdp",DM_MSG, "mpact:"<<glob_mpactive<<","<<glob_mpindex<<"/"<<glob_mpnum<<" step:"<<mLevel[mMaxRefine].lsteps<<" skipping tadap...",8); - return; - } - nextmax = mrInitTadap(nextmax); - } -#endif // LBM_INCLUDE_TESTSOLVERS==1 - - LbmFloat newdt = mpParam->getTimestep(); // newtr - if(nextmax > allowMax/reduceFac) { - mTimeMaxvelStepCnt++; } - else { mTimeMaxvelStepCnt=0; } - - // emergency, or 10 steps with high vel - if((mTimeMaxvelStepCnt>5) || (nextmax> (1.0/3.0)) || (mForceTimeStepReduce) ) { - newdt = mpParam->getTimestep() * reduceFac; - } else { - if(nextmax<allowMax*reduceFac) { - newdt = mpParam->getTimestep() / reduceFac; - } - } // newtr - //errMsg("LbmFsgrSolver::adaptTimestep","nextmax="<<nextmax<<" allowMax="<<allowMax<<" fac="<<reduceFac<<" simmaxv="<< mpParam->getSimulationMaxSpeed() ); - - bool minCutoff = false; - LbmFloat desireddt = newdt; - if(newdt>mpParam->getMaxTimestep()){ newdt = mpParam->getMaxTimestep(); } - if(newdt<mpParam->getMinTimestep()){ - newdt = mpParam->getMinTimestep(); - if(nextmax>allowMax/reduceFac){ minCutoff=true; } // only if really large vels... - } - - LbmFloat dtdiff = fabs(newdt - mpParam->getTimestep()); - if(!mSilent) { - debMsgStd("LbmFsgrSolver::TAdp",DM_MSG, "new"<<newdt - <<" max"<<mpParam->getMaxTimestep()<<" min"<<mpParam->getMinTimestep()<<" diff"<<dtdiff - <<" simt:"<<mSimulationTime<<" minsteps:"<<(mSimulationTime/mMaxTimestep)<<" maxsteps:"<<(mSimulationTime/mMinTimestep)<< - " olddt"<<levOldStepsize[mMaxRefine]<<" redlock"<<mTimestepReduceLock - , 10); } - - // in range, and more than X% change? - //if( newdt < mpParam->getTimestep() ) // DEBUG - LbmFloat rhoAvg = mCurrentMass/mCurrentVolume; - if( (newdt<=mpParam->getMaxTimestep()) && (newdt>=mpParam->getMinTimestep()) - && (dtdiff>(mpParam->getTimestep()*diffPercent)) ) { - if((newdt>levOldStepsize[mMaxRefine])&&(mTimestepReduceLock)) { - // wait some more... - //debMsgNnl("LbmFsgrSolver::TAdp",DM_NOTIFY," Delayed... "<<mTimestepReduceLock<<" ",10); - debMsgDirect("D"); - } else { - mpParam->setDesiredTimestep( newdt ); - rescale = true; - if(!mSilent) { - debMsgStd("LbmFsgrSolver::TAdp",DM_NOTIFY,"\n\n\n\n",10); - debMsgStd("LbmFsgrSolver::TAdp",DM_NOTIFY,"Timestep changing: new="<<newdt<<" old="<<mpParam->getTimestep() - <<" maxSpeed:"<<mpParam->getSimulationMaxSpeed()<<" next:"<<nextmax<<" step:"<<mStepCnt, 10 ); - //debMsgStd("LbmFsgrSolver::TAdp",DM_NOTIFY,"Timestep changing: "<< "rhoAvg="<<rhoAvg<<" cMass="<<mCurrentMass<<" cVol="<<mCurrentVolume,10); - } - } // really change dt - } - - if(mTimestepReduceLock>0) mTimestepReduceLock--; - - - // forced back and forth switchting (for testing) - /*const int tadtogInter = 100; - const double tadtogSwitch = 0.66; - errMsg("TIMESWITCHTOGGLETEST","warning enabled "<< tadtogSwitch<<","<<tadtogSwitch<<" !!!!!!!!!!!!!!!!!!!"); - if( ((mStepCnt% tadtogInter)== (tadtogInter/4*1)-1) || - ((mStepCnt% tadtogInter)== (tadtogInter/4*2)-1) ){ - rescale = true; minCutoff = false; - newdt = tadtogSwitch * mpParam->getTimestep(); - mpParam->setDesiredTimestep( newdt ); - } else - if( ((mStepCnt% tadtogInter)== (tadtogInter/4*3)-1) || - ((mStepCnt% tadtogInter)== (tadtogInter/4*4)-1) ){ - rescale = true; minCutoff = false; - newdt = mpParam->getTimestep()/tadtogSwitch ; - mpParam->setDesiredTimestep( newdt ); - } else { - rescale = false; minCutoff = false; - } - // */ - - // test mass rescale - - scaleFac = newdt/mpParam->getTimestep(); - if(rescale) { - // perform acutal rescaling... - mTimeMaxvelStepCnt=0; - mForceTimeStepReduce = false; - - // FIXME - approximate by averaging, take gravity direction here? - //mTimestepReduceLock = 4*(mLevel[mMaxRefine].lSizey+mLevel[mMaxRefine].lSizez+mLevel[mMaxRefine].lSizex)/3; - // use z as gravity direction - mTimestepReduceLock = 4*mLevel[mMaxRefine].lSizez; - - mTimeSwitchCounts++; - mpParam->calculateAllMissingValues( mSimulationTime, mSilent ); - recalculateObjectSpeeds(); - // calc omega, force for all levels - mLastOmega=1e10; mLastGravity=1e10; - initLevelOmegas(); - if(mpParam->getTimestep()<mMinTimestep) mMinTimestep = mpParam->getTimestep(); - if(mpParam->getTimestep()>mMaxTimestep) mMaxTimestep = mpParam->getTimestep(); - - // this might be called during init, before we have any particles - if(mpParticles) { mpParticles->adaptPartTimestep(scaleFac); } -#if LBM_INCLUDE_TESTSOLVERS==1 - if((mUseTestdata)&&(mpTest)) { - mpTest->adaptTimestep(scaleFac, mLevel[mMaxRefine].omega, mLevel[mMaxRefine].timestep, vec2L( mpParam->calculateGravity(mSimulationTime)) ); - mpTest->mGrav3d = mLevel[mMaxRefine].gravity; - } -#endif // LBM_INCLUDE_TESTSOLVERS!=1 - - for(int lev=mMaxRefine; lev>=0 ; lev--) { - LbmFloat newSteptime = mLevel[lev].timestep; - LbmFloat dfScaleFac = (newSteptime/1.0)/(levOldStepsize[lev]/levOldOmega[lev]); - - if(!mSilent) { - debMsgStd("LbmFsgrSolver::TAdp",DM_NOTIFY,"Level: "<<lev<<" Timestep chlevel: "<< - " scaleFac="<<dfScaleFac<<" newDt="<<newSteptime<<" newOmega="<<mLevel[lev].omega,10); - } - if(lev!=mMaxRefine) coarseCalculateFluxareas(lev); - - int wss = 0, wse = 1; - // only change currset (necessary for compressed grids, better for non-compr.gr.) - wss = wse = mLevel[lev].setCurr; - for(int workSet = wss; workSet<=wse; workSet++) { // COMPRT - // warning - check sets for higher levels...? - FSGR_FORIJK1(lev) { - if( (RFLAG(lev,i,j,k, workSet) & CFBndMoving) ) { - /* - // paranoid check - shouldnt be necessary! - if(QCELL(lev, i, j, k, workSet, dFlux)!=mSimulationTime) { - errMsg("TTTT","found invalid bnd cell.... removing at "<<PRINT_IJK); - RFLAG(lev,i,j,k, workSet) = CFInter; - // init empty zero vel interface cell... - initVelocityCell(lev, i,j,k, CFInter, 1.0, 0.01, LbmVec(0.) ); - } else {// */ - for(int l=0; l<cDfNum; l++) { - QCELL(lev, i, j, k, workSet, l) = QCELL(lev, i, j, k, workSet, l)* scaleFac; - } - //} // ok - continue; - } - if( - (RFLAG(lev,i,j,k, workSet) & CFFluid) || - (RFLAG(lev,i,j,k, workSet) & CFInter) || - (RFLAG(lev,i,j,k, workSet) & CFGrFromCoarse) || - (RFLAG(lev,i,j,k, workSet) & CFGrFromFine) || - (RFLAG(lev,i,j,k, workSet) & CFGrNorm) - ) { - // these cells have to be scaled... - } else { - continue; - } - - // collide on current set - LbmFloat rhoOld; - LbmVec velOld; - LbmFloat rho, ux,uy,uz; - rho=0.0; ux = uy = uz = 0.0; - for(int l=0; l<cDfNum; l++) { - LbmFloat m = QCELL(lev, i, j, k, workSet, l); - rho += m; - ux += (dfDvecX[l]*m); - uy += (dfDvecY[l]*m); - uz += (dfDvecZ[l]*m); - } - rhoOld = rho; - velOld = LbmVec(ux,uy,uz); - - LbmFloat rhoNew = (rhoOld-rhoAvg)*scaleFac +rhoAvg; - LbmVec velNew = velOld * scaleFac; - - LbmFloat df[LBM_DFNUM]; - LbmFloat feqOld[LBM_DFNUM]; - LbmFloat feqNew[LBM_DFNUM]; - for(int l=0; l<cDfNum; l++) { - feqOld[l] = getCollideEq(l,rhoOld, velOld[0],velOld[1],velOld[2] ); - feqNew[l] = getCollideEq(l,rhoNew, velNew[0],velNew[1],velNew[2] ); - df[l] = QCELL(lev, i,j,k,workSet, l); - } - const LbmFloat Qo = getLesNoneqTensorCoeff(df,feqOld); - const LbmFloat oldOmega = getLesOmega(levOldOmega[lev], mLevel[lev].lcsmago,Qo); - const LbmFloat newOmega = getLesOmega(mLevel[lev].omega,mLevel[lev].lcsmago,Qo); - //newOmega = mLevel[lev].omega; // FIXME debug test - - //LbmFloat dfScaleFac = (newSteptime/1.0)/(levOldStepsize[lev]/levOldOmega[lev]); - const LbmFloat dfScale = (newSteptime/newOmega)/(levOldStepsize[lev]/oldOmega); - //dfScale = dfScaleFac/newOmega; - - for(int l=0; l<cDfNum; l++) { - // org scaling - //df = eqOld + (df-eqOld)*dfScale; df *= (eqNew/eqOld); // non-eq. scaling, important - // new scaling - LbmFloat dfn = feqNew[l] + (df[l]-feqOld[l])*dfScale*feqNew[l]/feqOld[l]; // non-eq. scaling, important - //df = eqNew + (df-eqOld)*dfScale; // modified ig scaling, no real difference? - QCELL(lev, i,j,k,workSet, l) = dfn; - } - - if(RFLAG(lev,i,j,k, workSet) & CFInter) { - //if(workSet==mLevel[lev].setCurr) - LbmFloat area = 1.0; - if(lev!=mMaxRefine) area = QCELL(lev, i,j,k,workSet, dFlux); - massTOld += QCELL(lev, i,j,k,workSet, dMass) * area; - volTOld += QCELL(lev, i,j,k,workSet, dFfrac); - - // wrong... QCELL(i,j,k,workSet, dMass] = (QCELL(i,j,k,workSet, dFfrac]*rhoNew); - QCELL(lev, i,j,k,workSet, dMass) = (QCELL(lev, i,j,k,workSet, dMass)/rhoOld*rhoNew); - QCELL(lev, i,j,k,workSet, dFfrac) = (QCELL(lev, i,j,k,workSet, dMass)/rhoNew); - - //if(workSet==mLevel[lev].setCurr) - massTNew += QCELL(lev, i,j,k,workSet, dMass); - volTNew += QCELL(lev, i,j,k,workSet, dFfrac); - } - if(RFLAG(lev,i,j,k, workSet) & CFFluid) { // DEBUG - if(RFLAG(lev,i,j,k, workSet) & (CFGrFromFine|CFGrFromCoarse)) { // DEBUG - // dont include - } else { - LbmFloat area = 1.0; - if(lev!=mMaxRefine) area = QCELL(lev, i,j,k,workSet, dFlux) * mLevel[lev].lcellfactor; - //if(workSet==mLevel[lev].setCurr) - massTOld += rhoOld*area; - //if(workSet==mLevel[lev].setCurr) - massTNew += rhoNew*area; - volTOld += area; - volTNew += area; - } - } - - } // IJK - } // workSet - - } // lev - - if(!mSilent) { - debMsgStd("LbmFsgrSolver::step",DM_MSG,"REINIT DONE "<<mStepCnt<< - " no"<<mTimeSwitchCounts<<" maxdt"<<mMaxTimestep<< - " mindt"<<mMinTimestep<<" currdt"<<mLevel[mMaxRefine].timestep, 10); - debMsgStd("LbmFsgrSolver::step",DM_MSG,"REINIT DONE masst:"<<massTNew<<","<<massTOld<<" org:"<<mCurrentMass<<"; "<< - " volt:"<<volTNew<<","<<volTOld<<" org:"<<mCurrentVolume, 10); - } else { - debMsgStd("\nLbmOptSolver::step",DM_MSG,"Timestep changed by "<< (newdt/levOldStepsize[mMaxRefine]) <<" newDt:"<<newdt - <<", oldDt:"<<levOldStepsize[mMaxRefine]<<" newOmega:"<<mOmega<<" gStar:"<<mpParam->getCurrentGStar()<<", step:"<<mStepCnt , 10); - } - } // rescale? - //NEWDEBCHECK("tt2"); - - //errMsg("adaptTimestep","Warning - brute force rescale off!"); minCutoff = false; // DEBUG - if(minCutoff) { - errMsg("adaptTimestep","Warning - performing Brute-Force rescale... (sim:"<<mName<<" step:"<<mStepCnt<<" newdt="<<desireddt<<" mindt="<<mpParam->getMinTimestep()<<") " ); - //brute force resacle all the time? - - for(int lev=mMaxRefine; lev>=0 ; lev--) { - int rescs=0; - int wss = 0, wse = 1; -#if COMPRESSGRIDS==1 - if(lev== mMaxRefine) wss = wse = mLevel[lev].setCurr; -#endif // COMPRESSGRIDS==1 - for(int workSet = wss; workSet<=wse; workSet++) { // COMPRT - //for(int workSet = 0; workSet<=1; workSet++) { - FSGR_FORIJK1(lev) { - - //if( (RFLAG(lev, i,j,k, workSet) & CFFluid) || (RFLAG(lev, i,j,k, workSet) & CFInter) ) { - if( - (RFLAG(lev,i,j,k, workSet) & CFFluid) || - (RFLAG(lev,i,j,k, workSet) & CFInter) || - (RFLAG(lev,i,j,k, workSet) & CFGrFromCoarse) || - (RFLAG(lev,i,j,k, workSet) & CFGrFromFine) || - (RFLAG(lev,i,j,k, workSet) & CFGrNorm) - ) { - // these cells have to be scaled... - } else { - continue; - } - - // collide on current set - LbmFloat rho, ux,uy,uz; - rho=0.0; ux = uy = uz = 0.0; - for(int l=0; l<cDfNum; l++) { - LbmFloat m = QCELL(lev, i, j, k, workSet, l); - rho += m; - ux += (dfDvecX[l]*m); - uy += (dfDvecY[l]*m); - uz += (dfDvecZ[l]*m); - } -#ifndef WIN32 - if (!isfinite(rho)) { - errMsg("adaptTimestep","Brute force non-finite rho at"<<PRINT_IJK); // DEBUG! - rho = 1.0; - ux = uy = uz = 0.0; - QCELL(lev, i, j, k, workSet, dMass) = 1.0; - QCELL(lev, i, j, k, workSet, dFfrac) = 1.0; - } -#endif // WIN32 - - if( (ux*ux+uy*uy+uz*uz)> (allowMax*allowMax) ) { - LbmFloat cfac = allowMax/sqrt(ux*ux+uy*uy+uz*uz); - ux *= cfac; - uy *= cfac; - uz *= cfac; - for(int l=0; l<cDfNum; l++) { - QCELL(lev, i, j, k, workSet, l) = getCollideEq(l, rho, ux,uy,uz); } - rescs++; - debMsgDirect("B"); - } - - } } - //if(rescs>0) { errMsg("adaptTimestep","!!!!! Brute force rescaling was necessary !!!!!!!"); } - debMsgStd("adaptTimestep",DM_MSG,"Brute force rescale done. level:"<<lev<<" rescs:"<<rescs, 1); - //TTT mNumProblems += rescs; // add to problem display... - } // lev,set,ijk - - } // try brute force rescale? - - // time adap done... -} - - - diff --git a/intern/elbeem/intern/solver_class.h b/intern/elbeem/intern/solver_class.h deleted file mode 100644 index ac02f2cc85a..00000000000 --- a/intern/elbeem/intern/solver_class.h +++ /dev/null @@ -1,1036 +0,0 @@ -/** \file - * \ingroup elbeem - */ -/****************************************************************************** - * - * El'Beem - the visual lattice boltzmann freesurface simulator - * All code distributed as part of El'Beem is covered by the version 2 of the - * GNU General Public License. See the file COPYING for details. - * Copyright 2003-2006 Nils Thuerey - * - * Combined 2D/3D Lattice Boltzmann standard solver classes - * - *****************************************************************************/ - - -#ifndef LBM_SOLVERCLASS_H -#define LBM_SOLVERCLASS_H - -#include "utilities.h" -#include "solver_interface.h" -#include "ntl_ray.h" -#include <stdio.h> - -#ifdef WITH_CXX_GUARDEDALLOC -# include "MEM_guardedalloc.h" -#endif - -#if PARALLEL==1 -#include <omp.h> -#endif // PARALLEL=1 -#ifndef PARALLEL -#define PARALLEL 0 -#endif // PARALLEL - - -// general solver setting defines - -//! debug coordinate accesses and the like? (much slower) -// might be enabled by compilation -#ifndef FSGR_STRICT_DEBUG -#define FSGR_STRICT_DEBUG 0 -#endif // FSGR_STRICT_DEBUG - -//! debug coordinate accesses and the like? (much slower) -#define FSGR_OMEGA_DEBUG 0 - -//! OPT3D quick LES on/off, only debug/benchmarking -#define USE_LES 1 - -//! order of interpolation (0=always current/1=interpolate/2=always other) -//#define TIMEINTORDER 0 -// TODO remove interpol t param, also interTime - -// use optimized 3D code? -#if LBMDIM==2 -#define OPT3D 0 -#else -// determine with debugging... -# if FSGR_STRICT_DEBUG==1 -# define OPT3D 0 -# else // FSGR_STRICT_DEBUG==1 -// usually switch optimizations for 3d on, when not debugging -# define OPT3D 1 -// COMPRT -//# define OPT3D 0 -# endif // FSGR_STRICT_DEBUG==1 -#endif - -//! invalid mass value for unused mass data -#define MASS_INVALID -1000.0 - -// empty/fill cells without fluid/empty NB's by inserting them into the full/empty lists? -#define FSGR_LISTTRICK 1 -#define FSGR_LISTTTHRESHEMPTY 0.10 -#define FSGR_LISTTTHRESHFULL 0.90 -#define FSGR_MAGICNR 0.025 -//0.04 - -//! maxmimum no. of grid levels -#define FSGR_MAXNOOFLEVELS 5 - -// enable/disable fine grid compression for finest level -// make sure this is same as useGridComp in calculateMemreqEstimate -#if LBMDIM==3 -#define COMPRESSGRIDS 1 -#else -#define COMPRESSGRIDS 0 -#endif - -// helper for comparing floats with epsilon -#define GFX_FLOATNEQ(x,y) ( ABS((x)-(y)) > (VECTOR_EPSILON) ) -#define LBM_FLOATNEQ(x,y) ( ABS((x)-(y)) > (10.0*LBM_EPSILON) ) - - -// macros for loops over all DFs -#define FORDF0 for(int l= 0; l< LBM_DFNUM; ++l) -#define FORDF1 for(int l= 1; l< LBM_DFNUM; ++l) -// and with different loop var to prevent shadowing -#define FORDF0M for(int m= 0; m< LBM_DFNUM; ++m) -#define FORDF1M for(int m= 1; m< LBM_DFNUM; ++m) - -// iso value defines -// border for marching cubes -#define ISOCORR 3 - -#define LBM_INLINED inline - -// sirdude fix for solaris -#if !defined(linux) && defined(sun) -#include "ieeefp.h" -#ifndef expf -#define expf(x) exp((double)(x)) -#endif -#endif - -#include "solver_control.h" - -#if LBM_INCLUDE_TESTSOLVERS==1 -#include "solver_test.h" -#endif // LBM_INCLUDE_TESTSOLVERS==1 - -/*****************************************************************************/ -/*! cell access classes */ -class UniformFsgrCellIdentifier : - public CellIdentifierInterface , public LbmCellContents -{ - public: - //! which grid level? - int level; - //! location in grid - int x,y,z; - - //! reset constructor - UniformFsgrCellIdentifier() : - x(0), y(0), z(0) { }; - - // implement CellIdentifierInterface - virtual string getAsString() { - std::ostringstream ret; - ret <<"{ i"<<x<<",j"<<y; - if(LBMDIM>2) ret<<",k"<<z; - ret <<" }"; - return ret.str(); - } - - virtual bool equal(CellIdentifierInterface* other) { - UniformFsgrCellIdentifier *cid = (UniformFsgrCellIdentifier *)( other ); - if(!cid) return false; - if( x==cid->x && y==cid->y && z==cid->z && level==cid->level ) return true; - return false; - } - -private: -#ifdef WITH_CXX_GUARDEDALLOC - MEM_CXX_CLASS_ALLOC_FUNCS("ELBEEM:UniformFsgrCellIdentifier") -#endif -}; - -//! information needed for each level in the simulation -class FsgrLevelData { -public: - int id; // level number - - //! node size on this level (geometric, in world coordinates, not simulation units!) - LbmFloat nodeSize; - //! node size on this level in simulation units - LbmFloat simCellSize; - //! quadtree node relaxation parameter - LbmFloat omega; - //! size this level was advanced to - LbmFloat time; - //! size of a single lbm step in time units on this level - LbmFloat timestep; - //! step count - int lsteps; - //! gravity force for this level - LbmVec gravity; - //! level array - LbmFloat *mprsCells[2]; - CellFlagType *mprsFlags[2]; - - //! smago params and precalculated values - LbmFloat lcsmago; - LbmFloat lcsmago_sqr; - LbmFloat lcnu; - - // LES statistics per level - double avgOmega; - double avgOmegaCnt; - - //! current set of dist funcs - int setCurr; - //! target/other set of dist funcs - int setOther; - - //! mass&volume for this level - LbmFloat lmass; - LbmFloat lvolume; - LbmFloat lcellfactor; - - //! local storage of mSizes - int lSizex, lSizey, lSizez; - int lOffsx, lOffsy, lOffsz; - -private: -#ifdef WITH_CXX_GUARDEDALLOC - MEM_CXX_CLASS_ALLOC_FUNCS("ELBEEM:FsgrLevelData") -#endif -}; - - - -/*****************************************************************************/ -/*! class for solving a LBM problem */ -class LbmFsgrSolver : - public LbmSolverInterface // this means, the solver is a lbmData object and implements the lbmInterface -{ - - public: - //! Constructor - LbmFsgrSolver(); - //! Destructor - virtual ~LbmFsgrSolver(); - - //! initilize variables fom attribute list - virtual void parseAttrList(); - //! Initialize omegas and forces on all levels (for init/timestep change) - void initLevelOmegas(); - - // multi step solver init - /*! finish the init with config file values (allocate arrays...) */ - virtual bool initializeSolverMemory(); - /*! init solver arrays */ - virtual bool initializeSolverGrids(); - /*! prepare actual simulation start, setup viz etc */ - virtual bool initializeSolverPostinit(); - - //! notify object that dump is in progress (e.g. for field dump) - virtual void notifySolverOfDump(int dumptype, int frameNr,char *frameNrStr,string outfilename); - -# if LBM_USE_GUI==1 - //! show simulation info (implement LbmSolverInterface pure virtual func) - virtual void debugDisplay(int set); -# endif - - // implement CellIterator<UniformFsgrCellIdentifier> interface - typedef UniformFsgrCellIdentifier stdCellId; - virtual CellIdentifierInterface* getFirstCell( ); - virtual void advanceCell( CellIdentifierInterface* ); - virtual bool noEndCell( CellIdentifierInterface* ); - virtual void deleteCellIterator( CellIdentifierInterface** ); - virtual CellIdentifierInterface* getCellAt( ntlVec3Gfx pos ); - virtual int getCellSet ( CellIdentifierInterface* ); - virtual ntlVec3Gfx getCellOrigin ( CellIdentifierInterface* ); - virtual ntlVec3Gfx getCellSize ( CellIdentifierInterface* ); - virtual int getCellLevel ( CellIdentifierInterface* ); - virtual LbmFloat getCellDensity ( CellIdentifierInterface* ,int set); - virtual LbmVec getCellVelocity ( CellIdentifierInterface* ,int set); - virtual LbmFloat getCellDf ( CellIdentifierInterface* ,int set, int dir); - virtual LbmFloat getCellMass ( CellIdentifierInterface* ,int set); - virtual LbmFloat getCellFill ( CellIdentifierInterface* ,int set); - virtual CellFlagType getCellFlag ( CellIdentifierInterface* ,int set); - virtual LbmFloat getEquilDf ( int ); - virtual ntlVec3Gfx getVelocityAt (float x, float y, float z); - // convert pointers - stdCellId* convertBaseCidToStdCid( CellIdentifierInterface* basecid); - - //! perform geometry init (if switched on) - bool initGeometryFlags(); - //! init part for all freesurface testcases - void initFreeSurfaces(); - //! init density gradient if enabled - void initStandingFluidGradient(); - - /*! init a given cell with flag, density, mass and equilibrium dist. funcs */ - LBM_INLINED void initEmptyCell(int level, int i,int j,int k, CellFlagType flag, LbmFloat rho, LbmFloat mass); - LBM_INLINED void initVelocityCell(int level, int i,int j,int k, CellFlagType flag, LbmFloat rho, LbmFloat mass, LbmVec vel); - LBM_INLINED void changeFlag(int level, int xx,int yy,int zz,int set,CellFlagType newflag); - LBM_INLINED void forceChangeFlag(int level, int xx,int yy,int zz,int set,CellFlagType newflag); - LBM_INLINED void initInterfaceVars(int level, int i,int j,int k,int workSet, bool initMass); - //! interpolate velocity and density at a given position - void interpolateCellValues(int level,int ei,int ej,int ek,int workSet, LbmFloat &retrho, LbmFloat &retux, LbmFloat &retuy, LbmFloat &retuz); - - /*! perform a single LBM step */ - void stepMain(); - //! advance fine grid - void fineAdvance(); - //! advance coarse grid - void coarseAdvance(int lev); - //! update flux area values on coarse grids - void coarseCalculateFluxareas(int lev); - // adaptively coarsen grid - bool adaptGrid(int lev); - // restrict fine grid DFs to coarse grid - void coarseRestrictFromFine(int lev); - - /* simulation object interface, just calls stepMain */ - virtual void step(); - /*! init particle positions */ - virtual int initParticles(); - /*! move all particles */ - virtual void advanceParticles(); - /*! move a particle at a boundary */ - void handleObstacleParticle(ParticleObject *p); - /*! check whether to add particle - bool checkAddParticle(); - void performAddParticle();*/ - - - /*! debug object display (used e.g. for preview surface) */ - virtual vector<ntlGeometryObject*> getDebugObjects(); - - // gui/output debugging functions -# if LBM_USE_GUI==1 - virtual void debugDisplayNode(int dispset, CellIdentifierInterface* cell ); - virtual void lbmDebugDisplay(int dispset); - virtual void lbmMarkedCellDisplay(); -# endif // LBM_USE_GUI==1 - virtual void debugPrintNodeInfo(CellIdentifierInterface* cell, int forceSet=-1); - - //! for raytracing, preprocess - void prepareVisualization( void ); - - /* surface generation settings */ - virtual void setSurfGenSettings(short value); - - protected: - - //! internal quick print function (for debugging) - void printLbmCell(int level, int i, int j, int k,int set); - // debugging use CellIterator interface to mark cell - void debugMarkCellCall(int level, int vi,int vj,int vk); - - // loop over grid, stream&collide update - void mainLoop(const int lev); - // change time step size - void adaptTimestep(); - //! init mObjectSpeeds for current parametrization - void recalculateObjectSpeeds(); - //! init moving obstacles for next sim step sim - void initMovingObstacles(bool staticInit); - //! flag reinit step - always works on finest grid! - void reinitFlags( int workSet ); - //! mass dist weights - LbmFloat getMassdWeight(bool dirForw, int i,int j,int k,int workSet, int l); - //! compute surface normals: fluid, fluid more accurate, and for obstacles - void computeFluidSurfaceNormal(LbmFloat *cell, CellFlagType *cellflag, LbmFloat *snret); - void computeFluidSurfaceNormalAcc(LbmFloat *cell, CellFlagType *cellflag, LbmFloat *snret); - void computeObstacleSurfaceNormal(LbmFloat *cell, CellFlagType *cellflag, LbmFloat *snret); - void computeObstacleSurfaceNormalAcc(int i,int j,int k, LbmFloat *snret); - //! add point to mListNewInter list - LBM_INLINED void addToNewInterList( int ni, int nj, int nk ); - //! cell is interpolated from coarse level (inited into set, source sets are determined by t) - void interpolateCellFromCoarse(int lev, int i, int j,int k, int dstSet, LbmFloat t, CellFlagType flagSet,bool markNbs); - void coarseRestrictCell(int lev, int i,int j,int k, int srcSet, int dstSet); - - //! minimal and maximal z-coords (for 2D/3D loops) - LBM_INLINED int getForZMinBnd(); - LBM_INLINED int getForZMin1(); - LBM_INLINED int getForZMaxBnd(int lev); - LBM_INLINED int getForZMax1(int lev); - LBM_INLINED bool checkDomainBounds(int lev,int i,int j,int k); - LBM_INLINED bool checkDomainBoundsPos(int lev,LbmVec pos); - - // touch grid and flags once - void preinitGrids(); - // one relaxation step for standing fluid - void standingFluidPreinit(); - - - // member vars - - //! mass calculated during streaming step - LbmFloat mCurrentMass; - LbmFloat mCurrentVolume; - LbmFloat mInitialMass; - - //! count problematic cases, that occured so far... - int mNumProblems; - - // average mlsups, count how many so far... - double mAvgMLSUPS; - double mAvgMLSUPSCnt; - - //! Mcubes object for surface reconstruction - IsoSurface *mpPreviewSurface; - - //! use time adaptivity? - bool mTimeAdap; - //! force smaller timestep for next LBM step? (eg for mov obj) - bool mForceTimeStepReduce; - - //! fluid vol height - LbmFloat mFVHeight; - LbmFloat mFVArea; - bool mUpdateFVHeight; - - //! force quit for gfx - LbmFloat mGfxEndTime; - //! smoother surface initialization? - int mInitSurfaceSmoothing; - //! surface generation settings, default is all off (=0) - // each flag switches side on off, fssgNoObs is for obstacle sides - // -1 equals all on - typedef enum { - fssgNormal = 0, - fssgNoNorth = 1, - fssgNoSouth = 2, - fssgNoEast = 4, - fssgNoWest = 8, - fssgNoTop = 16, - fssgNoBottom = 32, - fssgNoObs = 64 - } fsSurfaceGen; - int mFsSurfGenSetting; - - //! lock time step down switching - int mTimestepReduceLock; - //! count no. of switches - int mTimeSwitchCounts; - // only switch of maxvel is higher for several steps... - int mTimeMaxvelStepCnt; - - //! total simulation time so far - LbmFloat mSimulationTime, mLastSimTime; - //! smallest and largest step size so far - LbmFloat mMinTimestep, mMaxTimestep; - //! track max. velocity - LbmFloat mMxvx, mMxvy, mMxvz, mMaxVlen; - - //! list of the cells to empty at the end of the step - vector<LbmPoint> mListEmpty; - //! list of the cells to make fluid at the end of the step - vector<LbmPoint> mListFull; - //! list of new interface cells to init - vector<LbmPoint> mListNewInter; - //! class for handling redist weights in reinit flag function - class lbmFloatSet { - public: - LbmFloat val[dTotalNum]; - LbmFloat numNbs; - }; - //! normalized vectors for all neighboring cell directions (for e.g. massdweight calc) - LbmVec mDvecNrm[27]; - - - //! debugging - bool checkSymmetry(string idstring); - //! kepp track of max/min no. of filled cells - int mMaxNoCells, mMinNoCells; - LONGINT mAvgNumUsedCells; - - //! precalculated objects speeds for current parametrization - vector<LbmVec> mObjectSpeeds; - //! partslip bc. values for obstacle boundary conditions - vector<LbmFloat> mObjectPartslips; - //! moving object mass boundary condition values - vector<LbmFloat> mObjectMassMovnd; - - //! permanent movobj vert storage - vector<ntlVec3Gfx> mMOIVertices; - vector<ntlVec3Gfx> mMOIVerticesOld; - vector<ntlVec3Gfx> mMOINormals; - - //! get isofield weights - int mIsoWeightMethod; - float mIsoWeight[27]; - - // grid coarsening vars - - /*! vector for the data for each level */ - FsgrLevelData mLevel[FSGR_MAXNOOFLEVELS]; - - /*! minimal and maximal refinement levels */ - int mMaxRefine; - - /*! df scale factors for level up/down */ - LbmFloat mDfScaleUp, mDfScaleDown; - - /*! precomputed cell area values */ - LbmFloat mFsgrCellArea[27]; - /*! restriction interpolation weights */ - LbmFloat mGaussw[27]; - - /*! LES C_smago paramter for finest grid */ - float mInitialCsmago; - /*! LES stats for non OPT3D */ - LbmFloat mDebugOmegaRet; - /*! remember last init for animated params */ - LbmFloat mLastOmega; - LbmVec mLastGravity; - - //! fluid stats - int mNumInterdCells; - int mNumInvIfCells; - int mNumInvIfTotal; - int mNumFsgrChanges; - - //! debug function to disable standing f init - int mDisableStandingFluidInit; - //! init 2d with skipped Y/Z coords - bool mInit2dYZ; - //! debug function to force tadap syncing - int mForceTadapRefine; - //! border cutoff value - int mCutoff; - - // strict debug interface -# if FSGR_STRICT_DEBUG==1 - int debLBMGI(int level, int ii,int ij,int ik, int is); - CellFlagType& debRFLAG(int level, int xx,int yy,int zz,int set); - CellFlagType& debRFLAG_NB(int level, int xx,int yy,int zz,int set, int dir); - CellFlagType& debRFLAG_NBINV(int level, int xx,int yy,int zz,int set, int dir); - int debLBMQI(int level, int ii,int ij,int ik, int is, int l); - LbmFloat& debQCELL(int level, int xx,int yy,int zz,int set,int l); - LbmFloat& debQCELL_NB(int level, int xx,int yy,int zz,int set, int dir,int l); - LbmFloat& debQCELL_NBINV(int level, int xx,int yy,int zz,int set, int dir,int l); - LbmFloat* debRACPNT(int level, int ii,int ij,int ik, int is ); - LbmFloat& debRAC(LbmFloat* s,int l); -# endif // FSGR_STRICT_DEBUG==1 - - LbmControlData *mpControl; - - void initCpdata(); - void handleCpdata(); - void cpDebugDisplay(int dispset); - - bool mUseTestdata; -# if LBM_INCLUDE_TESTSOLVERS==1 - // test functions - LbmTestdata *mpTest; - void initTestdata(); - void destroyTestdata(); - void handleTestdata(); - void set3dHeight(int ,int ); - - int mMpNum,mMpIndex; - int mOrgSizeX; - LbmFloat mOrgStartX; - LbmFloat mOrgEndX; - void mrSetup(); - void mrExchange(); - void mrIsoExchange(); - LbmFloat mrInitTadap(LbmFloat max); - void gcFillBuffer( LbmGridConnector *gc, int *retSizeCnt, const int *bdfs); - void gcUnpackBuffer(LbmGridConnector *gc, int *retSizeCnt, const int *bdfs); - public: - // needed for testdata - void find3dHeight(int i,int j, LbmFloat prev, LbmFloat &ret, LbmFloat *retux, LbmFloat *retuy, LbmFloat *retuz); - // mptest - int getMpIndex() { return mMpIndex; }; -# endif // LBM_INCLUDE_TESTSOLVERS==1 - - // former LbmModelLBGK functions - // relaxation funtions - implemented together with relax macros - static inline LbmFloat getVelVecLen(int l, LbmFloat ux,LbmFloat uy,LbmFloat uz); - static inline LbmFloat getCollideEq(int l, LbmFloat rho, LbmFloat ux, LbmFloat uy, LbmFloat uz); - inline LbmFloat getLesNoneqTensorCoeff( LbmFloat df[], LbmFloat feq[] ); - inline LbmFloat getLesOmega(LbmFloat omega, LbmFloat csmago, LbmFloat Qo); - inline void collideArrays( int lev, int i, int j, int k, // position - more for debugging - LbmFloat df[], LbmFloat &outrho, // out only! - // velocity modifiers (returns actual velocity!) - LbmFloat &mux, LbmFloat &muy, LbmFloat &muz, - LbmFloat omega, LbmVec gravity, LbmFloat csmago, - LbmFloat *newOmegaRet, LbmFloat *newQoRet); - - - // former LBM models - //! shorten static const definitions -# define STCON static const - -# if LBMDIM==3 - - //! id string of solver - virtual string getIdString() { return string("FreeSurfaceFsgrSolver[BGK_D3Q19]"); } - - //! how many dimensions? UNUSED? replace by LBMDIM? - STCON int cDimension; - - // Wi factors for collide step - STCON LbmFloat cCollenZero; - STCON LbmFloat cCollenOne; - STCON LbmFloat cCollenSqrtTwo; - - //! threshold value for filled/emptied cells - STCON LbmFloat cMagicNr2; - STCON LbmFloat cMagicNr2Neg; - STCON LbmFloat cMagicNr; - STCON LbmFloat cMagicNrNeg; - - //! size of a single set of distribution functions - STCON int cDfNum; - //! direction vector contain vecs for all spatial dirs, even if not used for LBM model - STCON int cDirNum; - - //! distribution functions directions - typedef enum { - cDirInv= -1, - cDirC = 0, - cDirN = 1, - cDirS = 2, - cDirE = 3, - cDirW = 4, - cDirT = 5, - cDirB = 6, - cDirNE = 7, - cDirNW = 8, - cDirSE = 9, - cDirSW = 10, - cDirNT = 11, - cDirNB = 12, - cDirST = 13, - cDirSB = 14, - cDirET = 15, - cDirEB = 16, - cDirWT = 17, - cDirWB = 18 - } dfDir; - - /* Vector Order 3D: - * 0 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 - * 0, 0, 0, 1,-1, 0, 0, 1,-1, 1,-1, 0, 0, 0, 0, 1, 1,-1,-1, 1,-1, 1,-1, 1,-1, 1,-1 - * 0, 1,-1, 0, 0, 0, 0, 1, 1,-1,-1, 1, 1,-1,-1, 0, 0, 0, 0, 1, 1,-1,-1, 1, 1,-1,-1 - * 0, 0, 0, 0, 0, 1,-1, 0, 0, 0, 0, 1,-1, 1,-1, 1,-1, 1,-1, 1, 1, 1, 1, -1,-1,-1,-1 - */ - - /*! name of the dist. function - only for nicer output */ - STCON char* dfString[ 19 ]; - - /*! index of normal dist func, not used so far?... */ - STCON int dfNorm[ 19 ]; - - /*! index of inverse dist func, not fast, but useful... */ - STCON int dfInv[ 19 ]; - - /*! index of x reflected dist func for free slip, not valid for all DFs... */ - STCON int dfRefX[ 19 ]; - /*! index of x reflected dist func for free slip, not valid for all DFs... */ - STCON int dfRefY[ 19 ]; - /*! index of x reflected dist func for free slip, not valid for all DFs... */ - STCON int dfRefZ[ 19 ]; - - /*! dist func vectors */ - STCON int dfVecX[ 27 ]; - STCON int dfVecY[ 27 ]; - STCON int dfVecZ[ 27 ]; - - /*! arrays as before with doubles */ - STCON LbmFloat dfDvecX[ 27 ]; - STCON LbmFloat dfDvecY[ 27 ]; - STCON LbmFloat dfDvecZ[ 27 ]; - - /*! principal directions */ - STCON int princDirX[ 2*3 ]; - STCON int princDirY[ 2*3 ]; - STCON int princDirZ[ 2*3 ]; - - /*! vector lengths */ - STCON LbmFloat dfLength[ 19 ]; - - /*! equilibrium distribution functions, precalculated = getCollideEq(i, 0,0,0,0) */ - static LbmFloat dfEquil[ dTotalNum ]; - - /*! arrays for les model coefficients */ - static LbmFloat lesCoeffDiag[ (3-1)*(3-1) ][ 27 ]; - static LbmFloat lesCoeffOffdiag[ 3 ][ 27 ]; - -# else // end LBMDIM==3 , LBMDIM==2 - - //! id string of solver - virtual string getIdString() { return string("FreeSurfaceFsgrSolver[BGK_D2Q9]"); } - - //! how many dimensions? - STCON int cDimension; - - //! Wi factors for collide step - STCON LbmFloat cCollenZero; - STCON LbmFloat cCollenOne; - STCON LbmFloat cCollenSqrtTwo; - - //! threshold value for filled/emptied cells - STCON LbmFloat cMagicNr2; - STCON LbmFloat cMagicNr2Neg; - STCON LbmFloat cMagicNr; - STCON LbmFloat cMagicNrNeg; - - //! size of a single set of distribution functions - STCON int cDfNum; - STCON int cDirNum; - - //! distribution functions directions - typedef enum { - cDirInv= -1, - cDirC = 0, - cDirN = 1, - cDirS = 2, - cDirE = 3, - cDirW = 4, - cDirNE = 5, - cDirNW = 6, - cDirSE = 7, - cDirSW = 8 - } dfDir; - - /* Vector Order 2D: - * 0 1 2 3 4 5 6 7 8 - * 0, 0,0, 1,-1, 1,-1,1,-1 - * 0, 1,-1, 0,0, 1,1,-1,-1 */ - - /* name of the dist. function - only for nicer output */ - STCON char* dfString[ 9 ]; - - /* index of normal dist func, not used so far?... */ - STCON int dfNorm[ 9 ]; - - /* index of inverse dist func, not fast, but useful... */ - STCON int dfInv[ 9 ]; - - /* index of x reflected dist func for free slip, not valid for all DFs... */ - STCON int dfRefX[ 9 ]; - /* index of x reflected dist func for free slip, not valid for all DFs... */ - STCON int dfRefY[ 9 ]; - /* index of x reflected dist func for free slip, not valid for all DFs... */ - STCON int dfRefZ[ 9 ]; - - /* dist func vectors */ - STCON int dfVecX[ 9 ]; - STCON int dfVecY[ 9 ]; - /* Z, 2D values are all 0! */ - STCON int dfVecZ[ 9 ]; - - /* arrays as before with doubles */ - STCON LbmFloat dfDvecX[ 9 ]; - STCON LbmFloat dfDvecY[ 9 ]; - /* Z, 2D values are all 0! */ - STCON LbmFloat dfDvecZ[ 9 ]; - - /*! principal directions */ - STCON int princDirX[ 2*2 ]; - STCON int princDirY[ 2*2 ]; - STCON int princDirZ[ 2*2 ]; - - /* vector lengths */ - STCON LbmFloat dfLength[ 9 ]; - - /* equilibrium distribution functions, precalculated = getCollideEq(i, 0,0,0,0) */ - static LbmFloat dfEquil[ dTotalNum ]; - - /*! arrays for les model coefficients */ - static LbmFloat lesCoeffDiag[ (2-1)*(2-1) ][ 9 ]; - static LbmFloat lesCoeffOffdiag[ 2 ][ 9 ]; - -# endif // LBMDIM==2 - -private: -#ifdef WITH_CXX_GUARDEDALLOC - MEM_CXX_CLASS_ALLOC_FUNCS("ELBEEM:LbmFsgrSolver") -#endif -}; - -#undef STCON - - -/*****************************************************************************/ -// relaxation_macros - - - -// cell mark debugging -#if FSGR_STRICT_DEBUG==10 -#define debugMarkCell(lev,x,y,z) \ - errMsg("debugMarkCell",this->mName<<" step: "<<this->mStepCnt<<" lev:"<<(lev)<<" marking "<<PRINT_VEC((x),(y),(z))<<" line "<< __LINE__ ); \ - debugMarkCellCall((lev),(x),(y),(z)); -#else // FSGR_STRICT_DEBUG==1 -#define debugMarkCell(lev,x,y,z) \ - debugMarkCellCall((lev),(x),(y),(z)); -#endif // FSGR_STRICT_DEBUG==1 - - -// flag array defines ----------------------------------------------------------------------------------------------- - -// lbm testsolver get index define, note - ignores is (set) as flag -// array is only a single entry -#define _LBMGI(level, ii,ij,ik, is) ( (LONGINT)((LONGINT)mLevel[level].lOffsy*(LONGINT)(ik)) + ((LONGINT)mLevel[level].lOffsx*(LONGINT)(ij)) + (LONGINT)(ii) ) - -//! flag array acces macro -#define _RFLAG(level,xx,yy,zz,set) mLevel[level].mprsFlags[set][ (LONGINT)LBMGI((level),(xx),(yy),(zz),(set)) ] -#define _RFLAG_NB(level,xx,yy,zz,set, dir) mLevel[level].mprsFlags[set][ (LONGINT)LBMGI((level),(xx)+this->dfVecX[dir],(yy)+this->dfVecY[dir],(zz)+this->dfVecZ[dir],set) ] -#define _RFLAG_NBINV(level,xx,yy,zz,set, dir) mLevel[level].mprsFlags[set][ (LONGINT)LBMGI((level),(xx)+this->dfVecX[this->dfInv[dir]],(yy)+this->dfVecY[this->dfInv[dir]],(zz)+this->dfVecZ[this->dfInv[dir]],set) ] - -// array handling ----------------------------------------------------------------------------------------------- - -#define _LBMQI(level, ii,ij,ik, is, lunused) ( (LONGINT)((LONGINT)mLevel[level].lOffsy*(LONGINT)(ik)) + (LONGINT)((LONGINT)mLevel[level].lOffsx*(LONGINT)(ij)) + (LONGINT)(ii) ) -#define _QCELL(level,xx,yy,zz,set,l) (mLevel[level].mprsCells[(set)][ (LONGINT)LBMQI((level),(xx),(yy),(zz),(set), l)*(LONGINT)dTotalNum +(LONGINT)(l)]) -#define _QCELL_NB(level,xx,yy,zz,set, dir,l) (mLevel[level].mprsCells[(set)][ (LONGINT)LBMQI((level),(xx)+this->dfVecX[dir],(yy)+this->dfVecY[dir],(zz)+this->dfVecZ[dir],set, l)*dTotalNum +(l)]) -#define _QCELL_NBINV(level,xx,yy,zz,set, dir,l) (mLevel[level].mprsCells[(set)][ (LONGINT)LBMQI((level),(xx)+this->dfVecX[this->dfInv[dir]],(yy)+this->dfVecY[this->dfInv[dir]],(zz)+this->dfVecZ[this->dfInv[dir]],set, l)*dTotalNum +(l)]) - -#define QCELLSTEP dTotalNum -#define _RACPNT(level, ii,ij,ik, is ) &QCELL(level,ii,ij,ik,is,0) -#define _RAC(s,l) (s)[(l)] - - -#if FSGR_STRICT_DEBUG==1 - -#define LBMGI(level,ii,ij,ik, is) debLBMGI(level,ii,ij,ik, is) -#define RFLAG(level,xx,yy,zz,set) debRFLAG(level,xx,yy,zz,set) -#define RFLAG_NB(level,xx,yy,zz,set, dir) debRFLAG_NB(level,xx,yy,zz,set, dir) -#define RFLAG_NBINV(level,xx,yy,zz,set, dir) debRFLAG_NBINV(level,xx,yy,zz,set, dir) - -#define LBMQI(level,ii,ij,ik, is, l) debLBMQI(level,ii,ij,ik, is, l) -#define QCELL(level,xx,yy,zz,set,l) debQCELL(level,xx,yy,zz,set,l) -#define QCELL_NB(level,xx,yy,zz,set, dir,l) debQCELL_NB(level,xx,yy,zz,set, dir,l) -#define QCELL_NBINV(level,xx,yy,zz,set, dir,l) debQCELL_NBINV(level,xx,yy,zz,set, dir,l) -#define RACPNT(level, ii,ij,ik, is ) debRACPNT(level, ii,ij,ik, is ) -#define RAC(s,l) debRAC(s,l) - -#else // FSGR_STRICT_DEBUG==1 - -#define LBMGI(level,ii,ij,ik, is) _LBMGI(level,ii,ij,ik, is) -#define RFLAG(level,xx,yy,zz,set) _RFLAG(level,xx,yy,zz,set) -#define RFLAG_NB(level,xx,yy,zz,set, dir) _RFLAG_NB(level,xx,yy,zz,set, dir) -#define RFLAG_NBINV(level,xx,yy,zz,set, dir) _RFLAG_NBINV(level,xx,yy,zz,set, dir) - -#define LBMQI(level,ii,ij,ik, is, l) _LBMQI(level,ii,ij,ik, is, l) -#define QCELL(level,xx,yy,zz,set,l) _QCELL(level,xx,yy,zz,set,l) -#define QCELL_NB(level,xx,yy,zz,set, dir,l) _QCELL_NB(level,xx,yy,zz,set, dir, l) -#define QCELL_NBINV(level,xx,yy,zz,set, dir,l) _QCELL_NBINV(level,xx,yy,zz,set, dir,l) -#define RACPNT(level, ii,ij,ik, is ) _RACPNT(level, ii,ij,ik, is ) -#define RAC(s,l) _RAC(s,l) - -#endif // FSGR_STRICT_DEBUG==1 - -// general defines ----------------------------------------------------------------------------------------------- - -// replace TESTFLAG -#define FLAGISEXACT(flag, compflag) ((flag & compflag)==compflag) - -#if LBMDIM==2 -#define dC 0 -#define dN 1 -#define dS 2 -#define dE 3 -#define dW 4 -#define dNE 5 -#define dNW 6 -#define dSE 7 -#define dSW 8 -#else -// direction indices -#define dC 0 -#define dN 1 -#define dS 2 -#define dE 3 -#define dW 4 -#define dT 5 -#define dB 6 -#define dNE 7 -#define dNW 8 -#define dSE 9 -#define dSW 10 -#define dNT 11 -#define dNB 12 -#define dST 13 -#define dSB 14 -#define dET 15 -#define dEB 16 -#define dWT 17 -#define dWB 18 -#endif -//? #define dWB 18 - -// default init for dFlux values -#define FLUX_INIT 0.5f * (float)(this->cDfNum) - -// only for non DF dir handling! -#define dNET 19 -#define dNWT 20 -#define dSET 21 -#define dSWT 22 -#define dNEB 23 -#define dNWB 24 -#define dSEB 25 -#define dSWB 26 - -//! fill value for boundary cells -#define BND_FILL 0.0 - -#define DFL1 (1.0/ 3.0) -#define DFL2 (1.0/18.0) -#define DFL3 (1.0/36.0) - -// loops over _all_ cells (including boundary layer) -#define FSGR_FORIJK_BOUNDS(leveli) \ - for(int k= getForZMinBnd(); k< getForZMaxBnd(leveli); ++k) \ - for(int j=0;j<mLevel[leveli].lSizey-0;++j) \ - for(int i=0;i<mLevel[leveli].lSizex-0;++i) \ - -// loops over _only inner_ cells -#define FSGR_FORIJK1(leveli) \ - for(int k= getForZMin1(); k< getForZMax1(leveli); ++k) \ - for(int j=1;j<mLevel[leveli].lSizey-1;++j) \ - for(int i=1;i<mLevel[leveli].lSizex-1;++i) \ - -// relaxation_macros end - - - -/******************************************************************************/ -/*! equilibrium functions */ -/******************************************************************************/ - -/*! calculate length of velocity vector */ -inline LbmFloat LbmFsgrSolver::getVelVecLen(int l, LbmFloat ux,LbmFloat uy,LbmFloat uz) { - return ((ux)*dfDvecX[l]+(uy)*dfDvecY[l]+(uz)*dfDvecZ[l]); -}; - -/*! calculate equilibrium DF for given values */ -inline LbmFloat LbmFsgrSolver::getCollideEq(int l, LbmFloat rho, LbmFloat ux, LbmFloat uy, LbmFloat uz) { -#if FSGR_STRICT_DEBUG==1 - if((l<0)||(l>LBM_DFNUM)) { errFatal("LbmFsgrSolver::getCollideEq","Invalid DFEQ call "<<l, SIMWORLD_PANIC ); /* no access to mPanic here */ } -#endif // FSGR_STRICT_DEBUG==1 - LbmFloat tmp = getVelVecLen(l,ux,uy,uz); - return( dfLength[l] *( - + rho - (3.0/2.0*(ux*ux + uy*uy + uz*uz)) - + 3.0 *tmp - + 9.0/2.0 *(tmp*tmp) ) - ); // */ -}; - -/*****************************************************************************/ -/* init a given cell with flag, density, mass and equilibrium dist. funcs */ - -void LbmFsgrSolver::forceChangeFlag(int level, int xx,int yy,int zz,int set,CellFlagType newflag) { - // also overwrite persisting flags - // function is useful for tracking accesses... - RFLAG(level,xx,yy,zz,set) = newflag; -} -void LbmFsgrSolver::changeFlag(int level, int xx,int yy,int zz,int set,CellFlagType newflag) { - CellFlagType pers = RFLAG(level,xx,yy,zz,set) & CFPersistMask; - RFLAG(level,xx,yy,zz,set) = newflag | pers; -} - -void -LbmFsgrSolver::initEmptyCell(int level, int i,int j,int k, CellFlagType flag, LbmFloat rho, LbmFloat mass) { - /* init eq. dist funcs */ - LbmFloat *ecel; - int workSet = mLevel[level].setCurr; - - ecel = RACPNT(level, i,j,k, workSet); - FORDF0 { RAC(ecel, l) = this->dfEquil[l] * rho; } - RAC(ecel, dMass) = mass; - RAC(ecel, dFfrac) = mass/rho; - RAC(ecel, dFlux) = FLUX_INIT; - changeFlag(level, i,j,k, workSet, flag); - - workSet ^= 1; - changeFlag(level, i,j,k, workSet, flag); - return; -} - -void -LbmFsgrSolver::initVelocityCell(int level, int i,int j,int k, CellFlagType flag, LbmFloat rho, LbmFloat mass, LbmVec vel) { - LbmFloat *ecel; - int workSet = mLevel[level].setCurr; - - ecel = RACPNT(level, i,j,k, workSet); - FORDF0 { RAC(ecel, l) = getCollideEq(l, rho,vel[0],vel[1],vel[2]); } - RAC(ecel, dMass) = mass; - RAC(ecel, dFfrac) = mass/rho; - RAC(ecel, dFlux) = FLUX_INIT; - changeFlag(level, i,j,k, workSet, flag); - - workSet ^= 1; - changeFlag(level, i,j,k, workSet, flag); - return; -} - -int LbmFsgrSolver::getForZMinBnd() { - return 0; -} -int LbmFsgrSolver::getForZMin1() { - if(LBMDIM==2) return 0; - return 1; -} - -int LbmFsgrSolver::getForZMaxBnd(int lev) { - if(LBMDIM==2) return 1; - return mLevel[lev].lSizez -0; -} -int LbmFsgrSolver::getForZMax1(int lev) { - if(LBMDIM==2) return 1; - return mLevel[lev].lSizez -1; -} - -bool LbmFsgrSolver::checkDomainBounds(int lev,int i,int j,int k) { - if(i<0) return false; - if(j<0) return false; - if(k<0) return false; - if(i>mLevel[lev].lSizex-1) return false; - if(j>mLevel[lev].lSizey-1) return false; - if(k>mLevel[lev].lSizez-1) return false; - return true; -} -bool LbmFsgrSolver::checkDomainBoundsPos(int lev,LbmVec pos) { - const int i= (int)pos[0]; - if(i<0) return false; - if(i>mLevel[lev].lSizex-1) return false; - const int j= (int)pos[1]; - if(j<0) return false; - if(j>mLevel[lev].lSizey-1) return false; - const int k= (int)pos[2]; - if(k<0) return false; - if(k>mLevel[lev].lSizez-1) return false; - return true; -} - -void LbmFsgrSolver::initInterfaceVars(int level, int i,int j,int k,int workSet, bool initMass) { - LbmFloat *ccel = &QCELL(level ,i,j,k, workSet,0); - LbmFloat nrho = 0.0; - FORDF0 { nrho += RAC(ccel,l); } - if(initMass) { - RAC(ccel,dMass) = nrho; - RAC(ccel, dFfrac) = 1.; - } else { - // preinited, e.g. from reinitFlags - RAC(ccel, dFfrac) = RAC(ccel, dMass)/nrho; - RAC(ccel, dFlux) = FLUX_INIT; - } -} - - -#endif - - diff --git a/intern/elbeem/intern/solver_control.cpp b/intern/elbeem/intern/solver_control.cpp deleted file mode 100644 index 7064dba8e22..00000000000 --- a/intern/elbeem/intern/solver_control.cpp +++ /dev/null @@ -1,876 +0,0 @@ -/** \file - * \ingroup elbeem - */ -/****************************************************************************** - * - * El'Beem - the visual lattice boltzmann freesurface simulator - * All code distributed as part of El'Beem is covered by the version 2 of the - * GNU General Public License. See the file COPYING for details. - * - * Copyright 2003-2008 Nils Thuerey - * - * control extensions - * - *****************************************************************************/ -#include "solver_class.h" -#include "solver_relax.h" -#include "particletracer.h" - -#include "solver_control.h" - -#include "controlparticles.h" - -#include "elbeem.h" - -#include "ntl_geometrymodel.h" - -/****************************************************************************** - * LbmControlData control set - *****************************************************************************/ - -LbmControlSet::LbmControlSet() : - mCparts(NULL), mCpmotion(NULL), mContrPartFile(""), mCpmotionFile(""), - mcForceAtt(0.), mcForceVel(0.), mcForceMaxd(0.), - mcRadiusAtt(0.), mcRadiusVel(0.), mcRadiusMind(0.), mcRadiusMaxd(0.), - mcCpScale(1.), mcCpOffset(0.) -{ -} -LbmControlSet::~LbmControlSet() { - if(mCparts) delete mCparts; - if(mCpmotion) delete mCpmotion; -} -void LbmControlSet::initCparts() { - mCparts = new ControlParticles(); - mCpmotion = new ControlParticles(); -} - - - -/****************************************************************************** - * LbmControlData control - *****************************************************************************/ - -LbmControlData::LbmControlData() : - mSetForceStrength(0.), - mCons(), - mCpUpdateInterval(8), // DG: was 16 --> causes problems (big sphere after some time), unstable - mCpOutfile(""), - mCpForces(), mCpKernel(), mMdKernel(), - mDiffVelCon(1.), - mDebugCpscale(0.), - mDebugVelScale(0.), - mDebugCompavScale(0.), - mDebugAttScale(0.), - mDebugMaxdScale(0.), - mDebugAvgVelScale(0.) -{ -} - -LbmControlData::~LbmControlData() -{ - while (!mCons.empty()) { - delete mCons.back(); mCons.pop_back(); - } -} - - -void LbmControlData::parseControldataAttrList(AttributeList *attr) { - // controlpart vars - mSetForceStrength = attr->readFloat("tforcestrength", mSetForceStrength,"LbmControlData", "mSetForceStrength", false); - //errMsg("tforcestrength set to "," "<<mSetForceStrength); - mCpUpdateInterval = attr->readInt("controlparticle_updateinterval", mCpUpdateInterval,"LbmControlData","mCpUpdateInterval", false); - // tracer output file - mCpOutfile = attr->readString("controlparticle_outfile",mCpOutfile,"LbmControlData","mCpOutfile", false); - if(getenv("ELBEEM_CPOUTFILE")) { - string outfile(getenv("ELBEEM_CPOUTFILE")); - mCpOutfile = outfile; - debMsgStd("LbmControlData::parseAttrList",DM_NOTIFY,"Using envvar ELBEEM_CPOUTFILE to set mCpOutfile to "<<outfile<<","<<mCpOutfile,7); - } - - for(int cpii=0; cpii<10; cpii++) { - string suffix(""); - //if(cpii>0) - { suffix = string("0"); suffix[0]+=cpii; } - LbmControlSet *cset; - cset = new LbmControlSet(); - cset->initCparts(); - - cset->mContrPartFile = attr->readString("controlparticle"+suffix+"_file",cset->mContrPartFile,"LbmControlData","cset->mContrPartFile", false); - if((cpii==0) && (getenv("ELBEEM_CPINFILE")) ) { - string infile(getenv("ELBEEM_CPINFILE")); - cset->mContrPartFile = infile; - debMsgStd("LbmControlData::parseAttrList",DM_NOTIFY,"Using envvar ELBEEM_CPINFILE to set mContrPartFile to "<<infile<<","<<cset->mContrPartFile,7); - } - - LbmFloat cpvort=0.; - cset->mcRadiusAtt = attr->readChannelSinglePrecFloat("controlparticle"+suffix+"_radiusatt", 0., "LbmControlData","mcRadiusAtt" ); - cset->mcRadiusVel = attr->readChannelSinglePrecFloat("controlparticle"+suffix+"_radiusvel", 0., "LbmControlData","mcRadiusVel" ); - cset->mcRadiusVel = attr->readChannelSinglePrecFloat("controlparticle"+suffix+"_radiusvel", 0., "LbmControlData","mcRadiusVel" ); - cset->mCparts->setRadiusAtt(cset->mcRadiusAtt.get(0.)); - cset->mCparts->setRadiusVel(cset->mcRadiusVel.get(0.)); - - // WARNING currently only for first set - //if(cpii==0) { - cset->mcForceAtt = attr->readChannelSinglePrecFloat("controlparticle"+suffix+"_attraction", 0. , "LbmControlData","cset->mcForceAtt", false); - cset->mcForceVel = attr->readChannelSinglePrecFloat("controlparticle"+suffix+"_velocity", 0. , "LbmControlData","mcForceVel", false); - cset->mcForceMaxd = attr->readChannelSinglePrecFloat("controlparticle"+suffix+"_maxdist", 0. , "LbmControlData","mcForceMaxd", false); - cset->mCparts->setInfluenceAttraction(cset->mcForceAtt.get(0.) ); - // warning - stores temprorarily, value converted to dt dep. factor - cset->mCparts->setInfluenceVelocity(cset->mcForceVel.get(0.) , 0.01 ); // dummy dt - cset->mCparts->setInfluenceMaxdist(cset->mcForceMaxd.get(0.) ); - cpvort = attr->readFloat("controlparticle"+suffix+"_vorticity", cpvort, "LbmControlData","cpvort", false); - cset->mCparts->setInfluenceTangential(cpvort); - - cset->mcRadiusMind = attr->readChannelSinglePrecFloat("controlparticle"+suffix+"_radiusmin", cset->mcRadiusMind.get(0.), "LbmControlData","mcRadiusMind", false); - cset->mcRadiusMaxd = attr->readChannelSinglePrecFloat("controlparticle"+suffix+"_radiusmax", cset->mcRadiusMind.get(0.), "LbmControlData","mcRadiusMaxd", false); - cset->mCparts->setRadiusMinMaxd(cset->mcRadiusMind.get(0.)); - cset->mCparts->setRadiusMaxd(cset->mcRadiusMaxd.get(0.)); - //} - - // now local... - //LbmVec cpOffset(0.), cpScale(1.); - LbmFloat cpTimescale = 1.; - string cpMirroring(""); - - //cset->mcCpOffset = attr->readChannelVec3f("controlparticle"+suffix+"_offset", ntlVec3f(0.),"LbmControlData","mcCpOffset", false); - //cset->mcCpScale = attr->readChannelVec3f("controlparticle"+suffix+"_scale", ntlVec3f(1.), "LbmControlData","mcCpScale", false); - cset->mcCpOffset = attr->readChannelVec3f("controlparticle"+suffix+"_offset", ntlVec3f(0.),"LbmControlData","mcCpOffset", false); - cset->mcCpScale = attr->readChannelVec3f("controlparticle"+suffix+"_scale", ntlVec3f(1.), "LbmControlData","mcCpScale", false); - cpTimescale = attr->readFloat("controlparticle"+suffix+"_timescale", cpTimescale, "LbmControlData","cpTimescale", false); - cpMirroring = attr->readString("controlparticle"+suffix+"_mirror", cpMirroring, "LbmControlData","cpMirroring", false); - - LbmFloat cpsWidth = cset->mCparts->getCPSWith(); - cpsWidth = attr->readFloat("controlparticle"+suffix+"_cpswidth", cpsWidth, "LbmControlData","cpsWidth", false); - LbmFloat cpsDt = cset->mCparts->getCPSTimestep(); - cpsDt = attr->readFloat("controlparticle"+suffix+"_cpstimestep", cpsDt, "LbmControlData","cpsDt", false); - LbmFloat cpsTstart = cset->mCparts->getCPSTimeStart(); - cpsTstart = attr->readFloat("controlparticle"+suffix+"_cpststart", cpsTstart, "LbmControlData","cpsTstart", false); - LbmFloat cpsTend = cset->mCparts->getCPSTimeEnd(); - cpsTend = attr->readFloat("controlparticle"+suffix+"_cpstend", cpsTend, "LbmControlData","cpsTend", false); - LbmFloat cpsMvmfac = cset->mCparts->getCPSMvmWeightFac(); - cpsMvmfac = attr->readFloat("controlparticle"+suffix+"_cpsmvmfac", cpsMvmfac, "LbmControlData","cpsMvmfac", false); - cset->mCparts->setCPSWith(cpsWidth); - cset->mCparts->setCPSTimestep(cpsDt); - cset->mCparts->setCPSTimeStart(cpsTstart); - cset->mCparts->setCPSTimeEnd(cpsTend); - cset->mCparts->setCPSMvmWeightFac(cpsMvmfac); - - cset->mCparts->setOffset( vec2L(cset->mcCpOffset.get(0.)) ); - cset->mCparts->setScale( vec2L(cset->mcCpScale.get(0.)) ); - cset->mCparts->setInitTimeScale( cpTimescale ); - cset->mCparts->setInitMirror( cpMirroring ); - - int mDebugInit = 0; - mDebugInit = attr->readInt("controlparticle"+suffix+"_debuginit", mDebugInit,"LbmControlData","mDebugInit", false); - cset->mCparts->setDebugInit(mDebugInit); - - // motion particle settings - LbmVec mcpOffset(0.), mcpScale(1.); - LbmFloat mcpTimescale = 1.; - string mcpMirroring(""); - - cset->mCpmotionFile = attr->readString("cpmotion"+suffix+"_file",cset->mCpmotionFile,"LbmControlData","mCpmotionFile", false); - mcpTimescale = attr->readFloat("cpmotion"+suffix+"_timescale", mcpTimescale, "LbmControlData","mcpTimescale", false); - mcpMirroring = attr->readString("cpmotion"+suffix+"_mirror", mcpMirroring, "LbmControlData","mcpMirroring", false); - mcpOffset = vec2L( attr->readVec3d("cpmotion"+suffix+"_offset", vec2P(mcpOffset),"LbmControlData","cpOffset", false) ); - mcpScale = vec2L( attr->readVec3d("cpmotion"+suffix+"_scale", vec2P(mcpScale), "LbmControlData","cpScale", false) ); - - cset->mCpmotion->setOffset( vec2L(mcpOffset) ); - cset->mCpmotion->setScale( vec2L(mcpScale) ); - cset->mCpmotion->setInitTimeScale( mcpTimescale ); - cset->mCpmotion->setInitMirror( mcpMirroring ); - - if(cset->mContrPartFile.length()>1) { - errMsg("LbmControlData","Using control particle set "<<cpii<<" file:"<<cset->mContrPartFile<<" cpmfile:"<<cset->mCpmotionFile<<" mirr:'"<<cset->mCpmotion->getInitMirror()<<"' " ); - mCons.push_back( cset ); - } else { - delete cset; - } - } - - // debug, testing - make sure theres at least an empty set - if(mCons.size()<1) { - mCons.push_back( new LbmControlSet() ); - mCons[0]->initCparts(); - } - - // take from first set - for(int cpii=1; cpii<(int)mCons.size(); cpii++) { - mCons[cpii]->mCparts->setRadiusMinMaxd( mCons[0]->mCparts->getRadiusMinMaxd() ); - mCons[cpii]->mCparts->setRadiusMaxd( mCons[0]->mCparts->getRadiusMaxd() ); - mCons[cpii]->mCparts->setInfluenceAttraction( mCons[0]->mCparts->getInfluenceAttraction() ); - mCons[cpii]->mCparts->setInfluenceTangential( mCons[0]->mCparts->getInfluenceTangential() ); - mCons[cpii]->mCparts->setInfluenceVelocity( mCons[0]->mCparts->getInfluenceVelocity() , 0.01 ); // dummy dt - mCons[cpii]->mCparts->setInfluenceMaxdist( mCons[0]->mCparts->getInfluenceMaxdist() ); - } - - // invert for usage in relax macro - mDiffVelCon = 1.-attr->readFloat("cpdiffvelcon", mDiffVelCon, "LbmControlData","mDiffVelCon", false); - - mDebugCpscale = attr->readFloat("cpdebug_cpscale", mDebugCpscale, "LbmControlData","mDebugCpscale", false); - mDebugMaxdScale = attr->readFloat("cpdebug_maxdscale", mDebugMaxdScale, "LbmControlData","mDebugMaxdScale", false); - mDebugAttScale = attr->readFloat("cpdebug_attscale", mDebugAttScale, "LbmControlData","mDebugAttScale", false); - mDebugVelScale = attr->readFloat("cpdebug_velscale", mDebugVelScale, "LbmControlData","mDebugVelScale", false); - mDebugCompavScale = attr->readFloat("cpdebug_compavscale", mDebugCompavScale, "LbmControlData","mDebugCompavScale", false); - mDebugAvgVelScale = attr->readFloat("cpdebug_avgvelsc", mDebugAvgVelScale, "LbmControlData","mDebugAvgVelScale", false); -} - - -void -LbmFsgrSolver::initCpdata() -{ - // enable for cps via env. vars - //if( (getenv("ELBEEM_CPINFILE")) || (getenv("ELBEEM_CPOUTFILE")) ){ mUseTestdata=1; } - - - // manually switch on! if this is zero, nothing is done... - mpControl->mSetForceStrength = this->mTForceStrength = 1.; - while (!mpControl->mCons.empty()) { - delete mpControl->mCons.back(); mpControl->mCons.pop_back(); - } - - - // init all control fluid objects - int numobjs = (int)(mpGiObjects->size()); - for(int o=0; o<numobjs; o++) { - ntlGeometryObjModel *obj = (ntlGeometryObjModel *)(*mpGiObjects)[o]; - if(obj->getGeoInitType() & FGI_CONTROL) { - // add new control set per object - LbmControlSet *cset; - - cset = new LbmControlSet(); - cset->initCparts(); - - // dont load any file - cset->mContrPartFile = string(""); - - cset->mcForceAtt = obj->getCpsAttrFStr(); - cset->mcRadiusAtt = obj->getCpsAttrFRad(); - cset->mcForceVel = obj->getCpsVelFStr(); - cset->mcRadiusVel = obj->getCpsVelFRad(); - - cset->mCparts->setCPSTimeStart(obj->getCpsTimeStart()); - cset->mCparts->setCPSTimeEnd(obj->getCpsTimeEnd()); - - if(obj->getCpsQuality() > LBM_EPSILON) - cset->mCparts->setCPSWith(1.0 / obj->getCpsQuality()); - - // this value can be left at 0.5: - cset->mCparts->setCPSMvmWeightFac(0.5); - - mpControl->mCons.push_back( cset ); - mpControl->mCons[mpControl->mCons.size()-1]->mCparts->initFromObject(obj); - } - } - - // NT blender integration manual test setup - if(0) { - // manually switch on! if this is zero, nothing is done... - mpControl->mSetForceStrength = this->mTForceStrength = 1.; - while (!mpControl->mCons.empty()) { - delete mpControl->mCons.back(); mpControl->mCons.pop_back(); - } - - // add new set - LbmControlSet *cset; - - cset = new LbmControlSet(); - cset->initCparts(); - // dont load any file - cset->mContrPartFile = string(""); - - // set radii for attraction & velocity forces - // set strength of the forces - // don't set directly! but use channels: - // mcForceAtt, mcForceVel, mcForceMaxd, mcRadiusAtt, mcRadiusVel, mcRadiusMind, mcRadiusMaxd etc. - - // wrong: cset->mCparts->setInfluenceAttraction(1.15); cset->mCparts->setRadiusAtt(1.5); - // right, e.g., to init some constant values: - cset->mcForceAtt = AnimChannel<float>(0.2); - cset->mcRadiusAtt = AnimChannel<float>(0.75); - cset->mcForceVel = AnimChannel<float>(0.2); - cset->mcRadiusVel = AnimChannel<float>(0.75); - - // this value can be left at 0.5: - cset->mCparts->setCPSMvmWeightFac(0.5); - - mpControl->mCons.push_back( cset ); - - // instead of reading from file (cset->mContrPartFile), manually init some particles - mpControl->mCons[0]->mCparts->initBlenderTest(); - - // other values that might be interesting to change: - //cset->mCparts->setCPSTimestep(0.02); - //cset->mCparts->setCPSTimeStart(0.); - //cset->mCparts->setCPSTimeEnd(1.); - - //mpControl->mDiffVelCon = 1.; // more rigid velocity control, 0 (default) allows more turbulence - } - - // control particle ------------------------------------------------------------------------------------- - - // init cppf stage, use set 0! - if(mCppfStage>0) { - if(mpControl->mCpOutfile.length()<1) mpControl->mCpOutfile = string("cpout"); // use getOutFilename !? - char strbuf[100]; - const char *cpFormat = "_d%dcppf%d"; - - // initial coarse stage, no input - if(mCppfStage==1) { - mpControl->mCons[0]->mContrPartFile = ""; - } else { - // read from prev stage - snprintf(strbuf,100, cpFormat ,LBMDIM,mCppfStage-1); - mpControl->mCons[0]->mContrPartFile = mpControl->mCpOutfile; - mpControl->mCons[0]->mContrPartFile += strbuf; - mpControl->mCons[0]->mContrPartFile += ".cpart2"; - } - - snprintf(strbuf,100, cpFormat ,LBMDIM,mCppfStage); - mpControl->mCpOutfile += strbuf; - } // */ - - for(int cpssi=0; cpssi<(int)mpControl->mCons.size(); cpssi++) { - ControlParticles *cparts = mpControl->mCons[cpssi]->mCparts; - ControlParticles *cpmotion = mpControl->mCons[cpssi]->mCpmotion; - - // now set with real dt - cparts->setInfluenceVelocity( mpControl->mCons[cpssi]->mcForceVel.get(0.), mLevel[mMaxRefine].timestep); - cparts->setCharLength( mLevel[mMaxRefine].nodeSize ); - cparts->setCharLength( mLevel[mMaxRefine].nodeSize ); - errMsg("LbmControlData","CppfStage "<<mCppfStage<<" in:"<<mpControl->mCons[cpssi]->mContrPartFile<< - " out:"<<mpControl->mCpOutfile<<" cl:"<< cparts->getCharLength() ); - - // control particle test init - if(mpControl->mCons[cpssi]->mCpmotionFile.length()>=1) cpmotion->initFromTextFile(mpControl->mCons[cpssi]->mCpmotionFile); - // not really necessary... - //? cparts->setFluidSpacing( mLevel[mMaxRefine].nodeSize ); // use grid coords!? - //? cparts->calculateKernelWeight(); - //? debMsgStd("LbmFsgrSolver::initCpdata",DM_MSG,"ControlParticles - motion inited: "<<cparts->getSize() ,10); - - // ensure both are on for env. var settings - // when no particles, but outfile enabled, initialize - const int lev = mMaxRefine; - if((mpParticles) && (mpControl->mCpOutfile.length()>=1) && (cpssi==0)) { - // check if auto num - if( (mpParticles->getNumInitialParticles()<=1) && - (mpParticles->getNumParticles()<=1) ) { // initParticles done afterwards anyway - int tracers = 0; - const int workSet = mLevel[lev].setCurr; - FSGR_FORIJK_BOUNDS(lev) { - if(RFLAG(lev,i,j,k, workSet)&(CFFluid)) tracers++; - } - if(LBMDIM==3) tracers /= 8; - else tracers /= 4; - mpParticles->setNumInitialParticles(tracers); - mpParticles->setDumpTextFile(mpControl->mCpOutfile); - debMsgStd("LbmFsgrSolver::initCpdata",DM_MSG,"ControlParticles - set tracers #"<<tracers<<", actual #"<<mpParticles->getNumParticles() ,10); - } - if(mpParticles->getDumpTextInterval()<=0.) { - mpParticles->setDumpTextInterval(mLevel[lev].timestep * mLevel[lev].lSizex); - debMsgStd("LbmFsgrSolver::initCpdata",DM_MSG,"ControlParticles - dump delta t not set, using dti="<< mpParticles->getDumpTextInterval()<<", sim dt="<<mLevel[lev].timestep, 5 ); - } - mpParticles->setDumpParts(true); // DEBUG? also dump as particle system - } - - if(mpControl->mCons[cpssi]->mContrPartFile.length()>=1) cparts->initFromTextFile(mpControl->mCons[cpssi]->mContrPartFile); - cparts->setFluidSpacing( mLevel[lev].nodeSize ); // use grid coords!? - cparts->calculateKernelWeight(); - debMsgStd("LbmFsgrSolver::initCpdata",DM_MSG,"ControlParticles mCons"<<cpssi<<" - inited, parts:"<<cparts->getTotalSize()<<","<<cparts->getSize()<<" dt:"<<mpParam->getTimestep()<<" control time:"<<cparts->getControlTimStart()<<" to "<<cparts->getControlTimEnd() ,10); - } // cpssi - - if(getenv("ELBEEM_CPINFILE")) { - this->mTForceStrength = 1.0; - } - this->mTForceStrength = mpControl->mSetForceStrength; - if(mpControl->mCpOutfile.length()>=1) mpParticles->setDumpTextFile(mpControl->mCpOutfile); - - // control particle init end ------------------------------------------------------------------------------------- - - // make sure equiv to solver init - if(this->mTForceStrength>0.) { \ - mpControl->mCpForces.resize( mMaxRefine+1 ); - for(int lev = 0; lev<=mMaxRefine; lev++) { - LONGINT rcellSize = (mLevel[lev].lSizex*mLevel[lev].lSizey*mLevel[lev].lSizez); - debMsgStd("LbmFsgrSolver::initControl",DM_MSG,"mCpForces init, lev="<<lev<<" rcs:"<<(int)(rcellSize+4)<<","<<(rcellSize*sizeof(ControlForces)/(1024*1024)), 9 ); - mpControl->mCpForces[lev].resize( (int)(rcellSize+4) ); - //for(int i=0 ;i<rcellSize; i++) mpControl->mCpForces.push_back( ControlForces() ); - for(int i=0 ;i<rcellSize; i++) mpControl->mCpForces[lev][i].resetForces(); - } - } // on? - - debMsgStd("LbmFsgrSolver::initCpdata",DM_MSG,"ControlParticles #mCons "<<mpControl->mCons.size()<<" done", 6); -} - - -#define CPODEBUG 0 -//define CPINTER ((int)(mpControl->mCpUpdateInterval)) - -#define KERN(x,y,z) mpControl->mCpKernel[ (((z)*cpkarWidth + (y))*cpkarWidth + (x)) ] -#define MDKERN(x,y,z) mpControl->mMdKernel[ (((z)*mdkarWidth + (y))*mdkarWidth + (x)) ] - -#define BOUNDCHECK(x,low,high) ( ((x)<low) ? low : (((x)>high) ? high : (x) ) ) -#define BOUNDSKIP(x,low,high) ( ((x)<low) || ((x)>high) ) - -void -LbmFsgrSolver::handleCpdata() -{ - myTime_t cpstart = getTime(); - int cpChecks=0; - int cpInfs=0; - //debMsgStd("ControlData::handleCpdata",DM_MSG,"called... "<<this->mTForceStrength,1); - - // add cp influence - if((true) && (this->mTForceStrength>0.)) { - // ok continue... - } // on off - else { - return; - } - - // check if we have control objects - if(mpControl->mCons.size()==0) - return; - - if((mpControl->mCpUpdateInterval<1) || (this->mStepCnt%mpControl->mCpUpdateInterval==0)) { - // do full reinit later on... - } - else if(this->mStepCnt>mpControl->mCpUpdateInterval) { - // only reinit new cells - // TODO !? remove loop dependance!? -#define NOFORCEENTRY(lev, i,j,k) (LBMGET_FORCE(lev, i,j,k).maxDistance==CPF_MAXDINIT) - // interpolate missing - for(int lev=0; lev<=mMaxRefine; lev++) { - FSGR_FORIJK_BOUNDS(lev) { - if( (RFLAG(lev,i,j,k, mLevel[lev].setCurr)) & (CFFluid|CFInter) ) - //if( (RFLAG(lev,i,j,k, mLevel[lev].setCurr)) & (CFInter) ) - //if(0) - { // only check new inter? RFLAG?check - if(NOFORCEENTRY(lev, i,j,k)) { - //errMsg("CP","FE_MISSING at "<<PRINT_IJK<<" f"<<LBMGET_FORCE(lev, i,j,k).weightAtt<<" md"<<LBMGET_FORCE(lev, i,j,k).maxDistance ); - - LbmFloat nbs=0.; - ControlForces vals; - vals.resetForces(); vals.maxDistance = 0.; - for(int l=1; l<this->cDirNum; l++) { - int ni=i+this->dfVecX[l], nj=j+this->dfVecY[l], nk=k+this->dfVecZ[l]; - //errMsg("CP","FE_MISSING check "<<PRINT_VEC(ni,nj,nk)<<" f"<<LBMGET_FORCE(lev, ni,nj,nk).weightAtt<<" md"<<LBMGET_FORCE(lev, ni,nj,nk).maxDistance ); - if(!NOFORCEENTRY(lev, ni,nj,nk)) { - //? vals.weightAtt += LBMGET_FORCE(lev, ni,nj,nk).weightAtt; - //? vals.forceAtt += LBMGET_FORCE(lev, ni,nj,nk).forceAtt; - vals.maxDistance += LBMGET_FORCE(lev, ni,nj,nk).maxDistance; - vals.forceMaxd += LBMGET_FORCE(lev, ni,nj,nk).forceMaxd; - vals.weightVel += LBMGET_FORCE(lev, ni,nj,nk).weightVel; - vals.forceVel += LBMGET_FORCE(lev, ni,nj,nk).forceVel; - // ignore att/compAv/avgVel here for now - nbs += 1.; - } - } - if(nbs>0.) { - nbs = 1./nbs; - //? LBMGET_FORCE(lev, i,j,k).weightAtt = vals.weightAtt*nbs; - //? LBMGET_FORCE(lev, i,j,k).forceAtt = vals.forceAtt*nbs; - LBMGET_FORCE(lev, i,j,k).maxDistance = vals.maxDistance*nbs; - LBMGET_FORCE(lev, i,j,k).forceMaxd = vals.forceMaxd*nbs; - LBMGET_FORCE(lev, i,j,k).weightVel = vals.weightVel*nbs; - LBMGET_FORCE(lev, i,j,k).forceVel = vals.forceVel*nbs; - } - /*ControlForces *ff = &LBMGET_FORCE(lev, i,j,k); // DEBUG - errMsg("CP","FE_MISSING rec at "<<PRINT_IJK // DEBUG - <<" w:"<<ff->weightAtt<<" wa:" <<PRINT_VEC( ff->forceAtt[0],ff->forceAtt[1],ff->forceAtt[2] ) - <<" v:"<<ff->weightVel<<" wv:" <<PRINT_VEC( ff->forceVel[0],ff->forceVel[1],ff->forceVel[2] ) - <<" v:"<<ff->maxDistance<<" wv:" <<PRINT_VEC( ff->forceMaxd[0],ff->forceMaxd[1],ff->forceMaxd[2] ) ); // DEBUG */ - // else errMsg("CP","FE_MISSING rec at "<<PRINT_IJK<<" failed!"); // DEBUG - - } - } - }} // ijk, lev - - // mStepCnt > mpControl->mCpUpdateInterval - return; - } else { - // nothing to do ... - return; - } - - // reset - for(int lev=0; lev<=mMaxRefine; lev++) { - FSGR_FORIJK_BOUNDS(lev) { LBMGET_FORCE(lev,i,j,k).resetForces(); } - } - // do setup for coarsest level - const int coarseLev = 0; - const int fineLev = mMaxRefine; - - // init for current time - for(int cpssi=0; cpssi<(int)mpControl->mCons.size(); cpssi++) { - ControlParticles *cparts = mpControl->mCons[cpssi]->mCparts; - LbmControlSet *cset = mpControl->mCons[cpssi]; - - cparts->setRadiusAtt(cset->mcRadiusAtt.get(mSimulationTime)); - cparts->setRadiusVel(cset->mcRadiusVel.get(mSimulationTime)); - cparts->setInfluenceAttraction(cset->mcForceAtt.get(mSimulationTime) ); - cparts->setInfluenceMaxdist(cset->mcForceMaxd.get(mSimulationTime) ); - cparts->setRadiusMinMaxd(cset->mcRadiusMind.get(mSimulationTime)); - cparts->setRadiusMaxd(cset->mcRadiusMaxd.get(mSimulationTime)); - cparts->calculateKernelWeight(); // always necessary!? - cparts->setOffset( vec2L(cset->mcCpOffset.get(mSimulationTime)) ); - cparts->setScale( vec2L(cset->mcCpScale.get(mSimulationTime)) ); - - cparts->setInfluenceVelocity( cset->mcForceVel.get(mSimulationTime), mLevel[fineLev].timestep ); - cparts->setLastOffset( vec2L(cset->mcCpOffset.get(mSimulationTime-mLevel[fineLev].timestep)) ); - cparts->setLastScale( vec2L(cset->mcCpScale.get(mSimulationTime-mLevel[fineLev].timestep)) ); - - } - - // check actual values - LbmFloat iatt = ABS(mpControl->mCons[0]->mCparts->getInfluenceAttraction()); - LbmFloat ivel = mpControl->mCons[0]->mCparts->getInfluenceVelocity(); - LbmFloat imaxd = mpControl->mCons[0]->mCparts->getInfluenceMaxdist(); - //errMsg("FINCIT","iatt="<<iatt<<" ivel="<<ivel<<" imaxd="<<imaxd); - for(int cpssi=1; cpssi<(int)mpControl->mCons.size(); cpssi++) { - LbmFloat iatt2 = ABS(mpControl->mCons[cpssi]->mCparts->getInfluenceAttraction()); - LbmFloat ivel2 = mpControl->mCons[cpssi]->mCparts->getInfluenceVelocity(); - LbmFloat imaxd2 = mpControl->mCons[cpssi]->mCparts->getInfluenceMaxdist(); - - // we allow negative attraction force here! - if(iatt2 > iatt) iatt = iatt2; - - if(ivel2 >ivel) ivel = ivel2; - if(imaxd2>imaxd) imaxd= imaxd2; - //errMsg("FINCIT"," "<<cpssi<<" iatt2="<<iatt2<<" ivel2="<<ivel2<<" imaxd2="<<imaxd<<" NEW "<<" iatt="<<iatt<<" ivel="<<ivel<<" imaxd="<<imaxd); - } - - if(iatt==0. && ivel==0. && imaxd==0.) { - debMsgStd("ControlData::initControl",DM_MSG,"Skipped, all zero...",4); - return; - } - //iatt = mpControl->mCons[1]->mCparts->getInfluenceAttraction(); //ivel = mpControl->mCons[1]->mCparts->getInfluenceVelocity(); //imaxd = mpControl->mCons[1]->mCparts->getInfluenceMaxdist(); // TTTTTT - - // do control setup - for(int cpssi=0; cpssi<(int)mpControl->mCons.size(); cpssi++) { - ControlParticles *cparts = mpControl->mCons[cpssi]->mCparts; - ControlParticles *cpmotion = mpControl->mCons[cpssi]->mCpmotion; - - // TEST!? - bool radmod = false; - const LbmFloat minRadSize = mLevel[coarseLev].nodeSize * 1.5; - if((cparts->getRadiusAtt()>0.) && (cparts->getRadiusAtt()<minRadSize) && (!radmod) ) { - LbmFloat radfac = minRadSize / cparts->getRadiusAtt(); radmod=true; - debMsgStd("ControlData::initControl",DM_MSG,"Modified radii att, fac="<<radfac, 7); - cparts->setRadiusAtt(cparts->getRadiusAtt()*radfac); - cparts->setRadiusVel(cparts->getRadiusVel()*radfac); - cparts->setRadiusMaxd(cparts->getRadiusMaxd()*radfac); - cparts->setRadiusMinMaxd(cparts->getRadiusMinMaxd()*radfac); - } else if((cparts->getRadiusVel()>0.) && (cparts->getRadiusVel()<minRadSize) && (!radmod) ) { - LbmFloat radfac = minRadSize / cparts->getRadiusVel(); - debMsgStd("ControlData::initControl",DM_MSG,"Modified radii vel, fac="<<radfac, 7); - cparts->setRadiusVel(cparts->getRadiusVel()*radfac); - cparts->setRadiusMaxd(cparts->getRadiusMaxd()*radfac); - cparts->setRadiusMinMaxd(cparts->getRadiusMinMaxd()*radfac); - } else if((cparts->getRadiusMaxd()>0.) && (cparts->getRadiusMaxd()<minRadSize) && (!radmod) ) { - LbmFloat radfac = minRadSize / cparts->getRadiusMaxd(); - debMsgStd("ControlData::initControl",DM_MSG,"Modified radii maxd, fac="<<radfac, 7); - cparts->setRadiusMaxd(cparts->getRadiusMaxd()*radfac); - cparts->setRadiusMinMaxd(cparts->getRadiusMinMaxd()*radfac); - } - if(radmod) { - debMsgStd("ControlData::initControl",DM_MSG,"Modified radii: att="<< - cparts->getRadiusAtt()<<", vel=" << cparts->getRadiusVel()<<", maxd=" << - cparts->getRadiusMaxd()<<", mind=" << cparts->getRadiusMinMaxd() ,5); - } - - cpmotion->prepareControl( mSimulationTime+((LbmFloat)mpControl->mCpUpdateInterval)*(mpParam->getTimestep()), mpParam->getTimestep(), NULL ); - cparts->prepareControl( mSimulationTime+((LbmFloat)mpControl->mCpUpdateInterval)*(mpParam->getTimestep()), mpParam->getTimestep(), cpmotion ); - } - - // do control... - for(int lev=0; lev<=mMaxRefine; lev++) { - LbmFloat levVolume = 1.; - LbmFloat levForceScale = 1.; - for(int ll=lev; ll<mMaxRefine; ll++) { - if(LBMDIM==3) levVolume *= 8.; - else levVolume *= 4.; - levForceScale *= 2.; - } - errMsg("LbmFsgrSolver::handleCpdata","levVolume="<<levVolume<<" levForceScale="<<levForceScale ); - //todo: scale velocity, att by level timestep!? - - for(int cpssi=0; cpssi<(int)mpControl->mCons.size(); cpssi++) { - ControlParticles *cparts = mpControl->mCons[cpssi]->mCparts; - // ControlParticles *cpmotion = mpControl->mCons[cpssi]->mCpmotion; - - // if control set is not active skip it - if((cparts->getControlTimStart() > mSimulationTime) || (cparts->getControlTimEnd() < mLastSimTime)) - { - continue; - } - - const LbmFloat velLatticeScale = mLevel[lev].timestep/mLevel[lev].nodeSize; - LbmFloat gsx = ((mvGeoEnd[0]-mvGeoStart[0])/(LbmFloat)mLevel[lev].lSizex); - LbmFloat gsy = ((mvGeoEnd[1]-mvGeoStart[1])/(LbmFloat)mLevel[lev].lSizey); - LbmFloat gsz = ((mvGeoEnd[2]-mvGeoStart[2])/(LbmFloat)mLevel[lev].lSizez); -#if LBMDIM==2 - gsz = gsx; -#endif - LbmFloat goffx = mvGeoStart[0]; - LbmFloat goffy = mvGeoStart[1]; - LbmFloat goffz = mvGeoStart[2]; - - //const LbmFloat cpwIncFac = 2.0; - // max to two thirds of domain size - const int cpw = MIN( mLevel[lev].lSizex/3, MAX( (int)( cparts->getRadiusAtt() /gsx) +1 , 2) ); // normal kernel, att,vel - const int cpkarWidth = 2*cpw+1; - mpControl->mCpKernel.resize(cpkarWidth* cpkarWidth* cpkarWidth); - ControlParticle cpt; cpt.reset(); - cpt.pos = LbmVec( (gsx*(LbmFloat)cpw)+goffx, (gsy*(LbmFloat)cpw)+goffy, (gsz*(LbmFloat)cpw)+goffz ); // optimize? - cpt.density = 0.5; cpt.densityWeight = 0.5; -#if LBMDIM==3 - for(int k= 0; k<cpkarWidth; ++k) { -#else // LBMDIM==3 - { int k = cpw; -#endif - for(int j= 0; j<cpkarWidth; ++j) - for(int i= 0; i<cpkarWidth; ++i) { - KERN(i,j,k).resetForces(); - //LbmFloat dx = i-cpw; LbmFloat dy = j-cpw; LbmFloat dz = k-cpw; - //LbmVec dv = ( LbmVec(dx,dy,dz) ); - //LbmFloat dl = norm( dv ); //LbmVec dir = dv / dl; - LbmVec pos = LbmVec( (gsx*(LbmFloat)i)+goffx, (gsy*(LbmFloat)j)+goffy, (gsz*(LbmFloat)k)+goffz ); // optimize? - cparts->calculateCpInfluenceOpt( &cpt, pos, LbmVec(0,0,0), &KERN(i,j,k) ,1. ); - /*if((CPODEBUG)&&(k==cpw)) errMsg("kern"," at "<<PRINT_IJK<<" pos"<<pos<<" cpp"<<cpt.pos - <<" wf:"<<KERN(i,j,k).weightAtt<<" wa:"<< PRINT_VEC( KERN(i,j,k).forceAtt[0],KERN(i,j,k).forceAtt[1],KERN(i,j,k).forceAtt[2] ) - <<" wf:"<<KERN(i,j,k).weightVel<<" wa:"<< PRINT_VEC( KERN(i,j,k).forceVel[0],KERN(i,j,k).forceVel[1],KERN(i,j,k).forceVel[2] ) - <<" wf:"<<KERN(i,j,k).maxDistance<<" wa:"<< PRINT_VEC( KERN(i,j,k).forceMaxd[0],KERN(i,j,k).forceMaxd[1],KERN(i,j,k).forceMaxd[2] ) ); // */ - KERN(i,j,k).weightAtt *= 2.; - KERN(i,j,k).forceAtt *= 2.; - //KERN(i,j,k).forceAtt[1] *= 2.; KERN(i,j,k).forceAtt[2] *= 2.; - KERN(i,j,k).weightVel *= 2.; - KERN(i,j,k).forceVel *= 2.; - //KERN(i,j,k).forceVel[1] *= 2.; KERN(i,j,k).forceVel[2] *= 2.; - } - } - - if(CPODEBUG) errMsg("cpw"," = "<<cpw<<" f"<< cparts->getRadiusAtt()<<" gsx"<<gsx<<" kpw"<<cpkarWidth); // DEBUG - // first cp loop - add att and vel forces - for(int cppi=0; cppi<cparts->getSize(); cppi++) { - ControlParticle *cp = cparts->getParticle(cppi); - if(cp->influence<=0.) continue; - const int cpi = (int)( (cp->pos[0]-goffx)/gsx ); - const int cpj = (int)( (cp->pos[1]-goffy)/gsy ); - int cpk = (int)( (cp->pos[2]-goffz)/gsz ); - /*if( ((LBMDIM==3)&&(BOUNDSKIP(cpk - cpwsm, getForZMinBnd(), getForZMaxBnd(lev) ))) || - ((LBMDIM==3)&&(BOUNDSKIP(cpk + cpwsm, getForZMinBnd(), getForZMaxBnd(lev) ))) || - BOUNDSKIP(cpj - cpwsm, 0, mLevel[lev].lSizey ) || - BOUNDSKIP(cpj + cpwsm, 0, mLevel[lev].lSizey ) || - BOUNDSKIP(cpi - cpwsm, 0, mLevel[lev].lSizex ) || - BOUNDSKIP(cpi + cpwsm, 0, mLevel[lev].lSizex ) ) { - continue; - } // */ - int is,ie,js,je,ks,ke; - ks = BOUNDCHECK(cpk - cpw, getForZMinBnd(), getForZMaxBnd(lev) ); - ke = BOUNDCHECK(cpk + cpw, getForZMinBnd(), getForZMaxBnd(lev) ); - js = BOUNDCHECK(cpj - cpw, 0, mLevel[lev].lSizey ); - je = BOUNDCHECK(cpj + cpw, 0, mLevel[lev].lSizey ); - is = BOUNDCHECK(cpi - cpw, 0, mLevel[lev].lSizex ); - ie = BOUNDCHECK(cpi + cpw, 0, mLevel[lev].lSizex ); - if(LBMDIM==2) { cpk = 0; ks = 0; ke = 1; } - if(CPODEBUG) errMsg("cppft","i"<<cppi<<" cpw"<<cpw<<" gpos"<<PRINT_VEC(cpi,cpj,cpk)<<" i:"<<is<<","<<ie<<" j:"<<js<<","<<je<<" k:"<<ks<<","<<ke<<" "); // DEBUG - cpInfs++; - - for(int k= ks; k<ke; ++k) { - for(int j= js; j<je; ++j) { - - CellFlagType *pflag = &RFLAG(lev,is,j,k, mLevel[lev].setCurr); - ControlForces *kk = &KERN( is-cpi+cpw, j-cpj+cpw, k-cpk+cpw); - ControlForces *ff = &LBMGET_FORCE(lev,is,j,k); - pflag--; kk--; ff--; - - for(int i= is; i<ie; ++i) { - // first cp loop (att,vel) - pflag++; kk++; ff++; - - //add weight for bnd cells - const LbmFloat pwforce = kk->weightAtt; - // control particle mod, - // dont add multiple CFFluid fsgr boundaries - if(lev==mMaxRefine) { - //if( ( ((*pflag)&(CFFluid )) && (lev==mMaxRefine) ) || - //( ((*pflag)&(CFGrNorm)) && (lev <mMaxRefine) ) ) { - if((*pflag)&(CFFluid|CFUnused)) { - // check not fromcoarse? - cp->density += levVolume* kk->weightAtt; // old CFFluid - } else if( (*pflag) & (CFEmpty) ) { - cp->density -= levVolume* 0.5; - } else { //if( ((*pflag) & (CFBnd)) ) { - cp->density -= levVolume* 0.2; // penalty - } - } else { - //if((*pflag)&(CFGrNorm)) { - //cp->density += levVolume* kk->weightAtt; // old CFFluid - //} - } - //else if(!((*pflag) & (CFUnused)) ) { cp->density -= levVolume* 0.2; } // penalty - - if( (*pflag) & (CFFluid|CFInter) ) // RFLAG_check - { - - cpChecks++; - //const LbmFloat pwforce = kk->weightAtt; - LbmFloat pwvel = kk->weightVel; - if((pwforce==0.)&&(pwvel==0.)) { continue; } - ff->weightAtt += 1e-6; // for distance - - if(pwforce>0.) { - ff->weightAtt += pwforce *cp->densityWeight *cp->influence; - ff->forceAtt += kk->forceAtt *levForceScale *cp->densityWeight *cp->influence; - - // old fill handling here - const int workSet =mLevel[lev].setCurr; - LbmFloat ux=0., uy=0., uz=0.; - FORDF1{ - const LbmFloat dfn = QCELL(lev, i,j,k, workSet, l); - ux += (this->dfDvecX[l]*dfn); - uy += (this->dfDvecY[l]*dfn); - uz += (this->dfDvecZ[l]*dfn); - } - // control particle mod - cp->avgVelWeight += levVolume*pwforce; - cp->avgVelAcc += LbmVec(ux,uy,uz) * levVolume*pwforce; - } - - if(pwvel>0.) { - // TODO make switch? vel.influence depends on density weight... - // (reduced lowering with 0.75 factor) - pwvel *= cp->influence *(1.-0.75*cp->densityWeight); - // control particle mod - // todo use Omega instead!? - ff->forceVel += cp->vel*levVolume*pwvel * velLatticeScale; // levVolume? - ff->weightVel += levVolume*pwvel; // levVolume? - ff->compAv += cp->avgVel*levVolume*pwvel; // levVolume? - ff->compAvWeight += levVolume*pwvel; // levVolume? - } - - if(CPODEBUG) errMsg("cppft","i"<<cppi<<" at "<<PRINT_IJK<<" kern:"<< - PRINT_VEC(i-cpi+cpw, j-cpj+cpw, k-cpk+cpw ) - //<<" w:"<<ff->weightAtt<<" wa:" - //<<PRINT_VEC( ff->forceAtt[0],ff->forceAtt[1],ff->forceAtt[2] ) - //<<" v:"<<ff->weightVel<<" wv:" - //<<PRINT_VEC( ff->forceVel[0],ff->forceVel[1],ff->forceVel[2] ) - //<<" v:"<<ff->maxDistance<<" wv:" - //<<PRINT_VEC( ff->forceMaxd[0],ff->forceMaxd[1],ff->forceMaxd[2] ) - ); - } // celltype - - } // ijk - } // ijk - } // ijk - } // cpi, end first cp loop (att,vel) - debMsgStd("LbmFsgrSolver::handleCpdata",DM_MSG,"Force cpgrid "<<cpssi<<" generated checks:"<<cpChecks<<" infs:"<<cpInfs ,9); - } //cpssi - } // lev - - // second loop - for(int lev=0; lev<=mMaxRefine; lev++) { - LbmFloat levVolume = 1.; - LbmFloat levForceScale = 1.; - for(int ll=lev; ll<mMaxRefine; ll++) { - if(LBMDIM==3) levVolume *= 8.; - else levVolume *= 4.; - levForceScale *= 2.; - } - // prepare maxd forces - for(int cpssi=0; cpssi<(int)mpControl->mCons.size(); cpssi++) { - ControlParticles *cparts = mpControl->mCons[cpssi]->mCparts; - - // WARNING copied from above! - const LbmFloat velLatticeScale = mLevel[lev].timestep/mLevel[lev].nodeSize; - LbmFloat gsx = ((mvGeoEnd[0]-mvGeoStart[0])/(LbmFloat)mLevel[lev].lSizex); - LbmFloat gsy = ((mvGeoEnd[1]-mvGeoStart[1])/(LbmFloat)mLevel[lev].lSizey); - LbmFloat gsz = ((mvGeoEnd[2]-mvGeoStart[2])/(LbmFloat)mLevel[lev].lSizez); -#if LBMDIM==2 - gsz = gsx; -#endif - LbmFloat goffx = mvGeoStart[0]; - LbmFloat goffy = mvGeoStart[1]; - LbmFloat goffz = mvGeoStart[2]; - - //const LbmFloat cpwIncFac = 2.0; - const int mdw = MIN( mLevel[lev].lSizex/2, MAX( (int)( cparts->getRadiusMaxd() /gsx) +1 , 2) ); // wide kernel, md - const int mdkarWidth = 2*mdw+1; - mpControl->mMdKernel.resize(mdkarWidth* mdkarWidth* mdkarWidth); - ControlParticle cpt; cpt.reset(); - cpt.density = 0.5; cpt.densityWeight = 0.5; - cpt.pos = LbmVec( (gsx*(LbmFloat)mdw)+goffx, (gsy*(LbmFloat)mdw)+goffy, (gsz*(LbmFloat)mdw)+goffz ); // optimize? -#if LBMDIM==3 - for(int k= 0; k<mdkarWidth; ++k) { -#else // LBMDIM==3 - { int k = mdw; -#endif - for(int j= 0; j<mdkarWidth; ++j) - for(int i= 0; i<mdkarWidth; ++i) { - MDKERN(i,j,k).resetForces(); - LbmVec pos = LbmVec( (gsx*(LbmFloat)i)+goffx, (gsy*(LbmFloat)j)+goffy, (gsz*(LbmFloat)k)+goffz ); // optimize? - cparts->calculateMaxdForce( &cpt, pos, &MDKERN(i,j,k) ); - } - } - - // second cpi loop, maxd forces - if(cparts->getInfluenceMaxdist()>0.) { - for(int cppi=0; cppi<cparts->getSize(); cppi++) { - ControlParticle *cp = cparts->getParticle(cppi); - if(cp->influence<=0.) continue; - const int cpi = (int)( (cp->pos[0]-goffx)/gsx ); - const int cpj = (int)( (cp->pos[1]-goffy)/gsy ); - int cpk = (int)( (cp->pos[2]-goffz)/gsz ); - - int is,ie,js,je,ks,ke; - ks = BOUNDCHECK(cpk - mdw, getForZMinBnd(), getForZMaxBnd(lev) ); - ke = BOUNDCHECK(cpk + mdw, getForZMinBnd(), getForZMaxBnd(lev) ); - js = BOUNDCHECK(cpj - mdw, 0, mLevel[lev].lSizey ); - je = BOUNDCHECK(cpj + mdw, 0, mLevel[lev].lSizey ); - is = BOUNDCHECK(cpi - mdw, 0, mLevel[lev].lSizex ); - ie = BOUNDCHECK(cpi + mdw, 0, mLevel[lev].lSizex ); - if(LBMDIM==2) { cpk = 0; ks = 0; ke = 1; } - if(CPODEBUG) errMsg("cppft","i"<<cppi<<" mdw"<<mdw<<" gpos"<<PRINT_VEC(cpi,cpj,cpk)<<" i:"<<is<<","<<ie<<" j:"<<js<<","<<je<<" k:"<<ks<<","<<ke<<" "); // DEBUG - cpInfs++; - - for(int k= ks; k<ke; ++k) - for(int j= js; j<je; ++j) { - CellFlagType *pflag = &RFLAG(lev,is-1,j,k, mLevel[lev].setCurr); - for(int i= is; i<ie; ++i) { - // second cpi loop, maxd forces - pflag++; - if( (*pflag) & (CFFluid|CFInter) ) // RFLAG_check - { - cpChecks++; - ControlForces *ff = &LBMGET_FORCE(lev,i,j,k); - if(ff->weightAtt == 0.) { - ControlForces *kk = &MDKERN( i-cpi+mdw, j-cpj+mdw, k-cpk+mdw); - const LbmFloat pmdf = kk->maxDistance; - if((ff->maxDistance > pmdf) || (ff->maxDistance<0.)) - ff->maxDistance = pmdf; - ff->forceMaxd = kk->forceMaxd; - // todo use Omega instead!? - ff->forceVel = cp->vel* velLatticeScale; - } - } // celltype - } } // ijk - } // cpi, md loop - } // maxd inf>0 */ - - - debMsgStd("ControlData::initControl",DM_MSG,"Maxd cpgrid "<<cpssi<<" generated checks:"<<cpChecks<<" infs:"<<cpInfs ,9); - } //cpssi - - // normalize, only done once for the whole array - mpControl->mCons[0]->mCparts->finishControl( mpControl->mCpForces[lev], iatt,ivel,imaxd ); - - } // lev loop - - myTime_t cpend = getTime(); - debMsgStd("ControlData::handleCpdata",DM_MSG,"Time for cpgrid generation:"<< getTimeString(cpend-cpstart)<<", checks:"<<cpChecks<<" infs:"<<cpInfs<<" " ,8); - - // warning, may return before -} - -void LbmFsgrSolver::cpDebugDisplay(int dispset) { } diff --git a/intern/elbeem/intern/solver_control.h b/intern/elbeem/intern/solver_control.h deleted file mode 100644 index 809cac17297..00000000000 --- a/intern/elbeem/intern/solver_control.h +++ /dev/null @@ -1,199 +0,0 @@ -/** \file - * \ingroup elbeem - */ -/****************************************************************************** - * - * El'Beem - the visual lattice boltzmann freesurface simulator - * All code distributed as part of El'Beem is covered by the version 2 of the - * GNU General Public License. See the file COPYING for details. - * Copyright 2003-2006 Nils Thuerey - * - * testing extensions - * - *****************************************************************************/ - - -#ifndef LBM_TESTCLASS_H -#define LBM_TESTCLASS_H - -#ifdef WITH_CXX_GUARDEDALLOC -# include "MEM_guardedalloc.h" -#endif - -//class IsoSurface; -class ParticleObject; -class ControlParticles; -class ControlForces; - -//#define NUMGRIDS 2 -//#define MAXNUMSWS 10 - -// farfield modes -#define FARF_3DONLY -1 -#define FARF_BOTH 0 -#define FARF_SWEONLY 1 -// dont reuse 3d vars/init -#define FARF_SEPSWE 2 - -// relaxation macros for solver_relax.h - -// WARNING has to match controlparts.h -#define CPF_ENTRIES 12 -#define CPF_FORCE 0 -#define CPF_VELWEIGHT 3 -#define CPF_VELOCITY 4 -#define CPF_FORCEWEIGHT 7 -#define CPF_MINCPDIST 8 -#define CPF_MINCPDIR 9 - -#include "controlparticles.h" - -#include "ntl_geometrymodel.h" - -// get force entry, set=0 is unused anyway -#define LBMGET_FORCE(lev, i,j,k) mpControl->mCpForces[lev][ (LBMGI(lev,i,j,k,0)) ] - -// debug mods off... -// same as in src/solver_relax.h! -#define __PRECOLLIDE_MODS(rho,ux,uy,uz, grav) \ - ux += (grav)[0]; \ - uy += (grav)[1]; \ - uz += (grav)[2]; - -//void testMaxdmod(int i, int j,int k, LbmFloat &ux,LbmFloat &uy,LbmFloat &uz,ControlForces &ff); -#if LBMDIM==3 -#define MAXDGRAV \ - if(myforce->forceMaxd[0]*ux+myforce->forceMaxd[1]*uy<LBM_EPSILON) { \ - ux = v2w*myforce->forceVel[0]+ v2wi*ux; \ - uy = v2w*myforce->forceVel[1]+ v2wi*uy; } \ - /* movement inverse to g? */ \ - if((uz>LBM_EPSILON)&&(uz>myforce->forceVel[2])) { \ - uz = v2w*myforce->forceVel[2]+ v2wi*uz; } -#else // LBMDIM==3 -#define MAXDGRAV \ - if(myforce->forceMaxd[0]*ux<LBM_EPSILON) { \ - ux = v2w*myforce->forceVel[0]+ v2wi*ux; } \ - /* movement inverse to g? */ \ - if((uy>LBM_EPSILON)&&(uy>myforce->forceVel[1])) { \ - uy = v2w*myforce->forceVel[1]+ v2wi*uy; } -#endif // LBMDIM==3 - -// debug modifications of collide vars (testing) -// requires: lev,i,j,k -#define PRECOLLIDE_MODS(rho,ux,uy,uz, grav) \ - LbmFloat attforce = 1.; \ - if(this->mTForceStrength>0.) { \ - ControlForces* myforce = &LBMGET_FORCE(lev,i,j,k); \ - const LbmFloat vf = myforce->weightAtt;\ - const LbmFloat vw = myforce->weightVel;\ - if(vf!=0.) { attforce = MAX(0., 1.-vf); /* TODO FIXME? use ABS(vf) for repulsion force? */ \ - ux += myforce->forceAtt[0]; \ - uy += myforce->forceAtt[1]; \ - uz += myforce->forceAtt[2]; \ - \ - } else if(( myforce->maxDistance>0.) && ( myforce->maxDistance<CPF_MAXDINIT)) {\ - const LbmFloat v2w = mpControl->mCons[0]->mCparts->getInfluenceMaxdist() * \ - (myforce->maxDistance-mpControl->mCons[0]->mCparts->getRadiusMinMaxd()) / (mpControl->mCons[0]->mCparts->getRadiusMaxd()-mpControl->mCons[0]->mCparts->getRadiusMinMaxd()); \ - const LbmFloat v2wi = 1.-v2w; \ - if(v2w>0.){ MAXDGRAV; \ - /* errMsg("ERRMDTT","at "<<PRINT_IJK<<" maxd="<<myforce->maxDistance<<", newu"<<PRINT_VEC(ux,uy,uz)<<", org"<<PRINT_VEC(oux,ouy,ouz)<<", fv"<<myforce->forceVel<<" " ); */ \ - }\ - } \ - if(vw>0.) { \ - const LbmFloat vwi = 1.-vw;\ - const LbmFloat vwd = mpControl->mDiffVelCon;\ - ux += vw*(myforce->forceVel[0]-myforce->compAv[0] + vwd*(myforce->compAv[0]-ux) ); \ - uy += vw*(myforce->forceVel[1]-myforce->compAv[1] + vwd*(myforce->compAv[1]-uy) ); \ - uz += vw*(myforce->forceVel[2]-myforce->compAv[2] + vwd*(myforce->compAv[2]-uz) ); \ - /* TODO test!? modify smooth vel by influence of force for each lbm step, to account for force update only each N steps */ \ - myforce->compAv = (myforce->forceVel*vw+ myforce->compAv*vwi); \ - } \ - } \ - ux += (grav)[0]*attforce; \ - uy += (grav)[1]*attforce; \ - uz += (grav)[2]*attforce; \ - /* end PRECOLLIDE_MODS */ - -#define TEST_IF_CHECK \ - if((!iffilled)&&(LBMGET_FORCE(lev,i,j,k).weightAtt!=0.)) { \ - errMsg("TESTIFFILL"," at "<<PRINT_IJK<<" "<<mass<<" "<<rho); \ - iffilled = true; \ - if(mass<rho*1.0) mass = rho*1.0; myfrac = 1.0; \ - } - - -// a single set of control particles and params -class LbmControlSet { - public: - LbmControlSet(); - ~LbmControlSet(); - void initCparts(); - - // control particles - ControlParticles *mCparts; - // control particle overall motion (for easier manual generation) - ControlParticles *mCpmotion; - // cp data file - string mContrPartFile; - string mCpmotionFile; - // cp debug displau - LbmFloat mDebugCpscale, mDebugVelScale, mDebugCompavScale, mDebugAttScale, mDebugMaxdScale, mDebugAvgVelScale; - - // params - AnimChannel<float> mcForceAtt; - AnimChannel<float> mcForceVel; - AnimChannel<float> mcForceMaxd; - - AnimChannel<float> mcRadiusAtt; - AnimChannel<float> mcRadiusVel; - AnimChannel<float> mcRadiusMind; - AnimChannel<float> mcRadiusMaxd; - - AnimChannel<ntlVec3f> mcCpScale; - AnimChannel<ntlVec3f> mcCpOffset; - -private: -#ifdef WITH_CXX_GUARDEDALLOC - MEM_CXX_CLASS_ALLOC_FUNCS("ELBEEM:LbmControlSet") -#endif -}; - - - -// main control data storage -class LbmControlData -{ - public: - LbmControlData(); - virtual ~LbmControlData(); - - // control data - - // contorl params - void parseControldataAttrList(AttributeList *attr); - - // control strength, set for solver interface - LbmFloat mSetForceStrength; - // cp vars - std::vector<LbmControlSet*> mCons; - // update interval - int mCpUpdateInterval; - // output - string mCpOutfile; - // control particle precomputed influence - std::vector< std::vector<ControlForces> > mCpForces; - std::vector<ControlForces> mCpKernel; - std::vector<ControlForces> mMdKernel; - // activate differential velcon - LbmFloat mDiffVelCon; - - // cp debug displau - LbmFloat mDebugCpscale, mDebugVelScale, mDebugCompavScale, mDebugAttScale, mDebugMaxdScale, mDebugAvgVelScale; - -private: -#ifdef WITH_CXX_GUARDEDALLOC - MEM_CXX_CLASS_ALLOC_FUNCS("ELBEEM:LbmControlData ") -#endif -}; - -#endif // LBM_TESTCLASS_H diff --git a/intern/elbeem/intern/solver_init.cpp b/intern/elbeem/intern/solver_init.cpp deleted file mode 100644 index 5f28b4da41a..00000000000 --- a/intern/elbeem/intern/solver_init.cpp +++ /dev/null @@ -1,2396 +0,0 @@ -/** \file - * \ingroup elbeem - */ -/****************************************************************************** - * - * El'Beem - Free Surface Fluid Simulation with the Lattice Boltzmann Method - * Copyright 2003-2006 Nils Thuerey - * - * Standard LBM Factory implementation - * - *****************************************************************************/ - - -#include "solver_class.h" -#include "solver_relax.h" -// for geo init FGI_ defines -#include "elbeem.h" -#include "globals.h" - - -// helper for 2d init -#define SWAPYZ(vec) { \ - const LbmFloat tmp = (vec)[2]; \ - (vec)[2] = (vec)[1]; (vec)[1] = tmp; } - - -/*****************************************************************************/ -//! common variables - -/*****************************************************************************/ -/*! 3D implementation D3Q19 */ -#if LBMDIM==3 - - //! how many dimensions? - const int LbmFsgrSolver::cDimension = 3; - - // Wi factors for collide step - const LbmFloat LbmFsgrSolver::cCollenZero = (1.0/3.0); - const LbmFloat LbmFsgrSolver::cCollenOne = (1.0/18.0); - const LbmFloat LbmFsgrSolver::cCollenSqrtTwo = (1.0/36.0); - - //! threshold value for filled/emptied cells - const LbmFloat LbmFsgrSolver::cMagicNr2 = 1.0005; - const LbmFloat LbmFsgrSolver::cMagicNr2Neg = -0.0005; - const LbmFloat LbmFsgrSolver::cMagicNr = 1.010001; - const LbmFloat LbmFsgrSolver::cMagicNrNeg = -0.010001; - - //! size of a single set of distribution functions - const int LbmFsgrSolver::cDfNum = 19; - //! direction vector contain vecs for all spatial dirs, even if not used for LBM model - const int LbmFsgrSolver::cDirNum = 27; - - //const string LbmFsgrSolver::dfString[ cDfNum ] = { - const char* LbmFsgrSolver::dfString[ cDfNum ] = { - " C", " N"," S"," E"," W"," T"," B", - "NE","NW","SE","SW", - "NT","NB","ST","SB", - "ET","EB","WT","WB" - }; - - const int LbmFsgrSolver::dfNorm[ cDfNum ] = { - cDirC, cDirN, cDirS, cDirE, cDirW, cDirT, cDirB, - cDirNE, cDirNW, cDirSE, cDirSW, - cDirNT, cDirNB, cDirST, cDirSB, - cDirET, cDirEB, cDirWT, cDirWB - }; - - const int LbmFsgrSolver::dfInv[ cDfNum ] = { - cDirC, cDirS, cDirN, cDirW, cDirE, cDirB, cDirT, - cDirSW, cDirSE, cDirNW, cDirNE, - cDirSB, cDirST, cDirNB, cDirNT, - cDirWB, cDirWT, cDirEB, cDirET - }; - - const int LbmFsgrSolver::dfRefX[ cDfNum ] = { - 0, 0, 0, 0, 0, 0, 0, - cDirSE, cDirSW, cDirNE, cDirNW, - 0, 0, 0, 0, - cDirEB, cDirET, cDirWB, cDirWT - }; - - const int LbmFsgrSolver::dfRefY[ cDfNum ] = { - 0, 0, 0, 0, 0, 0, 0, - cDirNW, cDirNE, cDirSW, cDirSE, - cDirNB, cDirNT, cDirSB, cDirST, - 0, 0, 0, 0 - }; - - const int LbmFsgrSolver::dfRefZ[ cDfNum ] = { - 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, - cDirST, cDirSB, cDirNT, cDirNB, - cDirWT, cDirWB, cDirET, cDirEB - }; - - // Vector Order 3D: - // 0 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 - // 0, 0, 0, 1,-1, 0, 0, 1,-1, 1,-1, 0, 0, 0, 0, 1, 1,-1,-1, 1,-1, 1,-1, 1,-1, 1,-1 - // 0, 1,-1, 0, 0, 0, 0, 1, 1,-1,-1, 1, 1,-1,-1, 0, 0, 0, 0, 1, 1,-1,-1, 1, 1,-1,-1 - // 0, 0, 0, 0, 0, 1,-1, 0, 0, 0, 0, 1,-1, 1,-1, 1,-1, 1,-1, 1, 1, 1, 1, -1,-1,-1,-1 - - const int LbmFsgrSolver::dfVecX[ cDirNum ] = { - 0, 0,0, 1,-1, 0,0, - 1,-1,1,-1, - 0,0,0,0, - 1,1,-1,-1, - 1,-1, 1,-1, - 1,-1, 1,-1, - }; - const int LbmFsgrSolver::dfVecY[ cDirNum ] = { - 0, 1,-1, 0,0,0,0, - 1,1,-1,-1, - 1,1,-1,-1, - 0,0,0,0, - 1, 1,-1,-1, - 1, 1,-1,-1 - }; - const int LbmFsgrSolver::dfVecZ[ cDirNum ] = { - 0, 0,0,0,0,1,-1, - 0,0,0,0, - 1,-1,1,-1, - 1,-1,1,-1, - 1, 1, 1, 1, - -1,-1,-1,-1 - }; - - const LbmFloat LbmFsgrSolver::dfDvecX[ cDirNum ] = { - 0, 0,0, 1,-1, 0,0, - 1,-1,1,-1, - 0,0,0,0, - 1,1,-1,-1, - 1,-1, 1,-1, - 1,-1, 1,-1 - }; - const LbmFloat LbmFsgrSolver::dfDvecY[ cDirNum ] = { - 0, 1,-1, 0,0,0,0, - 1,1,-1,-1, - 1,1,-1,-1, - 0,0,0,0, - 1, 1,-1,-1, - 1, 1,-1,-1 - }; - const LbmFloat LbmFsgrSolver::dfDvecZ[ cDirNum ] = { - 0, 0,0,0,0,1,-1, - 0,0,0,0, - 1,-1,1,-1, - 1,-1,1,-1, - 1, 1, 1, 1, - -1,-1,-1,-1 - }; - - /* principal directions */ - const int LbmFsgrSolver::princDirX[ 2*LbmFsgrSolver::cDimension ] = { - 1,-1, 0,0, 0,0 - }; - const int LbmFsgrSolver::princDirY[ 2*LbmFsgrSolver::cDimension ] = { - 0,0, 1,-1, 0,0 - }; - const int LbmFsgrSolver::princDirZ[ 2*LbmFsgrSolver::cDimension ] = { - 0,0, 0,0, 1,-1 - }; - - /*! arrays for les model coefficients, inited in lbmsolver constructor */ - LbmFloat LbmFsgrSolver::lesCoeffDiag[ (cDimension-1)*(cDimension-1) ][ cDirNum ]; - LbmFloat LbmFsgrSolver::lesCoeffOffdiag[ cDimension ][ cDirNum ]; - - - const LbmFloat LbmFsgrSolver::dfLength[ cDfNum ]= { - cCollenZero, - cCollenOne, cCollenOne, cCollenOne, - cCollenOne, cCollenOne, cCollenOne, - cCollenSqrtTwo, cCollenSqrtTwo, cCollenSqrtTwo, cCollenSqrtTwo, - cCollenSqrtTwo, cCollenSqrtTwo, cCollenSqrtTwo, cCollenSqrtTwo, - cCollenSqrtTwo, cCollenSqrtTwo, cCollenSqrtTwo, cCollenSqrtTwo - }; - - /* precalculated equilibrium dfs, inited in lbmsolver constructor */ - LbmFloat LbmFsgrSolver::dfEquil[ dTotalNum ]; - -#else // end LBMDIM==3 , LBMDIM==2 - -/*****************************************************************************/ -/*! 2D implementation D2Q9 */ - - //! how many dimensions? - const int LbmFsgrSolver::cDimension = 2; - - //! Wi factors for collide step - const LbmFloat LbmFsgrSolver::cCollenZero = (4.0/9.0); - const LbmFloat LbmFsgrSolver::cCollenOne = (1.0/9.0); - const LbmFloat LbmFsgrSolver::cCollenSqrtTwo = (1.0/36.0); - - //! threshold value for filled/emptied cells - const LbmFloat LbmFsgrSolver::cMagicNr2 = 1.0005; - const LbmFloat LbmFsgrSolver::cMagicNr2Neg = -0.0005; - const LbmFloat LbmFsgrSolver::cMagicNr = 1.010001; - const LbmFloat LbmFsgrSolver::cMagicNrNeg = -0.010001; - - //! size of a single set of distribution functions - const int LbmFsgrSolver::cDfNum = 9; - const int LbmFsgrSolver::cDirNum = 9; - - //const string LbmFsgrSolver::dfString[ cDfNum ] = { - const char* LbmFsgrSolver::dfString[ cDfNum ] = { - " C", - " N", " S", " E", " W", - "NE", "NW", "SE","SW" - }; - - const int LbmFsgrSolver::dfNorm[ cDfNum ] = { - cDirC, - cDirN, cDirS, cDirE, cDirW, - cDirNE, cDirNW, cDirSE, cDirSW - }; - - const int LbmFsgrSolver::dfInv[ cDfNum ] = { - cDirC, - cDirS, cDirN, cDirW, cDirE, - cDirSW, cDirSE, cDirNW, cDirNE - }; - - const int LbmFsgrSolver::dfRefX[ cDfNum ] = { - 0, - 0, 0, 0, 0, - cDirSE, cDirSW, cDirNE, cDirNW - }; - - const int LbmFsgrSolver::dfRefY[ cDfNum ] = { - 0, - 0, 0, 0, 0, - cDirNW, cDirNE, cDirSW, cDirSE - }; - - const int LbmFsgrSolver::dfRefZ[ cDfNum ] = { - 0, 0, 0, 0, 0, - 0, 0, 0, 0 - }; - - // Vector Order 2D: - // 0 1 2 3 4 5 6 7 8 - // 0, 0,0, 1,-1, 1,-1,1,-1 - // 0, 1,-1, 0,0, 1,1,-1,-1 - - const int LbmFsgrSolver::dfVecX[ cDirNum ] = { - 0, - 0,0, 1,-1, - 1,-1,1,-1 - }; - const int LbmFsgrSolver::dfVecY[ cDirNum ] = { - 0, - 1,-1, 0,0, - 1,1,-1,-1 - }; - const int LbmFsgrSolver::dfVecZ[ cDirNum ] = { - 0, 0,0,0,0, 0,0,0,0 - }; - - const LbmFloat LbmFsgrSolver::dfDvecX[ cDirNum ] = { - 0, - 0,0, 1,-1, - 1,-1,1,-1 - }; - const LbmFloat LbmFsgrSolver::dfDvecY[ cDirNum ] = { - 0, - 1,-1, 0,0, - 1,1,-1,-1 - }; - const LbmFloat LbmFsgrSolver::dfDvecZ[ cDirNum ] = { - 0, 0,0,0,0, 0,0,0,0 - }; - - const int LbmFsgrSolver::princDirX[ 2*LbmFsgrSolver::cDimension ] = { - 1,-1, 0,0 - }; - const int LbmFsgrSolver::princDirY[ 2*LbmFsgrSolver::cDimension ] = { - 0,0, 1,-1 - }; - const int LbmFsgrSolver::princDirZ[ 2*LbmFsgrSolver::cDimension ] = { - 0,0, 0,0 - }; - - - /*! arrays for les model coefficients, inited in lbmsolver constructor */ - LbmFloat LbmFsgrSolver::lesCoeffDiag[ (cDimension-1)*(cDimension-1) ][ cDirNum ]; - LbmFloat LbmFsgrSolver::lesCoeffOffdiag[ cDimension ][ cDirNum ]; - - - const LbmFloat LbmFsgrSolver::dfLength[ cDfNum ]= { - cCollenZero, - cCollenOne, cCollenOne, cCollenOne, cCollenOne, - cCollenSqrtTwo, cCollenSqrtTwo, cCollenSqrtTwo, cCollenSqrtTwo - }; - - /* precalculated equilibrium dfs, inited in lbmsolver constructor */ - LbmFloat LbmFsgrSolver::dfEquil[ dTotalNum ]; - -// D2Q9 end -#endif // LBMDIM==2 - - - - -/****************************************************************************** - * Lbm Constructor - *****************************************************************************/ -LbmFsgrSolver::LbmFsgrSolver() : - //D(), - mCurrentMass(0.0), mCurrentVolume(0.0), - mNumProblems(0), - mAvgMLSUPS(0.0), mAvgMLSUPSCnt(0.0), - mpPreviewSurface(NULL), - mTimeAdap(true), mForceTimeStepReduce(false), - mFVHeight(0.0), mFVArea(1.0), mUpdateFVHeight(false), - mInitSurfaceSmoothing(0), mFsSurfGenSetting(0), - mTimestepReduceLock(0), - mTimeSwitchCounts(0), mTimeMaxvelStepCnt(0), - mSimulationTime(0.0), mLastSimTime(0.0), - mMinTimestep(0.0), mMaxTimestep(0.0), - mMaxNoCells(0), mMinNoCells(0), mAvgNumUsedCells(0), - mObjectSpeeds(), mObjectPartslips(), mObjectMassMovnd(), - mMOIVertices(), mMOIVerticesOld(), mMOINormals(), - mIsoWeightMethod(1), - mMaxRefine(1), - mDfScaleUp(-1.0), mDfScaleDown(-1.0), - mInitialCsmago(0.02), // set to 0.02 for mMaxRefine==0 below and default for fine level, coarser ones are 0.03 - mDebugOmegaRet(0.0), - mLastOmega(1e10), mLastGravity(1e10), - mNumInvIfTotal(0), mNumFsgrChanges(0), - mDisableStandingFluidInit(0), - mInit2dYZ(false), - mForceTadapRefine(-1), mCutoff(-1) -{ - mpControl = new LbmControlData(); - -#if LBM_INCLUDE_TESTSOLVERS==1 - mpTest = new LbmTestdata(); - mMpNum = mMpIndex = 0; - mOrgSizeX = 0; - mOrgStartX = 0.; - mOrgEndX = 0.; -#endif // LBM_INCLUDE_TESTSOLVERS!=1 - mpIso = new IsoSurface( mIsoValue ); - - // init equilibrium dist. func - LbmFloat rho=1.0; - FORDF0 { - dfEquil[l] = this->getCollideEq( l,rho, 0.0, 0.0, 0.0); - } - dfEquil[dMass] = 1.; - dfEquil[dFfrac] = 1.; - dfEquil[dFlux] = FLUX_INIT; - - // init LES - int odm = 0; - for(int m=0; m<LBMDIM; m++) { - for(int l=0; l<cDfNum; l++) { - this->lesCoeffDiag[m][l] = - this->lesCoeffOffdiag[m][l] = 0.0; - } - } - for(int m=0; m<LBMDIM; m++) { - for(int n=0; n<LBMDIM; n++) { - for(int l=1; l<cDfNum; l++) { - LbmFloat em; - switch(m) { - case 0: em = dfDvecX[l]; break; - case 1: em = dfDvecY[l]; break; - case 2: em = dfDvecZ[l]; break; - default: em = -1.0; errFatal("SMAGO1","err m="<<m, SIMWORLD_GENERICERROR); - } - LbmFloat en; - switch(n) { - case 0: en = dfDvecX[l]; break; - case 1: en = dfDvecY[l]; break; - case 2: en = dfDvecZ[l]; break; - default: en = -1.0; errFatal("SMAGO2","err n="<<n, SIMWORLD_GENERICERROR); - } - const LbmFloat coeff = em*en; - if(m==n) { - this->lesCoeffDiag[m][l] = coeff; - } else { - if(m>n) { - this->lesCoeffOffdiag[odm][l] = coeff; - } - } - } - - if(m==n) { - } else { - if(m>n) odm++; - } - } - } - - mDvecNrm[0] = LbmVec(0.0); - FORDF1 { - mDvecNrm[l] = getNormalized( - LbmVec(dfDvecX[dfInv[l]], dfDvecY[dfInv[l]], dfDvecZ[dfInv[l]] ) - ) * -1.0; - } - - // calculate gauss weights for restriction - //LbmFloat mGaussw[27]; - LbmFloat totGaussw = 0.0; - const LbmFloat alpha = 1.0; - const LbmFloat gw = sqrt(2.0*LBMDIM); -#if ELBEEM_PLUGIN!=1 - errMsg("coarseRestrictFromFine", "TCRFF_DFDEBUG2 test df/dir num!"); -#endif - for(int n=0;(n<cDirNum); n++) { mGaussw[n] = 0.0; } - //for(int n=0;(n<cDirNum); n++) { - for(int n=0;(n<cDfNum); n++) { - const LbmFloat d = norm(LbmVec(dfVecX[n], dfVecY[n], dfVecZ[n])); - LbmFloat w = expf( -alpha*d*d ) - expf( -alpha*gw*gw ); - mGaussw[n] = w; - totGaussw += w; - } - for(int n=0;(n<cDirNum); n++) { - mGaussw[n] = mGaussw[n]/totGaussw; - } - -} - -/*****************************************************************************/ -/* Destructor */ -/*****************************************************************************/ -LbmFsgrSolver::~LbmFsgrSolver() -{ - if(!mInitDone){ debMsgStd("LbmFsgrSolver::LbmFsgrSolver",DM_MSG,"not inited...",0); return; } -#if COMPRESSGRIDS==1 - delete [] mLevel[mMaxRefine].mprsCells[1]; - mLevel[mMaxRefine].mprsCells[0] = mLevel[mMaxRefine].mprsCells[1] = NULL; -#endif // COMPRESSGRIDS==1 - - for(int i=0; i<=mMaxRefine; i++) { - for(int s=0; s<2; s++) { - if(mLevel[i].mprsCells[s]) delete [] mLevel[i].mprsCells[s]; - if(mLevel[i].mprsFlags[s]) delete [] mLevel[i].mprsFlags[s]; - } - } - delete mpIso; - if(mpPreviewSurface) delete mpPreviewSurface; - // cleanup done during scene deletion... - - if(mpControl) delete mpControl; - - // always output performance estimate - debMsgStd("LbmFsgrSolver::~LbmFsgrSolver",DM_MSG," Avg. MLSUPS:"<<(mAvgMLSUPS/mAvgMLSUPSCnt), 5); - if(!mSilent) debMsgStd("LbmFsgrSolver::~LbmFsgrSolver",DM_MSG,"Deleted...",10); -} - - - - -/****************************************************************************** - * initilize variables fom attribute list - *****************************************************************************/ -void LbmFsgrSolver::parseAttrList() -{ - LbmSolverInterface::parseStdAttrList(); - - string matIso("default"); - matIso = mpSifAttrs->readString("material_surf", matIso, "SimulationLbm","mpIso->material", false ); - mpIso->setMaterialName( matIso ); - mOutputSurfacePreview = mpSifAttrs->readInt("surfacepreview", mOutputSurfacePreview, "SimulationLbm","mOutputSurfacePreview", false ); - mTimeAdap = mpSifAttrs->readBool("timeadap", mTimeAdap, "SimulationLbm","mTimeAdap", false ); - mDomainBound = mpSifAttrs->readString("domainbound", mDomainBound, "SimulationLbm","mDomainBound", false ); - mDomainPartSlipValue = mpSifAttrs->readFloat("domainpartslip", mDomainPartSlipValue, "SimulationLbm","mDomainPartSlipValue", false ); - - mIsoWeightMethod= mpSifAttrs->readInt("isoweightmethod", mIsoWeightMethod, "SimulationLbm","mIsoWeightMethod", false ); - mInitSurfaceSmoothing = mpSifAttrs->readInt("initsurfsmooth", mInitSurfaceSmoothing, "SimulationLbm","mInitSurfaceSmoothing", false ); - mSmoothSurface = mpSifAttrs->readFloat("smoothsurface", mSmoothSurface, "SimulationLbm","mSmoothSurface", false ); - mSmoothNormals = mpSifAttrs->readFloat("smoothnormals", mSmoothNormals, "SimulationLbm","mSmoothNormals", false ); - mFsSurfGenSetting = mpSifAttrs->readInt("fssurfgen", mFsSurfGenSetting, "SimulationLbm","mFsSurfGenSetting", false ); - - // refinement - mMaxRefine = mRefinementDesired; - mMaxRefine = mpSifAttrs->readInt("maxrefine", mMaxRefine ,"LbmFsgrSolver", "mMaxRefine", false); - if(mMaxRefine<0) mMaxRefine=0; - if(mMaxRefine>FSGR_MAXNOOFLEVELS) mMaxRefine=FSGR_MAXNOOFLEVELS-1; - mDisableStandingFluidInit = mpSifAttrs->readInt("disable_stfluidinit", mDisableStandingFluidInit,"LbmFsgrSolver", "mDisableStandingFluidInit", false); - mInit2dYZ = mpSifAttrs->readBool("init2dyz", mInit2dYZ,"LbmFsgrSolver", "mInit2dYZ", false); - mForceTadapRefine = mpSifAttrs->readInt("forcetadaprefine", mForceTadapRefine,"LbmFsgrSolver", "mForceTadapRefine", false); - - // demo mode settings - mFVHeight = mpSifAttrs->readFloat("fvolheight", mFVHeight, "LbmFsgrSolver","mFVHeight", false ); - // FIXME check needed? - mFVArea = mpSifAttrs->readFloat("fvolarea", mFVArea, "LbmFsgrSolver","mFArea", false ); - - // debugging - skip some time... - double starttimeskip = 0.; - starttimeskip = mpSifAttrs->readFloat("forcestarttimeskip", starttimeskip, "LbmFsgrSolver","starttimeskip", false ); - mSimulationTime += starttimeskip; - if(starttimeskip>0.) debMsgStd("LbmFsgrSolver::parseStdAttrList",DM_NOTIFY,"Used starttimeskip="<<starttimeskip<<", t="<<mSimulationTime, 1); - - mpControl->parseControldataAttrList(mpSifAttrs); - -#if LBM_INCLUDE_TESTSOLVERS==1 - mUseTestdata = 0; - mUseTestdata = mpSifAttrs->readBool("use_testdata", mUseTestdata,"LbmFsgrSolver", "mUseTestdata", false); - mpTest->parseTestdataAttrList(mpSifAttrs); -#ifdef ELBEEM_PLUGIN - mUseTestdata=1; // DEBUG -#endif // ELBEEM_PLUGIN - - mMpNum = mpSifAttrs->readInt("mpnum", mMpNum ,"LbmFsgrSolver", "mMpNum", false); - mMpIndex = mpSifAttrs->readInt("mpindex", mMpIndex ,"LbmFsgrSolver", "mMpIndex", false); - if(glob_mpactive) { - // used instead... - mMpNum = glob_mpnum; - mMpIndex = glob_mpindex; - } else { - glob_mpnum = mMpNum; - glob_mpindex = 0; - } - errMsg("LbmFsgrSolver::parseAttrList"," mpactive:"<<glob_mpactive<<", "<<glob_mpindex<<"/"<<glob_mpnum); - if(mMpNum>0) { - mUseTestdata=1; // needed in this case... - } - - errMsg("LbmFsgrSolver::LBM_INCLUDE_TESTSOLVERS","Active, mUseTestdata:"<<mUseTestdata<<" "); -#else // LBM_INCLUDE_TESTSOLVERS!=1 - // not testsolvers, off by default - mUseTestdata = 0; - if(mFarFieldSize>=2.) mUseTestdata=1; // equiv. to test solver check -#endif // LBM_INCLUDE_TESTSOLVERS!=1 - - mInitialCsmago = mpSifAttrs->readFloat("csmago", mInitialCsmago, "SimulationLbm","mInitialCsmago", false ); - // deprecated! - float mInitialCsmagoCoarse = 0.0; - mInitialCsmagoCoarse = mpSifAttrs->readFloat("csmago_coarse", mInitialCsmagoCoarse, "SimulationLbm","mInitialCsmagoCoarse", false ); -#if USE_LES==1 -#else // USE_LES==1 - debMsgStd("LbmFsgrSolver", DM_WARNING, "LES model switched off!",2); - mInitialCsmago = 0.0; -#endif // USE_LES==1 -} - - -/****************************************************************************** - * (part of enabling chapter 6 of "Free Surface Flows with Moving and Deforming Objects for LBM") - *****************************************************************************/ -void LbmFsgrSolver::setSurfGenSettings(short value) -{ - mFsSurfGenSetting = value; -} - - -/****************************************************************************** - * Initialize omegas and forces on all levels (for init/timestep change) - *****************************************************************************/ -void LbmFsgrSolver::initLevelOmegas() -{ - // no explicit settings - mOmega = mpParam->calculateOmega(mSimulationTime); - mGravity = vec2L( mpParam->calculateGravity(mSimulationTime) ); - mSurfaceTension = 0.; //mpParam->calculateSurfaceTension(); // unused - if(mInit2dYZ) { SWAPYZ(mGravity); } - - // check if last init was ok - LbmFloat gravDelta = norm(mGravity-mLastGravity); - //errMsg("ChannelAnimDebug","t:"<<mSimulationTime<<" om:"<<mOmega<<" - lom:"<<mLastOmega<<" gv:"<<mGravity<<" - "<<mLastGravity<<" , "<<gravDelta ); - if((mOmega == mLastOmega) && (gravDelta<=0.0)) return; - - if(mInitialCsmago<=0.0) { - if(OPT3D==1) { - errFatal("LbmFsgrSolver::initLevelOmegas","Csmago-LES = 0 not supported for optimized 3D version...",SIMWORLD_INITERROR); - return; - } - } - - LbmFloat fineCsmago = mInitialCsmago; - LbmFloat coarseCsmago = mInitialCsmago; - LbmFloat maxFineCsmago1 = 0.026; - LbmFloat maxCoarseCsmago1 = 0.029; // try stabilizing - LbmFloat maxFineCsmago2 = 0.028; - LbmFloat maxCoarseCsmago2 = 0.032; // try stabilizing some more - if((mMaxRefine==1)&&(mInitialCsmago<maxFineCsmago1)) { - fineCsmago = maxFineCsmago1; - coarseCsmago = maxCoarseCsmago1; - } - if((mMaxRefine>1)&&(mInitialCsmago<maxFineCsmago2)) { - fineCsmago = maxFineCsmago2; - coarseCsmago = maxCoarseCsmago2; - } - - - // use Tau instead of Omega for calculations - { // init base level - int i = mMaxRefine; - mLevel[i].omega = mOmega; - mLevel[i].timestep = mpParam->getTimestep(); - mLevel[i].lcsmago = fineCsmago; //CSMAGO_INITIAL; - mLevel[i].lcsmago_sqr = mLevel[i].lcsmago*mLevel[i].lcsmago; - mLevel[i].lcnu = (2.0* (1.0/mLevel[i].omega)-1.0) * (1.0/6.0); - } - - // init all sub levels - for(int i=mMaxRefine-1; i>=0; i--) { - //mLevel[i].omega = 2.0 * (mLevel[i+1].omega-0.5) + 0.5; - double nomega = 0.5 * ( (1.0/(double)mLevel[i+1].omega) -0.5) + 0.5; - nomega = 1.0/nomega; - mLevel[i].omega = (LbmFloat)nomega; - mLevel[i].timestep = 2.0 * mLevel[i+1].timestep; - mLevel[i].lcsmago = coarseCsmago; - mLevel[i].lcsmago_sqr = mLevel[i].lcsmago*mLevel[i].lcsmago; - mLevel[i].lcnu = (2.0* (1.0/mLevel[i].omega)-1.0) * (1.0/6.0); - } - - // for lbgk - mLevel[ mMaxRefine ].gravity = mGravity / mLevel[ mMaxRefine ].omega; - for(int i=mMaxRefine-1; i>=0; i--) { - // should be the same on all levels... - // for lbgk - mLevel[i].gravity = (mLevel[i+1].gravity * mLevel[i+1].omega) * 2.0 / mLevel[i].omega; - } - - mLastOmega = mOmega; - mLastGravity = mGravity; - // debug? invalidate old values... - mGravity = -100.0; - mOmega = -100.0; - - for(int i=0; i<=mMaxRefine; i++) { - if(!mSilent) { - errMsg("LbmFsgrSolver", "Level init "<<i<<" - sizes:"<<mLevel[i].lSizex<<","<<mLevel[i].lSizey<<","<<mLevel[i].lSizez<<" offs:"<<mLevel[i].lOffsx<<","<<mLevel[i].lOffsy<<","<<mLevel[i].lOffsz - <<" omega:"<<mLevel[i].omega<<" grav:"<<mLevel[i].gravity<< ", " - <<" cmsagp:"<<mLevel[i].lcsmago<<", " - << " ss"<<mLevel[i].timestep<<" ns"<<mLevel[i].nodeSize<<" cs"<<mLevel[i].simCellSize ); - } else { - if(!mInitDone) { - debMsgStd("LbmFsgrSolver", DM_MSG, "Level init "<<i<<" - sizes:"<<mLevel[i].lSizex<<","<<mLevel[i].lSizey<<","<<mLevel[i].lSizez<<" " - <<"omega:"<<mLevel[i].omega<<" grav:"<<mLevel[i].gravity , 5); - } - } - } - if(mMaxRefine>0) { - mDfScaleUp = (mLevel[0 ].timestep/mLevel[0+1].timestep)* (1.0/mLevel[0 ].omega-1.0)/ (1.0/mLevel[0+1].omega-1.0); // yu - mDfScaleDown = (mLevel[0+1].timestep/mLevel[0 ].timestep)* (1.0/mLevel[0+1].omega-1.0)/ (1.0/mLevel[0 ].omega-1.0); // yu - } -} - - -/****************************************************************************** - * Init Solver (values should be read from config file) - *****************************************************************************/ - -/*! finish the init with config file values (allocate arrays...) */ -bool LbmFsgrSolver::initializeSolverMemory() -{ - debMsgStd("LbmFsgrSolver::initialize",DM_MSG,"Init start... "<<mInitDone<<" "<<(void*)this,1); - - // init cppf stage - if(mCppfStage>0) { - mSizex *= mCppfStage; - mSizey *= mCppfStage; - mSizez *= mCppfStage; - } - if(mFsSurfGenSetting==-1) { - // all on - mFsSurfGenSetting = - fssgNormal | fssgNoNorth | fssgNoSouth | fssgNoEast | - fssgNoWest | fssgNoTop | fssgNoBottom | fssgNoObs ; - } - - // size inits to force cubic cells and mult4 level dimensions - // and make sure we dont allocate too much... - bool memOk = false; - int orgSx = mSizex; - int orgSy = mSizey; - int orgSz = mSizez; - double sizeReduction = 1.0; - double memEstFromFunc = -1.0; - double memEstFine = -1.0; - string memreqStr(""); - bool firstMInit = true; - int minitTries=0; - while(!memOk) { - minitTries++; - initGridSizes( mSizex, mSizey, mSizez, - mvGeoStart, mvGeoEnd, mMaxRefine, PARALLEL); - - // MPT -#if LBM_INCLUDE_TESTSOLVERS==1 - if(firstMInit) { - mrSetup(); - } -#else - (void)firstMInit; -#endif // LBM_INCLUDE_TESTSOLVERS==1 - firstMInit=false; - - calculateMemreqEstimate( mSizex, mSizey, mSizez, - mMaxRefine, mFarFieldSize, &memEstFromFunc, &memEstFine, &memreqStr ); - - bool noLimit = false; - double memLimit = 0.; - string memLimStr("-"); - if(sizeof(void*)==4) { - // 32bit system, limit to 2GB - memLimit = 2.0* 1024.0*1024.0*1024.0; - memLimStr = string("2GB"); - } else { - // 64bit, just take 16GB as limit for now... - // memLimit = 16.0* 1024.0*1024.0*1024.0; - // memLimStr = string("16GB"); - noLimit = true; - } - - // restrict max. chunk of 1 mem block to 1GB for windows - bool memBlockAllocProblem = false; - double maxDefaultMemChunk = 2.*1024.*1024.*1024.; - //std::cerr<<" memEstFine "<< memEstFine <<" maxWin:" <<maxWinMemChunk <<" maxMac:" <<maxMacMemChunk ; // DEBUG -#ifdef WIN32 - double maxWinMemChunk = 1100.*1024.*1024.; - if(sizeof(void *)==4 && memEstFine>maxWinMemChunk) { - memBlockAllocProblem = true; - } -#endif // WIN32 -#ifdef __APPLE__ - double maxMacMemChunk = 1200.*1024.*1024.; - if(memEstFine> maxMacMemChunk) { - memBlockAllocProblem = true; - } -#endif // Mac - if(sizeof(void*)==4 && memEstFine>maxDefaultMemChunk) { - // max memory chunk for 32bit systems 2gig - memBlockAllocProblem = true; - } - - if(!noLimit && (memEstFromFunc>memLimit || memBlockAllocProblem)) { - sizeReduction *= 0.9; - mSizex = (int)(orgSx * sizeReduction); - mSizey = (int)(orgSy * sizeReduction); - mSizez = (int)(orgSz * sizeReduction); - debMsgStd("LbmFsgrSolver::initialize",DM_WARNING,"initGridSizes: memory limit exceeded "<< - //memEstFromFunc<<"/"<<memLimit<<", "<< - //memEstFine<<"/"<<maxWinMemChunk<<", "<< - memreqStr<<"/"<<memLimStr<<", "<< - "retrying: "<<PRINT_VEC(mSizex,mSizey,mSizez)<<" org:"<<PRINT_VEC(orgSx,orgSy,orgSz) - , 3 ); - } else { - memOk = true; - } - } - - mPreviewFactor = (LbmFloat)mOutputSurfacePreview / (LbmFloat)mSizex; - debMsgStd("LbmFsgrSolver::initialize",DM_MSG,"initGridSizes: Final domain size X:"<<mSizex<<" Y:"<<mSizey<<" Z:"<<mSizez<< - ", Domain: "<<mvGeoStart<<":"<<mvGeoEnd<<", "<<(mvGeoEnd-mvGeoStart)<< - ", PointerSize: "<< sizeof(void*) << ", IntSize: "<< sizeof(int) << - ", est. Mem.Req.: "<<memreqStr ,2); - mpParam->setSize(mSizex, mSizey, mSizez); - if((minitTries>1)&&(glob_mpnum)) { errMsg("LbmFsgrSolver::initialize","Warning!!!!!!!!!!!!!!! Original gridsize changed........."); } - - debMsgStd("LbmFsgrSolver::initialize",DM_MSG,"Definitions: " - <<"LBM_EPSILON="<<LBM_EPSILON <<" " - <<"FSGR_STRICT_DEBUG="<<FSGR_STRICT_DEBUG <<" " - <<"OPT3D="<<OPT3D <<" " - <<"COMPRESSGRIDS="<<COMPRESSGRIDS<<" " - <<"MASS_INVALID="<<MASS_INVALID <<" " - <<"FSGR_LISTTRICK="<<FSGR_LISTTRICK <<" " - <<"FSGR_LISTTTHRESHEMPTY="<<FSGR_LISTTTHRESHEMPTY <<" " - <<"FSGR_LISTTTHRESHFULL="<<FSGR_LISTTTHRESHFULL <<" " - <<"FSGR_MAGICNR="<<FSGR_MAGICNR <<" " - <<"USE_LES="<<USE_LES <<" " - ,10); - - // perform 2D corrections... - if(LBMDIM == 2) mSizez = 1; - - mpParam->setSimulationMaxSpeed(0.0); - if(mFVHeight>0.0) mpParam->setFluidVolumeHeight(mFVHeight); - mpParam->setTadapLevels( mMaxRefine+1 ); - - if(mForceTadapRefine>mMaxRefine) { - mpParam->setTadapLevels( mForceTadapRefine+1 ); - debMsgStd("LbmFsgrSolver::initialize",DM_MSG,"Forcing a t-adap refine level of "<<mForceTadapRefine, 6); - } - - if(!mpParam->calculateAllMissingValues(mSimulationTime, false)) { - errFatal("LbmFsgrSolver::initialize","Fatal: failed to init parameters! Aborting...",SIMWORLD_INITERROR); - return false; - } - - - // init vectors - for(int i=0; i<=mMaxRefine; i++) { - mLevel[i].id = i; - mLevel[i].nodeSize = 0.0; - mLevel[i].simCellSize = 0.0; - mLevel[i].omega = 0.0; - mLevel[i].time = 0.0; - mLevel[i].timestep = 1.0; - mLevel[i].gravity = LbmVec(0.0); - mLevel[i].mprsCells[0] = NULL; - mLevel[i].mprsCells[1] = NULL; - mLevel[i].mprsFlags[0] = NULL; - mLevel[i].mprsFlags[1] = NULL; - - mLevel[i].avgOmega = 0.0; - mLevel[i].avgOmegaCnt = 0.0; - } - -#if PARALLEL == 1 - /* - // DG: this would be the correct sanity check, not the "hack below" */ - // if(( mSizey / mNumOMPThreads) * mNumOMPThreads != mSizey) { - // setNumOMPThreads(); - //} - if( mSizey < mNumOMPThreads ) { - setNumOMPThreads(mSizey); - } -#endif - - // init sizes - mLevel[mMaxRefine].lSizex = mSizex; - mLevel[mMaxRefine].lSizey = mSizey; - mLevel[mMaxRefine].lSizez = mSizez; - for(int i=mMaxRefine-1; i>=0; i--) { - mLevel[i].lSizex = mLevel[i+1].lSizex/2; - mLevel[i].lSizey = mLevel[i+1].lSizey/2; - mLevel[i].lSizez = mLevel[i+1].lSizez/2; - } - - // safety check - if(sizeof(CellFlagType) != CellFlagTypeSize) { - errFatal("LbmFsgrSolver::initialize","Fatal Error: CellFlagType has wrong size! Is:"<<sizeof(CellFlagType)<<", should be:"<<CellFlagTypeSize, SIMWORLD_GENERICERROR); - return false; - } - - double ownMemCheck = 0.0; - mLevel[ mMaxRefine ].nodeSize = ((mvGeoEnd[0]-mvGeoStart[0]) / (LbmFloat)(mSizex)); - mLevel[ mMaxRefine ].simCellSize = mpParam->getCellSize(); - mLevel[ mMaxRefine ].lcellfactor = 1.0; - LONGINT rcellSize = (LONGINT)((LONGINT)((LONGINT)mLevel[mMaxRefine].lSizex*(LONGINT)mLevel[mMaxRefine].lSizey*(LONGINT)mLevel[mMaxRefine].lSizez) * (LONGINT)dTotalNum); - -#if COMPRESSGRIDS==0 - mLevel[ mMaxRefine ].mprsCells[0] = new LbmFloat[ rcellSize +4 ]; - mLevel[ mMaxRefine ].mprsCells[1] = new LbmFloat[ rcellSize +4 ]; - ownMemCheck += 2 * sizeof(LbmFloat) * (rcellSize+4); -#else // COMPRESSGRIDS==0 - LONGINT compressOffset = (LONGINT)((LONGINT)mLevel[mMaxRefine].lSizex * (LONGINT)mLevel[mMaxRefine].lSizey * (LONGINT)dTotalNum * 2); - // LONGINT tmp = ( (rcellSize +compressOffset +4)/(1024*1024) )*sizeof(LbmFloat); - // printf("Debug MEMMMM excee: %I64d, %I64d, %I64d, %d, %d\n", tmp, compressOffset, rcellSize, mLevel[mMaxRefine].lSizex, mLevel[mMaxRefine].lSizey ); - mLevel[ mMaxRefine ].mprsCells[1] = new LbmFloat[ rcellSize +compressOffset +4 ]; - mLevel[ mMaxRefine ].mprsCells[0] = mLevel[ mMaxRefine ].mprsCells[1]+compressOffset; - ownMemCheck += sizeof(LbmFloat) * (rcellSize +compressOffset +4); -#endif // COMPRESSGRIDS==0 - - if(!mLevel[ mMaxRefine ].mprsCells[1] || !mLevel[ mMaxRefine ].mprsCells[0]) { - errFatal("LbmFsgrSolver::initialize","Fatal: Couldnt allocate memory (1)! Aborting...",SIMWORLD_INITERROR); - return false; - } - - // +4 for safety ? - mLevel[ mMaxRefine ].mprsFlags[0] = new CellFlagType[ rcellSize/dTotalNum +4 ]; - mLevel[ mMaxRefine ].mprsFlags[1] = new CellFlagType[ rcellSize/dTotalNum +4 ]; - ownMemCheck += 2 * sizeof(CellFlagType) * (rcellSize/dTotalNum +4); - if(!mLevel[ mMaxRefine ].mprsFlags[1] || !mLevel[ mMaxRefine ].mprsFlags[0]) { - errFatal("LbmFsgrSolver::initialize","Fatal: Couldnt allocate memory (2)! Aborting...",SIMWORLD_INITERROR); - -#if COMPRESSGRIDS==0 - delete[] mLevel[ mMaxRefine ].mprsCells[0]; - delete[] mLevel[ mMaxRefine ].mprsCells[1]; -#else // COMPRESSGRIDS==0 - delete[] mLevel[ mMaxRefine ].mprsCells[1]; -#endif // COMPRESSGRIDS==0 - return false; - } - - LbmFloat lcfdimFac = 8.0; - if(LBMDIM==2) lcfdimFac = 4.0; - for(int i=mMaxRefine-1; i>=0; i--) { - mLevel[i].nodeSize = 2.0 * mLevel[i+1].nodeSize; - mLevel[i].simCellSize = 2.0 * mLevel[i+1].simCellSize; - mLevel[i].lcellfactor = mLevel[i+1].lcellfactor * lcfdimFac; - - if(LBMDIM==2){ mLevel[i].lSizez = 1; } // 2D - rcellSize = ((mLevel[i].lSizex*mLevel[i].lSizey*mLevel[i].lSizez) *dTotalNum); - mLevel[i].mprsFlags[0] = new CellFlagType[ rcellSize/dTotalNum +4 ]; - mLevel[i].mprsFlags[1] = new CellFlagType[ rcellSize/dTotalNum +4 ]; - ownMemCheck += 2 * sizeof(CellFlagType) * (rcellSize/dTotalNum +4); - mLevel[i].mprsCells[0] = new LbmFloat[ rcellSize +4 ]; - mLevel[i].mprsCells[1] = new LbmFloat[ rcellSize +4 ]; - ownMemCheck += 2 * sizeof(LbmFloat) * (rcellSize+4); - } - - // isosurface memory, use orig res values - if(mFarFieldSize>0.) { - ownMemCheck += (double)( (3*sizeof(int)+sizeof(float)) * ((mSizex+2)*(mSizey+2)*(mSizez+2)) ); - } else { - // ignore 3 int slices... - ownMemCheck += (double)( ( sizeof(float)) * ((mSizex+2)*(mSizey+2)*(mSizez+2)) ); - } - - // sanity check -#if ELBEEM_PLUGIN!=1 - if(ABS(1.0-ownMemCheck/memEstFromFunc)>0.01) { - errMsg("LbmFsgrSolver::initialize","Sanity Error - memory estimate is off! real:"<<ownMemCheck<<" vs. estimate:"<<memEstFromFunc ); - } -#endif // ELBEEM_PLUGIN!=1 - - // init sizes for _all_ levels - for(int i=mMaxRefine; i>=0; i--) { - mLevel[i].lOffsx = mLevel[i].lSizex; - mLevel[i].lOffsy = mLevel[i].lOffsx*mLevel[i].lSizey; - mLevel[i].lOffsz = mLevel[i].lOffsy*mLevel[i].lSizez; - mLevel[i].setCurr = 0; - mLevel[i].setOther = 1; - mLevel[i].lsteps = 0; - mLevel[i].lmass = 0.0; - mLevel[i].lvolume = 0.0; - } - - // calc omega, force for all levels - initLevelOmegas(); - mMinTimestep = mpParam->getTimestep(); - mMaxTimestep = mpParam->getTimestep(); - - // init isosurf - mpIso->setIsolevel( mIsoValue ); -#if LBM_INCLUDE_TESTSOLVERS==1 - if(mUseTestdata) { - mpTest->setMaterialName( mpIso->getMaterialName() ); - delete mpIso; - mpIso = mpTest; - if(mpTest->mFarfMode>0) { // 3d off - mpTest->setIsolevel(-100.0); - } else { - mpTest->setIsolevel( mIsoValue ); - } - } -#endif // LBM_INCLUDE_TESTSOLVERS!=1 - // approximate feature size with mesh resolution - float featureSize = mLevel[ mMaxRefine ].nodeSize*0.5; - // smooth vars defined in solver_interface, set by simulation object - // reset for invalid values... - if((mSmoothSurface<0.)||(mSmoothSurface>50.)) mSmoothSurface = 1.; - if((mSmoothNormals<0.)||(mSmoothNormals>50.)) mSmoothNormals = 1.; - mpIso->setSmoothSurface( mSmoothSurface * featureSize ); - mpIso->setSmoothNormals( mSmoothNormals * featureSize ); - - // init iso weight values mIsoWeightMethod - int wcnt = 0; - float totw = 0.0; - for(int ak=-1;ak<=1;ak++) - for(int aj=-1;aj<=1;aj++) - for(int ai=-1;ai<=1;ai++) { - switch(mIsoWeightMethod) { - case 1: // light smoothing - mIsoWeight[wcnt] = sqrt(3.0) - sqrt( (LbmFloat)(ak*ak + aj*aj + ai*ai) ); - break; - case 2: // very light smoothing - mIsoWeight[wcnt] = sqrt(3.0) - sqrt( (LbmFloat)(ak*ak + aj*aj + ai*ai) ); - mIsoWeight[wcnt] *= mIsoWeight[wcnt]; - break; - case 3: // no smoothing - if(ai==0 && aj==0 && ak==0) mIsoWeight[wcnt] = 1.0; - else mIsoWeight[wcnt] = 0.0; - break; - default: // strong smoothing (=0) - mIsoWeight[wcnt] = 1.0; - break; - } - totw += mIsoWeight[wcnt]; - wcnt++; - } - for(int i=0; i<27; i++) mIsoWeight[i] /= totw; - - LbmVec isostart = vec2L(mvGeoStart); - LbmVec isoend = vec2L(mvGeoEnd); - int twodOff = 0; // 2d slices - if(LBMDIM==2) { - LbmFloat sn,se; - sn = isostart[2]+(isoend[2]-isostart[2])*0.5 - ((isoend[0]-isostart[0]) / (LbmFloat)(mSizex+1.0))*0.5; - se = isostart[2]+(isoend[2]-isostart[2])*0.5 + ((isoend[0]-isostart[0]) / (LbmFloat)(mSizex+1.0))*0.5; - isostart[2] = sn; - isoend[2] = se; - twodOff = 2; - } - int isosx = mSizex+2; - int isosy = mSizey+2; - int isosz = mSizez+2+twodOff; - - // MPT -#if LBM_INCLUDE_TESTSOLVERS==1 - //if( strstr( this->getName().c_str(), "mpfluid1" ) != NULL) { - if( (mMpNum>0) && (mMpIndex==0) ) { - //? mpindex==0 - // restore original value for node0 - isosx = mOrgSizeX + 2; - isostart[0] = mOrgStartX; - isoend[0] = mOrgEndX; - } - errMsg("LbmFsgrSolver::initialize", "MPT: gcon "<<mMpNum<<","<<mMpIndex<<" src"<< PRINT_VEC(mpTest->mGCMin.mSrcx,mpTest->mGCMin.mSrcy,mpTest->mGCMin.mSrcz)<<" dst" - << PRINT_VEC(mpTest->mGCMin.mDstx,mpTest->mGCMin.mDsty,mpTest->mGCMin.mDstz)<<" consize" - << PRINT_VEC(mpTest->mGCMin.mConSizex,mpTest->mGCMin.mConSizey,mpTest->mGCMin.mConSizez)<<" "); - errMsg("LbmFsgrSolver::initialize", "MPT: gcon "<<mMpNum<<","<<mMpIndex<<" src"<< PRINT_VEC(mpTest->mGCMax.mSrcx,mpTest->mGCMax.mSrcy,mpTest->mGCMax.mSrcz)<<" dst" - << PRINT_VEC(mpTest->mGCMax.mDstx,mpTest->mGCMax.mDsty,mpTest->mGCMax.mDstz)<<" consize" - << PRINT_VEC(mpTest->mGCMax.mConSizex,mpTest->mGCMax.mConSizey,mpTest->mGCMax.mConSizez)<<" "); -#endif // LBM_INCLUDE_TESTSOLVERS==1 - - errMsg(" SETISO ", "iso "<<isostart<<" - "<<isoend<<" "<<(((isoend[0]-isostart[0]) / (LbmFloat)(mSizex+1.0))*0.5)<<" "<<(LbmFloat)(mSizex+1.0) ); - errMsg("LbmFsgrSolver::initialize", "MPT: geo "<< mvGeoStart<<","<<mvGeoEnd<< - " grid:"<<PRINT_VEC(mSizex,mSizey,mSizez)<<",iso:"<< PRINT_VEC(isosx,isosy,isosz) ); - mpIso->setStart( vec2G(isostart) ); - mpIso->setEnd( vec2G(isoend) ); - LbmVec isodist = isoend-isostart; - - int isosubs = mIsoSubdivs; - if(mFarFieldSize>1.) { - errMsg("LbmFsgrSolver::initialize","Warning - resetting isosubdivs, using fulledge!"); - isosubs = 1; - mpIso->setUseFulledgeArrays(true); - } - mpIso->setSubdivs(isosubs); - - mpIso->initializeIsosurface( isosx,isosy,isosz, vec2G(isodist) ); - - // reset iso field - for(int ak=0;ak<isosz;ak++) - for(int aj=0;aj<isosy;aj++) - for(int ai=0;ai<isosx;ai++) { *mpIso->getData(ai,aj,ak) = 0.0; } - - - /* init array (set all invalid first) */ - preinitGrids(); - for(int lev=0; lev<=mMaxRefine; lev++) { - FSGR_FORIJK_BOUNDS(lev) { - RFLAG(lev,i,j,k,0) = 0, RFLAG(lev,i,j,k,0) = 0; // reset for changeFlag usage - if(!mAllfluid) { - initEmptyCell(lev, i,j,k, CFEmpty, -1.0, -1.0); - } else { - initEmptyCell(lev, i,j,k, CFFluid, 1.0, 1.0); - } - } - } - - - if(LBMDIM==2) { - if(mOutputSurfacePreview) { - errMsg("LbmFsgrSolver::init","No preview in 2D allowed!"); - mOutputSurfacePreview = 0; } - } - if((glob_mpactive) && (glob_mpindex>0)) { - mOutputSurfacePreview = 0; - } - -#if LBM_USE_GUI==1 - if(mOutputSurfacePreview) { - errMsg("LbmFsgrSolver::init","No preview in GUI mode... mOutputSurfacePreview=0"); - mOutputSurfacePreview = 0; } -#endif // LBM_USE_GUI==1 - if(mOutputSurfacePreview) { - // same as normal one, but use reduced size - mpPreviewSurface = new IsoSurface( mIsoValue ); - mpPreviewSurface->setMaterialName( mpPreviewSurface->getMaterialName() ); - mpPreviewSurface->setIsolevel( mIsoValue ); - // usually dont display for rendering - mpPreviewSurface->setVisible( false ); - - mpPreviewSurface->setStart( vec2G(isostart) ); - mpPreviewSurface->setEnd( vec2G(isoend) ); - LbmVec pisodist = isoend-isostart; - LbmFloat pfac = mPreviewFactor; - mpPreviewSurface->initializeIsosurface( (int)(pfac*mSizex)+2, (int)(pfac*mSizey)+2, (int)(pfac*mSizez)+2, vec2G(pisodist) ); - //mpPreviewSurface->setName( getName() + "preview" ); - mpPreviewSurface->setName( "preview" ); - - debMsgStd("LbmFsgrSolver::initialize",DM_MSG,"Preview with sizes "<<(pfac*mSizex)<<","<<(pfac*mSizey)<<","<<(pfac*mSizez)<<" enabled",10); - } - - // init defaults - mAvgNumUsedCells = 0; - mFixMass= 0.0; - return true; -} - -/*! init solver arrays */ -bool LbmFsgrSolver::initializeSolverGrids() { - /* init boundaries */ - debMsgStd("LbmFsgrSolver::initialize",DM_MSG,"Boundary init...",10); - // init obstacles, and reinit time step size - initGeometryFlags(); - mLastSimTime = -1.0; - // TODO check for invalid cells? nitGenericTestCases(); - - // new - init noslip 1 everywhere... - // half fill boundary cells? - - CellFlagType domainBoundType = CFInvalid; - // TODO use normal object types instad... - if(mDomainBound.find(string("free")) != string::npos) { - domainBoundType = CFBnd | CFBndFreeslip; - debMsgStd("LbmFsgrSolver::initialize",DM_MSG,"Domain Boundary Type: FreeSlip, value:"<<mDomainBound,10); - } else if(mDomainBound.find(string("part")) != string::npos) { - domainBoundType = CFBnd | CFBndPartslip; // part slip type - debMsgStd("LbmFsgrSolver::initialize",DM_MSG,"Domain Boundary Type: PartSlip ("<<mDomainPartSlipValue<<"), value:"<<mDomainBound,10); - } else { - domainBoundType = CFBnd | CFBndNoslip; - debMsgStd("LbmFsgrSolver::initialize",DM_MSG,"Domain Boundary Type: NoSlip, value:"<<mDomainBound,10); - } - - // use ar[numobjs] as entry for domain (used e.g. for mDomainPartSlipValue in mObjectPartslips) - int domainobj = (int)(mpGiObjects->size()); - domainBoundType |= (domainobj<<24); - //for(int i=0; i<(int)(domainobj+0); i++) { - //errMsg("GEOIN","i"<<i<<" "<<(*mpGiObjects)[i]->getName()); - //if((*mpGiObjects)[i] == mpIso) { //check... - //} - //} - //errMsg("GEOIN"," dm "<<(domainBoundType>>24)); - - for(int k=0;k<mLevel[mMaxRefine].lSizez;k++) - for(int i=0;i<mLevel[mMaxRefine].lSizex;i++) { - initEmptyCell(mMaxRefine, i,0,k, domainBoundType, 0.0, BND_FILL); - initEmptyCell(mMaxRefine, i,mLevel[mMaxRefine].lSizey-1,k, domainBoundType, 0.0, BND_FILL); - } - - for(int k=0;k<mLevel[mMaxRefine].lSizez;k++) - for(int j=0;j<mLevel[mMaxRefine].lSizey;j++) { - initEmptyCell(mMaxRefine, 0,j,k, domainBoundType, 0.0, BND_FILL); - initEmptyCell(mMaxRefine, mLevel[mMaxRefine].lSizex-1,j,k, domainBoundType, 0.0, BND_FILL); - // DEBUG BORDER! - //initEmptyCell(mMaxRefine, mLevel[mMaxRefine].lSizex-2,j,k, domainBoundType, 0.0, BND_FILL); - } - - if(LBMDIM == 3) { - // only for 3D - for(int j=0;j<mLevel[mMaxRefine].lSizey;j++) - for(int i=0;i<mLevel[mMaxRefine].lSizex;i++) { - initEmptyCell(mMaxRefine, i,j,0, domainBoundType, 0.0, BND_FILL); - initEmptyCell(mMaxRefine, i,j,mLevel[mMaxRefine].lSizez-1, domainBoundType, 0.0, BND_FILL); - } - } - - // TEST!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!11 - /*for(int k=0;k<mLevel[mMaxRefine].lSizez;k++) - for(int j=0;j<mLevel[mMaxRefine].lSizey;j++) { - initEmptyCell(mMaxRefine, mLevel[mMaxRefine].lSizex-2,j,k, domainBoundType, 0.0, BND_FILL); - } - for(int k=0;k<mLevel[mMaxRefine].lSizez;k++) - for(int i=0;i<mLevel[mMaxRefine].lSizex;i++) { - initEmptyCell(mMaxRefine, i,1,k, domainBoundType, 0.0, BND_FILL); - } - // */ - - /*for(int ii=0; ii<(int)po w_change?(2.0,mMaxRefine)-1; ii++) { - errMsg("BNDTESTSYMM","set "<<mLevel[mMaxRefine].lSizex-2-ii ); - for(int k=0;k<mLevel[mMaxRefine].lSizez;k++) - for(int j=0;j<mLevel[mMaxRefine].lSizey;j++) { - initEmptyCell(mMaxRefine, mLevel[mMaxRefine].lSizex-2-ii,j,k, domainBoundType, 0.0, BND_FILL); // SYMM!? 2D? - } - for(int j=0;j<mLevel[mMaxRefine].lSizey;j++) - for(int i=0;i<mLevel[mMaxRefine].lSizex;i++) { - initEmptyCell(mMaxRefine, i,j,mLevel[mMaxRefine].lSizez-2-ii, domainBoundType, 0.0, BND_FILL); // SYMM!? 3D? - } - } - // Symmetry tests */ - // vortt -#if LBM_INCLUDE_TESTSOLVERS==1 - if(( strstr( this->getName().c_str(), "vorttfluid" ) != NULL) && (LBMDIM==2)) { - errMsg("VORTT","init"); - int level=mMaxRefine; - int cx = mLevel[level].lSizex/2; - int cyo = mLevel[level].lSizey/2; - int sx = mLevel[level].lSizex/8; - int sy = mLevel[level].lSizey/8; - LbmFloat rho = 1.; - LbmFloat rhomass = 1.; - LbmFloat uFactor = 0.15; - LbmFloat vdist = 1.0; - - int cy1=cyo-(int)(vdist*sy); - int cy2=cyo+(int)(vdist*sy); - - //for(int j=cy-sy;j<cy+sy;j++) for(int i=cx-sx;i<cx+sx;i++) { - for(int j=1;j<mLevel[level].lSizey-1;j++) - for(int i=1;i<mLevel[level].lSizex-1;i++) { - LbmFloat d1 = norm(LbmVec(cx,cy1,0.)-LbmVec(i,j,0)); - LbmFloat d2 = norm(LbmVec(cx,cy2,0.)-LbmVec(i,j,0)); - bool in1 = (d1<=(LbmFloat)(sx)); - bool in2 = (d2<=(LbmFloat)(sx)); - LbmVec uvec(0.); - LbmVec v1 = getNormalized( cross( LbmVec(cx,cy1,0.)-LbmVec(i,j,0), LbmVec(0.,0.,1.)) )* uFactor; - LbmVec v2 = getNormalized( cross( LbmVec(cx,cy2,0.)-LbmVec(i,j,0), LbmVec(0.,0.,1.)) )* uFactor; - LbmFloat w1=1., w2=1.; - if(!in1) w1=(LbmFloat)(sx)/(1.5*d1); - if(!in2) w2=(LbmFloat)(sx)/(1.5*d2); - if(!in1) w1=0.; if(!in2) w2=0.; // sharp falloff - uvec += v1*w1; - uvec += v2*w2; - initVelocityCell(level, i,j,0, CFFluid, rho, rhomass, uvec ); - //errMsg("VORTT","init uvec"<<uvec); - } - - } -#endif // LBM_INCLUDE_TESTSOLVERS==1 - - //if(getGlobalBakeState()<0) { CAUSE_PANIC; errMsg("LbmFsgrSolver::initialize","Got abort signal1, causing panic, aborting..."); return false; } - - // prepare interface cells - initFreeSurfaces(); - initStandingFluidGradient(); - - // perform first step to init initial mass - mInitialMass = 0.0; - int inmCellCnt = 0; - FSGR_FORIJK1(mMaxRefine) { - if( RFLAG(mMaxRefine, i,j,k, mLevel[mMaxRefine].setCurr)& CFFluid) { - LbmFloat fluidRho = QCELL(mMaxRefine, i,j,k, mLevel[mMaxRefine].setCurr, 0); - FORDF1 { fluidRho += QCELL(mMaxRefine, i,j,k, mLevel[mMaxRefine].setCurr, l); } - mInitialMass += fluidRho; - inmCellCnt ++; - } else if( RFLAG(mMaxRefine, i,j,k, mLevel[mMaxRefine].setCurr)& CFInter) { - mInitialMass += QCELL(mMaxRefine, i,j,k, mLevel[mMaxRefine].setCurr, dMass); - inmCellCnt ++; - } - } - mCurrentVolume = mCurrentMass = mInitialMass; - - ParamVec cspv = mpParam->calculateCellSize(); - if(LBMDIM==2) cspv[2] = 1.0; - inmCellCnt = 1; - double nrmMass = (double)mInitialMass / (double)(inmCellCnt) *cspv[0]*cspv[1]*cspv[2] * 1000.0; - debMsgStd("LbmFsgrSolver::initialize",DM_MSG,"Initial Mass:"<<mInitialMass<<" normalized:"<<nrmMass, 3); - mInitialMass = 0.0; // reset, and use actual value after first step - - //mStartSymm = false; -#if ELBEEM_PLUGIN!=1 - if((LBMDIM==2)&&(mSizex<200)) { - if(!checkSymmetry("init")) { - errMsg("LbmFsgrSolver::initialize","Unsymmetric init..."); - } else { - errMsg("LbmFsgrSolver::initialize","Symmetric init!"); - } - } -#endif // ELBEEM_PLUGIN!=1 - return true; -} - - -/*! prepare actual simulation start, setup viz etc */ -bool LbmFsgrSolver::initializeSolverPostinit() { - // coarsen region - myTime_t fsgrtstart = getTime(); - for(int lev=mMaxRefine-1; lev>=0; lev--) { - debMsgStd("LbmFsgrSolver::initialize",DM_MSG,"Coarsening level "<<lev<<".",8); - adaptGrid(lev); - coarseRestrictFromFine(lev); - adaptGrid(lev); - coarseRestrictFromFine(lev); - } - markedClearList(); - myTime_t fsgrtend = getTime(); - if(!mSilent){ debMsgStd("LbmFsgrSolver::initialize",DM_MSG,"FSGR init done ("<< getTimeString(fsgrtend-fsgrtstart)<<"), changes:"<<mNumFsgrChanges , 10 ); } - mNumFsgrChanges = 0; - - for(int l=0; l<cDirNum; l++) { - LbmFloat area = 0.5 * 0.5 *0.5; - if(LBMDIM==2) area = 0.5 * 0.5; - - if(dfVecX[l]!=0) area *= 0.5; - if(dfVecY[l]!=0) area *= 0.5; - if(dfVecZ[l]!=0) area *= 0.5; - mFsgrCellArea[l] = area; - } // l - - // make sure both sets are ok - // copy from other to curr - for(int lev=0; lev<=mMaxRefine; lev++) { - FSGR_FORIJK_BOUNDS(lev) { - RFLAG(lev, i,j,k,mLevel[lev].setOther) = RFLAG(lev, i,j,k,mLevel[lev].setCurr); - } } // first copy flags */ - - - // old mpPreviewSurface init - //if(getGlobalBakeState()<0) { CAUSE_PANIC; errMsg("LbmFsgrSolver::initialize","Got abort signal2, causing panic, aborting..."); return false; } - // make sure fill fracs are right for first surface generation - stepMain(); - - // prepare once... - mpIso->setParticles(mpParticles, mPartDropMassSub); - debMsgStd("LbmFsgrSolver::initialize",DM_MSG,"Iso Settings, subdivs="<<mpIso->getSubdivs()<<", partsize="<<mPartDropMassSub, 9); - prepareVisualization(); - // copy again for stats counting - for(int lev=0; lev<=mMaxRefine; lev++) { - FSGR_FORIJK_BOUNDS(lev) { - RFLAG(lev, i,j,k,mLevel[lev].setOther) = RFLAG(lev, i,j,k,mLevel[lev].setCurr); - } } // first copy flags */ - - - // now really done... - debMsgStd("LbmFsgrSolver::initialize",DM_MSG,"SurfaceGen: SmsOrg("<<mSmoothSurface<<","<<mSmoothNormals<< /*","<<featureSize<<*/ "), Iso("<<mpIso->getSmoothSurface()<<","<<mpIso->getSmoothNormals()<<") ",10); - debMsgStd("LbmFsgrSolver::initialize",DM_MSG,"Init done ... ",10); - mInitDone = 1; - - // init fluid control - initCpdata(); - -#if LBM_INCLUDE_TESTSOLVERS==1 - initTestdata(); -#endif // ELBEEM_PLUGIN!=1 - // not inited? dont use... - if(mCutoff<0) mCutoff=0; - - initParticles(); - return true; -} - - - -// macros for mov obj init -#if LBMDIM==2 - -#define POS2GRID_CHECK(vec,n) \ - monTotal++;\ - int k=(int)( ((vec)[n][2]-iniPos[2])/dvec[2] +0.0); \ - if(k!=0) continue; \ - const int i=(int)( ((vec)[n][0]-iniPos[0])/dvec[0] +0.0); \ - if(i<=0) continue; \ - if(i>=mLevel[level].lSizex-1) continue; \ - const int j=(int)( ((vec)[n][1]-iniPos[1])/dvec[1] +0.0); \ - if(j<=0) continue; \ - if(j>=mLevel[level].lSizey-1) continue; \ - -#else // LBMDIM -> 3 -#define POS2GRID_CHECK(vec,n) \ - monTotal++;\ - const int i=(int)( ((vec)[n][0]-iniPos[0])/dvec[0] +0.0); \ - if(i<=0) continue; \ - if(i>=mLevel[level].lSizex-1) continue; \ - const int j=(int)( ((vec)[n][1]-iniPos[1])/dvec[1] +0.0); \ - if(j<=0) continue; \ - if(j>=mLevel[level].lSizey-1) continue; \ - const int k=(int)( ((vec)[n][2]-iniPos[2])/dvec[2] +0.0); \ - if(k<=0) continue; \ - if(k>=mLevel[level].lSizez-1) continue; \ - -#endif // LBMDIM - -// calculate object velocity from vert arrays in objvel vec -#define OBJVEL_CALC \ - LbmVec objvel = vec2L((mMOIVertices[n]-mMOIVerticesOld[n]) /dvec); { \ - const LbmFloat usqr = (objvel[0]*objvel[0]+objvel[1]*objvel[1]+objvel[2]*objvel[2])*1.5; \ - USQRMAXCHECK(usqr, objvel[0],objvel[1],objvel[2], mMaxVlen, mMxvx,mMxvy,mMxvz); \ - if(usqr>maxusqr) { \ - /* cutoff at maxVelVal */ \ - for(int jj=0; jj<3; jj++) { \ - if(objvel[jj]>0.) objvel[jj] = maxVelVal; \ - if(objvel[jj]<0.) objvel[jj] = -maxVelVal; \ - } \ - } } \ - if(ntype&(CFBndFreeslip)) { \ - const LbmFloat dp=dot(objvel, vec2L((*pNormals)[n]) ); \ - /* const LbmVec oldov=objvel; */ /*DEBUG*/ \ - objvel = vec2L((*pNormals)[n]) *dp; \ - /* if((j==24)&&(n%5==2)) errMsg("FSBT","n"<<n<<" v"<<objvel<<" nn"<<(*pNormals)[n]<<" dp"<<dp<<" oldov"<<oldov ); */ \ - } \ - else if(ntype&(CFBndPartslip)) { \ - const LbmFloat dp=dot(objvel, vec2L((*pNormals)[n]) ); \ - /* const LbmVec oldov=objvel; */ /*DEBUG*/ \ - /* if((j==24)&&(n%5==2)) errMsg("FSBT","n"<<n<<" v"<<objvel<<" nn"<<(*pNormals)[n]<<" dp"<<dp<<" oldov"<<oldov ); */ \ - const LbmFloat partv = mObjectPartslips[OId]; \ - /*errMsg("PARTSLIP_DEBUG","l="<<l<<" ccel="<<RAC(ccel, dfInv[l] )<<" partv="<<partv<<",id="<<(int)(mnbf>>24)<<" newval="<<newval ); / part slip debug */ \ - /* m[l] = (RAC(ccel, dfInv[l] ) ) * partv + newval * (1.-partv); part slip */ \ - objvel = objvel*partv + vec2L((*pNormals)[n]) *dp*(1.-partv); \ - } - -#define TTT \ - - -/*****************************************************************************/ -//! init moving obstacles for next sim step sim -/*****************************************************************************/ -void LbmFsgrSolver::initMovingObstacles(bool staticInit) { - myTime_t monstart = getTime(); - - // movobj init - const int level = mMaxRefine; - const int workSet = mLevel[level].setCurr; - const int otherSet = mLevel[level].setOther; - LbmFloat sourceTime = mSimulationTime; // should be equal to mLastSimTime! - // for debugging - check targetTime check during DEFAULT STREAM - LbmFloat targetTime = mSimulationTime + mpParam->getTimestep(); - if(mLastSimTime == targetTime) { - debMsgStd("LbmFsgrSolver::initMovingObstacles",DM_WARNING,"Called for same time! (t="<<mSimulationTime<<" , targett="<<targetTime<<")", 1); - return; - } - //debMsgStd("LbmFsgrSolver::initMovingObstacles",DM_WARNING,"time: "<<mSimulationTime<<" lasttt:"<<mLastSimTime,10); - //if(mSimulationTime!=mLastSimTime) errMsg("LbmFsgrSolver::initMovingObstacles","time: "<<mSimulationTime<<" lasttt:"<<mLastSimTime); - - const LbmFloat maxVelVal = 0.1666; - const LbmFloat maxusqr = maxVelVal*maxVelVal*3. *1.5; - - LbmFloat rhomass = 0.0; - CellFlagType otype = CFInvalid; // verify type of last step, might be non moving obs! - CellFlagType ntype = CFInvalid; - // WARNING - copied from geo init! - int numobjs = (int)(mpGiObjects->size()); - ntlVec3Gfx dvec = ntlVec3Gfx(mLevel[level].nodeSize); //dvec*1.0; - // 2d display as rectangles - ntlVec3Gfx iniPos(0.0); - if(LBMDIM==2) { - dvec[2] = 1.0; - iniPos = (mvGeoStart + ntlVec3Gfx( 0.0, 0.0, (mvGeoEnd[2]-mvGeoStart[2])*0.5 ))-(dvec*0.0); - } else { - iniPos = (mvGeoStart + ntlVec3Gfx( 0.0 ))-(dvec*0.0); - } - - if( (int)mObjectMassMovnd.size() < numobjs) { - for(int i=mObjectMassMovnd.size(); i<numobjs; i++) { - mObjectMassMovnd.push_back(0.); - } - } - - // stats - int monPoints=0, monObsts=0, monFluids=0, monTotal=0, monTrafo=0; - int nbored; - for(int OId=0; OId<numobjs; OId++) { - ntlGeometryObject *obj = (*mpGiObjects)[OId]; - bool skip = false; - if(obj->getGeoInitId() != mLbmInitId) skip=true; - if( (!staticInit) && (!obj->getIsAnimated()) ) skip=true; - if( ( staticInit) && ( obj->getIsAnimated()) ) skip=true; - if(skip) continue; - debMsgStd("LbmFsgrSolver::initMovingObstacles",DM_MSG," obj "<<obj->getName()<<" skip:"<<skip<<", static:"<<staticInit<<" anim:"<<obj->getIsAnimated()<<" gid:"<<obj->getGeoInitId()<<" simgid:"<<mLbmInitId, 10); - - if( (obj->getGeoInitType()&FGI_ALLBOUNDS) || - ((obj->getGeoInitType()&FGI_FLUID) && staticInit) ) { - - otype = ntype = CFInvalid; - switch(obj->getGeoInitType()) { - /* case FGI_BNDPART: // old, use noslip for moving part/free objs - case FGI_BNDFREE: - if(!staticInit) { - errMsg("LbmFsgrSolver::initMovingObstacles","Warning - moving free/part slip objects NYI "<<obj->getName() ); - otype = ntype = CFBnd|CFBndNoslip; - } else { - if(obj->getGeoInitType()==FGI_BNDPART) otype = ntype = CFBnd|CFBndPartslip; - if(obj->getGeoInitType()==FGI_BNDFREE) otype = ntype = CFBnd|CFBndFreeslip; - } - break; - // off */ - case FGI_BNDPART: rhomass = BND_FILL; - otype = ntype = CFBnd|CFBndPartslip|(OId<<24); - break; - case FGI_BNDFREE: rhomass = BND_FILL; - otype = ntype = CFBnd|CFBndFreeslip|(OId<<24); - break; - // off */ - case FGI_BNDNO: rhomass = BND_FILL; - otype = ntype = CFBnd|CFBndNoslip|(OId<<24); - break; - case FGI_FLUID: - otype = ntype = CFFluid; - break; - case FGI_MBNDINFLOW: - otype = ntype = CFMbndInflow; - break; - case FGI_MBNDOUTFLOW: - otype = ntype = CFMbndOutflow; - break; - } - int wasActive = ((obj->getGeoActive(sourceTime)>0.)? 1:0); - int active = ((obj->getGeoActive(targetTime)>0.)? 1:0); - //errMsg("GEOACTT"," obj "<<obj->getName()<<" a:"<<active<<","<<wasActive<<" s"<<sourceTime<<" t"<<targetTime <<" v"<<mObjectSpeeds[OId] ); - // skip inactive in/out flows - if(ntype==CFInvalid){ errMsg("LbmFsgrSolver::initMovingObstacles","Invalid obj type "<<obj->getGeoInitType()); continue; } - if((!active) && (otype&(CFMbndOutflow|CFMbndInflow)) ) continue; - - // copied from recalculateObjectSpeeds - mObjectSpeeds[OId] = vec2L(mpParam->calculateLattVelocityFromRw( vec2P( (*mpGiObjects)[OId]->getInitialVelocity(mSimulationTime) ))); - debMsgStd("LbmFsgrSolver::initMovingObstacles",DM_MSG,"id"<<OId<<" "<<obj->getName()<<" inivel set to "<< mObjectSpeeds[OId]<<", unscaled:"<< (*mpGiObjects)[OId]->getInitialVelocity(mSimulationTime) ,10 ); - - //vector<ntlVec3Gfx> tNormals; - vector<ntlVec3Gfx> *pNormals = NULL; - mMOINormals.clear(); - if(ntype&(CFBndFreeslip|CFBndPartslip)) { pNormals = &mMOINormals; } - - mMOIVertices.clear(); - if(obj->getMeshAnimated()) { - // do two full update - // TODO tNormals handling!? - mMOIVerticesOld.clear(); - obj->initMovingPointsAnim(sourceTime,mMOIVerticesOld, targetTime, mMOIVertices, pNormals, mLevel[mMaxRefine].nodeSize, mvGeoStart, mvGeoEnd); - monTrafo += mMOIVerticesOld.size(); - obj->applyTransformation(sourceTime, &mMOIVerticesOld,pNormals, 0, mMOIVerticesOld.size(), false ); - monTrafo += mMOIVertices.size(); - obj->applyTransformation(targetTime, &mMOIVertices,NULL /* no old normals needed */, 0, mMOIVertices.size(), false ); - } else { - // only do transform update - obj->getMovingPoints(mMOIVertices,pNormals); // mMOIVertices = mCachedMovPoints - mMOIVerticesOld = mMOIVertices; - // WARNING - assumes mSimulationTime is global!? - obj->applyTransformation(targetTime, &mMOIVertices,pNormals, 0, mMOIVertices.size(), false ); - monTrafo += mMOIVertices.size(); - - // correct flags from last position, but extrapolate - // velocity to next timestep - obj->applyTransformation(sourceTime, &mMOIVerticesOld, NULL /* no old normals needed */, 0, mMOIVerticesOld.size(), false ); - monTrafo += mMOIVerticesOld.size(); - } - - // object types - if(ntype&CFBnd){ - - // check if object is moving at all - if(obj->getIsAnimated()) { - ntlVec3Gfx objMaxVel = obj->calculateMaxVel(sourceTime,targetTime); - // FIXME? - if(normNoSqrt(objMaxVel)>0.0) { ntype |= CFBndMoving; } - // get old type - CHECK FIXME , timestep could have changed - cause trouble? - ntlVec3Gfx oldobjMaxVel = obj->calculateMaxVel(sourceTime - mpParam->getTimestep(),sourceTime); - if(normNoSqrt(oldobjMaxVel)>0.0) { otype |= CFBndMoving; } - } - if(obj->getMeshAnimated()) { ntype |= CFBndMoving; otype |= CFBndMoving; } - CellFlagType rflagnb[27]; - LbmFloat massCheck = 0.; - int massReinits=0; - bool fillCells = (mObjectMassMovnd[OId]<=-1.); - LbmFloat impactCorrFactor = obj->getGeoImpactFactor(targetTime); - - - // first pass - set new obs. cells - if(active) { - for(size_t n=0; n<mMOIVertices.size(); n++) { - //errMsg("initMovingObstacles_Debug","OId"<<OId<<" n"<<n<<" -> "<<PRINT_IJK); - POS2GRID_CHECK(mMOIVertices,n); - //{ errMsg("initMovingObstacles_Debug","OId"<<OId<<" n"<<n<<" -> "<<PRINT_IJK<<", t="<<targetTime); } - if(QCELL(level, i,j,k, workSet, dFlux)==targetTime) continue; - monPoints++; - - // check mass - if(RFLAG(level, i,j,k, workSet)&(CFFluid)) { - FORDF0 { massCheck -= QCELL(level, i,j,k, workSet, l); } - massReinits++; - } - else if(RFLAG(level, i,j,k, workSet)&(CFInter)) { - massCheck -= QCELL(level, i,j,k, workSet, dMass); - massReinits++; - } - - RFLAG(level, i,j,k, workSet) = ntype; - FORDF1 { - //CellFlagType flag = RFLAG_NB(level, i,j,k,workSet,l); - rflagnb[l] = RFLAG_NB(level, i,j,k,workSet,l); - if(rflagnb[l]&(CFFluid|CFInter)) { - rflagnb[l] &= (~CFNoBndFluid); // remove CFNoBndFluid flag - RFLAG_NB(level, i,j,k,workSet,l) &= rflagnb[l]; - } - } - LbmFloat *dstCell = RACPNT(level, i,j,k,workSet); - RAC(dstCell,0) = 0.0; - if(ntype&CFBndMoving) { - OBJVEL_CALC; - - // compute fluid acceleration - FORDF1 { - if(rflagnb[l]&(CFFluid|CFInter)) { - const LbmFloat ux = dfDvecX[l]*objvel[0]; - const LbmFloat uy = dfDvecY[l]*objvel[1]; - const LbmFloat uz = dfDvecZ[l]*objvel[2]; - - LbmFloat factor = 2. * dfLength[l] * 3.0 * (ux+uy+uz); // - if(ntype&(CFBndFreeslip|CFBndPartslip)) { - // missing, diag mass checks... - //if(l<=LBMDIM*2) factor *= 1.4142; - factor *= 2.0; // TODO, optimize - } else { - factor *= 1.2; // TODO, optimize - } - factor *= impactCorrFactor; // use manual tweaking channel - RAC(dstCell,l) = factor; - massCheck += factor; - } else { - RAC(dstCell,l) = 0.; - } - } - -#if NEWDIRVELMOTEST==1 - FORDF1 { RAC(dstCell,l) = 0.; } - RAC(dstCell,dMass) = objvel[0]; - RAC(dstCell,dFfrac) = objvel[1]; - RAC(dstCell,dC) = objvel[2]; -#endif // NEWDIRVELMOTEST==1 - } else { - FORDF1 { RAC(dstCell,l) = 0.0; } - } - RAC(dstCell, dFlux) = targetTime; - //errMsg("initMovingObstacles_Debug","OId"<<OId<<" n"<<n<<" -> "<<PRINT_IJK" dflt="<<RAC(dstCell, dFlux) ); - monObsts++; - } // points - } // bnd, is active? - - // second pass, remove old ones - // warning - initEmptyCell et. al dont overwrite OId or persist flags... - if(wasActive) { - for(size_t n=0; n<mMOIVerticesOld.size(); n++) { - POS2GRID_CHECK(mMOIVerticesOld,n); - monPoints++; - if((RFLAG(level, i,j,k, workSet) == otype) && - (QCELL(level, i,j,k, workSet, dFlux) != targetTime)) { - // from mainloop - nbored = 0; - // TODO: optimize for OPT3D==0 - FORDF1 { - //rflagnb[l] = RFLAG_NB(level, i,j,k,workSet,l); - rflagnb[l] = RFLAG_NB(level, i,j,k,otherSet,l); // test use other set to not have loop dependance - nbored |= rflagnb[l]; - } - CellFlagType settype = CFInvalid; - if(nbored&CFFluid) { - settype = CFInter|CFNoInterpolSrc; - rhomass = 1.5; - if(!fillCells) rhomass = 0.; - - OBJVEL_CALC; - if(!(nbored&CFEmpty)) { settype=CFFluid|CFNoInterpolSrc; rhomass=1.; } - - // new interpolate values - LbmFloat avgrho = 0.0; - LbmFloat avgux = 0.0, avguy = 0.0, avguz = 0.0; - interpolateCellValues(level,i,j,k,workSet, avgrho,avgux,avguy,avguz); - initVelocityCell(level, i,j,k, settype, avgrho, rhomass, LbmVec(avgux,avguy,avguz) ); - //errMsg("NMOCIT"," at "<<PRINT_IJK<<" "<<avgrho<<" "<<norm(LbmVec(avgux,avguy,avguz))<<" "<<LbmVec(avgux,avguy,avguz) ); - massCheck += rhomass; - } else { - settype = CFEmpty; rhomass = 0.0; - initEmptyCell(level, i,j,k, settype, 1., rhomass ); - } - monFluids++; - massReinits++; - } // flag & simtime - } - } // wasactive - - // only compute mass transfer when init is done - if(mInitDone) { - errMsg("initMov","dccd\n\nMassd test "<<obj->getName()<<" dccd massCheck="<<massCheck<<" massReinits"<<massReinits<< - " fillCells"<<fillCells<<" massmovbnd:"<<mObjectMassMovnd[OId]<<" inim:"<<mInitialMass ); - mObjectMassMovnd[OId] += massCheck; - } - } // bnd, active - - else if(ntype&CFFluid){ - // second static init pass - if(staticInit) { - //debMsgStd("LbmFsgrSolver::initMovingObstacles",DM_MSG," obj "<<obj->getName()<<" verts"<<mMOIVertices.size() ,9); - CellFlagType setflflag = CFFluid; //|(OId<<24); - for(size_t n=0; n<mMOIVertices.size(); n++) { - POS2GRID_CHECK(mMOIVertices,n); - if(RFLAG(level, i,j,k, workSet)&(CFMbndInflow|CFMbndOutflow)){ continue; } - if(RFLAG(level, i,j,k, workSet)&(CFEmpty)) { - //changeFlag(level, i,j,k, workSet, setflflag); - initVelocityCell(level, i,j,k, setflflag, 1., 1., mObjectSpeeds[OId] ); - } - //else if(RFLAG(level, i,j,k, workSet)&(CFFluid|CFInter)) { changeFlag(level, i,j,k, workSet, RFLAG(level, i,j,k, workSet)|set2Flag); } - } - } // second static inflow pass - } // fluid - - else if(ntype&CFMbndInflow){ - // inflow pass - add new fluid cells - // this is slightly different for standing inflows, - // as the fluid is forced to the desired velocity inside as - // well... - const LbmFloat iniRho = 1.0; - const LbmVec vel(mObjectSpeeds[OId]); - const LbmFloat usqr = (vel[0]*vel[0]+vel[1]*vel[1]+vel[2]*vel[2])*1.5; - USQRMAXCHECK(usqr,vel[0],vel[1],vel[2], mMaxVlen, mMxvx,mMxvy,mMxvz); - //errMsg("LbmFsgrSolver::initMovingObstacles","id"<<OId<<" "<<obj->getName()<<" inflow "<<staticInit<<" "<<mMOIVertices.size() ); - - for(size_t n=0; n<mMOIVertices.size(); n++) { - POS2GRID_CHECK(mMOIVertices,n); - // TODO - also reinit interface cells !? - if(RFLAG(level, i,j,k, workSet)!=CFEmpty) { - // test prevent particle gen for inflow inter cells - if(RFLAG(level, i,j,k, workSet)&(CFInter)) { RFLAG(level, i,j,k, workSet) &= (~CFNoBndFluid); } // remove CFNoBndFluid flag - continue; } - monFluids++; - - // TODO add OPT3D treatment - LbmFloat *tcel = RACPNT(level, i,j,k,workSet); - FORDF0 { RAC(tcel, l) = this->getCollideEq(l, iniRho,vel[0],vel[1],vel[2]); } - RAC(tcel, dMass) = RAC(tcel, dFfrac) = iniRho; - RAC(tcel, dFlux) = FLUX_INIT; - CellFlagType setFlag = CFInter; - changeFlag(level, i,j,k, workSet, setFlag); - mInitialMass += iniRho; - } - // second static init pass - if(staticInit) { - CellFlagType set2Flag = CFMbndInflow|(OId<<24); - for(size_t n=0; n<mMOIVertices.size(); n++) { - POS2GRID_CHECK(mMOIVertices,n); - if(RFLAG(level, i,j,k, workSet)&(CFMbndInflow|CFMbndOutflow)){ continue; } - if(RFLAG(level, i,j,k, workSet)&(CFEmpty)) { - forceChangeFlag(level, i,j,k, workSet, set2Flag); - } else if(RFLAG(level, i,j,k, workSet)&(CFFluid|CFInter)) { - forceChangeFlag(level, i,j,k, workSet, - (RFLAG(level, i,j,k, workSet)&CFNoPersistMask)|set2Flag); - } - } - } // second static inflow pass - - } // inflow - - else if(ntype&CFMbndOutflow){ - const LbmFloat iniRho = 0.0; - for(size_t n=0; n<mMOIVertices.size(); n++) { - POS2GRID_CHECK(mMOIVertices,n); - // FIXME check fluid/inter cells for non-static!? - if(!(RFLAG(level, i,j,k, workSet)&(CFFluid|CFInter))) { - if((staticInit)&&(RFLAG(level, i,j,k, workSet)==CFEmpty)) { - forceChangeFlag(level, i,j,k, workSet, CFMbndOutflow); } - continue; - } - monFluids++; - // interface cell - might be double empty? FIXME check? - - // remove fluid cells, shouldnt be here anyway - LbmFloat *tcel = RACPNT(level, i,j,k,workSet); - LbmFloat fluidRho = RAC(tcel,0); FORDF1 { fluidRho += RAC(tcel,l); } - mInitialMass -= fluidRho; - RAC(tcel, dMass) = RAC(tcel, dFfrac) = iniRho; - RAC(tcel, dFlux) = FLUX_INIT; - CellFlagType setFlag = CFInter; - changeFlag(level, i,j,k, workSet, setFlag); - - // same as ifemptied for if below - LbmPoint emptyp; - emptyp.x = i; emptyp.y = j; emptyp.z = k; - mListEmpty.push_back( emptyp ); - //calcCellsEmptied++; - } // points - // second static init pass - if(staticInit) { - CellFlagType set2Flag = CFMbndOutflow|(OId<<24); - for(size_t n=0; n<mMOIVertices.size(); n++) { - POS2GRID_CHECK(mMOIVertices,n); - if(RFLAG(level, i,j,k, workSet)&(CFMbndInflow|CFMbndOutflow)){ continue; } - if(RFLAG(level, i,j,k, workSet)&(CFEmpty)) { - forceChangeFlag(level, i,j,k, workSet, set2Flag); - } else if(RFLAG(level, i,j,k, workSet)&(CFFluid|CFInter)) { - forceChangeFlag(level, i,j,k, workSet, - (RFLAG(level, i,j,k, workSet)&CFNoPersistMask)|set2Flag); - } - } - } // second static outflow pass - } // outflow - - } // allbound check - } // OId - - - /* { // DEBUG check - int workSet = mLevel[level].setCurr; - FSGR_FORIJK1(level) { - if( (RFLAG(level,i,j,k, workSet) & CFBndMoving) ) { - if(QCELL(level, i,j,k, workSet, dFlux)!=targetTime) { - errMsg("lastt"," old val!? at "<<PRINT_IJK<<" t="<<QCELL(level, i,j,k, workSet, dFlux)<<" target="<<targetTime); - } - } - } - } // DEBUG */ - -#undef POS2GRID_CHECK - myTime_t monend = getTime(); - if(monend-monstart>0) debMsgStd("LbmFsgrSolver::initMovingObstacles",DM_MSG,"Total: "<<monTotal<<" Points :"<<monPoints<<" ObstInits:"<<monObsts<<" FlInits:"<<monFluids<<" Trafos:"<<monTotal<<", took "<<getTimeString(monend-monstart), 7); - mLastSimTime = targetTime; -} - - -// geoinit position - -#define GETPOS(i,j,k) \ - ntlVec3Gfx ggpos = \ - ntlVec3Gfx( iniPos[0]+ dvec[0]*(gfxReal)(i), \ - iniPos[1]+ dvec[1]*(gfxReal)(j), \ - iniPos[2]+ dvec[2]*(gfxReal)(k) ); \ - if((LBMDIM==2)&&(mInit2dYZ)) { SWAPYZ(ggpos); } - -/*****************************************************************************/ -/*! perform geometry init (if switched on) */ -/*****************************************************************************/ -extern int globGeoInitDebug; //solver_interface -bool LbmFsgrSolver::initGeometryFlags() { - int level = mMaxRefine; - myTime_t geotimestart = getTime(); - ntlGeometryObject *pObj; - ntlVec3Gfx dvec = ntlVec3Gfx(mLevel[level].nodeSize); //dvec*1.0; - debMsgStd("LbmFsgrSolver::initGeometryFlags",DM_MSG,"Performing geometry init ("<< mLbmInitId <<") v"<<dvec,3); - // WARNING - copied to movobj init! - - /* init object velocities, this has always to be called for init */ - initGeoTree(); - if(mAllfluid) { - freeGeoTree(); - return true; } - - // make sure moving obstacles are inited correctly - // preinit moving obj points - int numobjs = (int)(mpGiObjects->size()); - for(int o=0; o<numobjs; o++) { - ntlGeometryObject *obj = (*mpGiObjects)[o]; - //debMsgStd("LbmFsgrSolver::initMovingObstacles",DM_MSG," obj "<<obj->getName()<<" type "<<obj->getGeoInitType()<<" anim"<<obj->getIsAnimated()<<" "<<obj->getVolumeInit() ,9); - if( - ((obj->getGeoInitType()&FGI_ALLBOUNDS) && (obj->getIsAnimated())) || - (obj->getVolumeInit()&VOLUMEINIT_SHELL) ) { - if(!obj->getMeshAnimated()) { - debMsgStd("LbmFsgrSolver::initMovingObstacles",DM_MSG," obj "<<obj->getName()<<" type "<<obj->getGeoInitType()<<" anim"<<obj->getIsAnimated()<<" "<<obj->getVolumeInit() ,9); - obj->initMovingPoints(mSimulationTime, mLevel[mMaxRefine].nodeSize); - } - } - } - - // max speed init - ntlVec3Gfx maxMovobjVelRw = getGeoMaxMovementVelocity( mSimulationTime, mpParam->getTimestep() ); - ntlVec3Gfx maxMovobjVel = vec2G( mpParam->calculateLattVelocityFromRw( vec2P( maxMovobjVelRw )) ); - mpParam->setSimulationMaxSpeed( norm(maxMovobjVel) + norm(mLevel[level].gravity) ); - LbmFloat allowMax = mpParam->getTadapMaxSpeed(); // maximum allowed velocity - debMsgStd("LbmFsgrSolver::initGeometryFlags",DM_MSG,"Maximum Velocity from geo init="<< maxMovobjVel <<" from mov. obj.="<<maxMovobjVelRw<<" , allowed Max="<<allowMax ,5); - if(mpParam->getSimulationMaxSpeed() > allowMax) { - // similar to adaptTimestep(); - LbmFloat nextmax = mpParam->getSimulationMaxSpeed(); - LbmFloat newdt = mpParam->getTimestep() * (allowMax / nextmax); // newtr - debMsgStd("LbmFsgrSolver::initGeometryFlags",DM_MSG,"Performing reparametrization, newdt="<< newdt<<" prevdt="<< mpParam->getTimestep() <<" ",5); - mpParam->setDesiredTimestep( newdt ); - mpParam->calculateAllMissingValues( mSimulationTime, mSilent ); - maxMovobjVel = vec2G( mpParam->calculateLattVelocityFromRw( vec2P(getGeoMaxMovementVelocity( - mSimulationTime, mpParam->getTimestep() )) )); - debMsgStd("LbmFsgrSolver::initGeometryFlags",DM_MSG,"New maximum Velocity from geo init="<< maxMovobjVel,5); - } - recalculateObjectSpeeds(); - // */ - - // init obstacles for first time step (requires obj speeds) - initMovingObstacles(true); - - /* set interface cells */ - ntlVec3Gfx pos,iniPos; // position of current cell - LbmFloat rhomass = 0.0; - CellFlagType ntype = CFInvalid; - int savedNodes = 0; - int OId = -1; - gfxReal distance; - - // 2d display as rectangles - if(LBMDIM==2) { - dvec[2] = 0.0; - iniPos =(mvGeoStart + ntlVec3Gfx( 0.0, 0.0, (mvGeoEnd[2]-mvGeoStart[2])*0.5 ))+(dvec*0.5); - //if(mInit2dYZ) { SWAPYZ(mGravity); for(int lev=0; lev<=mMaxRefine; lev++){ SWAPYZ( mLevel[lev].gravity ); } } - } else { - iniPos =(mvGeoStart + ntlVec3Gfx( 0.0 ))+(dvec*0.5); - } - - - // first init boundary conditions - // invalid cells are set to empty afterwards - // TODO use floop macros!? - for(int k= getForZMin1(); k< getForZMax1(level); ++k) { - for(int j=1;j<mLevel[level].lSizey-1;j++) { - for(int i=1;i<mLevel[level].lSizex-1;i++) { - ntype = CFInvalid; - - GETPOS(i,j,k); - const bool inside = geoInitCheckPointInside( ggpos, FGI_ALLBOUNDS, OId, distance); - if(inside) { - pObj = (*mpGiObjects)[OId]; - switch( pObj->getGeoInitType() ){ - case FGI_MBNDINFLOW: - if(! pObj->getIsAnimated() ) { - rhomass = 1.0; - ntype = CFFluid | CFMbndInflow; - } else { - ntype = CFInvalid; - } - break; - case FGI_MBNDOUTFLOW: - if(! pObj->getIsAnimated() ) { - rhomass = 0.0; - ntype = CFEmpty|CFMbndOutflow; - } else { - ntype = CFInvalid; - } - break; - case FGI_BNDNO: - rhomass = BND_FILL; - ntype = CFBnd|CFBndNoslip; - break; - case FGI_BNDPART: - rhomass = BND_FILL; - ntype = CFBnd|CFBndPartslip; break; - case FGI_BNDFREE: - rhomass = BND_FILL; - ntype = CFBnd|CFBndFreeslip; break; - default: // warn here? - rhomass = BND_FILL; - ntype = CFBnd|CFBndNoslip; break; - } - } - if(ntype != CFInvalid) { - // initDefaultCell - if((ntype & CFMbndInflow) || (ntype & CFMbndOutflow) ) { } - ntype |= (OId<<24); // NEWTEST2 - initVelocityCell(level, i,j,k, ntype, rhomass, rhomass, mObjectSpeeds[OId] ); - } - - // walk along x until hit for following inits - if(distance<=-1.0) { distance = 100.0; } // FIXME dangerous - if(distance>=0.0) { - gfxReal dcnt=dvec[0]; - while(( dcnt< distance-dvec[0] )&&(i+1<mLevel[level].lSizex-1)) { - dcnt += dvec[0]; i++; - savedNodes++; - if(ntype != CFInvalid) { - // rho,mass,OId are still inited from above - initVelocityCell(level, i,j,k, ntype, rhomass, rhomass, mObjectSpeeds[OId] ); - } - } - } - // */ - - } - } - } // zmax - // */ - - // now init fluid layer - for(int k= getForZMin1(); k< getForZMax1(level); ++k) { - for(int j=1;j<mLevel[level].lSizey-1;j++) { - for(int i=1;i<mLevel[level].lSizex-1;i++) { - if(!(RFLAG(level, i,j,k, mLevel[level].setCurr)==CFEmpty)) continue; - ntype = CFInvalid; - int inits = 0; - GETPOS(i,j,k); - const bool inside = geoInitCheckPointInside( ggpos, FGI_FLUID, OId, distance); - if(inside) { - ntype = CFFluid; - } - if(ntype != CFInvalid) { - // initDefaultCell - rhomass = 1.0; - initVelocityCell(level, i,j,k, ntype, rhomass, rhomass, mObjectSpeeds[OId] ); - inits++; - } - - // walk along x until hit for following inits - if(distance<=-1.0) { distance = 100.0; } - if(distance>=0.0) { - gfxReal dcnt=dvec[0]; - while((dcnt< distance )&&(i+1<mLevel[level].lSizex-1)) { - dcnt += dvec[0]; i++; - savedNodes++; - if(!(RFLAG(level, i,j,k, mLevel[level].setCurr)==CFEmpty)) continue; - if(ntype != CFInvalid) { - // rhomass are still inited from above - initVelocityCell(level, i,j,k, ntype, rhomass, rhomass, mObjectSpeeds[OId] ); - inits++; - } - } - } // distance>0 - - } - } - } // zmax - - // reset invalid to empty again - for(int k= getForZMin1(); k< getForZMax1(level); ++k) { - for(int j=1;j<mLevel[level].lSizey-1;j++) { - for(int i=1;i<mLevel[level].lSizex-1;i++) { - if(RFLAG(level, i,j,k, mLevel[level].setCurr)==CFInvalid) { - RFLAG(level, i,j,k, mLevel[level].setOther) = - RFLAG(level, i,j,k, mLevel[level].setCurr) = CFEmpty; - } - } - } - } - - freeGeoTree(); - myTime_t geotimeend = getTime(); - debMsgStd("LbmFsgrSolver::initGeometryFlags",DM_MSG,"Geometry init done ("<< getTimeString(geotimeend-geotimestart)<<","<<savedNodes<<") " , 10 ); - //errMsg(" SAVED "," "<<savedNodes<<" of "<<(mLevel[mMaxRefine].lSizex*mLevel[mMaxRefine].lSizey*mLevel[mMaxRefine].lSizez)); - return true; -} - -#undef GETPOS - -/*****************************************************************************/ -/* init part for all freesurface testcases */ -void LbmFsgrSolver::initFreeSurfaces() { - double interfaceFill = 0.45; // filling level of interface cells - //interfaceFill = 1.0; // DEUG!! GEOMTEST!!!!!!!!!!!! - - // set interface cells - FSGR_FORIJK1(mMaxRefine) { - if( ( RFLAG(mMaxRefine, i,j,k, mLevel[mMaxRefine].setCurr)& CFFluid )) { - FORDF1 { - int ni=i+dfVecX[l], nj=j+dfVecY[l], nk=k+dfVecZ[l]; - if( ( RFLAG(mMaxRefine, ni, nj, nk, mLevel[mMaxRefine].setCurr)& CFEmpty ) ) { - LbmFloat arho=0., aux=0., auy=0., auz=0.; - interpolateCellValues(mMaxRefine, ni,nj,nk, mLevel[mMaxRefine].setCurr, arho,aux,auy,auz); - //errMsg("TINI"," "<<PRINT_VEC(ni,nj,nk)<<" v"<<LbmVec(aux,auy,auz) ); - // unnecessary? initEmptyCell(mMaxRefine, ni,nj,nk, CFInter, arho, interfaceFill); - initVelocityCell(mMaxRefine, ni,nj,nk, CFInter, arho, interfaceFill, LbmVec(aux,auy,auz) ); - } - } - } - } - - // remove invalid interface cells - FSGR_FORIJK1(mMaxRefine) { - // remove invalid interface cells - if( ( RFLAG(mMaxRefine, i,j,k, mLevel[mMaxRefine].setCurr)& CFInter) ) { - int delit = 0; - int NBs = 0; // neighbor flags or'ed - int noEmptyNB = 1; - - FORDF1 { - if( ( RFLAG_NBINV(mMaxRefine, i, j, k, mLevel[mMaxRefine].setCurr,l )& CFEmpty ) ) { - noEmptyNB = 0; - } - NBs |= RFLAG_NBINV(mMaxRefine, i, j, k, mLevel[mMaxRefine].setCurr, l); - } - // remove cells with no fluid or interface neighbors - if((NBs & CFFluid)==0) { delit = 1; } - if((NBs & CFInter)==0) { delit = 1; } - // remove cells with no empty neighbors - if(noEmptyNB) { delit = 2; } - - // now we can remove the cell - if(delit==1) { - initEmptyCell(mMaxRefine, i,j,k, CFEmpty, 1.0, 0.0); - } - if(delit==2) { - //initEmptyCell(mMaxRefine, i,j,k, CFFluid, 1.0, 1.0); - LbmFloat arho=0., aux=0., auy=0., auz=0.; - interpolateCellValues(mMaxRefine, i,j,k, mLevel[mMaxRefine].setCurr, arho,aux,auy,auz); - initVelocityCell(mMaxRefine, i,j,k, CFFluid, arho,1., LbmVec(aux,auy,auz) ); - } - } // interface - } // */ - - // another brute force init, make sure the fill values are right... - // and make sure both sets are equal - for(int lev=0; lev<=mMaxRefine; lev++) { - FSGR_FORIJK_BOUNDS(lev) { - if( (RFLAG(lev, i,j,k,0) & (CFBnd)) ) { - QCELL(lev, i,j,k,mLevel[mMaxRefine].setCurr, dFfrac) = BND_FILL; - continue; - } - if( (RFLAG(lev, i,j,k,0) & (CFEmpty)) ) { - QCELL(lev, i,j,k,mLevel[mMaxRefine].setCurr, dFfrac) = 0.0; - continue; - } - } } - - // ---------------------------------------------------------------------- - // smoother surface... - if(mInitSurfaceSmoothing>0) { - debMsgStd("Surface Smoothing init", DM_MSG, "Performing "<<(mInitSurfaceSmoothing)<<" smoothing timestep ",10); -#if COMPRESSGRIDS==1 - //errFatal("NYI","COMPRESSGRIDS mInitSurfaceSmoothing",SIMWORLD_INITERROR); return; -#endif // COMPRESSGRIDS==0 - } - for(int s=0; s<mInitSurfaceSmoothing; s++) { - //SGR_FORIJK1(mMaxRefine) { - - int kstart=getForZMin1(), kend=getForZMax1(mMaxRefine); - int lev = mMaxRefine; -#if COMPRESSGRIDS==0 - for(int k=kstart;k<kend;++k) { -#else // COMPRESSGRIDS==0 - int kdir = 1; // COMPRT ON - if(mLevel[lev].setCurr==1) { - kdir = -1; - int temp = kend; - kend = kstart-1; - kstart = temp-1; - } // COMPRT - for(int k=kstart;k!=kend;k+=kdir) { -#endif // COMPRESSGRIDS==0 - for(int j=1;j<mLevel[lev].lSizey-1;++j) { - for(int i=1;i<mLevel[lev].lSizex-1;++i) { - if( ( RFLAG(lev, i,j,k, mLevel[lev].setCurr)& CFInter) ) { - LbmFloat mass = 0.0; - //LbmFloat nbdiv; - //FORDF0 { - for(int l=0;(l<cDirNum); l++) { - int ni=i+dfVecX[l], nj=j+dfVecY[l], nk=k+dfVecZ[l]; - if( RFLAG(lev, ni,nj,nk, mLevel[lev].setCurr) & CFFluid ){ - mass += 1.0; - } - if( RFLAG(lev, ni,nj,nk, mLevel[lev].setCurr) & CFInter ){ - mass += QCELL(lev, ni,nj,nk, mLevel[lev].setCurr, dMass); - } - //nbdiv+=1.0; - } - - //errMsg(" I ", PRINT_IJK<<" m"<<mass ); - QCELL(lev, i,j,k, mLevel[lev].setOther, dMass) = (mass/ ((LbmFloat)cDirNum) ); - QCELL(lev, i,j,k, mLevel[lev].setOther, dFfrac) = QCELL(lev, i,j,k, mLevel[lev].setOther, dMass); - } - }}} - - mLevel[lev].setOther = mLevel[lev].setCurr; - mLevel[lev].setCurr ^= 1; - } - // copy back...? -} - -/*****************************************************************************/ -/* init part for all freesurface testcases */ -void LbmFsgrSolver::initStandingFluidGradient() { - // ---------------------------------------------------------------------- - // standing fluid preinit - const int debugStandingPreinit = 0; - int haveStandingFluid = 0; - -#define STANDFLAGCHECK(iindex) \ - if( ( (RFLAG(mMaxRefine,i,j,k,mLevel[mMaxRefine].setCurr) & (CFInter)) ) || \ - ( (RFLAG(mMaxRefine,i,j,k,mLevel[mMaxRefine].setCurr) & (CFEmpty)) ) ){ \ - if((iindex)>1) { haveStandingFluid=(iindex); } \ - j = mLevel[mMaxRefine].lSizey; i=mLevel[mMaxRefine].lSizex; k=getForZMaxBnd(); \ - continue; \ - } - int gravIndex[3] = {0,0,0}; - int gravDir[3] = {1,1,1}; - int maxGravComp = 1; // by default y - int gravComp1 = 0; // by default y - int gravComp2 = 2; // by default y - if( ABS(mLevel[mMaxRefine].gravity[0]) > ABS(mLevel[mMaxRefine].gravity[1]) ){ maxGravComp = 0; gravComp1=1; gravComp2=2; } - if( ABS(mLevel[mMaxRefine].gravity[2]) > ABS(mLevel[mMaxRefine].gravity[0]) ){ maxGravComp = 2; gravComp1=0; gravComp2=1; } - - int gravIMin[3] = { 0 , 0 , 0 }; - int gravIMax[3] = { - mLevel[mMaxRefine].lSizex + 0, - mLevel[mMaxRefine].lSizey + 0, - mLevel[mMaxRefine].lSizez + 0 }; - if(LBMDIM==2) gravIMax[2] = 1; - - //int gravDir = 1; - if( mLevel[mMaxRefine].gravity[maxGravComp] > 0.0 ) { - // swap directions - int i=maxGravComp; - int tmp = gravIMin[i]; - gravIMin[i] = gravIMax[i] - 1; - gravIMax[i] = tmp - 1; - gravDir[i] = -1; - } -#define PRINTGDIRS \ - errMsg("Standing fp","X start="<<gravIMin[0]<<" end="<<gravIMax[0]<<" dir="<<gravDir[0] ); \ - errMsg("Standing fp","Y start="<<gravIMin[1]<<" end="<<gravIMax[1]<<" dir="<<gravDir[1] ); \ - errMsg("Standing fp","Z start="<<gravIMin[2]<<" end="<<gravIMax[2]<<" dir="<<gravDir[2] ); - // _PRINTGDIRS; - - bool gravAbort = false; -#define GRAVLOOP \ - gravAbort=false; \ - for(gravIndex[2]= gravIMin[2]; (gravIndex[2]!=gravIMax[2])&&(!gravAbort); gravIndex[2] += gravDir[2]) \ - for(gravIndex[1]= gravIMin[1]; (gravIndex[1]!=gravIMax[1])&&(!gravAbort); gravIndex[1] += gravDir[1]) \ - for(gravIndex[0]= gravIMin[0]; (gravIndex[0]!=gravIMax[0])&&(!gravAbort); gravIndex[0] += gravDir[0]) - - GRAVLOOP { - int i = gravIndex[0], j = gravIndex[1], k = gravIndex[2]; - if( ( (RFLAG(mMaxRefine,i,j,k,mLevel[mMaxRefine].setCurr) & (CFInter)) ) || - ( (RFLAG(mMaxRefine,i,j,k,mLevel[mMaxRefine].setCurr) & (CFBndMoving)) ) || - ( (RFLAG(mMaxRefine,i,j,k,mLevel[mMaxRefine].setCurr) & (CFEmpty)) ) ) { - int fluidHeight = (ABS(gravIndex[maxGravComp] - gravIMin[maxGravComp])); - if(debugStandingPreinit) errMsg("Standing fp","fh="<<fluidHeight<<" gmax="<<gravIMax[maxGravComp]<<" gi="<<gravIndex[maxGravComp] ); - if(fluidHeight>1) { - haveStandingFluid = fluidHeight; //gravIndex[maxGravComp]; - gravIMax[maxGravComp] = gravIndex[maxGravComp] + gravDir[maxGravComp]; - } - gravAbort = true; continue; - } - } // GRAVLOOP - // _PRINTGDIRS; - - LbmFloat fluidHeight; - fluidHeight = (LbmFloat)(ABS(gravIMax[maxGravComp]-gravIMin[maxGravComp])); -#if LBM_INCLUDE_TESTSOLVERS==1 - if(mUseTestdata) mpTest->mFluidHeight = (int)fluidHeight; -#endif // ELBEEM_PLUGIN!=1 - if(debugStandingPreinit) debMsgStd("Standing fluid preinit", DM_MSG, "fheight="<<fluidHeight<<" min="<<PRINT_VEC(gravIMin[0],gravIMin[1], gravIMin[2])<<" max="<<PRINT_VEC(gravIMax[0], gravIMax[1],gravIMax[2])<< - " mgc="<<maxGravComp<<" mc1="<<gravComp1<<" mc2="<<gravComp2<<" dir="<<gravDir[maxGravComp]<<" have="<<haveStandingFluid ,10); - - if(mDisableStandingFluidInit) { - debMsgStd("Standing fluid preinit", DM_MSG, "Should be performed - but skipped due to mDisableStandingFluidInit flag set!", 2); - haveStandingFluid=0; - } - - // copy flags and init , as no flags will be changed during grav init - // also important for corasening later on - const int lev = mMaxRefine; - CellFlagType nbflag[LBM_DFNUM], nbored; - for(int k=getForZMinBnd();k<getForZMaxBnd(mMaxRefine);++k) { - for(int j=0;j<mLevel[lev].lSizey-0;++j) { - for(int i=0;i<mLevel[lev].lSizex-0;++i) { - if( (RFLAG(lev, i,j,k,SRCS(lev)) & (CFFluid)) ) { - nbored = 0; - FORDF1 { - nbflag[l] = RFLAG_NB(lev, i,j,k, SRCS(lev),l); - nbored |= nbflag[l]; - } - if(nbored&CFBnd) { - RFLAG(lev, i,j,k,SRCS(lev)) &= (~CFNoBndFluid); - } else { - RFLAG(lev, i,j,k,SRCS(lev)) |= CFNoBndFluid; - } - } - RFLAG(lev, i,j,k,TSET(lev)) = RFLAG(lev, i,j,k,SRCS(lev)); - } } } - - if(haveStandingFluid) { - int rhoworkSet = mLevel[lev].setCurr; - myTime_t timestart = getTime(); // FIXME use user time here? - - GRAVLOOP { - int i = gravIndex[0], j = gravIndex[1], k = gravIndex[2]; - //debMsgStd("Standing fluid preinit", DM_MSG, " init check "<<PRINT_IJK<<" "<< haveStandingFluid, 1 ); - if( ( (RFLAG(lev, i,j,k,rhoworkSet) & (CFInter)) ) || - ( (RFLAG(lev, i,j,k,rhoworkSet) & (CFEmpty)) ) ){ - //gravAbort = true; - continue; - } - - LbmFloat rho = 1.0; - // 1/6 velocity from denisty gradient, 1/2 for delta of two cells - rho += 1.0* (fluidHeight-gravIndex[maxGravComp]) * - (mLevel[lev].gravity[maxGravComp])* (-3.0/1.0)*(mLevel[lev].omega); - if(debugStandingPreinit) - if((gravIndex[gravComp1]==gravIMin[gravComp1]) && (gravIndex[gravComp2]==gravIMin[gravComp2])) { - errMsg("Standing fp","gi="<<gravIndex[maxGravComp]<<" rho="<<rho<<" at "<<PRINT_IJK); - } - - if( (RFLAG(lev, i,j,k, rhoworkSet) & CFFluid) || - (RFLAG(lev, i,j,k, rhoworkSet) & CFInter) ) { - FORDF0 { QCELL(lev, i,j,k, rhoworkSet, l) *= rho; } - QCELL(lev, i,j,k, rhoworkSet, dMass) *= rho; - } - - } // GRAVLOOP - - debMsgStd("Standing fluid preinit", DM_MSG, "Density gradient inited (max-rho:"<< - (1.0+ (fluidHeight) * (mLevel[lev].gravity[maxGravComp])* (-3.0/1.0)*(mLevel[lev].omega)) <<", h:"<< fluidHeight<<") ", 8); - - int preinitSteps = (haveStandingFluid* ((mLevel[lev].lSizey+mLevel[lev].lSizez+mLevel[lev].lSizex)/3) ); - preinitSteps = (haveStandingFluid>>2); // not much use...? - //preinitSteps = 0; - debMsgStd("Standing fluid preinit", DM_MSG, "Performing "<<preinitSteps<<" prerelaxations ",10); - for(int s=0; s<preinitSteps; s++) { - // in solver main cpp - standingFluidPreinit(); - } - - myTime_t timeend = getTime(); - debMsgStd("Standing fluid preinit", DM_MSG, " done, "<<getTimeString(timeend-timestart), 9); -#undef NBFLAG - } -} - - - -bool LbmFsgrSolver::checkSymmetry(string idstring) -{ - bool erro = false; - bool symm = true; - int msgs = 0; - const int maxMsgs = 10; - const bool markCells = false; - - //for(int lev=0; lev<=mMaxRefine; lev++) { - { int lev = mMaxRefine; - - // no point if not symm. - if( (mLevel[lev].lSizex==mLevel[lev].lSizey) && (mLevel[lev].lSizex==mLevel[lev].lSizez)) { - // ok - } else { - return false; - } - - for(int s=0; s<2; s++) { - FSGR_FORIJK1(lev) { - if(i<(mLevel[lev].lSizex/2)) { - int inb = (mLevel[lev].lSizey-1-i); - - if(lev==mMaxRefine) inb -= 1; // FSGR_SYMM_T - - if( RFLAG(lev, i,j,k,s) != RFLAG(lev, inb,j,k,s) ) { erro = true; - if(LBMDIM==2) { - if(msgs<maxMsgs) { msgs++; - errMsg("EFLAG", PRINT_IJK<<"s"<<s<<" flag "<<RFLAG(lev, i,j,k,s)<<" , at "<<PRINT_VEC(inb,j,k)<<"s"<<s<<" flag "<<RFLAG(lev, inb,j,k,s) ); - } - } - if(markCells){ debugMarkCell(lev, i,j,k); debugMarkCell(lev, inb,j,k); } - symm = false; - } - if( LBM_FLOATNEQ(QCELL(lev, i,j,k,s, dMass), QCELL(lev, inb,j,k,s, dMass)) ) { erro = true; - if(LBMDIM==2) { - if(msgs<maxMsgs) { msgs++; - //debMsgDirect(" mass1 "<<QCELL(lev, i,j,k,s, dMass)<<" mass2 "<<QCELL(lev, inb,j,k,s, dMass) <<std::endl); - errMsg("EMASS", PRINT_IJK<<"s"<<s<<" mass "<<QCELL(lev, i,j,k,s, dMass)<<" , at "<<PRINT_VEC(inb,j,k)<<"s"<<s<<" mass "<<QCELL(lev, inb,j,k,s, dMass) ); - } - } - if(markCells){ debugMarkCell(lev, i,j,k); debugMarkCell(lev, inb,j,k); } - symm = false; - } - - LbmFloat nbrho = QCELL(lev, i,j,k, s, dC); - FORDF1 { nbrho += QCELL(lev, i,j,k, s, l); } - LbmFloat otrho = QCELL(lev, inb,j,k, s, dC); - FORDF1 { otrho += QCELL(lev, inb,j,k, s, l); } - if( LBM_FLOATNEQ(nbrho, otrho) ) { erro = true; - if(LBMDIM==2) { - if(msgs<maxMsgs) { msgs++; - //debMsgDirect(" rho 1 "<<nbrho <<" rho 2 "<<otrho <<std::endl); - errMsg("ERHO ", PRINT_IJK<<"s"<<s<<" rho "<<nbrho <<" , at "<<PRINT_VEC(inb,j,k)<<"s"<<s<<" rho "<<otrho ); - } - } - if(markCells){ debugMarkCell(lev, i,j,k); debugMarkCell(lev, inb,j,k); } - symm = false; - } - } - } } - } // lev - LbmFloat maxdiv =0.0; - if(erro) { - errMsg("SymCheck Failed!", idstring<<" rho maxdiv:"<< maxdiv ); - //if(LBMDIM==2) mPanic = true; - //return false; - } else { - errMsg("SymCheck OK!", idstring<<" rho maxdiv:"<< maxdiv ); - } - // all ok... - return symm; -}// */ - - -void -LbmFsgrSolver::interpolateCellValues( - int level,int ei,int ej,int ek,int workSet, - LbmFloat &retrho, LbmFloat &retux, LbmFloat &retuy, LbmFloat &retuz) -{ - LbmFloat avgrho = 0.0; - LbmFloat avgux = 0.0, avguy = 0.0, avguz = 0.0; - LbmFloat cellcnt = 0.0; - - for(int nbl=1; nbl< cDfNum ; ++nbl) { - if(RFLAG_NB(level,ei,ej,ek,workSet,nbl) & CFNoInterpolSrc) continue; - if( (RFLAG_NB(level,ei,ej,ek,workSet,nbl) & (CFFluid|CFInter)) ){ - //((!(RFLAG_NB(level,ei,ej,ek,workSet,nbl) & CFNoInterpolSrc) ) && - //(RFLAG_NB(level,ei,ej,ek,workSet,nbl) & CFInter) ) { - cellcnt += 1.0; - for(int rl=0; rl< cDfNum ; ++rl) { - LbmFloat nbdf = QCELL_NB(level,ei,ej,ek, workSet,nbl, rl); - avgux += (dfDvecX[rl]*nbdf); - avguy += (dfDvecY[rl]*nbdf); - avguz += (dfDvecZ[rl]*nbdf); - avgrho += nbdf; - } - } - } - - if(cellcnt<=0.0) { - // no nbs? just use eq. - avgrho = 1.0; - avgux = avguy = avguz = 0.0; - //TTT mNumProblems++; -#if ELBEEM_PLUGIN!=1 - //mPanic=1; - // this can happen for worst case moving obj scenarios... - errMsg("LbmFsgrSolver::interpolateCellValues","Cellcnt<=0.0 at "<<PRINT_VEC(ei,ej,ek)); -#endif // ELBEEM_PLUGIN - } else { - // init speed - avgux /= cellcnt; avguy /= cellcnt; avguz /= cellcnt; - avgrho /= cellcnt; - } - - retrho = avgrho; - retux = avgux; - retuy = avguy; - retuz = avguz; -} // interpolateCellValues - - -/****************************************************************************** - * instantiation - *****************************************************************************/ - -//! lbm factory functions -LbmSolverInterface* createSolver() { return new LbmFsgrSolver(); } - - diff --git a/intern/elbeem/intern/solver_interface.cpp b/intern/elbeem/intern/solver_interface.cpp deleted file mode 100644 index 7f8fe9256e1..00000000000 --- a/intern/elbeem/intern/solver_interface.cpp +++ /dev/null @@ -1,753 +0,0 @@ -/** \file - * \ingroup elbeem - */ -/****************************************************************************** - * - * El'Beem - Free Surface Fluid Simulation with the Lattice Boltzmann Method - * All code distributed as part of El'Beem is covered by the version 2 of the - * GNU General Public License. See the file COPYING for details. - * Copyright 2003-2006 Nils Thuerey - * - * Combined 2D/3D Lattice Boltzmann Interface Class - * contains stuff to be statically compiled - * - *****************************************************************************/ - -/* LBM Files */ -#include "ntl_matrices.h" -#include "solver_interface.h" -#include "ntl_ray.h" -#include "ntl_world.h" -#include "elbeem.h" - - - - -/****************************************************************************** - * Interface Constructor - *****************************************************************************/ -LbmSolverInterface::LbmSolverInterface() : - mPanic( false ), - mSizex(10), mSizey(10), mSizez(10), - mAllfluid(false), mStepCnt( 0 ), - mFixMass( 0.0 ), - mOmega( 1.0 ), - mGravity(0.0), - mSurfaceTension( 0.0 ), - mBoundaryEast( (CellFlagType)(CFBnd) ),mBoundaryWest( (CellFlagType)(CFBnd) ),mBoundaryNorth( (CellFlagType)(CFBnd) ), - mBoundarySouth( (CellFlagType)(CFBnd) ),mBoundaryTop( (CellFlagType)(CFBnd) ),mBoundaryBottom( (CellFlagType)(CFBnd) ), - mInitDone( false ), - mInitDensityGradient( false ), - mpSifAttrs( NULL ), mpSifSwsAttrs(NULL), mpParam( NULL ), mpParticles(NULL), - mNumParticlesLost(0), - mNumInvalidDfs(0), mNumFilledCells(0), mNumEmptiedCells(0), mNumUsedCells(0), mMLSUPS(0), - mDebugVelScale( 0.01 ), mNodeInfoString("+"), - mvGeoStart(-1.0), mvGeoEnd(1.0), mpSimTrafo(NULL), - mAccurateGeoinit(0), - mName("lbm_default") , - mpIso( NULL ), mIsoValue(0.499), - mSilent(false) , - mLbmInitId(1) , - mpGiTree( NULL ), - mpGiObjects( NULL ), mGiObjInside(), mpGlob( NULL ), - mRefinementDesired(0), - mOutputSurfacePreview(0), mPreviewFactor(0.25), - mSmoothSurface(1.0), mSmoothNormals(1.0), - mIsoSubdivs(1), mPartGenProb(0.), - mDumpVelocities(false), - mMarkedCells(), mMarkedCellIndex(0), - mDomainBound("noslip"), mDomainPartSlipValue(0.1), - mFarFieldSize(0.), - mPartDropMassSub(0.1), // good default - mPartUsePhysModel(false), - mTForceStrength(0.0), - mCppfStage(0), - mDumpRawText(false), - mDumpRawBinary(false), - mDumpRawBinaryZip(true) -#if PARALLEL==1 - , mNumOMPThreads(1) -#endif // PARALLEL==1 -{ -#if ELBEEM_PLUGIN==1 - if(gDebugLevel<=1) setSilent(true); -#endif - mpSimTrafo = new ntlMat4Gfx(0.0); - mpSimTrafo->initId(); - - if(getenv("ELBEEM_RAWDEBUGDUMP")) { - debMsgStd("LbmSolverInterface",DM_MSG,"Using env var ELBEEM_RAWDEBUGDUMP, mDumpRawText on",2); - mDumpRawText = true; - } - - if(getenv("ELBEEM_BINDEBUGDUMP")) { - debMsgStd("LbmSolverInterface",DM_MSG,"Using env var ELBEEM_RAWDEBUGDUMP, mDumpRawText on",2); - mDumpRawBinary = true; - } -} - -LbmSolverInterface::~LbmSolverInterface() -{ - if(mpSimTrafo) delete mpSimTrafo; -} - - -/****************************************************************************** - * initialize correct grid sizes given a geometric bounding box - * and desired grid resolutions, all params except maxrefine - * will be modified - *****************************************************************************/ -void initGridSizes(int &sizex, int &sizey, int &sizez, - ntlVec3Gfx &geoStart, ntlVec3Gfx &geoEnd, - int mMaxRefine, bool parallel) -{ - // fix size inits to force cubic cells and mult4 level dimensions - const int debugGridsizeInit = 1; - if(debugGridsizeInit) debMsgStd("initGridSizes",DM_MSG,"Called - size X:"<<sizex<<" Y:"<<sizey<<" Z:"<<sizez<<" "<<geoStart<<","<<geoEnd ,10); - - int maxGridSize = sizex; // get max size - if(sizey>maxGridSize) maxGridSize = sizey; - if(sizez>maxGridSize) maxGridSize = sizez; - LbmFloat maxGeoSize = (geoEnd[0]-geoStart[0]); // get max size - if((geoEnd[1]-geoStart[1])>maxGeoSize) maxGeoSize = (geoEnd[1]-geoStart[1]); - if((geoEnd[2]-geoStart[2])>maxGeoSize) maxGeoSize = (geoEnd[2]-geoStart[2]); - // FIXME better divide max geo size by corresponding resolution rather than max? no prob for rx==ry==rz though - LbmFloat cellSize = (maxGeoSize / (LbmFloat)maxGridSize); - if(debugGridsizeInit) debMsgStd("initGridSizes",DM_MSG,"Start:"<<geoStart<<" End:"<<geoEnd<<" maxS:"<<maxGeoSize<<" maxG:"<<maxGridSize<<" cs:"<<cellSize, 10); - // force grid sizes according to geom. size, rounded - sizex = (int) ((geoEnd[0]-geoStart[0]) / cellSize +0.5); - sizey = (int) ((geoEnd[1]-geoStart[1]) / cellSize +0.5); - sizez = (int) ((geoEnd[2]-geoStart[2]) / cellSize +0.5); - // match refinement sizes, round downwards to multiple of 4 - int sizeMask = 0; - int maskBits = mMaxRefine; - if(parallel==1) maskBits+=2; - for(int i=0; i<maskBits; i++) { sizeMask |= (1<<i); } - - // at least size 4 on coarsest level - int minSize = 4<<mMaxRefine; //(maskBits+2); - if(sizex<minSize) sizex = minSize; - if(sizey<minSize) sizey = minSize; - if(sizez<minSize) sizez = minSize; - - sizeMask = ~sizeMask; - if(debugGridsizeInit) debMsgStd("initGridSizes",DM_MSG,"Size X:"<<sizex<<" Y:"<<sizey<<" Z:"<<sizez<<" m"<<convertFlags2String(sizeMask)<<", maskBits:"<<maskBits<<",minSize:"<<minSize ,10); - sizex &= sizeMask; - sizey &= sizeMask; - sizez &= sizeMask; - // debug - int nextinc = (~sizeMask)+1; - debMsgStd("initGridSizes",DM_MSG,"MPTeffMLtest, curr size:"<<PRINT_VEC(sizex,sizey,sizez)<<", next size:"<<PRINT_VEC(sizex+nextinc,sizey+nextinc,sizez+nextinc) ,10); - - // force geom size to match rounded/modified grid sizes - geoEnd[0] = geoStart[0] + cellSize*(LbmFloat)sizex; - geoEnd[1] = geoStart[1] + cellSize*(LbmFloat)sizey; - geoEnd[2] = geoStart[2] + cellSize*(LbmFloat)sizez; -} - -void calculateMemreqEstimate( int resx,int resy,int resz, - int refine, float farfield, - double *reqret, double *reqretFine, string *reqstr) { - // debug estimation? - const bool debugMemEst = true; - // COMPRESSGRIDS define is not available here, make sure it matches - const bool useGridComp = true; - // make sure we can handle bid numbers here... all double - double memCnt = 0.0; - double ddTotalNum = (double)dTotalNum; - if(reqretFine) *reqretFine = -1.; - - double currResx = (double)resx; - double currResy = (double)resy; - double currResz = (double)resz; - double rcellSize = ((currResx*currResy*currResz) *ddTotalNum); - memCnt += (double)(sizeof(CellFlagType) * (rcellSize/ddTotalNum +4.0) *2.0); - if(debugMemEst) debMsgStd("calculateMemreqEstimate",DM_MSG,"res:"<<PRINT_VEC(currResx,currResy,currResz)<<" rcellSize:"<<rcellSize<<" mc:"<<memCnt, 10); - if(!useGridComp) { - memCnt += (double)(sizeof(LbmFloat) * (rcellSize +4.0) *2.0); - if(reqretFine) *reqretFine = (double)(sizeof(LbmFloat) * (rcellSize +4.0) *2.0); - if(debugMemEst) debMsgStd("calculateMemreqEstimate",DM_MSG," no-comp, mc:"<<memCnt, 10); - } else { - double compressOffset = (double)(currResx*currResy*ddTotalNum*2.0); - memCnt += (double)(sizeof(LbmFloat) * (rcellSize+compressOffset +4.0)); - if(reqretFine) *reqretFine = (double)(sizeof(LbmFloat) * (rcellSize+compressOffset +4.0)); - if(debugMemEst) debMsgStd("calculateMemreqEstimate",DM_MSG," w-comp, mc:"<<memCnt, 10); - } - for(int i=refine-1; i>=0; i--) { - currResx /= 2.0; - currResy /= 2.0; - currResz /= 2.0; - rcellSize = ((currResz*currResy*currResx) *ddTotalNum); - memCnt += (double)(sizeof(CellFlagType) * (rcellSize/ddTotalNum +4.0) *2.0); - memCnt += (double)(sizeof(LbmFloat) * (rcellSize +4.0) *2.0); - if(debugMemEst) debMsgStd("calculateMemreqEstimate",DM_MSG,"refine "<<i<<", mc:"<<memCnt, 10); - } - - // isosurface memory, use orig res values - if(farfield>0.) { - memCnt += (double)( (3*sizeof(int)+sizeof(float)) * ((resx+2)*(resy+2)*(resz+2)) ); - } else { - // ignore 3 int slices... - memCnt += (double)( ( sizeof(float)) * ((resx+2)*(resy+2)*(resz+2)) ); - } - if(debugMemEst) debMsgStd("calculateMemreqEstimate",DM_MSG,"iso, mc:"<<memCnt, 10); - - // cpdata init check missing... - - double memd = memCnt; - const char *sizeStr = ""; - const double sfac = 1024.0; - if(memd>sfac){ memd /= sfac; sizeStr="KB"; } - if(memd>sfac){ memd /= sfac; sizeStr="MB"; } - if(memd>sfac){ memd /= sfac; sizeStr="GB"; } - if(memd>sfac){ memd /= sfac; sizeStr="TB"; } - - // return values - std::ostringstream ret; - if(memCnt< 1024.0*1024.0) { - // show full MBs - ret << (ceil(memd)); - } else { - // two digits for anything larger than MB - ret << (ceil(memd*100.0)/100.0); - } - ret << " "<< sizeStr; - *reqret = memCnt; - *reqstr = ret.str(); - //debMsgStd("LbmFsgrSolver::initialize",DM_MSG,"Required Grid memory: "<< memd <<" "<< sizeStr<<" ",4); -} - -void LbmSolverInterface::initDomainTrafo(float *mat) { - mpSimTrafo->initArrayCheck(mat); -} - -/*******************************************************************************/ -/*! parse a boundary flag string */ -CellFlagType LbmSolverInterface::readBoundaryFlagInt(string name, int defaultValue, string source,string target, bool needed) { - string val = mpSifAttrs->readString(name, "", source, target, needed); - if(!strcmp(val.c_str(),"")) { - // no value given... - return CFEmpty; - } - if(!strcmp(val.c_str(),"bnd_no")) { - return (CellFlagType)( CFBnd ); - } - if(!strcmp(val.c_str(),"bnd_free")) { - return (CellFlagType)( CFBnd ); - } - if(!strcmp(val.c_str(),"fluid")) { - /* might be used for some in/out flow cases */ - return (CellFlagType)( CFFluid ); - } - errMsg("LbmSolverInterface::readBoundaryFlagInt","Invalid value '"<<val<<"' " ); -# if FSGR_STRICT_DEBUG==1 - errFatal("readBoundaryFlagInt","Strict abort..."<<val, SIMWORLD_INITERROR); -# endif - return defaultValue; -} - -/*******************************************************************************/ -/*! parse standard attributes */ -void LbmSolverInterface::parseStdAttrList() { - if(!mpSifAttrs) { - errFatal("LbmSolverInterface::parseAttrList","mpSifAttrs pointer not initialized!",SIMWORLD_INITERROR); - return; } - - // st currently unused - mBoundaryEast = readBoundaryFlagInt("boundary_east", mBoundaryEast, "LbmSolverInterface", "mBoundaryEast", false); - mBoundaryWest = readBoundaryFlagInt("boundary_west", mBoundaryWest, "LbmSolverInterface", "mBoundaryWest", false); - mBoundaryNorth = readBoundaryFlagInt("boundary_north", mBoundaryNorth,"LbmSolverInterface", "mBoundaryNorth", false); - mBoundarySouth = readBoundaryFlagInt("boundary_south", mBoundarySouth,"LbmSolverInterface", "mBoundarySouth", false); - mBoundaryTop = readBoundaryFlagInt("boundary_top", mBoundaryTop,"LbmSolverInterface", "mBoundaryTop", false); - mBoundaryBottom= readBoundaryFlagInt("boundary_bottom", mBoundaryBottom,"LbmSolverInterface", "mBoundaryBottom", false); - - mpSifAttrs->readMat4Gfx("domain_trafo" , (*mpSimTrafo), "ntlBlenderDumper","mpSimTrafo", false, mpSimTrafo ); - - LbmVec sizeVec(mSizex,mSizey,mSizez); - sizeVec = vec2L( mpSifAttrs->readVec3d("size", vec2P(sizeVec), "LbmSolverInterface", "sizeVec", false) ); - mSizex = (int)sizeVec[0]; - mSizey = (int)sizeVec[1]; - mSizez = (int)sizeVec[2]; - // param needs size in any case - // test solvers might not have mpPara, though - if(mpParam) mpParam->setSize(mSizex, mSizey, mSizez ); - - mInitDensityGradient = mpSifAttrs->readBool("initdensitygradient", mInitDensityGradient,"LbmSolverInterface", "mInitDensityGradient", false); - mIsoValue = mpSifAttrs->readFloat("isovalue", mIsoValue, "LbmOptSolver","mIsoValue", false ); - - mDebugVelScale = mpSifAttrs->readFloat("debugvelscale", mDebugVelScale,"LbmSolverInterface", "mDebugVelScale", false); - mNodeInfoString = mpSifAttrs->readString("nodeinfo", mNodeInfoString, "SimulationLbm","mNodeInfoString", false ); - - mDumpVelocities = mpSifAttrs->readBool("dump_velocities", mDumpVelocities, "SimulationLbm","mDumpVelocities", false ); - if(getenv("ELBEEM_DUMPVELOCITIES")) { - int get = atoi(getenv("ELBEEM_DUMPVELOCITIES")); - if((get==0)||(get==1)) { - mDumpVelocities = get; - debMsgStd("LbmSolverInterface::parseAttrList",DM_NOTIFY,"Using envvar ELBEEM_DUMPVELOCITIES to set mDumpVelocities to "<<get<<","<<mDumpVelocities,8); - } - } - - // new test vars - // mTForceStrength set from test solver - mFarFieldSize = mpSifAttrs->readFloat("farfieldsize", mFarFieldSize,"LbmSolverInterface", "mFarFieldSize", false); - // old compat - float sizeScale = mpSifAttrs->readFloat("test_scale", 0.,"LbmTestdata", "mSizeScale", false); - if((mFarFieldSize<=0.)&&(sizeScale>0.)) { mFarFieldSize=sizeScale; errMsg("LbmTestdata","Warning - using mSizeScale..."); } - - mPartDropMassSub = mpSifAttrs->readFloat("part_dropmass", mPartDropMassSub,"LbmSolverInterface", "mPartDropMassSub", false); - - mCppfStage = mpSifAttrs->readInt("cppfstage", mCppfStage,"LbmSolverInterface", "mCppfStage", false); - mPartGenProb = mpSifAttrs->readFloat("partgenprob", mPartGenProb,"LbmFsgrSolver", "mPartGenProb", false); - mPartUsePhysModel = mpSifAttrs->readBool("partusephysmodel", mPartUsePhysModel,"LbmFsgrSolver", "mPartUsePhysModel", false); - mIsoSubdivs = mpSifAttrs->readInt("isosubdivs", mIsoSubdivs,"LbmFsgrSolver", "mIsoSubdivs", false); -} - - -/*******************************************************************************/ -/*! geometry initialization */ -/*******************************************************************************/ - -/*****************************************************************************/ -/*! init tree for certain geometry init */ -void LbmSolverInterface::initGeoTree() { - if(mpGlob == NULL) { errFatal("LbmSolverInterface::initGeoTree","Requires globals!",SIMWORLD_INITERROR); return; } - ntlScene *scene = mpGlob->getSimScene(); - mpGiObjects = scene->getObjects(); - mGiObjInside.resize( mpGiObjects->size() ); - mGiObjDistance.resize( mpGiObjects->size() ); - mGiObjSecondDist.resize( mpGiObjects->size() ); - for(size_t i=0; i<mpGiObjects->size(); i++) { - if((*mpGiObjects)[i]->getGeoInitIntersect()) mAccurateGeoinit=true; - //debMsgStd("LbmSolverInterface::initGeoTree",DM_MSG,"id:"<<mLbmInitId<<" obj:"<< (*mpGiObjects)[i]->getName() <<" gid:"<<(*mpGiObjects)[i]->getGeoInitId(), 9 ); - } - debMsgStd("LbmSolverInterface::initGeoTree",DM_MSG,"Accurate geo init: "<<mAccurateGeoinit, 9) - debMsgStd("LbmSolverInterface::initGeoTree",DM_MSG,"Objects: "<<mpGiObjects->size() ,10); - - if(mpGiTree != NULL) delete mpGiTree; - char treeFlag = (1<<(this->mLbmInitId+4)); - mpGiTree = new ntlTree( -# if FSGR_STRICT_DEBUG!=1 - 15, 8, // TREEwarning - fixed values for depth & maxtriangles here... -# else // FSGR_STRICT_DEBUG==1 - 10, 20, // reduced/slower debugging values -# endif // FSGR_STRICT_DEBUG==1 - scene, treeFlag ); -} - -/*****************************************************************************/ -/*! destroy tree etc. when geometry init done */ -void LbmSolverInterface::freeGeoTree() { - if(mpGiTree != NULL) { - delete mpGiTree; - mpGiTree = NULL; - } -} - - -int globGeoInitDebug = 0; -int globGICPIProblems = 0; -/*****************************************************************************/ -/*! check for a certain flag type at position org */ -bool LbmSolverInterface::geoInitCheckPointInside(ntlVec3Gfx org, int flags, int &OId, gfxReal &distance, int shootDir) { - // shift ve ctors to avoid rounding errors - org += ntlVec3Gfx(0.0001); - OId = -1; - - // select shooting direction - ntlVec3Gfx dir = ntlVec3Gfx(1., 0., 0.); - if(shootDir==1) dir = ntlVec3Gfx(0., 1., 0.); - else if(shootDir==2) dir = ntlVec3Gfx(0., 0., 1.); - else if(shootDir==-2) dir = ntlVec3Gfx(0., 0., -1.); - else if(shootDir==-1) dir = ntlVec3Gfx(0., -1., 0.); - - ntlRay ray(org, dir, 0, 1.0, mpGlob); - bool done = false; - bool inside = false; - - vector<int> giObjFirstHistSide; - giObjFirstHistSide.resize( mpGiObjects->size() ); - for(size_t i=0; i<mGiObjInside.size(); i++) { - mGiObjInside[i] = 0; - mGiObjDistance[i] = -1.0; - mGiObjSecondDist[i] = -1.0; - giObjFirstHistSide[i] = 0; - } - // if not inside, return distance to first hit - gfxReal firstHit=-1.0; - int firstOId = -1; - if(globGeoInitDebug) errMsg("IIIstart"," isect "<<org<<" f"<<flags<<" acc"<<mAccurateGeoinit); - - if(mAccurateGeoinit) { - while(!done) { - // find first inside intersection - ntlTriangle *triIns = NULL; - distance = -1.0; - ntlVec3Gfx normal(0.0); - if(shootDir==0) mpGiTree->intersectX(ray,distance,normal, triIns, flags, true); - else mpGiTree->intersect(ray,distance,normal, triIns, flags, true); - if(triIns) { - ntlVec3Gfx norg = ray.getOrigin() + ray.getDirection()*distance; - LbmFloat orientation = dot(normal, dir); - OId = triIns->getObjectId(); - if(orientation<=0.0) { - // outside hit - normal *= -1.0; - mGiObjInside[OId]++; - if(giObjFirstHistSide[OId]==0) giObjFirstHistSide[OId] = 1; - if(globGeoInitDebug) errMsg("IIO"," oid:"<<OId<<" org"<<org<<" norg"<<norg<<" orient:"<<orientation); - } else { - // inside hit - mGiObjInside[OId]++; - if(mGiObjDistance[OId]<0.0) mGiObjDistance[OId] = distance; - if(globGeoInitDebug) errMsg("III"," oid:"<<OId<<" org"<<org<<" norg"<<norg<<" orient:"<<orientation); - if(giObjFirstHistSide[OId]==0) giObjFirstHistSide[OId] = -1; - } - norg += normal * getVecEpsilon(); - ray = ntlRay(norg, dir, 0, 1.0, mpGlob); - // remember first hit distance, in case we're not - // inside anything - if(firstHit<0.0) { - firstHit = distance; - firstOId = OId; - } - } else { - // no more intersections... return false - done = true; - } - } - - distance = -1.0; - for(size_t i=0; i<mGiObjInside.size(); i++) { - if(mGiObjInside[i]>0) { - bool mess = false; - if((mGiObjInside[i]%2)==1) { - if(giObjFirstHistSide[i] != -1) mess=true; - } else { - if(giObjFirstHistSide[i] != 1) mess=true; - } - if(mess) { - //errMsg("IIIproblem","At "<<org<<" obj "<<i<<" inside:"<<mGiObjInside[i]<<" firstside:"<<giObjFirstHistSide[i] ); - globGICPIProblems++; - mGiObjInside[i]++; // believe first hit side... - } - } - } - for(size_t i=0; i<mGiObjInside.size(); i++) { - if(globGeoInitDebug) errMsg("CHIII","i"<<i<<" ins="<<mGiObjInside[i]<<" t"<<mGiObjDistance[i]<<" d"<<distance); - if(((mGiObjInside[i]%2)==1)&&(mGiObjDistance[i]>0.0)) { - if( (distance<0.0) || // first intersection -> good - ((distance>0.0)&&(distance>mGiObjDistance[i])) // more than one intersection -> use closest one - ) { - distance = mGiObjDistance[i]; - OId = i; - inside = true; - } - } - } - if(!inside) { - distance = firstHit; - OId = firstOId; - } - if(globGeoInitDebug) errMsg("CHIII","i"<<inside<<" fh"<<firstHit<<" fo"<<firstOId<<" - h"<<distance<<" o"<<OId); - - return inside; - } else { - - // find first inside intersection - ntlTriangle *triIns = NULL; - distance = -1.0; - ntlVec3Gfx normal(0.0); - if(shootDir==0) mpGiTree->intersectX(ray,distance,normal, triIns, flags, true); - else mpGiTree->intersect(ray,distance,normal, triIns, flags, true); - if(triIns) { - // check outside intersect - LbmFloat orientation = dot(normal, dir); - if(orientation<=0.0) return false; - - OId = triIns->getObjectId(); - return true; - } - return false; - } -} -bool LbmSolverInterface::geoInitCheckPointInside(ntlVec3Gfx org, ntlVec3Gfx dir, int flags, int &OId, gfxReal &distance, const gfxReal halfCellsize, bool &thinHit, bool recurse) { - // shift ve ctors to avoid rounding errors - org += ntlVec3Gfx(0.0001); //? - OId = -1; - ntlRay ray(org, dir, 0, 1.0, mpGlob); - //int insCnt = 0; - bool done = false; - bool inside = false; - for(size_t i=0; i<mGiObjInside.size(); i++) { - mGiObjInside[i] = 0; - mGiObjDistance[i] = -1.0; - mGiObjSecondDist[i] = -1.0; - } - // if not inside, return distance to first hit - gfxReal firstHit=-1.0; - int firstOId = -1; - thinHit = false; - - if(mAccurateGeoinit) { - while(!done) { - // find first inside intersection - ntlTriangle *triIns = NULL; - distance = -1.0; - ntlVec3Gfx normal(0.0); - mpGiTree->intersect(ray,distance,normal, triIns, flags, true); - if(triIns) { - ntlVec3Gfx norg = ray.getOrigin() + ray.getDirection()*distance; - LbmFloat orientation = dot(normal, dir); - OId = triIns->getObjectId(); - if(orientation<=0.0) { - // outside hit - normal *= -1.0; - //mGiObjDistance[OId] = -1.0; - //errMsg("IIO"," oid:"<<OId<<" org"<<org<<" norg"<<norg); - } else { - // inside hit - //if(mGiObjDistance[OId]<0.0) mGiObjDistance[OId] = distance; - //errMsg("III"," oid:"<<OId<<" org"<<org<<" norg"<<norg); - if(mGiObjInside[OId]==1) { - // second inside hit - if(mGiObjSecondDist[OId]<0.0) mGiObjSecondDist[OId] = distance; - } - } - mGiObjInside[OId]++; - // always store first hit for thin obj init - if(mGiObjDistance[OId]<0.0) mGiObjDistance[OId] = distance; - - norg += normal * getVecEpsilon(); - ray = ntlRay(norg, dir, 0, 1.0, mpGlob); - // remember first hit distance, in case we're not - // inside anything - if(firstHit<0.0) { - firstHit = distance; - firstOId = OId; - } - } else { - // no more intersections... return false - done = true; - //if(insCnt%2) inside=true; - } - } - - distance = -1.0; - // standard inside check - for(size_t i=0; i<mGiObjInside.size(); i++) { - if(((mGiObjInside[i]%2)==1)&&(mGiObjDistance[i]>0.0)) { - if( (distance<0.0) || // first intersection -> good - ((distance>0.0)&&(distance>mGiObjDistance[i])) // more than one intersection -> use closest one - ) { - distance = mGiObjDistance[i]; - OId = i; - inside = true; - } - } - } - // now check for thin hits - if(!inside) { - distance = -1.0; - for(size_t i=0; i<mGiObjInside.size(); i++) { - if((mGiObjInside[i]>=2)&&(mGiObjDistance[i]>0.0)&&(mGiObjSecondDist[i]>0.0)&& - (mGiObjDistance[i]<1.0*halfCellsize)&&(mGiObjSecondDist[i]<2.0*halfCellsize) ) { - if( (distance<0.0) || // first intersection -> good - ((distance>0.0)&&(distance>mGiObjDistance[i])) // more than one intersection -> use closest one - ) { - distance = mGiObjDistance[i]; - OId = i; - inside = true; - thinHit = true; - } - } - } - } - if(!inside) { - // check for hit in this cell, opposite to current dir (only recurse once) - if(recurse) { - gfxReal r_distance; - int r_OId; - bool ret = geoInitCheckPointInside(org, dir*-1.0, flags, r_OId, r_distance, halfCellsize, thinHit, false); - if((ret)&&(thinHit)) { - OId = r_OId; - distance = 0.0; - return true; - } - } - } - // really no hit... - if(!inside) { - distance = firstHit; - OId = firstOId; - /*if((mGiObjDistance[OId]>0.0)&&(mGiObjSecondDist[OId]>0.0)) { - const gfxReal thisdist = mGiObjSecondDist[OId]-mGiObjDistance[OId]; - // dont walk over this cell... - if(thisdist<halfCellsize) distance-=2.0*halfCellsize; - } // ? */ - } - //errMsg("CHIII","i"<<inside<<" fh"<<firstHit<<" fo"<<firstOId<<" - h"<<distance<<" o"<<OId); - - return inside; - } else { - - // find first inside intersection - ntlTriangle *triIns = NULL; - distance = -1.0; - ntlVec3Gfx normal(0.0); - mpGiTree->intersect(ray,distance,normal, triIns, flags, true); - if(triIns) { - // check outside intersect - LbmFloat orientation = dot(normal, dir); - if(orientation<=0.0) return false; - - OId = triIns->getObjectId(); - return true; - } - return false; - } -} - - -/*****************************************************************************/ -ntlVec3Gfx LbmSolverInterface::getGeoMaxMovementVelocity(LbmFloat simtime, LbmFloat stepsize) { - ntlVec3Gfx max(0.0); - if(mpGlob == NULL) return max; - // mpGiObjects has to be inited here... - - for(int i=0; i< (int)mpGiObjects->size(); i++) { - //errMsg("LbmSolverInterface::getGeoMaxMovementVelocity","i="<<i<<" "<< (*mpGiObjects)[i]->getName() ); // DEBUG - if( (*mpGiObjects)[i]->getGeoInitType() & (FGI_FLUID|FGI_MBNDINFLOW) ){ - //ntlVec3Gfx objMaxVel = obj->calculateMaxVel(sourceTime,targetTime); - ntlVec3Gfx orgvel = (*mpGiObjects)[i]->calculateMaxVel( simtime, simtime+stepsize ); - if( normNoSqrt(orgvel) > normNoSqrt(max) ) { max = orgvel; } - //errMsg("MVT","i"<<i<<" a"<< (*mpGiObjects)[i]->getInitialVelocity(simtime)<<" o"<<orgvel ); // DEBUG - // TODO check if inflow and simtime - ntlVec3Gfx inivel = (*mpGiObjects)[i]->getInitialVelocity(simtime); - if( normNoSqrt(inivel) > normNoSqrt(max) ) { max = inivel; } - } - } - errMsg("LbmSolverInterface::getGeoMaxMovementVelocity", "max="<< max ); // DEBUG - return max; -} - - - - -/*******************************************************************************/ -/*! cell iteration functions */ -/*******************************************************************************/ - - - - -/*****************************************************************************/ -//! add cell to mMarkedCells list -void -LbmSolverInterface::addCellToMarkedList( CellIdentifierInterface *cid ) { - for(size_t i=0; i<mMarkedCells.size(); i++) { - // check if cids alreay in - if( mMarkedCells[i]->equal(cid) ) return; - //mMarkedCells[i]->setEnd(false); - } - mMarkedCells.push_back( cid ); - //cid->setEnd(true); -} - -/*****************************************************************************/ -//! marked cell iteration methods -CellIdentifierInterface* -LbmSolverInterface::markedGetFirstCell( ) { - if(mMarkedCells.size() > 0){ return mMarkedCells[0]; } - return NULL; -} - -CellIdentifierInterface* -LbmSolverInterface::markedAdvanceCell() { - mMarkedCellIndex++; - if(mMarkedCellIndex>=(int)mMarkedCells.size()) return NULL; - return mMarkedCells[mMarkedCellIndex]; -} - -void LbmSolverInterface::markedClearList() { - // FIXME free cids? - mMarkedCells.clear(); -} - -#if PARALLEL==1 -void LbmSolverInterface::setNumOMPThreads(int num_threads) { - mNumOMPThreads = num_threads; -} -#endif // PARALLEL==1 - -/*******************************************************************************/ -/*! string helper functions */ -/*******************************************************************************/ - - - -// 32k -string convertSingleFlag2String(CellFlagType cflag) { - CellFlagType flag = cflag; - if(flag == CFUnused ) return string("cCFUnused"); - if(flag == CFEmpty ) return string("cCFEmpty"); - if(flag == CFBnd ) return string("cCFBnd"); - if(flag == CFBndNoslip ) return string("cCFBndNoSlip"); - if(flag == CFBndFreeslip ) return string("cCFBndFreeSlip"); - if(flag == CFBndPartslip ) return string("cCFBndPartSlip"); - if(flag == CFNoInterpolSrc ) return string("cCFNoInterpolSrc"); - if(flag == CFFluid ) return string("cCFFluid"); - if(flag == CFInter ) return string("cCFInter"); - if(flag == CFNoNbFluid ) return string("cCFNoNbFluid"); - if(flag == CFNoNbEmpty ) return string("cCFNoNbEmpty"); - if(flag == CFNoDelete ) return string("cCFNoDelete"); - if(flag == CFNoBndFluid ) return string("cCFNoBndFluid"); - if(flag == CFGrNorm ) return string("cCFGrNorm"); - if(flag == CFGrFromFine ) return string("cCFGrFromFine"); - if(flag == CFGrFromCoarse ) return string("cCFGrFromCoarse"); - if(flag == CFGrCoarseInited ) return string("cCFGrCoarseInited"); - if(flag == CFMbndInflow ) return string("cCFMbndInflow"); - if(flag == CFMbndOutflow ) return string("cCFMbndOutflow"); - if(flag == CFInvalid ) return string("cfINVALID"); - - std::ostringstream mult; - int val = 0; - if(flag != 0) { - while(! (flag&1) ) { - flag = flag>>1; - val++; - } - } else { - val = -1; - } - if(val>=24) { - mult << "cfOID_" << (flag>>24) <<"_TYPE"; - } else { - mult << "cfUNKNOWN_" << val <<"_TYPE"; - } - return mult.str(); -} - -//! helper function to convert flag to string (for debuggin) -string convertCellFlagType2String( CellFlagType cflag ) { - int flag = cflag; - - const int jmax = sizeof(CellFlagType)*8; - bool somefound = false; - std::ostringstream mult; - mult << "["; - for(int j=0; j<jmax ; j++) { - if(flag& (1<<j)) { - if(somefound) mult << "|"; - mult << j<<"<"<< convertSingleFlag2String( (CellFlagType)(1<<j) ); // this call should always be _non_-recursive - somefound = true; - } - }; - mult << "]"; - - // return concatenated string - if(somefound) return mult.str(); - - // empty? - return string("[emptyCFT]"); -} - diff --git a/intern/elbeem/intern/solver_interface.h b/intern/elbeem/intern/solver_interface.h deleted file mode 100644 index 1301e0f6ebb..00000000000 --- a/intern/elbeem/intern/solver_interface.h +++ /dev/null @@ -1,639 +0,0 @@ -/** \file - * \ingroup elbeem - */ -/****************************************************************************** - * - * El'Beem - Free Surface Fluid Simulation with the Lattice Boltzmann Method - * All code distributed as part of El'Beem is covered by the version 2 of the - * GNU General Public License. See the file COPYING for details. - * Copyright 2003-2006 Nils Thuerey - * - * Header for Combined 2D/3D Lattice Boltzmann Interface Class - * - *****************************************************************************/ -#ifndef LBMINTERFACE_H -#define LBMINTERFACE_H - -//! include gui support? -#ifndef NOGUI -#define LBM_USE_GUI 1 -#else -#define LBM_USE_GUI 0 -#endif - -#if LBM_USE_GUI==1 -#define USE_GLUTILITIES -// for debug display -//#include <GL/gl.h> -#include "../gui/guifuncs.h" -#endif - -#include <sstream> -#include "utilities.h" -#include "ntl_bsptree.h" -#include "ntl_geometryobject.h" -#include "parametrizer.h" -#include "attributes.h" -#include "isosurface.h" - -#ifdef WITH_CXX_GUARDEDALLOC -# include "MEM_guardedalloc.h" -#endif - -class ParticleTracer; -class ParticleObject; - -// use which fp-precision for LBM? 1=float, 2=double -#ifdef PRECISION_LBM_SINGLE -#define LBM_PRECISION 1 -#else -#ifdef PRECISION_LBM_DOUBLE -#define LBM_PRECISION 2 -#else -// default to floats -#define LBM_PRECISION 1 -#endif -#endif - -#if LBM_PRECISION==1 -/* low precision for LBM solver */ -typedef float LbmFloat; -typedef ntlVec3f LbmVec; -#define LBM_EPSILON (1e-5) -#else -/* standard precision for LBM solver */ -typedef double LbmFloat; -typedef ntlVec3d LbmVec; -#define LBM_EPSILON (1e-10) -#endif - -// long integer, needed e.g. for memory calculations -#ifndef USE_MSVC6FIXES -#define LONGINT long long int -#else -#define LONGINT _int64 -#endif - - -// default to 3dim -#ifndef LBMDIM -#define LBMDIM 3 -#endif // LBMDIM - -#if LBMDIM==2 -#define LBM_DFNUM 9 -#else -#define LBM_DFNUM 19 -#endif - -// conversions (lbm and parametrizer) -template<class T> inline LbmVec vec2L(T v) { return LbmVec(v[0],v[1],v[2]); } -template<class T> inline ParamVec vec2P(T v) { return ParamVec(v[0],v[1],v[2]); } - -template<class Scalar> class ntlMatrix4x4; - - -// bubble id type -typedef int BubbleId; - -// basic cell type distinctions -#define CFUnused (1<< 0) -#define CFEmpty (1<< 1) -#define CFBnd (1<< 2) -#define CFMbndInflow (1<< 3) -#define CFMbndOutflow (1<< 4) -#define CFFluid (1<< 5) -#define CFInter (1<< 6) -// additional for fluid (needed separately for adaptive grids) -#define CFNoBndFluid (1<< 7) -#define CFNoDelete (1<< 8) - -// additional bnd add flags -#define CFBndNoslip (1<< 9) -#define CFBndFreeslip (1<<10) -#define CFBndPartslip (1<<11) -#define CFBndMoving (1<<12) - -// additional for fluid/interface -// force symmetry for flag reinit -#define CFNoInterpolSrc (1<<13) -#define CFNoNbFluid (1<<14) -#define CFNoNbEmpty (1<<15) - -// cell treated normally on coarser grids -#define CFGrNorm (1<<16) -#define CFGrCoarseInited (1<<17) - -// (the following values shouldnt overlap to ensure -// proper coarsening) -// border cells to be interpolated from finer grid -#define CFGrFromFine (1<<18) -// 32k aux border marker -#define CFGrToFine (1<<19) -// also needed on finest level -#define CFGrFromCoarse (1<<20) -// additional refinement tags (coarse grids only?) -// */ - -// above 24 is used to encode in/outflow object type -#define CFPersistMask (0xFF000000 | CFMbndInflow | CFMbndOutflow) -#define CFNoPersistMask (~CFPersistMask) - - -// nk -#define CFInvalid (CellFlagType)(1<<31) - -// use 32bit flag types -//#ifdef __x86_64__ - //typedef int cfINT32; -//#else - //typedef long cfINT32; -//#endif // defined (_IA64) -//#define CellFlagType cfINT32 -#define CellFlagType int -#define CellFlagTypeSize 4 - - -// aux. field indices (same for 2d) -#define dFfrac 19 -#define dMass 20 -#define dFlux 21 -// max. no. of cell values for 3d -#define dTotalNum 22 - - -/*****************************************************************************/ -/*! a single lbm cell */ -/* the template is only needed for - * dimension dependend constants e.g. - * number of df's in model */ -class LbmCellContents { - public: - LbmFloat df[ 27 ]; // be on the safe side here... - LbmFloat rho; - LbmVec vel; - LbmFloat mass; - CellFlagType flag; - BubbleId bubble; - LbmFloat ffrac; - -private: -#ifdef WITH_CXX_GUARDEDALLOC - MEM_CXX_CLASS_ALLOC_FUNCS("ELBEEM:LbmCellContents") -#endif -}; - -/* struct for the coordinates of a cell in the grid */ -typedef struct { - int x,y,z; - int flag; // special handling? -} LbmPoint; - -/* struct for the coordinates of a cell in the grid */ -typedef struct { - char active; // bubble in use, oder may be overwritten? - LbmFloat volume; // volume of this bubble (0 vor atmosphere) - LbmFloat mass; // "mass" of bubble - int i,j,k; // index of a cell in the bubble -} LbmBubble; - - - - -//! choose which data to display -#define FLUIDDISPINVALID 0 -#define FLUIDDISPNothing 1 -#define FLUIDDISPCelltypes 2 -#define FLUIDDISPVelocities 3 -#define FLUIDDISPCellfills 4 -#define FLUIDDISPDensity 5 -#define FLUIDDISPGrid 6 -#define FLUIDDISPSurface 7 - - - -/*****************************************************************************/ -//! cell identifier interface -class CellIdentifierInterface { - public: - //! reset constructor - CellIdentifierInterface():mEnd(false) { }; - //! virtual destructor - virtual ~CellIdentifierInterface() {}; - - //! return node as string (with some basic info) - virtual string getAsString() = 0; - - //! compare cids - virtual bool equal(CellIdentifierInterface* other) = 0; - - //! set/get end flag for grid traversal (not needed for marked cells) - inline void setEnd(bool set){ mEnd = set; } - inline bool getEnd( ) { return mEnd; } - - //! has the grid been traversed? - bool mEnd; - -private: -#ifdef WITH_CXX_GUARDEDALLOC - MEM_CXX_CLASS_ALLOC_FUNCS("ELBEEM:CellIdentifierInterface") -#endif -}; - - - -/*****************************************************************************/ -/*! class defining abstract function interface */ -/* has to provide iterating functionality */ -class LbmSolverInterface -{ - public: - //! Constructor - LbmSolverInterface(); - //! Destructor - virtual ~LbmSolverInterface(); - //! id string of solver - virtual string getIdString() = 0; - - // multi step solver init - /*! finish the init with config file values (allocate arrays...) */ - virtual bool initializeSolverMemory() =0; - /*! init solver arrays */ - virtual bool initializeSolverGrids() =0; - /*! prepare actual simulation start, setup viz etc */ - virtual bool initializeSolverPostinit() =0; - - /*! notify object that dump is in progress (e.g. for field dump) */ - virtual void notifySolverOfDump(int dumptype, int frameNr,char *frameNrStr,string outfilename) = 0; - - /*! parse a boundary flag string */ - CellFlagType readBoundaryFlagInt(string name, int defaultValue, string source,string target, bool needed); - /*! parse standard attributes */ - void parseStdAttrList(); - /*! initilize variables fom attribute list (should at least call std parse) */ - virtual void parseAttrList() = 0; - - virtual void step() = 0; - virtual void prepareVisualization() { /* by default off */ }; - - /*! particle handling */ - virtual int initParticles() = 0; - virtual void advanceParticles() = 0; - /*! get surface object (NULL if no surface) */ - IsoSurface* getSurfaceGeoObj() { return mpIso; } - - /*! debug object display */ - virtual vector<ntlGeometryObject*> getDebugObjects() { vector<ntlGeometryObject*> empty(0); return empty; } - - /* surface generation settings */ - virtual void setSurfGenSettings(short value) = 0; - -#if LBM_USE_GUI==1 - /*! show simulation info */ - virtual void debugDisplay(int) = 0; -#endif - - /*! init tree for certain geometry init */ - void initGeoTree(); - /*! destroy tree etc. when geometry init done */ - void freeGeoTree(); - /*! check for a certain flag type at position org (needed for e.g. quadtree refinement) */ - bool geoInitCheckPointInside(ntlVec3Gfx org, int flags, int &OId, gfxReal &distance,int shootDir=0); - bool geoInitCheckPointInside(ntlVec3Gfx org, ntlVec3Gfx dir, int flags, int &OId, gfxReal &distance, - const gfxReal halfCellsize, bool &thinHit, bool recurse); - /*! set render globals, for scene/tree access */ - void setRenderGlobals(ntlRenderGlobals *glob) { mpGlob = glob; }; - /*! get max. velocity of all objects to initialize as fluid regions, and of all moving objects */ - ntlVec3Gfx getGeoMaxMovementVelocity(LbmFloat simtime, LbmFloat stepsize); - - /* rt interface functions */ - unsigned int getIsoVertexCount() { return mpIso->getIsoVertexCount(); } - unsigned int getIsoIndexCount() { return mpIso->getIsoIndexCount(); } - char* getIsoVertexArray() { return mpIso->getIsoVertexArray(); } - unsigned int *getIsoIndexArray() { return mpIso->getIsoIndexArray(); } - void triangulateSurface() { mpIso->triangulate(); } - - /* access functions */ - - /*! return grid sizes */ - int getSizeX( void ) { return mSizex; } - int getSizeY( void ) { return mSizey; } - int getSizeZ( void ) { return mSizez; } - /*! return grid sizes */ - void setSizeX( int ns ) { mSizex = ns; } - void setSizeY( int ns ) { mSizey = ns; } - void setSizeZ( int ns ) { mSizez = ns; } - /*! access fluid only simulation flag */ - void setAllfluid(bool set) { mAllfluid=set; } - bool getAllfluid() { return mAllfluid; } - - /*! set attr list pointer */ - void setAttrList(AttributeList *set) { mpSifAttrs = set; } - /*! Returns the attribute list pointer */ - inline AttributeList *getAttributeList() { return mpSifAttrs; } - /*! set sws attr list pointer */ - void setSwsAttrList(AttributeList *set) { mpSifSwsAttrs = set; } - inline AttributeList *getSwsAttributeList() { return mpSifSwsAttrs; } - - /*! set parametrizer pointer */ - inline void setParametrizer(Parametrizer *set) { mpParam = set; } - /*! get parametrizer pointer */ - inline Parametrizer *getParametrizer() { return mpParam; } - /*! get/set particle pointer */ - inline void setParticleTracer(ParticleTracer *set) { mpParticles = set; } - inline ParticleTracer *getParticleTracer() { return mpParticles; } - - /*! set density gradient init from e.g. init test cases */ - inline void setInitDensityGradient(bool set) { mInitDensityGradient = set; } - - /*! access geometry start vector */ - inline void setGeoStart(ntlVec3Gfx set) { mvGeoStart = set; } - inline ntlVec3Gfx getGeoStart() const { return mvGeoStart; } - - /*! access geometry end vector */ - inline void setGeoEnd(ntlVec3Gfx set) { mvGeoEnd = set; } - inline ntlVec3Gfx getGeoEnd() const { return mvGeoEnd; } - - /*! access geo init vars */ - inline void setLbmInitId(int set) { mLbmInitId = set; } - inline int getLbmInitId() const { return mLbmInitId; } - - /*! init domain transformation matrix from float array */ - void initDomainTrafo(float *mat); - /*! get domain transformation matrix to have object centered fluid vertices */ - inline ntlMatrix4x4<gfxReal> *getDomainTrafo() { return mpSimTrafo; } - - /*! access name string */ - inline void setName(string set) { mName = set; } - inline string getName() const { return mName; } - - /*! access string for node info debugging output */ - inline string getNodeInfoString() const { return mNodeInfoString; } - - /*! get panic flag */ - inline bool getPanic() { return mPanic; } - - //! set silent mode? - inline void setSilent(bool set){ mSilent = set; } - - //! set amount of surface/normal smoothing - inline void setSmoothing(float setss,float setns){ mSmoothSurface=setss; mSmoothNormals=setns; } - //! set amount of iso subdivisions - inline void setIsoSubdivs(int s){ mIsoSubdivs=s; } - //! set desired refinement - inline void setPreviewSize(int set){ mOutputSurfacePreview = set; } - //! set desired refinement - inline void setRefinementDesired(int set){ mRefinementDesired = set; } - - //! set/get dump velocities flag - inline void setDumpVelocities(bool set) { mDumpVelocities = set; } - inline bool getDumpVelocities() const { return mDumpVelocities; } - - //! set/get particle generation prob. - inline void setGenerateParticles(LbmFloat set) { mPartGenProb = set; } - inline LbmFloat getGenerateParticles() const { return mPartGenProb; } - - //! set/get dump velocities flag - inline void setDomainBound(string set) { mDomainBound = set; } - inline string getDomainBound() const { return mDomainBound; } - //! set/get dump velocities flag - inline void setDomainPartSlip(LbmFloat set) { mDomainPartSlipValue = set; } - inline LbmFloat getDomainPartSlip() const { return mDomainPartSlipValue; } - //! set/get far field size - inline void setFarFieldSize(LbmFloat set) { mFarFieldSize = set; } - inline LbmFloat getFarFieldSize() const { return mFarFieldSize; } - //! set/get cp stage - inline void setCpStage(int set) { mCppfStage = set; } - inline int getCpStage() const { return mCppfStage; } - //! set/get dump modes - inline void setDumpRawText(bool set) { mDumpRawText = set; } - inline bool getDumpRawText() const { return mDumpRawText; } - inline void setDumpRawBinary(bool set) { mDumpRawBinary = set; } - inline bool getDumpRawBinary() const { return mDumpRawBinary; } - inline void setDumpRawBinaryZip(bool set) { mDumpRawBinaryZip = set; } - inline bool getDumpRawBinaryZip() const { return mDumpRawBinaryZip; } - //! set/get debug vel scale - inline void setDebugVelScale(LbmFloat set) { mDebugVelScale = set; } - inline LbmFloat getDebugVelScale() const { return mDebugVelScale; } - - // cell iterator interface - - // cell id type - typedef CellIdentifierInterface* CellIdentifier; - - //! cell iteration methods - virtual CellIdentifierInterface* getFirstCell( ) = 0; - virtual void advanceCell( CellIdentifierInterface* ) = 0; - virtual bool noEndCell( CellIdentifierInterface* ) = 0; - //! clean up iteration, this should be called, when the iteration is not completely finished - virtual void deleteCellIterator( CellIdentifierInterface** ) = 0; - - //! find cell at a given position (returns NULL if not in domain) - virtual CellIdentifierInterface* getCellAt( ntlVec3Gfx pos ) = 0; - - //! return node information - virtual int getCellSet ( CellIdentifierInterface* ) = 0; - virtual ntlVec3Gfx getCellOrigin ( CellIdentifierInterface* ) = 0; - virtual ntlVec3Gfx getCellSize ( CellIdentifierInterface* ) = 0; - virtual int getCellLevel ( CellIdentifierInterface* ) = 0; - virtual LbmFloat getCellDensity ( CellIdentifierInterface*,int ) = 0; - virtual LbmVec getCellVelocity ( CellIdentifierInterface*,int ) = 0; - /*! get equilibrium distribution functions */ - virtual LbmFloat getEquilDf ( int ) = 0; - /*! redundant cell functions */ - virtual LbmFloat getCellDf ( CellIdentifierInterface* ,int set, int dir) = 0; - virtual LbmFloat getCellMass ( CellIdentifierInterface* ,int set) = 0; - virtual LbmFloat getCellFill ( CellIdentifierInterface* ,int set) = 0; - virtual CellFlagType getCellFlag ( CellIdentifierInterface* ,int set) = 0; - - /*! get velocity directly from position */ - virtual ntlVec3Gfx getVelocityAt(float x, float y, float z) = 0; - - // gui/output debugging functions -#if LBM_USE_GUI==1 - virtual void debugDisplayNode(int dispset, CellIdentifier cell ) = 0; - virtual void lbmDebugDisplay(int dispset) = 0; - virtual void lbmMarkedCellDisplay() = 0; -#endif // LBM_USE_GUI==1 - virtual void debugPrintNodeInfo(CellIdentifier cell, int forceSet=-1) = 0; - - // debugging cell marker functions - - //! add cell to mMarkedCells list - void addCellToMarkedList( CellIdentifierInterface *cid ); - //! marked cell iteration methods - CellIdentifierInterface* markedGetFirstCell( ); - CellIdentifierInterface* markedAdvanceCell(); - void markedClearList(); - -#if PARALLEL==1 - void setNumOMPThreads(int num_threads); -#endif // PARALLEL==1 - protected: - - /*! abort simulation on error... */ - bool mPanic; - - - /*! Size of the array in x,y,z direction */ - int mSizex, mSizey, mSizez; - /*! only fluid in sim? */ - bool mAllfluid; - - - /*! step counter */ - int mStepCnt; - - /*! mass change from one step to the next, for extreme cases fix globally */ - LbmFloat mFixMass; - - // deprecated param vars - /*! omega for lbm */ - LbmFloat mOmega; - /*! gravity strength in neg. z direction */ - LbmVec mGravity; - /*! Surface tension of the fluid */ - LbmFloat mSurfaceTension; - - - /* boundary inits */ - CellFlagType mBoundaryEast, mBoundaryWest, - mBoundaryNorth, mBoundarySouth, - mBoundaryTop, mBoundaryBottom; - - /*! initialization from config file done? */ - int mInitDone; - - /*! init density gradient? */ - bool mInitDensityGradient; - - /*! pointer to the attribute list, only pointer to obj attrs */ - AttributeList *mpSifAttrs; - AttributeList *mpSifSwsAttrs; - - /*! get parameters from this parametrize in finishInit */ - Parametrizer *mpParam; - //! store particle tracer - ParticleTracer *mpParticles; - - /*! number of particles lost so far */ - int mNumParticlesLost; - /*! number of particles lost so far */ - int mNumInvalidDfs; - /*! no of filled/emptied cells per time step */ - int mNumFilledCells, mNumEmptiedCells; - /*! counter number of used cells for performance */ - int mNumUsedCells; - /*! MLSUPS counter */ - LbmFloat mMLSUPS; - /*! debug - velocity output scaling factor */ - LbmFloat mDebugVelScale; - /*! string for node info debugging output */ - string mNodeInfoString; - - // geo init vars - // TODO deprecate SimulationObject vars - - /*! for display - start and end vectors for geometry */ - ntlVec3Gfx mvGeoStart, mvGeoEnd; - //! domain vertex trafos - ntlMatrix4x4<gfxReal> *mpSimTrafo; - - /*! perform accurate geometry init? */ - bool mAccurateGeoinit; - - /*! name of this lbm object (for debug output) */ - string mName; - - //! Mcubes object for surface reconstruction - IsoSurface *mpIso; - /*! isolevel value for marching cubes surface reconstruction */ - LbmFloat mIsoValue; - - //! debug output? - bool mSilent; - - /*! geometry init id, passed from ntl_geomclass */ - int mLbmInitId; - /*! tree object for geomerty initialization */ - ntlTree *mpGiTree; - /*! object vector for geo init */ - vector<ntlGeometryObject*> *mpGiObjects; - /*! inside which objects? */ - vector<int> mGiObjInside; - /*! inside which objects? */ - vector<gfxReal> mGiObjDistance; - vector<gfxReal> mGiObjSecondDist; - /*! remember globals */ - ntlRenderGlobals *mpGlob; - - //! use refinement/coarsening? - int mRefinementDesired; - - //! output surface preview? if >0 yes, and use as reduzed size - int mOutputSurfacePreview; - LbmFloat mPreviewFactor; - - /*! enable surface and normals smoothing? */ - float mSmoothSurface; - float mSmoothNormals; - /*! isosurface subdivisions */ - int mIsoSubdivs; - - //! particle generation probability - LbmFloat mPartGenProb; - - //! dump velocities? - bool mDumpVelocities; - - // list for marked cells - vector<CellIdentifierInterface *> mMarkedCells; - int mMarkedCellIndex; - - //! domain boundary free/no slip type - string mDomainBound; - //! part slip value for domain - LbmFloat mDomainPartSlipValue; - - // size of far field area - LbmFloat mFarFieldSize; - // amount of drop mass to subtract - LbmFloat mPartDropMassSub; - // use physical drop model for particles? - bool mPartUsePhysModel; - - //! test vars - // strength of applied force - LbmFloat mTForceStrength; - int mCppfStage; - - //! dumping modes - bool mDumpRawText; - bool mDumpRawBinary; - bool mDumpRawBinaryZip; - -#if PARALLEL==1 - int mNumOMPThreads; -#endif // PARALLEL==1 - -private: -#ifdef WITH_CXX_GUARDEDALLOC - MEM_CXX_CLASS_ALLOC_FUNCS("ELBEEM:LbmSolverInterface") -#endif -}; - - -// helper function to create consistent grid resolutions -void initGridSizes(int &mSizex, int &mSizey, int &mSizez, - ntlVec3Gfx &mvGeoStart, ntlVec3Gfx &mvGeoEnd, - int mMaxRefine, bool parallel); -// return the amount of memory required in total (reqret) -// and for the finest grid only (reqretFine, can be NULL) -void calculateMemreqEstimate(int resx,int resy,int resz, int refine, - float farfieldsize, double *reqret, double *reqretFine, string *reqstr); - -//! helper function to convert flag to string (for debuggin) -string convertCellFlagType2String( CellFlagType flag ); -string convertSingleFlag2String(CellFlagType cflag); - -#endif // LBMINTERFACE_H diff --git a/intern/elbeem/intern/solver_main.cpp b/intern/elbeem/intern/solver_main.cpp deleted file mode 100644 index 961bd44e08f..00000000000 --- a/intern/elbeem/intern/solver_main.cpp +++ /dev/null @@ -1,1723 +0,0 @@ -/** \file - * \ingroup elbeem - */ -/****************************************************************************** - * - * El'Beem - Free Surface Fluid Simulation with the Lattice Boltzmann Method - * Copyright 2003-2006 Nils Thuerey - * - * Standard LBM Factory implementation - * - *****************************************************************************/ - -#include "solver_class.h" -#include "solver_relax.h" -#include "particletracer.h" -#include "loop_tools.h" -#include "globals.h" - -#include <stdlib.h> -#include <cmath> - -using std::isfinite; - -/*****************************************************************************/ -/*! perform a single LBM step */ -/*****************************************************************************/ - -double globdfcnt; -double globdfavg[19]; -double globdfmax[19]; -double globdfmin[19]; - -// simulation object interface -void LbmFsgrSolver::step() { - stepMain(); -} - -// lbm main step -void messageOutputForce(string from); -void LbmFsgrSolver::stepMain() { - myTime_t timestart = getTime(); - - initLevelOmegas(); - markedClearList(); // DMC clearMarkedCellsList - - // safety check, counter reset - mNumUsedCells = 0; - mNumInterdCells = 0; - mNumInvIfCells = 0; - - //debugOutNnl("LbmFsgrSolver::step : "<<mStepCnt, 10); - if(!mSilent){ debMsgStd("LbmFsgrSolver::step", DM_MSG, mName<<" cnt:"<<mStepCnt<<" t:"<<mSimulationTime, 10); } - //debMsgDirect( "LbmFsgrSolver::step : "<<mStepCnt<<" "); - //myTime_t timestart = 0; - //if(mStartSymm) { checkSymmetry("step1"); } // DEBUG - - // time adapt - mMaxVlen = mMxvz = mMxvy = mMxvx = 0.0; - - // init moving bc's, can change mMaxVlen - initMovingObstacles(false); - - // handle fluid control - handleCpdata(); - - // important - keep for tadap - LbmFloat lastMass = mCurrentMass; - mCurrentMass = mFixMass; // reset here for next step - mCurrentVolume = 0.0; - - //change to single step advance! - int levsteps = 0; - int dsbits = mStepCnt ^ (mStepCnt-1); - //errMsg("S"," step:"<<mStepCnt<<" s-1:"<<(mStepCnt-1)<<" xf:"<<convertCellFlagType2String(dsbits)); - for(int lev=0; lev<=mMaxRefine; lev++) { - //if(! (mStepCnt&(1<<lev)) ) { - if( dsbits & (1<<(mMaxRefine-lev)) ) { - //errMsg("S"," l"<<lev); - - if(lev==mMaxRefine) { - // always advance fine level... - fineAdvance(); - } else { - adaptGrid(lev); - coarseRestrictFromFine(lev); - coarseAdvance(lev); - } -#if FSGR_OMEGA_DEBUG==1 - errMsg("LbmFsgrSolver::step","LES stats l="<<lev<<" omega="<<mLevel[lev].omega<<" avgOmega="<< (mLevel[lev].avgOmega/mLevel[lev].avgOmegaCnt) ); - mLevel[lev].avgOmega = 0.0; mLevel[lev].avgOmegaCnt = 0.0; -#endif // FSGR_OMEGA_DEBUG==1 - levsteps++; - } - mCurrentMass += mLevel[lev].lmass; - mCurrentVolume += mLevel[lev].lvolume; - } - - // prepare next step - mStepCnt++; - - - // some dbugging output follows - // calculate MLSUPS - myTime_t timeend = getTime(); - - mNumUsedCells += mNumInterdCells; // count both types for MLSUPS - mAvgNumUsedCells += mNumUsedCells; - mMLSUPS = ((double)mNumUsedCells / ((timeend-timestart)/(double)1000.0) ) / (1000000.0); - if(mMLSUPS>10000){ mMLSUPS = -1; } - //else { mAvgMLSUPS += mMLSUPS; mAvgMLSUPSCnt += 1.0; } // track average mlsups - - LbmFloat totMLSUPS = ( ((mLevel[mMaxRefine].lSizex-2)*(mLevel[mMaxRefine].lSizey-2)*(getForZMax1(mMaxRefine)-getForZMin1())) / ((timeend-timestart)/(double)1000.0) ) / (1000000); - if(totMLSUPS>10000) totMLSUPS = -1; - mNumInvIfTotal += mNumInvIfCells; // debug - - // do some formatting - if(!mSilent){ - int avgcls = (int)(mAvgNumUsedCells/(LONGINT)mStepCnt); - debMsgStd("LbmFsgrSolver::step", DM_MSG, mName<<" cnt:"<<mStepCnt<<" t:"<<mSimulationTime<< - " cur-mlsups:"<<mMLSUPS<< //" avg:"<<(mAvgMLSUPS/mAvgMLSUPSCnt)<<"), "<< - " totcls:"<<mNumUsedCells<< " avgcls:"<< avgcls<< - " intd:"<<mNumInterdCells<< " invif:"<<mNumInvIfCells<< - " invift:"<<mNumInvIfTotal<< " fsgrcs:"<<mNumFsgrChanges<< - " filled:"<<mNumFilledCells<<", emptied:"<<mNumEmptiedCells<< - " mMxv:"<<PRINT_VEC(mMxvx,mMxvy,mMxvz)<<", tscnts:"<<mTimeSwitchCounts<< - //" RWmxv:"<<ntlVec3Gfx(mMxvx,mMxvy,mMxvz)*(mLevel[mMaxRefine].simCellSize / mLevel[mMaxRefine].timestep)<<" "<< /* realworld vel output */ - " probs:"<<mNumProblems<< " simt:"<<mSimulationTime<< - " took:"<< getTimeString(timeend-timestart)<< - " for '"<<mName<<"' " , 10); - } else { debMsgDirect("."); } - - if(mStepCnt==1) { - mMinNoCells = mMaxNoCells = mNumUsedCells; - } else { - if(mNumUsedCells>mMaxNoCells) mMaxNoCells = mNumUsedCells; - if(mNumUsedCells<mMinNoCells) mMinNoCells = mNumUsedCells; - } - - // mass scale test - if((mMaxRefine>0)&&(mInitialMass>0.0)) { - LbmFloat mscale = mInitialMass/mCurrentMass; - - mscale = 1.0; - const LbmFloat dchh = 0.001; - if(mCurrentMass<mInitialMass) mscale = 1.0+dchh; - if(mCurrentMass>mInitialMass) mscale = 1.0-dchh; - - // use mass rescaling? - // with float precision this seems to be nonsense... - const bool MREnable = false; - - const int MSInter = 2; - static int mscount = 0; - if( (MREnable) && ((mLevel[0].lsteps%MSInter)== (MSInter-1)) && ( ABS( (mInitialMass/mCurrentMass)-1.0 ) > 0.01) && ( dsbits & (1<<(mMaxRefine-0)) ) ){ - // example: FORCE RESCALE MASS! ini:1843.5, cur:1817.6, f=1.01425 step:22153 levstep:5539 msc:37 - // mass rescale MASS RESCALE check - errMsg("MDTDD","\n\n"); - errMsg("MDTDD","FORCE RESCALE MASS! " - <<"ini:"<<mInitialMass<<", cur:"<<mCurrentMass<<", f="<<ABS(mInitialMass/mCurrentMass) - <<" step:"<<mStepCnt<<" levstep:"<<mLevel[0].lsteps<<" msc:"<<mscount<<" " - ); - errMsg("MDTDD","\n\n"); - - mscount++; - for(int lev=mMaxRefine; lev>=0 ; lev--) { - //for(int workSet = 0; workSet<=1; workSet++) { - int wss = 0; - int wse = 1; -#if COMPRESSGRIDS==1 - if(lev== mMaxRefine) wss = wse = mLevel[lev].setCurr; -#endif // COMPRESSGRIDS==1 - for(int workSet = wss; workSet<=wse; workSet++) { // COMPRT - - FSGR_FORIJK1(lev) { - if( (RFLAG(lev,i,j,k, workSet) & (CFFluid| CFInter| CFGrFromCoarse| CFGrFromFine| CFGrNorm)) - ) { - - FORDF0 { QCELL(lev, i,j,k,workSet, l) *= mscale; } - QCELL(lev, i,j,k,workSet, dMass) *= mscale; - QCELL(lev, i,j,k,workSet, dFfrac) *= mscale; - - } else { - continue; - } - } - } - mLevel[lev].lmass *= mscale; - } - } - - mCurrentMass *= mscale; - }// if mass scale test */ - else { - // use current mass after full step for initial setting - if((mMaxRefine>0)&&(mInitialMass<=0.0) && (levsteps == (mMaxRefine+1))) { - mInitialMass = mCurrentMass; - debMsgStd("MDTDD",DM_NOTIFY,"Second Initial Mass Init: "<<mInitialMass, 2); - } - } - -#if LBM_INCLUDE_TESTSOLVERS==1 - if((mUseTestdata)&&(mInitDone)) { handleTestdata(); } - mrExchange(); -#endif - - // advance positions with current grid - advanceParticles(); - if(mpParticles) { - mpParticles->checkDumpTextPositions(mSimulationTime); - mpParticles->checkTrails(mSimulationTime); - } - - // one of the last things to do - adapt timestep - // was in fineAdvance before... - if(mTimeAdap) { - adaptTimestep(); - } // time adaptivity - - -#ifndef WIN32 - // good indicator for instabilities - if( (!isfinite(mMxvx)) || (!isfinite(mMxvy)) || (!isfinite(mMxvz)) ) { CAUSE_PANIC; } - if( (!isfinite(mCurrentMass)) || (!isfinite(mCurrentVolume)) ) { CAUSE_PANIC; } -#endif // WIN32 - - // output total step time - myTime_t timeend2 = getTime(); - double mdelta = (lastMass-mCurrentMass); - if(ABS(mdelta)<1e-12) mdelta=0.; - double effMLSUPS = ((double)mNumUsedCells / ((timeend2-timestart)/(double)1000.0) ) / (1000000.0); - if(mInitDone) { - if(effMLSUPS>10000){ effMLSUPS = -1; } - else { mAvgMLSUPS += effMLSUPS; mAvgMLSUPSCnt += 1.0; } // track average mlsups - } - - debMsgStd("LbmFsgrSolver::stepMain", DM_MSG, "mmpid:"<<glob_mpindex<<" step:"<<mStepCnt - <<" dccd="<< mCurrentMass - //<<",d"<<mdelta - //<<",ds"<<(mCurrentMass-mObjectMassMovnd[1]) - //<<"/"<<mCurrentVolume<<"(fix="<<mFixMass<<",ini="<<mInitialMass<<"), " - <<" effMLSUPS=("<< effMLSUPS - <<",avg:"<<(mAvgMLSUPS/mAvgMLSUPSCnt)<<"), " - <<" took totst:"<< getTimeString(timeend2-timestart), 3); - // nicer output - //debMsgDirect(std::endl); - // */ - - messageOutputForce(""); - //#endif // ELBEEM_PLUGIN!=1 -} - -#define NEWDEBCHECK(str) \ - if(!this->mPanic){ FSGR_FORIJK_BOUNDS(mMaxRefine) { \ - if(RFLAG(mMaxRefine,i,j,k,mLevel[mMaxRefine].setCurr)&(CFFluid|CFInter)) { \ - for(int l=0;l<dTotalNum;l++) { \ - if(!isfinite(QCELL(mMaxRefine,i,j,k,mLevel[mMaxRefine].setCurr,l))) { errMsg("NNOFIN"," "<<str<<" at "<<PRINT_IJK<<" l"<<l<<" "); }\ - }/*for*/ \ - }/*if*/ \ - } } - -void LbmFsgrSolver::fineAdvance() -{ - // do the real thing... - //NEWDEBCHECK("t1"); - mainLoop( mMaxRefine ); - if(mUpdateFVHeight) { - // warning assume -Y gravity... - mFVHeight = mCurrentMass*mFVArea/((LbmFloat)(mLevel[mMaxRefine].lSizex*mLevel[mMaxRefine].lSizez)); - if(mFVHeight<1.0) mFVHeight = 1.0; - mpParam->setFluidVolumeHeight(mFVHeight); - } - - // advance time before timestep change - mSimulationTime += mpParam->getTimestep(); - // time adaptivity - mpParam->setSimulationMaxSpeed( sqrt(mMaxVlen / 1.5) ); - //if(mStartSymm) { checkSymmetry("step2"); } // DEBUG - if(!mSilent){ debMsgStd("fineAdvance",DM_NOTIFY," stepped from "<<mLevel[mMaxRefine].setCurr<<" to "<<mLevel[mMaxRefine].setOther<<" step"<< (mLevel[mMaxRefine].lsteps), 3 ); } - - // update other set - mLevel[mMaxRefine].setOther = mLevel[mMaxRefine].setCurr; - mLevel[mMaxRefine].setCurr ^= 1; - mLevel[mMaxRefine].lsteps++; - - // flag init... (work on current set, to simplify flag checks) - reinitFlags( mLevel[mMaxRefine].setCurr ); - if(!mSilent){ debMsgStd("fineAdvance",DM_NOTIFY," flags reinit on set "<< mLevel[mMaxRefine].setCurr, 3 ); } - - // DEBUG VEL CHECK - if(0) { - int lev = mMaxRefine; - int workSet = mLevel[lev].setCurr; - int mi=0,mj=0,mk=0; - LbmFloat compRho=0.; - LbmFloat compUx=0.; - LbmFloat compUy=0.; - LbmFloat compUz=0.; - LbmFloat maxUlen=0.; - LbmVec maxU(0.); - LbmFloat maxRho=-100.; - int ri=0,rj=0,rk=0; - - FSGR_FORIJK1(lev) { - if( (RFLAG(lev,i,j,k, workSet) & (CFFluid| CFInter| CFGrFromCoarse| CFGrFromFine| CFGrNorm)) ) { - compRho=QCELL(lev, i,j,k,workSet, dC); - compUx = compUy = compUz = 0.0; - for(int l=1; l<this->cDfNum; l++) { - LbmFloat df = QCELL(lev, i,j,k,workSet, l); - compRho += df; - compUx += (this->dfDvecX[l]*df); - compUy += (this->dfDvecY[l]*df); - compUz += (this->dfDvecZ[l]*df); - } - LbmVec u(compUx,compUy,compUz); - LbmFloat nu = norm(u); - if(nu>maxUlen) { - maxU = u; - maxUlen = nu; - mi=i; mj=j; mk=k; - } - if(compRho>maxRho) { - maxRho=compRho; - ri=i; rj=j; rk=k; - } - } else { - continue; - } - } - - errMsg("MAXVELCHECK"," at "<<PRINT_VEC(mi,mj,mk)<<" norm:"<<maxUlen<<" u:"<<maxU); - errMsg("MAXRHOCHECK"," at "<<PRINT_VEC(ri,rj,rk)<<" rho:"<<maxRho); - printLbmCell(lev, 30,36,23, -1); - } // DEBUG VEL CHECK - -} - - - -// fine step defines - -// access to own dfs during step (may be changed to local array) -#define MYDF(l) RAC(ccel, l) - -// drop model definitions -#define RWVEL_THRESH 1.5 -#define RWVEL_WINDTHRESH (RWVEL_THRESH*0.5) - -#if LBMDIM==3 -// normal -#define SLOWDOWNREGION (mSizez/4) -#else // LBMDIM==2 -// off -#define SLOWDOWNREGION 10 -#endif // LBMDIM==2 -#define P_LCSMQO 0.01 - -/*****************************************************************************/ -//! fine step function -/*****************************************************************************/ -void -LbmFsgrSolver::mainLoop(const int lev) -{ - // loops over _only inner_ cells ----------------------------------------------------------------------------------- - - // slow surf regions smooth (if below) - const LbmFloat smoothStrength = 0.0; //0.01; - const LbmFloat sssUsqrLimit = 1.5 * 0.03*0.03; - const LbmFloat sssUsqrLimitInv = 1.0/sssUsqrLimit; - - const int cutMin = 1; - const int cutConst = mCutoff+2; - - -# if LBM_INCLUDE_TESTSOLVERS==1 - // 3d region off... quit - if((mUseTestdata)&&(mpTest->mFarfMode>0)) { return; } -# endif // ELBEEM_PLUGIN!=1 - - // main loop region - const bool doReduce = true; - const int gridLoopBound=1; - int calcNumInvIfCells = 0; - LbmFloat calcInitialMass = 0; - GRID_REGION_INIT(); -#if PARALLEL==1 - const int gDebugLevel = ::gDebugLevel; -#pragma omp parallel num_threads(mNumOMPThreads) \ - reduction(+: \ - calcCurrentMass,calcCurrentVolume, \ - calcCellsFilled,calcCellsEmptied, \ - calcNumUsedCells,calcNumInvIfCells,calcInitialMass) - GRID_REGION_START(); -#else // PARALLEL==1 - GRID_REGION_START(); -#endif // PARALLEL==1 - - // local to main - CellFlagType nbflag[LBM_DFNUM]; - int oldFlag, newFlag, nbored; - LbmFloat m[LBM_DFNUM]; - LbmFloat rho, ux, uy, uz, tmp, usqr; - - // smago vars - LbmFloat lcsmqadd, lcsmeq[LBM_DFNUM], lcsmomega; - - // ifempty cell conversion flags - bool iffilled, ifemptied; - LbmFloat nbfracs[LBM_DFNUM]; // ffracs of neighbors - int recons[LBM_DFNUM]; // reconstruct this DF? - int numRecons; // how many are reconstructed? - - LbmFloat mass=0., change=0., lcsmqo=0.; - rho= ux= uy= uz= usqr= tmp= 0.; - lcsmqadd = lcsmomega = 0.; - FORDF0{ lcsmeq[l] = 0.; } - - // --- - // now stream etc. - // use //template functions for 2D/3D - - GRID_LOOP_START(); - // loop start - // stream from current set to other, then collide and store - //errMsg("l2"," at "<<PRINT_IJK<<" id"<<id); - -# if FSGR_STRICT_DEBUG==1 - // safety pointer check - rho = ux = uy = uz = tmp = usqr = -100.0; // DEBUG - if( (&RFLAG(lev, i,j,k,mLevel[lev].setCurr) != pFlagSrc) || - (&RFLAG(lev, i,j,k,mLevel[lev].setOther) != pFlagDst) ) { - errMsg("LbmFsgrSolver::mainLoop","Err flagp "<<PRINT_IJK<<"="<< - RFLAG(lev, i,j,k,mLevel[lev].setCurr)<<","<<RFLAG(lev, i,j,k,mLevel[lev].setOther)<<" but is "<< - (*pFlagSrc)<<","<<(*pFlagDst) <<", pointers "<< - (long)(&RFLAG(lev, i,j,k,mLevel[lev].setCurr))<<","<<(long)(&RFLAG(lev, i,j,k,mLevel[lev].setOther))<<" but is "<< - (long)(pFlagSrc)<<","<<(long)(pFlagDst)<<" " - ); - CAUSE_PANIC; - } - if( (&QCELL(lev, i,j,k,mLevel[lev].setCurr,0) != ccel) || - (&QCELL(lev, i,j,k,mLevel[lev].setOther,0) != tcel) ) { - errMsg("LbmFsgrSolver::mainLoop","Err cellp "<<PRINT_IJK<<"="<< - (long)(&QCELL(lev, i,j,k,mLevel[lev].setCurr,0))<<","<<(long)(&QCELL(lev, i,j,k,mLevel[lev].setOther,0))<<" but is "<< - (long)(ccel)<<","<<(long)(tcel)<<" " - ); - CAUSE_PANIC; - } -# endif - oldFlag = *pFlagSrc; - - // old INTCFCOARSETEST==1 - if( (oldFlag & (CFGrFromCoarse)) ) { - if(( mStepCnt & (1<<(mMaxRefine-lev)) ) ==1) { - FORDF0 { RAC(tcel,l) = RAC(ccel,l); } - } else { - interpolateCellFromCoarse( lev, i,j,k, TSET(lev), 0.0, CFFluid|CFGrFromCoarse, false); - calcNumUsedCells++; - } - continue; // interpolateFineFromCoarse test! - } // interpolateFineFromCoarse test! - - if(oldFlag & (CFMbndInflow)) { - // fluid & if are ok, fill if later on - int isValid = oldFlag & (CFFluid|CFInter); - const LbmFloat iniRho = 1.0; - const int OId = oldFlag>>24; - if(!isValid) { - // make new if cell - const LbmVec vel(mObjectSpeeds[OId]); - // TODO add OPT3D treatment - FORDF0 { RAC(tcel, l) = this->getCollideEq(l, iniRho,vel[0],vel[1],vel[2]); } - RAC(tcel, dMass) = RAC(tcel, dFfrac) = iniRho; - RAC(tcel, dFlux) = FLUX_INIT; - changeFlag(lev, i,j,k, TSET(lev), CFInter); - calcCurrentMass += iniRho; - calcCurrentVolume += 1.0; - calcNumUsedCells++; - calcInitialMass += iniRho; - // dont treat cell until next step - continue; - } - } - else // these are exclusive - if(oldFlag & (CFMbndOutflow)) { - int isnotValid = oldFlag & (CFFluid); - if(isnotValid) { - // remove fluid cells, shouldnt be here anyway - LbmFloat fluidRho = m[0]; FORDF1 { fluidRho += m[l]; } - calcInitialMass -= fluidRho; - const LbmFloat iniRho = 0.0; - RAC(tcel, dMass) = RAC(tcel, dFfrac) = iniRho; - RAC(tcel, dFlux) = FLUX_INIT; - changeFlag(lev, i,j,k, TSET(lev), CFInter); - - // same as ifemptied for if below - LbmPoint oemptyp; oemptyp.flag = 0; - oemptyp.x = i; oemptyp.y = j; oemptyp.z = k; - LIST_EMPTY(oemptyp); - calcCellsEmptied++; - continue; - } - } - - if(oldFlag & (CFBnd|CFEmpty|CFGrFromCoarse|CFUnused)) { - *pFlagDst = oldFlag; - continue; - } - /*if( oldFlag & CFNoBndFluid ) { // TEST ME FASTER? - OPTIMIZED_STREAMCOLLIDE; PERFORM_USQRMAXCHECK; - RAC(tcel,dFfrac) = 1.0; - *pFlagDst = (CellFlagType)oldFlag; // newFlag; - calcCurrentMass += rho; calcCurrentVolume += 1.0; - calcNumUsedCells++; - continue; - }// TEST ME FASTER? */ - - // only neighbor flags! not own flag - nbored = 0; - -#if OPT3D==0 - FORDF1 { - nbflag[l] = RFLAG_NB(lev, i,j,k,SRCS(lev),l); - nbored |= nbflag[l]; - } -#else - nbflag[dSB] = *(pFlagSrc + (-mLevel[lev].lOffsy+-mLevel[lev].lOffsx)); nbored |= nbflag[dSB]; - nbflag[dWB] = *(pFlagSrc + (-mLevel[lev].lOffsy+-1)); nbored |= nbflag[dWB]; - nbflag[ dB] = *(pFlagSrc + (-mLevel[lev].lOffsy)); nbored |= nbflag[dB]; - nbflag[dEB] = *(pFlagSrc + (-mLevel[lev].lOffsy+ 1)); nbored |= nbflag[dEB]; - nbflag[dNB] = *(pFlagSrc + (-mLevel[lev].lOffsy+ mLevel[lev].lOffsx)); nbored |= nbflag[dNB]; - - nbflag[dSW] = *(pFlagSrc + (-mLevel[lev].lOffsx+-1)); nbored |= nbflag[dSW]; - nbflag[ dS] = *(pFlagSrc + (-mLevel[lev].lOffsx)); nbored |= nbflag[dS]; - nbflag[dSE] = *(pFlagSrc + (-mLevel[lev].lOffsx+ 1)); nbored |= nbflag[dSE]; - - nbflag[ dW] = *(pFlagSrc + (-1)); nbored |= nbflag[dW]; - nbflag[ dE] = *(pFlagSrc + ( 1)); nbored |= nbflag[dE]; - - nbflag[dNW] = *(pFlagSrc + ( mLevel[lev].lOffsx+-1)); nbored |= nbflag[dNW]; - nbflag[ dN] = *(pFlagSrc + ( mLevel[lev].lOffsx)); nbored |= nbflag[dN]; - nbflag[dNE] = *(pFlagSrc + ( mLevel[lev].lOffsx+ 1)); nbored |= nbflag[dNE]; - - nbflag[dST] = *(pFlagSrc + ( mLevel[lev].lOffsy+-mLevel[lev].lOffsx)); nbored |= nbflag[dST]; - nbflag[dWT] = *(pFlagSrc + ( mLevel[lev].lOffsy+-1)); nbored |= nbflag[dWT]; - nbflag[ dT] = *(pFlagSrc + ( mLevel[lev].lOffsy)); nbored |= nbflag[dT]; - nbflag[dET] = *(pFlagSrc + ( mLevel[lev].lOffsy+ 1)); nbored |= nbflag[dET]; - nbflag[dNT] = *(pFlagSrc + ( mLevel[lev].lOffsy+ mLevel[lev].lOffsx)); nbored |= nbflag[dNT]; - // */ -#endif - - // pointer to destination cell - calcNumUsedCells++; - - // FLUID cells - if( oldFlag & CFFluid ) { - // only standard fluid cells (with nothing except fluid as nbs - - if(oldFlag&CFMbndInflow) { - // force velocity for inflow, necessary to have constant direction of flow - // FIXME , test also set interface cells? - const int OId = oldFlag>>24; - //? DEFAULT_STREAM; - //const LbmFloat fluidRho = 1.0; - // for submerged inflows, streaming would have to be performed... - LbmFloat fluidRho = m[0]; FORDF1 { fluidRho += m[l]; } - const LbmVec vel(mObjectSpeeds[OId]); - ux=vel[0], uy=vel[1], uz=vel[2]; - usqr = 1.5 * (ux*ux + uy*uy + uz*uz); - FORDF0 { RAC(tcel, l) = this->getCollideEq(l, fluidRho,ux,uy,uz); } - rho = fluidRho; - //errMsg("INFLOW_DEBUG","std at "<<PRINT_IJK<<" v="<<vel<<" rho="<<rho); - } else { - if(nbored&CFBnd) { - DEFAULT_STREAM; - //ux = [0]; uy = mLevel[lev].gravity[1]; uz = mLevel[lev].gravity[2]; - DEFAULT_COLLIDEG(mLevel[lev].gravity); - oldFlag &= (~CFNoBndFluid); - } else { - // do standard stream/collide - OPTIMIZED_STREAMCOLLIDE; - oldFlag |= CFNoBndFluid; - } - } - - PERFORM_USQRMAXCHECK; - // "normal" fluid cells - RAC(tcel,dFfrac) = 1.0; - *pFlagDst = (CellFlagType)oldFlag; // newFlag; - calcCurrentMass += rho; - calcCurrentVolume += 1.0; - continue; - } - - newFlag = oldFlag; - // make sure here: always check which flags to really unset...! - newFlag = newFlag & (~( - CFNoNbFluid|CFNoNbEmpty| CFNoDelete - | CFNoInterpolSrc - | CFNoBndFluid - )); - if(!(nbored&CFBndNoslip)) { //NEWSURFT NEWSURFTNOS - newFlag |= CFNoBndFluid; - } - /*if(!(nbored&CFBnd)) { //NEWSURFT NEWSURFTNOS - // explicitly check for noslip neighbors - bool hasnoslipnb = false; - FORDF1 { if((nbflag[l]&CFBnd)&&(nbflag[l]&CFBndNoslip)) hasnoslipnb=true; } - if(!hasnoslipnb) newFlag |= CFNoBndFluid; - } // */ - - // store own dfs and mass - mass = RAC(ccel,dMass); - - // WARNING - only interface cells arrive here! - // read distribution funtions of adjacent cells = stream step - DEFAULT_STREAM; - - if((nbored & CFFluid)==0) { newFlag |= CFNoNbFluid; calcNumInvIfCells++; } - if((nbored & CFEmpty)==0) { newFlag |= CFNoNbEmpty; calcNumInvIfCells++; } - - // calculate mass exchange for interface cells - LbmFloat myfrac = RAC(ccel,dFfrac); - if(myfrac<0.) myfrac=0.; // NEWSURFT -# define nbdf(l) m[ this->dfInv[(l)] ] - - // update mass - // only do boundaries for fluid cells, and interface cells without - // any fluid neighbors (assume that interface cells _with_ fluid - // neighbors are affected enough by these) - // which Df's have to be reconstructed? - // for fluid cells - just the f_i difference from streaming to empty cells ---- - numRecons = 0; - bool onlyBndnb = ((!(oldFlag&CFNoBndFluid))&&(oldFlag&CFNoNbFluid)&&(nbored&CFBndNoslip)); - //onlyBndnb = false; // DEBUG test off - - FORDF1 { // dfl loop - recons[l] = 0; - nbfracs[l] = 0.0; - // finally, "normal" interface cells ---- - if( nbflag[l]&(CFFluid|CFBnd) ) { // NEWTEST! FIXME check!!!!!!!!!!!!!!!!!! - change = nbdf(l) - MYDF(l); - } - // interface cells - distuingish cells that shouldn't fill/empty - else if( nbflag[l] & CFInter ) { - - LbmFloat mynbfac,nbnbfac; - // NEW TEST t1 - // t2 -> off - if((oldFlag&CFNoBndFluid)&&(nbflag[l]&CFNoBndFluid)) { - mynbfac = QCELL_NB(lev, i,j,k,SRCS(lev),l, dFlux) / QCELL(lev, i,j,k,SRCS(lev), dFlux); - nbnbfac = 1.0/mynbfac; - onlyBndnb = false; - } else { - mynbfac = nbnbfac = 1.0; // switch calc flux off - goto changeDefault; // NEWSURFT - //change = 0.; goto changeDone; // NEWSURFT - } - //mynbfac = nbnbfac = 1.0; // switch calc flux off t3 - - // perform interface case handling - if ((oldFlag|nbflag[l])&(CFNoNbFluid|CFNoNbEmpty)) { - switch (oldFlag&(CFNoNbFluid|CFNoNbEmpty)) { - case 0: - // we are a normal cell so... - switch (nbflag[l]&(CFNoNbFluid|CFNoNbEmpty)) { - case CFNoNbFluid: - // just fill current cell = empty neighbor - change = nbnbfac*nbdf(l) ; goto changeDone; - case CFNoNbEmpty: - // just empty current cell = fill neighbor - change = - mynbfac*MYDF(l) ; goto changeDone; - } - break; - - case CFNoNbFluid: - // we dont have fluid nb's so... - switch (nbflag[l]&(CFNoNbFluid|CFNoNbEmpty)) { - case 0: - case CFNoNbEmpty: - // we have no fluid nb's -> just empty - change = - mynbfac*MYDF(l) ; goto changeDone; - } - break; - - case CFNoNbEmpty: - // we dont have empty nb's so... - switch (nbflag[l]&(CFNoNbFluid|CFNoNbEmpty)) { - case 0: - case CFNoNbFluid: - // we have no empty nb's -> just fill - change = nbnbfac*nbdf(l); goto changeDone; - } - break; - }} // inter-inter exchange - - changeDefault: ; - // just do normal mass exchange... - change = ( nbnbfac*nbdf(l) - mynbfac*MYDF(l) ) ; - changeDone: ; - nbfracs[l] = QCELL_NB(lev, i,j,k, SRCS(lev),l, dFfrac); - if(nbfracs[l]<0.) nbfracs[l] = 0.; // NEWSURFT - change *= (myfrac + nbfracs[l]) * 0.5; - } // the other cell is interface - - // last alternative - reconstruction in this direction - else { - // empty + bnd case - recons[l] = 1; - numRecons++; - change = 0.0; - } - - // modify mass at SRCS - mass += change; - } // l - // normal interface, no if empty/fluid - - // computenormal - LbmFloat surfaceNormal[3]; - computeFluidSurfaceNormal(ccel,pFlagSrc, surfaceNormal); - - if( (ABS(surfaceNormal[0])+ABS(surfaceNormal[1])+ABS(surfaceNormal[2])) > LBM_EPSILON) { - // normal ok and usable... - FORDF1 { - if( (this->dfDvecX[l]*surfaceNormal[0] + this->dfDvecY[l]*surfaceNormal[1] + this->dfDvecZ[l]*surfaceNormal[2]) // dot Dvec,norml - > LBM_EPSILON) { - recons[l] = 2; - numRecons++; - } - } - } - - // calculate macroscopic cell values - LbmFloat oldUx, oldUy, oldUz; - LbmFloat oldRho; // OLD rho = ccel->rho; -# define REFERENCE_PRESSURE 1.0 // always atmosphere... -# if OPT3D==0 - oldRho=RAC(ccel,0); - oldUx = oldUy = oldUz = 0.0; - for(int l=1; l<this->cDfNum; l++) { - oldRho += RAC(ccel,l); - oldUx += (this->dfDvecX[l]*RAC(ccel,l)); - oldUy += (this->dfDvecY[l]*RAC(ccel,l)); - oldUz += (this->dfDvecZ[l]*RAC(ccel,l)); - } - // reconstruct dist funcs from empty cells - FORDF1 { - if(recons[ l ]) { - m[ this->dfInv[l] ] = - this->getCollideEq(l, REFERENCE_PRESSURE, oldUx,oldUy,oldUz) + - this->getCollideEq(this->dfInv[l], REFERENCE_PRESSURE, oldUx,oldUy,oldUz) - - MYDF( l ); - } - } - ux=oldUx, uy=oldUy, uz=oldUz; // no local vars, only for usqr - usqr = 1.5 * (ux*ux + uy*uy + uz*uz); // needed later on -# else // OPT3D==0 - oldRho = + RAC(ccel,dC) + RAC(ccel,dN ) - + RAC(ccel,dS ) + RAC(ccel,dE ) - + RAC(ccel,dW ) + RAC(ccel,dT ) - + RAC(ccel,dB ) + RAC(ccel,dNE) - + RAC(ccel,dNW) + RAC(ccel,dSE) - + RAC(ccel,dSW) + RAC(ccel,dNT) - + RAC(ccel,dNB) + RAC(ccel,dST) - + RAC(ccel,dSB) + RAC(ccel,dET) - + RAC(ccel,dEB) + RAC(ccel,dWT) - + RAC(ccel,dWB); - - oldUx = + RAC(ccel,dE) - RAC(ccel,dW) - + RAC(ccel,dNE) - RAC(ccel,dNW) - + RAC(ccel,dSE) - RAC(ccel,dSW) - + RAC(ccel,dET) + RAC(ccel,dEB) - - RAC(ccel,dWT) - RAC(ccel,dWB); - - oldUy = + RAC(ccel,dN) - RAC(ccel,dS) - + RAC(ccel,dNE) + RAC(ccel,dNW) - - RAC(ccel,dSE) - RAC(ccel,dSW) - + RAC(ccel,dNT) + RAC(ccel,dNB) - - RAC(ccel,dST) - RAC(ccel,dSB); - - oldUz = + RAC(ccel,dT) - RAC(ccel,dB) - + RAC(ccel,dNT) - RAC(ccel,dNB) - + RAC(ccel,dST) - RAC(ccel,dSB) - + RAC(ccel,dET) - RAC(ccel,dEB) - + RAC(ccel,dWT) - RAC(ccel,dWB); - - (void)oldRho; - - // now reconstruction - ux=oldUx, uy=oldUy, uz=oldUz; // no local vars, only for usqr - rho = REFERENCE_PRESSURE; - usqr = 1.5 * (ux*ux + uy*uy + uz*uz); // needed later on - if(recons[dN ]) { m[dS ] = EQN + EQS - MYDF(dN ); } - if(recons[dS ]) { m[dN ] = EQS + EQN - MYDF(dS ); } - if(recons[dE ]) { m[dW ] = EQE + EQW - MYDF(dE ); } - if(recons[dW ]) { m[dE ] = EQW + EQE - MYDF(dW ); } - if(recons[dT ]) { m[dB ] = EQT + EQB - MYDF(dT ); } - if(recons[dB ]) { m[dT ] = EQB + EQT - MYDF(dB ); } - if(recons[dNE]) { m[dSW] = EQNE + EQSW - MYDF(dNE); } - if(recons[dNW]) { m[dSE] = EQNW + EQSE - MYDF(dNW); } - if(recons[dSE]) { m[dNW] = EQSE + EQNW - MYDF(dSE); } - if(recons[dSW]) { m[dNE] = EQSW + EQNE - MYDF(dSW); } - if(recons[dNT]) { m[dSB] = EQNT + EQSB - MYDF(dNT); } - if(recons[dNB]) { m[dST] = EQNB + EQST - MYDF(dNB); } - if(recons[dST]) { m[dNB] = EQST + EQNB - MYDF(dST); } - if(recons[dSB]) { m[dNT] = EQSB + EQNT - MYDF(dSB); } - if(recons[dET]) { m[dWB] = EQET + EQWB - MYDF(dET); } - if(recons[dEB]) { m[dWT] = EQEB + EQWT - MYDF(dEB); } - if(recons[dWT]) { m[dEB] = EQWT + EQEB - MYDF(dWT); } - if(recons[dWB]) { m[dET] = EQWB + EQET - MYDF(dWB); } -# endif - - - // inflow bc handling - if(oldFlag & (CFMbndInflow)) { - // fill if cells in inflow region - if(myfrac<0.5) { - mass += 0.25; - calcInitialMass += 0.25; - } - const int OId = oldFlag>>24; - const LbmVec vel(mObjectSpeeds[OId]); - ux=vel[0], uy=vel[1], uz=vel[2]; - //? usqr = 1.5 * (ux*ux + uy*uy + uz*uz); - //FORDF0 { RAC(tcel, l) = this->getCollideEq(l, fluidRho,ux,uy,uz); } rho = fluidRho; - rho = REFERENCE_PRESSURE; - FORDF0 { RAC(tcel, l) = this->getCollideEq(l, rho,ux,uy,uz); } - //errMsg("INFLOW_DEBUG","if at "<<PRINT_IJK<<" v="<<vel<<" rho="<<rho); - } else { - // NEWSURFT, todo optimize! - if(onlyBndnb) { //if(usqr<0.001*0.001) { - rho = ux = uy = uz = 0.; - FORDF0{ - rho += m[l]; - ux += (this->dfDvecX[l]*m[l]); - uy += (this->dfDvecY[l]*m[l]); - uz += (this->dfDvecZ[l]*m[l]); - } - FORDF0 { RAC(tcel, l) = this->getCollideEq(l, rho,ux,uy,uz); } - } else {// NEWSURFT */ - if(usqr>0.3*0.3) { - // force reset! , warning causes distortions... - FORDF0 { RAC(tcel, l) = this->getCollideEq(l, rho,0.,0.,0.); } - } else { - // normal collide - // mass streaming done... do normal collide - LbmVec grav = mLevel[lev].gravity*mass; - DEFAULT_COLLIDEG(grav); - PERFORM_USQRMAXCHECK; } - // rho init from default collide necessary for fill/empty check below - } // test - } - - // testing..., particle generation - // also check oldFlag for CFNoNbFluid, test - // for inflow no pargen test // NOBUBBB! - if((mInitDone) - // dont allow new if cells, or submerged ones - && (!((oldFlag|newFlag)& (CFNoDelete|CFNoNbEmpty) )) - // dont try to subtract from empty cells - && (mass>0.) && (mPartGenProb>0.0)) { - bool doAdd = true; - bool bndOk=true; - if( (i<cutMin)||(i>mSizex-cutMin)|| - (j<cutMin)||(j>mSizey-cutMin)|| - (k<cutMin)||(k>mSizez-cutMin) ) { bndOk=false; } - if(!bndOk) doAdd=false; - - LbmFloat prob = (rand()/(RAND_MAX+1.0)); - LbmFloat basethresh = mPartGenProb*lcsmqo*(LbmFloat)(mSizez+mSizey+mSizex)*0.5*0.333; - - // physical drop model - if(mPartUsePhysModel) { - LbmFloat realWorldFac = (mLevel[lev].simCellSize / mLevel[lev].timestep); - LbmVec ru(ux * realWorldFac, uy * realWorldFac, uz * realWorldFac); - LbmFloat rl = norm(ru); - basethresh *= rl; - - // reduce probability in outer region? - const int pibord = mLevel[mMaxRefine].lSizex/2-cutConst; - const int pjbord = mLevel[mMaxRefine].lSizey/2-cutConst; - LbmFloat pifac = 1.-(LbmFloat)(ABS(i-pibord)) / (LbmFloat)(pibord); - LbmFloat pjfac = 1.-(LbmFloat)(ABS(j-pjbord)) / (LbmFloat)(pjbord); - if(pifac<0.) pifac=0.; - if(pjfac<0.) pjfac=0.; - - //if( (prob< (basethresh*rl)) && (lcsmqo>0.0095) && (rl>RWVEL_THRESH) ) { - if( (prob< (basethresh*rl*pifac*pjfac)) && (lcsmqo>0.0095) && (rl>RWVEL_THRESH) ) { - // add - } else { - doAdd = false; // dont... - } - - // "wind" disturbance - // use realworld relative velocity here instead? - if( (doAdd && - ((rl>RWVEL_WINDTHRESH) && (lcsmqo<P_LCSMQO)) )// normal checks - ||(k>mSizez-SLOWDOWNREGION) ) { - LbmFloat nuz = uz; - if(k>mSizez-SLOWDOWNREGION) { - // special case - LbmFloat zfac = (LbmFloat)( k-(mSizez-SLOWDOWNREGION) ); - zfac /= (LbmFloat)(SLOWDOWNREGION); - nuz += (1.0) * zfac; // check max speed? OFF? - //errMsg("TOPT"," at "<<PRINT_IJK<<" zfac"<<zfac); - } else { - // normal probability - //? LbmFloat fac = P_LCSMQO-lcsmqo; - //? jdf *= fac; - } - FORDF1 { - const LbmFloat jdf = 0.05 * (rand()/(RAND_MAX+1.0)); - // TODO use wind velocity? - if(jdf>0.025) { - const LbmFloat add = this->dfLength[l]*(-ux*this->dfDvecX[l]-uy*this->dfDvecY[l]-nuz*this->dfDvecZ[l])*jdf; - RAC(tcel,l) += add; } - } - //errMsg("TOPDOWNCORR"," jdf:"<<jdf<<" rl"<<rl<<" vel "<<norm(LbmVec(ux,uy,nuz))<<" rwv"<<norm(LbmVec(rux,ruy,ruz)) ); - } // wind disturbance - } // mPartUsePhysModel - else { - // empirical model - //if((prob<basethresh) && (lcsmqo>0.0095)) { // add - if((prob<basethresh) && (lcsmqo>0.012)) { // add - } else { doAdd = false; }// dont... - } - - - // remove noise - if(usqr<0.0001) doAdd=false; // TODO check!? - - // dont try to subtract from empty cells - // ensure cell has enough mass for new drop - LbmFloat newPartsize = 1.0; - if(mPartUsePhysModel) { - // 1-10 - newPartsize += 9.0* (rand()/(RAND_MAX+1.0)); - } else { - // 1-5, overall size has to be less than - // .62 (ca. 0.5) to make drops significantly smaller - // than a full cell! - newPartsize += 4.0* (rand()/(RAND_MAX+1.0)); - } - LbmFloat dropmass = ParticleObject::getMass(mPartDropMassSub*newPartsize); //PARTMASS(mPartDropMassSub*newPartsize); // mass: 4/3 pi r^3 rho - while(dropmass>mass) { - newPartsize -= 0.2; - dropmass = ParticleObject::getMass(mPartDropMassSub*newPartsize); - } - if(newPartsize<=1.) doAdd=false; - - if( (doAdd) ) { // init new particle - for(int s=0; s<1; s++) { // one part! - const LbmFloat posjitter = 0.05; - const LbmFloat posjitteroffs = posjitter*-0.5; - LbmFloat jpx = posjitteroffs+ posjitter* (rand()/(RAND_MAX+1.0)); - LbmFloat jpy = posjitteroffs+ posjitter* (rand()/(RAND_MAX+1.0)); - LbmFloat jpz = posjitteroffs+ posjitter* (rand()/(RAND_MAX+1.0)); - - const LbmFloat jitterstr = 1.0; - const LbmFloat jitteroffs = jitterstr*-0.5; - LbmFloat jx = jitteroffs+ jitterstr* (rand()/(RAND_MAX+1.0)); - LbmFloat jy = jitteroffs+ jitterstr* (rand()/(RAND_MAX+1.0)); - LbmFloat jz = jitteroffs+ jitterstr* (rand()/(RAND_MAX+1.0)); - - // average normal & velocity - // -> mostly along velocity dir, many into surface - // fluid velocity (not normalized!) - LbmVec flvelVel(ux,uy,uz); - LbmFloat flvelLen = norm(flvelVel); - // surface normal - LbmVec normVel(surfaceNormal[0],surfaceNormal[1],surfaceNormal[2]); - normalize(normVel); - LbmFloat normScale = (0.01+flvelLen); - // jitter vector, 0.2 * flvel - LbmVec jittVel(jx,jy,jz); - jittVel *= (0.05+flvelLen)*0.1; - // weighten velocities - const LbmFloat flvelWeight = 0.9; - LbmVec newpartVel = normVel*normScale*(1.-flvelWeight) + flvelVel*(flvelWeight) + jittVel; - - // offset towards surface (hide popping) - jpx += -normVel[0]*0.4; - jpy += -normVel[1]*0.4; - jpz += -normVel[2]*0.4; - - LbmFloat srci=i+0.5+jpx, srcj=j+0.5+jpy, srck=k+0.5+jpz; - int type=0; - type = PART_DROP; - -# if LBMDIM==2 - newpartVel[2]=0.; srck=0.5; -# endif // LBMDIM==2 - // subtract drop mass - mass -= dropmass; - // init new particle - { - ParticleObject np( ntlVec3Gfx(srci,srcj,srck) ); - np.setVel(newpartVel[0],newpartVel[1],newpartVel[2]); - np.setStatus(PART_IN); - np.setType(type); - //if((s%3)==2) np.setType(PART_FLOAT); - np.setSize(newPartsize); - //errMsg("NEWPART"," at "<<PRINT_IJK<<" u="<<norm(LbmVec(ux,uy,uz)) <<" add"<<doAdd<<" pvel="<<norm(newpartVel)<<" size="<<newPartsize ); - //errMsg("NEWPT","u="<<newpartVel<<" norm="<<normVel<<" flvel="<<flvelVel<<" jitt="<<jittVel ); - FSGR_ADDPART(np); - } // new part - //errMsg("PIT","NEW pit"<<np.getId()<<" pos:"<< np.getPos()<<" status:"<<convertFlags2String(np.getFlags())<<" vel:"<< np.getVel() ); - } // multiple parts - } // doAdd - } // */ - - - // interface cell filled or emptied? - iffilled = ifemptied = 0; - // interface cells empty/full?, WARNING: to mark these cells, better do it at the end of reinitCellFlags - // interface cell if full? - if( (mass) >= (rho * (1.0+FSGR_MAGICNR)) ) { iffilled = 1; } - // interface cell if empty? - if( (mass) <= (rho * ( -FSGR_MAGICNR)) ) { ifemptied = 1; } - - if(oldFlag & (CFMbndOutflow)) { - calcInitialMass -= mass; - mass = myfrac = 0.0; - iffilled = 0; ifemptied = 1; - } - - // looks much nicer... LISTTRICK -# if FSGR_LISTTRICK==1 - //if((oldFlag&CFNoNbEmpty)&&(newFlag&CFNoNbEmpty)) { TEST_IF_CHECK; } - if(newFlag&CFNoBndFluid) { // test NEW TEST - if(!iffilled) { - // remove cells independent from amount of change... - if( (oldFlag & CFNoNbEmpty)&&(newFlag & CFNoNbEmpty)&& - ( (mass>(rho*FSGR_LISTTTHRESHFULL)) || ((nbored&CFInter)==0) )) { - //if((nbored&CFInter)==0){ errMsg("NBORED!CFINTER","filled "<<PRINT_IJK); }; - iffilled = 1; - } - } - if(!ifemptied) { - if( (oldFlag & CFNoNbFluid)&&(newFlag & CFNoNbFluid)&& - ( (mass<(rho*FSGR_LISTTTHRESHEMPTY)) || ((nbored&CFInter)==0) )) { - //if((nbored&CFInter)==0){ errMsg("NBORED!CFINTER","emptied "<<PRINT_IJK); }; - ifemptied = 1; - } - } - } // nobndfluid only */ -# endif - //iffilled = ifemptied = 0; // DEBUG!!!!!!!!!!!!!!! - - - // now that all dfs are known, handle last changes - if(iffilled) { - LbmPoint filledp; filledp.flag=0; - if(!(newFlag&CFNoBndFluid)) filledp.flag |= 1; // NEWSURFT - filledp.x = i; filledp.y = j; filledp.z = k; - LIST_FULL(filledp); - //mNumFilledCells++; // DEBUG - calcCellsFilled++; - } - else if(ifemptied) { - LbmPoint emptyp; emptyp.flag=0; - if(!(newFlag&CFNoBndFluid)) emptyp.flag |= 1; // NEWSURFT - emptyp.x = i; emptyp.y = j; emptyp.z = k; - LIST_EMPTY(emptyp); - //mNumEmptiedCells++; // DEBUG - calcCellsEmptied++; - } - // dont cutoff values -> better cell conversions - RAC(tcel,dFfrac) = (mass/rho); - - // init new flux value - float flux = FLUX_INIT; // dxqn on - if(newFlag&CFNoBndFluid) { - //flux = 50.0; // extreme on - for(int nn=1; nn<this->cDfNum; nn++) { - if(nbflag[nn] & (CFFluid|CFInter|CFBnd)) { flux += this->dfLength[nn]; } - } - // optical hack - smooth slow moving - // surface regions - if(usqr< sssUsqrLimit) { - for(int nn=1; nn<this->cDfNum; nn++) { - if(nbfracs[nn]!=0.0) { - LbmFloat curSmooth = (sssUsqrLimit-usqr)*sssUsqrLimitInv; - if(curSmooth>1.0) curSmooth=1.0; - flux *= (1.0+ smoothStrength*curSmooth * (nbfracs[nn]-myfrac)) ; - } - } } - // NEW TEST */ - } - // flux = FLUX_INIT; // calc flux off - QCELL(lev, i,j,k,TSET(lev), dFlux) = flux; // */ - - // perform mass exchange with streamed values - QCELL(lev, i,j,k,TSET(lev), dMass) = mass; // MASST - // set new flag - *pFlagDst = (CellFlagType)newFlag; - calcCurrentMass += mass; - calcCurrentVolume += RAC(tcel,dFfrac); - - // interface cell handling done... - -#if PARALLEL!=1 - GRID_LOOPREG_END(); -#else // PARALLEL==1 -#include "paraloopend.h" // = GRID_LOOPREG_END(); -#endif // PARALLEL==1 - - // write vars from computations to class - mLevel[lev].lmass = calcCurrentMass; - mLevel[lev].lvolume = calcCurrentVolume; - mNumFilledCells = calcCellsFilled; - mNumEmptiedCells = calcCellsEmptied; - mNumUsedCells = calcNumUsedCells; - mNumInvIfCells += calcNumInvIfCells; - mInitialMass += calcInitialMass; -} - - - -void -LbmFsgrSolver::preinitGrids() -{ - const int lev = mMaxRefine; - const bool doReduce = false; - const int gridLoopBound=0; - - // preinit both grids - for(int s=0; s<2; s++) { - - GRID_REGION_INIT(); -#if PARALLEL==1 - const int gDebugLevel = ::gDebugLevel; -#pragma omp parallel num_threads(mNumOMPThreads) \ - reduction(+: \ - calcCurrentMass,calcCurrentVolume, \ - calcCellsFilled,calcCellsEmptied, \ - calcNumUsedCells ) -#endif // PARALLEL==1 - GRID_REGION_START(); - GRID_LOOP_START(); - for(int l=0; l<dTotalNum; l++) { RAC(ccel,l) = 0.; } - *pFlagSrc =0; - *pFlagDst =0; - //errMsg("l1"," at "<<PRINT_IJK<<" id"<<id); -#if PARALLEL!=1 - GRID_LOOPREG_END(); -#else // PARALLEL==1 -#include "paraloopend.h" // = GRID_LOOPREG_END(); -#endif // PARALLEL==1 - - /* dummy, remove warnings */ - calcCurrentMass = calcCurrentVolume = 0.; - calcCellsFilled = calcCellsEmptied = calcNumUsedCells = 0; - - // change grid - mLevel[mMaxRefine].setOther = mLevel[mMaxRefine].setCurr; - mLevel[mMaxRefine].setCurr ^= 1; - } -} - -void -LbmFsgrSolver::standingFluidPreinit() -{ - const int lev = mMaxRefine; - const bool doReduce = false; - const int gridLoopBound=1; - - GRID_REGION_INIT(); -#if PARALLEL==1 - const int gDebugLevel = ::gDebugLevel; -#pragma omp parallel num_threads(mNumOMPThreads) \ - reduction(+: \ - calcCurrentMass,calcCurrentVolume, \ - calcCellsFilled,calcCellsEmptied, \ - calcNumUsedCells ) -#endif // PARALLEL==1 - GRID_REGION_START(); - - LbmFloat rho, ux,uy,uz, usqr; - CellFlagType nbflag[LBM_DFNUM]; - LbmFloat m[LBM_DFNUM]; - LbmFloat lcsmqo; -# if OPT3D==1 - LbmFloat lcsmqadd, lcsmeq[LBM_DFNUM], lcsmomega; -# endif // OPT3D==true - - GRID_LOOP_START(); - //errMsg("l1"," at "<<PRINT_IJK<<" id"<<id); - const CellFlagType currFlag = *pFlagSrc; //RFLAG(lev, i,j,k,workSet); - if( (currFlag & (CFEmpty|CFBnd)) ) continue; - - if( (currFlag & (CFInter)) ) { - // copy all values - for(int l=0; l<dTotalNum;l++) { RAC(tcel,l) = RAC(ccel,l); } - continue; - } - - if( (currFlag & CFNoBndFluid)) { - OPTIMIZED_STREAMCOLLIDE; - } else { - FORDF1 { - nbflag[l] = RFLAG_NB(lev, i,j,k, SRCS(lev),l); - } - DEFAULT_STREAM; - DEFAULT_COLLIDEG(mLevel[lev].gravity); - } - for(int l=LBM_DFNUM; l<dTotalNum;l++) { RAC(tcel,l) = RAC(ccel,l); } -#if PARALLEL!=1 - GRID_LOOPREG_END(); -#else // PARALLEL==1 -#include "paraloopend.h" // = GRID_LOOPREG_END(); -#endif // PARALLEL==1 - - /* dummy remove warnings */ - calcCurrentMass = calcCurrentVolume = 0.; - calcCellsFilled = calcCellsEmptied = calcNumUsedCells = 0; - - // change grid - mLevel[mMaxRefine].setOther = mLevel[mMaxRefine].setCurr; - mLevel[mMaxRefine].setCurr ^= 1; -} - - -/****************************************************************************** - * work on lists from updateCellMass to reinit cell flags - *****************************************************************************/ - -LbmFloat LbmFsgrSolver::getMassdWeight(bool dirForw, int i,int j,int k,int workSet, int l) { - //return 0.0; // test - int level = mMaxRefine; - LbmFloat *ccel = RACPNT(level, i,j,k, workSet); - - // computenormal - CellFlagType *cflag = &RFLAG(level, i,j,k, workSet); - LbmFloat n[3]; - computeFluidSurfaceNormal(ccel,cflag, n); - LbmFloat scal = mDvecNrm[l][0]*n[0] + mDvecNrm[l][1]*n[1] + mDvecNrm[l][2]*n[2]; - - LbmFloat ret = 1.0; - // forward direction, add mass (for filling cells): - if(dirForw) { - if(scal<LBM_EPSILON) ret = 0.0; - else ret = scal; - } else { - // backward for emptying - if(scal>-LBM_EPSILON) ret = 0.0; - else ret = scal * -1.0; - } - //errMsg("massd", PRINT_IJK<<" nv"<<nvel<<" : ret="<<ret ); //xit(1); //VECDEB - return ret; -} - -// warning - normal compuations are without -// boundary checks & -// normalization -void LbmFsgrSolver::computeFluidSurfaceNormal(LbmFloat *ccel, CellFlagType *cflagpnt,LbmFloat *snret) { - const int level = mMaxRefine; - LbmFloat nx,ny,nz, nv1,nv2; - const CellFlagType flagE = *(cflagpnt+1); - const CellFlagType flagW = *(cflagpnt-1); - if(flagE &(CFFluid|CFInter)){ nv1 = RAC((ccel+QCELLSTEP ),dFfrac); } - else if(flagE &(CFBnd)){ nv1 = 1.; } - else nv1 = 0.0; - if(flagW &(CFFluid|CFInter)){ nv2 = RAC((ccel-QCELLSTEP ),dFfrac); } - else if(flagW &(CFBnd)){ nv2 = 1.; } - else nv2 = 0.0; - nx = 0.5* (nv2-nv1); - - const CellFlagType flagN = *(cflagpnt+mLevel[level].lOffsx); - const CellFlagType flagS = *(cflagpnt-mLevel[level].lOffsx); - if(flagN &(CFFluid|CFInter)){ nv1 = RAC((ccel+(mLevel[level].lOffsx*QCELLSTEP)),dFfrac); } - else if(flagN &(CFBnd)){ nv1 = 1.; } - else nv1 = 0.0; - if(flagS &(CFFluid|CFInter)){ nv2 = RAC((ccel-(mLevel[level].lOffsx*QCELLSTEP)),dFfrac); } - else if(flagS &(CFBnd)){ nv2 = 1.; } - else nv2 = 0.0; - ny = 0.5* (nv2-nv1); - -#if LBMDIM==3 - const CellFlagType flagT = *(cflagpnt+mLevel[level].lOffsy); - const CellFlagType flagB = *(cflagpnt-mLevel[level].lOffsy); - if(flagT &(CFFluid|CFInter)){ nv1 = RAC((ccel+(mLevel[level].lOffsy*QCELLSTEP)),dFfrac); } - else if(flagT &(CFBnd)){ nv1 = 1.; } - else nv1 = 0.0; - if(flagB &(CFFluid|CFInter)){ nv2 = RAC((ccel-(mLevel[level].lOffsy*QCELLSTEP)),dFfrac); } - else if(flagB &(CFBnd)){ nv2 = 1.; } - else nv2 = 0.0; - nz = 0.5* (nv2-nv1); -#else //LBMDIM==3 - nz = 0.0; -#endif //LBMDIM==3 - - // return vals - snret[0]=nx; snret[1]=ny; snret[2]=nz; -} -void LbmFsgrSolver::computeFluidSurfaceNormalAcc(LbmFloat *ccel, CellFlagType *cflagpnt, LbmFloat *snret) { - LbmFloat nx=0.,ny=0.,nz=0.; - ccel = NULL; cflagpnt=NULL; // remove warning - snret[0]=nx; snret[1]=ny; snret[2]=nz; -} -void LbmFsgrSolver::computeObstacleSurfaceNormal(LbmFloat *ccel, CellFlagType *cflagpnt, LbmFloat *snret) { - const int level = mMaxRefine; - LbmFloat nx,ny,nz, nv1,nv2; - ccel = NULL; // remove warning - - const CellFlagType flagE = *(cflagpnt+1); - const CellFlagType flagW = *(cflagpnt-1); - if(flagE &(CFBnd)){ nv1 = 1.; } - else nv1 = 0.0; - if(flagW &(CFBnd)){ nv2 = 1.; } - else nv2 = 0.0; - nx = 0.5* (nv2-nv1); - - const CellFlagType flagN = *(cflagpnt+mLevel[level].lOffsx); - const CellFlagType flagS = *(cflagpnt-mLevel[level].lOffsx); - if(flagN &(CFBnd)){ nv1 = 1.; } - else nv1 = 0.0; - if(flagS &(CFBnd)){ nv2 = 1.; } - else nv2 = 0.0; - ny = 0.5* (nv2-nv1); - -#if LBMDIM==3 - const CellFlagType flagT = *(cflagpnt+mLevel[level].lOffsy); - const CellFlagType flagB = *(cflagpnt-mLevel[level].lOffsy); - if(flagT &(CFBnd)){ nv1 = 1.; } - else nv1 = 0.0; - if(flagB &(CFBnd)){ nv2 = 1.; } - else nv2 = 0.0; - nz = 0.5* (nv2-nv1); -#else //LBMDIM==3 - nz = 0.0; -#endif //LBMDIM==3 - - // return vals - snret[0]=nx; snret[1]=ny; snret[2]=nz; -} -void LbmFsgrSolver::computeObstacleSurfaceNormalAcc(int i,int j,int k, LbmFloat *snret) { - bool nonorm = false; - LbmFloat nx=0.,ny=0.,nz=0.; - if(i<=0) { nx = 1.; nonorm = true; } - if(i>=mSizex-1) { nx = -1.; nonorm = true; } - if(j<=0) { ny = 1.; nonorm = true; } - if(j>=mSizey-1) { ny = -1.; nonorm = true; } -# if LBMDIM==3 - if(k<=0) { nz = 1.; nonorm = true; } - if(k>=mSizez-1) { nz = -1.; nonorm = true; } -# endif // LBMDIM==3 - if(!nonorm) { - // in domain, revert to helper, use setCurr&mMaxRefine - LbmVec bnormal; - CellFlagType *bflag = &RFLAG(mMaxRefine, i,j,k, mLevel[mMaxRefine].setCurr); - LbmFloat *bcell = RACPNT(mMaxRefine, i,j,k, mLevel[mMaxRefine].setCurr); - computeObstacleSurfaceNormal(bcell,bflag, &bnormal[0]); - // TODO check if there is a normal near here? - // use wider range otherwise... - snret[0]=bnormal[0]; snret[1]=bnormal[0]; snret[2]=bnormal[0]; - return; - } - snret[0]=nx; snret[1]=ny; snret[2]=nz; -} - -void LbmFsgrSolver::addToNewInterList( int ni, int nj, int nk ) { -#if FSGR_STRICT_DEBUG==10 - // dangerous, this can change the simulation... - /*for( vector<LbmPoint>::iterator iter=mListNewInter.begin(); - iter != mListNewInter.end(); iter++ ) { - if(ni!=iter->x) continue; - if(nj!=iter->y) continue; - if(nk!=iter->z) continue; - // all 3 values match... skip point - return; - } */ -#endif // FSGR_STRICT_DEBUG==1 - // store point - LbmPoint newinter; newinter.flag = 0; - newinter.x = ni; newinter.y = nj; newinter.z = nk; - mListNewInter.push_back(newinter); -} - -void LbmFsgrSolver::reinitFlags( int workSet ) { - // reinitCellFlags OLD mods: - // add all to intel list? - // check ffrac for new cells - // new if cell inits (last loop) - // vweights handling - - const int debugFlagreinit = 0; - - // some things need to be read/modified on the other set - int otherSet = (workSet^1); - // fixed level on which to perform - int workLev = mMaxRefine; - - /* modify interface cells from lists */ - /* mark filled interface cells as fluid, or emptied as empty */ - /* count neighbors and distribute excess mass to interface neighbor cells - * problems arise when there are no interface neighbors anymore - * then just distribute to any fluid neighbors... - */ - - // for symmetry, first init all neighbor cells */ - for( vector<LbmPoint>::iterator iter=mListFull.begin(); - iter != mListFull.end(); iter++ ) { - int i=iter->x, j=iter->y, k=iter->z; - if(debugFlagreinit) errMsg("FULL", PRINT_IJK<<" mss"<<QCELL(workLev, i,j,k, workSet, dMass) <<" rho"<< QCELL(workLev, i,j,k, workSet, 0) ); // DEBUG SYMM - FORDF1 { - int ni=i+this->dfVecX[l], nj=j+this->dfVecY[l], nk=k+this->dfVecZ[l]; - //if((LBMDIM>2)&&( (ni<=0) || (nj<=0) || (nk<=0) || (ni>=mLevel[workLev].lSizex-1) || (nj>=mLevel[workLev].lSizey-1) || (nk>=mLevel[workLev].lSizez-1) )) { - if( (ni<=0) || (nj<=0) || - (ni>=mLevel[workLev].lSizex-1) || - (nj>=mLevel[workLev].lSizey-1) -# if LBMDIM==3 - || (nk<=0) || (nk>=mLevel[workLev].lSizez-1) -# endif // LBMDIM==1 - ) { - continue; } // new bc, dont treat cells on boundary NEWBC - if( RFLAG(workLev, ni,nj,nk, workSet) & CFEmpty ){ - - // preinit speed, get from average surrounding cells - // interpolate from non-workset to workset, sets are handled in function - - // new and empty interface cell, dont change old flag here! - addToNewInterList(ni,nj,nk); - - LbmFloat avgrho = 0.0; - LbmFloat avgux = 0.0, avguy = 0.0, avguz = 0.0; - interpolateCellValues(workLev,ni,nj,nk,workSet, avgrho,avgux,avguy,avguz); - - // careful with l's... - FORDF0M { - QCELL(workLev,ni,nj,nk, workSet, m) = this->getCollideEq( m,avgrho, avgux, avguy, avguz ); - //QCELL(workLev,ni,nj,nk, workSet, l) = avgnbdf[l]; // CHECK FIXME test? - } - //errMsg("FNEW", PRINT_VEC(ni,nj,nk)<<" mss"<<QCELL(workLev, i,j,k, workSet, dMass) <<" rho"<<avgrho<<" vel"<<PRINT_VEC(avgux,avguy,avguz) ); // DEBUG SYMM - QCELL(workLev,ni,nj,nk, workSet, dMass) = 0.0; //?? new - QCELL(workLev,ni,nj,nk, workSet, dFfrac) = 0.0; //?? new - //RFLAG(workLev,ni,nj,nk,workSet) = (CellFlagType)(CFInter|CFNoInterpolSrc); - changeFlag(workLev,ni,nj,nk,workSet, (CFInter|CFNoInterpolSrc)); - if(debugFlagreinit) errMsg("NEWE", PRINT_IJK<<" newif "<<PRINT_VEC(ni,nj,nk)<<" rho"<<avgrho<<" vel("<<avgux<<","<<avguy<<","<<avguz<<") " ); - } - /* prevent surrounding interface cells from getting removed as empty cells - * (also cells that are not newly inited) */ - if( RFLAG(workLev,ni,nj,nk, workSet) & CFInter) { - //RFLAG(workLev,ni,nj,nk, workSet) = (CellFlagType)(RFLAG(workLev,ni,nj,nk, workSet) | CFNoDelete); - changeFlag(workLev,ni,nj,nk, workSet, (RFLAG(workLev,ni,nj,nk, workSet) | CFNoDelete)); - // also add to list... - addToNewInterList(ni,nj,nk); - } // NEW? - } - - // NEW? no extra loop... - //RFLAG(workLev,i,j,k, workSet) = CFFluid; - changeFlag(workLev,i,j,k, workSet,CFFluid); - } - - /* remove empty interface cells that are not allowed to be removed anyway - * this is important, otherwise the dreaded cell-type-flickering can occur! */ - for(int n=0; n<(int)mListEmpty.size(); n++) { - int i=mListEmpty[n].x, j=mListEmpty[n].y, k=mListEmpty[n].z; - if((RFLAG(workLev,i,j,k, workSet)&(CFInter|CFNoDelete)) == (CFInter|CFNoDelete)) { - // treat as "new inter" - addToNewInterList(i,j,k); - // remove entry - if(debugFlagreinit) errMsg("EMPT REMOVED!!!", PRINT_IJK<<" mss"<<QCELL(workLev, i,j,k, workSet, dMass) <<" rho"<< QCELL(workLev, i,j,k, workSet, 0) ); // DEBUG SYMM - if(n<(int)mListEmpty.size()-1) mListEmpty[n] = mListEmpty[mListEmpty.size()-1]; - mListEmpty.pop_back(); - n--; - } - } - - - /* problems arise when adjacent cells empty&fill -> - let fill cells+surrounding interface cells have the higher importance */ - for( vector<LbmPoint>::iterator iter=mListEmpty.begin(); - iter != mListEmpty.end(); iter++ ) { - int i=iter->x, j=iter->y, k=iter->z; - if((RFLAG(workLev,i,j,k, workSet)&(CFInter|CFNoDelete)) == (CFInter|CFNoDelete)){ errMsg("A"," ARGHARGRAG "); } // DEBUG - if(debugFlagreinit) errMsg("EMPT", PRINT_IJK<<" mss"<<QCELL(workLev, i,j,k, workSet, dMass) <<" rho"<< QCELL(workLev, i,j,k, workSet, 0) ); - - /* set surrounding fluid cells to interface cells */ - FORDF1 { - int ni=i+this->dfVecX[l], nj=j+this->dfVecY[l], nk=k+this->dfVecZ[l]; - if( RFLAG(workLev,ni,nj,nk, workSet) & CFFluid){ - // init fluid->interface - //RFLAG(workLev,ni,nj,nk, workSet) = (CellFlagType)(CFInter); - changeFlag(workLev,ni,nj,nk, workSet, CFInter); - /* new mass = current density */ - LbmFloat nbrho = QCELL(workLev,ni,nj,nk, workSet, dC); - for(int rl=1; rl< this->cDfNum ; ++rl) { nbrho += QCELL(workLev,ni,nj,nk, workSet, rl); } - QCELL(workLev,ni,nj,nk, workSet, dMass) = nbrho; - QCELL(workLev,ni,nj,nk, workSet, dFfrac) = 1.0; - - // store point - addToNewInterList(ni,nj,nk); - } - if( RFLAG(workLev,ni,nj,nk, workSet) & CFInter){ - // test, also add to list... - addToNewInterList(ni,nj,nk); - } // NEW? - } - - /* for symmetry, set our flag right now */ - changeFlag(workLev,i,j,k, workSet, CFEmpty); - // mark cell not be changed mass... - not necessary, not in list anymore anyway! - } // emptylist - - - - // precompute weights to get rid of order dependancies - vector<lbmFloatSet> vWeights; - vWeights.resize( mListFull.size() + mListEmpty.size() ); - int weightIndex = 0; - int nbCount = 0; - LbmFloat nbWeights[LBM_DFNUM]; - LbmFloat nbTotWeights = 0.0; - for( vector<LbmPoint>::iterator iter=mListFull.begin(); - iter != mListFull.end(); iter++ ) { - int i=iter->x, j=iter->y, k=iter->z; - nbCount = 0; nbTotWeights = 0.0; - FORDF1 { - int ni=i+this->dfVecX[l], nj=j+this->dfVecY[l], nk=k+this->dfVecZ[l]; - if( RFLAG(workLev,ni,nj,nk, workSet) & CFInter) { - nbCount++; - if(iter->flag&1) nbWeights[l] = 1.; // NEWSURFT - else nbWeights[l] = getMassdWeight(1,i,j,k,workSet,l); // NEWSURFT - nbTotWeights += nbWeights[l]; - } else { - nbWeights[l] = -100.0; // DEBUG; - } - } - if(nbCount>0) { - //errMsg("FF I", PRINT_IJK<<" "<<weightIndex<<" "<<nbTotWeights); - vWeights[weightIndex].val[0] = nbTotWeights; - FORDF1 { vWeights[weightIndex].val[l] = nbWeights[l]; } - vWeights[weightIndex].numNbs = (LbmFloat)nbCount; - } else { - vWeights[weightIndex].numNbs = 0.0; - } - weightIndex++; - } - for( vector<LbmPoint>::iterator iter=mListEmpty.begin(); - iter != mListEmpty.end(); iter++ ) { - int i=iter->x, j=iter->y, k=iter->z; - nbCount = 0; nbTotWeights = 0.0; - FORDF1 { - int ni=i+this->dfVecX[l], nj=j+this->dfVecY[l], nk=k+this->dfVecZ[l]; - if( RFLAG(workLev,ni,nj,nk, workSet) & CFInter) { - nbCount++; - if(iter->flag&1) nbWeights[l] = 1.; // NEWSURFT - else nbWeights[l] = getMassdWeight(0,i,j,k,workSet,l); // NEWSURFT - nbTotWeights += nbWeights[l]; - } else { - nbWeights[l] = -100.0; // DEBUG; - } - } - if(nbCount>0) { - //errMsg("EE I", PRINT_IJK<<" "<<weightIndex<<" "<<nbTotWeights); - vWeights[weightIndex].val[0] = nbTotWeights; - FORDF1 { vWeights[weightIndex].val[l] = nbWeights[l]; } - vWeights[weightIndex].numNbs = (LbmFloat)nbCount; - } else { - vWeights[weightIndex].numNbs = 0.0; - } - weightIndex++; - } - weightIndex = 0; - - - /* process full list entries, filled cells are done after this loop */ - for( vector<LbmPoint>::iterator iter=mListFull.begin(); - iter != mListFull.end(); iter++ ) { - int i=iter->x, j=iter->y, k=iter->z; - - LbmFloat myrho = QCELL(workLev,i,j,k, workSet, dC); - FORDF1 { myrho += QCELL(workLev,i,j,k, workSet, l); } // QCELL.rho - - LbmFloat massChange = QCELL(workLev,i,j,k, workSet, dMass) - myrho; - if(vWeights[weightIndex].numNbs>0.0) { - const LbmFloat nbTotWeightsp = vWeights[weightIndex].val[0]; - //errMsg("FF I", PRINT_IJK<<" "<<weightIndex<<" "<<nbTotWeightsp); - FORDF1 { - int ni=i+this->dfVecX[l], nj=j+this->dfVecY[l], nk=k+this->dfVecZ[l]; - if( RFLAG(workLev,ni,nj,nk, workSet) & CFInter) { - LbmFloat change = -1.0; - if(nbTotWeightsp>0.0) { - //change = massChange * ( nbWeights[l]/nbTotWeightsp ); - change = massChange * ( vWeights[weightIndex].val[l]/nbTotWeightsp ); - } else { - change = (LbmFloat)(massChange/vWeights[weightIndex].numNbs); - } - QCELL(workLev,ni,nj,nk, workSet, dMass) += change; - } - } - massChange = 0.0; - } else { - // Problem! no interface neighbors - mFixMass += massChange; - //TTT mNumProblems++; - //errMsg(" FULL PROBLEM ", PRINT_IJK<<" "<<mFixMass); - } - weightIndex++; - - // already done? RFLAG(workLev,i,j,k, workSet) = CFFluid; - QCELL(workLev,i,j,k, workSet, dMass) = myrho; // should be rho... but unused? - QCELL(workLev,i,j,k, workSet, dFfrac) = 1.0; // should be rho... but unused? - } // fulllist - - - /* now, finally handle the empty cells - order is important, has to be after - * full cell handling */ - for( vector<LbmPoint>::iterator iter=mListEmpty.begin(); - iter != mListEmpty.end(); iter++ ) { - int i=iter->x, j=iter->y, k=iter->z; - - LbmFloat massChange = QCELL(workLev, i,j,k, workSet, dMass); - if(vWeights[weightIndex].numNbs>0.0) { - const LbmFloat nbTotWeightsp = vWeights[weightIndex].val[0]; - //errMsg("EE I", PRINT_IJK<<" "<<weightIndex<<" "<<nbTotWeightsp); - FORDF1 { - int ni=i+this->dfVecX[l], nj=j+this->dfVecY[l], nk=k+this->dfVecZ[l]; - if( RFLAG(workLev,ni,nj,nk, workSet) & CFInter) { - LbmFloat change = -1.0; - if(nbTotWeightsp>0.0) { - change = massChange * ( vWeights[weightIndex].val[l]/nbTotWeightsp ); - } else { - change = (LbmFloat)(massChange/vWeights[weightIndex].numNbs); - } - QCELL(workLev, ni,nj,nk, workSet, dMass) += change; - } - } - massChange = 0.0; - } else { - // Problem! no interface neighbors - mFixMass += massChange; - //TTT mNumProblems++; - //errMsg(" EMPT PROBLEM ", PRINT_IJK<<" "<<mFixMass); - } - weightIndex++; - - // finally... make it empty - // already done? RFLAG(workLev,i,j,k, workSet) = CFEmpty; - QCELL(workLev,i,j,k, workSet, dMass) = 0.0; - QCELL(workLev,i,j,k, workSet, dFfrac) = 0.0; - } - for( vector<LbmPoint>::iterator iter=mListEmpty.begin(); - iter != mListEmpty.end(); iter++ ) { - int i=iter->x, j=iter->y, k=iter->z; - changeFlag(workLev,i,j,k, otherSet, CFEmpty); - } - - - // check if some of the new interface cells can be removed again - // never happens !!! not necessary - // calculate ffrac for new IF cells NEW - - // how many are really new interface cells? - int numNewIf = 0; - for( vector<LbmPoint>::iterator iter=mListNewInter.begin(); - iter != mListNewInter.end(); iter++ ) { - int i=iter->x, j=iter->y, k=iter->z; - if(!(RFLAG(workLev,i,j,k, workSet)&CFInter)) { - continue; - // FIXME remove from list? - } - numNewIf++; - } - - // redistribute mass, reinit flags - if(debugFlagreinit) errMsg("NEWIF", "total:"<<mListNewInter.size()); - float newIfFac = 1.0/(LbmFloat)numNewIf; - for( vector<LbmPoint>::iterator iter=mListNewInter.begin(); - iter != mListNewInter.end(); iter++ ) { - int i=iter->x, j=iter->y, k=iter->z; - if((i<=0) || (j<=0) || - (i>=mLevel[workLev].lSizex-1) || - (j>=mLevel[workLev].lSizey-1) || - ((LBMDIM==3) && ((k<=0) || (k>=mLevel[workLev].lSizez-1) ) ) - ) { - continue; } // new bc, dont treat cells on boundary NEWBC - if(!(RFLAG(workLev,i,j,k, workSet)&CFInter)) { - //errMsg("???"," "<<PRINT_IJK); - continue; - } // */ - - QCELL(workLev,i,j,k, workSet, dMass) += (mFixMass * newIfFac); - - int nbored = 0; - FORDF1 { nbored |= RFLAG_NB(workLev, i,j,k, workSet,l); } - if(!(nbored & CFBndNoslip)) { RFLAG(workLev,i,j,k, workSet) |= CFNoBndFluid; } - if(!(nbored & CFFluid)) { RFLAG(workLev,i,j,k, workSet) |= CFNoNbFluid; } - if(!(nbored & CFEmpty)) { RFLAG(workLev,i,j,k, workSet) |= CFNoNbEmpty; } - - if(!(RFLAG(workLev,i,j,k, otherSet)&CFInter)) { - RFLAG(workLev,i,j,k, workSet) = (CellFlagType)(RFLAG(workLev,i,j,k, workSet) | CFNoDelete); - } - if(debugFlagreinit) errMsg("NEWIF", PRINT_IJK<<" mss"<<QCELL(workLev, i,j,k, workSet, dMass) <<" f"<< convertCellFlagType2String(RFLAG(workLev,i,j,k, workSet))<<" wl"<<workLev ); - } - - // reinit fill fraction - for( vector<LbmPoint>::iterator iter=mListNewInter.begin(); - iter != mListNewInter.end(); iter++ ) { - int i=iter->x, j=iter->y, k=iter->z; - if(!(RFLAG(workLev,i,j,k, workSet)&CFInter)) { continue; } - - initInterfaceVars(workLev, i,j,k, workSet, false); //int level, int i,int j,int k,int workSet, bool initMass) { - //LbmFloat nrho = 0.0; - //FORDF0 { nrho += QCELL(workLev, i,j,k, workSet, l); } - //QCELL(workLev,i,j,k, workSet, dFfrac) = QCELL(workLev,i,j,k, workSet, dMass)/nrho; - //QCELL(workLev,i,j,k, workSet, dFlux) = FLUX_INIT; - } - - if(mListNewInter.size()>0){ - //errMsg("FixMassDisted"," fm:"<<mFixMass<<" nif:"<<mListNewInter.size() ); - mFixMass = 0.0; - } - - // empty lists for next step - mListFull.clear(); - mListEmpty.clear(); - mListNewInter.clear(); -} // reinitFlags - - - diff --git a/intern/elbeem/intern/solver_relax.h b/intern/elbeem/intern/solver_relax.h deleted file mode 100644 index d665025ba33..00000000000 --- a/intern/elbeem/intern/solver_relax.h +++ /dev/null @@ -1,1169 +0,0 @@ -/** \file - * \ingroup elbeem - */ -/****************************************************************************** - * - * El'Beem - the visual lattice boltzmann freesurface simulator - * All code distributed as part of El'Beem is covered by the version 2 of the - * GNU General Public License. See the file COPYING for details. - * Copyright 2003-2006 Nils Thuerey - * - * Combined 2D/3D Lattice Boltzmann relaxation macros - * - *****************************************************************************/ - -#if FSGR_STRICT_DEBUG==1 -#define CAUSE_PANIC { this->mPanic=1; /* *((int*)(0x0)) = 1; crash*/ } -#else // FSGR_STRICT_DEBUG==1 -#define CAUSE_PANIC { this->mPanic=1; } /*set flag*/ -#endif // FSGR_STRICT_DEBUG==1 - -/****************************************************************************** - * normal relaxation - *****************************************************************************/ - -// standard arrays -#define CSRC_C RAC(ccel , dC ) -#define CSRC_E RAC(ccel + (-1) *(dTotalNum), dE ) -#define CSRC_W RAC(ccel + (+1) *(dTotalNum), dW ) -#define CSRC_N RAC(ccel + (-mLevel[lev].lOffsx) *(dTotalNum), dN ) -#define CSRC_S RAC(ccel + (+mLevel[lev].lOffsx) *(dTotalNum), dS ) -#define CSRC_NE RAC(ccel + (-mLevel[lev].lOffsx-1) *(dTotalNum), dNE) -#define CSRC_NW RAC(ccel + (-mLevel[lev].lOffsx+1) *(dTotalNum), dNW) -#define CSRC_SE RAC(ccel + (+mLevel[lev].lOffsx-1) *(dTotalNum), dSE) -#define CSRC_SW RAC(ccel + (+mLevel[lev].lOffsx+1) *(dTotalNum), dSW) -#define CSRC_T RAC(ccel + (-mLevel[lev].lOffsy) *(dTotalNum), dT ) -#define CSRC_B RAC(ccel + (+mLevel[lev].lOffsy) *(dTotalNum), dB ) -#define CSRC_ET RAC(ccel + (-mLevel[lev].lOffsy-1) *(dTotalNum), dET) -#define CSRC_EB RAC(ccel + (+mLevel[lev].lOffsy-1) *(dTotalNum), dEB) -#define CSRC_WT RAC(ccel + (-mLevel[lev].lOffsy+1) *(dTotalNum), dWT) -#define CSRC_WB RAC(ccel + (+mLevel[lev].lOffsy+1) *(dTotalNum), dWB) -#define CSRC_NT RAC(ccel + (-mLevel[lev].lOffsy-mLevel[lev].lOffsx) *(dTotalNum), dNT) -#define CSRC_NB RAC(ccel + (+mLevel[lev].lOffsy-mLevel[lev].lOffsx) *(dTotalNum), dNB) -#define CSRC_ST RAC(ccel + (-mLevel[lev].lOffsy+mLevel[lev].lOffsx) *(dTotalNum), dST) -#define CSRC_SB RAC(ccel + (+mLevel[lev].lOffsy+mLevel[lev].lOffsx) *(dTotalNum), dSB) - -#define XSRC_C(x) RAC(ccel + (x) *dTotalNum, dC ) -#define XSRC_E(x) RAC(ccel + ((x)-1) *dTotalNum, dE ) -#define XSRC_W(x) RAC(ccel + ((x)+1) *dTotalNum, dW ) -#define XSRC_N(x) RAC(ccel + ((x)-mLevel[lev].lOffsx) *dTotalNum, dN ) -#define XSRC_S(x) RAC(ccel + ((x)+mLevel[lev].lOffsx) *dTotalNum, dS ) -#define XSRC_NE(x) RAC(ccel + ((x)-mLevel[lev].lOffsx-1) *dTotalNum, dNE) -#define XSRC_NW(x) RAC(ccel + ((x)-mLevel[lev].lOffsx+1) *dTotalNum, dNW) -#define XSRC_SE(x) RAC(ccel + ((x)+mLevel[lev].lOffsx-1) *dTotalNum, dSE) -#define XSRC_SW(x) RAC(ccel + ((x)+mLevel[lev].lOffsx+1) *dTotalNum, dSW) -#define XSRC_T(x) RAC(ccel + ((x)-mLevel[lev].lOffsy) *dTotalNum, dT ) -#define XSRC_B(x) RAC(ccel + ((x)+mLevel[lev].lOffsy) *dTotalNum, dB ) -#define XSRC_ET(x) RAC(ccel + ((x)-mLevel[lev].lOffsy-1) *dTotalNum, dET) -#define XSRC_EB(x) RAC(ccel + ((x)+mLevel[lev].lOffsy-1) *dTotalNum, dEB) -#define XSRC_WT(x) RAC(ccel + ((x)-mLevel[lev].lOffsy+1) *dTotalNum, dWT) -#define XSRC_WB(x) RAC(ccel + ((x)+mLevel[lev].lOffsy+1) *dTotalNum, dWB) -#define XSRC_NT(x) RAC(ccel + ((x)-mLevel[lev].lOffsy-mLevel[lev].lOffsx) *dTotalNum, dNT) -#define XSRC_NB(x) RAC(ccel + ((x)+mLevel[lev].lOffsy-mLevel[lev].lOffsx) *dTotalNum, dNB) -#define XSRC_ST(x) RAC(ccel + ((x)-mLevel[lev].lOffsy+mLevel[lev].lOffsx) *dTotalNum, dST) -#define XSRC_SB(x) RAC(ccel + ((x)+mLevel[lev].lOffsy+mLevel[lev].lOffsx) *dTotalNum, dSB) - - - -#define OMEGA(l) mLevel[(l)].omega - -#define EQC ( DFL1*(rho - usqr)) -#define EQN ( DFL2*(rho + uy*(4.5*uy + 3.0) - usqr)) -#define EQS ( DFL2*(rho + uy*(4.5*uy - 3.0) - usqr)) -#define EQE ( DFL2*(rho + ux*(4.5*ux + 3.0) - usqr)) -#define EQW ( DFL2*(rho + ux*(4.5*ux - 3.0) - usqr)) -#define EQT ( DFL2*(rho + uz*(4.5*uz + 3.0) - usqr)) -#define EQB ( DFL2*(rho + uz*(4.5*uz - 3.0) - usqr)) - -#define EQNE ( DFL3*(rho + (+ux+uy)*(4.5*(+ux+uy) + 3.0) - usqr)) -#define EQNW ( DFL3*(rho + (-ux+uy)*(4.5*(-ux+uy) + 3.0) - usqr)) -#define EQSE ( DFL3*(rho + (+ux-uy)*(4.5*(+ux-uy) + 3.0) - usqr)) -#define EQSW ( DFL3*(rho + (-ux-uy)*(4.5*(-ux-uy) + 3.0) - usqr)) -#define EQNT ( DFL3*(rho + (+uy+uz)*(4.5*(+uy+uz) + 3.0) - usqr)) -#define EQNB ( DFL3*(rho + (+uy-uz)*(4.5*(+uy-uz) + 3.0) - usqr)) -#define EQST ( DFL3*(rho + (-uy+uz)*(4.5*(-uy+uz) + 3.0) - usqr)) -#define EQSB ( DFL3*(rho + (-uy-uz)*(4.5*(-uy-uz) + 3.0) - usqr)) -#define EQET ( DFL3*(rho + (+ux+uz)*(4.5*(+ux+uz) + 3.0) - usqr)) -#define EQEB ( DFL3*(rho + (+ux-uz)*(4.5*(+ux-uz) + 3.0) - usqr)) -#define EQWT ( DFL3*(rho + (-ux+uz)*(4.5*(-ux+uz) + 3.0) - usqr)) -#define EQWB ( DFL3*(rho + (-ux-uz)*(4.5*(-ux-uz) + 3.0) - usqr)) - - -// this is a bit ugly, but necessary for the CSRC_ access... -#define MSRC_C m[dC ] -#define MSRC_N m[dN ] -#define MSRC_S m[dS ] -#define MSRC_E m[dE ] -#define MSRC_W m[dW ] -#define MSRC_T m[dT ] -#define MSRC_B m[dB ] -#define MSRC_NE m[dNE] -#define MSRC_NW m[dNW] -#define MSRC_SE m[dSE] -#define MSRC_SW m[dSW] -#define MSRC_NT m[dNT] -#define MSRC_NB m[dNB] -#define MSRC_ST m[dST] -#define MSRC_SB m[dSB] -#define MSRC_ET m[dET] -#define MSRC_EB m[dEB] -#define MSRC_WT m[dWT] -#define MSRC_WB m[dWB] - -// this is a bit ugly, but necessary for the ccel local access... -#define CCEL_C RAC(ccel, dC ) -#define CCEL_N RAC(ccel, dN ) -#define CCEL_S RAC(ccel, dS ) -#define CCEL_E RAC(ccel, dE ) -#define CCEL_W RAC(ccel, dW ) -#define CCEL_T RAC(ccel, dT ) -#define CCEL_B RAC(ccel, dB ) -#define CCEL_NE RAC(ccel, dNE) -#define CCEL_NW RAC(ccel, dNW) -#define CCEL_SE RAC(ccel, dSE) -#define CCEL_SW RAC(ccel, dSW) -#define CCEL_NT RAC(ccel, dNT) -#define CCEL_NB RAC(ccel, dNB) -#define CCEL_ST RAC(ccel, dST) -#define CCEL_SB RAC(ccel, dSB) -#define CCEL_ET RAC(ccel, dET) -#define CCEL_EB RAC(ccel, dEB) -#define CCEL_WT RAC(ccel, dWT) -#define CCEL_WB RAC(ccel, dWB) -// for coarse to fine interpol access -#define CCELG_C(f) (RAC(ccel, dC )*mGaussw[(f)]) -#define CCELG_N(f) (RAC(ccel, dN )*mGaussw[(f)]) -#define CCELG_S(f) (RAC(ccel, dS )*mGaussw[(f)]) -#define CCELG_E(f) (RAC(ccel, dE )*mGaussw[(f)]) -#define CCELG_W(f) (RAC(ccel, dW )*mGaussw[(f)]) -#define CCELG_T(f) (RAC(ccel, dT )*mGaussw[(f)]) -#define CCELG_B(f) (RAC(ccel, dB )*mGaussw[(f)]) -#define CCELG_NE(f) (RAC(ccel, dNE)*mGaussw[(f)]) -#define CCELG_NW(f) (RAC(ccel, dNW)*mGaussw[(f)]) -#define CCELG_SE(f) (RAC(ccel, dSE)*mGaussw[(f)]) -#define CCELG_SW(f) (RAC(ccel, dSW)*mGaussw[(f)]) -#define CCELG_NT(f) (RAC(ccel, dNT)*mGaussw[(f)]) -#define CCELG_NB(f) (RAC(ccel, dNB)*mGaussw[(f)]) -#define CCELG_ST(f) (RAC(ccel, dST)*mGaussw[(f)]) -#define CCELG_SB(f) (RAC(ccel, dSB)*mGaussw[(f)]) -#define CCELG_ET(f) (RAC(ccel, dET)*mGaussw[(f)]) -#define CCELG_EB(f) (RAC(ccel, dEB)*mGaussw[(f)]) -#define CCELG_WT(f) (RAC(ccel, dWT)*mGaussw[(f)]) -#define CCELG_WB(f) (RAC(ccel, dWB)*mGaussw[(f)]) - - -#if PARALLEL==1 -#define CSMOMEGA_STATS(dlev, domega) -#else // PARALLEL==1 -#if FSGR_OMEGA_DEBUG==1 -#define CSMOMEGA_STATS(dlev, domega) \ - mLevel[dlev].avgOmega += domega; mLevel[dlev].avgOmegaCnt+=1.0; -#else // FSGR_OMEGA_DEBUG==1 -#define CSMOMEGA_STATS(dlev, domega) -#endif // FSGR_OMEGA_DEBUG==1 -#endif // PARALLEL==1 - - -// used for main loops and grav init -// source set -#define SRCS(l) mLevel[(l)].setCurr -// target set -#define TSET(l) mLevel[(l)].setOther - -// handle mov. obj -#if FSGR_STRICT_DEBUG==1 - -#define LBMDS_ADDMOV(linv,l) \ - \ - if((nbflag[linv]&CFBndMoving)&&(!(nbflag[l]&CFBnd))){ \ - \ - LbmFloat dte=QCELL_NBINV(lev, i, j, k, SRCS(lev), l,dFlux)-(mSimulationTime+this->mpParam->getTimestep()); \ - if( ABS(dte)< 1e-15 ) { \ - m[l]+=QCELL_NBINV(lev, i, j, k, SRCS(lev), l,l); \ - } else { \ - const int sdx = i+this->dfVecX[linv], sdy = j+this->dfVecY[linv], sdz = k+this->dfVecZ[linv]; \ - \ - errMsg("INVALID_MOV_OBJ_TIME"," at "<<PRINT_IJK<<" from l"<<l<<" "<<PRINT_VEC(sdx,sdy,sdz)<<" t="<<(mSimulationTime+this->mpParam->getTimestep())<<" ct="<<QCELL_NBINV(lev, i, j, k, SRCS(lev), l,dFlux)<<" dte="<<dte); \ - debugMarkCell(lev,sdx,sdy,sdz); \ - } \ - } \ - - - -#else // FSGR_STRICT_DEBUG==1 - -#define LBMDS_ADDMOV(linv,l) \ - \ - \ - if((nbflag[linv]&CFBndMoving)&&(!(nbflag[l]&CFBnd))){ \ - \ - m[l]+=QCELL_NBINV(lev, i, j, k, SRCS(lev), l,l); \ - } \ - - - -#endif // !FSGR_STRICT_DEBUG==1 - -// treatment of freeslip reflection -// used both for OPT and nonOPT -#define DEFAULT_STREAM_FREESLIP(l,invl,mnbf) \ - \ - int nb1 = 0, nb2 = 0; \ - LbmFloat newval = 0.0; \ - const int dx = this->dfVecX[invl], dy = this->dfVecY[invl], dz = this->dfVecZ[invl]; \ - \ - \ - \ - const LbmFloat movadd = ( \ - ((nbflag[invl]&CFBndMoving)&&(!(nbflag[l]&CFBnd))) ? \ - (QCELL_NBINV(lev, i, j, k, SRCS(lev), l,l)) : 0.); \ - \ - if(dz==0) { \ - nb1 = !(RFLAG(lev, i, j+dy,k, SRCS(lev))&(CFFluid|CFInter)); \ - nb2 = !(RFLAG(lev, i+dx,j, k, SRCS(lev))&(CFFluid|CFInter)); \ - if((nb1)&&(!nb2)) { \ - \ - newval = QCELL(lev, i+dx,j,k,SRCS(lev), this->dfRefX[l]); \ - } else \ - if((!nb1)&&(nb2)) { \ - \ - newval = QCELL(lev, i,j+dy,k,SRCS(lev), this->dfRefY[l]); \ - } else { \ - \ - newval = RAC(ccel, this->dfInv[l] ) +movadd /* */; \ - } \ - } else \ - if(dy==0) { \ - nb1 = !(RFLAG(lev, i,j,k+dz, SRCS(lev))&(CFFluid|CFInter)); \ - nb2 = !(RFLAG(lev, i+dx,j,k, SRCS(lev))&(CFFluid|CFInter)); \ - if((nb1)&&(!nb2)) { \ - \ - newval = QCELL(lev, i+dx,j,k,SRCS(lev), this->dfRefX[l]); \ - } else \ - if((!nb1)&&(nb2)) { \ - \ - newval = QCELL(lev, i,j,k+dz,SRCS(lev), this->dfRefZ[l]); \ - } else { \ - \ - newval = RAC(ccel, this->dfInv[l] ) +movadd /* */; \ - } \ - \ - } else \ - \ - { \ - \ - nb1 = !(RFLAG(lev, i,j,k+dz, SRCS(lev))&(CFFluid|CFInter)); \ - nb2 = !(RFLAG(lev, i,j+dy,k, SRCS(lev))&(CFFluid|CFInter)); \ - if((nb1)&&(!nb2)) { \ - \ - newval = QCELL(lev, i,j+dy,k,SRCS(lev), this->dfRefY[l]); \ - } else \ - if((!nb1)&&(nb2)) { \ - \ - newval = QCELL(lev, i,j,k+dz,SRCS(lev), this->dfRefZ[l]); \ - } else { \ - \ - newval = RAC(ccel, this->dfInv[l] ) +movadd /* */; \ - } \ - } \ - \ - if(mnbf & CFBndPartslip) { \ - const LbmFloat partv = mObjectPartslips[(int)(mnbf>>24)]; \ - \ - m[l] = (RAC(ccel, this->dfInv[l] ) +movadd /* d *(1./1.) */ ) * partv + newval * (1.0-partv); \ - } else { \ - m[l] = newval; \ - } \ - \ - - - - -// complete default stream&collide, 2d/3d -/* read distribution funtions of adjacent cells = sweep step */ -#if OPT3D==0 - -#if FSGR_STRICT_DEBUG==1 -#define MARKCELLCHECK \ - debugMarkCell(lev,i,j,k); CAUSE_PANIC; -#define STREAMCHECK(id,ni,nj,nk,nl) \ - if((!(m[nl] > -1.0) && (m[nl]<1.0)) ) {\ - errMsg("STREAMCHECK","ID"<<id<<" Invalid streamed DF nl"<<nl<<" value:"<<m[nl]<<" at "<<PRINT_IJK<<" from "<<PRINT_VEC(ni,nj,nk)<<" nl"<<(nl)<<\ - " nfc"<< RFLAG(lev, ni,nj,nk, mLevel[lev].setCurr)<<" nfo"<< RFLAG(lev, ni,nj,nk, mLevel[lev].setOther) ); \ - /*FORDF0{ errMsg("STREAMCHECK"," at "<<PRINT_IJK<<" df "<<l<<"="<<m[l] ); } */ \ - MARKCELLCHECK; \ - m[nl] = dfEquil[nl]; /* REPAIR */ \ - } -#define COLLCHECK \ - if( (rho>2.0) || (rho<-1.0) || (ABS(ux)>1.0) || (ABS(uy)>1.0) |(ABS(uz)>1.0) ) {\ - errMsg("COLLCHECK","Invalid collision values r:"<<rho<<" u:"PRINT_VEC(ux,uy,uz)<<" at? "<<PRINT_IJK ); \ - /*FORDF0{ errMsg("COLLCHECK"," at? "<<PRINT_IJK<<" df "<<l<<"="<<m[l] ); }*/ \ - rho=ux=uy=uz= 0.; /* REPAIR */ \ - MARKCELLCHECK; \ - } -#else -#define STREAMCHECK(id, ni,nj,nk,nl) -#define COLLCHECK -#endif - -// careful ux,uy,uz need to be inited before! -#define DEFAULT_STREAM \ - m[dC] = RAC(ccel,dC); \ - STREAMCHECK(1, i,j,k, dC); \ - FORDF1 { \ - CellFlagType nbf = nbflag[ this->dfInv[l] ]; \ - if(nbf & CFBnd) { \ - if(nbf & CFBndNoslip) { \ - \ - m[l] = RAC(ccel, this->dfInv[l] ); \ - LBMDS_ADDMOV(this->dfInv[l],l); \ - STREAMCHECK(2, i,j,k, l); \ - } else if(nbf & (CFBndFreeslip|CFBndPartslip)) { \ - \ - if(l<=LBMDIM*2) { \ - m[l] = RAC(ccel, this->dfInv[l] ); STREAMCHECK(3, i,j,k, l); \ - LBMDS_ADDMOV(this->dfInv[l],l); \ - } else { \ - const int inv_l = this->dfInv[l]; \ - DEFAULT_STREAM_FREESLIP(l,inv_l,nbf); \ - } \ - \ - } \ - else { \ - errMsg("LbmFsgrSolver","Invalid Bnd type at "<<PRINT_IJK<<" f"<<convertCellFlagType2String(nbf)<<",nbdir"<<this->dfInv[l] ); \ - } \ - } else { \ - m[l] = QCELL_NBINV(lev, i, j, k, SRCS(lev), l,l); \ - if(RFLAG(lev, i,j,k, mLevel[lev].setCurr)&CFFluid) { \ - if(!(nbf&(CFFluid|CFInter)) ) { \ - int ni=i+this->dfVecX[this->dfInv[l]], nj=j+this->dfVecY[this->dfInv[l]], nk=k+this->dfVecZ[this->dfInv[l]]; \ - errMsg("STREAMCHECK"," Invalid nbflag, streamed DF l"<<l<<" value:"<<m[l]<<" at "<<PRINT_IJK<<" from "<< \ - PRINT_VEC(ni,nj,nk) <<" l"<<(l)<< \ - " nfc"<< RFLAG(lev, ni,nj,nk, mLevel[lev].setCurr)<<" nfo"<< RFLAG(lev, ni,nj,nk, mLevel[lev].setOther) ); \ - \ - \ - } } \ - STREAMCHECK(4, i+this->dfVecX[this->dfInv[l]], j+this->dfVecY[this->dfInv[l]],k+this->dfVecZ[this->dfInv[l]], l); \ - } \ - } \ - - - - -// careful ux,uy,uz need to be inited before! -#define DEFAULT_COLLIDEG(grav) \ - this->collideArrays(lev, i,j,k, m, rho,ux,uy,uz, OMEGA(lev), grav, mLevel[lev].lcsmago, &mDebugOmegaRet, &lcsmqo ); \ - CSMOMEGA_STATS(lev,mDebugOmegaRet); \ - FORDF0 { RAC(tcel,l) = m[l]; } \ - usqr = 1.5 * (ux*ux + uy*uy + uz*uz); \ - COLLCHECK; \ - - - -#define OPTIMIZED_STREAMCOLLIDE \ - m[0] = RAC(ccel,0); \ - FORDF1 { \ - \ - if(RFLAG_NBINV(lev, i,j,k,SRCS(lev),l)&CFBnd) { errMsg("???", "bnd-err-nobndfl"); CAUSE_PANIC; \ - } else { m[l] = QCELL_NBINV(lev, i, j, k, SRCS(lev), l, l); } \ - STREAMCHECK(8, i+this->dfVecX[this->dfInv[l]], j+this->dfVecY[this->dfInv[l]],k+this->dfVecZ[this->dfInv[l]], l); \ - } \ - rho=m[0]; \ - DEFAULT_COLLIDEG(mLevel[lev].gravity) \ - - - -#define OPTIMIZED_STREAMCOLLIDE___UNUSED \ - \ - this->collideArrays(lev, i,j,k, m, rho,ux,uy,uz, OMEGA(lev), mLevel[lev].gravity, mLevel[lev].lcsmago , &mDebugOmegaRet, &lcsmqo ); \ - CSMOMEGA_STATS(lev,mDebugOmegaRet); \ - FORDF0 { RAC(tcel,l) = m[l]; } \ - usqr = 1.5 * (ux*ux + uy*uy + uz*uz); \ - COLLCHECK; \ - - - -#else // 3D, opt OPT3D==true - - -// default stream opt3d add moving bc val -#define DEFAULT_STREAM \ - m[dC] = RAC(ccel,dC); \ - \ - if(0 /* ((!nbored) & CFBnd) */) { \ - \ - m[dN ] = CSRC_N ; m[dS ] = CSRC_S ; \ - m[dE ] = CSRC_E ; m[dW ] = CSRC_W ; \ - m[dT ] = CSRC_T ; m[dB ] = CSRC_B ; \ - m[dNE] = CSRC_NE; m[dNW] = CSRC_NW; m[dSE] = CSRC_SE; m[dSW] = CSRC_SW; \ - m[dNT] = CSRC_NT; m[dNB] = CSRC_NB; m[dST] = CSRC_ST; m[dSB] = CSRC_SB; \ - m[dET] = CSRC_ET; m[dEB] = CSRC_EB; m[dWT] = CSRC_WT; m[dWB] = CSRC_WB; \ - } else { \ - \ - if(nbflag[dS ]&CFBnd) { m[dN ] = RAC(ccel,dS ); LBMDS_ADDMOV(dS ,dN ); } else { m[dN ] = CSRC_N ; } \ - if(nbflag[dN ]&CFBnd) { m[dS ] = RAC(ccel,dN ); LBMDS_ADDMOV(dN ,dS ); } else { m[dS ] = CSRC_S ; } \ - if(nbflag[dW ]&CFBnd) { m[dE ] = RAC(ccel,dW ); LBMDS_ADDMOV(dW ,dE ); } else { m[dE ] = CSRC_E ; } \ - if(nbflag[dE ]&CFBnd) { m[dW ] = RAC(ccel,dE ); LBMDS_ADDMOV(dE ,dW ); } else { m[dW ] = CSRC_W ; } \ - if(nbflag[dB ]&CFBnd) { m[dT ] = RAC(ccel,dB ); LBMDS_ADDMOV(dB ,dT ); } else { m[dT ] = CSRC_T ; } \ - if(nbflag[dT ]&CFBnd) { m[dB ] = RAC(ccel,dT ); LBMDS_ADDMOV(dT ,dB ); } else { m[dB ] = CSRC_B ; } \ - \ - \ - if(nbflag[dSW]&CFBnd) { if(nbflag[dSW]&CFBndNoslip){ m[dNE] = RAC(ccel,dSW); LBMDS_ADDMOV(dSW,dNE); }else{ DEFAULT_STREAM_FREESLIP(dNE,dSW,nbflag[dSW]);} } else { m[dNE] = CSRC_NE; } \ - if(nbflag[dSE]&CFBnd) { if(nbflag[dSE]&CFBndNoslip){ m[dNW] = RAC(ccel,dSE); LBMDS_ADDMOV(dSE,dNW); }else{ DEFAULT_STREAM_FREESLIP(dNW,dSE,nbflag[dSE]);} } else { m[dNW] = CSRC_NW; } \ - if(nbflag[dNW]&CFBnd) { if(nbflag[dNW]&CFBndNoslip){ m[dSE] = RAC(ccel,dNW); LBMDS_ADDMOV(dNW,dSE); }else{ DEFAULT_STREAM_FREESLIP(dSE,dNW,nbflag[dNW]);} } else { m[dSE] = CSRC_SE; } \ - if(nbflag[dNE]&CFBnd) { if(nbflag[dNE]&CFBndNoslip){ m[dSW] = RAC(ccel,dNE); LBMDS_ADDMOV(dNE,dSW); }else{ DEFAULT_STREAM_FREESLIP(dSW,dNE,nbflag[dNE]);} } else { m[dSW] = CSRC_SW; } \ - if(nbflag[dSB]&CFBnd) { if(nbflag[dSB]&CFBndNoslip){ m[dNT] = RAC(ccel,dSB); LBMDS_ADDMOV(dSB,dNT); }else{ DEFAULT_STREAM_FREESLIP(dNT,dSB,nbflag[dSB]);} } else { m[dNT] = CSRC_NT; } \ - if(nbflag[dST]&CFBnd) { if(nbflag[dST]&CFBndNoslip){ m[dNB] = RAC(ccel,dST); LBMDS_ADDMOV(dST,dNB); }else{ DEFAULT_STREAM_FREESLIP(dNB,dST,nbflag[dST]);} } else { m[dNB] = CSRC_NB; } \ - if(nbflag[dNB]&CFBnd) { if(nbflag[dNB]&CFBndNoslip){ m[dST] = RAC(ccel,dNB); LBMDS_ADDMOV(dNB,dST); }else{ DEFAULT_STREAM_FREESLIP(dST,dNB,nbflag[dNB]);} } else { m[dST] = CSRC_ST; } \ - if(nbflag[dNT]&CFBnd) { if(nbflag[dNT]&CFBndNoslip){ m[dSB] = RAC(ccel,dNT); LBMDS_ADDMOV(dNT,dSB); }else{ DEFAULT_STREAM_FREESLIP(dSB,dNT,nbflag[dNT]);} } else { m[dSB] = CSRC_SB; } \ - if(nbflag[dWB]&CFBnd) { if(nbflag[dWB]&CFBndNoslip){ m[dET] = RAC(ccel,dWB); LBMDS_ADDMOV(dWB,dET); }else{ DEFAULT_STREAM_FREESLIP(dET,dWB,nbflag[dWB]);} } else { m[dET] = CSRC_ET; } \ - if(nbflag[dWT]&CFBnd) { if(nbflag[dWT]&CFBndNoslip){ m[dEB] = RAC(ccel,dWT); LBMDS_ADDMOV(dWT,dEB); }else{ DEFAULT_STREAM_FREESLIP(dEB,dWT,nbflag[dWT]);} } else { m[dEB] = CSRC_EB; } \ - if(nbflag[dEB]&CFBnd) { if(nbflag[dEB]&CFBndNoslip){ m[dWT] = RAC(ccel,dEB); LBMDS_ADDMOV(dEB,dWT); }else{ DEFAULT_STREAM_FREESLIP(dWT,dEB,nbflag[dEB]);} } else { m[dWT] = CSRC_WT; } \ - if(nbflag[dET]&CFBnd) { if(nbflag[dET]&CFBndNoslip){ m[dWB] = RAC(ccel,dET); LBMDS_ADDMOV(dET,dWB); }else{ DEFAULT_STREAM_FREESLIP(dWB,dET,nbflag[dET]);} } else { m[dWB] = CSRC_WB; } \ - } \ - - - - - -#define COLL_CALCULATE_DFEQ(dstarray) \ - dstarray[dN ] = EQN ; dstarray[dS ] = EQS ; \ - dstarray[dE ] = EQE ; dstarray[dW ] = EQW ; \ - dstarray[dT ] = EQT ; dstarray[dB ] = EQB ; \ - dstarray[dNE] = EQNE; dstarray[dNW] = EQNW; dstarray[dSE] = EQSE; dstarray[dSW] = EQSW; \ - dstarray[dNT] = EQNT; dstarray[dNB] = EQNB; dstarray[dST] = EQST; dstarray[dSB] = EQSB; \ - dstarray[dET] = EQET; dstarray[dEB] = EQEB; dstarray[dWT] = EQWT; dstarray[dWB] = EQWB; \ - - - -#define COLL_CALCULATE_NONEQTENSOR(csolev, srcArray ) \ - lcsmqadd = (srcArray##NE - lcsmeq[ dNE ]); \ - lcsmqadd -= (srcArray##NW - lcsmeq[ dNW ]); \ - lcsmqadd -= (srcArray##SE - lcsmeq[ dSE ]); \ - lcsmqadd += (srcArray##SW - lcsmeq[ dSW ]); \ - lcsmqo = (lcsmqadd* lcsmqadd); \ - lcsmqadd = (srcArray##ET - lcsmeq[ dET ]); \ - lcsmqadd -= (srcArray##EB - lcsmeq[ dEB ]); \ - lcsmqadd -= (srcArray##WT - lcsmeq[ dWT ]); \ - lcsmqadd += (srcArray##WB - lcsmeq[ dWB ]); \ - lcsmqo += (lcsmqadd* lcsmqadd); \ - lcsmqadd = (srcArray##NT - lcsmeq[ dNT ]); \ - lcsmqadd -= (srcArray##NB - lcsmeq[ dNB ]); \ - lcsmqadd -= (srcArray##ST - lcsmeq[ dST ]); \ - lcsmqadd += (srcArray##SB - lcsmeq[ dSB ]); \ - lcsmqo += (lcsmqadd* lcsmqadd); \ - lcsmqo *= 2.0; \ - lcsmqadd = (srcArray##E - lcsmeq[ dE ]); \ - lcsmqadd += (srcArray##W - lcsmeq[ dW ]); \ - lcsmqadd += (srcArray##NE - lcsmeq[ dNE ]); \ - lcsmqadd += (srcArray##NW - lcsmeq[ dNW ]); \ - lcsmqadd += (srcArray##SE - lcsmeq[ dSE ]); \ - lcsmqadd += (srcArray##SW - lcsmeq[ dSW ]); \ - lcsmqadd += (srcArray##ET - lcsmeq[ dET ]); \ - lcsmqadd += (srcArray##EB - lcsmeq[ dEB ]); \ - lcsmqadd += (srcArray##WT - lcsmeq[ dWT ]); \ - lcsmqadd += (srcArray##WB - lcsmeq[ dWB ]); \ - lcsmqo += (lcsmqadd* lcsmqadd); \ - lcsmqadd = (srcArray##N - lcsmeq[ dN ]); \ - lcsmqadd += (srcArray##S - lcsmeq[ dS ]); \ - lcsmqadd += (srcArray##NE - lcsmeq[ dNE ]); \ - lcsmqadd += (srcArray##NW - lcsmeq[ dNW ]); \ - lcsmqadd += (srcArray##SE - lcsmeq[ dSE ]); \ - lcsmqadd += (srcArray##SW - lcsmeq[ dSW ]); \ - lcsmqadd += (srcArray##NT - lcsmeq[ dNT ]); \ - lcsmqadd += (srcArray##NB - lcsmeq[ dNB ]); \ - lcsmqadd += (srcArray##ST - lcsmeq[ dST ]); \ - lcsmqadd += (srcArray##SB - lcsmeq[ dSB ]); \ - lcsmqo += (lcsmqadd* lcsmqadd); \ - lcsmqadd = (srcArray##T - lcsmeq[ dT ]); \ - lcsmqadd += (srcArray##B - lcsmeq[ dB ]); \ - lcsmqadd += (srcArray##NT - lcsmeq[ dNT ]); \ - lcsmqadd += (srcArray##NB - lcsmeq[ dNB ]); \ - lcsmqadd += (srcArray##ST - lcsmeq[ dST ]); \ - lcsmqadd += (srcArray##SB - lcsmeq[ dSB ]); \ - lcsmqadd += (srcArray##ET - lcsmeq[ dET ]); \ - lcsmqadd += (srcArray##EB - lcsmeq[ dEB ]); \ - lcsmqadd += (srcArray##WT - lcsmeq[ dWT ]); \ - lcsmqadd += (srcArray##WB - lcsmeq[ dWB ]); \ - lcsmqo += (lcsmqadd* lcsmqadd); \ - lcsmqo = sqrt(lcsmqo); \ - - - -// COLL_CALCULATE_CSMOMEGAVAL(csolev, lcsmomega); - -// careful - need lcsmqo -#define COLL_CALCULATE_CSMOMEGAVAL(csolev, dstomega ) \ - dstomega = 1.0/ \ - ( 3.0*( mLevel[(csolev)].lcnu+mLevel[(csolev)].lcsmago_sqr*( \ - -mLevel[(csolev)].lcnu + sqrt( mLevel[(csolev)].lcnu*mLevel[(csolev)].lcnu + 18.0*mLevel[(csolev)].lcsmago_sqr* lcsmqo ) \ - / (6.0*mLevel[(csolev)].lcsmago_sqr)) \ - ) +0.5 ); \ - - - -#define DEFAULT_COLLIDE_LES(grav) \ - rho = + MSRC_C + MSRC_N \ - + MSRC_S + MSRC_E \ - + MSRC_W + MSRC_T \ - + MSRC_B + MSRC_NE \ - + MSRC_NW + MSRC_SE \ - + MSRC_SW + MSRC_NT \ - + MSRC_NB + MSRC_ST \ - + MSRC_SB + MSRC_ET \ - + MSRC_EB + MSRC_WT \ - + MSRC_WB; \ - \ - ux = MSRC_E - MSRC_W \ - + MSRC_NE - MSRC_NW \ - + MSRC_SE - MSRC_SW \ - + MSRC_ET + MSRC_EB \ - - MSRC_WT - MSRC_WB ; \ - \ - uy = MSRC_N - MSRC_S \ - + MSRC_NE + MSRC_NW \ - - MSRC_SE - MSRC_SW \ - + MSRC_NT + MSRC_NB \ - - MSRC_ST - MSRC_SB ; \ - \ - uz = MSRC_T - MSRC_B \ - + MSRC_NT - MSRC_NB \ - + MSRC_ST - MSRC_SB \ - + MSRC_ET - MSRC_EB \ - + MSRC_WT - MSRC_WB ; \ - PRECOLLIDE_MODS(rho,ux,uy,uz, grav); \ - usqr = 1.5 * (ux*ux + uy*uy + uz*uz); \ - COLL_CALCULATE_DFEQ(lcsmeq); \ - COLL_CALCULATE_NONEQTENSOR(lev, MSRC_); \ - COLL_CALCULATE_CSMOMEGAVAL(lev, lcsmomega); \ - CSMOMEGA_STATS(lev,lcsmomega); \ - \ - RAC(tcel,dC ) = (1.0-lcsmomega)*MSRC_C + lcsmomega*EQC ; \ - \ - RAC(tcel,dN ) = (1.0-lcsmomega)*MSRC_N + lcsmomega*lcsmeq[ dN ]; \ - RAC(tcel,dS ) = (1.0-lcsmomega)*MSRC_S + lcsmomega*lcsmeq[ dS ]; \ - RAC(tcel,dE ) = (1.0-lcsmomega)*MSRC_E + lcsmomega*lcsmeq[ dE ]; \ - RAC(tcel,dW ) = (1.0-lcsmomega)*MSRC_W + lcsmomega*lcsmeq[ dW ]; \ - RAC(tcel,dT ) = (1.0-lcsmomega)*MSRC_T + lcsmomega*lcsmeq[ dT ]; \ - RAC(tcel,dB ) = (1.0-lcsmomega)*MSRC_B + lcsmomega*lcsmeq[ dB ]; \ - \ - RAC(tcel,dNE) = (1.0-lcsmomega)*MSRC_NE + lcsmomega*lcsmeq[ dNE]; \ - RAC(tcel,dNW) = (1.0-lcsmomega)*MSRC_NW + lcsmomega*lcsmeq[ dNW]; \ - RAC(tcel,dSE) = (1.0-lcsmomega)*MSRC_SE + lcsmomega*lcsmeq[ dSE]; \ - RAC(tcel,dSW) = (1.0-lcsmomega)*MSRC_SW + lcsmomega*lcsmeq[ dSW]; \ - RAC(tcel,dNT) = (1.0-lcsmomega)*MSRC_NT + lcsmomega*lcsmeq[ dNT]; \ - RAC(tcel,dNB) = (1.0-lcsmomega)*MSRC_NB + lcsmomega*lcsmeq[ dNB]; \ - RAC(tcel,dST) = (1.0-lcsmomega)*MSRC_ST + lcsmomega*lcsmeq[ dST]; \ - RAC(tcel,dSB) = (1.0-lcsmomega)*MSRC_SB + lcsmomega*lcsmeq[ dSB]; \ - RAC(tcel,dET) = (1.0-lcsmomega)*MSRC_ET + lcsmomega*lcsmeq[ dET]; \ - RAC(tcel,dEB) = (1.0-lcsmomega)*MSRC_EB + lcsmomega*lcsmeq[ dEB]; \ - RAC(tcel,dWT) = (1.0-lcsmomega)*MSRC_WT + lcsmomega*lcsmeq[ dWT]; \ - RAC(tcel,dWB) = (1.0-lcsmomega)*MSRC_WB + lcsmomega*lcsmeq[ dWB]; \ - - - -#define DEFAULT_COLLIDE_NOLES(grav) \ - rho = + MSRC_C + MSRC_N \ - + MSRC_S + MSRC_E \ - + MSRC_W + MSRC_T \ - + MSRC_B + MSRC_NE \ - + MSRC_NW + MSRC_SE \ - + MSRC_SW + MSRC_NT \ - + MSRC_NB + MSRC_ST \ - + MSRC_SB + MSRC_ET \ - + MSRC_EB + MSRC_WT \ - + MSRC_WB; \ - \ - ux = MSRC_E - MSRC_W \ - + MSRC_NE - MSRC_NW \ - + MSRC_SE - MSRC_SW \ - + MSRC_ET + MSRC_EB \ - - MSRC_WT - MSRC_WB ; \ - \ - uy = MSRC_N - MSRC_S \ - + MSRC_NE + MSRC_NW \ - - MSRC_SE - MSRC_SW \ - + MSRC_NT + MSRC_NB \ - - MSRC_ST - MSRC_SB ; \ - \ - uz = MSRC_T - MSRC_B \ - + MSRC_NT - MSRC_NB \ - + MSRC_ST - MSRC_SB \ - + MSRC_ET - MSRC_EB \ - + MSRC_WT - MSRC_WB ; \ - PRECOLLIDE_MODS(rho, ux,uy,uz, grav); \ - usqr = 1.5 * (ux*ux + uy*uy + uz*uz); \ - \ - RAC(tcel,dC ) = (1.0-OMEGA(lev))*MSRC_C + OMEGA(lev)*EQC ; \ - \ - RAC(tcel,dN ) = (1.0-OMEGA(lev))*MSRC_N + OMEGA(lev)*EQN ; \ - RAC(tcel,dS ) = (1.0-OMEGA(lev))*MSRC_S + OMEGA(lev)*EQS ; \ - RAC(tcel,dE ) = (1.0-OMEGA(lev))*MSRC_E + OMEGA(lev)*EQE ; \ - RAC(tcel,dW ) = (1.0-OMEGA(lev))*MSRC_W + OMEGA(lev)*EQW ; \ - RAC(tcel,dT ) = (1.0-OMEGA(lev))*MSRC_T + OMEGA(lev)*EQT ; \ - RAC(tcel,dB ) = (1.0-OMEGA(lev))*MSRC_B + OMEGA(lev)*EQB ; \ - \ - RAC(tcel,dNE) = (1.0-OMEGA(lev))*MSRC_NE + OMEGA(lev)*EQNE; \ - RAC(tcel,dNW) = (1.0-OMEGA(lev))*MSRC_NW + OMEGA(lev)*EQNW; \ - RAC(tcel,dSE) = (1.0-OMEGA(lev))*MSRC_SE + OMEGA(lev)*EQSE; \ - RAC(tcel,dSW) = (1.0-OMEGA(lev))*MSRC_SW + OMEGA(lev)*EQSW; \ - RAC(tcel,dNT) = (1.0-OMEGA(lev))*MSRC_NT + OMEGA(lev)*EQNT; \ - RAC(tcel,dNB) = (1.0-OMEGA(lev))*MSRC_NB + OMEGA(lev)*EQNB; \ - RAC(tcel,dST) = (1.0-OMEGA(lev))*MSRC_ST + OMEGA(lev)*EQST; \ - RAC(tcel,dSB) = (1.0-OMEGA(lev))*MSRC_SB + OMEGA(lev)*EQSB; \ - RAC(tcel,dET) = (1.0-OMEGA(lev))*MSRC_ET + OMEGA(lev)*EQET; \ - RAC(tcel,dEB) = (1.0-OMEGA(lev))*MSRC_EB + OMEGA(lev)*EQEB; \ - RAC(tcel,dWT) = (1.0-OMEGA(lev))*MSRC_WT + OMEGA(lev)*EQWT; \ - RAC(tcel,dWB) = (1.0-OMEGA(lev))*MSRC_WB + OMEGA(lev)*EQWB; \ - - - - - -#define OPTIMIZED_STREAMCOLLIDE_LES \ - \ - m[dC ] = CSRC_C ; \ - m[dN ] = CSRC_N ; m[dS ] = CSRC_S ; \ - m[dE ] = CSRC_E ; m[dW ] = CSRC_W ; \ - m[dT ] = CSRC_T ; m[dB ] = CSRC_B ; \ - m[dNE] = CSRC_NE; m[dNW] = CSRC_NW; m[dSE] = CSRC_SE; m[dSW] = CSRC_SW; \ - m[dNT] = CSRC_NT; m[dNB] = CSRC_NB; m[dST] = CSRC_ST; m[dSB] = CSRC_SB; \ - m[dET] = CSRC_ET; m[dEB] = CSRC_EB; m[dWT] = CSRC_WT; m[dWB] = CSRC_WB; \ - \ - rho = MSRC_C + MSRC_N + MSRC_S + MSRC_E + MSRC_W + MSRC_T \ - + MSRC_B + MSRC_NE + MSRC_NW + MSRC_SE + MSRC_SW + MSRC_NT \ - + MSRC_NB + MSRC_ST + MSRC_SB + MSRC_ET + MSRC_EB + MSRC_WT + MSRC_WB; \ - ux = MSRC_E - MSRC_W + MSRC_NE - MSRC_NW + MSRC_SE - MSRC_SW \ - + MSRC_ET + MSRC_EB - MSRC_WT - MSRC_WB; \ - uy = MSRC_N - MSRC_S + MSRC_NE + MSRC_NW - MSRC_SE - MSRC_SW \ - + MSRC_NT + MSRC_NB - MSRC_ST - MSRC_SB; \ - uz = MSRC_T - MSRC_B + MSRC_NT - MSRC_NB + MSRC_ST - MSRC_SB \ - + MSRC_ET - MSRC_EB + MSRC_WT - MSRC_WB; \ - PRECOLLIDE_MODS(rho, ux,uy,uz, mLevel[lev].gravity); \ - usqr = 1.5 * (ux*ux + uy*uy + uz*uz); \ - COLL_CALCULATE_DFEQ(lcsmeq); \ - COLL_CALCULATE_NONEQTENSOR(lev, MSRC_) \ - COLL_CALCULATE_CSMOMEGAVAL(lev, lcsmomega); \ - CSMOMEGA_STATS(lev,lcsmomega); \ - \ - RAC(tcel,dC ) = (1.0-lcsmomega)*MSRC_C + lcsmomega*EQC ; \ - RAC(tcel,dN ) = (1.0-lcsmomega)*MSRC_N + lcsmomega*lcsmeq[ dN ]; \ - RAC(tcel,dS ) = (1.0-lcsmomega)*MSRC_S + lcsmomega*lcsmeq[ dS ]; \ - RAC(tcel,dE ) = (1.0-lcsmomega)*MSRC_E + lcsmomega*lcsmeq[ dE ]; \ - RAC(tcel,dW ) = (1.0-lcsmomega)*MSRC_W + lcsmomega*lcsmeq[ dW ]; \ - RAC(tcel,dT ) = (1.0-lcsmomega)*MSRC_T + lcsmomega*lcsmeq[ dT ]; \ - RAC(tcel,dB ) = (1.0-lcsmomega)*MSRC_B + lcsmomega*lcsmeq[ dB ]; \ - \ - RAC(tcel,dNE) = (1.0-lcsmomega)*MSRC_NE + lcsmomega*lcsmeq[ dNE]; \ - RAC(tcel,dNW) = (1.0-lcsmomega)*MSRC_NW + lcsmomega*lcsmeq[ dNW]; \ - RAC(tcel,dSE) = (1.0-lcsmomega)*MSRC_SE + lcsmomega*lcsmeq[ dSE]; \ - RAC(tcel,dSW) = (1.0-lcsmomega)*MSRC_SW + lcsmomega*lcsmeq[ dSW]; \ - \ - RAC(tcel,dNT) = (1.0-lcsmomega)*MSRC_NT + lcsmomega*lcsmeq[ dNT]; \ - RAC(tcel,dNB) = (1.0-lcsmomega)*MSRC_NB + lcsmomega*lcsmeq[ dNB]; \ - RAC(tcel,dST) = (1.0-lcsmomega)*MSRC_ST + lcsmomega*lcsmeq[ dST]; \ - RAC(tcel,dSB) = (1.0-lcsmomega)*MSRC_SB + lcsmomega*lcsmeq[ dSB]; \ - \ - RAC(tcel,dET) = (1.0-lcsmomega)*MSRC_ET + lcsmomega*lcsmeq[ dET]; \ - RAC(tcel,dEB) = (1.0-lcsmomega)*MSRC_EB + lcsmomega*lcsmeq[ dEB]; \ - RAC(tcel,dWT) = (1.0-lcsmomega)*MSRC_WT + lcsmomega*lcsmeq[ dWT]; \ - RAC(tcel,dWB) = (1.0-lcsmomega)*MSRC_WB + lcsmomega*lcsmeq[ dWB]; \ - - - -#define OPTIMIZED_STREAMCOLLIDE_UNUSED \ - \ - rho = CSRC_C + CSRC_N + CSRC_S + CSRC_E + CSRC_W + CSRC_T \ - + CSRC_B + CSRC_NE + CSRC_NW + CSRC_SE + CSRC_SW + CSRC_NT \ - + CSRC_NB + CSRC_ST + CSRC_SB + CSRC_ET + CSRC_EB + CSRC_WT + CSRC_WB; \ - ux = CSRC_E - CSRC_W + CSRC_NE - CSRC_NW + CSRC_SE - CSRC_SW \ - + CSRC_ET + CSRC_EB - CSRC_WT - CSRC_WB; \ - uy = CSRC_N - CSRC_S + CSRC_NE + CSRC_NW - CSRC_SE - CSRC_SW \ - + CSRC_NT + CSRC_NB - CSRC_ST - CSRC_SB; \ - uz = CSRC_T - CSRC_B + CSRC_NT - CSRC_NB + CSRC_ST - CSRC_SB \ - + CSRC_ET - CSRC_EB + CSRC_WT - CSRC_WB; \ - PRECOLLIDE_MODS(rho, ux,uy,uz, mLevel[lev].gravity); \ - usqr = 1.5 * (ux*ux + uy*uy + uz*uz); \ - COLL_CALCULATE_DFEQ(lcsmeq); \ - COLL_CALCULATE_NONEQTENSOR(lev, CSRC_) \ - COLL_CALCULATE_CSMOMEGAVAL(lev, lcsmomega); \ - \ - RAC(tcel,dC ) = (1.0-lcsmomega)*CSRC_C + lcsmomega*EQC ; \ - RAC(tcel,dN ) = (1.0-lcsmomega)*CSRC_N + lcsmomega*lcsmeq[ dN ]; \ - RAC(tcel,dS ) = (1.0-lcsmomega)*CSRC_S + lcsmomega*lcsmeq[ dS ]; \ - RAC(tcel,dE ) = (1.0-lcsmomega)*CSRC_E + lcsmomega*lcsmeq[ dE ]; \ - RAC(tcel,dW ) = (1.0-lcsmomega)*CSRC_W + lcsmomega*lcsmeq[ dW ]; \ - RAC(tcel,dT ) = (1.0-lcsmomega)*CSRC_T + lcsmomega*lcsmeq[ dT ]; \ - RAC(tcel,dB ) = (1.0-lcsmomega)*CSRC_B + lcsmomega*lcsmeq[ dB ]; \ - \ - RAC(tcel,dNE) = (1.0-lcsmomega)*CSRC_NE + lcsmomega*lcsmeq[ dNE]; \ - RAC(tcel,dNW) = (1.0-lcsmomega)*CSRC_NW + lcsmomega*lcsmeq[ dNW]; \ - RAC(tcel,dSE) = (1.0-lcsmomega)*CSRC_SE + lcsmomega*lcsmeq[ dSE]; \ - RAC(tcel,dSW) = (1.0-lcsmomega)*CSRC_SW + lcsmomega*lcsmeq[ dSW]; \ - \ - RAC(tcel,dNT) = (1.0-lcsmomega)*CSRC_NT + lcsmomega*lcsmeq[ dNT]; \ - RAC(tcel,dNB) = (1.0-lcsmomega)*CSRC_NB + lcsmomega*lcsmeq[ dNB]; \ - RAC(tcel,dST) = (1.0-lcsmomega)*CSRC_ST + lcsmomega*lcsmeq[ dST]; \ - RAC(tcel,dSB) = (1.0-lcsmomega)*CSRC_SB + lcsmomega*lcsmeq[ dSB]; \ - \ - RAC(tcel,dET) = (1.0-lcsmomega)*CSRC_ET + lcsmomega*lcsmeq[ dET]; \ - RAC(tcel,dEB) = (1.0-lcsmomega)*CSRC_EB + lcsmomega*lcsmeq[ dEB]; \ - RAC(tcel,dWT) = (1.0-lcsmomega)*CSRC_WT + lcsmomega*lcsmeq[ dWT]; \ - RAC(tcel,dWB) = (1.0-lcsmomega)*CSRC_WB + lcsmomega*lcsmeq[ dWB]; \ - - - -#define OPTIMIZED_STREAMCOLLIDE_NOLES \ - \ - rho = CSRC_C + CSRC_N + CSRC_S + CSRC_E + CSRC_W + CSRC_T \ - + CSRC_B + CSRC_NE + CSRC_NW + CSRC_SE + CSRC_SW + CSRC_NT \ - + CSRC_NB + CSRC_ST + CSRC_SB + CSRC_ET + CSRC_EB + CSRC_WT + CSRC_WB; \ - ux = CSRC_E - CSRC_W + CSRC_NE - CSRC_NW + CSRC_SE - CSRC_SW \ - + CSRC_ET + CSRC_EB - CSRC_WT - CSRC_WB; \ - uy = CSRC_N - CSRC_S + CSRC_NE + CSRC_NW - CSRC_SE - CSRC_SW \ - + CSRC_NT + CSRC_NB - CSRC_ST - CSRC_SB; \ - uz = CSRC_T - CSRC_B + CSRC_NT - CSRC_NB + CSRC_ST - CSRC_SB \ - + CSRC_ET - CSRC_EB + CSRC_WT - CSRC_WB; \ - PRECOLLIDE_MODS(rho, ux,uy,uz, mLevel[lev].gravity); \ - usqr = 1.5 * (ux*ux + uy*uy + uz*uz); \ - RAC(tcel,dC ) = (1.0-OMEGA(lev))*CSRC_C + OMEGA(lev)*EQC ; \ - RAC(tcel,dN ) = (1.0-OMEGA(lev))*CSRC_N + OMEGA(lev)*EQN ; \ - RAC(tcel,dS ) = (1.0-OMEGA(lev))*CSRC_S + OMEGA(lev)*EQS ; \ - RAC(tcel,dE ) = (1.0-OMEGA(lev))*CSRC_E + OMEGA(lev)*EQE ; \ - RAC(tcel,dW ) = (1.0-OMEGA(lev))*CSRC_W + OMEGA(lev)*EQW ; \ - RAC(tcel,dT ) = (1.0-OMEGA(lev))*CSRC_T + OMEGA(lev)*EQT ; \ - RAC(tcel,dB ) = (1.0-OMEGA(lev))*CSRC_B + OMEGA(lev)*EQB ; \ - \ - RAC(tcel,dNE) = (1.0-OMEGA(lev))*CSRC_NE + OMEGA(lev)*EQNE; \ - RAC(tcel,dNW) = (1.0-OMEGA(lev))*CSRC_NW + OMEGA(lev)*EQNW; \ - RAC(tcel,dSE) = (1.0-OMEGA(lev))*CSRC_SE + OMEGA(lev)*EQSE; \ - RAC(tcel,dSW) = (1.0-OMEGA(lev))*CSRC_SW + OMEGA(lev)*EQSW; \ - \ - RAC(tcel,dNT) = (1.0-OMEGA(lev))*CSRC_NT + OMEGA(lev)*EQNT; \ - RAC(tcel,dNB) = (1.0-OMEGA(lev))*CSRC_NB + OMEGA(lev)*EQNB; \ - RAC(tcel,dST) = (1.0-OMEGA(lev))*CSRC_ST + OMEGA(lev)*EQST; \ - RAC(tcel,dSB) = (1.0-OMEGA(lev))*CSRC_SB + OMEGA(lev)*EQSB; \ - \ - RAC(tcel,dET) = (1.0-OMEGA(lev))*CSRC_ET + OMEGA(lev)*EQET; \ - RAC(tcel,dEB) = (1.0-OMEGA(lev))*CSRC_EB + OMEGA(lev)*EQEB; \ - RAC(tcel,dWT) = (1.0-OMEGA(lev))*CSRC_WT + OMEGA(lev)*EQWT; \ - RAC(tcel,dWB) = (1.0-OMEGA(lev))*CSRC_WB + OMEGA(lev)*EQWB; \ - - - - - -// LES switching for OPT3D -#if USE_LES==1 -#define DEFAULT_COLLIDEG(grav) DEFAULT_COLLIDE_LES(grav) -#define OPTIMIZED_STREAMCOLLIDE OPTIMIZED_STREAMCOLLIDE_LES -#else -#define DEFAULT_COLLIDEG(grav) DEFAULT_COLLIDE_NOLES(grav) -#define OPTIMIZED_STREAMCOLLIDE OPTIMIZED_STREAMCOLLIDE_NOLES -#endif - -#endif // 3D, opt OPT3D==true - -#define USQRMAXCHECK(Cusqr,Cux,Cuy,Cuz, CmMaxVlen,CmMxvx,CmMxvy,CmMxvz) \ - if(Cusqr>CmMaxVlen) { \ - CmMxvx = Cux; CmMxvy = Cuy; CmMxvz = Cuz; CmMaxVlen = Cusqr; \ - } /* stats */ - - - -/****************************************************************************** - * interpolateCellFromCoarse macros - *****************************************************************************/ - - -// WOXDY_N = Weight Order X Dimension Y _ number N -#define WO1D1 ( 1.0/ 2.0) -#define WO1D2 ( 1.0/ 4.0) -#define WO1D3 ( 1.0/ 8.0) - -#define WO2D1_1 (-1.0/16.0) -#define WO2D1_9 ( 9.0/16.0) - -#define WO2D2_11 (WO2D1_1 * WO2D1_1) -#define WO2D2_19 (WO2D1_9 * WO2D1_1) -#define WO2D2_91 (WO2D1_9 * WO2D1_1) -#define WO2D2_99 (WO2D1_9 * WO2D1_9) - -#define WO2D3_111 (WO2D1_1 * WO2D1_1 * WO2D1_1) -#define WO2D3_191 (WO2D1_9 * WO2D1_1 * WO2D1_1) -#define WO2D3_911 (WO2D1_9 * WO2D1_1 * WO2D1_1) -#define WO2D3_991 (WO2D1_9 * WO2D1_9 * WO2D1_1) -#define WO2D3_119 (WO2D1_1 * WO2D1_1 * WO2D1_9) -#define WO2D3_199 (WO2D1_9 * WO2D1_1 * WO2D1_9) -#define WO2D3_919 (WO2D1_9 * WO2D1_1 * WO2D1_9) -#define WO2D3_999 (WO2D1_9 * WO2D1_9 * WO2D1_9) - -#if FSGR_STRICT_DEBUG==1 -#define ADD_INT_DFSCHECK(alev, ai,aj,ak, at, afac, l) \ - if( (((1.0-(at))>0.0) && (!(QCELL((alev), (ai),(aj),(ak),mLevel[(alev)].setCurr , l) > -1.0 ))) || \ - ((( (at))>0.0) && (!(QCELL((alev), (ai),(aj),(ak),mLevel[(alev)].setOther, l) > -1.0 ))) ){ \ - errMsg("INVDFSCHECK", " l"<<(alev)<<" "<<PRINT_VEC((ai),(aj),(ak))<<" fc:"<<RFLAG((alev), (ai),(aj),(ak),mLevel[(alev)].setCurr )<<" fo:"<<RFLAG((alev), (ai),(aj),(ak),mLevel[(alev)].setOther )<<" dfl"<<l ); \ - debugMarkCell((alev), (ai),(aj),(ak));\ - CAUSE_PANIC; \ - } - // end ADD_INT_DFSCHECK -#define ADD_INT_FLAGCHECK(alev, ai,aj,ak, at, afac) \ - if( (((1.0-(at))>0.0) && (!(RFLAG((alev), (ai),(aj),(ak),mLevel[(alev)].setCurr )&(CFInter|CFFluid|CFGrCoarseInited) ))) || \ - ((( (at))>0.0) && (!(RFLAG((alev), (ai),(aj),(ak),mLevel[(alev)].setOther)&(CFInter|CFFluid|CFGrCoarseInited) ))) ){ \ - errMsg("INVFLAGCINTCHECK", " l"<<(alev)<<" at:"<<(at)<<" "<<PRINT_VEC((ai),(aj),(ak))<<\ - " fc:"<< convertCellFlagType2String(RFLAG((alev), (ai),(aj),(ak),mLevel[(alev)].setCurr )) <<\ - " fold:"<< convertCellFlagType2String(RFLAG((alev), (ai),(aj),(ak),mLevel[(alev)].setOther )) ); \ - debugMarkCell((alev), (ai),(aj),(ak));\ - CAUSE_PANIC; \ - } - // end ADD_INT_DFSCHECK - -#define INTUNUTCHECK(ix,iy,iz) \ - if( (RFLAG(lev+1, (ix),(iy),(iz), mLevel[lev+1].setCurr) != (CFFluid|CFGrFromCoarse)) ){\ - errMsg("INTFLAGUNU_CHECK", PRINT_VEC(i,j,k)<<" child not unused at l"<<(lev+1)<<" "<<PRINT_VEC((ix),(iy),(iz))<<" flag: "<< RFLAG(lev+1, (ix),(iy),(iz), mLevel[lev+1].setCurr) ); \ - debugMarkCell((lev+1), (ix),(iy),(iz));\ - CAUSE_PANIC; \ - }\ - RFLAG(lev+1, (ix),(iy),(iz), mLevel[lev+1].setCurr) |= CFGrCoarseInited; \ - // INTUNUTCHECK -#define INTSTRICTCHECK(ix,iy,iz,caseId) \ - if( QCELL(lev+1, (ix),(iy),(iz), mLevel[lev+1].setCurr, l) <= 0.0 ){\ - errMsg("INVDFCCELLCHECK", "caseId:"<<caseId<<" "<<PRINT_VEC(i,j,k)<<" child inter at "<<PRINT_VEC((ix),(iy),(iz))<<" invalid df "<<l<<" = "<< QCELL(lev+1, (ix),(iy),(iz), mLevel[lev+1].setCurr, l) ); \ - debugMarkCell((lev+1), (ix),(iy),(iz));\ - CAUSE_PANIC; \ - }\ - // INTSTRICTCHECK - -#else// FSGR_STRICT_DEBUG==1 -#define ADD_INT_FLAGCHECK(alev, ai,aj,ak, at, afac) -#define ADD_INT_DFSCHECK(alev, ai,aj,ak, at, afac, l) -#define INTSTRICTCHECK(x,y,z,caseId) -#define INTUNUTCHECK(ix,iy,iz) -#endif// FSGR_STRICT_DEBUG==1 - - -#if FSGR_STRICT_DEBUG==1 -#define INTDEBOUT \ - { /*LbmFloat rho,ux,uy,uz;*/ \ - rho = ux=uy=uz=0.0; \ - FORDF0{ LbmFloat m = QCELL(lev,i,j,k, dstSet, l); \ - rho += m; ux += (this->dfDvecX[l]*m); uy += (this->dfDvecY[l]*m); uz += (this->dfDvecZ[l]*m); \ - if(ABS(m)>1.0) { errMsg("interpolateCellFromCoarse", "ICFC_DFCHECK cell "<<PRINT_IJK<<" m"<<l<<":"<< m );CAUSE_PANIC;}\ - /*errMsg("interpolateCellFromCoarse", " cell "<<PRINT_IJK<<" df"<<l<<":"<<m );*/ \ - } \ - /*if(this->mPanic) { errMsg("interpolateCellFromCoarse", "ICFC_DFOUT cell "<<PRINT_IJK<<" rho:"<<rho<<" u:"<<PRINT_VEC(ux,uy,uz)<<" b"<<PRINT_VEC(betx,bety,betz) ); }*/ \ - if(markNbs) errMsg("interpolateCellFromCoarse", " cell "<<PRINT_IJK<<" rho:"<<rho<<" u:"<<PRINT_VEC(ux,uy,uz)<<" b"<<PRINT_VEC(betx,bety,betz) ); \ - /*errMsg("interpolateCellFromCoarse", "ICFC_DFDEBUG cell "<<PRINT_IJK<<" rho:"<<rho<<" u:"<<PRINT_VEC(ux,uy,uz)<<" b"<<PRINT_VEC(betx,bety,betz) ); */\ - } \ - /* both cases are ok to interpolate */ \ - if( (!(RFLAG(lev,i,j,k, dstSet) & CFGrFromCoarse)) && \ - (!(RFLAG(lev,i,j,k, dstSet) & CFUnused)) ) { \ - /* might also have CFGrCoarseInited (shouldnt be a problem here)*/ \ - errMsg("interpolateCellFromCoarse", "CHECK cell not CFGrFromCoarse? "<<PRINT_IJK<<" flag:"<< RFLAG(lev,i,j,k, dstSet)<<" fstr:"<<convertCellFlagType2String( RFLAG(lev,i,j,k, dstSet) )); \ - /* FIXME check this warning...? return; this can happen !? */ \ - /*CAUSE_PANIC;*/ \ - } \ - // end INTDEBOUT -#else // FSGR_STRICT_DEBUG==1 -#define INTDEBOUT -#endif // FSGR_STRICT_DEBUG==1 - - -// t=0.0 -> only current -// t=0.5 -> mix -// t=1.0 -> only other -#if OPT3D==0 -#define ADD_INT_DFS(alev, ai,aj,ak, at, afac) \ - ADD_INT_FLAGCHECK(alev, ai,aj,ak, at, afac); \ - FORDF0{ \ - LbmFloat df = ( \ - QCELL((alev), (ai),(aj),(ak),mLevel[(alev)].setCurr , l)*(1.0-(at)) + \ - QCELL((alev), (ai),(aj),(ak),mLevel[(alev)].setOther, l)*( (at)) \ - ) ; \ - ADD_INT_DFSCHECK(alev, ai,aj,ak, at, afac, l); \ - df *= (afac); \ - rho += df; \ - ux += (this->dfDvecX[l]*df); \ - uy += (this->dfDvecY[l]*df); \ - uz += (this->dfDvecZ[l]*df); \ - intDf[l] += df; \ - } -// write interpolated dfs back to cell (correct non-eq. parts) -#define IDF_WRITEBACK_ \ - FORDF0{ \ - LbmFloat eq = getCollideEq(l, rho,ux,uy,uz);\ - QCELL(lev,i,j,k, dstSet, l) = (eq+ (intDf[l]-eq)*mDfScaleDown);\ - } \ - /* check that all values are ok */ \ - INTDEBOUT -#define IDF_WRITEBACK \ - LbmFloat omegaDst, omegaSrc;\ - /* smago new */ \ - LbmFloat feq[LBM_DFNUM]; \ - LbmFloat dfScale = mDfScaleDown; \ - FORDF0{ \ - feq[l] = getCollideEq(l, rho,ux,uy,uz); \ - } \ - if(mLevel[lev ].lcsmago>0.0) {\ - LbmFloat Qo = this->getLesNoneqTensorCoeff(intDf,feq); \ - omegaDst = this->getLesOmega(mLevel[lev+0].omega,mLevel[lev+0].lcsmago,Qo); \ - omegaSrc = this->getLesOmega(mLevel[lev-1].omega,mLevel[lev-1].lcsmago,Qo); \ - } else {\ - omegaDst = mLevel[lev+0].omega; \ - omegaSrc = mLevel[lev-1].omega;\ - } \ - \ - dfScale = (mLevel[lev+0].timestep/mLevel[lev-1].timestep)* (1.0/omegaDst-1.0)/ (1.0/omegaSrc-1.0); \ - FORDF0{ \ - /*errMsg("SMAGO"," org"<<mDfScaleDown<<" n"<<dfScale<<" qc"<< QCELL(lev,i,j,k, dstSet, l)<<" idf"<<intDf[l]<<" eq"<<feq[l] ); */ \ - QCELL(lev,i,j,k, dstSet, l) = (feq[l]+ (intDf[l]-feq[l])*dfScale);\ - } \ - /* check that all values are ok */ \ - INTDEBOUT - -#else //OPT3D==0 - -#define ADDALLVALS \ - addVal = addDfFacT * RAC(addfcel , dC ); \ - intDf[dC ] += addVal; rho += addVal; \ - addVal = addDfFacT * RAC(addfcel , dN ); \ - uy+=addVal; intDf[dN ] += addVal; rho += addVal; \ - addVal = addDfFacT * RAC(addfcel , dS ); \ - uy-=addVal; intDf[dS ] += addVal; rho += addVal; \ - addVal = addDfFacT * RAC(addfcel , dE ); \ - ux+=addVal; intDf[dE ] += addVal; rho += addVal; \ - addVal = addDfFacT * RAC(addfcel , dW ); \ - ux-=addVal; intDf[dW ] += addVal; rho += addVal; \ - addVal = addDfFacT * RAC(addfcel , dT ); \ - uz+=addVal; intDf[dT ] += addVal; rho += addVal; \ - addVal = addDfFacT * RAC(addfcel , dB ); \ - uz-=addVal; intDf[dB ] += addVal; rho += addVal; \ - addVal = addDfFacT * RAC(addfcel , dNE); \ - ux+=addVal; uy+=addVal; intDf[dNE] += addVal; rho += addVal; \ - addVal = addDfFacT * RAC(addfcel , dNW); \ - ux-=addVal; uy+=addVal; intDf[dNW] += addVal; rho += addVal; \ - addVal = addDfFacT * RAC(addfcel , dSE); \ - ux+=addVal; uy-=addVal; intDf[dSE] += addVal; rho += addVal; \ - addVal = addDfFacT * RAC(addfcel , dSW); \ - ux-=addVal; uy-=addVal; intDf[dSW] += addVal; rho += addVal; \ - addVal = addDfFacT * RAC(addfcel , dNT); \ - uy+=addVal; uz+=addVal; intDf[dNT] += addVal; rho += addVal; \ - addVal = addDfFacT * RAC(addfcel , dNB); \ - uy+=addVal; uz-=addVal; intDf[dNB] += addVal; rho += addVal; \ - addVal = addDfFacT * RAC(addfcel , dST); \ - uy-=addVal; uz+=addVal; intDf[dST] += addVal; rho += addVal; \ - addVal = addDfFacT * RAC(addfcel , dSB); \ - uy-=addVal; uz-=addVal; intDf[dSB] += addVal; rho += addVal; \ - addVal = addDfFacT * RAC(addfcel , dET); \ - ux+=addVal; uz+=addVal; intDf[dET] += addVal; rho += addVal; \ - addVal = addDfFacT * RAC(addfcel , dEB); \ - ux+=addVal; uz-=addVal; intDf[dEB] += addVal; rho += addVal; \ - addVal = addDfFacT * RAC(addfcel , dWT); \ - ux-=addVal; uz+=addVal; intDf[dWT] += addVal; rho += addVal; \ - addVal = addDfFacT * RAC(addfcel , dWB); \ - ux-=addVal; uz-=addVal; intDf[dWB] += addVal; rho += addVal; - -#define ADD_INT_DFS(alev, ai,aj,ak, at, afac) \ - addDfFacT = at*afac; \ - addfcel = RACPNT((alev), (ai),(aj),(ak),mLevel[(alev)].setOther); \ - ADDALLVALS\ - addDfFacT = (1.0-at)*afac; \ - addfcel = RACPNT((alev), (ai),(aj),(ak),mLevel[(alev)].setCurr); \ - ADDALLVALS - -// also ugly... -#define INTDF_C intDf[dC ] -#define INTDF_N intDf[dN ] -#define INTDF_S intDf[dS ] -#define INTDF_E intDf[dE ] -#define INTDF_W intDf[dW ] -#define INTDF_T intDf[dT ] -#define INTDF_B intDf[dB ] -#define INTDF_NE intDf[dNE] -#define INTDF_NW intDf[dNW] -#define INTDF_SE intDf[dSE] -#define INTDF_SW intDf[dSW] -#define INTDF_NT intDf[dNT] -#define INTDF_NB intDf[dNB] -#define INTDF_ST intDf[dST] -#define INTDF_SB intDf[dSB] -#define INTDF_ET intDf[dET] -#define INTDF_EB intDf[dEB] -#define INTDF_WT intDf[dWT] -#define INTDF_WB intDf[dWB] - - -// write interpolated dfs back to cell (correct non-eq. parts) -#define IDF_WRITEBACK_LES \ - dstcell = RACPNT(lev, i,j,k,dstSet); \ - usqr = 1.5 * (ux*ux + uy*uy + uz*uz); \ - \ - lcsmeq[dC] = EQC ; \ - COLL_CALCULATE_DFEQ(lcsmeq); \ - COLL_CALCULATE_NONEQTENSOR(lev, INTDF_ )\ - COLL_CALCULATE_CSMOMEGAVAL(lev+0, lcsmDstOmega); \ - COLL_CALCULATE_CSMOMEGAVAL(lev-1, lcsmSrcOmega); \ - \ - lcsmdfscale = (mLevel[lev+0].timestep/mLevel[lev-1].timestep)* (1.0/lcsmDstOmega-1.0)/ (1.0/lcsmSrcOmega-1.0); \ - RAC(dstcell, dC ) = (lcsmeq[dC ] + (intDf[dC ]-lcsmeq[dC ] )*lcsmdfscale);\ - RAC(dstcell, dN ) = (lcsmeq[dN ] + (intDf[dN ]-lcsmeq[dN ] )*lcsmdfscale);\ - RAC(dstcell, dS ) = (lcsmeq[dS ] + (intDf[dS ]-lcsmeq[dS ] )*lcsmdfscale);\ - RAC(dstcell, dE ) = (lcsmeq[dE ] + (intDf[dE ]-lcsmeq[dE ] )*lcsmdfscale);\ - RAC(dstcell, dW ) = (lcsmeq[dW ] + (intDf[dW ]-lcsmeq[dW ] )*lcsmdfscale);\ - RAC(dstcell, dT ) = (lcsmeq[dT ] + (intDf[dT ]-lcsmeq[dT ] )*lcsmdfscale);\ - RAC(dstcell, dB ) = (lcsmeq[dB ] + (intDf[dB ]-lcsmeq[dB ] )*lcsmdfscale);\ - RAC(dstcell, dNE) = (lcsmeq[dNE] + (intDf[dNE]-lcsmeq[dNE] )*lcsmdfscale);\ - RAC(dstcell, dNW) = (lcsmeq[dNW] + (intDf[dNW]-lcsmeq[dNW] )*lcsmdfscale);\ - RAC(dstcell, dSE) = (lcsmeq[dSE] + (intDf[dSE]-lcsmeq[dSE] )*lcsmdfscale);\ - RAC(dstcell, dSW) = (lcsmeq[dSW] + (intDf[dSW]-lcsmeq[dSW] )*lcsmdfscale);\ - RAC(dstcell, dNT) = (lcsmeq[dNT] + (intDf[dNT]-lcsmeq[dNT] )*lcsmdfscale);\ - RAC(dstcell, dNB) = (lcsmeq[dNB] + (intDf[dNB]-lcsmeq[dNB] )*lcsmdfscale);\ - RAC(dstcell, dST) = (lcsmeq[dST] + (intDf[dST]-lcsmeq[dST] )*lcsmdfscale);\ - RAC(dstcell, dSB) = (lcsmeq[dSB] + (intDf[dSB]-lcsmeq[dSB] )*lcsmdfscale);\ - RAC(dstcell, dET) = (lcsmeq[dET] + (intDf[dET]-lcsmeq[dET] )*lcsmdfscale);\ - RAC(dstcell, dEB) = (lcsmeq[dEB] + (intDf[dEB]-lcsmeq[dEB] )*lcsmdfscale);\ - RAC(dstcell, dWT) = (lcsmeq[dWT] + (intDf[dWT]-lcsmeq[dWT] )*lcsmdfscale);\ - RAC(dstcell, dWB) = (lcsmeq[dWB] + (intDf[dWB]-lcsmeq[dWB] )*lcsmdfscale);\ - /* IDF_WRITEBACK optimized */ - -#define IDF_WRITEBACK_NOLES \ - dstcell = RACPNT(lev, i,j,k,dstSet); \ - usqr = 1.5 * (ux*ux + uy*uy + uz*uz); \ - \ - RAC(dstcell, dC ) = (EQC + (intDf[dC ]-EQC )*mDfScaleDown);\ - RAC(dstcell, dN ) = (EQN + (intDf[dN ]-EQN )*mDfScaleDown);\ - RAC(dstcell, dS ) = (EQS + (intDf[dS ]-EQS )*mDfScaleDown);\ - /*old*/ RAC(dstcell, dE ) = (EQE + (intDf[dE ]-EQE )*mDfScaleDown);\ - RAC(dstcell, dW ) = (EQW + (intDf[dW ]-EQW )*mDfScaleDown);\ - RAC(dstcell, dT ) = (EQT + (intDf[dT ]-EQT )*mDfScaleDown);\ - RAC(dstcell, dB ) = (EQB + (intDf[dB ]-EQB )*mDfScaleDown);\ - /*old*/ RAC(dstcell, dNE) = (EQNE + (intDf[dNE]-EQNE )*mDfScaleDown);\ - RAC(dstcell, dNW) = (EQNW + (intDf[dNW]-EQNW )*mDfScaleDown);\ - RAC(dstcell, dSE) = (EQSE + (intDf[dSE]-EQSE )*mDfScaleDown);\ - RAC(dstcell, dSW) = (EQSW + (intDf[dSW]-EQSW )*mDfScaleDown);\ - RAC(dstcell, dNT) = (EQNT + (intDf[dNT]-EQNT )*mDfScaleDown);\ - RAC(dstcell, dNB) = (EQNB + (intDf[dNB]-EQNB )*mDfScaleDown);\ - RAC(dstcell, dST) = (EQST + (intDf[dST]-EQST )*mDfScaleDown);\ - RAC(dstcell, dSB) = (EQSB + (intDf[dSB]-EQSB )*mDfScaleDown);\ - RAC(dstcell, dET) = (EQET + (intDf[dET]-EQET )*mDfScaleDown);\ - /*old*/ RAC(dstcell, dEB) = (EQEB + (intDf[dEB]-EQEB )*mDfScaleDown);\ - RAC(dstcell, dWT) = (EQWT + (intDf[dWT]-EQWT )*mDfScaleDown);\ - RAC(dstcell, dWB) = (EQWB + (intDf[dWB]-EQWB )*mDfScaleDown);\ - /* IDF_WRITEBACK optimized */ - -#if USE_LES==1 -#define IDF_WRITEBACK IDF_WRITEBACK_LES -#else -#define IDF_WRITEBACK IDF_WRITEBACK_NOLES -#endif - -#endif// OPT3D==0 - - - -/******************************************************************************/ -/*! relaxation LES functions */ -/******************************************************************************/ - - -inline LbmFloat LbmFsgrSolver::getLesNoneqTensorCoeff( - LbmFloat df[], - LbmFloat feq[] ) { - LbmFloat Qo = 0.0; - for(int m=0; m< ((LBMDIM*LBMDIM)-LBMDIM)/2 ; m++) { - LbmFloat qadd = 0.0; - for(int l=1; l<this->cDfNum; l++) { - if(this->lesCoeffOffdiag[m][l]==0.0) continue; - qadd += this->lesCoeffOffdiag[m][l]*(df[l]-feq[l]); - } - Qo += (qadd*qadd); - } - Qo *= 2.0; // off diag twice - for(int m=0; m<LBMDIM; m++) { - LbmFloat qadd = 0.0; - for(int l=1; l<this->cDfNum; l++) { - if(this->lesCoeffDiag[m][l]==0.0) continue; - qadd += this->lesCoeffDiag[m][l]*(df[l]-feq[l]); - } - Qo += (qadd*qadd); - } - Qo = sqrt(Qo); - return Qo; -}; - -inline LbmFloat LbmFsgrSolver::getLesOmega(LbmFloat omega, LbmFloat csmago, LbmFloat Qo) { - const LbmFloat tau = 1.0/omega; - const LbmFloat nu = (2.0*tau-1.0) * (1.0/6.0); - const LbmFloat C = csmago; - const LbmFloat Csqr = C*C; - LbmFloat S = -nu + sqrt( nu*nu + 18.0*Csqr*Qo ) / (6.0*Csqr); - return( 1.0/( 3.0*( nu+Csqr*S ) +0.5 ) ); -} - -#define DEBUG_CALCPRINTCELL(str,df) {\ - LbmFloat prho=df[0], pux=0., puy=0., puz=0.; \ - for(int dfl=1; dfl<this->cDfNum; dfl++) { \ - prho += df[dfl]; \ - pux += (this->dfDvecX[dfl]*df[dfl]); \ - puy += (this->dfDvecY[dfl]*df[dfl]); \ - puz += (this->dfDvecZ[dfl]*df[dfl]); \ - } \ - errMsg("DEBUG_CALCPRINTCELL",">"<<str<<" rho="<<prho<<" vel="<<ntlVec3Gfx(pux,puy,puz) ); \ - } /* END DEBUG_CALCPRINTCELL */ - -// "normal" collision -inline void LbmFsgrSolver::collideArrays( - int lev, int i, int j, int k, // position - more for debugging - LbmFloat df[], - LbmFloat &outrho, // out only! - // velocity modifiers (returns actual velocity!) - LbmFloat &mux, LbmFloat &muy, LbmFloat &muz, - LbmFloat omega, - LbmVec gravity, - LbmFloat csmago, - LbmFloat *newOmegaRet, LbmFloat *newQoRet - ) { - int l; - LbmFloat rho=df[0]; - LbmFloat ux = 0; //mux; - LbmFloat uy = 0; //muy; - LbmFloat uz = 0; //muz; - LbmFloat feq[19]; - LbmFloat omegaNew; - LbmFloat Qo = 0.0; - - for(l=1; l<this->cDfNum; l++) { - rho += df[l]; - ux += (this->dfDvecX[l]*df[l]); - uy += (this->dfDvecY[l]*df[l]); - uz += (this->dfDvecZ[l]*df[l]); - } - - - PRECOLLIDE_MODS(rho,ux,uy,uz, gravity); - for(l=0; l<this->cDfNum; l++) { - feq[l] = getCollideEq(l,rho,ux,uy,uz); - } - - if(csmago>0.0) { - Qo = getLesNoneqTensorCoeff(df,feq); - omegaNew = getLesOmega(omega,csmago,Qo); - } else { - omegaNew = omega; // smago off... - } - if(newOmegaRet) *newOmegaRet = omegaNew; // return value for stats - if(newQoRet) *newQoRet = Qo; // return value of non-eq. stress tensor - - for(l=0; l<this->cDfNum; l++) { - df[l] = (1.0-omegaNew ) * df[l] + omegaNew * feq[l]; - } - //if((i==16)&&(j==10)) DEBUG_CALCPRINTCELL( "2dcoll "<<PRINT_IJK, df); - - mux = ux; - muy = uy; - muz = uz; - outrho = rho; - - lev=i=j=k; // debug, remove warnings -}; - diff --git a/intern/elbeem/intern/solver_util.cpp b/intern/elbeem/intern/solver_util.cpp deleted file mode 100644 index ca98e26e875..00000000000 --- a/intern/elbeem/intern/solver_util.cpp +++ /dev/null @@ -1,1753 +0,0 @@ -/** \file - * \ingroup elbeem - */ -/****************************************************************************** - * - * El'Beem - Free Surface Fluid Simulation with the Lattice Boltzmann Method - * Copyright 2003-2006 Nils Thuerey - * - * Standard LBM Factory implementation - * - *****************************************************************************/ - -#include "solver_class.h" -#include "solver_relax.h" -#include "particletracer.h" - -// MPT -#include "ntl_world.h" -#include "simulation_object.h" - -#include "globals.h" - -#include <stdlib.h> -#include <zlib.h> -#ifndef sqrtf -#define sqrtf sqrt -#endif - -/****************************************************************************** - * helper functions - *****************************************************************************/ - -// try to enhance surface? -#define SURFACE_ENH 2 - -//! for raytracing -void LbmFsgrSolver::prepareVisualization( void ) { - int lev = mMaxRefine; - int workSet = mLevel[lev].setCurr; - - int mainGravDir=6; // if normalizing fails, we asume z-direction gravity - LbmFloat mainGravLen = 0.; - FORDF1{ - LbmFloat thisGravLen = dot(LbmVec(dfVecX[l],dfVecY[l],dfVecZ[l]), mLevel[mMaxRefine].gravity ); - if(thisGravLen>mainGravLen) { - mainGravLen = thisGravLen; - mainGravDir = l; - } - } - -#if LBMDIM==2 - // 2d, place in the middle of isofield slice (k=2) -# define ZKD1 0 - // 2d z offset = 2, lbmGetData adds 1, so use one here -# define ZKOFF 1 - // reset all values... - for(int k= 0; k< 5; ++k) - for(int j=0;j<mLevel[lev].lSizey-0;j++) - for(int i=0;i<mLevel[lev].lSizex-0;i++) { - *mpIso->lbmGetData(i,j,ZKOFF)=0.0; - } -#else // LBMDIM==2 - // 3d, use normal bounds -# define ZKD1 1 -# define ZKOFF k - // reset all values... - for(int k= getForZMinBnd(); k< getForZMaxBnd(lev); ++k) - for(int j=0;j<mLevel[lev].lSizey-0;j++) - for(int i=0;i<mLevel[lev].lSizex-0;i++) { - *mpIso->lbmGetData(i,j,ZKOFF)=0.0; - } -#endif // LBMDIM==2 - - // MPT, ignore - if((glob_mpactive) && (glob_mpnum>1) && (glob_mpindex==0)) { - mpIso->resetAll(0.); - } - - - LbmFloat minval = mIsoValue*1.05; // / mIsoWeight[13]; - // add up... - float val = 0.0; - for(int k= getForZMin1(); k< getForZMax1(lev); ++k) - for(int j=1;j<mLevel[lev].lSizey-1;j++) - for(int i=1;i<mLevel[lev].lSizex-1;i++) { - const CellFlagType cflag = RFLAG(lev, i,j,k,workSet); - //if(cflag&(CFBnd|CFEmpty)) { - -#if SURFACE_ENH==0 - - // no enhancements... - if( (cflag&(CFFluid|CFUnused)) ) { - val = 1.; - } else if( (cflag&CFInter) ) { - val = (QCELL(lev, i,j,k,workSet, dFfrac)); - } else { - continue; - } - -#else // SURFACE_ENH!=1 - if(cflag&CFBnd) { - // treated in second loop - continue; - } else if(cflag&CFUnused) { - val = 1.; - } else if( (cflag&CFFluid) && (cflag&CFNoBndFluid)) { - // optimized fluid - val = 1.; - } else if( (cflag&(CFEmpty|CFInter|CFFluid)) ) { - int noslipbnd = 0; - int intercnt = 0; - FORDF1 { - const CellFlagType nbflag = RFLAG_NB(lev, i,j,k, workSet,l); - if(nbflag&CFInter){ intercnt++; } - - // check all directions otherwise we get bugs with splashes on obstacles - if(l!=mainGravDir) continue; // only check bnd along main grav. dir - //if((nbflag&CFBnd)&&(nbflag&CFBndNoslip)){ noslipbnd=1; } - if((nbflag&CFBnd)){ noslipbnd=1; } - } - - if(cflag&CFEmpty) { - // special empty treatment - if((noslipbnd)&&(intercnt>6)) { - *mpIso->lbmGetData(i,j,ZKOFF) += minval; - } else if((noslipbnd)&&(intercnt>0)) { - // necessary? - *mpIso->lbmGetData(i,j,ZKOFF) += mIsoValue*0.9; - } else { - // nothing to do... - } - - continue; - } else if(cflag&(CFNoNbEmpty|CFFluid)) { - // no empty nb interface cells are treated as full - val=1.0; - } else { - val = (QCELL(lev, i,j,k,workSet, dFfrac)); - } - - if(noslipbnd) { - if(val<minval) val = minval; - *mpIso->lbmGetData(i,j,ZKOFF) += minval-( val * mIsoWeight[13] ); - } - } else { // all others, unused? - continue; - } -#endif // SURFACE_ENH>0 - - *mpIso->lbmGetData( i-1 , j-1 ,ZKOFF-ZKD1) += ( val * mIsoWeight[0] ); - *mpIso->lbmGetData( i , j-1 ,ZKOFF-ZKD1) += ( val * mIsoWeight[1] ); - *mpIso->lbmGetData( i+1 , j-1 ,ZKOFF-ZKD1) += ( val * mIsoWeight[2] ); - - *mpIso->lbmGetData( i-1 , j ,ZKOFF-ZKD1) += ( val * mIsoWeight[3] ); - *mpIso->lbmGetData( i , j ,ZKOFF-ZKD1) += ( val * mIsoWeight[4] ); - *mpIso->lbmGetData( i+1 , j ,ZKOFF-ZKD1) += ( val * mIsoWeight[5] ); - - *mpIso->lbmGetData( i-1 , j+1 ,ZKOFF-ZKD1) += ( val * mIsoWeight[6] ); - *mpIso->lbmGetData( i , j+1 ,ZKOFF-ZKD1) += ( val * mIsoWeight[7] ); - *mpIso->lbmGetData( i+1 , j+1 ,ZKOFF-ZKD1) += ( val * mIsoWeight[8] ); - - - *mpIso->lbmGetData( i-1 , j-1 ,ZKOFF ) += ( val * mIsoWeight[9] ); - *mpIso->lbmGetData( i , j-1 ,ZKOFF ) += ( val * mIsoWeight[10] ); - *mpIso->lbmGetData( i+1 , j-1 ,ZKOFF ) += ( val * mIsoWeight[11] ); - - *mpIso->lbmGetData( i-1 , j ,ZKOFF ) += ( val * mIsoWeight[12] ); - *mpIso->lbmGetData( i , j ,ZKOFF ) += ( val * mIsoWeight[13] ); - *mpIso->lbmGetData( i+1 , j ,ZKOFF ) += ( val * mIsoWeight[14] ); - - *mpIso->lbmGetData( i-1 , j+1 ,ZKOFF ) += ( val * mIsoWeight[15] ); - *mpIso->lbmGetData( i , j+1 ,ZKOFF ) += ( val * mIsoWeight[16] ); - *mpIso->lbmGetData( i+1 , j+1 ,ZKOFF ) += ( val * mIsoWeight[17] ); - - - *mpIso->lbmGetData( i-1 , j-1 ,ZKOFF+ZKD1) += ( val * mIsoWeight[18] ); - *mpIso->lbmGetData( i , j-1 ,ZKOFF+ZKD1) += ( val * mIsoWeight[19] ); - *mpIso->lbmGetData( i+1 , j-1 ,ZKOFF+ZKD1) += ( val * mIsoWeight[20] ); - - *mpIso->lbmGetData( i-1 , j ,ZKOFF+ZKD1) += ( val * mIsoWeight[21] ); - *mpIso->lbmGetData( i , j ,ZKOFF+ZKD1)+= ( val * mIsoWeight[22] ); - *mpIso->lbmGetData( i+1 , j ,ZKOFF+ZKD1) += ( val * mIsoWeight[23] ); - - *mpIso->lbmGetData( i-1 , j+1 ,ZKOFF+ZKD1) += ( val * mIsoWeight[24] ); - *mpIso->lbmGetData( i , j+1 ,ZKOFF+ZKD1) += ( val * mIsoWeight[25] ); - *mpIso->lbmGetData( i+1 , j+1 ,ZKOFF+ZKD1) += ( val * mIsoWeight[26] ); - } - - // TEST!? -#if SURFACE_ENH>=2 - - if(mFsSurfGenSetting&fssgNoObs) { - for(int k= getForZMin1(); k< getForZMax1(lev); ++k) - for(int j=1;j<mLevel[lev].lSizey-1;j++) - for(int i=1;i<mLevel[lev].lSizex-1;i++) { - const CellFlagType cflag = RFLAG(lev, i,j,k,workSet); - if(cflag&(CFBnd)) { - CellFlagType nbored=0; - LbmFloat avgfill=0.,avgfcnt=0.; - FORDF1 { - const int ni = i+dfVecX[l]; - const int nj = j+dfVecY[l]; - const int nk = ZKOFF+dfVecZ[l]; - - const CellFlagType nbflag = RFLAG(lev, ni,nj,nk, workSet); - nbored |= nbflag; - if(nbflag&CFInter) { - avgfill += QCELL(lev, ni,nj,nk, workSet,dFfrac); avgfcnt += 1.; - } else if(nbflag&CFFluid) { - avgfill += 1.; avgfcnt += 1.; - } else if(nbflag&CFEmpty) { - avgfill += 0.; avgfcnt += 1.; - } - - //if( (ni<0) || (nj<0) || (nk<0) - //|| (ni>=mLevel[mMaxRefine].lSizex) - //|| (nj>=mLevel[mMaxRefine].lSizey) - //|| (nk>=mLevel[mMaxRefine].lSizez) ) continue; - } - - if(nbored&CFInter) { - if(avgfcnt>0.) avgfill/=avgfcnt; - *mpIso->lbmGetData(i,j,ZKOFF) = avgfill; continue; - } - else if(nbored&CFFluid) { - *mpIso->lbmGetData(i,j,ZKOFF) = 1.; continue; - } - - } - } - - // move surface towards inner "row" of obstacle - // cells if necessary (all obs cells without fluid/inter - // nbs (=iso==0) next to obstacles...) - for(int k= getForZMin1(); k< getForZMax1(lev); ++k) - for(int j=1;j<mLevel[lev].lSizey-1;j++) - for(int i=1;i<mLevel[lev].lSizex-1;i++) { - const CellFlagType cflag = RFLAG(lev, i,j,k,workSet); - if( (cflag&(CFBnd)) && (*mpIso->lbmGetData(i,j,ZKOFF)==0.)) { - int bndnbcnt=0; - FORDF1 { - const int ni = i+dfVecX[l]; - const int nj = j+dfVecY[l]; - const int nk = ZKOFF+dfVecZ[l]; - const CellFlagType nbflag = RFLAG(lev, ni,nj,nk, workSet); - if(nbflag&CFBnd) bndnbcnt++; - } - if(bndnbcnt>0) *mpIso->lbmGetData(i,j,ZKOFF)=mIsoValue*0.95; - } - } - } - // */ - - if(mFsSurfGenSetting&fssgNoNorth) - for(int k= getForZMinBnd(); k< getForZMaxBnd(lev); ++k) - for(int j=0;j<mLevel[lev].lSizey-0;j++) { - *mpIso->lbmGetData(0, j,ZKOFF) = *mpIso->lbmGetData(1, j,ZKOFF); - } - if(mFsSurfGenSetting&fssgNoEast) - for(int k= getForZMinBnd(); k< getForZMaxBnd(lev); ++k) - for(int i=0;i<mLevel[lev].lSizex-0;i++) { - *mpIso->lbmGetData(i,0, ZKOFF) = *mpIso->lbmGetData(i,1, ZKOFF); - } - if(mFsSurfGenSetting&fssgNoSouth) - for(int k= getForZMinBnd(); k< getForZMaxBnd(lev); ++k) - for(int j=0;j<mLevel[lev].lSizey-0;j++) { - *mpIso->lbmGetData(mLevel[lev].lSizex-1,j,ZKOFF) = *mpIso->lbmGetData(mLevel[lev].lSizex-2,j,ZKOFF); - } - if(mFsSurfGenSetting&fssgNoWest) - for(int k= getForZMinBnd(); k< getForZMaxBnd(lev); ++k) - for(int i=0;i<mLevel[lev].lSizex-0;i++) { - *mpIso->lbmGetData(i,mLevel[lev].lSizey-1,ZKOFF) = *mpIso->lbmGetData(i,mLevel[lev].lSizey-2,ZKOFF); - } - if(LBMDIM>2) { - if(mFsSurfGenSetting&fssgNoBottom) - for(int j=0;j<mLevel[lev].lSizey-0;j++) - for(int i=0;i<mLevel[lev].lSizex-0;i++) { - *mpIso->lbmGetData(i,j,0 ) = *mpIso->lbmGetData(i,j,1 ); - } - if(mFsSurfGenSetting&fssgNoTop) - for(int j=0;j<mLevel[lev].lSizey-0;j++) - for(int i=0;i<mLevel[lev].lSizex-0;i++) { - *mpIso->lbmGetData(i,j,mLevel[lev].lSizez-1) = *mpIso->lbmGetData(i,j,mLevel[lev].lSizez-2); - } - } -#endif // SURFACE_ENH>=2 - - - // update preview, remove 2d? - if((mOutputSurfacePreview)&&(LBMDIM==3)) { - int pvsx = (int)(mPreviewFactor*mSizex); - int pvsy = (int)(mPreviewFactor*mSizey); - int pvsz = (int)(mPreviewFactor*mSizez); - //float scale = (float)mSizex / previewSize; - LbmFloat scalex = (LbmFloat)mSizex/(LbmFloat)pvsx; - LbmFloat scaley = (LbmFloat)mSizey/(LbmFloat)pvsy; - LbmFloat scalez = (LbmFloat)mSizez/(LbmFloat)pvsz; - for(int k= 0; k< (pvsz-1); ++k) - for(int j=0;j< pvsy;j++) - for(int i=0;i< pvsx;i++) { - *mpPreviewSurface->lbmGetData(i,j,k) = *mpIso->lbmGetData( (int)(i*scalex), (int)(j*scaley), (int)(k*scalez) ); - } - // set borders again... - for(int k= 0; k< (pvsz-1); ++k) { - for(int j=0;j< pvsy;j++) { - *mpPreviewSurface->lbmGetData(0,j,k) = *mpIso->lbmGetData( 0, (int)(j*scaley), (int)(k*scalez) ); - *mpPreviewSurface->lbmGetData(pvsx-1,j,k) = *mpIso->lbmGetData( mSizex-1, (int)(j*scaley), (int)(k*scalez) ); - } - for(int i=0;i< pvsx;i++) { - *mpPreviewSurface->lbmGetData(i,0,k) = *mpIso->lbmGetData( (int)(i*scalex), 0, (int)(k*scalez) ); - *mpPreviewSurface->lbmGetData(i,pvsy-1,k) = *mpIso->lbmGetData( (int)(i*scalex), mSizey-1, (int)(k*scalez) ); - } - } - for(int j=0;j<pvsy;j++) - for(int i=0;i<pvsx;i++) { - *mpPreviewSurface->lbmGetData(i,j,0) = *mpIso->lbmGetData( (int)(i*scalex), (int)(j*scaley) , 0); - *mpPreviewSurface->lbmGetData(i,j,pvsz-1) = *mpIso->lbmGetData( (int)(i*scalex), (int)(j*scaley) , mSizez-1); - } - - if(mFarFieldSize>=1.2) { - // also remove preview border - for(int k= 0; k< (pvsz-1); ++k) { - for(int j=0;j< pvsy;j++) { - *mpPreviewSurface->lbmGetData(0,j,k) = - *mpPreviewSurface->lbmGetData(1,j,k) = - *mpPreviewSurface->lbmGetData(2,j,k); - *mpPreviewSurface->lbmGetData(pvsx-1,j,k) = - *mpPreviewSurface->lbmGetData(pvsx-2,j,k) = - *mpPreviewSurface->lbmGetData(pvsx-3,j,k); - //0.0; - } - for(int i=0;i< pvsx;i++) { - *mpPreviewSurface->lbmGetData(i,0,k) = - *mpPreviewSurface->lbmGetData(i,1,k) = - *mpPreviewSurface->lbmGetData(i,2,k); - *mpPreviewSurface->lbmGetData(i,pvsy-1,k) = - *mpPreviewSurface->lbmGetData(i,pvsy-2,k) = - *mpPreviewSurface->lbmGetData(i,pvsy-3,k); - //0.0; - } - } - for(int j=0;j<pvsy;j++) - for(int i=0;i<pvsx;i++) { - *mpPreviewSurface->lbmGetData(i,j,0) = - *mpPreviewSurface->lbmGetData(i,j,1) = - *mpPreviewSurface->lbmGetData(i,j,2); - *mpPreviewSurface->lbmGetData(i,j,pvsz-1) = - *mpPreviewSurface->lbmGetData(i,j,pvsz-2) = - *mpPreviewSurface->lbmGetData(i,j,pvsz-3); - //0.0; - } - } - } - - // MPT - #if LBM_INCLUDE_TESTSOLVERS==1 - mrIsoExchange(); - #endif // LBM_INCLUDE_TESTSOLVERS==1 - - return; -} - -/*! calculate speeds of fluid objects (or inflow) */ -void LbmFsgrSolver::recalculateObjectSpeeds() { - const bool debugRecalc = false; - int numobjs = (int)(this->mpGiObjects->size()); - // note - (numobjs + 1) is entry for domain settings - - if(debugRecalc) errMsg("recalculateObjectSpeeds","start, #obj:"<<numobjs); - if(numobjs>255-1) { - errFatal("LbmFsgrSolver::recalculateObjectSpeeds","More than 256 objects currently not supported...",SIMWORLD_INITERROR); - return; - } - mObjectSpeeds.resize(numobjs+1); - for(int i=0; i<(int)(numobjs+0); i++) { - mObjectSpeeds[i] = vec2L(this->mpParam->calculateLattVelocityFromRw( vec2P( (*this->mpGiObjects)[i]->getInitialVelocity(mSimulationTime) ))); - if(debugRecalc) errMsg("recalculateObjectSpeeds","id"<<i<<" set to "<< mObjectSpeeds[i]<<", unscaled:"<< (*this->mpGiObjects)[i]->getInitialVelocity(mSimulationTime) ); - } - - // also reinit part slip values here - mObjectPartslips.resize(numobjs+1); - for(int i=0; i<=(int)(numobjs+0); i++) { - if(i<numobjs) { - mObjectPartslips[i] = (LbmFloat)(*this->mpGiObjects)[i]->getGeoPartSlipValue(); - } else { - // domain setting - mObjectPartslips[i] = this->mDomainPartSlipValue; - } - LbmFloat set = mObjectPartslips[i]; - - // as in setInfluenceVelocity - const LbmFloat dt = mLevel[mMaxRefine].timestep; - const LbmFloat dtInter = 0.01; - //LbmFloat facFv = 1.-set; - // mLevel[mMaxRefine].timestep - LbmFloat facNv = (LbmFloat)( 1.-pow( (double)(set), (double)(dt/dtInter)) ); - errMsg("mObjectPartslips","id:"<<i<<"/"<<numobjs<<" ts:"<<dt<< " its:"<<(dt/dtInter) <<" set"<<set<<" nv"<<facNv<<" test:"<< - pow( (double)(1.-facNv),(double)(dtInter/dt)) ); - mObjectPartslips[i] = facNv; - - if(debugRecalc) errMsg("recalculateObjectSpeeds","id"<<i<<" parts "<< mObjectPartslips[i] ); - } - - if(debugRecalc) errMsg("recalculateObjectSpeeds","done, domain:"<<mObjectPartslips[numobjs]<<" n"<<numobjs); -} - - - -/*****************************************************************************/ -/*! debug object display */ -/*****************************************************************************/ -vector<ntlGeometryObject*> LbmFsgrSolver::getDebugObjects() { - vector<ntlGeometryObject*> debo; - if(this->mOutputSurfacePreview) { - debo.push_back( mpPreviewSurface ); - } -#if LBM_INCLUDE_TESTSOLVERS==1 - if(mUseTestdata) { - vector<ntlGeometryObject*> tdebo; - tdebo = mpTest->getDebugObjects(); - for(size_t i=0; i<tdebo.size(); i++) debo.push_back( tdebo[i] ); - } -#endif // ELBEEM_PLUGIN - return debo; -} - -/****************************************************************************** - * particle handling - *****************************************************************************/ - -/*! init particle positions */ -int LbmFsgrSolver::initParticles() { - int workSet = mLevel[mMaxRefine].setCurr; - int tries = 0; - int num = 0; - ParticleTracer *partt = mpParticles; - - partt->setStart( this->mvGeoStart + ntlVec3Gfx(mLevel[mMaxRefine].nodeSize*0.5) ); - partt->setEnd ( this->mvGeoEnd + ntlVec3Gfx(mLevel[mMaxRefine].nodeSize*0.5) ); - - partt->setSimStart( ntlVec3Gfx(0.0) ); - partt->setSimEnd ( ntlVec3Gfx(mSizex, mSizey, getForZMaxBnd(mMaxRefine)) ); - - while( (num<partt->getNumInitialParticles()) && (tries<100*partt->getNumInitialParticles()) ) { - LbmFloat x,y,z,t; - x = 1.0+(( (LbmFloat)(mSizex-3.) ) * (rand()/(RAND_MAX+1.0)) ); - y = 1.0+(( (LbmFloat)(mSizey-3.) ) * (rand()/(RAND_MAX+1.0)) ); - z = 1.0+(( (LbmFloat) getForZMax1(mMaxRefine)-2. )* (rand()/(RAND_MAX+1.0)) ); - int i = (int)(x+0.5); - int j = (int)(y+0.5); - int k = (int)(z+0.5); - if(LBMDIM==2) { - k = 0; z = 0.5; // place in the middle of domain - } - - //if( RFLAG(mMaxRefine, i,j,k, workSet)& (CFFluid) ) - //&& ( RFLAG(mMaxRefine, i,j,k, workSet)& CFNoNbFluid ) - //if( RFLAG(mMaxRefine, i,j,k, workSet) & (CFFluid|CFInter|CFMbndInflow) ) { - if( RFLAG(mMaxRefine, i,j,k, workSet) & (CFNoBndFluid|CFUnused) ) { - bool cellOk = true; - //? FORDF1 { if(!(RFLAG_NB(mMaxRefine,i,j,k,workSet, l) & CFFluid)) cellOk = false; } - if(!cellOk) continue; - // in fluid... - partt->addParticle(x,y,z); - partt->getLast()->setStatus(PART_IN); - partt->getLast()->setType(PART_TRACER); - - partt->getLast()->setSize(1.); - // randomize size - partt->getLast()->setSize(0.5 + (rand()/(RAND_MAX+1.0))); - - if( ( partt->getInitStart()>0.) - && ( partt->getInitEnd()>0.) - && ( partt->getInitEnd()>partt->getInitStart() )) { - t = partt->getInitStart()+ (partt->getInitEnd()-partt->getInitStart())*(rand()/(RAND_MAX+1.0)); - partt->getLast()->setLifeTime( -t ); - } - num++; - } - tries++; - } // */ - - /*FSGR_FORIJK1(mMaxRefine) { - if( (RFLAG(mMaxRefine,i,j,k, workSet) & (CFNoBndFluid)) ) { - LbmFloat rndn = (rand()/(RAND_MAX+1.0)); - if(rndn>0.0) { - ntlVec3Gfx pos( (LbmFloat)(i)-0.5, (LbmFloat)(j)-0.5, (LbmFloat)(k)-0.5 ); - if(LBMDIM==2) { pos[2]=0.5; } - partt->addParticle( pos[0],pos[1],pos[2] ); - partt->getLast()->setStatus(PART_IN); - partt->getLast()->setType(PART_TRACER); - partt->getLast()->setSize(1.0); - } - } - } // */ - - - // DEBUG TEST -#if LBM_INCLUDE_TESTSOLVERS==1 - if(mUseTestdata) { - const bool partDebug=false; - if(mpTest->mPartTestcase==0){ errMsg("LbmTestdata"," part init "<<mpTest->mPartTestcase); } - if(mpTest->mPartTestcase==-12){ - const int lev = mMaxRefine; - for(int i=5;i<15;i++) { - LbmFloat x,y,z; - y = 0.5+(LbmFloat)(i); - x = mLevel[lev].lSizex/20.0*10.0; - z = mLevel[lev].lSizez/20.0*2.0; - partt->addParticle(x,y,z); - partt->getLast()->setStatus(PART_IN); - partt->getLast()->setType(PART_BUBBLE); - partt->getLast()->setSize( (-4.0+(LbmFloat)i)/1.0 ); - if(partDebug) errMsg("PARTTT","SET "<<PRINT_VEC(x,y,z)<<" p"<<partt->getLast()->getPos() <<" s"<<partt->getLast()->getSize() ); - } - } - if(mpTest->mPartTestcase==-11){ - const int lev = mMaxRefine; - for(int i=5;i<15;i++) { - LbmFloat x,y,z; - y = 10.5+(LbmFloat)(i); - x = mLevel[lev].lSizex/20.0*10.0; - z = mLevel[lev].lSizez/20.0*40.0; - partt->addParticle(x,y,z); - partt->getLast()->setStatus(PART_IN); - partt->getLast()->setType(PART_DROP); - partt->getLast()->setSize( (-4.0+(LbmFloat)i)/1.0 ); - if(partDebug) errMsg("PARTTT","SET "<<PRINT_VEC(x,y,z)<<" p"<<partt->getLast()->getPos() <<" s"<<partt->getLast()->getSize() ); - } - } - // place floats on rectangular region FLOAT_JITTER_BND - if(mpTest->mPartTestcase==-10){ - const int lev = mMaxRefine; - const int sx = mLevel[lev].lSizex; - const int sy = mLevel[lev].lSizey; - //for(int j=-(int)(sy*0.25);j<-(int)(sy*0.25)+2;++j) { for(int i=-(int)(sx*0.25);i<-(int)(sy*0.25)+2;++i) { - //for(int j=-(int)(sy*1.25);j<(int)(2.25*sy);++j) { for(int i=-(int)(sx*1.25);i<(int)(2.25*sx);++i) { - for(int j=-(int)(sy*0.3);j<(int)(1.3*sy);++j) { for(int i=-(int)(sx*0.3);i<(int)(1.3*sx);++i) { - //for(int j=-(int)(sy*0.2);j<(int)(0.2*sy);++j) { for(int i= (int)(sx*0.5);i<= (int)(0.51*sx);++i) { - LbmFloat x,y,z; - x = 0.0+(LbmFloat)(i); - y = 0.0+(LbmFloat)(j); - //z = mLevel[lev].lSizez/10.0*2.5 - 1.0; - z = mLevel[lev].lSizez/20.0*9.5 - 1.0; - //z = mLevel[lev].lSizez/20.0*4.5 - 1.0; - partt->addParticle(x,y,z); - //if( (i>0)&&(i<sx) && (j>0)&&(j<sy) ) { partt->getLast()->setStatus(PART_IN); } else { partt->getLast()->setStatus(PART_OUT); } - partt->getLast()->setStatus(PART_IN); - partt->getLast()->setType(PART_FLOAT); - partt->getLast()->setSize( 15.0 ); - if(partDebug) errMsg("PARTTT","SET "<<PRINT_VEC(x,y,z)<<" p"<<partt->getLast()->getPos() <<" s"<<partt->getLast()->getSize() ); - } - } } - } - // DEBUG TEST -#endif // LBM_INCLUDE_TESTSOLVERS - - - debMsgStd("LbmFsgrSolver::initParticles",DM_MSG,"Added "<<num<<" particles, genProb:"<<this->mPartGenProb<<", tries:"<<tries, 10); - if(num != partt->getNumParticles()) return 1; - - return 0; -} - -// helper function for particle debugging -/*static string getParticleStatusString(int state) { - std::ostringstream out; - if(state&PART_DROP) out << "dropp "; - if(state&PART_TRACER) out << "tracr "; - if(state&PART_BUBBLE) out << "bubbl "; - if(state&PART_FLOAT) out << "float "; - if(state&PART_INTER) out << "inter "; - - if(state&PART_IN) out << "inn "; - if(state&PART_OUT) out << "out "; - if(state&PART_INACTIVE) out << "INACT "; - if(state&PART_OUTFLUID) out << "outfluid "; - return out.str(); -} // */ - -#define P_CHANGETYPE(p, newtype) \ - p->setLifeTime(0.); \ - /* errMsg("PIT","U pit"<<(p)->getId()<<" pos:"<< (p)->getPos()<<" status:"<<convertFlags2String((p)->getFlags())<<" to "<< (newtype) ); */ \ - p->setType(newtype); - -// tracer defines -#define TRACE_JITTER 0.025 -#define TRACE_RAND (rand()/(RAND_MAX+1.0))*TRACE_JITTER-(TRACE_JITTER*0.5) -#define FFGET_NORM(var,dl) \ - if(RFLAG_NB(lev,i,j,k,workSet, dl) &(CFInter)){ (var) = QCELL_NB(lev,i,j,k,workSet,dl,dFfrac); } \ - else if(RFLAG_NB(lev,i,j,k,workSet, dl) &(CFFluid|CFUnused)){ (var) = 1.; } else (var) = 0.0; - -// float jitter -#define FLOAT_JITTER_BND (FLOAT_JITTER*2.0) -#define FLOAT_JITTBNDRAND(x) ((rand()/(RAND_MAX+1.0))*FLOAT_JITTER_BND*(1.-(x/(LbmFloat)maxdw))-(FLOAT_JITTER_BND*(1.-(x)/(LbmFloat)maxdw)*0.5)) - -#define DEL_PART { \ - /*errMsg("PIT","DEL AT "<< __LINE__<<" type:"<<p->getType()<<" "); */ \ - p->setActive( false ); \ - continue; } - -void LbmFsgrSolver::advanceParticles() { - const int level = mMaxRefine; - const int workSet = mLevel[level].setCurr; - LbmFloat vx=0.0,vy=0.0,vz=0.0; - //int debugOutCounter=0; // debug output counter - - myTime_t parttstart = getTime(); - const LbmFloat cellsize = this->mpParam->getCellSize(); - const LbmFloat timestep = this->mpParam->getTimestep(); - //const LbmFloat viscAir = 1.79 * 1e-5; // RW2L kin. viscosity, mu - //const LbmFloat viscWater = 1.0 * 1e-6; // RW2L kin. viscosity, mu - const LbmFloat rhoAir = 1.2; // [kg m^-3] RW2L - const LbmFloat rhoWater = 1000.0; // RW2L - const LbmFloat minDropSize = 0.0005; // [m], = 2mm RW2L - const LbmVec velAir(0.); // [m / s] - - const LbmFloat r1 = 0.005; // r max - const LbmFloat r2 = 0.0005; // r min - const LbmFloat v1 = 9.0; // v max - const LbmFloat v2 = 2.0; // v min - const LbmVec rwgrav = vec2L( this->mpParam->getGravity(mSimulationTime) ); - const bool useff = (mFarFieldSize>1.2); // if(mpTest->mFarfMode>0){ - - // TODO scale bubble/part damping dep. on timestep, also drop bnd rev damping - const int cutval = mCutoff; // use full border!? - if(this->mStepCnt%50==49) { mpParticles->cleanup(); } - for(vector<ParticleObject>::iterator pit= mpParticles->getParticlesBegin(); - pit!= mpParticles->getParticlesEnd(); pit++) { - //if((*pit).getPos()[2]>10.) errMsg("PIT"," pit"<<(*pit).getId()<<" pos:"<< (*pit).getPos()<<" status:["<<getParticleStatusString((*pit).getFlags())<<"] vel:"<< (*pit).getVel() ); - if( (*pit).getActive()==false ) continue; - // skip until reached - ParticleObject *p = &(*pit); - if(p->getLifeTime()<0.){ - if(p->getLifeTime() < -mSimulationTime) continue; - else p->setLifeTime(-mLevel[level].timestep); // zero for following update - } - int i,j,k; - p->setLifeTime(p->getLifeTime()+mLevel[level].timestep); - - // nearest neighbor, particle positions don't include empty bounds - ntlVec3Gfx pos = p->getPos(); - i= (int)pos[0]; j= (int)pos[1]; k= (int)pos[2];// no offset necessary - if(LBMDIM==2) { k = 0; } - - // only testdata handling, all for sws -#if LBM_INCLUDE_TESTSOLVERS==1 - if(useff && (mpTest->mFarfMode>0)) { - p->setStatus(PART_OUT); - mpTest->handleParticle(p, i,j,k); continue; - } -#endif // LBM_INCLUDE_TESTSOLVERS==1 - - // in out tests - if(p->getStatus()&PART_IN) { // IN - if( (i<cutval)||(i>mSizex-1-cutval)|| - (j<cutval)||(j>mSizey-1-cutval) - //||(k<cutval)||(k>mSizez-1-cutval) - ) { - if(!useff) { DEL_PART; - } else { - p->setStatus(PART_OUT); - } - } - } else { // OUT rough check - // check in again? - if( (i>=cutval)&&(i<=mSizex-1-cutval)&& - (j>=cutval)&&(j<=mSizey-1-cutval) - ) { - p->setStatus(PART_IN); - } - } - - if( (p->getType()==PART_BUBBLE) || - (p->getType()==PART_TRACER) ) { - - // no interpol - vx = vy = vz = 0.0; - if(p->getStatus()&PART_IN) { // IN - if(k>=cutval) { - if(k>mSizez-1-cutval) DEL_PART; - - if( RFLAG(level, i,j,k, workSet)&(CFFluid|CFUnused) ) { - // still ok - int partLev = level; - int si=i, sj=j, sk=k; - while(partLev>0 && RFLAG(partLev, si,sj,sk, workSet)&(CFUnused)) { - partLev--; - si/=2; - sj/=2; - sk/=2; - } - // get velocity from fluid cell - if( RFLAG(partLev, si,sj,sk, workSet)&(CFFluid) ) { - LbmFloat *ccel = RACPNT(partLev, si,sj,sk, workSet); - FORDF1{ - LbmFloat cdf = RAC(ccel, l); - // TODO update below - vx += (this->dfDvecX[l]*cdf); - vy += (this->dfDvecY[l]*cdf); - vz += (this->dfDvecZ[l]*cdf); - } - // remove gravity influence - const LbmFloat lesomega = mLevel[level].omega; // no les - vx -= mLevel[level].gravity[0] * lesomega*0.5; - vy -= mLevel[level].gravity[1] * lesomega*0.5; - vz -= mLevel[level].gravity[2] * lesomega*0.5; - } // fluid vel - - } else { // OUT - // out of bounds, deactivate... - // FIXME make fsgr treatment - if(p->getType()==PART_BUBBLE) { P_CHANGETYPE(p, PART_FLOAT ); continue; } - } - } else { - // below 3d region, just rise - } - } else { // OUT -# if LBM_INCLUDE_TESTSOLVERS==1 - if(useff) { mpTest->handleParticle(p, i,j,k); } - else DEL_PART; -# else // LBM_INCLUDE_TESTSOLVERS==1 - DEL_PART; -# endif // LBM_INCLUDE_TESTSOLVERS==1 - // TODO use x,y vel...? - } - - ntlVec3Gfx v = p->getVel(); // dampen... - if( (useff)&& (p->getType()==PART_BUBBLE) ) { - // test rise - - if(mPartUsePhysModel) { - LbmFloat radius = p->getSize() * minDropSize; - //LbmVec velPart = vec2L(p->getVel()) *cellsize/timestep; // L2RW, lattice velocity - //LbmVec velWater = LbmVec(vx,vy,vz) *cellsize/timestep;// L2RW, fluid velocity - //LbmVec velRel = velWater - velPart; - //LbmFloat velRelNorm = norm(velRel); - //LbmFloat pvolume = rhoAir * 4.0/3.0 * M_PI* radius*radius*radius; // volume: 4/3 pi r^3 - - //LbmVec fb = -rwgrav* pvolume *rhoWater; - //LbmVec fd = velRel*6.0*M_PI*radius* (1e-3); //viscWater; - //LbmVec change = (fb+fd) *10.0*timestep *(timestep/cellsize); - /*if(debugOutCounter<0) { - errMsg("PIT","BTEST1 vol="<<pvolume<<" radius="<<radius<<" vn="<<velRelNorm<<" velPart="<<velPart<<" velRel"<<velRel); - errMsg("PIT","BTEST2 cellsize="<<cellsize<<" timestep="<<timestep<<" viscW="<<viscWater<<" ss/mb="<<(timestep/(pvolume*rhoAir))); - errMsg("PIT","BTEST2 grav="<<rwgrav<<" " ); - errMsg("PIT","BTEST2 change="<<(change)<<" fb="<<(fb)<<" fd="<<(fd)<<" "); - errMsg("PIT","BTEST2 change="<<norm(change)<<" fb="<<norm(fb)<<" fd="<<norm(fd)<<" "); - } // DEBUG */ - - LbmVec fd2 = (LbmVec(vx,vy,vz)-vec2L(p->getVel())) * 6.0*M_PI*radius* (1e-3); //viscWater; - LbmFloat w = 0.99; - vz = (1.0-w)*vz + w*(p->getVel()[2]-0.5*(p->getSize()/5.0)*mLevel[level].gravity[2]); - v = ntlVec3Gfx(vx,vy,vz)+vec2G(fd2); - p->setVel( v ); - } else { - // non phys, half old, half fluid, use slightly slower acc - v = v*0.5 + ntlVec3Gfx(vx,vy,vz)* 0.5-vec2G(mLevel[level].gravity)*0.5; - p->setVel( v * 0.99 ); - } - p->advanceVel(); - - } else if(p->getType()==PART_TRACER) { - v = ntlVec3Gfx(vx,vy,vz); - CellFlagType fflag = RFLAG(level, i,j,k, workSet); - - if(fflag&(CFFluid|CFInter) ) { p->setInFluid(true); - } else { p->setInFluid(false); } - - if( (( fflag&CFFluid ) && ( fflag&CFNoBndFluid )) || - (( fflag&CFInter ) && (!(fflag&CFNoNbFluid)) ) ) { - // only real fluid -# if LBMDIM==3 - p->advance( TRACE_RAND,TRACE_RAND,TRACE_RAND); -# else - p->advance( TRACE_RAND,TRACE_RAND, 0.); -# endif - - } else { - // move inwards along normal, make sure normal is valid first - // todo use class funcs! - const int lev = level; - LbmFloat nx=0.,ny=0.,nz=0., nv1,nv2; - bool nonorm = false; - if(i<=0) { nx = -1.; nonorm = true; } - if(i>=mSizex-1) { nx = 1.; nonorm = true; } - if(j<=0) { ny = -1.; nonorm = true; } - if(j>=mSizey-1) { ny = 1.; nonorm = true; } -# if LBMDIM==3 - if(k<=0) { nz = -1.; nonorm = true; } - if(k>=mSizez-1) { nz = 1.; nonorm = true; } -# endif // LBMDIM==3 - if(!nonorm) { - FFGET_NORM(nv1,dE); FFGET_NORM(nv2,dW); - nx = 0.5* (nv2-nv1); - FFGET_NORM(nv1,dN); FFGET_NORM(nv2,dS); - ny = 0.5* (nv2-nv1); -# if LBMDIM==3 - FFGET_NORM(nv1,dT); FFGET_NORM(nv2,dB); - nz = 0.5* (nv2-nv1); -# else // LBMDIM==3 - nz = 0.; -# endif // LBMDIM==3 - } else { - v = p->getVel() + vec2G(mLevel[level].gravity); - } - p->advanceVec( (ntlVec3Gfx(nx,ny,nz)) * -0.1 ); // + vec2G(mLevel[level].gravity); - } - } - - p->setVel( v ); - p->advanceVel(); - } - - // drop handling - else if(p->getType()==PART_DROP) { - ntlVec3Gfx v = p->getVel(); // dampen... - - if(mPartUsePhysModel) { - LbmFloat radius = p->getSize() * minDropSize; - LbmVec velPart = vec2L(p->getVel()) *cellsize /timestep; // * cellsize / timestep; // L2RW, lattice velocity - LbmVec velRel = velAir - velPart; - //LbmVec velRelLat = velRel /cellsize*timestep; // L2RW - LbmFloat velRelNorm = norm(velRel); - // TODO calculate values in lattice units, compute CD?!??! - LbmFloat mb = rhoWater * 4.0/3.0 * M_PI* radius*radius*radius; // mass: 4/3 pi r^3 rho - const LbmFloat rw = (r1-radius)/(r1-r2); - const LbmFloat rmax = (0.5 + 0.5*rw); - const LbmFloat vmax = (v2 + (v1-v2)* (1.0-rw) ); - const LbmFloat cd = (rmax) * (velRelNorm)/(vmax); - - LbmVec fg = rwgrav * mb;// * (1.0-rhoAir/rhoWater); - LbmVec fd = velRel* velRelNorm* cd*M_PI *rhoAir *0.5 *radius*radius; - LbmVec change = (fg+ fd ) *timestep / mb *(timestep/cellsize); - //if(k>0) { errMsg("\nPIT","NTEST1 mb="<<mb<<" radius="<<radius<<" vn="<<velRelNorm<<" velPart="<<velPart<<" velRel"<<velRel<<" pgetVel="<<p->getVel() ); } - - v += vec2G(change); - p->setVel(v); - // NEW - } else { - p->setVel( v ); - int gravk = (int)(p->getPos()[2]+mLevel[level].gravity[2]); - if(gravk>=0 && gravk<mSizez && RFLAG(level, i,j,gravk, workSet)&CFBnd) { - // dont add for "resting" parts - v[2] = 0.; - p->setVel( v*0.9 ); // restdamping - } else { - p->addToVel( vec2G(mLevel[level].gravity) ); - } - } // OLD - p->advanceVel(); - - if(p->getStatus()&PART_IN) { // IN - if(k<cutval) { DEL_PART; continue; } - if(k<=mSizez-1-cutval){ - CellFlagType pflag = RFLAG(level, i,j,k, workSet); - //errMsg("PIT move"," at "<<PRINT_IJK<<" flag"<<convertCellFlagType2String(pflag) ); - if (pflag & CFMbndOutflow) { - DEL_PART; - continue; - } - if(pflag & (CFBnd)) { - handleObstacleParticle(p); - continue; - } else if(pflag & (CFEmpty)) { - // still ok - } else if((pflag & CFInter) - //&&(!(RFLAG(level, i,j,k, workSet)& CFNoNbFluid)) - ) { - // add to no nb fluid i.f.'s, so skip if interface with fluid nb - } else if(pflag & (CFFluid|CFUnused|CFInter) ){ // interface cells ignored here due to previous check! - // add dropmass again, (these are only interf. with nonbfl.) - int oi= (int)(pos[0]-1.25*v[0]+0.5); - int oj= (int)(pos[1]-1.25*v[1]+0.5); - int ok= (int)(pos[2]-1.25*v[2]+0.5); - const LbmFloat size = p->getSize(); - const LbmFloat dropmass = ParticleObject::getMass(mPartDropMassSub*size); - bool orgcellok = false; - if( (oi<0)||(oi>mSizex-1)|| - (oj<0)||(oj>mSizey-1)|| - (ok<0)||(ok>mSizez-1) ) { - // org cell not ok! - } else if( RFLAG(level, oi,oj,ok, workSet) & (CFInter) ){ - orgcellok = true; - } else { - // search upward for interface - oi=i; oj=j; ok=k; - for(int kk=0; kk<5 && ok<=mSizez-2; kk++) { - ok++; // check sizez-2 due to this increment! - if( RFLAG(level, oi,oj,ok, workSet) & (CFInter) ){ - kk = 5; orgcellok = true; - } - } - } - - //errMsg("PTIMPULSE"," new v"<<v<<" at "<<PRINT_VEC(oi,oj,ok)<<" , was "<<PRINT_VEC(i,j,k)<<" ok "<<orgcellok ); - if(orgcellok) { - QCELL(level, oi,oj,ok, workSet, dMass) += dropmass; - QCELL(level, oi,oj,ok, workSet, dFfrac) += dropmass; // assume rho=1? - - if(RFLAG(level, oi,oj,ok, workSet) & CFNoBndFluid){ - // check speed, perhaps normalize - gfxReal vlensqr = normNoSqrt(v); - if(vlensqr > 0.166*0.166) { - v *= 1./sqrtf((float)vlensqr)*0.166; - } - // compute cell velocity - LbmFloat *tcel = RACPNT(level, oi,oj,ok, workSet); - LbmFloat velUx=0., velUy=0., velUz=0.; - FORDF0 { - velUx += (this->dfDvecX[l]*RAC(tcel,l)); - velUy += (this->dfDvecY[l]*RAC(tcel,l)); - velUz += (this->dfDvecZ[l]*RAC(tcel,l)); - } - // add impulse - /* - LbmFloat cellVelSqr = velUx*velUx+ velUy*velUy+ velUz*velUz; - //errMsg("PTIMPULSE"," new v"<<v<<" cvs"<<cellVelSqr<<"="<<sqrt(cellVelSqr)); - if(cellVelSqr< 0.166*0.166) { - FORDF1 { - const LbmFloat add = 3. * dropmass * this->dfLength[l]*(v[0]*this->dfDvecX[l]+v[1]*this->dfDvecY[l]+v[2]*this->dfDvecZ[l]); - RAC(tcel,l) += add; - } } // */ - } // only add impulse away from obstacles! - } // orgcellok - - // FIXME make fsgr treatment - P_CHANGETYPE(p, PART_FLOAT ); continue; - // jitter in cell to prevent stacking when hitting a steep surface - ntlVec3Gfx cpos = p->getPos(); - cpos[0] += (rand()/(RAND_MAX+1.0))-0.5; - cpos[1] += (rand()/(RAND_MAX+1.0))-0.5; - cpos[2] += (rand()/(RAND_MAX+1.0))-0.5; - p->setPos(cpos); - } else { - DEL_PART; - this->mNumParticlesLost++; - } - } - } else { // OUT -# if LBM_INCLUDE_TESTSOLVERS==1 - if(useff) { mpTest->handleParticle(p, i,j,k); } - else{ DEL_PART; } -# else // LBM_INCLUDE_TESTSOLVERS==1 - DEL_PART; -# endif // LBM_INCLUDE_TESTSOLVERS==1 - } - - } // air particle - - // inter particle - else if(p->getType()==PART_INTER) { - // unused!? - if(p->getStatus()&PART_IN) { // IN - if((k<cutval)||(k>mSizez-1-cutval)) { - // undecided particle above or below... remove? - DEL_PART; - } - - CellFlagType pflag = RFLAG(level, i,j,k, workSet); - if(pflag& CFInter ) { - // still ok - } else if(pflag& (CFFluid|CFUnused) ) { - P_CHANGETYPE(p, PART_FLOAT ); continue; - } else if(pflag& CFEmpty ) { - P_CHANGETYPE(p, PART_DROP ); continue; - } else if(pflag& CFBnd ) { - P_CHANGETYPE(p, PART_FLOAT ); continue; - } - } else { // OUT - // undecided particle outside... remove? - DEL_PART; - } - } - - // float particle - else if(p->getType()==PART_FLOAT) { - - if(p->getStatus()&PART_IN) { // IN - if(k<cutval) DEL_PART; - // not valid for mass... - vx = vy = vz = 0.0; - - // define from particletracer.h -#if MOVE_FLOATS==1 - const int DEPTH_AVG=3; // only average interface vels - int ccnt=0; - for(int kk=0;kk<DEPTH_AVG;kk+=1) { - if((k-kk)<1) continue; - if(RFLAG(level, i,j,k, workSet)&(CFInter)) {} else continue; - ccnt++; - FORDF1{ - LbmFloat cdf = QCELL(level, i,j,k-kk, workSet, l); - vx += (this->dfDvecX[l]*cdf); - vy += (this->dfDvecY[l]*cdf); - vz += (this->dfDvecZ[l]*cdf); - } - } - if(ccnt) { - // use halved surface velocity (todo, use omega instead) - vx /=(LbmFloat)(ccnt * 2.0); // half xy speed! value2 - vy /=(LbmFloat)(ccnt * 2.0); - vz /=(LbmFloat)(ccnt); } -#else // MOVE_FLOATS==1 - vx=vy=0.; //p->setVel(ntlVec3Gfx(0.) ); // static_float -#endif // MOVE_FLOATS==1 - vx += (rand()/(RAND_MAX+1.0))*(FLOAT_JITTER*0.2)-(FLOAT_JITTER*0.2*0.5); - vy += (rand()/(RAND_MAX+1.0))*(FLOAT_JITTER*0.2)-(FLOAT_JITTER*0.2*0.5); - - //bool delfloat = false; - if( ( RFLAG(level, i,j,k, workSet)& (CFFluid|CFUnused) ) ) { - // in fluid cell - vz = p->getVel()[2]-1.0*mLevel[level].gravity[2]; // simply rise... - if(vz<0.) vz=0.; - } else if( ( RFLAG(level, i,j,k, workSet)& CFBnd ) ) { - // force downwards movement, move below obstacle... - //vz = p->getVel()[2]+1.0*mLevel[level].gravity[2]; // fall... - //if(vz>0.) vz=0.; - DEL_PART; - } else if( ( RFLAG(level, i,j,k, workSet)& CFInter ) ) { - // keep in interface , one grid cell offset is added in part. gen - } else { // all else... - if( ( RFLAG(level, i,j,k-1, workSet)& (CFFluid|CFInter) ) ) { - vz = p->getVel()[2]+2.0*mLevel[level].gravity[2]; // fall... - if(vz>0.) vz=0.; } - else { DEL_PART; } - } - - p->setVel( vec2G( ntlVec3Gfx(vx,vy,vz) ) ); //? - p->advanceVel(); - } else { -#if LBM_INCLUDE_TESTSOLVERS==1 - if(useff) { mpTest->handleParticle(p, i,j,k); } - else DEL_PART; -#else // LBM_INCLUDE_TESTSOLVERS==1 - DEL_PART; -#endif // LBM_INCLUDE_TESTSOLVERS==1 - } - - // additional bnd jitter - if((0) && (useff) && (p->getLifeTime()<3.*mLevel[level].timestep)) { - // use half butoff border 1/8 - int maxdw = (int)(mLevel[level].lSizex*0.125*0.5); - if(maxdw<3) maxdw=3; - if((j>=0)&&(j<=mSizey-1)) { - if(ABS(i-( cutval))<maxdw) { p->advance( FLOAT_JITTBNDRAND( ABS(i-( cutval))), 0.,0.); } - if(ABS(i-(mSizex-1-cutval))<maxdw) { p->advance( FLOAT_JITTBNDRAND( ABS(i-(mSizex-1-cutval))), 0.,0.); } - } - } - } // PART_FLOAT - - // unknown particle type - else { - errMsg("LbmFsgrSolver::advanceParticles","PIT pit invalid type!? "<<p->getStatus() ); - } - } - myTime_t parttend = getTime(); - debMsgStd("LbmFsgrSolver::advanceParticles",DM_MSG,"Time for particle update:"<< getTimeString(parttend-parttstart)<<", #particles:"<<mpParticles->getNumParticles() , 10 ); -} - -void LbmFsgrSolver::notifySolverOfDump(int dumptype, int frameNr,char *frameNrStr,string outfilename) { - int workSet = mLevel[mMaxRefine].setCurr; - std::ostringstream name; - - // debug - raw dump of ffrac values, as text! - if(mDumpRawText) { - name << outfilename<< frameNrStr <<".dump"; - FILE *file = fopen(name.str().c_str(),"w"); - if(file) { - - for(int k= getForZMinBnd(); k< getForZMaxBnd(mMaxRefine); ++k) { - for(int j=0;j<mLevel[mMaxRefine].lSizey-0;j++) { - for(int i=0;i<mLevel[mMaxRefine].lSizex-0;i++) { - float val = 0.; - if(RFLAG(mMaxRefine, i,j,k, workSet) & CFInter) { - val = QCELL(mMaxRefine,i,j,k, mLevel[mMaxRefine].setCurr,dFfrac); - if(val<0.) val=0.; - if(val>1.) val=1.; - } - if(RFLAG(mMaxRefine, i,j,k, workSet) & CFFluid) val = 1.; - fprintf(file, "%f ",val); // text - //errMsg("W", PRINT_IJK<<" val:"<<val); - } - fprintf(file, "\n"); // text - } - fprintf(file, "\n"); // text - } - fclose(file); - - } // file - } // */ - - if(mDumpRawBinary) { - if(!mDumpRawBinaryZip) { - // unzipped, only fill - name << outfilename<< frameNrStr <<".bdump"; - FILE *file = fopen(name.str().c_str(),"w"); - if(file) { - for(int k= getForZMinBnd(); k< getForZMaxBnd(mMaxRefine); ++k) { - for(int j=0;j<mLevel[mMaxRefine].lSizey-0;j++) { - for(int i=0;i<mLevel[mMaxRefine].lSizex-0;i++) { - float val = 0.; - if(RFLAG(mMaxRefine, i,j,k, workSet) & CFInter) { - val = QCELL(mMaxRefine,i,j,k, mLevel[mMaxRefine].setCurr,dFfrac); - if(val<0.) val=0.; - if(val>1.) val=1.; - } - if(RFLAG(mMaxRefine, i,j,k, workSet) & CFFluid) val = 1.; - fwrite( &val, sizeof(val), 1, file); // binary - } - } - } - fclose(file); - } // file - } // unzipped - else { - // zipped, use iso values - prepareVisualization(); - name << outfilename<< frameNrStr <<".bdump.gz"; - gzFile gzf = gzopen(name.str().c_str(),"wb9"); - if(gzf) { - // write size - int s; - s=mSizex; gzwrite(gzf, &s, sizeof(s)); - s=mSizey; gzwrite(gzf, &s, sizeof(s)); - s=mSizez; gzwrite(gzf, &s, sizeof(s)); - - // write isovalues - for(int k= getForZMinBnd(); k< getForZMaxBnd(mMaxRefine); ++k) { - for(int j=0;j<mLevel[mMaxRefine].lSizey;j++) { - for(int i=0;i<mLevel[mMaxRefine].lSizex;i++) { - float val = 0.; - val = *mpIso->lbmGetData( i,j,k ); - gzwrite(gzf, &val, sizeof(val)); - } - } - } - gzclose(gzf); - } // gzf - } // zip - } // bin dump - - dumptype = 0; frameNr = 0; // get rid of warning -} - -/*! move a particle at a boundary */ -void LbmFsgrSolver::handleObstacleParticle(ParticleObject *p) { - //if(normNoSqrt(v)<=0.) continue; // skip stuck - /* - p->setVel( v * -1. ); // revert - p->advanceVel(); // move back twice... - if( RFLAG(mMaxRefine, i,j,k, workSet)& (CFBndNoslip)) { - p->setVel( v * -0.5 ); // revert & dampen - } - p->advanceVel(); - // */ - // TODO mark/remove stuck parts!? - - const int level = mMaxRefine; - const int workSet = mLevel[level].setCurr; - LbmVec v = vec2L( p->getVel() ); - if(normNoSqrt(v)<=0.) { - p->setVel(vec2G(mLevel[level].gravity)); - } - - CellFlagType pflag = CFBnd; - ntlVec3Gfx posOrg(p->getPos()); - ntlVec3Gfx npos(0.); - int ni=1,nj=1,nk=1; - int tries = 0; - - // try to undo movement - p->advanceVec( (p->getVel()-vec2G(mLevel[level].gravity)) * -2.); - - npos = p->getPos(); ni= (int)npos[0]; - nj= (int)npos[1]; nk= (int)npos[2]; - if(LBMDIM==2) { nk = 0; } - //errMsg("BOUNDCPAR"," t"<<PRINT_VEC(ni,nj,nk)<<" v"<<v<<" p"<<npos); - - // delete out of domain - if(!checkDomainBounds(level,ni,nj,nk)) { - //errMsg("BOUNDCPAR"," DEL! "); - p->setActive( false ); - return; - } - pflag = RFLAG(level, ni,nj,nk, workSet); - - // try to force particle out of boundary - bool haveNorm = false; - LbmVec bnormal; - if(pflag&CFBnd) { - npos = posOrg; ni= (int)npos[0]; - nj= (int)npos[1]; nk= (int)npos[2]; - if(LBMDIM==2) { nk = 0; } - - computeObstacleSurfaceNormalAcc(ni,nj,nk, &bnormal[0]); - haveNorm = true; - normalize(bnormal); - bnormal *= 0.25; - - tries = 1; - while(pflag&CFBnd && tries<=5) { - // use increasing step sizes - p->advanceVec( vec2G( bnormal *0.5 *(gfxReal)tries ) ); - npos = p->getPos(); - ni= (int)npos[0]; - nj= (int)npos[1]; - nk= (int)npos[2]; - - // delete out of domain - if(!checkDomainBounds(level,ni,nj,nk)) { - //errMsg("BOUNDCPAR"," DEL! "); - p->setActive( false ); - return; - } - pflag = RFLAG(level, ni,nj,nk, workSet); - tries++; - } - - // really stuck, delete... - if(pflag&CFBnd) { - p->setActive( false ); - return; - } - } - - // not in bound anymore! - if(!haveNorm) { - CellFlagType *bflag = &RFLAG(level, ni,nj,nk, workSet); - LbmFloat *bcell = RACPNT(level, ni,nj,nk, workSet); - computeObstacleSurfaceNormal(bcell,bflag, &bnormal[0]); - } - normalize(bnormal); - LbmVec normComp = bnormal * dot(vec2L(v),bnormal); - //errMsg("BOUNDCPAR","bnormal"<<bnormal<<" normComp"<<normComp<<" newv"<<(v-normComp) ); - v = (v-normComp)*0.9; // only move tangential - v *= 0.9; // restdamping , todo use timestep - p->setVel(vec2G(v)); - p->advanceVel(); -} - -/*****************************************************************************/ -/*! internal quick print function (for debugging) */ -/*****************************************************************************/ -void -LbmFsgrSolver::printLbmCell(int level, int i, int j, int k, int set) { - stdCellId *newcid = new stdCellId; - newcid->level = level; - newcid->x = i; - newcid->y = j; - newcid->z = k; - - // this function is not called upon clicking, then its from setMouseClick - debugPrintNodeInfo( newcid, set ); - delete newcid; -} -void -LbmFsgrSolver::debugMarkCellCall(int level, int vi,int vj,int vk) { - stdCellId *newcid = new stdCellId; - newcid->level = level; - newcid->x = vi; - newcid->y = vj; - newcid->z = vk; - this->addCellToMarkedList( newcid ); -} - - -/*****************************************************************************/ -// implement CellIterator<UniformFsgrCellIdentifier> interface -/*****************************************************************************/ - - - -// values from guiflkt.cpp -extern double guiRoiSX, guiRoiSY, guiRoiSZ, guiRoiEX, guiRoiEY, guiRoiEZ; -extern int guiRoiMaxLev, guiRoiMinLev; -#define CID_SX (int)( (mLevel[cid->level].lSizex-1) * guiRoiSX ) -#define CID_SY (int)( (mLevel[cid->level].lSizey-1) * guiRoiSY ) -#define CID_SZ (int)( (mLevel[cid->level].lSizez-1) * guiRoiSZ ) - -#define CID_EX (int)( (mLevel[cid->level].lSizex-1) * guiRoiEX ) -#define CID_EY (int)( (mLevel[cid->level].lSizey-1) * guiRoiEY ) -#define CID_EZ (int)( (mLevel[cid->level].lSizez-1) * guiRoiEZ ) - -CellIdentifierInterface* -LbmFsgrSolver::getFirstCell( ) { - int level = mMaxRefine; - -#if LBMDIM==3 - if(mMaxRefine>0) { level = mMaxRefine-1; } // NO1HIGHESTLEV DEBUG -#endif - level = guiRoiMaxLev; - if(level>mMaxRefine) level = mMaxRefine; - - //errMsg("LbmFsgrSolver::getFirstCell","Celliteration started..."); - stdCellId *cid = new stdCellId; - cid->level = level; - cid->x = CID_SX; - cid->y = CID_SY; - cid->z = CID_SZ; - return cid; -} - -LbmFsgrSolver::stdCellId* -LbmFsgrSolver::convertBaseCidToStdCid( CellIdentifierInterface* basecid) { - //stdCellId *cid = dynamic_cast<stdCellId*>( basecid ); - stdCellId *cid = (stdCellId*)( basecid ); - return cid; -} - -void LbmFsgrSolver::advanceCell( CellIdentifierInterface* basecid) { - stdCellId *cid = convertBaseCidToStdCid(basecid); - if(cid->getEnd()) return; - - //debugOut(" ADb "<<cid->x<<","<<cid->y<<","<<cid->z<<" e"<<cid->getEnd(), 10); - cid->x++; - if(cid->x > CID_EX){ cid->x = CID_SX; cid->y++; - if(cid->y > CID_EY){ cid->y = CID_SY; cid->z++; - if(cid->z > CID_EZ){ - cid->level--; - cid->x = CID_SX; - cid->y = CID_SY; - cid->z = CID_SZ; - if(cid->level < guiRoiMinLev) { - cid->level = guiRoiMaxLev; - cid->setEnd( true ); - } - } - } - } - //debugOut(" ADa "<<cid->x<<","<<cid->y<<","<<cid->z<<" e"<<cid->getEnd(), 10); -} - -bool LbmFsgrSolver::noEndCell( CellIdentifierInterface* basecid) { - stdCellId *cid = convertBaseCidToStdCid(basecid); - return (!cid->getEnd()); -} - -void LbmFsgrSolver::deleteCellIterator( CellIdentifierInterface** cid ) { - delete *cid; - *cid = NULL; -} - -CellIdentifierInterface* LbmFsgrSolver::getCellAt( ntlVec3Gfx pos ) { - //int cellok = false; - pos -= (this->mvGeoStart); - - LbmFloat mmaxsize = mLevel[mMaxRefine].nodeSize; - for(int level=mMaxRefine; level>=0; level--) { // finest first - //for(int level=0; level<=mMaxRefine; level++) { // coarsest first - LbmFloat nsize = mLevel[level].nodeSize; - int x,y,z; - // CHECK +- maxsize? - x = (int)((pos[0]+0.5*mmaxsize) / nsize ); - y = (int)((pos[1]+0.5*mmaxsize) / nsize ); - z = (int)((pos[2]+0.5*mmaxsize) / nsize ); - if(LBMDIM==2) z = 0; - - // double check... - if(x<0) continue; - if(y<0) continue; - if(z<0) continue; - if(x>=mLevel[level].lSizex) continue; - if(y>=mLevel[level].lSizey) continue; - if(z>=mLevel[level].lSizez) continue; - - // return fluid/if/border cells - if( ( (RFLAG(level, x,y,z, mLevel[level].setCurr)&(CFUnused)) ) || - ( (level<mMaxRefine) && (RFLAG(level, x,y,z, mLevel[level].setCurr)&(CFUnused|CFEmpty)) ) ) { - continue; - } // */ - - stdCellId *newcid = new stdCellId; - newcid->level = level; - newcid->x = x; - newcid->y = y; - newcid->z = z; - //errMsg("cellAt",this->mName<<" "<<pos<<" l"<<level<<":"<<x<<","<<y<<","<<z<<" "<<convertCellFlagType2String(RFLAG(level, x,y,z, mLevel[level].setCurr)) ); - return newcid; - } - - return NULL; -} - - -// INFO functions - -int LbmFsgrSolver::getCellSet ( CellIdentifierInterface* basecid) { - stdCellId *cid = convertBaseCidToStdCid(basecid); - return mLevel[cid->level].setCurr; - //return mLevel[cid->level].setOther; -} - -int LbmFsgrSolver::getCellLevel ( CellIdentifierInterface* basecid) { - stdCellId *cid = convertBaseCidToStdCid(basecid); - return cid->level; -} - -ntlVec3Gfx LbmFsgrSolver::getCellOrigin ( CellIdentifierInterface* basecid) { - ntlVec3Gfx ret; - - stdCellId *cid = convertBaseCidToStdCid(basecid); - ntlVec3Gfx cs( mLevel[cid->level].nodeSize ); - if(LBMDIM==2) { cs[2] = 0.0; } - - if(LBMDIM==2) { - ret =(this->mvGeoStart + ntlVec3Gfx( cid->x *cs[0], cid->y *cs[1], (this->mvGeoEnd[2]-this->mvGeoStart[2])*0.5 ) - + ntlVec3Gfx(0.0,0.0,cs[1]*-0.25)*cid->level ) - +getCellSize(basecid); - } else { - ret =(this->mvGeoStart + ntlVec3Gfx( cid->x *cs[0], cid->y *cs[1], cid->z *cs[2] )) - +getCellSize(basecid); - } - return (ret); -} - -ntlVec3Gfx LbmFsgrSolver::getCellSize ( CellIdentifierInterface* basecid) { - // return half size - stdCellId *cid = convertBaseCidToStdCid(basecid); - ntlVec3Gfx retvec( mLevel[cid->level].nodeSize * 0.5 ); - // 2d display as rectangles - if(LBMDIM==2) { retvec[2] = 0.0; } - return (retvec); -} - -LbmFloat LbmFsgrSolver::getCellDensity ( CellIdentifierInterface* basecid,int set) { - stdCellId *cid = convertBaseCidToStdCid(basecid); - - // skip non-fluid cells - if(RFLAG(cid->level, cid->x,cid->y,cid->z, set)&(CFFluid|CFInter)) { - // ok go on... - } else { - return 0.; - } - - LbmFloat rho = 0.0; - FORDF0 { rho += QCELL(cid->level, cid->x,cid->y,cid->z, set, l); } // ORG - return ((rho-1.0) * mLevel[cid->level].simCellSize / mLevel[cid->level].timestep) +1.0; // ORG - /*if(RFLAG(cid->level, cid->x,cid->y,cid->z, set)&CFInter) { // test - LbmFloat ux,uy,uz; - ux=uy=uz= 0.0; - int lev = cid->level; - LbmFloat df[27], feqOld[27]; - FORDF0 { - rho += QCELL(lev, cid->x,cid->y,cid->z, set, l); - ux += this->dfDvecX[l]* QCELL(lev, cid->x,cid->y,cid->z, set, l); - uy += this->dfDvecY[l]* QCELL(lev, cid->x,cid->y,cid->z, set, l); - uz += this->dfDvecZ[l]* QCELL(lev, cid->x,cid->y,cid->z, set, l); - df[l] = QCELL(lev, cid->x,cid->y,cid->z, set, l); - } - FORDF0 { - feqOld[l] = getCollideEq(l, rho,ux,uy,uz); - } - // debugging mods - //const LbmFloat Qo = this->getLesNoneqTensorCoeff(df,feqOld); - //const LbmFloat modOmega = this->getLesOmega(mLevel[lev].omega, mLevel[lev].lcsmago,Qo); - //rho = (2.0-modOmega) *25.0; - //rho = Qo*100.0; - //if(cid->x==24){ errMsg("MODOMT"," at "<<PRINT_VEC(cid->x,cid->y,cid->z)<<" = "<<rho<<" "<<Qo); } - //else{ rho=0.0; } - } // test - return rho; // test */ -} - -LbmVec LbmFsgrSolver::getCellVelocity ( CellIdentifierInterface* basecid,int set) { - stdCellId *cid = convertBaseCidToStdCid(basecid); - - // skip non-fluid cells - if(RFLAG(cid->level, cid->x,cid->y,cid->z, set)&(CFFluid|CFInter)) { - // ok go on... - } else { - return LbmVec(0.0); - } - - LbmFloat ux,uy,uz; - ux=uy=uz= 0.0; - FORDF0 { - ux += this->dfDvecX[l]* QCELL(cid->level, cid->x,cid->y,cid->z, set, l); - uy += this->dfDvecY[l]* QCELL(cid->level, cid->x,cid->y,cid->z, set, l); - uz += this->dfDvecZ[l]* QCELL(cid->level, cid->x,cid->y,cid->z, set, l); - } - LbmVec vel(ux,uy,uz); - // TODO fix... - return (vel * mLevel[cid->level].simCellSize / mLevel[cid->level].timestep * this->mDebugVelScale); // normal -} - -LbmFloat LbmFsgrSolver::getCellDf( CellIdentifierInterface* basecid,int set, int dir) { - stdCellId *cid = convertBaseCidToStdCid(basecid); - return QCELL(cid->level, cid->x,cid->y,cid->z, set, dir); -} -LbmFloat LbmFsgrSolver::getCellMass( CellIdentifierInterface* basecid,int set) { - stdCellId *cid = convertBaseCidToStdCid(basecid); - return QCELL(cid->level, cid->x,cid->y,cid->z, set, dMass); -} -LbmFloat LbmFsgrSolver::getCellFill( CellIdentifierInterface* basecid,int set) { - stdCellId *cid = convertBaseCidToStdCid(basecid); - if(RFLAG(cid->level, cid->x,cid->y,cid->z, set)&CFInter) return QCELL(cid->level, cid->x,cid->y,cid->z, set, dFfrac); - if(RFLAG(cid->level, cid->x,cid->y,cid->z, set)&CFFluid) return 1.0; - return 0.0; - //return QCELL(cid->level, cid->x,cid->y,cid->z, set, dFfrac); -} -CellFlagType LbmFsgrSolver::getCellFlag( CellIdentifierInterface* basecid,int set) { - stdCellId *cid = convertBaseCidToStdCid(basecid); - return RFLAG(cid->level, cid->x,cid->y,cid->z, set); -} - -LbmFloat LbmFsgrSolver::getEquilDf( int l ) { - return this->dfEquil[l]; -} - - -ntlVec3Gfx LbmFsgrSolver::getVelocityAt (float xp, float yp, float zp) { - ntlVec3Gfx avgvel(0.0); - LbmFloat avgnum = 0.; - - // taken from getCellAt! - const int level = mMaxRefine; - const int workSet = mLevel[level].setCurr; - const LbmFloat nsize = mLevel[level].nodeSize; - const int x = (int)((-this->mvGeoStart[0]+xp-0.5*nsize) / nsize ); - const int y = (int)((-this->mvGeoStart[1]+yp-0.5*nsize) / nsize ); - int z = (int)((-this->mvGeoStart[2]+zp-0.5*nsize) / nsize ); - if(LBMDIM==2) z=0; - //errMsg("DUMPVEL","p"<<PRINT_VEC(xp,yp,zp)<<" at "<<PRINT_VEC(x,y,z)<<" max"<<PRINT_VEC(mLevel[level].lSizex,mLevel[level].lSizey,mLevel[level].lSizez) ); - - // return fluid/if/border cells - // search neighborhood, do smoothing - FORDF0{ - const int i = x+this->dfVecX[l]; - const int j = y+this->dfVecY[l]; - const int k = z+this->dfVecZ[l]; - - if( (i<0) || (j<0) || (k<0) - || (i>=mLevel[level].lSizex) - || (j>=mLevel[level].lSizey) - || (k>=mLevel[level].lSizez) ) continue; - - if( (RFLAG(level, i,j,k, mLevel[level].setCurr)&(CFFluid|CFInter)) ) { - ntlVec3Gfx vel(0.0); - LbmFloat *ccel = RACPNT(level, i,j,k ,workSet); // omp - for(int n=1; n<this->cDfNum; n++) { - vel[0] += (this->dfDvecX[n]*RAC(ccel,n)); - vel[1] += (this->dfDvecY[n]*RAC(ccel,n)); - vel[2] += (this->dfDvecZ[n]*RAC(ccel,n)); - } - - avgvel += vel; - avgnum += 1.0; - if(l==0) { // center slightly more weight - avgvel += vel; avgnum += 1.0; - } - } // */ - } - - if(avgnum>0.) { - ntlVec3Gfx retv = avgvel / avgnum; - retv *= nsize/mLevel[level].timestep; - // scale for current animation settings (frame time) - retv *= mpParam->getCurrentAniFrameTime(); - //errMsg("DUMPVEL","t"<<mSimulationTime<<" at "<<PRINT_VEC(xp,yp,zp)<<" ret:"<<retv<<", avgv:"<<avgvel<<" n"<<avgnum<<" nsize"<<nsize<<" ts"<<mLevel[level].timestep<<" fr"<<mpParam->getCurrentAniFrameTime() ); - return retv; - } - // no cells here...? - //errMsg("DUMPVEL"," at "<<PRINT_VEC(xp,yp,zp)<<" v"<<avgvel<<" n"<<avgnum<<" no vel !?"); - return ntlVec3Gfx(0.); -} - -#if LBM_USE_GUI==1 -//! show simulation info (implement SimulationObject pure virtual func) -void -LbmFsgrSolver::debugDisplay(int set){ - //lbmDebugDisplay< LbmFsgrSolver >( set, this ); - lbmDebugDisplay( set ); -} -#endif - -/*****************************************************************************/ -// strict debugging functions -/*****************************************************************************/ -#if FSGR_STRICT_DEBUG==1 -#define STRICT_EXIT *((int *)0)=0; - -int LbmFsgrSolver::debLBMGI(int level, int ii,int ij,int ik, int is) { - if(level < 0){ errMsg("LbmStrict::debLBMGI"," invLev- l"<<level<<"|"<<ii<<","<<ij<<","<<ik<<" s"<<is); STRICT_EXIT; } - if(level > mMaxRefine){ errMsg("LbmStrict::debLBMGI"," invLev+ l"<<level<<"|"<<ii<<","<<ij<<","<<ik<<" s"<<is); STRICT_EXIT; } - - if((ii==-1)&&(ij==0)) { - // special case for main loop, ok - } else { - if(ii<0){ errMsg("LbmStrict"," invX- l"<<level<<"|"<<ii<<","<<ij<<","<<ik<<" s"<<is); STRICT_EXIT; } - if(ij<0){ errMsg("LbmStrict"," invY- l"<<level<<"|"<<ii<<","<<ij<<","<<ik<<" s"<<is); STRICT_EXIT; } - if(ii>mLevel[level].lSizex-1){ errMsg("LbmStrict"," invX+ l"<<level<<"|"<<ii<<","<<ij<<","<<ik<<" s"<<is); STRICT_EXIT; } - if(ij>mLevel[level].lSizey-1){ errMsg("LbmStrict"," invY+ l"<<level<<"|"<<ii<<","<<ij<<","<<ik<<" s"<<is); STRICT_EXIT; } - } - if(ik<0){ errMsg("LbmStrict"," invZ- l"<<level<<"|"<<ii<<","<<ij<<","<<ik<<" s"<<is); STRICT_EXIT; } - if(ik>mLevel[level].lSizez-1){ errMsg("LbmStrict"," invZ+ l"<<level<<"|"<<ii<<","<<ij<<","<<ik<<" s"<<is); STRICT_EXIT; } - if(is<0){ errMsg("LbmStrict"," invS- l"<<level<<"|"<<ii<<","<<ij<<","<<ik<<" s"<<is); STRICT_EXIT; } - if(is>1){ errMsg("LbmStrict"," invS+ l"<<level<<"|"<<ii<<","<<ij<<","<<ik<<" s"<<is); STRICT_EXIT; } - return _LBMGI(level, ii,ij,ik, is); -}; - -CellFlagType& LbmFsgrSolver::debRFLAG(int level, int xx,int yy,int zz,int set){ - return _RFLAG(level, xx,yy,zz,set); -}; - -CellFlagType& LbmFsgrSolver::debRFLAG_NB(int level, int xx,int yy,int zz,int set, int dir) { - if(dir<0) { errMsg("LbmStrict"," invD- l"<<level<<"|"<<xx<<","<<yy<<","<<zz<<" s"<<set<<" d"<<dir); STRICT_EXIT; } - // warning might access all spatial nbs - if(dir>this->cDirNum){ errMsg("LbmStrict"," invD+ l"<<level<<"|"<<xx<<","<<yy<<","<<zz<<" s"<<set<<" d"<<dir); STRICT_EXIT; } - return _RFLAG_NB(level, xx,yy,zz,set, dir); -}; - -CellFlagType& LbmFsgrSolver::debRFLAG_NBINV(int level, int xx,int yy,int zz,int set, int dir) { - if(dir<0) { errMsg("LbmStrict"," invD- l"<<level<<"|"<<xx<<","<<yy<<","<<zz<<" s"<<set<<" d"<<dir); STRICT_EXIT; } - if(dir>this->cDirNum){ errMsg("LbmStrict"," invD+ l"<<level<<"|"<<xx<<","<<yy<<","<<zz<<" s"<<set<<" d"<<dir); STRICT_EXIT; } - return _RFLAG_NBINV(level, xx,yy,zz,set, dir); -}; - -int LbmFsgrSolver::debLBMQI(int level, int ii,int ij,int ik, int is, int l) { - if(level < 0){ errMsg("LbmStrict::debLBMQI"," invLev- l"<<level<<"|"<<ii<<","<<ij<<","<<ik<<" s"<<is); STRICT_EXIT; } - if(level > mMaxRefine){ errMsg("LbmStrict::debLBMQI"," invLev+ l"<<level<<"|"<<ii<<","<<ij<<","<<ik<<" s"<<is); STRICT_EXIT; } - - if((ii==-1)&&(ij==0)) { - // special case for main loop, ok - } else { - if(ii<0){ errMsg("LbmStrict"," invX- l"<<level<<"|"<<ii<<","<<ij<<","<<ik<<" s"<<is); STRICT_EXIT; } - if(ij<0){ errMsg("LbmStrict"," invY- l"<<level<<"|"<<ii<<","<<ij<<","<<ik<<" s"<<is); STRICT_EXIT; } - if(ii>mLevel[level].lSizex-1){ errMsg("LbmStrict"," invX+ l"<<level<<"|"<<ii<<","<<ij<<","<<ik<<" s"<<is); STRICT_EXIT; } - if(ij>mLevel[level].lSizey-1){ errMsg("LbmStrict"," invY+ l"<<level<<"|"<<ii<<","<<ij<<","<<ik<<" s"<<is); STRICT_EXIT; } - } - if(ik<0){ errMsg("LbmStrict"," invZ- l"<<level<<"|"<<ii<<","<<ij<<","<<ik<<" s"<<is); STRICT_EXIT; } - if(ik>mLevel[level].lSizez-1){ errMsg("LbmStrict"," invZ+ l"<<level<<"|"<<ii<<","<<ij<<","<<ik<<" s"<<is); STRICT_EXIT; } - if(is<0){ errMsg("LbmStrict"," invS- l"<<level<<"|"<<ii<<","<<ij<<","<<ik<<" s"<<is); STRICT_EXIT; } - if(is>1){ errMsg("LbmStrict"," invS+ l"<<level<<"|"<<ii<<","<<ij<<","<<ik<<" s"<<is); STRICT_EXIT; } - if(l<0) { errMsg("LbmStrict"," invD- "<<" l"<<l); STRICT_EXIT; } - if(l>this->cDfNum){ // dFfrac is an exception - if((l != dMass) && (l != dFfrac) && (l != dFlux)){ errMsg("LbmStrict"," invD+ "<<" l"<<l); STRICT_EXIT; } } -#if COMPRESSGRIDS==1 - //if((!this->mInitDone) && (is!=mLevel[level].setCurr)){ STRICT_EXIT; } // COMPRT debug -#endif // COMPRESSGRIDS==1 - return _LBMQI(level, ii,ij,ik, is, l); -}; - -LbmFloat& LbmFsgrSolver::debQCELL(int level, int xx,int yy,int zz,int set,int l) { - //errMsg("LbmStrict","debQCELL debug: l"<<level<<"|"<<xx<<","<<yy<<","<<zz<<" s"<<set<<" l"<<l<<" index"<<LBMGI(level, xx,yy,zz,set)); - return _QCELL(level, xx,yy,zz,set,l); -}; - -LbmFloat& LbmFsgrSolver::debQCELL_NB(int level, int xx,int yy,int zz,int set, int dir,int l) { - if(dir<0) { errMsg("LbmStrict"," invD- l"<<level<<"|"<<xx<<","<<yy<<","<<zz<<" s"<<set<<" d"<<dir); STRICT_EXIT; } - if(dir>this->cDfNum){ errMsg("LbmStrict"," invD+ l"<<level<<"|"<<xx<<","<<yy<<","<<zz<<" s"<<set<<" d"<<dir); STRICT_EXIT; } - return _QCELL_NB(level, xx,yy,zz,set, dir,l); -}; - -LbmFloat& LbmFsgrSolver::debQCELL_NBINV(int level, int xx,int yy,int zz,int set, int dir,int l) { - if(dir<0) { errMsg("LbmStrict"," invD- l"<<level<<"|"<<xx<<","<<yy<<","<<zz<<" s"<<set<<" d"<<dir); STRICT_EXIT; } - if(dir>this->cDfNum){ errMsg("LbmStrict"," invD+ l"<<level<<"|"<<xx<<","<<yy<<","<<zz<<" s"<<set<<" d"<<dir); STRICT_EXIT; } - return _QCELL_NBINV(level, xx,yy,zz,set, dir,l); -}; - -LbmFloat* LbmFsgrSolver::debRACPNT(int level, int ii,int ij,int ik, int is ) { - return _RACPNT(level, ii,ij,ik, is ); -}; - -LbmFloat& LbmFsgrSolver::debRAC(LbmFloat* s,int l) { - if(l<0) { errMsg("LbmStrict"," invD- "<<" l"<<l); STRICT_EXIT; } - if(l>dTotalNum){ errMsg("LbmStrict"," invD+ "<<" l"<<l); STRICT_EXIT; } - //if(l>this->cDfNum){ // dFfrac is an exception - //if((l != dMass) && (l != dFfrac) && (l != dFlux)){ errMsg("LbmStrict"," invD+ "<<" l"<<l); STRICT_EXIT; } } - return _RAC(s,l); -}; - -#endif // FSGR_STRICT_DEBUG==1 - - -/****************************************************************************** - * GUI&debugging functions - *****************************************************************************/ - -//! display a single node -void LbmFsgrSolver::debugPrintNodeInfo(CellIdentifierInterface* cell, int forceSet) { - //string printInfo, - // force printing of one set? default = -1 = off - bool printDF = false; - bool printRho = false; - bool printVel = false; - bool printFlag = false; - bool printGeom = false; - bool printMass=false; - bool printBothSets = false; - string printInfo = this->getNodeInfoString(); - - for(size_t i=0; i<printInfo.length()-0; i++) { - char what = printInfo[i]; - switch(what) { - case '+': // all on - printDF = true; printRho = true; printVel = true; printFlag = true; printGeom = true; printMass = true ; - printBothSets = true; break; - case '-': // all off - printDF = false; printRho = false; printVel = false; printFlag = false; printGeom = false; printMass = false; - printBothSets = false; break; - case 'd': printDF = true; break; - case 'r': printRho = true; break; - case 'v': printVel = true; break; - case 'f': printFlag = true; break; - case 'g': printGeom = true; break; - case 'm': printMass = true; break; - case 's': printBothSets = true; break; - default: - errFatal("debugPrintNodeInfo","Invalid node info id "<<what,SIMWORLD_GENERICERROR); return; - } - } - - ntlVec3Gfx org = this->getCellOrigin( cell ); - ntlVec3Gfx halfsize = this->getCellSize( cell ); - int set = this->getCellSet( cell ); - debMsgStd("debugPrintNodeInfo",DM_NOTIFY, "Printing cell info '"<<printInfo<<"' for node: "<<cell->getAsString()<<" from "<<this->getName()<<" currSet:"<<set , 1); - if(printGeom) debMsgStd(" ",DM_MSG, "Org:"<<org<<" Halfsize:"<<halfsize<<" ", 1); - - int setmax = 2; - if(!printBothSets) setmax = 1; - if(forceSet>=0) setmax = 1; - - for(int s=0; s<setmax; s++) { - int workset = set; - if(s==1){ workset = (set^1); } - if(forceSet>=0) workset = forceSet; - debMsgStd(" ",DM_MSG, "Printing set:"<<workset<<" orgSet:"<<set, 1); - - if(printDF) { - for(int l=0; l<LBM_DFNUM; l++) { // FIXME ?? - debMsgStd(" ",DM_MSG, " Df"<<l<<": "<<this->getCellDf(cell,workset,l), 1); - } - } - if(printRho) { - debMsgStd(" ",DM_MSG, " Rho: "<<this->getCellDensity(cell,workset), 1); - } - if(printVel) { - debMsgStd(" ",DM_MSG, " Vel: "<<this->getCellVelocity(cell,workset), 1); - } - if(printFlag) { - CellFlagType flag = this->getCellFlag(cell,workset); - debMsgStd(" ",DM_MSG, " Flg: "<< flag<<" "<<convertFlags2String( flag ) <<" "<<convertCellFlagType2String( flag ), 1); - } - if(printMass) { - debMsgStd(" ",DM_MSG, " Mss: "<<this->getCellMass(cell,workset), 1); - } - // dirty... TODO fixme - debMsgStd(" ",DM_MSG, " Flx: "<<this->getCellDf(cell,workset,dFlux), 1); - } -} - - diff --git a/intern/elbeem/intern/utilities.cpp b/intern/elbeem/intern/utilities.cpp deleted file mode 100644 index 40596681b90..00000000000 --- a/intern/elbeem/intern/utilities.cpp +++ /dev/null @@ -1,498 +0,0 @@ -/** \file - * \ingroup elbeem - */ -/****************************************************************************** - * - * El'Beem - Free Surface Fluid Simulation with the Lattice Boltzmann Method - * Copyright 2003-2006 Nils Thuerey - * - * Global C style utility funcions - * - *****************************************************************************/ - - -#include <iostream> -#include <sstream> -#ifdef WIN32 -// for timing -#include <windows.h> -#else -#include <time.h> -#include <sys/time.h> -#include <sys/times.h> -#endif - -#include "utilities.h" - -#ifndef NOPNG -#ifdef WIN32 -#include "png.h" -#else -#include <png.h> -#endif -#endif // NOPNG -#include <zlib.h> - -// global debug level -#ifdef DEBUG -int gDebugLevel = DEBUG; -#else // DEBUG -int gDebugLevel = 0; -#endif // DEBUG - -// global world state, acces with get/setElbeemState -int gElbeemState = SIMWORLD_INVALID; - -// access global state of elbeem simulator -void setElbeemState(int set) { - gElbeemState = set; -} -int getElbeemState(void) { - return gElbeemState; -} -int isSimworldOk(void) { - return (getElbeemState() >=0); -} - -// last error as string, acces with get/setElbeemErrorString -char gElbeemErrorString[256] = {'-','\0' }; - -// access elbeem simulator error string -void setElbeemErrorString(const char* set) { - strncpy(gElbeemErrorString, set, 256); -} -char* getElbeemErrorString(void) { return gElbeemErrorString; } - - -//! for interval debugging output -myTime_t globalIntervalTime = 0; -//! color output setting for messages (0==off, else on) -#ifdef WIN32 -// switch off first call -#define DEF_globalColorSetting -1 -#else // WIN32 -// linux etc., on by default -#define DEF_globalColorSetting 1 -#endif // WIN32 -int globalColorSetting = DEF_globalColorSetting; // linux etc., on by default -int globalFirstEnvCheck = 0; -void resetGlobalColorSetting() { globalColorSetting = DEF_globalColorSetting; } - -// global string for formatting vector output, TODO test!? -const char *globVecFormatStr = "V[%f,%f,%f]"; - - -// global mp on/off switch -bool glob_mpactive = false; -// global access to mpi index, for debugging (e.g. in utilities.cpp) -int glob_mpnum = -1; -int glob_mpindex = -1; -int glob_mppn = -1; - - -//----------------------------------------------------------------------------- -// helper function that converts a string to integer, -// and returns an alternative value if the conversion fails -int convertString2Int(const char *str, int alt) -{ - int val; - char *endptr; - bool success=true; - - val = strtol(str, &endptr, 10); - if( (str==endptr) || - ((str!=endptr) && (*endptr != '\0')) ) success = false; - - if(!success) { - return alt; - } - return val; -} - -//----------------------------------------------------------------------------- -//! helper function that converts a flag field to a readable integer -string convertFlags2String(int flags) { - std::ostringstream ret; - ret <<"("; - int max = sizeof(int)*8; - for(int i=0; i<max; i++) { - if(flags & (1<<31)) ret <<"1"; - else ret<<"0"; - if(i<max-1) { - //ret << ","; - if((i%8)==7) ret << " "; - } - flags = flags << 1; - } - ret <<")"; - return ret.str(); -} - -#ifndef NOPNG -//----------------------------------------------------------------------------- -//! write png image -int writePng(const char *fileName, unsigned char **rowsp, int w, int h) -{ - // defaults for elbeem - const int colortype = PNG_COLOR_TYPE_RGBA; - const int bitdepth = 8; - png_structp png_ptr = NULL; - png_infop info_ptr = NULL; - png_bytep *rows = rowsp; - - //FILE *fp = fopen(fileName, "wb"); - FILE *fp = NULL; - string doing = "open for writing"; - if (!(fp = fopen(fileName, "wb"))) goto fail; - - if(!png_ptr) { - doing = "create png write struct"; - if (!(png_ptr = png_create_write_struct(PNG_LIBPNG_VER_STRING, NULL, NULL, NULL))) goto fail; - } - if(!info_ptr) { - doing = "create png info struct"; - if (!(info_ptr = png_create_info_struct(png_ptr))) goto fail; - } - - if (setjmp(png_jmpbuf(png_ptr))) goto fail; - doing = "init IO"; - png_init_io(png_ptr, fp); - doing = "write header"; - png_set_IHDR(png_ptr, info_ptr, w, h, bitdepth, colortype, PNG_INTERLACE_NONE, - PNG_COMPRESSION_TYPE_BASE, PNG_FILTER_TYPE_BASE); - doing = "write info"; - png_write_info(png_ptr, info_ptr); - doing = "write image"; - png_write_image(png_ptr, rows); - doing = "write end"; - png_write_end(png_ptr, NULL); - doing = "write destroy structs"; - png_destroy_write_struct(&png_ptr, &info_ptr); - - fclose( fp ); - return 0; - -fail: - errMsg("writePng","Write_png: could not "<<doing<<" !"); - if(fp) fclose( fp ); - if(png_ptr || info_ptr) png_destroy_write_struct(&png_ptr, &info_ptr); - return -1; -} -#else // NOPNG -// fallback - write ppm -int writePng(const char *fileName, unsigned char **rowsp, int w, int h) -{ - gzFile gzf; - string filentemp(fileName); - // remove suffix - if((filentemp.length()>4) && (filentemp[filentemp.length()-4]=='.')) { - filentemp[filentemp.length()-4] = '\0'; - } - std::ostringstream filennew; - filennew << filentemp.c_str(); - filennew << ".ppm.gz"; - - gzf = gzopen(filennew.str().c_str(), "wb9"); - if(!gzf) goto fail; - - gzprintf(gzf,"P6\n%d %d\n255\n",w,h); - // output binary pixels - for(int j=0;j<h;j++) { - for(int i=0;i<h;i++) { - // remove alpha values - gzwrite(gzf,&rowsp[j][i*4],3); - } - } - - gzclose( gzf ); - errMsg("writePng/ppm","Write_png/ppm: wrote to "<<filennew.str()<<"."); - return 0; - -fail: - errMsg("writePng/ppm","Write_png/ppm: could not write to "<<filennew.str()<<" !"); - return -1; -} -#endif // NOPNG - - -//----------------------------------------------------------------------------- -// helper function to determine current time -myTime_t getTime() -{ - myTime_t ret = 0; -#ifdef WIN32 - LARGE_INTEGER liTimerFrequency; - QueryPerformanceFrequency(&liTimerFrequency); - LARGE_INTEGER liLastTime; - QueryPerformanceCounter(&liLastTime); - ret = (INT)( ((double)liLastTime.QuadPart / liTimerFrequency.QuadPart)*1000 ); // - mFirstTime; -#else - struct timeval tv; - struct timezone tz; - tz.tz_minuteswest = 0; - tz.tz_dsttime = 0; - gettimeofday(&tv,&tz); - ret = (tv.tv_sec*1000)+(tv.tv_usec/1000); //-mFirstTime; -#endif - return (myTime_t)ret; -} -//----------------------------------------------------------------------------- -// convert time to readable string -string getTimeString(myTime_t usecs) { - std::ostringstream ret; - //myTime_t us = usecs % 1000; - myTime_t ms = (myTime_t)( (double)usecs / (60.0*1000.0) ); - myTime_t ss = (myTime_t)( ((double)usecs / 1000.0) - ((double)ms*60.0) ); - int ps = (int)( ((double)usecs - (double)ss*1000.0)/10.0 ); - - //ret.setf(ios::showpoint|ios::fixed); - //ret.precision(5); ret.width(7); - - if(ms>0) { - ret << ms<<"m"<< ss<<"s" ; - } else { - if(ps>0) { - ret << ss<<"."; - if(ps<10) { ret <<"0"; } - ret <<ps<<"s" ; - } else { - ret << ss<<"s" ; - } - } - return ret.str(); -} - -//! helper to check if a bounding box was specified in the right way -bool checkBoundingBox(ntlVec3Gfx s, ntlVec3Gfx e, string checker) { - if( (s[0]>e[0]) || - (s[1]>e[1]) || - (s[2]>e[2]) ) { - errFatal("checkBoundingBox","Check by '"<<checker<<"' for BB "<<s<<":"<<e<<" failed! Aborting...",SIMWORLD_INITERROR); - return 1; - } - return 0; -} - - - -//----------------------------------------------------------------------------- -// debug message output - -static string col_black ( "\033[0;30m"); -static string col_dark_gray ( "\033[1;30m"); -static string col_bright_gray ( "\033[0;37m"); -static string col_red ( "\033[0;31m"); -static string col_bright_red ( "\033[1;31m"); -static string col_green ( "\033[0;32m"); -static string col_bright_green ( "\033[1;32m"); -static string col_bright_yellow ( "\033[1;33m"); -static string col_yellow ( "\033[0;33m"); -static string col_cyan ( "\033[0;36m"); -static string col_bright_cyan ( "\033[1;36m"); -static string col_purple ( "\033[0;35m"); -static string col_bright_purple ( "\033[1;35m"); -static string col_neutral ( "\033[0m"); -static string col_std = col_bright_gray; - -std::ostringstream globOutstr; -bool globOutstrForce=false; -#define DM_NONE 100 -void messageOutputForce(string from) { - bool org = globOutstrForce; - globOutstrForce = true; - messageOutputFunc(from, DM_NONE, "\n", 0); - globOutstrForce = org; -} - -void messageOutputFunc(string from, int id, string msg, myTime_t interval) { - // fast skip - if((id!=DM_FATAL)&&(gDebugLevel<=0)) return; - - if(interval>0) { - myTime_t currTime = getTime(); - if((currTime - globalIntervalTime)>interval) { - globalIntervalTime = getTime(); - } else { - return; - } - } - - // colors off? - if( (globalColorSetting == -1) || // off for e.g. win32 - ((globalColorSetting==1) && ((id==DM_FATAL)||( getenv("ELBEEM_NOCOLOROUT") )) ) - ) { - // only reset once - col_std = col_black = col_dark_gray = col_bright_gray = - col_red = col_bright_red = col_green = - col_bright_green = col_bright_yellow = - col_yellow = col_cyan = col_bright_cyan = - col_purple = col_bright_purple = col_neutral = ""; - globalColorSetting = 0; - } - - std::ostringstream sout; - if(id==DM_DIRECT) { - sout << msg; - } else { - sout << col_cyan<< from; - switch(id) { - case DM_MSG: - sout << col_std << " message:"; - break; - case DM_NOTIFY: - sout << col_bright_cyan << " note:" << col_std; - break; - case DM_IMPORTANT: - sout << col_yellow << " important:" << col_std; - break; - case DM_WARNING: - sout << col_bright_red << " warning:" << col_std; - break; - case DM_ERROR: - sout << col_red << " error:" << col_red; - break; - case DM_FATAL: - sout << col_red << " fatal("<<gElbeemState<<"):" << col_red; - break; - case DM_NONE: - // only internal debugging msgs - break; - default: - // this shouldnt happen... - sout << col_red << " --- messageOutputFunc error: invalid id ("<<id<<") --- aborting... \n\n" << col_std; - break; - } - sout <<" "<< msg << col_std; - } - - if(id==DM_FATAL) { - strncpy(gElbeemErrorString,sout.str().c_str(), 256); - // dont print? - if(gDebugLevel==0) return; - sout << "\n"; // add newline for output - } - - // determine output - file==1/stdout==0 / globstr==2 - char filen[256]; - strcpy(filen,"debug_unini.txt"); - int fileout = false; -#if ELBEEM_MPI==1 - std::ostringstream mpin; - if(glob_mpindex>=0) { - mpin << "elbeem_log_"<< glob_mpindex <<".txt"; - } else { - mpin << "elbeem_log_ini.txt"; - } - fileout = 1; - strncpy(filen, mpin.str().c_str(),255); filen[255]='\0'; -#else - strncpy(filen, "elbeem_debug_log.txt",255); -#endif - -#ifdef WIN32 - // windows causes trouble with direct output - fileout = 1; -#endif // WIN32 - -#if PARALLEL==1 - fileout = 2;// buffer out, switch off again... - if(globOutstrForce) fileout=1; -#endif - if(getenv("ELBEEM_FORCESTDOUT")) { - fileout = 0;// always direct out - } - //fprintf(stdout,"out deb %d, %d, '%s',l%d \n",globOutstrForce,fileout, filen, globOutstr.str().size() ); - -#if PARALLEL==1 -#pragma omp critical -#endif // PARALLEL==1 - { - if(fileout==1) { - // debug level is >0 anyway, so write to file... - FILE *logf = fopen(filen,"a+"); - // dont complain anymore here... - if(logf) { - if(globOutstrForce) { - fprintf(logf, "%s",globOutstr.str().c_str() ); - globOutstr.str(""); // reset - } - fprintf(logf, "%s",sout.str().c_str() ); - fclose(logf); - } - } else if(fileout==2) { - globOutstr << sout.str(); - } else { - // normal stdout output - fprintf(stdout, "%s",sout.str().c_str() ); - if(id!=DM_DIRECT) fflush(stdout); - } - } // omp crit -} - -// helper functions from external program using elbeem lib (e.g. Blender) -/* set gDebugLevel according to env. var */ -extern "C" -void elbeemCheckDebugEnv(void) { - const char *strEnvName = "BLENDER_ELBEEMDEBUG"; - const char *strEnvName2 = "ELBEEM_DEBUGLEVEL"; - if(globalFirstEnvCheck) return; - - if(getenv(strEnvName)) { - gDebugLevel = atoi(getenv(strEnvName)); - if(gDebugLevel>0) debMsgStd("performElbeemSimulation",DM_NOTIFY,"Using envvar '"<<strEnvName<<"'='"<<getenv(strEnvName)<<"', debugLevel set to: "<<gDebugLevel<<"\n", 1); - } - if(getenv(strEnvName2)) { - gDebugLevel = atoi(getenv(strEnvName2)); - if(gDebugLevel>0) debMsgStd("performElbeemSimulation",DM_NOTIFY,"Using envvar '"<<strEnvName2<<"'='"<<getenv(strEnvName2)<<"', debugLevel set to: "<<gDebugLevel<<"\n", 1); - } - if(gDebugLevel< 0) gDebugLevel = 0; - if(gDebugLevel>10) gDebugLevel = 0; // only use valid values - globalFirstEnvCheck = 1; -} - -/* elbeem debug output function */ -extern "C" -void elbeemDebugOut(char *msg) { - elbeemCheckDebugEnv(); - // external messages default to debug level 5... - if(gDebugLevel<5) return; - // delegate to messageOutputFunc - messageOutputFunc("[External]",DM_MSG,msg,0); -} - -/* set elbeem debug output level (0=off to 10=full on) */ -extern "C" -void elbeemSetDebugLevel(int level) { - if(level<0) level=0; - if(level>10) level=10; - gDebugLevel=level; -} - - -/* estimate how much memory a given setup will require */ -#include "solver_interface.h" - -extern "C" -double elbeemEstimateMemreq(int res, - float sx, float sy, float sz, - int refine, char *retstr) { - int resx = res, resy = res, resz = res; - // dont use real coords, just place from 0.0 to sizeXYZ - ntlVec3Gfx vgs(0.0), vge(sx,sy,sz); - initGridSizes( resx,resy,resz, vgs,vge, refine, 0); - - double memreq = -1.0; - string memreqStr(""); - // ignore farfield for now... - calculateMemreqEstimate(resx,resy,resz, refine, 0., &memreq, NULL, &memreqStr ); - - if(retstr) { - // copy at max. 32 characters - strncpy(retstr, memreqStr.c_str(), 32 ); - retstr[31] = '\0'; - } - return memreq; -} - - - diff --git a/intern/elbeem/intern/utilities.h b/intern/elbeem/intern/utilities.h deleted file mode 100644 index 274862b93b4..00000000000 --- a/intern/elbeem/intern/utilities.h +++ /dev/null @@ -1,205 +0,0 @@ -/** \file - * \ingroup elbeem - */ -/****************************************************************************** - * - * El'Beem - Free Surface Fluid Simulation with the Lattice Boltzmann Method - * Copyright 2003-2006 Nils Thuerey - * - * Global C style utility funcions - * - *****************************************************************************/ -#ifndef UTILITIES_H -#include "ntl_vector3dim.h" - - -/* debugging outputs , debug level 0 (off) to 10 (max) */ -#ifdef ELBEEM_PLUGIN -#ifdef DEBUG -#undef DEBUG -#endif -#define DEBUG 0 -#else // ELBEEM_PLUGIN -#define DEBUG 10 -#endif // ELBEEM_PLUGIN -extern "C" int gDebugLevel; - - -// time measurements -typedef unsigned long myTime_t; - - -// state of the simulation world -// default -#define SIMWORLD_INVALID 0 -// performing init -#define SIMWORLD_INITIALIZING 1 -// after init, before starting simulation -#define SIMWORLD_INITED 2 -// stop of the simulation run, can be continued later -#define SIMWORLD_STOP 3 -// error during init -#define SIMWORLD_INITERROR -1 -// error during simulation -#define SIMWORLD_PANIC -2 -// general error -#define SIMWORLD_GENERICERROR -3 - -// access global state of elbeem simulator -void setElbeemState(int set); -int getElbeemState(void); -int isSimworldOk(void); - -// access elbeem simulator error string -void setElbeemErrorString(const char* set); -char* getElbeemErrorString(void); - - -/* debug output function */ -#define DM_MSG 1 -#define DM_NOTIFY 2 -#define DM_IMPORTANT 3 -#define DM_WARNING 4 -#define DM_ERROR 5 -#define DM_DIRECT 6 -#define DM_FATAL 7 -void messageOutputFunc(string from, int id, string msg, myTime_t interval); - -/* debugging messages defines */ -#ifdef DEBUG -#if LBM_PRECISION==2 -#define MSGSTREAM std::ostringstream msg; msg.precision(15); msg.width(17); -#else -#define MSGSTREAM std::ostringstream msg; msg.precision(7); msg.width(9); -#endif - -# define debMsgDirect(mStr) if(gDebugLevel>0) { std::ostringstream msg; msg << mStr; messageOutputFunc(string(""), DM_DIRECT, msg.str(), 0); } -# define debMsgStd(from,id,mStr,level) if(gDebugLevel>=level) { MSGSTREAM; msg << mStr <<"\n"; messageOutputFunc(from, id, msg.str(), 0); } -# define debMsgNnl(from,id,mStr,level) if(gDebugLevel>=level) { MSGSTREAM; msg << mStr ; messageOutputFunc(from, id, msg.str(), 0); } -# define debMsgInter(from,id,mStr,level, interval) if(gDebugLevel>=level) { MSGSTREAM; msg << mStr <<"\n"; messageOutputFunc(from, id, msg.str(), interval); } -# define debugOut(mStr,level) if(gDebugLevel>=level) { debMsgStd("D",DM_MSG,mStr,level); } -# define debugOutNnl(mStr,level) if(gDebugLevel>=level) { debMsgNnl("D",DM_MSG,mStr,level); } -# define debugOutInter(mStr,level, interval) debMsgInter("D",DM_MSG ,mStr,level, interval); -/* Error output function */ -#define errMsg(from,mStr) if(gDebugLevel>0){ MSGSTREAM; msg << mStr <<"\n"; messageOutputFunc(from, DM_ERROR, msg.str(), 0); } -#define warnMsg(from,mStr) if(gDebugLevel>0){ MSGSTREAM; msg << mStr <<"\n"; messageOutputFunc(from, DM_WARNING, msg.str(), 0); } - -#else -// no messages at all... -# define debMsgDirect(mStr) -# define debMsgStd(from,id,mStr,level) -# define debMsgNnl(from,id,mStr,level) -# define debMsgInter(from,id,mStr,level, interval) -# define debugOut(mStr,level) -# define debugOutNnl(mStr,level) -# define debugOutInter(mStr,level, interval) -# define errMsg(from,mStr) -# define warnMsg(from,mStr) -#endif - -#define errorOut(mStr) { errMsg("D",mStr); } - -// fatal errors - have to be handled -#define errFatal(from,mStr,errCode) { \ - setElbeemState(errCode); \ - MSGSTREAM; msg << mStr; \ - messageOutputFunc(from, DM_FATAL, msg.str(), 0); \ -} - - -//! helper function that converts a string to integer -int convertString2Int(const char *str, int alt); - -//! helper function that converts a flag field to a readable integer -string convertFlags2String(int flags); - -//! get the current system time -myTime_t getTime(); -//! convert time to readable string -string getTimeString(myTime_t usecs); - -//! helper to check if a bounding box was specified in the right way -bool checkBoundingBox(ntlVec3Gfx s, ntlVec3Gfx e, string checker); - -//! reset color output for elbeem init -void resetGlobalColorSetting(); - - -/*! print some vector from 3 values e.g. for ux,uy,uz */ -#define PRINT_VEC(x,y,z) " ["<<(x)<<","<<(y)<<","<<(z)<<"] " - -/*! print some vector from 3 values e.g. for ux,uy,uz */ -#define PRINT_VEC2D(x,y) " ["<<(x)<<","<<(y)<<"] " - -/*! print l'th neighbor of i,j,k as a vector, as we need ijk all the time */ -#define PRINT_IJK_NBL PRINT_VEC(i+D::dfVecX[l],j+D::dfVecY[l],k+D::dfVecZ[l]) - -/*! print i,j,k as a vector, as we need ijk all the time */ -#define PRINT_IJK PRINT_VEC(i,j,k) - -/*! print i,j,k as a vector, as we need ijk all the time */ -#define PRINT_IJ PRINT_VEC2D(i,j) - -/*! print some vector from 3 values e.g. for ux,uy,uz */ -#define PRINT_NTLVEC(v) " ["<<(v)[0]<<","<<(v)[1]<<","<<(v)[2]<<"] " - -/*! print some vector from 3 values e.g. for ux,uy,uz */ -#define PRINT_NTLVEC2D(v) " ["<<(v)[0]<<","<<(v)[1]<<"] " - -/*! print a triangle */ -#define PRINT_TRIANGLE(t,mpV) " { "<<PRINT_VEC( (mpV[(t).getPoints()[0]][0]),(mpV[(t).getPoints()[0]][1]),(mpV[(t).getPoints()[0]][2]) )<<\ - PRINT_VEC( (mpV[(t).getPoints()[1]][0]),(mpV[(t).getPoints()[1]][1]),(mpV[(t).getPoints()[1]][2]) )<<" | "<<\ - PRINT_VEC( (mpV[(t).getPoints()[2]][0]),(mpV[(t).getPoints()[2]][1]),(mpV[(t).getPoints()[2]][2]) )<<" } " - - -// write png image -int writePng(const char *fileName, unsigned char **rowsp, int w, int h); - -/* some useful templated functions - * may require some operators for the classes - */ - -/* minimum */ -#ifdef MIN -#undef MIN -#endif -template < class T > -inline T -MIN( T a, T b ) -{ return (a < b) ? a : b ; } - -/* maximum */ -#ifdef MAX -#undef MAX -#endif -template < class T > -inline T -MAX( T a, T b ) -{ return (a < b) ? b : a ; } - -/* sign of the value */ -template < class T > -inline T -SIGNUM( T a ) -{ return (0 < a) ? 1 : -1 ; } - -/* sign, returns -1,0,1 depending on sign/value=0 */ -template < class T > -inline T -SIGNUM0( T a ) -{ return (0 < a) ? 1 : ( a < 0 ? -1 : 0 ) ; } - -/* round to nearest integer */ -inline int -ROUND(double d) -{ return int(d + 0.5); } - -/* square function */ -template < class T > -inline T -SQUARE( T a ) -{ return a*a; } - - -#define UTILITIES_H -#endif |