diff --git a/AMDiS/AUTHORS b/AMDiS/AUTHORS new file mode 100644 index 0000000000000000000000000000000000000000..e69de29bb2d1d6434b8b29ae775ad8c2e48c5391 diff --git a/AMDiS/COPYING b/AMDiS/COPYING new file mode 100644 index 0000000000000000000000000000000000000000..60549be514af76c5db0c17ce6bbe01b2f81e2d9e --- /dev/null +++ b/AMDiS/COPYING @@ -0,0 +1,340 @@ + 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 + + 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) 19yy <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., 59 Temple Place, Suite 330, Boston, MA 02111-1307 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) 19yy 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/AMDiS/ChangeLog b/AMDiS/ChangeLog new file mode 100644 index 0000000000000000000000000000000000000000..99d49802ef309f4c19c4fce983eb7f3f5eba474f --- /dev/null +++ b/AMDiS/ChangeLog @@ -0,0 +1,17 @@ +28.03.2006: init file: + <myProblem>->output->serialize adapt info: 0/1 +28.03.2006: FileWriterInterface changed: + writeFiles(double time, bool force) -> + writeFiles(AdaptInfo *adaptInfo, bool force) +27.03.2006: GERSMarker corrected +23.03.2006: BasisFunction::getDOFIndices() -> BasisFunction::getLocalIndices() + both functions do the same -> getDOFIndices depricated +15.03.2006: parallel AMDiS: + DualTraverse generalized +14.03.2006: parallel AMDiS: + MeshStructure.h and .cc added. + (-> transfer mesh tree via MPI) +13.03.2006: parallel AMDiS: + EmptyElementData.h added. + (-> marks elements belonging to processors myRank region) + diff --git a/AMDiS/INSTALL b/AMDiS/INSTALL new file mode 100644 index 0000000000000000000000000000000000000000..23e5f25d0e5f85798dcfb368ecb2f04f59777f61 --- /dev/null +++ b/AMDiS/INSTALL @@ -0,0 +1,236 @@ +Installation Instructions +************************* + +Copyright (C) 1994, 1995, 1996, 1999, 2000, 2001, 2002, 2004, 2005 Free +Software Foundation, Inc. + +This file is free documentation; the Free Software Foundation gives +unlimited permission to copy, distribute and modify it. + +Basic Installation +================== + +These are generic installation instructions. + + The `configure' shell script attempts to guess correct values for +various system-dependent variables used during compilation. It uses +those values to create a `Makefile' in each directory of the package. +It may also create one or more `.h' files containing system-dependent +definitions. Finally, it creates a shell script `config.status' that +you can run in the future to recreate the current configuration, and a +file `config.log' containing compiler output (useful mainly for +debugging `configure'). + + It can also use an optional file (typically called `config.cache' +and enabled with `--cache-file=config.cache' or simply `-C') that saves +the results of its tests to speed up reconfiguring. (Caching is +disabled by default to prevent problems with accidental use of stale +cache files.) + + If you need to do unusual things to compile the package, please try +to figure out how `configure' could check whether to do them, and mail +diffs or instructions to the address given in the `README' so they can +be considered for the next release. If you are using the cache, and at +some point `config.cache' contains results you don't want to keep, you +may remove or edit it. + + The file `configure.ac' (or `configure.in') is used to create +`configure' by a program called `autoconf'. You only need +`configure.ac' if you want to change it or regenerate `configure' using +a newer version of `autoconf'. + +The simplest way to compile this package is: + + 1. `cd' to the directory containing the package's source code and type + `./configure' to configure the package for your system. If you're + using `csh' on an old version of System V, you might need to type + `sh ./configure' instead to prevent `csh' from trying to execute + `configure' itself. + + Running `configure' takes awhile. While running, it prints some + messages telling which features it is checking for. + + 2. Type `make' to compile the package. + + 3. Optionally, type `make check' to run any self-tests that come with + the package. + + 4. Type `make install' to install the programs and any data files and + documentation. + + 5. You can remove the program binaries and object files from the + source code directory by typing `make clean'. To also remove the + files that `configure' created (so you can compile the package for + a different kind of computer), type `make distclean'. There is + also a `make maintainer-clean' target, but that is intended mainly + for the package's developers. If you use it, you may have to get + all sorts of other programs in order to regenerate files that came + with the distribution. + +Compilers and Options +===================== + +Some systems require unusual options for compilation or linking that the +`configure' script does not know about. Run `./configure --help' for +details on some of the pertinent environment variables. + + You can give `configure' initial values for configuration parameters +by setting variables in the command line or in the environment. Here +is an example: + + ./configure CC=c89 CFLAGS=-O2 LIBS=-lposix + + *Note Defining Variables::, for more details. + +Compiling For Multiple Architectures +==================================== + +You can compile the package for more than one kind of computer at the +same time, by placing the object files for each architecture in their +own directory. To do this, you must use a version of `make' that +supports the `VPATH' variable, such as GNU `make'. `cd' to the +directory where you want the object files and executables to go and run +the `configure' script. `configure' automatically checks for the +source code in the directory that `configure' is in and in `..'. + + If you have to use a `make' that does not support the `VPATH' +variable, you have to compile the package for one architecture at a +time in the source code directory. After you have installed the +package for one architecture, use `make distclean' before reconfiguring +for another architecture. + +Installation Names +================== + +By default, `make install' installs the package's commands under +`/usr/local/bin', include files under `/usr/local/include', etc. You +can specify an installation prefix other than `/usr/local' by giving +`configure' the option `--prefix=PREFIX'. + + You can specify separate installation prefixes for +architecture-specific files and architecture-independent files. If you +pass the option `--exec-prefix=PREFIX' to `configure', the package uses +PREFIX as the prefix for installing programs and libraries. +Documentation and other data files still use the regular prefix. + + In addition, if you use an unusual directory layout you can give +options like `--bindir=DIR' to specify different values for particular +kinds of files. Run `configure --help' for a list of the directories +you can set and what kinds of files go in them. + + If the package supports it, you can cause programs to be installed +with an extra prefix or suffix on their names by giving `configure' the +option `--program-prefix=PREFIX' or `--program-suffix=SUFFIX'. + +Optional Features +================= + +Some packages pay attention to `--enable-FEATURE' options to +`configure', where FEATURE indicates an optional part of the package. +They may also pay attention to `--with-PACKAGE' options, where PACKAGE +is something like `gnu-as' or `x' (for the X Window System). The +`README' should mention any `--enable-' and `--with-' options that the +package recognizes. + + For packages that use the X Window System, `configure' can usually +find the X include and library files automatically, but if it doesn't, +you can use the `configure' options `--x-includes=DIR' and +`--x-libraries=DIR' to specify their locations. + +Specifying the System Type +========================== + +There may be some features `configure' cannot figure out automatically, +but needs to determine by the type of machine the package will run on. +Usually, assuming the package is built to be run on the _same_ +architectures, `configure' can figure that out, but if it prints a +message saying it cannot guess the machine type, give it the +`--build=TYPE' option. TYPE can either be a short name for the system +type, such as `sun4', or a canonical name which has the form: + + CPU-COMPANY-SYSTEM + +where SYSTEM can have one of these forms: + + OS KERNEL-OS + + See the file `config.sub' for the possible values of each field. If +`config.sub' isn't included in this package, then this package doesn't +need to know the machine type. + + If you are _building_ compiler tools for cross-compiling, you should +use the option `--target=TYPE' to select the type of system they will +produce code for. + + If you want to _use_ a cross compiler, that generates code for a +platform different from the build platform, you should specify the +"host" platform (i.e., that on which the generated programs will +eventually be run) with `--host=TYPE'. + +Sharing Defaults +================ + +If you want to set default values for `configure' scripts to share, you +can create a site shell script called `config.site' that gives default +values for variables like `CC', `cache_file', and `prefix'. +`configure' looks for `PREFIX/share/config.site' if it exists, then +`PREFIX/etc/config.site' if it exists. Or, you can set the +`CONFIG_SITE' environment variable to the location of the site script. +A warning: not all `configure' scripts look for a site script. + +Defining Variables +================== + +Variables not defined in a site shell script can be set in the +environment passed to `configure'. However, some packages may run +configure again during the build, and the customized values of these +variables may be lost. In order to avoid this problem, you should set +them in the `configure' command line, using `VAR=value'. For example: + + ./configure CC=/usr/local2/bin/gcc + +causes the specified `gcc' to be used as the C compiler (unless it is +overridden in the site shell script). Here is a another example: + + /bin/bash ./configure CONFIG_SHELL=/bin/bash + +Here the `CONFIG_SHELL=/bin/bash' operand causes subsequent +configuration-related scripts to be executed by `/bin/bash'. + +`configure' Invocation +====================== + +`configure' recognizes the following options to control how it operates. + +`--help' +`-h' + Print a summary of the options to `configure', and exit. + +`--version' +`-V' + Print the version of Autoconf used to generate the `configure' + script, and exit. + +`--cache-file=FILE' + Enable the cache: use and save the results of the tests in FILE, + traditionally `config.cache'. FILE defaults to `/dev/null' to + disable caching. + +`--config-cache' +`-C' + Alias for `--cache-file=config.cache'. + +`--quiet' +`--silent' +`-q' + Do not print messages saying which checks are being made. To + suppress all normal output, redirect it to `/dev/null' (any error + messages will still be shown). + +`--srcdir=DIR' + Look for the package's source code in directory DIR. Usually + `configure' can determine that directory automatically. + +`configure' also accepts some other, not widely useful, options. Run +`configure --help' for more details. + diff --git a/AMDiS/Makefile.am b/AMDiS/Makefile.am new file mode 100644 index 0000000000000000000000000000000000000000..a57b5e3b862a204334703ce48a8206f35d2537fd --- /dev/null +++ b/AMDiS/Makefile.am @@ -0,0 +1,3 @@ +SUBDIRS = lib bin + +EXTRA_DIST = demo diff --git a/AMDiS/Makefile.in b/AMDiS/Makefile.in new file mode 100644 index 0000000000000000000000000000000000000000..a5db81865b094b4e2bc6529d354f8e85a8eb84ae --- /dev/null +++ b/AMDiS/Makefile.in @@ -0,0 +1,605 @@ +# Makefile.in generated by automake 1.9.6 from Makefile.am. +# @configure_input@ + +# Copyright (C) 1994, 1995, 1996, 1997, 1998, 1999, 2000, 2001, 2002, +# 2003, 2004, 2005 Free Software Foundation, Inc. +# This Makefile.in is free software; the Free Software Foundation +# gives unlimited permission to copy and/or distribute it, +# with or without modifications, as long as this notice is preserved. + +# This program is distributed in the hope that it will be useful, +# but WITHOUT ANY WARRANTY, to the extent permitted by law; without +# even the implied warranty of MERCHANTABILITY or FITNESS FOR A +# PARTICULAR PURPOSE. + +@SET_MAKE@ +srcdir = @srcdir@ +top_srcdir = @top_srcdir@ +VPATH = @srcdir@ +pkgdatadir = $(datadir)/@PACKAGE@ +pkglibdir = $(libdir)/@PACKAGE@ +pkgincludedir = $(includedir)/@PACKAGE@ +top_builddir = . +am__cd = CDPATH="$${ZSH_VERSION+.}$(PATH_SEPARATOR)" && cd +INSTALL = @INSTALL@ +install_sh_DATA = $(install_sh) -c -m 644 +install_sh_PROGRAM = $(install_sh) -c +install_sh_SCRIPT = $(install_sh) -c +INSTALL_HEADER = $(INSTALL_DATA) +transform = $(program_transform_name) +NORMAL_INSTALL = : +PRE_INSTALL = : +POST_INSTALL = : +NORMAL_UNINSTALL = : +PRE_UNINSTALL = : +POST_UNINSTALL = : +build_triplet = @build@ +host_triplet = @host@ +DIST_COMMON = README $(am__configure_deps) $(srcdir)/Makefile.am \ + $(srcdir)/Makefile.in $(top_srcdir)/configure AUTHORS COPYING \ + ChangeLog INSTALL NEWS config.guess config.sub depcomp \ + install-sh ltmain.sh missing +subdir = . +ACLOCAL_M4 = $(top_srcdir)/aclocal.m4 +am__aclocal_m4_deps = $(top_srcdir)/configure.ac +am__configure_deps = $(am__aclocal_m4_deps) $(CONFIGURE_DEPENDENCIES) \ + $(ACLOCAL_M4) +am__CONFIG_DISTCLEAN_FILES = config.status config.cache config.log \ + configure.lineno configure.status.lineno +mkinstalldirs = $(install_sh) -d +CONFIG_CLEAN_FILES = +SOURCES = +DIST_SOURCES = +RECURSIVE_TARGETS = all-recursive check-recursive dvi-recursive \ + html-recursive info-recursive install-data-recursive \ + install-exec-recursive install-info-recursive \ + install-recursive installcheck-recursive installdirs-recursive \ + pdf-recursive ps-recursive uninstall-info-recursive \ + uninstall-recursive +ETAGS = etags +CTAGS = ctags +DIST_SUBDIRS = $(SUBDIRS) +DISTFILES = $(DIST_COMMON) $(DIST_SOURCES) $(TEXINFOS) $(EXTRA_DIST) +distdir = $(PACKAGE)-$(VERSION) +top_distdir = $(distdir) +am__remove_distdir = \ + { test ! -d $(distdir) \ + || { find $(distdir) -type d ! -perm -200 -exec chmod u+w {} ';' \ + && rm -fr $(distdir); }; } +DIST_ARCHIVES = $(distdir).tar.gz +GZIP_ENV = --best +distuninstallcheck_listfiles = find . -type f -print +distcleancheck_listfiles = find . -type f -print +ACLOCAL = @ACLOCAL@ +AMDEP_FALSE = @AMDEP_FALSE@ +AMDEP_TRUE = @AMDEP_TRUE@ +AMDIS_DEBUG_FALSE = @AMDIS_DEBUG_FALSE@ +AMDIS_DEBUG_TRUE = @AMDIS_DEBUG_TRUE@ +AMDIS_INTEL_FALSE = @AMDIS_INTEL_FALSE@ +AMDIS_INTEL_TRUE = @AMDIS_INTEL_TRUE@ +AMDIS_OPENMP_FALSE = @AMDIS_OPENMP_FALSE@ +AMDIS_OPENMP_TRUE = @AMDIS_OPENMP_TRUE@ +AMTAR = @AMTAR@ +AR = @AR@ +AUTOCONF = @AUTOCONF@ +AUTOHEADER = @AUTOHEADER@ +AUTOMAKE = @AUTOMAKE@ +AWK = @AWK@ +CC = @CC@ +CCDEPMODE = @CCDEPMODE@ +CFLAGS = @CFLAGS@ +CPP = @CPP@ +CPPFLAGS = @CPPFLAGS@ +CXX = @CXX@ +CXXCPP = @CXXCPP@ +CXXDEPMODE = @CXXDEPMODE@ +CXXFLAGS = @CXXFLAGS@ +CYGPATH_W = @CYGPATH_W@ +DEFS = @DEFS@ +DEPDIR = @DEPDIR@ +ECHO = @ECHO@ +ECHO_C = @ECHO_C@ +ECHO_N = @ECHO_N@ +ECHO_T = @ECHO_T@ +EGREP = @EGREP@ +ENABLE_UMFPACK_FALSE = @ENABLE_UMFPACK_FALSE@ +ENABLE_UMFPACK_TRUE = @ENABLE_UMFPACK_TRUE@ +EXEEXT = @EXEEXT@ +F77 = @F77@ +FFLAGS = @FFLAGS@ +INSTALL_DATA = @INSTALL_DATA@ +INSTALL_PROGRAM = @INSTALL_PROGRAM@ +INSTALL_SCRIPT = @INSTALL_SCRIPT@ +INSTALL_STRIP_PROGRAM = @INSTALL_STRIP_PROGRAM@ +LDFLAGS = @LDFLAGS@ +LIBOBJS = @LIBOBJS@ +LIBS = @LIBS@ +LIBTOOL = @LIBTOOL@ +LN_S = @LN_S@ +LTLIBOBJS = @LTLIBOBJS@ +MAINT = @MAINT@ +MAINTAINER_MODE_FALSE = @MAINTAINER_MODE_FALSE@ +MAINTAINER_MODE_TRUE = @MAINTAINER_MODE_TRUE@ +MAKEINFO = @MAKEINFO@ +MPI_DIR = @MPI_DIR@ +OBJEXT = @OBJEXT@ +OPENMP_FLAG = @OPENMP_FLAG@ +PACKAGE = @PACKAGE@ +PACKAGE_BUGREPORT = @PACKAGE_BUGREPORT@ +PACKAGE_NAME = @PACKAGE_NAME@ +PACKAGE_STRING = @PACKAGE_STRING@ +PACKAGE_TARNAME = @PACKAGE_TARNAME@ +PACKAGE_VERSION = @PACKAGE_VERSION@ +PATH_SEPARATOR = @PATH_SEPARATOR@ +RANLIB = @RANLIB@ +SED = @SED@ +SET_MAKE = @SET_MAKE@ +SHELL = @SHELL@ +STRIP = @STRIP@ +USE_PARALLEL_AMDIS_FALSE = @USE_PARALLEL_AMDIS_FALSE@ +USE_PARALLEL_AMDIS_TRUE = @USE_PARALLEL_AMDIS_TRUE@ +VERSION = @VERSION@ +ac_ct_AR = @ac_ct_AR@ +ac_ct_CC = @ac_ct_CC@ +ac_ct_CXX = @ac_ct_CXX@ +ac_ct_F77 = @ac_ct_F77@ +ac_ct_RANLIB = @ac_ct_RANLIB@ +ac_ct_STRIP = @ac_ct_STRIP@ +am__fastdepCC_FALSE = @am__fastdepCC_FALSE@ +am__fastdepCC_TRUE = @am__fastdepCC_TRUE@ +am__fastdepCXX_FALSE = @am__fastdepCXX_FALSE@ +am__fastdepCXX_TRUE = @am__fastdepCXX_TRUE@ +am__include = @am__include@ +am__leading_dot = @am__leading_dot@ +am__quote = @am__quote@ +am__tar = @am__tar@ +am__untar = @am__untar@ +bindir = @bindir@ +build = @build@ +build_alias = @build_alias@ +build_cpu = @build_cpu@ +build_os = @build_os@ +build_vendor = @build_vendor@ +datadir = @datadir@ +exec_prefix = @exec_prefix@ +host = @host@ +host_alias = @host_alias@ +host_cpu = @host_cpu@ +host_os = @host_os@ +host_vendor = @host_vendor@ +includedir = @includedir@ +infodir = @infodir@ +install_sh = @install_sh@ +libdir = @libdir@ +libexecdir = @libexecdir@ +localstatedir = @localstatedir@ +mandir = @mandir@ +mkdir_p = @mkdir_p@ +oldincludedir = @oldincludedir@ +prefix = @prefix@ +program_transform_name = @program_transform_name@ +sbindir = @sbindir@ +sharedstatedir = @sharedstatedir@ +sysconfdir = @sysconfdir@ +target_alias = @target_alias@ +SUBDIRS = lib bin +EXTRA_DIST = demo +all: all-recursive + +.SUFFIXES: +am--refresh: + @: +$(srcdir)/Makefile.in: @MAINTAINER_MODE_TRUE@ $(srcdir)/Makefile.am $(am__configure_deps) + @for dep in $?; do \ + case '$(am__configure_deps)' in \ + *$$dep*) \ + echo ' cd $(srcdir) && $(AUTOMAKE) --gnu '; \ + cd $(srcdir) && $(AUTOMAKE) --gnu \ + && exit 0; \ + exit 1;; \ + esac; \ + done; \ + echo ' cd $(top_srcdir) && $(AUTOMAKE) --gnu Makefile'; \ + cd $(top_srcdir) && \ + $(AUTOMAKE) --gnu Makefile +.PRECIOUS: Makefile +Makefile: $(srcdir)/Makefile.in $(top_builddir)/config.status + @case '$?' in \ + *config.status*) \ + echo ' $(SHELL) ./config.status'; \ + $(SHELL) ./config.status;; \ + *) \ + echo ' cd $(top_builddir) && $(SHELL) ./config.status $@ $(am__depfiles_maybe)'; \ + cd $(top_builddir) && $(SHELL) ./config.status $@ $(am__depfiles_maybe);; \ + esac; + +$(top_builddir)/config.status: $(top_srcdir)/configure $(CONFIG_STATUS_DEPENDENCIES) + $(SHELL) ./config.status --recheck + +$(top_srcdir)/configure: @MAINTAINER_MODE_TRUE@ $(am__configure_deps) + cd $(srcdir) && $(AUTOCONF) +$(ACLOCAL_M4): @MAINTAINER_MODE_TRUE@ $(am__aclocal_m4_deps) + cd $(srcdir) && $(ACLOCAL) $(ACLOCAL_AMFLAGS) + +mostlyclean-libtool: + -rm -f *.lo + +clean-libtool: + -rm -rf .libs _libs + +distclean-libtool: + -rm -f libtool +uninstall-info-am: + +# This directory's subdirectories are mostly independent; you can cd +# into them and run `make' without going through this Makefile. +# To change the values of `make' variables: instead of editing Makefiles, +# (1) if the variable is set in `config.status', edit `config.status' +# (which will cause the Makefiles to be regenerated when you run `make'); +# (2) otherwise, pass the desired values on the `make' command line. +$(RECURSIVE_TARGETS): + @failcom='exit 1'; \ + for f in x $$MAKEFLAGS; do \ + case $$f in \ + *=* | --[!k]*);; \ + *k*) failcom='fail=yes';; \ + esac; \ + done; \ + dot_seen=no; \ + target=`echo $@ | sed s/-recursive//`; \ + list='$(SUBDIRS)'; for subdir in $$list; do \ + echo "Making $$target in $$subdir"; \ + if test "$$subdir" = "."; then \ + dot_seen=yes; \ + local_target="$$target-am"; \ + else \ + local_target="$$target"; \ + fi; \ + (cd $$subdir && $(MAKE) $(AM_MAKEFLAGS) $$local_target) \ + || eval $$failcom; \ + done; \ + if test "$$dot_seen" = "no"; then \ + $(MAKE) $(AM_MAKEFLAGS) "$$target-am" || exit 1; \ + fi; test -z "$$fail" + +mostlyclean-recursive clean-recursive distclean-recursive \ +maintainer-clean-recursive: + @failcom='exit 1'; \ + for f in x $$MAKEFLAGS; do \ + case $$f in \ + *=* | --[!k]*);; \ + *k*) failcom='fail=yes';; \ + esac; \ + done; \ + dot_seen=no; \ + case "$@" in \ + distclean-* | maintainer-clean-*) list='$(DIST_SUBDIRS)' ;; \ + *) list='$(SUBDIRS)' ;; \ + esac; \ + rev=''; for subdir in $$list; do \ + if test "$$subdir" = "."; then :; else \ + rev="$$subdir $$rev"; \ + fi; \ + done; \ + rev="$$rev ."; \ + target=`echo $@ | sed s/-recursive//`; \ + for subdir in $$rev; do \ + echo "Making $$target in $$subdir"; \ + if test "$$subdir" = "."; then \ + local_target="$$target-am"; \ + else \ + local_target="$$target"; \ + fi; \ + (cd $$subdir && $(MAKE) $(AM_MAKEFLAGS) $$local_target) \ + || eval $$failcom; \ + done && test -z "$$fail" +tags-recursive: + list='$(SUBDIRS)'; for subdir in $$list; do \ + test "$$subdir" = . || (cd $$subdir && $(MAKE) $(AM_MAKEFLAGS) tags); \ + done +ctags-recursive: + list='$(SUBDIRS)'; for subdir in $$list; do \ + test "$$subdir" = . || (cd $$subdir && $(MAKE) $(AM_MAKEFLAGS) ctags); \ + done + +ID: $(HEADERS) $(SOURCES) $(LISP) $(TAGS_FILES) + list='$(SOURCES) $(HEADERS) $(LISP) $(TAGS_FILES)'; \ + unique=`for i in $$list; do \ + if test -f "$$i"; then echo $$i; else echo $(srcdir)/$$i; fi; \ + done | \ + $(AWK) ' { files[$$0] = 1; } \ + END { for (i in files) print i; }'`; \ + mkid -fID $$unique +tags: TAGS + +TAGS: tags-recursive $(HEADERS) $(SOURCES) $(TAGS_DEPENDENCIES) \ + $(TAGS_FILES) $(LISP) + tags=; \ + here=`pwd`; \ + if ($(ETAGS) --etags-include --version) >/dev/null 2>&1; then \ + include_option=--etags-include; \ + empty_fix=.; \ + else \ + include_option=--include; \ + empty_fix=; \ + fi; \ + list='$(SUBDIRS)'; for subdir in $$list; do \ + if test "$$subdir" = .; then :; else \ + test ! -f $$subdir/TAGS || \ + tags="$$tags $$include_option=$$here/$$subdir/TAGS"; \ + fi; \ + done; \ + list='$(SOURCES) $(HEADERS) $(LISP) $(TAGS_FILES)'; \ + unique=`for i in $$list; do \ + if test -f "$$i"; then echo $$i; else echo $(srcdir)/$$i; fi; \ + done | \ + $(AWK) ' { files[$$0] = 1; } \ + END { for (i in files) print i; }'`; \ + if test -z "$(ETAGS_ARGS)$$tags$$unique"; then :; else \ + test -n "$$unique" || unique=$$empty_fix; \ + $(ETAGS) $(ETAGSFLAGS) $(AM_ETAGSFLAGS) $(ETAGS_ARGS) \ + $$tags $$unique; \ + fi +ctags: CTAGS +CTAGS: ctags-recursive $(HEADERS) $(SOURCES) $(TAGS_DEPENDENCIES) \ + $(TAGS_FILES) $(LISP) + tags=; \ + here=`pwd`; \ + list='$(SOURCES) $(HEADERS) $(LISP) $(TAGS_FILES)'; \ + unique=`for i in $$list; do \ + if test -f "$$i"; then echo $$i; else echo $(srcdir)/$$i; fi; \ + done | \ + $(AWK) ' { files[$$0] = 1; } \ + END { for (i in files) print i; }'`; \ + test -z "$(CTAGS_ARGS)$$tags$$unique" \ + || $(CTAGS) $(CTAGSFLAGS) $(AM_CTAGSFLAGS) $(CTAGS_ARGS) \ + $$tags $$unique + +GTAGS: + here=`$(am__cd) $(top_builddir) && pwd` \ + && cd $(top_srcdir) \ + && gtags -i $(GTAGS_ARGS) $$here + +distclean-tags: + -rm -f TAGS ID GTAGS GRTAGS GSYMS GPATH tags + +distdir: $(DISTFILES) + $(am__remove_distdir) + mkdir $(distdir) + @srcdirstrip=`echo "$(srcdir)" | sed 's|.|.|g'`; \ + topsrcdirstrip=`echo "$(top_srcdir)" | sed 's|.|.|g'`; \ + list='$(DISTFILES)'; for file in $$list; do \ + case $$file in \ + $(srcdir)/*) file=`echo "$$file" | sed "s|^$$srcdirstrip/||"`;; \ + $(top_srcdir)/*) file=`echo "$$file" | sed "s|^$$topsrcdirstrip/|$(top_builddir)/|"`;; \ + esac; \ + if test -f $$file || test -d $$file; then d=.; else d=$(srcdir); fi; \ + dir=`echo "$$file" | sed -e 's,/[^/]*$$,,'`; \ + if test "$$dir" != "$$file" && test "$$dir" != "."; then \ + dir="/$$dir"; \ + $(mkdir_p) "$(distdir)$$dir"; \ + else \ + dir=''; \ + fi; \ + if test -d $$d/$$file; then \ + if test -d $(srcdir)/$$file && test $$d != $(srcdir); then \ + cp -pR $(srcdir)/$$file $(distdir)$$dir || exit 1; \ + fi; \ + cp -pR $$d/$$file $(distdir)$$dir || exit 1; \ + else \ + test -f $(distdir)/$$file \ + || cp -p $$d/$$file $(distdir)/$$file \ + || exit 1; \ + fi; \ + done + list='$(DIST_SUBDIRS)'; for subdir in $$list; do \ + if test "$$subdir" = .; then :; else \ + test -d "$(distdir)/$$subdir" \ + || $(mkdir_p) "$(distdir)/$$subdir" \ + || exit 1; \ + distdir=`$(am__cd) $(distdir) && pwd`; \ + top_distdir=`$(am__cd) $(top_distdir) && pwd`; \ + (cd $$subdir && \ + $(MAKE) $(AM_MAKEFLAGS) \ + top_distdir="$$top_distdir" \ + distdir="$$distdir/$$subdir" \ + distdir) \ + || exit 1; \ + fi; \ + done + -find $(distdir) -type d ! -perm -777 -exec chmod a+rwx {} \; -o \ + ! -type d ! -perm -444 -links 1 -exec chmod a+r {} \; -o \ + ! -type d ! -perm -400 -exec chmod a+r {} \; -o \ + ! -type d ! -perm -444 -exec $(SHELL) $(install_sh) -c -m a+r {} {} \; \ + || chmod -R a+r $(distdir) +dist-gzip: distdir + tardir=$(distdir) && $(am__tar) | GZIP=$(GZIP_ENV) gzip -c >$(distdir).tar.gz + $(am__remove_distdir) + +dist-bzip2: distdir + tardir=$(distdir) && $(am__tar) | bzip2 -9 -c >$(distdir).tar.bz2 + $(am__remove_distdir) + +dist-tarZ: distdir + tardir=$(distdir) && $(am__tar) | compress -c >$(distdir).tar.Z + $(am__remove_distdir) + +dist-shar: distdir + shar $(distdir) | GZIP=$(GZIP_ENV) gzip -c >$(distdir).shar.gz + $(am__remove_distdir) + +dist-zip: distdir + -rm -f $(distdir).zip + zip -rq $(distdir).zip $(distdir) + $(am__remove_distdir) + +dist dist-all: distdir + tardir=$(distdir) && $(am__tar) | GZIP=$(GZIP_ENV) gzip -c >$(distdir).tar.gz + $(am__remove_distdir) + +# This target untars the dist file and tries a VPATH configuration. Then +# it guarantees that the distribution is self-contained by making another +# tarfile. +distcheck: dist + case '$(DIST_ARCHIVES)' in \ + *.tar.gz*) \ + GZIP=$(GZIP_ENV) gunzip -c $(distdir).tar.gz | $(am__untar) ;;\ + *.tar.bz2*) \ + bunzip2 -c $(distdir).tar.bz2 | $(am__untar) ;;\ + *.tar.Z*) \ + uncompress -c $(distdir).tar.Z | $(am__untar) ;;\ + *.shar.gz*) \ + GZIP=$(GZIP_ENV) gunzip -c $(distdir).shar.gz | unshar ;;\ + *.zip*) \ + unzip $(distdir).zip ;;\ + esac + chmod -R a-w $(distdir); chmod a+w $(distdir) + mkdir $(distdir)/_build + mkdir $(distdir)/_inst + chmod a-w $(distdir) + dc_install_base=`$(am__cd) $(distdir)/_inst && pwd | sed -e 's,^[^:\\/]:[\\/],/,'` \ + && dc_destdir="$${TMPDIR-/tmp}/am-dc-$$$$/" \ + && cd $(distdir)/_build \ + && ../configure --srcdir=.. --prefix="$$dc_install_base" \ + $(DISTCHECK_CONFIGURE_FLAGS) \ + && $(MAKE) $(AM_MAKEFLAGS) \ + && $(MAKE) $(AM_MAKEFLAGS) dvi \ + && $(MAKE) $(AM_MAKEFLAGS) check \ + && $(MAKE) $(AM_MAKEFLAGS) install \ + && $(MAKE) $(AM_MAKEFLAGS) installcheck \ + && $(MAKE) $(AM_MAKEFLAGS) uninstall \ + && $(MAKE) $(AM_MAKEFLAGS) distuninstallcheck_dir="$$dc_install_base" \ + distuninstallcheck \ + && chmod -R a-w "$$dc_install_base" \ + && ({ \ + (cd ../.. && umask 077 && mkdir "$$dc_destdir") \ + && $(MAKE) $(AM_MAKEFLAGS) DESTDIR="$$dc_destdir" install \ + && $(MAKE) $(AM_MAKEFLAGS) DESTDIR="$$dc_destdir" uninstall \ + && $(MAKE) $(AM_MAKEFLAGS) DESTDIR="$$dc_destdir" \ + distuninstallcheck_dir="$$dc_destdir" distuninstallcheck; \ + } || { rm -rf "$$dc_destdir"; exit 1; }) \ + && rm -rf "$$dc_destdir" \ + && $(MAKE) $(AM_MAKEFLAGS) dist \ + && rm -rf $(DIST_ARCHIVES) \ + && $(MAKE) $(AM_MAKEFLAGS) distcleancheck + $(am__remove_distdir) + @(echo "$(distdir) archives ready for distribution: "; \ + list='$(DIST_ARCHIVES)'; for i in $$list; do echo $$i; done) | \ + sed -e '1{h;s/./=/g;p;x;}' -e '$${p;x;}' +distuninstallcheck: + @cd $(distuninstallcheck_dir) \ + && test `$(distuninstallcheck_listfiles) | wc -l` -le 1 \ + || { echo "ERROR: files left after uninstall:" ; \ + if test -n "$(DESTDIR)"; then \ + echo " (check DESTDIR support)"; \ + fi ; \ + $(distuninstallcheck_listfiles) ; \ + exit 1; } >&2 +distcleancheck: distclean + @if test '$(srcdir)' = . ; then \ + echo "ERROR: distcleancheck can only run from a VPATH build" ; \ + exit 1 ; \ + fi + @test `$(distcleancheck_listfiles) | wc -l` -eq 0 \ + || { echo "ERROR: files left in build directory after distclean:" ; \ + $(distcleancheck_listfiles) ; \ + exit 1; } >&2 +check-am: all-am +check: check-recursive +all-am: Makefile +installdirs: installdirs-recursive +installdirs-am: +install: install-recursive +install-exec: install-exec-recursive +install-data: install-data-recursive +uninstall: uninstall-recursive + +install-am: all-am + @$(MAKE) $(AM_MAKEFLAGS) install-exec-am install-data-am + +installcheck: installcheck-recursive +install-strip: + $(MAKE) $(AM_MAKEFLAGS) INSTALL_PROGRAM="$(INSTALL_STRIP_PROGRAM)" \ + install_sh_PROGRAM="$(INSTALL_STRIP_PROGRAM)" INSTALL_STRIP_FLAG=-s \ + `test -z '$(STRIP)' || \ + echo "INSTALL_PROGRAM_ENV=STRIPPROG='$(STRIP)'"` install +mostlyclean-generic: + +clean-generic: + +distclean-generic: + -test -z "$(CONFIG_CLEAN_FILES)" || rm -f $(CONFIG_CLEAN_FILES) + +maintainer-clean-generic: + @echo "This command is intended for maintainers to use" + @echo "it deletes files that may require special tools to rebuild." +clean: clean-recursive + +clean-am: clean-generic clean-libtool mostlyclean-am + +distclean: distclean-recursive + -rm -f $(am__CONFIG_DISTCLEAN_FILES) + -rm -f Makefile +distclean-am: clean-am distclean-generic distclean-libtool \ + distclean-tags + +dvi: dvi-recursive + +dvi-am: + +html: html-recursive + +info: info-recursive + +info-am: + +install-data-am: + +install-exec-am: + +install-info: install-info-recursive + +install-man: + +installcheck-am: + +maintainer-clean: maintainer-clean-recursive + -rm -f $(am__CONFIG_DISTCLEAN_FILES) + -rm -rf $(top_srcdir)/autom4te.cache + -rm -f Makefile +maintainer-clean-am: distclean-am maintainer-clean-generic + +mostlyclean: mostlyclean-recursive + +mostlyclean-am: mostlyclean-generic mostlyclean-libtool + +pdf: pdf-recursive + +pdf-am: + +ps: ps-recursive + +ps-am: + +uninstall-am: uninstall-info-am + +uninstall-info: uninstall-info-recursive + +.PHONY: $(RECURSIVE_TARGETS) CTAGS GTAGS all all-am am--refresh check \ + check-am clean clean-generic clean-libtool clean-recursive \ + ctags ctags-recursive dist dist-all dist-bzip2 dist-gzip \ + dist-shar dist-tarZ dist-zip distcheck distclean \ + distclean-generic distclean-libtool distclean-recursive \ + distclean-tags distcleancheck distdir distuninstallcheck dvi \ + dvi-am html html-am info info-am install install-am \ + install-data install-data-am install-exec install-exec-am \ + install-info install-info-am install-man install-strip \ + installcheck installcheck-am installdirs installdirs-am \ + maintainer-clean maintainer-clean-generic \ + maintainer-clean-recursive mostlyclean mostlyclean-generic \ + mostlyclean-libtool mostlyclean-recursive pdf pdf-am ps ps-am \ + tags tags-recursive uninstall uninstall-am uninstall-info-am + +# Tell versions [3.59,3.63) of GNU make to not export all variables. +# Otherwise a system limit (for SysV at least) may be exceeded. +.NOEXPORT: diff --git a/AMDiS/NEWS b/AMDiS/NEWS new file mode 100644 index 0000000000000000000000000000000000000000..e69de29bb2d1d6434b8b29ae775ad8c2e48c5391 diff --git a/AMDiS/README b/AMDiS/README new file mode 100644 index 0000000000000000000000000000000000000000..afb498d00aed7803b39c3bae1df98c8aeee2322d --- /dev/null +++ b/AMDiS/README @@ -0,0 +1,92 @@ +================== Install AMDiS =================== + +To install AMDiS run the following commands: + + ./configure --prefix=`pwd` [--enable-debug] + [--enable-intel] + [--with-mpi=<MPI-DIR>] + [--with-parmetis] + + make install + +Note that for debugging your application you should enable the flag +--enable-debug. If you do not need debugging information but, instead, +your application should run as fast as possible, do not set this flag. +The runtime will increase by factor 5 to 6 without --enable-debug! + +================== Compile AMDiS on mars =================== + +1) Load the Inter compiler: + + module load icc + +2) Change to the directory AMDiS/lib/ParMetis-3.1 + +3) Compile ParMETIS with: + + make CC=icc LD=icc + +4) Change to the AMDiS directory + +5) Run the configure script: + + ./configure --prefix=`pwd` --enable-intel --enable-parmetis + + You can also enabel --enable-debug. Enabling MPI using --with-mpi + does not work on mars and it is not necessary to use this parameter + to compile AMDiS with MPI on mars. Note taht is is also possible to + compile with gcc (just omit --enable-intel), but the result is less + performant. Compiling with the Intel compiler results in a huge + number of warnings. Just ignore them. + +6) Start compiling with: + + make install + +7) To compile the demos you have to edit the Makefile in the demo + directory. At the beginning of the file you will find several + parameters, which you have to define in order to compiler the demos + properly. + + +================== Compile AMDiS on deimos =================== + +1) Load MPI support for the GNU compiler: + + module load openmpi + +2) Change to the directory AMDiS/lib/ParMetis-3.1 + +3) Compile ParMETIS with: + + make + +4) Change to the AMDiS directory + +5) Run the configure script: + + ./configure --prefix=`pwd` --with-mpi=/licsoft/libraries/openmpi/1.2.4/64bit --enable-parmetis + + You may also enable --enable-debug. + +6) Start compiling with: + + make install + +7) To compile the demos you have to edit the Makefile in the demo + directory. At the beginning of the file you will find several + parameters, which you have to define in order to compiler the demos + properly. + +================== Remake AMDiS' make system =================== + +If you have added a new source file or you want to change something +on the automake-system, you have to rerun the following commands: + + libtoolize --copy --force + + aclocal + + autoconf + + automake --copy --add-missing diff --git a/AMDiS/Radiosity/3d/GL/glu.h b/AMDiS/Radiosity/3d/GL/glu.h new file mode 100755 index 0000000000000000000000000000000000000000..8aa962d658c5fafc6b21f199c02f89f9dc68709a --- /dev/null +++ b/AMDiS/Radiosity/3d/GL/glu.h @@ -0,0 +1,533 @@ +/* $Id: glu.h,v 1.1 2005/07/27 13:28:46 weichmann Exp $ */ + +/* + * Mesa 3-D graphics library + * Version: 3.3 + * + * Copyright (C) 1995-1999 Brian Paul + * + * This library is free software; you can redistribute it and/or + * modify it under the terms of the GNU Library General Public + * License as published by the Free Software Foundation; either + * version 2 of the License, or (at your option) any later version. + * + * This library 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 + * Library General Public License for more details. + * + * You should have received a copy of the GNU Library General Public + * License along with this library; if not, write to the Free + * Software Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. + */ + + +#ifndef __glu_h__ +#define __glu_h__ + + +#if defined(USE_MGL_NAMESPACE) +#include "glu_mangle.h" +#endif + +#include "GL/gl.h" + + +#ifdef __cplusplus +extern "C" { +#endif + + + /* to facilitate clean DLL building ... */ +#if !defined(OPENSTEP) && (defined(__WIN32__) || defined(__CYGWIN32__)) +# if defined(_MSC_VER) && defined(BUILD_GLU32) /* tag specify we're building mesa as a DLL */ +# define GLUAPI __declspec(dllexport) +# elif defined(_MSC_VER) && defined(_DLL) /* tag specifying we're building for DLL runtime support */ +# define GLUAPI __declspec(dllimport) +# else /* for use with static link lib build of Win32 edition only */ +# define GLUAPI extern +# endif /* _STATIC_MESA support */ +#else +# define GLUAPI extern +#endif /* WIN32 / CYGWIN32 bracket */ + +#ifdef macintosh + #pragma enumsalwaysint on + #if PRAGMA_IMPORT_SUPPORTED + #pragma import on + #endif +#endif + +#ifndef GLUAPI +#define GLUAPI +#endif + +#ifndef GLAPIENTRY +#define GLAPIENTRY +#endif + +#ifndef GLCALLBACK +#define GLCALLBACK +#endif + + +#define GLU_VERSION_1_1 1 +#define GLU_VERSION_1_2 1 + + +#define GLU_TRUE 1 +#define GLU_FALSE 0 + + +/* Normal vectors */ +#define GLU_SMOOTH 100000 +#define GLU_FLAT 100001 +#define GLU_NONE 100002 + +/* Quadric draw styles */ +#define GLU_POINT 100010 +#define GLU_LINE 100011 +#define GLU_FILL 100012 +#define GLU_SILHOUETTE 100013 + +/* Quadric orientation */ +#define GLU_OUTSIDE 100020 +#define GLU_INSIDE 100021 + +/* Tessellator */ +#define GLU_TESS_BEGIN 100100 +#define GLU_TESS_VERTEX 100101 +#define GLU_TESS_END 100102 +#define GLU_TESS_ERROR 100103 +#define GLU_TESS_EDGE_FLAG 100104 +#define GLU_TESS_COMBINE 100105 + +#define GLU_TESS_BEGIN_DATA 100106 +#define GLU_TESS_VERTEX_DATA 100107 +#define GLU_TESS_END_DATA 100108 +#define GLU_TESS_ERROR_DATA 100109 +#define GLU_TESS_EDGE_FLAG_DATA 100110 +#define GLU_TESS_COMBINE_DATA 100111 + +/* Winding rules */ +#define GLU_TESS_WINDING_ODD 100130 +#define GLU_TESS_WINDING_NONZERO 100131 +#define GLU_TESS_WINDING_POSITIVE 100132 +#define GLU_TESS_WINDING_NEGATIVE 100133 +#define GLU_TESS_WINDING_ABS_GEQ_TWO 100134 + +/* Tessellation properties */ +#define GLU_TESS_WINDING_RULE 100140 +#define GLU_TESS_BOUNDARY_ONLY 100141 +#define GLU_TESS_TOLERANCE 100142 + +/* Tessellation errors */ +#define GLU_TESS_ERROR1 100151 /* Missing gluBeginPolygon */ +#define GLU_TESS_ERROR2 100152 /* Missing gluBeginContour */ +#define GLU_TESS_ERROR3 100153 /* Missing gluEndPolygon */ +#define GLU_TESS_ERROR4 100154 /* Missing gluEndContour */ +#define GLU_TESS_ERROR5 100155 /* */ +#define GLU_TESS_ERROR6 100156 /* */ +#define GLU_TESS_ERROR7 100157 /* */ +#define GLU_TESS_ERROR8 100158 /* */ + +/* NURBS */ +#define GLU_AUTO_LOAD_MATRIX 100200 +#define GLU_CULLING 100201 +#define GLU_PARAMETRIC_TOLERANCE 100202 +#define GLU_SAMPLING_TOLERANCE 100203 +#define GLU_DISPLAY_MODE 100204 +#define GLU_SAMPLING_METHOD 100205 +#define GLU_U_STEP 100206 +#define GLU_V_STEP 100207 + +#define GLU_PATH_LENGTH 100215 +#define GLU_PARAMETRIC_ERROR 100216 +#define GLU_DOMAIN_DISTANCE 100217 + +#define GLU_MAP1_TRIM_2 100210 +#define GLU_MAP1_TRIM_3 100211 + +#define GLU_OUTLINE_POLYGON 100240 +#define GLU_OUTLINE_PATCH 100241 + +#define GLU_NURBS_ERROR1 100251 /* spline order un-supported */ +#define GLU_NURBS_ERROR2 100252 /* too few knots */ +#define GLU_NURBS_ERROR3 100253 /* valid knot range is empty */ +#define GLU_NURBS_ERROR4 100254 /* decreasing knot sequence */ +#define GLU_NURBS_ERROR5 100255 /* knot multiplicity > spline order */ +#define GLU_NURBS_ERROR6 100256 /* endcurve() must follow bgncurve() */ +#define GLU_NURBS_ERROR7 100257 /* bgncurve() must precede endcurve() */ +#define GLU_NURBS_ERROR8 100258 /* ctrlarray or knot vector is NULL */ +#define GLU_NURBS_ERROR9 100259 /* can't draw pwlcurves */ +#define GLU_NURBS_ERROR10 100260 /* missing gluNurbsCurve() */ +#define GLU_NURBS_ERROR11 100261 /* missing gluNurbsSurface() */ +#define GLU_NURBS_ERROR12 100262 /* endtrim() must precede endsurface() */ +#define GLU_NURBS_ERROR13 100263 /* bgnsurface() must precede endsurface() */ +#define GLU_NURBS_ERROR14 100264 /* curve of improper type passed as trim curve */ +#define GLU_NURBS_ERROR15 100265 /* bgnsurface() must precede bgntrim() */ +#define GLU_NURBS_ERROR16 100266 /* endtrim() must follow bgntrim() */ +#define GLU_NURBS_ERROR17 100267 /* bgntrim() must precede endtrim()*/ +#define GLU_NURBS_ERROR18 100268 /* invalid or missing trim curve*/ +#define GLU_NURBS_ERROR19 100269 /* bgntrim() must precede pwlcurve() */ +#define GLU_NURBS_ERROR20 100270 /* pwlcurve referenced twice*/ +#define GLU_NURBS_ERROR21 100271 /* pwlcurve and nurbscurve mixed */ +#define GLU_NURBS_ERROR22 100272 /* improper usage of trim data type */ +#define GLU_NURBS_ERROR23 100273 /* nurbscurve referenced twice */ +#define GLU_NURBS_ERROR24 100274 /* nurbscurve and pwlcurve mixed */ +#define GLU_NURBS_ERROR25 100275 /* nurbssurface referenced twice */ +#define GLU_NURBS_ERROR26 100276 /* invalid property */ +#define GLU_NURBS_ERROR27 100277 /* endsurface() must follow bgnsurface() */ +#define GLU_NURBS_ERROR28 100278 /* intersecting or misoriented trim curves */ +#define GLU_NURBS_ERROR29 100279 /* intersecting trim curves */ +#define GLU_NURBS_ERROR30 100280 /* UNUSED */ +#define GLU_NURBS_ERROR31 100281 /* unconnected trim curves */ +#define GLU_NURBS_ERROR32 100282 /* unknown knot error */ +#define GLU_NURBS_ERROR33 100283 /* negative vertex count encountered */ +#define GLU_NURBS_ERROR34 100284 /* negative byte-stride */ +#define GLU_NURBS_ERROR35 100285 /* unknown type descriptor */ +#define GLU_NURBS_ERROR36 100286 /* null control point reference */ +#define GLU_NURBS_ERROR37 100287 /* duplicate point on pwlcurve */ + +/* GLU 1.3 and later */ +#define GLU_NURBS_MODE ? + + +/* Errors */ +#define GLU_INVALID_ENUM 100900 +#define GLU_INVALID_VALUE 100901 +#define GLU_OUT_OF_MEMORY 100902 +#define GLU_INCOMPATIBLE_GL_VERSION 100903 + +/* GLU 1.1 and later */ +#define GLU_VERSION 100800 +#define GLU_EXTENSIONS 100801 + + + +/*** GLU 1.0 tessellation - obsolete! ***/ + +/* Contour types */ +#define GLU_CW 100120 +#define GLU_CCW 100121 +#define GLU_INTERIOR 100122 +#define GLU_EXTERIOR 100123 +#define GLU_UNKNOWN 100124 + +/* Tessellator */ +#define GLU_BEGIN GLU_TESS_BEGIN +#define GLU_VERTEX GLU_TESS_VERTEX +#define GLU_END GLU_TESS_END +#define GLU_ERROR GLU_TESS_ERROR +#define GLU_EDGE_FLAG GLU_TESS_EDGE_FLAG + + +/* + * These are the GLU 1.1 typedefs. GLU 1.3 has different ones! + */ +#if defined(__BEOS__) + /* The BeOS does something funky and makes these typedefs in one + * of its system headers. + */ +#else + typedef struct GLUquadric GLUquadricObj; + typedef struct GLUnurbs GLUnurbsObj; + + /* FIXME: We need to implement the other 1.3 typedefs - GH */ + typedef struct GLUtesselator GLUtesselator; + typedef GLUtesselator GLUtriangulatorObj; +#endif + + + +#if defined(__BEOS__) || defined(__QUICKDRAW__) +#pragma export on +#endif + + +/* + * + * Miscellaneous functions + * + */ + +GLUAPI void GLAPIENTRY gluLookAt( GLdouble eyex, GLdouble eyey, GLdouble eyez, + GLdouble centerx, GLdouble centery, + GLdouble centerz, + GLdouble upx, GLdouble upy, GLdouble upz ); + + +GLUAPI void GLAPIENTRY gluOrtho2D( GLdouble left, GLdouble right, + GLdouble bottom, GLdouble top ); + + +GLUAPI void GLAPIENTRY gluPerspective( GLdouble fovy, GLdouble aspect, + GLdouble zNear, GLdouble zFar ); + + +GLUAPI void GLAPIENTRY gluPickMatrix( GLdouble x, GLdouble y, + GLdouble width, GLdouble height, + const GLint viewport[4] ); + +GLUAPI GLint GLAPIENTRY gluProject( GLdouble objx, GLdouble objy, GLdouble objz, + const GLdouble modelMatrix[16], + const GLdouble projMatrix[16], + const GLint viewport[4], + GLdouble *winx, GLdouble *winy, + GLdouble *winz ); + +GLUAPI GLint GLAPIENTRY gluUnProject( GLdouble winx, GLdouble winy, + GLdouble winz, + const GLdouble modelMatrix[16], + const GLdouble projMatrix[16], + const GLint viewport[4], + GLdouble *objx, GLdouble *objy, + GLdouble *objz ); + +GLUAPI const GLubyte* GLAPIENTRY gluErrorString( GLenum errorCode ); + + + +/* + * + * Mipmapping and image scaling + * + */ + +GLUAPI GLint GLAPIENTRY gluScaleImage( GLenum format, + GLint widthin, GLint heightin, + GLenum typein, const void *datain, + GLint widthout, GLint heightout, + GLenum typeout, void *dataout ); + +GLUAPI GLint GLAPIENTRY gluBuild1DMipmaps( GLenum target, GLint components, + GLint width, GLenum format, + GLenum type, const void *data ); + +GLUAPI GLint GLAPIENTRY gluBuild2DMipmaps( GLenum target, GLint components, + GLint width, GLint height, + GLenum format, + GLenum type, const void *data ); + + + +/* + * + * Quadrics + * + */ + +GLUAPI GLUquadricObj* GLAPIENTRY gluNewQuadric( void ); + +GLUAPI void GLAPIENTRY gluDeleteQuadric( GLUquadricObj *state ); + +GLUAPI void GLAPIENTRY gluQuadricDrawStyle( GLUquadricObj *quadObject, + GLenum drawStyle ); + +GLUAPI void GLAPIENTRY gluQuadricOrientation( GLUquadricObj *quadObject, + GLenum orientation ); + +GLUAPI void GLAPIENTRY gluQuadricNormals( GLUquadricObj *quadObject, + GLenum normals ); + +GLUAPI void GLAPIENTRY gluQuadricTexture( GLUquadricObj *quadObject, + GLboolean textureCoords ); + +GLUAPI void GLAPIENTRY gluQuadricCallback( GLUquadricObj *qobj, + GLenum which, + void (GLCALLBACK *fn)() ); + +GLUAPI void GLAPIENTRY gluCylinder( GLUquadricObj *qobj, + GLdouble baseRadius, + GLdouble topRadius, + GLdouble height, + GLint slices, GLint stacks ); + +GLUAPI void GLAPIENTRY gluSphere( GLUquadricObj *qobj, + GLdouble radius, GLint slices, + GLint stacks ); + +GLUAPI void GLAPIENTRY gluDisk( GLUquadricObj *qobj, + GLdouble innerRadius, GLdouble outerRadius, + GLint slices, GLint loops ); + +GLUAPI void GLAPIENTRY gluPartialDisk( GLUquadricObj *qobj, GLdouble innerRadius, + GLdouble outerRadius, GLint slices, + GLint loops, GLdouble startAngle, + GLdouble sweepAngle ); + + + +/* + * + * Nurbs + * + */ + +GLUAPI GLUnurbsObj* GLAPIENTRY gluNewNurbsRenderer( void ); + +GLUAPI void GLAPIENTRY gluDeleteNurbsRenderer( GLUnurbsObj *nobj ); + +GLUAPI void GLAPIENTRY gluLoadSamplingMatrices( GLUnurbsObj *nobj, + const GLfloat modelMatrix[16], + const GLfloat projMatrix[16], + const GLint viewport[4] ); + +GLUAPI void GLAPIENTRY gluNurbsProperty( GLUnurbsObj *nobj, GLenum property, + GLfloat value ); + +GLUAPI void GLAPIENTRY gluGetNurbsProperty( GLUnurbsObj *nobj, GLenum property, + GLfloat *value ); + +GLUAPI void GLAPIENTRY gluBeginCurve( GLUnurbsObj *nobj ); + +GLUAPI void GLAPIENTRY gluEndCurve( GLUnurbsObj * nobj ); + +GLUAPI void GLAPIENTRY gluNurbsCurve( GLUnurbsObj *nobj, GLint nknots, + GLfloat *knot, GLint stride, + GLfloat *ctlarray, GLint order, + GLenum type ); + +GLUAPI void GLAPIENTRY gluBeginSurface( GLUnurbsObj *nobj ); + +GLUAPI void GLAPIENTRY gluEndSurface( GLUnurbsObj * nobj ); + +GLUAPI void GLAPIENTRY gluNurbsSurface( GLUnurbsObj *nobj, + GLint sknot_count, GLfloat *sknot, + GLint tknot_count, GLfloat *tknot, + GLint s_stride, GLint t_stride, + GLfloat *ctlarray, + GLint sorder, GLint torder, + GLenum type ); + +GLUAPI void GLAPIENTRY gluBeginTrim( GLUnurbsObj *nobj ); + +GLUAPI void GLAPIENTRY gluEndTrim( GLUnurbsObj *nobj ); + +GLUAPI void GLAPIENTRY gluPwlCurve( GLUnurbsObj *nobj, GLint count, + GLfloat *array, GLint stride, + GLenum type ); + +GLUAPI void GLAPIENTRY gluNurbsCallback( GLUnurbsObj *nobj, GLenum which, + void (GLCALLBACK *fn)() ); + + + +/* + * + * Polygon tessellation + * + */ + +GLUAPI GLUtesselator* GLAPIENTRY gluNewTess( void ); + +GLUAPI void GLAPIENTRY gluDeleteTess( GLUtesselator *tobj ); + +GLUAPI void GLAPIENTRY gluTessBeginPolygon( GLUtesselator *tobj, + void *polygon_data ); + +GLUAPI void GLAPIENTRY gluTessBeginContour( GLUtesselator *tobj ); + +GLUAPI void GLAPIENTRY gluTessVertex( GLUtesselator *tobj, GLdouble coords[3], + void *vertex_data ); + +GLUAPI void GLAPIENTRY gluTessEndContour( GLUtesselator *tobj ); + +GLUAPI void GLAPIENTRY gluTessEndPolygon( GLUtesselator *tobj ); + +GLUAPI void GLAPIENTRY gluTessProperty( GLUtesselator *tobj, GLenum which, + GLdouble value ); + +GLUAPI void GLAPIENTRY gluTessNormal( GLUtesselator *tobj, GLdouble x, + GLdouble y, GLdouble z ); + +GLUAPI void GLAPIENTRY gluTessCallback( GLUtesselator *tobj, GLenum which, + void (GLCALLBACK *fn)() ); + +GLUAPI void GLAPIENTRY gluGetTessProperty( GLUtesselator *tobj, GLenum which, + GLdouble *value ); + +/* + * + * Obsolete 1.0 tessellation functions + * + */ + +GLUAPI void GLAPIENTRY gluBeginPolygon( GLUtesselator *tobj ); + +GLUAPI void GLAPIENTRY gluNextContour( GLUtesselator *tobj, GLenum type ); + +GLUAPI void GLAPIENTRY gluEndPolygon( GLUtesselator *tobj ); + + + +/* + * + * New functions in GLU 1.1 + * + */ + +GLUAPI const GLubyte* GLAPIENTRY gluGetString( GLenum name ); + + + +/* + * + * GLU 1.3 functions + * + */ + +GLUAPI GLboolean GLAPIENTRY +gluCheckExtension(const char *extName, const GLubyte *extString); + + +GLUAPI GLint GLAPIENTRY +gluBuild3DMipmaps( GLenum target, GLint internalFormat, GLsizei width, + GLsizei height, GLsizei depth, GLenum format, + GLenum type, const void *data ); + +GLUAPI GLint GLAPIENTRY +gluBuild1DMipmapLevels( GLenum target, GLint internalFormat, GLsizei width, + GLenum format, GLenum type, GLint level, GLint base, + GLint max, const void *data ); + +GLUAPI GLint GLAPIENTRY +gluBuild2DMipmapLevels( GLenum target, GLint internalFormat, GLsizei width, + GLsizei height, GLenum format, GLenum type, + GLint level, GLint base, GLint max, + const void *data ); + +GLUAPI GLint GLAPIENTRY +gluBuild3DMipmapLevels( GLenum target, GLint internalFormat, GLsizei width, + GLsizei height, GLsizei depth, GLenum format, + GLenum type, GLint level, GLint base, GLint max, + const void *data ); + +GLUAPI GLint GLAPIENTRY +gluUnProject4( GLdouble winx, GLdouble winy, GLdouble winz, GLdouble clipw, + const GLdouble modelMatrix[16], const GLdouble projMatrix[16], + const GLint viewport[4], GLclampd zNear, GLclampd zFar, + GLdouble *objx, GLdouble *objy, GLdouble *objz, + GLdouble *objw ); + + + +#if defined(__BEOS__) || defined(__QUICKDRAW__) +#pragma export off +#endif + + +#ifdef macintosh + #pragma enumsalwaysint reset + #if PRAGMA_IMPORT_SUPPORTED + #pragma import off + #endif +#endif + + +#ifdef __cplusplus +} +#endif + + +#endif /* __glu_h__ */ diff --git a/AMDiS/aclocal.m4 b/AMDiS/aclocal.m4 new file mode 100644 index 0000000000000000000000000000000000000000..6cec4be818e153e5623e6e61d48999b94d619b09 --- /dev/null +++ b/AMDiS/aclocal.m4 @@ -0,0 +1,7278 @@ +# generated automatically by aclocal 1.9.6 -*- Autoconf -*- + +# Copyright (C) 1996, 1997, 1998, 1999, 2000, 2001, 2002, 2003, 2004, +# 2005 Free Software Foundation, Inc. +# This file is free software; the Free Software Foundation +# gives unlimited permission to copy and/or distribute it, +# with or without modifications, as long as this notice is preserved. + +# This program is distributed in the hope that it will be useful, +# but WITHOUT ANY WARRANTY, to the extent permitted by law; without +# even the implied warranty of MERCHANTABILITY or FITNESS FOR A +# PARTICULAR PURPOSE. + +# libtool.m4 - Configure libtool for the host system. -*-Autoconf-*- + +# serial 48 AC_PROG_LIBTOOL + + +# AC_PROVIDE_IFELSE(MACRO-NAME, IF-PROVIDED, IF-NOT-PROVIDED) +# ----------------------------------------------------------- +# If this macro is not defined by Autoconf, define it here. +m4_ifdef([AC_PROVIDE_IFELSE], + [], + [m4_define([AC_PROVIDE_IFELSE], + [m4_ifdef([AC_PROVIDE_$1], + [$2], [$3])])]) + + +# AC_PROG_LIBTOOL +# --------------- +AC_DEFUN([AC_PROG_LIBTOOL], +[AC_REQUIRE([_AC_PROG_LIBTOOL])dnl +dnl If AC_PROG_CXX has already been expanded, run AC_LIBTOOL_CXX +dnl immediately, otherwise, hook it in at the end of AC_PROG_CXX. + AC_PROVIDE_IFELSE([AC_PROG_CXX], + [AC_LIBTOOL_CXX], + [define([AC_PROG_CXX], defn([AC_PROG_CXX])[AC_LIBTOOL_CXX + ])]) +dnl And a similar setup for Fortran 77 support + AC_PROVIDE_IFELSE([AC_PROG_F77], + [AC_LIBTOOL_F77], + [define([AC_PROG_F77], defn([AC_PROG_F77])[AC_LIBTOOL_F77 +])]) + +dnl Quote A][M_PROG_GCJ so that aclocal doesn't bring it in needlessly. +dnl If either AC_PROG_GCJ or A][M_PROG_GCJ have already been expanded, run +dnl AC_LIBTOOL_GCJ immediately, otherwise, hook it in at the end of both. + AC_PROVIDE_IFELSE([AC_PROG_GCJ], + [AC_LIBTOOL_GCJ], + [AC_PROVIDE_IFELSE([A][M_PROG_GCJ], + [AC_LIBTOOL_GCJ], + [AC_PROVIDE_IFELSE([LT_AC_PROG_GCJ], + [AC_LIBTOOL_GCJ], + [ifdef([AC_PROG_GCJ], + [define([AC_PROG_GCJ], defn([AC_PROG_GCJ])[AC_LIBTOOL_GCJ])]) + ifdef([A][M_PROG_GCJ], + [define([A][M_PROG_GCJ], defn([A][M_PROG_GCJ])[AC_LIBTOOL_GCJ])]) + ifdef([LT_AC_PROG_GCJ], + [define([LT_AC_PROG_GCJ], + defn([LT_AC_PROG_GCJ])[AC_LIBTOOL_GCJ])])])]) +])])# AC_PROG_LIBTOOL + + +# _AC_PROG_LIBTOOL +# ---------------- +AC_DEFUN([_AC_PROG_LIBTOOL], +[AC_REQUIRE([AC_LIBTOOL_SETUP])dnl +AC_BEFORE([$0],[AC_LIBTOOL_CXX])dnl +AC_BEFORE([$0],[AC_LIBTOOL_F77])dnl +AC_BEFORE([$0],[AC_LIBTOOL_GCJ])dnl + +# This can be used to rebuild libtool when needed +LIBTOOL_DEPS="$ac_aux_dir/ltmain.sh" + +# Always use our own libtool. +LIBTOOL='$(SHELL) $(top_builddir)/libtool' +AC_SUBST(LIBTOOL)dnl + +# Prevent multiple expansion +define([AC_PROG_LIBTOOL], []) +])# _AC_PROG_LIBTOOL + + +# AC_LIBTOOL_SETUP +# ---------------- +AC_DEFUN([AC_LIBTOOL_SETUP], +[AC_PREREQ(2.50)dnl +AC_REQUIRE([AC_ENABLE_SHARED])dnl +AC_REQUIRE([AC_ENABLE_STATIC])dnl +AC_REQUIRE([AC_ENABLE_FAST_INSTALL])dnl +AC_REQUIRE([AC_CANONICAL_HOST])dnl +AC_REQUIRE([AC_CANONICAL_BUILD])dnl +AC_REQUIRE([AC_PROG_CC])dnl +AC_REQUIRE([AC_PROG_LD])dnl +AC_REQUIRE([AC_PROG_LD_RELOAD_FLAG])dnl +AC_REQUIRE([AC_PROG_NM])dnl + +AC_REQUIRE([AC_PROG_LN_S])dnl +AC_REQUIRE([AC_DEPLIBS_CHECK_METHOD])dnl +# Autoconf 2.13's AC_OBJEXT and AC_EXEEXT macros only works for C compilers! +AC_REQUIRE([AC_OBJEXT])dnl +AC_REQUIRE([AC_EXEEXT])dnl +dnl + +AC_LIBTOOL_SYS_MAX_CMD_LEN +AC_LIBTOOL_SYS_GLOBAL_SYMBOL_PIPE +AC_LIBTOOL_OBJDIR + +AC_REQUIRE([_LT_AC_SYS_COMPILER])dnl +_LT_AC_PROG_ECHO_BACKSLASH + +case $host_os in +aix3*) + # AIX sometimes has problems with the GCC collect2 program. For some + # reason, if we set the COLLECT_NAMES environment variable, the problems + # vanish in a puff of smoke. + if test "X${COLLECT_NAMES+set}" != Xset; then + COLLECT_NAMES= + export COLLECT_NAMES + fi + ;; +esac + +# Sed substitution that helps us do robust quoting. It backslashifies +# metacharacters that are still active within double-quoted strings. +Xsed='sed -e 1s/^X//' +[sed_quote_subst='s/\([\\"\\`$\\\\]\)/\\\1/g'] + +# Same as above, but do not quote variable references. +[double_quote_subst='s/\([\\"\\`\\\\]\)/\\\1/g'] + +# Sed substitution to delay expansion of an escaped shell variable in a +# double_quote_subst'ed string. +delay_variable_subst='s/\\\\\\\\\\\$/\\\\\\$/g' + +# Sed substitution to avoid accidental globbing in evaled expressions +no_glob_subst='s/\*/\\\*/g' + +# Constants: +rm="rm -f" + +# Global variables: +default_ofile=libtool +can_build_shared=yes + +# All known linkers require a `.a' archive for static linking (except MSVC, +# which needs '.lib'). +libext=a +ltmain="$ac_aux_dir/ltmain.sh" +ofile="$default_ofile" +with_gnu_ld="$lt_cv_prog_gnu_ld" + +AC_CHECK_TOOL(AR, ar, false) +AC_CHECK_TOOL(RANLIB, ranlib, :) +AC_CHECK_TOOL(STRIP, strip, :) + +old_CC="$CC" +old_CFLAGS="$CFLAGS" + +# Set sane defaults for various variables +test -z "$AR" && AR=ar +test -z "$AR_FLAGS" && AR_FLAGS=cru +test -z "$AS" && AS=as +test -z "$CC" && CC=cc +test -z "$LTCC" && LTCC=$CC +test -z "$LTCFLAGS" && LTCFLAGS=$CFLAGS +test -z "$DLLTOOL" && DLLTOOL=dlltool +test -z "$LD" && LD=ld +test -z "$LN_S" && LN_S="ln -s" +test -z "$MAGIC_CMD" && MAGIC_CMD=file +test -z "$NM" && NM=nm +test -z "$SED" && SED=sed +test -z "$OBJDUMP" && OBJDUMP=objdump +test -z "$RANLIB" && RANLIB=: +test -z "$STRIP" && STRIP=: +test -z "$ac_objext" && ac_objext=o + +# Determine commands to create old-style static archives. +old_archive_cmds='$AR $AR_FLAGS $oldlib$oldobjs$old_deplibs' +old_postinstall_cmds='chmod 644 $oldlib' +old_postuninstall_cmds= + +if test -n "$RANLIB"; then + case $host_os in + openbsd*) + old_postinstall_cmds="$old_postinstall_cmds~\$RANLIB -t \$oldlib" + ;; + *) + old_postinstall_cmds="$old_postinstall_cmds~\$RANLIB \$oldlib" + ;; + esac + old_archive_cmds="$old_archive_cmds~\$RANLIB \$oldlib" +fi + +_LT_CC_BASENAME([$compiler]) + +# Only perform the check for file, if the check method requires it +case $deplibs_check_method in +file_magic*) + if test "$file_magic_cmd" = '$MAGIC_CMD'; then + AC_PATH_MAGIC + fi + ;; +esac + +AC_PROVIDE_IFELSE([AC_LIBTOOL_DLOPEN], enable_dlopen=yes, enable_dlopen=no) +AC_PROVIDE_IFELSE([AC_LIBTOOL_WIN32_DLL], +enable_win32_dll=yes, enable_win32_dll=no) + +AC_ARG_ENABLE([libtool-lock], + [AC_HELP_STRING([--disable-libtool-lock], + [avoid locking (might break parallel builds)])]) +test "x$enable_libtool_lock" != xno && enable_libtool_lock=yes + +AC_ARG_WITH([pic], + [AC_HELP_STRING([--with-pic], + [try to use only PIC/non-PIC objects @<:@default=use both@:>@])], + [pic_mode="$withval"], + [pic_mode=default]) +test -z "$pic_mode" && pic_mode=default + +# Use C for the default configuration in the libtool script +tagname= +AC_LIBTOOL_LANG_C_CONFIG +_LT_AC_TAGCONFIG +])# AC_LIBTOOL_SETUP + + +# _LT_AC_SYS_COMPILER +# ------------------- +AC_DEFUN([_LT_AC_SYS_COMPILER], +[AC_REQUIRE([AC_PROG_CC])dnl + +# If no C compiler was specified, use CC. +LTCC=${LTCC-"$CC"} + +# If no C compiler flags were specified, use CFLAGS. +LTCFLAGS=${LTCFLAGS-"$CFLAGS"} + +# Allow CC to be a program name with arguments. +compiler=$CC +])# _LT_AC_SYS_COMPILER + + +# _LT_CC_BASENAME(CC) +# ------------------- +# Calculate cc_basename. Skip known compiler wrappers and cross-prefix. +AC_DEFUN([_LT_CC_BASENAME], +[for cc_temp in $1""; do + case $cc_temp in + compile | *[[\\/]]compile | ccache | *[[\\/]]ccache ) ;; + distcc | *[[\\/]]distcc | purify | *[[\\/]]purify ) ;; + \-*) ;; + *) break;; + esac +done +cc_basename=`$echo "X$cc_temp" | $Xsed -e 's%.*/%%' -e "s%^$host_alias-%%"` +]) + + +# _LT_COMPILER_BOILERPLATE +# ------------------------ +# Check for compiler boilerplate output or warnings with +# the simple compiler test code. +AC_DEFUN([_LT_COMPILER_BOILERPLATE], +[ac_outfile=conftest.$ac_objext +printf "$lt_simple_compile_test_code" >conftest.$ac_ext +eval "$ac_compile" 2>&1 >/dev/null | $SED '/^$/d; /^ *+/d' >conftest.err +_lt_compiler_boilerplate=`cat conftest.err` +$rm conftest* +])# _LT_COMPILER_BOILERPLATE + + +# _LT_LINKER_BOILERPLATE +# ---------------------- +# Check for linker boilerplate output or warnings with +# the simple link test code. +AC_DEFUN([_LT_LINKER_BOILERPLATE], +[ac_outfile=conftest.$ac_objext +printf "$lt_simple_link_test_code" >conftest.$ac_ext +eval "$ac_link" 2>&1 >/dev/null | $SED '/^$/d; /^ *+/d' >conftest.err +_lt_linker_boilerplate=`cat conftest.err` +$rm conftest* +])# _LT_LINKER_BOILERPLATE + + +# _LT_AC_SYS_LIBPATH_AIX +# ---------------------- +# Links a minimal program and checks the executable +# for the system default hardcoded library path. In most cases, +# this is /usr/lib:/lib, but when the MPI compilers are used +# the location of the communication and MPI libs are included too. +# If we don't find anything, use the default library path according +# to the aix ld manual. +AC_DEFUN([_LT_AC_SYS_LIBPATH_AIX], +[AC_LINK_IFELSE(AC_LANG_PROGRAM,[ +aix_libpath=`dump -H conftest$ac_exeext 2>/dev/null | $SED -n -e '/Import File Strings/,/^$/ { /^0/ { s/^0 *\(.*\)$/\1/; p; } +}'` +# Check for a 64-bit object if we didn't find anything. +if test -z "$aix_libpath"; then aix_libpath=`dump -HX64 conftest$ac_exeext 2>/dev/null | $SED -n -e '/Import File Strings/,/^$/ { /^0/ { s/^0 *\(.*\)$/\1/; p; } +}'`; fi],[]) +if test -z "$aix_libpath"; then aix_libpath="/usr/lib:/lib"; fi +])# _LT_AC_SYS_LIBPATH_AIX + + +# _LT_AC_SHELL_INIT(ARG) +# ---------------------- +AC_DEFUN([_LT_AC_SHELL_INIT], +[ifdef([AC_DIVERSION_NOTICE], + [AC_DIVERT_PUSH(AC_DIVERSION_NOTICE)], + [AC_DIVERT_PUSH(NOTICE)]) +$1 +AC_DIVERT_POP +])# _LT_AC_SHELL_INIT + + +# _LT_AC_PROG_ECHO_BACKSLASH +# -------------------------- +# Add some code to the start of the generated configure script which +# will find an echo command which doesn't interpret backslashes. +AC_DEFUN([_LT_AC_PROG_ECHO_BACKSLASH], +[_LT_AC_SHELL_INIT([ +# Check that we are running under the correct shell. +SHELL=${CONFIG_SHELL-/bin/sh} + +case X$ECHO in +X*--fallback-echo) + # Remove one level of quotation (which was required for Make). + ECHO=`echo "$ECHO" | sed 's,\\\\\[$]\\[$]0,'[$]0','` + ;; +esac + +echo=${ECHO-echo} +if test "X[$]1" = X--no-reexec; then + # Discard the --no-reexec flag, and continue. + shift +elif test "X[$]1" = X--fallback-echo; then + # Avoid inline document here, it may be left over + : +elif test "X`($echo '\t') 2>/dev/null`" = 'X\t' ; then + # Yippee, $echo works! + : +else + # Restart under the correct shell. + exec $SHELL "[$]0" --no-reexec ${1+"[$]@"} +fi + +if test "X[$]1" = X--fallback-echo; then + # used as fallback echo + shift + cat <<EOF +[$]* +EOF + exit 0 +fi + +# The HP-UX ksh and POSIX shell print the target directory to stdout +# if CDPATH is set. +(unset CDPATH) >/dev/null 2>&1 && unset CDPATH + +if test -z "$ECHO"; then +if test "X${echo_test_string+set}" != Xset; then +# find a string as large as possible, as long as the shell can cope with it + for cmd in 'sed 50q "[$]0"' 'sed 20q "[$]0"' 'sed 10q "[$]0"' 'sed 2q "[$]0"' 'echo test'; do + # expected sizes: less than 2Kb, 1Kb, 512 bytes, 16 bytes, ... + if (echo_test_string=`eval $cmd`) 2>/dev/null && + echo_test_string=`eval $cmd` && + (test "X$echo_test_string" = "X$echo_test_string") 2>/dev/null + then + break + fi + done +fi + +if test "X`($echo '\t') 2>/dev/null`" = 'X\t' && + echo_testing_string=`($echo "$echo_test_string") 2>/dev/null` && + test "X$echo_testing_string" = "X$echo_test_string"; then + : +else + # The Solaris, AIX, and Digital Unix default echo programs unquote + # backslashes. This makes it impossible to quote backslashes using + # echo "$something" | sed 's/\\/\\\\/g' + # + # So, first we look for a working echo in the user's PATH. + + lt_save_ifs="$IFS"; IFS=$PATH_SEPARATOR + for dir in $PATH /usr/ucb; do + IFS="$lt_save_ifs" + if (test -f $dir/echo || test -f $dir/echo$ac_exeext) && + test "X`($dir/echo '\t') 2>/dev/null`" = 'X\t' && + echo_testing_string=`($dir/echo "$echo_test_string") 2>/dev/null` && + test "X$echo_testing_string" = "X$echo_test_string"; then + echo="$dir/echo" + break + fi + done + IFS="$lt_save_ifs" + + if test "X$echo" = Xecho; then + # We didn't find a better echo, so look for alternatives. + if test "X`(print -r '\t') 2>/dev/null`" = 'X\t' && + echo_testing_string=`(print -r "$echo_test_string") 2>/dev/null` && + test "X$echo_testing_string" = "X$echo_test_string"; then + # This shell has a builtin print -r that does the trick. + echo='print -r' + elif (test -f /bin/ksh || test -f /bin/ksh$ac_exeext) && + test "X$CONFIG_SHELL" != X/bin/ksh; then + # If we have ksh, try running configure again with it. + ORIGINAL_CONFIG_SHELL=${CONFIG_SHELL-/bin/sh} + export ORIGINAL_CONFIG_SHELL + CONFIG_SHELL=/bin/ksh + export CONFIG_SHELL + exec $CONFIG_SHELL "[$]0" --no-reexec ${1+"[$]@"} + else + # Try using printf. + echo='printf %s\n' + if test "X`($echo '\t') 2>/dev/null`" = 'X\t' && + echo_testing_string=`($echo "$echo_test_string") 2>/dev/null` && + test "X$echo_testing_string" = "X$echo_test_string"; then + # Cool, printf works + : + elif echo_testing_string=`($ORIGINAL_CONFIG_SHELL "[$]0" --fallback-echo '\t') 2>/dev/null` && + test "X$echo_testing_string" = 'X\t' && + echo_testing_string=`($ORIGINAL_CONFIG_SHELL "[$]0" --fallback-echo "$echo_test_string") 2>/dev/null` && + test "X$echo_testing_string" = "X$echo_test_string"; then + CONFIG_SHELL=$ORIGINAL_CONFIG_SHELL + export CONFIG_SHELL + SHELL="$CONFIG_SHELL" + export SHELL + echo="$CONFIG_SHELL [$]0 --fallback-echo" + elif echo_testing_string=`($CONFIG_SHELL "[$]0" --fallback-echo '\t') 2>/dev/null` && + test "X$echo_testing_string" = 'X\t' && + echo_testing_string=`($CONFIG_SHELL "[$]0" --fallback-echo "$echo_test_string") 2>/dev/null` && + test "X$echo_testing_string" = "X$echo_test_string"; then + echo="$CONFIG_SHELL [$]0 --fallback-echo" + else + # maybe with a smaller string... + prev=: + + for cmd in 'echo test' 'sed 2q "[$]0"' 'sed 10q "[$]0"' 'sed 20q "[$]0"' 'sed 50q "[$]0"'; do + if (test "X$echo_test_string" = "X`eval $cmd`") 2>/dev/null + then + break + fi + prev="$cmd" + done + + if test "$prev" != 'sed 50q "[$]0"'; then + echo_test_string=`eval $prev` + export echo_test_string + exec ${ORIGINAL_CONFIG_SHELL-${CONFIG_SHELL-/bin/sh}} "[$]0" ${1+"[$]@"} + else + # Oops. We lost completely, so just stick with echo. + echo=echo + fi + fi + fi + fi +fi +fi + +# Copy echo and quote the copy suitably for passing to libtool from +# the Makefile, instead of quoting the original, which is used later. +ECHO=$echo +if test "X$ECHO" = "X$CONFIG_SHELL [$]0 --fallback-echo"; then + ECHO="$CONFIG_SHELL \\\$\[$]0 --fallback-echo" +fi + +AC_SUBST(ECHO) +])])# _LT_AC_PROG_ECHO_BACKSLASH + + +# _LT_AC_LOCK +# ----------- +AC_DEFUN([_LT_AC_LOCK], +[AC_ARG_ENABLE([libtool-lock], + [AC_HELP_STRING([--disable-libtool-lock], + [avoid locking (might break parallel builds)])]) +test "x$enable_libtool_lock" != xno && enable_libtool_lock=yes + +# Some flags need to be propagated to the compiler or linker for good +# libtool support. +case $host in +ia64-*-hpux*) + # Find out which ABI we are using. + echo 'int i;' > conftest.$ac_ext + if AC_TRY_EVAL(ac_compile); then + case `/usr/bin/file conftest.$ac_objext` in + *ELF-32*) + HPUX_IA64_MODE="32" + ;; + *ELF-64*) + HPUX_IA64_MODE="64" + ;; + esac + fi + rm -rf conftest* + ;; +*-*-irix6*) + # Find out which ABI we are using. + echo '[#]line __oline__ "configure"' > conftest.$ac_ext + if AC_TRY_EVAL(ac_compile); then + if test "$lt_cv_prog_gnu_ld" = yes; then + case `/usr/bin/file conftest.$ac_objext` in + *32-bit*) + LD="${LD-ld} -melf32bsmip" + ;; + *N32*) + LD="${LD-ld} -melf32bmipn32" + ;; + *64-bit*) + LD="${LD-ld} -melf64bmip" + ;; + esac + else + case `/usr/bin/file conftest.$ac_objext` in + *32-bit*) + LD="${LD-ld} -32" + ;; + *N32*) + LD="${LD-ld} -n32" + ;; + *64-bit*) + LD="${LD-ld} -64" + ;; + esac + fi + fi + rm -rf conftest* + ;; + +x86_64-*linux*|ppc*-*linux*|powerpc*-*linux*|s390*-*linux*|sparc*-*linux*) + # Find out which ABI we are using. + echo 'int i;' > conftest.$ac_ext + if AC_TRY_EVAL(ac_compile); then + case `/usr/bin/file conftest.o` in + *32-bit*) + case $host in + x86_64-*linux*) + LD="${LD-ld} -m elf_i386" + ;; + ppc64-*linux*|powerpc64-*linux*) + LD="${LD-ld} -m elf32ppclinux" + ;; + s390x-*linux*) + LD="${LD-ld} -m elf_s390" + ;; + sparc64-*linux*) + LD="${LD-ld} -m elf32_sparc" + ;; + esac + ;; + *64-bit*) + case $host in + x86_64-*linux*) + LD="${LD-ld} -m elf_x86_64" + ;; + ppc*-*linux*|powerpc*-*linux*) + LD="${LD-ld} -m elf64ppc" + ;; + s390*-*linux*) + LD="${LD-ld} -m elf64_s390" + ;; + sparc*-*linux*) + LD="${LD-ld} -m elf64_sparc" + ;; + esac + ;; + esac + fi + rm -rf conftest* + ;; + +*-*-sco3.2v5*) + # On SCO OpenServer 5, we need -belf to get full-featured binaries. + SAVE_CFLAGS="$CFLAGS" + CFLAGS="$CFLAGS -belf" + AC_CACHE_CHECK([whether the C compiler needs -belf], lt_cv_cc_needs_belf, + [AC_LANG_PUSH(C) + AC_TRY_LINK([],[],[lt_cv_cc_needs_belf=yes],[lt_cv_cc_needs_belf=no]) + AC_LANG_POP]) + if test x"$lt_cv_cc_needs_belf" != x"yes"; then + # this is probably gcc 2.8.0, egcs 1.0 or newer; no need for -belf + CFLAGS="$SAVE_CFLAGS" + fi + ;; +sparc*-*solaris*) + # Find out which ABI we are using. + echo 'int i;' > conftest.$ac_ext + if AC_TRY_EVAL(ac_compile); then + case `/usr/bin/file conftest.o` in + *64-bit*) + case $lt_cv_prog_gnu_ld in + yes*) LD="${LD-ld} -m elf64_sparc" ;; + *) LD="${LD-ld} -64" ;; + esac + ;; + esac + fi + rm -rf conftest* + ;; + +AC_PROVIDE_IFELSE([AC_LIBTOOL_WIN32_DLL], +[*-*-cygwin* | *-*-mingw* | *-*-pw32*) + AC_CHECK_TOOL(DLLTOOL, dlltool, false) + AC_CHECK_TOOL(AS, as, false) + AC_CHECK_TOOL(OBJDUMP, objdump, false) + ;; + ]) +esac + +need_locks="$enable_libtool_lock" + +])# _LT_AC_LOCK + + +# AC_LIBTOOL_COMPILER_OPTION(MESSAGE, VARIABLE-NAME, FLAGS, +# [OUTPUT-FILE], [ACTION-SUCCESS], [ACTION-FAILURE]) +# ---------------------------------------------------------------- +# Check whether the given compiler option works +AC_DEFUN([AC_LIBTOOL_COMPILER_OPTION], +[AC_REQUIRE([LT_AC_PROG_SED]) +AC_CACHE_CHECK([$1], [$2], + [$2=no + ifelse([$4], , [ac_outfile=conftest.$ac_objext], [ac_outfile=$4]) + printf "$lt_simple_compile_test_code" > conftest.$ac_ext + lt_compiler_flag="$3" + # Insert the option either (1) after the last *FLAGS variable, or + # (2) before a word containing "conftest.", or (3) at the end. + # Note that $ac_compile itself does not contain backslashes and begins + # with a dollar sign (not a hyphen), so the echo should work correctly. + # The option is referenced via a variable to avoid confusing sed. + lt_compile=`echo "$ac_compile" | $SED \ + -e 's:.*FLAGS}\{0,1\} :&$lt_compiler_flag :; t' \ + -e 's: [[^ ]]*conftest\.: $lt_compiler_flag&:; t' \ + -e 's:$: $lt_compiler_flag:'` + (eval echo "\"\$as_me:__oline__: $lt_compile\"" >&AS_MESSAGE_LOG_FD) + (eval "$lt_compile" 2>conftest.err) + ac_status=$? + cat conftest.err >&AS_MESSAGE_LOG_FD + echo "$as_me:__oline__: \$? = $ac_status" >&AS_MESSAGE_LOG_FD + if (exit $ac_status) && test -s "$ac_outfile"; then + # The compiler can only warn and ignore the option if not recognized + # So say no if there are warnings other than the usual output. + $echo "X$_lt_compiler_boilerplate" | $Xsed -e '/^$/d' >conftest.exp + $SED '/^$/d; /^ *+/d' conftest.err >conftest.er2 + if test ! -s conftest.er2 || diff conftest.exp conftest.er2 >/dev/null; then + $2=yes + fi + fi + $rm conftest* +]) + +if test x"[$]$2" = xyes; then + ifelse([$5], , :, [$5]) +else + ifelse([$6], , :, [$6]) +fi +])# AC_LIBTOOL_COMPILER_OPTION + + +# AC_LIBTOOL_LINKER_OPTION(MESSAGE, VARIABLE-NAME, FLAGS, +# [ACTION-SUCCESS], [ACTION-FAILURE]) +# ------------------------------------------------------------ +# Check whether the given compiler option works +AC_DEFUN([AC_LIBTOOL_LINKER_OPTION], +[AC_CACHE_CHECK([$1], [$2], + [$2=no + save_LDFLAGS="$LDFLAGS" + LDFLAGS="$LDFLAGS $3" + printf "$lt_simple_link_test_code" > conftest.$ac_ext + if (eval $ac_link 2>conftest.err) && test -s conftest$ac_exeext; then + # The linker can only warn and ignore the option if not recognized + # So say no if there are warnings + if test -s conftest.err; then + # Append any errors to the config.log. + cat conftest.err 1>&AS_MESSAGE_LOG_FD + $echo "X$_lt_linker_boilerplate" | $Xsed -e '/^$/d' > conftest.exp + $SED '/^$/d; /^ *+/d' conftest.err >conftest.er2 + if diff conftest.exp conftest.er2 >/dev/null; then + $2=yes + fi + else + $2=yes + fi + fi + $rm conftest* + LDFLAGS="$save_LDFLAGS" +]) + +if test x"[$]$2" = xyes; then + ifelse([$4], , :, [$4]) +else + ifelse([$5], , :, [$5]) +fi +])# AC_LIBTOOL_LINKER_OPTION + + +# AC_LIBTOOL_SYS_MAX_CMD_LEN +# -------------------------- +AC_DEFUN([AC_LIBTOOL_SYS_MAX_CMD_LEN], +[# find the maximum length of command line arguments +AC_MSG_CHECKING([the maximum length of command line arguments]) +AC_CACHE_VAL([lt_cv_sys_max_cmd_len], [dnl + i=0 + teststring="ABCD" + + case $build_os in + msdosdjgpp*) + # On DJGPP, this test can blow up pretty badly due to problems in libc + # (any single argument exceeding 2000 bytes causes a buffer overrun + # during glob expansion). Even if it were fixed, the result of this + # check would be larger than it should be. + lt_cv_sys_max_cmd_len=12288; # 12K is about right + ;; + + gnu*) + # Under GNU Hurd, this test is not required because there is + # no limit to the length of command line arguments. + # Libtool will interpret -1 as no limit whatsoever + lt_cv_sys_max_cmd_len=-1; + ;; + + cygwin* | mingw*) + # On Win9x/ME, this test blows up -- it succeeds, but takes + # about 5 minutes as the teststring grows exponentially. + # Worse, since 9x/ME are not pre-emptively multitasking, + # you end up with a "frozen" computer, even though with patience + # the test eventually succeeds (with a max line length of 256k). + # Instead, let's just punt: use the minimum linelength reported by + # all of the supported platforms: 8192 (on NT/2K/XP). + lt_cv_sys_max_cmd_len=8192; + ;; + + amigaos*) + # On AmigaOS with pdksh, this test takes hours, literally. + # So we just punt and use a minimum line length of 8192. + lt_cv_sys_max_cmd_len=8192; + ;; + + netbsd* | freebsd* | openbsd* | darwin* | dragonfly*) + # This has been around since 386BSD, at least. Likely further. + if test -x /sbin/sysctl; then + lt_cv_sys_max_cmd_len=`/sbin/sysctl -n kern.argmax` + elif test -x /usr/sbin/sysctl; then + lt_cv_sys_max_cmd_len=`/usr/sbin/sysctl -n kern.argmax` + else + lt_cv_sys_max_cmd_len=65536 # usable default for all BSDs + fi + # And add a safety zone + lt_cv_sys_max_cmd_len=`expr $lt_cv_sys_max_cmd_len \/ 4` + lt_cv_sys_max_cmd_len=`expr $lt_cv_sys_max_cmd_len \* 3` + ;; + + interix*) + # We know the value 262144 and hardcode it with a safety zone (like BSD) + lt_cv_sys_max_cmd_len=196608 + ;; + + osf*) + # Dr. Hans Ekkehard Plesser reports seeing a kernel panic running configure + # due to this test when exec_disable_arg_limit is 1 on Tru64. It is not + # nice to cause kernel panics so lets avoid the loop below. + # First set a reasonable default. + lt_cv_sys_max_cmd_len=16384 + # + if test -x /sbin/sysconfig; then + case `/sbin/sysconfig -q proc exec_disable_arg_limit` in + *1*) lt_cv_sys_max_cmd_len=-1 ;; + esac + fi + ;; + sco3.2v5*) + lt_cv_sys_max_cmd_len=102400 + ;; + sysv5* | sco5v6* | sysv4.2uw2*) + kargmax=`grep ARG_MAX /etc/conf/cf.d/stune 2>/dev/null` + if test -n "$kargmax"; then + lt_cv_sys_max_cmd_len=`echo $kargmax | sed 's/.*[[ ]]//'` + else + lt_cv_sys_max_cmd_len=32768 + fi + ;; + *) + # If test is not a shell built-in, we'll probably end up computing a + # maximum length that is only half of the actual maximum length, but + # we can't tell. + SHELL=${SHELL-${CONFIG_SHELL-/bin/sh}} + while (test "X"`$SHELL [$]0 --fallback-echo "X$teststring" 2>/dev/null` \ + = "XX$teststring") >/dev/null 2>&1 && + new_result=`expr "X$teststring" : ".*" 2>&1` && + lt_cv_sys_max_cmd_len=$new_result && + test $i != 17 # 1/2 MB should be enough + do + i=`expr $i + 1` + teststring=$teststring$teststring + done + teststring= + # Add a significant safety factor because C++ compilers can tack on massive + # amounts of additional arguments before passing them to the linker. + # It appears as though 1/2 is a usable value. + lt_cv_sys_max_cmd_len=`expr $lt_cv_sys_max_cmd_len \/ 2` + ;; + esac +]) +if test -n $lt_cv_sys_max_cmd_len ; then + AC_MSG_RESULT($lt_cv_sys_max_cmd_len) +else + AC_MSG_RESULT(none) +fi +])# AC_LIBTOOL_SYS_MAX_CMD_LEN + + +# _LT_AC_CHECK_DLFCN +# ------------------ +AC_DEFUN([_LT_AC_CHECK_DLFCN], +[AC_CHECK_HEADERS(dlfcn.h)dnl +])# _LT_AC_CHECK_DLFCN + + +# _LT_AC_TRY_DLOPEN_SELF (ACTION-IF-TRUE, ACTION-IF-TRUE-W-USCORE, +# ACTION-IF-FALSE, ACTION-IF-CROSS-COMPILING) +# --------------------------------------------------------------------- +AC_DEFUN([_LT_AC_TRY_DLOPEN_SELF], +[AC_REQUIRE([_LT_AC_CHECK_DLFCN])dnl +if test "$cross_compiling" = yes; then : + [$4] +else + lt_dlunknown=0; lt_dlno_uscore=1; lt_dlneed_uscore=2 + lt_status=$lt_dlunknown + cat > conftest.$ac_ext <<EOF +[#line __oline__ "configure" +#include "confdefs.h" + +#if HAVE_DLFCN_H +#include <dlfcn.h> +#endif + +#include <stdio.h> + +#ifdef RTLD_GLOBAL +# define LT_DLGLOBAL RTLD_GLOBAL +#else +# ifdef DL_GLOBAL +# define LT_DLGLOBAL DL_GLOBAL +# else +# define LT_DLGLOBAL 0 +# endif +#endif + +/* We may have to define LT_DLLAZY_OR_NOW in the command line if we + find out it does not work in some platform. */ +#ifndef LT_DLLAZY_OR_NOW +# ifdef RTLD_LAZY +# define LT_DLLAZY_OR_NOW RTLD_LAZY +# else +# ifdef DL_LAZY +# define LT_DLLAZY_OR_NOW DL_LAZY +# else +# ifdef RTLD_NOW +# define LT_DLLAZY_OR_NOW RTLD_NOW +# else +# ifdef DL_NOW +# define LT_DLLAZY_OR_NOW DL_NOW +# else +# define LT_DLLAZY_OR_NOW 0 +# endif +# endif +# endif +# endif +#endif + +#ifdef __cplusplus +extern "C" void exit (int); +#endif + +void fnord() { int i=42;} +int main () +{ + void *self = dlopen (0, LT_DLGLOBAL|LT_DLLAZY_OR_NOW); + int status = $lt_dlunknown; + + if (self) + { + if (dlsym (self,"fnord")) status = $lt_dlno_uscore; + else if (dlsym( self,"_fnord")) status = $lt_dlneed_uscore; + /* dlclose (self); */ + } + else + puts (dlerror ()); + + exit (status); +}] +EOF + if AC_TRY_EVAL(ac_link) && test -s conftest${ac_exeext} 2>/dev/null; then + (./conftest; exit; ) >&AS_MESSAGE_LOG_FD 2>/dev/null + lt_status=$? + case x$lt_status in + x$lt_dlno_uscore) $1 ;; + x$lt_dlneed_uscore) $2 ;; + x$lt_dlunknown|x*) $3 ;; + esac + else : + # compilation failed + $3 + fi +fi +rm -fr conftest* +])# _LT_AC_TRY_DLOPEN_SELF + + +# AC_LIBTOOL_DLOPEN_SELF +# ---------------------- +AC_DEFUN([AC_LIBTOOL_DLOPEN_SELF], +[AC_REQUIRE([_LT_AC_CHECK_DLFCN])dnl +if test "x$enable_dlopen" != xyes; then + enable_dlopen=unknown + enable_dlopen_self=unknown + enable_dlopen_self_static=unknown +else + lt_cv_dlopen=no + lt_cv_dlopen_libs= + + case $host_os in + beos*) + lt_cv_dlopen="load_add_on" + lt_cv_dlopen_libs= + lt_cv_dlopen_self=yes + ;; + + mingw* | pw32*) + lt_cv_dlopen="LoadLibrary" + lt_cv_dlopen_libs= + ;; + + cygwin*) + lt_cv_dlopen="dlopen" + lt_cv_dlopen_libs= + ;; + + darwin*) + # if libdl is installed we need to link against it + AC_CHECK_LIB([dl], [dlopen], + [lt_cv_dlopen="dlopen" lt_cv_dlopen_libs="-ldl"],[ + lt_cv_dlopen="dyld" + lt_cv_dlopen_libs= + lt_cv_dlopen_self=yes + ]) + ;; + + *) + AC_CHECK_FUNC([shl_load], + [lt_cv_dlopen="shl_load"], + [AC_CHECK_LIB([dld], [shl_load], + [lt_cv_dlopen="shl_load" lt_cv_dlopen_libs="-dld"], + [AC_CHECK_FUNC([dlopen], + [lt_cv_dlopen="dlopen"], + [AC_CHECK_LIB([dl], [dlopen], + [lt_cv_dlopen="dlopen" lt_cv_dlopen_libs="-ldl"], + [AC_CHECK_LIB([svld], [dlopen], + [lt_cv_dlopen="dlopen" lt_cv_dlopen_libs="-lsvld"], + [AC_CHECK_LIB([dld], [dld_link], + [lt_cv_dlopen="dld_link" lt_cv_dlopen_libs="-dld"]) + ]) + ]) + ]) + ]) + ]) + ;; + esac + + if test "x$lt_cv_dlopen" != xno; then + enable_dlopen=yes + else + enable_dlopen=no + fi + + case $lt_cv_dlopen in + dlopen) + save_CPPFLAGS="$CPPFLAGS" + test "x$ac_cv_header_dlfcn_h" = xyes && CPPFLAGS="$CPPFLAGS -DHAVE_DLFCN_H" + + save_LDFLAGS="$LDFLAGS" + wl=$lt_prog_compiler_wl eval LDFLAGS=\"\$LDFLAGS $export_dynamic_flag_spec\" + + save_LIBS="$LIBS" + LIBS="$lt_cv_dlopen_libs $LIBS" + + AC_CACHE_CHECK([whether a program can dlopen itself], + lt_cv_dlopen_self, [dnl + _LT_AC_TRY_DLOPEN_SELF( + lt_cv_dlopen_self=yes, lt_cv_dlopen_self=yes, + lt_cv_dlopen_self=no, lt_cv_dlopen_self=cross) + ]) + + if test "x$lt_cv_dlopen_self" = xyes; then + wl=$lt_prog_compiler_wl eval LDFLAGS=\"\$LDFLAGS $lt_prog_compiler_static\" + AC_CACHE_CHECK([whether a statically linked program can dlopen itself], + lt_cv_dlopen_self_static, [dnl + _LT_AC_TRY_DLOPEN_SELF( + lt_cv_dlopen_self_static=yes, lt_cv_dlopen_self_static=yes, + lt_cv_dlopen_self_static=no, lt_cv_dlopen_self_static=cross) + ]) + fi + + CPPFLAGS="$save_CPPFLAGS" + LDFLAGS="$save_LDFLAGS" + LIBS="$save_LIBS" + ;; + esac + + case $lt_cv_dlopen_self in + yes|no) enable_dlopen_self=$lt_cv_dlopen_self ;; + *) enable_dlopen_self=unknown ;; + esac + + case $lt_cv_dlopen_self_static in + yes|no) enable_dlopen_self_static=$lt_cv_dlopen_self_static ;; + *) enable_dlopen_self_static=unknown ;; + esac +fi +])# AC_LIBTOOL_DLOPEN_SELF + + +# AC_LIBTOOL_PROG_CC_C_O([TAGNAME]) +# --------------------------------- +# Check to see if options -c and -o are simultaneously supported by compiler +AC_DEFUN([AC_LIBTOOL_PROG_CC_C_O], +[AC_REQUIRE([_LT_AC_SYS_COMPILER])dnl +AC_CACHE_CHECK([if $compiler supports -c -o file.$ac_objext], + [_LT_AC_TAGVAR(lt_cv_prog_compiler_c_o, $1)], + [_LT_AC_TAGVAR(lt_cv_prog_compiler_c_o, $1)=no + $rm -r conftest 2>/dev/null + mkdir conftest + cd conftest + mkdir out + printf "$lt_simple_compile_test_code" > conftest.$ac_ext + + lt_compiler_flag="-o out/conftest2.$ac_objext" + # Insert the option either (1) after the last *FLAGS variable, or + # (2) before a word containing "conftest.", or (3) at the end. + # Note that $ac_compile itself does not contain backslashes and begins + # with a dollar sign (not a hyphen), so the echo should work correctly. + lt_compile=`echo "$ac_compile" | $SED \ + -e 's:.*FLAGS}\{0,1\} :&$lt_compiler_flag :; t' \ + -e 's: [[^ ]]*conftest\.: $lt_compiler_flag&:; t' \ + -e 's:$: $lt_compiler_flag:'` + (eval echo "\"\$as_me:__oline__: $lt_compile\"" >&AS_MESSAGE_LOG_FD) + (eval "$lt_compile" 2>out/conftest.err) + ac_status=$? + cat out/conftest.err >&AS_MESSAGE_LOG_FD + echo "$as_me:__oline__: \$? = $ac_status" >&AS_MESSAGE_LOG_FD + if (exit $ac_status) && test -s out/conftest2.$ac_objext + then + # The compiler can only warn and ignore the option if not recognized + # So say no if there are warnings + $echo "X$_lt_compiler_boilerplate" | $Xsed -e '/^$/d' > out/conftest.exp + $SED '/^$/d; /^ *+/d' out/conftest.err >out/conftest.er2 + if test ! -s out/conftest.er2 || diff out/conftest.exp out/conftest.er2 >/dev/null; then + _LT_AC_TAGVAR(lt_cv_prog_compiler_c_o, $1)=yes + fi + fi + chmod u+w . 2>&AS_MESSAGE_LOG_FD + $rm conftest* + # SGI C++ compiler will create directory out/ii_files/ for + # template instantiation + test -d out/ii_files && $rm out/ii_files/* && rmdir out/ii_files + $rm out/* && rmdir out + cd .. + rmdir conftest + $rm conftest* +]) +])# AC_LIBTOOL_PROG_CC_C_O + + +# AC_LIBTOOL_SYS_HARD_LINK_LOCKS([TAGNAME]) +# ----------------------------------------- +# Check to see if we can do hard links to lock some files if needed +AC_DEFUN([AC_LIBTOOL_SYS_HARD_LINK_LOCKS], +[AC_REQUIRE([_LT_AC_LOCK])dnl + +hard_links="nottested" +if test "$_LT_AC_TAGVAR(lt_cv_prog_compiler_c_o, $1)" = no && test "$need_locks" != no; then + # do not overwrite the value of need_locks provided by the user + AC_MSG_CHECKING([if we can lock with hard links]) + hard_links=yes + $rm conftest* + ln conftest.a conftest.b 2>/dev/null && hard_links=no + touch conftest.a + ln conftest.a conftest.b 2>&5 || hard_links=no + ln conftest.a conftest.b 2>/dev/null && hard_links=no + AC_MSG_RESULT([$hard_links]) + if test "$hard_links" = no; then + AC_MSG_WARN([`$CC' does not support `-c -o', so `make -j' may be unsafe]) + need_locks=warn + fi +else + need_locks=no +fi +])# AC_LIBTOOL_SYS_HARD_LINK_LOCKS + + +# AC_LIBTOOL_OBJDIR +# ----------------- +AC_DEFUN([AC_LIBTOOL_OBJDIR], +[AC_CACHE_CHECK([for objdir], [lt_cv_objdir], +[rm -f .libs 2>/dev/null +mkdir .libs 2>/dev/null +if test -d .libs; then + lt_cv_objdir=.libs +else + # MS-DOS does not allow filenames that begin with a dot. + lt_cv_objdir=_libs +fi +rmdir .libs 2>/dev/null]) +objdir=$lt_cv_objdir +])# AC_LIBTOOL_OBJDIR + + +# AC_LIBTOOL_PROG_LD_HARDCODE_LIBPATH([TAGNAME]) +# ---------------------------------------------- +# Check hardcoding attributes. +AC_DEFUN([AC_LIBTOOL_PROG_LD_HARDCODE_LIBPATH], +[AC_MSG_CHECKING([how to hardcode library paths into programs]) +_LT_AC_TAGVAR(hardcode_action, $1)= +if test -n "$_LT_AC_TAGVAR(hardcode_libdir_flag_spec, $1)" || \ + test -n "$_LT_AC_TAGVAR(runpath_var, $1)" || \ + test "X$_LT_AC_TAGVAR(hardcode_automatic, $1)" = "Xyes" ; then + + # We can hardcode non-existant directories. + if test "$_LT_AC_TAGVAR(hardcode_direct, $1)" != no && + # If the only mechanism to avoid hardcoding is shlibpath_var, we + # have to relink, otherwise we might link with an installed library + # when we should be linking with a yet-to-be-installed one + ## test "$_LT_AC_TAGVAR(hardcode_shlibpath_var, $1)" != no && + test "$_LT_AC_TAGVAR(hardcode_minus_L, $1)" != no; then + # Linking always hardcodes the temporary library directory. + _LT_AC_TAGVAR(hardcode_action, $1)=relink + else + # We can link without hardcoding, and we can hardcode nonexisting dirs. + _LT_AC_TAGVAR(hardcode_action, $1)=immediate + fi +else + # We cannot hardcode anything, or else we can only hardcode existing + # directories. + _LT_AC_TAGVAR(hardcode_action, $1)=unsupported +fi +AC_MSG_RESULT([$_LT_AC_TAGVAR(hardcode_action, $1)]) + +if test "$_LT_AC_TAGVAR(hardcode_action, $1)" = relink; then + # Fast installation is not supported + enable_fast_install=no +elif test "$shlibpath_overrides_runpath" = yes || + test "$enable_shared" = no; then + # Fast installation is not necessary + enable_fast_install=needless +fi +])# AC_LIBTOOL_PROG_LD_HARDCODE_LIBPATH + + +# AC_LIBTOOL_SYS_LIB_STRIP +# ------------------------ +AC_DEFUN([AC_LIBTOOL_SYS_LIB_STRIP], +[striplib= +old_striplib= +AC_MSG_CHECKING([whether stripping libraries is possible]) +if test -n "$STRIP" && $STRIP -V 2>&1 | grep "GNU strip" >/dev/null; then + test -z "$old_striplib" && old_striplib="$STRIP --strip-debug" + test -z "$striplib" && striplib="$STRIP --strip-unneeded" + AC_MSG_RESULT([yes]) +else +# FIXME - insert some real tests, host_os isn't really good enough + case $host_os in + darwin*) + if test -n "$STRIP" ; then + striplib="$STRIP -x" + AC_MSG_RESULT([yes]) + else + AC_MSG_RESULT([no]) +fi + ;; + *) + AC_MSG_RESULT([no]) + ;; + esac +fi +])# AC_LIBTOOL_SYS_LIB_STRIP + + +# AC_LIBTOOL_SYS_DYNAMIC_LINKER +# ----------------------------- +# PORTME Fill in your ld.so characteristics +AC_DEFUN([AC_LIBTOOL_SYS_DYNAMIC_LINKER], +[AC_MSG_CHECKING([dynamic linker characteristics]) +library_names_spec= +libname_spec='lib$name' +soname_spec= +shrext_cmds=".so" +postinstall_cmds= +postuninstall_cmds= +finish_cmds= +finish_eval= +shlibpath_var= +shlibpath_overrides_runpath=unknown +version_type=none +dynamic_linker="$host_os ld.so" +sys_lib_dlsearch_path_spec="/lib /usr/lib" +if test "$GCC" = yes; then + sys_lib_search_path_spec=`$CC -print-search-dirs | grep "^libraries:" | $SED -e "s/^libraries://" -e "s,=/,/,g"` + if echo "$sys_lib_search_path_spec" | grep ';' >/dev/null ; then + # if the path contains ";" then we assume it to be the separator + # otherwise default to the standard path separator (i.e. ":") - it is + # assumed that no part of a normal pathname contains ";" but that should + # okay in the real world where ";" in dirpaths is itself problematic. + sys_lib_search_path_spec=`echo "$sys_lib_search_path_spec" | $SED -e 's/;/ /g'` + else + sys_lib_search_path_spec=`echo "$sys_lib_search_path_spec" | $SED -e "s/$PATH_SEPARATOR/ /g"` + fi +else + sys_lib_search_path_spec="/lib /usr/lib /usr/local/lib" +fi +need_lib_prefix=unknown +hardcode_into_libs=no + +# when you set need_version to no, make sure it does not cause -set_version +# flags to be left without arguments +need_version=unknown + +case $host_os in +aix3*) + version_type=linux + library_names_spec='${libname}${release}${shared_ext}$versuffix $libname.a' + shlibpath_var=LIBPATH + + # AIX 3 has no versioning support, so we append a major version to the name. + soname_spec='${libname}${release}${shared_ext}$major' + ;; + +aix4* | aix5*) + version_type=linux + need_lib_prefix=no + need_version=no + hardcode_into_libs=yes + if test "$host_cpu" = ia64; then + # AIX 5 supports IA64 + library_names_spec='${libname}${release}${shared_ext}$major ${libname}${release}${shared_ext}$versuffix $libname${shared_ext}' + shlibpath_var=LD_LIBRARY_PATH + else + # With GCC up to 2.95.x, collect2 would create an import file + # for dependence libraries. The import file would start with + # the line `#! .'. This would cause the generated library to + # depend on `.', always an invalid library. This was fixed in + # development snapshots of GCC prior to 3.0. + case $host_os in + aix4 | aix4.[[01]] | aix4.[[01]].*) + if { echo '#if __GNUC__ > 2 || (__GNUC__ == 2 && __GNUC_MINOR__ >= 97)' + echo ' yes ' + echo '#endif'; } | ${CC} -E - | grep yes > /dev/null; then + : + else + can_build_shared=no + fi + ;; + esac + # AIX (on Power*) has no versioning support, so currently we can not hardcode correct + # soname into executable. Probably we can add versioning support to + # collect2, so additional links can be useful in future. + if test "$aix_use_runtimelinking" = yes; then + # If using run time linking (on AIX 4.2 or later) use lib<name>.so + # instead of lib<name>.a to let people know that these are not + # typical AIX shared libraries. + library_names_spec='${libname}${release}${shared_ext}$versuffix ${libname}${release}${shared_ext}$major $libname${shared_ext}' + else + # We preserve .a as extension for shared libraries through AIX4.2 + # and later when we are not doing run time linking. + library_names_spec='${libname}${release}.a $libname.a' + soname_spec='${libname}${release}${shared_ext}$major' + fi + shlibpath_var=LIBPATH + fi + ;; + +amigaos*) + library_names_spec='$libname.ixlibrary $libname.a' + # Create ${libname}_ixlibrary.a entries in /sys/libs. + finish_eval='for lib in `ls $libdir/*.ixlibrary 2>/dev/null`; do libname=`$echo "X$lib" | $Xsed -e '\''s%^.*/\([[^/]]*\)\.ixlibrary$%\1%'\''`; test $rm /sys/libs/${libname}_ixlibrary.a; $show "cd /sys/libs && $LN_S $lib ${libname}_ixlibrary.a"; cd /sys/libs && $LN_S $lib ${libname}_ixlibrary.a || exit 1; done' + ;; + +beos*) + library_names_spec='${libname}${shared_ext}' + dynamic_linker="$host_os ld.so" + shlibpath_var=LIBRARY_PATH + ;; + +bsdi[[45]]*) + version_type=linux + need_version=no + library_names_spec='${libname}${release}${shared_ext}$versuffix ${libname}${release}${shared_ext}$major $libname${shared_ext}' + soname_spec='${libname}${release}${shared_ext}$major' + finish_cmds='PATH="\$PATH:/sbin" ldconfig $libdir' + shlibpath_var=LD_LIBRARY_PATH + sys_lib_search_path_spec="/shlib /usr/lib /usr/X11/lib /usr/contrib/lib /lib /usr/local/lib" + sys_lib_dlsearch_path_spec="/shlib /usr/lib /usr/local/lib" + # the default ld.so.conf also contains /usr/contrib/lib and + # /usr/X11R6/lib (/usr/X11 is a link to /usr/X11R6), but let us allow + # libtool to hard-code these into programs + ;; + +cygwin* | mingw* | pw32*) + version_type=windows + shrext_cmds=".dll" + need_version=no + need_lib_prefix=no + + case $GCC,$host_os in + yes,cygwin* | yes,mingw* | yes,pw32*) + library_names_spec='$libname.dll.a' + # DLL is installed to $(libdir)/../bin by postinstall_cmds + postinstall_cmds='base_file=`basename \${file}`~ + dlpath=`$SHELL 2>&1 -c '\''. $dir/'\''\${base_file}'\''i;echo \$dlname'\''`~ + dldir=$destdir/`dirname \$dlpath`~ + test -d \$dldir || mkdir -p \$dldir~ + $install_prog $dir/$dlname \$dldir/$dlname~ + chmod a+x \$dldir/$dlname' + postuninstall_cmds='dldll=`$SHELL 2>&1 -c '\''. $file; echo \$dlname'\''`~ + dlpath=$dir/\$dldll~ + $rm \$dlpath' + shlibpath_overrides_runpath=yes + + case $host_os in + cygwin*) + # Cygwin DLLs use 'cyg' prefix rather than 'lib' + soname_spec='`echo ${libname} | sed -e 's/^lib/cyg/'``echo ${release} | $SED -e 's/[[.]]/-/g'`${versuffix}${shared_ext}' + sys_lib_search_path_spec="/usr/lib /lib/w32api /lib /usr/local/lib" + ;; + mingw*) + # MinGW DLLs use traditional 'lib' prefix + soname_spec='${libname}`echo ${release} | $SED -e 's/[[.]]/-/g'`${versuffix}${shared_ext}' + sys_lib_search_path_spec=`$CC -print-search-dirs | grep "^libraries:" | $SED -e "s/^libraries://" -e "s,=/,/,g"` + if echo "$sys_lib_search_path_spec" | [grep ';[c-zC-Z]:/' >/dev/null]; then + # It is most probably a Windows format PATH printed by + # mingw gcc, but we are running on Cygwin. Gcc prints its search + # path with ; separators, and with drive letters. We can handle the + # drive letters (cygwin fileutils understands them), so leave them, + # especially as we might pass files found there to a mingw objdump, + # which wouldn't understand a cygwinified path. Ahh. + sys_lib_search_path_spec=`echo "$sys_lib_search_path_spec" | $SED -e 's/;/ /g'` + else + sys_lib_search_path_spec=`echo "$sys_lib_search_path_spec" | $SED -e "s/$PATH_SEPARATOR/ /g"` + fi + ;; + pw32*) + # pw32 DLLs use 'pw' prefix rather than 'lib' + library_names_spec='`echo ${libname} | sed -e 's/^lib/pw/'``echo ${release} | $SED -e 's/[[.]]/-/g'`${versuffix}${shared_ext}' + ;; + esac + ;; + + *) + library_names_spec='${libname}`echo ${release} | $SED -e 's/[[.]]/-/g'`${versuffix}${shared_ext} $libname.lib' + ;; + esac + dynamic_linker='Win32 ld.exe' + # FIXME: first we should search . and the directory the executable is in + shlibpath_var=PATH + ;; + +darwin* | rhapsody*) + dynamic_linker="$host_os dyld" + version_type=darwin + need_lib_prefix=no + need_version=no + library_names_spec='${libname}${release}${versuffix}$shared_ext ${libname}${release}${major}$shared_ext ${libname}$shared_ext' + soname_spec='${libname}${release}${major}$shared_ext' + shlibpath_overrides_runpath=yes + shlibpath_var=DYLD_LIBRARY_PATH + shrext_cmds='`test .$module = .yes && echo .so || echo .dylib`' + # Apple's gcc prints 'gcc -print-search-dirs' doesn't operate the same. + if test "$GCC" = yes; then + sys_lib_search_path_spec=`$CC -print-search-dirs | tr "\n" "$PATH_SEPARATOR" | sed -e 's/libraries:/@libraries:/' | tr "@" "\n" | grep "^libraries:" | sed -e "s/^libraries://" -e "s,=/,/,g" -e "s,$PATH_SEPARATOR, ,g" -e "s,.*,& /lib /usr/lib /usr/local/lib,g"` + else + sys_lib_search_path_spec='/lib /usr/lib /usr/local/lib' + fi + sys_lib_dlsearch_path_spec='/usr/local/lib /lib /usr/lib' + ;; + +dgux*) + version_type=linux + need_lib_prefix=no + need_version=no + library_names_spec='${libname}${release}${shared_ext}$versuffix ${libname}${release}${shared_ext}$major $libname$shared_ext' + soname_spec='${libname}${release}${shared_ext}$major' + shlibpath_var=LD_LIBRARY_PATH + ;; + +freebsd1*) + dynamic_linker=no + ;; + +kfreebsd*-gnu) + version_type=linux + need_lib_prefix=no + need_version=no + library_names_spec='${libname}${release}${shared_ext}$versuffix ${libname}${release}${shared_ext}$major ${libname}${shared_ext}' + soname_spec='${libname}${release}${shared_ext}$major' + shlibpath_var=LD_LIBRARY_PATH + shlibpath_overrides_runpath=no + hardcode_into_libs=yes + dynamic_linker='GNU ld.so' + ;; + +freebsd* | dragonfly*) + # DragonFly does not have aout. When/if they implement a new + # versioning mechanism, adjust this. + if test -x /usr/bin/objformat; then + objformat=`/usr/bin/objformat` + else + case $host_os in + freebsd[[123]]*) objformat=aout ;; + *) objformat=elf ;; + esac + fi + version_type=freebsd-$objformat + case $version_type in + freebsd-elf*) + library_names_spec='${libname}${release}${shared_ext}$versuffix ${libname}${release}${shared_ext} $libname${shared_ext}' + need_version=no + need_lib_prefix=no + ;; + freebsd-*) + library_names_spec='${libname}${release}${shared_ext}$versuffix $libname${shared_ext}$versuffix' + need_version=yes + ;; + esac + shlibpath_var=LD_LIBRARY_PATH + case $host_os in + freebsd2*) + shlibpath_overrides_runpath=yes + ;; + freebsd3.[[01]]* | freebsdelf3.[[01]]*) + shlibpath_overrides_runpath=yes + hardcode_into_libs=yes + ;; + freebsd3.[[2-9]]* | freebsdelf3.[[2-9]]* | \ + freebsd4.[[0-5]] | freebsdelf4.[[0-5]] | freebsd4.1.1 | freebsdelf4.1.1) + shlibpath_overrides_runpath=no + hardcode_into_libs=yes + ;; + freebsd*) # from 4.6 on + shlibpath_overrides_runpath=yes + hardcode_into_libs=yes + ;; + esac + ;; + +gnu*) + version_type=linux + need_lib_prefix=no + need_version=no + library_names_spec='${libname}${release}${shared_ext}$versuffix ${libname}${release}${shared_ext}${major} ${libname}${shared_ext}' + soname_spec='${libname}${release}${shared_ext}$major' + shlibpath_var=LD_LIBRARY_PATH + hardcode_into_libs=yes + ;; + +hpux9* | hpux10* | hpux11*) + # Give a soname corresponding to the major version so that dld.sl refuses to + # link against other versions. + version_type=sunos + need_lib_prefix=no + need_version=no + case $host_cpu in + ia64*) + shrext_cmds='.so' + hardcode_into_libs=yes + dynamic_linker="$host_os dld.so" + shlibpath_var=LD_LIBRARY_PATH + shlibpath_overrides_runpath=yes # Unless +noenvvar is specified. + library_names_spec='${libname}${release}${shared_ext}$versuffix ${libname}${release}${shared_ext}$major $libname${shared_ext}' + soname_spec='${libname}${release}${shared_ext}$major' + if test "X$HPUX_IA64_MODE" = X32; then + sys_lib_search_path_spec="/usr/lib/hpux32 /usr/local/lib/hpux32 /usr/local/lib" + else + sys_lib_search_path_spec="/usr/lib/hpux64 /usr/local/lib/hpux64" + fi + sys_lib_dlsearch_path_spec=$sys_lib_search_path_spec + ;; + hppa*64*) + shrext_cmds='.sl' + hardcode_into_libs=yes + dynamic_linker="$host_os dld.sl" + shlibpath_var=LD_LIBRARY_PATH # How should we handle SHLIB_PATH + shlibpath_overrides_runpath=yes # Unless +noenvvar is specified. + library_names_spec='${libname}${release}${shared_ext}$versuffix ${libname}${release}${shared_ext}$major $libname${shared_ext}' + soname_spec='${libname}${release}${shared_ext}$major' + sys_lib_search_path_spec="/usr/lib/pa20_64 /usr/ccs/lib/pa20_64" + sys_lib_dlsearch_path_spec=$sys_lib_search_path_spec + ;; + *) + shrext_cmds='.sl' + dynamic_linker="$host_os dld.sl" + shlibpath_var=SHLIB_PATH + shlibpath_overrides_runpath=no # +s is required to enable SHLIB_PATH + library_names_spec='${libname}${release}${shared_ext}$versuffix ${libname}${release}${shared_ext}$major $libname${shared_ext}' + soname_spec='${libname}${release}${shared_ext}$major' + ;; + esac + # HP-UX runs *really* slowly unless shared libraries are mode 555. + postinstall_cmds='chmod 555 $lib' + ;; + +interix3*) + version_type=linux + need_lib_prefix=no + need_version=no + library_names_spec='${libname}${release}${shared_ext}$versuffix ${libname}${release}${shared_ext}$major ${libname}${shared_ext}' + soname_spec='${libname}${release}${shared_ext}$major' + dynamic_linker='Interix 3.x ld.so.1 (PE, like ELF)' + shlibpath_var=LD_LIBRARY_PATH + shlibpath_overrides_runpath=no + hardcode_into_libs=yes + ;; + +irix5* | irix6* | nonstopux*) + case $host_os in + nonstopux*) version_type=nonstopux ;; + *) + if test "$lt_cv_prog_gnu_ld" = yes; then + version_type=linux + else + version_type=irix + fi ;; + esac + need_lib_prefix=no + need_version=no + soname_spec='${libname}${release}${shared_ext}$major' + library_names_spec='${libname}${release}${shared_ext}$versuffix ${libname}${release}${shared_ext}$major ${libname}${release}${shared_ext} $libname${shared_ext}' + case $host_os in + irix5* | nonstopux*) + libsuff= shlibsuff= + ;; + *) + case $LD in # libtool.m4 will add one of these switches to LD + *-32|*"-32 "|*-melf32bsmip|*"-melf32bsmip ") + libsuff= shlibsuff= libmagic=32-bit;; + *-n32|*"-n32 "|*-melf32bmipn32|*"-melf32bmipn32 ") + libsuff=32 shlibsuff=N32 libmagic=N32;; + *-64|*"-64 "|*-melf64bmip|*"-melf64bmip ") + libsuff=64 shlibsuff=64 libmagic=64-bit;; + *) libsuff= shlibsuff= libmagic=never-match;; + esac + ;; + esac + shlibpath_var=LD_LIBRARY${shlibsuff}_PATH + shlibpath_overrides_runpath=no + sys_lib_search_path_spec="/usr/lib${libsuff} /lib${libsuff} /usr/local/lib${libsuff}" + sys_lib_dlsearch_path_spec="/usr/lib${libsuff} /lib${libsuff}" + hardcode_into_libs=yes + ;; + +# No shared lib support for Linux oldld, aout, or coff. +linux*oldld* | linux*aout* | linux*coff*) + dynamic_linker=no + ;; + +# This must be Linux ELF. +linux*) + version_type=linux + need_lib_prefix=no + need_version=no + library_names_spec='${libname}${release}${shared_ext}$versuffix ${libname}${release}${shared_ext}$major $libname${shared_ext}' + soname_spec='${libname}${release}${shared_ext}$major' + finish_cmds='PATH="\$PATH:/sbin" ldconfig -n $libdir' + shlibpath_var=LD_LIBRARY_PATH + shlibpath_overrides_runpath=no + # This implies no fast_install, which is unacceptable. + # Some rework will be needed to allow for fast_install + # before this can be enabled. + hardcode_into_libs=yes + + # find out which ABI we are using + libsuff= + case "$host_cpu" in + x86_64*|s390x*|powerpc64*) + echo '[#]line __oline__ "configure"' > conftest.$ac_ext + if AC_TRY_EVAL(ac_compile); then + case `/usr/bin/file conftest.$ac_objext` in + *64-bit*) + libsuff=64 + sys_lib_search_path_spec="/lib${libsuff} /usr/lib${libsuff} /usr/local/lib${libsuff}" + ;; + esac + fi + rm -rf conftest* + ;; + esac + + # Append ld.so.conf contents to the search path + if test -f /etc/ld.so.conf; then + lt_ld_extra=`awk '/^include / { system(sprintf("cd /etc; cat %s 2>/dev/null", \[$]2)); skip = 1; } { if (!skip) print \[$]0; skip = 0; }' < /etc/ld.so.conf | $SED -e 's/#.*//;s/[:, ]/ /g;s/=[^=]*$//;s/=[^= ]* / /g;/^$/d' | tr '\n' ' '` + sys_lib_dlsearch_path_spec="/lib${libsuff} /usr/lib${libsuff} $lt_ld_extra" + fi + + # We used to test for /lib/ld.so.1 and disable shared libraries on + # powerpc, because MkLinux only supported shared libraries with the + # GNU dynamic linker. Since this was broken with cross compilers, + # most powerpc-linux boxes support dynamic linking these days and + # people can always --disable-shared, the test was removed, and we + # assume the GNU/Linux dynamic linker is in use. + dynamic_linker='GNU/Linux ld.so' + ;; + +knetbsd*-gnu) + version_type=linux + need_lib_prefix=no + need_version=no + library_names_spec='${libname}${release}${shared_ext}$versuffix ${libname}${release}${shared_ext}$major ${libname}${shared_ext}' + soname_spec='${libname}${release}${shared_ext}$major' + shlibpath_var=LD_LIBRARY_PATH + shlibpath_overrides_runpath=no + hardcode_into_libs=yes + dynamic_linker='GNU ld.so' + ;; + +netbsd*) + version_type=sunos + need_lib_prefix=no + need_version=no + if echo __ELF__ | $CC -E - | grep __ELF__ >/dev/null; then + library_names_spec='${libname}${release}${shared_ext}$versuffix ${libname}${shared_ext}$versuffix' + finish_cmds='PATH="\$PATH:/sbin" ldconfig -m $libdir' + dynamic_linker='NetBSD (a.out) ld.so' + else + library_names_spec='${libname}${release}${shared_ext}$versuffix ${libname}${release}${shared_ext}$major ${libname}${shared_ext}' + soname_spec='${libname}${release}${shared_ext}$major' + dynamic_linker='NetBSD ld.elf_so' + fi + shlibpath_var=LD_LIBRARY_PATH + shlibpath_overrides_runpath=yes + hardcode_into_libs=yes + ;; + +newsos6) + version_type=linux + library_names_spec='${libname}${release}${shared_ext}$versuffix ${libname}${release}${shared_ext}$major $libname${shared_ext}' + shlibpath_var=LD_LIBRARY_PATH + shlibpath_overrides_runpath=yes + ;; + +nto-qnx*) + version_type=linux + need_lib_prefix=no + need_version=no + library_names_spec='${libname}${release}${shared_ext}$versuffix ${libname}${release}${shared_ext}$major $libname${shared_ext}' + soname_spec='${libname}${release}${shared_ext}$major' + shlibpath_var=LD_LIBRARY_PATH + shlibpath_overrides_runpath=yes + ;; + +openbsd*) + version_type=sunos + sys_lib_dlsearch_path_spec="/usr/lib" + need_lib_prefix=no + # Some older versions of OpenBSD (3.3 at least) *do* need versioned libs. + case $host_os in + openbsd3.3 | openbsd3.3.*) need_version=yes ;; + *) need_version=no ;; + esac + library_names_spec='${libname}${release}${shared_ext}$versuffix ${libname}${shared_ext}$versuffix' + finish_cmds='PATH="\$PATH:/sbin" ldconfig -m $libdir' + shlibpath_var=LD_LIBRARY_PATH + if test -z "`echo __ELF__ | $CC -E - | grep __ELF__`" || test "$host_os-$host_cpu" = "openbsd2.8-powerpc"; then + case $host_os in + openbsd2.[[89]] | openbsd2.[[89]].*) + shlibpath_overrides_runpath=no + ;; + *) + shlibpath_overrides_runpath=yes + ;; + esac + else + shlibpath_overrides_runpath=yes + fi + ;; + +os2*) + libname_spec='$name' + shrext_cmds=".dll" + need_lib_prefix=no + library_names_spec='$libname${shared_ext} $libname.a' + dynamic_linker='OS/2 ld.exe' + shlibpath_var=LIBPATH + ;; + +osf3* | osf4* | osf5*) + version_type=osf + need_lib_prefix=no + need_version=no + soname_spec='${libname}${release}${shared_ext}$major' + library_names_spec='${libname}${release}${shared_ext}$versuffix ${libname}${release}${shared_ext}$major $libname${shared_ext}' + shlibpath_var=LD_LIBRARY_PATH + sys_lib_search_path_spec="/usr/shlib /usr/ccs/lib /usr/lib/cmplrs/cc /usr/lib /usr/local/lib /var/shlib" + sys_lib_dlsearch_path_spec="$sys_lib_search_path_spec" + ;; + +solaris*) + version_type=linux + need_lib_prefix=no + need_version=no + library_names_spec='${libname}${release}${shared_ext}$versuffix ${libname}${release}${shared_ext}$major $libname${shared_ext}' + soname_spec='${libname}${release}${shared_ext}$major' + shlibpath_var=LD_LIBRARY_PATH + shlibpath_overrides_runpath=yes + hardcode_into_libs=yes + # ldd complains unless libraries are executable + postinstall_cmds='chmod +x $lib' + ;; + +sunos4*) + version_type=sunos + library_names_spec='${libname}${release}${shared_ext}$versuffix ${libname}${shared_ext}$versuffix' + finish_cmds='PATH="\$PATH:/usr/etc" ldconfig $libdir' + shlibpath_var=LD_LIBRARY_PATH + shlibpath_overrides_runpath=yes + if test "$with_gnu_ld" = yes; then + need_lib_prefix=no + fi + need_version=yes + ;; + +sysv4 | sysv4.3*) + version_type=linux + library_names_spec='${libname}${release}${shared_ext}$versuffix ${libname}${release}${shared_ext}$major $libname${shared_ext}' + soname_spec='${libname}${release}${shared_ext}$major' + shlibpath_var=LD_LIBRARY_PATH + case $host_vendor in + sni) + shlibpath_overrides_runpath=no + need_lib_prefix=no + export_dynamic_flag_spec='${wl}-Blargedynsym' + runpath_var=LD_RUN_PATH + ;; + siemens) + need_lib_prefix=no + ;; + motorola) + need_lib_prefix=no + need_version=no + shlibpath_overrides_runpath=no + sys_lib_search_path_spec='/lib /usr/lib /usr/ccs/lib' + ;; + esac + ;; + +sysv4*MP*) + if test -d /usr/nec ;then + version_type=linux + library_names_spec='$libname${shared_ext}.$versuffix $libname${shared_ext}.$major $libname${shared_ext}' + soname_spec='$libname${shared_ext}.$major' + shlibpath_var=LD_LIBRARY_PATH + fi + ;; + +sysv5* | sco3.2v5* | sco5v6* | unixware* | OpenUNIX* | sysv4*uw2*) + version_type=freebsd-elf + need_lib_prefix=no + need_version=no + library_names_spec='${libname}${release}${shared_ext}$versuffix ${libname}${release}${shared_ext} $libname${shared_ext}' + soname_spec='${libname}${release}${shared_ext}$major' + shlibpath_var=LD_LIBRARY_PATH + hardcode_into_libs=yes + if test "$with_gnu_ld" = yes; then + sys_lib_search_path_spec='/usr/local/lib /usr/gnu/lib /usr/ccs/lib /usr/lib /lib' + shlibpath_overrides_runpath=no + else + sys_lib_search_path_spec='/usr/ccs/lib /usr/lib' + shlibpath_overrides_runpath=yes + case $host_os in + sco3.2v5*) + sys_lib_search_path_spec="$sys_lib_search_path_spec /lib" + ;; + esac + fi + sys_lib_dlsearch_path_spec='/usr/lib' + ;; + +uts4*) + version_type=linux + library_names_spec='${libname}${release}${shared_ext}$versuffix ${libname}${release}${shared_ext}$major $libname${shared_ext}' + soname_spec='${libname}${release}${shared_ext}$major' + shlibpath_var=LD_LIBRARY_PATH + ;; + +*) + dynamic_linker=no + ;; +esac +AC_MSG_RESULT([$dynamic_linker]) +test "$dynamic_linker" = no && can_build_shared=no + +variables_saved_for_relink="PATH $shlibpath_var $runpath_var" +if test "$GCC" = yes; then + variables_saved_for_relink="$variables_saved_for_relink GCC_EXEC_PREFIX COMPILER_PATH LIBRARY_PATH" +fi +])# AC_LIBTOOL_SYS_DYNAMIC_LINKER + + +# _LT_AC_TAGCONFIG +# ---------------- +AC_DEFUN([_LT_AC_TAGCONFIG], +[AC_ARG_WITH([tags], + [AC_HELP_STRING([--with-tags@<:@=TAGS@:>@], + [include additional configurations @<:@automatic@:>@])], + [tagnames="$withval"]) + +if test -f "$ltmain" && test -n "$tagnames"; then + if test ! -f "${ofile}"; then + AC_MSG_WARN([output file `$ofile' does not exist]) + fi + + if test -z "$LTCC"; then + eval "`$SHELL ${ofile} --config | grep '^LTCC='`" + if test -z "$LTCC"; then + AC_MSG_WARN([output file `$ofile' does not look like a libtool script]) + else + AC_MSG_WARN([using `LTCC=$LTCC', extracted from `$ofile']) + fi + fi + if test -z "$LTCFLAGS"; then + eval "`$SHELL ${ofile} --config | grep '^LTCFLAGS='`" + fi + + # Extract list of available tagged configurations in $ofile. + # Note that this assumes the entire list is on one line. + available_tags=`grep "^available_tags=" "${ofile}" | $SED -e 's/available_tags=\(.*$\)/\1/' -e 's/\"//g'` + + lt_save_ifs="$IFS"; IFS="${IFS}$PATH_SEPARATOR," + for tagname in $tagnames; do + IFS="$lt_save_ifs" + # Check whether tagname contains only valid characters + case `$echo "X$tagname" | $Xsed -e 's:[[-_ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz1234567890,/]]::g'` in + "") ;; + *) AC_MSG_ERROR([invalid tag name: $tagname]) + ;; + esac + + if grep "^# ### BEGIN LIBTOOL TAG CONFIG: $tagname$" < "${ofile}" > /dev/null + then + AC_MSG_ERROR([tag name \"$tagname\" already exists]) + fi + + # Update the list of available tags. + if test -n "$tagname"; then + echo appending configuration tag \"$tagname\" to $ofile + + case $tagname in + CXX) + if test -n "$CXX" && ( test "X$CXX" != "Xno" && + ( (test "X$CXX" = "Xg++" && `g++ -v >/dev/null 2>&1` ) || + (test "X$CXX" != "Xg++"))) ; then + AC_LIBTOOL_LANG_CXX_CONFIG + else + tagname="" + fi + ;; + + F77) + if test -n "$F77" && test "X$F77" != "Xno"; then + AC_LIBTOOL_LANG_F77_CONFIG + else + tagname="" + fi + ;; + + GCJ) + if test -n "$GCJ" && test "X$GCJ" != "Xno"; then + AC_LIBTOOL_LANG_GCJ_CONFIG + else + tagname="" + fi + ;; + + RC) + AC_LIBTOOL_LANG_RC_CONFIG + ;; + + *) + AC_MSG_ERROR([Unsupported tag name: $tagname]) + ;; + esac + + # Append the new tag name to the list of available tags. + if test -n "$tagname" ; then + available_tags="$available_tags $tagname" + fi + fi + done + IFS="$lt_save_ifs" + + # Now substitute the updated list of available tags. + if eval "sed -e 's/^available_tags=.*\$/available_tags=\"$available_tags\"/' \"$ofile\" > \"${ofile}T\""; then + mv "${ofile}T" "$ofile" + chmod +x "$ofile" + else + rm -f "${ofile}T" + AC_MSG_ERROR([unable to update list of available tagged configurations.]) + fi +fi +])# _LT_AC_TAGCONFIG + + +# AC_LIBTOOL_DLOPEN +# ----------------- +# enable checks for dlopen support +AC_DEFUN([AC_LIBTOOL_DLOPEN], + [AC_BEFORE([$0],[AC_LIBTOOL_SETUP]) +])# AC_LIBTOOL_DLOPEN + + +# AC_LIBTOOL_WIN32_DLL +# -------------------- +# declare package support for building win32 DLLs +AC_DEFUN([AC_LIBTOOL_WIN32_DLL], +[AC_BEFORE([$0], [AC_LIBTOOL_SETUP]) +])# AC_LIBTOOL_WIN32_DLL + + +# AC_ENABLE_SHARED([DEFAULT]) +# --------------------------- +# implement the --enable-shared flag +# DEFAULT is either `yes' or `no'. If omitted, it defaults to `yes'. +AC_DEFUN([AC_ENABLE_SHARED], +[define([AC_ENABLE_SHARED_DEFAULT], ifelse($1, no, no, yes))dnl +AC_ARG_ENABLE([shared], + [AC_HELP_STRING([--enable-shared@<:@=PKGS@:>@], + [build shared libraries @<:@default=]AC_ENABLE_SHARED_DEFAULT[@:>@])], + [p=${PACKAGE-default} + case $enableval in + yes) enable_shared=yes ;; + no) enable_shared=no ;; + *) + enable_shared=no + # Look at the argument we got. We use all the common list separators. + lt_save_ifs="$IFS"; IFS="${IFS}$PATH_SEPARATOR," + for pkg in $enableval; do + IFS="$lt_save_ifs" + if test "X$pkg" = "X$p"; then + enable_shared=yes + fi + done + IFS="$lt_save_ifs" + ;; + esac], + [enable_shared=]AC_ENABLE_SHARED_DEFAULT) +])# AC_ENABLE_SHARED + + +# AC_DISABLE_SHARED +# ----------------- +# set the default shared flag to --disable-shared +AC_DEFUN([AC_DISABLE_SHARED], +[AC_BEFORE([$0],[AC_LIBTOOL_SETUP])dnl +AC_ENABLE_SHARED(no) +])# AC_DISABLE_SHARED + + +# AC_ENABLE_STATIC([DEFAULT]) +# --------------------------- +# implement the --enable-static flag +# DEFAULT is either `yes' or `no'. If omitted, it defaults to `yes'. +AC_DEFUN([AC_ENABLE_STATIC], +[define([AC_ENABLE_STATIC_DEFAULT], ifelse($1, no, no, yes))dnl +AC_ARG_ENABLE([static], + [AC_HELP_STRING([--enable-static@<:@=PKGS@:>@], + [build static libraries @<:@default=]AC_ENABLE_STATIC_DEFAULT[@:>@])], + [p=${PACKAGE-default} + case $enableval in + yes) enable_static=yes ;; + no) enable_static=no ;; + *) + enable_static=no + # Look at the argument we got. We use all the common list separators. + lt_save_ifs="$IFS"; IFS="${IFS}$PATH_SEPARATOR," + for pkg in $enableval; do + IFS="$lt_save_ifs" + if test "X$pkg" = "X$p"; then + enable_static=yes + fi + done + IFS="$lt_save_ifs" + ;; + esac], + [enable_static=]AC_ENABLE_STATIC_DEFAULT) +])# AC_ENABLE_STATIC + + +# AC_DISABLE_STATIC +# ----------------- +# set the default static flag to --disable-static +AC_DEFUN([AC_DISABLE_STATIC], +[AC_BEFORE([$0],[AC_LIBTOOL_SETUP])dnl +AC_ENABLE_STATIC(no) +])# AC_DISABLE_STATIC + + +# AC_ENABLE_FAST_INSTALL([DEFAULT]) +# --------------------------------- +# implement the --enable-fast-install flag +# DEFAULT is either `yes' or `no'. If omitted, it defaults to `yes'. +AC_DEFUN([AC_ENABLE_FAST_INSTALL], +[define([AC_ENABLE_FAST_INSTALL_DEFAULT], ifelse($1, no, no, yes))dnl +AC_ARG_ENABLE([fast-install], + [AC_HELP_STRING([--enable-fast-install@<:@=PKGS@:>@], + [optimize for fast installation @<:@default=]AC_ENABLE_FAST_INSTALL_DEFAULT[@:>@])], + [p=${PACKAGE-default} + case $enableval in + yes) enable_fast_install=yes ;; + no) enable_fast_install=no ;; + *) + enable_fast_install=no + # Look at the argument we got. We use all the common list separators. + lt_save_ifs="$IFS"; IFS="${IFS}$PATH_SEPARATOR," + for pkg in $enableval; do + IFS="$lt_save_ifs" + if test "X$pkg" = "X$p"; then + enable_fast_install=yes + fi + done + IFS="$lt_save_ifs" + ;; + esac], + [enable_fast_install=]AC_ENABLE_FAST_INSTALL_DEFAULT) +])# AC_ENABLE_FAST_INSTALL + + +# AC_DISABLE_FAST_INSTALL +# ----------------------- +# set the default to --disable-fast-install +AC_DEFUN([AC_DISABLE_FAST_INSTALL], +[AC_BEFORE([$0],[AC_LIBTOOL_SETUP])dnl +AC_ENABLE_FAST_INSTALL(no) +])# AC_DISABLE_FAST_INSTALL + + +# AC_LIBTOOL_PICMODE([MODE]) +# -------------------------- +# implement the --with-pic flag +# MODE is either `yes' or `no'. If omitted, it defaults to `both'. +AC_DEFUN([AC_LIBTOOL_PICMODE], +[AC_BEFORE([$0],[AC_LIBTOOL_SETUP])dnl +pic_mode=ifelse($#,1,$1,default) +])# AC_LIBTOOL_PICMODE + + +# AC_PROG_EGREP +# ------------- +# This is predefined starting with Autoconf 2.54, so this conditional +# definition can be removed once we require Autoconf 2.54 or later. +m4_ifndef([AC_PROG_EGREP], [AC_DEFUN([AC_PROG_EGREP], +[AC_CACHE_CHECK([for egrep], [ac_cv_prog_egrep], + [if echo a | (grep -E '(a|b)') >/dev/null 2>&1 + then ac_cv_prog_egrep='grep -E' + else ac_cv_prog_egrep='egrep' + fi]) + EGREP=$ac_cv_prog_egrep + AC_SUBST([EGREP]) +])]) + + +# AC_PATH_TOOL_PREFIX +# ------------------- +# find a file program which can recognise shared library +AC_DEFUN([AC_PATH_TOOL_PREFIX], +[AC_REQUIRE([AC_PROG_EGREP])dnl +AC_MSG_CHECKING([for $1]) +AC_CACHE_VAL(lt_cv_path_MAGIC_CMD, +[case $MAGIC_CMD in +[[\\/*] | ?:[\\/]*]) + lt_cv_path_MAGIC_CMD="$MAGIC_CMD" # Let the user override the test with a path. + ;; +*) + lt_save_MAGIC_CMD="$MAGIC_CMD" + lt_save_ifs="$IFS"; IFS=$PATH_SEPARATOR +dnl $ac_dummy forces splitting on constant user-supplied paths. +dnl POSIX.2 word splitting is done only on the output of word expansions, +dnl not every word. This closes a longstanding sh security hole. + ac_dummy="ifelse([$2], , $PATH, [$2])" + for ac_dir in $ac_dummy; do + IFS="$lt_save_ifs" + test -z "$ac_dir" && ac_dir=. + if test -f $ac_dir/$1; then + lt_cv_path_MAGIC_CMD="$ac_dir/$1" + if test -n "$file_magic_test_file"; then + case $deplibs_check_method in + "file_magic "*) + file_magic_regex=`expr "$deplibs_check_method" : "file_magic \(.*\)"` + MAGIC_CMD="$lt_cv_path_MAGIC_CMD" + if eval $file_magic_cmd \$file_magic_test_file 2> /dev/null | + $EGREP "$file_magic_regex" > /dev/null; then + : + else + cat <<EOF 1>&2 + +*** Warning: the command libtool uses to detect shared libraries, +*** $file_magic_cmd, produces output that libtool cannot recognize. +*** The result is that libtool may fail to recognize shared libraries +*** as such. This will affect the creation of libtool libraries that +*** depend on shared libraries, but programs linked with such libtool +*** libraries will work regardless of this problem. Nevertheless, you +*** may want to report the problem to your system manager and/or to +*** bug-libtool@gnu.org + +EOF + fi ;; + esac + fi + break + fi + done + IFS="$lt_save_ifs" + MAGIC_CMD="$lt_save_MAGIC_CMD" + ;; +esac]) +MAGIC_CMD="$lt_cv_path_MAGIC_CMD" +if test -n "$MAGIC_CMD"; then + AC_MSG_RESULT($MAGIC_CMD) +else + AC_MSG_RESULT(no) +fi +])# AC_PATH_TOOL_PREFIX + + +# AC_PATH_MAGIC +# ------------- +# find a file program which can recognise a shared library +AC_DEFUN([AC_PATH_MAGIC], +[AC_PATH_TOOL_PREFIX(${ac_tool_prefix}file, /usr/bin$PATH_SEPARATOR$PATH) +if test -z "$lt_cv_path_MAGIC_CMD"; then + if test -n "$ac_tool_prefix"; then + AC_PATH_TOOL_PREFIX(file, /usr/bin$PATH_SEPARATOR$PATH) + else + MAGIC_CMD=: + fi +fi +])# AC_PATH_MAGIC + + +# AC_PROG_LD +# ---------- +# find the pathname to the GNU or non-GNU linker +AC_DEFUN([AC_PROG_LD], +[AC_ARG_WITH([gnu-ld], + [AC_HELP_STRING([--with-gnu-ld], + [assume the C compiler uses GNU ld @<:@default=no@:>@])], + [test "$withval" = no || with_gnu_ld=yes], + [with_gnu_ld=no]) +AC_REQUIRE([LT_AC_PROG_SED])dnl +AC_REQUIRE([AC_PROG_CC])dnl +AC_REQUIRE([AC_CANONICAL_HOST])dnl +AC_REQUIRE([AC_CANONICAL_BUILD])dnl +ac_prog=ld +if test "$GCC" = yes; then + # Check if gcc -print-prog-name=ld gives a path. + AC_MSG_CHECKING([for ld used by $CC]) + case $host in + *-*-mingw*) + # gcc leaves a trailing carriage return which upsets mingw + ac_prog=`($CC -print-prog-name=ld) 2>&5 | tr -d '\015'` ;; + *) + ac_prog=`($CC -print-prog-name=ld) 2>&5` ;; + esac + case $ac_prog in + # Accept absolute paths. + [[\\/]]* | ?:[[\\/]]*) + re_direlt='/[[^/]][[^/]]*/\.\./' + # Canonicalize the pathname of ld + ac_prog=`echo $ac_prog| $SED 's%\\\\%/%g'` + while echo $ac_prog | grep "$re_direlt" > /dev/null 2>&1; do + ac_prog=`echo $ac_prog| $SED "s%$re_direlt%/%"` + done + test -z "$LD" && LD="$ac_prog" + ;; + "") + # If it fails, then pretend we aren't using GCC. + ac_prog=ld + ;; + *) + # If it is relative, then search for the first ld in PATH. + with_gnu_ld=unknown + ;; + esac +elif test "$with_gnu_ld" = yes; then + AC_MSG_CHECKING([for GNU ld]) +else + AC_MSG_CHECKING([for non-GNU ld]) +fi +AC_CACHE_VAL(lt_cv_path_LD, +[if test -z "$LD"; then + lt_save_ifs="$IFS"; IFS=$PATH_SEPARATOR + for ac_dir in $PATH; do + IFS="$lt_save_ifs" + test -z "$ac_dir" && ac_dir=. + if test -f "$ac_dir/$ac_prog" || test -f "$ac_dir/$ac_prog$ac_exeext"; then + lt_cv_path_LD="$ac_dir/$ac_prog" + # Check to see if the program is GNU ld. I'd rather use --version, + # but apparently some variants of GNU ld only accept -v. + # Break only if it was the GNU/non-GNU ld that we prefer. + case `"$lt_cv_path_LD" -v 2>&1 </dev/null` in + *GNU* | *'with BFD'*) + test "$with_gnu_ld" != no && break + ;; + *) + test "$with_gnu_ld" != yes && break + ;; + esac + fi + done + IFS="$lt_save_ifs" +else + lt_cv_path_LD="$LD" # Let the user override the test with a path. +fi]) +LD="$lt_cv_path_LD" +if test -n "$LD"; then + AC_MSG_RESULT($LD) +else + AC_MSG_RESULT(no) +fi +test -z "$LD" && AC_MSG_ERROR([no acceptable ld found in \$PATH]) +AC_PROG_LD_GNU +])# AC_PROG_LD + + +# AC_PROG_LD_GNU +# -------------- +AC_DEFUN([AC_PROG_LD_GNU], +[AC_REQUIRE([AC_PROG_EGREP])dnl +AC_CACHE_CHECK([if the linker ($LD) is GNU ld], lt_cv_prog_gnu_ld, +[# I'd rather use --version here, but apparently some GNU lds only accept -v. +case `$LD -v 2>&1 </dev/null` in +*GNU* | *'with BFD'*) + lt_cv_prog_gnu_ld=yes + ;; +*) + lt_cv_prog_gnu_ld=no + ;; +esac]) +with_gnu_ld=$lt_cv_prog_gnu_ld +])# AC_PROG_LD_GNU + + +# AC_PROG_LD_RELOAD_FLAG +# ---------------------- +# find reload flag for linker +# -- PORTME Some linkers may need a different reload flag. +AC_DEFUN([AC_PROG_LD_RELOAD_FLAG], +[AC_CACHE_CHECK([for $LD option to reload object files], + lt_cv_ld_reload_flag, + [lt_cv_ld_reload_flag='-r']) +reload_flag=$lt_cv_ld_reload_flag +case $reload_flag in +"" | " "*) ;; +*) reload_flag=" $reload_flag" ;; +esac +reload_cmds='$LD$reload_flag -o $output$reload_objs' +case $host_os in + darwin*) + if test "$GCC" = yes; then + reload_cmds='$LTCC $LTCFLAGS -nostdlib ${wl}-r -o $output$reload_objs' + else + reload_cmds='$LD$reload_flag -o $output$reload_objs' + fi + ;; +esac +])# AC_PROG_LD_RELOAD_FLAG + + +# AC_DEPLIBS_CHECK_METHOD +# ----------------------- +# how to check for library dependencies +# -- PORTME fill in with the dynamic library characteristics +AC_DEFUN([AC_DEPLIBS_CHECK_METHOD], +[AC_CACHE_CHECK([how to recognise dependent libraries], +lt_cv_deplibs_check_method, +[lt_cv_file_magic_cmd='$MAGIC_CMD' +lt_cv_file_magic_test_file= +lt_cv_deplibs_check_method='unknown' +# Need to set the preceding variable on all platforms that support +# interlibrary dependencies. +# 'none' -- dependencies not supported. +# `unknown' -- same as none, but documents that we really don't know. +# 'pass_all' -- all dependencies passed with no checks. +# 'test_compile' -- check by making test program. +# 'file_magic [[regex]]' -- check by looking for files in library path +# which responds to the $file_magic_cmd with a given extended regex. +# If you have `file' or equivalent on your system and you're not sure +# whether `pass_all' will *always* work, you probably want this one. + +case $host_os in +aix4* | aix5*) + lt_cv_deplibs_check_method=pass_all + ;; + +beos*) + lt_cv_deplibs_check_method=pass_all + ;; + +bsdi[[45]]*) + lt_cv_deplibs_check_method='file_magic ELF [[0-9]][[0-9]]*-bit [[ML]]SB (shared object|dynamic lib)' + lt_cv_file_magic_cmd='/usr/bin/file -L' + lt_cv_file_magic_test_file=/shlib/libc.so + ;; + +cygwin*) + # func_win32_libid is a shell function defined in ltmain.sh + lt_cv_deplibs_check_method='file_magic ^x86 archive import|^x86 DLL' + lt_cv_file_magic_cmd='func_win32_libid' + ;; + +mingw* | pw32*) + # Base MSYS/MinGW do not provide the 'file' command needed by + # func_win32_libid shell function, so use a weaker test based on 'objdump'. + lt_cv_deplibs_check_method='file_magic file format pei*-i386(.*architecture: i386)?' + lt_cv_file_magic_cmd='$OBJDUMP -f' + ;; + +darwin* | rhapsody*) + lt_cv_deplibs_check_method=pass_all + ;; + +freebsd* | kfreebsd*-gnu | dragonfly*) + if echo __ELF__ | $CC -E - | grep __ELF__ > /dev/null; then + case $host_cpu in + i*86 ) + # Not sure whether the presence of OpenBSD here was a mistake. + # Let's accept both of them until this is cleared up. + lt_cv_deplibs_check_method='file_magic (FreeBSD|OpenBSD|DragonFly)/i[[3-9]]86 (compact )?demand paged shared library' + lt_cv_file_magic_cmd=/usr/bin/file + lt_cv_file_magic_test_file=`echo /usr/lib/libc.so.*` + ;; + esac + else + lt_cv_deplibs_check_method=pass_all + fi + ;; + +gnu*) + lt_cv_deplibs_check_method=pass_all + ;; + +hpux10.20* | hpux11*) + lt_cv_file_magic_cmd=/usr/bin/file + case $host_cpu in + ia64*) + lt_cv_deplibs_check_method='file_magic (s[[0-9]][[0-9]][[0-9]]|ELF-[[0-9]][[0-9]]) shared object file - IA64' + lt_cv_file_magic_test_file=/usr/lib/hpux32/libc.so + ;; + hppa*64*) + [lt_cv_deplibs_check_method='file_magic (s[0-9][0-9][0-9]|ELF-[0-9][0-9]) shared object file - PA-RISC [0-9].[0-9]'] + lt_cv_file_magic_test_file=/usr/lib/pa20_64/libc.sl + ;; + *) + lt_cv_deplibs_check_method='file_magic (s[[0-9]][[0-9]][[0-9]]|PA-RISC[[0-9]].[[0-9]]) shared library' + lt_cv_file_magic_test_file=/usr/lib/libc.sl + ;; + esac + ;; + +interix3*) + # PIC code is broken on Interix 3.x, that's why |\.a not |_pic\.a here + lt_cv_deplibs_check_method='match_pattern /lib[[^/]]+(\.so|\.a)$' + ;; + +irix5* | irix6* | nonstopux*) + case $LD in + *-32|*"-32 ") libmagic=32-bit;; + *-n32|*"-n32 ") libmagic=N32;; + *-64|*"-64 ") libmagic=64-bit;; + *) libmagic=never-match;; + esac + lt_cv_deplibs_check_method=pass_all + ;; + +# This must be Linux ELF. +linux*) + lt_cv_deplibs_check_method=pass_all + ;; + +netbsd*) + if echo __ELF__ | $CC -E - | grep __ELF__ > /dev/null; then + lt_cv_deplibs_check_method='match_pattern /lib[[^/]]+(\.so\.[[0-9]]+\.[[0-9]]+|_pic\.a)$' + else + lt_cv_deplibs_check_method='match_pattern /lib[[^/]]+(\.so|_pic\.a)$' + fi + ;; + +newos6*) + lt_cv_deplibs_check_method='file_magic ELF [[0-9]][[0-9]]*-bit [[ML]]SB (executable|dynamic lib)' + lt_cv_file_magic_cmd=/usr/bin/file + lt_cv_file_magic_test_file=/usr/lib/libnls.so + ;; + +nto-qnx*) + lt_cv_deplibs_check_method=unknown + ;; + +openbsd*) + if test -z "`echo __ELF__ | $CC -E - | grep __ELF__`" || test "$host_os-$host_cpu" = "openbsd2.8-powerpc"; then + lt_cv_deplibs_check_method='match_pattern /lib[[^/]]+(\.so\.[[0-9]]+\.[[0-9]]+|\.so|_pic\.a)$' + else + lt_cv_deplibs_check_method='match_pattern /lib[[^/]]+(\.so\.[[0-9]]+\.[[0-9]]+|_pic\.a)$' + fi + ;; + +osf3* | osf4* | osf5*) + lt_cv_deplibs_check_method=pass_all + ;; + +solaris*) + lt_cv_deplibs_check_method=pass_all + ;; + +sysv4 | sysv4.3*) + case $host_vendor in + motorola) + lt_cv_deplibs_check_method='file_magic ELF [[0-9]][[0-9]]*-bit [[ML]]SB (shared object|dynamic lib) M[[0-9]][[0-9]]* Version [[0-9]]' + lt_cv_file_magic_test_file=`echo /usr/lib/libc.so*` + ;; + ncr) + lt_cv_deplibs_check_method=pass_all + ;; + sequent) + lt_cv_file_magic_cmd='/bin/file' + lt_cv_deplibs_check_method='file_magic ELF [[0-9]][[0-9]]*-bit [[LM]]SB (shared object|dynamic lib )' + ;; + sni) + lt_cv_file_magic_cmd='/bin/file' + lt_cv_deplibs_check_method="file_magic ELF [[0-9]][[0-9]]*-bit [[LM]]SB dynamic lib" + lt_cv_file_magic_test_file=/lib/libc.so + ;; + siemens) + lt_cv_deplibs_check_method=pass_all + ;; + pc) + lt_cv_deplibs_check_method=pass_all + ;; + esac + ;; + +sysv5* | sco3.2v5* | sco5v6* | unixware* | OpenUNIX* | sysv4*uw2*) + lt_cv_deplibs_check_method=pass_all + ;; +esac +]) +file_magic_cmd=$lt_cv_file_magic_cmd +deplibs_check_method=$lt_cv_deplibs_check_method +test -z "$deplibs_check_method" && deplibs_check_method=unknown +])# AC_DEPLIBS_CHECK_METHOD + + +# AC_PROG_NM +# ---------- +# find the pathname to a BSD-compatible name lister +AC_DEFUN([AC_PROG_NM], +[AC_CACHE_CHECK([for BSD-compatible nm], lt_cv_path_NM, +[if test -n "$NM"; then + # Let the user override the test. + lt_cv_path_NM="$NM" +else + lt_nm_to_check="${ac_tool_prefix}nm" + if test -n "$ac_tool_prefix" && test "$build" = "$host"; then + lt_nm_to_check="$lt_nm_to_check nm" + fi + for lt_tmp_nm in $lt_nm_to_check; do + lt_save_ifs="$IFS"; IFS=$PATH_SEPARATOR + for ac_dir in $PATH /usr/ccs/bin/elf /usr/ccs/bin /usr/ucb /bin; do + IFS="$lt_save_ifs" + test -z "$ac_dir" && ac_dir=. + tmp_nm="$ac_dir/$lt_tmp_nm" + if test -f "$tmp_nm" || test -f "$tmp_nm$ac_exeext" ; then + # Check to see if the nm accepts a BSD-compat flag. + # Adding the `sed 1q' prevents false positives on HP-UX, which says: + # nm: unknown option "B" ignored + # Tru64's nm complains that /dev/null is an invalid object file + case `"$tmp_nm" -B /dev/null 2>&1 | sed '1q'` in + */dev/null* | *'Invalid file or object type'*) + lt_cv_path_NM="$tmp_nm -B" + break + ;; + *) + case `"$tmp_nm" -p /dev/null 2>&1 | sed '1q'` in + */dev/null*) + lt_cv_path_NM="$tmp_nm -p" + break + ;; + *) + lt_cv_path_NM=${lt_cv_path_NM="$tmp_nm"} # keep the first match, but + continue # so that we can try to find one that supports BSD flags + ;; + esac + ;; + esac + fi + done + IFS="$lt_save_ifs" + done + test -z "$lt_cv_path_NM" && lt_cv_path_NM=nm +fi]) +NM="$lt_cv_path_NM" +])# AC_PROG_NM + + +# AC_CHECK_LIBM +# ------------- +# check for math library +AC_DEFUN([AC_CHECK_LIBM], +[AC_REQUIRE([AC_CANONICAL_HOST])dnl +LIBM= +case $host in +*-*-beos* | *-*-cygwin* | *-*-pw32* | *-*-darwin*) + # These system don't have libm, or don't need it + ;; +*-ncr-sysv4.3*) + AC_CHECK_LIB(mw, _mwvalidcheckl, LIBM="-lmw") + AC_CHECK_LIB(m, cos, LIBM="$LIBM -lm") + ;; +*) + AC_CHECK_LIB(m, cos, LIBM="-lm") + ;; +esac +])# AC_CHECK_LIBM + + +# AC_LIBLTDL_CONVENIENCE([DIRECTORY]) +# ----------------------------------- +# sets LIBLTDL to the link flags for the libltdl convenience library and +# LTDLINCL to the include flags for the libltdl header and adds +# --enable-ltdl-convenience to the configure arguments. Note that +# AC_CONFIG_SUBDIRS is not called here. If DIRECTORY is not provided, +# it is assumed to be `libltdl'. LIBLTDL will be prefixed with +# '${top_builddir}/' and LTDLINCL will be prefixed with '${top_srcdir}/' +# (note the single quotes!). If your package is not flat and you're not +# using automake, define top_builddir and top_srcdir appropriately in +# the Makefiles. +AC_DEFUN([AC_LIBLTDL_CONVENIENCE], +[AC_BEFORE([$0],[AC_LIBTOOL_SETUP])dnl + case $enable_ltdl_convenience in + no) AC_MSG_ERROR([this package needs a convenience libltdl]) ;; + "") enable_ltdl_convenience=yes + ac_configure_args="$ac_configure_args --enable-ltdl-convenience" ;; + esac + LIBLTDL='${top_builddir}/'ifelse($#,1,[$1],['libltdl'])/libltdlc.la + LTDLINCL='-I${top_srcdir}/'ifelse($#,1,[$1],['libltdl']) + # For backwards non-gettext consistent compatibility... + INCLTDL="$LTDLINCL" +])# AC_LIBLTDL_CONVENIENCE + + +# AC_LIBLTDL_INSTALLABLE([DIRECTORY]) +# ----------------------------------- +# sets LIBLTDL to the link flags for the libltdl installable library and +# LTDLINCL to the include flags for the libltdl header and adds +# --enable-ltdl-install to the configure arguments. Note that +# AC_CONFIG_SUBDIRS is not called here. If DIRECTORY is not provided, +# and an installed libltdl is not found, it is assumed to be `libltdl'. +# LIBLTDL will be prefixed with '${top_builddir}/'# and LTDLINCL with +# '${top_srcdir}/' (note the single quotes!). If your package is not +# flat and you're not using automake, define top_builddir and top_srcdir +# appropriately in the Makefiles. +# In the future, this macro may have to be called after AC_PROG_LIBTOOL. +AC_DEFUN([AC_LIBLTDL_INSTALLABLE], +[AC_BEFORE([$0],[AC_LIBTOOL_SETUP])dnl + AC_CHECK_LIB(ltdl, lt_dlinit, + [test x"$enable_ltdl_install" != xyes && enable_ltdl_install=no], + [if test x"$enable_ltdl_install" = xno; then + AC_MSG_WARN([libltdl not installed, but installation disabled]) + else + enable_ltdl_install=yes + fi + ]) + if test x"$enable_ltdl_install" = x"yes"; then + ac_configure_args="$ac_configure_args --enable-ltdl-install" + LIBLTDL='${top_builddir}/'ifelse($#,1,[$1],['libltdl'])/libltdl.la + LTDLINCL='-I${top_srcdir}/'ifelse($#,1,[$1],['libltdl']) + else + ac_configure_args="$ac_configure_args --enable-ltdl-install=no" + LIBLTDL="-lltdl" + LTDLINCL= + fi + # For backwards non-gettext consistent compatibility... + INCLTDL="$LTDLINCL" +])# AC_LIBLTDL_INSTALLABLE + + +# AC_LIBTOOL_CXX +# -------------- +# enable support for C++ libraries +AC_DEFUN([AC_LIBTOOL_CXX], +[AC_REQUIRE([_LT_AC_LANG_CXX]) +])# AC_LIBTOOL_CXX + + +# _LT_AC_LANG_CXX +# --------------- +AC_DEFUN([_LT_AC_LANG_CXX], +[AC_REQUIRE([AC_PROG_CXX]) +AC_REQUIRE([_LT_AC_PROG_CXXCPP]) +_LT_AC_SHELL_INIT([tagnames=${tagnames+${tagnames},}CXX]) +])# _LT_AC_LANG_CXX + +# _LT_AC_PROG_CXXCPP +# ------------------ +AC_DEFUN([_LT_AC_PROG_CXXCPP], +[ +AC_REQUIRE([AC_PROG_CXX]) +if test -n "$CXX" && ( test "X$CXX" != "Xno" && + ( (test "X$CXX" = "Xg++" && `g++ -v >/dev/null 2>&1` ) || + (test "X$CXX" != "Xg++"))) ; then + AC_PROG_CXXCPP +fi +])# _LT_AC_PROG_CXXCPP + +# AC_LIBTOOL_F77 +# -------------- +# enable support for Fortran 77 libraries +AC_DEFUN([AC_LIBTOOL_F77], +[AC_REQUIRE([_LT_AC_LANG_F77]) +])# AC_LIBTOOL_F77 + + +# _LT_AC_LANG_F77 +# --------------- +AC_DEFUN([_LT_AC_LANG_F77], +[AC_REQUIRE([AC_PROG_F77]) +_LT_AC_SHELL_INIT([tagnames=${tagnames+${tagnames},}F77]) +])# _LT_AC_LANG_F77 + + +# AC_LIBTOOL_GCJ +# -------------- +# enable support for GCJ libraries +AC_DEFUN([AC_LIBTOOL_GCJ], +[AC_REQUIRE([_LT_AC_LANG_GCJ]) +])# AC_LIBTOOL_GCJ + + +# _LT_AC_LANG_GCJ +# --------------- +AC_DEFUN([_LT_AC_LANG_GCJ], +[AC_PROVIDE_IFELSE([AC_PROG_GCJ],[], + [AC_PROVIDE_IFELSE([A][M_PROG_GCJ],[], + [AC_PROVIDE_IFELSE([LT_AC_PROG_GCJ],[], + [ifdef([AC_PROG_GCJ],[AC_REQUIRE([AC_PROG_GCJ])], + [ifdef([A][M_PROG_GCJ],[AC_REQUIRE([A][M_PROG_GCJ])], + [AC_REQUIRE([A][C_PROG_GCJ_OR_A][M_PROG_GCJ])])])])])]) +_LT_AC_SHELL_INIT([tagnames=${tagnames+${tagnames},}GCJ]) +])# _LT_AC_LANG_GCJ + + +# AC_LIBTOOL_RC +# ------------- +# enable support for Windows resource files +AC_DEFUN([AC_LIBTOOL_RC], +[AC_REQUIRE([LT_AC_PROG_RC]) +_LT_AC_SHELL_INIT([tagnames=${tagnames+${tagnames},}RC]) +])# AC_LIBTOOL_RC + + +# AC_LIBTOOL_LANG_C_CONFIG +# ------------------------ +# Ensure that the configuration vars for the C compiler are +# suitably defined. Those variables are subsequently used by +# AC_LIBTOOL_CONFIG to write the compiler configuration to `libtool'. +AC_DEFUN([AC_LIBTOOL_LANG_C_CONFIG], [_LT_AC_LANG_C_CONFIG]) +AC_DEFUN([_LT_AC_LANG_C_CONFIG], +[lt_save_CC="$CC" +AC_LANG_PUSH(C) + +# Source file extension for C test sources. +ac_ext=c + +# Object file extension for compiled C test sources. +objext=o +_LT_AC_TAGVAR(objext, $1)=$objext + +# Code to be used in simple compile tests +lt_simple_compile_test_code="int some_variable = 0;\n" + +# Code to be used in simple link tests +lt_simple_link_test_code='int main(){return(0);}\n' + +_LT_AC_SYS_COMPILER + +# save warnings/boilerplate of simple test code +_LT_COMPILER_BOILERPLATE +_LT_LINKER_BOILERPLATE + +AC_LIBTOOL_PROG_COMPILER_NO_RTTI($1) +AC_LIBTOOL_PROG_COMPILER_PIC($1) +AC_LIBTOOL_PROG_CC_C_O($1) +AC_LIBTOOL_SYS_HARD_LINK_LOCKS($1) +AC_LIBTOOL_PROG_LD_SHLIBS($1) +AC_LIBTOOL_SYS_DYNAMIC_LINKER($1) +AC_LIBTOOL_PROG_LD_HARDCODE_LIBPATH($1) +AC_LIBTOOL_SYS_LIB_STRIP +AC_LIBTOOL_DLOPEN_SELF + +# Report which library types will actually be built +AC_MSG_CHECKING([if libtool supports shared libraries]) +AC_MSG_RESULT([$can_build_shared]) + +AC_MSG_CHECKING([whether to build shared libraries]) +test "$can_build_shared" = "no" && enable_shared=no + +# On AIX, shared libraries and static libraries use the same namespace, and +# are all built from PIC. +case $host_os in +aix3*) + test "$enable_shared" = yes && enable_static=no + if test -n "$RANLIB"; then + archive_cmds="$archive_cmds~\$RANLIB \$lib" + postinstall_cmds='$RANLIB $lib' + fi + ;; + +aix4* | aix5*) + if test "$host_cpu" != ia64 && test "$aix_use_runtimelinking" = no ; then + test "$enable_shared" = yes && enable_static=no + fi + ;; +esac +AC_MSG_RESULT([$enable_shared]) + +AC_MSG_CHECKING([whether to build static libraries]) +# Make sure either enable_shared or enable_static is yes. +test "$enable_shared" = yes || enable_static=yes +AC_MSG_RESULT([$enable_static]) + +AC_LIBTOOL_CONFIG($1) + +AC_LANG_POP +CC="$lt_save_CC" +])# AC_LIBTOOL_LANG_C_CONFIG + + +# AC_LIBTOOL_LANG_CXX_CONFIG +# -------------------------- +# Ensure that the configuration vars for the C compiler are +# suitably defined. Those variables are subsequently used by +# AC_LIBTOOL_CONFIG to write the compiler configuration to `libtool'. +AC_DEFUN([AC_LIBTOOL_LANG_CXX_CONFIG], [_LT_AC_LANG_CXX_CONFIG(CXX)]) +AC_DEFUN([_LT_AC_LANG_CXX_CONFIG], +[AC_LANG_PUSH(C++) +AC_REQUIRE([AC_PROG_CXX]) +AC_REQUIRE([_LT_AC_PROG_CXXCPP]) + +_LT_AC_TAGVAR(archive_cmds_need_lc, $1)=no +_LT_AC_TAGVAR(allow_undefined_flag, $1)= +_LT_AC_TAGVAR(always_export_symbols, $1)=no +_LT_AC_TAGVAR(archive_expsym_cmds, $1)= +_LT_AC_TAGVAR(export_dynamic_flag_spec, $1)= +_LT_AC_TAGVAR(hardcode_direct, $1)=no +_LT_AC_TAGVAR(hardcode_libdir_flag_spec, $1)= +_LT_AC_TAGVAR(hardcode_libdir_flag_spec_ld, $1)= +_LT_AC_TAGVAR(hardcode_libdir_separator, $1)= +_LT_AC_TAGVAR(hardcode_minus_L, $1)=no +_LT_AC_TAGVAR(hardcode_shlibpath_var, $1)=unsupported +_LT_AC_TAGVAR(hardcode_automatic, $1)=no +_LT_AC_TAGVAR(module_cmds, $1)= +_LT_AC_TAGVAR(module_expsym_cmds, $1)= +_LT_AC_TAGVAR(link_all_deplibs, $1)=unknown +_LT_AC_TAGVAR(old_archive_cmds, $1)=$old_archive_cmds +_LT_AC_TAGVAR(no_undefined_flag, $1)= +_LT_AC_TAGVAR(whole_archive_flag_spec, $1)= +_LT_AC_TAGVAR(enable_shared_with_static_runtimes, $1)=no + +# Dependencies to place before and after the object being linked: +_LT_AC_TAGVAR(predep_objects, $1)= +_LT_AC_TAGVAR(postdep_objects, $1)= +_LT_AC_TAGVAR(predeps, $1)= +_LT_AC_TAGVAR(postdeps, $1)= +_LT_AC_TAGVAR(compiler_lib_search_path, $1)= + +# Source file extension for C++ test sources. +ac_ext=cpp + +# Object file extension for compiled C++ test sources. +objext=o +_LT_AC_TAGVAR(objext, $1)=$objext + +# Code to be used in simple compile tests +lt_simple_compile_test_code="int some_variable = 0;\n" + +# Code to be used in simple link tests +lt_simple_link_test_code='int main(int, char *[[]]) { return(0); }\n' + +# ltmain only uses $CC for tagged configurations so make sure $CC is set. +_LT_AC_SYS_COMPILER + +# save warnings/boilerplate of simple test code +_LT_COMPILER_BOILERPLATE +_LT_LINKER_BOILERPLATE + +# Allow CC to be a program name with arguments. +lt_save_CC=$CC +lt_save_LD=$LD +lt_save_GCC=$GCC +GCC=$GXX +lt_save_with_gnu_ld=$with_gnu_ld +lt_save_path_LD=$lt_cv_path_LD +if test -n "${lt_cv_prog_gnu_ldcxx+set}"; then + lt_cv_prog_gnu_ld=$lt_cv_prog_gnu_ldcxx +else + $as_unset lt_cv_prog_gnu_ld +fi +if test -n "${lt_cv_path_LDCXX+set}"; then + lt_cv_path_LD=$lt_cv_path_LDCXX +else + $as_unset lt_cv_path_LD +fi +test -z "${LDCXX+set}" || LD=$LDCXX +CC=${CXX-"c++"} +compiler=$CC +_LT_AC_TAGVAR(compiler, $1)=$CC +_LT_CC_BASENAME([$compiler]) + +# We don't want -fno-exception wen compiling C++ code, so set the +# no_builtin_flag separately +if test "$GXX" = yes; then + _LT_AC_TAGVAR(lt_prog_compiler_no_builtin_flag, $1)=' -fno-builtin' +else + _LT_AC_TAGVAR(lt_prog_compiler_no_builtin_flag, $1)= +fi + +if test "$GXX" = yes; then + # Set up default GNU C++ configuration + + AC_PROG_LD + + # Check if GNU C++ uses GNU ld as the underlying linker, since the + # archiving commands below assume that GNU ld is being used. + if test "$with_gnu_ld" = yes; then + _LT_AC_TAGVAR(archive_cmds, $1)='$CC -shared -nostdlib $predep_objects $libobjs $deplibs $postdep_objects $compiler_flags ${wl}-soname $wl$soname -o $lib' + _LT_AC_TAGVAR(archive_expsym_cmds, $1)='$CC -shared -nostdlib $predep_objects $libobjs $deplibs $postdep_objects $compiler_flags ${wl}-soname $wl$soname ${wl}-retain-symbols-file $wl$export_symbols -o $lib' + + _LT_AC_TAGVAR(hardcode_libdir_flag_spec, $1)='${wl}--rpath ${wl}$libdir' + _LT_AC_TAGVAR(export_dynamic_flag_spec, $1)='${wl}--export-dynamic' + + # If archive_cmds runs LD, not CC, wlarc should be empty + # XXX I think wlarc can be eliminated in ltcf-cxx, but I need to + # investigate it a little bit more. (MM) + wlarc='${wl}' + + # ancient GNU ld didn't support --whole-archive et. al. + if eval "`$CC -print-prog-name=ld` --help 2>&1" | \ + grep 'no-whole-archive' > /dev/null; then + _LT_AC_TAGVAR(whole_archive_flag_spec, $1)="$wlarc"'--whole-archive$convenience '"$wlarc"'--no-whole-archive' + else + _LT_AC_TAGVAR(whole_archive_flag_spec, $1)= + fi + else + with_gnu_ld=no + wlarc= + + # A generic and very simple default shared library creation + # command for GNU C++ for the case where it uses the native + # linker, instead of GNU ld. If possible, this setting should + # overridden to take advantage of the native linker features on + # the platform it is being used on. + _LT_AC_TAGVAR(archive_cmds, $1)='$CC -shared -nostdlib $predep_objects $libobjs $deplibs $postdep_objects $compiler_flags -o $lib' + fi + + # Commands to make compiler produce verbose output that lists + # what "hidden" libraries, object files and flags are used when + # linking a shared library. + output_verbose_link_cmd='$CC -shared $CFLAGS -v conftest.$objext 2>&1 | grep "\-L"' + +else + GXX=no + with_gnu_ld=no + wlarc= +fi + +# PORTME: fill in a description of your system's C++ link characteristics +AC_MSG_CHECKING([whether the $compiler linker ($LD) supports shared libraries]) +_LT_AC_TAGVAR(ld_shlibs, $1)=yes +case $host_os in + aix3*) + # FIXME: insert proper C++ library support + _LT_AC_TAGVAR(ld_shlibs, $1)=no + ;; + aix4* | aix5*) + if test "$host_cpu" = ia64; then + # On IA64, the linker does run time linking by default, so we don't + # have to do anything special. + aix_use_runtimelinking=no + exp_sym_flag='-Bexport' + no_entry_flag="" + else + aix_use_runtimelinking=no + + # Test if we are trying to use run time linking or normal + # AIX style linking. If -brtl is somewhere in LDFLAGS, we + # need to do runtime linking. + case $host_os in aix4.[[23]]|aix4.[[23]].*|aix5*) + for ld_flag in $LDFLAGS; do + case $ld_flag in + *-brtl*) + aix_use_runtimelinking=yes + break + ;; + esac + done + ;; + esac + + exp_sym_flag='-bexport' + no_entry_flag='-bnoentry' + fi + + # When large executables or shared objects are built, AIX ld can + # have problems creating the table of contents. If linking a library + # or program results in "error TOC overflow" add -mminimal-toc to + # CXXFLAGS/CFLAGS for g++/gcc. In the cases where that is not + # enough to fix the problem, add -Wl,-bbigtoc to LDFLAGS. + + _LT_AC_TAGVAR(archive_cmds, $1)='' + _LT_AC_TAGVAR(hardcode_direct, $1)=yes + _LT_AC_TAGVAR(hardcode_libdir_separator, $1)=':' + _LT_AC_TAGVAR(link_all_deplibs, $1)=yes + + if test "$GXX" = yes; then + case $host_os in aix4.[[012]]|aix4.[[012]].*) + # We only want to do this on AIX 4.2 and lower, the check + # below for broken collect2 doesn't work under 4.3+ + collect2name=`${CC} -print-prog-name=collect2` + if test -f "$collect2name" && \ + strings "$collect2name" | grep resolve_lib_name >/dev/null + then + # We have reworked collect2 + _LT_AC_TAGVAR(hardcode_direct, $1)=yes + else + # We have old collect2 + _LT_AC_TAGVAR(hardcode_direct, $1)=unsupported + # It fails to find uninstalled libraries when the uninstalled + # path is not listed in the libpath. Setting hardcode_minus_L + # to unsupported forces relinking + _LT_AC_TAGVAR(hardcode_minus_L, $1)=yes + _LT_AC_TAGVAR(hardcode_libdir_flag_spec, $1)='-L$libdir' + _LT_AC_TAGVAR(hardcode_libdir_separator, $1)= + fi + ;; + esac + shared_flag='-shared' + if test "$aix_use_runtimelinking" = yes; then + shared_flag="$shared_flag "'${wl}-G' + fi + else + # not using gcc + if test "$host_cpu" = ia64; then + # VisualAge C++, Version 5.5 for AIX 5L for IA-64, Beta 3 Release + # chokes on -Wl,-G. The following line is correct: + shared_flag='-G' + else + if test "$aix_use_runtimelinking" = yes; then + shared_flag='${wl}-G' + else + shared_flag='${wl}-bM:SRE' + fi + fi + fi + + # It seems that -bexpall does not export symbols beginning with + # underscore (_), so it is better to generate a list of symbols to export. + _LT_AC_TAGVAR(always_export_symbols, $1)=yes + if test "$aix_use_runtimelinking" = yes; then + # Warning - without using the other runtime loading flags (-brtl), + # -berok will link without error, but may produce a broken library. + _LT_AC_TAGVAR(allow_undefined_flag, $1)='-berok' + # Determine the default libpath from the value encoded in an empty executable. + _LT_AC_SYS_LIBPATH_AIX + _LT_AC_TAGVAR(hardcode_libdir_flag_spec, $1)='${wl}-blibpath:$libdir:'"$aix_libpath" + + _LT_AC_TAGVAR(archive_expsym_cmds, $1)="\$CC"' -o $output_objdir/$soname $libobjs $deplibs '"\${wl}$no_entry_flag"' $compiler_flags `if test "x${allow_undefined_flag}" != "x"; then echo "${wl}${allow_undefined_flag}"; else :; fi` '"\${wl}$exp_sym_flag:\$export_symbols $shared_flag" + else + if test "$host_cpu" = ia64; then + _LT_AC_TAGVAR(hardcode_libdir_flag_spec, $1)='${wl}-R $libdir:/usr/lib:/lib' + _LT_AC_TAGVAR(allow_undefined_flag, $1)="-z nodefs" + _LT_AC_TAGVAR(archive_expsym_cmds, $1)="\$CC $shared_flag"' -o $output_objdir/$soname $libobjs $deplibs '"\${wl}$no_entry_flag"' $compiler_flags ${wl}${allow_undefined_flag} '"\${wl}$exp_sym_flag:\$export_symbols" + else + # Determine the default libpath from the value encoded in an empty executable. + _LT_AC_SYS_LIBPATH_AIX + _LT_AC_TAGVAR(hardcode_libdir_flag_spec, $1)='${wl}-blibpath:$libdir:'"$aix_libpath" + # Warning - without using the other run time loading flags, + # -berok will link without error, but may produce a broken library. + _LT_AC_TAGVAR(no_undefined_flag, $1)=' ${wl}-bernotok' + _LT_AC_TAGVAR(allow_undefined_flag, $1)=' ${wl}-berok' + # Exported symbols can be pulled into shared objects from archives + _LT_AC_TAGVAR(whole_archive_flag_spec, $1)='$convenience' + _LT_AC_TAGVAR(archive_cmds_need_lc, $1)=yes + # This is similar to how AIX traditionally builds its shared libraries. + _LT_AC_TAGVAR(archive_expsym_cmds, $1)="\$CC $shared_flag"' -o $output_objdir/$soname $libobjs $deplibs ${wl}-bnoentry $compiler_flags ${wl}-bE:$export_symbols${allow_undefined_flag}~$AR $AR_FLAGS $output_objdir/$libname$release.a $output_objdir/$soname' + fi + fi + ;; + + beos*) + if $LD --help 2>&1 | grep ': supported targets:.* elf' > /dev/null; then + _LT_AC_TAGVAR(allow_undefined_flag, $1)=unsupported + # Joseph Beckenbach <jrb3@best.com> says some releases of gcc + # support --undefined. This deserves some investigation. FIXME + _LT_AC_TAGVAR(archive_cmds, $1)='$CC -nostart $libobjs $deplibs $compiler_flags ${wl}-soname $wl$soname -o $lib' + else + _LT_AC_TAGVAR(ld_shlibs, $1)=no + fi + ;; + + chorus*) + case $cc_basename in + *) + # FIXME: insert proper C++ library support + _LT_AC_TAGVAR(ld_shlibs, $1)=no + ;; + esac + ;; + + cygwin* | mingw* | pw32*) + # _LT_AC_TAGVAR(hardcode_libdir_flag_spec, $1) is actually meaningless, + # as there is no search path for DLLs. + _LT_AC_TAGVAR(hardcode_libdir_flag_spec, $1)='-L$libdir' + _LT_AC_TAGVAR(allow_undefined_flag, $1)=unsupported + _LT_AC_TAGVAR(always_export_symbols, $1)=no + _LT_AC_TAGVAR(enable_shared_with_static_runtimes, $1)=yes + + if $LD --help 2>&1 | grep 'auto-import' > /dev/null; then + _LT_AC_TAGVAR(archive_cmds, $1)='$CC -shared -nostdlib $predep_objects $libobjs $deplibs $postdep_objects $compiler_flags -o $output_objdir/$soname ${wl}--enable-auto-image-base -Xlinker --out-implib -Xlinker $lib' + # If the export-symbols file already is a .def file (1st line + # is EXPORTS), use it as is; otherwise, prepend... + _LT_AC_TAGVAR(archive_expsym_cmds, $1)='if test "x`$SED 1q $export_symbols`" = xEXPORTS; then + cp $export_symbols $output_objdir/$soname.def; + else + echo EXPORTS > $output_objdir/$soname.def; + cat $export_symbols >> $output_objdir/$soname.def; + fi~ + $CC -shared -nostdlib $output_objdir/$soname.def $predep_objects $libobjs $deplibs $postdep_objects $compiler_flags -o $output_objdir/$soname ${wl}--enable-auto-image-base -Xlinker --out-implib -Xlinker $lib' + else + _LT_AC_TAGVAR(ld_shlibs, $1)=no + fi + ;; + darwin* | rhapsody*) + case $host_os in + rhapsody* | darwin1.[[012]]) + _LT_AC_TAGVAR(allow_undefined_flag, $1)='${wl}-undefined ${wl}suppress' + ;; + *) # Darwin 1.3 on + if test -z ${MACOSX_DEPLOYMENT_TARGET} ; then + _LT_AC_TAGVAR(allow_undefined_flag, $1)='${wl}-flat_namespace ${wl}-undefined ${wl}suppress' + else + case ${MACOSX_DEPLOYMENT_TARGET} in + 10.[[012]]) + _LT_AC_TAGVAR(allow_undefined_flag, $1)='${wl}-flat_namespace ${wl}-undefined ${wl}suppress' + ;; + 10.*) + _LT_AC_TAGVAR(allow_undefined_flag, $1)='${wl}-undefined ${wl}dynamic_lookup' + ;; + esac + fi + ;; + esac + _LT_AC_TAGVAR(archive_cmds_need_lc, $1)=no + _LT_AC_TAGVAR(hardcode_direct, $1)=no + _LT_AC_TAGVAR(hardcode_automatic, $1)=yes + _LT_AC_TAGVAR(hardcode_shlibpath_var, $1)=unsupported + _LT_AC_TAGVAR(whole_archive_flag_spec, $1)='' + _LT_AC_TAGVAR(link_all_deplibs, $1)=yes + + if test "$GXX" = yes ; then + lt_int_apple_cc_single_mod=no + output_verbose_link_cmd='echo' + if $CC -dumpspecs 2>&1 | $EGREP 'single_module' >/dev/null ; then + lt_int_apple_cc_single_mod=yes + fi + if test "X$lt_int_apple_cc_single_mod" = Xyes ; then + _LT_AC_TAGVAR(archive_cmds, $1)='$CC -dynamiclib -single_module $allow_undefined_flag -o $lib $libobjs $deplibs $compiler_flags -install_name $rpath/$soname $verstring' + else + _LT_AC_TAGVAR(archive_cmds, $1)='$CC -r -keep_private_externs -nostdlib -o ${lib}-master.o $libobjs~$CC -dynamiclib $allow_undefined_flag -o $lib ${lib}-master.o $deplibs $compiler_flags -install_name $rpath/$soname $verstring' + fi + _LT_AC_TAGVAR(module_cmds, $1)='$CC $allow_undefined_flag -o $lib -bundle $libobjs $deplibs$compiler_flags' + # Don't fix this by using the ld -exported_symbols_list flag, it doesn't exist in older darwin lds + if test "X$lt_int_apple_cc_single_mod" = Xyes ; then + _LT_AC_TAGVAR(archive_expsym_cmds, $1)='sed -e "s,#.*,," -e "s,^[ ]*,," -e "s,^\(..*\),_&," < $export_symbols > $output_objdir/${libname}-symbols.expsym~$CC -dynamiclib -single_module $allow_undefined_flag -o $lib $libobjs $deplibs $compiler_flags -install_name $rpath/$soname $verstring~nmedit -s $output_objdir/${libname}-symbols.expsym ${lib}' + else + _LT_AC_TAGVAR(archive_expsym_cmds, $1)='sed -e "s,#.*,," -e "s,^[ ]*,," -e "s,^\(..*\),_&," < $export_symbols > $output_objdir/${libname}-symbols.expsym~$CC -r -keep_private_externs -nostdlib -o ${lib}-master.o $libobjs~$CC -dynamiclib $allow_undefined_flag -o $lib ${lib}-master.o $deplibs $compiler_flags -install_name $rpath/$soname $verstring~nmedit -s $output_objdir/${libname}-symbols.expsym ${lib}' + fi + _LT_AC_TAGVAR(module_expsym_cmds, $1)='sed -e "s,#.*,," -e "s,^[ ]*,," -e "s,^\(..*\),_&," < $export_symbols > $output_objdir/${libname}-symbols.expsym~$CC $allow_undefined_flag -o $lib -bundle $libobjs $deplibs$compiler_flags~nmedit -s $output_objdir/${libname}-symbols.expsym ${lib}' + else + case $cc_basename in + xlc*) + output_verbose_link_cmd='echo' + _LT_AC_TAGVAR(archive_cmds, $1)='$CC -qmkshrobj ${wl}-single_module $allow_undefined_flag -o $lib $libobjs $deplibs $compiler_flags ${wl}-install_name ${wl}`echo $rpath/$soname` $verstring' + _LT_AC_TAGVAR(module_cmds, $1)='$CC $allow_undefined_flag -o $lib -bundle $libobjs $deplibs$compiler_flags' + # Don't fix this by using the ld -exported_symbols_list flag, it doesn't exist in older darwin lds + _LT_AC_TAGVAR(archive_expsym_cmds, $1)='sed -e "s,#.*,," -e "s,^[ ]*,," -e "s,^\(..*\),_&," < $export_symbols > $output_objdir/${libname}-symbols.expsym~$CC -qmkshrobj ${wl}-single_module $allow_undefined_flag -o $lib $libobjs $deplibs $compiler_flags ${wl}-install_name ${wl}$rpath/$soname $verstring~nmedit -s $output_objdir/${libname}-symbols.expsym ${lib}' + _LT_AC_TAGVAR(module_expsym_cmds, $1)='sed -e "s,#.*,," -e "s,^[ ]*,," -e "s,^\(..*\),_&," < $export_symbols > $output_objdir/${libname}-symbols.expsym~$CC $allow_undefined_flag -o $lib -bundle $libobjs $deplibs$compiler_flags~nmedit -s $output_objdir/${libname}-symbols.expsym ${lib}' + ;; + *) + _LT_AC_TAGVAR(ld_shlibs, $1)=no + ;; + esac + fi + ;; + + dgux*) + case $cc_basename in + ec++*) + # FIXME: insert proper C++ library support + _LT_AC_TAGVAR(ld_shlibs, $1)=no + ;; + ghcx*) + # Green Hills C++ Compiler + # FIXME: insert proper C++ library support + _LT_AC_TAGVAR(ld_shlibs, $1)=no + ;; + *) + # FIXME: insert proper C++ library support + _LT_AC_TAGVAR(ld_shlibs, $1)=no + ;; + esac + ;; + freebsd[[12]]*) + # C++ shared libraries reported to be fairly broken before switch to ELF + _LT_AC_TAGVAR(ld_shlibs, $1)=no + ;; + freebsd-elf*) + _LT_AC_TAGVAR(archive_cmds_need_lc, $1)=no + ;; + freebsd* | kfreebsd*-gnu | dragonfly*) + # FreeBSD 3 and later use GNU C++ and GNU ld with standard ELF + # conventions + _LT_AC_TAGVAR(ld_shlibs, $1)=yes + ;; + gnu*) + ;; + hpux9*) + _LT_AC_TAGVAR(hardcode_libdir_flag_spec, $1)='${wl}+b ${wl}$libdir' + _LT_AC_TAGVAR(hardcode_libdir_separator, $1)=: + _LT_AC_TAGVAR(export_dynamic_flag_spec, $1)='${wl}-E' + _LT_AC_TAGVAR(hardcode_direct, $1)=yes + _LT_AC_TAGVAR(hardcode_minus_L, $1)=yes # Not in the search PATH, + # but as the default + # location of the library. + + case $cc_basename in + CC*) + # FIXME: insert proper C++ library support + _LT_AC_TAGVAR(ld_shlibs, $1)=no + ;; + aCC*) + _LT_AC_TAGVAR(archive_cmds, $1)='$rm $output_objdir/$soname~$CC -b ${wl}+b ${wl}$install_libdir -o $output_objdir/$soname $predep_objects $libobjs $deplibs $postdep_objects $compiler_flags~test $output_objdir/$soname = $lib || mv $output_objdir/$soname $lib' + # Commands to make compiler produce verbose output that lists + # what "hidden" libraries, object files and flags are used when + # linking a shared library. + # + # There doesn't appear to be a way to prevent this compiler from + # explicitly linking system object files so we need to strip them + # from the output so that they don't get included in the library + # dependencies. + output_verbose_link_cmd='templist=`($CC -b $CFLAGS -v conftest.$objext 2>&1) | grep "[[-]]L"`; list=""; for z in $templist; do case $z in conftest.$objext) list="$list $z";; *.$objext);; *) list="$list $z";;esac; done; echo $list' + ;; + *) + if test "$GXX" = yes; then + _LT_AC_TAGVAR(archive_cmds, $1)='$rm $output_objdir/$soname~$CC -shared -nostdlib -fPIC ${wl}+b ${wl}$install_libdir -o $output_objdir/$soname $predep_objects $libobjs $deplibs $postdep_objects $compiler_flags~test $output_objdir/$soname = $lib || mv $output_objdir/$soname $lib' + else + # FIXME: insert proper C++ library support + _LT_AC_TAGVAR(ld_shlibs, $1)=no + fi + ;; + esac + ;; + hpux10*|hpux11*) + if test $with_gnu_ld = no; then + _LT_AC_TAGVAR(hardcode_libdir_flag_spec, $1)='${wl}+b ${wl}$libdir' + _LT_AC_TAGVAR(hardcode_libdir_separator, $1)=: + + case $host_cpu in + hppa*64*|ia64*) + _LT_AC_TAGVAR(hardcode_libdir_flag_spec_ld, $1)='+b $libdir' + ;; + *) + _LT_AC_TAGVAR(export_dynamic_flag_spec, $1)='${wl}-E' + ;; + esac + fi + case $host_cpu in + hppa*64*|ia64*) + _LT_AC_TAGVAR(hardcode_direct, $1)=no + _LT_AC_TAGVAR(hardcode_shlibpath_var, $1)=no + ;; + *) + _LT_AC_TAGVAR(hardcode_direct, $1)=yes + _LT_AC_TAGVAR(hardcode_minus_L, $1)=yes # Not in the search PATH, + # but as the default + # location of the library. + ;; + esac + + case $cc_basename in + CC*) + # FIXME: insert proper C++ library support + _LT_AC_TAGVAR(ld_shlibs, $1)=no + ;; + aCC*) + case $host_cpu in + hppa*64*) + _LT_AC_TAGVAR(archive_cmds, $1)='$CC -b ${wl}+h ${wl}$soname -o $lib $predep_objects $libobjs $deplibs $postdep_objects $compiler_flags' + ;; + ia64*) + _LT_AC_TAGVAR(archive_cmds, $1)='$CC -b ${wl}+h ${wl}$soname ${wl}+nodefaultrpath -o $lib $predep_objects $libobjs $deplibs $postdep_objects $compiler_flags' + ;; + *) + _LT_AC_TAGVAR(archive_cmds, $1)='$CC -b ${wl}+h ${wl}$soname ${wl}+b ${wl}$install_libdir -o $lib $predep_objects $libobjs $deplibs $postdep_objects $compiler_flags' + ;; + esac + # Commands to make compiler produce verbose output that lists + # what "hidden" libraries, object files and flags are used when + # linking a shared library. + # + # There doesn't appear to be a way to prevent this compiler from + # explicitly linking system object files so we need to strip them + # from the output so that they don't get included in the library + # dependencies. + output_verbose_link_cmd='templist=`($CC -b $CFLAGS -v conftest.$objext 2>&1) | grep "\-L"`; list=""; for z in $templist; do case $z in conftest.$objext) list="$list $z";; *.$objext);; *) list="$list $z";;esac; done; echo $list' + ;; + *) + if test "$GXX" = yes; then + if test $with_gnu_ld = no; then + case $host_cpu in + hppa*64*) + _LT_AC_TAGVAR(archive_cmds, $1)='$CC -shared -nostdlib -fPIC ${wl}+h ${wl}$soname -o $lib $predep_objects $libobjs $deplibs $postdep_objects $compiler_flags' + ;; + ia64*) + _LT_AC_TAGVAR(archive_cmds, $1)='$CC -shared -nostdlib -fPIC ${wl}+h ${wl}$soname ${wl}+nodefaultrpath -o $lib $predep_objects $libobjs $deplibs $postdep_objects $compiler_flags' + ;; + *) + _LT_AC_TAGVAR(archive_cmds, $1)='$CC -shared -nostdlib -fPIC ${wl}+h ${wl}$soname ${wl}+b ${wl}$install_libdir -o $lib $predep_objects $libobjs $deplibs $postdep_objects $compiler_flags' + ;; + esac + fi + else + # FIXME: insert proper C++ library support + _LT_AC_TAGVAR(ld_shlibs, $1)=no + fi + ;; + esac + ;; + interix3*) + _LT_AC_TAGVAR(hardcode_direct, $1)=no + _LT_AC_TAGVAR(hardcode_shlibpath_var, $1)=no + _LT_AC_TAGVAR(hardcode_libdir_flag_spec, $1)='${wl}-rpath,$libdir' + _LT_AC_TAGVAR(export_dynamic_flag_spec, $1)='${wl}-E' + # Hack: On Interix 3.x, we cannot compile PIC because of a broken gcc. + # Instead, shared libraries are loaded at an image base (0x10000000 by + # default) and relocated if they conflict, which is a slow very memory + # consuming and fragmenting process. To avoid this, we pick a random, + # 256 KiB-aligned image base between 0x50000000 and 0x6FFC0000 at link + # time. Moving up from 0x10000000 also allows more sbrk(2) space. + _LT_AC_TAGVAR(archive_cmds, $1)='$CC -shared $pic_flag $libobjs $deplibs $compiler_flags ${wl}-h,$soname ${wl}--image-base,`expr ${RANDOM-$$} % 4096 / 2 \* 262144 + 1342177280` -o $lib' + _LT_AC_TAGVAR(archive_expsym_cmds, $1)='sed "s,^,_," $export_symbols >$output_objdir/$soname.expsym~$CC -shared $pic_flag $libobjs $deplibs $compiler_flags ${wl}-h,$soname ${wl}--retain-symbols-file,$output_objdir/$soname.expsym ${wl}--image-base,`expr ${RANDOM-$$} % 4096 / 2 \* 262144 + 1342177280` -o $lib' + ;; + irix5* | irix6*) + case $cc_basename in + CC*) + # SGI C++ + _LT_AC_TAGVAR(archive_cmds, $1)='$CC -shared -all -multigot $predep_objects $libobjs $deplibs $postdep_objects $compiler_flags -soname $soname `test -n "$verstring" && echo -set_version $verstring` -update_registry ${output_objdir}/so_locations -o $lib' + + # Archives containing C++ object files must be created using + # "CC -ar", where "CC" is the IRIX C++ compiler. This is + # necessary to make sure instantiated templates are included + # in the archive. + _LT_AC_TAGVAR(old_archive_cmds, $1)='$CC -ar -WR,-u -o $oldlib $oldobjs' + ;; + *) + if test "$GXX" = yes; then + if test "$with_gnu_ld" = no; then + _LT_AC_TAGVAR(archive_cmds, $1)='$CC -shared -nostdlib $predep_objects $libobjs $deplibs $postdep_objects $compiler_flags ${wl}-soname ${wl}$soname `test -n "$verstring" && echo ${wl}-set_version ${wl}$verstring` ${wl}-update_registry ${wl}${output_objdir}/so_locations -o $lib' + else + _LT_AC_TAGVAR(archive_cmds, $1)='$CC -shared -nostdlib $predep_objects $libobjs $deplibs $postdep_objects $compiler_flags ${wl}-soname ${wl}$soname `test -n "$verstring" && echo ${wl}-set_version ${wl}$verstring` -o $lib' + fi + fi + _LT_AC_TAGVAR(link_all_deplibs, $1)=yes + ;; + esac + _LT_AC_TAGVAR(hardcode_libdir_flag_spec, $1)='${wl}-rpath ${wl}$libdir' + _LT_AC_TAGVAR(hardcode_libdir_separator, $1)=: + ;; + linux*) + case $cc_basename in + KCC*) + # Kuck and Associates, Inc. (KAI) C++ Compiler + + # KCC will only create a shared library if the output file + # ends with ".so" (or ".sl" for HP-UX), so rename the library + # to its proper name (with version) after linking. + _LT_AC_TAGVAR(archive_cmds, $1)='tempext=`echo $shared_ext | $SED -e '\''s/\([[^()0-9A-Za-z{}]]\)/\\\\\1/g'\''`; templib=`echo $lib | $SED -e "s/\${tempext}\..*/.so/"`; $CC $predep_objects $libobjs $deplibs $postdep_objects $compiler_flags --soname $soname -o \$templib; mv \$templib $lib' + _LT_AC_TAGVAR(archive_expsym_cmds, $1)='tempext=`echo $shared_ext | $SED -e '\''s/\([[^()0-9A-Za-z{}]]\)/\\\\\1/g'\''`; templib=`echo $lib | $SED -e "s/\${tempext}\..*/.so/"`; $CC $predep_objects $libobjs $deplibs $postdep_objects $compiler_flags --soname $soname -o \$templib ${wl}-retain-symbols-file,$export_symbols; mv \$templib $lib' + # Commands to make compiler produce verbose output that lists + # what "hidden" libraries, object files and flags are used when + # linking a shared library. + # + # There doesn't appear to be a way to prevent this compiler from + # explicitly linking system object files so we need to strip them + # from the output so that they don't get included in the library + # dependencies. + output_verbose_link_cmd='templist=`$CC $CFLAGS -v conftest.$objext -o libconftest$shared_ext 2>&1 | grep "ld"`; rm -f libconftest$shared_ext; list=""; for z in $templist; do case $z in conftest.$objext) list="$list $z";; *.$objext);; *) list="$list $z";;esac; done; echo $list' + + _LT_AC_TAGVAR(hardcode_libdir_flag_spec, $1)='${wl}--rpath,$libdir' + _LT_AC_TAGVAR(export_dynamic_flag_spec, $1)='${wl}--export-dynamic' + + # Archives containing C++ object files must be created using + # "CC -Bstatic", where "CC" is the KAI C++ compiler. + _LT_AC_TAGVAR(old_archive_cmds, $1)='$CC -Bstatic -o $oldlib $oldobjs' + ;; + icpc*) + # Intel C++ + with_gnu_ld=yes + # version 8.0 and above of icpc choke on multiply defined symbols + # if we add $predep_objects and $postdep_objects, however 7.1 and + # earlier do not add the objects themselves. + case `$CC -V 2>&1` in + *"Version 7."*) + _LT_AC_TAGVAR(archive_cmds, $1)='$CC -shared $predep_objects $libobjs $deplibs $postdep_objects $compiler_flags ${wl}-soname $wl$soname -o $lib' + _LT_AC_TAGVAR(archive_expsym_cmds, $1)='$CC -shared $predep_objects $libobjs $deplibs $postdep_objects $compiler_flags ${wl}-soname $wl$soname ${wl}-retain-symbols-file $wl$export_symbols -o $lib' + ;; + *) # Version 8.0 or newer + tmp_idyn= + case $host_cpu in + ia64*) tmp_idyn=' -i_dynamic';; + esac + _LT_AC_TAGVAR(archive_cmds, $1)='$CC -shared'"$tmp_idyn"' $libobjs $deplibs $compiler_flags ${wl}-soname $wl$soname -o $lib' + _LT_AC_TAGVAR(archive_expsym_cmds, $1)='$CC -shared'"$tmp_idyn"' $libobjs $deplibs $compiler_flags ${wl}-soname $wl$soname ${wl}-retain-symbols-file $wl$export_symbols -o $lib' + ;; + esac + _LT_AC_TAGVAR(archive_cmds_need_lc, $1)=no + _LT_AC_TAGVAR(hardcode_libdir_flag_spec, $1)='${wl}-rpath,$libdir' + _LT_AC_TAGVAR(export_dynamic_flag_spec, $1)='${wl}--export-dynamic' + _LT_AC_TAGVAR(whole_archive_flag_spec, $1)='${wl}--whole-archive$convenience ${wl}--no-whole-archive' + ;; + pgCC*) + # Portland Group C++ compiler + _LT_AC_TAGVAR(archive_cmds, $1)='$CC -shared $pic_flag $predep_objects $libobjs $deplibs $postdep_objects $compiler_flags ${wl}-soname ${wl}$soname -o $lib' + _LT_AC_TAGVAR(archive_expsym_cmds, $1)='$CC -shared $pic_flag $predep_objects $libobjs $deplibs $postdep_objects $compiler_flags ${wl}-soname ${wl}$soname ${wl}-retain-symbols-file ${wl}$export_symbols -o $lib' + + _LT_AC_TAGVAR(hardcode_libdir_flag_spec, $1)='${wl}--rpath ${wl}$libdir' + _LT_AC_TAGVAR(export_dynamic_flag_spec, $1)='${wl}--export-dynamic' + _LT_AC_TAGVAR(whole_archive_flag_spec, $1)='${wl}--whole-archive`for conv in $convenience\"\"; do test -n \"$conv\" && new_convenience=\"$new_convenience,$conv\"; done; $echo \"$new_convenience\"` ${wl}--no-whole-archive' + ;; + cxx*) + # Compaq C++ + _LT_AC_TAGVAR(archive_cmds, $1)='$CC -shared $predep_objects $libobjs $deplibs $postdep_objects $compiler_flags ${wl}-soname $wl$soname -o $lib' + _LT_AC_TAGVAR(archive_expsym_cmds, $1)='$CC -shared $predep_objects $libobjs $deplibs $postdep_objects $compiler_flags ${wl}-soname $wl$soname -o $lib ${wl}-retain-symbols-file $wl$export_symbols' + + runpath_var=LD_RUN_PATH + _LT_AC_TAGVAR(hardcode_libdir_flag_spec, $1)='-rpath $libdir' + _LT_AC_TAGVAR(hardcode_libdir_separator, $1)=: + + # Commands to make compiler produce verbose output that lists + # what "hidden" libraries, object files and flags are used when + # linking a shared library. + # + # There doesn't appear to be a way to prevent this compiler from + # explicitly linking system object files so we need to strip them + # from the output so that they don't get included in the library + # dependencies. + output_verbose_link_cmd='templist=`$CC -shared $CFLAGS -v conftest.$objext 2>&1 | grep "ld"`; templist=`echo $templist | $SED "s/\(^.*ld.*\)\( .*ld .*$\)/\1/"`; list=""; for z in $templist; do case $z in conftest.$objext) list="$list $z";; *.$objext);; *) list="$list $z";;esac; done; echo $list' + ;; + esac + ;; + lynxos*) + # FIXME: insert proper C++ library support + _LT_AC_TAGVAR(ld_shlibs, $1)=no + ;; + m88k*) + # FIXME: insert proper C++ library support + _LT_AC_TAGVAR(ld_shlibs, $1)=no + ;; + mvs*) + case $cc_basename in + cxx*) + # FIXME: insert proper C++ library support + _LT_AC_TAGVAR(ld_shlibs, $1)=no + ;; + *) + # FIXME: insert proper C++ library support + _LT_AC_TAGVAR(ld_shlibs, $1)=no + ;; + esac + ;; + netbsd*) + if echo __ELF__ | $CC -E - | grep __ELF__ >/dev/null; then + _LT_AC_TAGVAR(archive_cmds, $1)='$LD -Bshareable -o $lib $predep_objects $libobjs $deplibs $postdep_objects $linker_flags' + wlarc= + _LT_AC_TAGVAR(hardcode_libdir_flag_spec, $1)='-R$libdir' + _LT_AC_TAGVAR(hardcode_direct, $1)=yes + _LT_AC_TAGVAR(hardcode_shlibpath_var, $1)=no + fi + # Workaround some broken pre-1.5 toolchains + output_verbose_link_cmd='$CC -shared $CFLAGS -v conftest.$objext 2>&1 | grep conftest.$objext | $SED -e "s:-lgcc -lc -lgcc::"' + ;; + openbsd2*) + # C++ shared libraries are fairly broken + _LT_AC_TAGVAR(ld_shlibs, $1)=no + ;; + openbsd*) + _LT_AC_TAGVAR(hardcode_direct, $1)=yes + _LT_AC_TAGVAR(hardcode_shlibpath_var, $1)=no + _LT_AC_TAGVAR(archive_cmds, $1)='$CC -shared $pic_flag $predep_objects $libobjs $deplibs $postdep_objects $compiler_flags -o $lib' + _LT_AC_TAGVAR(hardcode_libdir_flag_spec, $1)='${wl}-rpath,$libdir' + if test -z "`echo __ELF__ | $CC -E - | grep __ELF__`" || test "$host_os-$host_cpu" = "openbsd2.8-powerpc"; then + _LT_AC_TAGVAR(archive_expsym_cmds, $1)='$CC -shared $pic_flag $predep_objects $libobjs $deplibs $postdep_objects $compiler_flags ${wl}-retain-symbols-file,$export_symbols -o $lib' + _LT_AC_TAGVAR(export_dynamic_flag_spec, $1)='${wl}-E' + _LT_AC_TAGVAR(whole_archive_flag_spec, $1)="$wlarc"'--whole-archive$convenience '"$wlarc"'--no-whole-archive' + fi + output_verbose_link_cmd='echo' + ;; + osf3*) + case $cc_basename in + KCC*) + # Kuck and Associates, Inc. (KAI) C++ Compiler + + # KCC will only create a shared library if the output file + # ends with ".so" (or ".sl" for HP-UX), so rename the library + # to its proper name (with version) after linking. + _LT_AC_TAGVAR(archive_cmds, $1)='tempext=`echo $shared_ext | $SED -e '\''s/\([[^()0-9A-Za-z{}]]\)/\\\\\1/g'\''`; templib=`echo $lib | $SED -e "s/\${tempext}\..*/.so/"`; $CC $predep_objects $libobjs $deplibs $postdep_objects $compiler_flags --soname $soname -o \$templib; mv \$templib $lib' + + _LT_AC_TAGVAR(hardcode_libdir_flag_spec, $1)='${wl}-rpath,$libdir' + _LT_AC_TAGVAR(hardcode_libdir_separator, $1)=: + + # Archives containing C++ object files must be created using + # "CC -Bstatic", where "CC" is the KAI C++ compiler. + _LT_AC_TAGVAR(old_archive_cmds, $1)='$CC -Bstatic -o $oldlib $oldobjs' + + ;; + RCC*) + # Rational C++ 2.4.1 + # FIXME: insert proper C++ library support + _LT_AC_TAGVAR(ld_shlibs, $1)=no + ;; + cxx*) + _LT_AC_TAGVAR(allow_undefined_flag, $1)=' ${wl}-expect_unresolved ${wl}\*' + _LT_AC_TAGVAR(archive_cmds, $1)='$CC -shared${allow_undefined_flag} $predep_objects $libobjs $deplibs $postdep_objects $compiler_flags ${wl}-soname $soname `test -n "$verstring" && echo ${wl}-set_version $verstring` -update_registry ${output_objdir}/so_locations -o $lib' + + _LT_AC_TAGVAR(hardcode_libdir_flag_spec, $1)='${wl}-rpath ${wl}$libdir' + _LT_AC_TAGVAR(hardcode_libdir_separator, $1)=: + + # Commands to make compiler produce verbose output that lists + # what "hidden" libraries, object files and flags are used when + # linking a shared library. + # + # There doesn't appear to be a way to prevent this compiler from + # explicitly linking system object files so we need to strip them + # from the output so that they don't get included in the library + # dependencies. + output_verbose_link_cmd='templist=`$CC -shared $CFLAGS -v conftest.$objext 2>&1 | grep "ld" | grep -v "ld:"`; templist=`echo $templist | $SED "s/\(^.*ld.*\)\( .*ld.*$\)/\1/"`; list=""; for z in $templist; do case $z in conftest.$objext) list="$list $z";; *.$objext);; *) list="$list $z";;esac; done; echo $list' + ;; + *) + if test "$GXX" = yes && test "$with_gnu_ld" = no; then + _LT_AC_TAGVAR(allow_undefined_flag, $1)=' ${wl}-expect_unresolved ${wl}\*' + _LT_AC_TAGVAR(archive_cmds, $1)='$CC -shared -nostdlib ${allow_undefined_flag} $predep_objects $libobjs $deplibs $postdep_objects $compiler_flags ${wl}-soname ${wl}$soname `test -n "$verstring" && echo ${wl}-set_version ${wl}$verstring` ${wl}-update_registry ${wl}${output_objdir}/so_locations -o $lib' + + _LT_AC_TAGVAR(hardcode_libdir_flag_spec, $1)='${wl}-rpath ${wl}$libdir' + _LT_AC_TAGVAR(hardcode_libdir_separator, $1)=: + + # Commands to make compiler produce verbose output that lists + # what "hidden" libraries, object files and flags are used when + # linking a shared library. + output_verbose_link_cmd='$CC -shared $CFLAGS -v conftest.$objext 2>&1 | grep "\-L"' + + else + # FIXME: insert proper C++ library support + _LT_AC_TAGVAR(ld_shlibs, $1)=no + fi + ;; + esac + ;; + osf4* | osf5*) + case $cc_basename in + KCC*) + # Kuck and Associates, Inc. (KAI) C++ Compiler + + # KCC will only create a shared library if the output file + # ends with ".so" (or ".sl" for HP-UX), so rename the library + # to its proper name (with version) after linking. + _LT_AC_TAGVAR(archive_cmds, $1)='tempext=`echo $shared_ext | $SED -e '\''s/\([[^()0-9A-Za-z{}]]\)/\\\\\1/g'\''`; templib=`echo $lib | $SED -e "s/\${tempext}\..*/.so/"`; $CC $predep_objects $libobjs $deplibs $postdep_objects $compiler_flags --soname $soname -o \$templib; mv \$templib $lib' + + _LT_AC_TAGVAR(hardcode_libdir_flag_spec, $1)='${wl}-rpath,$libdir' + _LT_AC_TAGVAR(hardcode_libdir_separator, $1)=: + + # Archives containing C++ object files must be created using + # the KAI C++ compiler. + _LT_AC_TAGVAR(old_archive_cmds, $1)='$CC -o $oldlib $oldobjs' + ;; + RCC*) + # Rational C++ 2.4.1 + # FIXME: insert proper C++ library support + _LT_AC_TAGVAR(ld_shlibs, $1)=no + ;; + cxx*) + _LT_AC_TAGVAR(allow_undefined_flag, $1)=' -expect_unresolved \*' + _LT_AC_TAGVAR(archive_cmds, $1)='$CC -shared${allow_undefined_flag} $predep_objects $libobjs $deplibs $postdep_objects $compiler_flags -msym -soname $soname `test -n "$verstring" && echo -set_version $verstring` -update_registry ${output_objdir}/so_locations -o $lib' + _LT_AC_TAGVAR(archive_expsym_cmds, $1)='for i in `cat $export_symbols`; do printf "%s %s\\n" -exported_symbol "\$i" >> $lib.exp; done~ + echo "-hidden">> $lib.exp~ + $CC -shared$allow_undefined_flag $predep_objects $libobjs $deplibs $postdep_objects $compiler_flags -msym -soname $soname -Wl,-input -Wl,$lib.exp `test -n "$verstring" && echo -set_version $verstring` -update_registry ${output_objdir}/so_locations -o $lib~ + $rm $lib.exp' + + _LT_AC_TAGVAR(hardcode_libdir_flag_spec, $1)='-rpath $libdir' + _LT_AC_TAGVAR(hardcode_libdir_separator, $1)=: + + # Commands to make compiler produce verbose output that lists + # what "hidden" libraries, object files and flags are used when + # linking a shared library. + # + # There doesn't appear to be a way to prevent this compiler from + # explicitly linking system object files so we need to strip them + # from the output so that they don't get included in the library + # dependencies. + output_verbose_link_cmd='templist=`$CC -shared $CFLAGS -v conftest.$objext 2>&1 | grep "ld" | grep -v "ld:"`; templist=`echo $templist | $SED "s/\(^.*ld.*\)\( .*ld.*$\)/\1/"`; list=""; for z in $templist; do case $z in conftest.$objext) list="$list $z";; *.$objext);; *) list="$list $z";;esac; done; echo $list' + ;; + *) + if test "$GXX" = yes && test "$with_gnu_ld" = no; then + _LT_AC_TAGVAR(allow_undefined_flag, $1)=' ${wl}-expect_unresolved ${wl}\*' + _LT_AC_TAGVAR(archive_cmds, $1)='$CC -shared -nostdlib ${allow_undefined_flag} $predep_objects $libobjs $deplibs $postdep_objects $compiler_flags ${wl}-msym ${wl}-soname ${wl}$soname `test -n "$verstring" && echo ${wl}-set_version ${wl}$verstring` ${wl}-update_registry ${wl}${output_objdir}/so_locations -o $lib' + + _LT_AC_TAGVAR(hardcode_libdir_flag_spec, $1)='${wl}-rpath ${wl}$libdir' + _LT_AC_TAGVAR(hardcode_libdir_separator, $1)=: + + # Commands to make compiler produce verbose output that lists + # what "hidden" libraries, object files and flags are used when + # linking a shared library. + output_verbose_link_cmd='$CC -shared $CFLAGS -v conftest.$objext 2>&1 | grep "\-L"' + + else + # FIXME: insert proper C++ library support + _LT_AC_TAGVAR(ld_shlibs, $1)=no + fi + ;; + esac + ;; + psos*) + # FIXME: insert proper C++ library support + _LT_AC_TAGVAR(ld_shlibs, $1)=no + ;; + sunos4*) + case $cc_basename in + CC*) + # Sun C++ 4.x + # FIXME: insert proper C++ library support + _LT_AC_TAGVAR(ld_shlibs, $1)=no + ;; + lcc*) + # Lucid + # FIXME: insert proper C++ library support + _LT_AC_TAGVAR(ld_shlibs, $1)=no + ;; + *) + # FIXME: insert proper C++ library support + _LT_AC_TAGVAR(ld_shlibs, $1)=no + ;; + esac + ;; + solaris*) + case $cc_basename in + CC*) + # Sun C++ 4.2, 5.x and Centerline C++ + _LT_AC_TAGVAR(archive_cmds_need_lc,$1)=yes + _LT_AC_TAGVAR(no_undefined_flag, $1)=' -zdefs' + _LT_AC_TAGVAR(archive_cmds, $1)='$CC -G${allow_undefined_flag} -h$soname -o $lib $predep_objects $libobjs $deplibs $postdep_objects $compiler_flags' + _LT_AC_TAGVAR(archive_expsym_cmds, $1)='$echo "{ global:" > $lib.exp~cat $export_symbols | $SED -e "s/\(.*\)/\1;/" >> $lib.exp~$echo "local: *; };" >> $lib.exp~ + $CC -G${allow_undefined_flag} ${wl}-M ${wl}$lib.exp -h$soname -o $lib $predep_objects $libobjs $deplibs $postdep_objects $compiler_flags~$rm $lib.exp' + + _LT_AC_TAGVAR(hardcode_libdir_flag_spec, $1)='-R$libdir' + _LT_AC_TAGVAR(hardcode_shlibpath_var, $1)=no + case $host_os in + solaris2.[[0-5]] | solaris2.[[0-5]].*) ;; + *) + # The C++ compiler is used as linker so we must use $wl + # flag to pass the commands to the underlying system + # linker. We must also pass each convience library through + # to the system linker between allextract/defaultextract. + # The C++ compiler will combine linker options so we + # cannot just pass the convience library names through + # without $wl. + # Supported since Solaris 2.6 (maybe 2.5.1?) + _LT_AC_TAGVAR(whole_archive_flag_spec, $1)='${wl}-z ${wl}allextract`for conv in $convenience\"\"; do test -n \"$conv\" && new_convenience=\"$new_convenience,$conv\"; done; $echo \"$new_convenience\"` ${wl}-z ${wl}defaultextract' + ;; + esac + _LT_AC_TAGVAR(link_all_deplibs, $1)=yes + + output_verbose_link_cmd='echo' + + # Archives containing C++ object files must be created using + # "CC -xar", where "CC" is the Sun C++ compiler. This is + # necessary to make sure instantiated templates are included + # in the archive. + _LT_AC_TAGVAR(old_archive_cmds, $1)='$CC -xar -o $oldlib $oldobjs' + ;; + gcx*) + # Green Hills C++ Compiler + _LT_AC_TAGVAR(archive_cmds, $1)='$CC -shared $predep_objects $libobjs $deplibs $postdep_objects $compiler_flags ${wl}-h $wl$soname -o $lib' + + # The C++ compiler must be used to create the archive. + _LT_AC_TAGVAR(old_archive_cmds, $1)='$CC $LDFLAGS -archive -o $oldlib $oldobjs' + ;; + *) + # GNU C++ compiler with Solaris linker + if test "$GXX" = yes && test "$with_gnu_ld" = no; then + _LT_AC_TAGVAR(no_undefined_flag, $1)=' ${wl}-z ${wl}defs' + if $CC --version | grep -v '^2\.7' > /dev/null; then + _LT_AC_TAGVAR(archive_cmds, $1)='$CC -shared -nostdlib $LDFLAGS $predep_objects $libobjs $deplibs $postdep_objects $compiler_flags ${wl}-h $wl$soname -o $lib' + _LT_AC_TAGVAR(archive_expsym_cmds, $1)='$echo "{ global:" > $lib.exp~cat $export_symbols | $SED -e "s/\(.*\)/\1;/" >> $lib.exp~$echo "local: *; };" >> $lib.exp~ + $CC -shared -nostdlib ${wl}-M $wl$lib.exp -o $lib $predep_objects $libobjs $deplibs $postdep_objects $compiler_flags~$rm $lib.exp' + + # Commands to make compiler produce verbose output that lists + # what "hidden" libraries, object files and flags are used when + # linking a shared library. + output_verbose_link_cmd="$CC -shared $CFLAGS -v conftest.$objext 2>&1 | grep \"\-L\"" + else + # g++ 2.7 appears to require `-G' NOT `-shared' on this + # platform. + _LT_AC_TAGVAR(archive_cmds, $1)='$CC -G -nostdlib $LDFLAGS $predep_objects $libobjs $deplibs $postdep_objects $compiler_flags ${wl}-h $wl$soname -o $lib' + _LT_AC_TAGVAR(archive_expsym_cmds, $1)='$echo "{ global:" > $lib.exp~cat $export_symbols | $SED -e "s/\(.*\)/\1;/" >> $lib.exp~$echo "local: *; };" >> $lib.exp~ + $CC -G -nostdlib ${wl}-M $wl$lib.exp -o $lib $predep_objects $libobjs $deplibs $postdep_objects $compiler_flags~$rm $lib.exp' + + # Commands to make compiler produce verbose output that lists + # what "hidden" libraries, object files and flags are used when + # linking a shared library. + output_verbose_link_cmd="$CC -G $CFLAGS -v conftest.$objext 2>&1 | grep \"\-L\"" + fi + + _LT_AC_TAGVAR(hardcode_libdir_flag_spec, $1)='${wl}-R $wl$libdir' + fi + ;; + esac + ;; + sysv4*uw2* | sysv5OpenUNIX* | sysv5UnixWare7.[[01]].[[10]]* | unixware7* | sco3.2v5.0.[[024]]*) + _LT_AC_TAGVAR(no_undefined_flag, $1)='${wl}-z,text' + _LT_AC_TAGVAR(archive_cmds_need_lc, $1)=no + _LT_AC_TAGVAR(hardcode_shlibpath_var, $1)=no + runpath_var='LD_RUN_PATH' + + case $cc_basename in + CC*) + _LT_AC_TAGVAR(archive_cmds, $1)='$CC -G ${wl}-h,$soname -o $lib $libobjs $deplibs $compiler_flags' + _LT_AC_TAGVAR(archive_expsym_cmds, $1)='$CC -G ${wl}-Bexport:$export_symbols ${wl}-h,$soname -o $lib $libobjs $deplibs $compiler_flags' + ;; + *) + _LT_AC_TAGVAR(archive_cmds, $1)='$CC -shared ${wl}-h,$soname -o $lib $libobjs $deplibs $compiler_flags' + _LT_AC_TAGVAR(archive_expsym_cmds, $1)='$CC -shared ${wl}-Bexport:$export_symbols ${wl}-h,$soname -o $lib $libobjs $deplibs $compiler_flags' + ;; + esac + ;; + sysv5* | sco3.2v5* | sco5v6*) + # Note: We can NOT use -z defs as we might desire, because we do not + # link with -lc, and that would cause any symbols used from libc to + # always be unresolved, which means just about no library would + # ever link correctly. If we're not using GNU ld we use -z text + # though, which does catch some bad symbols but isn't as heavy-handed + # as -z defs. + # For security reasons, it is highly recommended that you always + # use absolute paths for naming shared libraries, and exclude the + # DT_RUNPATH tag from executables and libraries. But doing so + # requires that you compile everything twice, which is a pain. + # So that behaviour is only enabled if SCOABSPATH is set to a + # non-empty value in the environment. Most likely only useful for + # creating official distributions of packages. + # This is a hack until libtool officially supports absolute path + # names for shared libraries. + _LT_AC_TAGVAR(no_undefined_flag, $1)='${wl}-z,text' + _LT_AC_TAGVAR(allow_undefined_flag, $1)='${wl}-z,nodefs' + _LT_AC_TAGVAR(archive_cmds_need_lc, $1)=no + _LT_AC_TAGVAR(hardcode_shlibpath_var, $1)=no + _LT_AC_TAGVAR(hardcode_libdir_flag_spec, $1)='`test -z "$SCOABSPATH" && echo ${wl}-R,$libdir`' + _LT_AC_TAGVAR(hardcode_libdir_separator, $1)=':' + _LT_AC_TAGVAR(link_all_deplibs, $1)=yes + _LT_AC_TAGVAR(export_dynamic_flag_spec, $1)='${wl}-Bexport' + runpath_var='LD_RUN_PATH' + + case $cc_basename in + CC*) + _LT_AC_TAGVAR(archive_cmds, $1)='$CC -G ${wl}-h,\${SCOABSPATH:+${install_libdir}/}$soname -o $lib $libobjs $deplibs $compiler_flags' + _LT_AC_TAGVAR(archive_expsym_cmds, $1)='$CC -G ${wl}-Bexport:$export_symbols ${wl}-h,\${SCOABSPATH:+${install_libdir}/}$soname -o $lib $libobjs $deplibs $compiler_flags' + ;; + *) + _LT_AC_TAGVAR(archive_cmds, $1)='$CC -shared ${wl}-h,\${SCOABSPATH:+${install_libdir}/}$soname -o $lib $libobjs $deplibs $compiler_flags' + _LT_AC_TAGVAR(archive_expsym_cmds, $1)='$CC -shared ${wl}-Bexport:$export_symbols ${wl}-h,\${SCOABSPATH:+${install_libdir}/}$soname -o $lib $libobjs $deplibs $compiler_flags' + ;; + esac + ;; + tandem*) + case $cc_basename in + NCC*) + # NonStop-UX NCC 3.20 + # FIXME: insert proper C++ library support + _LT_AC_TAGVAR(ld_shlibs, $1)=no + ;; + *) + # FIXME: insert proper C++ library support + _LT_AC_TAGVAR(ld_shlibs, $1)=no + ;; + esac + ;; + vxworks*) + # FIXME: insert proper C++ library support + _LT_AC_TAGVAR(ld_shlibs, $1)=no + ;; + *) + # FIXME: insert proper C++ library support + _LT_AC_TAGVAR(ld_shlibs, $1)=no + ;; +esac +AC_MSG_RESULT([$_LT_AC_TAGVAR(ld_shlibs, $1)]) +test "$_LT_AC_TAGVAR(ld_shlibs, $1)" = no && can_build_shared=no + +_LT_AC_TAGVAR(GCC, $1)="$GXX" +_LT_AC_TAGVAR(LD, $1)="$LD" + +AC_LIBTOOL_POSTDEP_PREDEP($1) +AC_LIBTOOL_PROG_COMPILER_PIC($1) +AC_LIBTOOL_PROG_CC_C_O($1) +AC_LIBTOOL_SYS_HARD_LINK_LOCKS($1) +AC_LIBTOOL_PROG_LD_SHLIBS($1) +AC_LIBTOOL_SYS_DYNAMIC_LINKER($1) +AC_LIBTOOL_PROG_LD_HARDCODE_LIBPATH($1) + +AC_LIBTOOL_CONFIG($1) + +AC_LANG_POP +CC=$lt_save_CC +LDCXX=$LD +LD=$lt_save_LD +GCC=$lt_save_GCC +with_gnu_ldcxx=$with_gnu_ld +with_gnu_ld=$lt_save_with_gnu_ld +lt_cv_path_LDCXX=$lt_cv_path_LD +lt_cv_path_LD=$lt_save_path_LD +lt_cv_prog_gnu_ldcxx=$lt_cv_prog_gnu_ld +lt_cv_prog_gnu_ld=$lt_save_with_gnu_ld +])# AC_LIBTOOL_LANG_CXX_CONFIG + +# AC_LIBTOOL_POSTDEP_PREDEP([TAGNAME]) +# ------------------------------------ +# Figure out "hidden" library dependencies from verbose +# compiler output when linking a shared library. +# Parse the compiler output and extract the necessary +# objects, libraries and library flags. +AC_DEFUN([AC_LIBTOOL_POSTDEP_PREDEP],[ +dnl we can't use the lt_simple_compile_test_code here, +dnl because it contains code intended for an executable, +dnl not a library. It's possible we should let each +dnl tag define a new lt_????_link_test_code variable, +dnl but it's only used here... +ifelse([$1],[],[cat > conftest.$ac_ext <<EOF +int a; +void foo (void) { a = 0; } +EOF +],[$1],[CXX],[cat > conftest.$ac_ext <<EOF +class Foo +{ +public: + Foo (void) { a = 0; } +private: + int a; +}; +EOF +],[$1],[F77],[cat > conftest.$ac_ext <<EOF + subroutine foo + implicit none + integer*4 a + a=0 + return + end +EOF +],[$1],[GCJ],[cat > conftest.$ac_ext <<EOF +public class foo { + private int a; + public void bar (void) { + a = 0; + } +}; +EOF +]) +dnl Parse the compiler output and extract the necessary +dnl objects, libraries and library flags. +if AC_TRY_EVAL(ac_compile); then + # Parse the compiler output and extract the necessary + # objects, libraries and library flags. + + # Sentinel used to keep track of whether or not we are before + # the conftest object file. + pre_test_object_deps_done=no + + # The `*' in the case matches for architectures that use `case' in + # $output_verbose_cmd can trigger glob expansion during the loop + # eval without this substitution. + output_verbose_link_cmd=`$echo "X$output_verbose_link_cmd" | $Xsed -e "$no_glob_subst"` + + for p in `eval $output_verbose_link_cmd`; do + case $p in + + -L* | -R* | -l*) + # Some compilers place space between "-{L,R}" and the path. + # Remove the space. + if test $p = "-L" \ + || test $p = "-R"; then + prev=$p + continue + else + prev= + fi + + if test "$pre_test_object_deps_done" = no; then + case $p in + -L* | -R*) + # Internal compiler library paths should come after those + # provided the user. The postdeps already come after the + # user supplied libs so there is no need to process them. + if test -z "$_LT_AC_TAGVAR(compiler_lib_search_path, $1)"; then + _LT_AC_TAGVAR(compiler_lib_search_path, $1)="${prev}${p}" + else + _LT_AC_TAGVAR(compiler_lib_search_path, $1)="${_LT_AC_TAGVAR(compiler_lib_search_path, $1)} ${prev}${p}" + fi + ;; + # The "-l" case would never come before the object being + # linked, so don't bother handling this case. + esac + else + if test -z "$_LT_AC_TAGVAR(postdeps, $1)"; then + _LT_AC_TAGVAR(postdeps, $1)="${prev}${p}" + else + _LT_AC_TAGVAR(postdeps, $1)="${_LT_AC_TAGVAR(postdeps, $1)} ${prev}${p}" + fi + fi + ;; + + *.$objext) + # This assumes that the test object file only shows up + # once in the compiler output. + if test "$p" = "conftest.$objext"; then + pre_test_object_deps_done=yes + continue + fi + + if test "$pre_test_object_deps_done" = no; then + if test -z "$_LT_AC_TAGVAR(predep_objects, $1)"; then + _LT_AC_TAGVAR(predep_objects, $1)="$p" + else + _LT_AC_TAGVAR(predep_objects, $1)="$_LT_AC_TAGVAR(predep_objects, $1) $p" + fi + else + if test -z "$_LT_AC_TAGVAR(postdep_objects, $1)"; then + _LT_AC_TAGVAR(postdep_objects, $1)="$p" + else + _LT_AC_TAGVAR(postdep_objects, $1)="$_LT_AC_TAGVAR(postdep_objects, $1) $p" + fi + fi + ;; + + *) ;; # Ignore the rest. + + esac + done + + # Clean up. + rm -f a.out a.exe +else + echo "libtool.m4: error: problem compiling $1 test program" +fi + +$rm -f confest.$objext + +# PORTME: override above test on systems where it is broken +ifelse([$1],[CXX], +[case $host_os in +interix3*) + # Interix 3.5 installs completely hosed .la files for C++, so rather than + # hack all around it, let's just trust "g++" to DTRT. + _LT_AC_TAGVAR(predep_objects,$1)= + _LT_AC_TAGVAR(postdep_objects,$1)= + _LT_AC_TAGVAR(postdeps,$1)= + ;; + +solaris*) + case $cc_basename in + CC*) + # Adding this requires a known-good setup of shared libraries for + # Sun compiler versions before 5.6, else PIC objects from an old + # archive will be linked into the output, leading to subtle bugs. + _LT_AC_TAGVAR(postdeps,$1)='-lCstd -lCrun' + ;; + esac + ;; +esac +]) + +case " $_LT_AC_TAGVAR(postdeps, $1) " in +*" -lc "*) _LT_AC_TAGVAR(archive_cmds_need_lc, $1)=no ;; +esac +])# AC_LIBTOOL_POSTDEP_PREDEP + +# AC_LIBTOOL_LANG_F77_CONFIG +# -------------------------- +# Ensure that the configuration vars for the C compiler are +# suitably defined. Those variables are subsequently used by +# AC_LIBTOOL_CONFIG to write the compiler configuration to `libtool'. +AC_DEFUN([AC_LIBTOOL_LANG_F77_CONFIG], [_LT_AC_LANG_F77_CONFIG(F77)]) +AC_DEFUN([_LT_AC_LANG_F77_CONFIG], +[AC_REQUIRE([AC_PROG_F77]) +AC_LANG_PUSH(Fortran 77) + +_LT_AC_TAGVAR(archive_cmds_need_lc, $1)=no +_LT_AC_TAGVAR(allow_undefined_flag, $1)= +_LT_AC_TAGVAR(always_export_symbols, $1)=no +_LT_AC_TAGVAR(archive_expsym_cmds, $1)= +_LT_AC_TAGVAR(export_dynamic_flag_spec, $1)= +_LT_AC_TAGVAR(hardcode_direct, $1)=no +_LT_AC_TAGVAR(hardcode_libdir_flag_spec, $1)= +_LT_AC_TAGVAR(hardcode_libdir_flag_spec_ld, $1)= +_LT_AC_TAGVAR(hardcode_libdir_separator, $1)= +_LT_AC_TAGVAR(hardcode_minus_L, $1)=no +_LT_AC_TAGVAR(hardcode_automatic, $1)=no +_LT_AC_TAGVAR(module_cmds, $1)= +_LT_AC_TAGVAR(module_expsym_cmds, $1)= +_LT_AC_TAGVAR(link_all_deplibs, $1)=unknown +_LT_AC_TAGVAR(old_archive_cmds, $1)=$old_archive_cmds +_LT_AC_TAGVAR(no_undefined_flag, $1)= +_LT_AC_TAGVAR(whole_archive_flag_spec, $1)= +_LT_AC_TAGVAR(enable_shared_with_static_runtimes, $1)=no + +# Source file extension for f77 test sources. +ac_ext=f + +# Object file extension for compiled f77 test sources. +objext=o +_LT_AC_TAGVAR(objext, $1)=$objext + +# Code to be used in simple compile tests +lt_simple_compile_test_code=" subroutine t\n return\n end\n" + +# Code to be used in simple link tests +lt_simple_link_test_code=" program t\n end\n" + +# ltmain only uses $CC for tagged configurations so make sure $CC is set. +_LT_AC_SYS_COMPILER + +# save warnings/boilerplate of simple test code +_LT_COMPILER_BOILERPLATE +_LT_LINKER_BOILERPLATE + +# Allow CC to be a program name with arguments. +lt_save_CC="$CC" +CC=${F77-"f77"} +compiler=$CC +_LT_AC_TAGVAR(compiler, $1)=$CC +_LT_CC_BASENAME([$compiler]) + +AC_MSG_CHECKING([if libtool supports shared libraries]) +AC_MSG_RESULT([$can_build_shared]) + +AC_MSG_CHECKING([whether to build shared libraries]) +test "$can_build_shared" = "no" && enable_shared=no + +# On AIX, shared libraries and static libraries use the same namespace, and +# are all built from PIC. +case $host_os in +aix3*) + test "$enable_shared" = yes && enable_static=no + if test -n "$RANLIB"; then + archive_cmds="$archive_cmds~\$RANLIB \$lib" + postinstall_cmds='$RANLIB $lib' + fi + ;; +aix4* | aix5*) + if test "$host_cpu" != ia64 && test "$aix_use_runtimelinking" = no ; then + test "$enable_shared" = yes && enable_static=no + fi + ;; +esac +AC_MSG_RESULT([$enable_shared]) + +AC_MSG_CHECKING([whether to build static libraries]) +# Make sure either enable_shared or enable_static is yes. +test "$enable_shared" = yes || enable_static=yes +AC_MSG_RESULT([$enable_static]) + +_LT_AC_TAGVAR(GCC, $1)="$G77" +_LT_AC_TAGVAR(LD, $1)="$LD" + +AC_LIBTOOL_PROG_COMPILER_PIC($1) +AC_LIBTOOL_PROG_CC_C_O($1) +AC_LIBTOOL_SYS_HARD_LINK_LOCKS($1) +AC_LIBTOOL_PROG_LD_SHLIBS($1) +AC_LIBTOOL_SYS_DYNAMIC_LINKER($1) +AC_LIBTOOL_PROG_LD_HARDCODE_LIBPATH($1) + +AC_LIBTOOL_CONFIG($1) + +AC_LANG_POP +CC="$lt_save_CC" +])# AC_LIBTOOL_LANG_F77_CONFIG + + +# AC_LIBTOOL_LANG_GCJ_CONFIG +# -------------------------- +# Ensure that the configuration vars for the C compiler are +# suitably defined. Those variables are subsequently used by +# AC_LIBTOOL_CONFIG to write the compiler configuration to `libtool'. +AC_DEFUN([AC_LIBTOOL_LANG_GCJ_CONFIG], [_LT_AC_LANG_GCJ_CONFIG(GCJ)]) +AC_DEFUN([_LT_AC_LANG_GCJ_CONFIG], +[AC_LANG_SAVE + +# Source file extension for Java test sources. +ac_ext=java + +# Object file extension for compiled Java test sources. +objext=o +_LT_AC_TAGVAR(objext, $1)=$objext + +# Code to be used in simple compile tests +lt_simple_compile_test_code="class foo {}\n" + +# Code to be used in simple link tests +lt_simple_link_test_code='public class conftest { public static void main(String[[]] argv) {}; }\n' + +# ltmain only uses $CC for tagged configurations so make sure $CC is set. +_LT_AC_SYS_COMPILER + +# save warnings/boilerplate of simple test code +_LT_COMPILER_BOILERPLATE +_LT_LINKER_BOILERPLATE + +# Allow CC to be a program name with arguments. +lt_save_CC="$CC" +CC=${GCJ-"gcj"} +compiler=$CC +_LT_AC_TAGVAR(compiler, $1)=$CC +_LT_CC_BASENAME([$compiler]) + +# GCJ did not exist at the time GCC didn't implicitly link libc in. +_LT_AC_TAGVAR(archive_cmds_need_lc, $1)=no + +_LT_AC_TAGVAR(old_archive_cmds, $1)=$old_archive_cmds + +AC_LIBTOOL_PROG_COMPILER_NO_RTTI($1) +AC_LIBTOOL_PROG_COMPILER_PIC($1) +AC_LIBTOOL_PROG_CC_C_O($1) +AC_LIBTOOL_SYS_HARD_LINK_LOCKS($1) +AC_LIBTOOL_PROG_LD_SHLIBS($1) +AC_LIBTOOL_SYS_DYNAMIC_LINKER($1) +AC_LIBTOOL_PROG_LD_HARDCODE_LIBPATH($1) + +AC_LIBTOOL_CONFIG($1) + +AC_LANG_RESTORE +CC="$lt_save_CC" +])# AC_LIBTOOL_LANG_GCJ_CONFIG + + +# AC_LIBTOOL_LANG_RC_CONFIG +# ------------------------- +# Ensure that the configuration vars for the Windows resource compiler are +# suitably defined. Those variables are subsequently used by +# AC_LIBTOOL_CONFIG to write the compiler configuration to `libtool'. +AC_DEFUN([AC_LIBTOOL_LANG_RC_CONFIG], [_LT_AC_LANG_RC_CONFIG(RC)]) +AC_DEFUN([_LT_AC_LANG_RC_CONFIG], +[AC_LANG_SAVE + +# Source file extension for RC test sources. +ac_ext=rc + +# Object file extension for compiled RC test sources. +objext=o +_LT_AC_TAGVAR(objext, $1)=$objext + +# Code to be used in simple compile tests +lt_simple_compile_test_code='sample MENU { MENUITEM "&Soup", 100, CHECKED }\n' + +# Code to be used in simple link tests +lt_simple_link_test_code="$lt_simple_compile_test_code" + +# ltmain only uses $CC for tagged configurations so make sure $CC is set. +_LT_AC_SYS_COMPILER + +# save warnings/boilerplate of simple test code +_LT_COMPILER_BOILERPLATE +_LT_LINKER_BOILERPLATE + +# Allow CC to be a program name with arguments. +lt_save_CC="$CC" +CC=${RC-"windres"} +compiler=$CC +_LT_AC_TAGVAR(compiler, $1)=$CC +_LT_CC_BASENAME([$compiler]) +_LT_AC_TAGVAR(lt_cv_prog_compiler_c_o, $1)=yes + +AC_LIBTOOL_CONFIG($1) + +AC_LANG_RESTORE +CC="$lt_save_CC" +])# AC_LIBTOOL_LANG_RC_CONFIG + + +# AC_LIBTOOL_CONFIG([TAGNAME]) +# ---------------------------- +# If TAGNAME is not passed, then create an initial libtool script +# with a default configuration from the untagged config vars. Otherwise +# add code to config.status for appending the configuration named by +# TAGNAME from the matching tagged config vars. +AC_DEFUN([AC_LIBTOOL_CONFIG], +[# The else clause should only fire when bootstrapping the +# libtool distribution, otherwise you forgot to ship ltmain.sh +# with your package, and you will get complaints that there are +# no rules to generate ltmain.sh. +if test -f "$ltmain"; then + # See if we are running on zsh, and set the options which allow our commands through + # without removal of \ escapes. + if test -n "${ZSH_VERSION+set}" ; then + setopt NO_GLOB_SUBST + fi + # Now quote all the things that may contain metacharacters while being + # careful not to overquote the AC_SUBSTed values. We take copies of the + # variables and quote the copies for generation of the libtool script. + for var in echo old_CC old_CFLAGS AR AR_FLAGS EGREP RANLIB LN_S LTCC LTCFLAGS NM \ + SED SHELL STRIP \ + libname_spec library_names_spec soname_spec extract_expsyms_cmds \ + old_striplib striplib file_magic_cmd finish_cmds finish_eval \ + deplibs_check_method reload_flag reload_cmds need_locks \ + lt_cv_sys_global_symbol_pipe lt_cv_sys_global_symbol_to_cdecl \ + lt_cv_sys_global_symbol_to_c_name_address \ + sys_lib_search_path_spec sys_lib_dlsearch_path_spec \ + old_postinstall_cmds old_postuninstall_cmds \ + _LT_AC_TAGVAR(compiler, $1) \ + _LT_AC_TAGVAR(CC, $1) \ + _LT_AC_TAGVAR(LD, $1) \ + _LT_AC_TAGVAR(lt_prog_compiler_wl, $1) \ + _LT_AC_TAGVAR(lt_prog_compiler_pic, $1) \ + _LT_AC_TAGVAR(lt_prog_compiler_static, $1) \ + _LT_AC_TAGVAR(lt_prog_compiler_no_builtin_flag, $1) \ + _LT_AC_TAGVAR(export_dynamic_flag_spec, $1) \ + _LT_AC_TAGVAR(thread_safe_flag_spec, $1) \ + _LT_AC_TAGVAR(whole_archive_flag_spec, $1) \ + _LT_AC_TAGVAR(enable_shared_with_static_runtimes, $1) \ + _LT_AC_TAGVAR(old_archive_cmds, $1) \ + _LT_AC_TAGVAR(old_archive_from_new_cmds, $1) \ + _LT_AC_TAGVAR(predep_objects, $1) \ + _LT_AC_TAGVAR(postdep_objects, $1) \ + _LT_AC_TAGVAR(predeps, $1) \ + _LT_AC_TAGVAR(postdeps, $1) \ + _LT_AC_TAGVAR(compiler_lib_search_path, $1) \ + _LT_AC_TAGVAR(archive_cmds, $1) \ + _LT_AC_TAGVAR(archive_expsym_cmds, $1) \ + _LT_AC_TAGVAR(postinstall_cmds, $1) \ + _LT_AC_TAGVAR(postuninstall_cmds, $1) \ + _LT_AC_TAGVAR(old_archive_from_expsyms_cmds, $1) \ + _LT_AC_TAGVAR(allow_undefined_flag, $1) \ + _LT_AC_TAGVAR(no_undefined_flag, $1) \ + _LT_AC_TAGVAR(export_symbols_cmds, $1) \ + _LT_AC_TAGVAR(hardcode_libdir_flag_spec, $1) \ + _LT_AC_TAGVAR(hardcode_libdir_flag_spec_ld, $1) \ + _LT_AC_TAGVAR(hardcode_libdir_separator, $1) \ + _LT_AC_TAGVAR(hardcode_automatic, $1) \ + _LT_AC_TAGVAR(module_cmds, $1) \ + _LT_AC_TAGVAR(module_expsym_cmds, $1) \ + _LT_AC_TAGVAR(lt_cv_prog_compiler_c_o, $1) \ + _LT_AC_TAGVAR(exclude_expsyms, $1) \ + _LT_AC_TAGVAR(include_expsyms, $1); do + + case $var in + _LT_AC_TAGVAR(old_archive_cmds, $1) | \ + _LT_AC_TAGVAR(old_archive_from_new_cmds, $1) | \ + _LT_AC_TAGVAR(archive_cmds, $1) | \ + _LT_AC_TAGVAR(archive_expsym_cmds, $1) | \ + _LT_AC_TAGVAR(module_cmds, $1) | \ + _LT_AC_TAGVAR(module_expsym_cmds, $1) | \ + _LT_AC_TAGVAR(old_archive_from_expsyms_cmds, $1) | \ + _LT_AC_TAGVAR(export_symbols_cmds, $1) | \ + extract_expsyms_cmds | reload_cmds | finish_cmds | \ + postinstall_cmds | postuninstall_cmds | \ + old_postinstall_cmds | old_postuninstall_cmds | \ + sys_lib_search_path_spec | sys_lib_dlsearch_path_spec) + # Double-quote double-evaled strings. + eval "lt_$var=\\\"\`\$echo \"X\$$var\" | \$Xsed -e \"\$double_quote_subst\" -e \"\$sed_quote_subst\" -e \"\$delay_variable_subst\"\`\\\"" + ;; + *) + eval "lt_$var=\\\"\`\$echo \"X\$$var\" | \$Xsed -e \"\$sed_quote_subst\"\`\\\"" + ;; + esac + done + + case $lt_echo in + *'\[$]0 --fallback-echo"') + lt_echo=`$echo "X$lt_echo" | $Xsed -e 's/\\\\\\\[$]0 --fallback-echo"[$]/[$]0 --fallback-echo"/'` + ;; + esac + +ifelse([$1], [], + [cfgfile="${ofile}T" + trap "$rm \"$cfgfile\"; exit 1" 1 2 15 + $rm -f "$cfgfile" + AC_MSG_NOTICE([creating $ofile])], + [cfgfile="$ofile"]) + + cat <<__EOF__ >> "$cfgfile" +ifelse([$1], [], +[#! $SHELL + +# `$echo "$cfgfile" | sed 's%^.*/%%'` - Provide generalized library-building support services. +# Generated automatically by $PROGRAM (GNU $PACKAGE $VERSION$TIMESTAMP) +# NOTE: Changes made to this file will be lost: look at ltmain.sh. +# +# Copyright (C) 1996, 1997, 1998, 1999, 2000, 2001 +# Free Software Foundation, Inc. +# +# This file is part of GNU Libtool: +# Originally by Gordon Matzigkeit <gord@gnu.ai.mit.edu>, 1996 +# +# 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. +# +# As a special exception to the GNU General Public License, if you +# distribute this file as part of a program that contains a +# configuration script generated by Autoconf, you may include it under +# the same distribution terms that you use for the rest of that program. + +# A sed program that does not truncate output. +SED=$lt_SED + +# Sed that helps us avoid accidentally triggering echo(1) options like -n. +Xsed="$SED -e 1s/^X//" + +# The HP-UX ksh and POSIX shell print the target directory to stdout +# if CDPATH is set. +(unset CDPATH) >/dev/null 2>&1 && unset CDPATH + +# The names of the tagged configurations supported by this script. +available_tags= + +# ### BEGIN LIBTOOL CONFIG], +[# ### BEGIN LIBTOOL TAG CONFIG: $tagname]) + +# Libtool was configured on host `(hostname || uname -n) 2>/dev/null | sed 1q`: + +# Shell to use when invoking shell scripts. +SHELL=$lt_SHELL + +# Whether or not to build shared libraries. +build_libtool_libs=$enable_shared + +# Whether or not to build static libraries. +build_old_libs=$enable_static + +# Whether or not to add -lc for building shared libraries. +build_libtool_need_lc=$_LT_AC_TAGVAR(archive_cmds_need_lc, $1) + +# Whether or not to disallow shared libs when runtime libs are static +allow_libtool_libs_with_static_runtimes=$_LT_AC_TAGVAR(enable_shared_with_static_runtimes, $1) + +# Whether or not to optimize for fast installation. +fast_install=$enable_fast_install + +# The host system. +host_alias=$host_alias +host=$host +host_os=$host_os + +# The build system. +build_alias=$build_alias +build=$build +build_os=$build_os + +# An echo program that does not interpret backslashes. +echo=$lt_echo + +# The archiver. +AR=$lt_AR +AR_FLAGS=$lt_AR_FLAGS + +# A C compiler. +LTCC=$lt_LTCC + +# LTCC compiler flags. +LTCFLAGS=$lt_LTCFLAGS + +# A language-specific compiler. +CC=$lt_[]_LT_AC_TAGVAR(compiler, $1) + +# Is the compiler the GNU C compiler? +with_gcc=$_LT_AC_TAGVAR(GCC, $1) + +gcc_dir=\`gcc -print-file-name=. | $SED 's,/\.$,,'\` +gcc_ver=\`gcc -dumpversion\` + +# An ERE matcher. +EGREP=$lt_EGREP + +# The linker used to build libraries. +LD=$lt_[]_LT_AC_TAGVAR(LD, $1) + +# Whether we need hard or soft links. +LN_S=$lt_LN_S + +# A BSD-compatible nm program. +NM=$lt_NM + +# A symbol stripping program +STRIP=$lt_STRIP + +# Used to examine libraries when file_magic_cmd begins "file" +MAGIC_CMD=$MAGIC_CMD + +# Used on cygwin: DLL creation program. +DLLTOOL="$DLLTOOL" + +# Used on cygwin: object dumper. +OBJDUMP="$OBJDUMP" + +# Used on cygwin: assembler. +AS="$AS" + +# The name of the directory that contains temporary libtool files. +objdir=$objdir + +# How to create reloadable object files. +reload_flag=$lt_reload_flag +reload_cmds=$lt_reload_cmds + +# How to pass a linker flag through the compiler. +wl=$lt_[]_LT_AC_TAGVAR(lt_prog_compiler_wl, $1) + +# Object file suffix (normally "o"). +objext="$ac_objext" + +# Old archive suffix (normally "a"). +libext="$libext" + +# Shared library suffix (normally ".so"). +shrext_cmds='$shrext_cmds' + +# Executable file suffix (normally ""). +exeext="$exeext" + +# Additional compiler flags for building library objects. +pic_flag=$lt_[]_LT_AC_TAGVAR(lt_prog_compiler_pic, $1) +pic_mode=$pic_mode + +# What is the maximum length of a command? +max_cmd_len=$lt_cv_sys_max_cmd_len + +# Does compiler simultaneously support -c and -o options? +compiler_c_o=$lt_[]_LT_AC_TAGVAR(lt_cv_prog_compiler_c_o, $1) + +# Must we lock files when doing compilation? +need_locks=$lt_need_locks + +# Do we need the lib prefix for modules? +need_lib_prefix=$need_lib_prefix + +# Do we need a version for libraries? +need_version=$need_version + +# Whether dlopen is supported. +dlopen_support=$enable_dlopen + +# Whether dlopen of programs is supported. +dlopen_self=$enable_dlopen_self + +# Whether dlopen of statically linked programs is supported. +dlopen_self_static=$enable_dlopen_self_static + +# Compiler flag to prevent dynamic linking. +link_static_flag=$lt_[]_LT_AC_TAGVAR(lt_prog_compiler_static, $1) + +# Compiler flag to turn off builtin functions. +no_builtin_flag=$lt_[]_LT_AC_TAGVAR(lt_prog_compiler_no_builtin_flag, $1) + +# Compiler flag to allow reflexive dlopens. +export_dynamic_flag_spec=$lt_[]_LT_AC_TAGVAR(export_dynamic_flag_spec, $1) + +# Compiler flag to generate shared objects directly from archives. +whole_archive_flag_spec=$lt_[]_LT_AC_TAGVAR(whole_archive_flag_spec, $1) + +# Compiler flag to generate thread-safe objects. +thread_safe_flag_spec=$lt_[]_LT_AC_TAGVAR(thread_safe_flag_spec, $1) + +# Library versioning type. +version_type=$version_type + +# Format of library name prefix. +libname_spec=$lt_libname_spec + +# List of archive names. First name is the real one, the rest are links. +# The last name is the one that the linker finds with -lNAME. +library_names_spec=$lt_library_names_spec + +# The coded name of the library, if different from the real name. +soname_spec=$lt_soname_spec + +# Commands used to build and install an old-style archive. +RANLIB=$lt_RANLIB +old_archive_cmds=$lt_[]_LT_AC_TAGVAR(old_archive_cmds, $1) +old_postinstall_cmds=$lt_old_postinstall_cmds +old_postuninstall_cmds=$lt_old_postuninstall_cmds + +# Create an old-style archive from a shared archive. +old_archive_from_new_cmds=$lt_[]_LT_AC_TAGVAR(old_archive_from_new_cmds, $1) + +# Create a temporary old-style archive to link instead of a shared archive. +old_archive_from_expsyms_cmds=$lt_[]_LT_AC_TAGVAR(old_archive_from_expsyms_cmds, $1) + +# Commands used to build and install a shared archive. +archive_cmds=$lt_[]_LT_AC_TAGVAR(archive_cmds, $1) +archive_expsym_cmds=$lt_[]_LT_AC_TAGVAR(archive_expsym_cmds, $1) +postinstall_cmds=$lt_postinstall_cmds +postuninstall_cmds=$lt_postuninstall_cmds + +# Commands used to build a loadable module (assumed same as above if empty) +module_cmds=$lt_[]_LT_AC_TAGVAR(module_cmds, $1) +module_expsym_cmds=$lt_[]_LT_AC_TAGVAR(module_expsym_cmds, $1) + +# Commands to strip libraries. +old_striplib=$lt_old_striplib +striplib=$lt_striplib + +# Dependencies to place before the objects being linked to create a +# shared library. +predep_objects=\`echo $lt_[]_LT_AC_TAGVAR(predep_objects, $1) | \$SED -e "s@\${gcc_dir}@\\\${gcc_dir}@g;s@\${gcc_ver}@\\\${gcc_ver}@g"\` + +# Dependencies to place after the objects being linked to create a +# shared library. +postdep_objects=\`echo $lt_[]_LT_AC_TAGVAR(postdep_objects, $1) | \$SED -e "s@\${gcc_dir}@\\\${gcc_dir}@g;s@\${gcc_ver}@\\\${gcc_ver}@g"\` + +# Dependencies to place before the objects being linked to create a +# shared library. +predeps=$lt_[]_LT_AC_TAGVAR(predeps, $1) + +# Dependencies to place after the objects being linked to create a +# shared library. +postdeps=$lt_[]_LT_AC_TAGVAR(postdeps, $1) + +# The library search path used internally by the compiler when linking +# a shared library. +compiler_lib_search_path=\`echo $lt_[]_LT_AC_TAGVAR(compiler_lib_search_path, $1) | \$SED -e "s@\${gcc_dir}@\\\${gcc_dir}@g;s@\${gcc_ver}@\\\${gcc_ver}@g"\` + +# Method to check whether dependent libraries are shared objects. +deplibs_check_method=$lt_deplibs_check_method + +# Command to use when deplibs_check_method == file_magic. +file_magic_cmd=$lt_file_magic_cmd + +# Flag that allows shared libraries with undefined symbols to be built. +allow_undefined_flag=$lt_[]_LT_AC_TAGVAR(allow_undefined_flag, $1) + +# Flag that forces no undefined symbols. +no_undefined_flag=$lt_[]_LT_AC_TAGVAR(no_undefined_flag, $1) + +# Commands used to finish a libtool library installation in a directory. +finish_cmds=$lt_finish_cmds + +# Same as above, but a single script fragment to be evaled but not shown. +finish_eval=$lt_finish_eval + +# Take the output of nm and produce a listing of raw symbols and C names. +global_symbol_pipe=$lt_lt_cv_sys_global_symbol_pipe + +# Transform the output of nm in a proper C declaration +global_symbol_to_cdecl=$lt_lt_cv_sys_global_symbol_to_cdecl + +# Transform the output of nm in a C name address pair +global_symbol_to_c_name_address=$lt_lt_cv_sys_global_symbol_to_c_name_address + +# This is the shared library runtime path variable. +runpath_var=$runpath_var + +# This is the shared library path variable. +shlibpath_var=$shlibpath_var + +# Is shlibpath searched before the hard-coded library search path? +shlibpath_overrides_runpath=$shlibpath_overrides_runpath + +# How to hardcode a shared library path into an executable. +hardcode_action=$_LT_AC_TAGVAR(hardcode_action, $1) + +# Whether we should hardcode library paths into libraries. +hardcode_into_libs=$hardcode_into_libs + +# Flag to hardcode \$libdir into a binary during linking. +# This must work even if \$libdir does not exist. +hardcode_libdir_flag_spec=$lt_[]_LT_AC_TAGVAR(hardcode_libdir_flag_spec, $1) + +# If ld is used when linking, flag to hardcode \$libdir into +# a binary during linking. This must work even if \$libdir does +# not exist. +hardcode_libdir_flag_spec_ld=$lt_[]_LT_AC_TAGVAR(hardcode_libdir_flag_spec_ld, $1) + +# Whether we need a single -rpath flag with a separated argument. +hardcode_libdir_separator=$lt_[]_LT_AC_TAGVAR(hardcode_libdir_separator, $1) + +# Set to yes if using DIR/libNAME${shared_ext} during linking hardcodes DIR into the +# resulting binary. +hardcode_direct=$_LT_AC_TAGVAR(hardcode_direct, $1) + +# Set to yes if using the -LDIR flag during linking hardcodes DIR into the +# resulting binary. +hardcode_minus_L=$_LT_AC_TAGVAR(hardcode_minus_L, $1) + +# Set to yes if using SHLIBPATH_VAR=DIR during linking hardcodes DIR into +# the resulting binary. +hardcode_shlibpath_var=$_LT_AC_TAGVAR(hardcode_shlibpath_var, $1) + +# Set to yes if building a shared library automatically hardcodes DIR into the library +# and all subsequent libraries and executables linked against it. +hardcode_automatic=$_LT_AC_TAGVAR(hardcode_automatic, $1) + +# Variables whose values should be saved in libtool wrapper scripts and +# restored at relink time. +variables_saved_for_relink="$variables_saved_for_relink" + +# Whether libtool must link a program against all its dependency libraries. +link_all_deplibs=$_LT_AC_TAGVAR(link_all_deplibs, $1) + +# Compile-time system search path for libraries +sys_lib_search_path_spec=\`echo $lt_sys_lib_search_path_spec | \$SED -e "s@\${gcc_dir}@\\\${gcc_dir}@g;s@\${gcc_ver}@\\\${gcc_ver}@g"\` + +# Run-time system search path for libraries +sys_lib_dlsearch_path_spec=$lt_sys_lib_dlsearch_path_spec + +# Fix the shell variable \$srcfile for the compiler. +fix_srcfile_path="$_LT_AC_TAGVAR(fix_srcfile_path, $1)" + +# Set to yes if exported symbols are required. +always_export_symbols=$_LT_AC_TAGVAR(always_export_symbols, $1) + +# The commands to list exported symbols. +export_symbols_cmds=$lt_[]_LT_AC_TAGVAR(export_symbols_cmds, $1) + +# The commands to extract the exported symbol list from a shared archive. +extract_expsyms_cmds=$lt_extract_expsyms_cmds + +# Symbols that should not be listed in the preloaded symbols. +exclude_expsyms=$lt_[]_LT_AC_TAGVAR(exclude_expsyms, $1) + +# Symbols that must always be exported. +include_expsyms=$lt_[]_LT_AC_TAGVAR(include_expsyms, $1) + +ifelse([$1],[], +[# ### END LIBTOOL CONFIG], +[# ### END LIBTOOL TAG CONFIG: $tagname]) + +__EOF__ + +ifelse([$1],[], [ + case $host_os in + aix3*) + cat <<\EOF >> "$cfgfile" + +# AIX sometimes has problems with the GCC collect2 program. For some +# reason, if we set the COLLECT_NAMES environment variable, the problems +# vanish in a puff of smoke. +if test "X${COLLECT_NAMES+set}" != Xset; then + COLLECT_NAMES= + export COLLECT_NAMES +fi +EOF + ;; + esac + + # We use sed instead of cat because bash on DJGPP gets confused if + # if finds mixed CR/LF and LF-only lines. Since sed operates in + # text mode, it properly converts lines to CR/LF. This bash problem + # is reportedly fixed, but why not run on old versions too? + sed '$q' "$ltmain" >> "$cfgfile" || (rm -f "$cfgfile"; exit 1) + + mv -f "$cfgfile" "$ofile" || \ + (rm -f "$ofile" && cp "$cfgfile" "$ofile" && rm -f "$cfgfile") + chmod +x "$ofile" +]) +else + # If there is no Makefile yet, we rely on a make rule to execute + # `config.status --recheck' to rerun these tests and create the + # libtool script then. + ltmain_in=`echo $ltmain | sed -e 's/\.sh$/.in/'` + if test -f "$ltmain_in"; then + test -f Makefile && make "$ltmain" + fi +fi +])# AC_LIBTOOL_CONFIG + + +# AC_LIBTOOL_PROG_COMPILER_NO_RTTI([TAGNAME]) +# ------------------------------------------- +AC_DEFUN([AC_LIBTOOL_PROG_COMPILER_NO_RTTI], +[AC_REQUIRE([_LT_AC_SYS_COMPILER])dnl + +_LT_AC_TAGVAR(lt_prog_compiler_no_builtin_flag, $1)= + +if test "$GCC" = yes; then + _LT_AC_TAGVAR(lt_prog_compiler_no_builtin_flag, $1)=' -fno-builtin' + + AC_LIBTOOL_COMPILER_OPTION([if $compiler supports -fno-rtti -fno-exceptions], + lt_cv_prog_compiler_rtti_exceptions, + [-fno-rtti -fno-exceptions], [], + [_LT_AC_TAGVAR(lt_prog_compiler_no_builtin_flag, $1)="$_LT_AC_TAGVAR(lt_prog_compiler_no_builtin_flag, $1) -fno-rtti -fno-exceptions"]) +fi +])# AC_LIBTOOL_PROG_COMPILER_NO_RTTI + + +# AC_LIBTOOL_SYS_GLOBAL_SYMBOL_PIPE +# --------------------------------- +AC_DEFUN([AC_LIBTOOL_SYS_GLOBAL_SYMBOL_PIPE], +[AC_REQUIRE([AC_CANONICAL_HOST]) +AC_REQUIRE([AC_PROG_NM]) +AC_REQUIRE([AC_OBJEXT]) +# Check for command to grab the raw symbol name followed by C symbol from nm. +AC_MSG_CHECKING([command to parse $NM output from $compiler object]) +AC_CACHE_VAL([lt_cv_sys_global_symbol_pipe], +[ +# These are sane defaults that work on at least a few old systems. +# [They come from Ultrix. What could be older than Ultrix?!! ;)] + +# Character class describing NM global symbol codes. +symcode='[[BCDEGRST]]' + +# Regexp to match symbols that can be accessed directly from C. +sympat='\([[_A-Za-z]][[_A-Za-z0-9]]*\)' + +# Transform an extracted symbol line into a proper C declaration +lt_cv_sys_global_symbol_to_cdecl="sed -n -e 's/^. .* \(.*\)$/extern int \1;/p'" + +# Transform an extracted symbol line into symbol name and symbol address +lt_cv_sys_global_symbol_to_c_name_address="sed -n -e 's/^: \([[^ ]]*\) $/ {\\\"\1\\\", (lt_ptr) 0},/p' -e 's/^$symcode \([[^ ]]*\) \([[^ ]]*\)$/ {\"\2\", (lt_ptr) \&\2},/p'" + +# Define system-specific variables. +case $host_os in +aix*) + symcode='[[BCDT]]' + ;; +cygwin* | mingw* | pw32*) + symcode='[[ABCDGISTW]]' + ;; +hpux*) # Its linker distinguishes data from code symbols + if test "$host_cpu" = ia64; then + symcode='[[ABCDEGRST]]' + fi + lt_cv_sys_global_symbol_to_cdecl="sed -n -e 's/^T .* \(.*\)$/extern int \1();/p' -e 's/^$symcode* .* \(.*\)$/extern char \1;/p'" + lt_cv_sys_global_symbol_to_c_name_address="sed -n -e 's/^: \([[^ ]]*\) $/ {\\\"\1\\\", (lt_ptr) 0},/p' -e 's/^$symcode* \([[^ ]]*\) \([[^ ]]*\)$/ {\"\2\", (lt_ptr) \&\2},/p'" + ;; +linux*) + if test "$host_cpu" = ia64; then + symcode='[[ABCDGIRSTW]]' + lt_cv_sys_global_symbol_to_cdecl="sed -n -e 's/^T .* \(.*\)$/extern int \1();/p' -e 's/^$symcode* .* \(.*\)$/extern char \1;/p'" + lt_cv_sys_global_symbol_to_c_name_address="sed -n -e 's/^: \([[^ ]]*\) $/ {\\\"\1\\\", (lt_ptr) 0},/p' -e 's/^$symcode* \([[^ ]]*\) \([[^ ]]*\)$/ {\"\2\", (lt_ptr) \&\2},/p'" + fi + ;; +irix* | nonstopux*) + symcode='[[BCDEGRST]]' + ;; +osf*) + symcode='[[BCDEGQRST]]' + ;; +solaris*) + symcode='[[BDRT]]' + ;; +sco3.2v5*) + symcode='[[DT]]' + ;; +sysv4.2uw2*) + symcode='[[DT]]' + ;; +sysv5* | sco5v6* | unixware* | OpenUNIX*) + symcode='[[ABDT]]' + ;; +sysv4) + symcode='[[DFNSTU]]' + ;; +esac + +# Handle CRLF in mingw tool chain +opt_cr= +case $build_os in +mingw*) + opt_cr=`echo 'x\{0,1\}' | tr x '\015'` # option cr in regexp + ;; +esac + +# If we're using GNU nm, then use its standard symbol codes. +case `$NM -V 2>&1` in +*GNU* | *'with BFD'*) + symcode='[[ABCDGIRSTW]]' ;; +esac + +# Try without a prefix undercore, then with it. +for ac_symprfx in "" "_"; do + + # Transform symcode, sympat, and symprfx into a raw symbol and a C symbol. + symxfrm="\\1 $ac_symprfx\\2 \\2" + + # Write the raw and C identifiers. + lt_cv_sys_global_symbol_pipe="sed -n -e 's/^.*[[ ]]\($symcode$symcode*\)[[ ]][[ ]]*$ac_symprfx$sympat$opt_cr$/$symxfrm/p'" + + # Check to see that the pipe works correctly. + pipe_works=no + + rm -f conftest* + cat > conftest.$ac_ext <<EOF +#ifdef __cplusplus +extern "C" { +#endif +char nm_test_var; +void nm_test_func(){} +#ifdef __cplusplus +} +#endif +int main(){nm_test_var='a';nm_test_func();return(0);} +EOF + + if AC_TRY_EVAL(ac_compile); then + # Now try to grab the symbols. + nlist=conftest.nm + if AC_TRY_EVAL(NM conftest.$ac_objext \| $lt_cv_sys_global_symbol_pipe \> $nlist) && test -s "$nlist"; then + # Try sorting and uniquifying the output. + if sort "$nlist" | uniq > "$nlist"T; then + mv -f "$nlist"T "$nlist" + else + rm -f "$nlist"T + fi + + # Make sure that we snagged all the symbols we need. + if grep ' nm_test_var$' "$nlist" >/dev/null; then + if grep ' nm_test_func$' "$nlist" >/dev/null; then + cat <<EOF > conftest.$ac_ext +#ifdef __cplusplus +extern "C" { +#endif + +EOF + # Now generate the symbol file. + eval "$lt_cv_sys_global_symbol_to_cdecl"' < "$nlist" | grep -v main >> conftest.$ac_ext' + + cat <<EOF >> conftest.$ac_ext +#if defined (__STDC__) && __STDC__ +# define lt_ptr_t void * +#else +# define lt_ptr_t char * +# define const +#endif + +/* The mapping between symbol names and symbols. */ +const struct { + const char *name; + lt_ptr_t address; +} +lt_preloaded_symbols[[]] = +{ +EOF + $SED "s/^$symcode$symcode* \(.*\) \(.*\)$/ {\"\2\", (lt_ptr_t) \&\2},/" < "$nlist" | grep -v main >> conftest.$ac_ext + cat <<\EOF >> conftest.$ac_ext + {0, (lt_ptr_t) 0} +}; + +#ifdef __cplusplus +} +#endif +EOF + # Now try linking the two files. + mv conftest.$ac_objext conftstm.$ac_objext + lt_save_LIBS="$LIBS" + lt_save_CFLAGS="$CFLAGS" + LIBS="conftstm.$ac_objext" + CFLAGS="$CFLAGS$_LT_AC_TAGVAR(lt_prog_compiler_no_builtin_flag, $1)" + if AC_TRY_EVAL(ac_link) && test -s conftest${ac_exeext}; then + pipe_works=yes + fi + LIBS="$lt_save_LIBS" + CFLAGS="$lt_save_CFLAGS" + else + echo "cannot find nm_test_func in $nlist" >&AS_MESSAGE_LOG_FD + fi + else + echo "cannot find nm_test_var in $nlist" >&AS_MESSAGE_LOG_FD + fi + else + echo "cannot run $lt_cv_sys_global_symbol_pipe" >&AS_MESSAGE_LOG_FD + fi + else + echo "$progname: failed program was:" >&AS_MESSAGE_LOG_FD + cat conftest.$ac_ext >&5 + fi + rm -f conftest* conftst* + + # Do not use the global_symbol_pipe unless it works. + if test "$pipe_works" = yes; then + break + else + lt_cv_sys_global_symbol_pipe= + fi +done +]) +if test -z "$lt_cv_sys_global_symbol_pipe"; then + lt_cv_sys_global_symbol_to_cdecl= +fi +if test -z "$lt_cv_sys_global_symbol_pipe$lt_cv_sys_global_symbol_to_cdecl"; then + AC_MSG_RESULT(failed) +else + AC_MSG_RESULT(ok) +fi +]) # AC_LIBTOOL_SYS_GLOBAL_SYMBOL_PIPE + + +# AC_LIBTOOL_PROG_COMPILER_PIC([TAGNAME]) +# --------------------------------------- +AC_DEFUN([AC_LIBTOOL_PROG_COMPILER_PIC], +[_LT_AC_TAGVAR(lt_prog_compiler_wl, $1)= +_LT_AC_TAGVAR(lt_prog_compiler_pic, $1)= +_LT_AC_TAGVAR(lt_prog_compiler_static, $1)= + +AC_MSG_CHECKING([for $compiler option to produce PIC]) + ifelse([$1],[CXX],[ + # C++ specific cases for pic, static, wl, etc. + if test "$GXX" = yes; then + _LT_AC_TAGVAR(lt_prog_compiler_wl, $1)='-Wl,' + _LT_AC_TAGVAR(lt_prog_compiler_static, $1)='-static' + + case $host_os in + aix*) + # All AIX code is PIC. + if test "$host_cpu" = ia64; then + # AIX 5 now supports IA64 processor + _LT_AC_TAGVAR(lt_prog_compiler_static, $1)='-Bstatic' + fi + ;; + amigaos*) + # FIXME: we need at least 68020 code to build shared libraries, but + # adding the `-m68020' flag to GCC prevents building anything better, + # like `-m68040'. + _LT_AC_TAGVAR(lt_prog_compiler_pic, $1)='-m68020 -resident32 -malways-restore-a4' + ;; + beos* | cygwin* | irix5* | irix6* | nonstopux* | osf3* | osf4* | osf5*) + # PIC is the default for these OSes. + ;; + mingw* | os2* | pw32*) + # This hack is so that the source file can tell whether it is being + # built for inclusion in a dll (and should export symbols for example). + _LT_AC_TAGVAR(lt_prog_compiler_pic, $1)='-DDLL_EXPORT' + ;; + darwin* | rhapsody*) + # PIC is the default on this platform + # Common symbols not allowed in MH_DYLIB files + _LT_AC_TAGVAR(lt_prog_compiler_pic, $1)='-fno-common' + ;; + *djgpp*) + # DJGPP does not support shared libraries at all + _LT_AC_TAGVAR(lt_prog_compiler_pic, $1)= + ;; + interix3*) + # Interix 3.x gcc -fpic/-fPIC options generate broken code. + # Instead, we relocate shared libraries at runtime. + ;; + sysv4*MP*) + if test -d /usr/nec; then + _LT_AC_TAGVAR(lt_prog_compiler_pic, $1)=-Kconform_pic + fi + ;; + hpux*) + # PIC is the default for IA64 HP-UX and 64-bit HP-UX, but + # not for PA HP-UX. + case $host_cpu in + hppa*64*|ia64*) + ;; + *) + _LT_AC_TAGVAR(lt_prog_compiler_pic, $1)='-fPIC' + ;; + esac + ;; + *) + _LT_AC_TAGVAR(lt_prog_compiler_pic, $1)='-fPIC' + ;; + esac + else + case $host_os in + aix4* | aix5*) + # All AIX code is PIC. + if test "$host_cpu" = ia64; then + # AIX 5 now supports IA64 processor + _LT_AC_TAGVAR(lt_prog_compiler_static, $1)='-Bstatic' + else + _LT_AC_TAGVAR(lt_prog_compiler_static, $1)='-bnso -bI:/lib/syscalls.exp' + fi + ;; + chorus*) + case $cc_basename in + cxch68*) + # Green Hills C++ Compiler + # _LT_AC_TAGVAR(lt_prog_compiler_static, $1)="--no_auto_instantiation -u __main -u __premain -u _abort -r $COOL_DIR/lib/libOrb.a $MVME_DIR/lib/CC/libC.a $MVME_DIR/lib/classix/libcx.s.a" + ;; + esac + ;; + darwin*) + # PIC is the default on this platform + # Common symbols not allowed in MH_DYLIB files + case $cc_basename in + xlc*) + _LT_AC_TAGVAR(lt_prog_compiler_pic, $1)='-qnocommon' + _LT_AC_TAGVAR(lt_prog_compiler_wl, $1)='-Wl,' + ;; + esac + ;; + dgux*) + case $cc_basename in + ec++*) + _LT_AC_TAGVAR(lt_prog_compiler_pic, $1)='-KPIC' + ;; + ghcx*) + # Green Hills C++ Compiler + _LT_AC_TAGVAR(lt_prog_compiler_pic, $1)='-pic' + ;; + *) + ;; + esac + ;; + freebsd* | kfreebsd*-gnu | dragonfly*) + # FreeBSD uses GNU C++ + ;; + hpux9* | hpux10* | hpux11*) + case $cc_basename in + CC*) + _LT_AC_TAGVAR(lt_prog_compiler_wl, $1)='-Wl,' + _LT_AC_TAGVAR(lt_prog_compiler_static, $1)='${wl}-a ${wl}archive' + if test "$host_cpu" != ia64; then + _LT_AC_TAGVAR(lt_prog_compiler_pic, $1)='+Z' + fi + ;; + aCC*) + _LT_AC_TAGVAR(lt_prog_compiler_wl, $1)='-Wl,' + _LT_AC_TAGVAR(lt_prog_compiler_static, $1)='${wl}-a ${wl}archive' + case $host_cpu in + hppa*64*|ia64*) + # +Z the default + ;; + *) + _LT_AC_TAGVAR(lt_prog_compiler_pic, $1)='+Z' + ;; + esac + ;; + *) + ;; + esac + ;; + interix*) + # This is c89, which is MS Visual C++ (no shared libs) + # Anyone wants to do a port? + ;; + irix5* | irix6* | nonstopux*) + case $cc_basename in + CC*) + _LT_AC_TAGVAR(lt_prog_compiler_wl, $1)='-Wl,' + _LT_AC_TAGVAR(lt_prog_compiler_static, $1)='-non_shared' + # CC pic flag -KPIC is the default. + ;; + *) + ;; + esac + ;; + linux*) + case $cc_basename in + KCC*) + # KAI C++ Compiler + _LT_AC_TAGVAR(lt_prog_compiler_wl, $1)='--backend -Wl,' + _LT_AC_TAGVAR(lt_prog_compiler_pic, $1)='-fPIC' + ;; + icpc* | ecpc*) + # Intel C++ + _LT_AC_TAGVAR(lt_prog_compiler_wl, $1)='-Wl,' + _LT_AC_TAGVAR(lt_prog_compiler_pic, $1)='-KPIC' + _LT_AC_TAGVAR(lt_prog_compiler_static, $1)='-static' + ;; + pgCC*) + # Portland Group C++ compiler. + _LT_AC_TAGVAR(lt_prog_compiler_wl, $1)='-Wl,' + _LT_AC_TAGVAR(lt_prog_compiler_pic, $1)='-fpic' + _LT_AC_TAGVAR(lt_prog_compiler_static, $1)='-Bstatic' + ;; + cxx*) + # Compaq C++ + # Make sure the PIC flag is empty. It appears that all Alpha + # Linux and Compaq Tru64 Unix objects are PIC. + _LT_AC_TAGVAR(lt_prog_compiler_pic, $1)= + _LT_AC_TAGVAR(lt_prog_compiler_static, $1)='-non_shared' + ;; + *) + ;; + esac + ;; + lynxos*) + ;; + m88k*) + ;; + mvs*) + case $cc_basename in + cxx*) + _LT_AC_TAGVAR(lt_prog_compiler_pic, $1)='-W c,exportall' + ;; + *) + ;; + esac + ;; + netbsd*) + ;; + osf3* | osf4* | osf5*) + case $cc_basename in + KCC*) + _LT_AC_TAGVAR(lt_prog_compiler_wl, $1)='--backend -Wl,' + ;; + RCC*) + # Rational C++ 2.4.1 + _LT_AC_TAGVAR(lt_prog_compiler_pic, $1)='-pic' + ;; + cxx*) + # Digital/Compaq C++ + _LT_AC_TAGVAR(lt_prog_compiler_wl, $1)='-Wl,' + # Make sure the PIC flag is empty. It appears that all Alpha + # Linux and Compaq Tru64 Unix objects are PIC. + _LT_AC_TAGVAR(lt_prog_compiler_pic, $1)= + _LT_AC_TAGVAR(lt_prog_compiler_static, $1)='-non_shared' + ;; + *) + ;; + esac + ;; + psos*) + ;; + solaris*) + case $cc_basename in + CC*) + # Sun C++ 4.2, 5.x and Centerline C++ + _LT_AC_TAGVAR(lt_prog_compiler_pic, $1)='-KPIC' + _LT_AC_TAGVAR(lt_prog_compiler_static, $1)='-Bstatic' + _LT_AC_TAGVAR(lt_prog_compiler_wl, $1)='-Qoption ld ' + ;; + gcx*) + # Green Hills C++ Compiler + _LT_AC_TAGVAR(lt_prog_compiler_pic, $1)='-PIC' + ;; + *) + ;; + esac + ;; + sunos4*) + case $cc_basename in + CC*) + # Sun C++ 4.x + _LT_AC_TAGVAR(lt_prog_compiler_pic, $1)='-pic' + _LT_AC_TAGVAR(lt_prog_compiler_static, $1)='-Bstatic' + ;; + lcc*) + # Lucid + _LT_AC_TAGVAR(lt_prog_compiler_pic, $1)='-pic' + ;; + *) + ;; + esac + ;; + tandem*) + case $cc_basename in + NCC*) + # NonStop-UX NCC 3.20 + _LT_AC_TAGVAR(lt_prog_compiler_pic, $1)='-KPIC' + ;; + *) + ;; + esac + ;; + sysv5* | unixware* | sco3.2v5* | sco5v6* | OpenUNIX*) + case $cc_basename in + CC*) + _LT_AC_TAGVAR(lt_prog_compiler_wl, $1)='-Wl,' + _LT_AC_TAGVAR(lt_prog_compiler_pic, $1)='-KPIC' + _LT_AC_TAGVAR(lt_prog_compiler_static, $1)='-Bstatic' + ;; + esac + ;; + vxworks*) + ;; + *) + _LT_AC_TAGVAR(lt_prog_compiler_can_build_shared, $1)=no + ;; + esac + fi +], +[ + if test "$GCC" = yes; then + _LT_AC_TAGVAR(lt_prog_compiler_wl, $1)='-Wl,' + _LT_AC_TAGVAR(lt_prog_compiler_static, $1)='-static' + + case $host_os in + aix*) + # All AIX code is PIC. + if test "$host_cpu" = ia64; then + # AIX 5 now supports IA64 processor + _LT_AC_TAGVAR(lt_prog_compiler_static, $1)='-Bstatic' + fi + ;; + + amigaos*) + # FIXME: we need at least 68020 code to build shared libraries, but + # adding the `-m68020' flag to GCC prevents building anything better, + # like `-m68040'. + _LT_AC_TAGVAR(lt_prog_compiler_pic, $1)='-m68020 -resident32 -malways-restore-a4' + ;; + + beos* | cygwin* | irix5* | irix6* | nonstopux* | osf3* | osf4* | osf5*) + # PIC is the default for these OSes. + ;; + + mingw* | pw32* | os2*) + # This hack is so that the source file can tell whether it is being + # built for inclusion in a dll (and should export symbols for example). + _LT_AC_TAGVAR(lt_prog_compiler_pic, $1)='-DDLL_EXPORT' + ;; + + darwin* | rhapsody*) + # PIC is the default on this platform + # Common symbols not allowed in MH_DYLIB files + _LT_AC_TAGVAR(lt_prog_compiler_pic, $1)='-fno-common' + ;; + + interix3*) + # Interix 3.x gcc -fpic/-fPIC options generate broken code. + # Instead, we relocate shared libraries at runtime. + ;; + + msdosdjgpp*) + # Just because we use GCC doesn't mean we suddenly get shared libraries + # on systems that don't support them. + _LT_AC_TAGVAR(lt_prog_compiler_can_build_shared, $1)=no + enable_shared=no + ;; + + sysv4*MP*) + if test -d /usr/nec; then + _LT_AC_TAGVAR(lt_prog_compiler_pic, $1)=-Kconform_pic + fi + ;; + + hpux*) + # PIC is the default for IA64 HP-UX and 64-bit HP-UX, but + # not for PA HP-UX. + case $host_cpu in + hppa*64*|ia64*) + # +Z the default + ;; + *) + _LT_AC_TAGVAR(lt_prog_compiler_pic, $1)='-fPIC' + ;; + esac + ;; + + *) + _LT_AC_TAGVAR(lt_prog_compiler_pic, $1)='-fPIC' + ;; + esac + else + # PORTME Check for flag to pass linker flags through the system compiler. + case $host_os in + aix*) + _LT_AC_TAGVAR(lt_prog_compiler_wl, $1)='-Wl,' + if test "$host_cpu" = ia64; then + # AIX 5 now supports IA64 processor + _LT_AC_TAGVAR(lt_prog_compiler_static, $1)='-Bstatic' + else + _LT_AC_TAGVAR(lt_prog_compiler_static, $1)='-bnso -bI:/lib/syscalls.exp' + fi + ;; + darwin*) + # PIC is the default on this platform + # Common symbols not allowed in MH_DYLIB files + case $cc_basename in + xlc*) + _LT_AC_TAGVAR(lt_prog_compiler_pic, $1)='-qnocommon' + _LT_AC_TAGVAR(lt_prog_compiler_wl, $1)='-Wl,' + ;; + esac + ;; + + mingw* | pw32* | os2*) + # This hack is so that the source file can tell whether it is being + # built for inclusion in a dll (and should export symbols for example). + _LT_AC_TAGVAR(lt_prog_compiler_pic, $1)='-DDLL_EXPORT' + ;; + + hpux9* | hpux10* | hpux11*) + _LT_AC_TAGVAR(lt_prog_compiler_wl, $1)='-Wl,' + # PIC is the default for IA64 HP-UX and 64-bit HP-UX, but + # not for PA HP-UX. + case $host_cpu in + hppa*64*|ia64*) + # +Z the default + ;; + *) + _LT_AC_TAGVAR(lt_prog_compiler_pic, $1)='+Z' + ;; + esac + # Is there a better lt_prog_compiler_static that works with the bundled CC? + _LT_AC_TAGVAR(lt_prog_compiler_static, $1)='${wl}-a ${wl}archive' + ;; + + irix5* | irix6* | nonstopux*) + _LT_AC_TAGVAR(lt_prog_compiler_wl, $1)='-Wl,' + # PIC (with -KPIC) is the default. + _LT_AC_TAGVAR(lt_prog_compiler_static, $1)='-non_shared' + ;; + + newsos6) + _LT_AC_TAGVAR(lt_prog_compiler_pic, $1)='-KPIC' + _LT_AC_TAGVAR(lt_prog_compiler_static, $1)='-Bstatic' + ;; + + linux*) + case $cc_basename in + icc* | ecc*) + _LT_AC_TAGVAR(lt_prog_compiler_wl, $1)='-Wl,' + _LT_AC_TAGVAR(lt_prog_compiler_pic, $1)='-KPIC' + _LT_AC_TAGVAR(lt_prog_compiler_static, $1)='-static' + ;; + pgcc* | pgf77* | pgf90* | pgf95*) + # Portland Group compilers (*not* the Pentium gcc compiler, + # which looks to be a dead project) + _LT_AC_TAGVAR(lt_prog_compiler_wl, $1)='-Wl,' + _LT_AC_TAGVAR(lt_prog_compiler_pic, $1)='-fpic' + _LT_AC_TAGVAR(lt_prog_compiler_static, $1)='-Bstatic' + ;; + ccc*) + _LT_AC_TAGVAR(lt_prog_compiler_wl, $1)='-Wl,' + # All Alpha code is PIC. + _LT_AC_TAGVAR(lt_prog_compiler_static, $1)='-non_shared' + ;; + esac + ;; + + osf3* | osf4* | osf5*) + _LT_AC_TAGVAR(lt_prog_compiler_wl, $1)='-Wl,' + # All OSF/1 code is PIC. + _LT_AC_TAGVAR(lt_prog_compiler_static, $1)='-non_shared' + ;; + + solaris*) + _LT_AC_TAGVAR(lt_prog_compiler_pic, $1)='-KPIC' + _LT_AC_TAGVAR(lt_prog_compiler_static, $1)='-Bstatic' + case $cc_basename in + f77* | f90* | f95*) + _LT_AC_TAGVAR(lt_prog_compiler_wl, $1)='-Qoption ld ';; + *) + _LT_AC_TAGVAR(lt_prog_compiler_wl, $1)='-Wl,';; + esac + ;; + + sunos4*) + _LT_AC_TAGVAR(lt_prog_compiler_wl, $1)='-Qoption ld ' + _LT_AC_TAGVAR(lt_prog_compiler_pic, $1)='-PIC' + _LT_AC_TAGVAR(lt_prog_compiler_static, $1)='-Bstatic' + ;; + + sysv4 | sysv4.2uw2* | sysv4.3*) + _LT_AC_TAGVAR(lt_prog_compiler_wl, $1)='-Wl,' + _LT_AC_TAGVAR(lt_prog_compiler_pic, $1)='-KPIC' + _LT_AC_TAGVAR(lt_prog_compiler_static, $1)='-Bstatic' + ;; + + sysv4*MP*) + if test -d /usr/nec ;then + _LT_AC_TAGVAR(lt_prog_compiler_pic, $1)='-Kconform_pic' + _LT_AC_TAGVAR(lt_prog_compiler_static, $1)='-Bstatic' + fi + ;; + + sysv5* | unixware* | sco3.2v5* | sco5v6* | OpenUNIX*) + _LT_AC_TAGVAR(lt_prog_compiler_wl, $1)='-Wl,' + _LT_AC_TAGVAR(lt_prog_compiler_pic, $1)='-KPIC' + _LT_AC_TAGVAR(lt_prog_compiler_static, $1)='-Bstatic' + ;; + + unicos*) + _LT_AC_TAGVAR(lt_prog_compiler_wl, $1)='-Wl,' + _LT_AC_TAGVAR(lt_prog_compiler_can_build_shared, $1)=no + ;; + + uts4*) + _LT_AC_TAGVAR(lt_prog_compiler_pic, $1)='-pic' + _LT_AC_TAGVAR(lt_prog_compiler_static, $1)='-Bstatic' + ;; + + *) + _LT_AC_TAGVAR(lt_prog_compiler_can_build_shared, $1)=no + ;; + esac + fi +]) +AC_MSG_RESULT([$_LT_AC_TAGVAR(lt_prog_compiler_pic, $1)]) + +# +# Check to make sure the PIC flag actually works. +# +if test -n "$_LT_AC_TAGVAR(lt_prog_compiler_pic, $1)"; then + AC_LIBTOOL_COMPILER_OPTION([if $compiler PIC flag $_LT_AC_TAGVAR(lt_prog_compiler_pic, $1) works], + _LT_AC_TAGVAR(lt_prog_compiler_pic_works, $1), + [$_LT_AC_TAGVAR(lt_prog_compiler_pic, $1)ifelse([$1],[],[ -DPIC],[ifelse([$1],[CXX],[ -DPIC],[])])], [], + [case $_LT_AC_TAGVAR(lt_prog_compiler_pic, $1) in + "" | " "*) ;; + *) _LT_AC_TAGVAR(lt_prog_compiler_pic, $1)=" $_LT_AC_TAGVAR(lt_prog_compiler_pic, $1)" ;; + esac], + [_LT_AC_TAGVAR(lt_prog_compiler_pic, $1)= + _LT_AC_TAGVAR(lt_prog_compiler_can_build_shared, $1)=no]) +fi +case $host_os in + # For platforms which do not support PIC, -DPIC is meaningless: + *djgpp*) + _LT_AC_TAGVAR(lt_prog_compiler_pic, $1)= + ;; + *) + _LT_AC_TAGVAR(lt_prog_compiler_pic, $1)="$_LT_AC_TAGVAR(lt_prog_compiler_pic, $1)ifelse([$1],[],[ -DPIC],[ifelse([$1],[CXX],[ -DPIC],[])])" + ;; +esac + +# +# Check to make sure the static flag actually works. +# +wl=$_LT_AC_TAGVAR(lt_prog_compiler_wl, $1) eval lt_tmp_static_flag=\"$_LT_AC_TAGVAR(lt_prog_compiler_static, $1)\" +AC_LIBTOOL_LINKER_OPTION([if $compiler static flag $lt_tmp_static_flag works], + _LT_AC_TAGVAR(lt_prog_compiler_static_works, $1), + $lt_tmp_static_flag, + [], + [_LT_AC_TAGVAR(lt_prog_compiler_static, $1)=]) +]) + + +# AC_LIBTOOL_PROG_LD_SHLIBS([TAGNAME]) +# ------------------------------------ +# See if the linker supports building shared libraries. +AC_DEFUN([AC_LIBTOOL_PROG_LD_SHLIBS], +[AC_MSG_CHECKING([whether the $compiler linker ($LD) supports shared libraries]) +ifelse([$1],[CXX],[ + _LT_AC_TAGVAR(export_symbols_cmds, $1)='$NM $libobjs $convenience | $global_symbol_pipe | $SED '\''s/.* //'\'' | sort | uniq > $export_symbols' + case $host_os in + aix4* | aix5*) + # If we're using GNU nm, then we don't want the "-C" option. + # -C means demangle to AIX nm, but means don't demangle with GNU nm + if $NM -V 2>&1 | grep 'GNU' > /dev/null; then + _LT_AC_TAGVAR(export_symbols_cmds, $1)='$NM -Bpg $libobjs $convenience | awk '\''{ if (((\[$]2 == "T") || (\[$]2 == "D") || (\[$]2 == "B")) && ([substr](\[$]3,1,1) != ".")) { print \[$]3 } }'\'' | sort -u > $export_symbols' + else + _LT_AC_TAGVAR(export_symbols_cmds, $1)='$NM -BCpg $libobjs $convenience | awk '\''{ if (((\[$]2 == "T") || (\[$]2 == "D") || (\[$]2 == "B")) && ([substr](\[$]3,1,1) != ".")) { print \[$]3 } }'\'' | sort -u > $export_symbols' + fi + ;; + pw32*) + _LT_AC_TAGVAR(export_symbols_cmds, $1)="$ltdll_cmds" + ;; + cygwin* | mingw*) + _LT_AC_TAGVAR(export_symbols_cmds, $1)='$NM $libobjs $convenience | $global_symbol_pipe | $SED -e '\''/^[[BCDGRS]] /s/.* \([[^ ]]*\)/\1 DATA/;/^.* __nm__/s/^.* __nm__\([[^ ]]*\) [[^ ]]*/\1 DATA/;/^I /d;/^[[AITW]] /s/.* //'\'' | sort | uniq > $export_symbols' + ;; + *) + _LT_AC_TAGVAR(export_symbols_cmds, $1)='$NM $libobjs $convenience | $global_symbol_pipe | $SED '\''s/.* //'\'' | sort | uniq > $export_symbols' + ;; + esac +],[ + runpath_var= + _LT_AC_TAGVAR(allow_undefined_flag, $1)= + _LT_AC_TAGVAR(enable_shared_with_static_runtimes, $1)=no + _LT_AC_TAGVAR(archive_cmds, $1)= + _LT_AC_TAGVAR(archive_expsym_cmds, $1)= + _LT_AC_TAGVAR(old_archive_From_new_cmds, $1)= + _LT_AC_TAGVAR(old_archive_from_expsyms_cmds, $1)= + _LT_AC_TAGVAR(export_dynamic_flag_spec, $1)= + _LT_AC_TAGVAR(whole_archive_flag_spec, $1)= + _LT_AC_TAGVAR(thread_safe_flag_spec, $1)= + _LT_AC_TAGVAR(hardcode_libdir_flag_spec, $1)= + _LT_AC_TAGVAR(hardcode_libdir_flag_spec_ld, $1)= + _LT_AC_TAGVAR(hardcode_libdir_separator, $1)= + _LT_AC_TAGVAR(hardcode_direct, $1)=no + _LT_AC_TAGVAR(hardcode_minus_L, $1)=no + _LT_AC_TAGVAR(hardcode_shlibpath_var, $1)=unsupported + _LT_AC_TAGVAR(link_all_deplibs, $1)=unknown + _LT_AC_TAGVAR(hardcode_automatic, $1)=no + _LT_AC_TAGVAR(module_cmds, $1)= + _LT_AC_TAGVAR(module_expsym_cmds, $1)= + _LT_AC_TAGVAR(always_export_symbols, $1)=no + _LT_AC_TAGVAR(export_symbols_cmds, $1)='$NM $libobjs $convenience | $global_symbol_pipe | $SED '\''s/.* //'\'' | sort | uniq > $export_symbols' + # include_expsyms should be a list of space-separated symbols to be *always* + # included in the symbol list + _LT_AC_TAGVAR(include_expsyms, $1)= + # exclude_expsyms can be an extended regexp of symbols to exclude + # it will be wrapped by ` (' and `)$', so one must not match beginning or + # end of line. Example: `a|bc|.*d.*' will exclude the symbols `a' and `bc', + # as well as any symbol that contains `d'. + _LT_AC_TAGVAR(exclude_expsyms, $1)="_GLOBAL_OFFSET_TABLE_" + # Although _GLOBAL_OFFSET_TABLE_ is a valid symbol C name, most a.out + # platforms (ab)use it in PIC code, but their linkers get confused if + # the symbol is explicitly referenced. Since portable code cannot + # rely on this symbol name, it's probably fine to never include it in + # preloaded symbol tables. + extract_expsyms_cmds= + # Just being paranoid about ensuring that cc_basename is set. + _LT_CC_BASENAME([$compiler]) + case $host_os in + cygwin* | mingw* | pw32*) + # FIXME: the MSVC++ port hasn't been tested in a loooong time + # When not using gcc, we currently assume that we are using + # Microsoft Visual C++. + if test "$GCC" != yes; then + with_gnu_ld=no + fi + ;; + interix*) + # we just hope/assume this is gcc and not c89 (= MSVC++) + with_gnu_ld=yes + ;; + openbsd*) + with_gnu_ld=no + ;; + esac + + _LT_AC_TAGVAR(ld_shlibs, $1)=yes + if test "$with_gnu_ld" = yes; then + # If archive_cmds runs LD, not CC, wlarc should be empty + wlarc='${wl}' + + # Set some defaults for GNU ld with shared library support. These + # are reset later if shared libraries are not supported. Putting them + # here allows them to be overridden if necessary. + runpath_var=LD_RUN_PATH + _LT_AC_TAGVAR(hardcode_libdir_flag_spec, $1)='${wl}--rpath ${wl}$libdir' + _LT_AC_TAGVAR(export_dynamic_flag_spec, $1)='${wl}--export-dynamic' + # ancient GNU ld didn't support --whole-archive et. al. + if $LD --help 2>&1 | grep 'no-whole-archive' > /dev/null; then + _LT_AC_TAGVAR(whole_archive_flag_spec, $1)="$wlarc"'--whole-archive$convenience '"$wlarc"'--no-whole-archive' + else + _LT_AC_TAGVAR(whole_archive_flag_spec, $1)= + fi + supports_anon_versioning=no + case `$LD -v 2>/dev/null` in + *\ [[01]].* | *\ 2.[[0-9]].* | *\ 2.10.*) ;; # catch versions < 2.11 + *\ 2.11.93.0.2\ *) supports_anon_versioning=yes ;; # RH7.3 ... + *\ 2.11.92.0.12\ *) supports_anon_versioning=yes ;; # Mandrake 8.2 ... + *\ 2.11.*) ;; # other 2.11 versions + *) supports_anon_versioning=yes ;; + esac + + # See if GNU ld supports shared libraries. + case $host_os in + aix3* | aix4* | aix5*) + # On AIX/PPC, the GNU linker is very broken + if test "$host_cpu" != ia64; then + _LT_AC_TAGVAR(ld_shlibs, $1)=no + cat <<EOF 1>&2 + +*** Warning: the GNU linker, at least up to release 2.9.1, is reported +*** to be unable to reliably create shared libraries on AIX. +*** Therefore, libtool is disabling shared libraries support. If you +*** really care for shared libraries, you may want to modify your PATH +*** so that a non-GNU linker is found, and then restart. + +EOF + fi + ;; + + amigaos*) + _LT_AC_TAGVAR(archive_cmds, $1)='$rm $output_objdir/a2ixlibrary.data~$echo "#define NAME $libname" > $output_objdir/a2ixlibrary.data~$echo "#define LIBRARY_ID 1" >> $output_objdir/a2ixlibrary.data~$echo "#define VERSION $major" >> $output_objdir/a2ixlibrary.data~$echo "#define REVISION $revision" >> $output_objdir/a2ixlibrary.data~$AR $AR_FLAGS $lib $libobjs~$RANLIB $lib~(cd $output_objdir && a2ixlibrary -32)' + _LT_AC_TAGVAR(hardcode_libdir_flag_spec, $1)='-L$libdir' + _LT_AC_TAGVAR(hardcode_minus_L, $1)=yes + + # Samuel A. Falvo II <kc5tja@dolphin.openprojects.net> reports + # that the semantics of dynamic libraries on AmigaOS, at least up + # to version 4, is to share data among multiple programs linked + # with the same dynamic library. Since this doesn't match the + # behavior of shared libraries on other platforms, we can't use + # them. + _LT_AC_TAGVAR(ld_shlibs, $1)=no + ;; + + beos*) + if $LD --help 2>&1 | grep ': supported targets:.* elf' > /dev/null; then + _LT_AC_TAGVAR(allow_undefined_flag, $1)=unsupported + # Joseph Beckenbach <jrb3@best.com> says some releases of gcc + # support --undefined. This deserves some investigation. FIXME + _LT_AC_TAGVAR(archive_cmds, $1)='$CC -nostart $libobjs $deplibs $compiler_flags ${wl}-soname $wl$soname -o $lib' + else + _LT_AC_TAGVAR(ld_shlibs, $1)=no + fi + ;; + + cygwin* | mingw* | pw32*) + # _LT_AC_TAGVAR(hardcode_libdir_flag_spec, $1) is actually meaningless, + # as there is no search path for DLLs. + _LT_AC_TAGVAR(hardcode_libdir_flag_spec, $1)='-L$libdir' + _LT_AC_TAGVAR(allow_undefined_flag, $1)=unsupported + _LT_AC_TAGVAR(always_export_symbols, $1)=no + _LT_AC_TAGVAR(enable_shared_with_static_runtimes, $1)=yes + _LT_AC_TAGVAR(export_symbols_cmds, $1)='$NM $libobjs $convenience | $global_symbol_pipe | $SED -e '\''/^[[BCDGRS]] /s/.* \([[^ ]]*\)/\1 DATA/'\'' | $SED -e '\''/^[[AITW]] /s/.* //'\'' | sort | uniq > $export_symbols' + + if $LD --help 2>&1 | grep 'auto-import' > /dev/null; then + _LT_AC_TAGVAR(archive_cmds, $1)='$CC -shared $libobjs $deplibs $compiler_flags -o $output_objdir/$soname ${wl}--enable-auto-image-base -Xlinker --out-implib -Xlinker $lib' + # If the export-symbols file already is a .def file (1st line + # is EXPORTS), use it as is; otherwise, prepend... + _LT_AC_TAGVAR(archive_expsym_cmds, $1)='if test "x`$SED 1q $export_symbols`" = xEXPORTS; then + cp $export_symbols $output_objdir/$soname.def; + else + echo EXPORTS > $output_objdir/$soname.def; + cat $export_symbols >> $output_objdir/$soname.def; + fi~ + $CC -shared $output_objdir/$soname.def $libobjs $deplibs $compiler_flags -o $output_objdir/$soname ${wl}--enable-auto-image-base -Xlinker --out-implib -Xlinker $lib' + else + _LT_AC_TAGVAR(ld_shlibs, $1)=no + fi + ;; + + interix3*) + _LT_AC_TAGVAR(hardcode_direct, $1)=no + _LT_AC_TAGVAR(hardcode_shlibpath_var, $1)=no + _LT_AC_TAGVAR(hardcode_libdir_flag_spec, $1)='${wl}-rpath,$libdir' + _LT_AC_TAGVAR(export_dynamic_flag_spec, $1)='${wl}-E' + # Hack: On Interix 3.x, we cannot compile PIC because of a broken gcc. + # Instead, shared libraries are loaded at an image base (0x10000000 by + # default) and relocated if they conflict, which is a slow very memory + # consuming and fragmenting process. To avoid this, we pick a random, + # 256 KiB-aligned image base between 0x50000000 and 0x6FFC0000 at link + # time. Moving up from 0x10000000 also allows more sbrk(2) space. + _LT_AC_TAGVAR(archive_cmds, $1)='$CC -shared $pic_flag $libobjs $deplibs $compiler_flags ${wl}-h,$soname ${wl}--image-base,`expr ${RANDOM-$$} % 4096 / 2 \* 262144 + 1342177280` -o $lib' + _LT_AC_TAGVAR(archive_expsym_cmds, $1)='sed "s,^,_," $export_symbols >$output_objdir/$soname.expsym~$CC -shared $pic_flag $libobjs $deplibs $compiler_flags ${wl}-h,$soname ${wl}--retain-symbols-file,$output_objdir/$soname.expsym ${wl}--image-base,`expr ${RANDOM-$$} % 4096 / 2 \* 262144 + 1342177280` -o $lib' + ;; + + linux*) + if $LD --help 2>&1 | grep ': supported targets:.* elf' > /dev/null; then + tmp_addflag= + case $cc_basename,$host_cpu in + pgcc*) # Portland Group C compiler + _LT_AC_TAGVAR(whole_archive_flag_spec, $1)='${wl}--whole-archive`for conv in $convenience\"\"; do test -n \"$conv\" && new_convenience=\"$new_convenience,$conv\"; done; $echo \"$new_convenience\"` ${wl}--no-whole-archive' + tmp_addflag=' $pic_flag' + ;; + pgf77* | pgf90* | pgf95*) # Portland Group f77 and f90 compilers + _LT_AC_TAGVAR(whole_archive_flag_spec, $1)='${wl}--whole-archive`for conv in $convenience\"\"; do test -n \"$conv\" && new_convenience=\"$new_convenience,$conv\"; done; $echo \"$new_convenience\"` ${wl}--no-whole-archive' + tmp_addflag=' $pic_flag -Mnomain' ;; + ecc*,ia64* | icc*,ia64*) # Intel C compiler on ia64 + tmp_addflag=' -i_dynamic' ;; + efc*,ia64* | ifort*,ia64*) # Intel Fortran compiler on ia64 + tmp_addflag=' -i_dynamic -nofor_main' ;; + ifc* | ifort*) # Intel Fortran compiler + tmp_addflag=' -nofor_main' ;; + esac + _LT_AC_TAGVAR(archive_cmds, $1)='$CC -shared'"$tmp_addflag"' $libobjs $deplibs $compiler_flags ${wl}-soname $wl$soname -o $lib' + + if test $supports_anon_versioning = yes; then + _LT_AC_TAGVAR(archive_expsym_cmds, $1)='$echo "{ global:" > $output_objdir/$libname.ver~ + cat $export_symbols | sed -e "s/\(.*\)/\1;/" >> $output_objdir/$libname.ver~ + $echo "local: *; };" >> $output_objdir/$libname.ver~ + $CC -shared'"$tmp_addflag"' $libobjs $deplibs $compiler_flags ${wl}-soname $wl$soname ${wl}-version-script ${wl}$output_objdir/$libname.ver -o $lib' + fi + else + _LT_AC_TAGVAR(ld_shlibs, $1)=no + fi + ;; + + netbsd*) + if echo __ELF__ | $CC -E - | grep __ELF__ >/dev/null; then + _LT_AC_TAGVAR(archive_cmds, $1)='$LD -Bshareable $libobjs $deplibs $linker_flags -o $lib' + wlarc= + else + _LT_AC_TAGVAR(archive_cmds, $1)='$CC -shared $libobjs $deplibs $compiler_flags ${wl}-soname $wl$soname -o $lib' + _LT_AC_TAGVAR(archive_expsym_cmds, $1)='$CC -shared $libobjs $deplibs $compiler_flags ${wl}-soname $wl$soname ${wl}-retain-symbols-file $wl$export_symbols -o $lib' + fi + ;; + + solaris*) + if $LD -v 2>&1 | grep 'BFD 2\.8' > /dev/null; then + _LT_AC_TAGVAR(ld_shlibs, $1)=no + cat <<EOF 1>&2 + +*** Warning: The releases 2.8.* of the GNU linker cannot reliably +*** create shared libraries on Solaris systems. Therefore, libtool +*** is disabling shared libraries support. We urge you to upgrade GNU +*** binutils to release 2.9.1 or newer. Another option is to modify +*** your PATH or compiler configuration so that the native linker is +*** used, and then restart. + +EOF + elif $LD --help 2>&1 | grep ': supported targets:.* elf' > /dev/null; then + _LT_AC_TAGVAR(archive_cmds, $1)='$CC -shared $libobjs $deplibs $compiler_flags ${wl}-soname $wl$soname -o $lib' + _LT_AC_TAGVAR(archive_expsym_cmds, $1)='$CC -shared $libobjs $deplibs $compiler_flags ${wl}-soname $wl$soname ${wl}-retain-symbols-file $wl$export_symbols -o $lib' + else + _LT_AC_TAGVAR(ld_shlibs, $1)=no + fi + ;; + + sysv5* | sco3.2v5* | sco5v6* | unixware* | OpenUNIX*) + case `$LD -v 2>&1` in + *\ [[01]].* | *\ 2.[[0-9]].* | *\ 2.1[[0-5]].*) + _LT_AC_TAGVAR(ld_shlibs, $1)=no + cat <<_LT_EOF 1>&2 + +*** Warning: Releases of the GNU linker prior to 2.16.91.0.3 can not +*** reliably create shared libraries on SCO systems. Therefore, libtool +*** is disabling shared libraries support. We urge you to upgrade GNU +*** binutils to release 2.16.91.0.3 or newer. Another option is to modify +*** your PATH or compiler configuration so that the native linker is +*** used, and then restart. + +_LT_EOF + ;; + *) + if $LD --help 2>&1 | grep ': supported targets:.* elf' > /dev/null; then + _LT_AC_TAGVAR(hardcode_libdir_flag_spec, $1)='`test -z "$SCOABSPATH" && echo ${wl}-rpath,$libdir`' + _LT_AC_TAGVAR(archive_cmds, $1)='$CC -shared $libobjs $deplibs $compiler_flags ${wl}-soname,\${SCOABSPATH:+${install_libdir}/}$soname -o $lib' + _LT_AC_TAGVAR(archive_expsym_cmds, $1)='$CC -shared $libobjs $deplibs $compiler_flags ${wl}-soname,\${SCOABSPATH:+${install_libdir}/}$soname,-retain-symbols-file,$export_symbols -o $lib' + else + _LT_AC_TAGVAR(ld_shlibs, $1)=no + fi + ;; + esac + ;; + + sunos4*) + _LT_AC_TAGVAR(archive_cmds, $1)='$LD -assert pure-text -Bshareable -o $lib $libobjs $deplibs $linker_flags' + wlarc= + _LT_AC_TAGVAR(hardcode_direct, $1)=yes + _LT_AC_TAGVAR(hardcode_shlibpath_var, $1)=no + ;; + + *) + if $LD --help 2>&1 | grep ': supported targets:.* elf' > /dev/null; then + _LT_AC_TAGVAR(archive_cmds, $1)='$CC -shared $libobjs $deplibs $compiler_flags ${wl}-soname $wl$soname -o $lib' + _LT_AC_TAGVAR(archive_expsym_cmds, $1)='$CC -shared $libobjs $deplibs $compiler_flags ${wl}-soname $wl$soname ${wl}-retain-symbols-file $wl$export_symbols -o $lib' + else + _LT_AC_TAGVAR(ld_shlibs, $1)=no + fi + ;; + esac + + if test "$_LT_AC_TAGVAR(ld_shlibs, $1)" = no; then + runpath_var= + _LT_AC_TAGVAR(hardcode_libdir_flag_spec, $1)= + _LT_AC_TAGVAR(export_dynamic_flag_spec, $1)= + _LT_AC_TAGVAR(whole_archive_flag_spec, $1)= + fi + else + # PORTME fill in a description of your system's linker (not GNU ld) + case $host_os in + aix3*) + _LT_AC_TAGVAR(allow_undefined_flag, $1)=unsupported + _LT_AC_TAGVAR(always_export_symbols, $1)=yes + _LT_AC_TAGVAR(archive_expsym_cmds, $1)='$LD -o $output_objdir/$soname $libobjs $deplibs $linker_flags -bE:$export_symbols -T512 -H512 -bM:SRE~$AR $AR_FLAGS $lib $output_objdir/$soname' + # Note: this linker hardcodes the directories in LIBPATH if there + # are no directories specified by -L. + _LT_AC_TAGVAR(hardcode_minus_L, $1)=yes + if test "$GCC" = yes && test -z "$lt_prog_compiler_static"; then + # Neither direct hardcoding nor static linking is supported with a + # broken collect2. + _LT_AC_TAGVAR(hardcode_direct, $1)=unsupported + fi + ;; + + aix4* | aix5*) + if test "$host_cpu" = ia64; then + # On IA64, the linker does run time linking by default, so we don't + # have to do anything special. + aix_use_runtimelinking=no + exp_sym_flag='-Bexport' + no_entry_flag="" + else + # If we're using GNU nm, then we don't want the "-C" option. + # -C means demangle to AIX nm, but means don't demangle with GNU nm + if $NM -V 2>&1 | grep 'GNU' > /dev/null; then + _LT_AC_TAGVAR(export_symbols_cmds, $1)='$NM -Bpg $libobjs $convenience | awk '\''{ if (((\[$]2 == "T") || (\[$]2 == "D") || (\[$]2 == "B")) && ([substr](\[$]3,1,1) != ".")) { print \[$]3 } }'\'' | sort -u > $export_symbols' + else + _LT_AC_TAGVAR(export_symbols_cmds, $1)='$NM -BCpg $libobjs $convenience | awk '\''{ if (((\[$]2 == "T") || (\[$]2 == "D") || (\[$]2 == "B")) && ([substr](\[$]3,1,1) != ".")) { print \[$]3 } }'\'' | sort -u > $export_symbols' + fi + aix_use_runtimelinking=no + + # Test if we are trying to use run time linking or normal + # AIX style linking. If -brtl is somewhere in LDFLAGS, we + # need to do runtime linking. + case $host_os in aix4.[[23]]|aix4.[[23]].*|aix5*) + for ld_flag in $LDFLAGS; do + if (test $ld_flag = "-brtl" || test $ld_flag = "-Wl,-brtl"); then + aix_use_runtimelinking=yes + break + fi + done + ;; + esac + + exp_sym_flag='-bexport' + no_entry_flag='-bnoentry' + fi + + # When large executables or shared objects are built, AIX ld can + # have problems creating the table of contents. If linking a library + # or program results in "error TOC overflow" add -mminimal-toc to + # CXXFLAGS/CFLAGS for g++/gcc. In the cases where that is not + # enough to fix the problem, add -Wl,-bbigtoc to LDFLAGS. + + _LT_AC_TAGVAR(archive_cmds, $1)='' + _LT_AC_TAGVAR(hardcode_direct, $1)=yes + _LT_AC_TAGVAR(hardcode_libdir_separator, $1)=':' + _LT_AC_TAGVAR(link_all_deplibs, $1)=yes + + if test "$GCC" = yes; then + case $host_os in aix4.[[012]]|aix4.[[012]].*) + # We only want to do this on AIX 4.2 and lower, the check + # below for broken collect2 doesn't work under 4.3+ + collect2name=`${CC} -print-prog-name=collect2` + if test -f "$collect2name" && \ + strings "$collect2name" | grep resolve_lib_name >/dev/null + then + # We have reworked collect2 + _LT_AC_TAGVAR(hardcode_direct, $1)=yes + else + # We have old collect2 + _LT_AC_TAGVAR(hardcode_direct, $1)=unsupported + # It fails to find uninstalled libraries when the uninstalled + # path is not listed in the libpath. Setting hardcode_minus_L + # to unsupported forces relinking + _LT_AC_TAGVAR(hardcode_minus_L, $1)=yes + _LT_AC_TAGVAR(hardcode_libdir_flag_spec, $1)='-L$libdir' + _LT_AC_TAGVAR(hardcode_libdir_separator, $1)= + fi + ;; + esac + shared_flag='-shared' + if test "$aix_use_runtimelinking" = yes; then + shared_flag="$shared_flag "'${wl}-G' + fi + else + # not using gcc + if test "$host_cpu" = ia64; then + # VisualAge C++, Version 5.5 for AIX 5L for IA-64, Beta 3 Release + # chokes on -Wl,-G. The following line is correct: + shared_flag='-G' + else + if test "$aix_use_runtimelinking" = yes; then + shared_flag='${wl}-G' + else + shared_flag='${wl}-bM:SRE' + fi + fi + fi + + # It seems that -bexpall does not export symbols beginning with + # underscore (_), so it is better to generate a list of symbols to export. + _LT_AC_TAGVAR(always_export_symbols, $1)=yes + if test "$aix_use_runtimelinking" = yes; then + # Warning - without using the other runtime loading flags (-brtl), + # -berok will link without error, but may produce a broken library. + _LT_AC_TAGVAR(allow_undefined_flag, $1)='-berok' + # Determine the default libpath from the value encoded in an empty executable. + _LT_AC_SYS_LIBPATH_AIX + _LT_AC_TAGVAR(hardcode_libdir_flag_spec, $1)='${wl}-blibpath:$libdir:'"$aix_libpath" + _LT_AC_TAGVAR(archive_expsym_cmds, $1)="\$CC"' -o $output_objdir/$soname $libobjs $deplibs '"\${wl}$no_entry_flag"' $compiler_flags `if test "x${allow_undefined_flag}" != "x"; then echo "${wl}${allow_undefined_flag}"; else :; fi` '"\${wl}$exp_sym_flag:\$export_symbols $shared_flag" + else + if test "$host_cpu" = ia64; then + _LT_AC_TAGVAR(hardcode_libdir_flag_spec, $1)='${wl}-R $libdir:/usr/lib:/lib' + _LT_AC_TAGVAR(allow_undefined_flag, $1)="-z nodefs" + _LT_AC_TAGVAR(archive_expsym_cmds, $1)="\$CC $shared_flag"' -o $output_objdir/$soname $libobjs $deplibs '"\${wl}$no_entry_flag"' $compiler_flags ${wl}${allow_undefined_flag} '"\${wl}$exp_sym_flag:\$export_symbols" + else + # Determine the default libpath from the value encoded in an empty executable. + _LT_AC_SYS_LIBPATH_AIX + _LT_AC_TAGVAR(hardcode_libdir_flag_spec, $1)='${wl}-blibpath:$libdir:'"$aix_libpath" + # Warning - without using the other run time loading flags, + # -berok will link without error, but may produce a broken library. + _LT_AC_TAGVAR(no_undefined_flag, $1)=' ${wl}-bernotok' + _LT_AC_TAGVAR(allow_undefined_flag, $1)=' ${wl}-berok' + # Exported symbols can be pulled into shared objects from archives + _LT_AC_TAGVAR(whole_archive_flag_spec, $1)='$convenience' + _LT_AC_TAGVAR(archive_cmds_need_lc, $1)=yes + # This is similar to how AIX traditionally builds its shared libraries. + _LT_AC_TAGVAR(archive_expsym_cmds, $1)="\$CC $shared_flag"' -o $output_objdir/$soname $libobjs $deplibs ${wl}-bnoentry $compiler_flags ${wl}-bE:$export_symbols${allow_undefined_flag}~$AR $AR_FLAGS $output_objdir/$libname$release.a $output_objdir/$soname' + fi + fi + ;; + + amigaos*) + _LT_AC_TAGVAR(archive_cmds, $1)='$rm $output_objdir/a2ixlibrary.data~$echo "#define NAME $libname" > $output_objdir/a2ixlibrary.data~$echo "#define LIBRARY_ID 1" >> $output_objdir/a2ixlibrary.data~$echo "#define VERSION $major" >> $output_objdir/a2ixlibrary.data~$echo "#define REVISION $revision" >> $output_objdir/a2ixlibrary.data~$AR $AR_FLAGS $lib $libobjs~$RANLIB $lib~(cd $output_objdir && a2ixlibrary -32)' + _LT_AC_TAGVAR(hardcode_libdir_flag_spec, $1)='-L$libdir' + _LT_AC_TAGVAR(hardcode_minus_L, $1)=yes + # see comment about different semantics on the GNU ld section + _LT_AC_TAGVAR(ld_shlibs, $1)=no + ;; + + bsdi[[45]]*) + _LT_AC_TAGVAR(export_dynamic_flag_spec, $1)=-rdynamic + ;; + + cygwin* | mingw* | pw32*) + # When not using gcc, we currently assume that we are using + # Microsoft Visual C++. + # hardcode_libdir_flag_spec is actually meaningless, as there is + # no search path for DLLs. + _LT_AC_TAGVAR(hardcode_libdir_flag_spec, $1)=' ' + _LT_AC_TAGVAR(allow_undefined_flag, $1)=unsupported + # Tell ltmain to make .lib files, not .a files. + libext=lib + # Tell ltmain to make .dll files, not .so files. + shrext_cmds=".dll" + # FIXME: Setting linknames here is a bad hack. + _LT_AC_TAGVAR(archive_cmds, $1)='$CC -o $lib $libobjs $compiler_flags `echo "$deplibs" | $SED -e '\''s/ -lc$//'\''` -link -dll~linknames=' + # The linker will automatically build a .lib file if we build a DLL. + _LT_AC_TAGVAR(old_archive_From_new_cmds, $1)='true' + # FIXME: Should let the user specify the lib program. + _LT_AC_TAGVAR(old_archive_cmds, $1)='lib /OUT:$oldlib$oldobjs$old_deplibs' + _LT_AC_TAGVAR(fix_srcfile_path, $1)='`cygpath -w "$srcfile"`' + _LT_AC_TAGVAR(enable_shared_with_static_runtimes, $1)=yes + ;; + + darwin* | rhapsody*) + case $host_os in + rhapsody* | darwin1.[[012]]) + _LT_AC_TAGVAR(allow_undefined_flag, $1)='${wl}-undefined ${wl}suppress' + ;; + *) # Darwin 1.3 on + if test -z ${MACOSX_DEPLOYMENT_TARGET} ; then + _LT_AC_TAGVAR(allow_undefined_flag, $1)='${wl}-flat_namespace ${wl}-undefined ${wl}suppress' + else + case ${MACOSX_DEPLOYMENT_TARGET} in + 10.[[012]]) + _LT_AC_TAGVAR(allow_undefined_flag, $1)='${wl}-flat_namespace ${wl}-undefined ${wl}suppress' + ;; + 10.*) + _LT_AC_TAGVAR(allow_undefined_flag, $1)='${wl}-undefined ${wl}dynamic_lookup' + ;; + esac + fi + ;; + esac + _LT_AC_TAGVAR(archive_cmds_need_lc, $1)=no + _LT_AC_TAGVAR(hardcode_direct, $1)=no + _LT_AC_TAGVAR(hardcode_automatic, $1)=yes + _LT_AC_TAGVAR(hardcode_shlibpath_var, $1)=unsupported + _LT_AC_TAGVAR(whole_archive_flag_spec, $1)='' + _LT_AC_TAGVAR(link_all_deplibs, $1)=yes + if test "$GCC" = yes ; then + output_verbose_link_cmd='echo' + _LT_AC_TAGVAR(archive_cmds, $1)='$CC -dynamiclib $allow_undefined_flag -o $lib $libobjs $deplibs $compiler_flags -install_name $rpath/$soname $verstring' + _LT_AC_TAGVAR(module_cmds, $1)='$CC $allow_undefined_flag -o $lib -bundle $libobjs $deplibs$compiler_flags' + # Don't fix this by using the ld -exported_symbols_list flag, it doesn't exist in older darwin lds + _LT_AC_TAGVAR(archive_expsym_cmds, $1)='sed -e "s,#.*,," -e "s,^[ ]*,," -e "s,^\(..*\),_&," < $export_symbols > $output_objdir/${libname}-symbols.expsym~$CC -dynamiclib $allow_undefined_flag -o $lib $libobjs $deplibs $compiler_flags -install_name $rpath/$soname $verstring~nmedit -s $output_objdir/${libname}-symbols.expsym ${lib}' + _LT_AC_TAGVAR(module_expsym_cmds, $1)='sed -e "s,#.*,," -e "s,^[ ]*,," -e "s,^\(..*\),_&," < $export_symbols > $output_objdir/${libname}-symbols.expsym~$CC $allow_undefined_flag -o $lib -bundle $libobjs $deplibs$compiler_flags~nmedit -s $output_objdir/${libname}-symbols.expsym ${lib}' + else + case $cc_basename in + xlc*) + output_verbose_link_cmd='echo' + _LT_AC_TAGVAR(archive_cmds, $1)='$CC -qmkshrobj $allow_undefined_flag -o $lib $libobjs $deplibs $compiler_flags ${wl}-install_name ${wl}`echo $rpath/$soname` $verstring' + _LT_AC_TAGVAR(module_cmds, $1)='$CC $allow_undefined_flag -o $lib -bundle $libobjs $deplibs$compiler_flags' + # Don't fix this by using the ld -exported_symbols_list flag, it doesn't exist in older darwin lds + _LT_AC_TAGVAR(archive_expsym_cmds, $1)='sed -e "s,#.*,," -e "s,^[ ]*,," -e "s,^\(..*\),_&," < $export_symbols > $output_objdir/${libname}-symbols.expsym~$CC -qmkshrobj $allow_undefined_flag -o $lib $libobjs $deplibs $compiler_flags ${wl}-install_name ${wl}$rpath/$soname $verstring~nmedit -s $output_objdir/${libname}-symbols.expsym ${lib}' + _LT_AC_TAGVAR(module_expsym_cmds, $1)='sed -e "s,#.*,," -e "s,^[ ]*,," -e "s,^\(..*\),_&," < $export_symbols > $output_objdir/${libname}-symbols.expsym~$CC $allow_undefined_flag -o $lib -bundle $libobjs $deplibs$compiler_flags~nmedit -s $output_objdir/${libname}-symbols.expsym ${lib}' + ;; + *) + _LT_AC_TAGVAR(ld_shlibs, $1)=no + ;; + esac + fi + ;; + + dgux*) + _LT_AC_TAGVAR(archive_cmds, $1)='$LD -G -h $soname -o $lib $libobjs $deplibs $linker_flags' + _LT_AC_TAGVAR(hardcode_libdir_flag_spec, $1)='-L$libdir' + _LT_AC_TAGVAR(hardcode_shlibpath_var, $1)=no + ;; + + freebsd1*) + _LT_AC_TAGVAR(ld_shlibs, $1)=no + ;; + + # FreeBSD 2.2.[012] allows us to include c++rt0.o to get C++ constructor + # support. Future versions do this automatically, but an explicit c++rt0.o + # does not break anything, and helps significantly (at the cost of a little + # extra space). + freebsd2.2*) + _LT_AC_TAGVAR(archive_cmds, $1)='$LD -Bshareable -o $lib $libobjs $deplibs $linker_flags /usr/lib/c++rt0.o' + _LT_AC_TAGVAR(hardcode_libdir_flag_spec, $1)='-R$libdir' + _LT_AC_TAGVAR(hardcode_direct, $1)=yes + _LT_AC_TAGVAR(hardcode_shlibpath_var, $1)=no + ;; + + # Unfortunately, older versions of FreeBSD 2 do not have this feature. + freebsd2*) + _LT_AC_TAGVAR(archive_cmds, $1)='$LD -Bshareable -o $lib $libobjs $deplibs $linker_flags' + _LT_AC_TAGVAR(hardcode_direct, $1)=yes + _LT_AC_TAGVAR(hardcode_minus_L, $1)=yes + _LT_AC_TAGVAR(hardcode_shlibpath_var, $1)=no + ;; + + # FreeBSD 3 and greater uses gcc -shared to do shared libraries. + freebsd* | kfreebsd*-gnu | dragonfly*) + _LT_AC_TAGVAR(archive_cmds, $1)='$CC -shared -o $lib $libobjs $deplibs $compiler_flags' + _LT_AC_TAGVAR(hardcode_libdir_flag_spec, $1)='-R$libdir' + _LT_AC_TAGVAR(hardcode_direct, $1)=yes + _LT_AC_TAGVAR(hardcode_shlibpath_var, $1)=no + ;; + + hpux9*) + if test "$GCC" = yes; then + _LT_AC_TAGVAR(archive_cmds, $1)='$rm $output_objdir/$soname~$CC -shared -fPIC ${wl}+b ${wl}$install_libdir -o $output_objdir/$soname $libobjs $deplibs $compiler_flags~test $output_objdir/$soname = $lib || mv $output_objdir/$soname $lib' + else + _LT_AC_TAGVAR(archive_cmds, $1)='$rm $output_objdir/$soname~$LD -b +b $install_libdir -o $output_objdir/$soname $libobjs $deplibs $linker_flags~test $output_objdir/$soname = $lib || mv $output_objdir/$soname $lib' + fi + _LT_AC_TAGVAR(hardcode_libdir_flag_spec, $1)='${wl}+b ${wl}$libdir' + _LT_AC_TAGVAR(hardcode_libdir_separator, $1)=: + _LT_AC_TAGVAR(hardcode_direct, $1)=yes + + # hardcode_minus_L: Not really in the search PATH, + # but as the default location of the library. + _LT_AC_TAGVAR(hardcode_minus_L, $1)=yes + _LT_AC_TAGVAR(export_dynamic_flag_spec, $1)='${wl}-E' + ;; + + hpux10*) + if test "$GCC" = yes -a "$with_gnu_ld" = no; then + _LT_AC_TAGVAR(archive_cmds, $1)='$CC -shared -fPIC ${wl}+h ${wl}$soname ${wl}+b ${wl}$install_libdir -o $lib $libobjs $deplibs $compiler_flags' + else + _LT_AC_TAGVAR(archive_cmds, $1)='$LD -b +h $soname +b $install_libdir -o $lib $libobjs $deplibs $linker_flags' + fi + if test "$with_gnu_ld" = no; then + _LT_AC_TAGVAR(hardcode_libdir_flag_spec, $1)='${wl}+b ${wl}$libdir' + _LT_AC_TAGVAR(hardcode_libdir_separator, $1)=: + + _LT_AC_TAGVAR(hardcode_direct, $1)=yes + _LT_AC_TAGVAR(export_dynamic_flag_spec, $1)='${wl}-E' + + # hardcode_minus_L: Not really in the search PATH, + # but as the default location of the library. + _LT_AC_TAGVAR(hardcode_minus_L, $1)=yes + fi + ;; + + hpux11*) + if test "$GCC" = yes -a "$with_gnu_ld" = no; then + case $host_cpu in + hppa*64*) + _LT_AC_TAGVAR(archive_cmds, $1)='$CC -shared ${wl}+h ${wl}$soname -o $lib $libobjs $deplibs $compiler_flags' + ;; + ia64*) + _LT_AC_TAGVAR(archive_cmds, $1)='$CC -shared ${wl}+h ${wl}$soname ${wl}+nodefaultrpath -o $lib $libobjs $deplibs $compiler_flags' + ;; + *) + _LT_AC_TAGVAR(archive_cmds, $1)='$CC -shared -fPIC ${wl}+h ${wl}$soname ${wl}+b ${wl}$install_libdir -o $lib $libobjs $deplibs $compiler_flags' + ;; + esac + else + case $host_cpu in + hppa*64*) + _LT_AC_TAGVAR(archive_cmds, $1)='$CC -b ${wl}+h ${wl}$soname -o $lib $libobjs $deplibs $compiler_flags' + ;; + ia64*) + _LT_AC_TAGVAR(archive_cmds, $1)='$CC -b ${wl}+h ${wl}$soname ${wl}+nodefaultrpath -o $lib $libobjs $deplibs $compiler_flags' + ;; + *) + _LT_AC_TAGVAR(archive_cmds, $1)='$CC -b ${wl}+h ${wl}$soname ${wl}+b ${wl}$install_libdir -o $lib $libobjs $deplibs $compiler_flags' + ;; + esac + fi + if test "$with_gnu_ld" = no; then + _LT_AC_TAGVAR(hardcode_libdir_flag_spec, $1)='${wl}+b ${wl}$libdir' + _LT_AC_TAGVAR(hardcode_libdir_separator, $1)=: + + case $host_cpu in + hppa*64*|ia64*) + _LT_AC_TAGVAR(hardcode_libdir_flag_spec_ld, $1)='+b $libdir' + _LT_AC_TAGVAR(hardcode_direct, $1)=no + _LT_AC_TAGVAR(hardcode_shlibpath_var, $1)=no + ;; + *) + _LT_AC_TAGVAR(hardcode_direct, $1)=yes + _LT_AC_TAGVAR(export_dynamic_flag_spec, $1)='${wl}-E' + + # hardcode_minus_L: Not really in the search PATH, + # but as the default location of the library. + _LT_AC_TAGVAR(hardcode_minus_L, $1)=yes + ;; + esac + fi + ;; + + irix5* | irix6* | nonstopux*) + if test "$GCC" = yes; then + _LT_AC_TAGVAR(archive_cmds, $1)='$CC -shared $libobjs $deplibs $compiler_flags ${wl}-soname ${wl}$soname `test -n "$verstring" && echo ${wl}-set_version ${wl}$verstring` ${wl}-update_registry ${wl}${output_objdir}/so_locations -o $lib' + else + _LT_AC_TAGVAR(archive_cmds, $1)='$LD -shared $libobjs $deplibs $linker_flags -soname $soname `test -n "$verstring" && echo -set_version $verstring` -update_registry ${output_objdir}/so_locations -o $lib' + _LT_AC_TAGVAR(hardcode_libdir_flag_spec_ld, $1)='-rpath $libdir' + fi + _LT_AC_TAGVAR(hardcode_libdir_flag_spec, $1)='${wl}-rpath ${wl}$libdir' + _LT_AC_TAGVAR(hardcode_libdir_separator, $1)=: + _LT_AC_TAGVAR(link_all_deplibs, $1)=yes + ;; + + netbsd*) + if echo __ELF__ | $CC -E - | grep __ELF__ >/dev/null; then + _LT_AC_TAGVAR(archive_cmds, $1)='$LD -Bshareable -o $lib $libobjs $deplibs $linker_flags' # a.out + else + _LT_AC_TAGVAR(archive_cmds, $1)='$LD -shared -o $lib $libobjs $deplibs $linker_flags' # ELF + fi + _LT_AC_TAGVAR(hardcode_libdir_flag_spec, $1)='-R$libdir' + _LT_AC_TAGVAR(hardcode_direct, $1)=yes + _LT_AC_TAGVAR(hardcode_shlibpath_var, $1)=no + ;; + + newsos6) + _LT_AC_TAGVAR(archive_cmds, $1)='$LD -G -h $soname -o $lib $libobjs $deplibs $linker_flags' + _LT_AC_TAGVAR(hardcode_direct, $1)=yes + _LT_AC_TAGVAR(hardcode_libdir_flag_spec, $1)='${wl}-rpath ${wl}$libdir' + _LT_AC_TAGVAR(hardcode_libdir_separator, $1)=: + _LT_AC_TAGVAR(hardcode_shlibpath_var, $1)=no + ;; + + openbsd*) + _LT_AC_TAGVAR(hardcode_direct, $1)=yes + _LT_AC_TAGVAR(hardcode_shlibpath_var, $1)=no + if test -z "`echo __ELF__ | $CC -E - | grep __ELF__`" || test "$host_os-$host_cpu" = "openbsd2.8-powerpc"; then + _LT_AC_TAGVAR(archive_cmds, $1)='$CC -shared $pic_flag -o $lib $libobjs $deplibs $compiler_flags' + _LT_AC_TAGVAR(archive_expsym_cmds, $1)='$CC -shared $pic_flag -o $lib $libobjs $deplibs $compiler_flags ${wl}-retain-symbols-file,$export_symbols' + _LT_AC_TAGVAR(hardcode_libdir_flag_spec, $1)='${wl}-rpath,$libdir' + _LT_AC_TAGVAR(export_dynamic_flag_spec, $1)='${wl}-E' + else + case $host_os in + openbsd[[01]].* | openbsd2.[[0-7]] | openbsd2.[[0-7]].*) + _LT_AC_TAGVAR(archive_cmds, $1)='$LD -Bshareable -o $lib $libobjs $deplibs $linker_flags' + _LT_AC_TAGVAR(hardcode_libdir_flag_spec, $1)='-R$libdir' + ;; + *) + _LT_AC_TAGVAR(archive_cmds, $1)='$CC -shared $pic_flag -o $lib $libobjs $deplibs $compiler_flags' + _LT_AC_TAGVAR(hardcode_libdir_flag_spec, $1)='${wl}-rpath,$libdir' + ;; + esac + fi + ;; + + os2*) + _LT_AC_TAGVAR(hardcode_libdir_flag_spec, $1)='-L$libdir' + _LT_AC_TAGVAR(hardcode_minus_L, $1)=yes + _LT_AC_TAGVAR(allow_undefined_flag, $1)=unsupported + _LT_AC_TAGVAR(archive_cmds, $1)='$echo "LIBRARY $libname INITINSTANCE" > $output_objdir/$libname.def~$echo "DESCRIPTION \"$libname\"" >> $output_objdir/$libname.def~$echo DATA >> $output_objdir/$libname.def~$echo " SINGLE NONSHARED" >> $output_objdir/$libname.def~$echo EXPORTS >> $output_objdir/$libname.def~emxexp $libobjs >> $output_objdir/$libname.def~$CC -Zdll -Zcrtdll -o $lib $libobjs $deplibs $compiler_flags $output_objdir/$libname.def' + _LT_AC_TAGVAR(old_archive_From_new_cmds, $1)='emximp -o $output_objdir/$libname.a $output_objdir/$libname.def' + ;; + + osf3*) + if test "$GCC" = yes; then + _LT_AC_TAGVAR(allow_undefined_flag, $1)=' ${wl}-expect_unresolved ${wl}\*' + _LT_AC_TAGVAR(archive_cmds, $1)='$CC -shared${allow_undefined_flag} $libobjs $deplibs $compiler_flags ${wl}-soname ${wl}$soname `test -n "$verstring" && echo ${wl}-set_version ${wl}$verstring` ${wl}-update_registry ${wl}${output_objdir}/so_locations -o $lib' + else + _LT_AC_TAGVAR(allow_undefined_flag, $1)=' -expect_unresolved \*' + _LT_AC_TAGVAR(archive_cmds, $1)='$LD -shared${allow_undefined_flag} $libobjs $deplibs $linker_flags -soname $soname `test -n "$verstring" && echo -set_version $verstring` -update_registry ${output_objdir}/so_locations -o $lib' + fi + _LT_AC_TAGVAR(hardcode_libdir_flag_spec, $1)='${wl}-rpath ${wl}$libdir' + _LT_AC_TAGVAR(hardcode_libdir_separator, $1)=: + ;; + + osf4* | osf5*) # as osf3* with the addition of -msym flag + if test "$GCC" = yes; then + _LT_AC_TAGVAR(allow_undefined_flag, $1)=' ${wl}-expect_unresolved ${wl}\*' + _LT_AC_TAGVAR(archive_cmds, $1)='$CC -shared${allow_undefined_flag} $libobjs $deplibs $compiler_flags ${wl}-msym ${wl}-soname ${wl}$soname `test -n "$verstring" && echo ${wl}-set_version ${wl}$verstring` ${wl}-update_registry ${wl}${output_objdir}/so_locations -o $lib' + _LT_AC_TAGVAR(hardcode_libdir_flag_spec, $1)='${wl}-rpath ${wl}$libdir' + else + _LT_AC_TAGVAR(allow_undefined_flag, $1)=' -expect_unresolved \*' + _LT_AC_TAGVAR(archive_cmds, $1)='$LD -shared${allow_undefined_flag} $libobjs $deplibs $linker_flags -msym -soname $soname `test -n "$verstring" && echo -set_version $verstring` -update_registry ${output_objdir}/so_locations -o $lib' + _LT_AC_TAGVAR(archive_expsym_cmds, $1)='for i in `cat $export_symbols`; do printf "%s %s\\n" -exported_symbol "\$i" >> $lib.exp; done; echo "-hidden">> $lib.exp~ + $LD -shared${allow_undefined_flag} -input $lib.exp $linker_flags $libobjs $deplibs -soname $soname `test -n "$verstring" && echo -set_version $verstring` -update_registry ${output_objdir}/so_locations -o $lib~$rm $lib.exp' + + # Both c and cxx compiler support -rpath directly + _LT_AC_TAGVAR(hardcode_libdir_flag_spec, $1)='-rpath $libdir' + fi + _LT_AC_TAGVAR(hardcode_libdir_separator, $1)=: + ;; + + solaris*) + _LT_AC_TAGVAR(no_undefined_flag, $1)=' -z text' + if test "$GCC" = yes; then + wlarc='${wl}' + _LT_AC_TAGVAR(archive_cmds, $1)='$CC -shared ${wl}-h ${wl}$soname -o $lib $libobjs $deplibs $compiler_flags' + _LT_AC_TAGVAR(archive_expsym_cmds, $1)='$echo "{ global:" > $lib.exp~cat $export_symbols | $SED -e "s/\(.*\)/\1;/" >> $lib.exp~$echo "local: *; };" >> $lib.exp~ + $CC -shared ${wl}-M ${wl}$lib.exp ${wl}-h ${wl}$soname -o $lib $libobjs $deplibs $compiler_flags~$rm $lib.exp' + else + wlarc='' + _LT_AC_TAGVAR(archive_cmds, $1)='$LD -G${allow_undefined_flag} -h $soname -o $lib $libobjs $deplibs $linker_flags' + _LT_AC_TAGVAR(archive_expsym_cmds, $1)='$echo "{ global:" > $lib.exp~cat $export_symbols | $SED -e "s/\(.*\)/\1;/" >> $lib.exp~$echo "local: *; };" >> $lib.exp~ + $LD -G${allow_undefined_flag} -M $lib.exp -h $soname -o $lib $libobjs $deplibs $linker_flags~$rm $lib.exp' + fi + _LT_AC_TAGVAR(hardcode_libdir_flag_spec, $1)='-R$libdir' + _LT_AC_TAGVAR(hardcode_shlibpath_var, $1)=no + case $host_os in + solaris2.[[0-5]] | solaris2.[[0-5]].*) ;; + *) + # The compiler driver will combine linker options so we + # cannot just pass the convience library names through + # without $wl, iff we do not link with $LD. + # Luckily, gcc supports the same syntax we need for Sun Studio. + # Supported since Solaris 2.6 (maybe 2.5.1?) + case $wlarc in + '') + _LT_AC_TAGVAR(whole_archive_flag_spec, $1)='-z allextract$convenience -z defaultextract' ;; + *) + _LT_AC_TAGVAR(whole_archive_flag_spec, $1)='${wl}-z ${wl}allextract`for conv in $convenience\"\"; do test -n \"$conv\" && new_convenience=\"$new_convenience,$conv\"; done; $echo \"$new_convenience\"` ${wl}-z ${wl}defaultextract' ;; + esac ;; + esac + _LT_AC_TAGVAR(link_all_deplibs, $1)=yes + ;; + + sunos4*) + if test "x$host_vendor" = xsequent; then + # Use $CC to link under sequent, because it throws in some extra .o + # files that make .init and .fini sections work. + _LT_AC_TAGVAR(archive_cmds, $1)='$CC -G ${wl}-h $soname -o $lib $libobjs $deplibs $compiler_flags' + else + _LT_AC_TAGVAR(archive_cmds, $1)='$LD -assert pure-text -Bstatic -o $lib $libobjs $deplibs $linker_flags' + fi + _LT_AC_TAGVAR(hardcode_libdir_flag_spec, $1)='-L$libdir' + _LT_AC_TAGVAR(hardcode_direct, $1)=yes + _LT_AC_TAGVAR(hardcode_minus_L, $1)=yes + _LT_AC_TAGVAR(hardcode_shlibpath_var, $1)=no + ;; + + sysv4) + case $host_vendor in + sni) + _LT_AC_TAGVAR(archive_cmds, $1)='$LD -G -h $soname -o $lib $libobjs $deplibs $linker_flags' + _LT_AC_TAGVAR(hardcode_direct, $1)=yes # is this really true??? + ;; + siemens) + ## LD is ld it makes a PLAMLIB + ## CC just makes a GrossModule. + _LT_AC_TAGVAR(archive_cmds, $1)='$LD -G -o $lib $libobjs $deplibs $linker_flags' + _LT_AC_TAGVAR(reload_cmds, $1)='$CC -r -o $output$reload_objs' + _LT_AC_TAGVAR(hardcode_direct, $1)=no + ;; + motorola) + _LT_AC_TAGVAR(archive_cmds, $1)='$LD -G -h $soname -o $lib $libobjs $deplibs $linker_flags' + _LT_AC_TAGVAR(hardcode_direct, $1)=no #Motorola manual says yes, but my tests say they lie + ;; + esac + runpath_var='LD_RUN_PATH' + _LT_AC_TAGVAR(hardcode_shlibpath_var, $1)=no + ;; + + sysv4.3*) + _LT_AC_TAGVAR(archive_cmds, $1)='$LD -G -h $soname -o $lib $libobjs $deplibs $linker_flags' + _LT_AC_TAGVAR(hardcode_shlibpath_var, $1)=no + _LT_AC_TAGVAR(export_dynamic_flag_spec, $1)='-Bexport' + ;; + + sysv4*MP*) + if test -d /usr/nec; then + _LT_AC_TAGVAR(archive_cmds, $1)='$LD -G -h $soname -o $lib $libobjs $deplibs $linker_flags' + _LT_AC_TAGVAR(hardcode_shlibpath_var, $1)=no + runpath_var=LD_RUN_PATH + hardcode_runpath_var=yes + _LT_AC_TAGVAR(ld_shlibs, $1)=yes + fi + ;; + + sysv4*uw2* | sysv5OpenUNIX* | sysv5UnixWare7.[[01]].[[10]]* | unixware7*) + _LT_AC_TAGVAR(no_undefined_flag, $1)='${wl}-z,text' + _LT_AC_TAGVAR(archive_cmds_need_lc, $1)=no + _LT_AC_TAGVAR(hardcode_shlibpath_var, $1)=no + runpath_var='LD_RUN_PATH' + + if test "$GCC" = yes; then + _LT_AC_TAGVAR(archive_cmds, $1)='$CC -shared ${wl}-h,$soname -o $lib $libobjs $deplibs $compiler_flags' + _LT_AC_TAGVAR(archive_expsym_cmds, $1)='$CC -shared ${wl}-Bexport:$export_symbols ${wl}-h,$soname -o $lib $libobjs $deplibs $compiler_flags' + else + _LT_AC_TAGVAR(archive_cmds, $1)='$CC -G ${wl}-h,$soname -o $lib $libobjs $deplibs $compiler_flags' + _LT_AC_TAGVAR(archive_expsym_cmds, $1)='$CC -G ${wl}-Bexport:$export_symbols ${wl}-h,$soname -o $lib $libobjs $deplibs $compiler_flags' + fi + ;; + + sysv5* | sco3.2v5* | sco5v6*) + # Note: We can NOT use -z defs as we might desire, because we do not + # link with -lc, and that would cause any symbols used from libc to + # always be unresolved, which means just about no library would + # ever link correctly. If we're not using GNU ld we use -z text + # though, which does catch some bad symbols but isn't as heavy-handed + # as -z defs. + _LT_AC_TAGVAR(no_undefined_flag, $1)='${wl}-z,text' + _LT_AC_TAGVAR(allow_undefined_flag, $1)='${wl}-z,nodefs' + _LT_AC_TAGVAR(archive_cmds_need_lc, $1)=no + _LT_AC_TAGVAR(hardcode_shlibpath_var, $1)=no + _LT_AC_TAGVAR(hardcode_libdir_flag_spec, $1)='`test -z "$SCOABSPATH" && echo ${wl}-R,$libdir`' + _LT_AC_TAGVAR(hardcode_libdir_separator, $1)=':' + _LT_AC_TAGVAR(link_all_deplibs, $1)=yes + _LT_AC_TAGVAR(export_dynamic_flag_spec, $1)='${wl}-Bexport' + runpath_var='LD_RUN_PATH' + + if test "$GCC" = yes; then + _LT_AC_TAGVAR(archive_cmds, $1)='$CC -shared ${wl}-h,\${SCOABSPATH:+${install_libdir}/}$soname -o $lib $libobjs $deplibs $compiler_flags' + _LT_AC_TAGVAR(archive_expsym_cmds, $1)='$CC -shared ${wl}-Bexport:$export_symbols ${wl}-h,\${SCOABSPATH:+${install_libdir}/}$soname -o $lib $libobjs $deplibs $compiler_flags' + else + _LT_AC_TAGVAR(archive_cmds, $1)='$CC -G ${wl}-h,\${SCOABSPATH:+${install_libdir}/}$soname -o $lib $libobjs $deplibs $compiler_flags' + _LT_AC_TAGVAR(archive_expsym_cmds, $1)='$CC -G ${wl}-Bexport:$export_symbols ${wl}-h,\${SCOABSPATH:+${install_libdir}/}$soname -o $lib $libobjs $deplibs $compiler_flags' + fi + ;; + + uts4*) + _LT_AC_TAGVAR(archive_cmds, $1)='$LD -G -h $soname -o $lib $libobjs $deplibs $linker_flags' + _LT_AC_TAGVAR(hardcode_libdir_flag_spec, $1)='-L$libdir' + _LT_AC_TAGVAR(hardcode_shlibpath_var, $1)=no + ;; + + *) + _LT_AC_TAGVAR(ld_shlibs, $1)=no + ;; + esac + fi +]) +AC_MSG_RESULT([$_LT_AC_TAGVAR(ld_shlibs, $1)]) +test "$_LT_AC_TAGVAR(ld_shlibs, $1)" = no && can_build_shared=no + +# +# Do we need to explicitly link libc? +# +case "x$_LT_AC_TAGVAR(archive_cmds_need_lc, $1)" in +x|xyes) + # Assume -lc should be added + _LT_AC_TAGVAR(archive_cmds_need_lc, $1)=yes + + if test "$enable_shared" = yes && test "$GCC" = yes; then + case $_LT_AC_TAGVAR(archive_cmds, $1) in + *'~'*) + # FIXME: we may have to deal with multi-command sequences. + ;; + '$CC '*) + # Test whether the compiler implicitly links with -lc since on some + # systems, -lgcc has to come before -lc. If gcc already passes -lc + # to ld, don't add -lc before -lgcc. + AC_MSG_CHECKING([whether -lc should be explicitly linked in]) + $rm conftest* + printf "$lt_simple_compile_test_code" > conftest.$ac_ext + + if AC_TRY_EVAL(ac_compile) 2>conftest.err; then + soname=conftest + lib=conftest + libobjs=conftest.$ac_objext + deplibs= + wl=$_LT_AC_TAGVAR(lt_prog_compiler_wl, $1) + pic_flag=$_LT_AC_TAGVAR(lt_prog_compiler_pic, $1) + compiler_flags=-v + linker_flags=-v + verstring= + output_objdir=. + libname=conftest + lt_save_allow_undefined_flag=$_LT_AC_TAGVAR(allow_undefined_flag, $1) + _LT_AC_TAGVAR(allow_undefined_flag, $1)= + if AC_TRY_EVAL(_LT_AC_TAGVAR(archive_cmds, $1) 2\>\&1 \| grep \" -lc \" \>/dev/null 2\>\&1) + then + _LT_AC_TAGVAR(archive_cmds_need_lc, $1)=no + else + _LT_AC_TAGVAR(archive_cmds_need_lc, $1)=yes + fi + _LT_AC_TAGVAR(allow_undefined_flag, $1)=$lt_save_allow_undefined_flag + else + cat conftest.err 1>&5 + fi + $rm conftest* + AC_MSG_RESULT([$_LT_AC_TAGVAR(archive_cmds_need_lc, $1)]) + ;; + esac + fi + ;; +esac +])# AC_LIBTOOL_PROG_LD_SHLIBS + + +# _LT_AC_FILE_LTDLL_C +# ------------------- +# Be careful that the start marker always follows a newline. +AC_DEFUN([_LT_AC_FILE_LTDLL_C], [ +# /* ltdll.c starts here */ +# #define WIN32_LEAN_AND_MEAN +# #include <windows.h> +# #undef WIN32_LEAN_AND_MEAN +# #include <stdio.h> +# +# #ifndef __CYGWIN__ +# # ifdef __CYGWIN32__ +# # define __CYGWIN__ __CYGWIN32__ +# # endif +# #endif +# +# #ifdef __cplusplus +# extern "C" { +# #endif +# BOOL APIENTRY DllMain (HINSTANCE hInst, DWORD reason, LPVOID reserved); +# #ifdef __cplusplus +# } +# #endif +# +# #ifdef __CYGWIN__ +# #include <cygwin/cygwin_dll.h> +# DECLARE_CYGWIN_DLL( DllMain ); +# #endif +# HINSTANCE __hDllInstance_base; +# +# BOOL APIENTRY +# DllMain (HINSTANCE hInst, DWORD reason, LPVOID reserved) +# { +# __hDllInstance_base = hInst; +# return TRUE; +# } +# /* ltdll.c ends here */ +])# _LT_AC_FILE_LTDLL_C + + +# _LT_AC_TAGVAR(VARNAME, [TAGNAME]) +# --------------------------------- +AC_DEFUN([_LT_AC_TAGVAR], [ifelse([$2], [], [$1], [$1_$2])]) + + +# old names +AC_DEFUN([AM_PROG_LIBTOOL], [AC_PROG_LIBTOOL]) +AC_DEFUN([AM_ENABLE_SHARED], [AC_ENABLE_SHARED($@)]) +AC_DEFUN([AM_ENABLE_STATIC], [AC_ENABLE_STATIC($@)]) +AC_DEFUN([AM_DISABLE_SHARED], [AC_DISABLE_SHARED($@)]) +AC_DEFUN([AM_DISABLE_STATIC], [AC_DISABLE_STATIC($@)]) +AC_DEFUN([AM_PROG_LD], [AC_PROG_LD]) +AC_DEFUN([AM_PROG_NM], [AC_PROG_NM]) + +# This is just to silence aclocal about the macro not being used +ifelse([AC_DISABLE_FAST_INSTALL]) + +AC_DEFUN([LT_AC_PROG_GCJ], +[AC_CHECK_TOOL(GCJ, gcj, no) + test "x${GCJFLAGS+set}" = xset || GCJFLAGS="-g -O2" + AC_SUBST(GCJFLAGS) +]) + +AC_DEFUN([LT_AC_PROG_RC], +[AC_CHECK_TOOL(RC, windres, no) +]) + +# NOTE: This macro has been submitted for inclusion into # +# GNU Autoconf as AC_PROG_SED. When it is available in # +# a released version of Autoconf we should remove this # +# macro and use it instead. # +# LT_AC_PROG_SED +# -------------- +# Check for a fully-functional sed program, that truncates +# as few characters as possible. Prefer GNU sed if found. +AC_DEFUN([LT_AC_PROG_SED], +[AC_MSG_CHECKING([for a sed that does not truncate output]) +AC_CACHE_VAL(lt_cv_path_SED, +[# Loop through the user's path and test for sed and gsed. +# Then use that list of sed's as ones to test for truncation. +as_save_IFS=$IFS; IFS=$PATH_SEPARATOR +for as_dir in $PATH +do + IFS=$as_save_IFS + test -z "$as_dir" && as_dir=. + for lt_ac_prog in sed gsed; do + for ac_exec_ext in '' $ac_executable_extensions; do + if $as_executable_p "$as_dir/$lt_ac_prog$ac_exec_ext"; then + lt_ac_sed_list="$lt_ac_sed_list $as_dir/$lt_ac_prog$ac_exec_ext" + fi + done + done +done +IFS=$as_save_IFS +lt_ac_max=0 +lt_ac_count=0 +# Add /usr/xpg4/bin/sed as it is typically found on Solaris +# along with /bin/sed that truncates output. +for lt_ac_sed in $lt_ac_sed_list /usr/xpg4/bin/sed; do + test ! -f $lt_ac_sed && continue + cat /dev/null > conftest.in + lt_ac_count=0 + echo $ECHO_N "0123456789$ECHO_C" >conftest.in + # Check for GNU sed and select it if it is found. + if "$lt_ac_sed" --version 2>&1 < /dev/null | grep 'GNU' > /dev/null; then + lt_cv_path_SED=$lt_ac_sed + break + fi + while true; do + cat conftest.in conftest.in >conftest.tmp + mv conftest.tmp conftest.in + cp conftest.in conftest.nl + echo >>conftest.nl + $lt_ac_sed -e 's/a$//' < conftest.nl >conftest.out || break + cmp -s conftest.out conftest.nl || break + # 10000 chars as input seems more than enough + test $lt_ac_count -gt 10 && break + lt_ac_count=`expr $lt_ac_count + 1` + if test $lt_ac_count -gt $lt_ac_max; then + lt_ac_max=$lt_ac_count + lt_cv_path_SED=$lt_ac_sed + fi + done +done +]) +SED=$lt_cv_path_SED +AC_SUBST([SED]) +AC_MSG_RESULT([$SED]) +]) + +# Copyright (C) 2002, 2003, 2005 Free Software Foundation, Inc. +# +# This file is free software; the Free Software Foundation +# gives unlimited permission to copy and/or distribute it, +# with or without modifications, as long as this notice is preserved. + +# AM_AUTOMAKE_VERSION(VERSION) +# ---------------------------- +# Automake X.Y traces this macro to ensure aclocal.m4 has been +# generated from the m4 files accompanying Automake X.Y. +AC_DEFUN([AM_AUTOMAKE_VERSION], [am__api_version="1.9"]) + +# AM_SET_CURRENT_AUTOMAKE_VERSION +# ------------------------------- +# Call AM_AUTOMAKE_VERSION so it can be traced. +# This function is AC_REQUIREd by AC_INIT_AUTOMAKE. +AC_DEFUN([AM_SET_CURRENT_AUTOMAKE_VERSION], + [AM_AUTOMAKE_VERSION([1.9.6])]) + +# AM_AUX_DIR_EXPAND -*- Autoconf -*- + +# Copyright (C) 2001, 2003, 2005 Free Software Foundation, Inc. +# +# This file is free software; the Free Software Foundation +# gives unlimited permission to copy and/or distribute it, +# with or without modifications, as long as this notice is preserved. + +# For projects using AC_CONFIG_AUX_DIR([foo]), Autoconf sets +# $ac_aux_dir to `$srcdir/foo'. In other projects, it is set to +# `$srcdir', `$srcdir/..', or `$srcdir/../..'. +# +# Of course, Automake must honor this variable whenever it calls a +# tool from the auxiliary directory. The problem is that $srcdir (and +# therefore $ac_aux_dir as well) can be either absolute or relative, +# depending on how configure is run. This is pretty annoying, since +# it makes $ac_aux_dir quite unusable in subdirectories: in the top +# source directory, any form will work fine, but in subdirectories a +# relative path needs to be adjusted first. +# +# $ac_aux_dir/missing +# fails when called from a subdirectory if $ac_aux_dir is relative +# $top_srcdir/$ac_aux_dir/missing +# fails if $ac_aux_dir is absolute, +# fails when called from a subdirectory in a VPATH build with +# a relative $ac_aux_dir +# +# The reason of the latter failure is that $top_srcdir and $ac_aux_dir +# are both prefixed by $srcdir. In an in-source build this is usually +# harmless because $srcdir is `.', but things will broke when you +# start a VPATH build or use an absolute $srcdir. +# +# So we could use something similar to $top_srcdir/$ac_aux_dir/missing, +# iff we strip the leading $srcdir from $ac_aux_dir. That would be: +# am_aux_dir='\$(top_srcdir)/'`expr "$ac_aux_dir" : "$srcdir//*\(.*\)"` +# and then we would define $MISSING as +# MISSING="\${SHELL} $am_aux_dir/missing" +# This will work as long as MISSING is not called from configure, because +# unfortunately $(top_srcdir) has no meaning in configure. +# However there are other variables, like CC, which are often used in +# configure, and could therefore not use this "fixed" $ac_aux_dir. +# +# Another solution, used here, is to always expand $ac_aux_dir to an +# absolute PATH. The drawback is that using absolute paths prevent a +# configured tree to be moved without reconfiguration. + +AC_DEFUN([AM_AUX_DIR_EXPAND], +[dnl Rely on autoconf to set up CDPATH properly. +AC_PREREQ([2.50])dnl +# expand $ac_aux_dir to an absolute path +am_aux_dir=`cd $ac_aux_dir && pwd` +]) + +# AM_CONDITIONAL -*- Autoconf -*- + +# Copyright (C) 1997, 2000, 2001, 2003, 2004, 2005 +# Free Software Foundation, Inc. +# +# This file is free software; the Free Software Foundation +# gives unlimited permission to copy and/or distribute it, +# with or without modifications, as long as this notice is preserved. + +# serial 7 + +# AM_CONDITIONAL(NAME, SHELL-CONDITION) +# ------------------------------------- +# Define a conditional. +AC_DEFUN([AM_CONDITIONAL], +[AC_PREREQ(2.52)dnl + ifelse([$1], [TRUE], [AC_FATAL([$0: invalid condition: $1])], + [$1], [FALSE], [AC_FATAL([$0: invalid condition: $1])])dnl +AC_SUBST([$1_TRUE]) +AC_SUBST([$1_FALSE]) +if $2; then + $1_TRUE= + $1_FALSE='#' +else + $1_TRUE='#' + $1_FALSE= +fi +AC_CONFIG_COMMANDS_PRE( +[if test -z "${$1_TRUE}" && test -z "${$1_FALSE}"; then + AC_MSG_ERROR([[conditional "$1" was never defined. +Usually this means the macro was only invoked conditionally.]]) +fi])]) + + +# Copyright (C) 1999, 2000, 2001, 2002, 2003, 2004, 2005 +# Free Software Foundation, Inc. +# +# This file is free software; the Free Software Foundation +# gives unlimited permission to copy and/or distribute it, +# with or without modifications, as long as this notice is preserved. + +# serial 8 + +# There are a few dirty hacks below to avoid letting `AC_PROG_CC' be +# written in clear, in which case automake, when reading aclocal.m4, +# will think it sees a *use*, and therefore will trigger all it's +# C support machinery. Also note that it means that autoscan, seeing +# CC etc. in the Makefile, will ask for an AC_PROG_CC use... + + +# _AM_DEPENDENCIES(NAME) +# ---------------------- +# See how the compiler implements dependency checking. +# NAME is "CC", "CXX", "GCJ", or "OBJC". +# We try a few techniques and use that to set a single cache variable. +# +# We don't AC_REQUIRE the corresponding AC_PROG_CC since the latter was +# modified to invoke _AM_DEPENDENCIES(CC); we would have a circular +# dependency, and given that the user is not expected to run this macro, +# just rely on AC_PROG_CC. +AC_DEFUN([_AM_DEPENDENCIES], +[AC_REQUIRE([AM_SET_DEPDIR])dnl +AC_REQUIRE([AM_OUTPUT_DEPENDENCY_COMMANDS])dnl +AC_REQUIRE([AM_MAKE_INCLUDE])dnl +AC_REQUIRE([AM_DEP_TRACK])dnl + +ifelse([$1], CC, [depcc="$CC" am_compiler_list=], + [$1], CXX, [depcc="$CXX" am_compiler_list=], + [$1], OBJC, [depcc="$OBJC" am_compiler_list='gcc3 gcc'], + [$1], GCJ, [depcc="$GCJ" am_compiler_list='gcc3 gcc'], + [depcc="$$1" am_compiler_list=]) + +AC_CACHE_CHECK([dependency style of $depcc], + [am_cv_$1_dependencies_compiler_type], +[if test -z "$AMDEP_TRUE" && test -f "$am_depcomp"; then + # We make a subdir and do the tests there. Otherwise we can end up + # making bogus files that we don't know about and never remove. For + # instance it was reported that on HP-UX the gcc test will end up + # making a dummy file named `D' -- because `-MD' means `put the output + # in D'. + mkdir conftest.dir + # Copy depcomp to subdir because otherwise we won't find it if we're + # using a relative directory. + cp "$am_depcomp" conftest.dir + cd conftest.dir + # We will build objects and dependencies in a subdirectory because + # it helps to detect inapplicable dependency modes. For instance + # both Tru64's cc and ICC support -MD to output dependencies as a + # side effect of compilation, but ICC will put the dependencies in + # the current directory while Tru64 will put them in the object + # directory. + mkdir sub + + am_cv_$1_dependencies_compiler_type=none + if test "$am_compiler_list" = ""; then + am_compiler_list=`sed -n ['s/^#*\([a-zA-Z0-9]*\))$/\1/p'] < ./depcomp` + fi + for depmode in $am_compiler_list; do + # Setup a source with many dependencies, because some compilers + # like to wrap large dependency lists on column 80 (with \), and + # we should not choose a depcomp mode which is confused by this. + # + # We need to recreate these files for each test, as the compiler may + # overwrite some of them when testing with obscure command lines. + # This happens at least with the AIX C compiler. + : > sub/conftest.c + for i in 1 2 3 4 5 6; do + echo '#include "conftst'$i'.h"' >> sub/conftest.c + # Using `: > sub/conftst$i.h' creates only sub/conftst1.h with + # Solaris 8's {/usr,}/bin/sh. + touch sub/conftst$i.h + done + echo "${am__include} ${am__quote}sub/conftest.Po${am__quote}" > confmf + + case $depmode in + nosideeffect) + # after this tag, mechanisms are not by side-effect, so they'll + # only be used when explicitly requested + if test "x$enable_dependency_tracking" = xyes; then + continue + else + break + fi + ;; + none) break ;; + esac + # We check with `-c' and `-o' for the sake of the "dashmstdout" + # mode. It turns out that the SunPro C++ compiler does not properly + # handle `-M -o', and we need to detect this. + if depmode=$depmode \ + source=sub/conftest.c object=sub/conftest.${OBJEXT-o} \ + depfile=sub/conftest.Po tmpdepfile=sub/conftest.TPo \ + $SHELL ./depcomp $depcc -c -o sub/conftest.${OBJEXT-o} sub/conftest.c \ + >/dev/null 2>conftest.err && + grep sub/conftst6.h sub/conftest.Po > /dev/null 2>&1 && + grep sub/conftest.${OBJEXT-o} sub/conftest.Po > /dev/null 2>&1 && + ${MAKE-make} -s -f confmf > /dev/null 2>&1; then + # icc doesn't choke on unknown options, it will just issue warnings + # or remarks (even with -Werror). So we grep stderr for any message + # that says an option was ignored or not supported. + # When given -MP, icc 7.0 and 7.1 complain thusly: + # icc: Command line warning: ignoring option '-M'; no argument required + # The diagnosis changed in icc 8.0: + # icc: Command line remark: option '-MP' not supported + if (grep 'ignoring option' conftest.err || + grep 'not supported' conftest.err) >/dev/null 2>&1; then :; else + am_cv_$1_dependencies_compiler_type=$depmode + break + fi + fi + done + + cd .. + rm -rf conftest.dir +else + am_cv_$1_dependencies_compiler_type=none +fi +]) +AC_SUBST([$1DEPMODE], [depmode=$am_cv_$1_dependencies_compiler_type]) +AM_CONDITIONAL([am__fastdep$1], [ + test "x$enable_dependency_tracking" != xno \ + && test "$am_cv_$1_dependencies_compiler_type" = gcc3]) +]) + + +# AM_SET_DEPDIR +# ------------- +# Choose a directory name for dependency files. +# This macro is AC_REQUIREd in _AM_DEPENDENCIES +AC_DEFUN([AM_SET_DEPDIR], +[AC_REQUIRE([AM_SET_LEADING_DOT])dnl +AC_SUBST([DEPDIR], ["${am__leading_dot}deps"])dnl +]) + + +# AM_DEP_TRACK +# ------------ +AC_DEFUN([AM_DEP_TRACK], +[AC_ARG_ENABLE(dependency-tracking, +[ --disable-dependency-tracking speeds up one-time build + --enable-dependency-tracking do not reject slow dependency extractors]) +if test "x$enable_dependency_tracking" != xno; then + am_depcomp="$ac_aux_dir/depcomp" + AMDEPBACKSLASH='\' +fi +AM_CONDITIONAL([AMDEP], [test "x$enable_dependency_tracking" != xno]) +AC_SUBST([AMDEPBACKSLASH]) +]) + +# Generate code to set up dependency tracking. -*- Autoconf -*- + +# Copyright (C) 1999, 2000, 2001, 2002, 2003, 2004, 2005 +# Free Software Foundation, Inc. +# +# This file is free software; the Free Software Foundation +# gives unlimited permission to copy and/or distribute it, +# with or without modifications, as long as this notice is preserved. + +#serial 3 + +# _AM_OUTPUT_DEPENDENCY_COMMANDS +# ------------------------------ +AC_DEFUN([_AM_OUTPUT_DEPENDENCY_COMMANDS], +[for mf in $CONFIG_FILES; do + # Strip MF so we end up with the name of the file. + mf=`echo "$mf" | sed -e 's/:.*$//'` + # Check whether this is an Automake generated Makefile or not. + # We used to match only the files named `Makefile.in', but + # some people rename them; so instead we look at the file content. + # Grep'ing the first line is not enough: some people post-process + # each Makefile.in and add a new line on top of each file to say so. + # So let's grep whole file. + if grep '^#.*generated by automake' $mf > /dev/null 2>&1; then + dirpart=`AS_DIRNAME("$mf")` + else + continue + fi + # Extract the definition of DEPDIR, am__include, and am__quote + # from the Makefile without running `make'. + DEPDIR=`sed -n 's/^DEPDIR = //p' < "$mf"` + test -z "$DEPDIR" && continue + am__include=`sed -n 's/^am__include = //p' < "$mf"` + test -z "am__include" && continue + am__quote=`sed -n 's/^am__quote = //p' < "$mf"` + # When using ansi2knr, U may be empty or an underscore; expand it + U=`sed -n 's/^U = //p' < "$mf"` + # Find all dependency output files, they are included files with + # $(DEPDIR) in their names. We invoke sed twice because it is the + # simplest approach to changing $(DEPDIR) to its actual value in the + # expansion. + for file in `sed -n " + s/^$am__include $am__quote\(.*(DEPDIR).*\)$am__quote"'$/\1/p' <"$mf" | \ + sed -e 's/\$(DEPDIR)/'"$DEPDIR"'/g' -e 's/\$U/'"$U"'/g'`; do + # Make sure the directory exists. + test -f "$dirpart/$file" && continue + fdir=`AS_DIRNAME(["$file"])` + AS_MKDIR_P([$dirpart/$fdir]) + # echo "creating $dirpart/$file" + echo '# dummy' > "$dirpart/$file" + done +done +])# _AM_OUTPUT_DEPENDENCY_COMMANDS + + +# AM_OUTPUT_DEPENDENCY_COMMANDS +# ----------------------------- +# This macro should only be invoked once -- use via AC_REQUIRE. +# +# This code is only required when automatic dependency tracking +# is enabled. FIXME. This creates each `.P' file that we will +# need in order to bootstrap the dependency handling code. +AC_DEFUN([AM_OUTPUT_DEPENDENCY_COMMANDS], +[AC_CONFIG_COMMANDS([depfiles], + [test x"$AMDEP_TRUE" != x"" || _AM_OUTPUT_DEPENDENCY_COMMANDS], + [AMDEP_TRUE="$AMDEP_TRUE" ac_aux_dir="$ac_aux_dir"]) +]) + +# Do all the work for Automake. -*- Autoconf -*- + +# Copyright (C) 1996, 1997, 1998, 1999, 2000, 2001, 2002, 2003, 2004, 2005 +# Free Software Foundation, Inc. +# +# This file is free software; the Free Software Foundation +# gives unlimited permission to copy and/or distribute it, +# with or without modifications, as long as this notice is preserved. + +# serial 12 + +# This macro actually does too much. Some checks are only needed if +# your package does certain things. But this isn't really a big deal. + +# AM_INIT_AUTOMAKE(PACKAGE, VERSION, [NO-DEFINE]) +# AM_INIT_AUTOMAKE([OPTIONS]) +# ----------------------------------------------- +# The call with PACKAGE and VERSION arguments is the old style +# call (pre autoconf-2.50), which is being phased out. PACKAGE +# and VERSION should now be passed to AC_INIT and removed from +# the call to AM_INIT_AUTOMAKE. +# We support both call styles for the transition. After +# the next Automake release, Autoconf can make the AC_INIT +# arguments mandatory, and then we can depend on a new Autoconf +# release and drop the old call support. +AC_DEFUN([AM_INIT_AUTOMAKE], +[AC_PREREQ([2.58])dnl +dnl Autoconf wants to disallow AM_ names. We explicitly allow +dnl the ones we care about. +m4_pattern_allow([^AM_[A-Z]+FLAGS$])dnl +AC_REQUIRE([AM_SET_CURRENT_AUTOMAKE_VERSION])dnl +AC_REQUIRE([AC_PROG_INSTALL])dnl +# test to see if srcdir already configured +if test "`cd $srcdir && pwd`" != "`pwd`" && + test -f $srcdir/config.status; then + AC_MSG_ERROR([source directory already configured; run "make distclean" there first]) +fi + +# test whether we have cygpath +if test -z "$CYGPATH_W"; then + if (cygpath --version) >/dev/null 2>/dev/null; then + CYGPATH_W='cygpath -w' + else + CYGPATH_W=echo + fi +fi +AC_SUBST([CYGPATH_W]) + +# Define the identity of the package. +dnl Distinguish between old-style and new-style calls. +m4_ifval([$2], +[m4_ifval([$3], [_AM_SET_OPTION([no-define])])dnl + AC_SUBST([PACKAGE], [$1])dnl + AC_SUBST([VERSION], [$2])], +[_AM_SET_OPTIONS([$1])dnl + AC_SUBST([PACKAGE], ['AC_PACKAGE_TARNAME'])dnl + AC_SUBST([VERSION], ['AC_PACKAGE_VERSION'])])dnl + +_AM_IF_OPTION([no-define],, +[AC_DEFINE_UNQUOTED(PACKAGE, "$PACKAGE", [Name of package]) + AC_DEFINE_UNQUOTED(VERSION, "$VERSION", [Version number of package])])dnl + +# Some tools Automake needs. +AC_REQUIRE([AM_SANITY_CHECK])dnl +AC_REQUIRE([AC_ARG_PROGRAM])dnl +AM_MISSING_PROG(ACLOCAL, aclocal-${am__api_version}) +AM_MISSING_PROG(AUTOCONF, autoconf) +AM_MISSING_PROG(AUTOMAKE, automake-${am__api_version}) +AM_MISSING_PROG(AUTOHEADER, autoheader) +AM_MISSING_PROG(MAKEINFO, makeinfo) +AM_PROG_INSTALL_SH +AM_PROG_INSTALL_STRIP +AC_REQUIRE([AM_PROG_MKDIR_P])dnl +# We need awk for the "check" target. The system "awk" is bad on +# some platforms. +AC_REQUIRE([AC_PROG_AWK])dnl +AC_REQUIRE([AC_PROG_MAKE_SET])dnl +AC_REQUIRE([AM_SET_LEADING_DOT])dnl +_AM_IF_OPTION([tar-ustar], [_AM_PROG_TAR([ustar])], + [_AM_IF_OPTION([tar-pax], [_AM_PROG_TAR([pax])], + [_AM_PROG_TAR([v7])])]) +_AM_IF_OPTION([no-dependencies],, +[AC_PROVIDE_IFELSE([AC_PROG_CC], + [_AM_DEPENDENCIES(CC)], + [define([AC_PROG_CC], + defn([AC_PROG_CC])[_AM_DEPENDENCIES(CC)])])dnl +AC_PROVIDE_IFELSE([AC_PROG_CXX], + [_AM_DEPENDENCIES(CXX)], + [define([AC_PROG_CXX], + defn([AC_PROG_CXX])[_AM_DEPENDENCIES(CXX)])])dnl +]) +]) + + +# When config.status generates a header, we must update the stamp-h file. +# This file resides in the same directory as the config header +# that is generated. The stamp files are numbered to have different names. + +# Autoconf calls _AC_AM_CONFIG_HEADER_HOOK (when defined) in the +# loop where config.status creates the headers, so we can generate +# our stamp files there. +AC_DEFUN([_AC_AM_CONFIG_HEADER_HOOK], +[# Compute $1's index in $config_headers. +_am_stamp_count=1 +for _am_header in $config_headers :; do + case $_am_header in + $1 | $1:* ) + break ;; + * ) + _am_stamp_count=`expr $_am_stamp_count + 1` ;; + esac +done +echo "timestamp for $1" >`AS_DIRNAME([$1])`/stamp-h[]$_am_stamp_count]) + +# Copyright (C) 2001, 2003, 2005 Free Software Foundation, Inc. +# +# This file is free software; the Free Software Foundation +# gives unlimited permission to copy and/or distribute it, +# with or without modifications, as long as this notice is preserved. + +# AM_PROG_INSTALL_SH +# ------------------ +# Define $install_sh. +AC_DEFUN([AM_PROG_INSTALL_SH], +[AC_REQUIRE([AM_AUX_DIR_EXPAND])dnl +install_sh=${install_sh-"$am_aux_dir/install-sh"} +AC_SUBST(install_sh)]) + +# Copyright (C) 2003, 2005 Free Software Foundation, Inc. +# +# This file is free software; the Free Software Foundation +# gives unlimited permission to copy and/or distribute it, +# with or without modifications, as long as this notice is preserved. + +# serial 2 + +# Check whether the underlying file-system supports filenames +# with a leading dot. For instance MS-DOS doesn't. +AC_DEFUN([AM_SET_LEADING_DOT], +[rm -rf .tst 2>/dev/null +mkdir .tst 2>/dev/null +if test -d .tst; then + am__leading_dot=. +else + am__leading_dot=_ +fi +rmdir .tst 2>/dev/null +AC_SUBST([am__leading_dot])]) + +# Add --enable-maintainer-mode option to configure. -*- Autoconf -*- +# From Jim Meyering + +# Copyright (C) 1996, 1998, 2000, 2001, 2002, 2003, 2004, 2005 +# Free Software Foundation, Inc. +# +# This file is free software; the Free Software Foundation +# gives unlimited permission to copy and/or distribute it, +# with or without modifications, as long as this notice is preserved. + +# serial 4 + +AC_DEFUN([AM_MAINTAINER_MODE], +[AC_MSG_CHECKING([whether to enable maintainer-specific portions of Makefiles]) + dnl maintainer-mode is disabled by default + AC_ARG_ENABLE(maintainer-mode, +[ --enable-maintainer-mode enable make rules and dependencies not useful + (and sometimes confusing) to the casual installer], + USE_MAINTAINER_MODE=$enableval, + USE_MAINTAINER_MODE=no) + AC_MSG_RESULT([$USE_MAINTAINER_MODE]) + AM_CONDITIONAL(MAINTAINER_MODE, [test $USE_MAINTAINER_MODE = yes]) + MAINT=$MAINTAINER_MODE_TRUE + AC_SUBST(MAINT)dnl +] +) + +AU_DEFUN([jm_MAINTAINER_MODE], [AM_MAINTAINER_MODE]) + +# Check to see how 'make' treats includes. -*- Autoconf -*- + +# Copyright (C) 2001, 2002, 2003, 2005 Free Software Foundation, Inc. +# +# This file is free software; the Free Software Foundation +# gives unlimited permission to copy and/or distribute it, +# with or without modifications, as long as this notice is preserved. + +# serial 3 + +# AM_MAKE_INCLUDE() +# ----------------- +# Check to see how make treats includes. +AC_DEFUN([AM_MAKE_INCLUDE], +[am_make=${MAKE-make} +cat > confinc << 'END' +am__doit: + @echo done +.PHONY: am__doit +END +# If we don't find an include directive, just comment out the code. +AC_MSG_CHECKING([for style of include used by $am_make]) +am__include="#" +am__quote= +_am_result=none +# First try GNU make style include. +echo "include confinc" > confmf +# We grep out `Entering directory' and `Leaving directory' +# messages which can occur if `w' ends up in MAKEFLAGS. +# In particular we don't look at `^make:' because GNU make might +# be invoked under some other name (usually "gmake"), in which +# case it prints its new name instead of `make'. +if test "`$am_make -s -f confmf 2> /dev/null | grep -v 'ing directory'`" = "done"; then + am__include=include + am__quote= + _am_result=GNU +fi +# Now try BSD make style include. +if test "$am__include" = "#"; then + echo '.include "confinc"' > confmf + if test "`$am_make -s -f confmf 2> /dev/null`" = "done"; then + am__include=.include + am__quote="\"" + _am_result=BSD + fi +fi +AC_SUBST([am__include]) +AC_SUBST([am__quote]) +AC_MSG_RESULT([$_am_result]) +rm -f confinc confmf +]) + +# Fake the existence of programs that GNU maintainers use. -*- Autoconf -*- + +# Copyright (C) 1997, 1999, 2000, 2001, 2003, 2005 +# Free Software Foundation, Inc. +# +# This file is free software; the Free Software Foundation +# gives unlimited permission to copy and/or distribute it, +# with or without modifications, as long as this notice is preserved. + +# serial 4 + +# AM_MISSING_PROG(NAME, PROGRAM) +# ------------------------------ +AC_DEFUN([AM_MISSING_PROG], +[AC_REQUIRE([AM_MISSING_HAS_RUN]) +$1=${$1-"${am_missing_run}$2"} +AC_SUBST($1)]) + + +# AM_MISSING_HAS_RUN +# ------------------ +# Define MISSING if not defined so far and test if it supports --run. +# If it does, set am_missing_run to use it, otherwise, to nothing. +AC_DEFUN([AM_MISSING_HAS_RUN], +[AC_REQUIRE([AM_AUX_DIR_EXPAND])dnl +test x"${MISSING+set}" = xset || MISSING="\${SHELL} $am_aux_dir/missing" +# Use eval to expand $SHELL +if eval "$MISSING --run true"; then + am_missing_run="$MISSING --run " +else + am_missing_run= + AC_MSG_WARN([`missing' script is too old or missing]) +fi +]) + +# Copyright (C) 2003, 2004, 2005 Free Software Foundation, Inc. +# +# This file is free software; the Free Software Foundation +# gives unlimited permission to copy and/or distribute it, +# with or without modifications, as long as this notice is preserved. + +# AM_PROG_MKDIR_P +# --------------- +# Check whether `mkdir -p' is supported, fallback to mkinstalldirs otherwise. +# +# Automake 1.8 used `mkdir -m 0755 -p --' to ensure that directories +# created by `make install' are always world readable, even if the +# installer happens to have an overly restrictive umask (e.g. 077). +# This was a mistake. There are at least two reasons why we must not +# use `-m 0755': +# - it causes special bits like SGID to be ignored, +# - it may be too restrictive (some setups expect 775 directories). +# +# Do not use -m 0755 and let people choose whatever they expect by +# setting umask. +# +# We cannot accept any implementation of `mkdir' that recognizes `-p'. +# Some implementations (such as Solaris 8's) are not thread-safe: if a +# parallel make tries to run `mkdir -p a/b' and `mkdir -p a/c' +# concurrently, both version can detect that a/ is missing, but only +# one can create it and the other will error out. Consequently we +# restrict ourselves to GNU make (using the --version option ensures +# this.) +AC_DEFUN([AM_PROG_MKDIR_P], +[if mkdir -p --version . >/dev/null 2>&1 && test ! -d ./--version; then + # We used to keeping the `.' as first argument, in order to + # allow $(mkdir_p) to be used without argument. As in + # $(mkdir_p) $(somedir) + # where $(somedir) is conditionally defined. However this is wrong + # for two reasons: + # 1. if the package is installed by a user who cannot write `.' + # make install will fail, + # 2. the above comment should most certainly read + # $(mkdir_p) $(DESTDIR)$(somedir) + # so it does not work when $(somedir) is undefined and + # $(DESTDIR) is not. + # To support the latter case, we have to write + # test -z "$(somedir)" || $(mkdir_p) $(DESTDIR)$(somedir), + # so the `.' trick is pointless. + mkdir_p='mkdir -p --' +else + # On NextStep and OpenStep, the `mkdir' command does not + # recognize any option. It will interpret all options as + # directories to create, and then abort because `.' already + # exists. + for d in ./-p ./--version; + do + test -d $d && rmdir $d + done + # $(mkinstalldirs) is defined by Automake if mkinstalldirs exists. + if test -f "$ac_aux_dir/mkinstalldirs"; then + mkdir_p='$(mkinstalldirs)' + else + mkdir_p='$(install_sh) -d' + fi +fi +AC_SUBST([mkdir_p])]) + +# Helper functions for option handling. -*- Autoconf -*- + +# Copyright (C) 2001, 2002, 2003, 2005 Free Software Foundation, Inc. +# +# This file is free software; the Free Software Foundation +# gives unlimited permission to copy and/or distribute it, +# with or without modifications, as long as this notice is preserved. + +# serial 3 + +# _AM_MANGLE_OPTION(NAME) +# ----------------------- +AC_DEFUN([_AM_MANGLE_OPTION], +[[_AM_OPTION_]m4_bpatsubst($1, [[^a-zA-Z0-9_]], [_])]) + +# _AM_SET_OPTION(NAME) +# ------------------------------ +# Set option NAME. Presently that only means defining a flag for this option. +AC_DEFUN([_AM_SET_OPTION], +[m4_define(_AM_MANGLE_OPTION([$1]), 1)]) + +# _AM_SET_OPTIONS(OPTIONS) +# ---------------------------------- +# OPTIONS is a space-separated list of Automake options. +AC_DEFUN([_AM_SET_OPTIONS], +[AC_FOREACH([_AM_Option], [$1], [_AM_SET_OPTION(_AM_Option)])]) + +# _AM_IF_OPTION(OPTION, IF-SET, [IF-NOT-SET]) +# ------------------------------------------- +# Execute IF-SET if OPTION is set, IF-NOT-SET otherwise. +AC_DEFUN([_AM_IF_OPTION], +[m4_ifset(_AM_MANGLE_OPTION([$1]), [$2], [$3])]) + +# Check to make sure that the build environment is sane. -*- Autoconf -*- + +# Copyright (C) 1996, 1997, 2000, 2001, 2003, 2005 +# Free Software Foundation, Inc. +# +# This file is free software; the Free Software Foundation +# gives unlimited permission to copy and/or distribute it, +# with or without modifications, as long as this notice is preserved. + +# serial 4 + +# AM_SANITY_CHECK +# --------------- +AC_DEFUN([AM_SANITY_CHECK], +[AC_MSG_CHECKING([whether build environment is sane]) +# Just in case +sleep 1 +echo timestamp > conftest.file +# Do `set' in a subshell so we don't clobber the current shell's +# arguments. Must try -L first in case configure is actually a +# symlink; some systems play weird games with the mod time of symlinks +# (eg FreeBSD returns the mod time of the symlink's containing +# directory). +if ( + set X `ls -Lt $srcdir/configure conftest.file 2> /dev/null` + if test "$[*]" = "X"; then + # -L didn't work. + set X `ls -t $srcdir/configure conftest.file` + fi + rm -f conftest.file + if test "$[*]" != "X $srcdir/configure conftest.file" \ + && test "$[*]" != "X conftest.file $srcdir/configure"; then + + # If neither matched, then we have a broken ls. This can happen + # if, for instance, CONFIG_SHELL is bash and it inherits a + # broken ls alias from the environment. This has actually + # happened. Such a system could not be considered "sane". + AC_MSG_ERROR([ls -t appears to fail. Make sure there is not a broken +alias in your environment]) + fi + + test "$[2]" = conftest.file + ) +then + # Ok. + : +else + AC_MSG_ERROR([newly created file is older than distributed files! +Check your system clock]) +fi +AC_MSG_RESULT(yes)]) + +# Copyright (C) 2001, 2003, 2005 Free Software Foundation, Inc. +# +# This file is free software; the Free Software Foundation +# gives unlimited permission to copy and/or distribute it, +# with or without modifications, as long as this notice is preserved. + +# AM_PROG_INSTALL_STRIP +# --------------------- +# One issue with vendor `install' (even GNU) is that you can't +# specify the program used to strip binaries. This is especially +# annoying in cross-compiling environments, where the build's strip +# is unlikely to handle the host's binaries. +# Fortunately install-sh will honor a STRIPPROG variable, so we +# always use install-sh in `make install-strip', and initialize +# STRIPPROG with the value of the STRIP variable (set by the user). +AC_DEFUN([AM_PROG_INSTALL_STRIP], +[AC_REQUIRE([AM_PROG_INSTALL_SH])dnl +# Installed binaries are usually stripped using `strip' when the user +# run `make install-strip'. However `strip' might not be the right +# tool to use in cross-compilation environments, therefore Automake +# will honor the `STRIP' environment variable to overrule this program. +dnl Don't test for $cross_compiling = yes, because it might be `maybe'. +if test "$cross_compiling" != no; then + AC_CHECK_TOOL([STRIP], [strip], :) +fi +INSTALL_STRIP_PROGRAM="\${SHELL} \$(install_sh) -c -s" +AC_SUBST([INSTALL_STRIP_PROGRAM])]) + +# Check how to create a tarball. -*- Autoconf -*- + +# Copyright (C) 2004, 2005 Free Software Foundation, Inc. +# +# This file is free software; the Free Software Foundation +# gives unlimited permission to copy and/or distribute it, +# with or without modifications, as long as this notice is preserved. + +# serial 2 + +# _AM_PROG_TAR(FORMAT) +# -------------------- +# Check how to create a tarball in format FORMAT. +# FORMAT should be one of `v7', `ustar', or `pax'. +# +# Substitute a variable $(am__tar) that is a command +# writing to stdout a FORMAT-tarball containing the directory +# $tardir. +# tardir=directory && $(am__tar) > result.tar +# +# Substitute a variable $(am__untar) that extract such +# a tarball read from stdin. +# $(am__untar) < result.tar +AC_DEFUN([_AM_PROG_TAR], +[# Always define AMTAR for backward compatibility. +AM_MISSING_PROG([AMTAR], [tar]) +m4_if([$1], [v7], + [am__tar='${AMTAR} chof - "$$tardir"'; am__untar='${AMTAR} xf -'], + [m4_case([$1], [ustar],, [pax],, + [m4_fatal([Unknown tar format])]) +AC_MSG_CHECKING([how to create a $1 tar archive]) +# Loop over all known methods to create a tar archive until one works. +_am_tools='gnutar m4_if([$1], [ustar], [plaintar]) pax cpio none' +_am_tools=${am_cv_prog_tar_$1-$_am_tools} +# Do not fold the above two line into one, because Tru64 sh and +# Solaris sh will not grok spaces in the rhs of `-'. +for _am_tool in $_am_tools +do + case $_am_tool in + gnutar) + for _am_tar in tar gnutar gtar; + do + AM_RUN_LOG([$_am_tar --version]) && break + done + am__tar="$_am_tar --format=m4_if([$1], [pax], [posix], [$1]) -chf - "'"$$tardir"' + am__tar_="$_am_tar --format=m4_if([$1], [pax], [posix], [$1]) -chf - "'"$tardir"' + am__untar="$_am_tar -xf -" + ;; + plaintar) + # Must skip GNU tar: if it does not support --format= it doesn't create + # ustar tarball either. + (tar --version) >/dev/null 2>&1 && continue + am__tar='tar chf - "$$tardir"' + am__tar_='tar chf - "$tardir"' + am__untar='tar xf -' + ;; + pax) + am__tar='pax -L -x $1 -w "$$tardir"' + am__tar_='pax -L -x $1 -w "$tardir"' + am__untar='pax -r' + ;; + cpio) + am__tar='find "$$tardir" -print | cpio -o -H $1 -L' + am__tar_='find "$tardir" -print | cpio -o -H $1 -L' + am__untar='cpio -i -H $1 -d' + ;; + none) + am__tar=false + am__tar_=false + am__untar=false + ;; + esac + + # If the value was cached, stop now. We just wanted to have am__tar + # and am__untar set. + test -n "${am_cv_prog_tar_$1}" && break + + # tar/untar a dummy directory, and stop if the command works + rm -rf conftest.dir + mkdir conftest.dir + echo GrepMe > conftest.dir/file + AM_RUN_LOG([tardir=conftest.dir && eval $am__tar_ >conftest.tar]) + rm -rf conftest.dir + if test -s conftest.tar; then + AM_RUN_LOG([$am__untar <conftest.tar]) + grep GrepMe conftest.dir/file >/dev/null 2>&1 && break + fi +done +rm -rf conftest.dir + +AC_CACHE_VAL([am_cv_prog_tar_$1], [am_cv_prog_tar_$1=$_am_tool]) +AC_MSG_RESULT([$am_cv_prog_tar_$1])]) +AC_SUBST([am__tar]) +AC_SUBST([am__untar]) +]) # _AM_PROG_TAR + diff --git a/AMDiS/bin/Makefile.am b/AMDiS/bin/Makefile.am new file mode 100644 index 0000000000000000000000000000000000000000..92492e07eed697de6d56596f3e17af7b496f8f30 --- /dev/null +++ b/AMDiS/bin/Makefile.am @@ -0,0 +1,171 @@ +lib_LTLIBRARIES = libamdis.la libcompositeFEM.la + +SOURCE_DIR = ../src +LIB_DIR = ../lib +PARALLEL_DIR = $(SOURCE_DIR) + +PARMETIS_DIR = ../lib/ParMetis-3.1 + +AMDIS_INCLUDES = -I$(SOURCE_DIR) + +if USE_PARALLEL_AMDIS + PARALLEL_AMDIS_SOURCES = \ + $(PARALLEL_DIR)/ConditionalEstimator.h $(PARALLEL_DIR)/ConditionalEstimator.cc \ + $(PARALLEL_DIR)/ConditionalMarker.h \ + $(PARALLEL_DIR)/ElementFileWriter.h $(PARALLEL_DIR)/ElementFileWriter.cc \ + $(PARALLEL_DIR)/MeshStructure.h $(PARALLEL_DIR)/MeshStructure.cc \ + $(PARALLEL_DIR)/MeshStructure_ED.h \ + $(PARALLEL_DIR)/ParallelError.h $(PARALLEL_DIR)/ParallelError.hh \ + $(PARALLEL_DIR)/ParallelProblem.h $(PARALLEL_DIR)/ParallelProblem.cc \ + $(PARALLEL_DIR)/ParMetisPartitioner.h $(PARALLEL_DIR)/ParMetisPartitioner.cc \ + $(PARALLEL_DIR)/PartitionElementData.h + PARALLEL_INCLUDES = -I$(MPI_DIR)/include -I$(PARMETIS_DIR) +else + PARALLEL_AMDIS_SOURCES = + PARALLEL_INCLUDES = +endif + +libamdis_la_CXXFLAGS = + +if ENABLE_UMFPACK + libamdis_la_CXXFLAGS += -DHAVE_UMFPACK=1 + AMDIS_INCLUDES += -I$(LIB_DIR)/UFconfig \ + -I$(LIB_DIR)/AMD/Include \ + -I$(LIB_DIR)/UMFPACK/Include +endif + +INCLUDES = $(AMDIS_INCLUDES) $(PARALLEL_INCLUDES) + +if AMDIS_DEBUG + libamdis_la_CXXFLAGS += -g -O0 -Wall -DDEBUG=1 $(OPENMP_FLAG) -ftemplate-depth-30 $(INCLUDES) #-pedantic +else + libamdis_la_CXXFLAGS += -O3 -Wall -DDEBUG=0 $(OPENMP_FLAG) -ftemplate-depth-30 $(INCLUDES) #-pedantic +endif + + +libamdis_la_SOURCES = \ +$(PARALLEL_AMDIS_SOURCES) \ +$(SOURCE_DIR)/MultiGridPreconWrapper.h $(SOURCE_DIR)/MultiGridPreconWrapper.cc \ +$(SOURCE_DIR)/LagrangeInterpolRestrict.h $(SOURCE_DIR)/LagrangeInterpolRestrict.cc \ +$(SOURCE_DIR)/BiCGStab.h $(SOURCE_DIR)/BiCGStab.hh\ +$(SOURCE_DIR)/BiCGStab2.h $(SOURCE_DIR)/BiCGStab2.hh\ +$(SOURCE_DIR)/InterpolRestrictMatrix.h $(SOURCE_DIR)/InterpolRestrictMatrix.cc \ +$(SOURCE_DIR)/DOFIndexed.h $(SOURCE_DIR)/DOFIndexed.cc \ +$(SOURCE_DIR)/GNUPlotWriter.h $(SOURCE_DIR)/GNUPlotWriter.cc \ +$(SOURCE_DIR)/SmootherBase.h \ +$(SOURCE_DIR)/StlVector.h $(SOURCE_DIR)/StlVector.cc \ +$(SOURCE_DIR)/V3Vector.h $(SOURCE_DIR)/V3Vector.cc \ +$(SOURCE_DIR)/GSSMoother.h $(SOURCE_DIR)/GSSmoother.cc \ +$(SOURCE_DIR)/JacobiSMoother.h $(SOURCE_DIR)/JacobiSmoother.cc \ +$(SOURCE_DIR)/SparseVector.h $(SOURCE_DIR)/SparseVector.hh $(SOURCE_DIR)/SparseVector.cc \ +$(SOURCE_DIR)/VertexVector.h $(SOURCE_DIR)/VertexVector.cc \ +$(SOURCE_DIR)/PeriodicBC.h $(SOURCE_DIR)/PeriodicBC.cc \ +$(SOURCE_DIR)/MultiGridSolverBase.h $(SOURCE_DIR)/MultiGridSolverBase.hh \ +$(SOURCE_DIR)/MultiGridSolver.h $(SOURCE_DIR)/MultiGridSolver.cc \ +$(SOURCE_DIR)/Recovery.h $(SOURCE_DIR)/Recovery.cc \ +$(SOURCE_DIR)/RecoveryEstimator.h $(SOURCE_DIR)/RecoveryEstimator.cc \ +$(SOURCE_DIR)/Cholesky.h $(SOURCE_DIR)/Cholesky.cc \ +$(SOURCE_DIR)/AdaptBase.h $(SOURCE_DIR)/AdaptBase.cc \ +$(SOURCE_DIR)/ProblemIterationInterface.h $(SOURCE_DIR)/StandardProblemIteration.h $(SOURCE_DIR)/StandardProblemIteration.cc \ +$(SOURCE_DIR)/ProblemScal.h $(SOURCE_DIR)/ProblemScal.cc \ +$(SOURCE_DIR)/ProblemVec.h $(SOURCE_DIR)/ProblemVec.cc \ +$(SOURCE_DIR)/DualTraverse.h $(SOURCE_DIR)/DualTraverse.cc \ +$(SOURCE_DIR)/ElementPartition_ED.h $(SOURCE_DIR)/SurfacePartition_ED.h \ +$(SOURCE_DIR)/ElementData.h $(SOURCE_DIR)/ElementData.cc \ +$(SOURCE_DIR)/CreatorMap.h $(SOURCE_DIR)/CreatorMap.cc $(SOURCE_DIR)/CreatorInterface.h \ +$(SOURCE_DIR)/ElementFunction.h \ +$(SOURCE_DIR)/ProblemInterpolScal.h $(SOURCE_DIR)/ProblemInterpolScal.cc \ +$(SOURCE_DIR)/ProblemInterpolVec.h $(SOURCE_DIR)/ProblemInterpolVec.cc \ +$(SOURCE_DIR)/Serializable.h $(SOURCE_DIR)/BallProject.h $(SOURCE_DIR)/CylinderProject.h \ +$(SOURCE_DIR)/MacroReader.h $(SOURCE_DIR)/MacroReader.cc \ +$(SOURCE_DIR)/ValueReader.h $(SOURCE_DIR)/ValueReader.cc \ +$(SOURCE_DIR)/Projection.h $(SOURCE_DIR)/Projection.cc \ +$(SOURCE_DIR)/Assembler.h $(SOURCE_DIR)/Assembler.cc \ +$(SOURCE_DIR)/AdaptInfo.h $(SOURCE_DIR)/AdaptInfo.cc \ +$(SOURCE_DIR)/Marker.h $(SOURCE_DIR)/Marker.cc \ +$(SOURCE_DIR)/SystemVector.h \ +$(SOURCE_DIR)/MatrixVector.h $(SOURCE_DIR)/MatrixVector.cc \ +$(SOURCE_DIR)/SurfaceQuadrature.h $(SOURCE_DIR)/SurfaceQuadrature.cc \ +$(SOURCE_DIR)/LeafData.h $(SOURCE_DIR)/LeafData.cc \ +$(SOURCE_DIR)/BoundaryManager.h $(SOURCE_DIR)/BoundaryManager.cc $(SOURCE_DIR)/BoundaryCondition.h \ +$(SOURCE_DIR)/DirichletBC.h $(SOURCE_DIR)/DirichletBC.cc \ +$(SOURCE_DIR)/RobinBC.h $(SOURCE_DIR)/RobinBC.cc \ +$(SOURCE_DIR)/AbstractFunction.h \ +$(SOURCE_DIR)/ProblemStatBase.h \ +$(SOURCE_DIR)/MatVecMultiplier.cc \ +$(SOURCE_DIR)/DOFContainer.h \ +$(SOURCE_DIR)/FileWriter.h $(SOURCE_DIR)/FileWriter.hh $(SOURCE_DIR)/FileWriter.cc \ +$(SOURCE_DIR)/ElInfo.cc \ +$(SOURCE_DIR)/MatVecMultiplier.h \ +$(SOURCE_DIR)/Operator.h $(SOURCE_DIR)/Operator.cc \ +$(SOURCE_DIR)/Mesh.cc \ +$(SOURCE_DIR)/AMDiS.h \ +$(SOURCE_DIR)/AdaptStationary.h $(SOURCE_DIR)/AdaptStationary.cc \ +$(SOURCE_DIR)/AdaptInstationary.h $(SOURCE_DIR)/AdaptInstationary.cc \ +$(SOURCE_DIR)/QPsiPhi.h \ +$(SOURCE_DIR)/BasisFunction.h \ +$(SOURCE_DIR)/BiCGSolver.h $(SOURCE_DIR)/BiCGSolver.hh \ +$(SOURCE_DIR)/Boundary.h \ +$(SOURCE_DIR)/CGSolver.h $(SOURCE_DIR)/CGSolver.hh \ +$(SOURCE_DIR)/CoarseningManager.h \ +$(SOURCE_DIR)/CoarseningManager1d.h $(SOURCE_DIR)/CoarseningManager2d.h $(SOURCE_DIR)/CoarseningManager3d.h \ +$(SOURCE_DIR)/demangle.h \ +$(SOURCE_DIR)/DiagonalPreconditioner.h $(SOURCE_DIR)/DiagonalPreconditioner.cc \ +$(SOURCE_DIR)/ILUPreconditioner.h $(SOURCE_DIR)/ILUPreconditioner.cc \ +$(SOURCE_DIR)/ILUTPreconditioner.h $(SOURCE_DIR)/ILUTPreconditioner.cc \ +$(SOURCE_DIR)/DOFAdmin.h $(SOURCE_DIR)/DOFIterator.h $(SOURCE_DIR)/DOFMatrix.h $(SOURCE_DIR)/DOFVector.h $(SOURCE_DIR)/DOFVector.hh $(SOURCE_DIR)/DOFVector.cc $(SOURCE_DIR)/Element.h $(SOURCE_DIR)/ElementConnection.h \ +$(SOURCE_DIR)/ElInfo.h $(SOURCE_DIR)/ElInfo1d.h $(SOURCE_DIR)/ElInfo2d.h $(SOURCE_DIR)/ElInfo3d.h $(SOURCE_DIR)/Error.h \ +$(SOURCE_DIR)/Error.hh $(SOURCE_DIR)/Estimator.h $(SOURCE_DIR)/Estimator.cc $(SOURCE_DIR)/FiniteElemSpace.h $(SOURCE_DIR)/FixVec.h $(SOURCE_DIR)/FixVec.hh $(SOURCE_DIR)/FixVecConvert.h $(SOURCE_DIR)/Flag.h $(SOURCE_DIR)/Global.h \ +$(SOURCE_DIR)/GMResSolver.h \ $(SOURCE_DIR)/GMResSolver.hh \ +$(SOURCE_DIR)/GMResSolver2.h \ $(SOURCE_DIR)/GMResSolver2.hh \ +$(SOURCE_DIR)/TFQMR.h \ $(SOURCE_DIR)/TFQMR.hh \ +$(SOURCE_DIR)/VecSymSolver.h \ $(SOURCE_DIR)/VecSymSolver.hh \ +$(SOURCE_DIR)/UmfPackSolver.h \ $(SOURCE_DIR)/UmfPackSolver.hh \ +$(SOURCE_DIR)/Lagrange.h $(SOURCE_DIR)/Line.h \ +$(SOURCE_DIR)/MacroElement.h $(SOURCE_DIR)/MacroWriter.h $(SOURCE_DIR)/Markings.h $(SOURCE_DIR)/Markings.hh $(SOURCE_DIR)/MemoryManager.h $(SOURCE_DIR)/Mesh.h $(SOURCE_DIR)/ODirSolver.h $(SOURCE_DIR)/ODirSolver.hh $(SOURCE_DIR)/OEMSolver.h \ +$(SOURCE_DIR)/OEMSolver.hh $(SOURCE_DIR)/OResSolver.h $(SOURCE_DIR)/OResSolver.hh $(SOURCE_DIR)/Parameters.h $(SOURCE_DIR)/Parametric.h $(SOURCE_DIR)/Preconditioner.h \ +$(SOURCE_DIR)/Quadrature.h \ +$(SOURCE_DIR)/RCNeighbourList.h $(SOURCE_DIRe)/RefinementManager.h $(SOURCE_DIR)/RefinementManager1d.h $(SOURCE_DIR)/RefinementManager2d.h $(SOURCE_DIR)/RefinementManager3d.h $(SOURCE_DIR)/TecPlotWriter.h $(SOURCE_DIR)/TecPlotWriter.hh $(SOURCE_DIR)/Tetrahedron.h \ +$(SOURCE_DIR)/Traverse.h $(SOURCE_DIR)/Triangle.h $(SOURCE_DIR)/NonLinSolver.h $(SOURCE_DIR)/NonLinSolver.hh $(SOURCE_DIR)/ProblemInstat.h $(SOURCE_DIR)/ProblemInstat.cc $(SOURCE_DIR)/ProblemTimeInterface.h $(SOURCE_DIR)/ProblemNonLin.h $(SOURCE_DIR)/ProblemNonLin.cc \ +$(SOURCE_DIR)/NonLinUpdater.h $(SOURCE_DIR)/NonLinUpdater.cc \ +$(SOURCE_DIR)/Newton.h $(SOURCE_DIR)/Newton.hh $(SOURCE_DIR)/NewtonFS.h $(SOURCE_DIR)/NewtonFS.hh $(SOURCE_DIR)/GridWriter.h $(SOURCE_DIR)/GridWriter.hh $(SOURCE_DIR)/ValueWriter.h $(SOURCE_DIR)/QPsiPhi.cc $(SOURCE_DIR)/BasisFunction.cc $(SOURCE_DIR)/Boundary.cc \ +$(SOURCE_DIR)/CoarseningManager.cc $(SOURCE_DIR)/CoarseningManager1d.cc $(SOURCE_DIR)/CoarseningManager2d.cc $(SOURCE_DIR)/CoarseningManager3d.cc $(SOURCE_DIR)/demangle.cc $(SOURCE_DIR)/DOFAdmin.cc $(SOURCE_DIR)/DOFMatrix.cc $(SOURCE_DIR)/Element.cc $(SOURCE_DIR)/ElInfo1d.cc \ +$(SOURCE_DIR)/ElInfo2d.cc $(SOURCE_DIR)/ElInfo3d.cc $(SOURCE_DIR)/FiniteElemSpace.cc $(SOURCE_DIR)/FixVec.cc $(SOURCE_DIR)/Flag.cc $(SOURCE_DIR)/Global.cc $(SOURCE_DIR)/Lagrange.cc $(SOURCE_DIR)/Line.cc $(SOURCE_DIR)/MacroElement.cc $(SOURCE_DIR)/MacroWriter.cc $(SOURCE_DIR)/Parameters.cc \ +$(SOURCE_DIR)/Parametric.cc $(SOURCE_DIR)/Quadrature.cc $(SOURCE_DIR)/RCNeighbourList.cc $(SOURCE_DIR)/RefinementManager.cc $(SOURCE_DIR)/RefinementManager1d.cc $(SOURCE_DIR)/RefinementManager2d.cc $(SOURCE_DIR)/RefinementManager3d.cc $(SOURCE_DIR)/Tetrahedron.cc $(SOURCE_DIR)/Traverse.cc \ +$(SOURCE_DIR)/Triangle.cc $(SOURCE_DIR)/TecPlotWriter.cc $(SOURCE_DIR)/ValueWriter.cc $(SOURCE_DIR)/MemoryPool.h $(SOURCE_DIR)/MemoryPool.cc $(SOURCE_DIR)/MemoryManager.cc \ +$(SOURCE_DIR)/VtkWriter.h $(SOURCE_DIR)/VtkWriter.cc \ +$(SOURCE_DIR)/DataCollector.h $(SOURCE_DIR)/DataCollector.cc \ +$(SOURCE_DIR)/ElementInfo.h $(SOURCE_DIR)/VertexInfo.h $(SOURCE_DIR)/PeriodicInfo.h \ +$(SOURCE_DIR)/OpenMP.h + + +COMPOSITE_SOURCE_DIR = ../compositeFEM/src + +if AMDIS_DEBUG + libcompositeFEM_la_CXXFLAGS = -g -O0 -Wall -DDEBUG=1 -I$(SOURCE_DIR) +else + libcompositeFEM_la_CXXFLAGS = -O2 -Wall -DDEBUG=0 -I$(SOURCE_DIR) +endif + +libcompositeFEM_la_SOURCES = $(COMPOSITE_SOURCE_DIR)/CFE_Integration.h \ +$(COMPOSITE_SOURCE_DIR)/CFE_Integration.cc \ +$(COMPOSITE_SOURCE_DIR)/CFE_NormAndErrorFcts.h \ +$(COMPOSITE_SOURCE_DIR)/CFE_NormAndErrorFcts.cc \ +$(COMPOSITE_SOURCE_DIR)/CompositeFEMMethods.h \ +$(COMPOSITE_SOURCE_DIR)/CompositeFEMMethods.cc \ +$(COMPOSITE_SOURCE_DIR)/LevelSetAdaptMesh.h \ +$(COMPOSITE_SOURCE_DIR)/LevelSetAdaptMesh.cc \ +$(COMPOSITE_SOURCE_DIR)/PenaltyOperator.h \ +$(COMPOSITE_SOURCE_DIR)/PenaltyOperator.cc \ +$(COMPOSITE_SOURCE_DIR)/ElementLevelSet.h \ +$(COMPOSITE_SOURCE_DIR)/ElementLevelSet.cc \ +$(COMPOSITE_SOURCE_DIR)/CompositeFEMOperator.h \ +$(COMPOSITE_SOURCE_DIR)/CompositeFEMOperator.cc \ +$(COMPOSITE_SOURCE_DIR)/SubPolytope.h $(COMPOSITE_SOURCE_DIR)/SubPolytope.cc \ +$(COMPOSITE_SOURCE_DIR)/ScalableQuadrature.h \ +$(COMPOSITE_SOURCE_DIR)/ScalableQuadrature.cc \ +$(COMPOSITE_SOURCE_DIR)/SubElInfo.h $(COMPOSITE_SOURCE_DIR)/SubElInfo.cc \ +$(COMPOSITE_SOURCE_DIR)/SubElementAssembler.h \ +$(COMPOSITE_SOURCE_DIR)/SubElementAssembler.cc \ +$(COMPOSITE_SOURCE_DIR)/TranslateLsFct.h + diff --git a/AMDiS/bin/Makefile.in b/AMDiS/bin/Makefile.in new file mode 100644 index 0000000000000000000000000000000000000000..a6ee22916930ef2cca49f9c51018480919a3e73c --- /dev/null +++ b/AMDiS/bin/Makefile.in @@ -0,0 +1,1710 @@ +# Makefile.in generated by automake 1.9.6 from Makefile.am. +# @configure_input@ + +# Copyright (C) 1994, 1995, 1996, 1997, 1998, 1999, 2000, 2001, 2002, +# 2003, 2004, 2005 Free Software Foundation, Inc. +# This Makefile.in is free software; the Free Software Foundation +# gives unlimited permission to copy and/or distribute it, +# with or without modifications, as long as this notice is preserved. + +# This program is distributed in the hope that it will be useful, +# but WITHOUT ANY WARRANTY, to the extent permitted by law; without +# even the implied warranty of MERCHANTABILITY or FITNESS FOR A +# PARTICULAR PURPOSE. + +@SET_MAKE@ + +srcdir = @srcdir@ +top_srcdir = @top_srcdir@ +VPATH = @srcdir@ +pkgdatadir = $(datadir)/@PACKAGE@ +pkglibdir = $(libdir)/@PACKAGE@ +pkgincludedir = $(includedir)/@PACKAGE@ +top_builddir = .. +am__cd = CDPATH="$${ZSH_VERSION+.}$(PATH_SEPARATOR)" && cd +INSTALL = @INSTALL@ +install_sh_DATA = $(install_sh) -c -m 644 +install_sh_PROGRAM = $(install_sh) -c +install_sh_SCRIPT = $(install_sh) -c +INSTALL_HEADER = $(INSTALL_DATA) +transform = $(program_transform_name) +NORMAL_INSTALL = : +PRE_INSTALL = : +POST_INSTALL = : +NORMAL_UNINSTALL = : +PRE_UNINSTALL = : +POST_UNINSTALL = : +build_triplet = @build@ +host_triplet = @host@ +@ENABLE_UMFPACK_TRUE@am__append_1 = -DHAVE_UMFPACK=1 +@ENABLE_UMFPACK_TRUE@am__append_2 = -I$(LIB_DIR)/UFconfig \ +@ENABLE_UMFPACK_TRUE@ -I$(LIB_DIR)/AMD/Include \ +@ENABLE_UMFPACK_TRUE@ -I$(LIB_DIR)/UMFPACK/Include + +@AMDIS_DEBUG_TRUE@am__append_3 = -g -O0 -Wall -DDEBUG=1 $(OPENMP_FLAG) -ftemplate-depth-30 $(INCLUDES) #-pedantic +@AMDIS_DEBUG_FALSE@am__append_4 = -O3 -Wall -DDEBUG=0 $(OPENMP_FLAG) -ftemplate-depth-30 $(INCLUDES) #-pedantic +subdir = bin +DIST_COMMON = $(srcdir)/Makefile.am $(srcdir)/Makefile.in +ACLOCAL_M4 = $(top_srcdir)/aclocal.m4 +am__aclocal_m4_deps = $(top_srcdir)/configure.ac +am__configure_deps = $(am__aclocal_m4_deps) $(CONFIGURE_DEPENDENCIES) \ + $(ACLOCAL_M4) +mkinstalldirs = $(install_sh) -d +CONFIG_CLEAN_FILES = +am__vpath_adj_setup = srcdirstrip=`echo "$(srcdir)" | sed 's|.|.|g'`; +am__vpath_adj = case $$p in \ + $(srcdir)/*) f=`echo "$$p" | sed "s|^$$srcdirstrip/||"`;; \ + *) f=$$p;; \ + esac; +am__strip_dir = `echo $$p | sed -e 's|^.*/||'`; +am__installdirs = "$(DESTDIR)$(libdir)" +libLTLIBRARIES_INSTALL = $(INSTALL) +LTLIBRARIES = $(lib_LTLIBRARIES) +libamdis_la_LIBADD = +am__libamdis_la_SOURCES_DIST = $(PARALLEL_DIR)/ConditionalEstimator.h \ + $(PARALLEL_DIR)/ConditionalEstimator.cc \ + $(PARALLEL_DIR)/ConditionalMarker.h \ + $(PARALLEL_DIR)/ElementFileWriter.h \ + $(PARALLEL_DIR)/ElementFileWriter.cc \ + $(PARALLEL_DIR)/MeshStructure.h \ + $(PARALLEL_DIR)/MeshStructure.cc \ + $(PARALLEL_DIR)/MeshStructure_ED.h \ + $(PARALLEL_DIR)/ParallelError.h \ + $(PARALLEL_DIR)/ParallelError.hh \ + $(PARALLEL_DIR)/ParallelProblem.h \ + $(PARALLEL_DIR)/ParallelProblem.cc \ + $(PARALLEL_DIR)/ParMetisPartitioner.h \ + $(PARALLEL_DIR)/ParMetisPartitioner.cc \ + $(PARALLEL_DIR)/PartitionElementData.h \ + $(SOURCE_DIR)/MultiGridPreconWrapper.h \ + $(SOURCE_DIR)/MultiGridPreconWrapper.cc \ + $(SOURCE_DIR)/LagrangeInterpolRestrict.h \ + $(SOURCE_DIR)/LagrangeInterpolRestrict.cc \ + $(SOURCE_DIR)/BiCGStab.h $(SOURCE_DIR)/BiCGStab.hh \ + $(SOURCE_DIR)/BiCGStab2.h $(SOURCE_DIR)/BiCGStab2.hh \ + $(SOURCE_DIR)/InterpolRestrictMatrix.h \ + $(SOURCE_DIR)/InterpolRestrictMatrix.cc \ + $(SOURCE_DIR)/DOFIndexed.h $(SOURCE_DIR)/DOFIndexed.cc \ + $(SOURCE_DIR)/GNUPlotWriter.h $(SOURCE_DIR)/GNUPlotWriter.cc \ + $(SOURCE_DIR)/SmootherBase.h $(SOURCE_DIR)/StlVector.h \ + $(SOURCE_DIR)/StlVector.cc $(SOURCE_DIR)/V3Vector.h \ + $(SOURCE_DIR)/V3Vector.cc $(SOURCE_DIR)/GSSMoother.h \ + $(SOURCE_DIR)/GSSmoother.cc $(SOURCE_DIR)/JacobiSMoother.h \ + $(SOURCE_DIR)/JacobiSmoother.cc $(SOURCE_DIR)/SparseVector.h \ + $(SOURCE_DIR)/SparseVector.hh $(SOURCE_DIR)/SparseVector.cc \ + $(SOURCE_DIR)/VertexVector.h $(SOURCE_DIR)/VertexVector.cc \ + $(SOURCE_DIR)/PeriodicBC.h $(SOURCE_DIR)/PeriodicBC.cc \ + $(SOURCE_DIR)/MultiGridSolverBase.h \ + $(SOURCE_DIR)/MultiGridSolverBase.hh \ + $(SOURCE_DIR)/MultiGridSolver.h \ + $(SOURCE_DIR)/MultiGridSolver.cc $(SOURCE_DIR)/Recovery.h \ + $(SOURCE_DIR)/Recovery.cc $(SOURCE_DIR)/RecoveryEstimator.h \ + $(SOURCE_DIR)/RecoveryEstimator.cc $(SOURCE_DIR)/Cholesky.h \ + $(SOURCE_DIR)/Cholesky.cc $(SOURCE_DIR)/AdaptBase.h \ + $(SOURCE_DIR)/AdaptBase.cc \ + $(SOURCE_DIR)/ProblemIterationInterface.h \ + $(SOURCE_DIR)/StandardProblemIteration.h \ + $(SOURCE_DIR)/StandardProblemIteration.cc \ + $(SOURCE_DIR)/ProblemScal.h $(SOURCE_DIR)/ProblemScal.cc \ + $(SOURCE_DIR)/ProblemVec.h $(SOURCE_DIR)/ProblemVec.cc \ + $(SOURCE_DIR)/DualTraverse.h $(SOURCE_DIR)/DualTraverse.cc \ + $(SOURCE_DIR)/ElementPartition_ED.h \ + $(SOURCE_DIR)/SurfacePartition_ED.h \ + $(SOURCE_DIR)/ElementData.h $(SOURCE_DIR)/ElementData.cc \ + $(SOURCE_DIR)/CreatorMap.h $(SOURCE_DIR)/CreatorMap.cc \ + $(SOURCE_DIR)/CreatorInterface.h \ + $(SOURCE_DIR)/ElementFunction.h \ + $(SOURCE_DIR)/ProblemInterpolScal.h \ + $(SOURCE_DIR)/ProblemInterpolScal.cc \ + $(SOURCE_DIR)/ProblemInterpolVec.h \ + $(SOURCE_DIR)/ProblemInterpolVec.cc \ + $(SOURCE_DIR)/Serializable.h $(SOURCE_DIR)/BallProject.h \ + $(SOURCE_DIR)/CylinderProject.h $(SOURCE_DIR)/MacroReader.h \ + $(SOURCE_DIR)/MacroReader.cc $(SOURCE_DIR)/ValueReader.h \ + $(SOURCE_DIR)/ValueReader.cc $(SOURCE_DIR)/Projection.h \ + $(SOURCE_DIR)/Projection.cc $(SOURCE_DIR)/Assembler.h \ + $(SOURCE_DIR)/Assembler.cc $(SOURCE_DIR)/AdaptInfo.h \ + $(SOURCE_DIR)/AdaptInfo.cc $(SOURCE_DIR)/Marker.h \ + $(SOURCE_DIR)/Marker.cc $(SOURCE_DIR)/SystemVector.h \ + $(SOURCE_DIR)/MatrixVector.h $(SOURCE_DIR)/MatrixVector.cc \ + $(SOURCE_DIR)/SurfaceQuadrature.h \ + $(SOURCE_DIR)/SurfaceQuadrature.cc $(SOURCE_DIR)/LeafData.h \ + $(SOURCE_DIR)/LeafData.cc $(SOURCE_DIR)/BoundaryManager.h \ + $(SOURCE_DIR)/BoundaryManager.cc \ + $(SOURCE_DIR)/BoundaryCondition.h $(SOURCE_DIR)/DirichletBC.h \ + $(SOURCE_DIR)/DirichletBC.cc $(SOURCE_DIR)/RobinBC.h \ + $(SOURCE_DIR)/RobinBC.cc $(SOURCE_DIR)/AbstractFunction.h \ + $(SOURCE_DIR)/ProblemStatBase.h \ + $(SOURCE_DIR)/MatVecMultiplier.cc $(SOURCE_DIR)/DOFContainer.h \ + $(SOURCE_DIR)/FileWriter.h $(SOURCE_DIR)/FileWriter.hh \ + $(SOURCE_DIR)/FileWriter.cc $(SOURCE_DIR)/ElInfo.cc \ + $(SOURCE_DIR)/MatVecMultiplier.h $(SOURCE_DIR)/Operator.h \ + $(SOURCE_DIR)/Operator.cc $(SOURCE_DIR)/Mesh.cc \ + $(SOURCE_DIR)/AMDiS.h $(SOURCE_DIR)/AdaptStationary.h \ + $(SOURCE_DIR)/AdaptStationary.cc \ + $(SOURCE_DIR)/AdaptInstationary.h \ + $(SOURCE_DIR)/AdaptInstationary.cc $(SOURCE_DIR)/QPsiPhi.h \ + $(SOURCE_DIR)/BasisFunction.h $(SOURCE_DIR)/BiCGSolver.h \ + $(SOURCE_DIR)/BiCGSolver.hh $(SOURCE_DIR)/Boundary.h \ + $(SOURCE_DIR)/CGSolver.h $(SOURCE_DIR)/CGSolver.hh \ + $(SOURCE_DIR)/CoarseningManager.h \ + $(SOURCE_DIR)/CoarseningManager1d.h \ + $(SOURCE_DIR)/CoarseningManager2d.h \ + $(SOURCE_DIR)/CoarseningManager3d.h $(SOURCE_DIR)/demangle.h \ + $(SOURCE_DIR)/DiagonalPreconditioner.h \ + $(SOURCE_DIR)/DiagonalPreconditioner.cc \ + $(SOURCE_DIR)/ILUPreconditioner.h \ + $(SOURCE_DIR)/ILUPreconditioner.cc \ + $(SOURCE_DIR)/ILUTPreconditioner.h \ + $(SOURCE_DIR)/ILUTPreconditioner.cc $(SOURCE_DIR)/DOFAdmin.h \ + $(SOURCE_DIR)/DOFIterator.h $(SOURCE_DIR)/DOFMatrix.h \ + $(SOURCE_DIR)/DOFVector.h $(SOURCE_DIR)/DOFVector.hh \ + $(SOURCE_DIR)/DOFVector.cc $(SOURCE_DIR)/Element.h \ + $(SOURCE_DIR)/ElementConnection.h $(SOURCE_DIR)/ElInfo.h \ + $(SOURCE_DIR)/ElInfo1d.h $(SOURCE_DIR)/ElInfo2d.h \ + $(SOURCE_DIR)/ElInfo3d.h $(SOURCE_DIR)/Error.h \ + $(SOURCE_DIR)/Error.hh $(SOURCE_DIR)/Estimator.h \ + $(SOURCE_DIR)/Estimator.cc $(SOURCE_DIR)/FiniteElemSpace.h \ + $(SOURCE_DIR)/FixVec.h $(SOURCE_DIR)/FixVec.hh \ + $(SOURCE_DIR)/FixVecConvert.h $(SOURCE_DIR)/Flag.h \ + $(SOURCE_DIR)/Global.h $(SOURCE_DIR)/GMResSolver.h \ \ + $(SOURCE_DIR)/GMResSolver.hh $(SOURCE_DIR)/GMResSolver2.h \ + $(SOURCE_DIR)/GMResSolver2.hh $(SOURCE_DIR)/TFQMR.h \ + $(SOURCE_DIR)/TFQMR.hh $(SOURCE_DIR)/VecSymSolver.h \ + $(SOURCE_DIR)/VecSymSolver.hh $(SOURCE_DIR)/UmfPackSolver.h \ + $(SOURCE_DIR)/UmfPackSolver.hh $(SOURCE_DIR)/Lagrange.h \ + $(SOURCE_DIR)/Line.h $(SOURCE_DIR)/MacroElement.h \ + $(SOURCE_DIR)/MacroWriter.h $(SOURCE_DIR)/Markings.h \ + $(SOURCE_DIR)/Markings.hh $(SOURCE_DIR)/MemoryManager.h \ + $(SOURCE_DIR)/Mesh.h $(SOURCE_DIR)/ODirSolver.h \ + $(SOURCE_DIR)/ODirSolver.hh $(SOURCE_DIR)/OEMSolver.h \ + $(SOURCE_DIR)/OEMSolver.hh $(SOURCE_DIR)/OResSolver.h \ + $(SOURCE_DIR)/OResSolver.hh $(SOURCE_DIR)/Parameters.h \ + $(SOURCE_DIR)/Parametric.h $(SOURCE_DIR)/Preconditioner.h \ + $(SOURCE_DIR)/Quadrature.h $(SOURCE_DIR)/RCNeighbourList.h \ + $(SOURCE_DIRe)/RefinementManager.h \ + $(SOURCE_DIR)/RefinementManager1d.h \ + $(SOURCE_DIR)/RefinementManager2d.h \ + $(SOURCE_DIR)/RefinementManager3d.h \ + $(SOURCE_DIR)/TecPlotWriter.h $(SOURCE_DIR)/TecPlotWriter.hh \ + $(SOURCE_DIR)/Tetrahedron.h $(SOURCE_DIR)/Traverse.h \ + $(SOURCE_DIR)/Triangle.h $(SOURCE_DIR)/NonLinSolver.h \ + $(SOURCE_DIR)/NonLinSolver.hh $(SOURCE_DIR)/ProblemInstat.h \ + $(SOURCE_DIR)/ProblemInstat.cc \ + $(SOURCE_DIR)/ProblemTimeInterface.h \ + $(SOURCE_DIR)/ProblemNonLin.h $(SOURCE_DIR)/ProblemNonLin.cc \ + $(SOURCE_DIR)/NonLinUpdater.h $(SOURCE_DIR)/NonLinUpdater.cc \ + $(SOURCE_DIR)/Newton.h $(SOURCE_DIR)/Newton.hh \ + $(SOURCE_DIR)/NewtonFS.h $(SOURCE_DIR)/NewtonFS.hh \ + $(SOURCE_DIR)/GridWriter.h $(SOURCE_DIR)/GridWriter.hh \ + $(SOURCE_DIR)/ValueWriter.h $(SOURCE_DIR)/QPsiPhi.cc \ + $(SOURCE_DIR)/BasisFunction.cc $(SOURCE_DIR)/Boundary.cc \ + $(SOURCE_DIR)/CoarseningManager.cc \ + $(SOURCE_DIR)/CoarseningManager1d.cc \ + $(SOURCE_DIR)/CoarseningManager2d.cc \ + $(SOURCE_DIR)/CoarseningManager3d.cc $(SOURCE_DIR)/demangle.cc \ + $(SOURCE_DIR)/DOFAdmin.cc $(SOURCE_DIR)/DOFMatrix.cc \ + $(SOURCE_DIR)/Element.cc $(SOURCE_DIR)/ElInfo1d.cc \ + $(SOURCE_DIR)/ElInfo2d.cc $(SOURCE_DIR)/ElInfo3d.cc \ + $(SOURCE_DIR)/FiniteElemSpace.cc $(SOURCE_DIR)/FixVec.cc \ + $(SOURCE_DIR)/Flag.cc $(SOURCE_DIR)/Global.cc \ + $(SOURCE_DIR)/Lagrange.cc $(SOURCE_DIR)/Line.cc \ + $(SOURCE_DIR)/MacroElement.cc $(SOURCE_DIR)/MacroWriter.cc \ + $(SOURCE_DIR)/Parameters.cc $(SOURCE_DIR)/Parametric.cc \ + $(SOURCE_DIR)/Quadrature.cc $(SOURCE_DIR)/RCNeighbourList.cc \ + $(SOURCE_DIR)/RefinementManager.cc \ + $(SOURCE_DIR)/RefinementManager1d.cc \ + $(SOURCE_DIR)/RefinementManager2d.cc \ + $(SOURCE_DIR)/RefinementManager3d.cc \ + $(SOURCE_DIR)/Tetrahedron.cc $(SOURCE_DIR)/Traverse.cc \ + $(SOURCE_DIR)/Triangle.cc $(SOURCE_DIR)/TecPlotWriter.cc \ + $(SOURCE_DIR)/ValueWriter.cc $(SOURCE_DIR)/MemoryPool.h \ + $(SOURCE_DIR)/MemoryPool.cc $(SOURCE_DIR)/MemoryManager.cc \ + $(SOURCE_DIR)/VtkWriter.h $(SOURCE_DIR)/VtkWriter.cc \ + $(SOURCE_DIR)/DataCollector.h $(SOURCE_DIR)/DataCollector.cc \ + $(SOURCE_DIR)/ElementInfo.h $(SOURCE_DIR)/VertexInfo.h \ + $(SOURCE_DIR)/PeriodicInfo.h $(SOURCE_DIR)/OpenMP.h +@USE_PARALLEL_AMDIS_TRUE@am__objects_1 = \ +@USE_PARALLEL_AMDIS_TRUE@ libamdis_la-ConditionalEstimator.lo \ +@USE_PARALLEL_AMDIS_TRUE@ libamdis_la-ElementFileWriter.lo \ +@USE_PARALLEL_AMDIS_TRUE@ libamdis_la-MeshStructure.lo \ +@USE_PARALLEL_AMDIS_TRUE@ libamdis_la-ParallelProblem.lo \ +@USE_PARALLEL_AMDIS_TRUE@ libamdis_la-ParMetisPartitioner.lo +am_libamdis_la_OBJECTS = $(am__objects_1) \ + libamdis_la-MultiGridPreconWrapper.lo \ + libamdis_la-LagrangeInterpolRestrict.lo \ + libamdis_la-InterpolRestrictMatrix.lo \ + libamdis_la-DOFIndexed.lo libamdis_la-GNUPlotWriter.lo \ + libamdis_la-StlVector.lo libamdis_la-V3Vector.lo \ + libamdis_la-GSSmoother.lo libamdis_la-JacobiSmoother.lo \ + libamdis_la-SparseVector.lo libamdis_la-VertexVector.lo \ + libamdis_la-PeriodicBC.lo libamdis_la-MultiGridSolver.lo \ + libamdis_la-Recovery.lo libamdis_la-RecoveryEstimator.lo \ + libamdis_la-Cholesky.lo libamdis_la-AdaptBase.lo \ + libamdis_la-StandardProblemIteration.lo \ + libamdis_la-ProblemScal.lo libamdis_la-ProblemVec.lo \ + libamdis_la-DualTraverse.lo libamdis_la-ElementData.lo \ + libamdis_la-CreatorMap.lo libamdis_la-ProblemInterpolScal.lo \ + libamdis_la-ProblemInterpolVec.lo libamdis_la-MacroReader.lo \ + libamdis_la-ValueReader.lo libamdis_la-Projection.lo \ + libamdis_la-Assembler.lo libamdis_la-AdaptInfo.lo \ + libamdis_la-Marker.lo libamdis_la-MatrixVector.lo \ + libamdis_la-SurfaceQuadrature.lo libamdis_la-LeafData.lo \ + libamdis_la-BoundaryManager.lo libamdis_la-DirichletBC.lo \ + libamdis_la-RobinBC.lo libamdis_la-MatVecMultiplier.lo \ + libamdis_la-FileWriter.lo libamdis_la-ElInfo.lo \ + libamdis_la-Operator.lo libamdis_la-Mesh.lo \ + libamdis_la-AdaptStationary.lo \ + libamdis_la-AdaptInstationary.lo \ + libamdis_la-DiagonalPreconditioner.lo \ + libamdis_la-ILUPreconditioner.lo \ + libamdis_la-ILUTPreconditioner.lo libamdis_la-DOFVector.lo \ + libamdis_la-Estimator.lo libamdis_la-ProblemInstat.lo \ + libamdis_la-ProblemNonLin.lo libamdis_la-NonLinUpdater.lo \ + libamdis_la-QPsiPhi.lo libamdis_la-BasisFunction.lo \ + libamdis_la-Boundary.lo libamdis_la-CoarseningManager.lo \ + libamdis_la-CoarseningManager1d.lo \ + libamdis_la-CoarseningManager2d.lo \ + libamdis_la-CoarseningManager3d.lo libamdis_la-demangle.lo \ + libamdis_la-DOFAdmin.lo libamdis_la-DOFMatrix.lo \ + libamdis_la-Element.lo libamdis_la-ElInfo1d.lo \ + libamdis_la-ElInfo2d.lo libamdis_la-ElInfo3d.lo \ + libamdis_la-FiniteElemSpace.lo libamdis_la-FixVec.lo \ + libamdis_la-Flag.lo libamdis_la-Global.lo \ + libamdis_la-Lagrange.lo libamdis_la-Line.lo \ + libamdis_la-MacroElement.lo libamdis_la-MacroWriter.lo \ + libamdis_la-Parameters.lo libamdis_la-Parametric.lo \ + libamdis_la-Quadrature.lo libamdis_la-RCNeighbourList.lo \ + libamdis_la-RefinementManager.lo \ + libamdis_la-RefinementManager1d.lo \ + libamdis_la-RefinementManager2d.lo \ + libamdis_la-RefinementManager3d.lo libamdis_la-Tetrahedron.lo \ + libamdis_la-Traverse.lo libamdis_la-Triangle.lo \ + libamdis_la-TecPlotWriter.lo libamdis_la-ValueWriter.lo \ + libamdis_la-MemoryPool.lo libamdis_la-MemoryManager.lo \ + libamdis_la-VtkWriter.lo libamdis_la-DataCollector.lo +libamdis_la_OBJECTS = $(am_libamdis_la_OBJECTS) +libcompositeFEM_la_LIBADD = +am_libcompositeFEM_la_OBJECTS = libcompositeFEM_la-CFE_Integration.lo \ + libcompositeFEM_la-CFE_NormAndErrorFcts.lo \ + libcompositeFEM_la-CompositeFEMMethods.lo \ + libcompositeFEM_la-LevelSetAdaptMesh.lo \ + libcompositeFEM_la-PenaltyOperator.lo \ + libcompositeFEM_la-ElementLevelSet.lo \ + libcompositeFEM_la-CompositeFEMOperator.lo \ + libcompositeFEM_la-SubPolytope.lo \ + libcompositeFEM_la-ScalableQuadrature.lo \ + libcompositeFEM_la-SubElInfo.lo \ + libcompositeFEM_la-SubElementAssembler.lo +libcompositeFEM_la_OBJECTS = $(am_libcompositeFEM_la_OBJECTS) +DEFAULT_INCLUDES = -I. -I$(srcdir) +depcomp = $(SHELL) $(top_srcdir)/depcomp +am__depfiles_maybe = depfiles +CXXCOMPILE = $(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) \ + $(AM_CPPFLAGS) $(CPPFLAGS) $(AM_CXXFLAGS) $(CXXFLAGS) +LTCXXCOMPILE = $(LIBTOOL) --tag=CXX --mode=compile $(CXX) $(DEFS) \ + $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) \ + $(AM_CXXFLAGS) $(CXXFLAGS) +CXXLD = $(CXX) +CXXLINK = $(LIBTOOL) --tag=CXX --mode=link $(CXXLD) $(AM_CXXFLAGS) \ + $(CXXFLAGS) $(AM_LDFLAGS) $(LDFLAGS) -o $@ +COMPILE = $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) \ + $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) +LTCOMPILE = $(LIBTOOL) --tag=CC --mode=compile $(CC) $(DEFS) \ + $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) \ + $(AM_CFLAGS) $(CFLAGS) +CCLD = $(CC) +LINK = $(LIBTOOL) --tag=CC --mode=link $(CCLD) $(AM_CFLAGS) $(CFLAGS) \ + $(AM_LDFLAGS) $(LDFLAGS) -o $@ +SOURCES = $(libamdis_la_SOURCES) $(libcompositeFEM_la_SOURCES) +DIST_SOURCES = $(am__libamdis_la_SOURCES_DIST) \ + $(libcompositeFEM_la_SOURCES) +ETAGS = etags +CTAGS = ctags +DISTFILES = $(DIST_COMMON) $(DIST_SOURCES) $(TEXINFOS) $(EXTRA_DIST) +ACLOCAL = @ACLOCAL@ +AMDEP_FALSE = @AMDEP_FALSE@ +AMDEP_TRUE = @AMDEP_TRUE@ +AMDIS_DEBUG_FALSE = @AMDIS_DEBUG_FALSE@ +AMDIS_DEBUG_TRUE = @AMDIS_DEBUG_TRUE@ +AMDIS_INTEL_FALSE = @AMDIS_INTEL_FALSE@ +AMDIS_INTEL_TRUE = @AMDIS_INTEL_TRUE@ +AMDIS_OPENMP_FALSE = @AMDIS_OPENMP_FALSE@ +AMDIS_OPENMP_TRUE = @AMDIS_OPENMP_TRUE@ +AMTAR = @AMTAR@ +AR = @AR@ +AUTOCONF = @AUTOCONF@ +AUTOHEADER = @AUTOHEADER@ +AUTOMAKE = @AUTOMAKE@ +AWK = @AWK@ +CC = @CC@ +CCDEPMODE = @CCDEPMODE@ +CFLAGS = @CFLAGS@ +CPP = @CPP@ +CPPFLAGS = @CPPFLAGS@ +CXX = @CXX@ +CXXCPP = @CXXCPP@ +CXXDEPMODE = @CXXDEPMODE@ +CXXFLAGS = @CXXFLAGS@ +CYGPATH_W = @CYGPATH_W@ +DEFS = @DEFS@ +DEPDIR = @DEPDIR@ +ECHO = @ECHO@ +ECHO_C = @ECHO_C@ +ECHO_N = @ECHO_N@ +ECHO_T = @ECHO_T@ +EGREP = @EGREP@ +ENABLE_UMFPACK_FALSE = @ENABLE_UMFPACK_FALSE@ +ENABLE_UMFPACK_TRUE = @ENABLE_UMFPACK_TRUE@ +EXEEXT = @EXEEXT@ +F77 = @F77@ +FFLAGS = @FFLAGS@ +INSTALL_DATA = @INSTALL_DATA@ +INSTALL_PROGRAM = @INSTALL_PROGRAM@ +INSTALL_SCRIPT = @INSTALL_SCRIPT@ +INSTALL_STRIP_PROGRAM = @INSTALL_STRIP_PROGRAM@ +LDFLAGS = @LDFLAGS@ +LIBOBJS = @LIBOBJS@ +LIBS = @LIBS@ +LIBTOOL = @LIBTOOL@ +LN_S = @LN_S@ +LTLIBOBJS = @LTLIBOBJS@ +MAINT = @MAINT@ +MAINTAINER_MODE_FALSE = @MAINTAINER_MODE_FALSE@ +MAINTAINER_MODE_TRUE = @MAINTAINER_MODE_TRUE@ +MAKEINFO = @MAKEINFO@ +MPI_DIR = @MPI_DIR@ +OBJEXT = @OBJEXT@ +OPENMP_FLAG = @OPENMP_FLAG@ +PACKAGE = @PACKAGE@ +PACKAGE_BUGREPORT = @PACKAGE_BUGREPORT@ +PACKAGE_NAME = @PACKAGE_NAME@ +PACKAGE_STRING = @PACKAGE_STRING@ +PACKAGE_TARNAME = @PACKAGE_TARNAME@ +PACKAGE_VERSION = @PACKAGE_VERSION@ +PATH_SEPARATOR = @PATH_SEPARATOR@ +RANLIB = @RANLIB@ +SED = @SED@ +SET_MAKE = @SET_MAKE@ +SHELL = @SHELL@ +STRIP = @STRIP@ +USE_PARALLEL_AMDIS_FALSE = @USE_PARALLEL_AMDIS_FALSE@ +USE_PARALLEL_AMDIS_TRUE = @USE_PARALLEL_AMDIS_TRUE@ +VERSION = @VERSION@ +ac_ct_AR = @ac_ct_AR@ +ac_ct_CC = @ac_ct_CC@ +ac_ct_CXX = @ac_ct_CXX@ +ac_ct_F77 = @ac_ct_F77@ +ac_ct_RANLIB = @ac_ct_RANLIB@ +ac_ct_STRIP = @ac_ct_STRIP@ +am__fastdepCC_FALSE = @am__fastdepCC_FALSE@ +am__fastdepCC_TRUE = @am__fastdepCC_TRUE@ +am__fastdepCXX_FALSE = @am__fastdepCXX_FALSE@ +am__fastdepCXX_TRUE = @am__fastdepCXX_TRUE@ +am__include = @am__include@ +am__leading_dot = @am__leading_dot@ +am__quote = @am__quote@ +am__tar = @am__tar@ +am__untar = @am__untar@ +bindir = @bindir@ +build = @build@ +build_alias = @build_alias@ +build_cpu = @build_cpu@ +build_os = @build_os@ +build_vendor = @build_vendor@ +datadir = @datadir@ +exec_prefix = @exec_prefix@ +host = @host@ +host_alias = @host_alias@ +host_cpu = @host_cpu@ +host_os = @host_os@ +host_vendor = @host_vendor@ +includedir = @includedir@ +infodir = @infodir@ +install_sh = @install_sh@ +libdir = @libdir@ +libexecdir = @libexecdir@ +localstatedir = @localstatedir@ +mandir = @mandir@ +mkdir_p = @mkdir_p@ +oldincludedir = @oldincludedir@ +prefix = @prefix@ +program_transform_name = @program_transform_name@ +sbindir = @sbindir@ +sharedstatedir = @sharedstatedir@ +sysconfdir = @sysconfdir@ +target_alias = @target_alias@ +lib_LTLIBRARIES = libamdis.la libcompositeFEM.la +SOURCE_DIR = ../src +LIB_DIR = ../lib +PARALLEL_DIR = $(SOURCE_DIR) +PARMETIS_DIR = ../lib/ParMetis-3.1 +AMDIS_INCLUDES = -I$(SOURCE_DIR) $(am__append_2) +@USE_PARALLEL_AMDIS_FALSE@PARALLEL_AMDIS_SOURCES = +@USE_PARALLEL_AMDIS_TRUE@PARALLEL_AMDIS_SOURCES = \ +@USE_PARALLEL_AMDIS_TRUE@ $(PARALLEL_DIR)/ConditionalEstimator.h $(PARALLEL_DIR)/ConditionalEstimator.cc \ +@USE_PARALLEL_AMDIS_TRUE@ $(PARALLEL_DIR)/ConditionalMarker.h \ +@USE_PARALLEL_AMDIS_TRUE@ $(PARALLEL_DIR)/ElementFileWriter.h $(PARALLEL_DIR)/ElementFileWriter.cc \ +@USE_PARALLEL_AMDIS_TRUE@ $(PARALLEL_DIR)/MeshStructure.h $(PARALLEL_DIR)/MeshStructure.cc \ +@USE_PARALLEL_AMDIS_TRUE@ $(PARALLEL_DIR)/MeshStructure_ED.h \ +@USE_PARALLEL_AMDIS_TRUE@ $(PARALLEL_DIR)/ParallelError.h $(PARALLEL_DIR)/ParallelError.hh \ +@USE_PARALLEL_AMDIS_TRUE@ $(PARALLEL_DIR)/ParallelProblem.h $(PARALLEL_DIR)/ParallelProblem.cc \ +@USE_PARALLEL_AMDIS_TRUE@ $(PARALLEL_DIR)/ParMetisPartitioner.h $(PARALLEL_DIR)/ParMetisPartitioner.cc \ +@USE_PARALLEL_AMDIS_TRUE@ $(PARALLEL_DIR)/PartitionElementData.h + +@USE_PARALLEL_AMDIS_FALSE@PARALLEL_INCLUDES = +@USE_PARALLEL_AMDIS_TRUE@PARALLEL_INCLUDES = -I$(MPI_DIR)/include -I$(PARMETIS_DIR) +libamdis_la_CXXFLAGS = $(am__append_1) $(am__append_3) $(am__append_4) +INCLUDES = $(AMDIS_INCLUDES) $(PARALLEL_INCLUDES) +libamdis_la_SOURCES = \ +$(PARALLEL_AMDIS_SOURCES) \ +$(SOURCE_DIR)/MultiGridPreconWrapper.h $(SOURCE_DIR)/MultiGridPreconWrapper.cc \ +$(SOURCE_DIR)/LagrangeInterpolRestrict.h $(SOURCE_DIR)/LagrangeInterpolRestrict.cc \ +$(SOURCE_DIR)/BiCGStab.h $(SOURCE_DIR)/BiCGStab.hh\ +$(SOURCE_DIR)/BiCGStab2.h $(SOURCE_DIR)/BiCGStab2.hh\ +$(SOURCE_DIR)/InterpolRestrictMatrix.h $(SOURCE_DIR)/InterpolRestrictMatrix.cc \ +$(SOURCE_DIR)/DOFIndexed.h $(SOURCE_DIR)/DOFIndexed.cc \ +$(SOURCE_DIR)/GNUPlotWriter.h $(SOURCE_DIR)/GNUPlotWriter.cc \ +$(SOURCE_DIR)/SmootherBase.h \ +$(SOURCE_DIR)/StlVector.h $(SOURCE_DIR)/StlVector.cc \ +$(SOURCE_DIR)/V3Vector.h $(SOURCE_DIR)/V3Vector.cc \ +$(SOURCE_DIR)/GSSMoother.h $(SOURCE_DIR)/GSSmoother.cc \ +$(SOURCE_DIR)/JacobiSMoother.h $(SOURCE_DIR)/JacobiSmoother.cc \ +$(SOURCE_DIR)/SparseVector.h $(SOURCE_DIR)/SparseVector.hh $(SOURCE_DIR)/SparseVector.cc \ +$(SOURCE_DIR)/VertexVector.h $(SOURCE_DIR)/VertexVector.cc \ +$(SOURCE_DIR)/PeriodicBC.h $(SOURCE_DIR)/PeriodicBC.cc \ +$(SOURCE_DIR)/MultiGridSolverBase.h $(SOURCE_DIR)/MultiGridSolverBase.hh \ +$(SOURCE_DIR)/MultiGridSolver.h $(SOURCE_DIR)/MultiGridSolver.cc \ +$(SOURCE_DIR)/Recovery.h $(SOURCE_DIR)/Recovery.cc \ +$(SOURCE_DIR)/RecoveryEstimator.h $(SOURCE_DIR)/RecoveryEstimator.cc \ +$(SOURCE_DIR)/Cholesky.h $(SOURCE_DIR)/Cholesky.cc \ +$(SOURCE_DIR)/AdaptBase.h $(SOURCE_DIR)/AdaptBase.cc \ +$(SOURCE_DIR)/ProblemIterationInterface.h $(SOURCE_DIR)/StandardProblemIteration.h $(SOURCE_DIR)/StandardProblemIteration.cc \ +$(SOURCE_DIR)/ProblemScal.h $(SOURCE_DIR)/ProblemScal.cc \ +$(SOURCE_DIR)/ProblemVec.h $(SOURCE_DIR)/ProblemVec.cc \ +$(SOURCE_DIR)/DualTraverse.h $(SOURCE_DIR)/DualTraverse.cc \ +$(SOURCE_DIR)/ElementPartition_ED.h $(SOURCE_DIR)/SurfacePartition_ED.h \ +$(SOURCE_DIR)/ElementData.h $(SOURCE_DIR)/ElementData.cc \ +$(SOURCE_DIR)/CreatorMap.h $(SOURCE_DIR)/CreatorMap.cc $(SOURCE_DIR)/CreatorInterface.h \ +$(SOURCE_DIR)/ElementFunction.h \ +$(SOURCE_DIR)/ProblemInterpolScal.h $(SOURCE_DIR)/ProblemInterpolScal.cc \ +$(SOURCE_DIR)/ProblemInterpolVec.h $(SOURCE_DIR)/ProblemInterpolVec.cc \ +$(SOURCE_DIR)/Serializable.h $(SOURCE_DIR)/BallProject.h $(SOURCE_DIR)/CylinderProject.h \ +$(SOURCE_DIR)/MacroReader.h $(SOURCE_DIR)/MacroReader.cc \ +$(SOURCE_DIR)/ValueReader.h $(SOURCE_DIR)/ValueReader.cc \ +$(SOURCE_DIR)/Projection.h $(SOURCE_DIR)/Projection.cc \ +$(SOURCE_DIR)/Assembler.h $(SOURCE_DIR)/Assembler.cc \ +$(SOURCE_DIR)/AdaptInfo.h $(SOURCE_DIR)/AdaptInfo.cc \ +$(SOURCE_DIR)/Marker.h $(SOURCE_DIR)/Marker.cc \ +$(SOURCE_DIR)/SystemVector.h \ +$(SOURCE_DIR)/MatrixVector.h $(SOURCE_DIR)/MatrixVector.cc \ +$(SOURCE_DIR)/SurfaceQuadrature.h $(SOURCE_DIR)/SurfaceQuadrature.cc \ +$(SOURCE_DIR)/LeafData.h $(SOURCE_DIR)/LeafData.cc \ +$(SOURCE_DIR)/BoundaryManager.h $(SOURCE_DIR)/BoundaryManager.cc $(SOURCE_DIR)/BoundaryCondition.h \ +$(SOURCE_DIR)/DirichletBC.h $(SOURCE_DIR)/DirichletBC.cc \ +$(SOURCE_DIR)/RobinBC.h $(SOURCE_DIR)/RobinBC.cc \ +$(SOURCE_DIR)/AbstractFunction.h \ +$(SOURCE_DIR)/ProblemStatBase.h \ +$(SOURCE_DIR)/MatVecMultiplier.cc \ +$(SOURCE_DIR)/DOFContainer.h \ +$(SOURCE_DIR)/FileWriter.h $(SOURCE_DIR)/FileWriter.hh $(SOURCE_DIR)/FileWriter.cc \ +$(SOURCE_DIR)/ElInfo.cc \ +$(SOURCE_DIR)/MatVecMultiplier.h \ +$(SOURCE_DIR)/Operator.h $(SOURCE_DIR)/Operator.cc \ +$(SOURCE_DIR)/Mesh.cc \ +$(SOURCE_DIR)/AMDiS.h \ +$(SOURCE_DIR)/AdaptStationary.h $(SOURCE_DIR)/AdaptStationary.cc \ +$(SOURCE_DIR)/AdaptInstationary.h $(SOURCE_DIR)/AdaptInstationary.cc \ +$(SOURCE_DIR)/QPsiPhi.h \ +$(SOURCE_DIR)/BasisFunction.h \ +$(SOURCE_DIR)/BiCGSolver.h $(SOURCE_DIR)/BiCGSolver.hh \ +$(SOURCE_DIR)/Boundary.h \ +$(SOURCE_DIR)/CGSolver.h $(SOURCE_DIR)/CGSolver.hh \ +$(SOURCE_DIR)/CoarseningManager.h \ +$(SOURCE_DIR)/CoarseningManager1d.h $(SOURCE_DIR)/CoarseningManager2d.h $(SOURCE_DIR)/CoarseningManager3d.h \ +$(SOURCE_DIR)/demangle.h \ +$(SOURCE_DIR)/DiagonalPreconditioner.h $(SOURCE_DIR)/DiagonalPreconditioner.cc \ +$(SOURCE_DIR)/ILUPreconditioner.h $(SOURCE_DIR)/ILUPreconditioner.cc \ +$(SOURCE_DIR)/ILUTPreconditioner.h $(SOURCE_DIR)/ILUTPreconditioner.cc \ +$(SOURCE_DIR)/DOFAdmin.h $(SOURCE_DIR)/DOFIterator.h $(SOURCE_DIR)/DOFMatrix.h $(SOURCE_DIR)/DOFVector.h $(SOURCE_DIR)/DOFVector.hh $(SOURCE_DIR)/DOFVector.cc $(SOURCE_DIR)/Element.h $(SOURCE_DIR)/ElementConnection.h \ +$(SOURCE_DIR)/ElInfo.h $(SOURCE_DIR)/ElInfo1d.h $(SOURCE_DIR)/ElInfo2d.h $(SOURCE_DIR)/ElInfo3d.h $(SOURCE_DIR)/Error.h \ +$(SOURCE_DIR)/Error.hh $(SOURCE_DIR)/Estimator.h $(SOURCE_DIR)/Estimator.cc $(SOURCE_DIR)/FiniteElemSpace.h $(SOURCE_DIR)/FixVec.h $(SOURCE_DIR)/FixVec.hh $(SOURCE_DIR)/FixVecConvert.h $(SOURCE_DIR)/Flag.h $(SOURCE_DIR)/Global.h \ +$(SOURCE_DIR)/GMResSolver.h \ $(SOURCE_DIR)/GMResSolver.hh \ +$(SOURCE_DIR)/GMResSolver2.h \ $(SOURCE_DIR)/GMResSolver2.hh \ +$(SOURCE_DIR)/TFQMR.h \ $(SOURCE_DIR)/TFQMR.hh \ +$(SOURCE_DIR)/VecSymSolver.h \ $(SOURCE_DIR)/VecSymSolver.hh \ +$(SOURCE_DIR)/UmfPackSolver.h \ $(SOURCE_DIR)/UmfPackSolver.hh \ +$(SOURCE_DIR)/Lagrange.h $(SOURCE_DIR)/Line.h \ +$(SOURCE_DIR)/MacroElement.h $(SOURCE_DIR)/MacroWriter.h $(SOURCE_DIR)/Markings.h $(SOURCE_DIR)/Markings.hh $(SOURCE_DIR)/MemoryManager.h $(SOURCE_DIR)/Mesh.h $(SOURCE_DIR)/ODirSolver.h $(SOURCE_DIR)/ODirSolver.hh $(SOURCE_DIR)/OEMSolver.h \ +$(SOURCE_DIR)/OEMSolver.hh $(SOURCE_DIR)/OResSolver.h $(SOURCE_DIR)/OResSolver.hh $(SOURCE_DIR)/Parameters.h $(SOURCE_DIR)/Parametric.h $(SOURCE_DIR)/Preconditioner.h \ +$(SOURCE_DIR)/Quadrature.h \ +$(SOURCE_DIR)/RCNeighbourList.h $(SOURCE_DIRe)/RefinementManager.h $(SOURCE_DIR)/RefinementManager1d.h $(SOURCE_DIR)/RefinementManager2d.h $(SOURCE_DIR)/RefinementManager3d.h $(SOURCE_DIR)/TecPlotWriter.h $(SOURCE_DIR)/TecPlotWriter.hh $(SOURCE_DIR)/Tetrahedron.h \ +$(SOURCE_DIR)/Traverse.h $(SOURCE_DIR)/Triangle.h $(SOURCE_DIR)/NonLinSolver.h $(SOURCE_DIR)/NonLinSolver.hh $(SOURCE_DIR)/ProblemInstat.h $(SOURCE_DIR)/ProblemInstat.cc $(SOURCE_DIR)/ProblemTimeInterface.h $(SOURCE_DIR)/ProblemNonLin.h $(SOURCE_DIR)/ProblemNonLin.cc \ +$(SOURCE_DIR)/NonLinUpdater.h $(SOURCE_DIR)/NonLinUpdater.cc \ +$(SOURCE_DIR)/Newton.h $(SOURCE_DIR)/Newton.hh $(SOURCE_DIR)/NewtonFS.h $(SOURCE_DIR)/NewtonFS.hh $(SOURCE_DIR)/GridWriter.h $(SOURCE_DIR)/GridWriter.hh $(SOURCE_DIR)/ValueWriter.h $(SOURCE_DIR)/QPsiPhi.cc $(SOURCE_DIR)/BasisFunction.cc $(SOURCE_DIR)/Boundary.cc \ +$(SOURCE_DIR)/CoarseningManager.cc $(SOURCE_DIR)/CoarseningManager1d.cc $(SOURCE_DIR)/CoarseningManager2d.cc $(SOURCE_DIR)/CoarseningManager3d.cc $(SOURCE_DIR)/demangle.cc $(SOURCE_DIR)/DOFAdmin.cc $(SOURCE_DIR)/DOFMatrix.cc $(SOURCE_DIR)/Element.cc $(SOURCE_DIR)/ElInfo1d.cc \ +$(SOURCE_DIR)/ElInfo2d.cc $(SOURCE_DIR)/ElInfo3d.cc $(SOURCE_DIR)/FiniteElemSpace.cc $(SOURCE_DIR)/FixVec.cc $(SOURCE_DIR)/Flag.cc $(SOURCE_DIR)/Global.cc $(SOURCE_DIR)/Lagrange.cc $(SOURCE_DIR)/Line.cc $(SOURCE_DIR)/MacroElement.cc $(SOURCE_DIR)/MacroWriter.cc $(SOURCE_DIR)/Parameters.cc \ +$(SOURCE_DIR)/Parametric.cc $(SOURCE_DIR)/Quadrature.cc $(SOURCE_DIR)/RCNeighbourList.cc $(SOURCE_DIR)/RefinementManager.cc $(SOURCE_DIR)/RefinementManager1d.cc $(SOURCE_DIR)/RefinementManager2d.cc $(SOURCE_DIR)/RefinementManager3d.cc $(SOURCE_DIR)/Tetrahedron.cc $(SOURCE_DIR)/Traverse.cc \ +$(SOURCE_DIR)/Triangle.cc $(SOURCE_DIR)/TecPlotWriter.cc $(SOURCE_DIR)/ValueWriter.cc $(SOURCE_DIR)/MemoryPool.h $(SOURCE_DIR)/MemoryPool.cc $(SOURCE_DIR)/MemoryManager.cc \ +$(SOURCE_DIR)/VtkWriter.h $(SOURCE_DIR)/VtkWriter.cc \ +$(SOURCE_DIR)/DataCollector.h $(SOURCE_DIR)/DataCollector.cc \ +$(SOURCE_DIR)/ElementInfo.h $(SOURCE_DIR)/VertexInfo.h $(SOURCE_DIR)/PeriodicInfo.h \ +$(SOURCE_DIR)/OpenMP.h + +COMPOSITE_SOURCE_DIR = ../compositeFEM/src +@AMDIS_DEBUG_FALSE@libcompositeFEM_la_CXXFLAGS = -O2 -Wall -DDEBUG=0 -I$(SOURCE_DIR) +@AMDIS_DEBUG_TRUE@libcompositeFEM_la_CXXFLAGS = -g -O0 -Wall -DDEBUG=1 -I$(SOURCE_DIR) +libcompositeFEM_la_SOURCES = $(COMPOSITE_SOURCE_DIR)/CFE_Integration.h \ +$(COMPOSITE_SOURCE_DIR)/CFE_Integration.cc \ +$(COMPOSITE_SOURCE_DIR)/CFE_NormAndErrorFcts.h \ +$(COMPOSITE_SOURCE_DIR)/CFE_NormAndErrorFcts.cc \ +$(COMPOSITE_SOURCE_DIR)/CompositeFEMMethods.h \ +$(COMPOSITE_SOURCE_DIR)/CompositeFEMMethods.cc \ +$(COMPOSITE_SOURCE_DIR)/LevelSetAdaptMesh.h \ +$(COMPOSITE_SOURCE_DIR)/LevelSetAdaptMesh.cc \ +$(COMPOSITE_SOURCE_DIR)/PenaltyOperator.h \ +$(COMPOSITE_SOURCE_DIR)/PenaltyOperator.cc \ +$(COMPOSITE_SOURCE_DIR)/ElementLevelSet.h \ +$(COMPOSITE_SOURCE_DIR)/ElementLevelSet.cc \ +$(COMPOSITE_SOURCE_DIR)/CompositeFEMOperator.h \ +$(COMPOSITE_SOURCE_DIR)/CompositeFEMOperator.cc \ +$(COMPOSITE_SOURCE_DIR)/SubPolytope.h $(COMPOSITE_SOURCE_DIR)/SubPolytope.cc \ +$(COMPOSITE_SOURCE_DIR)/ScalableQuadrature.h \ +$(COMPOSITE_SOURCE_DIR)/ScalableQuadrature.cc \ +$(COMPOSITE_SOURCE_DIR)/SubElInfo.h $(COMPOSITE_SOURCE_DIR)/SubElInfo.cc \ +$(COMPOSITE_SOURCE_DIR)/SubElementAssembler.h \ +$(COMPOSITE_SOURCE_DIR)/SubElementAssembler.cc \ +$(COMPOSITE_SOURCE_DIR)/TranslateLsFct.h + +all: all-am + +.SUFFIXES: +.SUFFIXES: .cc .lo .o .obj +$(srcdir)/Makefile.in: @MAINTAINER_MODE_TRUE@ $(srcdir)/Makefile.am $(am__configure_deps) + @for dep in $?; do \ + case '$(am__configure_deps)' in \ + *$$dep*) \ + cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh \ + && exit 0; \ + exit 1;; \ + esac; \ + done; \ + echo ' cd $(top_srcdir) && $(AUTOMAKE) --gnu bin/Makefile'; \ + cd $(top_srcdir) && \ + $(AUTOMAKE) --gnu bin/Makefile +.PRECIOUS: Makefile +Makefile: $(srcdir)/Makefile.in $(top_builddir)/config.status + @case '$?' in \ + *config.status*) \ + cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh;; \ + *) \ + echo ' cd $(top_builddir) && $(SHELL) ./config.status $(subdir)/$@ $(am__depfiles_maybe)'; \ + cd $(top_builddir) && $(SHELL) ./config.status $(subdir)/$@ $(am__depfiles_maybe);; \ + esac; + +$(top_builddir)/config.status: $(top_srcdir)/configure $(CONFIG_STATUS_DEPENDENCIES) + cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh + +$(top_srcdir)/configure: @MAINTAINER_MODE_TRUE@ $(am__configure_deps) + cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh +$(ACLOCAL_M4): @MAINTAINER_MODE_TRUE@ $(am__aclocal_m4_deps) + cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh +install-libLTLIBRARIES: $(lib_LTLIBRARIES) + @$(NORMAL_INSTALL) + test -z "$(libdir)" || $(mkdir_p) "$(DESTDIR)$(libdir)" + @list='$(lib_LTLIBRARIES)'; for p in $$list; do \ + if test -f $$p; then \ + f=$(am__strip_dir) \ + echo " $(LIBTOOL) --mode=install $(libLTLIBRARIES_INSTALL) $(INSTALL_STRIP_FLAG) '$$p' '$(DESTDIR)$(libdir)/$$f'"; \ + $(LIBTOOL) --mode=install $(libLTLIBRARIES_INSTALL) $(INSTALL_STRIP_FLAG) "$$p" "$(DESTDIR)$(libdir)/$$f"; \ + else :; fi; \ + done + +uninstall-libLTLIBRARIES: + @$(NORMAL_UNINSTALL) + @set -x; list='$(lib_LTLIBRARIES)'; for p in $$list; do \ + p=$(am__strip_dir) \ + echo " $(LIBTOOL) --mode=uninstall rm -f '$(DESTDIR)$(libdir)/$$p'"; \ + $(LIBTOOL) --mode=uninstall rm -f "$(DESTDIR)$(libdir)/$$p"; \ + done + +clean-libLTLIBRARIES: + -test -z "$(lib_LTLIBRARIES)" || rm -f $(lib_LTLIBRARIES) + @list='$(lib_LTLIBRARIES)'; for p in $$list; do \ + dir="`echo $$p | sed -e 's|/[^/]*$$||'`"; \ + test "$$dir" != "$$p" || dir=.; \ + echo "rm -f \"$${dir}/so_locations\""; \ + rm -f "$${dir}/so_locations"; \ + done +libamdis.la: $(libamdis_la_OBJECTS) $(libamdis_la_DEPENDENCIES) + $(CXXLINK) -rpath $(libdir) $(libamdis_la_LDFLAGS) $(libamdis_la_OBJECTS) $(libamdis_la_LIBADD) $(LIBS) +libcompositeFEM.la: $(libcompositeFEM_la_OBJECTS) $(libcompositeFEM_la_DEPENDENCIES) + $(CXXLINK) -rpath $(libdir) $(libcompositeFEM_la_LDFLAGS) $(libcompositeFEM_la_OBJECTS) $(libcompositeFEM_la_LIBADD) $(LIBS) + +mostlyclean-compile: + -rm -f *.$(OBJEXT) + +distclean-compile: + -rm -f *.tab.c + +@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/libamdis_la-AdaptBase.Plo@am__quote@ +@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/libamdis_la-AdaptInfo.Plo@am__quote@ +@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/libamdis_la-AdaptInstationary.Plo@am__quote@ +@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/libamdis_la-AdaptStationary.Plo@am__quote@ +@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/libamdis_la-Assembler.Plo@am__quote@ +@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/libamdis_la-BasisFunction.Plo@am__quote@ +@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/libamdis_la-Boundary.Plo@am__quote@ +@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/libamdis_la-BoundaryManager.Plo@am__quote@ +@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/libamdis_la-Cholesky.Plo@am__quote@ +@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/libamdis_la-CoarseningManager.Plo@am__quote@ +@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/libamdis_la-CoarseningManager1d.Plo@am__quote@ +@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/libamdis_la-CoarseningManager2d.Plo@am__quote@ +@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/libamdis_la-CoarseningManager3d.Plo@am__quote@ +@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/libamdis_la-ConditionalEstimator.Plo@am__quote@ +@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/libamdis_la-CreatorMap.Plo@am__quote@ +@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/libamdis_la-DOFAdmin.Plo@am__quote@ +@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/libamdis_la-DOFIndexed.Plo@am__quote@ +@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/libamdis_la-DOFMatrix.Plo@am__quote@ +@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/libamdis_la-DOFVector.Plo@am__quote@ +@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/libamdis_la-DataCollector.Plo@am__quote@ +@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/libamdis_la-DiagonalPreconditioner.Plo@am__quote@ +@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/libamdis_la-DirichletBC.Plo@am__quote@ +@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/libamdis_la-DualTraverse.Plo@am__quote@ +@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/libamdis_la-ElInfo.Plo@am__quote@ +@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/libamdis_la-ElInfo1d.Plo@am__quote@ +@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/libamdis_la-ElInfo2d.Plo@am__quote@ +@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/libamdis_la-ElInfo3d.Plo@am__quote@ +@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/libamdis_la-Element.Plo@am__quote@ +@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/libamdis_la-ElementData.Plo@am__quote@ +@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/libamdis_la-ElementFileWriter.Plo@am__quote@ +@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/libamdis_la-Estimator.Plo@am__quote@ +@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/libamdis_la-FileWriter.Plo@am__quote@ +@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/libamdis_la-FiniteElemSpace.Plo@am__quote@ +@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/libamdis_la-FixVec.Plo@am__quote@ +@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/libamdis_la-Flag.Plo@am__quote@ +@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/libamdis_la-GNUPlotWriter.Plo@am__quote@ +@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/libamdis_la-GSSmoother.Plo@am__quote@ +@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/libamdis_la-Global.Plo@am__quote@ +@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/libamdis_la-ILUPreconditioner.Plo@am__quote@ +@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/libamdis_la-ILUTPreconditioner.Plo@am__quote@ +@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/libamdis_la-InterpolRestrictMatrix.Plo@am__quote@ +@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/libamdis_la-JacobiSmoother.Plo@am__quote@ +@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/libamdis_la-Lagrange.Plo@am__quote@ +@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/libamdis_la-LagrangeInterpolRestrict.Plo@am__quote@ +@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/libamdis_la-LeafData.Plo@am__quote@ +@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/libamdis_la-Line.Plo@am__quote@ +@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/libamdis_la-MacroElement.Plo@am__quote@ +@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/libamdis_la-MacroReader.Plo@am__quote@ +@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/libamdis_la-MacroWriter.Plo@am__quote@ +@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/libamdis_la-Marker.Plo@am__quote@ +@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/libamdis_la-MatVecMultiplier.Plo@am__quote@ +@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/libamdis_la-MatrixVector.Plo@am__quote@ +@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/libamdis_la-MemoryManager.Plo@am__quote@ +@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/libamdis_la-MemoryPool.Plo@am__quote@ +@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/libamdis_la-Mesh.Plo@am__quote@ +@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/libamdis_la-MeshStructure.Plo@am__quote@ +@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/libamdis_la-MultiGridPreconWrapper.Plo@am__quote@ +@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/libamdis_la-MultiGridSolver.Plo@am__quote@ +@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/libamdis_la-NonLinUpdater.Plo@am__quote@ +@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/libamdis_la-Operator.Plo@am__quote@ +@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/libamdis_la-ParMetisPartitioner.Plo@am__quote@ +@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/libamdis_la-ParallelProblem.Plo@am__quote@ +@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/libamdis_la-Parameters.Plo@am__quote@ +@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/libamdis_la-Parametric.Plo@am__quote@ +@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/libamdis_la-PeriodicBC.Plo@am__quote@ +@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/libamdis_la-ProblemInstat.Plo@am__quote@ +@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/libamdis_la-ProblemInterpolScal.Plo@am__quote@ +@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/libamdis_la-ProblemInterpolVec.Plo@am__quote@ +@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/libamdis_la-ProblemNonLin.Plo@am__quote@ +@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/libamdis_la-ProblemScal.Plo@am__quote@ +@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/libamdis_la-ProblemVec.Plo@am__quote@ +@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/libamdis_la-Projection.Plo@am__quote@ +@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/libamdis_la-QPsiPhi.Plo@am__quote@ +@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/libamdis_la-Quadrature.Plo@am__quote@ +@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/libamdis_la-RCNeighbourList.Plo@am__quote@ +@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/libamdis_la-Recovery.Plo@am__quote@ +@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/libamdis_la-RecoveryEstimator.Plo@am__quote@ +@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/libamdis_la-RefinementManager.Plo@am__quote@ +@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/libamdis_la-RefinementManager1d.Plo@am__quote@ +@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/libamdis_la-RefinementManager2d.Plo@am__quote@ +@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/libamdis_la-RefinementManager3d.Plo@am__quote@ +@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/libamdis_la-RobinBC.Plo@am__quote@ +@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/libamdis_la-SparseVector.Plo@am__quote@ +@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/libamdis_la-StandardProblemIteration.Plo@am__quote@ +@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/libamdis_la-StlVector.Plo@am__quote@ +@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/libamdis_la-SurfaceQuadrature.Plo@am__quote@ +@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/libamdis_la-TecPlotWriter.Plo@am__quote@ +@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/libamdis_la-Tetrahedron.Plo@am__quote@ +@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/libamdis_la-Traverse.Plo@am__quote@ +@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/libamdis_la-Triangle.Plo@am__quote@ +@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/libamdis_la-V3Vector.Plo@am__quote@ +@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/libamdis_la-ValueReader.Plo@am__quote@ +@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/libamdis_la-ValueWriter.Plo@am__quote@ +@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/libamdis_la-VertexVector.Plo@am__quote@ +@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/libamdis_la-VtkWriter.Plo@am__quote@ +@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/libamdis_la-demangle.Plo@am__quote@ +@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/libcompositeFEM_la-CFE_Integration.Plo@am__quote@ +@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/libcompositeFEM_la-CFE_NormAndErrorFcts.Plo@am__quote@ +@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/libcompositeFEM_la-CompositeFEMMethods.Plo@am__quote@ +@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/libcompositeFEM_la-CompositeFEMOperator.Plo@am__quote@ +@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/libcompositeFEM_la-ElementLevelSet.Plo@am__quote@ +@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/libcompositeFEM_la-LevelSetAdaptMesh.Plo@am__quote@ +@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/libcompositeFEM_la-PenaltyOperator.Plo@am__quote@ +@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/libcompositeFEM_la-ScalableQuadrature.Plo@am__quote@ +@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/libcompositeFEM_la-SubElInfo.Plo@am__quote@ +@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/libcompositeFEM_la-SubElementAssembler.Plo@am__quote@ +@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/libcompositeFEM_la-SubPolytope.Plo@am__quote@ + +.cc.o: +@am__fastdepCXX_TRUE@ if $(CXXCOMPILE) -MT $@ -MD -MP -MF "$(DEPDIR)/$*.Tpo" -c -o $@ $<; \ +@am__fastdepCXX_TRUE@ then mv -f "$(DEPDIR)/$*.Tpo" "$(DEPDIR)/$*.Po"; else rm -f "$(DEPDIR)/$*.Tpo"; exit 1; fi +@AMDEP_TRUE@@am__fastdepCXX_FALSE@ source='$<' object='$@' libtool=no @AMDEPBACKSLASH@ +@AMDEP_TRUE@@am__fastdepCXX_FALSE@ DEPDIR=$(DEPDIR) $(CXXDEPMODE) $(depcomp) @AMDEPBACKSLASH@ +@am__fastdepCXX_FALSE@ $(CXXCOMPILE) -c -o $@ $< + +.cc.obj: +@am__fastdepCXX_TRUE@ if $(CXXCOMPILE) -MT $@ -MD -MP -MF "$(DEPDIR)/$*.Tpo" -c -o $@ `$(CYGPATH_W) '$<'`; \ +@am__fastdepCXX_TRUE@ then mv -f "$(DEPDIR)/$*.Tpo" "$(DEPDIR)/$*.Po"; else rm -f "$(DEPDIR)/$*.Tpo"; exit 1; fi +@AMDEP_TRUE@@am__fastdepCXX_FALSE@ source='$<' object='$@' libtool=no @AMDEPBACKSLASH@ +@AMDEP_TRUE@@am__fastdepCXX_FALSE@ DEPDIR=$(DEPDIR) $(CXXDEPMODE) $(depcomp) @AMDEPBACKSLASH@ +@am__fastdepCXX_FALSE@ $(CXXCOMPILE) -c -o $@ `$(CYGPATH_W) '$<'` + +.cc.lo: +@am__fastdepCXX_TRUE@ if $(LTCXXCOMPILE) -MT $@ -MD -MP -MF "$(DEPDIR)/$*.Tpo" -c -o $@ $<; \ +@am__fastdepCXX_TRUE@ then mv -f "$(DEPDIR)/$*.Tpo" "$(DEPDIR)/$*.Plo"; else rm -f "$(DEPDIR)/$*.Tpo"; exit 1; fi +@AMDEP_TRUE@@am__fastdepCXX_FALSE@ source='$<' object='$@' libtool=yes @AMDEPBACKSLASH@ +@AMDEP_TRUE@@am__fastdepCXX_FALSE@ DEPDIR=$(DEPDIR) $(CXXDEPMODE) $(depcomp) @AMDEPBACKSLASH@ +@am__fastdepCXX_FALSE@ $(LTCXXCOMPILE) -c -o $@ $< + +libamdis_la-ConditionalEstimator.lo: $(PARALLEL_DIR)/ConditionalEstimator.cc +@am__fastdepCXX_TRUE@ if $(LIBTOOL) --tag=CXX --mode=compile $(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(libamdis_la_CXXFLAGS) $(CXXFLAGS) -MT libamdis_la-ConditionalEstimator.lo -MD -MP -MF "$(DEPDIR)/libamdis_la-ConditionalEstimator.Tpo" -c -o libamdis_la-ConditionalEstimator.lo `test -f '$(PARALLEL_DIR)/ConditionalEstimator.cc' || echo '$(srcdir)/'`$(PARALLEL_DIR)/ConditionalEstimator.cc; \ +@am__fastdepCXX_TRUE@ then mv -f "$(DEPDIR)/libamdis_la-ConditionalEstimator.Tpo" "$(DEPDIR)/libamdis_la-ConditionalEstimator.Plo"; else rm -f "$(DEPDIR)/libamdis_la-ConditionalEstimator.Tpo"; exit 1; fi +@AMDEP_TRUE@@am__fastdepCXX_FALSE@ source='$(PARALLEL_DIR)/ConditionalEstimator.cc' object='libamdis_la-ConditionalEstimator.lo' libtool=yes @AMDEPBACKSLASH@ +@AMDEP_TRUE@@am__fastdepCXX_FALSE@ DEPDIR=$(DEPDIR) $(CXXDEPMODE) $(depcomp) @AMDEPBACKSLASH@ +@am__fastdepCXX_FALSE@ $(LIBTOOL) --tag=CXX --mode=compile $(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(libamdis_la_CXXFLAGS) $(CXXFLAGS) -c -o libamdis_la-ConditionalEstimator.lo `test -f '$(PARALLEL_DIR)/ConditionalEstimator.cc' || echo '$(srcdir)/'`$(PARALLEL_DIR)/ConditionalEstimator.cc + +libamdis_la-ElementFileWriter.lo: $(PARALLEL_DIR)/ElementFileWriter.cc +@am__fastdepCXX_TRUE@ if $(LIBTOOL) --tag=CXX --mode=compile $(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(libamdis_la_CXXFLAGS) $(CXXFLAGS) -MT libamdis_la-ElementFileWriter.lo -MD -MP -MF "$(DEPDIR)/libamdis_la-ElementFileWriter.Tpo" -c -o libamdis_la-ElementFileWriter.lo `test -f '$(PARALLEL_DIR)/ElementFileWriter.cc' || echo '$(srcdir)/'`$(PARALLEL_DIR)/ElementFileWriter.cc; \ +@am__fastdepCXX_TRUE@ then mv -f "$(DEPDIR)/libamdis_la-ElementFileWriter.Tpo" "$(DEPDIR)/libamdis_la-ElementFileWriter.Plo"; else rm -f "$(DEPDIR)/libamdis_la-ElementFileWriter.Tpo"; exit 1; fi +@AMDEP_TRUE@@am__fastdepCXX_FALSE@ source='$(PARALLEL_DIR)/ElementFileWriter.cc' object='libamdis_la-ElementFileWriter.lo' libtool=yes @AMDEPBACKSLASH@ +@AMDEP_TRUE@@am__fastdepCXX_FALSE@ DEPDIR=$(DEPDIR) $(CXXDEPMODE) $(depcomp) @AMDEPBACKSLASH@ +@am__fastdepCXX_FALSE@ $(LIBTOOL) --tag=CXX --mode=compile $(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(libamdis_la_CXXFLAGS) $(CXXFLAGS) -c -o libamdis_la-ElementFileWriter.lo `test -f '$(PARALLEL_DIR)/ElementFileWriter.cc' || echo '$(srcdir)/'`$(PARALLEL_DIR)/ElementFileWriter.cc + +libamdis_la-MeshStructure.lo: $(PARALLEL_DIR)/MeshStructure.cc +@am__fastdepCXX_TRUE@ if $(LIBTOOL) --tag=CXX --mode=compile $(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(libamdis_la_CXXFLAGS) $(CXXFLAGS) -MT libamdis_la-MeshStructure.lo -MD -MP -MF "$(DEPDIR)/libamdis_la-MeshStructure.Tpo" -c -o libamdis_la-MeshStructure.lo `test -f '$(PARALLEL_DIR)/MeshStructure.cc' || echo '$(srcdir)/'`$(PARALLEL_DIR)/MeshStructure.cc; \ +@am__fastdepCXX_TRUE@ then mv -f "$(DEPDIR)/libamdis_la-MeshStructure.Tpo" "$(DEPDIR)/libamdis_la-MeshStructure.Plo"; else rm -f "$(DEPDIR)/libamdis_la-MeshStructure.Tpo"; exit 1; fi +@AMDEP_TRUE@@am__fastdepCXX_FALSE@ source='$(PARALLEL_DIR)/MeshStructure.cc' object='libamdis_la-MeshStructure.lo' libtool=yes @AMDEPBACKSLASH@ +@AMDEP_TRUE@@am__fastdepCXX_FALSE@ DEPDIR=$(DEPDIR) $(CXXDEPMODE) $(depcomp) @AMDEPBACKSLASH@ +@am__fastdepCXX_FALSE@ $(LIBTOOL) --tag=CXX --mode=compile $(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(libamdis_la_CXXFLAGS) $(CXXFLAGS) -c -o libamdis_la-MeshStructure.lo `test -f '$(PARALLEL_DIR)/MeshStructure.cc' || echo '$(srcdir)/'`$(PARALLEL_DIR)/MeshStructure.cc + +libamdis_la-ParallelProblem.lo: $(PARALLEL_DIR)/ParallelProblem.cc +@am__fastdepCXX_TRUE@ if $(LIBTOOL) --tag=CXX --mode=compile $(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(libamdis_la_CXXFLAGS) $(CXXFLAGS) -MT libamdis_la-ParallelProblem.lo -MD -MP -MF "$(DEPDIR)/libamdis_la-ParallelProblem.Tpo" -c -o libamdis_la-ParallelProblem.lo `test -f '$(PARALLEL_DIR)/ParallelProblem.cc' || echo '$(srcdir)/'`$(PARALLEL_DIR)/ParallelProblem.cc; \ +@am__fastdepCXX_TRUE@ then mv -f "$(DEPDIR)/libamdis_la-ParallelProblem.Tpo" "$(DEPDIR)/libamdis_la-ParallelProblem.Plo"; else rm -f "$(DEPDIR)/libamdis_la-ParallelProblem.Tpo"; exit 1; fi +@AMDEP_TRUE@@am__fastdepCXX_FALSE@ source='$(PARALLEL_DIR)/ParallelProblem.cc' object='libamdis_la-ParallelProblem.lo' libtool=yes @AMDEPBACKSLASH@ +@AMDEP_TRUE@@am__fastdepCXX_FALSE@ DEPDIR=$(DEPDIR) $(CXXDEPMODE) $(depcomp) @AMDEPBACKSLASH@ +@am__fastdepCXX_FALSE@ $(LIBTOOL) --tag=CXX --mode=compile $(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(libamdis_la_CXXFLAGS) $(CXXFLAGS) -c -o libamdis_la-ParallelProblem.lo `test -f '$(PARALLEL_DIR)/ParallelProblem.cc' || echo '$(srcdir)/'`$(PARALLEL_DIR)/ParallelProblem.cc + +libamdis_la-ParMetisPartitioner.lo: $(PARALLEL_DIR)/ParMetisPartitioner.cc +@am__fastdepCXX_TRUE@ if $(LIBTOOL) --tag=CXX --mode=compile $(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(libamdis_la_CXXFLAGS) $(CXXFLAGS) -MT libamdis_la-ParMetisPartitioner.lo -MD -MP -MF "$(DEPDIR)/libamdis_la-ParMetisPartitioner.Tpo" -c -o libamdis_la-ParMetisPartitioner.lo `test -f '$(PARALLEL_DIR)/ParMetisPartitioner.cc' || echo '$(srcdir)/'`$(PARALLEL_DIR)/ParMetisPartitioner.cc; \ +@am__fastdepCXX_TRUE@ then mv -f "$(DEPDIR)/libamdis_la-ParMetisPartitioner.Tpo" "$(DEPDIR)/libamdis_la-ParMetisPartitioner.Plo"; else rm -f "$(DEPDIR)/libamdis_la-ParMetisPartitioner.Tpo"; exit 1; fi +@AMDEP_TRUE@@am__fastdepCXX_FALSE@ source='$(PARALLEL_DIR)/ParMetisPartitioner.cc' object='libamdis_la-ParMetisPartitioner.lo' libtool=yes @AMDEPBACKSLASH@ +@AMDEP_TRUE@@am__fastdepCXX_FALSE@ DEPDIR=$(DEPDIR) $(CXXDEPMODE) $(depcomp) @AMDEPBACKSLASH@ +@am__fastdepCXX_FALSE@ $(LIBTOOL) --tag=CXX --mode=compile $(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(libamdis_la_CXXFLAGS) $(CXXFLAGS) -c -o libamdis_la-ParMetisPartitioner.lo `test -f '$(PARALLEL_DIR)/ParMetisPartitioner.cc' || echo '$(srcdir)/'`$(PARALLEL_DIR)/ParMetisPartitioner.cc + +libamdis_la-MultiGridPreconWrapper.lo: $(SOURCE_DIR)/MultiGridPreconWrapper.cc +@am__fastdepCXX_TRUE@ if $(LIBTOOL) --tag=CXX --mode=compile $(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(libamdis_la_CXXFLAGS) $(CXXFLAGS) -MT libamdis_la-MultiGridPreconWrapper.lo -MD -MP -MF "$(DEPDIR)/libamdis_la-MultiGridPreconWrapper.Tpo" -c -o libamdis_la-MultiGridPreconWrapper.lo `test -f '$(SOURCE_DIR)/MultiGridPreconWrapper.cc' || echo '$(srcdir)/'`$(SOURCE_DIR)/MultiGridPreconWrapper.cc; \ +@am__fastdepCXX_TRUE@ then mv -f "$(DEPDIR)/libamdis_la-MultiGridPreconWrapper.Tpo" "$(DEPDIR)/libamdis_la-MultiGridPreconWrapper.Plo"; else rm -f "$(DEPDIR)/libamdis_la-MultiGridPreconWrapper.Tpo"; exit 1; fi +@AMDEP_TRUE@@am__fastdepCXX_FALSE@ source='$(SOURCE_DIR)/MultiGridPreconWrapper.cc' object='libamdis_la-MultiGridPreconWrapper.lo' libtool=yes @AMDEPBACKSLASH@ +@AMDEP_TRUE@@am__fastdepCXX_FALSE@ DEPDIR=$(DEPDIR) $(CXXDEPMODE) $(depcomp) @AMDEPBACKSLASH@ +@am__fastdepCXX_FALSE@ $(LIBTOOL) --tag=CXX --mode=compile $(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(libamdis_la_CXXFLAGS) $(CXXFLAGS) -c -o libamdis_la-MultiGridPreconWrapper.lo `test -f '$(SOURCE_DIR)/MultiGridPreconWrapper.cc' || echo '$(srcdir)/'`$(SOURCE_DIR)/MultiGridPreconWrapper.cc + +libamdis_la-LagrangeInterpolRestrict.lo: $(SOURCE_DIR)/LagrangeInterpolRestrict.cc +@am__fastdepCXX_TRUE@ if $(LIBTOOL) --tag=CXX --mode=compile $(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(libamdis_la_CXXFLAGS) $(CXXFLAGS) -MT libamdis_la-LagrangeInterpolRestrict.lo -MD -MP -MF "$(DEPDIR)/libamdis_la-LagrangeInterpolRestrict.Tpo" -c -o libamdis_la-LagrangeInterpolRestrict.lo `test -f '$(SOURCE_DIR)/LagrangeInterpolRestrict.cc' || echo '$(srcdir)/'`$(SOURCE_DIR)/LagrangeInterpolRestrict.cc; \ +@am__fastdepCXX_TRUE@ then mv -f "$(DEPDIR)/libamdis_la-LagrangeInterpolRestrict.Tpo" "$(DEPDIR)/libamdis_la-LagrangeInterpolRestrict.Plo"; else rm -f "$(DEPDIR)/libamdis_la-LagrangeInterpolRestrict.Tpo"; exit 1; fi +@AMDEP_TRUE@@am__fastdepCXX_FALSE@ source='$(SOURCE_DIR)/LagrangeInterpolRestrict.cc' object='libamdis_la-LagrangeInterpolRestrict.lo' libtool=yes @AMDEPBACKSLASH@ +@AMDEP_TRUE@@am__fastdepCXX_FALSE@ DEPDIR=$(DEPDIR) $(CXXDEPMODE) $(depcomp) @AMDEPBACKSLASH@ +@am__fastdepCXX_FALSE@ $(LIBTOOL) --tag=CXX --mode=compile $(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(libamdis_la_CXXFLAGS) $(CXXFLAGS) -c -o libamdis_la-LagrangeInterpolRestrict.lo `test -f '$(SOURCE_DIR)/LagrangeInterpolRestrict.cc' || echo '$(srcdir)/'`$(SOURCE_DIR)/LagrangeInterpolRestrict.cc + +libamdis_la-InterpolRestrictMatrix.lo: $(SOURCE_DIR)/InterpolRestrictMatrix.cc +@am__fastdepCXX_TRUE@ if $(LIBTOOL) --tag=CXX --mode=compile $(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(libamdis_la_CXXFLAGS) $(CXXFLAGS) -MT libamdis_la-InterpolRestrictMatrix.lo -MD -MP -MF "$(DEPDIR)/libamdis_la-InterpolRestrictMatrix.Tpo" -c -o libamdis_la-InterpolRestrictMatrix.lo `test -f '$(SOURCE_DIR)/InterpolRestrictMatrix.cc' || echo '$(srcdir)/'`$(SOURCE_DIR)/InterpolRestrictMatrix.cc; \ +@am__fastdepCXX_TRUE@ then mv -f "$(DEPDIR)/libamdis_la-InterpolRestrictMatrix.Tpo" "$(DEPDIR)/libamdis_la-InterpolRestrictMatrix.Plo"; else rm -f "$(DEPDIR)/libamdis_la-InterpolRestrictMatrix.Tpo"; exit 1; fi +@AMDEP_TRUE@@am__fastdepCXX_FALSE@ source='$(SOURCE_DIR)/InterpolRestrictMatrix.cc' object='libamdis_la-InterpolRestrictMatrix.lo' libtool=yes @AMDEPBACKSLASH@ +@AMDEP_TRUE@@am__fastdepCXX_FALSE@ DEPDIR=$(DEPDIR) $(CXXDEPMODE) $(depcomp) @AMDEPBACKSLASH@ +@am__fastdepCXX_FALSE@ $(LIBTOOL) --tag=CXX --mode=compile $(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(libamdis_la_CXXFLAGS) $(CXXFLAGS) -c -o libamdis_la-InterpolRestrictMatrix.lo `test -f '$(SOURCE_DIR)/InterpolRestrictMatrix.cc' || echo '$(srcdir)/'`$(SOURCE_DIR)/InterpolRestrictMatrix.cc + +libamdis_la-DOFIndexed.lo: $(SOURCE_DIR)/DOFIndexed.cc +@am__fastdepCXX_TRUE@ if $(LIBTOOL) --tag=CXX --mode=compile $(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(libamdis_la_CXXFLAGS) $(CXXFLAGS) -MT libamdis_la-DOFIndexed.lo -MD -MP -MF "$(DEPDIR)/libamdis_la-DOFIndexed.Tpo" -c -o libamdis_la-DOFIndexed.lo `test -f '$(SOURCE_DIR)/DOFIndexed.cc' || echo '$(srcdir)/'`$(SOURCE_DIR)/DOFIndexed.cc; \ +@am__fastdepCXX_TRUE@ then mv -f "$(DEPDIR)/libamdis_la-DOFIndexed.Tpo" "$(DEPDIR)/libamdis_la-DOFIndexed.Plo"; else rm -f "$(DEPDIR)/libamdis_la-DOFIndexed.Tpo"; exit 1; fi +@AMDEP_TRUE@@am__fastdepCXX_FALSE@ source='$(SOURCE_DIR)/DOFIndexed.cc' object='libamdis_la-DOFIndexed.lo' libtool=yes @AMDEPBACKSLASH@ +@AMDEP_TRUE@@am__fastdepCXX_FALSE@ DEPDIR=$(DEPDIR) $(CXXDEPMODE) $(depcomp) @AMDEPBACKSLASH@ +@am__fastdepCXX_FALSE@ $(LIBTOOL) --tag=CXX --mode=compile $(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(libamdis_la_CXXFLAGS) $(CXXFLAGS) -c -o libamdis_la-DOFIndexed.lo `test -f '$(SOURCE_DIR)/DOFIndexed.cc' || echo '$(srcdir)/'`$(SOURCE_DIR)/DOFIndexed.cc + +libamdis_la-GNUPlotWriter.lo: $(SOURCE_DIR)/GNUPlotWriter.cc +@am__fastdepCXX_TRUE@ if $(LIBTOOL) --tag=CXX --mode=compile $(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(libamdis_la_CXXFLAGS) $(CXXFLAGS) -MT libamdis_la-GNUPlotWriter.lo -MD -MP -MF "$(DEPDIR)/libamdis_la-GNUPlotWriter.Tpo" -c -o libamdis_la-GNUPlotWriter.lo `test -f '$(SOURCE_DIR)/GNUPlotWriter.cc' || echo '$(srcdir)/'`$(SOURCE_DIR)/GNUPlotWriter.cc; \ +@am__fastdepCXX_TRUE@ then mv -f "$(DEPDIR)/libamdis_la-GNUPlotWriter.Tpo" "$(DEPDIR)/libamdis_la-GNUPlotWriter.Plo"; else rm -f "$(DEPDIR)/libamdis_la-GNUPlotWriter.Tpo"; exit 1; fi +@AMDEP_TRUE@@am__fastdepCXX_FALSE@ source='$(SOURCE_DIR)/GNUPlotWriter.cc' object='libamdis_la-GNUPlotWriter.lo' libtool=yes @AMDEPBACKSLASH@ +@AMDEP_TRUE@@am__fastdepCXX_FALSE@ DEPDIR=$(DEPDIR) $(CXXDEPMODE) $(depcomp) @AMDEPBACKSLASH@ +@am__fastdepCXX_FALSE@ $(LIBTOOL) --tag=CXX --mode=compile $(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(libamdis_la_CXXFLAGS) $(CXXFLAGS) -c -o libamdis_la-GNUPlotWriter.lo `test -f '$(SOURCE_DIR)/GNUPlotWriter.cc' || echo '$(srcdir)/'`$(SOURCE_DIR)/GNUPlotWriter.cc + +libamdis_la-StlVector.lo: $(SOURCE_DIR)/StlVector.cc +@am__fastdepCXX_TRUE@ if $(LIBTOOL) --tag=CXX --mode=compile $(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(libamdis_la_CXXFLAGS) $(CXXFLAGS) -MT libamdis_la-StlVector.lo -MD -MP -MF "$(DEPDIR)/libamdis_la-StlVector.Tpo" -c -o libamdis_la-StlVector.lo `test -f '$(SOURCE_DIR)/StlVector.cc' || echo '$(srcdir)/'`$(SOURCE_DIR)/StlVector.cc; \ +@am__fastdepCXX_TRUE@ then mv -f "$(DEPDIR)/libamdis_la-StlVector.Tpo" "$(DEPDIR)/libamdis_la-StlVector.Plo"; else rm -f "$(DEPDIR)/libamdis_la-StlVector.Tpo"; exit 1; fi +@AMDEP_TRUE@@am__fastdepCXX_FALSE@ source='$(SOURCE_DIR)/StlVector.cc' object='libamdis_la-StlVector.lo' libtool=yes @AMDEPBACKSLASH@ +@AMDEP_TRUE@@am__fastdepCXX_FALSE@ DEPDIR=$(DEPDIR) $(CXXDEPMODE) $(depcomp) @AMDEPBACKSLASH@ +@am__fastdepCXX_FALSE@ $(LIBTOOL) --tag=CXX --mode=compile $(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(libamdis_la_CXXFLAGS) $(CXXFLAGS) -c -o libamdis_la-StlVector.lo `test -f '$(SOURCE_DIR)/StlVector.cc' || echo '$(srcdir)/'`$(SOURCE_DIR)/StlVector.cc + +libamdis_la-V3Vector.lo: $(SOURCE_DIR)/V3Vector.cc +@am__fastdepCXX_TRUE@ if $(LIBTOOL) --tag=CXX --mode=compile $(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(libamdis_la_CXXFLAGS) $(CXXFLAGS) -MT libamdis_la-V3Vector.lo -MD -MP -MF "$(DEPDIR)/libamdis_la-V3Vector.Tpo" -c -o libamdis_la-V3Vector.lo `test -f '$(SOURCE_DIR)/V3Vector.cc' || echo '$(srcdir)/'`$(SOURCE_DIR)/V3Vector.cc; \ +@am__fastdepCXX_TRUE@ then mv -f "$(DEPDIR)/libamdis_la-V3Vector.Tpo" "$(DEPDIR)/libamdis_la-V3Vector.Plo"; else rm -f "$(DEPDIR)/libamdis_la-V3Vector.Tpo"; exit 1; fi +@AMDEP_TRUE@@am__fastdepCXX_FALSE@ source='$(SOURCE_DIR)/V3Vector.cc' object='libamdis_la-V3Vector.lo' libtool=yes @AMDEPBACKSLASH@ +@AMDEP_TRUE@@am__fastdepCXX_FALSE@ DEPDIR=$(DEPDIR) $(CXXDEPMODE) $(depcomp) @AMDEPBACKSLASH@ +@am__fastdepCXX_FALSE@ $(LIBTOOL) --tag=CXX --mode=compile $(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(libamdis_la_CXXFLAGS) $(CXXFLAGS) -c -o libamdis_la-V3Vector.lo `test -f '$(SOURCE_DIR)/V3Vector.cc' || echo '$(srcdir)/'`$(SOURCE_DIR)/V3Vector.cc + +libamdis_la-GSSmoother.lo: $(SOURCE_DIR)/GSSmoother.cc +@am__fastdepCXX_TRUE@ if $(LIBTOOL) --tag=CXX --mode=compile $(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(libamdis_la_CXXFLAGS) $(CXXFLAGS) -MT libamdis_la-GSSmoother.lo -MD -MP -MF "$(DEPDIR)/libamdis_la-GSSmoother.Tpo" -c -o libamdis_la-GSSmoother.lo `test -f '$(SOURCE_DIR)/GSSmoother.cc' || echo '$(srcdir)/'`$(SOURCE_DIR)/GSSmoother.cc; \ +@am__fastdepCXX_TRUE@ then mv -f "$(DEPDIR)/libamdis_la-GSSmoother.Tpo" "$(DEPDIR)/libamdis_la-GSSmoother.Plo"; else rm -f "$(DEPDIR)/libamdis_la-GSSmoother.Tpo"; exit 1; fi +@AMDEP_TRUE@@am__fastdepCXX_FALSE@ source='$(SOURCE_DIR)/GSSmoother.cc' object='libamdis_la-GSSmoother.lo' libtool=yes @AMDEPBACKSLASH@ +@AMDEP_TRUE@@am__fastdepCXX_FALSE@ DEPDIR=$(DEPDIR) $(CXXDEPMODE) $(depcomp) @AMDEPBACKSLASH@ +@am__fastdepCXX_FALSE@ $(LIBTOOL) --tag=CXX --mode=compile $(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(libamdis_la_CXXFLAGS) $(CXXFLAGS) -c -o libamdis_la-GSSmoother.lo `test -f '$(SOURCE_DIR)/GSSmoother.cc' || echo '$(srcdir)/'`$(SOURCE_DIR)/GSSmoother.cc + +libamdis_la-JacobiSmoother.lo: $(SOURCE_DIR)/JacobiSmoother.cc +@am__fastdepCXX_TRUE@ if $(LIBTOOL) --tag=CXX --mode=compile $(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(libamdis_la_CXXFLAGS) $(CXXFLAGS) -MT libamdis_la-JacobiSmoother.lo -MD -MP -MF "$(DEPDIR)/libamdis_la-JacobiSmoother.Tpo" -c -o libamdis_la-JacobiSmoother.lo `test -f '$(SOURCE_DIR)/JacobiSmoother.cc' || echo '$(srcdir)/'`$(SOURCE_DIR)/JacobiSmoother.cc; \ +@am__fastdepCXX_TRUE@ then mv -f "$(DEPDIR)/libamdis_la-JacobiSmoother.Tpo" "$(DEPDIR)/libamdis_la-JacobiSmoother.Plo"; else rm -f "$(DEPDIR)/libamdis_la-JacobiSmoother.Tpo"; exit 1; fi +@AMDEP_TRUE@@am__fastdepCXX_FALSE@ source='$(SOURCE_DIR)/JacobiSmoother.cc' object='libamdis_la-JacobiSmoother.lo' libtool=yes @AMDEPBACKSLASH@ +@AMDEP_TRUE@@am__fastdepCXX_FALSE@ DEPDIR=$(DEPDIR) $(CXXDEPMODE) $(depcomp) @AMDEPBACKSLASH@ +@am__fastdepCXX_FALSE@ $(LIBTOOL) --tag=CXX --mode=compile $(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(libamdis_la_CXXFLAGS) $(CXXFLAGS) -c -o libamdis_la-JacobiSmoother.lo `test -f '$(SOURCE_DIR)/JacobiSmoother.cc' || echo '$(srcdir)/'`$(SOURCE_DIR)/JacobiSmoother.cc + +libamdis_la-SparseVector.lo: $(SOURCE_DIR)/SparseVector.cc +@am__fastdepCXX_TRUE@ if $(LIBTOOL) --tag=CXX --mode=compile $(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(libamdis_la_CXXFLAGS) $(CXXFLAGS) -MT libamdis_la-SparseVector.lo -MD -MP -MF "$(DEPDIR)/libamdis_la-SparseVector.Tpo" -c -o libamdis_la-SparseVector.lo `test -f '$(SOURCE_DIR)/SparseVector.cc' || echo '$(srcdir)/'`$(SOURCE_DIR)/SparseVector.cc; \ +@am__fastdepCXX_TRUE@ then mv -f "$(DEPDIR)/libamdis_la-SparseVector.Tpo" "$(DEPDIR)/libamdis_la-SparseVector.Plo"; else rm -f "$(DEPDIR)/libamdis_la-SparseVector.Tpo"; exit 1; fi +@AMDEP_TRUE@@am__fastdepCXX_FALSE@ source='$(SOURCE_DIR)/SparseVector.cc' object='libamdis_la-SparseVector.lo' libtool=yes @AMDEPBACKSLASH@ +@AMDEP_TRUE@@am__fastdepCXX_FALSE@ DEPDIR=$(DEPDIR) $(CXXDEPMODE) $(depcomp) @AMDEPBACKSLASH@ +@am__fastdepCXX_FALSE@ $(LIBTOOL) --tag=CXX --mode=compile $(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(libamdis_la_CXXFLAGS) $(CXXFLAGS) -c -o libamdis_la-SparseVector.lo `test -f '$(SOURCE_DIR)/SparseVector.cc' || echo '$(srcdir)/'`$(SOURCE_DIR)/SparseVector.cc + +libamdis_la-VertexVector.lo: $(SOURCE_DIR)/VertexVector.cc +@am__fastdepCXX_TRUE@ if $(LIBTOOL) --tag=CXX --mode=compile $(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(libamdis_la_CXXFLAGS) $(CXXFLAGS) -MT libamdis_la-VertexVector.lo -MD -MP -MF "$(DEPDIR)/libamdis_la-VertexVector.Tpo" -c -o libamdis_la-VertexVector.lo `test -f '$(SOURCE_DIR)/VertexVector.cc' || echo '$(srcdir)/'`$(SOURCE_DIR)/VertexVector.cc; \ +@am__fastdepCXX_TRUE@ then mv -f "$(DEPDIR)/libamdis_la-VertexVector.Tpo" "$(DEPDIR)/libamdis_la-VertexVector.Plo"; else rm -f "$(DEPDIR)/libamdis_la-VertexVector.Tpo"; exit 1; fi +@AMDEP_TRUE@@am__fastdepCXX_FALSE@ source='$(SOURCE_DIR)/VertexVector.cc' object='libamdis_la-VertexVector.lo' libtool=yes @AMDEPBACKSLASH@ +@AMDEP_TRUE@@am__fastdepCXX_FALSE@ DEPDIR=$(DEPDIR) $(CXXDEPMODE) $(depcomp) @AMDEPBACKSLASH@ +@am__fastdepCXX_FALSE@ $(LIBTOOL) --tag=CXX --mode=compile $(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(libamdis_la_CXXFLAGS) $(CXXFLAGS) -c -o libamdis_la-VertexVector.lo `test -f '$(SOURCE_DIR)/VertexVector.cc' || echo '$(srcdir)/'`$(SOURCE_DIR)/VertexVector.cc + +libamdis_la-PeriodicBC.lo: $(SOURCE_DIR)/PeriodicBC.cc +@am__fastdepCXX_TRUE@ if $(LIBTOOL) --tag=CXX --mode=compile $(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(libamdis_la_CXXFLAGS) $(CXXFLAGS) -MT libamdis_la-PeriodicBC.lo -MD -MP -MF "$(DEPDIR)/libamdis_la-PeriodicBC.Tpo" -c -o libamdis_la-PeriodicBC.lo `test -f '$(SOURCE_DIR)/PeriodicBC.cc' || echo '$(srcdir)/'`$(SOURCE_DIR)/PeriodicBC.cc; \ +@am__fastdepCXX_TRUE@ then mv -f "$(DEPDIR)/libamdis_la-PeriodicBC.Tpo" "$(DEPDIR)/libamdis_la-PeriodicBC.Plo"; else rm -f "$(DEPDIR)/libamdis_la-PeriodicBC.Tpo"; exit 1; fi +@AMDEP_TRUE@@am__fastdepCXX_FALSE@ source='$(SOURCE_DIR)/PeriodicBC.cc' object='libamdis_la-PeriodicBC.lo' libtool=yes @AMDEPBACKSLASH@ +@AMDEP_TRUE@@am__fastdepCXX_FALSE@ DEPDIR=$(DEPDIR) $(CXXDEPMODE) $(depcomp) @AMDEPBACKSLASH@ +@am__fastdepCXX_FALSE@ $(LIBTOOL) --tag=CXX --mode=compile $(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(libamdis_la_CXXFLAGS) $(CXXFLAGS) -c -o libamdis_la-PeriodicBC.lo `test -f '$(SOURCE_DIR)/PeriodicBC.cc' || echo '$(srcdir)/'`$(SOURCE_DIR)/PeriodicBC.cc + +libamdis_la-MultiGridSolver.lo: $(SOURCE_DIR)/MultiGridSolver.cc +@am__fastdepCXX_TRUE@ if $(LIBTOOL) --tag=CXX --mode=compile $(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(libamdis_la_CXXFLAGS) $(CXXFLAGS) -MT libamdis_la-MultiGridSolver.lo -MD -MP -MF "$(DEPDIR)/libamdis_la-MultiGridSolver.Tpo" -c -o libamdis_la-MultiGridSolver.lo `test -f '$(SOURCE_DIR)/MultiGridSolver.cc' || echo '$(srcdir)/'`$(SOURCE_DIR)/MultiGridSolver.cc; \ +@am__fastdepCXX_TRUE@ then mv -f "$(DEPDIR)/libamdis_la-MultiGridSolver.Tpo" "$(DEPDIR)/libamdis_la-MultiGridSolver.Plo"; else rm -f "$(DEPDIR)/libamdis_la-MultiGridSolver.Tpo"; exit 1; fi +@AMDEP_TRUE@@am__fastdepCXX_FALSE@ source='$(SOURCE_DIR)/MultiGridSolver.cc' object='libamdis_la-MultiGridSolver.lo' libtool=yes @AMDEPBACKSLASH@ +@AMDEP_TRUE@@am__fastdepCXX_FALSE@ DEPDIR=$(DEPDIR) $(CXXDEPMODE) $(depcomp) @AMDEPBACKSLASH@ +@am__fastdepCXX_FALSE@ $(LIBTOOL) --tag=CXX --mode=compile $(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(libamdis_la_CXXFLAGS) $(CXXFLAGS) -c -o libamdis_la-MultiGridSolver.lo `test -f '$(SOURCE_DIR)/MultiGridSolver.cc' || echo '$(srcdir)/'`$(SOURCE_DIR)/MultiGridSolver.cc + +libamdis_la-Recovery.lo: $(SOURCE_DIR)/Recovery.cc +@am__fastdepCXX_TRUE@ if $(LIBTOOL) --tag=CXX --mode=compile $(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(libamdis_la_CXXFLAGS) $(CXXFLAGS) -MT libamdis_la-Recovery.lo -MD -MP -MF "$(DEPDIR)/libamdis_la-Recovery.Tpo" -c -o libamdis_la-Recovery.lo `test -f '$(SOURCE_DIR)/Recovery.cc' || echo '$(srcdir)/'`$(SOURCE_DIR)/Recovery.cc; \ +@am__fastdepCXX_TRUE@ then mv -f "$(DEPDIR)/libamdis_la-Recovery.Tpo" "$(DEPDIR)/libamdis_la-Recovery.Plo"; else rm -f "$(DEPDIR)/libamdis_la-Recovery.Tpo"; exit 1; fi +@AMDEP_TRUE@@am__fastdepCXX_FALSE@ source='$(SOURCE_DIR)/Recovery.cc' object='libamdis_la-Recovery.lo' libtool=yes @AMDEPBACKSLASH@ +@AMDEP_TRUE@@am__fastdepCXX_FALSE@ DEPDIR=$(DEPDIR) $(CXXDEPMODE) $(depcomp) @AMDEPBACKSLASH@ +@am__fastdepCXX_FALSE@ $(LIBTOOL) --tag=CXX --mode=compile $(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(libamdis_la_CXXFLAGS) $(CXXFLAGS) -c -o libamdis_la-Recovery.lo `test -f '$(SOURCE_DIR)/Recovery.cc' || echo '$(srcdir)/'`$(SOURCE_DIR)/Recovery.cc + +libamdis_la-RecoveryEstimator.lo: $(SOURCE_DIR)/RecoveryEstimator.cc +@am__fastdepCXX_TRUE@ if $(LIBTOOL) --tag=CXX --mode=compile $(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(libamdis_la_CXXFLAGS) $(CXXFLAGS) -MT libamdis_la-RecoveryEstimator.lo -MD -MP -MF "$(DEPDIR)/libamdis_la-RecoveryEstimator.Tpo" -c -o libamdis_la-RecoveryEstimator.lo `test -f '$(SOURCE_DIR)/RecoveryEstimator.cc' || echo '$(srcdir)/'`$(SOURCE_DIR)/RecoveryEstimator.cc; \ +@am__fastdepCXX_TRUE@ then mv -f "$(DEPDIR)/libamdis_la-RecoveryEstimator.Tpo" "$(DEPDIR)/libamdis_la-RecoveryEstimator.Plo"; else rm -f "$(DEPDIR)/libamdis_la-RecoveryEstimator.Tpo"; exit 1; fi +@AMDEP_TRUE@@am__fastdepCXX_FALSE@ source='$(SOURCE_DIR)/RecoveryEstimator.cc' object='libamdis_la-RecoveryEstimator.lo' libtool=yes @AMDEPBACKSLASH@ +@AMDEP_TRUE@@am__fastdepCXX_FALSE@ DEPDIR=$(DEPDIR) $(CXXDEPMODE) $(depcomp) @AMDEPBACKSLASH@ +@am__fastdepCXX_FALSE@ $(LIBTOOL) --tag=CXX --mode=compile $(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(libamdis_la_CXXFLAGS) $(CXXFLAGS) -c -o libamdis_la-RecoveryEstimator.lo `test -f '$(SOURCE_DIR)/RecoveryEstimator.cc' || echo '$(srcdir)/'`$(SOURCE_DIR)/RecoveryEstimator.cc + +libamdis_la-Cholesky.lo: $(SOURCE_DIR)/Cholesky.cc +@am__fastdepCXX_TRUE@ if $(LIBTOOL) --tag=CXX --mode=compile $(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(libamdis_la_CXXFLAGS) $(CXXFLAGS) -MT libamdis_la-Cholesky.lo -MD -MP -MF "$(DEPDIR)/libamdis_la-Cholesky.Tpo" -c -o libamdis_la-Cholesky.lo `test -f '$(SOURCE_DIR)/Cholesky.cc' || echo '$(srcdir)/'`$(SOURCE_DIR)/Cholesky.cc; \ +@am__fastdepCXX_TRUE@ then mv -f "$(DEPDIR)/libamdis_la-Cholesky.Tpo" "$(DEPDIR)/libamdis_la-Cholesky.Plo"; else rm -f "$(DEPDIR)/libamdis_la-Cholesky.Tpo"; exit 1; fi +@AMDEP_TRUE@@am__fastdepCXX_FALSE@ source='$(SOURCE_DIR)/Cholesky.cc' object='libamdis_la-Cholesky.lo' libtool=yes @AMDEPBACKSLASH@ +@AMDEP_TRUE@@am__fastdepCXX_FALSE@ DEPDIR=$(DEPDIR) $(CXXDEPMODE) $(depcomp) @AMDEPBACKSLASH@ +@am__fastdepCXX_FALSE@ $(LIBTOOL) --tag=CXX --mode=compile $(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(libamdis_la_CXXFLAGS) $(CXXFLAGS) -c -o libamdis_la-Cholesky.lo `test -f '$(SOURCE_DIR)/Cholesky.cc' || echo '$(srcdir)/'`$(SOURCE_DIR)/Cholesky.cc + +libamdis_la-AdaptBase.lo: $(SOURCE_DIR)/AdaptBase.cc +@am__fastdepCXX_TRUE@ if $(LIBTOOL) --tag=CXX --mode=compile $(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(libamdis_la_CXXFLAGS) $(CXXFLAGS) -MT libamdis_la-AdaptBase.lo -MD -MP -MF "$(DEPDIR)/libamdis_la-AdaptBase.Tpo" -c -o libamdis_la-AdaptBase.lo `test -f '$(SOURCE_DIR)/AdaptBase.cc' || echo '$(srcdir)/'`$(SOURCE_DIR)/AdaptBase.cc; \ +@am__fastdepCXX_TRUE@ then mv -f "$(DEPDIR)/libamdis_la-AdaptBase.Tpo" "$(DEPDIR)/libamdis_la-AdaptBase.Plo"; else rm -f "$(DEPDIR)/libamdis_la-AdaptBase.Tpo"; exit 1; fi +@AMDEP_TRUE@@am__fastdepCXX_FALSE@ source='$(SOURCE_DIR)/AdaptBase.cc' object='libamdis_la-AdaptBase.lo' libtool=yes @AMDEPBACKSLASH@ +@AMDEP_TRUE@@am__fastdepCXX_FALSE@ DEPDIR=$(DEPDIR) $(CXXDEPMODE) $(depcomp) @AMDEPBACKSLASH@ +@am__fastdepCXX_FALSE@ $(LIBTOOL) --tag=CXX --mode=compile $(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(libamdis_la_CXXFLAGS) $(CXXFLAGS) -c -o libamdis_la-AdaptBase.lo `test -f '$(SOURCE_DIR)/AdaptBase.cc' || echo '$(srcdir)/'`$(SOURCE_DIR)/AdaptBase.cc + +libamdis_la-StandardProblemIteration.lo: $(SOURCE_DIR)/StandardProblemIteration.cc +@am__fastdepCXX_TRUE@ if $(LIBTOOL) --tag=CXX --mode=compile $(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(libamdis_la_CXXFLAGS) $(CXXFLAGS) -MT libamdis_la-StandardProblemIteration.lo -MD -MP -MF "$(DEPDIR)/libamdis_la-StandardProblemIteration.Tpo" -c -o libamdis_la-StandardProblemIteration.lo `test -f '$(SOURCE_DIR)/StandardProblemIteration.cc' || echo '$(srcdir)/'`$(SOURCE_DIR)/StandardProblemIteration.cc; \ +@am__fastdepCXX_TRUE@ then mv -f "$(DEPDIR)/libamdis_la-StandardProblemIteration.Tpo" "$(DEPDIR)/libamdis_la-StandardProblemIteration.Plo"; else rm -f "$(DEPDIR)/libamdis_la-StandardProblemIteration.Tpo"; exit 1; fi +@AMDEP_TRUE@@am__fastdepCXX_FALSE@ source='$(SOURCE_DIR)/StandardProblemIteration.cc' object='libamdis_la-StandardProblemIteration.lo' libtool=yes @AMDEPBACKSLASH@ +@AMDEP_TRUE@@am__fastdepCXX_FALSE@ DEPDIR=$(DEPDIR) $(CXXDEPMODE) $(depcomp) @AMDEPBACKSLASH@ +@am__fastdepCXX_FALSE@ $(LIBTOOL) --tag=CXX --mode=compile $(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(libamdis_la_CXXFLAGS) $(CXXFLAGS) -c -o libamdis_la-StandardProblemIteration.lo `test -f '$(SOURCE_DIR)/StandardProblemIteration.cc' || echo '$(srcdir)/'`$(SOURCE_DIR)/StandardProblemIteration.cc + +libamdis_la-ProblemScal.lo: $(SOURCE_DIR)/ProblemScal.cc +@am__fastdepCXX_TRUE@ if $(LIBTOOL) --tag=CXX --mode=compile $(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(libamdis_la_CXXFLAGS) $(CXXFLAGS) -MT libamdis_la-ProblemScal.lo -MD -MP -MF "$(DEPDIR)/libamdis_la-ProblemScal.Tpo" -c -o libamdis_la-ProblemScal.lo `test -f '$(SOURCE_DIR)/ProblemScal.cc' || echo '$(srcdir)/'`$(SOURCE_DIR)/ProblemScal.cc; \ +@am__fastdepCXX_TRUE@ then mv -f "$(DEPDIR)/libamdis_la-ProblemScal.Tpo" "$(DEPDIR)/libamdis_la-ProblemScal.Plo"; else rm -f "$(DEPDIR)/libamdis_la-ProblemScal.Tpo"; exit 1; fi +@AMDEP_TRUE@@am__fastdepCXX_FALSE@ source='$(SOURCE_DIR)/ProblemScal.cc' object='libamdis_la-ProblemScal.lo' libtool=yes @AMDEPBACKSLASH@ +@AMDEP_TRUE@@am__fastdepCXX_FALSE@ DEPDIR=$(DEPDIR) $(CXXDEPMODE) $(depcomp) @AMDEPBACKSLASH@ +@am__fastdepCXX_FALSE@ $(LIBTOOL) --tag=CXX --mode=compile $(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(libamdis_la_CXXFLAGS) $(CXXFLAGS) -c -o libamdis_la-ProblemScal.lo `test -f '$(SOURCE_DIR)/ProblemScal.cc' || echo '$(srcdir)/'`$(SOURCE_DIR)/ProblemScal.cc + +libamdis_la-ProblemVec.lo: $(SOURCE_DIR)/ProblemVec.cc +@am__fastdepCXX_TRUE@ if $(LIBTOOL) --tag=CXX --mode=compile $(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(libamdis_la_CXXFLAGS) $(CXXFLAGS) -MT libamdis_la-ProblemVec.lo -MD -MP -MF "$(DEPDIR)/libamdis_la-ProblemVec.Tpo" -c -o libamdis_la-ProblemVec.lo `test -f '$(SOURCE_DIR)/ProblemVec.cc' || echo '$(srcdir)/'`$(SOURCE_DIR)/ProblemVec.cc; \ +@am__fastdepCXX_TRUE@ then mv -f "$(DEPDIR)/libamdis_la-ProblemVec.Tpo" "$(DEPDIR)/libamdis_la-ProblemVec.Plo"; else rm -f "$(DEPDIR)/libamdis_la-ProblemVec.Tpo"; exit 1; fi +@AMDEP_TRUE@@am__fastdepCXX_FALSE@ source='$(SOURCE_DIR)/ProblemVec.cc' object='libamdis_la-ProblemVec.lo' libtool=yes @AMDEPBACKSLASH@ +@AMDEP_TRUE@@am__fastdepCXX_FALSE@ DEPDIR=$(DEPDIR) $(CXXDEPMODE) $(depcomp) @AMDEPBACKSLASH@ +@am__fastdepCXX_FALSE@ $(LIBTOOL) --tag=CXX --mode=compile $(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(libamdis_la_CXXFLAGS) $(CXXFLAGS) -c -o libamdis_la-ProblemVec.lo `test -f '$(SOURCE_DIR)/ProblemVec.cc' || echo '$(srcdir)/'`$(SOURCE_DIR)/ProblemVec.cc + +libamdis_la-DualTraverse.lo: $(SOURCE_DIR)/DualTraverse.cc +@am__fastdepCXX_TRUE@ if $(LIBTOOL) --tag=CXX --mode=compile $(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(libamdis_la_CXXFLAGS) $(CXXFLAGS) -MT libamdis_la-DualTraverse.lo -MD -MP -MF "$(DEPDIR)/libamdis_la-DualTraverse.Tpo" -c -o libamdis_la-DualTraverse.lo `test -f '$(SOURCE_DIR)/DualTraverse.cc' || echo '$(srcdir)/'`$(SOURCE_DIR)/DualTraverse.cc; \ +@am__fastdepCXX_TRUE@ then mv -f "$(DEPDIR)/libamdis_la-DualTraverse.Tpo" "$(DEPDIR)/libamdis_la-DualTraverse.Plo"; else rm -f "$(DEPDIR)/libamdis_la-DualTraverse.Tpo"; exit 1; fi +@AMDEP_TRUE@@am__fastdepCXX_FALSE@ source='$(SOURCE_DIR)/DualTraverse.cc' object='libamdis_la-DualTraverse.lo' libtool=yes @AMDEPBACKSLASH@ +@AMDEP_TRUE@@am__fastdepCXX_FALSE@ DEPDIR=$(DEPDIR) $(CXXDEPMODE) $(depcomp) @AMDEPBACKSLASH@ +@am__fastdepCXX_FALSE@ $(LIBTOOL) --tag=CXX --mode=compile $(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(libamdis_la_CXXFLAGS) $(CXXFLAGS) -c -o libamdis_la-DualTraverse.lo `test -f '$(SOURCE_DIR)/DualTraverse.cc' || echo '$(srcdir)/'`$(SOURCE_DIR)/DualTraverse.cc + +libamdis_la-ElementData.lo: $(SOURCE_DIR)/ElementData.cc +@am__fastdepCXX_TRUE@ if $(LIBTOOL) --tag=CXX --mode=compile $(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(libamdis_la_CXXFLAGS) $(CXXFLAGS) -MT libamdis_la-ElementData.lo -MD -MP -MF "$(DEPDIR)/libamdis_la-ElementData.Tpo" -c -o libamdis_la-ElementData.lo `test -f '$(SOURCE_DIR)/ElementData.cc' || echo '$(srcdir)/'`$(SOURCE_DIR)/ElementData.cc; \ +@am__fastdepCXX_TRUE@ then mv -f "$(DEPDIR)/libamdis_la-ElementData.Tpo" "$(DEPDIR)/libamdis_la-ElementData.Plo"; else rm -f "$(DEPDIR)/libamdis_la-ElementData.Tpo"; exit 1; fi +@AMDEP_TRUE@@am__fastdepCXX_FALSE@ source='$(SOURCE_DIR)/ElementData.cc' object='libamdis_la-ElementData.lo' libtool=yes @AMDEPBACKSLASH@ +@AMDEP_TRUE@@am__fastdepCXX_FALSE@ DEPDIR=$(DEPDIR) $(CXXDEPMODE) $(depcomp) @AMDEPBACKSLASH@ +@am__fastdepCXX_FALSE@ $(LIBTOOL) --tag=CXX --mode=compile $(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(libamdis_la_CXXFLAGS) $(CXXFLAGS) -c -o libamdis_la-ElementData.lo `test -f '$(SOURCE_DIR)/ElementData.cc' || echo '$(srcdir)/'`$(SOURCE_DIR)/ElementData.cc + +libamdis_la-CreatorMap.lo: $(SOURCE_DIR)/CreatorMap.cc +@am__fastdepCXX_TRUE@ if $(LIBTOOL) --tag=CXX --mode=compile $(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(libamdis_la_CXXFLAGS) $(CXXFLAGS) -MT libamdis_la-CreatorMap.lo -MD -MP -MF "$(DEPDIR)/libamdis_la-CreatorMap.Tpo" -c -o libamdis_la-CreatorMap.lo `test -f '$(SOURCE_DIR)/CreatorMap.cc' || echo '$(srcdir)/'`$(SOURCE_DIR)/CreatorMap.cc; \ +@am__fastdepCXX_TRUE@ then mv -f "$(DEPDIR)/libamdis_la-CreatorMap.Tpo" "$(DEPDIR)/libamdis_la-CreatorMap.Plo"; else rm -f "$(DEPDIR)/libamdis_la-CreatorMap.Tpo"; exit 1; fi +@AMDEP_TRUE@@am__fastdepCXX_FALSE@ source='$(SOURCE_DIR)/CreatorMap.cc' object='libamdis_la-CreatorMap.lo' libtool=yes @AMDEPBACKSLASH@ +@AMDEP_TRUE@@am__fastdepCXX_FALSE@ DEPDIR=$(DEPDIR) $(CXXDEPMODE) $(depcomp) @AMDEPBACKSLASH@ +@am__fastdepCXX_FALSE@ $(LIBTOOL) --tag=CXX --mode=compile $(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(libamdis_la_CXXFLAGS) $(CXXFLAGS) -c -o libamdis_la-CreatorMap.lo `test -f '$(SOURCE_DIR)/CreatorMap.cc' || echo '$(srcdir)/'`$(SOURCE_DIR)/CreatorMap.cc + +libamdis_la-ProblemInterpolScal.lo: $(SOURCE_DIR)/ProblemInterpolScal.cc +@am__fastdepCXX_TRUE@ if $(LIBTOOL) --tag=CXX --mode=compile $(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(libamdis_la_CXXFLAGS) $(CXXFLAGS) -MT libamdis_la-ProblemInterpolScal.lo -MD -MP -MF "$(DEPDIR)/libamdis_la-ProblemInterpolScal.Tpo" -c -o libamdis_la-ProblemInterpolScal.lo `test -f '$(SOURCE_DIR)/ProblemInterpolScal.cc' || echo '$(srcdir)/'`$(SOURCE_DIR)/ProblemInterpolScal.cc; \ +@am__fastdepCXX_TRUE@ then mv -f "$(DEPDIR)/libamdis_la-ProblemInterpolScal.Tpo" "$(DEPDIR)/libamdis_la-ProblemInterpolScal.Plo"; else rm -f "$(DEPDIR)/libamdis_la-ProblemInterpolScal.Tpo"; exit 1; fi +@AMDEP_TRUE@@am__fastdepCXX_FALSE@ source='$(SOURCE_DIR)/ProblemInterpolScal.cc' object='libamdis_la-ProblemInterpolScal.lo' libtool=yes @AMDEPBACKSLASH@ +@AMDEP_TRUE@@am__fastdepCXX_FALSE@ DEPDIR=$(DEPDIR) $(CXXDEPMODE) $(depcomp) @AMDEPBACKSLASH@ +@am__fastdepCXX_FALSE@ $(LIBTOOL) --tag=CXX --mode=compile $(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(libamdis_la_CXXFLAGS) $(CXXFLAGS) -c -o libamdis_la-ProblemInterpolScal.lo `test -f '$(SOURCE_DIR)/ProblemInterpolScal.cc' || echo '$(srcdir)/'`$(SOURCE_DIR)/ProblemInterpolScal.cc + +libamdis_la-ProblemInterpolVec.lo: $(SOURCE_DIR)/ProblemInterpolVec.cc +@am__fastdepCXX_TRUE@ if $(LIBTOOL) --tag=CXX --mode=compile $(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(libamdis_la_CXXFLAGS) $(CXXFLAGS) -MT libamdis_la-ProblemInterpolVec.lo -MD -MP -MF "$(DEPDIR)/libamdis_la-ProblemInterpolVec.Tpo" -c -o libamdis_la-ProblemInterpolVec.lo `test -f '$(SOURCE_DIR)/ProblemInterpolVec.cc' || echo '$(srcdir)/'`$(SOURCE_DIR)/ProblemInterpolVec.cc; \ +@am__fastdepCXX_TRUE@ then mv -f "$(DEPDIR)/libamdis_la-ProblemInterpolVec.Tpo" "$(DEPDIR)/libamdis_la-ProblemInterpolVec.Plo"; else rm -f "$(DEPDIR)/libamdis_la-ProblemInterpolVec.Tpo"; exit 1; fi +@AMDEP_TRUE@@am__fastdepCXX_FALSE@ source='$(SOURCE_DIR)/ProblemInterpolVec.cc' object='libamdis_la-ProblemInterpolVec.lo' libtool=yes @AMDEPBACKSLASH@ +@AMDEP_TRUE@@am__fastdepCXX_FALSE@ DEPDIR=$(DEPDIR) $(CXXDEPMODE) $(depcomp) @AMDEPBACKSLASH@ +@am__fastdepCXX_FALSE@ $(LIBTOOL) --tag=CXX --mode=compile $(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(libamdis_la_CXXFLAGS) $(CXXFLAGS) -c -o libamdis_la-ProblemInterpolVec.lo `test -f '$(SOURCE_DIR)/ProblemInterpolVec.cc' || echo '$(srcdir)/'`$(SOURCE_DIR)/ProblemInterpolVec.cc + +libamdis_la-MacroReader.lo: $(SOURCE_DIR)/MacroReader.cc +@am__fastdepCXX_TRUE@ if $(LIBTOOL) --tag=CXX --mode=compile $(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(libamdis_la_CXXFLAGS) $(CXXFLAGS) -MT libamdis_la-MacroReader.lo -MD -MP -MF "$(DEPDIR)/libamdis_la-MacroReader.Tpo" -c -o libamdis_la-MacroReader.lo `test -f '$(SOURCE_DIR)/MacroReader.cc' || echo '$(srcdir)/'`$(SOURCE_DIR)/MacroReader.cc; \ +@am__fastdepCXX_TRUE@ then mv -f "$(DEPDIR)/libamdis_la-MacroReader.Tpo" "$(DEPDIR)/libamdis_la-MacroReader.Plo"; else rm -f "$(DEPDIR)/libamdis_la-MacroReader.Tpo"; exit 1; fi +@AMDEP_TRUE@@am__fastdepCXX_FALSE@ source='$(SOURCE_DIR)/MacroReader.cc' object='libamdis_la-MacroReader.lo' libtool=yes @AMDEPBACKSLASH@ +@AMDEP_TRUE@@am__fastdepCXX_FALSE@ DEPDIR=$(DEPDIR) $(CXXDEPMODE) $(depcomp) @AMDEPBACKSLASH@ +@am__fastdepCXX_FALSE@ $(LIBTOOL) --tag=CXX --mode=compile $(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(libamdis_la_CXXFLAGS) $(CXXFLAGS) -c -o libamdis_la-MacroReader.lo `test -f '$(SOURCE_DIR)/MacroReader.cc' || echo '$(srcdir)/'`$(SOURCE_DIR)/MacroReader.cc + +libamdis_la-ValueReader.lo: $(SOURCE_DIR)/ValueReader.cc +@am__fastdepCXX_TRUE@ if $(LIBTOOL) --tag=CXX --mode=compile $(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(libamdis_la_CXXFLAGS) $(CXXFLAGS) -MT libamdis_la-ValueReader.lo -MD -MP -MF "$(DEPDIR)/libamdis_la-ValueReader.Tpo" -c -o libamdis_la-ValueReader.lo `test -f '$(SOURCE_DIR)/ValueReader.cc' || echo '$(srcdir)/'`$(SOURCE_DIR)/ValueReader.cc; \ +@am__fastdepCXX_TRUE@ then mv -f "$(DEPDIR)/libamdis_la-ValueReader.Tpo" "$(DEPDIR)/libamdis_la-ValueReader.Plo"; else rm -f "$(DEPDIR)/libamdis_la-ValueReader.Tpo"; exit 1; fi +@AMDEP_TRUE@@am__fastdepCXX_FALSE@ source='$(SOURCE_DIR)/ValueReader.cc' object='libamdis_la-ValueReader.lo' libtool=yes @AMDEPBACKSLASH@ +@AMDEP_TRUE@@am__fastdepCXX_FALSE@ DEPDIR=$(DEPDIR) $(CXXDEPMODE) $(depcomp) @AMDEPBACKSLASH@ +@am__fastdepCXX_FALSE@ $(LIBTOOL) --tag=CXX --mode=compile $(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(libamdis_la_CXXFLAGS) $(CXXFLAGS) -c -o libamdis_la-ValueReader.lo `test -f '$(SOURCE_DIR)/ValueReader.cc' || echo '$(srcdir)/'`$(SOURCE_DIR)/ValueReader.cc + +libamdis_la-Projection.lo: $(SOURCE_DIR)/Projection.cc +@am__fastdepCXX_TRUE@ if $(LIBTOOL) --tag=CXX --mode=compile $(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(libamdis_la_CXXFLAGS) $(CXXFLAGS) -MT libamdis_la-Projection.lo -MD -MP -MF "$(DEPDIR)/libamdis_la-Projection.Tpo" -c -o libamdis_la-Projection.lo `test -f '$(SOURCE_DIR)/Projection.cc' || echo '$(srcdir)/'`$(SOURCE_DIR)/Projection.cc; \ +@am__fastdepCXX_TRUE@ then mv -f "$(DEPDIR)/libamdis_la-Projection.Tpo" "$(DEPDIR)/libamdis_la-Projection.Plo"; else rm -f "$(DEPDIR)/libamdis_la-Projection.Tpo"; exit 1; fi +@AMDEP_TRUE@@am__fastdepCXX_FALSE@ source='$(SOURCE_DIR)/Projection.cc' object='libamdis_la-Projection.lo' libtool=yes @AMDEPBACKSLASH@ +@AMDEP_TRUE@@am__fastdepCXX_FALSE@ DEPDIR=$(DEPDIR) $(CXXDEPMODE) $(depcomp) @AMDEPBACKSLASH@ +@am__fastdepCXX_FALSE@ $(LIBTOOL) --tag=CXX --mode=compile $(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(libamdis_la_CXXFLAGS) $(CXXFLAGS) -c -o libamdis_la-Projection.lo `test -f '$(SOURCE_DIR)/Projection.cc' || echo '$(srcdir)/'`$(SOURCE_DIR)/Projection.cc + +libamdis_la-Assembler.lo: $(SOURCE_DIR)/Assembler.cc +@am__fastdepCXX_TRUE@ if $(LIBTOOL) --tag=CXX --mode=compile $(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(libamdis_la_CXXFLAGS) $(CXXFLAGS) -MT libamdis_la-Assembler.lo -MD -MP -MF "$(DEPDIR)/libamdis_la-Assembler.Tpo" -c -o libamdis_la-Assembler.lo `test -f '$(SOURCE_DIR)/Assembler.cc' || echo '$(srcdir)/'`$(SOURCE_DIR)/Assembler.cc; \ +@am__fastdepCXX_TRUE@ then mv -f "$(DEPDIR)/libamdis_la-Assembler.Tpo" "$(DEPDIR)/libamdis_la-Assembler.Plo"; else rm -f "$(DEPDIR)/libamdis_la-Assembler.Tpo"; exit 1; fi +@AMDEP_TRUE@@am__fastdepCXX_FALSE@ source='$(SOURCE_DIR)/Assembler.cc' object='libamdis_la-Assembler.lo' libtool=yes @AMDEPBACKSLASH@ +@AMDEP_TRUE@@am__fastdepCXX_FALSE@ DEPDIR=$(DEPDIR) $(CXXDEPMODE) $(depcomp) @AMDEPBACKSLASH@ +@am__fastdepCXX_FALSE@ $(LIBTOOL) --tag=CXX --mode=compile $(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(libamdis_la_CXXFLAGS) $(CXXFLAGS) -c -o libamdis_la-Assembler.lo `test -f '$(SOURCE_DIR)/Assembler.cc' || echo '$(srcdir)/'`$(SOURCE_DIR)/Assembler.cc + +libamdis_la-AdaptInfo.lo: $(SOURCE_DIR)/AdaptInfo.cc +@am__fastdepCXX_TRUE@ if $(LIBTOOL) --tag=CXX --mode=compile $(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(libamdis_la_CXXFLAGS) $(CXXFLAGS) -MT libamdis_la-AdaptInfo.lo -MD -MP -MF "$(DEPDIR)/libamdis_la-AdaptInfo.Tpo" -c -o libamdis_la-AdaptInfo.lo `test -f '$(SOURCE_DIR)/AdaptInfo.cc' || echo '$(srcdir)/'`$(SOURCE_DIR)/AdaptInfo.cc; \ +@am__fastdepCXX_TRUE@ then mv -f "$(DEPDIR)/libamdis_la-AdaptInfo.Tpo" "$(DEPDIR)/libamdis_la-AdaptInfo.Plo"; else rm -f "$(DEPDIR)/libamdis_la-AdaptInfo.Tpo"; exit 1; fi +@AMDEP_TRUE@@am__fastdepCXX_FALSE@ source='$(SOURCE_DIR)/AdaptInfo.cc' object='libamdis_la-AdaptInfo.lo' libtool=yes @AMDEPBACKSLASH@ +@AMDEP_TRUE@@am__fastdepCXX_FALSE@ DEPDIR=$(DEPDIR) $(CXXDEPMODE) $(depcomp) @AMDEPBACKSLASH@ +@am__fastdepCXX_FALSE@ $(LIBTOOL) --tag=CXX --mode=compile $(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(libamdis_la_CXXFLAGS) $(CXXFLAGS) -c -o libamdis_la-AdaptInfo.lo `test -f '$(SOURCE_DIR)/AdaptInfo.cc' || echo '$(srcdir)/'`$(SOURCE_DIR)/AdaptInfo.cc + +libamdis_la-Marker.lo: $(SOURCE_DIR)/Marker.cc +@am__fastdepCXX_TRUE@ if $(LIBTOOL) --tag=CXX --mode=compile $(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(libamdis_la_CXXFLAGS) $(CXXFLAGS) -MT libamdis_la-Marker.lo -MD -MP -MF "$(DEPDIR)/libamdis_la-Marker.Tpo" -c -o libamdis_la-Marker.lo `test -f '$(SOURCE_DIR)/Marker.cc' || echo '$(srcdir)/'`$(SOURCE_DIR)/Marker.cc; \ +@am__fastdepCXX_TRUE@ then mv -f "$(DEPDIR)/libamdis_la-Marker.Tpo" "$(DEPDIR)/libamdis_la-Marker.Plo"; else rm -f "$(DEPDIR)/libamdis_la-Marker.Tpo"; exit 1; fi +@AMDEP_TRUE@@am__fastdepCXX_FALSE@ source='$(SOURCE_DIR)/Marker.cc' object='libamdis_la-Marker.lo' libtool=yes @AMDEPBACKSLASH@ +@AMDEP_TRUE@@am__fastdepCXX_FALSE@ DEPDIR=$(DEPDIR) $(CXXDEPMODE) $(depcomp) @AMDEPBACKSLASH@ +@am__fastdepCXX_FALSE@ $(LIBTOOL) --tag=CXX --mode=compile $(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(libamdis_la_CXXFLAGS) $(CXXFLAGS) -c -o libamdis_la-Marker.lo `test -f '$(SOURCE_DIR)/Marker.cc' || echo '$(srcdir)/'`$(SOURCE_DIR)/Marker.cc + +libamdis_la-MatrixVector.lo: $(SOURCE_DIR)/MatrixVector.cc +@am__fastdepCXX_TRUE@ if $(LIBTOOL) --tag=CXX --mode=compile $(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(libamdis_la_CXXFLAGS) $(CXXFLAGS) -MT libamdis_la-MatrixVector.lo -MD -MP -MF "$(DEPDIR)/libamdis_la-MatrixVector.Tpo" -c -o libamdis_la-MatrixVector.lo `test -f '$(SOURCE_DIR)/MatrixVector.cc' || echo '$(srcdir)/'`$(SOURCE_DIR)/MatrixVector.cc; \ +@am__fastdepCXX_TRUE@ then mv -f "$(DEPDIR)/libamdis_la-MatrixVector.Tpo" "$(DEPDIR)/libamdis_la-MatrixVector.Plo"; else rm -f "$(DEPDIR)/libamdis_la-MatrixVector.Tpo"; exit 1; fi +@AMDEP_TRUE@@am__fastdepCXX_FALSE@ source='$(SOURCE_DIR)/MatrixVector.cc' object='libamdis_la-MatrixVector.lo' libtool=yes @AMDEPBACKSLASH@ +@AMDEP_TRUE@@am__fastdepCXX_FALSE@ DEPDIR=$(DEPDIR) $(CXXDEPMODE) $(depcomp) @AMDEPBACKSLASH@ +@am__fastdepCXX_FALSE@ $(LIBTOOL) --tag=CXX --mode=compile $(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(libamdis_la_CXXFLAGS) $(CXXFLAGS) -c -o libamdis_la-MatrixVector.lo `test -f '$(SOURCE_DIR)/MatrixVector.cc' || echo '$(srcdir)/'`$(SOURCE_DIR)/MatrixVector.cc + +libamdis_la-SurfaceQuadrature.lo: $(SOURCE_DIR)/SurfaceQuadrature.cc +@am__fastdepCXX_TRUE@ if $(LIBTOOL) --tag=CXX --mode=compile $(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(libamdis_la_CXXFLAGS) $(CXXFLAGS) -MT libamdis_la-SurfaceQuadrature.lo -MD -MP -MF "$(DEPDIR)/libamdis_la-SurfaceQuadrature.Tpo" -c -o libamdis_la-SurfaceQuadrature.lo `test -f '$(SOURCE_DIR)/SurfaceQuadrature.cc' || echo '$(srcdir)/'`$(SOURCE_DIR)/SurfaceQuadrature.cc; \ +@am__fastdepCXX_TRUE@ then mv -f "$(DEPDIR)/libamdis_la-SurfaceQuadrature.Tpo" "$(DEPDIR)/libamdis_la-SurfaceQuadrature.Plo"; else rm -f "$(DEPDIR)/libamdis_la-SurfaceQuadrature.Tpo"; exit 1; fi +@AMDEP_TRUE@@am__fastdepCXX_FALSE@ source='$(SOURCE_DIR)/SurfaceQuadrature.cc' object='libamdis_la-SurfaceQuadrature.lo' libtool=yes @AMDEPBACKSLASH@ +@AMDEP_TRUE@@am__fastdepCXX_FALSE@ DEPDIR=$(DEPDIR) $(CXXDEPMODE) $(depcomp) @AMDEPBACKSLASH@ +@am__fastdepCXX_FALSE@ $(LIBTOOL) --tag=CXX --mode=compile $(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(libamdis_la_CXXFLAGS) $(CXXFLAGS) -c -o libamdis_la-SurfaceQuadrature.lo `test -f '$(SOURCE_DIR)/SurfaceQuadrature.cc' || echo '$(srcdir)/'`$(SOURCE_DIR)/SurfaceQuadrature.cc + +libamdis_la-LeafData.lo: $(SOURCE_DIR)/LeafData.cc +@am__fastdepCXX_TRUE@ if $(LIBTOOL) --tag=CXX --mode=compile $(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(libamdis_la_CXXFLAGS) $(CXXFLAGS) -MT libamdis_la-LeafData.lo -MD -MP -MF "$(DEPDIR)/libamdis_la-LeafData.Tpo" -c -o libamdis_la-LeafData.lo `test -f '$(SOURCE_DIR)/LeafData.cc' || echo '$(srcdir)/'`$(SOURCE_DIR)/LeafData.cc; \ +@am__fastdepCXX_TRUE@ then mv -f "$(DEPDIR)/libamdis_la-LeafData.Tpo" "$(DEPDIR)/libamdis_la-LeafData.Plo"; else rm -f "$(DEPDIR)/libamdis_la-LeafData.Tpo"; exit 1; fi +@AMDEP_TRUE@@am__fastdepCXX_FALSE@ source='$(SOURCE_DIR)/LeafData.cc' object='libamdis_la-LeafData.lo' libtool=yes @AMDEPBACKSLASH@ +@AMDEP_TRUE@@am__fastdepCXX_FALSE@ DEPDIR=$(DEPDIR) $(CXXDEPMODE) $(depcomp) @AMDEPBACKSLASH@ +@am__fastdepCXX_FALSE@ $(LIBTOOL) --tag=CXX --mode=compile $(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(libamdis_la_CXXFLAGS) $(CXXFLAGS) -c -o libamdis_la-LeafData.lo `test -f '$(SOURCE_DIR)/LeafData.cc' || echo '$(srcdir)/'`$(SOURCE_DIR)/LeafData.cc + +libamdis_la-BoundaryManager.lo: $(SOURCE_DIR)/BoundaryManager.cc +@am__fastdepCXX_TRUE@ if $(LIBTOOL) --tag=CXX --mode=compile $(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(libamdis_la_CXXFLAGS) $(CXXFLAGS) -MT libamdis_la-BoundaryManager.lo -MD -MP -MF "$(DEPDIR)/libamdis_la-BoundaryManager.Tpo" -c -o libamdis_la-BoundaryManager.lo `test -f '$(SOURCE_DIR)/BoundaryManager.cc' || echo '$(srcdir)/'`$(SOURCE_DIR)/BoundaryManager.cc; \ +@am__fastdepCXX_TRUE@ then mv -f "$(DEPDIR)/libamdis_la-BoundaryManager.Tpo" "$(DEPDIR)/libamdis_la-BoundaryManager.Plo"; else rm -f "$(DEPDIR)/libamdis_la-BoundaryManager.Tpo"; exit 1; fi +@AMDEP_TRUE@@am__fastdepCXX_FALSE@ source='$(SOURCE_DIR)/BoundaryManager.cc' object='libamdis_la-BoundaryManager.lo' libtool=yes @AMDEPBACKSLASH@ +@AMDEP_TRUE@@am__fastdepCXX_FALSE@ DEPDIR=$(DEPDIR) $(CXXDEPMODE) $(depcomp) @AMDEPBACKSLASH@ +@am__fastdepCXX_FALSE@ $(LIBTOOL) --tag=CXX --mode=compile $(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(libamdis_la_CXXFLAGS) $(CXXFLAGS) -c -o libamdis_la-BoundaryManager.lo `test -f '$(SOURCE_DIR)/BoundaryManager.cc' || echo '$(srcdir)/'`$(SOURCE_DIR)/BoundaryManager.cc + +libamdis_la-DirichletBC.lo: $(SOURCE_DIR)/DirichletBC.cc +@am__fastdepCXX_TRUE@ if $(LIBTOOL) --tag=CXX --mode=compile $(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(libamdis_la_CXXFLAGS) $(CXXFLAGS) -MT libamdis_la-DirichletBC.lo -MD -MP -MF "$(DEPDIR)/libamdis_la-DirichletBC.Tpo" -c -o libamdis_la-DirichletBC.lo `test -f '$(SOURCE_DIR)/DirichletBC.cc' || echo '$(srcdir)/'`$(SOURCE_DIR)/DirichletBC.cc; \ +@am__fastdepCXX_TRUE@ then mv -f "$(DEPDIR)/libamdis_la-DirichletBC.Tpo" "$(DEPDIR)/libamdis_la-DirichletBC.Plo"; else rm -f "$(DEPDIR)/libamdis_la-DirichletBC.Tpo"; exit 1; fi +@AMDEP_TRUE@@am__fastdepCXX_FALSE@ source='$(SOURCE_DIR)/DirichletBC.cc' object='libamdis_la-DirichletBC.lo' libtool=yes @AMDEPBACKSLASH@ +@AMDEP_TRUE@@am__fastdepCXX_FALSE@ DEPDIR=$(DEPDIR) $(CXXDEPMODE) $(depcomp) @AMDEPBACKSLASH@ +@am__fastdepCXX_FALSE@ $(LIBTOOL) --tag=CXX --mode=compile $(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(libamdis_la_CXXFLAGS) $(CXXFLAGS) -c -o libamdis_la-DirichletBC.lo `test -f '$(SOURCE_DIR)/DirichletBC.cc' || echo '$(srcdir)/'`$(SOURCE_DIR)/DirichletBC.cc + +libamdis_la-RobinBC.lo: $(SOURCE_DIR)/RobinBC.cc +@am__fastdepCXX_TRUE@ if $(LIBTOOL) --tag=CXX --mode=compile $(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(libamdis_la_CXXFLAGS) $(CXXFLAGS) -MT libamdis_la-RobinBC.lo -MD -MP -MF "$(DEPDIR)/libamdis_la-RobinBC.Tpo" -c -o libamdis_la-RobinBC.lo `test -f '$(SOURCE_DIR)/RobinBC.cc' || echo '$(srcdir)/'`$(SOURCE_DIR)/RobinBC.cc; \ +@am__fastdepCXX_TRUE@ then mv -f "$(DEPDIR)/libamdis_la-RobinBC.Tpo" "$(DEPDIR)/libamdis_la-RobinBC.Plo"; else rm -f "$(DEPDIR)/libamdis_la-RobinBC.Tpo"; exit 1; fi +@AMDEP_TRUE@@am__fastdepCXX_FALSE@ source='$(SOURCE_DIR)/RobinBC.cc' object='libamdis_la-RobinBC.lo' libtool=yes @AMDEPBACKSLASH@ +@AMDEP_TRUE@@am__fastdepCXX_FALSE@ DEPDIR=$(DEPDIR) $(CXXDEPMODE) $(depcomp) @AMDEPBACKSLASH@ +@am__fastdepCXX_FALSE@ $(LIBTOOL) --tag=CXX --mode=compile $(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(libamdis_la_CXXFLAGS) $(CXXFLAGS) -c -o libamdis_la-RobinBC.lo `test -f '$(SOURCE_DIR)/RobinBC.cc' || echo '$(srcdir)/'`$(SOURCE_DIR)/RobinBC.cc + +libamdis_la-MatVecMultiplier.lo: $(SOURCE_DIR)/MatVecMultiplier.cc +@am__fastdepCXX_TRUE@ if $(LIBTOOL) --tag=CXX --mode=compile $(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(libamdis_la_CXXFLAGS) $(CXXFLAGS) -MT libamdis_la-MatVecMultiplier.lo -MD -MP -MF "$(DEPDIR)/libamdis_la-MatVecMultiplier.Tpo" -c -o libamdis_la-MatVecMultiplier.lo `test -f '$(SOURCE_DIR)/MatVecMultiplier.cc' || echo '$(srcdir)/'`$(SOURCE_DIR)/MatVecMultiplier.cc; \ +@am__fastdepCXX_TRUE@ then mv -f "$(DEPDIR)/libamdis_la-MatVecMultiplier.Tpo" "$(DEPDIR)/libamdis_la-MatVecMultiplier.Plo"; else rm -f "$(DEPDIR)/libamdis_la-MatVecMultiplier.Tpo"; exit 1; fi +@AMDEP_TRUE@@am__fastdepCXX_FALSE@ source='$(SOURCE_DIR)/MatVecMultiplier.cc' object='libamdis_la-MatVecMultiplier.lo' libtool=yes @AMDEPBACKSLASH@ +@AMDEP_TRUE@@am__fastdepCXX_FALSE@ DEPDIR=$(DEPDIR) $(CXXDEPMODE) $(depcomp) @AMDEPBACKSLASH@ +@am__fastdepCXX_FALSE@ $(LIBTOOL) --tag=CXX --mode=compile $(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(libamdis_la_CXXFLAGS) $(CXXFLAGS) -c -o libamdis_la-MatVecMultiplier.lo `test -f '$(SOURCE_DIR)/MatVecMultiplier.cc' || echo '$(srcdir)/'`$(SOURCE_DIR)/MatVecMultiplier.cc + +libamdis_la-FileWriter.lo: $(SOURCE_DIR)/FileWriter.cc +@am__fastdepCXX_TRUE@ if $(LIBTOOL) --tag=CXX --mode=compile $(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(libamdis_la_CXXFLAGS) $(CXXFLAGS) -MT libamdis_la-FileWriter.lo -MD -MP -MF "$(DEPDIR)/libamdis_la-FileWriter.Tpo" -c -o libamdis_la-FileWriter.lo `test -f '$(SOURCE_DIR)/FileWriter.cc' || echo '$(srcdir)/'`$(SOURCE_DIR)/FileWriter.cc; \ +@am__fastdepCXX_TRUE@ then mv -f "$(DEPDIR)/libamdis_la-FileWriter.Tpo" "$(DEPDIR)/libamdis_la-FileWriter.Plo"; else rm -f "$(DEPDIR)/libamdis_la-FileWriter.Tpo"; exit 1; fi +@AMDEP_TRUE@@am__fastdepCXX_FALSE@ source='$(SOURCE_DIR)/FileWriter.cc' object='libamdis_la-FileWriter.lo' libtool=yes @AMDEPBACKSLASH@ +@AMDEP_TRUE@@am__fastdepCXX_FALSE@ DEPDIR=$(DEPDIR) $(CXXDEPMODE) $(depcomp) @AMDEPBACKSLASH@ +@am__fastdepCXX_FALSE@ $(LIBTOOL) --tag=CXX --mode=compile $(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(libamdis_la_CXXFLAGS) $(CXXFLAGS) -c -o libamdis_la-FileWriter.lo `test -f '$(SOURCE_DIR)/FileWriter.cc' || echo '$(srcdir)/'`$(SOURCE_DIR)/FileWriter.cc + +libamdis_la-ElInfo.lo: $(SOURCE_DIR)/ElInfo.cc +@am__fastdepCXX_TRUE@ if $(LIBTOOL) --tag=CXX --mode=compile $(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(libamdis_la_CXXFLAGS) $(CXXFLAGS) -MT libamdis_la-ElInfo.lo -MD -MP -MF "$(DEPDIR)/libamdis_la-ElInfo.Tpo" -c -o libamdis_la-ElInfo.lo `test -f '$(SOURCE_DIR)/ElInfo.cc' || echo '$(srcdir)/'`$(SOURCE_DIR)/ElInfo.cc; \ +@am__fastdepCXX_TRUE@ then mv -f "$(DEPDIR)/libamdis_la-ElInfo.Tpo" "$(DEPDIR)/libamdis_la-ElInfo.Plo"; else rm -f "$(DEPDIR)/libamdis_la-ElInfo.Tpo"; exit 1; fi +@AMDEP_TRUE@@am__fastdepCXX_FALSE@ source='$(SOURCE_DIR)/ElInfo.cc' object='libamdis_la-ElInfo.lo' libtool=yes @AMDEPBACKSLASH@ +@AMDEP_TRUE@@am__fastdepCXX_FALSE@ DEPDIR=$(DEPDIR) $(CXXDEPMODE) $(depcomp) @AMDEPBACKSLASH@ +@am__fastdepCXX_FALSE@ $(LIBTOOL) --tag=CXX --mode=compile $(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(libamdis_la_CXXFLAGS) $(CXXFLAGS) -c -o libamdis_la-ElInfo.lo `test -f '$(SOURCE_DIR)/ElInfo.cc' || echo '$(srcdir)/'`$(SOURCE_DIR)/ElInfo.cc + +libamdis_la-Operator.lo: $(SOURCE_DIR)/Operator.cc +@am__fastdepCXX_TRUE@ if $(LIBTOOL) --tag=CXX --mode=compile $(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(libamdis_la_CXXFLAGS) $(CXXFLAGS) -MT libamdis_la-Operator.lo -MD -MP -MF "$(DEPDIR)/libamdis_la-Operator.Tpo" -c -o libamdis_la-Operator.lo `test -f '$(SOURCE_DIR)/Operator.cc' || echo '$(srcdir)/'`$(SOURCE_DIR)/Operator.cc; \ +@am__fastdepCXX_TRUE@ then mv -f "$(DEPDIR)/libamdis_la-Operator.Tpo" "$(DEPDIR)/libamdis_la-Operator.Plo"; else rm -f "$(DEPDIR)/libamdis_la-Operator.Tpo"; exit 1; fi +@AMDEP_TRUE@@am__fastdepCXX_FALSE@ source='$(SOURCE_DIR)/Operator.cc' object='libamdis_la-Operator.lo' libtool=yes @AMDEPBACKSLASH@ +@AMDEP_TRUE@@am__fastdepCXX_FALSE@ DEPDIR=$(DEPDIR) $(CXXDEPMODE) $(depcomp) @AMDEPBACKSLASH@ +@am__fastdepCXX_FALSE@ $(LIBTOOL) --tag=CXX --mode=compile $(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(libamdis_la_CXXFLAGS) $(CXXFLAGS) -c -o libamdis_la-Operator.lo `test -f '$(SOURCE_DIR)/Operator.cc' || echo '$(srcdir)/'`$(SOURCE_DIR)/Operator.cc + +libamdis_la-Mesh.lo: $(SOURCE_DIR)/Mesh.cc +@am__fastdepCXX_TRUE@ if $(LIBTOOL) --tag=CXX --mode=compile $(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(libamdis_la_CXXFLAGS) $(CXXFLAGS) -MT libamdis_la-Mesh.lo -MD -MP -MF "$(DEPDIR)/libamdis_la-Mesh.Tpo" -c -o libamdis_la-Mesh.lo `test -f '$(SOURCE_DIR)/Mesh.cc' || echo '$(srcdir)/'`$(SOURCE_DIR)/Mesh.cc; \ +@am__fastdepCXX_TRUE@ then mv -f "$(DEPDIR)/libamdis_la-Mesh.Tpo" "$(DEPDIR)/libamdis_la-Mesh.Plo"; else rm -f "$(DEPDIR)/libamdis_la-Mesh.Tpo"; exit 1; fi +@AMDEP_TRUE@@am__fastdepCXX_FALSE@ source='$(SOURCE_DIR)/Mesh.cc' object='libamdis_la-Mesh.lo' libtool=yes @AMDEPBACKSLASH@ +@AMDEP_TRUE@@am__fastdepCXX_FALSE@ DEPDIR=$(DEPDIR) $(CXXDEPMODE) $(depcomp) @AMDEPBACKSLASH@ +@am__fastdepCXX_FALSE@ $(LIBTOOL) --tag=CXX --mode=compile $(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(libamdis_la_CXXFLAGS) $(CXXFLAGS) -c -o libamdis_la-Mesh.lo `test -f '$(SOURCE_DIR)/Mesh.cc' || echo '$(srcdir)/'`$(SOURCE_DIR)/Mesh.cc + +libamdis_la-AdaptStationary.lo: $(SOURCE_DIR)/AdaptStationary.cc +@am__fastdepCXX_TRUE@ if $(LIBTOOL) --tag=CXX --mode=compile $(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(libamdis_la_CXXFLAGS) $(CXXFLAGS) -MT libamdis_la-AdaptStationary.lo -MD -MP -MF "$(DEPDIR)/libamdis_la-AdaptStationary.Tpo" -c -o libamdis_la-AdaptStationary.lo `test -f '$(SOURCE_DIR)/AdaptStationary.cc' || echo '$(srcdir)/'`$(SOURCE_DIR)/AdaptStationary.cc; \ +@am__fastdepCXX_TRUE@ then mv -f "$(DEPDIR)/libamdis_la-AdaptStationary.Tpo" "$(DEPDIR)/libamdis_la-AdaptStationary.Plo"; else rm -f "$(DEPDIR)/libamdis_la-AdaptStationary.Tpo"; exit 1; fi +@AMDEP_TRUE@@am__fastdepCXX_FALSE@ source='$(SOURCE_DIR)/AdaptStationary.cc' object='libamdis_la-AdaptStationary.lo' libtool=yes @AMDEPBACKSLASH@ +@AMDEP_TRUE@@am__fastdepCXX_FALSE@ DEPDIR=$(DEPDIR) $(CXXDEPMODE) $(depcomp) @AMDEPBACKSLASH@ +@am__fastdepCXX_FALSE@ $(LIBTOOL) --tag=CXX --mode=compile $(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(libamdis_la_CXXFLAGS) $(CXXFLAGS) -c -o libamdis_la-AdaptStationary.lo `test -f '$(SOURCE_DIR)/AdaptStationary.cc' || echo '$(srcdir)/'`$(SOURCE_DIR)/AdaptStationary.cc + +libamdis_la-AdaptInstationary.lo: $(SOURCE_DIR)/AdaptInstationary.cc +@am__fastdepCXX_TRUE@ if $(LIBTOOL) --tag=CXX --mode=compile $(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(libamdis_la_CXXFLAGS) $(CXXFLAGS) -MT libamdis_la-AdaptInstationary.lo -MD -MP -MF "$(DEPDIR)/libamdis_la-AdaptInstationary.Tpo" -c -o libamdis_la-AdaptInstationary.lo `test -f '$(SOURCE_DIR)/AdaptInstationary.cc' || echo '$(srcdir)/'`$(SOURCE_DIR)/AdaptInstationary.cc; \ +@am__fastdepCXX_TRUE@ then mv -f "$(DEPDIR)/libamdis_la-AdaptInstationary.Tpo" "$(DEPDIR)/libamdis_la-AdaptInstationary.Plo"; else rm -f "$(DEPDIR)/libamdis_la-AdaptInstationary.Tpo"; exit 1; fi +@AMDEP_TRUE@@am__fastdepCXX_FALSE@ source='$(SOURCE_DIR)/AdaptInstationary.cc' object='libamdis_la-AdaptInstationary.lo' libtool=yes @AMDEPBACKSLASH@ +@AMDEP_TRUE@@am__fastdepCXX_FALSE@ DEPDIR=$(DEPDIR) $(CXXDEPMODE) $(depcomp) @AMDEPBACKSLASH@ +@am__fastdepCXX_FALSE@ $(LIBTOOL) --tag=CXX --mode=compile $(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(libamdis_la_CXXFLAGS) $(CXXFLAGS) -c -o libamdis_la-AdaptInstationary.lo `test -f '$(SOURCE_DIR)/AdaptInstationary.cc' || echo '$(srcdir)/'`$(SOURCE_DIR)/AdaptInstationary.cc + +libamdis_la-DiagonalPreconditioner.lo: $(SOURCE_DIR)/DiagonalPreconditioner.cc +@am__fastdepCXX_TRUE@ if $(LIBTOOL) --tag=CXX --mode=compile $(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(libamdis_la_CXXFLAGS) $(CXXFLAGS) -MT libamdis_la-DiagonalPreconditioner.lo -MD -MP -MF "$(DEPDIR)/libamdis_la-DiagonalPreconditioner.Tpo" -c -o libamdis_la-DiagonalPreconditioner.lo `test -f '$(SOURCE_DIR)/DiagonalPreconditioner.cc' || echo '$(srcdir)/'`$(SOURCE_DIR)/DiagonalPreconditioner.cc; \ +@am__fastdepCXX_TRUE@ then mv -f "$(DEPDIR)/libamdis_la-DiagonalPreconditioner.Tpo" "$(DEPDIR)/libamdis_la-DiagonalPreconditioner.Plo"; else rm -f "$(DEPDIR)/libamdis_la-DiagonalPreconditioner.Tpo"; exit 1; fi +@AMDEP_TRUE@@am__fastdepCXX_FALSE@ source='$(SOURCE_DIR)/DiagonalPreconditioner.cc' object='libamdis_la-DiagonalPreconditioner.lo' libtool=yes @AMDEPBACKSLASH@ +@AMDEP_TRUE@@am__fastdepCXX_FALSE@ DEPDIR=$(DEPDIR) $(CXXDEPMODE) $(depcomp) @AMDEPBACKSLASH@ +@am__fastdepCXX_FALSE@ $(LIBTOOL) --tag=CXX --mode=compile $(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(libamdis_la_CXXFLAGS) $(CXXFLAGS) -c -o libamdis_la-DiagonalPreconditioner.lo `test -f '$(SOURCE_DIR)/DiagonalPreconditioner.cc' || echo '$(srcdir)/'`$(SOURCE_DIR)/DiagonalPreconditioner.cc + +libamdis_la-ILUPreconditioner.lo: $(SOURCE_DIR)/ILUPreconditioner.cc +@am__fastdepCXX_TRUE@ if $(LIBTOOL) --tag=CXX --mode=compile $(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(libamdis_la_CXXFLAGS) $(CXXFLAGS) -MT libamdis_la-ILUPreconditioner.lo -MD -MP -MF "$(DEPDIR)/libamdis_la-ILUPreconditioner.Tpo" -c -o libamdis_la-ILUPreconditioner.lo `test -f '$(SOURCE_DIR)/ILUPreconditioner.cc' || echo '$(srcdir)/'`$(SOURCE_DIR)/ILUPreconditioner.cc; \ +@am__fastdepCXX_TRUE@ then mv -f "$(DEPDIR)/libamdis_la-ILUPreconditioner.Tpo" "$(DEPDIR)/libamdis_la-ILUPreconditioner.Plo"; else rm -f "$(DEPDIR)/libamdis_la-ILUPreconditioner.Tpo"; exit 1; fi +@AMDEP_TRUE@@am__fastdepCXX_FALSE@ source='$(SOURCE_DIR)/ILUPreconditioner.cc' object='libamdis_la-ILUPreconditioner.lo' libtool=yes @AMDEPBACKSLASH@ +@AMDEP_TRUE@@am__fastdepCXX_FALSE@ DEPDIR=$(DEPDIR) $(CXXDEPMODE) $(depcomp) @AMDEPBACKSLASH@ +@am__fastdepCXX_FALSE@ $(LIBTOOL) --tag=CXX --mode=compile $(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(libamdis_la_CXXFLAGS) $(CXXFLAGS) -c -o libamdis_la-ILUPreconditioner.lo `test -f '$(SOURCE_DIR)/ILUPreconditioner.cc' || echo '$(srcdir)/'`$(SOURCE_DIR)/ILUPreconditioner.cc + +libamdis_la-ILUTPreconditioner.lo: $(SOURCE_DIR)/ILUTPreconditioner.cc +@am__fastdepCXX_TRUE@ if $(LIBTOOL) --tag=CXX --mode=compile $(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(libamdis_la_CXXFLAGS) $(CXXFLAGS) -MT libamdis_la-ILUTPreconditioner.lo -MD -MP -MF "$(DEPDIR)/libamdis_la-ILUTPreconditioner.Tpo" -c -o libamdis_la-ILUTPreconditioner.lo `test -f '$(SOURCE_DIR)/ILUTPreconditioner.cc' || echo '$(srcdir)/'`$(SOURCE_DIR)/ILUTPreconditioner.cc; \ +@am__fastdepCXX_TRUE@ then mv -f "$(DEPDIR)/libamdis_la-ILUTPreconditioner.Tpo" "$(DEPDIR)/libamdis_la-ILUTPreconditioner.Plo"; else rm -f "$(DEPDIR)/libamdis_la-ILUTPreconditioner.Tpo"; exit 1; fi +@AMDEP_TRUE@@am__fastdepCXX_FALSE@ source='$(SOURCE_DIR)/ILUTPreconditioner.cc' object='libamdis_la-ILUTPreconditioner.lo' libtool=yes @AMDEPBACKSLASH@ +@AMDEP_TRUE@@am__fastdepCXX_FALSE@ DEPDIR=$(DEPDIR) $(CXXDEPMODE) $(depcomp) @AMDEPBACKSLASH@ +@am__fastdepCXX_FALSE@ $(LIBTOOL) --tag=CXX --mode=compile $(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(libamdis_la_CXXFLAGS) $(CXXFLAGS) -c -o libamdis_la-ILUTPreconditioner.lo `test -f '$(SOURCE_DIR)/ILUTPreconditioner.cc' || echo '$(srcdir)/'`$(SOURCE_DIR)/ILUTPreconditioner.cc + +libamdis_la-DOFVector.lo: $(SOURCE_DIR)/DOFVector.cc +@am__fastdepCXX_TRUE@ if $(LIBTOOL) --tag=CXX --mode=compile $(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(libamdis_la_CXXFLAGS) $(CXXFLAGS) -MT libamdis_la-DOFVector.lo -MD -MP -MF "$(DEPDIR)/libamdis_la-DOFVector.Tpo" -c -o libamdis_la-DOFVector.lo `test -f '$(SOURCE_DIR)/DOFVector.cc' || echo '$(srcdir)/'`$(SOURCE_DIR)/DOFVector.cc; \ +@am__fastdepCXX_TRUE@ then mv -f "$(DEPDIR)/libamdis_la-DOFVector.Tpo" "$(DEPDIR)/libamdis_la-DOFVector.Plo"; else rm -f "$(DEPDIR)/libamdis_la-DOFVector.Tpo"; exit 1; fi +@AMDEP_TRUE@@am__fastdepCXX_FALSE@ source='$(SOURCE_DIR)/DOFVector.cc' object='libamdis_la-DOFVector.lo' libtool=yes @AMDEPBACKSLASH@ +@AMDEP_TRUE@@am__fastdepCXX_FALSE@ DEPDIR=$(DEPDIR) $(CXXDEPMODE) $(depcomp) @AMDEPBACKSLASH@ +@am__fastdepCXX_FALSE@ $(LIBTOOL) --tag=CXX --mode=compile $(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(libamdis_la_CXXFLAGS) $(CXXFLAGS) -c -o libamdis_la-DOFVector.lo `test -f '$(SOURCE_DIR)/DOFVector.cc' || echo '$(srcdir)/'`$(SOURCE_DIR)/DOFVector.cc + +libamdis_la-Estimator.lo: $(SOURCE_DIR)/Estimator.cc +@am__fastdepCXX_TRUE@ if $(LIBTOOL) --tag=CXX --mode=compile $(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(libamdis_la_CXXFLAGS) $(CXXFLAGS) -MT libamdis_la-Estimator.lo -MD -MP -MF "$(DEPDIR)/libamdis_la-Estimator.Tpo" -c -o libamdis_la-Estimator.lo `test -f '$(SOURCE_DIR)/Estimator.cc' || echo '$(srcdir)/'`$(SOURCE_DIR)/Estimator.cc; \ +@am__fastdepCXX_TRUE@ then mv -f "$(DEPDIR)/libamdis_la-Estimator.Tpo" "$(DEPDIR)/libamdis_la-Estimator.Plo"; else rm -f "$(DEPDIR)/libamdis_la-Estimator.Tpo"; exit 1; fi +@AMDEP_TRUE@@am__fastdepCXX_FALSE@ source='$(SOURCE_DIR)/Estimator.cc' object='libamdis_la-Estimator.lo' libtool=yes @AMDEPBACKSLASH@ +@AMDEP_TRUE@@am__fastdepCXX_FALSE@ DEPDIR=$(DEPDIR) $(CXXDEPMODE) $(depcomp) @AMDEPBACKSLASH@ +@am__fastdepCXX_FALSE@ $(LIBTOOL) --tag=CXX --mode=compile $(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(libamdis_la_CXXFLAGS) $(CXXFLAGS) -c -o libamdis_la-Estimator.lo `test -f '$(SOURCE_DIR)/Estimator.cc' || echo '$(srcdir)/'`$(SOURCE_DIR)/Estimator.cc + +libamdis_la-ProblemInstat.lo: $(SOURCE_DIR)/ProblemInstat.cc +@am__fastdepCXX_TRUE@ if $(LIBTOOL) --tag=CXX --mode=compile $(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(libamdis_la_CXXFLAGS) $(CXXFLAGS) -MT libamdis_la-ProblemInstat.lo -MD -MP -MF "$(DEPDIR)/libamdis_la-ProblemInstat.Tpo" -c -o libamdis_la-ProblemInstat.lo `test -f '$(SOURCE_DIR)/ProblemInstat.cc' || echo '$(srcdir)/'`$(SOURCE_DIR)/ProblemInstat.cc; \ +@am__fastdepCXX_TRUE@ then mv -f "$(DEPDIR)/libamdis_la-ProblemInstat.Tpo" "$(DEPDIR)/libamdis_la-ProblemInstat.Plo"; else rm -f "$(DEPDIR)/libamdis_la-ProblemInstat.Tpo"; exit 1; fi +@AMDEP_TRUE@@am__fastdepCXX_FALSE@ source='$(SOURCE_DIR)/ProblemInstat.cc' object='libamdis_la-ProblemInstat.lo' libtool=yes @AMDEPBACKSLASH@ +@AMDEP_TRUE@@am__fastdepCXX_FALSE@ DEPDIR=$(DEPDIR) $(CXXDEPMODE) $(depcomp) @AMDEPBACKSLASH@ +@am__fastdepCXX_FALSE@ $(LIBTOOL) --tag=CXX --mode=compile $(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(libamdis_la_CXXFLAGS) $(CXXFLAGS) -c -o libamdis_la-ProblemInstat.lo `test -f '$(SOURCE_DIR)/ProblemInstat.cc' || echo '$(srcdir)/'`$(SOURCE_DIR)/ProblemInstat.cc + +libamdis_la-ProblemNonLin.lo: $(SOURCE_DIR)/ProblemNonLin.cc +@am__fastdepCXX_TRUE@ if $(LIBTOOL) --tag=CXX --mode=compile $(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(libamdis_la_CXXFLAGS) $(CXXFLAGS) -MT libamdis_la-ProblemNonLin.lo -MD -MP -MF "$(DEPDIR)/libamdis_la-ProblemNonLin.Tpo" -c -o libamdis_la-ProblemNonLin.lo `test -f '$(SOURCE_DIR)/ProblemNonLin.cc' || echo '$(srcdir)/'`$(SOURCE_DIR)/ProblemNonLin.cc; \ +@am__fastdepCXX_TRUE@ then mv -f "$(DEPDIR)/libamdis_la-ProblemNonLin.Tpo" "$(DEPDIR)/libamdis_la-ProblemNonLin.Plo"; else rm -f "$(DEPDIR)/libamdis_la-ProblemNonLin.Tpo"; exit 1; fi +@AMDEP_TRUE@@am__fastdepCXX_FALSE@ source='$(SOURCE_DIR)/ProblemNonLin.cc' object='libamdis_la-ProblemNonLin.lo' libtool=yes @AMDEPBACKSLASH@ +@AMDEP_TRUE@@am__fastdepCXX_FALSE@ DEPDIR=$(DEPDIR) $(CXXDEPMODE) $(depcomp) @AMDEPBACKSLASH@ +@am__fastdepCXX_FALSE@ $(LIBTOOL) --tag=CXX --mode=compile $(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(libamdis_la_CXXFLAGS) $(CXXFLAGS) -c -o libamdis_la-ProblemNonLin.lo `test -f '$(SOURCE_DIR)/ProblemNonLin.cc' || echo '$(srcdir)/'`$(SOURCE_DIR)/ProblemNonLin.cc + +libamdis_la-NonLinUpdater.lo: $(SOURCE_DIR)/NonLinUpdater.cc +@am__fastdepCXX_TRUE@ if $(LIBTOOL) --tag=CXX --mode=compile $(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(libamdis_la_CXXFLAGS) $(CXXFLAGS) -MT libamdis_la-NonLinUpdater.lo -MD -MP -MF "$(DEPDIR)/libamdis_la-NonLinUpdater.Tpo" -c -o libamdis_la-NonLinUpdater.lo `test -f '$(SOURCE_DIR)/NonLinUpdater.cc' || echo '$(srcdir)/'`$(SOURCE_DIR)/NonLinUpdater.cc; \ +@am__fastdepCXX_TRUE@ then mv -f "$(DEPDIR)/libamdis_la-NonLinUpdater.Tpo" "$(DEPDIR)/libamdis_la-NonLinUpdater.Plo"; else rm -f "$(DEPDIR)/libamdis_la-NonLinUpdater.Tpo"; exit 1; fi +@AMDEP_TRUE@@am__fastdepCXX_FALSE@ source='$(SOURCE_DIR)/NonLinUpdater.cc' object='libamdis_la-NonLinUpdater.lo' libtool=yes @AMDEPBACKSLASH@ +@AMDEP_TRUE@@am__fastdepCXX_FALSE@ DEPDIR=$(DEPDIR) $(CXXDEPMODE) $(depcomp) @AMDEPBACKSLASH@ +@am__fastdepCXX_FALSE@ $(LIBTOOL) --tag=CXX --mode=compile $(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(libamdis_la_CXXFLAGS) $(CXXFLAGS) -c -o libamdis_la-NonLinUpdater.lo `test -f '$(SOURCE_DIR)/NonLinUpdater.cc' || echo '$(srcdir)/'`$(SOURCE_DIR)/NonLinUpdater.cc + +libamdis_la-QPsiPhi.lo: $(SOURCE_DIR)/QPsiPhi.cc +@am__fastdepCXX_TRUE@ if $(LIBTOOL) --tag=CXX --mode=compile $(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(libamdis_la_CXXFLAGS) $(CXXFLAGS) -MT libamdis_la-QPsiPhi.lo -MD -MP -MF "$(DEPDIR)/libamdis_la-QPsiPhi.Tpo" -c -o libamdis_la-QPsiPhi.lo `test -f '$(SOURCE_DIR)/QPsiPhi.cc' || echo '$(srcdir)/'`$(SOURCE_DIR)/QPsiPhi.cc; \ +@am__fastdepCXX_TRUE@ then mv -f "$(DEPDIR)/libamdis_la-QPsiPhi.Tpo" "$(DEPDIR)/libamdis_la-QPsiPhi.Plo"; else rm -f "$(DEPDIR)/libamdis_la-QPsiPhi.Tpo"; exit 1; fi +@AMDEP_TRUE@@am__fastdepCXX_FALSE@ source='$(SOURCE_DIR)/QPsiPhi.cc' object='libamdis_la-QPsiPhi.lo' libtool=yes @AMDEPBACKSLASH@ +@AMDEP_TRUE@@am__fastdepCXX_FALSE@ DEPDIR=$(DEPDIR) $(CXXDEPMODE) $(depcomp) @AMDEPBACKSLASH@ +@am__fastdepCXX_FALSE@ $(LIBTOOL) --tag=CXX --mode=compile $(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(libamdis_la_CXXFLAGS) $(CXXFLAGS) -c -o libamdis_la-QPsiPhi.lo `test -f '$(SOURCE_DIR)/QPsiPhi.cc' || echo '$(srcdir)/'`$(SOURCE_DIR)/QPsiPhi.cc + +libamdis_la-BasisFunction.lo: $(SOURCE_DIR)/BasisFunction.cc +@am__fastdepCXX_TRUE@ if $(LIBTOOL) --tag=CXX --mode=compile $(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(libamdis_la_CXXFLAGS) $(CXXFLAGS) -MT libamdis_la-BasisFunction.lo -MD -MP -MF "$(DEPDIR)/libamdis_la-BasisFunction.Tpo" -c -o libamdis_la-BasisFunction.lo `test -f '$(SOURCE_DIR)/BasisFunction.cc' || echo '$(srcdir)/'`$(SOURCE_DIR)/BasisFunction.cc; \ +@am__fastdepCXX_TRUE@ then mv -f "$(DEPDIR)/libamdis_la-BasisFunction.Tpo" "$(DEPDIR)/libamdis_la-BasisFunction.Plo"; else rm -f "$(DEPDIR)/libamdis_la-BasisFunction.Tpo"; exit 1; fi +@AMDEP_TRUE@@am__fastdepCXX_FALSE@ source='$(SOURCE_DIR)/BasisFunction.cc' object='libamdis_la-BasisFunction.lo' libtool=yes @AMDEPBACKSLASH@ +@AMDEP_TRUE@@am__fastdepCXX_FALSE@ DEPDIR=$(DEPDIR) $(CXXDEPMODE) $(depcomp) @AMDEPBACKSLASH@ +@am__fastdepCXX_FALSE@ $(LIBTOOL) --tag=CXX --mode=compile $(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(libamdis_la_CXXFLAGS) $(CXXFLAGS) -c -o libamdis_la-BasisFunction.lo `test -f '$(SOURCE_DIR)/BasisFunction.cc' || echo '$(srcdir)/'`$(SOURCE_DIR)/BasisFunction.cc + +libamdis_la-Boundary.lo: $(SOURCE_DIR)/Boundary.cc +@am__fastdepCXX_TRUE@ if $(LIBTOOL) --tag=CXX --mode=compile $(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(libamdis_la_CXXFLAGS) $(CXXFLAGS) -MT libamdis_la-Boundary.lo -MD -MP -MF "$(DEPDIR)/libamdis_la-Boundary.Tpo" -c -o libamdis_la-Boundary.lo `test -f '$(SOURCE_DIR)/Boundary.cc' || echo '$(srcdir)/'`$(SOURCE_DIR)/Boundary.cc; \ +@am__fastdepCXX_TRUE@ then mv -f "$(DEPDIR)/libamdis_la-Boundary.Tpo" "$(DEPDIR)/libamdis_la-Boundary.Plo"; else rm -f "$(DEPDIR)/libamdis_la-Boundary.Tpo"; exit 1; fi +@AMDEP_TRUE@@am__fastdepCXX_FALSE@ source='$(SOURCE_DIR)/Boundary.cc' object='libamdis_la-Boundary.lo' libtool=yes @AMDEPBACKSLASH@ +@AMDEP_TRUE@@am__fastdepCXX_FALSE@ DEPDIR=$(DEPDIR) $(CXXDEPMODE) $(depcomp) @AMDEPBACKSLASH@ +@am__fastdepCXX_FALSE@ $(LIBTOOL) --tag=CXX --mode=compile $(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(libamdis_la_CXXFLAGS) $(CXXFLAGS) -c -o libamdis_la-Boundary.lo `test -f '$(SOURCE_DIR)/Boundary.cc' || echo '$(srcdir)/'`$(SOURCE_DIR)/Boundary.cc + +libamdis_la-CoarseningManager.lo: $(SOURCE_DIR)/CoarseningManager.cc +@am__fastdepCXX_TRUE@ if $(LIBTOOL) --tag=CXX --mode=compile $(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(libamdis_la_CXXFLAGS) $(CXXFLAGS) -MT libamdis_la-CoarseningManager.lo -MD -MP -MF "$(DEPDIR)/libamdis_la-CoarseningManager.Tpo" -c -o libamdis_la-CoarseningManager.lo `test -f '$(SOURCE_DIR)/CoarseningManager.cc' || echo '$(srcdir)/'`$(SOURCE_DIR)/CoarseningManager.cc; \ +@am__fastdepCXX_TRUE@ then mv -f "$(DEPDIR)/libamdis_la-CoarseningManager.Tpo" "$(DEPDIR)/libamdis_la-CoarseningManager.Plo"; else rm -f "$(DEPDIR)/libamdis_la-CoarseningManager.Tpo"; exit 1; fi +@AMDEP_TRUE@@am__fastdepCXX_FALSE@ source='$(SOURCE_DIR)/CoarseningManager.cc' object='libamdis_la-CoarseningManager.lo' libtool=yes @AMDEPBACKSLASH@ +@AMDEP_TRUE@@am__fastdepCXX_FALSE@ DEPDIR=$(DEPDIR) $(CXXDEPMODE) $(depcomp) @AMDEPBACKSLASH@ +@am__fastdepCXX_FALSE@ $(LIBTOOL) --tag=CXX --mode=compile $(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(libamdis_la_CXXFLAGS) $(CXXFLAGS) -c -o libamdis_la-CoarseningManager.lo `test -f '$(SOURCE_DIR)/CoarseningManager.cc' || echo '$(srcdir)/'`$(SOURCE_DIR)/CoarseningManager.cc + +libamdis_la-CoarseningManager1d.lo: $(SOURCE_DIR)/CoarseningManager1d.cc +@am__fastdepCXX_TRUE@ if $(LIBTOOL) --tag=CXX --mode=compile $(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(libamdis_la_CXXFLAGS) $(CXXFLAGS) -MT libamdis_la-CoarseningManager1d.lo -MD -MP -MF "$(DEPDIR)/libamdis_la-CoarseningManager1d.Tpo" -c -o libamdis_la-CoarseningManager1d.lo `test -f '$(SOURCE_DIR)/CoarseningManager1d.cc' || echo '$(srcdir)/'`$(SOURCE_DIR)/CoarseningManager1d.cc; \ +@am__fastdepCXX_TRUE@ then mv -f "$(DEPDIR)/libamdis_la-CoarseningManager1d.Tpo" "$(DEPDIR)/libamdis_la-CoarseningManager1d.Plo"; else rm -f "$(DEPDIR)/libamdis_la-CoarseningManager1d.Tpo"; exit 1; fi +@AMDEP_TRUE@@am__fastdepCXX_FALSE@ source='$(SOURCE_DIR)/CoarseningManager1d.cc' object='libamdis_la-CoarseningManager1d.lo' libtool=yes @AMDEPBACKSLASH@ +@AMDEP_TRUE@@am__fastdepCXX_FALSE@ DEPDIR=$(DEPDIR) $(CXXDEPMODE) $(depcomp) @AMDEPBACKSLASH@ +@am__fastdepCXX_FALSE@ $(LIBTOOL) --tag=CXX --mode=compile $(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(libamdis_la_CXXFLAGS) $(CXXFLAGS) -c -o libamdis_la-CoarseningManager1d.lo `test -f '$(SOURCE_DIR)/CoarseningManager1d.cc' || echo '$(srcdir)/'`$(SOURCE_DIR)/CoarseningManager1d.cc + +libamdis_la-CoarseningManager2d.lo: $(SOURCE_DIR)/CoarseningManager2d.cc +@am__fastdepCXX_TRUE@ if $(LIBTOOL) --tag=CXX --mode=compile $(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(libamdis_la_CXXFLAGS) $(CXXFLAGS) -MT libamdis_la-CoarseningManager2d.lo -MD -MP -MF "$(DEPDIR)/libamdis_la-CoarseningManager2d.Tpo" -c -o libamdis_la-CoarseningManager2d.lo `test -f '$(SOURCE_DIR)/CoarseningManager2d.cc' || echo '$(srcdir)/'`$(SOURCE_DIR)/CoarseningManager2d.cc; \ +@am__fastdepCXX_TRUE@ then mv -f "$(DEPDIR)/libamdis_la-CoarseningManager2d.Tpo" "$(DEPDIR)/libamdis_la-CoarseningManager2d.Plo"; else rm -f "$(DEPDIR)/libamdis_la-CoarseningManager2d.Tpo"; exit 1; fi +@AMDEP_TRUE@@am__fastdepCXX_FALSE@ source='$(SOURCE_DIR)/CoarseningManager2d.cc' object='libamdis_la-CoarseningManager2d.lo' libtool=yes @AMDEPBACKSLASH@ +@AMDEP_TRUE@@am__fastdepCXX_FALSE@ DEPDIR=$(DEPDIR) $(CXXDEPMODE) $(depcomp) @AMDEPBACKSLASH@ +@am__fastdepCXX_FALSE@ $(LIBTOOL) --tag=CXX --mode=compile $(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(libamdis_la_CXXFLAGS) $(CXXFLAGS) -c -o libamdis_la-CoarseningManager2d.lo `test -f '$(SOURCE_DIR)/CoarseningManager2d.cc' || echo '$(srcdir)/'`$(SOURCE_DIR)/CoarseningManager2d.cc + +libamdis_la-CoarseningManager3d.lo: $(SOURCE_DIR)/CoarseningManager3d.cc +@am__fastdepCXX_TRUE@ if $(LIBTOOL) --tag=CXX --mode=compile $(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(libamdis_la_CXXFLAGS) $(CXXFLAGS) -MT libamdis_la-CoarseningManager3d.lo -MD -MP -MF "$(DEPDIR)/libamdis_la-CoarseningManager3d.Tpo" -c -o libamdis_la-CoarseningManager3d.lo `test -f '$(SOURCE_DIR)/CoarseningManager3d.cc' || echo '$(srcdir)/'`$(SOURCE_DIR)/CoarseningManager3d.cc; \ +@am__fastdepCXX_TRUE@ then mv -f "$(DEPDIR)/libamdis_la-CoarseningManager3d.Tpo" "$(DEPDIR)/libamdis_la-CoarseningManager3d.Plo"; else rm -f "$(DEPDIR)/libamdis_la-CoarseningManager3d.Tpo"; exit 1; fi +@AMDEP_TRUE@@am__fastdepCXX_FALSE@ source='$(SOURCE_DIR)/CoarseningManager3d.cc' object='libamdis_la-CoarseningManager3d.lo' libtool=yes @AMDEPBACKSLASH@ +@AMDEP_TRUE@@am__fastdepCXX_FALSE@ DEPDIR=$(DEPDIR) $(CXXDEPMODE) $(depcomp) @AMDEPBACKSLASH@ +@am__fastdepCXX_FALSE@ $(LIBTOOL) --tag=CXX --mode=compile $(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(libamdis_la_CXXFLAGS) $(CXXFLAGS) -c -o libamdis_la-CoarseningManager3d.lo `test -f '$(SOURCE_DIR)/CoarseningManager3d.cc' || echo '$(srcdir)/'`$(SOURCE_DIR)/CoarseningManager3d.cc + +libamdis_la-demangle.lo: $(SOURCE_DIR)/demangle.cc +@am__fastdepCXX_TRUE@ if $(LIBTOOL) --tag=CXX --mode=compile $(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(libamdis_la_CXXFLAGS) $(CXXFLAGS) -MT libamdis_la-demangle.lo -MD -MP -MF "$(DEPDIR)/libamdis_la-demangle.Tpo" -c -o libamdis_la-demangle.lo `test -f '$(SOURCE_DIR)/demangle.cc' || echo '$(srcdir)/'`$(SOURCE_DIR)/demangle.cc; \ +@am__fastdepCXX_TRUE@ then mv -f "$(DEPDIR)/libamdis_la-demangle.Tpo" "$(DEPDIR)/libamdis_la-demangle.Plo"; else rm -f "$(DEPDIR)/libamdis_la-demangle.Tpo"; exit 1; fi +@AMDEP_TRUE@@am__fastdepCXX_FALSE@ source='$(SOURCE_DIR)/demangle.cc' object='libamdis_la-demangle.lo' libtool=yes @AMDEPBACKSLASH@ +@AMDEP_TRUE@@am__fastdepCXX_FALSE@ DEPDIR=$(DEPDIR) $(CXXDEPMODE) $(depcomp) @AMDEPBACKSLASH@ +@am__fastdepCXX_FALSE@ $(LIBTOOL) --tag=CXX --mode=compile $(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(libamdis_la_CXXFLAGS) $(CXXFLAGS) -c -o libamdis_la-demangle.lo `test -f '$(SOURCE_DIR)/demangle.cc' || echo '$(srcdir)/'`$(SOURCE_DIR)/demangle.cc + +libamdis_la-DOFAdmin.lo: $(SOURCE_DIR)/DOFAdmin.cc +@am__fastdepCXX_TRUE@ if $(LIBTOOL) --tag=CXX --mode=compile $(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(libamdis_la_CXXFLAGS) $(CXXFLAGS) -MT libamdis_la-DOFAdmin.lo -MD -MP -MF "$(DEPDIR)/libamdis_la-DOFAdmin.Tpo" -c -o libamdis_la-DOFAdmin.lo `test -f '$(SOURCE_DIR)/DOFAdmin.cc' || echo '$(srcdir)/'`$(SOURCE_DIR)/DOFAdmin.cc; \ +@am__fastdepCXX_TRUE@ then mv -f "$(DEPDIR)/libamdis_la-DOFAdmin.Tpo" "$(DEPDIR)/libamdis_la-DOFAdmin.Plo"; else rm -f "$(DEPDIR)/libamdis_la-DOFAdmin.Tpo"; exit 1; fi +@AMDEP_TRUE@@am__fastdepCXX_FALSE@ source='$(SOURCE_DIR)/DOFAdmin.cc' object='libamdis_la-DOFAdmin.lo' libtool=yes @AMDEPBACKSLASH@ +@AMDEP_TRUE@@am__fastdepCXX_FALSE@ DEPDIR=$(DEPDIR) $(CXXDEPMODE) $(depcomp) @AMDEPBACKSLASH@ +@am__fastdepCXX_FALSE@ $(LIBTOOL) --tag=CXX --mode=compile $(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(libamdis_la_CXXFLAGS) $(CXXFLAGS) -c -o libamdis_la-DOFAdmin.lo `test -f '$(SOURCE_DIR)/DOFAdmin.cc' || echo '$(srcdir)/'`$(SOURCE_DIR)/DOFAdmin.cc + +libamdis_la-DOFMatrix.lo: $(SOURCE_DIR)/DOFMatrix.cc +@am__fastdepCXX_TRUE@ if $(LIBTOOL) --tag=CXX --mode=compile $(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(libamdis_la_CXXFLAGS) $(CXXFLAGS) -MT libamdis_la-DOFMatrix.lo -MD -MP -MF "$(DEPDIR)/libamdis_la-DOFMatrix.Tpo" -c -o libamdis_la-DOFMatrix.lo `test -f '$(SOURCE_DIR)/DOFMatrix.cc' || echo '$(srcdir)/'`$(SOURCE_DIR)/DOFMatrix.cc; \ +@am__fastdepCXX_TRUE@ then mv -f "$(DEPDIR)/libamdis_la-DOFMatrix.Tpo" "$(DEPDIR)/libamdis_la-DOFMatrix.Plo"; else rm -f "$(DEPDIR)/libamdis_la-DOFMatrix.Tpo"; exit 1; fi +@AMDEP_TRUE@@am__fastdepCXX_FALSE@ source='$(SOURCE_DIR)/DOFMatrix.cc' object='libamdis_la-DOFMatrix.lo' libtool=yes @AMDEPBACKSLASH@ +@AMDEP_TRUE@@am__fastdepCXX_FALSE@ DEPDIR=$(DEPDIR) $(CXXDEPMODE) $(depcomp) @AMDEPBACKSLASH@ +@am__fastdepCXX_FALSE@ $(LIBTOOL) --tag=CXX --mode=compile $(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(libamdis_la_CXXFLAGS) $(CXXFLAGS) -c -o libamdis_la-DOFMatrix.lo `test -f '$(SOURCE_DIR)/DOFMatrix.cc' || echo '$(srcdir)/'`$(SOURCE_DIR)/DOFMatrix.cc + +libamdis_la-Element.lo: $(SOURCE_DIR)/Element.cc +@am__fastdepCXX_TRUE@ if $(LIBTOOL) --tag=CXX --mode=compile $(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(libamdis_la_CXXFLAGS) $(CXXFLAGS) -MT libamdis_la-Element.lo -MD -MP -MF "$(DEPDIR)/libamdis_la-Element.Tpo" -c -o libamdis_la-Element.lo `test -f '$(SOURCE_DIR)/Element.cc' || echo '$(srcdir)/'`$(SOURCE_DIR)/Element.cc; \ +@am__fastdepCXX_TRUE@ then mv -f "$(DEPDIR)/libamdis_la-Element.Tpo" "$(DEPDIR)/libamdis_la-Element.Plo"; else rm -f "$(DEPDIR)/libamdis_la-Element.Tpo"; exit 1; fi +@AMDEP_TRUE@@am__fastdepCXX_FALSE@ source='$(SOURCE_DIR)/Element.cc' object='libamdis_la-Element.lo' libtool=yes @AMDEPBACKSLASH@ +@AMDEP_TRUE@@am__fastdepCXX_FALSE@ DEPDIR=$(DEPDIR) $(CXXDEPMODE) $(depcomp) @AMDEPBACKSLASH@ +@am__fastdepCXX_FALSE@ $(LIBTOOL) --tag=CXX --mode=compile $(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(libamdis_la_CXXFLAGS) $(CXXFLAGS) -c -o libamdis_la-Element.lo `test -f '$(SOURCE_DIR)/Element.cc' || echo '$(srcdir)/'`$(SOURCE_DIR)/Element.cc + +libamdis_la-ElInfo1d.lo: $(SOURCE_DIR)/ElInfo1d.cc +@am__fastdepCXX_TRUE@ if $(LIBTOOL) --tag=CXX --mode=compile $(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(libamdis_la_CXXFLAGS) $(CXXFLAGS) -MT libamdis_la-ElInfo1d.lo -MD -MP -MF "$(DEPDIR)/libamdis_la-ElInfo1d.Tpo" -c -o libamdis_la-ElInfo1d.lo `test -f '$(SOURCE_DIR)/ElInfo1d.cc' || echo '$(srcdir)/'`$(SOURCE_DIR)/ElInfo1d.cc; \ +@am__fastdepCXX_TRUE@ then mv -f "$(DEPDIR)/libamdis_la-ElInfo1d.Tpo" "$(DEPDIR)/libamdis_la-ElInfo1d.Plo"; else rm -f "$(DEPDIR)/libamdis_la-ElInfo1d.Tpo"; exit 1; fi +@AMDEP_TRUE@@am__fastdepCXX_FALSE@ source='$(SOURCE_DIR)/ElInfo1d.cc' object='libamdis_la-ElInfo1d.lo' libtool=yes @AMDEPBACKSLASH@ +@AMDEP_TRUE@@am__fastdepCXX_FALSE@ DEPDIR=$(DEPDIR) $(CXXDEPMODE) $(depcomp) @AMDEPBACKSLASH@ +@am__fastdepCXX_FALSE@ $(LIBTOOL) --tag=CXX --mode=compile $(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(libamdis_la_CXXFLAGS) $(CXXFLAGS) -c -o libamdis_la-ElInfo1d.lo `test -f '$(SOURCE_DIR)/ElInfo1d.cc' || echo '$(srcdir)/'`$(SOURCE_DIR)/ElInfo1d.cc + +libamdis_la-ElInfo2d.lo: $(SOURCE_DIR)/ElInfo2d.cc +@am__fastdepCXX_TRUE@ if $(LIBTOOL) --tag=CXX --mode=compile $(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(libamdis_la_CXXFLAGS) $(CXXFLAGS) -MT libamdis_la-ElInfo2d.lo -MD -MP -MF "$(DEPDIR)/libamdis_la-ElInfo2d.Tpo" -c -o libamdis_la-ElInfo2d.lo `test -f '$(SOURCE_DIR)/ElInfo2d.cc' || echo '$(srcdir)/'`$(SOURCE_DIR)/ElInfo2d.cc; \ +@am__fastdepCXX_TRUE@ then mv -f "$(DEPDIR)/libamdis_la-ElInfo2d.Tpo" "$(DEPDIR)/libamdis_la-ElInfo2d.Plo"; else rm -f "$(DEPDIR)/libamdis_la-ElInfo2d.Tpo"; exit 1; fi +@AMDEP_TRUE@@am__fastdepCXX_FALSE@ source='$(SOURCE_DIR)/ElInfo2d.cc' object='libamdis_la-ElInfo2d.lo' libtool=yes @AMDEPBACKSLASH@ +@AMDEP_TRUE@@am__fastdepCXX_FALSE@ DEPDIR=$(DEPDIR) $(CXXDEPMODE) $(depcomp) @AMDEPBACKSLASH@ +@am__fastdepCXX_FALSE@ $(LIBTOOL) --tag=CXX --mode=compile $(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(libamdis_la_CXXFLAGS) $(CXXFLAGS) -c -o libamdis_la-ElInfo2d.lo `test -f '$(SOURCE_DIR)/ElInfo2d.cc' || echo '$(srcdir)/'`$(SOURCE_DIR)/ElInfo2d.cc + +libamdis_la-ElInfo3d.lo: $(SOURCE_DIR)/ElInfo3d.cc +@am__fastdepCXX_TRUE@ if $(LIBTOOL) --tag=CXX --mode=compile $(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(libamdis_la_CXXFLAGS) $(CXXFLAGS) -MT libamdis_la-ElInfo3d.lo -MD -MP -MF "$(DEPDIR)/libamdis_la-ElInfo3d.Tpo" -c -o libamdis_la-ElInfo3d.lo `test -f '$(SOURCE_DIR)/ElInfo3d.cc' || echo '$(srcdir)/'`$(SOURCE_DIR)/ElInfo3d.cc; \ +@am__fastdepCXX_TRUE@ then mv -f "$(DEPDIR)/libamdis_la-ElInfo3d.Tpo" "$(DEPDIR)/libamdis_la-ElInfo3d.Plo"; else rm -f "$(DEPDIR)/libamdis_la-ElInfo3d.Tpo"; exit 1; fi +@AMDEP_TRUE@@am__fastdepCXX_FALSE@ source='$(SOURCE_DIR)/ElInfo3d.cc' object='libamdis_la-ElInfo3d.lo' libtool=yes @AMDEPBACKSLASH@ +@AMDEP_TRUE@@am__fastdepCXX_FALSE@ DEPDIR=$(DEPDIR) $(CXXDEPMODE) $(depcomp) @AMDEPBACKSLASH@ +@am__fastdepCXX_FALSE@ $(LIBTOOL) --tag=CXX --mode=compile $(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(libamdis_la_CXXFLAGS) $(CXXFLAGS) -c -o libamdis_la-ElInfo3d.lo `test -f '$(SOURCE_DIR)/ElInfo3d.cc' || echo '$(srcdir)/'`$(SOURCE_DIR)/ElInfo3d.cc + +libamdis_la-FiniteElemSpace.lo: $(SOURCE_DIR)/FiniteElemSpace.cc +@am__fastdepCXX_TRUE@ if $(LIBTOOL) --tag=CXX --mode=compile $(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(libamdis_la_CXXFLAGS) $(CXXFLAGS) -MT libamdis_la-FiniteElemSpace.lo -MD -MP -MF "$(DEPDIR)/libamdis_la-FiniteElemSpace.Tpo" -c -o libamdis_la-FiniteElemSpace.lo `test -f '$(SOURCE_DIR)/FiniteElemSpace.cc' || echo '$(srcdir)/'`$(SOURCE_DIR)/FiniteElemSpace.cc; \ +@am__fastdepCXX_TRUE@ then mv -f "$(DEPDIR)/libamdis_la-FiniteElemSpace.Tpo" "$(DEPDIR)/libamdis_la-FiniteElemSpace.Plo"; else rm -f "$(DEPDIR)/libamdis_la-FiniteElemSpace.Tpo"; exit 1; fi +@AMDEP_TRUE@@am__fastdepCXX_FALSE@ source='$(SOURCE_DIR)/FiniteElemSpace.cc' object='libamdis_la-FiniteElemSpace.lo' libtool=yes @AMDEPBACKSLASH@ +@AMDEP_TRUE@@am__fastdepCXX_FALSE@ DEPDIR=$(DEPDIR) $(CXXDEPMODE) $(depcomp) @AMDEPBACKSLASH@ +@am__fastdepCXX_FALSE@ $(LIBTOOL) --tag=CXX --mode=compile $(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(libamdis_la_CXXFLAGS) $(CXXFLAGS) -c -o libamdis_la-FiniteElemSpace.lo `test -f '$(SOURCE_DIR)/FiniteElemSpace.cc' || echo '$(srcdir)/'`$(SOURCE_DIR)/FiniteElemSpace.cc + +libamdis_la-FixVec.lo: $(SOURCE_DIR)/FixVec.cc +@am__fastdepCXX_TRUE@ if $(LIBTOOL) --tag=CXX --mode=compile $(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(libamdis_la_CXXFLAGS) $(CXXFLAGS) -MT libamdis_la-FixVec.lo -MD -MP -MF "$(DEPDIR)/libamdis_la-FixVec.Tpo" -c -o libamdis_la-FixVec.lo `test -f '$(SOURCE_DIR)/FixVec.cc' || echo '$(srcdir)/'`$(SOURCE_DIR)/FixVec.cc; \ +@am__fastdepCXX_TRUE@ then mv -f "$(DEPDIR)/libamdis_la-FixVec.Tpo" "$(DEPDIR)/libamdis_la-FixVec.Plo"; else rm -f "$(DEPDIR)/libamdis_la-FixVec.Tpo"; exit 1; fi +@AMDEP_TRUE@@am__fastdepCXX_FALSE@ source='$(SOURCE_DIR)/FixVec.cc' object='libamdis_la-FixVec.lo' libtool=yes @AMDEPBACKSLASH@ +@AMDEP_TRUE@@am__fastdepCXX_FALSE@ DEPDIR=$(DEPDIR) $(CXXDEPMODE) $(depcomp) @AMDEPBACKSLASH@ +@am__fastdepCXX_FALSE@ $(LIBTOOL) --tag=CXX --mode=compile $(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(libamdis_la_CXXFLAGS) $(CXXFLAGS) -c -o libamdis_la-FixVec.lo `test -f '$(SOURCE_DIR)/FixVec.cc' || echo '$(srcdir)/'`$(SOURCE_DIR)/FixVec.cc + +libamdis_la-Flag.lo: $(SOURCE_DIR)/Flag.cc +@am__fastdepCXX_TRUE@ if $(LIBTOOL) --tag=CXX --mode=compile $(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(libamdis_la_CXXFLAGS) $(CXXFLAGS) -MT libamdis_la-Flag.lo -MD -MP -MF "$(DEPDIR)/libamdis_la-Flag.Tpo" -c -o libamdis_la-Flag.lo `test -f '$(SOURCE_DIR)/Flag.cc' || echo '$(srcdir)/'`$(SOURCE_DIR)/Flag.cc; \ +@am__fastdepCXX_TRUE@ then mv -f "$(DEPDIR)/libamdis_la-Flag.Tpo" "$(DEPDIR)/libamdis_la-Flag.Plo"; else rm -f "$(DEPDIR)/libamdis_la-Flag.Tpo"; exit 1; fi +@AMDEP_TRUE@@am__fastdepCXX_FALSE@ source='$(SOURCE_DIR)/Flag.cc' object='libamdis_la-Flag.lo' libtool=yes @AMDEPBACKSLASH@ +@AMDEP_TRUE@@am__fastdepCXX_FALSE@ DEPDIR=$(DEPDIR) $(CXXDEPMODE) $(depcomp) @AMDEPBACKSLASH@ +@am__fastdepCXX_FALSE@ $(LIBTOOL) --tag=CXX --mode=compile $(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(libamdis_la_CXXFLAGS) $(CXXFLAGS) -c -o libamdis_la-Flag.lo `test -f '$(SOURCE_DIR)/Flag.cc' || echo '$(srcdir)/'`$(SOURCE_DIR)/Flag.cc + +libamdis_la-Global.lo: $(SOURCE_DIR)/Global.cc +@am__fastdepCXX_TRUE@ if $(LIBTOOL) --tag=CXX --mode=compile $(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(libamdis_la_CXXFLAGS) $(CXXFLAGS) -MT libamdis_la-Global.lo -MD -MP -MF "$(DEPDIR)/libamdis_la-Global.Tpo" -c -o libamdis_la-Global.lo `test -f '$(SOURCE_DIR)/Global.cc' || echo '$(srcdir)/'`$(SOURCE_DIR)/Global.cc; \ +@am__fastdepCXX_TRUE@ then mv -f "$(DEPDIR)/libamdis_la-Global.Tpo" "$(DEPDIR)/libamdis_la-Global.Plo"; else rm -f "$(DEPDIR)/libamdis_la-Global.Tpo"; exit 1; fi +@AMDEP_TRUE@@am__fastdepCXX_FALSE@ source='$(SOURCE_DIR)/Global.cc' object='libamdis_la-Global.lo' libtool=yes @AMDEPBACKSLASH@ +@AMDEP_TRUE@@am__fastdepCXX_FALSE@ DEPDIR=$(DEPDIR) $(CXXDEPMODE) $(depcomp) @AMDEPBACKSLASH@ +@am__fastdepCXX_FALSE@ $(LIBTOOL) --tag=CXX --mode=compile $(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(libamdis_la_CXXFLAGS) $(CXXFLAGS) -c -o libamdis_la-Global.lo `test -f '$(SOURCE_DIR)/Global.cc' || echo '$(srcdir)/'`$(SOURCE_DIR)/Global.cc + +libamdis_la-Lagrange.lo: $(SOURCE_DIR)/Lagrange.cc +@am__fastdepCXX_TRUE@ if $(LIBTOOL) --tag=CXX --mode=compile $(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(libamdis_la_CXXFLAGS) $(CXXFLAGS) -MT libamdis_la-Lagrange.lo -MD -MP -MF "$(DEPDIR)/libamdis_la-Lagrange.Tpo" -c -o libamdis_la-Lagrange.lo `test -f '$(SOURCE_DIR)/Lagrange.cc' || echo '$(srcdir)/'`$(SOURCE_DIR)/Lagrange.cc; \ +@am__fastdepCXX_TRUE@ then mv -f "$(DEPDIR)/libamdis_la-Lagrange.Tpo" "$(DEPDIR)/libamdis_la-Lagrange.Plo"; else rm -f "$(DEPDIR)/libamdis_la-Lagrange.Tpo"; exit 1; fi +@AMDEP_TRUE@@am__fastdepCXX_FALSE@ source='$(SOURCE_DIR)/Lagrange.cc' object='libamdis_la-Lagrange.lo' libtool=yes @AMDEPBACKSLASH@ +@AMDEP_TRUE@@am__fastdepCXX_FALSE@ DEPDIR=$(DEPDIR) $(CXXDEPMODE) $(depcomp) @AMDEPBACKSLASH@ +@am__fastdepCXX_FALSE@ $(LIBTOOL) --tag=CXX --mode=compile $(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(libamdis_la_CXXFLAGS) $(CXXFLAGS) -c -o libamdis_la-Lagrange.lo `test -f '$(SOURCE_DIR)/Lagrange.cc' || echo '$(srcdir)/'`$(SOURCE_DIR)/Lagrange.cc + +libamdis_la-Line.lo: $(SOURCE_DIR)/Line.cc +@am__fastdepCXX_TRUE@ if $(LIBTOOL) --tag=CXX --mode=compile $(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(libamdis_la_CXXFLAGS) $(CXXFLAGS) -MT libamdis_la-Line.lo -MD -MP -MF "$(DEPDIR)/libamdis_la-Line.Tpo" -c -o libamdis_la-Line.lo `test -f '$(SOURCE_DIR)/Line.cc' || echo '$(srcdir)/'`$(SOURCE_DIR)/Line.cc; \ +@am__fastdepCXX_TRUE@ then mv -f "$(DEPDIR)/libamdis_la-Line.Tpo" "$(DEPDIR)/libamdis_la-Line.Plo"; else rm -f "$(DEPDIR)/libamdis_la-Line.Tpo"; exit 1; fi +@AMDEP_TRUE@@am__fastdepCXX_FALSE@ source='$(SOURCE_DIR)/Line.cc' object='libamdis_la-Line.lo' libtool=yes @AMDEPBACKSLASH@ +@AMDEP_TRUE@@am__fastdepCXX_FALSE@ DEPDIR=$(DEPDIR) $(CXXDEPMODE) $(depcomp) @AMDEPBACKSLASH@ +@am__fastdepCXX_FALSE@ $(LIBTOOL) --tag=CXX --mode=compile $(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(libamdis_la_CXXFLAGS) $(CXXFLAGS) -c -o libamdis_la-Line.lo `test -f '$(SOURCE_DIR)/Line.cc' || echo '$(srcdir)/'`$(SOURCE_DIR)/Line.cc + +libamdis_la-MacroElement.lo: $(SOURCE_DIR)/MacroElement.cc +@am__fastdepCXX_TRUE@ if $(LIBTOOL) --tag=CXX --mode=compile $(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(libamdis_la_CXXFLAGS) $(CXXFLAGS) -MT libamdis_la-MacroElement.lo -MD -MP -MF "$(DEPDIR)/libamdis_la-MacroElement.Tpo" -c -o libamdis_la-MacroElement.lo `test -f '$(SOURCE_DIR)/MacroElement.cc' || echo '$(srcdir)/'`$(SOURCE_DIR)/MacroElement.cc; \ +@am__fastdepCXX_TRUE@ then mv -f "$(DEPDIR)/libamdis_la-MacroElement.Tpo" "$(DEPDIR)/libamdis_la-MacroElement.Plo"; else rm -f "$(DEPDIR)/libamdis_la-MacroElement.Tpo"; exit 1; fi +@AMDEP_TRUE@@am__fastdepCXX_FALSE@ source='$(SOURCE_DIR)/MacroElement.cc' object='libamdis_la-MacroElement.lo' libtool=yes @AMDEPBACKSLASH@ +@AMDEP_TRUE@@am__fastdepCXX_FALSE@ DEPDIR=$(DEPDIR) $(CXXDEPMODE) $(depcomp) @AMDEPBACKSLASH@ +@am__fastdepCXX_FALSE@ $(LIBTOOL) --tag=CXX --mode=compile $(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(libamdis_la_CXXFLAGS) $(CXXFLAGS) -c -o libamdis_la-MacroElement.lo `test -f '$(SOURCE_DIR)/MacroElement.cc' || echo '$(srcdir)/'`$(SOURCE_DIR)/MacroElement.cc + +libamdis_la-MacroWriter.lo: $(SOURCE_DIR)/MacroWriter.cc +@am__fastdepCXX_TRUE@ if $(LIBTOOL) --tag=CXX --mode=compile $(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(libamdis_la_CXXFLAGS) $(CXXFLAGS) -MT libamdis_la-MacroWriter.lo -MD -MP -MF "$(DEPDIR)/libamdis_la-MacroWriter.Tpo" -c -o libamdis_la-MacroWriter.lo `test -f '$(SOURCE_DIR)/MacroWriter.cc' || echo '$(srcdir)/'`$(SOURCE_DIR)/MacroWriter.cc; \ +@am__fastdepCXX_TRUE@ then mv -f "$(DEPDIR)/libamdis_la-MacroWriter.Tpo" "$(DEPDIR)/libamdis_la-MacroWriter.Plo"; else rm -f "$(DEPDIR)/libamdis_la-MacroWriter.Tpo"; exit 1; fi +@AMDEP_TRUE@@am__fastdepCXX_FALSE@ source='$(SOURCE_DIR)/MacroWriter.cc' object='libamdis_la-MacroWriter.lo' libtool=yes @AMDEPBACKSLASH@ +@AMDEP_TRUE@@am__fastdepCXX_FALSE@ DEPDIR=$(DEPDIR) $(CXXDEPMODE) $(depcomp) @AMDEPBACKSLASH@ +@am__fastdepCXX_FALSE@ $(LIBTOOL) --tag=CXX --mode=compile $(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(libamdis_la_CXXFLAGS) $(CXXFLAGS) -c -o libamdis_la-MacroWriter.lo `test -f '$(SOURCE_DIR)/MacroWriter.cc' || echo '$(srcdir)/'`$(SOURCE_DIR)/MacroWriter.cc + +libamdis_la-Parameters.lo: $(SOURCE_DIR)/Parameters.cc +@am__fastdepCXX_TRUE@ if $(LIBTOOL) --tag=CXX --mode=compile $(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(libamdis_la_CXXFLAGS) $(CXXFLAGS) -MT libamdis_la-Parameters.lo -MD -MP -MF "$(DEPDIR)/libamdis_la-Parameters.Tpo" -c -o libamdis_la-Parameters.lo `test -f '$(SOURCE_DIR)/Parameters.cc' || echo '$(srcdir)/'`$(SOURCE_DIR)/Parameters.cc; \ +@am__fastdepCXX_TRUE@ then mv -f "$(DEPDIR)/libamdis_la-Parameters.Tpo" "$(DEPDIR)/libamdis_la-Parameters.Plo"; else rm -f "$(DEPDIR)/libamdis_la-Parameters.Tpo"; exit 1; fi +@AMDEP_TRUE@@am__fastdepCXX_FALSE@ source='$(SOURCE_DIR)/Parameters.cc' object='libamdis_la-Parameters.lo' libtool=yes @AMDEPBACKSLASH@ +@AMDEP_TRUE@@am__fastdepCXX_FALSE@ DEPDIR=$(DEPDIR) $(CXXDEPMODE) $(depcomp) @AMDEPBACKSLASH@ +@am__fastdepCXX_FALSE@ $(LIBTOOL) --tag=CXX --mode=compile $(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(libamdis_la_CXXFLAGS) $(CXXFLAGS) -c -o libamdis_la-Parameters.lo `test -f '$(SOURCE_DIR)/Parameters.cc' || echo '$(srcdir)/'`$(SOURCE_DIR)/Parameters.cc + +libamdis_la-Parametric.lo: $(SOURCE_DIR)/Parametric.cc +@am__fastdepCXX_TRUE@ if $(LIBTOOL) --tag=CXX --mode=compile $(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(libamdis_la_CXXFLAGS) $(CXXFLAGS) -MT libamdis_la-Parametric.lo -MD -MP -MF "$(DEPDIR)/libamdis_la-Parametric.Tpo" -c -o libamdis_la-Parametric.lo `test -f '$(SOURCE_DIR)/Parametric.cc' || echo '$(srcdir)/'`$(SOURCE_DIR)/Parametric.cc; \ +@am__fastdepCXX_TRUE@ then mv -f "$(DEPDIR)/libamdis_la-Parametric.Tpo" "$(DEPDIR)/libamdis_la-Parametric.Plo"; else rm -f "$(DEPDIR)/libamdis_la-Parametric.Tpo"; exit 1; fi +@AMDEP_TRUE@@am__fastdepCXX_FALSE@ source='$(SOURCE_DIR)/Parametric.cc' object='libamdis_la-Parametric.lo' libtool=yes @AMDEPBACKSLASH@ +@AMDEP_TRUE@@am__fastdepCXX_FALSE@ DEPDIR=$(DEPDIR) $(CXXDEPMODE) $(depcomp) @AMDEPBACKSLASH@ +@am__fastdepCXX_FALSE@ $(LIBTOOL) --tag=CXX --mode=compile $(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(libamdis_la_CXXFLAGS) $(CXXFLAGS) -c -o libamdis_la-Parametric.lo `test -f '$(SOURCE_DIR)/Parametric.cc' || echo '$(srcdir)/'`$(SOURCE_DIR)/Parametric.cc + +libamdis_la-Quadrature.lo: $(SOURCE_DIR)/Quadrature.cc +@am__fastdepCXX_TRUE@ if $(LIBTOOL) --tag=CXX --mode=compile $(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(libamdis_la_CXXFLAGS) $(CXXFLAGS) -MT libamdis_la-Quadrature.lo -MD -MP -MF "$(DEPDIR)/libamdis_la-Quadrature.Tpo" -c -o libamdis_la-Quadrature.lo `test -f '$(SOURCE_DIR)/Quadrature.cc' || echo '$(srcdir)/'`$(SOURCE_DIR)/Quadrature.cc; \ +@am__fastdepCXX_TRUE@ then mv -f "$(DEPDIR)/libamdis_la-Quadrature.Tpo" "$(DEPDIR)/libamdis_la-Quadrature.Plo"; else rm -f "$(DEPDIR)/libamdis_la-Quadrature.Tpo"; exit 1; fi +@AMDEP_TRUE@@am__fastdepCXX_FALSE@ source='$(SOURCE_DIR)/Quadrature.cc' object='libamdis_la-Quadrature.lo' libtool=yes @AMDEPBACKSLASH@ +@AMDEP_TRUE@@am__fastdepCXX_FALSE@ DEPDIR=$(DEPDIR) $(CXXDEPMODE) $(depcomp) @AMDEPBACKSLASH@ +@am__fastdepCXX_FALSE@ $(LIBTOOL) --tag=CXX --mode=compile $(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(libamdis_la_CXXFLAGS) $(CXXFLAGS) -c -o libamdis_la-Quadrature.lo `test -f '$(SOURCE_DIR)/Quadrature.cc' || echo '$(srcdir)/'`$(SOURCE_DIR)/Quadrature.cc + +libamdis_la-RCNeighbourList.lo: $(SOURCE_DIR)/RCNeighbourList.cc +@am__fastdepCXX_TRUE@ if $(LIBTOOL) --tag=CXX --mode=compile $(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(libamdis_la_CXXFLAGS) $(CXXFLAGS) -MT libamdis_la-RCNeighbourList.lo -MD -MP -MF "$(DEPDIR)/libamdis_la-RCNeighbourList.Tpo" -c -o libamdis_la-RCNeighbourList.lo `test -f '$(SOURCE_DIR)/RCNeighbourList.cc' || echo '$(srcdir)/'`$(SOURCE_DIR)/RCNeighbourList.cc; \ +@am__fastdepCXX_TRUE@ then mv -f "$(DEPDIR)/libamdis_la-RCNeighbourList.Tpo" "$(DEPDIR)/libamdis_la-RCNeighbourList.Plo"; else rm -f "$(DEPDIR)/libamdis_la-RCNeighbourList.Tpo"; exit 1; fi +@AMDEP_TRUE@@am__fastdepCXX_FALSE@ source='$(SOURCE_DIR)/RCNeighbourList.cc' object='libamdis_la-RCNeighbourList.lo' libtool=yes @AMDEPBACKSLASH@ +@AMDEP_TRUE@@am__fastdepCXX_FALSE@ DEPDIR=$(DEPDIR) $(CXXDEPMODE) $(depcomp) @AMDEPBACKSLASH@ +@am__fastdepCXX_FALSE@ $(LIBTOOL) --tag=CXX --mode=compile $(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(libamdis_la_CXXFLAGS) $(CXXFLAGS) -c -o libamdis_la-RCNeighbourList.lo `test -f '$(SOURCE_DIR)/RCNeighbourList.cc' || echo '$(srcdir)/'`$(SOURCE_DIR)/RCNeighbourList.cc + +libamdis_la-RefinementManager.lo: $(SOURCE_DIR)/RefinementManager.cc +@am__fastdepCXX_TRUE@ if $(LIBTOOL) --tag=CXX --mode=compile $(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(libamdis_la_CXXFLAGS) $(CXXFLAGS) -MT libamdis_la-RefinementManager.lo -MD -MP -MF "$(DEPDIR)/libamdis_la-RefinementManager.Tpo" -c -o libamdis_la-RefinementManager.lo `test -f '$(SOURCE_DIR)/RefinementManager.cc' || echo '$(srcdir)/'`$(SOURCE_DIR)/RefinementManager.cc; \ +@am__fastdepCXX_TRUE@ then mv -f "$(DEPDIR)/libamdis_la-RefinementManager.Tpo" "$(DEPDIR)/libamdis_la-RefinementManager.Plo"; else rm -f "$(DEPDIR)/libamdis_la-RefinementManager.Tpo"; exit 1; fi +@AMDEP_TRUE@@am__fastdepCXX_FALSE@ source='$(SOURCE_DIR)/RefinementManager.cc' object='libamdis_la-RefinementManager.lo' libtool=yes @AMDEPBACKSLASH@ +@AMDEP_TRUE@@am__fastdepCXX_FALSE@ DEPDIR=$(DEPDIR) $(CXXDEPMODE) $(depcomp) @AMDEPBACKSLASH@ +@am__fastdepCXX_FALSE@ $(LIBTOOL) --tag=CXX --mode=compile $(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(libamdis_la_CXXFLAGS) $(CXXFLAGS) -c -o libamdis_la-RefinementManager.lo `test -f '$(SOURCE_DIR)/RefinementManager.cc' || echo '$(srcdir)/'`$(SOURCE_DIR)/RefinementManager.cc + +libamdis_la-RefinementManager1d.lo: $(SOURCE_DIR)/RefinementManager1d.cc +@am__fastdepCXX_TRUE@ if $(LIBTOOL) --tag=CXX --mode=compile $(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(libamdis_la_CXXFLAGS) $(CXXFLAGS) -MT libamdis_la-RefinementManager1d.lo -MD -MP -MF "$(DEPDIR)/libamdis_la-RefinementManager1d.Tpo" -c -o libamdis_la-RefinementManager1d.lo `test -f '$(SOURCE_DIR)/RefinementManager1d.cc' || echo '$(srcdir)/'`$(SOURCE_DIR)/RefinementManager1d.cc; \ +@am__fastdepCXX_TRUE@ then mv -f "$(DEPDIR)/libamdis_la-RefinementManager1d.Tpo" "$(DEPDIR)/libamdis_la-RefinementManager1d.Plo"; else rm -f "$(DEPDIR)/libamdis_la-RefinementManager1d.Tpo"; exit 1; fi +@AMDEP_TRUE@@am__fastdepCXX_FALSE@ source='$(SOURCE_DIR)/RefinementManager1d.cc' object='libamdis_la-RefinementManager1d.lo' libtool=yes @AMDEPBACKSLASH@ +@AMDEP_TRUE@@am__fastdepCXX_FALSE@ DEPDIR=$(DEPDIR) $(CXXDEPMODE) $(depcomp) @AMDEPBACKSLASH@ +@am__fastdepCXX_FALSE@ $(LIBTOOL) --tag=CXX --mode=compile $(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(libamdis_la_CXXFLAGS) $(CXXFLAGS) -c -o libamdis_la-RefinementManager1d.lo `test -f '$(SOURCE_DIR)/RefinementManager1d.cc' || echo '$(srcdir)/'`$(SOURCE_DIR)/RefinementManager1d.cc + +libamdis_la-RefinementManager2d.lo: $(SOURCE_DIR)/RefinementManager2d.cc +@am__fastdepCXX_TRUE@ if $(LIBTOOL) --tag=CXX --mode=compile $(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(libamdis_la_CXXFLAGS) $(CXXFLAGS) -MT libamdis_la-RefinementManager2d.lo -MD -MP -MF "$(DEPDIR)/libamdis_la-RefinementManager2d.Tpo" -c -o libamdis_la-RefinementManager2d.lo `test -f '$(SOURCE_DIR)/RefinementManager2d.cc' || echo '$(srcdir)/'`$(SOURCE_DIR)/RefinementManager2d.cc; \ +@am__fastdepCXX_TRUE@ then mv -f "$(DEPDIR)/libamdis_la-RefinementManager2d.Tpo" "$(DEPDIR)/libamdis_la-RefinementManager2d.Plo"; else rm -f "$(DEPDIR)/libamdis_la-RefinementManager2d.Tpo"; exit 1; fi +@AMDEP_TRUE@@am__fastdepCXX_FALSE@ source='$(SOURCE_DIR)/RefinementManager2d.cc' object='libamdis_la-RefinementManager2d.lo' libtool=yes @AMDEPBACKSLASH@ +@AMDEP_TRUE@@am__fastdepCXX_FALSE@ DEPDIR=$(DEPDIR) $(CXXDEPMODE) $(depcomp) @AMDEPBACKSLASH@ +@am__fastdepCXX_FALSE@ $(LIBTOOL) --tag=CXX --mode=compile $(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(libamdis_la_CXXFLAGS) $(CXXFLAGS) -c -o libamdis_la-RefinementManager2d.lo `test -f '$(SOURCE_DIR)/RefinementManager2d.cc' || echo '$(srcdir)/'`$(SOURCE_DIR)/RefinementManager2d.cc + +libamdis_la-RefinementManager3d.lo: $(SOURCE_DIR)/RefinementManager3d.cc +@am__fastdepCXX_TRUE@ if $(LIBTOOL) --tag=CXX --mode=compile $(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(libamdis_la_CXXFLAGS) $(CXXFLAGS) -MT libamdis_la-RefinementManager3d.lo -MD -MP -MF "$(DEPDIR)/libamdis_la-RefinementManager3d.Tpo" -c -o libamdis_la-RefinementManager3d.lo `test -f '$(SOURCE_DIR)/RefinementManager3d.cc' || echo '$(srcdir)/'`$(SOURCE_DIR)/RefinementManager3d.cc; \ +@am__fastdepCXX_TRUE@ then mv -f "$(DEPDIR)/libamdis_la-RefinementManager3d.Tpo" "$(DEPDIR)/libamdis_la-RefinementManager3d.Plo"; else rm -f "$(DEPDIR)/libamdis_la-RefinementManager3d.Tpo"; exit 1; fi +@AMDEP_TRUE@@am__fastdepCXX_FALSE@ source='$(SOURCE_DIR)/RefinementManager3d.cc' object='libamdis_la-RefinementManager3d.lo' libtool=yes @AMDEPBACKSLASH@ +@AMDEP_TRUE@@am__fastdepCXX_FALSE@ DEPDIR=$(DEPDIR) $(CXXDEPMODE) $(depcomp) @AMDEPBACKSLASH@ +@am__fastdepCXX_FALSE@ $(LIBTOOL) --tag=CXX --mode=compile $(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(libamdis_la_CXXFLAGS) $(CXXFLAGS) -c -o libamdis_la-RefinementManager3d.lo `test -f '$(SOURCE_DIR)/RefinementManager3d.cc' || echo '$(srcdir)/'`$(SOURCE_DIR)/RefinementManager3d.cc + +libamdis_la-Tetrahedron.lo: $(SOURCE_DIR)/Tetrahedron.cc +@am__fastdepCXX_TRUE@ if $(LIBTOOL) --tag=CXX --mode=compile $(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(libamdis_la_CXXFLAGS) $(CXXFLAGS) -MT libamdis_la-Tetrahedron.lo -MD -MP -MF "$(DEPDIR)/libamdis_la-Tetrahedron.Tpo" -c -o libamdis_la-Tetrahedron.lo `test -f '$(SOURCE_DIR)/Tetrahedron.cc' || echo '$(srcdir)/'`$(SOURCE_DIR)/Tetrahedron.cc; \ +@am__fastdepCXX_TRUE@ then mv -f "$(DEPDIR)/libamdis_la-Tetrahedron.Tpo" "$(DEPDIR)/libamdis_la-Tetrahedron.Plo"; else rm -f "$(DEPDIR)/libamdis_la-Tetrahedron.Tpo"; exit 1; fi +@AMDEP_TRUE@@am__fastdepCXX_FALSE@ source='$(SOURCE_DIR)/Tetrahedron.cc' object='libamdis_la-Tetrahedron.lo' libtool=yes @AMDEPBACKSLASH@ +@AMDEP_TRUE@@am__fastdepCXX_FALSE@ DEPDIR=$(DEPDIR) $(CXXDEPMODE) $(depcomp) @AMDEPBACKSLASH@ +@am__fastdepCXX_FALSE@ $(LIBTOOL) --tag=CXX --mode=compile $(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(libamdis_la_CXXFLAGS) $(CXXFLAGS) -c -o libamdis_la-Tetrahedron.lo `test -f '$(SOURCE_DIR)/Tetrahedron.cc' || echo '$(srcdir)/'`$(SOURCE_DIR)/Tetrahedron.cc + +libamdis_la-Traverse.lo: $(SOURCE_DIR)/Traverse.cc +@am__fastdepCXX_TRUE@ if $(LIBTOOL) --tag=CXX --mode=compile $(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(libamdis_la_CXXFLAGS) $(CXXFLAGS) -MT libamdis_la-Traverse.lo -MD -MP -MF "$(DEPDIR)/libamdis_la-Traverse.Tpo" -c -o libamdis_la-Traverse.lo `test -f '$(SOURCE_DIR)/Traverse.cc' || echo '$(srcdir)/'`$(SOURCE_DIR)/Traverse.cc; \ +@am__fastdepCXX_TRUE@ then mv -f "$(DEPDIR)/libamdis_la-Traverse.Tpo" "$(DEPDIR)/libamdis_la-Traverse.Plo"; else rm -f "$(DEPDIR)/libamdis_la-Traverse.Tpo"; exit 1; fi +@AMDEP_TRUE@@am__fastdepCXX_FALSE@ source='$(SOURCE_DIR)/Traverse.cc' object='libamdis_la-Traverse.lo' libtool=yes @AMDEPBACKSLASH@ +@AMDEP_TRUE@@am__fastdepCXX_FALSE@ DEPDIR=$(DEPDIR) $(CXXDEPMODE) $(depcomp) @AMDEPBACKSLASH@ +@am__fastdepCXX_FALSE@ $(LIBTOOL) --tag=CXX --mode=compile $(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(libamdis_la_CXXFLAGS) $(CXXFLAGS) -c -o libamdis_la-Traverse.lo `test -f '$(SOURCE_DIR)/Traverse.cc' || echo '$(srcdir)/'`$(SOURCE_DIR)/Traverse.cc + +libamdis_la-Triangle.lo: $(SOURCE_DIR)/Triangle.cc +@am__fastdepCXX_TRUE@ if $(LIBTOOL) --tag=CXX --mode=compile $(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(libamdis_la_CXXFLAGS) $(CXXFLAGS) -MT libamdis_la-Triangle.lo -MD -MP -MF "$(DEPDIR)/libamdis_la-Triangle.Tpo" -c -o libamdis_la-Triangle.lo `test -f '$(SOURCE_DIR)/Triangle.cc' || echo '$(srcdir)/'`$(SOURCE_DIR)/Triangle.cc; \ +@am__fastdepCXX_TRUE@ then mv -f "$(DEPDIR)/libamdis_la-Triangle.Tpo" "$(DEPDIR)/libamdis_la-Triangle.Plo"; else rm -f "$(DEPDIR)/libamdis_la-Triangle.Tpo"; exit 1; fi +@AMDEP_TRUE@@am__fastdepCXX_FALSE@ source='$(SOURCE_DIR)/Triangle.cc' object='libamdis_la-Triangle.lo' libtool=yes @AMDEPBACKSLASH@ +@AMDEP_TRUE@@am__fastdepCXX_FALSE@ DEPDIR=$(DEPDIR) $(CXXDEPMODE) $(depcomp) @AMDEPBACKSLASH@ +@am__fastdepCXX_FALSE@ $(LIBTOOL) --tag=CXX --mode=compile $(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(libamdis_la_CXXFLAGS) $(CXXFLAGS) -c -o libamdis_la-Triangle.lo `test -f '$(SOURCE_DIR)/Triangle.cc' || echo '$(srcdir)/'`$(SOURCE_DIR)/Triangle.cc + +libamdis_la-TecPlotWriter.lo: $(SOURCE_DIR)/TecPlotWriter.cc +@am__fastdepCXX_TRUE@ if $(LIBTOOL) --tag=CXX --mode=compile $(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(libamdis_la_CXXFLAGS) $(CXXFLAGS) -MT libamdis_la-TecPlotWriter.lo -MD -MP -MF "$(DEPDIR)/libamdis_la-TecPlotWriter.Tpo" -c -o libamdis_la-TecPlotWriter.lo `test -f '$(SOURCE_DIR)/TecPlotWriter.cc' || echo '$(srcdir)/'`$(SOURCE_DIR)/TecPlotWriter.cc; \ +@am__fastdepCXX_TRUE@ then mv -f "$(DEPDIR)/libamdis_la-TecPlotWriter.Tpo" "$(DEPDIR)/libamdis_la-TecPlotWriter.Plo"; else rm -f "$(DEPDIR)/libamdis_la-TecPlotWriter.Tpo"; exit 1; fi +@AMDEP_TRUE@@am__fastdepCXX_FALSE@ source='$(SOURCE_DIR)/TecPlotWriter.cc' object='libamdis_la-TecPlotWriter.lo' libtool=yes @AMDEPBACKSLASH@ +@AMDEP_TRUE@@am__fastdepCXX_FALSE@ DEPDIR=$(DEPDIR) $(CXXDEPMODE) $(depcomp) @AMDEPBACKSLASH@ +@am__fastdepCXX_FALSE@ $(LIBTOOL) --tag=CXX --mode=compile $(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(libamdis_la_CXXFLAGS) $(CXXFLAGS) -c -o libamdis_la-TecPlotWriter.lo `test -f '$(SOURCE_DIR)/TecPlotWriter.cc' || echo '$(srcdir)/'`$(SOURCE_DIR)/TecPlotWriter.cc + +libamdis_la-ValueWriter.lo: $(SOURCE_DIR)/ValueWriter.cc +@am__fastdepCXX_TRUE@ if $(LIBTOOL) --tag=CXX --mode=compile $(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(libamdis_la_CXXFLAGS) $(CXXFLAGS) -MT libamdis_la-ValueWriter.lo -MD -MP -MF "$(DEPDIR)/libamdis_la-ValueWriter.Tpo" -c -o libamdis_la-ValueWriter.lo `test -f '$(SOURCE_DIR)/ValueWriter.cc' || echo '$(srcdir)/'`$(SOURCE_DIR)/ValueWriter.cc; \ +@am__fastdepCXX_TRUE@ then mv -f "$(DEPDIR)/libamdis_la-ValueWriter.Tpo" "$(DEPDIR)/libamdis_la-ValueWriter.Plo"; else rm -f "$(DEPDIR)/libamdis_la-ValueWriter.Tpo"; exit 1; fi +@AMDEP_TRUE@@am__fastdepCXX_FALSE@ source='$(SOURCE_DIR)/ValueWriter.cc' object='libamdis_la-ValueWriter.lo' libtool=yes @AMDEPBACKSLASH@ +@AMDEP_TRUE@@am__fastdepCXX_FALSE@ DEPDIR=$(DEPDIR) $(CXXDEPMODE) $(depcomp) @AMDEPBACKSLASH@ +@am__fastdepCXX_FALSE@ $(LIBTOOL) --tag=CXX --mode=compile $(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(libamdis_la_CXXFLAGS) $(CXXFLAGS) -c -o libamdis_la-ValueWriter.lo `test -f '$(SOURCE_DIR)/ValueWriter.cc' || echo '$(srcdir)/'`$(SOURCE_DIR)/ValueWriter.cc + +libamdis_la-MemoryPool.lo: $(SOURCE_DIR)/MemoryPool.cc +@am__fastdepCXX_TRUE@ if $(LIBTOOL) --tag=CXX --mode=compile $(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(libamdis_la_CXXFLAGS) $(CXXFLAGS) -MT libamdis_la-MemoryPool.lo -MD -MP -MF "$(DEPDIR)/libamdis_la-MemoryPool.Tpo" -c -o libamdis_la-MemoryPool.lo `test -f '$(SOURCE_DIR)/MemoryPool.cc' || echo '$(srcdir)/'`$(SOURCE_DIR)/MemoryPool.cc; \ +@am__fastdepCXX_TRUE@ then mv -f "$(DEPDIR)/libamdis_la-MemoryPool.Tpo" "$(DEPDIR)/libamdis_la-MemoryPool.Plo"; else rm -f "$(DEPDIR)/libamdis_la-MemoryPool.Tpo"; exit 1; fi +@AMDEP_TRUE@@am__fastdepCXX_FALSE@ source='$(SOURCE_DIR)/MemoryPool.cc' object='libamdis_la-MemoryPool.lo' libtool=yes @AMDEPBACKSLASH@ +@AMDEP_TRUE@@am__fastdepCXX_FALSE@ DEPDIR=$(DEPDIR) $(CXXDEPMODE) $(depcomp) @AMDEPBACKSLASH@ +@am__fastdepCXX_FALSE@ $(LIBTOOL) --tag=CXX --mode=compile $(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(libamdis_la_CXXFLAGS) $(CXXFLAGS) -c -o libamdis_la-MemoryPool.lo `test -f '$(SOURCE_DIR)/MemoryPool.cc' || echo '$(srcdir)/'`$(SOURCE_DIR)/MemoryPool.cc + +libamdis_la-MemoryManager.lo: $(SOURCE_DIR)/MemoryManager.cc +@am__fastdepCXX_TRUE@ if $(LIBTOOL) --tag=CXX --mode=compile $(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(libamdis_la_CXXFLAGS) $(CXXFLAGS) -MT libamdis_la-MemoryManager.lo -MD -MP -MF "$(DEPDIR)/libamdis_la-MemoryManager.Tpo" -c -o libamdis_la-MemoryManager.lo `test -f '$(SOURCE_DIR)/MemoryManager.cc' || echo '$(srcdir)/'`$(SOURCE_DIR)/MemoryManager.cc; \ +@am__fastdepCXX_TRUE@ then mv -f "$(DEPDIR)/libamdis_la-MemoryManager.Tpo" "$(DEPDIR)/libamdis_la-MemoryManager.Plo"; else rm -f "$(DEPDIR)/libamdis_la-MemoryManager.Tpo"; exit 1; fi +@AMDEP_TRUE@@am__fastdepCXX_FALSE@ source='$(SOURCE_DIR)/MemoryManager.cc' object='libamdis_la-MemoryManager.lo' libtool=yes @AMDEPBACKSLASH@ +@AMDEP_TRUE@@am__fastdepCXX_FALSE@ DEPDIR=$(DEPDIR) $(CXXDEPMODE) $(depcomp) @AMDEPBACKSLASH@ +@am__fastdepCXX_FALSE@ $(LIBTOOL) --tag=CXX --mode=compile $(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(libamdis_la_CXXFLAGS) $(CXXFLAGS) -c -o libamdis_la-MemoryManager.lo `test -f '$(SOURCE_DIR)/MemoryManager.cc' || echo '$(srcdir)/'`$(SOURCE_DIR)/MemoryManager.cc + +libamdis_la-VtkWriter.lo: $(SOURCE_DIR)/VtkWriter.cc +@am__fastdepCXX_TRUE@ if $(LIBTOOL) --tag=CXX --mode=compile $(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(libamdis_la_CXXFLAGS) $(CXXFLAGS) -MT libamdis_la-VtkWriter.lo -MD -MP -MF "$(DEPDIR)/libamdis_la-VtkWriter.Tpo" -c -o libamdis_la-VtkWriter.lo `test -f '$(SOURCE_DIR)/VtkWriter.cc' || echo '$(srcdir)/'`$(SOURCE_DIR)/VtkWriter.cc; \ +@am__fastdepCXX_TRUE@ then mv -f "$(DEPDIR)/libamdis_la-VtkWriter.Tpo" "$(DEPDIR)/libamdis_la-VtkWriter.Plo"; else rm -f "$(DEPDIR)/libamdis_la-VtkWriter.Tpo"; exit 1; fi +@AMDEP_TRUE@@am__fastdepCXX_FALSE@ source='$(SOURCE_DIR)/VtkWriter.cc' object='libamdis_la-VtkWriter.lo' libtool=yes @AMDEPBACKSLASH@ +@AMDEP_TRUE@@am__fastdepCXX_FALSE@ DEPDIR=$(DEPDIR) $(CXXDEPMODE) $(depcomp) @AMDEPBACKSLASH@ +@am__fastdepCXX_FALSE@ $(LIBTOOL) --tag=CXX --mode=compile $(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(libamdis_la_CXXFLAGS) $(CXXFLAGS) -c -o libamdis_la-VtkWriter.lo `test -f '$(SOURCE_DIR)/VtkWriter.cc' || echo '$(srcdir)/'`$(SOURCE_DIR)/VtkWriter.cc + +libamdis_la-DataCollector.lo: $(SOURCE_DIR)/DataCollector.cc +@am__fastdepCXX_TRUE@ if $(LIBTOOL) --tag=CXX --mode=compile $(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(libamdis_la_CXXFLAGS) $(CXXFLAGS) -MT libamdis_la-DataCollector.lo -MD -MP -MF "$(DEPDIR)/libamdis_la-DataCollector.Tpo" -c -o libamdis_la-DataCollector.lo `test -f '$(SOURCE_DIR)/DataCollector.cc' || echo '$(srcdir)/'`$(SOURCE_DIR)/DataCollector.cc; \ +@am__fastdepCXX_TRUE@ then mv -f "$(DEPDIR)/libamdis_la-DataCollector.Tpo" "$(DEPDIR)/libamdis_la-DataCollector.Plo"; else rm -f "$(DEPDIR)/libamdis_la-DataCollector.Tpo"; exit 1; fi +@AMDEP_TRUE@@am__fastdepCXX_FALSE@ source='$(SOURCE_DIR)/DataCollector.cc' object='libamdis_la-DataCollector.lo' libtool=yes @AMDEPBACKSLASH@ +@AMDEP_TRUE@@am__fastdepCXX_FALSE@ DEPDIR=$(DEPDIR) $(CXXDEPMODE) $(depcomp) @AMDEPBACKSLASH@ +@am__fastdepCXX_FALSE@ $(LIBTOOL) --tag=CXX --mode=compile $(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(libamdis_la_CXXFLAGS) $(CXXFLAGS) -c -o libamdis_la-DataCollector.lo `test -f '$(SOURCE_DIR)/DataCollector.cc' || echo '$(srcdir)/'`$(SOURCE_DIR)/DataCollector.cc + +libcompositeFEM_la-CFE_Integration.lo: $(COMPOSITE_SOURCE_DIR)/CFE_Integration.cc +@am__fastdepCXX_TRUE@ if $(LIBTOOL) --tag=CXX --mode=compile $(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(libcompositeFEM_la_CXXFLAGS) $(CXXFLAGS) -MT libcompositeFEM_la-CFE_Integration.lo -MD -MP -MF "$(DEPDIR)/libcompositeFEM_la-CFE_Integration.Tpo" -c -o libcompositeFEM_la-CFE_Integration.lo `test -f '$(COMPOSITE_SOURCE_DIR)/CFE_Integration.cc' || echo '$(srcdir)/'`$(COMPOSITE_SOURCE_DIR)/CFE_Integration.cc; \ +@am__fastdepCXX_TRUE@ then mv -f "$(DEPDIR)/libcompositeFEM_la-CFE_Integration.Tpo" "$(DEPDIR)/libcompositeFEM_la-CFE_Integration.Plo"; else rm -f "$(DEPDIR)/libcompositeFEM_la-CFE_Integration.Tpo"; exit 1; fi +@AMDEP_TRUE@@am__fastdepCXX_FALSE@ source='$(COMPOSITE_SOURCE_DIR)/CFE_Integration.cc' object='libcompositeFEM_la-CFE_Integration.lo' libtool=yes @AMDEPBACKSLASH@ +@AMDEP_TRUE@@am__fastdepCXX_FALSE@ DEPDIR=$(DEPDIR) $(CXXDEPMODE) $(depcomp) @AMDEPBACKSLASH@ +@am__fastdepCXX_FALSE@ $(LIBTOOL) --tag=CXX --mode=compile $(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(libcompositeFEM_la_CXXFLAGS) $(CXXFLAGS) -c -o libcompositeFEM_la-CFE_Integration.lo `test -f '$(COMPOSITE_SOURCE_DIR)/CFE_Integration.cc' || echo '$(srcdir)/'`$(COMPOSITE_SOURCE_DIR)/CFE_Integration.cc + +libcompositeFEM_la-CFE_NormAndErrorFcts.lo: $(COMPOSITE_SOURCE_DIR)/CFE_NormAndErrorFcts.cc +@am__fastdepCXX_TRUE@ if $(LIBTOOL) --tag=CXX --mode=compile $(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(libcompositeFEM_la_CXXFLAGS) $(CXXFLAGS) -MT libcompositeFEM_la-CFE_NormAndErrorFcts.lo -MD -MP -MF "$(DEPDIR)/libcompositeFEM_la-CFE_NormAndErrorFcts.Tpo" -c -o libcompositeFEM_la-CFE_NormAndErrorFcts.lo `test -f '$(COMPOSITE_SOURCE_DIR)/CFE_NormAndErrorFcts.cc' || echo '$(srcdir)/'`$(COMPOSITE_SOURCE_DIR)/CFE_NormAndErrorFcts.cc; \ +@am__fastdepCXX_TRUE@ then mv -f "$(DEPDIR)/libcompositeFEM_la-CFE_NormAndErrorFcts.Tpo" "$(DEPDIR)/libcompositeFEM_la-CFE_NormAndErrorFcts.Plo"; else rm -f "$(DEPDIR)/libcompositeFEM_la-CFE_NormAndErrorFcts.Tpo"; exit 1; fi +@AMDEP_TRUE@@am__fastdepCXX_FALSE@ source='$(COMPOSITE_SOURCE_DIR)/CFE_NormAndErrorFcts.cc' object='libcompositeFEM_la-CFE_NormAndErrorFcts.lo' libtool=yes @AMDEPBACKSLASH@ +@AMDEP_TRUE@@am__fastdepCXX_FALSE@ DEPDIR=$(DEPDIR) $(CXXDEPMODE) $(depcomp) @AMDEPBACKSLASH@ +@am__fastdepCXX_FALSE@ $(LIBTOOL) --tag=CXX --mode=compile $(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(libcompositeFEM_la_CXXFLAGS) $(CXXFLAGS) -c -o libcompositeFEM_la-CFE_NormAndErrorFcts.lo `test -f '$(COMPOSITE_SOURCE_DIR)/CFE_NormAndErrorFcts.cc' || echo '$(srcdir)/'`$(COMPOSITE_SOURCE_DIR)/CFE_NormAndErrorFcts.cc + +libcompositeFEM_la-CompositeFEMMethods.lo: $(COMPOSITE_SOURCE_DIR)/CompositeFEMMethods.cc +@am__fastdepCXX_TRUE@ if $(LIBTOOL) --tag=CXX --mode=compile $(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(libcompositeFEM_la_CXXFLAGS) $(CXXFLAGS) -MT libcompositeFEM_la-CompositeFEMMethods.lo -MD -MP -MF "$(DEPDIR)/libcompositeFEM_la-CompositeFEMMethods.Tpo" -c -o libcompositeFEM_la-CompositeFEMMethods.lo `test -f '$(COMPOSITE_SOURCE_DIR)/CompositeFEMMethods.cc' || echo '$(srcdir)/'`$(COMPOSITE_SOURCE_DIR)/CompositeFEMMethods.cc; \ +@am__fastdepCXX_TRUE@ then mv -f "$(DEPDIR)/libcompositeFEM_la-CompositeFEMMethods.Tpo" "$(DEPDIR)/libcompositeFEM_la-CompositeFEMMethods.Plo"; else rm -f "$(DEPDIR)/libcompositeFEM_la-CompositeFEMMethods.Tpo"; exit 1; fi +@AMDEP_TRUE@@am__fastdepCXX_FALSE@ source='$(COMPOSITE_SOURCE_DIR)/CompositeFEMMethods.cc' object='libcompositeFEM_la-CompositeFEMMethods.lo' libtool=yes @AMDEPBACKSLASH@ +@AMDEP_TRUE@@am__fastdepCXX_FALSE@ DEPDIR=$(DEPDIR) $(CXXDEPMODE) $(depcomp) @AMDEPBACKSLASH@ +@am__fastdepCXX_FALSE@ $(LIBTOOL) --tag=CXX --mode=compile $(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(libcompositeFEM_la_CXXFLAGS) $(CXXFLAGS) -c -o libcompositeFEM_la-CompositeFEMMethods.lo `test -f '$(COMPOSITE_SOURCE_DIR)/CompositeFEMMethods.cc' || echo '$(srcdir)/'`$(COMPOSITE_SOURCE_DIR)/CompositeFEMMethods.cc + +libcompositeFEM_la-LevelSetAdaptMesh.lo: $(COMPOSITE_SOURCE_DIR)/LevelSetAdaptMesh.cc +@am__fastdepCXX_TRUE@ if $(LIBTOOL) --tag=CXX --mode=compile $(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(libcompositeFEM_la_CXXFLAGS) $(CXXFLAGS) -MT libcompositeFEM_la-LevelSetAdaptMesh.lo -MD -MP -MF "$(DEPDIR)/libcompositeFEM_la-LevelSetAdaptMesh.Tpo" -c -o libcompositeFEM_la-LevelSetAdaptMesh.lo `test -f '$(COMPOSITE_SOURCE_DIR)/LevelSetAdaptMesh.cc' || echo '$(srcdir)/'`$(COMPOSITE_SOURCE_DIR)/LevelSetAdaptMesh.cc; \ +@am__fastdepCXX_TRUE@ then mv -f "$(DEPDIR)/libcompositeFEM_la-LevelSetAdaptMesh.Tpo" "$(DEPDIR)/libcompositeFEM_la-LevelSetAdaptMesh.Plo"; else rm -f "$(DEPDIR)/libcompositeFEM_la-LevelSetAdaptMesh.Tpo"; exit 1; fi +@AMDEP_TRUE@@am__fastdepCXX_FALSE@ source='$(COMPOSITE_SOURCE_DIR)/LevelSetAdaptMesh.cc' object='libcompositeFEM_la-LevelSetAdaptMesh.lo' libtool=yes @AMDEPBACKSLASH@ +@AMDEP_TRUE@@am__fastdepCXX_FALSE@ DEPDIR=$(DEPDIR) $(CXXDEPMODE) $(depcomp) @AMDEPBACKSLASH@ +@am__fastdepCXX_FALSE@ $(LIBTOOL) --tag=CXX --mode=compile $(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(libcompositeFEM_la_CXXFLAGS) $(CXXFLAGS) -c -o libcompositeFEM_la-LevelSetAdaptMesh.lo `test -f '$(COMPOSITE_SOURCE_DIR)/LevelSetAdaptMesh.cc' || echo '$(srcdir)/'`$(COMPOSITE_SOURCE_DIR)/LevelSetAdaptMesh.cc + +libcompositeFEM_la-PenaltyOperator.lo: $(COMPOSITE_SOURCE_DIR)/PenaltyOperator.cc +@am__fastdepCXX_TRUE@ if $(LIBTOOL) --tag=CXX --mode=compile $(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(libcompositeFEM_la_CXXFLAGS) $(CXXFLAGS) -MT libcompositeFEM_la-PenaltyOperator.lo -MD -MP -MF "$(DEPDIR)/libcompositeFEM_la-PenaltyOperator.Tpo" -c -o libcompositeFEM_la-PenaltyOperator.lo `test -f '$(COMPOSITE_SOURCE_DIR)/PenaltyOperator.cc' || echo '$(srcdir)/'`$(COMPOSITE_SOURCE_DIR)/PenaltyOperator.cc; \ +@am__fastdepCXX_TRUE@ then mv -f "$(DEPDIR)/libcompositeFEM_la-PenaltyOperator.Tpo" "$(DEPDIR)/libcompositeFEM_la-PenaltyOperator.Plo"; else rm -f "$(DEPDIR)/libcompositeFEM_la-PenaltyOperator.Tpo"; exit 1; fi +@AMDEP_TRUE@@am__fastdepCXX_FALSE@ source='$(COMPOSITE_SOURCE_DIR)/PenaltyOperator.cc' object='libcompositeFEM_la-PenaltyOperator.lo' libtool=yes @AMDEPBACKSLASH@ +@AMDEP_TRUE@@am__fastdepCXX_FALSE@ DEPDIR=$(DEPDIR) $(CXXDEPMODE) $(depcomp) @AMDEPBACKSLASH@ +@am__fastdepCXX_FALSE@ $(LIBTOOL) --tag=CXX --mode=compile $(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(libcompositeFEM_la_CXXFLAGS) $(CXXFLAGS) -c -o libcompositeFEM_la-PenaltyOperator.lo `test -f '$(COMPOSITE_SOURCE_DIR)/PenaltyOperator.cc' || echo '$(srcdir)/'`$(COMPOSITE_SOURCE_DIR)/PenaltyOperator.cc + +libcompositeFEM_la-ElementLevelSet.lo: $(COMPOSITE_SOURCE_DIR)/ElementLevelSet.cc +@am__fastdepCXX_TRUE@ if $(LIBTOOL) --tag=CXX --mode=compile $(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(libcompositeFEM_la_CXXFLAGS) $(CXXFLAGS) -MT libcompositeFEM_la-ElementLevelSet.lo -MD -MP -MF "$(DEPDIR)/libcompositeFEM_la-ElementLevelSet.Tpo" -c -o libcompositeFEM_la-ElementLevelSet.lo `test -f '$(COMPOSITE_SOURCE_DIR)/ElementLevelSet.cc' || echo '$(srcdir)/'`$(COMPOSITE_SOURCE_DIR)/ElementLevelSet.cc; \ +@am__fastdepCXX_TRUE@ then mv -f "$(DEPDIR)/libcompositeFEM_la-ElementLevelSet.Tpo" "$(DEPDIR)/libcompositeFEM_la-ElementLevelSet.Plo"; else rm -f "$(DEPDIR)/libcompositeFEM_la-ElementLevelSet.Tpo"; exit 1; fi +@AMDEP_TRUE@@am__fastdepCXX_FALSE@ source='$(COMPOSITE_SOURCE_DIR)/ElementLevelSet.cc' object='libcompositeFEM_la-ElementLevelSet.lo' libtool=yes @AMDEPBACKSLASH@ +@AMDEP_TRUE@@am__fastdepCXX_FALSE@ DEPDIR=$(DEPDIR) $(CXXDEPMODE) $(depcomp) @AMDEPBACKSLASH@ +@am__fastdepCXX_FALSE@ $(LIBTOOL) --tag=CXX --mode=compile $(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(libcompositeFEM_la_CXXFLAGS) $(CXXFLAGS) -c -o libcompositeFEM_la-ElementLevelSet.lo `test -f '$(COMPOSITE_SOURCE_DIR)/ElementLevelSet.cc' || echo '$(srcdir)/'`$(COMPOSITE_SOURCE_DIR)/ElementLevelSet.cc + +libcompositeFEM_la-CompositeFEMOperator.lo: $(COMPOSITE_SOURCE_DIR)/CompositeFEMOperator.cc +@am__fastdepCXX_TRUE@ if $(LIBTOOL) --tag=CXX --mode=compile $(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(libcompositeFEM_la_CXXFLAGS) $(CXXFLAGS) -MT libcompositeFEM_la-CompositeFEMOperator.lo -MD -MP -MF "$(DEPDIR)/libcompositeFEM_la-CompositeFEMOperator.Tpo" -c -o libcompositeFEM_la-CompositeFEMOperator.lo `test -f '$(COMPOSITE_SOURCE_DIR)/CompositeFEMOperator.cc' || echo '$(srcdir)/'`$(COMPOSITE_SOURCE_DIR)/CompositeFEMOperator.cc; \ +@am__fastdepCXX_TRUE@ then mv -f "$(DEPDIR)/libcompositeFEM_la-CompositeFEMOperator.Tpo" "$(DEPDIR)/libcompositeFEM_la-CompositeFEMOperator.Plo"; else rm -f "$(DEPDIR)/libcompositeFEM_la-CompositeFEMOperator.Tpo"; exit 1; fi +@AMDEP_TRUE@@am__fastdepCXX_FALSE@ source='$(COMPOSITE_SOURCE_DIR)/CompositeFEMOperator.cc' object='libcompositeFEM_la-CompositeFEMOperator.lo' libtool=yes @AMDEPBACKSLASH@ +@AMDEP_TRUE@@am__fastdepCXX_FALSE@ DEPDIR=$(DEPDIR) $(CXXDEPMODE) $(depcomp) @AMDEPBACKSLASH@ +@am__fastdepCXX_FALSE@ $(LIBTOOL) --tag=CXX --mode=compile $(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(libcompositeFEM_la_CXXFLAGS) $(CXXFLAGS) -c -o libcompositeFEM_la-CompositeFEMOperator.lo `test -f '$(COMPOSITE_SOURCE_DIR)/CompositeFEMOperator.cc' || echo '$(srcdir)/'`$(COMPOSITE_SOURCE_DIR)/CompositeFEMOperator.cc + +libcompositeFEM_la-SubPolytope.lo: $(COMPOSITE_SOURCE_DIR)/SubPolytope.cc +@am__fastdepCXX_TRUE@ if $(LIBTOOL) --tag=CXX --mode=compile $(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(libcompositeFEM_la_CXXFLAGS) $(CXXFLAGS) -MT libcompositeFEM_la-SubPolytope.lo -MD -MP -MF "$(DEPDIR)/libcompositeFEM_la-SubPolytope.Tpo" -c -o libcompositeFEM_la-SubPolytope.lo `test -f '$(COMPOSITE_SOURCE_DIR)/SubPolytope.cc' || echo '$(srcdir)/'`$(COMPOSITE_SOURCE_DIR)/SubPolytope.cc; \ +@am__fastdepCXX_TRUE@ then mv -f "$(DEPDIR)/libcompositeFEM_la-SubPolytope.Tpo" "$(DEPDIR)/libcompositeFEM_la-SubPolytope.Plo"; else rm -f "$(DEPDIR)/libcompositeFEM_la-SubPolytope.Tpo"; exit 1; fi +@AMDEP_TRUE@@am__fastdepCXX_FALSE@ source='$(COMPOSITE_SOURCE_DIR)/SubPolytope.cc' object='libcompositeFEM_la-SubPolytope.lo' libtool=yes @AMDEPBACKSLASH@ +@AMDEP_TRUE@@am__fastdepCXX_FALSE@ DEPDIR=$(DEPDIR) $(CXXDEPMODE) $(depcomp) @AMDEPBACKSLASH@ +@am__fastdepCXX_FALSE@ $(LIBTOOL) --tag=CXX --mode=compile $(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(libcompositeFEM_la_CXXFLAGS) $(CXXFLAGS) -c -o libcompositeFEM_la-SubPolytope.lo `test -f '$(COMPOSITE_SOURCE_DIR)/SubPolytope.cc' || echo '$(srcdir)/'`$(COMPOSITE_SOURCE_DIR)/SubPolytope.cc + +libcompositeFEM_la-ScalableQuadrature.lo: $(COMPOSITE_SOURCE_DIR)/ScalableQuadrature.cc +@am__fastdepCXX_TRUE@ if $(LIBTOOL) --tag=CXX --mode=compile $(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(libcompositeFEM_la_CXXFLAGS) $(CXXFLAGS) -MT libcompositeFEM_la-ScalableQuadrature.lo -MD -MP -MF "$(DEPDIR)/libcompositeFEM_la-ScalableQuadrature.Tpo" -c -o libcompositeFEM_la-ScalableQuadrature.lo `test -f '$(COMPOSITE_SOURCE_DIR)/ScalableQuadrature.cc' || echo '$(srcdir)/'`$(COMPOSITE_SOURCE_DIR)/ScalableQuadrature.cc; \ +@am__fastdepCXX_TRUE@ then mv -f "$(DEPDIR)/libcompositeFEM_la-ScalableQuadrature.Tpo" "$(DEPDIR)/libcompositeFEM_la-ScalableQuadrature.Plo"; else rm -f "$(DEPDIR)/libcompositeFEM_la-ScalableQuadrature.Tpo"; exit 1; fi +@AMDEP_TRUE@@am__fastdepCXX_FALSE@ source='$(COMPOSITE_SOURCE_DIR)/ScalableQuadrature.cc' object='libcompositeFEM_la-ScalableQuadrature.lo' libtool=yes @AMDEPBACKSLASH@ +@AMDEP_TRUE@@am__fastdepCXX_FALSE@ DEPDIR=$(DEPDIR) $(CXXDEPMODE) $(depcomp) @AMDEPBACKSLASH@ +@am__fastdepCXX_FALSE@ $(LIBTOOL) --tag=CXX --mode=compile $(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(libcompositeFEM_la_CXXFLAGS) $(CXXFLAGS) -c -o libcompositeFEM_la-ScalableQuadrature.lo `test -f '$(COMPOSITE_SOURCE_DIR)/ScalableQuadrature.cc' || echo '$(srcdir)/'`$(COMPOSITE_SOURCE_DIR)/ScalableQuadrature.cc + +libcompositeFEM_la-SubElInfo.lo: $(COMPOSITE_SOURCE_DIR)/SubElInfo.cc +@am__fastdepCXX_TRUE@ if $(LIBTOOL) --tag=CXX --mode=compile $(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(libcompositeFEM_la_CXXFLAGS) $(CXXFLAGS) -MT libcompositeFEM_la-SubElInfo.lo -MD -MP -MF "$(DEPDIR)/libcompositeFEM_la-SubElInfo.Tpo" -c -o libcompositeFEM_la-SubElInfo.lo `test -f '$(COMPOSITE_SOURCE_DIR)/SubElInfo.cc' || echo '$(srcdir)/'`$(COMPOSITE_SOURCE_DIR)/SubElInfo.cc; \ +@am__fastdepCXX_TRUE@ then mv -f "$(DEPDIR)/libcompositeFEM_la-SubElInfo.Tpo" "$(DEPDIR)/libcompositeFEM_la-SubElInfo.Plo"; else rm -f "$(DEPDIR)/libcompositeFEM_la-SubElInfo.Tpo"; exit 1; fi +@AMDEP_TRUE@@am__fastdepCXX_FALSE@ source='$(COMPOSITE_SOURCE_DIR)/SubElInfo.cc' object='libcompositeFEM_la-SubElInfo.lo' libtool=yes @AMDEPBACKSLASH@ +@AMDEP_TRUE@@am__fastdepCXX_FALSE@ DEPDIR=$(DEPDIR) $(CXXDEPMODE) $(depcomp) @AMDEPBACKSLASH@ +@am__fastdepCXX_FALSE@ $(LIBTOOL) --tag=CXX --mode=compile $(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(libcompositeFEM_la_CXXFLAGS) $(CXXFLAGS) -c -o libcompositeFEM_la-SubElInfo.lo `test -f '$(COMPOSITE_SOURCE_DIR)/SubElInfo.cc' || echo '$(srcdir)/'`$(COMPOSITE_SOURCE_DIR)/SubElInfo.cc + +libcompositeFEM_la-SubElementAssembler.lo: $(COMPOSITE_SOURCE_DIR)/SubElementAssembler.cc +@am__fastdepCXX_TRUE@ if $(LIBTOOL) --tag=CXX --mode=compile $(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(libcompositeFEM_la_CXXFLAGS) $(CXXFLAGS) -MT libcompositeFEM_la-SubElementAssembler.lo -MD -MP -MF "$(DEPDIR)/libcompositeFEM_la-SubElementAssembler.Tpo" -c -o libcompositeFEM_la-SubElementAssembler.lo `test -f '$(COMPOSITE_SOURCE_DIR)/SubElementAssembler.cc' || echo '$(srcdir)/'`$(COMPOSITE_SOURCE_DIR)/SubElementAssembler.cc; \ +@am__fastdepCXX_TRUE@ then mv -f "$(DEPDIR)/libcompositeFEM_la-SubElementAssembler.Tpo" "$(DEPDIR)/libcompositeFEM_la-SubElementAssembler.Plo"; else rm -f "$(DEPDIR)/libcompositeFEM_la-SubElementAssembler.Tpo"; exit 1; fi +@AMDEP_TRUE@@am__fastdepCXX_FALSE@ source='$(COMPOSITE_SOURCE_DIR)/SubElementAssembler.cc' object='libcompositeFEM_la-SubElementAssembler.lo' libtool=yes @AMDEPBACKSLASH@ +@AMDEP_TRUE@@am__fastdepCXX_FALSE@ DEPDIR=$(DEPDIR) $(CXXDEPMODE) $(depcomp) @AMDEPBACKSLASH@ +@am__fastdepCXX_FALSE@ $(LIBTOOL) --tag=CXX --mode=compile $(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(libcompositeFEM_la_CXXFLAGS) $(CXXFLAGS) -c -o libcompositeFEM_la-SubElementAssembler.lo `test -f '$(COMPOSITE_SOURCE_DIR)/SubElementAssembler.cc' || echo '$(srcdir)/'`$(COMPOSITE_SOURCE_DIR)/SubElementAssembler.cc + +mostlyclean-libtool: + -rm -f *.lo + +clean-libtool: + -rm -rf .libs _libs + +distclean-libtool: + -rm -f libtool +uninstall-info-am: + +ID: $(HEADERS) $(SOURCES) $(LISP) $(TAGS_FILES) + list='$(SOURCES) $(HEADERS) $(LISP) $(TAGS_FILES)'; \ + unique=`for i in $$list; do \ + if test -f "$$i"; then echo $$i; else echo $(srcdir)/$$i; fi; \ + done | \ + $(AWK) ' { files[$$0] = 1; } \ + END { for (i in files) print i; }'`; \ + mkid -fID $$unique +tags: TAGS + +TAGS: $(HEADERS) $(SOURCES) $(TAGS_DEPENDENCIES) \ + $(TAGS_FILES) $(LISP) + tags=; \ + here=`pwd`; \ + list='$(SOURCES) $(HEADERS) $(LISP) $(TAGS_FILES)'; \ + unique=`for i in $$list; do \ + if test -f "$$i"; then echo $$i; else echo $(srcdir)/$$i; fi; \ + done | \ + $(AWK) ' { files[$$0] = 1; } \ + END { for (i in files) print i; }'`; \ + if test -z "$(ETAGS_ARGS)$$tags$$unique"; then :; else \ + test -n "$$unique" || unique=$$empty_fix; \ + $(ETAGS) $(ETAGSFLAGS) $(AM_ETAGSFLAGS) $(ETAGS_ARGS) \ + $$tags $$unique; \ + fi +ctags: CTAGS +CTAGS: $(HEADERS) $(SOURCES) $(TAGS_DEPENDENCIES) \ + $(TAGS_FILES) $(LISP) + tags=; \ + here=`pwd`; \ + list='$(SOURCES) $(HEADERS) $(LISP) $(TAGS_FILES)'; \ + unique=`for i in $$list; do \ + if test -f "$$i"; then echo $$i; else echo $(srcdir)/$$i; fi; \ + done | \ + $(AWK) ' { files[$$0] = 1; } \ + END { for (i in files) print i; }'`; \ + test -z "$(CTAGS_ARGS)$$tags$$unique" \ + || $(CTAGS) $(CTAGSFLAGS) $(AM_CTAGSFLAGS) $(CTAGS_ARGS) \ + $$tags $$unique + +GTAGS: + here=`$(am__cd) $(top_builddir) && pwd` \ + && cd $(top_srcdir) \ + && gtags -i $(GTAGS_ARGS) $$here + +distclean-tags: + -rm -f TAGS ID GTAGS GRTAGS GSYMS GPATH tags + +distdir: $(DISTFILES) + @srcdirstrip=`echo "$(srcdir)" | sed 's|.|.|g'`; \ + topsrcdirstrip=`echo "$(top_srcdir)" | sed 's|.|.|g'`; \ + list='$(DISTFILES)'; for file in $$list; do \ + case $$file in \ + $(srcdir)/*) file=`echo "$$file" | sed "s|^$$srcdirstrip/||"`;; \ + $(top_srcdir)/*) file=`echo "$$file" | sed "s|^$$topsrcdirstrip/|$(top_builddir)/|"`;; \ + esac; \ + if test -f $$file || test -d $$file; then d=.; else d=$(srcdir); fi; \ + dir=`echo "$$file" | sed -e 's,/[^/]*$$,,'`; \ + if test "$$dir" != "$$file" && test "$$dir" != "."; then \ + dir="/$$dir"; \ + $(mkdir_p) "$(distdir)$$dir"; \ + else \ + dir=''; \ + fi; \ + if test -d $$d/$$file; then \ + if test -d $(srcdir)/$$file && test $$d != $(srcdir); then \ + cp -pR $(srcdir)/$$file $(distdir)$$dir || exit 1; \ + fi; \ + cp -pR $$d/$$file $(distdir)$$dir || exit 1; \ + else \ + test -f $(distdir)/$$file \ + || cp -p $$d/$$file $(distdir)/$$file \ + || exit 1; \ + fi; \ + done +check-am: all-am +check: check-am +all-am: Makefile $(LTLIBRARIES) +installdirs: + for dir in "$(DESTDIR)$(libdir)"; do \ + test -z "$$dir" || $(mkdir_p) "$$dir"; \ + done +install: install-am +install-exec: install-exec-am +install-data: install-data-am +uninstall: uninstall-am + +install-am: all-am + @$(MAKE) $(AM_MAKEFLAGS) install-exec-am install-data-am + +installcheck: installcheck-am +install-strip: + $(MAKE) $(AM_MAKEFLAGS) INSTALL_PROGRAM="$(INSTALL_STRIP_PROGRAM)" \ + install_sh_PROGRAM="$(INSTALL_STRIP_PROGRAM)" INSTALL_STRIP_FLAG=-s \ + `test -z '$(STRIP)' || \ + echo "INSTALL_PROGRAM_ENV=STRIPPROG='$(STRIP)'"` install +mostlyclean-generic: + +clean-generic: + +distclean-generic: + -test -z "$(CONFIG_CLEAN_FILES)" || rm -f $(CONFIG_CLEAN_FILES) + +maintainer-clean-generic: + @echo "This command is intended for maintainers to use" + @echo "it deletes files that may require special tools to rebuild." +clean: clean-am + +clean-am: clean-generic clean-libLTLIBRARIES clean-libtool \ + mostlyclean-am + +distclean: distclean-am + -rm -rf ./$(DEPDIR) + -rm -f Makefile +distclean-am: clean-am distclean-compile distclean-generic \ + distclean-libtool distclean-tags + +dvi: dvi-am + +dvi-am: + +html: html-am + +info: info-am + +info-am: + +install-data-am: + +install-exec-am: install-libLTLIBRARIES + +install-info: install-info-am + +install-man: + +installcheck-am: + +maintainer-clean: maintainer-clean-am + -rm -rf ./$(DEPDIR) + -rm -f Makefile +maintainer-clean-am: distclean-am maintainer-clean-generic + +mostlyclean: mostlyclean-am + +mostlyclean-am: mostlyclean-compile mostlyclean-generic \ + mostlyclean-libtool + +pdf: pdf-am + +pdf-am: + +ps: ps-am + +ps-am: + +uninstall-am: uninstall-info-am uninstall-libLTLIBRARIES + +.PHONY: CTAGS GTAGS all all-am check check-am clean clean-generic \ + clean-libLTLIBRARIES clean-libtool ctags distclean \ + distclean-compile distclean-generic distclean-libtool \ + distclean-tags distdir dvi dvi-am html html-am info info-am \ + install install-am install-data install-data-am install-exec \ + install-exec-am install-info install-info-am \ + install-libLTLIBRARIES install-man install-strip installcheck \ + installcheck-am installdirs maintainer-clean \ + maintainer-clean-generic mostlyclean mostlyclean-compile \ + mostlyclean-generic mostlyclean-libtool pdf pdf-am ps ps-am \ + tags uninstall uninstall-am uninstall-info-am \ + uninstall-libLTLIBRARIES + +# Tell versions [3.59,3.63) of GNU make to not export all variables. +# Otherwise a system limit (for SysV at least) may be exceeded. +.NOEXPORT: diff --git a/AMDiS/compositeFEM/src/CFE_Integration.cc b/AMDiS/compositeFEM/src/CFE_Integration.cc new file mode 100644 index 0000000000000000000000000000000000000000..c320acf8dc1f91b580c817b364918559e909953c --- /dev/null +++ b/AMDiS/compositeFEM/src/CFE_Integration.cc @@ -0,0 +1,294 @@ +#include "CFE_Integration.h" + +#include "Mesh.h" +#include "SurfaceQuadrature.h" +#include "Traverse.h" + +#include "ScalableQuadrature.h" +#include "SubElInfo.h" +#include "SubPolytope.h" + +double +CFE_Integration::integrate_onNegLs(ElementFunction<double> *f, + ElementLevelSet *elLS, + int deg, + Quadrature *q) +{ + FUNCNAME("CFE_Integration::integrate_onNegLs()"); + + int dim = elLS->getDim(); + double int_val = 0.0; + double el_int_val; + double subEl_int_val; + VectorOfFixVecs<DimVec<double> > *intersecPts; + SubPolytope *subPolytope; + int numIntersecPts; + int iq; + double val; + int numQuadPts; + int vertex_interior; + ScalableQuadrature *loc_scalQuad; + int numScalQuadPts; + bool subPolIsExterior = false; + int elStatus; + Mesh *mesh = elLS->getMesh(); + + // ===== Get quadratures. ===== + if (!q) { + q = Quadrature::provideQuadrature(dim, deg); + } + numQuadPts = q->getNumPoints(); + loc_scalQuad = NEW ScalableQuadrature(q); + numScalQuadPts = loc_scalQuad->getNumPoints(); + + + // ===== Traverse mesh and calculate integral on each element. ===== + TraverseStack stack; + + ElInfo *loc_elInfo = stack.traverseFirst(mesh, + -1, + Mesh::CALL_LEAF_EL | + Mesh::FILL_COORDS | + Mesh::FILL_DET); + while(loc_elInfo) { + el_int_val = 0.0; + subEl_int_val = 0.0; + subPolIsExterior = false; + + // Check whether current element is cut by the zero level set. + elStatus = elLS->createElementLevelSet(loc_elInfo); + + if (elStatus == ElementLevelSet::LEVEL_SET_BOUNDARY) { + + // ------------------------------------------------------------------- + // Element is cut by the zero level set. + // ------------------------------------------------------------------- + + // Create subelements. + intersecPts = elLS->getElIntersecPoints(); + numIntersecPts = elLS->getNumElIntersecPoints(); + + if (dim == 1 || (dim == 3 && numIntersecPts == 4)) { + + // ----------------------------------------------------------------- + // Subelement(s) are inside the domain with negative level set + // function value. + + // Get vertex with negative level set function value. + for (int i=0; i<=dim; ++i) { + if (elLS->getElVertLevelSetVec(i) < 0) { + vertex_interior = i; + break; + } + } + + subPolytope = NEW SubPolytope(loc_elInfo, + intersecPts, + numIntersecPts, + vertex_interior); + } + else { + + // ----------------------------------------------------------------- + // Subelement may be inside the domain with negative level set + // function value as well as inside the domain with positive + // function value. + // + // Whether a subelement is in the domain with negative or positive + // level set function values is checked by the level set function + // value of the first vertex of the subelement. (The subelements + // are created in such a way that this vertex always is a vertex + // of the element and not an intersection point. Thus the level set + // function value of this vertex really is unequal to zero.) + + subPolytope = NEW SubPolytope(loc_elInfo, + intersecPts, + numIntersecPts, + 0); + + if(elLS->getVertexPos(subPolytope->getSubElement(0)->getLambda(0)) == + ElementLevelSet::LEVEL_SET_EXTERIOR) { + subPolIsExterior = true; + } + } + + elLS->setLevelSetDomain(ElementLevelSet::LEVEL_SET_INTERIOR); + + // Calculate integral on subelement(s). + f->setElInfo(loc_elInfo); + for (std::vector<SubElInfo *>::iterator it = + subPolytope->getSubElementsBegin(); + it != subPolytope->getSubElementsEnd(); + it++) { + + loc_scalQuad->scaleQuadrature(**it); + + for (val = iq = 0; iq < numScalQuadPts; ++iq) { + val += loc_scalQuad->getWeight(iq)*(*f)(loc_scalQuad->getLambda(iq)); + } + el_int_val += fabs((*it)->getDet()) * val; + } + + // ------------------------------------------------------------------- + // In case the subelement is in the domain with positive level set + // function values: + // Calculate the integral on the element part with negative + // level set function values by substracting the integral on the + // subelement from the integral on the complete element. + if (subPolIsExterior) { + subEl_int_val = el_int_val; + el_int_val = 0.0; + + f->setElInfo(loc_elInfo); + for (val = iq = 0; iq < numQuadPts; ++iq) { + val += q->getWeight(iq)*(*f)(q->getLambda(iq)); + } + el_int_val = loc_elInfo->calcDet()*val - subEl_int_val; + } + + // Free data. + DELETE subPolytope; + } + else if (elStatus == ElementLevelSet::LEVEL_SET_INTERIOR) { + + // ------------------------------------------------------------------- + // Element is in the domain with negative level set function values. + // ------------------------------------------------------------------- + + elLS->setLevelSetDomain(ElementLevelSet::LEVEL_SET_INTERIOR); + + f->setElInfo(loc_elInfo); + for (val = iq = 0; iq < numQuadPts; ++iq) { + val += q->getWeight(iq)*(*f)(q->getLambda(iq)); + } + el_int_val = loc_elInfo->calcDet() * val; + } + + int_val += el_int_val; + loc_elInfo = stack.traverseNext(loc_elInfo); + + } // end of: mesh traverse + + DELETE loc_scalQuad; + + return int_val; +} + +double +CFE_Integration::integrate_onZeroLs(ElementFunction<double> *f, + ElementLevelSet *elLS, + int deg, + Quadrature *q) +{ + FUNCNAME("CFE_Integration::integrate_onZeroLs()"); + + int dim = elLS->getDim(); + double int_val = 0.0; + VectorOfFixVecs<DimVec<double> > *intersecPts; + int numIntersecPts; + int iq; + double val; + SurfaceQuadrature *surfQuad; + int numQuadPts; + VectorOfFixVecs<DimVec<double> > tmpPts(dim, dim, NO_INIT); + DimVec<double> tmpPt(dim, DEFAULT_VALUE, 0.0); + int elStatus; + Mesh *mesh = elLS->getMesh(); + + // ===== Define default points for surface quadrature. ===== + for (int i=0; i<dim; ++i) { + tmpPt[i] = 1.0; + tmpPts[i] = tmpPt; + tmpPt[i] = 0.0; + } + + // ===== Get quadratures. ===== + if (!q) { + q = Quadrature::provideQuadrature(dim-1, deg); + } + surfQuad = NEW SurfaceQuadrature(q, tmpPts); + numQuadPts = surfQuad->getNumPoints(); + + + // ===== Traverse mesh and calculate integral on each element cut by + // the zero level set. ===== + TraverseStack stack; + + ElInfo *loc_elInfo = stack.traverseFirst(mesh, + -1, + Mesh::CALL_LEAF_EL | + Mesh::FILL_COORDS | + Mesh::FILL_DET); + while(loc_elInfo) { + + // Check whether current element is cut by the zero level set. + elStatus = elLS->createElementLevelSet(loc_elInfo); + + if (elStatus == ElementLevelSet::LEVEL_SET_BOUNDARY) { + + // Get intersection points. + intersecPts = elLS->getElIntersecPoints(); + numIntersecPts = elLS->getNumElIntersecPoints(); + + // Calculate surface integral on intersection plane. + f->setElInfo(loc_elInfo); + + // Note: The vector *intersecPts has always MAX_INTERSECTION_POINTS + // entries. + for (int i=0; i<dim; ++i) + tmpPts[i] = (*intersecPts)[i]; + + surfQuad->scaleSurfaceQuadrature(tmpPts); + + for (val = iq = 0; iq < numQuadPts; ++iq) { + val += surfQuad->getWeight(iq)*(*f)(surfQuad->getLambda(iq)); + } + int_val += calcSurfaceDet(loc_elInfo, tmpPts) * val; + + if (dim == 3 && numIntersecPts == 4) { + + // ----------------------------------------------------------------- + // Intersection plane must be divided into two simplices. Calculate + // the surface integral for the second simplex. + // + // Note: The intersection points S0, S1, S2, S3 are supposed to be + // alligned in such a manner that a line through S1 and S2 + // divides the intersection plane. + tmpPts[0] = (*intersecPts)[3]; + + surfQuad->scaleSurfaceQuadrature(tmpPts); + + for (val = iq = 0; iq < numQuadPts; ++iq) { + val += surfQuad->getWeight(iq)*(*f)(surfQuad->getLambda(iq)); + } + int_val += calcSurfaceDet(loc_elInfo, tmpPts) * val; + } + } + + loc_elInfo = stack.traverseNext(loc_elInfo); + + } // end of: mesh traverse + + DELETE surfQuad; + + return int_val; +} + +double +CFE_Integration::calcSurfaceDet(ElInfo *loc_elInfo, + VectorOfFixVecs<DimVec<double> > &surfVert) +{ + double surfDet; + int dim = surfVert[0].getSize()-1; + FixVec<WorldVector<double>, VERTEX> worldCoords(dim-1, NO_INIT); + + // transform barycentric coords to world coords + for(int i = 0; i < dim; i++) { + loc_elInfo->coordToWorld(surfVert[i], &worldCoords[i]); + } + + // calculate determinant for surface + surfDet = ElInfo::calcDet(worldCoords); + + return surfDet; +} diff --git a/AMDiS/compositeFEM/src/CFE_Integration.h b/AMDiS/compositeFEM/src/CFE_Integration.h new file mode 100644 index 0000000000000000000000000000000000000000..4c1fa133c7602a8f11c3f2d8fe35aa4e15d7abc2 --- /dev/null +++ b/AMDiS/compositeFEM/src/CFE_Integration.h @@ -0,0 +1,43 @@ +#ifndef AMDIS_CFE_INTEGRATION_H +#define AMDIS_CFE_INTEGRATION_H + +#include "ElementFunction.h" +#include "MemoryManager.h" +#include "Quadrature.h" + +#include "ElementLevelSet.h" + +using namespace AMDiS; + +class CFE_Integration +{ + public: + MEMORY_MANAGED(CFE_Integration); + + /** + * Calculates integral of function f on domain where level set function + * is negative. + */ + static double integrate_onNegLs(ElementFunction<double> *f, + ElementLevelSet *elLS, + int deg = 1, + Quadrature *q = NULL); + + /** + * Calculates surface integral of function f on the zero level set. + * + * Note: Quadrature q is a quadrature formula for dimension dim-1. + */ + static double integrate_onZeroLs(ElementFunction<double> *f, + ElementLevelSet *elLS, + int deg = 1, + Quadrature *q = NULL); + protected: + /** + * Calculates determinant for surface given through surfVert. + */ + static double calcSurfaceDet(ElInfo *loc_elInfo, + VectorOfFixVecs<DimVec<double> > &surfVert); +}; + +#endif // AMDIS_CFE_INTEGRATION_H diff --git a/AMDiS/compositeFEM/src/CFE_NormAndErrorFcts.cc b/AMDiS/compositeFEM/src/CFE_NormAndErrorFcts.cc new file mode 100644 index 0000000000000000000000000000000000000000..0cee8c39370f83ff495bbc90e79e0fd1ccb710b6 --- /dev/null +++ b/AMDiS/compositeFEM/src/CFE_NormAndErrorFcts.cc @@ -0,0 +1,1148 @@ +#include "CFE_NormAndErrorFcts.h" + +#include <vector> +#include "Mesh.h" +#include "Traverse.h" + +#include "SubElInfo.h" + +double CFE_NormAndErrorFcts::L2_err_abs = 0.0; +double CFE_NormAndErrorFcts::L2_u_norm = 0.0; +double CFE_NormAndErrorFcts::H1_err_abs = 0.0; +double CFE_NormAndErrorFcts::H1_u_norm = 0.0; + +double +ElementL1Norm_Analyt::calcElNorm(ElInfo *elInfo, + const double &det, + const double &fac) +{ + double val = 0.0; + const WorldVector<double> *worldCoordsAtQP; + + for (int iq = 0; iq < nQPts; ++iq) { + worldCoordsAtQP = elInfo->coordToWorld(q->getLambda(iq), NULL); + val += q->getWeight(iq) * fabs((*f)(*worldCoordsAtQP)); + } + double nrm = det * val; + + return nrm; +} + +double +ElementL2Norm_Analyt::calcElNorm(ElInfo *elInfo, + const double &det, + const double &fac) +{ + double val = 0.0; + const WorldVector<double> *worldCoordsAtQP; + + for (int iq = 0; iq < nQPts; ++iq) { + worldCoordsAtQP = elInfo->coordToWorld(q->getLambda(iq), NULL); + val += q->getWeight(iq) * sqr((*f)(*worldCoordsAtQP)); + } + double nrm = det * val; + + return nrm; +} + +double +ElementH1Norm_Analyt::calcElNorm(ElInfo *elInfo, + const double &det, + const double &fac) +{ + double val = 0.0; + double norm_grd2; + const WorldVector<double> *worldCoordsAtQP; + + for (int iq = 0; iq < nQPts; ++iq) { + worldCoordsAtQP = elInfo->coordToWorld(q->getLambda(iq), NULL); + + norm_grd2 = 0.0; + for (int j = 0; j < dim; j++) + norm_grd2 += sqr(((*grd)(*worldCoordsAtQP))[j]); + + val += q->getWeight(iq) * norm_grd2; + } + double nrm = det * val; + + return nrm; +} + +double +ElementL1Norm_DOF::calcElNorm(ElInfo *elInfo, + const double &det, + const double &fac) +{ + double val = 0.0; + const double *dofAtQPs = dofVec->getVecAtQPs(elInfo, + q, + NULL, + NULL); + + for (int iq = 0; iq < nQPts; ++iq) { + val += q->getWeight(iq) * fabs(dofAtQPs[iq]); + } + double nrm = det * val; + + return nrm; +} + +double +ElementL2Norm_DOF::calcElNorm(ElInfo *elInfo, + const double &det, + const double &fac) +{ + double val = 0.0; + const double *dofAtQPs = dofVec->getVecAtQPs(elInfo, + q, + NULL, + NULL); + + for (int iq = 0; iq < nQPts; ++iq) { + val += q->getWeight(iq) * sqr(dofAtQPs[iq]); + } + double nrm = det * val; + + return nrm; +} + +double +ElementH1Norm_DOF::calcElNorm(ElInfo *elInfo, + const double &det, + const double &fac) +{ + double val = 0.0; + double norm_grd2; + const WorldVector<double> *grdDofAtQPs = dofVec->getGrdAtQPs(elInfo, + q, + NULL, + NULL); + + for (int iq = 0; iq < nQPts; ++iq) { + + norm_grd2 = 0.0; + for (int j = 0; j < dim; ++j) + norm_grd2 += sqr(grdDofAtQPs[iq][j]); + + val += q->getWeight(iq) * norm_grd2; + } + double nrm = det * val; + + return nrm; +} + +double +ElementL2Err::calcElNorm(ElInfo *elInfo, + const double &det, + const double &fac) +{ + double val = 0.0; + double val_nrm = 0.0; + const double *uhAtQPs = uh->getVecAtQPs(elInfo, + q, + NULL, + NULL); + const WorldVector<double> *worldCoordsAtQP; + + for (int iq = 0; iq < nQPts; ++iq) { + worldCoordsAtQP = elInfo->coordToWorld(q->getLambda(iq), NULL); + val += q->getWeight(iq) * sqr((*u)(*worldCoordsAtQP) - uhAtQPs[iq]); + + if (relErr) + val_nrm += q->getWeight(iq) * sqr((*u)(*worldCoordsAtQP)); + } + + double err = det * val; + + if (relErr) + nrmU += fac * det * val_nrm; + + return err; +} + +double +ElementH1Err::calcElNorm(ElInfo *elInfo, + const double &det, + const double &fac) +{ + double val = 0.0; + double val_nrm = 0.0; + double norm_err_grd2; + double norm_grd2; + const WorldVector<double> *grdUhAtQPs = uh->getGrdAtQPs(elInfo, + q, + NULL, + NULL); + const WorldVector<double> *worldCoordsAtQP; + + for (int iq = 0; iq < nQPts; ++iq) { + + worldCoordsAtQP = elInfo->coordToWorld(q->getLambda(iq), NULL); + + norm_err_grd2 = 0.0; + for (int j = 0; j < dim; ++j) + norm_err_grd2 += + sqr(((*grdu)(*worldCoordsAtQP))[j] - grdUhAtQPs[iq][j]); + + val += q->getWeight(iq) * norm_err_grd2; + + if (relErr) { + norm_grd2 = 0.0; + for (int j = 0; j < dim; ++j) + norm_grd2 += sqr(((*grdu)(*worldCoordsAtQP))[j]); + + val_nrm += q->getWeight(iq) * norm_grd2; + } + } + double err = det * val; + + if (relErr) + nrmGrdU += fac * det * val_nrm; + + return err; +} + +double +CFE_NormAndErrorFcts::Norm_IntNoBound(ElementNorm *elNorm, + ElementLevelSet *elLS, + Flag fillFlag, + int deg, + Quadrature *q) +{ + FUNCNAME("CFE_NormAndErrorFcts::Norm_IntNoBound()"); + + int dim = elLS->getDim(); + Mesh *mesh = elLS->getMesh(); + double nrm = 0.0; + int elStatus; + + // ===== Get quadratures. ===== + if (!q) { + q = Quadrature::provideQuadrature(dim, deg); + } + elNorm->setQuadrature(q); + + + // ===== Traverse mesh and calculate integral on each element. ===== + TraverseStack stack; + + ElInfo *elInfo = stack.traverseFirst(mesh, -1, fillFlag); + + while(elInfo) { + + // Check whether current element is cut by the zero level set. + elStatus = elLS->createElementLevelSet(elInfo); + + if (elStatus == ElementLevelSet::LEVEL_SET_INTERIOR) { + + // ------------------------------------------------------------------- + // Element is in the domain with negative level set function values. + // ------------------------------------------------------------------- + + elLS->setLevelSetDomain(ElementLevelSet::LEVEL_SET_INTERIOR); + + nrm += elNorm->calcElNorm(elInfo, fabs(elInfo->getDet())); + } + + elInfo = stack.traverseNext(elInfo); + + } // end of: mesh traverse + + return nrm; +} + +double +CFE_NormAndErrorFcts::Norm_IntBound(ElementNorm *elNorm, + ElementLevelSet *elLS, + Flag fillFlag, + int deg, + Quadrature *q) +{ + FUNCNAME("CFE_NormAndErrorFcts::Norm_IntBound()"); + + int dim = elLS->getDim(); + Mesh *mesh = elLS->getMesh(); + double nrm = 0.0; + double el_norm; + VectorOfFixVecs<DimVec<double> > *intersecPts; + int numIntersecPts; + SubPolytope *subPolytope; + ScalableQuadrature *scalQuad; + int nScalQPts; + int elStatus; + + // ===== Get quadratures. ===== + if (!q) { + q = Quadrature::provideQuadrature(dim, deg); + } + scalQuad = NEW ScalableQuadrature(q); + nScalQPts = scalQuad->getNumPoints(); + + + // ===== Traverse mesh and calculate integral on each element. ===== + TraverseStack stack; + + ElInfo *elInfo = stack.traverseFirst(mesh, -1, fillFlag); + + while(elInfo) { + el_norm = 0.0; + + // Check whether current element is cut by the zero level set. + elStatus = elLS->createElementLevelSet(elInfo); + + if (elStatus == ElementLevelSet::LEVEL_SET_BOUNDARY) { + + // ------------------------------------------------------------------- + // Element is cut by the zero level set. + // ------------------------------------------------------------------- + + // Calculate norm on subpolyope. + intersecPts = elLS->getElIntersecPoints(); + numIntersecPts = elLS->getNumElIntersecPoints(); + + // ----------------------------------------------------------------- + // Subelement may be inside the domain with negative level set + // function value as well as inside the domain with positive + // function value. + // + // Whether a subelement is in the domain with negative or positive + // level set function values is checked by the level set function + // value of the first vertex of the subelement. (The subelements + // are created in such a way that this vertex always is a vertex + // of the element and not an intersection point. Thus the level set + // function value of this vertex really is unequal to zero.) + + subPolytope = NEW SubPolytope(elInfo, + intersecPts, + numIntersecPts, + 0); + + elLS->setLevelSetDomain( + elLS->getVertexPos(subPolytope->getSubElement(0)->getLambda(0))); + + el_norm = calcSubPolNorm(elInfo, + subPolytope, + elNorm, + scalQuad); + + // Calculate integral on the other element part. + if (elLS->getLevelSetDomain() == ElementLevelSet::LEVEL_SET_EXTERIOR) + elLS->setLevelSetDomain(ElementLevelSet::LEVEL_SET_INTERIOR); + else + elLS->setLevelSetDomain(ElementLevelSet::LEVEL_SET_EXTERIOR); + + elNorm->setQuadrature(q); + el_norm += elNorm->calcElNorm(elInfo, fabs(elInfo->getDet())); + + el_norm -= calcSubPolNorm(elInfo, + subPolytope, + elNorm, + scalQuad, + -1.0); + + nrm += el_norm; + + // Free data. + DELETE subPolytope; + } + else if (elStatus == ElementLevelSet::LEVEL_SET_INTERIOR) { + + // ------------------------------------------------------------------- + // Element is in the domain with negative level set function values. + // ------------------------------------------------------------------- + + elLS->setLevelSetDomain(ElementLevelSet::LEVEL_SET_INTERIOR); + + elNorm->setQuadrature(q); + nrm += elNorm->calcElNorm(elInfo, fabs(elInfo->getDet())); + } + + elInfo = stack.traverseNext(elInfo); + + } // end of: mesh traverse + + DELETE scalQuad; + + return nrm; +} + +double +CFE_NormAndErrorFcts::Norm_Int(ElementNorm *elNorm, + ElementLevelSet *elLS, + Flag fillFlag, + int deg, + Quadrature *q) +{ + FUNCNAME("CFE_NormAndErrorFcts::Norm_Int()"); + + int dim = elLS->getDim(); + Mesh *mesh = elLS->getMesh(); + double nrm = 0.0; + double el_norm; + VectorOfFixVecs<DimVec<double> > *intersecPts; + int numIntersecPts; + int vertex_interior; + SubPolytope *subPolytope; + ScalableQuadrature *scalQuad; + int nScalQPts; + int elStatus; + + // ===== Get quadratures. ===== + if (!q) { + q = Quadrature::provideQuadrature(dim, deg); + } + scalQuad = NEW ScalableQuadrature(q); + nScalQPts = scalQuad->getNumPoints(); + + + // ===== Traverse mesh and calculate integral on each element. ===== + TraverseStack stack; + + ElInfo *elInfo = stack.traverseFirst(mesh, -1, fillFlag); + + while(elInfo) { + el_norm = 0.0; + + // Check whether current element is cut by the zero level set. + elStatus = elLS->createElementLevelSet(elInfo); + + if (elStatus == ElementLevelSet::LEVEL_SET_BOUNDARY) { + + // ------------------------------------------------------------------- + // Element is cut by the zero level set. + // ------------------------------------------------------------------- + + // Create subelements. + intersecPts = elLS->getElIntersecPoints(); + numIntersecPts = elLS->getNumElIntersecPoints(); + + if (dim == 1 || (dim == 3 && numIntersecPts == 4)) { + + // ----------------------------------------------------------------- + // Subelement(s) are inside the domain with negative level set + // function value. + + // Get vertex with negative level set function value. + for (int i=0; i<=dim; ++i) { + if (elLS->getElVertLevelSetVec(i) < 0) { + vertex_interior = i; + break; + } + } + + subPolytope = NEW SubPolytope(elInfo, + intersecPts, + numIntersecPts, + vertex_interior); + + elLS->setLevelSetDomain(ElementLevelSet::LEVEL_SET_INTERIOR); + } + else { + + // ----------------------------------------------------------------- + // Subelement may be inside the domain with negative level set + // function value as well as inside the domain with positive + // function value. + // + // Whether a subelement is in the domain with negative or positive + // level set function values is checked by the level set function + // value of the first vertex of the subelement. (The subelements + // are created in such a way that this vertex always is a vertex + // of the element and not an intersection point. Thus the level set + // function value of this vertex really is unequal to zero.) + + subPolytope = NEW SubPolytope(elInfo, + intersecPts, + numIntersecPts, + 0); + + elLS->setLevelSetDomain( + elLS->getVertexPos(subPolytope->getSubElement(0)->getLambda(0))); + } + + // Calculate norm on subpolytope. + if (elLS->getLevelSetDomain() == ElementLevelSet::LEVEL_SET_INTERIOR) + el_norm = calcSubPolNorm(elInfo, + subPolytope, + elNorm, + scalQuad); + else + el_norm = calcSubPolNorm(elInfo, + subPolytope, + elNorm, + scalQuad, + -1.0); + + // ------------------------------------------------------------------- + // In case the subelement is in the domain with positive level set + // function values: + // Calculate the integral on the element part with negative + // level set function values by substracting the integral on the + // subelement from the integral on the complete element. + if (elLS->getLevelSetDomain() == ElementLevelSet::LEVEL_SET_EXTERIOR) { + + elLS->setLevelSetDomain(ElementLevelSet::LEVEL_SET_INTERIOR); + + elNorm->setQuadrature(q); + el_norm *= -1.0; + el_norm += elNorm->calcElNorm(elInfo, fabs(elInfo->getDet())); + } + + // Free data. + DELETE subPolytope; + } + else if (elStatus == ElementLevelSet::LEVEL_SET_INTERIOR) { + + // ------------------------------------------------------------------- + // Element is in the domain with negative level set function values. + // ------------------------------------------------------------------- + + elLS->setLevelSetDomain(ElementLevelSet::LEVEL_SET_INTERIOR); + + elNorm->setQuadrature(q); + el_norm = elNorm->calcElNorm(elInfo, fabs(elInfo->getDet())); + } + + nrm += el_norm; + elInfo = stack.traverseNext(elInfo); + + } // end of: mesh traverse + + DELETE scalQuad; + + return nrm; +} + +double +CFE_NormAndErrorFcts::Norm_Bound(ElementNorm *elNorm, + ElementLevelSet *elLS, + Flag fillFlag, + int deg, + Quadrature *q) +{ + FUNCNAME("CFE_NormAndErrorFcts::Norm_Bound()"); + + int dim = elLS->getDim(); + Mesh *mesh = elLS->getMesh(); + double nrm = 0.0; + double el_norm; + VectorOfFixVecs<DimVec<double> > *intersecPts; + int numIntersecPts; + SubPolytope *subPolytope; + ScalableQuadrature *scalQuad; + int nScalQPts; + int elStatus; + + // ===== Get quadratures. ===== + if (!q) { + q = Quadrature::provideQuadrature(dim, deg); + } + scalQuad = NEW ScalableQuadrature(q); + nScalQPts = scalQuad->getNumPoints(); + + + // ===== Traverse mesh and calculate integral on each element. ===== + TraverseStack stack; + + ElInfo *elInfo = stack.traverseFirst(mesh, -1, fillFlag); + + while(elInfo) { + el_norm = 0.0; + + // Check whether current element is cut by the zero level set. + elStatus = elLS->createElementLevelSet(elInfo); + + if (elStatus == ElementLevelSet::LEVEL_SET_BOUNDARY) { + + // ------------------------------------------------------------------- + // Element is cut by the zero level set. + // ------------------------------------------------------------------- + + // Calculate norm on subpolyope. + intersecPts = elLS->getElIntersecPoints(); + numIntersecPts = elLS->getNumElIntersecPoints(); + + // ----------------------------------------------------------------- + // Subelement may be inside the domain with negative level set + // function value as well as inside the domain with positive + // function value. + // + // Whether a subelement is in the domain with negative or positive + // level set function values is checked by the level set function + // value of the first vertex of the subelement. (The subelements + // are created in such a way that this vertex always is a vertex + // of the element and not an intersection point. Thus the level set + // function value of this vertex really is unequal to zero.) + + subPolytope = NEW SubPolytope(elInfo, + intersecPts, + numIntersecPts, + 0); + + elLS->setLevelSetDomain( + elLS->getVertexPos(subPolytope->getSubElement(0)->getLambda(0))); + + el_norm = calcSubPolNorm(elInfo, + subPolytope, + elNorm, + scalQuad); + + // Calculate integral on the other element part. + if (elLS->getLevelSetDomain() == ElementLevelSet::LEVEL_SET_EXTERIOR) + elLS->setLevelSetDomain(ElementLevelSet::LEVEL_SET_INTERIOR); + else + elLS->setLevelSetDomain(ElementLevelSet::LEVEL_SET_EXTERIOR); + + elNorm->setQuadrature(q); + el_norm += elNorm->calcElNorm(elInfo, fabs(elInfo->getDet())); + + el_norm -= calcSubPolNorm(elInfo, + subPolytope, + elNorm, + scalQuad, + -1.0); + + nrm += el_norm; + + // Free data. + DELETE subPolytope; + } + + elInfo = stack.traverseNext(elInfo); + + } // end of: mesh traverse + + DELETE scalQuad; + + return nrm; +} + +double +CFE_NormAndErrorFcts::Norm_Complete(ElementNorm *elNorm, + ElementLevelSet *elLS, + Flag fillFlag, + int deg, + Quadrature *q) +{ + FUNCNAME("CFE_NormAndErrorFcts::Norm_Complete()"); + + int dim = elLS->getDim(); + Mesh *mesh = elLS->getMesh(); + double nrm = 0.0; + double el_norm; + VectorOfFixVecs<DimVec<double> > *intersecPts; + int numIntersecPts; + SubPolytope *subPolytope; + ScalableQuadrature *scalQuad; + int nScalQPts; + int elStatus; + + // ===== Get quadratures. ===== + if (!q) { + q = Quadrature::provideQuadrature(dim, deg); + } + scalQuad = NEW ScalableQuadrature(q); + nScalQPts = scalQuad->getNumPoints(); + + + // ===== Traverse mesh and calculate integral on each element. ===== + TraverseStack stack; + + ElInfo *elInfo = stack.traverseFirst(mesh, -1, fillFlag); + + while(elInfo) { + el_norm = 0.0; + + // Check whether current element is cut by the zero level set. + elStatus = elLS->createElementLevelSet(elInfo); + + if (elStatus == ElementLevelSet::LEVEL_SET_BOUNDARY) { + + // ------------------------------------------------------------------- + // Element is cut by the zero level set. + // ------------------------------------------------------------------- + + // Calculate norm on subpolyope. + intersecPts = elLS->getElIntersecPoints(); + numIntersecPts = elLS->getNumElIntersecPoints(); + + // ----------------------------------------------------------------- + // Subelement may be inside the domain with negative level set + // function value as well as inside the domain with positive + // function value. + // + // Whether a subelement is in the domain with negative or positive + // level set function values is checked by the level set function + // value of the first vertex of the subelement. (The subelements + // are created in such a way that this vertex always is a vertex + // of the element and not an intersection point. Thus the level set + // function value of this vertex really is unequal to zero.) + + subPolytope = NEW SubPolytope(elInfo, + intersecPts, + numIntersecPts, + 0); + + elLS->setLevelSetDomain( + elLS->getVertexPos(subPolytope->getSubElement(0)->getLambda(0))); + + el_norm = calcSubPolNorm(elInfo, + subPolytope, + elNorm, + scalQuad); + + // Calculate integral on the other element part. + if (elLS->getLevelSetDomain() == ElementLevelSet::LEVEL_SET_EXTERIOR) + elLS->setLevelSetDomain(ElementLevelSet::LEVEL_SET_INTERIOR); + else + elLS->setLevelSetDomain(ElementLevelSet::LEVEL_SET_EXTERIOR); + + elNorm->setQuadrature(q); + el_norm += elNorm->calcElNorm(elInfo, fabs(elInfo->getDet())); + + el_norm -= calcSubPolNorm(elInfo, + subPolytope, + elNorm, + scalQuad, + -1.0); + + nrm += el_norm; + + // Free data. + DELETE subPolytope; + } + else { + + // ------------------------------------------------------------------- + // Element is either completely in the domain with negative + // or positive level set function values. + // ------------------------------------------------------------------- + + elLS->setLevelSetDomain(elStatus); + + elNorm->setQuadrature(q); + nrm += elNorm->calcElNorm(elInfo, fabs(elInfo->getDet())); + } + + elInfo = stack.traverseNext(elInfo); + + } // end of: mesh traverse + + DELETE scalQuad; + + return nrm; +} + +double +CFE_NormAndErrorFcts::L1Norm_Analyt( + AbstractFunction<double, WorldVector<double> > *f, + ElementLevelSet *elLS, + int domainFlag, + int deg, + Quadrature *q) +{ + FUNCNAME("CFE_NormAndErrorFcts::L1Norm_Analyt"); + + ElementL1Norm_Analyt *elNorm = NEW ElementL1Norm_Analyt(q, f); + int dim = elLS->getDim(); + + TEST_EXIT(dim == Global::getGeo(WORLD)) + ("doesn't work for dimension of problem != dimension of world!\n"); + + Flag fillFlag = Mesh::CALL_LEAF_EL | + Mesh::FILL_COORDS | + Mesh::FILL_DET; + + double nrm; + switch(domainFlag) { + case -3: nrm = Norm_IntNoBound(elNorm, elLS, fillFlag, deg, q); + break; + case -2: nrm = Norm_IntBound(elNorm, elLS, fillFlag, deg, q); + break; + case -1: nrm = Norm_Int(elNorm, elLS, fillFlag, deg, q); + break; + case 0: nrm = Norm_Bound(elNorm, elLS, fillFlag, deg, q); + break; + case 1: nrm = Norm_Complete(elNorm, elLS, fillFlag, deg, q); + break; + default: ERROR_EXIT("illegal flag !\n"); + break; + } + + DELETE elNorm; + + return nrm; +} + +double +CFE_NormAndErrorFcts::L2NormSquare_Analyt( + AbstractFunction<double, WorldVector<double> > *f, + ElementLevelSet *elLS, + int domainFlag, + int deg, + Quadrature *q) +{ + FUNCNAME("CFE_NormAndErrorFcts::L2NormSquare_Analyt"); + + ElementL2Norm_Analyt *elNorm = NEW ElementL2Norm_Analyt(q, f); + int dim = elLS->getDim(); + + TEST_EXIT(dim == Global::getGeo(WORLD)) + ("doesn't work for dimension of problem != dimension of world!\n"); + + Flag fillFlag = Mesh::CALL_LEAF_EL | + Mesh::FILL_COORDS | + Mesh::FILL_DET; + + double nrm; + switch(domainFlag) { + case -3: nrm = Norm_IntNoBound(elNorm, elLS, fillFlag, deg, q); + break; + case -2: nrm = Norm_IntBound(elNorm, elLS, fillFlag, deg, q); + break; + case -1: nrm = Norm_Int(elNorm, elLS, fillFlag, deg, q); + break; + case 0: nrm = Norm_Bound(elNorm, elLS, fillFlag, deg, q); + break; + case 1: nrm = Norm_Complete(elNorm, elLS, fillFlag, deg, q); + break; + default: ERROR_EXIT("illegal flag !\n"); + break; + } + + DELETE elNorm; + + return nrm; +} + +double +CFE_NormAndErrorFcts::L2Norm_Analyt( + AbstractFunction<double, WorldVector<double> > *f, + ElementLevelSet *elLS, + int domainFlag, + int deg, + Quadrature *q) +{ + return sqrt(L2NormSquare_Analyt(f, elLS, domainFlag, deg, q)); +} + +double +CFE_NormAndErrorFcts::H1NormSquare_Analyt( + AbstractFunction<WorldVector<double>, WorldVector<double> > *grd, + ElementLevelSet *elLS, + int domainFlag, + int deg, + Quadrature *q) +{ + FUNCNAME("CFE_NormAndErrorFcts::H1NormSquare_Analyt"); + + int dim = elLS->getDim(); + ElementH1Norm_Analyt *elNorm = NEW ElementH1Norm_Analyt(q, grd, dim); + + TEST_EXIT(dim == Global::getGeo(WORLD)) + ("doesn't work for dimension of problem != dimension of world!\n"); + + Flag fillFlag = Mesh::CALL_LEAF_EL | + Mesh::FILL_COORDS | + Mesh::FILL_DET; + + double nrm; + switch(domainFlag) { + case -3: nrm = Norm_IntNoBound(elNorm, elLS, fillFlag, deg, q); + break; + case -2: nrm = Norm_IntBound(elNorm, elLS, fillFlag, deg, q); + break; + case -1: nrm = Norm_Int(elNorm, elLS, fillFlag, deg, q); + break; + case 0: nrm = Norm_Bound(elNorm, elLS, fillFlag, deg, q); + break; + case 1: nrm = Norm_Complete(elNorm, elLS, fillFlag, deg, q); + break; + default: ERROR_EXIT("illegal flag !\n"); + break; + } + + DELETE elNorm; + + return nrm; +} + +double +CFE_NormAndErrorFcts::H1Norm_Analyt( + AbstractFunction<WorldVector<double>, WorldVector<double> > *grd, + ElementLevelSet *elLS, + int domainFlag, + int deg, + Quadrature *q) +{ + return sqrt(H1NormSquare_Analyt(grd, elLS, domainFlag, deg, q)); +} + +double +CFE_NormAndErrorFcts::L1Norm_DOF(DOFVector<double> *dof, + ElementLevelSet *elLS, + int domainFlag, + int deg, + Quadrature *q) +{ + FUNCNAME("CFE_NormAndErrorFcts::L1Norm_DOF"); + + ElementL1Norm_DOF *elNorm = NEW ElementL1Norm_DOF(q, dof); + int dim = elLS->getDim(); + + TEST_EXIT(dim == Global::getGeo(WORLD)) + ("doesn't work for dimension of problem != dimension of world!\n"); + + Flag fillFlag = Mesh::CALL_LEAF_EL | + Mesh::FILL_COORDS | + Mesh::FILL_DET; + + double nrm; + switch(domainFlag) { + case -3: nrm = Norm_IntNoBound(elNorm, elLS, fillFlag, deg, q); + break; + case -2: nrm = Norm_IntBound(elNorm, elLS, fillFlag, deg, q); + break; + case -1: nrm = Norm_Int(elNorm, elLS, fillFlag, deg, q); + break; + case 0: nrm = Norm_Bound(elNorm, elLS, fillFlag, deg, q); + break; + case 1: nrm = Norm_Complete(elNorm, elLS, fillFlag, deg, q); + break; + default: ERROR_EXIT("illegal flag !\n"); + break; + } + + DELETE elNorm; + + return nrm; +} + +double +CFE_NormAndErrorFcts::L2NormSquare_DOF(DOFVector<double> *dof, + ElementLevelSet *elLS, + int domainFlag, + int deg, + Quadrature *q) +{ + FUNCNAME("CFE_NormAndErrorFcts::L2NormSquare_DOF"); + + ElementL2Norm_DOF *elNorm = NEW ElementL2Norm_DOF(q, dof); + int dim = elLS->getDim(); + + TEST_EXIT(dim == Global::getGeo(WORLD)) + ("doesn't work for dimension of problem != dimension of world!\n"); + + Flag fillFlag = Mesh::CALL_LEAF_EL | + Mesh::FILL_COORDS | + Mesh::FILL_DET; + + double nrm; + switch(domainFlag) { + case -3: nrm = Norm_IntNoBound(elNorm, elLS, fillFlag, deg, q); + break; + case -2: nrm = Norm_IntBound(elNorm, elLS, fillFlag, deg, q); + break; + case -1: nrm = Norm_Int(elNorm, elLS, fillFlag, deg, q); + break; + case 0: nrm = Norm_Bound(elNorm, elLS, fillFlag, deg, q); + break; + case 1: nrm = Norm_Complete(elNorm, elLS, fillFlag, deg, q); + break; + default: ERROR_EXIT("illegal flag !\n"); + break; + } + + DELETE elNorm; + + return nrm; +} + +double +CFE_NormAndErrorFcts::L2Norm_DOF(DOFVector<double> *dof, + ElementLevelSet *elLS, + int domainFlag, + int deg, + Quadrature *q) +{ + return sqrt(L2NormSquare_DOF(dof, elLS, domainFlag, deg, q)); +} + +double +CFE_NormAndErrorFcts::H1NormSquare_DOF(DOFVector<double> *dof, + ElementLevelSet *elLS, + int domainFlag, + int deg, + Quadrature *q) +{ + FUNCNAME("CFE_NormAndErrorFcts::H1NormSquare_DOF"); + + int dim = elLS->getDim(); + ElementH1Norm_DOF *elNorm = NEW ElementH1Norm_DOF(q, dof, dim); + + TEST_EXIT(dim == Global::getGeo(WORLD)) + ("doesn't work for dimension of problem != dimension of world!\n"); + + Flag fillFlag = Mesh::CALL_LEAF_EL | + Mesh::FILL_COORDS | + Mesh::FILL_DET | + Mesh::FILL_GRD_LAMBDA; + + double nrm; + switch(domainFlag) { + case -3: nrm = Norm_IntNoBound(elNorm, elLS, fillFlag, deg, q); + break; + case -2: nrm = Norm_IntBound(elNorm, elLS, fillFlag, deg, q); + break; + case -1: nrm = Norm_Int(elNorm, elLS, fillFlag, deg, q); + break; + case 0: nrm = Norm_Bound(elNorm, elLS, fillFlag, deg, q); + break; + case 1: nrm = Norm_Complete(elNorm, elLS, fillFlag, deg, q); + break; + default: ERROR_EXIT("illegal flag !\n"); + break; + } + + DELETE elNorm; + + return nrm; +} + +double +CFE_NormAndErrorFcts::H1Norm_DOF(DOFVector<double> *dof, + ElementLevelSet *elLS, + int domainFlag, + int deg, + Quadrature *q) +{ + return sqrt(H1NormSquare_DOF(dof, elLS, domainFlag, deg, q)); +} + +double +CFE_NormAndErrorFcts::L2Err( + AbstractFunction<double, WorldVector<double> > *u, + DOFVector<double> *uh, + ElementLevelSet *elLS, + int domainFlag, + int relErr, + int deg, + Quadrature *q) +{ + FUNCNAME("CFE_NormAndErrorFcts::L2Err()"); + + ElementL2Err *elNorm = NEW ElementL2Err(q, u, uh, relErr); + int dim = elLS->getDim(); + + TEST_EXIT(dim == Global::getGeo(WORLD)) + ("doesn't work for dimension of problem != dimension of world!\n"); + + Flag fillFlag = Mesh::CALL_LEAF_EL | + Mesh::FILL_COORDS | + Mesh::FILL_DET; + + double err; + switch(domainFlag) { + case -3: err = Norm_IntNoBound(elNorm, elLS, fillFlag, deg, q); + break; + case -2: err = Norm_IntBound(elNorm, elLS, fillFlag, deg, q); + break; + case -1: err = Norm_Int(elNorm, elLS, fillFlag, deg, q); + break; + case 0: err = Norm_Bound(elNorm, elLS, fillFlag, deg, q); + break; + case 1: err = Norm_Complete(elNorm, elLS, fillFlag, deg, q); + break; + default: ERROR_EXIT("illegal flag !\n"); + break; + } + + L2_err_abs = sqrt(err); + L2_u_norm = sqrt(elNorm->getNormU()); + + if (relErr) + err = L2_err_abs / (L2_u_norm + 1.e-15); + else + err = L2_err_abs; + + DELETE elNorm; + + return err; +} + +double +CFE_NormAndErrorFcts::H1Err( + AbstractFunction<WorldVector<double>, WorldVector<double> > *u, + DOFVector<double> *uh, + ElementLevelSet *elLS, + int domainFlag, + int relErr, + int deg, + Quadrature *q) +{ + FUNCNAME("CFE_NormAndErrorFcts::H1Err()"); + + int dim = elLS->getDim(); + ElementH1Err *elNorm = NEW ElementH1Err(q, u, uh, relErr, dim); + + TEST_EXIT(dim == Global::getGeo(WORLD)) + ("doesn't work for dimension of problem != dimension of world!\n"); + + Flag fillFlag = Mesh::CALL_LEAF_EL | + Mesh::FILL_COORDS | + Mesh::FILL_DET | + Mesh::FILL_GRD_LAMBDA; + + double err; + switch(domainFlag) { + case -3: err = Norm_IntNoBound(elNorm, elLS, fillFlag, deg, q); + break; + case -2: err = Norm_IntBound(elNorm, elLS, fillFlag, deg, q); + break; + case -1: err = Norm_Int(elNorm, elLS, fillFlag, deg, q); + break; + case 0: err = Norm_Bound(elNorm, elLS, fillFlag, deg, q); + break; + case 1: err = Norm_Complete(elNorm, elLS, fillFlag, deg, q); + break; + default: ERROR_EXIT("illegal flag !\n"); + break; + } + + H1_err_abs = sqrt(err); + H1_u_norm = sqrt(elNorm->getNormGrdU()); + + if (relErr) + err = H1_err_abs / (H1_u_norm + 1.e-15); + else + err = H1_err_abs; + + DELETE elNorm; + + return err; +} + +double +CFE_NormAndErrorFcts::calcSubPolNorm(ElInfo *elInfo, + SubPolytope *subPolytope, + ElementNorm *elNorm, + ScalableQuadrature *scalQuad, + const double &subPolFac) +{ + double nrm = 0.0; + + for (std::vector<SubElInfo *>::iterator it = + subPolytope->getSubElementsBegin(); + it != subPolytope->getSubElementsEnd(); + it++) { + + scalQuad->scaleQuadrature(**it); + elNorm->setQuadrature(scalQuad); + + nrm += elNorm->calcElNorm(elInfo, + fabs((*it)->getDet()), + subPolFac); + } + + return nrm; +} diff --git a/AMDiS/compositeFEM/src/CFE_NormAndErrorFcts.h b/AMDiS/compositeFEM/src/CFE_NormAndErrorFcts.h new file mode 100644 index 0000000000000000000000000000000000000000..4363642422b33c14991b24c4ac0b5db65ec1f118 --- /dev/null +++ b/AMDiS/compositeFEM/src/CFE_NormAndErrorFcts.h @@ -0,0 +1,574 @@ +#ifndef AMDIS_CFE_NORMANDERRORFCTS_H +#define AMDIS_CFE_NORMANDERRORFCTS_H + +#include "AbstractFunction.h" +#include "DOFVector.h" +#include "FixVec.h" +#include "MemoryManager.h" +#include "Quadrature.h" + +#include "ElementLevelSet.h" +#include "ScalableQuadrature.h" +#include "SubPolytope.h" + +using namespace AMDiS; + +class ElementNorm +{ + public: + MEMORY_MANAGED(ElementNorm); + + /** + * Constructor. + */ + ElementNorm(Quadrature *q_) + : q(q_), + nQPts(0) + { + if (q) + nQPts = q->getNumPoints(); + }; + + /** + * Destructor. + */ + virtual ~ElementNorm() + {}; + + /** + * Calculates element norm on elInfo. + */ + virtual double calcElNorm(ElInfo *elInfo, + const double &det, + const double &fac = 1.0) = 0; + + /** + * Sets quadrature to q_. + */ + inline void setQuadrature(Quadrature *q_) { + q = q_; + nQPts = q->getNumPoints(); + }; + + protected: + /** + * Quadrature formula. + */ + Quadrature *q; + + /** + * Number of quadrature points. + */ + int nQPts; +}; + +class ElementL1Norm_Analyt : public ElementNorm +{ + public: + MEMORY_MANAGED(ElementL1Norm_Analyt); + + /** + * Constructor. + */ + ElementL1Norm_Analyt(Quadrature *q_, + AbstractFunction<double, WorldVector<double> > *f_) + : ElementNorm(q_), + f(f_) + {}; + + /** + * Calculates element norm on elInfo. + */ + double calcElNorm(ElInfo *elInfo, + const double &det, + const double &fac = 1.0); + + protected: + /** + * Abstract function for which norm is calculated. + */ + AbstractFunction<double, WorldVector<double> > *f; +}; + +class ElementL2Norm_Analyt : public ElementNorm +{ + public: + MEMORY_MANAGED(ElementL2Norm_Analyt); + + /** + * Constructor. + */ + ElementL2Norm_Analyt(Quadrature *q_, + AbstractFunction<double, WorldVector<double> > *f_) + : ElementNorm(q_), + f(f_) + {}; + + /** + * Calculates element norm on elInfo. + */ + double calcElNorm(ElInfo *elInfo, + const double &det, + const double &fac = 1.0); + + protected: + /** + * Abstract function for which norm is calculated. + */ + AbstractFunction<double, WorldVector<double> > *f; +}; + +class ElementH1Norm_Analyt : public ElementNorm +{ + public: + MEMORY_MANAGED(ElementH1Norm_Analyt); + + /** + * Constructor. + */ + ElementH1Norm_Analyt(Quadrature *q_, + AbstractFunction<WorldVector<double>, WorldVector<double> > *grd_, + int dim_) + : ElementNorm(q_), + grd(grd_), + dim(dim_) + {}; + + /** + * Calculates element norm on elInfo. + */ + double calcElNorm(ElInfo *elInfo, + const double &det, + const double &fac = 1.0); + + protected: + /** + * Abstract function for which norm is calculated. + */ + AbstractFunction<WorldVector<double>, WorldVector<double> > *grd; + + /** + * Mesh dimension. + */ + int dim; +}; + +class ElementL1Norm_DOF : public ElementNorm +{ + public: + MEMORY_MANAGED(ElementL1Norm_DOF); + + /** + * Constructor. + */ + ElementL1Norm_DOF(Quadrature *q_, DOFVector<double> *dofVec_) + : ElementNorm(q_), + dofVec(dofVec_) + {}; + + /** + * Calculates element norm on elInfo. + */ + double calcElNorm(ElInfo *elInfo, + const double &det, + const double &fac = 1.0); + + protected: + /** + * DOF vector for which norm is calculated. + */ + DOFVector<double> *dofVec; +}; + +class ElementL2Norm_DOF : public ElementNorm +{ + public: + MEMORY_MANAGED(ElementL2Norm_DOF); + + /** + * Constructor. + */ + ElementL2Norm_DOF(Quadrature *q_, DOFVector<double> *dofVec_) + : ElementNorm(q_), + dofVec(dofVec_) + {}; + + /** + * Calculates element norm on elInfo. + */ + double calcElNorm(ElInfo *elInfo, + const double &det, + const double &fac = 1.0); + + protected: + /** + * DOF vector for which norm is calculated. + */ + DOFVector<double> *dofVec; +}; + +class ElementH1Norm_DOF : public ElementNorm +{ + public: + MEMORY_MANAGED(ElementH1Norm_DOF); + + /** + * Constructor. + */ + ElementH1Norm_DOF(Quadrature *q_, DOFVector<double> *dofVec_, int dim_) + : ElementNorm(q_), + dofVec(dofVec_), + dim(dim_) + {}; + + /** + * Calculates element norm on elInfo. + */ + double calcElNorm(ElInfo *elInfo, + const double &det, + const double &fac = 1.0); + + protected: + /** + * DOF vector for which norm is calculated. + */ + DOFVector<double> *dofVec; + + /** + * Mesh dimension. + */ + int dim; +}; + +class ElementL2Err : public ElementNorm +{ + public: + MEMORY_MANAGED(ElementL2Err); + + /** + * Constructor. + */ + ElementL2Err(Quadrature *q_, + AbstractFunction<double, WorldVector<double> > *u_, + DOFVector<double> *uh_, + int relErr_) + : ElementNorm(q_), + u(u_), + uh(uh_), + relErr(relErr_), + nrmU(0.0) + {}; + + /** + * Calculates element error on elInfo. + */ + double calcElNorm(ElInfo *elInfo, + const double &det, + const double &fac = 1.0); + + /** + * Get norm of u. + */ + inline double getNormU() const { + return nrmU; + }; + protected: + /** + * Abstract function for which error is calculated. + */ + AbstractFunction<double, WorldVector<double> > *u; + + /** + * DOF vector for which error is calculated. + */ + DOFVector<double> *uh; + + /** + * Indicates whether relative (1) or absolute error (0) is calculated. + */ + int relErr; + + /** + * Norm of u in case relative error is calculated. + */ + double nrmU; +}; + +class ElementH1Err : public ElementNorm +{ + public: + MEMORY_MANAGED(ElementH1Err); + + /** + * Constructor. + */ + ElementH1Err(Quadrature *q_, + AbstractFunction<WorldVector<double>, WorldVector<double> > *grdu_, + DOFVector<double> *uh_, + int relErr_, + int dim_) + : ElementNorm(q_), + grdu(grdu_), + uh(uh_), + relErr(relErr_), + nrmGrdU(0.0), + dim(dim_) + {}; + + /** + * Calculates element error on elInfo. + */ + double calcElNorm(ElInfo *elInfo, + const double &det, + const double &fac = 1.0); + + /** + * Get norm of grdu. + */ + inline double getNormGrdU() const { + return nrmGrdU; + }; + + protected: + /** + * Abstract function for which norm is calculated. + */ + AbstractFunction<WorldVector<double>, WorldVector<double> > *grdu; + + /** + * DOF vector for which error is calculated. + */ + DOFVector<double> *uh; + + /** + * Indicates whether relative (1) or absolute error (0) is calculated. + */ + int relErr; + + /** + * Norm of grdu in case relative error is calculated. + */ + double nrmGrdU; + + /** + * Mesh dimension. + */ + int dim; +}; + +///////////////////////////////////////////////////////////////////////////// +///// class CFE_NormAndErrorFcts //////////////////////////////////////////// +///////////////////////////////////////////////////////////////////////////// +class CFE_NormAndErrorFcts +{ + public: + MEMORY_MANAGED(CFE_NormAndErrorFcts); + + // ======================================================================== + // Calculation of L1-Norm, L2-Norm and H1-Norm on domain depending + // on the level set function. + // + // Here, the H1-norm is the H1-seminorm, i.e. you get the "common" + // H1-norm by + // H1_Norm() = sqrt(L2_Norm^2() + H1_Seminorm^2()) . + // + // Parameters for domainFlag: + // -3: all elements in the domain with negative level set function + // values which do not intersect the zero level set + // -2 : all elements which intersect the domain with negative level set + // function values, in particular all (complete) elements which + // cut the zero level set + // -1 : domain with negative level set function values + // 0 : all elements cut by the zero level set + // 1 : complete mesh + // ======================================================================== + static double L1Norm_Analyt( + AbstractFunction<double, WorldVector<double> > *f, + ElementLevelSet *elLS, + int domainFlag, + int deg = 1, + Quadrature* q = NULL); + static double L2Norm_Analyt( + AbstractFunction<double, WorldVector<double> > *f, + ElementLevelSet *elLS, + int domainFlag, + int deg = 2, + Quadrature* q = NULL); + static double L2NormSquare_Analyt( + AbstractFunction<double, WorldVector<double> > *f, + ElementLevelSet *elLS, + int domainFlag, + int deg = 2, + Quadrature* q = NULL); + static double H1Norm_Analyt( + AbstractFunction<WorldVector<double>, WorldVector<double> > *grd, + ElementLevelSet *elLS, + int domainFlag, + int deg = 0, + Quadrature* q = NULL); + static double H1NormSquare_Analyt( + AbstractFunction<WorldVector<double>, WorldVector<double> > *grd, + ElementLevelSet *elLS, + int domainFlag, + int deg = 0, + Quadrature* q = NULL); + static double L1Norm_DOF(DOFVector<double> *dof, + ElementLevelSet *elLS, + int domainFlag, + int deg = 1, + Quadrature* q = NULL); + static double L2Norm_DOF(DOFVector<double> *dof, + ElementLevelSet *elLS, + int domainFlag, + int deg = 2, + Quadrature* q = NULL); + static double L2NormSquare_DOF(DOFVector<double> *dof, + ElementLevelSet *elLS, + int domainFlag, + int deg = 2, + Quadrature* q = NULL); + static double H1Norm_DOF(DOFVector<double> *dof, + ElementLevelSet *elLS, + int domainFlag, + int deg = 0, + Quadrature* q = NULL); + static double H1NormSquare_DOF(DOFVector<double> *dof, + ElementLevelSet *elLS, + int domainFlag, + int deg = 0, + Quadrature* q = NULL); + + // ======================================================================== + // Calculation of error between + // -> true solution (analytically given) and + // -> FE solution (dof vector). + // + // Here, the H1-norm is the H1-seminorm, i.e. you get the "common" + // H1-norm by + // H1_Norm() = sqrt(L2_Norm^2() + H1_Seminorm^2()) . + // + // Parameter \ref domainFlag: + // -3: all elements in the domain with negative level set function + // values which do not intersect the zero level set + // -2 : all elements which intersect the domain with negative level set + // function values, in particular all (complete) elements which + // cut the zero level set + // -1 : domain with negative level set function values + // 0 : all elements cut by the zero level set + // 1 : complete mesh + // ======================================================================== + static double L2Err(AbstractFunction<double, WorldVector<double> > *u, + DOFVector<double> *uh, + ElementLevelSet *elLS, + int domainFlag, + int relErr = 0, + int deg = 2, + Quadrature *q = NULL); + static double H1Err( + AbstractFunction<WorldVector<double>, WorldVector<double> > *grdU, + DOFVector<double> *uh, + ElementLevelSet *elLS, + int domainFlag, + int relErr = 0, + int deg = 0, + Quadrature *q = NULL); + + /** + * Get absolute L2 error. + * (If relative L2 error is calculated, the absolute L2 error is also + * calculated and stored in L2_err_abs). + */ + inline static double getL2ErrAbs() + { + return L2_err_abs; + } + + /** + * Get absolute H1 error. + * (If relative H1 error is calculated, the absolute H1 error is also + * calculated and stored in H1_err_abs). + */ + inline static double getH1ErrAbs() + { + return H1_err_abs; + } + + /** + * Get L2 norm of solution u. + * (If relative L2 error is calculated, the L2 norm of the solution u is + * also calculated and stored in L2_u_norm). + */ + inline static double getL2_U_Norm() + { + return L2_u_norm; + } + + /** + * Get H1 norm of solution u. + * (If relative H1 error is calculated, the H1 norm of the solution u is + * also calculated and stored in H1_u_norm). + */ + inline static double getH1_U_Norm() + { + return H1_u_norm; + } + +protected: + static double Norm_IntNoBound(ElementNorm *elNorm, + ElementLevelSet *elLS, + Flag fillFlag, + int deg, + Quadrature* q); + static double Norm_IntBound(ElementNorm *elNorm, + ElementLevelSet *elLS, + Flag fillFlag, + int deg, + Quadrature* q); + static double Norm_Int(ElementNorm *elNorm, + ElementLevelSet *elLS, + Flag fillFlag, + int deg, + Quadrature* q); + static double Norm_Bound(ElementNorm *elNorm, + ElementLevelSet *elLS, + Flag fillFlag, + int deg, + Quadrature* q); + static double Norm_Complete(ElementNorm *elNorm, + ElementLevelSet *elLS, + Flag fillFlag, + int deg, + Quadrature* q); + + /** + * Calculate norm on subpolytope. + */ + static double calcSubPolNorm(ElInfo *elInfo, + SubPolytope *subPolytope, + ElementNorm *elNorm, + ScalableQuadrature *scalQuad, + const double &subPolFac = 1.0); + + protected: + /** + * Absolute L2 error (last L2 error calculation !). + */ + static double L2_err_abs; + + /** + * L2 norm of correct solution u (last L2 error calculation !). + */ + static double L2_u_norm; + + /** + * Absolute H1 error (last H1 error calculation !). + */ + static double H1_err_abs; + + /** + * H1 norm of correct solution u (last H1 error calculation !). + */ + static double H1_u_norm; +}; + +#endif // AMDIS_CFE_NORMANDERRORFCTS_H diff --git a/AMDiS/compositeFEM/src/CompositeFEMMethods.cc b/AMDiS/compositeFEM/src/CompositeFEMMethods.cc new file mode 100644 index 0000000000000000000000000000000000000000..55fdaf15ea80821f542234cd0966851283aa68e1 --- /dev/null +++ b/AMDiS/compositeFEM/src/CompositeFEMMethods.cc @@ -0,0 +1,145 @@ +#include "BasisFunction.h" +#include "DOFAdmin.h" +#include "Element.h" +#include "ElInfo.h" +#include "FiniteElemSpace.h" +#include "Global.h" +#include "Mesh.h" +#include "Parameters.h" +#include "Traverse.h" + +#include "CompositeFEMMethods.h" + + +void +CompositeFEMMethods::setPosLsToVal(DOFVector<double> *dof, + const double &val, + const DOFVector<double> *lsFct_dof) +{ + DOFVector<double>::Iterator it_dof(dof, USED_DOFS); + DOFVector<double>::Iterator it_lsFct_dof( + const_cast<DOFVector<double> *>(lsFct_dof), + USED_DOFS); + for (it_dof.reset(), it_lsFct_dof.reset(); + !it_dof.end(); + ++it_dof, ++it_lsFct_dof) { + + // Is vertex in domain with positive level set function values ? + if (*it_lsFct_dof > 0) { + *it_dof = val; + } + } +} + +void +CompositeFEMMethods::setPosLsToFct( + DOFVector<double> *dof, + const AbstractFunction<double, WorldVector<double> > *fct, + const DOFVector<double> *lsFct_dof) +{ + const BasisFunction *basisFcts = dof->getFESpace()->getBasisFcts(); + const DOFAdmin *admin = dof->getFESpace()->getAdmin(); + const int dim = dof->getFESpace()->getMesh()->getDim(); + const double *locVec; + const Element *el; + const DegreeOfFreedom *locInd; + TraverseStack stack; + + ElInfo *elInfo = stack.traverseFirst(dof->getFESpace()->getMesh(), -1, + Mesh::CALL_LEAF_EL | + Mesh::FILL_COORDS); + + while (elInfo) { + + el = elInfo->getElement(); + + // Get level set function values for all vertices of element. + locVec = lsFct_dof->getLocalVector(el, NULL); + + // Get dof indices of vertices. + locInd = basisFcts->getLocalIndices(el, admin, NULL); + + for (int i=0; i<=dim; ++i) { + // Is vertex in domain with positive level set function values ? + if (locVec[i] > 0) { + (*dof)[locInd[i]] = (*fct)(elInfo->getCoord(i)); + } + } + + elInfo = stack.traverseNext(elInfo); + } +} + +void +CompositeFEMMethods::printBoundaryElements(const std::string fn_str, + ElementLevelSet *elLS, + FiniteElemSpace *feSpace) +{ + FUNCNAME("CompositeFEMMethods::printBoundaryElements()"); + + int dim = feSpace->getMesh()->getDim(); + std::string fn_main; + std::string fn; + GET_PARAMETER(0, fn_str + "->filename", &fn_main); + fn = fn_main + "boundary_elements"; + int elStatus; + + ofstream boundaryOut(fn.c_str()); + + // ===== Traverse mesh and print boundary elements. ===== + TraverseStack stack; + int boundEl_cntr = 0; + WorldVector<double> coord; + + const int nBasFcts = feSpace->getBasisFcts()->getNumber(); + DegreeOfFreedom *locInd = GET_MEMORY(DegreeOfFreedom, nBasFcts); + + ElInfo *loc_elInfo = stack.traverseFirst(feSpace->getMesh(), + -1, + Mesh::CALL_LEAF_EL | + Mesh::FILL_BOUND | + Mesh::FILL_COORDS); + while(loc_elInfo) { + + // Get local indices of vertices. + feSpace->getBasisFcts()->getLocalIndices( + const_cast<Element *>(loc_elInfo->getElement()), + const_cast<DOFAdmin *>(feSpace->getAdmin()), + locInd); + + // Get element status. + elStatus = elLS->createElementLevelSet(loc_elInfo); + + // Is element cut by the interface ? + if (elStatus == ElementLevelSet::LEVEL_SET_BOUNDARY) { + ++boundEl_cntr; + + boundaryOut << loc_elInfo->getElement()->getIndex() << ": \t"; + + for (int i=0; i<=dim; ++i) { + + coord = loc_elInfo->getCoord(i); + + if (i > 0) { + boundaryOut << "\n\t"; + } + + boundaryOut << "\t" << coord[0]; + for (int j=1; j<dim; ++j) { + boundaryOut << "; " << coord[j] ; + } + boundaryOut << " (" << locInd[i] << ")"; + } + boundaryOut << "\n"; + } + + loc_elInfo = stack.traverseNext(loc_elInfo); + + } // end of: mesh traverse + + FREE_MEMORY(locInd, DegreeOfFreedom, nBasFcts); + + boundaryOut << "\nNumber of boundary elements: \t" << boundEl_cntr << "\n"; + + boundaryOut.close(); +} diff --git a/AMDiS/compositeFEM/src/CompositeFEMMethods.h b/AMDiS/compositeFEM/src/CompositeFEMMethods.h new file mode 100644 index 0000000000000000000000000000000000000000..41e484d1e00719ac75c5def82b869f98d6666f1d --- /dev/null +++ b/AMDiS/compositeFEM/src/CompositeFEMMethods.h @@ -0,0 +1,45 @@ +#ifndef AMDIS_COMPOSITEFEMMETHODS_H +#define AMDIS_COMPOSITEFEMMETHODS_H + +#include "AbstractFunction.h" +#include "DOFVector.h" +#include "FiniteElemSpace.h" +#include "MemoryManager.h" + +#include "ElementLevelSet.h" + +using namespace AMDiS; + +class CompositeFEMMethods +{ + public: + MEMORY_MANAGED(CompositeFEMMethods); + + /** + * Set all dof-values on domain with positive level set function values + * to val. + */ + static void setPosLsToVal( + DOFVector<double> *dof, + const double &val, + const DOFVector<double> *lsFct_dof); + + /** + * Set all dof-values on domain with positive level set function values + * to values of function fct. + */ + static void setPosLsToFct( + DOFVector<double> *dof, + const AbstractFunction<double, WorldVector<double> > *fct, + const DOFVector<double> *lsFct_dof); + + /** + * Print coordinates of all boundary elements to file. Name of file is + * read from init file. + */ + static void printBoundaryElements(const std::string fn_str, + ElementLevelSet *elLS, + FiniteElemSpace *feSpace); +}; + +#endif // AMDIS_COMPOSITEFEMMETHODS_H diff --git a/AMDiS/compositeFEM/src/CompositeFEMOperator.cc b/AMDiS/compositeFEM/src/CompositeFEMOperator.cc new file mode 100644 index 0000000000000000000000000000000000000000..d635200c343c8a7d3733889308ffa86f17af804e --- /dev/null +++ b/AMDiS/compositeFEM/src/CompositeFEMOperator.cc @@ -0,0 +1,298 @@ +#include "CompositeFEMOperator.h" + +#include "ElementMatrix.h" +#include "ElementVector.h" + +#include "SubElementAssembler.h" +#include "SubElInfo.h" +#include "SubPolytope.h" + +void +CompositeFEMOperator::getElementMatrix(const ElInfo *elInfo, + ElementMatrix *userMat, + double factor) +{ + FUNCNAME("CompositeFEMOperator::getElementMatrix"); + + VectorOfFixVecs<DimVec<double> > *intersecPoints = NULL; + SubPolytope *subPolytope = NULL; + double levelSetSubPolytope; + ElementMatrix *elMat; + ElementMatrix *subPolMat1; + ElementMatrix *subPolMat2; + DimVec<double> subElVertexBarCoords(elInfo->getMesh()->getDim()); + + /** + * Get element status. Does element lie completely inside the integration + * domain, completely outside of the integration domain or is it + * intersected by the boundary ? + */ + elStatus = elLS->createElementLevelSet(elInfo); + + /** + * element status == completely inside or outside + * ---> take the "normal" + * integration routine + * Operator::getElementMatrix + * element status == lies on boundary ---> integration on subpolytopes and + * subelements + */ + if (elStatus == ElementLevelSet::LEVEL_SET_INTERIOR || + elStatus == ElementLevelSet::LEVEL_SET_EXTERIOR) { + + elLS->setLevelSetDomain(elStatus); + Operator::getElementMatrix(elInfo, userMat, factor); + return; + } + + /*************************************************************************** + * Integration on intersected element. + * + * The integral is calculated as the sum of integrals on the two + * subpolytopes given by the intersection. + * We only calculate the integral on one of the subpolytopes. The + * integral on the second subpolytope then is the difference between the + * integral on the complete element and the integral on the first + * subpolytope. + */ + + if(!subElementAssembler) { + subElementAssembler = NEW SubElementAssembler(this, + rowFESpace, + colFESpace); + } + + /** + * Get intersection points. + */ + intersecPoints = elLS->getElIntersecPoints(); + subPolytope = NEW SubPolytope(elInfo, + intersecPoints, + elLS->getNumElIntersecPoints()); + + /** + * Calculate integral on element. + * + * Whether a subpolytope lies inside or outside the integration domain is + * decided using the level set of the first vertex in the first subelement + * of the subpolytope. (The subelements of a subpolytope are created in + * such a way that this vertex always is a vertex of the element + * and not an intersection point. Thus the level set of this vertex really + * is unequal to zero.) + */ + + /** + * Integration on subPolytope. + */ + subElVertexBarCoords = subPolytope->getSubElement(0)->getLambda(0); + levelSetSubPolytope = elLS->getVertexPos( + (const DimVec<double>) subElVertexBarCoords); + + if (levelSetSubPolytope < 0) { + elLS->setLevelSetDomain(ElementLevelSet::LEVEL_SET_INTERIOR); + } + else if (levelSetSubPolytope > 0) { + elLS->setLevelSetDomain(ElementLevelSet::LEVEL_SET_EXTERIOR); + } + else { + ERROR_EXIT("cannot get position of subpolytope\n"); + } + + subPolMat1 = NEW ElementMatrix(subElementAssembler->getNRow(), + subElementAssembler->getNCol()); + subPolMat1->set(0.0); + subElementAssembler->getSubPolytopeMatrix(subPolytope, + subElementAssembler, + elInfo, + subPolMat1); + + /** + * Integration on second subpolytope produced by the intersection. + */ + elMat = NEW ElementMatrix(subElementAssembler->getNRow(), + subElementAssembler->getNCol()); + elMat->set(0.0); + subPolMat2 = NEW ElementMatrix(subElementAssembler->getNRow(), + subElementAssembler->getNCol()); + subPolMat2->set(0.0); + + if(!assembler) { + assembler = NEW StandardAssembler(this, NULL, NULL, NULL, NULL, + rowFESpace, colFESpace); + } + + if (elLS->getLevelSetDomain() == + ElementLevelSet::LEVEL_SET_INTERIOR) { + elLS->setLevelSetDomain(ElementLevelSet::LEVEL_SET_EXTERIOR); + } + else { + elLS->setLevelSetDomain(ElementLevelSet::LEVEL_SET_INTERIOR); + } + + assembler->calculateElementMatrix(elInfo, elMat, 1.0); + subElementAssembler->getSubPolytopeMatrix(subPolytope, + subElementAssembler, + elInfo, + subPolMat2); + + axpy(-1.0, *subPolMat2, *elMat); + + // Get integral on element as sum of the two integrals on subpolytopes. + axpy(1.0, *subPolMat1, *elMat); + + // Add integral to userMat. + axpy(factor, *elMat, *userMat); + + /** + * Free data. + */ + DELETE subPolytope; + DELETE elMat; + DELETE subPolMat1; + DELETE subPolMat2; + + return; +} + +void +CompositeFEMOperator::getElementVector(const ElInfo *elInfo, + ElementVector *userVec, + double factor) +{ + FUNCNAME("CompositeFEMOperator::getElementVector"); + + VectorOfFixVecs<DimVec<double> >*intersecPoints = NULL; + SubPolytope *subPolytope = NULL; + double levelSetSubPolytope; + ElementVector *elVec; + ElementVector *subPolVec1; + ElementVector *subPolVec2; + DimVec<double> subElVertexBarCoords(elInfo->getMesh()->getDim()); + + /** + * Get element status. Does element lie completely inside the integration + * domain, completely outside of the integration domain or is it + * intersected by the boundary ? + */ + elStatus = elLS->createElementLevelSet(elInfo); + + /** + * element status == completely inside or outside + * ---> take the "normal" + * integration routine + * Operator::getElementVector + * element status == lies on boundary ---> integration on subpolytopes and + * subelements + */ + if (elStatus == ElementLevelSet::LEVEL_SET_INTERIOR || + elStatus == ElementLevelSet::LEVEL_SET_EXTERIOR) { + + elLS->setLevelSetDomain(elStatus); + Operator::getElementVector(elInfo, userVec, factor); + return; + } + + /********************************************************************************* + * Integration on intersected element. + * + * The integral is calculated as the sum of integrals on the two + * subpolytopes given by the intersection. + * We only calculate the integral on one of the subpolytopes. The integral + * on the second subpolytope then is the difference between the integral on + * the complete element and the integral on the first subpolytope. + */ + + if(!subElementAssembler) { + subElementAssembler = NEW SubElementAssembler(this, + rowFESpace, + colFESpace); + } + + /** + * Get intersection points. + */ + intersecPoints = elLS->getElIntersecPoints(); + subPolytope = NEW SubPolytope(elInfo, + intersecPoints, + elLS->getNumElIntersecPoints()); + + /** + * Calculate integral on element. + * + * Whether a subpolytope lies inside or outside the integration domain is + * decided using the level set of the first vertex in the first subelement + * of the subpolytope. (The subelements of a subpolytope are created in + * such a way that this vertex is always a vertex of the element and not + * an intersection point. Thus the level set of this vertex really is + * unequal to zero.) + */ + + /** + * Integration on ubPolytope. + */ + subElVertexBarCoords = subPolytope->getSubElement(0)->getLambda(0); + levelSetSubPolytope = elLS->getVertexPos( + (const DimVec<double>) subElVertexBarCoords); + + if (levelSetSubPolytope < 0) { + elLS->setLevelSetDomain(ElementLevelSet::LEVEL_SET_INTERIOR); + } + else if (levelSetSubPolytope > 0) { + elLS->setLevelSetDomain(ElementLevelSet::LEVEL_SET_EXTERIOR); + } + else { + ERROR_EXIT("cannot get position of subpolytope\n"); + } + + subPolVec1 = NEW ElementVector(subElementAssembler->getNRow()); + subPolVec1->set(0.0); + subElementAssembler->getSubPolytopeVector(subPolytope, + subElementAssembler, + elInfo, + subPolVec1); + + /** + * Integration on second subpolytope produced by the intersection. + */ + elVec = NEW ElementVector(subElementAssembler->getNRow()); + elVec->set(0.0); + subPolVec2 = NEW ElementVector(subElementAssembler->getNRow()); + subPolVec2->set(0.0); + + if(!assembler) { + assembler = NEW StandardAssembler(this, NULL, NULL, NULL, NULL, + rowFESpace, colFESpace); + } + + if (elLS->getLevelSetDomain() == + ElementLevelSet::LEVEL_SET_INTERIOR) { + elLS->setLevelSetDomain(ElementLevelSet::LEVEL_SET_EXTERIOR); + } + else { + elLS->setLevelSetDomain(ElementLevelSet::LEVEL_SET_INTERIOR); + } + + assembler->calculateElementVector(elInfo, elVec, 1.0); + subElementAssembler->getSubPolytopeVector(subPolytope, + subElementAssembler, + elInfo, + subPolVec2); + + axpy(-1.0, *subPolVec2, *elVec); + + // Get integral on element as sum of the two integrals on subpolytopes. + axpy(1.0, *subPolVec1, *elVec); + + // Add integral to userVec. + axpy(factor, *elVec, *userVec); + + /** + * Free data. + */ + DELETE subPolytope; + DELETE elVec; + DELETE subPolVec1; + DELETE subPolVec2; + + return; +} diff --git a/AMDiS/compositeFEM/src/CompositeFEMOperator.h b/AMDiS/compositeFEM/src/CompositeFEMOperator.h new file mode 100644 index 0000000000000000000000000000000000000000..7ef3c7a6bfa3d037a2102bdf95ffc0d708ba2d92 --- /dev/null +++ b/AMDiS/compositeFEM/src/CompositeFEMOperator.h @@ -0,0 +1,106 @@ +/** \file CompositeFEMOperator.h */ + +#ifndef AMDIS_COMPOSITEFEMOPERATOR_H +#define AMDIS_COMPOSITEFEMOPERATOR_H + +#include "FixVec.h" +#include "Flag.h" +#include "ElementLevelSet.h" +#include "MemoryManager.h" +#include "Operator.h" + +#include "ElementLevelSet.h" +#include "SubElementAssembler.h" + +namespace AMDiS { +class ElInfo; +class FiniteElemSpace; +} + +using namespace AMDiS; +using namespace std; + +// =========================================================================== +// === class CompositeFEMOperator ============================================ +// =========================================================================== +// +// Class Description: +// Class CompositeFEMOperator realizes the calculation of element-vectors +// and element-matrices for subelements. +// The boundary of the integration domain is the level set zero of the level +// set function (object elLevelSet). If the boundary intersects an +// element the integration for subelements is used (see class SubPolytope). +// Else, integration is done as usual. +// ============================================================================ +class CompositeFEMOperator : public Operator +{ +public: + MEMORY_MANAGED(CompositeFEMOperator); + /** + * Constructor. + */ + CompositeFEMOperator(Flag operatorType_, + ElementLevelSet *elLS_, + const FiniteElemSpace *rowFESpace_, + const FiniteElemSpace *colFESpace_ = NULL) + : Operator(operatorType_, rowFESpace_, colFESpace_), + elLS(elLS_), + subElementAssembler(NULL), + elStatus(ElementLevelSet::LEVEL_SET_UNDEFINED) + {}; + + /** + * Empty Destructor. + */ + ~CompositeFEMOperator() + { + if (subElementAssembler) + DELETE subElementAssembler; + }; + + /** + * Calculates the element matrix for this ElInfo and adds it multiplied by + * factor to userMat. + * In addition to Operator::getElementMatrix(), it distinguishes + * between elements divided by the boundary (level set zero intersects + * the element) and elements lying completely inside or outside the + * integration domain. + */ + void getElementMatrix(const ElInfo *elInfo, + ElementMatrix *userMat, + double factor = 1.0); + + /** + * Calculates the element vector for this ElInfo and adds it multiplied by + * factor to userVec. + * Similar to getElementMatrix it distinguishes between elements divided by + * the boundary and elements lying completely inside or outside the + * integration domain. + */ + void getElementVector(const ElInfo *elInfo, + ElementVector *userVec, + double factor = 1.0); + +protected: + /** + * Holds level set function and functionalities for intersection point + * calculation. + */ + ElementLevelSet *elLS; + + /** + * Calculates the element matrix and/or the element vector for subelements. + * It is created especially for this Operator, when getElementMatrix() + * or getElementVector is called for the first time. + */ + SubElementAssembler *subElementAssembler; + + /** + * Indicator for the position of an element. It shows whether an element + * lies inside the integration domain, outside of the integration domain + * or on the boundary. + */ + int elStatus; +}; + +#endif // AMDIS_COMPOSITEFEMOPERATOR_H diff --git a/AMDiS/compositeFEM/src/ElementLevelSet.cc b/AMDiS/compositeFEM/src/ElementLevelSet.cc new file mode 100644 index 0000000000000000000000000000000000000000..0f4176361207cc9702ae5ce4ac4b7097eba49621 --- /dev/null +++ b/AMDiS/compositeFEM/src/ElementLevelSet.cc @@ -0,0 +1,423 @@ +#include "ElementLevelSet.h" +#include "ElInfo.h" + +int +ElementLevelSet::createElementLevelSet(const ElInfo *elInfo_, + const bool doCalcIntersecPts_) +{ + Element *el = elInfo_->getElement(); + + if (elInfo == NULL || el != lastEl) { + /** + * Element has changed. New calculation. + */ + + // Set new element. + lastEl = el; + + // Set information for element and reset data. + setElement(elInfo_); + + // Calculate level set function values for each vertex of element. + calculateElementLevelSetVal(); + + // Check whether level set function values are not too small. + checkElementLevelSetVal(); + + // Calculate status of element and element vertices. + calculateElementStatus(); + + // Calculate intersection points with zero level set if necessary. + if (doCalcIntersecPts_ && elStatus == LEVEL_SET_BOUNDARY) { + calculateIntersecPoints(); + + // dim == 3: sort intersection points if necessary + if (dim == 3 && numIntersecPoints == 4) + sortIntersecPoints_4IP3D(); + } + } + +// else { + /** + * LevelSet-Status for element has already been calculated. + */ +// } + + return elStatus; +} + +void +ElementLevelSet::calculateElementLevelSetVal() +{ + DimVec<double> lambda(dim, DEFAULT_VALUE, 0.0); + + for (int i = 0; i <= dim; i++) { + + lambda[i] = 1.0; + lSFct->setElInfo(elInfo); + elVertexLevelSetVec[i] = (*lSFct)((const DimVec<double>) lambda); + lambda[i] = 0.0; + } +} + +int +ElementLevelSet::calculateElementStatus() +{ + for (int i=0; i<=dim; ++i) { + if (elVertexLevelSetVec[i] < 0) { + elVertexStatusVec[i] = LEVEL_SET_INTERIOR; + numElVertexInterior++; + } + else { + elVertexStatusVec[i] = LEVEL_SET_EXTERIOR; + numElVertexExterior++; + } + } + + /** + * Calculate level set status of element. + */ + if (numElVertexInterior == dim+1) { + elStatus = LEVEL_SET_INTERIOR; + return LEVEL_SET_INTERIOR; + } + if (numElVertexExterior == dim+1) { + elStatus = LEVEL_SET_EXTERIOR; + return LEVEL_SET_EXTERIOR; + } + elStatus = LEVEL_SET_BOUNDARY; + return LEVEL_SET_BOUNDARY; +} + +void +ElementLevelSet::calculateIntersecPoints() +{ + //************************************************************************** + // The level set function is linearly approximated by a hyperplane through + // the points of the graph of the level set function in the vertices + // of the element. + // This routine calculates the intersection points of the hyperplane + // with the edges of the element. + //************************************************************************** + DimVec<double> tempPoint(dim); + DimVec<double> zeroVec(dim, DEFAULT_VALUE, 0.0); + int i, j; + + /** + * Get intersection points (in barycentric coordinates). + * + * An edge is intersected if its vertices have level sets with + * different sign. + */ + for (i = 0; i <= dim; i++) { + for (j = i+1; j <= dim; j++) { + + if (elVertexStatusVec[i] * elVertexStatusVec[j] < 0.0) { + + tempPoint = zeroVec; + tempPoint[j] = elVertexLevelSetVec[i] / + (elVertexLevelSetVec[i] - elVertexLevelSetVec[j]); + checkIntersecBary(tempPoint[j]); + tempPoint[i] = 1 - tempPoint[j]; + + (*elIntersecPoints)[numIntersecPoints] = tempPoint; + ++numIntersecPoints; + } + + } // for(j ... + } // for(i ... +} + +int +ElementLevelSet::checkElementLevelSetVal() +{ + int changed = 0; + double abs_grd_val = 0.0; + double abs_min_val = 0.0; + double comp = 0.0; + + for (int i=0; i<dim; ++i) { + comp = elVertexLevelSetVec[i]-elVertexLevelSetVec[dim]; + abs_grd_val += comp*comp; + } + abs_grd_val = sqrt(abs_grd_val); + + abs_min_val = LS_VAL_TOL*abs_grd_val; + abs_min_val = (abs_min_val > LS_VAL_MIN) ? abs_min_val : LS_VAL_MIN; + + for (int i=0; i<=dim; ++i) { + if (fabs(elVertexLevelSetVec[i]) < abs_min_val) { +// elVertexLevelSetVec[i] = abs_min_val; + elVertexLevelSetVec[i] = (elVertexLevelSetVec[i] < 0) ? + -abs_min_val : abs_min_val; + ++changed; + } + } + + return changed; +} + +bool +ElementLevelSet::checkIntersecBary(double &bary) +{ + if (bary < SP_BARY_TOL) { + bary = SP_BARY_TOL; + return true; + } + if (bary > 1-SP_BARY_TOL) { + bary = 1-SP_BARY_TOL; + return true; + } + + return false; +} + +void +ElementLevelSet::sortIntersecPoints_4IP3D() +{ + FUNCNAME("sortIntersecPoints_4IP3D"); + + int indexFace1 = 0; + int indexFace2 = 0; + int indexOpVert = 0; + DimVec<double> tempPoint(dim); + int i,j; + + /** + * Consider the 4 intersection points S0, S1, S2 and S3. If the components + * of S0 indexFace1 and indexFace2 are not zero, i.e. S0 lies in + * the element faces indexFace1 and indexFace2, the intersection + * point with zero components indexFace1 and indexFace2 is + * opposite to S0 in the intersection plane. Move this vertex to the end + * of the intersection point list elIntersecPoints. + */ + + // Get indexFace1 and indexFace2. + for (i = 0; i < numIntersecPoints; i++) { + if (fabs((*elIntersecPoints)[0][i]) > 1.e-15) { + indexFace1 = i; + break; + } + } + for (j = i+1; j < numIntersecPoints; j++) { + if (fabs((*elIntersecPoints)[0][j]) > 1.e-15) { + indexFace2 = j; + break; + } + } + + // Get index of vertex opposite to S0. + for (i = 1; i < numIntersecPoints; i++) { + if (fabs((*elIntersecPoints)[i][indexFace1]) <= 1.e-15 && + fabs((*elIntersecPoints)[i][indexFace2]) <= 1.e-15) { + indexOpVert = i; + break; + } + } + + // Move vertex to the end of \ref elIntersecPoints. + if (indexOpVert != numIntersecPoints-1) { + tempPoint = (*elIntersecPoints)[indexOpVert]; + (*elIntersecPoints)[indexOpVert] = (*elIntersecPoints)[numIntersecPoints-1]; + (*elIntersecPoints)[numIntersecPoints-1] = tempPoint; + } + + return; +} + +void +ElementLevelSet::calcIntersecNormal(WorldVector<double> &normalVec) +{ + FUNCNAME("ElementLevelSet::calcIntersecNormal"); + + switch(dim) { + case 2: calcIntersecNormal_2d(normalVec); + break; + case 3: calcIntersecNormal_3d(normalVec); + break; + default: ERROR_EXIT("illegal dimension !\n"); + } +}; + +void +ElementLevelSet::calcIntersecNormal_2d(WorldVector<double> &normalVec) +{ + FUNCNAME("ElementLevelSet::calcIntersecNormal_2d"); + + TEST_EXIT(numIntersecPoints == 2)("illegal number of intersection points !\n"); + + // ===== Get world coordinates of intersection points. ===== + WorldVector<double> sP1; + WorldVector<double> sP2; + elInfo->coordToWorld((*elIntersecPoints)[0], &sP1); + elInfo->coordToWorld((*elIntersecPoints)[1], &sP2); + + // ===== Calculate normal vector. ===== + double norm2 = 0.0; + double val; + for (int i=0; i<dim; ++i){ + val = sP1[i] - sP2[i]; + norm2 += val*val; + normalVec[dim-1-i] = val; + } + normalVec[0] *= -1; + double norm = sqrt(norm2); + for(int i=0; i<dim; ++i) { + normalVec[i] = 1/norm * normalVec[i]; + } + + // ===== Set correct orientation (exterior normal vector). ===== + + // Calculate barycenter. + WorldVector<double> baryc; + for (int i=0; i<dim; ++i) { + baryc[i] = 0.5*sP1[i] + 0.5*sP2[i]; + } + double d = sqrt((sP1-sP2)*(sP1-sP2)); + + // Barycenter + factor*normalVec. + double elSize = sqrt(fabs(elInfo->getDet())); + double factor = 0.01*d/elSize; + WorldVector<double> tmpPoint; + int cntr = 0; + DimVec<double> lambda(dim, NO_INIT); + + while (1) { + ++cntr; + + for(int i=0; i<dim; ++i) { + tmpPoint[i] = baryc[i] + factor*normalVec[i]; + } + + elInfo->worldToCoord(tmpPoint, &lambda); + for (int i=0; i<=dim; ++i) { + if (lambda[i] < 0) { + factor *= 0.1; + + if (cntr == 10) { + WARNING("inefficient normal vector calculation !\n"); + } + if (cntr == 100) { + ERROR_EXIT("infinite loop !\n"); + } + + continue; + } + } + + break; + } + + if (ElementLevelSet::calcLevelSetFct(lambda) < 0) { + for (int i=0; i<dim; ++i) { + normalVec[i] *= -1; + } + } +}; + +void +ElementLevelSet::calcIntersecNormal_3d(WorldVector<double> &normalVec) +{ + FUNCNAME("ElementLevelSet::calcIntersecNormal_3d"); + + TEST_EXIT(numIntersecPoints == 3 || numIntersecPoints == 4)("illegal number of intersection points !\n"); + + // ===== Get world coordinates of intersection points. ===== + WorldVector<double> sP1; + WorldVector<double> sP2; + WorldVector<double> sP3; + elInfo->coordToWorld((*elIntersecPoints)[0], &sP1); + elInfo->coordToWorld((*elIntersecPoints)[1], &sP2); + elInfo->coordToWorld((*elIntersecPoints)[2], &sP3); + + // ===== Calculate normal vector. ===== + WorldVector<double> A = sP2-sP1; + WorldVector<double> B = sP3-sP1; + vectorProduct(A, B, normalVec); + + double norm = sqrt(normalVec * normalVec); + for(int i=0; i<dim; ++i) { + normalVec[i] = 1/(norm+1.e-4) * normalVec[i]; + } + + // ===== Set correct orientation (exterior normal vector). ===== + + // Calculate barycenter. + WorldVector<double> baryc; + for (int i=0; i<dim; ++i) { + baryc[i] = 1.0/3*sP1[i] + 1.0/3*sP2[i] + 1.0/3*sP3[i]; + } + double d = sqrt((sP1-sP2)*(sP1-sP2)); + + // Barycenter + factor*normalVec. + double elSize = pow(fabs(elInfo->getDet()), 1.0/3); + double factor = 0.01*d/elSize; + WorldVector<double> tmpPoint; + int cntr = 0; + DimVec<double> lambda(dim, NO_INIT); + + while (1) { + ++cntr; + + for(int i=0; i<dim; ++i) { + tmpPoint[i] = baryc[i] + factor*normalVec[i]; + } + + elInfo->worldToCoord(tmpPoint, &lambda); + for (int i=0; i<=dim; ++i) { + if (lambda[i] < 0) { + factor *= 0.1; + + if (cntr == 10) { + WARNING("inefficient normal vector calculation !\n"); + } + if (cntr == 100) { + ERROR_EXIT("infinite loop !\n"); + } + + continue; + } + } + + break; + } + + if (ElementLevelSet::calcLevelSetFct(lambda) < 0) { + for (int i=0; i<dim; ++i) { + normalVec[i] *= -1; + } + } +}; + +int +ElementLevelSet::getVertexPos(const DimVec<double> barCoords) +{ + double vertex_val; + + for (int i=0; i<=dim; ++i) { + if (barCoords[i] > 1-1.e-15) { + vertex_val = elVertexLevelSetVec[i]; + break; + } + } + + if (vertex_val > 0) { + return LEVEL_SET_EXTERIOR; + } + else { + return LEVEL_SET_INTERIOR; + } +} + +int +ElementLevelSet::getElPos(const DimVec<double> barCoords) +{ + double ls_val = calcLevelSetFct(barCoords); + if (ls_val > 0) { + return LEVEL_SET_EXTERIOR; + } + else { + return LEVEL_SET_INTERIOR; + } +} + diff --git a/AMDiS/compositeFEM/src/ElementLevelSet.h b/AMDiS/compositeFEM/src/ElementLevelSet.h new file mode 100644 index 0000000000000000000000000000000000000000..35d80d308cd6890eeadc056b66b32c9ab041cc4f --- /dev/null +++ b/AMDiS/compositeFEM/src/ElementLevelSet.h @@ -0,0 +1,497 @@ +#ifndef AMDIS_ELEMENTLEVELSET_H +#define AMDIS_ELEMENTLEVELSET_H + +#include "ElementFunction.h" +#include "FixVec.h" +#include "MemoryManager.h" +#include "Parameters.h" + +namespace AMDiS { + class Element; + class ElInfo; + class Mesh; +} + +using namespace AMDiS; +using namespace std; + +// =========================================================================== +// ===== class ElementLevelSet =============================================== +// =========================================================================== +// +// Class Description: +// The class ElementLevelSet contains the functionality for +// - calculating the intersection points resulting from an intersection +// of the boundary (level set zero) with an element, +// - calculating the status of an element, i.e. is the element cut +// by the zero level set or not. +// The calculation of the intersection points is done as follows: +// The level set function is linearly approximated on the element, i.e. its +// graph is approximated by the plane through the level set values of the +// element vertices. We approximate the intersection points by the +// intersection of the plane with the element edges. +// If in 3-dimensional finite element space the intersection produced 4 +// intersection points S0, S1, S2, S3, the intersection points in +// elIntersecPoints are rearranged so that S1 and S2 divides the intersection +// plane in two (dim - 1)-dimensional simplices. +// +// Constants indicating the level set status of element: +// LEVEL_SET_INTERIOR - element is in domain where level set function +// is negative +// LEVEL_SET_BOUNDARY - element is in domain where level set function +// is positive +// LEVEL_SET_EXTERIOR - element is cut by the zero level set +// +// Main routines: +// setElementLevelSet() - Defines the level set function for the +// following calculations. +// createElementLevelSet() - Calculates level set status of element and +// intersection points if needed. +// calculateElementLevelSetVal() - Calculates values of the level set +// function in the element vertices. +// setElement() - Sets elInfo. +// getElementLevelSetStatus() - Returns status of element. +// getElementIntersecPoints() - Returns intersection points. +// getElVertStatusVec() - Returns vector with status information +// for each vertex. +// =========================================================================== +class ElementLevelSet +{ + public: + MEMORY_MANAGED(ElementLevelSet); + + /** + * Constructor. + */ + ElementLevelSet(const char *name_, + ElementFunction<double> *lSFct_, + Mesh *mesh_) + : name(name_), + elInfo(NULL), + lastEl(NULL), + level_set_domain(LEVEL_SET_UNDEFINED), + numIntersecPoints(0), + elStatus(LEVEL_SET_UNDEFINED), + numElVertexInterior(0), + numElVertexBoundary(0), + numElVertexExterior(0), + LS_VAL_TOL(1.e-8), + LS_VAL_MIN(1.e-8), + SP_BARY_TOL(1.e-7) + { + FUNCNAME("ElementLevelSet::ElementLevelSet()"); + + TEST_EXIT(lSFct_ || mesh_) + ("illegal initialization of ElementLevelSet!\n"); + + lSFct = lSFct_; + mesh = mesh_; + dim = mesh->getDim(); + + elIntersecPoints = + NEW VectorOfFixVecs<DimVec<double> >(dim, + MAX_INTERSECTION_POINTS, + NO_INIT); + elVertexStatusVec = new int[dim+1]; + elVertexLevelSetVec = new double[dim+1]; + + int setElementLevelSetTol = 0; + GET_PARAMETER(0, name + "->set ElementLevelSet tolerances", "%d", + &setElementLevelSetTol); + if (setElementLevelSetTol) { + + GET_PARAMETER(0, name + "->LS_VAL_TOL", "%f", &LS_VAL_TOL); + GET_PARAMETER(0, name + "->LS_VAL_MIN", "%f", &LS_VAL_MIN); + GET_PARAMETER(0, name + "->SP_BARY_TOL", "%f", &SP_BARY_TOL); + + TEST_EXIT(LS_VAL_TOL > 0)("illegal LS_VAL_TOL\n"); + TEST_EXIT(LS_VAL_MIN > 0)("illegal LS_VAL_MIN\n"); + TEST_EXIT(SP_BARY_TOL > 0)("illegal SP_BARY_TOL\n"); + } + }; + + /** + * Destructor. + */ + ~ElementLevelSet() + { + if (elVertexStatusVec) + delete [] elVertexStatusVec; + if(elVertexLevelSetVec) + delete [] elVertexLevelSetVec; + if (elIntersecPoints) + DELETE elIntersecPoints; + }; + + /** + * Calculates LevelSet-status of element and its intersection points + * with the zero level set if necessary. + * + * Result: + * LEVEL_SET_BOUNDARY: Element elInfo is intersected by levelSetFct. + * LEVEL_SET_EXTERIOR / LEVEL_SET_INTERIOR: Element lies completely on + * one side of the zero level set. + * + * After proceeding this function, information about the level set + * status is given in: + * elStatus: status of element (LEVEL_SET_BOUNDARY, LEVEL_SET_INTERIOR or + * EXTERIOR) + * elVertexStatusVec: stores status of each vertex of element + * elVertexLevelSetVec: stores level set function value of each vertex of + * element + * numElVertexInterior: number of vertices of element with status + * LEVEL_SET_INTERIOR + * numElVertexExterior: number of vertices of element with status + * LEVEL_SET_EXTERIOR + * numElVertexBoundary: number of vertices of element with status + * LEVEL_SET_BOUNDARY + * elIntersecPoints: stores the intersection points produced by the + * intersection of element with the zero level set + * numIntersecPoints: number of intersection points + */ + int createElementLevelSet(const ElInfo *elInfo_, + const bool doCalcIntersecPts_ = true); + + /** + * Gets value of level set function at point given in + * barycentric coordinates. + */ + inline const double& calcLevelSetFct(const DimVec<double>& bary) { + return (*lSFct)(bary); + }; + + /** + * Resets level set information on element. + */ + inline void resetElement() { + FUNCNAME("ElementLevelSet::resetElement"); + + numElVertexInterior = 0; + numElVertexBoundary = 0; + numElVertexExterior = 0; + numIntersecPoints = 0; + elStatus = LEVEL_SET_UNDEFINED; + }; + + /** + * Defines current element (elInfo). + */ + inline void setElement(const ElInfo *elInfo_) { + elInfo = elInfo_; + resetElement(); + }; + + /** + * Set level_set_domain. + */ + inline void setLevelSetDomain(int status_) { + + TEST_EXIT(status_ == LEVEL_SET_INTERIOR || + status_ == LEVEL_SET_EXTERIOR || + status_ == LEVEL_SET_BOUNDARY)("illegal level set status !\n"); + level_set_domain = status_; + }; + + /** + * Functions to set tolerances for intersection point calculation. + */ + inline void setLsValTol(double tol) {LS_VAL_TOL = tol;}; + inline void setLsValMin(double min) {LS_VAL_MIN = min;}; + inline void setSpBaryTol(double tol) {SP_BARY_TOL = tol;}; + + /** + * Get level_set_domain. + */ + inline const int& getLevelSetDomain() const { + return level_set_domain; + }; + + /** + * Get LevelSet-Status of element. + */ + inline const int& getElementLevelSetStatus() const { + return elStatus; + }; + + /** + * Get number of vertices which are intersection points. + */ + inline const int& getNumVertIntPoints() const { + FUNCNAME("ElementLevelSet::getNumVertIntPoints"); + TEST_EXIT(numElVertexBoundary == 0)("numElVertexBoundary should be zero!\n"); + return numElVertexBoundary; + }; + + /** + * Get vector elVertexStatusVec. + */ + inline const int *getElVertStatusVec() const { + return elVertexStatusVec; + }; + + /** + * Get i-th component of vector elVertexLevelSetVec. + */ + inline const double getElVertLevelSetVec(const int i) const { + return elVertexLevelSetVec[i]; + }; + + /** + * Get vector elVertexLevelSetVec. + */ + inline const double *getElVertLevelSetVec() const { + return elVertexLevelSetVec; + }; + + /** + * Get levelSetFct. + */ + inline ElementFunction<double> *getLevelSetFct() const { + return lSFct; + }; + + /** + * Get mesh. + */ + inline Mesh *getMesh() const { + return mesh; + }; + + /** + * Get dim. + */ + inline int getDim() const { + return dim; + }; + + /** + * Get the intersection points. + */ + inline VectorOfFixVecs<DimVec<double> > *getElIntersecPoints() const { + return elIntersecPoints; + }; + + /** + * Get number of intersection points. + */ + inline int getNumElIntersecPoints() const { + return numIntersecPoints; + }; + + /** + * Calculate exterior normal to intersection plane. + */ + void calcIntersecNormal(WorldVector<double> &normal); + + /** + * Gets position of point in element with barycentric coordinates + * barCoords, i.e. whether point is in the domain with positive + * (LEVEL_SET_EXTERIOR) or negative (LEVEL_SET_INTERIOR) level set + * function values. Uses level set function, thus element vertices + * may have level set function value zero. + */ + int getElPos(const DimVec<double> barCoords); + + /** + * Gets position of element vertex given in barycentric coordinates, + * i.e. whether element vertex is in the domain with positive + * (LEVEL_SET_EXTERIOR) or negative (LEVEL_SET_INTERIOR) level set + * function values. Uses elVertexLevelSetVec. + */ + int getVertexPos(const DimVec<double> barCoords); + + protected: + /** + * Calculates level set value of each vertex of element. + */ + void calculateElementLevelSetVal(); + + /** + * Calculates the status of an element. + * + * Note: Uses values in elVertexLevelSetVec. + * + * Return value: + * LEVEL_SET_INTERIOR element lies completely inside + * LEVEL_SET_EXTERIOR element lies completely outside + * LEVEL_SET_BOUNDARY element is cut by the zero level set + */ + int calculateElementStatus(); + + /** + * Calculates intersection points of zero level set with element. + * + * Note: Uses elVertexLevelSet. + */ + void calculateIntersecPoints(); + + /** + * Checks whether level set values of element (in elVertexLevelSetVec) + * are below a certain bound and corrects them if this is the case. + * + * Return value: number of values corrected + */ + int checkElementLevelSetVal(); + + /** + * Checks whether barycentric coordinate of intersection point is not + * too small and corrects it if this is the case. + * + * Return value: true - barycentric coordinate has been corrected + * false - barycentric coordinate is ok + */ + bool checkIntersecBary(double &bary); + + /** + * Sort intersection points S0, S1, S2 and S3 in \ref elIntersecPoints in + * such a way that afterwards, a line through S1 and S2 divides the + * intersection plane into two (\ref dim - 1)-dimensional simplices. + */ + void sortIntersecPoints_4IP3D(); + + /** + * Calculate exterior normal to intersection plane for dimension 2. + */ + void calcIntersecNormal_2d(WorldVector<double> &normal); + + /** + * Calculate exterior normal to intersection plane for dimension 3. + */ + void calcIntersecNormal_3d(WorldVector<double> &normal); + + public: + /** + * Constants characterizing element position with respect to zero level set. + */ + static const int LEVEL_SET_INTERIOR = -1; + static const int LEVEL_SET_BOUNDARY = 0; + static const int LEVEL_SET_EXTERIOR = 1; + static const int LEVEL_SET_UNDEFINED = -2; + + protected: + /** + * Name of this object. + */ + std::string name; + + /** + * Level set function. + */ + ElementFunction<double> *lSFct; + + /** + * Mesh. + */ + Mesh *mesh; + + /** + * elInfo of element. + */ + const ElInfo *elInfo; + + /** + * Pointer to last element processed calculations on whithin this class. + */ + Element *lastEl; + + /** + * Indicator which can be used for example for function evaluation + * or integration on subelements. Indicates whether point/subelement ... + * is inside (LEVEL_SET_INTERIOR) or outside (LEVEL_SET_EXTERIOR) the + * zero level set or is cut by the zero level set (LEVEL_SET_BOUNDARY). + */ + int level_set_domain; + + /** + * Dimension of the problem. dim + 1 is the number of vertices + * of element. + */ + int dim; + + /** + * Vector for intersection points produced by the intersection of linearly + * approximated level set function with the edges of element. + */ + VectorOfFixVecs<DimVec<double> > *elIntersecPoints; + + /** + * Number of intersection points. + */ + int numIntersecPoints; + + /** + * LevelSet-Status of element. + */ + int elStatus; + + /** + * Holds for each vertex of element the information about the position + * of the vertex with respect to the zero level set. + */ + int *elVertexStatusVec; + + /** + * Stores for each vertex of element the level set of the vertex. + */ + double *elVertexLevelSetVec; + + /** + * Number of vertices in element with level set status LEVEL_SET_INTERIOR. + */ + int numElVertexInterior; + + /** + * Number of vertices in element with level set status LEVEL_SET_BOUNDARY. + * + * Note: should be zero + */ + int numElVertexBoundary; + + /** + * Number of vertices in element with level set status LEVEL_SET_EXTERIOR. + */ + int numElVertexExterior; + + /** + * Tolerance used in the calculation of the local minimal level set value. + * The local minimal level set value depends on the gradient of the + * level set function. + * Used for the calculation of intersection points. + * + * If intersection points are too close to vertices, they are slightly + * moved. + * IDEA: If d is the distance of an intersection point to vertex v, + * the property + * + * d > LS_VAL_TOL * h + * + * must be satisfied. + * In the implementation this results in + * + * phi(v) > LS_VAL_TOL * h * grad . + */ + double LS_VAL_TOL; + + /** + * Lower bound for level set value on elements cut by the zero level set. + * Used for the calculation of intersection points. + */ + double LS_VAL_MIN; + + /** + * Lower bound for barycentric coordinates of intersection points. + * + * Each component x of the barycentric coordinates of an intersection + * point satisfies + * + * SP_BARY_TOL < x < 1 - SP_BARY_TOL . + */ + double SP_BARY_TOL; + + /* + * Maximum number of intersection points. + */ + static const int MAX_INTERSECTION_POINTS = 4; +}; + +#endif // AMDIS_ELEMENTLEVELSET_H diff --git a/AMDiS/compositeFEM/src/LevelSetAdaptMesh.cc b/AMDiS/compositeFEM/src/LevelSetAdaptMesh.cc new file mode 100644 index 0000000000000000000000000000000000000000..7fc4dafa7d6f9901b4007d5e958393e413577a02 --- /dev/null +++ b/AMDiS/compositeFEM/src/LevelSetAdaptMesh.cc @@ -0,0 +1,222 @@ +#include "Traverse.h" + +#include "ElementLevelSet.h" +#include "LevelSetAdaptMesh.h" + +void +LevelSetAdaptMesh::adaptMesh(AdaptInfo *adaptInfo) +{ + TraverseStack *stack; + ElInfo *elInfo; + + doRefine = true; + doCoarsen = true; + + // === Process refinement/coarsening until prescribed element sizes are + // reached. + while (doRefine || doCoarsen) { + doRefine = false; + doCoarsen = false; + refinementMarkIsSet = false; + coarseningMarkIsSet = false; + + // === Mark elements for refinement/coarsening. + stack = NEW TraverseStack; + elInfo = stack->traverseFirst(mesh, -1, + Mesh::CALL_LEAF_EL | + Mesh::FILL_NEIGH | + Mesh::FILL_BOUND | + Mesh::FILL_DET | + Mesh::FILL_COORDS); + + while (elInfo) { + + if (bandAtInterf) + markElement_Band(elInfo); + else + markElement_noBand(elInfo); + + elInfo = stack->traverseNext(elInfo); + } + DELETE stack; + + // === Refine/coarsen mesh. + if(refinementMarkIsSet) { + if (prob->refineMesh(adaptInfo) != MESH_REFINED) { + doRefine = false; + } + } + if (coarseningMarkIsSet) { + if(prob->coarsenMesh(adaptInfo) != MESH_COARSENED) { + doCoarsen = false; + } + } + } // end: while (doRefine || doCoarsen) +} + +void +LevelSetAdaptMesh::markElement_noBand(ElInfo *elInfo) +{ + // === Get position of element with respect to the zero level set. + int elStatus = elLS->createElementLevelSet(elInfo, false); + + double elSize = fabs(elInfo->getDet()); + + if (elStatus == ElementLevelSet::LEVEL_SET_BOUNDARY) { + markElement(elInfo, elSize, sizeInterf); + return; + } + + if (!onlyInterfRef) { + if (elStatus == ElementLevelSet::LEVEL_SET_INTERIOR) { + markElement(elInfo, elSize, sizeNegLs); + return; + } + + if (elStatus == ElementLevelSet::LEVEL_SET_EXTERIOR) { + markElement(elInfo, elSize, sizePosLs); + return; + } + } +} + +void +LevelSetAdaptMesh::markElement_Band(ElInfo *elInfo) +{ + // === Get position of element with respect to the band around the + // zero level set. + int elStatusBand = calculateElementStatusBand(elInfo); + + double elSize = fabs(elInfo->getDet()); + + if (elStatusBand == LS_ADAPT_MESH_IN_BAND) { + markElement(elInfo, elSize, sizeInterf); + return; + } + + if (!onlyInterfRef) { + if (elStatusBand == LS_ADAPT_MESH_INTERIOR) { + markElement(elInfo, elSize, sizeNegLs); + return; + } + + if (elStatusBand == LS_ADAPT_MESH_EXTERIOR) { + markElement(elInfo, elSize, sizePosLs); + return; + } + } +} + +void +LevelSetAdaptMesh::markElement(ElInfo *elInfo, + double elSize, + double sizeWanted) +{ + // === After mesh adaption: sizeWanted is an upper bound for element size, + // i.e. if sizeWanted < 2*elSize the element is not coarsened. + + // Mark for refinement. + if (elSize > sizeWanted) { + elInfo->getElement()->setMark(1); + refinementMarkIsSet = true; + + // Is further refinement needed? + if (elSize > 2*sizeWanted) { + doRefine = true; + } + } + + // Mark for coarsening. + if (2*elSize <= sizeWanted) { + elInfo->getElement()->setMark(-1); + coarseningMarkIsSet = true; + + // Is further coarsening needed? + if (4*elSize <= sizeWanted) { + doCoarsen = true; + } + } +} + +int +LevelSetAdaptMesh::calculateElementStatusBand(ElInfo *elInfo) +{ + bool inBand = false; + const double *elVertexLevelSetVec = elLS->getElVertLevelSetVec(); + + // === Get position of element with respect to band around the zero + // level set. + int elStatus = elLS->createElementLevelSet(elInfo, false); + + for (int i=0; i<=dim; ++i) { + if (fabs(elVertexLevelSetVec[i]) < bandSize) { + inBand = true; + break; + } + } + + if (inBand || elStatus == ElementLevelSet::LEVEL_SET_BOUNDARY) { + return LS_ADAPT_MESH_IN_BAND; + } + else if (elStatus == ElementLevelSet::LEVEL_SET_INTERIOR) { + return LS_ADAPT_MESH_INTERIOR; + } + else { + return LS_ADAPT_MESH_EXTERIOR; + } +} + +void +LevelSetAdaptMesh::getElementSizesFromInit(const std::string probName, + double &sizeInterf_, + double &sizeNegLs_, + double &sizePosLs_, + double &bandSize_) +{ + FUNCNAME("LevelSetAdaptMesh::getElementSizesFromInit()"); + + // === Read parameter from file. === + int dim; + GET_PARAMETER(0, probName + "->dim", "%d", &dim); + std::string meshName; + GET_PARAMETER(0, probName + "->mesh", &meshName); + int globalRef=0; + GET_PARAMETER(0, meshName + "->global refinements", + "%d", &globalRef); + + int refInterf=0; + GET_PARAMETER(0, "LevelSetAdaptMesh->additional refinements at interface", + "%d", &refInterf); + int refNegLs=0; + GET_PARAMETER(0, "LevelSetAdaptMesh->additional refinements in negative domain", + "%d", &refNegLs); + int refPosLs=0; + GET_PARAMETER(0, "LevelSetAdaptMesh->additional refinements in positive domain", + "%d", &refPosLs); + + int numElBand=0; + GET_PARAMETER(0, "LevelSetAdaptMesh->number of elements for band", + "%d", &numElBand); + double macroElSize = -1.0; + GET_PARAMETER(0, "LevelSetAdaptMesh->macro element size", + "%f", ¯oElSize); + + // === Calculate element sizes. === + double fac = pow(0.5, 1.0/dim); + + sizeInterf_ = macroElSize * pow(fac, globalRef+refInterf); + sizeNegLs_ = macroElSize * pow(fac, globalRef+refNegLs); + sizePosLs_ = macroElSize * pow(fac, globalRef+refPosLs); + + bandSize_ = numElBand * sizeInterf_; + + sizeInterf_ = pow(sizeInterf_, dim); + sizeNegLs_ = pow(sizeNegLs_, dim); + sizePosLs_ = pow(sizePosLs_, dim); + + + TEST_EXIT(sizeInterf_ >= 0)("illegal sizeInterf !\n"); + TEST_EXIT(sizeNegLs_ >= 0)("illegal sizeNegLs !\n"); + TEST_EXIT(sizePosLs_ >= 0)("illegal sizePosLs !\n"); + TEST_EXIT(bandSize_ >= 0)("illegal bandSize !\n"); +} diff --git a/AMDiS/compositeFEM/src/LevelSetAdaptMesh.h b/AMDiS/compositeFEM/src/LevelSetAdaptMesh.h new file mode 100644 index 0000000000000000000000000000000000000000..3490975a07a2e693aa9a63115e88a98fde30820f --- /dev/null +++ b/AMDiS/compositeFEM/src/LevelSetAdaptMesh.h @@ -0,0 +1,204 @@ +#ifndef AMDIS_LEVELSETADAPTMESH_H +#define AMDIS_LEVELSETADAPTMESH_H + +#include "AdaptInfo.h" +#include "ElInfo.h" +#include "Global.h" +#include "MemoryManager.h" +#include "Mesh.h" +#include "ProblemStatBase.h" + +#include "ElementLevelSet.h" + +using namespace AMDiS; + +class LevelSetAdaptMesh +{ + public: + MEMORY_MANAGED(LevelSetAdaptMesh); + + /** + * Constructor. + */ + LevelSetAdaptMesh(ProblemStatBase *prob_, + Mesh *mesh_, + ElementLevelSet *elLS_, + double sizeInterf_, + double sizeNegLs_, + double sizePosLs_, + bool onlyInterfRef_ = false, + bool bandAtInterf_ = false, + double bandSize_ = -1.0) + : prob(prob_), + mesh(mesh_), + elLS(elLS_), + sizeInterf(sizeInterf_), + sizeNegLs(sizeNegLs_), + sizePosLs(sizePosLs_), + onlyInterfRef(onlyInterfRef_), + bandAtInterf(bandAtInterf_), + bandSize(bandSize_), + dim(mesh->getDim()) + {}; + + /** + * Calculates sizes sizeInterf, sizeNegLs, sizePosLs and bandSize + * from number of refinements additional to initial global refinements + * read from init file. + */ + static void getElementSizesFromInit(const std::string probName, + double &sizeInterf_, + double &sizeNegLs_, + double &sizePosLs_, + double &bandSize_); + + /** + * Sets sizeInterf, sizeNegLs, sizePosLs and bandSize. + */ + void setElementSizes(double &sizeInterf_, + double &sizeNegLs_, + double &sizePosLs_, + double bandSize_ = -1.0) + { + FUNCNAME("LevelSetAdaptMesh::setElementSizes()"); + + sizeInterf = sizeInterf_; + sizeNegLs = sizeNegLs_; + sizePosLs = sizePosLs_; + bandSize = bandSize_; + + TEST_EXIT(bandSize > 0 || bandAtInterf == false) + ("illegal band size!\n"); + }; + + /** + * Sets bandSize. + */ + void setBandSize(double &bandSize_) + { + FUNCNAME("LevelSetAdaptMesh::setBandSize()"); + + TEST_EXIT(bandSize_ > 0)("illegal bandSize !\n"); + + bandAtInterf = true; + bandSize = bandSize_; + }; + + /** + * Adapts mesh to the appropriate element sizes. + */ + void adaptMesh(AdaptInfo *adaptInfo); + + /** + * Get sizeInterf. + */ + inline double getSizeInterf() { + return sizeInterf; + }; + + protected: + /** + * Element mark function in case no band around the interface is used. + */ + void markElement_noBand(ElInfo *elInfo); + + /** + * Element mark function in case a band around the interface is used. + */ + void markElement_Band(ElInfo *elInfo); + + /** + * Checks whether element size elSize corresponds to the prescribed size + * sizeWanted and sets a mark for refinement/coarsening if needed. + */ + void markElement(ElInfo *elInfo, double elSize, double sizeWanted); + + /** + * Determines the position of element with respect to the band around + * the zero level set. + */ + int calculateElementStatusBand(ElInfo *elInfo); + + protected: + /** + * Problem for mesh adaption which gives refinement and coarsening manager. + */ + ProblemStatBase *prob; + + /** + * Mesh to be adapted. + */ + Mesh *mesh; + + /** + * Holds the level set function and functionalities on intersection point + * calculation. + */ + ElementLevelSet *elLS; + + /** + * Mesh element size after mesh adaption. + * sizeInterf - elements cut by zero level set and - if bandAtInterf + * is true - elements with at most distance bandSize to + * the zero level set + * sizeNegLs - elements in domain with negative level set function + * values (and not within band at interface) + * sizePosLs - elements in domain with positive level set function + * values (and not within band at interface) + */ + double sizeInterf; + double sizeNegLs; + double sizePosLs; + + /** + * Indicates whether only interface elements or elements within a + * band around the interface are refined (true) or refinement/coarsening + * on the complete mesh is done (false). + */ + bool onlyInterfRef; + + /** + * Indicates whether band around interface/zero level set is used (true) + * or not (false). + * If band is used, elements with at most distance bandSize to the + * zero level set are refined to size sizeInterf. + */ + bool bandAtInterf; + + /** + * Defines bandwidth if band around interface is used. + */ + double bandSize; + + /** + * Constants to describe the position of an element with respect to a band + * around the interface. + * INTERIOR - in domain with negative level set function values and + * not in band + * IN_BAND - at least on vertex of element has distance smaller than + * bandSize to the zero level set; the absolute value of + * the level set function is taken as the distance to + * the zero level set + * EXTERIOR - in domain with positive level set function values and + * not in band + */ + static const int LS_ADAPT_MESH_INTERIOR = -1; + static const int LS_ADAPT_MESH_IN_BAND = 0; + static const int LS_ADAPT_MESH_EXTERIOR = 1; + + /** + * Dimension of the mesh. + */ + int dim; + + /** + * Variables used in adaptMesh(), markElement_Band() and + * markElement_noBand(). + */ + bool doRefine; + bool doCoarsen; + bool refinementMarkIsSet; + bool coarseningMarkIsSet; +}; + +#endif // AMDIS_LEVELSETADAPTMESH_H diff --git a/AMDiS/compositeFEM/src/PenaltyOperator.cc b/AMDiS/compositeFEM/src/PenaltyOperator.cc new file mode 100644 index 0000000000000000000000000000000000000000..59daa976f9785eaab44d4e71d9ea580a3627b990 --- /dev/null +++ b/AMDiS/compositeFEM/src/PenaltyOperator.cc @@ -0,0 +1,252 @@ +#include "PenaltyOperator.h" + +#include "SurfaceOperator.h" + +double +PenaltyOperator::getPenaltyCoeff(const ElInfo *elInfo) +{ + if (penaltyCoeffFlag) { + eps = pow(fabs(elInfo->getDet()), degree*1.0/dim) * factor; + return 1.0/eps; + } + else { + eps = 1.0; + return 1.0; + } +} + +void +PenaltyOperator::getElementMatrix(const ElInfo *elInfo, + ElementMatrix *userMat, + double factor) +{ + FUNCNAME("PenaltyOperator::getElementMatrix"); + + VectorOfFixVecs<DimVec<double> > *intersecPoints = NULL; + double penaltyCoeff = getPenaltyCoeff(elInfo); + + /** + * Get element status. Does element lie completely inside the integration + * domain, completely outside of the integration domain or is it + * intersected by the boundary ? + */ + elStatus = elLS->createElementLevelSet(elInfo); + + /** + * element status == completely inside or outside + * ---> penalty term does not + * depend on this element; + * no integration has to + * be done + * + * element status == lies on boundary ---> surface integration on boundary + */ + if (elStatus == ElementLevelSet::LEVEL_SET_BOUNDARY) { + + /** + * Get intersection points. + */ + intersecPoints = elLS->getElIntersecPoints(); + + /** + * Create SurfaceOperator and calculate element matrix. + */ + if (dim == 3 && elLS->getNumElIntersecPoints() == 4) { + + /** + * Intersection plane must be divided into two simplices. + * + * Note: The intersection points S0, S1, S2, S3 are supposed to be + * alligned in such a manner that a line through S1 and S2 + * divides the intersection plane. + */ + + // Treat first simplex. + (*tempCoords)[0] = (*intersecPoints)[0]; + (*tempCoords)[1] = (*intersecPoints)[1]; + (*tempCoords)[2] = (*intersecPoints)[2]; + if (!surfaceOp) { + surfaceOp = NEW SurfaceOperator(this, (*tempCoords)); + } + else { + surfaceOp->adaptSurfaceOperator((*tempCoords)); + } + surfaceOp->getElementMatrix(elInfo, userMat, factor*penaltyCoeff); + + // Treat second simplex. + (*tempCoords)[0] = (*intersecPoints)[3]; + surfaceOp->adaptSurfaceOperator((*tempCoords)); + surfaceOp->getElementMatrix(elInfo, userMat, factor*penaltyCoeff); + } + + else { + + /** + * Intersection points form a simplex. + */ + + // *intersecPoints always has MAX_INTERSECTION_POINTS entries + (*tempCoords)[0] = (*intersecPoints)[0]; + if (dim > 1) + (*tempCoords)[1] = (*intersecPoints)[1]; + if (dim == 3) { + (*tempCoords)[2] = (*intersecPoints)[2]; + } + + if (!surfaceOp) { + surfaceOp = NEW SurfaceOperator(this, *tempCoords); + } + else { + surfaceOp->adaptSurfaceOperator(*tempCoords); + } + surfaceOp->getElementMatrix(elInfo, userMat, factor*penaltyCoeff); + } + + } // if (elstatus == LEVEL_SET_BOUNDARY) + +// else if (dim == 1 && ElementLevelSet::getNumVertIntPoints() != 0) { + +// // ===== intersection points are element vertices ===== +// DimVec<double> lambda(dim, DEFAULT_VALUE, 0.0); +// const int *statusVec = ElementLevelSet::getElVertStatusVec(); + +// for (int i=0; i<dim; ++i) { + +// if (statusVec[i] == ElementLevelSet::LEVEL_SET_BOUNDARY) { +// lambda[i] = 1.0; +// (*tempCoords)[0] = lambda; + +// if (!surfaceOp) { +// surfaceOp = NEW SurfaceOperator(this, *tempCoords); +// } +// else { +// surfaceOp->adaptSurfaceOperator(*tempCoords); +// } +// surfaceOp->getElementMatrix(elInfo, userMat, factor*penaltyCoeff); + +// lambda[i] = 0.0; +// } +// } + +// } + + return; +} + +void +PenaltyOperator::getElementVector(const ElInfo *elInfo, + ElementVector *userVec, + double factor) +{ + FUNCNAME("PenaltyOperator::getElementVector"); + + VectorOfFixVecs<DimVec<double> > *intersecPoints = NULL; + double penaltyCoeff = getPenaltyCoeff(elInfo); + + /** + * Get element status. Does element lie completely inside the integration + * domain, completely outside of the integration domain or is it + * intersected by the boundary ? + */ + elStatus = elLS->createElementLevelSet(elInfo); + + /** + * element status == completely inside or outside + * ---> penalty term does not + * depend on this element; + * no integration has to + * be done + * + * element status == lies on boundary ---> surface integration on boundary + */ + if (elStatus == ElementLevelSet::LEVEL_SET_BOUNDARY) { + + /** + * Get intersection points. + */ + intersecPoints = elLS->getElIntersecPoints(); + + /** + * Create SurfaceOperator and calculate element vector. + */ + if (dim == 3 && elLS->getNumElIntersecPoints() == 4) { + + /** + * Intersection plane must be divided into two simplices. + * + * Note: The intersection points S0, S1, S2, S3 are supposed to be + * alligned in such a manner that a line through S1 and S2 + * divides the intersection plane. + */ + + // Treat first simplex. + (*tempCoords)[0] = (*intersecPoints)[0]; + (*tempCoords)[1] = (*intersecPoints)[1]; + (*tempCoords)[2] = (*intersecPoints)[2]; + if (!surfaceOp) { + surfaceOp = NEW SurfaceOperator(this, (*tempCoords)); + } + else { + surfaceOp->adaptSurfaceOperator((*tempCoords)); + } + surfaceOp->getElementVector(elInfo, userVec, factor*penaltyCoeff); + + // Treat second simplex. + (*tempCoords)[0] = (*intersecPoints)[3]; + surfaceOp->adaptSurfaceOperator((*tempCoords)); + surfaceOp->getElementVector(elInfo, userVec, factor*penaltyCoeff); + } + + else { + + /** + * Intersection points form a simplex. + */ + + // *intersecPoints always has MAX_INTERSECTION_POINTS entries + (*tempCoords)[0] = (*intersecPoints)[0]; + if (dim > 1) + (*tempCoords)[1] = (*intersecPoints)[1]; + if (dim == 3) { + (*tempCoords)[2] = (*intersecPoints)[2]; + } + + if (!surfaceOp) { + surfaceOp = NEW SurfaceOperator(this, *tempCoords); + } + else { + surfaceOp->adaptSurfaceOperator(*tempCoords); + } + surfaceOp->getElementVector(elInfo, userVec, factor*penaltyCoeff); + } + + } // if (elstatus == LEVEL_SET_BOUNDARY) + +// else if (dim == 1 && ElementLevelSet::getNumVertIntPoints() != 0) { + +// // ===== intersection points are element vertices ===== +// DimVec<double> lambda(dim, DEFAULT_VALUE, 0.0); +// const int *statusVec = ElementLevelSet::getElVertStatusVec(); + +// for (int i=0; i<dim; ++i) { + +// if (statusVec[i] == ElementLevelSet::LEVEL_SET_BOUNDARY) { +// lambda[i] = 1.0; +// (*tempCoords)[0] = lambda; + +// if (!surfaceOp) { +// surfaceOp = NEW SurfaceOperator(this, *tempCoords); +// } +// else { +// surfaceOp->adaptSurfaceOperator(*tempCoords); +// } +// surfaceOp->getElementVector(elInfo, userVec, factor*penaltyCoeff); + +// lambda[i] = 0.0; +// } +// } + +// } + + return; +} diff --git a/AMDiS/compositeFEM/src/PenaltyOperator.h b/AMDiS/compositeFEM/src/PenaltyOperator.h new file mode 100644 index 0000000000000000000000000000000000000000..a9de2fe556f9e2dadf459c9cfe653e31eacb9a7c --- /dev/null +++ b/AMDiS/compositeFEM/src/PenaltyOperator.h @@ -0,0 +1,153 @@ +/** \file PenaltyOperator.h */ + +#ifndef AMDIS_PENALTYOPERATOR_H +#define AMDIS_PENALTYOPERATOR_H + +#include "ElementLevelSet.h" +#include "Flag.h" +#include "MemoryManager.h" +#include "Operator.h" +#include "SurfaceOperator.h" + +#include "ElementLevelSet.h" + +namespace AMDiS { + class ElInfo; + class FiniteElemSpace; +} + +using namespace AMDiS; +using namespace std; + +// =========================================================================== +// ===== class PenaltyOperator =============================================== +// =========================================================================== +// +// Class Description: +// +// =========================================================================== +class PenaltyOperator : public Operator +{ +public: + MEMORY_MANAGED(PenaltyOperator); + /** + * Constructor. + */ + PenaltyOperator(Flag operatorType_, + ElementLevelSet *elLS_, + double factor_, + bool penaltyCoeffFlag_, + FiniteElemSpace *rowFESpace_, + FiniteElemSpace *colFESpace_ = NULL) + : Operator(operatorType_, rowFESpace_, colFESpace_), + elLS(elLS_), + elStatus(ElementLevelSet::LEVEL_SET_UNDEFINED), + factor(factor_), + penaltyCoeffFlag(penaltyCoeffFlag_), + surfaceOp(NULL), + dim(getRowFESpace()->getMesh()->getDim()), + degree(getRowFESpace()->getBasisFcts()->getDegree()) + { + TEST_EXIT(elLS->getLevelSetFct() && elLS->getMesh()) + ("ElementLevelSet not initialized!\n"); + + tempCoords = NEW VectorOfFixVecs<DimVec<double> >(dim, dim, NO_INIT); + }; + + /** + * Destructor. + */ + ~PenaltyOperator() + { + if (surfaceOp) { + DELETE surfaceOp; + } +/* if (dim == 3) { */ + DELETE tempCoords; +/* } */ + }; + + /** + * Calculates the element matrix for this ElInfo and adds it multiplied by + * factor to userMat. + * In addition to \ref Operator::getElementMatrix(), it distinguishes + * between elements divided by the boundary (level set zero intersects the + * element) and elements lying completely inside or outside the integration + * domain. + */ + void getElementMatrix(const ElInfo *elInfo, + ElementMatrix *userMat, + double factor = 1.0); + + /** + * Calculates the element vector for this ElInfo and adds it multiplied by + * factor to userVec. + * Similar to \ref getElementMatrix it distinguishes between elements + * divided by the boundary and elements lying completely inside or outside + * the integration domain. + */ + void getElementVector(const ElInfo *elInfo, + ElementVector *userVec, + double factor = 1.0); + +protected: + + /** + * Calculate coefficient of the penalty term. + */ + double getPenaltyCoeff(const ElInfo *elInfo); + + protected: + /** + * Holds level set function and functionalities for intersection point + * calculation. + */ + ElementLevelSet *elLS; + + /** + * Indicator for the position of an element. It shows whether an element + * lies inside the integration domain, outside of the integration domain + * or on the boundary. + */ + int elStatus; + + /** + * Coefficient of the penalty term is 1/eps. eps depends on the size of + * element and on factor. + */ + double eps; + + /** + * Factor needed for eps. + */ + double factor; + + /** + * Flag to indicate whether to use penalty coefficient. + * true - use penalty coefficient + * false - do not use + */ + bool penaltyCoeffFlag; + + /** + * Surface operator for surface integration + */ + SurfaceOperator *surfaceOp; + + /** + * Problem Dimension. + */ + int dim; + + /** + * Degree of basis functions. + */ + int degree; + + /** + * Variables used for calculation. + */ + VectorOfFixVecs<DimVec<double> > *tempCoords; +}; + +#endif // AMDIS_PENALTYOPERATOR_H diff --git a/AMDiS/compositeFEM/src/ScalableQuadrature.cc b/AMDiS/compositeFEM/src/ScalableQuadrature.cc new file mode 100644 index 0000000000000000000000000000000000000000..38e31970ba105b45905cc4dbdd8974a27fe7d7ee --- /dev/null +++ b/AMDiS/compositeFEM/src/ScalableQuadrature.cc @@ -0,0 +1,56 @@ +#include "ScalableQuadrature.h" +#include "SubElInfo.h" + +ScalableQuadrature::ScalableQuadrature(Quadrature *quadrature) + : Quadrature(*quadrature) +{ + /** + * Change name of quadrature. + */ + name = "Scalable" + getName(); + + /** + * copy quadrature->lambda to oldLambda + */ + oldLambda = NEW VectorOfFixVecs<DimVec<double> >(*(quadrature->getLambda())); +} + +void +ScalableQuadrature::scaleQuadrature(const SubElInfo& subElInfo) +{ + //****************************************************************************** + // Manipulates the quadrature points for the assemblage of a subelement. + // A quadrature point for the assemblage of the subelement is then given in + // barycentric coordinates with respect to the element containing the + // subelement. + // Thus the assemblage of the subelement is done by assembling the element + // using the quadrature with manipulated quadrature points. + // Note: The result must be corrected by the determinant of the subelement !!! + //****************************************************************************** + int iq, i, j; + double l; + + /** + * If (l_0, l_1, l_2) is the old quadrature point and x_0, x_1, x_2 are the + * barycentric coordinates of the vertices of the subelement, the new quadrature + * point (n_0, n_1, n_2) is given as follows: + * (n_0, n_1, n_2) = l_0 * x_0 + l_1 * x_1 + l_2 * x_2 . + */ + for (iq = 0; iq < n_points; iq++) { + + for (i = 0; i <= dim; i++) { + + /** + * Calculate the i-th component of the iq-th new quadrature point. + */ + l = 0.0; + + for (j = 0; j <= dim; j++) { + l += getOldLambda(iq, j) * subElInfo.getLambda(j, i); + } + + (*lambda)[iq][i] = l; + } + } +} + diff --git a/AMDiS/compositeFEM/src/ScalableQuadrature.h b/AMDiS/compositeFEM/src/ScalableQuadrature.h new file mode 100644 index 0000000000000000000000000000000000000000..4f1fea012f55497d42c86bfae7380b91f1b31c99 --- /dev/null +++ b/AMDiS/compositeFEM/src/ScalableQuadrature.h @@ -0,0 +1,82 @@ +/** \file ScalableQuadrature.h */ + +#ifndef AMDIS_SCALABLEQUADRATURE_H +#define AMDIS_SCALABLEQUADRATURE_H + +#include "MemoryManager.h" +#include "Quadrature.h" +#include "FixVec.h" + +class SubElInfo; + +using namespace AMDiS; +using namespace std; + +// =============================================================================== +// ===== class ScalableQuadrature ================================================ +// =============================================================================== +// +// Class Description: +// The class \ref ScalableQuadrature holds the functionality for the manipulation +// of a quadrature formula used for the integration on subelements. +// If S' is a sublement and S the element containing S', the numerical integration +// on S' is done by integration on the element S with a manipulated quadrature +// formula and multiplication of the result with a correction term consisting of +// the determinants corresponding to S and S'. That means, the quadrature points +// are manipulated in the following way: +// The original quadrature formula holds quadrature points which are given in +// barycentric coordinates with respect to S'. Now we express these quadrature +// points in barycentric coordinates with respect to S and obtain the manipulated +// quadrature points we need. Obviously, the corresponding quadrature points +// in world coordinates coincide. Thus the numerical integration on S with the +// manipulated quadrature formula gives us the same result as the numerical +// integration on S' with the original quadrature formula up to the determinant. +// This method for integration on subelements allows the reuse of the routines for +// the integration on elements. +// +// Main routines: +// ScalableQuadrature() - Create a new quadrature formula which is a copy of the +// original quadrature formula and store the original +// quadrature points in \ref oldLambda. +// scaleQuadrature() - Manipulate the original quadrature formula for a +// subelement. +// =============================================================================== +class ScalableQuadrature : public Quadrature +{ +public: + MEMORY_MANAGED(ScalableQuadrature); + + /** + * Constructor + */ + ScalableQuadrature(Quadrature *quadrature); + + /** + * Destructor + */ + ~ScalableQuadrature() + { + DELETE oldLambda; + } + + /** + * Manipulates the quadrature points for the assemblage of a subelement. + */ + void scaleQuadrature(const SubElInfo& subElInfo); + + /** + * Get b-th coordinate of the a-th original quadrature point. + */ + inline const double getOldLambda(int a,int b) const { + if (oldLambda) return (*oldLambda)[a][b]; + else return 0.0; + }; + +protected: + /** + * Original quadrature points. + */ + VectorOfFixVecs<DimVec<double> > *oldLambda; +}; + +#endif // AMDIS_SCALABLEQUADRATURE_H diff --git a/AMDiS/compositeFEM/src/SubElInfo.cc b/AMDiS/compositeFEM/src/SubElInfo.cc new file mode 100644 index 0000000000000000000000000000000000000000..876ed8a4fcf80c2a59e7387d9d993f1f780bed54 --- /dev/null +++ b/AMDiS/compositeFEM/src/SubElInfo.cc @@ -0,0 +1,35 @@ +#include "SubElInfo.h" +#include "ElInfo.h" +#include "Mesh.h" + +SubElInfo::SubElInfo(VectorOfFixVecs<DimVec<double> > *lambda_, + const ElInfo *elInfo_) + : elInfo(elInfo_) +{ + FUNCNAME("SubElInfo::SubElInfo"); + + int numPoints = lambda_->getSize(); + int dim = elInfo_->getMesh()->getDim(); + int i; + + TEST_EXIT(numPoints == dim+1)("invalid number of vertices of subelement\n"); + + FixVec<WorldVector<double>, VERTEX> worldCoords(dim, NO_INIT); + + lambda = NEW VectorOfFixVecs<DimVec<double> >(dim, dim+1, NO_INIT); + for (i = 0; i <= dim; i++) { + (*lambda)[i] = (*lambda_)[i]; + } + + /** + * Get worldcoordinates of the vertices of subelement in order to + * calculate the corresponding determinant. + */ + for (i = 0; i < numPoints; i++) { + elInfo->coordToWorld((const DimVec<double>)((*lambda)[i]), + &(worldCoords[i])); + } + + det = ElInfo::calcDet(worldCoords); +} + diff --git a/AMDiS/compositeFEM/src/SubElInfo.h b/AMDiS/compositeFEM/src/SubElInfo.h new file mode 100644 index 0000000000000000000000000000000000000000..acacdf360b1536a5a00e40c774b450eebc588d67 --- /dev/null +++ b/AMDiS/compositeFEM/src/SubElInfo.h @@ -0,0 +1,98 @@ +/** \file SubElInfo.h */ + +#ifndef AMDIS_SUBELINFO_H +#define AMDIS_SUBELINFO_H + +#include "MemoryManager.h" +#include "FixVec.h" + +namespace AMDiS { + class ElInfo; +} + +using namespace AMDiS; +using namespace std; + +// ============================================================================ +// ===== class SubElInfo ====================================================== +// ============================================================================ +// +// Class description: +// The class \ref SubElInfo holds all information on a subelement (element to +// which it belongs, its vertices in barycentric coordinates with respect to +// the element, corresponding determinant, ...). +// +// Main routines: +// SubElInfo() - Creates a \ref SubElInfo for a subelement of the element +// \ref elInfo. The vertices of the subelement given in +// barycentric coordinates with respect to element are handed over +// to this routine. The determinant corresponding to subelement +// is calculated. +// ============================================================================ +class SubElInfo +{ +public: + MEMORY_MANAGED(SubElInfo); + + /** + * Constructor + */ + SubElInfo(VectorOfFixVecs<DimVec<double> > *lambda_, + const ElInfo *elInfo_); + + /** + * Destructor. + */ + ~SubElInfo() + { + DELETE lambda; + }; + /** + * Get b-th coordinate of the a-th vertex of subelement (barycentric + * coordinates). + */ + inline const double getLambda(int a,int b) const { + if (lambda) return (*lambda)[a][b]; + else return 0.0; + }; + + /** + * Get coordinates of a-th vertex of subelement (barycentric coordinates). + */ + inline const DimVec<double>& getLambda(int a) const { + return (*lambda)[a]; + }; + + /** + * Get coordinates of all vertices of subelement (barycentric coordinates). + */ + inline VectorOfFixVecs<DimVec<double> > *getLambda() const { + return lambda; + }; + + /** + * Get determinant corresponding to subelement. + */ + inline const double getDet() const { + return det; + }; + +protected: + + /** + * Contains elInfo of the element that contains subelement. + */ + const ElInfo *elInfo; + + /** + * Barycentrc coordinates of the vertices of subelement. + */ + VectorOfFixVecs<DimVec<double> > *lambda; + + /** + * Determinant corresponding to the (World-)subelement. + */ + double det; +}; + +#endif // AMDIS_SUBELINFO_H diff --git a/AMDiS/compositeFEM/src/SubElementAssembler.cc b/AMDiS/compositeFEM/src/SubElementAssembler.cc new file mode 100644 index 0000000000000000000000000000000000000000..810d45230146f2987d16fcc1bfc8ed143d75214a --- /dev/null +++ b/AMDiS/compositeFEM/src/SubElementAssembler.cc @@ -0,0 +1,199 @@ +#include <vector> +#include "ElementMatrix.h" +#include "ElementVector.h" +#include "SubElementAssembler.h" +#include "ScalableQuadrature.h" +#include "SubPolytope.h" + +SubElementAssembler::SubElementAssembler(Operator *op, + const FiniteElemSpace *rowFESpace_, + const FiniteElemSpace *colFESpace_) + : StandardAssembler(op, NULL, NULL, NULL, NULL, rowFESpace_, colFESpace_) +{ + /** + * Create a scalable quadrature for subassembler and replace the original + * quadrature of the subassembler with the scalable quadrature. + */ + + if (zeroOrderAssembler) { + checkQuadratures(); + zeroOrderScalableQuadrature = + NEW ScalableQuadrature(zeroOrderAssembler->getQuadrature()); + zeroOrderAssembler->setQuadrature(zeroOrderScalableQuadrature); + } + else { + zeroOrderScalableQuadrature = NULL; + } + + if (firstOrderAssemblerGrdPsi) { + checkQuadratures(); + firstOrderGrdPsiScalableQuadrature = + NEW ScalableQuadrature(firstOrderAssemblerGrdPsi->getQuadrature()); + firstOrderAssemblerGrdPsi->setQuadrature(firstOrderGrdPsiScalableQuadrature); + } + else { + firstOrderGrdPsiScalableQuadrature = NULL; + } + + if (firstOrderAssemblerGrdPhi) { + checkQuadratures(); + firstOrderGrdPhiScalableQuadrature = + NEW ScalableQuadrature(firstOrderAssemblerGrdPhi->getQuadrature()); + firstOrderAssemblerGrdPhi->setQuadrature(firstOrderGrdPhiScalableQuadrature); + } + else { + firstOrderGrdPhiScalableQuadrature = NULL; + } + + if (secondOrderAssembler) { + checkQuadratures(); + secondOrderScalableQuadrature = + NEW ScalableQuadrature(secondOrderAssembler->getQuadrature()); + secondOrderAssembler->setQuadrature(secondOrderScalableQuadrature); + } + else { + secondOrderScalableQuadrature = NULL; + } +} + +void +SubElementAssembler::scaleQuadratures(const SubElInfo& subElInfo) +{ + if (zeroOrderAssembler) { + zeroOrderScalableQuadrature->scaleQuadrature(subElInfo); + } + if (firstOrderAssemblerGrdPsi) { + firstOrderGrdPsiScalableQuadrature->scaleQuadrature(subElInfo); + } + if (firstOrderAssemblerGrdPhi) { + firstOrderGrdPhiScalableQuadrature->scaleQuadrature(subElInfo); + } + if (secondOrderAssembler) { + secondOrderScalableQuadrature->scaleQuadrature(subElInfo); + } +} + +void +SubElementAssembler::getSubElementVector(SubElInfo *subElInfo, + const ElInfo *elInfo, + ElementVector *userVec) +{ + double corrFactor; + + /** + * Manipulate the quadratures of the SubAssemblers for subelement. + */ + scaleQuadratures(*subElInfo); + + calculateElementVector(elInfo, userVec); + + /** + * The integration has been performed with a quadrature living on element. The + * determinant of element has been used instead of the determinant of subelement. Thus + * the result must be corrected with respect to subelement. + */ + corrFactor = subElInfo->getDet() / fabs(elInfo->getDet()); + int i; + for ( i = 0; i < nRow; i++) { + (*userVec)[i] *= corrFactor; + } +} + +void +SubElementAssembler::getSubElementMatrix(SubElInfo *subElInfo, + const ElInfo *elInfo, + ElementMatrix *userMat) +{ + double corrFactor; + + /** + * Manipulate the quadratures of the SubAssemblers for subelement. + */ + scaleQuadratures(*subElInfo); + + /** + * Integrate using the manipulated quadrature. + */ + calculateElementMatrix(elInfo, userMat); + + /** + * The integration has been performed with a quadrature living on element. The + * determinant of element has been used instead of the determinant of subelement. + * Thus the result must be corrected with respect to subelement. + */ + corrFactor = subElInfo->getDet() / fabs(elInfo->getDet()); + int i, j; + for ( i = 0; i < nRow; i++) { + for ( j = 0; j < nCol; j++) { + (*userMat)[i][j] *= corrFactor; + } + } +} + +void +SubElementAssembler::getSubPolytopeVector(SubPolytope *subPolytope, + SubElementAssembler *subElementAssembler, + const ElInfo *elInfo, + ElementVector *subPolVec) +{ + /** + * Note: There is no reset of subPolVec. + */ + std::vector<SubElInfo *>::iterator it; + ElementVector *subElVec = NEW ElementVector(nRow); + int i; + + /** + * Assemble for each subelement of subpolytope. + */ + for (it = subPolytope->getSubElementsBegin(); + it != subPolytope->getSubElementsEnd(); + it++) { + subElVec->set(0.0); + subElementAssembler->getSubElementVector(*it, elInfo, subElVec); + + /** + * Add results for subelement to total result for subpolytope. + */ + for(i = 0; i < nRow; i++) { + (*subPolVec)[i] += (*subElVec)[i]; + } + } + + DELETE subElVec; +} + +void +SubElementAssembler::getSubPolytopeMatrix(SubPolytope *subPolytope, + SubElementAssembler *subElementAssembler, + const ElInfo *elInfo, + ElementMatrix *subPolMat) +{ + /** + * Note: There is no reset of subPolMat. + */ + std::vector<SubElInfo *>::iterator it; + ElementMatrix *subElMat = NEW ElementMatrix(nRow, nCol); + int i,j; + + /** + * Assemble for each subelement of subpolytope. + */ + for (it = subPolytope->getSubElementsBegin(); + it != subPolytope->getSubElementsEnd(); + it++) { + subElMat->set(0.0); + subElementAssembler->getSubElementMatrix(*it, elInfo, subElMat); + + /** + * Add results for subelement to total result for subpolytope. + */ + for(i = 0; i < nRow; i++) { + for(j = 0; j < nCol; j++) { + (*subPolMat)[i][j] += (*subElMat)[i][j]; + } + } + } + + DELETE subElMat; +} diff --git a/AMDiS/compositeFEM/src/SubElementAssembler.h b/AMDiS/compositeFEM/src/SubElementAssembler.h new file mode 100644 index 0000000000000000000000000000000000000000..2d995e127fb171d42da7ede840ad1fab489dd5f1 --- /dev/null +++ b/AMDiS/compositeFEM/src/SubElementAssembler.h @@ -0,0 +1,104 @@ +/** \file SubElementAssembler.h */ + +#ifndef AMDIS_SUBELEMENTASSEMBLER_H +#define AMDIS_SUBELEMENTASSEMBLER_H + +#include "MemoryManager.h" +#include "Assembler.h" +#include "SubElInfo.h" + +#include "ScalableQuadrature.h" + +class SubPolytope; + +using namespace AMDiS; +using namespace std; + +// ============================================================================ +// ===== class SubElementAssembler ============================================ +// ============================================================================ +// +// Class Desription: +// The class \ref SubElementAssembler holds the routines for the assemblage on +// subpolytopes and subelements. +// The integration on a subpolytope takes place by integrating on the +// subelements and afterwards summing up the results. +// If S' is a sublement and S the element containing S', the numerical integration +// on S' is done by integration on the element S with a manipulated quadrature +// formula and multiplication of the result with a correction term consisting of +// the determinants corresponding to S and S'. That means, the quadrature points +// are manipulated in the following way: +// The original quadrature formula holds quadrature points which are given in +// barycentric coordinates with respect to S'. Now we express these quadrature +// points in barycentric coordinates with respect to S and obtain the manipulated +// quadrature points we need. Obviously, the corresponding quadrature points +// in world coordinates coincide. Thus the numerical integration on S with the +// manipulated quadrature formula gives us the same result as the numerical +// integration on S' with the original quadrature formula up to the determinant. +// This method for integration on subelements allows the reuse of the routines for +// the integration on elements. +// +// The manipulation of the quadrature formula takes place for the corresponding +// assembler type (ZeroOrderAssembler, FirstOrderAssemblerGrdPsi, ...). +// +// Main routines: +// SubElementAssembler() - Creates a scalable quadrature for the appropriate +// assembler type and assigns this quadrature to the +// assembler. +// scaleQuadratures() - Manipulates the scalable quadrature of the +// appropriate assembler type with respect to a +// subelement. +// getSubPolytopeVector() - Calculates the righthandside vector for a polytope. +// getSubPolytopeMatrix() - Calculates the system matrix for a polytope. +// getSubElementVector() - Calculates the righthandside vector for a subelement. +// getSubElementMatrix() - Calculates the system matrix for a subelement. +// ============================================================================ +class SubElementAssembler : public StandardAssembler +{ + public: + MEMORY_MANAGED(SubElementAssembler); + + SubElementAssembler(Operator *op, + const FiniteElemSpace *rowFESpace_, + const FiniteElemSpace *colFESpace_=NULL); + + virtual ~SubElementAssembler() + { + if (zeroOrderScalableQuadrature) + DELETE zeroOrderScalableQuadrature; + if (firstOrderGrdPsiScalableQuadrature) + DELETE firstOrderGrdPsiScalableQuadrature; + if (firstOrderGrdPhiScalableQuadrature) + DELETE firstOrderGrdPhiScalableQuadrature; + if (secondOrderScalableQuadrature) + DELETE secondOrderScalableQuadrature; + }; + + void scaleQuadratures(const SubElInfo& subElInfo); + + void getSubElementVector(SubElInfo *subElInfo, + const ElInfo *elInfo, + ElementVector *userVec); + + void getSubElementMatrix(SubElInfo *subElInfo, + const ElInfo *elInfo, + ElementMatrix *userMat); + + void getSubPolytopeVector(SubPolytope *subPolytope, + SubElementAssembler *subElementAssembler, + const ElInfo *elInfo, + ElementVector *userVec); + + void getSubPolytopeMatrix(SubPolytope *subPolytope, + SubElementAssembler *subElementAssembler, + const ElInfo *elInfo, + ElementMatrix *userMat); + +protected: + ScalableQuadrature *zeroOrderScalableQuadrature; + ScalableQuadrature *firstOrderGrdPsiScalableQuadrature; + ScalableQuadrature *firstOrderGrdPhiScalableQuadrature; + ScalableQuadrature *secondOrderScalableQuadrature; +}; + +#endif // AMDIS_SUBELEMENTASSEMBLER_H diff --git a/AMDiS/compositeFEM/src/SubPolytope.cc b/AMDiS/compositeFEM/src/SubPolytope.cc new file mode 100644 index 0000000000000000000000000000000000000000..dca19c6bf8f72f81528661b8a8386237fb849987 --- /dev/null +++ b/AMDiS/compositeFEM/src/SubPolytope.cc @@ -0,0 +1,494 @@ +#include "ElInfo.h" +#include "FixVec.h" +#include "SubElInfo.h" +#include "SubPolytope.h" + +bool +SubPolytope::checkIntPoints() +{ + //////////////////////////////////////////////////////////////////////////// + // + // Do the points in intPoints lie on edges ? And are they inner points, + // i.e. they aren't vertices ? + // + // Return value: true - yes + // false - no + //////////////////////////////////////////////////////////////////////////// + + int i,j; + int zeroCounter; + + for (i = 0; i < numIntPoints; i++) { + zeroCounter = 0; + for (j = 0; j < dim+1; j++) { + if ( fabs((*intPoints)[i][j]) <= 1.e-15 ) { zeroCounter++; } + } + + /** + * Dimension 1 + * + * "Inner" points on edges aren't equal to 0.0 in any component. + */ + if ( dim == 1 && zeroCounter != 0 ) { return false; } + + /** + * Dimension 2 + * + * "Inner" points on edges are equal to 0.0 in exactly 1 component. + */ + if ( dim == 2 && zeroCounter != 1 ) { return false; } + + /** + * Dimension 3 + * + * "Inner" points on edges are equal to 0.0 in exactly 2 components. + */ + if ( dim == 3 && zeroCounter != 2 ) { return false; } + } + + return true; +} + +SubPolytope::SubPolytope(const ElInfo *elInfo_, + VectorOfFixVecs<DimVec<double> > *intPoints_, + int numIntPoints_, + const int &indexElVertInPol_) + : elInfo(elInfo_), + intPoints(intPoints_), + numIntPoints(numIntPoints_) +{ + FUNCNAME("SubPolytope::SubPolytope"); + + dim = (*intPoints_)[0].getSize() - 1; + + TEST_EXIT((dim == 1 && numIntPoints == 1) || + (dim == 2 && numIntPoints == 2) || + (dim == 3 && numIntPoints == 3) || + (dim == 3 && numIntPoints == 4)) + ("invalid number of intersection points\n"); + + /** + * Check whether the points in intPoints are really intersection points, + * i.e. lie on edges. + */ + TEST_EXIT(checkIntPoints() == true) + ("invalid intersection points - do not lie on edges\n"); + + /* + * Create the subelements the polytope consists of. + */ + switch ( dim ) { + case 1: + createSubElementPolytopeIsSubElement1D(indexElVertInPol_); + break; + case 2: + createSubElementPolytopeIsSubElement2D3D(); + break; + case 3: + if (numIntPoints == 3) { + createSubElementPolytopeIsSubElement2D3D(); + } + else { + createSubElementsForPolytope3D(indexElVertInPol_); + } + break; + default: + ERROR_EXIT("invalid dimension\n"); + break; + } +} + +void +SubPolytope::createSubElementPolytopeIsSubElement1D(int indexElVertInPol) +{ + //************************************************************************** + // The intersection of the one-dimensional element (interval) divides + // element into two subelements. indexElVertInPol indicates which + // subelement to take. + //************************************************************************** + + FUNCNAME("SubPolytope::createSubElementPolytopeIsSubElement1D"); + + TEST_EXIT(dim == 1 && numIntPoints == 1)("invalid call of this routine\n"); + + VectorOfFixVecs<DimVec<double> > *subElVertices = + NEW VectorOfFixVecs<DimVec<double> >(dim, dim+1, NO_INIT); + DimVec<double> vertex(dim, DEFAULT_VALUE, 1.0); + + /** + * Get the vertex which - with the intersection point in intPoints - forms + * a subelement of element. + */ + if (indexElVertInPol == 0) { + /** + * The vertex in element with barycentric coordinates (1,0) is in + * subelement. + */ + vertex[1] = 0.0; + } + else { + /** + * The vertex in element with barycentric coordinates (0,1) is in + * subelement. + */ + vertex[0] = 0.0; + } + + /** + * Collect the vertices of the subelement in subElVertices. + * + * Note: The routines CompositeFEMOperator::getElementMatrix and + * CompositeFEMOperator::getElementVector expect the first vertice + * of a subelement to be a vertice of the corresponding element and + * not to be an intersection point. + */ + (*subElVertices)[0] = vertex; + (*subElVertices)[dim] = (*intPoints)[0]; + + + /** + * Create a new ElInfo for the subelement. + */ + subElements.push_back( NEW SubElInfo(subElVertices, elInfo) ); + + TEST_EXIT( subElements.size() == 1 )("error in creating subelements"); + numSubElements = 1; + + DELETE subElVertices; +} + + +void +SubPolytope::createSubElementPolytopeIsSubElement2D3D() +{ + //************************************************************************** + // The intersection with element produced dim intersection points. + // Thus there is exactly one vertice in element which - with the + // intersection points - forms a subelement of element. + // This routine determines this vertex and creates a new object of SubElInfo + // for the subelement stored in subElements. + // + // How does it work ? + // All intersection points lie on edges of element and aren't vertices. The + // missing vertex is the intersection point of these edges. + // Lying on edges means, that each intersection point has exactly one + // component equal to 0.0. The missing vertex is equal to 0.0 in all these + // components. + //************************************************************************** + + FUNCNAME("SubPolytope::createSubElementPolytopeIsSubElement2D3D"); + + TEST_EXIT((dim == 2 && numIntPoints == 2) || + (dim == 3 && numIntPoints == 3)) + ("invalid call of this routine\n"); + + VectorOfFixVecs<DimVec<double> >*subElVertices = + NEW VectorOfFixVecs<DimVec<double> >(dim, dim+1, NO_INIT); + DimVec<double> vertex(dim, DEFAULT_VALUE, 1.0); + + /** + * Get the vertex which - with the intersection points intPoints - forms + * a subelement of element. + */ + int i,j; + for (i = 0; i < numIntPoints; i++) { + for (j = 0; j < dim+1; j++) { + if ( fabs((*intPoints)[i][j]) <= 1.e-15 ) { vertex[j] = 0.0; }; + } + } + + /** + * Collect the vertices of the subelement in subElVertices. + * + * Note: The routines CompositeFEMOperator::getElementMatrix and + * CompositeFEMOperator::getElementVector expect the first vertice + * of a subelement to be a vertice of the corresponding element and + * not to be an intersection point. + */ + (*subElVertices)[0] = vertex; + for (i = 0; i < numIntPoints; i++) { + (*subElVertices)[i+1] = (*intPoints)[i]; + } + + + /** + * Create a new ElInfo for the subelement. + */ + subElements.push_back( NEW SubElInfo(subElVertices, elInfo) ); + + TEST_EXIT( subElements.size() == 1 )("error in creating subelements"); + numSubElements = 1; + + DELETE subElVertices; +} + +int +SubPolytope::getIndexSecondFaceIntPoint0(int indexFirstFace, int dim) +{ + int i; + + for (i = 0; i < dim+1; i++) { + if ( fabs((*intPoints)[0][i]) <= 1.e-15 && i != indexFirstFace ) { + return i; + } + } + ERROR_EXIT("couldn't determine the second face for IntPoint0\n"); + return -1; +} + +void +SubPolytope::createSubElementsForPolytope3D(int indexElVertInPol1) +{ + //************************************************************************** + // The intersection with element produced four intersection points. Thus the + // intersection doesn't induce a subelement. This routine divides the + // subpolytope given by the intersection into three subelements. + // + // How does it work ? + // The intersection points and two vertices of element form a subpolytope + // of element. First of all, we determine these vertices, and call them + // A and B. Then we sort the intersection points (S_0, S_1, S_2, S_3) + // in the following way: + // S_0 is the first intersection point in the creation-list /ref intPoints_. + // A and S_0 lie in the face of element opposite to B. + // S_0 and S_1 are neighbours of A. + // S_2 is opposite to S_0 in the intersection plane. + // S_1 and S_3 are neighbours of A. + // Then the subelements are: + // A - B - S_0 - S_1 , B - S_0 - S_1 - S_2 , B - S_0 - S_2 - S_3 . + // + // The index of one vertex of element that is in subpolytope is handed to + // this routine. The subpolytope is determined uniquely by this vertex and + // the intersection points. + //************************************************************************** + + FUNCNAME("SubPolytope::createSubElementForPolytope3D"); + + TEST_EXIT(dim == 3 && numIntPoints == 4)("invalid call of this routine\n"); + + TEST_EXIT(0 <= indexElVertInPol1 && indexElVertInPol1 <= 3) + ("invalid index for vertex of a tetrahedron"); + + VectorOfFixVecs<DimVec<double> > *subElVertices = + NEW VectorOfFixVecs<DimVec<double> >(dim, dim+1, NO_INIT); + DimVec<double> vertexA(dim, DEFAULT_VALUE, 0.0); + DimVec<double> vertexB(dim, DEFAULT_VALUE, 0.0); + + int indexElVertInPol2; // index of second vertex of element lying in + // subpolytope + // The vertices of element (3D -> tetrahedron) are + // indexed as usual: + // 0: (1,0,0,0), 1: (0,1,0,0), 2: (0,0,1,0), + // 3: (0,0,0,1) + bool intPointOnEdge[4][4] = {{false, false, false, false}, + {false, false, false, false}, + {false, false, false, false}, + {false, false, false, false}}; + // /ref intPointOnEdge[i][j] indicates whether there + // is an intersection point on the edge from + // vertice i to vertice j : + // false : no intersection point + // true: there is an intersection point + int indexEdge[2]; // For a vertex lying on an edge indexEdge + // stores the indices of the two barycentric + // coordinates which are not equal to zero. + int indexA; + int indexB; + int indexS_0; + int indexS_1; + int indexS_2; + int indexS_3; + int indexSecondFaceIntPoint0; + int i,j,k; + + /** + * Get the second vertex of element lying in subpolytope. + * + * There is exactly one vertex of element which - with vertex + * indexElVertInPol1 and the intersection points intPoints - + * forms a subpolytope of element. It is the vertex adjacent with + * indexElVertInPol1 whose common edge with indexElVertInPol1 + * doesn't contain an intersection point. + */ + + // Get the edges including the intersection points. + for (i = 0; i < numIntPoints; i++) { + k = 0; + for (j = 0; j < dim+1; j++) { + if ( fabs((*intPoints)[i][j]) > 1.e-15 ) { + indexEdge[k] = j; + k++; + } + } + intPointOnEdge[indexEdge[0]][indexEdge[1]] = true; + intPointOnEdge[indexEdge[1]][indexEdge[0]] = true; + } + + // Get the vertex of element adjacent with indexElVertInPol1 whose + // common edge with indexElVertInPol1 doesn't contain an + // intersection point, and store it in indexElVertInPol2. + for (i = 0; i < dim+1; i++) { + if ( intPointOnEdge[indexElVertInPol1][i] == false && + i != indexElVertInPol1 ) { + indexElVertInPol2 = i; + break; + } + } + + /** + * Determine A and B, so that intPoint0 is a neighbour of A. + * + * In the subpolytope A and two intersection points lie in the face + * opposite to B. And B and the other two intersection points lie in the + * face opposite to A. + */ + + if ( fabs((*intPoints)[0][indexElVertInPol1]) <= 1.e-15 ) { + + // (*intPoints)[0] lies in the face opposite to vertex + // /ref indexElVertInPol1. + + indexA = indexElVertInPol2; + indexB = indexElVertInPol1; + } + else if ( fabs((*intPoints)[0][indexElVertInPol2]) <= 1.e-15 ) { + + // (*intPoints)[0] lies in the face opposite to vertex + // /ref indexElVertInPol2. + + indexA = indexElVertInPol1; + indexB = indexElVertInPol2; + } + else { + ERROR_EXIT("couldn't determine A and B\n"); + } + + /** + * Sort the intersection points. + */ + + // (*intPoints)[0] is a neighbour of A (A has been constructed this way). + indexS_0 = 0; + + if ( fabs((*intPoints)[1][indexB]) <= 1.e-15 ) { + + // (*intPoints)[1] lies in the face opposite to B, thus is a neighbour + // of A. + + indexS_1 = 1; + + indexSecondFaceIntPoint0 = getIndexSecondFaceIntPoint0(indexB, dim); + + if ( fabs((*intPoints)[2][indexSecondFaceIntPoint0]) <= 1.e-15 ) { + + // (*intPoints)[2] is neighbour of (*intPoints)[0] + + indexS_2 = 3; + indexS_3 = 2; + } + else { + + // (*intPoints)[2] is opposite to (*intPoints)[0] in the intersection + // plane + + indexS_2 = 2; + indexS_3 = 3; + } + } + else if ( fabs((*intPoints)[1][indexA]) <= 1.e-15 ) { + + // (*intPoints)[1] lies in the face opposite to A + + indexSecondFaceIntPoint0 = getIndexSecondFaceIntPoint0(indexB, dim); + + if ( fabs((*intPoints)[1][indexSecondFaceIntPoint0]) <= 1.e-15 ) { + + // (*intPoints)[1] is neighbour of (*intPoints)[0], but isn't + // neighbour of A + + indexS_3 = 1; + + if ( fabs((*intPoints)[2][indexB]) <= 1.e-15 ) { + + // (*intPoints)[2] is neighbour of (*intPoints)[0] and neighbour of A + + indexS_1 = 2; + indexS_2 = 3; + } + else { + + // (*intPoints)[2] is opposite to (*intPoints)[0] in the intersection + // plane + + indexS_1 = 3; + indexS_2 = 2; + } + } + else { + + // (*intPoints)[1] isn't neighbour of (*intPoints)[0], thus lies opposite + // to (*intPoints)[0] in the intersection plane + + indexS_2 = 1; + + if ( fabs((*intPoints)[2][indexB]) <= 1.e-15 ) { + + // (*intPoints)[2] is neighbour of A + + indexS_1 = 2; + indexS_3 = 3; + } + else { + + // (*intPoints)[2] isn't neighbour of A + + indexS_1 = 3; + indexS_3 = 2; + } + } + } + else { + ERROR_EXIT("IntPoint1 isn't either part of the face opposite to A nor part of the face opposite to B\n"); + } + + /** + * For each subelement: Collect the vertices of the subelement in + * subElVertices, create a new SubElInfo for the subelement and + * store it in subElements. + * + * Note: The routines CompositeFEMOperator::getElementMatrix and + * CompositeFEMOperator::getElementVector expect the first vertice + * of a subelement to be a vertice of the corresponding element and + * not to be an intersection point. + */ + + // Create vertex A and vertex B. + vertexA[indexA] = 1.0; + vertexB[indexB] = 1.0; + + // Subelement 1: A - B - S_0 - S_1 + (*subElVertices)[0] = vertexA; + (*subElVertices)[1] = vertexB; + (*subElVertices)[2] = (*intPoints)[indexS_0]; + (*subElVertices)[3] = (*intPoints)[indexS_1]; + subElements.push_back( NEW SubElInfo(subElVertices, elInfo) ); + + // Subelement 2: B - S_0 - S_1 - S_2 + (*subElVertices)[0] = vertexB; + (*subElVertices)[1] = (*intPoints)[indexS_0]; + (*subElVertices)[2] = (*intPoints)[indexS_1]; + (*subElVertices)[3] = (*intPoints)[indexS_2]; + subElements.push_back( NEW SubElInfo(subElVertices, elInfo) ); + + // Subelement 3: B - S_0 - S_2 - S_3 + (*subElVertices)[0] = vertexB; + (*subElVertices)[1] = (*intPoints)[indexS_0]; + (*subElVertices)[2] = (*intPoints)[indexS_2]; + (*subElVertices)[3] = (*intPoints)[indexS_3]; + subElements.push_back( NEW SubElInfo(subElVertices, elInfo) ); + + TEST_EXIT( subElements.size() == 3 )("error in creating subelements"); + numSubElements = 3; + + DELETE subElVertices; +} diff --git a/AMDiS/compositeFEM/src/SubPolytope.h b/AMDiS/compositeFEM/src/SubPolytope.h new file mode 100644 index 0000000000000000000000000000000000000000..d91a02028bf3869936b7aea60f482d76a11e8250 --- /dev/null +++ b/AMDiS/compositeFEM/src/SubPolytope.h @@ -0,0 +1,202 @@ +/** \file SubPolytope.h */ + +#ifndef AMDIS_SUBPOLYTOPE_H +#define AMDIS_SUBPOLYTOPE_H + +#include <vector> +#include "ElInfo.h" +#include "MemoryManager.h" +#include "Mesh.h" +#include "FixVec.h" + +#include "SubElInfo.h" + +using namespace AMDiS; +using namespace std; + +// =========================================================================== +// === class SubPolytope ===================================================== +// =========================================================================== +// +// Class description: +// The class SubPolytope holds the functionality for the division of a +// subpolytope in subelements and contains a list of these subelements +// in subElements. The number of subelements is given in numSubElements. +// +// The subpolytope of the element elInfo is initially given by the +// intersection points (barycentric coordinates with respect to element) +// resulting from the intersection of a "plane" with the element. +// There is/are +// 1 intersection point in 1-dimensional finite element space, +// 2 intersection points in 2-dimensional finite element space, +// 3 or 4 intersection points in 3-dimensional finite element space. +// A detailed description of how the division into subelements works can be +// found in the corresponding routines. +// +// Note: This functionality is restricted to the finite element dimensions +// 1, 2 and 3. +// +// Note: The intersection points are expected to lie exactly on edges. +// That means in the barycentric coordinate vector there are exactly +// as many components equal to zero as are expected for points on edges. +// +// Main routines: +// SubPolytope() - Creates the subelements for a subpolytope given by the +// intersection points intPoints and stores them in +// subElements. +// createSubElementPolytopeIsSubElement1D() +// - Creates the subelement in 1-dimensional finite element +// space. +// createSubElementPolytopeIsSubElement2D3D() +// - Creates the subelement in 2-dimensional finite element +// space and in 3-dimensional finite element space if there +// are 3 intersection points. +// createSubElementsForPolytope3D() +// - Creates the 3 subelements in 3-dimensional finite element +// space if there are 4 intersection points. +// ============================================================================ + +class SubPolytope +{ + public: + MEMORY_MANAGED(SubPolytope); + + /** + * Constructor + * + * Divides the polytope produced by the intersection into subelements. + * In dimensions 1 and 3 (case "4 intersection points") indexElVertInPol_ + * indicates which subpolytope to divide. The element vertice with index + * indexElVertInPol_ is a vertice of the choosen subpolytope. + * Here the standard vertice numeration is used (e.g. in dimension 3: + * (1,0,0,0) - index 0, (0,1,0,0) - index 1, ...) + * The subelements are stored in subElements. + */ + SubPolytope(const ElInfo *elInfo_, + VectorOfFixVecs<DimVec<double> > *intPoints_, + int numIntPoints_, + const int &indexElVertInPol_=0); + + /** + * Destructor + */ + ~SubPolytope() + { + int i; + + for (i = 0; i < numSubElements; i++) { + DELETE subElements[i]; + } + }; + + /** + * Returns begin of vector subElements. + */ + inline std::vector<SubElInfo *>::iterator getSubElementsBegin() + { + return subElements.begin(); + } + + /** + * Returns end of vector subElements. + */ + inline std::vector<SubElInfo *>::iterator getSubElementsEnd() + { + return subElements.end(); + } + + /** + * Returns num-th subelement of polytope. + */ + inline SubElInfo* getSubElement(int num) + { + FUNCNAME("SubPolytope::getSubElement"); + + TEST_EXIT(num <= numSubElements)("invalid index for subelement"); + return subElements[num]; + } + + /** + * Returns the number of subelements of the polytope. + */ + inline int getNumSubElements() { return numSubElements; } + + protected: + + /** + * Checks whether the elements of intPoints are really intersection points, + * i.e. lie on edges. + */ + bool checkIntPoints(); + + /** + * In 1-dimensional space the intersection of an element always produces + * two subelements. indexElVertInPol indicates which subelement to take. + * The resulting subelement is created by this routine. + */ + void createSubElementPolytopeIsSubElement1D(int indexElVertInPol); + + /** + * In 2-dimensional space the intersection of an element always produces + * a subelement. The same in 3-dimensional space, if the intersection has + * three intersection points. + * The resulting subelement is created by this routine. + */ + void createSubElementPolytopeIsSubElement2D3D(); + + /** + * Routine used in createSubElementsForPolytope(). + * + * The intersection point /ref intPoints[0] lies on an edge of element + * and isn't a vertex of element. Thus it lies in exactly two faces. + * In barycentric coordinates, lying in the face opposite to e.g. (0,1,0,0) + * means that the second barycentric coordinate is equal to zero. We + * give this face the index 1 (we start indexing by 0). + * In this routine we know already one face containing intPoints[0], + * namely indexFirstFace. The task of the routine is to get the + * second face. + */ + int getIndexSecondFaceIntPoint0(int indexFirstFace, int dim); + + /** + * If in 3-dimensional space the intersection of an element has four + * intersection points, the resulting polytope is no subelement, but it + * can be divided into three subelements. This is done by this routine. + */ + void createSubElementsForPolytope3D(int indexElVertInPol); + + protected: + + /** + * elInfo of the element containing the polytope + */ + const ElInfo *elInfo; + + /** + * Intersection points with the element in barycentric coordinates with + * respect to element + */ + VectorOfFixVecs<DimVec<double> > *intPoints; + + /** + * Number of intersection points + */ + int numIntPoints; + + /** + * List of the subelements of subpolytope + */ + vector<SubElInfo *> subElements; + + /** + * Number of subelements + */ + int numSubElements; + + /** + * Dimension of the polytope + */ + int dim; +}; + +#endif // AMDIS_SUBPOLYTOPE_H diff --git a/AMDiS/compositeFEM/src/TranslateLsFct.h b/AMDiS/compositeFEM/src/TranslateLsFct.h new file mode 100644 index 0000000000000000000000000000000000000000..53b1b40a5e898b79e74efa7b8eab22a19496003f --- /dev/null +++ b/AMDiS/compositeFEM/src/TranslateLsFct.h @@ -0,0 +1,50 @@ +#ifndef AMDIS_TRANSLATELSFCT_H +#define AMDIS_TRANSLATELSFCT_H + +#include "ElementFunction.h" +#include "FixVec.h" +#include "MemoryManager.h" + +using namespace AMDiS; + +template<typename T> +class TranslateLsFct : public ElementFunction<T> +{ + public: + MEMORY_MANAGED(TranslateLsFct); + + /** + * Constructor + */ + TranslateLsFct(ElementFunction<T> *f_, + double c_) + : ElementFunction<T>(), + f(f_), + c(c_) + {}; + + /** + * evaluation at given coordinates. + * + * Defines new level set function. Zero level set of this level set + * function is level set c of level set function f. + */ + const T& operator()(const DimVec<double>& bary) const { + + f->setElInfo(elInfo_); + return ((*f)(bary) - c); + }; + + protected: + /** + * Level set function which is translated. + */ + ElementFunction<T> *f; + + /** + * Translation parameter. + */ + double c; +}; + +#endif // AMDIS_TRANSLATELSFCT_H diff --git a/AMDiS/compositeFEM/src/compositeFEM.h b/AMDiS/compositeFEM/src/compositeFEM.h new file mode 100644 index 0000000000000000000000000000000000000000..b78d737e190499f789f0ba43d66d300c8c7d4f6b --- /dev/null +++ b/AMDiS/compositeFEM/src/compositeFEM.h @@ -0,0 +1,16 @@ +#ifndef AMDIS_COMPOSITEFEM_H +#define AMDIS_COMPOSITEFEM_H +#include "CFE_Integration.h" +#include "CFE_NormAndErrorFcts.h" +#include "CompositeFEMMethods.h" +#include "CompositeFEMOperator.h" +#include "ElementLevelSet.h" +#include "LevelSetAdaptMesh.h" +#include "PenaltyOperator.h" +#include "ScalableQuadrature.h" +#include "SubElementAssembler.h" +#include "SubElInfo.h" +#include "SubPolytope.h" +#include "TranslateLsFct.h" +#endif + diff --git a/AMDiS/config.guess b/AMDiS/config.guess new file mode 100755 index 0000000000000000000000000000000000000000..2fc3acce2ea194699db402e89d32d5b10b0369a3 --- /dev/null +++ b/AMDiS/config.guess @@ -0,0 +1,1411 @@ +#! /bin/sh +# Attempt to guess a canonical system name. +# Copyright (C) 1992, 1993, 1994, 1995, 1996, 1997, 1998, 1999, +# 2000, 2001, 2002, 2003 Free Software Foundation, Inc. + +timestamp='2003-06-17' + +# This file 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., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. +# +# As a special exception to the GNU General Public License, if you +# distribute this file as part of a program that contains a +# configuration script generated by Autoconf, you may include it under +# the same distribution terms that you use for the rest of that program. + +# Originally written by Per Bothner <per@bothner.com>. +# Please send patches to <config-patches@gnu.org>. Submit a context +# diff and a properly formatted ChangeLog entry. +# +# This script attempts to guess a canonical system name similar to +# config.sub. If it succeeds, it prints the system name on stdout, and +# exits with 0. Otherwise, it exits with 1. +# +# The plan is that this can be called by configure scripts if you +# don't specify an explicit build system type. + +me=`echo "$0" | sed -e 's,.*/,,'` + +usage="\ +Usage: $0 [OPTION] + +Output the configuration name of the system \`$me' is run on. + +Operation modes: + -h, --help print this help, then exit + -t, --time-stamp print date of last modification, then exit + -v, --version print version number, then exit + +Report bugs and patches to <config-patches@gnu.org>." + +version="\ +GNU config.guess ($timestamp) + +Originally written by Per Bothner. +Copyright (C) 1992, 1993, 1994, 1995, 1996, 1997, 1998, 1999, 2000, 2001 +Free Software Foundation, Inc. + +This is free software; see the source for copying conditions. There is NO +warranty; not even for MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE." + +help=" +Try \`$me --help' for more information." + +# Parse command line +while test $# -gt 0 ; do + case $1 in + --time-stamp | --time* | -t ) + echo "$timestamp" ; exit 0 ;; + --version | -v ) + echo "$version" ; exit 0 ;; + --help | --h* | -h ) + echo "$usage"; exit 0 ;; + -- ) # Stop option processing + shift; break ;; + - ) # Use stdin as input. + break ;; + -* ) + echo "$me: invalid option $1$help" >&2 + exit 1 ;; + * ) + break ;; + esac +done + +if test $# != 0; then + echo "$me: too many arguments$help" >&2 + exit 1 +fi + +trap 'exit 1' 1 2 15 + +# CC_FOR_BUILD -- compiler used by this script. Note that the use of a +# compiler to aid in system detection is discouraged as it requires +# temporary files to be created and, as you can see below, it is a +# headache to deal with in a portable fashion. + +# Historically, `CC_FOR_BUILD' used to be named `HOST_CC'. We still +# use `HOST_CC' if defined, but it is deprecated. + +# Portable tmp directory creation inspired by the Autoconf team. + +set_cc_for_build=' +trap "exitcode=\$?; (rm -f \$tmpfiles 2>/dev/null; rmdir \$tmp 2>/dev/null) && exit \$exitcode" 0 ; +trap "rm -f \$tmpfiles 2>/dev/null; rmdir \$tmp 2>/dev/null; exit 1" 1 2 13 15 ; +: ${TMPDIR=/tmp} ; + { tmp=`(umask 077 && mktemp -d -q "$TMPDIR/cgXXXXXX") 2>/dev/null` && test -n "$tmp" && test -d "$tmp" ; } || + { test -n "$RANDOM" && tmp=$TMPDIR/cg$$-$RANDOM && (umask 077 && mkdir $tmp) ; } || + { tmp=$TMPDIR/cg-$$ && (umask 077 && mkdir $tmp) && echo "Warning: creating insecure temp directory" >&2 ; } || + { echo "$me: cannot create a temporary directory in $TMPDIR" >&2 ; exit 1 ; } ; +dummy=$tmp/dummy ; +tmpfiles="$dummy.c $dummy.o $dummy.rel $dummy" ; +case $CC_FOR_BUILD,$HOST_CC,$CC in + ,,) echo "int x;" > $dummy.c ; + for c in cc gcc c89 c99 ; do + if ($c -c -o $dummy.o $dummy.c) >/dev/null 2>&1 ; then + CC_FOR_BUILD="$c"; break ; + fi ; + done ; + if test x"$CC_FOR_BUILD" = x ; then + CC_FOR_BUILD=no_compiler_found ; + fi + ;; + ,,*) CC_FOR_BUILD=$CC ;; + ,*,*) CC_FOR_BUILD=$HOST_CC ;; +esac ;' + +# This is needed to find uname on a Pyramid OSx when run in the BSD universe. +# (ghazi@noc.rutgers.edu 1994-08-24) +if (test -f /.attbin/uname) >/dev/null 2>&1 ; then + PATH=$PATH:/.attbin ; export PATH +fi + +UNAME_MACHINE=`(uname -m) 2>/dev/null` || UNAME_MACHINE=unknown +UNAME_RELEASE=`(uname -r) 2>/dev/null` || UNAME_RELEASE=unknown +UNAME_SYSTEM=`(uname -s) 2>/dev/null` || UNAME_SYSTEM=unknown +UNAME_VERSION=`(uname -v) 2>/dev/null` || UNAME_VERSION=unknown + +## for Red Hat Linux +if test -f /etc/redhat-release ; then + VENDOR=redhat ; +else + VENDOR= ; +fi + +# Note: order is significant - the case branches are not exclusive. + +case "${UNAME_MACHINE}:${UNAME_SYSTEM}:${UNAME_RELEASE}:${UNAME_VERSION}" in + *:NetBSD:*:*) + # NetBSD (nbsd) targets should (where applicable) match one or + # more of the tupples: *-*-netbsdelf*, *-*-netbsdaout*, + # *-*-netbsdecoff* and *-*-netbsd*. For targets that recently + # switched to ELF, *-*-netbsd* would select the old + # object file format. This provides both forward + # compatibility and a consistent mechanism for selecting the + # object file format. + # + # Note: NetBSD doesn't particularly care about the vendor + # portion of the name. We always set it to "unknown". + sysctl="sysctl -n hw.machine_arch" + UNAME_MACHINE_ARCH=`(/sbin/$sysctl 2>/dev/null || \ + /usr/sbin/$sysctl 2>/dev/null || echo unknown)` + case "${UNAME_MACHINE_ARCH}" in + armeb) machine=armeb-unknown ;; + arm*) machine=arm-unknown ;; + sh3el) machine=shl-unknown ;; + sh3eb) machine=sh-unknown ;; + *) machine=${UNAME_MACHINE_ARCH}-unknown ;; + esac + # The Operating System including object format, if it has switched + # to ELF recently, or will in the future. + case "${UNAME_MACHINE_ARCH}" in + arm*|i386|m68k|ns32k|sh3*|sparc|vax) + eval $set_cc_for_build + if echo __ELF__ | $CC_FOR_BUILD -E - 2>/dev/null \ + | grep __ELF__ >/dev/null + then + # Once all utilities can be ECOFF (netbsdecoff) or a.out (netbsdaout). + # Return netbsd for either. FIX? + os=netbsd + else + os=netbsdelf + fi + ;; + *) + os=netbsd + ;; + esac + # The OS release + # Debian GNU/NetBSD machines have a different userland, and + # thus, need a distinct triplet. However, they do not need + # kernel version information, so it can be replaced with a + # suitable tag, in the style of linux-gnu. + case "${UNAME_VERSION}" in + Debian*) + release='-gnu' + ;; + *) + release=`echo ${UNAME_RELEASE}|sed -e 's/[-_].*/\./'` + ;; + esac + # Since CPU_TYPE-MANUFACTURER-KERNEL-OPERATING_SYSTEM: + # contains redundant information, the shorter form: + # CPU_TYPE-MANUFACTURER-OPERATING_SYSTEM is used. + echo "${machine}-${os}${release}" + exit 0 ;; + amiga:OpenBSD:*:*) + echo m68k-unknown-openbsd${UNAME_RELEASE} + exit 0 ;; + arc:OpenBSD:*:*) + echo mipsel-unknown-openbsd${UNAME_RELEASE} + exit 0 ;; + hp300:OpenBSD:*:*) + echo m68k-unknown-openbsd${UNAME_RELEASE} + exit 0 ;; + mac68k:OpenBSD:*:*) + echo m68k-unknown-openbsd${UNAME_RELEASE} + exit 0 ;; + macppc:OpenBSD:*:*) + echo powerpc-unknown-openbsd${UNAME_RELEASE} + exit 0 ;; + mvme68k:OpenBSD:*:*) + echo m68k-unknown-openbsd${UNAME_RELEASE} + exit 0 ;; + mvme88k:OpenBSD:*:*) + echo m88k-unknown-openbsd${UNAME_RELEASE} + exit 0 ;; + mvmeppc:OpenBSD:*:*) + echo powerpc-unknown-openbsd${UNAME_RELEASE} + exit 0 ;; + pmax:OpenBSD:*:*) + echo mipsel-unknown-openbsd${UNAME_RELEASE} + exit 0 ;; + sgi:OpenBSD:*:*) + echo mipseb-unknown-openbsd${UNAME_RELEASE} + exit 0 ;; + sun3:OpenBSD:*:*) + echo m68k-unknown-openbsd${UNAME_RELEASE} + exit 0 ;; + wgrisc:OpenBSD:*:*) + echo mipsel-unknown-openbsd${UNAME_RELEASE} + exit 0 ;; + *:OpenBSD:*:*) + echo ${UNAME_MACHINE}-unknown-openbsd${UNAME_RELEASE} + exit 0 ;; + alpha:OSF1:*:*) + if test $UNAME_RELEASE = "V4.0"; then + UNAME_RELEASE=`/usr/sbin/sizer -v | awk '{print $3}'` + fi + # According to Compaq, /usr/sbin/psrinfo has been available on + # OSF/1 and Tru64 systems produced since 1995. I hope that + # covers most systems running today. This code pipes the CPU + # types through head -n 1, so we only detect the type of CPU 0. + ALPHA_CPU_TYPE=`/usr/sbin/psrinfo -v | sed -n -e 's/^ The alpha \(.*\) processor.*$/\1/p' | head -n 1` + case "$ALPHA_CPU_TYPE" in + "EV4 (21064)") + UNAME_MACHINE="alpha" ;; + "EV4.5 (21064)") + UNAME_MACHINE="alpha" ;; + "LCA4 (21066/21068)") + UNAME_MACHINE="alpha" ;; + "EV5 (21164)") + UNAME_MACHINE="alphaev5" ;; + "EV5.6 (21164A)") + UNAME_MACHINE="alphaev56" ;; + "EV5.6 (21164PC)") + UNAME_MACHINE="alphapca56" ;; + "EV5.7 (21164PC)") + UNAME_MACHINE="alphapca57" ;; + "EV6 (21264)") + UNAME_MACHINE="alphaev6" ;; + "EV6.7 (21264A)") + UNAME_MACHINE="alphaev67" ;; + "EV6.8CB (21264C)") + UNAME_MACHINE="alphaev68" ;; + "EV6.8AL (21264B)") + UNAME_MACHINE="alphaev68" ;; + "EV6.8CX (21264D)") + UNAME_MACHINE="alphaev68" ;; + "EV6.9A (21264/EV69A)") + UNAME_MACHINE="alphaev69" ;; + "EV7 (21364)") + UNAME_MACHINE="alphaev7" ;; + "EV7.9 (21364A)") + UNAME_MACHINE="alphaev79" ;; + esac + # A Vn.n version is a released version. + # A Tn.n version is a released field test version. + # A Xn.n version is an unreleased experimental baselevel. + # 1.2 uses "1.2" for uname -r. + echo ${UNAME_MACHINE}-dec-osf`echo ${UNAME_RELEASE} | sed -e 's/^[VTX]//' | tr 'ABCDEFGHIJKLMNOPQRSTUVWXYZ' 'abcdefghijklmnopqrstuvwxyz'` + exit 0 ;; + Alpha*:OpenVMS:*:*) + echo alpha-hp-vms + exit 0 ;; + Alpha\ *:Windows_NT*:*) + # How do we know it's Interix rather than the generic POSIX subsystem? + # Should we change UNAME_MACHINE based on the output of uname instead + # of the specific Alpha model? + echo alpha-pc-interix + exit 0 ;; + 21064:Windows_NT:50:3) + echo alpha-dec-winnt3.5 + exit 0 ;; + Amiga*:UNIX_System_V:4.0:*) + echo m68k-unknown-sysv4 + exit 0;; + *:[Aa]miga[Oo][Ss]:*:*) + echo ${UNAME_MACHINE}-unknown-amigaos + exit 0 ;; + *:[Mm]orph[Oo][Ss]:*:*) + echo ${UNAME_MACHINE}-unknown-morphos + exit 0 ;; + *:OS/390:*:*) + echo i370-ibm-openedition + exit 0 ;; + arm:RISC*:1.[012]*:*|arm:riscix:1.[012]*:*) + echo arm-acorn-riscix${UNAME_RELEASE} + exit 0;; + SR2?01:HI-UX/MPP:*:* | SR8000:HI-UX/MPP:*:*) + echo hppa1.1-hitachi-hiuxmpp + exit 0;; + Pyramid*:OSx*:*:* | MIS*:OSx*:*:* | MIS*:SMP_DC-OSx*:*:*) + # akee@wpdis03.wpafb.af.mil (Earle F. Ake) contributed MIS and NILE. + if test "`(/bin/universe) 2>/dev/null`" = att ; then + echo pyramid-pyramid-sysv3 + else + echo pyramid-pyramid-bsd + fi + exit 0 ;; + NILE*:*:*:dcosx) + echo pyramid-pyramid-svr4 + exit 0 ;; + DRS?6000:unix:4.0:6*) + echo sparc-icl-nx6 + exit 0 ;; + DRS?6000:UNIX_SV:4.2*:7*) + case `/usr/bin/uname -p` in + sparc) echo sparc-icl-nx7 && exit 0 ;; + esac ;; + sun4H:SunOS:5.*:*) + echo sparc-hal-solaris2`echo ${UNAME_RELEASE}|sed -e 's/[^.]*//'` + exit 0 ;; + sun4*:SunOS:5.*:* | tadpole*:SunOS:5.*:*) + echo sparc-sun-solaris2`echo ${UNAME_RELEASE}|sed -e 's/[^.]*//'` + exit 0 ;; + i86pc:SunOS:5.*:*) + echo i386-pc-solaris2`echo ${UNAME_RELEASE}|sed -e 's/[^.]*//'` + exit 0 ;; + sun4*:SunOS:6*:*) + # According to config.sub, this is the proper way to canonicalize + # SunOS6. Hard to guess exactly what SunOS6 will be like, but + # it's likely to be more like Solaris than SunOS4. + echo sparc-sun-solaris3`echo ${UNAME_RELEASE}|sed -e 's/[^.]*//'` + exit 0 ;; + sun4*:SunOS:*:*) + case "`/usr/bin/arch -k`" in + Series*|S4*) + UNAME_RELEASE=`uname -v` + ;; + esac + # Japanese Language versions have a version number like `4.1.3-JL'. + echo sparc-sun-sunos`echo ${UNAME_RELEASE}|sed -e 's/-/_/'` + exit 0 ;; + sun3*:SunOS:*:*) + echo m68k-sun-sunos${UNAME_RELEASE} + exit 0 ;; + sun*:*:4.2BSD:*) + UNAME_RELEASE=`(sed 1q /etc/motd | awk '{print substr($5,1,3)}') 2>/dev/null` + test "x${UNAME_RELEASE}" = "x" && UNAME_RELEASE=3 + case "`/bin/arch`" in + sun3) + echo m68k-sun-sunos${UNAME_RELEASE} + ;; + sun4) + echo sparc-sun-sunos${UNAME_RELEASE} + ;; + esac + exit 0 ;; + aushp:SunOS:*:*) + echo sparc-auspex-sunos${UNAME_RELEASE} + exit 0 ;; + # The situation for MiNT is a little confusing. The machine name + # can be virtually everything (everything which is not + # "atarist" or "atariste" at least should have a processor + # > m68000). The system name ranges from "MiNT" over "FreeMiNT" + # to the lowercase version "mint" (or "freemint"). Finally + # the system name "TOS" denotes a system which is actually not + # MiNT. But MiNT is downward compatible to TOS, so this should + # be no problem. + atarist[e]:*MiNT:*:* | atarist[e]:*mint:*:* | atarist[e]:*TOS:*:*) + echo m68k-atari-mint${UNAME_RELEASE} + exit 0 ;; + atari*:*MiNT:*:* | atari*:*mint:*:* | atarist[e]:*TOS:*:*) + echo m68k-atari-mint${UNAME_RELEASE} + exit 0 ;; + *falcon*:*MiNT:*:* | *falcon*:*mint:*:* | *falcon*:*TOS:*:*) + echo m68k-atari-mint${UNAME_RELEASE} + exit 0 ;; + milan*:*MiNT:*:* | milan*:*mint:*:* | *milan*:*TOS:*:*) + echo m68k-milan-mint${UNAME_RELEASE} + exit 0 ;; + hades*:*MiNT:*:* | hades*:*mint:*:* | *hades*:*TOS:*:*) + echo m68k-hades-mint${UNAME_RELEASE} + exit 0 ;; + *:*MiNT:*:* | *:*mint:*:* | *:*TOS:*:*) + echo m68k-unknown-mint${UNAME_RELEASE} + exit 0 ;; + powerpc:machten:*:*) + echo powerpc-apple-machten${UNAME_RELEASE} + exit 0 ;; + RISC*:Mach:*:*) + echo mips-dec-mach_bsd4.3 + exit 0 ;; + RISC*:ULTRIX:*:*) + echo mips-dec-ultrix${UNAME_RELEASE} + exit 0 ;; + VAX*:ULTRIX*:*:*) + echo vax-dec-ultrix${UNAME_RELEASE} + exit 0 ;; + 2020:CLIX:*:* | 2430:CLIX:*:*) + echo clipper-intergraph-clix${UNAME_RELEASE} + exit 0 ;; + mips:*:*:UMIPS | mips:*:*:RISCos) + eval $set_cc_for_build + sed 's/^ //' << EOF >$dummy.c +#ifdef __cplusplus +#include <stdio.h> /* for printf() prototype */ + int main (int argc, char *argv[]) { +#else + int main (argc, argv) int argc; char *argv[]; { +#endif + #if defined (host_mips) && defined (MIPSEB) + #if defined (SYSTYPE_SYSV) + printf ("mips-mips-riscos%ssysv\n", argv[1]); exit (0); + #endif + #if defined (SYSTYPE_SVR4) + printf ("mips-mips-riscos%ssvr4\n", argv[1]); exit (0); + #endif + #if defined (SYSTYPE_BSD43) || defined(SYSTYPE_BSD) + printf ("mips-mips-riscos%sbsd\n", argv[1]); exit (0); + #endif + #endif + exit (-1); + } +EOF + $CC_FOR_BUILD -o $dummy $dummy.c \ + && $dummy `echo "${UNAME_RELEASE}" | sed -n 's/\([0-9]*\).*/\1/p'` \ + && exit 0 + echo mips-mips-riscos${UNAME_RELEASE} + exit 0 ;; + Motorola:PowerMAX_OS:*:*) + echo powerpc-motorola-powermax + exit 0 ;; + Motorola:*:4.3:PL8-*) + echo powerpc-harris-powermax + exit 0 ;; + Night_Hawk:*:*:PowerMAX_OS | Synergy:PowerMAX_OS:*:*) + echo powerpc-harris-powermax + exit 0 ;; + Night_Hawk:Power_UNIX:*:*) + echo powerpc-harris-powerunix + exit 0 ;; + m88k:CX/UX:7*:*) + echo m88k-harris-cxux7 + exit 0 ;; + m88k:*:4*:R4*) + echo m88k-motorola-sysv4 + exit 0 ;; + m88k:*:3*:R3*) + echo m88k-motorola-sysv3 + exit 0 ;; + AViiON:dgux:*:*) + # DG/UX returns AViiON for all architectures + UNAME_PROCESSOR=`/usr/bin/uname -p` + if [ $UNAME_PROCESSOR = mc88100 ] || [ $UNAME_PROCESSOR = mc88110 ] + then + if [ ${TARGET_BINARY_INTERFACE}x = m88kdguxelfx ] || \ + [ ${TARGET_BINARY_INTERFACE}x = x ] + then + echo m88k-dg-dgux${UNAME_RELEASE} + else + echo m88k-dg-dguxbcs${UNAME_RELEASE} + fi + else + echo i586-dg-dgux${UNAME_RELEASE} + fi + exit 0 ;; + M88*:DolphinOS:*:*) # DolphinOS (SVR3) + echo m88k-dolphin-sysv3 + exit 0 ;; + M88*:*:R3*:*) + # Delta 88k system running SVR3 + echo m88k-motorola-sysv3 + exit 0 ;; + XD88*:*:*:*) # Tektronix XD88 system running UTekV (SVR3) + echo m88k-tektronix-sysv3 + exit 0 ;; + Tek43[0-9][0-9]:UTek:*:*) # Tektronix 4300 system running UTek (BSD) + echo m68k-tektronix-bsd + exit 0 ;; + *:IRIX*:*:*) + echo mips-sgi-irix`echo ${UNAME_RELEASE}|sed -e 's/-/_/g'` + exit 0 ;; + ????????:AIX?:[12].1:2) # AIX 2.2.1 or AIX 2.1.1 is RT/PC AIX. + echo romp-ibm-aix # uname -m gives an 8 hex-code CPU id + exit 0 ;; # Note that: echo "'`uname -s`'" gives 'AIX ' + i*86:AIX:*:*) + echo i386-ibm-aix + exit 0 ;; + ia64:AIX:*:*) + if [ -x /usr/bin/oslevel ] ; then + IBM_REV=`/usr/bin/oslevel` + else + IBM_REV=${UNAME_VERSION}.${UNAME_RELEASE} + fi + echo ${UNAME_MACHINE}-ibm-aix${IBM_REV} + exit 0 ;; + *:AIX:2:3) + if grep bos325 /usr/include/stdio.h >/dev/null 2>&1; then + eval $set_cc_for_build + sed 's/^ //' << EOF >$dummy.c + #include <sys/systemcfg.h> + + main() + { + if (!__power_pc()) + exit(1); + puts("powerpc-ibm-aix3.2.5"); + exit(0); + } +EOF + $CC_FOR_BUILD -o $dummy $dummy.c && $dummy && exit 0 + echo rs6000-ibm-aix3.2.5 + elif grep bos324 /usr/include/stdio.h >/dev/null 2>&1; then + echo rs6000-ibm-aix3.2.4 + else + echo rs6000-ibm-aix3.2 + fi + exit 0 ;; + *:AIX:*:[45]) + IBM_CPU_ID=`/usr/sbin/lsdev -C -c processor -S available | sed 1q | awk '{ print $1 }'` + if /usr/sbin/lsattr -El ${IBM_CPU_ID} | grep ' POWER' >/dev/null 2>&1; then + IBM_ARCH=rs6000 + else + IBM_ARCH=powerpc + fi + if [ -x /usr/bin/oslevel ] ; then + IBM_REV=`/usr/bin/oslevel` + else + IBM_REV=${UNAME_VERSION}.${UNAME_RELEASE} + fi + echo ${IBM_ARCH}-ibm-aix${IBM_REV} + exit 0 ;; + *:AIX:*:*) + echo rs6000-ibm-aix + exit 0 ;; + ibmrt:4.4BSD:*|romp-ibm:BSD:*) + echo romp-ibm-bsd4.4 + exit 0 ;; + ibmrt:*BSD:*|romp-ibm:BSD:*) # covers RT/PC BSD and + echo romp-ibm-bsd${UNAME_RELEASE} # 4.3 with uname added to + exit 0 ;; # report: romp-ibm BSD 4.3 + *:BOSX:*:*) + echo rs6000-bull-bosx + exit 0 ;; + DPX/2?00:B.O.S.:*:*) + echo m68k-bull-sysv3 + exit 0 ;; + 9000/[34]??:4.3bsd:1.*:*) + echo m68k-hp-bsd + exit 0 ;; + hp300:4.4BSD:*:* | 9000/[34]??:4.3bsd:2.*:*) + echo m68k-hp-bsd4.4 + exit 0 ;; + 9000/[34678]??:HP-UX:*:*) + HPUX_REV=`echo ${UNAME_RELEASE}|sed -e 's/[^.]*.[0B]*//'` + case "${UNAME_MACHINE}" in + 9000/31? ) HP_ARCH=m68000 ;; + 9000/[34]?? ) HP_ARCH=m68k ;; + 9000/[678][0-9][0-9]) + if [ -x /usr/bin/getconf ]; then + sc_cpu_version=`/usr/bin/getconf SC_CPU_VERSION 2>/dev/null` + sc_kernel_bits=`/usr/bin/getconf SC_KERNEL_BITS 2>/dev/null` + case "${sc_cpu_version}" in + 523) HP_ARCH="hppa1.0" ;; # CPU_PA_RISC1_0 + 528) HP_ARCH="hppa1.1" ;; # CPU_PA_RISC1_1 + 532) # CPU_PA_RISC2_0 + case "${sc_kernel_bits}" in + 32) HP_ARCH="hppa2.0n" ;; + 64) HP_ARCH="hppa2.0w" ;; + '') HP_ARCH="hppa2.0" ;; # HP-UX 10.20 + esac ;; + esac + fi + if [ "${HP_ARCH}" = "" ]; then + eval $set_cc_for_build + sed 's/^ //' << EOF >$dummy.c + + #define _HPUX_SOURCE + #include <stdlib.h> + #include <unistd.h> + + int main () + { + #if defined(_SC_KERNEL_BITS) + long bits = sysconf(_SC_KERNEL_BITS); + #endif + long cpu = sysconf (_SC_CPU_VERSION); + + switch (cpu) + { + case CPU_PA_RISC1_0: puts ("hppa1.0"); break; + case CPU_PA_RISC1_1: puts ("hppa1.1"); break; + case CPU_PA_RISC2_0: + #if defined(_SC_KERNEL_BITS) + switch (bits) + { + case 64: puts ("hppa2.0w"); break; + case 32: puts ("hppa2.0n"); break; + default: puts ("hppa2.0"); break; + } break; + #else /* !defined(_SC_KERNEL_BITS) */ + puts ("hppa2.0"); break; + #endif + default: puts ("hppa1.0"); break; + } + exit (0); + } +EOF + (CCOPTS= $CC_FOR_BUILD -o $dummy $dummy.c 2>/dev/null) && HP_ARCH=`$dummy` + test -z "$HP_ARCH" && HP_ARCH=hppa + fi ;; + esac + if [ ${HP_ARCH} = "hppa2.0w" ] + then + # avoid double evaluation of $set_cc_for_build + test -n "$CC_FOR_BUILD" || eval $set_cc_for_build + if echo __LP64__ | (CCOPTS= $CC_FOR_BUILD -E -) | grep __LP64__ >/dev/null + then + HP_ARCH="hppa2.0w" + else + HP_ARCH="hppa64" + fi + fi + echo ${HP_ARCH}-hp-hpux${HPUX_REV} + exit 0 ;; + ia64:HP-UX:*:*) + HPUX_REV=`echo ${UNAME_RELEASE}|sed -e 's/[^.]*.[0B]*//'` + echo ia64-hp-hpux${HPUX_REV} + exit 0 ;; + 3050*:HI-UX:*:*) + eval $set_cc_for_build + sed 's/^ //' << EOF >$dummy.c + #include <unistd.h> + int + main () + { + long cpu = sysconf (_SC_CPU_VERSION); + /* The order matters, because CPU_IS_HP_MC68K erroneously returns + true for CPU_PA_RISC1_0. CPU_IS_PA_RISC returns correct + results, however. */ + if (CPU_IS_PA_RISC (cpu)) + { + switch (cpu) + { + case CPU_PA_RISC1_0: puts ("hppa1.0-hitachi-hiuxwe2"); break; + case CPU_PA_RISC1_1: puts ("hppa1.1-hitachi-hiuxwe2"); break; + case CPU_PA_RISC2_0: puts ("hppa2.0-hitachi-hiuxwe2"); break; + default: puts ("hppa-hitachi-hiuxwe2"); break; + } + } + else if (CPU_IS_HP_MC68K (cpu)) + puts ("m68k-hitachi-hiuxwe2"); + else puts ("unknown-hitachi-hiuxwe2"); + exit (0); + } +EOF + $CC_FOR_BUILD -o $dummy $dummy.c && $dummy && exit 0 + echo unknown-hitachi-hiuxwe2 + exit 0 ;; + 9000/7??:4.3bsd:*:* | 9000/8?[79]:4.3bsd:*:* ) + echo hppa1.1-hp-bsd + exit 0 ;; + 9000/8??:4.3bsd:*:*) + echo hppa1.0-hp-bsd + exit 0 ;; + *9??*:MPE/iX:*:* | *3000*:MPE/iX:*:*) + echo hppa1.0-hp-mpeix + exit 0 ;; + hp7??:OSF1:*:* | hp8?[79]:OSF1:*:* ) + echo hppa1.1-hp-osf + exit 0 ;; + hp8??:OSF1:*:*) + echo hppa1.0-hp-osf + exit 0 ;; + i*86:OSF1:*:*) + if [ -x /usr/sbin/sysversion ] ; then + echo ${UNAME_MACHINE}-unknown-osf1mk + else + echo ${UNAME_MACHINE}-unknown-osf1 + fi + exit 0 ;; + parisc*:Lites*:*:*) + echo hppa1.1-hp-lites + exit 0 ;; + C1*:ConvexOS:*:* | convex:ConvexOS:C1*:*) + echo c1-convex-bsd + exit 0 ;; + C2*:ConvexOS:*:* | convex:ConvexOS:C2*:*) + if getsysinfo -f scalar_acc + then echo c32-convex-bsd + else echo c2-convex-bsd + fi + exit 0 ;; + C34*:ConvexOS:*:* | convex:ConvexOS:C34*:*) + echo c34-convex-bsd + exit 0 ;; + C38*:ConvexOS:*:* | convex:ConvexOS:C38*:*) + echo c38-convex-bsd + exit 0 ;; + C4*:ConvexOS:*:* | convex:ConvexOS:C4*:*) + echo c4-convex-bsd + exit 0 ;; + CRAY*Y-MP:*:*:*) + echo ymp-cray-unicos${UNAME_RELEASE} | sed -e 's/\.[^.]*$/.X/' + exit 0 ;; + CRAY*[A-Z]90:*:*:*) + echo ${UNAME_MACHINE}-cray-unicos${UNAME_RELEASE} \ + | sed -e 's/CRAY.*\([A-Z]90\)/\1/' \ + -e y/ABCDEFGHIJKLMNOPQRSTUVWXYZ/abcdefghijklmnopqrstuvwxyz/ \ + -e 's/\.[^.]*$/.X/' + exit 0 ;; + CRAY*TS:*:*:*) + echo t90-cray-unicos${UNAME_RELEASE} | sed -e 's/\.[^.]*$/.X/' + exit 0 ;; + CRAY*T3E:*:*:*) + echo alphaev5-cray-unicosmk${UNAME_RELEASE} | sed -e 's/\.[^.]*$/.X/' + exit 0 ;; + CRAY*SV1:*:*:*) + echo sv1-cray-unicos${UNAME_RELEASE} | sed -e 's/\.[^.]*$/.X/' + exit 0 ;; + *:UNICOS/mp:*:*) + echo nv1-cray-unicosmp${UNAME_RELEASE} | sed -e 's/\.[^.]*$/.X/' + exit 0 ;; + F30[01]:UNIX_System_V:*:* | F700:UNIX_System_V:*:*) + FUJITSU_PROC=`uname -m | tr 'ABCDEFGHIJKLMNOPQRSTUVWXYZ' 'abcdefghijklmnopqrstuvwxyz'` + FUJITSU_SYS=`uname -p | tr 'ABCDEFGHIJKLMNOPQRSTUVWXYZ' 'abcdefghijklmnopqrstuvwxyz' | sed -e 's/\///'` + FUJITSU_REL=`echo ${UNAME_RELEASE} | sed -e 's/ /_/'` + echo "${FUJITSU_PROC}-fujitsu-${FUJITSU_SYS}${FUJITSU_REL}" + exit 0 ;; + i*86:BSD/386:*:* | i*86:BSD/OS:*:* | *:Ascend\ Embedded/OS:*:*) + echo ${UNAME_MACHINE}-pc-bsdi${UNAME_RELEASE} + exit 0 ;; + sparc*:BSD/OS:*:*) + echo sparc-unknown-bsdi${UNAME_RELEASE} + exit 0 ;; + *:BSD/OS:*:*) + echo ${UNAME_MACHINE}-unknown-bsdi${UNAME_RELEASE} + exit 0 ;; + *:FreeBSD:*:*|*:GNU/FreeBSD:*:*) + # Determine whether the default compiler uses glibc. + eval $set_cc_for_build + sed 's/^ //' << EOF >$dummy.c + #include <features.h> + #if __GLIBC__ >= 2 + LIBC=gnu + #else + LIBC= + #endif +EOF + eval `$CC_FOR_BUILD -E $dummy.c 2>/dev/null | grep ^LIBC=` + echo ${UNAME_MACHINE}-unknown-freebsd`echo ${UNAME_RELEASE}|sed -e 's/[-(].*//'`${LIBC:+-$LIBC} + exit 0 ;; + i*:CYGWIN*:*) + echo ${UNAME_MACHINE}-pc-cygwin + exit 0 ;; + i*:MINGW*:*) + echo ${UNAME_MACHINE}-pc-mingw32 + exit 0 ;; + i*:PW*:*) + echo ${UNAME_MACHINE}-pc-pw32 + exit 0 ;; + x86:Interix*:[34]*) + echo i586-pc-interix${UNAME_RELEASE}|sed -e 's/\..*//' + exit 0 ;; + [345]86:Windows_95:* | [345]86:Windows_98:* | [345]86:Windows_NT:*) + echo i${UNAME_MACHINE}-pc-mks + exit 0 ;; + i*:Windows_NT*:* | Pentium*:Windows_NT*:*) + # How do we know it's Interix rather than the generic POSIX subsystem? + # It also conflicts with pre-2.0 versions of AT&T UWIN. Should we + # UNAME_MACHINE based on the output of uname instead of i386? + echo i586-pc-interix + exit 0 ;; + i*:UWIN*:*) + echo ${UNAME_MACHINE}-pc-uwin + exit 0 ;; + p*:CYGWIN*:*) + echo powerpcle-unknown-cygwin + exit 0 ;; + prep*:SunOS:5.*:*) + echo powerpcle-unknown-solaris2`echo ${UNAME_RELEASE}|sed -e 's/[^.]*//'` + exit 0 ;; + *:GNU:*:*) + echo `echo ${UNAME_MACHINE}|sed -e 's,[-/].*$,,'`-unknown-gnu`echo ${UNAME_RELEASE}|sed -e 's,/.*$,,'` + exit 0 ;; + i*86:Minix:*:*) + echo ${UNAME_MACHINE}-pc-minix + exit 0 ;; + arm*:Linux:*:*) + echo ${UNAME_MACHINE}-unknown-linux-gnu + exit 0 ;; + cris:Linux:*:*) + echo cris-axis-linux-gnu + exit 0 ;; + ia64:Linux:*:*) + echo ${UNAME_MACHINE}-${VENDOR:-unknown}-linux-gnu + exit 0 ;; + m68*:Linux:*:*) + echo ${UNAME_MACHINE}-unknown-linux-gnu + exit 0 ;; + mips:Linux:*:*) + eval $set_cc_for_build + sed 's/^ //' << EOF >$dummy.c + #undef CPU + #undef mips + #undef mipsel + #if defined(__MIPSEL__) || defined(__MIPSEL) || defined(_MIPSEL) || defined(MIPSEL) + CPU=mipsel + #else + #if defined(__MIPSEB__) || defined(__MIPSEB) || defined(_MIPSEB) || defined(MIPSEB) + CPU=mips + #else + CPU= + #endif + #endif +EOF + eval `$CC_FOR_BUILD -E $dummy.c 2>/dev/null | grep ^CPU=` + test x"${CPU}" != x && echo "${CPU}-unknown-linux-gnu" && exit 0 + ;; + mips64:Linux:*:*) + eval $set_cc_for_build + sed 's/^ //' << EOF >$dummy.c + #undef CPU + #undef mips64 + #undef mips64el + #if defined(__MIPSEL__) || defined(__MIPSEL) || defined(_MIPSEL) || defined(MIPSEL) + CPU=mips64el + #else + #if defined(__MIPSEB__) || defined(__MIPSEB) || defined(_MIPSEB) || defined(MIPSEB) + CPU=mips64 + #else + CPU= + #endif + #endif +EOF + eval `$CC_FOR_BUILD -E $dummy.c 2>/dev/null | grep ^CPU=` + test x"${CPU}" != x && echo "${CPU}-unknown-linux-gnu" && exit 0 + ;; + ppc:Linux:*:*) + echo powerpc-${VENDOR:-unknown}-linux-gnu + exit 0 ;; + ppc64:Linux:*:*) + echo powerpc64-${VENDOR:-unknown}-linux-gnu + exit 0 ;; + alpha:Linux:*:*) + case `sed -n '/^cpu model/s/^.*: \(.*\)/\1/p' < /proc/cpuinfo` in + EV5) UNAME_MACHINE=alphaev5 ;; + EV56) UNAME_MACHINE=alphaev56 ;; + PCA56) UNAME_MACHINE=alphapca56 ;; + PCA57) UNAME_MACHINE=alphapca56 ;; + EV6) UNAME_MACHINE=alphaev6 ;; + EV67) UNAME_MACHINE=alphaev67 ;; + EV68*) UNAME_MACHINE=alphaev68 ;; + esac + objdump --private-headers /bin/sh | grep ld.so.1 >/dev/null + if test "$?" = 0 ; then LIBC="libc1" ; else LIBC="" ; fi + echo ${UNAME_MACHINE}-unknown-linux-gnu${LIBC} + exit 0 ;; + parisc:Linux:*:* | hppa:Linux:*:*) + # Look for CPU level + case `grep '^cpu[^a-z]*:' /proc/cpuinfo 2>/dev/null | cut -d' ' -f2` in + PA7*) echo hppa1.1-unknown-linux-gnu ;; + PA8*) echo hppa2.0-unknown-linux-gnu ;; + *) echo hppa-unknown-linux-gnu ;; + esac + exit 0 ;; + parisc64:Linux:*:* | hppa64:Linux:*:*) + echo hppa64-unknown-linux-gnu + exit 0 ;; + s390:Linux:*:* | s390x:Linux:*:*) + echo ${UNAME_MACHINE}-${VENDOR:-ibm}-linux-gnu + exit 0 ;; + sh64*:Linux:*:*) + echo ${UNAME_MACHINE}-unknown-linux-gnu + exit 0 ;; + sh*:Linux:*:*) + echo ${UNAME_MACHINE}-unknown-linux-gnu + exit 0 ;; + sparc:Linux:*:* | sparc64:Linux:*:*) + echo ${UNAME_MACHINE}-unknown-linux-gnu + exit 0 ;; + x86_64:Linux:*:*) + echo x86_64-${VENDOR:-unknown}-linux-gnu + exit 0 ;; + i*86:Linux:*:*) + # The BFD linker knows what the default object file format is, so + # first see if it will tell us. cd to the root directory to prevent + # problems with other programs or directories called `ld' in the path. + # Set LC_ALL=C to ensure ld outputs messages in English. + ld_supported_targets=`cd /; LC_ALL=C ld --help 2>&1 \ + | sed -ne '/supported targets:/!d + s/[ ][ ]*/ /g + s/.*supported targets: *// + s/ .*// + p'` + case "$ld_supported_targets" in + elf32-i386) + TENTATIVE="${UNAME_MACHINE}-pc-linux-gnu" + ;; + a.out-i386-linux) + echo "${UNAME_MACHINE}-pc-linux-gnuaout" + exit 0 ;; + coff-i386) + echo "${UNAME_MACHINE}-pc-linux-gnucoff" + exit 0 ;; + "") + # Either a pre-BFD a.out linker (linux-gnuoldld) or + # one that does not give us useful --help. + echo "${UNAME_MACHINE}-pc-linux-gnuoldld" + exit 0 ;; + esac + # Determine whether the default compiler is a.out or elf + eval $set_cc_for_build + sed 's/^ //' << EOF >$dummy.c + #include <features.h> + #ifdef __ELF__ + # ifdef __GLIBC__ + # if __GLIBC__ >= 2 + LIBC=gnu + # else + LIBC=gnulibc1 + # endif + # else + LIBC=gnulibc1 + # endif + #else + #ifdef __INTEL_COMPILER + LIBC=gnu + #else + LIBC=gnuaout + #endif + #endif +EOF + eval `$CC_FOR_BUILD -E $dummy.c 2>/dev/null | grep ^LIBC=` + test x"${LIBC}" != x && echo "${UNAME_MACHINE}-${VENDOR:-pc}-linux-${LIBC}" && exit 0 + test x"${TENTATIVE}" != x && echo "${TENTATIVE}" && exit 0 + ;; + i*86:DYNIX/ptx:4*:*) + # ptx 4.0 does uname -s correctly, with DYNIX/ptx in there. + # earlier versions are messed up and put the nodename in both + # sysname and nodename. + echo i386-sequent-sysv4 + exit 0 ;; + i*86:UNIX_SV:4.2MP:2.*) + # Unixware is an offshoot of SVR4, but it has its own version + # number series starting with 2... + # I am not positive that other SVR4 systems won't match this, + # I just have to hope. -- rms. + # Use sysv4.2uw... so that sysv4* matches it. + echo ${UNAME_MACHINE}-pc-sysv4.2uw${UNAME_VERSION} + exit 0 ;; + i*86:OS/2:*:*) + # If we were able to find `uname', then EMX Unix compatibility + # is probably installed. + echo ${UNAME_MACHINE}-pc-os2-emx + exit 0 ;; + i*86:XTS-300:*:STOP) + echo ${UNAME_MACHINE}-unknown-stop + exit 0 ;; + i*86:atheos:*:*) + echo ${UNAME_MACHINE}-unknown-atheos + exit 0 ;; + i*86:LynxOS:2.*:* | i*86:LynxOS:3.[01]*:* | i*86:LynxOS:4.0*:*) + echo i386-unknown-lynxos${UNAME_RELEASE} + exit 0 ;; + i*86:*DOS:*:*) + echo ${UNAME_MACHINE}-pc-msdosdjgpp + exit 0 ;; + i*86:*:4.*:* | i*86:SYSTEM_V:4.*:*) + UNAME_REL=`echo ${UNAME_RELEASE} | sed 's/\/MP$//'` + if grep Novell /usr/include/link.h >/dev/null 2>/dev/null; then + echo ${UNAME_MACHINE}-univel-sysv${UNAME_REL} + else + echo ${UNAME_MACHINE}-pc-sysv${UNAME_REL} + fi + exit 0 ;; + i*86:*:5:[78]*) + case `/bin/uname -X | grep "^Machine"` in + *486*) UNAME_MACHINE=i486 ;; + *Pentium) UNAME_MACHINE=i586 ;; + *Pent*|*Celeron) UNAME_MACHINE=i686 ;; + esac + echo ${UNAME_MACHINE}-unknown-sysv${UNAME_RELEASE}${UNAME_SYSTEM}${UNAME_VERSION} + exit 0 ;; + i*86:*:3.2:*) + if test -f /usr/options/cb.name; then + UNAME_REL=`sed -n 's/.*Version //p' </usr/options/cb.name` + echo ${UNAME_MACHINE}-pc-isc$UNAME_REL + elif /bin/uname -X 2>/dev/null >/dev/null ; then + UNAME_REL=`(/bin/uname -X|grep Release|sed -e 's/.*= //')` + (/bin/uname -X|grep i80486 >/dev/null) && UNAME_MACHINE=i486 + (/bin/uname -X|grep '^Machine.*Pentium' >/dev/null) \ + && UNAME_MACHINE=i586 + (/bin/uname -X|grep '^Machine.*Pent *II' >/dev/null) \ + && UNAME_MACHINE=i686 + (/bin/uname -X|grep '^Machine.*Pentium Pro' >/dev/null) \ + && UNAME_MACHINE=i686 + echo ${UNAME_MACHINE}-pc-sco$UNAME_REL + else + echo ${UNAME_MACHINE}-pc-sysv32 + fi + exit 0 ;; + pc:*:*:*) + # Left here for compatibility: + # uname -m prints for DJGPP always 'pc', but it prints nothing about + # the processor, so we play safe by assuming i386. + echo i386-pc-msdosdjgpp + exit 0 ;; + Intel:Mach:3*:*) + echo i386-pc-mach3 + exit 0 ;; + paragon:*:*:*) + echo i860-intel-osf1 + exit 0 ;; + i860:*:4.*:*) # i860-SVR4 + if grep Stardent /usr/include/sys/uadmin.h >/dev/null 2>&1 ; then + echo i860-stardent-sysv${UNAME_RELEASE} # Stardent Vistra i860-SVR4 + else # Add other i860-SVR4 vendors below as they are discovered. + echo i860-unknown-sysv${UNAME_RELEASE} # Unknown i860-SVR4 + fi + exit 0 ;; + mini*:CTIX:SYS*5:*) + # "miniframe" + echo m68010-convergent-sysv + exit 0 ;; + mc68k:UNIX:SYSTEM5:3.51m) + echo m68k-convergent-sysv + exit 0 ;; + M680?0:D-NIX:5.3:*) + echo m68k-diab-dnix + exit 0 ;; + M68*:*:R3V[567]*:*) + test -r /sysV68 && echo 'm68k-motorola-sysv' && exit 0 ;; + 3[34]??:*:4.0:3.0 | 3[34]??A:*:4.0:3.0 | 3[34]??,*:*:4.0:3.0 | 3[34]??/*:*:4.0:3.0 | 4400:*:4.0:3.0 | 4850:*:4.0:3.0 | SKA40:*:4.0:3.0 | SDS2:*:4.0:3.0 | SHG2:*:4.0:3.0) + OS_REL='' + test -r /etc/.relid \ + && OS_REL=.`sed -n 's/[^ ]* [^ ]* \([0-9][0-9]\).*/\1/p' < /etc/.relid` + /bin/uname -p 2>/dev/null | grep 86 >/dev/null \ + && echo i486-ncr-sysv4.3${OS_REL} && exit 0 + /bin/uname -p 2>/dev/null | /bin/grep entium >/dev/null \ + && echo i586-ncr-sysv4.3${OS_REL} && exit 0 ;; + 3[34]??:*:4.0:* | 3[34]??,*:*:4.0:*) + /bin/uname -p 2>/dev/null | grep 86 >/dev/null \ + && echo i486-ncr-sysv4 && exit 0 ;; + m68*:LynxOS:2.*:* | m68*:LynxOS:3.0*:*) + echo m68k-unknown-lynxos${UNAME_RELEASE} + exit 0 ;; + mc68030:UNIX_System_V:4.*:*) + echo m68k-atari-sysv4 + exit 0 ;; + TSUNAMI:LynxOS:2.*:*) + echo sparc-unknown-lynxos${UNAME_RELEASE} + exit 0 ;; + rs6000:LynxOS:2.*:*) + echo rs6000-unknown-lynxos${UNAME_RELEASE} + exit 0 ;; + PowerPC:LynxOS:2.*:* | PowerPC:LynxOS:3.[01]*:* | PowerPC:LynxOS:4.0*:*) + echo powerpc-unknown-lynxos${UNAME_RELEASE} + exit 0 ;; + SM[BE]S:UNIX_SV:*:*) + echo mips-dde-sysv${UNAME_RELEASE} + exit 0 ;; + RM*:ReliantUNIX-*:*:*) + echo mips-sni-sysv4 + exit 0 ;; + RM*:SINIX-*:*:*) + echo mips-sni-sysv4 + exit 0 ;; + *:SINIX-*:*:*) + if uname -p 2>/dev/null >/dev/null ; then + UNAME_MACHINE=`(uname -p) 2>/dev/null` + echo ${UNAME_MACHINE}-sni-sysv4 + else + echo ns32k-sni-sysv + fi + exit 0 ;; + PENTIUM:*:4.0*:*) # Unisys `ClearPath HMP IX 4000' SVR4/MP effort + # says <Richard.M.Bartel@ccMail.Census.GOV> + echo i586-unisys-sysv4 + exit 0 ;; + *:UNIX_System_V:4*:FTX*) + # From Gerald Hewes <hewes@openmarket.com>. + # How about differentiating between stratus architectures? -djm + echo hppa1.1-stratus-sysv4 + exit 0 ;; + *:*:*:FTX*) + # From seanf@swdc.stratus.com. + echo i860-stratus-sysv4 + exit 0 ;; + *:VOS:*:*) + # From Paul.Green@stratus.com. + echo hppa1.1-stratus-vos + exit 0 ;; + mc68*:A/UX:*:*) + echo m68k-apple-aux${UNAME_RELEASE} + exit 0 ;; + news*:NEWS-OS:6*:*) + echo mips-sony-newsos6 + exit 0 ;; + R[34]000:*System_V*:*:* | R4000:UNIX_SYSV:*:* | R*000:UNIX_SV:*:*) + if [ -d /usr/nec ]; then + echo mips-nec-sysv${UNAME_RELEASE} + else + echo mips-unknown-sysv${UNAME_RELEASE} + fi + exit 0 ;; + BeBox:BeOS:*:*) # BeOS running on hardware made by Be, PPC only. + echo powerpc-be-beos + exit 0 ;; + BeMac:BeOS:*:*) # BeOS running on Mac or Mac clone, PPC only. + echo powerpc-apple-beos + exit 0 ;; + BePC:BeOS:*:*) # BeOS running on Intel PC compatible. + echo i586-pc-beos + exit 0 ;; + SX-4:SUPER-UX:*:*) + echo sx4-nec-superux${UNAME_RELEASE} + exit 0 ;; + SX-5:SUPER-UX:*:*) + echo sx5-nec-superux${UNAME_RELEASE} + exit 0 ;; + SX-6:SUPER-UX:*:*) + echo sx6-nec-superux${UNAME_RELEASE} + exit 0 ;; + Power*:Rhapsody:*:*) + echo powerpc-apple-rhapsody${UNAME_RELEASE} + exit 0 ;; + *:Rhapsody:*:*) + echo ${UNAME_MACHINE}-apple-rhapsody${UNAME_RELEASE} + exit 0 ;; + *:Darwin:*:*) + case `uname -p` in + *86) UNAME_PROCESSOR=i686 ;; + powerpc) UNAME_PROCESSOR=powerpc ;; + esac + echo ${UNAME_PROCESSOR}-apple-darwin${UNAME_RELEASE} + exit 0 ;; + *:procnto*:*:* | *:QNX:[0123456789]*:*) + UNAME_PROCESSOR=`uname -p` + if test "$UNAME_PROCESSOR" = "x86"; then + UNAME_PROCESSOR=i386 + UNAME_MACHINE=pc + fi + echo ${UNAME_PROCESSOR}-${UNAME_MACHINE}-nto-qnx${UNAME_RELEASE} + exit 0 ;; + *:QNX:*:4*) + echo i386-pc-qnx + exit 0 ;; + NSR-[DGKLNPTVW]:NONSTOP_KERNEL:*:*) + echo nsr-tandem-nsk${UNAME_RELEASE} + exit 0 ;; + *:NonStop-UX:*:*) + echo mips-compaq-nonstopux + exit 0 ;; + BS2000:POSIX*:*:*) + echo bs2000-siemens-sysv + exit 0 ;; + DS/*:UNIX_System_V:*:*) + echo ${UNAME_MACHINE}-${UNAME_SYSTEM}-${UNAME_RELEASE} + exit 0 ;; + *:Plan9:*:*) + # "uname -m" is not consistent, so use $cputype instead. 386 + # is converted to i386 for consistency with other x86 + # operating systems. + if test "$cputype" = "386"; then + UNAME_MACHINE=i386 + else + UNAME_MACHINE="$cputype" + fi + echo ${UNAME_MACHINE}-unknown-plan9 + exit 0 ;; + *:TOPS-10:*:*) + echo pdp10-unknown-tops10 + exit 0 ;; + *:TENEX:*:*) + echo pdp10-unknown-tenex + exit 0 ;; + KS10:TOPS-20:*:* | KL10:TOPS-20:*:* | TYPE4:TOPS-20:*:*) + echo pdp10-dec-tops20 + exit 0 ;; + XKL-1:TOPS-20:*:* | TYPE5:TOPS-20:*:*) + echo pdp10-xkl-tops20 + exit 0 ;; + *:TOPS-20:*:*) + echo pdp10-unknown-tops20 + exit 0 ;; + *:ITS:*:*) + echo pdp10-unknown-its + exit 0 ;; + SEI:*:*:SEIUX) + echo mips-sei-seiux${UNAME_RELEASE} + exit 0 ;; +esac + +#echo '(No uname command or uname output not recognized.)' 1>&2 +#echo "${UNAME_MACHINE}:${UNAME_SYSTEM}:${UNAME_RELEASE}:${UNAME_VERSION}" 1>&2 + +eval $set_cc_for_build +cat >$dummy.c <<EOF +#ifdef _SEQUENT_ +# include <sys/types.h> +# include <sys/utsname.h> +#endif +main () +{ +#if defined (sony) +#if defined (MIPSEB) + /* BFD wants "bsd" instead of "newsos". Perhaps BFD should be changed, + I don't know.... */ + printf ("mips-sony-bsd\n"); exit (0); +#else +#include <sys/param.h> + printf ("m68k-sony-newsos%s\n", +#ifdef NEWSOS4 + "4" +#else + "" +#endif + ); exit (0); +#endif +#endif + +#if defined (__arm) && defined (__acorn) && defined (__unix) + printf ("arm-acorn-riscix"); exit (0); +#endif + +#if defined (hp300) && !defined (hpux) + printf ("m68k-hp-bsd\n"); exit (0); +#endif + +#if defined (NeXT) +#if !defined (__ARCHITECTURE__) +#define __ARCHITECTURE__ "m68k" +#endif + int version; + version=`(hostinfo | sed -n 's/.*NeXT Mach \([0-9]*\).*/\1/p') 2>/dev/null`; + if (version < 4) + printf ("%s-next-nextstep%d\n", __ARCHITECTURE__, version); + else + printf ("%s-next-openstep%d\n", __ARCHITECTURE__, version); + exit (0); +#endif + +#if defined (MULTIMAX) || defined (n16) +#if defined (UMAXV) + printf ("ns32k-encore-sysv\n"); exit (0); +#else +#if defined (CMU) + printf ("ns32k-encore-mach\n"); exit (0); +#else + printf ("ns32k-encore-bsd\n"); exit (0); +#endif +#endif +#endif + +#if defined (__386BSD__) + printf ("i386-pc-bsd\n"); exit (0); +#endif + +#if defined (sequent) +#if defined (i386) + printf ("i386-sequent-dynix\n"); exit (0); +#endif +#if defined (ns32000) + printf ("ns32k-sequent-dynix\n"); exit (0); +#endif +#endif + +#if defined (_SEQUENT_) + struct utsname un; + + uname(&un); + + if (strncmp(un.version, "V2", 2) == 0) { + printf ("i386-sequent-ptx2\n"); exit (0); + } + if (strncmp(un.version, "V1", 2) == 0) { /* XXX is V1 correct? */ + printf ("i386-sequent-ptx1\n"); exit (0); + } + printf ("i386-sequent-ptx\n"); exit (0); + +#endif + +#if defined (vax) +# if !defined (ultrix) +# include <sys/param.h> +# if defined (BSD) +# if BSD == 43 + printf ("vax-dec-bsd4.3\n"); exit (0); +# else +# if BSD == 199006 + printf ("vax-dec-bsd4.3reno\n"); exit (0); +# else + printf ("vax-dec-bsd\n"); exit (0); +# endif +# endif +# else + printf ("vax-dec-bsd\n"); exit (0); +# endif +# else + printf ("vax-dec-ultrix\n"); exit (0); +# endif +#endif + +#if defined (alliant) && defined (i860) + printf ("i860-alliant-bsd\n"); exit (0); +#endif + + exit (1); +} +EOF + +$CC_FOR_BUILD -o $dummy $dummy.c 2>/dev/null && $dummy && exit 0 + +# Apollos put the system type in the environment. + +test -d /usr/apollo && { echo ${ISP}-apollo-${SYSTYPE}; exit 0; } + +# Convex versions that predate uname can use getsysinfo(1) + +if [ -x /usr/convex/getsysinfo ] +then + case `getsysinfo -f cpu_type` in + c1*) + echo c1-convex-bsd + exit 0 ;; + c2*) + if getsysinfo -f scalar_acc + then echo c32-convex-bsd + else echo c2-convex-bsd + fi + exit 0 ;; + c34*) + echo c34-convex-bsd + exit 0 ;; + c38*) + echo c38-convex-bsd + exit 0 ;; + c4*) + echo c4-convex-bsd + exit 0 ;; + esac +fi + +cat >&2 <<EOF +$0: unable to guess system type + +This script, last modified $timestamp, has failed to recognize +the operating system you are using. It is advised that you +download the most up to date version of the config scripts from + + ftp://ftp.gnu.org/pub/gnu/config/ + +If the version you run ($0) is already up to date, please +send the following data and any information you think might be +pertinent to <config-patches@gnu.org> in order to provide the needed +information to handle your system. + +config.guess timestamp = $timestamp + +uname -m = `(uname -m) 2>/dev/null || echo unknown` +uname -r = `(uname -r) 2>/dev/null || echo unknown` +uname -s = `(uname -s) 2>/dev/null || echo unknown` +uname -v = `(uname -v) 2>/dev/null || echo unknown` + +/usr/bin/uname -p = `(/usr/bin/uname -p) 2>/dev/null` +/bin/uname -X = `(/bin/uname -X) 2>/dev/null` + +hostinfo = `(hostinfo) 2>/dev/null` +/bin/universe = `(/bin/universe) 2>/dev/null` +/usr/bin/arch -k = `(/usr/bin/arch -k) 2>/dev/null` +/bin/arch = `(/bin/arch) 2>/dev/null` +/usr/bin/oslevel = `(/usr/bin/oslevel) 2>/dev/null` +/usr/convex/getsysinfo = `(/usr/convex/getsysinfo) 2>/dev/null` + +UNAME_MACHINE = ${UNAME_MACHINE} +UNAME_RELEASE = ${UNAME_RELEASE} +UNAME_SYSTEM = ${UNAME_SYSTEM} +UNAME_VERSION = ${UNAME_VERSION} +EOF + +exit 1 + +# Local variables: +# eval: (add-hook 'write-file-hooks 'time-stamp) +# time-stamp-start: "timestamp='" +# time-stamp-format: "%:y-%02m-%02d" +# time-stamp-end: "'" +# End: diff --git a/AMDiS/config.sub b/AMDiS/config.sub new file mode 100755 index 0000000000000000000000000000000000000000..6b2ff9f6a7a89034532915972c4a1034fddf5bce --- /dev/null +++ b/AMDiS/config.sub @@ -0,0 +1,1500 @@ +#! /bin/sh +# Configuration validation subroutine script. +# Copyright (C) 1992, 1993, 1994, 1995, 1996, 1997, 1998, 1999, +# 2000, 2001, 2002, 2003 Free Software Foundation, Inc. + +timestamp='2003-06-18' + +# This file is (in principle) common to ALL GNU software. +# The presence of a machine in this file suggests that SOME GNU software +# can handle that machine. It does not imply ALL GNU software can. +# +# This file 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., 59 Temple Place - Suite 330, +# Boston, MA 02111-1307, USA. + +# As a special exception to the GNU General Public License, if you +# distribute this file as part of a program that contains a +# configuration script generated by Autoconf, you may include it under +# the same distribution terms that you use for the rest of that program. + +# Please send patches to <config-patches@gnu.org>. Submit a context +# diff and a properly formatted ChangeLog entry. +# +# Configuration subroutine to validate and canonicalize a configuration type. +# Supply the specified configuration type as an argument. +# If it is invalid, we print an error message on stderr and exit with code 1. +# Otherwise, we print the canonical config type on stdout and succeed. + +# This file is supposed to be the same for all GNU packages +# and recognize all the CPU types, system types and aliases +# that are meaningful with *any* GNU software. +# Each package is responsible for reporting which valid configurations +# it does not support. The user should be able to distinguish +# a failure to support a valid configuration from a meaningless +# configuration. + +# The goal of this file is to map all the various variations of a given +# machine specification into a single specification in the form: +# CPU_TYPE-MANUFACTURER-OPERATING_SYSTEM +# or in some cases, the newer four-part form: +# CPU_TYPE-MANUFACTURER-KERNEL-OPERATING_SYSTEM +# It is wrong to echo any other type of specification. + +me=`echo "$0" | sed -e 's,.*/,,'` + +usage="\ +Usage: $0 [OPTION] CPU-MFR-OPSYS + $0 [OPTION] ALIAS + +Canonicalize a configuration name. + +Operation modes: + -h, --help print this help, then exit + -t, --time-stamp print date of last modification, then exit + -v, --version print version number, then exit + +Report bugs and patches to <config-patches@gnu.org>." + +version="\ +GNU config.sub ($timestamp) + +Copyright (C) 1992, 1993, 1994, 1995, 1996, 1997, 1998, 1999, 2000, 2001 +Free Software Foundation, Inc. + +This is free software; see the source for copying conditions. There is NO +warranty; not even for MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE." + +help=" +Try \`$me --help' for more information." + +# Parse command line +while test $# -gt 0 ; do + case $1 in + --time-stamp | --time* | -t ) + echo "$timestamp" ; exit 0 ;; + --version | -v ) + echo "$version" ; exit 0 ;; + --help | --h* | -h ) + echo "$usage"; exit 0 ;; + -- ) # Stop option processing + shift; break ;; + - ) # Use stdin as input. + break ;; + -* ) + echo "$me: invalid option $1$help" + exit 1 ;; + + *local*) + # First pass through any local machine types. + echo $1 + exit 0;; + + * ) + break ;; + esac +done + +case $# in + 0) echo "$me: missing argument$help" >&2 + exit 1;; + 1) ;; + *) echo "$me: too many arguments$help" >&2 + exit 1;; +esac + +# Separate what the user gave into CPU-COMPANY and OS or KERNEL-OS (if any). +# Here we must recognize all the valid KERNEL-OS combinations. +maybe_os=`echo $1 | sed 's/^\(.*\)-\([^-]*-[^-]*\)$/\2/'` +case $maybe_os in + nto-qnx* | linux-gnu* | freebsd*-gnu* | netbsd*-gnu* | storm-chaos* | os2-emx* | rtmk-nova*) + os=-$maybe_os + basic_machine=`echo $1 | sed 's/^\(.*\)-\([^-]*-[^-]*\)$/\1/'` + ;; + *) + basic_machine=`echo $1 | sed 's/-[^-]*$//'` + if [ $basic_machine != $1 ] + then os=`echo $1 | sed 's/.*-/-/'` + else os=; fi + ;; +esac + +### Let's recognize common machines as not being operating systems so +### that things like config.sub decstation-3100 work. We also +### recognize some manufacturers as not being operating systems, so we +### can provide default operating systems below. +case $os in + -sun*os*) + # Prevent following clause from handling this invalid input. + ;; + -dec* | -mips* | -sequent* | -encore* | -pc532* | -sgi* | -sony* | \ + -att* | -7300* | -3300* | -delta* | -motorola* | -sun[234]* | \ + -unicom* | -ibm* | -next | -hp | -isi* | -apollo | -altos* | \ + -convergent* | -ncr* | -news | -32* | -3600* | -3100* | -hitachi* |\ + -c[123]* | -convex* | -sun | -crds | -omron* | -dg | -ultra | -tti* | \ + -harris | -dolphin | -highlevel | -gould | -cbm | -ns | -masscomp | \ + -apple | -axis) + os= + basic_machine=$1 + ;; + -sim | -cisco | -oki | -wec | -winbond) + os= + basic_machine=$1 + ;; + -scout) + ;; + -wrs) + os=-vxworks + basic_machine=$1 + ;; + -chorusos*) + os=-chorusos + basic_machine=$1 + ;; + -chorusrdb) + os=-chorusrdb + basic_machine=$1 + ;; + -hiux*) + os=-hiuxwe2 + ;; + -sco5) + os=-sco3.2v5 + basic_machine=`echo $1 | sed -e 's/86-.*/86-pc/'` + ;; + -sco4) + os=-sco3.2v4 + basic_machine=`echo $1 | sed -e 's/86-.*/86-pc/'` + ;; + -sco3.2.[4-9]*) + os=`echo $os | sed -e 's/sco3.2./sco3.2v/'` + basic_machine=`echo $1 | sed -e 's/86-.*/86-pc/'` + ;; + -sco3.2v[4-9]*) + # Don't forget version if it is 3.2v4 or newer. + basic_machine=`echo $1 | sed -e 's/86-.*/86-pc/'` + ;; + -sco*) + os=-sco3.2v2 + basic_machine=`echo $1 | sed -e 's/86-.*/86-pc/'` + ;; + -udk*) + basic_machine=`echo $1 | sed -e 's/86-.*/86-pc/'` + ;; + -isc) + os=-isc2.2 + basic_machine=`echo $1 | sed -e 's/86-.*/86-pc/'` + ;; + -clix*) + basic_machine=clipper-intergraph + ;; + -isc*) + basic_machine=`echo $1 | sed -e 's/86-.*/86-pc/'` + ;; + -lynx*) + os=-lynxos + ;; + -ptx*) + basic_machine=`echo $1 | sed -e 's/86-.*/86-sequent/'` + ;; + -windowsnt*) + os=`echo $os | sed -e 's/windowsnt/winnt/'` + ;; + -psos*) + os=-psos + ;; + -mint | -mint[0-9]*) + basic_machine=m68k-atari + os=-mint + ;; +esac + +# Decode aliases for certain CPU-COMPANY combinations. +case $basic_machine in + # Recognize the basic CPU types without company name. + # Some are omitted here because they have special meanings below. + 1750a | 580 \ + | a29k \ + | alpha | alphaev[4-8] | alphaev56 | alphaev6[78] | alphapca5[67] \ + | alpha64 | alpha64ev[4-8] | alpha64ev56 | alpha64ev6[78] | alpha64pca5[67] \ + | arc | arm | arm[bl]e | arme[lb] | armv[2345] | armv[345][lb] | avr \ + | c4x | clipper \ + | d10v | d30v | dlx | dsp16xx \ + | fr30 | frv \ + | h8300 | h8500 | hppa | hppa1.[01] | hppa2.0 | hppa2.0[nw] | hppa64 \ + | i370 | i860 | i960 | ia64 \ + | ip2k \ + | m32r | m68000 | m68k | m88k | mcore \ + | mips | mipsbe | mipseb | mipsel | mipsle \ + | mips16 \ + | mips64 | mips64el \ + | mips64vr | mips64vrel \ + | mips64orion | mips64orionel \ + | mips64vr4100 | mips64vr4100el \ + | mips64vr4300 | mips64vr4300el \ + | mips64vr5000 | mips64vr5000el \ + | mipsisa32 | mipsisa32el \ + | mipsisa32r2 | mipsisa32r2el \ + | mipsisa64 | mipsisa64el \ + | mipsisa64sb1 | mipsisa64sb1el \ + | mipsisa64sr71k | mipsisa64sr71kel \ + | mipstx39 | mipstx39el \ + | mn10200 | mn10300 \ + | msp430 \ + | ns16k | ns32k \ + | openrisc | or32 \ + | pdp10 | pdp11 | pj | pjl \ + | powerpc | powerpc64 | powerpc64le | powerpcle | ppcbe \ + | pyramid \ + | s390 | s390x \ + | sh | sh[1234] | sh[23]e | sh[34]eb | shbe | shle | sh[1234]le | sh3ele \ + | sh64 | sh64le \ + | sparc | sparc64 | sparc86x | sparclet | sparclite | sparcv8 | sparcv9 | sparcv9b \ + | strongarm \ + | tahoe | thumb | tic4x | tic80 | tron \ + | v850 | v850e \ + | we32k \ + | x86 | xscale | xstormy16 | xtensa \ + | z8k) + basic_machine=$basic_machine-unknown + ;; + m6811 | m68hc11 | m6812 | m68hc12) + # Motorola 68HC11/12. + basic_machine=$basic_machine-unknown + os=-none + ;; + m88110 | m680[12346]0 | m683?2 | m68360 | m5200 | v70 | w65 | z8k) + ;; + + # We use `pc' rather than `unknown' + # because (1) that's what they normally are, and + # (2) the word "unknown" tends to confuse beginning users. + i*86 | x86_64) + basic_machine=$basic_machine-pc + ;; + # Object if more than one company name word. + *-*-*) + echo Invalid configuration \`$1\': machine \`$basic_machine\' not recognized 1>&2 + exit 1 + ;; + # Recognize the basic CPU types with company name. + 580-* \ + | a29k-* \ + | alpha-* | alphaev[4-8]-* | alphaev56-* | alphaev6[78]-* \ + | alpha64-* | alpha64ev[4-8]-* | alpha64ev56-* | alpha64ev6[78]-* \ + | alphapca5[67]-* | alpha64pca5[67]-* | arc-* \ + | arm-* | armbe-* | armle-* | armeb-* | armv*-* \ + | avr-* \ + | bs2000-* \ + | c[123]* | c30-* | [cjt]90-* | c4x-* | c54x-* | c55x-* | c6x-* \ + | clipper-* | cydra-* \ + | d10v-* | d30v-* | dlx-* \ + | elxsi-* \ + | f30[01]-* | f700-* | fr30-* | frv-* | fx80-* \ + | h8300-* | h8500-* \ + | hppa-* | hppa1.[01]-* | hppa2.0-* | hppa2.0[nw]-* | hppa64-* \ + | i*86-* | i860-* | i960-* | ia64-* \ + | ip2k-* \ + | m32r-* \ + | m68000-* | m680[012346]0-* | m68360-* | m683?2-* | m68k-* \ + | m88110-* | m88k-* | mcore-* \ + | mips-* | mipsbe-* | mipseb-* | mipsel-* | mipsle-* \ + | mips16-* \ + | mips64-* | mips64el-* \ + | mips64vr-* | mips64vrel-* \ + | mips64orion-* | mips64orionel-* \ + | mips64vr4100-* | mips64vr4100el-* \ + | mips64vr4300-* | mips64vr4300el-* \ + | mips64vr5000-* | mips64vr5000el-* \ + | mipsisa32-* | mipsisa32el-* \ + | mipsisa32r2-* | mipsisa32r2el-* \ + | mipsisa64-* | mipsisa64el-* \ + | mipsisa64sb1-* | mipsisa64sb1el-* \ + | mipsisa64sr71k-* | mipsisa64sr71kel-* \ + | mipstx39-* | mipstx39el-* \ + | msp430-* \ + | none-* | np1-* | nv1-* | ns16k-* | ns32k-* \ + | orion-* \ + | pdp10-* | pdp11-* | pj-* | pjl-* | pn-* | power-* \ + | powerpc-* | powerpc64-* | powerpc64le-* | powerpcle-* | ppcbe-* \ + | pyramid-* \ + | romp-* | rs6000-* \ + | s390-* | s390x-* \ + | sh-* | sh[1234]-* | sh[23]e-* | sh[34]eb-* | shbe-* \ + | shle-* | sh[1234]le-* | sh3ele-* | sh64-* | sh64le-* \ + | sparc-* | sparc64-* | sparc86x-* | sparclet-* | sparclite-* \ + | sparcv8-* | sparcv9-* | sparcv9b-* | strongarm-* | sv1-* | sx?-* \ + | tahoe-* | thumb-* \ + | tic30-* | tic4x-* | tic54x-* | tic55x-* | tic6x-* | tic80-* \ + | tron-* \ + | v850-* | v850e-* | vax-* \ + | we32k-* \ + | x86-* | x86_64-* | xps100-* | xscale-* | xstormy16-* \ + | xtensa-* \ + | ymp-* \ + | z8k-*) + ;; + # Recognize the various machine names and aliases which stand + # for a CPU type and a company and sometimes even an OS. + 386bsd) + basic_machine=i386-unknown + os=-bsd + ;; + 3b1 | 7300 | 7300-att | att-7300 | pc7300 | safari | unixpc) + basic_machine=m68000-att + ;; + 3b*) + basic_machine=we32k-att + ;; + a29khif) + basic_machine=a29k-amd + os=-udi + ;; + adobe68k) + basic_machine=m68010-adobe + os=-scout + ;; + alliant | fx80) + basic_machine=fx80-alliant + ;; + altos | altos3068) + basic_machine=m68k-altos + ;; + am29k) + basic_machine=a29k-none + os=-bsd + ;; + amd64) + basic_machine=x86_64-pc + ;; + amdahl) + basic_machine=580-amdahl + os=-sysv + ;; + amiga | amiga-*) + basic_machine=m68k-unknown + ;; + amigaos | amigados) + basic_machine=m68k-unknown + os=-amigaos + ;; + amigaunix | amix) + basic_machine=m68k-unknown + os=-sysv4 + ;; + apollo68) + basic_machine=m68k-apollo + os=-sysv + ;; + apollo68bsd) + basic_machine=m68k-apollo + os=-bsd + ;; + aux) + basic_machine=m68k-apple + os=-aux + ;; + balance) + basic_machine=ns32k-sequent + os=-dynix + ;; + c90) + basic_machine=c90-cray + os=-unicos + ;; + convex-c1) + basic_machine=c1-convex + os=-bsd + ;; + convex-c2) + basic_machine=c2-convex + os=-bsd + ;; + convex-c32) + basic_machine=c32-convex + os=-bsd + ;; + convex-c34) + basic_machine=c34-convex + os=-bsd + ;; + convex-c38) + basic_machine=c38-convex + os=-bsd + ;; + cray | j90) + basic_machine=j90-cray + os=-unicos + ;; + crds | unos) + basic_machine=m68k-crds + ;; + cris | cris-* | etrax*) + basic_machine=cris-axis + ;; + da30 | da30-*) + basic_machine=m68k-da30 + ;; + decstation | decstation-3100 | pmax | pmax-* | pmin | dec3100 | decstatn) + basic_machine=mips-dec + ;; + decsystem10* | dec10*) + basic_machine=pdp10-dec + os=-tops10 + ;; + decsystem20* | dec20*) + basic_machine=pdp10-dec + os=-tops20 + ;; + delta | 3300 | motorola-3300 | motorola-delta \ + | 3300-motorola | delta-motorola) + basic_machine=m68k-motorola + ;; + delta88) + basic_machine=m88k-motorola + os=-sysv3 + ;; + dpx20 | dpx20-*) + basic_machine=rs6000-bull + os=-bosx + ;; + dpx2* | dpx2*-bull) + basic_machine=m68k-bull + os=-sysv3 + ;; + ebmon29k) + basic_machine=a29k-amd + os=-ebmon + ;; + elxsi) + basic_machine=elxsi-elxsi + os=-bsd + ;; + encore | umax | mmax) + basic_machine=ns32k-encore + ;; + es1800 | OSE68k | ose68k | ose | OSE) + basic_machine=m68k-ericsson + os=-ose + ;; + fx2800) + basic_machine=i860-alliant + ;; + genix) + basic_machine=ns32k-ns + ;; + gmicro) + basic_machine=tron-gmicro + os=-sysv + ;; + go32) + basic_machine=i386-pc + os=-go32 + ;; + h3050r* | hiux*) + basic_machine=hppa1.1-hitachi + os=-hiuxwe2 + ;; + h8300hms) + basic_machine=h8300-hitachi + os=-hms + ;; + h8300xray) + basic_machine=h8300-hitachi + os=-xray + ;; + h8500hms) + basic_machine=h8500-hitachi + os=-hms + ;; + harris) + basic_machine=m88k-harris + os=-sysv3 + ;; + hp300-*) + basic_machine=m68k-hp + ;; + hp300bsd) + basic_machine=m68k-hp + os=-bsd + ;; + hp300hpux) + basic_machine=m68k-hp + os=-hpux + ;; + hp3k9[0-9][0-9] | hp9[0-9][0-9]) + basic_machine=hppa1.0-hp + ;; + hp9k2[0-9][0-9] | hp9k31[0-9]) + basic_machine=m68000-hp + ;; + hp9k3[2-9][0-9]) + basic_machine=m68k-hp + ;; + hp9k6[0-9][0-9] | hp6[0-9][0-9]) + basic_machine=hppa1.0-hp + ;; + hp9k7[0-79][0-9] | hp7[0-79][0-9]) + basic_machine=hppa1.1-hp + ;; + hp9k78[0-9] | hp78[0-9]) + # FIXME: really hppa2.0-hp + basic_machine=hppa1.1-hp + ;; + hp9k8[67]1 | hp8[67]1 | hp9k80[24] | hp80[24] | hp9k8[78]9 | hp8[78]9 | hp9k893 | hp893) + # FIXME: really hppa2.0-hp + basic_machine=hppa1.1-hp + ;; + hp9k8[0-9][13679] | hp8[0-9][13679]) + basic_machine=hppa1.1-hp + ;; + hp9k8[0-9][0-9] | hp8[0-9][0-9]) + basic_machine=hppa1.0-hp + ;; + hppa-next) + os=-nextstep3 + ;; + hppaosf) + basic_machine=hppa1.1-hp + os=-osf + ;; + hppro) + basic_machine=hppa1.1-hp + os=-proelf + ;; + i370-ibm* | ibm*) + basic_machine=i370-ibm + ;; +# I'm not sure what "Sysv32" means. Should this be sysv3.2? + i*86v32) + basic_machine=`echo $1 | sed -e 's/86.*/86-pc/'` + os=-sysv32 + ;; + i*86v4*) + basic_machine=`echo $1 | sed -e 's/86.*/86-pc/'` + os=-sysv4 + ;; + i*86v) + basic_machine=`echo $1 | sed -e 's/86.*/86-pc/'` + os=-sysv + ;; + i*86sol2) + basic_machine=`echo $1 | sed -e 's/86.*/86-pc/'` + os=-solaris2 + ;; + i386mach) + basic_machine=i386-mach + os=-mach + ;; + i386-vsta | vsta) + basic_machine=i386-unknown + os=-vsta + ;; + iris | iris4d) + basic_machine=mips-sgi + case $os in + -irix*) + ;; + *) + os=-irix4 + ;; + esac + ;; + isi68 | isi) + basic_machine=m68k-isi + os=-sysv + ;; + m88k-omron*) + basic_machine=m88k-omron + ;; + magnum | m3230) + basic_machine=mips-mips + os=-sysv + ;; + merlin) + basic_machine=ns32k-utek + os=-sysv + ;; + mingw32) + basic_machine=i386-pc + os=-mingw32 + ;; + miniframe) + basic_machine=m68000-convergent + ;; + *mint | -mint[0-9]* | *MiNT | *MiNT[0-9]*) + basic_machine=m68k-atari + os=-mint + ;; + mips3*-*) + basic_machine=`echo $basic_machine | sed -e 's/mips3/mips64/'` + ;; + mips3*) + basic_machine=`echo $basic_machine | sed -e 's/mips3/mips64/'`-unknown + ;; + mmix*) + basic_machine=mmix-knuth + os=-mmixware + ;; + monitor) + basic_machine=m68k-rom68k + os=-coff + ;; + morphos) + basic_machine=powerpc-unknown + os=-morphos + ;; + msdos) + basic_machine=i386-pc + os=-msdos + ;; + mvs) + basic_machine=i370-ibm + os=-mvs + ;; + ncr3000) + basic_machine=i486-ncr + os=-sysv4 + ;; + netbsd386) + basic_machine=i386-unknown + os=-netbsd + ;; + netwinder) + basic_machine=armv4l-rebel + os=-linux + ;; + news | news700 | news800 | news900) + basic_machine=m68k-sony + os=-newsos + ;; + news1000) + basic_machine=m68030-sony + os=-newsos + ;; + news-3600 | risc-news) + basic_machine=mips-sony + os=-newsos + ;; + necv70) + basic_machine=v70-nec + os=-sysv + ;; + next | m*-next ) + basic_machine=m68k-next + case $os in + -nextstep* ) + ;; + -ns2*) + os=-nextstep2 + ;; + *) + os=-nextstep3 + ;; + esac + ;; + nh3000) + basic_machine=m68k-harris + os=-cxux + ;; + nh[45]000) + basic_machine=m88k-harris + os=-cxux + ;; + nindy960) + basic_machine=i960-intel + os=-nindy + ;; + mon960) + basic_machine=i960-intel + os=-mon960 + ;; + nonstopux) + basic_machine=mips-compaq + os=-nonstopux + ;; + np1) + basic_machine=np1-gould + ;; + nv1) + basic_machine=nv1-cray + os=-unicosmp + ;; + nsr-tandem) + basic_machine=nsr-tandem + ;; + op50n-* | op60c-*) + basic_machine=hppa1.1-oki + os=-proelf + ;; + or32 | or32-*) + basic_machine=or32-unknown + os=-coff + ;; + OSE68000 | ose68000) + basic_machine=m68000-ericsson + os=-ose + ;; + os68k) + basic_machine=m68k-none + os=-os68k + ;; + pa-hitachi) + basic_machine=hppa1.1-hitachi + os=-hiuxwe2 + ;; + paragon) + basic_machine=i860-intel + os=-osf + ;; + pbd) + basic_machine=sparc-tti + ;; + pbb) + basic_machine=m68k-tti + ;; + pc532 | pc532-*) + basic_machine=ns32k-pc532 + ;; + pentium | p5 | k5 | k6 | nexgen | viac3) + basic_machine=i586-pc + ;; + pentiumpro | p6 | 6x86 | athlon | athlon_*) + basic_machine=i686-pc + ;; + pentiumii | pentium2 | pentiumiii | pentium3) + basic_machine=i686-pc + ;; + pentium4) + basic_machine=i786-pc + ;; + pentium-* | p5-* | k5-* | k6-* | nexgen-* | viac3-*) + basic_machine=i586-`echo $basic_machine | sed 's/^[^-]*-//'` + ;; + pentiumpro-* | p6-* | 6x86-* | athlon-*) + basic_machine=i686-`echo $basic_machine | sed 's/^[^-]*-//'` + ;; + pentiumii-* | pentium2-* | pentiumiii-* | pentium3-*) + basic_machine=i686-`echo $basic_machine | sed 's/^[^-]*-//'` + ;; + pentium4-*) + basic_machine=i786-`echo $basic_machine | sed 's/^[^-]*-//'` + ;; + pn) + basic_machine=pn-gould + ;; + power) basic_machine=power-ibm + ;; + ppc) basic_machine=powerpc-unknown + ;; + ppc-*) basic_machine=powerpc-`echo $basic_machine | sed 's/^[^-]*-//'` + ;; + ppcle | powerpclittle | ppc-le | powerpc-little) + basic_machine=powerpcle-unknown + ;; + ppcle-* | powerpclittle-*) + basic_machine=powerpcle-`echo $basic_machine | sed 's/^[^-]*-//'` + ;; + ppc64) basic_machine=powerpc64-unknown + ;; + ppc64-*) basic_machine=powerpc64-`echo $basic_machine | sed 's/^[^-]*-//'` + ;; + ppc64le | powerpc64little | ppc64-le | powerpc64-little) + basic_machine=powerpc64le-unknown + ;; + ppc64le-* | powerpc64little-*) + basic_machine=powerpc64le-`echo $basic_machine | sed 's/^[^-]*-//'` + ;; + ps2) + basic_machine=i386-ibm + ;; + pw32) + basic_machine=i586-unknown + os=-pw32 + ;; + rom68k) + basic_machine=m68k-rom68k + os=-coff + ;; + rm[46]00) + basic_machine=mips-siemens + ;; + rtpc | rtpc-*) + basic_machine=romp-ibm + ;; + sa29200) + basic_machine=a29k-amd + os=-udi + ;; + sb1) + basic_machine=mipsisa64sb1-unknown + ;; + sb1el) + basic_machine=mipsisa64sb1el-unknown + ;; + sei) + basic_machine=mips-sei + os=-seiux + ;; + sequent) + basic_machine=i386-sequent + ;; + sh) + basic_machine=sh-hitachi + os=-hms + ;; + sh64) + basic_machine=sh64-unknown + ;; + sparclite-wrs | simso-wrs) + basic_machine=sparclite-wrs + os=-vxworks + ;; + sps7) + basic_machine=m68k-bull + os=-sysv2 + ;; + spur) + basic_machine=spur-unknown + ;; + st2000) + basic_machine=m68k-tandem + ;; + stratus) + basic_machine=i860-stratus + os=-sysv4 + ;; + sun2) + basic_machine=m68000-sun + ;; + sun2os3) + basic_machine=m68000-sun + os=-sunos3 + ;; + sun2os4) + basic_machine=m68000-sun + os=-sunos4 + ;; + sun3os3) + basic_machine=m68k-sun + os=-sunos3 + ;; + sun3os4) + basic_machine=m68k-sun + os=-sunos4 + ;; + sun4os3) + basic_machine=sparc-sun + os=-sunos3 + ;; + sun4os4) + basic_machine=sparc-sun + os=-sunos4 + ;; + sun4sol2) + basic_machine=sparc-sun + os=-solaris2 + ;; + sun3 | sun3-*) + basic_machine=m68k-sun + ;; + sun4) + basic_machine=sparc-sun + ;; + sun386 | sun386i | roadrunner) + basic_machine=i386-sun + ;; + sv1) + basic_machine=sv1-cray + os=-unicos + ;; + symmetry) + basic_machine=i386-sequent + os=-dynix + ;; + t3e) + basic_machine=alphaev5-cray + os=-unicos + ;; + t90) + basic_machine=t90-cray + os=-unicos + ;; + tic54x | c54x*) + basic_machine=tic54x-unknown + os=-coff + ;; + tic55x | c55x*) + basic_machine=tic55x-unknown + os=-coff + ;; + tic6x | c6x*) + basic_machine=tic6x-unknown + os=-coff + ;; + tx39) + basic_machine=mipstx39-unknown + ;; + tx39el) + basic_machine=mipstx39el-unknown + ;; + toad1) + basic_machine=pdp10-xkl + os=-tops20 + ;; + tower | tower-32) + basic_machine=m68k-ncr + ;; + udi29k) + basic_machine=a29k-amd + os=-udi + ;; + ultra3) + basic_machine=a29k-nyu + os=-sym1 + ;; + v810 | necv810) + basic_machine=v810-nec + os=-none + ;; + vaxv) + basic_machine=vax-dec + os=-sysv + ;; + vms) + basic_machine=vax-dec + os=-vms + ;; + vpp*|vx|vx-*) + basic_machine=f301-fujitsu + ;; + vxworks960) + basic_machine=i960-wrs + os=-vxworks + ;; + vxworks68) + basic_machine=m68k-wrs + os=-vxworks + ;; + vxworks29k) + basic_machine=a29k-wrs + os=-vxworks + ;; + w65*) + basic_machine=w65-wdc + os=-none + ;; + w89k-*) + basic_machine=hppa1.1-winbond + os=-proelf + ;; + xps | xps100) + basic_machine=xps100-honeywell + ;; + ymp) + basic_machine=ymp-cray + os=-unicos + ;; + z8k-*-coff) + basic_machine=z8k-unknown + os=-sim + ;; + none) + basic_machine=none-none + os=-none + ;; + +# Here we handle the default manufacturer of certain CPU types. It is in +# some cases the only manufacturer, in others, it is the most popular. + w89k) + basic_machine=hppa1.1-winbond + ;; + op50n) + basic_machine=hppa1.1-oki + ;; + op60c) + basic_machine=hppa1.1-oki + ;; + romp) + basic_machine=romp-ibm + ;; + rs6000) + basic_machine=rs6000-ibm + ;; + vax) + basic_machine=vax-dec + ;; + pdp10) + # there are many clones, so DEC is not a safe bet + basic_machine=pdp10-unknown + ;; + pdp11) + basic_machine=pdp11-dec + ;; + we32k) + basic_machine=we32k-att + ;; + sh3 | sh4 | sh[34]eb | sh[1234]le | sh[23]ele) + basic_machine=sh-unknown + ;; + sh64) + basic_machine=sh64-unknown + ;; + sparc | sparcv8 | sparcv9 | sparcv9b) + basic_machine=sparc-sun + ;; + cydra) + basic_machine=cydra-cydrome + ;; + orion) + basic_machine=orion-highlevel + ;; + orion105) + basic_machine=clipper-highlevel + ;; + mac | mpw | mac-mpw) + basic_machine=m68k-apple + ;; + pmac | pmac-mpw) + basic_machine=powerpc-apple + ;; + *-unknown) + # Make sure to match an already-canonicalized machine name. + ;; + *) + echo Invalid configuration \`$1\': machine \`$basic_machine\' not recognized 1>&2 + exit 1 + ;; +esac + +# Here we canonicalize certain aliases for manufacturers. +case $basic_machine in + *-digital*) + basic_machine=`echo $basic_machine | sed 's/digital.*/dec/'` + ;; + *-commodore*) + basic_machine=`echo $basic_machine | sed 's/commodore.*/cbm/'` + ;; + *) + ;; +esac + +# Decode manufacturer-specific aliases for certain operating systems. + +if [ x"$os" != x"" ] +then +case $os in + # First match some system type aliases + # that might get confused with valid system types. + # -solaris* is a basic system type, with this one exception. + -solaris1 | -solaris1.*) + os=`echo $os | sed -e 's|solaris1|sunos4|'` + ;; + -solaris) + os=-solaris2 + ;; + -svr4*) + os=-sysv4 + ;; + -unixware*) + os=-sysv4.2uw + ;; + -gnu/linux*) + os=`echo $os | sed -e 's|gnu/linux|linux-gnu|'` + ;; + # First accept the basic system types. + # The portable systems comes first. + # Each alternative MUST END IN A *, to match a version number. + # -sysv* is not here because it comes later, after sysvr4. + -gnu* | -bsd* | -mach* | -minix* | -genix* | -ultrix* | -irix* \ + | -*vms* | -sco* | -esix* | -isc* | -aix* | -sunos | -sunos[34]*\ + | -hpux* | -unos* | -osf* | -luna* | -dgux* | -solaris* | -sym* \ + | -amigaos* | -amigados* | -msdos* | -newsos* | -unicos* | -aof* \ + | -aos* \ + | -nindy* | -vxsim* | -vxworks* | -ebmon* | -hms* | -mvs* \ + | -clix* | -riscos* | -uniplus* | -iris* | -rtu* | -xenix* \ + | -hiux* | -386bsd* | -netbsd* | -openbsd* | -freebsd* | -riscix* \ + | -lynxos* | -bosx* | -nextstep* | -cxux* | -aout* | -elf* | -oabi* \ + | -ptx* | -coff* | -ecoff* | -winnt* | -domain* | -vsta* \ + | -udi* | -eabi* | -lites* | -ieee* | -go32* | -aux* \ + | -chorusos* | -chorusrdb* \ + | -cygwin* | -pe* | -psos* | -moss* | -proelf* | -rtems* \ + | -mingw32* | -linux-gnu* | -uxpv* | -beos* | -mpeix* | -udk* \ + | -interix* | -uwin* | -mks* | -rhapsody* | -darwin* | -opened* \ + | -openstep* | -oskit* | -conix* | -pw32* | -nonstopux* \ + | -storm-chaos* | -tops10* | -tenex* | -tops20* | -its* \ + | -os2* | -vos* | -palmos* | -uclinux* | -nucleus* \ + | -morphos* | -superux* | -rtmk* | -rtmk-nova* | -windiss* \ + | -powermax* | -dnix* | -nx6 | -nx7 | -sei*) + # Remember, each alternative MUST END IN *, to match a version number. + ;; + -qnx*) + case $basic_machine in + x86-* | i*86-*) + ;; + *) + os=-nto$os + ;; + esac + ;; + -nto-qnx*) + ;; + -nto*) + os=`echo $os | sed -e 's|nto|nto-qnx|'` + ;; + -sim | -es1800* | -hms* | -xray | -os68k* | -none* | -v88r* \ + | -windows* | -osx | -abug | -netware* | -os9* | -beos* \ + | -macos* | -mpw* | -magic* | -mmixware* | -mon960* | -lnews*) + ;; + -mac*) + os=`echo $os | sed -e 's|mac|macos|'` + ;; + -linux*) + os=`echo $os | sed -e 's|linux|linux-gnu|'` + ;; + -sunos5*) + os=`echo $os | sed -e 's|sunos5|solaris2|'` + ;; + -sunos6*) + os=`echo $os | sed -e 's|sunos6|solaris3|'` + ;; + -opened*) + os=-openedition + ;; + -wince*) + os=-wince + ;; + -osfrose*) + os=-osfrose + ;; + -osf*) + os=-osf + ;; + -utek*) + os=-bsd + ;; + -dynix*) + os=-bsd + ;; + -acis*) + os=-aos + ;; + -atheos*) + os=-atheos + ;; + -386bsd) + os=-bsd + ;; + -ctix* | -uts*) + os=-sysv + ;; + -nova*) + os=-rtmk-nova + ;; + -ns2 ) + os=-nextstep2 + ;; + -nsk*) + os=-nsk + ;; + # Preserve the version number of sinix5. + -sinix5.*) + os=`echo $os | sed -e 's|sinix|sysv|'` + ;; + -sinix*) + os=-sysv4 + ;; + -triton*) + os=-sysv3 + ;; + -oss*) + os=-sysv3 + ;; + -svr4) + os=-sysv4 + ;; + -svr3) + os=-sysv3 + ;; + -sysvr4) + os=-sysv4 + ;; + # This must come after -sysvr4. + -sysv*) + ;; + -ose*) + os=-ose + ;; + -es1800*) + os=-ose + ;; + -xenix) + os=-xenix + ;; + -*mint | -mint[0-9]* | -*MiNT | -MiNT[0-9]*) + os=-mint + ;; + -aros*) + os=-aros + ;; + -kaos*) + os=-kaos + ;; + -none) + ;; + *) + # Get rid of the `-' at the beginning of $os. + os=`echo $os | sed 's/[^-]*-//'` + echo Invalid configuration \`$1\': system \`$os\' not recognized 1>&2 + exit 1 + ;; +esac +else + +# Here we handle the default operating systems that come with various machines. +# The value should be what the vendor currently ships out the door with their +# machine or put another way, the most popular os provided with the machine. + +# Note that if you're going to try to match "-MANUFACTURER" here (say, +# "-sun"), then you have to tell the case statement up towards the top +# that MANUFACTURER isn't an operating system. Otherwise, code above +# will signal an error saying that MANUFACTURER isn't an operating +# system, and we'll never get to this point. + +case $basic_machine in + *-acorn) + os=-riscix1.2 + ;; + arm*-rebel) + os=-linux + ;; + arm*-semi) + os=-aout + ;; + c4x-* | tic4x-*) + os=-coff + ;; + # This must come before the *-dec entry. + pdp10-*) + os=-tops20 + ;; + pdp11-*) + os=-none + ;; + *-dec | vax-*) + os=-ultrix4.2 + ;; + m68*-apollo) + os=-domain + ;; + i386-sun) + os=-sunos4.0.2 + ;; + m68000-sun) + os=-sunos3 + # This also exists in the configure program, but was not the + # default. + # os=-sunos4 + ;; + m68*-cisco) + os=-aout + ;; + mips*-cisco) + os=-elf + ;; + mips*-*) + os=-elf + ;; + or32-*) + os=-coff + ;; + *-tti) # must be before sparc entry or we get the wrong os. + os=-sysv3 + ;; + sparc-* | *-sun) + os=-sunos4.1.1 + ;; + *-be) + os=-beos + ;; + *-ibm) + os=-aix + ;; + *-wec) + os=-proelf + ;; + *-winbond) + os=-proelf + ;; + *-oki) + os=-proelf + ;; + *-hp) + os=-hpux + ;; + *-hitachi) + os=-hiux + ;; + i860-* | *-att | *-ncr | *-altos | *-motorola | *-convergent) + os=-sysv + ;; + *-cbm) + os=-amigaos + ;; + *-dg) + os=-dgux + ;; + *-dolphin) + os=-sysv3 + ;; + m68k-ccur) + os=-rtu + ;; + m88k-omron*) + os=-luna + ;; + *-next ) + os=-nextstep + ;; + *-sequent) + os=-ptx + ;; + *-crds) + os=-unos + ;; + *-ns) + os=-genix + ;; + i370-*) + os=-mvs + ;; + *-next) + os=-nextstep3 + ;; + *-gould) + os=-sysv + ;; + *-highlevel) + os=-bsd + ;; + *-encore) + os=-bsd + ;; + *-sgi) + os=-irix + ;; + *-siemens) + os=-sysv4 + ;; + *-masscomp) + os=-rtu + ;; + f30[01]-fujitsu | f700-fujitsu) + os=-uxpv + ;; + *-rom68k) + os=-coff + ;; + *-*bug) + os=-coff + ;; + *-apple) + os=-macos + ;; + *-atari*) + os=-mint + ;; + *) + os=-none + ;; +esac +fi + +# Here we handle the case where we know the os, and the CPU type, but not the +# manufacturer. We pick the logical manufacturer. +vendor=unknown +case $basic_machine in + *-unknown) + case $os in + -riscix*) + vendor=acorn + ;; + -sunos*) + vendor=sun + ;; + -aix*) + vendor=ibm + ;; + -beos*) + vendor=be + ;; + -hpux*) + vendor=hp + ;; + -mpeix*) + vendor=hp + ;; + -hiux*) + vendor=hitachi + ;; + -unos*) + vendor=crds + ;; + -dgux*) + vendor=dg + ;; + -luna*) + vendor=omron + ;; + -genix*) + vendor=ns + ;; + -mvs* | -opened*) + vendor=ibm + ;; + -ptx*) + vendor=sequent + ;; + -vxsim* | -vxworks* | -windiss*) + vendor=wrs + ;; + -aux*) + vendor=apple + ;; + -hms*) + vendor=hitachi + ;; + -mpw* | -macos*) + vendor=apple + ;; + -*mint | -mint[0-9]* | -*MiNT | -MiNT[0-9]*) + vendor=atari + ;; + -vos*) + vendor=stratus + ;; + esac + basic_machine=`echo $basic_machine | sed "s/unknown/$vendor/"` + ;; +esac + +echo $basic_machine$os +exit 0 + +# Local variables: +# eval: (add-hook 'write-file-hooks 'time-stamp) +# time-stamp-start: "timestamp='" +# time-stamp-format: "%:y-%02m-%02d" +# time-stamp-end: "'" +# End: diff --git a/AMDiS/configure b/AMDiS/configure new file mode 100755 index 0000000000000000000000000000000000000000..d708ac39d266f4b44764f07b9008f7c77d64627d --- /dev/null +++ b/AMDiS/configure @@ -0,0 +1,20054 @@ +#! /bin/sh +# Guess values for system-dependent variables and create Makefiles. +# Generated by GNU Autoconf 2.59. +# +# Copyright (C) 2003 Free Software Foundation, Inc. +# This configure script is free software; the Free Software Foundation +# gives unlimited permission to copy, distribute and modify it. +## --------------------- ## +## M4sh Initialization. ## +## --------------------- ## + +# Be Bourne compatible +if test -n "${ZSH_VERSION+set}" && (emulate sh) >/dev/null 2>&1; then + emulate sh + NULLCMD=: + # Zsh 3.x and 4.x performs word splitting on ${1+"$@"}, which + # is contrary to our usage. Disable this feature. + alias -g '${1+"$@"}'='"$@"' +elif test -n "${BASH_VERSION+set}" && (set -o posix) >/dev/null 2>&1; then + set -o posix +fi +DUALCASE=1; export DUALCASE # for MKS sh + +# Support unset when possible. +if ( (MAIL=60; unset MAIL) || exit) >/dev/null 2>&1; then + as_unset=unset +else + as_unset=false +fi + + +# Work around bugs in pre-3.0 UWIN ksh. +$as_unset ENV MAIL MAILPATH +PS1='$ ' +PS2='> ' +PS4='+ ' + +# NLS nuisances. +for as_var in \ + LANG LANGUAGE LC_ADDRESS LC_ALL LC_COLLATE LC_CTYPE LC_IDENTIFICATION \ + LC_MEASUREMENT LC_MESSAGES LC_MONETARY LC_NAME LC_NUMERIC LC_PAPER \ + LC_TELEPHONE LC_TIME +do + if (set +x; test -z "`(eval $as_var=C; export $as_var) 2>&1`"); then + eval $as_var=C; export $as_var + else + $as_unset $as_var + fi +done + +# Required to use basename. +if expr a : '\(a\)' >/dev/null 2>&1; then + as_expr=expr +else + as_expr=false +fi + +if (basename /) >/dev/null 2>&1 && test "X`basename / 2>&1`" = "X/"; then + as_basename=basename +else + as_basename=false +fi + + +# Name of the executable. +as_me=`$as_basename "$0" || +$as_expr X/"$0" : '.*/\([^/][^/]*\)/*$' \| \ + X"$0" : 'X\(//\)$' \| \ + X"$0" : 'X\(/\)$' \| \ + . : '\(.\)' 2>/dev/null || +echo X/"$0" | + sed '/^.*\/\([^/][^/]*\)\/*$/{ s//\1/; q; } + /^X\/\(\/\/\)$/{ s//\1/; q; } + /^X\/\(\/\).*/{ s//\1/; q; } + s/.*/./; q'` + + +# PATH needs CR, and LINENO needs CR and PATH. +# Avoid depending upon Character Ranges. +as_cr_letters='abcdefghijklmnopqrstuvwxyz' +as_cr_LETTERS='ABCDEFGHIJKLMNOPQRSTUVWXYZ' +as_cr_Letters=$as_cr_letters$as_cr_LETTERS +as_cr_digits='0123456789' +as_cr_alnum=$as_cr_Letters$as_cr_digits + +# The user is always right. +if test "${PATH_SEPARATOR+set}" != set; then + echo "#! /bin/sh" >conf$$.sh + echo "exit 0" >>conf$$.sh + chmod +x conf$$.sh + if (PATH="/nonexistent;."; conf$$.sh) >/dev/null 2>&1; then + PATH_SEPARATOR=';' + else + PATH_SEPARATOR=: + fi + rm -f conf$$.sh +fi + + + as_lineno_1=$LINENO + as_lineno_2=$LINENO + as_lineno_3=`(expr $as_lineno_1 + 1) 2>/dev/null` + test "x$as_lineno_1" != "x$as_lineno_2" && + test "x$as_lineno_3" = "x$as_lineno_2" || { + # Find who we are. Look in the path if we contain no path at all + # relative or not. + case $0 in + *[\\/]* ) as_myself=$0 ;; + *) as_save_IFS=$IFS; IFS=$PATH_SEPARATOR +for as_dir in $PATH +do + IFS=$as_save_IFS + test -z "$as_dir" && as_dir=. + test -r "$as_dir/$0" && as_myself=$as_dir/$0 && break +done + + ;; + esac + # We did not find ourselves, most probably we were run as `sh COMMAND' + # in which case we are not to be found in the path. + if test "x$as_myself" = x; then + as_myself=$0 + fi + if test ! -f "$as_myself"; then + { echo "$as_me: error: cannot find myself; rerun with an absolute path" >&2 + { (exit 1); exit 1; }; } + fi + case $CONFIG_SHELL in + '') + as_save_IFS=$IFS; IFS=$PATH_SEPARATOR +for as_dir in /bin$PATH_SEPARATOR/usr/bin$PATH_SEPARATOR$PATH +do + IFS=$as_save_IFS + test -z "$as_dir" && as_dir=. + for as_base in sh bash ksh sh5; do + case $as_dir in + /*) + if ("$as_dir/$as_base" -c ' + as_lineno_1=$LINENO + as_lineno_2=$LINENO + as_lineno_3=`(expr $as_lineno_1 + 1) 2>/dev/null` + test "x$as_lineno_1" != "x$as_lineno_2" && + test "x$as_lineno_3" = "x$as_lineno_2" ') 2>/dev/null; then + $as_unset BASH_ENV || test "${BASH_ENV+set}" != set || { BASH_ENV=; export BASH_ENV; } + $as_unset ENV || test "${ENV+set}" != set || { ENV=; export ENV; } + CONFIG_SHELL=$as_dir/$as_base + export CONFIG_SHELL + exec "$CONFIG_SHELL" "$0" ${1+"$@"} + fi;; + esac + done +done +;; + esac + + # Create $as_me.lineno as a copy of $as_myself, but with $LINENO + # uniformly replaced by the line number. The first 'sed' inserts a + # line-number line before each line; the second 'sed' does the real + # work. The second script uses 'N' to pair each line-number line + # with the numbered line, and appends trailing '-' during + # substitution so that $LINENO is not a special case at line end. + # (Raja R Harinath suggested sed '=', and Paul Eggert wrote the + # second 'sed' script. Blame Lee E. McMahon for sed's syntax. :-) + sed '=' <$as_myself | + sed ' + N + s,$,-, + : loop + s,^\(['$as_cr_digits']*\)\(.*\)[$]LINENO\([^'$as_cr_alnum'_]\),\1\2\1\3, + t loop + s,-$,, + s,^['$as_cr_digits']*\n,, + ' >$as_me.lineno && + chmod +x $as_me.lineno || + { echo "$as_me: error: cannot create $as_me.lineno; rerun with a POSIX shell" >&2 + { (exit 1); exit 1; }; } + + # Don't try to exec as it changes $[0], causing all sort of problems + # (the dirname of $[0] is not the place where we might find the + # original and so on. Autoconf is especially sensible to this). + . ./$as_me.lineno + # Exit status is that of the last command. + exit +} + + +case `echo "testing\c"; echo 1,2,3`,`echo -n testing; echo 1,2,3` in + *c*,-n*) ECHO_N= ECHO_C=' +' ECHO_T=' ' ;; + *c*,* ) ECHO_N=-n ECHO_C= ECHO_T= ;; + *) ECHO_N= ECHO_C='\c' ECHO_T= ;; +esac + +if expr a : '\(a\)' >/dev/null 2>&1; then + as_expr=expr +else + as_expr=false +fi + +rm -f conf$$ conf$$.exe conf$$.file +echo >conf$$.file +if ln -s conf$$.file conf$$ 2>/dev/null; then + # We could just check for DJGPP; but this test a) works b) is more generic + # and c) will remain valid once DJGPP supports symlinks (DJGPP 2.04). + if test -f conf$$.exe; then + # Don't use ln at all; we don't have any links + as_ln_s='cp -p' + else + as_ln_s='ln -s' + fi +elif ln conf$$.file conf$$ 2>/dev/null; then + as_ln_s=ln +else + as_ln_s='cp -p' +fi +rm -f conf$$ conf$$.exe conf$$.file + +if mkdir -p . 2>/dev/null; then + as_mkdir_p=: +else + test -d ./-p && rmdir ./-p + as_mkdir_p=false +fi + +as_executable_p="test -f" + +# Sed expression to map a string onto a valid CPP name. +as_tr_cpp="eval sed 'y%*$as_cr_letters%P$as_cr_LETTERS%;s%[^_$as_cr_alnum]%_%g'" + +# Sed expression to map a string onto a valid variable name. +as_tr_sh="eval sed 'y%*+%pp%;s%[^_$as_cr_alnum]%_%g'" + + +# IFS +# We need space, tab and new line, in precisely that order. +as_nl=' +' +IFS=" $as_nl" + +# CDPATH. +$as_unset CDPATH + + + +# Check that we are running under the correct shell. +SHELL=${CONFIG_SHELL-/bin/sh} + +case X$ECHO in +X*--fallback-echo) + # Remove one level of quotation (which was required for Make). + ECHO=`echo "$ECHO" | sed 's,\\\\\$\\$0,'$0','` + ;; +esac + +echo=${ECHO-echo} +if test "X$1" = X--no-reexec; then + # Discard the --no-reexec flag, and continue. + shift +elif test "X$1" = X--fallback-echo; then + # Avoid inline document here, it may be left over + : +elif test "X`($echo '\t') 2>/dev/null`" = 'X\t' ; then + # Yippee, $echo works! + : +else + # Restart under the correct shell. + exec $SHELL "$0" --no-reexec ${1+"$@"} +fi + +if test "X$1" = X--fallback-echo; then + # used as fallback echo + shift + cat <<EOF +$* +EOF + exit 0 +fi + +# The HP-UX ksh and POSIX shell print the target directory to stdout +# if CDPATH is set. +(unset CDPATH) >/dev/null 2>&1 && unset CDPATH + +if test -z "$ECHO"; then +if test "X${echo_test_string+set}" != Xset; then +# find a string as large as possible, as long as the shell can cope with it + for cmd in 'sed 50q "$0"' 'sed 20q "$0"' 'sed 10q "$0"' 'sed 2q "$0"' 'echo test'; do + # expected sizes: less than 2Kb, 1Kb, 512 bytes, 16 bytes, ... + if (echo_test_string=`eval $cmd`) 2>/dev/null && + echo_test_string=`eval $cmd` && + (test "X$echo_test_string" = "X$echo_test_string") 2>/dev/null + then + break + fi + done +fi + +if test "X`($echo '\t') 2>/dev/null`" = 'X\t' && + echo_testing_string=`($echo "$echo_test_string") 2>/dev/null` && + test "X$echo_testing_string" = "X$echo_test_string"; then + : +else + # The Solaris, AIX, and Digital Unix default echo programs unquote + # backslashes. This makes it impossible to quote backslashes using + # echo "$something" | sed 's/\\/\\\\/g' + # + # So, first we look for a working echo in the user's PATH. + + lt_save_ifs="$IFS"; IFS=$PATH_SEPARATOR + for dir in $PATH /usr/ucb; do + IFS="$lt_save_ifs" + if (test -f $dir/echo || test -f $dir/echo$ac_exeext) && + test "X`($dir/echo '\t') 2>/dev/null`" = 'X\t' && + echo_testing_string=`($dir/echo "$echo_test_string") 2>/dev/null` && + test "X$echo_testing_string" = "X$echo_test_string"; then + echo="$dir/echo" + break + fi + done + IFS="$lt_save_ifs" + + if test "X$echo" = Xecho; then + # We didn't find a better echo, so look for alternatives. + if test "X`(print -r '\t') 2>/dev/null`" = 'X\t' && + echo_testing_string=`(print -r "$echo_test_string") 2>/dev/null` && + test "X$echo_testing_string" = "X$echo_test_string"; then + # This shell has a builtin print -r that does the trick. + echo='print -r' + elif (test -f /bin/ksh || test -f /bin/ksh$ac_exeext) && + test "X$CONFIG_SHELL" != X/bin/ksh; then + # If we have ksh, try running configure again with it. + ORIGINAL_CONFIG_SHELL=${CONFIG_SHELL-/bin/sh} + export ORIGINAL_CONFIG_SHELL + CONFIG_SHELL=/bin/ksh + export CONFIG_SHELL + exec $CONFIG_SHELL "$0" --no-reexec ${1+"$@"} + else + # Try using printf. + echo='printf %s\n' + if test "X`($echo '\t') 2>/dev/null`" = 'X\t' && + echo_testing_string=`($echo "$echo_test_string") 2>/dev/null` && + test "X$echo_testing_string" = "X$echo_test_string"; then + # Cool, printf works + : + elif echo_testing_string=`($ORIGINAL_CONFIG_SHELL "$0" --fallback-echo '\t') 2>/dev/null` && + test "X$echo_testing_string" = 'X\t' && + echo_testing_string=`($ORIGINAL_CONFIG_SHELL "$0" --fallback-echo "$echo_test_string") 2>/dev/null` && + test "X$echo_testing_string" = "X$echo_test_string"; then + CONFIG_SHELL=$ORIGINAL_CONFIG_SHELL + export CONFIG_SHELL + SHELL="$CONFIG_SHELL" + export SHELL + echo="$CONFIG_SHELL $0 --fallback-echo" + elif echo_testing_string=`($CONFIG_SHELL "$0" --fallback-echo '\t') 2>/dev/null` && + test "X$echo_testing_string" = 'X\t' && + echo_testing_string=`($CONFIG_SHELL "$0" --fallback-echo "$echo_test_string") 2>/dev/null` && + test "X$echo_testing_string" = "X$echo_test_string"; then + echo="$CONFIG_SHELL $0 --fallback-echo" + else + # maybe with a smaller string... + prev=: + + for cmd in 'echo test' 'sed 2q "$0"' 'sed 10q "$0"' 'sed 20q "$0"' 'sed 50q "$0"'; do + if (test "X$echo_test_string" = "X`eval $cmd`") 2>/dev/null + then + break + fi + prev="$cmd" + done + + if test "$prev" != 'sed 50q "$0"'; then + echo_test_string=`eval $prev` + export echo_test_string + exec ${ORIGINAL_CONFIG_SHELL-${CONFIG_SHELL-/bin/sh}} "$0" ${1+"$@"} + else + # Oops. We lost completely, so just stick with echo. + echo=echo + fi + fi + fi + fi +fi +fi + +# Copy echo and quote the copy suitably for passing to libtool from +# the Makefile, instead of quoting the original, which is used later. +ECHO=$echo +if test "X$ECHO" = "X$CONFIG_SHELL $0 --fallback-echo"; then + ECHO="$CONFIG_SHELL \\\$\$0 --fallback-echo" +fi + + + + +tagnames=${tagnames+${tagnames},}CXX + +tagnames=${tagnames+${tagnames},}F77 + +# Name of the host. +# hostname on some systems (SVR3.2, Linux) returns a bogus exit status, +# so uname gets run too. +ac_hostname=`(hostname || uname -n) 2>/dev/null | sed 1q` + +exec 6>&1 + +# +# Initializations. +# +ac_default_prefix=/usr/local +ac_config_libobj_dir=. +cross_compiling=no +subdirs= +MFLAGS= +MAKEFLAGS= +SHELL=${CONFIG_SHELL-/bin/sh} + +# Maximum number of lines to put in a shell here document. +# This variable seems obsolete. It should probably be removed, and +# only ac_max_sed_lines should be used. +: ${ac_max_here_lines=38} + +# Identity of this package. +PACKAGE_NAME= +PACKAGE_TARNAME= +PACKAGE_VERSION= +PACKAGE_STRING= +PACKAGE_BUGREPORT= + +# Factoring default headers for most tests. +ac_includes_default="\ +#include <stdio.h> +#if HAVE_SYS_TYPES_H +# include <sys/types.h> +#endif +#if HAVE_SYS_STAT_H +# include <sys/stat.h> +#endif +#if STDC_HEADERS +# include <stdlib.h> +# include <stddef.h> +#else +# if HAVE_STDLIB_H +# include <stdlib.h> +# endif +#endif +#if HAVE_STRING_H +# if !STDC_HEADERS && HAVE_MEMORY_H +# include <memory.h> +# endif +# include <string.h> +#endif +#if HAVE_STRINGS_H +# include <strings.h> +#endif +#if HAVE_INTTYPES_H +# include <inttypes.h> +#else +# if HAVE_STDINT_H +# include <stdint.h> +# endif +#endif +#if HAVE_UNISTD_H +# include <unistd.h> +#endif" + +ac_subst_vars='SHELL PATH_SEPARATOR PACKAGE_NAME PACKAGE_TARNAME PACKAGE_VERSION PACKAGE_STRING PACKAGE_BUGREPORT exec_prefix prefix program_transform_name bindir sbindir libexecdir datadir sysconfdir sharedstatedir localstatedir libdir includedir oldincludedir infodir mandir build_alias host_alias target_alias DEFS ECHO_C ECHO_N ECHO_T LIBS INSTALL_PROGRAM INSTALL_SCRIPT INSTALL_DATA CYGPATH_W PACKAGE VERSION ACLOCAL AUTOCONF AUTOMAKE AUTOHEADER MAKEINFO install_sh STRIP ac_ct_STRIP INSTALL_STRIP_PROGRAM mkdir_p AWK SET_MAKE am__leading_dot AMTAR am__tar am__untar MAINTAINER_MODE_TRUE MAINTAINER_MODE_FALSE MAINT AMDIS_DEBUG_TRUE AMDIS_DEBUG_FALSE CXX CC AMDIS_INTEL_TRUE AMDIS_INTEL_FALSE AMDIS_OPENMP_TRUE AMDIS_OPENMP_FALSE OPENMP_FLAG MPI_DIR USE_PARALLEL_AMDIS_TRUE USE_PARALLEL_AMDIS_FALSE ENABLE_UMFPACK_TRUE ENABLE_UMFPACK_FALSE CFLAGS LDFLAGS CPPFLAGS ac_ct_CC EXEEXT OBJEXT DEPDIR am__include am__quote AMDEP_TRUE AMDEP_FALSE AMDEPBACKSLASH CCDEPMODE am__fastdepCC_TRUE am__fastdepCC_FALSE CXXFLAGS ac_ct_CXX CXXDEPMODE am__fastdepCXX_TRUE am__fastdepCXX_FALSE build build_cpu build_vendor build_os host host_cpu host_vendor host_os SED EGREP LN_S ECHO AR ac_ct_AR RANLIB ac_ct_RANLIB CPP CXXCPP F77 FFLAGS ac_ct_F77 LIBTOOL LIBOBJS LTLIBOBJS' +ac_subst_files='' + +# Initialize some variables set by options. +ac_init_help= +ac_init_version=false +# The variables have the same names as the options, with +# dashes changed to underlines. +cache_file=/dev/null +exec_prefix=NONE +no_create= +no_recursion= +prefix=NONE +program_prefix=NONE +program_suffix=NONE +program_transform_name=s,x,x, +silent= +site= +srcdir= +verbose= +x_includes=NONE +x_libraries=NONE + +# Installation directory options. +# These are left unexpanded so users can "make install exec_prefix=/foo" +# and all the variables that are supposed to be based on exec_prefix +# by default will actually change. +# Use braces instead of parens because sh, perl, etc. also accept them. +bindir='${exec_prefix}/bin' +sbindir='${exec_prefix}/sbin' +libexecdir='${exec_prefix}/libexec' +datadir='${prefix}/share' +sysconfdir='${prefix}/etc' +sharedstatedir='${prefix}/com' +localstatedir='${prefix}/var' +libdir='${exec_prefix}/lib' +includedir='${prefix}/include' +oldincludedir='/usr/include' +infodir='${prefix}/info' +mandir='${prefix}/man' + +ac_prev= +for ac_option +do + # If the previous option needs an argument, assign it. + if test -n "$ac_prev"; then + eval "$ac_prev=\$ac_option" + ac_prev= + continue + fi + + ac_optarg=`expr "x$ac_option" : 'x[^=]*=\(.*\)'` + + # Accept the important Cygnus configure options, so we can diagnose typos. + + case $ac_option in + + -bindir | --bindir | --bindi | --bind | --bin | --bi) + ac_prev=bindir ;; + -bindir=* | --bindir=* | --bindi=* | --bind=* | --bin=* | --bi=*) + bindir=$ac_optarg ;; + + -build | --build | --buil | --bui | --bu) + ac_prev=build_alias ;; + -build=* | --build=* | --buil=* | --bui=* | --bu=*) + build_alias=$ac_optarg ;; + + -cache-file | --cache-file | --cache-fil | --cache-fi \ + | --cache-f | --cache- | --cache | --cach | --cac | --ca | --c) + ac_prev=cache_file ;; + -cache-file=* | --cache-file=* | --cache-fil=* | --cache-fi=* \ + | --cache-f=* | --cache-=* | --cache=* | --cach=* | --cac=* | --ca=* | --c=*) + cache_file=$ac_optarg ;; + + --config-cache | -C) + cache_file=config.cache ;; + + -datadir | --datadir | --datadi | --datad | --data | --dat | --da) + ac_prev=datadir ;; + -datadir=* | --datadir=* | --datadi=* | --datad=* | --data=* | --dat=* \ + | --da=*) + datadir=$ac_optarg ;; + + -disable-* | --disable-*) + ac_feature=`expr "x$ac_option" : 'x-*disable-\(.*\)'` + # Reject names that are not valid shell variable names. + expr "x$ac_feature" : ".*[^-_$as_cr_alnum]" >/dev/null && + { echo "$as_me: error: invalid feature name: $ac_feature" >&2 + { (exit 1); exit 1; }; } + ac_feature=`echo $ac_feature | sed 's/-/_/g'` + eval "enable_$ac_feature=no" ;; + + -enable-* | --enable-*) + ac_feature=`expr "x$ac_option" : 'x-*enable-\([^=]*\)'` + # Reject names that are not valid shell variable names. + expr "x$ac_feature" : ".*[^-_$as_cr_alnum]" >/dev/null && + { echo "$as_me: error: invalid feature name: $ac_feature" >&2 + { (exit 1); exit 1; }; } + ac_feature=`echo $ac_feature | sed 's/-/_/g'` + case $ac_option in + *=*) ac_optarg=`echo "$ac_optarg" | sed "s/'/'\\\\\\\\''/g"`;; + *) ac_optarg=yes ;; + esac + eval "enable_$ac_feature='$ac_optarg'" ;; + + -exec-prefix | --exec_prefix | --exec-prefix | --exec-prefi \ + | --exec-pref | --exec-pre | --exec-pr | --exec-p | --exec- \ + | --exec | --exe | --ex) + ac_prev=exec_prefix ;; + -exec-prefix=* | --exec_prefix=* | --exec-prefix=* | --exec-prefi=* \ + | --exec-pref=* | --exec-pre=* | --exec-pr=* | --exec-p=* | --exec-=* \ + | --exec=* | --exe=* | --ex=*) + exec_prefix=$ac_optarg ;; + + -gas | --gas | --ga | --g) + # Obsolete; use --with-gas. + with_gas=yes ;; + + -help | --help | --hel | --he | -h) + ac_init_help=long ;; + -help=r* | --help=r* | --hel=r* | --he=r* | -hr*) + ac_init_help=recursive ;; + -help=s* | --help=s* | --hel=s* | --he=s* | -hs*) + ac_init_help=short ;; + + -host | --host | --hos | --ho) + ac_prev=host_alias ;; + -host=* | --host=* | --hos=* | --ho=*) + host_alias=$ac_optarg ;; + + -includedir | --includedir | --includedi | --included | --include \ + | --includ | --inclu | --incl | --inc) + ac_prev=includedir ;; + -includedir=* | --includedir=* | --includedi=* | --included=* | --include=* \ + | --includ=* | --inclu=* | --incl=* | --inc=*) + includedir=$ac_optarg ;; + + -infodir | --infodir | --infodi | --infod | --info | --inf) + ac_prev=infodir ;; + -infodir=* | --infodir=* | --infodi=* | --infod=* | --info=* | --inf=*) + infodir=$ac_optarg ;; + + -libdir | --libdir | --libdi | --libd) + ac_prev=libdir ;; + -libdir=* | --libdir=* | --libdi=* | --libd=*) + libdir=$ac_optarg ;; + + -libexecdir | --libexecdir | --libexecdi | --libexecd | --libexec \ + | --libexe | --libex | --libe) + ac_prev=libexecdir ;; + -libexecdir=* | --libexecdir=* | --libexecdi=* | --libexecd=* | --libexec=* \ + | --libexe=* | --libex=* | --libe=*) + libexecdir=$ac_optarg ;; + + -localstatedir | --localstatedir | --localstatedi | --localstated \ + | --localstate | --localstat | --localsta | --localst \ + | --locals | --local | --loca | --loc | --lo) + ac_prev=localstatedir ;; + -localstatedir=* | --localstatedir=* | --localstatedi=* | --localstated=* \ + | --localstate=* | --localstat=* | --localsta=* | --localst=* \ + | --locals=* | --local=* | --loca=* | --loc=* | --lo=*) + localstatedir=$ac_optarg ;; + + -mandir | --mandir | --mandi | --mand | --man | --ma | --m) + ac_prev=mandir ;; + -mandir=* | --mandir=* | --mandi=* | --mand=* | --man=* | --ma=* | --m=*) + mandir=$ac_optarg ;; + + -nfp | --nfp | --nf) + # Obsolete; use --without-fp. + with_fp=no ;; + + -no-create | --no-create | --no-creat | --no-crea | --no-cre \ + | --no-cr | --no-c | -n) + no_create=yes ;; + + -no-recursion | --no-recursion | --no-recursio | --no-recursi \ + | --no-recurs | --no-recur | --no-recu | --no-rec | --no-re | --no-r) + no_recursion=yes ;; + + -oldincludedir | --oldincludedir | --oldincludedi | --oldincluded \ + | --oldinclude | --oldinclud | --oldinclu | --oldincl | --oldinc \ + | --oldin | --oldi | --old | --ol | --o) + ac_prev=oldincludedir ;; + -oldincludedir=* | --oldincludedir=* | --oldincludedi=* | --oldincluded=* \ + | --oldinclude=* | --oldinclud=* | --oldinclu=* | --oldincl=* | --oldinc=* \ + | --oldin=* | --oldi=* | --old=* | --ol=* | --o=*) + oldincludedir=$ac_optarg ;; + + -prefix | --prefix | --prefi | --pref | --pre | --pr | --p) + ac_prev=prefix ;; + -prefix=* | --prefix=* | --prefi=* | --pref=* | --pre=* | --pr=* | --p=*) + prefix=$ac_optarg ;; + + -program-prefix | --program-prefix | --program-prefi | --program-pref \ + | --program-pre | --program-pr | --program-p) + ac_prev=program_prefix ;; + -program-prefix=* | --program-prefix=* | --program-prefi=* \ + | --program-pref=* | --program-pre=* | --program-pr=* | --program-p=*) + program_prefix=$ac_optarg ;; + + -program-suffix | --program-suffix | --program-suffi | --program-suff \ + | --program-suf | --program-su | --program-s) + ac_prev=program_suffix ;; + -program-suffix=* | --program-suffix=* | --program-suffi=* \ + | --program-suff=* | --program-suf=* | --program-su=* | --program-s=*) + program_suffix=$ac_optarg ;; + + -program-transform-name | --program-transform-name \ + | --program-transform-nam | --program-transform-na \ + | --program-transform-n | --program-transform- \ + | --program-transform | --program-transfor \ + | --program-transfo | --program-transf \ + | --program-trans | --program-tran \ + | --progr-tra | --program-tr | --program-t) + ac_prev=program_transform_name ;; + -program-transform-name=* | --program-transform-name=* \ + | --program-transform-nam=* | --program-transform-na=* \ + | --program-transform-n=* | --program-transform-=* \ + | --program-transform=* | --program-transfor=* \ + | --program-transfo=* | --program-transf=* \ + | --program-trans=* | --program-tran=* \ + | --progr-tra=* | --program-tr=* | --program-t=*) + program_transform_name=$ac_optarg ;; + + -q | -quiet | --quiet | --quie | --qui | --qu | --q \ + | -silent | --silent | --silen | --sile | --sil) + silent=yes ;; + + -sbindir | --sbindir | --sbindi | --sbind | --sbin | --sbi | --sb) + ac_prev=sbindir ;; + -sbindir=* | --sbindir=* | --sbindi=* | --sbind=* | --sbin=* \ + | --sbi=* | --sb=*) + sbindir=$ac_optarg ;; + + -sharedstatedir | --sharedstatedir | --sharedstatedi \ + | --sharedstated | --sharedstate | --sharedstat | --sharedsta \ + | --sharedst | --shareds | --shared | --share | --shar \ + | --sha | --sh) + ac_prev=sharedstatedir ;; + -sharedstatedir=* | --sharedstatedir=* | --sharedstatedi=* \ + | --sharedstated=* | --sharedstate=* | --sharedstat=* | --sharedsta=* \ + | --sharedst=* | --shareds=* | --shared=* | --share=* | --shar=* \ + | --sha=* | --sh=*) + sharedstatedir=$ac_optarg ;; + + -site | --site | --sit) + ac_prev=site ;; + -site=* | --site=* | --sit=*) + site=$ac_optarg ;; + + -srcdir | --srcdir | --srcdi | --srcd | --src | --sr) + ac_prev=srcdir ;; + -srcdir=* | --srcdir=* | --srcdi=* | --srcd=* | --src=* | --sr=*) + srcdir=$ac_optarg ;; + + -sysconfdir | --sysconfdir | --sysconfdi | --sysconfd | --sysconf \ + | --syscon | --sysco | --sysc | --sys | --sy) + ac_prev=sysconfdir ;; + -sysconfdir=* | --sysconfdir=* | --sysconfdi=* | --sysconfd=* | --sysconf=* \ + | --syscon=* | --sysco=* | --sysc=* | --sys=* | --sy=*) + sysconfdir=$ac_optarg ;; + + -target | --target | --targe | --targ | --tar | --ta | --t) + ac_prev=target_alias ;; + -target=* | --target=* | --targe=* | --targ=* | --tar=* | --ta=* | --t=*) + target_alias=$ac_optarg ;; + + -v | -verbose | --verbose | --verbos | --verbo | --verb) + verbose=yes ;; + + -version | --version | --versio | --versi | --vers | -V) + ac_init_version=: ;; + + -with-* | --with-*) + ac_package=`expr "x$ac_option" : 'x-*with-\([^=]*\)'` + # Reject names that are not valid shell variable names. + expr "x$ac_package" : ".*[^-_$as_cr_alnum]" >/dev/null && + { echo "$as_me: error: invalid package name: $ac_package" >&2 + { (exit 1); exit 1; }; } + ac_package=`echo $ac_package| sed 's/-/_/g'` + case $ac_option in + *=*) ac_optarg=`echo "$ac_optarg" | sed "s/'/'\\\\\\\\''/g"`;; + *) ac_optarg=yes ;; + esac + eval "with_$ac_package='$ac_optarg'" ;; + + -without-* | --without-*) + ac_package=`expr "x$ac_option" : 'x-*without-\(.*\)'` + # Reject names that are not valid shell variable names. + expr "x$ac_package" : ".*[^-_$as_cr_alnum]" >/dev/null && + { echo "$as_me: error: invalid package name: $ac_package" >&2 + { (exit 1); exit 1; }; } + ac_package=`echo $ac_package | sed 's/-/_/g'` + eval "with_$ac_package=no" ;; + + --x) + # Obsolete; use --with-x. + with_x=yes ;; + + -x-includes | --x-includes | --x-include | --x-includ | --x-inclu \ + | --x-incl | --x-inc | --x-in | --x-i) + ac_prev=x_includes ;; + -x-includes=* | --x-includes=* | --x-include=* | --x-includ=* | --x-inclu=* \ + | --x-incl=* | --x-inc=* | --x-in=* | --x-i=*) + x_includes=$ac_optarg ;; + + -x-libraries | --x-libraries | --x-librarie | --x-librari \ + | --x-librar | --x-libra | --x-libr | --x-lib | --x-li | --x-l) + ac_prev=x_libraries ;; + -x-libraries=* | --x-libraries=* | --x-librarie=* | --x-librari=* \ + | --x-librar=* | --x-libra=* | --x-libr=* | --x-lib=* | --x-li=* | --x-l=*) + x_libraries=$ac_optarg ;; + + -*) { echo "$as_me: error: unrecognized option: $ac_option +Try \`$0 --help' for more information." >&2 + { (exit 1); exit 1; }; } + ;; + + *=*) + ac_envvar=`expr "x$ac_option" : 'x\([^=]*\)='` + # Reject names that are not valid shell variable names. + expr "x$ac_envvar" : ".*[^_$as_cr_alnum]" >/dev/null && + { echo "$as_me: error: invalid variable name: $ac_envvar" >&2 + { (exit 1); exit 1; }; } + ac_optarg=`echo "$ac_optarg" | sed "s/'/'\\\\\\\\''/g"` + eval "$ac_envvar='$ac_optarg'" + export $ac_envvar ;; + + *) + # FIXME: should be removed in autoconf 3.0. + echo "$as_me: WARNING: you should use --build, --host, --target" >&2 + expr "x$ac_option" : ".*[^-._$as_cr_alnum]" >/dev/null && + echo "$as_me: WARNING: invalid host type: $ac_option" >&2 + : ${build_alias=$ac_option} ${host_alias=$ac_option} ${target_alias=$ac_option} + ;; + + esac +done + +if test -n "$ac_prev"; then + ac_option=--`echo $ac_prev | sed 's/_/-/g'` + { echo "$as_me: error: missing argument to $ac_option" >&2 + { (exit 1); exit 1; }; } +fi + +# Be sure to have absolute paths. +for ac_var in exec_prefix prefix +do + eval ac_val=$`echo $ac_var` + case $ac_val in + [\\/$]* | ?:[\\/]* | NONE | '' ) ;; + *) { echo "$as_me: error: expected an absolute directory name for --$ac_var: $ac_val" >&2 + { (exit 1); exit 1; }; };; + esac +done + +# Be sure to have absolute paths. +for ac_var in bindir sbindir libexecdir datadir sysconfdir sharedstatedir \ + localstatedir libdir includedir oldincludedir infodir mandir +do + eval ac_val=$`echo $ac_var` + case $ac_val in + [\\/$]* | ?:[\\/]* ) ;; + *) { echo "$as_me: error: expected an absolute directory name for --$ac_var: $ac_val" >&2 + { (exit 1); exit 1; }; };; + esac +done + +# There might be people who depend on the old broken behavior: `$host' +# used to hold the argument of --host etc. +# FIXME: To remove some day. +build=$build_alias +host=$host_alias +target=$target_alias + +# FIXME: To remove some day. +if test "x$host_alias" != x; then + if test "x$build_alias" = x; then + cross_compiling=maybe + echo "$as_me: WARNING: If you wanted to set the --build type, don't use --host. + If a cross compiler is detected then cross compile mode will be used." >&2 + elif test "x$build_alias" != "x$host_alias"; then + cross_compiling=yes + fi +fi + +ac_tool_prefix= +test -n "$host_alias" && ac_tool_prefix=$host_alias- + +test "$silent" = yes && exec 6>/dev/null + + +# Find the source files, if location was not specified. +if test -z "$srcdir"; then + ac_srcdir_defaulted=yes + # Try the directory containing this script, then its parent. + ac_confdir=`(dirname "$0") 2>/dev/null || +$as_expr X"$0" : 'X\(.*[^/]\)//*[^/][^/]*/*$' \| \ + X"$0" : 'X\(//\)[^/]' \| \ + X"$0" : 'X\(//\)$' \| \ + X"$0" : 'X\(/\)' \| \ + . : '\(.\)' 2>/dev/null || +echo X"$0" | + sed '/^X\(.*[^/]\)\/\/*[^/][^/]*\/*$/{ s//\1/; q; } + /^X\(\/\/\)[^/].*/{ s//\1/; q; } + /^X\(\/\/\)$/{ s//\1/; q; } + /^X\(\/\).*/{ s//\1/; q; } + s/.*/./; q'` + srcdir=$ac_confdir + if test ! -r $srcdir/$ac_unique_file; then + srcdir=.. + fi +else + ac_srcdir_defaulted=no +fi +if test ! -r $srcdir/$ac_unique_file; then + if test "$ac_srcdir_defaulted" = yes; then + { echo "$as_me: error: cannot find sources ($ac_unique_file) in $ac_confdir or .." >&2 + { (exit 1); exit 1; }; } + else + { echo "$as_me: error: cannot find sources ($ac_unique_file) in $srcdir" >&2 + { (exit 1); exit 1; }; } + fi +fi +(cd $srcdir && test -r ./$ac_unique_file) 2>/dev/null || + { echo "$as_me: error: sources are in $srcdir, but \`cd $srcdir' does not work" >&2 + { (exit 1); exit 1; }; } +srcdir=`echo "$srcdir" | sed 's%\([^\\/]\)[\\/]*$%\1%'` +ac_env_build_alias_set=${build_alias+set} +ac_env_build_alias_value=$build_alias +ac_cv_env_build_alias_set=${build_alias+set} +ac_cv_env_build_alias_value=$build_alias +ac_env_host_alias_set=${host_alias+set} +ac_env_host_alias_value=$host_alias +ac_cv_env_host_alias_set=${host_alias+set} +ac_cv_env_host_alias_value=$host_alias +ac_env_target_alias_set=${target_alias+set} +ac_env_target_alias_value=$target_alias +ac_cv_env_target_alias_set=${target_alias+set} +ac_cv_env_target_alias_value=$target_alias +ac_env_CC_set=${CC+set} +ac_env_CC_value=$CC +ac_cv_env_CC_set=${CC+set} +ac_cv_env_CC_value=$CC +ac_env_CFLAGS_set=${CFLAGS+set} +ac_env_CFLAGS_value=$CFLAGS +ac_cv_env_CFLAGS_set=${CFLAGS+set} +ac_cv_env_CFLAGS_value=$CFLAGS +ac_env_LDFLAGS_set=${LDFLAGS+set} +ac_env_LDFLAGS_value=$LDFLAGS +ac_cv_env_LDFLAGS_set=${LDFLAGS+set} +ac_cv_env_LDFLAGS_value=$LDFLAGS +ac_env_CPPFLAGS_set=${CPPFLAGS+set} +ac_env_CPPFLAGS_value=$CPPFLAGS +ac_cv_env_CPPFLAGS_set=${CPPFLAGS+set} +ac_cv_env_CPPFLAGS_value=$CPPFLAGS +ac_env_CXX_set=${CXX+set} +ac_env_CXX_value=$CXX +ac_cv_env_CXX_set=${CXX+set} +ac_cv_env_CXX_value=$CXX +ac_env_CXXFLAGS_set=${CXXFLAGS+set} +ac_env_CXXFLAGS_value=$CXXFLAGS +ac_cv_env_CXXFLAGS_set=${CXXFLAGS+set} +ac_cv_env_CXXFLAGS_value=$CXXFLAGS +ac_env_CPP_set=${CPP+set} +ac_env_CPP_value=$CPP +ac_cv_env_CPP_set=${CPP+set} +ac_cv_env_CPP_value=$CPP +ac_env_CXXCPP_set=${CXXCPP+set} +ac_env_CXXCPP_value=$CXXCPP +ac_cv_env_CXXCPP_set=${CXXCPP+set} +ac_cv_env_CXXCPP_value=$CXXCPP +ac_env_F77_set=${F77+set} +ac_env_F77_value=$F77 +ac_cv_env_F77_set=${F77+set} +ac_cv_env_F77_value=$F77 +ac_env_FFLAGS_set=${FFLAGS+set} +ac_env_FFLAGS_value=$FFLAGS +ac_cv_env_FFLAGS_set=${FFLAGS+set} +ac_cv_env_FFLAGS_value=$FFLAGS + +# +# Report the --help message. +# +if test "$ac_init_help" = "long"; then + # Omit some internal or obsolete options to make the list less imposing. + # This message is too long to be a string in the A/UX 3.1 sh. + cat <<_ACEOF +\`configure' configures this package to adapt to many kinds of systems. + +Usage: $0 [OPTION]... [VAR=VALUE]... + +To assign environment variables (e.g., CC, CFLAGS...), specify them as +VAR=VALUE. See below for descriptions of some of the useful variables. + +Defaults for the options are specified in brackets. + +Configuration: + -h, --help display this help and exit + --help=short display options specific to this package + --help=recursive display the short help of all the included packages + -V, --version display version information and exit + -q, --quiet, --silent do not print \`checking...' messages + --cache-file=FILE cache test results in FILE [disabled] + -C, --config-cache alias for \`--cache-file=config.cache' + -n, --no-create do not create output files + --srcdir=DIR find the sources in DIR [configure dir or \`..'] + +_ACEOF + + cat <<_ACEOF +Installation directories: + --prefix=PREFIX install architecture-independent files in PREFIX + [$ac_default_prefix] + --exec-prefix=EPREFIX install architecture-dependent files in EPREFIX + [PREFIX] + +By default, \`make install' will install all the files in +\`$ac_default_prefix/bin', \`$ac_default_prefix/lib' etc. You can specify +an installation prefix other than \`$ac_default_prefix' using \`--prefix', +for instance \`--prefix=\$HOME'. + +For better control, use the options below. + +Fine tuning of the installation directories: + --bindir=DIR user executables [EPREFIX/bin] + --sbindir=DIR system admin executables [EPREFIX/sbin] + --libexecdir=DIR program executables [EPREFIX/libexec] + --datadir=DIR read-only architecture-independent data [PREFIX/share] + --sysconfdir=DIR read-only single-machine data [PREFIX/etc] + --sharedstatedir=DIR modifiable architecture-independent data [PREFIX/com] + --localstatedir=DIR modifiable single-machine data [PREFIX/var] + --libdir=DIR object code libraries [EPREFIX/lib] + --includedir=DIR C header files [PREFIX/include] + --oldincludedir=DIR C header files for non-gcc [/usr/include] + --infodir=DIR info documentation [PREFIX/info] + --mandir=DIR man documentation [PREFIX/man] +_ACEOF + + cat <<\_ACEOF + +Program names: + --program-prefix=PREFIX prepend PREFIX to installed program names + --program-suffix=SUFFIX append SUFFIX to installed program names + --program-transform-name=PROGRAM run sed PROGRAM on installed program names + +System types: + --build=BUILD configure for building on BUILD [guessed] + --host=HOST cross-compile to build programs to run on HOST [BUILD] +_ACEOF +fi + +if test -n "$ac_init_help"; then + + cat <<\_ACEOF + +Optional Features: + --disable-FEATURE do not include FEATURE (same as --enable-FEATURE=no) + --enable-FEATURE[=ARG] include FEATURE [ARG=yes] + --enable-maintainer-mode enable make rules and dependencies not useful + (and sometimes confusing) to the casual installer + --enable-debug Turn on debugging + --enable-intel Turn on support for the Intel compiler + --enable-openmp Turn on support for the Intel compiler + --enable-parmetis Compile with the ParMetis library + --enable-umfpack Compile with the UMFPACK direct solver library + --disable-dependency-tracking speeds up one-time build + --enable-dependency-tracking do not reject slow dependency extractors + --enable-shared[=PKGS] + build shared libraries [default=yes] + --enable-static[=PKGS] + build static libraries [default=yes] + --enable-fast-install[=PKGS] + optimize for fast installation [default=yes] + --disable-libtool-lock avoid locking (might break parallel builds) + +Optional Packages: + --with-PACKAGE[=ARG] use PACKAGE [ARG=yes] + --without-PACKAGE do not use PACKAGE (same as --with-PACKAGE=no) + --with-mpi=MPI_DIR + --with-gnu-ld assume the C compiler uses GNU ld [default=no] + --with-pic try to use only PIC/non-PIC objects [default=use + both] + --with-tags[=TAGS] + include additional configurations [automatic] + +Some influential environment variables: + CC C compiler command + CFLAGS C compiler flags + LDFLAGS linker flags, e.g. -L<lib dir> if you have libraries in a + nonstandard directory <lib dir> + CPPFLAGS C/C++ preprocessor flags, e.g. -I<include dir> if you have + headers in a nonstandard directory <include dir> + CXX C++ compiler command + CXXFLAGS C++ compiler flags + CPP C preprocessor + CXXCPP C++ preprocessor + F77 Fortran 77 compiler command + FFLAGS Fortran 77 compiler flags + +Use these variables to override the choices made by `configure' or to help +it to find libraries and programs with nonstandard names/locations. + +_ACEOF +fi + +if test "$ac_init_help" = "recursive"; then + # If there are subdirs, report their specific --help. + ac_popdir=`pwd` + for ac_dir in : $ac_subdirs_all; do test "x$ac_dir" = x: && continue + test -d $ac_dir || continue + ac_builddir=. + +if test "$ac_dir" != .; then + ac_dir_suffix=/`echo "$ac_dir" | sed 's,^\.[\\/],,'` + # A "../" for each directory in $ac_dir_suffix. + ac_top_builddir=`echo "$ac_dir_suffix" | sed 's,/[^\\/]*,../,g'` +else + ac_dir_suffix= ac_top_builddir= +fi + +case $srcdir in + .) # No --srcdir option. We are building in place. + ac_srcdir=. + if test -z "$ac_top_builddir"; then + ac_top_srcdir=. + else + ac_top_srcdir=`echo $ac_top_builddir | sed 's,/$,,'` + fi ;; + [\\/]* | ?:[\\/]* ) # Absolute path. + ac_srcdir=$srcdir$ac_dir_suffix; + ac_top_srcdir=$srcdir ;; + *) # Relative path. + ac_srcdir=$ac_top_builddir$srcdir$ac_dir_suffix + ac_top_srcdir=$ac_top_builddir$srcdir ;; +esac + +# Do not use `cd foo && pwd` to compute absolute paths, because +# the directories may not exist. +case `pwd` in +.) ac_abs_builddir="$ac_dir";; +*) + case "$ac_dir" in + .) ac_abs_builddir=`pwd`;; + [\\/]* | ?:[\\/]* ) ac_abs_builddir="$ac_dir";; + *) ac_abs_builddir=`pwd`/"$ac_dir";; + esac;; +esac +case $ac_abs_builddir in +.) ac_abs_top_builddir=${ac_top_builddir}.;; +*) + case ${ac_top_builddir}. in + .) ac_abs_top_builddir=$ac_abs_builddir;; + [\\/]* | ?:[\\/]* ) ac_abs_top_builddir=${ac_top_builddir}.;; + *) ac_abs_top_builddir=$ac_abs_builddir/${ac_top_builddir}.;; + esac;; +esac +case $ac_abs_builddir in +.) ac_abs_srcdir=$ac_srcdir;; +*) + case $ac_srcdir in + .) ac_abs_srcdir=$ac_abs_builddir;; + [\\/]* | ?:[\\/]* ) ac_abs_srcdir=$ac_srcdir;; + *) ac_abs_srcdir=$ac_abs_builddir/$ac_srcdir;; + esac;; +esac +case $ac_abs_builddir in +.) ac_abs_top_srcdir=$ac_top_srcdir;; +*) + case $ac_top_srcdir in + .) ac_abs_top_srcdir=$ac_abs_builddir;; + [\\/]* | ?:[\\/]* ) ac_abs_top_srcdir=$ac_top_srcdir;; + *) ac_abs_top_srcdir=$ac_abs_builddir/$ac_top_srcdir;; + esac;; +esac + + cd $ac_dir + # Check for guested configure; otherwise get Cygnus style configure. + if test -f $ac_srcdir/configure.gnu; then + echo + $SHELL $ac_srcdir/configure.gnu --help=recursive + elif test -f $ac_srcdir/configure; then + echo + $SHELL $ac_srcdir/configure --help=recursive + elif test -f $ac_srcdir/configure.ac || + test -f $ac_srcdir/configure.in; then + echo + $ac_configure --help + else + echo "$as_me: WARNING: no configuration information is in $ac_dir" >&2 + fi + cd $ac_popdir + done +fi + +test -n "$ac_init_help" && exit 0 +if $ac_init_version; then + cat <<\_ACEOF + +Copyright (C) 2003 Free Software Foundation, Inc. +This configure script is free software; the Free Software Foundation +gives unlimited permission to copy, distribute and modify it. +_ACEOF + exit 0 +fi +exec 5>config.log +cat >&5 <<_ACEOF +This file contains any messages produced by compilers while +running configure, to aid debugging if configure makes a mistake. + +It was created by $as_me, which was +generated by GNU Autoconf 2.59. Invocation command line was + + $ $0 $@ + +_ACEOF +{ +cat <<_ASUNAME +## --------- ## +## Platform. ## +## --------- ## + +hostname = `(hostname || uname -n) 2>/dev/null | sed 1q` +uname -m = `(uname -m) 2>/dev/null || echo unknown` +uname -r = `(uname -r) 2>/dev/null || echo unknown` +uname -s = `(uname -s) 2>/dev/null || echo unknown` +uname -v = `(uname -v) 2>/dev/null || echo unknown` + +/usr/bin/uname -p = `(/usr/bin/uname -p) 2>/dev/null || echo unknown` +/bin/uname -X = `(/bin/uname -X) 2>/dev/null || echo unknown` + +/bin/arch = `(/bin/arch) 2>/dev/null || echo unknown` +/usr/bin/arch -k = `(/usr/bin/arch -k) 2>/dev/null || echo unknown` +/usr/convex/getsysinfo = `(/usr/convex/getsysinfo) 2>/dev/null || echo unknown` +hostinfo = `(hostinfo) 2>/dev/null || echo unknown` +/bin/machine = `(/bin/machine) 2>/dev/null || echo unknown` +/usr/bin/oslevel = `(/usr/bin/oslevel) 2>/dev/null || echo unknown` +/bin/universe = `(/bin/universe) 2>/dev/null || echo unknown` + +_ASUNAME + +as_save_IFS=$IFS; IFS=$PATH_SEPARATOR +for as_dir in $PATH +do + IFS=$as_save_IFS + test -z "$as_dir" && as_dir=. + echo "PATH: $as_dir" +done + +} >&5 + +cat >&5 <<_ACEOF + + +## ----------- ## +## Core tests. ## +## ----------- ## + +_ACEOF + + +# Keep a trace of the command line. +# Strip out --no-create and --no-recursion so they do not pile up. +# Strip out --silent because we don't want to record it for future runs. +# Also quote any args containing shell meta-characters. +# Make two passes to allow for proper duplicate-argument suppression. +ac_configure_args= +ac_configure_args0= +ac_configure_args1= +ac_sep= +ac_must_keep_next=false +for ac_pass in 1 2 +do + for ac_arg + do + case $ac_arg in + -no-create | --no-c* | -n | -no-recursion | --no-r*) continue ;; + -q | -quiet | --quiet | --quie | --qui | --qu | --q \ + | -silent | --silent | --silen | --sile | --sil) + continue ;; + *" "*|*" "*|*[\[\]\~\#\$\^\&\*\(\)\{\}\\\|\;\<\>\?\"\']*) + ac_arg=`echo "$ac_arg" | sed "s/'/'\\\\\\\\''/g"` ;; + esac + case $ac_pass in + 1) ac_configure_args0="$ac_configure_args0 '$ac_arg'" ;; + 2) + ac_configure_args1="$ac_configure_args1 '$ac_arg'" + if test $ac_must_keep_next = true; then + ac_must_keep_next=false # Got value, back to normal. + else + case $ac_arg in + *=* | --config-cache | -C | -disable-* | --disable-* \ + | -enable-* | --enable-* | -gas | --g* | -nfp | --nf* \ + | -q | -quiet | --q* | -silent | --sil* | -v | -verb* \ + | -with-* | --with-* | -without-* | --without-* | --x) + case "$ac_configure_args0 " in + "$ac_configure_args1"*" '$ac_arg' "* ) continue ;; + esac + ;; + -* ) ac_must_keep_next=true ;; + esac + fi + ac_configure_args="$ac_configure_args$ac_sep'$ac_arg'" + # Get rid of the leading space. + ac_sep=" " + ;; + esac + done +done +$as_unset ac_configure_args0 || test "${ac_configure_args0+set}" != set || { ac_configure_args0=; export ac_configure_args0; } +$as_unset ac_configure_args1 || test "${ac_configure_args1+set}" != set || { ac_configure_args1=; export ac_configure_args1; } + +# When interrupted or exit'd, cleanup temporary files, and complete +# config.log. We remove comments because anyway the quotes in there +# would cause problems or look ugly. +# WARNING: Be sure not to use single quotes in there, as some shells, +# such as our DU 5.0 friend, will then `close' the trap. +trap 'exit_status=$? + # Save into config.log some information that might help in debugging. + { + echo + + cat <<\_ASBOX +## ---------------- ## +## Cache variables. ## +## ---------------- ## +_ASBOX + echo + # The following way of writing the cache mishandles newlines in values, +{ + (set) 2>&1 | + case `(ac_space='"'"' '"'"'; set | grep ac_space) 2>&1` in + *ac_space=\ *) + sed -n \ + "s/'"'"'/'"'"'\\\\'"'"''"'"'/g; + s/^\\([_$as_cr_alnum]*_cv_[_$as_cr_alnum]*\\)=\\(.*\\)/\\1='"'"'\\2'"'"'/p" + ;; + *) + sed -n \ + "s/^\\([_$as_cr_alnum]*_cv_[_$as_cr_alnum]*\\)=\\(.*\\)/\\1=\\2/p" + ;; + esac; +} + echo + + cat <<\_ASBOX +## ----------------- ## +## Output variables. ## +## ----------------- ## +_ASBOX + echo + for ac_var in $ac_subst_vars + do + eval ac_val=$`echo $ac_var` + echo "$ac_var='"'"'$ac_val'"'"'" + done | sort + echo + + if test -n "$ac_subst_files"; then + cat <<\_ASBOX +## ------------- ## +## Output files. ## +## ------------- ## +_ASBOX + echo + for ac_var in $ac_subst_files + do + eval ac_val=$`echo $ac_var` + echo "$ac_var='"'"'$ac_val'"'"'" + done | sort + echo + fi + + if test -s confdefs.h; then + cat <<\_ASBOX +## ----------- ## +## confdefs.h. ## +## ----------- ## +_ASBOX + echo + sed "/^$/d" confdefs.h | sort + echo + fi + test "$ac_signal" != 0 && + echo "$as_me: caught signal $ac_signal" + echo "$as_me: exit $exit_status" + } >&5 + rm -f core *.core && + rm -rf conftest* confdefs* conf$$* $ac_clean_files && + exit $exit_status + ' 0 +for ac_signal in 1 2 13 15; do + trap 'ac_signal='$ac_signal'; { (exit 1); exit 1; }' $ac_signal +done +ac_signal=0 + +# confdefs.h avoids OS command line length limits that DEFS can exceed. +rm -rf conftest* confdefs.h +# AIX cpp loses on an empty file, so make sure it contains at least a newline. +echo >confdefs.h + +# Predefined preprocessor variables. + +cat >>confdefs.h <<_ACEOF +#define PACKAGE_NAME "$PACKAGE_NAME" +_ACEOF + + +cat >>confdefs.h <<_ACEOF +#define PACKAGE_TARNAME "$PACKAGE_TARNAME" +_ACEOF + + +cat >>confdefs.h <<_ACEOF +#define PACKAGE_VERSION "$PACKAGE_VERSION" +_ACEOF + + +cat >>confdefs.h <<_ACEOF +#define PACKAGE_STRING "$PACKAGE_STRING" +_ACEOF + + +cat >>confdefs.h <<_ACEOF +#define PACKAGE_BUGREPORT "$PACKAGE_BUGREPORT" +_ACEOF + + +# Let the site file select an alternate cache file if it wants to. +# Prefer explicitly selected file to automatically selected ones. +if test -z "$CONFIG_SITE"; then + if test "x$prefix" != xNONE; then + CONFIG_SITE="$prefix/share/config.site $prefix/etc/config.site" + else + CONFIG_SITE="$ac_default_prefix/share/config.site $ac_default_prefix/etc/config.site" + fi +fi +for ac_site_file in $CONFIG_SITE; do + if test -r "$ac_site_file"; then + { echo "$as_me:$LINENO: loading site script $ac_site_file" >&5 +echo "$as_me: loading site script $ac_site_file" >&6;} + sed 's/^/| /' "$ac_site_file" >&5 + . "$ac_site_file" + fi +done + +if test -r "$cache_file"; then + # Some versions of bash will fail to source /dev/null (special + # files actually), so we avoid doing that. + if test -f "$cache_file"; then + { echo "$as_me:$LINENO: loading cache $cache_file" >&5 +echo "$as_me: loading cache $cache_file" >&6;} + case $cache_file in + [\\/]* | ?:[\\/]* ) . $cache_file;; + *) . ./$cache_file;; + esac + fi +else + { echo "$as_me:$LINENO: creating cache $cache_file" >&5 +echo "$as_me: creating cache $cache_file" >&6;} + >$cache_file +fi + +# Check that the precious variables saved in the cache have kept the same +# value. +ac_cache_corrupted=false +for ac_var in `(set) 2>&1 | + sed -n 's/^ac_env_\([a-zA-Z_0-9]*\)_set=.*/\1/p'`; do + eval ac_old_set=\$ac_cv_env_${ac_var}_set + eval ac_new_set=\$ac_env_${ac_var}_set + eval ac_old_val="\$ac_cv_env_${ac_var}_value" + eval ac_new_val="\$ac_env_${ac_var}_value" + case $ac_old_set,$ac_new_set in + set,) + { echo "$as_me:$LINENO: error: \`$ac_var' was set to \`$ac_old_val' in the previous run" >&5 +echo "$as_me: error: \`$ac_var' was set to \`$ac_old_val' in the previous run" >&2;} + ac_cache_corrupted=: ;; + ,set) + { echo "$as_me:$LINENO: error: \`$ac_var' was not set in the previous run" >&5 +echo "$as_me: error: \`$ac_var' was not set in the previous run" >&2;} + ac_cache_corrupted=: ;; + ,);; + *) + if test "x$ac_old_val" != "x$ac_new_val"; then + { echo "$as_me:$LINENO: error: \`$ac_var' has changed since the previous run:" >&5 +echo "$as_me: error: \`$ac_var' has changed since the previous run:" >&2;} + { echo "$as_me:$LINENO: former value: $ac_old_val" >&5 +echo "$as_me: former value: $ac_old_val" >&2;} + { echo "$as_me:$LINENO: current value: $ac_new_val" >&5 +echo "$as_me: current value: $ac_new_val" >&2;} + ac_cache_corrupted=: + fi;; + esac + # Pass precious variables to config.status. + if test "$ac_new_set" = set; then + case $ac_new_val in + *" "*|*" "*|*[\[\]\~\#\$\^\&\*\(\)\{\}\\\|\;\<\>\?\"\']*) + ac_arg=$ac_var=`echo "$ac_new_val" | sed "s/'/'\\\\\\\\''/g"` ;; + *) ac_arg=$ac_var=$ac_new_val ;; + esac + case " $ac_configure_args " in + *" '$ac_arg' "*) ;; # Avoid dups. Use of quotes ensures accuracy. + *) ac_configure_args="$ac_configure_args '$ac_arg'" ;; + esac + fi +done +if $ac_cache_corrupted; then + { echo "$as_me:$LINENO: error: changes in the environment can compromise the build" >&5 +echo "$as_me: error: changes in the environment can compromise the build" >&2;} + { { echo "$as_me:$LINENO: error: run \`make distclean' and/or \`rm $cache_file' and start over" >&5 +echo "$as_me: error: run \`make distclean' and/or \`rm $cache_file' and start over" >&2;} + { (exit 1); exit 1; }; } +fi + +ac_ext=c +ac_cpp='$CPP $CPPFLAGS' +ac_compile='$CC -c $CFLAGS $CPPFLAGS conftest.$ac_ext >&5' +ac_link='$CC -o conftest$ac_exeext $CFLAGS $CPPFLAGS $LDFLAGS conftest.$ac_ext $LIBS >&5' +ac_compiler_gnu=$ac_cv_c_compiler_gnu + + + + + + + + + + + + + + + + + + + +am__api_version="1.9" +ac_aux_dir= +for ac_dir in $srcdir $srcdir/.. $srcdir/../..; do + if test -f $ac_dir/install-sh; then + ac_aux_dir=$ac_dir + ac_install_sh="$ac_aux_dir/install-sh -c" + break + elif test -f $ac_dir/install.sh; then + ac_aux_dir=$ac_dir + ac_install_sh="$ac_aux_dir/install.sh -c" + break + elif test -f $ac_dir/shtool; then + ac_aux_dir=$ac_dir + ac_install_sh="$ac_aux_dir/shtool install -c" + break + fi +done +if test -z "$ac_aux_dir"; then + { { echo "$as_me:$LINENO: error: cannot find install-sh or install.sh in $srcdir $srcdir/.. $srcdir/../.." >&5 +echo "$as_me: error: cannot find install-sh or install.sh in $srcdir $srcdir/.. $srcdir/../.." >&2;} + { (exit 1); exit 1; }; } +fi +ac_config_guess="$SHELL $ac_aux_dir/config.guess" +ac_config_sub="$SHELL $ac_aux_dir/config.sub" +ac_configure="$SHELL $ac_aux_dir/configure" # This should be Cygnus configure. + +# Find a good install program. We prefer a C program (faster), +# so one script is as good as another. But avoid the broken or +# incompatible versions: +# SysV /etc/install, /usr/sbin/install +# SunOS /usr/etc/install +# IRIX /sbin/install +# AIX /bin/install +# AmigaOS /C/install, which installs bootblocks on floppy discs +# AIX 4 /usr/bin/installbsd, which doesn't work without a -g flag +# AFS /usr/afsws/bin/install, which mishandles nonexistent args +# SVR4 /usr/ucb/install, which tries to use the nonexistent group "staff" +# OS/2's system install, which has a completely different semantic +# ./install, which can be erroneously created by make from ./install.sh. +echo "$as_me:$LINENO: checking for a BSD-compatible install" >&5 +echo $ECHO_N "checking for a BSD-compatible install... $ECHO_C" >&6 +if test -z "$INSTALL"; then +if test "${ac_cv_path_install+set}" = set; then + echo $ECHO_N "(cached) $ECHO_C" >&6 +else + as_save_IFS=$IFS; IFS=$PATH_SEPARATOR +for as_dir in $PATH +do + IFS=$as_save_IFS + test -z "$as_dir" && as_dir=. + # Account for people who put trailing slashes in PATH elements. +case $as_dir/ in + ./ | .// | /cC/* | \ + /etc/* | /usr/sbin/* | /usr/etc/* | /sbin/* | /usr/afsws/bin/* | \ + ?:\\/os2\\/install\\/* | ?:\\/OS2\\/INSTALL\\/* | \ + /usr/ucb/* ) ;; + *) + # OSF1 and SCO ODT 3.0 have their own names for install. + # Don't use installbsd from OSF since it installs stuff as root + # by default. + for ac_prog in ginstall scoinst install; do + for ac_exec_ext in '' $ac_executable_extensions; do + if $as_executable_p "$as_dir/$ac_prog$ac_exec_ext"; then + if test $ac_prog = install && + grep dspmsg "$as_dir/$ac_prog$ac_exec_ext" >/dev/null 2>&1; then + # AIX install. It has an incompatible calling convention. + : + elif test $ac_prog = install && + grep pwplus "$as_dir/$ac_prog$ac_exec_ext" >/dev/null 2>&1; then + # program-specific install script used by HP pwplus--don't use. + : + else + ac_cv_path_install="$as_dir/$ac_prog$ac_exec_ext -c" + break 3 + fi + fi + done + done + ;; +esac +done + + +fi + if test "${ac_cv_path_install+set}" = set; then + INSTALL=$ac_cv_path_install + else + # As a last resort, use the slow shell script. We don't cache a + # path for INSTALL within a source directory, because that will + # break other packages using the cache if that directory is + # removed, or if the path is relative. + INSTALL=$ac_install_sh + fi +fi +echo "$as_me:$LINENO: result: $INSTALL" >&5 +echo "${ECHO_T}$INSTALL" >&6 + +# Use test -z because SunOS4 sh mishandles braces in ${var-val}. +# It thinks the first close brace ends the variable substitution. +test -z "$INSTALL_PROGRAM" && INSTALL_PROGRAM='${INSTALL}' + +test -z "$INSTALL_SCRIPT" && INSTALL_SCRIPT='${INSTALL}' + +test -z "$INSTALL_DATA" && INSTALL_DATA='${INSTALL} -m 644' + +echo "$as_me:$LINENO: checking whether build environment is sane" >&5 +echo $ECHO_N "checking whether build environment is sane... $ECHO_C" >&6 +# Just in case +sleep 1 +echo timestamp > conftest.file +# Do `set' in a subshell so we don't clobber the current shell's +# arguments. Must try -L first in case configure is actually a +# symlink; some systems play weird games with the mod time of symlinks +# (eg FreeBSD returns the mod time of the symlink's containing +# directory). +if ( + set X `ls -Lt $srcdir/configure conftest.file 2> /dev/null` + if test "$*" = "X"; then + # -L didn't work. + set X `ls -t $srcdir/configure conftest.file` + fi + rm -f conftest.file + if test "$*" != "X $srcdir/configure conftest.file" \ + && test "$*" != "X conftest.file $srcdir/configure"; then + + # If neither matched, then we have a broken ls. This can happen + # if, for instance, CONFIG_SHELL is bash and it inherits a + # broken ls alias from the environment. This has actually + # happened. Such a system could not be considered "sane". + { { echo "$as_me:$LINENO: error: ls -t appears to fail. Make sure there is not a broken +alias in your environment" >&5 +echo "$as_me: error: ls -t appears to fail. Make sure there is not a broken +alias in your environment" >&2;} + { (exit 1); exit 1; }; } + fi + + test "$2" = conftest.file + ) +then + # Ok. + : +else + { { echo "$as_me:$LINENO: error: newly created file is older than distributed files! +Check your system clock" >&5 +echo "$as_me: error: newly created file is older than distributed files! +Check your system clock" >&2;} + { (exit 1); exit 1; }; } +fi +echo "$as_me:$LINENO: result: yes" >&5 +echo "${ECHO_T}yes" >&6 +test "$program_prefix" != NONE && + program_transform_name="s,^,$program_prefix,;$program_transform_name" +# Use a double $ so make ignores it. +test "$program_suffix" != NONE && + program_transform_name="s,\$,$program_suffix,;$program_transform_name" +# Double any \ or $. echo might interpret backslashes. +# By default was `s,x,x', remove it if useless. +cat <<\_ACEOF >conftest.sed +s/[\\$]/&&/g;s/;s,x,x,$// +_ACEOF +program_transform_name=`echo $program_transform_name | sed -f conftest.sed` +rm conftest.sed + +# expand $ac_aux_dir to an absolute path +am_aux_dir=`cd $ac_aux_dir && pwd` + +test x"${MISSING+set}" = xset || MISSING="\${SHELL} $am_aux_dir/missing" +# Use eval to expand $SHELL +if eval "$MISSING --run true"; then + am_missing_run="$MISSING --run " +else + am_missing_run= + { echo "$as_me:$LINENO: WARNING: \`missing' script is too old or missing" >&5 +echo "$as_me: WARNING: \`missing' script is too old or missing" >&2;} +fi + +if mkdir -p --version . >/dev/null 2>&1 && test ! -d ./--version; then + # We used to keeping the `.' as first argument, in order to + # allow $(mkdir_p) to be used without argument. As in + # $(mkdir_p) $(somedir) + # where $(somedir) is conditionally defined. However this is wrong + # for two reasons: + # 1. if the package is installed by a user who cannot write `.' + # make install will fail, + # 2. the above comment should most certainly read + # $(mkdir_p) $(DESTDIR)$(somedir) + # so it does not work when $(somedir) is undefined and + # $(DESTDIR) is not. + # To support the latter case, we have to write + # test -z "$(somedir)" || $(mkdir_p) $(DESTDIR)$(somedir), + # so the `.' trick is pointless. + mkdir_p='mkdir -p --' +else + # On NextStep and OpenStep, the `mkdir' command does not + # recognize any option. It will interpret all options as + # directories to create, and then abort because `.' already + # exists. + for d in ./-p ./--version; + do + test -d $d && rmdir $d + done + # $(mkinstalldirs) is defined by Automake if mkinstalldirs exists. + if test -f "$ac_aux_dir/mkinstalldirs"; then + mkdir_p='$(mkinstalldirs)' + else + mkdir_p='$(install_sh) -d' + fi +fi + +for ac_prog in gawk mawk nawk awk +do + # Extract the first word of "$ac_prog", so it can be a program name with args. +set dummy $ac_prog; ac_word=$2 +echo "$as_me:$LINENO: checking for $ac_word" >&5 +echo $ECHO_N "checking for $ac_word... $ECHO_C" >&6 +if test "${ac_cv_prog_AWK+set}" = set; then + echo $ECHO_N "(cached) $ECHO_C" >&6 +else + if test -n "$AWK"; then + ac_cv_prog_AWK="$AWK" # Let the user override the test. +else +as_save_IFS=$IFS; IFS=$PATH_SEPARATOR +for as_dir in $PATH +do + IFS=$as_save_IFS + test -z "$as_dir" && as_dir=. + for ac_exec_ext in '' $ac_executable_extensions; do + if $as_executable_p "$as_dir/$ac_word$ac_exec_ext"; then + ac_cv_prog_AWK="$ac_prog" + echo "$as_me:$LINENO: found $as_dir/$ac_word$ac_exec_ext" >&5 + break 2 + fi +done +done + +fi +fi +AWK=$ac_cv_prog_AWK +if test -n "$AWK"; then + echo "$as_me:$LINENO: result: $AWK" >&5 +echo "${ECHO_T}$AWK" >&6 +else + echo "$as_me:$LINENO: result: no" >&5 +echo "${ECHO_T}no" >&6 +fi + + test -n "$AWK" && break +done + +echo "$as_me:$LINENO: checking whether ${MAKE-make} sets \$(MAKE)" >&5 +echo $ECHO_N "checking whether ${MAKE-make} sets \$(MAKE)... $ECHO_C" >&6 +set dummy ${MAKE-make}; ac_make=`echo "$2" | sed 'y,:./+-,___p_,'` +if eval "test \"\${ac_cv_prog_make_${ac_make}_set+set}\" = set"; then + echo $ECHO_N "(cached) $ECHO_C" >&6 +else + cat >conftest.make <<\_ACEOF +all: + @echo 'ac_maketemp="$(MAKE)"' +_ACEOF +# GNU make sometimes prints "make[1]: Entering...", which would confuse us. +eval `${MAKE-make} -f conftest.make 2>/dev/null | grep temp=` +if test -n "$ac_maketemp"; then + eval ac_cv_prog_make_${ac_make}_set=yes +else + eval ac_cv_prog_make_${ac_make}_set=no +fi +rm -f conftest.make +fi +if eval "test \"`echo '$ac_cv_prog_make_'${ac_make}_set`\" = yes"; then + echo "$as_me:$LINENO: result: yes" >&5 +echo "${ECHO_T}yes" >&6 + SET_MAKE= +else + echo "$as_me:$LINENO: result: no" >&5 +echo "${ECHO_T}no" >&6 + SET_MAKE="MAKE=${MAKE-make}" +fi + +rm -rf .tst 2>/dev/null +mkdir .tst 2>/dev/null +if test -d .tst; then + am__leading_dot=. +else + am__leading_dot=_ +fi +rmdir .tst 2>/dev/null + +# test to see if srcdir already configured +if test "`cd $srcdir && pwd`" != "`pwd`" && + test -f $srcdir/config.status; then + { { echo "$as_me:$LINENO: error: source directory already configured; run \"make distclean\" there first" >&5 +echo "$as_me: error: source directory already configured; run \"make distclean\" there first" >&2;} + { (exit 1); exit 1; }; } +fi + +# test whether we have cygpath +if test -z "$CYGPATH_W"; then + if (cygpath --version) >/dev/null 2>/dev/null; then + CYGPATH_W='cygpath -w' + else + CYGPATH_W=echo + fi +fi + + +# Define the identity of the package. + PACKAGE=AMDiS + VERSION=0.1 + + +cat >>confdefs.h <<_ACEOF +#define PACKAGE "$PACKAGE" +_ACEOF + + +cat >>confdefs.h <<_ACEOF +#define VERSION "$VERSION" +_ACEOF + +# Some tools Automake needs. + +ACLOCAL=${ACLOCAL-"${am_missing_run}aclocal-${am__api_version}"} + + +AUTOCONF=${AUTOCONF-"${am_missing_run}autoconf"} + + +AUTOMAKE=${AUTOMAKE-"${am_missing_run}automake-${am__api_version}"} + + +AUTOHEADER=${AUTOHEADER-"${am_missing_run}autoheader"} + + +MAKEINFO=${MAKEINFO-"${am_missing_run}makeinfo"} + +install_sh=${install_sh-"$am_aux_dir/install-sh"} + +# Installed binaries are usually stripped using `strip' when the user +# run `make install-strip'. However `strip' might not be the right +# tool to use in cross-compilation environments, therefore Automake +# will honor the `STRIP' environment variable to overrule this program. +if test "$cross_compiling" != no; then + if test -n "$ac_tool_prefix"; then + # Extract the first word of "${ac_tool_prefix}strip", so it can be a program name with args. +set dummy ${ac_tool_prefix}strip; ac_word=$2 +echo "$as_me:$LINENO: checking for $ac_word" >&5 +echo $ECHO_N "checking for $ac_word... $ECHO_C" >&6 +if test "${ac_cv_prog_STRIP+set}" = set; then + echo $ECHO_N "(cached) $ECHO_C" >&6 +else + if test -n "$STRIP"; then + ac_cv_prog_STRIP="$STRIP" # Let the user override the test. +else +as_save_IFS=$IFS; IFS=$PATH_SEPARATOR +for as_dir in $PATH +do + IFS=$as_save_IFS + test -z "$as_dir" && as_dir=. + for ac_exec_ext in '' $ac_executable_extensions; do + if $as_executable_p "$as_dir/$ac_word$ac_exec_ext"; then + ac_cv_prog_STRIP="${ac_tool_prefix}strip" + echo "$as_me:$LINENO: found $as_dir/$ac_word$ac_exec_ext" >&5 + break 2 + fi +done +done + +fi +fi +STRIP=$ac_cv_prog_STRIP +if test -n "$STRIP"; then + echo "$as_me:$LINENO: result: $STRIP" >&5 +echo "${ECHO_T}$STRIP" >&6 +else + echo "$as_me:$LINENO: result: no" >&5 +echo "${ECHO_T}no" >&6 +fi + +fi +if test -z "$ac_cv_prog_STRIP"; then + ac_ct_STRIP=$STRIP + # Extract the first word of "strip", so it can be a program name with args. +set dummy strip; ac_word=$2 +echo "$as_me:$LINENO: checking for $ac_word" >&5 +echo $ECHO_N "checking for $ac_word... $ECHO_C" >&6 +if test "${ac_cv_prog_ac_ct_STRIP+set}" = set; then + echo $ECHO_N "(cached) $ECHO_C" >&6 +else + if test -n "$ac_ct_STRIP"; then + ac_cv_prog_ac_ct_STRIP="$ac_ct_STRIP" # Let the user override the test. +else +as_save_IFS=$IFS; IFS=$PATH_SEPARATOR +for as_dir in $PATH +do + IFS=$as_save_IFS + test -z "$as_dir" && as_dir=. + for ac_exec_ext in '' $ac_executable_extensions; do + if $as_executable_p "$as_dir/$ac_word$ac_exec_ext"; then + ac_cv_prog_ac_ct_STRIP="strip" + echo "$as_me:$LINENO: found $as_dir/$ac_word$ac_exec_ext" >&5 + break 2 + fi +done +done + + test -z "$ac_cv_prog_ac_ct_STRIP" && ac_cv_prog_ac_ct_STRIP=":" +fi +fi +ac_ct_STRIP=$ac_cv_prog_ac_ct_STRIP +if test -n "$ac_ct_STRIP"; then + echo "$as_me:$LINENO: result: $ac_ct_STRIP" >&5 +echo "${ECHO_T}$ac_ct_STRIP" >&6 +else + echo "$as_me:$LINENO: result: no" >&5 +echo "${ECHO_T}no" >&6 +fi + + STRIP=$ac_ct_STRIP +else + STRIP="$ac_cv_prog_STRIP" +fi + +fi +INSTALL_STRIP_PROGRAM="\${SHELL} \$(install_sh) -c -s" + +# We need awk for the "check" target. The system "awk" is bad on +# some platforms. +# Always define AMTAR for backward compatibility. + +AMTAR=${AMTAR-"${am_missing_run}tar"} + +am__tar='${AMTAR} chof - "$$tardir"'; am__untar='${AMTAR} xf -' + + + + + +echo "$as_me:$LINENO: checking whether to enable maintainer-specific portions of Makefiles" >&5 +echo $ECHO_N "checking whether to enable maintainer-specific portions of Makefiles... $ECHO_C" >&6 + # Check whether --enable-maintainer-mode or --disable-maintainer-mode was given. +if test "${enable_maintainer_mode+set}" = set; then + enableval="$enable_maintainer_mode" + USE_MAINTAINER_MODE=$enableval +else + USE_MAINTAINER_MODE=no +fi; + echo "$as_me:$LINENO: result: $USE_MAINTAINER_MODE" >&5 +echo "${ECHO_T}$USE_MAINTAINER_MODE" >&6 + + +if test $USE_MAINTAINER_MODE = yes; then + MAINTAINER_MODE_TRUE= + MAINTAINER_MODE_FALSE='#' +else + MAINTAINER_MODE_TRUE='#' + MAINTAINER_MODE_FALSE= +fi + + MAINT=$MAINTAINER_MODE_TRUE + + + +#AC_DISABLE_SHARED + +# Check whether --enable-debug or --disable-debug was given. +if test "${enable_debug+set}" = set; then + enableval="$enable_debug" + case "${enableval}" in + yes) debug=true ;; + no) debug=false ;; + *) { { echo "$as_me:$LINENO: error: bad value ${enableval} for --enable-debug" >&5 +echo "$as_me: error: bad value ${enableval} for --enable-debug" >&2;} + { (exit 1); exit 1; }; } ;; + esac +else + debug=false +fi; + + +if test $debug = true; then + AMDIS_DEBUG_TRUE= + AMDIS_DEBUG_FALSE='#' +else + AMDIS_DEBUG_TRUE='#' + AMDIS_DEBUG_FALSE= +fi + + +# Check whether --enable-intel or --disable-intel was given. +if test "${enable_intel+set}" = set; then + enableval="$enable_intel" + case "${enableval}" in + yes) intel=true ;; + no) intel=false ;; + *) { { echo "$as_me:$LINENO: error: bad value ${enableval} for --enable-intel" >&5 +echo "$as_me: error: bad value ${enableval} for --enable-intel" >&2;} + { (exit 1); exit 1; }; } ;; + esac +else + intel=false +fi; +if test $intel = true +then + CXX=icpc + + CC=icc + +fi + + +if test $intel = true; then + AMDIS_INTEL_TRUE= + AMDIS_INTEL_FALSE='#' +else + AMDIS_INTEL_TRUE='#' + AMDIS_INTEL_FALSE= +fi + + +# Check whether --enable-openmp or --disable-openmp was given. +if test "${enable_openmp+set}" = set; then + enableval="$enable_openmp" + case "${enableval}" in + yes) openmp=true ;; + no) openmp=false ;; + *) { { echo "$as_me:$LINENO: error: bad value ${enableval} for --enable-openmp" >&5 +echo "$as_me: error: bad value ${enableval} for --enable-openmp" >&2;} + { (exit 1); exit 1; }; } ;; + esac +else + openmp=false +fi; + + +if test $openmp = true; then + AMDIS_OPENMP_TRUE= + AMDIS_OPENMP_FALSE='#' +else + AMDIS_OPENMP_TRUE='#' + AMDIS_OPENMP_FALSE= +fi + + +if test $openmp = true ; then + if test $intel = true ; then + OPENMP_FLAG=-openmp + + else + OPENMP_FLAG=-fopenmp + + fi +else + OPENMP_FLAG= + +fi + + +# Check whether --with-mpi or --without-mpi was given. +if test "${with_mpi+set}" = set; then + withval="$with_mpi" + mpidir=$withval +else + mpidir=no +fi; +MPI_DIR=$mpidir + +if test $mpidir != no ; then + CXX=$mpidir/bin/mpiCC + + CC=$mpidir/bin/mpicc + +fi + +# Check whether --enable-parmetis or --disable-parmetis was given. +if test "${enable_parmetis+set}" = set; then + enableval="$enable_parmetis" + case "${enableval}" in + yes) parmetis=true ;; + no) parmetis=false ;; + *) { { echo "$as_me:$LINENO: error: bad value ${enableval} for --enable-parmetis" >&5 +echo "$as_me: error: bad value ${enableval} for --enable-parmetis" >&2;} + { (exit 1); exit 1; }; } ;; + esac +else + parmetis=false +fi; + + +if test $parmetis = true; then + USE_PARALLEL_AMDIS_TRUE= + USE_PARALLEL_AMDIS_FALSE='#' +else + USE_PARALLEL_AMDIS_TRUE='#' + USE_PARALLEL_AMDIS_FALSE= +fi + + +# Check whether --enable-umfpack or --disable-umfpack was given. +if test "${enable_umfpack+set}" = set; then + enableval="$enable_umfpack" + case "${enableval}" in + yes) umfpack=true ;; + no) umfpack=false ;; + *) { { echo "$as_me:$LINENO: error: bad value ${enableval} for --enable-umfpack" >&5 +echo "$as_me: error: bad value ${enableval} for --enable-umfpack" >&2;} + { (exit 1); exit 1; }; } ;; + esac +else + umfpack=false +fi; + + +if test $umfpack = true; then + ENABLE_UMFPACK_TRUE= + ENABLE_UMFPACK_FALSE='#' +else + ENABLE_UMFPACK_TRUE='#' + ENABLE_UMFPACK_FALSE= +fi + + +ac_ext=c +ac_cpp='$CPP $CPPFLAGS' +ac_compile='$CC -c $CFLAGS $CPPFLAGS conftest.$ac_ext >&5' +ac_link='$CC -o conftest$ac_exeext $CFLAGS $CPPFLAGS $LDFLAGS conftest.$ac_ext $LIBS >&5' +ac_compiler_gnu=$ac_cv_c_compiler_gnu +if test -n "$ac_tool_prefix"; then + # Extract the first word of "${ac_tool_prefix}gcc", so it can be a program name with args. +set dummy ${ac_tool_prefix}gcc; ac_word=$2 +echo "$as_me:$LINENO: checking for $ac_word" >&5 +echo $ECHO_N "checking for $ac_word... $ECHO_C" >&6 +if test "${ac_cv_prog_CC+set}" = set; then + echo $ECHO_N "(cached) $ECHO_C" >&6 +else + if test -n "$CC"; then + ac_cv_prog_CC="$CC" # Let the user override the test. +else +as_save_IFS=$IFS; IFS=$PATH_SEPARATOR +for as_dir in $PATH +do + IFS=$as_save_IFS + test -z "$as_dir" && as_dir=. + for ac_exec_ext in '' $ac_executable_extensions; do + if $as_executable_p "$as_dir/$ac_word$ac_exec_ext"; then + ac_cv_prog_CC="${ac_tool_prefix}gcc" + echo "$as_me:$LINENO: found $as_dir/$ac_word$ac_exec_ext" >&5 + break 2 + fi +done +done + +fi +fi +CC=$ac_cv_prog_CC +if test -n "$CC"; then + echo "$as_me:$LINENO: result: $CC" >&5 +echo "${ECHO_T}$CC" >&6 +else + echo "$as_me:$LINENO: result: no" >&5 +echo "${ECHO_T}no" >&6 +fi + +fi +if test -z "$ac_cv_prog_CC"; then + ac_ct_CC=$CC + # Extract the first word of "gcc", so it can be a program name with args. +set dummy gcc; ac_word=$2 +echo "$as_me:$LINENO: checking for $ac_word" >&5 +echo $ECHO_N "checking for $ac_word... $ECHO_C" >&6 +if test "${ac_cv_prog_ac_ct_CC+set}" = set; then + echo $ECHO_N "(cached) $ECHO_C" >&6 +else + if test -n "$ac_ct_CC"; then + ac_cv_prog_ac_ct_CC="$ac_ct_CC" # Let the user override the test. +else +as_save_IFS=$IFS; IFS=$PATH_SEPARATOR +for as_dir in $PATH +do + IFS=$as_save_IFS + test -z "$as_dir" && as_dir=. + for ac_exec_ext in '' $ac_executable_extensions; do + if $as_executable_p "$as_dir/$ac_word$ac_exec_ext"; then + ac_cv_prog_ac_ct_CC="gcc" + echo "$as_me:$LINENO: found $as_dir/$ac_word$ac_exec_ext" >&5 + break 2 + fi +done +done + +fi +fi +ac_ct_CC=$ac_cv_prog_ac_ct_CC +if test -n "$ac_ct_CC"; then + echo "$as_me:$LINENO: result: $ac_ct_CC" >&5 +echo "${ECHO_T}$ac_ct_CC" >&6 +else + echo "$as_me:$LINENO: result: no" >&5 +echo "${ECHO_T}no" >&6 +fi + + CC=$ac_ct_CC +else + CC="$ac_cv_prog_CC" +fi + +if test -z "$CC"; then + if test -n "$ac_tool_prefix"; then + # Extract the first word of "${ac_tool_prefix}cc", so it can be a program name with args. +set dummy ${ac_tool_prefix}cc; ac_word=$2 +echo "$as_me:$LINENO: checking for $ac_word" >&5 +echo $ECHO_N "checking for $ac_word... $ECHO_C" >&6 +if test "${ac_cv_prog_CC+set}" = set; then + echo $ECHO_N "(cached) $ECHO_C" >&6 +else + if test -n "$CC"; then + ac_cv_prog_CC="$CC" # Let the user override the test. +else +as_save_IFS=$IFS; IFS=$PATH_SEPARATOR +for as_dir in $PATH +do + IFS=$as_save_IFS + test -z "$as_dir" && as_dir=. + for ac_exec_ext in '' $ac_executable_extensions; do + if $as_executable_p "$as_dir/$ac_word$ac_exec_ext"; then + ac_cv_prog_CC="${ac_tool_prefix}cc" + echo "$as_me:$LINENO: found $as_dir/$ac_word$ac_exec_ext" >&5 + break 2 + fi +done +done + +fi +fi +CC=$ac_cv_prog_CC +if test -n "$CC"; then + echo "$as_me:$LINENO: result: $CC" >&5 +echo "${ECHO_T}$CC" >&6 +else + echo "$as_me:$LINENO: result: no" >&5 +echo "${ECHO_T}no" >&6 +fi + +fi +if test -z "$ac_cv_prog_CC"; then + ac_ct_CC=$CC + # Extract the first word of "cc", so it can be a program name with args. +set dummy cc; ac_word=$2 +echo "$as_me:$LINENO: checking for $ac_word" >&5 +echo $ECHO_N "checking for $ac_word... $ECHO_C" >&6 +if test "${ac_cv_prog_ac_ct_CC+set}" = set; then + echo $ECHO_N "(cached) $ECHO_C" >&6 +else + if test -n "$ac_ct_CC"; then + ac_cv_prog_ac_ct_CC="$ac_ct_CC" # Let the user override the test. +else +as_save_IFS=$IFS; IFS=$PATH_SEPARATOR +for as_dir in $PATH +do + IFS=$as_save_IFS + test -z "$as_dir" && as_dir=. + for ac_exec_ext in '' $ac_executable_extensions; do + if $as_executable_p "$as_dir/$ac_word$ac_exec_ext"; then + ac_cv_prog_ac_ct_CC="cc" + echo "$as_me:$LINENO: found $as_dir/$ac_word$ac_exec_ext" >&5 + break 2 + fi +done +done + +fi +fi +ac_ct_CC=$ac_cv_prog_ac_ct_CC +if test -n "$ac_ct_CC"; then + echo "$as_me:$LINENO: result: $ac_ct_CC" >&5 +echo "${ECHO_T}$ac_ct_CC" >&6 +else + echo "$as_me:$LINENO: result: no" >&5 +echo "${ECHO_T}no" >&6 +fi + + CC=$ac_ct_CC +else + CC="$ac_cv_prog_CC" +fi + +fi +if test -z "$CC"; then + # Extract the first word of "cc", so it can be a program name with args. +set dummy cc; ac_word=$2 +echo "$as_me:$LINENO: checking for $ac_word" >&5 +echo $ECHO_N "checking for $ac_word... $ECHO_C" >&6 +if test "${ac_cv_prog_CC+set}" = set; then + echo $ECHO_N "(cached) $ECHO_C" >&6 +else + if test -n "$CC"; then + ac_cv_prog_CC="$CC" # Let the user override the test. +else + ac_prog_rejected=no +as_save_IFS=$IFS; IFS=$PATH_SEPARATOR +for as_dir in $PATH +do + IFS=$as_save_IFS + test -z "$as_dir" && as_dir=. + for ac_exec_ext in '' $ac_executable_extensions; do + if $as_executable_p "$as_dir/$ac_word$ac_exec_ext"; then + if test "$as_dir/$ac_word$ac_exec_ext" = "/usr/ucb/cc"; then + ac_prog_rejected=yes + continue + fi + ac_cv_prog_CC="cc" + echo "$as_me:$LINENO: found $as_dir/$ac_word$ac_exec_ext" >&5 + break 2 + fi +done +done + +if test $ac_prog_rejected = yes; then + # We found a bogon in the path, so make sure we never use it. + set dummy $ac_cv_prog_CC + shift + if test $# != 0; then + # We chose a different compiler from the bogus one. + # However, it has the same basename, so the bogon will be chosen + # first if we set CC to just the basename; use the full file name. + shift + ac_cv_prog_CC="$as_dir/$ac_word${1+' '}$@" + fi +fi +fi +fi +CC=$ac_cv_prog_CC +if test -n "$CC"; then + echo "$as_me:$LINENO: result: $CC" >&5 +echo "${ECHO_T}$CC" >&6 +else + echo "$as_me:$LINENO: result: no" >&5 +echo "${ECHO_T}no" >&6 +fi + +fi +if test -z "$CC"; then + if test -n "$ac_tool_prefix"; then + for ac_prog in cl + do + # Extract the first word of "$ac_tool_prefix$ac_prog", so it can be a program name with args. +set dummy $ac_tool_prefix$ac_prog; ac_word=$2 +echo "$as_me:$LINENO: checking for $ac_word" >&5 +echo $ECHO_N "checking for $ac_word... $ECHO_C" >&6 +if test "${ac_cv_prog_CC+set}" = set; then + echo $ECHO_N "(cached) $ECHO_C" >&6 +else + if test -n "$CC"; then + ac_cv_prog_CC="$CC" # Let the user override the test. +else +as_save_IFS=$IFS; IFS=$PATH_SEPARATOR +for as_dir in $PATH +do + IFS=$as_save_IFS + test -z "$as_dir" && as_dir=. + for ac_exec_ext in '' $ac_executable_extensions; do + if $as_executable_p "$as_dir/$ac_word$ac_exec_ext"; then + ac_cv_prog_CC="$ac_tool_prefix$ac_prog" + echo "$as_me:$LINENO: found $as_dir/$ac_word$ac_exec_ext" >&5 + break 2 + fi +done +done + +fi +fi +CC=$ac_cv_prog_CC +if test -n "$CC"; then + echo "$as_me:$LINENO: result: $CC" >&5 +echo "${ECHO_T}$CC" >&6 +else + echo "$as_me:$LINENO: result: no" >&5 +echo "${ECHO_T}no" >&6 +fi + + test -n "$CC" && break + done +fi +if test -z "$CC"; then + ac_ct_CC=$CC + for ac_prog in cl +do + # Extract the first word of "$ac_prog", so it can be a program name with args. +set dummy $ac_prog; ac_word=$2 +echo "$as_me:$LINENO: checking for $ac_word" >&5 +echo $ECHO_N "checking for $ac_word... $ECHO_C" >&6 +if test "${ac_cv_prog_ac_ct_CC+set}" = set; then + echo $ECHO_N "(cached) $ECHO_C" >&6 +else + if test -n "$ac_ct_CC"; then + ac_cv_prog_ac_ct_CC="$ac_ct_CC" # Let the user override the test. +else +as_save_IFS=$IFS; IFS=$PATH_SEPARATOR +for as_dir in $PATH +do + IFS=$as_save_IFS + test -z "$as_dir" && as_dir=. + for ac_exec_ext in '' $ac_executable_extensions; do + if $as_executable_p "$as_dir/$ac_word$ac_exec_ext"; then + ac_cv_prog_ac_ct_CC="$ac_prog" + echo "$as_me:$LINENO: found $as_dir/$ac_word$ac_exec_ext" >&5 + break 2 + fi +done +done + +fi +fi +ac_ct_CC=$ac_cv_prog_ac_ct_CC +if test -n "$ac_ct_CC"; then + echo "$as_me:$LINENO: result: $ac_ct_CC" >&5 +echo "${ECHO_T}$ac_ct_CC" >&6 +else + echo "$as_me:$LINENO: result: no" >&5 +echo "${ECHO_T}no" >&6 +fi + + test -n "$ac_ct_CC" && break +done + + CC=$ac_ct_CC +fi + +fi + + +test -z "$CC" && { { echo "$as_me:$LINENO: error: no acceptable C compiler found in \$PATH +See \`config.log' for more details." >&5 +echo "$as_me: error: no acceptable C compiler found in \$PATH +See \`config.log' for more details." >&2;} + { (exit 1); exit 1; }; } + +# Provide some information about the compiler. +echo "$as_me:$LINENO:" \ + "checking for C compiler version" >&5 +ac_compiler=`set X $ac_compile; echo $2` +{ (eval echo "$as_me:$LINENO: \"$ac_compiler --version </dev/null >&5\"") >&5 + (eval $ac_compiler --version </dev/null >&5) 2>&5 + ac_status=$? + echo "$as_me:$LINENO: \$? = $ac_status" >&5 + (exit $ac_status); } +{ (eval echo "$as_me:$LINENO: \"$ac_compiler -v </dev/null >&5\"") >&5 + (eval $ac_compiler -v </dev/null >&5) 2>&5 + ac_status=$? + echo "$as_me:$LINENO: \$? = $ac_status" >&5 + (exit $ac_status); } +{ (eval echo "$as_me:$LINENO: \"$ac_compiler -V </dev/null >&5\"") >&5 + (eval $ac_compiler -V </dev/null >&5) 2>&5 + ac_status=$? + echo "$as_me:$LINENO: \$? = $ac_status" >&5 + (exit $ac_status); } + +cat >conftest.$ac_ext <<_ACEOF +/* confdefs.h. */ +_ACEOF +cat confdefs.h >>conftest.$ac_ext +cat >>conftest.$ac_ext <<_ACEOF +/* end confdefs.h. */ + +int +main () +{ + + ; + return 0; +} +_ACEOF +ac_clean_files_save=$ac_clean_files +ac_clean_files="$ac_clean_files a.out a.exe b.out" +# Try to create an executable without -o first, disregard a.out. +# It will help us diagnose broken compilers, and finding out an intuition +# of exeext. +echo "$as_me:$LINENO: checking for C compiler default output file name" >&5 +echo $ECHO_N "checking for C compiler default output file name... $ECHO_C" >&6 +ac_link_default=`echo "$ac_link" | sed 's/ -o *conftest[^ ]*//'` +if { (eval echo "$as_me:$LINENO: \"$ac_link_default\"") >&5 + (eval $ac_link_default) 2>&5 + ac_status=$? + echo "$as_me:$LINENO: \$? = $ac_status" >&5 + (exit $ac_status); }; then + # Find the output, starting from the most likely. This scheme is +# not robust to junk in `.', hence go to wildcards (a.*) only as a last +# resort. + +# Be careful to initialize this variable, since it used to be cached. +# Otherwise an old cache value of `no' led to `EXEEXT = no' in a Makefile. +ac_cv_exeext= +# b.out is created by i960 compilers. +for ac_file in a_out.exe a.exe conftest.exe a.out conftest a.* conftest.* b.out +do + test -f "$ac_file" || continue + case $ac_file in + *.$ac_ext | *.xcoff | *.tds | *.d | *.pdb | *.xSYM | *.bb | *.bbg | *.o | *.obj ) + ;; + conftest.$ac_ext ) + # This is the source file. + ;; + [ab].out ) + # We found the default executable, but exeext='' is most + # certainly right. + break;; + *.* ) + ac_cv_exeext=`expr "$ac_file" : '[^.]*\(\..*\)'` + # FIXME: I believe we export ac_cv_exeext for Libtool, + # but it would be cool to find out if it's true. Does anybody + # maintain Libtool? --akim. + export ac_cv_exeext + break;; + * ) + break;; + esac +done +else + echo "$as_me: failed program was:" >&5 +sed 's/^/| /' conftest.$ac_ext >&5 + +{ { echo "$as_me:$LINENO: error: C compiler cannot create executables +See \`config.log' for more details." >&5 +echo "$as_me: error: C compiler cannot create executables +See \`config.log' for more details." >&2;} + { (exit 77); exit 77; }; } +fi + +ac_exeext=$ac_cv_exeext +echo "$as_me:$LINENO: result: $ac_file" >&5 +echo "${ECHO_T}$ac_file" >&6 + +# Check the compiler produces executables we can run. If not, either +# the compiler is broken, or we cross compile. +echo "$as_me:$LINENO: checking whether the C compiler works" >&5 +echo $ECHO_N "checking whether the C compiler works... $ECHO_C" >&6 +# FIXME: These cross compiler hacks should be removed for Autoconf 3.0 +# If not cross compiling, check that we can run a simple program. +if test "$cross_compiling" != yes; then + if { ac_try='./$ac_file' + { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5 + (eval $ac_try) 2>&5 + ac_status=$? + echo "$as_me:$LINENO: \$? = $ac_status" >&5 + (exit $ac_status); }; }; then + cross_compiling=no + else + if test "$cross_compiling" = maybe; then + cross_compiling=yes + else + { { echo "$as_me:$LINENO: error: cannot run C compiled programs. +If you meant to cross compile, use \`--host'. +See \`config.log' for more details." >&5 +echo "$as_me: error: cannot run C compiled programs. +If you meant to cross compile, use \`--host'. +See \`config.log' for more details." >&2;} + { (exit 1); exit 1; }; } + fi + fi +fi +echo "$as_me:$LINENO: result: yes" >&5 +echo "${ECHO_T}yes" >&6 + +rm -f a.out a.exe conftest$ac_cv_exeext b.out +ac_clean_files=$ac_clean_files_save +# Check the compiler produces executables we can run. If not, either +# the compiler is broken, or we cross compile. +echo "$as_me:$LINENO: checking whether we are cross compiling" >&5 +echo $ECHO_N "checking whether we are cross compiling... $ECHO_C" >&6 +echo "$as_me:$LINENO: result: $cross_compiling" >&5 +echo "${ECHO_T}$cross_compiling" >&6 + +echo "$as_me:$LINENO: checking for suffix of executables" >&5 +echo $ECHO_N "checking for suffix of executables... $ECHO_C" >&6 +if { (eval echo "$as_me:$LINENO: \"$ac_link\"") >&5 + (eval $ac_link) 2>&5 + ac_status=$? + echo "$as_me:$LINENO: \$? = $ac_status" >&5 + (exit $ac_status); }; then + # If both `conftest.exe' and `conftest' are `present' (well, observable) +# catch `conftest.exe'. For instance with Cygwin, `ls conftest' will +# work properly (i.e., refer to `conftest.exe'), while it won't with +# `rm'. +for ac_file in conftest.exe conftest conftest.*; do + test -f "$ac_file" || continue + case $ac_file in + *.$ac_ext | *.xcoff | *.tds | *.d | *.pdb | *.xSYM | *.bb | *.bbg | *.o | *.obj ) ;; + *.* ) ac_cv_exeext=`expr "$ac_file" : '[^.]*\(\..*\)'` + export ac_cv_exeext + break;; + * ) break;; + esac +done +else + { { echo "$as_me:$LINENO: error: cannot compute suffix of executables: cannot compile and link +See \`config.log' for more details." >&5 +echo "$as_me: error: cannot compute suffix of executables: cannot compile and link +See \`config.log' for more details." >&2;} + { (exit 1); exit 1; }; } +fi + +rm -f conftest$ac_cv_exeext +echo "$as_me:$LINENO: result: $ac_cv_exeext" >&5 +echo "${ECHO_T}$ac_cv_exeext" >&6 + +rm -f conftest.$ac_ext +EXEEXT=$ac_cv_exeext +ac_exeext=$EXEEXT +echo "$as_me:$LINENO: checking for suffix of object files" >&5 +echo $ECHO_N "checking for suffix of object files... $ECHO_C" >&6 +if test "${ac_cv_objext+set}" = set; then + echo $ECHO_N "(cached) $ECHO_C" >&6 +else + cat >conftest.$ac_ext <<_ACEOF +/* confdefs.h. */ +_ACEOF +cat confdefs.h >>conftest.$ac_ext +cat >>conftest.$ac_ext <<_ACEOF +/* end confdefs.h. */ + +int +main () +{ + + ; + return 0; +} +_ACEOF +rm -f conftest.o conftest.obj +if { (eval echo "$as_me:$LINENO: \"$ac_compile\"") >&5 + (eval $ac_compile) 2>&5 + ac_status=$? + echo "$as_me:$LINENO: \$? = $ac_status" >&5 + (exit $ac_status); }; then + for ac_file in `(ls conftest.o conftest.obj; ls conftest.*) 2>/dev/null`; do + case $ac_file in + *.$ac_ext | *.xcoff | *.tds | *.d | *.pdb | *.xSYM | *.bb | *.bbg ) ;; + *) ac_cv_objext=`expr "$ac_file" : '.*\.\(.*\)'` + break;; + esac +done +else + echo "$as_me: failed program was:" >&5 +sed 's/^/| /' conftest.$ac_ext >&5 + +{ { echo "$as_me:$LINENO: error: cannot compute suffix of object files: cannot compile +See \`config.log' for more details." >&5 +echo "$as_me: error: cannot compute suffix of object files: cannot compile +See \`config.log' for more details." >&2;} + { (exit 1); exit 1; }; } +fi + +rm -f conftest.$ac_cv_objext conftest.$ac_ext +fi +echo "$as_me:$LINENO: result: $ac_cv_objext" >&5 +echo "${ECHO_T}$ac_cv_objext" >&6 +OBJEXT=$ac_cv_objext +ac_objext=$OBJEXT +echo "$as_me:$LINENO: checking whether we are using the GNU C compiler" >&5 +echo $ECHO_N "checking whether we are using the GNU C compiler... $ECHO_C" >&6 +if test "${ac_cv_c_compiler_gnu+set}" = set; then + echo $ECHO_N "(cached) $ECHO_C" >&6 +else + cat >conftest.$ac_ext <<_ACEOF +/* confdefs.h. */ +_ACEOF +cat confdefs.h >>conftest.$ac_ext +cat >>conftest.$ac_ext <<_ACEOF +/* end confdefs.h. */ + +int +main () +{ +#ifndef __GNUC__ + choke me +#endif + + ; + return 0; +} +_ACEOF +rm -f conftest.$ac_objext +if { (eval echo "$as_me:$LINENO: \"$ac_compile\"") >&5 + (eval $ac_compile) 2>conftest.er1 + ac_status=$? + grep -v '^ *+' conftest.er1 >conftest.err + rm -f conftest.er1 + cat conftest.err >&5 + echo "$as_me:$LINENO: \$? = $ac_status" >&5 + (exit $ac_status); } && + { ac_try='test -z "$ac_c_werror_flag" + || test ! -s conftest.err' + { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5 + (eval $ac_try) 2>&5 + ac_status=$? + echo "$as_me:$LINENO: \$? = $ac_status" >&5 + (exit $ac_status); }; } && + { ac_try='test -s conftest.$ac_objext' + { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5 + (eval $ac_try) 2>&5 + ac_status=$? + echo "$as_me:$LINENO: \$? = $ac_status" >&5 + (exit $ac_status); }; }; then + ac_compiler_gnu=yes +else + echo "$as_me: failed program was:" >&5 +sed 's/^/| /' conftest.$ac_ext >&5 + +ac_compiler_gnu=no +fi +rm -f conftest.err conftest.$ac_objext conftest.$ac_ext +ac_cv_c_compiler_gnu=$ac_compiler_gnu + +fi +echo "$as_me:$LINENO: result: $ac_cv_c_compiler_gnu" >&5 +echo "${ECHO_T}$ac_cv_c_compiler_gnu" >&6 +GCC=`test $ac_compiler_gnu = yes && echo yes` +ac_test_CFLAGS=${CFLAGS+set} +ac_save_CFLAGS=$CFLAGS +CFLAGS="-g" +echo "$as_me:$LINENO: checking whether $CC accepts -g" >&5 +echo $ECHO_N "checking whether $CC accepts -g... $ECHO_C" >&6 +if test "${ac_cv_prog_cc_g+set}" = set; then + echo $ECHO_N "(cached) $ECHO_C" >&6 +else + cat >conftest.$ac_ext <<_ACEOF +/* confdefs.h. */ +_ACEOF +cat confdefs.h >>conftest.$ac_ext +cat >>conftest.$ac_ext <<_ACEOF +/* end confdefs.h. */ + +int +main () +{ + + ; + return 0; +} +_ACEOF +rm -f conftest.$ac_objext +if { (eval echo "$as_me:$LINENO: \"$ac_compile\"") >&5 + (eval $ac_compile) 2>conftest.er1 + ac_status=$? + grep -v '^ *+' conftest.er1 >conftest.err + rm -f conftest.er1 + cat conftest.err >&5 + echo "$as_me:$LINENO: \$? = $ac_status" >&5 + (exit $ac_status); } && + { ac_try='test -z "$ac_c_werror_flag" + || test ! -s conftest.err' + { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5 + (eval $ac_try) 2>&5 + ac_status=$? + echo "$as_me:$LINENO: \$? = $ac_status" >&5 + (exit $ac_status); }; } && + { ac_try='test -s conftest.$ac_objext' + { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5 + (eval $ac_try) 2>&5 + ac_status=$? + echo "$as_me:$LINENO: \$? = $ac_status" >&5 + (exit $ac_status); }; }; then + ac_cv_prog_cc_g=yes +else + echo "$as_me: failed program was:" >&5 +sed 's/^/| /' conftest.$ac_ext >&5 + +ac_cv_prog_cc_g=no +fi +rm -f conftest.err conftest.$ac_objext conftest.$ac_ext +fi +echo "$as_me:$LINENO: result: $ac_cv_prog_cc_g" >&5 +echo "${ECHO_T}$ac_cv_prog_cc_g" >&6 +if test "$ac_test_CFLAGS" = set; then + CFLAGS=$ac_save_CFLAGS +elif test $ac_cv_prog_cc_g = yes; then + if test "$GCC" = yes; then + CFLAGS="-g -O2" + else + CFLAGS="-g" + fi +else + if test "$GCC" = yes; then + CFLAGS="-O2" + else + CFLAGS= + fi +fi +echo "$as_me:$LINENO: checking for $CC option to accept ANSI C" >&5 +echo $ECHO_N "checking for $CC option to accept ANSI C... $ECHO_C" >&6 +if test "${ac_cv_prog_cc_stdc+set}" = set; then + echo $ECHO_N "(cached) $ECHO_C" >&6 +else + ac_cv_prog_cc_stdc=no +ac_save_CC=$CC +cat >conftest.$ac_ext <<_ACEOF +/* confdefs.h. */ +_ACEOF +cat confdefs.h >>conftest.$ac_ext +cat >>conftest.$ac_ext <<_ACEOF +/* end confdefs.h. */ +#include <stdarg.h> +#include <stdio.h> +#include <sys/types.h> +#include <sys/stat.h> +/* Most of the following tests are stolen from RCS 5.7's src/conf.sh. */ +struct buf { int x; }; +FILE * (*rcsopen) (struct buf *, struct stat *, int); +static char *e (p, i) + char **p; + int i; +{ + return p[i]; +} +static char *f (char * (*g) (char **, int), char **p, ...) +{ + char *s; + va_list v; + va_start (v,p); + s = g (p, va_arg (v,int)); + va_end (v); + return s; +} + +/* OSF 4.0 Compaq cc is some sort of almost-ANSI by default. It has + function prototypes and stuff, but not '\xHH' hex character constants. + These don't provoke an error unfortunately, instead are silently treated + as 'x'. The following induces an error, until -std1 is added to get + proper ANSI mode. Curiously '\x00'!='x' always comes out true, for an + array size at least. It's necessary to write '\x00'==0 to get something + that's true only with -std1. */ +int osf4_cc_array ['\x00' == 0 ? 1 : -1]; + +int test (int i, double x); +struct s1 {int (*f) (int a);}; +struct s2 {int (*f) (double a);}; +int pairnames (int, char **, FILE *(*)(struct buf *, struct stat *, int), int, int); +int argc; +char **argv; +int +main () +{ +return f (e, argv, 0) != argv[0] || f (e, argv, 1) != argv[1]; + ; + return 0; +} +_ACEOF +# Don't try gcc -ansi; that turns off useful extensions and +# breaks some systems' header files. +# AIX -qlanglvl=ansi +# Ultrix and OSF/1 -std1 +# HP-UX 10.20 and later -Ae +# HP-UX older versions -Aa -D_HPUX_SOURCE +# SVR4 -Xc -D__EXTENSIONS__ +for ac_arg in "" -qlanglvl=ansi -std1 -Ae "-Aa -D_HPUX_SOURCE" "-Xc -D__EXTENSIONS__" +do + CC="$ac_save_CC $ac_arg" + rm -f conftest.$ac_objext +if { (eval echo "$as_me:$LINENO: \"$ac_compile\"") >&5 + (eval $ac_compile) 2>conftest.er1 + ac_status=$? + grep -v '^ *+' conftest.er1 >conftest.err + rm -f conftest.er1 + cat conftest.err >&5 + echo "$as_me:$LINENO: \$? = $ac_status" >&5 + (exit $ac_status); } && + { ac_try='test -z "$ac_c_werror_flag" + || test ! -s conftest.err' + { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5 + (eval $ac_try) 2>&5 + ac_status=$? + echo "$as_me:$LINENO: \$? = $ac_status" >&5 + (exit $ac_status); }; } && + { ac_try='test -s conftest.$ac_objext' + { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5 + (eval $ac_try) 2>&5 + ac_status=$? + echo "$as_me:$LINENO: \$? = $ac_status" >&5 + (exit $ac_status); }; }; then + ac_cv_prog_cc_stdc=$ac_arg +break +else + echo "$as_me: failed program was:" >&5 +sed 's/^/| /' conftest.$ac_ext >&5 + +fi +rm -f conftest.err conftest.$ac_objext +done +rm -f conftest.$ac_ext conftest.$ac_objext +CC=$ac_save_CC + +fi + +case "x$ac_cv_prog_cc_stdc" in + x|xno) + echo "$as_me:$LINENO: result: none needed" >&5 +echo "${ECHO_T}none needed" >&6 ;; + *) + echo "$as_me:$LINENO: result: $ac_cv_prog_cc_stdc" >&5 +echo "${ECHO_T}$ac_cv_prog_cc_stdc" >&6 + CC="$CC $ac_cv_prog_cc_stdc" ;; +esac + +# Some people use a C++ compiler to compile C. Since we use `exit', +# in C++ we need to declare it. In case someone uses the same compiler +# for both compiling C and C++ we need to have the C++ compiler decide +# the declaration of exit, since it's the most demanding environment. +cat >conftest.$ac_ext <<_ACEOF +#ifndef __cplusplus + choke me +#endif +_ACEOF +rm -f conftest.$ac_objext +if { (eval echo "$as_me:$LINENO: \"$ac_compile\"") >&5 + (eval $ac_compile) 2>conftest.er1 + ac_status=$? + grep -v '^ *+' conftest.er1 >conftest.err + rm -f conftest.er1 + cat conftest.err >&5 + echo "$as_me:$LINENO: \$? = $ac_status" >&5 + (exit $ac_status); } && + { ac_try='test -z "$ac_c_werror_flag" + || test ! -s conftest.err' + { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5 + (eval $ac_try) 2>&5 + ac_status=$? + echo "$as_me:$LINENO: \$? = $ac_status" >&5 + (exit $ac_status); }; } && + { ac_try='test -s conftest.$ac_objext' + { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5 + (eval $ac_try) 2>&5 + ac_status=$? + echo "$as_me:$LINENO: \$? = $ac_status" >&5 + (exit $ac_status); }; }; then + for ac_declaration in \ + '' \ + 'extern "C" void std::exit (int) throw (); using std::exit;' \ + 'extern "C" void std::exit (int); using std::exit;' \ + 'extern "C" void exit (int) throw ();' \ + 'extern "C" void exit (int);' \ + 'void exit (int);' +do + cat >conftest.$ac_ext <<_ACEOF +/* confdefs.h. */ +_ACEOF +cat confdefs.h >>conftest.$ac_ext +cat >>conftest.$ac_ext <<_ACEOF +/* end confdefs.h. */ +$ac_declaration +#include <stdlib.h> +int +main () +{ +exit (42); + ; + return 0; +} +_ACEOF +rm -f conftest.$ac_objext +if { (eval echo "$as_me:$LINENO: \"$ac_compile\"") >&5 + (eval $ac_compile) 2>conftest.er1 + ac_status=$? + grep -v '^ *+' conftest.er1 >conftest.err + rm -f conftest.er1 + cat conftest.err >&5 + echo "$as_me:$LINENO: \$? = $ac_status" >&5 + (exit $ac_status); } && + { ac_try='test -z "$ac_c_werror_flag" + || test ! -s conftest.err' + { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5 + (eval $ac_try) 2>&5 + ac_status=$? + echo "$as_me:$LINENO: \$? = $ac_status" >&5 + (exit $ac_status); }; } && + { ac_try='test -s conftest.$ac_objext' + { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5 + (eval $ac_try) 2>&5 + ac_status=$? + echo "$as_me:$LINENO: \$? = $ac_status" >&5 + (exit $ac_status); }; }; then + : +else + echo "$as_me: failed program was:" >&5 +sed 's/^/| /' conftest.$ac_ext >&5 + +continue +fi +rm -f conftest.err conftest.$ac_objext conftest.$ac_ext + cat >conftest.$ac_ext <<_ACEOF +/* confdefs.h. */ +_ACEOF +cat confdefs.h >>conftest.$ac_ext +cat >>conftest.$ac_ext <<_ACEOF +/* end confdefs.h. */ +$ac_declaration +int +main () +{ +exit (42); + ; + return 0; +} +_ACEOF +rm -f conftest.$ac_objext +if { (eval echo "$as_me:$LINENO: \"$ac_compile\"") >&5 + (eval $ac_compile) 2>conftest.er1 + ac_status=$? + grep -v '^ *+' conftest.er1 >conftest.err + rm -f conftest.er1 + cat conftest.err >&5 + echo "$as_me:$LINENO: \$? = $ac_status" >&5 + (exit $ac_status); } && + { ac_try='test -z "$ac_c_werror_flag" + || test ! -s conftest.err' + { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5 + (eval $ac_try) 2>&5 + ac_status=$? + echo "$as_me:$LINENO: \$? = $ac_status" >&5 + (exit $ac_status); }; } && + { ac_try='test -s conftest.$ac_objext' + { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5 + (eval $ac_try) 2>&5 + ac_status=$? + echo "$as_me:$LINENO: \$? = $ac_status" >&5 + (exit $ac_status); }; }; then + break +else + echo "$as_me: failed program was:" >&5 +sed 's/^/| /' conftest.$ac_ext >&5 + +fi +rm -f conftest.err conftest.$ac_objext conftest.$ac_ext +done +rm -f conftest* +if test -n "$ac_declaration"; then + echo '#ifdef __cplusplus' >>confdefs.h + echo $ac_declaration >>confdefs.h + echo '#endif' >>confdefs.h +fi + +else + echo "$as_me: failed program was:" >&5 +sed 's/^/| /' conftest.$ac_ext >&5 + +fi +rm -f conftest.err conftest.$ac_objext conftest.$ac_ext +ac_ext=c +ac_cpp='$CPP $CPPFLAGS' +ac_compile='$CC -c $CFLAGS $CPPFLAGS conftest.$ac_ext >&5' +ac_link='$CC -o conftest$ac_exeext $CFLAGS $CPPFLAGS $LDFLAGS conftest.$ac_ext $LIBS >&5' +ac_compiler_gnu=$ac_cv_c_compiler_gnu +DEPDIR="${am__leading_dot}deps" + + ac_config_commands="$ac_config_commands depfiles" + + +am_make=${MAKE-make} +cat > confinc << 'END' +am__doit: + @echo done +.PHONY: am__doit +END +# If we don't find an include directive, just comment out the code. +echo "$as_me:$LINENO: checking for style of include used by $am_make" >&5 +echo $ECHO_N "checking for style of include used by $am_make... $ECHO_C" >&6 +am__include="#" +am__quote= +_am_result=none +# First try GNU make style include. +echo "include confinc" > confmf +# We grep out `Entering directory' and `Leaving directory' +# messages which can occur if `w' ends up in MAKEFLAGS. +# In particular we don't look at `^make:' because GNU make might +# be invoked under some other name (usually "gmake"), in which +# case it prints its new name instead of `make'. +if test "`$am_make -s -f confmf 2> /dev/null | grep -v 'ing directory'`" = "done"; then + am__include=include + am__quote= + _am_result=GNU +fi +# Now try BSD make style include. +if test "$am__include" = "#"; then + echo '.include "confinc"' > confmf + if test "`$am_make -s -f confmf 2> /dev/null`" = "done"; then + am__include=.include + am__quote="\"" + _am_result=BSD + fi +fi + + +echo "$as_me:$LINENO: result: $_am_result" >&5 +echo "${ECHO_T}$_am_result" >&6 +rm -f confinc confmf + +# Check whether --enable-dependency-tracking or --disable-dependency-tracking was given. +if test "${enable_dependency_tracking+set}" = set; then + enableval="$enable_dependency_tracking" + +fi; +if test "x$enable_dependency_tracking" != xno; then + am_depcomp="$ac_aux_dir/depcomp" + AMDEPBACKSLASH='\' +fi + + +if test "x$enable_dependency_tracking" != xno; then + AMDEP_TRUE= + AMDEP_FALSE='#' +else + AMDEP_TRUE='#' + AMDEP_FALSE= +fi + + + + +depcc="$CC" am_compiler_list= + +echo "$as_me:$LINENO: checking dependency style of $depcc" >&5 +echo $ECHO_N "checking dependency style of $depcc... $ECHO_C" >&6 +if test "${am_cv_CC_dependencies_compiler_type+set}" = set; then + echo $ECHO_N "(cached) $ECHO_C" >&6 +else + if test -z "$AMDEP_TRUE" && test -f "$am_depcomp"; then + # We make a subdir and do the tests there. Otherwise we can end up + # making bogus files that we don't know about and never remove. For + # instance it was reported that on HP-UX the gcc test will end up + # making a dummy file named `D' -- because `-MD' means `put the output + # in D'. + mkdir conftest.dir + # Copy depcomp to subdir because otherwise we won't find it if we're + # using a relative directory. + cp "$am_depcomp" conftest.dir + cd conftest.dir + # We will build objects and dependencies in a subdirectory because + # it helps to detect inapplicable dependency modes. For instance + # both Tru64's cc and ICC support -MD to output dependencies as a + # side effect of compilation, but ICC will put the dependencies in + # the current directory while Tru64 will put them in the object + # directory. + mkdir sub + + am_cv_CC_dependencies_compiler_type=none + if test "$am_compiler_list" = ""; then + am_compiler_list=`sed -n 's/^#*\([a-zA-Z0-9]*\))$/\1/p' < ./depcomp` + fi + for depmode in $am_compiler_list; do + # Setup a source with many dependencies, because some compilers + # like to wrap large dependency lists on column 80 (with \), and + # we should not choose a depcomp mode which is confused by this. + # + # We need to recreate these files for each test, as the compiler may + # overwrite some of them when testing with obscure command lines. + # This happens at least with the AIX C compiler. + : > sub/conftest.c + for i in 1 2 3 4 5 6; do + echo '#include "conftst'$i'.h"' >> sub/conftest.c + # Using `: > sub/conftst$i.h' creates only sub/conftst1.h with + # Solaris 8's {/usr,}/bin/sh. + touch sub/conftst$i.h + done + echo "${am__include} ${am__quote}sub/conftest.Po${am__quote}" > confmf + + case $depmode in + nosideeffect) + # after this tag, mechanisms are not by side-effect, so they'll + # only be used when explicitly requested + if test "x$enable_dependency_tracking" = xyes; then + continue + else + break + fi + ;; + none) break ;; + esac + # We check with `-c' and `-o' for the sake of the "dashmstdout" + # mode. It turns out that the SunPro C++ compiler does not properly + # handle `-M -o', and we need to detect this. + if depmode=$depmode \ + source=sub/conftest.c object=sub/conftest.${OBJEXT-o} \ + depfile=sub/conftest.Po tmpdepfile=sub/conftest.TPo \ + $SHELL ./depcomp $depcc -c -o sub/conftest.${OBJEXT-o} sub/conftest.c \ + >/dev/null 2>conftest.err && + grep sub/conftst6.h sub/conftest.Po > /dev/null 2>&1 && + grep sub/conftest.${OBJEXT-o} sub/conftest.Po > /dev/null 2>&1 && + ${MAKE-make} -s -f confmf > /dev/null 2>&1; then + # icc doesn't choke on unknown options, it will just issue warnings + # or remarks (even with -Werror). So we grep stderr for any message + # that says an option was ignored or not supported. + # When given -MP, icc 7.0 and 7.1 complain thusly: + # icc: Command line warning: ignoring option '-M'; no argument required + # The diagnosis changed in icc 8.0: + # icc: Command line remark: option '-MP' not supported + if (grep 'ignoring option' conftest.err || + grep 'not supported' conftest.err) >/dev/null 2>&1; then :; else + am_cv_CC_dependencies_compiler_type=$depmode + break + fi + fi + done + + cd .. + rm -rf conftest.dir +else + am_cv_CC_dependencies_compiler_type=none +fi + +fi +echo "$as_me:$LINENO: result: $am_cv_CC_dependencies_compiler_type" >&5 +echo "${ECHO_T}$am_cv_CC_dependencies_compiler_type" >&6 +CCDEPMODE=depmode=$am_cv_CC_dependencies_compiler_type + + + +if + test "x$enable_dependency_tracking" != xno \ + && test "$am_cv_CC_dependencies_compiler_type" = gcc3; then + am__fastdepCC_TRUE= + am__fastdepCC_FALSE='#' +else + am__fastdepCC_TRUE='#' + am__fastdepCC_FALSE= +fi + + +ac_ext=cc +ac_cpp='$CXXCPP $CPPFLAGS' +ac_compile='$CXX -c $CXXFLAGS $CPPFLAGS conftest.$ac_ext >&5' +ac_link='$CXX -o conftest$ac_exeext $CXXFLAGS $CPPFLAGS $LDFLAGS conftest.$ac_ext $LIBS >&5' +ac_compiler_gnu=$ac_cv_cxx_compiler_gnu +if test -n "$ac_tool_prefix"; then + for ac_prog in $CCC g++ c++ gpp aCC CC cxx cc++ cl FCC KCC RCC xlC_r xlC + do + # Extract the first word of "$ac_tool_prefix$ac_prog", so it can be a program name with args. +set dummy $ac_tool_prefix$ac_prog; ac_word=$2 +echo "$as_me:$LINENO: checking for $ac_word" >&5 +echo $ECHO_N "checking for $ac_word... $ECHO_C" >&6 +if test "${ac_cv_prog_CXX+set}" = set; then + echo $ECHO_N "(cached) $ECHO_C" >&6 +else + if test -n "$CXX"; then + ac_cv_prog_CXX="$CXX" # Let the user override the test. +else +as_save_IFS=$IFS; IFS=$PATH_SEPARATOR +for as_dir in $PATH +do + IFS=$as_save_IFS + test -z "$as_dir" && as_dir=. + for ac_exec_ext in '' $ac_executable_extensions; do + if $as_executable_p "$as_dir/$ac_word$ac_exec_ext"; then + ac_cv_prog_CXX="$ac_tool_prefix$ac_prog" + echo "$as_me:$LINENO: found $as_dir/$ac_word$ac_exec_ext" >&5 + break 2 + fi +done +done + +fi +fi +CXX=$ac_cv_prog_CXX +if test -n "$CXX"; then + echo "$as_me:$LINENO: result: $CXX" >&5 +echo "${ECHO_T}$CXX" >&6 +else + echo "$as_me:$LINENO: result: no" >&5 +echo "${ECHO_T}no" >&6 +fi + + test -n "$CXX" && break + done +fi +if test -z "$CXX"; then + ac_ct_CXX=$CXX + for ac_prog in $CCC g++ c++ gpp aCC CC cxx cc++ cl FCC KCC RCC xlC_r xlC +do + # Extract the first word of "$ac_prog", so it can be a program name with args. +set dummy $ac_prog; ac_word=$2 +echo "$as_me:$LINENO: checking for $ac_word" >&5 +echo $ECHO_N "checking for $ac_word... $ECHO_C" >&6 +if test "${ac_cv_prog_ac_ct_CXX+set}" = set; then + echo $ECHO_N "(cached) $ECHO_C" >&6 +else + if test -n "$ac_ct_CXX"; then + ac_cv_prog_ac_ct_CXX="$ac_ct_CXX" # Let the user override the test. +else +as_save_IFS=$IFS; IFS=$PATH_SEPARATOR +for as_dir in $PATH +do + IFS=$as_save_IFS + test -z "$as_dir" && as_dir=. + for ac_exec_ext in '' $ac_executable_extensions; do + if $as_executable_p "$as_dir/$ac_word$ac_exec_ext"; then + ac_cv_prog_ac_ct_CXX="$ac_prog" + echo "$as_me:$LINENO: found $as_dir/$ac_word$ac_exec_ext" >&5 + break 2 + fi +done +done + +fi +fi +ac_ct_CXX=$ac_cv_prog_ac_ct_CXX +if test -n "$ac_ct_CXX"; then + echo "$as_me:$LINENO: result: $ac_ct_CXX" >&5 +echo "${ECHO_T}$ac_ct_CXX" >&6 +else + echo "$as_me:$LINENO: result: no" >&5 +echo "${ECHO_T}no" >&6 +fi + + test -n "$ac_ct_CXX" && break +done +test -n "$ac_ct_CXX" || ac_ct_CXX="g++" + + CXX=$ac_ct_CXX +fi + + +# Provide some information about the compiler. +echo "$as_me:$LINENO:" \ + "checking for C++ compiler version" >&5 +ac_compiler=`set X $ac_compile; echo $2` +{ (eval echo "$as_me:$LINENO: \"$ac_compiler --version </dev/null >&5\"") >&5 + (eval $ac_compiler --version </dev/null >&5) 2>&5 + ac_status=$? + echo "$as_me:$LINENO: \$? = $ac_status" >&5 + (exit $ac_status); } +{ (eval echo "$as_me:$LINENO: \"$ac_compiler -v </dev/null >&5\"") >&5 + (eval $ac_compiler -v </dev/null >&5) 2>&5 + ac_status=$? + echo "$as_me:$LINENO: \$? = $ac_status" >&5 + (exit $ac_status); } +{ (eval echo "$as_me:$LINENO: \"$ac_compiler -V </dev/null >&5\"") >&5 + (eval $ac_compiler -V </dev/null >&5) 2>&5 + ac_status=$? + echo "$as_me:$LINENO: \$? = $ac_status" >&5 + (exit $ac_status); } + +echo "$as_me:$LINENO: checking whether we are using the GNU C++ compiler" >&5 +echo $ECHO_N "checking whether we are using the GNU C++ compiler... $ECHO_C" >&6 +if test "${ac_cv_cxx_compiler_gnu+set}" = set; then + echo $ECHO_N "(cached) $ECHO_C" >&6 +else + cat >conftest.$ac_ext <<_ACEOF +/* confdefs.h. */ +_ACEOF +cat confdefs.h >>conftest.$ac_ext +cat >>conftest.$ac_ext <<_ACEOF +/* end confdefs.h. */ + +int +main () +{ +#ifndef __GNUC__ + choke me +#endif + + ; + return 0; +} +_ACEOF +rm -f conftest.$ac_objext +if { (eval echo "$as_me:$LINENO: \"$ac_compile\"") >&5 + (eval $ac_compile) 2>conftest.er1 + ac_status=$? + grep -v '^ *+' conftest.er1 >conftest.err + rm -f conftest.er1 + cat conftest.err >&5 + echo "$as_me:$LINENO: \$? = $ac_status" >&5 + (exit $ac_status); } && + { ac_try='test -z "$ac_cxx_werror_flag" + || test ! -s conftest.err' + { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5 + (eval $ac_try) 2>&5 + ac_status=$? + echo "$as_me:$LINENO: \$? = $ac_status" >&5 + (exit $ac_status); }; } && + { ac_try='test -s conftest.$ac_objext' + { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5 + (eval $ac_try) 2>&5 + ac_status=$? + echo "$as_me:$LINENO: \$? = $ac_status" >&5 + (exit $ac_status); }; }; then + ac_compiler_gnu=yes +else + echo "$as_me: failed program was:" >&5 +sed 's/^/| /' conftest.$ac_ext >&5 + +ac_compiler_gnu=no +fi +rm -f conftest.err conftest.$ac_objext conftest.$ac_ext +ac_cv_cxx_compiler_gnu=$ac_compiler_gnu + +fi +echo "$as_me:$LINENO: result: $ac_cv_cxx_compiler_gnu" >&5 +echo "${ECHO_T}$ac_cv_cxx_compiler_gnu" >&6 +GXX=`test $ac_compiler_gnu = yes && echo yes` +ac_test_CXXFLAGS=${CXXFLAGS+set} +ac_save_CXXFLAGS=$CXXFLAGS +CXXFLAGS="-g" +echo "$as_me:$LINENO: checking whether $CXX accepts -g" >&5 +echo $ECHO_N "checking whether $CXX accepts -g... $ECHO_C" >&6 +if test "${ac_cv_prog_cxx_g+set}" = set; then + echo $ECHO_N "(cached) $ECHO_C" >&6 +else + cat >conftest.$ac_ext <<_ACEOF +/* confdefs.h. */ +_ACEOF +cat confdefs.h >>conftest.$ac_ext +cat >>conftest.$ac_ext <<_ACEOF +/* end confdefs.h. */ + +int +main () +{ + + ; + return 0; +} +_ACEOF +rm -f conftest.$ac_objext +if { (eval echo "$as_me:$LINENO: \"$ac_compile\"") >&5 + (eval $ac_compile) 2>conftest.er1 + ac_status=$? + grep -v '^ *+' conftest.er1 >conftest.err + rm -f conftest.er1 + cat conftest.err >&5 + echo "$as_me:$LINENO: \$? = $ac_status" >&5 + (exit $ac_status); } && + { ac_try='test -z "$ac_cxx_werror_flag" + || test ! -s conftest.err' + { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5 + (eval $ac_try) 2>&5 + ac_status=$? + echo "$as_me:$LINENO: \$? = $ac_status" >&5 + (exit $ac_status); }; } && + { ac_try='test -s conftest.$ac_objext' + { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5 + (eval $ac_try) 2>&5 + ac_status=$? + echo "$as_me:$LINENO: \$? = $ac_status" >&5 + (exit $ac_status); }; }; then + ac_cv_prog_cxx_g=yes +else + echo "$as_me: failed program was:" >&5 +sed 's/^/| /' conftest.$ac_ext >&5 + +ac_cv_prog_cxx_g=no +fi +rm -f conftest.err conftest.$ac_objext conftest.$ac_ext +fi +echo "$as_me:$LINENO: result: $ac_cv_prog_cxx_g" >&5 +echo "${ECHO_T}$ac_cv_prog_cxx_g" >&6 +if test "$ac_test_CXXFLAGS" = set; then + CXXFLAGS=$ac_save_CXXFLAGS +elif test $ac_cv_prog_cxx_g = yes; then + if test "$GXX" = yes; then + CXXFLAGS="-g -O2" + else + CXXFLAGS="-g" + fi +else + if test "$GXX" = yes; then + CXXFLAGS="-O2" + else + CXXFLAGS= + fi +fi +for ac_declaration in \ + '' \ + 'extern "C" void std::exit (int) throw (); using std::exit;' \ + 'extern "C" void std::exit (int); using std::exit;' \ + 'extern "C" void exit (int) throw ();' \ + 'extern "C" void exit (int);' \ + 'void exit (int);' +do + cat >conftest.$ac_ext <<_ACEOF +/* confdefs.h. */ +_ACEOF +cat confdefs.h >>conftest.$ac_ext +cat >>conftest.$ac_ext <<_ACEOF +/* end confdefs.h. */ +$ac_declaration +#include <stdlib.h> +int +main () +{ +exit (42); + ; + return 0; +} +_ACEOF +rm -f conftest.$ac_objext +if { (eval echo "$as_me:$LINENO: \"$ac_compile\"") >&5 + (eval $ac_compile) 2>conftest.er1 + ac_status=$? + grep -v '^ *+' conftest.er1 >conftest.err + rm -f conftest.er1 + cat conftest.err >&5 + echo "$as_me:$LINENO: \$? = $ac_status" >&5 + (exit $ac_status); } && + { ac_try='test -z "$ac_cxx_werror_flag" + || test ! -s conftest.err' + { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5 + (eval $ac_try) 2>&5 + ac_status=$? + echo "$as_me:$LINENO: \$? = $ac_status" >&5 + (exit $ac_status); }; } && + { ac_try='test -s conftest.$ac_objext' + { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5 + (eval $ac_try) 2>&5 + ac_status=$? + echo "$as_me:$LINENO: \$? = $ac_status" >&5 + (exit $ac_status); }; }; then + : +else + echo "$as_me: failed program was:" >&5 +sed 's/^/| /' conftest.$ac_ext >&5 + +continue +fi +rm -f conftest.err conftest.$ac_objext conftest.$ac_ext + cat >conftest.$ac_ext <<_ACEOF +/* confdefs.h. */ +_ACEOF +cat confdefs.h >>conftest.$ac_ext +cat >>conftest.$ac_ext <<_ACEOF +/* end confdefs.h. */ +$ac_declaration +int +main () +{ +exit (42); + ; + return 0; +} +_ACEOF +rm -f conftest.$ac_objext +if { (eval echo "$as_me:$LINENO: \"$ac_compile\"") >&5 + (eval $ac_compile) 2>conftest.er1 + ac_status=$? + grep -v '^ *+' conftest.er1 >conftest.err + rm -f conftest.er1 + cat conftest.err >&5 + echo "$as_me:$LINENO: \$? = $ac_status" >&5 + (exit $ac_status); } && + { ac_try='test -z "$ac_cxx_werror_flag" + || test ! -s conftest.err' + { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5 + (eval $ac_try) 2>&5 + ac_status=$? + echo "$as_me:$LINENO: \$? = $ac_status" >&5 + (exit $ac_status); }; } && + { ac_try='test -s conftest.$ac_objext' + { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5 + (eval $ac_try) 2>&5 + ac_status=$? + echo "$as_me:$LINENO: \$? = $ac_status" >&5 + (exit $ac_status); }; }; then + break +else + echo "$as_me: failed program was:" >&5 +sed 's/^/| /' conftest.$ac_ext >&5 + +fi +rm -f conftest.err conftest.$ac_objext conftest.$ac_ext +done +rm -f conftest* +if test -n "$ac_declaration"; then + echo '#ifdef __cplusplus' >>confdefs.h + echo $ac_declaration >>confdefs.h + echo '#endif' >>confdefs.h +fi + +ac_ext=c +ac_cpp='$CPP $CPPFLAGS' +ac_compile='$CC -c $CFLAGS $CPPFLAGS conftest.$ac_ext >&5' +ac_link='$CC -o conftest$ac_exeext $CFLAGS $CPPFLAGS $LDFLAGS conftest.$ac_ext $LIBS >&5' +ac_compiler_gnu=$ac_cv_c_compiler_gnu + +depcc="$CXX" am_compiler_list= + +echo "$as_me:$LINENO: checking dependency style of $depcc" >&5 +echo $ECHO_N "checking dependency style of $depcc... $ECHO_C" >&6 +if test "${am_cv_CXX_dependencies_compiler_type+set}" = set; then + echo $ECHO_N "(cached) $ECHO_C" >&6 +else + if test -z "$AMDEP_TRUE" && test -f "$am_depcomp"; then + # We make a subdir and do the tests there. Otherwise we can end up + # making bogus files that we don't know about and never remove. For + # instance it was reported that on HP-UX the gcc test will end up + # making a dummy file named `D' -- because `-MD' means `put the output + # in D'. + mkdir conftest.dir + # Copy depcomp to subdir because otherwise we won't find it if we're + # using a relative directory. + cp "$am_depcomp" conftest.dir + cd conftest.dir + # We will build objects and dependencies in a subdirectory because + # it helps to detect inapplicable dependency modes. For instance + # both Tru64's cc and ICC support -MD to output dependencies as a + # side effect of compilation, but ICC will put the dependencies in + # the current directory while Tru64 will put them in the object + # directory. + mkdir sub + + am_cv_CXX_dependencies_compiler_type=none + if test "$am_compiler_list" = ""; then + am_compiler_list=`sed -n 's/^#*\([a-zA-Z0-9]*\))$/\1/p' < ./depcomp` + fi + for depmode in $am_compiler_list; do + # Setup a source with many dependencies, because some compilers + # like to wrap large dependency lists on column 80 (with \), and + # we should not choose a depcomp mode which is confused by this. + # + # We need to recreate these files for each test, as the compiler may + # overwrite some of them when testing with obscure command lines. + # This happens at least with the AIX C compiler. + : > sub/conftest.c + for i in 1 2 3 4 5 6; do + echo '#include "conftst'$i'.h"' >> sub/conftest.c + # Using `: > sub/conftst$i.h' creates only sub/conftst1.h with + # Solaris 8's {/usr,}/bin/sh. + touch sub/conftst$i.h + done + echo "${am__include} ${am__quote}sub/conftest.Po${am__quote}" > confmf + + case $depmode in + nosideeffect) + # after this tag, mechanisms are not by side-effect, so they'll + # only be used when explicitly requested + if test "x$enable_dependency_tracking" = xyes; then + continue + else + break + fi + ;; + none) break ;; + esac + # We check with `-c' and `-o' for the sake of the "dashmstdout" + # mode. It turns out that the SunPro C++ compiler does not properly + # handle `-M -o', and we need to detect this. + if depmode=$depmode \ + source=sub/conftest.c object=sub/conftest.${OBJEXT-o} \ + depfile=sub/conftest.Po tmpdepfile=sub/conftest.TPo \ + $SHELL ./depcomp $depcc -c -o sub/conftest.${OBJEXT-o} sub/conftest.c \ + >/dev/null 2>conftest.err && + grep sub/conftst6.h sub/conftest.Po > /dev/null 2>&1 && + grep sub/conftest.${OBJEXT-o} sub/conftest.Po > /dev/null 2>&1 && + ${MAKE-make} -s -f confmf > /dev/null 2>&1; then + # icc doesn't choke on unknown options, it will just issue warnings + # or remarks (even with -Werror). So we grep stderr for any message + # that says an option was ignored or not supported. + # When given -MP, icc 7.0 and 7.1 complain thusly: + # icc: Command line warning: ignoring option '-M'; no argument required + # The diagnosis changed in icc 8.0: + # icc: Command line remark: option '-MP' not supported + if (grep 'ignoring option' conftest.err || + grep 'not supported' conftest.err) >/dev/null 2>&1; then :; else + am_cv_CXX_dependencies_compiler_type=$depmode + break + fi + fi + done + + cd .. + rm -rf conftest.dir +else + am_cv_CXX_dependencies_compiler_type=none +fi + +fi +echo "$as_me:$LINENO: result: $am_cv_CXX_dependencies_compiler_type" >&5 +echo "${ECHO_T}$am_cv_CXX_dependencies_compiler_type" >&6 +CXXDEPMODE=depmode=$am_cv_CXX_dependencies_compiler_type + + + +if + test "x$enable_dependency_tracking" != xno \ + && test "$am_cv_CXX_dependencies_compiler_type" = gcc3; then + am__fastdepCXX_TRUE= + am__fastdepCXX_FALSE='#' +else + am__fastdepCXX_TRUE='#' + am__fastdepCXX_FALSE= +fi + + +# Check whether --enable-shared or --disable-shared was given. +if test "${enable_shared+set}" = set; then + enableval="$enable_shared" + p=${PACKAGE-default} + case $enableval in + yes) enable_shared=yes ;; + no) enable_shared=no ;; + *) + enable_shared=no + # Look at the argument we got. We use all the common list separators. + lt_save_ifs="$IFS"; IFS="${IFS}$PATH_SEPARATOR," + for pkg in $enableval; do + IFS="$lt_save_ifs" + if test "X$pkg" = "X$p"; then + enable_shared=yes + fi + done + IFS="$lt_save_ifs" + ;; + esac +else + enable_shared=yes +fi; + +# Check whether --enable-static or --disable-static was given. +if test "${enable_static+set}" = set; then + enableval="$enable_static" + p=${PACKAGE-default} + case $enableval in + yes) enable_static=yes ;; + no) enable_static=no ;; + *) + enable_static=no + # Look at the argument we got. We use all the common list separators. + lt_save_ifs="$IFS"; IFS="${IFS}$PATH_SEPARATOR," + for pkg in $enableval; do + IFS="$lt_save_ifs" + if test "X$pkg" = "X$p"; then + enable_static=yes + fi + done + IFS="$lt_save_ifs" + ;; + esac +else + enable_static=yes +fi; + +# Check whether --enable-fast-install or --disable-fast-install was given. +if test "${enable_fast_install+set}" = set; then + enableval="$enable_fast_install" + p=${PACKAGE-default} + case $enableval in + yes) enable_fast_install=yes ;; + no) enable_fast_install=no ;; + *) + enable_fast_install=no + # Look at the argument we got. We use all the common list separators. + lt_save_ifs="$IFS"; IFS="${IFS}$PATH_SEPARATOR," + for pkg in $enableval; do + IFS="$lt_save_ifs" + if test "X$pkg" = "X$p"; then + enable_fast_install=yes + fi + done + IFS="$lt_save_ifs" + ;; + esac +else + enable_fast_install=yes +fi; + +# Make sure we can run config.sub. +$ac_config_sub sun4 >/dev/null 2>&1 || + { { echo "$as_me:$LINENO: error: cannot run $ac_config_sub" >&5 +echo "$as_me: error: cannot run $ac_config_sub" >&2;} + { (exit 1); exit 1; }; } + +echo "$as_me:$LINENO: checking build system type" >&5 +echo $ECHO_N "checking build system type... $ECHO_C" >&6 +if test "${ac_cv_build+set}" = set; then + echo $ECHO_N "(cached) $ECHO_C" >&6 +else + ac_cv_build_alias=$build_alias +test -z "$ac_cv_build_alias" && + ac_cv_build_alias=`$ac_config_guess` +test -z "$ac_cv_build_alias" && + { { echo "$as_me:$LINENO: error: cannot guess build type; you must specify one" >&5 +echo "$as_me: error: cannot guess build type; you must specify one" >&2;} + { (exit 1); exit 1; }; } +ac_cv_build=`$ac_config_sub $ac_cv_build_alias` || + { { echo "$as_me:$LINENO: error: $ac_config_sub $ac_cv_build_alias failed" >&5 +echo "$as_me: error: $ac_config_sub $ac_cv_build_alias failed" >&2;} + { (exit 1); exit 1; }; } + +fi +echo "$as_me:$LINENO: result: $ac_cv_build" >&5 +echo "${ECHO_T}$ac_cv_build" >&6 +build=$ac_cv_build +build_cpu=`echo $ac_cv_build | sed 's/^\([^-]*\)-\([^-]*\)-\(.*\)$/\1/'` +build_vendor=`echo $ac_cv_build | sed 's/^\([^-]*\)-\([^-]*\)-\(.*\)$/\2/'` +build_os=`echo $ac_cv_build | sed 's/^\([^-]*\)-\([^-]*\)-\(.*\)$/\3/'` + + +echo "$as_me:$LINENO: checking host system type" >&5 +echo $ECHO_N "checking host system type... $ECHO_C" >&6 +if test "${ac_cv_host+set}" = set; then + echo $ECHO_N "(cached) $ECHO_C" >&6 +else + ac_cv_host_alias=$host_alias +test -z "$ac_cv_host_alias" && + ac_cv_host_alias=$ac_cv_build_alias +ac_cv_host=`$ac_config_sub $ac_cv_host_alias` || + { { echo "$as_me:$LINENO: error: $ac_config_sub $ac_cv_host_alias failed" >&5 +echo "$as_me: error: $ac_config_sub $ac_cv_host_alias failed" >&2;} + { (exit 1); exit 1; }; } + +fi +echo "$as_me:$LINENO: result: $ac_cv_host" >&5 +echo "${ECHO_T}$ac_cv_host" >&6 +host=$ac_cv_host +host_cpu=`echo $ac_cv_host | sed 's/^\([^-]*\)-\([^-]*\)-\(.*\)$/\1/'` +host_vendor=`echo $ac_cv_host | sed 's/^\([^-]*\)-\([^-]*\)-\(.*\)$/\2/'` +host_os=`echo $ac_cv_host | sed 's/^\([^-]*\)-\([^-]*\)-\(.*\)$/\3/'` + + +echo "$as_me:$LINENO: checking for a sed that does not truncate output" >&5 +echo $ECHO_N "checking for a sed that does not truncate output... $ECHO_C" >&6 +if test "${lt_cv_path_SED+set}" = set; then + echo $ECHO_N "(cached) $ECHO_C" >&6 +else + # Loop through the user's path and test for sed and gsed. +# Then use that list of sed's as ones to test for truncation. +as_save_IFS=$IFS; IFS=$PATH_SEPARATOR +for as_dir in $PATH +do + IFS=$as_save_IFS + test -z "$as_dir" && as_dir=. + for lt_ac_prog in sed gsed; do + for ac_exec_ext in '' $ac_executable_extensions; do + if $as_executable_p "$as_dir/$lt_ac_prog$ac_exec_ext"; then + lt_ac_sed_list="$lt_ac_sed_list $as_dir/$lt_ac_prog$ac_exec_ext" + fi + done + done +done +IFS=$as_save_IFS +lt_ac_max=0 +lt_ac_count=0 +# Add /usr/xpg4/bin/sed as it is typically found on Solaris +# along with /bin/sed that truncates output. +for lt_ac_sed in $lt_ac_sed_list /usr/xpg4/bin/sed; do + test ! -f $lt_ac_sed && continue + cat /dev/null > conftest.in + lt_ac_count=0 + echo $ECHO_N "0123456789$ECHO_C" >conftest.in + # Check for GNU sed and select it if it is found. + if "$lt_ac_sed" --version 2>&1 < /dev/null | grep 'GNU' > /dev/null; then + lt_cv_path_SED=$lt_ac_sed + break + fi + while true; do + cat conftest.in conftest.in >conftest.tmp + mv conftest.tmp conftest.in + cp conftest.in conftest.nl + echo >>conftest.nl + $lt_ac_sed -e 's/a$//' < conftest.nl >conftest.out || break + cmp -s conftest.out conftest.nl || break + # 10000 chars as input seems more than enough + test $lt_ac_count -gt 10 && break + lt_ac_count=`expr $lt_ac_count + 1` + if test $lt_ac_count -gt $lt_ac_max; then + lt_ac_max=$lt_ac_count + lt_cv_path_SED=$lt_ac_sed + fi + done +done + +fi + +SED=$lt_cv_path_SED + +echo "$as_me:$LINENO: result: $SED" >&5 +echo "${ECHO_T}$SED" >&6 + +echo "$as_me:$LINENO: checking for egrep" >&5 +echo $ECHO_N "checking for egrep... $ECHO_C" >&6 +if test "${ac_cv_prog_egrep+set}" = set; then + echo $ECHO_N "(cached) $ECHO_C" >&6 +else + if echo a | (grep -E '(a|b)') >/dev/null 2>&1 + then ac_cv_prog_egrep='grep -E' + else ac_cv_prog_egrep='egrep' + fi +fi +echo "$as_me:$LINENO: result: $ac_cv_prog_egrep" >&5 +echo "${ECHO_T}$ac_cv_prog_egrep" >&6 + EGREP=$ac_cv_prog_egrep + + + +# Check whether --with-gnu-ld or --without-gnu-ld was given. +if test "${with_gnu_ld+set}" = set; then + withval="$with_gnu_ld" + test "$withval" = no || with_gnu_ld=yes +else + with_gnu_ld=no +fi; +ac_prog=ld +if test "$GCC" = yes; then + # Check if gcc -print-prog-name=ld gives a path. + echo "$as_me:$LINENO: checking for ld used by $CC" >&5 +echo $ECHO_N "checking for ld used by $CC... $ECHO_C" >&6 + case $host in + *-*-mingw*) + # gcc leaves a trailing carriage return which upsets mingw + ac_prog=`($CC -print-prog-name=ld) 2>&5 | tr -d '\015'` ;; + *) + ac_prog=`($CC -print-prog-name=ld) 2>&5` ;; + esac + case $ac_prog in + # Accept absolute paths. + [\\/]* | ?:[\\/]*) + re_direlt='/[^/][^/]*/\.\./' + # Canonicalize the pathname of ld + ac_prog=`echo $ac_prog| $SED 's%\\\\%/%g'` + while echo $ac_prog | grep "$re_direlt" > /dev/null 2>&1; do + ac_prog=`echo $ac_prog| $SED "s%$re_direlt%/%"` + done + test -z "$LD" && LD="$ac_prog" + ;; + "") + # If it fails, then pretend we aren't using GCC. + ac_prog=ld + ;; + *) + # If it is relative, then search for the first ld in PATH. + with_gnu_ld=unknown + ;; + esac +elif test "$with_gnu_ld" = yes; then + echo "$as_me:$LINENO: checking for GNU ld" >&5 +echo $ECHO_N "checking for GNU ld... $ECHO_C" >&6 +else + echo "$as_me:$LINENO: checking for non-GNU ld" >&5 +echo $ECHO_N "checking for non-GNU ld... $ECHO_C" >&6 +fi +if test "${lt_cv_path_LD+set}" = set; then + echo $ECHO_N "(cached) $ECHO_C" >&6 +else + if test -z "$LD"; then + lt_save_ifs="$IFS"; IFS=$PATH_SEPARATOR + for ac_dir in $PATH; do + IFS="$lt_save_ifs" + test -z "$ac_dir" && ac_dir=. + if test -f "$ac_dir/$ac_prog" || test -f "$ac_dir/$ac_prog$ac_exeext"; then + lt_cv_path_LD="$ac_dir/$ac_prog" + # Check to see if the program is GNU ld. I'd rather use --version, + # but apparently some variants of GNU ld only accept -v. + # Break only if it was the GNU/non-GNU ld that we prefer. + case `"$lt_cv_path_LD" -v 2>&1 </dev/null` in + *GNU* | *'with BFD'*) + test "$with_gnu_ld" != no && break + ;; + *) + test "$with_gnu_ld" != yes && break + ;; + esac + fi + done + IFS="$lt_save_ifs" +else + lt_cv_path_LD="$LD" # Let the user override the test with a path. +fi +fi + +LD="$lt_cv_path_LD" +if test -n "$LD"; then + echo "$as_me:$LINENO: result: $LD" >&5 +echo "${ECHO_T}$LD" >&6 +else + echo "$as_me:$LINENO: result: no" >&5 +echo "${ECHO_T}no" >&6 +fi +test -z "$LD" && { { echo "$as_me:$LINENO: error: no acceptable ld found in \$PATH" >&5 +echo "$as_me: error: no acceptable ld found in \$PATH" >&2;} + { (exit 1); exit 1; }; } +echo "$as_me:$LINENO: checking if the linker ($LD) is GNU ld" >&5 +echo $ECHO_N "checking if the linker ($LD) is GNU ld... $ECHO_C" >&6 +if test "${lt_cv_prog_gnu_ld+set}" = set; then + echo $ECHO_N "(cached) $ECHO_C" >&6 +else + # I'd rather use --version here, but apparently some GNU lds only accept -v. +case `$LD -v 2>&1 </dev/null` in +*GNU* | *'with BFD'*) + lt_cv_prog_gnu_ld=yes + ;; +*) + lt_cv_prog_gnu_ld=no + ;; +esac +fi +echo "$as_me:$LINENO: result: $lt_cv_prog_gnu_ld" >&5 +echo "${ECHO_T}$lt_cv_prog_gnu_ld" >&6 +with_gnu_ld=$lt_cv_prog_gnu_ld + + +echo "$as_me:$LINENO: checking for $LD option to reload object files" >&5 +echo $ECHO_N "checking for $LD option to reload object files... $ECHO_C" >&6 +if test "${lt_cv_ld_reload_flag+set}" = set; then + echo $ECHO_N "(cached) $ECHO_C" >&6 +else + lt_cv_ld_reload_flag='-r' +fi +echo "$as_me:$LINENO: result: $lt_cv_ld_reload_flag" >&5 +echo "${ECHO_T}$lt_cv_ld_reload_flag" >&6 +reload_flag=$lt_cv_ld_reload_flag +case $reload_flag in +"" | " "*) ;; +*) reload_flag=" $reload_flag" ;; +esac +reload_cmds='$LD$reload_flag -o $output$reload_objs' +case $host_os in + darwin*) + if test "$GCC" = yes; then + reload_cmds='$LTCC $LTCFLAGS -nostdlib ${wl}-r -o $output$reload_objs' + else + reload_cmds='$LD$reload_flag -o $output$reload_objs' + fi + ;; +esac + +echo "$as_me:$LINENO: checking for BSD-compatible nm" >&5 +echo $ECHO_N "checking for BSD-compatible nm... $ECHO_C" >&6 +if test "${lt_cv_path_NM+set}" = set; then + echo $ECHO_N "(cached) $ECHO_C" >&6 +else + if test -n "$NM"; then + # Let the user override the test. + lt_cv_path_NM="$NM" +else + lt_nm_to_check="${ac_tool_prefix}nm" + if test -n "$ac_tool_prefix" && test "$build" = "$host"; then + lt_nm_to_check="$lt_nm_to_check nm" + fi + for lt_tmp_nm in $lt_nm_to_check; do + lt_save_ifs="$IFS"; IFS=$PATH_SEPARATOR + for ac_dir in $PATH /usr/ccs/bin/elf /usr/ccs/bin /usr/ucb /bin; do + IFS="$lt_save_ifs" + test -z "$ac_dir" && ac_dir=. + tmp_nm="$ac_dir/$lt_tmp_nm" + if test -f "$tmp_nm" || test -f "$tmp_nm$ac_exeext" ; then + # Check to see if the nm accepts a BSD-compat flag. + # Adding the `sed 1q' prevents false positives on HP-UX, which says: + # nm: unknown option "B" ignored + # Tru64's nm complains that /dev/null is an invalid object file + case `"$tmp_nm" -B /dev/null 2>&1 | sed '1q'` in + */dev/null* | *'Invalid file or object type'*) + lt_cv_path_NM="$tmp_nm -B" + break + ;; + *) + case `"$tmp_nm" -p /dev/null 2>&1 | sed '1q'` in + */dev/null*) + lt_cv_path_NM="$tmp_nm -p" + break + ;; + *) + lt_cv_path_NM=${lt_cv_path_NM="$tmp_nm"} # keep the first match, but + continue # so that we can try to find one that supports BSD flags + ;; + esac + ;; + esac + fi + done + IFS="$lt_save_ifs" + done + test -z "$lt_cv_path_NM" && lt_cv_path_NM=nm +fi +fi +echo "$as_me:$LINENO: result: $lt_cv_path_NM" >&5 +echo "${ECHO_T}$lt_cv_path_NM" >&6 +NM="$lt_cv_path_NM" + +echo "$as_me:$LINENO: checking whether ln -s works" >&5 +echo $ECHO_N "checking whether ln -s works... $ECHO_C" >&6 +LN_S=$as_ln_s +if test "$LN_S" = "ln -s"; then + echo "$as_me:$LINENO: result: yes" >&5 +echo "${ECHO_T}yes" >&6 +else + echo "$as_me:$LINENO: result: no, using $LN_S" >&5 +echo "${ECHO_T}no, using $LN_S" >&6 +fi + +echo "$as_me:$LINENO: checking how to recognise dependent libraries" >&5 +echo $ECHO_N "checking how to recognise dependent libraries... $ECHO_C" >&6 +if test "${lt_cv_deplibs_check_method+set}" = set; then + echo $ECHO_N "(cached) $ECHO_C" >&6 +else + lt_cv_file_magic_cmd='$MAGIC_CMD' +lt_cv_file_magic_test_file= +lt_cv_deplibs_check_method='unknown' +# Need to set the preceding variable on all platforms that support +# interlibrary dependencies. +# 'none' -- dependencies not supported. +# `unknown' -- same as none, but documents that we really don't know. +# 'pass_all' -- all dependencies passed with no checks. +# 'test_compile' -- check by making test program. +# 'file_magic [[regex]]' -- check by looking for files in library path +# which responds to the $file_magic_cmd with a given extended regex. +# If you have `file' or equivalent on your system and you're not sure +# whether `pass_all' will *always* work, you probably want this one. + +case $host_os in +aix4* | aix5*) + lt_cv_deplibs_check_method=pass_all + ;; + +beos*) + lt_cv_deplibs_check_method=pass_all + ;; + +bsdi[45]*) + lt_cv_deplibs_check_method='file_magic ELF [0-9][0-9]*-bit [ML]SB (shared object|dynamic lib)' + lt_cv_file_magic_cmd='/usr/bin/file -L' + lt_cv_file_magic_test_file=/shlib/libc.so + ;; + +cygwin*) + # func_win32_libid is a shell function defined in ltmain.sh + lt_cv_deplibs_check_method='file_magic ^x86 archive import|^x86 DLL' + lt_cv_file_magic_cmd='func_win32_libid' + ;; + +mingw* | pw32*) + # Base MSYS/MinGW do not provide the 'file' command needed by + # func_win32_libid shell function, so use a weaker test based on 'objdump'. + lt_cv_deplibs_check_method='file_magic file format pei*-i386(.*architecture: i386)?' + lt_cv_file_magic_cmd='$OBJDUMP -f' + ;; + +darwin* | rhapsody*) + lt_cv_deplibs_check_method=pass_all + ;; + +freebsd* | kfreebsd*-gnu | dragonfly*) + if echo __ELF__ | $CC -E - | grep __ELF__ > /dev/null; then + case $host_cpu in + i*86 ) + # Not sure whether the presence of OpenBSD here was a mistake. + # Let's accept both of them until this is cleared up. + lt_cv_deplibs_check_method='file_magic (FreeBSD|OpenBSD|DragonFly)/i[3-9]86 (compact )?demand paged shared library' + lt_cv_file_magic_cmd=/usr/bin/file + lt_cv_file_magic_test_file=`echo /usr/lib/libc.so.*` + ;; + esac + else + lt_cv_deplibs_check_method=pass_all + fi + ;; + +gnu*) + lt_cv_deplibs_check_method=pass_all + ;; + +hpux10.20* | hpux11*) + lt_cv_file_magic_cmd=/usr/bin/file + case $host_cpu in + ia64*) + lt_cv_deplibs_check_method='file_magic (s[0-9][0-9][0-9]|ELF-[0-9][0-9]) shared object file - IA64' + lt_cv_file_magic_test_file=/usr/lib/hpux32/libc.so + ;; + hppa*64*) + lt_cv_deplibs_check_method='file_magic (s[0-9][0-9][0-9]|ELF-[0-9][0-9]) shared object file - PA-RISC [0-9].[0-9]' + lt_cv_file_magic_test_file=/usr/lib/pa20_64/libc.sl + ;; + *) + lt_cv_deplibs_check_method='file_magic (s[0-9][0-9][0-9]|PA-RISC[0-9].[0-9]) shared library' + lt_cv_file_magic_test_file=/usr/lib/libc.sl + ;; + esac + ;; + +interix3*) + # PIC code is broken on Interix 3.x, that's why |\.a not |_pic\.a here + lt_cv_deplibs_check_method='match_pattern /lib[^/]+(\.so|\.a)$' + ;; + +irix5* | irix6* | nonstopux*) + case $LD in + *-32|*"-32 ") libmagic=32-bit;; + *-n32|*"-n32 ") libmagic=N32;; + *-64|*"-64 ") libmagic=64-bit;; + *) libmagic=never-match;; + esac + lt_cv_deplibs_check_method=pass_all + ;; + +# This must be Linux ELF. +linux*) + lt_cv_deplibs_check_method=pass_all + ;; + +netbsd*) + if echo __ELF__ | $CC -E - | grep __ELF__ > /dev/null; then + lt_cv_deplibs_check_method='match_pattern /lib[^/]+(\.so\.[0-9]+\.[0-9]+|_pic\.a)$' + else + lt_cv_deplibs_check_method='match_pattern /lib[^/]+(\.so|_pic\.a)$' + fi + ;; + +newos6*) + lt_cv_deplibs_check_method='file_magic ELF [0-9][0-9]*-bit [ML]SB (executable|dynamic lib)' + lt_cv_file_magic_cmd=/usr/bin/file + lt_cv_file_magic_test_file=/usr/lib/libnls.so + ;; + +nto-qnx*) + lt_cv_deplibs_check_method=unknown + ;; + +openbsd*) + if test -z "`echo __ELF__ | $CC -E - | grep __ELF__`" || test "$host_os-$host_cpu" = "openbsd2.8-powerpc"; then + lt_cv_deplibs_check_method='match_pattern /lib[^/]+(\.so\.[0-9]+\.[0-9]+|\.so|_pic\.a)$' + else + lt_cv_deplibs_check_method='match_pattern /lib[^/]+(\.so\.[0-9]+\.[0-9]+|_pic\.a)$' + fi + ;; + +osf3* | osf4* | osf5*) + lt_cv_deplibs_check_method=pass_all + ;; + +solaris*) + lt_cv_deplibs_check_method=pass_all + ;; + +sysv4 | sysv4.3*) + case $host_vendor in + motorola) + lt_cv_deplibs_check_method='file_magic ELF [0-9][0-9]*-bit [ML]SB (shared object|dynamic lib) M[0-9][0-9]* Version [0-9]' + lt_cv_file_magic_test_file=`echo /usr/lib/libc.so*` + ;; + ncr) + lt_cv_deplibs_check_method=pass_all + ;; + sequent) + lt_cv_file_magic_cmd='/bin/file' + lt_cv_deplibs_check_method='file_magic ELF [0-9][0-9]*-bit [LM]SB (shared object|dynamic lib )' + ;; + sni) + lt_cv_file_magic_cmd='/bin/file' + lt_cv_deplibs_check_method="file_magic ELF [0-9][0-9]*-bit [LM]SB dynamic lib" + lt_cv_file_magic_test_file=/lib/libc.so + ;; + siemens) + lt_cv_deplibs_check_method=pass_all + ;; + pc) + lt_cv_deplibs_check_method=pass_all + ;; + esac + ;; + +sysv5* | sco3.2v5* | sco5v6* | unixware* | OpenUNIX* | sysv4*uw2*) + lt_cv_deplibs_check_method=pass_all + ;; +esac + +fi +echo "$as_me:$LINENO: result: $lt_cv_deplibs_check_method" >&5 +echo "${ECHO_T}$lt_cv_deplibs_check_method" >&6 +file_magic_cmd=$lt_cv_file_magic_cmd +deplibs_check_method=$lt_cv_deplibs_check_method +test -z "$deplibs_check_method" && deplibs_check_method=unknown + + + + +# If no C compiler was specified, use CC. +LTCC=${LTCC-"$CC"} + +# If no C compiler flags were specified, use CFLAGS. +LTCFLAGS=${LTCFLAGS-"$CFLAGS"} + +# Allow CC to be a program name with arguments. +compiler=$CC + + +# Check whether --enable-libtool-lock or --disable-libtool-lock was given. +if test "${enable_libtool_lock+set}" = set; then + enableval="$enable_libtool_lock" + +fi; +test "x$enable_libtool_lock" != xno && enable_libtool_lock=yes + +# Some flags need to be propagated to the compiler or linker for good +# libtool support. +case $host in +ia64-*-hpux*) + # Find out which ABI we are using. + echo 'int i;' > conftest.$ac_ext + if { (eval echo "$as_me:$LINENO: \"$ac_compile\"") >&5 + (eval $ac_compile) 2>&5 + ac_status=$? + echo "$as_me:$LINENO: \$? = $ac_status" >&5 + (exit $ac_status); }; then + case `/usr/bin/file conftest.$ac_objext` in + *ELF-32*) + HPUX_IA64_MODE="32" + ;; + *ELF-64*) + HPUX_IA64_MODE="64" + ;; + esac + fi + rm -rf conftest* + ;; +*-*-irix6*) + # Find out which ABI we are using. + echo '#line 4315 "configure"' > conftest.$ac_ext + if { (eval echo "$as_me:$LINENO: \"$ac_compile\"") >&5 + (eval $ac_compile) 2>&5 + ac_status=$? + echo "$as_me:$LINENO: \$? = $ac_status" >&5 + (exit $ac_status); }; then + if test "$lt_cv_prog_gnu_ld" = yes; then + case `/usr/bin/file conftest.$ac_objext` in + *32-bit*) + LD="${LD-ld} -melf32bsmip" + ;; + *N32*) + LD="${LD-ld} -melf32bmipn32" + ;; + *64-bit*) + LD="${LD-ld} -melf64bmip" + ;; + esac + else + case `/usr/bin/file conftest.$ac_objext` in + *32-bit*) + LD="${LD-ld} -32" + ;; + *N32*) + LD="${LD-ld} -n32" + ;; + *64-bit*) + LD="${LD-ld} -64" + ;; + esac + fi + fi + rm -rf conftest* + ;; + +x86_64-*linux*|ppc*-*linux*|powerpc*-*linux*|s390*-*linux*|sparc*-*linux*) + # Find out which ABI we are using. + echo 'int i;' > conftest.$ac_ext + if { (eval echo "$as_me:$LINENO: \"$ac_compile\"") >&5 + (eval $ac_compile) 2>&5 + ac_status=$? + echo "$as_me:$LINENO: \$? = $ac_status" >&5 + (exit $ac_status); }; then + case `/usr/bin/file conftest.o` in + *32-bit*) + case $host in + x86_64-*linux*) + LD="${LD-ld} -m elf_i386" + ;; + ppc64-*linux*|powerpc64-*linux*) + LD="${LD-ld} -m elf32ppclinux" + ;; + s390x-*linux*) + LD="${LD-ld} -m elf_s390" + ;; + sparc64-*linux*) + LD="${LD-ld} -m elf32_sparc" + ;; + esac + ;; + *64-bit*) + case $host in + x86_64-*linux*) + LD="${LD-ld} -m elf_x86_64" + ;; + ppc*-*linux*|powerpc*-*linux*) + LD="${LD-ld} -m elf64ppc" + ;; + s390*-*linux*) + LD="${LD-ld} -m elf64_s390" + ;; + sparc*-*linux*) + LD="${LD-ld} -m elf64_sparc" + ;; + esac + ;; + esac + fi + rm -rf conftest* + ;; + +*-*-sco3.2v5*) + # On SCO OpenServer 5, we need -belf to get full-featured binaries. + SAVE_CFLAGS="$CFLAGS" + CFLAGS="$CFLAGS -belf" + echo "$as_me:$LINENO: checking whether the C compiler needs -belf" >&5 +echo $ECHO_N "checking whether the C compiler needs -belf... $ECHO_C" >&6 +if test "${lt_cv_cc_needs_belf+set}" = set; then + echo $ECHO_N "(cached) $ECHO_C" >&6 +else + ac_ext=c +ac_cpp='$CPP $CPPFLAGS' +ac_compile='$CC -c $CFLAGS $CPPFLAGS conftest.$ac_ext >&5' +ac_link='$CC -o conftest$ac_exeext $CFLAGS $CPPFLAGS $LDFLAGS conftest.$ac_ext $LIBS >&5' +ac_compiler_gnu=$ac_cv_c_compiler_gnu + + cat >conftest.$ac_ext <<_ACEOF +/* confdefs.h. */ +_ACEOF +cat confdefs.h >>conftest.$ac_ext +cat >>conftest.$ac_ext <<_ACEOF +/* end confdefs.h. */ + +int +main () +{ + + ; + return 0; +} +_ACEOF +rm -f conftest.$ac_objext conftest$ac_exeext +if { (eval echo "$as_me:$LINENO: \"$ac_link\"") >&5 + (eval $ac_link) 2>conftest.er1 + ac_status=$? + grep -v '^ *+' conftest.er1 >conftest.err + rm -f conftest.er1 + cat conftest.err >&5 + echo "$as_me:$LINENO: \$? = $ac_status" >&5 + (exit $ac_status); } && + { ac_try='test -z "$ac_c_werror_flag" + || test ! -s conftest.err' + { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5 + (eval $ac_try) 2>&5 + ac_status=$? + echo "$as_me:$LINENO: \$? = $ac_status" >&5 + (exit $ac_status); }; } && + { ac_try='test -s conftest$ac_exeext' + { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5 + (eval $ac_try) 2>&5 + ac_status=$? + echo "$as_me:$LINENO: \$? = $ac_status" >&5 + (exit $ac_status); }; }; then + lt_cv_cc_needs_belf=yes +else + echo "$as_me: failed program was:" >&5 +sed 's/^/| /' conftest.$ac_ext >&5 + +lt_cv_cc_needs_belf=no +fi +rm -f conftest.err conftest.$ac_objext \ + conftest$ac_exeext conftest.$ac_ext + ac_ext=c +ac_cpp='$CPP $CPPFLAGS' +ac_compile='$CC -c $CFLAGS $CPPFLAGS conftest.$ac_ext >&5' +ac_link='$CC -o conftest$ac_exeext $CFLAGS $CPPFLAGS $LDFLAGS conftest.$ac_ext $LIBS >&5' +ac_compiler_gnu=$ac_cv_c_compiler_gnu + +fi +echo "$as_me:$LINENO: result: $lt_cv_cc_needs_belf" >&5 +echo "${ECHO_T}$lt_cv_cc_needs_belf" >&6 + if test x"$lt_cv_cc_needs_belf" != x"yes"; then + # this is probably gcc 2.8.0, egcs 1.0 or newer; no need for -belf + CFLAGS="$SAVE_CFLAGS" + fi + ;; +sparc*-*solaris*) + # Find out which ABI we are using. + echo 'int i;' > conftest.$ac_ext + if { (eval echo "$as_me:$LINENO: \"$ac_compile\"") >&5 + (eval $ac_compile) 2>&5 + ac_status=$? + echo "$as_me:$LINENO: \$? = $ac_status" >&5 + (exit $ac_status); }; then + case `/usr/bin/file conftest.o` in + *64-bit*) + case $lt_cv_prog_gnu_ld in + yes*) LD="${LD-ld} -m elf64_sparc" ;; + *) LD="${LD-ld} -64" ;; + esac + ;; + esac + fi + rm -rf conftest* + ;; + + +esac + +need_locks="$enable_libtool_lock" + + +ac_ext=c +ac_cpp='$CPP $CPPFLAGS' +ac_compile='$CC -c $CFLAGS $CPPFLAGS conftest.$ac_ext >&5' +ac_link='$CC -o conftest$ac_exeext $CFLAGS $CPPFLAGS $LDFLAGS conftest.$ac_ext $LIBS >&5' +ac_compiler_gnu=$ac_cv_c_compiler_gnu +echo "$as_me:$LINENO: checking how to run the C preprocessor" >&5 +echo $ECHO_N "checking how to run the C preprocessor... $ECHO_C" >&6 +# On Suns, sometimes $CPP names a directory. +if test -n "$CPP" && test -d "$CPP"; then + CPP= +fi +if test -z "$CPP"; then + if test "${ac_cv_prog_CPP+set}" = set; then + echo $ECHO_N "(cached) $ECHO_C" >&6 +else + # Double quotes because CPP needs to be expanded + for CPP in "$CC -E" "$CC -E -traditional-cpp" "/lib/cpp" + do + ac_preproc_ok=false +for ac_c_preproc_warn_flag in '' yes +do + # Use a header file that comes with gcc, so configuring glibc + # with a fresh cross-compiler works. + # Prefer <limits.h> to <assert.h> if __STDC__ is defined, since + # <limits.h> exists even on freestanding compilers. + # On the NeXT, cc -E runs the code through the compiler's parser, + # not just through cpp. "Syntax error" is here to catch this case. + cat >conftest.$ac_ext <<_ACEOF +/* confdefs.h. */ +_ACEOF +cat confdefs.h >>conftest.$ac_ext +cat >>conftest.$ac_ext <<_ACEOF +/* end confdefs.h. */ +#ifdef __STDC__ +# include <limits.h> +#else +# include <assert.h> +#endif + Syntax error +_ACEOF +if { (eval echo "$as_me:$LINENO: \"$ac_cpp conftest.$ac_ext\"") >&5 + (eval $ac_cpp conftest.$ac_ext) 2>conftest.er1 + ac_status=$? + grep -v '^ *+' conftest.er1 >conftest.err + rm -f conftest.er1 + cat conftest.err >&5 + echo "$as_me:$LINENO: \$? = $ac_status" >&5 + (exit $ac_status); } >/dev/null; then + if test -s conftest.err; then + ac_cpp_err=$ac_c_preproc_warn_flag + ac_cpp_err=$ac_cpp_err$ac_c_werror_flag + else + ac_cpp_err= + fi +else + ac_cpp_err=yes +fi +if test -z "$ac_cpp_err"; then + : +else + echo "$as_me: failed program was:" >&5 +sed 's/^/| /' conftest.$ac_ext >&5 + + # Broken: fails on valid input. +continue +fi +rm -f conftest.err conftest.$ac_ext + + # OK, works on sane cases. Now check whether non-existent headers + # can be detected and how. + cat >conftest.$ac_ext <<_ACEOF +/* confdefs.h. */ +_ACEOF +cat confdefs.h >>conftest.$ac_ext +cat >>conftest.$ac_ext <<_ACEOF +/* end confdefs.h. */ +#include <ac_nonexistent.h> +_ACEOF +if { (eval echo "$as_me:$LINENO: \"$ac_cpp conftest.$ac_ext\"") >&5 + (eval $ac_cpp conftest.$ac_ext) 2>conftest.er1 + ac_status=$? + grep -v '^ *+' conftest.er1 >conftest.err + rm -f conftest.er1 + cat conftest.err >&5 + echo "$as_me:$LINENO: \$? = $ac_status" >&5 + (exit $ac_status); } >/dev/null; then + if test -s conftest.err; then + ac_cpp_err=$ac_c_preproc_warn_flag + ac_cpp_err=$ac_cpp_err$ac_c_werror_flag + else + ac_cpp_err= + fi +else + ac_cpp_err=yes +fi +if test -z "$ac_cpp_err"; then + # Broken: success on invalid input. +continue +else + echo "$as_me: failed program was:" >&5 +sed 's/^/| /' conftest.$ac_ext >&5 + + # Passes both tests. +ac_preproc_ok=: +break +fi +rm -f conftest.err conftest.$ac_ext + +done +# Because of `break', _AC_PREPROC_IFELSE's cleaning code was skipped. +rm -f conftest.err conftest.$ac_ext +if $ac_preproc_ok; then + break +fi + + done + ac_cv_prog_CPP=$CPP + +fi + CPP=$ac_cv_prog_CPP +else + ac_cv_prog_CPP=$CPP +fi +echo "$as_me:$LINENO: result: $CPP" >&5 +echo "${ECHO_T}$CPP" >&6 +ac_preproc_ok=false +for ac_c_preproc_warn_flag in '' yes +do + # Use a header file that comes with gcc, so configuring glibc + # with a fresh cross-compiler works. + # Prefer <limits.h> to <assert.h> if __STDC__ is defined, since + # <limits.h> exists even on freestanding compilers. + # On the NeXT, cc -E runs the code through the compiler's parser, + # not just through cpp. "Syntax error" is here to catch this case. + cat >conftest.$ac_ext <<_ACEOF +/* confdefs.h. */ +_ACEOF +cat confdefs.h >>conftest.$ac_ext +cat >>conftest.$ac_ext <<_ACEOF +/* end confdefs.h. */ +#ifdef __STDC__ +# include <limits.h> +#else +# include <assert.h> +#endif + Syntax error +_ACEOF +if { (eval echo "$as_me:$LINENO: \"$ac_cpp conftest.$ac_ext\"") >&5 + (eval $ac_cpp conftest.$ac_ext) 2>conftest.er1 + ac_status=$? + grep -v '^ *+' conftest.er1 >conftest.err + rm -f conftest.er1 + cat conftest.err >&5 + echo "$as_me:$LINENO: \$? = $ac_status" >&5 + (exit $ac_status); } >/dev/null; then + if test -s conftest.err; then + ac_cpp_err=$ac_c_preproc_warn_flag + ac_cpp_err=$ac_cpp_err$ac_c_werror_flag + else + ac_cpp_err= + fi +else + ac_cpp_err=yes +fi +if test -z "$ac_cpp_err"; then + : +else + echo "$as_me: failed program was:" >&5 +sed 's/^/| /' conftest.$ac_ext >&5 + + # Broken: fails on valid input. +continue +fi +rm -f conftest.err conftest.$ac_ext + + # OK, works on sane cases. Now check whether non-existent headers + # can be detected and how. + cat >conftest.$ac_ext <<_ACEOF +/* confdefs.h. */ +_ACEOF +cat confdefs.h >>conftest.$ac_ext +cat >>conftest.$ac_ext <<_ACEOF +/* end confdefs.h. */ +#include <ac_nonexistent.h> +_ACEOF +if { (eval echo "$as_me:$LINENO: \"$ac_cpp conftest.$ac_ext\"") >&5 + (eval $ac_cpp conftest.$ac_ext) 2>conftest.er1 + ac_status=$? + grep -v '^ *+' conftest.er1 >conftest.err + rm -f conftest.er1 + cat conftest.err >&5 + echo "$as_me:$LINENO: \$? = $ac_status" >&5 + (exit $ac_status); } >/dev/null; then + if test -s conftest.err; then + ac_cpp_err=$ac_c_preproc_warn_flag + ac_cpp_err=$ac_cpp_err$ac_c_werror_flag + else + ac_cpp_err= + fi +else + ac_cpp_err=yes +fi +if test -z "$ac_cpp_err"; then + # Broken: success on invalid input. +continue +else + echo "$as_me: failed program was:" >&5 +sed 's/^/| /' conftest.$ac_ext >&5 + + # Passes both tests. +ac_preproc_ok=: +break +fi +rm -f conftest.err conftest.$ac_ext + +done +# Because of `break', _AC_PREPROC_IFELSE's cleaning code was skipped. +rm -f conftest.err conftest.$ac_ext +if $ac_preproc_ok; then + : +else + { { echo "$as_me:$LINENO: error: C preprocessor \"$CPP\" fails sanity check +See \`config.log' for more details." >&5 +echo "$as_me: error: C preprocessor \"$CPP\" fails sanity check +See \`config.log' for more details." >&2;} + { (exit 1); exit 1; }; } +fi + +ac_ext=c +ac_cpp='$CPP $CPPFLAGS' +ac_compile='$CC -c $CFLAGS $CPPFLAGS conftest.$ac_ext >&5' +ac_link='$CC -o conftest$ac_exeext $CFLAGS $CPPFLAGS $LDFLAGS conftest.$ac_ext $LIBS >&5' +ac_compiler_gnu=$ac_cv_c_compiler_gnu + + +echo "$as_me:$LINENO: checking for ANSI C header files" >&5 +echo $ECHO_N "checking for ANSI C header files... $ECHO_C" >&6 +if test "${ac_cv_header_stdc+set}" = set; then + echo $ECHO_N "(cached) $ECHO_C" >&6 +else + cat >conftest.$ac_ext <<_ACEOF +/* confdefs.h. */ +_ACEOF +cat confdefs.h >>conftest.$ac_ext +cat >>conftest.$ac_ext <<_ACEOF +/* end confdefs.h. */ +#include <stdlib.h> +#include <stdarg.h> +#include <string.h> +#include <float.h> + +int +main () +{ + + ; + return 0; +} +_ACEOF +rm -f conftest.$ac_objext +if { (eval echo "$as_me:$LINENO: \"$ac_compile\"") >&5 + (eval $ac_compile) 2>conftest.er1 + ac_status=$? + grep -v '^ *+' conftest.er1 >conftest.err + rm -f conftest.er1 + cat conftest.err >&5 + echo "$as_me:$LINENO: \$? = $ac_status" >&5 + (exit $ac_status); } && + { ac_try='test -z "$ac_c_werror_flag" + || test ! -s conftest.err' + { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5 + (eval $ac_try) 2>&5 + ac_status=$? + echo "$as_me:$LINENO: \$? = $ac_status" >&5 + (exit $ac_status); }; } && + { ac_try='test -s conftest.$ac_objext' + { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5 + (eval $ac_try) 2>&5 + ac_status=$? + echo "$as_me:$LINENO: \$? = $ac_status" >&5 + (exit $ac_status); }; }; then + ac_cv_header_stdc=yes +else + echo "$as_me: failed program was:" >&5 +sed 's/^/| /' conftest.$ac_ext >&5 + +ac_cv_header_stdc=no +fi +rm -f conftest.err conftest.$ac_objext conftest.$ac_ext + +if test $ac_cv_header_stdc = yes; then + # SunOS 4.x string.h does not declare mem*, contrary to ANSI. + cat >conftest.$ac_ext <<_ACEOF +/* confdefs.h. */ +_ACEOF +cat confdefs.h >>conftest.$ac_ext +cat >>conftest.$ac_ext <<_ACEOF +/* end confdefs.h. */ +#include <string.h> + +_ACEOF +if (eval "$ac_cpp conftest.$ac_ext") 2>&5 | + $EGREP "memchr" >/dev/null 2>&1; then + : +else + ac_cv_header_stdc=no +fi +rm -f conftest* + +fi + +if test $ac_cv_header_stdc = yes; then + # ISC 2.0.2 stdlib.h does not declare free, contrary to ANSI. + cat >conftest.$ac_ext <<_ACEOF +/* confdefs.h. */ +_ACEOF +cat confdefs.h >>conftest.$ac_ext +cat >>conftest.$ac_ext <<_ACEOF +/* end confdefs.h. */ +#include <stdlib.h> + +_ACEOF +if (eval "$ac_cpp conftest.$ac_ext") 2>&5 | + $EGREP "free" >/dev/null 2>&1; then + : +else + ac_cv_header_stdc=no +fi +rm -f conftest* + +fi + +if test $ac_cv_header_stdc = yes; then + # /bin/cc in Irix-4.0.5 gets non-ANSI ctype macros unless using -ansi. + if test "$cross_compiling" = yes; then + : +else + cat >conftest.$ac_ext <<_ACEOF +/* confdefs.h. */ +_ACEOF +cat confdefs.h >>conftest.$ac_ext +cat >>conftest.$ac_ext <<_ACEOF +/* end confdefs.h. */ +#include <ctype.h> +#if ((' ' & 0x0FF) == 0x020) +# define ISLOWER(c) ('a' <= (c) && (c) <= 'z') +# define TOUPPER(c) (ISLOWER(c) ? 'A' + ((c) - 'a') : (c)) +#else +# define ISLOWER(c) \ + (('a' <= (c) && (c) <= 'i') \ + || ('j' <= (c) && (c) <= 'r') \ + || ('s' <= (c) && (c) <= 'z')) +# define TOUPPER(c) (ISLOWER(c) ? ((c) | 0x40) : (c)) +#endif + +#define XOR(e, f) (((e) && !(f)) || (!(e) && (f))) +int +main () +{ + int i; + for (i = 0; i < 256; i++) + if (XOR (islower (i), ISLOWER (i)) + || toupper (i) != TOUPPER (i)) + exit(2); + exit (0); +} +_ACEOF +rm -f conftest$ac_exeext +if { (eval echo "$as_me:$LINENO: \"$ac_link\"") >&5 + (eval $ac_link) 2>&5 + ac_status=$? + echo "$as_me:$LINENO: \$? = $ac_status" >&5 + (exit $ac_status); } && { ac_try='./conftest$ac_exeext' + { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5 + (eval $ac_try) 2>&5 + ac_status=$? + echo "$as_me:$LINENO: \$? = $ac_status" >&5 + (exit $ac_status); }; }; then + : +else + echo "$as_me: program exited with status $ac_status" >&5 +echo "$as_me: failed program was:" >&5 +sed 's/^/| /' conftest.$ac_ext >&5 + +( exit $ac_status ) +ac_cv_header_stdc=no +fi +rm -f core *.core gmon.out bb.out conftest$ac_exeext conftest.$ac_objext conftest.$ac_ext +fi +fi +fi +echo "$as_me:$LINENO: result: $ac_cv_header_stdc" >&5 +echo "${ECHO_T}$ac_cv_header_stdc" >&6 +if test $ac_cv_header_stdc = yes; then + +cat >>confdefs.h <<\_ACEOF +#define STDC_HEADERS 1 +_ACEOF + +fi + +# On IRIX 5.3, sys/types and inttypes.h are conflicting. + + + + + + + + + +for ac_header in sys/types.h sys/stat.h stdlib.h string.h memory.h strings.h \ + inttypes.h stdint.h unistd.h +do +as_ac_Header=`echo "ac_cv_header_$ac_header" | $as_tr_sh` +echo "$as_me:$LINENO: checking for $ac_header" >&5 +echo $ECHO_N "checking for $ac_header... $ECHO_C" >&6 +if eval "test \"\${$as_ac_Header+set}\" = set"; then + echo $ECHO_N "(cached) $ECHO_C" >&6 +else + cat >conftest.$ac_ext <<_ACEOF +/* confdefs.h. */ +_ACEOF +cat confdefs.h >>conftest.$ac_ext +cat >>conftest.$ac_ext <<_ACEOF +/* end confdefs.h. */ +$ac_includes_default + +#include <$ac_header> +_ACEOF +rm -f conftest.$ac_objext +if { (eval echo "$as_me:$LINENO: \"$ac_compile\"") >&5 + (eval $ac_compile) 2>conftest.er1 + ac_status=$? + grep -v '^ *+' conftest.er1 >conftest.err + rm -f conftest.er1 + cat conftest.err >&5 + echo "$as_me:$LINENO: \$? = $ac_status" >&5 + (exit $ac_status); } && + { ac_try='test -z "$ac_c_werror_flag" + || test ! -s conftest.err' + { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5 + (eval $ac_try) 2>&5 + ac_status=$? + echo "$as_me:$LINENO: \$? = $ac_status" >&5 + (exit $ac_status); }; } && + { ac_try='test -s conftest.$ac_objext' + { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5 + (eval $ac_try) 2>&5 + ac_status=$? + echo "$as_me:$LINENO: \$? = $ac_status" >&5 + (exit $ac_status); }; }; then + eval "$as_ac_Header=yes" +else + echo "$as_me: failed program was:" >&5 +sed 's/^/| /' conftest.$ac_ext >&5 + +eval "$as_ac_Header=no" +fi +rm -f conftest.err conftest.$ac_objext conftest.$ac_ext +fi +echo "$as_me:$LINENO: result: `eval echo '${'$as_ac_Header'}'`" >&5 +echo "${ECHO_T}`eval echo '${'$as_ac_Header'}'`" >&6 +if test `eval echo '${'$as_ac_Header'}'` = yes; then + cat >>confdefs.h <<_ACEOF +#define `echo "HAVE_$ac_header" | $as_tr_cpp` 1 +_ACEOF + +fi + +done + + + +for ac_header in dlfcn.h +do +as_ac_Header=`echo "ac_cv_header_$ac_header" | $as_tr_sh` +if eval "test \"\${$as_ac_Header+set}\" = set"; then + echo "$as_me:$LINENO: checking for $ac_header" >&5 +echo $ECHO_N "checking for $ac_header... $ECHO_C" >&6 +if eval "test \"\${$as_ac_Header+set}\" = set"; then + echo $ECHO_N "(cached) $ECHO_C" >&6 +fi +echo "$as_me:$LINENO: result: `eval echo '${'$as_ac_Header'}'`" >&5 +echo "${ECHO_T}`eval echo '${'$as_ac_Header'}'`" >&6 +else + # Is the header compilable? +echo "$as_me:$LINENO: checking $ac_header usability" >&5 +echo $ECHO_N "checking $ac_header usability... $ECHO_C" >&6 +cat >conftest.$ac_ext <<_ACEOF +/* confdefs.h. */ +_ACEOF +cat confdefs.h >>conftest.$ac_ext +cat >>conftest.$ac_ext <<_ACEOF +/* end confdefs.h. */ +$ac_includes_default +#include <$ac_header> +_ACEOF +rm -f conftest.$ac_objext +if { (eval echo "$as_me:$LINENO: \"$ac_compile\"") >&5 + (eval $ac_compile) 2>conftest.er1 + ac_status=$? + grep -v '^ *+' conftest.er1 >conftest.err + rm -f conftest.er1 + cat conftest.err >&5 + echo "$as_me:$LINENO: \$? = $ac_status" >&5 + (exit $ac_status); } && + { ac_try='test -z "$ac_c_werror_flag" + || test ! -s conftest.err' + { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5 + (eval $ac_try) 2>&5 + ac_status=$? + echo "$as_me:$LINENO: \$? = $ac_status" >&5 + (exit $ac_status); }; } && + { ac_try='test -s conftest.$ac_objext' + { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5 + (eval $ac_try) 2>&5 + ac_status=$? + echo "$as_me:$LINENO: \$? = $ac_status" >&5 + (exit $ac_status); }; }; then + ac_header_compiler=yes +else + echo "$as_me: failed program was:" >&5 +sed 's/^/| /' conftest.$ac_ext >&5 + +ac_header_compiler=no +fi +rm -f conftest.err conftest.$ac_objext conftest.$ac_ext +echo "$as_me:$LINENO: result: $ac_header_compiler" >&5 +echo "${ECHO_T}$ac_header_compiler" >&6 + +# Is the header present? +echo "$as_me:$LINENO: checking $ac_header presence" >&5 +echo $ECHO_N "checking $ac_header presence... $ECHO_C" >&6 +cat >conftest.$ac_ext <<_ACEOF +/* confdefs.h. */ +_ACEOF +cat confdefs.h >>conftest.$ac_ext +cat >>conftest.$ac_ext <<_ACEOF +/* end confdefs.h. */ +#include <$ac_header> +_ACEOF +if { (eval echo "$as_me:$LINENO: \"$ac_cpp conftest.$ac_ext\"") >&5 + (eval $ac_cpp conftest.$ac_ext) 2>conftest.er1 + ac_status=$? + grep -v '^ *+' conftest.er1 >conftest.err + rm -f conftest.er1 + cat conftest.err >&5 + echo "$as_me:$LINENO: \$? = $ac_status" >&5 + (exit $ac_status); } >/dev/null; then + if test -s conftest.err; then + ac_cpp_err=$ac_c_preproc_warn_flag + ac_cpp_err=$ac_cpp_err$ac_c_werror_flag + else + ac_cpp_err= + fi +else + ac_cpp_err=yes +fi +if test -z "$ac_cpp_err"; then + ac_header_preproc=yes +else + echo "$as_me: failed program was:" >&5 +sed 's/^/| /' conftest.$ac_ext >&5 + + ac_header_preproc=no +fi +rm -f conftest.err conftest.$ac_ext +echo "$as_me:$LINENO: result: $ac_header_preproc" >&5 +echo "${ECHO_T}$ac_header_preproc" >&6 + +# So? What about this header? +case $ac_header_compiler:$ac_header_preproc:$ac_c_preproc_warn_flag in + yes:no: ) + { echo "$as_me:$LINENO: WARNING: $ac_header: accepted by the compiler, rejected by the preprocessor!" >&5 +echo "$as_me: WARNING: $ac_header: accepted by the compiler, rejected by the preprocessor!" >&2;} + { echo "$as_me:$LINENO: WARNING: $ac_header: proceeding with the compiler's result" >&5 +echo "$as_me: WARNING: $ac_header: proceeding with the compiler's result" >&2;} + ac_header_preproc=yes + ;; + no:yes:* ) + { echo "$as_me:$LINENO: WARNING: $ac_header: present but cannot be compiled" >&5 +echo "$as_me: WARNING: $ac_header: present but cannot be compiled" >&2;} + { echo "$as_me:$LINENO: WARNING: $ac_header: check for missing prerequisite headers?" >&5 +echo "$as_me: WARNING: $ac_header: check for missing prerequisite headers?" >&2;} + { echo "$as_me:$LINENO: WARNING: $ac_header: see the Autoconf documentation" >&5 +echo "$as_me: WARNING: $ac_header: see the Autoconf documentation" >&2;} + { echo "$as_me:$LINENO: WARNING: $ac_header: section \"Present But Cannot Be Compiled\"" >&5 +echo "$as_me: WARNING: $ac_header: section \"Present But Cannot Be Compiled\"" >&2;} + { echo "$as_me:$LINENO: WARNING: $ac_header: proceeding with the preprocessor's result" >&5 +echo "$as_me: WARNING: $ac_header: proceeding with the preprocessor's result" >&2;} + { echo "$as_me:$LINENO: WARNING: $ac_header: in the future, the compiler will take precedence" >&5 +echo "$as_me: WARNING: $ac_header: in the future, the compiler will take precedence" >&2;} + ( + cat <<\_ASBOX +## ------------------------------------------ ## +## Report this to the AC_PACKAGE_NAME lists. ## +## ------------------------------------------ ## +_ASBOX + ) | + sed "s/^/$as_me: WARNING: /" >&2 + ;; +esac +echo "$as_me:$LINENO: checking for $ac_header" >&5 +echo $ECHO_N "checking for $ac_header... $ECHO_C" >&6 +if eval "test \"\${$as_ac_Header+set}\" = set"; then + echo $ECHO_N "(cached) $ECHO_C" >&6 +else + eval "$as_ac_Header=\$ac_header_preproc" +fi +echo "$as_me:$LINENO: result: `eval echo '${'$as_ac_Header'}'`" >&5 +echo "${ECHO_T}`eval echo '${'$as_ac_Header'}'`" >&6 + +fi +if test `eval echo '${'$as_ac_Header'}'` = yes; then + cat >>confdefs.h <<_ACEOF +#define `echo "HAVE_$ac_header" | $as_tr_cpp` 1 +_ACEOF + +fi + +done + + + +if test -n "$CXX" && ( test "X$CXX" != "Xno" && + ( (test "X$CXX" = "Xg++" && `g++ -v >/dev/null 2>&1` ) || + (test "X$CXX" != "Xg++"))) ; then + ac_ext=cc +ac_cpp='$CXXCPP $CPPFLAGS' +ac_compile='$CXX -c $CXXFLAGS $CPPFLAGS conftest.$ac_ext >&5' +ac_link='$CXX -o conftest$ac_exeext $CXXFLAGS $CPPFLAGS $LDFLAGS conftest.$ac_ext $LIBS >&5' +ac_compiler_gnu=$ac_cv_cxx_compiler_gnu +echo "$as_me:$LINENO: checking how to run the C++ preprocessor" >&5 +echo $ECHO_N "checking how to run the C++ preprocessor... $ECHO_C" >&6 +if test -z "$CXXCPP"; then + if test "${ac_cv_prog_CXXCPP+set}" = set; then + echo $ECHO_N "(cached) $ECHO_C" >&6 +else + # Double quotes because CXXCPP needs to be expanded + for CXXCPP in "$CXX -E" "/lib/cpp" + do + ac_preproc_ok=false +for ac_cxx_preproc_warn_flag in '' yes +do + # Use a header file that comes with gcc, so configuring glibc + # with a fresh cross-compiler works. + # Prefer <limits.h> to <assert.h> if __STDC__ is defined, since + # <limits.h> exists even on freestanding compilers. + # On the NeXT, cc -E runs the code through the compiler's parser, + # not just through cpp. "Syntax error" is here to catch this case. + cat >conftest.$ac_ext <<_ACEOF +/* confdefs.h. */ +_ACEOF +cat confdefs.h >>conftest.$ac_ext +cat >>conftest.$ac_ext <<_ACEOF +/* end confdefs.h. */ +#ifdef __STDC__ +# include <limits.h> +#else +# include <assert.h> +#endif + Syntax error +_ACEOF +if { (eval echo "$as_me:$LINENO: \"$ac_cpp conftest.$ac_ext\"") >&5 + (eval $ac_cpp conftest.$ac_ext) 2>conftest.er1 + ac_status=$? + grep -v '^ *+' conftest.er1 >conftest.err + rm -f conftest.er1 + cat conftest.err >&5 + echo "$as_me:$LINENO: \$? = $ac_status" >&5 + (exit $ac_status); } >/dev/null; then + if test -s conftest.err; then + ac_cpp_err=$ac_cxx_preproc_warn_flag + ac_cpp_err=$ac_cpp_err$ac_cxx_werror_flag + else + ac_cpp_err= + fi +else + ac_cpp_err=yes +fi +if test -z "$ac_cpp_err"; then + : +else + echo "$as_me: failed program was:" >&5 +sed 's/^/| /' conftest.$ac_ext >&5 + + # Broken: fails on valid input. +continue +fi +rm -f conftest.err conftest.$ac_ext + + # OK, works on sane cases. Now check whether non-existent headers + # can be detected and how. + cat >conftest.$ac_ext <<_ACEOF +/* confdefs.h. */ +_ACEOF +cat confdefs.h >>conftest.$ac_ext +cat >>conftest.$ac_ext <<_ACEOF +/* end confdefs.h. */ +#include <ac_nonexistent.h> +_ACEOF +if { (eval echo "$as_me:$LINENO: \"$ac_cpp conftest.$ac_ext\"") >&5 + (eval $ac_cpp conftest.$ac_ext) 2>conftest.er1 + ac_status=$? + grep -v '^ *+' conftest.er1 >conftest.err + rm -f conftest.er1 + cat conftest.err >&5 + echo "$as_me:$LINENO: \$? = $ac_status" >&5 + (exit $ac_status); } >/dev/null; then + if test -s conftest.err; then + ac_cpp_err=$ac_cxx_preproc_warn_flag + ac_cpp_err=$ac_cpp_err$ac_cxx_werror_flag + else + ac_cpp_err= + fi +else + ac_cpp_err=yes +fi +if test -z "$ac_cpp_err"; then + # Broken: success on invalid input. +continue +else + echo "$as_me: failed program was:" >&5 +sed 's/^/| /' conftest.$ac_ext >&5 + + # Passes both tests. +ac_preproc_ok=: +break +fi +rm -f conftest.err conftest.$ac_ext + +done +# Because of `break', _AC_PREPROC_IFELSE's cleaning code was skipped. +rm -f conftest.err conftest.$ac_ext +if $ac_preproc_ok; then + break +fi + + done + ac_cv_prog_CXXCPP=$CXXCPP + +fi + CXXCPP=$ac_cv_prog_CXXCPP +else + ac_cv_prog_CXXCPP=$CXXCPP +fi +echo "$as_me:$LINENO: result: $CXXCPP" >&5 +echo "${ECHO_T}$CXXCPP" >&6 +ac_preproc_ok=false +for ac_cxx_preproc_warn_flag in '' yes +do + # Use a header file that comes with gcc, so configuring glibc + # with a fresh cross-compiler works. + # Prefer <limits.h> to <assert.h> if __STDC__ is defined, since + # <limits.h> exists even on freestanding compilers. + # On the NeXT, cc -E runs the code through the compiler's parser, + # not just through cpp. "Syntax error" is here to catch this case. + cat >conftest.$ac_ext <<_ACEOF +/* confdefs.h. */ +_ACEOF +cat confdefs.h >>conftest.$ac_ext +cat >>conftest.$ac_ext <<_ACEOF +/* end confdefs.h. */ +#ifdef __STDC__ +# include <limits.h> +#else +# include <assert.h> +#endif + Syntax error +_ACEOF +if { (eval echo "$as_me:$LINENO: \"$ac_cpp conftest.$ac_ext\"") >&5 + (eval $ac_cpp conftest.$ac_ext) 2>conftest.er1 + ac_status=$? + grep -v '^ *+' conftest.er1 >conftest.err + rm -f conftest.er1 + cat conftest.err >&5 + echo "$as_me:$LINENO: \$? = $ac_status" >&5 + (exit $ac_status); } >/dev/null; then + if test -s conftest.err; then + ac_cpp_err=$ac_cxx_preproc_warn_flag + ac_cpp_err=$ac_cpp_err$ac_cxx_werror_flag + else + ac_cpp_err= + fi +else + ac_cpp_err=yes +fi +if test -z "$ac_cpp_err"; then + : +else + echo "$as_me: failed program was:" >&5 +sed 's/^/| /' conftest.$ac_ext >&5 + + # Broken: fails on valid input. +continue +fi +rm -f conftest.err conftest.$ac_ext + + # OK, works on sane cases. Now check whether non-existent headers + # can be detected and how. + cat >conftest.$ac_ext <<_ACEOF +/* confdefs.h. */ +_ACEOF +cat confdefs.h >>conftest.$ac_ext +cat >>conftest.$ac_ext <<_ACEOF +/* end confdefs.h. */ +#include <ac_nonexistent.h> +_ACEOF +if { (eval echo "$as_me:$LINENO: \"$ac_cpp conftest.$ac_ext\"") >&5 + (eval $ac_cpp conftest.$ac_ext) 2>conftest.er1 + ac_status=$? + grep -v '^ *+' conftest.er1 >conftest.err + rm -f conftest.er1 + cat conftest.err >&5 + echo "$as_me:$LINENO: \$? = $ac_status" >&5 + (exit $ac_status); } >/dev/null; then + if test -s conftest.err; then + ac_cpp_err=$ac_cxx_preproc_warn_flag + ac_cpp_err=$ac_cpp_err$ac_cxx_werror_flag + else + ac_cpp_err= + fi +else + ac_cpp_err=yes +fi +if test -z "$ac_cpp_err"; then + # Broken: success on invalid input. +continue +else + echo "$as_me: failed program was:" >&5 +sed 's/^/| /' conftest.$ac_ext >&5 + + # Passes both tests. +ac_preproc_ok=: +break +fi +rm -f conftest.err conftest.$ac_ext + +done +# Because of `break', _AC_PREPROC_IFELSE's cleaning code was skipped. +rm -f conftest.err conftest.$ac_ext +if $ac_preproc_ok; then + : +else + { { echo "$as_me:$LINENO: error: C++ preprocessor \"$CXXCPP\" fails sanity check +See \`config.log' for more details." >&5 +echo "$as_me: error: C++ preprocessor \"$CXXCPP\" fails sanity check +See \`config.log' for more details." >&2;} + { (exit 1); exit 1; }; } +fi + +ac_ext=cc +ac_cpp='$CXXCPP $CPPFLAGS' +ac_compile='$CXX -c $CXXFLAGS $CPPFLAGS conftest.$ac_ext >&5' +ac_link='$CXX -o conftest$ac_exeext $CXXFLAGS $CPPFLAGS $LDFLAGS conftest.$ac_ext $LIBS >&5' +ac_compiler_gnu=$ac_cv_cxx_compiler_gnu + +fi + + +ac_ext=f +ac_compile='$F77 -c $FFLAGS conftest.$ac_ext >&5' +ac_link='$F77 -o conftest$ac_exeext $FFLAGS $LDFLAGS conftest.$ac_ext $LIBS >&5' +ac_compiler_gnu=$ac_cv_f77_compiler_gnu +if test -n "$ac_tool_prefix"; then + for ac_prog in g77 f77 xlf frt pgf77 fort77 fl32 af77 f90 xlf90 pgf90 epcf90 f95 fort xlf95 ifc efc pgf95 lf95 gfortran + do + # Extract the first word of "$ac_tool_prefix$ac_prog", so it can be a program name with args. +set dummy $ac_tool_prefix$ac_prog; ac_word=$2 +echo "$as_me:$LINENO: checking for $ac_word" >&5 +echo $ECHO_N "checking for $ac_word... $ECHO_C" >&6 +if test "${ac_cv_prog_F77+set}" = set; then + echo $ECHO_N "(cached) $ECHO_C" >&6 +else + if test -n "$F77"; then + ac_cv_prog_F77="$F77" # Let the user override the test. +else +as_save_IFS=$IFS; IFS=$PATH_SEPARATOR +for as_dir in $PATH +do + IFS=$as_save_IFS + test -z "$as_dir" && as_dir=. + for ac_exec_ext in '' $ac_executable_extensions; do + if $as_executable_p "$as_dir/$ac_word$ac_exec_ext"; then + ac_cv_prog_F77="$ac_tool_prefix$ac_prog" + echo "$as_me:$LINENO: found $as_dir/$ac_word$ac_exec_ext" >&5 + break 2 + fi +done +done + +fi +fi +F77=$ac_cv_prog_F77 +if test -n "$F77"; then + echo "$as_me:$LINENO: result: $F77" >&5 +echo "${ECHO_T}$F77" >&6 +else + echo "$as_me:$LINENO: result: no" >&5 +echo "${ECHO_T}no" >&6 +fi + + test -n "$F77" && break + done +fi +if test -z "$F77"; then + ac_ct_F77=$F77 + for ac_prog in g77 f77 xlf frt pgf77 fort77 fl32 af77 f90 xlf90 pgf90 epcf90 f95 fort xlf95 ifc efc pgf95 lf95 gfortran +do + # Extract the first word of "$ac_prog", so it can be a program name with args. +set dummy $ac_prog; ac_word=$2 +echo "$as_me:$LINENO: checking for $ac_word" >&5 +echo $ECHO_N "checking for $ac_word... $ECHO_C" >&6 +if test "${ac_cv_prog_ac_ct_F77+set}" = set; then + echo $ECHO_N "(cached) $ECHO_C" >&6 +else + if test -n "$ac_ct_F77"; then + ac_cv_prog_ac_ct_F77="$ac_ct_F77" # Let the user override the test. +else +as_save_IFS=$IFS; IFS=$PATH_SEPARATOR +for as_dir in $PATH +do + IFS=$as_save_IFS + test -z "$as_dir" && as_dir=. + for ac_exec_ext in '' $ac_executable_extensions; do + if $as_executable_p "$as_dir/$ac_word$ac_exec_ext"; then + ac_cv_prog_ac_ct_F77="$ac_prog" + echo "$as_me:$LINENO: found $as_dir/$ac_word$ac_exec_ext" >&5 + break 2 + fi +done +done + +fi +fi +ac_ct_F77=$ac_cv_prog_ac_ct_F77 +if test -n "$ac_ct_F77"; then + echo "$as_me:$LINENO: result: $ac_ct_F77" >&5 +echo "${ECHO_T}$ac_ct_F77" >&6 +else + echo "$as_me:$LINENO: result: no" >&5 +echo "${ECHO_T}no" >&6 +fi + + test -n "$ac_ct_F77" && break +done + + F77=$ac_ct_F77 +fi + + +# Provide some information about the compiler. +echo "$as_me:5450:" \ + "checking for Fortran 77 compiler version" >&5 +ac_compiler=`set X $ac_compile; echo $2` +{ (eval echo "$as_me:$LINENO: \"$ac_compiler --version </dev/null >&5\"") >&5 + (eval $ac_compiler --version </dev/null >&5) 2>&5 + ac_status=$? + echo "$as_me:$LINENO: \$? = $ac_status" >&5 + (exit $ac_status); } +{ (eval echo "$as_me:$LINENO: \"$ac_compiler -v </dev/null >&5\"") >&5 + (eval $ac_compiler -v </dev/null >&5) 2>&5 + ac_status=$? + echo "$as_me:$LINENO: \$? = $ac_status" >&5 + (exit $ac_status); } +{ (eval echo "$as_me:$LINENO: \"$ac_compiler -V </dev/null >&5\"") >&5 + (eval $ac_compiler -V </dev/null >&5) 2>&5 + ac_status=$? + echo "$as_me:$LINENO: \$? = $ac_status" >&5 + (exit $ac_status); } +rm -f a.out + +# If we don't use `.F' as extension, the preprocessor is not run on the +# input file. (Note that this only needs to work for GNU compilers.) +ac_save_ext=$ac_ext +ac_ext=F +echo "$as_me:$LINENO: checking whether we are using the GNU Fortran 77 compiler" >&5 +echo $ECHO_N "checking whether we are using the GNU Fortran 77 compiler... $ECHO_C" >&6 +if test "${ac_cv_f77_compiler_gnu+set}" = set; then + echo $ECHO_N "(cached) $ECHO_C" >&6 +else + cat >conftest.$ac_ext <<_ACEOF + program main +#ifndef __GNUC__ + choke me +#endif + + end +_ACEOF +rm -f conftest.$ac_objext +if { (eval echo "$as_me:$LINENO: \"$ac_compile\"") >&5 + (eval $ac_compile) 2>conftest.er1 + ac_status=$? + grep -v '^ *+' conftest.er1 >conftest.err + rm -f conftest.er1 + cat conftest.err >&5 + echo "$as_me:$LINENO: \$? = $ac_status" >&5 + (exit $ac_status); } && + { ac_try='test -z "$ac_f77_werror_flag" + || test ! -s conftest.err' + { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5 + (eval $ac_try) 2>&5 + ac_status=$? + echo "$as_me:$LINENO: \$? = $ac_status" >&5 + (exit $ac_status); }; } && + { ac_try='test -s conftest.$ac_objext' + { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5 + (eval $ac_try) 2>&5 + ac_status=$? + echo "$as_me:$LINENO: \$? = $ac_status" >&5 + (exit $ac_status); }; }; then + ac_compiler_gnu=yes +else + echo "$as_me: failed program was:" >&5 +sed 's/^/| /' conftest.$ac_ext >&5 + +ac_compiler_gnu=no +fi +rm -f conftest.err conftest.$ac_objext conftest.$ac_ext +ac_cv_f77_compiler_gnu=$ac_compiler_gnu + +fi +echo "$as_me:$LINENO: result: $ac_cv_f77_compiler_gnu" >&5 +echo "${ECHO_T}$ac_cv_f77_compiler_gnu" >&6 +ac_ext=$ac_save_ext +ac_test_FFLAGS=${FFLAGS+set} +ac_save_FFLAGS=$FFLAGS +FFLAGS= +echo "$as_me:$LINENO: checking whether $F77 accepts -g" >&5 +echo $ECHO_N "checking whether $F77 accepts -g... $ECHO_C" >&6 +if test "${ac_cv_prog_f77_g+set}" = set; then + echo $ECHO_N "(cached) $ECHO_C" >&6 +else + FFLAGS=-g +cat >conftest.$ac_ext <<_ACEOF + program main + + end +_ACEOF +rm -f conftest.$ac_objext +if { (eval echo "$as_me:$LINENO: \"$ac_compile\"") >&5 + (eval $ac_compile) 2>conftest.er1 + ac_status=$? + grep -v '^ *+' conftest.er1 >conftest.err + rm -f conftest.er1 + cat conftest.err >&5 + echo "$as_me:$LINENO: \$? = $ac_status" >&5 + (exit $ac_status); } && + { ac_try='test -z "$ac_f77_werror_flag" + || test ! -s conftest.err' + { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5 + (eval $ac_try) 2>&5 + ac_status=$? + echo "$as_me:$LINENO: \$? = $ac_status" >&5 + (exit $ac_status); }; } && + { ac_try='test -s conftest.$ac_objext' + { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5 + (eval $ac_try) 2>&5 + ac_status=$? + echo "$as_me:$LINENO: \$? = $ac_status" >&5 + (exit $ac_status); }; }; then + ac_cv_prog_f77_g=yes +else + echo "$as_me: failed program was:" >&5 +sed 's/^/| /' conftest.$ac_ext >&5 + +ac_cv_prog_f77_g=no +fi +rm -f conftest.err conftest.$ac_objext conftest.$ac_ext + +fi +echo "$as_me:$LINENO: result: $ac_cv_prog_f77_g" >&5 +echo "${ECHO_T}$ac_cv_prog_f77_g" >&6 +if test "$ac_test_FFLAGS" = set; then + FFLAGS=$ac_save_FFLAGS +elif test $ac_cv_prog_f77_g = yes; then + if test "x$ac_cv_f77_compiler_gnu" = xyes; then + FFLAGS="-g -O2" + else + FFLAGS="-g" + fi +else + if test "x$ac_cv_f77_compiler_gnu" = xyes; then + FFLAGS="-O2" + else + FFLAGS= + fi +fi + +G77=`test $ac_compiler_gnu = yes && echo yes` +ac_ext=c +ac_cpp='$CPP $CPPFLAGS' +ac_compile='$CC -c $CFLAGS $CPPFLAGS conftest.$ac_ext >&5' +ac_link='$CC -o conftest$ac_exeext $CFLAGS $CPPFLAGS $LDFLAGS conftest.$ac_ext $LIBS >&5' +ac_compiler_gnu=$ac_cv_c_compiler_gnu + + + +# Autoconf 2.13's AC_OBJEXT and AC_EXEEXT macros only works for C compilers! + +# find the maximum length of command line arguments +echo "$as_me:$LINENO: checking the maximum length of command line arguments" >&5 +echo $ECHO_N "checking the maximum length of command line arguments... $ECHO_C" >&6 +if test "${lt_cv_sys_max_cmd_len+set}" = set; then + echo $ECHO_N "(cached) $ECHO_C" >&6 +else + i=0 + teststring="ABCD" + + case $build_os in + msdosdjgpp*) + # On DJGPP, this test can blow up pretty badly due to problems in libc + # (any single argument exceeding 2000 bytes causes a buffer overrun + # during glob expansion). Even if it were fixed, the result of this + # check would be larger than it should be. + lt_cv_sys_max_cmd_len=12288; # 12K is about right + ;; + + gnu*) + # Under GNU Hurd, this test is not required because there is + # no limit to the length of command line arguments. + # Libtool will interpret -1 as no limit whatsoever + lt_cv_sys_max_cmd_len=-1; + ;; + + cygwin* | mingw*) + # On Win9x/ME, this test blows up -- it succeeds, but takes + # about 5 minutes as the teststring grows exponentially. + # Worse, since 9x/ME are not pre-emptively multitasking, + # you end up with a "frozen" computer, even though with patience + # the test eventually succeeds (with a max line length of 256k). + # Instead, let's just punt: use the minimum linelength reported by + # all of the supported platforms: 8192 (on NT/2K/XP). + lt_cv_sys_max_cmd_len=8192; + ;; + + amigaos*) + # On AmigaOS with pdksh, this test takes hours, literally. + # So we just punt and use a minimum line length of 8192. + lt_cv_sys_max_cmd_len=8192; + ;; + + netbsd* | freebsd* | openbsd* | darwin* | dragonfly*) + # This has been around since 386BSD, at least. Likely further. + if test -x /sbin/sysctl; then + lt_cv_sys_max_cmd_len=`/sbin/sysctl -n kern.argmax` + elif test -x /usr/sbin/sysctl; then + lt_cv_sys_max_cmd_len=`/usr/sbin/sysctl -n kern.argmax` + else + lt_cv_sys_max_cmd_len=65536 # usable default for all BSDs + fi + # And add a safety zone + lt_cv_sys_max_cmd_len=`expr $lt_cv_sys_max_cmd_len \/ 4` + lt_cv_sys_max_cmd_len=`expr $lt_cv_sys_max_cmd_len \* 3` + ;; + + interix*) + # We know the value 262144 and hardcode it with a safety zone (like BSD) + lt_cv_sys_max_cmd_len=196608 + ;; + + osf*) + # Dr. Hans Ekkehard Plesser reports seeing a kernel panic running configure + # due to this test when exec_disable_arg_limit is 1 on Tru64. It is not + # nice to cause kernel panics so lets avoid the loop below. + # First set a reasonable default. + lt_cv_sys_max_cmd_len=16384 + # + if test -x /sbin/sysconfig; then + case `/sbin/sysconfig -q proc exec_disable_arg_limit` in + *1*) lt_cv_sys_max_cmd_len=-1 ;; + esac + fi + ;; + sco3.2v5*) + lt_cv_sys_max_cmd_len=102400 + ;; + sysv5* | sco5v6* | sysv4.2uw2*) + kargmax=`grep ARG_MAX /etc/conf/cf.d/stune 2>/dev/null` + if test -n "$kargmax"; then + lt_cv_sys_max_cmd_len=`echo $kargmax | sed 's/.*[ ]//'` + else + lt_cv_sys_max_cmd_len=32768 + fi + ;; + *) + # If test is not a shell built-in, we'll probably end up computing a + # maximum length that is only half of the actual maximum length, but + # we can't tell. + SHELL=${SHELL-${CONFIG_SHELL-/bin/sh}} + while (test "X"`$SHELL $0 --fallback-echo "X$teststring" 2>/dev/null` \ + = "XX$teststring") >/dev/null 2>&1 && + new_result=`expr "X$teststring" : ".*" 2>&1` && + lt_cv_sys_max_cmd_len=$new_result && + test $i != 17 # 1/2 MB should be enough + do + i=`expr $i + 1` + teststring=$teststring$teststring + done + teststring= + # Add a significant safety factor because C++ compilers can tack on massive + # amounts of additional arguments before passing them to the linker. + # It appears as though 1/2 is a usable value. + lt_cv_sys_max_cmd_len=`expr $lt_cv_sys_max_cmd_len \/ 2` + ;; + esac + +fi + +if test -n $lt_cv_sys_max_cmd_len ; then + echo "$as_me:$LINENO: result: $lt_cv_sys_max_cmd_len" >&5 +echo "${ECHO_T}$lt_cv_sys_max_cmd_len" >&6 +else + echo "$as_me:$LINENO: result: none" >&5 +echo "${ECHO_T}none" >&6 +fi + + + + +# Check for command to grab the raw symbol name followed by C symbol from nm. +echo "$as_me:$LINENO: checking command to parse $NM output from $compiler object" >&5 +echo $ECHO_N "checking command to parse $NM output from $compiler object... $ECHO_C" >&6 +if test "${lt_cv_sys_global_symbol_pipe+set}" = set; then + echo $ECHO_N "(cached) $ECHO_C" >&6 +else + +# These are sane defaults that work on at least a few old systems. +# [They come from Ultrix. What could be older than Ultrix?!! ;)] + +# Character class describing NM global symbol codes. +symcode='[BCDEGRST]' + +# Regexp to match symbols that can be accessed directly from C. +sympat='\([_A-Za-z][_A-Za-z0-9]*\)' + +# Transform an extracted symbol line into a proper C declaration +lt_cv_sys_global_symbol_to_cdecl="sed -n -e 's/^. .* \(.*\)$/extern int \1;/p'" + +# Transform an extracted symbol line into symbol name and symbol address +lt_cv_sys_global_symbol_to_c_name_address="sed -n -e 's/^: \([^ ]*\) $/ {\\\"\1\\\", (lt_ptr) 0},/p' -e 's/^$symcode \([^ ]*\) \([^ ]*\)$/ {\"\2\", (lt_ptr) \&\2},/p'" + +# Define system-specific variables. +case $host_os in +aix*) + symcode='[BCDT]' + ;; +cygwin* | mingw* | pw32*) + symcode='[ABCDGISTW]' + ;; +hpux*) # Its linker distinguishes data from code symbols + if test "$host_cpu" = ia64; then + symcode='[ABCDEGRST]' + fi + lt_cv_sys_global_symbol_to_cdecl="sed -n -e 's/^T .* \(.*\)$/extern int \1();/p' -e 's/^$symcode* .* \(.*\)$/extern char \1;/p'" + lt_cv_sys_global_symbol_to_c_name_address="sed -n -e 's/^: \([^ ]*\) $/ {\\\"\1\\\", (lt_ptr) 0},/p' -e 's/^$symcode* \([^ ]*\) \([^ ]*\)$/ {\"\2\", (lt_ptr) \&\2},/p'" + ;; +linux*) + if test "$host_cpu" = ia64; then + symcode='[ABCDGIRSTW]' + lt_cv_sys_global_symbol_to_cdecl="sed -n -e 's/^T .* \(.*\)$/extern int \1();/p' -e 's/^$symcode* .* \(.*\)$/extern char \1;/p'" + lt_cv_sys_global_symbol_to_c_name_address="sed -n -e 's/^: \([^ ]*\) $/ {\\\"\1\\\", (lt_ptr) 0},/p' -e 's/^$symcode* \([^ ]*\) \([^ ]*\)$/ {\"\2\", (lt_ptr) \&\2},/p'" + fi + ;; +irix* | nonstopux*) + symcode='[BCDEGRST]' + ;; +osf*) + symcode='[BCDEGQRST]' + ;; +solaris*) + symcode='[BDRT]' + ;; +sco3.2v5*) + symcode='[DT]' + ;; +sysv4.2uw2*) + symcode='[DT]' + ;; +sysv5* | sco5v6* | unixware* | OpenUNIX*) + symcode='[ABDT]' + ;; +sysv4) + symcode='[DFNSTU]' + ;; +esac + +# Handle CRLF in mingw tool chain +opt_cr= +case $build_os in +mingw*) + opt_cr=`echo 'x\{0,1\}' | tr x '\015'` # option cr in regexp + ;; +esac + +# If we're using GNU nm, then use its standard symbol codes. +case `$NM -V 2>&1` in +*GNU* | *'with BFD'*) + symcode='[ABCDGIRSTW]' ;; +esac + +# Try without a prefix undercore, then with it. +for ac_symprfx in "" "_"; do + + # Transform symcode, sympat, and symprfx into a raw symbol and a C symbol. + symxfrm="\\1 $ac_symprfx\\2 \\2" + + # Write the raw and C identifiers. + lt_cv_sys_global_symbol_pipe="sed -n -e 's/^.*[ ]\($symcode$symcode*\)[ ][ ]*$ac_symprfx$sympat$opt_cr$/$symxfrm/p'" + + # Check to see that the pipe works correctly. + pipe_works=no + + rm -f conftest* + cat > conftest.$ac_ext <<EOF +#ifdef __cplusplus +extern "C" { +#endif +char nm_test_var; +void nm_test_func(){} +#ifdef __cplusplus +} +#endif +int main(){nm_test_var='a';nm_test_func();return(0);} +EOF + + if { (eval echo "$as_me:$LINENO: \"$ac_compile\"") >&5 + (eval $ac_compile) 2>&5 + ac_status=$? + echo "$as_me:$LINENO: \$? = $ac_status" >&5 + (exit $ac_status); }; then + # Now try to grab the symbols. + nlist=conftest.nm + if { (eval echo "$as_me:$LINENO: \"$NM conftest.$ac_objext \| $lt_cv_sys_global_symbol_pipe \> $nlist\"") >&5 + (eval $NM conftest.$ac_objext \| $lt_cv_sys_global_symbol_pipe \> $nlist) 2>&5 + ac_status=$? + echo "$as_me:$LINENO: \$? = $ac_status" >&5 + (exit $ac_status); } && test -s "$nlist"; then + # Try sorting and uniquifying the output. + if sort "$nlist" | uniq > "$nlist"T; then + mv -f "$nlist"T "$nlist" + else + rm -f "$nlist"T + fi + + # Make sure that we snagged all the symbols we need. + if grep ' nm_test_var$' "$nlist" >/dev/null; then + if grep ' nm_test_func$' "$nlist" >/dev/null; then + cat <<EOF > conftest.$ac_ext +#ifdef __cplusplus +extern "C" { +#endif + +EOF + # Now generate the symbol file. + eval "$lt_cv_sys_global_symbol_to_cdecl"' < "$nlist" | grep -v main >> conftest.$ac_ext' + + cat <<EOF >> conftest.$ac_ext +#if defined (__STDC__) && __STDC__ +# define lt_ptr_t void * +#else +# define lt_ptr_t char * +# define const +#endif + +/* The mapping between symbol names and symbols. */ +const struct { + const char *name; + lt_ptr_t address; +} +lt_preloaded_symbols[] = +{ +EOF + $SED "s/^$symcode$symcode* \(.*\) \(.*\)$/ {\"\2\", (lt_ptr_t) \&\2},/" < "$nlist" | grep -v main >> conftest.$ac_ext + cat <<\EOF >> conftest.$ac_ext + {0, (lt_ptr_t) 0} +}; + +#ifdef __cplusplus +} +#endif +EOF + # Now try linking the two files. + mv conftest.$ac_objext conftstm.$ac_objext + lt_save_LIBS="$LIBS" + lt_save_CFLAGS="$CFLAGS" + LIBS="conftstm.$ac_objext" + CFLAGS="$CFLAGS$lt_prog_compiler_no_builtin_flag" + if { (eval echo "$as_me:$LINENO: \"$ac_link\"") >&5 + (eval $ac_link) 2>&5 + ac_status=$? + echo "$as_me:$LINENO: \$? = $ac_status" >&5 + (exit $ac_status); } && test -s conftest${ac_exeext}; then + pipe_works=yes + fi + LIBS="$lt_save_LIBS" + CFLAGS="$lt_save_CFLAGS" + else + echo "cannot find nm_test_func in $nlist" >&5 + fi + else + echo "cannot find nm_test_var in $nlist" >&5 + fi + else + echo "cannot run $lt_cv_sys_global_symbol_pipe" >&5 + fi + else + echo "$progname: failed program was:" >&5 + cat conftest.$ac_ext >&5 + fi + rm -f conftest* conftst* + + # Do not use the global_symbol_pipe unless it works. + if test "$pipe_works" = yes; then + break + else + lt_cv_sys_global_symbol_pipe= + fi +done + +fi + +if test -z "$lt_cv_sys_global_symbol_pipe"; then + lt_cv_sys_global_symbol_to_cdecl= +fi +if test -z "$lt_cv_sys_global_symbol_pipe$lt_cv_sys_global_symbol_to_cdecl"; then + echo "$as_me:$LINENO: result: failed" >&5 +echo "${ECHO_T}failed" >&6 +else + echo "$as_me:$LINENO: result: ok" >&5 +echo "${ECHO_T}ok" >&6 +fi + +echo "$as_me:$LINENO: checking for objdir" >&5 +echo $ECHO_N "checking for objdir... $ECHO_C" >&6 +if test "${lt_cv_objdir+set}" = set; then + echo $ECHO_N "(cached) $ECHO_C" >&6 +else + rm -f .libs 2>/dev/null +mkdir .libs 2>/dev/null +if test -d .libs; then + lt_cv_objdir=.libs +else + # MS-DOS does not allow filenames that begin with a dot. + lt_cv_objdir=_libs +fi +rmdir .libs 2>/dev/null +fi +echo "$as_me:$LINENO: result: $lt_cv_objdir" >&5 +echo "${ECHO_T}$lt_cv_objdir" >&6 +objdir=$lt_cv_objdir + + + + + +case $host_os in +aix3*) + # AIX sometimes has problems with the GCC collect2 program. For some + # reason, if we set the COLLECT_NAMES environment variable, the problems + # vanish in a puff of smoke. + if test "X${COLLECT_NAMES+set}" != Xset; then + COLLECT_NAMES= + export COLLECT_NAMES + fi + ;; +esac + +# Sed substitution that helps us do robust quoting. It backslashifies +# metacharacters that are still active within double-quoted strings. +Xsed='sed -e 1s/^X//' +sed_quote_subst='s/\([\\"\\`$\\\\]\)/\\\1/g' + +# Same as above, but do not quote variable references. +double_quote_subst='s/\([\\"\\`\\\\]\)/\\\1/g' + +# Sed substitution to delay expansion of an escaped shell variable in a +# double_quote_subst'ed string. +delay_variable_subst='s/\\\\\\\\\\\$/\\\\\\$/g' + +# Sed substitution to avoid accidental globbing in evaled expressions +no_glob_subst='s/\*/\\\*/g' + +# Constants: +rm="rm -f" + +# Global variables: +default_ofile=libtool +can_build_shared=yes + +# All known linkers require a `.a' archive for static linking (except MSVC, +# which needs '.lib'). +libext=a +ltmain="$ac_aux_dir/ltmain.sh" +ofile="$default_ofile" +with_gnu_ld="$lt_cv_prog_gnu_ld" + +if test -n "$ac_tool_prefix"; then + # Extract the first word of "${ac_tool_prefix}ar", so it can be a program name with args. +set dummy ${ac_tool_prefix}ar; ac_word=$2 +echo "$as_me:$LINENO: checking for $ac_word" >&5 +echo $ECHO_N "checking for $ac_word... $ECHO_C" >&6 +if test "${ac_cv_prog_AR+set}" = set; then + echo $ECHO_N "(cached) $ECHO_C" >&6 +else + if test -n "$AR"; then + ac_cv_prog_AR="$AR" # Let the user override the test. +else +as_save_IFS=$IFS; IFS=$PATH_SEPARATOR +for as_dir in $PATH +do + IFS=$as_save_IFS + test -z "$as_dir" && as_dir=. + for ac_exec_ext in '' $ac_executable_extensions; do + if $as_executable_p "$as_dir/$ac_word$ac_exec_ext"; then + ac_cv_prog_AR="${ac_tool_prefix}ar" + echo "$as_me:$LINENO: found $as_dir/$ac_word$ac_exec_ext" >&5 + break 2 + fi +done +done + +fi +fi +AR=$ac_cv_prog_AR +if test -n "$AR"; then + echo "$as_me:$LINENO: result: $AR" >&5 +echo "${ECHO_T}$AR" >&6 +else + echo "$as_me:$LINENO: result: no" >&5 +echo "${ECHO_T}no" >&6 +fi + +fi +if test -z "$ac_cv_prog_AR"; then + ac_ct_AR=$AR + # Extract the first word of "ar", so it can be a program name with args. +set dummy ar; ac_word=$2 +echo "$as_me:$LINENO: checking for $ac_word" >&5 +echo $ECHO_N "checking for $ac_word... $ECHO_C" >&6 +if test "${ac_cv_prog_ac_ct_AR+set}" = set; then + echo $ECHO_N "(cached) $ECHO_C" >&6 +else + if test -n "$ac_ct_AR"; then + ac_cv_prog_ac_ct_AR="$ac_ct_AR" # Let the user override the test. +else +as_save_IFS=$IFS; IFS=$PATH_SEPARATOR +for as_dir in $PATH +do + IFS=$as_save_IFS + test -z "$as_dir" && as_dir=. + for ac_exec_ext in '' $ac_executable_extensions; do + if $as_executable_p "$as_dir/$ac_word$ac_exec_ext"; then + ac_cv_prog_ac_ct_AR="ar" + echo "$as_me:$LINENO: found $as_dir/$ac_word$ac_exec_ext" >&5 + break 2 + fi +done +done + + test -z "$ac_cv_prog_ac_ct_AR" && ac_cv_prog_ac_ct_AR="false" +fi +fi +ac_ct_AR=$ac_cv_prog_ac_ct_AR +if test -n "$ac_ct_AR"; then + echo "$as_me:$LINENO: result: $ac_ct_AR" >&5 +echo "${ECHO_T}$ac_ct_AR" >&6 +else + echo "$as_me:$LINENO: result: no" >&5 +echo "${ECHO_T}no" >&6 +fi + + AR=$ac_ct_AR +else + AR="$ac_cv_prog_AR" +fi + +if test -n "$ac_tool_prefix"; then + # Extract the first word of "${ac_tool_prefix}ranlib", so it can be a program name with args. +set dummy ${ac_tool_prefix}ranlib; ac_word=$2 +echo "$as_me:$LINENO: checking for $ac_word" >&5 +echo $ECHO_N "checking for $ac_word... $ECHO_C" >&6 +if test "${ac_cv_prog_RANLIB+set}" = set; then + echo $ECHO_N "(cached) $ECHO_C" >&6 +else + if test -n "$RANLIB"; then + ac_cv_prog_RANLIB="$RANLIB" # Let the user override the test. +else +as_save_IFS=$IFS; IFS=$PATH_SEPARATOR +for as_dir in $PATH +do + IFS=$as_save_IFS + test -z "$as_dir" && as_dir=. + for ac_exec_ext in '' $ac_executable_extensions; do + if $as_executable_p "$as_dir/$ac_word$ac_exec_ext"; then + ac_cv_prog_RANLIB="${ac_tool_prefix}ranlib" + echo "$as_me:$LINENO: found $as_dir/$ac_word$ac_exec_ext" >&5 + break 2 + fi +done +done + +fi +fi +RANLIB=$ac_cv_prog_RANLIB +if test -n "$RANLIB"; then + echo "$as_me:$LINENO: result: $RANLIB" >&5 +echo "${ECHO_T}$RANLIB" >&6 +else + echo "$as_me:$LINENO: result: no" >&5 +echo "${ECHO_T}no" >&6 +fi + +fi +if test -z "$ac_cv_prog_RANLIB"; then + ac_ct_RANLIB=$RANLIB + # Extract the first word of "ranlib", so it can be a program name with args. +set dummy ranlib; ac_word=$2 +echo "$as_me:$LINENO: checking for $ac_word" >&5 +echo $ECHO_N "checking for $ac_word... $ECHO_C" >&6 +if test "${ac_cv_prog_ac_ct_RANLIB+set}" = set; then + echo $ECHO_N "(cached) $ECHO_C" >&6 +else + if test -n "$ac_ct_RANLIB"; then + ac_cv_prog_ac_ct_RANLIB="$ac_ct_RANLIB" # Let the user override the test. +else +as_save_IFS=$IFS; IFS=$PATH_SEPARATOR +for as_dir in $PATH +do + IFS=$as_save_IFS + test -z "$as_dir" && as_dir=. + for ac_exec_ext in '' $ac_executable_extensions; do + if $as_executable_p "$as_dir/$ac_word$ac_exec_ext"; then + ac_cv_prog_ac_ct_RANLIB="ranlib" + echo "$as_me:$LINENO: found $as_dir/$ac_word$ac_exec_ext" >&5 + break 2 + fi +done +done + + test -z "$ac_cv_prog_ac_ct_RANLIB" && ac_cv_prog_ac_ct_RANLIB=":" +fi +fi +ac_ct_RANLIB=$ac_cv_prog_ac_ct_RANLIB +if test -n "$ac_ct_RANLIB"; then + echo "$as_me:$LINENO: result: $ac_ct_RANLIB" >&5 +echo "${ECHO_T}$ac_ct_RANLIB" >&6 +else + echo "$as_me:$LINENO: result: no" >&5 +echo "${ECHO_T}no" >&6 +fi + + RANLIB=$ac_ct_RANLIB +else + RANLIB="$ac_cv_prog_RANLIB" +fi + +if test -n "$ac_tool_prefix"; then + # Extract the first word of "${ac_tool_prefix}strip", so it can be a program name with args. +set dummy ${ac_tool_prefix}strip; ac_word=$2 +echo "$as_me:$LINENO: checking for $ac_word" >&5 +echo $ECHO_N "checking for $ac_word... $ECHO_C" >&6 +if test "${ac_cv_prog_STRIP+set}" = set; then + echo $ECHO_N "(cached) $ECHO_C" >&6 +else + if test -n "$STRIP"; then + ac_cv_prog_STRIP="$STRIP" # Let the user override the test. +else +as_save_IFS=$IFS; IFS=$PATH_SEPARATOR +for as_dir in $PATH +do + IFS=$as_save_IFS + test -z "$as_dir" && as_dir=. + for ac_exec_ext in '' $ac_executable_extensions; do + if $as_executable_p "$as_dir/$ac_word$ac_exec_ext"; then + ac_cv_prog_STRIP="${ac_tool_prefix}strip" + echo "$as_me:$LINENO: found $as_dir/$ac_word$ac_exec_ext" >&5 + break 2 + fi +done +done + +fi +fi +STRIP=$ac_cv_prog_STRIP +if test -n "$STRIP"; then + echo "$as_me:$LINENO: result: $STRIP" >&5 +echo "${ECHO_T}$STRIP" >&6 +else + echo "$as_me:$LINENO: result: no" >&5 +echo "${ECHO_T}no" >&6 +fi + +fi +if test -z "$ac_cv_prog_STRIP"; then + ac_ct_STRIP=$STRIP + # Extract the first word of "strip", so it can be a program name with args. +set dummy strip; ac_word=$2 +echo "$as_me:$LINENO: checking for $ac_word" >&5 +echo $ECHO_N "checking for $ac_word... $ECHO_C" >&6 +if test "${ac_cv_prog_ac_ct_STRIP+set}" = set; then + echo $ECHO_N "(cached) $ECHO_C" >&6 +else + if test -n "$ac_ct_STRIP"; then + ac_cv_prog_ac_ct_STRIP="$ac_ct_STRIP" # Let the user override the test. +else +as_save_IFS=$IFS; IFS=$PATH_SEPARATOR +for as_dir in $PATH +do + IFS=$as_save_IFS + test -z "$as_dir" && as_dir=. + for ac_exec_ext in '' $ac_executable_extensions; do + if $as_executable_p "$as_dir/$ac_word$ac_exec_ext"; then + ac_cv_prog_ac_ct_STRIP="strip" + echo "$as_me:$LINENO: found $as_dir/$ac_word$ac_exec_ext" >&5 + break 2 + fi +done +done + + test -z "$ac_cv_prog_ac_ct_STRIP" && ac_cv_prog_ac_ct_STRIP=":" +fi +fi +ac_ct_STRIP=$ac_cv_prog_ac_ct_STRIP +if test -n "$ac_ct_STRIP"; then + echo "$as_me:$LINENO: result: $ac_ct_STRIP" >&5 +echo "${ECHO_T}$ac_ct_STRIP" >&6 +else + echo "$as_me:$LINENO: result: no" >&5 +echo "${ECHO_T}no" >&6 +fi + + STRIP=$ac_ct_STRIP +else + STRIP="$ac_cv_prog_STRIP" +fi + + +old_CC="$CC" +old_CFLAGS="$CFLAGS" + +# Set sane defaults for various variables +test -z "$AR" && AR=ar +test -z "$AR_FLAGS" && AR_FLAGS=cru +test -z "$AS" && AS=as +test -z "$CC" && CC=cc +test -z "$LTCC" && LTCC=$CC +test -z "$LTCFLAGS" && LTCFLAGS=$CFLAGS +test -z "$DLLTOOL" && DLLTOOL=dlltool +test -z "$LD" && LD=ld +test -z "$LN_S" && LN_S="ln -s" +test -z "$MAGIC_CMD" && MAGIC_CMD=file +test -z "$NM" && NM=nm +test -z "$SED" && SED=sed +test -z "$OBJDUMP" && OBJDUMP=objdump +test -z "$RANLIB" && RANLIB=: +test -z "$STRIP" && STRIP=: +test -z "$ac_objext" && ac_objext=o + +# Determine commands to create old-style static archives. +old_archive_cmds='$AR $AR_FLAGS $oldlib$oldobjs$old_deplibs' +old_postinstall_cmds='chmod 644 $oldlib' +old_postuninstall_cmds= + +if test -n "$RANLIB"; then + case $host_os in + openbsd*) + old_postinstall_cmds="$old_postinstall_cmds~\$RANLIB -t \$oldlib" + ;; + *) + old_postinstall_cmds="$old_postinstall_cmds~\$RANLIB \$oldlib" + ;; + esac + old_archive_cmds="$old_archive_cmds~\$RANLIB \$oldlib" +fi + +for cc_temp in $compiler""; do + case $cc_temp in + compile | *[\\/]compile | ccache | *[\\/]ccache ) ;; + distcc | *[\\/]distcc | purify | *[\\/]purify ) ;; + \-*) ;; + *) break;; + esac +done +cc_basename=`$echo "X$cc_temp" | $Xsed -e 's%.*/%%' -e "s%^$host_alias-%%"` + + +# Only perform the check for file, if the check method requires it +case $deplibs_check_method in +file_magic*) + if test "$file_magic_cmd" = '$MAGIC_CMD'; then + echo "$as_me:$LINENO: checking for ${ac_tool_prefix}file" >&5 +echo $ECHO_N "checking for ${ac_tool_prefix}file... $ECHO_C" >&6 +if test "${lt_cv_path_MAGIC_CMD+set}" = set; then + echo $ECHO_N "(cached) $ECHO_C" >&6 +else + case $MAGIC_CMD in +[\\/*] | ?:[\\/]*) + lt_cv_path_MAGIC_CMD="$MAGIC_CMD" # Let the user override the test with a path. + ;; +*) + lt_save_MAGIC_CMD="$MAGIC_CMD" + lt_save_ifs="$IFS"; IFS=$PATH_SEPARATOR + ac_dummy="/usr/bin$PATH_SEPARATOR$PATH" + for ac_dir in $ac_dummy; do + IFS="$lt_save_ifs" + test -z "$ac_dir" && ac_dir=. + if test -f $ac_dir/${ac_tool_prefix}file; then + lt_cv_path_MAGIC_CMD="$ac_dir/${ac_tool_prefix}file" + if test -n "$file_magic_test_file"; then + case $deplibs_check_method in + "file_magic "*) + file_magic_regex=`expr "$deplibs_check_method" : "file_magic \(.*\)"` + MAGIC_CMD="$lt_cv_path_MAGIC_CMD" + if eval $file_magic_cmd \$file_magic_test_file 2> /dev/null | + $EGREP "$file_magic_regex" > /dev/null; then + : + else + cat <<EOF 1>&2 + +*** Warning: the command libtool uses to detect shared libraries, +*** $file_magic_cmd, produces output that libtool cannot recognize. +*** The result is that libtool may fail to recognize shared libraries +*** as such. This will affect the creation of libtool libraries that +*** depend on shared libraries, but programs linked with such libtool +*** libraries will work regardless of this problem. Nevertheless, you +*** may want to report the problem to your system manager and/or to +*** bug-libtool@gnu.org + +EOF + fi ;; + esac + fi + break + fi + done + IFS="$lt_save_ifs" + MAGIC_CMD="$lt_save_MAGIC_CMD" + ;; +esac +fi + +MAGIC_CMD="$lt_cv_path_MAGIC_CMD" +if test -n "$MAGIC_CMD"; then + echo "$as_me:$LINENO: result: $MAGIC_CMD" >&5 +echo "${ECHO_T}$MAGIC_CMD" >&6 +else + echo "$as_me:$LINENO: result: no" >&5 +echo "${ECHO_T}no" >&6 +fi + +if test -z "$lt_cv_path_MAGIC_CMD"; then + if test -n "$ac_tool_prefix"; then + echo "$as_me:$LINENO: checking for file" >&5 +echo $ECHO_N "checking for file... $ECHO_C" >&6 +if test "${lt_cv_path_MAGIC_CMD+set}" = set; then + echo $ECHO_N "(cached) $ECHO_C" >&6 +else + case $MAGIC_CMD in +[\\/*] | ?:[\\/]*) + lt_cv_path_MAGIC_CMD="$MAGIC_CMD" # Let the user override the test with a path. + ;; +*) + lt_save_MAGIC_CMD="$MAGIC_CMD" + lt_save_ifs="$IFS"; IFS=$PATH_SEPARATOR + ac_dummy="/usr/bin$PATH_SEPARATOR$PATH" + for ac_dir in $ac_dummy; do + IFS="$lt_save_ifs" + test -z "$ac_dir" && ac_dir=. + if test -f $ac_dir/file; then + lt_cv_path_MAGIC_CMD="$ac_dir/file" + if test -n "$file_magic_test_file"; then + case $deplibs_check_method in + "file_magic "*) + file_magic_regex=`expr "$deplibs_check_method" : "file_magic \(.*\)"` + MAGIC_CMD="$lt_cv_path_MAGIC_CMD" + if eval $file_magic_cmd \$file_magic_test_file 2> /dev/null | + $EGREP "$file_magic_regex" > /dev/null; then + : + else + cat <<EOF 1>&2 + +*** Warning: the command libtool uses to detect shared libraries, +*** $file_magic_cmd, produces output that libtool cannot recognize. +*** The result is that libtool may fail to recognize shared libraries +*** as such. This will affect the creation of libtool libraries that +*** depend on shared libraries, but programs linked with such libtool +*** libraries will work regardless of this problem. Nevertheless, you +*** may want to report the problem to your system manager and/or to +*** bug-libtool@gnu.org + +EOF + fi ;; + esac + fi + break + fi + done + IFS="$lt_save_ifs" + MAGIC_CMD="$lt_save_MAGIC_CMD" + ;; +esac +fi + +MAGIC_CMD="$lt_cv_path_MAGIC_CMD" +if test -n "$MAGIC_CMD"; then + echo "$as_me:$LINENO: result: $MAGIC_CMD" >&5 +echo "${ECHO_T}$MAGIC_CMD" >&6 +else + echo "$as_me:$LINENO: result: no" >&5 +echo "${ECHO_T}no" >&6 +fi + + else + MAGIC_CMD=: + fi +fi + + fi + ;; +esac + +enable_dlopen=no +enable_win32_dll=no + +# Check whether --enable-libtool-lock or --disable-libtool-lock was given. +if test "${enable_libtool_lock+set}" = set; then + enableval="$enable_libtool_lock" + +fi; +test "x$enable_libtool_lock" != xno && enable_libtool_lock=yes + + +# Check whether --with-pic or --without-pic was given. +if test "${with_pic+set}" = set; then + withval="$with_pic" + pic_mode="$withval" +else + pic_mode=default +fi; +test -z "$pic_mode" && pic_mode=default + +# Use C for the default configuration in the libtool script +tagname= +lt_save_CC="$CC" +ac_ext=c +ac_cpp='$CPP $CPPFLAGS' +ac_compile='$CC -c $CFLAGS $CPPFLAGS conftest.$ac_ext >&5' +ac_link='$CC -o conftest$ac_exeext $CFLAGS $CPPFLAGS $LDFLAGS conftest.$ac_ext $LIBS >&5' +ac_compiler_gnu=$ac_cv_c_compiler_gnu + + +# Source file extension for C test sources. +ac_ext=c + +# Object file extension for compiled C test sources. +objext=o +objext=$objext + +# Code to be used in simple compile tests +lt_simple_compile_test_code="int some_variable = 0;\n" + +# Code to be used in simple link tests +lt_simple_link_test_code='int main(){return(0);}\n' + + +# If no C compiler was specified, use CC. +LTCC=${LTCC-"$CC"} + +# If no C compiler flags were specified, use CFLAGS. +LTCFLAGS=${LTCFLAGS-"$CFLAGS"} + +# Allow CC to be a program name with arguments. +compiler=$CC + + +# save warnings/boilerplate of simple test code +ac_outfile=conftest.$ac_objext +printf "$lt_simple_compile_test_code" >conftest.$ac_ext +eval "$ac_compile" 2>&1 >/dev/null | $SED '/^$/d; /^ *+/d' >conftest.err +_lt_compiler_boilerplate=`cat conftest.err` +$rm conftest* + +ac_outfile=conftest.$ac_objext +printf "$lt_simple_link_test_code" >conftest.$ac_ext +eval "$ac_link" 2>&1 >/dev/null | $SED '/^$/d; /^ *+/d' >conftest.err +_lt_linker_boilerplate=`cat conftest.err` +$rm conftest* + + + +lt_prog_compiler_no_builtin_flag= + +if test "$GCC" = yes; then + lt_prog_compiler_no_builtin_flag=' -fno-builtin' + + +echo "$as_me:$LINENO: checking if $compiler supports -fno-rtti -fno-exceptions" >&5 +echo $ECHO_N "checking if $compiler supports -fno-rtti -fno-exceptions... $ECHO_C" >&6 +if test "${lt_cv_prog_compiler_rtti_exceptions+set}" = set; then + echo $ECHO_N "(cached) $ECHO_C" >&6 +else + lt_cv_prog_compiler_rtti_exceptions=no + ac_outfile=conftest.$ac_objext + printf "$lt_simple_compile_test_code" > conftest.$ac_ext + lt_compiler_flag="-fno-rtti -fno-exceptions" + # Insert the option either (1) after the last *FLAGS variable, or + # (2) before a word containing "conftest.", or (3) at the end. + # Note that $ac_compile itself does not contain backslashes and begins + # with a dollar sign (not a hyphen), so the echo should work correctly. + # The option is referenced via a variable to avoid confusing sed. + lt_compile=`echo "$ac_compile" | $SED \ + -e 's:.*FLAGS}\{0,1\} :&$lt_compiler_flag :; t' \ + -e 's: [^ ]*conftest\.: $lt_compiler_flag&:; t' \ + -e 's:$: $lt_compiler_flag:'` + (eval echo "\"\$as_me:6513: $lt_compile\"" >&5) + (eval "$lt_compile" 2>conftest.err) + ac_status=$? + cat conftest.err >&5 + echo "$as_me:6517: \$? = $ac_status" >&5 + if (exit $ac_status) && test -s "$ac_outfile"; then + # The compiler can only warn and ignore the option if not recognized + # So say no if there are warnings other than the usual output. + $echo "X$_lt_compiler_boilerplate" | $Xsed -e '/^$/d' >conftest.exp + $SED '/^$/d; /^ *+/d' conftest.err >conftest.er2 + if test ! -s conftest.er2 || diff conftest.exp conftest.er2 >/dev/null; then + lt_cv_prog_compiler_rtti_exceptions=yes + fi + fi + $rm conftest* + +fi +echo "$as_me:$LINENO: result: $lt_cv_prog_compiler_rtti_exceptions" >&5 +echo "${ECHO_T}$lt_cv_prog_compiler_rtti_exceptions" >&6 + +if test x"$lt_cv_prog_compiler_rtti_exceptions" = xyes; then + lt_prog_compiler_no_builtin_flag="$lt_prog_compiler_no_builtin_flag -fno-rtti -fno-exceptions" +else + : +fi + +fi + +lt_prog_compiler_wl= +lt_prog_compiler_pic= +lt_prog_compiler_static= + +echo "$as_me:$LINENO: checking for $compiler option to produce PIC" >&5 +echo $ECHO_N "checking for $compiler option to produce PIC... $ECHO_C" >&6 + + if test "$GCC" = yes; then + lt_prog_compiler_wl='-Wl,' + lt_prog_compiler_static='-static' + + case $host_os in + aix*) + # All AIX code is PIC. + if test "$host_cpu" = ia64; then + # AIX 5 now supports IA64 processor + lt_prog_compiler_static='-Bstatic' + fi + ;; + + amigaos*) + # FIXME: we need at least 68020 code to build shared libraries, but + # adding the `-m68020' flag to GCC prevents building anything better, + # like `-m68040'. + lt_prog_compiler_pic='-m68020 -resident32 -malways-restore-a4' + ;; + + beos* | cygwin* | irix5* | irix6* | nonstopux* | osf3* | osf4* | osf5*) + # PIC is the default for these OSes. + ;; + + mingw* | pw32* | os2*) + # This hack is so that the source file can tell whether it is being + # built for inclusion in a dll (and should export symbols for example). + lt_prog_compiler_pic='-DDLL_EXPORT' + ;; + + darwin* | rhapsody*) + # PIC is the default on this platform + # Common symbols not allowed in MH_DYLIB files + lt_prog_compiler_pic='-fno-common' + ;; + + interix3*) + # Interix 3.x gcc -fpic/-fPIC options generate broken code. + # Instead, we relocate shared libraries at runtime. + ;; + + msdosdjgpp*) + # Just because we use GCC doesn't mean we suddenly get shared libraries + # on systems that don't support them. + lt_prog_compiler_can_build_shared=no + enable_shared=no + ;; + + sysv4*MP*) + if test -d /usr/nec; then + lt_prog_compiler_pic=-Kconform_pic + fi + ;; + + hpux*) + # PIC is the default for IA64 HP-UX and 64-bit HP-UX, but + # not for PA HP-UX. + case $host_cpu in + hppa*64*|ia64*) + # +Z the default + ;; + *) + lt_prog_compiler_pic='-fPIC' + ;; + esac + ;; + + *) + lt_prog_compiler_pic='-fPIC' + ;; + esac + else + # PORTME Check for flag to pass linker flags through the system compiler. + case $host_os in + aix*) + lt_prog_compiler_wl='-Wl,' + if test "$host_cpu" = ia64; then + # AIX 5 now supports IA64 processor + lt_prog_compiler_static='-Bstatic' + else + lt_prog_compiler_static='-bnso -bI:/lib/syscalls.exp' + fi + ;; + darwin*) + # PIC is the default on this platform + # Common symbols not allowed in MH_DYLIB files + case $cc_basename in + xlc*) + lt_prog_compiler_pic='-qnocommon' + lt_prog_compiler_wl='-Wl,' + ;; + esac + ;; + + mingw* | pw32* | os2*) + # This hack is so that the source file can tell whether it is being + # built for inclusion in a dll (and should export symbols for example). + lt_prog_compiler_pic='-DDLL_EXPORT' + ;; + + hpux9* | hpux10* | hpux11*) + lt_prog_compiler_wl='-Wl,' + # PIC is the default for IA64 HP-UX and 64-bit HP-UX, but + # not for PA HP-UX. + case $host_cpu in + hppa*64*|ia64*) + # +Z the default + ;; + *) + lt_prog_compiler_pic='+Z' + ;; + esac + # Is there a better lt_prog_compiler_static that works with the bundled CC? + lt_prog_compiler_static='${wl}-a ${wl}archive' + ;; + + irix5* | irix6* | nonstopux*) + lt_prog_compiler_wl='-Wl,' + # PIC (with -KPIC) is the default. + lt_prog_compiler_static='-non_shared' + ;; + + newsos6) + lt_prog_compiler_pic='-KPIC' + lt_prog_compiler_static='-Bstatic' + ;; + + linux*) + case $cc_basename in + icc* | ecc*) + lt_prog_compiler_wl='-Wl,' + lt_prog_compiler_pic='-KPIC' + lt_prog_compiler_static='-static' + ;; + pgcc* | pgf77* | pgf90* | pgf95*) + # Portland Group compilers (*not* the Pentium gcc compiler, + # which looks to be a dead project) + lt_prog_compiler_wl='-Wl,' + lt_prog_compiler_pic='-fpic' + lt_prog_compiler_static='-Bstatic' + ;; + ccc*) + lt_prog_compiler_wl='-Wl,' + # All Alpha code is PIC. + lt_prog_compiler_static='-non_shared' + ;; + esac + ;; + + osf3* | osf4* | osf5*) + lt_prog_compiler_wl='-Wl,' + # All OSF/1 code is PIC. + lt_prog_compiler_static='-non_shared' + ;; + + solaris*) + lt_prog_compiler_pic='-KPIC' + lt_prog_compiler_static='-Bstatic' + case $cc_basename in + f77* | f90* | f95*) + lt_prog_compiler_wl='-Qoption ld ';; + *) + lt_prog_compiler_wl='-Wl,';; + esac + ;; + + sunos4*) + lt_prog_compiler_wl='-Qoption ld ' + lt_prog_compiler_pic='-PIC' + lt_prog_compiler_static='-Bstatic' + ;; + + sysv4 | sysv4.2uw2* | sysv4.3*) + lt_prog_compiler_wl='-Wl,' + lt_prog_compiler_pic='-KPIC' + lt_prog_compiler_static='-Bstatic' + ;; + + sysv4*MP*) + if test -d /usr/nec ;then + lt_prog_compiler_pic='-Kconform_pic' + lt_prog_compiler_static='-Bstatic' + fi + ;; + + sysv5* | unixware* | sco3.2v5* | sco5v6* | OpenUNIX*) + lt_prog_compiler_wl='-Wl,' + lt_prog_compiler_pic='-KPIC' + lt_prog_compiler_static='-Bstatic' + ;; + + unicos*) + lt_prog_compiler_wl='-Wl,' + lt_prog_compiler_can_build_shared=no + ;; + + uts4*) + lt_prog_compiler_pic='-pic' + lt_prog_compiler_static='-Bstatic' + ;; + + *) + lt_prog_compiler_can_build_shared=no + ;; + esac + fi + +echo "$as_me:$LINENO: result: $lt_prog_compiler_pic" >&5 +echo "${ECHO_T}$lt_prog_compiler_pic" >&6 + +# +# Check to make sure the PIC flag actually works. +# +if test -n "$lt_prog_compiler_pic"; then + +echo "$as_me:$LINENO: checking if $compiler PIC flag $lt_prog_compiler_pic works" >&5 +echo $ECHO_N "checking if $compiler PIC flag $lt_prog_compiler_pic works... $ECHO_C" >&6 +if test "${lt_prog_compiler_pic_works+set}" = set; then + echo $ECHO_N "(cached) $ECHO_C" >&6 +else + lt_prog_compiler_pic_works=no + ac_outfile=conftest.$ac_objext + printf "$lt_simple_compile_test_code" > conftest.$ac_ext + lt_compiler_flag="$lt_prog_compiler_pic -DPIC" + # Insert the option either (1) after the last *FLAGS variable, or + # (2) before a word containing "conftest.", or (3) at the end. + # Note that $ac_compile itself does not contain backslashes and begins + # with a dollar sign (not a hyphen), so the echo should work correctly. + # The option is referenced via a variable to avoid confusing sed. + lt_compile=`echo "$ac_compile" | $SED \ + -e 's:.*FLAGS}\{0,1\} :&$lt_compiler_flag :; t' \ + -e 's: [^ ]*conftest\.: $lt_compiler_flag&:; t' \ + -e 's:$: $lt_compiler_flag:'` + (eval echo "\"\$as_me:6781: $lt_compile\"" >&5) + (eval "$lt_compile" 2>conftest.err) + ac_status=$? + cat conftest.err >&5 + echo "$as_me:6785: \$? = $ac_status" >&5 + if (exit $ac_status) && test -s "$ac_outfile"; then + # The compiler can only warn and ignore the option if not recognized + # So say no if there are warnings other than the usual output. + $echo "X$_lt_compiler_boilerplate" | $Xsed -e '/^$/d' >conftest.exp + $SED '/^$/d; /^ *+/d' conftest.err >conftest.er2 + if test ! -s conftest.er2 || diff conftest.exp conftest.er2 >/dev/null; then + lt_prog_compiler_pic_works=yes + fi + fi + $rm conftest* + +fi +echo "$as_me:$LINENO: result: $lt_prog_compiler_pic_works" >&5 +echo "${ECHO_T}$lt_prog_compiler_pic_works" >&6 + +if test x"$lt_prog_compiler_pic_works" = xyes; then + case $lt_prog_compiler_pic in + "" | " "*) ;; + *) lt_prog_compiler_pic=" $lt_prog_compiler_pic" ;; + esac +else + lt_prog_compiler_pic= + lt_prog_compiler_can_build_shared=no +fi + +fi +case $host_os in + # For platforms which do not support PIC, -DPIC is meaningless: + *djgpp*) + lt_prog_compiler_pic= + ;; + *) + lt_prog_compiler_pic="$lt_prog_compiler_pic -DPIC" + ;; +esac + +# +# Check to make sure the static flag actually works. +# +wl=$lt_prog_compiler_wl eval lt_tmp_static_flag=\"$lt_prog_compiler_static\" +echo "$as_me:$LINENO: checking if $compiler static flag $lt_tmp_static_flag works" >&5 +echo $ECHO_N "checking if $compiler static flag $lt_tmp_static_flag works... $ECHO_C" >&6 +if test "${lt_prog_compiler_static_works+set}" = set; then + echo $ECHO_N "(cached) $ECHO_C" >&6 +else + lt_prog_compiler_static_works=no + save_LDFLAGS="$LDFLAGS" + LDFLAGS="$LDFLAGS $lt_tmp_static_flag" + printf "$lt_simple_link_test_code" > conftest.$ac_ext + if (eval $ac_link 2>conftest.err) && test -s conftest$ac_exeext; then + # The linker can only warn and ignore the option if not recognized + # So say no if there are warnings + if test -s conftest.err; then + # Append any errors to the config.log. + cat conftest.err 1>&5 + $echo "X$_lt_linker_boilerplate" | $Xsed -e '/^$/d' > conftest.exp + $SED '/^$/d; /^ *+/d' conftest.err >conftest.er2 + if diff conftest.exp conftest.er2 >/dev/null; then + lt_prog_compiler_static_works=yes + fi + else + lt_prog_compiler_static_works=yes + fi + fi + $rm conftest* + LDFLAGS="$save_LDFLAGS" + +fi +echo "$as_me:$LINENO: result: $lt_prog_compiler_static_works" >&5 +echo "${ECHO_T}$lt_prog_compiler_static_works" >&6 + +if test x"$lt_prog_compiler_static_works" = xyes; then + : +else + lt_prog_compiler_static= +fi + + +echo "$as_me:$LINENO: checking if $compiler supports -c -o file.$ac_objext" >&5 +echo $ECHO_N "checking if $compiler supports -c -o file.$ac_objext... $ECHO_C" >&6 +if test "${lt_cv_prog_compiler_c_o+set}" = set; then + echo $ECHO_N "(cached) $ECHO_C" >&6 +else + lt_cv_prog_compiler_c_o=no + $rm -r conftest 2>/dev/null + mkdir conftest + cd conftest + mkdir out + printf "$lt_simple_compile_test_code" > conftest.$ac_ext + + lt_compiler_flag="-o out/conftest2.$ac_objext" + # Insert the option either (1) after the last *FLAGS variable, or + # (2) before a word containing "conftest.", or (3) at the end. + # Note that $ac_compile itself does not contain backslashes and begins + # with a dollar sign (not a hyphen), so the echo should work correctly. + lt_compile=`echo "$ac_compile" | $SED \ + -e 's:.*FLAGS}\{0,1\} :&$lt_compiler_flag :; t' \ + -e 's: [^ ]*conftest\.: $lt_compiler_flag&:; t' \ + -e 's:$: $lt_compiler_flag:'` + (eval echo "\"\$as_me:6885: $lt_compile\"" >&5) + (eval "$lt_compile" 2>out/conftest.err) + ac_status=$? + cat out/conftest.err >&5 + echo "$as_me:6889: \$? = $ac_status" >&5 + if (exit $ac_status) && test -s out/conftest2.$ac_objext + then + # The compiler can only warn and ignore the option if not recognized + # So say no if there are warnings + $echo "X$_lt_compiler_boilerplate" | $Xsed -e '/^$/d' > out/conftest.exp + $SED '/^$/d; /^ *+/d' out/conftest.err >out/conftest.er2 + if test ! -s out/conftest.er2 || diff out/conftest.exp out/conftest.er2 >/dev/null; then + lt_cv_prog_compiler_c_o=yes + fi + fi + chmod u+w . 2>&5 + $rm conftest* + # SGI C++ compiler will create directory out/ii_files/ for + # template instantiation + test -d out/ii_files && $rm out/ii_files/* && rmdir out/ii_files + $rm out/* && rmdir out + cd .. + rmdir conftest + $rm conftest* + +fi +echo "$as_me:$LINENO: result: $lt_cv_prog_compiler_c_o" >&5 +echo "${ECHO_T}$lt_cv_prog_compiler_c_o" >&6 + + +hard_links="nottested" +if test "$lt_cv_prog_compiler_c_o" = no && test "$need_locks" != no; then + # do not overwrite the value of need_locks provided by the user + echo "$as_me:$LINENO: checking if we can lock with hard links" >&5 +echo $ECHO_N "checking if we can lock with hard links... $ECHO_C" >&6 + hard_links=yes + $rm conftest* + ln conftest.a conftest.b 2>/dev/null && hard_links=no + touch conftest.a + ln conftest.a conftest.b 2>&5 || hard_links=no + ln conftest.a conftest.b 2>/dev/null && hard_links=no + echo "$as_me:$LINENO: result: $hard_links" >&5 +echo "${ECHO_T}$hard_links" >&6 + if test "$hard_links" = no; then + { echo "$as_me:$LINENO: WARNING: \`$CC' does not support \`-c -o', so \`make -j' may be unsafe" >&5 +echo "$as_me: WARNING: \`$CC' does not support \`-c -o', so \`make -j' may be unsafe" >&2;} + need_locks=warn + fi +else + need_locks=no +fi + +echo "$as_me:$LINENO: checking whether the $compiler linker ($LD) supports shared libraries" >&5 +echo $ECHO_N "checking whether the $compiler linker ($LD) supports shared libraries... $ECHO_C" >&6 + + runpath_var= + allow_undefined_flag= + enable_shared_with_static_runtimes=no + archive_cmds= + archive_expsym_cmds= + old_archive_From_new_cmds= + old_archive_from_expsyms_cmds= + export_dynamic_flag_spec= + whole_archive_flag_spec= + thread_safe_flag_spec= + hardcode_libdir_flag_spec= + hardcode_libdir_flag_spec_ld= + hardcode_libdir_separator= + hardcode_direct=no + hardcode_minus_L=no + hardcode_shlibpath_var=unsupported + link_all_deplibs=unknown + hardcode_automatic=no + module_cmds= + module_expsym_cmds= + always_export_symbols=no + export_symbols_cmds='$NM $libobjs $convenience | $global_symbol_pipe | $SED '\''s/.* //'\'' | sort | uniq > $export_symbols' + # include_expsyms should be a list of space-separated symbols to be *always* + # included in the symbol list + include_expsyms= + # exclude_expsyms can be an extended regexp of symbols to exclude + # it will be wrapped by ` (' and `)$', so one must not match beginning or + # end of line. Example: `a|bc|.*d.*' will exclude the symbols `a' and `bc', + # as well as any symbol that contains `d'. + exclude_expsyms="_GLOBAL_OFFSET_TABLE_" + # Although _GLOBAL_OFFSET_TABLE_ is a valid symbol C name, most a.out + # platforms (ab)use it in PIC code, but their linkers get confused if + # the symbol is explicitly referenced. Since portable code cannot + # rely on this symbol name, it's probably fine to never include it in + # preloaded symbol tables. + extract_expsyms_cmds= + # Just being paranoid about ensuring that cc_basename is set. + for cc_temp in $compiler""; do + case $cc_temp in + compile | *[\\/]compile | ccache | *[\\/]ccache ) ;; + distcc | *[\\/]distcc | purify | *[\\/]purify ) ;; + \-*) ;; + *) break;; + esac +done +cc_basename=`$echo "X$cc_temp" | $Xsed -e 's%.*/%%' -e "s%^$host_alias-%%"` + + case $host_os in + cygwin* | mingw* | pw32*) + # FIXME: the MSVC++ port hasn't been tested in a loooong time + # When not using gcc, we currently assume that we are using + # Microsoft Visual C++. + if test "$GCC" != yes; then + with_gnu_ld=no + fi + ;; + interix*) + # we just hope/assume this is gcc and not c89 (= MSVC++) + with_gnu_ld=yes + ;; + openbsd*) + with_gnu_ld=no + ;; + esac + + ld_shlibs=yes + if test "$with_gnu_ld" = yes; then + # If archive_cmds runs LD, not CC, wlarc should be empty + wlarc='${wl}' + + # Set some defaults for GNU ld with shared library support. These + # are reset later if shared libraries are not supported. Putting them + # here allows them to be overridden if necessary. + runpath_var=LD_RUN_PATH + hardcode_libdir_flag_spec='${wl}--rpath ${wl}$libdir' + export_dynamic_flag_spec='${wl}--export-dynamic' + # ancient GNU ld didn't support --whole-archive et. al. + if $LD --help 2>&1 | grep 'no-whole-archive' > /dev/null; then + whole_archive_flag_spec="$wlarc"'--whole-archive$convenience '"$wlarc"'--no-whole-archive' + else + whole_archive_flag_spec= + fi + supports_anon_versioning=no + case `$LD -v 2>/dev/null` in + *\ [01].* | *\ 2.[0-9].* | *\ 2.10.*) ;; # catch versions < 2.11 + *\ 2.11.93.0.2\ *) supports_anon_versioning=yes ;; # RH7.3 ... + *\ 2.11.92.0.12\ *) supports_anon_versioning=yes ;; # Mandrake 8.2 ... + *\ 2.11.*) ;; # other 2.11 versions + *) supports_anon_versioning=yes ;; + esac + + # See if GNU ld supports shared libraries. + case $host_os in + aix3* | aix4* | aix5*) + # On AIX/PPC, the GNU linker is very broken + if test "$host_cpu" != ia64; then + ld_shlibs=no + cat <<EOF 1>&2 + +*** Warning: the GNU linker, at least up to release 2.9.1, is reported +*** to be unable to reliably create shared libraries on AIX. +*** Therefore, libtool is disabling shared libraries support. If you +*** really care for shared libraries, you may want to modify your PATH +*** so that a non-GNU linker is found, and then restart. + +EOF + fi + ;; + + amigaos*) + archive_cmds='$rm $output_objdir/a2ixlibrary.data~$echo "#define NAME $libname" > $output_objdir/a2ixlibrary.data~$echo "#define LIBRARY_ID 1" >> $output_objdir/a2ixlibrary.data~$echo "#define VERSION $major" >> $output_objdir/a2ixlibrary.data~$echo "#define REVISION $revision" >> $output_objdir/a2ixlibrary.data~$AR $AR_FLAGS $lib $libobjs~$RANLIB $lib~(cd $output_objdir && a2ixlibrary -32)' + hardcode_libdir_flag_spec='-L$libdir' + hardcode_minus_L=yes + + # Samuel A. Falvo II <kc5tja@dolphin.openprojects.net> reports + # that the semantics of dynamic libraries on AmigaOS, at least up + # to version 4, is to share data among multiple programs linked + # with the same dynamic library. Since this doesn't match the + # behavior of shared libraries on other platforms, we can't use + # them. + ld_shlibs=no + ;; + + beos*) + if $LD --help 2>&1 | grep ': supported targets:.* elf' > /dev/null; then + allow_undefined_flag=unsupported + # Joseph Beckenbach <jrb3@best.com> says some releases of gcc + # support --undefined. This deserves some investigation. FIXME + archive_cmds='$CC -nostart $libobjs $deplibs $compiler_flags ${wl}-soname $wl$soname -o $lib' + else + ld_shlibs=no + fi + ;; + + cygwin* | mingw* | pw32*) + # _LT_AC_TAGVAR(hardcode_libdir_flag_spec, ) is actually meaningless, + # as there is no search path for DLLs. + hardcode_libdir_flag_spec='-L$libdir' + allow_undefined_flag=unsupported + always_export_symbols=no + enable_shared_with_static_runtimes=yes + export_symbols_cmds='$NM $libobjs $convenience | $global_symbol_pipe | $SED -e '\''/^[BCDGRS] /s/.* \([^ ]*\)/\1 DATA/'\'' | $SED -e '\''/^[AITW] /s/.* //'\'' | sort | uniq > $export_symbols' + + if $LD --help 2>&1 | grep 'auto-import' > /dev/null; then + archive_cmds='$CC -shared $libobjs $deplibs $compiler_flags -o $output_objdir/$soname ${wl}--enable-auto-image-base -Xlinker --out-implib -Xlinker $lib' + # If the export-symbols file already is a .def file (1st line + # is EXPORTS), use it as is; otherwise, prepend... + archive_expsym_cmds='if test "x`$SED 1q $export_symbols`" = xEXPORTS; then + cp $export_symbols $output_objdir/$soname.def; + else + echo EXPORTS > $output_objdir/$soname.def; + cat $export_symbols >> $output_objdir/$soname.def; + fi~ + $CC -shared $output_objdir/$soname.def $libobjs $deplibs $compiler_flags -o $output_objdir/$soname ${wl}--enable-auto-image-base -Xlinker --out-implib -Xlinker $lib' + else + ld_shlibs=no + fi + ;; + + interix3*) + hardcode_direct=no + hardcode_shlibpath_var=no + hardcode_libdir_flag_spec='${wl}-rpath,$libdir' + export_dynamic_flag_spec='${wl}-E' + # Hack: On Interix 3.x, we cannot compile PIC because of a broken gcc. + # Instead, shared libraries are loaded at an image base (0x10000000 by + # default) and relocated if they conflict, which is a slow very memory + # consuming and fragmenting process. To avoid this, we pick a random, + # 256 KiB-aligned image base between 0x50000000 and 0x6FFC0000 at link + # time. Moving up from 0x10000000 also allows more sbrk(2) space. + archive_cmds='$CC -shared $pic_flag $libobjs $deplibs $compiler_flags ${wl}-h,$soname ${wl}--image-base,`expr ${RANDOM-$$} % 4096 / 2 \* 262144 + 1342177280` -o $lib' + archive_expsym_cmds='sed "s,^,_," $export_symbols >$output_objdir/$soname.expsym~$CC -shared $pic_flag $libobjs $deplibs $compiler_flags ${wl}-h,$soname ${wl}--retain-symbols-file,$output_objdir/$soname.expsym ${wl}--image-base,`expr ${RANDOM-$$} % 4096 / 2 \* 262144 + 1342177280` -o $lib' + ;; + + linux*) + if $LD --help 2>&1 | grep ': supported targets:.* elf' > /dev/null; then + tmp_addflag= + case $cc_basename,$host_cpu in + pgcc*) # Portland Group C compiler + whole_archive_flag_spec='${wl}--whole-archive`for conv in $convenience\"\"; do test -n \"$conv\" && new_convenience=\"$new_convenience,$conv\"; done; $echo \"$new_convenience\"` ${wl}--no-whole-archive' + tmp_addflag=' $pic_flag' + ;; + pgf77* | pgf90* | pgf95*) # Portland Group f77 and f90 compilers + whole_archive_flag_spec='${wl}--whole-archive`for conv in $convenience\"\"; do test -n \"$conv\" && new_convenience=\"$new_convenience,$conv\"; done; $echo \"$new_convenience\"` ${wl}--no-whole-archive' + tmp_addflag=' $pic_flag -Mnomain' ;; + ecc*,ia64* | icc*,ia64*) # Intel C compiler on ia64 + tmp_addflag=' -i_dynamic' ;; + efc*,ia64* | ifort*,ia64*) # Intel Fortran compiler on ia64 + tmp_addflag=' -i_dynamic -nofor_main' ;; + ifc* | ifort*) # Intel Fortran compiler + tmp_addflag=' -nofor_main' ;; + esac + archive_cmds='$CC -shared'"$tmp_addflag"' $libobjs $deplibs $compiler_flags ${wl}-soname $wl$soname -o $lib' + + if test $supports_anon_versioning = yes; then + archive_expsym_cmds='$echo "{ global:" > $output_objdir/$libname.ver~ + cat $export_symbols | sed -e "s/\(.*\)/\1;/" >> $output_objdir/$libname.ver~ + $echo "local: *; };" >> $output_objdir/$libname.ver~ + $CC -shared'"$tmp_addflag"' $libobjs $deplibs $compiler_flags ${wl}-soname $wl$soname ${wl}-version-script ${wl}$output_objdir/$libname.ver -o $lib' + fi + else + ld_shlibs=no + fi + ;; + + netbsd*) + if echo __ELF__ | $CC -E - | grep __ELF__ >/dev/null; then + archive_cmds='$LD -Bshareable $libobjs $deplibs $linker_flags -o $lib' + wlarc= + else + archive_cmds='$CC -shared $libobjs $deplibs $compiler_flags ${wl}-soname $wl$soname -o $lib' + archive_expsym_cmds='$CC -shared $libobjs $deplibs $compiler_flags ${wl}-soname $wl$soname ${wl}-retain-symbols-file $wl$export_symbols -o $lib' + fi + ;; + + solaris*) + if $LD -v 2>&1 | grep 'BFD 2\.8' > /dev/null; then + ld_shlibs=no + cat <<EOF 1>&2 + +*** Warning: The releases 2.8.* of the GNU linker cannot reliably +*** create shared libraries on Solaris systems. Therefore, libtool +*** is disabling shared libraries support. We urge you to upgrade GNU +*** binutils to release 2.9.1 or newer. Another option is to modify +*** your PATH or compiler configuration so that the native linker is +*** used, and then restart. + +EOF + elif $LD --help 2>&1 | grep ': supported targets:.* elf' > /dev/null; then + archive_cmds='$CC -shared $libobjs $deplibs $compiler_flags ${wl}-soname $wl$soname -o $lib' + archive_expsym_cmds='$CC -shared $libobjs $deplibs $compiler_flags ${wl}-soname $wl$soname ${wl}-retain-symbols-file $wl$export_symbols -o $lib' + else + ld_shlibs=no + fi + ;; + + sysv5* | sco3.2v5* | sco5v6* | unixware* | OpenUNIX*) + case `$LD -v 2>&1` in + *\ [01].* | *\ 2.[0-9].* | *\ 2.1[0-5].*) + ld_shlibs=no + cat <<_LT_EOF 1>&2 + +*** Warning: Releases of the GNU linker prior to 2.16.91.0.3 can not +*** reliably create shared libraries on SCO systems. Therefore, libtool +*** is disabling shared libraries support. We urge you to upgrade GNU +*** binutils to release 2.16.91.0.3 or newer. Another option is to modify +*** your PATH or compiler configuration so that the native linker is +*** used, and then restart. + +_LT_EOF + ;; + *) + if $LD --help 2>&1 | grep ': supported targets:.* elf' > /dev/null; then + hardcode_libdir_flag_spec='`test -z "$SCOABSPATH" && echo ${wl}-rpath,$libdir`' + archive_cmds='$CC -shared $libobjs $deplibs $compiler_flags ${wl}-soname,\${SCOABSPATH:+${install_libdir}/}$soname -o $lib' + archive_expsym_cmds='$CC -shared $libobjs $deplibs $compiler_flags ${wl}-soname,\${SCOABSPATH:+${install_libdir}/}$soname,-retain-symbols-file,$export_symbols -o $lib' + else + ld_shlibs=no + fi + ;; + esac + ;; + + sunos4*) + archive_cmds='$LD -assert pure-text -Bshareable -o $lib $libobjs $deplibs $linker_flags' + wlarc= + hardcode_direct=yes + hardcode_shlibpath_var=no + ;; + + *) + if $LD --help 2>&1 | grep ': supported targets:.* elf' > /dev/null; then + archive_cmds='$CC -shared $libobjs $deplibs $compiler_flags ${wl}-soname $wl$soname -o $lib' + archive_expsym_cmds='$CC -shared $libobjs $deplibs $compiler_flags ${wl}-soname $wl$soname ${wl}-retain-symbols-file $wl$export_symbols -o $lib' + else + ld_shlibs=no + fi + ;; + esac + + if test "$ld_shlibs" = no; then + runpath_var= + hardcode_libdir_flag_spec= + export_dynamic_flag_spec= + whole_archive_flag_spec= + fi + else + # PORTME fill in a description of your system's linker (not GNU ld) + case $host_os in + aix3*) + allow_undefined_flag=unsupported + always_export_symbols=yes + archive_expsym_cmds='$LD -o $output_objdir/$soname $libobjs $deplibs $linker_flags -bE:$export_symbols -T512 -H512 -bM:SRE~$AR $AR_FLAGS $lib $output_objdir/$soname' + # Note: this linker hardcodes the directories in LIBPATH if there + # are no directories specified by -L. + hardcode_minus_L=yes + if test "$GCC" = yes && test -z "$lt_prog_compiler_static"; then + # Neither direct hardcoding nor static linking is supported with a + # broken collect2. + hardcode_direct=unsupported + fi + ;; + + aix4* | aix5*) + if test "$host_cpu" = ia64; then + # On IA64, the linker does run time linking by default, so we don't + # have to do anything special. + aix_use_runtimelinking=no + exp_sym_flag='-Bexport' + no_entry_flag="" + else + # If we're using GNU nm, then we don't want the "-C" option. + # -C means demangle to AIX nm, but means don't demangle with GNU nm + if $NM -V 2>&1 | grep 'GNU' > /dev/null; then + export_symbols_cmds='$NM -Bpg $libobjs $convenience | awk '\''{ if (((\$2 == "T") || (\$2 == "D") || (\$2 == "B")) && (substr(\$3,1,1) != ".")) { print \$3 } }'\'' | sort -u > $export_symbols' + else + export_symbols_cmds='$NM -BCpg $libobjs $convenience | awk '\''{ if (((\$2 == "T") || (\$2 == "D") || (\$2 == "B")) && (substr(\$3,1,1) != ".")) { print \$3 } }'\'' | sort -u > $export_symbols' + fi + aix_use_runtimelinking=no + + # Test if we are trying to use run time linking or normal + # AIX style linking. If -brtl is somewhere in LDFLAGS, we + # need to do runtime linking. + case $host_os in aix4.[23]|aix4.[23].*|aix5*) + for ld_flag in $LDFLAGS; do + if (test $ld_flag = "-brtl" || test $ld_flag = "-Wl,-brtl"); then + aix_use_runtimelinking=yes + break + fi + done + ;; + esac + + exp_sym_flag='-bexport' + no_entry_flag='-bnoentry' + fi + + # When large executables or shared objects are built, AIX ld can + # have problems creating the table of contents. If linking a library + # or program results in "error TOC overflow" add -mminimal-toc to + # CXXFLAGS/CFLAGS for g++/gcc. In the cases where that is not + # enough to fix the problem, add -Wl,-bbigtoc to LDFLAGS. + + archive_cmds='' + hardcode_direct=yes + hardcode_libdir_separator=':' + link_all_deplibs=yes + + if test "$GCC" = yes; then + case $host_os in aix4.[012]|aix4.[012].*) + # We only want to do this on AIX 4.2 and lower, the check + # below for broken collect2 doesn't work under 4.3+ + collect2name=`${CC} -print-prog-name=collect2` + if test -f "$collect2name" && \ + strings "$collect2name" | grep resolve_lib_name >/dev/null + then + # We have reworked collect2 + hardcode_direct=yes + else + # We have old collect2 + hardcode_direct=unsupported + # It fails to find uninstalled libraries when the uninstalled + # path is not listed in the libpath. Setting hardcode_minus_L + # to unsupported forces relinking + hardcode_minus_L=yes + hardcode_libdir_flag_spec='-L$libdir' + hardcode_libdir_separator= + fi + ;; + esac + shared_flag='-shared' + if test "$aix_use_runtimelinking" = yes; then + shared_flag="$shared_flag "'${wl}-G' + fi + else + # not using gcc + if test "$host_cpu" = ia64; then + # VisualAge C++, Version 5.5 for AIX 5L for IA-64, Beta 3 Release + # chokes on -Wl,-G. The following line is correct: + shared_flag='-G' + else + if test "$aix_use_runtimelinking" = yes; then + shared_flag='${wl}-G' + else + shared_flag='${wl}-bM:SRE' + fi + fi + fi + + # It seems that -bexpall does not export symbols beginning with + # underscore (_), so it is better to generate a list of symbols to export. + always_export_symbols=yes + if test "$aix_use_runtimelinking" = yes; then + # Warning - without using the other runtime loading flags (-brtl), + # -berok will link without error, but may produce a broken library. + allow_undefined_flag='-berok' + # Determine the default libpath from the value encoded in an empty executable. + cat >conftest.$ac_ext <<_ACEOF +/* confdefs.h. */ +_ACEOF +cat confdefs.h >>conftest.$ac_ext +cat >>conftest.$ac_ext <<_ACEOF +/* end confdefs.h. */ + +int +main () +{ + + ; + return 0; +} +_ACEOF +rm -f conftest.$ac_objext conftest$ac_exeext +if { (eval echo "$as_me:$LINENO: \"$ac_link\"") >&5 + (eval $ac_link) 2>conftest.er1 + ac_status=$? + grep -v '^ *+' conftest.er1 >conftest.err + rm -f conftest.er1 + cat conftest.err >&5 + echo "$as_me:$LINENO: \$? = $ac_status" >&5 + (exit $ac_status); } && + { ac_try='test -z "$ac_c_werror_flag" + || test ! -s conftest.err' + { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5 + (eval $ac_try) 2>&5 + ac_status=$? + echo "$as_me:$LINENO: \$? = $ac_status" >&5 + (exit $ac_status); }; } && + { ac_try='test -s conftest$ac_exeext' + { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5 + (eval $ac_try) 2>&5 + ac_status=$? + echo "$as_me:$LINENO: \$? = $ac_status" >&5 + (exit $ac_status); }; }; then + +aix_libpath=`dump -H conftest$ac_exeext 2>/dev/null | $SED -n -e '/Import File Strings/,/^$/ { /^0/ { s/^0 *\(.*\)$/\1/; p; } +}'` +# Check for a 64-bit object if we didn't find anything. +if test -z "$aix_libpath"; then aix_libpath=`dump -HX64 conftest$ac_exeext 2>/dev/null | $SED -n -e '/Import File Strings/,/^$/ { /^0/ { s/^0 *\(.*\)$/\1/; p; } +}'`; fi +else + echo "$as_me: failed program was:" >&5 +sed 's/^/| /' conftest.$ac_ext >&5 + +fi +rm -f conftest.err conftest.$ac_objext \ + conftest$ac_exeext conftest.$ac_ext +if test -z "$aix_libpath"; then aix_libpath="/usr/lib:/lib"; fi + + hardcode_libdir_flag_spec='${wl}-blibpath:$libdir:'"$aix_libpath" + archive_expsym_cmds="\$CC"' -o $output_objdir/$soname $libobjs $deplibs '"\${wl}$no_entry_flag"' $compiler_flags `if test "x${allow_undefined_flag}" != "x"; then echo "${wl}${allow_undefined_flag}"; else :; fi` '"\${wl}$exp_sym_flag:\$export_symbols $shared_flag" + else + if test "$host_cpu" = ia64; then + hardcode_libdir_flag_spec='${wl}-R $libdir:/usr/lib:/lib' + allow_undefined_flag="-z nodefs" + archive_expsym_cmds="\$CC $shared_flag"' -o $output_objdir/$soname $libobjs $deplibs '"\${wl}$no_entry_flag"' $compiler_flags ${wl}${allow_undefined_flag} '"\${wl}$exp_sym_flag:\$export_symbols" + else + # Determine the default libpath from the value encoded in an empty executable. + cat >conftest.$ac_ext <<_ACEOF +/* confdefs.h. */ +_ACEOF +cat confdefs.h >>conftest.$ac_ext +cat >>conftest.$ac_ext <<_ACEOF +/* end confdefs.h. */ + +int +main () +{ + + ; + return 0; +} +_ACEOF +rm -f conftest.$ac_objext conftest$ac_exeext +if { (eval echo "$as_me:$LINENO: \"$ac_link\"") >&5 + (eval $ac_link) 2>conftest.er1 + ac_status=$? + grep -v '^ *+' conftest.er1 >conftest.err + rm -f conftest.er1 + cat conftest.err >&5 + echo "$as_me:$LINENO: \$? = $ac_status" >&5 + (exit $ac_status); } && + { ac_try='test -z "$ac_c_werror_flag" + || test ! -s conftest.err' + { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5 + (eval $ac_try) 2>&5 + ac_status=$? + echo "$as_me:$LINENO: \$? = $ac_status" >&5 + (exit $ac_status); }; } && + { ac_try='test -s conftest$ac_exeext' + { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5 + (eval $ac_try) 2>&5 + ac_status=$? + echo "$as_me:$LINENO: \$? = $ac_status" >&5 + (exit $ac_status); }; }; then + +aix_libpath=`dump -H conftest$ac_exeext 2>/dev/null | $SED -n -e '/Import File Strings/,/^$/ { /^0/ { s/^0 *\(.*\)$/\1/; p; } +}'` +# Check for a 64-bit object if we didn't find anything. +if test -z "$aix_libpath"; then aix_libpath=`dump -HX64 conftest$ac_exeext 2>/dev/null | $SED -n -e '/Import File Strings/,/^$/ { /^0/ { s/^0 *\(.*\)$/\1/; p; } +}'`; fi +else + echo "$as_me: failed program was:" >&5 +sed 's/^/| /' conftest.$ac_ext >&5 + +fi +rm -f conftest.err conftest.$ac_objext \ + conftest$ac_exeext conftest.$ac_ext +if test -z "$aix_libpath"; then aix_libpath="/usr/lib:/lib"; fi + + hardcode_libdir_flag_spec='${wl}-blibpath:$libdir:'"$aix_libpath" + # Warning - without using the other run time loading flags, + # -berok will link without error, but may produce a broken library. + no_undefined_flag=' ${wl}-bernotok' + allow_undefined_flag=' ${wl}-berok' + # Exported symbols can be pulled into shared objects from archives + whole_archive_flag_spec='$convenience' + archive_cmds_need_lc=yes + # This is similar to how AIX traditionally builds its shared libraries. + archive_expsym_cmds="\$CC $shared_flag"' -o $output_objdir/$soname $libobjs $deplibs ${wl}-bnoentry $compiler_flags ${wl}-bE:$export_symbols${allow_undefined_flag}~$AR $AR_FLAGS $output_objdir/$libname$release.a $output_objdir/$soname' + fi + fi + ;; + + amigaos*) + archive_cmds='$rm $output_objdir/a2ixlibrary.data~$echo "#define NAME $libname" > $output_objdir/a2ixlibrary.data~$echo "#define LIBRARY_ID 1" >> $output_objdir/a2ixlibrary.data~$echo "#define VERSION $major" >> $output_objdir/a2ixlibrary.data~$echo "#define REVISION $revision" >> $output_objdir/a2ixlibrary.data~$AR $AR_FLAGS $lib $libobjs~$RANLIB $lib~(cd $output_objdir && a2ixlibrary -32)' + hardcode_libdir_flag_spec='-L$libdir' + hardcode_minus_L=yes + # see comment about different semantics on the GNU ld section + ld_shlibs=no + ;; + + bsdi[45]*) + export_dynamic_flag_spec=-rdynamic + ;; + + cygwin* | mingw* | pw32*) + # When not using gcc, we currently assume that we are using + # Microsoft Visual C++. + # hardcode_libdir_flag_spec is actually meaningless, as there is + # no search path for DLLs. + hardcode_libdir_flag_spec=' ' + allow_undefined_flag=unsupported + # Tell ltmain to make .lib files, not .a files. + libext=lib + # Tell ltmain to make .dll files, not .so files. + shrext_cmds=".dll" + # FIXME: Setting linknames here is a bad hack. + archive_cmds='$CC -o $lib $libobjs $compiler_flags `echo "$deplibs" | $SED -e '\''s/ -lc$//'\''` -link -dll~linknames=' + # The linker will automatically build a .lib file if we build a DLL. + old_archive_From_new_cmds='true' + # FIXME: Should let the user specify the lib program. + old_archive_cmds='lib /OUT:$oldlib$oldobjs$old_deplibs' + fix_srcfile_path='`cygpath -w "$srcfile"`' + enable_shared_with_static_runtimes=yes + ;; + + darwin* | rhapsody*) + case $host_os in + rhapsody* | darwin1.[012]) + allow_undefined_flag='${wl}-undefined ${wl}suppress' + ;; + *) # Darwin 1.3 on + if test -z ${MACOSX_DEPLOYMENT_TARGET} ; then + allow_undefined_flag='${wl}-flat_namespace ${wl}-undefined ${wl}suppress' + else + case ${MACOSX_DEPLOYMENT_TARGET} in + 10.[012]) + allow_undefined_flag='${wl}-flat_namespace ${wl}-undefined ${wl}suppress' + ;; + 10.*) + allow_undefined_flag='${wl}-undefined ${wl}dynamic_lookup' + ;; + esac + fi + ;; + esac + archive_cmds_need_lc=no + hardcode_direct=no + hardcode_automatic=yes + hardcode_shlibpath_var=unsupported + whole_archive_flag_spec='' + link_all_deplibs=yes + if test "$GCC" = yes ; then + output_verbose_link_cmd='echo' + archive_cmds='$CC -dynamiclib $allow_undefined_flag -o $lib $libobjs $deplibs $compiler_flags -install_name $rpath/$soname $verstring' + module_cmds='$CC $allow_undefined_flag -o $lib -bundle $libobjs $deplibs$compiler_flags' + # Don't fix this by using the ld -exported_symbols_list flag, it doesn't exist in older darwin lds + archive_expsym_cmds='sed -e "s,#.*,," -e "s,^[ ]*,," -e "s,^\(..*\),_&," < $export_symbols > $output_objdir/${libname}-symbols.expsym~$CC -dynamiclib $allow_undefined_flag -o $lib $libobjs $deplibs $compiler_flags -install_name $rpath/$soname $verstring~nmedit -s $output_objdir/${libname}-symbols.expsym ${lib}' + module_expsym_cmds='sed -e "s,#.*,," -e "s,^[ ]*,," -e "s,^\(..*\),_&," < $export_symbols > $output_objdir/${libname}-symbols.expsym~$CC $allow_undefined_flag -o $lib -bundle $libobjs $deplibs$compiler_flags~nmedit -s $output_objdir/${libname}-symbols.expsym ${lib}' + else + case $cc_basename in + xlc*) + output_verbose_link_cmd='echo' + archive_cmds='$CC -qmkshrobj $allow_undefined_flag -o $lib $libobjs $deplibs $compiler_flags ${wl}-install_name ${wl}`echo $rpath/$soname` $verstring' + module_cmds='$CC $allow_undefined_flag -o $lib -bundle $libobjs $deplibs$compiler_flags' + # Don't fix this by using the ld -exported_symbols_list flag, it doesn't exist in older darwin lds + archive_expsym_cmds='sed -e "s,#.*,," -e "s,^[ ]*,," -e "s,^\(..*\),_&," < $export_symbols > $output_objdir/${libname}-symbols.expsym~$CC -qmkshrobj $allow_undefined_flag -o $lib $libobjs $deplibs $compiler_flags ${wl}-install_name ${wl}$rpath/$soname $verstring~nmedit -s $output_objdir/${libname}-symbols.expsym ${lib}' + module_expsym_cmds='sed -e "s,#.*,," -e "s,^[ ]*,," -e "s,^\(..*\),_&," < $export_symbols > $output_objdir/${libname}-symbols.expsym~$CC $allow_undefined_flag -o $lib -bundle $libobjs $deplibs$compiler_flags~nmedit -s $output_objdir/${libname}-symbols.expsym ${lib}' + ;; + *) + ld_shlibs=no + ;; + esac + fi + ;; + + dgux*) + archive_cmds='$LD -G -h $soname -o $lib $libobjs $deplibs $linker_flags' + hardcode_libdir_flag_spec='-L$libdir' + hardcode_shlibpath_var=no + ;; + + freebsd1*) + ld_shlibs=no + ;; + + # FreeBSD 2.2.[012] allows us to include c++rt0.o to get C++ constructor + # support. Future versions do this automatically, but an explicit c++rt0.o + # does not break anything, and helps significantly (at the cost of a little + # extra space). + freebsd2.2*) + archive_cmds='$LD -Bshareable -o $lib $libobjs $deplibs $linker_flags /usr/lib/c++rt0.o' + hardcode_libdir_flag_spec='-R$libdir' + hardcode_direct=yes + hardcode_shlibpath_var=no + ;; + + # Unfortunately, older versions of FreeBSD 2 do not have this feature. + freebsd2*) + archive_cmds='$LD -Bshareable -o $lib $libobjs $deplibs $linker_flags' + hardcode_direct=yes + hardcode_minus_L=yes + hardcode_shlibpath_var=no + ;; + + # FreeBSD 3 and greater uses gcc -shared to do shared libraries. + freebsd* | kfreebsd*-gnu | dragonfly*) + archive_cmds='$CC -shared -o $lib $libobjs $deplibs $compiler_flags' + hardcode_libdir_flag_spec='-R$libdir' + hardcode_direct=yes + hardcode_shlibpath_var=no + ;; + + hpux9*) + if test "$GCC" = yes; then + archive_cmds='$rm $output_objdir/$soname~$CC -shared -fPIC ${wl}+b ${wl}$install_libdir -o $output_objdir/$soname $libobjs $deplibs $compiler_flags~test $output_objdir/$soname = $lib || mv $output_objdir/$soname $lib' + else + archive_cmds='$rm $output_objdir/$soname~$LD -b +b $install_libdir -o $output_objdir/$soname $libobjs $deplibs $linker_flags~test $output_objdir/$soname = $lib || mv $output_objdir/$soname $lib' + fi + hardcode_libdir_flag_spec='${wl}+b ${wl}$libdir' + hardcode_libdir_separator=: + hardcode_direct=yes + + # hardcode_minus_L: Not really in the search PATH, + # but as the default location of the library. + hardcode_minus_L=yes + export_dynamic_flag_spec='${wl}-E' + ;; + + hpux10*) + if test "$GCC" = yes -a "$with_gnu_ld" = no; then + archive_cmds='$CC -shared -fPIC ${wl}+h ${wl}$soname ${wl}+b ${wl}$install_libdir -o $lib $libobjs $deplibs $compiler_flags' + else + archive_cmds='$LD -b +h $soname +b $install_libdir -o $lib $libobjs $deplibs $linker_flags' + fi + if test "$with_gnu_ld" = no; then + hardcode_libdir_flag_spec='${wl}+b ${wl}$libdir' + hardcode_libdir_separator=: + + hardcode_direct=yes + export_dynamic_flag_spec='${wl}-E' + + # hardcode_minus_L: Not really in the search PATH, + # but as the default location of the library. + hardcode_minus_L=yes + fi + ;; + + hpux11*) + if test "$GCC" = yes -a "$with_gnu_ld" = no; then + case $host_cpu in + hppa*64*) + archive_cmds='$CC -shared ${wl}+h ${wl}$soname -o $lib $libobjs $deplibs $compiler_flags' + ;; + ia64*) + archive_cmds='$CC -shared ${wl}+h ${wl}$soname ${wl}+nodefaultrpath -o $lib $libobjs $deplibs $compiler_flags' + ;; + *) + archive_cmds='$CC -shared -fPIC ${wl}+h ${wl}$soname ${wl}+b ${wl}$install_libdir -o $lib $libobjs $deplibs $compiler_flags' + ;; + esac + else + case $host_cpu in + hppa*64*) + archive_cmds='$CC -b ${wl}+h ${wl}$soname -o $lib $libobjs $deplibs $compiler_flags' + ;; + ia64*) + archive_cmds='$CC -b ${wl}+h ${wl}$soname ${wl}+nodefaultrpath -o $lib $libobjs $deplibs $compiler_flags' + ;; + *) + archive_cmds='$CC -b ${wl}+h ${wl}$soname ${wl}+b ${wl}$install_libdir -o $lib $libobjs $deplibs $compiler_flags' + ;; + esac + fi + if test "$with_gnu_ld" = no; then + hardcode_libdir_flag_spec='${wl}+b ${wl}$libdir' + hardcode_libdir_separator=: + + case $host_cpu in + hppa*64*|ia64*) + hardcode_libdir_flag_spec_ld='+b $libdir' + hardcode_direct=no + hardcode_shlibpath_var=no + ;; + *) + hardcode_direct=yes + export_dynamic_flag_spec='${wl}-E' + + # hardcode_minus_L: Not really in the search PATH, + # but as the default location of the library. + hardcode_minus_L=yes + ;; + esac + fi + ;; + + irix5* | irix6* | nonstopux*) + if test "$GCC" = yes; then + archive_cmds='$CC -shared $libobjs $deplibs $compiler_flags ${wl}-soname ${wl}$soname `test -n "$verstring" && echo ${wl}-set_version ${wl}$verstring` ${wl}-update_registry ${wl}${output_objdir}/so_locations -o $lib' + else + archive_cmds='$LD -shared $libobjs $deplibs $linker_flags -soname $soname `test -n "$verstring" && echo -set_version $verstring` -update_registry ${output_objdir}/so_locations -o $lib' + hardcode_libdir_flag_spec_ld='-rpath $libdir' + fi + hardcode_libdir_flag_spec='${wl}-rpath ${wl}$libdir' + hardcode_libdir_separator=: + link_all_deplibs=yes + ;; + + netbsd*) + if echo __ELF__ | $CC -E - | grep __ELF__ >/dev/null; then + archive_cmds='$LD -Bshareable -o $lib $libobjs $deplibs $linker_flags' # a.out + else + archive_cmds='$LD -shared -o $lib $libobjs $deplibs $linker_flags' # ELF + fi + hardcode_libdir_flag_spec='-R$libdir' + hardcode_direct=yes + hardcode_shlibpath_var=no + ;; + + newsos6) + archive_cmds='$LD -G -h $soname -o $lib $libobjs $deplibs $linker_flags' + hardcode_direct=yes + hardcode_libdir_flag_spec='${wl}-rpath ${wl}$libdir' + hardcode_libdir_separator=: + hardcode_shlibpath_var=no + ;; + + openbsd*) + hardcode_direct=yes + hardcode_shlibpath_var=no + if test -z "`echo __ELF__ | $CC -E - | grep __ELF__`" || test "$host_os-$host_cpu" = "openbsd2.8-powerpc"; then + archive_cmds='$CC -shared $pic_flag -o $lib $libobjs $deplibs $compiler_flags' + archive_expsym_cmds='$CC -shared $pic_flag -o $lib $libobjs $deplibs $compiler_flags ${wl}-retain-symbols-file,$export_symbols' + hardcode_libdir_flag_spec='${wl}-rpath,$libdir' + export_dynamic_flag_spec='${wl}-E' + else + case $host_os in + openbsd[01].* | openbsd2.[0-7] | openbsd2.[0-7].*) + archive_cmds='$LD -Bshareable -o $lib $libobjs $deplibs $linker_flags' + hardcode_libdir_flag_spec='-R$libdir' + ;; + *) + archive_cmds='$CC -shared $pic_flag -o $lib $libobjs $deplibs $compiler_flags' + hardcode_libdir_flag_spec='${wl}-rpath,$libdir' + ;; + esac + fi + ;; + + os2*) + hardcode_libdir_flag_spec='-L$libdir' + hardcode_minus_L=yes + allow_undefined_flag=unsupported + archive_cmds='$echo "LIBRARY $libname INITINSTANCE" > $output_objdir/$libname.def~$echo "DESCRIPTION \"$libname\"" >> $output_objdir/$libname.def~$echo DATA >> $output_objdir/$libname.def~$echo " SINGLE NONSHARED" >> $output_objdir/$libname.def~$echo EXPORTS >> $output_objdir/$libname.def~emxexp $libobjs >> $output_objdir/$libname.def~$CC -Zdll -Zcrtdll -o $lib $libobjs $deplibs $compiler_flags $output_objdir/$libname.def' + old_archive_From_new_cmds='emximp -o $output_objdir/$libname.a $output_objdir/$libname.def' + ;; + + osf3*) + if test "$GCC" = yes; then + allow_undefined_flag=' ${wl}-expect_unresolved ${wl}\*' + archive_cmds='$CC -shared${allow_undefined_flag} $libobjs $deplibs $compiler_flags ${wl}-soname ${wl}$soname `test -n "$verstring" && echo ${wl}-set_version ${wl}$verstring` ${wl}-update_registry ${wl}${output_objdir}/so_locations -o $lib' + else + allow_undefined_flag=' -expect_unresolved \*' + archive_cmds='$LD -shared${allow_undefined_flag} $libobjs $deplibs $linker_flags -soname $soname `test -n "$verstring" && echo -set_version $verstring` -update_registry ${output_objdir}/so_locations -o $lib' + fi + hardcode_libdir_flag_spec='${wl}-rpath ${wl}$libdir' + hardcode_libdir_separator=: + ;; + + osf4* | osf5*) # as osf3* with the addition of -msym flag + if test "$GCC" = yes; then + allow_undefined_flag=' ${wl}-expect_unresolved ${wl}\*' + archive_cmds='$CC -shared${allow_undefined_flag} $libobjs $deplibs $compiler_flags ${wl}-msym ${wl}-soname ${wl}$soname `test -n "$verstring" && echo ${wl}-set_version ${wl}$verstring` ${wl}-update_registry ${wl}${output_objdir}/so_locations -o $lib' + hardcode_libdir_flag_spec='${wl}-rpath ${wl}$libdir' + else + allow_undefined_flag=' -expect_unresolved \*' + archive_cmds='$LD -shared${allow_undefined_flag} $libobjs $deplibs $linker_flags -msym -soname $soname `test -n "$verstring" && echo -set_version $verstring` -update_registry ${output_objdir}/so_locations -o $lib' + archive_expsym_cmds='for i in `cat $export_symbols`; do printf "%s %s\\n" -exported_symbol "\$i" >> $lib.exp; done; echo "-hidden">> $lib.exp~ + $LD -shared${allow_undefined_flag} -input $lib.exp $linker_flags $libobjs $deplibs -soname $soname `test -n "$verstring" && echo -set_version $verstring` -update_registry ${output_objdir}/so_locations -o $lib~$rm $lib.exp' + + # Both c and cxx compiler support -rpath directly + hardcode_libdir_flag_spec='-rpath $libdir' + fi + hardcode_libdir_separator=: + ;; + + solaris*) + no_undefined_flag=' -z text' + if test "$GCC" = yes; then + wlarc='${wl}' + archive_cmds='$CC -shared ${wl}-h ${wl}$soname -o $lib $libobjs $deplibs $compiler_flags' + archive_expsym_cmds='$echo "{ global:" > $lib.exp~cat $export_symbols | $SED -e "s/\(.*\)/\1;/" >> $lib.exp~$echo "local: *; };" >> $lib.exp~ + $CC -shared ${wl}-M ${wl}$lib.exp ${wl}-h ${wl}$soname -o $lib $libobjs $deplibs $compiler_flags~$rm $lib.exp' + else + wlarc='' + archive_cmds='$LD -G${allow_undefined_flag} -h $soname -o $lib $libobjs $deplibs $linker_flags' + archive_expsym_cmds='$echo "{ global:" > $lib.exp~cat $export_symbols | $SED -e "s/\(.*\)/\1;/" >> $lib.exp~$echo "local: *; };" >> $lib.exp~ + $LD -G${allow_undefined_flag} -M $lib.exp -h $soname -o $lib $libobjs $deplibs $linker_flags~$rm $lib.exp' + fi + hardcode_libdir_flag_spec='-R$libdir' + hardcode_shlibpath_var=no + case $host_os in + solaris2.[0-5] | solaris2.[0-5].*) ;; + *) + # The compiler driver will combine linker options so we + # cannot just pass the convience library names through + # without $wl, iff we do not link with $LD. + # Luckily, gcc supports the same syntax we need for Sun Studio. + # Supported since Solaris 2.6 (maybe 2.5.1?) + case $wlarc in + '') + whole_archive_flag_spec='-z allextract$convenience -z defaultextract' ;; + *) + whole_archive_flag_spec='${wl}-z ${wl}allextract`for conv in $convenience\"\"; do test -n \"$conv\" && new_convenience=\"$new_convenience,$conv\"; done; $echo \"$new_convenience\"` ${wl}-z ${wl}defaultextract' ;; + esac ;; + esac + link_all_deplibs=yes + ;; + + sunos4*) + if test "x$host_vendor" = xsequent; then + # Use $CC to link under sequent, because it throws in some extra .o + # files that make .init and .fini sections work. + archive_cmds='$CC -G ${wl}-h $soname -o $lib $libobjs $deplibs $compiler_flags' + else + archive_cmds='$LD -assert pure-text -Bstatic -o $lib $libobjs $deplibs $linker_flags' + fi + hardcode_libdir_flag_spec='-L$libdir' + hardcode_direct=yes + hardcode_minus_L=yes + hardcode_shlibpath_var=no + ;; + + sysv4) + case $host_vendor in + sni) + archive_cmds='$LD -G -h $soname -o $lib $libobjs $deplibs $linker_flags' + hardcode_direct=yes # is this really true??? + ;; + siemens) + ## LD is ld it makes a PLAMLIB + ## CC just makes a GrossModule. + archive_cmds='$LD -G -o $lib $libobjs $deplibs $linker_flags' + reload_cmds='$CC -r -o $output$reload_objs' + hardcode_direct=no + ;; + motorola) + archive_cmds='$LD -G -h $soname -o $lib $libobjs $deplibs $linker_flags' + hardcode_direct=no #Motorola manual says yes, but my tests say they lie + ;; + esac + runpath_var='LD_RUN_PATH' + hardcode_shlibpath_var=no + ;; + + sysv4.3*) + archive_cmds='$LD -G -h $soname -o $lib $libobjs $deplibs $linker_flags' + hardcode_shlibpath_var=no + export_dynamic_flag_spec='-Bexport' + ;; + + sysv4*MP*) + if test -d /usr/nec; then + archive_cmds='$LD -G -h $soname -o $lib $libobjs $deplibs $linker_flags' + hardcode_shlibpath_var=no + runpath_var=LD_RUN_PATH + hardcode_runpath_var=yes + ld_shlibs=yes + fi + ;; + + sysv4*uw2* | sysv5OpenUNIX* | sysv5UnixWare7.[01].[10]* | unixware7*) + no_undefined_flag='${wl}-z,text' + archive_cmds_need_lc=no + hardcode_shlibpath_var=no + runpath_var='LD_RUN_PATH' + + if test "$GCC" = yes; then + archive_cmds='$CC -shared ${wl}-h,$soname -o $lib $libobjs $deplibs $compiler_flags' + archive_expsym_cmds='$CC -shared ${wl}-Bexport:$export_symbols ${wl}-h,$soname -o $lib $libobjs $deplibs $compiler_flags' + else + archive_cmds='$CC -G ${wl}-h,$soname -o $lib $libobjs $deplibs $compiler_flags' + archive_expsym_cmds='$CC -G ${wl}-Bexport:$export_symbols ${wl}-h,$soname -o $lib $libobjs $deplibs $compiler_flags' + fi + ;; + + sysv5* | sco3.2v5* | sco5v6*) + # Note: We can NOT use -z defs as we might desire, because we do not + # link with -lc, and that would cause any symbols used from libc to + # always be unresolved, which means just about no library would + # ever link correctly. If we're not using GNU ld we use -z text + # though, which does catch some bad symbols but isn't as heavy-handed + # as -z defs. + no_undefined_flag='${wl}-z,text' + allow_undefined_flag='${wl}-z,nodefs' + archive_cmds_need_lc=no + hardcode_shlibpath_var=no + hardcode_libdir_flag_spec='`test -z "$SCOABSPATH" && echo ${wl}-R,$libdir`' + hardcode_libdir_separator=':' + link_all_deplibs=yes + export_dynamic_flag_spec='${wl}-Bexport' + runpath_var='LD_RUN_PATH' + + if test "$GCC" = yes; then + archive_cmds='$CC -shared ${wl}-h,\${SCOABSPATH:+${install_libdir}/}$soname -o $lib $libobjs $deplibs $compiler_flags' + archive_expsym_cmds='$CC -shared ${wl}-Bexport:$export_symbols ${wl}-h,\${SCOABSPATH:+${install_libdir}/}$soname -o $lib $libobjs $deplibs $compiler_flags' + else + archive_cmds='$CC -G ${wl}-h,\${SCOABSPATH:+${install_libdir}/}$soname -o $lib $libobjs $deplibs $compiler_flags' + archive_expsym_cmds='$CC -G ${wl}-Bexport:$export_symbols ${wl}-h,\${SCOABSPATH:+${install_libdir}/}$soname -o $lib $libobjs $deplibs $compiler_flags' + fi + ;; + + uts4*) + archive_cmds='$LD -G -h $soname -o $lib $libobjs $deplibs $linker_flags' + hardcode_libdir_flag_spec='-L$libdir' + hardcode_shlibpath_var=no + ;; + + *) + ld_shlibs=no + ;; + esac + fi + +echo "$as_me:$LINENO: result: $ld_shlibs" >&5 +echo "${ECHO_T}$ld_shlibs" >&6 +test "$ld_shlibs" = no && can_build_shared=no + +# +# Do we need to explicitly link libc? +# +case "x$archive_cmds_need_lc" in +x|xyes) + # Assume -lc should be added + archive_cmds_need_lc=yes + + if test "$enable_shared" = yes && test "$GCC" = yes; then + case $archive_cmds in + *'~'*) + # FIXME: we may have to deal with multi-command sequences. + ;; + '$CC '*) + # Test whether the compiler implicitly links with -lc since on some + # systems, -lgcc has to come before -lc. If gcc already passes -lc + # to ld, don't add -lc before -lgcc. + echo "$as_me:$LINENO: checking whether -lc should be explicitly linked in" >&5 +echo $ECHO_N "checking whether -lc should be explicitly linked in... $ECHO_C" >&6 + $rm conftest* + printf "$lt_simple_compile_test_code" > conftest.$ac_ext + + if { (eval echo "$as_me:$LINENO: \"$ac_compile\"") >&5 + (eval $ac_compile) 2>&5 + ac_status=$? + echo "$as_me:$LINENO: \$? = $ac_status" >&5 + (exit $ac_status); } 2>conftest.err; then + soname=conftest + lib=conftest + libobjs=conftest.$ac_objext + deplibs= + wl=$lt_prog_compiler_wl + pic_flag=$lt_prog_compiler_pic + compiler_flags=-v + linker_flags=-v + verstring= + output_objdir=. + libname=conftest + lt_save_allow_undefined_flag=$allow_undefined_flag + allow_undefined_flag= + if { (eval echo "$as_me:$LINENO: \"$archive_cmds 2\>\&1 \| grep \" -lc \" \>/dev/null 2\>\&1\"") >&5 + (eval $archive_cmds 2\>\&1 \| grep \" -lc \" \>/dev/null 2\>\&1) 2>&5 + ac_status=$? + echo "$as_me:$LINENO: \$? = $ac_status" >&5 + (exit $ac_status); } + then + archive_cmds_need_lc=no + else + archive_cmds_need_lc=yes + fi + allow_undefined_flag=$lt_save_allow_undefined_flag + else + cat conftest.err 1>&5 + fi + $rm conftest* + echo "$as_me:$LINENO: result: $archive_cmds_need_lc" >&5 +echo "${ECHO_T}$archive_cmds_need_lc" >&6 + ;; + esac + fi + ;; +esac + +echo "$as_me:$LINENO: checking dynamic linker characteristics" >&5 +echo $ECHO_N "checking dynamic linker characteristics... $ECHO_C" >&6 +library_names_spec= +libname_spec='lib$name' +soname_spec= +shrext_cmds=".so" +postinstall_cmds= +postuninstall_cmds= +finish_cmds= +finish_eval= +shlibpath_var= +shlibpath_overrides_runpath=unknown +version_type=none +dynamic_linker="$host_os ld.so" +sys_lib_dlsearch_path_spec="/lib /usr/lib" +if test "$GCC" = yes; then + sys_lib_search_path_spec=`$CC -print-search-dirs | grep "^libraries:" | $SED -e "s/^libraries://" -e "s,=/,/,g"` + if echo "$sys_lib_search_path_spec" | grep ';' >/dev/null ; then + # if the path contains ";" then we assume it to be the separator + # otherwise default to the standard path separator (i.e. ":") - it is + # assumed that no part of a normal pathname contains ";" but that should + # okay in the real world where ";" in dirpaths is itself problematic. + sys_lib_search_path_spec=`echo "$sys_lib_search_path_spec" | $SED -e 's/;/ /g'` + else + sys_lib_search_path_spec=`echo "$sys_lib_search_path_spec" | $SED -e "s/$PATH_SEPARATOR/ /g"` + fi +else + sys_lib_search_path_spec="/lib /usr/lib /usr/local/lib" +fi +need_lib_prefix=unknown +hardcode_into_libs=no + +# when you set need_version to no, make sure it does not cause -set_version +# flags to be left without arguments +need_version=unknown + +case $host_os in +aix3*) + version_type=linux + library_names_spec='${libname}${release}${shared_ext}$versuffix $libname.a' + shlibpath_var=LIBPATH + + # AIX 3 has no versioning support, so we append a major version to the name. + soname_spec='${libname}${release}${shared_ext}$major' + ;; + +aix4* | aix5*) + version_type=linux + need_lib_prefix=no + need_version=no + hardcode_into_libs=yes + if test "$host_cpu" = ia64; then + # AIX 5 supports IA64 + library_names_spec='${libname}${release}${shared_ext}$major ${libname}${release}${shared_ext}$versuffix $libname${shared_ext}' + shlibpath_var=LD_LIBRARY_PATH + else + # With GCC up to 2.95.x, collect2 would create an import file + # for dependence libraries. The import file would start with + # the line `#! .'. This would cause the generated library to + # depend on `.', always an invalid library. This was fixed in + # development snapshots of GCC prior to 3.0. + case $host_os in + aix4 | aix4.[01] | aix4.[01].*) + if { echo '#if __GNUC__ > 2 || (__GNUC__ == 2 && __GNUC_MINOR__ >= 97)' + echo ' yes ' + echo '#endif'; } | ${CC} -E - | grep yes > /dev/null; then + : + else + can_build_shared=no + fi + ;; + esac + # AIX (on Power*) has no versioning support, so currently we can not hardcode correct + # soname into executable. Probably we can add versioning support to + # collect2, so additional links can be useful in future. + if test "$aix_use_runtimelinking" = yes; then + # If using run time linking (on AIX 4.2 or later) use lib<name>.so + # instead of lib<name>.a to let people know that these are not + # typical AIX shared libraries. + library_names_spec='${libname}${release}${shared_ext}$versuffix ${libname}${release}${shared_ext}$major $libname${shared_ext}' + else + # We preserve .a as extension for shared libraries through AIX4.2 + # and later when we are not doing run time linking. + library_names_spec='${libname}${release}.a $libname.a' + soname_spec='${libname}${release}${shared_ext}$major' + fi + shlibpath_var=LIBPATH + fi + ;; + +amigaos*) + library_names_spec='$libname.ixlibrary $libname.a' + # Create ${libname}_ixlibrary.a entries in /sys/libs. + finish_eval='for lib in `ls $libdir/*.ixlibrary 2>/dev/null`; do libname=`$echo "X$lib" | $Xsed -e '\''s%^.*/\([^/]*\)\.ixlibrary$%\1%'\''`; test $rm /sys/libs/${libname}_ixlibrary.a; $show "cd /sys/libs && $LN_S $lib ${libname}_ixlibrary.a"; cd /sys/libs && $LN_S $lib ${libname}_ixlibrary.a || exit 1; done' + ;; + +beos*) + library_names_spec='${libname}${shared_ext}' + dynamic_linker="$host_os ld.so" + shlibpath_var=LIBRARY_PATH + ;; + +bsdi[45]*) + version_type=linux + need_version=no + library_names_spec='${libname}${release}${shared_ext}$versuffix ${libname}${release}${shared_ext}$major $libname${shared_ext}' + soname_spec='${libname}${release}${shared_ext}$major' + finish_cmds='PATH="\$PATH:/sbin" ldconfig $libdir' + shlibpath_var=LD_LIBRARY_PATH + sys_lib_search_path_spec="/shlib /usr/lib /usr/X11/lib /usr/contrib/lib /lib /usr/local/lib" + sys_lib_dlsearch_path_spec="/shlib /usr/lib /usr/local/lib" + # the default ld.so.conf also contains /usr/contrib/lib and + # /usr/X11R6/lib (/usr/X11 is a link to /usr/X11R6), but let us allow + # libtool to hard-code these into programs + ;; + +cygwin* | mingw* | pw32*) + version_type=windows + shrext_cmds=".dll" + need_version=no + need_lib_prefix=no + + case $GCC,$host_os in + yes,cygwin* | yes,mingw* | yes,pw32*) + library_names_spec='$libname.dll.a' + # DLL is installed to $(libdir)/../bin by postinstall_cmds + postinstall_cmds='base_file=`basename \${file}`~ + dlpath=`$SHELL 2>&1 -c '\''. $dir/'\''\${base_file}'\''i;echo \$dlname'\''`~ + dldir=$destdir/`dirname \$dlpath`~ + test -d \$dldir || mkdir -p \$dldir~ + $install_prog $dir/$dlname \$dldir/$dlname~ + chmod a+x \$dldir/$dlname' + postuninstall_cmds='dldll=`$SHELL 2>&1 -c '\''. $file; echo \$dlname'\''`~ + dlpath=$dir/\$dldll~ + $rm \$dlpath' + shlibpath_overrides_runpath=yes + + case $host_os in + cygwin*) + # Cygwin DLLs use 'cyg' prefix rather than 'lib' + soname_spec='`echo ${libname} | sed -e 's/^lib/cyg/'``echo ${release} | $SED -e 's/[.]/-/g'`${versuffix}${shared_ext}' + sys_lib_search_path_spec="/usr/lib /lib/w32api /lib /usr/local/lib" + ;; + mingw*) + # MinGW DLLs use traditional 'lib' prefix + soname_spec='${libname}`echo ${release} | $SED -e 's/[.]/-/g'`${versuffix}${shared_ext}' + sys_lib_search_path_spec=`$CC -print-search-dirs | grep "^libraries:" | $SED -e "s/^libraries://" -e "s,=/,/,g"` + if echo "$sys_lib_search_path_spec" | grep ';[c-zC-Z]:/' >/dev/null; then + # It is most probably a Windows format PATH printed by + # mingw gcc, but we are running on Cygwin. Gcc prints its search + # path with ; separators, and with drive letters. We can handle the + # drive letters (cygwin fileutils understands them), so leave them, + # especially as we might pass files found there to a mingw objdump, + # which wouldn't understand a cygwinified path. Ahh. + sys_lib_search_path_spec=`echo "$sys_lib_search_path_spec" | $SED -e 's/;/ /g'` + else + sys_lib_search_path_spec=`echo "$sys_lib_search_path_spec" | $SED -e "s/$PATH_SEPARATOR/ /g"` + fi + ;; + pw32*) + # pw32 DLLs use 'pw' prefix rather than 'lib' + library_names_spec='`echo ${libname} | sed -e 's/^lib/pw/'``echo ${release} | $SED -e 's/[.]/-/g'`${versuffix}${shared_ext}' + ;; + esac + ;; + + *) + library_names_spec='${libname}`echo ${release} | $SED -e 's/[.]/-/g'`${versuffix}${shared_ext} $libname.lib' + ;; + esac + dynamic_linker='Win32 ld.exe' + # FIXME: first we should search . and the directory the executable is in + shlibpath_var=PATH + ;; + +darwin* | rhapsody*) + dynamic_linker="$host_os dyld" + version_type=darwin + need_lib_prefix=no + need_version=no + library_names_spec='${libname}${release}${versuffix}$shared_ext ${libname}${release}${major}$shared_ext ${libname}$shared_ext' + soname_spec='${libname}${release}${major}$shared_ext' + shlibpath_overrides_runpath=yes + shlibpath_var=DYLD_LIBRARY_PATH + shrext_cmds='`test .$module = .yes && echo .so || echo .dylib`' + # Apple's gcc prints 'gcc -print-search-dirs' doesn't operate the same. + if test "$GCC" = yes; then + sys_lib_search_path_spec=`$CC -print-search-dirs | tr "\n" "$PATH_SEPARATOR" | sed -e 's/libraries:/@libraries:/' | tr "@" "\n" | grep "^libraries:" | sed -e "s/^libraries://" -e "s,=/,/,g" -e "s,$PATH_SEPARATOR, ,g" -e "s,.*,& /lib /usr/lib /usr/local/lib,g"` + else + sys_lib_search_path_spec='/lib /usr/lib /usr/local/lib' + fi + sys_lib_dlsearch_path_spec='/usr/local/lib /lib /usr/lib' + ;; + +dgux*) + version_type=linux + need_lib_prefix=no + need_version=no + library_names_spec='${libname}${release}${shared_ext}$versuffix ${libname}${release}${shared_ext}$major $libname$shared_ext' + soname_spec='${libname}${release}${shared_ext}$major' + shlibpath_var=LD_LIBRARY_PATH + ;; + +freebsd1*) + dynamic_linker=no + ;; + +kfreebsd*-gnu) + version_type=linux + need_lib_prefix=no + need_version=no + library_names_spec='${libname}${release}${shared_ext}$versuffix ${libname}${release}${shared_ext}$major ${libname}${shared_ext}' + soname_spec='${libname}${release}${shared_ext}$major' + shlibpath_var=LD_LIBRARY_PATH + shlibpath_overrides_runpath=no + hardcode_into_libs=yes + dynamic_linker='GNU ld.so' + ;; + +freebsd* | dragonfly*) + # DragonFly does not have aout. When/if they implement a new + # versioning mechanism, adjust this. + if test -x /usr/bin/objformat; then + objformat=`/usr/bin/objformat` + else + case $host_os in + freebsd[123]*) objformat=aout ;; + *) objformat=elf ;; + esac + fi + version_type=freebsd-$objformat + case $version_type in + freebsd-elf*) + library_names_spec='${libname}${release}${shared_ext}$versuffix ${libname}${release}${shared_ext} $libname${shared_ext}' + need_version=no + need_lib_prefix=no + ;; + freebsd-*) + library_names_spec='${libname}${release}${shared_ext}$versuffix $libname${shared_ext}$versuffix' + need_version=yes + ;; + esac + shlibpath_var=LD_LIBRARY_PATH + case $host_os in + freebsd2*) + shlibpath_overrides_runpath=yes + ;; + freebsd3.[01]* | freebsdelf3.[01]*) + shlibpath_overrides_runpath=yes + hardcode_into_libs=yes + ;; + freebsd3.[2-9]* | freebsdelf3.[2-9]* | \ + freebsd4.[0-5] | freebsdelf4.[0-5] | freebsd4.1.1 | freebsdelf4.1.1) + shlibpath_overrides_runpath=no + hardcode_into_libs=yes + ;; + freebsd*) # from 4.6 on + shlibpath_overrides_runpath=yes + hardcode_into_libs=yes + ;; + esac + ;; + +gnu*) + version_type=linux + need_lib_prefix=no + need_version=no + library_names_spec='${libname}${release}${shared_ext}$versuffix ${libname}${release}${shared_ext}${major} ${libname}${shared_ext}' + soname_spec='${libname}${release}${shared_ext}$major' + shlibpath_var=LD_LIBRARY_PATH + hardcode_into_libs=yes + ;; + +hpux9* | hpux10* | hpux11*) + # Give a soname corresponding to the major version so that dld.sl refuses to + # link against other versions. + version_type=sunos + need_lib_prefix=no + need_version=no + case $host_cpu in + ia64*) + shrext_cmds='.so' + hardcode_into_libs=yes + dynamic_linker="$host_os dld.so" + shlibpath_var=LD_LIBRARY_PATH + shlibpath_overrides_runpath=yes # Unless +noenvvar is specified. + library_names_spec='${libname}${release}${shared_ext}$versuffix ${libname}${release}${shared_ext}$major $libname${shared_ext}' + soname_spec='${libname}${release}${shared_ext}$major' + if test "X$HPUX_IA64_MODE" = X32; then + sys_lib_search_path_spec="/usr/lib/hpux32 /usr/local/lib/hpux32 /usr/local/lib" + else + sys_lib_search_path_spec="/usr/lib/hpux64 /usr/local/lib/hpux64" + fi + sys_lib_dlsearch_path_spec=$sys_lib_search_path_spec + ;; + hppa*64*) + shrext_cmds='.sl' + hardcode_into_libs=yes + dynamic_linker="$host_os dld.sl" + shlibpath_var=LD_LIBRARY_PATH # How should we handle SHLIB_PATH + shlibpath_overrides_runpath=yes # Unless +noenvvar is specified. + library_names_spec='${libname}${release}${shared_ext}$versuffix ${libname}${release}${shared_ext}$major $libname${shared_ext}' + soname_spec='${libname}${release}${shared_ext}$major' + sys_lib_search_path_spec="/usr/lib/pa20_64 /usr/ccs/lib/pa20_64" + sys_lib_dlsearch_path_spec=$sys_lib_search_path_spec + ;; + *) + shrext_cmds='.sl' + dynamic_linker="$host_os dld.sl" + shlibpath_var=SHLIB_PATH + shlibpath_overrides_runpath=no # +s is required to enable SHLIB_PATH + library_names_spec='${libname}${release}${shared_ext}$versuffix ${libname}${release}${shared_ext}$major $libname${shared_ext}' + soname_spec='${libname}${release}${shared_ext}$major' + ;; + esac + # HP-UX runs *really* slowly unless shared libraries are mode 555. + postinstall_cmds='chmod 555 $lib' + ;; + +interix3*) + version_type=linux + need_lib_prefix=no + need_version=no + library_names_spec='${libname}${release}${shared_ext}$versuffix ${libname}${release}${shared_ext}$major ${libname}${shared_ext}' + soname_spec='${libname}${release}${shared_ext}$major' + dynamic_linker='Interix 3.x ld.so.1 (PE, like ELF)' + shlibpath_var=LD_LIBRARY_PATH + shlibpath_overrides_runpath=no + hardcode_into_libs=yes + ;; + +irix5* | irix6* | nonstopux*) + case $host_os in + nonstopux*) version_type=nonstopux ;; + *) + if test "$lt_cv_prog_gnu_ld" = yes; then + version_type=linux + else + version_type=irix + fi ;; + esac + need_lib_prefix=no + need_version=no + soname_spec='${libname}${release}${shared_ext}$major' + library_names_spec='${libname}${release}${shared_ext}$versuffix ${libname}${release}${shared_ext}$major ${libname}${release}${shared_ext} $libname${shared_ext}' + case $host_os in + irix5* | nonstopux*) + libsuff= shlibsuff= + ;; + *) + case $LD in # libtool.m4 will add one of these switches to LD + *-32|*"-32 "|*-melf32bsmip|*"-melf32bsmip ") + libsuff= shlibsuff= libmagic=32-bit;; + *-n32|*"-n32 "|*-melf32bmipn32|*"-melf32bmipn32 ") + libsuff=32 shlibsuff=N32 libmagic=N32;; + *-64|*"-64 "|*-melf64bmip|*"-melf64bmip ") + libsuff=64 shlibsuff=64 libmagic=64-bit;; + *) libsuff= shlibsuff= libmagic=never-match;; + esac + ;; + esac + shlibpath_var=LD_LIBRARY${shlibsuff}_PATH + shlibpath_overrides_runpath=no + sys_lib_search_path_spec="/usr/lib${libsuff} /lib${libsuff} /usr/local/lib${libsuff}" + sys_lib_dlsearch_path_spec="/usr/lib${libsuff} /lib${libsuff}" + hardcode_into_libs=yes + ;; + +# No shared lib support for Linux oldld, aout, or coff. +linux*oldld* | linux*aout* | linux*coff*) + dynamic_linker=no + ;; + +# This must be Linux ELF. +linux*) + version_type=linux + need_lib_prefix=no + need_version=no + library_names_spec='${libname}${release}${shared_ext}$versuffix ${libname}${release}${shared_ext}$major $libname${shared_ext}' + soname_spec='${libname}${release}${shared_ext}$major' + finish_cmds='PATH="\$PATH:/sbin" ldconfig -n $libdir' + shlibpath_var=LD_LIBRARY_PATH + shlibpath_overrides_runpath=no + # This implies no fast_install, which is unacceptable. + # Some rework will be needed to allow for fast_install + # before this can be enabled. + hardcode_into_libs=yes + + # find out which ABI we are using + libsuff= + case "$host_cpu" in + x86_64*|s390x*|powerpc64*) + echo '#line 8354 "configure"' > conftest.$ac_ext + if { (eval echo "$as_me:$LINENO: \"$ac_compile\"") >&5 + (eval $ac_compile) 2>&5 + ac_status=$? + echo "$as_me:$LINENO: \$? = $ac_status" >&5 + (exit $ac_status); }; then + case `/usr/bin/file conftest.$ac_objext` in + *64-bit*) + libsuff=64 + sys_lib_search_path_spec="/lib${libsuff} /usr/lib${libsuff} /usr/local/lib${libsuff}" + ;; + esac + fi + rm -rf conftest* + ;; + esac + + # Append ld.so.conf contents to the search path + if test -f /etc/ld.so.conf; then + lt_ld_extra=`awk '/^include / { system(sprintf("cd /etc; cat %s 2>/dev/null", \$2)); skip = 1; } { if (!skip) print \$0; skip = 0; }' < /etc/ld.so.conf | $SED -e 's/#.*//;s/[:, ]/ /g;s/=[^=]*$//;s/=[^= ]* / /g;/^$/d' | tr '\n' ' '` + sys_lib_dlsearch_path_spec="/lib${libsuff} /usr/lib${libsuff} $lt_ld_extra" + fi + + # We used to test for /lib/ld.so.1 and disable shared libraries on + # powerpc, because MkLinux only supported shared libraries with the + # GNU dynamic linker. Since this was broken with cross compilers, + # most powerpc-linux boxes support dynamic linking these days and + # people can always --disable-shared, the test was removed, and we + # assume the GNU/Linux dynamic linker is in use. + dynamic_linker='GNU/Linux ld.so' + ;; + +knetbsd*-gnu) + version_type=linux + need_lib_prefix=no + need_version=no + library_names_spec='${libname}${release}${shared_ext}$versuffix ${libname}${release}${shared_ext}$major ${libname}${shared_ext}' + soname_spec='${libname}${release}${shared_ext}$major' + shlibpath_var=LD_LIBRARY_PATH + shlibpath_overrides_runpath=no + hardcode_into_libs=yes + dynamic_linker='GNU ld.so' + ;; + +netbsd*) + version_type=sunos + need_lib_prefix=no + need_version=no + if echo __ELF__ | $CC -E - | grep __ELF__ >/dev/null; then + library_names_spec='${libname}${release}${shared_ext}$versuffix ${libname}${shared_ext}$versuffix' + finish_cmds='PATH="\$PATH:/sbin" ldconfig -m $libdir' + dynamic_linker='NetBSD (a.out) ld.so' + else + library_names_spec='${libname}${release}${shared_ext}$versuffix ${libname}${release}${shared_ext}$major ${libname}${shared_ext}' + soname_spec='${libname}${release}${shared_ext}$major' + dynamic_linker='NetBSD ld.elf_so' + fi + shlibpath_var=LD_LIBRARY_PATH + shlibpath_overrides_runpath=yes + hardcode_into_libs=yes + ;; + +newsos6) + version_type=linux + library_names_spec='${libname}${release}${shared_ext}$versuffix ${libname}${release}${shared_ext}$major $libname${shared_ext}' + shlibpath_var=LD_LIBRARY_PATH + shlibpath_overrides_runpath=yes + ;; + +nto-qnx*) + version_type=linux + need_lib_prefix=no + need_version=no + library_names_spec='${libname}${release}${shared_ext}$versuffix ${libname}${release}${shared_ext}$major $libname${shared_ext}' + soname_spec='${libname}${release}${shared_ext}$major' + shlibpath_var=LD_LIBRARY_PATH + shlibpath_overrides_runpath=yes + ;; + +openbsd*) + version_type=sunos + sys_lib_dlsearch_path_spec="/usr/lib" + need_lib_prefix=no + # Some older versions of OpenBSD (3.3 at least) *do* need versioned libs. + case $host_os in + openbsd3.3 | openbsd3.3.*) need_version=yes ;; + *) need_version=no ;; + esac + library_names_spec='${libname}${release}${shared_ext}$versuffix ${libname}${shared_ext}$versuffix' + finish_cmds='PATH="\$PATH:/sbin" ldconfig -m $libdir' + shlibpath_var=LD_LIBRARY_PATH + if test -z "`echo __ELF__ | $CC -E - | grep __ELF__`" || test "$host_os-$host_cpu" = "openbsd2.8-powerpc"; then + case $host_os in + openbsd2.[89] | openbsd2.[89].*) + shlibpath_overrides_runpath=no + ;; + *) + shlibpath_overrides_runpath=yes + ;; + esac + else + shlibpath_overrides_runpath=yes + fi + ;; + +os2*) + libname_spec='$name' + shrext_cmds=".dll" + need_lib_prefix=no + library_names_spec='$libname${shared_ext} $libname.a' + dynamic_linker='OS/2 ld.exe' + shlibpath_var=LIBPATH + ;; + +osf3* | osf4* | osf5*) + version_type=osf + need_lib_prefix=no + need_version=no + soname_spec='${libname}${release}${shared_ext}$major' + library_names_spec='${libname}${release}${shared_ext}$versuffix ${libname}${release}${shared_ext}$major $libname${shared_ext}' + shlibpath_var=LD_LIBRARY_PATH + sys_lib_search_path_spec="/usr/shlib /usr/ccs/lib /usr/lib/cmplrs/cc /usr/lib /usr/local/lib /var/shlib" + sys_lib_dlsearch_path_spec="$sys_lib_search_path_spec" + ;; + +solaris*) + version_type=linux + need_lib_prefix=no + need_version=no + library_names_spec='${libname}${release}${shared_ext}$versuffix ${libname}${release}${shared_ext}$major $libname${shared_ext}' + soname_spec='${libname}${release}${shared_ext}$major' + shlibpath_var=LD_LIBRARY_PATH + shlibpath_overrides_runpath=yes + hardcode_into_libs=yes + # ldd complains unless libraries are executable + postinstall_cmds='chmod +x $lib' + ;; + +sunos4*) + version_type=sunos + library_names_spec='${libname}${release}${shared_ext}$versuffix ${libname}${shared_ext}$versuffix' + finish_cmds='PATH="\$PATH:/usr/etc" ldconfig $libdir' + shlibpath_var=LD_LIBRARY_PATH + shlibpath_overrides_runpath=yes + if test "$with_gnu_ld" = yes; then + need_lib_prefix=no + fi + need_version=yes + ;; + +sysv4 | sysv4.3*) + version_type=linux + library_names_spec='${libname}${release}${shared_ext}$versuffix ${libname}${release}${shared_ext}$major $libname${shared_ext}' + soname_spec='${libname}${release}${shared_ext}$major' + shlibpath_var=LD_LIBRARY_PATH + case $host_vendor in + sni) + shlibpath_overrides_runpath=no + need_lib_prefix=no + export_dynamic_flag_spec='${wl}-Blargedynsym' + runpath_var=LD_RUN_PATH + ;; + siemens) + need_lib_prefix=no + ;; + motorola) + need_lib_prefix=no + need_version=no + shlibpath_overrides_runpath=no + sys_lib_search_path_spec='/lib /usr/lib /usr/ccs/lib' + ;; + esac + ;; + +sysv4*MP*) + if test -d /usr/nec ;then + version_type=linux + library_names_spec='$libname${shared_ext}.$versuffix $libname${shared_ext}.$major $libname${shared_ext}' + soname_spec='$libname${shared_ext}.$major' + shlibpath_var=LD_LIBRARY_PATH + fi + ;; + +sysv5* | sco3.2v5* | sco5v6* | unixware* | OpenUNIX* | sysv4*uw2*) + version_type=freebsd-elf + need_lib_prefix=no + need_version=no + library_names_spec='${libname}${release}${shared_ext}$versuffix ${libname}${release}${shared_ext} $libname${shared_ext}' + soname_spec='${libname}${release}${shared_ext}$major' + shlibpath_var=LD_LIBRARY_PATH + hardcode_into_libs=yes + if test "$with_gnu_ld" = yes; then + sys_lib_search_path_spec='/usr/local/lib /usr/gnu/lib /usr/ccs/lib /usr/lib /lib' + shlibpath_overrides_runpath=no + else + sys_lib_search_path_spec='/usr/ccs/lib /usr/lib' + shlibpath_overrides_runpath=yes + case $host_os in + sco3.2v5*) + sys_lib_search_path_spec="$sys_lib_search_path_spec /lib" + ;; + esac + fi + sys_lib_dlsearch_path_spec='/usr/lib' + ;; + +uts4*) + version_type=linux + library_names_spec='${libname}${release}${shared_ext}$versuffix ${libname}${release}${shared_ext}$major $libname${shared_ext}' + soname_spec='${libname}${release}${shared_ext}$major' + shlibpath_var=LD_LIBRARY_PATH + ;; + +*) + dynamic_linker=no + ;; +esac +echo "$as_me:$LINENO: result: $dynamic_linker" >&5 +echo "${ECHO_T}$dynamic_linker" >&6 +test "$dynamic_linker" = no && can_build_shared=no + +variables_saved_for_relink="PATH $shlibpath_var $runpath_var" +if test "$GCC" = yes; then + variables_saved_for_relink="$variables_saved_for_relink GCC_EXEC_PREFIX COMPILER_PATH LIBRARY_PATH" +fi + +echo "$as_me:$LINENO: checking how to hardcode library paths into programs" >&5 +echo $ECHO_N "checking how to hardcode library paths into programs... $ECHO_C" >&6 +hardcode_action= +if test -n "$hardcode_libdir_flag_spec" || \ + test -n "$runpath_var" || \ + test "X$hardcode_automatic" = "Xyes" ; then + + # We can hardcode non-existant directories. + if test "$hardcode_direct" != no && + # If the only mechanism to avoid hardcoding is shlibpath_var, we + # have to relink, otherwise we might link with an installed library + # when we should be linking with a yet-to-be-installed one + ## test "$_LT_AC_TAGVAR(hardcode_shlibpath_var, )" != no && + test "$hardcode_minus_L" != no; then + # Linking always hardcodes the temporary library directory. + hardcode_action=relink + else + # We can link without hardcoding, and we can hardcode nonexisting dirs. + hardcode_action=immediate + fi +else + # We cannot hardcode anything, or else we can only hardcode existing + # directories. + hardcode_action=unsupported +fi +echo "$as_me:$LINENO: result: $hardcode_action" >&5 +echo "${ECHO_T}$hardcode_action" >&6 + +if test "$hardcode_action" = relink; then + # Fast installation is not supported + enable_fast_install=no +elif test "$shlibpath_overrides_runpath" = yes || + test "$enable_shared" = no; then + # Fast installation is not necessary + enable_fast_install=needless +fi + +striplib= +old_striplib= +echo "$as_me:$LINENO: checking whether stripping libraries is possible" >&5 +echo $ECHO_N "checking whether stripping libraries is possible... $ECHO_C" >&6 +if test -n "$STRIP" && $STRIP -V 2>&1 | grep "GNU strip" >/dev/null; then + test -z "$old_striplib" && old_striplib="$STRIP --strip-debug" + test -z "$striplib" && striplib="$STRIP --strip-unneeded" + echo "$as_me:$LINENO: result: yes" >&5 +echo "${ECHO_T}yes" >&6 +else +# FIXME - insert some real tests, host_os isn't really good enough + case $host_os in + darwin*) + if test -n "$STRIP" ; then + striplib="$STRIP -x" + echo "$as_me:$LINENO: result: yes" >&5 +echo "${ECHO_T}yes" >&6 + else + echo "$as_me:$LINENO: result: no" >&5 +echo "${ECHO_T}no" >&6 +fi + ;; + *) + echo "$as_me:$LINENO: result: no" >&5 +echo "${ECHO_T}no" >&6 + ;; + esac +fi + +if test "x$enable_dlopen" != xyes; then + enable_dlopen=unknown + enable_dlopen_self=unknown + enable_dlopen_self_static=unknown +else + lt_cv_dlopen=no + lt_cv_dlopen_libs= + + case $host_os in + beos*) + lt_cv_dlopen="load_add_on" + lt_cv_dlopen_libs= + lt_cv_dlopen_self=yes + ;; + + mingw* | pw32*) + lt_cv_dlopen="LoadLibrary" + lt_cv_dlopen_libs= + ;; + + cygwin*) + lt_cv_dlopen="dlopen" + lt_cv_dlopen_libs= + ;; + + darwin*) + # if libdl is installed we need to link against it + echo "$as_me:$LINENO: checking for dlopen in -ldl" >&5 +echo $ECHO_N "checking for dlopen in -ldl... $ECHO_C" >&6 +if test "${ac_cv_lib_dl_dlopen+set}" = set; then + echo $ECHO_N "(cached) $ECHO_C" >&6 +else + ac_check_lib_save_LIBS=$LIBS +LIBS="-ldl $LIBS" +cat >conftest.$ac_ext <<_ACEOF +/* confdefs.h. */ +_ACEOF +cat confdefs.h >>conftest.$ac_ext +cat >>conftest.$ac_ext <<_ACEOF +/* end confdefs.h. */ + +/* Override any gcc2 internal prototype to avoid an error. */ +#ifdef __cplusplus +extern "C" +#endif +/* We use char because int might match the return type of a gcc2 + builtin and then its argument prototype would still apply. */ +char dlopen (); +int +main () +{ +dlopen (); + ; + return 0; +} +_ACEOF +rm -f conftest.$ac_objext conftest$ac_exeext +if { (eval echo "$as_me:$LINENO: \"$ac_link\"") >&5 + (eval $ac_link) 2>conftest.er1 + ac_status=$? + grep -v '^ *+' conftest.er1 >conftest.err + rm -f conftest.er1 + cat conftest.err >&5 + echo "$as_me:$LINENO: \$? = $ac_status" >&5 + (exit $ac_status); } && + { ac_try='test -z "$ac_c_werror_flag" + || test ! -s conftest.err' + { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5 + (eval $ac_try) 2>&5 + ac_status=$? + echo "$as_me:$LINENO: \$? = $ac_status" >&5 + (exit $ac_status); }; } && + { ac_try='test -s conftest$ac_exeext' + { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5 + (eval $ac_try) 2>&5 + ac_status=$? + echo "$as_me:$LINENO: \$? = $ac_status" >&5 + (exit $ac_status); }; }; then + ac_cv_lib_dl_dlopen=yes +else + echo "$as_me: failed program was:" >&5 +sed 's/^/| /' conftest.$ac_ext >&5 + +ac_cv_lib_dl_dlopen=no +fi +rm -f conftest.err conftest.$ac_objext \ + conftest$ac_exeext conftest.$ac_ext +LIBS=$ac_check_lib_save_LIBS +fi +echo "$as_me:$LINENO: result: $ac_cv_lib_dl_dlopen" >&5 +echo "${ECHO_T}$ac_cv_lib_dl_dlopen" >&6 +if test $ac_cv_lib_dl_dlopen = yes; then + lt_cv_dlopen="dlopen" lt_cv_dlopen_libs="-ldl" +else + + lt_cv_dlopen="dyld" + lt_cv_dlopen_libs= + lt_cv_dlopen_self=yes + +fi + + ;; + + *) + echo "$as_me:$LINENO: checking for shl_load" >&5 +echo $ECHO_N "checking for shl_load... $ECHO_C" >&6 +if test "${ac_cv_func_shl_load+set}" = set; then + echo $ECHO_N "(cached) $ECHO_C" >&6 +else + cat >conftest.$ac_ext <<_ACEOF +/* confdefs.h. */ +_ACEOF +cat confdefs.h >>conftest.$ac_ext +cat >>conftest.$ac_ext <<_ACEOF +/* end confdefs.h. */ +/* Define shl_load to an innocuous variant, in case <limits.h> declares shl_load. + For example, HP-UX 11i <limits.h> declares gettimeofday. */ +#define shl_load innocuous_shl_load + +/* System header to define __stub macros and hopefully few prototypes, + which can conflict with char shl_load (); below. + Prefer <limits.h> to <assert.h> if __STDC__ is defined, since + <limits.h> exists even on freestanding compilers. */ + +#ifdef __STDC__ +# include <limits.h> +#else +# include <assert.h> +#endif + +#undef shl_load + +/* Override any gcc2 internal prototype to avoid an error. */ +#ifdef __cplusplus +extern "C" +{ +#endif +/* We use char because int might match the return type of a gcc2 + builtin and then its argument prototype would still apply. */ +char shl_load (); +/* The GNU C library defines this for functions which it implements + to always fail with ENOSYS. Some functions are actually named + something starting with __ and the normal name is an alias. */ +#if defined (__stub_shl_load) || defined (__stub___shl_load) +choke me +#else +char (*f) () = shl_load; +#endif +#ifdef __cplusplus +} +#endif + +int +main () +{ +return f != shl_load; + ; + return 0; +} +_ACEOF +rm -f conftest.$ac_objext conftest$ac_exeext +if { (eval echo "$as_me:$LINENO: \"$ac_link\"") >&5 + (eval $ac_link) 2>conftest.er1 + ac_status=$? + grep -v '^ *+' conftest.er1 >conftest.err + rm -f conftest.er1 + cat conftest.err >&5 + echo "$as_me:$LINENO: \$? = $ac_status" >&5 + (exit $ac_status); } && + { ac_try='test -z "$ac_c_werror_flag" + || test ! -s conftest.err' + { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5 + (eval $ac_try) 2>&5 + ac_status=$? + echo "$as_me:$LINENO: \$? = $ac_status" >&5 + (exit $ac_status); }; } && + { ac_try='test -s conftest$ac_exeext' + { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5 + (eval $ac_try) 2>&5 + ac_status=$? + echo "$as_me:$LINENO: \$? = $ac_status" >&5 + (exit $ac_status); }; }; then + ac_cv_func_shl_load=yes +else + echo "$as_me: failed program was:" >&5 +sed 's/^/| /' conftest.$ac_ext >&5 + +ac_cv_func_shl_load=no +fi +rm -f conftest.err conftest.$ac_objext \ + conftest$ac_exeext conftest.$ac_ext +fi +echo "$as_me:$LINENO: result: $ac_cv_func_shl_load" >&5 +echo "${ECHO_T}$ac_cv_func_shl_load" >&6 +if test $ac_cv_func_shl_load = yes; then + lt_cv_dlopen="shl_load" +else + echo "$as_me:$LINENO: checking for shl_load in -ldld" >&5 +echo $ECHO_N "checking for shl_load in -ldld... $ECHO_C" >&6 +if test "${ac_cv_lib_dld_shl_load+set}" = set; then + echo $ECHO_N "(cached) $ECHO_C" >&6 +else + ac_check_lib_save_LIBS=$LIBS +LIBS="-ldld $LIBS" +cat >conftest.$ac_ext <<_ACEOF +/* confdefs.h. */ +_ACEOF +cat confdefs.h >>conftest.$ac_ext +cat >>conftest.$ac_ext <<_ACEOF +/* end confdefs.h. */ + +/* Override any gcc2 internal prototype to avoid an error. */ +#ifdef __cplusplus +extern "C" +#endif +/* We use char because int might match the return type of a gcc2 + builtin and then its argument prototype would still apply. */ +char shl_load (); +int +main () +{ +shl_load (); + ; + return 0; +} +_ACEOF +rm -f conftest.$ac_objext conftest$ac_exeext +if { (eval echo "$as_me:$LINENO: \"$ac_link\"") >&5 + (eval $ac_link) 2>conftest.er1 + ac_status=$? + grep -v '^ *+' conftest.er1 >conftest.err + rm -f conftest.er1 + cat conftest.err >&5 + echo "$as_me:$LINENO: \$? = $ac_status" >&5 + (exit $ac_status); } && + { ac_try='test -z "$ac_c_werror_flag" + || test ! -s conftest.err' + { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5 + (eval $ac_try) 2>&5 + ac_status=$? + echo "$as_me:$LINENO: \$? = $ac_status" >&5 + (exit $ac_status); }; } && + { ac_try='test -s conftest$ac_exeext' + { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5 + (eval $ac_try) 2>&5 + ac_status=$? + echo "$as_me:$LINENO: \$? = $ac_status" >&5 + (exit $ac_status); }; }; then + ac_cv_lib_dld_shl_load=yes +else + echo "$as_me: failed program was:" >&5 +sed 's/^/| /' conftest.$ac_ext >&5 + +ac_cv_lib_dld_shl_load=no +fi +rm -f conftest.err conftest.$ac_objext \ + conftest$ac_exeext conftest.$ac_ext +LIBS=$ac_check_lib_save_LIBS +fi +echo "$as_me:$LINENO: result: $ac_cv_lib_dld_shl_load" >&5 +echo "${ECHO_T}$ac_cv_lib_dld_shl_load" >&6 +if test $ac_cv_lib_dld_shl_load = yes; then + lt_cv_dlopen="shl_load" lt_cv_dlopen_libs="-dld" +else + echo "$as_me:$LINENO: checking for dlopen" >&5 +echo $ECHO_N "checking for dlopen... $ECHO_C" >&6 +if test "${ac_cv_func_dlopen+set}" = set; then + echo $ECHO_N "(cached) $ECHO_C" >&6 +else + cat >conftest.$ac_ext <<_ACEOF +/* confdefs.h. */ +_ACEOF +cat confdefs.h >>conftest.$ac_ext +cat >>conftest.$ac_ext <<_ACEOF +/* end confdefs.h. */ +/* Define dlopen to an innocuous variant, in case <limits.h> declares dlopen. + For example, HP-UX 11i <limits.h> declares gettimeofday. */ +#define dlopen innocuous_dlopen + +/* System header to define __stub macros and hopefully few prototypes, + which can conflict with char dlopen (); below. + Prefer <limits.h> to <assert.h> if __STDC__ is defined, since + <limits.h> exists even on freestanding compilers. */ + +#ifdef __STDC__ +# include <limits.h> +#else +# include <assert.h> +#endif + +#undef dlopen + +/* Override any gcc2 internal prototype to avoid an error. */ +#ifdef __cplusplus +extern "C" +{ +#endif +/* We use char because int might match the return type of a gcc2 + builtin and then its argument prototype would still apply. */ +char dlopen (); +/* The GNU C library defines this for functions which it implements + to always fail with ENOSYS. Some functions are actually named + something starting with __ and the normal name is an alias. */ +#if defined (__stub_dlopen) || defined (__stub___dlopen) +choke me +#else +char (*f) () = dlopen; +#endif +#ifdef __cplusplus +} +#endif + +int +main () +{ +return f != dlopen; + ; + return 0; +} +_ACEOF +rm -f conftest.$ac_objext conftest$ac_exeext +if { (eval echo "$as_me:$LINENO: \"$ac_link\"") >&5 + (eval $ac_link) 2>conftest.er1 + ac_status=$? + grep -v '^ *+' conftest.er1 >conftest.err + rm -f conftest.er1 + cat conftest.err >&5 + echo "$as_me:$LINENO: \$? = $ac_status" >&5 + (exit $ac_status); } && + { ac_try='test -z "$ac_c_werror_flag" + || test ! -s conftest.err' + { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5 + (eval $ac_try) 2>&5 + ac_status=$? + echo "$as_me:$LINENO: \$? = $ac_status" >&5 + (exit $ac_status); }; } && + { ac_try='test -s conftest$ac_exeext' + { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5 + (eval $ac_try) 2>&5 + ac_status=$? + echo "$as_me:$LINENO: \$? = $ac_status" >&5 + (exit $ac_status); }; }; then + ac_cv_func_dlopen=yes +else + echo "$as_me: failed program was:" >&5 +sed 's/^/| /' conftest.$ac_ext >&5 + +ac_cv_func_dlopen=no +fi +rm -f conftest.err conftest.$ac_objext \ + conftest$ac_exeext conftest.$ac_ext +fi +echo "$as_me:$LINENO: result: $ac_cv_func_dlopen" >&5 +echo "${ECHO_T}$ac_cv_func_dlopen" >&6 +if test $ac_cv_func_dlopen = yes; then + lt_cv_dlopen="dlopen" +else + echo "$as_me:$LINENO: checking for dlopen in -ldl" >&5 +echo $ECHO_N "checking for dlopen in -ldl... $ECHO_C" >&6 +if test "${ac_cv_lib_dl_dlopen+set}" = set; then + echo $ECHO_N "(cached) $ECHO_C" >&6 +else + ac_check_lib_save_LIBS=$LIBS +LIBS="-ldl $LIBS" +cat >conftest.$ac_ext <<_ACEOF +/* confdefs.h. */ +_ACEOF +cat confdefs.h >>conftest.$ac_ext +cat >>conftest.$ac_ext <<_ACEOF +/* end confdefs.h. */ + +/* Override any gcc2 internal prototype to avoid an error. */ +#ifdef __cplusplus +extern "C" +#endif +/* We use char because int might match the return type of a gcc2 + builtin and then its argument prototype would still apply. */ +char dlopen (); +int +main () +{ +dlopen (); + ; + return 0; +} +_ACEOF +rm -f conftest.$ac_objext conftest$ac_exeext +if { (eval echo "$as_me:$LINENO: \"$ac_link\"") >&5 + (eval $ac_link) 2>conftest.er1 + ac_status=$? + grep -v '^ *+' conftest.er1 >conftest.err + rm -f conftest.er1 + cat conftest.err >&5 + echo "$as_me:$LINENO: \$? = $ac_status" >&5 + (exit $ac_status); } && + { ac_try='test -z "$ac_c_werror_flag" + || test ! -s conftest.err' + { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5 + (eval $ac_try) 2>&5 + ac_status=$? + echo "$as_me:$LINENO: \$? = $ac_status" >&5 + (exit $ac_status); }; } && + { ac_try='test -s conftest$ac_exeext' + { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5 + (eval $ac_try) 2>&5 + ac_status=$? + echo "$as_me:$LINENO: \$? = $ac_status" >&5 + (exit $ac_status); }; }; then + ac_cv_lib_dl_dlopen=yes +else + echo "$as_me: failed program was:" >&5 +sed 's/^/| /' conftest.$ac_ext >&5 + +ac_cv_lib_dl_dlopen=no +fi +rm -f conftest.err conftest.$ac_objext \ + conftest$ac_exeext conftest.$ac_ext +LIBS=$ac_check_lib_save_LIBS +fi +echo "$as_me:$LINENO: result: $ac_cv_lib_dl_dlopen" >&5 +echo "${ECHO_T}$ac_cv_lib_dl_dlopen" >&6 +if test $ac_cv_lib_dl_dlopen = yes; then + lt_cv_dlopen="dlopen" lt_cv_dlopen_libs="-ldl" +else + echo "$as_me:$LINENO: checking for dlopen in -lsvld" >&5 +echo $ECHO_N "checking for dlopen in -lsvld... $ECHO_C" >&6 +if test "${ac_cv_lib_svld_dlopen+set}" = set; then + echo $ECHO_N "(cached) $ECHO_C" >&6 +else + ac_check_lib_save_LIBS=$LIBS +LIBS="-lsvld $LIBS" +cat >conftest.$ac_ext <<_ACEOF +/* confdefs.h. */ +_ACEOF +cat confdefs.h >>conftest.$ac_ext +cat >>conftest.$ac_ext <<_ACEOF +/* end confdefs.h. */ + +/* Override any gcc2 internal prototype to avoid an error. */ +#ifdef __cplusplus +extern "C" +#endif +/* We use char because int might match the return type of a gcc2 + builtin and then its argument prototype would still apply. */ +char dlopen (); +int +main () +{ +dlopen (); + ; + return 0; +} +_ACEOF +rm -f conftest.$ac_objext conftest$ac_exeext +if { (eval echo "$as_me:$LINENO: \"$ac_link\"") >&5 + (eval $ac_link) 2>conftest.er1 + ac_status=$? + grep -v '^ *+' conftest.er1 >conftest.err + rm -f conftest.er1 + cat conftest.err >&5 + echo "$as_me:$LINENO: \$? = $ac_status" >&5 + (exit $ac_status); } && + { ac_try='test -z "$ac_c_werror_flag" + || test ! -s conftest.err' + { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5 + (eval $ac_try) 2>&5 + ac_status=$? + echo "$as_me:$LINENO: \$? = $ac_status" >&5 + (exit $ac_status); }; } && + { ac_try='test -s conftest$ac_exeext' + { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5 + (eval $ac_try) 2>&5 + ac_status=$? + echo "$as_me:$LINENO: \$? = $ac_status" >&5 + (exit $ac_status); }; }; then + ac_cv_lib_svld_dlopen=yes +else + echo "$as_me: failed program was:" >&5 +sed 's/^/| /' conftest.$ac_ext >&5 + +ac_cv_lib_svld_dlopen=no +fi +rm -f conftest.err conftest.$ac_objext \ + conftest$ac_exeext conftest.$ac_ext +LIBS=$ac_check_lib_save_LIBS +fi +echo "$as_me:$LINENO: result: $ac_cv_lib_svld_dlopen" >&5 +echo "${ECHO_T}$ac_cv_lib_svld_dlopen" >&6 +if test $ac_cv_lib_svld_dlopen = yes; then + lt_cv_dlopen="dlopen" lt_cv_dlopen_libs="-lsvld" +else + echo "$as_me:$LINENO: checking for dld_link in -ldld" >&5 +echo $ECHO_N "checking for dld_link in -ldld... $ECHO_C" >&6 +if test "${ac_cv_lib_dld_dld_link+set}" = set; then + echo $ECHO_N "(cached) $ECHO_C" >&6 +else + ac_check_lib_save_LIBS=$LIBS +LIBS="-ldld $LIBS" +cat >conftest.$ac_ext <<_ACEOF +/* confdefs.h. */ +_ACEOF +cat confdefs.h >>conftest.$ac_ext +cat >>conftest.$ac_ext <<_ACEOF +/* end confdefs.h. */ + +/* Override any gcc2 internal prototype to avoid an error. */ +#ifdef __cplusplus +extern "C" +#endif +/* We use char because int might match the return type of a gcc2 + builtin and then its argument prototype would still apply. */ +char dld_link (); +int +main () +{ +dld_link (); + ; + return 0; +} +_ACEOF +rm -f conftest.$ac_objext conftest$ac_exeext +if { (eval echo "$as_me:$LINENO: \"$ac_link\"") >&5 + (eval $ac_link) 2>conftest.er1 + ac_status=$? + grep -v '^ *+' conftest.er1 >conftest.err + rm -f conftest.er1 + cat conftest.err >&5 + echo "$as_me:$LINENO: \$? = $ac_status" >&5 + (exit $ac_status); } && + { ac_try='test -z "$ac_c_werror_flag" + || test ! -s conftest.err' + { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5 + (eval $ac_try) 2>&5 + ac_status=$? + echo "$as_me:$LINENO: \$? = $ac_status" >&5 + (exit $ac_status); }; } && + { ac_try='test -s conftest$ac_exeext' + { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5 + (eval $ac_try) 2>&5 + ac_status=$? + echo "$as_me:$LINENO: \$? = $ac_status" >&5 + (exit $ac_status); }; }; then + ac_cv_lib_dld_dld_link=yes +else + echo "$as_me: failed program was:" >&5 +sed 's/^/| /' conftest.$ac_ext >&5 + +ac_cv_lib_dld_dld_link=no +fi +rm -f conftest.err conftest.$ac_objext \ + conftest$ac_exeext conftest.$ac_ext +LIBS=$ac_check_lib_save_LIBS +fi +echo "$as_me:$LINENO: result: $ac_cv_lib_dld_dld_link" >&5 +echo "${ECHO_T}$ac_cv_lib_dld_dld_link" >&6 +if test $ac_cv_lib_dld_dld_link = yes; then + lt_cv_dlopen="dld_link" lt_cv_dlopen_libs="-dld" +fi + + +fi + + +fi + + +fi + + +fi + + +fi + + ;; + esac + + if test "x$lt_cv_dlopen" != xno; then + enable_dlopen=yes + else + enable_dlopen=no + fi + + case $lt_cv_dlopen in + dlopen) + save_CPPFLAGS="$CPPFLAGS" + test "x$ac_cv_header_dlfcn_h" = xyes && CPPFLAGS="$CPPFLAGS -DHAVE_DLFCN_H" + + save_LDFLAGS="$LDFLAGS" + wl=$lt_prog_compiler_wl eval LDFLAGS=\"\$LDFLAGS $export_dynamic_flag_spec\" + + save_LIBS="$LIBS" + LIBS="$lt_cv_dlopen_libs $LIBS" + + echo "$as_me:$LINENO: checking whether a program can dlopen itself" >&5 +echo $ECHO_N "checking whether a program can dlopen itself... $ECHO_C" >&6 +if test "${lt_cv_dlopen_self+set}" = set; then + echo $ECHO_N "(cached) $ECHO_C" >&6 +else + if test "$cross_compiling" = yes; then : + lt_cv_dlopen_self=cross +else + lt_dlunknown=0; lt_dlno_uscore=1; lt_dlneed_uscore=2 + lt_status=$lt_dlunknown + cat > conftest.$ac_ext <<EOF +#line 9251 "configure" +#include "confdefs.h" + +#if HAVE_DLFCN_H +#include <dlfcn.h> +#endif + +#include <stdio.h> + +#ifdef RTLD_GLOBAL +# define LT_DLGLOBAL RTLD_GLOBAL +#else +# ifdef DL_GLOBAL +# define LT_DLGLOBAL DL_GLOBAL +# else +# define LT_DLGLOBAL 0 +# endif +#endif + +/* We may have to define LT_DLLAZY_OR_NOW in the command line if we + find out it does not work in some platform. */ +#ifndef LT_DLLAZY_OR_NOW +# ifdef RTLD_LAZY +# define LT_DLLAZY_OR_NOW RTLD_LAZY +# else +# ifdef DL_LAZY +# define LT_DLLAZY_OR_NOW DL_LAZY +# else +# ifdef RTLD_NOW +# define LT_DLLAZY_OR_NOW RTLD_NOW +# else +# ifdef DL_NOW +# define LT_DLLAZY_OR_NOW DL_NOW +# else +# define LT_DLLAZY_OR_NOW 0 +# endif +# endif +# endif +# endif +#endif + +#ifdef __cplusplus +extern "C" void exit (int); +#endif + +void fnord() { int i=42;} +int main () +{ + void *self = dlopen (0, LT_DLGLOBAL|LT_DLLAZY_OR_NOW); + int status = $lt_dlunknown; + + if (self) + { + if (dlsym (self,"fnord")) status = $lt_dlno_uscore; + else if (dlsym( self,"_fnord")) status = $lt_dlneed_uscore; + /* dlclose (self); */ + } + else + puts (dlerror ()); + + exit (status); +} +EOF + if { (eval echo "$as_me:$LINENO: \"$ac_link\"") >&5 + (eval $ac_link) 2>&5 + ac_status=$? + echo "$as_me:$LINENO: \$? = $ac_status" >&5 + (exit $ac_status); } && test -s conftest${ac_exeext} 2>/dev/null; then + (./conftest; exit; ) >&5 2>/dev/null + lt_status=$? + case x$lt_status in + x$lt_dlno_uscore) lt_cv_dlopen_self=yes ;; + x$lt_dlneed_uscore) lt_cv_dlopen_self=yes ;; + x$lt_dlunknown|x*) lt_cv_dlopen_self=no ;; + esac + else : + # compilation failed + lt_cv_dlopen_self=no + fi +fi +rm -fr conftest* + + +fi +echo "$as_me:$LINENO: result: $lt_cv_dlopen_self" >&5 +echo "${ECHO_T}$lt_cv_dlopen_self" >&6 + + if test "x$lt_cv_dlopen_self" = xyes; then + wl=$lt_prog_compiler_wl eval LDFLAGS=\"\$LDFLAGS $lt_prog_compiler_static\" + echo "$as_me:$LINENO: checking whether a statically linked program can dlopen itself" >&5 +echo $ECHO_N "checking whether a statically linked program can dlopen itself... $ECHO_C" >&6 +if test "${lt_cv_dlopen_self_static+set}" = set; then + echo $ECHO_N "(cached) $ECHO_C" >&6 +else + if test "$cross_compiling" = yes; then : + lt_cv_dlopen_self_static=cross +else + lt_dlunknown=0; lt_dlno_uscore=1; lt_dlneed_uscore=2 + lt_status=$lt_dlunknown + cat > conftest.$ac_ext <<EOF +#line 9351 "configure" +#include "confdefs.h" + +#if HAVE_DLFCN_H +#include <dlfcn.h> +#endif + +#include <stdio.h> + +#ifdef RTLD_GLOBAL +# define LT_DLGLOBAL RTLD_GLOBAL +#else +# ifdef DL_GLOBAL +# define LT_DLGLOBAL DL_GLOBAL +# else +# define LT_DLGLOBAL 0 +# endif +#endif + +/* We may have to define LT_DLLAZY_OR_NOW in the command line if we + find out it does not work in some platform. */ +#ifndef LT_DLLAZY_OR_NOW +# ifdef RTLD_LAZY +# define LT_DLLAZY_OR_NOW RTLD_LAZY +# else +# ifdef DL_LAZY +# define LT_DLLAZY_OR_NOW DL_LAZY +# else +# ifdef RTLD_NOW +# define LT_DLLAZY_OR_NOW RTLD_NOW +# else +# ifdef DL_NOW +# define LT_DLLAZY_OR_NOW DL_NOW +# else +# define LT_DLLAZY_OR_NOW 0 +# endif +# endif +# endif +# endif +#endif + +#ifdef __cplusplus +extern "C" void exit (int); +#endif + +void fnord() { int i=42;} +int main () +{ + void *self = dlopen (0, LT_DLGLOBAL|LT_DLLAZY_OR_NOW); + int status = $lt_dlunknown; + + if (self) + { + if (dlsym (self,"fnord")) status = $lt_dlno_uscore; + else if (dlsym( self,"_fnord")) status = $lt_dlneed_uscore; + /* dlclose (self); */ + } + else + puts (dlerror ()); + + exit (status); +} +EOF + if { (eval echo "$as_me:$LINENO: \"$ac_link\"") >&5 + (eval $ac_link) 2>&5 + ac_status=$? + echo "$as_me:$LINENO: \$? = $ac_status" >&5 + (exit $ac_status); } && test -s conftest${ac_exeext} 2>/dev/null; then + (./conftest; exit; ) >&5 2>/dev/null + lt_status=$? + case x$lt_status in + x$lt_dlno_uscore) lt_cv_dlopen_self_static=yes ;; + x$lt_dlneed_uscore) lt_cv_dlopen_self_static=yes ;; + x$lt_dlunknown|x*) lt_cv_dlopen_self_static=no ;; + esac + else : + # compilation failed + lt_cv_dlopen_self_static=no + fi +fi +rm -fr conftest* + + +fi +echo "$as_me:$LINENO: result: $lt_cv_dlopen_self_static" >&5 +echo "${ECHO_T}$lt_cv_dlopen_self_static" >&6 + fi + + CPPFLAGS="$save_CPPFLAGS" + LDFLAGS="$save_LDFLAGS" + LIBS="$save_LIBS" + ;; + esac + + case $lt_cv_dlopen_self in + yes|no) enable_dlopen_self=$lt_cv_dlopen_self ;; + *) enable_dlopen_self=unknown ;; + esac + + case $lt_cv_dlopen_self_static in + yes|no) enable_dlopen_self_static=$lt_cv_dlopen_self_static ;; + *) enable_dlopen_self_static=unknown ;; + esac +fi + + +# Report which library types will actually be built +echo "$as_me:$LINENO: checking if libtool supports shared libraries" >&5 +echo $ECHO_N "checking if libtool supports shared libraries... $ECHO_C" >&6 +echo "$as_me:$LINENO: result: $can_build_shared" >&5 +echo "${ECHO_T}$can_build_shared" >&6 + +echo "$as_me:$LINENO: checking whether to build shared libraries" >&5 +echo $ECHO_N "checking whether to build shared libraries... $ECHO_C" >&6 +test "$can_build_shared" = "no" && enable_shared=no + +# On AIX, shared libraries and static libraries use the same namespace, and +# are all built from PIC. +case $host_os in +aix3*) + test "$enable_shared" = yes && enable_static=no + if test -n "$RANLIB"; then + archive_cmds="$archive_cmds~\$RANLIB \$lib" + postinstall_cmds='$RANLIB $lib' + fi + ;; + +aix4* | aix5*) + if test "$host_cpu" != ia64 && test "$aix_use_runtimelinking" = no ; then + test "$enable_shared" = yes && enable_static=no + fi + ;; +esac +echo "$as_me:$LINENO: result: $enable_shared" >&5 +echo "${ECHO_T}$enable_shared" >&6 + +echo "$as_me:$LINENO: checking whether to build static libraries" >&5 +echo $ECHO_N "checking whether to build static libraries... $ECHO_C" >&6 +# Make sure either enable_shared or enable_static is yes. +test "$enable_shared" = yes || enable_static=yes +echo "$as_me:$LINENO: result: $enable_static" >&5 +echo "${ECHO_T}$enable_static" >&6 + +# The else clause should only fire when bootstrapping the +# libtool distribution, otherwise you forgot to ship ltmain.sh +# with your package, and you will get complaints that there are +# no rules to generate ltmain.sh. +if test -f "$ltmain"; then + # See if we are running on zsh, and set the options which allow our commands through + # without removal of \ escapes. + if test -n "${ZSH_VERSION+set}" ; then + setopt NO_GLOB_SUBST + fi + # Now quote all the things that may contain metacharacters while being + # careful not to overquote the AC_SUBSTed values. We take copies of the + # variables and quote the copies for generation of the libtool script. + for var in echo old_CC old_CFLAGS AR AR_FLAGS EGREP RANLIB LN_S LTCC LTCFLAGS NM \ + SED SHELL STRIP \ + libname_spec library_names_spec soname_spec extract_expsyms_cmds \ + old_striplib striplib file_magic_cmd finish_cmds finish_eval \ + deplibs_check_method reload_flag reload_cmds need_locks \ + lt_cv_sys_global_symbol_pipe lt_cv_sys_global_symbol_to_cdecl \ + lt_cv_sys_global_symbol_to_c_name_address \ + sys_lib_search_path_spec sys_lib_dlsearch_path_spec \ + old_postinstall_cmds old_postuninstall_cmds \ + compiler \ + CC \ + LD \ + lt_prog_compiler_wl \ + lt_prog_compiler_pic \ + lt_prog_compiler_static \ + lt_prog_compiler_no_builtin_flag \ + export_dynamic_flag_spec \ + thread_safe_flag_spec \ + whole_archive_flag_spec \ + enable_shared_with_static_runtimes \ + old_archive_cmds \ + old_archive_from_new_cmds \ + predep_objects \ + postdep_objects \ + predeps \ + postdeps \ + compiler_lib_search_path \ + archive_cmds \ + archive_expsym_cmds \ + postinstall_cmds \ + postuninstall_cmds \ + old_archive_from_expsyms_cmds \ + allow_undefined_flag \ + no_undefined_flag \ + export_symbols_cmds \ + hardcode_libdir_flag_spec \ + hardcode_libdir_flag_spec_ld \ + hardcode_libdir_separator \ + hardcode_automatic \ + module_cmds \ + module_expsym_cmds \ + lt_cv_prog_compiler_c_o \ + exclude_expsyms \ + include_expsyms; do + + case $var in + old_archive_cmds | \ + old_archive_from_new_cmds | \ + archive_cmds | \ + archive_expsym_cmds | \ + module_cmds | \ + module_expsym_cmds | \ + old_archive_from_expsyms_cmds | \ + export_symbols_cmds | \ + extract_expsyms_cmds | reload_cmds | finish_cmds | \ + postinstall_cmds | postuninstall_cmds | \ + old_postinstall_cmds | old_postuninstall_cmds | \ + sys_lib_search_path_spec | sys_lib_dlsearch_path_spec) + # Double-quote double-evaled strings. + eval "lt_$var=\\\"\`\$echo \"X\$$var\" | \$Xsed -e \"\$double_quote_subst\" -e \"\$sed_quote_subst\" -e \"\$delay_variable_subst\"\`\\\"" + ;; + *) + eval "lt_$var=\\\"\`\$echo \"X\$$var\" | \$Xsed -e \"\$sed_quote_subst\"\`\\\"" + ;; + esac + done + + case $lt_echo in + *'\$0 --fallback-echo"') + lt_echo=`$echo "X$lt_echo" | $Xsed -e 's/\\\\\\\$0 --fallback-echo"$/$0 --fallback-echo"/'` + ;; + esac + +cfgfile="${ofile}T" + trap "$rm \"$cfgfile\"; exit 1" 1 2 15 + $rm -f "$cfgfile" + { echo "$as_me:$LINENO: creating $ofile" >&5 +echo "$as_me: creating $ofile" >&6;} + + cat <<__EOF__ >> "$cfgfile" +#! $SHELL + +# `$echo "$cfgfile" | sed 's%^.*/%%'` - Provide generalized library-building support services. +# Generated automatically by $PROGRAM (GNU $PACKAGE $VERSION$TIMESTAMP) +# NOTE: Changes made to this file will be lost: look at ltmain.sh. +# +# Copyright (C) 1996, 1997, 1998, 1999, 2000, 2001 +# Free Software Foundation, Inc. +# +# This file is part of GNU Libtool: +# Originally by Gordon Matzigkeit <gord@gnu.ai.mit.edu>, 1996 +# +# 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. +# +# As a special exception to the GNU General Public License, if you +# distribute this file as part of a program that contains a +# configuration script generated by Autoconf, you may include it under +# the same distribution terms that you use for the rest of that program. + +# A sed program that does not truncate output. +SED=$lt_SED + +# Sed that helps us avoid accidentally triggering echo(1) options like -n. +Xsed="$SED -e 1s/^X//" + +# The HP-UX ksh and POSIX shell print the target directory to stdout +# if CDPATH is set. +(unset CDPATH) >/dev/null 2>&1 && unset CDPATH + +# The names of the tagged configurations supported by this script. +available_tags= + +# ### BEGIN LIBTOOL CONFIG + +# Libtool was configured on host `(hostname || uname -n) 2>/dev/null | sed 1q`: + +# Shell to use when invoking shell scripts. +SHELL=$lt_SHELL + +# Whether or not to build shared libraries. +build_libtool_libs=$enable_shared + +# Whether or not to build static libraries. +build_old_libs=$enable_static + +# Whether or not to add -lc for building shared libraries. +build_libtool_need_lc=$archive_cmds_need_lc + +# Whether or not to disallow shared libs when runtime libs are static +allow_libtool_libs_with_static_runtimes=$enable_shared_with_static_runtimes + +# Whether or not to optimize for fast installation. +fast_install=$enable_fast_install + +# The host system. +host_alias=$host_alias +host=$host +host_os=$host_os + +# The build system. +build_alias=$build_alias +build=$build +build_os=$build_os + +# An echo program that does not interpret backslashes. +echo=$lt_echo + +# The archiver. +AR=$lt_AR +AR_FLAGS=$lt_AR_FLAGS + +# A C compiler. +LTCC=$lt_LTCC + +# LTCC compiler flags. +LTCFLAGS=$lt_LTCFLAGS + +# A language-specific compiler. +CC=$lt_compiler + +# Is the compiler the GNU C compiler? +with_gcc=$GCC + +gcc_dir=\`gcc -print-file-name=. | $SED 's,/\.$,,'\` +gcc_ver=\`gcc -dumpversion\` + +# An ERE matcher. +EGREP=$lt_EGREP + +# The linker used to build libraries. +LD=$lt_LD + +# Whether we need hard or soft links. +LN_S=$lt_LN_S + +# A BSD-compatible nm program. +NM=$lt_NM + +# A symbol stripping program +STRIP=$lt_STRIP + +# Used to examine libraries when file_magic_cmd begins "file" +MAGIC_CMD=$MAGIC_CMD + +# Used on cygwin: DLL creation program. +DLLTOOL="$DLLTOOL" + +# Used on cygwin: object dumper. +OBJDUMP="$OBJDUMP" + +# Used on cygwin: assembler. +AS="$AS" + +# The name of the directory that contains temporary libtool files. +objdir=$objdir + +# How to create reloadable object files. +reload_flag=$lt_reload_flag +reload_cmds=$lt_reload_cmds + +# How to pass a linker flag through the compiler. +wl=$lt_lt_prog_compiler_wl + +# Object file suffix (normally "o"). +objext="$ac_objext" + +# Old archive suffix (normally "a"). +libext="$libext" + +# Shared library suffix (normally ".so"). +shrext_cmds='$shrext_cmds' + +# Executable file suffix (normally ""). +exeext="$exeext" + +# Additional compiler flags for building library objects. +pic_flag=$lt_lt_prog_compiler_pic +pic_mode=$pic_mode + +# What is the maximum length of a command? +max_cmd_len=$lt_cv_sys_max_cmd_len + +# Does compiler simultaneously support -c and -o options? +compiler_c_o=$lt_lt_cv_prog_compiler_c_o + +# Must we lock files when doing compilation? +need_locks=$lt_need_locks + +# Do we need the lib prefix for modules? +need_lib_prefix=$need_lib_prefix + +# Do we need a version for libraries? +need_version=$need_version + +# Whether dlopen is supported. +dlopen_support=$enable_dlopen + +# Whether dlopen of programs is supported. +dlopen_self=$enable_dlopen_self + +# Whether dlopen of statically linked programs is supported. +dlopen_self_static=$enable_dlopen_self_static + +# Compiler flag to prevent dynamic linking. +link_static_flag=$lt_lt_prog_compiler_static + +# Compiler flag to turn off builtin functions. +no_builtin_flag=$lt_lt_prog_compiler_no_builtin_flag + +# Compiler flag to allow reflexive dlopens. +export_dynamic_flag_spec=$lt_export_dynamic_flag_spec + +# Compiler flag to generate shared objects directly from archives. +whole_archive_flag_spec=$lt_whole_archive_flag_spec + +# Compiler flag to generate thread-safe objects. +thread_safe_flag_spec=$lt_thread_safe_flag_spec + +# Library versioning type. +version_type=$version_type + +# Format of library name prefix. +libname_spec=$lt_libname_spec + +# List of archive names. First name is the real one, the rest are links. +# The last name is the one that the linker finds with -lNAME. +library_names_spec=$lt_library_names_spec + +# The coded name of the library, if different from the real name. +soname_spec=$lt_soname_spec + +# Commands used to build and install an old-style archive. +RANLIB=$lt_RANLIB +old_archive_cmds=$lt_old_archive_cmds +old_postinstall_cmds=$lt_old_postinstall_cmds +old_postuninstall_cmds=$lt_old_postuninstall_cmds + +# Create an old-style archive from a shared archive. +old_archive_from_new_cmds=$lt_old_archive_from_new_cmds + +# Create a temporary old-style archive to link instead of a shared archive. +old_archive_from_expsyms_cmds=$lt_old_archive_from_expsyms_cmds + +# Commands used to build and install a shared archive. +archive_cmds=$lt_archive_cmds +archive_expsym_cmds=$lt_archive_expsym_cmds +postinstall_cmds=$lt_postinstall_cmds +postuninstall_cmds=$lt_postuninstall_cmds + +# Commands used to build a loadable module (assumed same as above if empty) +module_cmds=$lt_module_cmds +module_expsym_cmds=$lt_module_expsym_cmds + +# Commands to strip libraries. +old_striplib=$lt_old_striplib +striplib=$lt_striplib + +# Dependencies to place before the objects being linked to create a +# shared library. +predep_objects=\`echo $lt_predep_objects | \$SED -e "s@\${gcc_dir}@\\\${gcc_dir}@g;s@\${gcc_ver}@\\\${gcc_ver}@g"\` + +# Dependencies to place after the objects being linked to create a +# shared library. +postdep_objects=\`echo $lt_postdep_objects | \$SED -e "s@\${gcc_dir}@\\\${gcc_dir}@g;s@\${gcc_ver}@\\\${gcc_ver}@g"\` + +# Dependencies to place before the objects being linked to create a +# shared library. +predeps=$lt_predeps + +# Dependencies to place after the objects being linked to create a +# shared library. +postdeps=$lt_postdeps + +# The library search path used internally by the compiler when linking +# a shared library. +compiler_lib_search_path=\`echo $lt_compiler_lib_search_path | \$SED -e "s@\${gcc_dir}@\\\${gcc_dir}@g;s@\${gcc_ver}@\\\${gcc_ver}@g"\` + +# Method to check whether dependent libraries are shared objects. +deplibs_check_method=$lt_deplibs_check_method + +# Command to use when deplibs_check_method == file_magic. +file_magic_cmd=$lt_file_magic_cmd + +# Flag that allows shared libraries with undefined symbols to be built. +allow_undefined_flag=$lt_allow_undefined_flag + +# Flag that forces no undefined symbols. +no_undefined_flag=$lt_no_undefined_flag + +# Commands used to finish a libtool library installation in a directory. +finish_cmds=$lt_finish_cmds + +# Same as above, but a single script fragment to be evaled but not shown. +finish_eval=$lt_finish_eval + +# Take the output of nm and produce a listing of raw symbols and C names. +global_symbol_pipe=$lt_lt_cv_sys_global_symbol_pipe + +# Transform the output of nm in a proper C declaration +global_symbol_to_cdecl=$lt_lt_cv_sys_global_symbol_to_cdecl + +# Transform the output of nm in a C name address pair +global_symbol_to_c_name_address=$lt_lt_cv_sys_global_symbol_to_c_name_address + +# This is the shared library runtime path variable. +runpath_var=$runpath_var + +# This is the shared library path variable. +shlibpath_var=$shlibpath_var + +# Is shlibpath searched before the hard-coded library search path? +shlibpath_overrides_runpath=$shlibpath_overrides_runpath + +# How to hardcode a shared library path into an executable. +hardcode_action=$hardcode_action + +# Whether we should hardcode library paths into libraries. +hardcode_into_libs=$hardcode_into_libs + +# Flag to hardcode \$libdir into a binary during linking. +# This must work even if \$libdir does not exist. +hardcode_libdir_flag_spec=$lt_hardcode_libdir_flag_spec + +# If ld is used when linking, flag to hardcode \$libdir into +# a binary during linking. This must work even if \$libdir does +# not exist. +hardcode_libdir_flag_spec_ld=$lt_hardcode_libdir_flag_spec_ld + +# Whether we need a single -rpath flag with a separated argument. +hardcode_libdir_separator=$lt_hardcode_libdir_separator + +# Set to yes if using DIR/libNAME${shared_ext} during linking hardcodes DIR into the +# resulting binary. +hardcode_direct=$hardcode_direct + +# Set to yes if using the -LDIR flag during linking hardcodes DIR into the +# resulting binary. +hardcode_minus_L=$hardcode_minus_L + +# Set to yes if using SHLIBPATH_VAR=DIR during linking hardcodes DIR into +# the resulting binary. +hardcode_shlibpath_var=$hardcode_shlibpath_var + +# Set to yes if building a shared library automatically hardcodes DIR into the library +# and all subsequent libraries and executables linked against it. +hardcode_automatic=$hardcode_automatic + +# Variables whose values should be saved in libtool wrapper scripts and +# restored at relink time. +variables_saved_for_relink="$variables_saved_for_relink" + +# Whether libtool must link a program against all its dependency libraries. +link_all_deplibs=$link_all_deplibs + +# Compile-time system search path for libraries +sys_lib_search_path_spec=\`echo $lt_sys_lib_search_path_spec | \$SED -e "s@\${gcc_dir}@\\\${gcc_dir}@g;s@\${gcc_ver}@\\\${gcc_ver}@g"\` + +# Run-time system search path for libraries +sys_lib_dlsearch_path_spec=$lt_sys_lib_dlsearch_path_spec + +# Fix the shell variable \$srcfile for the compiler. +fix_srcfile_path="$fix_srcfile_path" + +# Set to yes if exported symbols are required. +always_export_symbols=$always_export_symbols + +# The commands to list exported symbols. +export_symbols_cmds=$lt_export_symbols_cmds + +# The commands to extract the exported symbol list from a shared archive. +extract_expsyms_cmds=$lt_extract_expsyms_cmds + +# Symbols that should not be listed in the preloaded symbols. +exclude_expsyms=$lt_exclude_expsyms + +# Symbols that must always be exported. +include_expsyms=$lt_include_expsyms + +# ### END LIBTOOL CONFIG + +__EOF__ + + + case $host_os in + aix3*) + cat <<\EOF >> "$cfgfile" + +# AIX sometimes has problems with the GCC collect2 program. For some +# reason, if we set the COLLECT_NAMES environment variable, the problems +# vanish in a puff of smoke. +if test "X${COLLECT_NAMES+set}" != Xset; then + COLLECT_NAMES= + export COLLECT_NAMES +fi +EOF + ;; + esac + + # We use sed instead of cat because bash on DJGPP gets confused if + # if finds mixed CR/LF and LF-only lines. Since sed operates in + # text mode, it properly converts lines to CR/LF. This bash problem + # is reportedly fixed, but why not run on old versions too? + sed '$q' "$ltmain" >> "$cfgfile" || (rm -f "$cfgfile"; exit 1) + + mv -f "$cfgfile" "$ofile" || \ + (rm -f "$ofile" && cp "$cfgfile" "$ofile" && rm -f "$cfgfile") + chmod +x "$ofile" + +else + # If there is no Makefile yet, we rely on a make rule to execute + # `config.status --recheck' to rerun these tests and create the + # libtool script then. + ltmain_in=`echo $ltmain | sed -e 's/\.sh$/.in/'` + if test -f "$ltmain_in"; then + test -f Makefile && make "$ltmain" + fi +fi + + +ac_ext=c +ac_cpp='$CPP $CPPFLAGS' +ac_compile='$CC -c $CFLAGS $CPPFLAGS conftest.$ac_ext >&5' +ac_link='$CC -o conftest$ac_exeext $CFLAGS $CPPFLAGS $LDFLAGS conftest.$ac_ext $LIBS >&5' +ac_compiler_gnu=$ac_cv_c_compiler_gnu + +CC="$lt_save_CC" + + +# Check whether --with-tags or --without-tags was given. +if test "${with_tags+set}" = set; then + withval="$with_tags" + tagnames="$withval" +fi; + +if test -f "$ltmain" && test -n "$tagnames"; then + if test ! -f "${ofile}"; then + { echo "$as_me:$LINENO: WARNING: output file \`$ofile' does not exist" >&5 +echo "$as_me: WARNING: output file \`$ofile' does not exist" >&2;} + fi + + if test -z "$LTCC"; then + eval "`$SHELL ${ofile} --config | grep '^LTCC='`" + if test -z "$LTCC"; then + { echo "$as_me:$LINENO: WARNING: output file \`$ofile' does not look like a libtool script" >&5 +echo "$as_me: WARNING: output file \`$ofile' does not look like a libtool script" >&2;} + else + { echo "$as_me:$LINENO: WARNING: using \`LTCC=$LTCC', extracted from \`$ofile'" >&5 +echo "$as_me: WARNING: using \`LTCC=$LTCC', extracted from \`$ofile'" >&2;} + fi + fi + if test -z "$LTCFLAGS"; then + eval "`$SHELL ${ofile} --config | grep '^LTCFLAGS='`" + fi + + # Extract list of available tagged configurations in $ofile. + # Note that this assumes the entire list is on one line. + available_tags=`grep "^available_tags=" "${ofile}" | $SED -e 's/available_tags=\(.*$\)/\1/' -e 's/\"//g'` + + lt_save_ifs="$IFS"; IFS="${IFS}$PATH_SEPARATOR," + for tagname in $tagnames; do + IFS="$lt_save_ifs" + # Check whether tagname contains only valid characters + case `$echo "X$tagname" | $Xsed -e 's:[-_ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz1234567890,/]::g'` in + "") ;; + *) { { echo "$as_me:$LINENO: error: invalid tag name: $tagname" >&5 +echo "$as_me: error: invalid tag name: $tagname" >&2;} + { (exit 1); exit 1; }; } + ;; + esac + + if grep "^# ### BEGIN LIBTOOL TAG CONFIG: $tagname$" < "${ofile}" > /dev/null + then + { { echo "$as_me:$LINENO: error: tag name \"$tagname\" already exists" >&5 +echo "$as_me: error: tag name \"$tagname\" already exists" >&2;} + { (exit 1); exit 1; }; } + fi + + # Update the list of available tags. + if test -n "$tagname"; then + echo appending configuration tag \"$tagname\" to $ofile + + case $tagname in + CXX) + if test -n "$CXX" && ( test "X$CXX" != "Xno" && + ( (test "X$CXX" = "Xg++" && `g++ -v >/dev/null 2>&1` ) || + (test "X$CXX" != "Xg++"))) ; then + ac_ext=cc +ac_cpp='$CXXCPP $CPPFLAGS' +ac_compile='$CXX -c $CXXFLAGS $CPPFLAGS conftest.$ac_ext >&5' +ac_link='$CXX -o conftest$ac_exeext $CXXFLAGS $CPPFLAGS $LDFLAGS conftest.$ac_ext $LIBS >&5' +ac_compiler_gnu=$ac_cv_cxx_compiler_gnu + + + + +archive_cmds_need_lc_CXX=no +allow_undefined_flag_CXX= +always_export_symbols_CXX=no +archive_expsym_cmds_CXX= +export_dynamic_flag_spec_CXX= +hardcode_direct_CXX=no +hardcode_libdir_flag_spec_CXX= +hardcode_libdir_flag_spec_ld_CXX= +hardcode_libdir_separator_CXX= +hardcode_minus_L_CXX=no +hardcode_shlibpath_var_CXX=unsupported +hardcode_automatic_CXX=no +module_cmds_CXX= +module_expsym_cmds_CXX= +link_all_deplibs_CXX=unknown +old_archive_cmds_CXX=$old_archive_cmds +no_undefined_flag_CXX= +whole_archive_flag_spec_CXX= +enable_shared_with_static_runtimes_CXX=no + +# Dependencies to place before and after the object being linked: +predep_objects_CXX= +postdep_objects_CXX= +predeps_CXX= +postdeps_CXX= +compiler_lib_search_path_CXX= + +# Source file extension for C++ test sources. +ac_ext=cpp + +# Object file extension for compiled C++ test sources. +objext=o +objext_CXX=$objext + +# Code to be used in simple compile tests +lt_simple_compile_test_code="int some_variable = 0;\n" + +# Code to be used in simple link tests +lt_simple_link_test_code='int main(int, char *[]) { return(0); }\n' + +# ltmain only uses $CC for tagged configurations so make sure $CC is set. + +# If no C compiler was specified, use CC. +LTCC=${LTCC-"$CC"} + +# If no C compiler flags were specified, use CFLAGS. +LTCFLAGS=${LTCFLAGS-"$CFLAGS"} + +# Allow CC to be a program name with arguments. +compiler=$CC + + +# save warnings/boilerplate of simple test code +ac_outfile=conftest.$ac_objext +printf "$lt_simple_compile_test_code" >conftest.$ac_ext +eval "$ac_compile" 2>&1 >/dev/null | $SED '/^$/d; /^ *+/d' >conftest.err +_lt_compiler_boilerplate=`cat conftest.err` +$rm conftest* + +ac_outfile=conftest.$ac_objext +printf "$lt_simple_link_test_code" >conftest.$ac_ext +eval "$ac_link" 2>&1 >/dev/null | $SED '/^$/d; /^ *+/d' >conftest.err +_lt_linker_boilerplate=`cat conftest.err` +$rm conftest* + + +# Allow CC to be a program name with arguments. +lt_save_CC=$CC +lt_save_LD=$LD +lt_save_GCC=$GCC +GCC=$GXX +lt_save_with_gnu_ld=$with_gnu_ld +lt_save_path_LD=$lt_cv_path_LD +if test -n "${lt_cv_prog_gnu_ldcxx+set}"; then + lt_cv_prog_gnu_ld=$lt_cv_prog_gnu_ldcxx +else + $as_unset lt_cv_prog_gnu_ld +fi +if test -n "${lt_cv_path_LDCXX+set}"; then + lt_cv_path_LD=$lt_cv_path_LDCXX +else + $as_unset lt_cv_path_LD +fi +test -z "${LDCXX+set}" || LD=$LDCXX +CC=${CXX-"c++"} +compiler=$CC +compiler_CXX=$CC +for cc_temp in $compiler""; do + case $cc_temp in + compile | *[\\/]compile | ccache | *[\\/]ccache ) ;; + distcc | *[\\/]distcc | purify | *[\\/]purify ) ;; + \-*) ;; + *) break;; + esac +done +cc_basename=`$echo "X$cc_temp" | $Xsed -e 's%.*/%%' -e "s%^$host_alias-%%"` + + +# We don't want -fno-exception wen compiling C++ code, so set the +# no_builtin_flag separately +if test "$GXX" = yes; then + lt_prog_compiler_no_builtin_flag_CXX=' -fno-builtin' +else + lt_prog_compiler_no_builtin_flag_CXX= +fi + +if test "$GXX" = yes; then + # Set up default GNU C++ configuration + + +# Check whether --with-gnu-ld or --without-gnu-ld was given. +if test "${with_gnu_ld+set}" = set; then + withval="$with_gnu_ld" + test "$withval" = no || with_gnu_ld=yes +else + with_gnu_ld=no +fi; +ac_prog=ld +if test "$GCC" = yes; then + # Check if gcc -print-prog-name=ld gives a path. + echo "$as_me:$LINENO: checking for ld used by $CC" >&5 +echo $ECHO_N "checking for ld used by $CC... $ECHO_C" >&6 + case $host in + *-*-mingw*) + # gcc leaves a trailing carriage return which upsets mingw + ac_prog=`($CC -print-prog-name=ld) 2>&5 | tr -d '\015'` ;; + *) + ac_prog=`($CC -print-prog-name=ld) 2>&5` ;; + esac + case $ac_prog in + # Accept absolute paths. + [\\/]* | ?:[\\/]*) + re_direlt='/[^/][^/]*/\.\./' + # Canonicalize the pathname of ld + ac_prog=`echo $ac_prog| $SED 's%\\\\%/%g'` + while echo $ac_prog | grep "$re_direlt" > /dev/null 2>&1; do + ac_prog=`echo $ac_prog| $SED "s%$re_direlt%/%"` + done + test -z "$LD" && LD="$ac_prog" + ;; + "") + # If it fails, then pretend we aren't using GCC. + ac_prog=ld + ;; + *) + # If it is relative, then search for the first ld in PATH. + with_gnu_ld=unknown + ;; + esac +elif test "$with_gnu_ld" = yes; then + echo "$as_me:$LINENO: checking for GNU ld" >&5 +echo $ECHO_N "checking for GNU ld... $ECHO_C" >&6 +else + echo "$as_me:$LINENO: checking for non-GNU ld" >&5 +echo $ECHO_N "checking for non-GNU ld... $ECHO_C" >&6 +fi +if test "${lt_cv_path_LD+set}" = set; then + echo $ECHO_N "(cached) $ECHO_C" >&6 +else + if test -z "$LD"; then + lt_save_ifs="$IFS"; IFS=$PATH_SEPARATOR + for ac_dir in $PATH; do + IFS="$lt_save_ifs" + test -z "$ac_dir" && ac_dir=. + if test -f "$ac_dir/$ac_prog" || test -f "$ac_dir/$ac_prog$ac_exeext"; then + lt_cv_path_LD="$ac_dir/$ac_prog" + # Check to see if the program is GNU ld. I'd rather use --version, + # but apparently some variants of GNU ld only accept -v. + # Break only if it was the GNU/non-GNU ld that we prefer. + case `"$lt_cv_path_LD" -v 2>&1 </dev/null` in + *GNU* | *'with BFD'*) + test "$with_gnu_ld" != no && break + ;; + *) + test "$with_gnu_ld" != yes && break + ;; + esac + fi + done + IFS="$lt_save_ifs" +else + lt_cv_path_LD="$LD" # Let the user override the test with a path. +fi +fi + +LD="$lt_cv_path_LD" +if test -n "$LD"; then + echo "$as_me:$LINENO: result: $LD" >&5 +echo "${ECHO_T}$LD" >&6 +else + echo "$as_me:$LINENO: result: no" >&5 +echo "${ECHO_T}no" >&6 +fi +test -z "$LD" && { { echo "$as_me:$LINENO: error: no acceptable ld found in \$PATH" >&5 +echo "$as_me: error: no acceptable ld found in \$PATH" >&2;} + { (exit 1); exit 1; }; } +echo "$as_me:$LINENO: checking if the linker ($LD) is GNU ld" >&5 +echo $ECHO_N "checking if the linker ($LD) is GNU ld... $ECHO_C" >&6 +if test "${lt_cv_prog_gnu_ld+set}" = set; then + echo $ECHO_N "(cached) $ECHO_C" >&6 +else + # I'd rather use --version here, but apparently some GNU lds only accept -v. +case `$LD -v 2>&1 </dev/null` in +*GNU* | *'with BFD'*) + lt_cv_prog_gnu_ld=yes + ;; +*) + lt_cv_prog_gnu_ld=no + ;; +esac +fi +echo "$as_me:$LINENO: result: $lt_cv_prog_gnu_ld" >&5 +echo "${ECHO_T}$lt_cv_prog_gnu_ld" >&6 +with_gnu_ld=$lt_cv_prog_gnu_ld + + + + # Check if GNU C++ uses GNU ld as the underlying linker, since the + # archiving commands below assume that GNU ld is being used. + if test "$with_gnu_ld" = yes; then + archive_cmds_CXX='$CC -shared -nostdlib $predep_objects $libobjs $deplibs $postdep_objects $compiler_flags ${wl}-soname $wl$soname -o $lib' + archive_expsym_cmds_CXX='$CC -shared -nostdlib $predep_objects $libobjs $deplibs $postdep_objects $compiler_flags ${wl}-soname $wl$soname ${wl}-retain-symbols-file $wl$export_symbols -o $lib' + + hardcode_libdir_flag_spec_CXX='${wl}--rpath ${wl}$libdir' + export_dynamic_flag_spec_CXX='${wl}--export-dynamic' + + # If archive_cmds runs LD, not CC, wlarc should be empty + # XXX I think wlarc can be eliminated in ltcf-cxx, but I need to + # investigate it a little bit more. (MM) + wlarc='${wl}' + + # ancient GNU ld didn't support --whole-archive et. al. + if eval "`$CC -print-prog-name=ld` --help 2>&1" | \ + grep 'no-whole-archive' > /dev/null; then + whole_archive_flag_spec_CXX="$wlarc"'--whole-archive$convenience '"$wlarc"'--no-whole-archive' + else + whole_archive_flag_spec_CXX= + fi + else + with_gnu_ld=no + wlarc= + + # A generic and very simple default shared library creation + # command for GNU C++ for the case where it uses the native + # linker, instead of GNU ld. If possible, this setting should + # overridden to take advantage of the native linker features on + # the platform it is being used on. + archive_cmds_CXX='$CC -shared -nostdlib $predep_objects $libobjs $deplibs $postdep_objects $compiler_flags -o $lib' + fi + + # Commands to make compiler produce verbose output that lists + # what "hidden" libraries, object files and flags are used when + # linking a shared library. + output_verbose_link_cmd='$CC -shared $CFLAGS -v conftest.$objext 2>&1 | grep "\-L"' + +else + GXX=no + with_gnu_ld=no + wlarc= +fi + +# PORTME: fill in a description of your system's C++ link characteristics +echo "$as_me:$LINENO: checking whether the $compiler linker ($LD) supports shared libraries" >&5 +echo $ECHO_N "checking whether the $compiler linker ($LD) supports shared libraries... $ECHO_C" >&6 +ld_shlibs_CXX=yes +case $host_os in + aix3*) + # FIXME: insert proper C++ library support + ld_shlibs_CXX=no + ;; + aix4* | aix5*) + if test "$host_cpu" = ia64; then + # On IA64, the linker does run time linking by default, so we don't + # have to do anything special. + aix_use_runtimelinking=no + exp_sym_flag='-Bexport' + no_entry_flag="" + else + aix_use_runtimelinking=no + + # Test if we are trying to use run time linking or normal + # AIX style linking. If -brtl is somewhere in LDFLAGS, we + # need to do runtime linking. + case $host_os in aix4.[23]|aix4.[23].*|aix5*) + for ld_flag in $LDFLAGS; do + case $ld_flag in + *-brtl*) + aix_use_runtimelinking=yes + break + ;; + esac + done + ;; + esac + + exp_sym_flag='-bexport' + no_entry_flag='-bnoentry' + fi + + # When large executables or shared objects are built, AIX ld can + # have problems creating the table of contents. If linking a library + # or program results in "error TOC overflow" add -mminimal-toc to + # CXXFLAGS/CFLAGS for g++/gcc. In the cases where that is not + # enough to fix the problem, add -Wl,-bbigtoc to LDFLAGS. + + archive_cmds_CXX='' + hardcode_direct_CXX=yes + hardcode_libdir_separator_CXX=':' + link_all_deplibs_CXX=yes + + if test "$GXX" = yes; then + case $host_os in aix4.[012]|aix4.[012].*) + # We only want to do this on AIX 4.2 and lower, the check + # below for broken collect2 doesn't work under 4.3+ + collect2name=`${CC} -print-prog-name=collect2` + if test -f "$collect2name" && \ + strings "$collect2name" | grep resolve_lib_name >/dev/null + then + # We have reworked collect2 + hardcode_direct_CXX=yes + else + # We have old collect2 + hardcode_direct_CXX=unsupported + # It fails to find uninstalled libraries when the uninstalled + # path is not listed in the libpath. Setting hardcode_minus_L + # to unsupported forces relinking + hardcode_minus_L_CXX=yes + hardcode_libdir_flag_spec_CXX='-L$libdir' + hardcode_libdir_separator_CXX= + fi + ;; + esac + shared_flag='-shared' + if test "$aix_use_runtimelinking" = yes; then + shared_flag="$shared_flag "'${wl}-G' + fi + else + # not using gcc + if test "$host_cpu" = ia64; then + # VisualAge C++, Version 5.5 for AIX 5L for IA-64, Beta 3 Release + # chokes on -Wl,-G. The following line is correct: + shared_flag='-G' + else + if test "$aix_use_runtimelinking" = yes; then + shared_flag='${wl}-G' + else + shared_flag='${wl}-bM:SRE' + fi + fi + fi + + # It seems that -bexpall does not export symbols beginning with + # underscore (_), so it is better to generate a list of symbols to export. + always_export_symbols_CXX=yes + if test "$aix_use_runtimelinking" = yes; then + # Warning - without using the other runtime loading flags (-brtl), + # -berok will link without error, but may produce a broken library. + allow_undefined_flag_CXX='-berok' + # Determine the default libpath from the value encoded in an empty executable. + cat >conftest.$ac_ext <<_ACEOF +/* confdefs.h. */ +_ACEOF +cat confdefs.h >>conftest.$ac_ext +cat >>conftest.$ac_ext <<_ACEOF +/* end confdefs.h. */ + +int +main () +{ + + ; + return 0; +} +_ACEOF +rm -f conftest.$ac_objext conftest$ac_exeext +if { (eval echo "$as_me:$LINENO: \"$ac_link\"") >&5 + (eval $ac_link) 2>conftest.er1 + ac_status=$? + grep -v '^ *+' conftest.er1 >conftest.err + rm -f conftest.er1 + cat conftest.err >&5 + echo "$as_me:$LINENO: \$? = $ac_status" >&5 + (exit $ac_status); } && + { ac_try='test -z "$ac_cxx_werror_flag" + || test ! -s conftest.err' + { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5 + (eval $ac_try) 2>&5 + ac_status=$? + echo "$as_me:$LINENO: \$? = $ac_status" >&5 + (exit $ac_status); }; } && + { ac_try='test -s conftest$ac_exeext' + { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5 + (eval $ac_try) 2>&5 + ac_status=$? + echo "$as_me:$LINENO: \$? = $ac_status" >&5 + (exit $ac_status); }; }; then + +aix_libpath=`dump -H conftest$ac_exeext 2>/dev/null | $SED -n -e '/Import File Strings/,/^$/ { /^0/ { s/^0 *\(.*\)$/\1/; p; } +}'` +# Check for a 64-bit object if we didn't find anything. +if test -z "$aix_libpath"; then aix_libpath=`dump -HX64 conftest$ac_exeext 2>/dev/null | $SED -n -e '/Import File Strings/,/^$/ { /^0/ { s/^0 *\(.*\)$/\1/; p; } +}'`; fi +else + echo "$as_me: failed program was:" >&5 +sed 's/^/| /' conftest.$ac_ext >&5 + +fi +rm -f conftest.err conftest.$ac_objext \ + conftest$ac_exeext conftest.$ac_ext +if test -z "$aix_libpath"; then aix_libpath="/usr/lib:/lib"; fi + + hardcode_libdir_flag_spec_CXX='${wl}-blibpath:$libdir:'"$aix_libpath" + + archive_expsym_cmds_CXX="\$CC"' -o $output_objdir/$soname $libobjs $deplibs '"\${wl}$no_entry_flag"' $compiler_flags `if test "x${allow_undefined_flag}" != "x"; then echo "${wl}${allow_undefined_flag}"; else :; fi` '"\${wl}$exp_sym_flag:\$export_symbols $shared_flag" + else + if test "$host_cpu" = ia64; then + hardcode_libdir_flag_spec_CXX='${wl}-R $libdir:/usr/lib:/lib' + allow_undefined_flag_CXX="-z nodefs" + archive_expsym_cmds_CXX="\$CC $shared_flag"' -o $output_objdir/$soname $libobjs $deplibs '"\${wl}$no_entry_flag"' $compiler_flags ${wl}${allow_undefined_flag} '"\${wl}$exp_sym_flag:\$export_symbols" + else + # Determine the default libpath from the value encoded in an empty executable. + cat >conftest.$ac_ext <<_ACEOF +/* confdefs.h. */ +_ACEOF +cat confdefs.h >>conftest.$ac_ext +cat >>conftest.$ac_ext <<_ACEOF +/* end confdefs.h. */ + +int +main () +{ + + ; + return 0; +} +_ACEOF +rm -f conftest.$ac_objext conftest$ac_exeext +if { (eval echo "$as_me:$LINENO: \"$ac_link\"") >&5 + (eval $ac_link) 2>conftest.er1 + ac_status=$? + grep -v '^ *+' conftest.er1 >conftest.err + rm -f conftest.er1 + cat conftest.err >&5 + echo "$as_me:$LINENO: \$? = $ac_status" >&5 + (exit $ac_status); } && + { ac_try='test -z "$ac_cxx_werror_flag" + || test ! -s conftest.err' + { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5 + (eval $ac_try) 2>&5 + ac_status=$? + echo "$as_me:$LINENO: \$? = $ac_status" >&5 + (exit $ac_status); }; } && + { ac_try='test -s conftest$ac_exeext' + { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5 + (eval $ac_try) 2>&5 + ac_status=$? + echo "$as_me:$LINENO: \$? = $ac_status" >&5 + (exit $ac_status); }; }; then + +aix_libpath=`dump -H conftest$ac_exeext 2>/dev/null | $SED -n -e '/Import File Strings/,/^$/ { /^0/ { s/^0 *\(.*\)$/\1/; p; } +}'` +# Check for a 64-bit object if we didn't find anything. +if test -z "$aix_libpath"; then aix_libpath=`dump -HX64 conftest$ac_exeext 2>/dev/null | $SED -n -e '/Import File Strings/,/^$/ { /^0/ { s/^0 *\(.*\)$/\1/; p; } +}'`; fi +else + echo "$as_me: failed program was:" >&5 +sed 's/^/| /' conftest.$ac_ext >&5 + +fi +rm -f conftest.err conftest.$ac_objext \ + conftest$ac_exeext conftest.$ac_ext +if test -z "$aix_libpath"; then aix_libpath="/usr/lib:/lib"; fi + + hardcode_libdir_flag_spec_CXX='${wl}-blibpath:$libdir:'"$aix_libpath" + # Warning - without using the other run time loading flags, + # -berok will link without error, but may produce a broken library. + no_undefined_flag_CXX=' ${wl}-bernotok' + allow_undefined_flag_CXX=' ${wl}-berok' + # Exported symbols can be pulled into shared objects from archives + whole_archive_flag_spec_CXX='$convenience' + archive_cmds_need_lc_CXX=yes + # This is similar to how AIX traditionally builds its shared libraries. + archive_expsym_cmds_CXX="\$CC $shared_flag"' -o $output_objdir/$soname $libobjs $deplibs ${wl}-bnoentry $compiler_flags ${wl}-bE:$export_symbols${allow_undefined_flag}~$AR $AR_FLAGS $output_objdir/$libname$release.a $output_objdir/$soname' + fi + fi + ;; + + beos*) + if $LD --help 2>&1 | grep ': supported targets:.* elf' > /dev/null; then + allow_undefined_flag_CXX=unsupported + # Joseph Beckenbach <jrb3@best.com> says some releases of gcc + # support --undefined. This deserves some investigation. FIXME + archive_cmds_CXX='$CC -nostart $libobjs $deplibs $compiler_flags ${wl}-soname $wl$soname -o $lib' + else + ld_shlibs_CXX=no + fi + ;; + + chorus*) + case $cc_basename in + *) + # FIXME: insert proper C++ library support + ld_shlibs_CXX=no + ;; + esac + ;; + + cygwin* | mingw* | pw32*) + # _LT_AC_TAGVAR(hardcode_libdir_flag_spec, CXX) is actually meaningless, + # as there is no search path for DLLs. + hardcode_libdir_flag_spec_CXX='-L$libdir' + allow_undefined_flag_CXX=unsupported + always_export_symbols_CXX=no + enable_shared_with_static_runtimes_CXX=yes + + if $LD --help 2>&1 | grep 'auto-import' > /dev/null; then + archive_cmds_CXX='$CC -shared -nostdlib $predep_objects $libobjs $deplibs $postdep_objects $compiler_flags -o $output_objdir/$soname ${wl}--enable-auto-image-base -Xlinker --out-implib -Xlinker $lib' + # If the export-symbols file already is a .def file (1st line + # is EXPORTS), use it as is; otherwise, prepend... + archive_expsym_cmds_CXX='if test "x`$SED 1q $export_symbols`" = xEXPORTS; then + cp $export_symbols $output_objdir/$soname.def; + else + echo EXPORTS > $output_objdir/$soname.def; + cat $export_symbols >> $output_objdir/$soname.def; + fi~ + $CC -shared -nostdlib $output_objdir/$soname.def $predep_objects $libobjs $deplibs $postdep_objects $compiler_flags -o $output_objdir/$soname ${wl}--enable-auto-image-base -Xlinker --out-implib -Xlinker $lib' + else + ld_shlibs_CXX=no + fi + ;; + darwin* | rhapsody*) + case $host_os in + rhapsody* | darwin1.[012]) + allow_undefined_flag_CXX='${wl}-undefined ${wl}suppress' + ;; + *) # Darwin 1.3 on + if test -z ${MACOSX_DEPLOYMENT_TARGET} ; then + allow_undefined_flag_CXX='${wl}-flat_namespace ${wl}-undefined ${wl}suppress' + else + case ${MACOSX_DEPLOYMENT_TARGET} in + 10.[012]) + allow_undefined_flag_CXX='${wl}-flat_namespace ${wl}-undefined ${wl}suppress' + ;; + 10.*) + allow_undefined_flag_CXX='${wl}-undefined ${wl}dynamic_lookup' + ;; + esac + fi + ;; + esac + archive_cmds_need_lc_CXX=no + hardcode_direct_CXX=no + hardcode_automatic_CXX=yes + hardcode_shlibpath_var_CXX=unsupported + whole_archive_flag_spec_CXX='' + link_all_deplibs_CXX=yes + + if test "$GXX" = yes ; then + lt_int_apple_cc_single_mod=no + output_verbose_link_cmd='echo' + if $CC -dumpspecs 2>&1 | $EGREP 'single_module' >/dev/null ; then + lt_int_apple_cc_single_mod=yes + fi + if test "X$lt_int_apple_cc_single_mod" = Xyes ; then + archive_cmds_CXX='$CC -dynamiclib -single_module $allow_undefined_flag -o $lib $libobjs $deplibs $compiler_flags -install_name $rpath/$soname $verstring' + else + archive_cmds_CXX='$CC -r -keep_private_externs -nostdlib -o ${lib}-master.o $libobjs~$CC -dynamiclib $allow_undefined_flag -o $lib ${lib}-master.o $deplibs $compiler_flags -install_name $rpath/$soname $verstring' + fi + module_cmds_CXX='$CC $allow_undefined_flag -o $lib -bundle $libobjs $deplibs$compiler_flags' + # Don't fix this by using the ld -exported_symbols_list flag, it doesn't exist in older darwin lds + if test "X$lt_int_apple_cc_single_mod" = Xyes ; then + archive_expsym_cmds_CXX='sed -e "s,#.*,," -e "s,^[ ]*,," -e "s,^\(..*\),_&," < $export_symbols > $output_objdir/${libname}-symbols.expsym~$CC -dynamiclib -single_module $allow_undefined_flag -o $lib $libobjs $deplibs $compiler_flags -install_name $rpath/$soname $verstring~nmedit -s $output_objdir/${libname}-symbols.expsym ${lib}' + else + archive_expsym_cmds_CXX='sed -e "s,#.*,," -e "s,^[ ]*,," -e "s,^\(..*\),_&," < $export_symbols > $output_objdir/${libname}-symbols.expsym~$CC -r -keep_private_externs -nostdlib -o ${lib}-master.o $libobjs~$CC -dynamiclib $allow_undefined_flag -o $lib ${lib}-master.o $deplibs $compiler_flags -install_name $rpath/$soname $verstring~nmedit -s $output_objdir/${libname}-symbols.expsym ${lib}' + fi + module_expsym_cmds_CXX='sed -e "s,#.*,," -e "s,^[ ]*,," -e "s,^\(..*\),_&," < $export_symbols > $output_objdir/${libname}-symbols.expsym~$CC $allow_undefined_flag -o $lib -bundle $libobjs $deplibs$compiler_flags~nmedit -s $output_objdir/${libname}-symbols.expsym ${lib}' + else + case $cc_basename in + xlc*) + output_verbose_link_cmd='echo' + archive_cmds_CXX='$CC -qmkshrobj ${wl}-single_module $allow_undefined_flag -o $lib $libobjs $deplibs $compiler_flags ${wl}-install_name ${wl}`echo $rpath/$soname` $verstring' + module_cmds_CXX='$CC $allow_undefined_flag -o $lib -bundle $libobjs $deplibs$compiler_flags' + # Don't fix this by using the ld -exported_symbols_list flag, it doesn't exist in older darwin lds + archive_expsym_cmds_CXX='sed -e "s,#.*,," -e "s,^[ ]*,," -e "s,^\(..*\),_&," < $export_symbols > $output_objdir/${libname}-symbols.expsym~$CC -qmkshrobj ${wl}-single_module $allow_undefined_flag -o $lib $libobjs $deplibs $compiler_flags ${wl}-install_name ${wl}$rpath/$soname $verstring~nmedit -s $output_objdir/${libname}-symbols.expsym ${lib}' + module_expsym_cmds_CXX='sed -e "s,#.*,," -e "s,^[ ]*,," -e "s,^\(..*\),_&," < $export_symbols > $output_objdir/${libname}-symbols.expsym~$CC $allow_undefined_flag -o $lib -bundle $libobjs $deplibs$compiler_flags~nmedit -s $output_objdir/${libname}-symbols.expsym ${lib}' + ;; + *) + ld_shlibs_CXX=no + ;; + esac + fi + ;; + + dgux*) + case $cc_basename in + ec++*) + # FIXME: insert proper C++ library support + ld_shlibs_CXX=no + ;; + ghcx*) + # Green Hills C++ Compiler + # FIXME: insert proper C++ library support + ld_shlibs_CXX=no + ;; + *) + # FIXME: insert proper C++ library support + ld_shlibs_CXX=no + ;; + esac + ;; + freebsd[12]*) + # C++ shared libraries reported to be fairly broken before switch to ELF + ld_shlibs_CXX=no + ;; + freebsd-elf*) + archive_cmds_need_lc_CXX=no + ;; + freebsd* | kfreebsd*-gnu | dragonfly*) + # FreeBSD 3 and later use GNU C++ and GNU ld with standard ELF + # conventions + ld_shlibs_CXX=yes + ;; + gnu*) + ;; + hpux9*) + hardcode_libdir_flag_spec_CXX='${wl}+b ${wl}$libdir' + hardcode_libdir_separator_CXX=: + export_dynamic_flag_spec_CXX='${wl}-E' + hardcode_direct_CXX=yes + hardcode_minus_L_CXX=yes # Not in the search PATH, + # but as the default + # location of the library. + + case $cc_basename in + CC*) + # FIXME: insert proper C++ library support + ld_shlibs_CXX=no + ;; + aCC*) + archive_cmds_CXX='$rm $output_objdir/$soname~$CC -b ${wl}+b ${wl}$install_libdir -o $output_objdir/$soname $predep_objects $libobjs $deplibs $postdep_objects $compiler_flags~test $output_objdir/$soname = $lib || mv $output_objdir/$soname $lib' + # Commands to make compiler produce verbose output that lists + # what "hidden" libraries, object files and flags are used when + # linking a shared library. + # + # There doesn't appear to be a way to prevent this compiler from + # explicitly linking system object files so we need to strip them + # from the output so that they don't get included in the library + # dependencies. + output_verbose_link_cmd='templist=`($CC -b $CFLAGS -v conftest.$objext 2>&1) | grep "[-]L"`; list=""; for z in $templist; do case $z in conftest.$objext) list="$list $z";; *.$objext);; *) list="$list $z";;esac; done; echo $list' + ;; + *) + if test "$GXX" = yes; then + archive_cmds_CXX='$rm $output_objdir/$soname~$CC -shared -nostdlib -fPIC ${wl}+b ${wl}$install_libdir -o $output_objdir/$soname $predep_objects $libobjs $deplibs $postdep_objects $compiler_flags~test $output_objdir/$soname = $lib || mv $output_objdir/$soname $lib' + else + # FIXME: insert proper C++ library support + ld_shlibs_CXX=no + fi + ;; + esac + ;; + hpux10*|hpux11*) + if test $with_gnu_ld = no; then + hardcode_libdir_flag_spec_CXX='${wl}+b ${wl}$libdir' + hardcode_libdir_separator_CXX=: + + case $host_cpu in + hppa*64*|ia64*) + hardcode_libdir_flag_spec_ld_CXX='+b $libdir' + ;; + *) + export_dynamic_flag_spec_CXX='${wl}-E' + ;; + esac + fi + case $host_cpu in + hppa*64*|ia64*) + hardcode_direct_CXX=no + hardcode_shlibpath_var_CXX=no + ;; + *) + hardcode_direct_CXX=yes + hardcode_minus_L_CXX=yes # Not in the search PATH, + # but as the default + # location of the library. + ;; + esac + + case $cc_basename in + CC*) + # FIXME: insert proper C++ library support + ld_shlibs_CXX=no + ;; + aCC*) + case $host_cpu in + hppa*64*) + archive_cmds_CXX='$CC -b ${wl}+h ${wl}$soname -o $lib $predep_objects $libobjs $deplibs $postdep_objects $compiler_flags' + ;; + ia64*) + archive_cmds_CXX='$CC -b ${wl}+h ${wl}$soname ${wl}+nodefaultrpath -o $lib $predep_objects $libobjs $deplibs $postdep_objects $compiler_flags' + ;; + *) + archive_cmds_CXX='$CC -b ${wl}+h ${wl}$soname ${wl}+b ${wl}$install_libdir -o $lib $predep_objects $libobjs $deplibs $postdep_objects $compiler_flags' + ;; + esac + # Commands to make compiler produce verbose output that lists + # what "hidden" libraries, object files and flags are used when + # linking a shared library. + # + # There doesn't appear to be a way to prevent this compiler from + # explicitly linking system object files so we need to strip them + # from the output so that they don't get included in the library + # dependencies. + output_verbose_link_cmd='templist=`($CC -b $CFLAGS -v conftest.$objext 2>&1) | grep "\-L"`; list=""; for z in $templist; do case $z in conftest.$objext) list="$list $z";; *.$objext);; *) list="$list $z";;esac; done; echo $list' + ;; + *) + if test "$GXX" = yes; then + if test $with_gnu_ld = no; then + case $host_cpu in + hppa*64*) + archive_cmds_CXX='$CC -shared -nostdlib -fPIC ${wl}+h ${wl}$soname -o $lib $predep_objects $libobjs $deplibs $postdep_objects $compiler_flags' + ;; + ia64*) + archive_cmds_CXX='$CC -shared -nostdlib -fPIC ${wl}+h ${wl}$soname ${wl}+nodefaultrpath -o $lib $predep_objects $libobjs $deplibs $postdep_objects $compiler_flags' + ;; + *) + archive_cmds_CXX='$CC -shared -nostdlib -fPIC ${wl}+h ${wl}$soname ${wl}+b ${wl}$install_libdir -o $lib $predep_objects $libobjs $deplibs $postdep_objects $compiler_flags' + ;; + esac + fi + else + # FIXME: insert proper C++ library support + ld_shlibs_CXX=no + fi + ;; + esac + ;; + interix3*) + hardcode_direct_CXX=no + hardcode_shlibpath_var_CXX=no + hardcode_libdir_flag_spec_CXX='${wl}-rpath,$libdir' + export_dynamic_flag_spec_CXX='${wl}-E' + # Hack: On Interix 3.x, we cannot compile PIC because of a broken gcc. + # Instead, shared libraries are loaded at an image base (0x10000000 by + # default) and relocated if they conflict, which is a slow very memory + # consuming and fragmenting process. To avoid this, we pick a random, + # 256 KiB-aligned image base between 0x50000000 and 0x6FFC0000 at link + # time. Moving up from 0x10000000 also allows more sbrk(2) space. + archive_cmds_CXX='$CC -shared $pic_flag $libobjs $deplibs $compiler_flags ${wl}-h,$soname ${wl}--image-base,`expr ${RANDOM-$$} % 4096 / 2 \* 262144 + 1342177280` -o $lib' + archive_expsym_cmds_CXX='sed "s,^,_," $export_symbols >$output_objdir/$soname.expsym~$CC -shared $pic_flag $libobjs $deplibs $compiler_flags ${wl}-h,$soname ${wl}--retain-symbols-file,$output_objdir/$soname.expsym ${wl}--image-base,`expr ${RANDOM-$$} % 4096 / 2 \* 262144 + 1342177280` -o $lib' + ;; + irix5* | irix6*) + case $cc_basename in + CC*) + # SGI C++ + archive_cmds_CXX='$CC -shared -all -multigot $predep_objects $libobjs $deplibs $postdep_objects $compiler_flags -soname $soname `test -n "$verstring" && echo -set_version $verstring` -update_registry ${output_objdir}/so_locations -o $lib' + + # Archives containing C++ object files must be created using + # "CC -ar", where "CC" is the IRIX C++ compiler. This is + # necessary to make sure instantiated templates are included + # in the archive. + old_archive_cmds_CXX='$CC -ar -WR,-u -o $oldlib $oldobjs' + ;; + *) + if test "$GXX" = yes; then + if test "$with_gnu_ld" = no; then + archive_cmds_CXX='$CC -shared -nostdlib $predep_objects $libobjs $deplibs $postdep_objects $compiler_flags ${wl}-soname ${wl}$soname `test -n "$verstring" && echo ${wl}-set_version ${wl}$verstring` ${wl}-update_registry ${wl}${output_objdir}/so_locations -o $lib' + else + archive_cmds_CXX='$CC -shared -nostdlib $predep_objects $libobjs $deplibs $postdep_objects $compiler_flags ${wl}-soname ${wl}$soname `test -n "$verstring" && echo ${wl}-set_version ${wl}$verstring` -o $lib' + fi + fi + link_all_deplibs_CXX=yes + ;; + esac + hardcode_libdir_flag_spec_CXX='${wl}-rpath ${wl}$libdir' + hardcode_libdir_separator_CXX=: + ;; + linux*) + case $cc_basename in + KCC*) + # Kuck and Associates, Inc. (KAI) C++ Compiler + + # KCC will only create a shared library if the output file + # ends with ".so" (or ".sl" for HP-UX), so rename the library + # to its proper name (with version) after linking. + archive_cmds_CXX='tempext=`echo $shared_ext | $SED -e '\''s/\([^()0-9A-Za-z{}]\)/\\\\\1/g'\''`; templib=`echo $lib | $SED -e "s/\${tempext}\..*/.so/"`; $CC $predep_objects $libobjs $deplibs $postdep_objects $compiler_flags --soname $soname -o \$templib; mv \$templib $lib' + archive_expsym_cmds_CXX='tempext=`echo $shared_ext | $SED -e '\''s/\([^()0-9A-Za-z{}]\)/\\\\\1/g'\''`; templib=`echo $lib | $SED -e "s/\${tempext}\..*/.so/"`; $CC $predep_objects $libobjs $deplibs $postdep_objects $compiler_flags --soname $soname -o \$templib ${wl}-retain-symbols-file,$export_symbols; mv \$templib $lib' + # Commands to make compiler produce verbose output that lists + # what "hidden" libraries, object files and flags are used when + # linking a shared library. + # + # There doesn't appear to be a way to prevent this compiler from + # explicitly linking system object files so we need to strip them + # from the output so that they don't get included in the library + # dependencies. + output_verbose_link_cmd='templist=`$CC $CFLAGS -v conftest.$objext -o libconftest$shared_ext 2>&1 | grep "ld"`; rm -f libconftest$shared_ext; list=""; for z in $templist; do case $z in conftest.$objext) list="$list $z";; *.$objext);; *) list="$list $z";;esac; done; echo $list' + + hardcode_libdir_flag_spec_CXX='${wl}--rpath,$libdir' + export_dynamic_flag_spec_CXX='${wl}--export-dynamic' + + # Archives containing C++ object files must be created using + # "CC -Bstatic", where "CC" is the KAI C++ compiler. + old_archive_cmds_CXX='$CC -Bstatic -o $oldlib $oldobjs' + ;; + icpc*) + # Intel C++ + with_gnu_ld=yes + # version 8.0 and above of icpc choke on multiply defined symbols + # if we add $predep_objects and $postdep_objects, however 7.1 and + # earlier do not add the objects themselves. + case `$CC -V 2>&1` in + *"Version 7."*) + archive_cmds_CXX='$CC -shared $predep_objects $libobjs $deplibs $postdep_objects $compiler_flags ${wl}-soname $wl$soname -o $lib' + archive_expsym_cmds_CXX='$CC -shared $predep_objects $libobjs $deplibs $postdep_objects $compiler_flags ${wl}-soname $wl$soname ${wl}-retain-symbols-file $wl$export_symbols -o $lib' + ;; + *) # Version 8.0 or newer + tmp_idyn= + case $host_cpu in + ia64*) tmp_idyn=' -i_dynamic';; + esac + archive_cmds_CXX='$CC -shared'"$tmp_idyn"' $libobjs $deplibs $compiler_flags ${wl}-soname $wl$soname -o $lib' + archive_expsym_cmds_CXX='$CC -shared'"$tmp_idyn"' $libobjs $deplibs $compiler_flags ${wl}-soname $wl$soname ${wl}-retain-symbols-file $wl$export_symbols -o $lib' + ;; + esac + archive_cmds_need_lc_CXX=no + hardcode_libdir_flag_spec_CXX='${wl}-rpath,$libdir' + export_dynamic_flag_spec_CXX='${wl}--export-dynamic' + whole_archive_flag_spec_CXX='${wl}--whole-archive$convenience ${wl}--no-whole-archive' + ;; + pgCC*) + # Portland Group C++ compiler + archive_cmds_CXX='$CC -shared $pic_flag $predep_objects $libobjs $deplibs $postdep_objects $compiler_flags ${wl}-soname ${wl}$soname -o $lib' + archive_expsym_cmds_CXX='$CC -shared $pic_flag $predep_objects $libobjs $deplibs $postdep_objects $compiler_flags ${wl}-soname ${wl}$soname ${wl}-retain-symbols-file ${wl}$export_symbols -o $lib' + + hardcode_libdir_flag_spec_CXX='${wl}--rpath ${wl}$libdir' + export_dynamic_flag_spec_CXX='${wl}--export-dynamic' + whole_archive_flag_spec_CXX='${wl}--whole-archive`for conv in $convenience\"\"; do test -n \"$conv\" && new_convenience=\"$new_convenience,$conv\"; done; $echo \"$new_convenience\"` ${wl}--no-whole-archive' + ;; + cxx*) + # Compaq C++ + archive_cmds_CXX='$CC -shared $predep_objects $libobjs $deplibs $postdep_objects $compiler_flags ${wl}-soname $wl$soname -o $lib' + archive_expsym_cmds_CXX='$CC -shared $predep_objects $libobjs $deplibs $postdep_objects $compiler_flags ${wl}-soname $wl$soname -o $lib ${wl}-retain-symbols-file $wl$export_symbols' + + runpath_var=LD_RUN_PATH + hardcode_libdir_flag_spec_CXX='-rpath $libdir' + hardcode_libdir_separator_CXX=: + + # Commands to make compiler produce verbose output that lists + # what "hidden" libraries, object files and flags are used when + # linking a shared library. + # + # There doesn't appear to be a way to prevent this compiler from + # explicitly linking system object files so we need to strip them + # from the output so that they don't get included in the library + # dependencies. + output_verbose_link_cmd='templist=`$CC -shared $CFLAGS -v conftest.$objext 2>&1 | grep "ld"`; templist=`echo $templist | $SED "s/\(^.*ld.*\)\( .*ld .*$\)/\1/"`; list=""; for z in $templist; do case $z in conftest.$objext) list="$list $z";; *.$objext);; *) list="$list $z";;esac; done; echo $list' + ;; + esac + ;; + lynxos*) + # FIXME: insert proper C++ library support + ld_shlibs_CXX=no + ;; + m88k*) + # FIXME: insert proper C++ library support + ld_shlibs_CXX=no + ;; + mvs*) + case $cc_basename in + cxx*) + # FIXME: insert proper C++ library support + ld_shlibs_CXX=no + ;; + *) + # FIXME: insert proper C++ library support + ld_shlibs_CXX=no + ;; + esac + ;; + netbsd*) + if echo __ELF__ | $CC -E - | grep __ELF__ >/dev/null; then + archive_cmds_CXX='$LD -Bshareable -o $lib $predep_objects $libobjs $deplibs $postdep_objects $linker_flags' + wlarc= + hardcode_libdir_flag_spec_CXX='-R$libdir' + hardcode_direct_CXX=yes + hardcode_shlibpath_var_CXX=no + fi + # Workaround some broken pre-1.5 toolchains + output_verbose_link_cmd='$CC -shared $CFLAGS -v conftest.$objext 2>&1 | grep conftest.$objext | $SED -e "s:-lgcc -lc -lgcc::"' + ;; + openbsd2*) + # C++ shared libraries are fairly broken + ld_shlibs_CXX=no + ;; + openbsd*) + hardcode_direct_CXX=yes + hardcode_shlibpath_var_CXX=no + archive_cmds_CXX='$CC -shared $pic_flag $predep_objects $libobjs $deplibs $postdep_objects $compiler_flags -o $lib' + hardcode_libdir_flag_spec_CXX='${wl}-rpath,$libdir' + if test -z "`echo __ELF__ | $CC -E - | grep __ELF__`" || test "$host_os-$host_cpu" = "openbsd2.8-powerpc"; then + archive_expsym_cmds_CXX='$CC -shared $pic_flag $predep_objects $libobjs $deplibs $postdep_objects $compiler_flags ${wl}-retain-symbols-file,$export_symbols -o $lib' + export_dynamic_flag_spec_CXX='${wl}-E' + whole_archive_flag_spec_CXX="$wlarc"'--whole-archive$convenience '"$wlarc"'--no-whole-archive' + fi + output_verbose_link_cmd='echo' + ;; + osf3*) + case $cc_basename in + KCC*) + # Kuck and Associates, Inc. (KAI) C++ Compiler + + # KCC will only create a shared library if the output file + # ends with ".so" (or ".sl" for HP-UX), so rename the library + # to its proper name (with version) after linking. + archive_cmds_CXX='tempext=`echo $shared_ext | $SED -e '\''s/\([^()0-9A-Za-z{}]\)/\\\\\1/g'\''`; templib=`echo $lib | $SED -e "s/\${tempext}\..*/.so/"`; $CC $predep_objects $libobjs $deplibs $postdep_objects $compiler_flags --soname $soname -o \$templib; mv \$templib $lib' + + hardcode_libdir_flag_spec_CXX='${wl}-rpath,$libdir' + hardcode_libdir_separator_CXX=: + + # Archives containing C++ object files must be created using + # "CC -Bstatic", where "CC" is the KAI C++ compiler. + old_archive_cmds_CXX='$CC -Bstatic -o $oldlib $oldobjs' + + ;; + RCC*) + # Rational C++ 2.4.1 + # FIXME: insert proper C++ library support + ld_shlibs_CXX=no + ;; + cxx*) + allow_undefined_flag_CXX=' ${wl}-expect_unresolved ${wl}\*' + archive_cmds_CXX='$CC -shared${allow_undefined_flag} $predep_objects $libobjs $deplibs $postdep_objects $compiler_flags ${wl}-soname $soname `test -n "$verstring" && echo ${wl}-set_version $verstring` -update_registry ${output_objdir}/so_locations -o $lib' + + hardcode_libdir_flag_spec_CXX='${wl}-rpath ${wl}$libdir' + hardcode_libdir_separator_CXX=: + + # Commands to make compiler produce verbose output that lists + # what "hidden" libraries, object files and flags are used when + # linking a shared library. + # + # There doesn't appear to be a way to prevent this compiler from + # explicitly linking system object files so we need to strip them + # from the output so that they don't get included in the library + # dependencies. + output_verbose_link_cmd='templist=`$CC -shared $CFLAGS -v conftest.$objext 2>&1 | grep "ld" | grep -v "ld:"`; templist=`echo $templist | $SED "s/\(^.*ld.*\)\( .*ld.*$\)/\1/"`; list=""; for z in $templist; do case $z in conftest.$objext) list="$list $z";; *.$objext);; *) list="$list $z";;esac; done; echo $list' + ;; + *) + if test "$GXX" = yes && test "$with_gnu_ld" = no; then + allow_undefined_flag_CXX=' ${wl}-expect_unresolved ${wl}\*' + archive_cmds_CXX='$CC -shared -nostdlib ${allow_undefined_flag} $predep_objects $libobjs $deplibs $postdep_objects $compiler_flags ${wl}-soname ${wl}$soname `test -n "$verstring" && echo ${wl}-set_version ${wl}$verstring` ${wl}-update_registry ${wl}${output_objdir}/so_locations -o $lib' + + hardcode_libdir_flag_spec_CXX='${wl}-rpath ${wl}$libdir' + hardcode_libdir_separator_CXX=: + + # Commands to make compiler produce verbose output that lists + # what "hidden" libraries, object files and flags are used when + # linking a shared library. + output_verbose_link_cmd='$CC -shared $CFLAGS -v conftest.$objext 2>&1 | grep "\-L"' + + else + # FIXME: insert proper C++ library support + ld_shlibs_CXX=no + fi + ;; + esac + ;; + osf4* | osf5*) + case $cc_basename in + KCC*) + # Kuck and Associates, Inc. (KAI) C++ Compiler + + # KCC will only create a shared library if the output file + # ends with ".so" (or ".sl" for HP-UX), so rename the library + # to its proper name (with version) after linking. + archive_cmds_CXX='tempext=`echo $shared_ext | $SED -e '\''s/\([^()0-9A-Za-z{}]\)/\\\\\1/g'\''`; templib=`echo $lib | $SED -e "s/\${tempext}\..*/.so/"`; $CC $predep_objects $libobjs $deplibs $postdep_objects $compiler_flags --soname $soname -o \$templib; mv \$templib $lib' + + hardcode_libdir_flag_spec_CXX='${wl}-rpath,$libdir' + hardcode_libdir_separator_CXX=: + + # Archives containing C++ object files must be created using + # the KAI C++ compiler. + old_archive_cmds_CXX='$CC -o $oldlib $oldobjs' + ;; + RCC*) + # Rational C++ 2.4.1 + # FIXME: insert proper C++ library support + ld_shlibs_CXX=no + ;; + cxx*) + allow_undefined_flag_CXX=' -expect_unresolved \*' + archive_cmds_CXX='$CC -shared${allow_undefined_flag} $predep_objects $libobjs $deplibs $postdep_objects $compiler_flags -msym -soname $soname `test -n "$verstring" && echo -set_version $verstring` -update_registry ${output_objdir}/so_locations -o $lib' + archive_expsym_cmds_CXX='for i in `cat $export_symbols`; do printf "%s %s\\n" -exported_symbol "\$i" >> $lib.exp; done~ + echo "-hidden">> $lib.exp~ + $CC -shared$allow_undefined_flag $predep_objects $libobjs $deplibs $postdep_objects $compiler_flags -msym -soname $soname -Wl,-input -Wl,$lib.exp `test -n "$verstring" && echo -set_version $verstring` -update_registry ${output_objdir}/so_locations -o $lib~ + $rm $lib.exp' + + hardcode_libdir_flag_spec_CXX='-rpath $libdir' + hardcode_libdir_separator_CXX=: + + # Commands to make compiler produce verbose output that lists + # what "hidden" libraries, object files and flags are used when + # linking a shared library. + # + # There doesn't appear to be a way to prevent this compiler from + # explicitly linking system object files so we need to strip them + # from the output so that they don't get included in the library + # dependencies. + output_verbose_link_cmd='templist=`$CC -shared $CFLAGS -v conftest.$objext 2>&1 | grep "ld" | grep -v "ld:"`; templist=`echo $templist | $SED "s/\(^.*ld.*\)\( .*ld.*$\)/\1/"`; list=""; for z in $templist; do case $z in conftest.$objext) list="$list $z";; *.$objext);; *) list="$list $z";;esac; done; echo $list' + ;; + *) + if test "$GXX" = yes && test "$with_gnu_ld" = no; then + allow_undefined_flag_CXX=' ${wl}-expect_unresolved ${wl}\*' + archive_cmds_CXX='$CC -shared -nostdlib ${allow_undefined_flag} $predep_objects $libobjs $deplibs $postdep_objects $compiler_flags ${wl}-msym ${wl}-soname ${wl}$soname `test -n "$verstring" && echo ${wl}-set_version ${wl}$verstring` ${wl}-update_registry ${wl}${output_objdir}/so_locations -o $lib' + + hardcode_libdir_flag_spec_CXX='${wl}-rpath ${wl}$libdir' + hardcode_libdir_separator_CXX=: + + # Commands to make compiler produce verbose output that lists + # what "hidden" libraries, object files and flags are used when + # linking a shared library. + output_verbose_link_cmd='$CC -shared $CFLAGS -v conftest.$objext 2>&1 | grep "\-L"' + + else + # FIXME: insert proper C++ library support + ld_shlibs_CXX=no + fi + ;; + esac + ;; + psos*) + # FIXME: insert proper C++ library support + ld_shlibs_CXX=no + ;; + sunos4*) + case $cc_basename in + CC*) + # Sun C++ 4.x + # FIXME: insert proper C++ library support + ld_shlibs_CXX=no + ;; + lcc*) + # Lucid + # FIXME: insert proper C++ library support + ld_shlibs_CXX=no + ;; + *) + # FIXME: insert proper C++ library support + ld_shlibs_CXX=no + ;; + esac + ;; + solaris*) + case $cc_basename in + CC*) + # Sun C++ 4.2, 5.x and Centerline C++ + archive_cmds_need_lc_CXX=yes + no_undefined_flag_CXX=' -zdefs' + archive_cmds_CXX='$CC -G${allow_undefined_flag} -h$soname -o $lib $predep_objects $libobjs $deplibs $postdep_objects $compiler_flags' + archive_expsym_cmds_CXX='$echo "{ global:" > $lib.exp~cat $export_symbols | $SED -e "s/\(.*\)/\1;/" >> $lib.exp~$echo "local: *; };" >> $lib.exp~ + $CC -G${allow_undefined_flag} ${wl}-M ${wl}$lib.exp -h$soname -o $lib $predep_objects $libobjs $deplibs $postdep_objects $compiler_flags~$rm $lib.exp' + + hardcode_libdir_flag_spec_CXX='-R$libdir' + hardcode_shlibpath_var_CXX=no + case $host_os in + solaris2.[0-5] | solaris2.[0-5].*) ;; + *) + # The C++ compiler is used as linker so we must use $wl + # flag to pass the commands to the underlying system + # linker. We must also pass each convience library through + # to the system linker between allextract/defaultextract. + # The C++ compiler will combine linker options so we + # cannot just pass the convience library names through + # without $wl. + # Supported since Solaris 2.6 (maybe 2.5.1?) + whole_archive_flag_spec_CXX='${wl}-z ${wl}allextract`for conv in $convenience\"\"; do test -n \"$conv\" && new_convenience=\"$new_convenience,$conv\"; done; $echo \"$new_convenience\"` ${wl}-z ${wl}defaultextract' + ;; + esac + link_all_deplibs_CXX=yes + + output_verbose_link_cmd='echo' + + # Archives containing C++ object files must be created using + # "CC -xar", where "CC" is the Sun C++ compiler. This is + # necessary to make sure instantiated templates are included + # in the archive. + old_archive_cmds_CXX='$CC -xar -o $oldlib $oldobjs' + ;; + gcx*) + # Green Hills C++ Compiler + archive_cmds_CXX='$CC -shared $predep_objects $libobjs $deplibs $postdep_objects $compiler_flags ${wl}-h $wl$soname -o $lib' + + # The C++ compiler must be used to create the archive. + old_archive_cmds_CXX='$CC $LDFLAGS -archive -o $oldlib $oldobjs' + ;; + *) + # GNU C++ compiler with Solaris linker + if test "$GXX" = yes && test "$with_gnu_ld" = no; then + no_undefined_flag_CXX=' ${wl}-z ${wl}defs' + if $CC --version | grep -v '^2\.7' > /dev/null; then + archive_cmds_CXX='$CC -shared -nostdlib $LDFLAGS $predep_objects $libobjs $deplibs $postdep_objects $compiler_flags ${wl}-h $wl$soname -o $lib' + archive_expsym_cmds_CXX='$echo "{ global:" > $lib.exp~cat $export_symbols | $SED -e "s/\(.*\)/\1;/" >> $lib.exp~$echo "local: *; };" >> $lib.exp~ + $CC -shared -nostdlib ${wl}-M $wl$lib.exp -o $lib $predep_objects $libobjs $deplibs $postdep_objects $compiler_flags~$rm $lib.exp' + + # Commands to make compiler produce verbose output that lists + # what "hidden" libraries, object files and flags are used when + # linking a shared library. + output_verbose_link_cmd="$CC -shared $CFLAGS -v conftest.$objext 2>&1 | grep \"\-L\"" + else + # g++ 2.7 appears to require `-G' NOT `-shared' on this + # platform. + archive_cmds_CXX='$CC -G -nostdlib $LDFLAGS $predep_objects $libobjs $deplibs $postdep_objects $compiler_flags ${wl}-h $wl$soname -o $lib' + archive_expsym_cmds_CXX='$echo "{ global:" > $lib.exp~cat $export_symbols | $SED -e "s/\(.*\)/\1;/" >> $lib.exp~$echo "local: *; };" >> $lib.exp~ + $CC -G -nostdlib ${wl}-M $wl$lib.exp -o $lib $predep_objects $libobjs $deplibs $postdep_objects $compiler_flags~$rm $lib.exp' + + # Commands to make compiler produce verbose output that lists + # what "hidden" libraries, object files and flags are used when + # linking a shared library. + output_verbose_link_cmd="$CC -G $CFLAGS -v conftest.$objext 2>&1 | grep \"\-L\"" + fi + + hardcode_libdir_flag_spec_CXX='${wl}-R $wl$libdir' + fi + ;; + esac + ;; + sysv4*uw2* | sysv5OpenUNIX* | sysv5UnixWare7.[01].[10]* | unixware7* | sco3.2v5.0.[024]*) + no_undefined_flag_CXX='${wl}-z,text' + archive_cmds_need_lc_CXX=no + hardcode_shlibpath_var_CXX=no + runpath_var='LD_RUN_PATH' + + case $cc_basename in + CC*) + archive_cmds_CXX='$CC -G ${wl}-h,$soname -o $lib $libobjs $deplibs $compiler_flags' + archive_expsym_cmds_CXX='$CC -G ${wl}-Bexport:$export_symbols ${wl}-h,$soname -o $lib $libobjs $deplibs $compiler_flags' + ;; + *) + archive_cmds_CXX='$CC -shared ${wl}-h,$soname -o $lib $libobjs $deplibs $compiler_flags' + archive_expsym_cmds_CXX='$CC -shared ${wl}-Bexport:$export_symbols ${wl}-h,$soname -o $lib $libobjs $deplibs $compiler_flags' + ;; + esac + ;; + sysv5* | sco3.2v5* | sco5v6*) + # Note: We can NOT use -z defs as we might desire, because we do not + # link with -lc, and that would cause any symbols used from libc to + # always be unresolved, which means just about no library would + # ever link correctly. If we're not using GNU ld we use -z text + # though, which does catch some bad symbols but isn't as heavy-handed + # as -z defs. + # For security reasons, it is highly recommended that you always + # use absolute paths for naming shared libraries, and exclude the + # DT_RUNPATH tag from executables and libraries. But doing so + # requires that you compile everything twice, which is a pain. + # So that behaviour is only enabled if SCOABSPATH is set to a + # non-empty value in the environment. Most likely only useful for + # creating official distributions of packages. + # This is a hack until libtool officially supports absolute path + # names for shared libraries. + no_undefined_flag_CXX='${wl}-z,text' + allow_undefined_flag_CXX='${wl}-z,nodefs' + archive_cmds_need_lc_CXX=no + hardcode_shlibpath_var_CXX=no + hardcode_libdir_flag_spec_CXX='`test -z "$SCOABSPATH" && echo ${wl}-R,$libdir`' + hardcode_libdir_separator_CXX=':' + link_all_deplibs_CXX=yes + export_dynamic_flag_spec_CXX='${wl}-Bexport' + runpath_var='LD_RUN_PATH' + + case $cc_basename in + CC*) + archive_cmds_CXX='$CC -G ${wl}-h,\${SCOABSPATH:+${install_libdir}/}$soname -o $lib $libobjs $deplibs $compiler_flags' + archive_expsym_cmds_CXX='$CC -G ${wl}-Bexport:$export_symbols ${wl}-h,\${SCOABSPATH:+${install_libdir}/}$soname -o $lib $libobjs $deplibs $compiler_flags' + ;; + *) + archive_cmds_CXX='$CC -shared ${wl}-h,\${SCOABSPATH:+${install_libdir}/}$soname -o $lib $libobjs $deplibs $compiler_flags' + archive_expsym_cmds_CXX='$CC -shared ${wl}-Bexport:$export_symbols ${wl}-h,\${SCOABSPATH:+${install_libdir}/}$soname -o $lib $libobjs $deplibs $compiler_flags' + ;; + esac + ;; + tandem*) + case $cc_basename in + NCC*) + # NonStop-UX NCC 3.20 + # FIXME: insert proper C++ library support + ld_shlibs_CXX=no + ;; + *) + # FIXME: insert proper C++ library support + ld_shlibs_CXX=no + ;; + esac + ;; + vxworks*) + # FIXME: insert proper C++ library support + ld_shlibs_CXX=no + ;; + *) + # FIXME: insert proper C++ library support + ld_shlibs_CXX=no + ;; +esac +echo "$as_me:$LINENO: result: $ld_shlibs_CXX" >&5 +echo "${ECHO_T}$ld_shlibs_CXX" >&6 +test "$ld_shlibs_CXX" = no && can_build_shared=no + +GCC_CXX="$GXX" +LD_CXX="$LD" + + +cat > conftest.$ac_ext <<EOF +class Foo +{ +public: + Foo (void) { a = 0; } +private: + int a; +}; +EOF + +if { (eval echo "$as_me:$LINENO: \"$ac_compile\"") >&5 + (eval $ac_compile) 2>&5 + ac_status=$? + echo "$as_me:$LINENO: \$? = $ac_status" >&5 + (exit $ac_status); }; then + # Parse the compiler output and extract the necessary + # objects, libraries and library flags. + + # Sentinel used to keep track of whether or not we are before + # the conftest object file. + pre_test_object_deps_done=no + + # The `*' in the case matches for architectures that use `case' in + # $output_verbose_cmd can trigger glob expansion during the loop + # eval without this substitution. + output_verbose_link_cmd=`$echo "X$output_verbose_link_cmd" | $Xsed -e "$no_glob_subst"` + + for p in `eval $output_verbose_link_cmd`; do + case $p in + + -L* | -R* | -l*) + # Some compilers place space between "-{L,R}" and the path. + # Remove the space. + if test $p = "-L" \ + || test $p = "-R"; then + prev=$p + continue + else + prev= + fi + + if test "$pre_test_object_deps_done" = no; then + case $p in + -L* | -R*) + # Internal compiler library paths should come after those + # provided the user. The postdeps already come after the + # user supplied libs so there is no need to process them. + if test -z "$compiler_lib_search_path_CXX"; then + compiler_lib_search_path_CXX="${prev}${p}" + else + compiler_lib_search_path_CXX="${compiler_lib_search_path_CXX} ${prev}${p}" + fi + ;; + # The "-l" case would never come before the object being + # linked, so don't bother handling this case. + esac + else + if test -z "$postdeps_CXX"; then + postdeps_CXX="${prev}${p}" + else + postdeps_CXX="${postdeps_CXX} ${prev}${p}" + fi + fi + ;; + + *.$objext) + # This assumes that the test object file only shows up + # once in the compiler output. + if test "$p" = "conftest.$objext"; then + pre_test_object_deps_done=yes + continue + fi + + if test "$pre_test_object_deps_done" = no; then + if test -z "$predep_objects_CXX"; then + predep_objects_CXX="$p" + else + predep_objects_CXX="$predep_objects_CXX $p" + fi + else + if test -z "$postdep_objects_CXX"; then + postdep_objects_CXX="$p" + else + postdep_objects_CXX="$postdep_objects_CXX $p" + fi + fi + ;; + + *) ;; # Ignore the rest. + + esac + done + + # Clean up. + rm -f a.out a.exe +else + echo "libtool.m4: error: problem compiling CXX test program" +fi + +$rm -f confest.$objext + +# PORTME: override above test on systems where it is broken +case $host_os in +interix3*) + # Interix 3.5 installs completely hosed .la files for C++, so rather than + # hack all around it, let's just trust "g++" to DTRT. + predep_objects_CXX= + postdep_objects_CXX= + postdeps_CXX= + ;; + +solaris*) + case $cc_basename in + CC*) + # Adding this requires a known-good setup of shared libraries for + # Sun compiler versions before 5.6, else PIC objects from an old + # archive will be linked into the output, leading to subtle bugs. + postdeps_CXX='-lCstd -lCrun' + ;; + esac + ;; +esac + + +case " $postdeps_CXX " in +*" -lc "*) archive_cmds_need_lc_CXX=no ;; +esac + +lt_prog_compiler_wl_CXX= +lt_prog_compiler_pic_CXX= +lt_prog_compiler_static_CXX= + +echo "$as_me:$LINENO: checking for $compiler option to produce PIC" >&5 +echo $ECHO_N "checking for $compiler option to produce PIC... $ECHO_C" >&6 + + # C++ specific cases for pic, static, wl, etc. + if test "$GXX" = yes; then + lt_prog_compiler_wl_CXX='-Wl,' + lt_prog_compiler_static_CXX='-static' + + case $host_os in + aix*) + # All AIX code is PIC. + if test "$host_cpu" = ia64; then + # AIX 5 now supports IA64 processor + lt_prog_compiler_static_CXX='-Bstatic' + fi + ;; + amigaos*) + # FIXME: we need at least 68020 code to build shared libraries, but + # adding the `-m68020' flag to GCC prevents building anything better, + # like `-m68040'. + lt_prog_compiler_pic_CXX='-m68020 -resident32 -malways-restore-a4' + ;; + beos* | cygwin* | irix5* | irix6* | nonstopux* | osf3* | osf4* | osf5*) + # PIC is the default for these OSes. + ;; + mingw* | os2* | pw32*) + # This hack is so that the source file can tell whether it is being + # built for inclusion in a dll (and should export symbols for example). + lt_prog_compiler_pic_CXX='-DDLL_EXPORT' + ;; + darwin* | rhapsody*) + # PIC is the default on this platform + # Common symbols not allowed in MH_DYLIB files + lt_prog_compiler_pic_CXX='-fno-common' + ;; + *djgpp*) + # DJGPP does not support shared libraries at all + lt_prog_compiler_pic_CXX= + ;; + interix3*) + # Interix 3.x gcc -fpic/-fPIC options generate broken code. + # Instead, we relocate shared libraries at runtime. + ;; + sysv4*MP*) + if test -d /usr/nec; then + lt_prog_compiler_pic_CXX=-Kconform_pic + fi + ;; + hpux*) + # PIC is the default for IA64 HP-UX and 64-bit HP-UX, but + # not for PA HP-UX. + case $host_cpu in + hppa*64*|ia64*) + ;; + *) + lt_prog_compiler_pic_CXX='-fPIC' + ;; + esac + ;; + *) + lt_prog_compiler_pic_CXX='-fPIC' + ;; + esac + else + case $host_os in + aix4* | aix5*) + # All AIX code is PIC. + if test "$host_cpu" = ia64; then + # AIX 5 now supports IA64 processor + lt_prog_compiler_static_CXX='-Bstatic' + else + lt_prog_compiler_static_CXX='-bnso -bI:/lib/syscalls.exp' + fi + ;; + chorus*) + case $cc_basename in + cxch68*) + # Green Hills C++ Compiler + # _LT_AC_TAGVAR(lt_prog_compiler_static, CXX)="--no_auto_instantiation -u __main -u __premain -u _abort -r $COOL_DIR/lib/libOrb.a $MVME_DIR/lib/CC/libC.a $MVME_DIR/lib/classix/libcx.s.a" + ;; + esac + ;; + darwin*) + # PIC is the default on this platform + # Common symbols not allowed in MH_DYLIB files + case $cc_basename in + xlc*) + lt_prog_compiler_pic_CXX='-qnocommon' + lt_prog_compiler_wl_CXX='-Wl,' + ;; + esac + ;; + dgux*) + case $cc_basename in + ec++*) + lt_prog_compiler_pic_CXX='-KPIC' + ;; + ghcx*) + # Green Hills C++ Compiler + lt_prog_compiler_pic_CXX='-pic' + ;; + *) + ;; + esac + ;; + freebsd* | kfreebsd*-gnu | dragonfly*) + # FreeBSD uses GNU C++ + ;; + hpux9* | hpux10* | hpux11*) + case $cc_basename in + CC*) + lt_prog_compiler_wl_CXX='-Wl,' + lt_prog_compiler_static_CXX='${wl}-a ${wl}archive' + if test "$host_cpu" != ia64; then + lt_prog_compiler_pic_CXX='+Z' + fi + ;; + aCC*) + lt_prog_compiler_wl_CXX='-Wl,' + lt_prog_compiler_static_CXX='${wl}-a ${wl}archive' + case $host_cpu in + hppa*64*|ia64*) + # +Z the default + ;; + *) + lt_prog_compiler_pic_CXX='+Z' + ;; + esac + ;; + *) + ;; + esac + ;; + interix*) + # This is c89, which is MS Visual C++ (no shared libs) + # Anyone wants to do a port? + ;; + irix5* | irix6* | nonstopux*) + case $cc_basename in + CC*) + lt_prog_compiler_wl_CXX='-Wl,' + lt_prog_compiler_static_CXX='-non_shared' + # CC pic flag -KPIC is the default. + ;; + *) + ;; + esac + ;; + linux*) + case $cc_basename in + KCC*) + # KAI C++ Compiler + lt_prog_compiler_wl_CXX='--backend -Wl,' + lt_prog_compiler_pic_CXX='-fPIC' + ;; + icpc* | ecpc*) + # Intel C++ + lt_prog_compiler_wl_CXX='-Wl,' + lt_prog_compiler_pic_CXX='-KPIC' + lt_prog_compiler_static_CXX='-static' + ;; + pgCC*) + # Portland Group C++ compiler. + lt_prog_compiler_wl_CXX='-Wl,' + lt_prog_compiler_pic_CXX='-fpic' + lt_prog_compiler_static_CXX='-Bstatic' + ;; + cxx*) + # Compaq C++ + # Make sure the PIC flag is empty. It appears that all Alpha + # Linux and Compaq Tru64 Unix objects are PIC. + lt_prog_compiler_pic_CXX= + lt_prog_compiler_static_CXX='-non_shared' + ;; + *) + ;; + esac + ;; + lynxos*) + ;; + m88k*) + ;; + mvs*) + case $cc_basename in + cxx*) + lt_prog_compiler_pic_CXX='-W c,exportall' + ;; + *) + ;; + esac + ;; + netbsd*) + ;; + osf3* | osf4* | osf5*) + case $cc_basename in + KCC*) + lt_prog_compiler_wl_CXX='--backend -Wl,' + ;; + RCC*) + # Rational C++ 2.4.1 + lt_prog_compiler_pic_CXX='-pic' + ;; + cxx*) + # Digital/Compaq C++ + lt_prog_compiler_wl_CXX='-Wl,' + # Make sure the PIC flag is empty. It appears that all Alpha + # Linux and Compaq Tru64 Unix objects are PIC. + lt_prog_compiler_pic_CXX= + lt_prog_compiler_static_CXX='-non_shared' + ;; + *) + ;; + esac + ;; + psos*) + ;; + solaris*) + case $cc_basename in + CC*) + # Sun C++ 4.2, 5.x and Centerline C++ + lt_prog_compiler_pic_CXX='-KPIC' + lt_prog_compiler_static_CXX='-Bstatic' + lt_prog_compiler_wl_CXX='-Qoption ld ' + ;; + gcx*) + # Green Hills C++ Compiler + lt_prog_compiler_pic_CXX='-PIC' + ;; + *) + ;; + esac + ;; + sunos4*) + case $cc_basename in + CC*) + # Sun C++ 4.x + lt_prog_compiler_pic_CXX='-pic' + lt_prog_compiler_static_CXX='-Bstatic' + ;; + lcc*) + # Lucid + lt_prog_compiler_pic_CXX='-pic' + ;; + *) + ;; + esac + ;; + tandem*) + case $cc_basename in + NCC*) + # NonStop-UX NCC 3.20 + lt_prog_compiler_pic_CXX='-KPIC' + ;; + *) + ;; + esac + ;; + sysv5* | unixware* | sco3.2v5* | sco5v6* | OpenUNIX*) + case $cc_basename in + CC*) + lt_prog_compiler_wl_CXX='-Wl,' + lt_prog_compiler_pic_CXX='-KPIC' + lt_prog_compiler_static_CXX='-Bstatic' + ;; + esac + ;; + vxworks*) + ;; + *) + lt_prog_compiler_can_build_shared_CXX=no + ;; + esac + fi + +echo "$as_me:$LINENO: result: $lt_prog_compiler_pic_CXX" >&5 +echo "${ECHO_T}$lt_prog_compiler_pic_CXX" >&6 + +# +# Check to make sure the PIC flag actually works. +# +if test -n "$lt_prog_compiler_pic_CXX"; then + +echo "$as_me:$LINENO: checking if $compiler PIC flag $lt_prog_compiler_pic_CXX works" >&5 +echo $ECHO_N "checking if $compiler PIC flag $lt_prog_compiler_pic_CXX works... $ECHO_C" >&6 +if test "${lt_prog_compiler_pic_works_CXX+set}" = set; then + echo $ECHO_N "(cached) $ECHO_C" >&6 +else + lt_prog_compiler_pic_works_CXX=no + ac_outfile=conftest.$ac_objext + printf "$lt_simple_compile_test_code" > conftest.$ac_ext + lt_compiler_flag="$lt_prog_compiler_pic_CXX -DPIC" + # Insert the option either (1) after the last *FLAGS variable, or + # (2) before a word containing "conftest.", or (3) at the end. + # Note that $ac_compile itself does not contain backslashes and begins + # with a dollar sign (not a hyphen), so the echo should work correctly. + # The option is referenced via a variable to avoid confusing sed. + lt_compile=`echo "$ac_compile" | $SED \ + -e 's:.*FLAGS}\{0,1\} :&$lt_compiler_flag :; t' \ + -e 's: [^ ]*conftest\.: $lt_compiler_flag&:; t' \ + -e 's:$: $lt_compiler_flag:'` + (eval echo "\"\$as_me:11694: $lt_compile\"" >&5) + (eval "$lt_compile" 2>conftest.err) + ac_status=$? + cat conftest.err >&5 + echo "$as_me:11698: \$? = $ac_status" >&5 + if (exit $ac_status) && test -s "$ac_outfile"; then + # The compiler can only warn and ignore the option if not recognized + # So say no if there are warnings other than the usual output. + $echo "X$_lt_compiler_boilerplate" | $Xsed -e '/^$/d' >conftest.exp + $SED '/^$/d; /^ *+/d' conftest.err >conftest.er2 + if test ! -s conftest.er2 || diff conftest.exp conftest.er2 >/dev/null; then + lt_prog_compiler_pic_works_CXX=yes + fi + fi + $rm conftest* + +fi +echo "$as_me:$LINENO: result: $lt_prog_compiler_pic_works_CXX" >&5 +echo "${ECHO_T}$lt_prog_compiler_pic_works_CXX" >&6 + +if test x"$lt_prog_compiler_pic_works_CXX" = xyes; then + case $lt_prog_compiler_pic_CXX in + "" | " "*) ;; + *) lt_prog_compiler_pic_CXX=" $lt_prog_compiler_pic_CXX" ;; + esac +else + lt_prog_compiler_pic_CXX= + lt_prog_compiler_can_build_shared_CXX=no +fi + +fi +case $host_os in + # For platforms which do not support PIC, -DPIC is meaningless: + *djgpp*) + lt_prog_compiler_pic_CXX= + ;; + *) + lt_prog_compiler_pic_CXX="$lt_prog_compiler_pic_CXX -DPIC" + ;; +esac + +# +# Check to make sure the static flag actually works. +# +wl=$lt_prog_compiler_wl_CXX eval lt_tmp_static_flag=\"$lt_prog_compiler_static_CXX\" +echo "$as_me:$LINENO: checking if $compiler static flag $lt_tmp_static_flag works" >&5 +echo $ECHO_N "checking if $compiler static flag $lt_tmp_static_flag works... $ECHO_C" >&6 +if test "${lt_prog_compiler_static_works_CXX+set}" = set; then + echo $ECHO_N "(cached) $ECHO_C" >&6 +else + lt_prog_compiler_static_works_CXX=no + save_LDFLAGS="$LDFLAGS" + LDFLAGS="$LDFLAGS $lt_tmp_static_flag" + printf "$lt_simple_link_test_code" > conftest.$ac_ext + if (eval $ac_link 2>conftest.err) && test -s conftest$ac_exeext; then + # The linker can only warn and ignore the option if not recognized + # So say no if there are warnings + if test -s conftest.err; then + # Append any errors to the config.log. + cat conftest.err 1>&5 + $echo "X$_lt_linker_boilerplate" | $Xsed -e '/^$/d' > conftest.exp + $SED '/^$/d; /^ *+/d' conftest.err >conftest.er2 + if diff conftest.exp conftest.er2 >/dev/null; then + lt_prog_compiler_static_works_CXX=yes + fi + else + lt_prog_compiler_static_works_CXX=yes + fi + fi + $rm conftest* + LDFLAGS="$save_LDFLAGS" + +fi +echo "$as_me:$LINENO: result: $lt_prog_compiler_static_works_CXX" >&5 +echo "${ECHO_T}$lt_prog_compiler_static_works_CXX" >&6 + +if test x"$lt_prog_compiler_static_works_CXX" = xyes; then + : +else + lt_prog_compiler_static_CXX= +fi + + +echo "$as_me:$LINENO: checking if $compiler supports -c -o file.$ac_objext" >&5 +echo $ECHO_N "checking if $compiler supports -c -o file.$ac_objext... $ECHO_C" >&6 +if test "${lt_cv_prog_compiler_c_o_CXX+set}" = set; then + echo $ECHO_N "(cached) $ECHO_C" >&6 +else + lt_cv_prog_compiler_c_o_CXX=no + $rm -r conftest 2>/dev/null + mkdir conftest + cd conftest + mkdir out + printf "$lt_simple_compile_test_code" > conftest.$ac_ext + + lt_compiler_flag="-o out/conftest2.$ac_objext" + # Insert the option either (1) after the last *FLAGS variable, or + # (2) before a word containing "conftest.", or (3) at the end. + # Note that $ac_compile itself does not contain backslashes and begins + # with a dollar sign (not a hyphen), so the echo should work correctly. + lt_compile=`echo "$ac_compile" | $SED \ + -e 's:.*FLAGS}\{0,1\} :&$lt_compiler_flag :; t' \ + -e 's: [^ ]*conftest\.: $lt_compiler_flag&:; t' \ + -e 's:$: $lt_compiler_flag:'` + (eval echo "\"\$as_me:11798: $lt_compile\"" >&5) + (eval "$lt_compile" 2>out/conftest.err) + ac_status=$? + cat out/conftest.err >&5 + echo "$as_me:11802: \$? = $ac_status" >&5 + if (exit $ac_status) && test -s out/conftest2.$ac_objext + then + # The compiler can only warn and ignore the option if not recognized + # So say no if there are warnings + $echo "X$_lt_compiler_boilerplate" | $Xsed -e '/^$/d' > out/conftest.exp + $SED '/^$/d; /^ *+/d' out/conftest.err >out/conftest.er2 + if test ! -s out/conftest.er2 || diff out/conftest.exp out/conftest.er2 >/dev/null; then + lt_cv_prog_compiler_c_o_CXX=yes + fi + fi + chmod u+w . 2>&5 + $rm conftest* + # SGI C++ compiler will create directory out/ii_files/ for + # template instantiation + test -d out/ii_files && $rm out/ii_files/* && rmdir out/ii_files + $rm out/* && rmdir out + cd .. + rmdir conftest + $rm conftest* + +fi +echo "$as_me:$LINENO: result: $lt_cv_prog_compiler_c_o_CXX" >&5 +echo "${ECHO_T}$lt_cv_prog_compiler_c_o_CXX" >&6 + + +hard_links="nottested" +if test "$lt_cv_prog_compiler_c_o_CXX" = no && test "$need_locks" != no; then + # do not overwrite the value of need_locks provided by the user + echo "$as_me:$LINENO: checking if we can lock with hard links" >&5 +echo $ECHO_N "checking if we can lock with hard links... $ECHO_C" >&6 + hard_links=yes + $rm conftest* + ln conftest.a conftest.b 2>/dev/null && hard_links=no + touch conftest.a + ln conftest.a conftest.b 2>&5 || hard_links=no + ln conftest.a conftest.b 2>/dev/null && hard_links=no + echo "$as_me:$LINENO: result: $hard_links" >&5 +echo "${ECHO_T}$hard_links" >&6 + if test "$hard_links" = no; then + { echo "$as_me:$LINENO: WARNING: \`$CC' does not support \`-c -o', so \`make -j' may be unsafe" >&5 +echo "$as_me: WARNING: \`$CC' does not support \`-c -o', so \`make -j' may be unsafe" >&2;} + need_locks=warn + fi +else + need_locks=no +fi + +echo "$as_me:$LINENO: checking whether the $compiler linker ($LD) supports shared libraries" >&5 +echo $ECHO_N "checking whether the $compiler linker ($LD) supports shared libraries... $ECHO_C" >&6 + + export_symbols_cmds_CXX='$NM $libobjs $convenience | $global_symbol_pipe | $SED '\''s/.* //'\'' | sort | uniq > $export_symbols' + case $host_os in + aix4* | aix5*) + # If we're using GNU nm, then we don't want the "-C" option. + # -C means demangle to AIX nm, but means don't demangle with GNU nm + if $NM -V 2>&1 | grep 'GNU' > /dev/null; then + export_symbols_cmds_CXX='$NM -Bpg $libobjs $convenience | awk '\''{ if (((\$2 == "T") || (\$2 == "D") || (\$2 == "B")) && (substr(\$3,1,1) != ".")) { print \$3 } }'\'' | sort -u > $export_symbols' + else + export_symbols_cmds_CXX='$NM -BCpg $libobjs $convenience | awk '\''{ if (((\$2 == "T") || (\$2 == "D") || (\$2 == "B")) && (substr(\$3,1,1) != ".")) { print \$3 } }'\'' | sort -u > $export_symbols' + fi + ;; + pw32*) + export_symbols_cmds_CXX="$ltdll_cmds" + ;; + cygwin* | mingw*) + export_symbols_cmds_CXX='$NM $libobjs $convenience | $global_symbol_pipe | $SED -e '\''/^[BCDGRS] /s/.* \([^ ]*\)/\1 DATA/;/^.* __nm__/s/^.* __nm__\([^ ]*\) [^ ]*/\1 DATA/;/^I /d;/^[AITW] /s/.* //'\'' | sort | uniq > $export_symbols' + ;; + *) + export_symbols_cmds_CXX='$NM $libobjs $convenience | $global_symbol_pipe | $SED '\''s/.* //'\'' | sort | uniq > $export_symbols' + ;; + esac + +echo "$as_me:$LINENO: result: $ld_shlibs_CXX" >&5 +echo "${ECHO_T}$ld_shlibs_CXX" >&6 +test "$ld_shlibs_CXX" = no && can_build_shared=no + +# +# Do we need to explicitly link libc? +# +case "x$archive_cmds_need_lc_CXX" in +x|xyes) + # Assume -lc should be added + archive_cmds_need_lc_CXX=yes + + if test "$enable_shared" = yes && test "$GCC" = yes; then + case $archive_cmds_CXX in + *'~'*) + # FIXME: we may have to deal with multi-command sequences. + ;; + '$CC '*) + # Test whether the compiler implicitly links with -lc since on some + # systems, -lgcc has to come before -lc. If gcc already passes -lc + # to ld, don't add -lc before -lgcc. + echo "$as_me:$LINENO: checking whether -lc should be explicitly linked in" >&5 +echo $ECHO_N "checking whether -lc should be explicitly linked in... $ECHO_C" >&6 + $rm conftest* + printf "$lt_simple_compile_test_code" > conftest.$ac_ext + + if { (eval echo "$as_me:$LINENO: \"$ac_compile\"") >&5 + (eval $ac_compile) 2>&5 + ac_status=$? + echo "$as_me:$LINENO: \$? = $ac_status" >&5 + (exit $ac_status); } 2>conftest.err; then + soname=conftest + lib=conftest + libobjs=conftest.$ac_objext + deplibs= + wl=$lt_prog_compiler_wl_CXX + pic_flag=$lt_prog_compiler_pic_CXX + compiler_flags=-v + linker_flags=-v + verstring= + output_objdir=. + libname=conftest + lt_save_allow_undefined_flag=$allow_undefined_flag_CXX + allow_undefined_flag_CXX= + if { (eval echo "$as_me:$LINENO: \"$archive_cmds_CXX 2\>\&1 \| grep \" -lc \" \>/dev/null 2\>\&1\"") >&5 + (eval $archive_cmds_CXX 2\>\&1 \| grep \" -lc \" \>/dev/null 2\>\&1) 2>&5 + ac_status=$? + echo "$as_me:$LINENO: \$? = $ac_status" >&5 + (exit $ac_status); } + then + archive_cmds_need_lc_CXX=no + else + archive_cmds_need_lc_CXX=yes + fi + allow_undefined_flag_CXX=$lt_save_allow_undefined_flag + else + cat conftest.err 1>&5 + fi + $rm conftest* + echo "$as_me:$LINENO: result: $archive_cmds_need_lc_CXX" >&5 +echo "${ECHO_T}$archive_cmds_need_lc_CXX" >&6 + ;; + esac + fi + ;; +esac + +echo "$as_me:$LINENO: checking dynamic linker characteristics" >&5 +echo $ECHO_N "checking dynamic linker characteristics... $ECHO_C" >&6 +library_names_spec= +libname_spec='lib$name' +soname_spec= +shrext_cmds=".so" +postinstall_cmds= +postuninstall_cmds= +finish_cmds= +finish_eval= +shlibpath_var= +shlibpath_overrides_runpath=unknown +version_type=none +dynamic_linker="$host_os ld.so" +sys_lib_dlsearch_path_spec="/lib /usr/lib" +if test "$GCC" = yes; then + sys_lib_search_path_spec=`$CC -print-search-dirs | grep "^libraries:" | $SED -e "s/^libraries://" -e "s,=/,/,g"` + if echo "$sys_lib_search_path_spec" | grep ';' >/dev/null ; then + # if the path contains ";" then we assume it to be the separator + # otherwise default to the standard path separator (i.e. ":") - it is + # assumed that no part of a normal pathname contains ";" but that should + # okay in the real world where ";" in dirpaths is itself problematic. + sys_lib_search_path_spec=`echo "$sys_lib_search_path_spec" | $SED -e 's/;/ /g'` + else + sys_lib_search_path_spec=`echo "$sys_lib_search_path_spec" | $SED -e "s/$PATH_SEPARATOR/ /g"` + fi +else + sys_lib_search_path_spec="/lib /usr/lib /usr/local/lib" +fi +need_lib_prefix=unknown +hardcode_into_libs=no + +# when you set need_version to no, make sure it does not cause -set_version +# flags to be left without arguments +need_version=unknown + +case $host_os in +aix3*) + version_type=linux + library_names_spec='${libname}${release}${shared_ext}$versuffix $libname.a' + shlibpath_var=LIBPATH + + # AIX 3 has no versioning support, so we append a major version to the name. + soname_spec='${libname}${release}${shared_ext}$major' + ;; + +aix4* | aix5*) + version_type=linux + need_lib_prefix=no + need_version=no + hardcode_into_libs=yes + if test "$host_cpu" = ia64; then + # AIX 5 supports IA64 + library_names_spec='${libname}${release}${shared_ext}$major ${libname}${release}${shared_ext}$versuffix $libname${shared_ext}' + shlibpath_var=LD_LIBRARY_PATH + else + # With GCC up to 2.95.x, collect2 would create an import file + # for dependence libraries. The import file would start with + # the line `#! .'. This would cause the generated library to + # depend on `.', always an invalid library. This was fixed in + # development snapshots of GCC prior to 3.0. + case $host_os in + aix4 | aix4.[01] | aix4.[01].*) + if { echo '#if __GNUC__ > 2 || (__GNUC__ == 2 && __GNUC_MINOR__ >= 97)' + echo ' yes ' + echo '#endif'; } | ${CC} -E - | grep yes > /dev/null; then + : + else + can_build_shared=no + fi + ;; + esac + # AIX (on Power*) has no versioning support, so currently we can not hardcode correct + # soname into executable. Probably we can add versioning support to + # collect2, so additional links can be useful in future. + if test "$aix_use_runtimelinking" = yes; then + # If using run time linking (on AIX 4.2 or later) use lib<name>.so + # instead of lib<name>.a to let people know that these are not + # typical AIX shared libraries. + library_names_spec='${libname}${release}${shared_ext}$versuffix ${libname}${release}${shared_ext}$major $libname${shared_ext}' + else + # We preserve .a as extension for shared libraries through AIX4.2 + # and later when we are not doing run time linking. + library_names_spec='${libname}${release}.a $libname.a' + soname_spec='${libname}${release}${shared_ext}$major' + fi + shlibpath_var=LIBPATH + fi + ;; + +amigaos*) + library_names_spec='$libname.ixlibrary $libname.a' + # Create ${libname}_ixlibrary.a entries in /sys/libs. + finish_eval='for lib in `ls $libdir/*.ixlibrary 2>/dev/null`; do libname=`$echo "X$lib" | $Xsed -e '\''s%^.*/\([^/]*\)\.ixlibrary$%\1%'\''`; test $rm /sys/libs/${libname}_ixlibrary.a; $show "cd /sys/libs && $LN_S $lib ${libname}_ixlibrary.a"; cd /sys/libs && $LN_S $lib ${libname}_ixlibrary.a || exit 1; done' + ;; + +beos*) + library_names_spec='${libname}${shared_ext}' + dynamic_linker="$host_os ld.so" + shlibpath_var=LIBRARY_PATH + ;; + +bsdi[45]*) + version_type=linux + need_version=no + library_names_spec='${libname}${release}${shared_ext}$versuffix ${libname}${release}${shared_ext}$major $libname${shared_ext}' + soname_spec='${libname}${release}${shared_ext}$major' + finish_cmds='PATH="\$PATH:/sbin" ldconfig $libdir' + shlibpath_var=LD_LIBRARY_PATH + sys_lib_search_path_spec="/shlib /usr/lib /usr/X11/lib /usr/contrib/lib /lib /usr/local/lib" + sys_lib_dlsearch_path_spec="/shlib /usr/lib /usr/local/lib" + # the default ld.so.conf also contains /usr/contrib/lib and + # /usr/X11R6/lib (/usr/X11 is a link to /usr/X11R6), but let us allow + # libtool to hard-code these into programs + ;; + +cygwin* | mingw* | pw32*) + version_type=windows + shrext_cmds=".dll" + need_version=no + need_lib_prefix=no + + case $GCC,$host_os in + yes,cygwin* | yes,mingw* | yes,pw32*) + library_names_spec='$libname.dll.a' + # DLL is installed to $(libdir)/../bin by postinstall_cmds + postinstall_cmds='base_file=`basename \${file}`~ + dlpath=`$SHELL 2>&1 -c '\''. $dir/'\''\${base_file}'\''i;echo \$dlname'\''`~ + dldir=$destdir/`dirname \$dlpath`~ + test -d \$dldir || mkdir -p \$dldir~ + $install_prog $dir/$dlname \$dldir/$dlname~ + chmod a+x \$dldir/$dlname' + postuninstall_cmds='dldll=`$SHELL 2>&1 -c '\''. $file; echo \$dlname'\''`~ + dlpath=$dir/\$dldll~ + $rm \$dlpath' + shlibpath_overrides_runpath=yes + + case $host_os in + cygwin*) + # Cygwin DLLs use 'cyg' prefix rather than 'lib' + soname_spec='`echo ${libname} | sed -e 's/^lib/cyg/'``echo ${release} | $SED -e 's/[.]/-/g'`${versuffix}${shared_ext}' + sys_lib_search_path_spec="/usr/lib /lib/w32api /lib /usr/local/lib" + ;; + mingw*) + # MinGW DLLs use traditional 'lib' prefix + soname_spec='${libname}`echo ${release} | $SED -e 's/[.]/-/g'`${versuffix}${shared_ext}' + sys_lib_search_path_spec=`$CC -print-search-dirs | grep "^libraries:" | $SED -e "s/^libraries://" -e "s,=/,/,g"` + if echo "$sys_lib_search_path_spec" | grep ';[c-zC-Z]:/' >/dev/null; then + # It is most probably a Windows format PATH printed by + # mingw gcc, but we are running on Cygwin. Gcc prints its search + # path with ; separators, and with drive letters. We can handle the + # drive letters (cygwin fileutils understands them), so leave them, + # especially as we might pass files found there to a mingw objdump, + # which wouldn't understand a cygwinified path. Ahh. + sys_lib_search_path_spec=`echo "$sys_lib_search_path_spec" | $SED -e 's/;/ /g'` + else + sys_lib_search_path_spec=`echo "$sys_lib_search_path_spec" | $SED -e "s/$PATH_SEPARATOR/ /g"` + fi + ;; + pw32*) + # pw32 DLLs use 'pw' prefix rather than 'lib' + library_names_spec='`echo ${libname} | sed -e 's/^lib/pw/'``echo ${release} | $SED -e 's/[.]/-/g'`${versuffix}${shared_ext}' + ;; + esac + ;; + + *) + library_names_spec='${libname}`echo ${release} | $SED -e 's/[.]/-/g'`${versuffix}${shared_ext} $libname.lib' + ;; + esac + dynamic_linker='Win32 ld.exe' + # FIXME: first we should search . and the directory the executable is in + shlibpath_var=PATH + ;; + +darwin* | rhapsody*) + dynamic_linker="$host_os dyld" + version_type=darwin + need_lib_prefix=no + need_version=no + library_names_spec='${libname}${release}${versuffix}$shared_ext ${libname}${release}${major}$shared_ext ${libname}$shared_ext' + soname_spec='${libname}${release}${major}$shared_ext' + shlibpath_overrides_runpath=yes + shlibpath_var=DYLD_LIBRARY_PATH + shrext_cmds='`test .$module = .yes && echo .so || echo .dylib`' + # Apple's gcc prints 'gcc -print-search-dirs' doesn't operate the same. + if test "$GCC" = yes; then + sys_lib_search_path_spec=`$CC -print-search-dirs | tr "\n" "$PATH_SEPARATOR" | sed -e 's/libraries:/@libraries:/' | tr "@" "\n" | grep "^libraries:" | sed -e "s/^libraries://" -e "s,=/,/,g" -e "s,$PATH_SEPARATOR, ,g" -e "s,.*,& /lib /usr/lib /usr/local/lib,g"` + else + sys_lib_search_path_spec='/lib /usr/lib /usr/local/lib' + fi + sys_lib_dlsearch_path_spec='/usr/local/lib /lib /usr/lib' + ;; + +dgux*) + version_type=linux + need_lib_prefix=no + need_version=no + library_names_spec='${libname}${release}${shared_ext}$versuffix ${libname}${release}${shared_ext}$major $libname$shared_ext' + soname_spec='${libname}${release}${shared_ext}$major' + shlibpath_var=LD_LIBRARY_PATH + ;; + +freebsd1*) + dynamic_linker=no + ;; + +kfreebsd*-gnu) + version_type=linux + need_lib_prefix=no + need_version=no + library_names_spec='${libname}${release}${shared_ext}$versuffix ${libname}${release}${shared_ext}$major ${libname}${shared_ext}' + soname_spec='${libname}${release}${shared_ext}$major' + shlibpath_var=LD_LIBRARY_PATH + shlibpath_overrides_runpath=no + hardcode_into_libs=yes + dynamic_linker='GNU ld.so' + ;; + +freebsd* | dragonfly*) + # DragonFly does not have aout. When/if they implement a new + # versioning mechanism, adjust this. + if test -x /usr/bin/objformat; then + objformat=`/usr/bin/objformat` + else + case $host_os in + freebsd[123]*) objformat=aout ;; + *) objformat=elf ;; + esac + fi + version_type=freebsd-$objformat + case $version_type in + freebsd-elf*) + library_names_spec='${libname}${release}${shared_ext}$versuffix ${libname}${release}${shared_ext} $libname${shared_ext}' + need_version=no + need_lib_prefix=no + ;; + freebsd-*) + library_names_spec='${libname}${release}${shared_ext}$versuffix $libname${shared_ext}$versuffix' + need_version=yes + ;; + esac + shlibpath_var=LD_LIBRARY_PATH + case $host_os in + freebsd2*) + shlibpath_overrides_runpath=yes + ;; + freebsd3.[01]* | freebsdelf3.[01]*) + shlibpath_overrides_runpath=yes + hardcode_into_libs=yes + ;; + freebsd3.[2-9]* | freebsdelf3.[2-9]* | \ + freebsd4.[0-5] | freebsdelf4.[0-5] | freebsd4.1.1 | freebsdelf4.1.1) + shlibpath_overrides_runpath=no + hardcode_into_libs=yes + ;; + freebsd*) # from 4.6 on + shlibpath_overrides_runpath=yes + hardcode_into_libs=yes + ;; + esac + ;; + +gnu*) + version_type=linux + need_lib_prefix=no + need_version=no + library_names_spec='${libname}${release}${shared_ext}$versuffix ${libname}${release}${shared_ext}${major} ${libname}${shared_ext}' + soname_spec='${libname}${release}${shared_ext}$major' + shlibpath_var=LD_LIBRARY_PATH + hardcode_into_libs=yes + ;; + +hpux9* | hpux10* | hpux11*) + # Give a soname corresponding to the major version so that dld.sl refuses to + # link against other versions. + version_type=sunos + need_lib_prefix=no + need_version=no + case $host_cpu in + ia64*) + shrext_cmds='.so' + hardcode_into_libs=yes + dynamic_linker="$host_os dld.so" + shlibpath_var=LD_LIBRARY_PATH + shlibpath_overrides_runpath=yes # Unless +noenvvar is specified. + library_names_spec='${libname}${release}${shared_ext}$versuffix ${libname}${release}${shared_ext}$major $libname${shared_ext}' + soname_spec='${libname}${release}${shared_ext}$major' + if test "X$HPUX_IA64_MODE" = X32; then + sys_lib_search_path_spec="/usr/lib/hpux32 /usr/local/lib/hpux32 /usr/local/lib" + else + sys_lib_search_path_spec="/usr/lib/hpux64 /usr/local/lib/hpux64" + fi + sys_lib_dlsearch_path_spec=$sys_lib_search_path_spec + ;; + hppa*64*) + shrext_cmds='.sl' + hardcode_into_libs=yes + dynamic_linker="$host_os dld.sl" + shlibpath_var=LD_LIBRARY_PATH # How should we handle SHLIB_PATH + shlibpath_overrides_runpath=yes # Unless +noenvvar is specified. + library_names_spec='${libname}${release}${shared_ext}$versuffix ${libname}${release}${shared_ext}$major $libname${shared_ext}' + soname_spec='${libname}${release}${shared_ext}$major' + sys_lib_search_path_spec="/usr/lib/pa20_64 /usr/ccs/lib/pa20_64" + sys_lib_dlsearch_path_spec=$sys_lib_search_path_spec + ;; + *) + shrext_cmds='.sl' + dynamic_linker="$host_os dld.sl" + shlibpath_var=SHLIB_PATH + shlibpath_overrides_runpath=no # +s is required to enable SHLIB_PATH + library_names_spec='${libname}${release}${shared_ext}$versuffix ${libname}${release}${shared_ext}$major $libname${shared_ext}' + soname_spec='${libname}${release}${shared_ext}$major' + ;; + esac + # HP-UX runs *really* slowly unless shared libraries are mode 555. + postinstall_cmds='chmod 555 $lib' + ;; + +interix3*) + version_type=linux + need_lib_prefix=no + need_version=no + library_names_spec='${libname}${release}${shared_ext}$versuffix ${libname}${release}${shared_ext}$major ${libname}${shared_ext}' + soname_spec='${libname}${release}${shared_ext}$major' + dynamic_linker='Interix 3.x ld.so.1 (PE, like ELF)' + shlibpath_var=LD_LIBRARY_PATH + shlibpath_overrides_runpath=no + hardcode_into_libs=yes + ;; + +irix5* | irix6* | nonstopux*) + case $host_os in + nonstopux*) version_type=nonstopux ;; + *) + if test "$lt_cv_prog_gnu_ld" = yes; then + version_type=linux + else + version_type=irix + fi ;; + esac + need_lib_prefix=no + need_version=no + soname_spec='${libname}${release}${shared_ext}$major' + library_names_spec='${libname}${release}${shared_ext}$versuffix ${libname}${release}${shared_ext}$major ${libname}${release}${shared_ext} $libname${shared_ext}' + case $host_os in + irix5* | nonstopux*) + libsuff= shlibsuff= + ;; + *) + case $LD in # libtool.m4 will add one of these switches to LD + *-32|*"-32 "|*-melf32bsmip|*"-melf32bsmip ") + libsuff= shlibsuff= libmagic=32-bit;; + *-n32|*"-n32 "|*-melf32bmipn32|*"-melf32bmipn32 ") + libsuff=32 shlibsuff=N32 libmagic=N32;; + *-64|*"-64 "|*-melf64bmip|*"-melf64bmip ") + libsuff=64 shlibsuff=64 libmagic=64-bit;; + *) libsuff= shlibsuff= libmagic=never-match;; + esac + ;; + esac + shlibpath_var=LD_LIBRARY${shlibsuff}_PATH + shlibpath_overrides_runpath=no + sys_lib_search_path_spec="/usr/lib${libsuff} /lib${libsuff} /usr/local/lib${libsuff}" + sys_lib_dlsearch_path_spec="/usr/lib${libsuff} /lib${libsuff}" + hardcode_into_libs=yes + ;; + +# No shared lib support for Linux oldld, aout, or coff. +linux*oldld* | linux*aout* | linux*coff*) + dynamic_linker=no + ;; + +# This must be Linux ELF. +linux*) + version_type=linux + need_lib_prefix=no + need_version=no + library_names_spec='${libname}${release}${shared_ext}$versuffix ${libname}${release}${shared_ext}$major $libname${shared_ext}' + soname_spec='${libname}${release}${shared_ext}$major' + finish_cmds='PATH="\$PATH:/sbin" ldconfig -n $libdir' + shlibpath_var=LD_LIBRARY_PATH + shlibpath_overrides_runpath=no + # This implies no fast_install, which is unacceptable. + # Some rework will be needed to allow for fast_install + # before this can be enabled. + hardcode_into_libs=yes + + # find out which ABI we are using + libsuff= + case "$host_cpu" in + x86_64*|s390x*|powerpc64*) + echo '#line 12334 "configure"' > conftest.$ac_ext + if { (eval echo "$as_me:$LINENO: \"$ac_compile\"") >&5 + (eval $ac_compile) 2>&5 + ac_status=$? + echo "$as_me:$LINENO: \$? = $ac_status" >&5 + (exit $ac_status); }; then + case `/usr/bin/file conftest.$ac_objext` in + *64-bit*) + libsuff=64 + sys_lib_search_path_spec="/lib${libsuff} /usr/lib${libsuff} /usr/local/lib${libsuff}" + ;; + esac + fi + rm -rf conftest* + ;; + esac + + # Append ld.so.conf contents to the search path + if test -f /etc/ld.so.conf; then + lt_ld_extra=`awk '/^include / { system(sprintf("cd /etc; cat %s 2>/dev/null", \$2)); skip = 1; } { if (!skip) print \$0; skip = 0; }' < /etc/ld.so.conf | $SED -e 's/#.*//;s/[:, ]/ /g;s/=[^=]*$//;s/=[^= ]* / /g;/^$/d' | tr '\n' ' '` + sys_lib_dlsearch_path_spec="/lib${libsuff} /usr/lib${libsuff} $lt_ld_extra" + fi + + # We used to test for /lib/ld.so.1 and disable shared libraries on + # powerpc, because MkLinux only supported shared libraries with the + # GNU dynamic linker. Since this was broken with cross compilers, + # most powerpc-linux boxes support dynamic linking these days and + # people can always --disable-shared, the test was removed, and we + # assume the GNU/Linux dynamic linker is in use. + dynamic_linker='GNU/Linux ld.so' + ;; + +knetbsd*-gnu) + version_type=linux + need_lib_prefix=no + need_version=no + library_names_spec='${libname}${release}${shared_ext}$versuffix ${libname}${release}${shared_ext}$major ${libname}${shared_ext}' + soname_spec='${libname}${release}${shared_ext}$major' + shlibpath_var=LD_LIBRARY_PATH + shlibpath_overrides_runpath=no + hardcode_into_libs=yes + dynamic_linker='GNU ld.so' + ;; + +netbsd*) + version_type=sunos + need_lib_prefix=no + need_version=no + if echo __ELF__ | $CC -E - | grep __ELF__ >/dev/null; then + library_names_spec='${libname}${release}${shared_ext}$versuffix ${libname}${shared_ext}$versuffix' + finish_cmds='PATH="\$PATH:/sbin" ldconfig -m $libdir' + dynamic_linker='NetBSD (a.out) ld.so' + else + library_names_spec='${libname}${release}${shared_ext}$versuffix ${libname}${release}${shared_ext}$major ${libname}${shared_ext}' + soname_spec='${libname}${release}${shared_ext}$major' + dynamic_linker='NetBSD ld.elf_so' + fi + shlibpath_var=LD_LIBRARY_PATH + shlibpath_overrides_runpath=yes + hardcode_into_libs=yes + ;; + +newsos6) + version_type=linux + library_names_spec='${libname}${release}${shared_ext}$versuffix ${libname}${release}${shared_ext}$major $libname${shared_ext}' + shlibpath_var=LD_LIBRARY_PATH + shlibpath_overrides_runpath=yes + ;; + +nto-qnx*) + version_type=linux + need_lib_prefix=no + need_version=no + library_names_spec='${libname}${release}${shared_ext}$versuffix ${libname}${release}${shared_ext}$major $libname${shared_ext}' + soname_spec='${libname}${release}${shared_ext}$major' + shlibpath_var=LD_LIBRARY_PATH + shlibpath_overrides_runpath=yes + ;; + +openbsd*) + version_type=sunos + sys_lib_dlsearch_path_spec="/usr/lib" + need_lib_prefix=no + # Some older versions of OpenBSD (3.3 at least) *do* need versioned libs. + case $host_os in + openbsd3.3 | openbsd3.3.*) need_version=yes ;; + *) need_version=no ;; + esac + library_names_spec='${libname}${release}${shared_ext}$versuffix ${libname}${shared_ext}$versuffix' + finish_cmds='PATH="\$PATH:/sbin" ldconfig -m $libdir' + shlibpath_var=LD_LIBRARY_PATH + if test -z "`echo __ELF__ | $CC -E - | grep __ELF__`" || test "$host_os-$host_cpu" = "openbsd2.8-powerpc"; then + case $host_os in + openbsd2.[89] | openbsd2.[89].*) + shlibpath_overrides_runpath=no + ;; + *) + shlibpath_overrides_runpath=yes + ;; + esac + else + shlibpath_overrides_runpath=yes + fi + ;; + +os2*) + libname_spec='$name' + shrext_cmds=".dll" + need_lib_prefix=no + library_names_spec='$libname${shared_ext} $libname.a' + dynamic_linker='OS/2 ld.exe' + shlibpath_var=LIBPATH + ;; + +osf3* | osf4* | osf5*) + version_type=osf + need_lib_prefix=no + need_version=no + soname_spec='${libname}${release}${shared_ext}$major' + library_names_spec='${libname}${release}${shared_ext}$versuffix ${libname}${release}${shared_ext}$major $libname${shared_ext}' + shlibpath_var=LD_LIBRARY_PATH + sys_lib_search_path_spec="/usr/shlib /usr/ccs/lib /usr/lib/cmplrs/cc /usr/lib /usr/local/lib /var/shlib" + sys_lib_dlsearch_path_spec="$sys_lib_search_path_spec" + ;; + +solaris*) + version_type=linux + need_lib_prefix=no + need_version=no + library_names_spec='${libname}${release}${shared_ext}$versuffix ${libname}${release}${shared_ext}$major $libname${shared_ext}' + soname_spec='${libname}${release}${shared_ext}$major' + shlibpath_var=LD_LIBRARY_PATH + shlibpath_overrides_runpath=yes + hardcode_into_libs=yes + # ldd complains unless libraries are executable + postinstall_cmds='chmod +x $lib' + ;; + +sunos4*) + version_type=sunos + library_names_spec='${libname}${release}${shared_ext}$versuffix ${libname}${shared_ext}$versuffix' + finish_cmds='PATH="\$PATH:/usr/etc" ldconfig $libdir' + shlibpath_var=LD_LIBRARY_PATH + shlibpath_overrides_runpath=yes + if test "$with_gnu_ld" = yes; then + need_lib_prefix=no + fi + need_version=yes + ;; + +sysv4 | sysv4.3*) + version_type=linux + library_names_spec='${libname}${release}${shared_ext}$versuffix ${libname}${release}${shared_ext}$major $libname${shared_ext}' + soname_spec='${libname}${release}${shared_ext}$major' + shlibpath_var=LD_LIBRARY_PATH + case $host_vendor in + sni) + shlibpath_overrides_runpath=no + need_lib_prefix=no + export_dynamic_flag_spec='${wl}-Blargedynsym' + runpath_var=LD_RUN_PATH + ;; + siemens) + need_lib_prefix=no + ;; + motorola) + need_lib_prefix=no + need_version=no + shlibpath_overrides_runpath=no + sys_lib_search_path_spec='/lib /usr/lib /usr/ccs/lib' + ;; + esac + ;; + +sysv4*MP*) + if test -d /usr/nec ;then + version_type=linux + library_names_spec='$libname${shared_ext}.$versuffix $libname${shared_ext}.$major $libname${shared_ext}' + soname_spec='$libname${shared_ext}.$major' + shlibpath_var=LD_LIBRARY_PATH + fi + ;; + +sysv5* | sco3.2v5* | sco5v6* | unixware* | OpenUNIX* | sysv4*uw2*) + version_type=freebsd-elf + need_lib_prefix=no + need_version=no + library_names_spec='${libname}${release}${shared_ext}$versuffix ${libname}${release}${shared_ext} $libname${shared_ext}' + soname_spec='${libname}${release}${shared_ext}$major' + shlibpath_var=LD_LIBRARY_PATH + hardcode_into_libs=yes + if test "$with_gnu_ld" = yes; then + sys_lib_search_path_spec='/usr/local/lib /usr/gnu/lib /usr/ccs/lib /usr/lib /lib' + shlibpath_overrides_runpath=no + else + sys_lib_search_path_spec='/usr/ccs/lib /usr/lib' + shlibpath_overrides_runpath=yes + case $host_os in + sco3.2v5*) + sys_lib_search_path_spec="$sys_lib_search_path_spec /lib" + ;; + esac + fi + sys_lib_dlsearch_path_spec='/usr/lib' + ;; + +uts4*) + version_type=linux + library_names_spec='${libname}${release}${shared_ext}$versuffix ${libname}${release}${shared_ext}$major $libname${shared_ext}' + soname_spec='${libname}${release}${shared_ext}$major' + shlibpath_var=LD_LIBRARY_PATH + ;; + +*) + dynamic_linker=no + ;; +esac +echo "$as_me:$LINENO: result: $dynamic_linker" >&5 +echo "${ECHO_T}$dynamic_linker" >&6 +test "$dynamic_linker" = no && can_build_shared=no + +variables_saved_for_relink="PATH $shlibpath_var $runpath_var" +if test "$GCC" = yes; then + variables_saved_for_relink="$variables_saved_for_relink GCC_EXEC_PREFIX COMPILER_PATH LIBRARY_PATH" +fi + +echo "$as_me:$LINENO: checking how to hardcode library paths into programs" >&5 +echo $ECHO_N "checking how to hardcode library paths into programs... $ECHO_C" >&6 +hardcode_action_CXX= +if test -n "$hardcode_libdir_flag_spec_CXX" || \ + test -n "$runpath_var_CXX" || \ + test "X$hardcode_automatic_CXX" = "Xyes" ; then + + # We can hardcode non-existant directories. + if test "$hardcode_direct_CXX" != no && + # If the only mechanism to avoid hardcoding is shlibpath_var, we + # have to relink, otherwise we might link with an installed library + # when we should be linking with a yet-to-be-installed one + ## test "$_LT_AC_TAGVAR(hardcode_shlibpath_var, CXX)" != no && + test "$hardcode_minus_L_CXX" != no; then + # Linking always hardcodes the temporary library directory. + hardcode_action_CXX=relink + else + # We can link without hardcoding, and we can hardcode nonexisting dirs. + hardcode_action_CXX=immediate + fi +else + # We cannot hardcode anything, or else we can only hardcode existing + # directories. + hardcode_action_CXX=unsupported +fi +echo "$as_me:$LINENO: result: $hardcode_action_CXX" >&5 +echo "${ECHO_T}$hardcode_action_CXX" >&6 + +if test "$hardcode_action_CXX" = relink; then + # Fast installation is not supported + enable_fast_install=no +elif test "$shlibpath_overrides_runpath" = yes || + test "$enable_shared" = no; then + # Fast installation is not necessary + enable_fast_install=needless +fi + + +# The else clause should only fire when bootstrapping the +# libtool distribution, otherwise you forgot to ship ltmain.sh +# with your package, and you will get complaints that there are +# no rules to generate ltmain.sh. +if test -f "$ltmain"; then + # See if we are running on zsh, and set the options which allow our commands through + # without removal of \ escapes. + if test -n "${ZSH_VERSION+set}" ; then + setopt NO_GLOB_SUBST + fi + # Now quote all the things that may contain metacharacters while being + # careful not to overquote the AC_SUBSTed values. We take copies of the + # variables and quote the copies for generation of the libtool script. + for var in echo old_CC old_CFLAGS AR AR_FLAGS EGREP RANLIB LN_S LTCC LTCFLAGS NM \ + SED SHELL STRIP \ + libname_spec library_names_spec soname_spec extract_expsyms_cmds \ + old_striplib striplib file_magic_cmd finish_cmds finish_eval \ + deplibs_check_method reload_flag reload_cmds need_locks \ + lt_cv_sys_global_symbol_pipe lt_cv_sys_global_symbol_to_cdecl \ + lt_cv_sys_global_symbol_to_c_name_address \ + sys_lib_search_path_spec sys_lib_dlsearch_path_spec \ + old_postinstall_cmds old_postuninstall_cmds \ + compiler_CXX \ + CC_CXX \ + LD_CXX \ + lt_prog_compiler_wl_CXX \ + lt_prog_compiler_pic_CXX \ + lt_prog_compiler_static_CXX \ + lt_prog_compiler_no_builtin_flag_CXX \ + export_dynamic_flag_spec_CXX \ + thread_safe_flag_spec_CXX \ + whole_archive_flag_spec_CXX \ + enable_shared_with_static_runtimes_CXX \ + old_archive_cmds_CXX \ + old_archive_from_new_cmds_CXX \ + predep_objects_CXX \ + postdep_objects_CXX \ + predeps_CXX \ + postdeps_CXX \ + compiler_lib_search_path_CXX \ + archive_cmds_CXX \ + archive_expsym_cmds_CXX \ + postinstall_cmds_CXX \ + postuninstall_cmds_CXX \ + old_archive_from_expsyms_cmds_CXX \ + allow_undefined_flag_CXX \ + no_undefined_flag_CXX \ + export_symbols_cmds_CXX \ + hardcode_libdir_flag_spec_CXX \ + hardcode_libdir_flag_spec_ld_CXX \ + hardcode_libdir_separator_CXX \ + hardcode_automatic_CXX \ + module_cmds_CXX \ + module_expsym_cmds_CXX \ + lt_cv_prog_compiler_c_o_CXX \ + exclude_expsyms_CXX \ + include_expsyms_CXX; do + + case $var in + old_archive_cmds_CXX | \ + old_archive_from_new_cmds_CXX | \ + archive_cmds_CXX | \ + archive_expsym_cmds_CXX | \ + module_cmds_CXX | \ + module_expsym_cmds_CXX | \ + old_archive_from_expsyms_cmds_CXX | \ + export_symbols_cmds_CXX | \ + extract_expsyms_cmds | reload_cmds | finish_cmds | \ + postinstall_cmds | postuninstall_cmds | \ + old_postinstall_cmds | old_postuninstall_cmds | \ + sys_lib_search_path_spec | sys_lib_dlsearch_path_spec) + # Double-quote double-evaled strings. + eval "lt_$var=\\\"\`\$echo \"X\$$var\" | \$Xsed -e \"\$double_quote_subst\" -e \"\$sed_quote_subst\" -e \"\$delay_variable_subst\"\`\\\"" + ;; + *) + eval "lt_$var=\\\"\`\$echo \"X\$$var\" | \$Xsed -e \"\$sed_quote_subst\"\`\\\"" + ;; + esac + done + + case $lt_echo in + *'\$0 --fallback-echo"') + lt_echo=`$echo "X$lt_echo" | $Xsed -e 's/\\\\\\\$0 --fallback-echo"$/$0 --fallback-echo"/'` + ;; + esac + +cfgfile="$ofile" + + cat <<__EOF__ >> "$cfgfile" +# ### BEGIN LIBTOOL TAG CONFIG: $tagname + +# Libtool was configured on host `(hostname || uname -n) 2>/dev/null | sed 1q`: + +# Shell to use when invoking shell scripts. +SHELL=$lt_SHELL + +# Whether or not to build shared libraries. +build_libtool_libs=$enable_shared + +# Whether or not to build static libraries. +build_old_libs=$enable_static + +# Whether or not to add -lc for building shared libraries. +build_libtool_need_lc=$archive_cmds_need_lc_CXX + +# Whether or not to disallow shared libs when runtime libs are static +allow_libtool_libs_with_static_runtimes=$enable_shared_with_static_runtimes_CXX + +# Whether or not to optimize for fast installation. +fast_install=$enable_fast_install + +# The host system. +host_alias=$host_alias +host=$host +host_os=$host_os + +# The build system. +build_alias=$build_alias +build=$build +build_os=$build_os + +# An echo program that does not interpret backslashes. +echo=$lt_echo + +# The archiver. +AR=$lt_AR +AR_FLAGS=$lt_AR_FLAGS + +# A C compiler. +LTCC=$lt_LTCC + +# LTCC compiler flags. +LTCFLAGS=$lt_LTCFLAGS + +# A language-specific compiler. +CC=$lt_compiler_CXX + +# Is the compiler the GNU C compiler? +with_gcc=$GCC_CXX + +gcc_dir=\`gcc -print-file-name=. | $SED 's,/\.$,,'\` +gcc_ver=\`gcc -dumpversion\` + +# An ERE matcher. +EGREP=$lt_EGREP + +# The linker used to build libraries. +LD=$lt_LD_CXX + +# Whether we need hard or soft links. +LN_S=$lt_LN_S + +# A BSD-compatible nm program. +NM=$lt_NM + +# A symbol stripping program +STRIP=$lt_STRIP + +# Used to examine libraries when file_magic_cmd begins "file" +MAGIC_CMD=$MAGIC_CMD + +# Used on cygwin: DLL creation program. +DLLTOOL="$DLLTOOL" + +# Used on cygwin: object dumper. +OBJDUMP="$OBJDUMP" + +# Used on cygwin: assembler. +AS="$AS" + +# The name of the directory that contains temporary libtool files. +objdir=$objdir + +# How to create reloadable object files. +reload_flag=$lt_reload_flag +reload_cmds=$lt_reload_cmds + +# How to pass a linker flag through the compiler. +wl=$lt_lt_prog_compiler_wl_CXX + +# Object file suffix (normally "o"). +objext="$ac_objext" + +# Old archive suffix (normally "a"). +libext="$libext" + +# Shared library suffix (normally ".so"). +shrext_cmds='$shrext_cmds' + +# Executable file suffix (normally ""). +exeext="$exeext" + +# Additional compiler flags for building library objects. +pic_flag=$lt_lt_prog_compiler_pic_CXX +pic_mode=$pic_mode + +# What is the maximum length of a command? +max_cmd_len=$lt_cv_sys_max_cmd_len + +# Does compiler simultaneously support -c and -o options? +compiler_c_o=$lt_lt_cv_prog_compiler_c_o_CXX + +# Must we lock files when doing compilation? +need_locks=$lt_need_locks + +# Do we need the lib prefix for modules? +need_lib_prefix=$need_lib_prefix + +# Do we need a version for libraries? +need_version=$need_version + +# Whether dlopen is supported. +dlopen_support=$enable_dlopen + +# Whether dlopen of programs is supported. +dlopen_self=$enable_dlopen_self + +# Whether dlopen of statically linked programs is supported. +dlopen_self_static=$enable_dlopen_self_static + +# Compiler flag to prevent dynamic linking. +link_static_flag=$lt_lt_prog_compiler_static_CXX + +# Compiler flag to turn off builtin functions. +no_builtin_flag=$lt_lt_prog_compiler_no_builtin_flag_CXX + +# Compiler flag to allow reflexive dlopens. +export_dynamic_flag_spec=$lt_export_dynamic_flag_spec_CXX + +# Compiler flag to generate shared objects directly from archives. +whole_archive_flag_spec=$lt_whole_archive_flag_spec_CXX + +# Compiler flag to generate thread-safe objects. +thread_safe_flag_spec=$lt_thread_safe_flag_spec_CXX + +# Library versioning type. +version_type=$version_type + +# Format of library name prefix. +libname_spec=$lt_libname_spec + +# List of archive names. First name is the real one, the rest are links. +# The last name is the one that the linker finds with -lNAME. +library_names_spec=$lt_library_names_spec + +# The coded name of the library, if different from the real name. +soname_spec=$lt_soname_spec + +# Commands used to build and install an old-style archive. +RANLIB=$lt_RANLIB +old_archive_cmds=$lt_old_archive_cmds_CXX +old_postinstall_cmds=$lt_old_postinstall_cmds +old_postuninstall_cmds=$lt_old_postuninstall_cmds + +# Create an old-style archive from a shared archive. +old_archive_from_new_cmds=$lt_old_archive_from_new_cmds_CXX + +# Create a temporary old-style archive to link instead of a shared archive. +old_archive_from_expsyms_cmds=$lt_old_archive_from_expsyms_cmds_CXX + +# Commands used to build and install a shared archive. +archive_cmds=$lt_archive_cmds_CXX +archive_expsym_cmds=$lt_archive_expsym_cmds_CXX +postinstall_cmds=$lt_postinstall_cmds +postuninstall_cmds=$lt_postuninstall_cmds + +# Commands used to build a loadable module (assumed same as above if empty) +module_cmds=$lt_module_cmds_CXX +module_expsym_cmds=$lt_module_expsym_cmds_CXX + +# Commands to strip libraries. +old_striplib=$lt_old_striplib +striplib=$lt_striplib + +# Dependencies to place before the objects being linked to create a +# shared library. +predep_objects=\`echo $lt_predep_objects_CXX | \$SED -e "s@\${gcc_dir}@\\\${gcc_dir}@g;s@\${gcc_ver}@\\\${gcc_ver}@g"\` + +# Dependencies to place after the objects being linked to create a +# shared library. +postdep_objects=\`echo $lt_postdep_objects_CXX | \$SED -e "s@\${gcc_dir}@\\\${gcc_dir}@g;s@\${gcc_ver}@\\\${gcc_ver}@g"\` + +# Dependencies to place before the objects being linked to create a +# shared library. +predeps=$lt_predeps_CXX + +# Dependencies to place after the objects being linked to create a +# shared library. +postdeps=$lt_postdeps_CXX + +# The library search path used internally by the compiler when linking +# a shared library. +compiler_lib_search_path=\`echo $lt_compiler_lib_search_path_CXX | \$SED -e "s@\${gcc_dir}@\\\${gcc_dir}@g;s@\${gcc_ver}@\\\${gcc_ver}@g"\` + +# Method to check whether dependent libraries are shared objects. +deplibs_check_method=$lt_deplibs_check_method + +# Command to use when deplibs_check_method == file_magic. +file_magic_cmd=$lt_file_magic_cmd + +# Flag that allows shared libraries with undefined symbols to be built. +allow_undefined_flag=$lt_allow_undefined_flag_CXX + +# Flag that forces no undefined symbols. +no_undefined_flag=$lt_no_undefined_flag_CXX + +# Commands used to finish a libtool library installation in a directory. +finish_cmds=$lt_finish_cmds + +# Same as above, but a single script fragment to be evaled but not shown. +finish_eval=$lt_finish_eval + +# Take the output of nm and produce a listing of raw symbols and C names. +global_symbol_pipe=$lt_lt_cv_sys_global_symbol_pipe + +# Transform the output of nm in a proper C declaration +global_symbol_to_cdecl=$lt_lt_cv_sys_global_symbol_to_cdecl + +# Transform the output of nm in a C name address pair +global_symbol_to_c_name_address=$lt_lt_cv_sys_global_symbol_to_c_name_address + +# This is the shared library runtime path variable. +runpath_var=$runpath_var + +# This is the shared library path variable. +shlibpath_var=$shlibpath_var + +# Is shlibpath searched before the hard-coded library search path? +shlibpath_overrides_runpath=$shlibpath_overrides_runpath + +# How to hardcode a shared library path into an executable. +hardcode_action=$hardcode_action_CXX + +# Whether we should hardcode library paths into libraries. +hardcode_into_libs=$hardcode_into_libs + +# Flag to hardcode \$libdir into a binary during linking. +# This must work even if \$libdir does not exist. +hardcode_libdir_flag_spec=$lt_hardcode_libdir_flag_spec_CXX + +# If ld is used when linking, flag to hardcode \$libdir into +# a binary during linking. This must work even if \$libdir does +# not exist. +hardcode_libdir_flag_spec_ld=$lt_hardcode_libdir_flag_spec_ld_CXX + +# Whether we need a single -rpath flag with a separated argument. +hardcode_libdir_separator=$lt_hardcode_libdir_separator_CXX + +# Set to yes if using DIR/libNAME${shared_ext} during linking hardcodes DIR into the +# resulting binary. +hardcode_direct=$hardcode_direct_CXX + +# Set to yes if using the -LDIR flag during linking hardcodes DIR into the +# resulting binary. +hardcode_minus_L=$hardcode_minus_L_CXX + +# Set to yes if using SHLIBPATH_VAR=DIR during linking hardcodes DIR into +# the resulting binary. +hardcode_shlibpath_var=$hardcode_shlibpath_var_CXX + +# Set to yes if building a shared library automatically hardcodes DIR into the library +# and all subsequent libraries and executables linked against it. +hardcode_automatic=$hardcode_automatic_CXX + +# Variables whose values should be saved in libtool wrapper scripts and +# restored at relink time. +variables_saved_for_relink="$variables_saved_for_relink" + +# Whether libtool must link a program against all its dependency libraries. +link_all_deplibs=$link_all_deplibs_CXX + +# Compile-time system search path for libraries +sys_lib_search_path_spec=\`echo $lt_sys_lib_search_path_spec | \$SED -e "s@\${gcc_dir}@\\\${gcc_dir}@g;s@\${gcc_ver}@\\\${gcc_ver}@g"\` + +# Run-time system search path for libraries +sys_lib_dlsearch_path_spec=$lt_sys_lib_dlsearch_path_spec + +# Fix the shell variable \$srcfile for the compiler. +fix_srcfile_path="$fix_srcfile_path_CXX" + +# Set to yes if exported symbols are required. +always_export_symbols=$always_export_symbols_CXX + +# The commands to list exported symbols. +export_symbols_cmds=$lt_export_symbols_cmds_CXX + +# The commands to extract the exported symbol list from a shared archive. +extract_expsyms_cmds=$lt_extract_expsyms_cmds + +# Symbols that should not be listed in the preloaded symbols. +exclude_expsyms=$lt_exclude_expsyms_CXX + +# Symbols that must always be exported. +include_expsyms=$lt_include_expsyms_CXX + +# ### END LIBTOOL TAG CONFIG: $tagname + +__EOF__ + + +else + # If there is no Makefile yet, we rely on a make rule to execute + # `config.status --recheck' to rerun these tests and create the + # libtool script then. + ltmain_in=`echo $ltmain | sed -e 's/\.sh$/.in/'` + if test -f "$ltmain_in"; then + test -f Makefile && make "$ltmain" + fi +fi + + +ac_ext=c +ac_cpp='$CPP $CPPFLAGS' +ac_compile='$CC -c $CFLAGS $CPPFLAGS conftest.$ac_ext >&5' +ac_link='$CC -o conftest$ac_exeext $CFLAGS $CPPFLAGS $LDFLAGS conftest.$ac_ext $LIBS >&5' +ac_compiler_gnu=$ac_cv_c_compiler_gnu + +CC=$lt_save_CC +LDCXX=$LD +LD=$lt_save_LD +GCC=$lt_save_GCC +with_gnu_ldcxx=$with_gnu_ld +with_gnu_ld=$lt_save_with_gnu_ld +lt_cv_path_LDCXX=$lt_cv_path_LD +lt_cv_path_LD=$lt_save_path_LD +lt_cv_prog_gnu_ldcxx=$lt_cv_prog_gnu_ld +lt_cv_prog_gnu_ld=$lt_save_with_gnu_ld + + else + tagname="" + fi + ;; + + F77) + if test -n "$F77" && test "X$F77" != "Xno"; then + +ac_ext=f +ac_compile='$F77 -c $FFLAGS conftest.$ac_ext >&5' +ac_link='$F77 -o conftest$ac_exeext $FFLAGS $LDFLAGS conftest.$ac_ext $LIBS >&5' +ac_compiler_gnu=$ac_cv_f77_compiler_gnu + + +archive_cmds_need_lc_F77=no +allow_undefined_flag_F77= +always_export_symbols_F77=no +archive_expsym_cmds_F77= +export_dynamic_flag_spec_F77= +hardcode_direct_F77=no +hardcode_libdir_flag_spec_F77= +hardcode_libdir_flag_spec_ld_F77= +hardcode_libdir_separator_F77= +hardcode_minus_L_F77=no +hardcode_automatic_F77=no +module_cmds_F77= +module_expsym_cmds_F77= +link_all_deplibs_F77=unknown +old_archive_cmds_F77=$old_archive_cmds +no_undefined_flag_F77= +whole_archive_flag_spec_F77= +enable_shared_with_static_runtimes_F77=no + +# Source file extension for f77 test sources. +ac_ext=f + +# Object file extension for compiled f77 test sources. +objext=o +objext_F77=$objext + +# Code to be used in simple compile tests +lt_simple_compile_test_code=" subroutine t\n return\n end\n" + +# Code to be used in simple link tests +lt_simple_link_test_code=" program t\n end\n" + +# ltmain only uses $CC for tagged configurations so make sure $CC is set. + +# If no C compiler was specified, use CC. +LTCC=${LTCC-"$CC"} + +# If no C compiler flags were specified, use CFLAGS. +LTCFLAGS=${LTCFLAGS-"$CFLAGS"} + +# Allow CC to be a program name with arguments. +compiler=$CC + + +# save warnings/boilerplate of simple test code +ac_outfile=conftest.$ac_objext +printf "$lt_simple_compile_test_code" >conftest.$ac_ext +eval "$ac_compile" 2>&1 >/dev/null | $SED '/^$/d; /^ *+/d' >conftest.err +_lt_compiler_boilerplate=`cat conftest.err` +$rm conftest* + +ac_outfile=conftest.$ac_objext +printf "$lt_simple_link_test_code" >conftest.$ac_ext +eval "$ac_link" 2>&1 >/dev/null | $SED '/^$/d; /^ *+/d' >conftest.err +_lt_linker_boilerplate=`cat conftest.err` +$rm conftest* + + +# Allow CC to be a program name with arguments. +lt_save_CC="$CC" +CC=${F77-"f77"} +compiler=$CC +compiler_F77=$CC +for cc_temp in $compiler""; do + case $cc_temp in + compile | *[\\/]compile | ccache | *[\\/]ccache ) ;; + distcc | *[\\/]distcc | purify | *[\\/]purify ) ;; + \-*) ;; + *) break;; + esac +done +cc_basename=`$echo "X$cc_temp" | $Xsed -e 's%.*/%%' -e "s%^$host_alias-%%"` + + +echo "$as_me:$LINENO: checking if libtool supports shared libraries" >&5 +echo $ECHO_N "checking if libtool supports shared libraries... $ECHO_C" >&6 +echo "$as_me:$LINENO: result: $can_build_shared" >&5 +echo "${ECHO_T}$can_build_shared" >&6 + +echo "$as_me:$LINENO: checking whether to build shared libraries" >&5 +echo $ECHO_N "checking whether to build shared libraries... $ECHO_C" >&6 +test "$can_build_shared" = "no" && enable_shared=no + +# On AIX, shared libraries and static libraries use the same namespace, and +# are all built from PIC. +case $host_os in +aix3*) + test "$enable_shared" = yes && enable_static=no + if test -n "$RANLIB"; then + archive_cmds="$archive_cmds~\$RANLIB \$lib" + postinstall_cmds='$RANLIB $lib' + fi + ;; +aix4* | aix5*) + if test "$host_cpu" != ia64 && test "$aix_use_runtimelinking" = no ; then + test "$enable_shared" = yes && enable_static=no + fi + ;; +esac +echo "$as_me:$LINENO: result: $enable_shared" >&5 +echo "${ECHO_T}$enable_shared" >&6 + +echo "$as_me:$LINENO: checking whether to build static libraries" >&5 +echo $ECHO_N "checking whether to build static libraries... $ECHO_C" >&6 +# Make sure either enable_shared or enable_static is yes. +test "$enable_shared" = yes || enable_static=yes +echo "$as_me:$LINENO: result: $enable_static" >&5 +echo "${ECHO_T}$enable_static" >&6 + +GCC_F77="$G77" +LD_F77="$LD" + +lt_prog_compiler_wl_F77= +lt_prog_compiler_pic_F77= +lt_prog_compiler_static_F77= + +echo "$as_me:$LINENO: checking for $compiler option to produce PIC" >&5 +echo $ECHO_N "checking for $compiler option to produce PIC... $ECHO_C" >&6 + + if test "$GCC" = yes; then + lt_prog_compiler_wl_F77='-Wl,' + lt_prog_compiler_static_F77='-static' + + case $host_os in + aix*) + # All AIX code is PIC. + if test "$host_cpu" = ia64; then + # AIX 5 now supports IA64 processor + lt_prog_compiler_static_F77='-Bstatic' + fi + ;; + + amigaos*) + # FIXME: we need at least 68020 code to build shared libraries, but + # adding the `-m68020' flag to GCC prevents building anything better, + # like `-m68040'. + lt_prog_compiler_pic_F77='-m68020 -resident32 -malways-restore-a4' + ;; + + beos* | cygwin* | irix5* | irix6* | nonstopux* | osf3* | osf4* | osf5*) + # PIC is the default for these OSes. + ;; + + mingw* | pw32* | os2*) + # This hack is so that the source file can tell whether it is being + # built for inclusion in a dll (and should export symbols for example). + lt_prog_compiler_pic_F77='-DDLL_EXPORT' + ;; + + darwin* | rhapsody*) + # PIC is the default on this platform + # Common symbols not allowed in MH_DYLIB files + lt_prog_compiler_pic_F77='-fno-common' + ;; + + interix3*) + # Interix 3.x gcc -fpic/-fPIC options generate broken code. + # Instead, we relocate shared libraries at runtime. + ;; + + msdosdjgpp*) + # Just because we use GCC doesn't mean we suddenly get shared libraries + # on systems that don't support them. + lt_prog_compiler_can_build_shared_F77=no + enable_shared=no + ;; + + sysv4*MP*) + if test -d /usr/nec; then + lt_prog_compiler_pic_F77=-Kconform_pic + fi + ;; + + hpux*) + # PIC is the default for IA64 HP-UX and 64-bit HP-UX, but + # not for PA HP-UX. + case $host_cpu in + hppa*64*|ia64*) + # +Z the default + ;; + *) + lt_prog_compiler_pic_F77='-fPIC' + ;; + esac + ;; + + *) + lt_prog_compiler_pic_F77='-fPIC' + ;; + esac + else + # PORTME Check for flag to pass linker flags through the system compiler. + case $host_os in + aix*) + lt_prog_compiler_wl_F77='-Wl,' + if test "$host_cpu" = ia64; then + # AIX 5 now supports IA64 processor + lt_prog_compiler_static_F77='-Bstatic' + else + lt_prog_compiler_static_F77='-bnso -bI:/lib/syscalls.exp' + fi + ;; + darwin*) + # PIC is the default on this platform + # Common symbols not allowed in MH_DYLIB files + case $cc_basename in + xlc*) + lt_prog_compiler_pic_F77='-qnocommon' + lt_prog_compiler_wl_F77='-Wl,' + ;; + esac + ;; + + mingw* | pw32* | os2*) + # This hack is so that the source file can tell whether it is being + # built for inclusion in a dll (and should export symbols for example). + lt_prog_compiler_pic_F77='-DDLL_EXPORT' + ;; + + hpux9* | hpux10* | hpux11*) + lt_prog_compiler_wl_F77='-Wl,' + # PIC is the default for IA64 HP-UX and 64-bit HP-UX, but + # not for PA HP-UX. + case $host_cpu in + hppa*64*|ia64*) + # +Z the default + ;; + *) + lt_prog_compiler_pic_F77='+Z' + ;; + esac + # Is there a better lt_prog_compiler_static that works with the bundled CC? + lt_prog_compiler_static_F77='${wl}-a ${wl}archive' + ;; + + irix5* | irix6* | nonstopux*) + lt_prog_compiler_wl_F77='-Wl,' + # PIC (with -KPIC) is the default. + lt_prog_compiler_static_F77='-non_shared' + ;; + + newsos6) + lt_prog_compiler_pic_F77='-KPIC' + lt_prog_compiler_static_F77='-Bstatic' + ;; + + linux*) + case $cc_basename in + icc* | ecc*) + lt_prog_compiler_wl_F77='-Wl,' + lt_prog_compiler_pic_F77='-KPIC' + lt_prog_compiler_static_F77='-static' + ;; + pgcc* | pgf77* | pgf90* | pgf95*) + # Portland Group compilers (*not* the Pentium gcc compiler, + # which looks to be a dead project) + lt_prog_compiler_wl_F77='-Wl,' + lt_prog_compiler_pic_F77='-fpic' + lt_prog_compiler_static_F77='-Bstatic' + ;; + ccc*) + lt_prog_compiler_wl_F77='-Wl,' + # All Alpha code is PIC. + lt_prog_compiler_static_F77='-non_shared' + ;; + esac + ;; + + osf3* | osf4* | osf5*) + lt_prog_compiler_wl_F77='-Wl,' + # All OSF/1 code is PIC. + lt_prog_compiler_static_F77='-non_shared' + ;; + + solaris*) + lt_prog_compiler_pic_F77='-KPIC' + lt_prog_compiler_static_F77='-Bstatic' + case $cc_basename in + f77* | f90* | f95*) + lt_prog_compiler_wl_F77='-Qoption ld ';; + *) + lt_prog_compiler_wl_F77='-Wl,';; + esac + ;; + + sunos4*) + lt_prog_compiler_wl_F77='-Qoption ld ' + lt_prog_compiler_pic_F77='-PIC' + lt_prog_compiler_static_F77='-Bstatic' + ;; + + sysv4 | sysv4.2uw2* | sysv4.3*) + lt_prog_compiler_wl_F77='-Wl,' + lt_prog_compiler_pic_F77='-KPIC' + lt_prog_compiler_static_F77='-Bstatic' + ;; + + sysv4*MP*) + if test -d /usr/nec ;then + lt_prog_compiler_pic_F77='-Kconform_pic' + lt_prog_compiler_static_F77='-Bstatic' + fi + ;; + + sysv5* | unixware* | sco3.2v5* | sco5v6* | OpenUNIX*) + lt_prog_compiler_wl_F77='-Wl,' + lt_prog_compiler_pic_F77='-KPIC' + lt_prog_compiler_static_F77='-Bstatic' + ;; + + unicos*) + lt_prog_compiler_wl_F77='-Wl,' + lt_prog_compiler_can_build_shared_F77=no + ;; + + uts4*) + lt_prog_compiler_pic_F77='-pic' + lt_prog_compiler_static_F77='-Bstatic' + ;; + + *) + lt_prog_compiler_can_build_shared_F77=no + ;; + esac + fi + +echo "$as_me:$LINENO: result: $lt_prog_compiler_pic_F77" >&5 +echo "${ECHO_T}$lt_prog_compiler_pic_F77" >&6 + +# +# Check to make sure the PIC flag actually works. +# +if test -n "$lt_prog_compiler_pic_F77"; then + +echo "$as_me:$LINENO: checking if $compiler PIC flag $lt_prog_compiler_pic_F77 works" >&5 +echo $ECHO_N "checking if $compiler PIC flag $lt_prog_compiler_pic_F77 works... $ECHO_C" >&6 +if test "${lt_prog_compiler_pic_works_F77+set}" = set; then + echo $ECHO_N "(cached) $ECHO_C" >&6 +else + lt_prog_compiler_pic_works_F77=no + ac_outfile=conftest.$ac_objext + printf "$lt_simple_compile_test_code" > conftest.$ac_ext + lt_compiler_flag="$lt_prog_compiler_pic_F77" + # Insert the option either (1) after the last *FLAGS variable, or + # (2) before a word containing "conftest.", or (3) at the end. + # Note that $ac_compile itself does not contain backslashes and begins + # with a dollar sign (not a hyphen), so the echo should work correctly. + # The option is referenced via a variable to avoid confusing sed. + lt_compile=`echo "$ac_compile" | $SED \ + -e 's:.*FLAGS}\{0,1\} :&$lt_compiler_flag :; t' \ + -e 's: [^ ]*conftest\.: $lt_compiler_flag&:; t' \ + -e 's:$: $lt_compiler_flag:'` + (eval echo "\"\$as_me:13392: $lt_compile\"" >&5) + (eval "$lt_compile" 2>conftest.err) + ac_status=$? + cat conftest.err >&5 + echo "$as_me:13396: \$? = $ac_status" >&5 + if (exit $ac_status) && test -s "$ac_outfile"; then + # The compiler can only warn and ignore the option if not recognized + # So say no if there are warnings other than the usual output. + $echo "X$_lt_compiler_boilerplate" | $Xsed -e '/^$/d' >conftest.exp + $SED '/^$/d; /^ *+/d' conftest.err >conftest.er2 + if test ! -s conftest.er2 || diff conftest.exp conftest.er2 >/dev/null; then + lt_prog_compiler_pic_works_F77=yes + fi + fi + $rm conftest* + +fi +echo "$as_me:$LINENO: result: $lt_prog_compiler_pic_works_F77" >&5 +echo "${ECHO_T}$lt_prog_compiler_pic_works_F77" >&6 + +if test x"$lt_prog_compiler_pic_works_F77" = xyes; then + case $lt_prog_compiler_pic_F77 in + "" | " "*) ;; + *) lt_prog_compiler_pic_F77=" $lt_prog_compiler_pic_F77" ;; + esac +else + lt_prog_compiler_pic_F77= + lt_prog_compiler_can_build_shared_F77=no +fi + +fi +case $host_os in + # For platforms which do not support PIC, -DPIC is meaningless: + *djgpp*) + lt_prog_compiler_pic_F77= + ;; + *) + lt_prog_compiler_pic_F77="$lt_prog_compiler_pic_F77" + ;; +esac + +# +# Check to make sure the static flag actually works. +# +wl=$lt_prog_compiler_wl_F77 eval lt_tmp_static_flag=\"$lt_prog_compiler_static_F77\" +echo "$as_me:$LINENO: checking if $compiler static flag $lt_tmp_static_flag works" >&5 +echo $ECHO_N "checking if $compiler static flag $lt_tmp_static_flag works... $ECHO_C" >&6 +if test "${lt_prog_compiler_static_works_F77+set}" = set; then + echo $ECHO_N "(cached) $ECHO_C" >&6 +else + lt_prog_compiler_static_works_F77=no + save_LDFLAGS="$LDFLAGS" + LDFLAGS="$LDFLAGS $lt_tmp_static_flag" + printf "$lt_simple_link_test_code" > conftest.$ac_ext + if (eval $ac_link 2>conftest.err) && test -s conftest$ac_exeext; then + # The linker can only warn and ignore the option if not recognized + # So say no if there are warnings + if test -s conftest.err; then + # Append any errors to the config.log. + cat conftest.err 1>&5 + $echo "X$_lt_linker_boilerplate" | $Xsed -e '/^$/d' > conftest.exp + $SED '/^$/d; /^ *+/d' conftest.err >conftest.er2 + if diff conftest.exp conftest.er2 >/dev/null; then + lt_prog_compiler_static_works_F77=yes + fi + else + lt_prog_compiler_static_works_F77=yes + fi + fi + $rm conftest* + LDFLAGS="$save_LDFLAGS" + +fi +echo "$as_me:$LINENO: result: $lt_prog_compiler_static_works_F77" >&5 +echo "${ECHO_T}$lt_prog_compiler_static_works_F77" >&6 + +if test x"$lt_prog_compiler_static_works_F77" = xyes; then + : +else + lt_prog_compiler_static_F77= +fi + + +echo "$as_me:$LINENO: checking if $compiler supports -c -o file.$ac_objext" >&5 +echo $ECHO_N "checking if $compiler supports -c -o file.$ac_objext... $ECHO_C" >&6 +if test "${lt_cv_prog_compiler_c_o_F77+set}" = set; then + echo $ECHO_N "(cached) $ECHO_C" >&6 +else + lt_cv_prog_compiler_c_o_F77=no + $rm -r conftest 2>/dev/null + mkdir conftest + cd conftest + mkdir out + printf "$lt_simple_compile_test_code" > conftest.$ac_ext + + lt_compiler_flag="-o out/conftest2.$ac_objext" + # Insert the option either (1) after the last *FLAGS variable, or + # (2) before a word containing "conftest.", or (3) at the end. + # Note that $ac_compile itself does not contain backslashes and begins + # with a dollar sign (not a hyphen), so the echo should work correctly. + lt_compile=`echo "$ac_compile" | $SED \ + -e 's:.*FLAGS}\{0,1\} :&$lt_compiler_flag :; t' \ + -e 's: [^ ]*conftest\.: $lt_compiler_flag&:; t' \ + -e 's:$: $lt_compiler_flag:'` + (eval echo "\"\$as_me:13496: $lt_compile\"" >&5) + (eval "$lt_compile" 2>out/conftest.err) + ac_status=$? + cat out/conftest.err >&5 + echo "$as_me:13500: \$? = $ac_status" >&5 + if (exit $ac_status) && test -s out/conftest2.$ac_objext + then + # The compiler can only warn and ignore the option if not recognized + # So say no if there are warnings + $echo "X$_lt_compiler_boilerplate" | $Xsed -e '/^$/d' > out/conftest.exp + $SED '/^$/d; /^ *+/d' out/conftest.err >out/conftest.er2 + if test ! -s out/conftest.er2 || diff out/conftest.exp out/conftest.er2 >/dev/null; then + lt_cv_prog_compiler_c_o_F77=yes + fi + fi + chmod u+w . 2>&5 + $rm conftest* + # SGI C++ compiler will create directory out/ii_files/ for + # template instantiation + test -d out/ii_files && $rm out/ii_files/* && rmdir out/ii_files + $rm out/* && rmdir out + cd .. + rmdir conftest + $rm conftest* + +fi +echo "$as_me:$LINENO: result: $lt_cv_prog_compiler_c_o_F77" >&5 +echo "${ECHO_T}$lt_cv_prog_compiler_c_o_F77" >&6 + + +hard_links="nottested" +if test "$lt_cv_prog_compiler_c_o_F77" = no && test "$need_locks" != no; then + # do not overwrite the value of need_locks provided by the user + echo "$as_me:$LINENO: checking if we can lock with hard links" >&5 +echo $ECHO_N "checking if we can lock with hard links... $ECHO_C" >&6 + hard_links=yes + $rm conftest* + ln conftest.a conftest.b 2>/dev/null && hard_links=no + touch conftest.a + ln conftest.a conftest.b 2>&5 || hard_links=no + ln conftest.a conftest.b 2>/dev/null && hard_links=no + echo "$as_me:$LINENO: result: $hard_links" >&5 +echo "${ECHO_T}$hard_links" >&6 + if test "$hard_links" = no; then + { echo "$as_me:$LINENO: WARNING: \`$CC' does not support \`-c -o', so \`make -j' may be unsafe" >&5 +echo "$as_me: WARNING: \`$CC' does not support \`-c -o', so \`make -j' may be unsafe" >&2;} + need_locks=warn + fi +else + need_locks=no +fi + +echo "$as_me:$LINENO: checking whether the $compiler linker ($LD) supports shared libraries" >&5 +echo $ECHO_N "checking whether the $compiler linker ($LD) supports shared libraries... $ECHO_C" >&6 + + runpath_var= + allow_undefined_flag_F77= + enable_shared_with_static_runtimes_F77=no + archive_cmds_F77= + archive_expsym_cmds_F77= + old_archive_From_new_cmds_F77= + old_archive_from_expsyms_cmds_F77= + export_dynamic_flag_spec_F77= + whole_archive_flag_spec_F77= + thread_safe_flag_spec_F77= + hardcode_libdir_flag_spec_F77= + hardcode_libdir_flag_spec_ld_F77= + hardcode_libdir_separator_F77= + hardcode_direct_F77=no + hardcode_minus_L_F77=no + hardcode_shlibpath_var_F77=unsupported + link_all_deplibs_F77=unknown + hardcode_automatic_F77=no + module_cmds_F77= + module_expsym_cmds_F77= + always_export_symbols_F77=no + export_symbols_cmds_F77='$NM $libobjs $convenience | $global_symbol_pipe | $SED '\''s/.* //'\'' | sort | uniq > $export_symbols' + # include_expsyms should be a list of space-separated symbols to be *always* + # included in the symbol list + include_expsyms_F77= + # exclude_expsyms can be an extended regexp of symbols to exclude + # it will be wrapped by ` (' and `)$', so one must not match beginning or + # end of line. Example: `a|bc|.*d.*' will exclude the symbols `a' and `bc', + # as well as any symbol that contains `d'. + exclude_expsyms_F77="_GLOBAL_OFFSET_TABLE_" + # Although _GLOBAL_OFFSET_TABLE_ is a valid symbol C name, most a.out + # platforms (ab)use it in PIC code, but their linkers get confused if + # the symbol is explicitly referenced. Since portable code cannot + # rely on this symbol name, it's probably fine to never include it in + # preloaded symbol tables. + extract_expsyms_cmds= + # Just being paranoid about ensuring that cc_basename is set. + for cc_temp in $compiler""; do + case $cc_temp in + compile | *[\\/]compile | ccache | *[\\/]ccache ) ;; + distcc | *[\\/]distcc | purify | *[\\/]purify ) ;; + \-*) ;; + *) break;; + esac +done +cc_basename=`$echo "X$cc_temp" | $Xsed -e 's%.*/%%' -e "s%^$host_alias-%%"` + + case $host_os in + cygwin* | mingw* | pw32*) + # FIXME: the MSVC++ port hasn't been tested in a loooong time + # When not using gcc, we currently assume that we are using + # Microsoft Visual C++. + if test "$GCC" != yes; then + with_gnu_ld=no + fi + ;; + interix*) + # we just hope/assume this is gcc and not c89 (= MSVC++) + with_gnu_ld=yes + ;; + openbsd*) + with_gnu_ld=no + ;; + esac + + ld_shlibs_F77=yes + if test "$with_gnu_ld" = yes; then + # If archive_cmds runs LD, not CC, wlarc should be empty + wlarc='${wl}' + + # Set some defaults for GNU ld with shared library support. These + # are reset later if shared libraries are not supported. Putting them + # here allows them to be overridden if necessary. + runpath_var=LD_RUN_PATH + hardcode_libdir_flag_spec_F77='${wl}--rpath ${wl}$libdir' + export_dynamic_flag_spec_F77='${wl}--export-dynamic' + # ancient GNU ld didn't support --whole-archive et. al. + if $LD --help 2>&1 | grep 'no-whole-archive' > /dev/null; then + whole_archive_flag_spec_F77="$wlarc"'--whole-archive$convenience '"$wlarc"'--no-whole-archive' + else + whole_archive_flag_spec_F77= + fi + supports_anon_versioning=no + case `$LD -v 2>/dev/null` in + *\ [01].* | *\ 2.[0-9].* | *\ 2.10.*) ;; # catch versions < 2.11 + *\ 2.11.93.0.2\ *) supports_anon_versioning=yes ;; # RH7.3 ... + *\ 2.11.92.0.12\ *) supports_anon_versioning=yes ;; # Mandrake 8.2 ... + *\ 2.11.*) ;; # other 2.11 versions + *) supports_anon_versioning=yes ;; + esac + + # See if GNU ld supports shared libraries. + case $host_os in + aix3* | aix4* | aix5*) + # On AIX/PPC, the GNU linker is very broken + if test "$host_cpu" != ia64; then + ld_shlibs_F77=no + cat <<EOF 1>&2 + +*** Warning: the GNU linker, at least up to release 2.9.1, is reported +*** to be unable to reliably create shared libraries on AIX. +*** Therefore, libtool is disabling shared libraries support. If you +*** really care for shared libraries, you may want to modify your PATH +*** so that a non-GNU linker is found, and then restart. + +EOF + fi + ;; + + amigaos*) + archive_cmds_F77='$rm $output_objdir/a2ixlibrary.data~$echo "#define NAME $libname" > $output_objdir/a2ixlibrary.data~$echo "#define LIBRARY_ID 1" >> $output_objdir/a2ixlibrary.data~$echo "#define VERSION $major" >> $output_objdir/a2ixlibrary.data~$echo "#define REVISION $revision" >> $output_objdir/a2ixlibrary.data~$AR $AR_FLAGS $lib $libobjs~$RANLIB $lib~(cd $output_objdir && a2ixlibrary -32)' + hardcode_libdir_flag_spec_F77='-L$libdir' + hardcode_minus_L_F77=yes + + # Samuel A. Falvo II <kc5tja@dolphin.openprojects.net> reports + # that the semantics of dynamic libraries on AmigaOS, at least up + # to version 4, is to share data among multiple programs linked + # with the same dynamic library. Since this doesn't match the + # behavior of shared libraries on other platforms, we can't use + # them. + ld_shlibs_F77=no + ;; + + beos*) + if $LD --help 2>&1 | grep ': supported targets:.* elf' > /dev/null; then + allow_undefined_flag_F77=unsupported + # Joseph Beckenbach <jrb3@best.com> says some releases of gcc + # support --undefined. This deserves some investigation. FIXME + archive_cmds_F77='$CC -nostart $libobjs $deplibs $compiler_flags ${wl}-soname $wl$soname -o $lib' + else + ld_shlibs_F77=no + fi + ;; + + cygwin* | mingw* | pw32*) + # _LT_AC_TAGVAR(hardcode_libdir_flag_spec, F77) is actually meaningless, + # as there is no search path for DLLs. + hardcode_libdir_flag_spec_F77='-L$libdir' + allow_undefined_flag_F77=unsupported + always_export_symbols_F77=no + enable_shared_with_static_runtimes_F77=yes + export_symbols_cmds_F77='$NM $libobjs $convenience | $global_symbol_pipe | $SED -e '\''/^[BCDGRS] /s/.* \([^ ]*\)/\1 DATA/'\'' | $SED -e '\''/^[AITW] /s/.* //'\'' | sort | uniq > $export_symbols' + + if $LD --help 2>&1 | grep 'auto-import' > /dev/null; then + archive_cmds_F77='$CC -shared $libobjs $deplibs $compiler_flags -o $output_objdir/$soname ${wl}--enable-auto-image-base -Xlinker --out-implib -Xlinker $lib' + # If the export-symbols file already is a .def file (1st line + # is EXPORTS), use it as is; otherwise, prepend... + archive_expsym_cmds_F77='if test "x`$SED 1q $export_symbols`" = xEXPORTS; then + cp $export_symbols $output_objdir/$soname.def; + else + echo EXPORTS > $output_objdir/$soname.def; + cat $export_symbols >> $output_objdir/$soname.def; + fi~ + $CC -shared $output_objdir/$soname.def $libobjs $deplibs $compiler_flags -o $output_objdir/$soname ${wl}--enable-auto-image-base -Xlinker --out-implib -Xlinker $lib' + else + ld_shlibs_F77=no + fi + ;; + + interix3*) + hardcode_direct_F77=no + hardcode_shlibpath_var_F77=no + hardcode_libdir_flag_spec_F77='${wl}-rpath,$libdir' + export_dynamic_flag_spec_F77='${wl}-E' + # Hack: On Interix 3.x, we cannot compile PIC because of a broken gcc. + # Instead, shared libraries are loaded at an image base (0x10000000 by + # default) and relocated if they conflict, which is a slow very memory + # consuming and fragmenting process. To avoid this, we pick a random, + # 256 KiB-aligned image base between 0x50000000 and 0x6FFC0000 at link + # time. Moving up from 0x10000000 also allows more sbrk(2) space. + archive_cmds_F77='$CC -shared $pic_flag $libobjs $deplibs $compiler_flags ${wl}-h,$soname ${wl}--image-base,`expr ${RANDOM-$$} % 4096 / 2 \* 262144 + 1342177280` -o $lib' + archive_expsym_cmds_F77='sed "s,^,_," $export_symbols >$output_objdir/$soname.expsym~$CC -shared $pic_flag $libobjs $deplibs $compiler_flags ${wl}-h,$soname ${wl}--retain-symbols-file,$output_objdir/$soname.expsym ${wl}--image-base,`expr ${RANDOM-$$} % 4096 / 2 \* 262144 + 1342177280` -o $lib' + ;; + + linux*) + if $LD --help 2>&1 | grep ': supported targets:.* elf' > /dev/null; then + tmp_addflag= + case $cc_basename,$host_cpu in + pgcc*) # Portland Group C compiler + whole_archive_flag_spec_F77='${wl}--whole-archive`for conv in $convenience\"\"; do test -n \"$conv\" && new_convenience=\"$new_convenience,$conv\"; done; $echo \"$new_convenience\"` ${wl}--no-whole-archive' + tmp_addflag=' $pic_flag' + ;; + pgf77* | pgf90* | pgf95*) # Portland Group f77 and f90 compilers + whole_archive_flag_spec_F77='${wl}--whole-archive`for conv in $convenience\"\"; do test -n \"$conv\" && new_convenience=\"$new_convenience,$conv\"; done; $echo \"$new_convenience\"` ${wl}--no-whole-archive' + tmp_addflag=' $pic_flag -Mnomain' ;; + ecc*,ia64* | icc*,ia64*) # Intel C compiler on ia64 + tmp_addflag=' -i_dynamic' ;; + efc*,ia64* | ifort*,ia64*) # Intel Fortran compiler on ia64 + tmp_addflag=' -i_dynamic -nofor_main' ;; + ifc* | ifort*) # Intel Fortran compiler + tmp_addflag=' -nofor_main' ;; + esac + archive_cmds_F77='$CC -shared'"$tmp_addflag"' $libobjs $deplibs $compiler_flags ${wl}-soname $wl$soname -o $lib' + + if test $supports_anon_versioning = yes; then + archive_expsym_cmds_F77='$echo "{ global:" > $output_objdir/$libname.ver~ + cat $export_symbols | sed -e "s/\(.*\)/\1;/" >> $output_objdir/$libname.ver~ + $echo "local: *; };" >> $output_objdir/$libname.ver~ + $CC -shared'"$tmp_addflag"' $libobjs $deplibs $compiler_flags ${wl}-soname $wl$soname ${wl}-version-script ${wl}$output_objdir/$libname.ver -o $lib' + fi + else + ld_shlibs_F77=no + fi + ;; + + netbsd*) + if echo __ELF__ | $CC -E - | grep __ELF__ >/dev/null; then + archive_cmds_F77='$LD -Bshareable $libobjs $deplibs $linker_flags -o $lib' + wlarc= + else + archive_cmds_F77='$CC -shared $libobjs $deplibs $compiler_flags ${wl}-soname $wl$soname -o $lib' + archive_expsym_cmds_F77='$CC -shared $libobjs $deplibs $compiler_flags ${wl}-soname $wl$soname ${wl}-retain-symbols-file $wl$export_symbols -o $lib' + fi + ;; + + solaris*) + if $LD -v 2>&1 | grep 'BFD 2\.8' > /dev/null; then + ld_shlibs_F77=no + cat <<EOF 1>&2 + +*** Warning: The releases 2.8.* of the GNU linker cannot reliably +*** create shared libraries on Solaris systems. Therefore, libtool +*** is disabling shared libraries support. We urge you to upgrade GNU +*** binutils to release 2.9.1 or newer. Another option is to modify +*** your PATH or compiler configuration so that the native linker is +*** used, and then restart. + +EOF + elif $LD --help 2>&1 | grep ': supported targets:.* elf' > /dev/null; then + archive_cmds_F77='$CC -shared $libobjs $deplibs $compiler_flags ${wl}-soname $wl$soname -o $lib' + archive_expsym_cmds_F77='$CC -shared $libobjs $deplibs $compiler_flags ${wl}-soname $wl$soname ${wl}-retain-symbols-file $wl$export_symbols -o $lib' + else + ld_shlibs_F77=no + fi + ;; + + sysv5* | sco3.2v5* | sco5v6* | unixware* | OpenUNIX*) + case `$LD -v 2>&1` in + *\ [01].* | *\ 2.[0-9].* | *\ 2.1[0-5].*) + ld_shlibs_F77=no + cat <<_LT_EOF 1>&2 + +*** Warning: Releases of the GNU linker prior to 2.16.91.0.3 can not +*** reliably create shared libraries on SCO systems. Therefore, libtool +*** is disabling shared libraries support. We urge you to upgrade GNU +*** binutils to release 2.16.91.0.3 or newer. Another option is to modify +*** your PATH or compiler configuration so that the native linker is +*** used, and then restart. + +_LT_EOF + ;; + *) + if $LD --help 2>&1 | grep ': supported targets:.* elf' > /dev/null; then + hardcode_libdir_flag_spec_F77='`test -z "$SCOABSPATH" && echo ${wl}-rpath,$libdir`' + archive_cmds_F77='$CC -shared $libobjs $deplibs $compiler_flags ${wl}-soname,\${SCOABSPATH:+${install_libdir}/}$soname -o $lib' + archive_expsym_cmds_F77='$CC -shared $libobjs $deplibs $compiler_flags ${wl}-soname,\${SCOABSPATH:+${install_libdir}/}$soname,-retain-symbols-file,$export_symbols -o $lib' + else + ld_shlibs_F77=no + fi + ;; + esac + ;; + + sunos4*) + archive_cmds_F77='$LD -assert pure-text -Bshareable -o $lib $libobjs $deplibs $linker_flags' + wlarc= + hardcode_direct_F77=yes + hardcode_shlibpath_var_F77=no + ;; + + *) + if $LD --help 2>&1 | grep ': supported targets:.* elf' > /dev/null; then + archive_cmds_F77='$CC -shared $libobjs $deplibs $compiler_flags ${wl}-soname $wl$soname -o $lib' + archive_expsym_cmds_F77='$CC -shared $libobjs $deplibs $compiler_flags ${wl}-soname $wl$soname ${wl}-retain-symbols-file $wl$export_symbols -o $lib' + else + ld_shlibs_F77=no + fi + ;; + esac + + if test "$ld_shlibs_F77" = no; then + runpath_var= + hardcode_libdir_flag_spec_F77= + export_dynamic_flag_spec_F77= + whole_archive_flag_spec_F77= + fi + else + # PORTME fill in a description of your system's linker (not GNU ld) + case $host_os in + aix3*) + allow_undefined_flag_F77=unsupported + always_export_symbols_F77=yes + archive_expsym_cmds_F77='$LD -o $output_objdir/$soname $libobjs $deplibs $linker_flags -bE:$export_symbols -T512 -H512 -bM:SRE~$AR $AR_FLAGS $lib $output_objdir/$soname' + # Note: this linker hardcodes the directories in LIBPATH if there + # are no directories specified by -L. + hardcode_minus_L_F77=yes + if test "$GCC" = yes && test -z "$lt_prog_compiler_static"; then + # Neither direct hardcoding nor static linking is supported with a + # broken collect2. + hardcode_direct_F77=unsupported + fi + ;; + + aix4* | aix5*) + if test "$host_cpu" = ia64; then + # On IA64, the linker does run time linking by default, so we don't + # have to do anything special. + aix_use_runtimelinking=no + exp_sym_flag='-Bexport' + no_entry_flag="" + else + # If we're using GNU nm, then we don't want the "-C" option. + # -C means demangle to AIX nm, but means don't demangle with GNU nm + if $NM -V 2>&1 | grep 'GNU' > /dev/null; then + export_symbols_cmds_F77='$NM -Bpg $libobjs $convenience | awk '\''{ if (((\$2 == "T") || (\$2 == "D") || (\$2 == "B")) && (substr(\$3,1,1) != ".")) { print \$3 } }'\'' | sort -u > $export_symbols' + else + export_symbols_cmds_F77='$NM -BCpg $libobjs $convenience | awk '\''{ if (((\$2 == "T") || (\$2 == "D") || (\$2 == "B")) && (substr(\$3,1,1) != ".")) { print \$3 } }'\'' | sort -u > $export_symbols' + fi + aix_use_runtimelinking=no + + # Test if we are trying to use run time linking or normal + # AIX style linking. If -brtl is somewhere in LDFLAGS, we + # need to do runtime linking. + case $host_os in aix4.[23]|aix4.[23].*|aix5*) + for ld_flag in $LDFLAGS; do + if (test $ld_flag = "-brtl" || test $ld_flag = "-Wl,-brtl"); then + aix_use_runtimelinking=yes + break + fi + done + ;; + esac + + exp_sym_flag='-bexport' + no_entry_flag='-bnoentry' + fi + + # When large executables or shared objects are built, AIX ld can + # have problems creating the table of contents. If linking a library + # or program results in "error TOC overflow" add -mminimal-toc to + # CXXFLAGS/CFLAGS for g++/gcc. In the cases where that is not + # enough to fix the problem, add -Wl,-bbigtoc to LDFLAGS. + + archive_cmds_F77='' + hardcode_direct_F77=yes + hardcode_libdir_separator_F77=':' + link_all_deplibs_F77=yes + + if test "$GCC" = yes; then + case $host_os in aix4.[012]|aix4.[012].*) + # We only want to do this on AIX 4.2 and lower, the check + # below for broken collect2 doesn't work under 4.3+ + collect2name=`${CC} -print-prog-name=collect2` + if test -f "$collect2name" && \ + strings "$collect2name" | grep resolve_lib_name >/dev/null + then + # We have reworked collect2 + hardcode_direct_F77=yes + else + # We have old collect2 + hardcode_direct_F77=unsupported + # It fails to find uninstalled libraries when the uninstalled + # path is not listed in the libpath. Setting hardcode_minus_L + # to unsupported forces relinking + hardcode_minus_L_F77=yes + hardcode_libdir_flag_spec_F77='-L$libdir' + hardcode_libdir_separator_F77= + fi + ;; + esac + shared_flag='-shared' + if test "$aix_use_runtimelinking" = yes; then + shared_flag="$shared_flag "'${wl}-G' + fi + else + # not using gcc + if test "$host_cpu" = ia64; then + # VisualAge C++, Version 5.5 for AIX 5L for IA-64, Beta 3 Release + # chokes on -Wl,-G. The following line is correct: + shared_flag='-G' + else + if test "$aix_use_runtimelinking" = yes; then + shared_flag='${wl}-G' + else + shared_flag='${wl}-bM:SRE' + fi + fi + fi + + # It seems that -bexpall does not export symbols beginning with + # underscore (_), so it is better to generate a list of symbols to export. + always_export_symbols_F77=yes + if test "$aix_use_runtimelinking" = yes; then + # Warning - without using the other runtime loading flags (-brtl), + # -berok will link without error, but may produce a broken library. + allow_undefined_flag_F77='-berok' + # Determine the default libpath from the value encoded in an empty executable. + cat >conftest.$ac_ext <<_ACEOF + program main + + end +_ACEOF +rm -f conftest.$ac_objext conftest$ac_exeext +if { (eval echo "$as_me:$LINENO: \"$ac_link\"") >&5 + (eval $ac_link) 2>conftest.er1 + ac_status=$? + grep -v '^ *+' conftest.er1 >conftest.err + rm -f conftest.er1 + cat conftest.err >&5 + echo "$as_me:$LINENO: \$? = $ac_status" >&5 + (exit $ac_status); } && + { ac_try='test -z "$ac_f77_werror_flag" + || test ! -s conftest.err' + { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5 + (eval $ac_try) 2>&5 + ac_status=$? + echo "$as_me:$LINENO: \$? = $ac_status" >&5 + (exit $ac_status); }; } && + { ac_try='test -s conftest$ac_exeext' + { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5 + (eval $ac_try) 2>&5 + ac_status=$? + echo "$as_me:$LINENO: \$? = $ac_status" >&5 + (exit $ac_status); }; }; then + +aix_libpath=`dump -H conftest$ac_exeext 2>/dev/null | $SED -n -e '/Import File Strings/,/^$/ { /^0/ { s/^0 *\(.*\)$/\1/; p; } +}'` +# Check for a 64-bit object if we didn't find anything. +if test -z "$aix_libpath"; then aix_libpath=`dump -HX64 conftest$ac_exeext 2>/dev/null | $SED -n -e '/Import File Strings/,/^$/ { /^0/ { s/^0 *\(.*\)$/\1/; p; } +}'`; fi +else + echo "$as_me: failed program was:" >&5 +sed 's/^/| /' conftest.$ac_ext >&5 + +fi +rm -f conftest.err conftest.$ac_objext \ + conftest$ac_exeext conftest.$ac_ext +if test -z "$aix_libpath"; then aix_libpath="/usr/lib:/lib"; fi + + hardcode_libdir_flag_spec_F77='${wl}-blibpath:$libdir:'"$aix_libpath" + archive_expsym_cmds_F77="\$CC"' -o $output_objdir/$soname $libobjs $deplibs '"\${wl}$no_entry_flag"' $compiler_flags `if test "x${allow_undefined_flag}" != "x"; then echo "${wl}${allow_undefined_flag}"; else :; fi` '"\${wl}$exp_sym_flag:\$export_symbols $shared_flag" + else + if test "$host_cpu" = ia64; then + hardcode_libdir_flag_spec_F77='${wl}-R $libdir:/usr/lib:/lib' + allow_undefined_flag_F77="-z nodefs" + archive_expsym_cmds_F77="\$CC $shared_flag"' -o $output_objdir/$soname $libobjs $deplibs '"\${wl}$no_entry_flag"' $compiler_flags ${wl}${allow_undefined_flag} '"\${wl}$exp_sym_flag:\$export_symbols" + else + # Determine the default libpath from the value encoded in an empty executable. + cat >conftest.$ac_ext <<_ACEOF + program main + + end +_ACEOF +rm -f conftest.$ac_objext conftest$ac_exeext +if { (eval echo "$as_me:$LINENO: \"$ac_link\"") >&5 + (eval $ac_link) 2>conftest.er1 + ac_status=$? + grep -v '^ *+' conftest.er1 >conftest.err + rm -f conftest.er1 + cat conftest.err >&5 + echo "$as_me:$LINENO: \$? = $ac_status" >&5 + (exit $ac_status); } && + { ac_try='test -z "$ac_f77_werror_flag" + || test ! -s conftest.err' + { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5 + (eval $ac_try) 2>&5 + ac_status=$? + echo "$as_me:$LINENO: \$? = $ac_status" >&5 + (exit $ac_status); }; } && + { ac_try='test -s conftest$ac_exeext' + { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5 + (eval $ac_try) 2>&5 + ac_status=$? + echo "$as_me:$LINENO: \$? = $ac_status" >&5 + (exit $ac_status); }; }; then + +aix_libpath=`dump -H conftest$ac_exeext 2>/dev/null | $SED -n -e '/Import File Strings/,/^$/ { /^0/ { s/^0 *\(.*\)$/\1/; p; } +}'` +# Check for a 64-bit object if we didn't find anything. +if test -z "$aix_libpath"; then aix_libpath=`dump -HX64 conftest$ac_exeext 2>/dev/null | $SED -n -e '/Import File Strings/,/^$/ { /^0/ { s/^0 *\(.*\)$/\1/; p; } +}'`; fi +else + echo "$as_me: failed program was:" >&5 +sed 's/^/| /' conftest.$ac_ext >&5 + +fi +rm -f conftest.err conftest.$ac_objext \ + conftest$ac_exeext conftest.$ac_ext +if test -z "$aix_libpath"; then aix_libpath="/usr/lib:/lib"; fi + + hardcode_libdir_flag_spec_F77='${wl}-blibpath:$libdir:'"$aix_libpath" + # Warning - without using the other run time loading flags, + # -berok will link without error, but may produce a broken library. + no_undefined_flag_F77=' ${wl}-bernotok' + allow_undefined_flag_F77=' ${wl}-berok' + # Exported symbols can be pulled into shared objects from archives + whole_archive_flag_spec_F77='$convenience' + archive_cmds_need_lc_F77=yes + # This is similar to how AIX traditionally builds its shared libraries. + archive_expsym_cmds_F77="\$CC $shared_flag"' -o $output_objdir/$soname $libobjs $deplibs ${wl}-bnoentry $compiler_flags ${wl}-bE:$export_symbols${allow_undefined_flag}~$AR $AR_FLAGS $output_objdir/$libname$release.a $output_objdir/$soname' + fi + fi + ;; + + amigaos*) + archive_cmds_F77='$rm $output_objdir/a2ixlibrary.data~$echo "#define NAME $libname" > $output_objdir/a2ixlibrary.data~$echo "#define LIBRARY_ID 1" >> $output_objdir/a2ixlibrary.data~$echo "#define VERSION $major" >> $output_objdir/a2ixlibrary.data~$echo "#define REVISION $revision" >> $output_objdir/a2ixlibrary.data~$AR $AR_FLAGS $lib $libobjs~$RANLIB $lib~(cd $output_objdir && a2ixlibrary -32)' + hardcode_libdir_flag_spec_F77='-L$libdir' + hardcode_minus_L_F77=yes + # see comment about different semantics on the GNU ld section + ld_shlibs_F77=no + ;; + + bsdi[45]*) + export_dynamic_flag_spec_F77=-rdynamic + ;; + + cygwin* | mingw* | pw32*) + # When not using gcc, we currently assume that we are using + # Microsoft Visual C++. + # hardcode_libdir_flag_spec is actually meaningless, as there is + # no search path for DLLs. + hardcode_libdir_flag_spec_F77=' ' + allow_undefined_flag_F77=unsupported + # Tell ltmain to make .lib files, not .a files. + libext=lib + # Tell ltmain to make .dll files, not .so files. + shrext_cmds=".dll" + # FIXME: Setting linknames here is a bad hack. + archive_cmds_F77='$CC -o $lib $libobjs $compiler_flags `echo "$deplibs" | $SED -e '\''s/ -lc$//'\''` -link -dll~linknames=' + # The linker will automatically build a .lib file if we build a DLL. + old_archive_From_new_cmds_F77='true' + # FIXME: Should let the user specify the lib program. + old_archive_cmds_F77='lib /OUT:$oldlib$oldobjs$old_deplibs' + fix_srcfile_path_F77='`cygpath -w "$srcfile"`' + enable_shared_with_static_runtimes_F77=yes + ;; + + darwin* | rhapsody*) + case $host_os in + rhapsody* | darwin1.[012]) + allow_undefined_flag_F77='${wl}-undefined ${wl}suppress' + ;; + *) # Darwin 1.3 on + if test -z ${MACOSX_DEPLOYMENT_TARGET} ; then + allow_undefined_flag_F77='${wl}-flat_namespace ${wl}-undefined ${wl}suppress' + else + case ${MACOSX_DEPLOYMENT_TARGET} in + 10.[012]) + allow_undefined_flag_F77='${wl}-flat_namespace ${wl}-undefined ${wl}suppress' + ;; + 10.*) + allow_undefined_flag_F77='${wl}-undefined ${wl}dynamic_lookup' + ;; + esac + fi + ;; + esac + archive_cmds_need_lc_F77=no + hardcode_direct_F77=no + hardcode_automatic_F77=yes + hardcode_shlibpath_var_F77=unsupported + whole_archive_flag_spec_F77='' + link_all_deplibs_F77=yes + if test "$GCC" = yes ; then + output_verbose_link_cmd='echo' + archive_cmds_F77='$CC -dynamiclib $allow_undefined_flag -o $lib $libobjs $deplibs $compiler_flags -install_name $rpath/$soname $verstring' + module_cmds_F77='$CC $allow_undefined_flag -o $lib -bundle $libobjs $deplibs$compiler_flags' + # Don't fix this by using the ld -exported_symbols_list flag, it doesn't exist in older darwin lds + archive_expsym_cmds_F77='sed -e "s,#.*,," -e "s,^[ ]*,," -e "s,^\(..*\),_&," < $export_symbols > $output_objdir/${libname}-symbols.expsym~$CC -dynamiclib $allow_undefined_flag -o $lib $libobjs $deplibs $compiler_flags -install_name $rpath/$soname $verstring~nmedit -s $output_objdir/${libname}-symbols.expsym ${lib}' + module_expsym_cmds_F77='sed -e "s,#.*,," -e "s,^[ ]*,," -e "s,^\(..*\),_&," < $export_symbols > $output_objdir/${libname}-symbols.expsym~$CC $allow_undefined_flag -o $lib -bundle $libobjs $deplibs$compiler_flags~nmedit -s $output_objdir/${libname}-symbols.expsym ${lib}' + else + case $cc_basename in + xlc*) + output_verbose_link_cmd='echo' + archive_cmds_F77='$CC -qmkshrobj $allow_undefined_flag -o $lib $libobjs $deplibs $compiler_flags ${wl}-install_name ${wl}`echo $rpath/$soname` $verstring' + module_cmds_F77='$CC $allow_undefined_flag -o $lib -bundle $libobjs $deplibs$compiler_flags' + # Don't fix this by using the ld -exported_symbols_list flag, it doesn't exist in older darwin lds + archive_expsym_cmds_F77='sed -e "s,#.*,," -e "s,^[ ]*,," -e "s,^\(..*\),_&," < $export_symbols > $output_objdir/${libname}-symbols.expsym~$CC -qmkshrobj $allow_undefined_flag -o $lib $libobjs $deplibs $compiler_flags ${wl}-install_name ${wl}$rpath/$soname $verstring~nmedit -s $output_objdir/${libname}-symbols.expsym ${lib}' + module_expsym_cmds_F77='sed -e "s,#.*,," -e "s,^[ ]*,," -e "s,^\(..*\),_&," < $export_symbols > $output_objdir/${libname}-symbols.expsym~$CC $allow_undefined_flag -o $lib -bundle $libobjs $deplibs$compiler_flags~nmedit -s $output_objdir/${libname}-symbols.expsym ${lib}' + ;; + *) + ld_shlibs_F77=no + ;; + esac + fi + ;; + + dgux*) + archive_cmds_F77='$LD -G -h $soname -o $lib $libobjs $deplibs $linker_flags' + hardcode_libdir_flag_spec_F77='-L$libdir' + hardcode_shlibpath_var_F77=no + ;; + + freebsd1*) + ld_shlibs_F77=no + ;; + + # FreeBSD 2.2.[012] allows us to include c++rt0.o to get C++ constructor + # support. Future versions do this automatically, but an explicit c++rt0.o + # does not break anything, and helps significantly (at the cost of a little + # extra space). + freebsd2.2*) + archive_cmds_F77='$LD -Bshareable -o $lib $libobjs $deplibs $linker_flags /usr/lib/c++rt0.o' + hardcode_libdir_flag_spec_F77='-R$libdir' + hardcode_direct_F77=yes + hardcode_shlibpath_var_F77=no + ;; + + # Unfortunately, older versions of FreeBSD 2 do not have this feature. + freebsd2*) + archive_cmds_F77='$LD -Bshareable -o $lib $libobjs $deplibs $linker_flags' + hardcode_direct_F77=yes + hardcode_minus_L_F77=yes + hardcode_shlibpath_var_F77=no + ;; + + # FreeBSD 3 and greater uses gcc -shared to do shared libraries. + freebsd* | kfreebsd*-gnu | dragonfly*) + archive_cmds_F77='$CC -shared -o $lib $libobjs $deplibs $compiler_flags' + hardcode_libdir_flag_spec_F77='-R$libdir' + hardcode_direct_F77=yes + hardcode_shlibpath_var_F77=no + ;; + + hpux9*) + if test "$GCC" = yes; then + archive_cmds_F77='$rm $output_objdir/$soname~$CC -shared -fPIC ${wl}+b ${wl}$install_libdir -o $output_objdir/$soname $libobjs $deplibs $compiler_flags~test $output_objdir/$soname = $lib || mv $output_objdir/$soname $lib' + else + archive_cmds_F77='$rm $output_objdir/$soname~$LD -b +b $install_libdir -o $output_objdir/$soname $libobjs $deplibs $linker_flags~test $output_objdir/$soname = $lib || mv $output_objdir/$soname $lib' + fi + hardcode_libdir_flag_spec_F77='${wl}+b ${wl}$libdir' + hardcode_libdir_separator_F77=: + hardcode_direct_F77=yes + + # hardcode_minus_L: Not really in the search PATH, + # but as the default location of the library. + hardcode_minus_L_F77=yes + export_dynamic_flag_spec_F77='${wl}-E' + ;; + + hpux10*) + if test "$GCC" = yes -a "$with_gnu_ld" = no; then + archive_cmds_F77='$CC -shared -fPIC ${wl}+h ${wl}$soname ${wl}+b ${wl}$install_libdir -o $lib $libobjs $deplibs $compiler_flags' + else + archive_cmds_F77='$LD -b +h $soname +b $install_libdir -o $lib $libobjs $deplibs $linker_flags' + fi + if test "$with_gnu_ld" = no; then + hardcode_libdir_flag_spec_F77='${wl}+b ${wl}$libdir' + hardcode_libdir_separator_F77=: + + hardcode_direct_F77=yes + export_dynamic_flag_spec_F77='${wl}-E' + + # hardcode_minus_L: Not really in the search PATH, + # but as the default location of the library. + hardcode_minus_L_F77=yes + fi + ;; + + hpux11*) + if test "$GCC" = yes -a "$with_gnu_ld" = no; then + case $host_cpu in + hppa*64*) + archive_cmds_F77='$CC -shared ${wl}+h ${wl}$soname -o $lib $libobjs $deplibs $compiler_flags' + ;; + ia64*) + archive_cmds_F77='$CC -shared ${wl}+h ${wl}$soname ${wl}+nodefaultrpath -o $lib $libobjs $deplibs $compiler_flags' + ;; + *) + archive_cmds_F77='$CC -shared -fPIC ${wl}+h ${wl}$soname ${wl}+b ${wl}$install_libdir -o $lib $libobjs $deplibs $compiler_flags' + ;; + esac + else + case $host_cpu in + hppa*64*) + archive_cmds_F77='$CC -b ${wl}+h ${wl}$soname -o $lib $libobjs $deplibs $compiler_flags' + ;; + ia64*) + archive_cmds_F77='$CC -b ${wl}+h ${wl}$soname ${wl}+nodefaultrpath -o $lib $libobjs $deplibs $compiler_flags' + ;; + *) + archive_cmds_F77='$CC -b ${wl}+h ${wl}$soname ${wl}+b ${wl}$install_libdir -o $lib $libobjs $deplibs $compiler_flags' + ;; + esac + fi + if test "$with_gnu_ld" = no; then + hardcode_libdir_flag_spec_F77='${wl}+b ${wl}$libdir' + hardcode_libdir_separator_F77=: + + case $host_cpu in + hppa*64*|ia64*) + hardcode_libdir_flag_spec_ld_F77='+b $libdir' + hardcode_direct_F77=no + hardcode_shlibpath_var_F77=no + ;; + *) + hardcode_direct_F77=yes + export_dynamic_flag_spec_F77='${wl}-E' + + # hardcode_minus_L: Not really in the search PATH, + # but as the default location of the library. + hardcode_minus_L_F77=yes + ;; + esac + fi + ;; + + irix5* | irix6* | nonstopux*) + if test "$GCC" = yes; then + archive_cmds_F77='$CC -shared $libobjs $deplibs $compiler_flags ${wl}-soname ${wl}$soname `test -n "$verstring" && echo ${wl}-set_version ${wl}$verstring` ${wl}-update_registry ${wl}${output_objdir}/so_locations -o $lib' + else + archive_cmds_F77='$LD -shared $libobjs $deplibs $linker_flags -soname $soname `test -n "$verstring" && echo -set_version $verstring` -update_registry ${output_objdir}/so_locations -o $lib' + hardcode_libdir_flag_spec_ld_F77='-rpath $libdir' + fi + hardcode_libdir_flag_spec_F77='${wl}-rpath ${wl}$libdir' + hardcode_libdir_separator_F77=: + link_all_deplibs_F77=yes + ;; + + netbsd*) + if echo __ELF__ | $CC -E - | grep __ELF__ >/dev/null; then + archive_cmds_F77='$LD -Bshareable -o $lib $libobjs $deplibs $linker_flags' # a.out + else + archive_cmds_F77='$LD -shared -o $lib $libobjs $deplibs $linker_flags' # ELF + fi + hardcode_libdir_flag_spec_F77='-R$libdir' + hardcode_direct_F77=yes + hardcode_shlibpath_var_F77=no + ;; + + newsos6) + archive_cmds_F77='$LD -G -h $soname -o $lib $libobjs $deplibs $linker_flags' + hardcode_direct_F77=yes + hardcode_libdir_flag_spec_F77='${wl}-rpath ${wl}$libdir' + hardcode_libdir_separator_F77=: + hardcode_shlibpath_var_F77=no + ;; + + openbsd*) + hardcode_direct_F77=yes + hardcode_shlibpath_var_F77=no + if test -z "`echo __ELF__ | $CC -E - | grep __ELF__`" || test "$host_os-$host_cpu" = "openbsd2.8-powerpc"; then + archive_cmds_F77='$CC -shared $pic_flag -o $lib $libobjs $deplibs $compiler_flags' + archive_expsym_cmds_F77='$CC -shared $pic_flag -o $lib $libobjs $deplibs $compiler_flags ${wl}-retain-symbols-file,$export_symbols' + hardcode_libdir_flag_spec_F77='${wl}-rpath,$libdir' + export_dynamic_flag_spec_F77='${wl}-E' + else + case $host_os in + openbsd[01].* | openbsd2.[0-7] | openbsd2.[0-7].*) + archive_cmds_F77='$LD -Bshareable -o $lib $libobjs $deplibs $linker_flags' + hardcode_libdir_flag_spec_F77='-R$libdir' + ;; + *) + archive_cmds_F77='$CC -shared $pic_flag -o $lib $libobjs $deplibs $compiler_flags' + hardcode_libdir_flag_spec_F77='${wl}-rpath,$libdir' + ;; + esac + fi + ;; + + os2*) + hardcode_libdir_flag_spec_F77='-L$libdir' + hardcode_minus_L_F77=yes + allow_undefined_flag_F77=unsupported + archive_cmds_F77='$echo "LIBRARY $libname INITINSTANCE" > $output_objdir/$libname.def~$echo "DESCRIPTION \"$libname\"" >> $output_objdir/$libname.def~$echo DATA >> $output_objdir/$libname.def~$echo " SINGLE NONSHARED" >> $output_objdir/$libname.def~$echo EXPORTS >> $output_objdir/$libname.def~emxexp $libobjs >> $output_objdir/$libname.def~$CC -Zdll -Zcrtdll -o $lib $libobjs $deplibs $compiler_flags $output_objdir/$libname.def' + old_archive_From_new_cmds_F77='emximp -o $output_objdir/$libname.a $output_objdir/$libname.def' + ;; + + osf3*) + if test "$GCC" = yes; then + allow_undefined_flag_F77=' ${wl}-expect_unresolved ${wl}\*' + archive_cmds_F77='$CC -shared${allow_undefined_flag} $libobjs $deplibs $compiler_flags ${wl}-soname ${wl}$soname `test -n "$verstring" && echo ${wl}-set_version ${wl}$verstring` ${wl}-update_registry ${wl}${output_objdir}/so_locations -o $lib' + else + allow_undefined_flag_F77=' -expect_unresolved \*' + archive_cmds_F77='$LD -shared${allow_undefined_flag} $libobjs $deplibs $linker_flags -soname $soname `test -n "$verstring" && echo -set_version $verstring` -update_registry ${output_objdir}/so_locations -o $lib' + fi + hardcode_libdir_flag_spec_F77='${wl}-rpath ${wl}$libdir' + hardcode_libdir_separator_F77=: + ;; + + osf4* | osf5*) # as osf3* with the addition of -msym flag + if test "$GCC" = yes; then + allow_undefined_flag_F77=' ${wl}-expect_unresolved ${wl}\*' + archive_cmds_F77='$CC -shared${allow_undefined_flag} $libobjs $deplibs $compiler_flags ${wl}-msym ${wl}-soname ${wl}$soname `test -n "$verstring" && echo ${wl}-set_version ${wl}$verstring` ${wl}-update_registry ${wl}${output_objdir}/so_locations -o $lib' + hardcode_libdir_flag_spec_F77='${wl}-rpath ${wl}$libdir' + else + allow_undefined_flag_F77=' -expect_unresolved \*' + archive_cmds_F77='$LD -shared${allow_undefined_flag} $libobjs $deplibs $linker_flags -msym -soname $soname `test -n "$verstring" && echo -set_version $verstring` -update_registry ${output_objdir}/so_locations -o $lib' + archive_expsym_cmds_F77='for i in `cat $export_symbols`; do printf "%s %s\\n" -exported_symbol "\$i" >> $lib.exp; done; echo "-hidden">> $lib.exp~ + $LD -shared${allow_undefined_flag} -input $lib.exp $linker_flags $libobjs $deplibs -soname $soname `test -n "$verstring" && echo -set_version $verstring` -update_registry ${output_objdir}/so_locations -o $lib~$rm $lib.exp' + + # Both c and cxx compiler support -rpath directly + hardcode_libdir_flag_spec_F77='-rpath $libdir' + fi + hardcode_libdir_separator_F77=: + ;; + + solaris*) + no_undefined_flag_F77=' -z text' + if test "$GCC" = yes; then + wlarc='${wl}' + archive_cmds_F77='$CC -shared ${wl}-h ${wl}$soname -o $lib $libobjs $deplibs $compiler_flags' + archive_expsym_cmds_F77='$echo "{ global:" > $lib.exp~cat $export_symbols | $SED -e "s/\(.*\)/\1;/" >> $lib.exp~$echo "local: *; };" >> $lib.exp~ + $CC -shared ${wl}-M ${wl}$lib.exp ${wl}-h ${wl}$soname -o $lib $libobjs $deplibs $compiler_flags~$rm $lib.exp' + else + wlarc='' + archive_cmds_F77='$LD -G${allow_undefined_flag} -h $soname -o $lib $libobjs $deplibs $linker_flags' + archive_expsym_cmds_F77='$echo "{ global:" > $lib.exp~cat $export_symbols | $SED -e "s/\(.*\)/\1;/" >> $lib.exp~$echo "local: *; };" >> $lib.exp~ + $LD -G${allow_undefined_flag} -M $lib.exp -h $soname -o $lib $libobjs $deplibs $linker_flags~$rm $lib.exp' + fi + hardcode_libdir_flag_spec_F77='-R$libdir' + hardcode_shlibpath_var_F77=no + case $host_os in + solaris2.[0-5] | solaris2.[0-5].*) ;; + *) + # The compiler driver will combine linker options so we + # cannot just pass the convience library names through + # without $wl, iff we do not link with $LD. + # Luckily, gcc supports the same syntax we need for Sun Studio. + # Supported since Solaris 2.6 (maybe 2.5.1?) + case $wlarc in + '') + whole_archive_flag_spec_F77='-z allextract$convenience -z defaultextract' ;; + *) + whole_archive_flag_spec_F77='${wl}-z ${wl}allextract`for conv in $convenience\"\"; do test -n \"$conv\" && new_convenience=\"$new_convenience,$conv\"; done; $echo \"$new_convenience\"` ${wl}-z ${wl}defaultextract' ;; + esac ;; + esac + link_all_deplibs_F77=yes + ;; + + sunos4*) + if test "x$host_vendor" = xsequent; then + # Use $CC to link under sequent, because it throws in some extra .o + # files that make .init and .fini sections work. + archive_cmds_F77='$CC -G ${wl}-h $soname -o $lib $libobjs $deplibs $compiler_flags' + else + archive_cmds_F77='$LD -assert pure-text -Bstatic -o $lib $libobjs $deplibs $linker_flags' + fi + hardcode_libdir_flag_spec_F77='-L$libdir' + hardcode_direct_F77=yes + hardcode_minus_L_F77=yes + hardcode_shlibpath_var_F77=no + ;; + + sysv4) + case $host_vendor in + sni) + archive_cmds_F77='$LD -G -h $soname -o $lib $libobjs $deplibs $linker_flags' + hardcode_direct_F77=yes # is this really true??? + ;; + siemens) + ## LD is ld it makes a PLAMLIB + ## CC just makes a GrossModule. + archive_cmds_F77='$LD -G -o $lib $libobjs $deplibs $linker_flags' + reload_cmds_F77='$CC -r -o $output$reload_objs' + hardcode_direct_F77=no + ;; + motorola) + archive_cmds_F77='$LD -G -h $soname -o $lib $libobjs $deplibs $linker_flags' + hardcode_direct_F77=no #Motorola manual says yes, but my tests say they lie + ;; + esac + runpath_var='LD_RUN_PATH' + hardcode_shlibpath_var_F77=no + ;; + + sysv4.3*) + archive_cmds_F77='$LD -G -h $soname -o $lib $libobjs $deplibs $linker_flags' + hardcode_shlibpath_var_F77=no + export_dynamic_flag_spec_F77='-Bexport' + ;; + + sysv4*MP*) + if test -d /usr/nec; then + archive_cmds_F77='$LD -G -h $soname -o $lib $libobjs $deplibs $linker_flags' + hardcode_shlibpath_var_F77=no + runpath_var=LD_RUN_PATH + hardcode_runpath_var=yes + ld_shlibs_F77=yes + fi + ;; + + sysv4*uw2* | sysv5OpenUNIX* | sysv5UnixWare7.[01].[10]* | unixware7*) + no_undefined_flag_F77='${wl}-z,text' + archive_cmds_need_lc_F77=no + hardcode_shlibpath_var_F77=no + runpath_var='LD_RUN_PATH' + + if test "$GCC" = yes; then + archive_cmds_F77='$CC -shared ${wl}-h,$soname -o $lib $libobjs $deplibs $compiler_flags' + archive_expsym_cmds_F77='$CC -shared ${wl}-Bexport:$export_symbols ${wl}-h,$soname -o $lib $libobjs $deplibs $compiler_flags' + else + archive_cmds_F77='$CC -G ${wl}-h,$soname -o $lib $libobjs $deplibs $compiler_flags' + archive_expsym_cmds_F77='$CC -G ${wl}-Bexport:$export_symbols ${wl}-h,$soname -o $lib $libobjs $deplibs $compiler_flags' + fi + ;; + + sysv5* | sco3.2v5* | sco5v6*) + # Note: We can NOT use -z defs as we might desire, because we do not + # link with -lc, and that would cause any symbols used from libc to + # always be unresolved, which means just about no library would + # ever link correctly. If we're not using GNU ld we use -z text + # though, which does catch some bad symbols but isn't as heavy-handed + # as -z defs. + no_undefined_flag_F77='${wl}-z,text' + allow_undefined_flag_F77='${wl}-z,nodefs' + archive_cmds_need_lc_F77=no + hardcode_shlibpath_var_F77=no + hardcode_libdir_flag_spec_F77='`test -z "$SCOABSPATH" && echo ${wl}-R,$libdir`' + hardcode_libdir_separator_F77=':' + link_all_deplibs_F77=yes + export_dynamic_flag_spec_F77='${wl}-Bexport' + runpath_var='LD_RUN_PATH' + + if test "$GCC" = yes; then + archive_cmds_F77='$CC -shared ${wl}-h,\${SCOABSPATH:+${install_libdir}/}$soname -o $lib $libobjs $deplibs $compiler_flags' + archive_expsym_cmds_F77='$CC -shared ${wl}-Bexport:$export_symbols ${wl}-h,\${SCOABSPATH:+${install_libdir}/}$soname -o $lib $libobjs $deplibs $compiler_flags' + else + archive_cmds_F77='$CC -G ${wl}-h,\${SCOABSPATH:+${install_libdir}/}$soname -o $lib $libobjs $deplibs $compiler_flags' + archive_expsym_cmds_F77='$CC -G ${wl}-Bexport:$export_symbols ${wl}-h,\${SCOABSPATH:+${install_libdir}/}$soname -o $lib $libobjs $deplibs $compiler_flags' + fi + ;; + + uts4*) + archive_cmds_F77='$LD -G -h $soname -o $lib $libobjs $deplibs $linker_flags' + hardcode_libdir_flag_spec_F77='-L$libdir' + hardcode_shlibpath_var_F77=no + ;; + + *) + ld_shlibs_F77=no + ;; + esac + fi + +echo "$as_me:$LINENO: result: $ld_shlibs_F77" >&5 +echo "${ECHO_T}$ld_shlibs_F77" >&6 +test "$ld_shlibs_F77" = no && can_build_shared=no + +# +# Do we need to explicitly link libc? +# +case "x$archive_cmds_need_lc_F77" in +x|xyes) + # Assume -lc should be added + archive_cmds_need_lc_F77=yes + + if test "$enable_shared" = yes && test "$GCC" = yes; then + case $archive_cmds_F77 in + *'~'*) + # FIXME: we may have to deal with multi-command sequences. + ;; + '$CC '*) + # Test whether the compiler implicitly links with -lc since on some + # systems, -lgcc has to come before -lc. If gcc already passes -lc + # to ld, don't add -lc before -lgcc. + echo "$as_me:$LINENO: checking whether -lc should be explicitly linked in" >&5 +echo $ECHO_N "checking whether -lc should be explicitly linked in... $ECHO_C" >&6 + $rm conftest* + printf "$lt_simple_compile_test_code" > conftest.$ac_ext + + if { (eval echo "$as_me:$LINENO: \"$ac_compile\"") >&5 + (eval $ac_compile) 2>&5 + ac_status=$? + echo "$as_me:$LINENO: \$? = $ac_status" >&5 + (exit $ac_status); } 2>conftest.err; then + soname=conftest + lib=conftest + libobjs=conftest.$ac_objext + deplibs= + wl=$lt_prog_compiler_wl_F77 + pic_flag=$lt_prog_compiler_pic_F77 + compiler_flags=-v + linker_flags=-v + verstring= + output_objdir=. + libname=conftest + lt_save_allow_undefined_flag=$allow_undefined_flag_F77 + allow_undefined_flag_F77= + if { (eval echo "$as_me:$LINENO: \"$archive_cmds_F77 2\>\&1 \| grep \" -lc \" \>/dev/null 2\>\&1\"") >&5 + (eval $archive_cmds_F77 2\>\&1 \| grep \" -lc \" \>/dev/null 2\>\&1) 2>&5 + ac_status=$? + echo "$as_me:$LINENO: \$? = $ac_status" >&5 + (exit $ac_status); } + then + archive_cmds_need_lc_F77=no + else + archive_cmds_need_lc_F77=yes + fi + allow_undefined_flag_F77=$lt_save_allow_undefined_flag + else + cat conftest.err 1>&5 + fi + $rm conftest* + echo "$as_me:$LINENO: result: $archive_cmds_need_lc_F77" >&5 +echo "${ECHO_T}$archive_cmds_need_lc_F77" >&6 + ;; + esac + fi + ;; +esac + +echo "$as_me:$LINENO: checking dynamic linker characteristics" >&5 +echo $ECHO_N "checking dynamic linker characteristics... $ECHO_C" >&6 +library_names_spec= +libname_spec='lib$name' +soname_spec= +shrext_cmds=".so" +postinstall_cmds= +postuninstall_cmds= +finish_cmds= +finish_eval= +shlibpath_var= +shlibpath_overrides_runpath=unknown +version_type=none +dynamic_linker="$host_os ld.so" +sys_lib_dlsearch_path_spec="/lib /usr/lib" +if test "$GCC" = yes; then + sys_lib_search_path_spec=`$CC -print-search-dirs | grep "^libraries:" | $SED -e "s/^libraries://" -e "s,=/,/,g"` + if echo "$sys_lib_search_path_spec" | grep ';' >/dev/null ; then + # if the path contains ";" then we assume it to be the separator + # otherwise default to the standard path separator (i.e. ":") - it is + # assumed that no part of a normal pathname contains ";" but that should + # okay in the real world where ";" in dirpaths is itself problematic. + sys_lib_search_path_spec=`echo "$sys_lib_search_path_spec" | $SED -e 's/;/ /g'` + else + sys_lib_search_path_spec=`echo "$sys_lib_search_path_spec" | $SED -e "s/$PATH_SEPARATOR/ /g"` + fi +else + sys_lib_search_path_spec="/lib /usr/lib /usr/local/lib" +fi +need_lib_prefix=unknown +hardcode_into_libs=no + +# when you set need_version to no, make sure it does not cause -set_version +# flags to be left without arguments +need_version=unknown + +case $host_os in +aix3*) + version_type=linux + library_names_spec='${libname}${release}${shared_ext}$versuffix $libname.a' + shlibpath_var=LIBPATH + + # AIX 3 has no versioning support, so we append a major version to the name. + soname_spec='${libname}${release}${shared_ext}$major' + ;; + +aix4* | aix5*) + version_type=linux + need_lib_prefix=no + need_version=no + hardcode_into_libs=yes + if test "$host_cpu" = ia64; then + # AIX 5 supports IA64 + library_names_spec='${libname}${release}${shared_ext}$major ${libname}${release}${shared_ext}$versuffix $libname${shared_ext}' + shlibpath_var=LD_LIBRARY_PATH + else + # With GCC up to 2.95.x, collect2 would create an import file + # for dependence libraries. The import file would start with + # the line `#! .'. This would cause the generated library to + # depend on `.', always an invalid library. This was fixed in + # development snapshots of GCC prior to 3.0. + case $host_os in + aix4 | aix4.[01] | aix4.[01].*) + if { echo '#if __GNUC__ > 2 || (__GNUC__ == 2 && __GNUC_MINOR__ >= 97)' + echo ' yes ' + echo '#endif'; } | ${CC} -E - | grep yes > /dev/null; then + : + else + can_build_shared=no + fi + ;; + esac + # AIX (on Power*) has no versioning support, so currently we can not hardcode correct + # soname into executable. Probably we can add versioning support to + # collect2, so additional links can be useful in future. + if test "$aix_use_runtimelinking" = yes; then + # If using run time linking (on AIX 4.2 or later) use lib<name>.so + # instead of lib<name>.a to let people know that these are not + # typical AIX shared libraries. + library_names_spec='${libname}${release}${shared_ext}$versuffix ${libname}${release}${shared_ext}$major $libname${shared_ext}' + else + # We preserve .a as extension for shared libraries through AIX4.2 + # and later when we are not doing run time linking. + library_names_spec='${libname}${release}.a $libname.a' + soname_spec='${libname}${release}${shared_ext}$major' + fi + shlibpath_var=LIBPATH + fi + ;; + +amigaos*) + library_names_spec='$libname.ixlibrary $libname.a' + # Create ${libname}_ixlibrary.a entries in /sys/libs. + finish_eval='for lib in `ls $libdir/*.ixlibrary 2>/dev/null`; do libname=`$echo "X$lib" | $Xsed -e '\''s%^.*/\([^/]*\)\.ixlibrary$%\1%'\''`; test $rm /sys/libs/${libname}_ixlibrary.a; $show "cd /sys/libs && $LN_S $lib ${libname}_ixlibrary.a"; cd /sys/libs && $LN_S $lib ${libname}_ixlibrary.a || exit 1; done' + ;; + +beos*) + library_names_spec='${libname}${shared_ext}' + dynamic_linker="$host_os ld.so" + shlibpath_var=LIBRARY_PATH + ;; + +bsdi[45]*) + version_type=linux + need_version=no + library_names_spec='${libname}${release}${shared_ext}$versuffix ${libname}${release}${shared_ext}$major $libname${shared_ext}' + soname_spec='${libname}${release}${shared_ext}$major' + finish_cmds='PATH="\$PATH:/sbin" ldconfig $libdir' + shlibpath_var=LD_LIBRARY_PATH + sys_lib_search_path_spec="/shlib /usr/lib /usr/X11/lib /usr/contrib/lib /lib /usr/local/lib" + sys_lib_dlsearch_path_spec="/shlib /usr/lib /usr/local/lib" + # the default ld.so.conf also contains /usr/contrib/lib and + # /usr/X11R6/lib (/usr/X11 is a link to /usr/X11R6), but let us allow + # libtool to hard-code these into programs + ;; + +cygwin* | mingw* | pw32*) + version_type=windows + shrext_cmds=".dll" + need_version=no + need_lib_prefix=no + + case $GCC,$host_os in + yes,cygwin* | yes,mingw* | yes,pw32*) + library_names_spec='$libname.dll.a' + # DLL is installed to $(libdir)/../bin by postinstall_cmds + postinstall_cmds='base_file=`basename \${file}`~ + dlpath=`$SHELL 2>&1 -c '\''. $dir/'\''\${base_file}'\''i;echo \$dlname'\''`~ + dldir=$destdir/`dirname \$dlpath`~ + test -d \$dldir || mkdir -p \$dldir~ + $install_prog $dir/$dlname \$dldir/$dlname~ + chmod a+x \$dldir/$dlname' + postuninstall_cmds='dldll=`$SHELL 2>&1 -c '\''. $file; echo \$dlname'\''`~ + dlpath=$dir/\$dldll~ + $rm \$dlpath' + shlibpath_overrides_runpath=yes + + case $host_os in + cygwin*) + # Cygwin DLLs use 'cyg' prefix rather than 'lib' + soname_spec='`echo ${libname} | sed -e 's/^lib/cyg/'``echo ${release} | $SED -e 's/[.]/-/g'`${versuffix}${shared_ext}' + sys_lib_search_path_spec="/usr/lib /lib/w32api /lib /usr/local/lib" + ;; + mingw*) + # MinGW DLLs use traditional 'lib' prefix + soname_spec='${libname}`echo ${release} | $SED -e 's/[.]/-/g'`${versuffix}${shared_ext}' + sys_lib_search_path_spec=`$CC -print-search-dirs | grep "^libraries:" | $SED -e "s/^libraries://" -e "s,=/,/,g"` + if echo "$sys_lib_search_path_spec" | grep ';[c-zC-Z]:/' >/dev/null; then + # It is most probably a Windows format PATH printed by + # mingw gcc, but we are running on Cygwin. Gcc prints its search + # path with ; separators, and with drive letters. We can handle the + # drive letters (cygwin fileutils understands them), so leave them, + # especially as we might pass files found there to a mingw objdump, + # which wouldn't understand a cygwinified path. Ahh. + sys_lib_search_path_spec=`echo "$sys_lib_search_path_spec" | $SED -e 's/;/ /g'` + else + sys_lib_search_path_spec=`echo "$sys_lib_search_path_spec" | $SED -e "s/$PATH_SEPARATOR/ /g"` + fi + ;; + pw32*) + # pw32 DLLs use 'pw' prefix rather than 'lib' + library_names_spec='`echo ${libname} | sed -e 's/^lib/pw/'``echo ${release} | $SED -e 's/[.]/-/g'`${versuffix}${shared_ext}' + ;; + esac + ;; + + *) + library_names_spec='${libname}`echo ${release} | $SED -e 's/[.]/-/g'`${versuffix}${shared_ext} $libname.lib' + ;; + esac + dynamic_linker='Win32 ld.exe' + # FIXME: first we should search . and the directory the executable is in + shlibpath_var=PATH + ;; + +darwin* | rhapsody*) + dynamic_linker="$host_os dyld" + version_type=darwin + need_lib_prefix=no + need_version=no + library_names_spec='${libname}${release}${versuffix}$shared_ext ${libname}${release}${major}$shared_ext ${libname}$shared_ext' + soname_spec='${libname}${release}${major}$shared_ext' + shlibpath_overrides_runpath=yes + shlibpath_var=DYLD_LIBRARY_PATH + shrext_cmds='`test .$module = .yes && echo .so || echo .dylib`' + # Apple's gcc prints 'gcc -print-search-dirs' doesn't operate the same. + if test "$GCC" = yes; then + sys_lib_search_path_spec=`$CC -print-search-dirs | tr "\n" "$PATH_SEPARATOR" | sed -e 's/libraries:/@libraries:/' | tr "@" "\n" | grep "^libraries:" | sed -e "s/^libraries://" -e "s,=/,/,g" -e "s,$PATH_SEPARATOR, ,g" -e "s,.*,& /lib /usr/lib /usr/local/lib,g"` + else + sys_lib_search_path_spec='/lib /usr/lib /usr/local/lib' + fi + sys_lib_dlsearch_path_spec='/usr/local/lib /lib /usr/lib' + ;; + +dgux*) + version_type=linux + need_lib_prefix=no + need_version=no + library_names_spec='${libname}${release}${shared_ext}$versuffix ${libname}${release}${shared_ext}$major $libname$shared_ext' + soname_spec='${libname}${release}${shared_ext}$major' + shlibpath_var=LD_LIBRARY_PATH + ;; + +freebsd1*) + dynamic_linker=no + ;; + +kfreebsd*-gnu) + version_type=linux + need_lib_prefix=no + need_version=no + library_names_spec='${libname}${release}${shared_ext}$versuffix ${libname}${release}${shared_ext}$major ${libname}${shared_ext}' + soname_spec='${libname}${release}${shared_ext}$major' + shlibpath_var=LD_LIBRARY_PATH + shlibpath_overrides_runpath=no + hardcode_into_libs=yes + dynamic_linker='GNU ld.so' + ;; + +freebsd* | dragonfly*) + # DragonFly does not have aout. When/if they implement a new + # versioning mechanism, adjust this. + if test -x /usr/bin/objformat; then + objformat=`/usr/bin/objformat` + else + case $host_os in + freebsd[123]*) objformat=aout ;; + *) objformat=elf ;; + esac + fi + version_type=freebsd-$objformat + case $version_type in + freebsd-elf*) + library_names_spec='${libname}${release}${shared_ext}$versuffix ${libname}${release}${shared_ext} $libname${shared_ext}' + need_version=no + need_lib_prefix=no + ;; + freebsd-*) + library_names_spec='${libname}${release}${shared_ext}$versuffix $libname${shared_ext}$versuffix' + need_version=yes + ;; + esac + shlibpath_var=LD_LIBRARY_PATH + case $host_os in + freebsd2*) + shlibpath_overrides_runpath=yes + ;; + freebsd3.[01]* | freebsdelf3.[01]*) + shlibpath_overrides_runpath=yes + hardcode_into_libs=yes + ;; + freebsd3.[2-9]* | freebsdelf3.[2-9]* | \ + freebsd4.[0-5] | freebsdelf4.[0-5] | freebsd4.1.1 | freebsdelf4.1.1) + shlibpath_overrides_runpath=no + hardcode_into_libs=yes + ;; + freebsd*) # from 4.6 on + shlibpath_overrides_runpath=yes + hardcode_into_libs=yes + ;; + esac + ;; + +gnu*) + version_type=linux + need_lib_prefix=no + need_version=no + library_names_spec='${libname}${release}${shared_ext}$versuffix ${libname}${release}${shared_ext}${major} ${libname}${shared_ext}' + soname_spec='${libname}${release}${shared_ext}$major' + shlibpath_var=LD_LIBRARY_PATH + hardcode_into_libs=yes + ;; + +hpux9* | hpux10* | hpux11*) + # Give a soname corresponding to the major version so that dld.sl refuses to + # link against other versions. + version_type=sunos + need_lib_prefix=no + need_version=no + case $host_cpu in + ia64*) + shrext_cmds='.so' + hardcode_into_libs=yes + dynamic_linker="$host_os dld.so" + shlibpath_var=LD_LIBRARY_PATH + shlibpath_overrides_runpath=yes # Unless +noenvvar is specified. + library_names_spec='${libname}${release}${shared_ext}$versuffix ${libname}${release}${shared_ext}$major $libname${shared_ext}' + soname_spec='${libname}${release}${shared_ext}$major' + if test "X$HPUX_IA64_MODE" = X32; then + sys_lib_search_path_spec="/usr/lib/hpux32 /usr/local/lib/hpux32 /usr/local/lib" + else + sys_lib_search_path_spec="/usr/lib/hpux64 /usr/local/lib/hpux64" + fi + sys_lib_dlsearch_path_spec=$sys_lib_search_path_spec + ;; + hppa*64*) + shrext_cmds='.sl' + hardcode_into_libs=yes + dynamic_linker="$host_os dld.sl" + shlibpath_var=LD_LIBRARY_PATH # How should we handle SHLIB_PATH + shlibpath_overrides_runpath=yes # Unless +noenvvar is specified. + library_names_spec='${libname}${release}${shared_ext}$versuffix ${libname}${release}${shared_ext}$major $libname${shared_ext}' + soname_spec='${libname}${release}${shared_ext}$major' + sys_lib_search_path_spec="/usr/lib/pa20_64 /usr/ccs/lib/pa20_64" + sys_lib_dlsearch_path_spec=$sys_lib_search_path_spec + ;; + *) + shrext_cmds='.sl' + dynamic_linker="$host_os dld.sl" + shlibpath_var=SHLIB_PATH + shlibpath_overrides_runpath=no # +s is required to enable SHLIB_PATH + library_names_spec='${libname}${release}${shared_ext}$versuffix ${libname}${release}${shared_ext}$major $libname${shared_ext}' + soname_spec='${libname}${release}${shared_ext}$major' + ;; + esac + # HP-UX runs *really* slowly unless shared libraries are mode 555. + postinstall_cmds='chmod 555 $lib' + ;; + +interix3*) + version_type=linux + need_lib_prefix=no + need_version=no + library_names_spec='${libname}${release}${shared_ext}$versuffix ${libname}${release}${shared_ext}$major ${libname}${shared_ext}' + soname_spec='${libname}${release}${shared_ext}$major' + dynamic_linker='Interix 3.x ld.so.1 (PE, like ELF)' + shlibpath_var=LD_LIBRARY_PATH + shlibpath_overrides_runpath=no + hardcode_into_libs=yes + ;; + +irix5* | irix6* | nonstopux*) + case $host_os in + nonstopux*) version_type=nonstopux ;; + *) + if test "$lt_cv_prog_gnu_ld" = yes; then + version_type=linux + else + version_type=irix + fi ;; + esac + need_lib_prefix=no + need_version=no + soname_spec='${libname}${release}${shared_ext}$major' + library_names_spec='${libname}${release}${shared_ext}$versuffix ${libname}${release}${shared_ext}$major ${libname}${release}${shared_ext} $libname${shared_ext}' + case $host_os in + irix5* | nonstopux*) + libsuff= shlibsuff= + ;; + *) + case $LD in # libtool.m4 will add one of these switches to LD + *-32|*"-32 "|*-melf32bsmip|*"-melf32bsmip ") + libsuff= shlibsuff= libmagic=32-bit;; + *-n32|*"-n32 "|*-melf32bmipn32|*"-melf32bmipn32 ") + libsuff=32 shlibsuff=N32 libmagic=N32;; + *-64|*"-64 "|*-melf64bmip|*"-melf64bmip ") + libsuff=64 shlibsuff=64 libmagic=64-bit;; + *) libsuff= shlibsuff= libmagic=never-match;; + esac + ;; + esac + shlibpath_var=LD_LIBRARY${shlibsuff}_PATH + shlibpath_overrides_runpath=no + sys_lib_search_path_spec="/usr/lib${libsuff} /lib${libsuff} /usr/local/lib${libsuff}" + sys_lib_dlsearch_path_spec="/usr/lib${libsuff} /lib${libsuff}" + hardcode_into_libs=yes + ;; + +# No shared lib support for Linux oldld, aout, or coff. +linux*oldld* | linux*aout* | linux*coff*) + dynamic_linker=no + ;; + +# This must be Linux ELF. +linux*) + version_type=linux + need_lib_prefix=no + need_version=no + library_names_spec='${libname}${release}${shared_ext}$versuffix ${libname}${release}${shared_ext}$major $libname${shared_ext}' + soname_spec='${libname}${release}${shared_ext}$major' + finish_cmds='PATH="\$PATH:/sbin" ldconfig -n $libdir' + shlibpath_var=LD_LIBRARY_PATH + shlibpath_overrides_runpath=no + # This implies no fast_install, which is unacceptable. + # Some rework will be needed to allow for fast_install + # before this can be enabled. + hardcode_into_libs=yes + + # find out which ABI we are using + libsuff= + case "$host_cpu" in + x86_64*|s390x*|powerpc64*) + echo '#line 14945 "configure"' > conftest.$ac_ext + if { (eval echo "$as_me:$LINENO: \"$ac_compile\"") >&5 + (eval $ac_compile) 2>&5 + ac_status=$? + echo "$as_me:$LINENO: \$? = $ac_status" >&5 + (exit $ac_status); }; then + case `/usr/bin/file conftest.$ac_objext` in + *64-bit*) + libsuff=64 + sys_lib_search_path_spec="/lib${libsuff} /usr/lib${libsuff} /usr/local/lib${libsuff}" + ;; + esac + fi + rm -rf conftest* + ;; + esac + + # Append ld.so.conf contents to the search path + if test -f /etc/ld.so.conf; then + lt_ld_extra=`awk '/^include / { system(sprintf("cd /etc; cat %s 2>/dev/null", \$2)); skip = 1; } { if (!skip) print \$0; skip = 0; }' < /etc/ld.so.conf | $SED -e 's/#.*//;s/[:, ]/ /g;s/=[^=]*$//;s/=[^= ]* / /g;/^$/d' | tr '\n' ' '` + sys_lib_dlsearch_path_spec="/lib${libsuff} /usr/lib${libsuff} $lt_ld_extra" + fi + + # We used to test for /lib/ld.so.1 and disable shared libraries on + # powerpc, because MkLinux only supported shared libraries with the + # GNU dynamic linker. Since this was broken with cross compilers, + # most powerpc-linux boxes support dynamic linking these days and + # people can always --disable-shared, the test was removed, and we + # assume the GNU/Linux dynamic linker is in use. + dynamic_linker='GNU/Linux ld.so' + ;; + +knetbsd*-gnu) + version_type=linux + need_lib_prefix=no + need_version=no + library_names_spec='${libname}${release}${shared_ext}$versuffix ${libname}${release}${shared_ext}$major ${libname}${shared_ext}' + soname_spec='${libname}${release}${shared_ext}$major' + shlibpath_var=LD_LIBRARY_PATH + shlibpath_overrides_runpath=no + hardcode_into_libs=yes + dynamic_linker='GNU ld.so' + ;; + +netbsd*) + version_type=sunos + need_lib_prefix=no + need_version=no + if echo __ELF__ | $CC -E - | grep __ELF__ >/dev/null; then + library_names_spec='${libname}${release}${shared_ext}$versuffix ${libname}${shared_ext}$versuffix' + finish_cmds='PATH="\$PATH:/sbin" ldconfig -m $libdir' + dynamic_linker='NetBSD (a.out) ld.so' + else + library_names_spec='${libname}${release}${shared_ext}$versuffix ${libname}${release}${shared_ext}$major ${libname}${shared_ext}' + soname_spec='${libname}${release}${shared_ext}$major' + dynamic_linker='NetBSD ld.elf_so' + fi + shlibpath_var=LD_LIBRARY_PATH + shlibpath_overrides_runpath=yes + hardcode_into_libs=yes + ;; + +newsos6) + version_type=linux + library_names_spec='${libname}${release}${shared_ext}$versuffix ${libname}${release}${shared_ext}$major $libname${shared_ext}' + shlibpath_var=LD_LIBRARY_PATH + shlibpath_overrides_runpath=yes + ;; + +nto-qnx*) + version_type=linux + need_lib_prefix=no + need_version=no + library_names_spec='${libname}${release}${shared_ext}$versuffix ${libname}${release}${shared_ext}$major $libname${shared_ext}' + soname_spec='${libname}${release}${shared_ext}$major' + shlibpath_var=LD_LIBRARY_PATH + shlibpath_overrides_runpath=yes + ;; + +openbsd*) + version_type=sunos + sys_lib_dlsearch_path_spec="/usr/lib" + need_lib_prefix=no + # Some older versions of OpenBSD (3.3 at least) *do* need versioned libs. + case $host_os in + openbsd3.3 | openbsd3.3.*) need_version=yes ;; + *) need_version=no ;; + esac + library_names_spec='${libname}${release}${shared_ext}$versuffix ${libname}${shared_ext}$versuffix' + finish_cmds='PATH="\$PATH:/sbin" ldconfig -m $libdir' + shlibpath_var=LD_LIBRARY_PATH + if test -z "`echo __ELF__ | $CC -E - | grep __ELF__`" || test "$host_os-$host_cpu" = "openbsd2.8-powerpc"; then + case $host_os in + openbsd2.[89] | openbsd2.[89].*) + shlibpath_overrides_runpath=no + ;; + *) + shlibpath_overrides_runpath=yes + ;; + esac + else + shlibpath_overrides_runpath=yes + fi + ;; + +os2*) + libname_spec='$name' + shrext_cmds=".dll" + need_lib_prefix=no + library_names_spec='$libname${shared_ext} $libname.a' + dynamic_linker='OS/2 ld.exe' + shlibpath_var=LIBPATH + ;; + +osf3* | osf4* | osf5*) + version_type=osf + need_lib_prefix=no + need_version=no + soname_spec='${libname}${release}${shared_ext}$major' + library_names_spec='${libname}${release}${shared_ext}$versuffix ${libname}${release}${shared_ext}$major $libname${shared_ext}' + shlibpath_var=LD_LIBRARY_PATH + sys_lib_search_path_spec="/usr/shlib /usr/ccs/lib /usr/lib/cmplrs/cc /usr/lib /usr/local/lib /var/shlib" + sys_lib_dlsearch_path_spec="$sys_lib_search_path_spec" + ;; + +solaris*) + version_type=linux + need_lib_prefix=no + need_version=no + library_names_spec='${libname}${release}${shared_ext}$versuffix ${libname}${release}${shared_ext}$major $libname${shared_ext}' + soname_spec='${libname}${release}${shared_ext}$major' + shlibpath_var=LD_LIBRARY_PATH + shlibpath_overrides_runpath=yes + hardcode_into_libs=yes + # ldd complains unless libraries are executable + postinstall_cmds='chmod +x $lib' + ;; + +sunos4*) + version_type=sunos + library_names_spec='${libname}${release}${shared_ext}$versuffix ${libname}${shared_ext}$versuffix' + finish_cmds='PATH="\$PATH:/usr/etc" ldconfig $libdir' + shlibpath_var=LD_LIBRARY_PATH + shlibpath_overrides_runpath=yes + if test "$with_gnu_ld" = yes; then + need_lib_prefix=no + fi + need_version=yes + ;; + +sysv4 | sysv4.3*) + version_type=linux + library_names_spec='${libname}${release}${shared_ext}$versuffix ${libname}${release}${shared_ext}$major $libname${shared_ext}' + soname_spec='${libname}${release}${shared_ext}$major' + shlibpath_var=LD_LIBRARY_PATH + case $host_vendor in + sni) + shlibpath_overrides_runpath=no + need_lib_prefix=no + export_dynamic_flag_spec='${wl}-Blargedynsym' + runpath_var=LD_RUN_PATH + ;; + siemens) + need_lib_prefix=no + ;; + motorola) + need_lib_prefix=no + need_version=no + shlibpath_overrides_runpath=no + sys_lib_search_path_spec='/lib /usr/lib /usr/ccs/lib' + ;; + esac + ;; + +sysv4*MP*) + if test -d /usr/nec ;then + version_type=linux + library_names_spec='$libname${shared_ext}.$versuffix $libname${shared_ext}.$major $libname${shared_ext}' + soname_spec='$libname${shared_ext}.$major' + shlibpath_var=LD_LIBRARY_PATH + fi + ;; + +sysv5* | sco3.2v5* | sco5v6* | unixware* | OpenUNIX* | sysv4*uw2*) + version_type=freebsd-elf + need_lib_prefix=no + need_version=no + library_names_spec='${libname}${release}${shared_ext}$versuffix ${libname}${release}${shared_ext} $libname${shared_ext}' + soname_spec='${libname}${release}${shared_ext}$major' + shlibpath_var=LD_LIBRARY_PATH + hardcode_into_libs=yes + if test "$with_gnu_ld" = yes; then + sys_lib_search_path_spec='/usr/local/lib /usr/gnu/lib /usr/ccs/lib /usr/lib /lib' + shlibpath_overrides_runpath=no + else + sys_lib_search_path_spec='/usr/ccs/lib /usr/lib' + shlibpath_overrides_runpath=yes + case $host_os in + sco3.2v5*) + sys_lib_search_path_spec="$sys_lib_search_path_spec /lib" + ;; + esac + fi + sys_lib_dlsearch_path_spec='/usr/lib' + ;; + +uts4*) + version_type=linux + library_names_spec='${libname}${release}${shared_ext}$versuffix ${libname}${release}${shared_ext}$major $libname${shared_ext}' + soname_spec='${libname}${release}${shared_ext}$major' + shlibpath_var=LD_LIBRARY_PATH + ;; + +*) + dynamic_linker=no + ;; +esac +echo "$as_me:$LINENO: result: $dynamic_linker" >&5 +echo "${ECHO_T}$dynamic_linker" >&6 +test "$dynamic_linker" = no && can_build_shared=no + +variables_saved_for_relink="PATH $shlibpath_var $runpath_var" +if test "$GCC" = yes; then + variables_saved_for_relink="$variables_saved_for_relink GCC_EXEC_PREFIX COMPILER_PATH LIBRARY_PATH" +fi + +echo "$as_me:$LINENO: checking how to hardcode library paths into programs" >&5 +echo $ECHO_N "checking how to hardcode library paths into programs... $ECHO_C" >&6 +hardcode_action_F77= +if test -n "$hardcode_libdir_flag_spec_F77" || \ + test -n "$runpath_var_F77" || \ + test "X$hardcode_automatic_F77" = "Xyes" ; then + + # We can hardcode non-existant directories. + if test "$hardcode_direct_F77" != no && + # If the only mechanism to avoid hardcoding is shlibpath_var, we + # have to relink, otherwise we might link with an installed library + # when we should be linking with a yet-to-be-installed one + ## test "$_LT_AC_TAGVAR(hardcode_shlibpath_var, F77)" != no && + test "$hardcode_minus_L_F77" != no; then + # Linking always hardcodes the temporary library directory. + hardcode_action_F77=relink + else + # We can link without hardcoding, and we can hardcode nonexisting dirs. + hardcode_action_F77=immediate + fi +else + # We cannot hardcode anything, or else we can only hardcode existing + # directories. + hardcode_action_F77=unsupported +fi +echo "$as_me:$LINENO: result: $hardcode_action_F77" >&5 +echo "${ECHO_T}$hardcode_action_F77" >&6 + +if test "$hardcode_action_F77" = relink; then + # Fast installation is not supported + enable_fast_install=no +elif test "$shlibpath_overrides_runpath" = yes || + test "$enable_shared" = no; then + # Fast installation is not necessary + enable_fast_install=needless +fi + + +# The else clause should only fire when bootstrapping the +# libtool distribution, otherwise you forgot to ship ltmain.sh +# with your package, and you will get complaints that there are +# no rules to generate ltmain.sh. +if test -f "$ltmain"; then + # See if we are running on zsh, and set the options which allow our commands through + # without removal of \ escapes. + if test -n "${ZSH_VERSION+set}" ; then + setopt NO_GLOB_SUBST + fi + # Now quote all the things that may contain metacharacters while being + # careful not to overquote the AC_SUBSTed values. We take copies of the + # variables and quote the copies for generation of the libtool script. + for var in echo old_CC old_CFLAGS AR AR_FLAGS EGREP RANLIB LN_S LTCC LTCFLAGS NM \ + SED SHELL STRIP \ + libname_spec library_names_spec soname_spec extract_expsyms_cmds \ + old_striplib striplib file_magic_cmd finish_cmds finish_eval \ + deplibs_check_method reload_flag reload_cmds need_locks \ + lt_cv_sys_global_symbol_pipe lt_cv_sys_global_symbol_to_cdecl \ + lt_cv_sys_global_symbol_to_c_name_address \ + sys_lib_search_path_spec sys_lib_dlsearch_path_spec \ + old_postinstall_cmds old_postuninstall_cmds \ + compiler_F77 \ + CC_F77 \ + LD_F77 \ + lt_prog_compiler_wl_F77 \ + lt_prog_compiler_pic_F77 \ + lt_prog_compiler_static_F77 \ + lt_prog_compiler_no_builtin_flag_F77 \ + export_dynamic_flag_spec_F77 \ + thread_safe_flag_spec_F77 \ + whole_archive_flag_spec_F77 \ + enable_shared_with_static_runtimes_F77 \ + old_archive_cmds_F77 \ + old_archive_from_new_cmds_F77 \ + predep_objects_F77 \ + postdep_objects_F77 \ + predeps_F77 \ + postdeps_F77 \ + compiler_lib_search_path_F77 \ + archive_cmds_F77 \ + archive_expsym_cmds_F77 \ + postinstall_cmds_F77 \ + postuninstall_cmds_F77 \ + old_archive_from_expsyms_cmds_F77 \ + allow_undefined_flag_F77 \ + no_undefined_flag_F77 \ + export_symbols_cmds_F77 \ + hardcode_libdir_flag_spec_F77 \ + hardcode_libdir_flag_spec_ld_F77 \ + hardcode_libdir_separator_F77 \ + hardcode_automatic_F77 \ + module_cmds_F77 \ + module_expsym_cmds_F77 \ + lt_cv_prog_compiler_c_o_F77 \ + exclude_expsyms_F77 \ + include_expsyms_F77; do + + case $var in + old_archive_cmds_F77 | \ + old_archive_from_new_cmds_F77 | \ + archive_cmds_F77 | \ + archive_expsym_cmds_F77 | \ + module_cmds_F77 | \ + module_expsym_cmds_F77 | \ + old_archive_from_expsyms_cmds_F77 | \ + export_symbols_cmds_F77 | \ + extract_expsyms_cmds | reload_cmds | finish_cmds | \ + postinstall_cmds | postuninstall_cmds | \ + old_postinstall_cmds | old_postuninstall_cmds | \ + sys_lib_search_path_spec | sys_lib_dlsearch_path_spec) + # Double-quote double-evaled strings. + eval "lt_$var=\\\"\`\$echo \"X\$$var\" | \$Xsed -e \"\$double_quote_subst\" -e \"\$sed_quote_subst\" -e \"\$delay_variable_subst\"\`\\\"" + ;; + *) + eval "lt_$var=\\\"\`\$echo \"X\$$var\" | \$Xsed -e \"\$sed_quote_subst\"\`\\\"" + ;; + esac + done + + case $lt_echo in + *'\$0 --fallback-echo"') + lt_echo=`$echo "X$lt_echo" | $Xsed -e 's/\\\\\\\$0 --fallback-echo"$/$0 --fallback-echo"/'` + ;; + esac + +cfgfile="$ofile" + + cat <<__EOF__ >> "$cfgfile" +# ### BEGIN LIBTOOL TAG CONFIG: $tagname + +# Libtool was configured on host `(hostname || uname -n) 2>/dev/null | sed 1q`: + +# Shell to use when invoking shell scripts. +SHELL=$lt_SHELL + +# Whether or not to build shared libraries. +build_libtool_libs=$enable_shared + +# Whether or not to build static libraries. +build_old_libs=$enable_static + +# Whether or not to add -lc for building shared libraries. +build_libtool_need_lc=$archive_cmds_need_lc_F77 + +# Whether or not to disallow shared libs when runtime libs are static +allow_libtool_libs_with_static_runtimes=$enable_shared_with_static_runtimes_F77 + +# Whether or not to optimize for fast installation. +fast_install=$enable_fast_install + +# The host system. +host_alias=$host_alias +host=$host +host_os=$host_os + +# The build system. +build_alias=$build_alias +build=$build +build_os=$build_os + +# An echo program that does not interpret backslashes. +echo=$lt_echo + +# The archiver. +AR=$lt_AR +AR_FLAGS=$lt_AR_FLAGS + +# A C compiler. +LTCC=$lt_LTCC + +# LTCC compiler flags. +LTCFLAGS=$lt_LTCFLAGS + +# A language-specific compiler. +CC=$lt_compiler_F77 + +# Is the compiler the GNU C compiler? +with_gcc=$GCC_F77 + +gcc_dir=\`gcc -print-file-name=. | $SED 's,/\.$,,'\` +gcc_ver=\`gcc -dumpversion\` + +# An ERE matcher. +EGREP=$lt_EGREP + +# The linker used to build libraries. +LD=$lt_LD_F77 + +# Whether we need hard or soft links. +LN_S=$lt_LN_S + +# A BSD-compatible nm program. +NM=$lt_NM + +# A symbol stripping program +STRIP=$lt_STRIP + +# Used to examine libraries when file_magic_cmd begins "file" +MAGIC_CMD=$MAGIC_CMD + +# Used on cygwin: DLL creation program. +DLLTOOL="$DLLTOOL" + +# Used on cygwin: object dumper. +OBJDUMP="$OBJDUMP" + +# Used on cygwin: assembler. +AS="$AS" + +# The name of the directory that contains temporary libtool files. +objdir=$objdir + +# How to create reloadable object files. +reload_flag=$lt_reload_flag +reload_cmds=$lt_reload_cmds + +# How to pass a linker flag through the compiler. +wl=$lt_lt_prog_compiler_wl_F77 + +# Object file suffix (normally "o"). +objext="$ac_objext" + +# Old archive suffix (normally "a"). +libext="$libext" + +# Shared library suffix (normally ".so"). +shrext_cmds='$shrext_cmds' + +# Executable file suffix (normally ""). +exeext="$exeext" + +# Additional compiler flags for building library objects. +pic_flag=$lt_lt_prog_compiler_pic_F77 +pic_mode=$pic_mode + +# What is the maximum length of a command? +max_cmd_len=$lt_cv_sys_max_cmd_len + +# Does compiler simultaneously support -c and -o options? +compiler_c_o=$lt_lt_cv_prog_compiler_c_o_F77 + +# Must we lock files when doing compilation? +need_locks=$lt_need_locks + +# Do we need the lib prefix for modules? +need_lib_prefix=$need_lib_prefix + +# Do we need a version for libraries? +need_version=$need_version + +# Whether dlopen is supported. +dlopen_support=$enable_dlopen + +# Whether dlopen of programs is supported. +dlopen_self=$enable_dlopen_self + +# Whether dlopen of statically linked programs is supported. +dlopen_self_static=$enable_dlopen_self_static + +# Compiler flag to prevent dynamic linking. +link_static_flag=$lt_lt_prog_compiler_static_F77 + +# Compiler flag to turn off builtin functions. +no_builtin_flag=$lt_lt_prog_compiler_no_builtin_flag_F77 + +# Compiler flag to allow reflexive dlopens. +export_dynamic_flag_spec=$lt_export_dynamic_flag_spec_F77 + +# Compiler flag to generate shared objects directly from archives. +whole_archive_flag_spec=$lt_whole_archive_flag_spec_F77 + +# Compiler flag to generate thread-safe objects. +thread_safe_flag_spec=$lt_thread_safe_flag_spec_F77 + +# Library versioning type. +version_type=$version_type + +# Format of library name prefix. +libname_spec=$lt_libname_spec + +# List of archive names. First name is the real one, the rest are links. +# The last name is the one that the linker finds with -lNAME. +library_names_spec=$lt_library_names_spec + +# The coded name of the library, if different from the real name. +soname_spec=$lt_soname_spec + +# Commands used to build and install an old-style archive. +RANLIB=$lt_RANLIB +old_archive_cmds=$lt_old_archive_cmds_F77 +old_postinstall_cmds=$lt_old_postinstall_cmds +old_postuninstall_cmds=$lt_old_postuninstall_cmds + +# Create an old-style archive from a shared archive. +old_archive_from_new_cmds=$lt_old_archive_from_new_cmds_F77 + +# Create a temporary old-style archive to link instead of a shared archive. +old_archive_from_expsyms_cmds=$lt_old_archive_from_expsyms_cmds_F77 + +# Commands used to build and install a shared archive. +archive_cmds=$lt_archive_cmds_F77 +archive_expsym_cmds=$lt_archive_expsym_cmds_F77 +postinstall_cmds=$lt_postinstall_cmds +postuninstall_cmds=$lt_postuninstall_cmds + +# Commands used to build a loadable module (assumed same as above if empty) +module_cmds=$lt_module_cmds_F77 +module_expsym_cmds=$lt_module_expsym_cmds_F77 + +# Commands to strip libraries. +old_striplib=$lt_old_striplib +striplib=$lt_striplib + +# Dependencies to place before the objects being linked to create a +# shared library. +predep_objects=\`echo $lt_predep_objects_F77 | \$SED -e "s@\${gcc_dir}@\\\${gcc_dir}@g;s@\${gcc_ver}@\\\${gcc_ver}@g"\` + +# Dependencies to place after the objects being linked to create a +# shared library. +postdep_objects=\`echo $lt_postdep_objects_F77 | \$SED -e "s@\${gcc_dir}@\\\${gcc_dir}@g;s@\${gcc_ver}@\\\${gcc_ver}@g"\` + +# Dependencies to place before the objects being linked to create a +# shared library. +predeps=$lt_predeps_F77 + +# Dependencies to place after the objects being linked to create a +# shared library. +postdeps=$lt_postdeps_F77 + +# The library search path used internally by the compiler when linking +# a shared library. +compiler_lib_search_path=\`echo $lt_compiler_lib_search_path_F77 | \$SED -e "s@\${gcc_dir}@\\\${gcc_dir}@g;s@\${gcc_ver}@\\\${gcc_ver}@g"\` + +# Method to check whether dependent libraries are shared objects. +deplibs_check_method=$lt_deplibs_check_method + +# Command to use when deplibs_check_method == file_magic. +file_magic_cmd=$lt_file_magic_cmd + +# Flag that allows shared libraries with undefined symbols to be built. +allow_undefined_flag=$lt_allow_undefined_flag_F77 + +# Flag that forces no undefined symbols. +no_undefined_flag=$lt_no_undefined_flag_F77 + +# Commands used to finish a libtool library installation in a directory. +finish_cmds=$lt_finish_cmds + +# Same as above, but a single script fragment to be evaled but not shown. +finish_eval=$lt_finish_eval + +# Take the output of nm and produce a listing of raw symbols and C names. +global_symbol_pipe=$lt_lt_cv_sys_global_symbol_pipe + +# Transform the output of nm in a proper C declaration +global_symbol_to_cdecl=$lt_lt_cv_sys_global_symbol_to_cdecl + +# Transform the output of nm in a C name address pair +global_symbol_to_c_name_address=$lt_lt_cv_sys_global_symbol_to_c_name_address + +# This is the shared library runtime path variable. +runpath_var=$runpath_var + +# This is the shared library path variable. +shlibpath_var=$shlibpath_var + +# Is shlibpath searched before the hard-coded library search path? +shlibpath_overrides_runpath=$shlibpath_overrides_runpath + +# How to hardcode a shared library path into an executable. +hardcode_action=$hardcode_action_F77 + +# Whether we should hardcode library paths into libraries. +hardcode_into_libs=$hardcode_into_libs + +# Flag to hardcode \$libdir into a binary during linking. +# This must work even if \$libdir does not exist. +hardcode_libdir_flag_spec=$lt_hardcode_libdir_flag_spec_F77 + +# If ld is used when linking, flag to hardcode \$libdir into +# a binary during linking. This must work even if \$libdir does +# not exist. +hardcode_libdir_flag_spec_ld=$lt_hardcode_libdir_flag_spec_ld_F77 + +# Whether we need a single -rpath flag with a separated argument. +hardcode_libdir_separator=$lt_hardcode_libdir_separator_F77 + +# Set to yes if using DIR/libNAME${shared_ext} during linking hardcodes DIR into the +# resulting binary. +hardcode_direct=$hardcode_direct_F77 + +# Set to yes if using the -LDIR flag during linking hardcodes DIR into the +# resulting binary. +hardcode_minus_L=$hardcode_minus_L_F77 + +# Set to yes if using SHLIBPATH_VAR=DIR during linking hardcodes DIR into +# the resulting binary. +hardcode_shlibpath_var=$hardcode_shlibpath_var_F77 + +# Set to yes if building a shared library automatically hardcodes DIR into the library +# and all subsequent libraries and executables linked against it. +hardcode_automatic=$hardcode_automatic_F77 + +# Variables whose values should be saved in libtool wrapper scripts and +# restored at relink time. +variables_saved_for_relink="$variables_saved_for_relink" + +# Whether libtool must link a program against all its dependency libraries. +link_all_deplibs=$link_all_deplibs_F77 + +# Compile-time system search path for libraries +sys_lib_search_path_spec=\`echo $lt_sys_lib_search_path_spec | \$SED -e "s@\${gcc_dir}@\\\${gcc_dir}@g;s@\${gcc_ver}@\\\${gcc_ver}@g"\` + +# Run-time system search path for libraries +sys_lib_dlsearch_path_spec=$lt_sys_lib_dlsearch_path_spec + +# Fix the shell variable \$srcfile for the compiler. +fix_srcfile_path="$fix_srcfile_path_F77" + +# Set to yes if exported symbols are required. +always_export_symbols=$always_export_symbols_F77 + +# The commands to list exported symbols. +export_symbols_cmds=$lt_export_symbols_cmds_F77 + +# The commands to extract the exported symbol list from a shared archive. +extract_expsyms_cmds=$lt_extract_expsyms_cmds + +# Symbols that should not be listed in the preloaded symbols. +exclude_expsyms=$lt_exclude_expsyms_F77 + +# Symbols that must always be exported. +include_expsyms=$lt_include_expsyms_F77 + +# ### END LIBTOOL TAG CONFIG: $tagname + +__EOF__ + + +else + # If there is no Makefile yet, we rely on a make rule to execute + # `config.status --recheck' to rerun these tests and create the + # libtool script then. + ltmain_in=`echo $ltmain | sed -e 's/\.sh$/.in/'` + if test -f "$ltmain_in"; then + test -f Makefile && make "$ltmain" + fi +fi + + +ac_ext=c +ac_cpp='$CPP $CPPFLAGS' +ac_compile='$CC -c $CFLAGS $CPPFLAGS conftest.$ac_ext >&5' +ac_link='$CC -o conftest$ac_exeext $CFLAGS $CPPFLAGS $LDFLAGS conftest.$ac_ext $LIBS >&5' +ac_compiler_gnu=$ac_cv_c_compiler_gnu + +CC="$lt_save_CC" + + else + tagname="" + fi + ;; + + GCJ) + if test -n "$GCJ" && test "X$GCJ" != "Xno"; then + + + +# Source file extension for Java test sources. +ac_ext=java + +# Object file extension for compiled Java test sources. +objext=o +objext_GCJ=$objext + +# Code to be used in simple compile tests +lt_simple_compile_test_code="class foo {}\n" + +# Code to be used in simple link tests +lt_simple_link_test_code='public class conftest { public static void main(String[] argv) {}; }\n' + +# ltmain only uses $CC for tagged configurations so make sure $CC is set. + +# If no C compiler was specified, use CC. +LTCC=${LTCC-"$CC"} + +# If no C compiler flags were specified, use CFLAGS. +LTCFLAGS=${LTCFLAGS-"$CFLAGS"} + +# Allow CC to be a program name with arguments. +compiler=$CC + + +# save warnings/boilerplate of simple test code +ac_outfile=conftest.$ac_objext +printf "$lt_simple_compile_test_code" >conftest.$ac_ext +eval "$ac_compile" 2>&1 >/dev/null | $SED '/^$/d; /^ *+/d' >conftest.err +_lt_compiler_boilerplate=`cat conftest.err` +$rm conftest* + +ac_outfile=conftest.$ac_objext +printf "$lt_simple_link_test_code" >conftest.$ac_ext +eval "$ac_link" 2>&1 >/dev/null | $SED '/^$/d; /^ *+/d' >conftest.err +_lt_linker_boilerplate=`cat conftest.err` +$rm conftest* + + +# Allow CC to be a program name with arguments. +lt_save_CC="$CC" +CC=${GCJ-"gcj"} +compiler=$CC +compiler_GCJ=$CC +for cc_temp in $compiler""; do + case $cc_temp in + compile | *[\\/]compile | ccache | *[\\/]ccache ) ;; + distcc | *[\\/]distcc | purify | *[\\/]purify ) ;; + \-*) ;; + *) break;; + esac +done +cc_basename=`$echo "X$cc_temp" | $Xsed -e 's%.*/%%' -e "s%^$host_alias-%%"` + + +# GCJ did not exist at the time GCC didn't implicitly link libc in. +archive_cmds_need_lc_GCJ=no + +old_archive_cmds_GCJ=$old_archive_cmds + + +lt_prog_compiler_no_builtin_flag_GCJ= + +if test "$GCC" = yes; then + lt_prog_compiler_no_builtin_flag_GCJ=' -fno-builtin' + + +echo "$as_me:$LINENO: checking if $compiler supports -fno-rtti -fno-exceptions" >&5 +echo $ECHO_N "checking if $compiler supports -fno-rtti -fno-exceptions... $ECHO_C" >&6 +if test "${lt_cv_prog_compiler_rtti_exceptions+set}" = set; then + echo $ECHO_N "(cached) $ECHO_C" >&6 +else + lt_cv_prog_compiler_rtti_exceptions=no + ac_outfile=conftest.$ac_objext + printf "$lt_simple_compile_test_code" > conftest.$ac_ext + lt_compiler_flag="-fno-rtti -fno-exceptions" + # Insert the option either (1) after the last *FLAGS variable, or + # (2) before a word containing "conftest.", or (3) at the end. + # Note that $ac_compile itself does not contain backslashes and begins + # with a dollar sign (not a hyphen), so the echo should work correctly. + # The option is referenced via a variable to avoid confusing sed. + lt_compile=`echo "$ac_compile" | $SED \ + -e 's:.*FLAGS}\{0,1\} :&$lt_compiler_flag :; t' \ + -e 's: [^ ]*conftest\.: $lt_compiler_flag&:; t' \ + -e 's:$: $lt_compiler_flag:'` + (eval echo "\"\$as_me:15723: $lt_compile\"" >&5) + (eval "$lt_compile" 2>conftest.err) + ac_status=$? + cat conftest.err >&5 + echo "$as_me:15727: \$? = $ac_status" >&5 + if (exit $ac_status) && test -s "$ac_outfile"; then + # The compiler can only warn and ignore the option if not recognized + # So say no if there are warnings other than the usual output. + $echo "X$_lt_compiler_boilerplate" | $Xsed -e '/^$/d' >conftest.exp + $SED '/^$/d; /^ *+/d' conftest.err >conftest.er2 + if test ! -s conftest.er2 || diff conftest.exp conftest.er2 >/dev/null; then + lt_cv_prog_compiler_rtti_exceptions=yes + fi + fi + $rm conftest* + +fi +echo "$as_me:$LINENO: result: $lt_cv_prog_compiler_rtti_exceptions" >&5 +echo "${ECHO_T}$lt_cv_prog_compiler_rtti_exceptions" >&6 + +if test x"$lt_cv_prog_compiler_rtti_exceptions" = xyes; then + lt_prog_compiler_no_builtin_flag_GCJ="$lt_prog_compiler_no_builtin_flag_GCJ -fno-rtti -fno-exceptions" +else + : +fi + +fi + +lt_prog_compiler_wl_GCJ= +lt_prog_compiler_pic_GCJ= +lt_prog_compiler_static_GCJ= + +echo "$as_me:$LINENO: checking for $compiler option to produce PIC" >&5 +echo $ECHO_N "checking for $compiler option to produce PIC... $ECHO_C" >&6 + + if test "$GCC" = yes; then + lt_prog_compiler_wl_GCJ='-Wl,' + lt_prog_compiler_static_GCJ='-static' + + case $host_os in + aix*) + # All AIX code is PIC. + if test "$host_cpu" = ia64; then + # AIX 5 now supports IA64 processor + lt_prog_compiler_static_GCJ='-Bstatic' + fi + ;; + + amigaos*) + # FIXME: we need at least 68020 code to build shared libraries, but + # adding the `-m68020' flag to GCC prevents building anything better, + # like `-m68040'. + lt_prog_compiler_pic_GCJ='-m68020 -resident32 -malways-restore-a4' + ;; + + beos* | cygwin* | irix5* | irix6* | nonstopux* | osf3* | osf4* | osf5*) + # PIC is the default for these OSes. + ;; + + mingw* | pw32* | os2*) + # This hack is so that the source file can tell whether it is being + # built for inclusion in a dll (and should export symbols for example). + lt_prog_compiler_pic_GCJ='-DDLL_EXPORT' + ;; + + darwin* | rhapsody*) + # PIC is the default on this platform + # Common symbols not allowed in MH_DYLIB files + lt_prog_compiler_pic_GCJ='-fno-common' + ;; + + interix3*) + # Interix 3.x gcc -fpic/-fPIC options generate broken code. + # Instead, we relocate shared libraries at runtime. + ;; + + msdosdjgpp*) + # Just because we use GCC doesn't mean we suddenly get shared libraries + # on systems that don't support them. + lt_prog_compiler_can_build_shared_GCJ=no + enable_shared=no + ;; + + sysv4*MP*) + if test -d /usr/nec; then + lt_prog_compiler_pic_GCJ=-Kconform_pic + fi + ;; + + hpux*) + # PIC is the default for IA64 HP-UX and 64-bit HP-UX, but + # not for PA HP-UX. + case $host_cpu in + hppa*64*|ia64*) + # +Z the default + ;; + *) + lt_prog_compiler_pic_GCJ='-fPIC' + ;; + esac + ;; + + *) + lt_prog_compiler_pic_GCJ='-fPIC' + ;; + esac + else + # PORTME Check for flag to pass linker flags through the system compiler. + case $host_os in + aix*) + lt_prog_compiler_wl_GCJ='-Wl,' + if test "$host_cpu" = ia64; then + # AIX 5 now supports IA64 processor + lt_prog_compiler_static_GCJ='-Bstatic' + else + lt_prog_compiler_static_GCJ='-bnso -bI:/lib/syscalls.exp' + fi + ;; + darwin*) + # PIC is the default on this platform + # Common symbols not allowed in MH_DYLIB files + case $cc_basename in + xlc*) + lt_prog_compiler_pic_GCJ='-qnocommon' + lt_prog_compiler_wl_GCJ='-Wl,' + ;; + esac + ;; + + mingw* | pw32* | os2*) + # This hack is so that the source file can tell whether it is being + # built for inclusion in a dll (and should export symbols for example). + lt_prog_compiler_pic_GCJ='-DDLL_EXPORT' + ;; + + hpux9* | hpux10* | hpux11*) + lt_prog_compiler_wl_GCJ='-Wl,' + # PIC is the default for IA64 HP-UX and 64-bit HP-UX, but + # not for PA HP-UX. + case $host_cpu in + hppa*64*|ia64*) + # +Z the default + ;; + *) + lt_prog_compiler_pic_GCJ='+Z' + ;; + esac + # Is there a better lt_prog_compiler_static that works with the bundled CC? + lt_prog_compiler_static_GCJ='${wl}-a ${wl}archive' + ;; + + irix5* | irix6* | nonstopux*) + lt_prog_compiler_wl_GCJ='-Wl,' + # PIC (with -KPIC) is the default. + lt_prog_compiler_static_GCJ='-non_shared' + ;; + + newsos6) + lt_prog_compiler_pic_GCJ='-KPIC' + lt_prog_compiler_static_GCJ='-Bstatic' + ;; + + linux*) + case $cc_basename in + icc* | ecc*) + lt_prog_compiler_wl_GCJ='-Wl,' + lt_prog_compiler_pic_GCJ='-KPIC' + lt_prog_compiler_static_GCJ='-static' + ;; + pgcc* | pgf77* | pgf90* | pgf95*) + # Portland Group compilers (*not* the Pentium gcc compiler, + # which looks to be a dead project) + lt_prog_compiler_wl_GCJ='-Wl,' + lt_prog_compiler_pic_GCJ='-fpic' + lt_prog_compiler_static_GCJ='-Bstatic' + ;; + ccc*) + lt_prog_compiler_wl_GCJ='-Wl,' + # All Alpha code is PIC. + lt_prog_compiler_static_GCJ='-non_shared' + ;; + esac + ;; + + osf3* | osf4* | osf5*) + lt_prog_compiler_wl_GCJ='-Wl,' + # All OSF/1 code is PIC. + lt_prog_compiler_static_GCJ='-non_shared' + ;; + + solaris*) + lt_prog_compiler_pic_GCJ='-KPIC' + lt_prog_compiler_static_GCJ='-Bstatic' + case $cc_basename in + f77* | f90* | f95*) + lt_prog_compiler_wl_GCJ='-Qoption ld ';; + *) + lt_prog_compiler_wl_GCJ='-Wl,';; + esac + ;; + + sunos4*) + lt_prog_compiler_wl_GCJ='-Qoption ld ' + lt_prog_compiler_pic_GCJ='-PIC' + lt_prog_compiler_static_GCJ='-Bstatic' + ;; + + sysv4 | sysv4.2uw2* | sysv4.3*) + lt_prog_compiler_wl_GCJ='-Wl,' + lt_prog_compiler_pic_GCJ='-KPIC' + lt_prog_compiler_static_GCJ='-Bstatic' + ;; + + sysv4*MP*) + if test -d /usr/nec ;then + lt_prog_compiler_pic_GCJ='-Kconform_pic' + lt_prog_compiler_static_GCJ='-Bstatic' + fi + ;; + + sysv5* | unixware* | sco3.2v5* | sco5v6* | OpenUNIX*) + lt_prog_compiler_wl_GCJ='-Wl,' + lt_prog_compiler_pic_GCJ='-KPIC' + lt_prog_compiler_static_GCJ='-Bstatic' + ;; + + unicos*) + lt_prog_compiler_wl_GCJ='-Wl,' + lt_prog_compiler_can_build_shared_GCJ=no + ;; + + uts4*) + lt_prog_compiler_pic_GCJ='-pic' + lt_prog_compiler_static_GCJ='-Bstatic' + ;; + + *) + lt_prog_compiler_can_build_shared_GCJ=no + ;; + esac + fi + +echo "$as_me:$LINENO: result: $lt_prog_compiler_pic_GCJ" >&5 +echo "${ECHO_T}$lt_prog_compiler_pic_GCJ" >&6 + +# +# Check to make sure the PIC flag actually works. +# +if test -n "$lt_prog_compiler_pic_GCJ"; then + +echo "$as_me:$LINENO: checking if $compiler PIC flag $lt_prog_compiler_pic_GCJ works" >&5 +echo $ECHO_N "checking if $compiler PIC flag $lt_prog_compiler_pic_GCJ works... $ECHO_C" >&6 +if test "${lt_prog_compiler_pic_works_GCJ+set}" = set; then + echo $ECHO_N "(cached) $ECHO_C" >&6 +else + lt_prog_compiler_pic_works_GCJ=no + ac_outfile=conftest.$ac_objext + printf "$lt_simple_compile_test_code" > conftest.$ac_ext + lt_compiler_flag="$lt_prog_compiler_pic_GCJ" + # Insert the option either (1) after the last *FLAGS variable, or + # (2) before a word containing "conftest.", or (3) at the end. + # Note that $ac_compile itself does not contain backslashes and begins + # with a dollar sign (not a hyphen), so the echo should work correctly. + # The option is referenced via a variable to avoid confusing sed. + lt_compile=`echo "$ac_compile" | $SED \ + -e 's:.*FLAGS}\{0,1\} :&$lt_compiler_flag :; t' \ + -e 's: [^ ]*conftest\.: $lt_compiler_flag&:; t' \ + -e 's:$: $lt_compiler_flag:'` + (eval echo "\"\$as_me:15991: $lt_compile\"" >&5) + (eval "$lt_compile" 2>conftest.err) + ac_status=$? + cat conftest.err >&5 + echo "$as_me:15995: \$? = $ac_status" >&5 + if (exit $ac_status) && test -s "$ac_outfile"; then + # The compiler can only warn and ignore the option if not recognized + # So say no if there are warnings other than the usual output. + $echo "X$_lt_compiler_boilerplate" | $Xsed -e '/^$/d' >conftest.exp + $SED '/^$/d; /^ *+/d' conftest.err >conftest.er2 + if test ! -s conftest.er2 || diff conftest.exp conftest.er2 >/dev/null; then + lt_prog_compiler_pic_works_GCJ=yes + fi + fi + $rm conftest* + +fi +echo "$as_me:$LINENO: result: $lt_prog_compiler_pic_works_GCJ" >&5 +echo "${ECHO_T}$lt_prog_compiler_pic_works_GCJ" >&6 + +if test x"$lt_prog_compiler_pic_works_GCJ" = xyes; then + case $lt_prog_compiler_pic_GCJ in + "" | " "*) ;; + *) lt_prog_compiler_pic_GCJ=" $lt_prog_compiler_pic_GCJ" ;; + esac +else + lt_prog_compiler_pic_GCJ= + lt_prog_compiler_can_build_shared_GCJ=no +fi + +fi +case $host_os in + # For platforms which do not support PIC, -DPIC is meaningless: + *djgpp*) + lt_prog_compiler_pic_GCJ= + ;; + *) + lt_prog_compiler_pic_GCJ="$lt_prog_compiler_pic_GCJ" + ;; +esac + +# +# Check to make sure the static flag actually works. +# +wl=$lt_prog_compiler_wl_GCJ eval lt_tmp_static_flag=\"$lt_prog_compiler_static_GCJ\" +echo "$as_me:$LINENO: checking if $compiler static flag $lt_tmp_static_flag works" >&5 +echo $ECHO_N "checking if $compiler static flag $lt_tmp_static_flag works... $ECHO_C" >&6 +if test "${lt_prog_compiler_static_works_GCJ+set}" = set; then + echo $ECHO_N "(cached) $ECHO_C" >&6 +else + lt_prog_compiler_static_works_GCJ=no + save_LDFLAGS="$LDFLAGS" + LDFLAGS="$LDFLAGS $lt_tmp_static_flag" + printf "$lt_simple_link_test_code" > conftest.$ac_ext + if (eval $ac_link 2>conftest.err) && test -s conftest$ac_exeext; then + # The linker can only warn and ignore the option if not recognized + # So say no if there are warnings + if test -s conftest.err; then + # Append any errors to the config.log. + cat conftest.err 1>&5 + $echo "X$_lt_linker_boilerplate" | $Xsed -e '/^$/d' > conftest.exp + $SED '/^$/d; /^ *+/d' conftest.err >conftest.er2 + if diff conftest.exp conftest.er2 >/dev/null; then + lt_prog_compiler_static_works_GCJ=yes + fi + else + lt_prog_compiler_static_works_GCJ=yes + fi + fi + $rm conftest* + LDFLAGS="$save_LDFLAGS" + +fi +echo "$as_me:$LINENO: result: $lt_prog_compiler_static_works_GCJ" >&5 +echo "${ECHO_T}$lt_prog_compiler_static_works_GCJ" >&6 + +if test x"$lt_prog_compiler_static_works_GCJ" = xyes; then + : +else + lt_prog_compiler_static_GCJ= +fi + + +echo "$as_me:$LINENO: checking if $compiler supports -c -o file.$ac_objext" >&5 +echo $ECHO_N "checking if $compiler supports -c -o file.$ac_objext... $ECHO_C" >&6 +if test "${lt_cv_prog_compiler_c_o_GCJ+set}" = set; then + echo $ECHO_N "(cached) $ECHO_C" >&6 +else + lt_cv_prog_compiler_c_o_GCJ=no + $rm -r conftest 2>/dev/null + mkdir conftest + cd conftest + mkdir out + printf "$lt_simple_compile_test_code" > conftest.$ac_ext + + lt_compiler_flag="-o out/conftest2.$ac_objext" + # Insert the option either (1) after the last *FLAGS variable, or + # (2) before a word containing "conftest.", or (3) at the end. + # Note that $ac_compile itself does not contain backslashes and begins + # with a dollar sign (not a hyphen), so the echo should work correctly. + lt_compile=`echo "$ac_compile" | $SED \ + -e 's:.*FLAGS}\{0,1\} :&$lt_compiler_flag :; t' \ + -e 's: [^ ]*conftest\.: $lt_compiler_flag&:; t' \ + -e 's:$: $lt_compiler_flag:'` + (eval echo "\"\$as_me:16095: $lt_compile\"" >&5) + (eval "$lt_compile" 2>out/conftest.err) + ac_status=$? + cat out/conftest.err >&5 + echo "$as_me:16099: \$? = $ac_status" >&5 + if (exit $ac_status) && test -s out/conftest2.$ac_objext + then + # The compiler can only warn and ignore the option if not recognized + # So say no if there are warnings + $echo "X$_lt_compiler_boilerplate" | $Xsed -e '/^$/d' > out/conftest.exp + $SED '/^$/d; /^ *+/d' out/conftest.err >out/conftest.er2 + if test ! -s out/conftest.er2 || diff out/conftest.exp out/conftest.er2 >/dev/null; then + lt_cv_prog_compiler_c_o_GCJ=yes + fi + fi + chmod u+w . 2>&5 + $rm conftest* + # SGI C++ compiler will create directory out/ii_files/ for + # template instantiation + test -d out/ii_files && $rm out/ii_files/* && rmdir out/ii_files + $rm out/* && rmdir out + cd .. + rmdir conftest + $rm conftest* + +fi +echo "$as_me:$LINENO: result: $lt_cv_prog_compiler_c_o_GCJ" >&5 +echo "${ECHO_T}$lt_cv_prog_compiler_c_o_GCJ" >&6 + + +hard_links="nottested" +if test "$lt_cv_prog_compiler_c_o_GCJ" = no && test "$need_locks" != no; then + # do not overwrite the value of need_locks provided by the user + echo "$as_me:$LINENO: checking if we can lock with hard links" >&5 +echo $ECHO_N "checking if we can lock with hard links... $ECHO_C" >&6 + hard_links=yes + $rm conftest* + ln conftest.a conftest.b 2>/dev/null && hard_links=no + touch conftest.a + ln conftest.a conftest.b 2>&5 || hard_links=no + ln conftest.a conftest.b 2>/dev/null && hard_links=no + echo "$as_me:$LINENO: result: $hard_links" >&5 +echo "${ECHO_T}$hard_links" >&6 + if test "$hard_links" = no; then + { echo "$as_me:$LINENO: WARNING: \`$CC' does not support \`-c -o', so \`make -j' may be unsafe" >&5 +echo "$as_me: WARNING: \`$CC' does not support \`-c -o', so \`make -j' may be unsafe" >&2;} + need_locks=warn + fi +else + need_locks=no +fi + +echo "$as_me:$LINENO: checking whether the $compiler linker ($LD) supports shared libraries" >&5 +echo $ECHO_N "checking whether the $compiler linker ($LD) supports shared libraries... $ECHO_C" >&6 + + runpath_var= + allow_undefined_flag_GCJ= + enable_shared_with_static_runtimes_GCJ=no + archive_cmds_GCJ= + archive_expsym_cmds_GCJ= + old_archive_From_new_cmds_GCJ= + old_archive_from_expsyms_cmds_GCJ= + export_dynamic_flag_spec_GCJ= + whole_archive_flag_spec_GCJ= + thread_safe_flag_spec_GCJ= + hardcode_libdir_flag_spec_GCJ= + hardcode_libdir_flag_spec_ld_GCJ= + hardcode_libdir_separator_GCJ= + hardcode_direct_GCJ=no + hardcode_minus_L_GCJ=no + hardcode_shlibpath_var_GCJ=unsupported + link_all_deplibs_GCJ=unknown + hardcode_automatic_GCJ=no + module_cmds_GCJ= + module_expsym_cmds_GCJ= + always_export_symbols_GCJ=no + export_symbols_cmds_GCJ='$NM $libobjs $convenience | $global_symbol_pipe | $SED '\''s/.* //'\'' | sort | uniq > $export_symbols' + # include_expsyms should be a list of space-separated symbols to be *always* + # included in the symbol list + include_expsyms_GCJ= + # exclude_expsyms can be an extended regexp of symbols to exclude + # it will be wrapped by ` (' and `)$', so one must not match beginning or + # end of line. Example: `a|bc|.*d.*' will exclude the symbols `a' and `bc', + # as well as any symbol that contains `d'. + exclude_expsyms_GCJ="_GLOBAL_OFFSET_TABLE_" + # Although _GLOBAL_OFFSET_TABLE_ is a valid symbol C name, most a.out + # platforms (ab)use it in PIC code, but their linkers get confused if + # the symbol is explicitly referenced. Since portable code cannot + # rely on this symbol name, it's probably fine to never include it in + # preloaded symbol tables. + extract_expsyms_cmds= + # Just being paranoid about ensuring that cc_basename is set. + for cc_temp in $compiler""; do + case $cc_temp in + compile | *[\\/]compile | ccache | *[\\/]ccache ) ;; + distcc | *[\\/]distcc | purify | *[\\/]purify ) ;; + \-*) ;; + *) break;; + esac +done +cc_basename=`$echo "X$cc_temp" | $Xsed -e 's%.*/%%' -e "s%^$host_alias-%%"` + + case $host_os in + cygwin* | mingw* | pw32*) + # FIXME: the MSVC++ port hasn't been tested in a loooong time + # When not using gcc, we currently assume that we are using + # Microsoft Visual C++. + if test "$GCC" != yes; then + with_gnu_ld=no + fi + ;; + interix*) + # we just hope/assume this is gcc and not c89 (= MSVC++) + with_gnu_ld=yes + ;; + openbsd*) + with_gnu_ld=no + ;; + esac + + ld_shlibs_GCJ=yes + if test "$with_gnu_ld" = yes; then + # If archive_cmds runs LD, not CC, wlarc should be empty + wlarc='${wl}' + + # Set some defaults for GNU ld with shared library support. These + # are reset later if shared libraries are not supported. Putting them + # here allows them to be overridden if necessary. + runpath_var=LD_RUN_PATH + hardcode_libdir_flag_spec_GCJ='${wl}--rpath ${wl}$libdir' + export_dynamic_flag_spec_GCJ='${wl}--export-dynamic' + # ancient GNU ld didn't support --whole-archive et. al. + if $LD --help 2>&1 | grep 'no-whole-archive' > /dev/null; then + whole_archive_flag_spec_GCJ="$wlarc"'--whole-archive$convenience '"$wlarc"'--no-whole-archive' + else + whole_archive_flag_spec_GCJ= + fi + supports_anon_versioning=no + case `$LD -v 2>/dev/null` in + *\ [01].* | *\ 2.[0-9].* | *\ 2.10.*) ;; # catch versions < 2.11 + *\ 2.11.93.0.2\ *) supports_anon_versioning=yes ;; # RH7.3 ... + *\ 2.11.92.0.12\ *) supports_anon_versioning=yes ;; # Mandrake 8.2 ... + *\ 2.11.*) ;; # other 2.11 versions + *) supports_anon_versioning=yes ;; + esac + + # See if GNU ld supports shared libraries. + case $host_os in + aix3* | aix4* | aix5*) + # On AIX/PPC, the GNU linker is very broken + if test "$host_cpu" != ia64; then + ld_shlibs_GCJ=no + cat <<EOF 1>&2 + +*** Warning: the GNU linker, at least up to release 2.9.1, is reported +*** to be unable to reliably create shared libraries on AIX. +*** Therefore, libtool is disabling shared libraries support. If you +*** really care for shared libraries, you may want to modify your PATH +*** so that a non-GNU linker is found, and then restart. + +EOF + fi + ;; + + amigaos*) + archive_cmds_GCJ='$rm $output_objdir/a2ixlibrary.data~$echo "#define NAME $libname" > $output_objdir/a2ixlibrary.data~$echo "#define LIBRARY_ID 1" >> $output_objdir/a2ixlibrary.data~$echo "#define VERSION $major" >> $output_objdir/a2ixlibrary.data~$echo "#define REVISION $revision" >> $output_objdir/a2ixlibrary.data~$AR $AR_FLAGS $lib $libobjs~$RANLIB $lib~(cd $output_objdir && a2ixlibrary -32)' + hardcode_libdir_flag_spec_GCJ='-L$libdir' + hardcode_minus_L_GCJ=yes + + # Samuel A. Falvo II <kc5tja@dolphin.openprojects.net> reports + # that the semantics of dynamic libraries on AmigaOS, at least up + # to version 4, is to share data among multiple programs linked + # with the same dynamic library. Since this doesn't match the + # behavior of shared libraries on other platforms, we can't use + # them. + ld_shlibs_GCJ=no + ;; + + beos*) + if $LD --help 2>&1 | grep ': supported targets:.* elf' > /dev/null; then + allow_undefined_flag_GCJ=unsupported + # Joseph Beckenbach <jrb3@best.com> says some releases of gcc + # support --undefined. This deserves some investigation. FIXME + archive_cmds_GCJ='$CC -nostart $libobjs $deplibs $compiler_flags ${wl}-soname $wl$soname -o $lib' + else + ld_shlibs_GCJ=no + fi + ;; + + cygwin* | mingw* | pw32*) + # _LT_AC_TAGVAR(hardcode_libdir_flag_spec, GCJ) is actually meaningless, + # as there is no search path for DLLs. + hardcode_libdir_flag_spec_GCJ='-L$libdir' + allow_undefined_flag_GCJ=unsupported + always_export_symbols_GCJ=no + enable_shared_with_static_runtimes_GCJ=yes + export_symbols_cmds_GCJ='$NM $libobjs $convenience | $global_symbol_pipe | $SED -e '\''/^[BCDGRS] /s/.* \([^ ]*\)/\1 DATA/'\'' | $SED -e '\''/^[AITW] /s/.* //'\'' | sort | uniq > $export_symbols' + + if $LD --help 2>&1 | grep 'auto-import' > /dev/null; then + archive_cmds_GCJ='$CC -shared $libobjs $deplibs $compiler_flags -o $output_objdir/$soname ${wl}--enable-auto-image-base -Xlinker --out-implib -Xlinker $lib' + # If the export-symbols file already is a .def file (1st line + # is EXPORTS), use it as is; otherwise, prepend... + archive_expsym_cmds_GCJ='if test "x`$SED 1q $export_symbols`" = xEXPORTS; then + cp $export_symbols $output_objdir/$soname.def; + else + echo EXPORTS > $output_objdir/$soname.def; + cat $export_symbols >> $output_objdir/$soname.def; + fi~ + $CC -shared $output_objdir/$soname.def $libobjs $deplibs $compiler_flags -o $output_objdir/$soname ${wl}--enable-auto-image-base -Xlinker --out-implib -Xlinker $lib' + else + ld_shlibs_GCJ=no + fi + ;; + + interix3*) + hardcode_direct_GCJ=no + hardcode_shlibpath_var_GCJ=no + hardcode_libdir_flag_spec_GCJ='${wl}-rpath,$libdir' + export_dynamic_flag_spec_GCJ='${wl}-E' + # Hack: On Interix 3.x, we cannot compile PIC because of a broken gcc. + # Instead, shared libraries are loaded at an image base (0x10000000 by + # default) and relocated if they conflict, which is a slow very memory + # consuming and fragmenting process. To avoid this, we pick a random, + # 256 KiB-aligned image base between 0x50000000 and 0x6FFC0000 at link + # time. Moving up from 0x10000000 also allows more sbrk(2) space. + archive_cmds_GCJ='$CC -shared $pic_flag $libobjs $deplibs $compiler_flags ${wl}-h,$soname ${wl}--image-base,`expr ${RANDOM-$$} % 4096 / 2 \* 262144 + 1342177280` -o $lib' + archive_expsym_cmds_GCJ='sed "s,^,_," $export_symbols >$output_objdir/$soname.expsym~$CC -shared $pic_flag $libobjs $deplibs $compiler_flags ${wl}-h,$soname ${wl}--retain-symbols-file,$output_objdir/$soname.expsym ${wl}--image-base,`expr ${RANDOM-$$} % 4096 / 2 \* 262144 + 1342177280` -o $lib' + ;; + + linux*) + if $LD --help 2>&1 | grep ': supported targets:.* elf' > /dev/null; then + tmp_addflag= + case $cc_basename,$host_cpu in + pgcc*) # Portland Group C compiler + whole_archive_flag_spec_GCJ='${wl}--whole-archive`for conv in $convenience\"\"; do test -n \"$conv\" && new_convenience=\"$new_convenience,$conv\"; done; $echo \"$new_convenience\"` ${wl}--no-whole-archive' + tmp_addflag=' $pic_flag' + ;; + pgf77* | pgf90* | pgf95*) # Portland Group f77 and f90 compilers + whole_archive_flag_spec_GCJ='${wl}--whole-archive`for conv in $convenience\"\"; do test -n \"$conv\" && new_convenience=\"$new_convenience,$conv\"; done; $echo \"$new_convenience\"` ${wl}--no-whole-archive' + tmp_addflag=' $pic_flag -Mnomain' ;; + ecc*,ia64* | icc*,ia64*) # Intel C compiler on ia64 + tmp_addflag=' -i_dynamic' ;; + efc*,ia64* | ifort*,ia64*) # Intel Fortran compiler on ia64 + tmp_addflag=' -i_dynamic -nofor_main' ;; + ifc* | ifort*) # Intel Fortran compiler + tmp_addflag=' -nofor_main' ;; + esac + archive_cmds_GCJ='$CC -shared'"$tmp_addflag"' $libobjs $deplibs $compiler_flags ${wl}-soname $wl$soname -o $lib' + + if test $supports_anon_versioning = yes; then + archive_expsym_cmds_GCJ='$echo "{ global:" > $output_objdir/$libname.ver~ + cat $export_symbols | sed -e "s/\(.*\)/\1;/" >> $output_objdir/$libname.ver~ + $echo "local: *; };" >> $output_objdir/$libname.ver~ + $CC -shared'"$tmp_addflag"' $libobjs $deplibs $compiler_flags ${wl}-soname $wl$soname ${wl}-version-script ${wl}$output_objdir/$libname.ver -o $lib' + fi + else + ld_shlibs_GCJ=no + fi + ;; + + netbsd*) + if echo __ELF__ | $CC -E - | grep __ELF__ >/dev/null; then + archive_cmds_GCJ='$LD -Bshareable $libobjs $deplibs $linker_flags -o $lib' + wlarc= + else + archive_cmds_GCJ='$CC -shared $libobjs $deplibs $compiler_flags ${wl}-soname $wl$soname -o $lib' + archive_expsym_cmds_GCJ='$CC -shared $libobjs $deplibs $compiler_flags ${wl}-soname $wl$soname ${wl}-retain-symbols-file $wl$export_symbols -o $lib' + fi + ;; + + solaris*) + if $LD -v 2>&1 | grep 'BFD 2\.8' > /dev/null; then + ld_shlibs_GCJ=no + cat <<EOF 1>&2 + +*** Warning: The releases 2.8.* of the GNU linker cannot reliably +*** create shared libraries on Solaris systems. Therefore, libtool +*** is disabling shared libraries support. We urge you to upgrade GNU +*** binutils to release 2.9.1 or newer. Another option is to modify +*** your PATH or compiler configuration so that the native linker is +*** used, and then restart. + +EOF + elif $LD --help 2>&1 | grep ': supported targets:.* elf' > /dev/null; then + archive_cmds_GCJ='$CC -shared $libobjs $deplibs $compiler_flags ${wl}-soname $wl$soname -o $lib' + archive_expsym_cmds_GCJ='$CC -shared $libobjs $deplibs $compiler_flags ${wl}-soname $wl$soname ${wl}-retain-symbols-file $wl$export_symbols -o $lib' + else + ld_shlibs_GCJ=no + fi + ;; + + sysv5* | sco3.2v5* | sco5v6* | unixware* | OpenUNIX*) + case `$LD -v 2>&1` in + *\ [01].* | *\ 2.[0-9].* | *\ 2.1[0-5].*) + ld_shlibs_GCJ=no + cat <<_LT_EOF 1>&2 + +*** Warning: Releases of the GNU linker prior to 2.16.91.0.3 can not +*** reliably create shared libraries on SCO systems. Therefore, libtool +*** is disabling shared libraries support. We urge you to upgrade GNU +*** binutils to release 2.16.91.0.3 or newer. Another option is to modify +*** your PATH or compiler configuration so that the native linker is +*** used, and then restart. + +_LT_EOF + ;; + *) + if $LD --help 2>&1 | grep ': supported targets:.* elf' > /dev/null; then + hardcode_libdir_flag_spec_GCJ='`test -z "$SCOABSPATH" && echo ${wl}-rpath,$libdir`' + archive_cmds_GCJ='$CC -shared $libobjs $deplibs $compiler_flags ${wl}-soname,\${SCOABSPATH:+${install_libdir}/}$soname -o $lib' + archive_expsym_cmds_GCJ='$CC -shared $libobjs $deplibs $compiler_flags ${wl}-soname,\${SCOABSPATH:+${install_libdir}/}$soname,-retain-symbols-file,$export_symbols -o $lib' + else + ld_shlibs_GCJ=no + fi + ;; + esac + ;; + + sunos4*) + archive_cmds_GCJ='$LD -assert pure-text -Bshareable -o $lib $libobjs $deplibs $linker_flags' + wlarc= + hardcode_direct_GCJ=yes + hardcode_shlibpath_var_GCJ=no + ;; + + *) + if $LD --help 2>&1 | grep ': supported targets:.* elf' > /dev/null; then + archive_cmds_GCJ='$CC -shared $libobjs $deplibs $compiler_flags ${wl}-soname $wl$soname -o $lib' + archive_expsym_cmds_GCJ='$CC -shared $libobjs $deplibs $compiler_flags ${wl}-soname $wl$soname ${wl}-retain-symbols-file $wl$export_symbols -o $lib' + else + ld_shlibs_GCJ=no + fi + ;; + esac + + if test "$ld_shlibs_GCJ" = no; then + runpath_var= + hardcode_libdir_flag_spec_GCJ= + export_dynamic_flag_spec_GCJ= + whole_archive_flag_spec_GCJ= + fi + else + # PORTME fill in a description of your system's linker (not GNU ld) + case $host_os in + aix3*) + allow_undefined_flag_GCJ=unsupported + always_export_symbols_GCJ=yes + archive_expsym_cmds_GCJ='$LD -o $output_objdir/$soname $libobjs $deplibs $linker_flags -bE:$export_symbols -T512 -H512 -bM:SRE~$AR $AR_FLAGS $lib $output_objdir/$soname' + # Note: this linker hardcodes the directories in LIBPATH if there + # are no directories specified by -L. + hardcode_minus_L_GCJ=yes + if test "$GCC" = yes && test -z "$lt_prog_compiler_static"; then + # Neither direct hardcoding nor static linking is supported with a + # broken collect2. + hardcode_direct_GCJ=unsupported + fi + ;; + + aix4* | aix5*) + if test "$host_cpu" = ia64; then + # On IA64, the linker does run time linking by default, so we don't + # have to do anything special. + aix_use_runtimelinking=no + exp_sym_flag='-Bexport' + no_entry_flag="" + else + # If we're using GNU nm, then we don't want the "-C" option. + # -C means demangle to AIX nm, but means don't demangle with GNU nm + if $NM -V 2>&1 | grep 'GNU' > /dev/null; then + export_symbols_cmds_GCJ='$NM -Bpg $libobjs $convenience | awk '\''{ if (((\$2 == "T") || (\$2 == "D") || (\$2 == "B")) && (substr(\$3,1,1) != ".")) { print \$3 } }'\'' | sort -u > $export_symbols' + else + export_symbols_cmds_GCJ='$NM -BCpg $libobjs $convenience | awk '\''{ if (((\$2 == "T") || (\$2 == "D") || (\$2 == "B")) && (substr(\$3,1,1) != ".")) { print \$3 } }'\'' | sort -u > $export_symbols' + fi + aix_use_runtimelinking=no + + # Test if we are trying to use run time linking or normal + # AIX style linking. If -brtl is somewhere in LDFLAGS, we + # need to do runtime linking. + case $host_os in aix4.[23]|aix4.[23].*|aix5*) + for ld_flag in $LDFLAGS; do + if (test $ld_flag = "-brtl" || test $ld_flag = "-Wl,-brtl"); then + aix_use_runtimelinking=yes + break + fi + done + ;; + esac + + exp_sym_flag='-bexport' + no_entry_flag='-bnoentry' + fi + + # When large executables or shared objects are built, AIX ld can + # have problems creating the table of contents. If linking a library + # or program results in "error TOC overflow" add -mminimal-toc to + # CXXFLAGS/CFLAGS for g++/gcc. In the cases where that is not + # enough to fix the problem, add -Wl,-bbigtoc to LDFLAGS. + + archive_cmds_GCJ='' + hardcode_direct_GCJ=yes + hardcode_libdir_separator_GCJ=':' + link_all_deplibs_GCJ=yes + + if test "$GCC" = yes; then + case $host_os in aix4.[012]|aix4.[012].*) + # We only want to do this on AIX 4.2 and lower, the check + # below for broken collect2 doesn't work under 4.3+ + collect2name=`${CC} -print-prog-name=collect2` + if test -f "$collect2name" && \ + strings "$collect2name" | grep resolve_lib_name >/dev/null + then + # We have reworked collect2 + hardcode_direct_GCJ=yes + else + # We have old collect2 + hardcode_direct_GCJ=unsupported + # It fails to find uninstalled libraries when the uninstalled + # path is not listed in the libpath. Setting hardcode_minus_L + # to unsupported forces relinking + hardcode_minus_L_GCJ=yes + hardcode_libdir_flag_spec_GCJ='-L$libdir' + hardcode_libdir_separator_GCJ= + fi + ;; + esac + shared_flag='-shared' + if test "$aix_use_runtimelinking" = yes; then + shared_flag="$shared_flag "'${wl}-G' + fi + else + # not using gcc + if test "$host_cpu" = ia64; then + # VisualAge C++, Version 5.5 for AIX 5L for IA-64, Beta 3 Release + # chokes on -Wl,-G. The following line is correct: + shared_flag='-G' + else + if test "$aix_use_runtimelinking" = yes; then + shared_flag='${wl}-G' + else + shared_flag='${wl}-bM:SRE' + fi + fi + fi + + # It seems that -bexpall does not export symbols beginning with + # underscore (_), so it is better to generate a list of symbols to export. + always_export_symbols_GCJ=yes + if test "$aix_use_runtimelinking" = yes; then + # Warning - without using the other runtime loading flags (-brtl), + # -berok will link without error, but may produce a broken library. + allow_undefined_flag_GCJ='-berok' + # Determine the default libpath from the value encoded in an empty executable. + cat >conftest.$ac_ext <<_ACEOF +/* confdefs.h. */ +_ACEOF +cat confdefs.h >>conftest.$ac_ext +cat >>conftest.$ac_ext <<_ACEOF +/* end confdefs.h. */ + +int +main () +{ + + ; + return 0; +} +_ACEOF +rm -f conftest.$ac_objext conftest$ac_exeext +if { (eval echo "$as_me:$LINENO: \"$ac_link\"") >&5 + (eval $ac_link) 2>conftest.er1 + ac_status=$? + grep -v '^ *+' conftest.er1 >conftest.err + rm -f conftest.er1 + cat conftest.err >&5 + echo "$as_me:$LINENO: \$? = $ac_status" >&5 + (exit $ac_status); } && + { ac_try='test -z "$ac_c_werror_flag" + || test ! -s conftest.err' + { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5 + (eval $ac_try) 2>&5 + ac_status=$? + echo "$as_me:$LINENO: \$? = $ac_status" >&5 + (exit $ac_status); }; } && + { ac_try='test -s conftest$ac_exeext' + { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5 + (eval $ac_try) 2>&5 + ac_status=$? + echo "$as_me:$LINENO: \$? = $ac_status" >&5 + (exit $ac_status); }; }; then + +aix_libpath=`dump -H conftest$ac_exeext 2>/dev/null | $SED -n -e '/Import File Strings/,/^$/ { /^0/ { s/^0 *\(.*\)$/\1/; p; } +}'` +# Check for a 64-bit object if we didn't find anything. +if test -z "$aix_libpath"; then aix_libpath=`dump -HX64 conftest$ac_exeext 2>/dev/null | $SED -n -e '/Import File Strings/,/^$/ { /^0/ { s/^0 *\(.*\)$/\1/; p; } +}'`; fi +else + echo "$as_me: failed program was:" >&5 +sed 's/^/| /' conftest.$ac_ext >&5 + +fi +rm -f conftest.err conftest.$ac_objext \ + conftest$ac_exeext conftest.$ac_ext +if test -z "$aix_libpath"; then aix_libpath="/usr/lib:/lib"; fi + + hardcode_libdir_flag_spec_GCJ='${wl}-blibpath:$libdir:'"$aix_libpath" + archive_expsym_cmds_GCJ="\$CC"' -o $output_objdir/$soname $libobjs $deplibs '"\${wl}$no_entry_flag"' $compiler_flags `if test "x${allow_undefined_flag}" != "x"; then echo "${wl}${allow_undefined_flag}"; else :; fi` '"\${wl}$exp_sym_flag:\$export_symbols $shared_flag" + else + if test "$host_cpu" = ia64; then + hardcode_libdir_flag_spec_GCJ='${wl}-R $libdir:/usr/lib:/lib' + allow_undefined_flag_GCJ="-z nodefs" + archive_expsym_cmds_GCJ="\$CC $shared_flag"' -o $output_objdir/$soname $libobjs $deplibs '"\${wl}$no_entry_flag"' $compiler_flags ${wl}${allow_undefined_flag} '"\${wl}$exp_sym_flag:\$export_symbols" + else + # Determine the default libpath from the value encoded in an empty executable. + cat >conftest.$ac_ext <<_ACEOF +/* confdefs.h. */ +_ACEOF +cat confdefs.h >>conftest.$ac_ext +cat >>conftest.$ac_ext <<_ACEOF +/* end confdefs.h. */ + +int +main () +{ + + ; + return 0; +} +_ACEOF +rm -f conftest.$ac_objext conftest$ac_exeext +if { (eval echo "$as_me:$LINENO: \"$ac_link\"") >&5 + (eval $ac_link) 2>conftest.er1 + ac_status=$? + grep -v '^ *+' conftest.er1 >conftest.err + rm -f conftest.er1 + cat conftest.err >&5 + echo "$as_me:$LINENO: \$? = $ac_status" >&5 + (exit $ac_status); } && + { ac_try='test -z "$ac_c_werror_flag" + || test ! -s conftest.err' + { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5 + (eval $ac_try) 2>&5 + ac_status=$? + echo "$as_me:$LINENO: \$? = $ac_status" >&5 + (exit $ac_status); }; } && + { ac_try='test -s conftest$ac_exeext' + { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5 + (eval $ac_try) 2>&5 + ac_status=$? + echo "$as_me:$LINENO: \$? = $ac_status" >&5 + (exit $ac_status); }; }; then + +aix_libpath=`dump -H conftest$ac_exeext 2>/dev/null | $SED -n -e '/Import File Strings/,/^$/ { /^0/ { s/^0 *\(.*\)$/\1/; p; } +}'` +# Check for a 64-bit object if we didn't find anything. +if test -z "$aix_libpath"; then aix_libpath=`dump -HX64 conftest$ac_exeext 2>/dev/null | $SED -n -e '/Import File Strings/,/^$/ { /^0/ { s/^0 *\(.*\)$/\1/; p; } +}'`; fi +else + echo "$as_me: failed program was:" >&5 +sed 's/^/| /' conftest.$ac_ext >&5 + +fi +rm -f conftest.err conftest.$ac_objext \ + conftest$ac_exeext conftest.$ac_ext +if test -z "$aix_libpath"; then aix_libpath="/usr/lib:/lib"; fi + + hardcode_libdir_flag_spec_GCJ='${wl}-blibpath:$libdir:'"$aix_libpath" + # Warning - without using the other run time loading flags, + # -berok will link without error, but may produce a broken library. + no_undefined_flag_GCJ=' ${wl}-bernotok' + allow_undefined_flag_GCJ=' ${wl}-berok' + # Exported symbols can be pulled into shared objects from archives + whole_archive_flag_spec_GCJ='$convenience' + archive_cmds_need_lc_GCJ=yes + # This is similar to how AIX traditionally builds its shared libraries. + archive_expsym_cmds_GCJ="\$CC $shared_flag"' -o $output_objdir/$soname $libobjs $deplibs ${wl}-bnoentry $compiler_flags ${wl}-bE:$export_symbols${allow_undefined_flag}~$AR $AR_FLAGS $output_objdir/$libname$release.a $output_objdir/$soname' + fi + fi + ;; + + amigaos*) + archive_cmds_GCJ='$rm $output_objdir/a2ixlibrary.data~$echo "#define NAME $libname" > $output_objdir/a2ixlibrary.data~$echo "#define LIBRARY_ID 1" >> $output_objdir/a2ixlibrary.data~$echo "#define VERSION $major" >> $output_objdir/a2ixlibrary.data~$echo "#define REVISION $revision" >> $output_objdir/a2ixlibrary.data~$AR $AR_FLAGS $lib $libobjs~$RANLIB $lib~(cd $output_objdir && a2ixlibrary -32)' + hardcode_libdir_flag_spec_GCJ='-L$libdir' + hardcode_minus_L_GCJ=yes + # see comment about different semantics on the GNU ld section + ld_shlibs_GCJ=no + ;; + + bsdi[45]*) + export_dynamic_flag_spec_GCJ=-rdynamic + ;; + + cygwin* | mingw* | pw32*) + # When not using gcc, we currently assume that we are using + # Microsoft Visual C++. + # hardcode_libdir_flag_spec is actually meaningless, as there is + # no search path for DLLs. + hardcode_libdir_flag_spec_GCJ=' ' + allow_undefined_flag_GCJ=unsupported + # Tell ltmain to make .lib files, not .a files. + libext=lib + # Tell ltmain to make .dll files, not .so files. + shrext_cmds=".dll" + # FIXME: Setting linknames here is a bad hack. + archive_cmds_GCJ='$CC -o $lib $libobjs $compiler_flags `echo "$deplibs" | $SED -e '\''s/ -lc$//'\''` -link -dll~linknames=' + # The linker will automatically build a .lib file if we build a DLL. + old_archive_From_new_cmds_GCJ='true' + # FIXME: Should let the user specify the lib program. + old_archive_cmds_GCJ='lib /OUT:$oldlib$oldobjs$old_deplibs' + fix_srcfile_path_GCJ='`cygpath -w "$srcfile"`' + enable_shared_with_static_runtimes_GCJ=yes + ;; + + darwin* | rhapsody*) + case $host_os in + rhapsody* | darwin1.[012]) + allow_undefined_flag_GCJ='${wl}-undefined ${wl}suppress' + ;; + *) # Darwin 1.3 on + if test -z ${MACOSX_DEPLOYMENT_TARGET} ; then + allow_undefined_flag_GCJ='${wl}-flat_namespace ${wl}-undefined ${wl}suppress' + else + case ${MACOSX_DEPLOYMENT_TARGET} in + 10.[012]) + allow_undefined_flag_GCJ='${wl}-flat_namespace ${wl}-undefined ${wl}suppress' + ;; + 10.*) + allow_undefined_flag_GCJ='${wl}-undefined ${wl}dynamic_lookup' + ;; + esac + fi + ;; + esac + archive_cmds_need_lc_GCJ=no + hardcode_direct_GCJ=no + hardcode_automatic_GCJ=yes + hardcode_shlibpath_var_GCJ=unsupported + whole_archive_flag_spec_GCJ='' + link_all_deplibs_GCJ=yes + if test "$GCC" = yes ; then + output_verbose_link_cmd='echo' + archive_cmds_GCJ='$CC -dynamiclib $allow_undefined_flag -o $lib $libobjs $deplibs $compiler_flags -install_name $rpath/$soname $verstring' + module_cmds_GCJ='$CC $allow_undefined_flag -o $lib -bundle $libobjs $deplibs$compiler_flags' + # Don't fix this by using the ld -exported_symbols_list flag, it doesn't exist in older darwin lds + archive_expsym_cmds_GCJ='sed -e "s,#.*,," -e "s,^[ ]*,," -e "s,^\(..*\),_&," < $export_symbols > $output_objdir/${libname}-symbols.expsym~$CC -dynamiclib $allow_undefined_flag -o $lib $libobjs $deplibs $compiler_flags -install_name $rpath/$soname $verstring~nmedit -s $output_objdir/${libname}-symbols.expsym ${lib}' + module_expsym_cmds_GCJ='sed -e "s,#.*,," -e "s,^[ ]*,," -e "s,^\(..*\),_&," < $export_symbols > $output_objdir/${libname}-symbols.expsym~$CC $allow_undefined_flag -o $lib -bundle $libobjs $deplibs$compiler_flags~nmedit -s $output_objdir/${libname}-symbols.expsym ${lib}' + else + case $cc_basename in + xlc*) + output_verbose_link_cmd='echo' + archive_cmds_GCJ='$CC -qmkshrobj $allow_undefined_flag -o $lib $libobjs $deplibs $compiler_flags ${wl}-install_name ${wl}`echo $rpath/$soname` $verstring' + module_cmds_GCJ='$CC $allow_undefined_flag -o $lib -bundle $libobjs $deplibs$compiler_flags' + # Don't fix this by using the ld -exported_symbols_list flag, it doesn't exist in older darwin lds + archive_expsym_cmds_GCJ='sed -e "s,#.*,," -e "s,^[ ]*,," -e "s,^\(..*\),_&," < $export_symbols > $output_objdir/${libname}-symbols.expsym~$CC -qmkshrobj $allow_undefined_flag -o $lib $libobjs $deplibs $compiler_flags ${wl}-install_name ${wl}$rpath/$soname $verstring~nmedit -s $output_objdir/${libname}-symbols.expsym ${lib}' + module_expsym_cmds_GCJ='sed -e "s,#.*,," -e "s,^[ ]*,," -e "s,^\(..*\),_&," < $export_symbols > $output_objdir/${libname}-symbols.expsym~$CC $allow_undefined_flag -o $lib -bundle $libobjs $deplibs$compiler_flags~nmedit -s $output_objdir/${libname}-symbols.expsym ${lib}' + ;; + *) + ld_shlibs_GCJ=no + ;; + esac + fi + ;; + + dgux*) + archive_cmds_GCJ='$LD -G -h $soname -o $lib $libobjs $deplibs $linker_flags' + hardcode_libdir_flag_spec_GCJ='-L$libdir' + hardcode_shlibpath_var_GCJ=no + ;; + + freebsd1*) + ld_shlibs_GCJ=no + ;; + + # FreeBSD 2.2.[012] allows us to include c++rt0.o to get C++ constructor + # support. Future versions do this automatically, but an explicit c++rt0.o + # does not break anything, and helps significantly (at the cost of a little + # extra space). + freebsd2.2*) + archive_cmds_GCJ='$LD -Bshareable -o $lib $libobjs $deplibs $linker_flags /usr/lib/c++rt0.o' + hardcode_libdir_flag_spec_GCJ='-R$libdir' + hardcode_direct_GCJ=yes + hardcode_shlibpath_var_GCJ=no + ;; + + # Unfortunately, older versions of FreeBSD 2 do not have this feature. + freebsd2*) + archive_cmds_GCJ='$LD -Bshareable -o $lib $libobjs $deplibs $linker_flags' + hardcode_direct_GCJ=yes + hardcode_minus_L_GCJ=yes + hardcode_shlibpath_var_GCJ=no + ;; + + # FreeBSD 3 and greater uses gcc -shared to do shared libraries. + freebsd* | kfreebsd*-gnu | dragonfly*) + archive_cmds_GCJ='$CC -shared -o $lib $libobjs $deplibs $compiler_flags' + hardcode_libdir_flag_spec_GCJ='-R$libdir' + hardcode_direct_GCJ=yes + hardcode_shlibpath_var_GCJ=no + ;; + + hpux9*) + if test "$GCC" = yes; then + archive_cmds_GCJ='$rm $output_objdir/$soname~$CC -shared -fPIC ${wl}+b ${wl}$install_libdir -o $output_objdir/$soname $libobjs $deplibs $compiler_flags~test $output_objdir/$soname = $lib || mv $output_objdir/$soname $lib' + else + archive_cmds_GCJ='$rm $output_objdir/$soname~$LD -b +b $install_libdir -o $output_objdir/$soname $libobjs $deplibs $linker_flags~test $output_objdir/$soname = $lib || mv $output_objdir/$soname $lib' + fi + hardcode_libdir_flag_spec_GCJ='${wl}+b ${wl}$libdir' + hardcode_libdir_separator_GCJ=: + hardcode_direct_GCJ=yes + + # hardcode_minus_L: Not really in the search PATH, + # but as the default location of the library. + hardcode_minus_L_GCJ=yes + export_dynamic_flag_spec_GCJ='${wl}-E' + ;; + + hpux10*) + if test "$GCC" = yes -a "$with_gnu_ld" = no; then + archive_cmds_GCJ='$CC -shared -fPIC ${wl}+h ${wl}$soname ${wl}+b ${wl}$install_libdir -o $lib $libobjs $deplibs $compiler_flags' + else + archive_cmds_GCJ='$LD -b +h $soname +b $install_libdir -o $lib $libobjs $deplibs $linker_flags' + fi + if test "$with_gnu_ld" = no; then + hardcode_libdir_flag_spec_GCJ='${wl}+b ${wl}$libdir' + hardcode_libdir_separator_GCJ=: + + hardcode_direct_GCJ=yes + export_dynamic_flag_spec_GCJ='${wl}-E' + + # hardcode_minus_L: Not really in the search PATH, + # but as the default location of the library. + hardcode_minus_L_GCJ=yes + fi + ;; + + hpux11*) + if test "$GCC" = yes -a "$with_gnu_ld" = no; then + case $host_cpu in + hppa*64*) + archive_cmds_GCJ='$CC -shared ${wl}+h ${wl}$soname -o $lib $libobjs $deplibs $compiler_flags' + ;; + ia64*) + archive_cmds_GCJ='$CC -shared ${wl}+h ${wl}$soname ${wl}+nodefaultrpath -o $lib $libobjs $deplibs $compiler_flags' + ;; + *) + archive_cmds_GCJ='$CC -shared -fPIC ${wl}+h ${wl}$soname ${wl}+b ${wl}$install_libdir -o $lib $libobjs $deplibs $compiler_flags' + ;; + esac + else + case $host_cpu in + hppa*64*) + archive_cmds_GCJ='$CC -b ${wl}+h ${wl}$soname -o $lib $libobjs $deplibs $compiler_flags' + ;; + ia64*) + archive_cmds_GCJ='$CC -b ${wl}+h ${wl}$soname ${wl}+nodefaultrpath -o $lib $libobjs $deplibs $compiler_flags' + ;; + *) + archive_cmds_GCJ='$CC -b ${wl}+h ${wl}$soname ${wl}+b ${wl}$install_libdir -o $lib $libobjs $deplibs $compiler_flags' + ;; + esac + fi + if test "$with_gnu_ld" = no; then + hardcode_libdir_flag_spec_GCJ='${wl}+b ${wl}$libdir' + hardcode_libdir_separator_GCJ=: + + case $host_cpu in + hppa*64*|ia64*) + hardcode_libdir_flag_spec_ld_GCJ='+b $libdir' + hardcode_direct_GCJ=no + hardcode_shlibpath_var_GCJ=no + ;; + *) + hardcode_direct_GCJ=yes + export_dynamic_flag_spec_GCJ='${wl}-E' + + # hardcode_minus_L: Not really in the search PATH, + # but as the default location of the library. + hardcode_minus_L_GCJ=yes + ;; + esac + fi + ;; + + irix5* | irix6* | nonstopux*) + if test "$GCC" = yes; then + archive_cmds_GCJ='$CC -shared $libobjs $deplibs $compiler_flags ${wl}-soname ${wl}$soname `test -n "$verstring" && echo ${wl}-set_version ${wl}$verstring` ${wl}-update_registry ${wl}${output_objdir}/so_locations -o $lib' + else + archive_cmds_GCJ='$LD -shared $libobjs $deplibs $linker_flags -soname $soname `test -n "$verstring" && echo -set_version $verstring` -update_registry ${output_objdir}/so_locations -o $lib' + hardcode_libdir_flag_spec_ld_GCJ='-rpath $libdir' + fi + hardcode_libdir_flag_spec_GCJ='${wl}-rpath ${wl}$libdir' + hardcode_libdir_separator_GCJ=: + link_all_deplibs_GCJ=yes + ;; + + netbsd*) + if echo __ELF__ | $CC -E - | grep __ELF__ >/dev/null; then + archive_cmds_GCJ='$LD -Bshareable -o $lib $libobjs $deplibs $linker_flags' # a.out + else + archive_cmds_GCJ='$LD -shared -o $lib $libobjs $deplibs $linker_flags' # ELF + fi + hardcode_libdir_flag_spec_GCJ='-R$libdir' + hardcode_direct_GCJ=yes + hardcode_shlibpath_var_GCJ=no + ;; + + newsos6) + archive_cmds_GCJ='$LD -G -h $soname -o $lib $libobjs $deplibs $linker_flags' + hardcode_direct_GCJ=yes + hardcode_libdir_flag_spec_GCJ='${wl}-rpath ${wl}$libdir' + hardcode_libdir_separator_GCJ=: + hardcode_shlibpath_var_GCJ=no + ;; + + openbsd*) + hardcode_direct_GCJ=yes + hardcode_shlibpath_var_GCJ=no + if test -z "`echo __ELF__ | $CC -E - | grep __ELF__`" || test "$host_os-$host_cpu" = "openbsd2.8-powerpc"; then + archive_cmds_GCJ='$CC -shared $pic_flag -o $lib $libobjs $deplibs $compiler_flags' + archive_expsym_cmds_GCJ='$CC -shared $pic_flag -o $lib $libobjs $deplibs $compiler_flags ${wl}-retain-symbols-file,$export_symbols' + hardcode_libdir_flag_spec_GCJ='${wl}-rpath,$libdir' + export_dynamic_flag_spec_GCJ='${wl}-E' + else + case $host_os in + openbsd[01].* | openbsd2.[0-7] | openbsd2.[0-7].*) + archive_cmds_GCJ='$LD -Bshareable -o $lib $libobjs $deplibs $linker_flags' + hardcode_libdir_flag_spec_GCJ='-R$libdir' + ;; + *) + archive_cmds_GCJ='$CC -shared $pic_flag -o $lib $libobjs $deplibs $compiler_flags' + hardcode_libdir_flag_spec_GCJ='${wl}-rpath,$libdir' + ;; + esac + fi + ;; + + os2*) + hardcode_libdir_flag_spec_GCJ='-L$libdir' + hardcode_minus_L_GCJ=yes + allow_undefined_flag_GCJ=unsupported + archive_cmds_GCJ='$echo "LIBRARY $libname INITINSTANCE" > $output_objdir/$libname.def~$echo "DESCRIPTION \"$libname\"" >> $output_objdir/$libname.def~$echo DATA >> $output_objdir/$libname.def~$echo " SINGLE NONSHARED" >> $output_objdir/$libname.def~$echo EXPORTS >> $output_objdir/$libname.def~emxexp $libobjs >> $output_objdir/$libname.def~$CC -Zdll -Zcrtdll -o $lib $libobjs $deplibs $compiler_flags $output_objdir/$libname.def' + old_archive_From_new_cmds_GCJ='emximp -o $output_objdir/$libname.a $output_objdir/$libname.def' + ;; + + osf3*) + if test "$GCC" = yes; then + allow_undefined_flag_GCJ=' ${wl}-expect_unresolved ${wl}\*' + archive_cmds_GCJ='$CC -shared${allow_undefined_flag} $libobjs $deplibs $compiler_flags ${wl}-soname ${wl}$soname `test -n "$verstring" && echo ${wl}-set_version ${wl}$verstring` ${wl}-update_registry ${wl}${output_objdir}/so_locations -o $lib' + else + allow_undefined_flag_GCJ=' -expect_unresolved \*' + archive_cmds_GCJ='$LD -shared${allow_undefined_flag} $libobjs $deplibs $linker_flags -soname $soname `test -n "$verstring" && echo -set_version $verstring` -update_registry ${output_objdir}/so_locations -o $lib' + fi + hardcode_libdir_flag_spec_GCJ='${wl}-rpath ${wl}$libdir' + hardcode_libdir_separator_GCJ=: + ;; + + osf4* | osf5*) # as osf3* with the addition of -msym flag + if test "$GCC" = yes; then + allow_undefined_flag_GCJ=' ${wl}-expect_unresolved ${wl}\*' + archive_cmds_GCJ='$CC -shared${allow_undefined_flag} $libobjs $deplibs $compiler_flags ${wl}-msym ${wl}-soname ${wl}$soname `test -n "$verstring" && echo ${wl}-set_version ${wl}$verstring` ${wl}-update_registry ${wl}${output_objdir}/so_locations -o $lib' + hardcode_libdir_flag_spec_GCJ='${wl}-rpath ${wl}$libdir' + else + allow_undefined_flag_GCJ=' -expect_unresolved \*' + archive_cmds_GCJ='$LD -shared${allow_undefined_flag} $libobjs $deplibs $linker_flags -msym -soname $soname `test -n "$verstring" && echo -set_version $verstring` -update_registry ${output_objdir}/so_locations -o $lib' + archive_expsym_cmds_GCJ='for i in `cat $export_symbols`; do printf "%s %s\\n" -exported_symbol "\$i" >> $lib.exp; done; echo "-hidden">> $lib.exp~ + $LD -shared${allow_undefined_flag} -input $lib.exp $linker_flags $libobjs $deplibs -soname $soname `test -n "$verstring" && echo -set_version $verstring` -update_registry ${output_objdir}/so_locations -o $lib~$rm $lib.exp' + + # Both c and cxx compiler support -rpath directly + hardcode_libdir_flag_spec_GCJ='-rpath $libdir' + fi + hardcode_libdir_separator_GCJ=: + ;; + + solaris*) + no_undefined_flag_GCJ=' -z text' + if test "$GCC" = yes; then + wlarc='${wl}' + archive_cmds_GCJ='$CC -shared ${wl}-h ${wl}$soname -o $lib $libobjs $deplibs $compiler_flags' + archive_expsym_cmds_GCJ='$echo "{ global:" > $lib.exp~cat $export_symbols | $SED -e "s/\(.*\)/\1;/" >> $lib.exp~$echo "local: *; };" >> $lib.exp~ + $CC -shared ${wl}-M ${wl}$lib.exp ${wl}-h ${wl}$soname -o $lib $libobjs $deplibs $compiler_flags~$rm $lib.exp' + else + wlarc='' + archive_cmds_GCJ='$LD -G${allow_undefined_flag} -h $soname -o $lib $libobjs $deplibs $linker_flags' + archive_expsym_cmds_GCJ='$echo "{ global:" > $lib.exp~cat $export_symbols | $SED -e "s/\(.*\)/\1;/" >> $lib.exp~$echo "local: *; };" >> $lib.exp~ + $LD -G${allow_undefined_flag} -M $lib.exp -h $soname -o $lib $libobjs $deplibs $linker_flags~$rm $lib.exp' + fi + hardcode_libdir_flag_spec_GCJ='-R$libdir' + hardcode_shlibpath_var_GCJ=no + case $host_os in + solaris2.[0-5] | solaris2.[0-5].*) ;; + *) + # The compiler driver will combine linker options so we + # cannot just pass the convience library names through + # without $wl, iff we do not link with $LD. + # Luckily, gcc supports the same syntax we need for Sun Studio. + # Supported since Solaris 2.6 (maybe 2.5.1?) + case $wlarc in + '') + whole_archive_flag_spec_GCJ='-z allextract$convenience -z defaultextract' ;; + *) + whole_archive_flag_spec_GCJ='${wl}-z ${wl}allextract`for conv in $convenience\"\"; do test -n \"$conv\" && new_convenience=\"$new_convenience,$conv\"; done; $echo \"$new_convenience\"` ${wl}-z ${wl}defaultextract' ;; + esac ;; + esac + link_all_deplibs_GCJ=yes + ;; + + sunos4*) + if test "x$host_vendor" = xsequent; then + # Use $CC to link under sequent, because it throws in some extra .o + # files that make .init and .fini sections work. + archive_cmds_GCJ='$CC -G ${wl}-h $soname -o $lib $libobjs $deplibs $compiler_flags' + else + archive_cmds_GCJ='$LD -assert pure-text -Bstatic -o $lib $libobjs $deplibs $linker_flags' + fi + hardcode_libdir_flag_spec_GCJ='-L$libdir' + hardcode_direct_GCJ=yes + hardcode_minus_L_GCJ=yes + hardcode_shlibpath_var_GCJ=no + ;; + + sysv4) + case $host_vendor in + sni) + archive_cmds_GCJ='$LD -G -h $soname -o $lib $libobjs $deplibs $linker_flags' + hardcode_direct_GCJ=yes # is this really true??? + ;; + siemens) + ## LD is ld it makes a PLAMLIB + ## CC just makes a GrossModule. + archive_cmds_GCJ='$LD -G -o $lib $libobjs $deplibs $linker_flags' + reload_cmds_GCJ='$CC -r -o $output$reload_objs' + hardcode_direct_GCJ=no + ;; + motorola) + archive_cmds_GCJ='$LD -G -h $soname -o $lib $libobjs $deplibs $linker_flags' + hardcode_direct_GCJ=no #Motorola manual says yes, but my tests say they lie + ;; + esac + runpath_var='LD_RUN_PATH' + hardcode_shlibpath_var_GCJ=no + ;; + + sysv4.3*) + archive_cmds_GCJ='$LD -G -h $soname -o $lib $libobjs $deplibs $linker_flags' + hardcode_shlibpath_var_GCJ=no + export_dynamic_flag_spec_GCJ='-Bexport' + ;; + + sysv4*MP*) + if test -d /usr/nec; then + archive_cmds_GCJ='$LD -G -h $soname -o $lib $libobjs $deplibs $linker_flags' + hardcode_shlibpath_var_GCJ=no + runpath_var=LD_RUN_PATH + hardcode_runpath_var=yes + ld_shlibs_GCJ=yes + fi + ;; + + sysv4*uw2* | sysv5OpenUNIX* | sysv5UnixWare7.[01].[10]* | unixware7*) + no_undefined_flag_GCJ='${wl}-z,text' + archive_cmds_need_lc_GCJ=no + hardcode_shlibpath_var_GCJ=no + runpath_var='LD_RUN_PATH' + + if test "$GCC" = yes; then + archive_cmds_GCJ='$CC -shared ${wl}-h,$soname -o $lib $libobjs $deplibs $compiler_flags' + archive_expsym_cmds_GCJ='$CC -shared ${wl}-Bexport:$export_symbols ${wl}-h,$soname -o $lib $libobjs $deplibs $compiler_flags' + else + archive_cmds_GCJ='$CC -G ${wl}-h,$soname -o $lib $libobjs $deplibs $compiler_flags' + archive_expsym_cmds_GCJ='$CC -G ${wl}-Bexport:$export_symbols ${wl}-h,$soname -o $lib $libobjs $deplibs $compiler_flags' + fi + ;; + + sysv5* | sco3.2v5* | sco5v6*) + # Note: We can NOT use -z defs as we might desire, because we do not + # link with -lc, and that would cause any symbols used from libc to + # always be unresolved, which means just about no library would + # ever link correctly. If we're not using GNU ld we use -z text + # though, which does catch some bad symbols but isn't as heavy-handed + # as -z defs. + no_undefined_flag_GCJ='${wl}-z,text' + allow_undefined_flag_GCJ='${wl}-z,nodefs' + archive_cmds_need_lc_GCJ=no + hardcode_shlibpath_var_GCJ=no + hardcode_libdir_flag_spec_GCJ='`test -z "$SCOABSPATH" && echo ${wl}-R,$libdir`' + hardcode_libdir_separator_GCJ=':' + link_all_deplibs_GCJ=yes + export_dynamic_flag_spec_GCJ='${wl}-Bexport' + runpath_var='LD_RUN_PATH' + + if test "$GCC" = yes; then + archive_cmds_GCJ='$CC -shared ${wl}-h,\${SCOABSPATH:+${install_libdir}/}$soname -o $lib $libobjs $deplibs $compiler_flags' + archive_expsym_cmds_GCJ='$CC -shared ${wl}-Bexport:$export_symbols ${wl}-h,\${SCOABSPATH:+${install_libdir}/}$soname -o $lib $libobjs $deplibs $compiler_flags' + else + archive_cmds_GCJ='$CC -G ${wl}-h,\${SCOABSPATH:+${install_libdir}/}$soname -o $lib $libobjs $deplibs $compiler_flags' + archive_expsym_cmds_GCJ='$CC -G ${wl}-Bexport:$export_symbols ${wl}-h,\${SCOABSPATH:+${install_libdir}/}$soname -o $lib $libobjs $deplibs $compiler_flags' + fi + ;; + + uts4*) + archive_cmds_GCJ='$LD -G -h $soname -o $lib $libobjs $deplibs $linker_flags' + hardcode_libdir_flag_spec_GCJ='-L$libdir' + hardcode_shlibpath_var_GCJ=no + ;; + + *) + ld_shlibs_GCJ=no + ;; + esac + fi + +echo "$as_me:$LINENO: result: $ld_shlibs_GCJ" >&5 +echo "${ECHO_T}$ld_shlibs_GCJ" >&6 +test "$ld_shlibs_GCJ" = no && can_build_shared=no + +# +# Do we need to explicitly link libc? +# +case "x$archive_cmds_need_lc_GCJ" in +x|xyes) + # Assume -lc should be added + archive_cmds_need_lc_GCJ=yes + + if test "$enable_shared" = yes && test "$GCC" = yes; then + case $archive_cmds_GCJ in + *'~'*) + # FIXME: we may have to deal with multi-command sequences. + ;; + '$CC '*) + # Test whether the compiler implicitly links with -lc since on some + # systems, -lgcc has to come before -lc. If gcc already passes -lc + # to ld, don't add -lc before -lgcc. + echo "$as_me:$LINENO: checking whether -lc should be explicitly linked in" >&5 +echo $ECHO_N "checking whether -lc should be explicitly linked in... $ECHO_C" >&6 + $rm conftest* + printf "$lt_simple_compile_test_code" > conftest.$ac_ext + + if { (eval echo "$as_me:$LINENO: \"$ac_compile\"") >&5 + (eval $ac_compile) 2>&5 + ac_status=$? + echo "$as_me:$LINENO: \$? = $ac_status" >&5 + (exit $ac_status); } 2>conftest.err; then + soname=conftest + lib=conftest + libobjs=conftest.$ac_objext + deplibs= + wl=$lt_prog_compiler_wl_GCJ + pic_flag=$lt_prog_compiler_pic_GCJ + compiler_flags=-v + linker_flags=-v + verstring= + output_objdir=. + libname=conftest + lt_save_allow_undefined_flag=$allow_undefined_flag_GCJ + allow_undefined_flag_GCJ= + if { (eval echo "$as_me:$LINENO: \"$archive_cmds_GCJ 2\>\&1 \| grep \" -lc \" \>/dev/null 2\>\&1\"") >&5 + (eval $archive_cmds_GCJ 2\>\&1 \| grep \" -lc \" \>/dev/null 2\>\&1) 2>&5 + ac_status=$? + echo "$as_me:$LINENO: \$? = $ac_status" >&5 + (exit $ac_status); } + then + archive_cmds_need_lc_GCJ=no + else + archive_cmds_need_lc_GCJ=yes + fi + allow_undefined_flag_GCJ=$lt_save_allow_undefined_flag + else + cat conftest.err 1>&5 + fi + $rm conftest* + echo "$as_me:$LINENO: result: $archive_cmds_need_lc_GCJ" >&5 +echo "${ECHO_T}$archive_cmds_need_lc_GCJ" >&6 + ;; + esac + fi + ;; +esac + +echo "$as_me:$LINENO: checking dynamic linker characteristics" >&5 +echo $ECHO_N "checking dynamic linker characteristics... $ECHO_C" >&6 +library_names_spec= +libname_spec='lib$name' +soname_spec= +shrext_cmds=".so" +postinstall_cmds= +postuninstall_cmds= +finish_cmds= +finish_eval= +shlibpath_var= +shlibpath_overrides_runpath=unknown +version_type=none +dynamic_linker="$host_os ld.so" +sys_lib_dlsearch_path_spec="/lib /usr/lib" +if test "$GCC" = yes; then + sys_lib_search_path_spec=`$CC -print-search-dirs | grep "^libraries:" | $SED -e "s/^libraries://" -e "s,=/,/,g"` + if echo "$sys_lib_search_path_spec" | grep ';' >/dev/null ; then + # if the path contains ";" then we assume it to be the separator + # otherwise default to the standard path separator (i.e. ":") - it is + # assumed that no part of a normal pathname contains ";" but that should + # okay in the real world where ";" in dirpaths is itself problematic. + sys_lib_search_path_spec=`echo "$sys_lib_search_path_spec" | $SED -e 's/;/ /g'` + else + sys_lib_search_path_spec=`echo "$sys_lib_search_path_spec" | $SED -e "s/$PATH_SEPARATOR/ /g"` + fi +else + sys_lib_search_path_spec="/lib /usr/lib /usr/local/lib" +fi +need_lib_prefix=unknown +hardcode_into_libs=no + +# when you set need_version to no, make sure it does not cause -set_version +# flags to be left without arguments +need_version=unknown + +case $host_os in +aix3*) + version_type=linux + library_names_spec='${libname}${release}${shared_ext}$versuffix $libname.a' + shlibpath_var=LIBPATH + + # AIX 3 has no versioning support, so we append a major version to the name. + soname_spec='${libname}${release}${shared_ext}$major' + ;; + +aix4* | aix5*) + version_type=linux + need_lib_prefix=no + need_version=no + hardcode_into_libs=yes + if test "$host_cpu" = ia64; then + # AIX 5 supports IA64 + library_names_spec='${libname}${release}${shared_ext}$major ${libname}${release}${shared_ext}$versuffix $libname${shared_ext}' + shlibpath_var=LD_LIBRARY_PATH + else + # With GCC up to 2.95.x, collect2 would create an import file + # for dependence libraries. The import file would start with + # the line `#! .'. This would cause the generated library to + # depend on `.', always an invalid library. This was fixed in + # development snapshots of GCC prior to 3.0. + case $host_os in + aix4 | aix4.[01] | aix4.[01].*) + if { echo '#if __GNUC__ > 2 || (__GNUC__ == 2 && __GNUC_MINOR__ >= 97)' + echo ' yes ' + echo '#endif'; } | ${CC} -E - | grep yes > /dev/null; then + : + else + can_build_shared=no + fi + ;; + esac + # AIX (on Power*) has no versioning support, so currently we can not hardcode correct + # soname into executable. Probably we can add versioning support to + # collect2, so additional links can be useful in future. + if test "$aix_use_runtimelinking" = yes; then + # If using run time linking (on AIX 4.2 or later) use lib<name>.so + # instead of lib<name>.a to let people know that these are not + # typical AIX shared libraries. + library_names_spec='${libname}${release}${shared_ext}$versuffix ${libname}${release}${shared_ext}$major $libname${shared_ext}' + else + # We preserve .a as extension for shared libraries through AIX4.2 + # and later when we are not doing run time linking. + library_names_spec='${libname}${release}.a $libname.a' + soname_spec='${libname}${release}${shared_ext}$major' + fi + shlibpath_var=LIBPATH + fi + ;; + +amigaos*) + library_names_spec='$libname.ixlibrary $libname.a' + # Create ${libname}_ixlibrary.a entries in /sys/libs. + finish_eval='for lib in `ls $libdir/*.ixlibrary 2>/dev/null`; do libname=`$echo "X$lib" | $Xsed -e '\''s%^.*/\([^/]*\)\.ixlibrary$%\1%'\''`; test $rm /sys/libs/${libname}_ixlibrary.a; $show "cd /sys/libs && $LN_S $lib ${libname}_ixlibrary.a"; cd /sys/libs && $LN_S $lib ${libname}_ixlibrary.a || exit 1; done' + ;; + +beos*) + library_names_spec='${libname}${shared_ext}' + dynamic_linker="$host_os ld.so" + shlibpath_var=LIBRARY_PATH + ;; + +bsdi[45]*) + version_type=linux + need_version=no + library_names_spec='${libname}${release}${shared_ext}$versuffix ${libname}${release}${shared_ext}$major $libname${shared_ext}' + soname_spec='${libname}${release}${shared_ext}$major' + finish_cmds='PATH="\$PATH:/sbin" ldconfig $libdir' + shlibpath_var=LD_LIBRARY_PATH + sys_lib_search_path_spec="/shlib /usr/lib /usr/X11/lib /usr/contrib/lib /lib /usr/local/lib" + sys_lib_dlsearch_path_spec="/shlib /usr/lib /usr/local/lib" + # the default ld.so.conf also contains /usr/contrib/lib and + # /usr/X11R6/lib (/usr/X11 is a link to /usr/X11R6), but let us allow + # libtool to hard-code these into programs + ;; + +cygwin* | mingw* | pw32*) + version_type=windows + shrext_cmds=".dll" + need_version=no + need_lib_prefix=no + + case $GCC,$host_os in + yes,cygwin* | yes,mingw* | yes,pw32*) + library_names_spec='$libname.dll.a' + # DLL is installed to $(libdir)/../bin by postinstall_cmds + postinstall_cmds='base_file=`basename \${file}`~ + dlpath=`$SHELL 2>&1 -c '\''. $dir/'\''\${base_file}'\''i;echo \$dlname'\''`~ + dldir=$destdir/`dirname \$dlpath`~ + test -d \$dldir || mkdir -p \$dldir~ + $install_prog $dir/$dlname \$dldir/$dlname~ + chmod a+x \$dldir/$dlname' + postuninstall_cmds='dldll=`$SHELL 2>&1 -c '\''. $file; echo \$dlname'\''`~ + dlpath=$dir/\$dldll~ + $rm \$dlpath' + shlibpath_overrides_runpath=yes + + case $host_os in + cygwin*) + # Cygwin DLLs use 'cyg' prefix rather than 'lib' + soname_spec='`echo ${libname} | sed -e 's/^lib/cyg/'``echo ${release} | $SED -e 's/[.]/-/g'`${versuffix}${shared_ext}' + sys_lib_search_path_spec="/usr/lib /lib/w32api /lib /usr/local/lib" + ;; + mingw*) + # MinGW DLLs use traditional 'lib' prefix + soname_spec='${libname}`echo ${release} | $SED -e 's/[.]/-/g'`${versuffix}${shared_ext}' + sys_lib_search_path_spec=`$CC -print-search-dirs | grep "^libraries:" | $SED -e "s/^libraries://" -e "s,=/,/,g"` + if echo "$sys_lib_search_path_spec" | grep ';[c-zC-Z]:/' >/dev/null; then + # It is most probably a Windows format PATH printed by + # mingw gcc, but we are running on Cygwin. Gcc prints its search + # path with ; separators, and with drive letters. We can handle the + # drive letters (cygwin fileutils understands them), so leave them, + # especially as we might pass files found there to a mingw objdump, + # which wouldn't understand a cygwinified path. Ahh. + sys_lib_search_path_spec=`echo "$sys_lib_search_path_spec" | $SED -e 's/;/ /g'` + else + sys_lib_search_path_spec=`echo "$sys_lib_search_path_spec" | $SED -e "s/$PATH_SEPARATOR/ /g"` + fi + ;; + pw32*) + # pw32 DLLs use 'pw' prefix rather than 'lib' + library_names_spec='`echo ${libname} | sed -e 's/^lib/pw/'``echo ${release} | $SED -e 's/[.]/-/g'`${versuffix}${shared_ext}' + ;; + esac + ;; + + *) + library_names_spec='${libname}`echo ${release} | $SED -e 's/[.]/-/g'`${versuffix}${shared_ext} $libname.lib' + ;; + esac + dynamic_linker='Win32 ld.exe' + # FIXME: first we should search . and the directory the executable is in + shlibpath_var=PATH + ;; + +darwin* | rhapsody*) + dynamic_linker="$host_os dyld" + version_type=darwin + need_lib_prefix=no + need_version=no + library_names_spec='${libname}${release}${versuffix}$shared_ext ${libname}${release}${major}$shared_ext ${libname}$shared_ext' + soname_spec='${libname}${release}${major}$shared_ext' + shlibpath_overrides_runpath=yes + shlibpath_var=DYLD_LIBRARY_PATH + shrext_cmds='`test .$module = .yes && echo .so || echo .dylib`' + # Apple's gcc prints 'gcc -print-search-dirs' doesn't operate the same. + if test "$GCC" = yes; then + sys_lib_search_path_spec=`$CC -print-search-dirs | tr "\n" "$PATH_SEPARATOR" | sed -e 's/libraries:/@libraries:/' | tr "@" "\n" | grep "^libraries:" | sed -e "s/^libraries://" -e "s,=/,/,g" -e "s,$PATH_SEPARATOR, ,g" -e "s,.*,& /lib /usr/lib /usr/local/lib,g"` + else + sys_lib_search_path_spec='/lib /usr/lib /usr/local/lib' + fi + sys_lib_dlsearch_path_spec='/usr/local/lib /lib /usr/lib' + ;; + +dgux*) + version_type=linux + need_lib_prefix=no + need_version=no + library_names_spec='${libname}${release}${shared_ext}$versuffix ${libname}${release}${shared_ext}$major $libname$shared_ext' + soname_spec='${libname}${release}${shared_ext}$major' + shlibpath_var=LD_LIBRARY_PATH + ;; + +freebsd1*) + dynamic_linker=no + ;; + +kfreebsd*-gnu) + version_type=linux + need_lib_prefix=no + need_version=no + library_names_spec='${libname}${release}${shared_ext}$versuffix ${libname}${release}${shared_ext}$major ${libname}${shared_ext}' + soname_spec='${libname}${release}${shared_ext}$major' + shlibpath_var=LD_LIBRARY_PATH + shlibpath_overrides_runpath=no + hardcode_into_libs=yes + dynamic_linker='GNU ld.so' + ;; + +freebsd* | dragonfly*) + # DragonFly does not have aout. When/if they implement a new + # versioning mechanism, adjust this. + if test -x /usr/bin/objformat; then + objformat=`/usr/bin/objformat` + else + case $host_os in + freebsd[123]*) objformat=aout ;; + *) objformat=elf ;; + esac + fi + version_type=freebsd-$objformat + case $version_type in + freebsd-elf*) + library_names_spec='${libname}${release}${shared_ext}$versuffix ${libname}${release}${shared_ext} $libname${shared_ext}' + need_version=no + need_lib_prefix=no + ;; + freebsd-*) + library_names_spec='${libname}${release}${shared_ext}$versuffix $libname${shared_ext}$versuffix' + need_version=yes + ;; + esac + shlibpath_var=LD_LIBRARY_PATH + case $host_os in + freebsd2*) + shlibpath_overrides_runpath=yes + ;; + freebsd3.[01]* | freebsdelf3.[01]*) + shlibpath_overrides_runpath=yes + hardcode_into_libs=yes + ;; + freebsd3.[2-9]* | freebsdelf3.[2-9]* | \ + freebsd4.[0-5] | freebsdelf4.[0-5] | freebsd4.1.1 | freebsdelf4.1.1) + shlibpath_overrides_runpath=no + hardcode_into_libs=yes + ;; + freebsd*) # from 4.6 on + shlibpath_overrides_runpath=yes + hardcode_into_libs=yes + ;; + esac + ;; + +gnu*) + version_type=linux + need_lib_prefix=no + need_version=no + library_names_spec='${libname}${release}${shared_ext}$versuffix ${libname}${release}${shared_ext}${major} ${libname}${shared_ext}' + soname_spec='${libname}${release}${shared_ext}$major' + shlibpath_var=LD_LIBRARY_PATH + hardcode_into_libs=yes + ;; + +hpux9* | hpux10* | hpux11*) + # Give a soname corresponding to the major version so that dld.sl refuses to + # link against other versions. + version_type=sunos + need_lib_prefix=no + need_version=no + case $host_cpu in + ia64*) + shrext_cmds='.so' + hardcode_into_libs=yes + dynamic_linker="$host_os dld.so" + shlibpath_var=LD_LIBRARY_PATH + shlibpath_overrides_runpath=yes # Unless +noenvvar is specified. + library_names_spec='${libname}${release}${shared_ext}$versuffix ${libname}${release}${shared_ext}$major $libname${shared_ext}' + soname_spec='${libname}${release}${shared_ext}$major' + if test "X$HPUX_IA64_MODE" = X32; then + sys_lib_search_path_spec="/usr/lib/hpux32 /usr/local/lib/hpux32 /usr/local/lib" + else + sys_lib_search_path_spec="/usr/lib/hpux64 /usr/local/lib/hpux64" + fi + sys_lib_dlsearch_path_spec=$sys_lib_search_path_spec + ;; + hppa*64*) + shrext_cmds='.sl' + hardcode_into_libs=yes + dynamic_linker="$host_os dld.sl" + shlibpath_var=LD_LIBRARY_PATH # How should we handle SHLIB_PATH + shlibpath_overrides_runpath=yes # Unless +noenvvar is specified. + library_names_spec='${libname}${release}${shared_ext}$versuffix ${libname}${release}${shared_ext}$major $libname${shared_ext}' + soname_spec='${libname}${release}${shared_ext}$major' + sys_lib_search_path_spec="/usr/lib/pa20_64 /usr/ccs/lib/pa20_64" + sys_lib_dlsearch_path_spec=$sys_lib_search_path_spec + ;; + *) + shrext_cmds='.sl' + dynamic_linker="$host_os dld.sl" + shlibpath_var=SHLIB_PATH + shlibpath_overrides_runpath=no # +s is required to enable SHLIB_PATH + library_names_spec='${libname}${release}${shared_ext}$versuffix ${libname}${release}${shared_ext}$major $libname${shared_ext}' + soname_spec='${libname}${release}${shared_ext}$major' + ;; + esac + # HP-UX runs *really* slowly unless shared libraries are mode 555. + postinstall_cmds='chmod 555 $lib' + ;; + +interix3*) + version_type=linux + need_lib_prefix=no + need_version=no + library_names_spec='${libname}${release}${shared_ext}$versuffix ${libname}${release}${shared_ext}$major ${libname}${shared_ext}' + soname_spec='${libname}${release}${shared_ext}$major' + dynamic_linker='Interix 3.x ld.so.1 (PE, like ELF)' + shlibpath_var=LD_LIBRARY_PATH + shlibpath_overrides_runpath=no + hardcode_into_libs=yes + ;; + +irix5* | irix6* | nonstopux*) + case $host_os in + nonstopux*) version_type=nonstopux ;; + *) + if test "$lt_cv_prog_gnu_ld" = yes; then + version_type=linux + else + version_type=irix + fi ;; + esac + need_lib_prefix=no + need_version=no + soname_spec='${libname}${release}${shared_ext}$major' + library_names_spec='${libname}${release}${shared_ext}$versuffix ${libname}${release}${shared_ext}$major ${libname}${release}${shared_ext} $libname${shared_ext}' + case $host_os in + irix5* | nonstopux*) + libsuff= shlibsuff= + ;; + *) + case $LD in # libtool.m4 will add one of these switches to LD + *-32|*"-32 "|*-melf32bsmip|*"-melf32bsmip ") + libsuff= shlibsuff= libmagic=32-bit;; + *-n32|*"-n32 "|*-melf32bmipn32|*"-melf32bmipn32 ") + libsuff=32 shlibsuff=N32 libmagic=N32;; + *-64|*"-64 "|*-melf64bmip|*"-melf64bmip ") + libsuff=64 shlibsuff=64 libmagic=64-bit;; + *) libsuff= shlibsuff= libmagic=never-match;; + esac + ;; + esac + shlibpath_var=LD_LIBRARY${shlibsuff}_PATH + shlibpath_overrides_runpath=no + sys_lib_search_path_spec="/usr/lib${libsuff} /lib${libsuff} /usr/local/lib${libsuff}" + sys_lib_dlsearch_path_spec="/usr/lib${libsuff} /lib${libsuff}" + hardcode_into_libs=yes + ;; + +# No shared lib support for Linux oldld, aout, or coff. +linux*oldld* | linux*aout* | linux*coff*) + dynamic_linker=no + ;; + +# This must be Linux ELF. +linux*) + version_type=linux + need_lib_prefix=no + need_version=no + library_names_spec='${libname}${release}${shared_ext}$versuffix ${libname}${release}${shared_ext}$major $libname${shared_ext}' + soname_spec='${libname}${release}${shared_ext}$major' + finish_cmds='PATH="\$PATH:/sbin" ldconfig -n $libdir' + shlibpath_var=LD_LIBRARY_PATH + shlibpath_overrides_runpath=no + # This implies no fast_install, which is unacceptable. + # Some rework will be needed to allow for fast_install + # before this can be enabled. + hardcode_into_libs=yes + + # find out which ABI we are using + libsuff= + case "$host_cpu" in + x86_64*|s390x*|powerpc64*) + echo '#line 17564 "configure"' > conftest.$ac_ext + if { (eval echo "$as_me:$LINENO: \"$ac_compile\"") >&5 + (eval $ac_compile) 2>&5 + ac_status=$? + echo "$as_me:$LINENO: \$? = $ac_status" >&5 + (exit $ac_status); }; then + case `/usr/bin/file conftest.$ac_objext` in + *64-bit*) + libsuff=64 + sys_lib_search_path_spec="/lib${libsuff} /usr/lib${libsuff} /usr/local/lib${libsuff}" + ;; + esac + fi + rm -rf conftest* + ;; + esac + + # Append ld.so.conf contents to the search path + if test -f /etc/ld.so.conf; then + lt_ld_extra=`awk '/^include / { system(sprintf("cd /etc; cat %s 2>/dev/null", \$2)); skip = 1; } { if (!skip) print \$0; skip = 0; }' < /etc/ld.so.conf | $SED -e 's/#.*//;s/[:, ]/ /g;s/=[^=]*$//;s/=[^= ]* / /g;/^$/d' | tr '\n' ' '` + sys_lib_dlsearch_path_spec="/lib${libsuff} /usr/lib${libsuff} $lt_ld_extra" + fi + + # We used to test for /lib/ld.so.1 and disable shared libraries on + # powerpc, because MkLinux only supported shared libraries with the + # GNU dynamic linker. Since this was broken with cross compilers, + # most powerpc-linux boxes support dynamic linking these days and + # people can always --disable-shared, the test was removed, and we + # assume the GNU/Linux dynamic linker is in use. + dynamic_linker='GNU/Linux ld.so' + ;; + +knetbsd*-gnu) + version_type=linux + need_lib_prefix=no + need_version=no + library_names_spec='${libname}${release}${shared_ext}$versuffix ${libname}${release}${shared_ext}$major ${libname}${shared_ext}' + soname_spec='${libname}${release}${shared_ext}$major' + shlibpath_var=LD_LIBRARY_PATH + shlibpath_overrides_runpath=no + hardcode_into_libs=yes + dynamic_linker='GNU ld.so' + ;; + +netbsd*) + version_type=sunos + need_lib_prefix=no + need_version=no + if echo __ELF__ | $CC -E - | grep __ELF__ >/dev/null; then + library_names_spec='${libname}${release}${shared_ext}$versuffix ${libname}${shared_ext}$versuffix' + finish_cmds='PATH="\$PATH:/sbin" ldconfig -m $libdir' + dynamic_linker='NetBSD (a.out) ld.so' + else + library_names_spec='${libname}${release}${shared_ext}$versuffix ${libname}${release}${shared_ext}$major ${libname}${shared_ext}' + soname_spec='${libname}${release}${shared_ext}$major' + dynamic_linker='NetBSD ld.elf_so' + fi + shlibpath_var=LD_LIBRARY_PATH + shlibpath_overrides_runpath=yes + hardcode_into_libs=yes + ;; + +newsos6) + version_type=linux + library_names_spec='${libname}${release}${shared_ext}$versuffix ${libname}${release}${shared_ext}$major $libname${shared_ext}' + shlibpath_var=LD_LIBRARY_PATH + shlibpath_overrides_runpath=yes + ;; + +nto-qnx*) + version_type=linux + need_lib_prefix=no + need_version=no + library_names_spec='${libname}${release}${shared_ext}$versuffix ${libname}${release}${shared_ext}$major $libname${shared_ext}' + soname_spec='${libname}${release}${shared_ext}$major' + shlibpath_var=LD_LIBRARY_PATH + shlibpath_overrides_runpath=yes + ;; + +openbsd*) + version_type=sunos + sys_lib_dlsearch_path_spec="/usr/lib" + need_lib_prefix=no + # Some older versions of OpenBSD (3.3 at least) *do* need versioned libs. + case $host_os in + openbsd3.3 | openbsd3.3.*) need_version=yes ;; + *) need_version=no ;; + esac + library_names_spec='${libname}${release}${shared_ext}$versuffix ${libname}${shared_ext}$versuffix' + finish_cmds='PATH="\$PATH:/sbin" ldconfig -m $libdir' + shlibpath_var=LD_LIBRARY_PATH + if test -z "`echo __ELF__ | $CC -E - | grep __ELF__`" || test "$host_os-$host_cpu" = "openbsd2.8-powerpc"; then + case $host_os in + openbsd2.[89] | openbsd2.[89].*) + shlibpath_overrides_runpath=no + ;; + *) + shlibpath_overrides_runpath=yes + ;; + esac + else + shlibpath_overrides_runpath=yes + fi + ;; + +os2*) + libname_spec='$name' + shrext_cmds=".dll" + need_lib_prefix=no + library_names_spec='$libname${shared_ext} $libname.a' + dynamic_linker='OS/2 ld.exe' + shlibpath_var=LIBPATH + ;; + +osf3* | osf4* | osf5*) + version_type=osf + need_lib_prefix=no + need_version=no + soname_spec='${libname}${release}${shared_ext}$major' + library_names_spec='${libname}${release}${shared_ext}$versuffix ${libname}${release}${shared_ext}$major $libname${shared_ext}' + shlibpath_var=LD_LIBRARY_PATH + sys_lib_search_path_spec="/usr/shlib /usr/ccs/lib /usr/lib/cmplrs/cc /usr/lib /usr/local/lib /var/shlib" + sys_lib_dlsearch_path_spec="$sys_lib_search_path_spec" + ;; + +solaris*) + version_type=linux + need_lib_prefix=no + need_version=no + library_names_spec='${libname}${release}${shared_ext}$versuffix ${libname}${release}${shared_ext}$major $libname${shared_ext}' + soname_spec='${libname}${release}${shared_ext}$major' + shlibpath_var=LD_LIBRARY_PATH + shlibpath_overrides_runpath=yes + hardcode_into_libs=yes + # ldd complains unless libraries are executable + postinstall_cmds='chmod +x $lib' + ;; + +sunos4*) + version_type=sunos + library_names_spec='${libname}${release}${shared_ext}$versuffix ${libname}${shared_ext}$versuffix' + finish_cmds='PATH="\$PATH:/usr/etc" ldconfig $libdir' + shlibpath_var=LD_LIBRARY_PATH + shlibpath_overrides_runpath=yes + if test "$with_gnu_ld" = yes; then + need_lib_prefix=no + fi + need_version=yes + ;; + +sysv4 | sysv4.3*) + version_type=linux + library_names_spec='${libname}${release}${shared_ext}$versuffix ${libname}${release}${shared_ext}$major $libname${shared_ext}' + soname_spec='${libname}${release}${shared_ext}$major' + shlibpath_var=LD_LIBRARY_PATH + case $host_vendor in + sni) + shlibpath_overrides_runpath=no + need_lib_prefix=no + export_dynamic_flag_spec='${wl}-Blargedynsym' + runpath_var=LD_RUN_PATH + ;; + siemens) + need_lib_prefix=no + ;; + motorola) + need_lib_prefix=no + need_version=no + shlibpath_overrides_runpath=no + sys_lib_search_path_spec='/lib /usr/lib /usr/ccs/lib' + ;; + esac + ;; + +sysv4*MP*) + if test -d /usr/nec ;then + version_type=linux + library_names_spec='$libname${shared_ext}.$versuffix $libname${shared_ext}.$major $libname${shared_ext}' + soname_spec='$libname${shared_ext}.$major' + shlibpath_var=LD_LIBRARY_PATH + fi + ;; + +sysv5* | sco3.2v5* | sco5v6* | unixware* | OpenUNIX* | sysv4*uw2*) + version_type=freebsd-elf + need_lib_prefix=no + need_version=no + library_names_spec='${libname}${release}${shared_ext}$versuffix ${libname}${release}${shared_ext} $libname${shared_ext}' + soname_spec='${libname}${release}${shared_ext}$major' + shlibpath_var=LD_LIBRARY_PATH + hardcode_into_libs=yes + if test "$with_gnu_ld" = yes; then + sys_lib_search_path_spec='/usr/local/lib /usr/gnu/lib /usr/ccs/lib /usr/lib /lib' + shlibpath_overrides_runpath=no + else + sys_lib_search_path_spec='/usr/ccs/lib /usr/lib' + shlibpath_overrides_runpath=yes + case $host_os in + sco3.2v5*) + sys_lib_search_path_spec="$sys_lib_search_path_spec /lib" + ;; + esac + fi + sys_lib_dlsearch_path_spec='/usr/lib' + ;; + +uts4*) + version_type=linux + library_names_spec='${libname}${release}${shared_ext}$versuffix ${libname}${release}${shared_ext}$major $libname${shared_ext}' + soname_spec='${libname}${release}${shared_ext}$major' + shlibpath_var=LD_LIBRARY_PATH + ;; + +*) + dynamic_linker=no + ;; +esac +echo "$as_me:$LINENO: result: $dynamic_linker" >&5 +echo "${ECHO_T}$dynamic_linker" >&6 +test "$dynamic_linker" = no && can_build_shared=no + +variables_saved_for_relink="PATH $shlibpath_var $runpath_var" +if test "$GCC" = yes; then + variables_saved_for_relink="$variables_saved_for_relink GCC_EXEC_PREFIX COMPILER_PATH LIBRARY_PATH" +fi + +echo "$as_me:$LINENO: checking how to hardcode library paths into programs" >&5 +echo $ECHO_N "checking how to hardcode library paths into programs... $ECHO_C" >&6 +hardcode_action_GCJ= +if test -n "$hardcode_libdir_flag_spec_GCJ" || \ + test -n "$runpath_var_GCJ" || \ + test "X$hardcode_automatic_GCJ" = "Xyes" ; then + + # We can hardcode non-existant directories. + if test "$hardcode_direct_GCJ" != no && + # If the only mechanism to avoid hardcoding is shlibpath_var, we + # have to relink, otherwise we might link with an installed library + # when we should be linking with a yet-to-be-installed one + ## test "$_LT_AC_TAGVAR(hardcode_shlibpath_var, GCJ)" != no && + test "$hardcode_minus_L_GCJ" != no; then + # Linking always hardcodes the temporary library directory. + hardcode_action_GCJ=relink + else + # We can link without hardcoding, and we can hardcode nonexisting dirs. + hardcode_action_GCJ=immediate + fi +else + # We cannot hardcode anything, or else we can only hardcode existing + # directories. + hardcode_action_GCJ=unsupported +fi +echo "$as_me:$LINENO: result: $hardcode_action_GCJ" >&5 +echo "${ECHO_T}$hardcode_action_GCJ" >&6 + +if test "$hardcode_action_GCJ" = relink; then + # Fast installation is not supported + enable_fast_install=no +elif test "$shlibpath_overrides_runpath" = yes || + test "$enable_shared" = no; then + # Fast installation is not necessary + enable_fast_install=needless +fi + + +# The else clause should only fire when bootstrapping the +# libtool distribution, otherwise you forgot to ship ltmain.sh +# with your package, and you will get complaints that there are +# no rules to generate ltmain.sh. +if test -f "$ltmain"; then + # See if we are running on zsh, and set the options which allow our commands through + # without removal of \ escapes. + if test -n "${ZSH_VERSION+set}" ; then + setopt NO_GLOB_SUBST + fi + # Now quote all the things that may contain metacharacters while being + # careful not to overquote the AC_SUBSTed values. We take copies of the + # variables and quote the copies for generation of the libtool script. + for var in echo old_CC old_CFLAGS AR AR_FLAGS EGREP RANLIB LN_S LTCC LTCFLAGS NM \ + SED SHELL STRIP \ + libname_spec library_names_spec soname_spec extract_expsyms_cmds \ + old_striplib striplib file_magic_cmd finish_cmds finish_eval \ + deplibs_check_method reload_flag reload_cmds need_locks \ + lt_cv_sys_global_symbol_pipe lt_cv_sys_global_symbol_to_cdecl \ + lt_cv_sys_global_symbol_to_c_name_address \ + sys_lib_search_path_spec sys_lib_dlsearch_path_spec \ + old_postinstall_cmds old_postuninstall_cmds \ + compiler_GCJ \ + CC_GCJ \ + LD_GCJ \ + lt_prog_compiler_wl_GCJ \ + lt_prog_compiler_pic_GCJ \ + lt_prog_compiler_static_GCJ \ + lt_prog_compiler_no_builtin_flag_GCJ \ + export_dynamic_flag_spec_GCJ \ + thread_safe_flag_spec_GCJ \ + whole_archive_flag_spec_GCJ \ + enable_shared_with_static_runtimes_GCJ \ + old_archive_cmds_GCJ \ + old_archive_from_new_cmds_GCJ \ + predep_objects_GCJ \ + postdep_objects_GCJ \ + predeps_GCJ \ + postdeps_GCJ \ + compiler_lib_search_path_GCJ \ + archive_cmds_GCJ \ + archive_expsym_cmds_GCJ \ + postinstall_cmds_GCJ \ + postuninstall_cmds_GCJ \ + old_archive_from_expsyms_cmds_GCJ \ + allow_undefined_flag_GCJ \ + no_undefined_flag_GCJ \ + export_symbols_cmds_GCJ \ + hardcode_libdir_flag_spec_GCJ \ + hardcode_libdir_flag_spec_ld_GCJ \ + hardcode_libdir_separator_GCJ \ + hardcode_automatic_GCJ \ + module_cmds_GCJ \ + module_expsym_cmds_GCJ \ + lt_cv_prog_compiler_c_o_GCJ \ + exclude_expsyms_GCJ \ + include_expsyms_GCJ; do + + case $var in + old_archive_cmds_GCJ | \ + old_archive_from_new_cmds_GCJ | \ + archive_cmds_GCJ | \ + archive_expsym_cmds_GCJ | \ + module_cmds_GCJ | \ + module_expsym_cmds_GCJ | \ + old_archive_from_expsyms_cmds_GCJ | \ + export_symbols_cmds_GCJ | \ + extract_expsyms_cmds | reload_cmds | finish_cmds | \ + postinstall_cmds | postuninstall_cmds | \ + old_postinstall_cmds | old_postuninstall_cmds | \ + sys_lib_search_path_spec | sys_lib_dlsearch_path_spec) + # Double-quote double-evaled strings. + eval "lt_$var=\\\"\`\$echo \"X\$$var\" | \$Xsed -e \"\$double_quote_subst\" -e \"\$sed_quote_subst\" -e \"\$delay_variable_subst\"\`\\\"" + ;; + *) + eval "lt_$var=\\\"\`\$echo \"X\$$var\" | \$Xsed -e \"\$sed_quote_subst\"\`\\\"" + ;; + esac + done + + case $lt_echo in + *'\$0 --fallback-echo"') + lt_echo=`$echo "X$lt_echo" | $Xsed -e 's/\\\\\\\$0 --fallback-echo"$/$0 --fallback-echo"/'` + ;; + esac + +cfgfile="$ofile" + + cat <<__EOF__ >> "$cfgfile" +# ### BEGIN LIBTOOL TAG CONFIG: $tagname + +# Libtool was configured on host `(hostname || uname -n) 2>/dev/null | sed 1q`: + +# Shell to use when invoking shell scripts. +SHELL=$lt_SHELL + +# Whether or not to build shared libraries. +build_libtool_libs=$enable_shared + +# Whether or not to build static libraries. +build_old_libs=$enable_static + +# Whether or not to add -lc for building shared libraries. +build_libtool_need_lc=$archive_cmds_need_lc_GCJ + +# Whether or not to disallow shared libs when runtime libs are static +allow_libtool_libs_with_static_runtimes=$enable_shared_with_static_runtimes_GCJ + +# Whether or not to optimize for fast installation. +fast_install=$enable_fast_install + +# The host system. +host_alias=$host_alias +host=$host +host_os=$host_os + +# The build system. +build_alias=$build_alias +build=$build +build_os=$build_os + +# An echo program that does not interpret backslashes. +echo=$lt_echo + +# The archiver. +AR=$lt_AR +AR_FLAGS=$lt_AR_FLAGS + +# A C compiler. +LTCC=$lt_LTCC + +# LTCC compiler flags. +LTCFLAGS=$lt_LTCFLAGS + +# A language-specific compiler. +CC=$lt_compiler_GCJ + +# Is the compiler the GNU C compiler? +with_gcc=$GCC_GCJ + +gcc_dir=\`gcc -print-file-name=. | $SED 's,/\.$,,'\` +gcc_ver=\`gcc -dumpversion\` + +# An ERE matcher. +EGREP=$lt_EGREP + +# The linker used to build libraries. +LD=$lt_LD_GCJ + +# Whether we need hard or soft links. +LN_S=$lt_LN_S + +# A BSD-compatible nm program. +NM=$lt_NM + +# A symbol stripping program +STRIP=$lt_STRIP + +# Used to examine libraries when file_magic_cmd begins "file" +MAGIC_CMD=$MAGIC_CMD + +# Used on cygwin: DLL creation program. +DLLTOOL="$DLLTOOL" + +# Used on cygwin: object dumper. +OBJDUMP="$OBJDUMP" + +# Used on cygwin: assembler. +AS="$AS" + +# The name of the directory that contains temporary libtool files. +objdir=$objdir + +# How to create reloadable object files. +reload_flag=$lt_reload_flag +reload_cmds=$lt_reload_cmds + +# How to pass a linker flag through the compiler. +wl=$lt_lt_prog_compiler_wl_GCJ + +# Object file suffix (normally "o"). +objext="$ac_objext" + +# Old archive suffix (normally "a"). +libext="$libext" + +# Shared library suffix (normally ".so"). +shrext_cmds='$shrext_cmds' + +# Executable file suffix (normally ""). +exeext="$exeext" + +# Additional compiler flags for building library objects. +pic_flag=$lt_lt_prog_compiler_pic_GCJ +pic_mode=$pic_mode + +# What is the maximum length of a command? +max_cmd_len=$lt_cv_sys_max_cmd_len + +# Does compiler simultaneously support -c and -o options? +compiler_c_o=$lt_lt_cv_prog_compiler_c_o_GCJ + +# Must we lock files when doing compilation? +need_locks=$lt_need_locks + +# Do we need the lib prefix for modules? +need_lib_prefix=$need_lib_prefix + +# Do we need a version for libraries? +need_version=$need_version + +# Whether dlopen is supported. +dlopen_support=$enable_dlopen + +# Whether dlopen of programs is supported. +dlopen_self=$enable_dlopen_self + +# Whether dlopen of statically linked programs is supported. +dlopen_self_static=$enable_dlopen_self_static + +# Compiler flag to prevent dynamic linking. +link_static_flag=$lt_lt_prog_compiler_static_GCJ + +# Compiler flag to turn off builtin functions. +no_builtin_flag=$lt_lt_prog_compiler_no_builtin_flag_GCJ + +# Compiler flag to allow reflexive dlopens. +export_dynamic_flag_spec=$lt_export_dynamic_flag_spec_GCJ + +# Compiler flag to generate shared objects directly from archives. +whole_archive_flag_spec=$lt_whole_archive_flag_spec_GCJ + +# Compiler flag to generate thread-safe objects. +thread_safe_flag_spec=$lt_thread_safe_flag_spec_GCJ + +# Library versioning type. +version_type=$version_type + +# Format of library name prefix. +libname_spec=$lt_libname_spec + +# List of archive names. First name is the real one, the rest are links. +# The last name is the one that the linker finds with -lNAME. +library_names_spec=$lt_library_names_spec + +# The coded name of the library, if different from the real name. +soname_spec=$lt_soname_spec + +# Commands used to build and install an old-style archive. +RANLIB=$lt_RANLIB +old_archive_cmds=$lt_old_archive_cmds_GCJ +old_postinstall_cmds=$lt_old_postinstall_cmds +old_postuninstall_cmds=$lt_old_postuninstall_cmds + +# Create an old-style archive from a shared archive. +old_archive_from_new_cmds=$lt_old_archive_from_new_cmds_GCJ + +# Create a temporary old-style archive to link instead of a shared archive. +old_archive_from_expsyms_cmds=$lt_old_archive_from_expsyms_cmds_GCJ + +# Commands used to build and install a shared archive. +archive_cmds=$lt_archive_cmds_GCJ +archive_expsym_cmds=$lt_archive_expsym_cmds_GCJ +postinstall_cmds=$lt_postinstall_cmds +postuninstall_cmds=$lt_postuninstall_cmds + +# Commands used to build a loadable module (assumed same as above if empty) +module_cmds=$lt_module_cmds_GCJ +module_expsym_cmds=$lt_module_expsym_cmds_GCJ + +# Commands to strip libraries. +old_striplib=$lt_old_striplib +striplib=$lt_striplib + +# Dependencies to place before the objects being linked to create a +# shared library. +predep_objects=\`echo $lt_predep_objects_GCJ | \$SED -e "s@\${gcc_dir}@\\\${gcc_dir}@g;s@\${gcc_ver}@\\\${gcc_ver}@g"\` + +# Dependencies to place after the objects being linked to create a +# shared library. +postdep_objects=\`echo $lt_postdep_objects_GCJ | \$SED -e "s@\${gcc_dir}@\\\${gcc_dir}@g;s@\${gcc_ver}@\\\${gcc_ver}@g"\` + +# Dependencies to place before the objects being linked to create a +# shared library. +predeps=$lt_predeps_GCJ + +# Dependencies to place after the objects being linked to create a +# shared library. +postdeps=$lt_postdeps_GCJ + +# The library search path used internally by the compiler when linking +# a shared library. +compiler_lib_search_path=\`echo $lt_compiler_lib_search_path_GCJ | \$SED -e "s@\${gcc_dir}@\\\${gcc_dir}@g;s@\${gcc_ver}@\\\${gcc_ver}@g"\` + +# Method to check whether dependent libraries are shared objects. +deplibs_check_method=$lt_deplibs_check_method + +# Command to use when deplibs_check_method == file_magic. +file_magic_cmd=$lt_file_magic_cmd + +# Flag that allows shared libraries with undefined symbols to be built. +allow_undefined_flag=$lt_allow_undefined_flag_GCJ + +# Flag that forces no undefined symbols. +no_undefined_flag=$lt_no_undefined_flag_GCJ + +# Commands used to finish a libtool library installation in a directory. +finish_cmds=$lt_finish_cmds + +# Same as above, but a single script fragment to be evaled but not shown. +finish_eval=$lt_finish_eval + +# Take the output of nm and produce a listing of raw symbols and C names. +global_symbol_pipe=$lt_lt_cv_sys_global_symbol_pipe + +# Transform the output of nm in a proper C declaration +global_symbol_to_cdecl=$lt_lt_cv_sys_global_symbol_to_cdecl + +# Transform the output of nm in a C name address pair +global_symbol_to_c_name_address=$lt_lt_cv_sys_global_symbol_to_c_name_address + +# This is the shared library runtime path variable. +runpath_var=$runpath_var + +# This is the shared library path variable. +shlibpath_var=$shlibpath_var + +# Is shlibpath searched before the hard-coded library search path? +shlibpath_overrides_runpath=$shlibpath_overrides_runpath + +# How to hardcode a shared library path into an executable. +hardcode_action=$hardcode_action_GCJ + +# Whether we should hardcode library paths into libraries. +hardcode_into_libs=$hardcode_into_libs + +# Flag to hardcode \$libdir into a binary during linking. +# This must work even if \$libdir does not exist. +hardcode_libdir_flag_spec=$lt_hardcode_libdir_flag_spec_GCJ + +# If ld is used when linking, flag to hardcode \$libdir into +# a binary during linking. This must work even if \$libdir does +# not exist. +hardcode_libdir_flag_spec_ld=$lt_hardcode_libdir_flag_spec_ld_GCJ + +# Whether we need a single -rpath flag with a separated argument. +hardcode_libdir_separator=$lt_hardcode_libdir_separator_GCJ + +# Set to yes if using DIR/libNAME${shared_ext} during linking hardcodes DIR into the +# resulting binary. +hardcode_direct=$hardcode_direct_GCJ + +# Set to yes if using the -LDIR flag during linking hardcodes DIR into the +# resulting binary. +hardcode_minus_L=$hardcode_minus_L_GCJ + +# Set to yes if using SHLIBPATH_VAR=DIR during linking hardcodes DIR into +# the resulting binary. +hardcode_shlibpath_var=$hardcode_shlibpath_var_GCJ + +# Set to yes if building a shared library automatically hardcodes DIR into the library +# and all subsequent libraries and executables linked against it. +hardcode_automatic=$hardcode_automatic_GCJ + +# Variables whose values should be saved in libtool wrapper scripts and +# restored at relink time. +variables_saved_for_relink="$variables_saved_for_relink" + +# Whether libtool must link a program against all its dependency libraries. +link_all_deplibs=$link_all_deplibs_GCJ + +# Compile-time system search path for libraries +sys_lib_search_path_spec=\`echo $lt_sys_lib_search_path_spec | \$SED -e "s@\${gcc_dir}@\\\${gcc_dir}@g;s@\${gcc_ver}@\\\${gcc_ver}@g"\` + +# Run-time system search path for libraries +sys_lib_dlsearch_path_spec=$lt_sys_lib_dlsearch_path_spec + +# Fix the shell variable \$srcfile for the compiler. +fix_srcfile_path="$fix_srcfile_path_GCJ" + +# Set to yes if exported symbols are required. +always_export_symbols=$always_export_symbols_GCJ + +# The commands to list exported symbols. +export_symbols_cmds=$lt_export_symbols_cmds_GCJ + +# The commands to extract the exported symbol list from a shared archive. +extract_expsyms_cmds=$lt_extract_expsyms_cmds + +# Symbols that should not be listed in the preloaded symbols. +exclude_expsyms=$lt_exclude_expsyms_GCJ + +# Symbols that must always be exported. +include_expsyms=$lt_include_expsyms_GCJ + +# ### END LIBTOOL TAG CONFIG: $tagname + +__EOF__ + + +else + # If there is no Makefile yet, we rely on a make rule to execute + # `config.status --recheck' to rerun these tests and create the + # libtool script then. + ltmain_in=`echo $ltmain | sed -e 's/\.sh$/.in/'` + if test -f "$ltmain_in"; then + test -f Makefile && make "$ltmain" + fi +fi + + +ac_ext=c +ac_cpp='$CPP $CPPFLAGS' +ac_compile='$CC -c $CFLAGS $CPPFLAGS conftest.$ac_ext >&5' +ac_link='$CC -o conftest$ac_exeext $CFLAGS $CPPFLAGS $LDFLAGS conftest.$ac_ext $LIBS >&5' +ac_compiler_gnu=$ac_cv_c_compiler_gnu + +CC="$lt_save_CC" + + else + tagname="" + fi + ;; + + RC) + + + +# Source file extension for RC test sources. +ac_ext=rc + +# Object file extension for compiled RC test sources. +objext=o +objext_RC=$objext + +# Code to be used in simple compile tests +lt_simple_compile_test_code='sample MENU { MENUITEM "&Soup", 100, CHECKED }\n' + +# Code to be used in simple link tests +lt_simple_link_test_code="$lt_simple_compile_test_code" + +# ltmain only uses $CC for tagged configurations so make sure $CC is set. + +# If no C compiler was specified, use CC. +LTCC=${LTCC-"$CC"} + +# If no C compiler flags were specified, use CFLAGS. +LTCFLAGS=${LTCFLAGS-"$CFLAGS"} + +# Allow CC to be a program name with arguments. +compiler=$CC + + +# save warnings/boilerplate of simple test code +ac_outfile=conftest.$ac_objext +printf "$lt_simple_compile_test_code" >conftest.$ac_ext +eval "$ac_compile" 2>&1 >/dev/null | $SED '/^$/d; /^ *+/d' >conftest.err +_lt_compiler_boilerplate=`cat conftest.err` +$rm conftest* + +ac_outfile=conftest.$ac_objext +printf "$lt_simple_link_test_code" >conftest.$ac_ext +eval "$ac_link" 2>&1 >/dev/null | $SED '/^$/d; /^ *+/d' >conftest.err +_lt_linker_boilerplate=`cat conftest.err` +$rm conftest* + + +# Allow CC to be a program name with arguments. +lt_save_CC="$CC" +CC=${RC-"windres"} +compiler=$CC +compiler_RC=$CC +for cc_temp in $compiler""; do + case $cc_temp in + compile | *[\\/]compile | ccache | *[\\/]ccache ) ;; + distcc | *[\\/]distcc | purify | *[\\/]purify ) ;; + \-*) ;; + *) break;; + esac +done +cc_basename=`$echo "X$cc_temp" | $Xsed -e 's%.*/%%' -e "s%^$host_alias-%%"` + +lt_cv_prog_compiler_c_o_RC=yes + +# The else clause should only fire when bootstrapping the +# libtool distribution, otherwise you forgot to ship ltmain.sh +# with your package, and you will get complaints that there are +# no rules to generate ltmain.sh. +if test -f "$ltmain"; then + # See if we are running on zsh, and set the options which allow our commands through + # without removal of \ escapes. + if test -n "${ZSH_VERSION+set}" ; then + setopt NO_GLOB_SUBST + fi + # Now quote all the things that may contain metacharacters while being + # careful not to overquote the AC_SUBSTed values. We take copies of the + # variables and quote the copies for generation of the libtool script. + for var in echo old_CC old_CFLAGS AR AR_FLAGS EGREP RANLIB LN_S LTCC LTCFLAGS NM \ + SED SHELL STRIP \ + libname_spec library_names_spec soname_spec extract_expsyms_cmds \ + old_striplib striplib file_magic_cmd finish_cmds finish_eval \ + deplibs_check_method reload_flag reload_cmds need_locks \ + lt_cv_sys_global_symbol_pipe lt_cv_sys_global_symbol_to_cdecl \ + lt_cv_sys_global_symbol_to_c_name_address \ + sys_lib_search_path_spec sys_lib_dlsearch_path_spec \ + old_postinstall_cmds old_postuninstall_cmds \ + compiler_RC \ + CC_RC \ + LD_RC \ + lt_prog_compiler_wl_RC \ + lt_prog_compiler_pic_RC \ + lt_prog_compiler_static_RC \ + lt_prog_compiler_no_builtin_flag_RC \ + export_dynamic_flag_spec_RC \ + thread_safe_flag_spec_RC \ + whole_archive_flag_spec_RC \ + enable_shared_with_static_runtimes_RC \ + old_archive_cmds_RC \ + old_archive_from_new_cmds_RC \ + predep_objects_RC \ + postdep_objects_RC \ + predeps_RC \ + postdeps_RC \ + compiler_lib_search_path_RC \ + archive_cmds_RC \ + archive_expsym_cmds_RC \ + postinstall_cmds_RC \ + postuninstall_cmds_RC \ + old_archive_from_expsyms_cmds_RC \ + allow_undefined_flag_RC \ + no_undefined_flag_RC \ + export_symbols_cmds_RC \ + hardcode_libdir_flag_spec_RC \ + hardcode_libdir_flag_spec_ld_RC \ + hardcode_libdir_separator_RC \ + hardcode_automatic_RC \ + module_cmds_RC \ + module_expsym_cmds_RC \ + lt_cv_prog_compiler_c_o_RC \ + exclude_expsyms_RC \ + include_expsyms_RC; do + + case $var in + old_archive_cmds_RC | \ + old_archive_from_new_cmds_RC | \ + archive_cmds_RC | \ + archive_expsym_cmds_RC | \ + module_cmds_RC | \ + module_expsym_cmds_RC | \ + old_archive_from_expsyms_cmds_RC | \ + export_symbols_cmds_RC | \ + extract_expsyms_cmds | reload_cmds | finish_cmds | \ + postinstall_cmds | postuninstall_cmds | \ + old_postinstall_cmds | old_postuninstall_cmds | \ + sys_lib_search_path_spec | sys_lib_dlsearch_path_spec) + # Double-quote double-evaled strings. + eval "lt_$var=\\\"\`\$echo \"X\$$var\" | \$Xsed -e \"\$double_quote_subst\" -e \"\$sed_quote_subst\" -e \"\$delay_variable_subst\"\`\\\"" + ;; + *) + eval "lt_$var=\\\"\`\$echo \"X\$$var\" | \$Xsed -e \"\$sed_quote_subst\"\`\\\"" + ;; + esac + done + + case $lt_echo in + *'\$0 --fallback-echo"') + lt_echo=`$echo "X$lt_echo" | $Xsed -e 's/\\\\\\\$0 --fallback-echo"$/$0 --fallback-echo"/'` + ;; + esac + +cfgfile="$ofile" + + cat <<__EOF__ >> "$cfgfile" +# ### BEGIN LIBTOOL TAG CONFIG: $tagname + +# Libtool was configured on host `(hostname || uname -n) 2>/dev/null | sed 1q`: + +# Shell to use when invoking shell scripts. +SHELL=$lt_SHELL + +# Whether or not to build shared libraries. +build_libtool_libs=$enable_shared + +# Whether or not to build static libraries. +build_old_libs=$enable_static + +# Whether or not to add -lc for building shared libraries. +build_libtool_need_lc=$archive_cmds_need_lc_RC + +# Whether or not to disallow shared libs when runtime libs are static +allow_libtool_libs_with_static_runtimes=$enable_shared_with_static_runtimes_RC + +# Whether or not to optimize for fast installation. +fast_install=$enable_fast_install + +# The host system. +host_alias=$host_alias +host=$host +host_os=$host_os + +# The build system. +build_alias=$build_alias +build=$build +build_os=$build_os + +# An echo program that does not interpret backslashes. +echo=$lt_echo + +# The archiver. +AR=$lt_AR +AR_FLAGS=$lt_AR_FLAGS + +# A C compiler. +LTCC=$lt_LTCC + +# LTCC compiler flags. +LTCFLAGS=$lt_LTCFLAGS + +# A language-specific compiler. +CC=$lt_compiler_RC + +# Is the compiler the GNU C compiler? +with_gcc=$GCC_RC + +gcc_dir=\`gcc -print-file-name=. | $SED 's,/\.$,,'\` +gcc_ver=\`gcc -dumpversion\` + +# An ERE matcher. +EGREP=$lt_EGREP + +# The linker used to build libraries. +LD=$lt_LD_RC + +# Whether we need hard or soft links. +LN_S=$lt_LN_S + +# A BSD-compatible nm program. +NM=$lt_NM + +# A symbol stripping program +STRIP=$lt_STRIP + +# Used to examine libraries when file_magic_cmd begins "file" +MAGIC_CMD=$MAGIC_CMD + +# Used on cygwin: DLL creation program. +DLLTOOL="$DLLTOOL" + +# Used on cygwin: object dumper. +OBJDUMP="$OBJDUMP" + +# Used on cygwin: assembler. +AS="$AS" + +# The name of the directory that contains temporary libtool files. +objdir=$objdir + +# How to create reloadable object files. +reload_flag=$lt_reload_flag +reload_cmds=$lt_reload_cmds + +# How to pass a linker flag through the compiler. +wl=$lt_lt_prog_compiler_wl_RC + +# Object file suffix (normally "o"). +objext="$ac_objext" + +# Old archive suffix (normally "a"). +libext="$libext" + +# Shared library suffix (normally ".so"). +shrext_cmds='$shrext_cmds' + +# Executable file suffix (normally ""). +exeext="$exeext" + +# Additional compiler flags for building library objects. +pic_flag=$lt_lt_prog_compiler_pic_RC +pic_mode=$pic_mode + +# What is the maximum length of a command? +max_cmd_len=$lt_cv_sys_max_cmd_len + +# Does compiler simultaneously support -c and -o options? +compiler_c_o=$lt_lt_cv_prog_compiler_c_o_RC + +# Must we lock files when doing compilation? +need_locks=$lt_need_locks + +# Do we need the lib prefix for modules? +need_lib_prefix=$need_lib_prefix + +# Do we need a version for libraries? +need_version=$need_version + +# Whether dlopen is supported. +dlopen_support=$enable_dlopen + +# Whether dlopen of programs is supported. +dlopen_self=$enable_dlopen_self + +# Whether dlopen of statically linked programs is supported. +dlopen_self_static=$enable_dlopen_self_static + +# Compiler flag to prevent dynamic linking. +link_static_flag=$lt_lt_prog_compiler_static_RC + +# Compiler flag to turn off builtin functions. +no_builtin_flag=$lt_lt_prog_compiler_no_builtin_flag_RC + +# Compiler flag to allow reflexive dlopens. +export_dynamic_flag_spec=$lt_export_dynamic_flag_spec_RC + +# Compiler flag to generate shared objects directly from archives. +whole_archive_flag_spec=$lt_whole_archive_flag_spec_RC + +# Compiler flag to generate thread-safe objects. +thread_safe_flag_spec=$lt_thread_safe_flag_spec_RC + +# Library versioning type. +version_type=$version_type + +# Format of library name prefix. +libname_spec=$lt_libname_spec + +# List of archive names. First name is the real one, the rest are links. +# The last name is the one that the linker finds with -lNAME. +library_names_spec=$lt_library_names_spec + +# The coded name of the library, if different from the real name. +soname_spec=$lt_soname_spec + +# Commands used to build and install an old-style archive. +RANLIB=$lt_RANLIB +old_archive_cmds=$lt_old_archive_cmds_RC +old_postinstall_cmds=$lt_old_postinstall_cmds +old_postuninstall_cmds=$lt_old_postuninstall_cmds + +# Create an old-style archive from a shared archive. +old_archive_from_new_cmds=$lt_old_archive_from_new_cmds_RC + +# Create a temporary old-style archive to link instead of a shared archive. +old_archive_from_expsyms_cmds=$lt_old_archive_from_expsyms_cmds_RC + +# Commands used to build and install a shared archive. +archive_cmds=$lt_archive_cmds_RC +archive_expsym_cmds=$lt_archive_expsym_cmds_RC +postinstall_cmds=$lt_postinstall_cmds +postuninstall_cmds=$lt_postuninstall_cmds + +# Commands used to build a loadable module (assumed same as above if empty) +module_cmds=$lt_module_cmds_RC +module_expsym_cmds=$lt_module_expsym_cmds_RC + +# Commands to strip libraries. +old_striplib=$lt_old_striplib +striplib=$lt_striplib + +# Dependencies to place before the objects being linked to create a +# shared library. +predep_objects=\`echo $lt_predep_objects_RC | \$SED -e "s@\${gcc_dir}@\\\${gcc_dir}@g;s@\${gcc_ver}@\\\${gcc_ver}@g"\` + +# Dependencies to place after the objects being linked to create a +# shared library. +postdep_objects=\`echo $lt_postdep_objects_RC | \$SED -e "s@\${gcc_dir}@\\\${gcc_dir}@g;s@\${gcc_ver}@\\\${gcc_ver}@g"\` + +# Dependencies to place before the objects being linked to create a +# shared library. +predeps=$lt_predeps_RC + +# Dependencies to place after the objects being linked to create a +# shared library. +postdeps=$lt_postdeps_RC + +# The library search path used internally by the compiler when linking +# a shared library. +compiler_lib_search_path=\`echo $lt_compiler_lib_search_path_RC | \$SED -e "s@\${gcc_dir}@\\\${gcc_dir}@g;s@\${gcc_ver}@\\\${gcc_ver}@g"\` + +# Method to check whether dependent libraries are shared objects. +deplibs_check_method=$lt_deplibs_check_method + +# Command to use when deplibs_check_method == file_magic. +file_magic_cmd=$lt_file_magic_cmd + +# Flag that allows shared libraries with undefined symbols to be built. +allow_undefined_flag=$lt_allow_undefined_flag_RC + +# Flag that forces no undefined symbols. +no_undefined_flag=$lt_no_undefined_flag_RC + +# Commands used to finish a libtool library installation in a directory. +finish_cmds=$lt_finish_cmds + +# Same as above, but a single script fragment to be evaled but not shown. +finish_eval=$lt_finish_eval + +# Take the output of nm and produce a listing of raw symbols and C names. +global_symbol_pipe=$lt_lt_cv_sys_global_symbol_pipe + +# Transform the output of nm in a proper C declaration +global_symbol_to_cdecl=$lt_lt_cv_sys_global_symbol_to_cdecl + +# Transform the output of nm in a C name address pair +global_symbol_to_c_name_address=$lt_lt_cv_sys_global_symbol_to_c_name_address + +# This is the shared library runtime path variable. +runpath_var=$runpath_var + +# This is the shared library path variable. +shlibpath_var=$shlibpath_var + +# Is shlibpath searched before the hard-coded library search path? +shlibpath_overrides_runpath=$shlibpath_overrides_runpath + +# How to hardcode a shared library path into an executable. +hardcode_action=$hardcode_action_RC + +# Whether we should hardcode library paths into libraries. +hardcode_into_libs=$hardcode_into_libs + +# Flag to hardcode \$libdir into a binary during linking. +# This must work even if \$libdir does not exist. +hardcode_libdir_flag_spec=$lt_hardcode_libdir_flag_spec_RC + +# If ld is used when linking, flag to hardcode \$libdir into +# a binary during linking. This must work even if \$libdir does +# not exist. +hardcode_libdir_flag_spec_ld=$lt_hardcode_libdir_flag_spec_ld_RC + +# Whether we need a single -rpath flag with a separated argument. +hardcode_libdir_separator=$lt_hardcode_libdir_separator_RC + +# Set to yes if using DIR/libNAME${shared_ext} during linking hardcodes DIR into the +# resulting binary. +hardcode_direct=$hardcode_direct_RC + +# Set to yes if using the -LDIR flag during linking hardcodes DIR into the +# resulting binary. +hardcode_minus_L=$hardcode_minus_L_RC + +# Set to yes if using SHLIBPATH_VAR=DIR during linking hardcodes DIR into +# the resulting binary. +hardcode_shlibpath_var=$hardcode_shlibpath_var_RC + +# Set to yes if building a shared library automatically hardcodes DIR into the library +# and all subsequent libraries and executables linked against it. +hardcode_automatic=$hardcode_automatic_RC + +# Variables whose values should be saved in libtool wrapper scripts and +# restored at relink time. +variables_saved_for_relink="$variables_saved_for_relink" + +# Whether libtool must link a program against all its dependency libraries. +link_all_deplibs=$link_all_deplibs_RC + +# Compile-time system search path for libraries +sys_lib_search_path_spec=\`echo $lt_sys_lib_search_path_spec | \$SED -e "s@\${gcc_dir}@\\\${gcc_dir}@g;s@\${gcc_ver}@\\\${gcc_ver}@g"\` + +# Run-time system search path for libraries +sys_lib_dlsearch_path_spec=$lt_sys_lib_dlsearch_path_spec + +# Fix the shell variable \$srcfile for the compiler. +fix_srcfile_path="$fix_srcfile_path_RC" + +# Set to yes if exported symbols are required. +always_export_symbols=$always_export_symbols_RC + +# The commands to list exported symbols. +export_symbols_cmds=$lt_export_symbols_cmds_RC + +# The commands to extract the exported symbol list from a shared archive. +extract_expsyms_cmds=$lt_extract_expsyms_cmds + +# Symbols that should not be listed in the preloaded symbols. +exclude_expsyms=$lt_exclude_expsyms_RC + +# Symbols that must always be exported. +include_expsyms=$lt_include_expsyms_RC + +# ### END LIBTOOL TAG CONFIG: $tagname + +__EOF__ + + +else + # If there is no Makefile yet, we rely on a make rule to execute + # `config.status --recheck' to rerun these tests and create the + # libtool script then. + ltmain_in=`echo $ltmain | sed -e 's/\.sh$/.in/'` + if test -f "$ltmain_in"; then + test -f Makefile && make "$ltmain" + fi +fi + + +ac_ext=c +ac_cpp='$CPP $CPPFLAGS' +ac_compile='$CC -c $CFLAGS $CPPFLAGS conftest.$ac_ext >&5' +ac_link='$CC -o conftest$ac_exeext $CFLAGS $CPPFLAGS $LDFLAGS conftest.$ac_ext $LIBS >&5' +ac_compiler_gnu=$ac_cv_c_compiler_gnu + +CC="$lt_save_CC" + + ;; + + *) + { { echo "$as_me:$LINENO: error: Unsupported tag name: $tagname" >&5 +echo "$as_me: error: Unsupported tag name: $tagname" >&2;} + { (exit 1); exit 1; }; } + ;; + esac + + # Append the new tag name to the list of available tags. + if test -n "$tagname" ; then + available_tags="$available_tags $tagname" + fi + fi + done + IFS="$lt_save_ifs" + + # Now substitute the updated list of available tags. + if eval "sed -e 's/^available_tags=.*\$/available_tags=\"$available_tags\"/' \"$ofile\" > \"${ofile}T\""; then + mv "${ofile}T" "$ofile" + chmod +x "$ofile" + else + rm -f "${ofile}T" + { { echo "$as_me:$LINENO: error: unable to update list of available tagged configurations." >&5 +echo "$as_me: error: unable to update list of available tagged configurations." >&2;} + { (exit 1); exit 1; }; } + fi +fi + + + +# This can be used to rebuild libtool when needed +LIBTOOL_DEPS="$ac_aux_dir/ltmain.sh" + +# Always use our own libtool. +LIBTOOL='$(SHELL) $(top_builddir)/libtool' + +# Prevent multiple expansion + + + + + + + + + + + + + + + + + + + + + ac_config_files="$ac_config_files Makefile lib/Makefile bin/Makefile" + +cat >confcache <<\_ACEOF +# This file is a shell script that caches the results of configure +# tests run on this system so they can be shared between configure +# scripts and configure runs, see configure's option --config-cache. +# It is not useful on other systems. If it contains results you don't +# want to keep, you may remove or edit it. +# +# config.status only pays attention to the cache file if you give it +# the --recheck option to rerun configure. +# +# `ac_cv_env_foo' variables (set or unset) will be overridden when +# loading this file, other *unset* `ac_cv_foo' will be assigned the +# following values. + +_ACEOF + +# The following way of writing the cache mishandles newlines in values, +# but we know of no workaround that is simple, portable, and efficient. +# So, don't put newlines in cache variables' values. +# Ultrix sh set writes to stderr and can't be redirected directly, +# and sets the high bit in the cache file unless we assign to the vars. +{ + (set) 2>&1 | + case `(ac_space=' '; set | grep ac_space) 2>&1` in + *ac_space=\ *) + # `set' does not quote correctly, so add quotes (double-quote + # substitution turns \\\\ into \\, and sed turns \\ into \). + sed -n \ + "s/'/'\\\\''/g; + s/^\\([_$as_cr_alnum]*_cv_[_$as_cr_alnum]*\\)=\\(.*\\)/\\1='\\2'/p" + ;; + *) + # `set' quotes correctly as required by POSIX, so do not add quotes. + sed -n \ + "s/^\\([_$as_cr_alnum]*_cv_[_$as_cr_alnum]*\\)=\\(.*\\)/\\1=\\2/p" + ;; + esac; +} | + sed ' + t clear + : clear + s/^\([^=]*\)=\(.*[{}].*\)$/test "${\1+set}" = set || &/ + t end + /^ac_cv_env/!s/^\([^=]*\)=\(.*\)$/\1=${\1=\2}/ + : end' >>confcache +if diff $cache_file confcache >/dev/null 2>&1; then :; else + if test -w $cache_file; then + test "x$cache_file" != "x/dev/null" && echo "updating cache $cache_file" + cat confcache >$cache_file + else + echo "not updating unwritable cache $cache_file" + fi +fi +rm -f confcache + +test "x$prefix" = xNONE && prefix=$ac_default_prefix +# Let make expand exec_prefix. +test "x$exec_prefix" = xNONE && exec_prefix='${prefix}' + +# VPATH may cause trouble with some makes, so we remove $(srcdir), +# ${srcdir} and @srcdir@ from VPATH if srcdir is ".", strip leading and +# trailing colons and then remove the whole line if VPATH becomes empty +# (actually we leave an empty line to preserve line numbers). +if test "x$srcdir" = x.; then + ac_vpsub='/^[ ]*VPATH[ ]*=/{ +s/:*\$(srcdir):*/:/; +s/:*\${srcdir}:*/:/; +s/:*@srcdir@:*/:/; +s/^\([^=]*=[ ]*\):*/\1/; +s/:*$//; +s/^[^=]*=[ ]*$//; +}' +fi + +# Transform confdefs.h into DEFS. +# Protect against shell expansion while executing Makefile rules. +# Protect against Makefile macro expansion. +# +# If the first sed substitution is executed (which looks for macros that +# take arguments), then we branch to the quote section. Otherwise, +# look for a macro that doesn't take arguments. +cat >confdef2opt.sed <<\_ACEOF +t clear +: clear +s,^[ ]*#[ ]*define[ ][ ]*\([^ (][^ (]*([^)]*)\)[ ]*\(.*\),-D\1=\2,g +t quote +s,^[ ]*#[ ]*define[ ][ ]*\([^ ][^ ]*\)[ ]*\(.*\),-D\1=\2,g +t quote +d +: quote +s,[ `~#$^&*(){}\\|;'"<>?],\\&,g +s,\[,\\&,g +s,\],\\&,g +s,\$,$$,g +p +_ACEOF +# We use echo to avoid assuming a particular line-breaking character. +# The extra dot is to prevent the shell from consuming trailing +# line-breaks from the sub-command output. A line-break within +# single-quotes doesn't work because, if this script is created in a +# platform that uses two characters for line-breaks (e.g., DOS), tr +# would break. +ac_LF_and_DOT=`echo; echo .` +DEFS=`sed -n -f confdef2opt.sed confdefs.h | tr "$ac_LF_and_DOT" ' .'` +rm -f confdef2opt.sed + + +ac_libobjs= +ac_ltlibobjs= +for ac_i in : $LIBOBJS; do test "x$ac_i" = x: && continue + # 1. Remove the extension, and $U if already installed. + ac_i=`echo "$ac_i" | + sed 's/\$U\././;s/\.o$//;s/\.obj$//'` + # 2. Add them. + ac_libobjs="$ac_libobjs $ac_i\$U.$ac_objext" + ac_ltlibobjs="$ac_ltlibobjs $ac_i"'$U.lo' +done +LIBOBJS=$ac_libobjs + +LTLIBOBJS=$ac_ltlibobjs + + +if test -z "${MAINTAINER_MODE_TRUE}" && test -z "${MAINTAINER_MODE_FALSE}"; then + { { echo "$as_me:$LINENO: error: conditional \"MAINTAINER_MODE\" was never defined. +Usually this means the macro was only invoked conditionally." >&5 +echo "$as_me: error: conditional \"MAINTAINER_MODE\" was never defined. +Usually this means the macro was only invoked conditionally." >&2;} + { (exit 1); exit 1; }; } +fi +if test -z "${AMDIS_DEBUG_TRUE}" && test -z "${AMDIS_DEBUG_FALSE}"; then + { { echo "$as_me:$LINENO: error: conditional \"AMDIS_DEBUG\" was never defined. +Usually this means the macro was only invoked conditionally." >&5 +echo "$as_me: error: conditional \"AMDIS_DEBUG\" was never defined. +Usually this means the macro was only invoked conditionally." >&2;} + { (exit 1); exit 1; }; } +fi +if test -z "${AMDIS_INTEL_TRUE}" && test -z "${AMDIS_INTEL_FALSE}"; then + { { echo "$as_me:$LINENO: error: conditional \"AMDIS_INTEL\" was never defined. +Usually this means the macro was only invoked conditionally." >&5 +echo "$as_me: error: conditional \"AMDIS_INTEL\" was never defined. +Usually this means the macro was only invoked conditionally." >&2;} + { (exit 1); exit 1; }; } +fi +if test -z "${AMDIS_OPENMP_TRUE}" && test -z "${AMDIS_OPENMP_FALSE}"; then + { { echo "$as_me:$LINENO: error: conditional \"AMDIS_OPENMP\" was never defined. +Usually this means the macro was only invoked conditionally." >&5 +echo "$as_me: error: conditional \"AMDIS_OPENMP\" was never defined. +Usually this means the macro was only invoked conditionally." >&2;} + { (exit 1); exit 1; }; } +fi +if test -z "${USE_PARALLEL_AMDIS_TRUE}" && test -z "${USE_PARALLEL_AMDIS_FALSE}"; then + { { echo "$as_me:$LINENO: error: conditional \"USE_PARALLEL_AMDIS\" was never defined. +Usually this means the macro was only invoked conditionally." >&5 +echo "$as_me: error: conditional \"USE_PARALLEL_AMDIS\" was never defined. +Usually this means the macro was only invoked conditionally." >&2;} + { (exit 1); exit 1; }; } +fi +if test -z "${ENABLE_UMFPACK_TRUE}" && test -z "${ENABLE_UMFPACK_FALSE}"; then + { { echo "$as_me:$LINENO: error: conditional \"ENABLE_UMFPACK\" was never defined. +Usually this means the macro was only invoked conditionally." >&5 +echo "$as_me: error: conditional \"ENABLE_UMFPACK\" was never defined. +Usually this means the macro was only invoked conditionally." >&2;} + { (exit 1); exit 1; }; } +fi +if test -z "${AMDEP_TRUE}" && test -z "${AMDEP_FALSE}"; then + { { echo "$as_me:$LINENO: error: conditional \"AMDEP\" was never defined. +Usually this means the macro was only invoked conditionally." >&5 +echo "$as_me: error: conditional \"AMDEP\" was never defined. +Usually this means the macro was only invoked conditionally." >&2;} + { (exit 1); exit 1; }; } +fi +if test -z "${am__fastdepCC_TRUE}" && test -z "${am__fastdepCC_FALSE}"; then + { { echo "$as_me:$LINENO: error: conditional \"am__fastdepCC\" was never defined. +Usually this means the macro was only invoked conditionally." >&5 +echo "$as_me: error: conditional \"am__fastdepCC\" was never defined. +Usually this means the macro was only invoked conditionally." >&2;} + { (exit 1); exit 1; }; } +fi +if test -z "${am__fastdepCXX_TRUE}" && test -z "${am__fastdepCXX_FALSE}"; then + { { echo "$as_me:$LINENO: error: conditional \"am__fastdepCXX\" was never defined. +Usually this means the macro was only invoked conditionally." >&5 +echo "$as_me: error: conditional \"am__fastdepCXX\" was never defined. +Usually this means the macro was only invoked conditionally." >&2;} + { (exit 1); exit 1; }; } +fi + +: ${CONFIG_STATUS=./config.status} +ac_clean_files_save=$ac_clean_files +ac_clean_files="$ac_clean_files $CONFIG_STATUS" +{ echo "$as_me:$LINENO: creating $CONFIG_STATUS" >&5 +echo "$as_me: creating $CONFIG_STATUS" >&6;} +cat >$CONFIG_STATUS <<_ACEOF +#! $SHELL +# Generated by $as_me. +# Run this file to recreate the current configuration. +# Compiler output produced by configure, useful for debugging +# configure, is in config.log if it exists. + +debug=false +ac_cs_recheck=false +ac_cs_silent=false +SHELL=\${CONFIG_SHELL-$SHELL} +_ACEOF + +cat >>$CONFIG_STATUS <<\_ACEOF +## --------------------- ## +## M4sh Initialization. ## +## --------------------- ## + +# Be Bourne compatible +if test -n "${ZSH_VERSION+set}" && (emulate sh) >/dev/null 2>&1; then + emulate sh + NULLCMD=: + # Zsh 3.x and 4.x performs word splitting on ${1+"$@"}, which + # is contrary to our usage. Disable this feature. + alias -g '${1+"$@"}'='"$@"' +elif test -n "${BASH_VERSION+set}" && (set -o posix) >/dev/null 2>&1; then + set -o posix +fi +DUALCASE=1; export DUALCASE # for MKS sh + +# Support unset when possible. +if ( (MAIL=60; unset MAIL) || exit) >/dev/null 2>&1; then + as_unset=unset +else + as_unset=false +fi + + +# Work around bugs in pre-3.0 UWIN ksh. +$as_unset ENV MAIL MAILPATH +PS1='$ ' +PS2='> ' +PS4='+ ' + +# NLS nuisances. +for as_var in \ + LANG LANGUAGE LC_ADDRESS LC_ALL LC_COLLATE LC_CTYPE LC_IDENTIFICATION \ + LC_MEASUREMENT LC_MESSAGES LC_MONETARY LC_NAME LC_NUMERIC LC_PAPER \ + LC_TELEPHONE LC_TIME +do + if (set +x; test -z "`(eval $as_var=C; export $as_var) 2>&1`"); then + eval $as_var=C; export $as_var + else + $as_unset $as_var + fi +done + +# Required to use basename. +if expr a : '\(a\)' >/dev/null 2>&1; then + as_expr=expr +else + as_expr=false +fi + +if (basename /) >/dev/null 2>&1 && test "X`basename / 2>&1`" = "X/"; then + as_basename=basename +else + as_basename=false +fi + + +# Name of the executable. +as_me=`$as_basename "$0" || +$as_expr X/"$0" : '.*/\([^/][^/]*\)/*$' \| \ + X"$0" : 'X\(//\)$' \| \ + X"$0" : 'X\(/\)$' \| \ + . : '\(.\)' 2>/dev/null || +echo X/"$0" | + sed '/^.*\/\([^/][^/]*\)\/*$/{ s//\1/; q; } + /^X\/\(\/\/\)$/{ s//\1/; q; } + /^X\/\(\/\).*/{ s//\1/; q; } + s/.*/./; q'` + + +# PATH needs CR, and LINENO needs CR and PATH. +# Avoid depending upon Character Ranges. +as_cr_letters='abcdefghijklmnopqrstuvwxyz' +as_cr_LETTERS='ABCDEFGHIJKLMNOPQRSTUVWXYZ' +as_cr_Letters=$as_cr_letters$as_cr_LETTERS +as_cr_digits='0123456789' +as_cr_alnum=$as_cr_Letters$as_cr_digits + +# The user is always right. +if test "${PATH_SEPARATOR+set}" != set; then + echo "#! /bin/sh" >conf$$.sh + echo "exit 0" >>conf$$.sh + chmod +x conf$$.sh + if (PATH="/nonexistent;."; conf$$.sh) >/dev/null 2>&1; then + PATH_SEPARATOR=';' + else + PATH_SEPARATOR=: + fi + rm -f conf$$.sh +fi + + + as_lineno_1=$LINENO + as_lineno_2=$LINENO + as_lineno_3=`(expr $as_lineno_1 + 1) 2>/dev/null` + test "x$as_lineno_1" != "x$as_lineno_2" && + test "x$as_lineno_3" = "x$as_lineno_2" || { + # Find who we are. Look in the path if we contain no path at all + # relative or not. + case $0 in + *[\\/]* ) as_myself=$0 ;; + *) as_save_IFS=$IFS; IFS=$PATH_SEPARATOR +for as_dir in $PATH +do + IFS=$as_save_IFS + test -z "$as_dir" && as_dir=. + test -r "$as_dir/$0" && as_myself=$as_dir/$0 && break +done + + ;; + esac + # We did not find ourselves, most probably we were run as `sh COMMAND' + # in which case we are not to be found in the path. + if test "x$as_myself" = x; then + as_myself=$0 + fi + if test ! -f "$as_myself"; then + { { echo "$as_me:$LINENO: error: cannot find myself; rerun with an absolute path" >&5 +echo "$as_me: error: cannot find myself; rerun with an absolute path" >&2;} + { (exit 1); exit 1; }; } + fi + case $CONFIG_SHELL in + '') + as_save_IFS=$IFS; IFS=$PATH_SEPARATOR +for as_dir in /bin$PATH_SEPARATOR/usr/bin$PATH_SEPARATOR$PATH +do + IFS=$as_save_IFS + test -z "$as_dir" && as_dir=. + for as_base in sh bash ksh sh5; do + case $as_dir in + /*) + if ("$as_dir/$as_base" -c ' + as_lineno_1=$LINENO + as_lineno_2=$LINENO + as_lineno_3=`(expr $as_lineno_1 + 1) 2>/dev/null` + test "x$as_lineno_1" != "x$as_lineno_2" && + test "x$as_lineno_3" = "x$as_lineno_2" ') 2>/dev/null; then + $as_unset BASH_ENV || test "${BASH_ENV+set}" != set || { BASH_ENV=; export BASH_ENV; } + $as_unset ENV || test "${ENV+set}" != set || { ENV=; export ENV; } + CONFIG_SHELL=$as_dir/$as_base + export CONFIG_SHELL + exec "$CONFIG_SHELL" "$0" ${1+"$@"} + fi;; + esac + done +done +;; + esac + + # Create $as_me.lineno as a copy of $as_myself, but with $LINENO + # uniformly replaced by the line number. The first 'sed' inserts a + # line-number line before each line; the second 'sed' does the real + # work. The second script uses 'N' to pair each line-number line + # with the numbered line, and appends trailing '-' during + # substitution so that $LINENO is not a special case at line end. + # (Raja R Harinath suggested sed '=', and Paul Eggert wrote the + # second 'sed' script. Blame Lee E. McMahon for sed's syntax. :-) + sed '=' <$as_myself | + sed ' + N + s,$,-, + : loop + s,^\(['$as_cr_digits']*\)\(.*\)[$]LINENO\([^'$as_cr_alnum'_]\),\1\2\1\3, + t loop + s,-$,, + s,^['$as_cr_digits']*\n,, + ' >$as_me.lineno && + chmod +x $as_me.lineno || + { { echo "$as_me:$LINENO: error: cannot create $as_me.lineno; rerun with a POSIX shell" >&5 +echo "$as_me: error: cannot create $as_me.lineno; rerun with a POSIX shell" >&2;} + { (exit 1); exit 1; }; } + + # Don't try to exec as it changes $[0], causing all sort of problems + # (the dirname of $[0] is not the place where we might find the + # original and so on. Autoconf is especially sensible to this). + . ./$as_me.lineno + # Exit status is that of the last command. + exit +} + + +case `echo "testing\c"; echo 1,2,3`,`echo -n testing; echo 1,2,3` in + *c*,-n*) ECHO_N= ECHO_C=' +' ECHO_T=' ' ;; + *c*,* ) ECHO_N=-n ECHO_C= ECHO_T= ;; + *) ECHO_N= ECHO_C='\c' ECHO_T= ;; +esac + +if expr a : '\(a\)' >/dev/null 2>&1; then + as_expr=expr +else + as_expr=false +fi + +rm -f conf$$ conf$$.exe conf$$.file +echo >conf$$.file +if ln -s conf$$.file conf$$ 2>/dev/null; then + # We could just check for DJGPP; but this test a) works b) is more generic + # and c) will remain valid once DJGPP supports symlinks (DJGPP 2.04). + if test -f conf$$.exe; then + # Don't use ln at all; we don't have any links + as_ln_s='cp -p' + else + as_ln_s='ln -s' + fi +elif ln conf$$.file conf$$ 2>/dev/null; then + as_ln_s=ln +else + as_ln_s='cp -p' +fi +rm -f conf$$ conf$$.exe conf$$.file + +if mkdir -p . 2>/dev/null; then + as_mkdir_p=: +else + test -d ./-p && rmdir ./-p + as_mkdir_p=false +fi + +as_executable_p="test -f" + +# Sed expression to map a string onto a valid CPP name. +as_tr_cpp="eval sed 'y%*$as_cr_letters%P$as_cr_LETTERS%;s%[^_$as_cr_alnum]%_%g'" + +# Sed expression to map a string onto a valid variable name. +as_tr_sh="eval sed 'y%*+%pp%;s%[^_$as_cr_alnum]%_%g'" + + +# IFS +# We need space, tab and new line, in precisely that order. +as_nl=' +' +IFS=" $as_nl" + +# CDPATH. +$as_unset CDPATH + +exec 6>&1 + +# Open the log real soon, to keep \$[0] and so on meaningful, and to +# report actual input values of CONFIG_FILES etc. instead of their +# values after options handling. Logging --version etc. is OK. +exec 5>>config.log +{ + echo + sed 'h;s/./-/g;s/^.../## /;s/...$/ ##/;p;x;p;x' <<_ASBOX +## Running $as_me. ## +_ASBOX +} >&5 +cat >&5 <<_CSEOF + +This file was extended by $as_me, which was +generated by GNU Autoconf 2.59. Invocation command line was + + CONFIG_FILES = $CONFIG_FILES + CONFIG_HEADERS = $CONFIG_HEADERS + CONFIG_LINKS = $CONFIG_LINKS + CONFIG_COMMANDS = $CONFIG_COMMANDS + $ $0 $@ + +_CSEOF +echo "on `(hostname || uname -n) 2>/dev/null | sed 1q`" >&5 +echo >&5 +_ACEOF + +# Files that config.status was made for. +if test -n "$ac_config_files"; then + echo "config_files=\"$ac_config_files\"" >>$CONFIG_STATUS +fi + +if test -n "$ac_config_headers"; then + echo "config_headers=\"$ac_config_headers\"" >>$CONFIG_STATUS +fi + +if test -n "$ac_config_links"; then + echo "config_links=\"$ac_config_links\"" >>$CONFIG_STATUS +fi + +if test -n "$ac_config_commands"; then + echo "config_commands=\"$ac_config_commands\"" >>$CONFIG_STATUS +fi + +cat >>$CONFIG_STATUS <<\_ACEOF + +ac_cs_usage="\ +\`$as_me' instantiates files from templates according to the +current configuration. + +Usage: $0 [OPTIONS] [FILE]... + + -h, --help print this help, then exit + -V, --version print version number, then exit + -q, --quiet do not print progress messages + -d, --debug don't remove temporary files + --recheck update $as_me by reconfiguring in the same conditions + --file=FILE[:TEMPLATE] + instantiate the configuration file FILE + +Configuration files: +$config_files + +Configuration commands: +$config_commands + +Report bugs to <bug-autoconf@gnu.org>." +_ACEOF + +cat >>$CONFIG_STATUS <<_ACEOF +ac_cs_version="\\ +config.status +configured by $0, generated by GNU Autoconf 2.59, + with options \\"`echo "$ac_configure_args" | sed 's/[\\""\`\$]/\\\\&/g'`\\" + +Copyright (C) 2003 Free Software Foundation, Inc. +This config.status script is free software; the Free Software Foundation +gives unlimited permission to copy, distribute and modify it." +srcdir=$srcdir +INSTALL="$INSTALL" +_ACEOF + +cat >>$CONFIG_STATUS <<\_ACEOF +# If no file are specified by the user, then we need to provide default +# value. By we need to know if files were specified by the user. +ac_need_defaults=: +while test $# != 0 +do + case $1 in + --*=*) + ac_option=`expr "x$1" : 'x\([^=]*\)='` + ac_optarg=`expr "x$1" : 'x[^=]*=\(.*\)'` + ac_shift=: + ;; + -*) + ac_option=$1 + ac_optarg=$2 + ac_shift=shift + ;; + *) # This is not an option, so the user has probably given explicit + # arguments. + ac_option=$1 + ac_need_defaults=false;; + esac + + case $ac_option in + # Handling of the options. +_ACEOF +cat >>$CONFIG_STATUS <<\_ACEOF + -recheck | --recheck | --rechec | --reche | --rech | --rec | --re | --r) + ac_cs_recheck=: ;; + --version | --vers* | -V ) + echo "$ac_cs_version"; exit 0 ;; + --he | --h) + # Conflict between --help and --header + { { echo "$as_me:$LINENO: error: ambiguous option: $1 +Try \`$0 --help' for more information." >&5 +echo "$as_me: error: ambiguous option: $1 +Try \`$0 --help' for more information." >&2;} + { (exit 1); exit 1; }; };; + --help | --hel | -h ) + echo "$ac_cs_usage"; exit 0 ;; + --debug | --d* | -d ) + debug=: ;; + --file | --fil | --fi | --f ) + $ac_shift + CONFIG_FILES="$CONFIG_FILES $ac_optarg" + ac_need_defaults=false;; + --header | --heade | --head | --hea ) + $ac_shift + CONFIG_HEADERS="$CONFIG_HEADERS $ac_optarg" + ac_need_defaults=false;; + -q | -quiet | --quiet | --quie | --qui | --qu | --q \ + | -silent | --silent | --silen | --sile | --sil | --si | --s) + ac_cs_silent=: ;; + + # This is an error. + -*) { { echo "$as_me:$LINENO: error: unrecognized option: $1 +Try \`$0 --help' for more information." >&5 +echo "$as_me: error: unrecognized option: $1 +Try \`$0 --help' for more information." >&2;} + { (exit 1); exit 1; }; } ;; + + *) ac_config_targets="$ac_config_targets $1" ;; + + esac + shift +done + +ac_configure_extra_args= + +if $ac_cs_silent; then + exec 6>/dev/null + ac_configure_extra_args="$ac_configure_extra_args --silent" +fi + +_ACEOF +cat >>$CONFIG_STATUS <<_ACEOF +if \$ac_cs_recheck; then + echo "running $SHELL $0 " $ac_configure_args \$ac_configure_extra_args " --no-create --no-recursion" >&6 + exec $SHELL $0 $ac_configure_args \$ac_configure_extra_args --no-create --no-recursion +fi + +_ACEOF + +cat >>$CONFIG_STATUS <<_ACEOF +# +# INIT-COMMANDS section. +# + +AMDEP_TRUE="$AMDEP_TRUE" ac_aux_dir="$ac_aux_dir" + +_ACEOF + + + +cat >>$CONFIG_STATUS <<\_ACEOF +for ac_config_target in $ac_config_targets +do + case "$ac_config_target" in + # Handling of arguments. + "Makefile" ) CONFIG_FILES="$CONFIG_FILES Makefile" ;; + "lib/Makefile" ) CONFIG_FILES="$CONFIG_FILES lib/Makefile" ;; + "bin/Makefile" ) CONFIG_FILES="$CONFIG_FILES bin/Makefile" ;; + "depfiles" ) CONFIG_COMMANDS="$CONFIG_COMMANDS depfiles" ;; + *) { { echo "$as_me:$LINENO: error: invalid argument: $ac_config_target" >&5 +echo "$as_me: error: invalid argument: $ac_config_target" >&2;} + { (exit 1); exit 1; }; };; + esac +done + +# If the user did not use the arguments to specify the items to instantiate, +# then the envvar interface is used. Set only those that are not. +# We use the long form for the default assignment because of an extremely +# bizarre bug on SunOS 4.1.3. +if $ac_need_defaults; then + test "${CONFIG_FILES+set}" = set || CONFIG_FILES=$config_files + test "${CONFIG_COMMANDS+set}" = set || CONFIG_COMMANDS=$config_commands +fi + +# Have a temporary directory for convenience. Make it in the build tree +# simply because there is no reason to put it here, and in addition, +# creating and moving files from /tmp can sometimes cause problems. +# Create a temporary directory, and hook for its removal unless debugging. +$debug || +{ + trap 'exit_status=$?; rm -rf $tmp && exit $exit_status' 0 + trap '{ (exit 1); exit 1; }' 1 2 13 15 +} + +# Create a (secure) tmp directory for tmp files. + +{ + tmp=`(umask 077 && mktemp -d -q "./confstatXXXXXX") 2>/dev/null` && + test -n "$tmp" && test -d "$tmp" +} || +{ + tmp=./confstat$$-$RANDOM + (umask 077 && mkdir $tmp) +} || +{ + echo "$me: cannot create a temporary directory in ." >&2 + { (exit 1); exit 1; } +} + +_ACEOF + +cat >>$CONFIG_STATUS <<_ACEOF + +# +# CONFIG_FILES section. +# + +# No need to generate the scripts if there are no CONFIG_FILES. +# This happens for instance when ./config.status config.h +if test -n "\$CONFIG_FILES"; then + # Protect against being on the right side of a sed subst in config.status. + sed 's/,@/@@/; s/@,/@@/; s/,;t t\$/@;t t/; /@;t t\$/s/[\\\\&,]/\\\\&/g; + s/@@/,@/; s/@@/@,/; s/@;t t\$/,;t t/' >\$tmp/subs.sed <<\\CEOF +s,@SHELL@,$SHELL,;t t +s,@PATH_SEPARATOR@,$PATH_SEPARATOR,;t t +s,@PACKAGE_NAME@,$PACKAGE_NAME,;t t +s,@PACKAGE_TARNAME@,$PACKAGE_TARNAME,;t t +s,@PACKAGE_VERSION@,$PACKAGE_VERSION,;t t +s,@PACKAGE_STRING@,$PACKAGE_STRING,;t t +s,@PACKAGE_BUGREPORT@,$PACKAGE_BUGREPORT,;t t +s,@exec_prefix@,$exec_prefix,;t t +s,@prefix@,$prefix,;t t +s,@program_transform_name@,$program_transform_name,;t t +s,@bindir@,$bindir,;t t +s,@sbindir@,$sbindir,;t t +s,@libexecdir@,$libexecdir,;t t +s,@datadir@,$datadir,;t t +s,@sysconfdir@,$sysconfdir,;t t +s,@sharedstatedir@,$sharedstatedir,;t t +s,@localstatedir@,$localstatedir,;t t +s,@libdir@,$libdir,;t t +s,@includedir@,$includedir,;t t +s,@oldincludedir@,$oldincludedir,;t t +s,@infodir@,$infodir,;t t +s,@mandir@,$mandir,;t t +s,@build_alias@,$build_alias,;t t +s,@host_alias@,$host_alias,;t t +s,@target_alias@,$target_alias,;t t +s,@DEFS@,$DEFS,;t t +s,@ECHO_C@,$ECHO_C,;t t +s,@ECHO_N@,$ECHO_N,;t t +s,@ECHO_T@,$ECHO_T,;t t +s,@LIBS@,$LIBS,;t t +s,@INSTALL_PROGRAM@,$INSTALL_PROGRAM,;t t +s,@INSTALL_SCRIPT@,$INSTALL_SCRIPT,;t t +s,@INSTALL_DATA@,$INSTALL_DATA,;t t +s,@CYGPATH_W@,$CYGPATH_W,;t t +s,@PACKAGE@,$PACKAGE,;t t +s,@VERSION@,$VERSION,;t t +s,@ACLOCAL@,$ACLOCAL,;t t +s,@AUTOCONF@,$AUTOCONF,;t t +s,@AUTOMAKE@,$AUTOMAKE,;t t +s,@AUTOHEADER@,$AUTOHEADER,;t t +s,@MAKEINFO@,$MAKEINFO,;t t +s,@install_sh@,$install_sh,;t t +s,@STRIP@,$STRIP,;t t +s,@ac_ct_STRIP@,$ac_ct_STRIP,;t t +s,@INSTALL_STRIP_PROGRAM@,$INSTALL_STRIP_PROGRAM,;t t +s,@mkdir_p@,$mkdir_p,;t t +s,@AWK@,$AWK,;t t +s,@SET_MAKE@,$SET_MAKE,;t t +s,@am__leading_dot@,$am__leading_dot,;t t +s,@AMTAR@,$AMTAR,;t t +s,@am__tar@,$am__tar,;t t +s,@am__untar@,$am__untar,;t t +s,@MAINTAINER_MODE_TRUE@,$MAINTAINER_MODE_TRUE,;t t +s,@MAINTAINER_MODE_FALSE@,$MAINTAINER_MODE_FALSE,;t t +s,@MAINT@,$MAINT,;t t +s,@AMDIS_DEBUG_TRUE@,$AMDIS_DEBUG_TRUE,;t t +s,@AMDIS_DEBUG_FALSE@,$AMDIS_DEBUG_FALSE,;t t +s,@CXX@,$CXX,;t t +s,@CC@,$CC,;t t +s,@AMDIS_INTEL_TRUE@,$AMDIS_INTEL_TRUE,;t t +s,@AMDIS_INTEL_FALSE@,$AMDIS_INTEL_FALSE,;t t +s,@AMDIS_OPENMP_TRUE@,$AMDIS_OPENMP_TRUE,;t t +s,@AMDIS_OPENMP_FALSE@,$AMDIS_OPENMP_FALSE,;t t +s,@OPENMP_FLAG@,$OPENMP_FLAG,;t t +s,@MPI_DIR@,$MPI_DIR,;t t +s,@USE_PARALLEL_AMDIS_TRUE@,$USE_PARALLEL_AMDIS_TRUE,;t t +s,@USE_PARALLEL_AMDIS_FALSE@,$USE_PARALLEL_AMDIS_FALSE,;t t +s,@ENABLE_UMFPACK_TRUE@,$ENABLE_UMFPACK_TRUE,;t t +s,@ENABLE_UMFPACK_FALSE@,$ENABLE_UMFPACK_FALSE,;t t +s,@CFLAGS@,$CFLAGS,;t t +s,@LDFLAGS@,$LDFLAGS,;t t +s,@CPPFLAGS@,$CPPFLAGS,;t t +s,@ac_ct_CC@,$ac_ct_CC,;t t +s,@EXEEXT@,$EXEEXT,;t t +s,@OBJEXT@,$OBJEXT,;t t +s,@DEPDIR@,$DEPDIR,;t t +s,@am__include@,$am__include,;t t +s,@am__quote@,$am__quote,;t t +s,@AMDEP_TRUE@,$AMDEP_TRUE,;t t +s,@AMDEP_FALSE@,$AMDEP_FALSE,;t t +s,@AMDEPBACKSLASH@,$AMDEPBACKSLASH,;t t +s,@CCDEPMODE@,$CCDEPMODE,;t t +s,@am__fastdepCC_TRUE@,$am__fastdepCC_TRUE,;t t +s,@am__fastdepCC_FALSE@,$am__fastdepCC_FALSE,;t t +s,@CXXFLAGS@,$CXXFLAGS,;t t +s,@ac_ct_CXX@,$ac_ct_CXX,;t t +s,@CXXDEPMODE@,$CXXDEPMODE,;t t +s,@am__fastdepCXX_TRUE@,$am__fastdepCXX_TRUE,;t t +s,@am__fastdepCXX_FALSE@,$am__fastdepCXX_FALSE,;t t +s,@build@,$build,;t t +s,@build_cpu@,$build_cpu,;t t +s,@build_vendor@,$build_vendor,;t t +s,@build_os@,$build_os,;t t +s,@host@,$host,;t t +s,@host_cpu@,$host_cpu,;t t +s,@host_vendor@,$host_vendor,;t t +s,@host_os@,$host_os,;t t +s,@SED@,$SED,;t t +s,@EGREP@,$EGREP,;t t +s,@LN_S@,$LN_S,;t t +s,@ECHO@,$ECHO,;t t +s,@AR@,$AR,;t t +s,@ac_ct_AR@,$ac_ct_AR,;t t +s,@RANLIB@,$RANLIB,;t t +s,@ac_ct_RANLIB@,$ac_ct_RANLIB,;t t +s,@CPP@,$CPP,;t t +s,@CXXCPP@,$CXXCPP,;t t +s,@F77@,$F77,;t t +s,@FFLAGS@,$FFLAGS,;t t +s,@ac_ct_F77@,$ac_ct_F77,;t t +s,@LIBTOOL@,$LIBTOOL,;t t +s,@LIBOBJS@,$LIBOBJS,;t t +s,@LTLIBOBJS@,$LTLIBOBJS,;t t +CEOF + +_ACEOF + + cat >>$CONFIG_STATUS <<\_ACEOF + # Split the substitutions into bite-sized pieces for seds with + # small command number limits, like on Digital OSF/1 and HP-UX. + ac_max_sed_lines=48 + ac_sed_frag=1 # Number of current file. + ac_beg=1 # First line for current file. + ac_end=$ac_max_sed_lines # Line after last line for current file. + ac_more_lines=: + ac_sed_cmds= + while $ac_more_lines; do + if test $ac_beg -gt 1; then + sed "1,${ac_beg}d; ${ac_end}q" $tmp/subs.sed >$tmp/subs.frag + else + sed "${ac_end}q" $tmp/subs.sed >$tmp/subs.frag + fi + if test ! -s $tmp/subs.frag; then + ac_more_lines=false + else + # The purpose of the label and of the branching condition is to + # speed up the sed processing (if there are no `@' at all, there + # is no need to browse any of the substitutions). + # These are the two extra sed commands mentioned above. + (echo ':t + /@[a-zA-Z_][a-zA-Z_0-9]*@/!b' && cat $tmp/subs.frag) >$tmp/subs-$ac_sed_frag.sed + if test -z "$ac_sed_cmds"; then + ac_sed_cmds="sed -f $tmp/subs-$ac_sed_frag.sed" + else + ac_sed_cmds="$ac_sed_cmds | sed -f $tmp/subs-$ac_sed_frag.sed" + fi + ac_sed_frag=`expr $ac_sed_frag + 1` + ac_beg=$ac_end + ac_end=`expr $ac_end + $ac_max_sed_lines` + fi + done + if test -z "$ac_sed_cmds"; then + ac_sed_cmds=cat + fi +fi # test -n "$CONFIG_FILES" + +_ACEOF +cat >>$CONFIG_STATUS <<\_ACEOF +for ac_file in : $CONFIG_FILES; do test "x$ac_file" = x: && continue + # Support "outfile[:infile[:infile...]]", defaulting infile="outfile.in". + case $ac_file in + - | *:- | *:-:* ) # input from stdin + cat >$tmp/stdin + ac_file_in=`echo "$ac_file" | sed 's,[^:]*:,,'` + ac_file=`echo "$ac_file" | sed 's,:.*,,'` ;; + *:* ) ac_file_in=`echo "$ac_file" | sed 's,[^:]*:,,'` + ac_file=`echo "$ac_file" | sed 's,:.*,,'` ;; + * ) ac_file_in=$ac_file.in ;; + esac + + # Compute @srcdir@, @top_srcdir@, and @INSTALL@ for subdirectories. + ac_dir=`(dirname "$ac_file") 2>/dev/null || +$as_expr X"$ac_file" : 'X\(.*[^/]\)//*[^/][^/]*/*$' \| \ + X"$ac_file" : 'X\(//\)[^/]' \| \ + X"$ac_file" : 'X\(//\)$' \| \ + X"$ac_file" : 'X\(/\)' \| \ + . : '\(.\)' 2>/dev/null || +echo X"$ac_file" | + sed '/^X\(.*[^/]\)\/\/*[^/][^/]*\/*$/{ s//\1/; q; } + /^X\(\/\/\)[^/].*/{ s//\1/; q; } + /^X\(\/\/\)$/{ s//\1/; q; } + /^X\(\/\).*/{ s//\1/; q; } + s/.*/./; q'` + { if $as_mkdir_p; then + mkdir -p "$ac_dir" + else + as_dir="$ac_dir" + as_dirs= + while test ! -d "$as_dir"; do + as_dirs="$as_dir $as_dirs" + as_dir=`(dirname "$as_dir") 2>/dev/null || +$as_expr X"$as_dir" : 'X\(.*[^/]\)//*[^/][^/]*/*$' \| \ + X"$as_dir" : 'X\(//\)[^/]' \| \ + X"$as_dir" : 'X\(//\)$' \| \ + X"$as_dir" : 'X\(/\)' \| \ + . : '\(.\)' 2>/dev/null || +echo X"$as_dir" | + sed '/^X\(.*[^/]\)\/\/*[^/][^/]*\/*$/{ s//\1/; q; } + /^X\(\/\/\)[^/].*/{ s//\1/; q; } + /^X\(\/\/\)$/{ s//\1/; q; } + /^X\(\/\).*/{ s//\1/; q; } + s/.*/./; q'` + done + test ! -n "$as_dirs" || mkdir $as_dirs + fi || { { echo "$as_me:$LINENO: error: cannot create directory \"$ac_dir\"" >&5 +echo "$as_me: error: cannot create directory \"$ac_dir\"" >&2;} + { (exit 1); exit 1; }; }; } + + ac_builddir=. + +if test "$ac_dir" != .; then + ac_dir_suffix=/`echo "$ac_dir" | sed 's,^\.[\\/],,'` + # A "../" for each directory in $ac_dir_suffix. + ac_top_builddir=`echo "$ac_dir_suffix" | sed 's,/[^\\/]*,../,g'` +else + ac_dir_suffix= ac_top_builddir= +fi + +case $srcdir in + .) # No --srcdir option. We are building in place. + ac_srcdir=. + if test -z "$ac_top_builddir"; then + ac_top_srcdir=. + else + ac_top_srcdir=`echo $ac_top_builddir | sed 's,/$,,'` + fi ;; + [\\/]* | ?:[\\/]* ) # Absolute path. + ac_srcdir=$srcdir$ac_dir_suffix; + ac_top_srcdir=$srcdir ;; + *) # Relative path. + ac_srcdir=$ac_top_builddir$srcdir$ac_dir_suffix + ac_top_srcdir=$ac_top_builddir$srcdir ;; +esac + +# Do not use `cd foo && pwd` to compute absolute paths, because +# the directories may not exist. +case `pwd` in +.) ac_abs_builddir="$ac_dir";; +*) + case "$ac_dir" in + .) ac_abs_builddir=`pwd`;; + [\\/]* | ?:[\\/]* ) ac_abs_builddir="$ac_dir";; + *) ac_abs_builddir=`pwd`/"$ac_dir";; + esac;; +esac +case $ac_abs_builddir in +.) ac_abs_top_builddir=${ac_top_builddir}.;; +*) + case ${ac_top_builddir}. in + .) ac_abs_top_builddir=$ac_abs_builddir;; + [\\/]* | ?:[\\/]* ) ac_abs_top_builddir=${ac_top_builddir}.;; + *) ac_abs_top_builddir=$ac_abs_builddir/${ac_top_builddir}.;; + esac;; +esac +case $ac_abs_builddir in +.) ac_abs_srcdir=$ac_srcdir;; +*) + case $ac_srcdir in + .) ac_abs_srcdir=$ac_abs_builddir;; + [\\/]* | ?:[\\/]* ) ac_abs_srcdir=$ac_srcdir;; + *) ac_abs_srcdir=$ac_abs_builddir/$ac_srcdir;; + esac;; +esac +case $ac_abs_builddir in +.) ac_abs_top_srcdir=$ac_top_srcdir;; +*) + case $ac_top_srcdir in + .) ac_abs_top_srcdir=$ac_abs_builddir;; + [\\/]* | ?:[\\/]* ) ac_abs_top_srcdir=$ac_top_srcdir;; + *) ac_abs_top_srcdir=$ac_abs_builddir/$ac_top_srcdir;; + esac;; +esac + + + case $INSTALL in + [\\/$]* | ?:[\\/]* ) ac_INSTALL=$INSTALL ;; + *) ac_INSTALL=$ac_top_builddir$INSTALL ;; + esac + + if test x"$ac_file" != x-; then + { echo "$as_me:$LINENO: creating $ac_file" >&5 +echo "$as_me: creating $ac_file" >&6;} + rm -f "$ac_file" + fi + # Let's still pretend it is `configure' which instantiates (i.e., don't + # use $as_me), people would be surprised to read: + # /* config.h. Generated by config.status. */ + if test x"$ac_file" = x-; then + configure_input= + else + configure_input="$ac_file. " + fi + configure_input=$configure_input"Generated from `echo $ac_file_in | + sed 's,.*/,,'` by configure." + + # First look for the input files in the build tree, otherwise in the + # src tree. + ac_file_inputs=`IFS=: + for f in $ac_file_in; do + case $f in + -) echo $tmp/stdin ;; + [\\/$]*) + # Absolute (can't be DOS-style, as IFS=:) + test -f "$f" || { { echo "$as_me:$LINENO: error: cannot find input file: $f" >&5 +echo "$as_me: error: cannot find input file: $f" >&2;} + { (exit 1); exit 1; }; } + echo "$f";; + *) # Relative + if test -f "$f"; then + # Build tree + echo "$f" + elif test -f "$srcdir/$f"; then + # Source tree + echo "$srcdir/$f" + else + # /dev/null tree + { { echo "$as_me:$LINENO: error: cannot find input file: $f" >&5 +echo "$as_me: error: cannot find input file: $f" >&2;} + { (exit 1); exit 1; }; } + fi;; + esac + done` || { (exit 1); exit 1; } +_ACEOF +cat >>$CONFIG_STATUS <<_ACEOF + sed "$ac_vpsub +$extrasub +_ACEOF +cat >>$CONFIG_STATUS <<\_ACEOF +:t +/@[a-zA-Z_][a-zA-Z_0-9]*@/!b +s,@configure_input@,$configure_input,;t t +s,@srcdir@,$ac_srcdir,;t t +s,@abs_srcdir@,$ac_abs_srcdir,;t t +s,@top_srcdir@,$ac_top_srcdir,;t t +s,@abs_top_srcdir@,$ac_abs_top_srcdir,;t t +s,@builddir@,$ac_builddir,;t t +s,@abs_builddir@,$ac_abs_builddir,;t t +s,@top_builddir@,$ac_top_builddir,;t t +s,@abs_top_builddir@,$ac_abs_top_builddir,;t t +s,@INSTALL@,$ac_INSTALL,;t t +" $ac_file_inputs | (eval "$ac_sed_cmds") >$tmp/out + rm -f $tmp/stdin + if test x"$ac_file" != x-; then + mv $tmp/out $ac_file + else + cat $tmp/out + rm -f $tmp/out + fi + +done +_ACEOF +cat >>$CONFIG_STATUS <<\_ACEOF + +# +# CONFIG_COMMANDS section. +# +for ac_file in : $CONFIG_COMMANDS; do test "x$ac_file" = x: && continue + ac_dest=`echo "$ac_file" | sed 's,:.*,,'` + ac_source=`echo "$ac_file" | sed 's,[^:]*:,,'` + ac_dir=`(dirname "$ac_dest") 2>/dev/null || +$as_expr X"$ac_dest" : 'X\(.*[^/]\)//*[^/][^/]*/*$' \| \ + X"$ac_dest" : 'X\(//\)[^/]' \| \ + X"$ac_dest" : 'X\(//\)$' \| \ + X"$ac_dest" : 'X\(/\)' \| \ + . : '\(.\)' 2>/dev/null || +echo X"$ac_dest" | + sed '/^X\(.*[^/]\)\/\/*[^/][^/]*\/*$/{ s//\1/; q; } + /^X\(\/\/\)[^/].*/{ s//\1/; q; } + /^X\(\/\/\)$/{ s//\1/; q; } + /^X\(\/\).*/{ s//\1/; q; } + s/.*/./; q'` + { if $as_mkdir_p; then + mkdir -p "$ac_dir" + else + as_dir="$ac_dir" + as_dirs= + while test ! -d "$as_dir"; do + as_dirs="$as_dir $as_dirs" + as_dir=`(dirname "$as_dir") 2>/dev/null || +$as_expr X"$as_dir" : 'X\(.*[^/]\)//*[^/][^/]*/*$' \| \ + X"$as_dir" : 'X\(//\)[^/]' \| \ + X"$as_dir" : 'X\(//\)$' \| \ + X"$as_dir" : 'X\(/\)' \| \ + . : '\(.\)' 2>/dev/null || +echo X"$as_dir" | + sed '/^X\(.*[^/]\)\/\/*[^/][^/]*\/*$/{ s//\1/; q; } + /^X\(\/\/\)[^/].*/{ s//\1/; q; } + /^X\(\/\/\)$/{ s//\1/; q; } + /^X\(\/\).*/{ s//\1/; q; } + s/.*/./; q'` + done + test ! -n "$as_dirs" || mkdir $as_dirs + fi || { { echo "$as_me:$LINENO: error: cannot create directory \"$ac_dir\"" >&5 +echo "$as_me: error: cannot create directory \"$ac_dir\"" >&2;} + { (exit 1); exit 1; }; }; } + + ac_builddir=. + +if test "$ac_dir" != .; then + ac_dir_suffix=/`echo "$ac_dir" | sed 's,^\.[\\/],,'` + # A "../" for each directory in $ac_dir_suffix. + ac_top_builddir=`echo "$ac_dir_suffix" | sed 's,/[^\\/]*,../,g'` +else + ac_dir_suffix= ac_top_builddir= +fi + +case $srcdir in + .) # No --srcdir option. We are building in place. + ac_srcdir=. + if test -z "$ac_top_builddir"; then + ac_top_srcdir=. + else + ac_top_srcdir=`echo $ac_top_builddir | sed 's,/$,,'` + fi ;; + [\\/]* | ?:[\\/]* ) # Absolute path. + ac_srcdir=$srcdir$ac_dir_suffix; + ac_top_srcdir=$srcdir ;; + *) # Relative path. + ac_srcdir=$ac_top_builddir$srcdir$ac_dir_suffix + ac_top_srcdir=$ac_top_builddir$srcdir ;; +esac + +# Do not use `cd foo && pwd` to compute absolute paths, because +# the directories may not exist. +case `pwd` in +.) ac_abs_builddir="$ac_dir";; +*) + case "$ac_dir" in + .) ac_abs_builddir=`pwd`;; + [\\/]* | ?:[\\/]* ) ac_abs_builddir="$ac_dir";; + *) ac_abs_builddir=`pwd`/"$ac_dir";; + esac;; +esac +case $ac_abs_builddir in +.) ac_abs_top_builddir=${ac_top_builddir}.;; +*) + case ${ac_top_builddir}. in + .) ac_abs_top_builddir=$ac_abs_builddir;; + [\\/]* | ?:[\\/]* ) ac_abs_top_builddir=${ac_top_builddir}.;; + *) ac_abs_top_builddir=$ac_abs_builddir/${ac_top_builddir}.;; + esac;; +esac +case $ac_abs_builddir in +.) ac_abs_srcdir=$ac_srcdir;; +*) + case $ac_srcdir in + .) ac_abs_srcdir=$ac_abs_builddir;; + [\\/]* | ?:[\\/]* ) ac_abs_srcdir=$ac_srcdir;; + *) ac_abs_srcdir=$ac_abs_builddir/$ac_srcdir;; + esac;; +esac +case $ac_abs_builddir in +.) ac_abs_top_srcdir=$ac_top_srcdir;; +*) + case $ac_top_srcdir in + .) ac_abs_top_srcdir=$ac_abs_builddir;; + [\\/]* | ?:[\\/]* ) ac_abs_top_srcdir=$ac_top_srcdir;; + *) ac_abs_top_srcdir=$ac_abs_builddir/$ac_top_srcdir;; + esac;; +esac + + + { echo "$as_me:$LINENO: executing $ac_dest commands" >&5 +echo "$as_me: executing $ac_dest commands" >&6;} + case $ac_dest in + depfiles ) test x"$AMDEP_TRUE" != x"" || for mf in $CONFIG_FILES; do + # Strip MF so we end up with the name of the file. + mf=`echo "$mf" | sed -e 's/:.*$//'` + # Check whether this is an Automake generated Makefile or not. + # We used to match only the files named `Makefile.in', but + # some people rename them; so instead we look at the file content. + # Grep'ing the first line is not enough: some people post-process + # each Makefile.in and add a new line on top of each file to say so. + # So let's grep whole file. + if grep '^#.*generated by automake' $mf > /dev/null 2>&1; then + dirpart=`(dirname "$mf") 2>/dev/null || +$as_expr X"$mf" : 'X\(.*[^/]\)//*[^/][^/]*/*$' \| \ + X"$mf" : 'X\(//\)[^/]' \| \ + X"$mf" : 'X\(//\)$' \| \ + X"$mf" : 'X\(/\)' \| \ + . : '\(.\)' 2>/dev/null || +echo X"$mf" | + sed '/^X\(.*[^/]\)\/\/*[^/][^/]*\/*$/{ s//\1/; q; } + /^X\(\/\/\)[^/].*/{ s//\1/; q; } + /^X\(\/\/\)$/{ s//\1/; q; } + /^X\(\/\).*/{ s//\1/; q; } + s/.*/./; q'` + else + continue + fi + # Extract the definition of DEPDIR, am__include, and am__quote + # from the Makefile without running `make'. + DEPDIR=`sed -n 's/^DEPDIR = //p' < "$mf"` + test -z "$DEPDIR" && continue + am__include=`sed -n 's/^am__include = //p' < "$mf"` + test -z "am__include" && continue + am__quote=`sed -n 's/^am__quote = //p' < "$mf"` + # When using ansi2knr, U may be empty or an underscore; expand it + U=`sed -n 's/^U = //p' < "$mf"` + # Find all dependency output files, they are included files with + # $(DEPDIR) in their names. We invoke sed twice because it is the + # simplest approach to changing $(DEPDIR) to its actual value in the + # expansion. + for file in `sed -n " + s/^$am__include $am__quote\(.*(DEPDIR).*\)$am__quote"'$/\1/p' <"$mf" | \ + sed -e 's/\$(DEPDIR)/'"$DEPDIR"'/g' -e 's/\$U/'"$U"'/g'`; do + # Make sure the directory exists. + test -f "$dirpart/$file" && continue + fdir=`(dirname "$file") 2>/dev/null || +$as_expr X"$file" : 'X\(.*[^/]\)//*[^/][^/]*/*$' \| \ + X"$file" : 'X\(//\)[^/]' \| \ + X"$file" : 'X\(//\)$' \| \ + X"$file" : 'X\(/\)' \| \ + . : '\(.\)' 2>/dev/null || +echo X"$file" | + sed '/^X\(.*[^/]\)\/\/*[^/][^/]*\/*$/{ s//\1/; q; } + /^X\(\/\/\)[^/].*/{ s//\1/; q; } + /^X\(\/\/\)$/{ s//\1/; q; } + /^X\(\/\).*/{ s//\1/; q; } + s/.*/./; q'` + { if $as_mkdir_p; then + mkdir -p $dirpart/$fdir + else + as_dir=$dirpart/$fdir + as_dirs= + while test ! -d "$as_dir"; do + as_dirs="$as_dir $as_dirs" + as_dir=`(dirname "$as_dir") 2>/dev/null || +$as_expr X"$as_dir" : 'X\(.*[^/]\)//*[^/][^/]*/*$' \| \ + X"$as_dir" : 'X\(//\)[^/]' \| \ + X"$as_dir" : 'X\(//\)$' \| \ + X"$as_dir" : 'X\(/\)' \| \ + . : '\(.\)' 2>/dev/null || +echo X"$as_dir" | + sed '/^X\(.*[^/]\)\/\/*[^/][^/]*\/*$/{ s//\1/; q; } + /^X\(\/\/\)[^/].*/{ s//\1/; q; } + /^X\(\/\/\)$/{ s//\1/; q; } + /^X\(\/\).*/{ s//\1/; q; } + s/.*/./; q'` + done + test ! -n "$as_dirs" || mkdir $as_dirs + fi || { { echo "$as_me:$LINENO: error: cannot create directory $dirpart/$fdir" >&5 +echo "$as_me: error: cannot create directory $dirpart/$fdir" >&2;} + { (exit 1); exit 1; }; }; } + + # echo "creating $dirpart/$file" + echo '# dummy' > "$dirpart/$file" + done +done + ;; + esac +done +_ACEOF + +cat >>$CONFIG_STATUS <<\_ACEOF + +{ (exit 0); exit 0; } +_ACEOF +chmod +x $CONFIG_STATUS +ac_clean_files=$ac_clean_files_save + + +# configure is writing to config.log, and then calls config.status. +# config.status does its own redirection, appending to config.log. +# Unfortunately, on DOS this fails, as config.log is still kept open +# by configure, so config.status won't be able to write to it; its +# output is simply discarded. So we exec the FD to /dev/null, +# effectively closing config.log, so it can be properly (re)opened and +# appended to by config.status. When coming back to configure, we +# need to make the FD available again. +if test "$no_create" != yes; then + ac_cs_success=: + ac_config_status_args= + test "$silent" = yes && + ac_config_status_args="$ac_config_status_args --quiet" + exec 5>/dev/null + $SHELL $CONFIG_STATUS $ac_config_status_args || ac_cs_success=false + exec 5>>config.log + # Use ||, not &&, to avoid exiting from the if with $? = 1, which + # would make configure fail if this is the last instruction. + $ac_cs_success || { (exit 1); exit 1; } +fi diff --git a/AMDiS/configure.ac b/AMDiS/configure.ac new file mode 100644 index 0000000000000000000000000000000000000000..de4166ec3328a47c78454c28477dfec3276b88ca --- /dev/null +++ b/AMDiS/configure.ac @@ -0,0 +1,83 @@ +AC_INIT() +AM_INIT_AUTOMAKE(AMDiS, 0.1) +AM_MAINTAINER_MODE + +#AC_DISABLE_SHARED + +AC_ARG_ENABLE(debug, + [ --enable-debug Turn on debugging], + [case "${enableval}" in + yes) debug=true ;; + no) debug=false ;; + *) AC_MSG_ERROR(bad value ${enableval} for --enable-debug) ;; + esac],[debug=false]) +AM_CONDITIONAL(AMDIS_DEBUG, test $debug = true) + +AC_ARG_ENABLE(intel, + [ --enable-intel Turn on support for the Intel compiler], + [case "${enableval}" in + yes) intel=true ;; + no) intel=false ;; + *) AC_MSG_ERROR(bad value ${enableval} for --enable-intel) ;; + esac],[intel=false]) +if test $intel = true +then + AC_SUBST(CXX, icpc) + AC_SUBST(CC, icc) +fi +AM_CONDITIONAL(AMDIS_INTEL, test $intel = true) + +AC_ARG_ENABLE(openmp, + [ --enable-openmp Turn on support for the Intel compiler], + [case "${enableval}" in + yes) openmp=true ;; + no) openmp=false ;; + *) AC_MSG_ERROR(bad value ${enableval} for --enable-openmp) ;; + esac],[openmp=false]) +AM_CONDITIONAL(AMDIS_OPENMP, test $openmp = true) + +if test $openmp = true ; then + if test $intel = true ; then + AC_SUBST(OPENMP_FLAG, -openmp) + else + AC_SUBST(OPENMP_FLAG, -fopenmp) + fi +else + OPENMP_FLAG= + AC_SUBST(OPENMP_FLAG, ) +fi + +AC_ARG_WITH(mpi, [ --with-mpi=MPI_DIR], mpidir=$withval, mpidir=no) +AC_SUBST(MPI_DIR, $mpidir) +if test $mpidir != no ; then + AC_SUBST(CXX, $mpidir/bin/mpiCC) + AC_SUBST(CC, $mpidir/bin/mpicc) +fi + +AC_ARG_ENABLE(parmetis, + [ --enable-parmetis Compile with the ParMetis library], + [case "${enableval}" in + yes) parmetis=true ;; + no) parmetis=false ;; + *) AC_MSG_ERROR(bad value ${enableval} for --enable-parmetis) ;; + esac],[parmetis=false]) +AM_CONDITIONAL(USE_PARALLEL_AMDIS, test $parmetis = true) + +AC_ARG_ENABLE(umfpack, + [ --enable-umfpack Compile with the UMFPACK direct solver library], + [case "${enableval}" in + yes) umfpack=true ;; + no) umfpack=false ;; + *) AC_MSG_ERROR(bad value ${enableval} for --enable-umfpack) ;; + esac],[umfpack=false]) +AM_CONDITIONAL(ENABLE_UMFPACK, test $umfpack = true) + +AC_PROG_CC +AC_PROG_CXX +AC_PROG_LIBTOOL +AC_CONFIG_FILES([ + Makefile + lib/Makefile + bin/Makefile + ]) +AC_OUTPUT \ No newline at end of file diff --git a/AMDiS/depcomp b/AMDiS/depcomp new file mode 100755 index 0000000000000000000000000000000000000000..04701da536f33a7c39d7bb01b87a70ae3a776df5 --- /dev/null +++ b/AMDiS/depcomp @@ -0,0 +1,530 @@ +#! /bin/sh +# depcomp - compile a program generating dependencies as side-effects + +scriptversion=2005-07-09.11 + +# Copyright (C) 1999, 2000, 2003, 2004, 2005 Free Software Foundation, Inc. + +# 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, 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. + +# As a special exception to the GNU General Public License, if you +# distribute this file as part of a program that contains a +# configuration script generated by Autoconf, you may include it under +# the same distribution terms that you use for the rest of that program. + +# Originally written by Alexandre Oliva <oliva@dcc.unicamp.br>. + +case $1 in + '') + echo "$0: No command. Try \`$0 --help' for more information." 1>&2 + exit 1; + ;; + -h | --h*) + cat <<\EOF +Usage: depcomp [--help] [--version] PROGRAM [ARGS] + +Run PROGRAMS ARGS to compile a file, generating dependencies +as side-effects. + +Environment variables: + depmode Dependency tracking mode. + source Source file read by `PROGRAMS ARGS'. + object Object file output by `PROGRAMS ARGS'. + DEPDIR directory where to store dependencies. + depfile Dependency file to output. + tmpdepfile Temporary file to use when outputing dependencies. + libtool Whether libtool is used (yes/no). + +Report bugs to <bug-automake@gnu.org>. +EOF + exit $? + ;; + -v | --v*) + echo "depcomp $scriptversion" + exit $? + ;; +esac + +if test -z "$depmode" || test -z "$source" || test -z "$object"; then + echo "depcomp: Variables source, object and depmode must be set" 1>&2 + exit 1 +fi + +# Dependencies for sub/bar.o or sub/bar.obj go into sub/.deps/bar.Po. +depfile=${depfile-`echo "$object" | + sed 's|[^\\/]*$|'${DEPDIR-.deps}'/&|;s|\.\([^.]*\)$|.P\1|;s|Pobj$|Po|'`} +tmpdepfile=${tmpdepfile-`echo "$depfile" | sed 's/\.\([^.]*\)$/.T\1/'`} + +rm -f "$tmpdepfile" + +# Some modes work just like other modes, but use different flags. We +# parameterize here, but still list the modes in the big case below, +# to make depend.m4 easier to write. Note that we *cannot* use a case +# here, because this file can only contain one case statement. +if test "$depmode" = hp; then + # HP compiler uses -M and no extra arg. + gccflag=-M + depmode=gcc +fi + +if test "$depmode" = dashXmstdout; then + # This is just like dashmstdout with a different argument. + dashmflag=-xM + depmode=dashmstdout +fi + +case "$depmode" in +gcc3) +## gcc 3 implements dependency tracking that does exactly what +## we want. Yay! Note: for some reason libtool 1.4 doesn't like +## it if -MD -MP comes after the -MF stuff. Hmm. + "$@" -MT "$object" -MD -MP -MF "$tmpdepfile" + stat=$? + if test $stat -eq 0; then : + else + rm -f "$tmpdepfile" + exit $stat + fi + mv "$tmpdepfile" "$depfile" + ;; + +gcc) +## There are various ways to get dependency output from gcc. Here's +## why we pick this rather obscure method: +## - Don't want to use -MD because we'd like the dependencies to end +## up in a subdir. Having to rename by hand is ugly. +## (We might end up doing this anyway to support other compilers.) +## - The DEPENDENCIES_OUTPUT environment variable makes gcc act like +## -MM, not -M (despite what the docs say). +## - Using -M directly means running the compiler twice (even worse +## than renaming). + if test -z "$gccflag"; then + gccflag=-MD, + fi + "$@" -Wp,"$gccflag$tmpdepfile" + stat=$? + if test $stat -eq 0; then : + else + rm -f "$tmpdepfile" + exit $stat + fi + rm -f "$depfile" + echo "$object : \\" > "$depfile" + alpha=ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz +## The second -e expression handles DOS-style file names with drive letters. + sed -e 's/^[^:]*: / /' \ + -e 's/^['$alpha']:\/[^:]*: / /' < "$tmpdepfile" >> "$depfile" +## This next piece of magic avoids the `deleted header file' problem. +## The problem is that when a header file which appears in a .P file +## is deleted, the dependency causes make to die (because there is +## typically no way to rebuild the header). We avoid this by adding +## dummy dependencies for each header file. Too bad gcc doesn't do +## this for us directly. + tr ' ' ' +' < "$tmpdepfile" | +## Some versions of gcc put a space before the `:'. On the theory +## that the space means something, we add a space to the output as +## well. +## Some versions of the HPUX 10.20 sed can't process this invocation +## correctly. Breaking it into two sed invocations is a workaround. + sed -e 's/^\\$//' -e '/^$/d' -e '/:$/d' | sed -e 's/$/ :/' >> "$depfile" + rm -f "$tmpdepfile" + ;; + +hp) + # This case exists only to let depend.m4 do its work. It works by + # looking at the text of this script. This case will never be run, + # since it is checked for above. + exit 1 + ;; + +sgi) + if test "$libtool" = yes; then + "$@" "-Wp,-MDupdate,$tmpdepfile" + else + "$@" -MDupdate "$tmpdepfile" + fi + stat=$? + if test $stat -eq 0; then : + else + rm -f "$tmpdepfile" + exit $stat + fi + rm -f "$depfile" + + if test -f "$tmpdepfile"; then # yes, the sourcefile depend on other files + echo "$object : \\" > "$depfile" + + # Clip off the initial element (the dependent). Don't try to be + # clever and replace this with sed code, as IRIX sed won't handle + # lines with more than a fixed number of characters (4096 in + # IRIX 6.2 sed, 8192 in IRIX 6.5). We also remove comment lines; + # the IRIX cc adds comments like `#:fec' to the end of the + # dependency line. + tr ' ' ' +' < "$tmpdepfile" \ + | sed -e 's/^.*\.o://' -e 's/#.*$//' -e '/^$/ d' | \ + tr ' +' ' ' >> $depfile + echo >> $depfile + + # The second pass generates a dummy entry for each header file. + tr ' ' ' +' < "$tmpdepfile" \ + | sed -e 's/^.*\.o://' -e 's/#.*$//' -e '/^$/ d' -e 's/$/:/' \ + >> $depfile + else + # The sourcefile does not contain any dependencies, so just + # store a dummy comment line, to avoid errors with the Makefile + # "include basename.Plo" scheme. + echo "#dummy" > "$depfile" + fi + rm -f "$tmpdepfile" + ;; + +aix) + # The C for AIX Compiler uses -M and outputs the dependencies + # in a .u file. In older versions, this file always lives in the + # current directory. Also, the AIX compiler puts `$object:' at the + # start of each line; $object doesn't have directory information. + # Version 6 uses the directory in both cases. + stripped=`echo "$object" | sed 's/\(.*\)\..*$/\1/'` + tmpdepfile="$stripped.u" + if test "$libtool" = yes; then + "$@" -Wc,-M + else + "$@" -M + fi + stat=$? + + if test -f "$tmpdepfile"; then : + else + stripped=`echo "$stripped" | sed 's,^.*/,,'` + tmpdepfile="$stripped.u" + fi + + if test $stat -eq 0; then : + else + rm -f "$tmpdepfile" + exit $stat + fi + + if test -f "$tmpdepfile"; then + outname="$stripped.o" + # Each line is of the form `foo.o: dependent.h'. + # Do two passes, one to just change these to + # `$object: dependent.h' and one to simply `dependent.h:'. + sed -e "s,^$outname:,$object :," < "$tmpdepfile" > "$depfile" + sed -e "s,^$outname: \(.*\)$,\1:," < "$tmpdepfile" >> "$depfile" + else + # The sourcefile does not contain any dependencies, so just + # store a dummy comment line, to avoid errors with the Makefile + # "include basename.Plo" scheme. + echo "#dummy" > "$depfile" + fi + rm -f "$tmpdepfile" + ;; + +icc) + # Intel's C compiler understands `-MD -MF file'. However on + # icc -MD -MF foo.d -c -o sub/foo.o sub/foo.c + # ICC 7.0 will fill foo.d with something like + # foo.o: sub/foo.c + # foo.o: sub/foo.h + # which is wrong. We want: + # sub/foo.o: sub/foo.c + # sub/foo.o: sub/foo.h + # sub/foo.c: + # sub/foo.h: + # ICC 7.1 will output + # foo.o: sub/foo.c sub/foo.h + # and will wrap long lines using \ : + # foo.o: sub/foo.c ... \ + # sub/foo.h ... \ + # ... + + "$@" -MD -MF "$tmpdepfile" + stat=$? + if test $stat -eq 0; then : + else + rm -f "$tmpdepfile" + exit $stat + fi + rm -f "$depfile" + # Each line is of the form `foo.o: dependent.h', + # or `foo.o: dep1.h dep2.h \', or ` dep3.h dep4.h \'. + # Do two passes, one to just change these to + # `$object: dependent.h' and one to simply `dependent.h:'. + sed "s,^[^:]*:,$object :," < "$tmpdepfile" > "$depfile" + # Some versions of the HPUX 10.20 sed can't process this invocation + # correctly. Breaking it into two sed invocations is a workaround. + sed 's,^[^:]*: \(.*\)$,\1,;s/^\\$//;/^$/d;/:$/d' < "$tmpdepfile" | + sed -e 's/$/ :/' >> "$depfile" + rm -f "$tmpdepfile" + ;; + +tru64) + # The Tru64 compiler uses -MD to generate dependencies as a side + # effect. `cc -MD -o foo.o ...' puts the dependencies into `foo.o.d'. + # At least on Alpha/Redhat 6.1, Compaq CCC V6.2-504 seems to put + # dependencies in `foo.d' instead, so we check for that too. + # Subdirectories are respected. + dir=`echo "$object" | sed -e 's|/[^/]*$|/|'` + test "x$dir" = "x$object" && dir= + base=`echo "$object" | sed -e 's|^.*/||' -e 's/\.o$//' -e 's/\.lo$//'` + + if test "$libtool" = yes; then + # With Tru64 cc, shared objects can also be used to make a + # static library. This mecanism is used in libtool 1.4 series to + # handle both shared and static libraries in a single compilation. + # With libtool 1.4, dependencies were output in $dir.libs/$base.lo.d. + # + # With libtool 1.5 this exception was removed, and libtool now + # generates 2 separate objects for the 2 libraries. These two + # compilations output dependencies in in $dir.libs/$base.o.d and + # in $dir$base.o.d. We have to check for both files, because + # one of the two compilations can be disabled. We should prefer + # $dir$base.o.d over $dir.libs/$base.o.d because the latter is + # automatically cleaned when .libs/ is deleted, while ignoring + # the former would cause a distcleancheck panic. + tmpdepfile1=$dir.libs/$base.lo.d # libtool 1.4 + tmpdepfile2=$dir$base.o.d # libtool 1.5 + tmpdepfile3=$dir.libs/$base.o.d # libtool 1.5 + tmpdepfile4=$dir.libs/$base.d # Compaq CCC V6.2-504 + "$@" -Wc,-MD + else + tmpdepfile1=$dir$base.o.d + tmpdepfile2=$dir$base.d + tmpdepfile3=$dir$base.d + tmpdepfile4=$dir$base.d + "$@" -MD + fi + + stat=$? + if test $stat -eq 0; then : + else + rm -f "$tmpdepfile1" "$tmpdepfile2" "$tmpdepfile3" "$tmpdepfile4" + exit $stat + fi + + for tmpdepfile in "$tmpdepfile1" "$tmpdepfile2" "$tmpdepfile3" "$tmpdepfile4" + do + test -f "$tmpdepfile" && break + done + if test -f "$tmpdepfile"; then + sed -e "s,^.*\.[a-z]*:,$object:," < "$tmpdepfile" > "$depfile" + # That's a tab and a space in the []. + sed -e 's,^.*\.[a-z]*:[ ]*,,' -e 's,$,:,' < "$tmpdepfile" >> "$depfile" + else + echo "#dummy" > "$depfile" + fi + rm -f "$tmpdepfile" + ;; + +#nosideeffect) + # This comment above is used by automake to tell side-effect + # dependency tracking mechanisms from slower ones. + +dashmstdout) + # Important note: in order to support this mode, a compiler *must* + # always write the preprocessed file to stdout, regardless of -o. + "$@" || exit $? + + # Remove the call to Libtool. + if test "$libtool" = yes; then + while test $1 != '--mode=compile'; do + shift + done + shift + fi + + # Remove `-o $object'. + IFS=" " + for arg + do + case $arg in + -o) + shift + ;; + $object) + shift + ;; + *) + set fnord "$@" "$arg" + shift # fnord + shift # $arg + ;; + esac + done + + test -z "$dashmflag" && dashmflag=-M + # Require at least two characters before searching for `:' + # in the target name. This is to cope with DOS-style filenames: + # a dependency such as `c:/foo/bar' could be seen as target `c' otherwise. + "$@" $dashmflag | + sed 's:^[ ]*[^: ][^:][^:]*\:[ ]*:'"$object"'\: :' > "$tmpdepfile" + rm -f "$depfile" + cat < "$tmpdepfile" > "$depfile" + tr ' ' ' +' < "$tmpdepfile" | \ +## Some versions of the HPUX 10.20 sed can't process this invocation +## correctly. Breaking it into two sed invocations is a workaround. + sed -e 's/^\\$//' -e '/^$/d' -e '/:$/d' | sed -e 's/$/ :/' >> "$depfile" + rm -f "$tmpdepfile" + ;; + +dashXmstdout) + # This case only exists to satisfy depend.m4. It is never actually + # run, as this mode is specially recognized in the preamble. + exit 1 + ;; + +makedepend) + "$@" || exit $? + # Remove any Libtool call + if test "$libtool" = yes; then + while test $1 != '--mode=compile'; do + shift + done + shift + fi + # X makedepend + shift + cleared=no + for arg in "$@"; do + case $cleared in + no) + set ""; shift + cleared=yes ;; + esac + case "$arg" in + -D*|-I*) + set fnord "$@" "$arg"; shift ;; + # Strip any option that makedepend may not understand. Remove + # the object too, otherwise makedepend will parse it as a source file. + -*|$object) + ;; + *) + set fnord "$@" "$arg"; shift ;; + esac + done + obj_suffix="`echo $object | sed 's/^.*\././'`" + touch "$tmpdepfile" + ${MAKEDEPEND-makedepend} -o"$obj_suffix" -f"$tmpdepfile" "$@" + rm -f "$depfile" + cat < "$tmpdepfile" > "$depfile" + sed '1,2d' "$tmpdepfile" | tr ' ' ' +' | \ +## Some versions of the HPUX 10.20 sed can't process this invocation +## correctly. Breaking it into two sed invocations is a workaround. + sed -e 's/^\\$//' -e '/^$/d' -e '/:$/d' | sed -e 's/$/ :/' >> "$depfile" + rm -f "$tmpdepfile" "$tmpdepfile".bak + ;; + +cpp) + # Important note: in order to support this mode, a compiler *must* + # always write the preprocessed file to stdout. + "$@" || exit $? + + # Remove the call to Libtool. + if test "$libtool" = yes; then + while test $1 != '--mode=compile'; do + shift + done + shift + fi + + # Remove `-o $object'. + IFS=" " + for arg + do + case $arg in + -o) + shift + ;; + $object) + shift + ;; + *) + set fnord "$@" "$arg" + shift # fnord + shift # $arg + ;; + esac + done + + "$@" -E | + sed -n -e '/^# [0-9][0-9]* "\([^"]*\)".*/ s:: \1 \\:p' \ + -e '/^#line [0-9][0-9]* "\([^"]*\)".*/ s:: \1 \\:p' | + sed '$ s: \\$::' > "$tmpdepfile" + rm -f "$depfile" + echo "$object : \\" > "$depfile" + cat < "$tmpdepfile" >> "$depfile" + sed < "$tmpdepfile" '/^$/d;s/^ //;s/ \\$//;s/$/ :/' >> "$depfile" + rm -f "$tmpdepfile" + ;; + +msvisualcpp) + # Important note: in order to support this mode, a compiler *must* + # always write the preprocessed file to stdout, regardless of -o, + # because we must use -o when running libtool. + "$@" || exit $? + IFS=" " + for arg + do + case "$arg" in + "-Gm"|"/Gm"|"-Gi"|"/Gi"|"-ZI"|"/ZI") + set fnord "$@" + shift + shift + ;; + *) + set fnord "$@" "$arg" + shift + shift + ;; + esac + done + "$@" -E | + sed -n '/^#line [0-9][0-9]* "\([^"]*\)"/ s::echo "`cygpath -u \\"\1\\"`":p' | sort | uniq > "$tmpdepfile" + rm -f "$depfile" + echo "$object : \\" > "$depfile" + . "$tmpdepfile" | sed 's% %\\ %g' | sed -n '/^\(.*\)$/ s:: \1 \\:p' >> "$depfile" + echo " " >> "$depfile" + . "$tmpdepfile" | sed 's% %\\ %g' | sed -n '/^\(.*\)$/ s::\1\::p' >> "$depfile" + rm -f "$tmpdepfile" + ;; + +none) + exec "$@" + ;; + +*) + echo "Unknown depmode $depmode" 1>&2 + exit 1 + ;; +esac + +exit 0 + +# Local Variables: +# mode: shell-script +# sh-indentation: 2 +# eval: (add-hook 'write-file-hooks 'time-stamp) +# time-stamp-start: "scriptversion=" +# time-stamp-format: "%:y-%02m-%02d.%02H" +# time-stamp-end: "$" +# End: diff --git a/AMDiS/doc/Doxyfile b/AMDiS/doc/Doxyfile new file mode 100644 index 0000000000000000000000000000000000000000..4f43a41b96e5a99c22045619b49f0d7548c7ca5c --- /dev/null +++ b/AMDiS/doc/Doxyfile @@ -0,0 +1,177 @@ +# Doxyfile 0.1 + +#--------------------------------------------------------------------------- +# General configuration options +#--------------------------------------------------------------------------- +PROJECT_NAME = AMDiS +PROJECT_NUMBER = +OUTPUT_DIRECTORY = . +OUTPUT_LANGUAGE = English +EXTRACT_ALL = NO +EXTRACT_PRIVATE = YES +EXTRACT_STATIC = NO +EXTRACT_LOCAL_CLASSES = NO +HIDE_UNDOC_MEMBERS = YES +HIDE_UNDOC_CLASSES = YES +BRIEF_MEMBER_DESC = YES +REPEAT_BRIEF = YES +ALWAYS_DETAILED_SEC = NO +INLINE_INHERITED_MEMB = NO +FULL_PATH_NAMES = NO +STRIP_FROM_PATH = +INTERNAL_DOCS = NO +STRIP_CODE_COMMENTS = YES +CASE_SENSE_NAMES = YES +SHORT_NAMES = NO +HIDE_SCOPE_NAMES = NO +VERBATIM_HEADERS = YES +SHOW_INCLUDE_FILES = YES +JAVADOC_AUTOBRIEF = NO +INHERIT_DOCS = YES +INLINE_INFO = YES +SORT_MEMBER_DOCS = YES +DISTRIBUTE_GROUP_DOC = NO +TAB_SIZE = 8 +GENERATE_TODOLIST = YES +GENERATE_TESTLIST = YES +GENERATE_BUGLIST = YES +ALIASES = +ENABLED_SECTIONS = +MAX_INITIALIZER_LINES = 30 +OPTIMIZE_OUTPUT_FOR_C = NO +SHOW_USED_FILES = YES +#--------------------------------------------------------------------------- +# configuration options related to warning and progress messages +#--------------------------------------------------------------------------- +QUIET = NO +WARNINGS = YES +WARN_IF_UNDOCUMENTED = YES +WARN_FORMAT = "$file:$line: $text" +WARN_LOGFILE = +#--------------------------------------------------------------------------- +# configuration options related to the input files +#--------------------------------------------------------------------------- +INPUT = ../src/ +FILE_PATTERNS = *.h +RECURSIVE = NO +EXCLUDE = +EXCLUDE_PATTERNS = +EXAMPLE_PATH = +EXAMPLE_PATTERNS = +EXAMPLE_RECURSIVE = NO +IMAGE_PATH = +INPUT_FILTER = +FILTER_SOURCE_FILES = NO +#--------------------------------------------------------------------------- +# configuration options related to source browsing +#--------------------------------------------------------------------------- +SOURCE_BROWSER = NO +INLINE_SOURCES = NO +REFERENCED_BY_RELATION = YES +REFERENCES_RELATION = YES +#--------------------------------------------------------------------------- +# configuration options related to the alphabetical class index +#--------------------------------------------------------------------------- +ALPHABETICAL_INDEX = NO +COLS_IN_ALPHA_INDEX = 5 +IGNORE_PREFIX = +#--------------------------------------------------------------------------- +# configuration options related to the HTML output +#--------------------------------------------------------------------------- +GENERATE_HTML = YES +HTML_OUTPUT = html +HTML_HEADER = +HTML_FOOTER = +HTML_STYLESHEET = +HTML_ALIGN_MEMBERS = YES +GENERATE_HTMLHELP = NO +GENERATE_CHI = NO +BINARY_TOC = NO +TOC_EXPAND = NO +DISABLE_INDEX = NO +ENUM_VALUES_PER_LINE = 4 +GENERATE_TREEVIEW = NO +TREEVIEW_WIDTH = 250 +#--------------------------------------------------------------------------- +# configuration options related to the LaTeX output +#--------------------------------------------------------------------------- +GENERATE_LATEX = NO +LATEX_OUTPUT = latex +COMPACT_LATEX = NO +PAPER_TYPE = a4wide +EXTRA_PACKAGES = +LATEX_HEADER = +PDF_HYPERLINKS = NO +USE_PDFLATEX = NO +LATEX_BATCHMODE = NO +#--------------------------------------------------------------------------- +# configuration options related to the RTF output +#--------------------------------------------------------------------------- +GENERATE_RTF = NO +RTF_OUTPUT = rtf +COMPACT_RTF = NO +RTF_HYPERLINKS = NO +RTF_STYLESHEET_FILE = +RTF_EXTENSIONS_FILE = +#--------------------------------------------------------------------------- +# configuration options related to the man page output +#--------------------------------------------------------------------------- +GENERATE_MAN = NO +MAN_OUTPUT = man +MAN_EXTENSION = .3 +MAN_LINKS = NO +#--------------------------------------------------------------------------- +# configuration options related to the XML output +#--------------------------------------------------------------------------- +GENERATE_XML = NO +#--------------------------------------------------------------------------- +# configuration options for the AutoGen Definitions output +#--------------------------------------------------------------------------- +GENERATE_AUTOGEN_DEF = NO +#--------------------------------------------------------------------------- +# Configuration options related to the preprocessor +#--------------------------------------------------------------------------- +ENABLE_PREPROCESSING = YES +MACRO_EXPANSION = NO +EXPAND_ONLY_PREDEF = NO +SEARCH_INCLUDES = YES +INCLUDE_PATH = +INCLUDE_FILE_PATTERNS = +PREDEFINED = +EXPAND_AS_DEFINED = +SKIP_FUNCTION_MACROS = YES +#--------------------------------------------------------------------------- +# Configuration::addtions related to external references +#--------------------------------------------------------------------------- +TAGFILES = +GENERATE_TAGFILE = +ALLEXTERNALS = NO +PERL_PATH = /usr/bin/perl +#--------------------------------------------------------------------------- +# Configuration options related to the dot tool +#--------------------------------------------------------------------------- +CLASS_DIAGRAMS = YES +HAVE_DOT = NO +CLASS_GRAPH = YES +COLLABORATION_GRAPH = YES +TEMPLATE_RELATIONS = YES +HIDE_UNDOC_RELATIONS = YES +INCLUDE_GRAPH = YES +INCLUDED_BY_GRAPH = YES +GRAPHICAL_HIERARCHY = YES +DOT_PATH = /solhome/vey/graphviz/graphviz-1.10/bin/ +DOTFILE_DIRS = +MAX_DOT_GRAPH_WIDTH = 1024 +MAX_DOT_GRAPH_HEIGHT = 1024 +GENERATE_LEGEND = YES +DOT_CLEANUP = YES +#--------------------------------------------------------------------------- +# Configuration::addtions related to the search engine +#--------------------------------------------------------------------------- +SEARCHENGINE = NO +CGI_NAME = search.cgi +CGI_URL = +DOC_URL = +DOC_ABSPATH = +BIN_ABSPATH = /usr/local/bin/ +EXT_DOC_PATHS = diff --git a/AMDiS/install-sh b/AMDiS/install-sh new file mode 100755 index 0000000000000000000000000000000000000000..4d4a9519eaf88b18fb157dfe5fae59c1c5d005c7 --- /dev/null +++ b/AMDiS/install-sh @@ -0,0 +1,323 @@ +#!/bin/sh +# install - install a program, script, or datafile + +scriptversion=2005-05-14.22 + +# This originates from X11R5 (mit/util/scripts/install.sh), which was +# later released in X11R6 (xc/config/util/install.sh) with the +# following copyright and license. +# +# Copyright (C) 1994 X Consortium +# +# Permission is hereby granted, free of charge, to any person obtaining a copy +# of this software and associated documentation files (the "Software"), to +# deal in the Software without restriction, including without limitation the +# rights to use, copy, modify, merge, publish, distribute, sublicense, and/or +# sell copies of the Software, and to permit persons to whom the Software is +# furnished to do so, subject to the following conditions: +# +# The above copyright notice and this permission notice shall be included in +# all copies or substantial portions of the Software. +# +# THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR +# IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, +# FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE +# X CONSORTIUM BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN +# AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNEC- +# TION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. +# +# Except as contained in this notice, the name of the X Consortium shall not +# be used in advertising or otherwise to promote the sale, use or other deal- +# ings in this Software without prior written authorization from the X Consor- +# tium. +# +# +# FSF changes to this file are in the public domain. +# +# Calling this script install-sh is preferred over install.sh, to prevent +# `make' implicit rules from creating a file called install from it +# when there is no Makefile. +# +# This script is compatible with the BSD install script, but was written +# from scratch. It can only install one file at a time, a restriction +# shared with many OS's install programs. + +# set DOITPROG to echo to test this script + +# Don't use :- since 4.3BSD and earlier shells don't like it. +doit="${DOITPROG-}" + +# put in absolute paths if you don't have them in your path; or use env. vars. + +mvprog="${MVPROG-mv}" +cpprog="${CPPROG-cp}" +chmodprog="${CHMODPROG-chmod}" +chownprog="${CHOWNPROG-chown}" +chgrpprog="${CHGRPPROG-chgrp}" +stripprog="${STRIPPROG-strip}" +rmprog="${RMPROG-rm}" +mkdirprog="${MKDIRPROG-mkdir}" + +chmodcmd="$chmodprog 0755" +chowncmd= +chgrpcmd= +stripcmd= +rmcmd="$rmprog -f" +mvcmd="$mvprog" +src= +dst= +dir_arg= +dstarg= +no_target_directory= + +usage="Usage: $0 [OPTION]... [-T] SRCFILE DSTFILE + or: $0 [OPTION]... SRCFILES... DIRECTORY + or: $0 [OPTION]... -t DIRECTORY SRCFILES... + or: $0 [OPTION]... -d DIRECTORIES... + +In the 1st form, copy SRCFILE to DSTFILE. +In the 2nd and 3rd, copy all SRCFILES to DIRECTORY. +In the 4th, create DIRECTORIES. + +Options: +-c (ignored) +-d create directories instead of installing files. +-g GROUP $chgrpprog installed files to GROUP. +-m MODE $chmodprog installed files to MODE. +-o USER $chownprog installed files to USER. +-s $stripprog installed files. +-t DIRECTORY install into DIRECTORY. +-T report an error if DSTFILE is a directory. +--help display this help and exit. +--version display version info and exit. + +Environment variables override the default commands: + CHGRPPROG CHMODPROG CHOWNPROG CPPROG MKDIRPROG MVPROG RMPROG STRIPPROG +" + +while test -n "$1"; do + case $1 in + -c) shift + continue;; + + -d) dir_arg=true + shift + continue;; + + -g) chgrpcmd="$chgrpprog $2" + shift + shift + continue;; + + --help) echo "$usage"; exit $?;; + + -m) chmodcmd="$chmodprog $2" + shift + shift + continue;; + + -o) chowncmd="$chownprog $2" + shift + shift + continue;; + + -s) stripcmd=$stripprog + shift + continue;; + + -t) dstarg=$2 + shift + shift + continue;; + + -T) no_target_directory=true + shift + continue;; + + --version) echo "$0 $scriptversion"; exit $?;; + + *) # When -d is used, all remaining arguments are directories to create. + # When -t is used, the destination is already specified. + test -n "$dir_arg$dstarg" && break + # Otherwise, the last argument is the destination. Remove it from $@. + for arg + do + if test -n "$dstarg"; then + # $@ is not empty: it contains at least $arg. + set fnord "$@" "$dstarg" + shift # fnord + fi + shift # arg + dstarg=$arg + done + break;; + esac +done + +if test -z "$1"; then + if test -z "$dir_arg"; then + echo "$0: no input file specified." >&2 + exit 1 + fi + # It's OK to call `install-sh -d' without argument. + # This can happen when creating conditional directories. + exit 0 +fi + +for src +do + # Protect names starting with `-'. + case $src in + -*) src=./$src ;; + esac + + if test -n "$dir_arg"; then + dst=$src + src= + + if test -d "$dst"; then + mkdircmd=: + chmodcmd= + else + mkdircmd=$mkdirprog + fi + else + # Waiting for this to be detected by the "$cpprog $src $dsttmp" command + # might cause directories to be created, which would be especially bad + # if $src (and thus $dsttmp) contains '*'. + if test ! -f "$src" && test ! -d "$src"; then + echo "$0: $src does not exist." >&2 + exit 1 + fi + + if test -z "$dstarg"; then + echo "$0: no destination specified." >&2 + exit 1 + fi + + dst=$dstarg + # Protect names starting with `-'. + case $dst in + -*) dst=./$dst ;; + esac + + # If destination is a directory, append the input filename; won't work + # if double slashes aren't ignored. + if test -d "$dst"; then + if test -n "$no_target_directory"; then + echo "$0: $dstarg: Is a directory" >&2 + exit 1 + fi + dst=$dst/`basename "$src"` + fi + fi + + # This sed command emulates the dirname command. + dstdir=`echo "$dst" | sed -e 's,/*$,,;s,[^/]*$,,;s,/*$,,;s,^$,.,'` + + # Make sure that the destination directory exists. + + # Skip lots of stat calls in the usual case. + if test ! -d "$dstdir"; then + defaultIFS=' + ' + IFS="${IFS-$defaultIFS}" + + oIFS=$IFS + # Some sh's can't handle IFS=/ for some reason. + IFS='%' + set x `echo "$dstdir" | sed -e 's@/@%@g' -e 's@^%@/@'` + shift + IFS=$oIFS + + pathcomp= + + while test $# -ne 0 ; do + pathcomp=$pathcomp$1 + shift + if test ! -d "$pathcomp"; then + $mkdirprog "$pathcomp" + # mkdir can fail with a `File exist' error in case several + # install-sh are creating the directory concurrently. This + # is OK. + test -d "$pathcomp" || exit + fi + pathcomp=$pathcomp/ + done + fi + + if test -n "$dir_arg"; then + $doit $mkdircmd "$dst" \ + && { test -z "$chowncmd" || $doit $chowncmd "$dst"; } \ + && { test -z "$chgrpcmd" || $doit $chgrpcmd "$dst"; } \ + && { test -z "$stripcmd" || $doit $stripcmd "$dst"; } \ + && { test -z "$chmodcmd" || $doit $chmodcmd "$dst"; } + + else + dstfile=`basename "$dst"` + + # Make a couple of temp file names in the proper directory. + dsttmp=$dstdir/_inst.$$_ + rmtmp=$dstdir/_rm.$$_ + + # Trap to clean up those temp files at exit. + trap 'ret=$?; rm -f "$dsttmp" "$rmtmp" && exit $ret' 0 + trap '(exit $?); exit' 1 2 13 15 + + # Copy the file name to the temp name. + $doit $cpprog "$src" "$dsttmp" && + + # and set any options; do chmod last to preserve setuid bits. + # + # If any of these fail, we abort the whole thing. If we want to + # ignore errors from any of these, just make sure not to ignore + # errors from the above "$doit $cpprog $src $dsttmp" command. + # + { test -z "$chowncmd" || $doit $chowncmd "$dsttmp"; } \ + && { test -z "$chgrpcmd" || $doit $chgrpcmd "$dsttmp"; } \ + && { test -z "$stripcmd" || $doit $stripcmd "$dsttmp"; } \ + && { test -z "$chmodcmd" || $doit $chmodcmd "$dsttmp"; } && + + # Now rename the file to the real destination. + { $doit $mvcmd -f "$dsttmp" "$dstdir/$dstfile" 2>/dev/null \ + || { + # The rename failed, perhaps because mv can't rename something else + # to itself, or perhaps because mv is so ancient that it does not + # support -f. + + # Now remove or move aside any old file at destination location. + # We try this two ways since rm can't unlink itself on some + # systems and the destination file might be busy for other + # reasons. In this case, the final cleanup might fail but the new + # file should still install successfully. + { + if test -f "$dstdir/$dstfile"; then + $doit $rmcmd -f "$dstdir/$dstfile" 2>/dev/null \ + || $doit $mvcmd -f "$dstdir/$dstfile" "$rmtmp" 2>/dev/null \ + || { + echo "$0: cannot unlink or rename $dstdir/$dstfile" >&2 + (exit 1); exit 1 + } + else + : + fi + } && + + # Now rename the file to the real destination. + $doit $mvcmd "$dsttmp" "$dstdir/$dstfile" + } + } + fi || { (exit 1); exit 1; } +done + +# The final little trick to "correctly" pass the exit status to the exit trap. +{ + (exit 0); exit 0 +} + +# Local variables: +# eval: (add-hook 'write-file-hooks 'time-stamp) +# time-stamp-start: "scriptversion=" +# time-stamp-format: "%:y-%02m-%02d.%02H" +# time-stamp-end: "$" +# End: diff --git a/AMDiS/levelset/Makefile b/AMDiS/levelset/Makefile new file mode 100644 index 0000000000000000000000000000000000000000..f95338fef65849e81459289f24390184a81433bc --- /dev/null +++ b/AMDiS/levelset/Makefile @@ -0,0 +1,46 @@ + +SHELL = /bin/sh +CXX = g++ +DEFS = -DPACKAGE=\"AMDiS\" -DVERSION=\"0.1\" -DHAVE_DLFCN_H=1 +DEFAULT_INCLUDES = -I. +INCLUDES = -I/solhome/vey/sourcen/AMDiS//src +CPPFLAGS = +top_builddir = ../ +LIBS = +LIBTOOL = $(SHELL) $(top_builddir)/libtool + +LDADD = /solhome/vey/sourcen/AMDiS//lib/libAMDiS_debug.la +#LDADD = /solhome/vey/sourcen/AMDiS//lib/libAMDiS.la +PCXXFLAGS = -g -O0 +#PCXXFLAGS = -O2 +PLDFLAGS = -static +#PLDFLAGS = + +CXXFLAGS = -ftemplate-depth-30 $(PCXXFLAGS) +LDFLAGS = $(PLDFLAGS) + +all : + make $(PROGRAMS) + +clean: + -rm -rf *.o + -rm -rf $(PROGRAMS) + +.cc.o: src/$*.cc + $(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(AM_CXXFLAGS) $(CXXFLAGS) -c -o $*.o src/$*.cc + + +# ============================================================================ +# ===== user programs ======================================================== +# ============================================================================ + +PROGRAMS = levelset + +VPATH = ./src/:./ + +# ===== ellipt ============================================================== + +LEVELSET_OFILES = levelset.o + +levelset: $(LEVELSET_OFILES) + $(LIBTOOL) --mode=link $(CXX) $(CXXFLAGS) $(PCXXFLAGS) -o levelset levelset.o $(LDADD) diff --git a/AMDiS/levelset/init/levelset.dat.2d b/AMDiS/levelset/init/levelset.dat.2d new file mode 100644 index 0000000000000000000000000000000000000000..b6c8d1c4b9b94cbed5e3a2bc8424860a3d382b26 --- /dev/null +++ b/AMDiS/levelset/init/levelset.dat.2d @@ -0,0 +1,63 @@ +dimension of world: 2 + +levelsetMesh->macro file name: ./macro/macro.stand.2d +levelsetMesh->global refinements: 0 + +levelset->space->polynomial degree: 2 + + +%-------------------------- problem parameters ----------------------------- +levelset->epsilon: 1.e-8 +levelset->alpha: 1.0 +levelset->problem number: 0 + + + + +levelset->space->mesh: levelsetMesh + +levelset->space->solver: 2 % 1: BICGSTAB 2: CG 3: GMRES 4: ODIR 5: ORES +levelset->space->solver->max iteration: 1000 +levelset->space->solver->restart: 10 % only used for GMRES +levelset->space->solver->tolerance: 1.e-8 +levelset->space->solver->info: 8 +levelset->space->solver->precon: 1 % 0: no precon 1: diag precon + +levelset->estimator C0: 1.0 +levelset->estimator C1: 1.0 +levelset->estimator C2: 1.0 +levelset->estimator C3: 1.0 + +levelset->theta: 1.0 + +levelset->adapt->tolerance: 0.01 + +levelset->adapt->timestep: 0.01 +levelset->adapt->startTime: 0.0 +levelset->adapt->endTime: 0.05 +levelset->adapt->rel initial error: 0.5 +levelset->adapt->rel space error: 0.5 +levelset->adapt->rel time error: 0.5 +levelset->adapt->strategy: 0 % 0=explicit, 1=implicit +levelset->adapt->max iteration: 1 +levelset->adapt->info: 8 + +levelset->initial->adapt->strategy: 0 % 0=none, 1=GR, 2=MS, 3=ES, 4=GERS +levelset->initial->adapt->max iteration: 10 +levelset->initial->adapt->info: 8 + +levelset->space->dim: 2 +levelset->space->adapt->strategy: 3 % 0=none, 1=GR, 2=MS, 3=ES, 4=GERS +levelset->space->adapt->ESTheta: 0.9 +levelset->space->adapt->ESThetaC: 0.05 +levelset->space->adapt->max iteration: 2 +levelset->space->adapt->coarsen allowed: 1 % 0|1 +levelset->space->adapt->info: 8 + +WAIT: 0 + + + + + + diff --git a/AMDiS/levelset/macro/macro.stand.1d b/AMDiS/levelset/macro/macro.stand.1d new file mode 100644 index 0000000000000000000000000000000000000000..31eb45ca4222eec6566dc69fd74a8d2791798424 --- /dev/null +++ b/AMDiS/levelset/macro/macro.stand.1d @@ -0,0 +1,15 @@ +DIM: 1 +DIM_OF_WORLD: 1 + +number of elements: 1 +number of vertices: 2 + +element vertices: +0 1 + +element boundaries: +1 1 + +vertex coordinates: + 0.0 + 1.0 diff --git a/AMDiS/levelset/macro/macro.stand.2d b/AMDiS/levelset/macro/macro.stand.2d new file mode 100644 index 0000000000000000000000000000000000000000..f81cc45794cc9986247ae5953d71dbd6e6c86d33 --- /dev/null +++ b/AMDiS/levelset/macro/macro.stand.2d @@ -0,0 +1,30 @@ +DIM: 2 +DIM_OF_WORLD: 2 + +number of elements: 4 +number of vertices: 5 + +element vertices: +0 1 4 +1 2 4 +2 3 4 +3 0 4 + +element boundaries: +0 0 1 +0 0 1 +0 0 1 +0 0 1 + +vertex coordinates: + 0.0 0.0 + 1.0 0.0 + 1.0 1.0 + 0.0 1.0 + 0.5 0.5 + +element neighbours: +1 3 -1 +2 0 -1 +3 1 -1 +0 2 -1 diff --git a/AMDiS/levelset/macro/macro.stand.3d b/AMDiS/levelset/macro/macro.stand.3d new file mode 100644 index 0000000000000000000000000000000000000000..2bde72fd05fdaf113903d2f185a727eb9ed2a7da --- /dev/null +++ b/AMDiS/levelset/macro/macro.stand.3d @@ -0,0 +1,39 @@ +DIM: 3 +DIM_OF_WORLD: 3 + +number of vertices: 8 +number of elements: 6 + +vertex coordinates: + 0.0 0.0 0.0 + 1.0 0.0 0.0 + 0.0 0.0 1.0 + 1.0 0.0 1.0 + 1.0 1.0 0.0 + 1.0 1.0 1.0 + 0.0 1.0 0.0 + 0.0 1.0 1.0 + +element vertices: + 0 5 4 1 + 0 5 3 1 + 0 5 3 2 + 0 5 4 6 + 0 5 7 6 + 0 5 7 2 + +element boundaries: + 1 1 0 0 + 1 1 0 0 + 1 1 0 0 + 1 1 0 0 + 1 1 0 0 + 1 1 0 0 + +element neighbours: + -1 -1 1 3 + -1 -1 0 2 + -1 -1 5 1 + -1 -1 4 0 + -1 -1 3 5 + -1 -1 2 4 diff --git a/AMDiS/levelset/macro/macro_big.stand.1d b/AMDiS/levelset/macro/macro_big.stand.1d new file mode 100644 index 0000000000000000000000000000000000000000..a1bf307b5696d1a6c9fd91f4f764d44778595745 --- /dev/null +++ b/AMDiS/levelset/macro/macro_big.stand.1d @@ -0,0 +1,15 @@ +DIM: 1 +DIM_OF_WORLD: 1 + +number of vertices: 2 +number of elements: 1 + +vertex coordinates: +-1.0 + 1.0 + +element vertices: +0 1 + +element boundaries: +1 1 \ No newline at end of file diff --git a/AMDiS/levelset/macro/macro_big.stand.2d b/AMDiS/levelset/macro/macro_big.stand.2d new file mode 100644 index 0000000000000000000000000000000000000000..5aee8edf9ec2ee0c631e776d4b926eee4a86e7a1 --- /dev/null +++ b/AMDiS/levelset/macro/macro_big.stand.2d @@ -0,0 +1,24 @@ +DIM: 2 +DIM_OF_WORLD: 2 + +number of vertices: 5 +number of elements: 4 + +vertex coordinates: +-1.0 -1.0 + 1.0 -1.0 + 1.0 1.0 +-1.0 1.0 + 0.0 0.0 + +element vertices: +0 1 4 +1 2 4 +2 3 4 +3 0 4 + +element boundaries: +0 0 1 +0 0 1 +0 0 1 +0 0 1 diff --git a/AMDiS/levelset/macro/macro_big.stand.3d b/AMDiS/levelset/macro/macro_big.stand.3d new file mode 100644 index 0000000000000000000000000000000000000000..4deeef781ba49d903a3da21dd9f320a38793bd2d --- /dev/null +++ b/AMDiS/levelset/macro/macro_big.stand.3d @@ -0,0 +1,40 @@ +DIM: 3 +DIM_OF_WORLD: 3 + +number of vertices: 8 +number of elements: 6 + +vertex coordinates: + -1.0 -1.0 -1.0 + 1.0 -1.0 -1.0 + -1.0 -1.0 1.0 + 1.0 -1.0 1.0 + 1.0 1.0 -1.0 + 1.0 1.0 1.0 + -1.0 1.0 -1.0 + -1.0 1.0 1.0 + +element vertices: + 0 5 4 1 + 0 5 3 1 + 0 5 3 2 + 0 5 4 6 + 0 5 7 6 + 0 5 7 2 + +element boundaries: + 1 1 0 0 + 1 1 0 0 + 1 1 0 0 + 1 1 0 0 + 1 1 0 0 + 1 1 0 0 + +element neighbours: + -1 -1 1 3 + -1 -1 0 2 + -1 -1 5 1 + -1 -1 4 0 + -1 -1 3 5 + -1 -1 2 4 + diff --git a/AMDiS/levelset/src/levelset.cc b/AMDiS/levelset/src/levelset.cc new file mode 100644 index 0000000000000000000000000000000000000000..035255e5a14f20fab409f0ab724490e42efc681b --- /dev/null +++ b/AMDiS/levelset/src/levelset.cc @@ -0,0 +1,669 @@ +#include "AMDiS.h" + +using namespace std; + + + + +static double epsNorm1(const WorldVector x, const double eps) +{ + static double result = 0.0; + static int k; + + result = 0.0; + for(k=0; k<x.getSize(); k++){ + result += x[k]*x[k]; + } + result += eps*eps; + result = sqrt( result ); + TEST_EXIT( result > 1.e-10)( "eps_norm = %e \n", result); + result = 1.0/result; + + return(result); +} + + +static double epsNorm(const WorldVector x, const double eps) +{ + static double result = 0.0; + static int k; + + result = 0.0; + + for(k=0; k<x.getSize(); k++){ + result += x[k]*x[k]; + } + result += eps*eps; + result = sqrt( result ); + + return(result); +} + +static void epsNormalize(const WorldVector x, const double eps, WorldVector y) +{ + static int k; + + for(k=0; k<x.getSize(); k++) + y[k] = x[k] * epsNorm1(x,eps); + + return; +} + + + +class Circle : public AbstractFunction<double, double> +{ +public: + Circle(double radius_) : radius(radius_) {}; + + const double& f(const double& alpha) const + { + return radius; + }; + +protected: + double radius; +}; + + +class PerturbedCircle : public AbstractFunction<double, double> +{ +public: + PerturbedCircle(double radius_, double strength_, int period_) : + radius(radius_), strength(strength_), period(period_) {}; + + const double& f(const double &alpha) const + { + static double result; + result = 1.0 + strength * cos( period * alpha ); + result *= radius; + return result; + }; + +protected: + double radius; + double strength; + int period; +}; + + +/****************************************************************************/ +/* signed distance function for levelset 0 circle with radius */ +/****************************************************************************/ + + +static double signedDistStar(const WorldVector& x, const WorldVector& midPoint, + AbstractFunction<double, double> *radius, double eps) +{ + WorldVector x_trans; + double norm_x; + double result; + double alpha; + + int k; + for(k=0; k < x.getSize(); k++) { + x_trans[k] = x[k] - midPoint[k]; + } + + //x_trans = (WorldVector&) x - (WorldVector&) mid_point; + + norm_x = epsNorm(x_trans, eps); + TEST_EXIT( norm_x > 1.e-15)( "eps_norm = %e \n", norm_x); + + if( x_trans[0] >= 0.0 ) + alpha = acos( x_trans[0] / norm_x ); + else + alpha = 2.0*M_PI - acos( x_trans[0] / norm_x ); + + result = ( norm_x - (*radius)(alpha)); + + return(result); +}; + + + +/****************************************************************************/ +/* anisotropy function and derivative */ +/****************************************************************************/ + +class Gamma : public AbstractFunction<double, WorldVector> +{ +public: + Gamma(double alpha_) : alpha(alpha_) {}; + + const double& f(const WorldVector& x) const + { + static double result; + int k; + + result = alpha * x[0] * x[0] + 1.e-10; + for( k=1; k<x.getSize(); k++) + result += x[k]*x[k]; + + result = sqrt(result); + return result; + }; + +protected: + double alpha; +}; + + + + +class Gamma_z : public AbstractFunction<WorldVector, WorldVector> +{ +public: + Gamma_z(double alpha_) : alpha(alpha_) {}; + + const WorldVector& f(const WorldVector& x) const + { + static WorldVector result; + int k; + double norm_1 = 0.0; + static Gamma gamma(alpha); + double norm = gamma(x); + + TEST_EXIT( norm > 1.e-15)( "gamma(z) = %e \n", norm); + norm_1 = 1.0/norm; + + result[0] = alpha * x[0] * norm_1; + + for( k=1; k<x.getSize(); k++) + result[k] = x[k] * norm_1; + + return result; + }; + +protected: + double alpha; +}; + + +/****************************************************************************/ +/* Abstract functions used by operators */ +/****************************************************************************/ + +/* function for second order operator A */ + +class ProjectionGradNorm : public AbstractFunction<WorldMatrix, WorldVector> +{ +public: + ProjectionGradNorm( double epsilon_) : epsilon(epsilon_) {}; + + const WorldMatrix& f(const WorldVector& x) const + { + static WorldMatrix result; + static WorldVector gradNorm; + static double norm; + int k,l; + + norm = epsNorm(x, epsilon); + epsNormalize(x, epsilon, gradNorm); + + for(k = 0; k<x.getSize(); k++) + for(l = 0; l<= k; l++){ + if( k == l ) + result[k][l] = 1.0 - gradNorm[k]*gradNorm[l]; + else + result[k][l] = -gradNorm[k]*gradNorm[l]; + result[k][l] *= norm; + result[l][k] = result[k][l]; + } + + return result; + }; + +protected: + double alpha; + double epsilon; +}; + + +/* function for second order operator B */ + +class GammaNorm : public AbstractFunction<double, WorldVector> +{ +public: + GammaNorm( double epsilon_, double alpha_) : epsilon(epsilon_), alpha(alpha_) {}; + + const double& f(const WorldVector& x) const + { + static double result; + static WorldVector gradNorm; + static double norm1; + static Gamma gamma(alpha); + int k,l; + + norm1 = epsNorm1(x, epsilon); + epsNormalize(x, epsilon, gradNorm); + + result = gamma(gradNorm) * norm1; + return result; + }; + +protected: + double epsilon; + double alpha; +}; + + + + + +/* function for rhs F */ +class GammaGradNorm : public AbstractFunction<WorldVector, WorldVector> +{ +public: + GammaGradNorm(double alpha_, double epsilon_) : alpha(alpha_), epsilon(epsilon_) {}; + + const WorldVector& f(const WorldVector& x) const + { + static WorldVector result; + static WorldVector gradNorm; + static Gamma gamma(alpha); + + epsNormalize(x, epsilon, gradNorm); + result = gamma( gradNorm ) * gradNorm; + + return result; + }; + +protected: + double alpha; + double epsilon; +}; + + +/* function for rhs G */ +class Gamma_zGradNorm : public AbstractFunction<WorldVector, WorldVector> +{ +public: + Gamma_zGradNorm(double alpha_, double epsilon_) : alpha(alpha_), epsilon(epsilon_) {}; + + const WorldVector& f(const WorldVector& x) const + { + static WorldVector result; + static WorldVector gradNorm; + static Gamma_z gamma_z(alpha); + + epsNormalize(x, epsilon, gradNorm); + result = gamma_z( gradNorm ); + + return result; + }; + +protected: + double alpha; + double epsilon; +}; + + +/**********************************************/ +/* create stationary problem */ +/**********************************************/ + +class LevelsetSpace : public Problem<double> +{ +public: + LevelsetSpace() + : Problem<double>("levelset->space") + { + GET_PARAMETER(1, name + "->lambda", "%f", &lambda); + + A = NEW DOFMatrix(feSpace, "A"); + B = NEW DOFMatrix(feSpace, "B"); + M = NEW DOFMatrix(feSpace, "M"); + M_lump = NEW DOFMatrix(feSpace, "M_lump"); + M_1 = NEW DOFMatrix(feSpace, "M_1"); + + f = NEW DOFVector<double>(feSpace, "f"); + g = NEW DOFVector<double>(feSpace, "g"); + rhs = NEW DOFVector<double>(feSpace, "rhs"); + }; + + ~LevelsetSpace() + { + DELETE A; + DELETE B; + DELETE M; + DELETE M_lump; + DELETE M_1; + DELETE f; + DELETE g; + }; + + DOFMatrix *getMatrixA() { return A; }; + DOFMatrix *getMatrixB() { return B; }; + DOFMatrix *getMatrixM() { return M; }; + DOFVector<double> *getVectorF() { return f; }; + DOFVector<double> *getVectorG() { return g; }; + + static int buildAfterCoarsenFunction(ElInfo *elInfo) + { + const char *bound; + + if(traversePtr->useGetBound) + bound = traversePtr->feSpace->getBasisFcts()->getBound(elInfo, NULL); + else + bound = NULL; + + traversePtr->A->assemble(1.0, elInfo, bound); + traversePtr->B->assemble(1.0, elInfo, bound); + traversePtr->M->assemble(1.0, elInfo, bound); + traversePtr->f->assemble(1.0, elInfo, bound); + traversePtr->g->assemble(1.0, elInfo, bound); + + return 0; + }; + + void buildAfterCoarsen(Flag flag) + { + FUNCNAME("LevelsetSpace::buildAfterCoarsen"); + + MSG("%d DOFs for %s\n", feSpace->getAdmin()->getUsedSize(), feSpace->getName().c_str()); + + mesh->dofCompress(); + + Flag assembleFlag = + flag | A->getAssembleFlag() | B->getAssembleFlag() | M->getAssembleFlag() | + f->getAssembleFlag() | g->getAssembleFlag(); + + if(useGetBound) + assembleFlag |= Mesh::FILL_BOUND; + + A->clear(); + B->clear(); + M->clear(); + f->set(0.0); + g->set(0.0); + + + traversePtr = this; + + mesh->traverse(-1, assembleFlag, &buildAfterCoarsenFunction); + //dirichletBound(gFct, fh, uh, NULL); /* boundary values */ + }; + + void solve() {}; + + double estimate() { return 0.0; }; + +private: + +#if 0 + +void matrixLump(DOF_MATRIX *matrix, DOF_MATRIX *matrix_diag) +{ + int k,i,icol; + MATRIX_ROW *row; + + FUNCNAME("matrix_lump"); + clear_dof_matrix(matrix_diag); + FOR_ALL_DOFS(gd->fe_space->admin, + matrix_diag->matrix_row[dof] = get_matrix_row(gd->fe_space); + matrix_diag->matrix_row[dof]->entry[0]=0.0; + row = matrix->matrix_row[dof]; + while( row ) { + for(i=0; i<ROW_LENGTH; i++){ + icol = row->col[i]; + if( ENTRY_USED(icol) ) + matrix_diag->matrix_row[dof]->entry[0] += + matrix->matrix_row[dof]->entry[i]; + else{ + if (icol == NO_MORE_ENTRIES) + break; + } + } + row = row->next; + } + matrix_diag->matrix_row[dof]->col[0] = dof; + matrix_diag->matrix_row[dof]->col[1] = NO_MORE_ENTRIES; + for( k = 2; k < ROW_LENGTH; k++) + matrix_diag->matrix_row[dof]->col[k] = UNUSED_ENTRY; + + matrix_diag->matrix_row[dof]->next = nil; + ) + return; +} + +#endif + +/****************************************************************************/ +/*invertDiagMatrix(): inverts a positive definit diagonal matrix */ +/****************************************************************************/ + +void invertDiagMatrix(DOFMatrix *matrix, DOFMatrix *matrix_1) +{ + int k; + FUNCNAME("invert_matrix_lump"); + matrix_1->clear(); + + DOFMatrix::Iterator matrixIt(matrix, USED_DOFS); + double entry = 0.0; + DegreeOfFreedom dof = 0; + + for(matrixIt.reset(); !matrixIt.end(); ++matrixIt) { + dof = matrixIt.getPosition(); + if( (*matrix)[dof][0].entry > 1.e-10 ){ + entry = 1.0 / (*matrix)[dof][0].entry; + matrix_1->addSparseDofEntry(1.0, dof, dof, entry); + } + else + ERROR_EXIT("matrix[%d][%d] = %f", dof, dof, (*matrix)[dof][0].entry ); + + } + + + return; +} + + + + + +private: + DOFMatrix *A, *B, *M, *M_lump, *M_1; + DOFVector<double> *rhs, *f, *g; + + double *timestepPtr; + + double lambda; + + static LevelsetSpace *traversePtr; + + friend class Levelset; +}; + +LevelsetSpace *LevelsetSpace::traversePtr = NULL; + +/**********************************************/ +/* create instationary problem */ +/**********************************************/ + +class Levelset : public ProblemInstat<double> +{ +public: + Levelset(LevelsetSpace *levelsetSpace) + : ProblemInstat<double>("levelset", (Problem<double>*) levelsetSpace) + { + + timestep = adaptInstat->getTimestepPtr(); + levelsetSpace->timestepPtr = timestep; + + int problemNumber = -1; + GET_PARAMETER(1, name + "->problem number","%d", &problemNumber); + epsilon = 0.1; + GET_PARAMETER(1, name + "->epsilon","%f", &epsilon); + alpha = 1.0; + GET_PARAMETER(1, name + "->alpha","%f", &alpha); + + + switch(problemNumber) { + case 0: + initialFunction = new InitialFunction0(epsilon); + break; + + case 1: + initialFunction = new InitialFunction1(epsilon); + break; + + case -1: + ERROR_EXIT("no problem number specified\n"); + break; + default: ERROR_EXIT("non existing problem number %d\n", problemNumber); + } + + }; + + + // === timestep =================================================== + void initTimestep() + { + uhOld->copy(*(problemStat->getUh())); + }; + + void closeTimestep() + { + FUNCNAME("closeTimestep"); + }; + + // === initial functions ================================== + void solveInitial() + { + //problemStat->getMesh()->dofCompress(); + //problemStat->getBoundaryFunction()->setTime(0.0); + //problemStat->getUh()->interpol(initialFunction); + }; + + void setEvaluationTimes() {}; + + double *getTimestepPtr() { return timestep; }; + + + double getAlpha(){ return alpha; }; + double getEpsilon(){ return epsilon; }; + + +private: + AbstractFunction<double, WorldVector> *initialFunction; + + double *timestep; + double epsilon; + double alpha; + +private: + class InitialFunction0 : public AbstractFunction<double, WorldVector> + { + public: + InitialFunction0(double epsilon_) : epsilon(epsilon_) {} + + const double& f(const WorldVector& x) const + { + static WorldVector midPoint(DEFAULT_VALUE, 2.0); + static double result; + static Circle circle1(1.0); + result = signedDistStar( x, midPoint, &circle1, epsilon ); + + }; + + private: + double epsilon; + + }; + + class InitialFunction1 : public AbstractFunction<double, WorldVector> + { + public: + InitialFunction1(double epsilon_) : epsilon(epsilon_) {} + + const double& f(const WorldVector& x) const + { + static WorldVector midPoint(DEFAULT_VALUE, 2.0); + static double result; + static PerturbedCircle perturbedCircle1(1.0, 0.3, 6); + result = signedDistStar( x, midPoint, &perturbedCircle1, epsilon ); + }; + + private: + double epsilon; + }; + +}; + + + + +int main(int argc, char** argv) +{ + TEST_EXIT(argc == 2)("usage: levelset initfile\n"); + + Parameters::init(false, argv[1]); + + LevelsetSpace *levelsetSpace = new LevelsetSpace; + + Levelset *levelset = new Levelset(levelsetSpace); + double epsilon = levelset->getEpsilon(); + double alpha = levelset->getAlpha(); + + + // create mass matrix M operator + Operator *operatorM = NEW Operator(Operator::MATRIX_OPERATOR | + Operator::VECTOR_OPERATOR, + levelsetSpace->getFESpace()); + + operatorM->addZeroOrderTerm(NEW SimpleZeroOrderTerm); + + operatorM->setUhOld(levelset->getUhOld()); + + levelsetSpace->addMatrixOperator(operatorM); + levelsetSpace->addVectorOperator(operatorM); + + // create mass matrix B operator + Operator *operatorB = NEW Operator(Operator::MATRIX_OPERATOR, + levelsetSpace->getFESpace()); + + operatorB->addSecondOrderTerm(NEW FctGradient_SOT(levelset->getUhOld(), + new GammaNorm(alpha, epsilon), + 100)); + + // create mass matrix A operator + Operator *operatorA = NEW Operator(Operator::MATRIX_OPERATOR, + levelsetSpace->getFESpace()); + + operatorA->addSecondOrderTerm(NEW MatrixGradient_SOT(levelset->getUhOld(), + new ProjectionGradNorm(epsilon), + 100)); + + // create rhs F + Operator *operatorF = NEW Operator(Operator::VECTOR_OPERATOR, + levelsetSpace->getFESpace()); + + operatorF->addFirstOrderTerm(NEW VectorGradient_FOT(levelset->getUhOld(), + new Gamma_zGradNorm(alpha,epsilon), + 100, false)); + + + // create rhs G + Operator *operatorG = NEW Operator(Operator::VECTOR_OPERATOR, + levelsetSpace->getFESpace()); + + operatorG->addFirstOrderTerm(NEW VectorGradient_FOT(levelset->getUhOld(), + new GammaGradNorm(alpha,epsilon), + 100, false)); + + + levelsetSpace->getMatrixA()->addOperator(operatorA); + levelsetSpace->getMatrixB()->addOperator(operatorB); + levelsetSpace->getMatrixM()->addOperator(operatorM); + levelsetSpace->getVectorF()->addOperator(operatorF); + levelsetSpace->getVectorG()->addOperator(operatorG); + + + levelsetSpace->addVectorOperator(operatorM); + + + levelset->adaptMethodInstat(); + + return 0; +} diff --git a/AMDiS/libtool b/AMDiS/libtool new file mode 100755 index 0000000000000000000000000000000000000000..315f21f9edc2dd35889d8300a9d22b7df3847804 --- /dev/null +++ b/AMDiS/libtool @@ -0,0 +1,7885 @@ +#! /bin/sh + +# libtoolT - Provide generalized library-building support services. +# Generated automatically by (GNU AMDiS 0.1) +# NOTE: Changes made to this file will be lost: look at ltmain.sh. +# +# Copyright (C) 1996, 1997, 1998, 1999, 2000, 2001 +# Free Software Foundation, Inc. +# +# This file is part of GNU Libtool: +# Originally by Gordon Matzigkeit <gord@gnu.ai.mit.edu>, 1996 +# +# 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. +# +# As a special exception to the GNU General Public License, if you +# distribute this file as part of a program that contains a +# configuration script generated by Autoconf, you may include it under +# the same distribution terms that you use for the rest of that program. + +# A sed program that does not truncate output. +SED="/bin/sed" + +# Sed that helps us avoid accidentally triggering echo(1) options like -n. +Xsed="/bin/sed -e 1s/^X//" + +# The HP-UX ksh and POSIX shell print the target directory to stdout +# if CDPATH is set. +(unset CDPATH) >/dev/null 2>&1 && unset CDPATH + +# The names of the tagged configurations supported by this script. +available_tags=" CXX F77" + +# ### BEGIN LIBTOOL CONFIG + +# Libtool was configured on host NWRW15: + +# Shell to use when invoking shell scripts. +SHELL="/bin/sh" + +# Whether or not to build shared libraries. +build_libtool_libs=yes + +# Whether or not to build static libraries. +build_old_libs=yes + +# Whether or not to add -lc for building shared libraries. +build_libtool_need_lc=no + +# Whether or not to disallow shared libs when runtime libs are static +allow_libtool_libs_with_static_runtimes=no + +# Whether or not to optimize for fast installation. +fast_install=yes + +# The host system. +host_alias= +host=i686-redhat-linux-gnu +host_os=linux-gnu + +# The build system. +build_alias= +build=i686-redhat-linux-gnu +build_os=linux-gnu + +# An echo program that does not interpret backslashes. +echo="echo" + +# The archiver. +AR="ar" +AR_FLAGS="cru" + +# A C compiler. +LTCC="gcc" + +# LTCC compiler flags. +LTCFLAGS="-g -O2" + +# A language-specific compiler. +CC="gcc" + +# Is the compiler the GNU C compiler? +with_gcc=yes + +gcc_dir=`gcc -print-file-name=. | /bin/sed 's,/\.$,,'` +gcc_ver=`gcc -dumpversion` + +# An ERE matcher. +EGREP="grep -E" + +# The linker used to build libraries. +LD="/usr/bin/ld" + +# Whether we need hard or soft links. +LN_S="ln -s" + +# A BSD-compatible nm program. +NM="/usr/bin/nm -B" + +# A symbol stripping program +STRIP="strip" + +# Used to examine libraries when file_magic_cmd begins "file" +MAGIC_CMD=file + +# Used on cygwin: DLL creation program. +DLLTOOL="dlltool" + +# Used on cygwin: object dumper. +OBJDUMP="objdump" + +# Used on cygwin: assembler. +AS="as" + +# The name of the directory that contains temporary libtool files. +objdir=.libs + +# How to create reloadable object files. +reload_flag=" -r" +reload_cmds="\$LD\$reload_flag -o \$output\$reload_objs" + +# How to pass a linker flag through the compiler. +wl="-Wl," + +# Object file suffix (normally "o"). +objext="o" + +# Old archive suffix (normally "a"). +libext="a" + +# Shared library suffix (normally ".so"). +shrext_cmds='.so' + +# Executable file suffix (normally ""). +exeext="" + +# Additional compiler flags for building library objects. +pic_flag=" -fPIC -DPIC" +pic_mode=default + +# What is the maximum length of a command? +max_cmd_len=32768 + +# Does compiler simultaneously support -c and -o options? +compiler_c_o="yes" + +# Must we lock files when doing compilation? +need_locks="no" + +# Do we need the lib prefix for modules? +need_lib_prefix=no + +# Do we need a version for libraries? +need_version=no + +# Whether dlopen is supported. +dlopen_support=unknown + +# Whether dlopen of programs is supported. +dlopen_self=unknown + +# Whether dlopen of statically linked programs is supported. +dlopen_self_static=unknown + +# Compiler flag to prevent dynamic linking. +link_static_flag="-static" + +# Compiler flag to turn off builtin functions. +no_builtin_flag=" -fno-builtin" + +# Compiler flag to allow reflexive dlopens. +export_dynamic_flag_spec="\${wl}--export-dynamic" + +# Compiler flag to generate shared objects directly from archives. +whole_archive_flag_spec="\${wl}--whole-archive\$convenience \${wl}--no-whole-archive" + +# Compiler flag to generate thread-safe objects. +thread_safe_flag_spec="" + +# Library versioning type. +version_type=linux + +# Format of library name prefix. +libname_spec="lib\$name" + +# List of archive names. First name is the real one, the rest are links. +# The last name is the one that the linker finds with -lNAME. +library_names_spec="\${libname}\${release}\${shared_ext}\$versuffix \${libname}\${release}\${shared_ext}\$major \$libname\${shared_ext}" + +# The coded name of the library, if different from the real name. +soname_spec="\${libname}\${release}\${shared_ext}\$major" + +# Commands used to build and install an old-style archive. +RANLIB="ranlib" +old_archive_cmds="\$AR \$AR_FLAGS \$oldlib\$oldobjs\$old_deplibs~\$RANLIB \$oldlib" +old_postinstall_cmds="chmod 644 \$oldlib~\$RANLIB \$oldlib" +old_postuninstall_cmds="" + +# Create an old-style archive from a shared archive. +old_archive_from_new_cmds="" + +# Create a temporary old-style archive to link instead of a shared archive. +old_archive_from_expsyms_cmds="" + +# Commands used to build and install a shared archive. +archive_cmds="\$CC -shared \$libobjs \$deplibs \$compiler_flags \${wl}-soname \$wl\$soname -o \$lib" +archive_expsym_cmds="\$echo \\\"{ global:\\\" > \$output_objdir/\$libname.ver~ + cat \$export_symbols | sed -e \\\"s/\\\\(.*\\\\)/\\\\1;/\\\" >> \$output_objdir/\$libname.ver~ + \$echo \\\"local: *; };\\\" >> \$output_objdir/\$libname.ver~ + \$CC -shared \$libobjs \$deplibs \$compiler_flags \${wl}-soname \$wl\$soname \${wl}-version-script \${wl}\$output_objdir/\$libname.ver -o \$lib" +postinstall_cmds="" +postuninstall_cmds="" + +# Commands used to build a loadable module (assumed same as above if empty) +module_cmds="" +module_expsym_cmds="" + +# Commands to strip libraries. +old_striplib="strip --strip-debug" +striplib="strip --strip-unneeded" + +# Dependencies to place before the objects being linked to create a +# shared library. +predep_objects=`echo "" | $SED -e "s@${gcc_dir}@\${gcc_dir}@g;s@${gcc_ver}@\${gcc_ver}@g"` + +# Dependencies to place after the objects being linked to create a +# shared library. +postdep_objects=`echo "" | $SED -e "s@${gcc_dir}@\${gcc_dir}@g;s@${gcc_ver}@\${gcc_ver}@g"` + +# Dependencies to place before the objects being linked to create a +# shared library. +predeps="" + +# Dependencies to place after the objects being linked to create a +# shared library. +postdeps="" + +# The library search path used internally by the compiler when linking +# a shared library. +compiler_lib_search_path=`echo "" | $SED -e "s@${gcc_dir}@\${gcc_dir}@g;s@${gcc_ver}@\${gcc_ver}@g"` + +# Method to check whether dependent libraries are shared objects. +deplibs_check_method="pass_all" + +# Command to use when deplibs_check_method == file_magic. +file_magic_cmd="\$MAGIC_CMD" + +# Flag that allows shared libraries with undefined symbols to be built. +allow_undefined_flag="" + +# Flag that forces no undefined symbols. +no_undefined_flag="" + +# Commands used to finish a libtool library installation in a directory. +finish_cmds="PATH=\\\"\\\$PATH:/sbin\\\" ldconfig -n \$libdir" + +# Same as above, but a single script fragment to be evaled but not shown. +finish_eval="" + +# Take the output of nm and produce a listing of raw symbols and C names. +global_symbol_pipe="sed -n -e 's/^.*[ ]\\([ABCDGIRSTW][ABCDGIRSTW]*\\)[ ][ ]*\\([_A-Za-z][_A-Za-z0-9]*\\)\$/\\1 \\2 \\2/p'" + +# Transform the output of nm in a proper C declaration +global_symbol_to_cdecl="sed -n -e 's/^. .* \\(.*\\)\$/extern int \\1;/p'" + +# Transform the output of nm in a C name address pair +global_symbol_to_c_name_address="sed -n -e 's/^: \\([^ ]*\\) \$/ {\\\"\\1\\\", (lt_ptr) 0},/p' -e 's/^[BCDEGRST] \\([^ ]*\\) \\([^ ]*\\)\$/ {\"\\2\", (lt_ptr) \\&\\2},/p'" + +# This is the shared library runtime path variable. +runpath_var=LD_RUN_PATH + +# This is the shared library path variable. +shlibpath_var=LD_LIBRARY_PATH + +# Is shlibpath searched before the hard-coded library search path? +shlibpath_overrides_runpath=no + +# How to hardcode a shared library path into an executable. +hardcode_action=immediate + +# Whether we should hardcode library paths into libraries. +hardcode_into_libs=yes + +# Flag to hardcode $libdir into a binary during linking. +# This must work even if $libdir does not exist. +hardcode_libdir_flag_spec="\${wl}--rpath \${wl}\$libdir" + +# If ld is used when linking, flag to hardcode $libdir into +# a binary during linking. This must work even if $libdir does +# not exist. +hardcode_libdir_flag_spec_ld="" + +# Whether we need a single -rpath flag with a separated argument. +hardcode_libdir_separator="" + +# Set to yes if using DIR/libNAME during linking hardcodes DIR into the +# resulting binary. +hardcode_direct=no + +# Set to yes if using the -LDIR flag during linking hardcodes DIR into the +# resulting binary. +hardcode_minus_L=no + +# Set to yes if using SHLIBPATH_VAR=DIR during linking hardcodes DIR into +# the resulting binary. +hardcode_shlibpath_var=unsupported + +# Set to yes if building a shared library automatically hardcodes DIR into the library +# and all subsequent libraries and executables linked against it. +hardcode_automatic=no + +# Variables whose values should be saved in libtool wrapper scripts and +# restored at relink time. +variables_saved_for_relink="PATH LD_LIBRARY_PATH LD_RUN_PATH GCC_EXEC_PREFIX COMPILER_PATH LIBRARY_PATH" + +# Whether libtool must link a program against all its dependency libraries. +link_all_deplibs=unknown + +# Compile-time system search path for libraries +sys_lib_search_path_spec=`echo " /usr/lib/gcc/i386-redhat-linux/4.1.2/ /usr/lib/gcc/i386-redhat-linux/4.1.2/ /usr/lib/gcc/i386-redhat-linux/4.1.2/../../../../i386-redhat-linux/lib/i386-redhat-linux/4.1.2/ /usr/lib/gcc/i386-redhat-linux/4.1.2/../../../../i386-redhat-linux/lib/ /usr/lib/gcc/i386-redhat-linux/4.1.2/../../../i386-redhat-linux/4.1.2/ /usr/lib/gcc/i386-redhat-linux/4.1.2/../../../ /lib/i386-redhat-linux/4.1.2/ /lib/ /usr/lib/i386-redhat-linux/4.1.2/ /usr/lib/" | $SED -e "s@${gcc_dir}@\${gcc_dir}@g;s@${gcc_ver}@\${gcc_ver}@g"` + +# Run-time system search path for libraries +sys_lib_dlsearch_path_spec="/lib /usr/lib /usr/lib/qt-3.3/lib " + +# Fix the shell variable $srcfile for the compiler. +fix_srcfile_path="" + +# Set to yes if exported symbols are required. +always_export_symbols=no + +# The commands to list exported symbols. +export_symbols_cmds="\$NM \$libobjs \$convenience | \$global_symbol_pipe | \$SED 's/.* //' | sort | uniq > \$export_symbols" + +# The commands to extract the exported symbol list from a shared archive. +extract_expsyms_cmds="" + +# Symbols that should not be listed in the preloaded symbols. +exclude_expsyms="_GLOBAL_OFFSET_TABLE_" + +# Symbols that must always be exported. +include_expsyms="" + +# ### END LIBTOOL CONFIG + +# ltmain.sh - Provide generalized library-building support services. +# NOTE: Changing this file will not affect anything until you rerun configure. +# +# Copyright (C) 1996, 1997, 1998, 1999, 2000, 2001, 2003, 2004, 2005 +# Free Software Foundation, Inc. +# Originally by Gordon Matzigkeit <gord@gnu.ai.mit.edu>, 1996 +# +# 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. +# +# As a special exception to the GNU General Public License, if you +# distribute this file as part of a program that contains a +# configuration script generated by Autoconf, you may include it under +# the same distribution terms that you use for the rest of that program. + +basename="s,^.*/,,g" + +# Work around backward compatibility issue on IRIX 6.5. On IRIX 6.4+, sh +# is ksh but when the shell is invoked as "sh" and the current value of +# the _XPG environment variable is not equal to 1 (one), the special +# positional parameter $0, within a function call, is the name of the +# function. +progpath="$0" + +# The name of this program: +progname=`echo "$progpath" | $SED $basename` +modename="$progname" + +# Global variables: +EXIT_SUCCESS=0 +EXIT_FAILURE=1 + +PROGRAM=ltmain.sh +PACKAGE=libtool +VERSION=1.5.22 +TIMESTAMP=" (1.1220.2.365 2005/12/18 22:14:06)" + +# Be Bourne compatible (taken from Autoconf:_AS_BOURNE_COMPATIBLE). +if test -n "${ZSH_VERSION+set}" && (emulate sh) >/dev/null 2>&1; then + emulate sh + NULLCMD=: + # Zsh 3.x and 4.x performs word splitting on ${1+"$@"}, which + # is contrary to our usage. Disable this feature. + alias -g '${1+"$@"}'='"$@"' + setopt NO_GLOB_SUBST +else + case `(set -o) 2>/dev/null` in *posix*) set -o posix;; esac +fi + +# Check that we have a working $echo. +if test "X$1" = X--no-reexec; then + # Discard the --no-reexec flag, and continue. + shift +elif test "X$1" = X--fallback-echo; then + # Avoid inline document here, it may be left over + : +elif test "X`($echo '\t') 2>/dev/null`" = 'X\t'; then + # Yippee, $echo works! + : +else + # Restart under the correct shell, and then maybe $echo will work. + exec $SHELL "$progpath" --no-reexec ${1+"$@"} +fi + +if test "X$1" = X--fallback-echo; then + # used as fallback echo + shift + cat <<EOF +$* +EOF + exit $EXIT_SUCCESS +fi + +default_mode= +help="Try \`$progname --help' for more information." +magic="%%%MAGIC variable%%%" +mkdir="mkdir" +mv="mv -f" +rm="rm -f" + +# Sed substitution that helps us do robust quoting. It backslashifies +# metacharacters that are still active within double-quoted strings. +Xsed="${SED}"' -e 1s/^X//' +sed_quote_subst='s/\([\\`\\"$\\\\]\)/\\\1/g' +# test EBCDIC or ASCII +case `echo X|tr X '\101'` in + A) # ASCII based system + # \n is not interpreted correctly by Solaris 8 /usr/ucb/tr + SP2NL='tr \040 \012' + NL2SP='tr \015\012 \040\040' + ;; + *) # EBCDIC based system + SP2NL='tr \100 \n' + NL2SP='tr \r\n \100\100' + ;; +esac + +# NLS nuisances. +# Only set LANG and LC_ALL to C if already set. +# These must not be set unconditionally because not all systems understand +# e.g. LANG=C (notably SCO). +# We save the old values to restore during execute mode. +for lt_var in LANG LC_ALL LC_CTYPE LC_COLLATE LC_MESSAGES +do + eval "if test \"\${$lt_var+set}\" = set; then + save_$lt_var=\$$lt_var + $lt_var=C + export $lt_var + fi" +done + +# Make sure IFS has a sensible default +lt_nl=' +' +IFS=" $lt_nl" + +if test "$build_libtool_libs" != yes && test "$build_old_libs" != yes; then + $echo "$modename: not configured to build any kind of library" 1>&2 + $echo "Fatal configuration error. See the $PACKAGE docs for more information." 1>&2 + exit $EXIT_FAILURE +fi + +# Global variables. +mode=$default_mode +nonopt= +prev= +prevopt= +run= +show="$echo" +show_help= +execute_dlfiles= +duplicate_deps=no +preserve_args= +lo2o="s/\\.lo\$/.${objext}/" +o2lo="s/\\.${objext}\$/.lo/" +extracted_archives= +extracted_serial=0 + +##################################### +# Shell function definitions: +# This seems to be the best place for them + +# func_mktempdir [string] +# Make a temporary directory that won't clash with other running +# libtool processes, and avoids race conditions if possible. If +# given, STRING is the basename for that directory. +func_mktempdir () +{ + my_template="${TMPDIR-/tmp}/${1-$progname}" + + if test "$run" = ":"; then + # Return a directory name, but don't create it in dry-run mode + my_tmpdir="${my_template}-$$" + else + + # If mktemp works, use that first and foremost + my_tmpdir=`mktemp -d "${my_template}-XXXXXXXX" 2>/dev/null` + + if test ! -d "$my_tmpdir"; then + # Failing that, at least try and use $RANDOM to avoid a race + my_tmpdir="${my_template}-${RANDOM-0}$$" + + save_mktempdir_umask=`umask` + umask 0077 + $mkdir "$my_tmpdir" + umask $save_mktempdir_umask + fi + + # If we're not in dry-run mode, bomb out on failure + test -d "$my_tmpdir" || { + $echo "cannot create temporary directory \`$my_tmpdir'" 1>&2 + exit $EXIT_FAILURE + } + fi + + $echo "X$my_tmpdir" | $Xsed +} + + +# func_win32_libid arg +# return the library type of file 'arg' +# +# Need a lot of goo to handle *both* DLLs and import libs +# Has to be a shell function in order to 'eat' the argument +# that is supplied when $file_magic_command is called. +func_win32_libid () +{ + win32_libid_type="unknown" + win32_fileres=`file -L $1 2>/dev/null` + case $win32_fileres in + *ar\ archive\ import\ library*) # definitely import + win32_libid_type="x86 archive import" + ;; + *ar\ archive*) # could be an import, or static + if eval $OBJDUMP -f $1 | $SED -e '10q' 2>/dev/null | \ + $EGREP -e 'file format pe-i386(.*architecture: i386)?' >/dev/null ; then + win32_nmres=`eval $NM -f posix -A $1 | \ + $SED -n -e '1,100{/ I /{s,.*,import,;p;q;};}'` + case $win32_nmres in + import*) win32_libid_type="x86 archive import";; + *) win32_libid_type="x86 archive static";; + esac + fi + ;; + *DLL*) + win32_libid_type="x86 DLL" + ;; + *executable*) # but shell scripts are "executable" too... + case $win32_fileres in + *MS\ Windows\ PE\ Intel*) + win32_libid_type="x86 DLL" + ;; + esac + ;; + esac + $echo $win32_libid_type +} + + +# func_infer_tag arg +# Infer tagged configuration to use if any are available and +# if one wasn't chosen via the "--tag" command line option. +# Only attempt this if the compiler in the base compile +# command doesn't match the default compiler. +# arg is usually of the form 'gcc ...' +func_infer_tag () +{ + if test -n "$available_tags" && test -z "$tagname"; then + CC_quoted= + for arg in $CC; do + case $arg in + *[\[\~\#\^\&\*\(\)\{\}\|\;\<\>\?\'\ \ ]*|*]*|"") + arg="\"$arg\"" + ;; + esac + CC_quoted="$CC_quoted $arg" + done + case $@ in + # Blanks in the command may have been stripped by the calling shell, + # but not from the CC environment variable when configure was run. + " $CC "* | "$CC "* | " `$echo $CC` "* | "`$echo $CC` "* | " $CC_quoted"* | "$CC_quoted "* | " `$echo $CC_quoted` "* | "`$echo $CC_quoted` "*) ;; + # Blanks at the start of $base_compile will cause this to fail + # if we don't check for them as well. + *) + for z in $available_tags; do + if grep "^# ### BEGIN LIBTOOL TAG CONFIG: $z$" < "$progpath" > /dev/null; then + # Evaluate the configuration. + eval "`${SED} -n -e '/^# ### BEGIN LIBTOOL TAG CONFIG: '$z'$/,/^# ### END LIBTOOL TAG CONFIG: '$z'$/p' < $progpath`" + CC_quoted= + for arg in $CC; do + # Double-quote args containing other shell metacharacters. + case $arg in + *[\[\~\#\^\&\*\(\)\{\}\|\;\<\>\?\'\ \ ]*|*]*|"") + arg="\"$arg\"" + ;; + esac + CC_quoted="$CC_quoted $arg" + done + case "$@ " in + " $CC "* | "$CC "* | " `$echo $CC` "* | "`$echo $CC` "* | " $CC_quoted"* | "$CC_quoted "* | " `$echo $CC_quoted` "* | "`$echo $CC_quoted` "*) + # The compiler in the base compile command matches + # the one in the tagged configuration. + # Assume this is the tagged configuration we want. + tagname=$z + break + ;; + esac + fi + done + # If $tagname still isn't set, then no tagged configuration + # was found and let the user know that the "--tag" command + # line option must be used. + if test -z "$tagname"; then + $echo "$modename: unable to infer tagged configuration" + $echo "$modename: specify a tag with \`--tag'" 1>&2 + exit $EXIT_FAILURE +# else +# $echo "$modename: using $tagname tagged configuration" + fi + ;; + esac + fi +} + + +# func_extract_an_archive dir oldlib +func_extract_an_archive () +{ + f_ex_an_ar_dir="$1"; shift + f_ex_an_ar_oldlib="$1" + + $show "(cd $f_ex_an_ar_dir && $AR x $f_ex_an_ar_oldlib)" + $run eval "(cd \$f_ex_an_ar_dir && $AR x \$f_ex_an_ar_oldlib)" || exit $? + if ($AR t "$f_ex_an_ar_oldlib" | sort | sort -uc >/dev/null 2>&1); then + : + else + $echo "$modename: ERROR: object name conflicts: $f_ex_an_ar_dir/$f_ex_an_ar_oldlib" 1>&2 + exit $EXIT_FAILURE + fi +} + +# func_extract_archives gentop oldlib ... +func_extract_archives () +{ + my_gentop="$1"; shift + my_oldlibs=${1+"$@"} + my_oldobjs="" + my_xlib="" + my_xabs="" + my_xdir="" + my_status="" + + $show "${rm}r $my_gentop" + $run ${rm}r "$my_gentop" + $show "$mkdir $my_gentop" + $run $mkdir "$my_gentop" + my_status=$? + if test "$my_status" -ne 0 && test ! -d "$my_gentop"; then + exit $my_status + fi + + for my_xlib in $my_oldlibs; do + # Extract the objects. + case $my_xlib in + [\\/]* | [A-Za-z]:[\\/]*) my_xabs="$my_xlib" ;; + *) my_xabs=`pwd`"/$my_xlib" ;; + esac + my_xlib=`$echo "X$my_xlib" | $Xsed -e 's%^.*/%%'` + my_xlib_u=$my_xlib + while :; do + case " $extracted_archives " in + *" $my_xlib_u "*) + extracted_serial=`expr $extracted_serial + 1` + my_xlib_u=lt$extracted_serial-$my_xlib ;; + *) break ;; + esac + done + extracted_archives="$extracted_archives $my_xlib_u" + my_xdir="$my_gentop/$my_xlib_u" + + $show "${rm}r $my_xdir" + $run ${rm}r "$my_xdir" + $show "$mkdir $my_xdir" + $run $mkdir "$my_xdir" + exit_status=$? + if test "$exit_status" -ne 0 && test ! -d "$my_xdir"; then + exit $exit_status + fi + case $host in + *-darwin*) + $show "Extracting $my_xabs" + # Do not bother doing anything if just a dry run + if test -z "$run"; then + darwin_orig_dir=`pwd` + cd $my_xdir || exit $? + darwin_archive=$my_xabs + darwin_curdir=`pwd` + darwin_base_archive=`$echo "X$darwin_archive" | $Xsed -e 's%^.*/%%'` + darwin_arches=`lipo -info "$darwin_archive" 2>/dev/null | $EGREP Architectures 2>/dev/null` + if test -n "$darwin_arches"; then + darwin_arches=`echo "$darwin_arches" | $SED -e 's/.*are://'` + darwin_arch= + $show "$darwin_base_archive has multiple architectures $darwin_arches" + for darwin_arch in $darwin_arches ; do + mkdir -p "unfat-$$/${darwin_base_archive}-${darwin_arch}" + lipo -thin $darwin_arch -output "unfat-$$/${darwin_base_archive}-${darwin_arch}/${darwin_base_archive}" "${darwin_archive}" + cd "unfat-$$/${darwin_base_archive}-${darwin_arch}" + func_extract_an_archive "`pwd`" "${darwin_base_archive}" + cd "$darwin_curdir" + $rm "unfat-$$/${darwin_base_archive}-${darwin_arch}/${darwin_base_archive}" + done # $darwin_arches + ## Okay now we have a bunch of thin objects, gotta fatten them up :) + darwin_filelist=`find unfat-$$ -type f -name \*.o -print -o -name \*.lo -print| xargs basename | sort -u | $NL2SP` + darwin_file= + darwin_files= + for darwin_file in $darwin_filelist; do + darwin_files=`find unfat-$$ -name $darwin_file -print | $NL2SP` + lipo -create -output "$darwin_file" $darwin_files + done # $darwin_filelist + ${rm}r unfat-$$ + cd "$darwin_orig_dir" + else + cd "$darwin_orig_dir" + func_extract_an_archive "$my_xdir" "$my_xabs" + fi # $darwin_arches + fi # $run + ;; + *) + func_extract_an_archive "$my_xdir" "$my_xabs" + ;; + esac + my_oldobjs="$my_oldobjs "`find $my_xdir -name \*.$objext -print -o -name \*.lo -print | $NL2SP` + done + func_extract_archives_result="$my_oldobjs" +} +# End of Shell function definitions +##################################### + +# Darwin sucks +eval std_shrext=\"$shrext_cmds\" + +disable_libs=no + +# Parse our command line options once, thoroughly. +while test "$#" -gt 0 +do + arg="$1" + shift + + case $arg in + -*=*) optarg=`$echo "X$arg" | $Xsed -e 's/[-_a-zA-Z0-9]*=//'` ;; + *) optarg= ;; + esac + + # If the previous option needs an argument, assign it. + if test -n "$prev"; then + case $prev in + execute_dlfiles) + execute_dlfiles="$execute_dlfiles $arg" + ;; + tag) + tagname="$arg" + preserve_args="${preserve_args}=$arg" + + # Check whether tagname contains only valid characters + case $tagname in + *[!-_A-Za-z0-9,/]*) + $echo "$progname: invalid tag name: $tagname" 1>&2 + exit $EXIT_FAILURE + ;; + esac + + case $tagname in + CC) + # Don't test for the "default" C tag, as we know, it's there, but + # not specially marked. + ;; + *) + if grep "^# ### BEGIN LIBTOOL TAG CONFIG: $tagname$" < "$progpath" > /dev/null; then + taglist="$taglist $tagname" + # Evaluate the configuration. + eval "`${SED} -n -e '/^# ### BEGIN LIBTOOL TAG CONFIG: '$tagname'$/,/^# ### END LIBTOOL TAG CONFIG: '$tagname'$/p' < $progpath`" + else + $echo "$progname: ignoring unknown tag $tagname" 1>&2 + fi + ;; + esac + ;; + *) + eval "$prev=\$arg" + ;; + esac + + prev= + prevopt= + continue + fi + + # Have we seen a non-optional argument yet? + case $arg in + --help) + show_help=yes + ;; + + --version) + $echo "$PROGRAM (GNU $PACKAGE) $VERSION$TIMESTAMP" + $echo + $echo "Copyright (C) 2005 Free Software Foundation, Inc." + $echo "This is free software; see the source for copying conditions. There is NO" + $echo "warranty; not even for MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE." + exit $? + ;; + + --config) + ${SED} -e '1,/^# ### BEGIN LIBTOOL CONFIG/d' -e '/^# ### END LIBTOOL CONFIG/,$d' $progpath + # Now print the configurations for the tags. + for tagname in $taglist; do + ${SED} -n -e "/^# ### BEGIN LIBTOOL TAG CONFIG: $tagname$/,/^# ### END LIBTOOL TAG CONFIG: $tagname$/p" < "$progpath" + done + exit $? + ;; + + --debug) + $echo "$progname: enabling shell trace mode" + set -x + preserve_args="$preserve_args $arg" + ;; + + --dry-run | -n) + run=: + ;; + + --features) + $echo "host: $host" + if test "$build_libtool_libs" = yes; then + $echo "enable shared libraries" + else + $echo "disable shared libraries" + fi + if test "$build_old_libs" = yes; then + $echo "enable static libraries" + else + $echo "disable static libraries" + fi + exit $? + ;; + + --finish) mode="finish" ;; + + --mode) prevopt="--mode" prev=mode ;; + --mode=*) mode="$optarg" ;; + + --preserve-dup-deps) duplicate_deps="yes" ;; + + --quiet | --silent) + show=: + preserve_args="$preserve_args $arg" + ;; + + --tag) + prevopt="--tag" + prev=tag + preserve_args="$preserve_args --tag" + ;; + --tag=*) + set tag "$optarg" ${1+"$@"} + shift + prev=tag + preserve_args="$preserve_args --tag" + ;; + + -dlopen) + prevopt="-dlopen" + prev=execute_dlfiles + ;; + + -*) + $echo "$modename: unrecognized option \`$arg'" 1>&2 + $echo "$help" 1>&2 + exit $EXIT_FAILURE + ;; + + *) + nonopt="$arg" + break + ;; + esac +done + +if test -n "$prevopt"; then + $echo "$modename: option \`$prevopt' requires an argument" 1>&2 + $echo "$help" 1>&2 + exit $EXIT_FAILURE +fi + +case $disable_libs in +no) + ;; +shared) + build_libtool_libs=no + build_old_libs=yes + ;; +static) + build_old_libs=`case $build_libtool_libs in yes) echo no;; *) echo yes;; esac` + ;; +esac + +# If this variable is set in any of the actions, the command in it +# will be execed at the end. This prevents here-documents from being +# left over by shells. +exec_cmd= + +if test -z "$show_help"; then + + # Infer the operation mode. + if test -z "$mode"; then + $echo "*** Warning: inferring the mode of operation is deprecated." 1>&2 + $echo "*** Future versions of Libtool will require --mode=MODE be specified." 1>&2 + case $nonopt in + *cc | cc* | *++ | gcc* | *-gcc* | g++* | xlc*) + mode=link + for arg + do + case $arg in + -c) + mode=compile + break + ;; + esac + done + ;; + *db | *dbx | *strace | *truss) + mode=execute + ;; + *install*|cp|mv) + mode=install + ;; + *rm) + mode=uninstall + ;; + *) + # If we have no mode, but dlfiles were specified, then do execute mode. + test -n "$execute_dlfiles" && mode=execute + + # Just use the default operation mode. + if test -z "$mode"; then + if test -n "$nonopt"; then + $echo "$modename: warning: cannot infer operation mode from \`$nonopt'" 1>&2 + else + $echo "$modename: warning: cannot infer operation mode without MODE-ARGS" 1>&2 + fi + fi + ;; + esac + fi + + # Only execute mode is allowed to have -dlopen flags. + if test -n "$execute_dlfiles" && test "$mode" != execute; then + $echo "$modename: unrecognized option \`-dlopen'" 1>&2 + $echo "$help" 1>&2 + exit $EXIT_FAILURE + fi + + # Change the help message to a mode-specific one. + generic_help="$help" + help="Try \`$modename --help --mode=$mode' for more information." + + # These modes are in order of execution frequency so that they run quickly. + case $mode in + # libtool compile mode + compile) + modename="$modename: compile" + # Get the compilation command and the source file. + base_compile= + srcfile="$nonopt" # always keep a non-empty value in "srcfile" + suppress_opt=yes + suppress_output= + arg_mode=normal + libobj= + later= + + for arg + do + case $arg_mode in + arg ) + # do not "continue". Instead, add this to base_compile + lastarg="$arg" + arg_mode=normal + ;; + + target ) + libobj="$arg" + arg_mode=normal + continue + ;; + + normal ) + # Accept any command-line options. + case $arg in + -o) + if test -n "$libobj" ; then + $echo "$modename: you cannot specify \`-o' more than once" 1>&2 + exit $EXIT_FAILURE + fi + arg_mode=target + continue + ;; + + -static | -prefer-pic | -prefer-non-pic) + later="$later $arg" + continue + ;; + + -no-suppress) + suppress_opt=no + continue + ;; + + -Xcompiler) + arg_mode=arg # the next one goes into the "base_compile" arg list + continue # The current "srcfile" will either be retained or + ;; # replaced later. I would guess that would be a bug. + + -Wc,*) + args=`$echo "X$arg" | $Xsed -e "s/^-Wc,//"` + lastarg= + save_ifs="$IFS"; IFS=',' + for arg in $args; do + IFS="$save_ifs" + + # Double-quote args containing other shell metacharacters. + # Many Bourne shells cannot handle close brackets correctly + # in scan sets, so we specify it separately. + case $arg in + *[\[\~\#\^\&\*\(\)\{\}\|\;\<\>\?\'\ \ ]*|*]*|"") + arg="\"$arg\"" + ;; + esac + lastarg="$lastarg $arg" + done + IFS="$save_ifs" + lastarg=`$echo "X$lastarg" | $Xsed -e "s/^ //"` + + # Add the arguments to base_compile. + base_compile="$base_compile $lastarg" + continue + ;; + + * ) + # Accept the current argument as the source file. + # The previous "srcfile" becomes the current argument. + # + lastarg="$srcfile" + srcfile="$arg" + ;; + esac # case $arg + ;; + esac # case $arg_mode + + # Aesthetically quote the previous argument. + lastarg=`$echo "X$lastarg" | $Xsed -e "$sed_quote_subst"` + + case $lastarg in + # Double-quote args containing other shell metacharacters. + # Many Bourne shells cannot handle close brackets correctly + # in scan sets, and some SunOS ksh mistreat backslash-escaping + # in scan sets (worked around with variable expansion), + # and furthermore cannot handle '|' '&' '(' ')' in scan sets + # at all, so we specify them separately. + *[\[\~\#\^\&\*\(\)\{\}\|\;\<\>\?\'\ \ ]*|*]*|"") + lastarg="\"$lastarg\"" + ;; + esac + + base_compile="$base_compile $lastarg" + done # for arg + + case $arg_mode in + arg) + $echo "$modename: you must specify an argument for -Xcompile" + exit $EXIT_FAILURE + ;; + target) + $echo "$modename: you must specify a target with \`-o'" 1>&2 + exit $EXIT_FAILURE + ;; + *) + # Get the name of the library object. + [ -z "$libobj" ] && libobj=`$echo "X$srcfile" | $Xsed -e 's%^.*/%%'` + ;; + esac + + # Recognize several different file suffixes. + # If the user specifies -o file.o, it is replaced with file.lo + xform='[cCFSifmso]' + case $libobj in + *.ada) xform=ada ;; + *.adb) xform=adb ;; + *.ads) xform=ads ;; + *.asm) xform=asm ;; + *.c++) xform=c++ ;; + *.cc) xform=cc ;; + *.ii) xform=ii ;; + *.class) xform=class ;; + *.cpp) xform=cpp ;; + *.cxx) xform=cxx ;; + *.f90) xform=f90 ;; + *.for) xform=for ;; + *.java) xform=java ;; + *.obj) xform=obj ;; + esac + + libobj=`$echo "X$libobj" | $Xsed -e "s/\.$xform$/.lo/"` + + case $libobj in + *.lo) obj=`$echo "X$libobj" | $Xsed -e "$lo2o"` ;; + *) + $echo "$modename: cannot determine name of library object from \`$libobj'" 1>&2 + exit $EXIT_FAILURE + ;; + esac + + func_infer_tag $base_compile + + for arg in $later; do + case $arg in + -static) + build_old_libs=yes + continue + ;; + + -prefer-pic) + pic_mode=yes + continue + ;; + + -prefer-non-pic) + pic_mode=no + continue + ;; + esac + done + + qlibobj=`$echo "X$libobj" | $Xsed -e "$sed_quote_subst"` + case $qlibobj in + *[\[\~\#\^\&\*\(\)\{\}\|\;\<\>\?\'\ \ ]*|*]*|"") + qlibobj="\"$qlibobj\"" ;; + esac + test "X$libobj" != "X$qlibobj" \ + && $echo "X$libobj" | grep '[]~#^*{};<>?"'"'"' &()|`$[]' \ + && $echo "$modename: libobj name \`$libobj' may not contain shell special characters." + objname=`$echo "X$obj" | $Xsed -e 's%^.*/%%'` + xdir=`$echo "X$obj" | $Xsed -e 's%/[^/]*$%%'` + if test "X$xdir" = "X$obj"; then + xdir= + else + xdir=$xdir/ + fi + lobj=${xdir}$objdir/$objname + + if test -z "$base_compile"; then + $echo "$modename: you must specify a compilation command" 1>&2 + $echo "$help" 1>&2 + exit $EXIT_FAILURE + fi + + # Delete any leftover library objects. + if test "$build_old_libs" = yes; then + removelist="$obj $lobj $libobj ${libobj}T" + else + removelist="$lobj $libobj ${libobj}T" + fi + + $run $rm $removelist + trap "$run $rm $removelist; exit $EXIT_FAILURE" 1 2 15 + + # On Cygwin there's no "real" PIC flag so we must build both object types + case $host_os in + cygwin* | mingw* | pw32* | os2*) + pic_mode=default + ;; + esac + if test "$pic_mode" = no && test "$deplibs_check_method" != pass_all; then + # non-PIC code in shared libraries is not supported + pic_mode=default + fi + + # Calculate the filename of the output object if compiler does + # not support -o with -c + if test "$compiler_c_o" = no; then + output_obj=`$echo "X$srcfile" | $Xsed -e 's%^.*/%%' -e 's%\.[^.]*$%%'`.${objext} + lockfile="$output_obj.lock" + removelist="$removelist $output_obj $lockfile" + trap "$run $rm $removelist; exit $EXIT_FAILURE" 1 2 15 + else + output_obj= + need_locks=no + lockfile= + fi + + # Lock this critical section if it is needed + # We use this script file to make the link, it avoids creating a new file + if test "$need_locks" = yes; then + until $run ln "$progpath" "$lockfile" 2>/dev/null; do + $show "Waiting for $lockfile to be removed" + sleep 2 + done + elif test "$need_locks" = warn; then + if test -f "$lockfile"; then + $echo "\ +*** ERROR, $lockfile exists and contains: +`cat $lockfile 2>/dev/null` + +This indicates that another process is trying to use the same +temporary object file, and libtool could not work around it because +your compiler does not support \`-c' and \`-o' together. If you +repeat this compilation, it may succeed, by chance, but you had better +avoid parallel builds (make -j) in this platform, or get a better +compiler." + + $run $rm $removelist + exit $EXIT_FAILURE + fi + $echo "$srcfile" > "$lockfile" + fi + + if test -n "$fix_srcfile_path"; then + eval srcfile=\"$fix_srcfile_path\" + fi + qsrcfile=`$echo "X$srcfile" | $Xsed -e "$sed_quote_subst"` + case $qsrcfile in + *[\[\~\#\^\&\*\(\)\{\}\|\;\<\>\?\'\ \ ]*|*]*|"") + qsrcfile="\"$qsrcfile\"" ;; + esac + + $run $rm "$libobj" "${libobj}T" + + # Create a libtool object file (analogous to a ".la" file), + # but don't create it if we're doing a dry run. + test -z "$run" && cat > ${libobj}T <<EOF +# $libobj - a libtool object file +# Generated by $PROGRAM - GNU $PACKAGE $VERSION$TIMESTAMP +# +# Please DO NOT delete this file! +# It is necessary for linking the library. + +# Name of the PIC object. +EOF + + # Only build a PIC object if we are building libtool libraries. + if test "$build_libtool_libs" = yes; then + # Without this assignment, base_compile gets emptied. + fbsd_hideous_sh_bug=$base_compile + + if test "$pic_mode" != no; then + command="$base_compile $qsrcfile $pic_flag" + else + # Don't build PIC code + command="$base_compile $qsrcfile" + fi + + if test ! -d "${xdir}$objdir"; then + $show "$mkdir ${xdir}$objdir" + $run $mkdir ${xdir}$objdir + exit_status=$? + if test "$exit_status" -ne 0 && test ! -d "${xdir}$objdir"; then + exit $exit_status + fi + fi + + if test -z "$output_obj"; then + # Place PIC objects in $objdir + command="$command -o $lobj" + fi + + $run $rm "$lobj" "$output_obj" + + $show "$command" + if $run eval "$command"; then : + else + test -n "$output_obj" && $run $rm $removelist + exit $EXIT_FAILURE + fi + + if test "$need_locks" = warn && + test "X`cat $lockfile 2>/dev/null`" != "X$srcfile"; then + $echo "\ +*** ERROR, $lockfile contains: +`cat $lockfile 2>/dev/null` + +but it should contain: +$srcfile + +This indicates that another process is trying to use the same +temporary object file, and libtool could not work around it because +your compiler does not support \`-c' and \`-o' together. If you +repeat this compilation, it may succeed, by chance, but you had better +avoid parallel builds (make -j) in this platform, or get a better +compiler." + + $run $rm $removelist + exit $EXIT_FAILURE + fi + + # Just move the object if needed, then go on to compile the next one + if test -n "$output_obj" && test "X$output_obj" != "X$lobj"; then + $show "$mv $output_obj $lobj" + if $run $mv $output_obj $lobj; then : + else + error=$? + $run $rm $removelist + exit $error + fi + fi + + # Append the name of the PIC object to the libtool object file. + test -z "$run" && cat >> ${libobj}T <<EOF +pic_object='$objdir/$objname' + +EOF + + # Allow error messages only from the first compilation. + if test "$suppress_opt" = yes; then + suppress_output=' >/dev/null 2>&1' + fi + else + # No PIC object so indicate it doesn't exist in the libtool + # object file. + test -z "$run" && cat >> ${libobj}T <<EOF +pic_object=none + +EOF + fi + + # Only build a position-dependent object if we build old libraries. + if test "$build_old_libs" = yes; then + if test "$pic_mode" != yes; then + # Don't build PIC code + command="$base_compile $qsrcfile" + else + command="$base_compile $qsrcfile $pic_flag" + fi + if test "$compiler_c_o" = yes; then + command="$command -o $obj" + fi + + # Suppress compiler output if we already did a PIC compilation. + command="$command$suppress_output" + $run $rm "$obj" "$output_obj" + $show "$command" + if $run eval "$command"; then : + else + $run $rm $removelist + exit $EXIT_FAILURE + fi + + if test "$need_locks" = warn && + test "X`cat $lockfile 2>/dev/null`" != "X$srcfile"; then + $echo "\ +*** ERROR, $lockfile contains: +`cat $lockfile 2>/dev/null` + +but it should contain: +$srcfile + +This indicates that another process is trying to use the same +temporary object file, and libtool could not work around it because +your compiler does not support \`-c' and \`-o' together. If you +repeat this compilation, it may succeed, by chance, but you had better +avoid parallel builds (make -j) in this platform, or get a better +compiler." + + $run $rm $removelist + exit $EXIT_FAILURE + fi + + # Just move the object if needed + if test -n "$output_obj" && test "X$output_obj" != "X$obj"; then + $show "$mv $output_obj $obj" + if $run $mv $output_obj $obj; then : + else + error=$? + $run $rm $removelist + exit $error + fi + fi + + # Append the name of the non-PIC object the libtool object file. + # Only append if the libtool object file exists. + test -z "$run" && cat >> ${libobj}T <<EOF +# Name of the non-PIC object. +non_pic_object='$objname' + +EOF + else + # Append the name of the non-PIC object the libtool object file. + # Only append if the libtool object file exists. + test -z "$run" && cat >> ${libobj}T <<EOF +# Name of the non-PIC object. +non_pic_object=none + +EOF + fi + + $run $mv "${libobj}T" "${libobj}" + + # Unlock the critical section if it was locked + if test "$need_locks" != no; then + $run $rm "$lockfile" + fi + + exit $EXIT_SUCCESS + ;; + + # libtool link mode + link | relink) + modename="$modename: link" + case $host in + *-*-cygwin* | *-*-mingw* | *-*-pw32* | *-*-os2*) + # It is impossible to link a dll without this setting, and + # we shouldn't force the makefile maintainer to figure out + # which system we are compiling for in order to pass an extra + # flag for every libtool invocation. + # allow_undefined=no + + # FIXME: Unfortunately, there are problems with the above when trying + # to make a dll which has undefined symbols, in which case not + # even a static library is built. For now, we need to specify + # -no-undefined on the libtool link line when we can be certain + # that all symbols are satisfied, otherwise we get a static library. + allow_undefined=yes + ;; + *) + allow_undefined=yes + ;; + esac + libtool_args="$nonopt" + base_compile="$nonopt $@" + compile_command="$nonopt" + finalize_command="$nonopt" + + compile_rpath= + finalize_rpath= + compile_shlibpath= + finalize_shlibpath= + convenience= + old_convenience= + deplibs= + old_deplibs= + compiler_flags= + linker_flags= + dllsearchpath= + lib_search_path=`pwd` + inst_prefix_dir= + + avoid_version=no + dlfiles= + dlprefiles= + dlself=no + export_dynamic=no + export_symbols= + export_symbols_regex= + generated= + libobjs= + ltlibs= + module=no + no_install=no + objs= + non_pic_objects= + notinst_path= # paths that contain not-installed libtool libraries + precious_files_regex= + prefer_static_libs=no + preload=no + prev= + prevarg= + release= + rpath= + xrpath= + perm_rpath= + temp_rpath= + thread_safe=no + vinfo= + vinfo_number=no + + func_infer_tag $base_compile + + # We need to know -static, to get the right output filenames. + for arg + do + case $arg in + -all-static | -static | -static-libtool-libs) + case $arg in + -all-static) + if test "$build_libtool_libs" = yes && test -z "$link_static_flag"; then + $echo "$modename: warning: complete static linking is impossible in this configuration" 1>&2 + fi + if test -n "$link_static_flag"; then + dlopen_self=$dlopen_self_static + fi + prefer_static_libs=yes + ;; + -static) + if test -z "$pic_flag" && test -n "$link_static_flag"; then + dlopen_self=$dlopen_self_static + fi + prefer_static_libs=built + ;; + -static-libtool-libs) + if test -z "$pic_flag" && test -n "$link_static_flag"; then + dlopen_self=$dlopen_self_static + fi + prefer_static_libs=yes + ;; + esac + build_libtool_libs=no + build_old_libs=yes + break + ;; + esac + done + + # See if our shared archives depend on static archives. + test -n "$old_archive_from_new_cmds" && build_old_libs=yes + + # Go through the arguments, transforming them on the way. + while test "$#" -gt 0; do + arg="$1" + shift + case $arg in + *[\[\~\#\^\&\*\(\)\{\}\|\;\<\>\?\'\ \ ]*|*]*|"") + qarg=\"`$echo "X$arg" | $Xsed -e "$sed_quote_subst"`\" ### testsuite: skip nested quoting test + ;; + *) qarg=$arg ;; + esac + libtool_args="$libtool_args $qarg" + + # If the previous option needs an argument, assign it. + if test -n "$prev"; then + case $prev in + output) + compile_command="$compile_command @OUTPUT@" + finalize_command="$finalize_command @OUTPUT@" + ;; + esac + + case $prev in + dlfiles|dlprefiles) + if test "$preload" = no; then + # Add the symbol object into the linking commands. + compile_command="$compile_command @SYMFILE@" + finalize_command="$finalize_command @SYMFILE@" + preload=yes + fi + case $arg in + *.la | *.lo) ;; # We handle these cases below. + force) + if test "$dlself" = no; then + dlself=needless + export_dynamic=yes + fi + prev= + continue + ;; + self) + if test "$prev" = dlprefiles; then + dlself=yes + elif test "$prev" = dlfiles && test "$dlopen_self" != yes; then + dlself=yes + else + dlself=needless + export_dynamic=yes + fi + prev= + continue + ;; + *) + if test "$prev" = dlfiles; then + dlfiles="$dlfiles $arg" + else + dlprefiles="$dlprefiles $arg" + fi + prev= + continue + ;; + esac + ;; + expsyms) + export_symbols="$arg" + if test ! -f "$arg"; then + $echo "$modename: symbol file \`$arg' does not exist" + exit $EXIT_FAILURE + fi + prev= + continue + ;; + expsyms_regex) + export_symbols_regex="$arg" + prev= + continue + ;; + inst_prefix) + inst_prefix_dir="$arg" + prev= + continue + ;; + precious_regex) + precious_files_regex="$arg" + prev= + continue + ;; + release) + release="-$arg" + prev= + continue + ;; + objectlist) + if test -f "$arg"; then + save_arg=$arg + moreargs= + for fil in `cat $save_arg` + do +# moreargs="$moreargs $fil" + arg=$fil + # A libtool-controlled object. + + # Check to see that this really is a libtool object. + if (${SED} -e '2q' $arg | grep "^# Generated by .*$PACKAGE") >/dev/null 2>&1; then + pic_object= + non_pic_object= + + # Read the .lo file + # If there is no directory component, then add one. + case $arg in + */* | *\\*) . $arg ;; + *) . ./$arg ;; + esac + + if test -z "$pic_object" || \ + test -z "$non_pic_object" || + test "$pic_object" = none && \ + test "$non_pic_object" = none; then + $echo "$modename: cannot find name of object for \`$arg'" 1>&2 + exit $EXIT_FAILURE + fi + + # Extract subdirectory from the argument. + xdir=`$echo "X$arg" | $Xsed -e 's%/[^/]*$%%'` + if test "X$xdir" = "X$arg"; then + xdir= + else + xdir="$xdir/" + fi + + if test "$pic_object" != none; then + # Prepend the subdirectory the object is found in. + pic_object="$xdir$pic_object" + + if test "$prev" = dlfiles; then + if test "$build_libtool_libs" = yes && test "$dlopen_support" = yes; then + dlfiles="$dlfiles $pic_object" + prev= + continue + else + # If libtool objects are unsupported, then we need to preload. + prev=dlprefiles + fi + fi + + # CHECK ME: I think I busted this. -Ossama + if test "$prev" = dlprefiles; then + # Preload the old-style object. + dlprefiles="$dlprefiles $pic_object" + prev= + fi + + # A PIC object. + libobjs="$libobjs $pic_object" + arg="$pic_object" + fi + + # Non-PIC object. + if test "$non_pic_object" != none; then + # Prepend the subdirectory the object is found in. + non_pic_object="$xdir$non_pic_object" + + # A standard non-PIC object + non_pic_objects="$non_pic_objects $non_pic_object" + if test -z "$pic_object" || test "$pic_object" = none ; then + arg="$non_pic_object" + fi + else + # If the PIC object exists, use it instead. + # $xdir was prepended to $pic_object above. + non_pic_object="$pic_object" + non_pic_objects="$non_pic_objects $non_pic_object" + fi + else + # Only an error if not doing a dry-run. + if test -z "$run"; then + $echo "$modename: \`$arg' is not a valid libtool object" 1>&2 + exit $EXIT_FAILURE + else + # Dry-run case. + + # Extract subdirectory from the argument. + xdir=`$echo "X$arg" | $Xsed -e 's%/[^/]*$%%'` + if test "X$xdir" = "X$arg"; then + xdir= + else + xdir="$xdir/" + fi + + pic_object=`$echo "X${xdir}${objdir}/${arg}" | $Xsed -e "$lo2o"` + non_pic_object=`$echo "X${xdir}${arg}" | $Xsed -e "$lo2o"` + libobjs="$libobjs $pic_object" + non_pic_objects="$non_pic_objects $non_pic_object" + fi + fi + done + else + $echo "$modename: link input file \`$save_arg' does not exist" + exit $EXIT_FAILURE + fi + arg=$save_arg + prev= + continue + ;; + rpath | xrpath) + # We need an absolute path. + case $arg in + [\\/]* | [A-Za-z]:[\\/]*) ;; + *) + $echo "$modename: only absolute run-paths are allowed" 1>&2 + exit $EXIT_FAILURE + ;; + esac + if test "$prev" = rpath; then + case "$rpath " in + *" $arg "*) ;; + *) rpath="$rpath $arg" ;; + esac + else + case "$xrpath " in + *" $arg "*) ;; + *) xrpath="$xrpath $arg" ;; + esac + fi + prev= + continue + ;; + xcompiler) + compiler_flags="$compiler_flags $qarg" + prev= + compile_command="$compile_command $qarg" + finalize_command="$finalize_command $qarg" + continue + ;; + xlinker) + linker_flags="$linker_flags $qarg" + compiler_flags="$compiler_flags $wl$qarg" + prev= + compile_command="$compile_command $wl$qarg" + finalize_command="$finalize_command $wl$qarg" + continue + ;; + xcclinker) + linker_flags="$linker_flags $qarg" + compiler_flags="$compiler_flags $qarg" + prev= + compile_command="$compile_command $qarg" + finalize_command="$finalize_command $qarg" + continue + ;; + shrext) + shrext_cmds="$arg" + prev= + continue + ;; + darwin_framework|darwin_framework_skip) + test "$prev" = "darwin_framework" && compiler_flags="$compiler_flags $arg" + compile_command="$compile_command $arg" + finalize_command="$finalize_command $arg" + prev= + continue + ;; + *) + eval "$prev=\"\$arg\"" + prev= + continue + ;; + esac + fi # test -n "$prev" + + prevarg="$arg" + + case $arg in + -all-static) + if test -n "$link_static_flag"; then + compile_command="$compile_command $link_static_flag" + finalize_command="$finalize_command $link_static_flag" + fi + continue + ;; + + -allow-undefined) + # FIXME: remove this flag sometime in the future. + $echo "$modename: \`-allow-undefined' is deprecated because it is the default" 1>&2 + continue + ;; + + -avoid-version) + avoid_version=yes + continue + ;; + + -dlopen) + prev=dlfiles + continue + ;; + + -dlpreopen) + prev=dlprefiles + continue + ;; + + -export-dynamic) + export_dynamic=yes + continue + ;; + + -export-symbols | -export-symbols-regex) + if test -n "$export_symbols" || test -n "$export_symbols_regex"; then + $echo "$modename: more than one -exported-symbols argument is not allowed" + exit $EXIT_FAILURE + fi + if test "X$arg" = "X-export-symbols"; then + prev=expsyms + else + prev=expsyms_regex + fi + continue + ;; + + -framework|-arch|-isysroot) + case " $CC " in + *" ${arg} ${1} "* | *" ${arg} ${1} "*) + prev=darwin_framework_skip ;; + *) compiler_flags="$compiler_flags $arg" + prev=darwin_framework ;; + esac + compile_command="$compile_command $arg" + finalize_command="$finalize_command $arg" + continue + ;; + + -inst-prefix-dir) + prev=inst_prefix + continue + ;; + + # The native IRIX linker understands -LANG:*, -LIST:* and -LNO:* + # so, if we see these flags be careful not to treat them like -L + -L[A-Z][A-Z]*:*) + case $with_gcc/$host in + no/*-*-irix* | /*-*-irix*) + compile_command="$compile_command $arg" + finalize_command="$finalize_command $arg" + ;; + esac + continue + ;; + + -L*) + dir=`$echo "X$arg" | $Xsed -e 's/^-L//'` + # We need an absolute path. + case $dir in + [\\/]* | [A-Za-z]:[\\/]*) ;; + *) + absdir=`cd "$dir" && pwd` + if test -z "$absdir"; then + $echo "$modename: cannot determine absolute directory name of \`$dir'" 1>&2 + absdir="$dir" + notinst_path="$notinst_path $dir" + fi + dir="$absdir" + ;; + esac + case "$deplibs " in + *" -L$dir "*) ;; + *) + deplibs="$deplibs -L$dir" + lib_search_path="$lib_search_path $dir" + ;; + esac + case $host in + *-*-cygwin* | *-*-mingw* | *-*-pw32* | *-*-os2*) + testbindir=`$echo "X$dir" | $Xsed -e 's*/lib$*/bin*'` + case :$dllsearchpath: in + *":$dir:"*) ;; + *) dllsearchpath="$dllsearchpath:$dir";; + esac + case :$dllsearchpath: in + *":$testbindir:"*) ;; + *) dllsearchpath="$dllsearchpath:$testbindir";; + esac + ;; + esac + continue + ;; + + -l*) + if test "X$arg" = "X-lc" || test "X$arg" = "X-lm"; then + case $host in + *-*-cygwin* | *-*-mingw* | *-*-pw32* | *-*-beos*) + # These systems don't actually have a C or math library (as such) + continue + ;; + *-*-os2*) + # These systems don't actually have a C library (as such) + test "X$arg" = "X-lc" && continue + ;; + *-*-openbsd* | *-*-freebsd* | *-*-dragonfly*) + # Do not include libc due to us having libc/libc_r. + test "X$arg" = "X-lc" && continue + ;; + *-*-rhapsody* | *-*-darwin1.[012]) + # Rhapsody C and math libraries are in the System framework + deplibs="$deplibs -framework System" + continue + ;; + *-*-sco3.2v5* | *-*-sco5v6*) + # Causes problems with __ctype + test "X$arg" = "X-lc" && continue + ;; + *-*-sysv4.2uw2* | *-*-sysv5* | *-*-unixware* | *-*-OpenUNIX*) + # Compiler inserts libc in the correct place for threads to work + test "X$arg" = "X-lc" && continue + ;; + esac + elif test "X$arg" = "X-lc_r"; then + case $host in + *-*-openbsd* | *-*-freebsd* | *-*-dragonfly*) + # Do not include libc_r directly, use -pthread flag. + continue + ;; + esac + fi + deplibs="$deplibs $arg" + continue + ;; + + # Tru64 UNIX uses -model [arg] to determine the layout of C++ + # classes, name mangling, and exception handling. + -model) + compile_command="$compile_command $arg" + compiler_flags="$compiler_flags $arg" + finalize_command="$finalize_command $arg" + prev=xcompiler + continue + ;; + + -mt|-mthreads|-kthread|-Kthread|-pthread|-pthreads|--thread-safe) + compiler_flags="$compiler_flags $arg" + compile_command="$compile_command $arg" + finalize_command="$finalize_command $arg" + continue + ;; + + -module) + module=yes + continue + ;; + + # -64, -mips[0-9] enable 64-bit mode on the SGI compiler + # -r[0-9][0-9]* specifies the processor on the SGI compiler + # -xarch=*, -xtarget=* enable 64-bit mode on the Sun compiler + # +DA*, +DD* enable 64-bit mode on the HP compiler + # -q* pass through compiler args for the IBM compiler + # -m* pass through architecture-specific compiler args for GCC + # -m*, -t[45]*, -txscale* pass through architecture-specific + # compiler args for GCC + # -pg pass through profiling flag for GCC + # @file GCC response files + -64|-mips[0-9]|-r[0-9][0-9]*|-xarch=*|-xtarget=*|+DA*|+DD*|-q*|-m*|-pg| \ + -t[45]*|-txscale*|@*) + + # Unknown arguments in both finalize_command and compile_command need + # to be aesthetically quoted because they are evaled later. + arg=`$echo "X$arg" | $Xsed -e "$sed_quote_subst"` + case $arg in + *[\[\~\#\^\&\*\(\)\{\}\|\;\<\>\?\'\ \ ]*|*]*|"") + arg="\"$arg\"" + ;; + esac + compile_command="$compile_command $arg" + finalize_command="$finalize_command $arg" + compiler_flags="$compiler_flags $arg" + continue + ;; + + -shrext) + prev=shrext + continue + ;; + + -no-fast-install) + fast_install=no + continue + ;; + + -no-install) + case $host in + *-*-cygwin* | *-*-mingw* | *-*-pw32* | *-*-os2*) + # The PATH hackery in wrapper scripts is required on Windows + # in order for the loader to find any dlls it needs. + $echo "$modename: warning: \`-no-install' is ignored for $host" 1>&2 + $echo "$modename: warning: assuming \`-no-fast-install' instead" 1>&2 + fast_install=no + ;; + *) no_install=yes ;; + esac + continue + ;; + + -no-undefined) + allow_undefined=no + continue + ;; + + -objectlist) + prev=objectlist + continue + ;; + + -o) prev=output ;; + + -precious-files-regex) + prev=precious_regex + continue + ;; + + -release) + prev=release + continue + ;; + + -rpath) + prev=rpath + continue + ;; + + -R) + prev=xrpath + continue + ;; + + -R*) + dir=`$echo "X$arg" | $Xsed -e 's/^-R//'` + # We need an absolute path. + case $dir in + [\\/]* | [A-Za-z]:[\\/]*) ;; + *) + $echo "$modename: only absolute run-paths are allowed" 1>&2 + exit $EXIT_FAILURE + ;; + esac + case "$xrpath " in + *" $dir "*) ;; + *) xrpath="$xrpath $dir" ;; + esac + continue + ;; + + -static | -static-libtool-libs) + # The effects of -static are defined in a previous loop. + # We used to do the same as -all-static on platforms that + # didn't have a PIC flag, but the assumption that the effects + # would be equivalent was wrong. It would break on at least + # Digital Unix and AIX. + continue + ;; + + -thread-safe) + thread_safe=yes + continue + ;; + + -version-info) + prev=vinfo + continue + ;; + -version-number) + prev=vinfo + vinfo_number=yes + continue + ;; + + -Wc,*) + args=`$echo "X$arg" | $Xsed -e "$sed_quote_subst" -e 's/^-Wc,//'` + arg= + save_ifs="$IFS"; IFS=',' + for flag in $args; do + IFS="$save_ifs" + case $flag in + *[\[\~\#\^\&\*\(\)\{\}\|\;\<\>\?\'\ \ ]*|*]*|"") + flag="\"$flag\"" + ;; + esac + arg="$arg $wl$flag" + compiler_flags="$compiler_flags $flag" + done + IFS="$save_ifs" + arg=`$echo "X$arg" | $Xsed -e "s/^ //"` + ;; + + -Wl,*) + args=`$echo "X$arg" | $Xsed -e "$sed_quote_subst" -e 's/^-Wl,//'` + arg= + save_ifs="$IFS"; IFS=',' + for flag in $args; do + IFS="$save_ifs" + case $flag in + *[\[\~\#\^\&\*\(\)\{\}\|\;\<\>\?\'\ \ ]*|*]*|"") + flag="\"$flag\"" + ;; + esac + arg="$arg $wl$flag" + compiler_flags="$compiler_flags $wl$flag" + linker_flags="$linker_flags $flag" + done + IFS="$save_ifs" + arg=`$echo "X$arg" | $Xsed -e "s/^ //"` + ;; + + -Xcompiler) + prev=xcompiler + continue + ;; + + -Xlinker) + prev=xlinker + continue + ;; + + -XCClinker) + prev=xcclinker + continue + ;; + + # Some other compiler flag. + -* | +*) + # Unknown arguments in both finalize_command and compile_command need + # to be aesthetically quoted because they are evaled later. + arg=`$echo "X$arg" | $Xsed -e "$sed_quote_subst"` + case $arg in + *[\[\~\#\^\&\*\(\)\{\}\|\;\<\>\?\'\ \ ]*|*]*|"") + arg="\"$arg\"" + ;; + esac + ;; + + *.$objext) + # A standard object. + objs="$objs $arg" + ;; + + *.lo) + # A libtool-controlled object. + + # Check to see that this really is a libtool object. + if (${SED} -e '2q' $arg | grep "^# Generated by .*$PACKAGE") >/dev/null 2>&1; then + pic_object= + non_pic_object= + + # Read the .lo file + # If there is no directory component, then add one. + case $arg in + */* | *\\*) . $arg ;; + *) . ./$arg ;; + esac + + if test -z "$pic_object" || \ + test -z "$non_pic_object" || + test "$pic_object" = none && \ + test "$non_pic_object" = none; then + $echo "$modename: cannot find name of object for \`$arg'" 1>&2 + exit $EXIT_FAILURE + fi + + # Extract subdirectory from the argument. + xdir=`$echo "X$arg" | $Xsed -e 's%/[^/]*$%%'` + if test "X$xdir" = "X$arg"; then + xdir= + else + xdir="$xdir/" + fi + + if test "$pic_object" != none; then + # Prepend the subdirectory the object is found in. + pic_object="$xdir$pic_object" + + if test "$prev" = dlfiles; then + if test "$build_libtool_libs" = yes && test "$dlopen_support" = yes; then + dlfiles="$dlfiles $pic_object" + prev= + continue + else + # If libtool objects are unsupported, then we need to preload. + prev=dlprefiles + fi + fi + + # CHECK ME: I think I busted this. -Ossama + if test "$prev" = dlprefiles; then + # Preload the old-style object. + dlprefiles="$dlprefiles $pic_object" + prev= + fi + + # A PIC object. + libobjs="$libobjs $pic_object" + arg="$pic_object" + fi + + # Non-PIC object. + if test "$non_pic_object" != none; then + # Prepend the subdirectory the object is found in. + non_pic_object="$xdir$non_pic_object" + + # A standard non-PIC object + non_pic_objects="$non_pic_objects $non_pic_object" + if test -z "$pic_object" || test "$pic_object" = none ; then + arg="$non_pic_object" + fi + else + # If the PIC object exists, use it instead. + # $xdir was prepended to $pic_object above. + non_pic_object="$pic_object" + non_pic_objects="$non_pic_objects $non_pic_object" + fi + else + # Only an error if not doing a dry-run. + if test -z "$run"; then + $echo "$modename: \`$arg' is not a valid libtool object" 1>&2 + exit $EXIT_FAILURE + else + # Dry-run case. + + # Extract subdirectory from the argument. + xdir=`$echo "X$arg" | $Xsed -e 's%/[^/]*$%%'` + if test "X$xdir" = "X$arg"; then + xdir= + else + xdir="$xdir/" + fi + + pic_object=`$echo "X${xdir}${objdir}/${arg}" | $Xsed -e "$lo2o"` + non_pic_object=`$echo "X${xdir}${arg}" | $Xsed -e "$lo2o"` + libobjs="$libobjs $pic_object" + non_pic_objects="$non_pic_objects $non_pic_object" + fi + fi + ;; + + *.$libext) + # An archive. + deplibs="$deplibs $arg" + old_deplibs="$old_deplibs $arg" + continue + ;; + + *.la) + # A libtool-controlled library. + + if test "$prev" = dlfiles; then + # This library was specified with -dlopen. + dlfiles="$dlfiles $arg" + prev= + elif test "$prev" = dlprefiles; then + # The library was specified with -dlpreopen. + dlprefiles="$dlprefiles $arg" + prev= + else + deplibs="$deplibs $arg" + fi + continue + ;; + + # Some other compiler argument. + *) + # Unknown arguments in both finalize_command and compile_command need + # to be aesthetically quoted because they are evaled later. + arg=`$echo "X$arg" | $Xsed -e "$sed_quote_subst"` + case $arg in + *[\[\~\#\^\&\*\(\)\{\}\|\;\<\>\?\'\ \ ]*|*]*|"") + arg="\"$arg\"" + ;; + esac + ;; + esac # arg + + # Now actually substitute the argument into the commands. + if test -n "$arg"; then + compile_command="$compile_command $arg" + finalize_command="$finalize_command $arg" + fi + done # argument parsing loop + + if test -n "$prev"; then + $echo "$modename: the \`$prevarg' option requires an argument" 1>&2 + $echo "$help" 1>&2 + exit $EXIT_FAILURE + fi + + if test "$export_dynamic" = yes && test -n "$export_dynamic_flag_spec"; then + eval arg=\"$export_dynamic_flag_spec\" + compile_command="$compile_command $arg" + finalize_command="$finalize_command $arg" + fi + + oldlibs= + # calculate the name of the file, without its directory + outputname=`$echo "X$output" | $Xsed -e 's%^.*/%%'` + libobjs_save="$libobjs" + + if test -n "$shlibpath_var"; then + # get the directories listed in $shlibpath_var + eval shlib_search_path=\`\$echo \"X\${$shlibpath_var}\" \| \$Xsed -e \'s/:/ /g\'\` + else + shlib_search_path= + fi + eval sys_lib_search_path=\"$sys_lib_search_path_spec\" + eval sys_lib_dlsearch_path=\"$sys_lib_dlsearch_path_spec\" + + output_objdir=`$echo "X$output" | $Xsed -e 's%/[^/]*$%%'` + if test "X$output_objdir" = "X$output"; then + output_objdir="$objdir" + else + output_objdir="$output_objdir/$objdir" + fi + # Create the object directory. + if test ! -d "$output_objdir"; then + $show "$mkdir $output_objdir" + $run $mkdir $output_objdir + exit_status=$? + if test "$exit_status" -ne 0 && test ! -d "$output_objdir"; then + exit $exit_status + fi + fi + + # Determine the type of output + case $output in + "") + $echo "$modename: you must specify an output file" 1>&2 + $echo "$help" 1>&2 + exit $EXIT_FAILURE + ;; + *.$libext) linkmode=oldlib ;; + *.lo | *.$objext) linkmode=obj ;; + *.la) linkmode=lib ;; + *) linkmode=prog ;; # Anything else should be a program. + esac + + case $host in + *cygwin* | *mingw* | *pw32*) + # don't eliminate duplications in $postdeps and $predeps + duplicate_compiler_generated_deps=yes + ;; + *) + duplicate_compiler_generated_deps=$duplicate_deps + ;; + esac + specialdeplibs= + + libs= + # Find all interdependent deplibs by searching for libraries + # that are linked more than once (e.g. -la -lb -la) + for deplib in $deplibs; do + if test "X$duplicate_deps" = "Xyes" ; then + case "$libs " in + *" $deplib "*) specialdeplibs="$specialdeplibs $deplib" ;; + esac + fi + libs="$libs $deplib" + done + + if test "$linkmode" = lib; then + libs="$predeps $libs $compiler_lib_search_path $postdeps" + + # Compute libraries that are listed more than once in $predeps + # $postdeps and mark them as special (i.e., whose duplicates are + # not to be eliminated). + pre_post_deps= + if test "X$duplicate_compiler_generated_deps" = "Xyes" ; then + for pre_post_dep in $predeps $postdeps; do + case "$pre_post_deps " in + *" $pre_post_dep "*) specialdeplibs="$specialdeplibs $pre_post_deps" ;; + esac + pre_post_deps="$pre_post_deps $pre_post_dep" + done + fi + pre_post_deps= + fi + + deplibs= + newdependency_libs= + newlib_search_path= + need_relink=no # whether we're linking any uninstalled libtool libraries + notinst_deplibs= # not-installed libtool libraries + case $linkmode in + lib) + passes="conv link" + for file in $dlfiles $dlprefiles; do + case $file in + *.la) ;; + *) + $echo "$modename: libraries can \`-dlopen' only libtool libraries: $file" 1>&2 + exit $EXIT_FAILURE + ;; + esac + done + ;; + prog) + compile_deplibs= + finalize_deplibs= + alldeplibs=no + newdlfiles= + newdlprefiles= + passes="conv scan dlopen dlpreopen link" + ;; + *) passes="conv" + ;; + esac + for pass in $passes; do + if test "$linkmode,$pass" = "lib,link" || + test "$linkmode,$pass" = "prog,scan"; then + libs="$deplibs" + deplibs= + fi + if test "$linkmode" = prog; then + case $pass in + dlopen) libs="$dlfiles" ;; + dlpreopen) libs="$dlprefiles" ;; + link) libs="$deplibs %DEPLIBS% $dependency_libs" ;; + esac + fi + if test "$pass" = dlopen; then + # Collect dlpreopened libraries + save_deplibs="$deplibs" + deplibs= + fi + for deplib in $libs; do + lib= + found=no + case $deplib in + -mt|-mthreads|-kthread|-Kthread|-pthread|-pthreads|--thread-safe) + if test "$linkmode,$pass" = "prog,link"; then + compile_deplibs="$deplib $compile_deplibs" + finalize_deplibs="$deplib $finalize_deplibs" + else + compiler_flags="$compiler_flags $deplib" + fi + continue + ;; + -l*) + if test "$linkmode" != lib && test "$linkmode" != prog; then + $echo "$modename: warning: \`-l' is ignored for archives/objects" 1>&2 + continue + fi + name=`$echo "X$deplib" | $Xsed -e 's/^-l//'` + for searchdir in $newlib_search_path $lib_search_path $sys_lib_search_path $shlib_search_path; do + for search_ext in .la $std_shrext .so .a; do + # Search the libtool library + lib="$searchdir/lib${name}${search_ext}" + if test -f "$lib"; then + if test "$search_ext" = ".la"; then + found=yes + else + found=no + fi + break 2 + fi + done + done + if test "$found" != yes; then + # deplib doesn't seem to be a libtool library + if test "$linkmode,$pass" = "prog,link"; then + compile_deplibs="$deplib $compile_deplibs" + finalize_deplibs="$deplib $finalize_deplibs" + else + deplibs="$deplib $deplibs" + test "$linkmode" = lib && newdependency_libs="$deplib $newdependency_libs" + fi + continue + else # deplib is a libtool library + # If $allow_libtool_libs_with_static_runtimes && $deplib is a stdlib, + # We need to do some special things here, and not later. + if test "X$allow_libtool_libs_with_static_runtimes" = "Xyes" ; then + case " $predeps $postdeps " in + *" $deplib "*) + if (${SED} -e '2q' $lib | + grep "^# Generated by .*$PACKAGE") >/dev/null 2>&1; then + library_names= + old_library= + case $lib in + */* | *\\*) . $lib ;; + *) . ./$lib ;; + esac + for l in $old_library $library_names; do + ll="$l" + done + if test "X$ll" = "X$old_library" ; then # only static version available + found=no + ladir=`$echo "X$lib" | $Xsed -e 's%/[^/]*$%%'` + test "X$ladir" = "X$lib" && ladir="." + lib=$ladir/$old_library + if test "$linkmode,$pass" = "prog,link"; then + compile_deplibs="$deplib $compile_deplibs" + finalize_deplibs="$deplib $finalize_deplibs" + else + deplibs="$deplib $deplibs" + test "$linkmode" = lib && newdependency_libs="$deplib $newdependency_libs" + fi + continue + fi + fi + ;; + *) ;; + esac + fi + fi + ;; # -l + -L*) + case $linkmode in + lib) + deplibs="$deplib $deplibs" + test "$pass" = conv && continue + newdependency_libs="$deplib $newdependency_libs" + newlib_search_path="$newlib_search_path "`$echo "X$deplib" | $Xsed -e 's/^-L//'` + ;; + prog) + if test "$pass" = conv; then + deplibs="$deplib $deplibs" + continue + fi + if test "$pass" = scan; then + deplibs="$deplib $deplibs" + else + compile_deplibs="$deplib $compile_deplibs" + finalize_deplibs="$deplib $finalize_deplibs" + fi + newlib_search_path="$newlib_search_path "`$echo "X$deplib" | $Xsed -e 's/^-L//'` + ;; + *) + $echo "$modename: warning: \`-L' is ignored for archives/objects" 1>&2 + ;; + esac # linkmode + continue + ;; # -L + -R*) + if test "$pass" = link; then + dir=`$echo "X$deplib" | $Xsed -e 's/^-R//'` + # Make sure the xrpath contains only unique directories. + case "$xrpath " in + *" $dir "*) ;; + *) xrpath="$xrpath $dir" ;; + esac + fi + deplibs="$deplib $deplibs" + continue + ;; + *.la) lib="$deplib" ;; + *.$libext) + if test "$pass" = conv; then + deplibs="$deplib $deplibs" + continue + fi + case $linkmode in + lib) + valid_a_lib=no + case $deplibs_check_method in + match_pattern*) + set dummy $deplibs_check_method + match_pattern_regex=`expr "$deplibs_check_method" : "$2 \(.*\)"` + if eval $echo \"$deplib\" 2>/dev/null \ + | $SED 10q \ + | $EGREP "$match_pattern_regex" > /dev/null; then + valid_a_lib=yes + fi + ;; + pass_all) + valid_a_lib=yes + ;; + esac + if test "$valid_a_lib" != yes; then + $echo + $echo "*** Warning: Trying to link with static lib archive $deplib." + $echo "*** I have the capability to make that library automatically link in when" + $echo "*** you link to this library. But I can only do this if you have a" + $echo "*** shared version of the library, which you do not appear to have" + $echo "*** because the file extensions .$libext of this argument makes me believe" + $echo "*** that it is just a static archive that I should not used here." + else + $echo + $echo "*** Warning: Linking the shared library $output against the" + $echo "*** static library $deplib is not portable!" + deplibs="$deplib $deplibs" + fi + continue + ;; + prog) + if test "$pass" != link; then + deplibs="$deplib $deplibs" + else + compile_deplibs="$deplib $compile_deplibs" + finalize_deplibs="$deplib $finalize_deplibs" + fi + continue + ;; + esac # linkmode + ;; # *.$libext + *.lo | *.$objext) + if test "$pass" = conv; then + deplibs="$deplib $deplibs" + elif test "$linkmode" = prog; then + if test "$pass" = dlpreopen || test "$dlopen_support" != yes || test "$build_libtool_libs" = no; then + # If there is no dlopen support or we're linking statically, + # we need to preload. + newdlprefiles="$newdlprefiles $deplib" + compile_deplibs="$deplib $compile_deplibs" + finalize_deplibs="$deplib $finalize_deplibs" + else + newdlfiles="$newdlfiles $deplib" + fi + fi + continue + ;; + %DEPLIBS%) + alldeplibs=yes + continue + ;; + esac # case $deplib + if test "$found" = yes || test -f "$lib"; then : + else + $echo "$modename: cannot find the library \`$lib' or unhandled argument \`$deplib'" 1>&2 + exit $EXIT_FAILURE + fi + + # Check to see that this really is a libtool archive. + if (${SED} -e '2q' $lib | grep "^# Generated by .*$PACKAGE") >/dev/null 2>&1; then : + else + $echo "$modename: \`$lib' is not a valid libtool archive" 1>&2 + exit $EXIT_FAILURE + fi + + ladir=`$echo "X$lib" | $Xsed -e 's%/[^/]*$%%'` + test "X$ladir" = "X$lib" && ladir="." + + dlname= + dlopen= + dlpreopen= + libdir= + library_names= + old_library= + # If the library was installed with an old release of libtool, + # it will not redefine variables installed, or shouldnotlink + installed=yes + shouldnotlink=no + avoidtemprpath= + + + # Read the .la file + case $lib in + */* | *\\*) . $lib ;; + *) . ./$lib ;; + esac + + if test "$linkmode,$pass" = "lib,link" || + test "$linkmode,$pass" = "prog,scan" || + { test "$linkmode" != prog && test "$linkmode" != lib; }; then + test -n "$dlopen" && dlfiles="$dlfiles $dlopen" + test -n "$dlpreopen" && dlprefiles="$dlprefiles $dlpreopen" + fi + + if test "$pass" = conv; then + # Only check for convenience libraries + deplibs="$lib $deplibs" + if test -z "$libdir"; then + if test -z "$old_library"; then + $echo "$modename: cannot find name of link library for \`$lib'" 1>&2 + exit $EXIT_FAILURE + fi + # It is a libtool convenience library, so add in its objects. + convenience="$convenience $ladir/$objdir/$old_library" + old_convenience="$old_convenience $ladir/$objdir/$old_library" + tmp_libs= + for deplib in $dependency_libs; do + deplibs="$deplib $deplibs" + if test "X$duplicate_deps" = "Xyes" ; then + case "$tmp_libs " in + *" $deplib "*) specialdeplibs="$specialdeplibs $deplib" ;; + esac + fi + tmp_libs="$tmp_libs $deplib" + done + elif test "$linkmode" != prog && test "$linkmode" != lib; then + $echo "$modename: \`$lib' is not a convenience library" 1>&2 + exit $EXIT_FAILURE + fi + continue + fi # $pass = conv + + + # Get the name of the library we link against. + linklib= + for l in $old_library $library_names; do + linklib="$l" + done + if test -z "$linklib"; then + $echo "$modename: cannot find name of link library for \`$lib'" 1>&2 + exit $EXIT_FAILURE + fi + + # This library was specified with -dlopen. + if test "$pass" = dlopen; then + if test -z "$libdir"; then + $echo "$modename: cannot -dlopen a convenience library: \`$lib'" 1>&2 + exit $EXIT_FAILURE + fi + if test -z "$dlname" || + test "$dlopen_support" != yes || + test "$build_libtool_libs" = no; then + # If there is no dlname, no dlopen support or we're linking + # statically, we need to preload. We also need to preload any + # dependent libraries so libltdl's deplib preloader doesn't + # bomb out in the load deplibs phase. + dlprefiles="$dlprefiles $lib $dependency_libs" + else + newdlfiles="$newdlfiles $lib" + fi + continue + fi # $pass = dlopen + + # We need an absolute path. + case $ladir in + [\\/]* | [A-Za-z]:[\\/]*) abs_ladir="$ladir" ;; + *) + abs_ladir=`cd "$ladir" && pwd` + if test -z "$abs_ladir"; then + $echo "$modename: warning: cannot determine absolute directory name of \`$ladir'" 1>&2 + $echo "$modename: passing it literally to the linker, although it might fail" 1>&2 + abs_ladir="$ladir" + fi + ;; + esac + laname=`$echo "X$lib" | $Xsed -e 's%^.*/%%'` + + # Find the relevant object directory and library name. + if test "X$installed" = Xyes; then + if test ! -f "$libdir/$linklib" && test -f "$abs_ladir/$linklib"; then + $echo "$modename: warning: library \`$lib' was moved." 1>&2 + dir="$ladir" + absdir="$abs_ladir" + libdir="$abs_ladir" + else + dir="$libdir" + absdir="$libdir" + fi + test "X$hardcode_automatic" = Xyes && avoidtemprpath=yes + else + if test ! -f "$ladir/$objdir/$linklib" && test -f "$abs_ladir/$linklib"; then + dir="$ladir" + absdir="$abs_ladir" + # Remove this search path later + notinst_path="$notinst_path $abs_ladir" + else + dir="$ladir/$objdir" + absdir="$abs_ladir/$objdir" + # Remove this search path later + notinst_path="$notinst_path $abs_ladir" + fi + fi # $installed = yes + name=`$echo "X$laname" | $Xsed -e 's/\.la$//' -e 's/^lib//'` + + # This library was specified with -dlpreopen. + if test "$pass" = dlpreopen; then + if test -z "$libdir"; then + $echo "$modename: cannot -dlpreopen a convenience library: \`$lib'" 1>&2 + exit $EXIT_FAILURE + fi + # Prefer using a static library (so that no silly _DYNAMIC symbols + # are required to link). + if test -n "$old_library"; then + newdlprefiles="$newdlprefiles $dir/$old_library" + # Otherwise, use the dlname, so that lt_dlopen finds it. + elif test -n "$dlname"; then + newdlprefiles="$newdlprefiles $dir/$dlname" + else + newdlprefiles="$newdlprefiles $dir/$linklib" + fi + fi # $pass = dlpreopen + + if test -z "$libdir"; then + # Link the convenience library + if test "$linkmode" = lib; then + deplibs="$dir/$old_library $deplibs" + elif test "$linkmode,$pass" = "prog,link"; then + compile_deplibs="$dir/$old_library $compile_deplibs" + finalize_deplibs="$dir/$old_library $finalize_deplibs" + else + deplibs="$lib $deplibs" # used for prog,scan pass + fi + continue + fi + + + if test "$linkmode" = prog && test "$pass" != link; then + newlib_search_path="$newlib_search_path $ladir" + deplibs="$lib $deplibs" + + linkalldeplibs=no + if test "$link_all_deplibs" != no || test -z "$library_names" || + test "$build_libtool_libs" = no; then + linkalldeplibs=yes + fi + + tmp_libs= + for deplib in $dependency_libs; do + case $deplib in + -L*) newlib_search_path="$newlib_search_path "`$echo "X$deplib" | $Xsed -e 's/^-L//'`;; ### testsuite: skip nested quoting test + esac + # Need to link against all dependency_libs? + if test "$linkalldeplibs" = yes; then + deplibs="$deplib $deplibs" + else + # Need to hardcode shared library paths + # or/and link against static libraries + newdependency_libs="$deplib $newdependency_libs" + fi + if test "X$duplicate_deps" = "Xyes" ; then + case "$tmp_libs " in + *" $deplib "*) specialdeplibs="$specialdeplibs $deplib" ;; + esac + fi + tmp_libs="$tmp_libs $deplib" + done # for deplib + continue + fi # $linkmode = prog... + + if test "$linkmode,$pass" = "prog,link"; then + if test -n "$library_names" && + { { test "$prefer_static_libs" = no || + test "$prefer_static_libs,$installed" = "built,yes"; } || + test -z "$old_library"; }; then + # We need to hardcode the library path + if test -n "$shlibpath_var" && test -z "$avoidtemprpath" ; then + # Make sure the rpath contains only unique directories. + case "$temp_rpath " in + *" $dir "*) ;; + *" $absdir "*) ;; + *) temp_rpath="$temp_rpath $absdir" ;; + esac + fi + + # Hardcode the library path. + # Skip directories that are in the system default run-time + # search path. + case " $sys_lib_dlsearch_path " in + *" $absdir "*) ;; + *) + case "$compile_rpath " in + *" $absdir "*) ;; + *) compile_rpath="$compile_rpath $absdir" + esac + ;; + esac + case " $sys_lib_dlsearch_path " in + *" $libdir "*) ;; + *) + case "$finalize_rpath " in + *" $libdir "*) ;; + *) finalize_rpath="$finalize_rpath $libdir" + esac + ;; + esac + fi # $linkmode,$pass = prog,link... + + if test "$alldeplibs" = yes && + { test "$deplibs_check_method" = pass_all || + { test "$build_libtool_libs" = yes && + test -n "$library_names"; }; }; then + # We only need to search for static libraries + continue + fi + fi + + link_static=no # Whether the deplib will be linked statically + use_static_libs=$prefer_static_libs + if test "$use_static_libs" = built && test "$installed" = yes ; then + use_static_libs=no + fi + if test -n "$library_names" && + { test "$use_static_libs" = no || test -z "$old_library"; }; then + if test "$installed" = no; then + notinst_deplibs="$notinst_deplibs $lib" + need_relink=yes + fi + # This is a shared library + + # Warn about portability, can't link against -module's on + # some systems (darwin) + if test "$shouldnotlink" = yes && test "$pass" = link ; then + $echo + if test "$linkmode" = prog; then + $echo "*** Warning: Linking the executable $output against the loadable module" + else + $echo "*** Warning: Linking the shared library $output against the loadable module" + fi + $echo "*** $linklib is not portable!" + fi + if test "$linkmode" = lib && + test "$hardcode_into_libs" = yes; then + # Hardcode the library path. + # Skip directories that are in the system default run-time + # search path. + case " $sys_lib_dlsearch_path " in + *" $absdir "*) ;; + *) + case "$compile_rpath " in + *" $absdir "*) ;; + *) compile_rpath="$compile_rpath $absdir" + esac + ;; + esac + case " $sys_lib_dlsearch_path " in + *" $libdir "*) ;; + *) + case "$finalize_rpath " in + *" $libdir "*) ;; + *) finalize_rpath="$finalize_rpath $libdir" + esac + ;; + esac + fi + + if test -n "$old_archive_from_expsyms_cmds"; then + # figure out the soname + set dummy $library_names + realname="$2" + shift; shift + libname=`eval \\$echo \"$libname_spec\"` + # use dlname if we got it. it's perfectly good, no? + if test -n "$dlname"; then + soname="$dlname" + elif test -n "$soname_spec"; then + # bleh windows + case $host in + *cygwin* | mingw*) + major=`expr $current - $age` + versuffix="-$major" + ;; + esac + eval soname=\"$soname_spec\" + else + soname="$realname" + fi + + # Make a new name for the extract_expsyms_cmds to use + soroot="$soname" + soname=`$echo $soroot | ${SED} -e 's/^.*\///'` + newlib="libimp-`$echo $soname | ${SED} 's/^lib//;s/\.dll$//'`.a" + + # If the library has no export list, then create one now + if test -f "$output_objdir/$soname-def"; then : + else + $show "extracting exported symbol list from \`$soname'" + save_ifs="$IFS"; IFS='~' + cmds=$extract_expsyms_cmds + for cmd in $cmds; do + IFS="$save_ifs" + eval cmd=\"$cmd\" + $show "$cmd" + $run eval "$cmd" || exit $? + done + IFS="$save_ifs" + fi + + # Create $newlib + if test -f "$output_objdir/$newlib"; then :; else + $show "generating import library for \`$soname'" + save_ifs="$IFS"; IFS='~' + cmds=$old_archive_from_expsyms_cmds + for cmd in $cmds; do + IFS="$save_ifs" + eval cmd=\"$cmd\" + $show "$cmd" + $run eval "$cmd" || exit $? + done + IFS="$save_ifs" + fi + # make sure the library variables are pointing to the new library + dir=$output_objdir + linklib=$newlib + fi # test -n "$old_archive_from_expsyms_cmds" + + if test "$linkmode" = prog || test "$mode" != relink; then + add_shlibpath= + add_dir= + add= + lib_linked=yes + case $hardcode_action in + immediate | unsupported) + if test "$hardcode_direct" = no; then + add="$dir/$linklib" + case $host in + *-*-sco3.2v5.0.[024]*) add_dir="-L$dir" ;; + *-*-sysv4*uw2*) add_dir="-L$dir" ;; + *-*-sysv5OpenUNIX* | *-*-sysv5UnixWare7.[01].[10]* | \ + *-*-unixware7*) add_dir="-L$dir" ;; + *-*-darwin* ) + # if the lib is a module then we can not link against + # it, someone is ignoring the new warnings I added + if /usr/bin/file -L $add 2> /dev/null | + $EGREP ": [^:]* bundle" >/dev/null ; then + $echo "** Warning, lib $linklib is a module, not a shared library" + if test -z "$old_library" ; then + $echo + $echo "** And there doesn't seem to be a static archive available" + $echo "** The link will probably fail, sorry" + else + add="$dir/$old_library" + fi + fi + esac + elif test "$hardcode_minus_L" = no; then + case $host in + *-*-sunos*) add_shlibpath="$dir" ;; + esac + add_dir="-L$dir" + add="-l$name" + elif test "$hardcode_shlibpath_var" = no; then + add_shlibpath="$dir" + add="-l$name" + else + lib_linked=no + fi + ;; + relink) + if test "$hardcode_direct" = yes; then + add="$dir/$linklib" + elif test "$hardcode_minus_L" = yes; then + add_dir="-L$dir" + # Try looking first in the location we're being installed to. + if test -n "$inst_prefix_dir"; then + case $libdir in + [\\/]*) + add_dir="$add_dir -L$inst_prefix_dir$libdir" + ;; + esac + fi + add="-l$name" + elif test "$hardcode_shlibpath_var" = yes; then + add_shlibpath="$dir" + add="-l$name" + else + lib_linked=no + fi + ;; + *) lib_linked=no ;; + esac + + if test "$lib_linked" != yes; then + $echo "$modename: configuration error: unsupported hardcode properties" + exit $EXIT_FAILURE + fi + + if test -n "$add_shlibpath"; then + case :$compile_shlibpath: in + *":$add_shlibpath:"*) ;; + *) compile_shlibpath="$compile_shlibpath$add_shlibpath:" ;; + esac + fi + if test "$linkmode" = prog; then + test -n "$add_dir" && compile_deplibs="$add_dir $compile_deplibs" + test -n "$add" && compile_deplibs="$add $compile_deplibs" + else + test -n "$add_dir" && deplibs="$add_dir $deplibs" + test -n "$add" && deplibs="$add $deplibs" + if test "$hardcode_direct" != yes && \ + test "$hardcode_minus_L" != yes && \ + test "$hardcode_shlibpath_var" = yes; then + case :$finalize_shlibpath: in + *":$libdir:"*) ;; + *) finalize_shlibpath="$finalize_shlibpath$libdir:" ;; + esac + fi + fi + fi + + if test "$linkmode" = prog || test "$mode" = relink; then + add_shlibpath= + add_dir= + add= + # Finalize command for both is simple: just hardcode it. + if test "$hardcode_direct" = yes; then + add="$libdir/$linklib" + elif test "$hardcode_minus_L" = yes; then + add_dir="-L$libdir" + add="-l$name" + elif test "$hardcode_shlibpath_var" = yes; then + case :$finalize_shlibpath: in + *":$libdir:"*) ;; + *) finalize_shlibpath="$finalize_shlibpath$libdir:" ;; + esac + add="-l$name" + elif test "$hardcode_automatic" = yes; then + if test -n "$inst_prefix_dir" && + test -f "$inst_prefix_dir$libdir/$linklib" ; then + add="$inst_prefix_dir$libdir/$linklib" + else + add="$libdir/$linklib" + fi + else + # We cannot seem to hardcode it, guess we'll fake it. + add_dir="-L$libdir" + # Try looking first in the location we're being installed to. + if test -n "$inst_prefix_dir"; then + case $libdir in + [\\/]*) + add_dir="$add_dir -L$inst_prefix_dir$libdir" + ;; + esac + fi + add="-l$name" + fi + + if test "$linkmode" = prog; then + test -n "$add_dir" && finalize_deplibs="$add_dir $finalize_deplibs" + test -n "$add" && finalize_deplibs="$add $finalize_deplibs" + else + test -n "$add_dir" && deplibs="$add_dir $deplibs" + test -n "$add" && deplibs="$add $deplibs" + fi + fi + elif test "$linkmode" = prog; then + # Here we assume that one of hardcode_direct or hardcode_minus_L + # is not unsupported. This is valid on all known static and + # shared platforms. + if test "$hardcode_direct" != unsupported; then + test -n "$old_library" && linklib="$old_library" + compile_deplibs="$dir/$linklib $compile_deplibs" + finalize_deplibs="$dir/$linklib $finalize_deplibs" + else + compile_deplibs="-l$name -L$dir $compile_deplibs" + finalize_deplibs="-l$name -L$dir $finalize_deplibs" + fi + elif test "$build_libtool_libs" = yes; then + # Not a shared library + if test "$deplibs_check_method" != pass_all; then + # We're trying link a shared library against a static one + # but the system doesn't support it. + + # Just print a warning and add the library to dependency_libs so + # that the program can be linked against the static library. + $echo + $echo "*** Warning: This system can not link to static lib archive $lib." + $echo "*** I have the capability to make that library automatically link in when" + $echo "*** you link to this library. But I can only do this if you have a" + $echo "*** shared version of the library, which you do not appear to have." + if test "$module" = yes; then + $echo "*** But as you try to build a module library, libtool will still create " + $echo "*** a static module, that should work as long as the dlopening application" + $echo "*** is linked with the -dlopen flag to resolve symbols at runtime." + if test -z "$global_symbol_pipe"; then + $echo + $echo "*** However, this would only work if libtool was able to extract symbol" + $echo "*** lists from a program, using \`nm' or equivalent, but libtool could" + $echo "*** not find such a program. So, this module is probably useless." + $echo "*** \`nm' from GNU binutils and a full rebuild may help." + fi + if test "$build_old_libs" = no; then + build_libtool_libs=module + build_old_libs=yes + else + build_libtool_libs=no + fi + fi + else + deplibs="$dir/$old_library $deplibs" + link_static=yes + fi + fi # link shared/static library? + + if test "$linkmode" = lib; then + if test -n "$dependency_libs" && + { test "$hardcode_into_libs" != yes || + test "$build_old_libs" = yes || + test "$link_static" = yes; }; then + # Extract -R from dependency_libs + temp_deplibs= + for libdir in $dependency_libs; do + case $libdir in + -R*) temp_xrpath=`$echo "X$libdir" | $Xsed -e 's/^-R//'` + case " $xrpath " in + *" $temp_xrpath "*) ;; + *) xrpath="$xrpath $temp_xrpath";; + esac;; + *) temp_deplibs="$temp_deplibs $libdir";; + esac + done + dependency_libs="$temp_deplibs" + fi + + newlib_search_path="$newlib_search_path $absdir" + # Link against this library + test "$link_static" = no && newdependency_libs="$abs_ladir/$laname $newdependency_libs" + # ... and its dependency_libs + tmp_libs= + for deplib in $dependency_libs; do + newdependency_libs="$deplib $newdependency_libs" + if test "X$duplicate_deps" = "Xyes" ; then + case "$tmp_libs " in + *" $deplib "*) specialdeplibs="$specialdeplibs $deplib" ;; + esac + fi + tmp_libs="$tmp_libs $deplib" + done + + if test "$link_all_deplibs" != no; then + # Add the search paths of all dependency libraries + for deplib in $dependency_libs; do + case $deplib in + -L*) path="$deplib" ;; + *.la) + dir=`$echo "X$deplib" | $Xsed -e 's%/[^/]*$%%'` + test "X$dir" = "X$deplib" && dir="." + # We need an absolute path. + case $dir in + [\\/]* | [A-Za-z]:[\\/]*) absdir="$dir" ;; + *) + absdir=`cd "$dir" && pwd` + if test -z "$absdir"; then + $echo "$modename: warning: cannot determine absolute directory name of \`$dir'" 1>&2 + absdir="$dir" + fi + ;; + esac + if grep "^installed=no" $deplib > /dev/null; then + path="$absdir/$objdir" + else + eval libdir=`${SED} -n -e 's/^libdir=\(.*\)$/\1/p' $deplib` + if test -z "$libdir"; then + $echo "$modename: \`$deplib' is not a valid libtool archive" 1>&2 + exit $EXIT_FAILURE + fi + if test "$absdir" != "$libdir"; then + $echo "$modename: warning: \`$deplib' seems to be moved" 1>&2 + fi + path="$absdir" + fi + depdepl= + case $host in + *-*-darwin*) + # we do not want to link against static libs, + # but need to link against shared + eval deplibrary_names=`${SED} -n -e 's/^library_names=\(.*\)$/\1/p' $deplib` + if test -n "$deplibrary_names" ; then + for tmp in $deplibrary_names ; do + depdepl=$tmp + done + if test -f "$path/$depdepl" ; then + depdepl="$path/$depdepl" + fi + # do not add paths which are already there + case " $newlib_search_path " in + *" $path "*) ;; + *) newlib_search_path="$newlib_search_path $path";; + esac + fi + path="" + ;; + *) + path="-L$path" + ;; + esac + ;; + -l*) + case $host in + *-*-darwin*) + # Again, we only want to link against shared libraries + eval tmp_libs=`$echo "X$deplib" | $Xsed -e "s,^\-l,,"` + for tmp in $newlib_search_path ; do + if test -f "$tmp/lib$tmp_libs.dylib" ; then + eval depdepl="$tmp/lib$tmp_libs.dylib" + break + fi + done + path="" + ;; + *) continue ;; + esac + ;; + *) continue ;; + esac + case " $deplibs " in + *" $path "*) ;; + *) deplibs="$path $deplibs" ;; + esac + case " $deplibs " in + *" $depdepl "*) ;; + *) deplibs="$depdepl $deplibs" ;; + esac + done + fi # link_all_deplibs != no + fi # linkmode = lib + done # for deplib in $libs + dependency_libs="$newdependency_libs" + if test "$pass" = dlpreopen; then + # Link the dlpreopened libraries before other libraries + for deplib in $save_deplibs; do + deplibs="$deplib $deplibs" + done + fi + if test "$pass" != dlopen; then + if test "$pass" != conv; then + # Make sure lib_search_path contains only unique directories. + lib_search_path= + for dir in $newlib_search_path; do + case "$lib_search_path " in + *" $dir "*) ;; + *) lib_search_path="$lib_search_path $dir" ;; + esac + done + newlib_search_path= + fi + + if test "$linkmode,$pass" != "prog,link"; then + vars="deplibs" + else + vars="compile_deplibs finalize_deplibs" + fi + for var in $vars dependency_libs; do + # Add libraries to $var in reverse order + eval tmp_libs=\"\$$var\" + new_libs= + for deplib in $tmp_libs; do + # FIXME: Pedantically, this is the right thing to do, so + # that some nasty dependency loop isn't accidentally + # broken: + #new_libs="$deplib $new_libs" + # Pragmatically, this seems to cause very few problems in + # practice: + case $deplib in + -L*) new_libs="$deplib $new_libs" ;; + -R*) ;; + *) + # And here is the reason: when a library appears more + # than once as an explicit dependence of a library, or + # is implicitly linked in more than once by the + # compiler, it is considered special, and multiple + # occurrences thereof are not removed. Compare this + # with having the same library being listed as a + # dependency of multiple other libraries: in this case, + # we know (pedantically, we assume) the library does not + # need to be listed more than once, so we keep only the + # last copy. This is not always right, but it is rare + # enough that we require users that really mean to play + # such unportable linking tricks to link the library + # using -Wl,-lname, so that libtool does not consider it + # for duplicate removal. + case " $specialdeplibs " in + *" $deplib "*) new_libs="$deplib $new_libs" ;; + *) + case " $new_libs " in + *" $deplib "*) ;; + *) new_libs="$deplib $new_libs" ;; + esac + ;; + esac + ;; + esac + done + tmp_libs= + for deplib in $new_libs; do + case $deplib in + -L*) + case " $tmp_libs " in + *" $deplib "*) ;; + *) tmp_libs="$tmp_libs $deplib" ;; + esac + ;; + *) tmp_libs="$tmp_libs $deplib" ;; + esac + done + eval $var=\"$tmp_libs\" + done # for var + fi + # Last step: remove runtime libs from dependency_libs + # (they stay in deplibs) + tmp_libs= + for i in $dependency_libs ; do + case " $predeps $postdeps $compiler_lib_search_path " in + *" $i "*) + i="" + ;; + esac + if test -n "$i" ; then + tmp_libs="$tmp_libs $i" + fi + done + dependency_libs=$tmp_libs + done # for pass + if test "$linkmode" = prog; then + dlfiles="$newdlfiles" + dlprefiles="$newdlprefiles" + fi + + case $linkmode in + oldlib) + if test -n "$deplibs"; then + $echo "$modename: warning: \`-l' and \`-L' are ignored for archives" 1>&2 + fi + + if test -n "$dlfiles$dlprefiles" || test "$dlself" != no; then + $echo "$modename: warning: \`-dlopen' is ignored for archives" 1>&2 + fi + + if test -n "$rpath"; then + $echo "$modename: warning: \`-rpath' is ignored for archives" 1>&2 + fi + + if test -n "$xrpath"; then + $echo "$modename: warning: \`-R' is ignored for archives" 1>&2 + fi + + if test -n "$vinfo"; then + $echo "$modename: warning: \`-version-info/-version-number' is ignored for archives" 1>&2 + fi + + if test -n "$release"; then + $echo "$modename: warning: \`-release' is ignored for archives" 1>&2 + fi + + if test -n "$export_symbols" || test -n "$export_symbols_regex"; then + $echo "$modename: warning: \`-export-symbols' is ignored for archives" 1>&2 + fi + + # Now set the variables for building old libraries. + build_libtool_libs=no + oldlibs="$output" + objs="$objs$old_deplibs" + ;; + + lib) + # Make sure we only generate libraries of the form `libNAME.la'. + case $outputname in + lib*) + name=`$echo "X$outputname" | $Xsed -e 's/\.la$//' -e 's/^lib//'` + eval shared_ext=\"$shrext_cmds\" + eval libname=\"$libname_spec\" + ;; + *) + if test "$module" = no; then + $echo "$modename: libtool library \`$output' must begin with \`lib'" 1>&2 + $echo "$help" 1>&2 + exit $EXIT_FAILURE + fi + if test "$need_lib_prefix" != no; then + # Add the "lib" prefix for modules if required + name=`$echo "X$outputname" | $Xsed -e 's/\.la$//'` + eval shared_ext=\"$shrext_cmds\" + eval libname=\"$libname_spec\" + else + libname=`$echo "X$outputname" | $Xsed -e 's/\.la$//'` + fi + ;; + esac + + if test -n "$objs"; then + if test "$deplibs_check_method" != pass_all; then + $echo "$modename: cannot build libtool library \`$output' from non-libtool objects on this host:$objs" 2>&1 + exit $EXIT_FAILURE + else + $echo + $echo "*** Warning: Linking the shared library $output against the non-libtool" + $echo "*** objects $objs is not portable!" + libobjs="$libobjs $objs" + fi + fi + + if test "$dlself" != no; then + $echo "$modename: warning: \`-dlopen self' is ignored for libtool libraries" 1>&2 + fi + + set dummy $rpath + if test "$#" -gt 2; then + $echo "$modename: warning: ignoring multiple \`-rpath's for a libtool library" 1>&2 + fi + install_libdir="$2" + + oldlibs= + if test -z "$rpath"; then + if test "$build_libtool_libs" = yes; then + # Building a libtool convenience library. + # Some compilers have problems with a `.al' extension so + # convenience libraries should have the same extension an + # archive normally would. + oldlibs="$output_objdir/$libname.$libext $oldlibs" + build_libtool_libs=convenience + build_old_libs=yes + fi + + if test -n "$vinfo"; then + $echo "$modename: warning: \`-version-info/-version-number' is ignored for convenience libraries" 1>&2 + fi + + if test -n "$release"; then + $echo "$modename: warning: \`-release' is ignored for convenience libraries" 1>&2 + fi + else + + # Parse the version information argument. + save_ifs="$IFS"; IFS=':' + set dummy $vinfo 0 0 0 + IFS="$save_ifs" + + if test -n "$8"; then + $echo "$modename: too many parameters to \`-version-info'" 1>&2 + $echo "$help" 1>&2 + exit $EXIT_FAILURE + fi + + # convert absolute version numbers to libtool ages + # this retains compatibility with .la files and attempts + # to make the code below a bit more comprehensible + + case $vinfo_number in + yes) + number_major="$2" + number_minor="$3" + number_revision="$4" + # + # There are really only two kinds -- those that + # use the current revision as the major version + # and those that subtract age and use age as + # a minor version. But, then there is irix + # which has an extra 1 added just for fun + # + case $version_type in + darwin|linux|osf|windows|none) + current=`expr $number_major + $number_minor` + age="$number_minor" + revision="$number_revision" + ;; + freebsd-aout|freebsd-elf|sunos) + current="$number_major" + revision="$number_minor" + age="0" + ;; + irix|nonstopux) + current=`expr $number_major + $number_minor - 1` + age="$number_minor" + revision="$number_minor" + ;; + esac + ;; + no) + current="$2" + revision="$3" + age="$4" + ;; + esac + + # Check that each of the things are valid numbers. + case $current in + 0|[1-9]|[1-9][0-9]|[1-9][0-9][0-9]|[1-9][0-9][0-9][0-9]|[1-9][0-9][0-9][0-9][0-9]) ;; + *) + $echo "$modename: CURRENT \`$current' must be a nonnegative integer" 1>&2 + $echo "$modename: \`$vinfo' is not valid version information" 1>&2 + exit $EXIT_FAILURE + ;; + esac + + case $revision in + 0|[1-9]|[1-9][0-9]|[1-9][0-9][0-9]|[1-9][0-9][0-9][0-9]|[1-9][0-9][0-9][0-9][0-9]) ;; + *) + $echo "$modename: REVISION \`$revision' must be a nonnegative integer" 1>&2 + $echo "$modename: \`$vinfo' is not valid version information" 1>&2 + exit $EXIT_FAILURE + ;; + esac + + case $age in + 0|[1-9]|[1-9][0-9]|[1-9][0-9][0-9]|[1-9][0-9][0-9][0-9]|[1-9][0-9][0-9][0-9][0-9]) ;; + *) + $echo "$modename: AGE \`$age' must be a nonnegative integer" 1>&2 + $echo "$modename: \`$vinfo' is not valid version information" 1>&2 + exit $EXIT_FAILURE + ;; + esac + + if test "$age" -gt "$current"; then + $echo "$modename: AGE \`$age' is greater than the current interface number \`$current'" 1>&2 + $echo "$modename: \`$vinfo' is not valid version information" 1>&2 + exit $EXIT_FAILURE + fi + + # Calculate the version variables. + major= + versuffix= + verstring= + case $version_type in + none) ;; + + darwin) + # Like Linux, but with the current version available in + # verstring for coding it into the library header + major=.`expr $current - $age` + versuffix="$major.$age.$revision" + # Darwin ld doesn't like 0 for these options... + minor_current=`expr $current + 1` + verstring="${wl}-compatibility_version ${wl}$minor_current ${wl}-current_version ${wl}$minor_current.$revision" + ;; + + freebsd-aout) + major=".$current" + versuffix=".$current.$revision"; + ;; + + freebsd-elf) + major=".$current" + versuffix=".$current"; + ;; + + irix | nonstopux) + major=`expr $current - $age + 1` + + case $version_type in + nonstopux) verstring_prefix=nonstopux ;; + *) verstring_prefix=sgi ;; + esac + verstring="$verstring_prefix$major.$revision" + + # Add in all the interfaces that we are compatible with. + loop=$revision + while test "$loop" -ne 0; do + iface=`expr $revision - $loop` + loop=`expr $loop - 1` + verstring="$verstring_prefix$major.$iface:$verstring" + done + + # Before this point, $major must not contain `.'. + major=.$major + versuffix="$major.$revision" + ;; + + linux) + major=.`expr $current - $age` + versuffix="$major.$age.$revision" + ;; + + osf) + major=.`expr $current - $age` + versuffix=".$current.$age.$revision" + verstring="$current.$age.$revision" + + # Add in all the interfaces that we are compatible with. + loop=$age + while test "$loop" -ne 0; do + iface=`expr $current - $loop` + loop=`expr $loop - 1` + verstring="$verstring:${iface}.0" + done + + # Make executables depend on our current version. + verstring="$verstring:${current}.0" + ;; + + sunos) + major=".$current" + versuffix=".$current.$revision" + ;; + + windows) + # Use '-' rather than '.', since we only want one + # extension on DOS 8.3 filesystems. + major=`expr $current - $age` + versuffix="-$major" + ;; + + *) + $echo "$modename: unknown library version type \`$version_type'" 1>&2 + $echo "Fatal configuration error. See the $PACKAGE docs for more information." 1>&2 + exit $EXIT_FAILURE + ;; + esac + + # Clear the version info if we defaulted, and they specified a release. + if test -z "$vinfo" && test -n "$release"; then + major= + case $version_type in + darwin) + # we can't check for "0.0" in archive_cmds due to quoting + # problems, so we reset it completely + verstring= + ;; + *) + verstring="0.0" + ;; + esac + if test "$need_version" = no; then + versuffix= + else + versuffix=".0.0" + fi + fi + + # Remove version info from name if versioning should be avoided + if test "$avoid_version" = yes && test "$need_version" = no; then + major= + versuffix= + verstring="" + fi + + # Check to see if the archive will have undefined symbols. + if test "$allow_undefined" = yes; then + if test "$allow_undefined_flag" = unsupported; then + $echo "$modename: warning: undefined symbols not allowed in $host shared libraries" 1>&2 + build_libtool_libs=no + build_old_libs=yes + fi + else + # Don't allow undefined symbols. + allow_undefined_flag="$no_undefined_flag" + fi + fi + + if test "$mode" != relink; then + # Remove our outputs, but don't remove object files since they + # may have been created when compiling PIC objects. + removelist= + tempremovelist=`$echo "$output_objdir/*"` + for p in $tempremovelist; do + case $p in + *.$objext) + ;; + $output_objdir/$outputname | $output_objdir/$libname.* | $output_objdir/${libname}${release}.*) + if test "X$precious_files_regex" != "X"; then + if echo $p | $EGREP -e "$precious_files_regex" >/dev/null 2>&1 + then + continue + fi + fi + removelist="$removelist $p" + ;; + *) ;; + esac + done + if test -n "$removelist"; then + $show "${rm}r $removelist" + $run ${rm}r $removelist + fi + fi + + # Now set the variables for building old libraries. + if test "$build_old_libs" = yes && test "$build_libtool_libs" != convenience ; then + oldlibs="$oldlibs $output_objdir/$libname.$libext" + + # Transform .lo files to .o files. + oldobjs="$objs "`$echo "X$libobjs" | $SP2NL | $Xsed -e '/\.'${libext}'$/d' -e "$lo2o" | $NL2SP` + fi + + # Eliminate all temporary directories. +# for path in $notinst_path; do +# lib_search_path=`$echo "$lib_search_path " | ${SED} -e "s% $path % %g"` +# deplibs=`$echo "$deplibs " | ${SED} -e "s% -L$path % %g"` +# dependency_libs=`$echo "$dependency_libs " | ${SED} -e "s% -L$path % %g"` +# done + + if test -n "$xrpath"; then + # If the user specified any rpath flags, then add them. + temp_xrpath= + for libdir in $xrpath; do + temp_xrpath="$temp_xrpath -R$libdir" + case "$finalize_rpath " in + *" $libdir "*) ;; + *) finalize_rpath="$finalize_rpath $libdir" ;; + esac + done + if test "$hardcode_into_libs" != yes || test "$build_old_libs" = yes; then + dependency_libs="$temp_xrpath $dependency_libs" + fi + fi + + # Make sure dlfiles contains only unique files that won't be dlpreopened + old_dlfiles="$dlfiles" + dlfiles= + for lib in $old_dlfiles; do + case " $dlprefiles $dlfiles " in + *" $lib "*) ;; + *) dlfiles="$dlfiles $lib" ;; + esac + done + + # Make sure dlprefiles contains only unique files + old_dlprefiles="$dlprefiles" + dlprefiles= + for lib in $old_dlprefiles; do + case "$dlprefiles " in + *" $lib "*) ;; + *) dlprefiles="$dlprefiles $lib" ;; + esac + done + + if test "$build_libtool_libs" = yes; then + if test -n "$rpath"; then + case $host in + *-*-cygwin* | *-*-mingw* | *-*-pw32* | *-*-os2* | *-*-beos*) + # these systems don't actually have a c library (as such)! + ;; + *-*-rhapsody* | *-*-darwin1.[012]) + # Rhapsody C library is in the System framework + deplibs="$deplibs -framework System" + ;; + *-*-netbsd*) + # Don't link with libc until the a.out ld.so is fixed. + ;; + *-*-openbsd* | *-*-freebsd* | *-*-dragonfly*) + # Do not include libc due to us having libc/libc_r. + ;; + *-*-sco3.2v5* | *-*-sco5v6*) + # Causes problems with __ctype + ;; + *-*-sysv4.2uw2* | *-*-sysv5* | *-*-unixware* | *-*-OpenUNIX*) + # Compiler inserts libc in the correct place for threads to work + ;; + *) + # Add libc to deplibs on all other systems if necessary. + if test "$build_libtool_need_lc" = "yes"; then + deplibs="$deplibs -lc" + fi + ;; + esac + fi + + # Transform deplibs into only deplibs that can be linked in shared. + name_save=$name + libname_save=$libname + release_save=$release + versuffix_save=$versuffix + major_save=$major + # I'm not sure if I'm treating the release correctly. I think + # release should show up in the -l (ie -lgmp5) so we don't want to + # add it in twice. Is that correct? + release="" + versuffix="" + major="" + newdeplibs= + droppeddeps=no + case $deplibs_check_method in + pass_all) + # Don't check for shared/static. Everything works. + # This might be a little naive. We might want to check + # whether the library exists or not. But this is on + # osf3 & osf4 and I'm not really sure... Just + # implementing what was already the behavior. + newdeplibs=$deplibs + ;; + test_compile) + # This code stresses the "libraries are programs" paradigm to its + # limits. Maybe even breaks it. We compile a program, linking it + # against the deplibs as a proxy for the library. Then we can check + # whether they linked in statically or dynamically with ldd. + $rm conftest.c + cat > conftest.c <<EOF + int main() { return 0; } +EOF + $rm conftest + if $LTCC $LTCFLAGS -o conftest conftest.c $deplibs; then + ldd_output=`ldd conftest` + for i in $deplibs; do + name=`expr $i : '-l\(.*\)'` + # If $name is empty we are operating on a -L argument. + if test "$name" != "" && test "$name" != "0"; then + if test "X$allow_libtool_libs_with_static_runtimes" = "Xyes" ; then + case " $predeps $postdeps " in + *" $i "*) + newdeplibs="$newdeplibs $i" + i="" + ;; + esac + fi + if test -n "$i" ; then + libname=`eval \\$echo \"$libname_spec\"` + deplib_matches=`eval \\$echo \"$library_names_spec\"` + set dummy $deplib_matches + deplib_match=$2 + if test `expr "$ldd_output" : ".*$deplib_match"` -ne 0 ; then + newdeplibs="$newdeplibs $i" + else + droppeddeps=yes + $echo + $echo "*** Warning: dynamic linker does not accept needed library $i." + $echo "*** I have the capability to make that library automatically link in when" + $echo "*** you link to this library. But I can only do this if you have a" + $echo "*** shared version of the library, which I believe you do not have" + $echo "*** because a test_compile did reveal that the linker did not use it for" + $echo "*** its dynamic dependency list that programs get resolved with at runtime." + fi + fi + else + newdeplibs="$newdeplibs $i" + fi + done + else + # Error occurred in the first compile. Let's try to salvage + # the situation: Compile a separate program for each library. + for i in $deplibs; do + name=`expr $i : '-l\(.*\)'` + # If $name is empty we are operating on a -L argument. + if test "$name" != "" && test "$name" != "0"; then + $rm conftest + if $LTCC $LTCFLAGS -o conftest conftest.c $i; then + ldd_output=`ldd conftest` + if test "X$allow_libtool_libs_with_static_runtimes" = "Xyes" ; then + case " $predeps $postdeps " in + *" $i "*) + newdeplibs="$newdeplibs $i" + i="" + ;; + esac + fi + if test -n "$i" ; then + libname=`eval \\$echo \"$libname_spec\"` + deplib_matches=`eval \\$echo \"$library_names_spec\"` + set dummy $deplib_matches + deplib_match=$2 + if test `expr "$ldd_output" : ".*$deplib_match"` -ne 0 ; then + newdeplibs="$newdeplibs $i" + else + droppeddeps=yes + $echo + $echo "*** Warning: dynamic linker does not accept needed library $i." + $echo "*** I have the capability to make that library automatically link in when" + $echo "*** you link to this library. But I can only do this if you have a" + $echo "*** shared version of the library, which you do not appear to have" + $echo "*** because a test_compile did reveal that the linker did not use this one" + $echo "*** as a dynamic dependency that programs can get resolved with at runtime." + fi + fi + else + droppeddeps=yes + $echo + $echo "*** Warning! Library $i is needed by this library but I was not able to" + $echo "*** make it link in! You will probably need to install it or some" + $echo "*** library that it depends on before this library will be fully" + $echo "*** functional. Installing it before continuing would be even better." + fi + else + newdeplibs="$newdeplibs $i" + fi + done + fi + ;; + file_magic*) + set dummy $deplibs_check_method + file_magic_regex=`expr "$deplibs_check_method" : "$2 \(.*\)"` + for a_deplib in $deplibs; do + name=`expr $a_deplib : '-l\(.*\)'` + # If $name is empty we are operating on a -L argument. + if test "$name" != "" && test "$name" != "0"; then + if test "X$allow_libtool_libs_with_static_runtimes" = "Xyes" ; then + case " $predeps $postdeps " in + *" $a_deplib "*) + newdeplibs="$newdeplibs $a_deplib" + a_deplib="" + ;; + esac + fi + if test -n "$a_deplib" ; then + libname=`eval \\$echo \"$libname_spec\"` + for i in $lib_search_path $sys_lib_search_path $shlib_search_path; do + potential_libs=`ls $i/$libname[.-]* 2>/dev/null` + for potent_lib in $potential_libs; do + # Follow soft links. + if ls -lLd "$potent_lib" 2>/dev/null \ + | grep " -> " >/dev/null; then + continue + fi + # The statement above tries to avoid entering an + # endless loop below, in case of cyclic links. + # We might still enter an endless loop, since a link + # loop can be closed while we follow links, + # but so what? + potlib="$potent_lib" + while test -h "$potlib" 2>/dev/null; do + potliblink=`ls -ld $potlib | ${SED} 's/.* -> //'` + case $potliblink in + [\\/]* | [A-Za-z]:[\\/]*) potlib="$potliblink";; + *) potlib=`$echo "X$potlib" | $Xsed -e 's,[^/]*$,,'`"$potliblink";; + esac + done + if eval $file_magic_cmd \"\$potlib\" 2>/dev/null \ + | ${SED} 10q \ + | $EGREP "$file_magic_regex" > /dev/null; then + newdeplibs="$newdeplibs $a_deplib" + a_deplib="" + break 2 + fi + done + done + fi + if test -n "$a_deplib" ; then + droppeddeps=yes + $echo + $echo "*** Warning: linker path does not have real file for library $a_deplib." + $echo "*** I have the capability to make that library automatically link in when" + $echo "*** you link to this library. But I can only do this if you have a" + $echo "*** shared version of the library, which you do not appear to have" + $echo "*** because I did check the linker path looking for a file starting" + if test -z "$potlib" ; then + $echo "*** with $libname but no candidates were found. (...for file magic test)" + else + $echo "*** with $libname and none of the candidates passed a file format test" + $echo "*** using a file magic. Last file checked: $potlib" + fi + fi + else + # Add a -L argument. + newdeplibs="$newdeplibs $a_deplib" + fi + done # Gone through all deplibs. + ;; + match_pattern*) + set dummy $deplibs_check_method + match_pattern_regex=`expr "$deplibs_check_method" : "$2 \(.*\)"` + for a_deplib in $deplibs; do + name=`expr $a_deplib : '-l\(.*\)'` + # If $name is empty we are operating on a -L argument. + if test -n "$name" && test "$name" != "0"; then + if test "X$allow_libtool_libs_with_static_runtimes" = "Xyes" ; then + case " $predeps $postdeps " in + *" $a_deplib "*) + newdeplibs="$newdeplibs $a_deplib" + a_deplib="" + ;; + esac + fi + if test -n "$a_deplib" ; then + libname=`eval \\$echo \"$libname_spec\"` + for i in $lib_search_path $sys_lib_search_path $shlib_search_path; do + potential_libs=`ls $i/$libname[.-]* 2>/dev/null` + for potent_lib in $potential_libs; do + potlib="$potent_lib" # see symlink-check above in file_magic test + if eval $echo \"$potent_lib\" 2>/dev/null \ + | ${SED} 10q \ + | $EGREP "$match_pattern_regex" > /dev/null; then + newdeplibs="$newdeplibs $a_deplib" + a_deplib="" + break 2 + fi + done + done + fi + if test -n "$a_deplib" ; then + droppeddeps=yes + $echo + $echo "*** Warning: linker path does not have real file for library $a_deplib." + $echo "*** I have the capability to make that library automatically link in when" + $echo "*** you link to this library. But I can only do this if you have a" + $echo "*** shared version of the library, which you do not appear to have" + $echo "*** because I did check the linker path looking for a file starting" + if test -z "$potlib" ; then + $echo "*** with $libname but no candidates were found. (...for regex pattern test)" + else + $echo "*** with $libname and none of the candidates passed a file format test" + $echo "*** using a regex pattern. Last file checked: $potlib" + fi + fi + else + # Add a -L argument. + newdeplibs="$newdeplibs $a_deplib" + fi + done # Gone through all deplibs. + ;; + none | unknown | *) + newdeplibs="" + tmp_deplibs=`$echo "X $deplibs" | $Xsed -e 's/ -lc$//' \ + -e 's/ -[LR][^ ]*//g'` + if test "X$allow_libtool_libs_with_static_runtimes" = "Xyes" ; then + for i in $predeps $postdeps ; do + # can't use Xsed below, because $i might contain '/' + tmp_deplibs=`$echo "X $tmp_deplibs" | ${SED} -e "1s,^X,," -e "s,$i,,"` + done + fi + if $echo "X $tmp_deplibs" | $Xsed -e 's/[ ]//g' \ + | grep . >/dev/null; then + $echo + if test "X$deplibs_check_method" = "Xnone"; then + $echo "*** Warning: inter-library dependencies are not supported in this platform." + else + $echo "*** Warning: inter-library dependencies are not known to be supported." + fi + $echo "*** All declared inter-library dependencies are being dropped." + droppeddeps=yes + fi + ;; + esac + versuffix=$versuffix_save + major=$major_save + release=$release_save + libname=$libname_save + name=$name_save + + case $host in + *-*-rhapsody* | *-*-darwin1.[012]) + # On Rhapsody replace the C library is the System framework + newdeplibs=`$echo "X $newdeplibs" | $Xsed -e 's/ -lc / -framework System /'` + ;; + esac + + if test "$droppeddeps" = yes; then + if test "$module" = yes; then + $echo + $echo "*** Warning: libtool could not satisfy all declared inter-library" + $echo "*** dependencies of module $libname. Therefore, libtool will create" + $echo "*** a static module, that should work as long as the dlopening" + $echo "*** application is linked with the -dlopen flag." + if test -z "$global_symbol_pipe"; then + $echo + $echo "*** However, this would only work if libtool was able to extract symbol" + $echo "*** lists from a program, using \`nm' or equivalent, but libtool could" + $echo "*** not find such a program. So, this module is probably useless." + $echo "*** \`nm' from GNU binutils and a full rebuild may help." + fi + if test "$build_old_libs" = no; then + oldlibs="$output_objdir/$libname.$libext" + build_libtool_libs=module + build_old_libs=yes + else + build_libtool_libs=no + fi + else + $echo "*** The inter-library dependencies that have been dropped here will be" + $echo "*** automatically added whenever a program is linked with this library" + $echo "*** or is declared to -dlopen it." + + if test "$allow_undefined" = no; then + $echo + $echo "*** Since this library must not contain undefined symbols," + $echo "*** because either the platform does not support them or" + $echo "*** it was explicitly requested with -no-undefined," + $echo "*** libtool will only create a static version of it." + if test "$build_old_libs" = no; then + oldlibs="$output_objdir/$libname.$libext" + build_libtool_libs=module + build_old_libs=yes + else + build_libtool_libs=no + fi + fi + fi + fi + # Done checking deplibs! + deplibs=$newdeplibs + fi + + + # move library search paths that coincide with paths to not yet + # installed libraries to the beginning of the library search list + new_libs= + for path in $notinst_path; do + case " $new_libs " in + *" -L$path/$objdir "*) ;; + *) + case " $deplibs " in + *" -L$path/$objdir "*) + new_libs="$new_libs -L$path/$objdir" ;; + esac + ;; + esac + done + for deplib in $deplibs; do + case $deplib in + -L*) + case " $new_libs " in + *" $deplib "*) ;; + *) new_libs="$new_libs $deplib" ;; + esac + ;; + *) new_libs="$new_libs $deplib" ;; + esac + done + deplibs="$new_libs" + + + # All the library-specific variables (install_libdir is set above). + library_names= + old_library= + dlname= + + # Test again, we may have decided not to build it any more + if test "$build_libtool_libs" = yes; then + if test "$hardcode_into_libs" = yes; then + # Hardcode the library paths + hardcode_libdirs= + dep_rpath= + rpath="$finalize_rpath" + test "$mode" != relink && rpath="$compile_rpath$rpath" + for libdir in $rpath; do + if test -n "$hardcode_libdir_flag_spec"; then + if test -n "$hardcode_libdir_separator"; then + if test -z "$hardcode_libdirs"; then + hardcode_libdirs="$libdir" + else + # Just accumulate the unique libdirs. + case $hardcode_libdir_separator$hardcode_libdirs$hardcode_libdir_separator in + *"$hardcode_libdir_separator$libdir$hardcode_libdir_separator"*) + ;; + *) + hardcode_libdirs="$hardcode_libdirs$hardcode_libdir_separator$libdir" + ;; + esac + fi + else + eval flag=\"$hardcode_libdir_flag_spec\" + dep_rpath="$dep_rpath $flag" + fi + elif test -n "$runpath_var"; then + case "$perm_rpath " in + *" $libdir "*) ;; + *) perm_rpath="$perm_rpath $libdir" ;; + esac + fi + done + # Substitute the hardcoded libdirs into the rpath. + if test -n "$hardcode_libdir_separator" && + test -n "$hardcode_libdirs"; then + libdir="$hardcode_libdirs" + if test -n "$hardcode_libdir_flag_spec_ld"; then + eval dep_rpath=\"$hardcode_libdir_flag_spec_ld\" + else + eval dep_rpath=\"$hardcode_libdir_flag_spec\" + fi + fi + if test -n "$runpath_var" && test -n "$perm_rpath"; then + # We should set the runpath_var. + rpath= + for dir in $perm_rpath; do + rpath="$rpath$dir:" + done + eval "$runpath_var='$rpath\$$runpath_var'; export $runpath_var" + fi + test -n "$dep_rpath" && deplibs="$dep_rpath $deplibs" + fi + + shlibpath="$finalize_shlibpath" + test "$mode" != relink && shlibpath="$compile_shlibpath$shlibpath" + if test -n "$shlibpath"; then + eval "$shlibpath_var='$shlibpath\$$shlibpath_var'; export $shlibpath_var" + fi + + # Get the real and link names of the library. + eval shared_ext=\"$shrext_cmds\" + eval library_names=\"$library_names_spec\" + set dummy $library_names + realname="$2" + shift; shift + + if test -n "$soname_spec"; then + eval soname=\"$soname_spec\" + else + soname="$realname" + fi + if test -z "$dlname"; then + dlname=$soname + fi + + lib="$output_objdir/$realname" + linknames= + for link + do + linknames="$linknames $link" + done + + # Use standard objects if they are pic + test -z "$pic_flag" && libobjs=`$echo "X$libobjs" | $SP2NL | $Xsed -e "$lo2o" | $NL2SP` + + # Prepare the list of exported symbols + if test -z "$export_symbols"; then + if test "$always_export_symbols" = yes || test -n "$export_symbols_regex"; then + $show "generating symbol list for \`$libname.la'" + export_symbols="$output_objdir/$libname.exp" + $run $rm $export_symbols + cmds=$export_symbols_cmds + save_ifs="$IFS"; IFS='~' + for cmd in $cmds; do + IFS="$save_ifs" + eval cmd=\"$cmd\" + if len=`expr "X$cmd" : ".*"` && + test "$len" -le "$max_cmd_len" || test "$max_cmd_len" -le -1; then + $show "$cmd" + $run eval "$cmd" || exit $? + skipped_export=false + else + # The command line is too long to execute in one step. + $show "using reloadable object file for export list..." + skipped_export=: + # Break out early, otherwise skipped_export may be + # set to false by a later but shorter cmd. + break + fi + done + IFS="$save_ifs" + if test -n "$export_symbols_regex"; then + $show "$EGREP -e \"$export_symbols_regex\" \"$export_symbols\" > \"${export_symbols}T\"" + $run eval '$EGREP -e "$export_symbols_regex" "$export_symbols" > "${export_symbols}T"' + $show "$mv \"${export_symbols}T\" \"$export_symbols\"" + $run eval '$mv "${export_symbols}T" "$export_symbols"' + fi + fi + fi + + if test -n "$export_symbols" && test -n "$include_expsyms"; then + $run eval '$echo "X$include_expsyms" | $SP2NL >> "$export_symbols"' + fi + + tmp_deplibs= + for test_deplib in $deplibs; do + case " $convenience " in + *" $test_deplib "*) ;; + *) + tmp_deplibs="$tmp_deplibs $test_deplib" + ;; + esac + done + deplibs="$tmp_deplibs" + + if test -n "$convenience"; then + if test -n "$whole_archive_flag_spec"; then + save_libobjs=$libobjs + eval libobjs=\"\$libobjs $whole_archive_flag_spec\" + else + gentop="$output_objdir/${outputname}x" + generated="$generated $gentop" + + func_extract_archives $gentop $convenience + libobjs="$libobjs $func_extract_archives_result" + fi + fi + + if test "$thread_safe" = yes && test -n "$thread_safe_flag_spec"; then + eval flag=\"$thread_safe_flag_spec\" + linker_flags="$linker_flags $flag" + fi + + # Make a backup of the uninstalled library when relinking + if test "$mode" = relink; then + $run eval '(cd $output_objdir && $rm ${realname}U && $mv $realname ${realname}U)' || exit $? + fi + + # Do each of the archive commands. + if test "$module" = yes && test -n "$module_cmds" ; then + if test -n "$export_symbols" && test -n "$module_expsym_cmds"; then + eval test_cmds=\"$module_expsym_cmds\" + cmds=$module_expsym_cmds + else + eval test_cmds=\"$module_cmds\" + cmds=$module_cmds + fi + else + if test -n "$export_symbols" && test -n "$archive_expsym_cmds"; then + eval test_cmds=\"$archive_expsym_cmds\" + cmds=$archive_expsym_cmds + else + eval test_cmds=\"$archive_cmds\" + cmds=$archive_cmds + fi + fi + + if test "X$skipped_export" != "X:" && + len=`expr "X$test_cmds" : ".*" 2>/dev/null` && + test "$len" -le "$max_cmd_len" || test "$max_cmd_len" -le -1; then + : + else + # The command line is too long to link in one step, link piecewise. + $echo "creating reloadable object files..." + + # Save the value of $output and $libobjs because we want to + # use them later. If we have whole_archive_flag_spec, we + # want to use save_libobjs as it was before + # whole_archive_flag_spec was expanded, because we can't + # assume the linker understands whole_archive_flag_spec. + # This may have to be revisited, in case too many + # convenience libraries get linked in and end up exceeding + # the spec. + if test -z "$convenience" || test -z "$whole_archive_flag_spec"; then + save_libobjs=$libobjs + fi + save_output=$output + output_la=`$echo "X$output" | $Xsed -e "$basename"` + + # Clear the reloadable object creation command queue and + # initialize k to one. + test_cmds= + concat_cmds= + objlist= + delfiles= + last_robj= + k=1 + output=$output_objdir/$output_la-${k}.$objext + # Loop over the list of objects to be linked. + for obj in $save_libobjs + do + eval test_cmds=\"$reload_cmds $objlist $last_robj\" + if test "X$objlist" = X || + { len=`expr "X$test_cmds" : ".*" 2>/dev/null` && + test "$len" -le "$max_cmd_len"; }; then + objlist="$objlist $obj" + else + # The command $test_cmds is almost too long, add a + # command to the queue. + if test "$k" -eq 1 ; then + # The first file doesn't have a previous command to add. + eval concat_cmds=\"$reload_cmds $objlist $last_robj\" + else + # All subsequent reloadable object files will link in + # the last one created. + eval concat_cmds=\"\$concat_cmds~$reload_cmds $objlist $last_robj\" + fi + last_robj=$output_objdir/$output_la-${k}.$objext + k=`expr $k + 1` + output=$output_objdir/$output_la-${k}.$objext + objlist=$obj + len=1 + fi + done + # Handle the remaining objects by creating one last + # reloadable object file. All subsequent reloadable object + # files will link in the last one created. + test -z "$concat_cmds" || concat_cmds=$concat_cmds~ + eval concat_cmds=\"\${concat_cmds}$reload_cmds $objlist $last_robj\" + + if ${skipped_export-false}; then + $show "generating symbol list for \`$libname.la'" + export_symbols="$output_objdir/$libname.exp" + $run $rm $export_symbols + libobjs=$output + # Append the command to create the export file. + eval concat_cmds=\"\$concat_cmds~$export_symbols_cmds\" + fi + + # Set up a command to remove the reloadable object files + # after they are used. + i=0 + while test "$i" -lt "$k" + do + i=`expr $i + 1` + delfiles="$delfiles $output_objdir/$output_la-${i}.$objext" + done + + $echo "creating a temporary reloadable object file: $output" + + # Loop through the commands generated above and execute them. + save_ifs="$IFS"; IFS='~' + for cmd in $concat_cmds; do + IFS="$save_ifs" + $show "$cmd" + $run eval "$cmd" || exit $? + done + IFS="$save_ifs" + + libobjs=$output + # Restore the value of output. + output=$save_output + + if test -n "$convenience" && test -n "$whole_archive_flag_spec"; then + eval libobjs=\"\$libobjs $whole_archive_flag_spec\" + fi + # Expand the library linking commands again to reset the + # value of $libobjs for piecewise linking. + + # Do each of the archive commands. + if test "$module" = yes && test -n "$module_cmds" ; then + if test -n "$export_symbols" && test -n "$module_expsym_cmds"; then + cmds=$module_expsym_cmds + else + cmds=$module_cmds + fi + else + if test -n "$export_symbols" && test -n "$archive_expsym_cmds"; then + cmds=$archive_expsym_cmds + else + cmds=$archive_cmds + fi + fi + + # Append the command to remove the reloadable object files + # to the just-reset $cmds. + eval cmds=\"\$cmds~\$rm $delfiles\" + fi + save_ifs="$IFS"; IFS='~' + for cmd in $cmds; do + IFS="$save_ifs" + eval cmd=\"$cmd\" + $show "$cmd" + $run eval "$cmd" || { + lt_exit=$? + + # Restore the uninstalled library and exit + if test "$mode" = relink; then + $run eval '(cd $output_objdir && $rm ${realname}T && $mv ${realname}U $realname)' + fi + + exit $lt_exit + } + done + IFS="$save_ifs" + + # Restore the uninstalled library and exit + if test "$mode" = relink; then + $run eval '(cd $output_objdir && $rm ${realname}T && $mv $realname ${realname}T && $mv "$realname"U $realname)' || exit $? + + if test -n "$convenience"; then + if test -z "$whole_archive_flag_spec"; then + $show "${rm}r $gentop" + $run ${rm}r "$gentop" + fi + fi + + exit $EXIT_SUCCESS + fi + + # Create links to the real library. + for linkname in $linknames; do + if test "$realname" != "$linkname"; then + $show "(cd $output_objdir && $rm $linkname && $LN_S $realname $linkname)" + $run eval '(cd $output_objdir && $rm $linkname && $LN_S $realname $linkname)' || exit $? + fi + done + + # If -module or -export-dynamic was specified, set the dlname. + if test "$module" = yes || test "$export_dynamic" = yes; then + # On all known operating systems, these are identical. + dlname="$soname" + fi + fi + ;; + + obj) + if test -n "$deplibs"; then + $echo "$modename: warning: \`-l' and \`-L' are ignored for objects" 1>&2 + fi + + if test -n "$dlfiles$dlprefiles" || test "$dlself" != no; then + $echo "$modename: warning: \`-dlopen' is ignored for objects" 1>&2 + fi + + if test -n "$rpath"; then + $echo "$modename: warning: \`-rpath' is ignored for objects" 1>&2 + fi + + if test -n "$xrpath"; then + $echo "$modename: warning: \`-R' is ignored for objects" 1>&2 + fi + + if test -n "$vinfo"; then + $echo "$modename: warning: \`-version-info' is ignored for objects" 1>&2 + fi + + if test -n "$release"; then + $echo "$modename: warning: \`-release' is ignored for objects" 1>&2 + fi + + case $output in + *.lo) + if test -n "$objs$old_deplibs"; then + $echo "$modename: cannot build library object \`$output' from non-libtool objects" 1>&2 + exit $EXIT_FAILURE + fi + libobj="$output" + obj=`$echo "X$output" | $Xsed -e "$lo2o"` + ;; + *) + libobj= + obj="$output" + ;; + esac + + # Delete the old objects. + $run $rm $obj $libobj + + # Objects from convenience libraries. This assumes + # single-version convenience libraries. Whenever we create + # different ones for PIC/non-PIC, this we'll have to duplicate + # the extraction. + reload_conv_objs= + gentop= + # reload_cmds runs $LD directly, so let us get rid of + # -Wl from whole_archive_flag_spec and hope we can get by with + # turning comma into space.. + wl= + + if test -n "$convenience"; then + if test -n "$whole_archive_flag_spec"; then + eval tmp_whole_archive_flags=\"$whole_archive_flag_spec\" + reload_conv_objs=$reload_objs\ `$echo "X$tmp_whole_archive_flags" | $Xsed -e 's|,| |g'` + else + gentop="$output_objdir/${obj}x" + generated="$generated $gentop" + + func_extract_archives $gentop $convenience + reload_conv_objs="$reload_objs $func_extract_archives_result" + fi + fi + + # Create the old-style object. + reload_objs="$objs$old_deplibs "`$echo "X$libobjs" | $SP2NL | $Xsed -e '/\.'${libext}$'/d' -e '/\.lib$/d' -e "$lo2o" | $NL2SP`" $reload_conv_objs" ### testsuite: skip nested quoting test + + output="$obj" + cmds=$reload_cmds + save_ifs="$IFS"; IFS='~' + for cmd in $cmds; do + IFS="$save_ifs" + eval cmd=\"$cmd\" + $show "$cmd" + $run eval "$cmd" || exit $? + done + IFS="$save_ifs" + + # Exit if we aren't doing a library object file. + if test -z "$libobj"; then + if test -n "$gentop"; then + $show "${rm}r $gentop" + $run ${rm}r $gentop + fi + + exit $EXIT_SUCCESS + fi + + if test "$build_libtool_libs" != yes; then + if test -n "$gentop"; then + $show "${rm}r $gentop" + $run ${rm}r $gentop + fi + + # Create an invalid libtool object if no PIC, so that we don't + # accidentally link it into a program. + # $show "echo timestamp > $libobj" + # $run eval "echo timestamp > $libobj" || exit $? + exit $EXIT_SUCCESS + fi + + if test -n "$pic_flag" || test "$pic_mode" != default; then + # Only do commands if we really have different PIC objects. + reload_objs="$libobjs $reload_conv_objs" + output="$libobj" + cmds=$reload_cmds + save_ifs="$IFS"; IFS='~' + for cmd in $cmds; do + IFS="$save_ifs" + eval cmd=\"$cmd\" + $show "$cmd" + $run eval "$cmd" || exit $? + done + IFS="$save_ifs" + fi + + if test -n "$gentop"; then + $show "${rm}r $gentop" + $run ${rm}r $gentop + fi + + exit $EXIT_SUCCESS + ;; + + prog) + case $host in + *cygwin*) output=`$echo $output | ${SED} -e 's,.exe$,,;s,$,.exe,'` ;; + esac + if test -n "$vinfo"; then + $echo "$modename: warning: \`-version-info' is ignored for programs" 1>&2 + fi + + if test -n "$release"; then + $echo "$modename: warning: \`-release' is ignored for programs" 1>&2 + fi + + if test "$preload" = yes; then + if test "$dlopen_support" = unknown && test "$dlopen_self" = unknown && + test "$dlopen_self_static" = unknown; then + $echo "$modename: warning: \`AC_LIBTOOL_DLOPEN' not used. Assuming no dlopen support." + fi + fi + + case $host in + *-*-rhapsody* | *-*-darwin1.[012]) + # On Rhapsody replace the C library is the System framework + compile_deplibs=`$echo "X $compile_deplibs" | $Xsed -e 's/ -lc / -framework System /'` + finalize_deplibs=`$echo "X $finalize_deplibs" | $Xsed -e 's/ -lc / -framework System /'` + ;; + esac + + case $host in + *darwin*) + # Don't allow lazy linking, it breaks C++ global constructors + if test "$tagname" = CXX ; then + compile_command="$compile_command ${wl}-bind_at_load" + finalize_command="$finalize_command ${wl}-bind_at_load" + fi + ;; + esac + + + # move library search paths that coincide with paths to not yet + # installed libraries to the beginning of the library search list + new_libs= + for path in $notinst_path; do + case " $new_libs " in + *" -L$path/$objdir "*) ;; + *) + case " $compile_deplibs " in + *" -L$path/$objdir "*) + new_libs="$new_libs -L$path/$objdir" ;; + esac + ;; + esac + done + for deplib in $compile_deplibs; do + case $deplib in + -L*) + case " $new_libs " in + *" $deplib "*) ;; + *) new_libs="$new_libs $deplib" ;; + esac + ;; + *) new_libs="$new_libs $deplib" ;; + esac + done + compile_deplibs="$new_libs" + + + compile_command="$compile_command $compile_deplibs" + finalize_command="$finalize_command $finalize_deplibs" + + if test -n "$rpath$xrpath"; then + # If the user specified any rpath flags, then add them. + for libdir in $rpath $xrpath; do + # This is the magic to use -rpath. + case "$finalize_rpath " in + *" $libdir "*) ;; + *) finalize_rpath="$finalize_rpath $libdir" ;; + esac + done + fi + + # Now hardcode the library paths + rpath= + hardcode_libdirs= + for libdir in $compile_rpath $finalize_rpath; do + if test -n "$hardcode_libdir_flag_spec"; then + if test -n "$hardcode_libdir_separator"; then + if test -z "$hardcode_libdirs"; then + hardcode_libdirs="$libdir" + else + # Just accumulate the unique libdirs. + case $hardcode_libdir_separator$hardcode_libdirs$hardcode_libdir_separator in + *"$hardcode_libdir_separator$libdir$hardcode_libdir_separator"*) + ;; + *) + hardcode_libdirs="$hardcode_libdirs$hardcode_libdir_separator$libdir" + ;; + esac + fi + else + eval flag=\"$hardcode_libdir_flag_spec\" + rpath="$rpath $flag" + fi + elif test -n "$runpath_var"; then + case "$perm_rpath " in + *" $libdir "*) ;; + *) perm_rpath="$perm_rpath $libdir" ;; + esac + fi + case $host in + *-*-cygwin* | *-*-mingw* | *-*-pw32* | *-*-os2*) + testbindir=`$echo "X$libdir" | $Xsed -e 's*/lib$*/bin*'` + case :$dllsearchpath: in + *":$libdir:"*) ;; + *) dllsearchpath="$dllsearchpath:$libdir";; + esac + case :$dllsearchpath: in + *":$testbindir:"*) ;; + *) dllsearchpath="$dllsearchpath:$testbindir";; + esac + ;; + esac + done + # Substitute the hardcoded libdirs into the rpath. + if test -n "$hardcode_libdir_separator" && + test -n "$hardcode_libdirs"; then + libdir="$hardcode_libdirs" + eval rpath=\" $hardcode_libdir_flag_spec\" + fi + compile_rpath="$rpath" + + rpath= + hardcode_libdirs= + for libdir in $finalize_rpath; do + if test -n "$hardcode_libdir_flag_spec"; then + if test -n "$hardcode_libdir_separator"; then + if test -z "$hardcode_libdirs"; then + hardcode_libdirs="$libdir" + else + # Just accumulate the unique libdirs. + case $hardcode_libdir_separator$hardcode_libdirs$hardcode_libdir_separator in + *"$hardcode_libdir_separator$libdir$hardcode_libdir_separator"*) + ;; + *) + hardcode_libdirs="$hardcode_libdirs$hardcode_libdir_separator$libdir" + ;; + esac + fi + else + eval flag=\"$hardcode_libdir_flag_spec\" + rpath="$rpath $flag" + fi + elif test -n "$runpath_var"; then + case "$finalize_perm_rpath " in + *" $libdir "*) ;; + *) finalize_perm_rpath="$finalize_perm_rpath $libdir" ;; + esac + fi + done + # Substitute the hardcoded libdirs into the rpath. + if test -n "$hardcode_libdir_separator" && + test -n "$hardcode_libdirs"; then + libdir="$hardcode_libdirs" + eval rpath=\" $hardcode_libdir_flag_spec\" + fi + finalize_rpath="$rpath" + + if test -n "$libobjs" && test "$build_old_libs" = yes; then + # Transform all the library objects into standard objects. + compile_command=`$echo "X$compile_command" | $SP2NL | $Xsed -e "$lo2o" | $NL2SP` + finalize_command=`$echo "X$finalize_command" | $SP2NL | $Xsed -e "$lo2o" | $NL2SP` + fi + + dlsyms= + if test -n "$dlfiles$dlprefiles" || test "$dlself" != no; then + if test -n "$NM" && test -n "$global_symbol_pipe"; then + dlsyms="${outputname}S.c" + else + $echo "$modename: not configured to extract global symbols from dlpreopened files" 1>&2 + fi + fi + + if test -n "$dlsyms"; then + case $dlsyms in + "") ;; + *.c) + # Discover the nlist of each of the dlfiles. + nlist="$output_objdir/${outputname}.nm" + + $show "$rm $nlist ${nlist}S ${nlist}T" + $run $rm "$nlist" "${nlist}S" "${nlist}T" + + # Parse the name list into a source file. + $show "creating $output_objdir/$dlsyms" + + test -z "$run" && $echo > "$output_objdir/$dlsyms" "\ +/* $dlsyms - symbol resolution table for \`$outputname' dlsym emulation. */ +/* Generated by $PROGRAM - GNU $PACKAGE $VERSION$TIMESTAMP */ + +#ifdef __cplusplus +extern \"C\" { +#endif + +/* Prevent the only kind of declaration conflicts we can make. */ +#define lt_preloaded_symbols some_other_symbol + +/* External symbol declarations for the compiler. */\ +" + + if test "$dlself" = yes; then + $show "generating symbol list for \`$output'" + + test -z "$run" && $echo ': @PROGRAM@ ' > "$nlist" + + # Add our own program objects to the symbol list. + progfiles=`$echo "X$objs$old_deplibs" | $SP2NL | $Xsed -e "$lo2o" | $NL2SP` + for arg in $progfiles; do + $show "extracting global C symbols from \`$arg'" + $run eval "$NM $arg | $global_symbol_pipe >> '$nlist'" + done + + if test -n "$exclude_expsyms"; then + $run eval '$EGREP -v " ($exclude_expsyms)$" "$nlist" > "$nlist"T' + $run eval '$mv "$nlist"T "$nlist"' + fi + + if test -n "$export_symbols_regex"; then + $run eval '$EGREP -e "$export_symbols_regex" "$nlist" > "$nlist"T' + $run eval '$mv "$nlist"T "$nlist"' + fi + + # Prepare the list of exported symbols + if test -z "$export_symbols"; then + export_symbols="$output_objdir/$outputname.exp" + $run $rm $export_symbols + $run eval "${SED} -n -e '/^: @PROGRAM@ $/d' -e 's/^.* \(.*\)$/\1/p' "'< "$nlist" > "$export_symbols"' + case $host in + *cygwin* | *mingw* ) + $run eval "echo EXPORTS "'> "$output_objdir/$outputname.def"' + $run eval 'cat "$export_symbols" >> "$output_objdir/$outputname.def"' + ;; + esac + else + $run eval "${SED} -e 's/\([].[*^$]\)/\\\\\1/g' -e 's/^/ /' -e 's/$/$/'"' < "$export_symbols" > "$output_objdir/$outputname.exp"' + $run eval 'grep -f "$output_objdir/$outputname.exp" < "$nlist" > "$nlist"T' + $run eval 'mv "$nlist"T "$nlist"' + case $host in + *cygwin* | *mingw* ) + $run eval "echo EXPORTS "'> "$output_objdir/$outputname.def"' + $run eval 'cat "$nlist" >> "$output_objdir/$outputname.def"' + ;; + esac + fi + fi + + for arg in $dlprefiles; do + $show "extracting global C symbols from \`$arg'" + name=`$echo "$arg" | ${SED} -e 's%^.*/%%'` + $run eval '$echo ": $name " >> "$nlist"' + $run eval "$NM $arg | $global_symbol_pipe >> '$nlist'" + done + + if test -z "$run"; then + # Make sure we have at least an empty file. + test -f "$nlist" || : > "$nlist" + + if test -n "$exclude_expsyms"; then + $EGREP -v " ($exclude_expsyms)$" "$nlist" > "$nlist"T + $mv "$nlist"T "$nlist" + fi + + # Try sorting and uniquifying the output. + if grep -v "^: " < "$nlist" | + if sort -k 3 </dev/null >/dev/null 2>&1; then + sort -k 3 + else + sort +2 + fi | + uniq > "$nlist"S; then + : + else + grep -v "^: " < "$nlist" > "$nlist"S + fi + + if test -f "$nlist"S; then + eval "$global_symbol_to_cdecl"' < "$nlist"S >> "$output_objdir/$dlsyms"' + else + $echo '/* NONE */' >> "$output_objdir/$dlsyms" + fi + + $echo >> "$output_objdir/$dlsyms" "\ + +#undef lt_preloaded_symbols + +#if defined (__STDC__) && __STDC__ +# define lt_ptr void * +#else +# define lt_ptr char * +# define const +#endif + +/* The mapping between symbol names and symbols. */ +" + + case $host in + *cygwin* | *mingw* ) + $echo >> "$output_objdir/$dlsyms" "\ +/* DATA imports from DLLs on WIN32 can't be const, because + runtime relocations are performed -- see ld's documentation + on pseudo-relocs */ +struct { +" + ;; + * ) + $echo >> "$output_objdir/$dlsyms" "\ +const struct { +" + ;; + esac + + + $echo >> "$output_objdir/$dlsyms" "\ + const char *name; + lt_ptr address; +} +lt_preloaded_symbols[] = +{\ +" + + eval "$global_symbol_to_c_name_address" < "$nlist" >> "$output_objdir/$dlsyms" + + $echo >> "$output_objdir/$dlsyms" "\ + {0, (lt_ptr) 0} +}; + +/* This works around a problem in FreeBSD linker */ +#ifdef FREEBSD_WORKAROUND +static const void *lt_preloaded_setup() { + return lt_preloaded_symbols; +} +#endif + +#ifdef __cplusplus +} +#endif\ +" + fi + + pic_flag_for_symtable= + case $host in + # compiling the symbol table file with pic_flag works around + # a FreeBSD bug that causes programs to crash when -lm is + # linked before any other PIC object. But we must not use + # pic_flag when linking with -static. The problem exists in + # FreeBSD 2.2.6 and is fixed in FreeBSD 3.1. + *-*-freebsd2*|*-*-freebsd3.0*|*-*-freebsdelf3.0*) + case "$compile_command " in + *" -static "*) ;; + *) pic_flag_for_symtable=" $pic_flag -DFREEBSD_WORKAROUND";; + esac;; + *-*-hpux*) + case "$compile_command " in + *" -static "*) ;; + *) pic_flag_for_symtable=" $pic_flag";; + esac + esac + + # Now compile the dynamic symbol file. + $show "(cd $output_objdir && $LTCC $LTCFLAGS -c$no_builtin_flag$pic_flag_for_symtable \"$dlsyms\")" + $run eval '(cd $output_objdir && $LTCC $LTCFLAGS -c$no_builtin_flag$pic_flag_for_symtable "$dlsyms")' || exit $? + + # Clean up the generated files. + $show "$rm $output_objdir/$dlsyms $nlist ${nlist}S ${nlist}T" + $run $rm "$output_objdir/$dlsyms" "$nlist" "${nlist}S" "${nlist}T" + + # Transform the symbol file into the correct name. + case $host in + *cygwin* | *mingw* ) + if test -f "$output_objdir/${outputname}.def" ; then + compile_command=`$echo "X$compile_command" | $SP2NL | $Xsed -e "s%@SYMFILE@%$output_objdir/${outputname}.def $output_objdir/${outputname}S.${objext}%" | $NL2SP` + finalize_command=`$echo "X$finalize_command" | $SP2NL | $Xsed -e "s%@SYMFILE@%$output_objdir/${outputname}.def $output_objdir/${outputname}S.${objext}%" | $NL2SP` + else + compile_command=`$echo "X$compile_command" | $SP2NL | $Xsed -e "s%@SYMFILE@%$output_objdir/${outputname}S.${objext}%" | $NL2SP` + finalize_command=`$echo "X$finalize_command" | $SP2NL | $Xsed -e "s%@SYMFILE@%$output_objdir/${outputname}S.${objext}%" | $NL2SP` + fi + ;; + * ) + compile_command=`$echo "X$compile_command" | $SP2NL | $Xsed -e "s%@SYMFILE@%$output_objdir/${outputname}S.${objext}%" | $NL2SP` + finalize_command=`$echo "X$finalize_command" | $SP2NL | $Xsed -e "s%@SYMFILE@%$output_objdir/${outputname}S.${objext}%" | $NL2SP` + ;; + esac + ;; + *) + $echo "$modename: unknown suffix for \`$dlsyms'" 1>&2 + exit $EXIT_FAILURE + ;; + esac + else + # We keep going just in case the user didn't refer to + # lt_preloaded_symbols. The linker will fail if global_symbol_pipe + # really was required. + + # Nullify the symbol file. + compile_command=`$echo "X$compile_command" | $SP2NL | $Xsed -e "s% @SYMFILE@%%" | $NL2SP` + finalize_command=`$echo "X$finalize_command" | $SP2NL | $Xsed -e "s% @SYMFILE@%%" | $NL2SP` + fi + + if test "$need_relink" = no || test "$build_libtool_libs" != yes; then + # Replace the output file specification. + compile_command=`$echo "X$compile_command" | $SP2NL | $Xsed -e 's%@OUTPUT@%'"$output"'%g' | $NL2SP` + link_command="$compile_command$compile_rpath" + + # We have no uninstalled library dependencies, so finalize right now. + $show "$link_command" + $run eval "$link_command" + exit_status=$? + + # Delete the generated files. + if test -n "$dlsyms"; then + $show "$rm $output_objdir/${outputname}S.${objext}" + $run $rm "$output_objdir/${outputname}S.${objext}" + fi + + exit $exit_status + fi + + if test -n "$shlibpath_var"; then + # We should set the shlibpath_var + rpath= + for dir in $temp_rpath; do + case $dir in + [\\/]* | [A-Za-z]:[\\/]*) + # Absolute path. + rpath="$rpath$dir:" + ;; + *) + # Relative path: add a thisdir entry. + rpath="$rpath\$thisdir/$dir:" + ;; + esac + done + temp_rpath="$rpath" + fi + + if test -n "$compile_shlibpath$finalize_shlibpath"; then + compile_command="$shlibpath_var=\"$compile_shlibpath$finalize_shlibpath\$$shlibpath_var\" $compile_command" + fi + if test -n "$finalize_shlibpath"; then + finalize_command="$shlibpath_var=\"$finalize_shlibpath\$$shlibpath_var\" $finalize_command" + fi + + compile_var= + finalize_var= + if test -n "$runpath_var"; then + if test -n "$perm_rpath"; then + # We should set the runpath_var. + rpath= + for dir in $perm_rpath; do + rpath="$rpath$dir:" + done + compile_var="$runpath_var=\"$rpath\$$runpath_var\" " + fi + if test -n "$finalize_perm_rpath"; then + # We should set the runpath_var. + rpath= + for dir in $finalize_perm_rpath; do + rpath="$rpath$dir:" + done + finalize_var="$runpath_var=\"$rpath\$$runpath_var\" " + fi + fi + + if test "$no_install" = yes; then + # We don't need to create a wrapper script. + link_command="$compile_var$compile_command$compile_rpath" + # Replace the output file specification. + link_command=`$echo "X$link_command" | $Xsed -e 's%@OUTPUT@%'"$output"'%g'` + # Delete the old output file. + $run $rm $output + # Link the executable and exit + $show "$link_command" + $run eval "$link_command" || exit $? + exit $EXIT_SUCCESS + fi + + if test "$hardcode_action" = relink; then + # Fast installation is not supported + link_command="$compile_var$compile_command$compile_rpath" + relink_command="$finalize_var$finalize_command$finalize_rpath" + + $echo "$modename: warning: this platform does not like uninstalled shared libraries" 1>&2 + $echo "$modename: \`$output' will be relinked during installation" 1>&2 + else + if test "$fast_install" != no; then + link_command="$finalize_var$compile_command$finalize_rpath" + if test "$fast_install" = yes; then + relink_command=`$echo "X$compile_var$compile_command$compile_rpath" | $SP2NL | $Xsed -e 's%@OUTPUT@%\$progdir/\$file%g' | $NL2SP` + else + # fast_install is set to needless + relink_command= + fi + else + link_command="$compile_var$compile_command$compile_rpath" + relink_command="$finalize_var$finalize_command$finalize_rpath" + fi + fi + + # Replace the output file specification. + link_command=`$echo "X$link_command" | $Xsed -e 's%@OUTPUT@%'"$output_objdir/$outputname"'%g'` + + # Delete the old output files. + $run $rm $output $output_objdir/$outputname $output_objdir/lt-$outputname + + $show "$link_command" + $run eval "$link_command" || exit $? + + # Now create the wrapper script. + $show "creating $output" + + # Quote the relink command for shipping. + if test -n "$relink_command"; then + # Preserve any variables that may affect compiler behavior + for var in $variables_saved_for_relink; do + if eval test -z \"\${$var+set}\"; then + relink_command="{ test -z \"\${$var+set}\" || unset $var || { $var=; export $var; }; }; $relink_command" + elif eval var_value=\$$var; test -z "$var_value"; then + relink_command="$var=; export $var; $relink_command" + else + var_value=`$echo "X$var_value" | $Xsed -e "$sed_quote_subst"` + relink_command="$var=\"$var_value\"; export $var; $relink_command" + fi + done + relink_command="(cd `pwd`; $relink_command)" + relink_command=`$echo "X$relink_command" | $SP2NL | $Xsed -e "$sed_quote_subst" | $NL2SP` + fi + + # Quote $echo for shipping. + if test "X$echo" = "X$SHELL $progpath --fallback-echo"; then + case $progpath in + [\\/]* | [A-Za-z]:[\\/]*) qecho="$SHELL $progpath --fallback-echo";; + *) qecho="$SHELL `pwd`/$progpath --fallback-echo";; + esac + qecho=`$echo "X$qecho" | $Xsed -e "$sed_quote_subst"` + else + qecho=`$echo "X$echo" | $Xsed -e "$sed_quote_subst"` + fi + + # Only actually do things if our run command is non-null. + if test -z "$run"; then + # win32 will think the script is a binary if it has + # a .exe suffix, so we strip it off here. + case $output in + *.exe) output=`$echo $output|${SED} 's,.exe$,,'` ;; + esac + # test for cygwin because mv fails w/o .exe extensions + case $host in + *cygwin*) + exeext=.exe + outputname=`$echo $outputname|${SED} 's,.exe$,,'` ;; + *) exeext= ;; + esac + case $host in + *cygwin* | *mingw* ) + output_name=`basename $output` + output_path=`dirname $output` + cwrappersource="$output_path/$objdir/lt-$output_name.c" + cwrapper="$output_path/$output_name.exe" + $rm $cwrappersource $cwrapper + trap "$rm $cwrappersource $cwrapper; exit $EXIT_FAILURE" 1 2 15 + + cat > $cwrappersource <<EOF + +/* $cwrappersource - temporary wrapper executable for $objdir/$outputname + Generated by $PROGRAM - GNU $PACKAGE $VERSION$TIMESTAMP + + The $output program cannot be directly executed until all the libtool + libraries that it depends on are installed. + + This wrapper executable should never be moved out of the build directory. + If it is, it will not operate correctly. + + Currently, it simply execs the wrapper *script* "/bin/sh $output", + but could eventually absorb all of the scripts functionality and + exec $objdir/$outputname directly. +*/ +EOF + cat >> $cwrappersource<<"EOF" +#include <stdio.h> +#include <stdlib.h> +#include <unistd.h> +#include <malloc.h> +#include <stdarg.h> +#include <assert.h> +#include <string.h> +#include <ctype.h> +#include <sys/stat.h> + +#if defined(PATH_MAX) +# define LT_PATHMAX PATH_MAX +#elif defined(MAXPATHLEN) +# define LT_PATHMAX MAXPATHLEN +#else +# define LT_PATHMAX 1024 +#endif + +#ifndef DIR_SEPARATOR +# define DIR_SEPARATOR '/' +# define PATH_SEPARATOR ':' +#endif + +#if defined (_WIN32) || defined (__MSDOS__) || defined (__DJGPP__) || \ + defined (__OS2__) +# define HAVE_DOS_BASED_FILE_SYSTEM +# ifndef DIR_SEPARATOR_2 +# define DIR_SEPARATOR_2 '\\' +# endif +# ifndef PATH_SEPARATOR_2 +# define PATH_SEPARATOR_2 ';' +# endif +#endif + +#ifndef DIR_SEPARATOR_2 +# define IS_DIR_SEPARATOR(ch) ((ch) == DIR_SEPARATOR) +#else /* DIR_SEPARATOR_2 */ +# define IS_DIR_SEPARATOR(ch) \ + (((ch) == DIR_SEPARATOR) || ((ch) == DIR_SEPARATOR_2)) +#endif /* DIR_SEPARATOR_2 */ + +#ifndef PATH_SEPARATOR_2 +# define IS_PATH_SEPARATOR(ch) ((ch) == PATH_SEPARATOR) +#else /* PATH_SEPARATOR_2 */ +# define IS_PATH_SEPARATOR(ch) ((ch) == PATH_SEPARATOR_2) +#endif /* PATH_SEPARATOR_2 */ + +#define XMALLOC(type, num) ((type *) xmalloc ((num) * sizeof(type))) +#define XFREE(stale) do { \ + if (stale) { free ((void *) stale); stale = 0; } \ +} while (0) + +/* -DDEBUG is fairly common in CFLAGS. */ +#undef DEBUG +#if defined DEBUGWRAPPER +# define DEBUG(format, ...) fprintf(stderr, format, __VA_ARGS__) +#else +# define DEBUG(format, ...) +#endif + +const char *program_name = NULL; + +void * xmalloc (size_t num); +char * xstrdup (const char *string); +const char * base_name (const char *name); +char * find_executable(const char *wrapper); +int check_executable(const char *path); +char * strendzap(char *str, const char *pat); +void lt_fatal (const char *message, ...); + +int +main (int argc, char *argv[]) +{ + char **newargz; + int i; + + program_name = (char *) xstrdup (base_name (argv[0])); + DEBUG("(main) argv[0] : %s\n",argv[0]); + DEBUG("(main) program_name : %s\n",program_name); + newargz = XMALLOC(char *, argc+2); +EOF + + cat >> $cwrappersource <<EOF + newargz[0] = (char *) xstrdup("$SHELL"); +EOF + + cat >> $cwrappersource <<"EOF" + newargz[1] = find_executable(argv[0]); + if (newargz[1] == NULL) + lt_fatal("Couldn't find %s", argv[0]); + DEBUG("(main) found exe at : %s\n",newargz[1]); + /* we know the script has the same name, without the .exe */ + /* so make sure newargz[1] doesn't end in .exe */ + strendzap(newargz[1],".exe"); + for (i = 1; i < argc; i++) + newargz[i+1] = xstrdup(argv[i]); + newargz[argc+1] = NULL; + + for (i=0; i<argc+1; i++) + { + DEBUG("(main) newargz[%d] : %s\n",i,newargz[i]); + ; + } + +EOF + + case $host_os in + mingw*) + cat >> $cwrappersource <<EOF + execv("$SHELL",(char const **)newargz); +EOF + ;; + *) + cat >> $cwrappersource <<EOF + execv("$SHELL",newargz); +EOF + ;; + esac + + cat >> $cwrappersource <<"EOF" + return 127; +} + +void * +xmalloc (size_t num) +{ + void * p = (void *) malloc (num); + if (!p) + lt_fatal ("Memory exhausted"); + + return p; +} + +char * +xstrdup (const char *string) +{ + return string ? strcpy ((char *) xmalloc (strlen (string) + 1), string) : NULL +; +} + +const char * +base_name (const char *name) +{ + const char *base; + +#if defined (HAVE_DOS_BASED_FILE_SYSTEM) + /* Skip over the disk name in MSDOS pathnames. */ + if (isalpha ((unsigned char)name[0]) && name[1] == ':') + name += 2; +#endif + + for (base = name; *name; name++) + if (IS_DIR_SEPARATOR (*name)) + base = name + 1; + return base; +} + +int +check_executable(const char * path) +{ + struct stat st; + + DEBUG("(check_executable) : %s\n", path ? (*path ? path : "EMPTY!") : "NULL!"); + if ((!path) || (!*path)) + return 0; + + if ((stat (path, &st) >= 0) && + ( + /* MinGW & native WIN32 do not support S_IXOTH or S_IXGRP */ +#if defined (S_IXOTH) + ((st.st_mode & S_IXOTH) == S_IXOTH) || +#endif +#if defined (S_IXGRP) + ((st.st_mode & S_IXGRP) == S_IXGRP) || +#endif + ((st.st_mode & S_IXUSR) == S_IXUSR)) + ) + return 1; + else + return 0; +} + +/* Searches for the full path of the wrapper. Returns + newly allocated full path name if found, NULL otherwise */ +char * +find_executable (const char* wrapper) +{ + int has_slash = 0; + const char* p; + const char* p_next; + /* static buffer for getcwd */ + char tmp[LT_PATHMAX + 1]; + int tmp_len; + char* concat_name; + + DEBUG("(find_executable) : %s\n", wrapper ? (*wrapper ? wrapper : "EMPTY!") : "NULL!"); + + if ((wrapper == NULL) || (*wrapper == '\0')) + return NULL; + + /* Absolute path? */ +#if defined (HAVE_DOS_BASED_FILE_SYSTEM) + if (isalpha ((unsigned char)wrapper[0]) && wrapper[1] == ':') + { + concat_name = xstrdup (wrapper); + if (check_executable(concat_name)) + return concat_name; + XFREE(concat_name); + } + else + { +#endif + if (IS_DIR_SEPARATOR (wrapper[0])) + { + concat_name = xstrdup (wrapper); + if (check_executable(concat_name)) + return concat_name; + XFREE(concat_name); + } +#if defined (HAVE_DOS_BASED_FILE_SYSTEM) + } +#endif + + for (p = wrapper; *p; p++) + if (*p == '/') + { + has_slash = 1; + break; + } + if (!has_slash) + { + /* no slashes; search PATH */ + const char* path = getenv ("PATH"); + if (path != NULL) + { + for (p = path; *p; p = p_next) + { + const char* q; + size_t p_len; + for (q = p; *q; q++) + if (IS_PATH_SEPARATOR(*q)) + break; + p_len = q - p; + p_next = (*q == '\0' ? q : q + 1); + if (p_len == 0) + { + /* empty path: current directory */ + if (getcwd (tmp, LT_PATHMAX) == NULL) + lt_fatal ("getcwd failed"); + tmp_len = strlen(tmp); + concat_name = XMALLOC(char, tmp_len + 1 + strlen(wrapper) + 1); + memcpy (concat_name, tmp, tmp_len); + concat_name[tmp_len] = '/'; + strcpy (concat_name + tmp_len + 1, wrapper); + } + else + { + concat_name = XMALLOC(char, p_len + 1 + strlen(wrapper) + 1); + memcpy (concat_name, p, p_len); + concat_name[p_len] = '/'; + strcpy (concat_name + p_len + 1, wrapper); + } + if (check_executable(concat_name)) + return concat_name; + XFREE(concat_name); + } + } + /* not found in PATH; assume curdir */ + } + /* Relative path | not found in path: prepend cwd */ + if (getcwd (tmp, LT_PATHMAX) == NULL) + lt_fatal ("getcwd failed"); + tmp_len = strlen(tmp); + concat_name = XMALLOC(char, tmp_len + 1 + strlen(wrapper) + 1); + memcpy (concat_name, tmp, tmp_len); + concat_name[tmp_len] = '/'; + strcpy (concat_name + tmp_len + 1, wrapper); + + if (check_executable(concat_name)) + return concat_name; + XFREE(concat_name); + return NULL; +} + +char * +strendzap(char *str, const char *pat) +{ + size_t len, patlen; + + assert(str != NULL); + assert(pat != NULL); + + len = strlen(str); + patlen = strlen(pat); + + if (patlen <= len) + { + str += len - patlen; + if (strcmp(str, pat) == 0) + *str = '\0'; + } + return str; +} + +static void +lt_error_core (int exit_status, const char * mode, + const char * message, va_list ap) +{ + fprintf (stderr, "%s: %s: ", program_name, mode); + vfprintf (stderr, message, ap); + fprintf (stderr, ".\n"); + + if (exit_status >= 0) + exit (exit_status); +} + +void +lt_fatal (const char *message, ...) +{ + va_list ap; + va_start (ap, message); + lt_error_core (EXIT_FAILURE, "FATAL", message, ap); + va_end (ap); +} +EOF + # we should really use a build-platform specific compiler + # here, but OTOH, the wrappers (shell script and this C one) + # are only useful if you want to execute the "real" binary. + # Since the "real" binary is built for $host, then this + # wrapper might as well be built for $host, too. + $run $LTCC $LTCFLAGS -s -o $cwrapper $cwrappersource + ;; + esac + $rm $output + trap "$rm $output; exit $EXIT_FAILURE" 1 2 15 + + $echo > $output "\ +#! $SHELL + +# $output - temporary wrapper script for $objdir/$outputname +# Generated by $PROGRAM - GNU $PACKAGE $VERSION$TIMESTAMP +# +# The $output program cannot be directly executed until all the libtool +# libraries that it depends on are installed. +# +# This wrapper script should never be moved out of the build directory. +# If it is, it will not operate correctly. + +# Sed substitution that helps us do robust quoting. It backslashifies +# metacharacters that are still active within double-quoted strings. +Xsed='${SED} -e 1s/^X//' +sed_quote_subst='$sed_quote_subst' + +# Be Bourne compatible (taken from Autoconf:_AS_BOURNE_COMPATIBLE). +if test -n \"\${ZSH_VERSION+set}\" && (emulate sh) >/dev/null 2>&1; then + emulate sh + NULLCMD=: + # Zsh 3.x and 4.x performs word splitting on \${1+\"\$@\"}, which + # is contrary to our usage. Disable this feature. + alias -g '\${1+\"\$@\"}'='\"\$@\"' + setopt NO_GLOB_SUBST +else + case \`(set -o) 2>/dev/null\` in *posix*) set -o posix;; esac +fi + +# The HP-UX ksh and POSIX shell print the target directory to stdout +# if CDPATH is set. +(unset CDPATH) >/dev/null 2>&1 && unset CDPATH + +relink_command=\"$relink_command\" + +# This environment variable determines our operation mode. +if test \"\$libtool_install_magic\" = \"$magic\"; then + # install mode needs the following variable: + notinst_deplibs='$notinst_deplibs' +else + # When we are sourced in execute mode, \$file and \$echo are already set. + if test \"\$libtool_execute_magic\" != \"$magic\"; then + echo=\"$qecho\" + file=\"\$0\" + # Make sure echo works. + if test \"X\$1\" = X--no-reexec; then + # Discard the --no-reexec flag, and continue. + shift + elif test \"X\`(\$echo '\t') 2>/dev/null\`\" = 'X\t'; then + # Yippee, \$echo works! + : + else + # Restart under the correct shell, and then maybe \$echo will work. + exec $SHELL \"\$0\" --no-reexec \${1+\"\$@\"} + fi + fi\ +" + $echo >> $output "\ + + # Find the directory that this script lives in. + thisdir=\`\$echo \"X\$file\" | \$Xsed -e 's%/[^/]*$%%'\` + test \"x\$thisdir\" = \"x\$file\" && thisdir=. + + # Follow symbolic links until we get to the real thisdir. + file=\`ls -ld \"\$file\" | ${SED} -n 's/.*-> //p'\` + while test -n \"\$file\"; do + destdir=\`\$echo \"X\$file\" | \$Xsed -e 's%/[^/]*\$%%'\` + + # If there was a directory component, then change thisdir. + if test \"x\$destdir\" != \"x\$file\"; then + case \"\$destdir\" in + [\\\\/]* | [A-Za-z]:[\\\\/]*) thisdir=\"\$destdir\" ;; + *) thisdir=\"\$thisdir/\$destdir\" ;; + esac + fi + + file=\`\$echo \"X\$file\" | \$Xsed -e 's%^.*/%%'\` + file=\`ls -ld \"\$thisdir/\$file\" | ${SED} -n 's/.*-> //p'\` + done + + # Try to get the absolute directory name. + absdir=\`cd \"\$thisdir\" && pwd\` + test -n \"\$absdir\" && thisdir=\"\$absdir\" +" + + if test "$fast_install" = yes; then + $echo >> $output "\ + program=lt-'$outputname'$exeext + progdir=\"\$thisdir/$objdir\" + + if test ! -f \"\$progdir/\$program\" || \\ + { file=\`ls -1dt \"\$progdir/\$program\" \"\$progdir/../\$program\" 2>/dev/null | ${SED} 1q\`; \\ + test \"X\$file\" != \"X\$progdir/\$program\"; }; then + + file=\"\$\$-\$program\" + + if test ! -d \"\$progdir\"; then + $mkdir \"\$progdir\" + else + $rm \"\$progdir/\$file\" + fi" + + $echo >> $output "\ + + # relink executable if necessary + if test -n \"\$relink_command\"; then + if relink_command_output=\`eval \$relink_command 2>&1\`; then : + else + $echo \"\$relink_command_output\" >&2 + $rm \"\$progdir/\$file\" + exit $EXIT_FAILURE + fi + fi + + $mv \"\$progdir/\$file\" \"\$progdir/\$program\" 2>/dev/null || + { $rm \"\$progdir/\$program\"; + $mv \"\$progdir/\$file\" \"\$progdir/\$program\"; } + $rm \"\$progdir/\$file\" + fi" + else + $echo >> $output "\ + program='$outputname' + progdir=\"\$thisdir/$objdir\" +" + fi + + $echo >> $output "\ + + if test -f \"\$progdir/\$program\"; then" + + # Export our shlibpath_var if we have one. + if test "$shlibpath_overrides_runpath" = yes && test -n "$shlibpath_var" && test -n "$temp_rpath"; then + $echo >> $output "\ + # Add our own library path to $shlibpath_var + $shlibpath_var=\"$temp_rpath\$$shlibpath_var\" + + # Some systems cannot cope with colon-terminated $shlibpath_var + # The second colon is a workaround for a bug in BeOS R4 sed + $shlibpath_var=\`\$echo \"X\$$shlibpath_var\" | \$Xsed -e 's/::*\$//'\` + + export $shlibpath_var +" + fi + + # fixup the dll searchpath if we need to. + if test -n "$dllsearchpath"; then + $echo >> $output "\ + # Add the dll search path components to the executable PATH + PATH=$dllsearchpath:\$PATH +" + fi + + $echo >> $output "\ + if test \"\$libtool_execute_magic\" != \"$magic\"; then + # Run the actual program with our arguments. +" + case $host in + # Backslashes separate directories on plain windows + *-*-mingw | *-*-os2*) + $echo >> $output "\ + exec \"\$progdir\\\\\$program\" \${1+\"\$@\"} +" + ;; + + *) + $echo >> $output "\ + exec \"\$progdir/\$program\" \${1+\"\$@\"} +" + ;; + esac + $echo >> $output "\ + \$echo \"\$0: cannot exec \$program \$*\" + exit $EXIT_FAILURE + fi + else + # The program doesn't exist. + \$echo \"\$0: error: \\\`\$progdir/\$program' does not exist\" 1>&2 + \$echo \"This script is just a wrapper for \$program.\" 1>&2 + $echo \"See the $PACKAGE documentation for more information.\" 1>&2 + exit $EXIT_FAILURE + fi +fi\ +" + chmod +x $output + fi + exit $EXIT_SUCCESS + ;; + esac + + # See if we need to build an old-fashioned archive. + for oldlib in $oldlibs; do + + if test "$build_libtool_libs" = convenience; then + oldobjs="$libobjs_save" + addlibs="$convenience" + build_libtool_libs=no + else + if test "$build_libtool_libs" = module; then + oldobjs="$libobjs_save" + build_libtool_libs=no + else + oldobjs="$old_deplibs $non_pic_objects" + fi + addlibs="$old_convenience" + fi + + if test -n "$addlibs"; then + gentop="$output_objdir/${outputname}x" + generated="$generated $gentop" + + func_extract_archives $gentop $addlibs + oldobjs="$oldobjs $func_extract_archives_result" + fi + + # Do each command in the archive commands. + if test -n "$old_archive_from_new_cmds" && test "$build_libtool_libs" = yes; then + cmds=$old_archive_from_new_cmds + else + # POSIX demands no paths to be encoded in archives. We have + # to avoid creating archives with duplicate basenames if we + # might have to extract them afterwards, e.g., when creating a + # static archive out of a convenience library, or when linking + # the entirety of a libtool archive into another (currently + # not supported by libtool). + if (for obj in $oldobjs + do + $echo "X$obj" | $Xsed -e 's%^.*/%%' + done | sort | sort -uc >/dev/null 2>&1); then + : + else + $echo "copying selected object files to avoid basename conflicts..." + + if test -z "$gentop"; then + gentop="$output_objdir/${outputname}x" + generated="$generated $gentop" + + $show "${rm}r $gentop" + $run ${rm}r "$gentop" + $show "$mkdir $gentop" + $run $mkdir "$gentop" + exit_status=$? + if test "$exit_status" -ne 0 && test ! -d "$gentop"; then + exit $exit_status + fi + fi + + save_oldobjs=$oldobjs + oldobjs= + counter=1 + for obj in $save_oldobjs + do + objbase=`$echo "X$obj" | $Xsed -e 's%^.*/%%'` + case " $oldobjs " in + " ") oldobjs=$obj ;; + *[\ /]"$objbase "*) + while :; do + # Make sure we don't pick an alternate name that also + # overlaps. + newobj=lt$counter-$objbase + counter=`expr $counter + 1` + case " $oldobjs " in + *[\ /]"$newobj "*) ;; + *) if test ! -f "$gentop/$newobj"; then break; fi ;; + esac + done + $show "ln $obj $gentop/$newobj || cp $obj $gentop/$newobj" + $run ln "$obj" "$gentop/$newobj" || + $run cp "$obj" "$gentop/$newobj" + oldobjs="$oldobjs $gentop/$newobj" + ;; + *) oldobjs="$oldobjs $obj" ;; + esac + done + fi + + eval cmds=\"$old_archive_cmds\" + + if len=`expr "X$cmds" : ".*"` && + test "$len" -le "$max_cmd_len" || test "$max_cmd_len" -le -1; then + cmds=$old_archive_cmds + else + # the command line is too long to link in one step, link in parts + $echo "using piecewise archive linking..." + save_RANLIB=$RANLIB + RANLIB=: + objlist= + concat_cmds= + save_oldobjs=$oldobjs + + # Is there a better way of finding the last object in the list? + for obj in $save_oldobjs + do + last_oldobj=$obj + done + for obj in $save_oldobjs + do + oldobjs="$objlist $obj" + objlist="$objlist $obj" + eval test_cmds=\"$old_archive_cmds\" + if len=`expr "X$test_cmds" : ".*" 2>/dev/null` && + test "$len" -le "$max_cmd_len"; then + : + else + # the above command should be used before it gets too long + oldobjs=$objlist + if test "$obj" = "$last_oldobj" ; then + RANLIB=$save_RANLIB + fi + test -z "$concat_cmds" || concat_cmds=$concat_cmds~ + eval concat_cmds=\"\${concat_cmds}$old_archive_cmds\" + objlist= + fi + done + RANLIB=$save_RANLIB + oldobjs=$objlist + if test "X$oldobjs" = "X" ; then + eval cmds=\"\$concat_cmds\" + else + eval cmds=\"\$concat_cmds~\$old_archive_cmds\" + fi + fi + fi + save_ifs="$IFS"; IFS='~' + for cmd in $cmds; do + eval cmd=\"$cmd\" + IFS="$save_ifs" + $show "$cmd" + $run eval "$cmd" || exit $? + done + IFS="$save_ifs" + done + + if test -n "$generated"; then + $show "${rm}r$generated" + $run ${rm}r$generated + fi + + # Now create the libtool archive. + case $output in + *.la) + old_library= + test "$build_old_libs" = yes && old_library="$libname.$libext" + $show "creating $output" + + # Preserve any variables that may affect compiler behavior + for var in $variables_saved_for_relink; do + if eval test -z \"\${$var+set}\"; then + relink_command="{ test -z \"\${$var+set}\" || unset $var || { $var=; export $var; }; }; $relink_command" + elif eval var_value=\$$var; test -z "$var_value"; then + relink_command="$var=; export $var; $relink_command" + else + var_value=`$echo "X$var_value" | $Xsed -e "$sed_quote_subst"` + relink_command="$var=\"$var_value\"; export $var; $relink_command" + fi + done + # Quote the link command for shipping. + relink_command="(cd `pwd`; $SHELL $progpath $preserve_args --mode=relink $libtool_args @inst_prefix_dir@)" + relink_command=`$echo "X$relink_command" | $SP2NL | $Xsed -e "$sed_quote_subst" | $NL2SP` + if test "$hardcode_automatic" = yes ; then + relink_command= + fi + + + # Only create the output if not a dry run. + if test -z "$run"; then + for installed in no yes; do + if test "$installed" = yes; then + if test -z "$install_libdir"; then + break + fi + output="$output_objdir/$outputname"i + # Replace all uninstalled libtool libraries with the installed ones + newdependency_libs= + for deplib in $dependency_libs; do + case $deplib in + *.la) + name=`$echo "X$deplib" | $Xsed -e 's%^.*/%%'` + eval libdir=`${SED} -n -e 's/^libdir=\(.*\)$/\1/p' $deplib` + if test -z "$libdir"; then + $echo "$modename: \`$deplib' is not a valid libtool archive" 1>&2 + exit $EXIT_FAILURE + fi + newdependency_libs="$newdependency_libs $libdir/$name" + ;; + *) newdependency_libs="$newdependency_libs $deplib" ;; + esac + done + dependency_libs="$newdependency_libs" + newdlfiles= + for lib in $dlfiles; do + name=`$echo "X$lib" | $Xsed -e 's%^.*/%%'` + eval libdir=`${SED} -n -e 's/^libdir=\(.*\)$/\1/p' $lib` + if test -z "$libdir"; then + $echo "$modename: \`$lib' is not a valid libtool archive" 1>&2 + exit $EXIT_FAILURE + fi + newdlfiles="$newdlfiles $libdir/$name" + done + dlfiles="$newdlfiles" + newdlprefiles= + for lib in $dlprefiles; do + name=`$echo "X$lib" | $Xsed -e 's%^.*/%%'` + eval libdir=`${SED} -n -e 's/^libdir=\(.*\)$/\1/p' $lib` + if test -z "$libdir"; then + $echo "$modename: \`$lib' is not a valid libtool archive" 1>&2 + exit $EXIT_FAILURE + fi + newdlprefiles="$newdlprefiles $libdir/$name" + done + dlprefiles="$newdlprefiles" + else + newdlfiles= + for lib in $dlfiles; do + case $lib in + [\\/]* | [A-Za-z]:[\\/]*) abs="$lib" ;; + *) abs=`pwd`"/$lib" ;; + esac + newdlfiles="$newdlfiles $abs" + done + dlfiles="$newdlfiles" + newdlprefiles= + for lib in $dlprefiles; do + case $lib in + [\\/]* | [A-Za-z]:[\\/]*) abs="$lib" ;; + *) abs=`pwd`"/$lib" ;; + esac + newdlprefiles="$newdlprefiles $abs" + done + dlprefiles="$newdlprefiles" + fi + $rm $output + # place dlname in correct position for cygwin + tdlname=$dlname + case $host,$output,$installed,$module,$dlname in + *cygwin*,*lai,yes,no,*.dll | *mingw*,*lai,yes,no,*.dll) tdlname=../bin/$dlname ;; + esac + $echo > $output "\ +# $outputname - a libtool library file +# Generated by $PROGRAM - GNU $PACKAGE $VERSION$TIMESTAMP +# +# Please DO NOT delete this file! +# It is necessary for linking the library. + +# The name that we can dlopen(3). +dlname='$tdlname' + +# Names of this library. +library_names='$library_names' + +# The name of the static archive. +old_library='$old_library' + +# Libraries that this one depends upon. +dependency_libs='$dependency_libs' + +# Version information for $libname. +current=$current +age=$age +revision=$revision + +# Is this an already installed library? +installed=$installed + +# Should we warn about portability when linking against -modules? +shouldnotlink=$module + +# Files to dlopen/dlpreopen +dlopen='$dlfiles' +dlpreopen='$dlprefiles' + +# Directory that this library needs to be installed in: +libdir='$install_libdir'" + if test "$installed" = no && test "$need_relink" = yes; then + $echo >> $output "\ +relink_command=\"$relink_command\"" + fi + done + fi + + # Do a symbolic link so that the libtool archive can be found in + # LD_LIBRARY_PATH before the program is installed. + $show "(cd $output_objdir && $rm $outputname && $LN_S ../$outputname $outputname)" + $run eval '(cd $output_objdir && $rm $outputname && $LN_S ../$outputname $outputname)' || exit $? + ;; + esac + exit $EXIT_SUCCESS + ;; + + # libtool install mode + install) + modename="$modename: install" + + # There may be an optional sh(1) argument at the beginning of + # install_prog (especially on Windows NT). + if test "$nonopt" = "$SHELL" || test "$nonopt" = /bin/sh || + # Allow the use of GNU shtool's install command. + $echo "X$nonopt" | grep shtool > /dev/null; then + # Aesthetically quote it. + arg=`$echo "X$nonopt" | $Xsed -e "$sed_quote_subst"` + case $arg in + *[\[\~\#\^\&\*\(\)\{\}\|\;\<\>\?\'\ \ ]*|*]*|"") + arg="\"$arg\"" + ;; + esac + install_prog="$arg " + arg="$1" + shift + else + install_prog= + arg=$nonopt + fi + + # The real first argument should be the name of the installation program. + # Aesthetically quote it. + arg=`$echo "X$arg" | $Xsed -e "$sed_quote_subst"` + case $arg in + *[\[\~\#\^\&\*\(\)\{\}\|\;\<\>\?\'\ \ ]*|*]*|"") + arg="\"$arg\"" + ;; + esac + install_prog="$install_prog$arg" + + # We need to accept at least all the BSD install flags. + dest= + files= + opts= + prev= + install_type= + isdir=no + stripme= + for arg + do + if test -n "$dest"; then + files="$files $dest" + dest=$arg + continue + fi + + case $arg in + -d) isdir=yes ;; + -f) + case " $install_prog " in + *[\\\ /]cp\ *) ;; + *) prev=$arg ;; + esac + ;; + -g | -m | -o) prev=$arg ;; + -s) + stripme=" -s" + continue + ;; + -*) + ;; + *) + # If the previous option needed an argument, then skip it. + if test -n "$prev"; then + prev= + else + dest=$arg + continue + fi + ;; + esac + + # Aesthetically quote the argument. + arg=`$echo "X$arg" | $Xsed -e "$sed_quote_subst"` + case $arg in + *[\[\~\#\^\&\*\(\)\{\}\|\;\<\>\?\'\ \ ]*|*]*|"") + arg="\"$arg\"" + ;; + esac + install_prog="$install_prog $arg" + done + + if test -z "$install_prog"; then + $echo "$modename: you must specify an install program" 1>&2 + $echo "$help" 1>&2 + exit $EXIT_FAILURE + fi + + if test -n "$prev"; then + $echo "$modename: the \`$prev' option requires an argument" 1>&2 + $echo "$help" 1>&2 + exit $EXIT_FAILURE + fi + + if test -z "$files"; then + if test -z "$dest"; then + $echo "$modename: no file or destination specified" 1>&2 + else + $echo "$modename: you must specify a destination" 1>&2 + fi + $echo "$help" 1>&2 + exit $EXIT_FAILURE + fi + + # Strip any trailing slash from the destination. + dest=`$echo "X$dest" | $Xsed -e 's%/$%%'` + + # Check to see that the destination is a directory. + test -d "$dest" && isdir=yes + if test "$isdir" = yes; then + destdir="$dest" + destname= + else + destdir=`$echo "X$dest" | $Xsed -e 's%/[^/]*$%%'` + test "X$destdir" = "X$dest" && destdir=. + destname=`$echo "X$dest" | $Xsed -e 's%^.*/%%'` + + # Not a directory, so check to see that there is only one file specified. + set dummy $files + if test "$#" -gt 2; then + $echo "$modename: \`$dest' is not a directory" 1>&2 + $echo "$help" 1>&2 + exit $EXIT_FAILURE + fi + fi + case $destdir in + [\\/]* | [A-Za-z]:[\\/]*) ;; + *) + for file in $files; do + case $file in + *.lo) ;; + *) + $echo "$modename: \`$destdir' must be an absolute directory name" 1>&2 + $echo "$help" 1>&2 + exit $EXIT_FAILURE + ;; + esac + done + ;; + esac + + # This variable tells wrapper scripts just to set variables rather + # than running their programs. + libtool_install_magic="$magic" + + staticlibs= + future_libdirs= + current_libdirs= + for file in $files; do + + # Do each installation. + case $file in + *.$libext) + # Do the static libraries later. + staticlibs="$staticlibs $file" + ;; + + *.la) + # Check to see that this really is a libtool archive. + if (${SED} -e '2q' $file | grep "^# Generated by .*$PACKAGE") >/dev/null 2>&1; then : + else + $echo "$modename: \`$file' is not a valid libtool archive" 1>&2 + $echo "$help" 1>&2 + exit $EXIT_FAILURE + fi + + library_names= + old_library= + relink_command= + # If there is no directory component, then add one. + case $file in + */* | *\\*) . $file ;; + *) . ./$file ;; + esac + + # Add the libdir to current_libdirs if it is the destination. + if test "X$destdir" = "X$libdir"; then + case "$current_libdirs " in + *" $libdir "*) ;; + *) current_libdirs="$current_libdirs $libdir" ;; + esac + else + # Note the libdir as a future libdir. + case "$future_libdirs " in + *" $libdir "*) ;; + *) future_libdirs="$future_libdirs $libdir" ;; + esac + fi + + dir=`$echo "X$file" | $Xsed -e 's%/[^/]*$%%'`/ + test "X$dir" = "X$file/" && dir= + dir="$dir$objdir" + + if test -n "$relink_command"; then + # Determine the prefix the user has applied to our future dir. + inst_prefix_dir=`$echo "$destdir" | $SED "s%$libdir\$%%"` + + # Don't allow the user to place us outside of our expected + # location b/c this prevents finding dependent libraries that + # are installed to the same prefix. + # At present, this check doesn't affect windows .dll's that + # are installed into $libdir/../bin (currently, that works fine) + # but it's something to keep an eye on. + if test "$inst_prefix_dir" = "$destdir"; then + $echo "$modename: error: cannot install \`$file' to a directory not ending in $libdir" 1>&2 + exit $EXIT_FAILURE + fi + + if test -n "$inst_prefix_dir"; then + # Stick the inst_prefix_dir data into the link command. + relink_command=`$echo "$relink_command" | $SP2NL | $SED "s%@inst_prefix_dir@%-inst-prefix-dir $inst_prefix_dir%" | $NL2SP` + else + relink_command=`$echo "$relink_command" | $SP2NL | $SED "s%@inst_prefix_dir@%%" | $NL2SP` + fi + + $echo "$modename: warning: relinking \`$file'" 1>&2 + $show "$relink_command" + if $run eval "$relink_command"; then : + else + $echo "$modename: error: relink \`$file' with the above command before installing it" 1>&2 + exit $EXIT_FAILURE + fi + fi + + # See the names of the shared library. + set dummy $library_names + if test -n "$2"; then + realname="$2" + shift + shift + + srcname="$realname" + test -n "$relink_command" && srcname="$realname"T + + # Install the shared library and build the symlinks. + $show "$install_prog $dir/$srcname $destdir/$realname" + $run eval "$install_prog $dir/$srcname $destdir/$realname" || exit $? + if test -n "$stripme" && test -n "$striplib"; then + $show "$striplib $destdir/$realname" + $run eval "$striplib $destdir/$realname" || exit $? + fi + + if test "$#" -gt 0; then + # Delete the old symlinks, and create new ones. + # Try `ln -sf' first, because the `ln' binary might depend on + # the symlink we replace! Solaris /bin/ln does not understand -f, + # so we also need to try rm && ln -s. + for linkname + do + if test "$linkname" != "$realname"; then + $show "(cd $destdir && { $LN_S -f $realname $linkname || { $rm $linkname && $LN_S $realname $linkname; }; })" + $run eval "(cd $destdir && { $LN_S -f $realname $linkname || { $rm $linkname && $LN_S $realname $linkname; }; })" + fi + done + fi + + # Do each command in the postinstall commands. + lib="$destdir/$realname" + cmds=$postinstall_cmds + save_ifs="$IFS"; IFS='~' + for cmd in $cmds; do + IFS="$save_ifs" + eval cmd=\"$cmd\" + $show "$cmd" + $run eval "$cmd" || { + lt_exit=$? + + # Restore the uninstalled library and exit + if test "$mode" = relink; then + $run eval '(cd $output_objdir && $rm ${realname}T && $mv ${realname}U $realname)' + fi + + exit $lt_exit + } + done + IFS="$save_ifs" + fi + + # Install the pseudo-library for information purposes. + name=`$echo "X$file" | $Xsed -e 's%^.*/%%'` + instname="$dir/$name"i + $show "$install_prog $instname $destdir/$name" + $run eval "$install_prog $instname $destdir/$name" || exit $? + + # Maybe install the static library, too. + test -n "$old_library" && staticlibs="$staticlibs $dir/$old_library" + ;; + + *.lo) + # Install (i.e. copy) a libtool object. + + # Figure out destination file name, if it wasn't already specified. + if test -n "$destname"; then + destfile="$destdir/$destname" + else + destfile=`$echo "X$file" | $Xsed -e 's%^.*/%%'` + destfile="$destdir/$destfile" + fi + + # Deduce the name of the destination old-style object file. + case $destfile in + *.lo) + staticdest=`$echo "X$destfile" | $Xsed -e "$lo2o"` + ;; + *.$objext) + staticdest="$destfile" + destfile= + ;; + *) + $echo "$modename: cannot copy a libtool object to \`$destfile'" 1>&2 + $echo "$help" 1>&2 + exit $EXIT_FAILURE + ;; + esac + + # Install the libtool object if requested. + if test -n "$destfile"; then + $show "$install_prog $file $destfile" + $run eval "$install_prog $file $destfile" || exit $? + fi + + # Install the old object if enabled. + if test "$build_old_libs" = yes; then + # Deduce the name of the old-style object file. + staticobj=`$echo "X$file" | $Xsed -e "$lo2o"` + + $show "$install_prog $staticobj $staticdest" + $run eval "$install_prog \$staticobj \$staticdest" || exit $? + fi + exit $EXIT_SUCCESS + ;; + + *) + # Figure out destination file name, if it wasn't already specified. + if test -n "$destname"; then + destfile="$destdir/$destname" + else + destfile=`$echo "X$file" | $Xsed -e 's%^.*/%%'` + destfile="$destdir/$destfile" + fi + + # If the file is missing, and there is a .exe on the end, strip it + # because it is most likely a libtool script we actually want to + # install + stripped_ext="" + case $file in + *.exe) + if test ! -f "$file"; then + file=`$echo $file|${SED} 's,.exe$,,'` + stripped_ext=".exe" + fi + ;; + esac + + # Do a test to see if this is really a libtool program. + case $host in + *cygwin*|*mingw*) + wrapper=`$echo $file | ${SED} -e 's,.exe$,,'` + ;; + *) + wrapper=$file + ;; + esac + if (${SED} -e '4q' $wrapper | grep "^# Generated by .*$PACKAGE")>/dev/null 2>&1; then + notinst_deplibs= + relink_command= + + # Note that it is not necessary on cygwin/mingw to append a dot to + # foo even if both foo and FILE.exe exist: automatic-append-.exe + # behavior happens only for exec(3), not for open(2)! Also, sourcing + # `FILE.' does not work on cygwin managed mounts. + # + # If there is no directory component, then add one. + case $wrapper in + */* | *\\*) . ${wrapper} ;; + *) . ./${wrapper} ;; + esac + + # Check the variables that should have been set. + if test -z "$notinst_deplibs"; then + $echo "$modename: invalid libtool wrapper script \`$wrapper'" 1>&2 + exit $EXIT_FAILURE + fi + + finalize=yes + for lib in $notinst_deplibs; do + # Check to see that each library is installed. + libdir= + if test -f "$lib"; then + # If there is no directory component, then add one. + case $lib in + */* | *\\*) . $lib ;; + *) . ./$lib ;; + esac + fi + libfile="$libdir/"`$echo "X$lib" | $Xsed -e 's%^.*/%%g'` ### testsuite: skip nested quoting test + if test -n "$libdir" && test ! -f "$libfile"; then + $echo "$modename: warning: \`$lib' has not been installed in \`$libdir'" 1>&2 + finalize=no + fi + done + + relink_command= + # Note that it is not necessary on cygwin/mingw to append a dot to + # foo even if both foo and FILE.exe exist: automatic-append-.exe + # behavior happens only for exec(3), not for open(2)! Also, sourcing + # `FILE.' does not work on cygwin managed mounts. + # + # If there is no directory component, then add one. + case $wrapper in + */* | *\\*) . ${wrapper} ;; + *) . ./${wrapper} ;; + esac + + outputname= + if test "$fast_install" = no && test -n "$relink_command"; then + if test "$finalize" = yes && test -z "$run"; then + tmpdir=`func_mktempdir` + file=`$echo "X$file$stripped_ext" | $Xsed -e 's%^.*/%%'` + outputname="$tmpdir/$file" + # Replace the output file specification. + relink_command=`$echo "X$relink_command" | $SP2NL | $Xsed -e 's%@OUTPUT@%'"$outputname"'%g' | $NL2SP` + + $show "$relink_command" + if $run eval "$relink_command"; then : + else + $echo "$modename: error: relink \`$file' with the above command before installing it" 1>&2 + ${rm}r "$tmpdir" + continue + fi + file="$outputname" + else + $echo "$modename: warning: cannot relink \`$file'" 1>&2 + fi + else + # Install the binary that we compiled earlier. + file=`$echo "X$file$stripped_ext" | $Xsed -e "s%\([^/]*\)$%$objdir/\1%"` + fi + fi + + # remove .exe since cygwin /usr/bin/install will append another + # one anyway + case $install_prog,$host in + */usr/bin/install*,*cygwin*) + case $file:$destfile in + *.exe:*.exe) + # this is ok + ;; + *.exe:*) + destfile=$destfile.exe + ;; + *:*.exe) + destfile=`$echo $destfile | ${SED} -e 's,.exe$,,'` + ;; + esac + ;; + esac + $show "$install_prog$stripme $file $destfile" + $run eval "$install_prog\$stripme \$file \$destfile" || exit $? + test -n "$outputname" && ${rm}r "$tmpdir" + ;; + esac + done + + for file in $staticlibs; do + name=`$echo "X$file" | $Xsed -e 's%^.*/%%'` + + # Set up the ranlib parameters. + oldlib="$destdir/$name" + + $show "$install_prog $file $oldlib" + $run eval "$install_prog \$file \$oldlib" || exit $? + + if test -n "$stripme" && test -n "$old_striplib"; then + $show "$old_striplib $oldlib" + $run eval "$old_striplib $oldlib" || exit $? + fi + + # Do each command in the postinstall commands. + cmds=$old_postinstall_cmds + save_ifs="$IFS"; IFS='~' + for cmd in $cmds; do + IFS="$save_ifs" + eval cmd=\"$cmd\" + $show "$cmd" + $run eval "$cmd" || exit $? + done + IFS="$save_ifs" + done + + if test -n "$future_libdirs"; then + $echo "$modename: warning: remember to run \`$progname --finish$future_libdirs'" 1>&2 + fi + + if test -n "$current_libdirs"; then + # Maybe just do a dry run. + test -n "$run" && current_libdirs=" -n$current_libdirs" + exec_cmd='$SHELL $progpath $preserve_args --finish$current_libdirs' + else + exit $EXIT_SUCCESS + fi + ;; + + # libtool finish mode + finish) + modename="$modename: finish" + libdirs="$nonopt" + admincmds= + + if test -n "$finish_cmds$finish_eval" && test -n "$libdirs"; then + for dir + do + libdirs="$libdirs $dir" + done + + for libdir in $libdirs; do + if test -n "$finish_cmds"; then + # Do each command in the finish commands. + cmds=$finish_cmds + save_ifs="$IFS"; IFS='~' + for cmd in $cmds; do + IFS="$save_ifs" + eval cmd=\"$cmd\" + $show "$cmd" + $run eval "$cmd" || admincmds="$admincmds + $cmd" + done + IFS="$save_ifs" + fi + if test -n "$finish_eval"; then + # Do the single finish_eval. + eval cmds=\"$finish_eval\" + $run eval "$cmds" || admincmds="$admincmds + $cmds" + fi + done + fi + + # Exit here if they wanted silent mode. + test "$show" = : && exit $EXIT_SUCCESS + + $echo "X----------------------------------------------------------------------" | $Xsed + $echo "Libraries have been installed in:" + for libdir in $libdirs; do + $echo " $libdir" + done + $echo + $echo "If you ever happen to want to link against installed libraries" + $echo "in a given directory, LIBDIR, you must either use libtool, and" + $echo "specify the full pathname of the library, or use the \`-LLIBDIR'" + $echo "flag during linking and do at least one of the following:" + if test -n "$shlibpath_var"; then + $echo " - add LIBDIR to the \`$shlibpath_var' environment variable" + $echo " during execution" + fi + if test -n "$runpath_var"; then + $echo " - add LIBDIR to the \`$runpath_var' environment variable" + $echo " during linking" + fi + if test -n "$hardcode_libdir_flag_spec"; then + libdir=LIBDIR + eval flag=\"$hardcode_libdir_flag_spec\" + + $echo " - use the \`$flag' linker flag" + fi + if test -n "$admincmds"; then + $echo " - have your system administrator run these commands:$admincmds" + fi + if test -f /etc/ld.so.conf; then + $echo " - have your system administrator add LIBDIR to \`/etc/ld.so.conf'" + fi + $echo + $echo "See any operating system documentation about shared libraries for" + $echo "more information, such as the ld(1) and ld.so(8) manual pages." + $echo "X----------------------------------------------------------------------" | $Xsed + exit $EXIT_SUCCESS + ;; + + # libtool execute mode + execute) + modename="$modename: execute" + + # The first argument is the command name. + cmd="$nonopt" + if test -z "$cmd"; then + $echo "$modename: you must specify a COMMAND" 1>&2 + $echo "$help" + exit $EXIT_FAILURE + fi + + # Handle -dlopen flags immediately. + for file in $execute_dlfiles; do + if test ! -f "$file"; then + $echo "$modename: \`$file' is not a file" 1>&2 + $echo "$help" 1>&2 + exit $EXIT_FAILURE + fi + + dir= + case $file in + *.la) + # Check to see that this really is a libtool archive. + if (${SED} -e '2q' $file | grep "^# Generated by .*$PACKAGE") >/dev/null 2>&1; then : + else + $echo "$modename: \`$lib' is not a valid libtool archive" 1>&2 + $echo "$help" 1>&2 + exit $EXIT_FAILURE + fi + + # Read the libtool library. + dlname= + library_names= + + # If there is no directory component, then add one. + case $file in + */* | *\\*) . $file ;; + *) . ./$file ;; + esac + + # Skip this library if it cannot be dlopened. + if test -z "$dlname"; then + # Warn if it was a shared library. + test -n "$library_names" && $echo "$modename: warning: \`$file' was not linked with \`-export-dynamic'" + continue + fi + + dir=`$echo "X$file" | $Xsed -e 's%/[^/]*$%%'` + test "X$dir" = "X$file" && dir=. + + if test -f "$dir/$objdir/$dlname"; then + dir="$dir/$objdir" + else + $echo "$modename: cannot find \`$dlname' in \`$dir' or \`$dir/$objdir'" 1>&2 + exit $EXIT_FAILURE + fi + ;; + + *.lo) + # Just add the directory containing the .lo file. + dir=`$echo "X$file" | $Xsed -e 's%/[^/]*$%%'` + test "X$dir" = "X$file" && dir=. + ;; + + *) + $echo "$modename: warning \`-dlopen' is ignored for non-libtool libraries and objects" 1>&2 + continue + ;; + esac + + # Get the absolute pathname. + absdir=`cd "$dir" && pwd` + test -n "$absdir" && dir="$absdir" + + # Now add the directory to shlibpath_var. + if eval "test -z \"\$$shlibpath_var\""; then + eval "$shlibpath_var=\"\$dir\"" + else + eval "$shlibpath_var=\"\$dir:\$$shlibpath_var\"" + fi + done + + # This variable tells wrapper scripts just to set shlibpath_var + # rather than running their programs. + libtool_execute_magic="$magic" + + # Check if any of the arguments is a wrapper script. + args= + for file + do + case $file in + -*) ;; + *) + # Do a test to see if this is really a libtool program. + if (${SED} -e '4q' $file | grep "^# Generated by .*$PACKAGE") >/dev/null 2>&1; then + # If there is no directory component, then add one. + case $file in + */* | *\\*) . $file ;; + *) . ./$file ;; + esac + + # Transform arg to wrapped name. + file="$progdir/$program" + fi + ;; + esac + # Quote arguments (to preserve shell metacharacters). + file=`$echo "X$file" | $Xsed -e "$sed_quote_subst"` + args="$args \"$file\"" + done + + if test -z "$run"; then + if test -n "$shlibpath_var"; then + # Export the shlibpath_var. + eval "export $shlibpath_var" + fi + + # Restore saved environment variables + for lt_var in LANG LC_ALL LC_CTYPE LC_COLLATE LC_MESSAGES + do + eval "if test \"\${save_$lt_var+set}\" = set; then + $lt_var=\$save_$lt_var; export $lt_var + else + $lt_unset $lt_var + fi" + done + + + # Now prepare to actually exec the command. + exec_cmd="\$cmd$args" + else + # Display what would be done. + if test -n "$shlibpath_var"; then + eval "\$echo \"\$shlibpath_var=\$$shlibpath_var\"" + $echo "export $shlibpath_var" + fi + $echo "$cmd$args" + exit $EXIT_SUCCESS + fi + ;; + + # libtool clean and uninstall mode + clean | uninstall) + modename="$modename: $mode" + rm="$nonopt" + files= + rmforce= + exit_status=0 + + # This variable tells wrapper scripts just to set variables rather + # than running their programs. + libtool_install_magic="$magic" + + for arg + do + case $arg in + -f) rm="$rm $arg"; rmforce=yes ;; + -*) rm="$rm $arg" ;; + *) files="$files $arg" ;; + esac + done + + if test -z "$rm"; then + $echo "$modename: you must specify an RM program" 1>&2 + $echo "$help" 1>&2 + exit $EXIT_FAILURE + fi + + rmdirs= + + origobjdir="$objdir" + for file in $files; do + dir=`$echo "X$file" | $Xsed -e 's%/[^/]*$%%'` + if test "X$dir" = "X$file"; then + dir=. + objdir="$origobjdir" + else + objdir="$dir/$origobjdir" + fi + name=`$echo "X$file" | $Xsed -e 's%^.*/%%'` + test "$mode" = uninstall && objdir="$dir" + + # Remember objdir for removal later, being careful to avoid duplicates + if test "$mode" = clean; then + case " $rmdirs " in + *" $objdir "*) ;; + *) rmdirs="$rmdirs $objdir" ;; + esac + fi + + # Don't error if the file doesn't exist and rm -f was used. + if (test -L "$file") >/dev/null 2>&1 \ + || (test -h "$file") >/dev/null 2>&1 \ + || test -f "$file"; then + : + elif test -d "$file"; then + exit_status=1 + continue + elif test "$rmforce" = yes; then + continue + fi + + rmfiles="$file" + + case $name in + *.la) + # Possibly a libtool archive, so verify it. + if (${SED} -e '2q' $file | grep "^# Generated by .*$PACKAGE") >/dev/null 2>&1; then + . $dir/$name + + # Delete the libtool libraries and symlinks. + for n in $library_names; do + rmfiles="$rmfiles $objdir/$n" + done + test -n "$old_library" && rmfiles="$rmfiles $objdir/$old_library" + + case "$mode" in + clean) + case " $library_names " in + # " " in the beginning catches empty $dlname + *" $dlname "*) ;; + *) rmfiles="$rmfiles $objdir/$dlname" ;; + esac + test -n "$libdir" && rmfiles="$rmfiles $objdir/$name $objdir/${name}i" + ;; + uninstall) + if test -n "$library_names"; then + # Do each command in the postuninstall commands. + cmds=$postuninstall_cmds + save_ifs="$IFS"; IFS='~' + for cmd in $cmds; do + IFS="$save_ifs" + eval cmd=\"$cmd\" + $show "$cmd" + $run eval "$cmd" + if test "$?" -ne 0 && test "$rmforce" != yes; then + exit_status=1 + fi + done + IFS="$save_ifs" + fi + + if test -n "$old_library"; then + # Do each command in the old_postuninstall commands. + cmds=$old_postuninstall_cmds + save_ifs="$IFS"; IFS='~' + for cmd in $cmds; do + IFS="$save_ifs" + eval cmd=\"$cmd\" + $show "$cmd" + $run eval "$cmd" + if test "$?" -ne 0 && test "$rmforce" != yes; then + exit_status=1 + fi + done + IFS="$save_ifs" + fi + # FIXME: should reinstall the best remaining shared library. + ;; + esac + fi + ;; + + *.lo) + # Possibly a libtool object, so verify it. + if (${SED} -e '2q' $file | grep "^# Generated by .*$PACKAGE") >/dev/null 2>&1; then + + # Read the .lo file + . $dir/$name + + # Add PIC object to the list of files to remove. + if test -n "$pic_object" \ + && test "$pic_object" != none; then + rmfiles="$rmfiles $dir/$pic_object" + fi + + # Add non-PIC object to the list of files to remove. + if test -n "$non_pic_object" \ + && test "$non_pic_object" != none; then + rmfiles="$rmfiles $dir/$non_pic_object" + fi + fi + ;; + + *) + if test "$mode" = clean ; then + noexename=$name + case $file in + *.exe) + file=`$echo $file|${SED} 's,.exe$,,'` + noexename=`$echo $name|${SED} 's,.exe$,,'` + # $file with .exe has already been added to rmfiles, + # add $file without .exe + rmfiles="$rmfiles $file" + ;; + esac + # Do a test to see if this is a libtool program. + if (${SED} -e '4q' $file | grep "^# Generated by .*$PACKAGE") >/dev/null 2>&1; then + relink_command= + . $dir/$noexename + + # note $name still contains .exe if it was in $file originally + # as does the version of $file that was added into $rmfiles + rmfiles="$rmfiles $objdir/$name $objdir/${name}S.${objext}" + if test "$fast_install" = yes && test -n "$relink_command"; then + rmfiles="$rmfiles $objdir/lt-$name" + fi + if test "X$noexename" != "X$name" ; then + rmfiles="$rmfiles $objdir/lt-${noexename}.c" + fi + fi + fi + ;; + esac + $show "$rm $rmfiles" + $run $rm $rmfiles || exit_status=1 + done + objdir="$origobjdir" + + # Try to remove the ${objdir}s in the directories where we deleted files + for dir in $rmdirs; do + if test -d "$dir"; then + $show "rmdir $dir" + $run rmdir $dir >/dev/null 2>&1 + fi + done + + exit $exit_status + ;; + + "") + $echo "$modename: you must specify a MODE" 1>&2 + $echo "$generic_help" 1>&2 + exit $EXIT_FAILURE + ;; + esac + + if test -z "$exec_cmd"; then + $echo "$modename: invalid operation mode \`$mode'" 1>&2 + $echo "$generic_help" 1>&2 + exit $EXIT_FAILURE + fi +fi # test -z "$show_help" + +if test -n "$exec_cmd"; then + eval exec $exec_cmd + exit $EXIT_FAILURE +fi + +# We need to display help for each of the modes. +case $mode in +"") $echo \ +"Usage: $modename [OPTION]... [MODE-ARG]... + +Provide generalized library-building support services. + + --config show all configuration variables + --debug enable verbose shell tracing +-n, --dry-run display commands without modifying any files + --features display basic configuration information and exit + --finish same as \`--mode=finish' + --help display this help message and exit + --mode=MODE use operation mode MODE [default=inferred from MODE-ARGS] + --quiet same as \`--silent' + --silent don't print informational messages + --tag=TAG use configuration variables from tag TAG + --version print version information + +MODE must be one of the following: + + clean remove files from the build directory + compile compile a source file into a libtool object + execute automatically set library path, then run a program + finish complete the installation of libtool libraries + install install libraries or executables + link create a library or an executable + uninstall remove libraries from an installed directory + +MODE-ARGS vary depending on the MODE. Try \`$modename --help --mode=MODE' for +a more detailed description of MODE. + +Report bugs to <bug-libtool@gnu.org>." + exit $EXIT_SUCCESS + ;; + +clean) + $echo \ +"Usage: $modename [OPTION]... --mode=clean RM [RM-OPTION]... FILE... + +Remove files from the build directory. + +RM is the name of the program to use to delete files associated with each FILE +(typically \`/bin/rm'). RM-OPTIONS are options (such as \`-f') to be passed +to RM. + +If FILE is a libtool library, object or program, all the files associated +with it are deleted. Otherwise, only FILE itself is deleted using RM." + ;; + +compile) + $echo \ +"Usage: $modename [OPTION]... --mode=compile COMPILE-COMMAND... SOURCEFILE + +Compile a source file into a libtool library object. + +This mode accepts the following additional options: + + -o OUTPUT-FILE set the output file name to OUTPUT-FILE + -prefer-pic try to building PIC objects only + -prefer-non-pic try to building non-PIC objects only + -static always build a \`.o' file suitable for static linking + +COMPILE-COMMAND is a command to be used in creating a \`standard' object file +from the given SOURCEFILE. + +The output file name is determined by removing the directory component from +SOURCEFILE, then substituting the C source code suffix \`.c' with the +library object suffix, \`.lo'." + ;; + +execute) + $echo \ +"Usage: $modename [OPTION]... --mode=execute COMMAND [ARGS]... + +Automatically set library path, then run a program. + +This mode accepts the following additional options: + + -dlopen FILE add the directory containing FILE to the library path + +This mode sets the library path environment variable according to \`-dlopen' +flags. + +If any of the ARGS are libtool executable wrappers, then they are translated +into their corresponding uninstalled binary, and any of their required library +directories are added to the library path. + +Then, COMMAND is executed, with ARGS as arguments." + ;; + +finish) + $echo \ +"Usage: $modename [OPTION]... --mode=finish [LIBDIR]... + +Complete the installation of libtool libraries. + +Each LIBDIR is a directory that contains libtool libraries. + +The commands that this mode executes may require superuser privileges. Use +the \`--dry-run' option if you just want to see what would be executed." + ;; + +install) + $echo \ +"Usage: $modename [OPTION]... --mode=install INSTALL-COMMAND... + +Install executables or libraries. + +INSTALL-COMMAND is the installation command. The first component should be +either the \`install' or \`cp' program. + +The rest of the components are interpreted as arguments to that command (only +BSD-compatible install options are recognized)." + ;; + +link) + $echo \ +"Usage: $modename [OPTION]... --mode=link LINK-COMMAND... + +Link object files or libraries together to form another library, or to +create an executable program. + +LINK-COMMAND is a command using the C compiler that you would use to create +a program from several object files. + +The following components of LINK-COMMAND are treated specially: + + -all-static do not do any dynamic linking at all + -avoid-version do not add a version suffix if possible + -dlopen FILE \`-dlpreopen' FILE if it cannot be dlopened at runtime + -dlpreopen FILE link in FILE and add its symbols to lt_preloaded_symbols + -export-dynamic allow symbols from OUTPUT-FILE to be resolved with dlsym(3) + -export-symbols SYMFILE + try to export only the symbols listed in SYMFILE + -export-symbols-regex REGEX + try to export only the symbols matching REGEX + -LLIBDIR search LIBDIR for required installed libraries + -lNAME OUTPUT-FILE requires the installed library libNAME + -module build a library that can dlopened + -no-fast-install disable the fast-install mode + -no-install link a not-installable executable + -no-undefined declare that a library does not refer to external symbols + -o OUTPUT-FILE create OUTPUT-FILE from the specified objects + -objectlist FILE Use a list of object files found in FILE to specify objects + -precious-files-regex REGEX + don't remove output files matching REGEX + -release RELEASE specify package release information + -rpath LIBDIR the created library will eventually be installed in LIBDIR + -R[ ]LIBDIR add LIBDIR to the runtime path of programs and libraries + -static do not do any dynamic linking of uninstalled libtool libraries + -static-libtool-libs + do not do any dynamic linking of libtool libraries + -version-info CURRENT[:REVISION[:AGE]] + specify library version info [each variable defaults to 0] + +All other options (arguments beginning with \`-') are ignored. + +Every other argument is treated as a filename. Files ending in \`.la' are +treated as uninstalled libtool libraries, other files are standard or library +object files. + +If the OUTPUT-FILE ends in \`.la', then a libtool library is created, +only library objects (\`.lo' files) may be specified, and \`-rpath' is +required, except when creating a convenience library. + +If OUTPUT-FILE ends in \`.a' or \`.lib', then a standard library is created +using \`ar' and \`ranlib', or on Windows using \`lib'. + +If OUTPUT-FILE ends in \`.lo' or \`.${objext}', then a reloadable object file +is created, otherwise an executable program is created." + ;; + +uninstall) + $echo \ +"Usage: $modename [OPTION]... --mode=uninstall RM [RM-OPTION]... FILE... + +Remove libraries from an installation directory. + +RM is the name of the program to use to delete files associated with each FILE +(typically \`/bin/rm'). RM-OPTIONS are options (such as \`-f') to be passed +to RM. + +If FILE is a libtool library, all the files associated with it are deleted. +Otherwise, only FILE itself is deleted using RM." + ;; + +*) + $echo "$modename: invalid operation mode \`$mode'" 1>&2 + $echo "$help" 1>&2 + exit $EXIT_FAILURE + ;; +esac + +$echo +$echo "Try \`$modename --help' for more information about other modes." + +exit $? + +# The TAGs below are defined such that we never get into a situation +# in which we disable both kinds of libraries. Given conflicting +# choices, we go for a static library, that is the most portable, +# since we can't tell whether shared libraries were disabled because +# the user asked for that or because the platform doesn't support +# them. This is particularly important on AIX, because we don't +# support having both static and shared libraries enabled at the same +# time on that platform, so we default to a shared-only configuration. +# If a disable-shared tag is given, we'll fallback to a static-only +# configuration. But we'll never go from static-only to shared-only. + +# ### BEGIN LIBTOOL TAG CONFIG: disable-shared +disable_libs=shared +# ### END LIBTOOL TAG CONFIG: disable-shared + +# ### BEGIN LIBTOOL TAG CONFIG: disable-static +disable_libs=static +# ### END LIBTOOL TAG CONFIG: disable-static + +# Local Variables: +# mode:shell-script +# sh-indentation:2 +# End: +# ### BEGIN LIBTOOL TAG CONFIG: CXX + +# Libtool was configured on host NWRW15: + +# Shell to use when invoking shell scripts. +SHELL="/bin/sh" + +# Whether or not to build shared libraries. +build_libtool_libs=yes + +# Whether or not to build static libraries. +build_old_libs=yes + +# Whether or not to add -lc for building shared libraries. +build_libtool_need_lc=no + +# Whether or not to disallow shared libs when runtime libs are static +allow_libtool_libs_with_static_runtimes=no + +# Whether or not to optimize for fast installation. +fast_install=yes + +# The host system. +host_alias= +host=i686-redhat-linux-gnu +host_os=linux-gnu + +# The build system. +build_alias= +build=i686-redhat-linux-gnu +build_os=linux-gnu + +# An echo program that does not interpret backslashes. +echo="echo" + +# The archiver. +AR="ar" +AR_FLAGS="cru" + +# A C compiler. +LTCC="gcc" + +# LTCC compiler flags. +LTCFLAGS="-g -O2" + +# A language-specific compiler. +CC="g++" + +# Is the compiler the GNU C compiler? +with_gcc=yes + +gcc_dir=`gcc -print-file-name=. | /bin/sed 's,/\.$,,'` +gcc_ver=`gcc -dumpversion` + +# An ERE matcher. +EGREP="grep -E" + +# The linker used to build libraries. +LD="/usr/bin/ld" + +# Whether we need hard or soft links. +LN_S="ln -s" + +# A BSD-compatible nm program. +NM="/usr/bin/nm -B" + +# A symbol stripping program +STRIP="strip" + +# Used to examine libraries when file_magic_cmd begins "file" +MAGIC_CMD=file + +# Used on cygwin: DLL creation program. +DLLTOOL="dlltool" + +# Used on cygwin: object dumper. +OBJDUMP="objdump" + +# Used on cygwin: assembler. +AS="as" + +# The name of the directory that contains temporary libtool files. +objdir=.libs + +# How to create reloadable object files. +reload_flag=" -r" +reload_cmds="\$LD\$reload_flag -o \$output\$reload_objs" + +# How to pass a linker flag through the compiler. +wl="-Wl," + +# Object file suffix (normally "o"). +objext="o" + +# Old archive suffix (normally "a"). +libext="a" + +# Shared library suffix (normally ".so"). +shrext_cmds='.so' + +# Executable file suffix (normally ""). +exeext="" + +# Additional compiler flags for building library objects. +pic_flag=" -fPIC -DPIC" +pic_mode=default + +# What is the maximum length of a command? +max_cmd_len=32768 + +# Does compiler simultaneously support -c and -o options? +compiler_c_o="yes" + +# Must we lock files when doing compilation? +need_locks="no" + +# Do we need the lib prefix for modules? +need_lib_prefix=no + +# Do we need a version for libraries? +need_version=no + +# Whether dlopen is supported. +dlopen_support=unknown + +# Whether dlopen of programs is supported. +dlopen_self=unknown + +# Whether dlopen of statically linked programs is supported. +dlopen_self_static=unknown + +# Compiler flag to prevent dynamic linking. +link_static_flag="-static" + +# Compiler flag to turn off builtin functions. +no_builtin_flag=" -fno-builtin" + +# Compiler flag to allow reflexive dlopens. +export_dynamic_flag_spec="\${wl}--export-dynamic" + +# Compiler flag to generate shared objects directly from archives. +whole_archive_flag_spec="\${wl}--whole-archive\$convenience \${wl}--no-whole-archive" + +# Compiler flag to generate thread-safe objects. +thread_safe_flag_spec="" + +# Library versioning type. +version_type=linux + +# Format of library name prefix. +libname_spec="lib\$name" + +# List of archive names. First name is the real one, the rest are links. +# The last name is the one that the linker finds with -lNAME. +library_names_spec="\${libname}\${release}\${shared_ext}\$versuffix \${libname}\${release}\${shared_ext}\$major \$libname\${shared_ext}" + +# The coded name of the library, if different from the real name. +soname_spec="\${libname}\${release}\${shared_ext}\$major" + +# Commands used to build and install an old-style archive. +RANLIB="ranlib" +old_archive_cmds="\$AR \$AR_FLAGS \$oldlib\$oldobjs\$old_deplibs~\$RANLIB \$oldlib" +old_postinstall_cmds="chmod 644 \$oldlib~\$RANLIB \$oldlib" +old_postuninstall_cmds="" + +# Create an old-style archive from a shared archive. +old_archive_from_new_cmds="" + +# Create a temporary old-style archive to link instead of a shared archive. +old_archive_from_expsyms_cmds="" + +# Commands used to build and install a shared archive. +archive_cmds="\$CC -shared -nostdlib \$predep_objects \$libobjs \$deplibs \$postdep_objects \$compiler_flags \${wl}-soname \$wl\$soname -o \$lib" +archive_expsym_cmds="\$CC -shared -nostdlib \$predep_objects \$libobjs \$deplibs \$postdep_objects \$compiler_flags \${wl}-soname \$wl\$soname \${wl}-retain-symbols-file \$wl\$export_symbols -o \$lib" +postinstall_cmds="" +postuninstall_cmds="" + +# Commands used to build a loadable module (assumed same as above if empty) +module_cmds="" +module_expsym_cmds="" + +# Commands to strip libraries. +old_striplib="strip --strip-debug" +striplib="strip --strip-unneeded" + +# Dependencies to place before the objects being linked to create a +# shared library. +predep_objects=`echo "/usr/lib/gcc/i386-redhat-linux/4.1.2/../../../crti.o /usr/lib/gcc/i386-redhat-linux/4.1.2/crtbeginS.o" | $SED -e "s@${gcc_dir}@\${gcc_dir}@g;s@${gcc_ver}@\${gcc_ver}@g"` + +# Dependencies to place after the objects being linked to create a +# shared library. +postdep_objects=`echo "/usr/lib/gcc/i386-redhat-linux/4.1.2/crtendS.o /usr/lib/gcc/i386-redhat-linux/4.1.2/../../../crtn.o" | $SED -e "s@${gcc_dir}@\${gcc_dir}@g;s@${gcc_ver}@\${gcc_ver}@g"` + +# Dependencies to place before the objects being linked to create a +# shared library. +predeps="" + +# Dependencies to place after the objects being linked to create a +# shared library. +postdeps="-lstdc++ -lm -lgcc_s -lc -lgcc_s" + +# The library search path used internally by the compiler when linking +# a shared library. +compiler_lib_search_path=`echo "-L/usr/lib/gcc/i386-redhat-linux/4.1.2 -L/usr/lib/gcc/i386-redhat-linux/4.1.2 -L/usr/lib/gcc/i386-redhat-linux/4.1.2/../../.." | $SED -e "s@${gcc_dir}@\${gcc_dir}@g;s@${gcc_ver}@\${gcc_ver}@g"` + +# Method to check whether dependent libraries are shared objects. +deplibs_check_method="pass_all" + +# Command to use when deplibs_check_method == file_magic. +file_magic_cmd="\$MAGIC_CMD" + +# Flag that allows shared libraries with undefined symbols to be built. +allow_undefined_flag="" + +# Flag that forces no undefined symbols. +no_undefined_flag="" + +# Commands used to finish a libtool library installation in a directory. +finish_cmds="PATH=\\\"\\\$PATH:/sbin\\\" ldconfig -n \$libdir" + +# Same as above, but a single script fragment to be evaled but not shown. +finish_eval="" + +# Take the output of nm and produce a listing of raw symbols and C names. +global_symbol_pipe="sed -n -e 's/^.*[ ]\\([ABCDGIRSTW][ABCDGIRSTW]*\\)[ ][ ]*\\([_A-Za-z][_A-Za-z0-9]*\\)\$/\\1 \\2 \\2/p'" + +# Transform the output of nm in a proper C declaration +global_symbol_to_cdecl="sed -n -e 's/^. .* \\(.*\\)\$/extern int \\1;/p'" + +# Transform the output of nm in a C name address pair +global_symbol_to_c_name_address="sed -n -e 's/^: \\([^ ]*\\) \$/ {\\\"\\1\\\", (lt_ptr) 0},/p' -e 's/^[BCDEGRST] \\([^ ]*\\) \\([^ ]*\\)\$/ {\"\\2\", (lt_ptr) \\&\\2},/p'" + +# This is the shared library runtime path variable. +runpath_var=LD_RUN_PATH + +# This is the shared library path variable. +shlibpath_var=LD_LIBRARY_PATH + +# Is shlibpath searched before the hard-coded library search path? +shlibpath_overrides_runpath=no + +# How to hardcode a shared library path into an executable. +hardcode_action=immediate + +# Whether we should hardcode library paths into libraries. +hardcode_into_libs=yes + +# Flag to hardcode $libdir into a binary during linking. +# This must work even if $libdir does not exist. +hardcode_libdir_flag_spec="\${wl}--rpath \${wl}\$libdir" + +# If ld is used when linking, flag to hardcode $libdir into +# a binary during linking. This must work even if $libdir does +# not exist. +hardcode_libdir_flag_spec_ld="" + +# Whether we need a single -rpath flag with a separated argument. +hardcode_libdir_separator="" + +# Set to yes if using DIR/libNAME during linking hardcodes DIR into the +# resulting binary. +hardcode_direct=no + +# Set to yes if using the -LDIR flag during linking hardcodes DIR into the +# resulting binary. +hardcode_minus_L=no + +# Set to yes if using SHLIBPATH_VAR=DIR during linking hardcodes DIR into +# the resulting binary. +hardcode_shlibpath_var=unsupported + +# Set to yes if building a shared library automatically hardcodes DIR into the library +# and all subsequent libraries and executables linked against it. +hardcode_automatic=no + +# Variables whose values should be saved in libtool wrapper scripts and +# restored at relink time. +variables_saved_for_relink="PATH LD_LIBRARY_PATH LD_RUN_PATH GCC_EXEC_PREFIX COMPILER_PATH LIBRARY_PATH" + +# Whether libtool must link a program against all its dependency libraries. +link_all_deplibs=unknown + +# Compile-time system search path for libraries +sys_lib_search_path_spec=`echo " /usr/lib/gcc/i386-redhat-linux/4.1.2/ /usr/lib/gcc/i386-redhat-linux/4.1.2/ /usr/lib/gcc/i386-redhat-linux/4.1.2/../../../../i386-redhat-linux/lib/i386-redhat-linux/4.1.2/ /usr/lib/gcc/i386-redhat-linux/4.1.2/../../../../i386-redhat-linux/lib/ /usr/lib/gcc/i386-redhat-linux/4.1.2/../../../i386-redhat-linux/4.1.2/ /usr/lib/gcc/i386-redhat-linux/4.1.2/../../../ /lib/i386-redhat-linux/4.1.2/ /lib/ /usr/lib/i386-redhat-linux/4.1.2/ /usr/lib/" | $SED -e "s@${gcc_dir}@\${gcc_dir}@g;s@${gcc_ver}@\${gcc_ver}@g"` + +# Run-time system search path for libraries +sys_lib_dlsearch_path_spec="/lib /usr/lib /usr/lib/qt-3.3/lib " + +# Fix the shell variable $srcfile for the compiler. +fix_srcfile_path="" + +# Set to yes if exported symbols are required. +always_export_symbols=no + +# The commands to list exported symbols. +export_symbols_cmds="\$NM \$libobjs \$convenience | \$global_symbol_pipe | \$SED 's/.* //' | sort | uniq > \$export_symbols" + +# The commands to extract the exported symbol list from a shared archive. +extract_expsyms_cmds="" + +# Symbols that should not be listed in the preloaded symbols. +exclude_expsyms="" + +# Symbols that must always be exported. +include_expsyms="" + +# ### END LIBTOOL TAG CONFIG: CXX + +# ### BEGIN LIBTOOL TAG CONFIG: F77 + +# Libtool was configured on host NWRW15: + +# Shell to use when invoking shell scripts. +SHELL="/bin/sh" + +# Whether or not to build shared libraries. +build_libtool_libs=yes + +# Whether or not to build static libraries. +build_old_libs=yes + +# Whether or not to add -lc for building shared libraries. +build_libtool_need_lc=no + +# Whether or not to disallow shared libs when runtime libs are static +allow_libtool_libs_with_static_runtimes=no + +# Whether or not to optimize for fast installation. +fast_install=yes + +# The host system. +host_alias= +host=i686-redhat-linux-gnu +host_os=linux-gnu + +# The build system. +build_alias= +build=i686-redhat-linux-gnu +build_os=linux-gnu + +# An echo program that does not interpret backslashes. +echo="echo" + +# The archiver. +AR="ar" +AR_FLAGS="cru" + +# A C compiler. +LTCC="gcc" + +# LTCC compiler flags. +LTCFLAGS="-g -O2" + +# A language-specific compiler. +CC="g77" + +# Is the compiler the GNU C compiler? +with_gcc=yes + +gcc_dir=`gcc -print-file-name=. | /bin/sed 's,/\.$,,'` +gcc_ver=`gcc -dumpversion` + +# An ERE matcher. +EGREP="grep -E" + +# The linker used to build libraries. +LD="/usr/bin/ld" + +# Whether we need hard or soft links. +LN_S="ln -s" + +# A BSD-compatible nm program. +NM="/usr/bin/nm -B" + +# A symbol stripping program +STRIP="strip" + +# Used to examine libraries when file_magic_cmd begins "file" +MAGIC_CMD=file + +# Used on cygwin: DLL creation program. +DLLTOOL="dlltool" + +# Used on cygwin: object dumper. +OBJDUMP="objdump" + +# Used on cygwin: assembler. +AS="as" + +# The name of the directory that contains temporary libtool files. +objdir=.libs + +# How to create reloadable object files. +reload_flag=" -r" +reload_cmds="\$LD\$reload_flag -o \$output\$reload_objs" + +# How to pass a linker flag through the compiler. +wl="-Wl," + +# Object file suffix (normally "o"). +objext="o" + +# Old archive suffix (normally "a"). +libext="a" + +# Shared library suffix (normally ".so"). +shrext_cmds='.so' + +# Executable file suffix (normally ""). +exeext="" + +# Additional compiler flags for building library objects. +pic_flag=" -fPIC" +pic_mode=default + +# What is the maximum length of a command? +max_cmd_len=32768 + +# Does compiler simultaneously support -c and -o options? +compiler_c_o="yes" + +# Must we lock files when doing compilation? +need_locks="no" + +# Do we need the lib prefix for modules? +need_lib_prefix=no + +# Do we need a version for libraries? +need_version=no + +# Whether dlopen is supported. +dlopen_support=unknown + +# Whether dlopen of programs is supported. +dlopen_self=unknown + +# Whether dlopen of statically linked programs is supported. +dlopen_self_static=unknown + +# Compiler flag to prevent dynamic linking. +link_static_flag="-static" + +# Compiler flag to turn off builtin functions. +no_builtin_flag="" + +# Compiler flag to allow reflexive dlopens. +export_dynamic_flag_spec="\${wl}--export-dynamic" + +# Compiler flag to generate shared objects directly from archives. +whole_archive_flag_spec="\${wl}--whole-archive\$convenience \${wl}--no-whole-archive" + +# Compiler flag to generate thread-safe objects. +thread_safe_flag_spec="" + +# Library versioning type. +version_type=linux + +# Format of library name prefix. +libname_spec="lib\$name" + +# List of archive names. First name is the real one, the rest are links. +# The last name is the one that the linker finds with -lNAME. +library_names_spec="\${libname}\${release}\${shared_ext}\$versuffix \${libname}\${release}\${shared_ext}\$major \$libname\${shared_ext}" + +# The coded name of the library, if different from the real name. +soname_spec="\${libname}\${release}\${shared_ext}\$major" + +# Commands used to build and install an old-style archive. +RANLIB="ranlib" +old_archive_cmds="\$AR \$AR_FLAGS \$oldlib\$oldobjs\$old_deplibs~\$RANLIB \$oldlib" +old_postinstall_cmds="chmod 644 \$oldlib~\$RANLIB \$oldlib" +old_postuninstall_cmds="" + +# Create an old-style archive from a shared archive. +old_archive_from_new_cmds="" + +# Create a temporary old-style archive to link instead of a shared archive. +old_archive_from_expsyms_cmds="" + +# Commands used to build and install a shared archive. +archive_cmds="\$CC -shared \$libobjs \$deplibs \$compiler_flags \${wl}-soname \$wl\$soname -o \$lib" +archive_expsym_cmds="\$echo \\\"{ global:\\\" > \$output_objdir/\$libname.ver~ + cat \$export_symbols | sed -e \\\"s/\\\\(.*\\\\)/\\\\1;/\\\" >> \$output_objdir/\$libname.ver~ + \$echo \\\"local: *; };\\\" >> \$output_objdir/\$libname.ver~ + \$CC -shared \$libobjs \$deplibs \$compiler_flags \${wl}-soname \$wl\$soname \${wl}-version-script \${wl}\$output_objdir/\$libname.ver -o \$lib" +postinstall_cmds="" +postuninstall_cmds="" + +# Commands used to build a loadable module (assumed same as above if empty) +module_cmds="" +module_expsym_cmds="" + +# Commands to strip libraries. +old_striplib="strip --strip-debug" +striplib="strip --strip-unneeded" + +# Dependencies to place before the objects being linked to create a +# shared library. +predep_objects=`echo "" | $SED -e "s@${gcc_dir}@\${gcc_dir}@g;s@${gcc_ver}@\${gcc_ver}@g"` + +# Dependencies to place after the objects being linked to create a +# shared library. +postdep_objects=`echo "" | $SED -e "s@${gcc_dir}@\${gcc_dir}@g;s@${gcc_ver}@\${gcc_ver}@g"` + +# Dependencies to place before the objects being linked to create a +# shared library. +predeps="" + +# Dependencies to place after the objects being linked to create a +# shared library. +postdeps="" + +# The library search path used internally by the compiler when linking +# a shared library. +compiler_lib_search_path=`echo "" | $SED -e "s@${gcc_dir}@\${gcc_dir}@g;s@${gcc_ver}@\${gcc_ver}@g"` + +# Method to check whether dependent libraries are shared objects. +deplibs_check_method="pass_all" + +# Command to use when deplibs_check_method == file_magic. +file_magic_cmd="\$MAGIC_CMD" + +# Flag that allows shared libraries with undefined symbols to be built. +allow_undefined_flag="" + +# Flag that forces no undefined symbols. +no_undefined_flag="" + +# Commands used to finish a libtool library installation in a directory. +finish_cmds="PATH=\\\"\\\$PATH:/sbin\\\" ldconfig -n \$libdir" + +# Same as above, but a single script fragment to be evaled but not shown. +finish_eval="" + +# Take the output of nm and produce a listing of raw symbols and C names. +global_symbol_pipe="sed -n -e 's/^.*[ ]\\([ABCDGIRSTW][ABCDGIRSTW]*\\)[ ][ ]*\\([_A-Za-z][_A-Za-z0-9]*\\)\$/\\1 \\2 \\2/p'" + +# Transform the output of nm in a proper C declaration +global_symbol_to_cdecl="sed -n -e 's/^. .* \\(.*\\)\$/extern int \\1;/p'" + +# Transform the output of nm in a C name address pair +global_symbol_to_c_name_address="sed -n -e 's/^: \\([^ ]*\\) \$/ {\\\"\\1\\\", (lt_ptr) 0},/p' -e 's/^[BCDEGRST] \\([^ ]*\\) \\([^ ]*\\)\$/ {\"\\2\", (lt_ptr) \\&\\2},/p'" + +# This is the shared library runtime path variable. +runpath_var=LD_RUN_PATH + +# This is the shared library path variable. +shlibpath_var=LD_LIBRARY_PATH + +# Is shlibpath searched before the hard-coded library search path? +shlibpath_overrides_runpath=no + +# How to hardcode a shared library path into an executable. +hardcode_action=immediate + +# Whether we should hardcode library paths into libraries. +hardcode_into_libs=yes + +# Flag to hardcode $libdir into a binary during linking. +# This must work even if $libdir does not exist. +hardcode_libdir_flag_spec="\${wl}--rpath \${wl}\$libdir" + +# If ld is used when linking, flag to hardcode $libdir into +# a binary during linking. This must work even if $libdir does +# not exist. +hardcode_libdir_flag_spec_ld="" + +# Whether we need a single -rpath flag with a separated argument. +hardcode_libdir_separator="" + +# Set to yes if using DIR/libNAME during linking hardcodes DIR into the +# resulting binary. +hardcode_direct=no + +# Set to yes if using the -LDIR flag during linking hardcodes DIR into the +# resulting binary. +hardcode_minus_L=no + +# Set to yes if using SHLIBPATH_VAR=DIR during linking hardcodes DIR into +# the resulting binary. +hardcode_shlibpath_var=unsupported + +# Set to yes if building a shared library automatically hardcodes DIR into the library +# and all subsequent libraries and executables linked against it. +hardcode_automatic=no + +# Variables whose values should be saved in libtool wrapper scripts and +# restored at relink time. +variables_saved_for_relink="PATH LD_LIBRARY_PATH LD_RUN_PATH GCC_EXEC_PREFIX COMPILER_PATH LIBRARY_PATH" + +# Whether libtool must link a program against all its dependency libraries. +link_all_deplibs=unknown + +# Compile-time system search path for libraries +sys_lib_search_path_spec=`echo " /usr/lib/gcc/i386-redhat-linux/3.4.6/ /usr/lib/gcc/i386-redhat-linux/3.4.6/ /usr/lib/gcc/i386-redhat-linux/3.4.6/../../../../i386-redhat-linux/lib/i386-redhat-linux/3.4.6/ /usr/lib/gcc/i386-redhat-linux/3.4.6/../../../../i386-redhat-linux/lib/ /usr/lib/gcc/i386-redhat-linux/3.4.6/../../../i386-redhat-linux/3.4.6/ /usr/lib/gcc/i386-redhat-linux/3.4.6/../../../ /lib/i386-redhat-linux/3.4.6/ /lib/ /usr/lib/i386-redhat-linux/3.4.6/ /usr/lib/" | $SED -e "s@${gcc_dir}@\${gcc_dir}@g;s@${gcc_ver}@\${gcc_ver}@g"` + +# Run-time system search path for libraries +sys_lib_dlsearch_path_spec="/lib /usr/lib /usr/lib/qt-3.3/lib " + +# Fix the shell variable $srcfile for the compiler. +fix_srcfile_path="" + +# Set to yes if exported symbols are required. +always_export_symbols=no + +# The commands to list exported symbols. +export_symbols_cmds="\$NM \$libobjs \$convenience | \$global_symbol_pipe | \$SED 's/.* //' | sort | uniq > \$export_symbols" + +# The commands to extract the exported symbol list from a shared archive. +extract_expsyms_cmds="" + +# Symbols that should not be listed in the preloaded symbols. +exclude_expsyms="_GLOBAL_OFFSET_TABLE_" + +# Symbols that must always be exported. +include_expsyms="" + +# ### END LIBTOOL TAG CONFIG: F77 + diff --git a/AMDiS/ltmain.sh b/AMDiS/ltmain.sh new file mode 100644 index 0000000000000000000000000000000000000000..0223495a0299f6b5fe2dd0eee8e01cdd48b065b3 --- /dev/null +++ b/AMDiS/ltmain.sh @@ -0,0 +1,6911 @@ +# ltmain.sh - Provide generalized library-building support services. +# NOTE: Changing this file will not affect anything until you rerun configure. +# +# Copyright (C) 1996, 1997, 1998, 1999, 2000, 2001, 2003, 2004, 2005 +# Free Software Foundation, Inc. +# Originally by Gordon Matzigkeit <gord@gnu.ai.mit.edu>, 1996 +# +# 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. +# +# As a special exception to the GNU General Public License, if you +# distribute this file as part of a program that contains a +# configuration script generated by Autoconf, you may include it under +# the same distribution terms that you use for the rest of that program. + +basename="s,^.*/,,g" + +# Work around backward compatibility issue on IRIX 6.5. On IRIX 6.4+, sh +# is ksh but when the shell is invoked as "sh" and the current value of +# the _XPG environment variable is not equal to 1 (one), the special +# positional parameter $0, within a function call, is the name of the +# function. +progpath="$0" + +# The name of this program: +progname=`echo "$progpath" | $SED $basename` +modename="$progname" + +# Global variables: +EXIT_SUCCESS=0 +EXIT_FAILURE=1 + +PROGRAM=ltmain.sh +PACKAGE=libtool +VERSION=1.5.22 +TIMESTAMP=" (1.1220.2.365 2005/12/18 22:14:06)" + +# Be Bourne compatible (taken from Autoconf:_AS_BOURNE_COMPATIBLE). +if test -n "${ZSH_VERSION+set}" && (emulate sh) >/dev/null 2>&1; then + emulate sh + NULLCMD=: + # Zsh 3.x and 4.x performs word splitting on ${1+"$@"}, which + # is contrary to our usage. Disable this feature. + alias -g '${1+"$@"}'='"$@"' + setopt NO_GLOB_SUBST +else + case `(set -o) 2>/dev/null` in *posix*) set -o posix;; esac +fi + +# Check that we have a working $echo. +if test "X$1" = X--no-reexec; then + # Discard the --no-reexec flag, and continue. + shift +elif test "X$1" = X--fallback-echo; then + # Avoid inline document here, it may be left over + : +elif test "X`($echo '\t') 2>/dev/null`" = 'X\t'; then + # Yippee, $echo works! + : +else + # Restart under the correct shell, and then maybe $echo will work. + exec $SHELL "$progpath" --no-reexec ${1+"$@"} +fi + +if test "X$1" = X--fallback-echo; then + # used as fallback echo + shift + cat <<EOF +$* +EOF + exit $EXIT_SUCCESS +fi + +default_mode= +help="Try \`$progname --help' for more information." +magic="%%%MAGIC variable%%%" +mkdir="mkdir" +mv="mv -f" +rm="rm -f" + +# Sed substitution that helps us do robust quoting. It backslashifies +# metacharacters that are still active within double-quoted strings. +Xsed="${SED}"' -e 1s/^X//' +sed_quote_subst='s/\([\\`\\"$\\\\]\)/\\\1/g' +# test EBCDIC or ASCII +case `echo X|tr X '\101'` in + A) # ASCII based system + # \n is not interpreted correctly by Solaris 8 /usr/ucb/tr + SP2NL='tr \040 \012' + NL2SP='tr \015\012 \040\040' + ;; + *) # EBCDIC based system + SP2NL='tr \100 \n' + NL2SP='tr \r\n \100\100' + ;; +esac + +# NLS nuisances. +# Only set LANG and LC_ALL to C if already set. +# These must not be set unconditionally because not all systems understand +# e.g. LANG=C (notably SCO). +# We save the old values to restore during execute mode. +for lt_var in LANG LC_ALL LC_CTYPE LC_COLLATE LC_MESSAGES +do + eval "if test \"\${$lt_var+set}\" = set; then + save_$lt_var=\$$lt_var + $lt_var=C + export $lt_var + fi" +done + +# Make sure IFS has a sensible default +lt_nl=' +' +IFS=" $lt_nl" + +if test "$build_libtool_libs" != yes && test "$build_old_libs" != yes; then + $echo "$modename: not configured to build any kind of library" 1>&2 + $echo "Fatal configuration error. See the $PACKAGE docs for more information." 1>&2 + exit $EXIT_FAILURE +fi + +# Global variables. +mode=$default_mode +nonopt= +prev= +prevopt= +run= +show="$echo" +show_help= +execute_dlfiles= +duplicate_deps=no +preserve_args= +lo2o="s/\\.lo\$/.${objext}/" +o2lo="s/\\.${objext}\$/.lo/" +extracted_archives= +extracted_serial=0 + +##################################### +# Shell function definitions: +# This seems to be the best place for them + +# func_mktempdir [string] +# Make a temporary directory that won't clash with other running +# libtool processes, and avoids race conditions if possible. If +# given, STRING is the basename for that directory. +func_mktempdir () +{ + my_template="${TMPDIR-/tmp}/${1-$progname}" + + if test "$run" = ":"; then + # Return a directory name, but don't create it in dry-run mode + my_tmpdir="${my_template}-$$" + else + + # If mktemp works, use that first and foremost + my_tmpdir=`mktemp -d "${my_template}-XXXXXXXX" 2>/dev/null` + + if test ! -d "$my_tmpdir"; then + # Failing that, at least try and use $RANDOM to avoid a race + my_tmpdir="${my_template}-${RANDOM-0}$$" + + save_mktempdir_umask=`umask` + umask 0077 + $mkdir "$my_tmpdir" + umask $save_mktempdir_umask + fi + + # If we're not in dry-run mode, bomb out on failure + test -d "$my_tmpdir" || { + $echo "cannot create temporary directory \`$my_tmpdir'" 1>&2 + exit $EXIT_FAILURE + } + fi + + $echo "X$my_tmpdir" | $Xsed +} + + +# func_win32_libid arg +# return the library type of file 'arg' +# +# Need a lot of goo to handle *both* DLLs and import libs +# Has to be a shell function in order to 'eat' the argument +# that is supplied when $file_magic_command is called. +func_win32_libid () +{ + win32_libid_type="unknown" + win32_fileres=`file -L $1 2>/dev/null` + case $win32_fileres in + *ar\ archive\ import\ library*) # definitely import + win32_libid_type="x86 archive import" + ;; + *ar\ archive*) # could be an import, or static + if eval $OBJDUMP -f $1 | $SED -e '10q' 2>/dev/null | \ + $EGREP -e 'file format pe-i386(.*architecture: i386)?' >/dev/null ; then + win32_nmres=`eval $NM -f posix -A $1 | \ + $SED -n -e '1,100{/ I /{s,.*,import,;p;q;};}'` + case $win32_nmres in + import*) win32_libid_type="x86 archive import";; + *) win32_libid_type="x86 archive static";; + esac + fi + ;; + *DLL*) + win32_libid_type="x86 DLL" + ;; + *executable*) # but shell scripts are "executable" too... + case $win32_fileres in + *MS\ Windows\ PE\ Intel*) + win32_libid_type="x86 DLL" + ;; + esac + ;; + esac + $echo $win32_libid_type +} + + +# func_infer_tag arg +# Infer tagged configuration to use if any are available and +# if one wasn't chosen via the "--tag" command line option. +# Only attempt this if the compiler in the base compile +# command doesn't match the default compiler. +# arg is usually of the form 'gcc ...' +func_infer_tag () +{ + if test -n "$available_tags" && test -z "$tagname"; then + CC_quoted= + for arg in $CC; do + case $arg in + *[\[\~\#\^\&\*\(\)\{\}\|\;\<\>\?\'\ \ ]*|*]*|"") + arg="\"$arg\"" + ;; + esac + CC_quoted="$CC_quoted $arg" + done + case $@ in + # Blanks in the command may have been stripped by the calling shell, + # but not from the CC environment variable when configure was run. + " $CC "* | "$CC "* | " `$echo $CC` "* | "`$echo $CC` "* | " $CC_quoted"* | "$CC_quoted "* | " `$echo $CC_quoted` "* | "`$echo $CC_quoted` "*) ;; + # Blanks at the start of $base_compile will cause this to fail + # if we don't check for them as well. + *) + for z in $available_tags; do + if grep "^# ### BEGIN LIBTOOL TAG CONFIG: $z$" < "$progpath" > /dev/null; then + # Evaluate the configuration. + eval "`${SED} -n -e '/^# ### BEGIN LIBTOOL TAG CONFIG: '$z'$/,/^# ### END LIBTOOL TAG CONFIG: '$z'$/p' < $progpath`" + CC_quoted= + for arg in $CC; do + # Double-quote args containing other shell metacharacters. + case $arg in + *[\[\~\#\^\&\*\(\)\{\}\|\;\<\>\?\'\ \ ]*|*]*|"") + arg="\"$arg\"" + ;; + esac + CC_quoted="$CC_quoted $arg" + done + case "$@ " in + " $CC "* | "$CC "* | " `$echo $CC` "* | "`$echo $CC` "* | " $CC_quoted"* | "$CC_quoted "* | " `$echo $CC_quoted` "* | "`$echo $CC_quoted` "*) + # The compiler in the base compile command matches + # the one in the tagged configuration. + # Assume this is the tagged configuration we want. + tagname=$z + break + ;; + esac + fi + done + # If $tagname still isn't set, then no tagged configuration + # was found and let the user know that the "--tag" command + # line option must be used. + if test -z "$tagname"; then + $echo "$modename: unable to infer tagged configuration" + $echo "$modename: specify a tag with \`--tag'" 1>&2 + exit $EXIT_FAILURE +# else +# $echo "$modename: using $tagname tagged configuration" + fi + ;; + esac + fi +} + + +# func_extract_an_archive dir oldlib +func_extract_an_archive () +{ + f_ex_an_ar_dir="$1"; shift + f_ex_an_ar_oldlib="$1" + + $show "(cd $f_ex_an_ar_dir && $AR x $f_ex_an_ar_oldlib)" + $run eval "(cd \$f_ex_an_ar_dir && $AR x \$f_ex_an_ar_oldlib)" || exit $? + if ($AR t "$f_ex_an_ar_oldlib" | sort | sort -uc >/dev/null 2>&1); then + : + else + $echo "$modename: ERROR: object name conflicts: $f_ex_an_ar_dir/$f_ex_an_ar_oldlib" 1>&2 + exit $EXIT_FAILURE + fi +} + +# func_extract_archives gentop oldlib ... +func_extract_archives () +{ + my_gentop="$1"; shift + my_oldlibs=${1+"$@"} + my_oldobjs="" + my_xlib="" + my_xabs="" + my_xdir="" + my_status="" + + $show "${rm}r $my_gentop" + $run ${rm}r "$my_gentop" + $show "$mkdir $my_gentop" + $run $mkdir "$my_gentop" + my_status=$? + if test "$my_status" -ne 0 && test ! -d "$my_gentop"; then + exit $my_status + fi + + for my_xlib in $my_oldlibs; do + # Extract the objects. + case $my_xlib in + [\\/]* | [A-Za-z]:[\\/]*) my_xabs="$my_xlib" ;; + *) my_xabs=`pwd`"/$my_xlib" ;; + esac + my_xlib=`$echo "X$my_xlib" | $Xsed -e 's%^.*/%%'` + my_xlib_u=$my_xlib + while :; do + case " $extracted_archives " in + *" $my_xlib_u "*) + extracted_serial=`expr $extracted_serial + 1` + my_xlib_u=lt$extracted_serial-$my_xlib ;; + *) break ;; + esac + done + extracted_archives="$extracted_archives $my_xlib_u" + my_xdir="$my_gentop/$my_xlib_u" + + $show "${rm}r $my_xdir" + $run ${rm}r "$my_xdir" + $show "$mkdir $my_xdir" + $run $mkdir "$my_xdir" + exit_status=$? + if test "$exit_status" -ne 0 && test ! -d "$my_xdir"; then + exit $exit_status + fi + case $host in + *-darwin*) + $show "Extracting $my_xabs" + # Do not bother doing anything if just a dry run + if test -z "$run"; then + darwin_orig_dir=`pwd` + cd $my_xdir || exit $? + darwin_archive=$my_xabs + darwin_curdir=`pwd` + darwin_base_archive=`$echo "X$darwin_archive" | $Xsed -e 's%^.*/%%'` + darwin_arches=`lipo -info "$darwin_archive" 2>/dev/null | $EGREP Architectures 2>/dev/null` + if test -n "$darwin_arches"; then + darwin_arches=`echo "$darwin_arches" | $SED -e 's/.*are://'` + darwin_arch= + $show "$darwin_base_archive has multiple architectures $darwin_arches" + for darwin_arch in $darwin_arches ; do + mkdir -p "unfat-$$/${darwin_base_archive}-${darwin_arch}" + lipo -thin $darwin_arch -output "unfat-$$/${darwin_base_archive}-${darwin_arch}/${darwin_base_archive}" "${darwin_archive}" + cd "unfat-$$/${darwin_base_archive}-${darwin_arch}" + func_extract_an_archive "`pwd`" "${darwin_base_archive}" + cd "$darwin_curdir" + $rm "unfat-$$/${darwin_base_archive}-${darwin_arch}/${darwin_base_archive}" + done # $darwin_arches + ## Okay now we have a bunch of thin objects, gotta fatten them up :) + darwin_filelist=`find unfat-$$ -type f -name \*.o -print -o -name \*.lo -print| xargs basename | sort -u | $NL2SP` + darwin_file= + darwin_files= + for darwin_file in $darwin_filelist; do + darwin_files=`find unfat-$$ -name $darwin_file -print | $NL2SP` + lipo -create -output "$darwin_file" $darwin_files + done # $darwin_filelist + ${rm}r unfat-$$ + cd "$darwin_orig_dir" + else + cd "$darwin_orig_dir" + func_extract_an_archive "$my_xdir" "$my_xabs" + fi # $darwin_arches + fi # $run + ;; + *) + func_extract_an_archive "$my_xdir" "$my_xabs" + ;; + esac + my_oldobjs="$my_oldobjs "`find $my_xdir -name \*.$objext -print -o -name \*.lo -print | $NL2SP` + done + func_extract_archives_result="$my_oldobjs" +} +# End of Shell function definitions +##################################### + +# Darwin sucks +eval std_shrext=\"$shrext_cmds\" + +disable_libs=no + +# Parse our command line options once, thoroughly. +while test "$#" -gt 0 +do + arg="$1" + shift + + case $arg in + -*=*) optarg=`$echo "X$arg" | $Xsed -e 's/[-_a-zA-Z0-9]*=//'` ;; + *) optarg= ;; + esac + + # If the previous option needs an argument, assign it. + if test -n "$prev"; then + case $prev in + execute_dlfiles) + execute_dlfiles="$execute_dlfiles $arg" + ;; + tag) + tagname="$arg" + preserve_args="${preserve_args}=$arg" + + # Check whether tagname contains only valid characters + case $tagname in + *[!-_A-Za-z0-9,/]*) + $echo "$progname: invalid tag name: $tagname" 1>&2 + exit $EXIT_FAILURE + ;; + esac + + case $tagname in + CC) + # Don't test for the "default" C tag, as we know, it's there, but + # not specially marked. + ;; + *) + if grep "^# ### BEGIN LIBTOOL TAG CONFIG: $tagname$" < "$progpath" > /dev/null; then + taglist="$taglist $tagname" + # Evaluate the configuration. + eval "`${SED} -n -e '/^# ### BEGIN LIBTOOL TAG CONFIG: '$tagname'$/,/^# ### END LIBTOOL TAG CONFIG: '$tagname'$/p' < $progpath`" + else + $echo "$progname: ignoring unknown tag $tagname" 1>&2 + fi + ;; + esac + ;; + *) + eval "$prev=\$arg" + ;; + esac + + prev= + prevopt= + continue + fi + + # Have we seen a non-optional argument yet? + case $arg in + --help) + show_help=yes + ;; + + --version) + $echo "$PROGRAM (GNU $PACKAGE) $VERSION$TIMESTAMP" + $echo + $echo "Copyright (C) 2005 Free Software Foundation, Inc." + $echo "This is free software; see the source for copying conditions. There is NO" + $echo "warranty; not even for MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE." + exit $? + ;; + + --config) + ${SED} -e '1,/^# ### BEGIN LIBTOOL CONFIG/d' -e '/^# ### END LIBTOOL CONFIG/,$d' $progpath + # Now print the configurations for the tags. + for tagname in $taglist; do + ${SED} -n -e "/^# ### BEGIN LIBTOOL TAG CONFIG: $tagname$/,/^# ### END LIBTOOL TAG CONFIG: $tagname$/p" < "$progpath" + done + exit $? + ;; + + --debug) + $echo "$progname: enabling shell trace mode" + set -x + preserve_args="$preserve_args $arg" + ;; + + --dry-run | -n) + run=: + ;; + + --features) + $echo "host: $host" + if test "$build_libtool_libs" = yes; then + $echo "enable shared libraries" + else + $echo "disable shared libraries" + fi + if test "$build_old_libs" = yes; then + $echo "enable static libraries" + else + $echo "disable static libraries" + fi + exit $? + ;; + + --finish) mode="finish" ;; + + --mode) prevopt="--mode" prev=mode ;; + --mode=*) mode="$optarg" ;; + + --preserve-dup-deps) duplicate_deps="yes" ;; + + --quiet | --silent) + show=: + preserve_args="$preserve_args $arg" + ;; + + --tag) + prevopt="--tag" + prev=tag + preserve_args="$preserve_args --tag" + ;; + --tag=*) + set tag "$optarg" ${1+"$@"} + shift + prev=tag + preserve_args="$preserve_args --tag" + ;; + + -dlopen) + prevopt="-dlopen" + prev=execute_dlfiles + ;; + + -*) + $echo "$modename: unrecognized option \`$arg'" 1>&2 + $echo "$help" 1>&2 + exit $EXIT_FAILURE + ;; + + *) + nonopt="$arg" + break + ;; + esac +done + +if test -n "$prevopt"; then + $echo "$modename: option \`$prevopt' requires an argument" 1>&2 + $echo "$help" 1>&2 + exit $EXIT_FAILURE +fi + +case $disable_libs in +no) + ;; +shared) + build_libtool_libs=no + build_old_libs=yes + ;; +static) + build_old_libs=`case $build_libtool_libs in yes) echo no;; *) echo yes;; esac` + ;; +esac + +# If this variable is set in any of the actions, the command in it +# will be execed at the end. This prevents here-documents from being +# left over by shells. +exec_cmd= + +if test -z "$show_help"; then + + # Infer the operation mode. + if test -z "$mode"; then + $echo "*** Warning: inferring the mode of operation is deprecated." 1>&2 + $echo "*** Future versions of Libtool will require --mode=MODE be specified." 1>&2 + case $nonopt in + *cc | cc* | *++ | gcc* | *-gcc* | g++* | xlc*) + mode=link + for arg + do + case $arg in + -c) + mode=compile + break + ;; + esac + done + ;; + *db | *dbx | *strace | *truss) + mode=execute + ;; + *install*|cp|mv) + mode=install + ;; + *rm) + mode=uninstall + ;; + *) + # If we have no mode, but dlfiles were specified, then do execute mode. + test -n "$execute_dlfiles" && mode=execute + + # Just use the default operation mode. + if test -z "$mode"; then + if test -n "$nonopt"; then + $echo "$modename: warning: cannot infer operation mode from \`$nonopt'" 1>&2 + else + $echo "$modename: warning: cannot infer operation mode without MODE-ARGS" 1>&2 + fi + fi + ;; + esac + fi + + # Only execute mode is allowed to have -dlopen flags. + if test -n "$execute_dlfiles" && test "$mode" != execute; then + $echo "$modename: unrecognized option \`-dlopen'" 1>&2 + $echo "$help" 1>&2 + exit $EXIT_FAILURE + fi + + # Change the help message to a mode-specific one. + generic_help="$help" + help="Try \`$modename --help --mode=$mode' for more information." + + # These modes are in order of execution frequency so that they run quickly. + case $mode in + # libtool compile mode + compile) + modename="$modename: compile" + # Get the compilation command and the source file. + base_compile= + srcfile="$nonopt" # always keep a non-empty value in "srcfile" + suppress_opt=yes + suppress_output= + arg_mode=normal + libobj= + later= + + for arg + do + case $arg_mode in + arg ) + # do not "continue". Instead, add this to base_compile + lastarg="$arg" + arg_mode=normal + ;; + + target ) + libobj="$arg" + arg_mode=normal + continue + ;; + + normal ) + # Accept any command-line options. + case $arg in + -o) + if test -n "$libobj" ; then + $echo "$modename: you cannot specify \`-o' more than once" 1>&2 + exit $EXIT_FAILURE + fi + arg_mode=target + continue + ;; + + -static | -prefer-pic | -prefer-non-pic) + later="$later $arg" + continue + ;; + + -no-suppress) + suppress_opt=no + continue + ;; + + -Xcompiler) + arg_mode=arg # the next one goes into the "base_compile" arg list + continue # The current "srcfile" will either be retained or + ;; # replaced later. I would guess that would be a bug. + + -Wc,*) + args=`$echo "X$arg" | $Xsed -e "s/^-Wc,//"` + lastarg= + save_ifs="$IFS"; IFS=',' + for arg in $args; do + IFS="$save_ifs" + + # Double-quote args containing other shell metacharacters. + # Many Bourne shells cannot handle close brackets correctly + # in scan sets, so we specify it separately. + case $arg in + *[\[\~\#\^\&\*\(\)\{\}\|\;\<\>\?\'\ \ ]*|*]*|"") + arg="\"$arg\"" + ;; + esac + lastarg="$lastarg $arg" + done + IFS="$save_ifs" + lastarg=`$echo "X$lastarg" | $Xsed -e "s/^ //"` + + # Add the arguments to base_compile. + base_compile="$base_compile $lastarg" + continue + ;; + + * ) + # Accept the current argument as the source file. + # The previous "srcfile" becomes the current argument. + # + lastarg="$srcfile" + srcfile="$arg" + ;; + esac # case $arg + ;; + esac # case $arg_mode + + # Aesthetically quote the previous argument. + lastarg=`$echo "X$lastarg" | $Xsed -e "$sed_quote_subst"` + + case $lastarg in + # Double-quote args containing other shell metacharacters. + # Many Bourne shells cannot handle close brackets correctly + # in scan sets, and some SunOS ksh mistreat backslash-escaping + # in scan sets (worked around with variable expansion), + # and furthermore cannot handle '|' '&' '(' ')' in scan sets + # at all, so we specify them separately. + *[\[\~\#\^\&\*\(\)\{\}\|\;\<\>\?\'\ \ ]*|*]*|"") + lastarg="\"$lastarg\"" + ;; + esac + + base_compile="$base_compile $lastarg" + done # for arg + + case $arg_mode in + arg) + $echo "$modename: you must specify an argument for -Xcompile" + exit $EXIT_FAILURE + ;; + target) + $echo "$modename: you must specify a target with \`-o'" 1>&2 + exit $EXIT_FAILURE + ;; + *) + # Get the name of the library object. + [ -z "$libobj" ] && libobj=`$echo "X$srcfile" | $Xsed -e 's%^.*/%%'` + ;; + esac + + # Recognize several different file suffixes. + # If the user specifies -o file.o, it is replaced with file.lo + xform='[cCFSifmso]' + case $libobj in + *.ada) xform=ada ;; + *.adb) xform=adb ;; + *.ads) xform=ads ;; + *.asm) xform=asm ;; + *.c++) xform=c++ ;; + *.cc) xform=cc ;; + *.ii) xform=ii ;; + *.class) xform=class ;; + *.cpp) xform=cpp ;; + *.cxx) xform=cxx ;; + *.f90) xform=f90 ;; + *.for) xform=for ;; + *.java) xform=java ;; + *.obj) xform=obj ;; + esac + + libobj=`$echo "X$libobj" | $Xsed -e "s/\.$xform$/.lo/"` + + case $libobj in + *.lo) obj=`$echo "X$libobj" | $Xsed -e "$lo2o"` ;; + *) + $echo "$modename: cannot determine name of library object from \`$libobj'" 1>&2 + exit $EXIT_FAILURE + ;; + esac + + func_infer_tag $base_compile + + for arg in $later; do + case $arg in + -static) + build_old_libs=yes + continue + ;; + + -prefer-pic) + pic_mode=yes + continue + ;; + + -prefer-non-pic) + pic_mode=no + continue + ;; + esac + done + + qlibobj=`$echo "X$libobj" | $Xsed -e "$sed_quote_subst"` + case $qlibobj in + *[\[\~\#\^\&\*\(\)\{\}\|\;\<\>\?\'\ \ ]*|*]*|"") + qlibobj="\"$qlibobj\"" ;; + esac + test "X$libobj" != "X$qlibobj" \ + && $echo "X$libobj" | grep '[]~#^*{};<>?"'"'"' &()|`$[]' \ + && $echo "$modename: libobj name \`$libobj' may not contain shell special characters." + objname=`$echo "X$obj" | $Xsed -e 's%^.*/%%'` + xdir=`$echo "X$obj" | $Xsed -e 's%/[^/]*$%%'` + if test "X$xdir" = "X$obj"; then + xdir= + else + xdir=$xdir/ + fi + lobj=${xdir}$objdir/$objname + + if test -z "$base_compile"; then + $echo "$modename: you must specify a compilation command" 1>&2 + $echo "$help" 1>&2 + exit $EXIT_FAILURE + fi + + # Delete any leftover library objects. + if test "$build_old_libs" = yes; then + removelist="$obj $lobj $libobj ${libobj}T" + else + removelist="$lobj $libobj ${libobj}T" + fi + + $run $rm $removelist + trap "$run $rm $removelist; exit $EXIT_FAILURE" 1 2 15 + + # On Cygwin there's no "real" PIC flag so we must build both object types + case $host_os in + cygwin* | mingw* | pw32* | os2*) + pic_mode=default + ;; + esac + if test "$pic_mode" = no && test "$deplibs_check_method" != pass_all; then + # non-PIC code in shared libraries is not supported + pic_mode=default + fi + + # Calculate the filename of the output object if compiler does + # not support -o with -c + if test "$compiler_c_o" = no; then + output_obj=`$echo "X$srcfile" | $Xsed -e 's%^.*/%%' -e 's%\.[^.]*$%%'`.${objext} + lockfile="$output_obj.lock" + removelist="$removelist $output_obj $lockfile" + trap "$run $rm $removelist; exit $EXIT_FAILURE" 1 2 15 + else + output_obj= + need_locks=no + lockfile= + fi + + # Lock this critical section if it is needed + # We use this script file to make the link, it avoids creating a new file + if test "$need_locks" = yes; then + until $run ln "$progpath" "$lockfile" 2>/dev/null; do + $show "Waiting for $lockfile to be removed" + sleep 2 + done + elif test "$need_locks" = warn; then + if test -f "$lockfile"; then + $echo "\ +*** ERROR, $lockfile exists and contains: +`cat $lockfile 2>/dev/null` + +This indicates that another process is trying to use the same +temporary object file, and libtool could not work around it because +your compiler does not support \`-c' and \`-o' together. If you +repeat this compilation, it may succeed, by chance, but you had better +avoid parallel builds (make -j) in this platform, or get a better +compiler." + + $run $rm $removelist + exit $EXIT_FAILURE + fi + $echo "$srcfile" > "$lockfile" + fi + + if test -n "$fix_srcfile_path"; then + eval srcfile=\"$fix_srcfile_path\" + fi + qsrcfile=`$echo "X$srcfile" | $Xsed -e "$sed_quote_subst"` + case $qsrcfile in + *[\[\~\#\^\&\*\(\)\{\}\|\;\<\>\?\'\ \ ]*|*]*|"") + qsrcfile="\"$qsrcfile\"" ;; + esac + + $run $rm "$libobj" "${libobj}T" + + # Create a libtool object file (analogous to a ".la" file), + # but don't create it if we're doing a dry run. + test -z "$run" && cat > ${libobj}T <<EOF +# $libobj - a libtool object file +# Generated by $PROGRAM - GNU $PACKAGE $VERSION$TIMESTAMP +# +# Please DO NOT delete this file! +# It is necessary for linking the library. + +# Name of the PIC object. +EOF + + # Only build a PIC object if we are building libtool libraries. + if test "$build_libtool_libs" = yes; then + # Without this assignment, base_compile gets emptied. + fbsd_hideous_sh_bug=$base_compile + + if test "$pic_mode" != no; then + command="$base_compile $qsrcfile $pic_flag" + else + # Don't build PIC code + command="$base_compile $qsrcfile" + fi + + if test ! -d "${xdir}$objdir"; then + $show "$mkdir ${xdir}$objdir" + $run $mkdir ${xdir}$objdir + exit_status=$? + if test "$exit_status" -ne 0 && test ! -d "${xdir}$objdir"; then + exit $exit_status + fi + fi + + if test -z "$output_obj"; then + # Place PIC objects in $objdir + command="$command -o $lobj" + fi + + $run $rm "$lobj" "$output_obj" + + $show "$command" + if $run eval "$command"; then : + else + test -n "$output_obj" && $run $rm $removelist + exit $EXIT_FAILURE + fi + + if test "$need_locks" = warn && + test "X`cat $lockfile 2>/dev/null`" != "X$srcfile"; then + $echo "\ +*** ERROR, $lockfile contains: +`cat $lockfile 2>/dev/null` + +but it should contain: +$srcfile + +This indicates that another process is trying to use the same +temporary object file, and libtool could not work around it because +your compiler does not support \`-c' and \`-o' together. If you +repeat this compilation, it may succeed, by chance, but you had better +avoid parallel builds (make -j) in this platform, or get a better +compiler." + + $run $rm $removelist + exit $EXIT_FAILURE + fi + + # Just move the object if needed, then go on to compile the next one + if test -n "$output_obj" && test "X$output_obj" != "X$lobj"; then + $show "$mv $output_obj $lobj" + if $run $mv $output_obj $lobj; then : + else + error=$? + $run $rm $removelist + exit $error + fi + fi + + # Append the name of the PIC object to the libtool object file. + test -z "$run" && cat >> ${libobj}T <<EOF +pic_object='$objdir/$objname' + +EOF + + # Allow error messages only from the first compilation. + if test "$suppress_opt" = yes; then + suppress_output=' >/dev/null 2>&1' + fi + else + # No PIC object so indicate it doesn't exist in the libtool + # object file. + test -z "$run" && cat >> ${libobj}T <<EOF +pic_object=none + +EOF + fi + + # Only build a position-dependent object if we build old libraries. + if test "$build_old_libs" = yes; then + if test "$pic_mode" != yes; then + # Don't build PIC code + command="$base_compile $qsrcfile" + else + command="$base_compile $qsrcfile $pic_flag" + fi + if test "$compiler_c_o" = yes; then + command="$command -o $obj" + fi + + # Suppress compiler output if we already did a PIC compilation. + command="$command$suppress_output" + $run $rm "$obj" "$output_obj" + $show "$command" + if $run eval "$command"; then : + else + $run $rm $removelist + exit $EXIT_FAILURE + fi + + if test "$need_locks" = warn && + test "X`cat $lockfile 2>/dev/null`" != "X$srcfile"; then + $echo "\ +*** ERROR, $lockfile contains: +`cat $lockfile 2>/dev/null` + +but it should contain: +$srcfile + +This indicates that another process is trying to use the same +temporary object file, and libtool could not work around it because +your compiler does not support \`-c' and \`-o' together. If you +repeat this compilation, it may succeed, by chance, but you had better +avoid parallel builds (make -j) in this platform, or get a better +compiler." + + $run $rm $removelist + exit $EXIT_FAILURE + fi + + # Just move the object if needed + if test -n "$output_obj" && test "X$output_obj" != "X$obj"; then + $show "$mv $output_obj $obj" + if $run $mv $output_obj $obj; then : + else + error=$? + $run $rm $removelist + exit $error + fi + fi + + # Append the name of the non-PIC object the libtool object file. + # Only append if the libtool object file exists. + test -z "$run" && cat >> ${libobj}T <<EOF +# Name of the non-PIC object. +non_pic_object='$objname' + +EOF + else + # Append the name of the non-PIC object the libtool object file. + # Only append if the libtool object file exists. + test -z "$run" && cat >> ${libobj}T <<EOF +# Name of the non-PIC object. +non_pic_object=none + +EOF + fi + + $run $mv "${libobj}T" "${libobj}" + + # Unlock the critical section if it was locked + if test "$need_locks" != no; then + $run $rm "$lockfile" + fi + + exit $EXIT_SUCCESS + ;; + + # libtool link mode + link | relink) + modename="$modename: link" + case $host in + *-*-cygwin* | *-*-mingw* | *-*-pw32* | *-*-os2*) + # It is impossible to link a dll without this setting, and + # we shouldn't force the makefile maintainer to figure out + # which system we are compiling for in order to pass an extra + # flag for every libtool invocation. + # allow_undefined=no + + # FIXME: Unfortunately, there are problems with the above when trying + # to make a dll which has undefined symbols, in which case not + # even a static library is built. For now, we need to specify + # -no-undefined on the libtool link line when we can be certain + # that all symbols are satisfied, otherwise we get a static library. + allow_undefined=yes + ;; + *) + allow_undefined=yes + ;; + esac + libtool_args="$nonopt" + base_compile="$nonopt $@" + compile_command="$nonopt" + finalize_command="$nonopt" + + compile_rpath= + finalize_rpath= + compile_shlibpath= + finalize_shlibpath= + convenience= + old_convenience= + deplibs= + old_deplibs= + compiler_flags= + linker_flags= + dllsearchpath= + lib_search_path=`pwd` + inst_prefix_dir= + + avoid_version=no + dlfiles= + dlprefiles= + dlself=no + export_dynamic=no + export_symbols= + export_symbols_regex= + generated= + libobjs= + ltlibs= + module=no + no_install=no + objs= + non_pic_objects= + notinst_path= # paths that contain not-installed libtool libraries + precious_files_regex= + prefer_static_libs=no + preload=no + prev= + prevarg= + release= + rpath= + xrpath= + perm_rpath= + temp_rpath= + thread_safe=no + vinfo= + vinfo_number=no + + func_infer_tag $base_compile + + # We need to know -static, to get the right output filenames. + for arg + do + case $arg in + -all-static | -static | -static-libtool-libs) + case $arg in + -all-static) + if test "$build_libtool_libs" = yes && test -z "$link_static_flag"; then + $echo "$modename: warning: complete static linking is impossible in this configuration" 1>&2 + fi + if test -n "$link_static_flag"; then + dlopen_self=$dlopen_self_static + fi + prefer_static_libs=yes + ;; + -static) + if test -z "$pic_flag" && test -n "$link_static_flag"; then + dlopen_self=$dlopen_self_static + fi + prefer_static_libs=built + ;; + -static-libtool-libs) + if test -z "$pic_flag" && test -n "$link_static_flag"; then + dlopen_self=$dlopen_self_static + fi + prefer_static_libs=yes + ;; + esac + build_libtool_libs=no + build_old_libs=yes + break + ;; + esac + done + + # See if our shared archives depend on static archives. + test -n "$old_archive_from_new_cmds" && build_old_libs=yes + + # Go through the arguments, transforming them on the way. + while test "$#" -gt 0; do + arg="$1" + shift + case $arg in + *[\[\~\#\^\&\*\(\)\{\}\|\;\<\>\?\'\ \ ]*|*]*|"") + qarg=\"`$echo "X$arg" | $Xsed -e "$sed_quote_subst"`\" ### testsuite: skip nested quoting test + ;; + *) qarg=$arg ;; + esac + libtool_args="$libtool_args $qarg" + + # If the previous option needs an argument, assign it. + if test -n "$prev"; then + case $prev in + output) + compile_command="$compile_command @OUTPUT@" + finalize_command="$finalize_command @OUTPUT@" + ;; + esac + + case $prev in + dlfiles|dlprefiles) + if test "$preload" = no; then + # Add the symbol object into the linking commands. + compile_command="$compile_command @SYMFILE@" + finalize_command="$finalize_command @SYMFILE@" + preload=yes + fi + case $arg in + *.la | *.lo) ;; # We handle these cases below. + force) + if test "$dlself" = no; then + dlself=needless + export_dynamic=yes + fi + prev= + continue + ;; + self) + if test "$prev" = dlprefiles; then + dlself=yes + elif test "$prev" = dlfiles && test "$dlopen_self" != yes; then + dlself=yes + else + dlself=needless + export_dynamic=yes + fi + prev= + continue + ;; + *) + if test "$prev" = dlfiles; then + dlfiles="$dlfiles $arg" + else + dlprefiles="$dlprefiles $arg" + fi + prev= + continue + ;; + esac + ;; + expsyms) + export_symbols="$arg" + if test ! -f "$arg"; then + $echo "$modename: symbol file \`$arg' does not exist" + exit $EXIT_FAILURE + fi + prev= + continue + ;; + expsyms_regex) + export_symbols_regex="$arg" + prev= + continue + ;; + inst_prefix) + inst_prefix_dir="$arg" + prev= + continue + ;; + precious_regex) + precious_files_regex="$arg" + prev= + continue + ;; + release) + release="-$arg" + prev= + continue + ;; + objectlist) + if test -f "$arg"; then + save_arg=$arg + moreargs= + for fil in `cat $save_arg` + do +# moreargs="$moreargs $fil" + arg=$fil + # A libtool-controlled object. + + # Check to see that this really is a libtool object. + if (${SED} -e '2q' $arg | grep "^# Generated by .*$PACKAGE") >/dev/null 2>&1; then + pic_object= + non_pic_object= + + # Read the .lo file + # If there is no directory component, then add one. + case $arg in + */* | *\\*) . $arg ;; + *) . ./$arg ;; + esac + + if test -z "$pic_object" || \ + test -z "$non_pic_object" || + test "$pic_object" = none && \ + test "$non_pic_object" = none; then + $echo "$modename: cannot find name of object for \`$arg'" 1>&2 + exit $EXIT_FAILURE + fi + + # Extract subdirectory from the argument. + xdir=`$echo "X$arg" | $Xsed -e 's%/[^/]*$%%'` + if test "X$xdir" = "X$arg"; then + xdir= + else + xdir="$xdir/" + fi + + if test "$pic_object" != none; then + # Prepend the subdirectory the object is found in. + pic_object="$xdir$pic_object" + + if test "$prev" = dlfiles; then + if test "$build_libtool_libs" = yes && test "$dlopen_support" = yes; then + dlfiles="$dlfiles $pic_object" + prev= + continue + else + # If libtool objects are unsupported, then we need to preload. + prev=dlprefiles + fi + fi + + # CHECK ME: I think I busted this. -Ossama + if test "$prev" = dlprefiles; then + # Preload the old-style object. + dlprefiles="$dlprefiles $pic_object" + prev= + fi + + # A PIC object. + libobjs="$libobjs $pic_object" + arg="$pic_object" + fi + + # Non-PIC object. + if test "$non_pic_object" != none; then + # Prepend the subdirectory the object is found in. + non_pic_object="$xdir$non_pic_object" + + # A standard non-PIC object + non_pic_objects="$non_pic_objects $non_pic_object" + if test -z "$pic_object" || test "$pic_object" = none ; then + arg="$non_pic_object" + fi + else + # If the PIC object exists, use it instead. + # $xdir was prepended to $pic_object above. + non_pic_object="$pic_object" + non_pic_objects="$non_pic_objects $non_pic_object" + fi + else + # Only an error if not doing a dry-run. + if test -z "$run"; then + $echo "$modename: \`$arg' is not a valid libtool object" 1>&2 + exit $EXIT_FAILURE + else + # Dry-run case. + + # Extract subdirectory from the argument. + xdir=`$echo "X$arg" | $Xsed -e 's%/[^/]*$%%'` + if test "X$xdir" = "X$arg"; then + xdir= + else + xdir="$xdir/" + fi + + pic_object=`$echo "X${xdir}${objdir}/${arg}" | $Xsed -e "$lo2o"` + non_pic_object=`$echo "X${xdir}${arg}" | $Xsed -e "$lo2o"` + libobjs="$libobjs $pic_object" + non_pic_objects="$non_pic_objects $non_pic_object" + fi + fi + done + else + $echo "$modename: link input file \`$save_arg' does not exist" + exit $EXIT_FAILURE + fi + arg=$save_arg + prev= + continue + ;; + rpath | xrpath) + # We need an absolute path. + case $arg in + [\\/]* | [A-Za-z]:[\\/]*) ;; + *) + $echo "$modename: only absolute run-paths are allowed" 1>&2 + exit $EXIT_FAILURE + ;; + esac + if test "$prev" = rpath; then + case "$rpath " in + *" $arg "*) ;; + *) rpath="$rpath $arg" ;; + esac + else + case "$xrpath " in + *" $arg "*) ;; + *) xrpath="$xrpath $arg" ;; + esac + fi + prev= + continue + ;; + xcompiler) + compiler_flags="$compiler_flags $qarg" + prev= + compile_command="$compile_command $qarg" + finalize_command="$finalize_command $qarg" + continue + ;; + xlinker) + linker_flags="$linker_flags $qarg" + compiler_flags="$compiler_flags $wl$qarg" + prev= + compile_command="$compile_command $wl$qarg" + finalize_command="$finalize_command $wl$qarg" + continue + ;; + xcclinker) + linker_flags="$linker_flags $qarg" + compiler_flags="$compiler_flags $qarg" + prev= + compile_command="$compile_command $qarg" + finalize_command="$finalize_command $qarg" + continue + ;; + shrext) + shrext_cmds="$arg" + prev= + continue + ;; + darwin_framework|darwin_framework_skip) + test "$prev" = "darwin_framework" && compiler_flags="$compiler_flags $arg" + compile_command="$compile_command $arg" + finalize_command="$finalize_command $arg" + prev= + continue + ;; + *) + eval "$prev=\"\$arg\"" + prev= + continue + ;; + esac + fi # test -n "$prev" + + prevarg="$arg" + + case $arg in + -all-static) + if test -n "$link_static_flag"; then + compile_command="$compile_command $link_static_flag" + finalize_command="$finalize_command $link_static_flag" + fi + continue + ;; + + -allow-undefined) + # FIXME: remove this flag sometime in the future. + $echo "$modename: \`-allow-undefined' is deprecated because it is the default" 1>&2 + continue + ;; + + -avoid-version) + avoid_version=yes + continue + ;; + + -dlopen) + prev=dlfiles + continue + ;; + + -dlpreopen) + prev=dlprefiles + continue + ;; + + -export-dynamic) + export_dynamic=yes + continue + ;; + + -export-symbols | -export-symbols-regex) + if test -n "$export_symbols" || test -n "$export_symbols_regex"; then + $echo "$modename: more than one -exported-symbols argument is not allowed" + exit $EXIT_FAILURE + fi + if test "X$arg" = "X-export-symbols"; then + prev=expsyms + else + prev=expsyms_regex + fi + continue + ;; + + -framework|-arch|-isysroot) + case " $CC " in + *" ${arg} ${1} "* | *" ${arg} ${1} "*) + prev=darwin_framework_skip ;; + *) compiler_flags="$compiler_flags $arg" + prev=darwin_framework ;; + esac + compile_command="$compile_command $arg" + finalize_command="$finalize_command $arg" + continue + ;; + + -inst-prefix-dir) + prev=inst_prefix + continue + ;; + + # The native IRIX linker understands -LANG:*, -LIST:* and -LNO:* + # so, if we see these flags be careful not to treat them like -L + -L[A-Z][A-Z]*:*) + case $with_gcc/$host in + no/*-*-irix* | /*-*-irix*) + compile_command="$compile_command $arg" + finalize_command="$finalize_command $arg" + ;; + esac + continue + ;; + + -L*) + dir=`$echo "X$arg" | $Xsed -e 's/^-L//'` + # We need an absolute path. + case $dir in + [\\/]* | [A-Za-z]:[\\/]*) ;; + *) + absdir=`cd "$dir" && pwd` + if test -z "$absdir"; then + $echo "$modename: cannot determine absolute directory name of \`$dir'" 1>&2 + absdir="$dir" + notinst_path="$notinst_path $dir" + fi + dir="$absdir" + ;; + esac + case "$deplibs " in + *" -L$dir "*) ;; + *) + deplibs="$deplibs -L$dir" + lib_search_path="$lib_search_path $dir" + ;; + esac + case $host in + *-*-cygwin* | *-*-mingw* | *-*-pw32* | *-*-os2*) + testbindir=`$echo "X$dir" | $Xsed -e 's*/lib$*/bin*'` + case :$dllsearchpath: in + *":$dir:"*) ;; + *) dllsearchpath="$dllsearchpath:$dir";; + esac + case :$dllsearchpath: in + *":$testbindir:"*) ;; + *) dllsearchpath="$dllsearchpath:$testbindir";; + esac + ;; + esac + continue + ;; + + -l*) + if test "X$arg" = "X-lc" || test "X$arg" = "X-lm"; then + case $host in + *-*-cygwin* | *-*-mingw* | *-*-pw32* | *-*-beos*) + # These systems don't actually have a C or math library (as such) + continue + ;; + *-*-os2*) + # These systems don't actually have a C library (as such) + test "X$arg" = "X-lc" && continue + ;; + *-*-openbsd* | *-*-freebsd* | *-*-dragonfly*) + # Do not include libc due to us having libc/libc_r. + test "X$arg" = "X-lc" && continue + ;; + *-*-rhapsody* | *-*-darwin1.[012]) + # Rhapsody C and math libraries are in the System framework + deplibs="$deplibs -framework System" + continue + ;; + *-*-sco3.2v5* | *-*-sco5v6*) + # Causes problems with __ctype + test "X$arg" = "X-lc" && continue + ;; + *-*-sysv4.2uw2* | *-*-sysv5* | *-*-unixware* | *-*-OpenUNIX*) + # Compiler inserts libc in the correct place for threads to work + test "X$arg" = "X-lc" && continue + ;; + esac + elif test "X$arg" = "X-lc_r"; then + case $host in + *-*-openbsd* | *-*-freebsd* | *-*-dragonfly*) + # Do not include libc_r directly, use -pthread flag. + continue + ;; + esac + fi + deplibs="$deplibs $arg" + continue + ;; + + # Tru64 UNIX uses -model [arg] to determine the layout of C++ + # classes, name mangling, and exception handling. + -model) + compile_command="$compile_command $arg" + compiler_flags="$compiler_flags $arg" + finalize_command="$finalize_command $arg" + prev=xcompiler + continue + ;; + + -mt|-mthreads|-kthread|-Kthread|-pthread|-pthreads|--thread-safe) + compiler_flags="$compiler_flags $arg" + compile_command="$compile_command $arg" + finalize_command="$finalize_command $arg" + continue + ;; + + -module) + module=yes + continue + ;; + + # -64, -mips[0-9] enable 64-bit mode on the SGI compiler + # -r[0-9][0-9]* specifies the processor on the SGI compiler + # -xarch=*, -xtarget=* enable 64-bit mode on the Sun compiler + # +DA*, +DD* enable 64-bit mode on the HP compiler + # -q* pass through compiler args for the IBM compiler + # -m* pass through architecture-specific compiler args for GCC + # -m*, -t[45]*, -txscale* pass through architecture-specific + # compiler args for GCC + # -pg pass through profiling flag for GCC + # @file GCC response files + -64|-mips[0-9]|-r[0-9][0-9]*|-xarch=*|-xtarget=*|+DA*|+DD*|-q*|-m*|-pg| \ + -t[45]*|-txscale*|@*) + + # Unknown arguments in both finalize_command and compile_command need + # to be aesthetically quoted because they are evaled later. + arg=`$echo "X$arg" | $Xsed -e "$sed_quote_subst"` + case $arg in + *[\[\~\#\^\&\*\(\)\{\}\|\;\<\>\?\'\ \ ]*|*]*|"") + arg="\"$arg\"" + ;; + esac + compile_command="$compile_command $arg" + finalize_command="$finalize_command $arg" + compiler_flags="$compiler_flags $arg" + continue + ;; + + -shrext) + prev=shrext + continue + ;; + + -no-fast-install) + fast_install=no + continue + ;; + + -no-install) + case $host in + *-*-cygwin* | *-*-mingw* | *-*-pw32* | *-*-os2*) + # The PATH hackery in wrapper scripts is required on Windows + # in order for the loader to find any dlls it needs. + $echo "$modename: warning: \`-no-install' is ignored for $host" 1>&2 + $echo "$modename: warning: assuming \`-no-fast-install' instead" 1>&2 + fast_install=no + ;; + *) no_install=yes ;; + esac + continue + ;; + + -no-undefined) + allow_undefined=no + continue + ;; + + -objectlist) + prev=objectlist + continue + ;; + + -o) prev=output ;; + + -precious-files-regex) + prev=precious_regex + continue + ;; + + -release) + prev=release + continue + ;; + + -rpath) + prev=rpath + continue + ;; + + -R) + prev=xrpath + continue + ;; + + -R*) + dir=`$echo "X$arg" | $Xsed -e 's/^-R//'` + # We need an absolute path. + case $dir in + [\\/]* | [A-Za-z]:[\\/]*) ;; + *) + $echo "$modename: only absolute run-paths are allowed" 1>&2 + exit $EXIT_FAILURE + ;; + esac + case "$xrpath " in + *" $dir "*) ;; + *) xrpath="$xrpath $dir" ;; + esac + continue + ;; + + -static | -static-libtool-libs) + # The effects of -static are defined in a previous loop. + # We used to do the same as -all-static on platforms that + # didn't have a PIC flag, but the assumption that the effects + # would be equivalent was wrong. It would break on at least + # Digital Unix and AIX. + continue + ;; + + -thread-safe) + thread_safe=yes + continue + ;; + + -version-info) + prev=vinfo + continue + ;; + -version-number) + prev=vinfo + vinfo_number=yes + continue + ;; + + -Wc,*) + args=`$echo "X$arg" | $Xsed -e "$sed_quote_subst" -e 's/^-Wc,//'` + arg= + save_ifs="$IFS"; IFS=',' + for flag in $args; do + IFS="$save_ifs" + case $flag in + *[\[\~\#\^\&\*\(\)\{\}\|\;\<\>\?\'\ \ ]*|*]*|"") + flag="\"$flag\"" + ;; + esac + arg="$arg $wl$flag" + compiler_flags="$compiler_flags $flag" + done + IFS="$save_ifs" + arg=`$echo "X$arg" | $Xsed -e "s/^ //"` + ;; + + -Wl,*) + args=`$echo "X$arg" | $Xsed -e "$sed_quote_subst" -e 's/^-Wl,//'` + arg= + save_ifs="$IFS"; IFS=',' + for flag in $args; do + IFS="$save_ifs" + case $flag in + *[\[\~\#\^\&\*\(\)\{\}\|\;\<\>\?\'\ \ ]*|*]*|"") + flag="\"$flag\"" + ;; + esac + arg="$arg $wl$flag" + compiler_flags="$compiler_flags $wl$flag" + linker_flags="$linker_flags $flag" + done + IFS="$save_ifs" + arg=`$echo "X$arg" | $Xsed -e "s/^ //"` + ;; + + -Xcompiler) + prev=xcompiler + continue + ;; + + -Xlinker) + prev=xlinker + continue + ;; + + -XCClinker) + prev=xcclinker + continue + ;; + + # Some other compiler flag. + -* | +*) + # Unknown arguments in both finalize_command and compile_command need + # to be aesthetically quoted because they are evaled later. + arg=`$echo "X$arg" | $Xsed -e "$sed_quote_subst"` + case $arg in + *[\[\~\#\^\&\*\(\)\{\}\|\;\<\>\?\'\ \ ]*|*]*|"") + arg="\"$arg\"" + ;; + esac + ;; + + *.$objext) + # A standard object. + objs="$objs $arg" + ;; + + *.lo) + # A libtool-controlled object. + + # Check to see that this really is a libtool object. + if (${SED} -e '2q' $arg | grep "^# Generated by .*$PACKAGE") >/dev/null 2>&1; then + pic_object= + non_pic_object= + + # Read the .lo file + # If there is no directory component, then add one. + case $arg in + */* | *\\*) . $arg ;; + *) . ./$arg ;; + esac + + if test -z "$pic_object" || \ + test -z "$non_pic_object" || + test "$pic_object" = none && \ + test "$non_pic_object" = none; then + $echo "$modename: cannot find name of object for \`$arg'" 1>&2 + exit $EXIT_FAILURE + fi + + # Extract subdirectory from the argument. + xdir=`$echo "X$arg" | $Xsed -e 's%/[^/]*$%%'` + if test "X$xdir" = "X$arg"; then + xdir= + else + xdir="$xdir/" + fi + + if test "$pic_object" != none; then + # Prepend the subdirectory the object is found in. + pic_object="$xdir$pic_object" + + if test "$prev" = dlfiles; then + if test "$build_libtool_libs" = yes && test "$dlopen_support" = yes; then + dlfiles="$dlfiles $pic_object" + prev= + continue + else + # If libtool objects are unsupported, then we need to preload. + prev=dlprefiles + fi + fi + + # CHECK ME: I think I busted this. -Ossama + if test "$prev" = dlprefiles; then + # Preload the old-style object. + dlprefiles="$dlprefiles $pic_object" + prev= + fi + + # A PIC object. + libobjs="$libobjs $pic_object" + arg="$pic_object" + fi + + # Non-PIC object. + if test "$non_pic_object" != none; then + # Prepend the subdirectory the object is found in. + non_pic_object="$xdir$non_pic_object" + + # A standard non-PIC object + non_pic_objects="$non_pic_objects $non_pic_object" + if test -z "$pic_object" || test "$pic_object" = none ; then + arg="$non_pic_object" + fi + else + # If the PIC object exists, use it instead. + # $xdir was prepended to $pic_object above. + non_pic_object="$pic_object" + non_pic_objects="$non_pic_objects $non_pic_object" + fi + else + # Only an error if not doing a dry-run. + if test -z "$run"; then + $echo "$modename: \`$arg' is not a valid libtool object" 1>&2 + exit $EXIT_FAILURE + else + # Dry-run case. + + # Extract subdirectory from the argument. + xdir=`$echo "X$arg" | $Xsed -e 's%/[^/]*$%%'` + if test "X$xdir" = "X$arg"; then + xdir= + else + xdir="$xdir/" + fi + + pic_object=`$echo "X${xdir}${objdir}/${arg}" | $Xsed -e "$lo2o"` + non_pic_object=`$echo "X${xdir}${arg}" | $Xsed -e "$lo2o"` + libobjs="$libobjs $pic_object" + non_pic_objects="$non_pic_objects $non_pic_object" + fi + fi + ;; + + *.$libext) + # An archive. + deplibs="$deplibs $arg" + old_deplibs="$old_deplibs $arg" + continue + ;; + + *.la) + # A libtool-controlled library. + + if test "$prev" = dlfiles; then + # This library was specified with -dlopen. + dlfiles="$dlfiles $arg" + prev= + elif test "$prev" = dlprefiles; then + # The library was specified with -dlpreopen. + dlprefiles="$dlprefiles $arg" + prev= + else + deplibs="$deplibs $arg" + fi + continue + ;; + + # Some other compiler argument. + *) + # Unknown arguments in both finalize_command and compile_command need + # to be aesthetically quoted because they are evaled later. + arg=`$echo "X$arg" | $Xsed -e "$sed_quote_subst"` + case $arg in + *[\[\~\#\^\&\*\(\)\{\}\|\;\<\>\?\'\ \ ]*|*]*|"") + arg="\"$arg\"" + ;; + esac + ;; + esac # arg + + # Now actually substitute the argument into the commands. + if test -n "$arg"; then + compile_command="$compile_command $arg" + finalize_command="$finalize_command $arg" + fi + done # argument parsing loop + + if test -n "$prev"; then + $echo "$modename: the \`$prevarg' option requires an argument" 1>&2 + $echo "$help" 1>&2 + exit $EXIT_FAILURE + fi + + if test "$export_dynamic" = yes && test -n "$export_dynamic_flag_spec"; then + eval arg=\"$export_dynamic_flag_spec\" + compile_command="$compile_command $arg" + finalize_command="$finalize_command $arg" + fi + + oldlibs= + # calculate the name of the file, without its directory + outputname=`$echo "X$output" | $Xsed -e 's%^.*/%%'` + libobjs_save="$libobjs" + + if test -n "$shlibpath_var"; then + # get the directories listed in $shlibpath_var + eval shlib_search_path=\`\$echo \"X\${$shlibpath_var}\" \| \$Xsed -e \'s/:/ /g\'\` + else + shlib_search_path= + fi + eval sys_lib_search_path=\"$sys_lib_search_path_spec\" + eval sys_lib_dlsearch_path=\"$sys_lib_dlsearch_path_spec\" + + output_objdir=`$echo "X$output" | $Xsed -e 's%/[^/]*$%%'` + if test "X$output_objdir" = "X$output"; then + output_objdir="$objdir" + else + output_objdir="$output_objdir/$objdir" + fi + # Create the object directory. + if test ! -d "$output_objdir"; then + $show "$mkdir $output_objdir" + $run $mkdir $output_objdir + exit_status=$? + if test "$exit_status" -ne 0 && test ! -d "$output_objdir"; then + exit $exit_status + fi + fi + + # Determine the type of output + case $output in + "") + $echo "$modename: you must specify an output file" 1>&2 + $echo "$help" 1>&2 + exit $EXIT_FAILURE + ;; + *.$libext) linkmode=oldlib ;; + *.lo | *.$objext) linkmode=obj ;; + *.la) linkmode=lib ;; + *) linkmode=prog ;; # Anything else should be a program. + esac + + case $host in + *cygwin* | *mingw* | *pw32*) + # don't eliminate duplications in $postdeps and $predeps + duplicate_compiler_generated_deps=yes + ;; + *) + duplicate_compiler_generated_deps=$duplicate_deps + ;; + esac + specialdeplibs= + + libs= + # Find all interdependent deplibs by searching for libraries + # that are linked more than once (e.g. -la -lb -la) + for deplib in $deplibs; do + if test "X$duplicate_deps" = "Xyes" ; then + case "$libs " in + *" $deplib "*) specialdeplibs="$specialdeplibs $deplib" ;; + esac + fi + libs="$libs $deplib" + done + + if test "$linkmode" = lib; then + libs="$predeps $libs $compiler_lib_search_path $postdeps" + + # Compute libraries that are listed more than once in $predeps + # $postdeps and mark them as special (i.e., whose duplicates are + # not to be eliminated). + pre_post_deps= + if test "X$duplicate_compiler_generated_deps" = "Xyes" ; then + for pre_post_dep in $predeps $postdeps; do + case "$pre_post_deps " in + *" $pre_post_dep "*) specialdeplibs="$specialdeplibs $pre_post_deps" ;; + esac + pre_post_deps="$pre_post_deps $pre_post_dep" + done + fi + pre_post_deps= + fi + + deplibs= + newdependency_libs= + newlib_search_path= + need_relink=no # whether we're linking any uninstalled libtool libraries + notinst_deplibs= # not-installed libtool libraries + case $linkmode in + lib) + passes="conv link" + for file in $dlfiles $dlprefiles; do + case $file in + *.la) ;; + *) + $echo "$modename: libraries can \`-dlopen' only libtool libraries: $file" 1>&2 + exit $EXIT_FAILURE + ;; + esac + done + ;; + prog) + compile_deplibs= + finalize_deplibs= + alldeplibs=no + newdlfiles= + newdlprefiles= + passes="conv scan dlopen dlpreopen link" + ;; + *) passes="conv" + ;; + esac + for pass in $passes; do + if test "$linkmode,$pass" = "lib,link" || + test "$linkmode,$pass" = "prog,scan"; then + libs="$deplibs" + deplibs= + fi + if test "$linkmode" = prog; then + case $pass in + dlopen) libs="$dlfiles" ;; + dlpreopen) libs="$dlprefiles" ;; + link) libs="$deplibs %DEPLIBS% $dependency_libs" ;; + esac + fi + if test "$pass" = dlopen; then + # Collect dlpreopened libraries + save_deplibs="$deplibs" + deplibs= + fi + for deplib in $libs; do + lib= + found=no + case $deplib in + -mt|-mthreads|-kthread|-Kthread|-pthread|-pthreads|--thread-safe) + if test "$linkmode,$pass" = "prog,link"; then + compile_deplibs="$deplib $compile_deplibs" + finalize_deplibs="$deplib $finalize_deplibs" + else + compiler_flags="$compiler_flags $deplib" + fi + continue + ;; + -l*) + if test "$linkmode" != lib && test "$linkmode" != prog; then + $echo "$modename: warning: \`-l' is ignored for archives/objects" 1>&2 + continue + fi + name=`$echo "X$deplib" | $Xsed -e 's/^-l//'` + for searchdir in $newlib_search_path $lib_search_path $sys_lib_search_path $shlib_search_path; do + for search_ext in .la $std_shrext .so .a; do + # Search the libtool library + lib="$searchdir/lib${name}${search_ext}" + if test -f "$lib"; then + if test "$search_ext" = ".la"; then + found=yes + else + found=no + fi + break 2 + fi + done + done + if test "$found" != yes; then + # deplib doesn't seem to be a libtool library + if test "$linkmode,$pass" = "prog,link"; then + compile_deplibs="$deplib $compile_deplibs" + finalize_deplibs="$deplib $finalize_deplibs" + else + deplibs="$deplib $deplibs" + test "$linkmode" = lib && newdependency_libs="$deplib $newdependency_libs" + fi + continue + else # deplib is a libtool library + # If $allow_libtool_libs_with_static_runtimes && $deplib is a stdlib, + # We need to do some special things here, and not later. + if test "X$allow_libtool_libs_with_static_runtimes" = "Xyes" ; then + case " $predeps $postdeps " in + *" $deplib "*) + if (${SED} -e '2q' $lib | + grep "^# Generated by .*$PACKAGE") >/dev/null 2>&1; then + library_names= + old_library= + case $lib in + */* | *\\*) . $lib ;; + *) . ./$lib ;; + esac + for l in $old_library $library_names; do + ll="$l" + done + if test "X$ll" = "X$old_library" ; then # only static version available + found=no + ladir=`$echo "X$lib" | $Xsed -e 's%/[^/]*$%%'` + test "X$ladir" = "X$lib" && ladir="." + lib=$ladir/$old_library + if test "$linkmode,$pass" = "prog,link"; then + compile_deplibs="$deplib $compile_deplibs" + finalize_deplibs="$deplib $finalize_deplibs" + else + deplibs="$deplib $deplibs" + test "$linkmode" = lib && newdependency_libs="$deplib $newdependency_libs" + fi + continue + fi + fi + ;; + *) ;; + esac + fi + fi + ;; # -l + -L*) + case $linkmode in + lib) + deplibs="$deplib $deplibs" + test "$pass" = conv && continue + newdependency_libs="$deplib $newdependency_libs" + newlib_search_path="$newlib_search_path "`$echo "X$deplib" | $Xsed -e 's/^-L//'` + ;; + prog) + if test "$pass" = conv; then + deplibs="$deplib $deplibs" + continue + fi + if test "$pass" = scan; then + deplibs="$deplib $deplibs" + else + compile_deplibs="$deplib $compile_deplibs" + finalize_deplibs="$deplib $finalize_deplibs" + fi + newlib_search_path="$newlib_search_path "`$echo "X$deplib" | $Xsed -e 's/^-L//'` + ;; + *) + $echo "$modename: warning: \`-L' is ignored for archives/objects" 1>&2 + ;; + esac # linkmode + continue + ;; # -L + -R*) + if test "$pass" = link; then + dir=`$echo "X$deplib" | $Xsed -e 's/^-R//'` + # Make sure the xrpath contains only unique directories. + case "$xrpath " in + *" $dir "*) ;; + *) xrpath="$xrpath $dir" ;; + esac + fi + deplibs="$deplib $deplibs" + continue + ;; + *.la) lib="$deplib" ;; + *.$libext) + if test "$pass" = conv; then + deplibs="$deplib $deplibs" + continue + fi + case $linkmode in + lib) + valid_a_lib=no + case $deplibs_check_method in + match_pattern*) + set dummy $deplibs_check_method + match_pattern_regex=`expr "$deplibs_check_method" : "$2 \(.*\)"` + if eval $echo \"$deplib\" 2>/dev/null \ + | $SED 10q \ + | $EGREP "$match_pattern_regex" > /dev/null; then + valid_a_lib=yes + fi + ;; + pass_all) + valid_a_lib=yes + ;; + esac + if test "$valid_a_lib" != yes; then + $echo + $echo "*** Warning: Trying to link with static lib archive $deplib." + $echo "*** I have the capability to make that library automatically link in when" + $echo "*** you link to this library. But I can only do this if you have a" + $echo "*** shared version of the library, which you do not appear to have" + $echo "*** because the file extensions .$libext of this argument makes me believe" + $echo "*** that it is just a static archive that I should not used here." + else + $echo + $echo "*** Warning: Linking the shared library $output against the" + $echo "*** static library $deplib is not portable!" + deplibs="$deplib $deplibs" + fi + continue + ;; + prog) + if test "$pass" != link; then + deplibs="$deplib $deplibs" + else + compile_deplibs="$deplib $compile_deplibs" + finalize_deplibs="$deplib $finalize_deplibs" + fi + continue + ;; + esac # linkmode + ;; # *.$libext + *.lo | *.$objext) + if test "$pass" = conv; then + deplibs="$deplib $deplibs" + elif test "$linkmode" = prog; then + if test "$pass" = dlpreopen || test "$dlopen_support" != yes || test "$build_libtool_libs" = no; then + # If there is no dlopen support or we're linking statically, + # we need to preload. + newdlprefiles="$newdlprefiles $deplib" + compile_deplibs="$deplib $compile_deplibs" + finalize_deplibs="$deplib $finalize_deplibs" + else + newdlfiles="$newdlfiles $deplib" + fi + fi + continue + ;; + %DEPLIBS%) + alldeplibs=yes + continue + ;; + esac # case $deplib + if test "$found" = yes || test -f "$lib"; then : + else + $echo "$modename: cannot find the library \`$lib' or unhandled argument \`$deplib'" 1>&2 + exit $EXIT_FAILURE + fi + + # Check to see that this really is a libtool archive. + if (${SED} -e '2q' $lib | grep "^# Generated by .*$PACKAGE") >/dev/null 2>&1; then : + else + $echo "$modename: \`$lib' is not a valid libtool archive" 1>&2 + exit $EXIT_FAILURE + fi + + ladir=`$echo "X$lib" | $Xsed -e 's%/[^/]*$%%'` + test "X$ladir" = "X$lib" && ladir="." + + dlname= + dlopen= + dlpreopen= + libdir= + library_names= + old_library= + # If the library was installed with an old release of libtool, + # it will not redefine variables installed, or shouldnotlink + installed=yes + shouldnotlink=no + avoidtemprpath= + + + # Read the .la file + case $lib in + */* | *\\*) . $lib ;; + *) . ./$lib ;; + esac + + if test "$linkmode,$pass" = "lib,link" || + test "$linkmode,$pass" = "prog,scan" || + { test "$linkmode" != prog && test "$linkmode" != lib; }; then + test -n "$dlopen" && dlfiles="$dlfiles $dlopen" + test -n "$dlpreopen" && dlprefiles="$dlprefiles $dlpreopen" + fi + + if test "$pass" = conv; then + # Only check for convenience libraries + deplibs="$lib $deplibs" + if test -z "$libdir"; then + if test -z "$old_library"; then + $echo "$modename: cannot find name of link library for \`$lib'" 1>&2 + exit $EXIT_FAILURE + fi + # It is a libtool convenience library, so add in its objects. + convenience="$convenience $ladir/$objdir/$old_library" + old_convenience="$old_convenience $ladir/$objdir/$old_library" + tmp_libs= + for deplib in $dependency_libs; do + deplibs="$deplib $deplibs" + if test "X$duplicate_deps" = "Xyes" ; then + case "$tmp_libs " in + *" $deplib "*) specialdeplibs="$specialdeplibs $deplib" ;; + esac + fi + tmp_libs="$tmp_libs $deplib" + done + elif test "$linkmode" != prog && test "$linkmode" != lib; then + $echo "$modename: \`$lib' is not a convenience library" 1>&2 + exit $EXIT_FAILURE + fi + continue + fi # $pass = conv + + + # Get the name of the library we link against. + linklib= + for l in $old_library $library_names; do + linklib="$l" + done + if test -z "$linklib"; then + $echo "$modename: cannot find name of link library for \`$lib'" 1>&2 + exit $EXIT_FAILURE + fi + + # This library was specified with -dlopen. + if test "$pass" = dlopen; then + if test -z "$libdir"; then + $echo "$modename: cannot -dlopen a convenience library: \`$lib'" 1>&2 + exit $EXIT_FAILURE + fi + if test -z "$dlname" || + test "$dlopen_support" != yes || + test "$build_libtool_libs" = no; then + # If there is no dlname, no dlopen support or we're linking + # statically, we need to preload. We also need to preload any + # dependent libraries so libltdl's deplib preloader doesn't + # bomb out in the load deplibs phase. + dlprefiles="$dlprefiles $lib $dependency_libs" + else + newdlfiles="$newdlfiles $lib" + fi + continue + fi # $pass = dlopen + + # We need an absolute path. + case $ladir in + [\\/]* | [A-Za-z]:[\\/]*) abs_ladir="$ladir" ;; + *) + abs_ladir=`cd "$ladir" && pwd` + if test -z "$abs_ladir"; then + $echo "$modename: warning: cannot determine absolute directory name of \`$ladir'" 1>&2 + $echo "$modename: passing it literally to the linker, although it might fail" 1>&2 + abs_ladir="$ladir" + fi + ;; + esac + laname=`$echo "X$lib" | $Xsed -e 's%^.*/%%'` + + # Find the relevant object directory and library name. + if test "X$installed" = Xyes; then + if test ! -f "$libdir/$linklib" && test -f "$abs_ladir/$linklib"; then + $echo "$modename: warning: library \`$lib' was moved." 1>&2 + dir="$ladir" + absdir="$abs_ladir" + libdir="$abs_ladir" + else + dir="$libdir" + absdir="$libdir" + fi + test "X$hardcode_automatic" = Xyes && avoidtemprpath=yes + else + if test ! -f "$ladir/$objdir/$linklib" && test -f "$abs_ladir/$linklib"; then + dir="$ladir" + absdir="$abs_ladir" + # Remove this search path later + notinst_path="$notinst_path $abs_ladir" + else + dir="$ladir/$objdir" + absdir="$abs_ladir/$objdir" + # Remove this search path later + notinst_path="$notinst_path $abs_ladir" + fi + fi # $installed = yes + name=`$echo "X$laname" | $Xsed -e 's/\.la$//' -e 's/^lib//'` + + # This library was specified with -dlpreopen. + if test "$pass" = dlpreopen; then + if test -z "$libdir"; then + $echo "$modename: cannot -dlpreopen a convenience library: \`$lib'" 1>&2 + exit $EXIT_FAILURE + fi + # Prefer using a static library (so that no silly _DYNAMIC symbols + # are required to link). + if test -n "$old_library"; then + newdlprefiles="$newdlprefiles $dir/$old_library" + # Otherwise, use the dlname, so that lt_dlopen finds it. + elif test -n "$dlname"; then + newdlprefiles="$newdlprefiles $dir/$dlname" + else + newdlprefiles="$newdlprefiles $dir/$linklib" + fi + fi # $pass = dlpreopen + + if test -z "$libdir"; then + # Link the convenience library + if test "$linkmode" = lib; then + deplibs="$dir/$old_library $deplibs" + elif test "$linkmode,$pass" = "prog,link"; then + compile_deplibs="$dir/$old_library $compile_deplibs" + finalize_deplibs="$dir/$old_library $finalize_deplibs" + else + deplibs="$lib $deplibs" # used for prog,scan pass + fi + continue + fi + + + if test "$linkmode" = prog && test "$pass" != link; then + newlib_search_path="$newlib_search_path $ladir" + deplibs="$lib $deplibs" + + linkalldeplibs=no + if test "$link_all_deplibs" != no || test -z "$library_names" || + test "$build_libtool_libs" = no; then + linkalldeplibs=yes + fi + + tmp_libs= + for deplib in $dependency_libs; do + case $deplib in + -L*) newlib_search_path="$newlib_search_path "`$echo "X$deplib" | $Xsed -e 's/^-L//'`;; ### testsuite: skip nested quoting test + esac + # Need to link against all dependency_libs? + if test "$linkalldeplibs" = yes; then + deplibs="$deplib $deplibs" + else + # Need to hardcode shared library paths + # or/and link against static libraries + newdependency_libs="$deplib $newdependency_libs" + fi + if test "X$duplicate_deps" = "Xyes" ; then + case "$tmp_libs " in + *" $deplib "*) specialdeplibs="$specialdeplibs $deplib" ;; + esac + fi + tmp_libs="$tmp_libs $deplib" + done # for deplib + continue + fi # $linkmode = prog... + + if test "$linkmode,$pass" = "prog,link"; then + if test -n "$library_names" && + { { test "$prefer_static_libs" = no || + test "$prefer_static_libs,$installed" = "built,yes"; } || + test -z "$old_library"; }; then + # We need to hardcode the library path + if test -n "$shlibpath_var" && test -z "$avoidtemprpath" ; then + # Make sure the rpath contains only unique directories. + case "$temp_rpath " in + *" $dir "*) ;; + *" $absdir "*) ;; + *) temp_rpath="$temp_rpath $absdir" ;; + esac + fi + + # Hardcode the library path. + # Skip directories that are in the system default run-time + # search path. + case " $sys_lib_dlsearch_path " in + *" $absdir "*) ;; + *) + case "$compile_rpath " in + *" $absdir "*) ;; + *) compile_rpath="$compile_rpath $absdir" + esac + ;; + esac + case " $sys_lib_dlsearch_path " in + *" $libdir "*) ;; + *) + case "$finalize_rpath " in + *" $libdir "*) ;; + *) finalize_rpath="$finalize_rpath $libdir" + esac + ;; + esac + fi # $linkmode,$pass = prog,link... + + if test "$alldeplibs" = yes && + { test "$deplibs_check_method" = pass_all || + { test "$build_libtool_libs" = yes && + test -n "$library_names"; }; }; then + # We only need to search for static libraries + continue + fi + fi + + link_static=no # Whether the deplib will be linked statically + use_static_libs=$prefer_static_libs + if test "$use_static_libs" = built && test "$installed" = yes ; then + use_static_libs=no + fi + if test -n "$library_names" && + { test "$use_static_libs" = no || test -z "$old_library"; }; then + if test "$installed" = no; then + notinst_deplibs="$notinst_deplibs $lib" + need_relink=yes + fi + # This is a shared library + + # Warn about portability, can't link against -module's on + # some systems (darwin) + if test "$shouldnotlink" = yes && test "$pass" = link ; then + $echo + if test "$linkmode" = prog; then + $echo "*** Warning: Linking the executable $output against the loadable module" + else + $echo "*** Warning: Linking the shared library $output against the loadable module" + fi + $echo "*** $linklib is not portable!" + fi + if test "$linkmode" = lib && + test "$hardcode_into_libs" = yes; then + # Hardcode the library path. + # Skip directories that are in the system default run-time + # search path. + case " $sys_lib_dlsearch_path " in + *" $absdir "*) ;; + *) + case "$compile_rpath " in + *" $absdir "*) ;; + *) compile_rpath="$compile_rpath $absdir" + esac + ;; + esac + case " $sys_lib_dlsearch_path " in + *" $libdir "*) ;; + *) + case "$finalize_rpath " in + *" $libdir "*) ;; + *) finalize_rpath="$finalize_rpath $libdir" + esac + ;; + esac + fi + + if test -n "$old_archive_from_expsyms_cmds"; then + # figure out the soname + set dummy $library_names + realname="$2" + shift; shift + libname=`eval \\$echo \"$libname_spec\"` + # use dlname if we got it. it's perfectly good, no? + if test -n "$dlname"; then + soname="$dlname" + elif test -n "$soname_spec"; then + # bleh windows + case $host in + *cygwin* | mingw*) + major=`expr $current - $age` + versuffix="-$major" + ;; + esac + eval soname=\"$soname_spec\" + else + soname="$realname" + fi + + # Make a new name for the extract_expsyms_cmds to use + soroot="$soname" + soname=`$echo $soroot | ${SED} -e 's/^.*\///'` + newlib="libimp-`$echo $soname | ${SED} 's/^lib//;s/\.dll$//'`.a" + + # If the library has no export list, then create one now + if test -f "$output_objdir/$soname-def"; then : + else + $show "extracting exported symbol list from \`$soname'" + save_ifs="$IFS"; IFS='~' + cmds=$extract_expsyms_cmds + for cmd in $cmds; do + IFS="$save_ifs" + eval cmd=\"$cmd\" + $show "$cmd" + $run eval "$cmd" || exit $? + done + IFS="$save_ifs" + fi + + # Create $newlib + if test -f "$output_objdir/$newlib"; then :; else + $show "generating import library for \`$soname'" + save_ifs="$IFS"; IFS='~' + cmds=$old_archive_from_expsyms_cmds + for cmd in $cmds; do + IFS="$save_ifs" + eval cmd=\"$cmd\" + $show "$cmd" + $run eval "$cmd" || exit $? + done + IFS="$save_ifs" + fi + # make sure the library variables are pointing to the new library + dir=$output_objdir + linklib=$newlib + fi # test -n "$old_archive_from_expsyms_cmds" + + if test "$linkmode" = prog || test "$mode" != relink; then + add_shlibpath= + add_dir= + add= + lib_linked=yes + case $hardcode_action in + immediate | unsupported) + if test "$hardcode_direct" = no; then + add="$dir/$linklib" + case $host in + *-*-sco3.2v5.0.[024]*) add_dir="-L$dir" ;; + *-*-sysv4*uw2*) add_dir="-L$dir" ;; + *-*-sysv5OpenUNIX* | *-*-sysv5UnixWare7.[01].[10]* | \ + *-*-unixware7*) add_dir="-L$dir" ;; + *-*-darwin* ) + # if the lib is a module then we can not link against + # it, someone is ignoring the new warnings I added + if /usr/bin/file -L $add 2> /dev/null | + $EGREP ": [^:]* bundle" >/dev/null ; then + $echo "** Warning, lib $linklib is a module, not a shared library" + if test -z "$old_library" ; then + $echo + $echo "** And there doesn't seem to be a static archive available" + $echo "** The link will probably fail, sorry" + else + add="$dir/$old_library" + fi + fi + esac + elif test "$hardcode_minus_L" = no; then + case $host in + *-*-sunos*) add_shlibpath="$dir" ;; + esac + add_dir="-L$dir" + add="-l$name" + elif test "$hardcode_shlibpath_var" = no; then + add_shlibpath="$dir" + add="-l$name" + else + lib_linked=no + fi + ;; + relink) + if test "$hardcode_direct" = yes; then + add="$dir/$linklib" + elif test "$hardcode_minus_L" = yes; then + add_dir="-L$dir" + # Try looking first in the location we're being installed to. + if test -n "$inst_prefix_dir"; then + case $libdir in + [\\/]*) + add_dir="$add_dir -L$inst_prefix_dir$libdir" + ;; + esac + fi + add="-l$name" + elif test "$hardcode_shlibpath_var" = yes; then + add_shlibpath="$dir" + add="-l$name" + else + lib_linked=no + fi + ;; + *) lib_linked=no ;; + esac + + if test "$lib_linked" != yes; then + $echo "$modename: configuration error: unsupported hardcode properties" + exit $EXIT_FAILURE + fi + + if test -n "$add_shlibpath"; then + case :$compile_shlibpath: in + *":$add_shlibpath:"*) ;; + *) compile_shlibpath="$compile_shlibpath$add_shlibpath:" ;; + esac + fi + if test "$linkmode" = prog; then + test -n "$add_dir" && compile_deplibs="$add_dir $compile_deplibs" + test -n "$add" && compile_deplibs="$add $compile_deplibs" + else + test -n "$add_dir" && deplibs="$add_dir $deplibs" + test -n "$add" && deplibs="$add $deplibs" + if test "$hardcode_direct" != yes && \ + test "$hardcode_minus_L" != yes && \ + test "$hardcode_shlibpath_var" = yes; then + case :$finalize_shlibpath: in + *":$libdir:"*) ;; + *) finalize_shlibpath="$finalize_shlibpath$libdir:" ;; + esac + fi + fi + fi + + if test "$linkmode" = prog || test "$mode" = relink; then + add_shlibpath= + add_dir= + add= + # Finalize command for both is simple: just hardcode it. + if test "$hardcode_direct" = yes; then + add="$libdir/$linklib" + elif test "$hardcode_minus_L" = yes; then + add_dir="-L$libdir" + add="-l$name" + elif test "$hardcode_shlibpath_var" = yes; then + case :$finalize_shlibpath: in + *":$libdir:"*) ;; + *) finalize_shlibpath="$finalize_shlibpath$libdir:" ;; + esac + add="-l$name" + elif test "$hardcode_automatic" = yes; then + if test -n "$inst_prefix_dir" && + test -f "$inst_prefix_dir$libdir/$linklib" ; then + add="$inst_prefix_dir$libdir/$linklib" + else + add="$libdir/$linklib" + fi + else + # We cannot seem to hardcode it, guess we'll fake it. + add_dir="-L$libdir" + # Try looking first in the location we're being installed to. + if test -n "$inst_prefix_dir"; then + case $libdir in + [\\/]*) + add_dir="$add_dir -L$inst_prefix_dir$libdir" + ;; + esac + fi + add="-l$name" + fi + + if test "$linkmode" = prog; then + test -n "$add_dir" && finalize_deplibs="$add_dir $finalize_deplibs" + test -n "$add" && finalize_deplibs="$add $finalize_deplibs" + else + test -n "$add_dir" && deplibs="$add_dir $deplibs" + test -n "$add" && deplibs="$add $deplibs" + fi + fi + elif test "$linkmode" = prog; then + # Here we assume that one of hardcode_direct or hardcode_minus_L + # is not unsupported. This is valid on all known static and + # shared platforms. + if test "$hardcode_direct" != unsupported; then + test -n "$old_library" && linklib="$old_library" + compile_deplibs="$dir/$linklib $compile_deplibs" + finalize_deplibs="$dir/$linklib $finalize_deplibs" + else + compile_deplibs="-l$name -L$dir $compile_deplibs" + finalize_deplibs="-l$name -L$dir $finalize_deplibs" + fi + elif test "$build_libtool_libs" = yes; then + # Not a shared library + if test "$deplibs_check_method" != pass_all; then + # We're trying link a shared library against a static one + # but the system doesn't support it. + + # Just print a warning and add the library to dependency_libs so + # that the program can be linked against the static library. + $echo + $echo "*** Warning: This system can not link to static lib archive $lib." + $echo "*** I have the capability to make that library automatically link in when" + $echo "*** you link to this library. But I can only do this if you have a" + $echo "*** shared version of the library, which you do not appear to have." + if test "$module" = yes; then + $echo "*** But as you try to build a module library, libtool will still create " + $echo "*** a static module, that should work as long as the dlopening application" + $echo "*** is linked with the -dlopen flag to resolve symbols at runtime." + if test -z "$global_symbol_pipe"; then + $echo + $echo "*** However, this would only work if libtool was able to extract symbol" + $echo "*** lists from a program, using \`nm' or equivalent, but libtool could" + $echo "*** not find such a program. So, this module is probably useless." + $echo "*** \`nm' from GNU binutils and a full rebuild may help." + fi + if test "$build_old_libs" = no; then + build_libtool_libs=module + build_old_libs=yes + else + build_libtool_libs=no + fi + fi + else + deplibs="$dir/$old_library $deplibs" + link_static=yes + fi + fi # link shared/static library? + + if test "$linkmode" = lib; then + if test -n "$dependency_libs" && + { test "$hardcode_into_libs" != yes || + test "$build_old_libs" = yes || + test "$link_static" = yes; }; then + # Extract -R from dependency_libs + temp_deplibs= + for libdir in $dependency_libs; do + case $libdir in + -R*) temp_xrpath=`$echo "X$libdir" | $Xsed -e 's/^-R//'` + case " $xrpath " in + *" $temp_xrpath "*) ;; + *) xrpath="$xrpath $temp_xrpath";; + esac;; + *) temp_deplibs="$temp_deplibs $libdir";; + esac + done + dependency_libs="$temp_deplibs" + fi + + newlib_search_path="$newlib_search_path $absdir" + # Link against this library + test "$link_static" = no && newdependency_libs="$abs_ladir/$laname $newdependency_libs" + # ... and its dependency_libs + tmp_libs= + for deplib in $dependency_libs; do + newdependency_libs="$deplib $newdependency_libs" + if test "X$duplicate_deps" = "Xyes" ; then + case "$tmp_libs " in + *" $deplib "*) specialdeplibs="$specialdeplibs $deplib" ;; + esac + fi + tmp_libs="$tmp_libs $deplib" + done + + if test "$link_all_deplibs" != no; then + # Add the search paths of all dependency libraries + for deplib in $dependency_libs; do + case $deplib in + -L*) path="$deplib" ;; + *.la) + dir=`$echo "X$deplib" | $Xsed -e 's%/[^/]*$%%'` + test "X$dir" = "X$deplib" && dir="." + # We need an absolute path. + case $dir in + [\\/]* | [A-Za-z]:[\\/]*) absdir="$dir" ;; + *) + absdir=`cd "$dir" && pwd` + if test -z "$absdir"; then + $echo "$modename: warning: cannot determine absolute directory name of \`$dir'" 1>&2 + absdir="$dir" + fi + ;; + esac + if grep "^installed=no" $deplib > /dev/null; then + path="$absdir/$objdir" + else + eval libdir=`${SED} -n -e 's/^libdir=\(.*\)$/\1/p' $deplib` + if test -z "$libdir"; then + $echo "$modename: \`$deplib' is not a valid libtool archive" 1>&2 + exit $EXIT_FAILURE + fi + if test "$absdir" != "$libdir"; then + $echo "$modename: warning: \`$deplib' seems to be moved" 1>&2 + fi + path="$absdir" + fi + depdepl= + case $host in + *-*-darwin*) + # we do not want to link against static libs, + # but need to link against shared + eval deplibrary_names=`${SED} -n -e 's/^library_names=\(.*\)$/\1/p' $deplib` + if test -n "$deplibrary_names" ; then + for tmp in $deplibrary_names ; do + depdepl=$tmp + done + if test -f "$path/$depdepl" ; then + depdepl="$path/$depdepl" + fi + # do not add paths which are already there + case " $newlib_search_path " in + *" $path "*) ;; + *) newlib_search_path="$newlib_search_path $path";; + esac + fi + path="" + ;; + *) + path="-L$path" + ;; + esac + ;; + -l*) + case $host in + *-*-darwin*) + # Again, we only want to link against shared libraries + eval tmp_libs=`$echo "X$deplib" | $Xsed -e "s,^\-l,,"` + for tmp in $newlib_search_path ; do + if test -f "$tmp/lib$tmp_libs.dylib" ; then + eval depdepl="$tmp/lib$tmp_libs.dylib" + break + fi + done + path="" + ;; + *) continue ;; + esac + ;; + *) continue ;; + esac + case " $deplibs " in + *" $path "*) ;; + *) deplibs="$path $deplibs" ;; + esac + case " $deplibs " in + *" $depdepl "*) ;; + *) deplibs="$depdepl $deplibs" ;; + esac + done + fi # link_all_deplibs != no + fi # linkmode = lib + done # for deplib in $libs + dependency_libs="$newdependency_libs" + if test "$pass" = dlpreopen; then + # Link the dlpreopened libraries before other libraries + for deplib in $save_deplibs; do + deplibs="$deplib $deplibs" + done + fi + if test "$pass" != dlopen; then + if test "$pass" != conv; then + # Make sure lib_search_path contains only unique directories. + lib_search_path= + for dir in $newlib_search_path; do + case "$lib_search_path " in + *" $dir "*) ;; + *) lib_search_path="$lib_search_path $dir" ;; + esac + done + newlib_search_path= + fi + + if test "$linkmode,$pass" != "prog,link"; then + vars="deplibs" + else + vars="compile_deplibs finalize_deplibs" + fi + for var in $vars dependency_libs; do + # Add libraries to $var in reverse order + eval tmp_libs=\"\$$var\" + new_libs= + for deplib in $tmp_libs; do + # FIXME: Pedantically, this is the right thing to do, so + # that some nasty dependency loop isn't accidentally + # broken: + #new_libs="$deplib $new_libs" + # Pragmatically, this seems to cause very few problems in + # practice: + case $deplib in + -L*) new_libs="$deplib $new_libs" ;; + -R*) ;; + *) + # And here is the reason: when a library appears more + # than once as an explicit dependence of a library, or + # is implicitly linked in more than once by the + # compiler, it is considered special, and multiple + # occurrences thereof are not removed. Compare this + # with having the same library being listed as a + # dependency of multiple other libraries: in this case, + # we know (pedantically, we assume) the library does not + # need to be listed more than once, so we keep only the + # last copy. This is not always right, but it is rare + # enough that we require users that really mean to play + # such unportable linking tricks to link the library + # using -Wl,-lname, so that libtool does not consider it + # for duplicate removal. + case " $specialdeplibs " in + *" $deplib "*) new_libs="$deplib $new_libs" ;; + *) + case " $new_libs " in + *" $deplib "*) ;; + *) new_libs="$deplib $new_libs" ;; + esac + ;; + esac + ;; + esac + done + tmp_libs= + for deplib in $new_libs; do + case $deplib in + -L*) + case " $tmp_libs " in + *" $deplib "*) ;; + *) tmp_libs="$tmp_libs $deplib" ;; + esac + ;; + *) tmp_libs="$tmp_libs $deplib" ;; + esac + done + eval $var=\"$tmp_libs\" + done # for var + fi + # Last step: remove runtime libs from dependency_libs + # (they stay in deplibs) + tmp_libs= + for i in $dependency_libs ; do + case " $predeps $postdeps $compiler_lib_search_path " in + *" $i "*) + i="" + ;; + esac + if test -n "$i" ; then + tmp_libs="$tmp_libs $i" + fi + done + dependency_libs=$tmp_libs + done # for pass + if test "$linkmode" = prog; then + dlfiles="$newdlfiles" + dlprefiles="$newdlprefiles" + fi + + case $linkmode in + oldlib) + if test -n "$deplibs"; then + $echo "$modename: warning: \`-l' and \`-L' are ignored for archives" 1>&2 + fi + + if test -n "$dlfiles$dlprefiles" || test "$dlself" != no; then + $echo "$modename: warning: \`-dlopen' is ignored for archives" 1>&2 + fi + + if test -n "$rpath"; then + $echo "$modename: warning: \`-rpath' is ignored for archives" 1>&2 + fi + + if test -n "$xrpath"; then + $echo "$modename: warning: \`-R' is ignored for archives" 1>&2 + fi + + if test -n "$vinfo"; then + $echo "$modename: warning: \`-version-info/-version-number' is ignored for archives" 1>&2 + fi + + if test -n "$release"; then + $echo "$modename: warning: \`-release' is ignored for archives" 1>&2 + fi + + if test -n "$export_symbols" || test -n "$export_symbols_regex"; then + $echo "$modename: warning: \`-export-symbols' is ignored for archives" 1>&2 + fi + + # Now set the variables for building old libraries. + build_libtool_libs=no + oldlibs="$output" + objs="$objs$old_deplibs" + ;; + + lib) + # Make sure we only generate libraries of the form `libNAME.la'. + case $outputname in + lib*) + name=`$echo "X$outputname" | $Xsed -e 's/\.la$//' -e 's/^lib//'` + eval shared_ext=\"$shrext_cmds\" + eval libname=\"$libname_spec\" + ;; + *) + if test "$module" = no; then + $echo "$modename: libtool library \`$output' must begin with \`lib'" 1>&2 + $echo "$help" 1>&2 + exit $EXIT_FAILURE + fi + if test "$need_lib_prefix" != no; then + # Add the "lib" prefix for modules if required + name=`$echo "X$outputname" | $Xsed -e 's/\.la$//'` + eval shared_ext=\"$shrext_cmds\" + eval libname=\"$libname_spec\" + else + libname=`$echo "X$outputname" | $Xsed -e 's/\.la$//'` + fi + ;; + esac + + if test -n "$objs"; then + if test "$deplibs_check_method" != pass_all; then + $echo "$modename: cannot build libtool library \`$output' from non-libtool objects on this host:$objs" 2>&1 + exit $EXIT_FAILURE + else + $echo + $echo "*** Warning: Linking the shared library $output against the non-libtool" + $echo "*** objects $objs is not portable!" + libobjs="$libobjs $objs" + fi + fi + + if test "$dlself" != no; then + $echo "$modename: warning: \`-dlopen self' is ignored for libtool libraries" 1>&2 + fi + + set dummy $rpath + if test "$#" -gt 2; then + $echo "$modename: warning: ignoring multiple \`-rpath's for a libtool library" 1>&2 + fi + install_libdir="$2" + + oldlibs= + if test -z "$rpath"; then + if test "$build_libtool_libs" = yes; then + # Building a libtool convenience library. + # Some compilers have problems with a `.al' extension so + # convenience libraries should have the same extension an + # archive normally would. + oldlibs="$output_objdir/$libname.$libext $oldlibs" + build_libtool_libs=convenience + build_old_libs=yes + fi + + if test -n "$vinfo"; then + $echo "$modename: warning: \`-version-info/-version-number' is ignored for convenience libraries" 1>&2 + fi + + if test -n "$release"; then + $echo "$modename: warning: \`-release' is ignored for convenience libraries" 1>&2 + fi + else + + # Parse the version information argument. + save_ifs="$IFS"; IFS=':' + set dummy $vinfo 0 0 0 + IFS="$save_ifs" + + if test -n "$8"; then + $echo "$modename: too many parameters to \`-version-info'" 1>&2 + $echo "$help" 1>&2 + exit $EXIT_FAILURE + fi + + # convert absolute version numbers to libtool ages + # this retains compatibility with .la files and attempts + # to make the code below a bit more comprehensible + + case $vinfo_number in + yes) + number_major="$2" + number_minor="$3" + number_revision="$4" + # + # There are really only two kinds -- those that + # use the current revision as the major version + # and those that subtract age and use age as + # a minor version. But, then there is irix + # which has an extra 1 added just for fun + # + case $version_type in + darwin|linux|osf|windows|none) + current=`expr $number_major + $number_minor` + age="$number_minor" + revision="$number_revision" + ;; + freebsd-aout|freebsd-elf|sunos) + current="$number_major" + revision="$number_minor" + age="0" + ;; + irix|nonstopux) + current=`expr $number_major + $number_minor - 1` + age="$number_minor" + revision="$number_minor" + ;; + esac + ;; + no) + current="$2" + revision="$3" + age="$4" + ;; + esac + + # Check that each of the things are valid numbers. + case $current in + 0|[1-9]|[1-9][0-9]|[1-9][0-9][0-9]|[1-9][0-9][0-9][0-9]|[1-9][0-9][0-9][0-9][0-9]) ;; + *) + $echo "$modename: CURRENT \`$current' must be a nonnegative integer" 1>&2 + $echo "$modename: \`$vinfo' is not valid version information" 1>&2 + exit $EXIT_FAILURE + ;; + esac + + case $revision in + 0|[1-9]|[1-9][0-9]|[1-9][0-9][0-9]|[1-9][0-9][0-9][0-9]|[1-9][0-9][0-9][0-9][0-9]) ;; + *) + $echo "$modename: REVISION \`$revision' must be a nonnegative integer" 1>&2 + $echo "$modename: \`$vinfo' is not valid version information" 1>&2 + exit $EXIT_FAILURE + ;; + esac + + case $age in + 0|[1-9]|[1-9][0-9]|[1-9][0-9][0-9]|[1-9][0-9][0-9][0-9]|[1-9][0-9][0-9][0-9][0-9]) ;; + *) + $echo "$modename: AGE \`$age' must be a nonnegative integer" 1>&2 + $echo "$modename: \`$vinfo' is not valid version information" 1>&2 + exit $EXIT_FAILURE + ;; + esac + + if test "$age" -gt "$current"; then + $echo "$modename: AGE \`$age' is greater than the current interface number \`$current'" 1>&2 + $echo "$modename: \`$vinfo' is not valid version information" 1>&2 + exit $EXIT_FAILURE + fi + + # Calculate the version variables. + major= + versuffix= + verstring= + case $version_type in + none) ;; + + darwin) + # Like Linux, but with the current version available in + # verstring for coding it into the library header + major=.`expr $current - $age` + versuffix="$major.$age.$revision" + # Darwin ld doesn't like 0 for these options... + minor_current=`expr $current + 1` + verstring="${wl}-compatibility_version ${wl}$minor_current ${wl}-current_version ${wl}$minor_current.$revision" + ;; + + freebsd-aout) + major=".$current" + versuffix=".$current.$revision"; + ;; + + freebsd-elf) + major=".$current" + versuffix=".$current"; + ;; + + irix | nonstopux) + major=`expr $current - $age + 1` + + case $version_type in + nonstopux) verstring_prefix=nonstopux ;; + *) verstring_prefix=sgi ;; + esac + verstring="$verstring_prefix$major.$revision" + + # Add in all the interfaces that we are compatible with. + loop=$revision + while test "$loop" -ne 0; do + iface=`expr $revision - $loop` + loop=`expr $loop - 1` + verstring="$verstring_prefix$major.$iface:$verstring" + done + + # Before this point, $major must not contain `.'. + major=.$major + versuffix="$major.$revision" + ;; + + linux) + major=.`expr $current - $age` + versuffix="$major.$age.$revision" + ;; + + osf) + major=.`expr $current - $age` + versuffix=".$current.$age.$revision" + verstring="$current.$age.$revision" + + # Add in all the interfaces that we are compatible with. + loop=$age + while test "$loop" -ne 0; do + iface=`expr $current - $loop` + loop=`expr $loop - 1` + verstring="$verstring:${iface}.0" + done + + # Make executables depend on our current version. + verstring="$verstring:${current}.0" + ;; + + sunos) + major=".$current" + versuffix=".$current.$revision" + ;; + + windows) + # Use '-' rather than '.', since we only want one + # extension on DOS 8.3 filesystems. + major=`expr $current - $age` + versuffix="-$major" + ;; + + *) + $echo "$modename: unknown library version type \`$version_type'" 1>&2 + $echo "Fatal configuration error. See the $PACKAGE docs for more information." 1>&2 + exit $EXIT_FAILURE + ;; + esac + + # Clear the version info if we defaulted, and they specified a release. + if test -z "$vinfo" && test -n "$release"; then + major= + case $version_type in + darwin) + # we can't check for "0.0" in archive_cmds due to quoting + # problems, so we reset it completely + verstring= + ;; + *) + verstring="0.0" + ;; + esac + if test "$need_version" = no; then + versuffix= + else + versuffix=".0.0" + fi + fi + + # Remove version info from name if versioning should be avoided + if test "$avoid_version" = yes && test "$need_version" = no; then + major= + versuffix= + verstring="" + fi + + # Check to see if the archive will have undefined symbols. + if test "$allow_undefined" = yes; then + if test "$allow_undefined_flag" = unsupported; then + $echo "$modename: warning: undefined symbols not allowed in $host shared libraries" 1>&2 + build_libtool_libs=no + build_old_libs=yes + fi + else + # Don't allow undefined symbols. + allow_undefined_flag="$no_undefined_flag" + fi + fi + + if test "$mode" != relink; then + # Remove our outputs, but don't remove object files since they + # may have been created when compiling PIC objects. + removelist= + tempremovelist=`$echo "$output_objdir/*"` + for p in $tempremovelist; do + case $p in + *.$objext) + ;; + $output_objdir/$outputname | $output_objdir/$libname.* | $output_objdir/${libname}${release}.*) + if test "X$precious_files_regex" != "X"; then + if echo $p | $EGREP -e "$precious_files_regex" >/dev/null 2>&1 + then + continue + fi + fi + removelist="$removelist $p" + ;; + *) ;; + esac + done + if test -n "$removelist"; then + $show "${rm}r $removelist" + $run ${rm}r $removelist + fi + fi + + # Now set the variables for building old libraries. + if test "$build_old_libs" = yes && test "$build_libtool_libs" != convenience ; then + oldlibs="$oldlibs $output_objdir/$libname.$libext" + + # Transform .lo files to .o files. + oldobjs="$objs "`$echo "X$libobjs" | $SP2NL | $Xsed -e '/\.'${libext}'$/d' -e "$lo2o" | $NL2SP` + fi + + # Eliminate all temporary directories. +# for path in $notinst_path; do +# lib_search_path=`$echo "$lib_search_path " | ${SED} -e "s% $path % %g"` +# deplibs=`$echo "$deplibs " | ${SED} -e "s% -L$path % %g"` +# dependency_libs=`$echo "$dependency_libs " | ${SED} -e "s% -L$path % %g"` +# done + + if test -n "$xrpath"; then + # If the user specified any rpath flags, then add them. + temp_xrpath= + for libdir in $xrpath; do + temp_xrpath="$temp_xrpath -R$libdir" + case "$finalize_rpath " in + *" $libdir "*) ;; + *) finalize_rpath="$finalize_rpath $libdir" ;; + esac + done + if test "$hardcode_into_libs" != yes || test "$build_old_libs" = yes; then + dependency_libs="$temp_xrpath $dependency_libs" + fi + fi + + # Make sure dlfiles contains only unique files that won't be dlpreopened + old_dlfiles="$dlfiles" + dlfiles= + for lib in $old_dlfiles; do + case " $dlprefiles $dlfiles " in + *" $lib "*) ;; + *) dlfiles="$dlfiles $lib" ;; + esac + done + + # Make sure dlprefiles contains only unique files + old_dlprefiles="$dlprefiles" + dlprefiles= + for lib in $old_dlprefiles; do + case "$dlprefiles " in + *" $lib "*) ;; + *) dlprefiles="$dlprefiles $lib" ;; + esac + done + + if test "$build_libtool_libs" = yes; then + if test -n "$rpath"; then + case $host in + *-*-cygwin* | *-*-mingw* | *-*-pw32* | *-*-os2* | *-*-beos*) + # these systems don't actually have a c library (as such)! + ;; + *-*-rhapsody* | *-*-darwin1.[012]) + # Rhapsody C library is in the System framework + deplibs="$deplibs -framework System" + ;; + *-*-netbsd*) + # Don't link with libc until the a.out ld.so is fixed. + ;; + *-*-openbsd* | *-*-freebsd* | *-*-dragonfly*) + # Do not include libc due to us having libc/libc_r. + ;; + *-*-sco3.2v5* | *-*-sco5v6*) + # Causes problems with __ctype + ;; + *-*-sysv4.2uw2* | *-*-sysv5* | *-*-unixware* | *-*-OpenUNIX*) + # Compiler inserts libc in the correct place for threads to work + ;; + *) + # Add libc to deplibs on all other systems if necessary. + if test "$build_libtool_need_lc" = "yes"; then + deplibs="$deplibs -lc" + fi + ;; + esac + fi + + # Transform deplibs into only deplibs that can be linked in shared. + name_save=$name + libname_save=$libname + release_save=$release + versuffix_save=$versuffix + major_save=$major + # I'm not sure if I'm treating the release correctly. I think + # release should show up in the -l (ie -lgmp5) so we don't want to + # add it in twice. Is that correct? + release="" + versuffix="" + major="" + newdeplibs= + droppeddeps=no + case $deplibs_check_method in + pass_all) + # Don't check for shared/static. Everything works. + # This might be a little naive. We might want to check + # whether the library exists or not. But this is on + # osf3 & osf4 and I'm not really sure... Just + # implementing what was already the behavior. + newdeplibs=$deplibs + ;; + test_compile) + # This code stresses the "libraries are programs" paradigm to its + # limits. Maybe even breaks it. We compile a program, linking it + # against the deplibs as a proxy for the library. Then we can check + # whether they linked in statically or dynamically with ldd. + $rm conftest.c + cat > conftest.c <<EOF + int main() { return 0; } +EOF + $rm conftest + if $LTCC $LTCFLAGS -o conftest conftest.c $deplibs; then + ldd_output=`ldd conftest` + for i in $deplibs; do + name=`expr $i : '-l\(.*\)'` + # If $name is empty we are operating on a -L argument. + if test "$name" != "" && test "$name" != "0"; then + if test "X$allow_libtool_libs_with_static_runtimes" = "Xyes" ; then + case " $predeps $postdeps " in + *" $i "*) + newdeplibs="$newdeplibs $i" + i="" + ;; + esac + fi + if test -n "$i" ; then + libname=`eval \\$echo \"$libname_spec\"` + deplib_matches=`eval \\$echo \"$library_names_spec\"` + set dummy $deplib_matches + deplib_match=$2 + if test `expr "$ldd_output" : ".*$deplib_match"` -ne 0 ; then + newdeplibs="$newdeplibs $i" + else + droppeddeps=yes + $echo + $echo "*** Warning: dynamic linker does not accept needed library $i." + $echo "*** I have the capability to make that library automatically link in when" + $echo "*** you link to this library. But I can only do this if you have a" + $echo "*** shared version of the library, which I believe you do not have" + $echo "*** because a test_compile did reveal that the linker did not use it for" + $echo "*** its dynamic dependency list that programs get resolved with at runtime." + fi + fi + else + newdeplibs="$newdeplibs $i" + fi + done + else + # Error occurred in the first compile. Let's try to salvage + # the situation: Compile a separate program for each library. + for i in $deplibs; do + name=`expr $i : '-l\(.*\)'` + # If $name is empty we are operating on a -L argument. + if test "$name" != "" && test "$name" != "0"; then + $rm conftest + if $LTCC $LTCFLAGS -o conftest conftest.c $i; then + ldd_output=`ldd conftest` + if test "X$allow_libtool_libs_with_static_runtimes" = "Xyes" ; then + case " $predeps $postdeps " in + *" $i "*) + newdeplibs="$newdeplibs $i" + i="" + ;; + esac + fi + if test -n "$i" ; then + libname=`eval \\$echo \"$libname_spec\"` + deplib_matches=`eval \\$echo \"$library_names_spec\"` + set dummy $deplib_matches + deplib_match=$2 + if test `expr "$ldd_output" : ".*$deplib_match"` -ne 0 ; then + newdeplibs="$newdeplibs $i" + else + droppeddeps=yes + $echo + $echo "*** Warning: dynamic linker does not accept needed library $i." + $echo "*** I have the capability to make that library automatically link in when" + $echo "*** you link to this library. But I can only do this if you have a" + $echo "*** shared version of the library, which you do not appear to have" + $echo "*** because a test_compile did reveal that the linker did not use this one" + $echo "*** as a dynamic dependency that programs can get resolved with at runtime." + fi + fi + else + droppeddeps=yes + $echo + $echo "*** Warning! Library $i is needed by this library but I was not able to" + $echo "*** make it link in! You will probably need to install it or some" + $echo "*** library that it depends on before this library will be fully" + $echo "*** functional. Installing it before continuing would be even better." + fi + else + newdeplibs="$newdeplibs $i" + fi + done + fi + ;; + file_magic*) + set dummy $deplibs_check_method + file_magic_regex=`expr "$deplibs_check_method" : "$2 \(.*\)"` + for a_deplib in $deplibs; do + name=`expr $a_deplib : '-l\(.*\)'` + # If $name is empty we are operating on a -L argument. + if test "$name" != "" && test "$name" != "0"; then + if test "X$allow_libtool_libs_with_static_runtimes" = "Xyes" ; then + case " $predeps $postdeps " in + *" $a_deplib "*) + newdeplibs="$newdeplibs $a_deplib" + a_deplib="" + ;; + esac + fi + if test -n "$a_deplib" ; then + libname=`eval \\$echo \"$libname_spec\"` + for i in $lib_search_path $sys_lib_search_path $shlib_search_path; do + potential_libs=`ls $i/$libname[.-]* 2>/dev/null` + for potent_lib in $potential_libs; do + # Follow soft links. + if ls -lLd "$potent_lib" 2>/dev/null \ + | grep " -> " >/dev/null; then + continue + fi + # The statement above tries to avoid entering an + # endless loop below, in case of cyclic links. + # We might still enter an endless loop, since a link + # loop can be closed while we follow links, + # but so what? + potlib="$potent_lib" + while test -h "$potlib" 2>/dev/null; do + potliblink=`ls -ld $potlib | ${SED} 's/.* -> //'` + case $potliblink in + [\\/]* | [A-Za-z]:[\\/]*) potlib="$potliblink";; + *) potlib=`$echo "X$potlib" | $Xsed -e 's,[^/]*$,,'`"$potliblink";; + esac + done + if eval $file_magic_cmd \"\$potlib\" 2>/dev/null \ + | ${SED} 10q \ + | $EGREP "$file_magic_regex" > /dev/null; then + newdeplibs="$newdeplibs $a_deplib" + a_deplib="" + break 2 + fi + done + done + fi + if test -n "$a_deplib" ; then + droppeddeps=yes + $echo + $echo "*** Warning: linker path does not have real file for library $a_deplib." + $echo "*** I have the capability to make that library automatically link in when" + $echo "*** you link to this library. But I can only do this if you have a" + $echo "*** shared version of the library, which you do not appear to have" + $echo "*** because I did check the linker path looking for a file starting" + if test -z "$potlib" ; then + $echo "*** with $libname but no candidates were found. (...for file magic test)" + else + $echo "*** with $libname and none of the candidates passed a file format test" + $echo "*** using a file magic. Last file checked: $potlib" + fi + fi + else + # Add a -L argument. + newdeplibs="$newdeplibs $a_deplib" + fi + done # Gone through all deplibs. + ;; + match_pattern*) + set dummy $deplibs_check_method + match_pattern_regex=`expr "$deplibs_check_method" : "$2 \(.*\)"` + for a_deplib in $deplibs; do + name=`expr $a_deplib : '-l\(.*\)'` + # If $name is empty we are operating on a -L argument. + if test -n "$name" && test "$name" != "0"; then + if test "X$allow_libtool_libs_with_static_runtimes" = "Xyes" ; then + case " $predeps $postdeps " in + *" $a_deplib "*) + newdeplibs="$newdeplibs $a_deplib" + a_deplib="" + ;; + esac + fi + if test -n "$a_deplib" ; then + libname=`eval \\$echo \"$libname_spec\"` + for i in $lib_search_path $sys_lib_search_path $shlib_search_path; do + potential_libs=`ls $i/$libname[.-]* 2>/dev/null` + for potent_lib in $potential_libs; do + potlib="$potent_lib" # see symlink-check above in file_magic test + if eval $echo \"$potent_lib\" 2>/dev/null \ + | ${SED} 10q \ + | $EGREP "$match_pattern_regex" > /dev/null; then + newdeplibs="$newdeplibs $a_deplib" + a_deplib="" + break 2 + fi + done + done + fi + if test -n "$a_deplib" ; then + droppeddeps=yes + $echo + $echo "*** Warning: linker path does not have real file for library $a_deplib." + $echo "*** I have the capability to make that library automatically link in when" + $echo "*** you link to this library. But I can only do this if you have a" + $echo "*** shared version of the library, which you do not appear to have" + $echo "*** because I did check the linker path looking for a file starting" + if test -z "$potlib" ; then + $echo "*** with $libname but no candidates were found. (...for regex pattern test)" + else + $echo "*** with $libname and none of the candidates passed a file format test" + $echo "*** using a regex pattern. Last file checked: $potlib" + fi + fi + else + # Add a -L argument. + newdeplibs="$newdeplibs $a_deplib" + fi + done # Gone through all deplibs. + ;; + none | unknown | *) + newdeplibs="" + tmp_deplibs=`$echo "X $deplibs" | $Xsed -e 's/ -lc$//' \ + -e 's/ -[LR][^ ]*//g'` + if test "X$allow_libtool_libs_with_static_runtimes" = "Xyes" ; then + for i in $predeps $postdeps ; do + # can't use Xsed below, because $i might contain '/' + tmp_deplibs=`$echo "X $tmp_deplibs" | ${SED} -e "1s,^X,," -e "s,$i,,"` + done + fi + if $echo "X $tmp_deplibs" | $Xsed -e 's/[ ]//g' \ + | grep . >/dev/null; then + $echo + if test "X$deplibs_check_method" = "Xnone"; then + $echo "*** Warning: inter-library dependencies are not supported in this platform." + else + $echo "*** Warning: inter-library dependencies are not known to be supported." + fi + $echo "*** All declared inter-library dependencies are being dropped." + droppeddeps=yes + fi + ;; + esac + versuffix=$versuffix_save + major=$major_save + release=$release_save + libname=$libname_save + name=$name_save + + case $host in + *-*-rhapsody* | *-*-darwin1.[012]) + # On Rhapsody replace the C library is the System framework + newdeplibs=`$echo "X $newdeplibs" | $Xsed -e 's/ -lc / -framework System /'` + ;; + esac + + if test "$droppeddeps" = yes; then + if test "$module" = yes; then + $echo + $echo "*** Warning: libtool could not satisfy all declared inter-library" + $echo "*** dependencies of module $libname. Therefore, libtool will create" + $echo "*** a static module, that should work as long as the dlopening" + $echo "*** application is linked with the -dlopen flag." + if test -z "$global_symbol_pipe"; then + $echo + $echo "*** However, this would only work if libtool was able to extract symbol" + $echo "*** lists from a program, using \`nm' or equivalent, but libtool could" + $echo "*** not find such a program. So, this module is probably useless." + $echo "*** \`nm' from GNU binutils and a full rebuild may help." + fi + if test "$build_old_libs" = no; then + oldlibs="$output_objdir/$libname.$libext" + build_libtool_libs=module + build_old_libs=yes + else + build_libtool_libs=no + fi + else + $echo "*** The inter-library dependencies that have been dropped here will be" + $echo "*** automatically added whenever a program is linked with this library" + $echo "*** or is declared to -dlopen it." + + if test "$allow_undefined" = no; then + $echo + $echo "*** Since this library must not contain undefined symbols," + $echo "*** because either the platform does not support them or" + $echo "*** it was explicitly requested with -no-undefined," + $echo "*** libtool will only create a static version of it." + if test "$build_old_libs" = no; then + oldlibs="$output_objdir/$libname.$libext" + build_libtool_libs=module + build_old_libs=yes + else + build_libtool_libs=no + fi + fi + fi + fi + # Done checking deplibs! + deplibs=$newdeplibs + fi + + + # move library search paths that coincide with paths to not yet + # installed libraries to the beginning of the library search list + new_libs= + for path in $notinst_path; do + case " $new_libs " in + *" -L$path/$objdir "*) ;; + *) + case " $deplibs " in + *" -L$path/$objdir "*) + new_libs="$new_libs -L$path/$objdir" ;; + esac + ;; + esac + done + for deplib in $deplibs; do + case $deplib in + -L*) + case " $new_libs " in + *" $deplib "*) ;; + *) new_libs="$new_libs $deplib" ;; + esac + ;; + *) new_libs="$new_libs $deplib" ;; + esac + done + deplibs="$new_libs" + + + # All the library-specific variables (install_libdir is set above). + library_names= + old_library= + dlname= + + # Test again, we may have decided not to build it any more + if test "$build_libtool_libs" = yes; then + if test "$hardcode_into_libs" = yes; then + # Hardcode the library paths + hardcode_libdirs= + dep_rpath= + rpath="$finalize_rpath" + test "$mode" != relink && rpath="$compile_rpath$rpath" + for libdir in $rpath; do + if test -n "$hardcode_libdir_flag_spec"; then + if test -n "$hardcode_libdir_separator"; then + if test -z "$hardcode_libdirs"; then + hardcode_libdirs="$libdir" + else + # Just accumulate the unique libdirs. + case $hardcode_libdir_separator$hardcode_libdirs$hardcode_libdir_separator in + *"$hardcode_libdir_separator$libdir$hardcode_libdir_separator"*) + ;; + *) + hardcode_libdirs="$hardcode_libdirs$hardcode_libdir_separator$libdir" + ;; + esac + fi + else + eval flag=\"$hardcode_libdir_flag_spec\" + dep_rpath="$dep_rpath $flag" + fi + elif test -n "$runpath_var"; then + case "$perm_rpath " in + *" $libdir "*) ;; + *) perm_rpath="$perm_rpath $libdir" ;; + esac + fi + done + # Substitute the hardcoded libdirs into the rpath. + if test -n "$hardcode_libdir_separator" && + test -n "$hardcode_libdirs"; then + libdir="$hardcode_libdirs" + if test -n "$hardcode_libdir_flag_spec_ld"; then + eval dep_rpath=\"$hardcode_libdir_flag_spec_ld\" + else + eval dep_rpath=\"$hardcode_libdir_flag_spec\" + fi + fi + if test -n "$runpath_var" && test -n "$perm_rpath"; then + # We should set the runpath_var. + rpath= + for dir in $perm_rpath; do + rpath="$rpath$dir:" + done + eval "$runpath_var='$rpath\$$runpath_var'; export $runpath_var" + fi + test -n "$dep_rpath" && deplibs="$dep_rpath $deplibs" + fi + + shlibpath="$finalize_shlibpath" + test "$mode" != relink && shlibpath="$compile_shlibpath$shlibpath" + if test -n "$shlibpath"; then + eval "$shlibpath_var='$shlibpath\$$shlibpath_var'; export $shlibpath_var" + fi + + # Get the real and link names of the library. + eval shared_ext=\"$shrext_cmds\" + eval library_names=\"$library_names_spec\" + set dummy $library_names + realname="$2" + shift; shift + + if test -n "$soname_spec"; then + eval soname=\"$soname_spec\" + else + soname="$realname" + fi + if test -z "$dlname"; then + dlname=$soname + fi + + lib="$output_objdir/$realname" + linknames= + for link + do + linknames="$linknames $link" + done + + # Use standard objects if they are pic + test -z "$pic_flag" && libobjs=`$echo "X$libobjs" | $SP2NL | $Xsed -e "$lo2o" | $NL2SP` + + # Prepare the list of exported symbols + if test -z "$export_symbols"; then + if test "$always_export_symbols" = yes || test -n "$export_symbols_regex"; then + $show "generating symbol list for \`$libname.la'" + export_symbols="$output_objdir/$libname.exp" + $run $rm $export_symbols + cmds=$export_symbols_cmds + save_ifs="$IFS"; IFS='~' + for cmd in $cmds; do + IFS="$save_ifs" + eval cmd=\"$cmd\" + if len=`expr "X$cmd" : ".*"` && + test "$len" -le "$max_cmd_len" || test "$max_cmd_len" -le -1; then + $show "$cmd" + $run eval "$cmd" || exit $? + skipped_export=false + else + # The command line is too long to execute in one step. + $show "using reloadable object file for export list..." + skipped_export=: + # Break out early, otherwise skipped_export may be + # set to false by a later but shorter cmd. + break + fi + done + IFS="$save_ifs" + if test -n "$export_symbols_regex"; then + $show "$EGREP -e \"$export_symbols_regex\" \"$export_symbols\" > \"${export_symbols}T\"" + $run eval '$EGREP -e "$export_symbols_regex" "$export_symbols" > "${export_symbols}T"' + $show "$mv \"${export_symbols}T\" \"$export_symbols\"" + $run eval '$mv "${export_symbols}T" "$export_symbols"' + fi + fi + fi + + if test -n "$export_symbols" && test -n "$include_expsyms"; then + $run eval '$echo "X$include_expsyms" | $SP2NL >> "$export_symbols"' + fi + + tmp_deplibs= + for test_deplib in $deplibs; do + case " $convenience " in + *" $test_deplib "*) ;; + *) + tmp_deplibs="$tmp_deplibs $test_deplib" + ;; + esac + done + deplibs="$tmp_deplibs" + + if test -n "$convenience"; then + if test -n "$whole_archive_flag_spec"; then + save_libobjs=$libobjs + eval libobjs=\"\$libobjs $whole_archive_flag_spec\" + else + gentop="$output_objdir/${outputname}x" + generated="$generated $gentop" + + func_extract_archives $gentop $convenience + libobjs="$libobjs $func_extract_archives_result" + fi + fi + + if test "$thread_safe" = yes && test -n "$thread_safe_flag_spec"; then + eval flag=\"$thread_safe_flag_spec\" + linker_flags="$linker_flags $flag" + fi + + # Make a backup of the uninstalled library when relinking + if test "$mode" = relink; then + $run eval '(cd $output_objdir && $rm ${realname}U && $mv $realname ${realname}U)' || exit $? + fi + + # Do each of the archive commands. + if test "$module" = yes && test -n "$module_cmds" ; then + if test -n "$export_symbols" && test -n "$module_expsym_cmds"; then + eval test_cmds=\"$module_expsym_cmds\" + cmds=$module_expsym_cmds + else + eval test_cmds=\"$module_cmds\" + cmds=$module_cmds + fi + else + if test -n "$export_symbols" && test -n "$archive_expsym_cmds"; then + eval test_cmds=\"$archive_expsym_cmds\" + cmds=$archive_expsym_cmds + else + eval test_cmds=\"$archive_cmds\" + cmds=$archive_cmds + fi + fi + + if test "X$skipped_export" != "X:" && + len=`expr "X$test_cmds" : ".*" 2>/dev/null` && + test "$len" -le "$max_cmd_len" || test "$max_cmd_len" -le -1; then + : + else + # The command line is too long to link in one step, link piecewise. + $echo "creating reloadable object files..." + + # Save the value of $output and $libobjs because we want to + # use them later. If we have whole_archive_flag_spec, we + # want to use save_libobjs as it was before + # whole_archive_flag_spec was expanded, because we can't + # assume the linker understands whole_archive_flag_spec. + # This may have to be revisited, in case too many + # convenience libraries get linked in and end up exceeding + # the spec. + if test -z "$convenience" || test -z "$whole_archive_flag_spec"; then + save_libobjs=$libobjs + fi + save_output=$output + output_la=`$echo "X$output" | $Xsed -e "$basename"` + + # Clear the reloadable object creation command queue and + # initialize k to one. + test_cmds= + concat_cmds= + objlist= + delfiles= + last_robj= + k=1 + output=$output_objdir/$output_la-${k}.$objext + # Loop over the list of objects to be linked. + for obj in $save_libobjs + do + eval test_cmds=\"$reload_cmds $objlist $last_robj\" + if test "X$objlist" = X || + { len=`expr "X$test_cmds" : ".*" 2>/dev/null` && + test "$len" -le "$max_cmd_len"; }; then + objlist="$objlist $obj" + else + # The command $test_cmds is almost too long, add a + # command to the queue. + if test "$k" -eq 1 ; then + # The first file doesn't have a previous command to add. + eval concat_cmds=\"$reload_cmds $objlist $last_robj\" + else + # All subsequent reloadable object files will link in + # the last one created. + eval concat_cmds=\"\$concat_cmds~$reload_cmds $objlist $last_robj\" + fi + last_robj=$output_objdir/$output_la-${k}.$objext + k=`expr $k + 1` + output=$output_objdir/$output_la-${k}.$objext + objlist=$obj + len=1 + fi + done + # Handle the remaining objects by creating one last + # reloadable object file. All subsequent reloadable object + # files will link in the last one created. + test -z "$concat_cmds" || concat_cmds=$concat_cmds~ + eval concat_cmds=\"\${concat_cmds}$reload_cmds $objlist $last_robj\" + + if ${skipped_export-false}; then + $show "generating symbol list for \`$libname.la'" + export_symbols="$output_objdir/$libname.exp" + $run $rm $export_symbols + libobjs=$output + # Append the command to create the export file. + eval concat_cmds=\"\$concat_cmds~$export_symbols_cmds\" + fi + + # Set up a command to remove the reloadable object files + # after they are used. + i=0 + while test "$i" -lt "$k" + do + i=`expr $i + 1` + delfiles="$delfiles $output_objdir/$output_la-${i}.$objext" + done + + $echo "creating a temporary reloadable object file: $output" + + # Loop through the commands generated above and execute them. + save_ifs="$IFS"; IFS='~' + for cmd in $concat_cmds; do + IFS="$save_ifs" + $show "$cmd" + $run eval "$cmd" || exit $? + done + IFS="$save_ifs" + + libobjs=$output + # Restore the value of output. + output=$save_output + + if test -n "$convenience" && test -n "$whole_archive_flag_spec"; then + eval libobjs=\"\$libobjs $whole_archive_flag_spec\" + fi + # Expand the library linking commands again to reset the + # value of $libobjs for piecewise linking. + + # Do each of the archive commands. + if test "$module" = yes && test -n "$module_cmds" ; then + if test -n "$export_symbols" && test -n "$module_expsym_cmds"; then + cmds=$module_expsym_cmds + else + cmds=$module_cmds + fi + else + if test -n "$export_symbols" && test -n "$archive_expsym_cmds"; then + cmds=$archive_expsym_cmds + else + cmds=$archive_cmds + fi + fi + + # Append the command to remove the reloadable object files + # to the just-reset $cmds. + eval cmds=\"\$cmds~\$rm $delfiles\" + fi + save_ifs="$IFS"; IFS='~' + for cmd in $cmds; do + IFS="$save_ifs" + eval cmd=\"$cmd\" + $show "$cmd" + $run eval "$cmd" || { + lt_exit=$? + + # Restore the uninstalled library and exit + if test "$mode" = relink; then + $run eval '(cd $output_objdir && $rm ${realname}T && $mv ${realname}U $realname)' + fi + + exit $lt_exit + } + done + IFS="$save_ifs" + + # Restore the uninstalled library and exit + if test "$mode" = relink; then + $run eval '(cd $output_objdir && $rm ${realname}T && $mv $realname ${realname}T && $mv "$realname"U $realname)' || exit $? + + if test -n "$convenience"; then + if test -z "$whole_archive_flag_spec"; then + $show "${rm}r $gentop" + $run ${rm}r "$gentop" + fi + fi + + exit $EXIT_SUCCESS + fi + + # Create links to the real library. + for linkname in $linknames; do + if test "$realname" != "$linkname"; then + $show "(cd $output_objdir && $rm $linkname && $LN_S $realname $linkname)" + $run eval '(cd $output_objdir && $rm $linkname && $LN_S $realname $linkname)' || exit $? + fi + done + + # If -module or -export-dynamic was specified, set the dlname. + if test "$module" = yes || test "$export_dynamic" = yes; then + # On all known operating systems, these are identical. + dlname="$soname" + fi + fi + ;; + + obj) + if test -n "$deplibs"; then + $echo "$modename: warning: \`-l' and \`-L' are ignored for objects" 1>&2 + fi + + if test -n "$dlfiles$dlprefiles" || test "$dlself" != no; then + $echo "$modename: warning: \`-dlopen' is ignored for objects" 1>&2 + fi + + if test -n "$rpath"; then + $echo "$modename: warning: \`-rpath' is ignored for objects" 1>&2 + fi + + if test -n "$xrpath"; then + $echo "$modename: warning: \`-R' is ignored for objects" 1>&2 + fi + + if test -n "$vinfo"; then + $echo "$modename: warning: \`-version-info' is ignored for objects" 1>&2 + fi + + if test -n "$release"; then + $echo "$modename: warning: \`-release' is ignored for objects" 1>&2 + fi + + case $output in + *.lo) + if test -n "$objs$old_deplibs"; then + $echo "$modename: cannot build library object \`$output' from non-libtool objects" 1>&2 + exit $EXIT_FAILURE + fi + libobj="$output" + obj=`$echo "X$output" | $Xsed -e "$lo2o"` + ;; + *) + libobj= + obj="$output" + ;; + esac + + # Delete the old objects. + $run $rm $obj $libobj + + # Objects from convenience libraries. This assumes + # single-version convenience libraries. Whenever we create + # different ones for PIC/non-PIC, this we'll have to duplicate + # the extraction. + reload_conv_objs= + gentop= + # reload_cmds runs $LD directly, so let us get rid of + # -Wl from whole_archive_flag_spec and hope we can get by with + # turning comma into space.. + wl= + + if test -n "$convenience"; then + if test -n "$whole_archive_flag_spec"; then + eval tmp_whole_archive_flags=\"$whole_archive_flag_spec\" + reload_conv_objs=$reload_objs\ `$echo "X$tmp_whole_archive_flags" | $Xsed -e 's|,| |g'` + else + gentop="$output_objdir/${obj}x" + generated="$generated $gentop" + + func_extract_archives $gentop $convenience + reload_conv_objs="$reload_objs $func_extract_archives_result" + fi + fi + + # Create the old-style object. + reload_objs="$objs$old_deplibs "`$echo "X$libobjs" | $SP2NL | $Xsed -e '/\.'${libext}$'/d' -e '/\.lib$/d' -e "$lo2o" | $NL2SP`" $reload_conv_objs" ### testsuite: skip nested quoting test + + output="$obj" + cmds=$reload_cmds + save_ifs="$IFS"; IFS='~' + for cmd in $cmds; do + IFS="$save_ifs" + eval cmd=\"$cmd\" + $show "$cmd" + $run eval "$cmd" || exit $? + done + IFS="$save_ifs" + + # Exit if we aren't doing a library object file. + if test -z "$libobj"; then + if test -n "$gentop"; then + $show "${rm}r $gentop" + $run ${rm}r $gentop + fi + + exit $EXIT_SUCCESS + fi + + if test "$build_libtool_libs" != yes; then + if test -n "$gentop"; then + $show "${rm}r $gentop" + $run ${rm}r $gentop + fi + + # Create an invalid libtool object if no PIC, so that we don't + # accidentally link it into a program. + # $show "echo timestamp > $libobj" + # $run eval "echo timestamp > $libobj" || exit $? + exit $EXIT_SUCCESS + fi + + if test -n "$pic_flag" || test "$pic_mode" != default; then + # Only do commands if we really have different PIC objects. + reload_objs="$libobjs $reload_conv_objs" + output="$libobj" + cmds=$reload_cmds + save_ifs="$IFS"; IFS='~' + for cmd in $cmds; do + IFS="$save_ifs" + eval cmd=\"$cmd\" + $show "$cmd" + $run eval "$cmd" || exit $? + done + IFS="$save_ifs" + fi + + if test -n "$gentop"; then + $show "${rm}r $gentop" + $run ${rm}r $gentop + fi + + exit $EXIT_SUCCESS + ;; + + prog) + case $host in + *cygwin*) output=`$echo $output | ${SED} -e 's,.exe$,,;s,$,.exe,'` ;; + esac + if test -n "$vinfo"; then + $echo "$modename: warning: \`-version-info' is ignored for programs" 1>&2 + fi + + if test -n "$release"; then + $echo "$modename: warning: \`-release' is ignored for programs" 1>&2 + fi + + if test "$preload" = yes; then + if test "$dlopen_support" = unknown && test "$dlopen_self" = unknown && + test "$dlopen_self_static" = unknown; then + $echo "$modename: warning: \`AC_LIBTOOL_DLOPEN' not used. Assuming no dlopen support." + fi + fi + + case $host in + *-*-rhapsody* | *-*-darwin1.[012]) + # On Rhapsody replace the C library is the System framework + compile_deplibs=`$echo "X $compile_deplibs" | $Xsed -e 's/ -lc / -framework System /'` + finalize_deplibs=`$echo "X $finalize_deplibs" | $Xsed -e 's/ -lc / -framework System /'` + ;; + esac + + case $host in + *darwin*) + # Don't allow lazy linking, it breaks C++ global constructors + if test "$tagname" = CXX ; then + compile_command="$compile_command ${wl}-bind_at_load" + finalize_command="$finalize_command ${wl}-bind_at_load" + fi + ;; + esac + + + # move library search paths that coincide with paths to not yet + # installed libraries to the beginning of the library search list + new_libs= + for path in $notinst_path; do + case " $new_libs " in + *" -L$path/$objdir "*) ;; + *) + case " $compile_deplibs " in + *" -L$path/$objdir "*) + new_libs="$new_libs -L$path/$objdir" ;; + esac + ;; + esac + done + for deplib in $compile_deplibs; do + case $deplib in + -L*) + case " $new_libs " in + *" $deplib "*) ;; + *) new_libs="$new_libs $deplib" ;; + esac + ;; + *) new_libs="$new_libs $deplib" ;; + esac + done + compile_deplibs="$new_libs" + + + compile_command="$compile_command $compile_deplibs" + finalize_command="$finalize_command $finalize_deplibs" + + if test -n "$rpath$xrpath"; then + # If the user specified any rpath flags, then add them. + for libdir in $rpath $xrpath; do + # This is the magic to use -rpath. + case "$finalize_rpath " in + *" $libdir "*) ;; + *) finalize_rpath="$finalize_rpath $libdir" ;; + esac + done + fi + + # Now hardcode the library paths + rpath= + hardcode_libdirs= + for libdir in $compile_rpath $finalize_rpath; do + if test -n "$hardcode_libdir_flag_spec"; then + if test -n "$hardcode_libdir_separator"; then + if test -z "$hardcode_libdirs"; then + hardcode_libdirs="$libdir" + else + # Just accumulate the unique libdirs. + case $hardcode_libdir_separator$hardcode_libdirs$hardcode_libdir_separator in + *"$hardcode_libdir_separator$libdir$hardcode_libdir_separator"*) + ;; + *) + hardcode_libdirs="$hardcode_libdirs$hardcode_libdir_separator$libdir" + ;; + esac + fi + else + eval flag=\"$hardcode_libdir_flag_spec\" + rpath="$rpath $flag" + fi + elif test -n "$runpath_var"; then + case "$perm_rpath " in + *" $libdir "*) ;; + *) perm_rpath="$perm_rpath $libdir" ;; + esac + fi + case $host in + *-*-cygwin* | *-*-mingw* | *-*-pw32* | *-*-os2*) + testbindir=`$echo "X$libdir" | $Xsed -e 's*/lib$*/bin*'` + case :$dllsearchpath: in + *":$libdir:"*) ;; + *) dllsearchpath="$dllsearchpath:$libdir";; + esac + case :$dllsearchpath: in + *":$testbindir:"*) ;; + *) dllsearchpath="$dllsearchpath:$testbindir";; + esac + ;; + esac + done + # Substitute the hardcoded libdirs into the rpath. + if test -n "$hardcode_libdir_separator" && + test -n "$hardcode_libdirs"; then + libdir="$hardcode_libdirs" + eval rpath=\" $hardcode_libdir_flag_spec\" + fi + compile_rpath="$rpath" + + rpath= + hardcode_libdirs= + for libdir in $finalize_rpath; do + if test -n "$hardcode_libdir_flag_spec"; then + if test -n "$hardcode_libdir_separator"; then + if test -z "$hardcode_libdirs"; then + hardcode_libdirs="$libdir" + else + # Just accumulate the unique libdirs. + case $hardcode_libdir_separator$hardcode_libdirs$hardcode_libdir_separator in + *"$hardcode_libdir_separator$libdir$hardcode_libdir_separator"*) + ;; + *) + hardcode_libdirs="$hardcode_libdirs$hardcode_libdir_separator$libdir" + ;; + esac + fi + else + eval flag=\"$hardcode_libdir_flag_spec\" + rpath="$rpath $flag" + fi + elif test -n "$runpath_var"; then + case "$finalize_perm_rpath " in + *" $libdir "*) ;; + *) finalize_perm_rpath="$finalize_perm_rpath $libdir" ;; + esac + fi + done + # Substitute the hardcoded libdirs into the rpath. + if test -n "$hardcode_libdir_separator" && + test -n "$hardcode_libdirs"; then + libdir="$hardcode_libdirs" + eval rpath=\" $hardcode_libdir_flag_spec\" + fi + finalize_rpath="$rpath" + + if test -n "$libobjs" && test "$build_old_libs" = yes; then + # Transform all the library objects into standard objects. + compile_command=`$echo "X$compile_command" | $SP2NL | $Xsed -e "$lo2o" | $NL2SP` + finalize_command=`$echo "X$finalize_command" | $SP2NL | $Xsed -e "$lo2o" | $NL2SP` + fi + + dlsyms= + if test -n "$dlfiles$dlprefiles" || test "$dlself" != no; then + if test -n "$NM" && test -n "$global_symbol_pipe"; then + dlsyms="${outputname}S.c" + else + $echo "$modename: not configured to extract global symbols from dlpreopened files" 1>&2 + fi + fi + + if test -n "$dlsyms"; then + case $dlsyms in + "") ;; + *.c) + # Discover the nlist of each of the dlfiles. + nlist="$output_objdir/${outputname}.nm" + + $show "$rm $nlist ${nlist}S ${nlist}T" + $run $rm "$nlist" "${nlist}S" "${nlist}T" + + # Parse the name list into a source file. + $show "creating $output_objdir/$dlsyms" + + test -z "$run" && $echo > "$output_objdir/$dlsyms" "\ +/* $dlsyms - symbol resolution table for \`$outputname' dlsym emulation. */ +/* Generated by $PROGRAM - GNU $PACKAGE $VERSION$TIMESTAMP */ + +#ifdef __cplusplus +extern \"C\" { +#endif + +/* Prevent the only kind of declaration conflicts we can make. */ +#define lt_preloaded_symbols some_other_symbol + +/* External symbol declarations for the compiler. */\ +" + + if test "$dlself" = yes; then + $show "generating symbol list for \`$output'" + + test -z "$run" && $echo ': @PROGRAM@ ' > "$nlist" + + # Add our own program objects to the symbol list. + progfiles=`$echo "X$objs$old_deplibs" | $SP2NL | $Xsed -e "$lo2o" | $NL2SP` + for arg in $progfiles; do + $show "extracting global C symbols from \`$arg'" + $run eval "$NM $arg | $global_symbol_pipe >> '$nlist'" + done + + if test -n "$exclude_expsyms"; then + $run eval '$EGREP -v " ($exclude_expsyms)$" "$nlist" > "$nlist"T' + $run eval '$mv "$nlist"T "$nlist"' + fi + + if test -n "$export_symbols_regex"; then + $run eval '$EGREP -e "$export_symbols_regex" "$nlist" > "$nlist"T' + $run eval '$mv "$nlist"T "$nlist"' + fi + + # Prepare the list of exported symbols + if test -z "$export_symbols"; then + export_symbols="$output_objdir/$outputname.exp" + $run $rm $export_symbols + $run eval "${SED} -n -e '/^: @PROGRAM@ $/d' -e 's/^.* \(.*\)$/\1/p' "'< "$nlist" > "$export_symbols"' + case $host in + *cygwin* | *mingw* ) + $run eval "echo EXPORTS "'> "$output_objdir/$outputname.def"' + $run eval 'cat "$export_symbols" >> "$output_objdir/$outputname.def"' + ;; + esac + else + $run eval "${SED} -e 's/\([].[*^$]\)/\\\\\1/g' -e 's/^/ /' -e 's/$/$/'"' < "$export_symbols" > "$output_objdir/$outputname.exp"' + $run eval 'grep -f "$output_objdir/$outputname.exp" < "$nlist" > "$nlist"T' + $run eval 'mv "$nlist"T "$nlist"' + case $host in + *cygwin* | *mingw* ) + $run eval "echo EXPORTS "'> "$output_objdir/$outputname.def"' + $run eval 'cat "$nlist" >> "$output_objdir/$outputname.def"' + ;; + esac + fi + fi + + for arg in $dlprefiles; do + $show "extracting global C symbols from \`$arg'" + name=`$echo "$arg" | ${SED} -e 's%^.*/%%'` + $run eval '$echo ": $name " >> "$nlist"' + $run eval "$NM $arg | $global_symbol_pipe >> '$nlist'" + done + + if test -z "$run"; then + # Make sure we have at least an empty file. + test -f "$nlist" || : > "$nlist" + + if test -n "$exclude_expsyms"; then + $EGREP -v " ($exclude_expsyms)$" "$nlist" > "$nlist"T + $mv "$nlist"T "$nlist" + fi + + # Try sorting and uniquifying the output. + if grep -v "^: " < "$nlist" | + if sort -k 3 </dev/null >/dev/null 2>&1; then + sort -k 3 + else + sort +2 + fi | + uniq > "$nlist"S; then + : + else + grep -v "^: " < "$nlist" > "$nlist"S + fi + + if test -f "$nlist"S; then + eval "$global_symbol_to_cdecl"' < "$nlist"S >> "$output_objdir/$dlsyms"' + else + $echo '/* NONE */' >> "$output_objdir/$dlsyms" + fi + + $echo >> "$output_objdir/$dlsyms" "\ + +#undef lt_preloaded_symbols + +#if defined (__STDC__) && __STDC__ +# define lt_ptr void * +#else +# define lt_ptr char * +# define const +#endif + +/* The mapping between symbol names and symbols. */ +" + + case $host in + *cygwin* | *mingw* ) + $echo >> "$output_objdir/$dlsyms" "\ +/* DATA imports from DLLs on WIN32 can't be const, because + runtime relocations are performed -- see ld's documentation + on pseudo-relocs */ +struct { +" + ;; + * ) + $echo >> "$output_objdir/$dlsyms" "\ +const struct { +" + ;; + esac + + + $echo >> "$output_objdir/$dlsyms" "\ + const char *name; + lt_ptr address; +} +lt_preloaded_symbols[] = +{\ +" + + eval "$global_symbol_to_c_name_address" < "$nlist" >> "$output_objdir/$dlsyms" + + $echo >> "$output_objdir/$dlsyms" "\ + {0, (lt_ptr) 0} +}; + +/* This works around a problem in FreeBSD linker */ +#ifdef FREEBSD_WORKAROUND +static const void *lt_preloaded_setup() { + return lt_preloaded_symbols; +} +#endif + +#ifdef __cplusplus +} +#endif\ +" + fi + + pic_flag_for_symtable= + case $host in + # compiling the symbol table file with pic_flag works around + # a FreeBSD bug that causes programs to crash when -lm is + # linked before any other PIC object. But we must not use + # pic_flag when linking with -static. The problem exists in + # FreeBSD 2.2.6 and is fixed in FreeBSD 3.1. + *-*-freebsd2*|*-*-freebsd3.0*|*-*-freebsdelf3.0*) + case "$compile_command " in + *" -static "*) ;; + *) pic_flag_for_symtable=" $pic_flag -DFREEBSD_WORKAROUND";; + esac;; + *-*-hpux*) + case "$compile_command " in + *" -static "*) ;; + *) pic_flag_for_symtable=" $pic_flag";; + esac + esac + + # Now compile the dynamic symbol file. + $show "(cd $output_objdir && $LTCC $LTCFLAGS -c$no_builtin_flag$pic_flag_for_symtable \"$dlsyms\")" + $run eval '(cd $output_objdir && $LTCC $LTCFLAGS -c$no_builtin_flag$pic_flag_for_symtable "$dlsyms")' || exit $? + + # Clean up the generated files. + $show "$rm $output_objdir/$dlsyms $nlist ${nlist}S ${nlist}T" + $run $rm "$output_objdir/$dlsyms" "$nlist" "${nlist}S" "${nlist}T" + + # Transform the symbol file into the correct name. + case $host in + *cygwin* | *mingw* ) + if test -f "$output_objdir/${outputname}.def" ; then + compile_command=`$echo "X$compile_command" | $SP2NL | $Xsed -e "s%@SYMFILE@%$output_objdir/${outputname}.def $output_objdir/${outputname}S.${objext}%" | $NL2SP` + finalize_command=`$echo "X$finalize_command" | $SP2NL | $Xsed -e "s%@SYMFILE@%$output_objdir/${outputname}.def $output_objdir/${outputname}S.${objext}%" | $NL2SP` + else + compile_command=`$echo "X$compile_command" | $SP2NL | $Xsed -e "s%@SYMFILE@%$output_objdir/${outputname}S.${objext}%" | $NL2SP` + finalize_command=`$echo "X$finalize_command" | $SP2NL | $Xsed -e "s%@SYMFILE@%$output_objdir/${outputname}S.${objext}%" | $NL2SP` + fi + ;; + * ) + compile_command=`$echo "X$compile_command" | $SP2NL | $Xsed -e "s%@SYMFILE@%$output_objdir/${outputname}S.${objext}%" | $NL2SP` + finalize_command=`$echo "X$finalize_command" | $SP2NL | $Xsed -e "s%@SYMFILE@%$output_objdir/${outputname}S.${objext}%" | $NL2SP` + ;; + esac + ;; + *) + $echo "$modename: unknown suffix for \`$dlsyms'" 1>&2 + exit $EXIT_FAILURE + ;; + esac + else + # We keep going just in case the user didn't refer to + # lt_preloaded_symbols. The linker will fail if global_symbol_pipe + # really was required. + + # Nullify the symbol file. + compile_command=`$echo "X$compile_command" | $SP2NL | $Xsed -e "s% @SYMFILE@%%" | $NL2SP` + finalize_command=`$echo "X$finalize_command" | $SP2NL | $Xsed -e "s% @SYMFILE@%%" | $NL2SP` + fi + + if test "$need_relink" = no || test "$build_libtool_libs" != yes; then + # Replace the output file specification. + compile_command=`$echo "X$compile_command" | $SP2NL | $Xsed -e 's%@OUTPUT@%'"$output"'%g' | $NL2SP` + link_command="$compile_command$compile_rpath" + + # We have no uninstalled library dependencies, so finalize right now. + $show "$link_command" + $run eval "$link_command" + exit_status=$? + + # Delete the generated files. + if test -n "$dlsyms"; then + $show "$rm $output_objdir/${outputname}S.${objext}" + $run $rm "$output_objdir/${outputname}S.${objext}" + fi + + exit $exit_status + fi + + if test -n "$shlibpath_var"; then + # We should set the shlibpath_var + rpath= + for dir in $temp_rpath; do + case $dir in + [\\/]* | [A-Za-z]:[\\/]*) + # Absolute path. + rpath="$rpath$dir:" + ;; + *) + # Relative path: add a thisdir entry. + rpath="$rpath\$thisdir/$dir:" + ;; + esac + done + temp_rpath="$rpath" + fi + + if test -n "$compile_shlibpath$finalize_shlibpath"; then + compile_command="$shlibpath_var=\"$compile_shlibpath$finalize_shlibpath\$$shlibpath_var\" $compile_command" + fi + if test -n "$finalize_shlibpath"; then + finalize_command="$shlibpath_var=\"$finalize_shlibpath\$$shlibpath_var\" $finalize_command" + fi + + compile_var= + finalize_var= + if test -n "$runpath_var"; then + if test -n "$perm_rpath"; then + # We should set the runpath_var. + rpath= + for dir in $perm_rpath; do + rpath="$rpath$dir:" + done + compile_var="$runpath_var=\"$rpath\$$runpath_var\" " + fi + if test -n "$finalize_perm_rpath"; then + # We should set the runpath_var. + rpath= + for dir in $finalize_perm_rpath; do + rpath="$rpath$dir:" + done + finalize_var="$runpath_var=\"$rpath\$$runpath_var\" " + fi + fi + + if test "$no_install" = yes; then + # We don't need to create a wrapper script. + link_command="$compile_var$compile_command$compile_rpath" + # Replace the output file specification. + link_command=`$echo "X$link_command" | $Xsed -e 's%@OUTPUT@%'"$output"'%g'` + # Delete the old output file. + $run $rm $output + # Link the executable and exit + $show "$link_command" + $run eval "$link_command" || exit $? + exit $EXIT_SUCCESS + fi + + if test "$hardcode_action" = relink; then + # Fast installation is not supported + link_command="$compile_var$compile_command$compile_rpath" + relink_command="$finalize_var$finalize_command$finalize_rpath" + + $echo "$modename: warning: this platform does not like uninstalled shared libraries" 1>&2 + $echo "$modename: \`$output' will be relinked during installation" 1>&2 + else + if test "$fast_install" != no; then + link_command="$finalize_var$compile_command$finalize_rpath" + if test "$fast_install" = yes; then + relink_command=`$echo "X$compile_var$compile_command$compile_rpath" | $SP2NL | $Xsed -e 's%@OUTPUT@%\$progdir/\$file%g' | $NL2SP` + else + # fast_install is set to needless + relink_command= + fi + else + link_command="$compile_var$compile_command$compile_rpath" + relink_command="$finalize_var$finalize_command$finalize_rpath" + fi + fi + + # Replace the output file specification. + link_command=`$echo "X$link_command" | $Xsed -e 's%@OUTPUT@%'"$output_objdir/$outputname"'%g'` + + # Delete the old output files. + $run $rm $output $output_objdir/$outputname $output_objdir/lt-$outputname + + $show "$link_command" + $run eval "$link_command" || exit $? + + # Now create the wrapper script. + $show "creating $output" + + # Quote the relink command for shipping. + if test -n "$relink_command"; then + # Preserve any variables that may affect compiler behavior + for var in $variables_saved_for_relink; do + if eval test -z \"\${$var+set}\"; then + relink_command="{ test -z \"\${$var+set}\" || unset $var || { $var=; export $var; }; }; $relink_command" + elif eval var_value=\$$var; test -z "$var_value"; then + relink_command="$var=; export $var; $relink_command" + else + var_value=`$echo "X$var_value" | $Xsed -e "$sed_quote_subst"` + relink_command="$var=\"$var_value\"; export $var; $relink_command" + fi + done + relink_command="(cd `pwd`; $relink_command)" + relink_command=`$echo "X$relink_command" | $SP2NL | $Xsed -e "$sed_quote_subst" | $NL2SP` + fi + + # Quote $echo for shipping. + if test "X$echo" = "X$SHELL $progpath --fallback-echo"; then + case $progpath in + [\\/]* | [A-Za-z]:[\\/]*) qecho="$SHELL $progpath --fallback-echo";; + *) qecho="$SHELL `pwd`/$progpath --fallback-echo";; + esac + qecho=`$echo "X$qecho" | $Xsed -e "$sed_quote_subst"` + else + qecho=`$echo "X$echo" | $Xsed -e "$sed_quote_subst"` + fi + + # Only actually do things if our run command is non-null. + if test -z "$run"; then + # win32 will think the script is a binary if it has + # a .exe suffix, so we strip it off here. + case $output in + *.exe) output=`$echo $output|${SED} 's,.exe$,,'` ;; + esac + # test for cygwin because mv fails w/o .exe extensions + case $host in + *cygwin*) + exeext=.exe + outputname=`$echo $outputname|${SED} 's,.exe$,,'` ;; + *) exeext= ;; + esac + case $host in + *cygwin* | *mingw* ) + output_name=`basename $output` + output_path=`dirname $output` + cwrappersource="$output_path/$objdir/lt-$output_name.c" + cwrapper="$output_path/$output_name.exe" + $rm $cwrappersource $cwrapper + trap "$rm $cwrappersource $cwrapper; exit $EXIT_FAILURE" 1 2 15 + + cat > $cwrappersource <<EOF + +/* $cwrappersource - temporary wrapper executable for $objdir/$outputname + Generated by $PROGRAM - GNU $PACKAGE $VERSION$TIMESTAMP + + The $output program cannot be directly executed until all the libtool + libraries that it depends on are installed. + + This wrapper executable should never be moved out of the build directory. + If it is, it will not operate correctly. + + Currently, it simply execs the wrapper *script* "/bin/sh $output", + but could eventually absorb all of the scripts functionality and + exec $objdir/$outputname directly. +*/ +EOF + cat >> $cwrappersource<<"EOF" +#include <stdio.h> +#include <stdlib.h> +#include <unistd.h> +#include <malloc.h> +#include <stdarg.h> +#include <assert.h> +#include <string.h> +#include <ctype.h> +#include <sys/stat.h> + +#if defined(PATH_MAX) +# define LT_PATHMAX PATH_MAX +#elif defined(MAXPATHLEN) +# define LT_PATHMAX MAXPATHLEN +#else +# define LT_PATHMAX 1024 +#endif + +#ifndef DIR_SEPARATOR +# define DIR_SEPARATOR '/' +# define PATH_SEPARATOR ':' +#endif + +#if defined (_WIN32) || defined (__MSDOS__) || defined (__DJGPP__) || \ + defined (__OS2__) +# define HAVE_DOS_BASED_FILE_SYSTEM +# ifndef DIR_SEPARATOR_2 +# define DIR_SEPARATOR_2 '\\' +# endif +# ifndef PATH_SEPARATOR_2 +# define PATH_SEPARATOR_2 ';' +# endif +#endif + +#ifndef DIR_SEPARATOR_2 +# define IS_DIR_SEPARATOR(ch) ((ch) == DIR_SEPARATOR) +#else /* DIR_SEPARATOR_2 */ +# define IS_DIR_SEPARATOR(ch) \ + (((ch) == DIR_SEPARATOR) || ((ch) == DIR_SEPARATOR_2)) +#endif /* DIR_SEPARATOR_2 */ + +#ifndef PATH_SEPARATOR_2 +# define IS_PATH_SEPARATOR(ch) ((ch) == PATH_SEPARATOR) +#else /* PATH_SEPARATOR_2 */ +# define IS_PATH_SEPARATOR(ch) ((ch) == PATH_SEPARATOR_2) +#endif /* PATH_SEPARATOR_2 */ + +#define XMALLOC(type, num) ((type *) xmalloc ((num) * sizeof(type))) +#define XFREE(stale) do { \ + if (stale) { free ((void *) stale); stale = 0; } \ +} while (0) + +/* -DDEBUG is fairly common in CFLAGS. */ +#undef DEBUG +#if defined DEBUGWRAPPER +# define DEBUG(format, ...) fprintf(stderr, format, __VA_ARGS__) +#else +# define DEBUG(format, ...) +#endif + +const char *program_name = NULL; + +void * xmalloc (size_t num); +char * xstrdup (const char *string); +const char * base_name (const char *name); +char * find_executable(const char *wrapper); +int check_executable(const char *path); +char * strendzap(char *str, const char *pat); +void lt_fatal (const char *message, ...); + +int +main (int argc, char *argv[]) +{ + char **newargz; + int i; + + program_name = (char *) xstrdup (base_name (argv[0])); + DEBUG("(main) argv[0] : %s\n",argv[0]); + DEBUG("(main) program_name : %s\n",program_name); + newargz = XMALLOC(char *, argc+2); +EOF + + cat >> $cwrappersource <<EOF + newargz[0] = (char *) xstrdup("$SHELL"); +EOF + + cat >> $cwrappersource <<"EOF" + newargz[1] = find_executable(argv[0]); + if (newargz[1] == NULL) + lt_fatal("Couldn't find %s", argv[0]); + DEBUG("(main) found exe at : %s\n",newargz[1]); + /* we know the script has the same name, without the .exe */ + /* so make sure newargz[1] doesn't end in .exe */ + strendzap(newargz[1],".exe"); + for (i = 1; i < argc; i++) + newargz[i+1] = xstrdup(argv[i]); + newargz[argc+1] = NULL; + + for (i=0; i<argc+1; i++) + { + DEBUG("(main) newargz[%d] : %s\n",i,newargz[i]); + ; + } + +EOF + + case $host_os in + mingw*) + cat >> $cwrappersource <<EOF + execv("$SHELL",(char const **)newargz); +EOF + ;; + *) + cat >> $cwrappersource <<EOF + execv("$SHELL",newargz); +EOF + ;; + esac + + cat >> $cwrappersource <<"EOF" + return 127; +} + +void * +xmalloc (size_t num) +{ + void * p = (void *) malloc (num); + if (!p) + lt_fatal ("Memory exhausted"); + + return p; +} + +char * +xstrdup (const char *string) +{ + return string ? strcpy ((char *) xmalloc (strlen (string) + 1), string) : NULL +; +} + +const char * +base_name (const char *name) +{ + const char *base; + +#if defined (HAVE_DOS_BASED_FILE_SYSTEM) + /* Skip over the disk name in MSDOS pathnames. */ + if (isalpha ((unsigned char)name[0]) && name[1] == ':') + name += 2; +#endif + + for (base = name; *name; name++) + if (IS_DIR_SEPARATOR (*name)) + base = name + 1; + return base; +} + +int +check_executable(const char * path) +{ + struct stat st; + + DEBUG("(check_executable) : %s\n", path ? (*path ? path : "EMPTY!") : "NULL!"); + if ((!path) || (!*path)) + return 0; + + if ((stat (path, &st) >= 0) && + ( + /* MinGW & native WIN32 do not support S_IXOTH or S_IXGRP */ +#if defined (S_IXOTH) + ((st.st_mode & S_IXOTH) == S_IXOTH) || +#endif +#if defined (S_IXGRP) + ((st.st_mode & S_IXGRP) == S_IXGRP) || +#endif + ((st.st_mode & S_IXUSR) == S_IXUSR)) + ) + return 1; + else + return 0; +} + +/* Searches for the full path of the wrapper. Returns + newly allocated full path name if found, NULL otherwise */ +char * +find_executable (const char* wrapper) +{ + int has_slash = 0; + const char* p; + const char* p_next; + /* static buffer for getcwd */ + char tmp[LT_PATHMAX + 1]; + int tmp_len; + char* concat_name; + + DEBUG("(find_executable) : %s\n", wrapper ? (*wrapper ? wrapper : "EMPTY!") : "NULL!"); + + if ((wrapper == NULL) || (*wrapper == '\0')) + return NULL; + + /* Absolute path? */ +#if defined (HAVE_DOS_BASED_FILE_SYSTEM) + if (isalpha ((unsigned char)wrapper[0]) && wrapper[1] == ':') + { + concat_name = xstrdup (wrapper); + if (check_executable(concat_name)) + return concat_name; + XFREE(concat_name); + } + else + { +#endif + if (IS_DIR_SEPARATOR (wrapper[0])) + { + concat_name = xstrdup (wrapper); + if (check_executable(concat_name)) + return concat_name; + XFREE(concat_name); + } +#if defined (HAVE_DOS_BASED_FILE_SYSTEM) + } +#endif + + for (p = wrapper; *p; p++) + if (*p == '/') + { + has_slash = 1; + break; + } + if (!has_slash) + { + /* no slashes; search PATH */ + const char* path = getenv ("PATH"); + if (path != NULL) + { + for (p = path; *p; p = p_next) + { + const char* q; + size_t p_len; + for (q = p; *q; q++) + if (IS_PATH_SEPARATOR(*q)) + break; + p_len = q - p; + p_next = (*q == '\0' ? q : q + 1); + if (p_len == 0) + { + /* empty path: current directory */ + if (getcwd (tmp, LT_PATHMAX) == NULL) + lt_fatal ("getcwd failed"); + tmp_len = strlen(tmp); + concat_name = XMALLOC(char, tmp_len + 1 + strlen(wrapper) + 1); + memcpy (concat_name, tmp, tmp_len); + concat_name[tmp_len] = '/'; + strcpy (concat_name + tmp_len + 1, wrapper); + } + else + { + concat_name = XMALLOC(char, p_len + 1 + strlen(wrapper) + 1); + memcpy (concat_name, p, p_len); + concat_name[p_len] = '/'; + strcpy (concat_name + p_len + 1, wrapper); + } + if (check_executable(concat_name)) + return concat_name; + XFREE(concat_name); + } + } + /* not found in PATH; assume curdir */ + } + /* Relative path | not found in path: prepend cwd */ + if (getcwd (tmp, LT_PATHMAX) == NULL) + lt_fatal ("getcwd failed"); + tmp_len = strlen(tmp); + concat_name = XMALLOC(char, tmp_len + 1 + strlen(wrapper) + 1); + memcpy (concat_name, tmp, tmp_len); + concat_name[tmp_len] = '/'; + strcpy (concat_name + tmp_len + 1, wrapper); + + if (check_executable(concat_name)) + return concat_name; + XFREE(concat_name); + return NULL; +} + +char * +strendzap(char *str, const char *pat) +{ + size_t len, patlen; + + assert(str != NULL); + assert(pat != NULL); + + len = strlen(str); + patlen = strlen(pat); + + if (patlen <= len) + { + str += len - patlen; + if (strcmp(str, pat) == 0) + *str = '\0'; + } + return str; +} + +static void +lt_error_core (int exit_status, const char * mode, + const char * message, va_list ap) +{ + fprintf (stderr, "%s: %s: ", program_name, mode); + vfprintf (stderr, message, ap); + fprintf (stderr, ".\n"); + + if (exit_status >= 0) + exit (exit_status); +} + +void +lt_fatal (const char *message, ...) +{ + va_list ap; + va_start (ap, message); + lt_error_core (EXIT_FAILURE, "FATAL", message, ap); + va_end (ap); +} +EOF + # we should really use a build-platform specific compiler + # here, but OTOH, the wrappers (shell script and this C one) + # are only useful if you want to execute the "real" binary. + # Since the "real" binary is built for $host, then this + # wrapper might as well be built for $host, too. + $run $LTCC $LTCFLAGS -s -o $cwrapper $cwrappersource + ;; + esac + $rm $output + trap "$rm $output; exit $EXIT_FAILURE" 1 2 15 + + $echo > $output "\ +#! $SHELL + +# $output - temporary wrapper script for $objdir/$outputname +# Generated by $PROGRAM - GNU $PACKAGE $VERSION$TIMESTAMP +# +# The $output program cannot be directly executed until all the libtool +# libraries that it depends on are installed. +# +# This wrapper script should never be moved out of the build directory. +# If it is, it will not operate correctly. + +# Sed substitution that helps us do robust quoting. It backslashifies +# metacharacters that are still active within double-quoted strings. +Xsed='${SED} -e 1s/^X//' +sed_quote_subst='$sed_quote_subst' + +# Be Bourne compatible (taken from Autoconf:_AS_BOURNE_COMPATIBLE). +if test -n \"\${ZSH_VERSION+set}\" && (emulate sh) >/dev/null 2>&1; then + emulate sh + NULLCMD=: + # Zsh 3.x and 4.x performs word splitting on \${1+\"\$@\"}, which + # is contrary to our usage. Disable this feature. + alias -g '\${1+\"\$@\"}'='\"\$@\"' + setopt NO_GLOB_SUBST +else + case \`(set -o) 2>/dev/null\` in *posix*) set -o posix;; esac +fi + +# The HP-UX ksh and POSIX shell print the target directory to stdout +# if CDPATH is set. +(unset CDPATH) >/dev/null 2>&1 && unset CDPATH + +relink_command=\"$relink_command\" + +# This environment variable determines our operation mode. +if test \"\$libtool_install_magic\" = \"$magic\"; then + # install mode needs the following variable: + notinst_deplibs='$notinst_deplibs' +else + # When we are sourced in execute mode, \$file and \$echo are already set. + if test \"\$libtool_execute_magic\" != \"$magic\"; then + echo=\"$qecho\" + file=\"\$0\" + # Make sure echo works. + if test \"X\$1\" = X--no-reexec; then + # Discard the --no-reexec flag, and continue. + shift + elif test \"X\`(\$echo '\t') 2>/dev/null\`\" = 'X\t'; then + # Yippee, \$echo works! + : + else + # Restart under the correct shell, and then maybe \$echo will work. + exec $SHELL \"\$0\" --no-reexec \${1+\"\$@\"} + fi + fi\ +" + $echo >> $output "\ + + # Find the directory that this script lives in. + thisdir=\`\$echo \"X\$file\" | \$Xsed -e 's%/[^/]*$%%'\` + test \"x\$thisdir\" = \"x\$file\" && thisdir=. + + # Follow symbolic links until we get to the real thisdir. + file=\`ls -ld \"\$file\" | ${SED} -n 's/.*-> //p'\` + while test -n \"\$file\"; do + destdir=\`\$echo \"X\$file\" | \$Xsed -e 's%/[^/]*\$%%'\` + + # If there was a directory component, then change thisdir. + if test \"x\$destdir\" != \"x\$file\"; then + case \"\$destdir\" in + [\\\\/]* | [A-Za-z]:[\\\\/]*) thisdir=\"\$destdir\" ;; + *) thisdir=\"\$thisdir/\$destdir\" ;; + esac + fi + + file=\`\$echo \"X\$file\" | \$Xsed -e 's%^.*/%%'\` + file=\`ls -ld \"\$thisdir/\$file\" | ${SED} -n 's/.*-> //p'\` + done + + # Try to get the absolute directory name. + absdir=\`cd \"\$thisdir\" && pwd\` + test -n \"\$absdir\" && thisdir=\"\$absdir\" +" + + if test "$fast_install" = yes; then + $echo >> $output "\ + program=lt-'$outputname'$exeext + progdir=\"\$thisdir/$objdir\" + + if test ! -f \"\$progdir/\$program\" || \\ + { file=\`ls -1dt \"\$progdir/\$program\" \"\$progdir/../\$program\" 2>/dev/null | ${SED} 1q\`; \\ + test \"X\$file\" != \"X\$progdir/\$program\"; }; then + + file=\"\$\$-\$program\" + + if test ! -d \"\$progdir\"; then + $mkdir \"\$progdir\" + else + $rm \"\$progdir/\$file\" + fi" + + $echo >> $output "\ + + # relink executable if necessary + if test -n \"\$relink_command\"; then + if relink_command_output=\`eval \$relink_command 2>&1\`; then : + else + $echo \"\$relink_command_output\" >&2 + $rm \"\$progdir/\$file\" + exit $EXIT_FAILURE + fi + fi + + $mv \"\$progdir/\$file\" \"\$progdir/\$program\" 2>/dev/null || + { $rm \"\$progdir/\$program\"; + $mv \"\$progdir/\$file\" \"\$progdir/\$program\"; } + $rm \"\$progdir/\$file\" + fi" + else + $echo >> $output "\ + program='$outputname' + progdir=\"\$thisdir/$objdir\" +" + fi + + $echo >> $output "\ + + if test -f \"\$progdir/\$program\"; then" + + # Export our shlibpath_var if we have one. + if test "$shlibpath_overrides_runpath" = yes && test -n "$shlibpath_var" && test -n "$temp_rpath"; then + $echo >> $output "\ + # Add our own library path to $shlibpath_var + $shlibpath_var=\"$temp_rpath\$$shlibpath_var\" + + # Some systems cannot cope with colon-terminated $shlibpath_var + # The second colon is a workaround for a bug in BeOS R4 sed + $shlibpath_var=\`\$echo \"X\$$shlibpath_var\" | \$Xsed -e 's/::*\$//'\` + + export $shlibpath_var +" + fi + + # fixup the dll searchpath if we need to. + if test -n "$dllsearchpath"; then + $echo >> $output "\ + # Add the dll search path components to the executable PATH + PATH=$dllsearchpath:\$PATH +" + fi + + $echo >> $output "\ + if test \"\$libtool_execute_magic\" != \"$magic\"; then + # Run the actual program with our arguments. +" + case $host in + # Backslashes separate directories on plain windows + *-*-mingw | *-*-os2*) + $echo >> $output "\ + exec \"\$progdir\\\\\$program\" \${1+\"\$@\"} +" + ;; + + *) + $echo >> $output "\ + exec \"\$progdir/\$program\" \${1+\"\$@\"} +" + ;; + esac + $echo >> $output "\ + \$echo \"\$0: cannot exec \$program \$*\" + exit $EXIT_FAILURE + fi + else + # The program doesn't exist. + \$echo \"\$0: error: \\\`\$progdir/\$program' does not exist\" 1>&2 + \$echo \"This script is just a wrapper for \$program.\" 1>&2 + $echo \"See the $PACKAGE documentation for more information.\" 1>&2 + exit $EXIT_FAILURE + fi +fi\ +" + chmod +x $output + fi + exit $EXIT_SUCCESS + ;; + esac + + # See if we need to build an old-fashioned archive. + for oldlib in $oldlibs; do + + if test "$build_libtool_libs" = convenience; then + oldobjs="$libobjs_save" + addlibs="$convenience" + build_libtool_libs=no + else + if test "$build_libtool_libs" = module; then + oldobjs="$libobjs_save" + build_libtool_libs=no + else + oldobjs="$old_deplibs $non_pic_objects" + fi + addlibs="$old_convenience" + fi + + if test -n "$addlibs"; then + gentop="$output_objdir/${outputname}x" + generated="$generated $gentop" + + func_extract_archives $gentop $addlibs + oldobjs="$oldobjs $func_extract_archives_result" + fi + + # Do each command in the archive commands. + if test -n "$old_archive_from_new_cmds" && test "$build_libtool_libs" = yes; then + cmds=$old_archive_from_new_cmds + else + # POSIX demands no paths to be encoded in archives. We have + # to avoid creating archives with duplicate basenames if we + # might have to extract them afterwards, e.g., when creating a + # static archive out of a convenience library, or when linking + # the entirety of a libtool archive into another (currently + # not supported by libtool). + if (for obj in $oldobjs + do + $echo "X$obj" | $Xsed -e 's%^.*/%%' + done | sort | sort -uc >/dev/null 2>&1); then + : + else + $echo "copying selected object files to avoid basename conflicts..." + + if test -z "$gentop"; then + gentop="$output_objdir/${outputname}x" + generated="$generated $gentop" + + $show "${rm}r $gentop" + $run ${rm}r "$gentop" + $show "$mkdir $gentop" + $run $mkdir "$gentop" + exit_status=$? + if test "$exit_status" -ne 0 && test ! -d "$gentop"; then + exit $exit_status + fi + fi + + save_oldobjs=$oldobjs + oldobjs= + counter=1 + for obj in $save_oldobjs + do + objbase=`$echo "X$obj" | $Xsed -e 's%^.*/%%'` + case " $oldobjs " in + " ") oldobjs=$obj ;; + *[\ /]"$objbase "*) + while :; do + # Make sure we don't pick an alternate name that also + # overlaps. + newobj=lt$counter-$objbase + counter=`expr $counter + 1` + case " $oldobjs " in + *[\ /]"$newobj "*) ;; + *) if test ! -f "$gentop/$newobj"; then break; fi ;; + esac + done + $show "ln $obj $gentop/$newobj || cp $obj $gentop/$newobj" + $run ln "$obj" "$gentop/$newobj" || + $run cp "$obj" "$gentop/$newobj" + oldobjs="$oldobjs $gentop/$newobj" + ;; + *) oldobjs="$oldobjs $obj" ;; + esac + done + fi + + eval cmds=\"$old_archive_cmds\" + + if len=`expr "X$cmds" : ".*"` && + test "$len" -le "$max_cmd_len" || test "$max_cmd_len" -le -1; then + cmds=$old_archive_cmds + else + # the command line is too long to link in one step, link in parts + $echo "using piecewise archive linking..." + save_RANLIB=$RANLIB + RANLIB=: + objlist= + concat_cmds= + save_oldobjs=$oldobjs + + # Is there a better way of finding the last object in the list? + for obj in $save_oldobjs + do + last_oldobj=$obj + done + for obj in $save_oldobjs + do + oldobjs="$objlist $obj" + objlist="$objlist $obj" + eval test_cmds=\"$old_archive_cmds\" + if len=`expr "X$test_cmds" : ".*" 2>/dev/null` && + test "$len" -le "$max_cmd_len"; then + : + else + # the above command should be used before it gets too long + oldobjs=$objlist + if test "$obj" = "$last_oldobj" ; then + RANLIB=$save_RANLIB + fi + test -z "$concat_cmds" || concat_cmds=$concat_cmds~ + eval concat_cmds=\"\${concat_cmds}$old_archive_cmds\" + objlist= + fi + done + RANLIB=$save_RANLIB + oldobjs=$objlist + if test "X$oldobjs" = "X" ; then + eval cmds=\"\$concat_cmds\" + else + eval cmds=\"\$concat_cmds~\$old_archive_cmds\" + fi + fi + fi + save_ifs="$IFS"; IFS='~' + for cmd in $cmds; do + eval cmd=\"$cmd\" + IFS="$save_ifs" + $show "$cmd" + $run eval "$cmd" || exit $? + done + IFS="$save_ifs" + done + + if test -n "$generated"; then + $show "${rm}r$generated" + $run ${rm}r$generated + fi + + # Now create the libtool archive. + case $output in + *.la) + old_library= + test "$build_old_libs" = yes && old_library="$libname.$libext" + $show "creating $output" + + # Preserve any variables that may affect compiler behavior + for var in $variables_saved_for_relink; do + if eval test -z \"\${$var+set}\"; then + relink_command="{ test -z \"\${$var+set}\" || unset $var || { $var=; export $var; }; }; $relink_command" + elif eval var_value=\$$var; test -z "$var_value"; then + relink_command="$var=; export $var; $relink_command" + else + var_value=`$echo "X$var_value" | $Xsed -e "$sed_quote_subst"` + relink_command="$var=\"$var_value\"; export $var; $relink_command" + fi + done + # Quote the link command for shipping. + relink_command="(cd `pwd`; $SHELL $progpath $preserve_args --mode=relink $libtool_args @inst_prefix_dir@)" + relink_command=`$echo "X$relink_command" | $SP2NL | $Xsed -e "$sed_quote_subst" | $NL2SP` + if test "$hardcode_automatic" = yes ; then + relink_command= + fi + + + # Only create the output if not a dry run. + if test -z "$run"; then + for installed in no yes; do + if test "$installed" = yes; then + if test -z "$install_libdir"; then + break + fi + output="$output_objdir/$outputname"i + # Replace all uninstalled libtool libraries with the installed ones + newdependency_libs= + for deplib in $dependency_libs; do + case $deplib in + *.la) + name=`$echo "X$deplib" | $Xsed -e 's%^.*/%%'` + eval libdir=`${SED} -n -e 's/^libdir=\(.*\)$/\1/p' $deplib` + if test -z "$libdir"; then + $echo "$modename: \`$deplib' is not a valid libtool archive" 1>&2 + exit $EXIT_FAILURE + fi + newdependency_libs="$newdependency_libs $libdir/$name" + ;; + *) newdependency_libs="$newdependency_libs $deplib" ;; + esac + done + dependency_libs="$newdependency_libs" + newdlfiles= + for lib in $dlfiles; do + name=`$echo "X$lib" | $Xsed -e 's%^.*/%%'` + eval libdir=`${SED} -n -e 's/^libdir=\(.*\)$/\1/p' $lib` + if test -z "$libdir"; then + $echo "$modename: \`$lib' is not a valid libtool archive" 1>&2 + exit $EXIT_FAILURE + fi + newdlfiles="$newdlfiles $libdir/$name" + done + dlfiles="$newdlfiles" + newdlprefiles= + for lib in $dlprefiles; do + name=`$echo "X$lib" | $Xsed -e 's%^.*/%%'` + eval libdir=`${SED} -n -e 's/^libdir=\(.*\)$/\1/p' $lib` + if test -z "$libdir"; then + $echo "$modename: \`$lib' is not a valid libtool archive" 1>&2 + exit $EXIT_FAILURE + fi + newdlprefiles="$newdlprefiles $libdir/$name" + done + dlprefiles="$newdlprefiles" + else + newdlfiles= + for lib in $dlfiles; do + case $lib in + [\\/]* | [A-Za-z]:[\\/]*) abs="$lib" ;; + *) abs=`pwd`"/$lib" ;; + esac + newdlfiles="$newdlfiles $abs" + done + dlfiles="$newdlfiles" + newdlprefiles= + for lib in $dlprefiles; do + case $lib in + [\\/]* | [A-Za-z]:[\\/]*) abs="$lib" ;; + *) abs=`pwd`"/$lib" ;; + esac + newdlprefiles="$newdlprefiles $abs" + done + dlprefiles="$newdlprefiles" + fi + $rm $output + # place dlname in correct position for cygwin + tdlname=$dlname + case $host,$output,$installed,$module,$dlname in + *cygwin*,*lai,yes,no,*.dll | *mingw*,*lai,yes,no,*.dll) tdlname=../bin/$dlname ;; + esac + $echo > $output "\ +# $outputname - a libtool library file +# Generated by $PROGRAM - GNU $PACKAGE $VERSION$TIMESTAMP +# +# Please DO NOT delete this file! +# It is necessary for linking the library. + +# The name that we can dlopen(3). +dlname='$tdlname' + +# Names of this library. +library_names='$library_names' + +# The name of the static archive. +old_library='$old_library' + +# Libraries that this one depends upon. +dependency_libs='$dependency_libs' + +# Version information for $libname. +current=$current +age=$age +revision=$revision + +# Is this an already installed library? +installed=$installed + +# Should we warn about portability when linking against -modules? +shouldnotlink=$module + +# Files to dlopen/dlpreopen +dlopen='$dlfiles' +dlpreopen='$dlprefiles' + +# Directory that this library needs to be installed in: +libdir='$install_libdir'" + if test "$installed" = no && test "$need_relink" = yes; then + $echo >> $output "\ +relink_command=\"$relink_command\"" + fi + done + fi + + # Do a symbolic link so that the libtool archive can be found in + # LD_LIBRARY_PATH before the program is installed. + $show "(cd $output_objdir && $rm $outputname && $LN_S ../$outputname $outputname)" + $run eval '(cd $output_objdir && $rm $outputname && $LN_S ../$outputname $outputname)' || exit $? + ;; + esac + exit $EXIT_SUCCESS + ;; + + # libtool install mode + install) + modename="$modename: install" + + # There may be an optional sh(1) argument at the beginning of + # install_prog (especially on Windows NT). + if test "$nonopt" = "$SHELL" || test "$nonopt" = /bin/sh || + # Allow the use of GNU shtool's install command. + $echo "X$nonopt" | grep shtool > /dev/null; then + # Aesthetically quote it. + arg=`$echo "X$nonopt" | $Xsed -e "$sed_quote_subst"` + case $arg in + *[\[\~\#\^\&\*\(\)\{\}\|\;\<\>\?\'\ \ ]*|*]*|"") + arg="\"$arg\"" + ;; + esac + install_prog="$arg " + arg="$1" + shift + else + install_prog= + arg=$nonopt + fi + + # The real first argument should be the name of the installation program. + # Aesthetically quote it. + arg=`$echo "X$arg" | $Xsed -e "$sed_quote_subst"` + case $arg in + *[\[\~\#\^\&\*\(\)\{\}\|\;\<\>\?\'\ \ ]*|*]*|"") + arg="\"$arg\"" + ;; + esac + install_prog="$install_prog$arg" + + # We need to accept at least all the BSD install flags. + dest= + files= + opts= + prev= + install_type= + isdir=no + stripme= + for arg + do + if test -n "$dest"; then + files="$files $dest" + dest=$arg + continue + fi + + case $arg in + -d) isdir=yes ;; + -f) + case " $install_prog " in + *[\\\ /]cp\ *) ;; + *) prev=$arg ;; + esac + ;; + -g | -m | -o) prev=$arg ;; + -s) + stripme=" -s" + continue + ;; + -*) + ;; + *) + # If the previous option needed an argument, then skip it. + if test -n "$prev"; then + prev= + else + dest=$arg + continue + fi + ;; + esac + + # Aesthetically quote the argument. + arg=`$echo "X$arg" | $Xsed -e "$sed_quote_subst"` + case $arg in + *[\[\~\#\^\&\*\(\)\{\}\|\;\<\>\?\'\ \ ]*|*]*|"") + arg="\"$arg\"" + ;; + esac + install_prog="$install_prog $arg" + done + + if test -z "$install_prog"; then + $echo "$modename: you must specify an install program" 1>&2 + $echo "$help" 1>&2 + exit $EXIT_FAILURE + fi + + if test -n "$prev"; then + $echo "$modename: the \`$prev' option requires an argument" 1>&2 + $echo "$help" 1>&2 + exit $EXIT_FAILURE + fi + + if test -z "$files"; then + if test -z "$dest"; then + $echo "$modename: no file or destination specified" 1>&2 + else + $echo "$modename: you must specify a destination" 1>&2 + fi + $echo "$help" 1>&2 + exit $EXIT_FAILURE + fi + + # Strip any trailing slash from the destination. + dest=`$echo "X$dest" | $Xsed -e 's%/$%%'` + + # Check to see that the destination is a directory. + test -d "$dest" && isdir=yes + if test "$isdir" = yes; then + destdir="$dest" + destname= + else + destdir=`$echo "X$dest" | $Xsed -e 's%/[^/]*$%%'` + test "X$destdir" = "X$dest" && destdir=. + destname=`$echo "X$dest" | $Xsed -e 's%^.*/%%'` + + # Not a directory, so check to see that there is only one file specified. + set dummy $files + if test "$#" -gt 2; then + $echo "$modename: \`$dest' is not a directory" 1>&2 + $echo "$help" 1>&2 + exit $EXIT_FAILURE + fi + fi + case $destdir in + [\\/]* | [A-Za-z]:[\\/]*) ;; + *) + for file in $files; do + case $file in + *.lo) ;; + *) + $echo "$modename: \`$destdir' must be an absolute directory name" 1>&2 + $echo "$help" 1>&2 + exit $EXIT_FAILURE + ;; + esac + done + ;; + esac + + # This variable tells wrapper scripts just to set variables rather + # than running their programs. + libtool_install_magic="$magic" + + staticlibs= + future_libdirs= + current_libdirs= + for file in $files; do + + # Do each installation. + case $file in + *.$libext) + # Do the static libraries later. + staticlibs="$staticlibs $file" + ;; + + *.la) + # Check to see that this really is a libtool archive. + if (${SED} -e '2q' $file | grep "^# Generated by .*$PACKAGE") >/dev/null 2>&1; then : + else + $echo "$modename: \`$file' is not a valid libtool archive" 1>&2 + $echo "$help" 1>&2 + exit $EXIT_FAILURE + fi + + library_names= + old_library= + relink_command= + # If there is no directory component, then add one. + case $file in + */* | *\\*) . $file ;; + *) . ./$file ;; + esac + + # Add the libdir to current_libdirs if it is the destination. + if test "X$destdir" = "X$libdir"; then + case "$current_libdirs " in + *" $libdir "*) ;; + *) current_libdirs="$current_libdirs $libdir" ;; + esac + else + # Note the libdir as a future libdir. + case "$future_libdirs " in + *" $libdir "*) ;; + *) future_libdirs="$future_libdirs $libdir" ;; + esac + fi + + dir=`$echo "X$file" | $Xsed -e 's%/[^/]*$%%'`/ + test "X$dir" = "X$file/" && dir= + dir="$dir$objdir" + + if test -n "$relink_command"; then + # Determine the prefix the user has applied to our future dir. + inst_prefix_dir=`$echo "$destdir" | $SED "s%$libdir\$%%"` + + # Don't allow the user to place us outside of our expected + # location b/c this prevents finding dependent libraries that + # are installed to the same prefix. + # At present, this check doesn't affect windows .dll's that + # are installed into $libdir/../bin (currently, that works fine) + # but it's something to keep an eye on. + if test "$inst_prefix_dir" = "$destdir"; then + $echo "$modename: error: cannot install \`$file' to a directory not ending in $libdir" 1>&2 + exit $EXIT_FAILURE + fi + + if test -n "$inst_prefix_dir"; then + # Stick the inst_prefix_dir data into the link command. + relink_command=`$echo "$relink_command" | $SP2NL | $SED "s%@inst_prefix_dir@%-inst-prefix-dir $inst_prefix_dir%" | $NL2SP` + else + relink_command=`$echo "$relink_command" | $SP2NL | $SED "s%@inst_prefix_dir@%%" | $NL2SP` + fi + + $echo "$modename: warning: relinking \`$file'" 1>&2 + $show "$relink_command" + if $run eval "$relink_command"; then : + else + $echo "$modename: error: relink \`$file' with the above command before installing it" 1>&2 + exit $EXIT_FAILURE + fi + fi + + # See the names of the shared library. + set dummy $library_names + if test -n "$2"; then + realname="$2" + shift + shift + + srcname="$realname" + test -n "$relink_command" && srcname="$realname"T + + # Install the shared library and build the symlinks. + $show "$install_prog $dir/$srcname $destdir/$realname" + $run eval "$install_prog $dir/$srcname $destdir/$realname" || exit $? + if test -n "$stripme" && test -n "$striplib"; then + $show "$striplib $destdir/$realname" + $run eval "$striplib $destdir/$realname" || exit $? + fi + + if test "$#" -gt 0; then + # Delete the old symlinks, and create new ones. + # Try `ln -sf' first, because the `ln' binary might depend on + # the symlink we replace! Solaris /bin/ln does not understand -f, + # so we also need to try rm && ln -s. + for linkname + do + if test "$linkname" != "$realname"; then + $show "(cd $destdir && { $LN_S -f $realname $linkname || { $rm $linkname && $LN_S $realname $linkname; }; })" + $run eval "(cd $destdir && { $LN_S -f $realname $linkname || { $rm $linkname && $LN_S $realname $linkname; }; })" + fi + done + fi + + # Do each command in the postinstall commands. + lib="$destdir/$realname" + cmds=$postinstall_cmds + save_ifs="$IFS"; IFS='~' + for cmd in $cmds; do + IFS="$save_ifs" + eval cmd=\"$cmd\" + $show "$cmd" + $run eval "$cmd" || { + lt_exit=$? + + # Restore the uninstalled library and exit + if test "$mode" = relink; then + $run eval '(cd $output_objdir && $rm ${realname}T && $mv ${realname}U $realname)' + fi + + exit $lt_exit + } + done + IFS="$save_ifs" + fi + + # Install the pseudo-library for information purposes. + name=`$echo "X$file" | $Xsed -e 's%^.*/%%'` + instname="$dir/$name"i + $show "$install_prog $instname $destdir/$name" + $run eval "$install_prog $instname $destdir/$name" || exit $? + + # Maybe install the static library, too. + test -n "$old_library" && staticlibs="$staticlibs $dir/$old_library" + ;; + + *.lo) + # Install (i.e. copy) a libtool object. + + # Figure out destination file name, if it wasn't already specified. + if test -n "$destname"; then + destfile="$destdir/$destname" + else + destfile=`$echo "X$file" | $Xsed -e 's%^.*/%%'` + destfile="$destdir/$destfile" + fi + + # Deduce the name of the destination old-style object file. + case $destfile in + *.lo) + staticdest=`$echo "X$destfile" | $Xsed -e "$lo2o"` + ;; + *.$objext) + staticdest="$destfile" + destfile= + ;; + *) + $echo "$modename: cannot copy a libtool object to \`$destfile'" 1>&2 + $echo "$help" 1>&2 + exit $EXIT_FAILURE + ;; + esac + + # Install the libtool object if requested. + if test -n "$destfile"; then + $show "$install_prog $file $destfile" + $run eval "$install_prog $file $destfile" || exit $? + fi + + # Install the old object if enabled. + if test "$build_old_libs" = yes; then + # Deduce the name of the old-style object file. + staticobj=`$echo "X$file" | $Xsed -e "$lo2o"` + + $show "$install_prog $staticobj $staticdest" + $run eval "$install_prog \$staticobj \$staticdest" || exit $? + fi + exit $EXIT_SUCCESS + ;; + + *) + # Figure out destination file name, if it wasn't already specified. + if test -n "$destname"; then + destfile="$destdir/$destname" + else + destfile=`$echo "X$file" | $Xsed -e 's%^.*/%%'` + destfile="$destdir/$destfile" + fi + + # If the file is missing, and there is a .exe on the end, strip it + # because it is most likely a libtool script we actually want to + # install + stripped_ext="" + case $file in + *.exe) + if test ! -f "$file"; then + file=`$echo $file|${SED} 's,.exe$,,'` + stripped_ext=".exe" + fi + ;; + esac + + # Do a test to see if this is really a libtool program. + case $host in + *cygwin*|*mingw*) + wrapper=`$echo $file | ${SED} -e 's,.exe$,,'` + ;; + *) + wrapper=$file + ;; + esac + if (${SED} -e '4q' $wrapper | grep "^# Generated by .*$PACKAGE")>/dev/null 2>&1; then + notinst_deplibs= + relink_command= + + # Note that it is not necessary on cygwin/mingw to append a dot to + # foo even if both foo and FILE.exe exist: automatic-append-.exe + # behavior happens only for exec(3), not for open(2)! Also, sourcing + # `FILE.' does not work on cygwin managed mounts. + # + # If there is no directory component, then add one. + case $wrapper in + */* | *\\*) . ${wrapper} ;; + *) . ./${wrapper} ;; + esac + + # Check the variables that should have been set. + if test -z "$notinst_deplibs"; then + $echo "$modename: invalid libtool wrapper script \`$wrapper'" 1>&2 + exit $EXIT_FAILURE + fi + + finalize=yes + for lib in $notinst_deplibs; do + # Check to see that each library is installed. + libdir= + if test -f "$lib"; then + # If there is no directory component, then add one. + case $lib in + */* | *\\*) . $lib ;; + *) . ./$lib ;; + esac + fi + libfile="$libdir/"`$echo "X$lib" | $Xsed -e 's%^.*/%%g'` ### testsuite: skip nested quoting test + if test -n "$libdir" && test ! -f "$libfile"; then + $echo "$modename: warning: \`$lib' has not been installed in \`$libdir'" 1>&2 + finalize=no + fi + done + + relink_command= + # Note that it is not necessary on cygwin/mingw to append a dot to + # foo even if both foo and FILE.exe exist: automatic-append-.exe + # behavior happens only for exec(3), not for open(2)! Also, sourcing + # `FILE.' does not work on cygwin managed mounts. + # + # If there is no directory component, then add one. + case $wrapper in + */* | *\\*) . ${wrapper} ;; + *) . ./${wrapper} ;; + esac + + outputname= + if test "$fast_install" = no && test -n "$relink_command"; then + if test "$finalize" = yes && test -z "$run"; then + tmpdir=`func_mktempdir` + file=`$echo "X$file$stripped_ext" | $Xsed -e 's%^.*/%%'` + outputname="$tmpdir/$file" + # Replace the output file specification. + relink_command=`$echo "X$relink_command" | $SP2NL | $Xsed -e 's%@OUTPUT@%'"$outputname"'%g' | $NL2SP` + + $show "$relink_command" + if $run eval "$relink_command"; then : + else + $echo "$modename: error: relink \`$file' with the above command before installing it" 1>&2 + ${rm}r "$tmpdir" + continue + fi + file="$outputname" + else + $echo "$modename: warning: cannot relink \`$file'" 1>&2 + fi + else + # Install the binary that we compiled earlier. + file=`$echo "X$file$stripped_ext" | $Xsed -e "s%\([^/]*\)$%$objdir/\1%"` + fi + fi + + # remove .exe since cygwin /usr/bin/install will append another + # one anyway + case $install_prog,$host in + */usr/bin/install*,*cygwin*) + case $file:$destfile in + *.exe:*.exe) + # this is ok + ;; + *.exe:*) + destfile=$destfile.exe + ;; + *:*.exe) + destfile=`$echo $destfile | ${SED} -e 's,.exe$,,'` + ;; + esac + ;; + esac + $show "$install_prog$stripme $file $destfile" + $run eval "$install_prog\$stripme \$file \$destfile" || exit $? + test -n "$outputname" && ${rm}r "$tmpdir" + ;; + esac + done + + for file in $staticlibs; do + name=`$echo "X$file" | $Xsed -e 's%^.*/%%'` + + # Set up the ranlib parameters. + oldlib="$destdir/$name" + + $show "$install_prog $file $oldlib" + $run eval "$install_prog \$file \$oldlib" || exit $? + + if test -n "$stripme" && test -n "$old_striplib"; then + $show "$old_striplib $oldlib" + $run eval "$old_striplib $oldlib" || exit $? + fi + + # Do each command in the postinstall commands. + cmds=$old_postinstall_cmds + save_ifs="$IFS"; IFS='~' + for cmd in $cmds; do + IFS="$save_ifs" + eval cmd=\"$cmd\" + $show "$cmd" + $run eval "$cmd" || exit $? + done + IFS="$save_ifs" + done + + if test -n "$future_libdirs"; then + $echo "$modename: warning: remember to run \`$progname --finish$future_libdirs'" 1>&2 + fi + + if test -n "$current_libdirs"; then + # Maybe just do a dry run. + test -n "$run" && current_libdirs=" -n$current_libdirs" + exec_cmd='$SHELL $progpath $preserve_args --finish$current_libdirs' + else + exit $EXIT_SUCCESS + fi + ;; + + # libtool finish mode + finish) + modename="$modename: finish" + libdirs="$nonopt" + admincmds= + + if test -n "$finish_cmds$finish_eval" && test -n "$libdirs"; then + for dir + do + libdirs="$libdirs $dir" + done + + for libdir in $libdirs; do + if test -n "$finish_cmds"; then + # Do each command in the finish commands. + cmds=$finish_cmds + save_ifs="$IFS"; IFS='~' + for cmd in $cmds; do + IFS="$save_ifs" + eval cmd=\"$cmd\" + $show "$cmd" + $run eval "$cmd" || admincmds="$admincmds + $cmd" + done + IFS="$save_ifs" + fi + if test -n "$finish_eval"; then + # Do the single finish_eval. + eval cmds=\"$finish_eval\" + $run eval "$cmds" || admincmds="$admincmds + $cmds" + fi + done + fi + + # Exit here if they wanted silent mode. + test "$show" = : && exit $EXIT_SUCCESS + + $echo "X----------------------------------------------------------------------" | $Xsed + $echo "Libraries have been installed in:" + for libdir in $libdirs; do + $echo " $libdir" + done + $echo + $echo "If you ever happen to want to link against installed libraries" + $echo "in a given directory, LIBDIR, you must either use libtool, and" + $echo "specify the full pathname of the library, or use the \`-LLIBDIR'" + $echo "flag during linking and do at least one of the following:" + if test -n "$shlibpath_var"; then + $echo " - add LIBDIR to the \`$shlibpath_var' environment variable" + $echo " during execution" + fi + if test -n "$runpath_var"; then + $echo " - add LIBDIR to the \`$runpath_var' environment variable" + $echo " during linking" + fi + if test -n "$hardcode_libdir_flag_spec"; then + libdir=LIBDIR + eval flag=\"$hardcode_libdir_flag_spec\" + + $echo " - use the \`$flag' linker flag" + fi + if test -n "$admincmds"; then + $echo " - have your system administrator run these commands:$admincmds" + fi + if test -f /etc/ld.so.conf; then + $echo " - have your system administrator add LIBDIR to \`/etc/ld.so.conf'" + fi + $echo + $echo "See any operating system documentation about shared libraries for" + $echo "more information, such as the ld(1) and ld.so(8) manual pages." + $echo "X----------------------------------------------------------------------" | $Xsed + exit $EXIT_SUCCESS + ;; + + # libtool execute mode + execute) + modename="$modename: execute" + + # The first argument is the command name. + cmd="$nonopt" + if test -z "$cmd"; then + $echo "$modename: you must specify a COMMAND" 1>&2 + $echo "$help" + exit $EXIT_FAILURE + fi + + # Handle -dlopen flags immediately. + for file in $execute_dlfiles; do + if test ! -f "$file"; then + $echo "$modename: \`$file' is not a file" 1>&2 + $echo "$help" 1>&2 + exit $EXIT_FAILURE + fi + + dir= + case $file in + *.la) + # Check to see that this really is a libtool archive. + if (${SED} -e '2q' $file | grep "^# Generated by .*$PACKAGE") >/dev/null 2>&1; then : + else + $echo "$modename: \`$lib' is not a valid libtool archive" 1>&2 + $echo "$help" 1>&2 + exit $EXIT_FAILURE + fi + + # Read the libtool library. + dlname= + library_names= + + # If there is no directory component, then add one. + case $file in + */* | *\\*) . $file ;; + *) . ./$file ;; + esac + + # Skip this library if it cannot be dlopened. + if test -z "$dlname"; then + # Warn if it was a shared library. + test -n "$library_names" && $echo "$modename: warning: \`$file' was not linked with \`-export-dynamic'" + continue + fi + + dir=`$echo "X$file" | $Xsed -e 's%/[^/]*$%%'` + test "X$dir" = "X$file" && dir=. + + if test -f "$dir/$objdir/$dlname"; then + dir="$dir/$objdir" + else + $echo "$modename: cannot find \`$dlname' in \`$dir' or \`$dir/$objdir'" 1>&2 + exit $EXIT_FAILURE + fi + ;; + + *.lo) + # Just add the directory containing the .lo file. + dir=`$echo "X$file" | $Xsed -e 's%/[^/]*$%%'` + test "X$dir" = "X$file" && dir=. + ;; + + *) + $echo "$modename: warning \`-dlopen' is ignored for non-libtool libraries and objects" 1>&2 + continue + ;; + esac + + # Get the absolute pathname. + absdir=`cd "$dir" && pwd` + test -n "$absdir" && dir="$absdir" + + # Now add the directory to shlibpath_var. + if eval "test -z \"\$$shlibpath_var\""; then + eval "$shlibpath_var=\"\$dir\"" + else + eval "$shlibpath_var=\"\$dir:\$$shlibpath_var\"" + fi + done + + # This variable tells wrapper scripts just to set shlibpath_var + # rather than running their programs. + libtool_execute_magic="$magic" + + # Check if any of the arguments is a wrapper script. + args= + for file + do + case $file in + -*) ;; + *) + # Do a test to see if this is really a libtool program. + if (${SED} -e '4q' $file | grep "^# Generated by .*$PACKAGE") >/dev/null 2>&1; then + # If there is no directory component, then add one. + case $file in + */* | *\\*) . $file ;; + *) . ./$file ;; + esac + + # Transform arg to wrapped name. + file="$progdir/$program" + fi + ;; + esac + # Quote arguments (to preserve shell metacharacters). + file=`$echo "X$file" | $Xsed -e "$sed_quote_subst"` + args="$args \"$file\"" + done + + if test -z "$run"; then + if test -n "$shlibpath_var"; then + # Export the shlibpath_var. + eval "export $shlibpath_var" + fi + + # Restore saved environment variables + for lt_var in LANG LC_ALL LC_CTYPE LC_COLLATE LC_MESSAGES + do + eval "if test \"\${save_$lt_var+set}\" = set; then + $lt_var=\$save_$lt_var; export $lt_var + else + $lt_unset $lt_var + fi" + done + + + # Now prepare to actually exec the command. + exec_cmd="\$cmd$args" + else + # Display what would be done. + if test -n "$shlibpath_var"; then + eval "\$echo \"\$shlibpath_var=\$$shlibpath_var\"" + $echo "export $shlibpath_var" + fi + $echo "$cmd$args" + exit $EXIT_SUCCESS + fi + ;; + + # libtool clean and uninstall mode + clean | uninstall) + modename="$modename: $mode" + rm="$nonopt" + files= + rmforce= + exit_status=0 + + # This variable tells wrapper scripts just to set variables rather + # than running their programs. + libtool_install_magic="$magic" + + for arg + do + case $arg in + -f) rm="$rm $arg"; rmforce=yes ;; + -*) rm="$rm $arg" ;; + *) files="$files $arg" ;; + esac + done + + if test -z "$rm"; then + $echo "$modename: you must specify an RM program" 1>&2 + $echo "$help" 1>&2 + exit $EXIT_FAILURE + fi + + rmdirs= + + origobjdir="$objdir" + for file in $files; do + dir=`$echo "X$file" | $Xsed -e 's%/[^/]*$%%'` + if test "X$dir" = "X$file"; then + dir=. + objdir="$origobjdir" + else + objdir="$dir/$origobjdir" + fi + name=`$echo "X$file" | $Xsed -e 's%^.*/%%'` + test "$mode" = uninstall && objdir="$dir" + + # Remember objdir for removal later, being careful to avoid duplicates + if test "$mode" = clean; then + case " $rmdirs " in + *" $objdir "*) ;; + *) rmdirs="$rmdirs $objdir" ;; + esac + fi + + # Don't error if the file doesn't exist and rm -f was used. + if (test -L "$file") >/dev/null 2>&1 \ + || (test -h "$file") >/dev/null 2>&1 \ + || test -f "$file"; then + : + elif test -d "$file"; then + exit_status=1 + continue + elif test "$rmforce" = yes; then + continue + fi + + rmfiles="$file" + + case $name in + *.la) + # Possibly a libtool archive, so verify it. + if (${SED} -e '2q' $file | grep "^# Generated by .*$PACKAGE") >/dev/null 2>&1; then + . $dir/$name + + # Delete the libtool libraries and symlinks. + for n in $library_names; do + rmfiles="$rmfiles $objdir/$n" + done + test -n "$old_library" && rmfiles="$rmfiles $objdir/$old_library" + + case "$mode" in + clean) + case " $library_names " in + # " " in the beginning catches empty $dlname + *" $dlname "*) ;; + *) rmfiles="$rmfiles $objdir/$dlname" ;; + esac + test -n "$libdir" && rmfiles="$rmfiles $objdir/$name $objdir/${name}i" + ;; + uninstall) + if test -n "$library_names"; then + # Do each command in the postuninstall commands. + cmds=$postuninstall_cmds + save_ifs="$IFS"; IFS='~' + for cmd in $cmds; do + IFS="$save_ifs" + eval cmd=\"$cmd\" + $show "$cmd" + $run eval "$cmd" + if test "$?" -ne 0 && test "$rmforce" != yes; then + exit_status=1 + fi + done + IFS="$save_ifs" + fi + + if test -n "$old_library"; then + # Do each command in the old_postuninstall commands. + cmds=$old_postuninstall_cmds + save_ifs="$IFS"; IFS='~' + for cmd in $cmds; do + IFS="$save_ifs" + eval cmd=\"$cmd\" + $show "$cmd" + $run eval "$cmd" + if test "$?" -ne 0 && test "$rmforce" != yes; then + exit_status=1 + fi + done + IFS="$save_ifs" + fi + # FIXME: should reinstall the best remaining shared library. + ;; + esac + fi + ;; + + *.lo) + # Possibly a libtool object, so verify it. + if (${SED} -e '2q' $file | grep "^# Generated by .*$PACKAGE") >/dev/null 2>&1; then + + # Read the .lo file + . $dir/$name + + # Add PIC object to the list of files to remove. + if test -n "$pic_object" \ + && test "$pic_object" != none; then + rmfiles="$rmfiles $dir/$pic_object" + fi + + # Add non-PIC object to the list of files to remove. + if test -n "$non_pic_object" \ + && test "$non_pic_object" != none; then + rmfiles="$rmfiles $dir/$non_pic_object" + fi + fi + ;; + + *) + if test "$mode" = clean ; then + noexename=$name + case $file in + *.exe) + file=`$echo $file|${SED} 's,.exe$,,'` + noexename=`$echo $name|${SED} 's,.exe$,,'` + # $file with .exe has already been added to rmfiles, + # add $file without .exe + rmfiles="$rmfiles $file" + ;; + esac + # Do a test to see if this is a libtool program. + if (${SED} -e '4q' $file | grep "^# Generated by .*$PACKAGE") >/dev/null 2>&1; then + relink_command= + . $dir/$noexename + + # note $name still contains .exe if it was in $file originally + # as does the version of $file that was added into $rmfiles + rmfiles="$rmfiles $objdir/$name $objdir/${name}S.${objext}" + if test "$fast_install" = yes && test -n "$relink_command"; then + rmfiles="$rmfiles $objdir/lt-$name" + fi + if test "X$noexename" != "X$name" ; then + rmfiles="$rmfiles $objdir/lt-${noexename}.c" + fi + fi + fi + ;; + esac + $show "$rm $rmfiles" + $run $rm $rmfiles || exit_status=1 + done + objdir="$origobjdir" + + # Try to remove the ${objdir}s in the directories where we deleted files + for dir in $rmdirs; do + if test -d "$dir"; then + $show "rmdir $dir" + $run rmdir $dir >/dev/null 2>&1 + fi + done + + exit $exit_status + ;; + + "") + $echo "$modename: you must specify a MODE" 1>&2 + $echo "$generic_help" 1>&2 + exit $EXIT_FAILURE + ;; + esac + + if test -z "$exec_cmd"; then + $echo "$modename: invalid operation mode \`$mode'" 1>&2 + $echo "$generic_help" 1>&2 + exit $EXIT_FAILURE + fi +fi # test -z "$show_help" + +if test -n "$exec_cmd"; then + eval exec $exec_cmd + exit $EXIT_FAILURE +fi + +# We need to display help for each of the modes. +case $mode in +"") $echo \ +"Usage: $modename [OPTION]... [MODE-ARG]... + +Provide generalized library-building support services. + + --config show all configuration variables + --debug enable verbose shell tracing +-n, --dry-run display commands without modifying any files + --features display basic configuration information and exit + --finish same as \`--mode=finish' + --help display this help message and exit + --mode=MODE use operation mode MODE [default=inferred from MODE-ARGS] + --quiet same as \`--silent' + --silent don't print informational messages + --tag=TAG use configuration variables from tag TAG + --version print version information + +MODE must be one of the following: + + clean remove files from the build directory + compile compile a source file into a libtool object + execute automatically set library path, then run a program + finish complete the installation of libtool libraries + install install libraries or executables + link create a library or an executable + uninstall remove libraries from an installed directory + +MODE-ARGS vary depending on the MODE. Try \`$modename --help --mode=MODE' for +a more detailed description of MODE. + +Report bugs to <bug-libtool@gnu.org>." + exit $EXIT_SUCCESS + ;; + +clean) + $echo \ +"Usage: $modename [OPTION]... --mode=clean RM [RM-OPTION]... FILE... + +Remove files from the build directory. + +RM is the name of the program to use to delete files associated with each FILE +(typically \`/bin/rm'). RM-OPTIONS are options (such as \`-f') to be passed +to RM. + +If FILE is a libtool library, object or program, all the files associated +with it are deleted. Otherwise, only FILE itself is deleted using RM." + ;; + +compile) + $echo \ +"Usage: $modename [OPTION]... --mode=compile COMPILE-COMMAND... SOURCEFILE + +Compile a source file into a libtool library object. + +This mode accepts the following additional options: + + -o OUTPUT-FILE set the output file name to OUTPUT-FILE + -prefer-pic try to building PIC objects only + -prefer-non-pic try to building non-PIC objects only + -static always build a \`.o' file suitable for static linking + +COMPILE-COMMAND is a command to be used in creating a \`standard' object file +from the given SOURCEFILE. + +The output file name is determined by removing the directory component from +SOURCEFILE, then substituting the C source code suffix \`.c' with the +library object suffix, \`.lo'." + ;; + +execute) + $echo \ +"Usage: $modename [OPTION]... --mode=execute COMMAND [ARGS]... + +Automatically set library path, then run a program. + +This mode accepts the following additional options: + + -dlopen FILE add the directory containing FILE to the library path + +This mode sets the library path environment variable according to \`-dlopen' +flags. + +If any of the ARGS are libtool executable wrappers, then they are translated +into their corresponding uninstalled binary, and any of their required library +directories are added to the library path. + +Then, COMMAND is executed, with ARGS as arguments." + ;; + +finish) + $echo \ +"Usage: $modename [OPTION]... --mode=finish [LIBDIR]... + +Complete the installation of libtool libraries. + +Each LIBDIR is a directory that contains libtool libraries. + +The commands that this mode executes may require superuser privileges. Use +the \`--dry-run' option if you just want to see what would be executed." + ;; + +install) + $echo \ +"Usage: $modename [OPTION]... --mode=install INSTALL-COMMAND... + +Install executables or libraries. + +INSTALL-COMMAND is the installation command. The first component should be +either the \`install' or \`cp' program. + +The rest of the components are interpreted as arguments to that command (only +BSD-compatible install options are recognized)." + ;; + +link) + $echo \ +"Usage: $modename [OPTION]... --mode=link LINK-COMMAND... + +Link object files or libraries together to form another library, or to +create an executable program. + +LINK-COMMAND is a command using the C compiler that you would use to create +a program from several object files. + +The following components of LINK-COMMAND are treated specially: + + -all-static do not do any dynamic linking at all + -avoid-version do not add a version suffix if possible + -dlopen FILE \`-dlpreopen' FILE if it cannot be dlopened at runtime + -dlpreopen FILE link in FILE and add its symbols to lt_preloaded_symbols + -export-dynamic allow symbols from OUTPUT-FILE to be resolved with dlsym(3) + -export-symbols SYMFILE + try to export only the symbols listed in SYMFILE + -export-symbols-regex REGEX + try to export only the symbols matching REGEX + -LLIBDIR search LIBDIR for required installed libraries + -lNAME OUTPUT-FILE requires the installed library libNAME + -module build a library that can dlopened + -no-fast-install disable the fast-install mode + -no-install link a not-installable executable + -no-undefined declare that a library does not refer to external symbols + -o OUTPUT-FILE create OUTPUT-FILE from the specified objects + -objectlist FILE Use a list of object files found in FILE to specify objects + -precious-files-regex REGEX + don't remove output files matching REGEX + -release RELEASE specify package release information + -rpath LIBDIR the created library will eventually be installed in LIBDIR + -R[ ]LIBDIR add LIBDIR to the runtime path of programs and libraries + -static do not do any dynamic linking of uninstalled libtool libraries + -static-libtool-libs + do not do any dynamic linking of libtool libraries + -version-info CURRENT[:REVISION[:AGE]] + specify library version info [each variable defaults to 0] + +All other options (arguments beginning with \`-') are ignored. + +Every other argument is treated as a filename. Files ending in \`.la' are +treated as uninstalled libtool libraries, other files are standard or library +object files. + +If the OUTPUT-FILE ends in \`.la', then a libtool library is created, +only library objects (\`.lo' files) may be specified, and \`-rpath' is +required, except when creating a convenience library. + +If OUTPUT-FILE ends in \`.a' or \`.lib', then a standard library is created +using \`ar' and \`ranlib', or on Windows using \`lib'. + +If OUTPUT-FILE ends in \`.lo' or \`.${objext}', then a reloadable object file +is created, otherwise an executable program is created." + ;; + +uninstall) + $echo \ +"Usage: $modename [OPTION]... --mode=uninstall RM [RM-OPTION]... FILE... + +Remove libraries from an installation directory. + +RM is the name of the program to use to delete files associated with each FILE +(typically \`/bin/rm'). RM-OPTIONS are options (such as \`-f') to be passed +to RM. + +If FILE is a libtool library, all the files associated with it are deleted. +Otherwise, only FILE itself is deleted using RM." + ;; + +*) + $echo "$modename: invalid operation mode \`$mode'" 1>&2 + $echo "$help" 1>&2 + exit $EXIT_FAILURE + ;; +esac + +$echo +$echo "Try \`$modename --help' for more information about other modes." + +exit $? + +# The TAGs below are defined such that we never get into a situation +# in which we disable both kinds of libraries. Given conflicting +# choices, we go for a static library, that is the most portable, +# since we can't tell whether shared libraries were disabled because +# the user asked for that or because the platform doesn't support +# them. This is particularly important on AIX, because we don't +# support having both static and shared libraries enabled at the same +# time on that platform, so we default to a shared-only configuration. +# If a disable-shared tag is given, we'll fallback to a static-only +# configuration. But we'll never go from static-only to shared-only. + +# ### BEGIN LIBTOOL TAG CONFIG: disable-shared +disable_libs=shared +# ### END LIBTOOL TAG CONFIG: disable-shared + +# ### BEGIN LIBTOOL TAG CONFIG: disable-static +disable_libs=static +# ### END LIBTOOL TAG CONFIG: disable-static + +# Local Variables: +# mode:shell-script +# sh-indentation:2 +# End: diff --git a/AMDiS/missing b/AMDiS/missing new file mode 100755 index 0000000000000000000000000000000000000000..894e786e16c1d0d94dfc08d6b475270fe1418d6a --- /dev/null +++ b/AMDiS/missing @@ -0,0 +1,360 @@ +#! /bin/sh +# Common stub for a few missing GNU programs while installing. + +scriptversion=2005-06-08.21 + +# Copyright (C) 1996, 1997, 1999, 2000, 2002, 2003, 2004, 2005 +# Free Software Foundation, Inc. +# Originally by Fran,cois Pinard <pinard@iro.umontreal.ca>, 1996. + +# 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, 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. + +# As a special exception to the GNU General Public License, if you +# distribute this file as part of a program that contains a +# configuration script generated by Autoconf, you may include it under +# the same distribution terms that you use for the rest of that program. + +if test $# -eq 0; then + echo 1>&2 "Try \`$0 --help' for more information" + exit 1 +fi + +run=: + +# In the cases where this matters, `missing' is being run in the +# srcdir already. +if test -f configure.ac; then + configure_ac=configure.ac +else + configure_ac=configure.in +fi + +msg="missing on your system" + +case "$1" in +--run) + # Try to run requested program, and just exit if it succeeds. + run= + shift + "$@" && exit 0 + # Exit code 63 means version mismatch. This often happens + # when the user try to use an ancient version of a tool on + # a file that requires a minimum version. In this case we + # we should proceed has if the program had been absent, or + # if --run hadn't been passed. + if test $? = 63; then + run=: + msg="probably too old" + fi + ;; + + -h|--h|--he|--hel|--help) + echo "\ +$0 [OPTION]... PROGRAM [ARGUMENT]... + +Handle \`PROGRAM [ARGUMENT]...' for when PROGRAM is missing, or return an +error status if there is no known handling for PROGRAM. + +Options: + -h, --help display this help and exit + -v, --version output version information and exit + --run try to run the given command, and emulate it if it fails + +Supported PROGRAM values: + aclocal touch file \`aclocal.m4' + autoconf touch file \`configure' + autoheader touch file \`config.h.in' + automake touch all \`Makefile.in' files + bison create \`y.tab.[ch]', if possible, from existing .[ch] + flex create \`lex.yy.c', if possible, from existing .c + help2man touch the output file + lex create \`lex.yy.c', if possible, from existing .c + makeinfo touch the output file + tar try tar, gnutar, gtar, then tar without non-portable flags + yacc create \`y.tab.[ch]', if possible, from existing .[ch] + +Send bug reports to <bug-automake@gnu.org>." + exit $? + ;; + + -v|--v|--ve|--ver|--vers|--versi|--versio|--version) + echo "missing $scriptversion (GNU Automake)" + exit $? + ;; + + -*) + echo 1>&2 "$0: Unknown \`$1' option" + echo 1>&2 "Try \`$0 --help' for more information" + exit 1 + ;; + +esac + +# Now exit if we have it, but it failed. Also exit now if we +# don't have it and --version was passed (most likely to detect +# the program). +case "$1" in + lex|yacc) + # Not GNU programs, they don't have --version. + ;; + + tar) + if test -n "$run"; then + echo 1>&2 "ERROR: \`tar' requires --run" + exit 1 + elif test "x$2" = "x--version" || test "x$2" = "x--help"; then + exit 1 + fi + ;; + + *) + if test -z "$run" && ($1 --version) > /dev/null 2>&1; then + # We have it, but it failed. + exit 1 + elif test "x$2" = "x--version" || test "x$2" = "x--help"; then + # Could not run --version or --help. This is probably someone + # running `$TOOL --version' or `$TOOL --help' to check whether + # $TOOL exists and not knowing $TOOL uses missing. + exit 1 + fi + ;; +esac + +# If it does not exist, or fails to run (possibly an outdated version), +# try to emulate it. +case "$1" in + aclocal*) + echo 1>&2 "\ +WARNING: \`$1' is $msg. You should only need it if + you modified \`acinclude.m4' or \`${configure_ac}'. You might want + to install the \`Automake' and \`Perl' packages. Grab them from + any GNU archive site." + touch aclocal.m4 + ;; + + autoconf) + echo 1>&2 "\ +WARNING: \`$1' is $msg. You should only need it if + you modified \`${configure_ac}'. You might want to install the + \`Autoconf' and \`GNU m4' packages. Grab them from any GNU + archive site." + touch configure + ;; + + autoheader) + echo 1>&2 "\ +WARNING: \`$1' is $msg. You should only need it if + you modified \`acconfig.h' or \`${configure_ac}'. You might want + to install the \`Autoconf' and \`GNU m4' packages. Grab them + from any GNU archive site." + files=`sed -n 's/^[ ]*A[CM]_CONFIG_HEADER(\([^)]*\)).*/\1/p' ${configure_ac}` + test -z "$files" && files="config.h" + touch_files= + for f in $files; do + case "$f" in + *:*) touch_files="$touch_files "`echo "$f" | + sed -e 's/^[^:]*://' -e 's/:.*//'`;; + *) touch_files="$touch_files $f.in";; + esac + done + touch $touch_files + ;; + + automake*) + echo 1>&2 "\ +WARNING: \`$1' is $msg. You should only need it if + you modified \`Makefile.am', \`acinclude.m4' or \`${configure_ac}'. + You might want to install the \`Automake' and \`Perl' packages. + Grab them from any GNU archive site." + find . -type f -name Makefile.am -print | + sed 's/\.am$/.in/' | + while read f; do touch "$f"; done + ;; + + autom4te) + echo 1>&2 "\ +WARNING: \`$1' is needed, but is $msg. + You might have modified some files without having the + proper tools for further handling them. + You can get \`$1' as part of \`Autoconf' from any GNU + archive site." + + file=`echo "$*" | sed -n 's/.*--output[ =]*\([^ ]*\).*/\1/p'` + test -z "$file" && file=`echo "$*" | sed -n 's/.*-o[ ]*\([^ ]*\).*/\1/p'` + if test -f "$file"; then + touch $file + else + test -z "$file" || exec >$file + echo "#! /bin/sh" + echo "# Created by GNU Automake missing as a replacement of" + echo "# $ $@" + echo "exit 0" + chmod +x $file + exit 1 + fi + ;; + + bison|yacc) + echo 1>&2 "\ +WARNING: \`$1' $msg. You should only need it if + you modified a \`.y' file. You may need the \`Bison' package + in order for those modifications to take effect. You can get + \`Bison' from any GNU archive site." + rm -f y.tab.c y.tab.h + if [ $# -ne 1 ]; then + eval LASTARG="\${$#}" + case "$LASTARG" in + *.y) + SRCFILE=`echo "$LASTARG" | sed 's/y$/c/'` + if [ -f "$SRCFILE" ]; then + cp "$SRCFILE" y.tab.c + fi + SRCFILE=`echo "$LASTARG" | sed 's/y$/h/'` + if [ -f "$SRCFILE" ]; then + cp "$SRCFILE" y.tab.h + fi + ;; + esac + fi + if [ ! -f y.tab.h ]; then + echo >y.tab.h + fi + if [ ! -f y.tab.c ]; then + echo 'main() { return 0; }' >y.tab.c + fi + ;; + + lex|flex) + echo 1>&2 "\ +WARNING: \`$1' is $msg. You should only need it if + you modified a \`.l' file. You may need the \`Flex' package + in order for those modifications to take effect. You can get + \`Flex' from any GNU archive site." + rm -f lex.yy.c + if [ $# -ne 1 ]; then + eval LASTARG="\${$#}" + case "$LASTARG" in + *.l) + SRCFILE=`echo "$LASTARG" | sed 's/l$/c/'` + if [ -f "$SRCFILE" ]; then + cp "$SRCFILE" lex.yy.c + fi + ;; + esac + fi + if [ ! -f lex.yy.c ]; then + echo 'main() { return 0; }' >lex.yy.c + fi + ;; + + help2man) + echo 1>&2 "\ +WARNING: \`$1' is $msg. You should only need it if + you modified a dependency of a manual page. You may need the + \`Help2man' package in order for those modifications to take + effect. You can get \`Help2man' from any GNU archive site." + + file=`echo "$*" | sed -n 's/.*-o \([^ ]*\).*/\1/p'` + if test -z "$file"; then + file=`echo "$*" | sed -n 's/.*--output=\([^ ]*\).*/\1/p'` + fi + if [ -f "$file" ]; then + touch $file + else + test -z "$file" || exec >$file + echo ".ab help2man is required to generate this page" + exit 1 + fi + ;; + + makeinfo) + echo 1>&2 "\ +WARNING: \`$1' is $msg. You should only need it if + you modified a \`.texi' or \`.texinfo' file, or any other file + indirectly affecting the aspect of the manual. The spurious + call might also be the consequence of using a buggy \`make' (AIX, + DU, IRIX). You might want to install the \`Texinfo' package or + the \`GNU make' package. Grab either from any GNU archive site." + # The file to touch is that specified with -o ... + file=`echo "$*" | sed -n 's/.*-o \([^ ]*\).*/\1/p'` + if test -z "$file"; then + # ... or it is the one specified with @setfilename ... + infile=`echo "$*" | sed 's/.* \([^ ]*\) *$/\1/'` + file=`sed -n '/^@setfilename/ { s/.* \([^ ]*\) *$/\1/; p; q; }' $infile` + # ... or it is derived from the source name (dir/f.texi becomes f.info) + test -z "$file" && file=`echo "$infile" | sed 's,.*/,,;s,.[^.]*$,,'`.info + fi + # If the file does not exist, the user really needs makeinfo; + # let's fail without touching anything. + test -f $file || exit 1 + touch $file + ;; + + tar) + shift + + # We have already tried tar in the generic part. + # Look for gnutar/gtar before invocation to avoid ugly error + # messages. + if (gnutar --version > /dev/null 2>&1); then + gnutar "$@" && exit 0 + fi + if (gtar --version > /dev/null 2>&1); then + gtar "$@" && exit 0 + fi + firstarg="$1" + if shift; then + case "$firstarg" in + *o*) + firstarg=`echo "$firstarg" | sed s/o//` + tar "$firstarg" "$@" && exit 0 + ;; + esac + case "$firstarg" in + *h*) + firstarg=`echo "$firstarg" | sed s/h//` + tar "$firstarg" "$@" && exit 0 + ;; + esac + fi + + echo 1>&2 "\ +WARNING: I can't seem to be able to run \`tar' with the given arguments. + You may want to install GNU tar or Free paxutils, or check the + command line arguments." + exit 1 + ;; + + *) + echo 1>&2 "\ +WARNING: \`$1' is needed, and is $msg. + You might have modified some files without having the + proper tools for further handling them. Check the \`README' file, + it often tells you about the needed prerequisites for installing + this package. You may also peek at any GNU archive site, in case + some other package would contain this missing \`$1' program." + exit 1 + ;; +esac + +exit 0 + +# Local variables: +# eval: (add-hook 'write-file-hooks 'time-stamp) +# time-stamp-start: "scriptversion=" +# time-stamp-format: "%:y-%02m-%02d.%02H" +# time-stamp-end: "$" +# End: diff --git a/AMDiS/other/scripts/schedule b/AMDiS/other/scripts/schedule new file mode 100755 index 0000000000000000000000000000000000000000..f11de3443ce4398f081016e05b0d3304e3c3de1c --- /dev/null +++ b/AMDiS/other/scripts/schedule @@ -0,0 +1,121 @@ +#!/bin/bash + +# Define the program to be executed +EXEC_CMD="./vecheat init/vecheat.dat.2d" + +# Define the number of required processors +NUMBER_PROC=1 + +# Define if the program makes use of OpenMP. +USE_OPENMP=0 + +# Define if the program makes use of an MPI library. +USE_MPI=0 + +# Define the server on which the program is running (mars or deimos) +SERVER=mars + +# Expected runtime of one execution, the format is hh::mm +WTIME=1:00 + +# Define the output file to which all output (standard and error) will be written. +OUTFILE=out + + +############################################################################## +# # +# Do not edit the script after this line! # +# # +############################################################################## + +SCRIPT_NAME=$0 +SCHEDULE_ERROR_CODE=23 + + +if [ $NUMBER_PROC -gt 1 ] ; then + if [ $USE_OPENMP -eq 1 ] ; then + export OMP_NUM_THREADS=$NUMBER_PROC + fi + + if [ $USE_MPI -eq 1 ] ; then + if [ $SERVER -eq mars ] ; then + EXEC_CMD="mpirun -np ${NUMBER_PROC} {$EXEC_CMD}" + fi + + if [ $SERVER -eq deimos] ; then + EXEC_CMD="openmpi mpirun.lsf {$EXEC_CMD}" + fi + fi +fi + + + +case "$1" in + -rs ) + # The program is started after is has been terminated before + date >> $OUTFILE 2>&1 + printf "Schedule-Skript: Computation restarted\n" >> $OUTFILE 2>&1 + (${EXEC_CMD} -rs __serialized_problem.ser) >> $OUTFILE 2>&1 + ERROR_CODE=$? + date >> $OUTFILE 2>&1 + printf "Schedule-Skript: Computation terminated\n" >> $OUTFILE 2>&1 + ;; + -s ) + # The program is started for the first time + date >> $OUTFILE 2>&1 + printf "Schedule-Skript: Computation started\n" >> $OUTFILE 2>&1 + ${EXEC_CMD} >> $OUTFILE 2>&1 + ERROR_CODE=$? + date >> $OUTFILE 2>&1 + printf "Schedule-Skript: Computation terminated with code %d\n" $ERROR_CODE >> $OUTFILE 2>&1 + ;; + -c ) + date > $OUTFILE 2>&1 + printf "Schedule-Skript: Submitted programm to the batch system\n" >> $OUTFILE 2>&1 + bsub -n $NUMBER_PROC -W $WTIME $SCRIPT_NAME -rs >> $OUTFILE 2>&1 + if [ $? -eq 0 ] ; then + printf "Submitted program to the batch system!\n" + printf "Submitted program to the batch system!\n" >> $OUTFILE 2>&1 + exit 0 + else + printf "Error: Could not submit program to the batch system!\n" + printf "Error: Could not submit program to the batch system!\n" >> $OUTFILE 2>&1 + exit 1 + fi + ;; + * ) + # First scheduling of the program + date > $OUTFILE 2>&1 + printf "Schedule-Skript: Submitted programm to the batch system\n" >> $OUTFILE 2>&1 + bsub -n $NUMBER_PROC -W $WTIME $SCRIPT_NAME -s >> $OUTFILE 2>&1 + if [ $? -eq 0 ] ; then + printf "Submitted program to the batch system!\n" + printf "Submitted program to the batch system!\n" >> $OUTFILE 2>&1 + exit 0 + else + printf "Error: Could not submit program to the batch system!\n" + printf "Error: Could not submit program to the batch system!\n" >> $OUTFILE 2>&1 + exit 1 + fi + ;; +esac + + + +if [ $ERROR_CODE -eq $SCHEDULE_ERROR_CODE ] ; then + # Error code indicates that the program has been terminated in order to be rescheduled. + date >> $OUTFILE 2>&1 + printf "Schedule-Skript: Submitted programm to the batch system\n" >> $OUTFILE 2>&1 + bsub -n $NUMBER_PROC -W $WTIME $SCRIPT_NAME -rs >> $OUTFILE 2>&1 + exit 0 +elif [ $ERROR_CODE -eq 0 ] ; then + # The program terminated successfully. + date >> $OUTFILE 2>&1 + printf "Schedule-Skript: Program stopped successfully\n" >> $OUTFILE 2>&1 + exit 0 +else + # Other error occurred. Forward the error code. + date >> $OUTFILE 2>&1 + printf "Schedule-Skript: ERROR CODE: %d\n" $ERROR_CODE >> $OUTFILE 2>&1 + exit $ERROR_CODE +fi diff --git a/AMDiS/src/AMDiS.h b/AMDiS/src/AMDiS.h new file mode 100644 index 0000000000000000000000000000000000000000..54f170a79d10d89139583815757db16ca84b619b --- /dev/null +++ b/AMDiS/src/AMDiS.h @@ -0,0 +1,98 @@ +#ifndef AMDIS_H +#define AMDIS_H +#include "AbstractFunction.h" +#include "AdaptInfo.h" +#include "AdaptInstationary.h" +#include "AdaptStationary.h" +#include "Assembler.h" +#include "BasisFunction.h" +#include "BiCGSolver.h" +#include "Boundary.h" +#include "BiCGStab_M.h" +#include "Boundary.h" +#include "BoundaryCondition.h" +#include "BoundaryManager.h" +#include "CGSolver.h" +#include "CoarseningManager.h" +#include "CoarseningManager1d.h" +#include "CoarseningManager2d.h" +#include "CoarseningManager3d.h" +#include "CreatorInterface.h" +#include "CreatorMap.h" +#include "DOFAdmin.h" +#include "DOFContainer.h" +#include "DOFIndexed.h" +#include "DOFIterator.h" +#include "DOFMatrix.h" +#include "DOFVector.h" +#include "DiagonalPreconditioner.h" +#include "DirichletBC.h" +#include "DualTraverse.h" +#include "ElInfo.h" +#include "ElInfo1d.h" +#include "ElInfo2d.h" +#include "ElInfo3d.h" +#include "Element.h" +#include "ElementMatrix.h" +#include "ElementVector.h" +#include "Error.h" +#include "Estimator.h" +#include "FileWriter.h" +#include "FiniteElemSpace.h" +#include "FixVec.h" +#include "Flag.h" +#include "GMResSolver.h" +#include "Global.h" +#include "GridWriter.h" +#include "Lagrange.h" +#include "LeafData.h" +#include "Line.h" +#include "MacroElement.h" +#include "MacroWriter.h" +#include "Marker.h" +#include "MatVecMultiplier.h" +#include "MatrixVector.h" +#include "MemoryManager.h" +#include "MemoryPool.h" +#include "Mesh.h" +#include "Newton.h" +#include "NewtonS.h" +#include "NonLinSolver.h" +#include "NonLinUpdater.h" +#include "ODirSolver.h" +#include "OEMSolver.h" +#include "OResSolver.h" +#include "Operator.h" +#include "Parameters.h" +#include "Parametric.h" +#include "PeriodicMap.h" +#include "PeriodicBC.h" +#include "Preconditioner.h" +#include "ProblemScal.h" +#include "ProblemVec.h" +#include "ProblemInstat.h" +#include "ProblemTimeInterface.h" +#include "ProblemInterpolScal.h" +#include "ProblemNonLin.h" +#include "ProblemStatBase.h" +#include "StandardProblemIteration.h" +#include "Projection.h" +#include "QPsiPhi.h" +#include "Quadrature.h" +#include "RCNeighbourList.h" +#include "RefinementManager.h" +#include "RefinementManager1d.h" +#include "RefinementManager2d.h" +#include "RefinementManager3d.h" +#include "RobinBC.h" +#include "SurfaceOperator.h" +#include "SurfaceQuadrature.h" +#include "SystemVector.h" +#include "TecPlotWriter.h" +#include "Tetrahedron.h" +#include "TimedObject.h" +#include "Traverse.h" +#include "Triangle.h" +#include "ValueWriter.h" +#include "demangle.h" +#endif diff --git a/AMDiS/src/AUTHORS b/AMDiS/src/AUTHORS new file mode 100644 index 0000000000000000000000000000000000000000..e69de29bb2d1d6434b8b29ae775ad8c2e48c5391 diff --git a/AMDiS/src/AbstractFunction.h b/AMDiS/src/AbstractFunction.h new file mode 100644 index 0000000000000000000000000000000000000000..decfd6e8a046f79c2d133a45b668dc10f908950b --- /dev/null +++ b/AMDiS/src/AbstractFunction.h @@ -0,0 +1,196 @@ +// ============================================================================ +// == == +// == AMDiS - Adaptive multidimensional simulations == +// == == +// ============================================================================ +// == == +// == crystal growth group == +// == == +// == Stiftung caesar == +// == Ludwig-Erhard-Allee 2 == +// == 53175 Bonn == +// == germany == +// == == +// ============================================================================ +// == == +// == http://www.caesar.de/cg/AMDiS == +// == == +// ============================================================================ + +/** \file AbstractFunction.h */ + +#ifndef AMDIS_ABSTRACTFUNCTION_H +#define AMDIS_ABSTRACTFUNCTION_H + +#include "Global.h" +#include "MemoryManager.h" + +namespace AMDiS { + + // ============================================================================ + // ===== class AbstractFunction =============================================== + // ============================================================================ + + /** + * \ingroup Common + * + * \brief + * An AbstractFunction object represents a function + * f : ArgumentType -> ReturnType. + * + * AbstractFunction is a pure virtual class interface class. + * To create your own function you have to derive AbstractFunction and + * overload operator(). + */ + template<typename ReturnType, typename ArgumentType> + class AbstractFunction + { + public: + /** \brief + * Constructor. + */ + AbstractFunction(int degree = 0) : degree_(degree) {}; + + virtual ~AbstractFunction() {}; + + /** \brief + * Returns \ref degree_. + */ + inline int getDegree() const { return degree_; }; + + /** \brief + * Deligates the evaluation to overriden method f. + */ + virtual const ReturnType& operator()(const ArgumentType& x) const = 0; + + protected: + int degree_; + }; + + // ============================================================================ + // ===== class BinaryAbstractFunction ========================================= + // ============================================================================ + + /** + * \ingroup Common + * + * \brief + * Interface for binary functions. + */ + template<typename ReturnType, + typename ArgumentType1, + typename ArgumentType2> + class BinaryAbstractFunction + { + public: + /** \brief + * Constructor. + */ + BinaryAbstractFunction(int degree = 0) : degree_(degree) {}; + + virtual ~BinaryAbstractFunction() {}; + + /** \brief + * Returns \ref degree_. + */ + inline int getDegree() const { return degree_; }; + + /** \brief + * Deligates the evaluation to overriden method f. + */ + virtual const ReturnType& operator()(const ArgumentType1& x, + const ArgumentType2& y) const = 0; + + protected: + int degree_; + }; + + // ============================================================================ + // ===== class TertiaryAbstractFunction ======================================= + // ============================================================================ + + /** + * \ingroup Common + * + * \brief + * Interface for tertiary functions. + */ + template<typename ReturnType, + typename ArgumentType1, + typename ArgumentType2, + typename ArgumentType3> + class TertiaryAbstractFunction + { + public: + /** \brief + * Constructor. + */ + TertiaryAbstractFunction(int degree = 0) : degree_(degree) {}; + + virtual ~TertiaryAbstractFunction() {}; + + /** \brief + * Returns \ref degree_. + */ + inline int getDegree() const { return degree_; }; + + /** \brief + * function evaluation. + */ + virtual const ReturnType& operator()(const ArgumentType1& x, + const ArgumentType2& y, + const ArgumentType3& z) const = 0; + + protected: + int degree_; + }; + + + // ============================================================================ + // ===== class QuartAbstractFunction ======================================= + // ============================================================================ + + /** + * \ingroup Common + * + * \brief + * Interface for quart functions. + */ + template<typename ReturnType, + typename ArgumentType1, + typename ArgumentType2, + typename ArgumentType3, + typename ArgumentType4> + class QuartAbstractFunction + { + public: + /** \brief + * Constructor. + */ + QuartAbstractFunction(int degree = 0) : degree_(degree) {}; + + virtual ~QuartAbstractFunction() {}; + + /** \brief + * Returns \ref degree_. + */ + inline int getDegree() const { return degree_; }; + + /** \brief + * function evaluation. + */ + virtual const ReturnType& operator()(const ArgumentType1& x, + const ArgumentType2& y, + const ArgumentType3& z, + const ArgumentType4& u) const = 0; + + protected: + int degree_; + }; + + + + +} + +#endif // AMDIS_ABSTRACTFUNCTION_H diff --git a/AMDiS/src/AdaptBase.cc b/AMDiS/src/AdaptBase.cc new file mode 100644 index 0000000000000000000000000000000000000000..98a4ac8de979479cb12412a2bdf156889997abe9 --- /dev/null +++ b/AMDiS/src/AdaptBase.cc @@ -0,0 +1,7 @@ +#include "AdaptBase.h" + +namespace AMDiS { + + int AdaptBase::info_ = 10; + +} diff --git a/AMDiS/src/AdaptBase.h b/AMDiS/src/AdaptBase.h new file mode 100644 index 0000000000000000000000000000000000000000..f754bbb7576fd6c2bcbef6238479bc80353e247d --- /dev/null +++ b/AMDiS/src/AdaptBase.h @@ -0,0 +1,141 @@ +// ============================================================================ +// == == +// == AMDiS - Adaptive multidimensional simulations == +// == == +// ============================================================================ +// == == +// == crystal growth group == +// == == +// == Stiftung caesar == +// == Ludwig-Erhard-Allee 2 == +// == 53175 Bonn == +// == germany == +// == == +// ============================================================================ +// == == +// == http://www.caesar.de/cg/AMDiS == +// == == +// ============================================================================ + +/** \file AdaptBase.h */ + +#ifndef AMDIS_ADAPTBASE_H +#define AMDIS_ADAPTBASE_H + +#include <string> + +namespace AMDiS { + + class ProblemIterationInterface; + class ProblemTimeInterface; + class AdaptInfo; + + // ============================================================================ + // ===== class AdaptBase ====================================================== + // ============================================================================ + + /** \brief + * Interface for adaption loops. + */ + class AdaptBase + { + public: + /** \brief + * Constructor + */ + AdaptBase(const ::std::string& name, + ProblemIterationInterface *problemIteration, + AdaptInfo *adaptInfo, + ProblemTimeInterface *problemTime = NULL, + AdaptInfo *initialAdaptInfo = NULL) + : name_(name), + problemIteration_(problemIteration), + adaptInfo_(adaptInfo), + problemTime_(problemTime), + initialAdaptInfo_(initialAdaptInfo) + {}; + + /** \brief + * Destructor + */ + virtual ~AdaptBase() {}; + + /** \brief + * Pure virtual method. Must be overloaded by sub classes to perform + * a concrete adaption loop. + */ + virtual int adapt() = 0; + + /** \brief + * Returns \ref name_ + */ + inline const ::std::string& getName() const { return name_; }; + + /** \brief + * Returns \ref problemIteration_ + */ + inline ProblemIterationInterface *getProblemIteration() { + return problemIteration_; + }; + + inline void setProblemIteration(ProblemIterationInterface *pii) { + problemIteration_ = pii; + }; + + /** \brief + * Returns \ref adaptInfo_ + */ + inline AdaptInfo *getAdaptInfo() { return adaptInfo_; }; + + /** \brief + * Returns \ref problemTime_ + */ + inline ProblemTimeInterface *getProblemTime() { + return problemTime_; + }; + + inline void setProblemTime(ProblemTimeInterface *pti) { + problemTime_ = pti; + } + + /** \brief + * Returns \ref initialAdaptInfo_ + */ + inline AdaptInfo *getInitialAdaptInfo() { return initialAdaptInfo_; }; + + protected: + /** \brief + * Name of the adaption loop + */ + ::std::string name_; + + /** \brief + * Problem iteration interface + */ + ProblemIterationInterface *problemIteration_; + + /** \brief + * Main adapt info + */ + AdaptInfo *adaptInfo_; + + /** \brief + * problem time interface + */ + ProblemTimeInterface *problemTime_; + + /** \brief + * Adapt info for initial adapt. Will be given to + * problemTime_->solveInitialProblem(). + */ + AdaptInfo *initialAdaptInfo_; + + /** \brief + * Info level + */ + static int info_; + }; + +} + +#endif diff --git a/AMDiS/src/AdaptInfo.cc b/AMDiS/src/AdaptInfo.cc new file mode 100644 index 0000000000000000000000000000000000000000..e0f7cfd0d7f79329484ced1af3f060b87b495a12 --- /dev/null +++ b/AMDiS/src/AdaptInfo.cc @@ -0,0 +1,121 @@ +#include <AdaptInfo.h> + +namespace AMDiS { + + void AdaptInfo::setScalContents(int newSize) { + int oldSize = scalContents.getSize(); + + if (newSize > oldSize) { + scalContents.resize(newSize); + + char number[5]; + for (int i = oldSize; i < newSize; i++) { + sprintf(number, "[%d]", i); + scalContents[i] = new ScalContent(name + ::std::string(number)); + } + } + } + + void AdaptInfo::serialize(::std::ostream& out) { + out << name << ::std::endl; + out.write(reinterpret_cast<const char*>(&maxSpaceIteration), sizeof(int)); + out.write(reinterpret_cast<const char*>(&spaceIteration), sizeof(int)); + out.write(reinterpret_cast<const char*>(×tepIteration), sizeof(int)); + out.write(reinterpret_cast<const char*>(&maxTimestepIteration), sizeof(int)); + out.write(reinterpret_cast<const char*>(&timeIteration), sizeof(int)); + out.write(reinterpret_cast<const char*>(&maxTimeIteration), sizeof(int)); + out.write(reinterpret_cast<const char*>(&time), sizeof(double)); + out.write(reinterpret_cast<const char*>(&startTime), sizeof(double)); + out.write(reinterpret_cast<const char*>(&endTime), sizeof(double)); + out.write(reinterpret_cast<const char*>(×tep), sizeof(double)); + out.write(reinterpret_cast<const char*>(&minTimestep), sizeof(double)); + out.write(reinterpret_cast<const char*>(&maxTimestep), sizeof(double)); + out.write(reinterpret_cast<const char*>(×tepNumber), sizeof(int)); + out.write(reinterpret_cast<const char*>(&solverIterations), sizeof(int)); + out.write(reinterpret_cast<const char*>(&maxSolverIterations), sizeof(int)); + out.write(reinterpret_cast<const char*>(&solverTolerance), sizeof(double)); + out.write(reinterpret_cast<const char*>(&solverResidual), sizeof(double)); + int size = scalContents.getSize(); + out.write(reinterpret_cast<const char*>(&size), sizeof(int)); + for (int i = 0; i < size; i++) { + out.write(reinterpret_cast<const char*>(&(scalContents[i]->est_sum)), + sizeof(double)); + out.write(reinterpret_cast<const char*>(&(scalContents[i]->est_t_sum)), + sizeof(double)); + out.write(reinterpret_cast<const char*>(&(scalContents[i]->est_max)), + sizeof(double)); + out.write(reinterpret_cast<const char*>(&(scalContents[i]->est_t_max)), + sizeof(double)); + out.write(reinterpret_cast<const char*>(&(scalContents[i]->spaceTolerance)), + sizeof(double)); + out.write(reinterpret_cast<const char*>(&(scalContents[i]->timeTolerance)), + sizeof(double)); + out.write(reinterpret_cast<const char*>(&(scalContents[i]->timeErrLow)), + sizeof(double)); + out.write(reinterpret_cast<const char*>(&(scalContents[i]->coarsenAllowed)), + sizeof(int)); + out.write(reinterpret_cast<const char*>(&(scalContents[i]->refinementAllowed)), + sizeof(int)); + out.write(reinterpret_cast<const char*>(&(scalContents[i]->refineBisections)), + sizeof(int)); + out.write(reinterpret_cast<const char*>(&(scalContents[i]->coarseBisections)), + sizeof(int)); + } + } + + void AdaptInfo::deserialize(::std::istream& in) { + in >> name; + in.get(); // because of ::std::endl in serialization + + in.read(reinterpret_cast<char*>(&maxSpaceIteration), sizeof(int)); + in.read(reinterpret_cast<char*>(&spaceIteration), sizeof(int)); + in.read(reinterpret_cast<char*>(×tepIteration), sizeof(int)); + in.read(reinterpret_cast<char*>(&maxTimestepIteration), sizeof(int)); + in.read(reinterpret_cast<char*>(&timeIteration), sizeof(int)); + in.read(reinterpret_cast<char*>(&maxTimeIteration), sizeof(int)); + in.read(reinterpret_cast<char*>(&time), sizeof(double)); + in.read(reinterpret_cast<char*>(&startTime), sizeof(double)); + in.read(reinterpret_cast<char*>(&endTime), sizeof(double)); + in.read(reinterpret_cast<char*>(×tep), sizeof(double)); + in.read(reinterpret_cast<char*>(&minTimestep), sizeof(double)); + in.read(reinterpret_cast<char*>(&maxTimestep), sizeof(double)); + in.read(reinterpret_cast<char*>(×tepNumber), sizeof(int)); + in.read(reinterpret_cast<char*>(&solverIterations), sizeof(int)); + in.read(reinterpret_cast<char*>(&maxSolverIterations), sizeof(int)); + in.read(reinterpret_cast<char*>(&solverTolerance), sizeof(double)); + in.read(reinterpret_cast<char*>(&solverResidual), sizeof(double)); + int size; + in.read(reinterpret_cast<char*>(&size), sizeof(int)); + scalContents.resize(size); + for (int i = 0; i < size; i++) { + // if (!scalContents[i]) { + char number[5]; + sprintf(number, "[%d]", i); + scalContents[i] = new ScalContent(name + ::std::string(number)); + // } + in.read(reinterpret_cast<char*>(&(scalContents[i]->est_sum)), + sizeof(double)); + in.read(reinterpret_cast<char*>(&(scalContents[i]->est_t_sum)), + sizeof(double)); + in.read(reinterpret_cast<char*>(&(scalContents[i]->est_max)), + sizeof(double)); + in.read(reinterpret_cast<char*>(&(scalContents[i]->est_t_max)), + sizeof(double)); + in.read(reinterpret_cast<char*>(&(scalContents[i]->spaceTolerance)), + sizeof(double)); + in.read(reinterpret_cast<char*>(&(scalContents[i]->timeTolerance)), + sizeof(double)); + in.read(reinterpret_cast<char*>(&(scalContents[i]->timeErrLow)), + sizeof(double)); + in.read(reinterpret_cast<char*>(&(scalContents[i]->coarsenAllowed)), + sizeof(int)); + in.read(reinterpret_cast<char*>(&(scalContents[i]->refinementAllowed)), + sizeof(int)); + in.read(reinterpret_cast<char*>(&(scalContents[i]->refineBisections)), + sizeof(int)); + in.read(reinterpret_cast<char*>(&(scalContents[i]->coarseBisections)), + sizeof(int)); + } + } + +} diff --git a/AMDiS/src/AdaptInfo.h b/AMDiS/src/AdaptInfo.h new file mode 100644 index 0000000000000000000000000000000000000000..211cdabd30519535e526cfb1888635072b114496 --- /dev/null +++ b/AMDiS/src/AdaptInfo.h @@ -0,0 +1,771 @@ +// ============================================================================ +// == == +// == AMDiS - Adaptive multidimensional simulations == +// == == +// ============================================================================ +// == == +// == crystal growth group == +// == == +// == Stiftung caesar == +// == Ludwig-Erhard-Allee 2 == +// == 53175 Bonn == +// == germany == +// == == +// ============================================================================ +// == == +// == http://www.caesar.de/cg/AMDiS == +// == == +// ============================================================================ + +/** \file AdaptInfo.h */ + +#ifndef AMDIS_ADAPTINFO_H +#define AMDIS_ADAPTINFO_H + +#include "MemoryManager.h" +#include "MatrixVector.h" +#include "Parameters.h" +#include "Serializable.h" + +namespace AMDiS { + + // =========================================================================== + // ===== class AdaptInfo ===================================================== + // =========================================================================== + + /** + * \ingroup Adaption + * + * \brief + * Holds adapt parameters and infos about the problem. Base class + * for AdaptInfoScal and AdaptInfoVec. + */ + class AdaptInfo : public Serializable + { + protected: + /** \brief + * Stores adapt infos for a scalar problem or for one component of a + * vector valued problem. + */ + class ScalContent { + public: + /** \brief + * Constructor. + */ + ScalContent(::std::string prefix) + : est_sum(0.0), + est_t_sum(0.0), + est_max(0.0), + est_t_max(0.0), + spaceTolerance(1.0), + timeTolerance(1.0), + timeErrLow(1.0), + coarsenAllowed(0), + refinementAllowed(1), + refineBisections(1), + coarseBisections(1) + { + double totalTol = 1.0; + double relSpaceErr = 1.0; + double relTimeErr = 0.5; + double timeTheta1 = 1.0; + double timeTheta2 = 0.3; + + GET_PARAMETER(0, prefix + "->tolerance", "%f", &totalTol); + GET_PARAMETER(0, prefix + "->rel space error", "%f", &relSpaceErr); + GET_PARAMETER(0, prefix + "->rel time error", "%f", &relTimeErr); + GET_PARAMETER(0, prefix + "->time theta 1", "%f", &timeTheta1); + GET_PARAMETER(0, prefix + "->time theta 2", "%f", &timeTheta2); + GET_PARAMETER(0, prefix + "->coarsen allowed", "%d", &coarsenAllowed); + GET_PARAMETER(0, prefix + "->refinement allowed", "%d", &refinementAllowed); + GET_PARAMETER(0, prefix + "->refine bisections", "%d", &refineBisections); + GET_PARAMETER(0, prefix + "->coarsen bisections", "%d", &coarseBisections); + + spaceTolerance = totalTol * relSpaceErr; + timeTolerance = totalTol * relTimeErr * timeTheta1; + timeErrLow = totalTol * relTimeErr * timeTheta2; + }; + + /** \brief + * Sum of all error estimates + */ + double est_sum; + + /** \brief + * Sum of all time error estimates + */ + double est_t_sum; + + /** \brief + * maximal local error estimate. + */ + double est_max; + + /** \brief + * Maximum of all time error estimates + */ + double est_t_max; + + /** \brief + * Tolerance for the (absolute or relative) error + */ + double spaceTolerance; + + /** \brief + * Time tolerance. + */ + double timeTolerance; + + /** \brief + * Lower bound for the time error. + */ + double timeErrLow; + + /** \brief + * true if coarsening is allowed, false otherwise. + */ + int coarsenAllowed; + + /** \brief + * true if refinement is allowed, false otherwise. + */ + int refinementAllowed; + + /** \brief + * parameter to tell the marking strategy how many bisections should be + * performed when an element is marked for refinement; usually the value is + * 1 or DIM + */ + int refineBisections; + + /** \brief + * parameter to tell the marking strategy how many bisections should + * be undone when an element is marked for coarsening; usually the value is + * 1 or DIM + */ + int coarseBisections; + }; + + public: + /** \brief + * Constructor. + */ + AdaptInfo(::std::string name_, int size = 1) + : name(name_), + spaceIteration(-1), + maxSpaceIteration(-1), + timestepIteration(0), + maxTimestepIteration(30), + timeIteration(0), + maxTimeIteration(30), + time(0.0), + startTime(0.0), + endTime(1.0), + timestep(0.0), + minTimestep(0.0), + maxTimestep(1.0), + timestepNumber(0), + solverIterations(0), + maxSolverIterations(0), + solverTolerance(1e-8), + solverResidual(0.0), + scalContents(size) + { + GET_PARAMETER(0, name_ + "->start time", "%f", &startTime); + time = startTime; + GET_PARAMETER(0, name_ + "->timestep", "%f", ×tep); + GET_PARAMETER(0, name_ + "->end time", "%f", &endTime); + GET_PARAMETER(0, name_ + "->max iteration", "%d", &maxSpaceIteration); + GET_PARAMETER(0, name_ + "->max timestep iteration", "%d", &maxTimestepIteration); + GET_PARAMETER(0, name_ + "->max time iteration", "%d", &maxTimeIteration); + + GET_PARAMETER(0, name_ + "->min timestep", "%f", &minTimestep); + GET_PARAMETER(0, name_ + "->max timestep", "%f", &maxTimestep); + + if (size == 1) { + scalContents[0] = new ScalContent(name); + } else { + char number[5]; + for (int i = 0; i < size; i++) { + sprintf(number, "[%d]", i); + scalContents[i] = new ScalContent(name + ::std::string(number)); + } + } + }; + + /** \brief + * Destructor. + */ + virtual ~AdaptInfo() { + int i; + for(i = 0; i < scalContents.getSize(); i++) { + delete scalContents[i]; + } + }; + + inline void reset() + { + spaceIteration = -1; + timestepIteration = 0; + timeIteration = 0; + time = 0.0; + timestep = 0.0; + timestepNumber = 0; + solverIterations = 0; + solverResidual = 0.0; + }; + + /** \brief + * Returns whether space tolerance is reached. + */ + virtual bool spaceToleranceReached() { + int i, size = scalContents.getSize(); + for(i = 0; i < size; i++) { + if(!(scalContents[i]->est_sum < scalContents[i]->spaceTolerance)) { + return false; + } + } + return true; + }; + + /** \brief + * Returns whether space tolerance of component i is reached. + */ + virtual bool spaceToleranceReached(int i) { + if(!(scalContents[i]->est_sum < scalContents[i]->spaceTolerance)) { + return false; + } else { + return true; + } + }; + + /** \brief + * Returns whether time tolerance is reached. + */ + virtual bool timeToleranceReached() { + //if(timestep <= minTimestep) return true; + int i, size = scalContents.getSize(); + for(i = 0; i < size; i++) { + if(!(scalContents[i]->est_t_sum < scalContents[i]->timeTolerance)) { + return false; + } + } + return true; + }; + + /** \brief + * Returns whether time tolerance of component i is reached. + */ + virtual bool timeToleranceReached(int i) { + if(!(scalContents[i]->est_t_sum < scalContents[i]->timeTolerance)) { + return false; + } else { + return true; + } + }; + + /** \brief + * Returns whether time error is under its lower bound. + */ + virtual bool timeErrorLow() { + int size = scalContents.getSize(); + for (int i = 0; i < size; i++) { + if (!(scalContents[i]->est_t_sum < scalContents[i]->timeErrLow)) { + return false; + } + } + return true; + }; + + /** \brief + * Returns \ref spaceIteration. + */ + inline int getSpaceIteration() { + return spaceIteration; + }; + + /** \brief + * Sets \ref spaceIteration. + */ + inline void setSpaceIteration(int it) { + spaceIteration = it; + }; + + /** \brief + * Returns \ref maxSpaceIteration. + */ + inline int getMaxSpaceIteration() { + return maxSpaceIteration; + }; + + /** \brief + * Sets \ref maxSpaceIteration. + */ + inline void setMaxSpaceIteration(int it) { + maxSpaceIteration = it; + }; + + /** \brief + * Increments \ref spaceIteration by 1; + */ + inline void incSpaceIteration() { + spaceIteration++; + }; + + /** \brief + * Sets \ref timestepIteration. + */ + inline void setTimestepIteration(int it) { + timestepIteration = it; + }; + + /** \brief + * Returns \ref timestepIteration. + */ + inline int getTimestepIteration() { + return timestepIteration; + }; + + /** \brief + * Increments \ref timestepIteration by 1; + */ + inline void incTimestepIteration() { + timestepIteration++; + }; + + /** \brief + * Returns \ref maxTimestepIteration. + */ + inline int getMaxTimestepIteration() { + return maxTimestepIteration; + }; + + /** \brief + * Sets \ref maxTimestepIteration. + */ + inline void setMaxTimestepIteration(int it) { + maxTimestepIteration = it; + }; + + /** \brief + * Sets \ref timeIteration. + */ + inline void setTimeIteration(int it) { + timeIteration = it; + }; + + /** \brief + * Returns \ref timeIteration. + */ + inline int getTimeIteration() { + return timeIteration; + }; + + /** \brief + * Increments \ref timesIteration by 1; + */ + inline void incTimeIteration() { + timeIteration++; + }; + + /** \brief + * Returns \ref maxTimeIteration. + */ + inline int getMaxTimeIteration() { + return maxTimeIteration; + }; + + /** \brief + * Sets \ref maxTimeIteration. + */ + inline void setMaxTimeIteration(int it) { + maxTimeIteration = it; + }; + + /** \brief + * Returns \ref timestepNumber. + */ + inline int getTimestepNumber() { + return timestepNumber; + }; + + /** \brief + * Increments \ref timestepNumber by 1; + */ + inline void incTimestepNumber() { + timestepNumber++; + }; + + /** \brief + * Sets \ref est_sum. + */ + inline void setEstSum(double e, int index) { + scalContents[index]->est_sum = e; + }; + + /** \brief + * Sets \ref est_max. + */ + inline void setEstMax(double e, int index) { + scalContents[index]->est_max = e; + }; + + /** \brief + * Sets \ref est_max. + */ + inline void setTimeEstMax(double e, int index) { + scalContents[index]->est_t_max = e; + }; + + /** \brief + * Sets \ref est_t_sum. + */ + inline void setTimeEstSum(double e, int index) { + scalContents[index]->est_t_sum = e; + }; + + /** \brief + * Returns \ref est_sum. + */ + inline double getEstSum(int index) { + return scalContents[index]->est_sum; + }; + + /** \brief + * Returns \ref est_max. + */ + inline double getEstMax(int index) { + return scalContents[index]->est_max; + }; + + /** \brief + * Returns \ref est_max. + */ + inline double getTimeEstMax(int index) { + return scalContents[index]->est_t_max; + }; + + /** \brief + * Returns \ref est_t_sum. + */ + inline double getTimeEstSum(int index) { + return scalContents[index]->est_t_sum; + }; + + /** \brief + * Returns \ref spaceTolerance. + */ + inline double getSpaceTolerance(int index) { + return scalContents[index]->spaceTolerance; + }; + + /** \brief + * Sets \ref spaceTolerance. + */ + inline void setSpaceTolerance(int index, double tol) { + scalContents[index]->spaceTolerance = tol; + }; + + /** \brief + * Returns \ref timeTolerance. + */ + inline double getTimeTolerance(int index) { + return scalContents[index]->timeTolerance; + }; + + /** \brief + * Sets \ref time + */ + inline double setTime(double t) { + time = t; + if (time > endTime) time = endTime; + if (time < startTime) time = startTime; + return time; + }; + + /** \brief + * Gets \ref time + */ + inline double getTime() { + return time; + }; + + /** \brief + * Gets \ref &time + */ + inline double *getTimePtr() { + return &time; + }; + + /** \brief + * Sets \ref timestep + */ + inline double setTimestep(double t) { + timestep = t; + if (timestep > maxTimestep) timestep = maxTimestep; + if (timestep < minTimestep) timestep = minTimestep; + if (time + timestep > endTime) timestep = endTime - time; + return timestep; + }; + + /** \brief + * Gets \ref timestep + */ + inline double getTimestep() { + return timestep; + }; + + /** \brief + * Sets \ref minTimestep + */ + inline void setMinTimestep(double t) { + minTimestep = t; + }; + + /** \brief + * Gets \ref minTimestep + */ + inline double getMinTimestep() { + return minTimestep; + }; + + /** \brief + * Sets \ref maxTimestep + */ + inline void setMaxTimestep(double t) { + maxTimestep = t; + }; + + /** \brief + * Gets \ref maxTimestep + */ + inline double getMaxTimestep() { + return maxTimestep; + }; + + /** \brief + * Gets \ref ×tep + */ + inline double *getTimestepPtr() { + return ×tep; + }; + + /** \brief + * Sets \ref startTime = time + */ + inline void setStartTime(double time) { + startTime = time; + }; + + /** \brief + * Sets \ref endTime = time + */ + inline void setEndTime(double time) { + endTime = time; + }; + + /** \brief + * Returns \ref startTime + */ + inline double getStartTime() { + return startTime; + }; + + /** \brief + * Returns \ref endTime + */ + inline double getEndTime() { + return endTime; + }; + + /** \brief + * Returns \ref timeErrLow. + */ + inline double getTimeErrLow(int index) { + return scalContents[index]->timeErrLow; + }; + + /** \brief + * Returns whether coarsening is allowed or not. + */ + inline bool isCoarseningAllowed(int index) { + return (scalContents[index]->coarsenAllowed == 1); + }; + + /** \brief + * Returns whether coarsening is allowed or not. + */ + inline bool isRefinementAllowed(int index) { + return (scalContents[index]->refinementAllowed == 1); + }; + + /** \brief + * + */ + inline void allowRefinement(bool allow, int index) { + scalContents[index]->refinementAllowed = allow; + }; + + /** \brief + * + */ + inline void allowCoarsening(bool allow, int index) { + scalContents[index]->coarsenAllowed = allow; + }; + + /** \brief + * Returns \ref refineBisections + */ + inline const int getRefineBisections(int index) const { + return scalContents[index]->refineBisections; + }; + + /** \brief + * Returns \ref coarseBisections + */ + inline const int getCoarseBisections(int index) const { + return scalContents[index]->coarseBisections; + }; + + inline int getSize() { + return scalContents.getSize(); + }; + + inline void setSolverIterations(int it) { + solverIterations = it; + }; + + inline int getSolverIterations() { + return solverIterations; + }; + + inline void setMaxSolverIterations(int it) { + maxSolverIterations = it; + }; + + inline int getMaxSolverIterations() { + return maxSolverIterations; + }; + + inline void setSolverTolerance(double tol) { + solverTolerance = tol; + }; + + inline double getSolverTolerance() { + return solverTolerance; + }; + + inline void setSolverResidual(double res) { + solverResidual = res; + }; + + inline double getSolverResidual() { + return solverResidual; + }; + + /** \brief + * Creates new scalContents with the given size. + */ + void setScalContents(int newSize); + + // ===== Serialiazable implementation ===== + void serialize(::std::ostream& out); + + void deserialize(::std::istream& in); + + protected: + /** \brief + * Name. + */ + ::std::string name; + + /** \brief + * Current space iteration + */ + int spaceIteration; + + /** \brief + * maximal allowed number of iterations of the adaptive procedure; if + * maxIteration <= 0, no iteration bound is used + */ + int maxSpaceIteration; + + /** \brief + * Current timestep iteration + */ + int timestepIteration; + + /** \brief + * Maximal number of iterations for choosing a timestep + */ + int maxTimestepIteration; + + /** \brief + * Current time iteration + */ + int timeIteration; + + /** \brief + * Maximal number of time iterations + */ + int maxTimeIteration; + + /** \brief + * Actual time, end of time interval for current time step + */ + double time; + + /** \brief + * Initial time + */ + double startTime; + + /** \brief + * Final time + */ + double endTime; + + /** \brief + * Current time step size + */ + double timestep; + + /** \brief + * Minimal step size + */ + double minTimestep; + + /** \brief + * Maximal step size + */ + double maxTimestep; + + /** \brief + * Number of current time step + */ + int timestepNumber; + + /** \brief + * number of iterations needed of linear or nonlinear solver + */ + int solverIterations; + + + /** \brief + * maximal number of iterations needed of linear or nonlinear solver + */ + int maxSolverIterations; + + double solverTolerance; + + double solverResidual; + + /** \brief + * Scalar adapt infos. + */ + Vector<ScalContent*> scalContents; + }; + +} + +#endif // AMDIS_ADAPTINFO_H diff --git a/AMDiS/src/AdaptInstationary.cc b/AMDiS/src/AdaptInstationary.cc new file mode 100644 index 0000000000000000000000000000000000000000..3d83ab1e358373d375b282b65d1df12c0f4835bf --- /dev/null +++ b/AMDiS/src/AdaptInstationary.cc @@ -0,0 +1,308 @@ +#include "AdaptInstationary.h" +#include "Parameters.h" +#include "Estimator.h" +#include "TecPlotWriter.h" +#include "ProblemIterationInterface.h" +#include "ProblemTimeInterface.h" +#include "Serializer.h" + +namespace AMDiS { + + AdaptInstationary::AdaptInstationary(const char *name, + ProblemIterationInterface *problemStat, + AdaptInfo *info, + ProblemTimeInterface *problemInstat, + AdaptInfo *initialInfo, + time_t initialTimestamp) + : AdaptBase(name, problemStat, info, problemInstat, initialInfo), + breakWhenStable(0), + isDeserialized_(false) + { + FUNCNAME("AdaptInstationary::AdaptInstationary()"); + + initialize(name_); + + fixedTimestep_ = (info->getMinTimestep() == info->getMaxTimestep()); + + if (initialTimestamp == 0) { + initialTimestamp_ = time(NULL); + } else { + initialTimestamp_ = initialTimestamp; + } + + // Check if the problem should be deserialized because of the -rs parameter. + ::std::string serializationFilename = ""; + GET_PARAMETER(0, "argv->rs", &serializationFilename); + + if (serializationFilename.compare("")) { + // The value of the -rs argument is ignored, because we want to use the + // serialization file mentioned in the used init file. + MSG("Deserialization from file: %s\n", queueSerializationFilename_.c_str()); + + ::std::ifstream in(queueSerializationFilename_.c_str()); + deserialize(in); + in.close(); + + isDeserialized_ = true; + } else { + int readSerialization = 0; + int readSerializationWithAdaptInfo = 0; + + GET_PARAMETER(0, (*problemStat).getName() + "->input->read serialization", "%d", + &readSerialization); + GET_PARAMETER(0, (*problemStat).getName() + "->input->serialization with adaptinfo", "%d", + &readSerializationWithAdaptInfo); + + if (readSerialization && readSerializationWithAdaptInfo) { + ::std::string serializationFilename = ""; + + GET_PARAMETER(0, (*problemStat).getName() + "->input->serialization filename", + &serializationFilename); + TEST_EXIT(serializationFilename != "")("no serialization file\n"); + + MSG("Deserialization with AdaptInfo from file: %s\n", serializationFilename.c_str()); + ::std::ifstream in(serializationFilename.c_str()); + deserialize(in); + in.close(); + } + } + } + + AdaptInstationary::~AdaptInstationary() + { + } + + void AdaptInstationary::explicitTimeStrategy() + { + FUNCNAME("AdaptInstationary::explicitTimeStrategy()"); + + // estimate before first adaption + if (adaptInfo_->getTime() <= adaptInfo_->getStartTime()) { + problemIteration_->oneIteration(adaptInfo_, ESTIMATE); + } + + // increment time + adaptInfo_->setTime(adaptInfo_->getTime() + adaptInfo_->getTimestep()); + + problemTime_->setTime(adaptInfo_); + + INFO(info_,6)("time = %e, timestep = %e\n", + adaptInfo_->getTime(), adaptInfo_->getTimestep()); + + adaptInfo_->setSpaceIteration(0); + + // do the iteration + problemIteration_->beginIteration(adaptInfo_); + problemIteration_->oneIteration(adaptInfo_, FULL_ITERATION); + problemIteration_->endIteration(adaptInfo_); + } + + void AdaptInstationary::implicitTimeStrategy() + { + FUNCNAME("AdaptInstationary::implicitTimeStrategy()"); + + do { + adaptInfo_->setTime(adaptInfo_->getTime() + adaptInfo_->getTimestep()); + problemTime_->setTime(adaptInfo_); + + INFO(info_,6)("time = %e, try timestep = %e\n", + adaptInfo_->getTime(), adaptInfo_->getTimestep()); + + problemIteration_->oneIteration(adaptInfo_, NO_ADAPTION); + + adaptInfo_->incTimestepIteration(); + + if(!fixedTimestep_ && + !adaptInfo_->timeToleranceReached() && + !adaptInfo_->getTimestep() <= adaptInfo_->getMinTimestep()) + { + adaptInfo_->setTime(adaptInfo_->getTime() - adaptInfo_->getTimestep()); + adaptInfo_->setTimestep(adaptInfo_->getTimestep() * time_delta_1); + continue; + } + + adaptInfo_->setSpaceIteration(0); + + do { + problemIteration_->beginIteration(adaptInfo_); + + if(problemIteration_->oneIteration(adaptInfo_, FULL_ITERATION)) { + if(!fixedTimestep_ && + !adaptInfo_->timeToleranceReached() && + !adaptInfo_->getTimestep() <= adaptInfo_->getMinTimestep()) + { + adaptInfo_->setTime(adaptInfo_->getTime() - adaptInfo_->getTimestep()); + adaptInfo_->setTimestep(adaptInfo_->getTimestep() * time_delta_1); + problemIteration_->endIteration(adaptInfo_); + adaptInfo_->incSpaceIteration(); + break; + } + } + + adaptInfo_->incSpaceIteration(); + problemIteration_->endIteration(adaptInfo_); + + } while(!adaptInfo_->spaceToleranceReached() && + adaptInfo_->getSpaceIteration() <= adaptInfo_->getMaxSpaceIteration()); + } while(!adaptInfo_->timeToleranceReached() && + !adaptInfo_->getTimestep() <= adaptInfo_->getMinTimestep() && + adaptInfo_->getTimestepIteration() <= adaptInfo_->getMaxTimestepIteration()); + + if(!fixedTimestep_ && adaptInfo_->timeErrorLow()) { + adaptInfo_->setTimestep(adaptInfo_->getTimestep() *time_delta_2); + } + } + + void AdaptInstationary::oneTimestep() + { + FUNCNAME("AdaptInstationary::oneTimestep"); + + adaptInfo_->setTimestepIteration(0); + + switch(strategy) + { + case 0: + explicitTimeStrategy(); + break; + case 1: + implicitTimeStrategy(); + break; + default: + MSG("unknown strategy = %d; use explicit strategy\n", strategy); + explicitTimeStrategy(); + } + + adaptInfo_->incTimestepNumber(); + } + + int AdaptInstationary::adapt() + { + FUNCNAME("AdaptInstationary::adapt()"); + + int errorCode = 0; + + TEST_EXIT(adaptInfo_->getTimestep() >= adaptInfo_->getMinTimestep()) + ("timestep < min timestep\n"); + TEST_EXIT(adaptInfo_->getTimestep() <= adaptInfo_->getMaxTimestep()) + ("timestep > max timestep\n"); + + TEST_EXIT(adaptInfo_->getTimestep() > 0)("timestep <= 0!\n"); + + if (adaptInfo_->getTimestepNumber() == 0) { + adaptInfo_->setTime(adaptInfo_->getStartTime()); + initialAdaptInfo_->setStartTime(adaptInfo_->getStartTime()); + initialAdaptInfo_->setTime(adaptInfo_->getStartTime()); + + problemTime_->setTime(adaptInfo_); + + // initial adaption + problemTime_->solveInitialProblem(initialAdaptInfo_); + problemTime_->transferInitialSolution(adaptInfo_); + } + + while (adaptInfo_->getTime() < adaptInfo_->getEndTime() - DBL_TOL) { + iterationTimestamp_ = time(NULL); + + problemTime_->initTimestep(adaptInfo_); + oneTimestep(); + problemTime_->closeTimestep(adaptInfo_); + + if(breakWhenStable && (adaptInfo_->getSolverIterations() == 0)) { + break; + } + + // Check if there is a runtime limitation. If there is a runtime limitation + // and there is no more time for a next adaption loop, than return the error + // code for rescheduling the problem and break the adaption loop. + if (checkQueueRuntime()) { + errorCode = RescheduleErrorCode; + break; + } + } + + return errorCode; + } + + void AdaptInstationary::initialize(const ::std::string& aName) + { + FUNCNAME("AdaptInstationary::initialize()"); + + strategy = 0; + time_delta_1 = 0.7071; + time_delta_2 = 1.4142; + queueRuntime_ = -1; + queueSerializationFilename_ = "__serialized_problem.ser"; + + GET_PARAMETER(0, aName + "->strategy", "%d", &strategy); + GET_PARAMETER(0, aName + "->time delta 1", "%f", &time_delta_1); + GET_PARAMETER(0, aName + "->time delta 2", "%f", &time_delta_2); + GET_PARAMETER(0, aName + "->info", "%d", &info_); + GET_PARAMETER(0, aName + "->break when stable", "%d", &breakWhenStable); + GET_PARAMETER(0, aName + "->queue->runtime", "%d", &queueRuntime_); + GET_PARAMETER(0, aName + "->queue->serialization filename", &queueSerializationFilename_); + + return; + } + + void AdaptInstationary::serialize(::std::ostream &out) + { + FUNCNAME("AdaptInstationary::serialize()"); + + problemIteration_->serialize(out); + adaptInfo_->serialize(out); + if (problemTime_) { + problemTime_->serialize(out); + } + } + + void AdaptInstationary::deserialize(::std::istream &in) + { + FUNCNAME("AdaptInstationary::deserialize()"); + + problemIteration_->deserialize(in); + adaptInfo_->deserialize(in); + if (problemTime_) { + problemTime_->deserialize(in); + } + } + + + bool AdaptInstationary::checkQueueRuntime() + { + // If there is no time limited runtime queue, there is also nothing to check. + if (queueRuntime_ == -1) { + return false; + } + + // Get the current time. + time_t currentTimestamp = time(NULL); + + // Update list with the last iteration runtimes. + lastIterationsDuration_.push(currentTimestamp - iterationTimestamp_); + // The list should not contain more than 5 elements. If so, delete the oldest one. + if (lastIterationsDuration_.size() > 5) { + lastIterationsDuration_.pop(); + } + + // Calculate the avarage of the last iterations. + ::std::queue<int> tmpQueue = lastIterationsDuration_; + int avrgLastIterations = 0; + while (!tmpQueue.empty()) { + avrgLastIterations += tmpQueue.front(); + tmpQueue.pop(); + } + avrgLastIterations /= lastIterationsDuration_.size(); + + // Check if there is enough time for a further iteration. + if (initialTimestamp_ + queueRuntime_ - currentTimestamp < avrgLastIterations * 2) { + ::std::ofstream out(queueSerializationFilename_.c_str()); + serialize(out); + out.close(); + + return true; + } + + return false; + } + +} diff --git a/AMDiS/src/AdaptInstationary.h b/AMDiS/src/AdaptInstationary.h new file mode 100644 index 0000000000000000000000000000000000000000..1e08cfb0548156f3d9819161ffee7bbe23625da0 --- /dev/null +++ b/AMDiS/src/AdaptInstationary.h @@ -0,0 +1,206 @@ +// ============================================================================ +// == == +// == AMDiS - Adaptive multidimensional simulations == +// == == +// ============================================================================ +// == == +// == crystal growth group == +// == == +// == Stiftung caesar == +// == Ludwig-Erhard-Allee 2 == +// == 53175 Bonn == +// == germany == +// == == +// ============================================================================ +// == == +// == http://www.caesar.de/cg/AMDiS == +// == == +// ============================================================================ + +/** \file AdaptInstationary.h */ + +#ifndef AMDIS_ADAPTINSTATIONARY_H +#define AMDIS_ADAPTINSTATIONARY_H + +#include <string> +#include <ctime> +#include <queue> +#include "Flag.h" +#include "MemoryManager.h" +#include "AdaptInfo.h" +#include "AdaptBase.h" + +namespace AMDiS { + + class ProblemIterationInterface; + class ProblemTimeInterface; + + // ============================================================================ + // ===== class AdaptInstationary ============================================== + // ============================================================================ + + /** \ingroup Adaption + * \brief + * AdaptInstationary implements the adaptive procdure for time dependent + * problems (see ProblemInstat). It contains a pointer to a ProblemInstat + * object. + */ + class AdaptInstationary : public AdaptBase + { + public: + MEMORY_MANAGED(AdaptInstationary); + + /** \brief + * Creates a AdaptInstationary object with the given name for the time + * dependent problem problemInstat. + */ + AdaptInstationary(const char *name_, + ProblemIterationInterface *problemStat, + AdaptInfo *info, + ProblemTimeInterface *problemInstat, + AdaptInfo *initialInfo, + time_t initialTimestamp = 0); + + /** \brief + * Destructor + */ + virtual ~AdaptInstationary(); + + /** \brief + * Sets \ref strategy to aStrategy + */ + inline void setStrategy(int aStrategy) { + strategy = aStrategy; + }; + + /** \brief + * Returns \ref strategy + */ + const int getStrategy() const { + return strategy; + }; + + /** \brief + * Returns true, if the adaptive procedure was deserialized from a file. + */ + const bool isDeserialized() const { + return isDeserialized_; + } + + /** \brief + * Implementation of AdaptBase::adapt() + */ + virtual int adapt(); + + /** \brief + * serialization + */ + virtual void serialize(::std::ostream &out); + + /** \brief + * deserialization + */ + virtual void deserialize(::std::istream &in); + + + protected: + /** \brief + * Implements one (maybe adaptive) timestep. Both the explicit and the + * implicit time strategy are implemented. The semi-implicit strategy + * is only a special case of the implicit strategy with a limited number of + * iterations (exactly one). + * The routine uses the parameter \ref strategy to select the strategy: + * strategy 0: Explicit strategy, + * strategy 1: Implicit strategy. + */ + virtual void oneTimestep(); + + /** \brief + * Initialisation of this AdaptInstationary object + */ + void initialize(const ::std::string& aName); + + /** \brief + * Implements the explit time strategy. Used by \ref oneTimestep(). + */ + virtual void explicitTimeStrategy(); + + /** \brief + * Implements the implicit time strategy. Used by \ref oneTimestep(). + */ + virtual void implicitTimeStrategy(); + + /** \brief + * Checks whether the runtime of the queue (of the servers batch system) requires + * to stop the calculation and to reschedule the problem to the batch system. + * + * The function return true, if there will be a timeout in the near future, and + * therefore the problem should be rescheduled. Otherwise, the return value is + * false. + */ + bool checkQueueRuntime(); + + protected: + /** \brief + * Strategy for choosing one timestep + */ + int strategy; + + /** \brief + * Parameter \f$ \delta_1 \f$ used in time step reduction + */ + double time_delta_1; + + /** \brief + * Parameter \f$ \delta_2 \f$ used in time step enlargement + */ + double time_delta_2; + + /** \brief + * If this parameter is 1 and the instationary problem is stable, hence the number + * of solver iterations to solve the problem is zero, the adaption loop will stop. + */ + int breakWhenStable; + + /** \brief + * + */ + bool fixedTimestep_; + + /** \brief + * Runtime of the queue (of the servers batch system) in seconds. If the problem + * runs on a computer/server without a time limited queue, the value is -1. + */ + int queueRuntime_; + + /** \brief + * Name of the file used to automatically serialize the problem. + */ + ::std::string queueSerializationFilename_; + + /** \brief + * Timestamp at the beginning of all calculations. It is used to calculate the overall + * runtime of the problem. + */ + time_t initialTimestamp_; + + /** \brief + * Timestamp at the beginning of the last timestep iteration. Is is used to calculate + * the runtime of the last timestep. + */ + time_t iterationTimestamp_; + + /** \brief + * Stores the runtime (in seconds) of some last timestep iterations. + */ + ::std::queue<int> lastIterationsDuration_; + + /** \brief + * Is true, if the adaptive procedure was deserialized from a file. + */ + bool isDeserialized_; + }; + +} + +#endif // AMDIS_ADAPTINSTATIONARY_H diff --git a/AMDiS/src/AdaptStationary.cc b/AMDiS/src/AdaptStationary.cc new file mode 100644 index 0000000000000000000000000000000000000000..458ee4a1dc13b4ae8bd62651b8bb15a0256396eb --- /dev/null +++ b/AMDiS/src/AdaptStationary.cc @@ -0,0 +1,55 @@ +#include "AdaptStationary.h" +#include "Parameters.h" +#include "Estimator.h" +#include "TecPlotWriter.h" +#include "ProblemIterationInterface.h" +#include <math.h> + +namespace AMDiS { + + AdaptStationary::AdaptStationary(const char *name, + ProblemIterationInterface *prob, + AdaptInfo *info) + : AdaptBase(name, prob, info) + { + initialize(); + } + + int AdaptStationary::adapt() + { + FUNCNAME("AdaptStationary::adapt()"); + + // initial iteration + if (adaptInfo_->getSpaceIteration() == -1) { + problemIteration_->beginIteration(adaptInfo_); + problemIteration_->oneIteration(adaptInfo_, NO_ADAPTION); + problemIteration_->endIteration(adaptInfo_); + adaptInfo_->incSpaceIteration(); + } + + // adaption loop + while(!adaptInfo_->spaceToleranceReached() && + (adaptInfo_->getSpaceIteration() < adaptInfo_->getMaxSpaceIteration() || + adaptInfo_->getMaxSpaceIteration() < 0) ) + { + problemIteration_->beginIteration(adaptInfo_); + Flag adapted = problemIteration_->oneIteration(adaptInfo_, FULL_ITERATION); + problemIteration_->endIteration(adaptInfo_); + + if (!adapted) + break; + + adaptInfo_->incSpaceIteration(); + } + + return 0; + } + + void AdaptStationary::initialize() + { + FUNCNAME("AdaptStationary::initialize()"); + + GET_PARAMETER(0, name_ + "->info", "%d", &info_); + } + +} diff --git a/AMDiS/src/AdaptStationary.h b/AMDiS/src/AdaptStationary.h new file mode 100644 index 0000000000000000000000000000000000000000..9b457e3705c2db2a9bcba5c03c0c82381cb6f327 --- /dev/null +++ b/AMDiS/src/AdaptStationary.h @@ -0,0 +1,84 @@ +// ============================================================================ +// == == +// == AMDiS - Adaptive multidimensional simulations == +// == == +// ============================================================================ +// == == +// == crystal growth group == +// == == +// == Stiftung caesar == +// == Ludwig-Erhard-Allee 2 == +// == 53175 Bonn == +// == germany == +// == == +// ============================================================================ +// == == +// == http://www.caesar.de/cg/AMDiS == +// == == +// ============================================================================ + +/** \file AdaptStationary.h */ + +/** \defgroup Adaption Adaption module + * @{ <img src="adaption.png"> @} + * + * \brief + * Contains all classes needed for adaption. + */ + +#ifndef AMDIS_ADPATSTATIONARY_H +#define AMDIS_ADPATSTATIONARY_H + +#include <string> +#include "Flag.h" +#include "MemoryManager.h" +#include "AdaptInfo.h" +#include "AdaptBase.h" + +namespace AMDiS { + + class Element; + template <typename T> class OEMSolver; + class ProblemIterationInterface; + + // ============================================================================ + // ===== class AdaptStationary ================================================ + // ============================================================================ + + /** \ingroup Adaption + * \brief + * AdaptStationary contains information about the adaptive procedure and the + * adapt procedure itself + */ + class AdaptStationary : public AdaptBase + { + public: + MEMORY_MANAGED(AdaptStationary); + + /** \brief + * Creates a AdaptStationary object with given name. + */ + AdaptStationary(const char *name, + ProblemIterationInterface *prob, + AdaptInfo *info); + + /** \brief + * Destructor + */ + virtual ~AdaptStationary() {}; + + /** \brief + * Implementation of AdaptBase::adapt() + */ + virtual int adapt(); + + protected: + /** \brief + * Initialisation + */ + void initialize(); + }; + +} + +#endif // AMDIS_ADPATSTATIONARY_H diff --git a/AMDiS/src/Assembler.cc b/AMDiS/src/Assembler.cc new file mode 100644 index 0000000000000000000000000000000000000000..9405f7745fb89415c438f6e84c288ea84dd8b267 --- /dev/null +++ b/AMDiS/src/Assembler.cc @@ -0,0 +1,1869 @@ +#include "Assembler.h" +#include "Operator.h" +#include "Element.h" +#include "QPsiPhi.h" +#include "ElementMatrix.h" +#include "ElementVector.h" +#include "DOFVector.h" +#include <vector> +#include <algorithm> + +namespace AMDiS { + + ::std::vector<SubAssembler*> ZeroOrderAssembler::optimizedSubAssemblers; + ::std::vector<SubAssembler*> FirstOrderAssembler::optimizedSubAssemblersGrdPhi; + ::std::vector<SubAssembler*> FirstOrderAssembler::optimizedSubAssemblersGrdPsi; + ::std::vector<SubAssembler*> SecondOrderAssembler::optimizedSubAssemblers; + + ::std::vector<SubAssembler*> ZeroOrderAssembler::standardSubAssemblers; + ::std::vector<SubAssembler*> FirstOrderAssembler::standardSubAssemblersGrdPhi; + ::std::vector<SubAssembler*> FirstOrderAssembler::standardSubAssemblersGrdPsi; + ::std::vector<SubAssembler*> SecondOrderAssembler::standardSubAssemblers; + + SubAssembler::SubAssembler(Operator *op, + Assembler *assembler, + Quadrature *quadrat, + int order, + bool optimized, + FirstOrderType type) + : nRow(0), + nCol(0), + coordsAtQPs(NULL), + quadrature(quadrat), + psiFast(NULL), + phiFast(NULL), + owner(assembler), + symmetric(true), + opt(optimized), + firstCall(true) + { + int i; + + const BasisFunction *psi = assembler->rowFESpace->getBasisFcts(); + const BasisFunction *phi = assembler->colFESpace->getBasisFcts(); + + nRow = psi->getNumber(); + nCol = phi->getNumber(); + + switch(order) { + case 0: + terms = op->zeroOrder; + break; + case 1: + if(type == GRD_PHI) + terms = op->firstOrderGrdPhi; + else + terms = op->firstOrderGrdPsi; + break; + case 2: + terms = op->secondOrder; + break; + } + + // check if all terms are symmetric + symmetric = true; + for(i=0; i < static_cast<int>(terms.size()); i++) { + if(!(terms[i])->isSymmetric()) { + symmetric = false; + break; + } + } + + dim = assembler->rowFESpace->getMesh()->getDim(); + // // create quadrature + // if(!quadrature) { + // dim = assembler->rowFESpace->getMesh()->getDim(); + // int degree = op->getQuadratureDegree(order, type); + // quadrature = Quadrature::provideQuadrature(dim, degree); + // } + } + + FastQuadrature *SubAssembler::updateFastQuadrature(FastQuadrature *quadFast, + const BasisFunction *psi, + Flag updateFlag) + { + if(!quadFast) { + quadFast = + FastQuadrature::provideFastQuadrature(psi, + *quadrature, + updateFlag); + } else { + if(!quadFast->initialized(updateFlag)) + quadFast->init(updateFlag); + } + + return quadFast; + } + + void SubAssembler::initElement(const ElInfo* elInfo, + Quadrature *quad) + { + // set corrdsAtQPs invalid + coordsValid = false; + + // set values at QPs invalid + ::std::map<const DOFVectorBase<double>*, ValuesAtQPs*>::iterator it1; + for(it1 = valuesAtQPs.begin(); it1 != valuesAtQPs.end(); ++it1) { + ((*it1).second)->valid = false; + } + + // set gradients at QPs invalid + ::std::map<const DOFVectorBase<double>*, GradientsAtQPs*>::iterator it2; + for(it2 = gradientsAtQPs.begin(); it2 != gradientsAtQPs.end(); ++it2) { + ((*it2).second)->valid = false; + } + + // calls initElement of each term + ::std::vector<OperatorTerm*>::iterator it; + for(it = terms.begin(); it != terms.end(); ++it) { + (*it)->initElement(elInfo, this, quad); + } + } + + WorldVector<double>* SubAssembler::getCoordsAtQPs(const ElInfo* elInfo, + Quadrature *quad) + { + Quadrature *localQuad = quad ? quad : quadrature; + + const int numPoints = localQuad->getNumPoints(); + + // already calculated for this element ? + if(coordsValid) { + return coordsAtQPs; + } + + // not yet calcualted ! + if(coordsAtQPs) DELETE [] coordsAtQPs; + // allocate memory + coordsAtQPs = NEW WorldVector<double>[numPoints]; + + // set new values + WorldVector<double>* k = NULL; + int l; + for(k=&(coordsAtQPs[0]), l=0; k < &(coordsAtQPs[numPoints]); ++k, ++l) { + elInfo->coordToWorld(localQuad->getLambda(l), k); + } + + // mark values as valid + coordsValid = true; + + return coordsAtQPs; + } + + double* SubAssembler::getVectorAtQPs(DOFVectorBase<double>* dv, + const ElInfo* elInfo, + Quadrature *quad) + { + FUNCNAME("SubAssembler::getVectorAtQPs()"); + + const DOFVectorBase<double>* vec = dv ? dv : owner->operat->getUhOld(); + + TEST_EXIT(vec)("no dof vector!\n"); + + if(valuesAtQPs[vec] && valuesAtQPs[vec]->valid) + return valuesAtQPs[vec]->values.getValArray(); + + Quadrature *localQuad = quad ? quad : quadrature; + + if(!valuesAtQPs[vec]) { + valuesAtQPs[vec] = new ValuesAtQPs; + } + valuesAtQPs[vec]->values.resize(localQuad->getNumPoints()); + + double *values = valuesAtQPs[vec]->values.getValArray(); + + bool sameFESpaces = + (vec->getFESpace() == owner->rowFESpace) || + (vec->getFESpace() == owner->colFESpace); + + if(opt && !quad && sameFESpaces) { + const BasisFunction *psi = owner->rowFESpace->getBasisFcts(); + const BasisFunction *phi = owner->colFESpace->getBasisFcts(); + if(vec->getFESpace()->getBasisFcts() == psi) { + psiFast = updateFastQuadrature(psiFast, psi, INIT_PHI); + } else if(vec->getFESpace()->getBasisFcts() == phi) { + phiFast = updateFastQuadrature(phiFast, phi, INIT_PHI); + } + } + + // calculate new values + const BasisFunction *basFcts = vec->getFESpace()->getBasisFcts(); + + //double* uhLoc = GET_MEMORY(double, basFcts->getNumber()); + //vec->getLocalVector(elInfo->getElement(), uhLoc); + + if(opt && !quad && sameFESpaces) { + if(psiFast->getBasisFunctions() == basFcts) { + //psiFast->uhAtQp(uhLoc, values); + vec->getVecAtQPs(elInfo, NULL, psiFast, values); + } else if(phiFast->getBasisFunctions() == basFcts) { + //phiFast->uhAtQp(uhLoc, values); + vec->getVecAtQPs(elInfo, NULL, phiFast, values); + } else { + vec->getVecAtQPs(elInfo, localQuad, NULL, values); + } + } else { + //localQuad->uhAtQp(basFcts, uhLoc, values); + vec->getVecAtQPs(elInfo, localQuad, NULL, values); + } + + //FREE_MEMORY(uhLoc, double, basFcts->getNumber()); + + valuesAtQPs[vec]->valid = true; + + // return values + return values; + } + + WorldVector<double>* SubAssembler::getGradientsAtQPs(DOFVectorBase<double>* dv, + const ElInfo* elInfo, + Quadrature *quad) + { + FUNCNAME("SubAssembler::getGradientsAtQPs()"); + + const DOFVectorBase<double>* vec = dv ? dv : owner->operat->getUhOld(); + + TEST_EXIT(vec)("no dof vector!\n"); + + if(gradientsAtQPs[vec] && gradientsAtQPs[vec]->valid) + return gradientsAtQPs[vec]->values.getValArray(); + + Quadrature *localQuad = quad ? quad : quadrature; + + if(!gradientsAtQPs[vec]) { + gradientsAtQPs[vec] = new GradientsAtQPs; + } + gradientsAtQPs[vec]->values.resize(localQuad->getNumPoints()); + + WorldVector<double> *values = gradientsAtQPs[vec]->values.getValArray(); + + const BasisFunction *psi = owner->rowFESpace->getBasisFcts(); + const BasisFunction *phi = owner->colFESpace->getBasisFcts(); + + bool sameFESpaces = + (vec->getFESpace() == owner->rowFESpace) || + (vec->getFESpace() == owner->colFESpace); + + if(opt && !quad && sameFESpaces) { + if(vec->getFESpace()->getBasisFcts() == psi) { + psiFast = updateFastQuadrature(psiFast, psi, INIT_GRD_PHI); + } else if(vec->getFESpace()->getBasisFcts() == phi) { + phiFast = updateFastQuadrature(phiFast, phi, INIT_GRD_PHI); + } + } + + // calculate new values + //const DimVec<WorldVector<double> > &Lambda = elInfo->getGrdLambda(); + const BasisFunction *basFcts = vec->getFESpace()->getBasisFcts(); + //double* uhLoc = GET_MEMORY(double, basFcts->getNumber()); + + //vec->getLocalVector(elInfo->getElement(), uhLoc); + + if(opt && !quad && sameFESpaces) { + if(psiFast->getBasisFunctions() == basFcts) { + //psiFast->grdUhAtQp(Lambda, uhLoc, values); + vec->getGrdAtQPs(elInfo, NULL, psiFast, values); + } else { + //phiFast->grdUhAtQp(Lambda, uhLoc, values); + vec->getGrdAtQPs(elInfo, NULL, phiFast, values); + } + } else { + //localQuad->grdUhAtQp(basFcts, + // Lambda, + // uhLoc, + // values); + vec->getGrdAtQPs(elInfo, localQuad, NULL, values); + } + + //FREE_MEMORY(uhLoc, double, basFcts->getNumber()); + + gradientsAtQPs[vec]->valid = true; + + // return values + return values; + } + + ZeroOrderAssembler::ZeroOrderAssembler(Operator *op, + Assembler *assembler, + Quadrature *quad, + bool optimized) + : SubAssembler(op, assembler, quad, 0, optimized) + {} + + FirstOrderAssembler::FirstOrderAssembler(Operator *op, + Assembler *assembler, + Quadrature *quad, + bool optimized, + FirstOrderType type) + : SubAssembler(op, assembler, quad, 1, optimized, type) + {} + + SecondOrderAssembler::SecondOrderAssembler(Operator *op, + Assembler *assembler, + Quadrature *quad, + bool optimized) + : SubAssembler(op, assembler, quad, 2, optimized) + {} + + ZeroOrderAssembler* + ZeroOrderAssembler::getSubAssembler(Operator* op, + Assembler *assembler, + Quadrature *quad, + bool optimized) + { + int i; + + // check if a assembler is needed at all + if(op->zeroOrder.size() == 0) { + return NULL; + } + + ZeroOrderAssembler *newAssembler; + + ::std::vector<SubAssembler*> *subAssemblers = + optimized ? + &optimizedSubAssemblers : + &standardSubAssemblers; + + ::std::vector<OperatorTerm*> opTerms = op->zeroOrder; + + sort(opTerms.begin(), opTerms.end()); + + // check if a new assembler is needed + if(quad) { + for(i=0; i < static_cast<int>( subAssemblers->size()); i++) { + ::std::vector<OperatorTerm*> assTerms = *((*subAssemblers)[i]->getTerms()); + + sort(assTerms.begin(), assTerms.end()); + + if((opTerms == assTerms) && + ((*subAssemblers)[i]->getQuadrature() == quad)) + { + return dynamic_cast<ZeroOrderAssembler*>((*subAssemblers)[i]); + } + } + } + + // check if all terms are pw_const + bool pwConst = true; + for(i=0; i < static_cast<int>( op->zeroOrder.size()); i++) { + if(!op->zeroOrder[i]->isPWConst()) { + pwConst = false; + break; + } + } + + // create new assembler + if(!optimized) { + newAssembler = NEW Stand0(op, assembler, quad); + } else { + if(pwConst) { + newAssembler = NEW Pre0(op, assembler, quad); + } else { + newAssembler = NEW Quad0(op, assembler, quad); + } + } + + subAssemblers->push_back(newAssembler); + return newAssembler; + } + + FirstOrderAssembler* + FirstOrderAssembler::getSubAssembler(Operator* op, + Assembler *assembler, + Quadrature *quad, + FirstOrderType type, + bool optimized) + { + int i; + + ::std::vector<SubAssembler*> *subAssemblers = + optimized ? + (type == GRD_PSI ? + &optimizedSubAssemblersGrdPsi : + &optimizedSubAssemblersGrdPhi) : + (type == GRD_PSI ? + &standardSubAssemblersGrdPsi : + &standardSubAssemblersGrdPhi); + + ::std::vector<OperatorTerm*> opTerms + = (type == GRD_PSI) ? op->firstOrderGrdPsi : op->firstOrderGrdPhi; + + // check if a assembler is needed at all + if(opTerms.size() == 0) { + return NULL; + } + + sort(opTerms.begin(), opTerms.end()); + + FirstOrderAssembler *newAssembler; + + // check if a new assembler is needed + for(i=0; i < static_cast<int>( subAssemblers->size()); i++) { + + ::std::vector<OperatorTerm*> assTerms = *((*subAssemblers)[i]->getTerms()); + + sort(assTerms.begin(), assTerms.end()); + + + + if((opTerms == assTerms) && + ((*subAssemblers)[i]->getQuadrature() == quad)) + { + return dynamic_cast<FirstOrderAssembler*>((*subAssemblers)[i]); + } + } + + // check if all terms are pw_const + bool pwConst = true; + for(i=0; i < static_cast<int>( opTerms.size()); i++) { + if(!(opTerms[i])->isPWConst()) { + pwConst = false; + break; + } + } + + // create new assembler + if(!optimized) { + newAssembler = + (type == GRD_PSI) ? + dynamic_cast<FirstOrderAssembler*>(NEW Stand10(op, assembler, quad)) : + dynamic_cast<FirstOrderAssembler*>(NEW Stand01(op, assembler, quad)); + } else { + if(pwConst) { + newAssembler = + (type == GRD_PSI) ? + dynamic_cast<FirstOrderAssembler*>(NEW Pre10(op, assembler, quad)) : + dynamic_cast<FirstOrderAssembler*>(NEW Pre01(op, assembler, quad)); + } else { + newAssembler = + (type == GRD_PSI) ? + dynamic_cast<FirstOrderAssembler*>( NEW Quad10(op, assembler, quad)) : + dynamic_cast<FirstOrderAssembler*>( NEW Quad01(op, assembler, quad)); + } + } + + subAssemblers->push_back(newAssembler); + return newAssembler; + }; + + SecondOrderAssembler* + SecondOrderAssembler::getSubAssembler(Operator* op, + Assembler *assembler, + Quadrature *quad, + bool optimized) + { + int i; + + // check if a assembler is needed at all + if(op->secondOrder.size() == 0) { + return NULL; + } + + SecondOrderAssembler *newAssembler; + + ::std::vector<SubAssembler*> *subAssemblers = + optimized ? + &optimizedSubAssemblers : + &standardSubAssemblers; + + ::std::vector<OperatorTerm*> opTerms = op->zeroOrder; + + sort(opTerms.begin(), opTerms.end()); + + // check if a new assembler is needed + for(i=0; i < static_cast<int>( subAssemblers->size()); i++) { + ::std::vector<OperatorTerm*> assTerms = *((*subAssemblers)[i]->getTerms()); + + sort(assTerms.begin(), assTerms.end()); + + if((opTerms == assTerms) && + ((*subAssemblers)[i]->getQuadrature() == quad)) + { + return dynamic_cast<SecondOrderAssembler*>((*subAssemblers)[i]); + } + } + + // check if all terms are pw_const + bool pwConst = true; + for(i=0; i < static_cast<int>( op->secondOrder.size()); i++) { + if(!op->secondOrder[i]->isPWConst()) { + pwConst = false; + break; + } + } + + // create new assembler + if(!optimized) { + newAssembler = NEW Stand2(op, assembler, quad); + } else { + if(pwConst) { + newAssembler = NEW Pre2(op, assembler, quad); + } else { + newAssembler = NEW Quad2(op, assembler, quad); + } + } + + subAssemblers->push_back(newAssembler); + return newAssembler; + } + + Stand0::Stand0(Operator *op, Assembler *assembler, Quadrature *quad) + : ZeroOrderAssembler(op, assembler, quad, false) + { + } + + void Stand0::calculateElementMatrix(const ElInfo *elInfo, ElementMatrix *mat) + { + int iq, i, j; + double val; + + const BasisFunction *psi = owner->getRowFESpace()->getBasisFcts(); + const BasisFunction *phi = owner->getColFESpace()->getBasisFcts(); + + double psival; + double *phival = GET_MEMORY(double, nCol); + + int numPoints = quadrature->getNumPoints(); + + double *c = GET_MEMORY(double, numPoints); + for (iq = 0; iq < numPoints; iq++) { + c[iq] = 0.0; + } + + ::std::vector<OperatorTerm*>::iterator termIt; + for(termIt = terms.begin(); termIt != terms.end(); ++termIt) { + (static_cast<ZeroOrderTerm*>((*termIt)))->getC(elInfo, numPoints, c); + } + + if (symmetric) { + for (iq = 0; iq < numPoints; iq++) { + c[iq] *= elInfo->getDet(); + + // calculate phi at QPs only once! + for(i=0; i < nCol; i++) { + phival[i] = (*(phi->getPhi(i)))(quadrature->getLambda(iq)); + } + + for (i = 0; i < nRow; i++) { + psival = (*(psi->getPhi(i)))(quadrature->getLambda(iq)); + (*mat)[i][i] += quadrature->getWeight(iq)*c[iq]*psival*phival[i]; + for (j = i+1; j < nCol; j++) { + val = quadrature->getWeight(iq)*c[iq]*psival*phival[j]; + (*mat)[i][j] += val; + (*mat)[j][i] += val; + } + } + } + } else { /* non symmetric assembling */ + for (iq = 0; iq < numPoints; iq++) { + c[iq] *= elInfo->getDet(); + + // calculate phi at QPs only once! + for(i=0; i < nCol; i++) { + phival[i] = (*(phi->getPhi(i)))(quadrature->getLambda(iq)); + } + + for (i = 0; i < nRow; i++) { + psival = (*(psi->getPhi(i)))(quadrature->getLambda(iq)); + for (j = 0; j < nCol; j++) { + (*mat)[i][j] += quadrature->getWeight(iq)*c[iq]*psival*phival[j]; + } + } + } + } + FREE_MEMORY(c, double, numPoints); + FREE_MEMORY(phival, double, nCol); + } + + void Stand0::calculateElementVector(const ElInfo *elInfo, ElementVector *vec) + { + double psi; + int iq, i; + + int numPoints = quadrature->getNumPoints(); + + double *c = GET_MEMORY(double, numPoints); + for (iq = 0; iq < numPoints; iq++) { + c[iq] = 0.0; + } + + ::std::vector<OperatorTerm*>::iterator termIt; + for(termIt = terms.begin(); termIt != terms.end(); ++termIt) { + (static_cast<ZeroOrderTerm*>((*termIt)))->getC(elInfo, numPoints, c); + } + + for (iq = 0; iq < numPoints; iq++) { + c[iq] *= elInfo->getDet(); + + for (i = 0; i < nRow; i++) { + psi = (*(owner->getRowFESpace()->getBasisFcts()->getPhi(i))) + (quadrature->getLambda(iq)); + (*vec)[i] += quadrature->getWeight(iq)*c[iq]*psi; + } + } + FREE_MEMORY(c, double, numPoints); + } + + Quad0::Quad0(Operator *op, Assembler *assembler, Quadrature *quad) + : ZeroOrderAssembler(op, assembler, quad, true) + { + // if(!psiFast) { + // psiFast = + // FastQuadrature::provideFastQuadrature(assembler-> + // getRowFESpace()->getBasisFcts(), + // *quadrature, + // INIT_PHI); + // } + // if(!phiFast) { + // phiFast = + // FastQuadrature::provideFastQuadrature(assembler-> + // getColFESpace()->getBasisFcts(), + // *quadrature, + // INIT_PHI); + // } + } + + void Quad0::calculateElementMatrix(const ElInfo *elInfo, ElementMatrix *mat) + { + const double *psi, *phi; + int iq, i, j; + double val; + + if(firstCall) { + const BasisFunction *basFcts = owner->getRowFESpace()->getBasisFcts(); + psiFast = updateFastQuadrature(psiFast, basFcts, INIT_PHI); + basFcts = owner->getColFESpace()->getBasisFcts(); + phiFast = updateFastQuadrature(phiFast, basFcts, INIT_PHI); + firstCall = false; + } + + int numPoints = quadrature->getNumPoints(); + + double *c = GET_MEMORY(double, numPoints); + for (iq = 0; iq < numPoints; iq++) { + c[iq] = 0.0; + } + + ::std::vector<OperatorTerm*>::iterator termIt; + for(termIt = terms.begin(); termIt != terms.end(); ++termIt) { + (static_cast<ZeroOrderTerm*>((*termIt)))->getC(elInfo, numPoints, c); + } + + if (symmetric) { + for (iq = 0; iq < numPoints; iq++) { + c[iq] *= elInfo->getDet(); + + psi = psiFast->getPhi(iq); + phi = phiFast->getPhi(iq); + for (i = 0; i < nRow; i++) { + (*mat)[i][i] += quadrature->getWeight(iq)*c[iq]*psi[i]*phi[i]; + for (j = i+1; j < nCol; j++) { + val = quadrature->getWeight(iq)*c[iq]*psi[i]*phi[j]; + (*mat)[i][j] += val; + (*mat)[j][i] += val; + } + } + } + } else { /* non symmetric assembling */ + for (iq = 0; iq < numPoints; iq++) { + c[iq] *= elInfo->getDet(); + + psi = psiFast->getPhi(iq); + phi = phiFast->getPhi(iq); + for (i = 0; i < nRow; i++) { + for (j = 0; j < nCol; j++) { + (*mat)[i][j] += quadrature->getWeight(iq)*c[iq]*psi[i]*phi[j]; + } + } + } + } + FREE_MEMORY(c, double, numPoints); + } + + void Quad0::calculateElementVector(const ElInfo *elInfo, ElementVector *vec) + { + const double *psi; + int iq, i; + + if(firstCall) { + const BasisFunction *basFcts = owner->getRowFESpace()->getBasisFcts(); + psiFast = updateFastQuadrature(psiFast, basFcts, INIT_PHI); + basFcts = owner->getColFESpace()->getBasisFcts(); + phiFast = updateFastQuadrature(phiFast, basFcts, INIT_PHI); + firstCall = false; + } + + int numPoints = quadrature->getNumPoints(); + + double *c = GET_MEMORY(double, numPoints); + for (iq = 0; iq < numPoints; iq++) { + c[iq] = 0.0; + } + + ::std::vector<OperatorTerm*>::iterator termIt; + for(termIt = terms.begin(); termIt != terms.end(); ++termIt) { + (static_cast<ZeroOrderTerm*>((*termIt)))->getC(elInfo, numPoints, c); + } + + for (iq = 0; iq < numPoints; iq++) { + c[iq] *= elInfo->getDet(); + + psi = psiFast->getPhi(iq); + for (i = 0; i < nRow; i++) { + (*vec)[i] += quadrature->getWeight(iq)*c[iq]*psi[i]; + } + } + FREE_MEMORY(c, double, numPoints); + } + + Pre0::Pre0(Operator *op, Assembler *assembler, Quadrature *quad) + : ZeroOrderAssembler(op, assembler, quad, true) + { + // q00 = Q00PsiPhi::provideQ00PsiPhi(assembler->getRowFESpace()->getBasisFcts(), + // assembler->getColFESpace()->getBasisFcts(), + // quadrature); + // q0 = Q0Psi::provideQ0Psi(assembler->getRowFESpace()->getBasisFcts(), + // quadrature); + } + + void Pre0::calculateElementMatrix(const ElInfo *elInfo, ElementMatrix *mat) + { + int i, j; + double val, *c = GET_MEMORY(double, 1); + + if(firstCall) { + q00 = Q00PsiPhi::provideQ00PsiPhi(owner->getRowFESpace()->getBasisFcts(), + owner->getColFESpace()->getBasisFcts(), + quadrature); + q0 = Q0Psi::provideQ0Psi(owner->getRowFESpace()->getBasisFcts(), + quadrature); + firstCall = false; + } + + c[0] = 0.0; + for(i=0; i < static_cast<int>( terms.size()); i++) { + (static_cast<ZeroOrderTerm*>((terms[i])))->getC(elInfo, 1, c); + } + + c[0] *= elInfo->getDet(); + + if (symmetric) { + for (i = 0; i < nRow; i++) { + (*mat)[i][i] += c[0]*q00->getValue(i,i); + for (j = i + 1; j < nCol; j++) { + val = c[0]*q00->getValue(i,j); + (*mat)[i][j] += val; + (*mat)[j][i] += val; + } + } + } else { + for (i = 0; i < nRow; i++) + for (j = 0; j < nCol; j++) + (*mat)[i][j] += c[0]*q00->getValue(i,j); + } + + FREE_MEMORY(c, double, 1); + } + + void Pre0::calculateElementVector(const ElInfo *elInfo, ElementVector *vec) + { + int i; + double *c = GET_MEMORY(double, 1);; + + if(firstCall) { + q00 = Q00PsiPhi::provideQ00PsiPhi(owner->getRowFESpace()->getBasisFcts(), + owner->getColFESpace()->getBasisFcts(), + quadrature); + q0 = Q0Psi::provideQ0Psi(owner->getRowFESpace()->getBasisFcts(), + quadrature); + firstCall = false; + } + + ::std::vector<OperatorTerm*>::iterator termIt; + + c[0] = 0.0; + for(termIt = terms.begin(); termIt != terms.end(); ++termIt) { + (static_cast<ZeroOrderTerm*>( *termIt))->getC(elInfo, 1, c); + } + + c[0] *= elInfo->getDet(); + + for (i = 0; i < nRow; i++) + (*vec)[i] += c[0] * q0->getValue(i); + + FREE_MEMORY(c, double, 1); + } + + Stand10::Stand10(Operator *op, Assembler *assembler, Quadrature *quad) + : FirstOrderAssembler(op, assembler, quad, false, GRD_PSI) + {} + + + void Stand10::calculateElementMatrix(const ElInfo *elInfo, ElementMatrix *mat) + { + DimVec<double> grdPsi(dim, NO_INIT); + double *phival = GET_MEMORY(double, nCol); + int iq, i, j; + + const BasisFunction *psi = owner->getRowFESpace()->getBasisFcts(); + const BasisFunction *phi = owner->getColFESpace()->getBasisFcts(); + + int numPoints = quadrature->getNumPoints(); + + VectorOfFixVecs<DimVec<double> > Lb(dim,numPoints,NO_INIT); + // DimVec<double> *Lb = NEW DimVec<double>[numPoints](dim, NO_INIT); + for (iq = 0; iq < numPoints; iq++) { + Lb[iq].set(0.0); + } + for(i=0; i < static_cast<int>(terms.size()); i++) { + (static_cast<FirstOrderTerm*>((terms[i])))->getLb(elInfo, numPoints, Lb); + } + + for (iq = 0; iq < numPoints; iq++) { + Lb[iq] *= elInfo->getDet(); + + for(i=0; i < nCol; i++) { + phival[i] = (*(phi->getPhi(i)))(quadrature->getLambda(iq)); + } + + for (i = 0; i < nRow; i++) { + grdPsi = (*(psi->getGrdPhi(i)))(quadrature->getLambda(iq)); + for (j = 0; j < nCol; j++) { + (*mat)[i][j] += + quadrature->getWeight(iq) * (Lb[iq] * grdPsi) * phival[j]; + } + } + } + // DELETE [] Lb; + FREE_MEMORY(phival, double, nCol); + } + + // void Stand10::calculateElementVector(const ElInfo *elInfo, double *vec) + // { + // DimVec<double> Lb(dim, NO_INIT); + // DimVec<double> grdPsi(dim, NO_INIT); + // int iq, i; + + // const BasisFunction *psi = owner->getRowFESpace()->getBasisFcts(); + + // for (iq = 0; iq < quadrature->getNumPoints(); iq++) { + // Lb.set(0.0); + // for(i=0; i < static_cast<int>( terms->size()); i++) { + // (static_cast<FirstOrderTerm*>(((*terms)[i]))->eval(elInfo, 0, &Lb); + // } + + // Lb *= elInfo->getDet(); + + // for (i = 0; i < nRow; i++) { + // grdPsi = (*(psi->getGrdPhi(i)))(quadrature->getLambda(iq)); + // vec[i] += quadrature->getWeight(iq) * (Lb * grdPsi); + // } + // } + // } + + + Quad10::Quad10(Operator *op, Assembler *assembler, Quadrature *quad) + : FirstOrderAssembler(op, assembler, quad, true, GRD_PSI) + { + // if(!psiFast) { + // psiFast = FastQuadrature::provideFastQuadrature( + // assembler->getRowFESpace()->getBasisFcts(), + // *quadrature, + // INIT_GRD_PHI); + // } + // if(!phiFast) { + // phiFast = FastQuadrature::provideFastQuadrature( + // assembler->getColFESpace()->getBasisFcts(), + // *quadrature, + // INIT_PHI); + // } + } + + + void Quad10::calculateElementMatrix(const ElInfo *elInfo, ElementMatrix *mat) + { + VectorOfFixVecs<DimVec<double> > *grdPsi; + const double *phi; + int iq, i, j; + + if(firstCall) { + const BasisFunction *basFcts = owner->getRowFESpace()->getBasisFcts(); + psiFast = updateFastQuadrature(psiFast, basFcts, INIT_GRD_PHI); + basFcts = owner->getColFESpace()->getBasisFcts(); + phiFast = updateFastQuadrature(phiFast, basFcts, INIT_PHI); + firstCall = false; + } + + int numPoints = quadrature->getNumPoints(); + + VectorOfFixVecs<DimVec<double> > Lb(dim,numPoints,NO_INIT); + // DimVec<double> *Lb = NEW DimVec<double>[numPoints](dim, NO_INIT); + for (iq = 0; iq < numPoints; iq++) { + Lb[iq].set(0.0); + } + for(i=0; i < static_cast<int>(terms.size()); i++) { + (static_cast<FirstOrderTerm*>((terms[i])))->getLb(elInfo, numPoints, Lb); + } + + for (iq = 0; iq < numPoints; iq++) { + Lb[iq] *= elInfo->getDet(); + + phi = phiFast->getPhi(iq); + grdPsi = psiFast->getGradient(iq); + + for (i = 0; i < nRow; i++) { + for (j = 0; j < nCol; j++) + (*mat)[i][j] += + quadrature->getWeight(iq) * (Lb[iq] * (*grdPsi)[i]) * phi[j]; + } + } + // DELETE [] Lb; + } + + // void Quad10::calculateElementVector(const ElInfo *elInfo, double *vec) + // { + // DimVec<double> Lb(dim, NO_INIT); + // VectorOfFixVecs<DimVec<double> > *grdPsi; + // int iq, i; + + // for (iq = 0; iq < quadrature->getNumPoints(); iq++) { + // Lb.set(0.0); + // for(i=0; i < static_cast<int>( terms->size()); i++) { + // (static_cast<FirstOrderTerm*>(((*terms)[i]))->eval(elInfo, 0, &Lb); + // } + + // Lb *= elInfo->getDet(); + + // grdPsi = psiFast->getGradient(iq); + + // for (i = 0; i < nRow; i++) { + // vec[i] += quadrature->getWeight(iq) * (Lb * (*grdPsi)[i]); + // } + // } + // } + + Pre10::Pre10(Operator *op, Assembler *assembler, Quadrature *quad) + : FirstOrderAssembler(op, assembler, quad, true, GRD_PSI) + { + // q10 = Q10PsiPhi::provideQ10PsiPhi(assembler->getRowFESpace()->getBasisFcts(), + // assembler->getColFESpace()->getBasisFcts(), + // quadrature); + // q1 = Q1Psi::provideQ1Psi(assembler->getRowFESpace()->getBasisFcts(), + // quadrature); + } + + void Pre10::calculateElementMatrix(const ElInfo *elInfo, ElementMatrix *mat) + { + VectorOfFixVecs<DimVec<double> > Lb(dim,1,NO_INIT); + //DimVec<double> *Lb = NEW DimVec<double>[1](dim, NO_INIT); + const int *k; + const double *values; + int i, j, m; + double val; + + if(firstCall) { + q10 = Q10PsiPhi::provideQ10PsiPhi(owner->getRowFESpace()->getBasisFcts(), + owner->getColFESpace()->getBasisFcts(), + quadrature); + q1 = Q1Psi::provideQ1Psi(owner->getRowFESpace()->getBasisFcts(), + quadrature); + firstCall = false; + } + + const int **nEntries = q10->getNumberEntries(); + + Lb[0].set(0.0); + for(i=0; i < static_cast<int>( terms.size()); i++) { + (static_cast<FirstOrderTerm*>((terms[i])))->getLb(elInfo, 1, Lb); + } + + Lb[0] *= elInfo->getDet(); + + for (i = 0; i < nRow; i++) { + for (j = 0; j < nCol; j++) { + k = q10->getKVec(i, j); + values = q10->getValVec(i, j); + for (val = m = 0; m < nEntries[i][j]; m++) + val += values[m]*Lb[0][k[m]]; + (*mat)[i][j] += val; + } + } + + // DELETE [] Lb; + } + + // void Pre10::calculateElementVector(const ElInfo *elInfo, double *vec) + // { + // DimVec<double> Lb(dim, NO_INIT); + // const int *nEntries = q1->getNumberEntries(); + // const int *k; + // const double *values; + // int i, m; + // double val; + + // Lb.set(0.0); + // for(i=0; i < static_cast<int>( terms->size()); i++) { + // (static_cast<FirstOrderTerm*>(((*terms)[i]))->eval(elInfo, 0, &Lb); + // } + + // Lb *= elInfo->getDet(); + + // for (i = 0; i < nRow; i++) { + // k = q1->getKVec(i); + // values = q1->getValVec(i); + // for (val = m = 0; m < nEntries[i]; m++) + // val += values[m]*Lb[k[m]]; + // vec[i] += val; + // } + // } + + Stand01::Stand01(Operator *op, Assembler *assembler, Quadrature *quad) + : FirstOrderAssembler(op, assembler, quad, false, GRD_PHI) + {} + + void Stand01::calculateElementMatrix(const ElInfo *elInfo, ElementMatrix *mat) + { + VectorOfFixVecs<DimVec<double> > grdPhi(dim, nCol, NO_INIT); + double psival; + int iq, i, j; + + const BasisFunction *psi = owner->getRowFESpace()->getBasisFcts(); + const BasisFunction *phi = owner->getColFESpace()->getBasisFcts(); + + int numPoints = quadrature->getNumPoints(); + + VectorOfFixVecs<DimVec<double> > Lb(dim,numPoints,NO_INIT); + // DimVec<double> *Lb = NEW DimVec<double>[numPoints](dim, NO_INIT); + + for (iq = 0; iq < numPoints; iq++) { + Lb[iq].set(0.0); + } + for(i=0; i < static_cast<int>(terms.size()); i++) { + (static_cast<FirstOrderTerm*>((terms[i])))->getLb(elInfo, numPoints, Lb); + } + + for (iq = 0; iq < numPoints; iq++) { + Lb[iq] *= elInfo->getDet(); + + for(i=0; i < nCol; i++) { + grdPhi[i] = (*(phi->getGrdPhi(i)))(quadrature->getLambda(iq)); + } + + for (i = 0; i < nRow; i++) { + psival = (*(psi->getPhi(i)))(quadrature->getLambda(iq)); + for (j = 0; j < nCol; j++) + (*mat)[i][j] += + quadrature->getWeight(iq) * ((Lb[iq] * psival) * grdPhi[j]); + } + } + + // DELETE [] Lb; + } + + void Stand10::calculateElementVector(const ElInfo *elInfo, ElementVector *vec) + { + DimVec<double> grdPsi(dim, NO_INIT); + int iq, i; + + const BasisFunction *psi = owner->getRowFESpace()->getBasisFcts(); + + int numPoints = quadrature->getNumPoints(); + + VectorOfFixVecs<DimVec<double> > Lb(dim,numPoints,NO_INIT); + // DimVec<double> *Lb = NEW DimVec<double>[numPoints](dim, NO_INIT); + + for (iq = 0; iq < numPoints; iq++) { + Lb[iq].set(0.0); + } + for(i=0; i < static_cast<int>(terms.size()); i++) { + (static_cast<FirstOrderTerm*>((terms[i])))->getLb(elInfo, numPoints, Lb); + } + + for (iq = 0; iq < numPoints; iq++) { + Lb[iq] *= elInfo->getDet(); + + for (i = 0; i < nRow; i++) { + grdPsi = (*(psi->getGrdPhi(i)))(quadrature->getLambda(iq)); + (*vec)[i] += quadrature->getWeight(iq) * (Lb[iq] * grdPsi); + } + } + } + + Quad01::Quad01(Operator *op, Assembler *assembler, Quadrature *quad) + : FirstOrderAssembler(op, assembler, quad, true, GRD_PHI) + { + // if(!psiFast) { + // psiFast = FastQuadrature::provideFastQuadrature( + // assembler->getRowFESpace()->getBasisFcts(), + // *quadrature, + // INIT_PHI); + // } + // if(!phiFast) { + // phiFast = FastQuadrature::provideFastQuadrature( + // assembler->getColFESpace()->getBasisFcts(), + // *quadrature, + // INIT_GRD_PHI); + // } + } + + void Quad01::calculateElementMatrix(const ElInfo *elInfo, ElementMatrix *mat) + { + VectorOfFixVecs<DimVec<double> > *grdPhi; + const double *psi; + int iq, i, j; + + if(firstCall) { + const BasisFunction *basFcts = owner->getRowFESpace()->getBasisFcts(); + psiFast = updateFastQuadrature(psiFast, basFcts, INIT_PHI); + basFcts = owner->getColFESpace()->getBasisFcts(); + phiFast = updateFastQuadrature(phiFast, basFcts, INIT_GRD_PHI); + firstCall = false; + } + + int numPoints = quadrature->getNumPoints(); + + VectorOfFixVecs<DimVec<double> > Lb(dim,numPoints,NO_INIT); + // DimVec<double> *Lb = NEW DimVec<double>[numPoints](dim, NO_INIT); + + for (iq = 0; iq < numPoints; iq++) { + Lb[iq].set(0.0); + } + for(i=0; i < static_cast<int>(terms.size()); i++) { + (static_cast<FirstOrderTerm*>((terms[i])))->getLb(elInfo, numPoints, Lb); + } + + for (iq = 0; iq < numPoints; iq++) { + Lb[iq] *= elInfo->getDet(); + + psi = psiFast->getPhi(iq); + grdPhi = phiFast->getGradient(iq); + + for (i = 0; i < nRow; i++) { + for (j = 0; j < nCol; j++) + (*mat)[i][j] += + quadrature->getWeight(iq) * (Lb[iq] * (*grdPhi)[j]) * psi[i]; + } + } + + // DELETE [] Lb; + } + + void Quad10::calculateElementVector(const ElInfo *elInfo, ElementVector *vec) + { + VectorOfFixVecs<DimVec<double> > *grdPsi; + int iq, i; + + if(firstCall) { + const BasisFunction *basFcts = owner->getRowFESpace()->getBasisFcts(); + psiFast = updateFastQuadrature(psiFast, basFcts, INIT_GRD_PHI); + basFcts = owner->getColFESpace()->getBasisFcts(); + phiFast = updateFastQuadrature(phiFast, basFcts, INIT_PHI); + firstCall = false; + } + + int numPoints = quadrature->getNumPoints(); + + VectorOfFixVecs<DimVec<double> > Lb(dim,numPoints,NO_INIT); + // DimVec<double> *Lb = NEW DimVec<double>[numPoints](dim, NO_INIT); + + for (iq = 0; iq < numPoints; iq++) { + Lb[iq].set(0.0); + } + for(i=0; i < static_cast<int>(terms.size()); i++) { + (static_cast<FirstOrderTerm*>((terms[i])))->getLb(elInfo, numPoints, Lb); + } + + for (iq = 0; iq < numPoints; iq++) { + + Lb[iq] *= elInfo->getDet(); + + grdPsi = psiFast->getGradient(iq); + + for (i = 0; i < nRow; i++) { + (*vec)[i] += quadrature->getWeight(iq) * (Lb[iq] * (*grdPsi)[i]); + } + } + // DELETE [] Lb; + } + + Pre01::Pre01(Operator *op, Assembler *assembler, Quadrature *quad) + : FirstOrderAssembler(op, assembler, quad, true, GRD_PHI) + { + } + + void Pre01::calculateElementMatrix(const ElInfo *elInfo, ElementMatrix *mat) + { + VectorOfFixVecs<DimVec<double> > Lb(dim,1,NO_INIT); + //DimVec<double> *Lb = NEW DimVec<double>[1](dim, NO_INIT); + + const int *l; + const double *values; + int i, j, m; + double val; + + if(firstCall) { + q01 = Q01PsiPhi::provideQ01PsiPhi(owner->getRowFESpace()->getBasisFcts(), + owner->getColFESpace()->getBasisFcts(), + quadrature); + q1 = Q1Psi::provideQ1Psi(owner->getRowFESpace()->getBasisFcts(), + quadrature); + firstCall = false; + } + + const int **nEntries = q01->getNumberEntries(); + + Lb[0].set(0.0); + for(i=0; i < static_cast<int>( terms.size()); i++) { + (static_cast<FirstOrderTerm*>((terms[i])))->getLb(elInfo, 1, Lb); + } + + Lb[0] *= elInfo->getDet(); + + for (i = 0; i < nRow; i++) { + for (j = 0; j < nCol; j++) { + l = q01->getLVec(i, j); + values = q01->getValVec(i, j); + for (val = m = 0; m < nEntries[i][j]; m++) + val += values[m]*Lb[0][l[m]]; + (*mat)[i][j] += val; + } + } + // DELETE [] Lb; + } + + void Pre10::calculateElementVector(const ElInfo *elInfo, ElementVector *vec) + { + VectorOfFixVecs<DimVec<double> > Lb(dim,1,NO_INIT); + //DimVec<double> *Lb = NEW DimVec<double>[1](dim, NO_INIT); + + const int *k; + const double *values; + int i, m; + double val; + + if(firstCall) { + q10 = Q10PsiPhi::provideQ10PsiPhi(owner->getRowFESpace()->getBasisFcts(), + owner->getColFESpace()->getBasisFcts(), + quadrature); + q1 = Q1Psi::provideQ1Psi(owner->getRowFESpace()->getBasisFcts(), + quadrature); + firstCall = false; + } + + const int *nEntries = q1->getNumberEntries(); + + Lb[0].set(0.0); + for(i=0; i < static_cast<int>(terms.size()); i++) { + (static_cast<FirstOrderTerm*>(terms[i]))->getLb(elInfo, 1, Lb); + } + + Lb[0] *= elInfo->getDet(); + + for (i = 0; i < nRow; i++) { + k = q1->getKVec(i); + values = q1->getValVec(i); + for (val = m = 0; m < nEntries[i]; m++) + val += values[m]*Lb[0][k[m]]; + (*vec)[i] += val; + } + + //DELETE [] Lb; + } + + Pre2::Pre2(Operator *op, Assembler *assembler, Quadrature *quad) + : SecondOrderAssembler(op, assembler, quad, true) + { + // q11 = Q11PsiPhi::provideQ11PsiPhi(assembler->getRowFESpace()->getBasisFcts(), + // assembler->getColFESpace()->getBasisFcts(), + // quadrature); + } + + void Pre2::calculateElementMatrix(const ElInfo *elInfo, ElementMatrix *mat) + { + DimMat<double> **LALt = NEW DimMat<double>*; + *LALt=NEW DimMat<double>(dim, NO_INIT); + const int **nEntries; + const int *k, *l; + const double *values; + int i, j, m; + double val; + + if(firstCall) { + q11 = Q11PsiPhi::provideQ11PsiPhi(owner->getRowFESpace()->getBasisFcts(), + owner->getColFESpace()->getBasisFcts(), + quadrature); + firstCall = false; + } + + LALt[0]->set(0.0); + + for(i=0; i < static_cast<int>( terms.size()); i++) { + (static_cast<SecondOrderTerm*>(terms[i]))->getLALt(elInfo, 1, LALt); + } + + (*LALt[0]) *= elInfo->getDet(); + + nEntries = q11->getNumberEntries(); + + if (symmetric) { + for (i = 0; i < nRow; i++) { + k = q11->getKVec(i, i); + l = q11->getLVec(i, i); + values = q11->getValVec(i, i); + for (val = m = 0; m < nEntries[i][i]; m++) + val += values[m]*(*LALt[0])[k[m]][l[m]]; + (*mat)[i][i] += val; + for (j = i+1; j < nCol; j++) { + k = q11->getKVec(i, j); + l = q11->getLVec(i, j); + values = q11->getValVec(i, j); + for (val = m = 0; m < nEntries[i][j]; m++) + val += values[m]*(*LALt[0])[k[m]][l[m]]; + (*mat)[i][j] += val; + (*mat)[j][i] += val; + } + } + } + else { /* A not symmetric or psi != phi */ + for (i = 0; i < nRow; i++) { + for (j = 0; j < nCol; j++) { + k = q11->getKVec(i, j); + l = q11->getLVec(i, j); + values = q11->getValVec(i, j); + for (val = m = 0; m < nEntries[i][j]; m++) + val += values[m]*(*LALt[0])[k[m]][l[m]]; + (*mat)[i][j] += val; + } + } + } + + DELETE *LALt; + DELETE LALt; + } + + // void Pre2::calculateElementVector(const ElInfo *elInfo, double *vec) + // { + // FUNCNAME("Pre2::calculateElementVector"); + // ERROR_EXIT("should not be called\n"); + // } + + // void Pre2::calculateElementVector(const ElInfo *elInfo, double *vec) + // { + // DimMat<double> LALt(dim, NO_INIT); + // const int *nEntries; + // const int *k, *l; + // const double *values; + // int i, m; + // double val; + + // LALt.set(0.0); + + // for(i=0; i < static_cast<int>( terms->size()); i++) { + // (static_cast<SecondOrderTerm*>((*terms)[i])->eval(elInfo, 0, &LALt); + // } + + // nEntries = q2->getNumberEntries(); + + // for (i = 0; i < nRow; i++) { + // k = q2->getKVec(i); + // l = q2->getLVec(i); + // values = q2->getValVec(i); + // for (val = m = 0; m < nEntries[i]; m++) + // val += values[m]*LALt[k[m]][l[m]]; + // vec[i] += val; + // } + // } + + Quad2::Quad2(Operator *op, Assembler *assembler, Quadrature *quad) + : SecondOrderAssembler(op, assembler, quad, true) + { + // if(!psiFast) { + // psiFast = FastQuadrature::provideFastQuadrature( + // assembler->getRowFESpace()->getBasisFcts(), + // *quadrature, + // INIT_GRD_PHI); + // } else { + // psiFast->init(INIT_GRD_PHI); + // } + // if(!phiFast) { + // phiFast = FastQuadrature::provideFastQuadrature( + // assembler->getColFESpace()->getBasisFcts(), + // *quadrature, + // INIT_PHI); + // } else { + // phiFast->init(INIT_GRD_PHI); + // } + } + + void Quad2::calculateElementMatrix(const ElInfo *elInfo, ElementMatrix *mat) + { + double val; + VectorOfFixVecs<DimVec<double> > *grdPsi, *grdPhi; + int iq, i, j; + + if(firstCall) { + const BasisFunction *basFcts = owner->getRowFESpace()->getBasisFcts(); + psiFast = updateFastQuadrature(psiFast, basFcts, INIT_GRD_PHI); + basFcts = owner->getColFESpace()->getBasisFcts(); + phiFast = updateFastQuadrature(phiFast, basFcts, INIT_GRD_PHI); + firstCall = false; + } + + int nPoints = quadrature->getNumPoints(); + + DimMat<double> **LALt = NEW DimMat<double>*[nPoints]; + for(i=0;i<nPoints;i++) LALt[i]=NEW DimMat<double>(dim, NO_INIT); + for (iq = 0; iq < nPoints; iq++) { + LALt[iq]->set(0.0); + } + for(i=0; i < static_cast<int>(terms.size()); i++) { + (static_cast<SecondOrderTerm*>(terms[i]))->getLALt(elInfo, nPoints, LALt); + } + + if (symmetric) { + for (iq = 0; iq < nPoints; iq++) { + (*LALt[iq]) *= elInfo->getDet(); + + grdPsi = psiFast->getGradient(iq); + grdPhi = phiFast->getGradient(iq); + + for (i = 0; i < nRow; i++) { + (*mat)[i][i] += quadrature->getWeight(iq) * + ((*grdPsi)[i] * ((*LALt[iq]) * (*grdPhi)[i])); + + for (j = i+1; j < nCol; j++) { + val = quadrature->getWeight(iq) * ((*grdPsi)[i] * ((*LALt[iq]) * (*grdPhi)[j])); + (*mat)[i][j] += val; + (*mat)[j][i] += val; + } + } + } + } + else { /* non symmetric assembling */ + for (iq = 0; iq < nPoints; iq++) { + (*LALt[iq]) *= elInfo->getDet(); + + grdPsi = psiFast->getGradient(iq); + grdPhi = phiFast->getGradient(iq); + + for (i = 0; i < nRow; i++) { + for (j = 0; j < nCol; j++) { + (*mat)[i][j] += quadrature->getWeight(iq) * + ((*grdPsi)[i] * ((*LALt[iq]) * (*grdPhi)[j])); + } + } + } + } + + for(i=0;i<nPoints;i++) DELETE LALt[i]; + DELETE [] LALt; + } + + // void Quad2::calculateElementVector(const ElInfo *elInfo, double *vec) + // { + // FUNCNAME("Quad2::calculateElementVector"); + // ERROR_EXIT("should not be called\n"); + // } + + Stand2::Stand2(Operator *op, Assembler *assembler, Quadrature *quad) + : SecondOrderAssembler(op, assembler, quad, false) + {} + + void Stand2::calculateElementMatrix(const ElInfo *elInfo, ElementMatrix *mat) + { + double val; + DimVec<double> grdPsi(dim, NO_INIT); + VectorOfFixVecs<DimVec<double> > grdPhi(dim, nCol, NO_INIT); + int iq, i, j; + + const BasisFunction *psi = owner->getRowFESpace()->getBasisFcts(); + const BasisFunction *phi = owner->getColFESpace()->getBasisFcts(); + + int nPoints = quadrature->getNumPoints(); + + DimMat<double> **LALt = NEW DimMat<double>*[nPoints]; + for (iq = 0; iq < nPoints; iq++) { + LALt[iq]=NEW DimMat<double>(dim,NO_INIT); + LALt[iq]->set(0.0); + } + for(i=0; i < static_cast<int>(terms.size()); i++) { + (static_cast<SecondOrderTerm*>(terms[i]))->getLALt(elInfo, nPoints, LALt); + } + + if (symmetric) { + for (iq = 0; iq < nPoints; iq++) { + (*LALt[iq]) *= elInfo->getDet(); + + for(i=0; i < nCol; i++) { + grdPhi[i] = (*(phi->getGrdPhi(i)))(quadrature->getLambda(iq)); + } + + for (i = 0; i < nRow; i++) { + grdPsi = (*(psi->getGrdPhi(i)))(quadrature->getLambda(iq)); + (*mat)[i][i] += quadrature->getWeight(iq) * + (grdPsi * ((*LALt[iq]) * grdPhi[i])); + + for (j = i+1; j < nCol; j++) { + val = quadrature->getWeight(iq) * (grdPsi * ((*LALt[iq]) * grdPhi[j])); + (*mat)[i][j] += val; + (*mat)[j][i] += val; + } + } + } + } + else { /* non symmetric assembling */ + for (iq = 0; iq < nPoints; iq++) { + (*LALt[iq]) *= elInfo->getDet(); + + for(i=0; i < nCol; i++) { + grdPhi[i] = (*(phi->getGrdPhi(i)))(quadrature->getLambda(iq)); + } + + for (i = 0; i < nRow; i++) { + grdPsi = (*(psi->getGrdPhi(i)))(quadrature->getLambda(iq)); + for (j = 0; j < nCol; j++) { + (*mat)[i][j] += quadrature->getWeight(iq) * + (grdPsi * ((*LALt[iq]) * grdPhi[j])); + } + } + } + } + + for(iq=0;iq<nPoints;iq++) DELETE LALt[iq]; + DELETE [] LALt; + } + + // void Stand2::calculateElementVector(const ElInfo *elInfo, double *vec) + // { + // FUNCNAME("Stand2::calculateElementVector"); + // ERROR_EXIT("should not be called\n"); + // } + + Assembler::Assembler(Operator *op, + const FiniteElemSpace *rowFESpace_, + const FiniteElemSpace *colFESpace_) + : operat(op), + rowFESpace(rowFESpace_), + colFESpace(colFESpace_ ? colFESpace_ : rowFESpace_), + nRow(rowFESpace->getBasisFcts()->getNumber()), + nCol(colFESpace->getBasisFcts()->getNumber()), + remember(true), + rememberElMat(false), + rememberElVec(false), + elementMatrix(NULL), + elementVector(NULL), + lastMatEl(NULL), + lastVecEl(NULL), + lastTraverseId(-1) + + { + //if(op->uhOld) rememberElMat = true; + } + + void Assembler::calculateElementMatrix(const ElInfo *elInfo, + ElementMatrix *userMat, + double factor) + { + FUNCNAME("Assembler::calculateElementMatrix()"); + + if (remember && ((factor != 1.0) || (operat->uhOld))) { + rememberElMat = true; + } + + if (rememberElMat && !elementMatrix) + elementMatrix = NEW ElementMatrix(nRow, nCol); + + Element *el = elInfo->getElement(); + + checkForNewTraverse(); + + checkQuadratures(); + + if ((el != lastMatEl && el != lastVecEl) || !operat->isOptimized()) { + initElement(elInfo); + } + + if (el != lastMatEl || !operat->isOptimized()) { + if (rememberElMat) { + elementMatrix->set(0.0); + } + lastMatEl = el; + } else { + if (rememberElMat) { + axpy(factor, *elementMatrix, *userMat); + //*userMat += *elementMatrix * factor; + //operat->addElementMatrix(elementMatrix, userMat, factor); + return; + } + } + + ElementMatrix *mat = rememberElMat ? elementMatrix : userMat; + + if (secondOrderAssembler) + secondOrderAssembler->calculateElementMatrix(elInfo, mat); + if (firstOrderAssemblerGrdPsi) + firstOrderAssemblerGrdPsi->calculateElementMatrix(elInfo, mat); + if (firstOrderAssemblerGrdPhi) + firstOrderAssemblerGrdPhi->calculateElementMatrix(elInfo, mat); + if (zeroOrderAssembler) + zeroOrderAssembler->calculateElementMatrix(elInfo, mat); + + if(rememberElMat && userMat) { + axpy(factor, *elementMatrix, *userMat); + //*userMat += *elementMatrix * factor; + //operat->addElementMatrix(elementMatrix, userMat, factor); + } + } + + void Assembler::calculateElementVector(const ElInfo *elInfo, + ElementVector *userVec, + double factor) + { + FUNCNAME("Assembler::calculateElementVector()"); + + if(remember && factor != 1.0) { + rememberElVec = true; + } + + if(rememberElVec && !elementVector) + elementVector = NEW ElementVector(nRow); + + Element *el = elInfo->getElement(); + + checkForNewTraverse(); + + checkQuadratures(); + + if((el != lastMatEl && el != lastVecEl) || !operat->isOptimized()) { + initElement(elInfo); + } + + if(el != lastVecEl || !operat->isOptimized()) { + if(rememberElVec) { + elementVector->set(0.0); + } + lastVecEl = el; + } else { + if(rememberElVec) { + axpy(factor, *elementVector, *userVec); + //*userVec += *elementVector * factor; + //operat->addElementVector(elementVector, userVec, factor); + return; + } + } + + ElementVector *vec = rememberElVec ? elementVector : userVec; + + if(operat->uhOld && remember) { + matVecAssemble(elInfo, vec); + if(rememberElVec) { + axpy(factor, *elementVector, *userVec); + //*userVec += *elementVector * factor; + //operat->addElementVector(elementVector, userVec, factor); + } + return; + } + + //if(secondOrderAssembler) + // secondOrderAssembler->calculateElementVector(elInfo, vec); + if(firstOrderAssemblerGrdPsi) + firstOrderAssemblerGrdPsi->calculateElementVector(elInfo, vec); + //if(firstOrderAssemblerGrdPhi) + // firstOrderAssemblerGrdPhi->calculateElementVector(elInfo, vec); + if(zeroOrderAssembler) + zeroOrderAssembler->calculateElementVector(elInfo, vec); + + if(rememberElVec) { + axpy(factor, *elementVector, *userVec); + //*userVec += *elementVector * factor; + //operat->addElementVector(elementVector, userVec, factor); + } + + // MSG("\n"); + // for(int i=0; i < 3; i++) { + // MSG("%e\n", (*vec)[i]); + // } + + } + + void Assembler::matVecAssemble(const ElInfo *elInfo, ElementVector *vec) + { + FUNCNAME("Assembler::matVecAssemble()"); + + int i, j; + + Element *el = elInfo->getElement(); + const BasisFunction *basFcts = rowFESpace->getBasisFcts(); + const double *uhOldLoc = operat->uhOld->getLocalVector(el, NULL); + int n = basFcts->getNumber(); + + if(el != lastMatEl) { + calculateElementMatrix(elInfo, NULL); + } + + double val; + for (i = 0; i < n; i++) { + val = 0; + for (j = 0; j < n; j++) { + val += (*elementMatrix)[i][j]*uhOldLoc[j]; + } + (*vec)[i] += val; + } + + // MSG("\n"); + // MSG("uh loc:\n"); + // for (i = 0; i < n; i++) { + // MSG("%e\n", uhOldLoc[i]); + // } + } + + void Assembler::initElement(const ElInfo *elInfo, Quadrature *quad) + { + checkQuadratures(); + + if(secondOrderAssembler) + secondOrderAssembler->initElement(elInfo, quad); + if(firstOrderAssemblerGrdPsi) + firstOrderAssemblerGrdPsi->initElement(elInfo, quad); + if(firstOrderAssemblerGrdPhi) + firstOrderAssemblerGrdPhi->initElement(elInfo, quad); + if(zeroOrderAssembler) + zeroOrderAssembler->initElement(elInfo, quad); + } + + OptimizedAssembler::OptimizedAssembler(Operator *op, + Quadrature *quad2, + Quadrature *quad1GrdPsi, + Quadrature *quad1GrdPhi, + Quadrature *quad0, + const FiniteElemSpace *rowFESpace_, + const FiniteElemSpace *colFESpace_) + : Assembler(op, rowFESpace_, colFESpace_) + { + bool opt = (rowFESpace_ == colFESpace_); + + // create sub assemblers + secondOrderAssembler = + SecondOrderAssembler::getSubAssembler(op, this, quad2, opt); + firstOrderAssemblerGrdPsi = + FirstOrderAssembler::getSubAssembler(op, this, quad1GrdPsi, GRD_PSI, opt); + firstOrderAssemblerGrdPhi = + FirstOrderAssembler::getSubAssembler(op, this, quad1GrdPhi, GRD_PHI, opt); + zeroOrderAssembler = + ZeroOrderAssembler::getSubAssembler(op, this, quad0, opt); + } + + StandardAssembler::StandardAssembler(Operator *op, + Quadrature *quad2, + Quadrature *quad1GrdPsi, + Quadrature *quad1GrdPhi, + Quadrature *quad0, + const FiniteElemSpace *rowFESpace_, + const FiniteElemSpace *colFESpace_) + : Assembler(op, rowFESpace_, colFESpace_) + { + remember = false; + + // create sub assemblers + secondOrderAssembler = + SecondOrderAssembler::getSubAssembler(op, this, quad2, false); + firstOrderAssemblerGrdPsi = + FirstOrderAssembler::getSubAssembler(op, this, quad1GrdPsi, GRD_PSI, false); + firstOrderAssemblerGrdPhi = + FirstOrderAssembler::getSubAssembler(op, this, quad1GrdPhi, GRD_PHI, false); + zeroOrderAssembler = + ZeroOrderAssembler::getSubAssembler(op, this, quad0, false); + } + + ElementMatrix *Assembler::initElementMatrix(ElementMatrix *elMat, + const ElInfo *elInfo) + { + if(!elMat) { + elMat = NEW ElementMatrix(nRow, nCol); + } + + elMat->set(0.0); + + DOFAdmin *rowAdmin = rowFESpace->getAdmin(); + DOFAdmin *colAdmin = colFESpace->getAdmin(); + + Element *element = elInfo->getElement(); + + elMat->rowIndices = + rowFESpace->getBasisFcts()->getLocalIndices(element, + rowAdmin, + NULL); + + elMat->colIndices = + colFESpace->getBasisFcts()->getLocalIndices(element, + colAdmin, + NULL); + + return elMat; + } + + ElementVector *Assembler::initElementVector(ElementVector *elVec, + const ElInfo *elInfo) + { + if(!elVec) { + elVec = NEW ElementVector(nRow); + } + + elVec->set(0.0); + + DOFAdmin *rowAdmin = rowFESpace->getAdmin(); + + Element *element = elInfo->getElement(); + + elVec->dofIndices = + rowFESpace->getBasisFcts()->getLocalIndices(element, + rowAdmin, + NULL); + + return elVec; + } + + void Assembler::checkQuadratures() + { + int dim; + + if(secondOrderAssembler) { + // create quadrature + if(!secondOrderAssembler->getQuadrature()) { + dim = rowFESpace->getMesh()->getDim(); + int degree = operat->getQuadratureDegree(2); + Quadrature *quadrature = Quadrature::provideQuadrature(dim, degree); + secondOrderAssembler->setQuadrature(quadrature); + } + } + if(firstOrderAssemblerGrdPsi) { + // create quadrature + if(!firstOrderAssemblerGrdPsi->getQuadrature()) { + dim = rowFESpace->getMesh()->getDim(); + int degree = operat->getQuadratureDegree(1, GRD_PSI); + Quadrature *quadrature = Quadrature::provideQuadrature(dim, degree); + firstOrderAssemblerGrdPsi->setQuadrature(quadrature); + } + } + if(firstOrderAssemblerGrdPhi) { + // create quadrature + if(!firstOrderAssemblerGrdPhi->getQuadrature()) { + dim = rowFESpace->getMesh()->getDim(); + int degree = operat->getQuadratureDegree(1, GRD_PHI); + Quadrature *quadrature = Quadrature::provideQuadrature(dim, degree); + firstOrderAssemblerGrdPhi->setQuadrature(quadrature); + } + } + if(zeroOrderAssembler) { + // create quadrature + if(!zeroOrderAssembler->getQuadrature()) { + dim = rowFESpace->getMesh()->getDim(); + int degree = operat->getQuadratureDegree(0); + Quadrature *quadrature = Quadrature::provideQuadrature(dim, degree); + zeroOrderAssembler->setQuadrature(quadrature); + } + } + } + +} diff --git a/AMDiS/src/Assembler.h b/AMDiS/src/Assembler.h new file mode 100644 index 0000000000000000000000000000000000000000..e5d8131ebcbd787ba1c2de442ea3039b42fe32ae --- /dev/null +++ b/AMDiS/src/Assembler.h @@ -0,0 +1,1184 @@ +// ============================================================================ +// == == +// == AMDiS - Adaptive multidimensional simulations == +// == == +// ============================================================================ +// == == +// == crystal growth group == +// == == +// == Stiftung caesar == +// == Ludwig-Erhard-Allee 2 == +// == 53175 Bonn == +// == germany == +// == == +// ============================================================================ +// == == +// == http://www.caesar.de/cg/AMDiS == +// == == +// ============================================================================ + +/** \file Assembler.h */ + +/** + * \defgroup Assembler Assembler module + * + * \brief + * Contains the operator and assembler classes: + * @{ <img src="assembler.png"> @} + */ + +#ifndef AMDIS_ASSEMBLER_H +#define AMDIS_ASSEMBLER_H + +#include <vector> +#include "FixVec.h" +#include "MemoryManager.h" +#include "Operator.h" + +namespace AMDiS { + + class ElInfo; + class Element; + class Assembler; + class Quadrature; + class FastQuadrature; + class FiniteElemSpace; + class ElementMatrix; + class ElementVector; + class BasisFunction; + class Q00PsiPhi; + class Q10PsiPhi; + class Q01PsiPhi; + class Q11PsiPhi; + class Q0Psi; + class Q1Psi; + class Q2Psi; + // class Operator; + // class OperatorTerm; + + template<typename T> class DOFVectorBase; + + // enum FirstOrderType; + + // ============================================================================ + // ===== class SubAssembler =================================================== + // ============================================================================ + + /** + * \ingroup Assembler + * + * \brief + * Base class for SecondOrderAssembler, FirstOrderAssembler, + * ZeroOrderAssembler. The task of a SubAssembler is to assemble a list of + * terms of a spezial order and add their contributions to a DOFMatrix or a + * DOFVector. An Assembler can consist of up to four SubAssemblers: one + * SecondOrderAssembler for second order terms, one ZeroOrderAssembler for + * terms of order zero, and two FirstOrderAssemblers. One for terms with + * derivatives of the basis functions connected to to row DOFs and one for + * those connected to the column DOFs. + */ + class SubAssembler + { + public: + MEMORY_MANAGED(SubAssembler); + + /** \brief + * Creates a SubAssembler belonging to assembler for the terms of given + * order of Operator op. If order is equal to one, type spezifies what kind + * of FirstOrderType are to assemble. During construction of a SubAssembler + * the needs and properties of the terms are considered. + */ + SubAssembler(Operator *op, + Assembler *assembler, + Quadrature *quadrat, + int order, + bool optimized, + FirstOrderType type = GRD_PHI); + + /** \brief + * Destructor + */ + virtual ~SubAssembler() {}; + + /** \brief + * Calculates the element matrix for elInfo and adds it to mat. Memory + * for mat must be provided by the caller. + */ + virtual void calculateElementMatrix(const ElInfo *elInfo, + ElementMatrix *mat) = 0; + + /** \brief + * Calculates the element vector for elInfo and adds it to vec. Memory + * for vec must be provided by the caller. + */ + virtual void calculateElementVector(const ElInfo *elInfo, + ElementVector *vec) = 0; + + /** \brief + * Returns \ref terms + */ + inline ::std::vector<OperatorTerm*> *getTerms() { return &terms; }; + + /** \brief + * Returns \ref quadrature. + */ + inline Quadrature *getQuadrature() { + return quadrature; + }; + + /** \brief + * Sets \ref quadrature to q. + */ + inline void setQuadrature(Quadrature* q) { + /* TEST_EXIT(!quadrature)("quadrature already set\n"); */ + quadrature = q; + }; + + /** \brief + * Returns a vector with the world coordinates of the quadrature points + * of \ref quadrature on the element of elInfo. + * Used by \ref OperatorTerm::initElement(). + */ + WorldVector<double>* getCoordsAtQPs(const ElInfo* elInfo, + Quadrature *quad = NULL); + + /** \brief + * DOFVector dv evaluated at quadrature points. + * Used by \ref OperatorTerm::initElement(). + */ + double* getVectorAtQPs(DOFVectorBase<double>* dv, const ElInfo* elInfo, + Quadrature *quad = NULL); + + /** \brief + * Gradients of DOFVector dv evaluated at quadrature points. + * Used by \ref OperatorTerm::initElement(). + */ + WorldVector<double>* getGradientsAtQPs(DOFVectorBase<double>* dv, + const ElInfo* elInfo, + Quadrature *quad = NULL); + + /** \brief + * Called once for each ElInfo when \ref calculateElementMatrix() or + * \ref calculateElementVector() is called for the first time for this + * Element. + */ + virtual void initElement(const ElInfo *elInfo, + Quadrature *quad = NULL); + + /** \brief + * Returns \ref psiFast. + */ + const FastQuadrature *getPsiFast() const { return psiFast; }; + + /** \brief + * Returns \ref phiFast. + */ + const FastQuadrature *getPhiFast() const { return phiFast; }; + + protected: + /** \brief + * Updates \ref psiFast and \ref phiFast. + */ + FastQuadrature *updateFastQuadrature(FastQuadrature *quadFast, + const BasisFunction *psi, + Flag updateFlag); + + protected: + /** \brief + * Problem dimension + */ + int dim; + + /** \brief + * Number of rows of the element matrix and length of the element + * vector. Is equal to the number of row basis functions + */ + int nRow; + + /** \brief + * Number of columns of the element matrix. Is equal to the number + * of column basis functions + */ + int nCol; + + /** \brief + * Used for \ref getVectorAtQPs(). + */ + class ValuesAtQPs { + public: + Vector<double> values; + bool valid; + }; + + /** \brief + * Used for \ref getGradientsAtQPs(). + */ + class GradientsAtQPs { + public: + Vector<WorldVector<double> > values; + bool valid; + }; + + /** \brief + * Used for \ref getVectorAtQPs(). + */ + ::std::map<const DOFVectorBase<double>*, ValuesAtQPs*> valuesAtQPs; + + /** \brief + * Used for \ref getGradientsAtQPs(). + */ + ::std::map<const DOFVectorBase<double>*, GradientsAtQPs*> gradientsAtQPs; + + /** \brief + * Set and updated by \ref initElement() for each ElInfo. + * coordsAtQPs[i] points to the coordinates of the i-th quadrature point. + */ + WorldVector<double> *coordsAtQPs; + + /** \brief + * Used for \ref getCoordsAtQPs(). + */ + bool coordsValid; + + /** \brief + * Needed Quadrature. Constructed in the constructor of SubAssembler + */ + Quadrature *quadrature; + + /** \brief + * FastQuadrature for row basis functions + */ + FastQuadrature *psiFast; + + /** \brief + * FastQuadrature for column basis functions + */ + FastQuadrature *phiFast; + + /** \brief + * Corresponding Assembler + */ + Assembler* owner; + + /** \brief + * Flag that specifies whether the element matrix is symmetric. + */ + bool symmetric; + + /** \brief + * List of all terms with a contribution to this SubAssembler + */ + ::std::vector<OperatorTerm*> terms; + + bool opt; + + bool firstCall; + + friend class Assembler; + }; + + // ============================================================================ + // ===== class ZeroOrderAssembler ============================================= + // ============================================================================ + + /** + * \ingroup Assembler + * + * \brief + * SubAssembler for zero order terms. + */ + class ZeroOrderAssembler : public SubAssembler + { + public: + MEMORY_MANAGED(ZeroOrderAssembler); + + /** \brief + * Creates and returns the ZeroOrderAssembler for Operator op and + * the given assembler. If all terms are piecewise constant precalculated + * integrals can be used while assembling and the returned + * ZeroOrderAssembler is of type Pre0. Otherwise a Quad0 object will + * be returned. + */ + static ZeroOrderAssembler* getSubAssembler(Operator *op, + Assembler *assembler, + Quadrature *quadrat, + bool optimized); + + + /** \brief + * Destructor. + */ + virtual ~ZeroOrderAssembler() {}; + + protected: + /** \brief + * Constructor. + */ + ZeroOrderAssembler(Operator *op, + Assembler *assembler, + Quadrature *quadrat, + bool optimized); + + protected: + /** \brief + * List of all yet created optimized SubAssembler objects. + */ + static ::std::vector<SubAssembler*> optimizedSubAssemblers; + + /** \brief + * List of all yet created standard SubAssembler objects. + */ + static ::std::vector<SubAssembler*> standardSubAssemblers; + }; + + // ============================================================================ + // ===== class Stand0 ========================================================= + // ============================================================================ + + /** + * \ingroup Assembler + * + * \brief + * Standard zero order assembler. + */ + class Stand0 : public ZeroOrderAssembler + { + public: + MEMORY_MANAGED(Stand0); + + /** \brief + * Constructor. + */ + Stand0(Operator *op, Assembler *assembler, Quadrature *quad); + + /** \brief + * Implements SubAssembler::calculateElementMatrix(). + */ + void calculateElementMatrix(const ElInfo *elInfo, ElementMatrix *mat); + + /** \brief + * Implements SubAssembler::calculateElementVector(). + */ + void calculateElementVector(const ElInfo *elInfo, ElementVector *vec); + }; + + // ============================================================================ + // ===== class Quad0 ========================================================== + // ============================================================================ + + /** + * \ingroup Assembler + * + * \brief + * Zero order assembler using fast quadratures. + */ + class Quad0 : public ZeroOrderAssembler + { + public: + MEMORY_MANAGED(Quad0); + + /** \brief + * Constructor. + */ + Quad0(Operator *op, Assembler *assembler, Quadrature *quad); + + /** \brief + * Implements SubAssembler::calculateElementMatrix(). + */ + void calculateElementMatrix(const ElInfo *elInfo, ElementMatrix *mat); + + /** \brief + * Implements SubAssembler::calculateElementVector(). + */ + void calculateElementVector(const ElInfo *elInfo, ElementVector *vec); + }; + + + // ============================================================================ + // ===== class Pre0 =========================================================== + // ============================================================================ + + /** + * \ingroup Assembler + * + * \brief + * Zero order assembler using precaculated integrals. + */ + class Pre0 : public ZeroOrderAssembler + { + public: + MEMORY_MANAGED(Pre0); + + /** \brief + * Constructor. + */ + Pre0(Operator *op, Assembler *assembler, Quadrature *quad); + + /** \brief + * Implements SubAssembler::calculateElementMatrix(). + */ + void calculateElementMatrix(const ElInfo *elInfo, ElementMatrix *mat); + + /** \brief + * Implements SubAssembler::calculateElementVector(). + */ + void calculateElementVector(const ElInfo *elInfo, ElementVector *vec); + + protected: + /** \brief + * Integral of the product of psi and phi. + */ + const Q00PsiPhi *q00; + + /** \brief + * Integral of psi. + */ + const Q0Psi *q0; + + friend class ZeroOrderAssembler; + }; + + // ============================================================================ + // ===== class FirstOrderAssembler ============================================ + // ============================================================================ + + /** + * \ingroup Assembler + * + * \brief + * SubAssembler for first order terms. + */ + class FirstOrderAssembler : public SubAssembler + { + public: + MEMORY_MANAGED(FirstOrderAssembler); + + /** \brief + * Creates and returns the FirstOrderAssembler for Operator op and + * the given assembler. If all terms are piecewise constant precalculated + * integrals can be used while assembling and the returned + * ZeroOrderAssembler is of type Pre0. Otherwise a Quad0 object will + * be returned. + */ + static FirstOrderAssembler* getSubAssembler(Operator *op, + Assembler *assembler, + Quadrature *quadrat, + FirstOrderType type, + bool optimized); + + /** \brief + * Destructor. + */ + virtual ~FirstOrderAssembler() {}; + + protected: + /** \brief + * Constructor. + */ + FirstOrderAssembler(Operator *op, + Assembler *assembler, + Quadrature *quadrat, + bool optimized, + FirstOrderType type); + + + protected: + /** \brief + * List of all yet created optimized zero order assemblers for grdPsi. + */ + static ::std::vector<SubAssembler*> optimizedSubAssemblersGrdPsi; + + /** \brief + * List of all yet created standard zero order assemblers for grdPsi. + */ + static ::std::vector<SubAssembler*> standardSubAssemblersGrdPsi; + + /** \brief + * List of all yet created optimized zero order assemblers for grdPhi. + */ + static ::std::vector<SubAssembler*> optimizedSubAssemblersGrdPhi; + + /** \brief + * List of all yet created standard zero order assemblers for grdPhi. + */ + static ::std::vector<SubAssembler*> standardSubAssemblersGrdPhi; + }; + + // ============================================================================ + // ===== class Stand10 ======================================================== + // ============================================================================ + + /** + * \ingroup Assembler + * + * \brief + * Standard first order assembler for grdPsi. + */ + class Stand10 : public FirstOrderAssembler + { + public: + MEMORY_MANAGED(Stand10); + + /** \brief + * Constructor. + */ + Stand10(Operator *op, Assembler *assembler, Quadrature *quad); + + /** \brief + * Implements SubAssembler::calculateElementMatrix(). + */ + void calculateElementMatrix(const ElInfo *elInfo, ElementMatrix *mat); + + /** \brief + * Implements SubAssembler::calculateElementVector(). + */ + void calculateElementVector(const ElInfo *, ElementVector */*vec*/); + }; + + // ============================================================================ + // ===== class Stand10 ======================================================== + // ============================================================================ + + /** + * \ingroup Assembler + * + * \brief + * Standard first order assembler for grdPhi. + */ + class Stand01 : public FirstOrderAssembler + { + public: + MEMORY_MANAGED(Stand01); + + /** \brief + * Constructor. + */ + Stand01(Operator *op, Assembler *assembler, Quadrature *quad); + + /** \brief + * Implements SubAssembler::calculateElementMatrix(). + */ + void calculateElementMatrix(const ElInfo *elInfo, ElementMatrix *mat); + + /** \brief + * Implements SubAssembler::calculateElementVector(). + */ + void calculateElementVector(const ElInfo *, ElementVector *) { + ERROR_EXIT("should not be called\n"); + }; + }; + + // ============================================================================ + // ===== class Quad10 ========================================================= + // ============================================================================ + + /** \brief + * First order assembler for grdPsi using fast quadratures. + */ + class Quad10 : public FirstOrderAssembler + { + public: + MEMORY_MANAGED(Quad10); + + /** \brief + * Constructor. + */ + Quad10(Operator *op, Assembler *assembler, Quadrature *quad); + + /** \brief + * Implements SubAssembler::calculateElementMatrix(). + */ + void calculateElementMatrix(const ElInfo *elInfo, ElementMatrix *mat); + + /** \brief + * Implements SubAssembler::calculateElementVector(). + */ + void calculateElementVector(const ElInfo *, ElementVector */*vec*/); + }; + + // ============================================================================ + // ===== class Quad01 ========================================================= + // ============================================================================ + + /** \brief + * First order assembler for grdPhi using fast quadratures. + */ + class Quad01 : public FirstOrderAssembler + { + public: + MEMORY_MANAGED(Quad01); + + /** \brief + * Constructor. + */ + Quad01(Operator *op, Assembler *assembler, Quadrature *quad); + + /** \brief + * Implements SubAssembler::calculateElementMatrix(). + */ + void calculateElementMatrix(const ElInfo *elInfo, ElementMatrix *mat); + + /** \brief + * Implements SubAssembler::calculateElementVector(). + */ + void calculateElementVector(const ElInfo *, ElementVector */*vec*/) { + ERROR_EXIT("should not be called\n"); + }; + }; + + // ============================================================================ + // ===== class Pre10 ========================================================== + // ============================================================================ + + /** \brief + * First order assembler for grdPsi using precalculated integrals + */ + class Pre10 : public FirstOrderAssembler + { + public: + MEMORY_MANAGED(Pre10); + + /** \brief + * Constructor. + */ + Pre10(Operator *op, Assembler *assembler, Quadrature *quad); + + /** \brief + * Implements SubAssembler::calculateElementMatrix(). + */ + void calculateElementMatrix(const ElInfo *elInfo, ElementMatrix *mat); + + /** \brief + * Implements SubAssembler::calculateElementVector(). + */ + void calculateElementVector(const ElInfo *, ElementVector */*vec*/); + + protected: + /** \brief + * Integral of the product of the derivative of psi and phi. + */ + const Q10PsiPhi *q10; + + /** \brief + * Integral of the derivative of psi. + */ + const Q1Psi *q1; + + friend class FirstOrderAssembler; + }; + + // ============================================================================ + // ===== class Pre01 ========================================================== + // ============================================================================ + + /** \brief + * First order assembler for grdPhi using precalculated integrals + */ + class Pre01 : public FirstOrderAssembler + { + public: + MEMORY_MANAGED(Pre01); + + /** \brief + * Constructor. + */ + Pre01(Operator *op, Assembler *assembler, Quadrature *quad); + + /** \brief + * Implements SubAssembler::calculateElementMatrix(). + */ + void calculateElementMatrix(const ElInfo *elInfo, ElementMatrix *mat); + + /** \brief + * Implements SubAssembler::calculateElementVector(). + */ + void calculateElementVector(const ElInfo *, ElementVector */*vec*/) { + ERROR_EXIT("should not be called\n"); + }; + + protected: + /** \brief + * Integral of the product of psi and the derivative of phi. + */ + const Q01PsiPhi *q01; + + /** \brief + * Integral of the derivative of phi. + */ + const Q1Psi *q1; + + friend class FirstOrderAssembler; + }; + + // ============================================================================ + // ===== class SecondOrderAssembler =========================================== + // ============================================================================ + + /** + * \ingroup Assembler + * + * \brief + * SubAssembler for second order terms. + */ + class SecondOrderAssembler : public SubAssembler + { + public: + MEMORY_MANAGED(SecondOrderAssembler); + + /** \brief + * Creates and returns the SecondOrderAssembler for Operator op and + * the given assembler. If all terms are piecewise constant precalculated + * integrals can be used while assembling and the returned + * ZeroOrderAssembler is of type Pre0. Otherwise a Quad0 object will + * be returned. + */ + static SecondOrderAssembler* getSubAssembler(Operator *op, + Assembler *assembler, + Quadrature *quadrat, + bool optimized); + + /** \brief + * Destructor. + */ + virtual ~SecondOrderAssembler() {}; + + protected: + /** \brief + * Constructor. + */ + SecondOrderAssembler(Operator *op, + Assembler *assembler, + Quadrature *quadrat, + bool optimized); + + protected: + /** \brief + * List of all yet created optimized second order assemblers. + */ + static ::std::vector<SubAssembler*> optimizedSubAssemblers; + + /** \brief + * List of all yet created standard second order assemblers. + */ + static ::std::vector<SubAssembler*> standardSubAssemblers; + }; + + // ============================================================================ + // ===== class Stand2 ========================================================= + // ============================================================================ + + /** + * \ingroup Assembler + * + * \brief + * Standard second order assembler + */ + class Stand2 : public SecondOrderAssembler + { + public: + MEMORY_MANAGED(Stand2); + + /** \brief + * Constructor. + */ + Stand2(Operator *op, Assembler *assembler, Quadrature *quad); + + /** \brief + * Implements SubAssembler::calculateElementMatrix(). + */ + void calculateElementMatrix(const ElInfo *elInfo, ElementMatrix *mat); + + /** \brief + * Implements SubAssembler::calculateElementVector(). + */ + void calculateElementVector(const ElInfo *, ElementVector */*vec*/) { + ERROR_EXIT("should not be called\n"); + }; + }; + + // ============================================================================ + // ===== class Quad2 ========================================================== + // ============================================================================ + + /** \brief + * Second order assembler using fast quadratures. + */ + class Quad2 : public SecondOrderAssembler + { + public: + MEMORY_MANAGED(Quad2); + + /** \brief + * Constructor. + */ + Quad2(Operator *op, Assembler *assembler, Quadrature *quad); + + /** \brief + * Implements SubAssembler::calculateElementMatrix(). + */ + void calculateElementMatrix(const ElInfo *elInfo, ElementMatrix *mat); + + /** \brief + * Implements SubAssembler::calculateElementVector(). + */ + void calculateElementVector(const ElInfo *, ElementVector */*vec*/) { + ERROR_EXIT("should not be called\n"); + }; + }; + + // ============================================================================ + // ===== class Pre2 =========================================================== + // ============================================================================ + + /** \brief + * Second order assembler using predefined integrals. + */ + class Pre2 : public SecondOrderAssembler + { + public: + MEMORY_MANAGED(Pre2); + + /** \brief + * Constructor. + */ + Pre2(Operator *op, Assembler *assembler, Quadrature *quad); + + /** \brief + * Implements SubAssembler::calculateElementMatrix(). + */ + void calculateElementMatrix(const ElInfo *elInfo, ElementMatrix *mat); + + /** \brief + * Implements SubAssembler::calculateElementVector(). + */ + void calculateElementVector(const ElInfo *, ElementVector */*vec*/) { + ERROR_EXIT("should not be called\n"); + }; + + protected: + /** \brief + * Integral of the product of the derivative of psi and the derivative + * of phi. + */ + const Q11PsiPhi *q11; + + friend class SecondOrderAssembler; + }; + + // ============================================================================ + // ===== class Assembler ====================================================== + // ============================================================================ + + /** + * \ingroup Assembler + * + * \brief + * Assembles element matrices and vectors for a given Operator. Uses + * one SubAssembler for all second order terms of the Operator, one for all + * first order terms, and one for all zero order terms. + */ + class Assembler + { + public: + MEMORY_MANAGED(Assembler); + + /** \brief + * Constructor. + */ + Assembler(Operator *op, + const FiniteElemSpace *rowFESpace_, + const FiniteElemSpace *colFESpace_=NULL); + + virtual ~Assembler() {}; + + ElementMatrix *initElementMatrix(ElementMatrix *elMat, + const ElInfo *elInfo); + + + ElementVector *initElementVector(ElementVector *elVec, + const ElInfo *elInfo); + + /** \brief + * Assembles the element matrix for the given ElInfo + */ + virtual void calculateElementMatrix(const ElInfo *elInfo, + ElementMatrix *userMat, + double factor=1.0); + + /** \brief + * Assembles the element vector for the given ElInfo + */ + virtual void calculateElementVector(const ElInfo *elInfo, + ElementVector *userVec, + double factor=1.0); + + /** \brief + * Returns \ref rowFESpace. + */ + inline const FiniteElemSpace* getRowFESpace() { return rowFESpace; }; + + /** \brief + * Returns \ref colFESpace. + */ + inline const FiniteElemSpace* getColFESpace() { return colFESpace; }; + + /** \brief + * Returns \ref nRow. + */ + inline int getNRow() { return nRow; }; + + /** \brief + * Returns \ref nCol. + */ + inline int getNCol() { return nCol; }; + + /** \brief + * Sets \ref rememberElMat. + */ + inline void rememberElementMatrix(bool rem) { rememberElMat = rem; }; + + /** \brief + * Sets \ref rememberElVec. + */ + inline void rememberElementVector(bool rem) { rememberElVec = rem; }; + + /** \brief + * Returns \ref zeroOrderAssembler. + */ + inline ZeroOrderAssembler* getZeroOrderAssembler() { + return zeroOrderAssembler; + }; + + /** \brief + * Returns \ref firstOrderAssemblerGrdPsi or \ref firstOrderAssemblerGrdPhi + * depending on type. + */ + inline FirstOrderAssembler* getFirstOrderAssembler(FirstOrderType type = + GRD_PSI) + { + return + (type == GRD_PSI) ? + firstOrderAssemblerGrdPsi : + firstOrderAssemblerGrdPhi; + }; + + /** \brief + * Returns \ref secondOrderAssembler. + */ + inline SecondOrderAssembler* getSecondOrderAssembler() { + return secondOrderAssembler; + }; + + /** \brief + * Returns \ref operat; + */ + inline Operator* getOperator() { return operat; }; + + /** \brief + * Initialisation for the given ElInfo. The call is deligated to + * the sub assemblers. + */ + void initElement(const ElInfo *elInfo, + Quadrature *quad = NULL); + + /** \brief + * Sets quadratures of all sub assemblers. + */ + void setQuadratures(Quadrature *quad2, + Quadrature *quad1GrdPsi, + Quadrature *quad1GrdPhi, + Quadrature *quad0) + { + if(secondOrderAssembler) { + TEST_EXIT(!secondOrderAssembler->getQuadrature()) + ("quadrature already existing\n"); + secondOrderAssembler->setQuadrature(quad2); + } + if(firstOrderAssemblerGrdPsi) { + TEST_EXIT(!firstOrderAssemblerGrdPsi->getQuadrature()) + ("quadrature already existing\n"); + firstOrderAssemblerGrdPsi->setQuadrature(quad1GrdPsi); + } + if(firstOrderAssemblerGrdPhi) { + TEST_EXIT(!firstOrderAssemblerGrdPhi->getQuadrature()) + ("quadrature already existing\n"); + firstOrderAssemblerGrdPhi->setQuadrature(quad1GrdPhi); + } + if(zeroOrderAssembler) { + TEST_EXIT(!zeroOrderAssembler->getQuadrature()) + ("quadrature already existing\n"); + zeroOrderAssembler->setQuadrature(quad0); + } + }; + + protected: + /** \brief + * Vector assembling by element matrix-vector multiplication. + * Usefull if an element matrix was already calculated. + */ + void matVecAssemble(const ElInfo *elInfo, ElementVector *vec); + + /** \brief + * Checks whether this is a new travese. + */ + inline void checkForNewTraverse() { + if(lastTraverseId != ElInfo::traverseId) { + lastVecEl = lastMatEl = NULL; + lastTraverseId = ElInfo::traverseId; + } + }; + + /** \brief + * Checks whether quadratures for sub assemblers are already set. + * If not they will be created. + */ + void checkQuadratures(); + + protected: + /** \brief + * Operator this Assembler belongs to. + */ + Operator *operat; + + /** \brief + * Row FiniteElemSpace. + */ + const FiniteElemSpace *rowFESpace; + + /** \brief + * Column FiniteElemSpace. + */ + const FiniteElemSpace *colFESpace; + + /** \brief + * Number of rows. + */ + int nRow; + + /** \brief + * Number of columns. + */ + int nCol; + + /** \brief + * SubAssembler for the second order terms + */ + SecondOrderAssembler *secondOrderAssembler; + + /** \brief + * SubAssembler for the first order terms (grdPsi) + */ + FirstOrderAssembler *firstOrderAssemblerGrdPsi; + + /** \brief + * SubAssembler for the first order terms (grdPhi) + */ + FirstOrderAssembler *firstOrderAssemblerGrdPhi; + + /** \brief + * SubAssembler for the zero order terms + */ + ZeroOrderAssembler *zeroOrderAssembler; + + bool remember; + + /** \brief + * Determines whether the element matrix should be stored locally. + */ + bool rememberElMat; + + /** \brief + * Determines whether the element vector should be stored locally. + */ + bool rememberElVec; + + /** \brief + * locally stored element matrix + */ + ElementMatrix* elementMatrix; + + /** \brief + * locally stored element vector + */ + ElementVector* elementVector; + + /** \brief + * Used to check whether \ref initElement() must be called, because + * a new Element is visited. + */ + Element* lastMatEl; + + /** \brief + * Used to check whether \ref initElement() must be called, because + * a new Element is visited. + */ + Element* lastVecEl; + + /** \brief + * Used to check for new traverse. + */ + int lastTraverseId; + + friend class SubAssembler; + friend class ZeroOrderAssembler; + friend class FirstOrderAssembler; + friend class SecondOrderAssembler; + }; + + // ============================================================================ + // ===== class StandardAssembler ============================================= + // ============================================================================ + + /** + * \ingroup Assembler + * + * \brief + * Assembler using non optimized sub assemblers. + */ + class StandardAssembler : public Assembler + { + public: + MEMORY_MANAGED(StandardAssembler); + + /** \brief + * Constructor. + */ + StandardAssembler(Operator *op, + Quadrature *quad2, + Quadrature *quad1GrdPsi, + Quadrature *quad1GrdPhi, + Quadrature *quad0, + const FiniteElemSpace *rowFESpace_, + const FiniteElemSpace *colFESpace_=NULL); + }; + + // ============================================================================ + // ===== class OptimizedAssembler ============================================= + // ============================================================================ + + /** + * \ingroup Assembler + * + * \brief + * Assembler using optimized sub assemblers. + */ + class OptimizedAssembler : public Assembler + { + public: + MEMORY_MANAGED(OptimizedAssembler); + + /** \brief + * Constructor. + */ + OptimizedAssembler(Operator *op, + Quadrature *quad2, + Quadrature *quad1GrdPsi, + Quadrature *quad1GrdPhi, + Quadrature *quad0, + const FiniteElemSpace *rowFESpace_, + const FiniteElemSpace *colFESpace_=NULL); + }; + +} + +#endif // AMDIS_ASSEMBLER_H diff --git a/AMDiS/src/BallProject.h b/AMDiS/src/BallProject.h new file mode 100644 index 0000000000000000000000000000000000000000..f82a8bfb59d65aaaffa47af677a965330c91aad2 --- /dev/null +++ b/AMDiS/src/BallProject.h @@ -0,0 +1,80 @@ +// ============================================================================ +// == == +// == AMDiS - Adaptive multidimensional simulations == +// == == +// ============================================================================ +// == == +// == crystal growth group == +// == == +// == Stiftung caesar == +// == Ludwig-Erhard-Allee 2 == +// == 53175 Bonn == +// == germany == +// == == +// ============================================================================ +// == == +// == http://www.caesar.de/cg/AMDiS == +// == == +// ============================================================================ + +/** \file BallProject.h */ + +#ifndef AMDIS_BALLPROJECT_H +#define AMDIS_BALLPROJECT_H + +namespace AMDiS { + + // ============================================================================== + // ===== class BallProject ====================================================== + // ============================================================================== + + /** \brief + * Projects world coordinates to the surface of a ball with given center and + * radius. Can be used as boundary or volume projection. + */ + class BallProject : public Projection + { + public: + /** \brief + * Constructor. + */ + BallProject(int id, + ProjectionType type, + WorldVector<double> ¢er, + double radius) + : Projection(id, type), + center_(center), + radius_(radius) + {}; + + /** \brief + * Destructor. + */ + virtual ~BallProject() {}; + + /** \brief + * Implementation of Projection::project(); + */ + void project(WorldVector<double> &x) { + x -= center_; + double norm = sqrt(x*x); + TEST_EXIT(norm != 0.0)("can't project vector x\n"); + x *= radius_/norm; + x += center_; + }; + + protected: + /** \brief + * Center of the ball. + */ + WorldVector<double> center_; + + /** \brief + * Radius of the ball. + */ + double radius_; + }; + +} + +#endif diff --git a/AMDiS/src/BasisFunction.cc b/AMDiS/src/BasisFunction.cc new file mode 100644 index 0000000000000000000000000000000000000000..2578159099ba572e7b4f309e9a46faac834f380f --- /dev/null +++ b/AMDiS/src/BasisFunction.cc @@ -0,0 +1,118 @@ +#include <algorithm> + +#include "FixVec.h" +#include "DOFVector.h" +#include "BasisFunction.h" +#include "Lagrange.h" + +namespace AMDiS { + + + /****************************************************************************/ + /* Lagrangian basisfunctions of order 0-4; these */ + /* functions are evaluated in barycentric coordinates; the derivatives */ + /* are those corresponding to these barycentric coordinates. */ + /****************************************************************************/ + + BasisFunction::~BasisFunction() + { + DELETE nDOF; + } + + + BasisFunction::BasisFunction(const ::std::string& name_, int dim_, int degree_) + : name(name_), degree(degree_), dim(dim_) + { + FUNCNAME("BasisFunction::BasisFunction()"); + nDOF = NEW DimVec<int>(dim, DEFAULT_VALUE, -1); + }; + + + /****************************************************************************/ + /* some routines for evaluation of a finite element function, its gradient */ + /* and second derivatives; all those with _fast use the preevaluated */ + /* basis functions at that point. */ + /****************************************************************************/ + + double BasisFunction::evalUh(const DimVec<double>& lambda, + const double *uh_loc) const + { + double val = 0.0; + + for (int i = 0; i < nBasFcts; i++) + val += uh_loc[i] * (*(*phi)[i])(lambda); + + return(val); + } + + + const WorldVector<double>& BasisFunction::evalGrdUh(const DimVec<double>& lambda, + const DimVec<WorldVector<double> >& grd_lambda, + const double *uh_loc, WorldVector<double>* grd_uh) const + { + static WorldVector<double> grd; + + DimVec<double> grd_b(dim, DEFAULT_VALUE, 0.); + WorldVector<double> *val; + DimVec<double> grd1(dim, DEFAULT_VALUE, 0.); + + val = grd_uh ? grd_uh : &grd; + + for (int j = 0; j < dim + 1; j++) + grd1[j] = 0.0; + + for (int i = 0; i < nBasFcts; i++) { + grd_b = (*(*grdPhi)[i])(lambda); + for (int j = 0; j < dim + 1; j++) + grd1[j] += uh_loc[i] * grd_b[j]; + } + + int dow = Global::getGeo(WORLD); + + for (int i = 0; i < dow; i++) { + (*val)[i] = 0; + for (int j = 0; j < dim + 1; j++) + (*val)[i] += grd_lambda[j][i] * grd1[j]; + } + + return((*val)); + } + + const WorldMatrix<double>& BasisFunction::evalD2Uh(const DimVec<double>& lambda, + const DimVec<WorldVector<double> >& grd_lambda, + const double *uh_loc, WorldMatrix<double>* D2_uh) const + { + static WorldMatrix<double> D2(DEFAULT_VALUE, 0.); + DimMat<double> D2_b(dim, NO_INIT); + WorldMatrix<double> *val; + DimMat<double> D2_tmp(dim, DEFAULT_VALUE, 0.0); + + val = D2_uh ? D2_uh : &D2; + + for (int i = 0; i < nBasFcts; i++) { + D2_b = (*(*d2Phi)[i])(lambda); + for (int k = 0; k < dim + 1; k++) + for (int l = 0; l < dim + 1; l++) + D2_tmp[k][l] += uh_loc[i] * D2_b[k][l]; + } + + int dow = Global::getGeo(WORLD); + + for (int i = 0; i < dow; i++) + for (int j = 0; j < dow; j++) { + (*val)[i][j] = 0.0; + for (int k = 0; k < dim+1; k++) + for (int l = 0; l < dim+1; l++) + (*val)[i][j] += grd_lambda[k][i] * grd_lambda[l][j] * D2_tmp[k][l]; + } + + return((*val)); + } + + + int BasisFunction::getNumberOfDOFs(int i) const + { + return (*nDOF)[i]; + } + +} diff --git a/AMDiS/src/BasisFunction.h b/AMDiS/src/BasisFunction.h new file mode 100644 index 0000000000000000000000000000000000000000..a9db74ffe899314524477c59dae49d5c373679ab --- /dev/null +++ b/AMDiS/src/BasisFunction.h @@ -0,0 +1,394 @@ +// ============================================================================ +// == == +// == AMDiS - Adaptive multidimensional simulations == +// == == +// ============================================================================ +// == == +// == crystal growth group == +// == == +// == Stiftung caesar == +// == Ludwig-Erhard-Allee 2 == +// == 53175 Bonn == +// == germany == +// == == +// ============================================================================ +// == == +// == http://www.caesar.de/cg/AMDiS == +// == == +// ============================================================================ + +/** \file BasisFunction.h */ + +#ifndef AMDIS_BASISFUNCTION_H +#define AMDIS_BASISFUNCTION_H + +// ============================================================================ +// ===== includes ============================================================= +// ============================================================================ + +#include <string> +#include "Global.h" +#include "Boundary.h" + +namespace AMDiS { + + // ============================================================================ + // ===== forward declarations ================================================= + // ============================================================================ + + class DOFAdmin; + //template<typename T> class DOFMatrix; + class Element; + class ElInfo; + class RCNeighbourList; + template<typename T> class WorldVector; + template<typename T> class WorldMatrix; + class Quadrature; + + template <typename ReturnType, typename ArgumentType> class AbstractFunction; + template <typename T> class DOFVector; + template <typename T> class DOFIndexed; + template <typename T> class DimVec; + template <typename T> class DimMat; + template <typename T, GeoIndex d> class FixVec; + template <typename T> class VectorOfFixVecs; + + // ============================================================================ + // ===== typedefs ============================================================= + // ============================================================================ + + typedef AbstractFunction<double, DimVec<double> > BasFctType; + typedef AbstractFunction<DimVec<double>, DimVec<double> > GrdBasFctType; + typedef AbstractFunction<DimMat<double>, DimVec<double> > D2BasFctType; + typedef BasFctType *BFptr; + typedef GrdBasFctType *GBFptr; + typedef D2BasFctType *DBFptr; + + // ============================================================================ + // ===== class BasisFunction ================================================== + // ============================================================================ + + /** \ingroup FEMSpace + * \brief + * Base class for finite element basis functions. In order to build up a + * finite element space, we have to specify a set of local basis functions. + * Together with the correspondig DOF administration and the underlying mesh, + * the finite element space is given. + * This class holds the local basis functions and their derivatives of the + * reference element. They are evaluated at barycentric coordinates, so they + * can be used on every element of the mesh. + */ + class BasisFunction + { + protected: + /** \brief + * Creates a BasisFunction object of given dim and degree + */ + BasisFunction(const ::std::string& name_, int dim_, int degree_); + + /** \brief + * destructor + */ + virtual ~BasisFunction(); + + public: + /** \brief + * compares two BasisFunction objects. + */ + virtual bool operator==(const BasisFunction& a) const { + return a.getName()==name; + }; + + /** \brief + * Returns !(*this == b) + */ + inline bool operator!=(const BasisFunction& b) const { + return !operator==(b); + }; + + /** \brief + * Used by \ref getDOFIndices and \ref getVec + */ + virtual int* orderOfPositionIndices(const Element* el, GeoIndex position, + int positionIndex) const = 0; + + /** \brief + * Pointer to a function which connects the set of local basis functions + * with its global DOFs. + * getDOFIndices(el, admin, dof) returns a pointer to a const vector of + * length \ref nBasFcts where the i-th entry is the index of the DOF + * associated to the i-th basis function; arguments are the actual element + * el and the DOF admin admin of the corresponding finite element space + * (these indices depend on all defined DOF admins and thus on the + * corresponding admin); if the last argument dof is NULL, getDOFndices + * has to provide memory for storing this vector, which is overwritten on the + * next call of getDOFIndices; if dof is not NULL, dof is a pointer to a + * vector which has to be filled; + */ + virtual const DegreeOfFreedom* getDOFIndices(const Element*, + const DOFAdmin&, + DegreeOfFreedom*) const = 0; + + /** \brief + * Pointer to a function which fills a vector with the boundary types of the + * basis functions; + * getBound(el info, bound) returns a pointer to this vector of length + * \ref nBasFcts where the i-th entry is the boundary type of the i-th basis + * function; bound may be a pointer to a vector which has to be filled + * (compare the dof argument of \ref getDOFIindices); + * such a function needs boundary information; thus, all routines using this + * function on the elements need the FILL_BOUND flag during mesh traversal; + */ + virtual const BoundaryType* getBound(const ElInfo*, BoundaryType *) const { + return NULL; + }; + + /** \brief + * Returns \ref degree of BasisFunction + */ + inline const int getDegree() const { + return degree; + }; + + /** \brief + * Returns \ref dim of BasisFunction + */ + inline const int getDim() const { + return dim; + }; + + /** \brief + * Returns \ref nBasFcts which is the number of local basis functions + */ + inline const int getNumber() const { + return nBasFcts; + }; + + /** \brief + * Returns \ref name of BasisFunction + */ + inline const ::std::string& getName() const { + return name; + }; + + /** \brief + * Returns \ref nDOF[i] + */ + int getNumberOfDOFs(int i) const; + + /** \brief + * Returns \ref nDOF + */ + inline DimVec<int>* getNumberOfDOFs() const { + return nDOF; + }; + + /** \brief + * Initialisation of the \ref nDOF vector. Must be implemented by sub classes + */ + virtual void setNDOF() = 0; + + /** \brief + * Returns the barycentric coordinates of the i-th basis function. + */ + virtual DimVec<double> *getCoords(int i) const = 0; + + /** \brief + * Returns a pointer to a const vector with interpolation coefficients of the + * function f; if indices is a pointer to NULL, the coefficient for all + * basis functions are calculated and the i-th entry in the vector is the + * coefficient of the i-th basis function; if indices is non NULL, only the + * coefficients for a subset of the local basis functions has to be + * calculated; n is the number of those basis functions, indices[0], . . . + * , indices[n-1] are the local indices of the basis functions where the + * coefficients have to be calculated, and the i-th entry in the return + * vector is then the coefficient of the indices[i]-th basis function; coeff + * may be a pointer to a vector which has to be filled + * (compare the dof argument of \ref getDOFIndices()); + * such a function usually needs vertex coordinate information; thus, all + * routines using this function on the elements need the FILL COORDS flag + * during mesh traversal. + * Must be implemented by sub classes. + */ + virtual const double* interpol(const ElInfo *el_info, + int n, const int *indices, + AbstractFunction<double, WorldVector<double> > *f, + double *coeff) = 0; + + + /** \brief + * WorldVector<double> valued interpol function. + */ + virtual const WorldVector<double>* + interpol(const ElInfo *el_info, int no, + const int *b_no, + AbstractFunction<WorldVector<double>,WorldVector<double> > *f, + WorldVector<double> *vec) = 0; + + /** \brief + * Returns the i-th local basis function + */ + inline BasFctType *getPhi(int i) const { + return (*phi)[i]; + }; + + /** \brief + * Returns the gradient of the i-th local basis function + */ + inline GrdBasFctType *getGrdPhi(int i) const { + return (*grdPhi)[i]; + }; + + /** \brief + * Returns the second derivative of the i-th local basis function + */ + inline D2BasFctType *getD2Phi(int i) const { + return (*d2Phi)[i]; + }; + + /** \brief + * Approximates the L2 scalar products of a given function with all basis + * functions by numerical quadrature and adds the corresponding values to a + * DOF vector; + * f is a pointer for the evaluation of the given function in world + * coordinates x and returns the value of that function at x; if f is a NULL + * pointer, nothing is done; + * fh is the DOF vector where at the i-th entry the approximation of the L2 + * scalar product of the given function with the i-th global basis function + * of fh->feSpace is stored; + * quad is the quadrature for the approximation of the integral on each leaf + * element of fh->feSpace->mesh; if quad is a NULL pointer, a default + * quadrature which is exact of degree 2*fh->feSpace->basFcts->degree-2 is + * used. + * The integrals are approximated by looping over all leaf elements, + * computing the approximations to the element contributions and adding + * these values to the vector fh by add element vec(). + * The vector fh is not initialized with 0.0; only the new contributions are + * added + */ + virtual void l2ScpFctBas(Quadrature*, + AbstractFunction<double, WorldVector<double> >* /*f*/, + DOFVector<double>* /*fh*/) {}; + + /** \brief + * WorldVector<double> valued l2ScpFctBas function + */ + virtual void l2ScpFctBas(Quadrature* , + AbstractFunction<WorldVector<double>, WorldVector<double> >* /*f*/, + DOFVector<WorldVector<double> >* /*fh*/) {}; + + + /** \brief + * Interpolates a DOFIndexed<double> after refinement + */ + virtual void refineInter(DOFIndexed<double> *, RCNeighbourList*, int){}; + + /** \brief + * Interpolates a DOFIndexed<double> after coarsening + */ + virtual void coarseInter(DOFIndexed<double> *, RCNeighbourList*, int){}; + + /** \brief + * Restricts a DOFIndexed<double> after coarsening + */ + virtual void coarseRestr(DOFIndexed<double> *, RCNeighbourList*, int){}; + + /** \brief + * Interpolates a DOFVector<WorldVector<double> > after refinement + */ + virtual void refineInter(DOFVector<WorldVector<double> >*, RCNeighbourList*, int){}; + + /** \brief + * Interpolates a DOFVector<WorldVector<double> > after coarsening + */ + virtual void coarseInter(DOFVector<WorldVector<double> >*, RCNeighbourList*, int){}; + + /** \brief + * Restricts a DOFVector<WorldVector<double> > after coarsening + */ + virtual void coarseRestr(DOFVector<WorldVector<double> >*, RCNeighbourList*, int){}; + + /** \brief + * Returns local dof indices of the element for the given fe space. + */ + virtual const DegreeOfFreedom *getLocalIndices(const Element*, + const DOFAdmin*, + DegreeOfFreedom*) const + { + return NULL; + }; + + + /** \brief + * Evaluates elements value at barycentric coordinates lambda with local + * coefficient vector uh. + */ + double evalUh(const DimVec<double>& lambda, const double* uh) const; + + /** \brief + * Evaluates the gradient at barycentric coordinates lambda. Lambda is the + * Jacobian of the barycentric coordinates. uh is the local coefficient + * vector. If val is not NULL the result will be stored + * there, otherwise a pointer to a static local variable is returned which + * will be overwritten after the next call. + */ + const WorldVector<double>& evalGrdUh(const DimVec<double>& lambda, + const DimVec<WorldVector<double> >& Lambda, + const double* uh, WorldVector<double>* val) const; + + /** \brief + * Evaluates the second derivative at barycentric coordinates lambda. + * Lambda is the Jacobian of the barycentric coordinates. uh is the local + * coefficient vector. If val is not NULL the result will be stored + * there, otherwise a pointer to a static local variable is returned which + * will be overwritten after the next call. + */ + const WorldMatrix<double>& evalD2Uh(const DimVec<double>& lambda, + const DimVec<WorldVector<double> >& Lambda, + const double* uh, WorldMatrix<double>* val) const; + + protected: + /** \brief + * Textual description + */ + ::std::string name; + + /** \brief + * Number of basisfunctions on one Element + */ + int nBasFcts; + + /** \brief + * Maximal degree of the basis functions + */ + int degree; + + /** \brief + * Dimension of the basis functions + */ + int dim; + + /** \brief + * Number of DOFs at the different positions + */ + DimVec<int> *nDOF; + + /** \brief + * Vector of the local functions + */ + ::std::vector<BasFctType*> *phi; + + /** \brief + * Vector of gradients + */ + ::std::vector<GrdBasFctType*> *grdPhi; + + /** \brief + * Vector of second derivatives + */ + ::std::vector<D2BasFctType*> *d2Phi; + }; + +} + +#endif // AMDIS_BASISFUNCTION_H diff --git a/AMDiS/src/BiCGSolver.h b/AMDiS/src/BiCGSolver.h new file mode 100644 index 0000000000000000000000000000000000000000..8f9a2c907edc492760946cef783f67e218aa4898 --- /dev/null +++ b/AMDiS/src/BiCGSolver.h @@ -0,0 +1,101 @@ +// ============================================================================ +// == == +// == AMDiS - Adaptive multidimensional simulations == +// == == +// ============================================================================ +// == == +// == crystal growth group == +// == == +// == Stiftung caesar == +// == Ludwig-Erhard-Allee 2 == +// == 53175 Bonn == +// == germany == +// == == +// ============================================================================ +// == == +// == http://www.caesar.de/cg/AMDiS == +// == == +// ============================================================================ + +/** \file BiCGSolver.h */ + +#ifndef AMDIS_BICGSOLVER_H +#define AMDIS_BICGSOLVER_H + +#include "OEMSolver.h" +#include "MemoryManager.h" +#include "CreatorInterface.h" + +namespace AMDiS { + + // ============================================================================ + // ===== class BiCGSolver ===================================================== + // ============================================================================ + + /** + * \ingroup Solver + * + * \brief + * Solves a linear system by a stabilized BiCG method and can be used for + * symmetric system matrices. + */ + template<typename VectorType> + class BiCGSolver : public OEMSolver<VectorType> + { + public: + MEMORY_MANAGED(BiCGSolver<VectorType>); + + /** \brief + * Creator class used in the OEMSolverMap. + */ + class Creator : public OEMSolverCreator<VectorType> + { + public: + MEMORY_MANAGED(Creator); + + virtual ~Creator() {}; + + /** \brief + * Returns a new BiCGSolver object. + */ + OEMSolver<VectorType>* create() { + return NEW BiCGSolver<VectorType>(this->name); + }; + }; + + /** \brief + * constructor + */ + BiCGSolver(::std::string name); + + /** \brief + * destructor + */ + ~BiCGSolver(); + + protected: + /** \brief + * realisation of OEMSolver::solveSystem + */ + int solveSystem(MatVecMultiplier<VectorType> *mv, VectorType *x, VectorType *b); + + /** \brief + * realisation of OEMSolver::init + */ + void init(); + + /** \brief + * realisation of OEMSolver::exit + */ + void exit(); + + private: + // pointer to memory needed for solveSystem + VectorType *rstar, *d, *s, *CAd, *h; + }; + +} + +#include "BiCGSolver.hh" + +#endif // AMDIS_BICGSOLVER_H diff --git a/AMDiS/src/BiCGSolver.hh b/AMDiS/src/BiCGSolver.hh new file mode 100644 index 0000000000000000000000000000000000000000..f3071fc1c95549551f7d11fffb8f1f840854f27d --- /dev/null +++ b/AMDiS/src/BiCGSolver.hh @@ -0,0 +1,193 @@ +#include "Preconditioner.h" + +namespace AMDiS { + + template<typename VectorType> + BiCGSolver<VectorType>::BiCGSolver(::std::string name) + : OEMSolver<VectorType>(name), + rstar(NULL), d(NULL), s(NULL), CAd(NULL), h(NULL) + { + } + + template<typename VectorType> + BiCGSolver<VectorType>::~BiCGSolver() + {} + + template<typename VectorType> + void BiCGSolver<VectorType>::init() + { + rstar = this->vectorCreator->create(); + d = this->vectorCreator->create(); + s = this->vectorCreator->create(); + CAd = this->vectorCreator->create(); + h = this->vectorCreator->create(); + } + + template<typename VectorType> + void BiCGSolver<VectorType>::exit() + { + this->vectorCreator->free(rstar); + this->vectorCreator->free(d); + this->vectorCreator->free(s); + this->vectorCreator->free(CAd); + this->vectorCreator->free(h); + } + + template<typename VectorType> + int BiCGSolver<VectorType>::solveSystem(MatVecMultiplier<VectorType> *matVec, + VectorType *x, VectorType *b) + { + FUNCNAME("BiCGSolver::solveSystem"); + VectorType *t = h; + + double res, old_res = -1.0; + double rh1, rh2, dad, alpha, ast, att, omega, beta; + int iter; + + const double TOL = 1.e-30; + + /*--------------------------------------------------------------------------*/ + /*--- Initalization ------------------------------------------------------*/ + /*--------------------------------------------------------------------------*/ + + if (norm(b) < TOL) + { + INFO(this->info,2)("b == 0, x = 0 is the solution of the linear system\n"); + set(*x, 0.0); + this->residual = 0.0; + return(0); + } + + // h = Ax + matVec->matVec(NoTranspose, *x, *h); + + // h -= b + *h -= *b; + + // rstar = h; + *rstar = *h; + + // preconditioning + if(this->leftPrecon) this->leftPrecon->precon(h); + if(this->rightPrecon) this->rightPrecon->precon(b); + + /*--------------------------------------------------------------------------*/ + /*--- check initial residual ---------------------------------------------*/ + /*--------------------------------------------------------------------------*/ + + res = norm(h); + + START_INFO(); + if (SOLVE_INFO(0, res, &old_res)) + return(0); + + // d = h + *d = *h; + + // rh1 = h*rstar + rh1 = *h * *rstar; + + /*--------------------------------------------------------------------------*/ + /*--- Iteration ----------------------------------------------------------*/ + /*--------------------------------------------------------------------------*/ + + for (iter = 1; iter <= this->max_iter; iter++) + { + /*--------------------------------------------------------------------------*/ + /*--- calculate CA.d and CA.d*rstar --------------------------------------*/ + /*--------------------------------------------------------------------------*/ + + // CAd = Ad + matVec->matVec(NoTranspose, *d, *CAd); + + if(this->leftPrecon) this->leftPrecon->precon(CAd); + + // dad = CAd * rstar; + dad = *CAd * *rstar; + + if (abs(rh1) < TOL) { + BREAK_INFO("(h,r^*)_2 = 0", iter, res, &old_res); + return(iter); + } + if (abs(dad) < TOL) { + BREAK_INFO("(Ad,d^*)_2 = 0", iter, res, &old_res); + return(iter); + } + + /*-------------------------------------------------------------------------*/ + /*--- update s and t ----------------------------------------------------*/ + /*-------------------------------------------------------------------------*/ + + alpha = rh1/dad; + + // s = h + *s = *h; + + // s = -alpha CAd + s + axpy(-alpha, *CAd, *s); + + // t = As + matVec->matVec(NoTranspose, *s, *t); + + /*--------------------------------------------------------------------------*/ + /*--- calculate omega ----------------------------------------------------*/ + /*--------------------------------------------------------------------------*/ + + // ast = s*t + ast = *s * *t; + + // att = t*t + att = *t * *t; + + if (abs(ast) < TOL) { + INFO(this->info,2)("omega = 0"); + ast = ast > 0 ? TOL : -TOL; + } + + if (att < TOL) + { + INFO(this->info,2)("t = 0"); + att = TOL; + } + + omega= ast/att; + + /*--------------------------------------------------------------------------*/ + /*--- update x and calculate new h --------------------------------------*/ + /*--------------------------------------------------------------------------*/ + + // x = -alpha d + x + axpy(-alpha, *d, *x); + + // x = -omega s + x + axpy(-omega, *s, *x); + + // h = s - omega * h + *h *= -omega; + *h += *s; + + res = norm(h); + if (SOLVE_INFO(iter, res, &old_res)) + return(iter); + + if (this->leftPrecon) this->leftPrecon->precon(t); + + // rh2 = h * rstar + rh2 = *h * *rstar; + + beta= (rh2/rh1)* (alpha/omega); + + // d = -omega CAd + d + axpy(-omega, *CAd, *d); + + // d = h + beta d + *d *= beta; + *d += *h; + + rh1 = rh2; + } + + return 0; // never reached ! + } + +} diff --git a/AMDiS/src/BiCGStab.h b/AMDiS/src/BiCGStab.h new file mode 100644 index 0000000000000000000000000000000000000000..6994d0ed2139cc129eddbda607f9b38bbdf898c6 --- /dev/null +++ b/AMDiS/src/BiCGStab.h @@ -0,0 +1,104 @@ +// ============================================================================ +// == == +// == AMDiS - Adaptive multidimensional simulations == +// == == +// ============================================================================ +// == == +// == crystal growth group == +// == == +// == Stiftung caesar == +// == Ludwig-Erhard-Allee 2 == +// == 53175 Bonn == +// == germany == +// == == +// ============================================================================ +// == == +// == http://www.caesar.de/cg/AMDiS == +// == == +// ============================================================================ + +/** \file BiCGStab.h */ + +#ifndef AMDIS_BiCGStab_H +#define AMDIS_BiCGStab_H + +#include "OEMSolver.h" +#include "MemoryManager.h" +#include "CreatorInterface.h" + +namespace AMDiS +{ + + // ============================================================================ + // ===== class BiCGStab ======================================================= + // ============================================================================ + + /** + * \ingroup Solver + * + * \brief + * Solves a linear system by the stabilized BiCG method. + * Can be used for general system matrices. + */ + template<typename VectorType> + class BiCGStab : public OEMSolver<VectorType> + { + public: + MEMORY_MANAGED(BiCGStab<VectorType>); + + /** \brief + * Creator class used in the OEMSolverMap. + */ + class Creator : public OEMSolverCreator<VectorType> + { + public: + MEMORY_MANAGED(Creator); + + virtual ~Creator() {}; + + /** \brief + * Returns a new BiCGStab object. + */ + OEMSolver<VectorType>* create() + { + return NEW BiCGStab<VectorType>(this->name); + }; + }; + + /** \brief + * constructor + */ + BiCGStab(::std::string name); + + /** \brief + * destructor + */ + ~BiCGStab(); + + protected: + /** \brief + * realisation of OEMSolver::solveSystem + */ + int solveSystem(MatVecMultiplier<VectorType> *mv, + VectorType *x, VectorType *b); + + /** \brief + * realisation of OEMSolver::init + */ + void init(); + + /** \brief + * realisation of OEMSolver::exit + */ + void exit(); + + private: + // pointer to memory needed for solveSystem + VectorType *r, *rstar, *p, *v, *t, *xmin; + }; + +} + +#include "BiCGStab.hh" + +#endif // AMDIS_BiCGStab_H diff --git a/AMDiS/src/BiCGStab.hh b/AMDiS/src/BiCGStab.hh new file mode 100644 index 0000000000000000000000000000000000000000..692053b7ec810b2fdd536e553211b9d057143b6e --- /dev/null +++ b/AMDiS/src/BiCGStab.hh @@ -0,0 +1,234 @@ +#include "Preconditioner.h" + +namespace AMDiS +{ + + template<typename VectorType> + BiCGStab<VectorType>::BiCGStab(::std::string name) + : OEMSolver<VectorType>(name), + r(NULL), rstar(NULL), p(NULL), v(NULL), t(NULL), xmin(NULL) + {} + + template<typename VectorType> + BiCGStab<VectorType>::~BiCGStab() + {} + + template<typename VectorType> + void BiCGStab<VectorType>::init() + { + r = this->vectorCreator->create(); + rstar = this->vectorCreator->create(); + p = this->vectorCreator->create(); + v = this->vectorCreator->create(); + t = this->vectorCreator->create(); + xmin = this->vectorCreator->create(); + } + + template<typename VectorType> + void BiCGStab<VectorType>::exit() + { + this->vectorCreator->free(r); + this->vectorCreator->free(rstar); + this->vectorCreator->free(p); + this->vectorCreator->free(v); + this->vectorCreator->free(t); + this->vectorCreator->free(xmin); + } + + template<typename VectorType> + int BiCGStab<VectorType>::solveSystem(MatVecMultiplier<VectorType> *mv, + VectorType *x, VectorType *b) + { + FUNCNAME("BiCGStab::solveSystem"); + + double res, old_res = -1.0; + double rh1, rh2, dad, alpha, ast, att, omega, beta; + int iter; + + const double TOL = 1e-30; + + /*------------------------------------------------------------------------*/ + /*--- Initalization ----------------------------------------------------*/ + /*------------------------------------------------------------------------*/ + + *p = *b; + if (this->leftPrecon) + this->leftPrecon->precon(p); + double normB = norm(p); + + if (normB < TOL) { + INFO(this->info,2)("b == 0; x = 0 is the solution of the linear system\n"); + setValue(*x, 0.0); + this->residual = 0.0; + return(0); + } + + double save_tolerance = this->tolerance; + if (this->relative) + this->tolerance *= normB; + + *xmin = *x; + int imin = 0; + + // h = Ax + mv->matVec(NoTranspose, *x, *r); + + // h -= b + *r *= -1.0; + *r += *b; + + // preconditioning + if (this->leftPrecon) this->leftPrecon->precon(r); + + // rstar = h; + *rstar = *r; + + /*--- check initial residual -------------------------------------------*/ + + res = norm(r); + + START_INFO(); + if (SOLVE_INFO(0, res, &old_res)) { + if (this->relative) + this->tolerance = save_tolerance; + return(0); + } + + double normrmin = res; + + // d = h + *p = *r; + + // rh1 = h*rstar + rh1 = *r * *rstar; + + /*------------------------------------------------------------------------*/ + /*--- Iteration --------------------------------------------------------*/ + /*------------------------------------------------------------------------*/ + + for (iter = 1; iter <= this->max_iter; iter++) { + /*--- calculate CA.d and CA.d*rstar ----------------------------------*/ + + // CAd = Ad + mv->matVec(NoTranspose, *p, *v); + + if (this->leftPrecon) this->leftPrecon->precon(v); + + // dad = CAd * rstar; + dad = *v * *rstar; + + alpha = rh1/dad; + + if (abs(alpha) > 1e+6 * (res/norm(v))) { + BREAK_INFO("(Ad,d^*)_2 = 0", iter, res, &old_res); + break; + } + + /*--- update s and t ------------------------------------------------*/ + + // s = h + + // s = -alpha CAd + s + axpy(-alpha, *v, *r); + + // x = -alpha d + x + axpy(alpha, *p, *x); + + res = norm(r); + if (res <= this->tolerance) { + double red = res/old_res; + INFO(this->info,2)("%5d | %12.5e | %8.2e\n", iter, res, red); + INFO(this->info,6)("finished successfully with %d iterations\n", iter); + if (this->relative) + this->tolerance = save_tolerance; + return(iter); + } + + if (res < normrmin) { // update minimal norm quantities + normrmin = res; + *xmin = *x; + imin = iter; + } else if (res > normrmin * 1e+6) { + INFO(this->info,2)("Linear solver diverges.\n"); + INFO(this->info,2)("Current iteration: %d.\n", iter); + INFO(this->info,2)("Current residual: %e.\n", res); + break; + } + + // t = As + mv->matVec(NoTranspose, *r, *t); + + if (this->leftPrecon) + this->leftPrecon->precon(t); + + /*--- calculate omega ------------------------------------------------*/ + + // ast = s*t + ast = *r * *t; + + // att = t*t + att = *t * *t; + + omega = ast/att; + + if (abs(omega) <= 1e-6 * (res/norm(t))) { + BREAK_INFO("omega = 0", iter, res, &old_res); + break; + } + + /*--- update x and calculate new h ----------------------------------*/ + + // x = -omega s + x + axpy(omega, *r, *x); + + // h = s - omega * h + axpy(-omega, *t, *r); + + res = norm(r); + if (SOLVE_INFO(iter, res, &old_res) == 1) { + if (this->relative) + this->tolerance = save_tolerance; + return(iter); + } + + if (res < normrmin) { // update minimal norm quantities + normrmin = res; + *xmin = *x; + imin = iter; + } else if (res > normrmin * 1e+6) { + INFO(this->info,2)("Linear solver diverges.\n"); + INFO(this->info,2)("Current iteration: %d.\n", iter); + INFO(this->info,2)("Current residual: %e.\n", res); + break; + } + + // rh2 = h * rstar + rh2 = *r * *rstar; + + beta = (rh2/rh1) * (alpha/omega); + + // d = -omega CAd + d + axpy(-omega, *v, *p); + + // d = h + beta d + *p *= beta; + *p += *r; + + rh1 = rh2; + } + + // returned solution is first with minimal residual + *x = *xmin; + iter = imin; + this->residual = normrmin; + + if (this->relative) + this->tolerance = save_tolerance; + + INFO(this->info,2)("The minimal norm was %e; it was achieved in iteration %d.\n", + this->residual, iter); + + return(iter); + } + +} diff --git a/AMDiS/src/BiCGStab2.h b/AMDiS/src/BiCGStab2.h new file mode 100644 index 0000000000000000000000000000000000000000..ac2e898ac32b46453f2caddf846111050a14b77d --- /dev/null +++ b/AMDiS/src/BiCGStab2.h @@ -0,0 +1,103 @@ +// ============================================================================ +// == == +// == AMDiS - Adaptive multidimensional simulations == +// == == +// ============================================================================ +// == == +// == crystal growth group == +// == == +// == Stiftung caesar == +// == Ludwig-Erhard-Allee 2 == +// == 53175 Bonn == +// == germany == +// == == +// ============================================================================ +// == == +// == http://www.caesar.de/cg/AMDiS == +// == == +// ============================================================================ + +/** \file BiCGStab2.h */ + +#ifndef AMDIS_BiCGStab2_H +#define AMDIS_BiCGStab2_H + +#include "OEMSolver.h" +#include "MemoryManager.h" + +namespace AMDiS +{ + + // ============================================================================ + // ===== class BiCGStab2 ====================================================== + // ============================================================================ + + /** + * \ingroup Solver + * + * \brief + * Solves a linear system by the stabilized BiCG method. + * Can be used for general non-singular system matrices. + */ + template<typename VectorType> + class BiCGStab2 : public OEMSolver<VectorType> + { + public: + MEMORY_MANAGED(BiCGStab2<VectorType>); + + /** \brief + * Creator class used in the OEMSolverMap. + */ + class Creator : public OEMSolverCreator<VectorType> + { + public: + MEMORY_MANAGED(Creator); + + virtual ~Creator() {}; + + /** \brief + * Returns a new BiCGStab2 object. + */ + OEMSolver<VectorType>* create() + { + return NEW BiCGStab2<VectorType>(this->name); + }; + }; + + /** \brief + * constructor + */ + BiCGStab2(::std::string name); + + /** \brief + * destructor + */ + ~BiCGStab2(); + + protected: + /** \brief + * realisation of OEMSolver::solveSystem + */ + int solveSystem(MatVecMultiplier<VectorType> *mv, + VectorType *x, VectorType *b); + + /** \brief + * realisation of OEMSolver::init + */ + void init(); + + /** \brief + * realisation of OEMSolver::exit + */ + void exit(); + + private: + // pointer to memory needed for solveSystem + VectorType *r, *rstar, *u, *v, *s, *w, *t, *xmin; + }; + +} + +#include "BiCGStab2.hh" + +#endif // AMDIS_BiCGStab2_H diff --git a/AMDiS/src/BiCGStab2.hh b/AMDiS/src/BiCGStab2.hh new file mode 100644 index 0000000000000000000000000000000000000000..421876e5bdab6bced69015dc5ef86127667ca50f --- /dev/null +++ b/AMDiS/src/BiCGStab2.hh @@ -0,0 +1,230 @@ +#include "Preconditioner.h" + +namespace AMDiS +{ + + template<typename VectorType> + BiCGStab2<VectorType>::BiCGStab2(::std::string name) + : OEMSolver<VectorType>(name), + r(NULL), rstar(NULL), u(NULL), v(NULL), s(NULL), w(NULL), t(NULL), + xmin(NULL) + {} + + template<typename VectorType> + BiCGStab2<VectorType>::~BiCGStab2() + {} + + template<typename VectorType> + void BiCGStab2<VectorType>::init() + { + r = this->vectorCreator->create(); + rstar = this->vectorCreator->create(); + u = this->vectorCreator->create(); + v = this->vectorCreator->create(); + s = this->vectorCreator->create(); + w = this->vectorCreator->create(); + t = this->vectorCreator->create(); + xmin = this->vectorCreator->create(); + } + + template<typename VectorType> + void BiCGStab2<VectorType>::exit() + { + this->vectorCreator->free(r); + this->vectorCreator->free(rstar); + this->vectorCreator->free(u); + this->vectorCreator->free(v); + this->vectorCreator->free(s); + this->vectorCreator->free(w); + this->vectorCreator->free(t); + this->vectorCreator->free(xmin); + } + + template<typename VectorType> + int BiCGStab2<VectorType>::solveSystem(MatVecMultiplier<VectorType> *mv, + VectorType *x, VectorType *b) + { + FUNCNAME("BiCGStab2::solveSystem()"); + + double res, old_res = -1.0; + double rho0, alpha, omega1, omega2, rho1, beta, gamma, mu, nu, tau; + int iter; + + const double TOL = 1e-30; + + /*------------------------------------------------------------------------*/ + /*--- Initalization ----------------------------------------------------*/ + /*------------------------------------------------------------------------*/ + + *u = *b; + if (this->leftPrecon) + this->leftPrecon->precon(u); + double normB = norm(u); + + if (normB < TOL) { + INFO(this->info, 2)("b == 0; x = 0 is the solution of the linear system\n"); + setValue(*x, 0.0); + this->residual = 0.0; + return(0); + } + + double save_tolerance = this->tolerance; + if (this->relative) + this->tolerance *= normB; + + *xmin = *x; + int imin = 0; + + // r = b - Ax + mv->matVec(NoTranspose, *x, *r); + *r *= -1.0; + *r += *b; + + if (this->leftPrecon) + this->leftPrecon->precon(r); + + /*--- check initial residual -------------------------------------------*/ + + res = norm(r); + + START_INFO(); + if (SOLVE_INFO(0, res, &old_res)) { + if (this->relative) + this->tolerance = save_tolerance; + return(0); + } + + double normrmin = res; + + // setting for the method + *rstar = *r; + *rstar *= 1.0 / res; + + rho0 = 1.0; + alpha = 0.0; + omega2 = 1.0; + // u->set(0.0); + setValue(*u, 0.0); + + /*------------------------------------------------------------------------*/ + /*--- Iteration --------------------------------------------------------*/ + /*------------------------------------------------------------------------*/ + + for (iter = 1; iter <= this->max_iter; iter++) { + rho0 *= -omega2; + + /*--- even BiCG step -------------------------------------------------*/ + + // updating u + rho1 = *r * *rstar; + beta = alpha * rho1 / rho0; + rho0 = rho1; + *u *= -beta; + *u += *r; + + // computing v + mv->matVec(NoTranspose, *u, *v); + if (this->leftPrecon) + this->leftPrecon->precon(v); + + // Updating x and r + gamma = *v * *rstar; + alpha = rho0 / gamma; + axpy(alpha, *u, *x); + axpy(-alpha, *v, *r); + + // computing s + mv->matVec(NoTranspose, *r, *s); + if (this->leftPrecon) + this->leftPrecon->precon(s); + + /*--- odd BiCG step --------------------------------------------------*/ + + // updating v + rho1 = *s * *rstar; + beta = alpha * rho1 / rho0; + rho0 = rho1; + *v *= -beta; + *v += *s; + + // computing w + mv->matVec(NoTranspose, *v, *w); + if (this->leftPrecon) + this->leftPrecon->precon(w); + + // updating u, r and s + gamma = *w * *rstar; + alpha = rho0 / gamma; + *u *= -beta; + *u += *r; + axpy(-alpha, *v, *r); + axpy(-alpha, *w, *s); + + // computing t + mv->matVec(NoTranspose, *s, *t); + if (this->leftPrecon) + this->leftPrecon->precon(t); + + /*--- CGR(2) part ----------------------------------------------------*/ + + // computing constants + omega1 = *r * *s; + mu = *s * *s; + nu = *s * *t; + tau = *t * *t; + omega2 = *r * *t; + tau -= nu * nu / mu; + omega2 -= nu * omega1 / mu; + omega2 /= tau; + omega1 -= nu * omega2; + omega1 /= mu; + + // updating x + axpy(omega1, *r, *x); + axpy(omega2, *s, *x); + axpy(alpha, *u, *x); + + // updating r + axpy(-omega1, *s, *r); + axpy(-omega2, *t, *r); + + /*--- checking accuracy ----------------------------------------------*/ + + res = norm(r); + if (SOLVE_INFO(iter, res, &old_res) == 1) { + if (this->relative) + this->tolerance = save_tolerance; + return(iter); + } + + // update minimal norm quantities + if (res < normrmin) { + normrmin = res; + *xmin = *x; + imin = iter; + } else if (res > normrmin * 1e+6) { + INFO(this->info,2)("Linear solver diverges.\n"); + INFO(this->info,2)("Current iteration: %d.\n", iter); + INFO(this->info,2)("Current residual: %e.\n", res); + break; + } + + // updating u + axpy(-omega1, *v, *u); + axpy(-omega2, *w, *u); + } + + // returned solution is first with minimal residual + *x = *xmin; + iter = imin; + this->residual = normrmin; + + if (this->relative) + this->tolerance = save_tolerance; + + INFO(this->info,2)("The minimal norm was %e; it was achieved in iteration %d.\n", + this->residual, iter); + + return(iter); + } +} diff --git a/AMDiS/src/BiCGStab_M.h b/AMDiS/src/BiCGStab_M.h new file mode 100644 index 0000000000000000000000000000000000000000..904a24fe57e82ea3f89f26d87d03d8a8eb988db2 --- /dev/null +++ b/AMDiS/src/BiCGStab_M.h @@ -0,0 +1,98 @@ +// ============================================================================ +// == == +// == AMDiS - Adaptive multidimensional simulations == +// == == +// ============================================================================ +// == == +// == crystal growth group == +// == == +// == Stiftung caesar == +// == Ludwig-Erhard-Allee 2 == +// == 53175 Bonn == +// == germany == +// == == +// ============================================================================ +// == == +// == http://www.caesar.de/cg/AMDiS == +// == == +// ============================================================================ + +/** \file BiCGStab_M.h */ + +#ifndef BICGStab_M_H +#define BICGStab_M_H + +namespace AMDiS { + + // ============================================================================ + // ===== class BiCGStab_M ===================================================== + // ============================================================================ + + /** + * \ingroup Solver + * + * \brief + * Solves a linear system by a stabilized BiCG method. + * Can be used for general matrices. + */ + template<typename VectorType> + class BiCGStab_M : public OEMSolver<VectorType> + { + public: + MEMORY_MANAGED(BiCGStab_M<VectorType>); + + /** \brief + * Creator class used in the OEMSolverMap. + */ + class Creator : public OEMSolverCreator<VectorType> + { + public: + MEMORY_MANAGED(Creator); + + virtual ~Creator() {}; + + /** \brief + * Returns a new BiCGStab_M object. + */ + OEMSolver<VectorType>* create() + { + return NEW BiCGStab_M<VectorType>(this->name); + }; + }; + + /** \brief + * constructor + */ + BiCGStab_M(::std::string name); + + /** \brief + * destructor + */ + ~BiCGStab_M(); + + protected: + /** \brief + * Implements OEMSolver<VectorType>::init(). + */ + void init(); + + /** \brief + * Implements OEMSolver<VectorType>::exit(). + */ + void exit(); + + /** \brief + * Implements OEMSolver<VectorType>::solve(). + */ + int solveSystem(MatVecMultiplier<VectorType> *mv, VectorType *x, VectorType *b); + + private: + // Pointers to memory needed for solveSystem + VectorType *r, *rt, *p, *v, *t, *ph, *sh, *xmin; + }; + +} + +#include "BiCGStab_M.hh" + +#endif // BICGStab_M_H diff --git a/AMDiS/src/BiCGStab_M.hh b/AMDiS/src/BiCGStab_M.hh new file mode 100644 index 0000000000000000000000000000000000000000..533c7ecb06213a8ddf40482622994facabad033d --- /dev/null +++ b/AMDiS/src/BiCGStab_M.hh @@ -0,0 +1,191 @@ +namespace AMDiS { + + template<typename VectorType> + BiCGStab_M<VectorType>::BiCGStab_M(::std::string name) : OEMSolver<VectorType>(name) {} + + template<typename VectorType> + BiCGStab_M<VectorType>::~BiCGStab_M() {} + + template<typename VectorType> + void BiCGStab_M<VectorType>::init() + { + r = this->vectorCreator->create(); + rt = this->vectorCreator->create(); + p = this->vectorCreator->create(); + v = this->vectorCreator->create(); + t = this->vectorCreator->create(); + ph = this->vectorCreator->create(); + sh = this->vectorCreator->create(); + xmin = this->vectorCreator->create(); + } + + template<typename VectorType> + void BiCGStab_M<VectorType>::exit() + { + this->vectorCreator->free(r); + this->vectorCreator->free(rt); + this->vectorCreator->free(p); + this->vectorCreator->free(v); + this->vectorCreator->free(t); + this->vectorCreator->free(ph); + this->vectorCreator->free(sh); + this->vectorCreator->free(xmin); + } + + template<typename VectorType> + int BiCGStab_M<VectorType>::solveSystem(MatVecMultiplier<VectorType> *matVec, + VectorType *x, VectorType *b) + { + FUNCNAME("BiCGStab_M::solveSystem"); + double old_res = -1.0; + int iter, imin; + double n2b, normrmin, rho, rho1, omega, alpha = 0.0, beta, rtv; + + const double TOL_0 = 1e-30, TOL_INF = 1e+30; + + double save_tolerance = this->tolerance; + + // Check for all zero right hand side vector => all zero solution + n2b = norm(b); // norm of rhs vector b + if (n2b < TOL_0) + { + INFO(this->info,2)("b == 0, x = 0 is the solution of the linear system\n"); + set(*x, 0.0); // solution is all zeros + this->residual = 0.0; // residual is zero + return(0); // no iterations need to be performed + } + + if (this->relative) this->tolerance *= n2b; + + // Set up for the method + *xmin = *x; // iterate which has minimal residual so far + imin = 0; // iteration at which xmin was computed + matVec->matVec(NoTranspose, *x, *r); + *r *= -1.0; + *r += *b; // zero-th order residual + this->residual = norm(r); // norm of the residual + + START_INFO(); + if (SOLVE_INFO(0, this->residual, &old_res) == 1) + { + if (this->relative) this->tolerance = save_tolerance; + return(0); // initial guess is a good enough solution + } + + *rt = *r; // shadow residual + normrmin = this->residual; // norm of residual from xmin + rho = 1.0; + omega = 1.0; + + // Loop over maxit iterations (unless convergence or failure) + for (iter = 1; iter <= this->max_iter; iter++) + { + rho1 = rho; + rho = *r * *rt; + if (abs(rho) < TOL_0 || abs(rho) > TOL_INF) + { + BREAK_INFO("R and RT have become orthogonal", iter, this->residual, &old_res); + break; + } + + if (iter == 1) + *p = *r; + else + { + beta = (rho/rho1) * (alpha/omega); + if (abs(beta) < TOL_0 || abs(beta) > TOL_INF) + { + BREAK_INFO("beta has become too small or too large to continue " + "computing", iter, this->residual, &old_res); + break; + } + axpy(-omega, *v, *p); + *p *= beta; + *p += *r; + } + + *ph = *p; + if (this->leftPrecon) + this->leftPrecon->precon(ph); + + matVec->matVec(NoTranspose, *ph, *v); + + rtv = *v * *rt; + if (abs(rtv) < TOL_0 || abs(rtv) > TOL_INF) + { + BREAK_INFO("V and RT have become orthogonal", iter, this->residual, &old_res); + break; + } + + alpha = rho / rtv; + if (abs(alpha) > TOL_INF) + { + BREAK_INFO("alpha has become too large to continue computing", + iter, this->residual, &old_res); + break; + } + + axpy(alpha, *ph, *x); // form the "half" iterate + axpy(-alpha, *v, *r); // and its residual + this->residual = norm(r); + + if (this->residual < normrmin) // update minimal norm quantities + { + normrmin = this->residual; + *xmin = *x; + imin = iter; + } + + if (abs(alpha) < TOL_0) + { + BREAK_INFO("Stagnation of the method", iter, this->residual, &old_res); + break; // stagnation of the method + } + + *sh = *r; // residual associated with xhalf + if (this->leftPrecon) + this->leftPrecon->precon(sh); + matVec->matVec(NoTranspose, *sh, *t); + + omega = (*t * *r) / (*t * *t); + if (abs(omega) > TOL_INF) + { + BREAK_INFO("omega has become too large to continue computing", + iter, this->residual, &old_res); + break; + } + + axpy(omega, *sh, *x); // update x + axpy(-omega, *t, *r); + this->residual = norm(r); + if (SOLVE_INFO(iter, this->residual, &old_res) == 1) + { + if (this->relative) this->tolerance = save_tolerance; + return(iter); // check for convergence + } + + if (this->residual < normrmin) // update minimal norm quantities + { + normrmin = this->residual; + *xmin = *x; + imin = iter; + } + + if (abs(omega) < TOL_0) + { + BREAK_INFO("T and S have become orthogonal", iter, this->residual, &old_res); + break; // stagnation of the method + } + } // end for (iter = 1; iter <= this->max_iter; iter++) + + // returned solution is first with minimal residual + *x = *xmin; + iter = imin; + this->residual = normrmin; + + if (this->relative) this->tolerance = save_tolerance; + + return(iter); + } + +} diff --git a/AMDiS/src/Boundary.cc b/AMDiS/src/Boundary.cc new file mode 100644 index 0000000000000000000000000000000000000000..fa0ecb4cc7574b935cd6e6f0444bc35ab161993d --- /dev/null +++ b/AMDiS/src/Boundary.cc @@ -0,0 +1,30 @@ +#include "Boundary.h" +#include "FixVec.h" +#include "Parameters.h" + +namespace AMDiS { + + BoundaryType newBound(BoundaryType oldBound, BoundaryType newBound) + { + if (newBound <= INTERIOR) { + /*************************************************************************/ + /* face on NEUMANN-boundary or interior face; weak type */ + /*************************************************************************/ + return(oldBound); + } else { + /*************************************************************************/ + /* node is already node on the DIRICHLET boundary */ + /*************************************************************************/ + if (oldBound > newBound) + return(oldBound); + else + return(newBound); + } + + /**************************************************************************/ + /* new face is interior face; node type is always stronger */ + /**************************************************************************/ + return(newBound); + } + +} diff --git a/AMDiS/src/Boundary.h b/AMDiS/src/Boundary.h new file mode 100644 index 0000000000000000000000000000000000000000..bf3567de13032d9c82bdfa018755fdc0c2cf2a60 --- /dev/null +++ b/AMDiS/src/Boundary.h @@ -0,0 +1,162 @@ +// ============================================================================ +// == == +// == AMDiS - Adaptive multidimensional simulations == +// == == +// ============================================================================ +// == == +// == crystal growth group == +// == == +// == Stiftung caesar == +// == Ludwig-Erhard-Allee 2 == +// == 53175 Bonn == +// == germany == +// == == +// ============================================================================ +// == == +// == http://www.caesar.de/cg/AMDiS == +// == == +// ============================================================================ + +/** \file Boundary.h */ + +#ifndef AMDIS_BOUNDARY_H +#define AMDIS_BOUNDARY_H + +#include "Global.h" +#include "MemoryManager.h" +#include <map> + +namespace AMDiS { + + template<typename T> class WorldVector; + + /** \brief + * Contains boundary constants + */ + typedef enum { + INTERIOR=0, /**< interior => no boundary (b = 0) */ + DIRICHLET=1, /**< dirichlet boundary (b > 0) */ + NEUMANN=-1, /**< neumann boundary (-100 < b < 0) */ + ROBIN=-100 /**< robin boundary ( b <= -100) */ + } BoundaryConstants; + + /** \brief + * Type specifier for the different boundary types + */ + typedef signed int BoundaryType; + + // /** \ingroup Triangulation + // * \brief + // * Holds information about the type of boundary associated to an edge/face, + // * and how new vertices are projected to the boundary in the case of curved + // * boundaries. + // + // class Boundary + // { + // public: + // MEMORY_MANAGED(Boundary); + + // /** \brief + // * constructor + // + // Boundary(BoundaryType type=0) { + // bound = type; + // }; + + // /** \brief + // * copy constructor + // + // Boundary(const Boundary& old) { bound = old.getBound(); }; + + // /** \brief + // * destructor + // + // virtual ~Boundary() {}; + + // /** \brief + // * assignment operator + // + // Boundary& operator=(const Boundary& old) { + // if (this!=&old) bound = old.getBound(); + // return *this; + // }; + + // /** \brief + // * Returns + // * -true: if a new vertex should be projected to a curved boundary + // * -false: otherwise + // + // virtual bool interpolateBoundary() { return false; }; + + // /** \brief + // * Projection to the curved boundary + // + // virtual void interpolateBoundary(WorldVector<double>& ) {}; + + // /** \brief + // * Returns \ref bound + // + // inline const BoundaryType getBound() const { return bound; }; + + // /** \brief + // * Returns + // * -true: is \ref bound is INTERIOR + // * -false: otherwise + // + // inline const bool isInterior() const {return (bound == INTERIOR);}; + + // /** \brief + // * Returns + // * -true: is \ref bound is DIRICHLET + // * -false: otherwise + // + // inline const bool isDirichlet() const {return (bound == DIRICHLET);}; + + // /** \brief + // * Returns + // * -true: is \ref bound is NEUMANN + // * -false: otherwise + // + // inline const bool isNeumann() const {return (bound == NEUMANN);}; + + // /** \brief + // * Returns + // * -true: is \ref bound is ROBIN + // * -false: otherwise + // + // inline const bool isRobin() const {return (bound == ROBIN);}; + + // /** \brief + // * Returns the new value of \ref bound with respect to its old value and + // * the value of bound_. + // + // BoundaryType newVal(const BoundaryType bound_); + + // /** \brief + // * Returns the Boundary with given type from \ref boundaryMap. + // + // static Boundary* getBoundary(BoundaryType type); + + // /** \brief + // * Adds Boundary b to \ref boundaryMap. + // + // //static void addBoundary(Boundary *b); + + // protected: + // /** \brief + // * type of this boundary + // + // BoundaryType bound; + + // protected: + // /** \brief + // * stl map of all existing boundaries. + // + // static ::std::map<BoundaryType, Boundary*> boundaryMap; + // }; + + BoundaryType newBound(BoundaryType oldBound, BoundaryType newBound); + +} + +#endif // !_Boundary_H_ diff --git a/AMDiS/src/BoundaryCondition.h b/AMDiS/src/BoundaryCondition.h new file mode 100644 index 0000000000000000000000000000000000000000..34626153b8d5012a41a93ddbae26dbce7a334de2 --- /dev/null +++ b/AMDiS/src/BoundaryCondition.h @@ -0,0 +1,146 @@ +// ============================================================================ +// == == +// == AMDiS - Adaptive multidimensional simulations == +// == == +// ============================================================================ +// == == +// == crystal growth group == +// == == +// == Stiftung caesar == +// == Ludwig-Erhard-Allee 2 == +// == 53175 Bonn == +// == germany == +// == == +// ============================================================================ +// == == +// == http://www.caesar.de/cg/AMDiS == +// == == +// ============================================================================ + +/** \file BoundaryCondition.h */ + +#ifndef AMDIS_BOUNDARYCONDITION_H +#define AMDIS_BOUNDARYCONDITION_H + +#include "Boundary.h" +#include "FiniteElemSpace.h" + +namespace AMDiS { + + class DOFMatrix; + template<typename T> class DOFVectorBase; + class Estimator; + class ElInfo; + + // ============================================================================ + // ===== class BoundaryCondition ============================================== + // ============================================================================ + + /** + * \ingroup Assembler + * + * \brief + * Sub class of BoundaryCondition. Local boundary conditions are filled + * while mesh traversal. + */ + class BoundaryCondition //: public BoundaryCondition + { + public: + /** \brief + * Constructor. + */ + BoundaryCondition(BoundaryType type, + const FiniteElemSpace *rowFESpace_, + const FiniteElemSpace *colFESpace_ = NULL) + : boundaryType(type), + rowFESpace(rowFESpace_), + colFESpace(colFESpace_) + { + if(!colFESpace) colFESpace = rowFESpace; + }; + + /** \brief + * Returns \ref boundaryType. + */ + inline BoundaryType getBoundaryType() { return boundaryType; }; + + /** \brief + * Returns \ref rowFESpace. + */ + inline const FiniteElemSpace *getRowFESpace() { return rowFESpace; }; + + /** \brief + * Returns \ref rowFESpace. + */ + inline const FiniteElemSpace *getColFESpace() { return colFESpace; }; + + virtual void initMatrix(DOFMatrix*) {}; + + virtual void exitMatrix(DOFMatrix*) {}; + + virtual void initVector(DOFVectorBase<double>*) {}; + + virtual void exitVector(DOFVectorBase<double>*) {}; + + /** \brief + * Destructor. + */ + virtual ~BoundaryCondition() {}; + + /** \brief + * Adds the local boundary condition for elInfo to object. + * The dofIndices and localBound as well as nBasFcts are determined by + * the calling BoundaryManager. + */ + virtual void fillBoundaryCondition(DOFMatrix *matrix, + ElInfo *elInfo, + const DegreeOfFreedom *dofIndices, + const BoundaryType *localBound, + int nBasFcts) {}; + + /** \brief + * Adds the local boundary condition for elInfo to vector. + * The dofIndices and localBound as well as nBasFcts are determined by + * the calling BoundaryManager. + */ + virtual void fillBoundaryCondition(DOFVectorBase<double> *vector, + ElInfo *elInfo, + const DegreeOfFreedom *dofIndices, + const BoundaryType *localBound, + int nBasFcts) {}; + + /** \brief + * Returns the boundary residual for the given element. Called by estimator. + */ + virtual double boundResidual(ElInfo *elInfo, + DOFMatrix *matrix, + const DOFVectorBase<double> *dv) { return 0.0; }; + + /** \brief + * Returns whether the condition must be treated as dirichlet condition + * while assemblage. + */ + virtual bool isDirichlet() { return false; }; + + protected: + /** \brief + * Speciefies for which parts of the boundary the condition holds. + * This id corresponds to the boundary numbers spcified in the + * macro file. + */ + BoundaryType boundaryType; + + /** \brief + * FiniteElemSpace for this BoundaryCondition. + */ + const FiniteElemSpace *rowFESpace; + + /** \brief + * FiniteElemSpace for this BoundaryCondition. + */ + const FiniteElemSpace *colFESpace; + }; + +} + +#endif diff --git a/AMDiS/src/BoundaryManager.cc b/AMDiS/src/BoundaryManager.cc new file mode 100644 index 0000000000000000000000000000000000000000..b28f95d0af510a36e941bc70b37a888982e3f22f --- /dev/null +++ b/AMDiS/src/BoundaryManager.cc @@ -0,0 +1,207 @@ +#include "FiniteElemSpace.h" +//#include "BoundaryCondition.h" +#include "BoundaryManager.h" +#include "DOFIndexed.h" +#include "DOFVector.h" +#include "Traverse.h" +#include "BasisFunction.h" +#include "ElInfo.h" + +namespace AMDiS { + + double BoundaryManager::boundResidual(ElInfo *elInfo, + DOFMatrix *matrix, + const DOFVectorBase<double> *dv) + { + double result = 0; + ::std::map<BoundaryType, BoundaryCondition*>::iterator it; + for(it = localBCs.begin(); it != localBCs.end(); ++it) { + if((*it).second) + result += (*it).second->boundResidual(elInfo, matrix, dv); + } + return result; + } + + void BoundaryManager::fillBoundaryConditions(ElInfo *elInfo, + DOFVectorBase<double> *vec) + { + // ===== fill local conditions ============================================== + const FiniteElemSpace *feSpace = vec->getFESpace(); + const BoundaryType *localBound = NULL; + const DegreeOfFreedom *dofIndices = NULL; + const BasisFunction *basisFcts = feSpace->getBasisFcts(); + int nBasFcts = basisFcts->getNumber(); + DOFAdmin *admin = feSpace->getAdmin(); + + ::std::map<BoundaryType, BoundaryCondition*>::iterator it; + + if(localBCs.size() > 0) { + + // get boundaries of all DOFs + localBound = basisFcts->getBound(elInfo, NULL); + + // get dof indices + dofIndices = basisFcts->getLocalIndices(elInfo->getElement(), + admin, NULL); + + // apply non dirichlet boundary conditions + for(it = localBCs.begin(); it != localBCs.end(); ++it) { + if((*it).second) { + if(!(*it).second->isDirichlet()) { + (*it).second->fillBoundaryCondition(vec, elInfo, dofIndices, localBound, nBasFcts); + } + } + } + + // apply dirichlet boundary conditions + for(it = localBCs.begin(); it != localBCs.end(); ++it) { + if((*it).second) { + if((*it).second->isDirichlet()) { + (*it).second->fillBoundaryCondition(vec, elInfo, dofIndices, localBound, nBasFcts); + } + } + } + } + } + + void BoundaryManager::fillBoundaryConditions(ElInfo *elInfo, + DOFMatrix *mat) + { + // ===== fill local conditions ============================================== + const FiniteElemSpace *feSpace = mat->getRowFESpace(); + const BoundaryType *localBound = NULL; + const DegreeOfFreedom *dofIndices = NULL; + const BasisFunction *basisFcts = feSpace->getBasisFcts(); + int nBasFcts = basisFcts->getNumber(); + DOFAdmin *admin = feSpace->getAdmin(); + + ::std::map<BoundaryType, BoundaryCondition*>::iterator it; + + if (localBCs.size() > 0) { + // get boundaries of all DOFs + localBound = basisFcts->getBound(elInfo, NULL); + + // get dof indices + dofIndices = basisFcts->getLocalIndices(elInfo->getElement(), admin, NULL); + + // apply non dirichlet boundary conditions + for (it = localBCs.begin(); it != localBCs.end(); ++it) { + if ((*it).second) { + if (!(*it).second->isDirichlet()) { + (*it).second->fillBoundaryCondition(mat, elInfo, dofIndices, localBound, nBasFcts); + } + } + } + + // apply dirichlet boundary conditions + for (it = localBCs.begin(); it != localBCs.end(); ++it) { + if ((*it).second) { + if ((*it).second->isDirichlet()) { + (*it).second->fillBoundaryCondition(mat, elInfo, dofIndices, localBound, nBasFcts); + } + } + } + } + } + + // void BoundaryManager::fillGlobalBoundVector(DOFVectorBase<BoundaryType> *bound) + // { + // int i; + // const BasisFunction *basFcts = bound->getFESpace()->getBasisFcts(); + // int numBasFcts = basFcts->getNumber(); + // TraverseStack stack; + // ElInfo *elInfo = stack.traverseFirst(bound->getFESpace()->getMesh(), + // -1, + // Mesh::CALL_LEAF_EL | Mesh::FILL_BOUND); + // while(elInfo) { + // const DegreeOfFreedom *localIndices = + // basFcts->getLocalIndices(elInfo->getElement(), + // bound->getFESpace()->getAdmin(), + // NULL); + + // for(i = 0; i < numBasFcts; i++) { + // (*bound)[localIndices[i]] = elInfo->getBoundary(i); + // } + + // elInfo = stack.traverseNext(elInfo); + // } + // } + + void BoundaryManager::initMatrix(DOFMatrix *matrix) + { + ::std::map<BoundaryType, BoundaryCondition*>::iterator it; + + for(it = localBCs.begin(); it != localBCs.end(); ++it) { + if((*it).second) { + if(!(*it).second->isDirichlet()) { + (*it).second->initMatrix(matrix); + } + } + } + for(it = localBCs.begin(); it != localBCs.end(); ++it) { + if((*it).second) { + if((*it).second->isDirichlet()) { + (*it).second->initMatrix(matrix); + } + } + } + } + + void BoundaryManager::exitMatrix(DOFMatrix *matrix) + { + ::std::map<BoundaryType, BoundaryCondition*>::iterator it; + for(it = localBCs.begin(); it != localBCs.end(); ++it) { + if((*it).second) { + if(!(*it).second->isDirichlet()) { + (*it).second->exitMatrix(matrix); + } + } + } + for(it = localBCs.begin(); it != localBCs.end(); ++it) { + if((*it).second) { + if((*it).second->isDirichlet()) { + (*it).second->exitMatrix(matrix); + } + } + } + } + + void BoundaryManager::initVector(DOFVectorBase<double> *vector) + { + ::std::map<BoundaryType, BoundaryCondition*>::iterator it; + for(it = localBCs.begin(); it != localBCs.end(); ++it) { + if((*it).second) { + if(!(*it).second->isDirichlet()) { + (*it).second->initVector(vector); + } + } + } + for(it = localBCs.begin(); it != localBCs.end(); ++it) { + if((*it).second) { + if((*it).second->isDirichlet()) { + (*it).second->initVector(vector); + } + } + } + } + + void BoundaryManager::exitVector(DOFVectorBase<double> *vector) + { + ::std::map<BoundaryType, BoundaryCondition*>::iterator it; + for(it = localBCs.begin(); it != localBCs.end(); ++it) { + if((*it).second) { + if(!(*it).second->isDirichlet()) { + (*it).second->exitVector(vector); + } + } + } + for(it = localBCs.begin(); it != localBCs.end(); ++it) { + if((*it).second) { + if((*it).second->isDirichlet()) { + (*it).second->exitVector(vector); + } + } + } + } + +} diff --git a/AMDiS/src/BoundaryManager.h b/AMDiS/src/BoundaryManager.h new file mode 100644 index 0000000000000000000000000000000000000000..c56ec264b27eb377e55b119310aa6bb1b6259257 --- /dev/null +++ b/AMDiS/src/BoundaryManager.h @@ -0,0 +1,117 @@ +// ============================================================================ +// == == +// == AMDiS - Adaptive multidimensional simulations == +// == == +// ============================================================================ +// == == +// == crystal growth group == +// == == +// == Stiftung caesar == +// == Ludwig-Erhard-Allee 2 == +// == 53175 Bonn == +// == germany == +// == == +// ============================================================================ +// == == +// == http://www.caesar.de/cg/AMDiS == +// == == +// ============================================================================ + +/** \file BoundaryManager.h */ + +#ifndef AMDIS_BOUNDARYMANAGER_H +#define AMDIS_BOUNDARYMANAGER_H + +#include <map> + +#include "Boundary.h" +#include "BoundaryCondition.h" + +namespace AMDiS { + + class DOFMatrix; + class FiniteElemSpace; + template<typename T> class DOFVectorBase; + + // ============================================================================ + // ===== class BoundaryManager ================================================ + // ============================================================================ + + /** + * \ingroup Assembler + * + * \brief + * A BoundaryManager handles a set of boundary conditions and applies + * this conditions to DOFVectorBase and DOFMatrix objects. Each DOFVectorBase + * and each DOFMatrix has its own BoundaryManager. + */ + class BoundaryManager + { + public: + MEMORY_MANAGED(BoundaryManager); + + /** \brief + * Adds a local boundary condition to the list of managed conditions. + */ + void addBoundaryCondition(BoundaryCondition *localBC) { + BoundaryType type = localBC->getBoundaryType(); + TEST_EXIT(localBCs[type] == NULL) + ("there is already a condition for this type\n"); + localBCs[type] = localBC; + }; + + void initMatrix(DOFMatrix *matrix); + + void exitMatrix(DOFMatrix *matrix); + + void initVector(DOFVectorBase<double> *vector); + + void exitVector(DOFVectorBase<double> *vector); + + /** \brief + * Calls DOFVectorBase::fillBoundaryCondition() for each local boundary condition + * in \ref localBCs. + */ + void fillBoundaryConditions(ElInfo *elInfo, DOFVectorBase<double> *vec); + + /** \brief + * Calls DOFMatrix::fillBoundaryCondition() for each local boundary condition + * in \ref localBCs. + */ + void fillBoundaryConditions(ElInfo *elInfo, DOFMatrix *mat); + + /** \brief + * Calls BoundaryCondition::boundResidual() for each boundary condition in + * \ref localBCs. + */ + double boundResidual(ElInfo *elInfo, + DOFMatrix *matrix, + const DOFVectorBase<double> *dv); + + inline BoundaryCondition *getBoundaryCondition(BoundaryType type) { + return localBCs[type]; + }; + + // /** \brief + // * Fills boundary types in DOFVectorBase bound. + // */ + // void fillGlobalBoundVector(DOFVectorBase<BoundaryType> *bound); + + const ::std::map<BoundaryType, BoundaryCondition*>& getBoundaryConditionMap() { + return localBCs; + }; + + void setBoundaryConditionMap(const ::std::map<BoundaryType, BoundaryCondition*>& bcs) { + localBCs = bcs; + }; + + protected: + /** \brief + * Map of managed local boundary conditions. + */ + ::std::map<BoundaryType, BoundaryCondition*> localBCs; + }; + +} + +#endif diff --git a/AMDiS/src/BoundaryManager.hh b/AMDiS/src/BoundaryManager.hh new file mode 100644 index 0000000000000000000000000000000000000000..de1e045defb4e6ee7b9c1e8dde01ab0de0e30c61 --- /dev/null +++ b/AMDiS/src/BoundaryManager.hh @@ -0,0 +1,130 @@ +#include "FiniteElemSpace.h" +#include "DOFIndexed.h" +#include "DOFVector.h" +#include "Traverse.h" +#include "BasisFunction.h" +#include "ElInfo.h" +#include "BoundaryCondition.h" +#include <list> + +namespace AMDiS { + + template<typename T> + double BoundaryManager<T>::boundResidual(ElInfo *elInfo, Estimator<T> *estimator) + { + double result = 0; + typename ::std::list<LocalBC<T>*>::iterator it; + for(it = localBCs.begin(); it != localBCs.end(); ++it) { + result += (*it)->boundResidual(elInfo, estimator); + } + return result; + } + + template<typename T> + void BoundaryManager<T>::fillGlobalBoundVector(DOFVector<BoundaryType> *globalBound) + { + int i; + TraverseStack stack; + const FiniteElemSpace *feSpace = globalBound->getFESpace(); + + const BasisFunction *basisFcts = feSpace->getBasisFcts(); + int nBasFcts = basisFcts->getNumber(); + Mesh *mesh = feSpace->getMesh(); + DOFAdmin *admin = feSpace->getAdmin(); + + const BoundaryType *localBound = NULL; + const DegreeOfFreedom *dofIndices = NULL; + + ElInfo *elInfo = + stack.traverseFirst(mesh, -1, + Mesh::CALL_LEAF_EL | + Mesh::FILL_BOUND | + Mesh::FILL_COORDS); + + // for all elements ... + while(elInfo) { + // get boundaries of all DOFs + localBound = basisFcts->getBound(elInfo, NULL); + + // get dof indices + dofIndices = basisFcts->getLocalIndices(elInfo->getElement(), + admin, NULL); + + // for all DOFs + for(i=0; i < nBasFcts; i++) { + (*globalBound)[dofIndices[i]] = localBound[i]; + } + + elInfo = stack.traverseNext(elInfo); + } + } + + template<typename T> + void BoundaryManager<T>::fillLocalBCs(ElInfo *elInfo, + DOFVector<T> *vec) + { + int i; + + // ===== fill local conditions ============================================== + const FiniteElemSpace *feSpace = vec->getFESpace(); + const BoundaryType *localBound = NULL; + const DegreeOfFreedom *dofIndices = NULL; + Mesh *mesh = feSpace->getMesh(); + const BasisFunction *basisFcts = feSpace->getBasisFcts(); + int nBasFcts = basisFcts->getNumber(); + LocalBC<T> *localBC; + DOFAdmin *admin = feSpace->getAdmin(); + + typename ::std::list<LocalBC<T>*>::iterator it; + + if(localBCs.size() > 0) { + + // get boundaries of all DOFs + localBound = basisFcts->getBound(elInfo, NULL); + + // get dof indices + dofIndices = basisFcts->getLocalIndices(elInfo->getElement(), + admin, NULL); + + // apply boundary conditions + for(it = localBCs.begin(); it != localBCs.end(); ++it) { + (*it)->fillLocalBC(vec, elInfo, dofIndices, localBound, nBasFcts); + } + } + } + + template<typename T> + void BoundaryManager<T>::fillLocalBCs(ElInfo *elInfo, + DOFMatrix *mat) + { + int i; + + // ===== fill local conditions ============================================== + const FiniteElemSpace *feSpace = mat->getRowFESpace(); + const BoundaryType *localBound = NULL; + const DegreeOfFreedom *dofIndices = NULL; + Mesh *mesh = feSpace->getMesh(); + const BasisFunction *basisFcts = feSpace->getBasisFcts(); + int nBasFcts = basisFcts->getNumber(); + LocalBC<T> *localBC; + DOFAdmin *admin = feSpace->getAdmin(); + + typename ::std::list<LocalBC<T>*>::iterator it; + + if(localBCs.size() > 0) { + + // get boundaries of all DOFs + localBound = basisFcts->getBound(elInfo, NULL); + + // get dof indices + dofIndices = basisFcts->getLocalIndices(elInfo->getElement(), + admin, NULL); + + // apply boundary conditions + for(it = localBCs.begin(); it != localBCs.end(); ++it) { + (*it)->fillLocalBC(mat, elInfo, dofIndices, localBound, nBasFcts); + } + } + } + +} diff --git a/AMDiS/src/BoxSmoother.h b/AMDiS/src/BoxSmoother.h new file mode 100644 index 0000000000000000000000000000000000000000..dcb7220274847267ab1273795f3e63cd1632f7de --- /dev/null +++ b/AMDiS/src/BoxSmoother.h @@ -0,0 +1,227 @@ +#ifndef AMDIS_BOXSMOOTHER_H +#define AMDIS_BOXSMOOTHER_H + +#include "SmootherBase.h" +#include "MemoryManager.h" +#include "DOFMatrix.h" +#include "SparseVector.h" +#include "MatrixVector.h" +#include "Global.h" +#include "GaussElimination.h" +#include "FiniteElemSpace.h" +#include "GaussElimination.h" +#include <set> + +namespace AMDiS { + + class BoxSmoother + : public SmootherBase<Matrix<DOFMatrix*>, + Vector<SparseVector<double>*>, + Vector< ::std::set<DegreeOfFreedom>*> > + { + public: + MEMORY_MANAGED(BoxSmoother); + + class Creator + : public SmootherCreator<Matrix<DOFMatrix*>, + Vector<SparseVector<double>*>, + Vector< ::std::set<DegreeOfFreedom>*> > + { + public: + MEMORY_MANAGED(Creator); + + SmootherBase<Matrix<DOFMatrix*>, + Vector<SparseVector<double>*>, + Vector< ::std::set<DegreeOfFreedom>*> >* + create() { + return NEW BoxSmoother(this->name); + }; + }; + + BoxSmoother(::std::string name) + : SmootherBase<Matrix<DOFMatrix*>, + Vector<SparseVector<double>*>, + Vector< ::std::set<DegreeOfFreedom>*> >(name), + boxMatrix_(NULL), + boxSolution_(NULL), + boxRHS_(NULL), + numComponents_(0), + sumDOFs_(0) + { + directSolver_ = + NEW GaussElimination<Matrix<double>, Vector<double> >(); + }; + + virtual ~BoxSmoother() + { + if(boxMatrix_) DELETE boxMatrix_; + if(boxSolution_) DELETE boxSolution_; + if(boxRHS_) DELETE boxRHS_; + DELETE directSolver_; + }; + + void smooth(Matrix<DOFMatrix*> *matrix, + Vector<SparseVector<double>*> *solution, + Vector<SparseVector<double>*> *rhs, + int iterations, + const Vector< ::std::set<DegreeOfFreedom>*> &dofSet) + { + FUNCNAME("BoxSmoother::smooth()"); + + int i, j, k; + + // allocate memory + if(!boxMatrix_) { + numComponents_ = solution->getSize(); + numDOFs_.resize(numComponents_); + sumDOFs_ = 0; + for(i = 0; i < numComponents_; i++) { + numDOFs_[i] = (*solution)[i]->getFESpace()->getBasisFcts()->getNumber(); + sumDOFs_ += numDOFs_[i]; + } + + boxMatrix_ = NEW Matrix<double>(sumDOFs_, sumDOFs_); + boxSolution_ = NEW Vector<double>(sumDOFs_); + boxRHS_ = NEW Vector<double>(sumDOFs_); + } + + // create local equation system + int boxSize = 0; + ::std::vector<int> offset(numComponents_, 0); + ::std::vector< ::std::map<DegreeOfFreedom, int> > indexOfDOF(numComponents_); + ::std::set<DegreeOfFreedom>::const_iterator dofIt, dofBegin, dofEnd; + ::std::vector<MatEntry>::iterator rowIt, rowBegin, rowEnd; + + int pos; + for(i = 0; i < numComponents_; i++) { + if(dofSet[i]) { + offset[i] = boxSize; + boxSize += numDOFs_[i]; + dofBegin = dofSet[i]->begin(); + dofEnd = dofSet[i]->end(); + pos = 0; + for(dofIt = dofBegin; dofIt != dofEnd; ++dofIt) { + indexOfDOF[i][*dofIt] = pos + 1; +// MSG("%d : %d, %d \n", *dofIt, i, pos); + ++pos; + } + } + } + + for(i = 0; i < boxSize; i++) { + for(j = 0; j < boxSize; j++) { + (*boxMatrix_)[i][j] = 0.0; + } + (*boxRHS_)[i] = 0.0; + } + + pos = 0; + for(i = 0; i < numComponents_; i++) { + if(dofSet[i]) { + dofBegin = dofSet[i]->begin(); + dofEnd = dofSet[i]->end(); + for(dofIt = dofBegin; dofIt != dofEnd; ++dofIt) { + + // fill box rhs + (*boxRHS_)[pos] = (*((*rhs)[i]))[*dofIt]; + + // fill box matrix + for(j = 0; j < numComponents_; j++) { + if((*matrix)[i][j] != NULL) { + rowBegin = (*((*matrix)[i][j]))[*dofIt].begin(); + rowEnd = (*((*matrix)[i][j]))[*dofIt].end(); + for(rowIt = rowBegin; rowIt != rowEnd; ++rowIt) { + if(rowIt->col == DOFMatrix::UNUSED_ENTRY) continue; + if(rowIt->col == DOFMatrix::NO_MORE_ENTRIES) break; + int ind = indexOfDOF[j][rowIt->col] - 1; + if(ind != -1) { + (*boxMatrix_)[pos][offset[j] + ind] = rowIt->entry; + } else { + (*boxRHS_)[pos] -= + rowIt->entry * (*((*solution)[j]))[rowIt->col]; + } + } + } else { + for(k = 0; k < numDOFs_[j]; k++) { + (*boxMatrix_)[pos][offset[j] + k] = 0.0; + } + } + } + + ++pos; + } + } + } + +// int a,b; + +// for(i = 0; i < numComponents_; i++) { +// MSG("DOFs %d: ", i); +// dofBegin = dofSet[i]->begin(); +// dofEnd = dofSet[i]->end(); +// for(dofIt = dofBegin; dofIt != dofEnd; ++dofIt) { +// MSG("%d ", *dofIt); +// } +// MSG("\n"); +// } + +// for(a = 0; a < numComponents_; a++) { +// for(b = 0; b < numComponents_; b++) { +// MSG("matrix[%d][%d]:\n", a, b); +// if((*matrix)[a][b]) { +// (*matrix)[a][b]->print(); +// MSG("solution[%d]\n", b); +// (*solution)[b]->print(); +// MSG("rhs[%d]\n", a); +// (*rhs)[a]->print(); +// } +// } +// } + +// MSG("matrix:\n"); +// for(a = 0; a < boxSize; a++) { +// for(b = 0; b < boxSize; b++) { +// MSG("%e ", (*boxMatrix_)[a][b]); +// } +// MSG("\n"); +// } + +// MSG("rhs:\n"); +// for(a = 0; a < boxSize; a++) { +// MSG("%e\n", (*boxRHS_)[a]); +// } + + // apply direct solver + directSolver_->solve(*boxMatrix_, *boxRHS_, *boxSolution_, boxSize); + +// MSG("solution:\n"); +// for(a = 0; a < boxSize; a++) { +// MSG("%e\n", (*boxSolution_)[a]); +// } + +// WAIT_REALLY; + + // copy solution + pos = 0; + for(i = 0; i < numComponents_; i++) { + dofBegin = dofSet[i]->begin(); + dofEnd = dofSet[i]->end(); + for(dofIt = dofBegin; dofIt != dofEnd; ++dofIt) { + (*((*solution)[i]))[*dofIt] = (*boxSolution_)[pos]; + ++pos; + } + } + }; + + protected: + Matrix<double> *boxMatrix_; + Vector<double> *boxSolution_; + Vector<double> *boxRHS_; + int numComponents_; + ::std::vector<int> numDOFs_; + int sumDOFs_; + DirectSolverInterface<Matrix<double>, Vector<double> > *directSolver_; + }; +} + +#endif diff --git a/AMDiS/src/CGSolver.h b/AMDiS/src/CGSolver.h new file mode 100644 index 0000000000000000000000000000000000000000..986f0f177dfe10827047d957042177f740543146 --- /dev/null +++ b/AMDiS/src/CGSolver.h @@ -0,0 +1,114 @@ +// ============================================================================ +// == == +// == AMDiS - Adaptive multidimensional simulations == +// == == +// ============================================================================ +// == == +// == crystal growth group == +// == == +// == Stiftung caesar == +// == Ludwig-Erhard-Allee 2 == +// == 53175 Bonn == +// == germany == +// == == +// ============================================================================ +// == == +// == http://www.caesar.de/cg/AMDiS == +// == == +// ============================================================================ + +/** \file CGSolver.h */ + +#ifndef AMDIS_CGSOLVER_H +#define AMDIS_CGSOLVER_H + +namespace AMDiS { + + #include "OEMSolver.h" + #include "MemoryManager.h" + + // ============================================================================ + // ===== class CGSolver ======================================================= + // ============================================================================ + + /** + * \ingroup Solver + * + * \brief + * Solves a linear system by the conjugate gradient method and can be used for + * symmetric positive definite system matrices. + * + * The implementation is based on the following book: "Numerik linearer + * Gleichungssystene", 2. Auflage, Andreas Meister. The algorithm is described + * on page 124. The extension to the preconditioned cg method (pcg) is described + * on page 207 in the same book. We here use the same variable names, but without + * subscription. + */ + template<typename VectorType> + class CGSolver : public OEMSolver<VectorType> + { + public: + MEMORY_MANAGED(CGSolver<VectorType>); + + /** \brief + * Creator class used in the OEMSolverMap. + */ + class Creator : public OEMSolverCreator<VectorType> + { + public: + MEMORY_MANAGED(Creator); + + virtual ~Creator() {}; + + /** \brief + * Returns a new CGSolver object. + */ + OEMSolver<VectorType>* create() { + return NEW CGSolver<VectorType>(this->name); + }; + }; + + /** \brief + * constructor + */ + CGSolver(::std::string name); + + /** \brief + * destructor + */ + ~CGSolver(); + + protected: + /** \brief + * Implements OEMSolver<VectorType>::init(). + */ + void init() { + p = this->vectorCreator->create(); + r = this->vectorCreator->create(); + v = this->vectorCreator->create(); + z = this->vectorCreator->create(); + }; + + /** \brief + * Implements OEMSolver<VectorType>::exit(). + */ + void exit() { + this->vectorCreator->free(p); + this->vectorCreator->free(r); + this->vectorCreator->free(v); + this->vectorCreator->free(z); + }; + + /** \brief + * Implements OEMSolver<VectorType>::solve(). + */ + int solveSystem(MatVecMultiplier<VectorType> *mv, VectorType *x, VectorType *b); + + private: + VectorType *p, *r, *v, *z; + }; +} + +#include "CGSolver.hh" + +#endif // AMDIS_CGSOLVER_H diff --git a/AMDiS/src/CGSolver.hh b/AMDiS/src/CGSolver.hh new file mode 100644 index 0000000000000000000000000000000000000000..00c001cea2eda6ed1b20c39846ccc643c85eac32 --- /dev/null +++ b/AMDiS/src/CGSolver.hh @@ -0,0 +1,134 @@ +#include "DOFVector.h" +#include "DOFMatrix.h" +#include "MatVecMultiplier.h" +#include "StlVector.h" +#include "V3Vector.h" + +namespace AMDiS { + + template<typename VectorType> + CGSolver<VectorType>::CGSolver(::std::string name) + : OEMSolver<VectorType>(name) + {} + + template<typename VectorType> + CGSolver<VectorType>::~CGSolver() {} + + template<typename VectorType> + int CGSolver<VectorType>::solveSystem(MatVecMultiplier<VectorType> *matVec, + VectorType *x, VectorType *b) + { + FUNCNAME("CGSolver::solve()"); + + const double TOL = 1.e-30; + +// ::std::cout << "b: " << ::std::endl; +// print(b); + + // If norm of b is smaller than the tolarance, we can assume b to be zero. + // Hence, x = 0 is the solution of the linear system. + if (norm(b) < TOL) { + INFO(this->info,2)("b == 0, x = 0 is the solution of the linear system\n"); + setValue(*x, 0.0); + this->residual = 0.0; + + return(0); + } + +// ::std::cout << "x: " << ::std::endl; +// print(x); + + // p is temporaly used to calculate -x. + *p = *x; + *p *= -1.0; + + // r = b - Ax + matVec->matVec(NoTranspose, *p, *r); +// ::std::cout << "-Ax: " << ::std::endl; +// print(r); + *r += *b; + +// ::std::cout << "r: " << ::std::endl; +// print(r); + + *p = *r; + if (this->leftPrecon) { + this->leftPrecon->precon(p); + } + + // \alpha = (r,p)_2 + // without precondition, \alpha = (r,p)_2 = (r,r)_2 = \|r\|_2^2 +// ::std::cout << "Berechne Alpha: " << ::std::endl; +// ::std::cout << "r: " << ::std::endl; +// print(r); +// ::std::cout << "p: " << ::std::endl; +// print(p); + double alpha = *r * *p; +// ::std::cout << "alpha=" << alpha << ::std::endl; + + double alpha1, lambda, old_res = -1.0; + + START_INFO(); + // Test if x is already a solution of the lineas system. + if (SOLVE_INFO(0, sqrt(alpha), &old_res)) { + return(0); + } + + for (int iter = 1; iter <= this->max_iter; iter++) { + // ::std::cout << "---------------------------Ein Schritt---------------------------" << ::std::endl; + // v = Ap + matVec->matVec(NoTranspose, *p, *v); +// ::std::cout << "p: " << ::std::endl; +// print(p); +// ::std::cout << "Ap: " << ::std::endl; +// print(v); + + // \lambda = alpha / (v,p)_2 + lambda = *v * *p; + if (abs(lambda) < TOL) { + BREAK_INFO("(v,p)_2 = 0", iter, sqrt(alpha), &old_res); + return(iter); + } + lambda = alpha / lambda; + + // x = x + \lambda * p + axpy(lambda, *p, *x); + + // r = r - \lambda * v + axpy(-lambda, *v, *r); + + *z = *r; + if (this->leftPrecon) { + this->leftPrecon->precon(z); + } + + // \alpha_{m + 1} = (r,z)_2 + // without precondition, \alpha_{m + 1} = (r,z)_2 = (r,r)_2 = \|r\|_2^2 + alpha1 = *r * *z; + + // Check if x is a solution of the linear system. + if (SOLVE_INFO(iter, sqrt(alpha1), &old_res)) { + *p = *x; + *p *= -1.0; + + // r = b - Ax + matVec->matVec(NoTranspose, *p, *r); + *r += *b; + + ::std::cout << "Final res: " << norm(r) << ::std::endl; + + return(iter); + } + + // p = z + (alpha_{m + 1} / alpha_{m}) * p + xpay(alpha1 / alpha, *z, *p); + + // Put the value of the alpha_{m + 1} variable to alpha_{m} variable + // for the next iteration. + alpha = alpha1; + } + + ERROR_EXIT("Should not be reached\n"); + return(0); + } +} diff --git a/AMDiS/src/ChangeLog b/AMDiS/src/ChangeLog new file mode 100644 index 0000000000000000000000000000000000000000..e69de29bb2d1d6434b8b29ae775ad8c2e48c5391 diff --git a/AMDiS/src/Cholesky.cc b/AMDiS/src/Cholesky.cc new file mode 100644 index 0000000000000000000000000000000000000000..16078c9bb0546b671e600655066ae5ad68b56cea --- /dev/null +++ b/AMDiS/src/Cholesky.cc @@ -0,0 +1,165 @@ +#include "Cholesky.h" + +bool Cholesky::factorization(Matrix<double> *A, Vector<double> *p) +{ + FUNCNAME("Cholesky::factorization"); + + int n = A->getNumRows(); + TEST_EXIT(n == A->getNumCols())("Matrix is not quadratic!\n"); + + // Checking memory for vector P of diagonal elements of factorization. + static Vector<double> *pT = NULL; + + if (p) + { + if (p->getSize() != n) + p->resize(n); + } + else + { + if (pT) + { + if (pT->getSize() != n) + pT->resize(n); + } + else + pT = NEW Vector<double>(n); + + p = pT; + } + + // Constructs the Cholesky factorization A = L*L, with L lower triangular. + // Only the upper triangle need be given; it is not modified. + // The Cholesky factor L is stored in the lower triangle of A, except for + // its diagonal which is stored in P. + + int i, j, k; + double sum; + + for (i=0; i<n; i++) + { + for (j=i; j<n; j++) + { + for (sum=(*A)[i][j], k=i-1; k>=0; k--) + sum -= (*A)[i][k] * (*A)[j][k]; + + if (i==j) + { + if (sum<=0) + { + MSG("Matrix is (numerically) not positive definite!\n"); + MSG("Cholesky decomposition does not work; choose another method for solving the system.\n"); + return false; + } + (*p)[i] = sqrt(sum); + } + else + (*A)[j][i] = sum / (*p)[i]; + } + } + + return true; +} + +bool Cholesky::solve(Matrix<double> *A, Vector<double> *b, Vector<double> *x, + Vector<double> *p) +{ + FUNCNAME("Cholesky::solve"); + + bool success = true; + int n = b->getSize(); + TEST_EXIT(n == A->getNumRows()) + ("Dimensions of matrix and vector do not match!\n"); + + // Checking memory for solution vector X. + if (x && (x->getSize() != n)) + x->resize(n); + + if (!x) + x = NEW Vector<double>(n); + + // Checking vector P. + static Vector<double> *pT = NULL; + + if (!p || (p->getSize() != n)) + { + if (pT && pT->getSize() != n) + DELETE pT; + + if (!pT) + pT = NEW Vector<double>(n); + + p = pT; + + success = factorization(A, p); + } + + // Now solve the system by backsubstitution. + int i, k; + double sum; + + for (i=0; i<n; i++) // Solve L*Y = B, storing Y in X. + { + for (sum=(*b)[i], k=i-1; k>=0; k--) + sum -= (*A)[i][k] * (*x)[k]; + (*x)[i] = sum / (*p)[i]; + } + + for (i=n-1; i>=0; i--) // Solve L^T*X = Y. + { + for (sum=(*x)[i], k=i+1; k<n; k++) + sum -= (*A)[k][i] * (*x)[k]; + (*x)[i] = sum / (*p)[i]; + } + + return success; +} + +bool Cholesky::solve(Matrix<double> *A, Vector<WorldVector<double> > *b, + Vector<WorldVector<double> > *x, Vector<double> *p) +{ + FUNCNAME("Cholesky::solve"); + + bool success = true; + int n = b->getSize(); + TEST_EXIT(n == A->getNumRows()) + ("Dimensions of matrix and vector do not match!\n"); + + // Checking memory for solution vector X. + if (x && (x->getSize() != n)) + x->resize(n); + + if (!x) + x = NEW Vector<WorldVector<double> >(n); + + // Checking vector P. + static Vector<double> *pT = NULL; + + if (!p || (p->getSize() != n)) + { + pT = NEW Vector<double>(n); + p = pT; + + success = factorization(A, p); + } + + // Now solve the system by backsubstitution. + int i, k; + WorldVector<double> vec_sum; + + for (i=0; i<n; i++) // Solve L*Y = B, storing L in X. + { + for (vec_sum=(*b)[i], k=i-1; k>=0; k--) + vec_sum -= (*x)[k] * (*A)[i][k] ; + (*x)[i] = vec_sum * (1.0/(*p)[i]); + } + + for (i=n-1; i>=0; i--) // Solve L^T*X = Y. + { + for (vec_sum=(*x)[i], k=i+1; k<n; k++) + vec_sum -= (*x)[k] * (*A)[k][i] ; + (*x)[i] = vec_sum * (1.0/(*p)[i]); + } + + return success; +} diff --git a/AMDiS/src/Cholesky.h b/AMDiS/src/Cholesky.h new file mode 100644 index 0000000000000000000000000000000000000000..a2d5eae7f70d146a0d702af221509627c6555296 --- /dev/null +++ b/AMDiS/src/Cholesky.h @@ -0,0 +1,69 @@ +// ============================================================================ +// == == +// == AMDiS - Adaptive multidimensional simulations == +// == == +// ============================================================================ +// == == +// == crystal growth group == +// == == +// == Stiftung caesar == +// == Ludwig-Erhard-Allee 2 == +// == 53175 Bonn == +// == germany == +// == == +// ============================================================================ +// == == +// == http://www.caesar.de/cg/AMDiS == +// == == +// ============================================================================ + +/** \file Cholesky.h */ + +#ifndef CHOLESKY_H +#define CHOLESKY_H + +#include "FixVec.h" + +using namespace std; +using namespace AMDiS; + +// ============================================================================ +// ===== class Cholesky ======================================================= +// ============================================================================ + +/** + * \ingroup Solvers + * + * \brief + * Solves a symmetric positive definite system using Cholesky decomposition. + * Returns true if the matrix in (numerically) positive definite. + */ + +class Cholesky +{ + public: + MEMORY_MANAGED(Cholesky); + + /** \brief + * Computes the Cholesky factor of a positive definite matrix A. + * On input, only the upper triangle of A need be given; it is not modified. + * The Cholesky factor is returned in the lower triangle of A, except for its + * diagonal elements which are returned in P. + */ + static bool factorization(Matrix<double> *A, Vector<double> *p); + + /** \brief + * Solves system A*X=B, where A is a positive definite matrix. + * If P=NULL; A is assumed to be positive definite, and a Cholesky + * decomposition is computed using the previous routine. + * If P is given, A and P are assumed to be already given as the output of + * the previous routine. + */ + static bool solve(Matrix<double> *A, Vector<double> *b, Vector<double> *x, + Vector<double> *p = NULL); + static bool solve(Matrix<double> *A, Vector<WorldVector<double> > *b, + Vector<WorldVector<double> > *x, + Vector<double> *p = NULL); +}; + +#endif diff --git a/AMDiS/src/CoarseningManager.cc b/AMDiS/src/CoarseningManager.cc new file mode 100644 index 0000000000000000000000000000000000000000..f43833c4d92190b49b6ddaed47c1bd2709802d61 --- /dev/null +++ b/AMDiS/src/CoarseningManager.cc @@ -0,0 +1,137 @@ +#include "CoarseningManager.h" +#include "Mesh.h" +#include "AdaptStationary.h" +#include "AdaptInstationary.h" +#include "Traverse.h" +#include "MacroElement.h" +#include "RCNeighbourList.h" +#include "FixVec.h" +//#include "PeriodicBC.h" + +namespace AMDiS { + + CoarseningManager* CoarseningManager::traversePtr = NULL; + + /****************************************************************************/ + /* sets the mark on all elements that have to be coarsend */ + /****************************************************************************/ + + int CoarseningManager::coarsenMarkFunction(ElInfo *el_info) + { + el_info->getElement()->setMark(traversePtr->globalMark); + return 0; + } + + /****************************************************************************/ + /* tries to coarsen every element of mesh at least mark times */ + /****************************************************************************/ + + Flag CoarseningManager::globalCoarsen(Mesh *aMesh, int mark) + { + if (mark >= 0) return(0); + globalMark = mark; + traversePtr = this; + aMesh->traverse(-1, Mesh::CALL_LEAF_EL, coarsenMarkFunction); + return(coarsenMesh(aMesh)); + } + + int CoarseningManager::spreadCoarsenMarkFunction(ElInfo* el_info) + { + Element *el = el_info->getElement(); + signed char mark; + + if (el->getChild(0)) + { + /****************************************************************************/ + /* interior node of the tree */ + /****************************************************************************/ + mark = max(el->getChild(0)->getMark(), el->getChild(1)->getMark()); + el->setMark(::std::min(mark + 1, 0)); + } + else + { + /****************************************************************************/ + /* leaf node of the tree */ + /****************************************************************************/ + if (el->getMark() < 0) el->setMark(el->getMark() - 1); + } + return 0; + } + + void CoarseningManager::spreadCoarsenMark() + { + traversePtr = this; + mesh->traverse(-1, + Mesh::CALL_EVERY_EL_POSTORDER, + spreadCoarsenMarkFunction); + } + + + /****************************************************************************/ + /* cleanup_after_coarsen: */ + /* resets the element marks */ + /****************************************************************************/ + + int CoarseningManager::cleanUpAfterCoarsenFunction(ElInfo *el_info) + { + Element *el = el_info->getElement(); + el->setMark(max(el->getMark(), 0)); + return 0; + } + + void CoarseningManager::cleanUpAfterCoarsen() + { + traversePtr = this; + mesh->traverse(-1, Mesh::CALL_LEAF_EL, cleanUpAfterCoarsenFunction); + } + + /****************************************************************************/ + /* coarsenMesh: */ + /* traversal routine for recursiv coarsening of a triangulation */ + /****************************************************************************/ + + Flag CoarseningManager::coarsenMesh(Mesh *aMesh) + { + int n_elements; + Flag flag = Mesh::CALL_EVERY_EL_POSTORDER | Mesh::FILL_NEIGH; + ElInfo *el_info; + + mesh = aMesh; + + // if(mesh->getDim() == 3) { + // ::std::map<BoundaryType, PeriodicBC*> &periodicBCs = + // mesh->getPeriodicBCMap(); + + // ::std::map<BoundaryType, PeriodicBC*>::iterator it; + // ::std::map<BoundaryType, PeriodicBC*>::iterator end = periodicBCs.end(); + // for(it = periodicBCs.begin(); it != end; ++it) { + // it->second->updateAssociatedDOFs(); + // } + // } + + n_elements = mesh->getNumberOfLeaves(); + + spreadCoarsenMark(); + + stack = NEW TraverseStack; + + do { + doMore = false; + el_info = stack->traverseFirst(mesh, -1, flag); + while (el_info) + { + coarsenFunction(el_info); + el_info = stack->traverseNext(el_info); + } + } while (doMore); + + DELETE stack; + + cleanUpAfterCoarsen(); + + n_elements -= mesh->getNumberOfLeaves(); + + return(n_elements ? MESH_COARSENED : Flag(0)); + } + +} diff --git a/AMDiS/src/CoarseningManager.h b/AMDiS/src/CoarseningManager.h new file mode 100644 index 0000000000000000000000000000000000000000..6c91164e6ce3e107585449d775d5d2f52b0927bd --- /dev/null +++ b/AMDiS/src/CoarseningManager.h @@ -0,0 +1,182 @@ +// ============================================================================ +// == == +// == AMDiS - Adaptive multidimensional simulations == +// == == +// ============================================================================ +// == == +// == crystal growth group == +// == == +// == Stiftung caesar == +// == Ludwig-Erhard-Allee 2 == +// == 53175 Bonn == +// == germany == +// == == +// ============================================================================ +// == == +// == http://www.caesar.de/cg/AMDiS == +// == == +// ============================================================================ + +/** \file CoarseningManager.h */ + +#ifndef AMDIS_COARSENINGMANAGER_H +#define AMDIS_COARSENINGMANAGER_H + +// ============================================================================ +// ===== includes ============================================================= +// ============================================================================ + +#include "Global.h" +#include "Mesh.h" +#include "ProblemStatBase.h" + +namespace AMDiS { + + // ============================================================================ + // ===== forward declarations ================================================= + // ============================================================================ + + class Element; + class Line; + class Triangle; + class Tetrahedron; + class RCNeighbourList; + class ElInfo; + class TraverseStack; + + // ============================================================================ + // ===== class CoarseningManager ============================================== + // ============================================================================ + + /** \ingroup Adaption + * \brief + * Base class of CoarseningManager1d, CoarseningManager2d, CoarseningManager3d. + * A CoarseningManager contains all functionality to perform coarsening + * operations on the mesh. + */ + class CoarseningManager + { + public: + /** \brief + * constructs a CoarseningManager which belongs to aMesh + */ + CoarseningManager() + : mesh(NULL), stack(NULL), globalMark(0), doMore(0) + {}; + + /** \brief + * destructor + */ + virtual ~CoarseningManager() {}; + + /** \brief + * Returns the Mesh the CoarseningManager belongs to. + */ + inline Mesh* getMesh() { return mesh; }; + + // /** \brief + // * Coarsens a single Element by decrement its mark and then coarsen + // * the mesh. + // */ + // void coarsenElement(Element *element) { + // FUNCNAME("CoarseninManager::coarseElement"); + // element->decrementMark(); + // coarsenMesh(); + // }; + + /** \brief + * Tries to coarsen every element of mesh at least mark times. First + * all elements are marked for coarsening and then coarsenMesh will + * be called. + */ + Flag globalCoarsen(Mesh *aMesh, int mark); + + /** \brief + * Traversal routine for recursiv coarsening of a triangulation. It has + * a default definition in CoarseningManager but it can be overriden + * by sub classes (like in CoarseningManager1d), if another implementation + * is needed. + */ + virtual Flag coarsenMesh(Mesh *aMesh); + + + protected: + /** \brief + * If the mesh is coarsened by non recurisive traversal, this method + * spezifies + * how one element of the mesh is coarsened. The method can be overriden + * by sub classes, if used. + */ + virtual int coarsenFunction(ElInfo *) { return 0; }; + + /** \brief + * Propagate coarsening information over the whole hierarchy + * by POSTORDER traversal of the hierarchy tree. + * leaves: 'increment' coarsening mark, + * inner nodes: set coarsening mark to + * min(0,child[0].mark+1,child[1].mark+1) + */ + void spreadCoarsenMark(); + + /** \brief + * Used while traversal in spreadCoarsenMark + */ + static int spreadCoarsenMarkFunction(ElInfo* el_info); + + /** \brief + *Used while traversal in cleanUpAfterCoarsen + */ + static int cleanUpAfterCoarsenFunction(ElInfo* el_info); + + /** \brief + * Sets the mark on all elements that have to be coarsend + */ + static int coarsenMarkFunction(ElInfo *el_info); + + /** \brief + * Resets the element marks + */ + void cleanUpAfterCoarsen(); + + protected: + /** \brief + * the Mesh this CoarseningManager belongs to + */ + Mesh *mesh; + + /** \brief + * Used for non recursive mesh traversal. + */ + TraverseStack *stack; + + /** \brief + * Used by globalCoarsen to remember the given mark value + */ + int globalMark; + + /** \brief + * Spezifies whether the coarsening operation is still in progress + */ + bool doMore; + + /** \brief + * Used while mesh traversal to have a pointer to this CoarseningManager + * from a static method + */ + static CoarseningManager* traversePtr; + + /** \brief + * Spezifies how many DOFVectors should restricted while coarsening + */ + int callCoarseRestrict; + + friend class RCNeighbourList; + }; + +} + +#include "CoarseningManager1d.h" +#include "CoarseningManager2d.h" +#include "CoarseningManager3d.h" + +#endif // AMDIS_COARSENINGMANAGER_H diff --git a/AMDiS/src/CoarseningManager1d.cc b/AMDiS/src/CoarseningManager1d.cc new file mode 100644 index 0000000000000000000000000000000000000000..6d9de4994673d76790fa15d41e9e002da7d3ee34 --- /dev/null +++ b/AMDiS/src/CoarseningManager1d.cc @@ -0,0 +1,135 @@ +#include "CoarseningManager1d.h" +#include "Mesh.h" +#include "AdaptStationary.h" +#include "AdaptInstationary.h" +#include "Traverse.h" +#include "MacroElement.h" +#include "RCNeighbourList.h" +#include "FixVec.h" +#include "DOFIndexed.h" + +namespace AMDiS { + + Flag CoarseningManager1d::coarsenMesh(Mesh *aMesh) + { + mesh = aMesh; + + ::std::deque<MacroElement*>::const_iterator mel; + int n_elements = mesh->getNumberOfLeaves(); + + for (mel = mesh->firstMacroElement(); + mel != mesh->endOfMacroElements(); + mel++) + { + coarsenRecursive(dynamic_cast<Line*>(const_cast<Element*>((*mel)->getElement()))); + } + + return(mesh->getNumberOfLeaves() < n_elements ? MESH_COARSENED : Flag(0)); + } + + int CoarseningManager1d::coarsenRecursive(Line *parent) + { + FUNCNAME("CoarseningManager1d::coarsenRecursive"); + int mark; + + INFO(0,2)("\n"); + if (parent->isLeaf()) // leaf element, clean element marker + { + mark = parent->getMark(); + parent->setMark(0); + return(mark); + } + else { // no leaf element, first coarse children + Line *child[2]; + + int mark0 = coarsenRecursive(dynamic_cast<Line*>(const_cast<Element*>(parent->getChild(0)))); + int mark1 = coarsenRecursive(dynamic_cast<Line*>(const_cast<Element*>( parent->getChild(1)))); + + mark = max(mark0, mark1); + + child[0] = dynamic_cast<Line*>(const_cast<Element*>( parent->getChild(0))); + child[1] = dynamic_cast<Line*>(const_cast<Element*>( parent->getChild(1))); + + if (mark >= 0) { // element must not be coarsend + parent->setMark(0); + if (child[0]) { + child[0]->setMark(0); + child[1]->setMark(0); + } + + return(0); + } + + /*--------------------------------------------------------------------------*/ + /*--- and now coarsen child[0] and child[1] into parent ---*/ + /*--------------------------------------------------------------------------*/ + + /*--------------------------------------------------------------------------*/ + /*--- hand DOFs from children to parent, and add DOF at center ---*/ + /*--------------------------------------------------------------------------*/ + + if (mesh->getNumberOfDOFs(VERTEX) && !mesh->queryCoarseDOFs()) { + int node = mesh->getNode(VERTEX); + parent->setDOF(node+0, const_cast<int*>( child[0]->getDOF(node+0))); + parent->setDOF(node+1, const_cast<int*>( child[1]->getDOF(node+1))); + } + + if (mesh->getNumberOfDOFs(CENTER) && !mesh->queryCoarseDOFs()) { + parent->setDOF(mesh->getNode(CENTER), mesh->getDOF(CENTER)); + } + + /*--------------------------------------------------------------------------*/ + /* restrict dof vectors to the parents on the patch */ + /*--------------------------------------------------------------------------*/ + + + RCNeighbourList coarsenList(1); // = {{nil, 0, 0}}; + coarsenList.setElement(0, parent); + int iadmin; + int nrAdmin = mesh->getNumberOfDOFAdmin(); + for(iadmin = 0; iadmin < nrAdmin; iadmin++) { + ::std::list<DOFIndexedBase*>::iterator it; + DOFAdmin* admin = const_cast<DOFAdmin*>(&(mesh->getDOFAdmin(iadmin))); + ::std::list<DOFIndexedBase*>::iterator end = admin->endDOFIndexed(); + for(it = admin->beginDOFIndexed(); it != end; ++it) + (*it)->coarseRestrict(coarsenList, 1); + } + + + /*--------------------------------------------------------------------------*/ + /*--- remove all DOFs of children that are not used anymore ---*/ + /*--------------------------------------------------------------------------*/ + + if (mesh->getNumberOfDOFs(VERTEX)) /*--- midpoint of parent ---*/ + { + mesh->freeDOF(const_cast<int*>( child[1]->getDOF(mesh->getNode(VERTEX))), VERTEX); + } + + if (mesh->getNumberOfDOFs(CENTER)) /*--- center of the children ---*/ + { + mesh->freeDOF(const_cast<int*>( child[0]->getDOF(mesh->getNode(CENTER))), CENTER); + mesh->freeDOF(const_cast<int*>( child[1]->getDOF(mesh->getNode(CENTER))), CENTER); + } + + parent->coarsenElementData(child[0], child[1]); + + parent->setFirstChild(NULL); + parent->setSecondChild(NULL); + + mesh->freeElement(child[0]); + mesh->freeElement(child[1]); + + mesh->incrementNumberOfLeaves(-1); + mesh->incrementNumberOfElements(-2); + mesh->incrementNumberOfVertices(-1); + + mark++; + parent->setMark(::std::min(mark,0)); + + return(parent->getMark()); + } + + return(0); /*--- statement never reached ---*/ + } + +} diff --git a/AMDiS/src/CoarseningManager1d.h b/AMDiS/src/CoarseningManager1d.h new file mode 100644 index 0000000000000000000000000000000000000000..605f0bc24145d96f224fad22c3915974f15c039c --- /dev/null +++ b/AMDiS/src/CoarseningManager1d.h @@ -0,0 +1,81 @@ +// ============================================================================ +// == == +// == AMDiS - Adaptive multidimensional simulations == +// == == +// ============================================================================ +// == == +// == crystal growth group == +// == == +// == Stiftung caesar == +// == Ludwig-Erhard-Allee 2 == +// == 53175 Bonn == +// == germany == +// == == +// ============================================================================ +// == == +// == http://www.caesar.de/cg/AMDiS == +// == == +// ============================================================================ + +/** \file CoarseningManager1d.h */ + +#ifndef AMDIS_COARSENINGMANAGER_1D_H +#define AMDIS_COARSENINGMANAGER_1D_H + +#include "CoarseningManager.h" +#include "MemoryManager.h" + +namespace AMDiS { + + // ============================================================================ + // ===== class CoarseningManager1d ============================================ + // ============================================================================ + + /** \ingroup Adaption + * \brief + * Implements a CoarseningManager for 1-dimensional meshes. + */ + class CoarseningManager1d : public CoarseningManager + { + public: + MEMORY_MANAGED(CoarseningManager1d); + + /** \brief + * Calls base class constructor and checks dimension of mesh. + */ + CoarseningManager1d() : CoarseningManager() { + // FUNCNAME("CoarseningManager1d::CoarseningManager1d"); + // TEST_EXIT(mesh->getDim()==1)("mesh->dim != 1\n"); + }; + + /** \brief + * destructor + */ + virtual ~CoarseningManager1d() {}; + + /** \brief + * Overloads CoarseningManager::coarsenMesh. In 1d a simple recursive + * coarsening algorithm is implemented which doesn't need coarsenFunction. + */ + Flag coarsenMesh(Mesh *aMesh); + + protected: + /** \brief + * Not needed in this sub class + */ + int coarsenFunction(ElInfo *) { + FUNCNAME("CoarseningManager1d::coarsenFunction"); + ERROR_EXIT("not used for dim = 1"); + return 0; + }; + + /** \brief + * Needed instead of coarsenFunction in 1d. + */ + int coarsenRecursive(Line *parent); + + }; + +} + +#endif // AMDIS_COARSENINGMANAGER_1D_H diff --git a/AMDiS/src/CoarseningManager2d.cc b/AMDiS/src/CoarseningManager2d.cc new file mode 100644 index 0000000000000000000000000000000000000000..8893093990b5250df071e620299fa514ae7a41c9 --- /dev/null +++ b/AMDiS/src/CoarseningManager2d.cc @@ -0,0 +1,290 @@ +#include "CoarseningManager2d.h" +#include "Mesh.h" +#include "AdaptStationary.h" +#include "AdaptInstationary.h" +#include "Traverse.h" +#include "MacroElement.h" +#include "RCNeighbourList.h" +#include "FixVec.h" +#include "DOFIndexed.h" + +namespace AMDiS { + + /****************************************************************************/ + /* coarseTriangle: coarses a single element of the coarsening patch; dofs */ + /* in the interior of the element are removed; dofs for higher order */ + /* at the boundary or the coarsening patch still belong to */ + /* the parent. Do not remove them form the mesh!!! */ + /****************************************************************************/ + + void CoarseningManager2d::coarsenTriangle(Triangle *el) + { + FUNCNAME("CoarseningManager2d::coarseTriangle"); + Triangle *child[2]; + + child[0] = dynamic_cast<Triangle*>(const_cast<Element*>( el->getChild(0))); + child[1] = dynamic_cast<Triangle*>(const_cast<Element*>( el->getChild(1))); + + TEST_EXIT(child[0]->getMark() < 0 && child[1]->getMark() < 0) + ("element %d with children[%d,%d] must not be coarsend!\n", + el->getIndex(), child[0]->getIndex(), child[1]->getIndex()); + + if (mesh->getNumberOfDOFs(EDGE)) + { + /****************************************************************************/ + /* remove dof from common edge of child[0] and child[1] */ + /****************************************************************************/ + mesh->freeDOF(const_cast<int*>( child[0]->getDOF(4)), EDGE); + } + + if (mesh->getNumberOfDOFs(CENTER)) + { + /****************************************************************************/ + /* remove dof from the barycenters of child[0] and child[1] */ + /****************************************************************************/ + int node = mesh->getNode(CENTER); + + mesh->freeDOF(const_cast<int*>( child[0]->getDOF(node)), CENTER); + mesh->freeDOF(const_cast<int*>( child[1]->getDOF(node)), CENTER); + } + + el->coarsenElementData(child[0], child[1]); + + el->setFirstChild(NULL); + el->setSecondChild(NULL); + + + mesh->freeElement(child[0]); + mesh->freeElement(child[1]); + + el->incrementMark(); + + mesh->incrementNumberOfLeaves(-1); + mesh->incrementNumberOfElements(-2); + mesh->incrementNumberOfEdges(-1); + + return; + } + + /****************************************************************************/ + /* coarsenPatch: first rebuild the dofs on the parents then do restriction */ + /* of data (if possible) and finally coarsen the patch elements */ + /****************************************************************************/ + + void CoarseningManager2d::coarsenPatch(RCNeighbourList *coarsenList, + int n_neigh, + int bound) + { + Triangle *el = dynamic_cast<Triangle*>(const_cast<Element*>( coarsenList->getElement(0))); + Triangle *neigh = dynamic_cast<Triangle*>(const_cast<Element*>( coarsenList->getElement(1))); + DegreeOfFreedom *dof[3]; + + dof[0] = const_cast<int*>( el->getChild(0)->getDOF(2)); + if (mesh->getNumberOfDOFs(EDGE)) + { + dof[1] = const_cast<int*>( el->getChild(0)->getDOF(3)); + dof[2] = const_cast<int*>( el->getChild(1)->getDOF(4)); + } + + int node = mesh->getNode(EDGE); + if (mesh->getNumberOfDOFs(EDGE)) + { + /****************************************************************************/ + /* get new dof on el at the midpoint of the coarsening edge */ + /****************************************************************************/ + if (!el->getDOF(node+2)) + { + el->setDOF(node+2, mesh->getDOF(EDGE)); + if (neigh) { + // // periodic boundary ? + // if(el->getDOF(0) != neigh->getDOF(0) && + // el->getDOF(1) != neigh->getDOF(0)) + // { + // neigh->setDOF(node+2, mesh->getDOF(EDGE)); + // } else { + neigh->setDOF(node+2, const_cast<int*>( el->getDOF(node+2))); + // } + } + } + } + + // // periodic boundary? + // DegreeOfFreedom *neighDOF[3] = {NULL, NULL, NULL}; + // RCNeighbourList *periodicCoarsenList = NULL; + // int n_neigh_periodic; + // if(neigh && + // (neigh->getDOF(0) != el->getDOF(1)) && + // (neigh->getDOF(0) != el->getDOF(0))) + // { + // neighDOF[0] = const_cast<int*>(neigh->getChild(0)->getDOF(2)); + // if (mesh->getNumberOfDOFs(EDGE)) { + // neighDOF[1] = const_cast<int*>(neigh->getChild(0)->getDOF(3)); + // neighDOF[2] = const_cast<int*>(neigh->getChild(1)->getDOF(4)); + // if (!neigh->getDOF(node+2)) { + // neigh->setDOF(node+2, mesh->getDOF(EDGE)); + // } + // } + + // DegreeOfFreedom *edge[2] = { + // const_cast<DegreeOfFreedom*>(el->getDOF(0)), + // const_cast<DegreeOfFreedom*>(el->getDOF(1)) + // }; + // DegreeOfFreedom *periodicEdge[2] = { + // const_cast<DegreeOfFreedom*>(neigh->getDOF(0)), + // const_cast<DegreeOfFreedom*>(neigh->getDOF(1)) + // }; + + // periodicCoarsenList = coarsenList->periodicSplit(edge, + // &n_neigh, + // periodicEdge, + // &n_neigh_periodic); + // } + + if (mesh->getNumberOfDOFs(EDGE) || mesh->getNumberOfDOFs(CENTER)) { + coarsenList->addDOFParents(n_neigh); + // if(periodicCoarsenList) { + // periodicCoarsenList->addDOFParents(n_neigh_periodic); + // } + } + + /****************************************************************************/ + /* restrict dof vectors to the parents on the patch */ + /****************************************************************************/ + int iadmin; + int nrAdmin = mesh->getNumberOfDOFAdmin(); + for(iadmin = 0; iadmin < nrAdmin; iadmin++) { + ::std::list<DOFIndexedBase*>::iterator it; + DOFAdmin* admin = const_cast<DOFAdmin*>(&mesh->getDOFAdmin(iadmin)); + ::std::list<DOFIndexedBase*>::iterator end = admin->endDOFIndexed(); + for(it = admin->beginDOFIndexed(); it != end; ++it) { + (*it)->coarseRestrict(*coarsenList, n_neigh); + // if(periodicCoarsenList) { + // (*it)->coarseRestrict(*periodicCoarsenList, n_neigh_periodic); + // } + } + } + + // if(periodicCoarsenList) DELETE periodicCoarsenList; + + coarsenTriangle(el); + + if (neigh) coarsenTriangle(neigh); + + /****************************************************************************/ + /* now, remove those dofs in the coarcening edge */ + /****************************************************************************/ + mesh->freeDOF(dof[0], VERTEX); + if (mesh->getNumberOfDOFs(EDGE)) + { + mesh->freeDOF(dof[1], EDGE); + mesh->freeDOF(dof[2], EDGE); + } + + mesh->incrementNumberOfVertices(-1); + mesh->incrementNumberOfEdges(-1); + + // // periodic boundary? + // if(neigh && + // (neigh->getDOF(0) != el->getDOF(1)) && + // (neigh->getDOF(0) != el->getDOF(0))) + // { + // mesh->freeDOF(neighDOF[0], VERTEX); + // if (mesh->getNumberOfDOFs(EDGE)) { + // mesh->freeDOF(neighDOF[1], EDGE); + // mesh->freeDOF(neighDOF[2], EDGE); + // } + // mesh->incrementNumberOfVertices(-1); + // mesh->incrementNumberOfEdges(-1); + // } + + return; + } + + int CoarseningManager2d::coarsenFunction(ElInfo *el_info) + { + Triangle *el = dynamic_cast<Triangle*>(const_cast<Element*>( el_info->getElement())); + DegreeOfFreedom *edge[2]; + int n_neigh, bound = 0; + RCNeighbourList coarse_list(2); + + coarse_list.setCoarseningManager(this); + + if (el->getMark() >= 0) return 0; // el must not be coarsend, return + if (!(el->getChild(0))) return 0; // single leaves don't get coarsened + + if (el->getChild(0)->getMark() >= 0 || el->getChild(1)->getMark() >= 0) + { + /****************************************************************************/ + /* one of the children must not be coarsend; return :-( */ + /****************************************************************************/ + el->setMark(0); + return 0; + } + + if (!el->getChild(0)->isLeaf() || !el->getChild(1)->isLeaf()) + { + /****************************************************************************/ + /* one of the children is not a leaf element; try again later on */ + /****************************************************************************/ + doMore = true; + return 0; + } + + /****************************************************************************/ + /* give the refinement edge the right orientation */ + /****************************************************************************/ + + if (el->getDOF(0,0) < el->getDOF(1,0)) + { + edge[0] = const_cast<int*>( el->getDOF(0)); + edge[1] = const_cast<int*>( el->getDOF(1)); + } + else + { + edge[1] = const_cast<int*>( el->getDOF(0)); + edge[0] = const_cast<int*>( el->getDOF(1)); + } + + coarse_list.setElement(0, el, true); + + n_neigh = 1; + if (coarse_list.setElement(1, el_info->getNeighbour(2))) + { + n_neigh = 2; + coarse_list.setCoarsePatch(1, el_info->getOppVertex(2) == 2); + } + + /****************************************************************************/ + /* check wether we can coarsen the patch or not */ + /****************************************************************************/ + + // ========================================================================== + // === check for periodic boundary ========================================== + // ========================================================================== + + if(coarse_list.doCoarsePatch(n_neigh)) { + int n_neigh_periodic; + + DegreeOfFreedom *next_edge[2]; + + RCNeighbourList *periodicList; + + while(edge[0] != NULL) { + periodicList = coarse_list.periodicSplit(edge, + next_edge, + &n_neigh, + &n_neigh_periodic); + + TEST_EXIT(periodicList)("periodicList = NULL\n"); + + coarsenPatch(periodicList, n_neigh_periodic, bound); + + edge[0] = next_edge[0]; + edge[1] = next_edge[1]; + } + } + + return 0; + } + +} diff --git a/AMDiS/src/CoarseningManager2d.h b/AMDiS/src/CoarseningManager2d.h new file mode 100644 index 0000000000000000000000000000000000000000..8e2f81c1119dd950531519b5b918c3eb2258cce4 --- /dev/null +++ b/AMDiS/src/CoarseningManager2d.h @@ -0,0 +1,80 @@ +// ============================================================================ +// == == +// == AMDiS - Adaptive multidimensional simulations == +// == == +// ============================================================================ +// == == +// == crystal growth group == +// == == +// == Stiftung caesar == +// == Ludwig-Erhard-Allee 2 == +// == 53175 Bonn == +// == germany == +// == == +// ============================================================================ +// == == +// == http://www.caesar.de/cg/AMDiS == +// == == +// ============================================================================ + +/** \file CoarseningManager2d.h */ + +#ifndef AMDIS_COARSENINGMANAGER_2D_H +#define AMDIS_COARSENINGMANAGER_2D_H + +#include "CoarseningManager.h" +#include "MemoryManager.h" + +namespace AMDiS { + + // ============================================================================ + // ===== class CoarseningManager2d ============================================ + // ============================================================================ + + /** \ingroup Adaption + * \brief + * Implements a CoarseningManager for 2-dimensional meshes. + */ + class CoarseningManager2d : public CoarseningManager + { + public: + MEMORY_MANAGED(CoarseningManager2d); + + /** \brief + * Calls base class constructor and checks dimension of mesh. + */ + CoarseningManager2d() : CoarseningManager() { + // FUNCNAME("CoarseningManager2d::CoarseningManager2d"); + // TEST_EXIT(mesh->getDim()==2)("mesh->dim != 2\n"); + }; + + /** \brief + * destructor + */ + virtual ~CoarseningManager2d() {}; + + protected: + /** \brief + * Implements CoarseningManager::coarsenFunction + */ + virtual int coarsenFunction(ElInfo *el_info); + + /** \brief + * Coarsens a single Triangle of the coarsening patch. DOFs + * in the interior of the element are removed; DOFs for higher order + * at the boundary or the coarsening patch still belong to + * the parent. Do not remove them form the mesh!!! + */ + void coarsenTriangle(Triangle *el); + + /** \brief + * First rebuild the DOFs on the parents then do restriction + * of data (if possible) and finally coarsen the patch elements + */ + void coarsenPatch(RCNeighbourList *coarsenList, int n_neigh, int bound); + }; + + +} + +#endif // AMDIS_COARSENINGMANAGER_2D_H diff --git a/AMDiS/src/CoarseningManager3d.cc b/AMDiS/src/CoarseningManager3d.cc new file mode 100644 index 0000000000000000000000000000000000000000..d85bd42f3d17c6ac3dd888b121a45ec6b5083d7d --- /dev/null +++ b/AMDiS/src/CoarseningManager3d.cc @@ -0,0 +1,426 @@ +#include "CoarseningManager3d.h" +#include "Mesh.h" +#include "AdaptStationary.h" +#include "AdaptInstationary.h" +#include "Traverse.h" +#include "MacroElement.h" +#include "RCNeighbourList.h" +#include "FixVec.h" +#include "DOFIndexed.h" + +namespace AMDiS { + + int CoarseningManager3d::coarsenFunction(ElInfo *el_info) + { + Tetrahedron *el = dynamic_cast<Tetrahedron*>(const_cast<Element*>( el_info->getElement())); + DegreeOfFreedom *edge[2]; + int n_neigh, bound = 0; + + ElInfo *elinfo = el_info; + RCNeighbourList *coarsenList; + + + if (el->getMark() >= 0) return 0; // el must not be coarsend, return :-( + if (el->isLeaf()) return 0; // single leaves don't get coarsened + + if (el->getChild(0)->getMark() >= 0 || el->getChild(1)->getMark() >= 0) { + /****************************************************************************/ + /* one of the children must not be coarsend; return :-( */ + /****************************************************************************/ + el->setMark(0); + return 0; + } + + if (!(el->getChild(0)->isLeaf()) || !(el->getChild(1)->isLeaf())) { + /****************************************************************************/ + /* one of the children is not a leaf element; try again later on */ + /****************************************************************************/ + doMore = true; + return 0; + } + /****************************************************************************/ + /* get a list for storing all elements at the coarsening edge and fill it */ + /****************************************************************************/ + coarsenList = NEW RCNeighbourList(mesh->getMaxEdgeNeigh()); + coarsenList->setCoarseningManager(this); + + /****************************************************************************/ + /* give the refinement edge the right orientation */ + /****************************************************************************/ + + if (el->getDOF(0,0) < el->getDOF(1,0)) { + edge[0] = const_cast<int*>( el->getDOF(0)); + edge[1] = const_cast<int*>( el->getDOF(1)); + } else { + edge[1] = const_cast<int*>( el->getDOF(0)); + edge[0] = const_cast<int*>( el->getDOF(1)); + } + + coarsenList->setElement(0, el, true); + n_neigh = 1; + + coarsenList->setOppVertex(0,0,0); + coarsenList->setElType(0, (dynamic_cast<ElInfo3d*>( el_info)->getType())); + bound = false; + if (getCoarsenPatch(elinfo, edge, 0, coarsenList, &n_neigh)) { + getCoarsenPatch(elinfo, edge, 1, coarsenList, &n_neigh); + bound = true; + } + coarsenList->getNeighOnPatch(n_neigh, bound); + + /****************************************************************************/ + /* check wether we can coarsen the patch or not */ + /****************************************************************************/ + + // // ========================================================================== + // // === check for periodic boundary ========================================== + // // ========================================================================== + + // DegreeOfFreedom *periodic_edge[2]; + // int n_neigh_periodic; + + // RCNeighbourList *periodicList = coarsenList->periodicSplit(edge, + // &n_neigh, + // periodic_edge, + // &n_neigh_periodic); + + // bool doCoarsening = coarsenList->doCoarsePatch(n_neigh); + + // if(periodicList && doCoarsening) { + // if (periodicList->doCoarsePatch(n_neigh_periodic)) { + // coarsenPatch(periodicList, n_neigh_periodic, bound); + // } else { + // doCoarsening = false; + // } + // DELETE periodicList; + // } + + // if (coarsenList->doCoarsePatch(n_neigh)/*doCoarsening*/) { + // coarsenPatch(coarsenList, n_neigh, bound); + // } + + // ========================================================================== + // === check for periodic boundary ========================================== + // ========================================================================== + + if(coarsenList->doCoarsePatch(n_neigh)) { + int n_neigh_periodic; + + DegreeOfFreedom *next_edge[2]; + + RCNeighbourList *periodicList; + + while(edge[0] != NULL) { + periodicList = coarsenList->periodicSplit(edge, + next_edge, + &n_neigh, + &n_neigh_periodic); + + TEST_EXIT(periodicList)("periodicList = NULL\n"); + + coarsenPatch(periodicList, n_neigh_periodic, bound); + + edge[0] = next_edge[0]; + edge[1] = next_edge[1]; + } + } + + DELETE coarsenList; + + return 0; + } + + /*****************************************************************************/ + /* coarsenTetrahedron: coarses a single element of the coarsening patch; */ + /* dofs in the interior of the element are removed and dofs in the faces of */ + /* the element are removed if neighbour has been coarsend or if the face */ + /* is part of the domains boundary */ + /*****************************************************************************/ + + void CoarseningManager3d::coarsenTetrahedron(RCNeighbourList *coarsenList, + int index) + { + Tetrahedron *el = dynamic_cast<Tetrahedron*>(const_cast<Element*>( coarsenList->getElement(index))), *child[2]; + Tetrahedron *neigh; + int dir, el_type, i, node, opp_v; + + child[0] = dynamic_cast<Tetrahedron*>(const_cast<Element*>( el->getChild(0))); + child[1] = dynamic_cast<Tetrahedron*>(const_cast<Element*>( el->getChild(1))); + el_type = coarsenList->getType(index); + + /****************************************************************************/ + /* Information about patch neighbours is still valid! But edge and face */ + /* dof's in a common face of patch neighbours have to be removed */ + /****************************************************************************/ + + for (dir = 0; dir < 2; dir++) { + neigh = dynamic_cast<Tetrahedron*>(const_cast<Element*>( coarsenList->getNeighbourElement(index, dir))); + opp_v = coarsenList->getOppVertex(index, dir); + + if (!neigh || neigh->isLeaf()) { + /****************************************************************************/ + /* boundary face or neigh has been coarsend: free the dof's in the face */ + /****************************************************************************/ + + if (mesh->getNumberOfDOFs(EDGE)) { + node = mesh->getNode(EDGE) + Tetrahedron::nChildEdge[el_type][0][dir]; + mesh->freeDOF(const_cast<int*>( child[0]->getDOF(node)), EDGE); + } + if (mesh->getNumberOfDOFs(FACE)) + { + node = mesh->getNode(FACE) + Tetrahedron::nChildFace[el_type][0][dir]; + mesh->freeDOF(const_cast<int*>( child[0]->getDOF(node)), FACE); + node = mesh->getNode(FACE) + Tetrahedron::nChildFace[el_type][1][dir]; + mesh->freeDOF(const_cast<int*>( child[1]->getDOF(node)), FACE); + } + } + } + + /****************************************************************************/ + /* finally remove the interior dof's: in the common face of child[0] and */ + /* child[1] and at the two barycenter */ + /****************************************************************************/ + + if (mesh->getNumberOfDOFs(FACE)) { + node = mesh->getNode(FACE); + mesh->freeDOF(const_cast<int*>( child[0]->getDOF(node)), FACE); + } + + + if (mesh->getNumberOfDOFs(CENTER)) { + node = mesh->getNode(CENTER); + for (i = 0; i < 2; i++) + mesh->freeDOF(const_cast<int*>( child[i]->getDOF(node)), CENTER); + } + + /****************************************************************************/ + /* get new data on parent and transfer data from children to parent */ + /****************************************************************************/ + + el->coarsenElementData(child[0], child[1], el_type); + + el->setFirstChild(NULL); + el->setSecondChild(NULL); + + mesh->freeElement(child[0]); + mesh->freeElement(child[1]); + + el->incrementMark(); + + mesh->incrementNumberOfLeaves(-1); + mesh->incrementNumberOfElements(-2); + + return; + } + + /****************************************************************************/ + /* get_coarse_patch: gets the patch for coarsening starting on element */ + /* el_info->el in direction of neighbour [3-dir]; returns 1 if a boundary */ + /* reached and 0 if we come back to the starting element. */ + /* */ + /* if NEIGH_IN_EL we only can find the complete coarsening patch if the */ + /* can be coarsend; otherwise neighbour information is not valid for */ + /* parents; in such situation we stop looping around the edge and return 0 */ + /* */ + /* if !NEIGH_IN_EL we complete the loop also in the case of a incompatible */ + /* coarsening patch since then all marks of patch elements are reset by */ + /* do_coarse_patch() and this minimizes calls of traverse_neighbour(); */ + /* if we reach a boundary while looping around the edge we loop back to */ + /* the starting element before we return */ + /****************************************************************************/ + + bool CoarseningManager3d::getCoarsenPatch(ElInfo *el_info, + DegreeOfFreedom *edge[2], + int dir, + RCNeighbourList *coarsenList, + int *n_neigh) + { + FUNCNAME("CoarseningManager3d::getCoarsenPatch"); + ElInfo *neigh_info; + Tetrahedron *el, *neigh; + int i, j, k, opp_v, edge_no; + + static unsigned char next_el[6][2] = {{3,2}, + {1,3}, + {1,2}, + {0,3}, + {0,2}, + {0,1}}; + + el = dynamic_cast<Tetrahedron*>(const_cast<Element*>( el_info->getElement())); + + if ((neigh = dynamic_cast<Tetrahedron*>(const_cast<Element*>( el_info->getNeighbour(3-dir)))) == NULL) + return true; + + opp_v = el_info->getOppVertex(3-dir); + + neigh_info = stack->traverseNeighbour3d(el_info, 3-dir); + TEST_EXIT(neigh == neigh_info->getElement()) + ("neigh %d and neigh_info->el %d are not identical\n", + neigh->getIndex(), neigh_info->getElement()->getIndex()); + /****************************************************************************/ + /* we have to go back to the starting element via opp_v values */ + /* correct information is produce by get_neigh_on_patch() */ + /****************************************************************************/ + coarsenList->setOppVertex(*n_neigh, 0, opp_v); + coarsenList->setElement(*n_neigh, neigh); + coarsenList->setElType(*n_neigh, (dynamic_cast<ElInfo3d*>( neigh_info))->getType()); + + int n_vertices = mesh->getGeo(VERTEX); + + while (neigh != el) { + for (j = 0; j < n_vertices; j++) + if (neigh->getDOF(j) == edge[0]) break; + for (k = 0; k < n_vertices; k++) + if (neigh->getDOF(k) == edge[1]) break; + + if(j > 3 || k > 3) { + for (j = 0; j < n_vertices; j++) + if (mesh->associated(neigh->getDOF(j, 0), edge[0][0])) break; + for (k = 0; k < n_vertices; k++) + if (mesh->associated(neigh->getDOF(k, 0), edge[1][0])) break; + + TEST_EXIT(j < n_vertices && k < n_vertices) + ("dof %d or dof %d not found on element %d with nodes (%d %d %d %d)\n", + edge[0][0], edge[1][0], neigh->getIndex(), neigh->getDOF(0,0), + neigh->getDOF(1,0), neigh->getDOF(2,0), neigh->getDOF(3,0)); + } + edge_no = Tetrahedron::edgeOfDOFs[j][k]; + coarsenList->setCoarsePatch(*n_neigh, edge_no == 0); + + /****************************************************************************/ + /* get the direction of the next neighbour */ + /****************************************************************************/ + + if (next_el[edge_no][0] != opp_v) + i = next_el[edge_no][0]; + else + i = next_el[edge_no][1]; + + ++*n_neigh; + + opp_v = neigh_info->getOppVertex(i); + if ((neigh = dynamic_cast<Tetrahedron*>(const_cast<Element*>( neigh_info->getNeighbour(i))))) { + neigh_info = stack->traverseNeighbour3d(neigh_info, i); + TEST_EXIT(neigh == neigh_info->getElement()) + ("neigh %d and neigh_info->el %d are not identical\n", + neigh->getIndex(), neigh_info->getElement()->getIndex()); + /****************************************************************************/ + /* we have to go back to the starting element via opp_v values */ + /* correct information is produce by get_neigh_on_patch() */ + /****************************************************************************/ + coarsenList->setOppVertex(*n_neigh, 0, opp_v); + coarsenList->setElement(*n_neigh, neigh); + coarsenList->setElType(*n_neigh, (dynamic_cast<ElInfo3d*>( neigh_info))->getType()); + } else + break; + } + + if (neigh == el) + return false; + + /****************************************************************************/ + /* the domain's boundary is reached; loop back to the starting el */ + /****************************************************************************/ + + i = *n_neigh-1; + opp_v = coarsenList->getOppVertex(i, 0); + do { + TEST_EXIT(neigh_info->getNeighbour(opp_v) && i > 0) + ("while looping back domains boundary was reached or i == 0\n"); + opp_v = coarsenList->getOppVertex(i--, 0); + neigh_info = stack->traverseNeighbour3d(neigh_info, opp_v); + } while(neigh_info->getElement() != el); + + return true; + } + + /****************************************************************************/ + /* coarse_patch: first rebuild the dofs on the parents then do restriction */ + /* of data (if possible) and finally coarsen the patch elements */ + /****************************************************************************/ + + void CoarseningManager3d::coarsenPatch(RCNeighbourList *coarsenList, + int n_neigh, + int bound) + { + Tetrahedron *el = dynamic_cast<Tetrahedron*>(const_cast<Element*>( coarsenList->getElement(0))); + int i, node; + DegreeOfFreedom *dof; + + if (mesh->getNumberOfDOFs(EDGE)) { + /****************************************************************************/ + /* get dof for coarsening edge */ + /****************************************************************************/ + node = mesh->getNode(EDGE); + if (!(dof = const_cast<int*>( el->getDOF(node)))) + dof = mesh->getDOF(EDGE); + } else + dof = NULL; + + if (mesh->getNumberOfDOFs(EDGE) || + mesh->getNumberOfDOFs(FACE) || + mesh->getNumberOfDOFs(CENTER)) + { + for (i = 0; i < n_neigh; i++) + coarsenList->addDOFParent(i, dof); + } + + /****************************************************************************/ + /* restrict dof vectors to the parents on the patch */ + /****************************************************************************/ + + int iadmin; + int nrAdmin = mesh->getNumberOfDOFAdmin(); + for(iadmin = 0; iadmin < nrAdmin; iadmin++) { + ::std::list<DOFIndexedBase*>::iterator it; + DOFAdmin* admin = const_cast<DOFAdmin*>(&mesh->getDOFAdmin(iadmin)); + ::std::list<DOFIndexedBase*>::iterator end = admin->endDOFIndexed(); + for(it = admin->beginDOFIndexed(); it != end; ++it) + (*it)->coarseRestrict(*coarsenList, n_neigh); + } + + /****************************************************************************/ + /* and now start to coarsen the patch: */ + /****************************************************************************/ + /* remove dof's of the coarsening edge */ + /****************************************************************************/ + + mesh->freeDOF(const_cast<int*>( el->getChild(0)->getDOF(3)), VERTEX); + mesh->incrementNumberOfVertices(-1); + + if (mesh->getNumberOfDOFs(EDGE)) + { + node = mesh->getNode(EDGE)+2; + mesh->freeDOF(const_cast<int*>( el->getChild(0)->getDOF(node)), EDGE); + mesh->freeDOF(const_cast<int*>( el->getChild(1)->getDOF(node)), EDGE); + } + + if (coarsenList->getElement(0)->isNewCoordSet()) { + coarsenList->getElement(0)->eraseNewCoord(); + } + + for (i = 0; i < n_neigh; i++) + { + coarsenList->getElement(i)->setNewCoord(NULL); + coarsenTetrahedron(coarsenList, i); + } + + /****************************************************************************/ + /* if the coarsening edge is an interior edge there are n_neigh + 1 edges */ + /* and 2*n_neigh + 1 faces removed; if it is a boundary edge it is one */ + /* more edge and one more face */ + /****************************************************************************/ + + if (bound) { + mesh->incrementNumberOfEdges(-(n_neigh + 2)); + mesh->incrementNumberOfFaces(-(2*n_neigh + 1)); + } else { + mesh->incrementNumberOfEdges(-(n_neigh + 1)); + mesh->incrementNumberOfFaces(-(2*n_neigh)); + } + + return; + } + +} diff --git a/AMDiS/src/CoarseningManager3d.h b/AMDiS/src/CoarseningManager3d.h new file mode 100644 index 0000000000000000000000000000000000000000..cb009cd66dbc6eb587becfa7e5e875d2d168ee73 --- /dev/null +++ b/AMDiS/src/CoarseningManager3d.h @@ -0,0 +1,93 @@ +// ============================================================================ +// == == +// == AMDiS - Adaptive multidimensional simulations == +// == == +// ============================================================================ +// == == +// == crystal growth group == +// == == +// == Stiftung caesar == +// == Ludwig-Erhard-Allee 2 == +// == 53175 Bonn == +// == germany == +// == == +// ============================================================================ +// == == +// == http://www.caesar.de/cg/AMDiS == +// == == +// ============================================================================ + +/** \file CoarseningManager3d.h */ + +#ifndef AMDIS_COARSENINGMANAGER_3D_H +#define AMDIS_COARSENINGMANAGER_3D_H + +#include "CoarseningManager.h" +#include "MemoryManager.h" + +namespace AMDiS { + + // ============================================================================ + // ===== class CoarseningManager3d ============================================ + // ============================================================================ + + /** \ingroup Adaption + * \brief + * Implements a CoarseningManager for 3-dimensional meshes. + */ + class CoarseningManager3d : public CoarseningManager + { + public: + MEMORY_MANAGED(CoarseningManager3d); + + /** \brief + * Calls base class constructor and checks dimension of mesh. + */ + CoarseningManager3d() : CoarseningManager() { + // FUNCNAME("CoarseningManager3d::CoarseningManager3d"); + // TEST_EXIT(mesh->getDim()==3)("mesh->dim != 3\n"); + }; + + /** \brief + * destructor + */ + virtual ~CoarseningManager3d() {}; + + protected: + /** \brief + * Implements CoarseningManager::coarsenFunction + */ + int coarsenFunction(ElInfo *el_info); + + /** \brief + * Coarsens a single Tetrahedron of the coarsening patch. DOFs + * in the interior of the element are removed; DOFs for higher order + * at the boundary or the coarsening patch still belong to + * the parent. Do not remove them form the mesh!!! + */ + void coarsenTetrahedron(RCNeighbourList *coarsenList, int index); + + /** \brief + * Gets the patch for coarsening starting on element + * el_info->el in direction of neighbour [3-dir]; returns 1 if a boundary + * reached and 0 if we come back to the starting element. + * We complete the loop also in the case of a incompatible + * coarsening patch since then all marks of patch elements are reset by + * coarsenPatch() and this minimizes calls of traverseNeighbour(); + * if we reach a boundary while looping around the edge we loop back to + * the starting element before we return + */ + bool getCoarsenPatch(ElInfo* el_info, DegreeOfFreedom *edge[2], + int dir, RCNeighbourList* coarsenList, int *n_neigh); + + /** \brief + * First rebuild the DOFs on the parents then do restriction + * of data (if possible) and finally coarsen the patch elements + */ + void coarsenPatch(RCNeighbourList *coarsenList, int n_neigh, int bound); + + }; + +} + +#endif // AMDIS_COARSENINGMANAGER_3D_H diff --git a/AMDiS/src/ConditionalEstimator.cc b/AMDiS/src/ConditionalEstimator.cc new file mode 100644 index 0000000000000000000000000000000000000000..82e8c081bea41662ffa654bb9260b65d27b33af4 --- /dev/null +++ b/AMDiS/src/ConditionalEstimator.cc @@ -0,0 +1,101 @@ +#include "ConditionalEstimator.h" +#include "ElInfo.h" +#include "PartitionElementData.h" +#include "Element.h" +#include "Traverse.h" +#include "mpi.h" + +namespace AMDiS { + + double ConditionalEstimator::estimate(double ts) + { + if(decoratedEstimator_) { + + double partition_sum = 0.0; + + elementCount_ = 0; + + decoratedEstimator_->init(ts); + + mesh = decoratedEstimator_->getMesh(); + traverseFlag = decoratedEstimator_->getTraverseFlag(); + + TraverseStack stack; + ElInfo *elInfo = stack.traverseFirst(mesh, -1, traverseFlag); + while(elInfo) { + PartitionElementData *elData = dynamic_cast<PartitionElementData*> + (elInfo->getElement()->getElementData(PARTITION_ED)); + + TEST_EXIT(elInfo->getElement()->isLeaf())("element not leaf\n"); + TEST_EXIT(elData)("no partitoin data on leaf element %d (rank %d)\n", + elInfo->getElement()->getIndex(), + MPI::COMM_WORLD.Get_rank()); + + PartitionStatus status = elData->getPartitionStatus(); + + if(status == IN || status == OVERLAP) { + decoratedEstimator_->estimateElement(elInfo); + } else { + elInfo->getElement()->setMark(0); + } + elInfo = stack.traverseNext(elInfo); + } + + elInfo = stack.traverseFirst(mesh, -1, traverseFlag); + while(elInfo) { + PartitionElementData *elData = dynamic_cast<PartitionElementData*> + (elInfo->getElement()->getElementData(PARTITION_ED)); + PartitionStatus status = elData->getPartitionStatus(); + if(status == IN) { + elementCount_++; + partition_sum += elInfo->getElement()->getEstimation(row_); + } + elInfo = stack.traverseNext(elInfo); + } + + // !!! test !!! + double total_sum = 0.0; + MPI::COMM_WORLD.Allreduce(&partition_sum, + &total_sum, + 1, + MPI_DOUBLE, + MPI_SUM); + + decoratedEstimator_->setErrorSum(total_sum); + + double total_max = 0.0; + est_max = decoratedEstimator_->getErrorMax(); + MPI::COMM_WORLD.Allreduce(&est_max, + &total_max, + 1, + MPI_DOUBLE, + MPI_MAX); + + decoratedEstimator_->setErrorMax(total_max); + + decoratedEstimator_->exit(); + + est_sum = decoratedEstimator_->getErrorSum(); + est_max = decoratedEstimator_->getErrorMax(); + + // !!! test !!! +#if 0 + decoratedEstimator_->exit(); + + est_sum = sqrt(partition_sum); //decoratedEstimator_->getErrorSum(); + est_t_sum = decoratedEstimator_->getTimeEst(); + est_max = decoratedEstimator_->getErrorMax(); +#endif + + // MSG("rank %d , estimate %e (total %e) elements %d (total %d)\n", + // MPI::COMM_WORLD.Get_rank(), est_sum, total_sum, + // elementCount_, + // mesh->getNumberOfLeaves()); + + return est_sum; + } else { + return 0.0; + } + } + +} diff --git a/AMDiS/src/ConditionalEstimator.h b/AMDiS/src/ConditionalEstimator.h new file mode 100644 index 0000000000000000000000000000000000000000..cbca46de2868ba452b24c5b3061a3bd6be89f51f --- /dev/null +++ b/AMDiS/src/ConditionalEstimator.h @@ -0,0 +1,96 @@ +// ============================================================================ +// == == +// == AMDiS - Adaptive multidimensional simulations == +// == == +// ============================================================================ +// == == +// == crystal growth group == +// == == +// == Stiftung caesar == +// == Ludwig-Erhard-Allee 2 == +// == 53175 Bonn == +// == germany == +// == == +// ============================================================================ +// == == +// == http://www.caesar.de/cg/AMDiS == +// == == +// ============================================================================ + +/** \file ConditionalEstimator.h */ + +/** \defgroup Estimator Estimator module + * @{ <img src="estimator.png"> @} + */ + +#ifndef AMDIS_CONDITIONALESTIMATOR_H +#define AMDIS_CONDITIONALESTIMATOR_H + +#include "Estimator.h" + +namespace AMDiS { + + // ============================================================================ + // ===== class ConditionalEstimator ============================================== + // ============================================================================ + + /** + * \ingroup Estimator + * + * \brief + * Estimator for scalar problems. + */ + class ConditionalEstimator : public Estimator + { + public: + MEMORY_MANAGED(ConditionalEstimator); + + ConditionalEstimator(Estimator *decorated) + : decoratedEstimator_(decorated), + elementCount_(0), + row_(decorated ? decorated->getRow() : 0) + {}; + + double estimate(double timestep); + + inline int getElementCount() { + return elementCount_; + }; + + // inline double getErrorSum() const { + // return decoratedEstimator_->getErrorSum(); + // }; + + // inline void setErrorSum(double sum) { + // decoratedEstimator_->setErrorSum(sum); + // }; + + // inline double getErrorMax() const { + // return decoratedEstimator_->getErrorMax(); + // }; + + // inline double getTimeEst() const { + // return decoratedEstimator_->getTimeEst(); + // }; + + // inline void setErrorMax(double m) { + // decoratedEstimator_->setErrorMax(m); + // }; + + // inline Norm getErrorNorm() { + // return decoratedEstimator_->getErrorNorm(); + // }; + + inline Estimator *getDecoratedEstimator() { return decoratedEstimator_; }; + + protected: + Estimator *decoratedEstimator_; + + int elementCount_; + + int row_; + }; + +} + +#endif // AMDIS_ESTIMATOR_H diff --git a/AMDiS/src/ConditionalMarker.h b/AMDiS/src/ConditionalMarker.h new file mode 100644 index 0000000000000000000000000000000000000000..64f174a07535cb6a31b4f95879ddebe6e50e2cda --- /dev/null +++ b/AMDiS/src/ConditionalMarker.h @@ -0,0 +1,135 @@ +// ============================================================================ +// == == +// == AMDiS - Adaptive multidimensional simulations == +// == == +// ============================================================================ +// == == +// == crystal growth group == +// == == +// == Stiftung caesar == +// == Ludwig-Erhard-Allee 2 == +// == 53175 Bonn == +// == germany == +// == == +// ============================================================================ +// == == +// == http://www.caesar.de/cg/AMDiS == +// == == +// ============================================================================ + +/** \file ConditionalMarker.h */ + +#ifndef AMDIS_CONDITIONALMARKER_H +#define AMDIS_CONDITIONALMARKER_H + +#include "mpi.h" +#include "Marker.h" +#include "Marker.h" +#include "MemoryManager.h" +#include "PartitionElementData.h" +#include "Traverse.h" +#include "ElInfo.h" + +namespace AMDiS { + + // =========================================================================== + // ===== class ESMarker ====================================================== + // =========================================================================== + + /** + * \ingroup Adaption + * + * \brief + * + */ + class ConditionalMarker : public Marker + { + public: + MEMORY_MANAGED(ConditionalMarker); + + /** \brief + * Constructor. + */ + ConditionalMarker(const std::string name, + int row, + Marker *decoratedMarker, + int globalCoarseGridLevel, + int localCoarseGridLevel) + : Marker(name, row), + decoratedMarker_(decoratedMarker), + globalCoarseGridLevel_(globalCoarseGridLevel), + localCoarseGridLevel_(localCoarseGridLevel) + {}; + + /** \brief + * Implementation of MarkScal::initMarking(). + */ + virtual void initMarking(AdaptInfo *adaptInfo, Mesh *mesh) { + if(decoratedMarker_) + decoratedMarker_->initMarking(adaptInfo, mesh); + }; + + virtual void finishMarking(AdaptInfo *adaptInfo) { + if(decoratedMarker_) { + int tmp = decoratedMarker_->getElMarkRefine(); + MPI::COMM_WORLD.Allreduce(&tmp, + &elMarkRefine, + 1, + MPI_INT, + MPI_SUM); + tmp = decoratedMarker_->getElMarkCoarsen(); + MPI::COMM_WORLD.Allreduce(&tmp, + &elMarkCoarsen, + 1, + MPI_INT, + MPI_SUM); + decoratedMarker_->finishMarking(adaptInfo); + } + }; + + void markElement(AdaptInfo *adaptInfo, ElInfo *elInfo) { + FUNCNAME("ConditionalMarker::markElement()"); + if(decoratedMarker_) { + PartitionElementData *elData = + dynamic_cast<PartitionElementData*>(elInfo->getElement()-> + getElementData(PARTITION_ED)); + + TEST_EXIT(elData)("no partition data\n"); + + decoratedMarker_->markElement(adaptInfo, elInfo); + + if(elData->getPartitionStatus() == OUT) { + //if(elData->getPartitionStatus() != IN) { + // allow coarsening, forbid refinement + Element *element = elInfo->getElement(); + if(element->getMark() > 0) { + element->setMark(0); + } + } + + // if(elInfo->getElement()->getMark() != 0) { + // MSG("rank %d , index %d, mark %d\n", + // MPI::COMM_WORLD.Get_rank(), elInfo->getElement()->getIndex(), + // elInfo->getElement()->getMark()); + // } + + int minLevel = + elData->getPartitionStatus() != OUT ? + localCoarseGridLevel_ : + globalCoarseGridLevel_; + + if(elData->getLevel() + elInfo->getElement()->getMark() < minLevel) { + elInfo->getElement()->setMark(-(elData->getLevel() - minLevel)); + } + } + }; + + protected: + Marker *decoratedMarker_; + int globalCoarseGridLevel_; + int localCoarseGridLevel_; + }; + +} + +#endif diff --git a/AMDiS/src/CouplingTimeInterface.h b/AMDiS/src/CouplingTimeInterface.h new file mode 100644 index 0000000000000000000000000000000000000000..c20779dc8239846305c1cf68dd9bc1891a05491c --- /dev/null +++ b/AMDiS/src/CouplingTimeInterface.h @@ -0,0 +1,106 @@ +// ============================================================================ +// == == +// == AMDiS - Adaptive multidimensional simulations == +// == == +// ============================================================================ +// == == +// == crystal growth group == +// == == +// == Stiftung caesar == +// == Ludwig-Erhard-Allee 2 == +// == 53175 Bonn == +// == germany == +// == == +// ============================================================================ +// == == +// == http://www.caesar.de/cg/AMDiS == +// == == +// ============================================================================ + +/** \file CouplingTimeInterface.h */ + +#ifndef AMDIS_COUPLINGTIMEINTERFACE_H +#define AMDIS_COUPLINGTIMEINTERFACE_H + +#include "Flag.h" +#include "ProblemTimeInterface.h" +#include <vector> + +namespace AMDiS { + + // ============================================================================ + // ===== class CouplingTimeInterface ========================================== + // ============================================================================ + + /** + * \ingroup Problem + * + * \brief + */ + class CouplingTimeInterface : public ProblemTimeInterface + { + public: + void addTimeInterface(ProblemTimeInterface *interface) { + interfaces_.push_back(interface); + }; + + /** \brief + * Executes all needed operations when the simulation time changes. + */ + virtual void setTime(AdaptInfo *adaptInfo) { + int i, size = static_cast<int>(interfaces_.size()); + for(i = 0; i < size; i++) { + interfaces_[i]->setTime(adaptInfo); + } + }; + + /** \brief + * Called at the beginning of each timestep + */ + virtual void initTimestep(AdaptInfo *adaptInfo) { + int i, size = static_cast<int>(interfaces_.size()); + for(i = 0; i < size; i++) { + interfaces_[i]->initTimestep(adaptInfo); + } + }; + + /** \brief + * Called at the end of each timestep. + */ + virtual void closeTimestep(AdaptInfo *adaptInfo) { + int i, size = static_cast<int>(interfaces_.size()); + for(i = 0; i < size; i++) { + interfaces_[i]->closeTimestep(adaptInfo); + } + }; + + /** \brief + * Solves the initial problem. + */ + virtual void solveInitialProblem(AdaptInfo *adaptInfo) { + int i, size = static_cast<int>(interfaces_.size()); + for(i = 0; i < size; i++) { + interfaces_[i]->solveInitialProblem(adaptInfo); + } + }; + + /** \brief + * Solves the initial problem. + */ + virtual void transferInitialSolution(AdaptInfo *adaptInfo) { + int i, size = static_cast<int>(interfaces_.size()); + for(i = 0; i < size; i++) { + interfaces_[i]->transferInitialSolution(adaptInfo); + } + }; + + protected: + /** \brief + * vector of coupled time interfaces + */ + ::std::vector<ProblemTimeInterface*> interfaces_; + }; + +} + +#endif diff --git a/AMDiS/src/CreatorInterface.h b/AMDiS/src/CreatorInterface.h new file mode 100644 index 0000000000000000000000000000000000000000..687827e8046cbf1a6b0c4a1145eefdcc4c429fe0 --- /dev/null +++ b/AMDiS/src/CreatorInterface.h @@ -0,0 +1,88 @@ +// ============================================================================ +// == == +// == AMDiS - Adaptive multidimensional simulations == +// == == +// ============================================================================ +// == == +// == crystal growth group == +// == == +// == Stiftung caesar == +// == Ludwig-Erhard-Allee 2 == +// == 53175 Bonn == +// == germany == +// == == +// ============================================================================ +// == == +// == http://www.caesar.de/cg/AMDiS == +// == == +// ============================================================================ + +/** \file CreatorInterface.h */ + +#ifndef AMDIS_CREATORINTERFACE_H +#define AMDIS_CREATORINTERFACE_H + +namespace AMDiS { + + /** \ingroup Common + * \brief + * Interface for the implementation of the factory method pattern. + * The creation of an object of a sub class of BaseClass is deligated + * to a corresponding sub class of Creator<BaseClass>. So it is possible to + * manage a CreatorMap, which can be extended at run-time. An example is + * the OEMSolverMap: If you write your own OEMSolver sub class and a + * corresponding Creator<OEMSolver<T> >, you can add the creator together + * with a key string to the OEMSolverMap. Then you can create an OEMSolver + * depending of a key string read from the init file, which can also be + * your own new solver. + */ + template<typename BaseClass> + class CreatorInterface + { + public: + virtual ~CreatorInterface() {}; + + /** \brief + * Must be implemented by sub classes of CreatorInterface. + * Creates a new instance of the sub class of BaseClass. + */ + virtual BaseClass* create() = 0; + + /** \brief + * Can be implemented by sub classes. + */ + virtual void free(BaseClass *) {}; + + /** \brief + * + */ + virtual bool isNullCreator() { + return false; + }; + }; + + /** \brief + * A Creator which creates no object abd returns NULL instead. + * Used together with the key word 'no' in CreatorMap. + */ + template<typename BaseClass> + class NullCreator : public CreatorInterface<BaseClass> + { + /** \brief + * Creates no object. + */ + BaseClass* create() { + return NULL; + }; + + /** \brief + * + */ + virtual bool isNullCreator() { + return true; + }; + }; + +} + +#endif diff --git a/AMDiS/src/CreatorMap.cc b/AMDiS/src/CreatorMap.cc new file mode 100644 index 0000000000000000000000000000000000000000..c2548b115626ac611824565a1d9c8580946265c3 --- /dev/null +++ b/AMDiS/src/CreatorMap.cc @@ -0,0 +1,275 @@ +#include "CreatorMap.h" +#include "OEMSolver.h" +#include "Preconditioner.h" +#include "DiagonalPreconditioner.h" +#include "ILUPreconditioner.h" +#include "ILUTPreconditioner.h" +#include "NonLinSolver.h" +#include "MatrixVector.h" +#include "SystemVector.h" +#include "Estimator.h" +#include "RecoveryEstimator.h" +#include "LeafData.h" +#include "SurfaceRegion_ED.h" +#include "MultiGridWrapper.h" +#include "DOFMatrix.h" +#include "SparseVector.h" +#include "GSSmoother.h" +#include "JacobiSmoother.h" +#include "ElementRegion_ED.h" +#include "BiCGStab.h" +#include "BiCGStab2.h" +#include "BoxSmoother.h" +#include "MultiGridPreconWrapper.h" +#include "GMResSolver2.h" +#include "TFQMR.h" +#include "VecSymSolver.h" +#include "UmfPackSolver.h" + +namespace AMDiS { + + template<> + void CreatorMap<OEMSolver<DOFVector<double> > >::addDefaultCreators() + { + OEMSolverCreator<DOFVector<double> > *creator; + + creator = NEW BiCGSolver<DOFVector<double> >::Creator; + addCreator("bicgstab_albert", creator); + addCreator("1", creator); + + creator = NEW CGSolver<DOFVector<double> >::Creator; + addCreator("cg", creator); + addCreator("2", creator); + + creator = NEW GMResSolver<DOFVector<double> >::Creator; + addCreator("gmres", creator); + addCreator("3", creator); + + creator = NEW ODirSolver<DOFVector<double> >::Creator; + addCreator("odir", creator); + addCreator("4", creator); + + creator = NEW OResSolver<DOFVector<double> >::Creator; + addCreator("ores", creator); + addCreator("5", creator); + + // creator = NEW BiCGStab_M<DOFVector<double> >::Creator; + // addCreator("bicgstab", creator); + // addCreator("6", creator); + + creator = NEW BiCGStab<DOFVector<double> >::Creator; + addCreator("bicgstab", creator); + addCreator("6", creator); + + creator = NEW MultiGridWrapperScal::Creator; + addCreator("mg", creator); + addCreator("7", creator); + + creator = NEW BiCGStab2<DOFVector<double> >::Creator; + addCreator("bicgstab2", creator); + addCreator("8", creator); + + // creator = NEW GMResSolver2<DOFVector<double> >::Creator; + // addCreator("gmres2", creator); + // addCreator("9", creator); + + creator = NEW TFQMR<DOFVector<double> >::Creator; + addCreator("tfqmr", creator); + addCreator("10", creator); + } + + template<> + void CreatorMap<SmootherBase<DOFMatrix, + SparseVector<double>, + ::std::set<DegreeOfFreedom> > >::addDefaultCreators() + { + SmootherCreator<DOFMatrix, SparseVector<double>, ::std::set<DegreeOfFreedom> > *creator; + + creator = NEW GSSmoother<DOFMatrix, SparseVector<double>, ::std::set<DegreeOfFreedom> >::Creator; + addCreator("gs", creator); + addCreator("1", creator); + + creator = NEW JacobiSmoother<DOFMatrix, SparseVector<double>, ::std::set<DegreeOfFreedom> >::Creator; + addCreator("j", creator); + addCreator("2", creator); + } + + template<> + void CreatorMap<PreconditionerScal>::addDefaultCreators() + { + CreatorInterface<PreconditionerScal> *creator; + + creator = NEW DiagonalPreconditioner::Creator; + addCreator("diag", creator); + addCreator("1", creator); + + creator = NEW ILUPreconditioner::Creator; + addCreator("ilu", creator); + addCreator("2", creator); + + creator = NEW ILUTPreconditioner::Creator; + addCreator("ilut", creator); + addCreator("3", creator); + + creator = NEW MGPreconWrapperScal::Creator; + addCreator("mg", creator); + addCreator("4", creator); + } + + template<> + void CreatorMap<NonLinSolver<DOFVector<double> > >::addDefaultCreators() + { + NonLinSolverCreator<DOFVector<double> > *creator; + + creator = NEW Newton<DOFVector<double> >::Creator; + addCreator("newton", creator); + addCreator("1", creator); + + creator = NEW NewtonS<DOFVector<double> >::Creator; + addCreator("newton_fs", creator); + addCreator("2", creator); + } + + template<> + void CreatorMap<OEMSolver<SystemVector> >::addDefaultCreators() + { + OEMSolverCreator<SystemVector> *creator; + + creator = NEW BiCGSolver<SystemVector>::Creator; + addCreator("bicgstab_albert", creator); + addCreator("1", creator); + + creator = NEW CGSolver<SystemVector>::Creator; + addCreator("cg", creator); + addCreator("2", creator); + + creator = NEW GMResSolver<SystemVector>::Creator; + addCreator("gmres", creator); + addCreator("3", creator); + + creator = NEW ODirSolver<SystemVector>::Creator; + addCreator("odir", creator); + addCreator("4", creator); + + creator = NEW OResSolver<SystemVector>::Creator; + addCreator("ores", creator); + addCreator("5", creator); + + // creator = NEW BiCGStab_M<SystemVector>::Creator; + // addCreator("bicgstab", creator); + // addCreator("6", creator); + + creator = NEW BiCGStab<SystemVector>::Creator; + addCreator("bicgstab", creator); + addCreator("6", creator); + + creator = NEW BiCGStab2<SystemVector>::Creator; + addCreator("bicgstab2", creator); + addCreator("8", creator); + + creator = NEW MultiGridWrapperVec::Creator; + addCreator("mg", creator); + addCreator("7", creator); + + creator = NEW GMResSolver2<SystemVector>::Creator; + addCreator("gmres2", creator); + addCreator("9", creator); + + creator = NEW TFQMR<SystemVector>::Creator; + addCreator("tfqmr", creator); + addCreator("10", creator); + + creator = NEW VecSymSolver<SystemVector>::Creator; + addCreator("vecsym", creator); + addCreator("11", creator); + +#ifdef HAVE_UMFPACK + creator = NEW UmfPackSolver<SystemVector>::Creator; + addCreator("umfpack", creator); + addCreator("12", creator); +#endif + } + + template<> + void CreatorMap<SmootherBase<Matrix<DOFMatrix*>, + Vector<SparseVector<double>*>, + Vector< ::std::set<DegreeOfFreedom>*> > >::addDefaultCreators() + { + SmootherCreator<Matrix<DOFMatrix*>, + Vector<SparseVector<double>*>, + Vector< ::std::set<DegreeOfFreedom>*> > *creator; + + creator = NEW GSSmoother<Matrix<DOFMatrix*>, + Vector<SparseVector<double>*>, + Vector< ::std::set<DegreeOfFreedom>*> >::Creator; + addCreator("gs", creator); + addCreator("1", creator); + + creator = NEW JacobiSmoother<Matrix<DOFMatrix*>, + Vector<SparseVector<double>*>, + Vector< ::std::set<DegreeOfFreedom>*> >::Creator; + addCreator("j", creator); + addCreator("2", creator); + + creator = NEW BoxSmoother::Creator; + addCreator("box", creator); + addCreator("3", creator); + + } + + template<> + void CreatorMap<NonLinSolver<SystemVector> >::addDefaultCreators() + { + NonLinSolverCreator<SystemVector> *creator; + + creator = NEW Newton<SystemVector>::Creator; + addCreator("newton", creator); + addCreator("1", creator); + + creator = NEW NewtonS<SystemVector>::Creator; + addCreator("newton_fs", creator); + addCreator("2", creator); + } + + template<> + void CreatorMap<Estimator>::addDefaultCreators() + { + EstimatorCreator *creator; + + creator = NEW ResidualEstimator::Creator; + addCreator("residual", creator); + addCreator("1", creator); + + creator = NEW RecoveryEstimator::Creator; + addCreator("recovery", creator); + addCreator("2", creator); + } + + template<> + void CreatorMap<ElementData>::addDefaultCreators() + { + CreatorInterface<ElementData> *creator; + + creator = NEW LeafDataEstimatable::Creator; + addCreator("LeafDataEstimatable", creator); + + creator = NEW LeafDataEstimatableVec::Creator; + addCreator("LeafDataEstimatableVec", creator); + + creator = NEW LeafDataCoarsenable::Creator; + addCreator("LeafDataCoarsenable", creator); + + creator = NEW LeafDataCoarsenableVec::Creator; + addCreator("LeafDataCoarsenableVec", creator); + + creator = NEW LeafDataPeriodic::Creator; + addCreator("LeafDataPeriodic", creator); + + creator = NEW SurfaceRegion_ED::Creator; + addCreator("SurfaceRegion_ED", creator); + + creator = NEW ElementRegion_ED::Creator; + addCreator("ElementRegion_ED", creator); + } + +} diff --git a/AMDiS/src/CreatorMap.h b/AMDiS/src/CreatorMap.h new file mode 100644 index 0000000000000000000000000000000000000000..cf9d642e5d3eae7a7596b444c9066e071f15ad26 --- /dev/null +++ b/AMDiS/src/CreatorMap.h @@ -0,0 +1,101 @@ +// ============================================================================ +// == == +// == AMDiS - Adaptive multidimensional simulations == +// == == +// ============================================================================ +// == == +// == crystal growth group == +// == == +// == Stiftung caesar == +// == Ludwig-Erhard-Allee 2 == +// == 53175 Bonn == +// == germany == +// == == +// ============================================================================ +// == == +// == http://www.caesar.de/cg/AMDiS == +// == == +// ============================================================================ + +/** \file CreatorMap.h */ + +#ifndef AMDIS_CREATORMAP_H +#define AMDIS_CREATORMAP_H + +#include <map> + +#include "Global.h" +#include "CreatorInterface.h" + +namespace AMDiS { + + /** \ingroup Common + * \brief + * A CreatorMap is used to construct objects, which types depends on key words + * determined at run time. For example the OEMSolverMap can create the different + * solver types depending on the solver parameter of the init file. The benefit + * of such creator maps is, that you can extend them only by writing an creator + * class for your own new class and give the creator together with a key word + * to the map. + */ + template<typename BaseClass> + class CreatorMap + { + public: + /** \brief + * Adds a new creator together with the given key to the map. + */ + static void addCreator(::std::string key, CreatorInterface<BaseClass>* creator) + { + FUNCNAME("CreatorMap::addCreator()"); + init(); + TEST_EXIT(creatorMap[key] == NULL) + ("there is already a creator for key %s\n",key.c_str()); + creatorMap[key] = creator; + }; + + /** \brief + * Creates a object of the type corresponding to key. + */ + static CreatorInterface<BaseClass>* getCreator(::std::string key) { + FUNCNAME("CreatorMap::getCreator()"); + init(); + CreatorInterface<BaseClass> *creator = creatorMap[key]; + TEST_EXIT(creator)("no creator for key %s\n", key.c_str()); + return creator; + }; + + static void addDefaultCreators(); + + protected: + /** \brief + * Constructor is protected because derived maps should be singleton. + */ + static void init() { + if(!initialized) { + initialized = true; + NullCreator<BaseClass> *nullCreator = new NullCreator<BaseClass>; + addCreator("no", nullCreator); + addCreator("0", nullCreator); + addDefaultCreators(); + } + }; + + protected: + /** \brief + * STL map containing the pairs of keys and creators. + */ + static ::std::map< ::std::string, CreatorInterface<BaseClass>* > creatorMap; + + static bool initialized; + }; + + template<typename BaseClass> + ::std::map< ::std::string, CreatorInterface<BaseClass>* > CreatorMap<BaseClass>::creatorMap; + + template<typename BaseClass> + bool CreatorMap<BaseClass>::initialized = false; + +} + +#endif diff --git a/AMDiS/src/CylinderProject.h b/AMDiS/src/CylinderProject.h new file mode 100644 index 0000000000000000000000000000000000000000..daa50dc36f56881cab99e07f0ea3ac24cc5bb551 --- /dev/null +++ b/AMDiS/src/CylinderProject.h @@ -0,0 +1,93 @@ +// ============================================================================ +// == == +// == AMDiS - Adaptive multidimensional simulations == +// == == +// ============================================================================ +// == == +// == crystal growth group == +// == == +// == Stiftung caesar == +// == Ludwig-Erhard-Allee 2 == +// == 53175 Bonn == +// == germany == +// == == +// ============================================================================ +// == == +// == http://www.caesar.de/cg/AMDiS == +// == == +// ============================================================================ + +/** \file CylinderProject.h */ + +#ifndef AMDIS_CYLINDERPROJECT_H +#define AMDIS_CYLINDERPROJECT_H + +namespace AMDiS { + + // ============================================================================== + // ===== class CylinderProject ================================================== + // ============================================================================== + + /** \brief + * Projects world coordinates to the surface of a cylinder with given center, + * radius and direction. Can be used as boundary or volume projection. + */ + class CylinderProject : public Projection + { + public: + /** \brief + * Constructor. + */ + CylinderProject(int id, + ProjectionType type, + WorldVector<double> &c, + WorldVector<double> &d, + double r) + : Projection(id, type), + center_(c), + direction_(d), + radius_(r) + { + double norm = sqrt(direction_*direction_); + direction_ *= 1.0 / norm; + }; + + /** \brief + * Destructor. + */ + virtual ~CylinderProject() {}; + + /** \brief + * Implementation of Projection::project(); + */ + void project(WorldVector<double> &x) { + x -= center_; + WorldVector<double> v1 = direction_; v1 *= (x*direction_); + WorldVector<double> v2 = x; v2 -= v1; + double norm = sqrt(v2 * v2); + TEST_EXIT(norm != 0.0)("can't project vector x\n"); + v2 *= 1.0 / norm; + x = v2; x *= radius_; x += v1; + x += center_; + }; + + protected: + /** \brief + * Center of the cylinder. + */ + WorldVector<double> center_; + + /** \brief + * Direction of the cylinder. + */ + WorldVector<double> direction_; + + /** \brief + * Radius of the cylinder. + */ + double radius_; + }; + +} + +#endif diff --git a/AMDiS/src/DOFAdmin.cc b/AMDiS/src/DOFAdmin.cc new file mode 100755 index 0000000000000000000000000000000000000000..c8cc47b655eee2845c2858a8c9d811dd35c57494 --- /dev/null +++ b/AMDiS/src/DOFAdmin.cc @@ -0,0 +1,403 @@ +#include <algorithm> + +#include "QPsiPhi.h" +#include "BasisFunction.h" +#include "Boundary.h" +#include "DOFAdmin.h" +#include "ElInfo.h" +#include "Error.h" +#include "FiniteElemSpace.h" +#include "Mesh.h" +#include "DOFVector.h" +#include "DOFIterator.h" + +namespace AMDiS { + + const int DOFAdmin::sizeIncrement = 10; + + void DOFAdmin::init() + { + firstHole = size = usedCount = holeCount = sizeUsed = 0; + dofFree.clear(); + } + + + DOFAdmin::DOFAdmin(Mesh* m) + : mesh(m), + nrDOF(mesh->getDim(), NO_INIT), + nr0DOF(mesh->getDim(), NO_INIT) + { init(); } + + DOFAdmin::DOFAdmin(Mesh* m,::std::string aName) + : name(aName), + mesh(m), + nrDOF(mesh->getDim(), NO_INIT), + nr0DOF(mesh->getDim(), NO_INIT) + { + init(); + } + + DOFAdmin& DOFAdmin::operator=(const DOFAdmin& src) + { + int i; + + if (this!=&src) { + mesh=src.mesh; + name=src.name; + dofFree=src.dofFree; + firstHole=src.firstHole; + size=src.size; + usedCount=src.usedCount; + holeCount=src.holeCount; + sizeUsed=src.sizeUsed; + for(i=0;i<4;nrDOF[i]=src.nrDOF[i++]) { + nr0DOF[i]=src.nr0DOF[i]; + }; + dofIndexedList=src.dofIndexedList; + dofContainerList=src.dofContainerList; + } + return *this; + } + /****************************************************************************/ + /* use a bit vector to indicate used/unused dofs */ + /* storage needed: one bit per dof */ + /****************************************************************************/ + + bool DOFAdmin::operator==(const DOFAdmin& ad) const + { + if (name!=ad.name) return false; + if (mesh!=ad.mesh) return false; + return true; + } + + + DOFAdmin::DOFAdmin(const DOFAdmin&) + {} + + void DOFAdmin::freeDOFIndex(int dof) { + FUNCNAME("DOFAdmin::freeDOFIndex"); + + TEST_EXIT(usedCount > 0)("no dofs in use\n"); + TEST_EXIT((dof >= 0)&&(dof < size))("invalid dof index %d\n",dof); + + ::std::list<DOFIndexedBase*>::iterator di; + ::std::list<DOFIndexedBase*>::iterator end = dofIndexedList.end(); + + for(di = dofIndexedList.begin(); di != end; ++di) { + (*di)->freeDOFContent(dof); + } + + ::std::list<DOFContainer*>::iterator dc; + ::std::list<DOFContainer*>::iterator dcend = dofContainerList.end(); + + for(dc = dofContainerList.begin(); dc != dcend; ++dc) { + (*dc)->freeDOFIndex(dof); + } + + dofFree[dof] = true; + + if (static_cast<int>(firstHole) > dof) firstHole = dof; + + usedCount--; + holeCount++; + } + + /****************************************************************************/ + + int DOFAdmin::getDOFIndex() + { + FUNCNAME("DOFAdmin::getDOFIndex"); + int i, dof = 0; + + // if there is a hole + if (firstHole < static_cast<int>(dofFree.size())) { + TEST_EXIT(dofFree[firstHole])("no hole at firstHole!\n"); + // its no longer a hole + dofFree[firstHole] = false; + dof = firstHole; + // search new hole + int dfsize = static_cast<int>(dofFree.size()); + for (i = firstHole+1; i < dfsize; i++) { + if (dofFree[i]) { + break; + } + } + firstHole = i; + } + // if there is no hole + else { + // enlarge dof-list + enlargeDOFLists(0); + TEST_EXIT(firstHole < static_cast<int>(dofFree.size())) + ("no free entry after enlargeDOFLists\n"); + TEST_EXIT(dofFree[firstHole]) + ("no free bit at firstHole\n"); + dofFree[firstHole] = false; + dof = firstHole; + firstHole++; + } + + usedCount++; + if (holeCount > 0) holeCount--; + sizeUsed = max(sizeUsed, dof+1); + + return(dof); + } + + + /****************************************************************************/ + + void DOFAdmin::enlargeDOFLists(int minsize) + { + FUNCNAME("DOFAdmin::enlargeDOFLists"); + int old, newval; //, i, j; + + old = size; + if (minsize > 0) { + if (old > minsize) return; + } + + newval = max(minsize, static_cast<int>((dofFree.size() + sizeIncrement))); + + size = newval; + + // stl resizes dofFree to at least newval and sets all new values true + dofFree.resize(newval, true); + + firstHole = old; + + // enlarge all vectors and matrices + // but DOFVectors<int> don't have to be changed + + ::std::list<DOFIndexedBase*>::iterator di; + ::std::list<DOFIndexedBase*>::iterator end = dofIndexedList.end(); + + for(di = dofIndexedList.begin(); di != end; ++di) { + if((*di)->getSize() < newval) { + (*di)->resize(newval); + } + } + } + + void DOFAdmin::addDOFIndexed(DOFIndexedBase* dofIndexed) { + FUNCNAME("DOFAdmin::addDOFIndexed"); + TEST_EXIT(dofIndexed)("no dofIndexed\n"); + + if(dofIndexed->getSize() < size) { + dofIndexed->resize(size); + } + + dofIndexedList.push_back(dofIndexed); + } + + void DOFAdmin::removeDOFIndexed(DOFIndexedBase* dofIndexed) + { + FUNCNAME("DOFAdmin::removeDOFIndexed"); + ::std::list<DOFIndexedBase*>::iterator it; + ::std::list<DOFIndexedBase*>::iterator end = dofIndexedList.end(); + for(it=dofIndexedList.begin(); it != end; ++it) { + if(*it == dofIndexed) { + dofIndexedList.erase(it); + return; + } + } + ERROR("DOFIndexed not in list\n"); + } + + void DOFAdmin::addDOFContainer(DOFContainer* cont) + { + FUNCNAME("DOFAdmin::addDOFContainer"); + TEST_EXIT(cont)("no container\n"); + dofContainerList.push_back(cont); + } + + void DOFAdmin::removeDOFContainer(DOFContainer* cont) + { + FUNCNAME("DOFAdmin::removeDOFContainer"); + ::std::list<DOFContainer*>::iterator it; + ::std::list<DOFContainer*>::iterator end = dofContainerList.end(); + for(it=dofContainerList.begin(); it != end; ++it) { + if(*it == cont) { + dofContainerList.erase(it); + return; + } + } + ERROR("container not in list\n"); + } + + + /****************************************************************************/ + + void DOFAdmin::compress(::std::vector<DegreeOfFreedom> &new_dof) + { + FUNCNAME("DOFAdmin::compress"); + int i,n,first,last=0; + + // nothing to do ? + if (size < 1) return; + if (usedCount < 1) return; + if (holeCount < 1) return; + + // vector to mark used dofs + for(i=0; i < size; i++) { + new_dof[i] = -1; + } + + // mark used dofs + DOFIteratorBase it(this, USED_DOFS); + for (it.reset(); !it.end(); ++it) new_dof[it.getDOFIndex()] = 1; + + n = 0; + for (i = 0; i < size; i++) { /* create a MONOTONE compress */ + if (new_dof[i] == 1) { + new_dof[i] = n++; + last = i; + } + } + + TEST_EXIT(n == usedCount)("count %d != usedCount %d\n", n, usedCount); + + // mark used dofs in compressed dofFree + for(i=0; i < n; i++) { + dofFree[i] = false; + } + // mark unused dofs in compressed dofFree + for(i=n; i < size; i++) { + dofFree[i] = true; + } + + firstHole = n; + holeCount = 0; + sizeUsed = n; + + // get index of first changed dof + first = last; + for (i=0; i<size; i++) { + if ((new_dof[i] < i) && (new_dof[i] >= 0)) { + first = i; + break; + } + } + + ::std::list<DOFIndexedBase*>::iterator di; + ::std::list<DOFIndexedBase*>::iterator end = dofIndexedList.end(); + for(di = dofIndexedList.begin(); di != end; ++di) { + (*di)->compressDOFIndexed(first, last, new_dof); + }; + + + ::std::list<DOFContainer*>::iterator dc; + ::std::list<DOFContainer*>::iterator endc = dofContainerList.end(); + for(dc = dofContainerList.begin(); dc != endc; dc++) { + (*dc)->compressDOFContainer(n, new_dof); + }; + + return; + } + + const int DOFAdmin::getNumberOfDOFs(int i) const { + return nrDOF[i]; + } + + const int DOFAdmin::getNumberOfPreDOFs(int i) const { + TEST_EXIT((0<=i)&&(4>i))(""); + return nr0DOF[i]; + } + + void DOFAdmin::setNumberOfDOFs(int i,int v) { + TEST_EXIT((0<=i)&&(4>i))(""); + nrDOF[i]=v; + } + + void DOFAdmin::setNumberOfPreDOFs(int i, int v) { + TEST_EXIT((0<=i)&&(4>i))(""); + nr0DOF[i]=v; + } + + DOFAdmin::~DOFAdmin() + { + } + + void DOFAdmin::serialize(::std::ostream &out) + { + // write name + out << name << ::std::endl; + + // write dofFree + int i; + int s = static_cast<int>(dofFree.size()); + out.write(reinterpret_cast<const char*>(&s), sizeof(int)); + for (i = 0; i < s; i++) { + bool free = dofFree[i]; + out.write(reinterpret_cast<const char*>(&free), sizeof(bool)); + } + + // write firstHole + out.write(reinterpret_cast<const char*>(&firstHole), sizeof(unsigned int)); + + // write size + out.write(reinterpret_cast<const char*>(&size), sizeof(int)); + + // write usedCount + out.write(reinterpret_cast<const char*>(&usedCount), sizeof(int)); + + // write holeCount + out.write(reinterpret_cast<const char*>(&holeCount), sizeof(int)); + + // write sizeUsed + out.write(reinterpret_cast<const char*>(&sizeUsed), sizeof(int)); + + // write nrDOF + nrDOF.serialize(out); + + // write nr0DOF + nr0DOF.serialize(out); +} + + void DOFAdmin::deserialize(::std::istream &in) + { + // read name + in >> name; + in.get(); + + // read dofFree + int i; + int s; + in.read(reinterpret_cast<char*>(&s), sizeof(int)); + dofFree.resize(s); + for (i = 0; i < s; i++) { + bool free; + in.read(reinterpret_cast<char*>(&free), sizeof(bool)); + dofFree[i] = free; + } + + // read firstHole + in.read(reinterpret_cast<char*>(&firstHole), sizeof(unsigned int)); + + // read size + in.read(reinterpret_cast<char*>(&size), sizeof(int)); + + // read usedCount + in.read(reinterpret_cast<char*>(&usedCount), sizeof(int)); + + // read holeCount + in.read(reinterpret_cast<char*>(&holeCount), sizeof(int)); + + // read sizeUsed + in.read(reinterpret_cast<char*>(&sizeUsed), sizeof(int)); + + // read nrDOF + nrDOF.deserialize(in); + + // read nr0DOF + nr0DOF.deserialize(in); + + ::std::list<DOFIndexedBase*>::iterator di; + ::std::list<DOFIndexedBase*>::iterator end = dofIndexedList.end(); + + for(di = dofIndexedList.begin(); di != end; ++di) { + (*di)->resize(size); + } + } + +} diff --git a/AMDiS/src/DOFAdmin.h b/AMDiS/src/DOFAdmin.h new file mode 100644 index 0000000000000000000000000000000000000000..51a5ae689dcdaad29bc67fa5e36dd4af2d681c80 --- /dev/null +++ b/AMDiS/src/DOFAdmin.h @@ -0,0 +1,372 @@ +// ============================================================================ +// == == +// == AMDiS - Adaptive multidimensional simulations == +// == == +// ============================================================================ +// == == +// == crystal growth group == +// == == +// == Stiftung caesar == +// == Ludwig-Erhard-Allee 2 == +// == 53175 Bonn == +// == germany == +// == == +// ============================================================================ +// == == +// == http://www.caesar.de/cg/AMDiS == +// == == +// ============================================================================ + +/** \file DOFAdmin.h */ + +/** \defgroup DOFAdministration DOF adaministration module + * @{ <img src="dof.png"> @} + * \brief + * Contains all classes used for the DOF administration. + */ + +#ifndef AMDIS_DOFADMIN_H +#define AMDIS_DOFADMIN_H + +// ============================================================================ +// ===== includes ============================================================= +// ============================================================================ + +#include "Global.h" +#include "FixVec.h" +#include "MemoryManager.h" +#include "Serializable.h" +#include <vector> +#include <memory> +#include <list> + +namespace AMDiS { + + // ============================================================================ + // ===== forward declarations ================================================= + // ============================================================================ + + class Mesh; + class FiniteElemSpace; + class ElInfo; + class DOFAdmin; + class BasisFunction; + class DOFIndexedBase; + class DOFContainer; + + template<typename T> class DOFVector; + + // ============================================================================ + // ===== class DOFAdmin ======================================================= + // ============================================================================ + + /** \ingroup DOFAdministration + * \brief + * Holds all data about one set of DOFs. It includes information about used and + * unused DOF indices, as well as lists of DOFIndexed objects and DOFContainer + * objects, that are automatically resized and resorted during mesh changes. + */ + class DOFAdmin : public Serializable + { + public: + MEMORY_MANAGED(DOFAdmin); + + DOFAdmin(); + + /** \brief + * constructor + */ + DOFAdmin(Mesh* m); + + /** \brief + * constructor + */ + DOFAdmin(Mesh* m,::std::string aName); + + /** \brief + * copy constructor + */ + DOFAdmin(const DOFAdmin&); + + /** \brief + * destructor + */ + virtual ~DOFAdmin(); + + /** \brief + * Enlarges the number of DOFs that can be managed at least to minsize by + * a step size of \ref sizeIncrement. + */ + void enlargeDOFLists(int minsize); + + /** \brief + * assignment operator + */ + DOFAdmin& operator=(const DOFAdmin&); + + /** \brief + * Compares two DOFAdmins by their names. + */ + bool operator==(const DOFAdmin&) const; + + /** \brief + * Compares two DOFAdmins by their names. + */ + inline bool operator!=(const DOFAdmin& ad) const {return !(ad==*this);}; + + /** \brief + * Adds a DOFIndexedBase object to the DOFAdmin. This object will be + * managed by DOFAdmin from now on. + */ + void addDOFIndexed(DOFIndexedBase* dofIndexed); + + /** \brief + * Adds a DOFContainer object to the DOFAdmin. + */ + void addDOFContainer(DOFContainer* dofContainer); + + /** \brief + * Removes the given DOFIndexedBase object from DOFAdmin. + */ + void removeDOFIndexed(DOFIndexedBase* dofIndexed); + + /** \brief + * Removes the given DOFContainer object from DOFAdmin. + */ + void removeDOFContainer(DOFContainer* dofContainer); + + /** \brief + * Removes all holes of unused DOF indices by compressing the used range of + * indices (it does not resize the vectors). While the global index of a DOF + * may change, the relative order of DOF indices remains unchanged during + * compression. This method is usually called after mesh adaption involving + * higher order elements or coarsening. + */ + void compress(::std::vector<DegreeOfFreedom> &new_dof); + + /** \brief + * Returns an iterator to the begin of \ref dofIndexedList + */ + ::std::list<DOFIndexedBase*>::iterator beginDOFIndexed() { + return dofIndexedList.begin(); + }; + + /** \brief + * Returns an iterator to the end of \ref dofIndexedList + */ + ::std::list<DOFIndexedBase*>::iterator endDOFIndexed() { + return dofIndexedList.end(); + }; + + // ===== getting methods ====================================================== + + /** \name getting methods + * \{ + */ + + /** \brief + * Returns \ref sizeUsed. + */ + inline const int getUsedSize() const { + return sizeUsed; + }; + + /** \brief + * Returns \ref size + */ + inline const int getSize() const { + return size; + }; + + /** \brief + * Returns \ref usedCount + */ + inline const int getUsedDOFs() const { + return usedCount; + }; + + /** \brief + * Returns \ref holeCount + */ + inline const int getHoleCount() const { + return holeCount; + }; + + /** \brief + * Returns \ref name + */ + inline const ::std::string& getName() const { + return name; + }; + + /** \brief + * Returns \ref nrDOF[i] + */ + const int getNumberOfDOFs(int i) const; + + /** \brief + * Returns \ref nrDOF + */ + inline const DimVec<int>& getNumberOfDOFs() const { + return nrDOF; + }; + + /** \brief + * Returns \ref nr0DOF[i] + */ + const int getNumberOfPreDOFs(int i) const; + + /** \brief + * Returns \ref nr0DOF + */ + inline const DimVec<int>& getNumberOfPreDOFs() const { + return nr0DOF; + }; + + /** \brief + * Returns \ref mesh + */ + inline const Mesh* getMesh() const { + return mesh; + }; + + /** \brief + * Returns \ref dofFree, the array denoting DOFs to be either free or used. + */ + inline const ::std::vector<bool>& getDOFFree() const { + return dofFree; + }; + + /** \brief + * Returns if the given DOF is free. + */ + inline const bool isDOFFree(int i) const { + return dofFree[i]; + }; + + /** \} */ + + // ===== setting methods ====================================================== + + /** \name setting methods + * \{ + */ + + /** \brief + * Sets \ref nrDOF[i] = v + */ + void setNumberOfDOFs(int i,int v); + + /** \brief + * Sets \ref nr0DOF[i] = v + */ + void setNumberOfPreDOFs(int i, int v); + + /** \brief + * Sets \ref name = n + */ + inline void setName(const ::std::string& n) { name = n; }; + + /** \brief + * Sets \ref mesh = m + */ + inline void setMesh(Mesh* m) { mesh = m; }; + + /** \} */ + + protected: + /** \brief + * initializes this DOFAdmin + */ + void init(); + + /** \brief + * Adds one index to all DOF lists. Used by Mesh::getDOF() to provide + * DOFS for a specific position + */ + int getDOFIndex(); + + /** \brief + * Frees index dof. Used by Mesh::getDOF() + */ + void freeDOFIndex(int dof); + + // ===== Serializable implementation ===== + + void serialize(::std::ostream &out); + + void deserialize(::std::istream &in); + + protected: + /** \brief + * name of this DOFAdmin + */ + ::std::string name; + + /** \brief + * the mesh this DOFAdmin belongs to + */ + Mesh *mesh; + + /** \brief + * the dofFree vector stores for each index whether it is used or not + */ + ::std::vector<bool> dofFree; + + /** \brief + * index of the first free value in \ref dofFree + */ + int firstHole; + + /** \brief + * allocated size of managed vectors and matrices + */ + int size; + + /** \brief + * number of used dof indices + */ + int usedCount; + + /** \brief + * number of FREED dof indices (NOT size-sizeUsed) + */ + int holeCount; + + /** \brief + * > max. index of a used entry + */ + int sizeUsed; + + /** \brief + * dofs from THIS DOFAdmin + */ + DimVec<int> nrDOF; + + /** \brief + * dofs from previous DOFAdmins + */ + DimVec<int> nr0DOF; + + /** \brief + * list of all managed DOFIndexed objects. + */ + ::std::list<DOFIndexedBase*> dofIndexedList; + + /** \brief + * list of all managed DOFContainer objects + */ + ::std::list<DOFContainer*> dofContainerList; + + /** \brief + * size increment used by \ref enlargeDOFLists. + */ + static const int sizeIncrement; + + friend class DOFIteratorBase; + friend class Mesh; + }; + +} + +#endif // AMDIS_DOFADMIN_H diff --git a/AMDiS/src/DOFContainer.h b/AMDiS/src/DOFContainer.h new file mode 100644 index 0000000000000000000000000000000000000000..a37de183b8c004c89b3553213ee0da9590652bb4 --- /dev/null +++ b/AMDiS/src/DOFContainer.h @@ -0,0 +1,73 @@ +// ============================================================================ +// == == +// == AMDiS - Adaptive multidimensional simulations == +// == == +// ============================================================================ +// == == +// == crystal growth group == +// == == +// == Stiftung caesar == +// == Ludwig-Erhard-Allee 2 == +// == 53175 Bonn == +// == germany == +// == == +// ============================================================================ +// == == +// == http://www.caesar.de/cg/AMDiS == +// == == +// ============================================================================ + +/** \file DOFContainer.h */ + +#ifndef AMDIS_DOFCONTAINER_H +#define AMDIS_DOFCONTAINER_H + +#include "Global.h" + +namespace AMDiS { + + // =========================================================================== + // ===== class DOFContainer ================================================== + // =========================================================================== + + /** \ingroup DOFAdministration + * \brief + * DOFContainer is the base class for objects that stores DOF indices. + * After a DOFContainer object is registered to a DOFAdmin, the DOF + * indices of the container will be managed during DOF compression. The + * DOFAdmin then calls the compress method of every registered DOFContainer. + */ + class DOFContainer + { + public: + virtual ~DOFContainer() {}; + + /** \brief + * Returns the DOF index at position i. Must be overriden by a concrete + * DOFContainer. + */ + virtual DegreeOfFreedom& operator[](int i) = 0; + + virtual void freeDOFIndex(DegreeOfFreedom dof) {}; + + /** \brief + * Used by DOFAdmin to actualize the DOF indices in this container after + * DOF compression. + */ + + virtual void compressDOFContainer(int size, ::std::vector<DegreeOfFreedom> &newDOF) + { + int i, j; + for(i=0; i < size; i++) { + if((j = newDOF[operator[](i)]) >= 0) { + operator[](i) = j; + } else { + ERROR_EXIT("invalid dof in dof container\n"); + } + } + }; + }; + +} + +#endif diff --git a/AMDiS/src/DOFIndexed.cc b/AMDiS/src/DOFIndexed.cc new file mode 100644 index 0000000000000000000000000000000000000000..b6e4758093bebe1fd236bedf2613d699794931e8 --- /dev/null +++ b/AMDiS/src/DOFIndexed.cc @@ -0,0 +1,41 @@ +#include "DOFIndexed.h" +#include "DOFMatrix.h" + +namespace AMDiS { + + void mv(MatrixTranspose transpose, + const DOFMatrix &a, + DOFIndexed<double> &x, + DOFIndexed<double> &result, + bool add) + { + FUNCNAME("DOFVector<T>::mv"); + int irow, jcol; + double sum; + + if (transpose == NoTranspose) { + DOFMatrix::Iterator rowIterator(const_cast<DOFMatrix*>(&a), USED_DOFS); + for(rowIterator.reset(); !rowIterator.end(); ++rowIterator) { + sum = 0; + irow = rowIterator.getDOFIndex(); + if(!add) result[irow] = 0.0; + for(::std::vector<MatEntry>::iterator colIterator = rowIterator->begin(); + colIterator != rowIterator->end(); + colIterator++) + { + jcol = colIterator->col; + if (jcol >= 0) { // entry used? + sum += (static_cast<double>(colIterator->entry)) * x[jcol]; + } else { + if (jcol == DOFMatrix::NO_MORE_ENTRIES) + break; + } + } + result[irow] += sum; + } + } else { + ERROR_EXIT("transpose=%d\n", transpose); + } + } + +} diff --git a/AMDiS/src/DOFIndexed.h b/AMDiS/src/DOFIndexed.h new file mode 100644 index 0000000000000000000000000000000000000000..0e250b0b75ea6f0efd02d7cd69620a7bd22671fc --- /dev/null +++ b/AMDiS/src/DOFIndexed.h @@ -0,0 +1,137 @@ +// ============================================================================ +// == == +// == AMDiS - Adaptive multidimensional simulations == +// == == +// ============================================================================ +// == == +// == crystal growth group == +// == == +// == Stiftung caesar == +// == Ludwig-Erhard-Allee 2 == +// == 53175 Bonn == +// == germany == +// == == +// ============================================================================ +// == == +// == http://www.caesar.de/cg/AMDiS == +// == == +// ============================================================================ + +/** \file DOFIndexed.h */ + +#ifndef AMDIS_DOFINDEXED_H +#define AMDIS_DOFINDEXED_H + +#include <vector> +#include "Global.h" +#include "DOFIterator.h" + +namespace AMDiS { + + class RCNeighbourList; + class FiniteElemSpace; + class DOFMatrix; + class ElInfo; + class Quadrature; + class FastQuadrature; + + // ============================================================================ + // ===== class DOFIndexedBase ================================================= + // ============================================================================ + + /** \ingroup DOFAdministration + * \brief + * Interface for objects that stores information indexed by DOF indices + * (like DOFVector or DOFMatrix). This interface is template type independent, + * so a DOFAdmin can handle a single list of DOFIndexedBase objects. + */ + class DOFIndexedBase + { + public: + virtual ~DOFIndexedBase() {}; + + /** \brief + * Returns the actual size. Must be overriden by sub classes + */ + virtual int getSize() const = 0; + + /** \brief + * Resizes the object to size. Must be overriden by sub classes + */ + virtual void resize(int size) = 0; + + /** \brief + * Used by DOFAdmin::compress. Must be overriden by sub classes + */ + virtual void compressDOFIndexed(int first, int last, + ::std::vector<DegreeOfFreedom> &newDOF) = 0; + + /** \brief + * Performs needed action when a DOF index is freed. Can be overriden in + * sub classes. The default behavior is to do nothing. + */ + virtual void freeDOFContent(int) {}; + + /** \brief + * Interpolation after refinement. Can be overriden in subclasses. + * The default behavior is to do nothing. + */ + virtual void refineInterpol(RCNeighbourList&, int) {}; + + /** \brief + * Restriction after coarsening. Can be overriden in subclasses. + * The default behavior is to do nothing. + */ + virtual void coarseRestrict(RCNeighbourList&, int) {}; + + /** \brief + * Returns the finite element space of this DOFIndexed object. Must be + * overriden in sub classes. + */ + virtual const FiniteElemSpace* getFESpace() const = 0; + }; + + // ============================================================================ + // ===== class DOFIndexed ===================================================== + // ============================================================================ + + /** \ingroup DOFAdministration + * \brief + * Templated interface for DOFIndexed objects. + */ + template<typename T> + class DOFIndexed : public DOFIndexedBase + { + public: + virtual ~DOFIndexed() {}; + + /** \brief + * Returns iterator to the begin of container + */ + virtual typename ::std::vector<T>::iterator begin() = 0; + + /** \brief + * Returns iterator to the end of container + */ + virtual typename ::std::vector<T>::iterator end() = 0; + + /** \brief + * Returns container element at index i + */ + virtual T& operator[](DegreeOfFreedom i) = 0; + + /** \brief + * Returns container element at index i + */ + virtual const T& operator[](DegreeOfFreedom i) const = 0; + }; + + void mv(MatrixTranspose transpose, + const DOFMatrix &a, + DOFIndexed<double> &x, + DOFIndexed<double> &result, + bool add = false); + +} + +#endif // AMDIS_DOFINDEXED_H diff --git a/AMDiS/src/DOFIterator.h b/AMDiS/src/DOFIterator.h new file mode 100644 index 0000000000000000000000000000000000000000..cea4da9e0ea93d391c0e93a63f3dace8f08b190f --- /dev/null +++ b/AMDiS/src/DOFIterator.h @@ -0,0 +1,324 @@ +// ============================================================================ +// == == +// == AMDiS - Adaptive multidimensional simulations == +// == == +// ============================================================================ +// == == +// == crystal growth group == +// == == +// == Stiftung caesar == +// == Ludwig-Erhard-Allee 2 == +// == 53175 Bonn == +// == germany == +// == == +// ============================================================================ +// == == +// == http://www.caesar.de/cg/AMDiS == +// == == +// ============================================================================ + +/** \file DOFIterator.h */ + +#ifndef AMDIS_DOFITERATOR_H +#define AMDIS_DOFITERATOR_H + +// ============================================================================ +// ===== includes ============================================================= +// ============================================================================ + +#include "DOFAdmin.h" +//#include "DOFIndexed.h" +#include "FiniteElemSpace.h" +#include "MemoryManager.h" + +namespace AMDiS { + + template<typename T> class DOFIndexed; + + // ============================================================================ + // ===== definitions ========================================================== + // ============================================================================ + + /** \brief + * Possible types of DOFIterator + */ + typedef enum { + USED_DOFS = 0, /**< iterate only used DOFs */ + FREE_DOFS = 1, /**< iterate only free DOFs */ + ALL_DOFS = 2 /**< iterate all DOFs */ + } DOFIteratorType; + + // ============================================================================ + // ===== class DOFIteratorBase ================================================ + // ============================================================================ + + /** \ingroup DOFAdministration + * \brief + * DOFIteratorBase can be the base class of Iterators for DOFIndexed objects + * or it can be used stand alone. Than it iterates through DOFAdmin's dofFree + * vector which stores whether a DOF is used or not. If it is used as base + * class for another Iterator, it provides base functionality, to iterate + * through the \ref iteratedObject of the sub class. All you have to do is to + * override the methods \ref goToBeginOfIteratedObject(), + * \ref goToEndOfIteratedObject() and \ref incObjectIterator(). + * Normally it is usefull to provide + * operator->() and operator*(), to dereference the iterator. But this is not + * possible in this base class, because it is template type independent. + */ + class DOFIteratorBase + { + public: + /** \brief + * Constructs a DOFIteratorBase object of type t which can iterate through + * admin's dofFree vector + */ + DOFIteratorBase(DOFAdmin* admin, DOFIteratorType t) + : dofAdmin(admin), + dofFree(&(dofAdmin->dofFree)), + type(t) + {}; + + virtual ~DOFIteratorBase() {}; + + /** \brief + * Resets the iterator to the begin of the iterated object. + * Sub classes must + * implement goToBeginOfIteratedObject() which resets the iterator. + */ + virtual void reset() { + position = 0; + dofFreeIterator = dofFree->begin(); + if(dofFreeIterator == dofFree->end()) { + return; + } + goToBeginOfIteratedObject(); + if(type != ALL_DOFS) { + if(*dofFreeIterator == (type == USED_DOFS)) + operator++(); + } + }; + + /** \brief + * Resets the iterator to the begin of the iterated object. + * Sub classes must + * implement goToBeginOfIteratedObject() which resets the iterator. + */ + virtual void reset2() { + position = 0; + dofFreeIterator = dofFree->begin(); + if(dofFreeIterator == dofFree->end()) { + return; + } + goToBeginOfIteratedObject(); + if(type != ALL_DOFS) { + if(*dofFreeIterator == (type == USED_DOFS)) + operator++(); + } + }; + + /** \brief + * Prefix operator++. + * Incrementation depends of the type of the iterator. If type is USED_DOFS, + * the iterator points to the next used DOF after operator call. If type is + * FREE_DOFS, it points to the next free DOF and if type is ALL_DOFS, it will + * point to the next DOF regardless whether it is used or not. Sub classes + * must implement incObjectIterator() which increments the object + * iterator. + */ + inline const DOFIteratorBase& operator++() { + if (type == ALL_DOFS) { + incObjectIterator(); + dofFreeIterator++; + position++; + return *this; + } + + if (type == USED_DOFS) { + if (position >= dofAdmin->getUsedSize()) { + position = dofAdmin->getSize(); + goToEndOfIteratedObject(); + dofFreeIterator = dofFree->end(); + return *this; + } + } + + do { + incObjectIterator(); + dofFreeIterator++; + position++; + } while ((dofFreeIterator != dofFree->end()) + && (*dofFreeIterator == (type == USED_DOFS))); + + return *this; + }; + + /** \brief + * Postfix operator++. + */ + inline DOFIteratorBase operator++(int) { + DOFIteratorBase clone = *this; + operator++(); + return clone; + }; + + inline const DOFIteratorBase& operator--() { + if (type == ALL_DOFS) { + decObjectIterator(); + dofFreeIterator--; + position--; + return *this; + } + + do { + decObjectIterator(); + dofFreeIterator--; + position--; + } while ((dofFreeIterator != dofFree->begin()) + && (*dofFreeIterator == (type == USED_DOFS))); + + return *this; + }; + + inline DOFIteratorBase operator--(int) { + DOFIteratorBase clone = *this; + operator--(); + return clone; + } + + /** \brief + * Dereferntiation of the \ref dofFreeIterator + */ + virtual bool isDOFFree() { + return *dofFreeIterator; + }; + + /** \brief + * Returns whether \ref dofFreeIterator already has reached the end of + * \ref dofFree + */ + inline bool end() { return (dofFreeIterator == dofFree->end()); }; + + inline bool begin() { return (dofFreeIterator == dofFree->begin()); }; + + /** \brief + * Returns the current position index of this iterator + */ + inline int getDOFIndex() { return position; }; + + protected: + /** \brief + * Override this to enable iteration through the object + */ + virtual void goToBeginOfIteratedObject() {}; + + /** \brief + * Override this to enable iteration through the object + */ + virtual void goToEndOfIteratedObject() {}; + + /** \brief + * Override this to enable iteration through the object + */ + virtual void incObjectIterator() {}; + + virtual void decObjectIterator() {}; + + protected: + DOFAdmin *dofAdmin; /**< DOFAdmin which contains + * the dofFree vector + */ + int position; /**< current position index */ + ::std::vector<bool> *dofFree; /**< stores which DOFs are used + */ + ::std::vector<bool>::iterator dofFreeIterator; /**< iterator for dofFree */ + const DOFIteratorType type; /**< type of this iterator */ + }; + + // ============================================================================ + // ===== class DOFIterator ==================================================== + // ============================================================================ + + /** \ingroup DOFAdministration + * \brief + * Implements a DOFIterator for a DOFIndexed<T> object + */ + template<typename T> + class DOFIterator : public DOFIteratorBase + { + public: + MEMORY_MANAGED(DOFIterator<T>); + + /** \brief + * Constructs a DOFIterator for cont of type t + */ + DOFIterator(DOFIndexed<T> *obj, DOFIteratorType t) + : DOFIteratorBase(dynamic_cast<DOFAdmin*>(obj->getFESpace()->getAdmin()), t), + iteratedObject(obj) + {}; + + /** \brief + * Constructs a DOFIterator for cont of type t + */ + DOFIterator(DOFAdmin *admin, + DOFIndexed<T> *obj, + DOFIteratorType t) + : DOFIteratorBase(admin, t), + iteratedObject(obj) + {}; + + /** \brief + * Dereference operator + */ + inline T& operator*() { return *it; }; + + /** \brief + * Dereference operator + */ + inline T* operator->() { return &(*it); }; + + inline bool operator!=(const DOFIterator<T>& rhs) { + if(this->iteratedObject != rhs.iteratedObject) return true; + if(this->it != rhs.it) return true; + return false; + }; + + inline bool operator==(const DOFIterator<T>& rhs) { + return !(this->operator==(rhs)); + } + + protected: + /** \brief + * Implementation of DOFIteratorBase::goToBeginOfIteratedObject() + */ + inline void goToBeginOfIteratedObject() { it = iteratedObject->begin(); }; + + /** \brief + * Implementation of DOFIteratorBase::goToEndOfIteratedObject() + */ + inline void goToEndOfIteratedObject() { it = iteratedObject->end(); }; + + /** \brief + * Implementation of DOFIteratorBase::incObjectIterator() + */ + inline void incObjectIterator() { ++it; }; + + /** \brief + * Implementation of DOFIteratorBase::incObjectIterator() + */ + inline void decObjectIterator() { --it; }; + + protected: + /** \brief + * Object that is iterated + */ + DOFIndexed<T> *iteratedObject; + + /** \brief + * Iterator for \ref iteratedObject + */ + typename ::std::vector<T>::iterator it; + }; + +} + +#endif // AMDIS_DOFITERATOR_H diff --git a/AMDiS/src/DOFMatrix.cc b/AMDiS/src/DOFMatrix.cc new file mode 100644 index 0000000000000000000000000000000000000000..5ee8198366286bccd511de35b3add3f367c347d3 --- /dev/null +++ b/AMDiS/src/DOFMatrix.cc @@ -0,0 +1,800 @@ +#include "DOFMatrix.h" +#include <algorithm> +#include <png.h> +#include "QPsiPhi.h" +#include "BasisFunction.h" +#include "Boundary.h" +#include "DOFAdmin.h" +#include "ElInfo.h" +#include "FiniteElemSpace.h" +#include "Mesh.h" +#include "DOFVector.h" +#include "Operator.h" +#include "BoundaryCondition.h" +#include "BoundaryManager.h" +#include "ElementMatrix.h" +#include "Assembler.h" + +namespace AMDiS { + + DOFMatrix *DOFMatrix::traversePtr = NULL; + + DOFMatrix::DOFMatrix() + { + rowFESpace = NULL; + colFESpace = NULL; + elementMatrix = NULL; + } + + DOFMatrix::DOFMatrix(const FiniteElemSpace* rowFESpace_, + const FiniteElemSpace* colFESpace_, + ::std::string name_) + : rowFESpace(rowFESpace_), + colFESpace(colFESpace_), + name(name_), + elementMatrix(NULL), + coupleMatrix(false) + { + TEST_EXIT(rowFESpace)("no rowFESpace\n"); + + if(!colFESpace) { + colFESpace = rowFESpace; + } + + if (rowFESpace && rowFESpace->getAdmin()) + (const_cast<DOFAdmin*>( rowFESpace->getAdmin()))->addDOFIndexed(this); + + boundaryManager = NEW BoundaryManager; + } + + DOFMatrix::DOFMatrix(const DOFMatrix& rhs) + : name(rhs.name+"copy") + { + *this=rhs; + elementMatrix = NULL; + if (rowFESpace && rowFESpace->getAdmin()) + (const_cast<DOFAdmin*>( rowFESpace->getAdmin()))->addDOFIndexed(this); + } + + DOFMatrix::~DOFMatrix() + { + FUNCNAME("DOFMatrix::~DOFMatrix"); + if(rowFESpace && rowFESpace->getAdmin()) { + (const_cast<DOFAdmin*>(rowFESpace->getAdmin()))->removeDOFIndexed(this); + } + if(elementMatrix != NULL) { + DELETE elementMatrix; + } + //DELETE boundaryManager; + } + + void DOFMatrix::print() const + { + FUNCNAME("DOFMatrix::print()"); + int i, j, jcol; + DOFMatrix::MatrixRow row; + + int sizeUsed = rowFESpace->getAdmin()->getUsedSize(); + + if (static_cast<int>(matrix.size()) < sizeUsed) { + WARNING("DOFMatrix not yet initialized\n"); + return; + } + + for (i = 0; i < sizeUsed; i++) { + row = matrix[i]; + MSG("row %3d:",i); + int rowSize = static_cast<int>( row.size()); + for (j = 0; j < rowSize; j++) { + jcol = row[j].col; + if (entryUsed(i,j)) { + Msg::print(" (%3d,%20.17lf)", jcol, row[j].entry); + } + } + Msg::print("\n"); + } + return; + } + + void DOFMatrix::printRow(int i) const + { + FUNCNAME("DOFMatrix::printRow()"); + + int sizeUsed = rowFESpace->getAdmin()->getUsedSize(); + + if (static_cast<int>(matrix.size()) < sizeUsed) { + WARNING("DOFMatrix not yet initialized\n"); + return; + } + + DOFMatrix::MatrixRow row = matrix[i]; + MSG("row %3d:",i); + int rowSize = static_cast<int>( row.size()); + for (int j = 0; j < rowSize; j++) { + int jcol = row[j].col; + if (entryUsed(i,j)) { + Msg::print(" (%3d,%20.17lf)", jcol, row[j].entry); + } + } + Msg::print("\n"); + } + + /****************************************************************************/ + /* clear: remove all entries from dof_matrix */ + /****************************************************************************/ + + void DOFMatrix::clear() + { + int i; + + for (i=0; i<static_cast<int>(matrix.size()); i++) { + matrix[i].resize(0); + } + return; + } + + bool DOFMatrix::symmetric() + { + FUNCNAME("DOFMatrix::symmetric()"); + + DegreeOfFreedom row, col; + double entry, tol = 1e-5; + + DOFMatrix::Iterator matrixRow(this, USED_DOFS); + + for (matrixRow.reset(); !matrixRow.end(); ++matrixRow) { + row = matrixRow.getDOFIndex(); + int rowSize = matrixRow->size(); + for (int i = 0; i < rowSize; i++) { + col = (*matrixRow)[i].col; + entry = (*matrixRow)[i].entry; + if (abs(entry - logAcc(col, row)) > tol) { + MSG("matrix[%d][%d] = %e, matrix[%d][%d] = %e\n", + row, col, entry, col, row, logAcc(col, row)); + + return false; + } + } + } + + return true; + } + + void DOFMatrix::test() + { + FUNCNAME("DOFMatrix::test()"); + + int non_symmetric = 0, found = 0; + + /* test symmetry */ + for (int i = 0; i < static_cast<int>(matrix.size()); i++) { + double sum = 0.0; + DOFMatrix::MatrixRow *row = &matrix[i]; + for (int j = 0; j < static_cast<int>(row->size()); j++) { + int jcol = (*row)[j].col; + if (entryUsed(i, j)) { + found = 0; + if ((*row)[j].entry != (*row)[j].entry) { + MSG("mat[%d,%d]=%10.5e ???\n", i, jcol, (*row)[j].entry); + WAIT; + } + DOFMatrix::MatrixRow *row2 = &matrix[jcol]; + for (int k = 0; k < static_cast<int>(row->size()); k++) { + int kcol = (*row)[k].col; + if (entryUsed(jcol, k)) { + if (kcol == i) { + found = 1; + if (abs((*row2)[k].entry - (*row)[j].entry) > 1.E-5) { + non_symmetric = 1; + MSG("mat[%d,%d]=%10.5e != mat[%d,%d]=%10.5e\n", + i, jcol, (*row)[j].entry, jcol, i, (*row2)[k].entry); + } + row2 = NULL; + break; + } + } + } + if (!found) { + non_symmetric = 1; + MSG("mat[%d,%d] not found\n", jcol, i); + } + } + } + if (abs(sum) > 1.E-5) { + MSG("Zeilensumme[%d] = %10.5e\n", i, sum); + } + } + + if (non_symmetric) { + MSG("matrix `%s' not symmetric.\n", name.data()); + } else { + MSG("matrix `%s' is symmetric.\n", name.data()); + } + } + + + DOFMatrix& DOFMatrix::operator=(const DOFMatrix& rhs) + { + rowFESpace = rhs.rowFESpace; + colFESpace = rhs.colFESpace; + operators = rhs.operators; + operatorFactor = rhs.operatorFactor; + matrix = rhs.matrix; + if (rhs.boundaryManager) { + boundaryManager = new BoundaryManager(*rhs.boundaryManager); + } else { + boundaryManager=NULL; + } + + return *this; + } + + + void DOFMatrix::addElementMatrix(double sign, + const ElementMatrix &elMat, + const BoundaryType *bound, + bool add) + { + FUNCNAME("DOFMatrix::addElementMatrix"); + + DegreeOfFreedom row, col; + double entry; + + int n_row = elMat.rowIndices.getSize(); + int n_col = elMat.colIndices.getSize(); + + for (int i = 0; i < n_row; i++) { // for all rows of element matrix + row = elMat.rowIndices[i]; + + BoundaryCondition *condition = + bound ? boundaryManager->getBoundaryCondition(bound[i]) : NULL; + + if (condition && condition->isDirichlet()) { + MatrixRow *matrixRow = &(matrix[row]); + if(coupleMatrix) { + matrixRow->resize(0); + } else { + matrixRow->resize(1); + ((*matrixRow)[0]).col = row; + ((*matrixRow)[0]).entry = 1.0; + } + } else { + for (int j = 0; j < n_col; j++) { // for all columns + col = elMat.colIndices[j]; + entry = elMat[i][j]; + addSparseDOFEntry(sign, row, col, entry, add); + } + } + } + } + + + + DegreeOfFreedom DOFMatrix::logToPhysIndex(DegreeOfFreedom a, + DegreeOfFreedom b) const + { + int j; + + for (j = 0; j < static_cast<int>(matrix[a].size()); j++) + if (b == matrix[a][j].col) + break; + + return (j == static_cast<int>(matrix[a].size())) ? -1 : j; + } + + + double DOFMatrix::logAcc(DegreeOfFreedom a,DegreeOfFreedom b) const + { + int j; + + for (j = 0; j < static_cast<int>(matrix[a].size()); j++) + if (b == matrix[a][j].col) + break; + + return (j == static_cast<int>(matrix[a].size())) ? 0.0 : matrix[a][j].entry; + } + + void DOFMatrix::changeColOfEntry(DegreeOfFreedom a, + DegreeOfFreedom b, + DegreeOfFreedom c) + { + int j; + + for (j=0; j<static_cast<int>(matrix[a].size());j++) + if (b==matrix[a][j].col) break; + if (j!=static_cast<int>(matrix[a].size())) matrix[a][j].col=c; + } + + double *DOFMatrix::addSparseDOFEntry(double sign, int irow, + int jcol, double entry, + bool add) + { + FUNCNAME("add_sparse_dof_entry"); + + MatrixRow *row = &(matrix[irow]); + + if(add && !entry) return NULL; + + double *result = NULL; + + int i, freeCol = -1, rowSize = static_cast<int>( row->size()); + + TEST_EXIT(jcol>=0&&jcol<colFESpace->getAdmin()->getUsedSize())("Column index %d out of range 0-%d\n",jcol,colFESpace->getAdmin()->getUsedSize()-1); + + // first entry is diagonal entry + if(rowFESpace==colFESpace) + if (rowSize == 0) { + MatEntry newEntry = {irow, 0.0}; + row->push_back(newEntry); + rowSize = 1; + } + + // search jcol + for(i=0; i < rowSize; i++) { + // jcol found ? + if((*row)[i].col == jcol) { + break; + } + // remember free entry + if((*row)[i].col == UNUSED_ENTRY) { + freeCol = i; + } + // no more entries + if((*row)[i].col == NO_MORE_ENTRIES) { + freeCol = i; + if(rowSize > i+1) { + (*row)[i+1].entry = NO_MORE_ENTRIES; + } + break; + } + } + + // jcol found? + if(i < rowSize) { + if(!add) (*row)[i].entry = 0.0; + (*row)[i].entry += sign * entry; + result = &((*row)[i].entry); + } else { + if(freeCol == -1) { + MatEntry newEntry = {jcol, sign * entry}; + row->push_back(newEntry); + result = &((*row)[row->size() - 1].entry); + } else { + (*row)[freeCol].col = jcol; + if(!add) (*row)[freeCol].entry = 0.0; + (*row)[freeCol].entry += sign * entry; + result = &((*row)[freeCol].entry); + } + } + + return result; + } + + void DOFMatrix::addMatEntry(int row, MatEntry entry) + { + matrix[row].push_back(entry); + } + + void DOFMatrix::addMatEntry(int row, DegreeOfFreedom col, double value) + { + MatEntry entry; + entry.col = col; + entry.entry = value; + matrix[row].push_back(entry); + } + + void DOFMatrix::addRow(::std::vector<MatEntry> row) + { + matrix.push_back(row); + } + + void DOFMatrix::compressDOFIndexed(int first, int last, + ::std::vector<DegreeOfFreedom> &newDOF) + { + int i, j, k, col; + ::std::vector<MatEntry> *row; + + for(i = first; i <= last; i++) { + if((k = newDOF[i]) >= 0) { + matrix[k].swap(matrix[i]); + matrix[i].resize(0); + } + } + int usedSize = rowFESpace->getAdmin()->getUsedSize(); + for(i=0; i < usedSize; i++) { + row = reinterpret_cast< ::std::vector<MatEntry>*>(&(matrix[i])); + int rowSize = static_cast<int>(row->size()); + for (j=0; j < rowSize; j++) { + col = (*row)[j].col; + if (entryUsed(i,j)) (*row)[j].col = newDOF[col]; + } + } + } + + void DOFMatrix::freeDOFContent(int index) + { + int i, j, col=0, col2; + + if (0 < matrix[index].size()) { + // for all columns in this row + int size = static_cast<int>(matrix[index].size()); + for (i=0; i<size; i++) { + // if entry is used + if (entryUsed(index,i)) { + // get column of this entry + col = matrix[index][i].col; + if (col != index) { // remove symmetric entry if exists + int colsize = static_cast<int>(matrix[col].size()); + for (j=0; j< colsize; j++) { + col2 = matrix[col][j].col; + if (col2 == index) { + matrix[col][j].col = DOFMatrix::UNUSED_ENTRY; + } + else if (col2 == DOFMatrix::NO_MORE_ENTRIES) { + break; + } + } + } + } + else if (col == DOFMatrix::NO_MORE_ENTRIES) { + break; + } + } + matrix[index].resize(0); + } + } + + + ElementMatrix *DOFMatrix::assemble(double factor, ElInfo *elInfo, + const BoundaryType *bound, Operator *op) + { + FUNCNAME("DOFMatrix::assemble"); + + if(!op && operators.size() == 0) { + //WARNING("no operator\n"); + return NULL; + } + + Operator *operat = op ? op : operators[0]; + + elementMatrix = + operat->getAssembler()->initElementMatrix(elementMatrix, elInfo); + + if(op) { + op->getElementMatrix(elInfo, elementMatrix); + } else { + ::std::vector<Operator*>::iterator it; + ::std::vector<double*>::iterator factorIt; + for(it = operators.begin(), factorIt = operatorFactor.begin(); + it != operators.end(); + ++it, ++factorIt) + { + (*it)->getElementMatrix(elInfo, + elementMatrix, + *factorIt ? **factorIt : 1.0); + } + } + + addElementMatrix(factor, *elementMatrix, bound); + + return elementMatrix; + } + + Flag DOFMatrix::getAssembleFlag() + { + Flag fillFlag(0); + ::std::vector<Operator*>::iterator op; + for(op = operators.begin(); op != operators.end(); ++op) { + fillFlag |= (*op)->getFillFlag(); + } + return fillFlag; + } + + void DOFMatrix::mm(MatrixTranspose aTranspose, + DOFMatrix& a, + MatrixTranspose bTranspose, + DOFMatrix& b) + { + FUNCNAME("DOFMatrix::mm()"); + + WARNING("implementation not finished!!!\n"); + + int i,j; + + //TEST_EXIT(bTranspose == NoTranspose)("not yet for transposed matrix b"); + + TEST_EXIT(a.getColFESpace() == b.getRowFESpace()) + ("a.colFESpace != b.rowFESpace\n"); + TEST_EXIT(rowFESpace == a.getRowFESpace()) + ("rowFESpace != a.rowFESpace\n"); + TEST_EXIT(colFESpace == b.getColFESpace()) + ("colFESpace != b.colFESpace\n"); + + clear(); + + + if(aTranspose == NoTranspose && bTranspose == NoTranspose) { + int cols = b.getColFESpace()->getAdmin()->getUsedSize(); + DOFMatrix::Iterator rowIterator(this, USED_DOFS); + + // for every row ... + for(rowIterator.reset(); !rowIterator.end(); ++rowIterator) { + int rowIndex = rowIterator.getDOFIndex(); + // and every column of result + for(i=0; i < cols; i++) { + double entry = 0.0; + // for every entry in a[i] ... + for(j=0; j < static_cast<int>( a[rowIndex].size()); j++) { + int logIndex = a[rowIndex][j].col; + int physIndex = b.logToPhysIndex(logIndex, i); + if(physIndex != -1) { + entry += a[rowIndex][j].entry * b[logIndex][physIndex].entry; + } + } + if(entry != 0.0) { + addSparseDOFEntry(1.0, rowIndex, i, entry); + } + } + } + } else if(aTranspose == Transpose && bTranspose == NoTranspose) { + DOFMatrix::Iterator aIterator(&a, USED_DOFS); + DOFMatrix::Iterator bIterator(&b, USED_DOFS); + for(aIterator.reset(), bIterator.reset(); + !aIterator.end(); + ++aIterator, ++bIterator) + { + ::std::vector<MatEntry>::const_iterator aRowIt; + ::std::vector<MatEntry>::const_iterator bRowIt; + for(aRowIt = aIterator->begin(); aRowIt != aIterator->end(); ++aRowIt) { + int aCol = aRowIt->col; + if(aCol == UNUSED_ENTRY) continue; + if(aCol == NO_MORE_ENTRIES) break; + for(bRowIt = bIterator->begin(); bRowIt !=bIterator->end(); ++bRowIt) { + int bCol = bRowIt->col; + if(bCol == UNUSED_ENTRY) continue; + if(bCol == NO_MORE_ENTRIES) break; + + double entry = aRowIt->entry * bRowIt->entry; + + if(entry != 0.0) { + addSparseDOFEntry(1.0, aCol, bCol, entry); + } + } + } + } + } else if(aTranspose == NoTranspose && bTranspose == Transpose) { + // DOFMatrix::Iterator aIterator(&a, USED_DOFS); + // DOFMatrix::Iterator bIterator(&b, USED_DOFS); + // ::std::vector<MatEntry>::const_iterator aRowIt; + // ::std::vector<MatEntry>::const_iterator aRowBegin; + // ::std::vector<MatEntry>::const_iterator aRowEnd; + // ::std::vector<MatEntry>::const_iterator bRowIt; + // ::std::vector<MatEntry>::const_iterator bRowBegin; + // ::std::vector<MatEntry>::const_iterator bRowEnd; + // int row, col; + + // for(aIterator.reset(); !aIterator.end(); ++aIterator) { + // row = aIterator.getDOFIndex(); + // aRowBegin = aIterator->begin(); + // aRowEnd = aIterator->end(); + // for(bIterator.reset(); !bIterator.end(); ++bIterator) { + // col = bIterator.getDOFIndex(); + // double *entry = NULL; + // bRowBegin = bIterator->begin(); + // for(aRowIt = aRowBegin, bRowIt = bRowBegin; + // aRowIt != aRowEnd; + // ++aRowIt, ++bRowIt) + // { + // TEST_EXIT(aRowIt->col == bRowIt->col)("invalid col\n"); + // if(aRowIt->col == UNUSED_ENTRY) continue; + // if(aRowIt->col == NO_MORE_ENTRIES) break; + // double val = aRowIt->entry * bRowIt->entry; + // if(!entry) + // entry = addSparseDOFEntry(1.0, row, col, + // aRowIt->entry * bRowIt->entry, false); + // else + // (*entry) += aRowIt->entry * bRowIt->entry; + // } + // } + // } + ERROR_EXIT("not yet\n"); + } else if(aTranspose == Transpose && bTranspose == Transpose) { + ERROR_EXIT("not yet\n"); + } + } + + void DOFMatrix::axpy(double a, + const DOFMatrix& x, + const DOFMatrix& y) + { + FUNCNAME("DOFMatrix::axpy"); + TEST_EXIT(x.getRowFESpace() == y.getRowFESpace() && + rowFESpace == x.getRowFESpace()) + ("row fe-spaces not equal\n"); + TEST_EXIT(x.getColFESpace() == y.getColFESpace() && + colFESpace == x.getColFESpace()) + ("col fe-spaces not equal\n"); + + DOFMatrix::Iterator rowIterator(this, USED_DOFS); + DOFMatrix::Iterator xIterator(const_cast<DOFMatrix*>(&x), USED_DOFS); + DOFMatrix::Iterator yIterator(const_cast<DOFMatrix*>(&y), USED_DOFS); + + int i, rowIndex, colIndex; + + for(rowIterator.reset(), xIterator.reset(), yIterator.reset(); + !rowIterator.end(); + ++rowIterator, ++xIterator, ++yIterator) + { + rowIndex = rowIterator.getDOFIndex(); + // add x contributions to this row + for(i=0; i < static_cast<int>((*xIterator).size()); i++) { + colIndex = (*xIterator)[i].col; + if(colIndex >= 0) { + addSparseDOFEntry(a, rowIndex, colIndex, (*xIterator)[i].entry); + } + } + // add y contributions to this row + for(i=0; i < static_cast<int>((*yIterator).size()); i++) { + colIndex = (*yIterator)[i].col; + if(colIndex >= 0) { + addSparseDOFEntry(1.0, rowIndex, colIndex, (*yIterator)[i].entry); + } + } + } + } + + void DOFMatrix::scal(double b) + { + int i; + DOFMatrix::Iterator rowIterator(this, USED_DOFS); + for(rowIterator.reset(); !rowIterator.end(); ++rowIterator) { + for(i=0; i < static_cast<int>((*rowIterator).size()); i++) { + if((*rowIterator)[i].col >= 0) { + (*rowIterator)[i].entry *= b; + } + } + } + } + + void DOFMatrix::copy(const DOFMatrix& rhs) + { + clear(); + DOFMatrix::Iterator rhsIterator(const_cast<DOFMatrix*>(&rhs), USED_DOFS); + DOFMatrix::Iterator thisIterator(this, USED_DOFS); + ::std::vector<MatEntry>::const_iterator colIt; + ::std::vector<MatEntry>::const_iterator colBegin; + ::std::vector<MatEntry>::const_iterator colEnd; + for(rhsIterator.reset(), thisIterator.reset(); + !rhsIterator.end(); + ++rhsIterator, ++thisIterator) + { + colBegin = rhsIterator->begin(); + colEnd = rhsIterator->end(); + for(colIt = colBegin; colIt != colEnd; ++colIt) { + MatEntry matEntry; + matEntry.col = colIt->col; + matEntry.entry = colIt->entry; + thisIterator->push_back(matEntry); + } + } + } + + void DOFMatrix::createPictureFile(const char* filename, int dim) + { + png_structp png_ptr = png_create_write_struct(PNG_LIBPNG_VER_STRING, NULL, NULL, NULL); + + if (!png_ptr) + return; + + png_bytep rowPointers[dim]; + for (int i = 0; i < dim; i++) { + rowPointers[i] = (png_byte*)png_malloc(png_ptr, dim); + + for (int j = 0; j < dim; j++) { + rowPointers[i][j] = 255; + } + } + + double scalFactor = static_cast<double>(dim) / static_cast<double>(matrix.size()); + + for (int i = 0; i < static_cast<int>(matrix.size()); i++) { + int pi = static_cast<int>(static_cast<double>(i) * scalFactor); + + TEST_EXIT((pi >= 0) && (pi < dim))("PI"); + + for (int j = 0; j < static_cast<int>(matrix[i].size()); j++) { + + int pj = static_cast<int>(static_cast<double>(matrix[i][j].col) * scalFactor); + + TEST_EXIT((pj >= 0) && (pj < dim))("PJ"); + + rowPointers[pi][pj] = 0; + } + } + + FILE *fp = fopen(filename, "wb"); + TEST_EXIT(fp)("Cannot open file for writing matrix picture file!\n"); + + png_infop info_ptr = png_create_info_struct(png_ptr); + + if (!info_ptr) { + png_destroy_write_struct(&png_ptr, (png_infopp)NULL); + return; + } + + png_init_io(png_ptr, fp); + + png_set_IHDR(png_ptr, info_ptr, dim, dim, 8, + PNG_COLOR_TYPE_GRAY, + PNG_INTERLACE_NONE, + PNG_COMPRESSION_TYPE_DEFAULT, + PNG_FILTER_TYPE_DEFAULT); + + png_set_rows(png_ptr, info_ptr, rowPointers); + + png_write_png(png_ptr, info_ptr, PNG_TRANSFORM_IDENTITY, NULL); + + png_destroy_write_struct(&png_ptr, &info_ptr); + + fclose(fp); + } + + + int DOFMatrix::memsize() + { + int sizeDOFMatrix = sizeof(DOFMatrix); + int sizeMatrix = sizeof(::std::vector<MatrixRow>); + for (int i = 0; i < static_cast<int>(matrix.size()); i++) { + sizeMatrix += sizeof(MatrixRow) + matrix[i].size() * sizeof(MatEntry); + } + + return sizeDOFMatrix + sizeMatrix; + } + + + double norm(::std::vector<MatEntry> *row) + { + double result = 0.0; + ::std::vector<MatEntry>::iterator it; + for (it = row->begin(); it < row->end(); ++it) { + result += (*it).entry * (*it).entry; + } + + return(sqrt(result)); + } + + double min(::std::vector<MatEntry> *row) + { + double result = 0.0; + if (row->size() > 0) { + result = (*row)[0].entry; + } + + ::std::vector<MatEntry>::iterator it; + for (it = row->begin(); it < row->end(); ++it) { + if ((*it).entry < result) { + result = (*it).entry; + } + } + + return(result); + } + + double max(::std::vector<MatEntry> *row) + { + double result = 0.0; + if (row->size() > 0) { + result = (*row)[0].entry; + } + + ::std::vector<MatEntry>::iterator it; + for (it = row->begin(); it < row->end(); ++it) { + if ((*it).entry > result) { + result = (*it).entry; + } + } + + return(result); + } + +} diff --git a/AMDiS/src/DOFMatrix.h b/AMDiS/src/DOFMatrix.h new file mode 100644 index 0000000000000000000000000000000000000000..5e002e69b9ecadc43a16d30d2897c602e88a22d8 --- /dev/null +++ b/AMDiS/src/DOFMatrix.h @@ -0,0 +1,691 @@ +// ============================================================================ +// == == +// == AMDiS - Adaptive multidimensional simulations == +// == == +// ============================================================================ +// == == +// == crystal growth group == +// == == +// == Stiftung caesar == +// == Ludwig-Erhard-Allee 2 == +// == 53175 Bonn == +// == germany == +// == == +// ============================================================================ +// == == +// == http://www.caesar.de/cg/AMDiS == +// == == +// ============================================================================ + +/** \file DOFMatrix.h */ + +#ifndef AMDIS_DOFMATRIX_H +#define AMDIS_DOFMATRIX_H + +// ============================================================================ +// ===== includes ============================================================= +// ============================================================================ + +#include <vector> +#include <memory> +#include <list> +#include "Global.h" +#include "Flag.h" +#include "RCNeighbourList.h" +#include "DOFAdmin.h" +#include "DOFIterator.h" +#include "DOFIndexed.h" +#include "MemoryManager.h" +#include "Boundary.h" +#include "Serializable.h" + +namespace AMDiS { + + // ============================================================================ + // ===== forward declarations ================================================= + // ============================================================================ + + class Mesh; + class FiniteElemSpace; + class ElInfo; + class BasisFunction; + class FillInfo; + class Operator; + class ElementMatrix; + class BoundaryManager; + + template<typename T> class DOFVector; + + // =========================================================================== + // ===== struct MatEntry ===================================================== + // =========================================================================== + + /** \brief + * Represents one entry of a DOFMatrix + */ + struct MatEntry + { + /** \brief + * column index of entry (if >= 0; else unused) + */ + DegreeOfFreedom col; + + /** \brief + * matrix entry + */ + double entry; + }; + + + /** \brief + * Is used to search for all entries of a matrix which column index is + * smaller than a given value. + */ + class MatEntryValueLess : public ::std::unary_function<MatEntry, bool> { + private: + const double value_; + public: + MatEntryValueLess(const double& value) + : value_(value) + {}; + + bool operator()(const MatEntry& m) { + return (fabs(m.entry) < value_); + }; + }; + + + /** \brief + * Is used to search for all entries of a matrix which value is smaller + * than a given value. + */ + class MatEntryColLess : public ::std::unary_function<MatEntry, bool> { + private: + const int col_; + public: + MatEntryColLess(const int& col) + : col_(col) + {}; + + bool operator()(const MatEntry& m) { + return (fabs(m.col) < col_); + }; + }; + + + /** \brief + * This function is required if two MatEntries are compared by their col + * entry (for example when sorting a vector of MatEntries). + */ + struct CmpMatEntryCol : public ::std::binary_function<MatEntry, MatEntry, bool> { + bool operator()(const MatEntry& m1, const MatEntry m2) const { + return m1.col < m2.col; + }; + }; + + + /** \brief + * This function compares two matrix entries by their values. It returns true, + * if the value of m2 is greater than the value of m1. + */ + struct CmpMatEntryValue : public ::std::binary_function<MatEntry, MatEntry, bool> { + bool operator()(const MatEntry& m1, const MatEntry m2) const { + return m1.entry < m2.entry; + }; + }; + + + /** \brief + * This function compares two matrix entries by their values. It returns true, + * if the value of m2 is greater than the value of m1. + */ + struct CmpMatEntryAbsValueLess : public ::std::binary_function<MatEntry, MatEntry, bool> { + bool operator()(const MatEntry& m1, const MatEntry m2) const { + return fabs(m1.entry) < fabs(m2.entry); + }; + }; + + /** \brief + * This function compares two matrix entries by their values. It returns true, + * if the value of m1 is greater than the value of m2. + */ + struct CmpMatEntryAbsValueGreater : public ::std::binary_function<MatEntry, MatEntry, bool> { + bool operator()(const MatEntry& m1, const MatEntry m2) const { + return fabs(m1.entry) > fabs(m2.entry); + }; + }; + + // ============================================================================ + // ===== class DOFMatrix ====================================================== + // ============================================================================ + + /** \ingroup DOFAdministration + * \brief + * A DOFMatrix is a sparse matrix representation for matrices that work + * on DOFVectors. Every row of a matrix is realized as a vector of MatEntry + * objects. Each entry consists of a column DOF index and the corresponding + * double matrix entry. Unused entries are marked with a negative column index. + */ + class DOFMatrix : public DOFIndexed< ::std::vector<MatEntry> >, + public Serializable + { + public: + MEMORY_MANAGED(DOFMatrix); + + /** \ingroup DOFAdministration + * \brief + * Alias for DOFIterator< ::std::vector<MatEntry<T> > >. So one can access an + * iterator working on a DOFMatrix via DOFMatrix::Iterator + */ + class Iterator : public DOFIterator< ::std::vector<MatEntry> > { + public: + Iterator(DOFIndexed< ::std::vector<MatEntry> > *c, + DOFIteratorType type) + : DOFIterator< ::std::vector<MatEntry> >(c, type) + {}; + }; + + /** \brief + * A MatrixRow represents one row of the sparse matrix. It is realized by + * a STL vector of MatEntry<T> objects + */ + typedef ::std::vector<MatEntry> MatrixRow; + + /** \brief + * Symbolic constant for an unused matrix entry + */ + static const int UNUSED_ENTRY = -1; + + /** \brief + * Symbolic constant for an unused entry which is not followed by any + * used entry in this row + */ + static const int NO_MORE_ENTRIES = -2; + + public: + DOFMatrix(); + + /** \brief + * Constructs a DOFMatrix with name n and the given row and + * column FESpaces. + */ + DOFMatrix(const FiniteElemSpace* rowFESpace, + const FiniteElemSpace* colFESpace, + ::std::string n=""); + + /** \brief + * Copy-Constructor + */ + DOFMatrix(const DOFMatrix& rhs); + + + /** \brief + * Destructor + */ + virtual ~DOFMatrix(); + + /** \brief + * operator= + */ + DOFMatrix& operator=(const DOFMatrix& rhs); + + void copy(const DOFMatrix& rhs); + + /** \brief + * Returns an iterator to the begin of matrix rows (\ref matrix.begin()) + */ + ::std::vector< ::std::vector<MatEntry> >::iterator begin() { + return matrix.begin(); + }; + + /** \brief + * Returns an iterator to the end of matrix rows (\ref matrix.end()) + */ + ::std::vector< ::std::vector<MatEntry> >::iterator end() { + return matrix.end(); + }; + + /** \brief + * Used by DOFAdmin to compress the DOFMatrix + */ + virtual void compressDOFIndexed(int first, int last, + ::std::vector<DegreeOfFreedom> &newDOF); + + /** \brief + * Implements DOFIndexedBase::freeDOFContent() + */ + virtual void freeDOFContent(int index); + + /** \brief + * Returns whether entry matrix[a][b] is used + */ + inline bool entryUsed(DegreeOfFreedom a,int b) const { + return (((matrix[a])[b]).col >= 0); + }; + + /** \brief + * Returns true if matrix[a][b] has entry \ref NO_MORE_ENTRIES + */ + inline bool noMoreEntries(DegreeOfFreedom a,int b) const { + return (NO_MORE_ENTRIES==((matrix[a])[b]).col); + }; + + /** \brief + * Returns \ref coupleMatrix. + */ + inline bool isCoupleMatrix() { return coupleMatrix; }; + + /** \brief + * Returns \ref coupleMatrix. + */ + inline void setCoupleMatrix(bool c) { coupleMatrix = c; }; + + /** \brief + * Matrix-matrix multiplication. + */ + void mm(MatrixTranspose aTranspose, DOFMatrix& a, + MatrixTranspose bTranspose, DOFMatrix& b); + + /** \brief + * a*x + y + */ + void axpy(double a, + const DOFMatrix& x, + const DOFMatrix& y); + + /** \brief + * Multiplication with a scalar. + */ + void scal(double s); + + inline void addOperator(Operator *op, + double* factor = NULL, + double* estFactor = NULL) + { + operators.push_back(op); + operatorFactor.push_back(factor); + operatorEstFactor.push_back(estFactor); + }; + + inline ::std::vector<double*>::iterator getOperatorFactorBegin() { + return operatorFactor.begin(); + }; + + inline ::std::vector<double*>::iterator getOperatorFactorEnd() { + return operatorFactor.end(); + }; + + inline ::std::vector<double*>::iterator getOperatorEstFactorBegin() { + return operatorEstFactor.begin(); + }; + + inline ::std::vector<double*>::iterator getOperatorEstFactorEnd() { + return operatorEstFactor.end(); + }; + + inline ::std::vector<Operator*>::iterator getOperatorsBegin() { + return operators.begin(); + }; + + inline ::std::vector<Operator*>::iterator getOperatorsEnd() { + return operators.end(); + }; + + Flag getAssembleFlag(); + + /** \brief + * Updates the matrix matrix by traversing the underlying mesh and assembling + * the element contributions into the matrix. Information about the + * computation of element matrices and connection of local and global DOFs is + * stored in minfo; the flags for the mesh traversal are stored at + * minfo->fill_flags which specifies the elements to be visited and + * information that should be present on the elements for the calculation of + * the element matrices and boundary information (if minfo->boundBas is not + * NULL). On the elements, information about the row DOFs is accessed by + * minfo->rowBas using info->row_admin; this vector is also used for the + * column DOFs if minfo->nCol is less or equal zero, or minfo->col_admin or + * minfo->colBas is a NULL pointer; if row and column DOFs are the same, the + * boundary type of the DOFs is accessed by minfo->boundBas if + * minfo->boundBas is not a NULL pointer; then the element matrix is + * computed by minfo->fillElementMatrix(el info, minfo->myFill); these + * contributions, multiplied by minfo->factor, are eventually added to matrix + * by a call of addElementMatrix() with all information about row and column + * DOFs, the element matrix, and boundary types, if available; + * updateMatrix() only adds element contributions; this makes several calls + * for the assemblage of one matrix possible; before the first call, the + * matrix should be cleared by calling clear dof matrix(). + */ + + ElementMatrix *assemble(double factor, ElInfo *elInfo, + const BoundaryType *bound, Operator *op = NULL); + + /** \brief + * Adds an element matrix to \ref matrix + */ + void addElementMatrix(double sign, + const ElementMatrix& elMat, + const BoundaryType *bound, + bool add = true); + + /** \brief + * Returns \ref matrix + */ + ::std::vector< ::std::vector<MatEntry> >& getMatrix() { + return matrix; + }; + + void setMatrix(::std::vector< ::std::vector<MatEntry> > m) { + matrix = m; + }; + + /** \brief + * Returns \ref matrix[n] + */ + const ::std::vector<MatEntry>& getRow(int n) const { + return matrix[n]; + }; + + /** \brief + * Returns \ref matrix[n] + */ + ::std::vector<MatEntry>& getRow(int n) { + return matrix[n]; + }; + + /** \brief + * Returns whether interpolation should be performed after refinement + * (false by default) + */ + virtual bool refineInterpol() { + return false; + }; + + /** \brief + * Returns whether restriction should be performed after coarsening + * (false by default) + */ + virtual bool coarseRestrict() { + return false; + }; + + /** \brief + * Returns const \ref rowFESpace + */ + const FiniteElemSpace* getRowFESpace() const { + return rowFESpace; + }; + + /** \brief + * Returns const \ref colFESpace + */ + const FiniteElemSpace* getColFESpace() const { + return colFESpace; + }; + + /** \brief + * Returns const \ref rowFESpace + */ + const FiniteElemSpace* getFESpace() const { + return rowFESpace; + }; + + /** \brief + * Returns number of rows (\ref matrix.size()) + */ + inline int getSize() const { + return matrix.size(); + }; + + /** \brief + * Returns \ref name + */ + inline const ::std::string& getName() const { + return name; + }; + + /** \brief + * Resizes \ref matrix to n rows + */ + inline void resize(int n) { + TEST_EXIT(n >= 0)("Can't resize DOFMatrix to negative size\n"); + matrix.resize(n); + }; + + /** \brief + * Returns \ref matrix[i] which is the i-th row + */ + inline const ::std::vector<MatEntry>& operator[](int i) const { + TEST_EXIT((i >= 0) && (i < (static_cast<int>(matrix.size())))) + ("Illegal matrix index %d.\n",i); + return matrix[i]; + }; + + /** \brief + * Returns \ref matrix[i] which is the i-th row + */ + inline ::std::vector<MatEntry>& operator[](int i) { + TEST_EXIT((i >= 0) && (i < (static_cast<int>(matrix.size())))) + ("Illegal vector index %d.\n", i); + return matrix[i]; + }; + + /** \brief + * Access to \ref matrix[a][b].entry + */ + inline double physAcc(DegreeOfFreedom a,DegreeOfFreedom b) const { + return matrix[a][b].entry; + }; + + /** \brief + * Access to \ref matrix[a][b].col + */ + inline DegreeOfFreedom physToLogIndex(DegreeOfFreedom a, + DegreeOfFreedom b) const + { + return matrix[a][b].col; + }; + + /** \brief + * Returns physical column index of logical index b in row a + */ + DegreeOfFreedom logToPhysIndex(DegreeOfFreedom a,DegreeOfFreedom b) const; + + /** \brief + * Returns value at logical indices a,b + */ + double logAcc(DegreeOfFreedom a,DegreeOfFreedom b) const; + + /** \brief + * Changes col at logical indices a,b to c + */ + void changeColOfEntry(DegreeOfFreedom a,DegreeOfFreedom b,DegreeOfFreedom c); + + /** \brief + * Changes col of \ref matrix[a][b] to c + */ + inline void changePhysColOfEntry(DegreeOfFreedom a, + DegreeOfFreedom b, + DegreeOfFreedom c) + { + matrix[a][b].col = c; + }; + + /** \brief + * Creates an entry with logical indices irow, icol if there is no entry + * yet. Than sign * entry is added to the value at this logical indices + */ + double *addSparseDOFEntry(double sign, + int irow, int jcol, double entry, + bool add = true); + + inline double *hasSparseDOFEntry(int irow, int jcol) { + ::std::vector<MatEntry>::iterator it; + ::std::vector<MatEntry>::iterator end = matrix[irow].end(); + for (it = matrix[irow].begin(); it != end; ++it) { + if (it->col == NO_MORE_ENTRIES) + return NULL; + if (it->col == jcol) + return &(it->entry); + }; + return NULL; + }; + + void addMatEntry(int row, MatEntry entry); + + void addMatEntry(int row, int DegreeOfFreedom, double value); + + void addRow(::std::vector<MatEntry> row); + + /** \brief + * Prints \ref matrix to stdout + */ + void print() const; + + /** \brief + * Prints a row of \ref matrix to stdout + */ + void printRow(int i) const; + + /** \brief + * Removes all matrix entries + */ + void clear(); + + /** \brief + * Test whether \ref matrix is symmetric. Exits if not. + */ + void test(); + + bool symmetric(); + + inline ::std::vector<Operator*> getOperators() { + return operators; + }; + + inline ::std::vector<double*> getOperatorFactor() { + return operatorFactor; + }; + + inline ::std::vector<double*> getOperatorEstFactor() { + return operatorEstFactor; + }; + + inline BoundaryManager* getBoundaryManager() const { + return boundaryManager; + }; + + inline void setBoundaryManager(BoundaryManager *bm) { + boundaryManager = bm; + }; + + void createPictureFile(const char* filename, int dim); + + // ===== Serializable implementation ===== + + void serialize(::std::ostream &out) + { + unsigned int matrixSize = matrix.size(); + unsigned int vecSize = 0; + + out.write(reinterpret_cast<const char*>(&matrixSize), sizeof(unsigned int)); + for(unsigned int i = 0; i < matrixSize; i++) { + vecSize = matrix[i].size(); + out.write(reinterpret_cast<const char*>(&vecSize), sizeof(unsigned int)); + out.write(reinterpret_cast<const char*>(&(matrix[i][0])), vecSize * sizeof(MatEntry)); + } + }; + + void deserialize(::std::istream &in) { + unsigned int matrixSize, vecSize; + + in.read(reinterpret_cast<char*>(&matrixSize), sizeof(unsigned int)); + matrix.resize(matrixSize); + for(unsigned int i = 0; i < matrixSize; i++) { + in.read(reinterpret_cast<char*>(&vecSize), sizeof(unsigned int)); + matrix[i].resize(vecSize); + in.read(reinterpret_cast<char*>(&(matrix[i][0])), vecSize * sizeof(MatEntry)); + } + }; + + int memsize(); + + protected: + /** \brief + * Used by updateMatrix + */ + //static int assembleFct(ElInfo *el_info); + + protected: + /** \brief + * Pointer to a FiniteElemSpace with information about corresponding row DOFs + * and basis functions + */ + const FiniteElemSpace *rowFESpace; + + /** \brief + * Pointer to a FiniteElemSpace with information about corresponding + * column DOFs and basis functions + */ + const FiniteElemSpace *colFESpace; + + /** \brief + * Name of the DOFMatrix + */ + ::std::string name; + + /** \brief + * Sparse matrix stored in an STL vector of MatrixRow objects + */ + ::std::vector<MatrixRow> matrix; + + /** \brief + * Is used in the assembling process to store the assembled matrix of + * one element. + */ + ElementMatrix *elementMatrix; + + /** \brief + * Used while mesh traversal + */ + static DOFMatrix *traversePtr; + + /** \brief + * Pointers to all operators of the equation systems. Are used in the + * assembling process. + */ + ::std::vector<Operator*> operators; + + /** \brief + * Defines for each operator a factor which is used to scal the element + * matrix after the assembling process of the operator. + */ + ::std::vector<double*> operatorFactor; + + ::std::vector<double*> operatorEstFactor; + + BoundaryManager *boundaryManager; + + bool coupleMatrix; + + friend class DOFAdmin; + friend class DOFVector<double>; + friend class DOFVector<unsigned char>; + friend class DOFVector<int>; + friend class DOFVector<WorldVector<double> >; + }; + + + inline DegreeOfFreedom logToPhysIndex(DOFMatrix *m, DegreeOfFreedom a, DegreeOfFreedom b) + { + return m->logToPhysIndex(a, b); + } + + double norm(::std::vector<MatEntry> *row); + + double min(::std::vector<MatEntry> *row); + + double max(::std::vector<MatEntry> *row); + +} + +#endif // AMDIS_DOFMATRIX_H diff --git a/AMDiS/src/DOFVector.cc b/AMDiS/src/DOFVector.cc new file mode 100644 index 0000000000000000000000000000000000000000..90af161cbc4371ce79dd91f873ca169dc2c29b64 --- /dev/null +++ b/AMDiS/src/DOFVector.cc @@ -0,0 +1,766 @@ +#include "DOFVector.h" +#include "Traverse.h" +#include "DualTraverse.h" +#include "FixVec.h" + +namespace AMDiS { + + template<> + void DOFVector<double>::coarseRestrict(RCNeighbourList& list, int n) + { + switch(coarsenOperation) { + case NO_OPERATION: + return; + break; + case COARSE_RESTRICT: + (const_cast<BasisFunction*>(feSpace->getBasisFcts()))->coarseRestr(this, &list, n); + break; + case COARSE_INTERPOL: + (const_cast<BasisFunction*>(feSpace->getBasisFcts()))->coarseInter(this, &list, n); + break; + default: + ERROR_EXIT("invalid coarsen operation\n"); + } + } + + template<> + void DOFVector<double>::refineInterpol(RCNeighbourList& list, int n) + { + (const_cast<BasisFunction*>(feSpace->getBasisFcts()))->refineInter(this, &list, n); + } + + template<> + void DOFVector<WorldVector<double> >::refineInterpol(RCNeighbourList& list, int n) + { + if(n < 1) return; + int dim = feSpace->getMesh()->getDim(); + Element *el = list.getElement(0); + int n0 = feSpace->getAdmin()->getNumberOfPreDOFs(VERTEX); + DegreeOfFreedom dof0 = el->getDOF(0, n0); + DegreeOfFreedom dof1 = el->getDOF(1, n0); + DegreeOfFreedom dof_new = el->getChild(0)->getDOF(dim, n0); + vec[dof_new] = vec[dof0]; + vec[dof_new] += vec[dof1]; + vec[dof_new] *= 0.5; + } + + template<> + DOFVector<WorldVector<double> >* + DOFVector<double>::getGradient(DOFVector<WorldVector<double> > *grad) const + { + FUNCNAME("DOFVector<double>::getGradient()"); + + // define result vector + static DOFVector<WorldVector<double> > *result = NULL; + + if(grad) { + result = grad; + } else { + if(result && result->getFESpace() != feSpace) { + DELETE result; + result = NEW DOFVector<WorldVector<double> >(feSpace, "gradient"); + } + } + + int i, j; + + Mesh *mesh = feSpace->getMesh(); + + int dim = mesh->getDim(); + + const BasisFunction *basFcts = feSpace->getBasisFcts(); + int nBasFcts = basFcts->getNumber(); + + DOFAdmin *admin = feSpace->getAdmin(); + + // count number of nodes and dofs per node + ::std::vector<int> numNodeDOFs; + ::std::vector<int> numNodePreDOFs; + ::std::vector<DimVec<double>*> bary; + + int numNodes = 0; + int numDOFs = 0; + + for(i = 0; i < dim + 1; i++) { + GeoIndex geoIndex = INDEX_OF_DIM(i, dim); + int numPositionNodes = mesh->getGeo(geoIndex); + int numPreDOFs = admin->getNumberOfPreDOFs(i); + for(j = 0; j < numPositionNodes; j++) { + int dofs = basFcts->getNumberOfDOFs(geoIndex); + numNodeDOFs.push_back(dofs); + numDOFs += dofs; + numNodePreDOFs.push_back(numPreDOFs); + } + numNodes += numPositionNodes; + } + + TEST_EXIT(numNodes == mesh->getNumberOfNodes()) + ("invalid number of nodes\n"); + + TEST_EXIT(numDOFs == nBasFcts) + ("number of dofs != number of basis functions\n"); + + for(i = 0; i < numDOFs; i++) { + bary.push_back(basFcts->getCoords(i)); + } + + // traverse mesh + ::std::vector<bool> visited(getUsedSize(), false); + + TraverseStack stack; + + Flag fillFlag = Mesh::CALL_LEAF_EL | Mesh::FILL_GRD_LAMBDA; + + ElInfo *elInfo = stack.traverseFirst(mesh, -1, fillFlag); + + while(elInfo) { + + const DegreeOfFreedom **dof = elInfo->getElement()->getDOF(); + + const double *localUh = getLocalVector(elInfo->getElement(), NULL); + + const DimVec<WorldVector<double> > &grdLambda = elInfo->getGrdLambda(); + + int localDOFNr = 0; + for(i = 0; i < numNodes; i++) { // for all nodes + for(j = 0; j < numNodeDOFs[i]; j++) { // for all dofs at this node + DegreeOfFreedom dofIndex = dof[i][numNodePreDOFs[localDOFNr] + j]; + if(!visited[dofIndex]) { + + result[dofIndex] = basFcts->evalGrdUh(*(bary[localDOFNr]), + grdLambda, + localUh, + NULL); + + visited[dofIndex] = true; + } + localDOFNr++; + } + } + + elInfo = stack.traverseNext(elInfo); + } + + return result; + } + + template<> + DOFVector<WorldVector<double> >* + DOFVector<double>::getRecoveryGradient(DOFVector<WorldVector<double> > *grad) const + { + FUNCNAME("DOFVector<double>::getRecoveryGradient()"); + + // define result vector + static DOFVector<WorldVector<double> > *vec = NULL; + + DOFVector<WorldVector<double> > *result = grad; + + if(!result) { + if(vec && vec->getFESpace() != feSpace) { + DELETE vec; + vec = NULL; + } + if(!vec) { + vec = NEW DOFVector<WorldVector<double> >(feSpace, "gradient"); + } + result = vec; + } + + result->set(WorldVector<double>(DEFAULT_VALUE, 0.0)); + + DOFVector<double> volume(feSpace, "volume"); + volume.set(0.0); + + int i; + + Mesh *mesh = feSpace->getMesh(); + + int dim = mesh->getDim(); + + const BasisFunction *basFcts = feSpace->getBasisFcts(); + + DOFAdmin *admin = feSpace->getAdmin(); + + int numPreDOFs = admin->getNumberOfPreDOFs(0); + + DimVec<double> bary(dim, DEFAULT_VALUE, (1.0 / (dim + 1.0))); + + // traverse mesh + TraverseStack stack; + + Flag fillFlag = + Mesh::CALL_LEAF_EL | Mesh::FILL_DET | Mesh::FILL_GRD_LAMBDA | Mesh::FILL_COORDS; + + ElInfo *elInfo = stack.traverseFirst(mesh, -1, fillFlag); + + while(elInfo) { + double det = elInfo->getDet(); + const DegreeOfFreedom **dof = elInfo->getElement()->getDOF(); + const double *localUh = getLocalVector(elInfo->getElement(), NULL); + const DimVec<WorldVector<double> > &grdLambda = elInfo->getGrdLambda(); + const WorldVector<double> &grd = basFcts->evalGrdUh(bary, + grdLambda, + localUh, + NULL); + + for(i = 0; i < dim + 1; i++) { + DegreeOfFreedom dofIndex = dof[i][numPreDOFs]; + (*result)[dofIndex] += grd * det; + volume[dofIndex] += det; + } + + elInfo = stack.traverseNext(elInfo); + } + + DOFVector<double>::Iterator volIt(&volume, USED_DOFS); + DOFVector<WorldVector<double> >::Iterator grdIt(result, USED_DOFS); + + for(volIt.reset(), grdIt.reset(); !volIt.end(); ++volIt, ++grdIt) { + if(*volIt != 0.0) { + *grdIt *= 1.0/(*volIt); + } + } + + return result; + } + + template<> + const WorldVector<double> *DOFVectorBase<double>::getGrdAtQPs(const ElInfo *elInfo, + const Quadrature *quad, + const FastQuadrature *quadFast, + WorldVector<double> *grdAtQPs) const + { + FUNCNAME("DOFVector<double>::getGrdAtQPs()"); + + TEST_EXIT(quad || quadFast)("neither quad nor quadFast defined\n"); + + if(quad && quadFast) { + TEST_EXIT(quad == quadFast->getQuadrature()) + ("quad != quadFast->quadrature\n"); + } + + TEST_EXIT(!quadFast || quadFast->getBasisFunctions() == feSpace->getBasisFcts()) + ("invalid basis functions"); + + Element *el = elInfo->getElement(); + + int dim = elInfo->getMesh()->getDim(); + int dow = Global::getGeo(WORLD); + + const Quadrature *quadrature = quadFast ? quadFast->getQuadrature() : quad; + + const BasisFunction *basFcts = feSpace->getBasisFcts(); + + int numPoints = quadrature->getNumPoints(); + int nBasFcts = basFcts->getNumber(); + int i, j, k, l; + + static WorldVector<double> *grd = NULL; + + WorldVector<double> *result; + + if (grdAtQPs) { + result = grdAtQPs; + } else { + if(grd) delete [] grd; + grd = new WorldVector<double>[numPoints]; + for(i = 0; i < numPoints; i++) { + grd[i].set(0.0); + } + result = grd; + } + + const double *localVec = getLocalVector(el, NULL); + + DimVec<double> grd1(dim, NO_INIT); + int parts = Global::getGeo(PARTS, dim); + const DimVec<WorldVector<double> > &grdLambda = elInfo->getGrdLambda(); + + if(quadFast) { + for (i = 0; i < numPoints; i++) { + for(j = 0; j < dim + 1; j++) + grd1[j] = 0.0; + + for (j = 0; j < nBasFcts; j++) { + for (k = 0; k < parts; k++) { + grd1[k] += quadFast->getGradient(i, j, k) * localVec[j]; + } + } + + for(l=0; l < dow; l++) { + for (result[i][l] = k = 0; k < parts; k++) { + result[i][l] += grdLambda[k][l] * grd1[k]; + } + } + } + } else { + DimVec<double> grdPhi(dim, NO_INIT); + for (i = 0; i < numPoints; i++) { + for(j = 0; j < dim + 1; j++) + grd1[j] = 0.0; + for (j = 0; j < nBasFcts; j++) { + grdPhi = (*(basFcts->getGrdPhi(j)))(quad->getLambda(i)); + for(k = 0; k < parts; k++) { + grd1[k] += grdPhi[k] * localVec[j]; + } + } + + for(l=0; l < dow; l++) { + for (result[i][l] = k = 0; k < parts; k++) { + result[i][l] += grdLambda[k][l] * grd1[k]; + } + } + } + } + + + return const_cast<const WorldVector<double>*>(result); + } + + template<> + const WorldMatrix<double> *DOFVectorBase<double>::getD2AtQPs(const ElInfo *elInfo, + const Quadrature *quad, + const FastQuadrature *quadFast, + WorldMatrix<double> *d2AtQPs) const + { + FUNCNAME("DOFVector<double>::getD2AtQPs()"); + + TEST_EXIT(quad || quadFast)("neither quad nor quadFast defined\n"); + + if(quad && quadFast) { + TEST_EXIT(quad == quadFast->getQuadrature()) + ("quad != quadFast->quadrature\n"); + } + + TEST_EXIT(!quadFast || quadFast->getBasisFunctions() == feSpace->getBasisFcts()) + ("invalid basis functions"); + + Element *el = elInfo->getElement(); + + int dim = elInfo->getMesh()->getDim(); + int dow = Global::getGeo(WORLD); + + const Quadrature *quadrature = quadFast ? quadFast->getQuadrature() : quad; + + const BasisFunction *basFcts = feSpace->getBasisFcts(); + + int numPoints = quadrature->getNumPoints(); + int nBasFcts = basFcts->getNumber(); + int i, j, k, l, iq; + + static WorldMatrix<double> *vec = NULL; + + WorldMatrix<double> *result; + + if (d2AtQPs) { + result = d2AtQPs; + } else { + if(vec) delete [] vec; + vec = new WorldMatrix<double>[numPoints]; + for(i = 0; i < numPoints; i++) { + vec[i].set(0.0); + } + result = vec; + } + + const double *localVec = getLocalVector(el, NULL); + + DimMat<double> D2Tmp(dim, DEFAULT_VALUE, 0.0); + int parts = Global::getGeo(PARTS, dim); + const DimVec<WorldVector<double> > &grdLambda = elInfo->getGrdLambda(); + + if(quadFast) { + for (iq = 0; iq < numPoints; iq++) { + for (k = 0; k < parts; k++) + for (l = 0; l < parts; l++) + D2Tmp[k][l] = 0.0; + + for (i = 0; i < nBasFcts; i++) { + for (k = 0; k < parts; k++) + for (l = 0; l < parts; l++) + D2Tmp[k][l] += localVec[i]* quadFast->getSecDer(iq, i, k, l); + } + + for (i = 0; i < dow; i++) + for (j = 0; j < dow; j++) { + result[iq][i][j] = 0.0; + for (k = 0; k < parts; k++) + for (l = 0; l < parts; l++) + result[iq][i][j] += grdLambda[k][i]*grdLambda[l][j]*D2Tmp[k][l]; + } + } + } else { + DimMat<double> D2Phi(dim, NO_INIT); + for (iq = 0; iq < numPoints; iq++) { + for (k = 0; k < parts; k++) + for (l = 0; l < parts; l++) + D2Tmp[k][l] = 0.0; + + for (i = 0; i < nBasFcts; i++) { + WARNING("not tested after index correction\n"); + //D2Phi = (*(basFcts->getD2Phi(j)))(quad->getLambda(i)); + D2Phi = (*(basFcts->getD2Phi(i)))(quad->getLambda(iq)); + for (k = 0; k < parts; k++) + for (l = 0; l < parts; l++) + D2Tmp[k][l] += localVec[i] * D2Phi[k][l]; + } + + for (i = 0; i < dow; i++) + for (j = 0; j < dow; j++) { + result[iq][i][j] = 0.0; + for (k = 0; k < parts; k++) + for (l = 0; l < parts; l++) + result[iq][i][j] += grdLambda[k][i]*grdLambda[l][j]*D2Tmp[k][l]; + } + } + } + + + return const_cast<const WorldMatrix<double>*>(result); + } + + template<> + void DOFVector<double>::interpol(DOFVector<double> *source, double factor) + { + FUNCNAME("DOFVector<double>::interpol"); + + int i, j; + const FiniteElemSpace *sourceFeSpace = source->getFESpace(); + + const BasisFunction *basisFcts = feSpace->getBasisFcts(); + const BasisFunction *sourceBasisFcts = sourceFeSpace->getBasisFcts(); + + int nBasisFcts = basisFcts->getNumber(); + int nSourceBasisFcts = sourceBasisFcts->getNumber(); + + this->set(0.0); + + DegreeOfFreedom *localIndices = GET_MEMORY(DegreeOfFreedom, nBasisFcts); + double *sourceLocalCoeffs = GET_MEMORY(double, nSourceBasisFcts); + + if(feSpace->getMesh() == sourceFeSpace->getMesh()) { + DimVec<double> *coords = NULL; + TraverseStack stack; + ElInfo *elInfo = stack.traverseFirst(feSpace->getMesh(), -1, + Mesh::CALL_LEAF_EL | + Mesh::FILL_COORDS); + + while(elInfo) { + Element *el = elInfo->getElement(); + + basisFcts->getLocalIndices(el, feSpace->getAdmin(), localIndices); + + source->getLocalVector(el, sourceLocalCoeffs); + + for(i = 0; i < nBasisFcts; i++) { + if(vec[localIndices[i]] == 0.0) { + coords = basisFcts->getCoords(i); + vec[localIndices[i]] = sourceBasisFcts->evalUh(*coords, sourceLocalCoeffs) * factor; + } + } + elInfo = stack.traverseNext(elInfo); + } + } else { + DimVec<double> *coords1 = NULL; + DimVec<double> coords2(feSpace->getMesh()->getDim(), NO_INIT); + DualTraverse dualStack; + ElInfo *elInfo1, *elInfo2; + ElInfo *elInfoSmall, *elInfoLarge; + WorldVector<double> worldVec; + + bool nextTraverse = dualStack.traverseFirst(feSpace->getMesh(), + sourceFeSpace->getMesh(), + -1, -1, + Mesh::CALL_LEAF_EL | Mesh::FILL_COORDS, + Mesh::CALL_LEAF_EL | Mesh::FILL_COORDS, + &elInfo1, &elInfo2, + &elInfoSmall, &elInfoLarge); + while(nextTraverse) { + basisFcts->getLocalIndices(elInfo1->getElement(), + feSpace->getAdmin(), + localIndices); + source->getLocalVector(elInfo2->getElement(), + sourceLocalCoeffs); + + for(i = 0; i < nBasisFcts; i++) { + if(vec[localIndices[i]] == 0.0) { + coords1 = basisFcts->getCoords(i); + elInfo1->coordToWorld(*coords1, &worldVec); + elInfo2->worldToCoord(worldVec, &coords2); + + bool isPositive = true; + for(j = 0; j < coords2.size(); j++) { + if (coords2[j] < 0) { + isPositive = false; + break; + } + } + + if(isPositive) { + vec[localIndices[i]] = sourceBasisFcts->evalUh(coords2, sourceLocalCoeffs); + } + } + } + + nextTraverse = dualStack.traverseNext(&elInfo1, &elInfo2, + &elInfoSmall, &elInfoLarge); + } + } + + FREE_MEMORY(localIndices, DegreeOfFreedom, nBasisFcts); + FREE_MEMORY(sourceLocalCoeffs, double, nSourceBasisFcts); + } + + template<> + WorldVector<DOFVector<double>*> *DOFVector<double>::getGradient(WorldVector<DOFVector<double>*> *grad) const + { + FUNCNAME("DOFVector<double>::getGradient()"); + + int i, j, k; + + Mesh *mesh = feSpace->getMesh(); + + int dim = mesh->getDim(); + int dow = Global::getGeo(WORLD); + + const BasisFunction *basFcts = feSpace->getBasisFcts(); + int nBasFcts = basFcts->getNumber(); + + DOFAdmin *admin = feSpace->getAdmin(); + + // define result vector + static WorldVector<DOFVector<double>*> *result = NULL; + + if(grad) { + result = grad; + } else { + if(!result) { + result = NEW WorldVector<DOFVector<double>*>; + result->set(NULL); + } + for(i = 0; i < dow; i++) { + if((*result)[i] && (*result)[i]->getFESpace() != feSpace) { + DELETE (*result)[i]; + (*result)[i] = NEW DOFVector<double>(feSpace, "gradient"); + } + } + } + + // count number of nodes and dofs per node + ::std::vector<int> numNodeDOFs; + ::std::vector<int> numNodePreDOFs; + ::std::vector<DimVec<double>*> bary; + + int numNodes = 0; + int numDOFs = 0; + + for(i = 0; i < dim + 1; i++) { + GeoIndex geoIndex = INDEX_OF_DIM(i, dim); + int numPositionNodes = mesh->getGeo(geoIndex); + int numPreDOFs = admin->getNumberOfPreDOFs(i); + for(j = 0; j < numPositionNodes; j++) { + int dofs = basFcts->getNumberOfDOFs(geoIndex); + numNodeDOFs.push_back(dofs); + numDOFs += dofs; + numNodePreDOFs.push_back(numPreDOFs); + } + numNodes += numPositionNodes; + } + + TEST_EXIT(numNodes == mesh->getNumberOfNodes()) + ("invalid number of nodes\n"); + + TEST_EXIT(numDOFs == nBasFcts) + ("number of dofs != number of basis functions\n"); + + for(i = 0; i < numDOFs; i++) { + bary.push_back(basFcts->getCoords(i)); + } + + // traverse mesh + ::std::vector<bool> visited(getUsedSize(), false); + + TraverseStack stack; + + Flag fillFlag = Mesh::CALL_LEAF_EL | Mesh::FILL_GRD_LAMBDA; + + ElInfo *elInfo = stack.traverseFirst(mesh, -1, fillFlag); + + WorldVector<double> grd; + + while(elInfo) { + + const DegreeOfFreedom **dof = elInfo->getElement()->getDOF(); + + const double *localUh = getLocalVector(elInfo->getElement(), NULL); + + const DimVec<WorldVector<double> > &grdLambda = elInfo->getGrdLambda(); + + int localDOFNr = 0; + for(i = 0; i < numNodes; i++) { // for all nodes + for(j = 0; j < numNodeDOFs[i]; j++) { // for all dofs at this node + DegreeOfFreedom dofIndex = dof[i][numNodePreDOFs[localDOFNr] + j]; + if(!visited[dofIndex]) { + + grd = basFcts->evalGrdUh(*(bary[localDOFNr]), + grdLambda, + localUh, + NULL); + + for(k = 0; k < dow; k++) { + (*result)[k][dofIndex] = grd[k]; + } + + visited[dofIndex] = true; + } + localDOFNr++; + } + } + + elInfo = stack.traverseNext(elInfo); + } + + return result; + } + + // template<> + // void interpolGrd(DOFVector<double> *v, + // WorldVector<DOFVector<double>*> *grad, + // double factor, bool add) + // { + // int i, j, k; + // int dow = Global::getGeo(WORLD); + + // TEST_EXIT(grad)("no gradient\n"); + // for(i = 0; i < dow; i++) { + // TEST_EXIT((*grad)[i])("missing (*grad)[%d]\n", i); + // } + + // if(!add) { + // for(i = 0; i < dow; i++) { + // (*grad)[i]->set(0.0); + // } + // } + + // DimVec<double> *coords = NULL; + + // const FiniteElemSpace *feSpace = (*grad)[0]->getFESpace(); + + // const FiniteElemSpace *vFESpace = v->getFESpace(); + + // if(feSpace == vFESpace) { + // WARNING("same FE-spaces\n"); + // } + + // const BasisFunction *basFcts = feSpace->getBasisFcts(); + // const BasisFunction *vBasFcts = vFESpace->getBasisFcts(); + + // int numBasFcts = basFcts->getNumber(); + // int vNumBasFcts = vBasFcts->getNumber(); + + // if(feSpace->getMesh() == vFESpace->getMesh()) { + // DegreeOfFreedom *localIndices = GET_MEMORY(DegreeOfFreedom, numBasFcts); + // double *vLocalCoeffs = GET_MEMORY(double, vNumBasFcts); + + // Mesh *mesh = feSpace->getMesh(); + // TraverseStack stack; + // ElInfo *elInfo = stack.traverseFirst(mesh, -1, + // Mesh::CALL_LEAF_EL | + // Mesh::FILL_COORDS | + // Mesh::FILL_GRD_LAMBDA); + + // while(elInfo) { + // const DimVec<WorldVector<double> > &grdLambda = elInfo->getGrdLambda(); + + // Element *el = elInfo->getElement(); + + // basFcts->getLocalIndices(el, feSpace->getAdmin(), localIndices); + + // v->getLocalVector(el, vLocalCoeffs); + + // for(i = 0; i < numBasFcts; i++) { + // coords = basFcts->getCoords(i); + // for(j = 0; j < vNumBasFcts; j++) { + // WorldVector<double> g; + // vBasFcts->evalGrdUh(*coords, grdLambda, vLocalCoeffs, &g); + + // for(k = 0; k < dow; k++) { + // (*((*grad)[k]))[localIndices[i]] += g[k] * factor; + // } + // } + // } + // elInfo = stack.traverseNext(elInfo); + // } + + // FREE_MEMORY(localIndices, DegreeOfFreedom, numBasFcts); + // FREE_MEMORY(vLocalCoeffs, double, vNumBasFcts); + // } else { + // ERROR_EXIT("not yet for dual traverse\n"); + // } + // } + + + DOFVectorDOF::DOFVectorDOF() : DOFVector<DegreeOfFreedom>() {}; + + void DOFVectorDOF::freeDOFContent(DegreeOfFreedom dof) { + ::std::vector<DegreeOfFreedom>::iterator it; + ::std::vector<DegreeOfFreedom>::iterator end = vec.end(); + DegreeOfFreedom pos; + for(it = vec.begin(), pos = 0; it != end; ++it, ++pos) { + if(*it == dof) *it = pos; + } + }; + + WorldVector<DOFVector<double>*> *transform(DOFVector<WorldVector<double> > *vec, + WorldVector<DOFVector<double>*> *res) + { + FUNCNAME("transform()"); + + TEST_EXIT(vec)("no vector\n"); + + int i, j, dow = Global::getGeo(WORLD); + + static WorldVector<DOFVector<double>*> *result = NULL; + + if(!res && !result) { + result = NEW WorldVector<DOFVector<double>*>; + for(i = 0; i < dow; i++) { + (*result)[i] = NEW DOFVector<double>(vec->getFESpace(), "transform"); + } + } + + WorldVector<DOFVector<double>*> *r = res ? res : result; + + int vecSize = vec->getSize(); + for(i = 0; i < vecSize; i++) { + for(j = 0; j < dow; j++) { + (*((*r)[j]))[i] = (*vec)[i][j]; + } + } + + return r; + } + +#if 0 + void transform2(DOFVector<WorldVector<double> > *vec, + ::std::vector<DOFVector<double>*> *res) + { + FUNCNAME("transform2()"); + + TEST_EXIT(vec && res)("no vector\n"); + + int i, j, dow = Global::getGeo(WORLD); + + int vecSize = vec->getSize(); + for(i = 0; i < vecSize; i++) { + for(j = 0; j < dow; j++) { + (*((*res)[j]))[i] = (*vec)[i][j]; + } + } + + return r; + } +#endif + +} + diff --git a/AMDiS/src/DOFVector.h b/AMDiS/src/DOFVector.h new file mode 100644 index 0000000000000000000000000000000000000000..fe044c5fb00b1d42d7f101113b167ff6a4bfb301 --- /dev/null +++ b/AMDiS/src/DOFVector.h @@ -0,0 +1,1022 @@ +// ============================================================================ +// == == +// == AMDiS - Adaptive multidimensional simulations == +// == == +// ============================================================================ +// == == +// == crystal growth group == +// == == +// == Stiftung caesar == +// == Ludwig-Erhard-Allee 2 == +// == 53175 Bonn == +// == germany == +// == == +// ============================================================================ +// == == +// == http://www.caesar.de/cg/AMDiS == +// == == +// ============================================================================ + +/** \file DOFVector.h */ + +#ifndef AMDIS_DOFVECTOR_H +#define AMDIS_DOFVECTOR_H + +// =========================================================================== +// ===== includes ============================================================ +// =========================================================================== + +#include "FixVec.h" +#include "Global.h" +#include "Flag.h" +#include "RCNeighbourList.h" +#include "DOFIterator.h" +#include "DOFIndexed.h" +#include "DOFContainer.h" +#include "MemoryManager.h" +#include "Boundary.h" +#include "CreatorInterface.h" +#include "Serializable.h" +#include "DOFMatrix.h" +#include <vector> +#include <memory> +#include <list> + +namespace AMDiS { + + // =========================================================================== + // ===== forward declarations ================================================ + // =========================================================================== + + class Mesh; + class FiniteElemSpace; + class ElInfo; + class DOFAdmin; + class BasisFunction; + class FillInfo; + class Quadrature; + class FastQuadrature; + class DOFMatrix; + class MultiGridSortSolver; + class Operator; + class ElementVector; + class BoundaryManager; + + template<typename ReturnType, typename ArgumentType> class AbstractFunction; + + + template<typename T> + class DOFVectorBase : public DOFIndexed<T> + { + public: + DOFVectorBase() + : feSpace(NULL), + elementVector(NULL), + boundaryManager(NULL) + {}; + + DOFVectorBase(const FiniteElemSpace *f, ::std::string n) + : feSpace(f), + name(n), + elementVector(NULL), + boundaryManager(NULL) + {}; + + virtual const T *getLocalVector(const Element *el, T* localVec) const; + + const T *getVecAtQPs(const ElInfo *elInfo, + const Quadrature *quad, + const FastQuadrature *quadFast, + T *vecAtQPs) const; + + const WorldVector<T> *getGrdAtQPs(const ElInfo *elInfo, + const Quadrature *quad, + const FastQuadrature *quadFast, + WorldVector<T> *grdAtQPs) const; + + const WorldMatrix<T> *getD2AtQPs(const ElInfo *elInfo, + const Quadrature *quad, + const FastQuadrature *quadFast, + WorldMatrix<T> *d2AtQPs) const; + + virtual const FiniteElemSpace* getFESpace() const { + return feSpace; + }; + + ElementVector *assemble(T factor, ElInfo *elInfo, + const BoundaryType *bound, + Operator *op = NULL); + + void addElementVector(T sign, + const ElementVector &elVec, + const BoundaryType *bound, + bool add = true); + + inline void addOperator(Operator* op, + double *factor = NULL, + double *estFactor = NULL) + { + operators.push_back(op); + operatorFactor.push_back(factor); + operatorEstFactor.push_back(estFactor); + }; + + inline ::std::vector<double*>::iterator getOperatorFactorBegin() { + return operatorFactor.begin(); + }; + + inline ::std::vector<double*>::iterator getOperatorFactorEnd() { + return operatorFactor.end(); + }; + + inline ::std::vector<double*>::iterator getOperatorEstFactorBegin() { + return operatorEstFactor.begin(); + }; + + inline ::std::vector<double*>::iterator getOperatorEstFactorEnd() { + return operatorEstFactor.end(); + }; + + + inline ::std::vector<Operator*>::iterator getOperatorsBegin() { + return operators.begin(); + }; + + inline ::std::vector<Operator*>::iterator getOperatorsEnd() { + return operators.end(); + }; + + Flag getAssembleFlag(); + + /** \brief + * Evaluates \f[ u_h(x(\lambda)) = \sum_{i=0}^{m-1} vec[ind[i]] * + * \varphi^i(\lambda) \f] where \f$ \varphi^i \f$ is the i-th basis function, + * \f$ x(\lambda) \f$ are the world coordinates of lambda and + * \f$ m \f$ is the number of basis functions + */ + T evalUh(const DimVec<double>& lambda, DegreeOfFreedom* ind); + + inline ::std::vector<Operator*>& getOperators() { return operators; }; + + inline ::std::vector<double*>& getOperatorFactor() { return operatorFactor; }; + inline ::std::vector<double*>& getOperatorEstFactor() { + return operatorEstFactor; + }; + + /** \brief + * Returns \ref name + */ + inline const ::std::string& getName() const { return name; }; + + inline BoundaryManager* getBoundaryManager() const { return boundaryManager; }; + + inline void setBoundaryManager(BoundaryManager *bm) { + boundaryManager = bm; + }; + + protected: + const FiniteElemSpace *feSpace; + + ::std::string name; + + ElementVector *elementVector; + + ::std::vector<Operator*> operators; + + ::std::vector<double*> operatorFactor; + + ::std::vector<double*> operatorEstFactor; + + BoundaryManager *boundaryManager; + }; + + + // template<typename T> + // class QPEvaluatable : public DOFVectorBase<T> + // { + // public: + // QPEvaluatable() + // : DOFVectorBase<T>() + // {}; + + // QPEvaluatable(const FiniteElemSpace *f, ::std::string n) + // : DOFVectorBase<T>(f, n) + // {}; + + // protected: + // }; + + // =========================================================================== + // ===== defs ================================================================ + // =========================================================================== + + /** \brief + * Specifies which operation should be done after coarsening + */ + typedef enum{ + NO_OPERATION = 0, + COARSE_RESTRICT = 1, + COARSE_INTERPOL = 2 + } CoarsenOperation; + + // =========================================================================== + // ===== class DOFVector ===================================================== + // =========================================================================== + + /** \ingroup DOFAdministration + * \brief + * The DOFs described above are just integers that can be used as indices into + * vectors and matrices. During refinement and coarsening of the mesh, the + * number of used DOFs, the meaning of one integer index, and even the total + * range of DOFs change. To be able to handle these changes automatically for + * all vectors, which are indexed by the DOFs, special data structures are + * used which contain such vector data. Lists of these structures are kept in + * DOFAdmin, so that all vectors in the lists can be resized together with the + * range of DOFs. During refinement and coarsening of elements, values can be + * interpolated automatically to new DOFs, and restricted from old DOFs. + */ + template<typename T> + class DOFVector : public DOFVectorBase<T>, public Serializable + { + public: + MEMORY_MANAGED(DOFVector<T>); + + /** \ingroup DOFAdministration + * \brief + * Enables the access of DOFVector<T>::Iterator. Alias for DOFIterator<T> + */ + class Iterator : public DOFIterator<T> { + public: + Iterator(DOFIndexed<T> *c, DOFIteratorType type) + : DOFIterator<T>(c, type) + {}; + + Iterator(DOFAdmin *admin, DOFIndexed<T> *c, DOFIteratorType type) + : DOFIterator<T>(admin, c, type) + {}; + }; + + class Creator : public CreatorInterface<DOFVector<T> > { + public: + MEMORY_MANAGED(Creator); + + Creator(FiniteElemSpace *feSpace_) : feSpace(feSpace_) {}; + + DOFVector<T> *create() { + return NEW DOFVector<T>(feSpace, ""); + }; + + void free(DOFVector<T> *vec) { + DELETE vec; + }; + + private: + FiniteElemSpace *feSpace; + }; + + public: + /** \brief + * Empty constructor. No initialization! + */ + DOFVector() + : DOFVectorBase<T>(), + //elementVector(NULL), + refineInter(false), + feSpace(NULL), + coarsenOperation(NO_OPERATION) + {}; + + /** \brief + * Constructs a DOFVector with name n belonging to FiniteElemSpace f + */ + DOFVector(const FiniteElemSpace* f,::std::string n); + + /** \brief + * Initialization. + */ + void init(const FiniteElemSpace* f, ::std::string n); + + /** \brief + * Copy Constructor + */ + DOFVector(const DOFVector& rhs) { + *this=rhs; + name=rhs.name+"copy"; + if(feSpace && feSpace->getAdmin()) { + (dynamic_cast<DOFAdmin*>(feSpace->getAdmin()))->addDOFIndexed(this); + } + }; + + /** \brief + * Destructor + */ + virtual ~DOFVector(); + + /** \brief + * Returns iterator to the begin of \ref vec + */ + typename ::std::vector<T>::iterator begin() { return vec.begin(); }; + + /** \brief + * Returns iterator to the end of \ref vec + */ + typename ::std::vector<T>::iterator end() { return vec.end(); }; + + /** \brief + * Used by DOFAdmin to compress this DOFVector. Implementation of + * DOFIndexedBase::compress() + */ + virtual void compressDOFIndexed(int first, int last, + ::std::vector<DegreeOfFreedom> &newDof); + + /** \brief + * Sets \ref refineInter to b + */ + inline void refineInterpol(bool b) { refineInter = b; }; + + /** \brief + * Sets \ref coarsenOperation to op + */ + inline void setCoarsenOperation(CoarsenOperation op) { + coarsenOperation = op; + }; + + /** \brief + * Returns \ref coarsenOperation + */ + inline CoarsenOperation getCoarsenOperation() { return coarsenOperation; }; + + /** \brief + * Restriction after coarsening. Implemented for DOFVector<double> + */ + inline void coarseRestrict(RCNeighbourList&, int) {}; + + /** \brief + * Returns \ref refineInter + */ + inline bool refineInterpol() { return refineInter; }; + + /** \brief + * Interpolation after refinement. + */ + inline void refineInterpol(RCNeighbourList&, int) {}; + + /** \brief + * Returns \ref vec + */ + // ::std::vector<T>& getVector() const {return (::std::vector<T>&) vec;} ; + ::std::vector<T>& getVector() { return vec;} ; + + // /** \brief + // * Returns \ref feSpace + // */ + // inline const FiniteElemSpace* getFESpace() const { return feSpace; }; + + /** \brief + * Returns size of \ref vec + */ + inline int getSize() const { return vec.size();}; + + /** \brief + * Returns used size of the vector. + */ + inline int getUsedSize() const { return feSpace->getAdmin()->getUsedSize(); }; + + /** \brief + * Resizes \ref vec to n + */ + inline void resize(int n) { + FUNCNAME("DOFVector<T>::resize"); + TEST_EXIT((n>=0))("Can't resize DOFVector to negative size\n"); + vec.resize(n); + }; + + /** \brief + * Resizes \ref vec to n and inits new values with init + */ + inline void resize(int n, T init) { + FUNCNAME("DOFVector<T>::resize"); + TEST_EXIT((n>=0))("Can't resize DOFVector to negative size\n"); + vec.resize(n, init); + }; + + /** \brief + * Returns \ref vec[i] + */ + inline const T& operator[](DegreeOfFreedom i) const { + FUNCNAME("DOFVector<T>::operator[]"); + TEST_EXIT((i>=0)&&(i<static_cast<int>(vec.size())))("Illegal vector index %d.\n",i); + return vec[i]; + }; + + inline int getSize() { return vec.size(); }; + + /** \brief + * Returns \ref vec[i] + */ + inline T& operator[](DegreeOfFreedom i) { + FUNCNAME("DOFVector<T>::operator[]"); + TEST_EXIT((i>=0)&&(i<static_cast<int>(vec.size())))("Illegal vector index %d.\n",i); + return vec[i]; + }; + + // Andreas Ergaenzungen: + + /** \brief + * Calculates Integral of this DOFVector + */ + double Int(Quadrature* q = NULL) const; + + /** \brief + * Calculates L1 norm of this DOFVector + */ + double L1Norm(Quadrature* q = NULL) const; + + // Ende Andreas Ergaenzungen (hier) unten geht es weiter + + + /** \brief + * Calculates L2 norm of this DOFVector + */ + inline double L2Norm(Quadrature* q = NULL) const { + return sqrt(L2NormSquare()); + }; + + /** \brief + * Calculates square of L2 norm of this DOFVector + */ + double L2NormSquare(Quadrature* q = NULL) const; + + /** \brief + * Calculates H1 norm of this DOFVector + */ + inline double H1Norm(Quadrature* q = NULL) const { + return sqrt(H1NormSquare()); + }; + + /** \brief + * Calculates square of H1 norm of this DOFVector + */ + double H1NormSquare(Quadrature* q = NULL) const; + + /** \brief + * Calculates euclidian norm of this DOFVector + */ + double nrm2() const; + + /** \brief + * Returns square of the euclidian norm. + */ + double squareNrm2() const; + + /** \brief + * Calculates l2 norm of this DOFVector + */ + inline double l2norm() const { + return nrm2(); + }; + + /** \brief + * Calculates the absolute sum of this DOFVector + */ + T asum() const; + + /** \brief + * Calculates the l1 norm of this DOFVector + */ + inline double l1norm() const { + return asum(); + }; + + // hier Andreas Ergaenzung + + /** \brief + * Calculates the sum of this DOFVector + */ + T sum() const; + + // bis hier Andreas E. + + /** \brief + * Sets \ref vec[i] = val, i=0 , ... , size + */ + void set(T val); + + /** \brief + * Assignment operator for setting complete vector to a certain value d + */ + inline DOFVector<T>& operator=(T d) { + set(d); + return *this; + }; + + /** \brief + * Assignment operator between two vectors + */ + DOFVector<T>& operator=(const DOFVector<T>& ); + + + //virtual DOFVector<T>& operator-=(const DOFVector<T>& rhs) { + // axpy(-1.0, rhs); return *this; + //}; + + //virtual DOFVector<T>& operator+=(const DOFVector<T>& rhs) { + // axpy(1.0, rhs); return *this; + //}; + + /** \brief + * Multiplies all entries of \ref vec with s + */ + //virtual void scal(T s); + + /** \brief + * Multiplication with a scalar + */ + //virtual const DOFVector<T>& operator*(T d) const { + // static DOFVector<T> vec(this->feSpace, "operator*-vector"); + // vec = *this; + // vec.scal(d); + // return vec; + //}; + + /** \brief + * \ref vec[i] = d * \ref vec[i] + */ + //virtual const DOFVector<T>& operator*=(T d) { + // scal(d); + // return (*this); + //}; + + /** \brief + * vec[i] = v.vec[i] + */ + void copy(const DOFVector<T>& v); + + /** \brief + * vec[i] = a * x.vec[i] + vec[i] + */ + //void axpy(T a,const DOFVector<T>& x); + + /** \brief + * vec[i] = a * x.vec[i] + y.vec[i] + */ + //void axpy(T a,const DOFVector<T>& x, const DOFVector<T>& y); + + /** \brief + * vec[i] = x.vec[i] + a * vec[i] + */ + //void xpay(T a,const DOFVector<T>& x); + + /** \brief + * Returns minimum of DOFVector + */ + T min() const; + + /** \brief + * Returns maximum of DOFVector + */ + T max() const; + + /** \brief + * Used by interpol while mesh traversal + */ + static int interpolFct(ElInfo* elinfo); + + /** \brief + * Generalized matrix-vector multiplication + */ + //virtual void gemv(MatrixTranspose transpose, T alpha, + // const DOFMatrix &a, const DOFVector<T>& x, + // T beta); + + /** \brief + * Matrix-vector multiplication + */ + //virtual void mv(MatrixTranspose transpose, + // const DOFMatrix&a, const DOFVector<T>&x); + + /** \brief + * Prints \ref vec to stdout + */ + void print() const; + + // ElementVector *assemble(T factor, ElInfo *elInfo, + // const BoundaryType *bound, + // Operator *op = NULL); + + // /** \brief + // * Adds element contribution to the vector + // */ + // void addElementVector(T sign, + // const ElementVector &elVec, + // const BoundaryType *bound, + // bool add = true); + + + + // inline void addOperator(Operator* op, + // double *factor = NULL, + // double *estFactor = NULL) + // { + // operators.push_back(op); + // operatorFactor.push_back(factor); + // operatorEstFactor.push_back(estFactor); + // }; + + // inline ::std::vector<double*>::iterator getOperatorFactorBegin() { + // return operatorFactor.begin(); + // }; + + // inline ::std::vector<double*>::iterator getOperatorFactorEnd() { + // return operatorFactor.end(); + // }; + + // inline ::std::vector<double*>::iterator getOperatorEstFactorBegin() { + // return operatorEstFactor.begin(); + // }; + + // inline ::std::vector<double*>::iterator getOperatorEstFactorEnd() { + // return operatorEstFactor.end(); + // }; + + + // inline ::std::vector<Operator*>::iterator getOperatorsBegin() { + // return operators.begin(); + // }; + + // inline ::std::vector<Operator*>::iterator getOperatorsEnd() { + // return operators.end(); + // }; + + // Flag getAssembleFlag(); + + // /** \brief + // * Evaluates \f[ u_h(x(\lambda)) = \sum_{i=0}^{m-1} vec[ind[i]] * + // * \varphi^i(\lambda) \f] where \f$ \varphi^i \f$ is the i-th basis function, + // * \f$ x(\lambda) \f$ are the world coordinates of lambda and + // * \f$ m \f$ is the number of basis functions + // */ + // T evalUh(const DimVec<double>& lambda, DegreeOfFreedom* ind); + + /** \brief + * Computes the coefficients of the interpolant of the function fct and + * stores these in the DOFVector + */ + void interpol(AbstractFunction<T, WorldVector<double> > *fct); + + void interpol(DOFVector<T> *v, double factor); + + // inline ::std::vector<Operator*>& getOperators() { return operators; }; + + // inline ::std::vector<double*>& getOperatorFactor() { return operatorFactor; }; + // inline ::std::vector<double*>& getOperatorEstFactor() { + // return operatorEstFactor; + // }; + + + // ===== Serializable implementation ===== + + void serialize(::std::ostream &out) + { + unsigned int size = vec.size(); + out.write(reinterpret_cast<const char*>(&size), sizeof(unsigned int)); + out.write(reinterpret_cast<const char*>(&(vec[0])), size * sizeof(T)); + }; + + void deserialize(::std::istream &in) { + unsigned int size; + in.read(reinterpret_cast<char*>(&size), sizeof(unsigned int)); + vec.resize(size); + in.read(reinterpret_cast<char*>(&(vec[0])), size * sizeof(T)); + }; + + DOFVector<WorldVector<T> > *getGradient(DOFVector<WorldVector<T> >*) const; + // { + // FUNCNAME("DOFVector<T>::getGradient()"); + // ERROR_EXIT("only specialized for DOFVector<double>\n"); + // return NULL; + // }; + + WorldVector<DOFVector<T>*> *getGradient(WorldVector<DOFVector<T>*> *grad) const; + + DOFVector<WorldVector<T> >* + getRecoveryGradient(DOFVector<WorldVector<T> >*) const; + // { + // FUNCNAME("DOFVector<T>::getRecoveryGradient()"); + // ERROR_EXIT("only specialized for DOFVector<double>\n"); + // return NULL; + // }; + + //const T *getLocalVector(const Element *el, T* localVec); + + // const T *getVecAtQPs(const ElInfo *elInfo, + // const Quadrature *quad, + // const FastQuadrature *quadFast, + // T *vecAtQPs) const; + + // const WorldVector<T> *getGrdAtQPs(const ElInfo *elInfo, + // const Quadrature *quad, + // const FastQuadrature *quadFast, + // WorldVector<T> *grdAtQPs) const; + // { + // FUNCNAME("DOFVector<T>::getGrdAtQPs()"); + // ERROR_EXIT("only specialized for DOFVector<double>\n"); + // return NULL; + // }; + + // const WorldMatrix<T> *getD2AtQPs(const ElInfo *elInfo, + // const Quadrature *quad, + // const FastQuadrature *quadFast, + // WorldMatrix<T> *d2AtQPs) const; + // { + // FUNCNAME("DOFVector<T>::getD2AtQPs()"); + // ERROR_EXIT("only specialized for DOFVector<double>\n"); + // return NULL; + // }; + + + protected: + + //Hier auch Ergaenzungen (Andreas) + + /** \brief + * Used by Int while mesh traversal + */ + static int Int_fct(ElInfo* elinfo); + + /** \brief + * Used by L1Norm while mesh traversal + */ + static int L1Norm_fct(ElInfo* elinfo); + + // Letzte Erganzung in diesem File (Andreas) + + + + /** \brief + * Used by L2Norm while mesh traversal + */ + static int L2Norm_fct(ElInfo* elinfo); + + /** \brief + * Used by H1Norm while mesh traversal + */ + static int H1Norm_fct(ElInfo* elinfo); + + protected: + /** \brief + * Name of this DOFVector + */ + ::std::string name; + + /** \brief + * FiniteElemSpace of the vector + */ + const FiniteElemSpace *feSpace; + + /** \brief + * Data container + */ + ::std::vector<T> vec; + + // ElementVector *elementVector; + + /** \brief + * Specifies whether interpolation should be performed after refinement + */ + bool refineInter; + + /** \brief + * Specifies what operation should be performed after coarsening + */ + CoarsenOperation coarsenOperation; + + // ::std::vector<Operator*> operators; + + // ::std::vector<double*> operatorFactor; + + // ::std::vector<double*> operatorEstFactor; + + /** \brief + * Used by \ref interpol + */ + AbstractFunction<T, WorldVector<double> > *interFct; + + /** \brief + * Used for mesh traversal + */ + static DOFVector<T> *traverseVector; + + protected: + /** \brief + * Used for mesh traversal + */ + // static DOFVector<T> *traverseVector; + + /** \brief + * Used while calculating vector norms + */ + static FastQuadrature *quad_fast; + + /** \brief + * Stores the last calculated vector norm + */ + static double norm; + + /** \brief + * Dimension of the mesh this DOFVector belongs to + */ + static int dim; + }; + + template<> + void DOFVector<double>::refineInterpol(RCNeighbourList&, int); + + template<> + void DOFVector<double>::coarseRestrict(RCNeighbourList&, int); + + inline double min(const DOFVector<double>& v) {return v.min();}; + inline double max(const DOFVector<double>& v) {return v.max();}; + + // =========================================================================== + // ===== class DOFVectorDOF ================================================== + // =========================================================================== + + /** \ingroup DOFAdministration + * \brief + * A DOFVector that stores DOF indices. + */ + class DOFVectorDOF : public DOFVector<DegreeOfFreedom>, + public DOFContainer + { + public: + MEMORY_MANAGED(DOFVectorDOF); + + /** \brief + * Calls constructor of DOFVector<DegreeOfFreedom> and registers itself + * as DOFContainer at DOFAdmin + */ + DOFVectorDOF(const FiniteElemSpace* feSpace_, ::std::string name_) + : DOFVector<DegreeOfFreedom>(feSpace_, name_) + { + feSpace->getAdmin()->addDOFContainer(this); + }; + + /** \brief + * Deregisters itself at DOFAdmin. + */ + ~DOFVectorDOF() { + feSpace->getAdmin()->removeDOFContainer(this); + }; + + /** \brief + * Implements DOFContainer::operator[]() by calling + * DOFVEctor<DegreeOfFreedom>::operator[]() + */ + DegreeOfFreedom& operator[](DegreeOfFreedom i) { + return DOFVector<DegreeOfFreedom>::operator[](i); + }; + + /** \brief + * Implements DOFIndexedBase::getSize() + */ + int getSize() const { + return DOFVector<DegreeOfFreedom>::getSize(); + }; + + /** \brief + * Implements DOFIndexedBase::resize() + */ + void resize(int size) { + DOFVector<DegreeOfFreedom>::resize(size); + } + + void freeDOFContent(DegreeOfFreedom dof); + + protected: + DOFVectorDOF(); + }; + + template<typename T> + double norm(DOFVector<T> *vec) { + return vec->nrm2(); + }; + + template<typename T> + double L2Norm(DOFVector<T> *vec) { + return vec->L2Norm(); + }; + + template<typename T> + double H1Norm(DOFVector<T> *vec) { + return vec->H1Norm(); + }; + + template<typename T> + void print(DOFVector<T> *vec) { + vec->print(); + }; + + // point wise multiplication + template<typename T> + const DOFVector<T>& operator*=(DOFVector<T>& x, const DOFVector<T>& y); + + // multiplication with scalar + + template<typename T> + const DOFVector<T>& operator*=(DOFVector<T>& x, T scal); + + // scalar product + + template<typename T> + T operator*(DOFVector<T>& x, DOFVector<T>& y); + + // addition + + template<typename T> + const DOFVector<T>& operator+=(DOFVector<T>& x, const DOFVector<T>& y); + + // subtraction + + template<typename T> + const DOFVector<T>& operator-=(DOFVector<T>& x, const DOFVector<T>& y); + + template<typename T> + const DOFVector<T>& operator*(const DOFVector<T>& v, double d); + + template<typename T> + const DOFVector<T>& operator*(double d, const DOFVector<T>& v); + + template<typename T> + const DOFVector<T>& operator+(const DOFVector<T>&v1 , const DOFVector<T>& v2); + + + + // y = a*x + y + + template<typename T> + void axpy(double a,const DOFVector<T>& x, DOFVector<T>& y); + + // matrix vector product + template<typename T> + void mv(MatrixTranspose transpose, + const DOFMatrix &a, + const DOFVector<T> &x, + DOFVector<T> &result, + bool add = false); + + template<typename T> + void xpay(double a,const DOFVector<T>& x,DOFVector<T>& y); + + template<typename T> + inline void scal(T a, DOFVector<T>& y) {y*=a;}; + + template<typename T> + inline const DOFVector<T>& mult(double scal, + const DOFVector<T>& v, + DOFVector<T>& result); + + template<typename T> + inline const DOFVector<T>& add(const DOFVector<T>& v, + double scal, + DOFVector<T>& result); + + template<typename T> + inline const DOFVector<T>& add(const DOFVector<T>& v1, + const DOFVector<T>& v2, + DOFVector<T>& result); + + template<typename T> + inline void set(DOFVector<T>& vec, T d) + { + vec.set(d); + }; + + template<typename T> + inline void setValue(DOFVector<T>& vec, T d) + { + vec.set(d); + }; + + template<typename T> + inline int size(DOFVector<T> *vec) { + return vec->getUsedSize(); + }; + + //template<typename T> + //void interpolGrd(DOFVector<T> *v, + // WorldVector<DOFVector<T>*> *grad, + // double factor, bool add = false); + + WorldVector<DOFVector<double>*> *transform(DOFVector<WorldVector<double> > *vec, + WorldVector<DOFVector<double>*> *result); +#if 0 + void transform2(DOFVector<WorldVector<double> > *vec, + ::std::vector<DOFVector<double>*> *result); +#endif + +} + +#include "DOFVector.hh" + +#endif // !_DOFVECTOR_H_ diff --git a/AMDiS/src/DOFVector.hh b/AMDiS/src/DOFVector.hh new file mode 100644 index 0000000000000000000000000000000000000000..274d3eb8899a2523163b6c53f6cefb2d72e383a4 --- /dev/null +++ b/AMDiS/src/DOFVector.hh @@ -0,0 +1,1562 @@ +#include <list> + +#include "FixVec.h" +#include "Boundary.h" +#include "DOFAdmin.h" +#include "ElInfo.h" +#include "Error.h" +#include "FiniteElemSpace.h" +#include "Global.h" +#include "Mesh.h" +#include "Quadrature.h" +#include "AbstractFunction.h" +#include "BoundaryManager.h" +#include "ElementVector.h" +#include "Assembler.h" + +namespace AMDiS { + + // template<typename T> + // void DOFVector<T>::coarseRestrict(RCNeighbourList& list, int n) {} + + template<typename T> + void DOFVectorBase<T>::addElementVector(T factor, + const ElementVector &elVec, + const BoundaryType *bound, + bool add) + { + FUNCNAME("DOFVector::addElementVector"); + DegreeOfFreedom i, irow; + + int n_row = elVec.getSize(); + + for (i = 0; i < n_row; i++) { + BoundaryCondition *condition = + bound ? this->getBoundaryManager()->getBoundaryCondition(bound[i]) : NULL; + + if(!(condition && condition->isDirichlet())) { + irow = elVec.dofIndices[i]; + (*this)[irow] = (add ? (*this)[irow] : 0.0); + (*this)[irow] += factor * elVec[i]; + } + } + } + + template<typename T> + DOFVector<T>::DOFVector(const FiniteElemSpace* f,::std::string n) + : DOFVectorBase<T>(f, n), + //elementVector(NULL), + refineInter(false), coarsenOperation(NO_OPERATION) + { + init(f, n); + } + + template<typename T> + void DOFVector<T>::init(const FiniteElemSpace* f,::std::string n) + { + name = n; + feSpace = f; + if(feSpace && feSpace->getAdmin()) { + (feSpace->getAdmin())->addDOFIndexed(this); + } + this->boundaryManager = NEW BoundaryManager; + } + + template<typename T> + DOFVector<T>::~DOFVector() + { + if(feSpace && feSpace->getAdmin()) { + (feSpace->getAdmin())->removeDOFIndexed(this); + } + + if (this->boundaryManager) { + DELETE this->boundaryManager; + } + } + + template<typename T> + DOFVector<T> * DOFVector<T>::traverseVector = NULL; + + template<typename T> + FastQuadrature *DOFVector<T>::quad_fast = NULL; + + template<typename T> + double DOFVector<T>::norm = 0.0; + + template<typename T> + int DOFVector<T>::dim = 0; + + template<typename T> + double DOFVector<T>::nrm2() const + { + FUNCNAME("DOFVector<T>::nrm2()"); + double nrm; + const DOFAdmin *admin = NULL; + + TEST_EXIT(feSpace && (admin = feSpace->getAdmin())) + ("pointer is NULL: %8X, %8X\n", feSpace,admin); + TEST_EXIT(static_cast<int>(vec.size()) >= admin->getUsedSize()) + ("size = %d too small: admin->sizeUsed = %d\n", vec.size(), + admin->getUsedSize()); + + nrm = 0.0; + + Iterator vecIterator(dynamic_cast<DOFIndexed<T>*>(const_cast<DOFVector<T>*>(this)), USED_DOFS); + for(vecIterator.reset(); !vecIterator.end(); ++vecIterator) + nrm += (*vecIterator) * (*vecIterator); + + return(sqrt(nrm)); + } + + template<typename T> + double DOFVector<T>::squareNrm2() const + { + FUNCNAME("DOFVector<T>::nrm2()"); + double nrm; + const DOFAdmin *admin = NULL; + + TEST_EXIT(feSpace && (admin = feSpace->getAdmin())) + ("pointer is NULL: %8X, %8X\n", feSpace,admin); + TEST_EXIT(static_cast<int>(vec.size()) >= admin->getUsedSize()) + ("size = %d too small: admin->sizeUsed = %d\n", vec.size(), + admin->getUsedSize()); + + nrm = 0.0; + + Iterator vecIterator(dynamic_cast<DOFIndexed<T>*>(const_cast<DOFVector<T>*>(this)), USED_DOFS); + for(vecIterator.reset(); !vecIterator.end(); ++vecIterator) + nrm += (*vecIterator) * (*vecIterator); + + return nrm; + } + + template<typename T> + T DOFVector<T>::asum() const + { + FUNCNAME("DOFVector<T>::asum"); + double nrm; + const DOFAdmin *admin = NULL; + TEST_EXIT(feSpace && (admin = feSpace->getAdmin())) + ("pointer is NULL: %8X, %8X\n", feSpace, admin); + TEST_EXIT(vec.size() >= admin->getUsedSize()) + ("size = %d too small: admin->sizeUsed = %d\n", vec.size(), + admin->getUsedSize()); + + nrm = 0.0; + + Iterator vecIterator(dynamic_cast<DOFIndexed<T>*>(const_cast<DOFVector<T>*>(this)), USED_DOFS); + for(vecIterator.reset(); !vecIterator.end(); ++vecIterator) + nrm += abs(*vecIterator); + + return(nrm); + } + + // Andreas ergaenzte .. + + template<typename T> + T DOFVector<T>::sum() const + { + FUNCNAME("DOFVector<T>::sum"); + double nrm; + const DOFAdmin *admin = NULL; + TEST_EXIT(feSpace && (admin = feSpace->getAdmin())) + ("pointer is NULL: %8X, %8X\n", feSpace, admin); + TEST_EXIT(vec.size() >= admin->getUsedSize()) + ("size = %d too small: admin->sizeUsed = %d\n", vec.size(), + admin->getUsedSize()); + + nrm = 0.0; + + Iterator vecIterator(dynamic_cast<DOFIndexed<T>*>(const_cast<DOFVector<T>*>(this)), USED_DOFS); + for(vecIterator.reset(); !vecIterator.end(); ++vecIterator) + nrm += *vecIterator; + + return(nrm); + } + + // .. bis hier (Andreas) + + + template<typename T> + void DOFVector<T>::set(T alpha) + { + FUNCNAME("DOFVector<T>::set"); + const DOFAdmin *admin = NULL; + + TEST_EXIT(feSpace && (admin = feSpace->getAdmin())) + ("pointer is NULL: %8X, %8X\n", feSpace, admin); + TEST_EXIT(static_cast<int>( vec.size()) >= admin->getUsedSize()) + ("size = %d too small: admin->sizeUsed = %d\n", vec.size(), + admin->getUsedSize()); + + Iterator vecIterator(dynamic_cast<DOFIndexed<T>*>(this), USED_DOFS); + for(vecIterator.reset(); !vecIterator.end(); ++vecIterator) { + *vecIterator = alpha ; + }; + } + + // template<typename T> + // void DOFVector<T>::scal(T alpha) + // { + // FUNCNAME("DOFVector<T>::scal"); + // const DOFAdmin *admin = NULL; + + // TEST_EXIT( feSpace && (admin = feSpace->getAdmin())) + // ("pointer is NULL: %8X, %8X\n", this, admin); + // TEST_EXIT(static_cast<int>(vec.size()) >= admin->getUsedSize()) + // ("size = %d too small: admin->sizeUsed = %d\n", vec.size(), + // admin->getUsedSize()); + + // Iterator vecIterator((DOFIndexed<T>*) this, USED_DOFS); + // for(vecIterator.reset(); !vecIterator.end(); ++vecIterator) { + // (*vecIterator) *= alpha ; + // }; + // } + + + template<typename T> + void DOFVector<T>::copy(const DOFVector<T>& x) + { + FUNCNAME("DOFVector<T>::copy"); + const DOFAdmin *admin = NULL; + + TEST_EXIT(feSpace && x.feSpace) + ("feSpace is NULL: %8X, %8X\n", feSpace,x.feSpace); + TEST_EXIT((admin = feSpace->getAdmin()) && (admin == x.feSpace->getAdmin())) + ("no admin or different admins: %8X, %8X\n", + feSpace->getAdmin(), x.feSpace->getAdmin()); + TEST_EXIT(static_cast<int>(vec.size()) >= admin->getUsedSize()) + ("size = %d too small: admin->sizeUsed = %d\n", vec.size(), + admin->getUsedSize()); + TEST_EXIT(static_cast<int>(x.vec.size()) >= admin->getUsedSize()) + ("x.size = %d too small: admin->sizeUsed = %d\n", x.vec.size(), + admin->getUsedSize()); + + Iterator vecIterator(dynamic_cast<DOFIndexed<T>*>(this), USED_DOFS); + Iterator xIterator(dynamic_cast<DOFVector<T>*>(const_cast<DOFVector<T>*>(&x)), USED_DOFS); + for(vecIterator.reset(), xIterator.reset(); + !vecIterator.end(); + ++vecIterator, ++xIterator) + { + *vecIterator = *xIterator; + }; + } + + // template<typename T> + // void DOFVector<T>::axpy(T alpha, const DOFVector<T>& x) + // { + // FUNCNAME("DOFVector<T>::axpy"); + // const DOFAdmin *admin; + + // TEST_EXIT(feSpace && x.feSpace) + // ("feSpace is NULL: %8X, %8X\n", feSpace,x.feSpace); + // TEST_EXIT((admin = feSpace->getAdmin()) && (admin == x.feSpace->getAdmin())) + // ("no admin or different admins: %8X, %8X\n", + // feSpace->getAdmin(), x.feSpace->getAdmin()); + // TEST_EXIT(static_cast<int>(vec.size()) >= admin->getUsedSize()) + // ("size = %d too small: admin->size = %d\n", vec.size(), + // admin->getUsedSize()); + // TEST_EXIT(static_cast<int>(x.vec.size()) >= admin->getUsedSize()) + // ("x.size = %d too small: admin->size = %d\n", x.vec.size(), + // admin->getUsedSize()); + + // Iterator vecIterator((DOFIndexed<T>*) this, USED_DOFS); + // Iterator xIterator((DOFIndexed<T>*) &x, USED_DOFS); + // for(vecIterator.reset(), xIterator.reset(); + // !vecIterator.end(); + // ++vecIterator, ++xIterator) + // { + // *vecIterator += alpha * (*xIterator); + // }; + // } + + // template<typename T> + // void DOFVector<T>::axpy(T alpha, + // const DOFVector<T>& x, + // const DOFVector<T>& y) + // { + // FUNCNAME("DOFVector<T>::axpy"); + // const DOFAdmin *admin; + + // TEST_EXIT(feSpace && x.feSpace && y.feSpace) + // ("feSpace is NULL: %8X, %8X, %8X\n", feSpace, x.feSpace, y.feSpace); + // TEST_EXIT((admin = feSpace->getAdmin()) && + // (admin == x.feSpace->getAdmin()) && + // (admin == y.feSpace->getAdmin())) + // ("no admin or different admins: %8X, %8X, %8X\n", + // feSpace->getAdmin(), x.feSpace->getAdmin(), y.feSpace->getAdmin()); + // TEST_EXIT(static_cast<int>(vec.size()) >= admin->getUsedSize()) + // ("size = %d too small: admin->size = %d\n", vec.size(), + // admin->getUsedSize()); + // TEST_EXIT(static_cast<int>(x.vec.size()) >= admin->getUsedSize()) + // ("x.size = %d too small: admin->size = %d\n", x.vec.size(), + // admin->getUsedSize()); + // TEST_EXIT(static_cast<int>(y.vec.size()) >= admin->getUsedSize()) + // ("y.size = %d too small: admin->size = %d\n", y.vec.size(), + // admin->getUsedSize()); + + // Iterator vecIterator((DOFIndexed<T>*) this, USED_DOFS); + // Iterator xIterator((DOFIndexed<T>*) &x, USED_DOFS); + // Iterator yIterator((DOFIndexed<T>*) &y, USED_DOFS); + // for(vecIterator.reset(), xIterator.reset(), yIterator.reset(); + // !vecIterator.end(); + // ++vecIterator, ++xIterator, ++yIterator) + // { + // *vecIterator = alpha * (*xIterator) + (*yIterator); + // }; + // } + + // template<typename T> + // void DOFVector<T>::xpay(T alpha, const DOFVector<T>& x) + // { + // FUNCNAME("DOFVector<T>::xpay"); + // const DOFAdmin *admin; + + // TEST_EXIT(feSpace && x.feSpace) + // ("feSpace is NULL: %8X, %8X\n", feSpace,x.feSpace); + // TEST_EXIT((admin = feSpace->getAdmin()) && (admin == x.feSpace->getAdmin())) + // ("no admin or different admins: %8X, %8X\n", + // feSpace->getAdmin(), x.feSpace->getAdmin()); + // TEST_EXIT(static_cast<int>(vec.size()) >= admin->getUsedSize()) + // ("size = %d too small: admin->sizeUsed = %d\n", + // vec.size(), admin->getUsedSize()); + // TEST_EXIT(static_cast<int>(x.vec.size()) >= admin->getUsedSize()) + // ("x.size = %d too small: admin->sizeUsed = %d\n", + // x.vec.size(), admin->getUsedSize()); + + // Iterator vecIterator((DOFIndexed<T>*) this, USED_DOFS); + // Iterator xIterator((DOFIndexed<T>*) &x, USED_DOFS); + // for(vecIterator.reset(), xIterator.reset(); + // !vecIterator.end(); + // ++vecIterator, ++xIterator) + // { + // *vecIterator = (*xIterator) + alpha * (*vecIterator); + // }; + // } + + template<typename T> + T DOFVector<T>::min() const + { + FUNCNAME("DOFVector<T>::min"); + T m; + const DOFAdmin *admin = NULL; + + TEST_EXIT( feSpace && (admin = feSpace->getAdmin())) + ("pointer is NULL: %8X, %8X\n", this, admin); + TEST_EXIT((static_cast<int>( vec.size())) >= admin->getUsedSize()) + ("size = %d too small: admin->sizeUsed = %d\n", vec.size(), + admin->getUsedSize()); + + Iterator vecIterator(const_cast<DOFIndexed<T>*>(dynamic_cast<const DOFIndexed<T>*>(this)), USED_DOFS); + for(vecIterator.reset(), m = *vecIterator; !vecIterator.end(); ++vecIterator) + { + m = ::std::min(m, *vecIterator); + } + return m; + } + + template<typename T> + T DOFVector<T>::max() const + { + FUNCNAME("DOFVector<T>::max"); + T m; + const DOFAdmin *admin = NULL; + + TEST_EXIT( feSpace && (admin = feSpace->getAdmin())) + ("pointer is NULL: %8X, %8X\n", this, admin); + TEST_EXIT((static_cast<int>( vec.size())) >= admin->getUsedSize()) + ("size = %d too small: admin->sizeUsed = %d\n", vec.size(), + admin->getUsedSize()); + + Iterator vecIterator(const_cast<DOFIndexed<T>*>(dynamic_cast<const DOFIndexed<T>*>(this)), USED_DOFS); + for(vecIterator.reset(), m = *vecIterator; !vecIterator.end(); ++vecIterator) + { + m = ::std::max(m, *vecIterator); + } + return m; + } + + template<typename T> + void gemv(MatrixTranspose transpose, T alpha, + const DOFMatrix& a, const DOFVector<T>& x, + T beta, DOFVector<T>& y) + { + FUNCNAME("gemv"); + int j, jcol, ysize; + T sum, ax; + const DOFMatrix::MatrixRow *row; + const DOFAdmin *cadmin,*radmin; + + TEST_EXIT(a.getRowFESpace() && a.getColFESpace() && x.getFESpace() && y.getFESpace()) + ("feSpace is NULL: %8X, %8X, %8X, %8X\n", a.getRowFESpace(),a.getColFESpace(),x.getFESpace(),y.getFESpace()); + TEST_EXIT((radmin=a.getRowFESpace()->getAdmin()) && + (cadmin = a.getColFESpace()->getAdmin()) && + (((transpose == NoTranspose) && (cadmin == x.getFESpace()->getAdmin()) && + (radmin == y.getFESpace()->getAdmin()))|| + ((transpose == Transpose) && (radmin == x.getFESpace()->getAdmin()) && + (cadmin == y.getFESpace()->getAdmin())))) + ("no admin or different admins: %8X, %8X, %8X, %8X\n", + a.getRowFESpace()->getAdmin(), a.getColFESpace()->getAdmin(), + x.getFESpace()->getAdmin(), y.getFESpace()->getAdmin()); + + if (transpose == NoTranspose) { + TEST_EXIT(static_cast<int>(x.getSize()) >= cadmin->getUsedSize()) + ("x.size = %d too small: admin->sizeUsed = %d\n", + x.getSize(), cadmin->getUsedSize()); + TEST_EXIT(static_cast<int>(y.getSize()) >= radmin->getUsedSize()) + ("y.size = %d too small: admin->sizeUsed = %d\n", + y.getSize(), radmin->getUsedSize()); + TEST_EXIT(static_cast<int>( a.getSize()) >= radmin->getUsedSize()) + ("a.size = %d too small: admin->sizeUsed = %d\n", + a.getSize(), radmin->getUsedSize()); + } + else if (transpose == Transpose) { + TEST_EXIT(static_cast<int>(x.getSize()) >= radmin->getUsedSize()) + ("x.size = %d too small: admin->sizeUsed = %d\n", + x.getSize(), radmin->getUsedSize()); + TEST_EXIT(static_cast<int>(y.getSize()) >= cadmin->getUsedSize()) + ("y.size = %d too small: admin->sizeUsed = %d\n", + y.getSize(), cadmin->getUsedSize()); + TEST_EXIT(static_cast<int>( a.getSize()) >= radmin->getUsedSize()) + ("a.size = %d too small: admin->sizeUsed = %d\n", + a.getSize(), radmin->getUsedSize()); + } + + ysize = y.getSize(); + + typename DOFVector<T>::Iterator vecIterator(dynamic_cast<DOFIndexed<T>*>(&y), FREE_DOFS); + for(vecIterator.reset(); + !vecIterator.end(); ++vecIterator) { + *vecIterator = 0; + }; + + if (transpose == NoTranspose) { + typename DOFVector<T>::Iterator vecIterator(dynamic_cast<DOFIndexed<T>*>(&y), USED_DOFS); + DOFMatrix::Iterator rowIterator(const_cast<DOFMatrix*>(&a), USED_DOFS); + for(vecIterator.reset(), rowIterator.reset(); + !rowIterator.end(); + ++rowIterator, ++vecIterator) { + sum = 0; + row = &(a[rowIterator.getDOFIndex()]); + for(::std::vector<MatEntry>::iterator colIterator = rowIterator->begin(); + colIterator != rowIterator->end(); + colIterator++) { + jcol = colIterator->col; + if (jcol >= 0) { // entry used? + sum += (static_cast<T>(colIterator->entry)) * x[jcol]; + } else { + if (jcol == DOFMatrix::NO_MORE_ENTRIES) + break; + } + } + *vecIterator *= beta; + *vecIterator += alpha * sum; + }; + } else if (transpose == Transpose) { + typename DOFVector<T>::Iterator vecIterator(dynamic_cast<DOFIndexed<T>*>(&y), USED_DOFS); + for(vecIterator.reset(); + !vecIterator.end(); + ++vecIterator) { + *vecIterator *= beta ; + }; + + typename DOFVector<T>::Iterator xIterator(dynamic_cast<DOFIndexed<T>*>(const_cast<DOFVector<T>*>(&x)), USED_DOFS); + DOFMatrix::Iterator rowIterator(const_cast<DOFMatrix*>(&a), USED_DOFS); + for(xIterator.reset(), rowIterator.reset(); + !rowIterator.end(); + ++rowIterator, ++xIterator) { + ax = alpha * (*xIterator); + row = &(a[rowIterator.getDOFIndex()]); + for(::std::vector<MatEntry>::iterator colIterator = rowIterator->begin(); + colIterator != rowIterator->end(); + colIterator++) { + jcol = colIterator->col; + if (jcol >= 0) // entry used? + y[jcol] += ax * (static_cast<T>(colIterator->entry)); + else + if (jcol == DOFMatrix::NO_MORE_ENTRIES) break; + } + } + } + else { + ERROR_EXIT("transpose=%d\n", transpose); + } + } + + + // /****************************************************************************/ + + // template<typename T> + // void DOFVector<T>::mv(MatrixTranspose transpose, + // const DOFMatrix&a, const DOFVector<T>&x) + // { + // FUNCNAME("DOFVector<T>::mv"); + // int jcol; + // T sum, ax; + // const DOFAdmin *radmin,*cadmin = NULL; + + // TEST_EXIT(a.getRowFESpace() && a.getColFESpace() && x.feSpace && feSpace) + // ("feSpace is NULL: %8X, %8X, %8X, %8X\n", + // a.getRowFESpace(), a.getColFESpace(), x.feSpace,feSpace); + // TEST_EXIT((radmin=a.getRowFESpace()->getAdmin()) && + // (cadmin = a.getColFESpace()->getAdmin()) && + // (((transpose == NoTranspose) && (cadmin == x.feSpace->getAdmin()) && + // (radmin == feSpace->getAdmin()))|| + // ((transpose == Transpose) && (radmin == x.feSpace->getAdmin()) && + // (cadmin == feSpace->getAdmin())))) + // ("no admin or different admins: %8X, %8X, %8X, %8X\n", + // a.getRowFESpace()->getAdmin(), a.getColFESpace()->getAdmin(), + // x.feSpace->getAdmin(), feSpace->getAdmin()); + + // if (transpose == NoTranspose) { + // TEST_EXIT(static_cast<int>(x.vec.size()) >= cadmin->getUsedSize()) + // ("x.size = %d too small: admin->sizeUsed = %d\n", + // x.vec.size(), cadmin->getUsedSize()); + // TEST_EXIT(static_cast<int>(vec.size()) >= radmin->getUsedSize()) + // ("size = %d too small: admin->sizeUsed = %d\n", + // vec.size(), radmin->getUsedSize()); + // TEST_EXIT(static_cast<int>( a.getSize()) >= radmin->getUsedSize()) + // ("a.size = %d too small: admin->sizeUsed = %d\n", + // a.getSize(), radmin->getUsedSize()); + + // Iterator vecIterator((DOFIndexed<T>*) this, USED_DOFS); + // DOFMatrix::Iterator rowIterator((DOFMatrix*) &a, USED_DOFS); + // for(vecIterator.reset(), rowIterator.reset(); + // !rowIterator.end(); + // ++rowIterator, ++vecIterator) { + // sum = 0; + // for(::std::vector<MatEntry>::iterator colIterator = rowIterator->begin(); + // colIterator != rowIterator->end(); + // colIterator++) { + // jcol = colIterator->col; + // if (jcol >= 0) { // entry used? + // sum += ((T) colIterator->entry) * x[jcol]; + // } else { + // if (jcol == DOFMatrix::NO_MORE_ENTRIES) + // break; + // } + // } + // *vecIterator = sum; + // } + // } else if (transpose == Transpose) { + // TEST_EXIT(static_cast<int>(x.vec.size()) >= radmin->getUsedSize()) + // ("x.size = %d too small: admin->sizeUsed = %d\n", + // x.vec.size(), radmin->getUsedSize()); + // TEST_EXIT(static_cast<int>(vec.size()) >= cadmin->getUsedSize()) + // ("size = %d too small: admin->sizeUsed = %d\n", + // vec.size(), cadmin->getUsedSize()); + // TEST_EXIT(static_cast<int>( a.getSize()) >= radmin->getUsedSize()) + // ("a.size = %d too small: admin->sizeUsed = %d\n", + // a.getSize(), radmin->getUsedSize()); + + // Iterator vecIterator((DOFIndexed<T>*) this, USED_DOFS); + // for(vecIterator.reset(); + // !vecIterator.end(); ++vecIterator) { + // *vecIterator = 0; + // }; + + // Iterator xIterator((DOFIndexed<T>*) &x, USED_DOFS); + // DOFMatrix::Iterator rowIterator((DOFMatrix*) &a, USED_DOFS); + // for(xIterator.reset(), rowIterator.reset(); + // !rowIterator.end(); + // ++rowIterator, ++xIterator) { + // ax = (*xIterator); + // for(::std::vector<MatEntry>::iterator colIterator = rowIterator->begin(); + // colIterator != rowIterator->end(); + // colIterator++) { + // jcol = colIterator->col; + // if (jcol >= 0) // entry used? + // vec[jcol] += ax * ((T) colIterator->entry); + // else + // if (jcol == DOFMatrix::NO_MORE_ENTRIES) break; + // } + // } + // } else { + // ERROR_EXIT("transpose=%d\n", transpose); + // } + // } + + template<typename T> + void DOFVector<T>::print() const + { + FUNCNAME("DOFVector<T>::print"); + int i, j; + const DOFAdmin *admin = NULL; + const char *format; + + if (feSpace) admin = feSpace->getAdmin(); + + MSG("Vec `%s':\n", name.c_str()); + j = 0; + if (admin) { + if (admin->getUsedSize() > 100) + format = "%s(%3d,%10.5le)"; + else if (admin->getUsedSize() > 10) + format = "%s(%2d,%10.5le)"; + else + format = "%s(%1d,%10.5le)"; + + Iterator vecIterator(dynamic_cast<DOFIndexed<T>*>(const_cast<DOFVector<T>*>(this)), USED_DOFS); + for(vecIterator.reset(); + !vecIterator.end(); ++vecIterator) { + if ((j % 3) == 0) { + if (j) Msg::print("\n"); + MSG(format, "", vecIterator.getDOFIndex(), *vecIterator); + } + else + Msg::print(format, " ", vecIterator.getDOFIndex(), *vecIterator); + j++; + }; + Msg::print("\n"); + } + else + { + MSG("no DOFAdmin, print whole vector.\n"); + + for (i = 0; i < static_cast<int>( vec.size()); i++) { + if ((j % 3) == 0) + { + if (j) Msg::print("\n"); + MSG("(%d,%10.5e)",i,vec[i]); + } + else + Msg::print(" (%d,%10.5e)",i,vec[i]); + j++; + } + Msg::print("\n"); + } + return; + } + + + template<typename T> + T DOFVectorBase<T>::evalUh(const DimVec<double>& lambda, + DegreeOfFreedom* dof_indices) + { + int i; + BasisFunction* phi = const_cast<BasisFunction*>(this->getFESpace()->getBasisFcts()); + int numberOfBasFcts = phi->getNumber(); + T val = 0.0; + + for (i = 0; i < numberOfBasFcts; i++) + val += (*this)[dof_indices[i]]*(*phi->getPhi(i))(lambda); + + return val; + } + + template<typename T> + void DOFVector<T>::interpol(AbstractFunction<T, WorldVector<double> > *fct) + { + FUNCNAME("interpol"); + + TEST_EXIT(interFct = fct)("no function to interpolate\n"); + + if (!this->getFESpace()) + { + MSG("no dof admin in vec %s, skipping interpolation\n", + this->getName().c_str()); + return; + } + + if (!(this->getFESpace()->getAdmin())) + { + MSG("no dof admin in feSpace %s, skipping interpolation\n", + this->getFESpace()->getName().c_str()); + return; + } + + if (!(this->getFESpace()->getBasisFcts())) + { + MSG("no basis functions in admin of vec %s, skipping interpolation\n", + this->getName().c_str()); + return; + } + + if (!(fct)) + { + MSG("function that should be interpolated only pointer to NULL, "); + Msg::print("skipping interpolation\n"); + return; + } + + traverseVector = this; + this->getFESpace()->getMesh()->traverse(-1, + Mesh::CALL_LEAF_EL | + Mesh::FILL_COORDS, + interpolFct); + + return; + } + + template<typename T> + int DOFVector<T>::interpolFct(ElInfo* elinfo) + { + int i; + const BasisFunction *basFct = traverseVector->getFESpace()->getBasisFcts(); + const DOFAdmin* admin = traverseVector->getFESpace()->getAdmin(); + const DegreeOfFreedom *dof = + basFct->getLocalIndices(const_cast<Element *>(elinfo->getElement()), + admin, NULL); + const T *inter_val = + const_cast<BasisFunction*>(basFct)->interpol(elinfo, + 0, + NULL, + traverseVector->interFct, + NULL); + + int number = basFct->getNumber(); + for (i = 0; i < number; i++) + (*traverseVector)[dof[i]] = inter_val[i]; + + return 0; + } + + // das hat Andreas eingefuegt: Integral... + + template<typename T> + double DOFVector<T>::Int(Quadrature* q) const + { + FUNCNAME("DOFVector::Int"); + + Mesh* mesh = feSpace->getMesh(); + + int deg; + dim = mesh->getDim(); + + if (!q) + { + deg = 2*feSpace->getBasisFcts()->getDegree(); + q = Quadrature::provideQuadrature(dim, deg); + } + + quad_fast = FastQuadrature::provideFastQuadrature(feSpace->getBasisFcts(), *q, INIT_PHI); + + norm = 0.0; + traverseVector = const_cast<DOFVector<T>*>(this); + + mesh->traverse(-1, + Mesh::CALL_LEAF_EL| + Mesh::FILL_COORDS | + Mesh::FILL_DET, + Int_fct); + + return norm; + } + + template<typename T> + int DOFVector<T>::Int_fct(ElInfo *elinfo) + { + double det, normT; + const T *uh_vec; + int iq; + + det = elinfo->getDet(); + //uh_loc = traverseVector->getLocalVector(elinfo->getElement(), NULL); + //uh_vec = quad_fast->uhAtQp(uh_loc, NULL); + + uh_vec = traverseVector->getVecAtQPs(elinfo, + NULL, + quad_fast, + NULL); + + int numPoints = quad_fast->getNumPoints(); + for (normT = iq = 0; iq < numPoints; iq++) + { + normT += quad_fast->getWeight(iq)*(uh_vec[iq]); + } + norm += det*normT; + + return 0; + } + + // ... und die L1-Norm ... + + template<typename T> + double DOFVector<T>::L1Norm(Quadrature* q) const + { + FUNCNAME("DOFVector::L1Norm"); + + Mesh* mesh = feSpace->getMesh(); + + int deg; + dim = mesh->getDim(); + + if (!q) + { + deg = 2*feSpace->getBasisFcts()->getDegree(); + q = Quadrature::provideQuadrature(dim, deg); + } + + quad_fast = FastQuadrature::provideFastQuadrature(feSpace->getBasisFcts(),*q,INIT_PHI); + + norm = 0.0; + traverseVector = const_cast<DOFVector<T>*>(this); + + mesh->traverse(-1, + Mesh::CALL_LEAF_EL| + Mesh::FILL_COORDS | + Mesh::FILL_DET, + L1Norm_fct); + + return norm; + } + + template<typename T> + int DOFVector<T>::L1Norm_fct(ElInfo *elinfo) + { + double det, normT; + const T *uh_loc, *uh_vec; + int iq; + + det = elinfo->getDet(); + // uh_loc = + // traverseVector->getLocalVector(elinfo->getElement(), + // NULL); + // uh_vec = quad_fast->uhAtQp(uh_loc, NULL); + + uh_vec = traverseVector->getVecAtQPs(elinfo, + NULL, + quad_fast, + NULL); + + int numPoints = quad_fast->getNumPoints(); + for (normT = iq = 0; iq < numPoints; iq++) + { + normT += quad_fast->getWeight(iq)*abs(uh_vec[iq]); + } + norm += det*normT; + + return 0; + } + + + // bis hierhin gehen Andreas Ergaenzungen... + + template<typename T> + double DOFVector<T>::L2NormSquare(Quadrature* q) const + { + FUNCNAME("DOFVector::L2NormSquare"); + + Mesh* mesh = feSpace->getMesh(); + + int deg; + dim = mesh->getDim(); + + if (!q) + { + deg = 2*feSpace->getBasisFcts()->getDegree(); + q = Quadrature::provideQuadrature(dim, deg); + } + + quad_fast = FastQuadrature::provideFastQuadrature(feSpace->getBasisFcts(), + *q, + INIT_PHI); + + norm = 0.0; + traverseVector = const_cast<DOFVector<T>*>(this); + + mesh->traverse(-1, Mesh::CALL_LEAF_EL|Mesh::FILL_COORDS|Mesh::FILL_DET, L2Norm_fct); + + return norm; + } + + template<typename T> + int DOFVector<T>::L2Norm_fct(ElInfo *elinfo) + { + double det, normT; + const T *uh_vec; + int iq; + + det = elinfo->getDet(); + // uh_loc = + // traverseVector->getLocalVector(elinfo->getElement(), + // NULL); + // uh_vec = quad_fast->uhAtQp(uh_loc, NULL); + + uh_vec = traverseVector->getVecAtQPs(elinfo, + NULL, + quad_fast, + NULL); + + int numPoints = quad_fast->getNumPoints(); + for (normT = iq = 0; iq < numPoints; iq++) + { + normT += quad_fast->getWeight(iq)*sqr(uh_vec[iq]); + } + norm += det*normT; + + return 0; + } + + template<typename T> + int DOFVector<T>::H1Norm_fct(ElInfo *elinfo) + { + double norm2, normT; + //const T *uh_loc; + const WorldVector<T> *grduh_vec; + int iq, j; + + double det = elinfo->getDet(); + //const DimVec<WorldVector<double> > &Lambda = elinfo->getGrdLambda(); + + //det = elinfo->calcGrdLambda(Lambda); + //uh_loc = + // traverseVector->getLocalVector(elinfo->getElement(), NULL); + //grduh_vec = + // quad_fast->grdUhAtQp(const_cast<const DimVec<WorldVector<T> >&>(Lambda), uh_loc, NULL); + + grduh_vec = traverseVector->getGrdAtQPs(elinfo, NULL, quad_fast, NULL); + + int dimOfWorld = Global::getGeo(WORLD); + + int numPoints = quad_fast->getNumPoints(); + for (normT = iq = 0; iq < numPoints; iq++) + { + for (norm2 = j = 0; j < dimOfWorld; j++) + norm2 += sqr(grduh_vec[iq][j]); + + normT += quad_fast->getWeight(iq)*norm2; + } + norm += det*normT; + + return 0; + } + + + template<typename T> + double DOFVector<T>::H1NormSquare(Quadrature *q) const + { + FUNCNAME("DOFVector::H1NormSquare"); + int deg; + + Mesh *mesh = feSpace->getMesh(); + dim = mesh->getDim(); + + if (!q) + { + deg = 2*feSpace->getBasisFcts()->getDegree()-2; + q = Quadrature::provideQuadrature(dim, deg); + } + quad_fast = + FastQuadrature::provideFastQuadrature(feSpace->getBasisFcts(), + *q, + INIT_GRD_PHI); + + norm = 0.0; + traverseVector = const_cast<DOFVector<T>*>(this); + + mesh->traverse(-1, Mesh::CALL_LEAF_EL | Mesh::FILL_COORDS | + Mesh::FILL_DET | Mesh::FILL_GRD_LAMBDA, + H1Norm_fct); + + return norm; + } + + template<typename T> + void DOFVector<T>::compressDOFIndexed(int first, int last, + ::std::vector<DegreeOfFreedom> &newDOF) + { + int i, j; + for(i = first; i <= last; i++) { + if((j = newDOF[i]) >= 0) { + vec[j] = vec[i]; + } + } + } + + template<typename T> + ElementVector* DOFVectorBase<T>::assemble(T factor, ElInfo *elInfo, + const BoundaryType *bound, + Operator *op) + { + FUNCNAME("DOFVector::assemble"); + + //TEST_EXIT(op || operators.size())("no rhs operator\n"); + if(!(op || this->operators.size())) return NULL; + + Operator *operat = op ? op : this->operators[0]; + + // const DegreeOfFreedom *rowDOF; + // const Element *el = elInfo->getElement(); + + // const BasisFunction *psi = operat->getRowFESpace()->getBasisFcts(); + + // DOFAdmin *rowAdmin = operat->getRowFESpace()->getAdmin(); + + // int nRow = psi->getNumber(); + + // if(!elementVector) elementVector = operat->createElementVector(); + + // operat->resetElementVector(elementVector); + + this->elementVector = + operat->getAssembler()->initElementVector(this->elementVector, elInfo); + + if(op) { + op->getElementVector(elInfo, this->elementVector); + } else { + ::std::vector<Operator*>::iterator it; + ::std::vector<double*>::iterator factorIt; + for(it = this->operators.begin(), factorIt = this->operatorFactor.begin(); + it != this->operators.end(); + ++it, ++factorIt) + { + (*it)->getElementVector(elInfo, + this->elementVector, + *factorIt ? **factorIt : 1.0); + } + } + + // rowDOF = psi->getLocalIndices(el, rowAdmin, NULL); + + addElementVector(factor, + *this->elementVector, + bound); + + return this->elementVector; + } + + template<typename T> + Flag DOFVectorBase<T>::getAssembleFlag() + { + Flag fillFlag(0); + ::std::vector<Operator*>::iterator op; + for(op = this->operators.begin(); op != this->operators.end(); ++op) { + fillFlag |= (*op)->getFillFlag(); + } + return fillFlag; + } + + template<typename T> + DOFVector<T>& DOFVector<T>::operator=(const DOFVector<T>& rhs ) + { + feSpace=rhs.feSpace; + vec=rhs.vec; + this->elementVector=NULL; + interFct=rhs.interFct; + refineInter=rhs.refineInter; + coarsenOperation=rhs.coarsenOperation; + this->operators=rhs.operators; + this->operatorFactor=rhs.operatorFactor; + if (rhs.boundaryManager) { + if(this->boundaryManager) delete this->boundaryManager; + this->boundaryManager = new BoundaryManager(*rhs.boundaryManager); + // boundaryManager->setDOFVector(this); + } + else + this->boundaryManager=NULL; + return *this; + } + + template<typename T> + const DOFVector<T>& operator*=(DOFVector<T>& x, T scal) + { + FUNCNAME("operator*=(DOFVector<T>& x, T scal)"); + const DOFAdmin *admin = NULL; + + TEST_EXIT( x.getFESpace() && (admin = x.getFESpace()->getAdmin())) + ("pointer is NULL: %8X, %8X\n", x.getFESpace(), admin); + + typename DOFVector<T>::Iterator vecIterator(dynamic_cast<DOFIndexed<T>*>(&x), USED_DOFS); + for(vecIterator.reset(); !vecIterator.end(); ++vecIterator) { + (*vecIterator) *= scal; + }; + return x; + } + + + template<typename T> + const DOFVector<T>& operator+=(DOFVector<T>& x, const DOFVector<T>& y) + { + FUNCNAME("operator*=(DOFVector<T>& x, const DOFVector<T>& y)"); + const DOFAdmin *admin; + + TEST_EXIT(x.getFESpace() && y.getFESpace()) + ("feSpace is NULL: %8X, %8X\n", x.getFESpace(), y.getFESpace()); + TEST_EXIT((admin = x.getFESpace()->getAdmin()) && + (admin == y.getFESpace()->getAdmin())) + ("no admin or different admins: %8X, %8X\n", + x.getFESpace()->getAdmin(), y.getFESpace()->getAdmin()); + TEST_EXIT(x.getSize() == y.getSize())("different sizes\n"); + + typename DOFVector<T>::Iterator xIterator(dynamic_cast<DOFIndexed<T>*>(&x), USED_DOFS); + typename DOFVector<T>::Iterator yIterator(dynamic_cast<DOFIndexed<T>*>(const_cast<DOFVector<T>*>(&y)), USED_DOFS); + for(xIterator.reset(), yIterator.reset(); + !xIterator.end(); + ++xIterator, ++yIterator) + { + *xIterator += *yIterator; + } + return x; + } + + // F.H. 17/3/2006 + template<typename T> + const DOFVector<T>& operator-=(DOFVector<T>& x, const DOFVector<T>& y) + { + FUNCNAME("operator*=(DOFVector<T>& x, const DOFVector<T>& y)"); + const DOFAdmin *admin; + + TEST_EXIT(x.getFESpace() && y.getFESpace()) + ("feSpace is NULL: %8X, %8X\n", x.getFESpace(), y.getFESpace()); + TEST_EXIT((admin = x.getFESpace()->getAdmin()) && + (admin == y.getFESpace()->getAdmin())) + ("no admin or different admins: %8X, %8X\n", + x.getFESpace()->getAdmin(), y.getFESpace()->getAdmin()); + TEST_EXIT(x.getSize() == y.getSize())("different sizes\n"); + + typename DOFVector<T>::Iterator xIterator(dynamic_cast<DOFIndexed<T>*>(&x), USED_DOFS); + typename DOFVector<T>::Iterator yIterator(dynamic_cast<DOFIndexed<T>*>(const_cast<DOFVector<T>*>(&y)), USED_DOFS); + for(xIterator.reset(), yIterator.reset(); + !xIterator.end(); + ++xIterator, ++yIterator) + { + *xIterator -= *yIterator; + } + return x; + } + + + + + template<typename T> + const DOFVector<T>& operator*=(DOFVector<T>& x, const DOFVector<T>& y) + { + FUNCNAME("operator*=(DOFVector<T>& x, const DOFVector<T>& y)"); + const DOFAdmin *admin; + + TEST_EXIT(x.getFESpace() && y.getFESpace()) + ("feSpace is NULL: %8X, %8X\n", x.getFESpace(), y.getFESpace()); + TEST_EXIT((admin = x.getFESpace()->getAdmin()) && + (admin == y.getFESpace()->getAdmin())) + ("no admin or different admins: %8X, %8X\n", + x.getFESpace()->getAdmin(), y.getFESpace()->getAdmin()); + TEST_EXIT(x.getSize() == y.getSize())("different sizes\n"); + + typename DOFVector<T>::Iterator xIterator(dynamic_cast<DOFIndexed<T>*>(&x), USED_DOFS); + typename DOFVector<T>::Iterator yIterator(dynamic_cast<DOFIndexed<T>*>(const_cast<DOFVector<T>*>(&y)), USED_DOFS); + for(xIterator.reset(), yIterator.reset(); + !xIterator.end(); + ++xIterator, ++yIterator) + { + *xIterator *= *yIterator; + } + + return x; + } + // F.H. 17/3/2006 + + + template<typename T> + T operator*(DOFVector<T>& x, DOFVector<T>& y) + { + FUNCNAME("DOFVector<T>::operator*(DOFVector<T>& x, DOFVector<T>& y)"); + T dot; + const DOFAdmin *admin = NULL; + + TEST_EXIT(x.getFESpace() && y.getFESpace()) + ("feSpace is NULL: %8X, %8X\n", x.getFESpace(), y.getFESpace()); + TEST_EXIT((admin = x.getFESpace()->getAdmin()) && (admin == y.getFESpace()->getAdmin())) + ("no admin or different admins: %8X, %8X\n", + x.getFESpace()->getAdmin(), y.getFESpace()->getAdmin()); + TEST_EXIT(x.getSize() == y.getSize())("different sizes\n"); + + dot = 0; + + typename DOFVector<T>::Iterator xIterator(dynamic_cast<DOFIndexed<T>*>(&x), USED_DOFS); + typename DOFVector<T>::Iterator yIterator(dynamic_cast<DOFIndexed<T>*>(&y), USED_DOFS); + for (xIterator.reset(), yIterator.reset(); + !xIterator.end(); + ++xIterator, ++yIterator) + { + dot += (*xIterator) * (*yIterator); + }; + + return(dot); + } + + template<typename T> + void mv(MatrixTranspose transpose, + const DOFMatrix &a, + const DOFVector<T>&x, + DOFVector<T> &result, + bool add) + { + FUNCNAME("DOFVector<T>::mv()"); + + TEST_EXIT(a.getRowFESpace() && a.getColFESpace() && x.getFESpace() && result.getFESpace()) + ("getFESpace() is NULL: %8X, %8X, %8X, %8X\n", + a.getRowFESpace(), a.getColFESpace(), x.getFESpace(), result.getFESpace()); + + const DOFAdmin *rowAdmin = a.getRowFESpace()->getAdmin(); + const DOFAdmin *colAdmin = a.getColFESpace()->getAdmin(); + + TEST_EXIT((rowAdmin && colAdmin) && + (((transpose == NoTranspose) && (colAdmin == x.getFESpace()->getAdmin()) && + (rowAdmin == result.getFESpace()->getAdmin()))|| + ((transpose == Transpose) && (rowAdmin == x.getFESpace()->getAdmin()) && + (colAdmin == result.getFESpace()->getAdmin())))) + ("no admin or different admins: %8X, %8X, %8X, %8X\n", + a.getRowFESpace()->getAdmin(), a.getColFESpace()->getAdmin(), + x.getFESpace()->getAdmin(), result.getFESpace()->getAdmin()); + + if (transpose == NoTranspose) { + TEST_EXIT(static_cast<int>(x.getSize()) >= colAdmin->getUsedSize()) + ("x.size = %d too small: admin->sizeUsed = %d\n", + x.getSize(), colAdmin->getUsedSize()); + TEST_EXIT(static_cast<int>( result.getSize()) >= rowAdmin->getUsedSize()) + ("size = %d too small: admin->sizeUsed = %d\n", + result.getSize(), rowAdmin->getUsedSize()); + TEST_EXIT(static_cast<int>( a.getSize()) >= rowAdmin->getUsedSize()) + ("a.size = %d too small: admin->sizeUsed = %d\n", + a.getSize(), rowAdmin->getUsedSize()); + + // This is the old implementation of the mv-multiplication. It have been changed + // because of the OpenMP-parallelization: + // typename DOFVector<T>::Iterator vecIterator(dynamic_cast<DOFIndexed<T>*>(&result), USED_DOFS); + // DOFMatrix::Iterator rowIterator(const_cast<DOFMatrix*>(&a), USED_DOFS); + // for(vecIterator.reset(), rowIterator.reset(); + // !rowIterator.end(); + // ++rowIterator, ++vecIterator) { + // sum = 0; + // if(!add) *vecIterator = 0.0; + // for(::std::vector<MatEntry>::iterator colIterator = rowIterator->begin(); + // colIterator != rowIterator->end(); + // colIterator++) { + // jcol = colIterator->col; + // if (jcol >= 0) { // entry used? + // sum += (static_cast<double>(colIterator->entry)) * x[jcol]; + // } else { + // if (jcol == DOFMatrix::NO_MORE_ENTRIES) + // break; + // } + // } + // *vecIterator += sum; + // } + + int i; + int maxI = result.getSize(); + +#ifdef _OPENMP +#pragma omp parallel for schedule(dynamic, 25000) default(shared) private(i) +#endif + for (i = 0; i < maxI; i++) { + if (rowAdmin->isDOFFree(i)) { + continue; + } + + T sum = 0; + + const ::std::vector<MatEntry> *v = &a[i]; + + for (int j = 0; j < static_cast<int>(v->size()); j++) { + const MatEntry *m = &((*v)[j]); + int jcol = m->col; + + if (jcol >= 0) { // entry used? + sum += (static_cast<double>(m->entry)) * x[jcol]; + } else { + if (jcol == DOFMatrix::NO_MORE_ENTRIES) + break; + } + } + + if (add) { + result[i] += sum; + } else { + result[i] = sum; + } + } + + } else if (transpose == Transpose) { + TEST_EXIT(static_cast<int>(x.getSize()) >= rowAdmin->getUsedSize()) + ("x.size = %d too small: admin->sizeUsed = %d\n", + x.getSize(), rowAdmin->getUsedSize()); + TEST_EXIT(static_cast<int>( result.getSize()) >= colAdmin->getUsedSize()) + ("size = %d too small: admin->sizeUsed = %d\n", + result.getSize(), colAdmin->getUsedSize()); + TEST_EXIT(static_cast<int>( a.getSize()) >= rowAdmin->getUsedSize()) + ("a.size = %d too small: admin->sizeUsed = %d\n", + a.getSize(), rowAdmin->getUsedSize()); + + if(!add) { + typename DOFVector<T>::Iterator vecIterator(dynamic_cast<DOFIndexed<T>*>(&result), USED_DOFS); + for(vecIterator.reset(); + !vecIterator.end(); ++vecIterator) { + *vecIterator = 0; + }; + } + + typename DOFVector<T>::Iterator xIterator(const_cast<DOFIndexed<T>*>(dynamic_cast<const DOFIndexed<T>*>(&x)), USED_DOFS); + DOFMatrix::Iterator rowIterator(const_cast<DOFMatrix*>(&a), USED_DOFS); + for(xIterator.reset(), rowIterator.reset(); + !rowIterator.end(); + ++rowIterator, ++xIterator) { + T ax = (*xIterator); + for(::std::vector<MatEntry>::iterator colIterator = rowIterator->begin(); + colIterator != rowIterator->end(); + colIterator++) { + int jcol = colIterator->col; + if (jcol >= 0) // entry used? + result[jcol] += (static_cast<double>(colIterator->entry)) * ax; + else + if (jcol == DOFMatrix::NO_MORE_ENTRIES) break; + } + } + } else { + ERROR_EXIT("transpose = %d\n", transpose); + } + } + + template<typename T> + void axpy(double alpha, + const DOFVector<T>& x, + DOFVector<T>& y) + { + FUNCNAME("DOFVector<T>::axpy()"); + + TEST_EXIT(x.getFESpace() && y.getFESpace()) + ("feSpace is NULL: %8X, %8X\n", x.getFESpace(), y.getFESpace()); + + const DOFAdmin *admin = x.getFESpace()->getAdmin(); + + TEST_EXIT((admin) && (admin == y.getFESpace()->getAdmin())) + ("no admin or different admins: %8X, %8X\n", + x.getFESpace()->getAdmin(), y.getFESpace()->getAdmin()); + TEST_EXIT(static_cast<int>(x.getSize()) >= admin->getUsedSize()) + ("size = %d too small: admin->size = %d\n", x.getSize(), + admin->getUsedSize()); + TEST_EXIT(static_cast<int>(y.getSize()) >= admin->getUsedSize()) + ("y.size = %d too small: admin->size = %d\n", y.getSize(), + admin->getUsedSize()); + + // This is the old implementation of the mv-multiplication. It have been changed + // because of the OpenMP-parallelization: +// typename DOFVector<T>::Iterator xIterator(dynamic_cast<DOFIndexed<T>*>(const_cast<DOFVector<T>*>(&x)), USED_DOFS); +// typename DOFVector<T>::Iterator yIterator(dynamic_cast<DOFIndexed<T>*>(&y), USED_DOFS); +// for(xIterator.reset(), yIterator.reset(); +// !xIterator.end(); +// ++xIterator, ++yIterator) +// { +// *yIterator += alpha * (*xIterator); +// }; + + int i; + int maxI = y.getSize(); + +#ifdef _OPENMP +#pragma omp parallel for schedule(dynamic, 25000) default(shared) private(i) +#endif + for (i = 0; i < maxI; i++) { + if (!admin->isDOFFree(i)) { + y[i] += alpha * x[i]; + } + } + } + + template<typename T> + const DOFVector<T>& operator*(const DOFVector<T>& v, double d) + { + static DOFVector<T> result; + return mult(d, v, result); + } + + template<typename T> + const DOFVector<T>& operator*(double d, const DOFVector<T>& v) + { + static DOFVector<T> result; + return mult(d, v, result); + } + + template<typename T> + const DOFVector<T>& operator+(const DOFVector<T> &v1 , const DOFVector<T> &v2) + { + static DOFVector<T> result; + return add(v1, v2, result); + } + + + template<typename T> + void xpay(double alpha, + const DOFVector<T>& x, + DOFVector<T>& y) + { + FUNCNAME("DOFVector<T>::xpay()"); + + TEST_EXIT(x.getFESpace() && y.getFESpace()) + ("feSpace is NULL: %8X, %8X\n", x.getFESpace(), y.getFESpace()); + + const DOFAdmin *admin = x.getFESpace()->getAdmin(); + + TEST_EXIT(admin && (admin == y.getFESpace()->getAdmin())) + ("no admin or different admins: %8X, %8X\n", + x.getFESpace()->getAdmin(), y.getFESpace()->getAdmin()); + TEST_EXIT(static_cast<int>(x.getSize()) >= admin->getUsedSize()) + ("size = %d too small: admin->size = %d\n", x.getSize(), + admin->getUsedSize()); + TEST_EXIT(static_cast<int>(y.getSize()) >= admin->getUsedSize()) + ("y.size = %d too small: admin->size = %d\n", y.getSize(), + admin->getUsedSize()); + + // This is the old implementation of the mv-multiplication. It have been changed + // because of the OpenMP-parallelization: + // typename DOFVector<T>::Iterator xIterator(dynamic_cast<DOFIndexed<T>*>(const_cast<DOFVector<T>*>(&x)), USED_DOFS); + // typename DOFVector<T>::Iterator yIterator(dynamic_cast<DOFIndexed<T>*>(&y), USED_DOFS); + // for(xIterator.reset(), yIterator.reset(); + // !xIterator.end(); + // ++xIterator, ++yIterator) + // { + // *yIterator = alpha *(*yIterator)+ (*xIterator); + // }; + + int i; + int maxI = y.getSize(); + +#ifdef _OPENMP +#pragma omp parallel for schedule(dynamic, 25000) default(shared) private(i) +#endif + for (i = 0; i < maxI; i++) { + if (!admin->isDOFFree(i)) { + y[i] = alpha * y[i] + x[i]; + } + } + } + + template<typename T> + inline const DOFVector<T>& mult(double scal, + const DOFVector<T>& v, + DOFVector<T>& result) + { + typename DOFVector<T>::Iterator vIterator(dynamic_cast<DOFIndexed<T>*>(const_cast<DOFVector<T>*>(&v)), USED_DOFS); + typename DOFVector<T>::Iterator rIterator(dynamic_cast<DOFIndexed<T>*>(&result), USED_DOFS); + for(vIterator.reset(), rIterator.reset(); + !vIterator.end(); + ++vIterator, ++rIterator) + { + *rIterator = scal * (*vIterator); + }; + + return result; + } + + template<typename T> + inline const DOFVector<T>& add(const DOFVector<T>& v, + double scal, + DOFVector<T>& result) + { + typename DOFVector<T>::Iterator vIterator(dynamic_cast<DOFIndexed<T>*>(const_cast<DOFVector<T>*>(&v)), USED_DOFS); + typename DOFVector<T>::Iterator rIterator(dynamic_cast<DOFIndexed<T>*>(&result), USED_DOFS); + for(vIterator.reset(), rIterator.reset(); + !vIterator.end(); + ++vIterator, ++rIterator) + { + *rIterator = (*vIterator) + scal; + }; + return result; + } + + template<typename T> + inline const DOFVector<T>& add(const DOFVector<T>& v1, + const DOFVector<T>& v2, + DOFVector<T>& result) + { + typename DOFVector<T>::Iterator v1Iterator(dynamic_cast<DOFIndexed<T>*>(const_cast<DOFVector<T>*>(&v1)), USED_DOFS); + typename DOFVector<T>::Iterator v2Iterator(dynamic_cast<DOFIndexed<T>*>(const_cast<DOFVector<T>*>(&v2)), USED_DOFS); + typename DOFVector<T>::Iterator rIterator(dynamic_cast<DOFIndexed<T>*>(&result), USED_DOFS); + for(v1Iterator.reset(), v2Iterator.reset(), rIterator.reset(); + !v1Iterator.end(); + ++v1Iterator, ++v2Iterator, ++rIterator) + { + *rIterator = (*v1Iterator) + (*v2Iterator); + }; + return result; + + } + + template<typename T> + const T *DOFVectorBase<T>::getLocalVector(const Element *el, T *d) const + { + static T* localVec = NULL; + const DOFAdmin* admin = feSpace->getAdmin(); + + int i; + int nBasFcts = feSpace->getBasisFcts()->getNumber(); + + T *result; + + if(d) { + result = d; + } else { + if(localVec) delete [] localVec; + localVec = new T[nBasFcts]; + result = localVec; + } + + const DegreeOfFreedom *localIndices = + feSpace->getBasisFcts()->getLocalIndices(el, admin, NULL); + + for(i = 0; i < nBasFcts; i++) { + result[i] = (*this)[localIndices[i]]; + } + + return result; + } + + template<typename T> + const T *DOFVectorBase<T>::getVecAtQPs(const ElInfo *elInfo, + const Quadrature *quad, + const FastQuadrature *quadFast, + T *vecAtQPs) const + { + FUNCNAME("DOFVector<T>::getVecAtQPs()"); + + TEST_EXIT(quad || quadFast)("neither quad nor quadFast defined\n"); + + if(quad && quadFast) { + TEST_EXIT(quad == quadFast->getQuadrature()) + ("quad != quadFast->quadrature\n"); + } + + TEST_EXIT(!quadFast || quadFast->getBasisFunctions() == feSpace->getBasisFcts()) + ("invalid basis functions"); + + Element *el = elInfo->getElement(); + + const Quadrature *quadrature = quadFast ? quadFast->getQuadrature() : quad; + + const BasisFunction *basFcts = feSpace->getBasisFcts(); + + int numPoints = quadrature->getNumPoints(); + int nBasFcts = basFcts->getNumber(); + int i, j; + + static T *localvec = NULL; + + T *result; + + if (vecAtQPs) { + result = vecAtQPs; + } else { + if(localvec) delete [] localvec; + localvec = new T[numPoints]; + for(i = 0; i < numPoints; i++) { + localvec[i] = 0.0; + } + result = localvec; + } + + const T *localVec = getLocalVector(el, NULL); + + for(i = 0; i < numPoints; i++) { + for(result[i] = j = 0; j < nBasFcts; j++) { + result[i] += localVec[j] * + (quadFast ? + (quadFast->getPhi(i, j)) : + ((*(basFcts->getPhi(j)))(quad->getLambda(i)))); + } + } + + return const_cast<const T*>(result); + } + +} diff --git a/AMDiS/src/DataCollector.cc b/AMDiS/src/DataCollector.cc new file mode 100644 index 0000000000000000000000000000000000000000..cf5b8a41f8843e3a0d227130d966fa67881aab89 --- /dev/null +++ b/AMDiS/src/DataCollector.cc @@ -0,0 +1,523 @@ +#include "DataCollector.h" +#include "Traverse.h" +#include "DOFVector.h" +#include "SurfaceRegion_ED.h" +#include "ElementRegion_ED.h" +#include "Projection.h" + +namespace AMDiS { + DataCollector::DataCollector(const FiniteElemSpace *feSpace, + DOFVector<double> *values, + int level, + Flag traverseFlag, + bool (*writeElem)(ElInfo*)) + : writeElem_(writeElem) + { + FUNCNAME("DataCollector::DataCollector"); + + TEST_EXIT(feSpace)("no feSpace\n"); + TEST_EXIT(values)("no value Vector\n"); + + // === get mesh === + mesh_ = feSpace->getMesh(); + + // === get admin === + localAdmin_ = const_cast<DOFAdmin*>(feSpace->getAdmin()); + + // === create vertex info vector === + vertexInfos_ = NEW DOFVector< ::std::list<VertexInfo> >(feSpace, "vertex infos"); + + interpPointInd_ = NEW DOFVector<int>(feSpace, "interpolation point indices"); + dofCoords_ = NEW DOFVector< ::std::list<WorldVector<double> > >(feSpace, "dof coords"); + + dim_ = mesh_->getDim(); + + nPreDofs_ = localAdmin_->getNumberOfPreDOFs(VERTEX); + nVertices_ = 0; + nElements_ = 0; + nInterpPoints_ = 0; + nConnections_ = 0; + + feSpace_ = feSpace; + values_ = values; + level_ = level; + traverseFlag_ = traverseFlag; + + elementDataCollected_ = false; + valueDataCollected_ = false; + periodicDataCollected_ = false; + } + + DataCollector::~DataCollector() + { + DELETE vertexInfos_; + DELETE interpPointInd_; + DELETE dofCoords_; + } + + int DataCollector::startCollectingElementData() + { + FUNCNAME("DataCollector::startCollectingElementData"); + + Flag flag = traverseFlag_; + flag |= + Mesh::FILL_NEIGH | + Mesh::FILL_COORDS | + Mesh::FILL_OPP_COORDS | + Mesh::FILL_BOUND; + + elements_.resize(0, dim_); + + TraverseStack stack; + + // Traverse elements to create continuous element indices + ElInfo *elInfo = stack.traverseFirst(mesh_, level_, flag); + while(elInfo) { + if(!writeElem_ || writeElem_(elInfo)) + outputIndices_[elInfo->getElement()->getIndex()] = nElements_++; + elInfo = stack.traverseNext(elInfo); + } + + // Traverse elements to create element information + elInfo = stack.traverseFirst(mesh_, level_, flag); + while(elInfo) { + if(!writeElem_ || writeElem_(elInfo)) + addElementData(elInfo); + elInfo = stack.traverseNext(elInfo); + } + + elementDataCollected_ = true; + + return(0); + } + + int DataCollector::startCollectingValueData() + { + FUNCNAME("DataCollector::startCollectingValueData"); + + DOFVector<int>::Iterator intPointIt(interpPointInd_, USED_DOFS); + for(intPointIt.reset(); !intPointIt.end(); ++intPointIt) { + (*intPointIt) = -1; + } + + interpPoints_.clear(); + + TraverseStack stack; + + // Traverse elements to add value information and to mark + // interpolation points. + ElInfo *elInfo = stack.traverseFirst(mesh_, + level_, + traverseFlag_ | Mesh::FILL_COORDS); + while(elInfo) { + if(!writeElem_ || writeElem_(elInfo)) + addValueData(elInfo); + elInfo = stack.traverseNext(elInfo); + } + + // Remove all interpolation marks and, instead, set to each + // interpolation point its continous index starting from 0. + int i = 0; + for(intPointIt.reset(); !intPointIt.end(); ++intPointIt) { + if(*intPointIt == -3) { + *intPointIt = i++; + } + } + + // Traverse elements to create interpolation values. + elInfo = stack.traverseFirst(mesh_, level_, traverseFlag_); + while(elInfo) { + if(!writeElem_ || writeElem_(elInfo)) + addInterpData(elInfo); + elInfo = stack.traverseNext(elInfo); + } + + valueDataCollected_ = true; + + return(0); + } + + int DataCollector::startCollectingPeriodicData() + { + FUNCNAME("DataCollector::startCollectingPeriodicData"); + + periodicConnections_.clear(); + + TraverseStack stack; + ElInfo *elInfo = stack.traverseFirst(mesh_, level_, traverseFlag_); + while(elInfo) { + if(!writeElem_ || writeElem_(elInfo)) { + LeafDataPeriodic *ldp = dynamic_cast<LeafDataPeriodic*> + (elInfo->getElement()-> + getElementData()-> + getElementData(PERIODIC)); + + if(ldp) { + nConnections_ += + dynamic_cast<LeafDataPeriodic*>(ldp)->getInfoList().size(); + } + + periodicConnections_.push_back(DimVec<bool>(dim_, DEFAULT_VALUE, false)); + } + elInfo = stack.traverseNext(elInfo); + } + + nConnections_ /= 2; + + periodicInfos_.clear(); + + Flag flag = traverseFlag_; + flag |= + Mesh::FILL_COORDS | + Mesh::FILL_OPP_COORDS| + Mesh::FILL_NEIGH | + Mesh::FILL_BOUND; + + elInfo = stack.traverseFirst(mesh_, level_, flag); + while(elInfo) { + if(!writeElem_ || writeElem_(elInfo)) + addPeriodicData(elInfo); + elInfo = stack.traverseNext(elInfo); + } + + periodicDataCollected_ = true; + + return(0); + } + + int DataCollector::addElementData(ElInfo* elInfo) + { + FUNCNAME("DataCollector::addElementData"); + + int i; + const DegreeOfFreedom **dof = elInfo->getElement()->getDOF(); + DegreeOfFreedom vertexDOF; + WorldVector<double> vertexCoords; + + // create ElementInfo + ElementInfo elementInfo(dim_); + + // read element region + ElementData *ed = + elInfo->getElement()->getElementData(ELEMENT_REGION); + + if(ed) { + elementInfo.elementRegion = dynamic_cast<ElementRegion_ED*>(ed)->getRegion(); + } else { + elementInfo.elementRegion = -1; + } + + // read surface regions to element info + ed = elInfo->getElement()->getElementData(SURFACE_REGION); + + elementInfo.surfaceRegions.set(-1); + + while(ed) { + SurfaceRegion_ED *sr = dynamic_cast<SurfaceRegion_ED*>(ed); + elementInfo.surfaceRegions[sr->getSide()] = sr->getRegion(); + ed = ed->getDecorated(SURFACE_REGION); + } + + // for all vertices + for(i = 0; i < dim_ + 1; i++) { + // get coords of this vertex + vertexCoords = elInfo->getCoord(i); + + // get dof index of this vertex + vertexDOF = dof[i][nPreDofs_]; + + // search for coords at this dof + ::std::list<VertexInfo>::iterator it = + find((*vertexInfos_)[vertexDOF].begin(), + (*vertexInfos_)[vertexDOF].end(), + vertexCoords); + + // coords not yet in list? + if(it == (*vertexInfos_)[vertexDOF].end()) { + // create new vertex info and increment number of vertices + VertexInfo newVertexInfo = {vertexCoords, nVertices_}; + + // add new vertex info to list + (*vertexInfos_)[vertexDOF].push_front(newVertexInfo); + + // set iterator to new vertex info + it = (*vertexInfos_)[vertexDOF].begin(); + + nVertices_++; + } + + // fill element info + elementInfo.vertexInfo[i] = it; + elementInfo.boundary[i] = elInfo->getBoundary(i); + elementInfo.projection[i] = elInfo->getProjection(i); + elementInfo.neighbour[i] = + elInfo->getNeighbour(i) ? + outputIndices_[elInfo->getNeighbour(i)->getIndex()] : + -1; + } + + if(dim_ == 3) { + elementInfo.type = (dynamic_cast<ElInfo3d*>(elInfo)->getType()); + } + + // remember element info + elements_.push_back(elementInfo); + + return(0); + } + + int DataCollector::addValueData(ElInfo *elInfo) + { + FUNCNAME("DataCollector::addValueData"); + + int i, j, k; + int node_offset, dof_offset, num_dofs, node, dof_index; + const DegreeOfFreedom **dof = elInfo->getElement()->getDOF(); + + /* vertex dofs */ + dof_offset = localAdmin_->getNumberOfPreDOFs(VERTEX); + + for (i = 0; i < mesh_->getGeo(VERTEX); i++) { + (*interpPointInd_)[dof[i][dof_offset]] = -2; // mark as vertex + + // get coords of this vertex + WorldVector<double> vertexCoords = elInfo->getCoord(i); + + // search for coords at this dof + ::std::list<WorldVector<double> >::iterator it = + find((*dofCoords_)[dof[i][dof_offset]].begin(), + (*dofCoords_)[dof[i][dof_offset]].end(), + vertexCoords); + + // coords not yet in list? + if(it == (*dofCoords_)[dof[i][dof_offset]].end()) { + // add new coords to list + (*dofCoords_)[dof[i][dof_offset]].push_back(vertexCoords); + } + } + + for(i = 1; i <= dim_; i++) { + num_dofs = localAdmin_->getNumberOfDOFs(INDEX_OF_DIM(i, dim_)); + node_offset = mesh_->getNode(INDEX_OF_DIM(i, dim_)); + dof_offset = localAdmin_->getNumberOfPreDOFs(INDEX_OF_DIM(i, dim_)); + for (j = 0; j < mesh_->getGeo(INDEX_OF_DIM(i, dim_)); j++) { + node = node_offset + j; + for(k = 0; k < num_dofs; k++) { + dof_index = dof_offset + k; + + if ((*interpPointInd_)[dof[node][dof_index]] == -1) { + // mark as interp. point + (*interpPointInd_)[dof[node][dof_index]] = -3; + nInterpPoints_++; + } + } + } + } + + return(0); + } + + int DataCollector::addInterpData(ElInfo *elInfo) + { + FUNCNAME("DataCollector::addInterpData"); + + int i, j, k; + int node_offset, dof_offset, num_dofs, node, dof_index; + const DegreeOfFreedom **dof = elInfo->getElement()->getDOF(); + + ::std::list<int> elemInterpPoints; + + elemInterpPoints.clear(); + + for(i = 1; i <= dim_; i++) { + num_dofs = localAdmin_->getNumberOfDOFs(INDEX_OF_DIM(i, dim_)); + node_offset = mesh_->getNode(INDEX_OF_DIM(i, dim_)); + dof_offset = localAdmin_->getNumberOfPreDOFs(INDEX_OF_DIM(i, dim_)); + for (j = 0; j < mesh_->getGeo(INDEX_OF_DIM(i, dim_)); j++) { + node = node_offset + j; + for(k = 0; k < num_dofs; k++) { + dof_index = dof_offset + k; + + elemInterpPoints.push_back((*interpPointInd_)[dof[node][dof_index]]); + } + } + } + + interpPoints_.push_back(elemInterpPoints); + + return(0); + } + + int DataCollector::addPeriodicData(ElInfo *elInfo) { + FUNCNAME("DataCollector::addPeriodicData"); + + LeafDataPeriodic *ldp = dynamic_cast<LeafDataPeriodic*> + (elInfo->getElement()-> + getElementData()-> + getElementData(PERIODIC)); + + if(ldp) { + ::std::list<LeafDataPeriodic::PeriodicInfo>::iterator it; + + for(it = dynamic_cast<LeafDataPeriodic*>(ldp)->getInfoList().begin(); + it != dynamic_cast<LeafDataPeriodic*>(ldp)->getInfoList().end(); + ++it) + { + int outputIndex = outputIndices_[elInfo->getElement()->getIndex()]; + int neighIndex = outputIndices_[elInfo-> + getNeighbour(it->elementSide)-> + getIndex()]; + + if(!periodicConnections_[outputIndex][it->elementSide]) { + PeriodicInfo periodicInfo; + + periodicInfo.mode = it->periodicMode; + periodicInfo.type = it->type; + periodicInfo.outputIndex = outputIndex; + periodicInfo.neighIndex = neighIndex; + periodicInfo.vertexMap.clear(); + + periodicConnections_[outputIndex][it->elementSide] = true; + periodicConnections_ + [neighIndex][elInfo->getOppVertex(it->elementSide)] = true; + + int index1, index2, dof1, dof2, i, j; + + for(i = 0; i < dim_; i++) { + index1 = + elInfo->getElement()->getVertexOfPosition(INDEX_OF_DIM(dim_ - 1, dim_), + it->elementSide, + i); + dof1 = elInfo->getElement()->getDOF(index1, nPreDofs_); + + for(j = 0; j < dim_; j++) { + index2 = + elInfo->getElement()->getVertexOfPosition(INDEX_OF_DIM(dim_ - 1, dim_), + elInfo->getOppVertex(it->elementSide), + j); + dof2 = elInfo->getNeighbour(it->elementSide)->getDOF(index2, nPreDofs_); + + if((dof1 == dof2) || (mesh_->associated(dof1, dof2))) { + periodicInfo.vertexMap[index1] = index2; + break; + } + } + } + + periodicInfos_.push_back(periodicInfo); + } + } + } + + return(0); + } + + ::std::list<ElementInfo>* DataCollector::getElementInfos() + { + if (!elementDataCollected_) { + startCollectingElementData(); + } + + return &elements_; + } + + DOFVector< ::std::list<VertexInfo> >* DataCollector::getVertexInfos() + { + if (!elementDataCollected_) { + startCollectingElementData(); + } + + return vertexInfos_; + } + + ::std::list<PeriodicInfo>* DataCollector::getPeriodicInfos() + { + if(!periodicDataCollected_) { + startCollectingPeriodicData(); + } + + return &periodicInfos_; + } + + int DataCollector::getNumberVertices() + { + if (!elementDataCollected_) { + startCollectingElementData(); + } + + return nVertices_; + } + + int DataCollector::getNumberElements() + { + if (!elementDataCollected_) { + startCollectingElementData(); + } + + return nElements_; + } + + int DataCollector::getNumberInterpPoints() + { + if (!valueDataCollected_) { + startCollectingValueData(); + } + + return nInterpPoints_; + } + + int DataCollector::getNumberConnections() + { + if(!periodicDataCollected_) { + startCollectingPeriodicData(); + } + + return nConnections_; + } + + const FiniteElemSpace* DataCollector::getFeSpace() + { + return feSpace_; + } + + Mesh* DataCollector::getMesh() + { + return mesh_; + } + + DOFVector<double>* DataCollector::getValues() + { + if (!valueDataCollected_) { + startCollectingValueData(); + } + + return values_; + } + + DOFVector< ::std::list<WorldVector<double> > >* DataCollector::getDofCoords() + { + if (!valueDataCollected_) { + startCollectingValueData(); + } + + return dofCoords_; + } + + DOFVector<int>* DataCollector::getInterpPointInd() + { + if (!valueDataCollected_) { + startCollectingValueData(); + } + + return interpPointInd_; + } + + ::std::list< ::std::list<int> >* DataCollector::getInterpPoints() + { + if (!valueDataCollected_) { + startCollectingValueData(); + } + + return &interpPoints_; + } +} diff --git a/AMDiS/src/DataCollector.h b/AMDiS/src/DataCollector.h new file mode 100644 index 0000000000000000000000000000000000000000..a531bad3fafc8d81d991ff87282951abc3c312ae --- /dev/null +++ b/AMDiS/src/DataCollector.h @@ -0,0 +1,290 @@ +// ============================================================================ +// == == +// == AMDiS - Adaptive multidimensional simulations == +// == == +// ============================================================================ +// == == +// == crystal growth group == +// == == +// == Stiftung caesar == +// == Ludwig-Erhard-Allee 2 == +// == 53175 Bonn == +// == germany == +// == == +// ============================================================================ +// == == +// == http://www.caesar.de/cg/AMDiS == +// == == +// ============================================================================ + +/** \file DataCollector.h */ + +#ifndef AMDIS_DATACOLLECTOR_H +#define AMDIS_DATACOLLECTOR_H + +#include <list> +#include <vector> + +#include "ElementInfo.h" +#include "VertexInfo.h" +#include "PeriodicInfo.h" +#include "MemoryManager.h" +#include "Mesh.h" + +namespace AMDiS { + class VertexInfo; + class ElementInfo; + class Mesh; + class FiniteElemSpace; + template<typename T> class DOFVector; + + /** + * \ingroup Output + * + * \brief + * Provides data collecting of element, vertex and value data + * for file writers. + */ + class DataCollector + { + public: + MEMORY_MANAGED(DataCollector); + + /** \brief + * Constructor. + */ + DataCollector(const FiniteElemSpace *feSpace, + DOFVector<double> *values, + int level = -1, + Flag traverseFlag = Mesh::CALL_LEAF_EL, + bool (*writeElem)(ElInfo*) = NULL); + + ~DataCollector(); + + /** \brief + * Returns list with element information. + */ + ::std::list<ElementInfo>* getElementInfos(); + + /** \brief + * Returns vector with vertex information. + */ + DOFVector< ::std::list<VertexInfo> >* getVertexInfos(); + + /** \brief + * Returns the finite element space of the problem. + */ + const FiniteElemSpace* getFeSpace(); + + /** \brief + * Returns vector with value information. + */ + DOFVector<double>* getValues(); + + /** \brief + * Returns vector with information about dof coordinates. + */ + DOFVector< ::std::list<WorldVector<double> > >* getDofCoords(); + + /** \brief + * Returns vector with information about interpolation + * point indexing. + */ + DOFVector<int>* getInterpPointInd(); + + /** \brief + * Returns list of interpolation point information. + */ + ::std::list< ::std::list<int> >* getInterpPoints(); + + /** \brief + * Returns list of information about periodics. + */ + ::std::list<PeriodicInfo>* getPeriodicInfos(); + + /** \brief + * Returns the number of vertices. + */ + int getNumberVertices(); + + /** \brief + * Returns the number of elements. + */ + int getNumberElements(); + + /** \brief + * Returns the number of interpolation points. + */ + int getNumberInterpPoints(); + + /** \brief + * Returns the number of connections. + */ + int getNumberConnections(); + + /** \brief + * Returns the mesh of the problem. + */ + Mesh* getMesh(); + + protected: + /** \brief + * Start collecting element and vertex data of the problem. + */ + int startCollectingElementData(); + + /** \brief + * Start collecting value data of the problem. + */ + int startCollectingValueData(); + + /** \brief + * Start collecting periodic data of the problem. + */ + int startCollectingPeriodicData(); + + /** \brief + * Adds information about one element and its vertices. + */ + int addElementData(ElInfo* elInfo); + + /** \brief + * Adds value information of one element. + */ + int addValueData(ElInfo *elInfo); + + /** \brief + * Adds information about interpolation points of vertices. + */ + int addInterpData(ElInfo *elInfo); + + /** \brief + * Adds value information of one element. + */ + int addPeriodicData(ElInfo *elInfo); + + + /** \brief + * Vector with vertex values + */ + DOFVector<double> *values_; + + /** \brief + * Level information for traversing the mesh. + */ + int level_; + + /** \brief + * Flags for traversing the mesh. + */ + Flag traverseFlag_; + + /** \brief + * + */ + const FiniteElemSpace *feSpace_; + + /** \brief + * Mesh that should be written + */ + Mesh *mesh_; + + /** \brief + * DOFAdmin of values + */ + DOFAdmin *localAdmin_; + + /** \brief + * vertex pre-dofs + */ + int nPreDofs_; + + /** \brief + * Number of vertices. + */ + int nVertices_; + + /** \brief + * Number of elements. + */ + int nElements_; + + /** \brief + * Total number of interpolation points. + */ + int nInterpPoints_; + + /** \brief + * Number of connections in periodic problems. + */ + int nConnections_; + + /** \brief + * Dimension of \ref mesh + */ + int dim_; + + /** \brief + * Maps internal element indices to global output indices. + */ + ::std::map<int, int> outputIndices_; + + /** \brief + * Global interpolation point indexing + */ + DOFVector<int> *interpPointInd_; + + /** \brief + * Stores for each simplex the interpolation points. + */ + ::std::list< ::std::list<int> > interpPoints_; + + /** \brief + * list of coords for each dof + */ + DOFVector< ::std::list<WorldVector<double> > > *dofCoords_; + + /** \brief + * List that stores an ElementInfo for each element. + */ + ::std::list<ElementInfo> elements_; + + /** \brief + * List stat stores information about all periodics. + */ + ::std::list<PeriodicInfo> periodicInfos_; + + /** \brief + * Stores a list of vertex infos for each dof. + */ + DOFVector< ::std::list<VertexInfo> > *vertexInfos_; + + /** \brief + * periodicConnections[i][j] stores whether the connection at side j of + * the element with output index i has already been written. + */ + ::std::vector<DimVec<bool> > periodicConnections_; + + /** \brief + * Stores if element data was collected before. + */ + bool elementDataCollected_; + + /** \brief + * Stores if value data was collected before. + */ + bool valueDataCollected_; + + /** \brief + * Stores if periodic data was collected before. + */ + bool periodicDataCollected_; + + /** \brief + * Pointer to a function which decides whether an element is considered. + */ + bool (*writeElem_)(ElInfo*); + }; +} + +#endif diff --git a/AMDiS/src/DiagonalPreconditioner.cc b/AMDiS/src/DiagonalPreconditioner.cc new file mode 100644 index 0000000000000000000000000000000000000000..a0bf3108d335ab7aa79561f8921daf4f17cddab1 --- /dev/null +++ b/AMDiS/src/DiagonalPreconditioner.cc @@ -0,0 +1,62 @@ +#include "DiagonalPreconditioner.h" +#include "FiniteElemSpace.h" +#include "DOFAdmin.h" +#include "DOFVector.h" +#include "DOFMatrix.h" +#include "DOFIterator.h" + +namespace AMDiS { + + void DiagonalPreconditioner::precon(DOFVector<double>* x) + { + FUNCNAME("DiagonalPreconditioner::precon()"); + + TEST_EXIT(matrix[row])("no matrix\n"); + TEST_EXIT(x)("no solution vector\n"); + + DOFMatrix::Iterator rowIterator((*matrix[row]), USED_DOFS); + DOFVector<double>::Iterator vecIterator(x, USED_DOFS); + + if (bound) { + ERROR_EXIT("not up to date\n"); + DOFVector<BoundaryType>::Iterator bIterator(const_cast<DOFVector<BoundaryType>*>(bound), USED_DOFS); + for (vecIterator.reset(), rowIterator.reset(), bIterator.reset(); + !vecIterator.end(); ++vecIterator, ++bIterator, ++rowIterator) { + // only non-dirichlet nodes will be preconditioned + if ((*bIterator) <= 0 && rowIterator->size() != 0) { + (*vecIterator) /= (*rowIterator)[0].entry; + } + } + } else { + for (vecIterator.reset(), rowIterator.reset(); + !vecIterator.end(); + ++vecIterator, ++rowIterator) + { + if (rowIterator->size() != 0) { + (*vecIterator) /= (*rowIterator)[0].entry; + } + } + } + } + + void DiagonalPreconditionerStd::precon(::std::vector<double>* x) + { + FUNCNAME("DiagonalPreconditionerStd::precon()"); + + TEST_EXIT(x)("no solution vector\n"); + TEST_EXIT(x->size() == matrix->size())("solution vector and matrix have different size\n"); + + ::std::vector<double>::iterator vecIt; + ::std::vector< ::std::vector<MatEntry> >::iterator matrixIt; + + for (vecIt = x->begin(), matrixIt = matrix->begin(); + vecIt < x->end(); + ++vecIt, ++matrixIt) + { + if (matrixIt->size() != 0) { + (*vecIt) /= (*matrixIt)[0].entry; + } + } + } + +} diff --git a/AMDiS/src/DiagonalPreconditioner.h b/AMDiS/src/DiagonalPreconditioner.h new file mode 100644 index 0000000000000000000000000000000000000000..8b6986c93cf5923bb4b64dd79f1f2427e787aeda --- /dev/null +++ b/AMDiS/src/DiagonalPreconditioner.h @@ -0,0 +1,133 @@ +// ============================================================================ +// == == +// == AMDiS - Adaptive multidimensional simulations == +// == == +// ============================================================================ +// == == +// == crystal growth group == +// == == +// == Stiftung caesar == +// == Ludwig-Erhard-Allee 2 == +// == 53175 Bonn == +// == germany == +// == == +// ============================================================================ +// == == +// == http://www.caesar.de/cg/AMDiS == +// == == +// ============================================================================ + +/** \file DiagonalPreconditioner.h */ + +#ifndef AMDIS_DIAGONAL_PRECONDITIONER_H +#define AMDIS_DIAGONAL_PRECONDITIONER_H + +#include <vector> +#include "Preconditioner.h" +#include "MemoryManager.h" +#include "CreatorInterface.h" + +namespace AMDiS { + + template<typename T> class DOFVector; + template<typename T> class OEMSolver; + + // ============================================================================ + // ===== class DiagonalPreconditioner ========================================= + // ============================================================================ + + /** + * \ingroup Solver + * + * \brief + * diagonal preconditioner. Implements the singleton design pattern to allow + * only one instance of this class. + */ + class DiagonalPreconditioner : public PreconditionerScal + { + public: + MEMORY_MANAGED(DiagonalPreconditioner); + + /** \brief + * Creator class used in the PreconditionerMap. + */ + class Creator : public PreconditionerScalCreator + { + public: + MEMORY_MANAGED(Creator); + + /** \brief + * Creates a DiagonalPreconditioner. + */ + PreconditionerScal *create() { + return NEW DiagonalPreconditioner(size, row); + }; + }; + + /** \brief + * Constructor. + */ + DiagonalPreconditioner(int size = 1, int row = 0) + : PreconditionerScal(size, row) + {}; + + /** \brief + * Destructor. + */ + virtual ~DiagonalPreconditioner() {}; + + /** \brief + * realisation of Preconditioner::init + */ + inline void init() { + FUNCNAME("DiagonalPreconditioner::init"); + TEST_EXIT(matrix[row])("no matrix\n"); + }; + + /** \brief + * realisation of Preconditioner::precon + */ + void precon(DOFVector<double> *x); + + /** \brief + * realisation of Preconditioner::exit + */ + inline void exit() {}; + }; + + + class DiagonalPreconditionerStd : public PreconditionerScalStd + { + public: + MEMORY_MANAGED(DiagonalPreconditionerStd); + + /** \brief + * Constructor. + */ + DiagonalPreconditionerStd() + {}; + + /** \brief + * Destructor. + */ + virtual ~DiagonalPreconditionerStd() {}; + + /** \brief + * realisation of Preconditioner::init + */ + inline void init() {}; + + /** \brief + * Realisation of Preconditioner::precon + */ + void precon(::std::vector<double>* x); + + /** \brief + * realisation of Preconditioner::exit + */ + inline void exit() {}; + }; + +} + +#endif // AMDIS_DIAGONAL_PRECONDITIONER_H diff --git a/AMDiS/src/DirectSolverInterface.h b/AMDiS/src/DirectSolverInterface.h new file mode 100644 index 0000000000000000000000000000000000000000..cb78c18cfd5535480136d2ab79c73181ffa2a2e6 --- /dev/null +++ b/AMDiS/src/DirectSolverInterface.h @@ -0,0 +1,22 @@ +#ifndef AMDIS_DIRECTSOLVERINTERFACE_H +#define AMDIS_DIRECTSOLVERINTERFACE_H + +namespace AMDiS { + + template<typename MatrixType, typename VectorType> + class DirectSolverInterface + { + public: + DirectSolverInterface() {}; + + virtual ~DirectSolverInterface() {}; + + virtual void solve(MatrixType &A, + VectorType &b, + VectorType &x, + int numUnknowns) = 0; + }; + +} + +#endif diff --git a/AMDiS/src/DirichletBC.cc b/AMDiS/src/DirichletBC.cc new file mode 100644 index 0000000000000000000000000000000000000000..24658e6335269610bf721d0f22d594bd2d906122 --- /dev/null +++ b/AMDiS/src/DirichletBC.cc @@ -0,0 +1,54 @@ +#include "DirichletBC.h" +#include "ElInfo.h" +#include "BasisFunction.h" +#include "DOFVector.h" +#include "DOFMatrix.h" + +namespace AMDiS { + + DirichletBC::DirichletBC(BoundaryType type, + DOFVectorBase<double> *vec) + : BoundaryCondition(type, vec->getFESpace()), f(NULL), dofVec(vec) + {} + + void DirichletBC::fillBoundaryCondition(DOFMatrix* matrix, + ElInfo* elInfo, + const DegreeOfFreedom* dofIndices, + const BoundaryType* localBound, + int nBasFcts) + { + FUNCNAME("DirichletBC::fillBoundaryCondition()"); + TEST_EXIT(matrix->getRowFESpace() == rowFESpace) + ("invalid row fe space\n"); + TEST_EXIT(matrix->getColFESpace() == colFESpace) + ("invalid col fe space\n"); + } + + void DirichletBC::fillBoundaryCondition(DOFVectorBase<double>* vector, + ElInfo* elInfo, + const DegreeOfFreedom* dofIndices, + const BoundaryType* localBound, + int nBasFcts) + { + FUNCNAME("DirichletBC::fillBoundaryCondition()"); + TEST_EXIT(vector->getFESpace() == rowFESpace) + ("invalid row fe space\n"); + + const BasisFunction *basFcts = rowFESpace->getBasisFcts(); + int i; + for(i=0; i < nBasFcts; i++) { + if(localBound[i] == boundaryType) { + if(f) { + DimVec<double> *coords = basFcts->getCoords(i); + const WorldVector<double> *worldCoords = elInfo->coordToWorld(*coords, NULL); + double fAtCoords = f ? (*f)(*worldCoords) : 0; + (*vector)[dofIndices[i]] = fAtCoords; + } + if(dofVec) { + (*vector)[dofIndices[i]] = (*dofVec)[dofIndices[i]]; + } + } + } + } + +} diff --git a/AMDiS/src/DirichletBC.h b/AMDiS/src/DirichletBC.h new file mode 100644 index 0000000000000000000000000000000000000000..040930b9a8c3297d88138413db6cbe6035be9ee8 --- /dev/null +++ b/AMDiS/src/DirichletBC.h @@ -0,0 +1,113 @@ +// ============================================================================ +// == == +// == AMDiS - Adaptive multidimensional simulations == +// == == +// ============================================================================ +// == == +// == crystal growth group == +// == == +// == Stiftung caesar == +// == Ludwig-Erhard-Allee 2 == +// == 53175 Bonn == +// == germany == +// == == +// ============================================================================ +// == == +// == http://www.caesar.de/cg/AMDiS == +// == == +// ============================================================================ + +/** \file DirichletBC.h */ + +#ifndef AMDIS_DIRICHLETBC_H +#define AMDIS_DIRICHLETBC_H + +#include "BoundaryCondition.h" +#include "AbstractFunction.h" + +namespace AMDiS { + + template<typename T> class DOFVectorBase; + class ElInfo; + + // ============================================================================ + // ===== class DirichletBC ==================================================== + // ============================================================================ + + /** + * \ingroup Assembler + * + * \brief + * Sub class of BoundaryCondition. Implements Dirichlet boundary conditions. + * A DOFVectors is set to a given value at a Dirichlet dof and in a DOFMatrix + * the row corresponding to a Dirichlet dof is replaced by a row containing + * only a 1.0 in the diagonal. + */ + class DirichletBC : public BoundaryCondition + { + public: + /** \brief + * Constructor. + */ + DirichletBC(BoundaryType type, + AbstractFunction<double, WorldVector<double> > *fct, + FiniteElemSpace *rowFESpace_) + : BoundaryCondition(type, rowFESpace_, NULL), f(fct), dofVec(NULL) + {}; + + /** \brief + * Constructor. + */ + DirichletBC(BoundaryType type, + DOFVectorBase<double> *vec); + + /** \brief + * Implementation of BoundaryCondition::fillBoundaryCondition(). + */ + void fillBoundaryCondition(DOFMatrix* matrix, + ElInfo* elInfo, + const DegreeOfFreedom* dofIndices, + const BoundaryType* localBound, + int nBasFcts); + + /** \brief + * Implementation of BoundaryCondition::fillBoundaryCondition(). + */ + void fillBoundaryCondition(DOFVectorBase<double>* vector, + ElInfo* elInfo, + const DegreeOfFreedom* dofIndices, + const BoundaryType* localBound, + int nBasFcts); + + /** \brief + * Implementation of BoundaryCondition::boundResidual(). + */ + double boundResidual(ElInfo*, + DOFMatrix *, + const DOFVectorBase<double>*) { return 0.0; }; + + bool isDirichlet() { return true; }; + + inline AbstractFunction<double, WorldVector<double> > *getF() { + return f; + }; + + inline DOFVectorBase<double> *getDOFVector() { + return dofVec; + }; + + protected: + /** \brief + * Function which is evaluated at world coords of Dirichlet dofs. + */ + AbstractFunction<double, WorldVector<double> > *f; + + /** \brief + * DOFVector containing the boundary values + */ + DOFVectorBase<double> *dofVec; + }; + +} + +#endif diff --git a/AMDiS/src/DualTraverse.cc b/AMDiS/src/DualTraverse.cc new file mode 100644 index 0000000000000000000000000000000000000000..80833addf298c4a761bbce37e3a7f474290cf17d --- /dev/null +++ b/AMDiS/src/DualTraverse.cc @@ -0,0 +1,160 @@ +#include "DualTraverse.h" +#include "Mesh.h" +#include "ElInfo.h" + +namespace AMDiS { + + bool DualTraverse::traverseFirst(Mesh *mesh1, + Mesh *mesh2, + int level1, + int level2, + Flag flag1, + Flag flag2, + ElInfo **elInfo1, + ElInfo **elInfo2, + ElInfo **elInfoSmall, + ElInfo **elInfoLarge) + { + // replace CALL_EL_LEVEL by CALL_MG_LEVEL (covers whole domain) + if(flag1.isSet(Mesh::CALL_EL_LEVEL)) { + flag1 &= ~Mesh::CALL_EL_LEVEL; + flag1 |= Mesh::CALL_MG_LEVEL; + level1_ = level1; + } else { + level1_ = -1; + } + + if(flag2.isSet(Mesh::CALL_EL_LEVEL)) { + flag2 &= ~Mesh::CALL_EL_LEVEL; + flag2 |= Mesh::CALL_MG_LEVEL; + level2_ = level2; + } else { + level2_ = -1; + } + + // replace CALL_LEAF_EL_LEVEL by CALL_MG_LEVEL (covers whole domain) + if(flag1.isSet(Mesh::CALL_LEAF_EL_LEVEL)) { + flag1 &= ~Mesh::CALL_LEAF_EL_LEVEL; + flag1 |= Mesh::CALL_MG_LEVEL; + level1_ = level1; + callLeafElLevel1_ = true; + } else { + level1_ = -1; + callLeafElLevel1_ = false; + } + + if(flag2.isSet(Mesh::CALL_LEAF_EL_LEVEL)) { + flag2 &= ~Mesh::CALL_LEAF_EL_LEVEL; + flag2 |= Mesh::CALL_MG_LEVEL; + level2_ = level2; + callLeafElLevel2_ = true; + } else { + level2_ = -1; + callLeafElLevel2_ = false; + } + + // call standard traverse + *elInfo1 = stack1.traverseFirst(mesh1, level1, flag1); + while(*elInfo1 != NULL && skipEl1(*elInfo1)) + *elInfo1 = stack1.traverseNext(*elInfo1); + *elInfo2 = stack2.traverseFirst(mesh2, level2, flag2); + while(*elInfo2 != NULL && skipEl2(*elInfo2)) + *elInfo2 = stack2.traverseNext(*elInfo2); + + // finished ? + if(*elInfo1 == NULL || *elInfo2 == NULL) { + TEST_EXIT(*elInfo1 == *elInfo2)("invalid dual traverse\n"); + return false; + } + + rest_ = 1.0; + + bool accepted = check(elInfo1, elInfo2, + elInfoSmall, elInfoLarge); + + // check for non domain covering level traverse + if(!accepted || + (level1_ != -1 && (*elInfo1)->getLevel() != level1_) || + (callLeafElLevel1_ && !(*elInfo1)->getElement()->isLeaf()) || + (level2_ != -1 && (*elInfo2)->getLevel() != level2_) || + (callLeafElLevel2_ && !(*elInfo2)->getElement()->isLeaf())) + { + return traverseNext(elInfo1, elInfo2, elInfoSmall, elInfoLarge); + } + + return true; + } + + bool DualTraverse::traverseNext(ElInfo **elInfo1, + ElInfo **elInfo2, + ElInfo **elInfoSmall, + ElInfo **elInfoLarge) + { + // call standard traverse + if(inc1_) { + do { + *elInfo1 = stack1.traverseNext(*elInfo1); + } while(*elInfo1 != NULL && skipEl1(*elInfo1)); + } + if(inc2_) { + do { + *elInfo2 = stack2.traverseNext(*elInfo2); + } while (*elInfo2 != NULL && skipEl2(*elInfo2)); + } + + // finished ? + if(*elInfo1 == NULL || *elInfo2 == NULL) { + TEST_EXIT(*elInfo1 == *elInfo2)("invalid dual traverse\n"); + return false; + } + + bool accepted = check(elInfo1, elInfo2, + elInfoSmall, elInfoLarge); + + // check for non domain covering level traverse + if(!accepted || + (level1_ != -1 && (*elInfo1)->getLevel() != level1_) || + (callLeafElLevel1_ && !(*elInfo1)->getElement()->isLeaf()) || + (level2_ != -1 && (*elInfo2)->getLevel() != level2_) || + (callLeafElLevel2_ && !(*elInfo2)->getElement()->isLeaf())) + { + return traverseNext(elInfo1, elInfo2, elInfoSmall, elInfoLarge); + } + + return true; + } + + void DualTraverse::prepareNextStep(ElInfo **elInfo1, + ElInfo **elInfo2, + ElInfo **elInfoSmall, + ElInfo **elInfoLarge) + { + // which is the smaller element ? + *elInfoSmall = + (*elInfo1)->getLevel() > (*elInfo2)->getLevel() ? + *elInfo1 : + *elInfo2; + *elInfoLarge = + (*elInfo1)->getLevel() <= (*elInfo2)->getLevel() ? + *elInfo1 : + *elInfo2; + + int smallLevel = (*elInfoSmall)->getLevel(); + int largeLevel = (*elInfoLarge)->getLevel(); + + // update rest + rest_ -= 1.0 / (1 << (smallLevel - largeLevel)); + + if(rest_ < 1e-32) { + // large element finished -> increment both elements + rest_ = 1.0; + inc1_ = true; + inc2_ = true; + } else { + // increment only small element + inc1_ = (*elInfo1 == *elInfoSmall) ? true : false; + inc2_ = (*elInfo2 == *elInfoSmall) ? true : false; + } + } + +} diff --git a/AMDiS/src/DualTraverse.h b/AMDiS/src/DualTraverse.h new file mode 100644 index 0000000000000000000000000000000000000000..78b76b9a673de77baa809576a23ef303ed7266d7 --- /dev/null +++ b/AMDiS/src/DualTraverse.h @@ -0,0 +1,148 @@ +// ============================================================================ +// == == +// == AMDiS - Adaptive multidimensional simulations == +// == == +// ============================================================================ +// == == +// == crystal growth group == +// == == +// == Stiftung caesar == +// == Ludwig-Erhard-Allee 2 == +// == 53175 Bonn == +// == germany == +// == == +// ============================================================================ +// == == +// == http://www.caesar.de/cg/AMDiS == +// == == +// ============================================================================ + +/** \file DualTraverse.h */ + +#ifndef AMDIS_DUALTRAVERSE_H +#define AMDIS_DUALTRAVERSE_H + +#include "Traverse.h" +#include "Flag.h" +#include "MemoryManager.h" + +namespace AMDiS { + + class Mesh; + class ElInfo; + + // ==================================================================== + // === class DualTraverse ============================================= + // ==================================================================== + + /** \brief + * Parallel traversal of two meshes. + */ + class DualTraverse + { + public: + MEMORY_MANAGED(DualTraverse); + + virtual ~DualTraverse() {}; + + /** \brief + * Start dual traversal + */ + bool traverseFirst(Mesh *mesh1, + Mesh *mesh2, + int level1, + int level2, + Flag flag1, + Flag flag2, + ElInfo **elInfo1, + ElInfo **elInfo2, + ElInfo **elInfoSmall, + ElInfo **elInfoLarge); + + /** \brief + * Get next ElInfo combination + */ + bool traverseNext(ElInfo **elInfoNext1, + ElInfo **elInfoNext2, + ElInfo **elInfoSmall, + ElInfo **elInfoLarge); + + virtual bool skipEl1(ElInfo *elInfo) { + return false; + }; + + virtual bool skipEl2(ElInfo *elInfo) { + return false; + }; + + virtual bool check(ElInfo **elInfo1, + ElInfo **elInfo2, + ElInfo **elInfoSmall, + ElInfo **elInfoLarge) + { + prepareNextStep(elInfo1, elInfo2, elInfoSmall, elInfoLarge); + return true; + }; + + protected: + /** \brief + * Determines smaller and larger element, determines which element(s) has to + * be incremented in the next step + */ + void prepareNextStep(ElInfo **elInfo1, + ElInfo **elInfo2, + ElInfo **elInfoSmall, + ElInfo **elInfoLarge); + + protected: + /** \brief + * stack for mesh 1 + */ + TraverseStack stack1; + + /** \brief + * stack for mesh 2 + */ + TraverseStack stack2; + + /** \brief + * used to determine whether all small elements belonging to the large + * element are traversed. + */ + double rest_; + + /** \brief + * true is element 1 should be incremented (set in prepareNextStep()) + */ + bool inc1_; + + /** \brief + * true is element 2 should be incremented (set in prepareNextStep()) + */ + bool inc2_; + + /** \brief + * for level traverse of mesh 1 + */ + int level1_; + + /** \brief + * for level traverse of mesh 2 + */ + int level2_; + + /** \brief + * for leaf element level traverse of mesh 1 + */ + bool callLeafElLevel1_; + + /** \brief + * for leaf element level traverse of mesh 2 + */ + bool callLeafElLevel2_; + }; + +} + +#endif + diff --git a/AMDiS/src/ElInfo.cc b/AMDiS/src/ElInfo.cc new file mode 100644 index 0000000000000000000000000000000000000000..1ad36621bdd501e8d638c3888e9babcdee881c9b --- /dev/null +++ b/AMDiS/src/ElInfo.cc @@ -0,0 +1,204 @@ +#include "ElInfo.h" +#include "BasisFunction.h" +#include "Element.h" +#include "Line.h" +#include "Triangle.h" +#include "Tetrahedron.h" +#include "FiniteElemSpace.h" +#include "Flag.h" +#include "MacroElement.h" +#include "Mesh.h" +#include "Global.h" +#include "FixVec.h" +#include "DOFVector.h" + +namespace AMDiS { + + int ElInfo::traverseId = -1; + int ElInfo::traverseIdCounter = 0; + + ElInfo::ElInfo(Mesh *aMesh) + : mesh_(aMesh), + element_(NULL), + parent_(NULL), + macroElement_(NULL), + coord_(mesh_->getDim(), NO_INIT), + boundary_(mesh_->getDim(), DEFAULT_VALUE, INTERIOR), + projection_(mesh_->getDim(), NO_INIT), + oppCoord_(mesh_->getDim(), NO_INIT), + neighbour_(mesh_->getDim(), NO_INIT), + oppVertex_(mesh_->getDim(), NO_INIT), + grdLambda_(mesh_->getDim(), NO_INIT) + //parametric_(false) + + { + projection_.set(NULL); + } + + ElInfo::~ElInfo() + { + } + + + /****************************************************************************/ + /* transform local coordintes l to world coordinates; if w is non NULL */ + /* store them at w otherwise return a pointer to some local static */ + /* area containing world coordintes */ + /****************************************************************************/ + const WorldVector<double> *ElInfo::coordToWorld(const DimVec<double>& l, + WorldVector<double>* w) const + + { + return coordToWorld(l, &coord_, w); + } + + const WorldVector<double> *ElInfo::coordToWorld(const DimVec<double>& l, + const FixVec<WorldVector<double>, VERTEX> *coords, + WorldVector<double> *w) + + { + static WorldVector<double> world; + double c; + WorldVector<double> *ret; + WorldVector<double> v; + int i, j; + + int dim = l.getSize() - 1; + int dimOfWorld = Global::getGeo(WORLD); + + + ret = w ? w : &world; + + v = (*coords)[0]; + c = l[0]; + for (j = 0; j < dimOfWorld; j++) + (*ret)[j] = c*v[j]; + + int vertices = Global::getGeo(VERTEX, dim); + + for (i = 1; i < vertices; i++) { + v = (*coords)[i]; + c = l[i]; + for (j = 0; j < dimOfWorld; j++) + (*ret)[j] += c*v[j]; + } + return ret; + } + + /****************************************************************************/ + /* compute volume of an element */ + /****************************************************************************/ + + double ElInfo::calcDet() const + { + testFlag(Mesh::FILL_COORDS); + return calcDet(coord_); + } + + double ElInfo::calcDet(const FixVec<WorldVector<double>, VERTEX> &coords) + { + FUNCNAME("ElInfo::calcDet"); + + int i; + int dim = coords.getSize() - 1; + int dow = Global::getGeo(WORLD); + + TEST_EXIT(dim <= dow)("dim > dow\n"); + + double det = 0.0; + + // --> changes Christina + if (dim == 0) + return 1.0; + // --> end: changes Christina + + // dim = dim of world + WorldVector<double> e1, e2, e3, v0; + + v0 = coords[0]; + + for (i = 0; i < dow; i++) { + e1[i] = coords[1][i] - v0[i]; + if(dim > 1) + e2[i] = coords[2][i] - v0[i]; + if(dim > 2) + e3[i] = coords[3][i] - v0[i]; + } + + switch(dow) { + case 1: + det = coords[1][0] - coords[0][0]; + break; + case 2: + if(dim == 1) { + det = norm(&e1); + } else { + det = e1[0]*e2[1] - e1[1]*e2[0]; + } + break; + case 3: + { + WorldVector<double> n; + + if(dim > 1) { + n[0] = e1[1]*e2[2] - e1[2]*e2[1]; + n[1] = e1[2]*e2[0] - e1[0]*e2[2]; + n[2] = e1[0]*e2[1] - e1[1]*e2[0]; + } + + if(dim == 1) { + det = norm(&e1); + } else if (dim == 2) { + det = norm(&n); + } else if (dim == 3) { + det = n[0]*e3[0]+n[1]*e3[1]+n[2]*e3[2]; + } else + ERROR_EXIT("not yet for problem dimension = %d",dim); + break; + } + default: + ERROR_EXIT("not yet for Global::getGeo(WORLD) = %d",dow); + } + + return abs(det); + } + + void ElInfo::testFlag(const Flag& flags) const + { + TEST_EXIT(fillFlag_.isSet(flags))("flag not set\n"); + } + + + void ElInfo::fillDetGrdLambda() + { + if(fillFlag_.isSet(Mesh::FILL_GRD_LAMBDA)) { + det_ = calcGrdLambda(grdLambda_); + } else { + if(fillFlag_.isSet(Mesh::FILL_DET)) { + det_ = calcDet(); + } + } + } + + BoundaryType ElInfo::getBoundary(GeoIndex pos, int i) + { + static int indexOffset[3][3] = { + { 0, 0, 0}, + { 3, 0, 0}, + {10, 4, 0} + }; + + int dim = mesh_->getDim(); + int posIndex = DIM_OF_INDEX(pos, dim); + int offset = indexOffset[dim-1][posIndex]; + + return boundary_[offset + i]; + } + + // BoundaryType ElInfo::getBoundOfBoundary(int i) const { + // WARNING("USE: getBoundary() instead of getBoundOfBoundary()\n"); + // TEST_EXIT(boundary_)("no boundary\n"); + // return (*boundary_)[i]; + // } + +} diff --git a/AMDiS/src/ElInfo.h b/AMDiS/src/ElInfo.h new file mode 100644 index 0000000000000000000000000000000000000000..179df71aaa0d7635d0c4b293cd2f15f81560438d --- /dev/null +++ b/AMDiS/src/ElInfo.h @@ -0,0 +1,588 @@ +// ============================================================================ +// == == +// == AMDiS - Adaptive multidimensional simulations == +// == == +// ============================================================================ +// == == +// == crystal growth group == +// == == +// == Stiftung caesar == +// == Ludwig-Erhard-Allee 2 == +// == 53175 Bonn == +// == germany == +// == == +// ============================================================================ +// == == +// == http://www.caesar.de/cg/AMDiS == +// == == +// ============================================================================ + +/** \file ElInfo.h */ + +#ifndef AMDIS_ELINFO_H +#define AMDIS_ELINFO_H + +// ============================================================================ +// ===== includes ============================================================= +// ============================================================================ +#include "Flag.h" +#include "Boundary.h" +#include "Global.h" +#include "FixVec.h" +#include "Element.h" + +namespace AMDiS { + + // ============================================================================ + // ===== forward declarations ================================================= + // ============================================================================ + class MacroElement; + class Mesh; + class Element; + class BasisFunction; + class Projection; + template<typename ReturnType, typename ArgumentType> class AbstractFunction; + + + // ============================================================================ + // ===== class ElInfo ========================================================= + // ============================================================================ + + /** \ingroup Traverse + * \brief + * An ElInfo object holds informations wich are not stored in the corresponding + * element. It is filled during mesh traversal by the traversal routines. + * A fill flag determines which informations should be filled and which elements + * should be visited. Since it is a + * pure virtual base class for the dimension speciefic ElInfo classes, it must + * not be instantiated directly. + * \see ElInfo1d \see ElInfo2d \see ElInfo3d + */ + + class ElInfo + { + // ===== construtors, destructors ============================================= + protected: + /** \brief + * Protected constructor. Avoids instatiation of the basis class + */ + ElInfo(); + + /** \brief + * Protected constructor. Avoids instatiation of the basis class. + * \param mesh pointer to the corresponding mesh. + */ + ElInfo(Mesh *mesh); + + public: + /** \brief + * Virtual destructor because ElInfo is pure virtual. + */ + virtual ~ElInfo(); + + /** \brief + * Assignement operator. + * \param rhs right hand side. + */ + ElInfo& operator=(const ElInfo& rhs) { + mesh_ = rhs.mesh_; + element_ = rhs.element_; + parent_ = rhs.parent_; + macroElement_ = rhs.macroElement_; + fillFlag_ = rhs.fillFlag_; + coord_ = rhs.coord_; + boundary_ = rhs.boundary_; + oppCoord_ = rhs.oppCoord_; + neighbour_ = rhs.neighbour_; + oppVertex_ = rhs.oppVertex_; + return *this; + }; + + // ===== getting-methods ====================================================== + public: + /** \name getting methods + * \{ + */ + + /** \brief + * Get ElInfo's \ref mesh_ + */ + inline Mesh* getMesh() const { + return mesh_; + }; + + /** \brief + * Get ElInfo's \ref macroElement_ + */ + inline MacroElement* getMacroElement() const { + return macroElement_; + }; + + /** \brief + * Get ElInfo's \ref element + */ + inline Element* getElement() const { + return element_; + }; + + /** \brief + * Get ElInfo's \ref parent_ + */ + inline Element* getParent() const { + return parent_; + }; + + /** \brief + * Get ElInfo's \ref fillFlag_ + */ + inline Flag getFillFlag() const { + return fillFlag_; + }; + + /** \brief + * Get ElInfo's \ref level_ + */ + inline unsigned char getLevel() const { + return level_; + }; + + + /** \brief + * Get ElInfo's \ref coord_[i]. This is a WorldVector<double> filled with the + * coordinates of the i-th vertex of element \ref el. + */ + inline WorldVector<double>& getCoord(int i) { + return coord_[i]; + }; + + /** \brief + * Get ElInfo's \ref coord_[i]. This is a WorldVector<double> filled with the + * coordinates of the i-th vertex of element \ref el. + */ + inline const WorldVector<double>& getCoord(int i) const { + return coord_[i]; + }; + + /** \brief + * Get ElInfo's \ref coord_. This is a FixVec<WorldVector<double> > filled with the + * coordinates of the all vertice of element \ref el. + */ + inline FixVec<WorldVector<double>,VERTEX>& getCoords() { + return coord_; + }; + + /** \brief + * Get ElInfo's \ref coord_. This is a FixVec<WorldVector<double> > filled with the + * coordinates of the all vertice of element \ref el. + */ + inline const FixVec<WorldVector<double>,VERTEX>& getCoords() const { + return coord_; + }; + + /** \brief + * Get ElInfo's \ref oppCoord_[i] + */ + inline WorldVector<double>& getOppCoord(int i) { + return oppCoord_[i]; + }; + + /** \brief + * Get ElInfo's \ref boundary_[i] + */ + virtual BoundaryType getBoundary(int i) const { + return boundary_[i]; + }; + + /** \brief + * Get boundary type of i-th vertex/edge/face (pos). + */ + BoundaryType getBoundary(GeoIndex pos, int i); + + /** \brief + * Get ElInfo's \ref neighbour_[i] + */ + inline Element* getNeighbour(int i) const { + return neighbour_[i]; + }; + + /** \brief + * Get ElInfo's \ref oppVertex_[i] + */ + inline unsigned char getOppVertex(int i) const { + return oppVertex_[i]; + }; + + virtual int getSideOfNeighbour(int i) { + return oppVertex_[i]; + }; + + /** \brief + * Get ElInfo's \ref det_ + */ + inline double getDet() const { + return det_; + }; + + /** \brief + * Returns \ref grdLambda_ + */ + inline const DimVec<WorldVector<double> >& getGrdLambda() const { + return grdLambda_; + }; + + /** \brief + * Returns \ref projection_[i] + */ + inline Projection *getProjection(int i) const { + return projection_[i]; + }; + + /** \brief + * Returns \ref parametric_ + */ + inline bool getParametric() { + return parametric_; + }; + + /** \} */ + + // ===== setting-methods ====================================================== + + /** \name setting methods + * \{ + */ + + /** \brief + * Set ElInfo's \ref mesh_ + */ + inline void setMesh(Mesh* aMesh) { + mesh_ = aMesh; + }; + + /** \brief + * Set ElInfo's \ref macroElement_ + */ + inline void setMacroElement(MacroElement* mel) { + macroElement_ = mel; + }; + + /** \brief + * Set ElInfo's \ref element + */ + inline void setElement(Element* elem) { + element_ = elem; + }; + + /** \brief + * Set ElInfo's \ref parent_ + */ + inline void setParent(Element* elem) { + parent_ = elem; + }; + + /** \brief + * Set ElInfo's \ref fillFlag_ + */ + inline void setFillFlag(Flag flag) { + fillFlag_ = flag; + }; + + /** \brief + * Sets ElInfo's \ref coord_[i]. + */ + inline void setCoord(int i,WorldVector<double>& coord) { + coord_[i] = coord; + }; + + /** \brief + * Sets ElInfo's \ref coord. + */ + inline void setCoords(FixVec<WorldVector<double>,VERTEX >& coords) { + coord_ = coords; + }; + + /** \brief + * Set ElInfo's \ref level_ + */ + inline void setLevel(int l) { + level_ = l; + }; + + /** \brief + * Set ElInfo's \ref boundary_[i] + */ + inline void setBoundary(int i, BoundaryType t) { + boundary_[i] = newBound(boundary_[i], t); + }; + + /** \brief + * Set \ref projection_[i] = p + */ + inline void setProjection(int i, Projection *p) { + projection_[i] = p; + }; + + /** \brief + * Set \ref det_ = d + */ + inline void setDet(double d) { + det_ = d; + }; + + /** \brief + * Set \ref parametric_ = param + */ + inline void setParametric(bool param) { + parametric_ = param; + }; + + /** \} */ + + // ===== other public methods ================================================= + + + /** \brief + * Returns the absolute value of the determinant of the affine linear + * parametrization's Jacobian + */ + virtual double calcDet() const; + + /** \brief + * Used by non static method \ref calcDet(). Calculates the determinant + * for a given vector of vertex coordinates. + */ + static double calcDet(const FixVec<WorldVector<double>, VERTEX> &coords); + + /** \brief + * Checks whether flag is set in ElInfo's \ref fillFlag_. If not, the program + * exits. + */ + void testFlag(const Flag& flag) const; + + /** \brief + * Returns a pointer to a vector, wich contains the world coordinates + * of a point in barycentric coordinates lambda with respect to \ref element. + * If world is not NULL the world coordinates are stored in this vector. + * Otherwise the function itself provides memory for this vector. In this + * case the vector is overwritten during the next call of coordToWorld. + */ + virtual const WorldVector<double> + *coordToWorld(const DimVec<double>& lambda, + WorldVector<double>* world) const; + + + /** \brief + * Fills ElInfo's \ref det_ and \ref grdLambda_ entries. + */ + virtual void fillDetGrdLambda(); + + // ===== pure virtual functions. Must be overriden in sub-classes ============ + + /** \brief + * Returns a pointer to a vector, which contains the barycentric coordinates + * with respect to \ref element of a point with world coordinates world. + * The barycentric coordinates are stored in lambda. + * pure virtual => must be overriden in sub-class. + */ + virtual const int worldToCoord(const WorldVector<double>& world, + DimVec<double>* lambda) const = 0; + + /** \brief + * Fills this ElInfo with macro element information of mel. + * pure virtual => must be overriden in sub-class. + */ + virtual void fillMacroInfo(const MacroElement *mel) = 0; + + /** \brief + * Fills this ElInfo for the child ichild using hierarchy information and + * parent data parentInfo. + * pure virtual => must be overriden in sub-class. + */ + virtual void fillElInfo(int ichild, const ElInfo *parentInfo)=0; + + /** \brief + * calculates the Jacobian of the barycentric coordinates on \element and stores + * the matrix in grd_lam. The return value of the function is the absolute + * value of the determinant of the affine linear paraetrization's Jacobian. + * pure virtual => must be overriden in sub-class. + */ + virtual double calcGrdLambda(DimVec<WorldVector<double> >& grd_lam) const = 0; + + /** \brief + * calculates a normal of the given side (1d,2d: edge, 3d: face) of \ref element. + * Returns the absolute value of the determinant of the + * transformation to the reference element. + * pure virtual => must be overriden in sub-class. + */ + virtual double getNormal(int side, WorldVector<double> &normal) const = 0; + + + /** \brief + * calculates a normal of the element in dim of world = dim + 1. + * Returns the absolute value of the determinant of the + * transformation to the reference element. + * pure virtual => must be overriden in sub-class. + */ + virtual double getElementNormal(WorldVector<double> &elementNormal) const + { + FUNCNAME("ElInfo::getElementNormal"); + ERROR("virtual function not implemented in this sub-class "); + + return(0.0); + }; + + + + + + // ===== protected methods ==================================================== + + protected: + /** \brief + * Used by ElInfo's coordToWorld(). + * \param lambda barycentric coordinates which should be converted. + * \param coords coords of element vertices. + * \param world world coordinates corresponding to lambda + */ + static const WorldVector<double> + *coordToWorld(const DimVec<double>& lambda, + const FixVec<WorldVector<double>, VERTEX> *coords, + WorldVector<double> *world); + + // ===== protected members ==================================================== + protected: + + /** \brief + * Pointer to the current mesh + */ + Mesh *mesh_; + + /** \brief + * Pointer to the current element + */ + Element *element_; + + /** \brief + * \ref element is child of element parent_ + */ + Element *parent_; + + /** \brief + * \ref element is an element of the binary tree located at MacroElement + * macroElement_ + */ + MacroElement *macroElement_; + + /** \brief + * Indicates wich elements will be called and wich information should be + * present while mesh traversal. + */ + Flag fillFlag_; + + /** \brief + * Level of the element. The level is zero for macro elements and the level + * of the children is (level of the parent + 1). level_ is filled always by + * the traversal routines. + */ + unsigned char level_; + + /** \brief + * \ref coord_[i] is a WorldVector<double> storing the world coordinates of the + * i-th vertex of element \ref element. + */ + FixVec<WorldVector<double>,VERTEX> coord_; + + /** \brief + * boundary_[i] is the BoundaryType of the i-th edge/face + * for i=0,...,N_NEIGH - 1. In 3d + * (*boundary_)[N_FACES + i] is a pointer to the Boundary + * object of the i-th edge, for i=0,..,N_EDGES - 1. It is + * a pointer to NULL for an interior edge/face. + */ + FixVec<BoundaryType ,BOUNDARY> boundary_; + + /** \brief + * Vector storing pointers to projections for each face, edge, vertex. + */ + FixVec<Projection*, PROJECTION> projection_; + + /** \brief + * oppCoord_[i] coordinates of the i-th neighbour vertex opposite the + * common edge/face. + */ + FixVec<WorldVector<double>,NEIGH> oppCoord_; + + /** \brief + * neighbour_[i] pointer to the element at the edge/face with local index i. + * It is a pointer to NULL for boundary edges/faces. + */ + FixVec<Element*,NEIGH> neighbour_; + + /** \brief + * oppVertex_[i] is undefined if neighbour_[i] is a pointer to NULL. + * Otherwise it is the local index of the neighbour's vertex opposite the + * common edge/face. + */ + FixVec<unsigned char,NEIGH> oppVertex_; + + /** \brief + * Elements determinant. + */ + double det_; + + /** \brief + * Gradient of lambda. + */ + DimVec<WorldVector<double> > grdLambda_; + + /** \brief + * True, if this elInfo stores parametrized information. Flase, otherwise. + */ + bool parametric_; + + // ===== static public members ================================================ + public: + /** \brief + * child_vertex[el_type][child][i] = father's local vertex index of new + * vertex i. 4 stands for the newly generated vertex . + */ + static const int childVertex[3][2][4]; + + /** \brief + *child_edge[el_type][child][i] = father's local edge index of new edge i. + * new edge 2 is half of old edge 0, new edges 4,5 are really new edges, and + * value is different: child_edge[][][4,5] = index of same edge in other + * child. + */ + static const int childEdge[3][2][6]; + + /** \brief + * Used to determine to which traverse an ElInfo belongs + */ + static int traverseId; + + /** \brief + * Used to determine to which traverse an ElInfo belongs + */ + static int traverseIdCounter; + + friend class ElInfo1d; + friend class ElInfo2d; + friend class ElInfo3d; + }; + +} + +#include "ElInfo1d.h" +#include "ElInfo2d.h" +#include "ElInfo3d.h" + +#endif // AMDIS_ELINFO_H + + + + + + + + diff --git a/AMDiS/src/ElInfo1d.cc b/AMDiS/src/ElInfo1d.cc new file mode 100644 index 0000000000000000000000000000000000000000..6a249bbf635c9b425e6e46c395c1de7716c75296 --- /dev/null +++ b/AMDiS/src/ElInfo1d.cc @@ -0,0 +1,327 @@ +#include "ElInfo1d.h" +#include "BasisFunction.h" +#include "Element.h" +#include "Line.h" +#include "Triangle.h" +#include "Tetrahedron.h" +#include "FiniteElemSpace.h" +#include "Flag.h" +#include "MacroElement.h" +#include "Mesh.h" +#include "Global.h" +#include "FixVec.h" +#include "DOFVector.h" + +namespace AMDiS { + + void ElInfo1d::fillMacroInfo(const MacroElement * mel) + { + FUNCNAME("ElInfo1d::fillMacroInfo"); + Element *nb; + MacroElement *mnb; + int i; + + macroElement_ = const_cast<MacroElement*>( mel); + element_ = const_cast<Element*>( mel->getElement()); + parent_ = NULL; + level_ = 0; + + int vertices = mesh_->getGeo(VERTEX); + + if (fillFlag_.isSet(Mesh::FILL_COORDS) || fillFlag_.isSet(Mesh::FILL_DET) || + fillFlag_.isSet(Mesh::FILL_GRD_LAMBDA)) + { + for (i = 0; i < vertices; i++) + { + coord_[i] = mel->coord[i]; + } + } + + // if(fillFlag_.isSet(Mesh::FILL_DET) || fillFlag_.isSet(Mesh::FILL_GRD_LAMBDA)) { + // det = elGrdLambda(*Lambda); + // } + + if (fillFlag_.isSet(Mesh::FILL_NEIGH) || fillFlag_.isSet(Mesh::FILL_OPP_COORDS)) + { + WorldVector<double> oppC; + + int neighbours = mesh_->getGeo(NEIGH); + for (i = 0; i < neighbours; i++) + { + nb = NULL; + if ((mnb = const_cast<MacroElement*>( mel->getNeighbour(i)))) + { + if (fillFlag_.isSet(Mesh::FILL_OPP_COORDS)) + { + oppC = mnb->coord[i]; + } + + nb = const_cast<Element*>( mnb->getElement()); + + while (!(nb->isLeaf())) // make nb nearest element + { + if (fillFlag_.isSet(Mesh::FILL_OPP_COORDS)) + { + if (nb->getNewCoord(-1)) { + oppC = *(nb->getNewCoord()); + } else { + oppC = (mel->coord[i] + oppC) * 0.5; + } + } + nb = const_cast<Element*>( nb->getChild(1-i)); + } + + if (fillFlag_.isSet(Mesh::FILL_OPP_COORDS)) + { + oppCoord_[i] = oppC; + } + } + neighbour_[i] = nb; + oppVertex_[i] = nb ? i : -1; + } + } + + if (fillFlag_.isSet(Mesh::FILL_BOUND) ) { + for (i = 0; i < vertices; i++) + boundary_[i] = mel->getBoundary(i); + + for(i = 0; i < element_->getGeo(PROJECTION); i++) { + projection_[i] = mel->getProjection(i); + } + } + } + + /****************************************************************************/ + /* compute gradients of basis functions on element; return the absulute */ + /* value of the determinante from the transformation to the reference */ + /* element */ + /****************************************************************************/ + double ElInfo1d::calcGrdLambda(DimVec<WorldVector<double> >& grd_lam) const + { + FUNCNAME("ElInfo1d::calcGrdLambda\n"); + + int i; + double adet2; + + testFlag(Mesh::FILL_COORDS); + + WorldVector<double> e; + + e = coord_[1]; e -= coord_[0]; + adet2 = e*e; + + if (adet2 < 1.0E-15) { + MSG("det*det = %lf\n", adet2); + for (i = 0; i <= 1; i++) + grd_lam[i] = 0.0; + } else { + grd_lam[1] = e * (1.0/adet2); + grd_lam[0] = grd_lam[1] * (-1.0); + } + + return sqrt(adet2); + } + + const int ElInfo1d::worldToCoord(const WorldVector<double>& x, + DimVec<double>* lambda) const + { + FUNCNAME("ElInfo1d::worldToCoord"); + double lmin; + double a = coord_[0][0]; + double length = (coord_[1][0] - a); + int i, j, k; + + int dim = mesh_->getDim(); + + static DimVec<double> vec(dim, NO_INIT); + + TEST_EXIT(lambda)("lambda must not be NULL\n"); + TEST_EXIT(dim==1)("dim!=1\n"); + TEST_EXIT(Global::getGeo(WORLD)==dim)("not yet for DIM != DIM_OF_WORLD\n"); + + if (abs(length) < DBL_TOL) { + ERROR_EXIT("length = %le; abort\n", length); + return 0; + } + + (*lambda)[1] = (x[0]-a)/length; + (*lambda)[0] = 1.0 - (*lambda)[1]; + + k = -1; + lmin = 0.0; + j = 0; + for (i = 0; i <= dim; i++) { + if ((*lambda)[i] < -1.E-5) { + if ((*lambda)[i] < lmin) { + k = i; + lmin = (*lambda)[i]; + } + j++; + } + } + + return k; + } + + /****************************************************************************/ + /* calculate a facenormal of edge side of a triangle with coordinates */ + /* coord; return the absulute value of the determinant from the */ + /* transformation to the reference element */ + /****************************************************************************/ + double ElInfo1d::getNormal(int side, WorldVector<double> &normal) const + { + double det; + normal = coord_[side] - coord_[(side + 1) % 2]; + det = norm(&normal); + TEST_EXIT(det > 1.e-30)("det = 0 on side %d\n", side); + normal *= 1.0/det; + + // int dow = Global::getGeo(WORLD); + // double det = 0.0; + + // if(dow == 1){ + // normal[0] = side ? 1.0 : -1.0; + // det = 1.0; + // } + // else{ + // normal = side ? coord_[1] - coord_[0] : coord_[0] - coord_[1]; + // det = norm(&normal); + // normal *= 1.0 / det; + // det = 1.0; + // } + + return(det); + } + + + /****************************************************************************/ + /* calculate the normal of the element for dim of world = 2 */ + /* return the absulute value of the determinant from the */ + /* transformation to the reference element */ + /****************************************************************************/ + double ElInfo1d::getElementNormal( WorldVector<double> &elementNormal) const + { + FUNCNAME("ElInfo::getElementNormal"); + double det = 0.0; + int dow = Global::getGeo(WORLD); + + TEST_EXIT(dow = 2)(" element normal only well defined for DIM_OF_WORLD = DIM + 1 !!"); + + elementNormal[0] = coord_[1][1] - coord_[0][1]; + elementNormal[1] = coord_[0][0] - coord_[1][0]; + + det = norm(&elementNormal); + + TEST_EXIT(det > 1.e-30)("det = 0"); + + elementNormal *= 1.0 / det; + + return(det); + } + + + void ElInfo1d::fillElInfo(int ichild, const ElInfo *elinfo_old) + { + FUNCNAME("ElInfo1d::fillElInfo"); + int i; //, j; + Element *nb; + Element *elem = elinfo_old->element_; + + TEST_EXIT(elem->getChild(0))("no children?\n"); + TEST_EXIT((element_ = const_cast<Element*>( elem->getChild(ichild)))) + ("missing child %d?\n", ichild); + + macroElement_ = elinfo_old->macroElement_; + fillFlag_ = elinfo_old->fillFlag_; + parent_ = elem; + level_ = elinfo_old->level_ + 1; + + //int dow = Global::getGeo(WORLD); + int neighbours = mesh_->getGeo(NEIGH); + + if (fillFlag_.isSet(Mesh::FILL_COORDS) || fillFlag_.isSet(Mesh::FILL_DET) || + fillFlag_.isSet(Mesh::FILL_GRD_LAMBDA)) + { + const FixVec<WorldVector<double>, VERTEX> *old_coord = &(elinfo_old->coord_); + + coord_[ichild] = (*old_coord)[ichild]; + if (elem->getNewCoord(-1)) { + coord_[1-ichild] = *(elem->getNewCoord()); + } else { + coord_[1-ichild] = ((*old_coord)[0] + (*old_coord)[1]) * 0.5; + } + } + + // if(fillFlag_.isSet(Mesh::FILL_DET) || fillFlag_.isSet(Mesh::FILL_GRD_LAMBDA)) { + // det = calcGrdLambda(*Lambda); + // } + + if (fillFlag_.isSet(Mesh::FILL_NEIGH) || fillFlag_.isSet(Mesh::FILL_OPP_COORDS)) + { + WorldVector<double> oppC; + + TEST_EXIT(fillFlag_.isSet(Mesh::FILL_COORDS)) + ("FILL_OPP_COORDS only with FILL_COORDS\n"); + + for (i = 0; i < neighbours; i++) + { + if (i != ichild) + { + nb = const_cast<Element*>( elem->getChild(1-ichild)); + // if (nb && fillFlag_.isSet(Mesh::FILL_OPP_COORDS)) + if ( fillFlag_.isSet(Mesh::FILL_OPP_COORDS)) + { + oppC = elinfo_old->coord_[i]; + } + } + else + { + nb = const_cast<Element*>( elinfo_old->getNeighbour(i)); + + if (nb && fillFlag_.isSet(Mesh::FILL_OPP_COORDS)) + { + oppC = elinfo_old->oppCoord_[i]; + } + } + + if (nb) + { + while (nb->getChild(0)) // make nb nearest element + { + if (fillFlag_.isSet(Mesh::FILL_OPP_COORDS)) + { + if (nb->getNewCoord(-1)) { + oppC = *(nb->getNewCoord()); + } else { + oppC = (coord_[i] + oppC) * 0.5; + } + } + nb = const_cast<Element*>( nb->getChild(1-i)); + } + + if (fillFlag_.isSet(Mesh::FILL_OPP_COORDS)) + { + oppCoord_[i] = oppC; + } + } + neighbour_[i] = nb; + oppVertex_[i] = nb ? i : -1; + } + } + + if (fillFlag_.isSet(Mesh::FILL_BOUND)) + { + boundary_[ichild] = elinfo_old->getBoundary(ichild); + boundary_[1-ichild] = INTERIOR; + + if(elinfo_old->getProjection(0) && + elinfo_old->getProjection(0)->getType() == VOLUME_PROJECTION) + { + projection_[0] = elinfo_old->getProjection(0); + } + } + + return; + } + +} diff --git a/AMDiS/src/ElInfo1d.h b/AMDiS/src/ElInfo1d.h new file mode 100644 index 0000000000000000000000000000000000000000..bc46f1694e3919e2301d11f2959a243bfe01c24b --- /dev/null +++ b/AMDiS/src/ElInfo1d.h @@ -0,0 +1,83 @@ +// ============================================================================ +// == == +// == AMDiS - Adaptive multidimensional simulations == +// == == +// ============================================================================ +// == == +// == crystal growth group == +// == == +// == Stiftung caesar == +// == Ludwig-Erhard-Allee 2 == +// == 53175 Bonn == +// == germany == +// == == +// ============================================================================ +// == == +// == http://www.caesar.de/cg/AMDiS == +// == == +// ============================================================================ + +/** \file ElInfo1d.h */ + +#ifndef AMDIS_ELINFO1D_H +#define AMDIS_ELINFO1D_H + +#include "ElInfo.h" +#include "MemoryManager.h" + +namespace AMDiS { + + // ============================================================================ + // ===== class ElInfo1d ======================================================= + // ============================================================================ + + /** \ingroup Traverse + * \brief + * ElInfo class for 1-dimensional elements (\ref Line). + */ + class ElInfo1d : public ElInfo + { + public: + MEMORY_MANAGED(ElInfo1d); + + /** \brief + * Constructor. Calls ElInfo's protected Constructor. + */ + ElInfo1d(Mesh* aMesh) : ElInfo(aMesh) {}; + + /** \brief + * 1-dimensional realisation of ElInfo's fillElInfo method. + */ + void fillElInfo(int ichild, const ElInfo *elinfo_old); + + /** \brief + * 1-dimensional realisation of ElInfo's fillMacroInfo method. + */ + void fillMacroInfo(const MacroElement *); + + /** \brief + * 1-dimensional realisation of ElInfo's worldToCoord method. + */ + const int worldToCoord(const WorldVector<double>& w, DimVec<double>* l) const; + + /** \brief + * 1-dimensional realisation of ElInfo's calcGrdLambda method. + */ + double calcGrdLambda(DimVec<WorldVector<double> >& grd_lam) const; + + /** \brief + * 1-dimensional realisation of ElInfo's getNormal method. + */ + double getNormal(int side, WorldVector<double> &normal) const; + + /** \brief + * 1-dimensional realisation of ElInfo's getElementNormal method. + */ + double getElementNormal( WorldVector<double> &normal) const; + + int getSideOfNeighbour(int i) { return (i+1)%2; }; + }; + +} + +#endif // AMDIS_ELINFO1D_H diff --git a/AMDiS/src/ElInfo2d.cc b/AMDiS/src/ElInfo2d.cc new file mode 100644 index 0000000000000000000000000000000000000000..0370a1f3331e46f5832a9dabfb41357ea047523b --- /dev/null +++ b/AMDiS/src/ElInfo2d.cc @@ -0,0 +1,533 @@ +#include "ElInfo2d.h" +#include "BasisFunction.h" +#include "Element.h" +#include "Line.h" +#include "Triangle.h" +#include "Tetrahedron.h" +#include "FiniteElemSpace.h" +#include "Flag.h" +#include "MacroElement.h" +#include "Mesh.h" +#include "Global.h" +#include "FixVec.h" +#include "DOFVector.h" + +namespace AMDiS { + + void ElInfo2d::fillMacroInfo(const MacroElement * mel) + { + FUNCNAME("ElInfo::fillMacroInfo"); + + int i, k; + Element *nb; + MacroElement *mnb; +#if 1 // #if !NEIGH_IN_EL + bool fill_opp_coords; +#endif + + + macroElement_ = const_cast<MacroElement*>(mel); + element_ = const_cast<Element*>(mel->getElement()); + parent_ = NULL; + level_ = 0; + + int vertices = mesh_->getGeo(VERTEX); + //int edges = mesh_->getGeo(EDGE); + + if (fillFlag_.isSet(Mesh::FILL_COORDS) || + fillFlag_.isSet(Mesh::FILL_DET) || + fillFlag_.isSet(Mesh::FILL_GRD_LAMBDA)) { + for (i=0; i<vertices; i++) { + coord_[i] = mel->coord[i]; + } + } + + // if(fillFlag_.isSet(Mesh::FILL_DET) || fillFlag_.isSet(Mesh::FILL_GRD_LAMBDA)) { + // det = calcGrdLambda(*Lambda); + // } + + int neighbours = mesh_->getGeo(NEIGH); + + if(fillFlag_.isSet(Mesh::FILL_OPP_COORDS) || + fillFlag_.isSet(Mesh::FILL_NEIGH)) + { + fill_opp_coords = (fillFlag_.isSet(Mesh::FILL_OPP_COORDS)); + + for (i = 0; i < neighbours; i++) { + if ((mnb = mel->getNeighbour(i))) { + neighbour_[i] = mel->getNeighbour(i)->getElement(); + nb = const_cast<Element*>(neighbour_[i]); + k = oppVertex_[i] = mel->getOppVertex(i); + if (nb->getFirstChild() && (k != 2)) { // make nb nearest el. + nb = neighbour_[i] = + (k==0) ? + nb->getSecondChild() : + nb->getFirstChild(); + k = oppVertex_[i] = 2; + if (fill_opp_coords) { + if (nb->getNewCoord(-1)) { + oppCoord_[i] = *(nb->getNewCoord()); + } else { + oppCoord_[i] = + (mnb->coord[0] + mnb->coord[1]) * 0.5; + } + } + } else { + if (fill_opp_coords) { + oppCoord_[i] = mnb->coord[k]; + } + } + } else { + neighbour_[i] = NULL; + } + } + } + + if (fillFlag_.isSet(Mesh::FILL_BOUND)) { + + // for (i = 0; i < vertices; i++) + // (*bound)[i] = mel->getBound(i); + + for (i = 0; i < element_->getGeo(BOUNDARY) ; i++) { + boundary_[i] = mel->getBoundary(i); + } + + for(i = 0; i < element_->getGeo(PROJECTION); i++) { + projection_[i] = mel->getProjection(i); + } + } + } + + + /****************************************************************************/ + /* fill ElInfo structure for one child of an element */ + /****************************************************************************/ + + void ElInfo2d::fillElInfo(int ichild, const ElInfo *elinfo_old) + { + FUNCNAME("ElInfo::fillElInfo"); + Element *elem = elinfo_old->element_; + int j; + Element *nb; + + Flag fill_flag = elinfo_old->fillFlag_; + bool fill_opp_coords; + + TEST_EXIT(elem->getFirstChild())("no children?\n"); + TEST_EXIT(element_ = const_cast<Element*>((ichild==0) ? + elem->getFirstChild() : + elem->getSecondChild())) + ("missing child %d?\n", ichild); + + macroElement_ = elinfo_old->macroElement_; + fillFlag_ = fill_flag; + parent_ = elem; + level_ = elinfo_old->level_ + 1; + + int dow = Global::getGeo(WORLD); + + if (fillFlag_.isSet(Mesh::FILL_COORDS) || + fillFlag_.isSet(Mesh::FILL_DET) || + fillFlag_.isSet(Mesh::FILL_GRD_LAMBDA)) + { + if (elem->getNewCoord(-1)) { + coord_[2] = *(elem->getNewCoord()); + } else { + for (j = 0; j < dow; j++) + coord_[2][j] = + 0.5 * (elinfo_old->coord_[0][j] + elinfo_old->coord_[1][j]); + // projection !?! + } + + if (ichild==0) { + for (j = 0; j < dow; j++) { + coord_[0][j] = elinfo_old->coord_[2][j]; + coord_[1][j] = elinfo_old->coord_[0][j]; + } + } else { + for (j = 0; j < dow; j++) { + coord_[0][j] = elinfo_old->coord_[1][j]; + coord_[1][j] = elinfo_old->coord_[2][j]; + } + } + } + + // if(fillFlag_.isSet(Mesh::FILL_DET) || fillFlag_.isSet(Mesh::FILL_GRD_LAMBDA)) { + // det = calcGrdLambda(*Lambda); + // } + + if (fill_flag.isSet(Mesh::FILL_NEIGH) + || fillFlag_.isSet(Mesh::FILL_OPP_COORDS)) + { + fill_opp_coords = (fill_flag.isSet(Mesh::FILL_OPP_COORDS)); + if (ichild==0) { + if ((neighbour_[2] = elinfo_old->neighbour_[1])) { + if (fill_opp_coords) { + for (j=0; j<dow; j++) + oppCoord_[2][j] = elinfo_old->oppCoord_[1][j]; + } + } + + oppVertex_[2] = elinfo_old->oppVertex_[1]; + + if (elem->getFirstChild() && + elem->getSecondChild()->getFirstChild() && + elem->getSecondChild()->getFirstChild()) // ???? + { + TEST_EXIT((neighbour_[1] = elem->getSecondChild()->getSecondChild())) + ("???"); + oppVertex_[1] = 2; + if (fill_opp_coords) { + if (elem->getSecondChild()->getNewCoord(-1)) + oppCoord_[1] = *(elem->getSecondChild()->getNewCoord()); + else + for (j=0; j<dow; j++) + oppCoord_[1][j] = + 0.5 * (elinfo_old->coord_[1][j] + + elinfo_old->coord_[2][j]); + // projection !?! + } + } else { + TEST_EXIT((neighbour_[1] = elem->getSecondChild()))("???"); + oppVertex_[1] = 0; + if (fill_opp_coords) { + for (j=0; j<dow; j++) + oppCoord_[1][j] = elinfo_old->coord_[1][j]; + } + } + if ((nb = elinfo_old->neighbour_[2])) { + TEST(elinfo_old->oppVertex_[2] == 2)("invalid neighbour\n"); + TEST_EXIT(nb->getFirstChild())("missing children?\n"); + TEST_EXIT((nb = nb->getSecondChild()))("missing getSecondChild()?\n"); + + if (nb->getFirstChild()) { + oppVertex_[0] = 2; + if (fill_opp_coords) { + if (nb->getNewCoord(-1)) { + oppCoord_[0] = *(nb->getNewCoord()); + } else { + for (j=0; j<dow; j++) + oppCoord_[0][j] = + 0.5*(elinfo_old->oppCoord_[2][j] + + elinfo_old->coord_[0][j]); + } + } + nb = nb->getFirstChild(); + } else { + oppVertex_[0] = 1; + if (fill_opp_coords) { + for (j=0; j<dow; j++) + oppCoord_[0][j] = elinfo_old->oppCoord_[2][j]; + } + } + } + + neighbour_[0] = nb; + } else { /* ichild==1 */ + if ((neighbour_[2] = elinfo_old->neighbour_[0])) { + if (fill_opp_coords) { + for (j=0; j<dow; j++) + oppCoord_[2][j] = elinfo_old->oppCoord_[0][j]; + } + } + + oppVertex_[2] = elinfo_old->oppVertex_[0]; + if (elem->getFirstChild()->getFirstChild()) { + neighbour_[0] = elem->getFirstChild()->getFirstChild(); + oppVertex_[0] = 2; + if (fill_opp_coords) { + if (elem->getFirstChild()->getNewCoord(-1)) { + oppCoord_[0] = *(elem->getFirstChild()->getNewCoord()); + } else { + for (j=0; j<dow; j++) + oppCoord_[0][j] = + 0.5 * (elinfo_old->coord_[0][j] + + elinfo_old->coord_[2][j]); + // projection !?! + } + } + } else { + neighbour_[0] = elem->getFirstChild(); + oppVertex_[0] = 1; + if (fill_opp_coords) { + for (j=0; j<dow; j++) + oppCoord_[0][j] = elinfo_old->coord_[0][j]; + } + } + if ((nb = elinfo_old->neighbour_[2])) { + TEST(elinfo_old->oppVertex_[2] == 2)("invalid neighbour\n"); + TEST((nb = nb->getFirstChild()))("missing child?\n"); + if (nb->getFirstChild()) { + oppVertex_[1] = 2; + if (fill_opp_coords) { + if (nb->getNewCoord(-1)) + oppCoord_[1] = *(nb->getNewCoord()); + else + for (j=0; j<dow; j++) + oppCoord_[1][j] = + 0.5*(elinfo_old->oppCoord_[2][j] + + elinfo_old->coord_[1][j]); + // projection !?! + } + nb = nb->getSecondChild(); + } else { + oppVertex_[1] = 0; + if (fill_opp_coords) { + for (j=0; j<dow; j++) + oppCoord_[1][j] = elinfo_old->oppCoord_[2][j]; + } + } + } + neighbour_[1] = nb; + } + } + + if (fill_flag.isSet(Mesh::FILL_BOUND)) { + if (elinfo_old->getBoundary(2)) + boundary_[5] = elinfo_old->getBoundary(2); + else + boundary_[5] = INTERIOR; + + + if (ichild==0) { + boundary_[3] = elinfo_old->getBoundary(5); + boundary_[4] = elinfo_old->getBoundary(3); + boundary_[0] = elinfo_old->getBoundary(2); + boundary_[1] = INTERIOR; + boundary_[2] = elinfo_old->getBoundary(1); + } else { + boundary_[3] = elinfo_old->getBoundary(4); + boundary_[4] = elinfo_old->getBoundary(5); + boundary_[0] = INTERIOR; + boundary_[1] = elinfo_old->getBoundary(2); + boundary_[2] = elinfo_old->getBoundary(0); + } + + if(elinfo_old->getProjection(0) && + elinfo_old->getProjection(0)->getType() == VOLUME_PROJECTION) + { + projection_[0] = elinfo_old->getProjection(0); + } else { // boundary projection + if (ichild==0) { + projection_[0] = elinfo_old->getProjection(2); + projection_[1] = NULL; + projection_[2] = elinfo_old->getProjection(1); + } else { + projection_[0] = NULL; + projection_[1] = elinfo_old->getProjection(2); + projection_[2] = elinfo_old->getProjection(0); + } + } + } + } + + double ElInfo2d::calcGrdLambda(DimVec<WorldVector<double> >& grd_lam) const + { + FUNCNAME("ElInfo2d::calcGrdLambda"); + // TEST_EXIT(Global::getGeo(WORLD) == 2) + // ("dim != dim_of_world ! use parametric elements!\n"); + + int i, j; + WorldVector<double> e1, e2; + double sdet, det1, adet = 0.0; + const WorldVector<double> v0= coord_[0]; + double a11, a12, a21, a22; + + testFlag(Mesh::FILL_COORDS); + int dow = Global::getGeo(WORLD); + int dim = mesh_->getDim(); + + for (i = 0; i < dow; i++) { + e1[i] = coord_[1][i] - v0[i]; + e2[i] = coord_[2][i] - v0[i]; + } + + if(Global::getGeo(WORLD) == 2) { + sdet = e1[0] * e2[1] - e1[1] * e2[0]; + adet = abs(sdet); + + if (adet < 1.0E-25) { + MSG("abs(det) = %f\n", adet); + for (i = 0; i <= dim; i++) + for (j = 0; j < dow; j++) + grd_lam[i][j] = 0.0; + } + else + { + det1 = 1.0 / sdet; + a11 = e2[1] * det1; /* (a_ij) = A^{-T} */ + a21 = -e2[0] * det1; + a12 = -e1[1] * det1; + a22 = e1[0] * det1; + + grd_lam[1][0] = a11; + grd_lam[1][1] = a21; + grd_lam[2][0] = a12; + grd_lam[2][1] = a22; + grd_lam[0][0] = - grd_lam[1][0] - grd_lam[2][0]; + grd_lam[0][1] = - grd_lam[1][1] - grd_lam[2][1]; + } + } else { + WorldVector<double> normal; + + vectorProduct(e1, e2, normal); + + adet = norm(&normal); + + if (adet < 1.0E-15) { + MSG("abs(det) = %lf\n", adet); + for (i = 0; i <= dim; i++) + for (j = 0; j < dow; j++) + grd_lam[i][j] = 0.0; + } else { + vectorProduct(e2, normal, grd_lam[1]); + vectorProduct(normal, e1, grd_lam[2]); + + double adet2 = 1.0/(adet*adet); + + for (i = 0; i < dow; i++) { + grd_lam[1][i] *= adet2; + grd_lam[2][i] *= adet2; + } + + grd_lam[0][0] = - grd_lam[1][0] - grd_lam[2][0]; + grd_lam[0][1] = - grd_lam[1][1] - grd_lam[2][1]; + grd_lam[0][2] = - grd_lam[1][2] - grd_lam[2][2]; + } + } + + return adet; + } + + const int ElInfo2d::worldToCoord(const WorldVector<double>& xy, + DimVec<double>* lambda) const + { + FUNCNAME("ElInfo::worldToCoord"); + DimVec<WorldVector<double> > edge(mesh_->getDim(), NO_INIT); + WorldVector<double> x; + double x0, det, det0, det1; + int i, j; + + static DimVec<double> vec(mesh_->getDim(), NO_INIT); + + TEST_EXIT(lambda)("lambda must not be NULL\n"); + + int dim = mesh_->getDim(); + int dimOfWorld = Global::getGeo(WORLD); + + for (j=0; j<dimOfWorld; j++) { + x0 = coord_[dim][j]; + x[j] = xy[j] - x0; + for (i=0; i < dim; i++) + edge[i][j] = coord_[i][j] - x0; + } + + det = edge[0][0] * edge[1][1] - edge[0][1] * edge[1][0]; + det0 = x[0] * edge[1][1] - x[1] * edge[1][0]; + det1 = edge[0][0] * x[1] - edge[0][1] * x[0]; + + if (abs(det) < DBL_TOL) { + ERROR("det = %le; abort\n", det); + for (i=0; i<=dim; i++) (*lambda)[i] = 1.0/dim; + return 0; + } + + (*lambda)[0] = det0 / det; + (*lambda)[1] = det1 / det; + (*lambda)[2] = 1.0 - (*lambda)[0] - (*lambda)[1]; + + // if(dimOfWorld == 3) { + // if(abs(x[2] - edge[0][2] * lambda[0] - edge[1][2] * lambda[1]) > 1.e-5) { + // WARNING("system not solvable\n"); + // }; + // } + + int k = -1; + double lmin = 0.0; + j = 0; + for (i = 0; i <= dim; i++) { + if ((*lambda)[i] < -1.E-5) { + if ((*lambda)[i] < lmin) { + k = i; + lmin = (*lambda)[i]; + } + j++; + } + } + + return k; + } + + + double ElInfo2d::getNormal(int side, WorldVector<double> &normal) const + { + FUNCNAME("ElInfo::getNormal"); + double det = 0.0; + int i0, i1; + + int dow = Global::getGeo(WORLD); + + i0 = (side+1) % 3; + i1 = (side+2) % 3; + + if (dow == 2){ + normal[0] = coord_[i1][1] - coord_[i0][1]; + normal[1] = coord_[i0][0] - coord_[i1][0]; + } else { // dow == 3 + WorldVector<double> e0, e1,e2, elementNormal; + + e0 = coord_[i1]; e0 -= coord_[i0]; + e1 = coord_[i1]; e1 -= coord_[side]; + e2 = coord_[i0]; e2 -= coord_[side]; + + vectorProduct(e1, e2, elementNormal); + vectorProduct(elementNormal, e0, normal); + } + + det = norm(&normal); + + TEST_EXIT(det > 1.e-30)("det = 0 on face %d\n", side); + + normal *= 1.0 / det; + + return(det); + } + + + /****************************************************************************/ + /* calculate the normal of the element for dim of world = dim + 1 */ + /* return the absulute value of the determinant from the */ + /* transformation to the reference element */ + /****************************************************************************/ + double ElInfo2d::getElementNormal( WorldVector<double> &elementNormal) const + { + FUNCNAME("ElInfo::getElementNormal"); + double det = 0.0; + int dow = Global::getGeo(WORLD); + WorldVector<double> e0, e1; + + TEST_EXIT(dow = 3)(" element normal only well defined for DIM_OF_WORLD = DIM + 1 !!"); + + e0 = coord_[1] - coord_[0]; + e1 = coord_[2] - coord_[0]; + + vectorProduct(e0, e1, elementNormal); + + det = norm(&elementNormal); + + TEST_EXIT(det > 1.e-30)("det = 0"); + + elementNormal *= 1.0 / det; + + return(det); + } + + + + + + + + + +} diff --git a/AMDiS/src/ElInfo2d.h b/AMDiS/src/ElInfo2d.h new file mode 100644 index 0000000000000000000000000000000000000000..f09787c1c2fbc0c410bca248e65dbd1be0449d45 --- /dev/null +++ b/AMDiS/src/ElInfo2d.h @@ -0,0 +1,81 @@ +// ============================================================================ +// == == +// == AMDiS - Adaptive multidimensional simulations == +// == == +// ============================================================================ +// == == +// == crystal growth group == +// == == +// == Stiftung caesar == +// == Ludwig-Erhard-Allee 2 == +// == 53175 Bonn == +// == germany == +// == == +// ============================================================================ +// == == +// == http://www.caesar.de/cg/AMDiS == +// == == +// ============================================================================ + +/** \file ElInfo2d.h */ + +#ifndef AMDIS_ELINFO2D_H +#define AMDIS_ELINFO2D_H + +#include "ElInfo.h" +#include "MemoryManager.h" + +namespace AMDiS { + + // ============================================================================ + // ===== class ElInfo2d ======================================================= + // ============================================================================ + + /** \ingroup Traverse + * \brief + * ElInfo class for 2-dimensional elements (\ref Triangle). + */ + class ElInfo2d : public ElInfo + { + public: + MEMORY_MANAGED(ElInfo2d); + + /** \brief + * Constructor. Calls ElInfo's protected Constructor. + */ + ElInfo2d(Mesh* aMesh) : ElInfo(aMesh) {}; + + /** \brief + * 2-dimensional realisation of ElInfo's fillElInfo method. + */ + void fillElInfo(int ichild, const ElInfo *elinfo_old); + + /** \brief + * 2-dimensional realisation of ElInfo's fillMacroInfo method. + */ + void fillMacroInfo(const MacroElement *); + + /** \brief + * 2-dimensional realisation of ElInfo's worldToCoord method. + */ + const int worldToCoord(const WorldVector<double>& w, DimVec<double>* l) const; + + /** \brief + * 2-dimensional realisation of ElInfo's calcGrdLambda method. + */ + double calcGrdLambda(DimVec<WorldVector<double> >& grd_lam) const; + + /** \brief + * 2-dimensional realisation of ElInfo's getNormal method. + */ + double getNormal(int side, WorldVector<double> &normal) const; + + /** \brief + * 2-dimensional realisation of ElInfo's getElementNormal method. + */ + double getElementNormal( WorldVector<double> &normal) const; + }; + +} + +#endif // AMDIS_ELINFO2D_H diff --git a/AMDiS/src/ElInfo3d.cc b/AMDiS/src/ElInfo3d.cc new file mode 100644 index 0000000000000000000000000000000000000000..5796a62e8484b451a6f69b45f4114c611e0f72f1 --- /dev/null +++ b/AMDiS/src/ElInfo3d.cc @@ -0,0 +1,661 @@ +#include "ElInfo3d.h" +#include "BasisFunction.h" +#include "Element.h" +#include "Line.h" +#include "Triangle.h" +#include "Tetrahedron.h" +#include "FiniteElemSpace.h" +#include "Flag.h" +#include "MacroElement.h" +#include "Mesh.h" +#include "Global.h" +#include "FixVec.h" +#include "DOFVector.h" + +namespace AMDiS { + + void ElInfo3d::fillMacroInfo(const MacroElement * mel) + { + FUNCNAME("ElInfo3d::fillMacroInfo"); + Element *nb; + MacroElement *mnb; + int i, k; + Flag fill_opp_coords; + + macroElement_ = const_cast<MacroElement*>( mel); + element_ = const_cast<Element*>( mel->getElement()); + parent_ = NULL; + level_ = 0; + el_type = const_cast<MacroElement*>(mel)->getElType(); + + int vertices = mesh_->getGeo(VERTEX); + + if (fillFlag_.isSet(Mesh::FILL_COORDS) || + fillFlag_.isSet(Mesh::FILL_DET) || + fillFlag_.isSet(Mesh::FILL_GRD_LAMBDA)) { + for (i=0; i<vertices; i++) { + coord_[i] = mel->coord[i]; + } + } + + // if(fillFlag_.isSet(Mesh::FILL_DET) || fillFlag_.isSet(Mesh::FILL_GRD_LAMBDA)) { + // det = calcGrdLambda(*Lambda); + // } + + int neighbours = mesh_->getGeo(NEIGH); + + if(fillFlag_.isSet(Mesh::FILL_OPP_COORDS) || + fillFlag_.isSet(Mesh::FILL_NEIGH)) { + + fill_opp_coords.setFlags(fillFlag_ & Mesh::FILL_OPP_COORDS); + for (i=0; i < neighbours; i++) { + if ((mnb = const_cast<MacroElement*>( mel->getNeighbour(i)))) { + neighbour_[i] = const_cast<Element*>( mel->getNeighbour(i)->getElement()); + nb = const_cast<Element*>( neighbour_[i]); + k = oppVertex_[i] = mel->getOppVertex(i); + + if (nb->getChild(0) && (k < 2)) { /*make nb nearest element.*/ + if (k==1) { + neighbour_[i] = const_cast<Element*>( nb->getChild(0)); + nb = const_cast<Element*>( neighbour_[i]); + } else { + neighbour_[i] = const_cast<Element*>( nb->getChild(1)); + nb = const_cast<Element*>( neighbour_[i]); + } + k = oppVertex_[i] = 3; + if (fill_opp_coords.isAnySet()) + { + /* always edge between vertices 0 and 1 is bisected! */ + if (mnb->getElement()->isNewCoordSet()) + oppCoord_[i] = *(mnb->getElement()->getNewCoord()); + else + oppCoord_[i] = (mnb->coord[0] + mnb->coord[1]) * 0.5; + } + } + else { + if (fill_opp_coords.isAnySet()) { + oppCoord_[i] = mnb->coord[k]; + } + } + } + else { + neighbour_[i] = NULL; + } + } + } + + //int faces = mesh->getGeo(FACE); + //int edges = mesh->getGeo(EDGE); + + if (fillFlag_.isSet(Mesh::FILL_BOUND)) + { + for (i = 0; i < element_->getGeo(BOUNDARY); i++) { + boundary_[i] = mel->getBoundary(i); + } + + for (i = 0; i < element_->getGeo(PROJECTION); i++) { + projection_[i] = mel->getProjection(i); + } + } + + if (fillFlag_.isSet(Mesh::FILL_ORIENTATION)) { + WorldVector<WorldVector<double> > a; + double s; + + for (i=0; i<3; i++) { + a[i] = mel->coord[i+1]; + a[i] -= mel->coord[0]; + } + + s = (a[0][1] * a[1][2] - a[0][2] * a[1][1]) * a[2][0] + + (a[0][2] * a[1][0] - a[0][0] * a[1][2]) * a[2][1] + + (a[0][0] * a[1][1] - a[0][1] * a[1][0]) * a[2][2]; + + if (s >= 0) + orientation = 1; + else + orientation = -1; + } + } + + double ElInfo3d::calcGrdLambda(DimVec<WorldVector<double> >& grd_lam) const + { + FUNCNAME("ElInfo3d::calcGrdLambda"); + TEST_EXIT(Global::getGeo(WORLD) == 3) + ("dim != dim_of_world ! use parametric elements!\n"); + + int i, j; + WorldVector<double> e1, e2, e3; + WorldVector<double> v0; + double det, adet; + double a11, a12, a13, a21, a22, a23, a31, a32, a33; + + testFlag(Mesh::FILL_COORDS); + + v0 = coord_[0]; + for (i = 0; i < 3; i++) { + e1[i] = coord_[1][i] - v0[i]; + e2[i] = coord_[2][i] - v0[i]; + e3[i] = coord_[3][i] - v0[i]; + } + + det = e1[0] * (e2[1]*e3[2] - e2[2]*e3[1]) + - e1[1] * (e2[0]*e3[2] - e2[2]*e3[0]) + + e1[2] * (e2[0]*e3[1] - e2[1]*e3[0]); + + adet = abs(det); + + if (adet < 1.0E-25) + { + MSG("abs(det) = %f\n",adet); + for (i = 0; i < 4; i++) + for (j = 0; j < 3; j++) + grd_lam[i][j] = 0.0; + } + else + { + det = 1.0 / det; + a11 = (e2[1]*e3[2] - e2[2]*e3[1]) * det; /* (a_ij) = A^{-T} */ + a12 = (e2[2]*e3[0] - e2[0]*e3[2]) * det; + a13 = (e2[0]*e3[1] - e2[1]*e3[0]) * det; + a21 = (e1[2]*e3[1] - e1[1]*e3[2]) * det; + a22 = (e1[0]*e3[2] - e1[2]*e3[0]) * det; + a23 = (e1[1]*e3[0] - e1[0]*e3[1]) * det; + a31 = (e1[1]*e2[2] - e1[2]*e2[1]) * det; + a32 = (e1[2]*e2[0] - e1[0]*e2[2]) * det; + a33 = (e1[0]*e2[1] - e1[1]*e2[0]) * det; + + grd_lam[1][0] = a11; + grd_lam[1][1] = a12; + grd_lam[1][2] = a13; + grd_lam[2][0] = a21; + grd_lam[2][1] = a22; + grd_lam[2][2] = a23; + grd_lam[3][0] = a31; + grd_lam[3][1] = a32; + grd_lam[3][2] = a33; + + grd_lam[0][0] = -grd_lam[1][0] -grd_lam[2][0] -grd_lam[3][0]; + grd_lam[0][1] = -grd_lam[1][1] -grd_lam[2][1] -grd_lam[3][1]; + grd_lam[0][2] = -grd_lam[1][2] -grd_lam[2][2] -grd_lam[3][2]; + } + + return adet; + } + + const int ElInfo3d::worldToCoord(const WorldVector<double>& xy, + DimVec<double>* lambda) const + { + FUNCNAME("ElInfo::worldToCoord"); + DimVec<WorldVector<double> > edge(mesh_->getDim(), NO_INIT); + WorldVector<double> x; + double x0, det, det0, det1, det2; + int i, j; + + static DimVec<double> vec(mesh_->getDim(), NO_INIT); + + TEST_EXIT(lambda)("lambda must not be NULL\n"); + + int dim = mesh_->getDim(); + int dimOfWorld = Global::getGeo(WORLD); + + TEST_EXIT(dim == dimOfWorld)("dim!=dimOfWorld not yet implemented\n"); + + /* wir haben das gleichungssystem zu loesen: */ + /* ( q1x q2x q3x) (lambda1) (qx) */ + /* ( q1y q2y q3y) (lambda2) = (qy) */ + /* ( q1z q2z q3z) (lambda3) (qz) */ + /* mit qi=pi-p3, q=xy-p3 */ + + for (j=0; j<dimOfWorld; j++) { + x0 = coord_[dim][j]; + x[j] = xy[j] - x0; + for (i=0; i<dim; i++) + edge[i][j] = coord_[i][j] - x0; + } + + det = edge[0][0] * edge[1][1] * edge[2][2] + + edge[0][1] * edge[1][2] * edge[2][0] + + edge[0][2] * edge[1][0] * edge[2][1] + - edge[0][2] * edge[1][1] * edge[2][0] + - edge[0][0] * edge[1][2] * edge[2][1] + - edge[0][1] * edge[1][0] * edge[2][2]; + det0 = x[0] * edge[1][1] * edge[2][2] + + x[1] * edge[1][2] * edge[2][0] + + x[2] * edge[1][0] * edge[2][1] + - x[2] * edge[1][1] * edge[2][0] + - x[0] * edge[1][2] * edge[2][1] + - x[1] * edge[1][0] * edge[2][2]; + det1 = edge[0][0] * x[1] * edge[2][2] + + edge[0][1] * x[2] * edge[2][0] + + edge[0][2] * x[0] * edge[2][1] + - edge[0][2] * x[1] * edge[2][0] + - edge[0][0] * x[2] * edge[2][1] + - edge[0][1] * x[0] * edge[2][2]; + det2 = edge[0][0] * edge[1][1] * x[2] + + edge[0][1] * edge[1][2] * x[0] + + edge[0][2] * edge[1][0] * x[1] + - edge[0][2] * edge[1][1] * x[0] + - edge[0][0] * edge[1][2] * x[1] + - edge[0][1] * edge[1][0] * x[2]; + + if (abs(det) < DBL_TOL) { + ERROR("det = %le; abort\n", det); + for (i=0; i<=dim; i++) (*lambda)[i] = 1.0/dim; + return 0; + } + + (*lambda)[0] = det0 / det; + (*lambda)[1] = det1 / det; + (*lambda)[2] = det2 / det; + (*lambda)[3] = 1.0 - (*lambda)[0] - (*lambda)[1] - (*lambda)[2]; + + int k = -1; + double lmin = 0.0; + j = 0; + for (i = 0; i <= dim; i++) { + if ((*lambda)[i] < -1.E-5) { + if ((*lambda)[i] < lmin) { + k = i; + lmin = (*lambda)[i]; + } + j++; + } + } + + return k; + } + + + /****************************************************************************/ + /* update EL_INFO structure after refinement (of some neighbours) */ + /****************************************************************************/ + + void ElInfo3d::update() + { + FUNCNAME("ElInfo::update"); + + int neighbours = mesh_->getGeo(NEIGH); + int vertices = mesh_->getGeo(VERTEX); + int dow = Global::getGeo(WORLD); + + if (fillFlag_.isSet(Mesh::FILL_NEIGH) || fillFlag_.isSet(Mesh::FILL_OPP_COORDS)) + { + Tetrahedron *nb; + int ineigh, ov, j, k; + Flag fill_opp_coords = fillFlag_ & Mesh::FILL_OPP_COORDS; + + for (ineigh=0; ineigh < neighbours; ineigh++) { + if ((nb = dynamic_cast<Tetrahedron*>(const_cast<Element*>(neighbour_[ineigh])))) { + ov = oppVertex_[ineigh]; + if (ov < 2 && nb->getFirstChild()) { + if (fill_opp_coords != Flag(0)) { + k = -1; + for (j=0; j<vertices; j++) + if (element_->getDOF(j) == nb->getDOF(1-ov)) k = j; + + if(k == -1) { + for (j=0; j<vertices; j++) + if (mesh_->associated(element_->getDOF(j, 0), + nb->getDOF(1-ov, 0))) + k = j; + } + TEST_EXIT(k >= 0)("neighbour dof not found\n"); + + if (nb->isNewCoordSet()) + oppCoord_[ineigh] = *(nb->getNewCoord()); + else + for (j = 0; j < dow; j++) + oppCoord_[ineigh][j] = + (oppCoord_[ineigh][j] + coord_[k][j]) / 2; + } + neighbour_[ineigh] = dynamic_cast<Tetrahedron*>(const_cast<Element*>(nb->getChild(1-ov))); + oppVertex_[ineigh] = 3; + } + } + } + } + } + + + double ElInfo3d::getNormal(int face, WorldVector<double> &normal) const + { + FUNCNAME("ElInfo3d::getNormal"); + double det = 0.0; + int i, i0, i1, i2; + WorldVector<double> e0, e1, e2; + + int dow = Global::getGeo(WORLD); + + if(dow == 3) { + i0 = (face+1)%4; + i1 = (face+2)%4; + i2 = (face+3)%4; + + for (i = 0; i < dow; i++) { + e0[i] = coord_[i1][i] - coord_[i0][i]; + e1[i] = coord_[i2][i] - coord_[i0][i]; + e2[i] = coord_[face][i] - coord_[i0][i]; + } + + vectorProduct(e0, e1, normal); + + if ((e2*normal) < 0.0) + for (i = 0; i < dow; i++) + normal[i] = -normal[i]; + + det = norm(&normal); + TEST_EXIT(det > 1.e-30)("det = 0 on face %d\n", face); + + normal[0] /= det; + normal[1] /= det; + normal[2] /= det; + } else { + MSG("not implemented for DIM_OF_WORLD = %d in 3d\n", dow); + } + + return(det); + } + + + + + void ElInfo3d::fillElInfo(int ichild, const ElInfo *elinfo_old) + { + FUNCNAME("ElInfo3d::fillElInfo"); + int i,j,k; + int el_type_local = 0; /* el_type in {0,1,2} */ + int ochild = 0; /* index of other child = 1-ichild */ + int *cv = NULL; /* cv = child_vertex[el_type][ichild] */ + const int (*cvg)[4] = NULL; /* cvg = child_vertex[el_type] */ + int *ce; /* ce = child_edge[el_type][ichild] */ + int iedge; + Element *nb, *nbk; + const FixVec<Element*, NEIGH> *neigh_old; + Element *el_old = elinfo_old->element_; + Flag fillFlag__local = elinfo_old->fillFlag_; + DegreeOfFreedom *dof; + int ov = -1; + FixVec<Element*, NEIGH> *neigh_local; + Flag fill_opp_coords; + Mesh *mesh = elinfo_old->getMesh(); + + TEST_EXIT(el_old->getChild(0))("missing child?\n"); /* Kuni 22.08.96 */ + + element_ = const_cast<Element*>( el_old->getChild(ichild)); + macroElement_ = elinfo_old->macroElement_; + fillFlag_ = fillFlag__local; + parent_ = el_old; + level_ = elinfo_old->level_ + 1; + el_type = (( dynamic_cast<ElInfo3d*>(const_cast<ElInfo*>( elinfo_old)))->el_type + 1) % 3; + + TEST_EXIT(element_)("missing child %d?\n", ichild); + + if (fillFlag__local.isAnySet()) { + el_type_local = ( dynamic_cast<ElInfo3d*>(const_cast<ElInfo*>( elinfo_old)))->getType(); + cvg = Tetrahedron::childVertex[el_type_local]; + cv = const_cast<int*>( cvg[ichild]); + ochild = 1-ichild; + } + + int dow = Global::getGeo(WORLD); + + if(fillFlag__local.isSet(Mesh::FILL_COORDS) || + fillFlag_.isSet(Mesh::FILL_DET) || + fillFlag_.isSet(Mesh::FILL_GRD_LAMBDA)) + { + for (i=0; i<3; i++) { + for (j = 0; j < dow; j++) { + coord_[i][j] = elinfo_old->coord_[cv[i]][j]; + } + } + if (el_old->getNewCoord()) + coord_[3] = *(el_old->getNewCoord()); + else + for (j = 0; j < dow; j++) + coord_[3][j] = + (elinfo_old->coord_[0][j] + elinfo_old->coord_[1][j]) / 2; + } + + // if(fillFlag_.isSet(Mesh::FILL_DET) || fillFlag_.isSet(Mesh::FILL_GRD_LAMBDA)) { + // det = calcGrdLambda(*Lambda); + // } + + + if(fillFlag__local.isSet(Mesh::FILL_NEIGH) || + fillFlag_.isSet(Mesh::FILL_OPP_COORDS)) + { + neigh_local = &neighbour_; + neigh_old = &elinfo_old->neighbour_; + //oppVertex__local = *oppVertex_; + fill_opp_coords.setFlags(fillFlag__local & Mesh::FILL_OPP_COORDS); + + /*----- nb[0] is other child --------------------------------------------*/ + + /* if (nb = el_old->child[ochild]) old version */ + if(el_old->getChild(0) && + (nb = const_cast<Element*>( el_old->getChild(ochild)))) /*Kuni 22.08.96*/ + { + if (nb->getChild(0)) + { /* go down one level for direct neighbour */ + if (fill_opp_coords.isAnySet()) + { + if (nb->getNewCoord()) + { + oppCoord_[0]= *(nb->getNewCoord()); + } + else + { + k = cvg[ochild][1]; + for (j = 0; j < dow; j++) + oppCoord_[0][j] = + (elinfo_old->coord_[ochild][j] + + elinfo_old->coord_[k][j]) / 2; + } + } + (*neigh_local)[0] = const_cast<Element*>( nb->getChild(1)); + oppVertex_[0] = 3; + } + else { + if (fill_opp_coords.isAnySet()) { + for (j = 0; j < dow; j++) { + oppCoord_[0][j] = elinfo_old->coord_[ochild][j]; + } + } + (*neigh_local)[0] = nb; + oppVertex_[0] = 0; + } + } + else { + ERROR_EXIT("no other child"); + (*neigh_local)[0] = NULL; + } + + + /*----- nb[1],nb[2] are childs of old neighbours nb_old[cv[i]] ----------*/ + + for (i=1; i<3; i++) + { + if ((nb = const_cast<Element*>( (*neigh_old)[cv[i]]))) + { + TEST_EXIT(nb->getChild(0))("nonconforming triangulation\n"); + + for (k=0; k<2; k++) /* look at both childs of old neighbour */ + { + nbk = const_cast<Element*>( nb->getChild(k)); + if (nbk->getDOF(0) == el_old->getDOF(ichild)) { + /* opp. vertex */ + dof = const_cast<int*>(nb->getDOF(elinfo_old->oppVertex_[cv[i]])); + + if (dof == nbk->getDOF(1)) + { + ov = 1; + if (nbk->getChild(0)) + { + if (fill_opp_coords.isAnySet()) + { + if (nbk->getNewCoord()) + oppCoord_[i] = *(nbk->getNewCoord()); + else + for (j = 0; j < dow; j++) + oppCoord_[i][j] = + (elinfo_old->oppCoord_[cv[i]][j] + + elinfo_old->coord_[ichild][j]) / 2; + } + (*neigh_local)[i] = nbk->getChild(0); + oppVertex_[i] = 3; + break; + } + } + else + { + //TEST_EXIT(dof == nbk->getDOF(2))("opp_vertex not found\n"); + if(dof != nbk->getDOF(2)) { + ov = -1; break; + } + ov = 2; + } + + if (fill_opp_coords.isAnySet()) + { + for (j = 0; j < dow; j++) + { + oppCoord_[i][j] = elinfo_old->oppCoord_[cv[i]][j]; + } + } + (*neigh_local)[i] = nbk; + oppVertex_[i] = ov; + break; + } + + } /* end for k */ + //TEST_EXIT(k<2)("child not found with vertex\n"); + + // periodic ? + if(k == 2 || ov == -1) { + for (k=0; k<2; k++) /* look at both childs of old neighbour */ + { + nbk = const_cast<Element*>( nb->getChild(k)); + if (nbk->getDOF(0) == el_old->getDOF(ichild) || + mesh->associated(nbk->getDOF(0, 0), el_old->getDOF(ichild, 0))) { + /* opp. vertex */ + dof = const_cast<int*>(nb->getDOF(elinfo_old->oppVertex_[cv[i]])); + + if (dof == nbk->getDOF(1) || + mesh->associated(dof[0], nbk->getDOF(1, 0))) + { + ov = 1; + if (nbk->getChild(0)) + { + if (fill_opp_coords.isAnySet()) + { + if (nbk->getNewCoord()) + oppCoord_[i] = *(nbk->getNewCoord()); + else + for (j = 0; j < dow; j++) + oppCoord_[i][j] = + (elinfo_old->oppCoord_[cv[i]][j] + + elinfo_old->coord_[ichild][j]) / 2; + } + (*neigh_local)[i] = nbk->getChild(0); + oppVertex_[i] = 3; + break; + } + } + else + { + TEST_EXIT(dof == nbk->getDOF(2) || + mesh->associated(dof[0], nbk->getDOF(2, 0))) + ("opp_vertex not found\n"); + ov = 2; + } + + if (fill_opp_coords.isAnySet()) + { + for (j = 0; j < dow; j++) + { + oppCoord_[i][j] = elinfo_old->oppCoord_[cv[i]][j]; + } + } + (*neigh_local)[i] = nbk; + oppVertex_[i] = ov; + break; + } + + } /* end for k */ + TEST_EXIT(k<2)("child not found with vertex\n"); + } + } + else + { + (*neigh_local)[i] = NULL; + } + } /* end for i */ + + + /*----- nb[3] is old neighbour neigh_old[ochild] ------------------------*/ + + if (((*neigh_local)[3] = (*neigh_old)[ochild])) + { + oppVertex_[3] = elinfo_old->oppVertex_[ochild]; + if (fill_opp_coords.isAnySet()) { + for (j = 0; j < dow; j++) { + oppCoord_[3][j] = elinfo_old->oppCoord_[ochild][j]; + } + } + } + } + + if (fillFlag__local.isSet(Mesh::FILL_BOUND)) + { + for (i = 0; i < 3; i++) { + boundary_[10 + i] = elinfo_old->getBoundary(10 + cv[i]); + } + + boundary_[13] = elinfo_old->getBoundary(4); + + boundary_[0] = INTERIOR; + boundary_[1] = elinfo_old->getBoundary(cv[1]); + boundary_[2] = elinfo_old->getBoundary(cv[2]); + boundary_[3] = elinfo_old->getBoundary(ochild); + + ce = const_cast<int*>(Tetrahedron::childEdge[el_type_local][ichild]); + for (iedge=0; iedge<4; iedge++) { + boundary_[mesh_->getGeo(FACE)+iedge] = + elinfo_old->getBoundary(mesh_->getGeo(FACE)+ce[iedge]); + } + for (iedge=4; iedge<6; iedge++) { + i = 5 - cv[iedge-3]; /* old vertex opposite new edge */ + boundary_[mesh_->getGeo(FACE)+iedge] = elinfo_old->getBoundary(i); + } + + if(elinfo_old->getProjection(0) && + elinfo_old->getProjection(0)->getType() == VOLUME_PROJECTION) + { + projection_[0] = elinfo_old->getProjection(0); + } else { // boundary projection + projection_[0] = NULL; + projection_[1] = elinfo_old->getProjection(cv[1]); + projection_[2] = elinfo_old->getProjection(cv[2]); + projection_[3] = elinfo_old->getProjection(ochild); + + for (iedge=0; iedge<4; iedge++) { + projection_[mesh_->getGeo(FACE)+iedge] = + elinfo_old->getProjection(mesh_->getGeo(FACE)+ce[iedge]); + } + for (iedge=4; iedge<6; iedge++) { + i = 5 - cv[iedge-3]; /* old vertex opposite new edge */ + projection_[mesh_->getGeo(FACE)+iedge] = elinfo_old->getProjection(i); + } + } + } + + + if (fillFlag_.isSet(Mesh::FILL_ORIENTATION)) { + orientation = + ( dynamic_cast<ElInfo3d*>(const_cast<ElInfo*>(elinfo_old)))->orientation + * Tetrahedron::childOrientation[el_type_local][ichild]; + } + } + +} diff --git a/AMDiS/src/ElInfo3d.h b/AMDiS/src/ElInfo3d.h new file mode 100644 index 0000000000000000000000000000000000000000..348737acae0a5ab5669b3ece74c87eb24ab3fd35 --- /dev/null +++ b/AMDiS/src/ElInfo3d.h @@ -0,0 +1,132 @@ +// ============================================================================ +// == == +// == AMDiS - Adaptive multidimensional simulations == +// == == +// ============================================================================ +// == == +// == crystal growth group == +// == == +// == Stiftung caesar == +// == Ludwig-Erhard-Allee 2 == +// == 53175 Bonn == +// == germany == +// == == +// ============================================================================ +// == == +// == http://www.caesar.de/cg/AMDiS == +// == == +// ============================================================================ + +/** \file ElInfo3d.h */ + +#ifndef AMDIS_ELINFO3D_H +#define AMDIS_ELINFO3D_H + +#include "ElInfo.h" +#include "MemoryManager.h" + +namespace AMDiS { + + // ============================================================================ + // ===== class ElInfo3d ======================================================= + // ============================================================================ + + + /** \ingroup Traverse + * \brief + * ElInfo class for 3-dimensional elements (\ref Tetrahedron). + */ + class ElInfo3d : public ElInfo + { + public: + MEMORY_MANAGED(ElInfo3d); + + /** \brief + * Constructor. Calls ElInfo's protected Constructor. + */ + ElInfo3d(Mesh* aMesh) : ElInfo(aMesh) {}; + + /** \brief + * Assignment operator + */ + ElInfo3d& operator=(const ElInfo3d& rhs) { + ElInfo::operator=(rhs); + el_type = rhs.el_type; + orientation = rhs.orientation; + return *this; + } + + /** \brief + * 3-dimensional realisation of ElInfo's fillElInfo method. + */ + void fillElInfo(int ichild, const ElInfo *elinfo_old); + + /** \brief + * 3-dimensional realisation of ElInfo's fillMacroInfo method. + */ + void fillMacroInfo(const MacroElement *); + + /** \brief + * 3-dimensional realisation of ElInfo's worldToCoord method. + */ + const int worldToCoord(const WorldVector<double>& w, DimVec<double>* l) const; + + /** \brief + * 3-dimensional realisation of ElInfo's calcGrdLambda method. + */ + double calcGrdLambda(DimVec<WorldVector<double> >& grd_lam) const; + + /** \brief + * 3-dimensional realisation of ElInfo's getNormal method. + */ + double getNormal(int side, WorldVector<double> &normal) const; + + /** \brief + * 3-dimensional realisation of ElInfo's getElementNormal method. + */ + //double getElementNormal( WorldVector<double> &normal) const; + + + + /** \brief + * update ElInfo after refinement (of some neighbours). Only in 3d! + */ + void update(); + + /** \brief + * get ElInfo's \ref el_type + */ + inline unsigned char getType() const { return el_type; }; + + /** \brief + * get ElInfo's \ref orientation + */ + inline signed char getOrientation() const { return orientation; }; + + /** \brief + * set ElInfo's \ref el_type to t + */ + inline void setType(unsigned char t) { el_type = t; }; + + /** \brief + * set ElInfo's \ref orientation to o + */ + inline void setOrientation(signed char o) { orientation = o; }; + + protected: + + /** \brief + * \ref el 's type. Is Filled automatically by the traversal routines. + */ + unsigned char el_type; + + /** \brief + * +/- 1: sign of the determinant of the transformation to the reference + * element with vertices (0,0,0), (1,1,1), (1,1,0), (1,0,0). + */ + signed char orientation; + }; + +} + +#endif // AMDIS_ELINFO3D_H diff --git a/AMDiS/src/Element.cc b/AMDiS/src/Element.cc new file mode 100644 index 0000000000000000000000000000000000000000..39ba45978e9644cd7d722d0166d0d0386795bc80 --- /dev/null +++ b/AMDiS/src/Element.cc @@ -0,0 +1,417 @@ +#include "Element.h" +#include "DOFAdmin.h" +#include "Mesh.h" +#include "CoarseningManager.h" +#include "FixVec.h" +#include "ElementRegion_ED.h" + +namespace AMDiS { + + + int Element::getRegion() const + { + ElementRegion_ED* red_; + + if (!elementData) return -1; + red_=dynamic_cast<ElementRegion_ED*>(elementData->getElementData(ELEMENT_REGION)); + if (red_) + return red_->getRegion(); + + return -1; + } + + void Element::setDOFPtrs() + { + FUNCNAME("Element::setDOFPtrs"); + TEST_EXIT(mesh)("no mesh!\n"); + dof = mesh->createDOFPtrs(); + } + + Element::Element(Mesh *aMesh) + { + mesh = aMesh; + + index = mesh ? mesh->getNextElementIndex() : -1; + + child[0] = NULL; + child[1] = NULL; + + dof = mesh ? mesh->createDOFPtrs() : NULL; + newCoord = NULL; + + elementData = NULL; + } + + // call destructor through Mesh::freeElement !!! + Element::~Element() + { + if(child[0]) DELETE child[0]; + if(child[1]) DELETE child[1]; + + //if(elementData) DELETE elementData; + + if (newCoord) + { + DELETE newCoord; + } + } + + /****************************************************************************/ + /* ATTENTION: */ + /* new_dof_fct() destroys new_dof !!!!!!!!!! */ + /* should be used only at the end of dof_compress()!!!!! */ + /****************************************************************************/ + + /* CHANGE_DOFS_1 changes old dofs to NEGATIVE new dofs */ + +#define CHANGE_DOFS_1(el) \ + ldof = el->dof[n0+i] + nd0; \ + for (j = 0; j < nd; j++) { \ + if ((k = ldof[j]) >= 0) { \ + /* do it only once! (dofs are visited more than once) */ \ + ldof[j] = - admin->getMesh()->newDOF[k] - 1; \ + } } + + /* CHANGE_DOFS_2 changes NEGATIVE new dofs to POSITIVE */ + +#define CHANGE_DOFS_2(el) \ + ldof = el->dof[n0+i] + nd0; \ + for (j = 0; j < nd; j++) { \ + if ((k = ldof[j]) < 0) { \ + /* do it only once! (dofs are visited more than once) */ \ + ldof[j] = - k - 1; \ + } } + + void Element::newDOFFct1(const DOFAdmin* admin) + { + int i, j, k, n0, nd, nd0; + DegreeOfFreedom *ldof; + + int vertices = mesh->getGeo(VERTEX); + int edges = mesh->getGeo(EDGE); + int faces = mesh->getGeo(FACE); + + if ((nd = admin->getNumberOfDOFs(VERTEX))) { + nd0 = admin->getNumberOfPreDOFs(VERTEX); + n0 = admin->getMesh()->getNode(VERTEX); + for (i = 0; i < vertices; i++) { + CHANGE_DOFS_1(this); + } + } + + if(mesh->getDim() > 1) { + if ((nd = admin->getNumberOfDOFs(EDGE))) { + nd0 = admin->getNumberOfPreDOFs(EDGE); + n0 = admin->getMesh()->getNode(EDGE); + for (i = 0; i < edges; i++) { + CHANGE_DOFS_1(this); + } + } + } + + if (3==mesh->getDim()) { + if ((nd = admin->getNumberOfDOFs(FACE))) { + nd0 = admin->getNumberOfPreDOFs(FACE); + n0 = admin->getMesh()->getNode(FACE); + for (i = 0; i < faces; i++) { + CHANGE_DOFS_1(this); + } + } + } + + if ((nd = admin->getNumberOfDOFs(CENTER))) { + nd0 = admin->getNumberOfPreDOFs(CENTER); + n0 = admin->getMesh()->getNode(CENTER); + i = 0; /* only one center */ + CHANGE_DOFS_1(this); + } + } + + + void Element::newDOFFct2(const DOFAdmin* admin) + { + int i, j, k, n0, nd, nd0; + DegreeOfFreedom *ldof; + + int vertices = mesh->getGeo(VERTEX); + int edges = mesh->getGeo(EDGE); + int faces = mesh->getGeo(FACE); + + if ((nd = admin->getNumberOfDOFs(VERTEX))) { + nd0 = admin->getNumberOfPreDOFs(VERTEX); + n0 = admin->getMesh()->getNode(VERTEX); + for (i = 0; i < vertices; i++) { + CHANGE_DOFS_2(this); + } + } + + if(mesh->getDim() > 1) { + if ((nd = admin->getNumberOfDOFs(EDGE))) { + nd0 = admin->getNumberOfPreDOFs(EDGE); + n0 = admin->getMesh()->getNode(EDGE); + for (i = 0; i < edges; i++) { + CHANGE_DOFS_2(this); + } + } + } + + if (3==mesh->getDim()) { + if ((nd = admin->getNumberOfDOFs(FACE))) { + nd0 = admin->getNumberOfPreDOFs(FACE); + n0 = admin->getMesh()->getNode(FACE); + for (i = 0; i < faces; i++) { + CHANGE_DOFS_2(this); + } + } + } + + if ((nd = admin->getNumberOfDOFs(CENTER))) { + nd0 = admin->getNumberOfPreDOFs(CENTER); + n0 = admin->getMesh()->getNode(CENTER); + i = 0; /* only one center */ + CHANGE_DOFS_2(this); + } + } + +#undef CHANGE_DOFS_1 +#undef CHANGE_DOFS_2 + + /****************************************************************************/ + /* opp_vertex checks whether the face with vertices dof[0],..,dof[DIM-1] is */ + /* part of mel's boundary. returns the opposite vertex if true, -1 else */ + /****************************************************************************/ + + int Element::oppVertex(FixVec<DegreeOfFreedom*, DIMEN> pdof) const + { + int i, j, nv = 0, ov = 0; + + int vertices = mesh->getGeo(VERTEX); + int dim = mesh->getDim(); + + for (i = 0; i < vertices; i++) + { + if (nv < i-1) return(-1); + + for (j = 0; j < dim; j++) + { + if (dof[i] == pdof[j]) + { + /****************************************************************************/ + /* i is a common vertex */ + /****************************************************************************/ + ov += i; + nv++; + break; + } + } + + } + if (nv != mesh->getDim()) return(-1); + /****************************************************************************/ + /* the opposite vertex is 3(6) - (sum of indices of common vertices) in */ + /* 2d(3d) */ + /****************************************************************************/ + + switch(mesh->getDim()) { + case 1: + return ov; + break; + case 2: + return 3-ov; + break; + case 3: + return 6-ov; + break; + default: + ERROR_EXIT("invalid dim\n"); + return 0; + } + } + + double Element::getNewCoord(int j) const { + if (j>=0) { + TEST_EXIT(newCoord)("newCoord = NULL\n"); + return (*newCoord)[j]; + } else { + return (newCoord!=NULL); + } + } + + void Element::eraseNewCoord() { + if (newCoord!=NULL) { + DELETE newCoord; + newCoord=NULL; + }; + } + + void Element::serialize(::std::ostream &out) + { + // write children + if(child[0]) { + out << child[0]->getTypeName() << ::std::endl; + child[0]->serialize(out); + child[1]->serialize(out); + } else { + out << "NULL" << ::std::endl; + } + + // write dofs + int dim = mesh->getDim(); + int nodes = mesh->getNumberOfNodes(); + out.write(reinterpret_cast<const char*>(&nodes), sizeof(int)); + + int i, j = 0, ndof, pos; + + for(pos = 0; pos <= dim; pos++) { + GeoIndex position = INDEX_OF_DIM(pos ,dim); + + ndof = 0; + + for(i = 0; i < mesh->getNumberOfDOFAdmin(); i++) { + const DOFAdmin *localAdmin = &mesh->getDOFAdmin(i); + TEST_EXIT(localAdmin)("no admin[%d]\n", i); + ndof += localAdmin->getNumberOfDOFs(position); + } + + if(ndof > 0) { + for(i = 0; i < mesh->getGeo(position); i++) { + if(dof[j] != NULL) { + if(Mesh::serializedDOFs[dof[j][0]] == NULL) { + Mesh::serializedDOFs[dof[j][0]] = dof[j]; + out.write(reinterpret_cast<const char*>(&ndof), sizeof(int)); + out.write(reinterpret_cast<const char*>(dof[j]), + ndof * sizeof(DegreeOfFreedom)); + } else { + int minusOne = -1; + out.write(reinterpret_cast<const char*>(&minusOne), sizeof(int)); + out.write(reinterpret_cast<const char*>(&(dof[j][0])), sizeof(DegreeOfFreedom)); + } + } else { + int zero = 0; + out.write(reinterpret_cast<const char*>(&zero), sizeof(int)); + } + j++; + } + } + } + + // write index + out.write(reinterpret_cast<const char*>(&index), sizeof(int)); + + // write mark + out.write(reinterpret_cast<const char*>(&mark), sizeof(signed char)); + + // write newCoord + if(newCoord) { + out << "WorldVector" << ::std::endl; + newCoord->serialize(out); + } else { + out << "NULL" << ::std::endl; + } + + // write element data + if(elementData) { + out << elementData->getTypeName() << ::std::endl; + elementData->serialize(out); + } else { + out << "NULL" << ::std::endl; + } + } + + void Element::deserialize(::std::istream &in) + { + ::std::string typeName; + + // read children + in >> typeName; + in.get(); + + if(typeName != "NULL") { + if(typeName == "Line") { + child[0] = new Line(NULL); + child[1] = new Line(NULL); + }; + if(typeName == "Triangle") { + child[0] = new Triangle(NULL); + child[1] = new Triangle(NULL); + }; + if(typeName == "Tetrahedron") { + child[0] = new Tetrahedron(NULL); + child[1] = new Tetrahedron(NULL); + }; + child[0]->deserialize(in); + child[1]->deserialize(in); + } else { + child[0] = child[1] = NULL; + } + + // read dofs + int nodes; + in.read(reinterpret_cast<char*>(&nodes), sizeof(int)); + + dof = GET_MEMORY(DegreeOfFreedom*, nodes); + + int i; + for(i = 0; i < nodes; i++) { + int dofs; + in.read(reinterpret_cast<char*>(&dofs), sizeof(int)); + + if(dofs) { + if(dofs != -1) { + dof[i] = GET_MEMORY(DegreeOfFreedom, dofs); + in.read(reinterpret_cast<char*>(dof[i]), dofs * sizeof(DegreeOfFreedom)); + if(Mesh::serializedDOFs[dof[i][0]] != NULL) { + //WARNING("christina -> dofs already deserialized\n"); + DegreeOfFreedom *dofPtr = Mesh::serializedDOFs[dof[i][0]]; + FREE_MEMORY(dof[i], DegreeOfFreedom, dofs); + dof[i] = dofPtr; + } + Mesh::serializedDOFs[dof[i][0]] = dof[i]; + } else { + DegreeOfFreedom index; + in.read(reinterpret_cast<char*>(&index), sizeof(DegreeOfFreedom)); + dof[i] = Mesh::serializedDOFs[index]; + } + } else { + dof[i] = NULL; + } + } + + // read index + in.read(reinterpret_cast<char*>(&index), sizeof(int)); + + // write mark + in.read(reinterpret_cast<char*>(&mark), sizeof(signed char)); + + // read newCoord + in >> typeName; + in.get(); + + if(typeName != "NULL") { + if(typeName == "WorldVector") { + newCoord = NEW WorldVector<double>; + newCoord->deserialize(in); + } else { + ERROR_EXIT("unexpected type name\n"); + } + } else { + newCoord = NULL; + } + + // read element data + in >> typeName; + in.get(); + + if(typeName != "NULL") { + elementData = CreatorMap<ElementData>::getCreator(typeName)->create(); + if(elementData) { + elementData->deserialize(in); + } else { + ERROR_EXIT("unexpected type name\n"); + } + } else { + elementData = NULL; + } + } + +} diff --git a/AMDiS/src/Element.h b/AMDiS/src/Element.h new file mode 100644 index 0000000000000000000000000000000000000000..6f43acad83f28c86ff3daec30ea1386b07faf54f --- /dev/null +++ b/AMDiS/src/Element.h @@ -0,0 +1,594 @@ +// ============================================================================ +// == == +// == AMDiS - Adaptive multidimensional simulations == +// == == +// ============================================================================ +// == == +// == crystal growth group == +// == == +// == Stiftung caesar == +// == Ludwig-Erhard-Allee 2 == +// == 53175 Bonn == +// == germany == +// == == +// ============================================================================ +// == == +// == http://www.caesar.de/cg/AMDiS == +// == == +// ============================================================================ + +/** \file Element.h */ + +#ifndef AMDIS_ELEMENT_H +#define AMDIS_ELEMENT_H + +// ============================================================================ +// ===== includes ============================================================= +// ============================================================================ + +#include "Global.h" +#include "RefinementManager.h" +#include "Serializable.h" +#include "ElementData.h" +#include "LeafData.h" + +namespace AMDiS { + + // ============================================================================ + // ===== forward declarations ================================================= + // ============================================================================ + + class Mesh; + class DOFAdmin; + template<typename T> class WorldVector; + class CoarseningManager; + + template<typename T, GeoIndex d> class FixVec; + +#define AMDIS_UNDEFINED 5 + + // ============================================================================ + // ===== class Element ======================================================== + // ============================================================================ + + /** \ingroup Triangulation + * \brief + * Base class for Line, Triangle, Tetrahedron + * + * Elements in AMDiS are always simplices (a simplex is a Line in 1d, a + * Triangle in 2d and a Tetrahedron in 3d). + * We restrict ourselves here to simplicial meshes, for several reasons: + * -# A simplex is one of the most simple geometric types and complex domains + * may be approximated by a set of simplices quite easily. + * -# Simplicial meshes allow local refinement without the need of + * nonconforming meshes (hanging nodes), parametric elements, or mixture of + * element types (which is the case for quadrilateral meshes). + * -# Polynomials of any degree are easily represented on a simplex using + * local (barycentric) coordinates. + * + * A Line element and its refinement: + * + * <img src="line.png"> + * + * A Triangle element and its refinement: + * + * <img src="triangle.png"> + * + * A Tetrahedron element and its refinements: + * + * <img src="tetrahedron.png"> + */ + class Element : public Serializable + { + private: + /** \brief + * private standard constructor because an Element must know his Mesh + */ + Element() {}; + public: + /** \brief + * constructs an Element which belongs to Mesh + */ + Element(Mesh *); + + /** \brief + * copy constructor + */ + Element(const Element& old); + + /** \brief + * destructor + */ + virtual ~Element(); + + // ===== getting methods ====================================================== + + /** \name getting methods + * \{ + */ + + /** \brief + * Returns \ref child[0] + */ + virtual Element* getFirstChild() const { + return child[0]; + }; + + /** \brief + * Returns \ref child[1] + */ + virtual Element* getSecondChild() const { + return child[1]; + }; + + /** \brief + * Returns \ref child[i], i=0,1 + */ + virtual Element* getChild(int i) const { + FUNCNAME("Element::getChild"); + TEST_EXIT(i==0 || i==1)("i must be 0 or 1\n"); + return child[i]; + }; + + /** \brief + * Returns true if Element is a leaf element (\ref child[0] == NULL), returns + * false otherwise. + */ + inline const bool isLeaf() const { return (child[0]==NULL); }; + + /** \brief + * Returns \ref dof[i][j] which is the j-th DOF of the i-th node of Element. + */ + const DegreeOfFreedom getDOF(int i,int j) const { return dof[i][j];}; + + /** \brief + * Returns \ref dof[i] which is a pointer to the DOFs of the i-th node. + */ + const DegreeOfFreedom* getDOF(int i) const {return dof[i];}; + + /** \brief + * Returns a pointer to the DOFs of this Element + */ + const DegreeOfFreedom** getDOF() const { + return const_cast<const DegreeOfFreedom**>(dof); + }; + + /** \brief + * Returns \ref mesh of Element + */ + inline Mesh* getMesh() const { return mesh; }; + + /** \brief + * Returns \ref elementData's error estimation, if Element is a leaf element + * and has leaf data. + */ + inline double getEstimation(int row) const + { + if(isLeaf()) { + TEST_EXIT(elementData)("leaf element without leaf data\n"); + ElementData *ld = elementData->getElementData(ESTIMATABLE); + TEST_EXIT(ld)("leaf data not estimatable!\n"); + + return dynamic_cast<LeafDataEstimatableInterface*>(ld)-> + getErrorEstimate(row); + } + else return 0.0; + }; + + /** \brief + * Returns Element's coarsening error estimation, if Element is a leaf + * element and if it has leaf data and if this leaf data are coarsenable. + */ + inline double getCoarseningEstimation(int row) { + if(isLeaf()) { + TEST_EXIT(elementData)("leaf element without leaf data\n"); + ElementData *ld = elementData->getElementData(COARSENABLE); + TEST_EXIT(ld)("element data not coarsenable!\n"); + + return dynamic_cast<LeafDataCoarsenableInterface*>(ld)-> + getCoarseningErrorEstimate(row); + } + else return 0.0; + }; + + /** \brief + * Returns region of element if defined, -1 else. + */ + int getRegion() const; + + + /** \brief + * Returns local vertex number of the j-th vertex of the i-th edge + */ + virtual int getVertexOfEdge(int i, int j) const = 0; + + /** \brief + * Returns local vertex number of the vertexIndex-th vertex of the + * positionIndex-th part of type position (vertex, edge, face) + */ + virtual int getVertexOfPosition(GeoIndex position, + int positionIndex, + int vertexIndex) const = 0; + + virtual int getPositionOfVertex(int side, int vertex) const = 0; + + virtual int getEdgeOfFace(int face, int edge) const = 0; + + /** \brief + * Returns the number of parts of type i in this element + */ + virtual int getGeo(GeoIndex i) const = 0; + + /** \brief + * Returns Element's \ref mark + */ + inline const signed char getMark() const { + return mark; + }; + + /** \brief + * Returns \ref newCoord[i] + */ + double getNewCoord(int j) const; + + /** \brief + * Returns Element's \ref index + */ + inline int getIndex() const { + return index; + }; + + /** \brief + * Returns \ref newCoord + */ + inline WorldVector<double>* getNewCoord() const { + return newCoord; + }; + + /** \} */ + + // ===== setting methods ====================================================== + + /** \name setting methods + * \{ + */ + + /** \brief + * Sets \ref child[0] + */ + virtual void setFirstChild(Element *aChild) { child[0] = aChild; }; + + /** \brief + * Sets \ref child[1] + */ + virtual void setSecondChild(Element *aChild) { child[1] = aChild; }; + + /** \brief + * Sets \ref elementData of Element + */ + void setElementData(ElementData* ed) { elementData = ed; }; + + /** \brief + * Sets \ref newCoord of Element. Needed by refinement, if Element has a + * boundary edge on a curved boundary. + */ + inline void setNewCoord(WorldVector<double>* coord) { newCoord = coord; }; + + /** \brief + * Sets \ref mesh. + */ + inline void setMesh(Mesh *m) { mesh = m; }; + + /** \brief + * Sets the pointer to the DOFs of the i-th node of Element + */ + DegreeOfFreedom* setDOF(int i,DegreeOfFreedom* p) {dof[i]=p;return dof[i];}; + + /** \brief + * Checks whether Element is a leaf element and whether it has leaf data. + * If the checks don't fail, leaf data's error estimation is set to est. + */ + inline void setEstimation(double est, int row) + { + if(isLeaf()) { + TEST_EXIT(elementData)("leaf element without leaf data\n"); + ElementData *ld = elementData->getElementData(ESTIMATABLE); + TEST_EXIT(ld)("leaf data not estimatable\n"); + + dynamic_cast<LeafDataEstimatableInterface*>(ld)-> + setErrorEstimate(row, est); + } + else { + ERROR_EXIT("setEstimation only for leaf elements!\n"); + } + }; + + /** \brief + * Sets Element's coarsening error estimation, if Element is a leaf element + * and if it has leaf data and if this leaf data are coarsenable. + */ + inline void setCoarseningEstimation(double est, int row) + { + if(isLeaf()) { + TEST_EXIT(elementData)("leaf element without leaf data\n"); + ElementData *ld = elementData->getElementData(COARSENABLE); + TEST_EXIT(ld)("leaf data not coarsenable\n"); + + dynamic_cast<LeafDataCoarsenableInterface*>(ld)-> + setCoarseningErrorEstimate(row, est); + } + else { + ERROR_EXIT("setEstimation only for leaf elements!\n"); + } + }; + + /** \brief + * Sets Elements \ref mark = mark + 1; + */ + inline void incrementMark() {mark++;} + + /** \brief + * Sets Elements \ref mark = mark - 1; + */ + inline void decrementMark() {if (0<mark) mark--;}; + + /** \brief + * Sets Element's \ref mark + */ + inline void setMark(signed char m) {mark=m;}; + + /** \} */ + + // ===== pure virtual methods ================================================= + + /** \name pure virtual methods + * \{ + */ + + /** \brief + * orient the vertices of edges/faces. + * Used by Estimator for the jumps => same quadrature nodes from both sides! + */ + virtual const FixVec<int,WORLD>& + sortFaceIndices(int face, FixVec<int,WORLD> *vec) const = 0; + + /** \brief + * Returns a copy of itself. Needed by Mesh to create Elements by a + * prototype. + */ + virtual Element *clone() = 0; + + /** \brief + * Returns which side of child[childnr] corresponds to side sidenr of + * this Element. If the child has no corresponding + * side, the return value is negative. *isBisected is true after the + * function call, if the side of the child is only a part of element's + * side, false otherwise. + */ + virtual int getSideOfChild(int childnr, int sidenr, int elType = 0) const = 0; + + /** \brief + * Returns which vertex of elements parent corresponds to the vertexnr of + * the element, if the element is the childnr-th child of the parent. + * If the vertex is the ner vertex at the refinement edge, -1 is returned. + */ + virtual int getVertexOfParent(int childnr, int vertexnr, int elType = 0) const = 0; + + /** \brief + * Returns whether Element is a Line + */ + virtual bool isLine() const = 0; + + /** \brief + * Returns whether Element is a Triangle + */ + virtual bool isTriangle() const = 0; + + /** \brief + * Returns whether Element is a Tetrahedron + */ + virtual bool isTetrahedron() const = 0; + + /** \brief + * Returns whether Element has sideElem as one of its sides. + */ + virtual bool hasSide(Element *sideElem) const = 0; + + /** \} */ + + // ===== other public methods ================================================= + + /** \brief + * assignment operator + */ + Element& operator=(const Element& old); + + /** \brief + * Checks whether the face with vertices dof[0],..,dof[DIM-1] is + * part of mel's boundary. returns the opposite vertex if true, -1 else + */ + int oppVertex(FixVec<DegreeOfFreedom*, DIMEN> pdof) const; + + /** \brief + * Refines Element's leaf data + */ + inline void refineElementData(Element* child1, Element* child2, int elType=0) { + if(elementData) { + bool remove = + elementData->refineElementData(this, child1, child2, elType); + if(remove) { + ElementData *tmp = elementData->getDecorated(); + DELETE elementData; + elementData = tmp; + } + } + }; + + /** \brief + * Coarsens Element's leaf data + */ + inline void coarsenElementData(Element* child1, Element* child2, int elType=0) { + ElementData *childData; + childData = child1->getElementData(); + if(childData) { + childData->coarsenElementData(this, child1, child2, elType); + DELETE childData; + child1->setElementData(NULL); + } + childData = child2->getElementData(); + if(childData) { + childData->coarsenElementData(this, child2, child1, elType); + DELETE childData; + child2->setElementData(NULL); + } + }; + + /** \brief + * Returns pointer to \ref elementData + */ + inline ElementData* getElementData() const { + return elementData; + }; + + inline ElementData* getElementData(int typeID) const { + if(elementData) { + return elementData->getElementData(typeID); + } + return NULL; + }; + + /** \brief + * kills \ref elementData + */ + bool deleteElementData(int typeID) { + FUNCNAME("Element::deleteElementData()"); + if(elementData) { + if(elementData->isOfType(typeID)) { + ElementData *tmp = elementData; + elementData = elementData->getDecorated(); + DELETE tmp; + return true; + } else { + return elementData->deleteDecorated(typeID); + } + } + return false; + }; + + /** \brief + * Returns whether element is refined at side side + * el1, el2 are the corresponding children. + * (not neccessarly the direct children!) + * elementTyp is the type of this element (comes from ElInfo) + */ + bool isRefinedAtSide(int side, Element *el1, Element *el2, + unsigned char elementTyp=255); + + /** \brief + * Returns whether Element's \ref newCoord is set + */ + inline bool isNewCoordSet() const { return (newCoord != NULL);}; + + /** \brief + * Frees memory for \ref newCoord + */ + void eraseNewCoord(); + + // ===== Serializable implementation ===== + + void serialize(::std::ostream &out); + + void deserialize(::std::istream &in); + + // ===== protected methods ==================================================== + protected: + /** \brief + * Sets Element's \ref dof pointer. Used by friend class Mesh. + */ + void setDOFPtrs(); + + /** \brief + * Sets Element's \ref index. Used by friend class Mesh. + */ + inline void setIndex(int i) {index=i ; }; + + /** \brief + * Used by friend class Mesh while dofCompress + */ + void newDOFFct1(const DOFAdmin*); + + /** \brief + * Used by friend class Mesh while dofCompress + */ + void newDOFFct2(const DOFAdmin*); + + protected: + /** \brief + * Pointers to the two children of interior elements of the tree. Pointers + * to NULL for leaf elements. + */ + Element *child[2]; + + /** \brief + * Vector of pointers to DOFs. These pointers must be available for elements + * vertices (for the geometric description of the mesh). There my be pointers + * for the edges, for faces and for the center of an element. They are + * ordered + * the following way: The first N_VERTICES entries correspond to the DOFs at + * the vertices of the element. The next ones are those at the edges, if + * present, then those at the faces, if present, and then those at the + * barycenter, if present. + */ + DegreeOfFreedom **dof; + + /** \brief + * Unique global index of the element. these indices are not strictly ordered + * and may be larger than the number of elements in the binary tree (the list + * of indices may have holes after coarsening). + */ + int index; + + /** \brief + * Marker for refinement and coarsening. if mark is positive for a leaf + * element, this element is refined mark times. if mark is negative for + * a leaf element, this element is coarsened -mark times. + */ + signed char mark; + + /** \brief + * If the element has a boundary edge on a curved boundary, this is a pointer + * to the coordinates of the new vertex that is created due to the refinement + * of the element, otherwise it is a NULL pointer. Thus coordinate + * information + * can be also produced by the traversal routines in the case of curved + * boundary. + */ + WorldVector<double> *newCoord; + + /** \brief + * Pointer to the Mesh this element belongs to + */ + Mesh* mesh; + + /** \brief + * Pointer to Element's leaf data + */ + ElementData* elementData; + + // struct ElementConnection + // { + // Element *connectedElement; + // int connectedToPart; // number of edge/face of this element + // ElementConnection* virtualConnection; + // }; + + // ::std::list<ElementConnection*> connections; + + + friend class Mesh; + }; + +} + +#endif // AMDIS_ELEMENT_H + diff --git a/AMDiS/src/ElementData.cc b/AMDiS/src/ElementData.cc new file mode 100644 index 0000000000000000000000000000000000000000..76707978383ede5f494caf751a350e8c94fb59db --- /dev/null +++ b/AMDiS/src/ElementData.cc @@ -0,0 +1,30 @@ +#include "ElementData.h" + +namespace AMDiS { + + void ElementData::serialize(::std::ostream& out) { + ::std::string decoratedType; + if(decorated_) { + decoratedType = decorated_->getTypeName(); + out << decoratedType << ::std::endl; + decorated_->serialize(out); + } else { + out << "NULL" << ::std::endl; + } + } + + void ElementData::deserialize(::std::istream& in) { + TEST_EXIT(decorated_ == NULL) + ("there are already decorated element data\n"); + ::std::string decoratedType; + in >> decoratedType; + in.get(); + if(decoratedType != "NULL") { + decorated_ = CreatorMap<ElementData>::getCreator(decoratedType)->create(); + decorated_->deserialize(in); + } else { + decorated_ = NULL; + }; + } + +} diff --git a/AMDiS/src/ElementData.h b/AMDiS/src/ElementData.h new file mode 100644 index 0000000000000000000000000000000000000000..e1423de555b224d1cdf1d85e87283cf645ffae16 --- /dev/null +++ b/AMDiS/src/ElementData.h @@ -0,0 +1,177 @@ +// ============================================================================ +// == == +// == AMDiS - Adaptive multidimensional simulations == +// == == +// ============================================================================ +// == == +// == crystal growth group == +// == == +// == Stiftung caesar == +// == Ludwig-Erhard-Allee 2 == +// == 53175 Bonn == +// == germany == +// == == +// ============================================================================ +// == == +// == http://www.caesar.de/cg/AMDiS == +// == == +// ============================================================================ + +/** \file ElementData.h */ + +#ifndef AMDIS_ELEMENTDATA_H +#define AMDIS_ELEMENTDATA_H + +#include "Serializable.h" +#include "CreatorMap.h" + +namespace AMDiS { + + const int ESTIMATABLE = 1; + const int COARSENABLE = 2; + const int PERIODIC = 3; + const int ELEMENT_REGION = 4; + const int SURFACE_REGION = 5; + + // ============================================================================ + // ===== class ElementData ==================================================== + // ============================================================================ + + /** \brief + * Base class for element data. To allow to assign arbitrary data to arbitrary + * elements at run time, the decorator pattern in combination with the + * chain-of-responsibility pattern is applied. So only data have to be managed + * at each element which are used for this element at this time. + */ + class ElementData : public Serializable + { + public: + /** \brief + * constructor + */ + ElementData(ElementData *decorated = NULL) + : decorated_(decorated) + {}; + + /** \brief + * destructor + */ + virtual ~ElementData() {}; + + /** \brief + * Refinement of parent to child1 and child2. + */ + virtual bool refineElementData(Element* parent, + Element* child1, + Element* child2, + int elType) + { + if(decorated_) { + bool remove = + decorated_->refineElementData(parent, child1, child2, elType); + + if(remove) { + ElementData *tmp = decorated_->decorated_; + delete decorated_; + decorated_ = tmp; + } + } + return false; + }; + + /** \brief + * + */ + virtual void coarsenElementData(Element* parent, + Element* thisChild, + Element* otherChild, + int elTypeParent) + { + if(decorated_) { + decorated_->coarsenElementData(parent, + thisChild, + otherChild, + elTypeParent); + delete decorated_; + decorated_ = NULL; + } + }; + + /** \brief + * Returns a copy of this ElementData object including all decorated data. + */ + virtual ElementData *clone() const { + if(decorated_) { + return decorated_->clone(); + } + return NULL; + }; + + /** \brief + * Returns the name of element data type. + */ + virtual const int getTypeID() const = 0; + + /** \brief + * Returns whether the ElemnetData object is of the type specified by + * typeName. Must return true, even if typeName describes a base class. + */ + virtual bool isOfType(int typeID) const = 0; + + /** \brief + * Implements Serializable::serialize(). + */ + virtual void serialize(::std::ostream& out); + + /** \brief + * Implements Serializable::deserialize(). + */ + virtual void deserialize(::std::istream& in); + + /** \brief + * Returns first element data in the chain which is of the spcified type. + */ + inline ElementData *getElementData(int typeID) { + if(this->isOfType(typeID)) { + return this; + } else { + if(decorated_) { + return decorated_->getElementData(typeID); + } + } + return NULL; + }; + + inline ElementData *getDecorated(int typeID) { + if(decorated_) { + return decorated_->getElementData(typeID); + } + return NULL; + }; + + inline bool deleteDecorated(int typeID) { + if(decorated_) { + if(decorated_->isOfType(typeID)) { + ElementData *tmp = decorated_; + decorated_ = decorated_->decorated_; + delete tmp; + return true; + } else { + return decorated_->deleteDecorated(typeID); + } + } + return false; + }; + + inline ElementData *getDecorated() { return decorated_; }; + + protected: + /** \brief + * Pointer to next ElementData object in the chain of responsibility. + */ + ElementData *decorated_; + }; + +} + +#endif diff --git a/AMDiS/src/ElementFileWriter.cc b/AMDiS/src/ElementFileWriter.cc new file mode 100644 index 0000000000000000000000000000000000000000..0dcf8b726b658ef62d9feb8318550c618b0b81c4 --- /dev/null +++ b/AMDiS/src/ElementFileWriter.cc @@ -0,0 +1,275 @@ +#include "ElementFileWriter.h" + +#include "BasisFunction.h" +#include "Parameters.h" +#include "Traverse.h" +#include "AdaptInfo.h" + +using namespace std; + +ElementFileWriter::ElementFileWriter(const std::string& name_, + Mesh *mesh_, + const FiniteElemSpace *feSpace_, + std::map<int, int> &vec_) + : name(name_), + tecplotExt(".plt"), + amdisMeshDatExt(".elem.mesh"), + writeTecPlotFormat(0), + writeAMDiSFormat(0), + appendIndex(0), + indexLength(5), + indexDecimals(3), + tsModulo(1), + timestepNumber(-1), + mesh(mesh_), + feSpace(feSpace_), + vec(vec_) +{ + GET_PARAMETER(0, name + "->output->filename", &filename); + GET_PARAMETER(0, name + "->output->TecPlot format", "%d", + &writeTecPlotFormat); + GET_PARAMETER(0, name + "->output->TecPlot ext", &tecplotExt); + GET_PARAMETER(0, name + "->output->AMDiS format", "%d", &writeAMDiSFormat); + GET_PARAMETER(0, name + "->output->AMDiS mesh-dat ext", &amdisMeshDatExt); + GET_PARAMETER(0, name + "->output->append index", "%d", &appendIndex); + GET_PARAMETER(0, name + "->output->index length", "%d", &indexLength); + GET_PARAMETER(0, name + "->output->index decimals", "%d", &indexDecimals); + GET_PARAMETER(0, name + "->output->write every i-th timestep", "%d", + &tsModulo); + + // TEST_EXIT(vec.size() == mesh->getNumberOfLeaves()) + // ("illegal size !\n"); +} + +void +ElementFileWriter::writeFiles(AdaptInfo *adaptInfo, bool force) +{ + FUNCNAME("ElementFileWriter::writeFiles()"); + + timestepNumber++; + timestepNumber %= tsModulo; + + if((timestepNumber != 0) && !force) return; + + std::string fn = filename; + + if(appendIndex) { + TEST_EXIT(indexLength <= 99)("index lenght > 99\n"); + TEST_EXIT(indexDecimals <= 97)("index decimals > 97\n"); + TEST_EXIT(indexDecimals < indexLength) + ("index length <= index decimals\n"); + + char formatStr[9]; + + sprintf(formatStr, "%%0%d.%df", indexLength, indexDecimals); + + char timeStr[20]; + + sprintf(timeStr, formatStr, adaptInfo ? adaptInfo->getTime() : 0.0); + + fn += timeStr; + } + + + if(writeTecPlotFormat) { + writeTecPlotValues(const_cast<char*>((fn + tecplotExt).c_str())); + MSG("TecPlot file written to %s\n", (fn + tecplotExt).c_str()); + } + + if(writeAMDiSFormat) { + TEST_EXIT(mesh)("no mesh\n"); + + writeMeshDatValues(const_cast<char*>( (fn + amdisMeshDatExt).c_str()), + adaptInfo ? adaptInfo->getTime() : 0.0); + + MSG("MeshDat file written to %s\n", (fn + amdisMeshDatExt).c_str()); + } +} + +void +ElementFileWriter::writeTecPlotValues(const char* filename) +{ + FUNCNAME("ElementFileWriter::writeTecPlotValues()"); + ofstream fout(filename); + + TEST_EXIT(fout)("Could not open file %s !\n", filename); + fout.setf(std::ios::scientific,std::ios::floatfield); + + int dim = mesh->getDim(); + double val; + + + // === Write header. === + fout << "TITLE = \"" << name.c_str() << "\"\n"; + fout << "VARIABLES = "; + switch(dim) { + case 2: fout << "\"x\",\"y\""; + break; + case 3: fout << "\"x\",\"y\",\"z\""; + break; + default: ERROR_EXIT("illegal dimension !\n"); + break; + } + fout << ",\"" << name.c_str() << "\"\n"; + fout << "ZONE T=\"" << name.c_str() << "\"" + << ", N=" << 3*mesh->getNumberOfLeaves() + << ", E=" << mesh->getNumberOfLeaves() + << ", F=FEPOINT, "; + switch(dim) { + case 2: fout << "ET=TRIANGLE\n\n"; + break; + case 3: fout << "ET=TETRAHEDRON\n\n"; + break; + default: ERROR_EXIT("illegal dimension !\n"); + break; + } + + + // === Write vertex coordinates and values (for each element !). === + TraverseStack stack; + + ElInfo *elInfo = stack.traverseFirst(mesh, + -1, + Mesh::CALL_LEAF_EL | + Mesh::FILL_COORDS); + + while(elInfo) { + + // Get element value. + val = (double) vec[elInfo->getElement()->getIndex()]; + + // Write coordinates of all element vertices and element value. + for (int i=0; i<=dim; ++i) { + + for (int j=0; j<dim; ++j) { + fout << elInfo->getCoord(i)[j] << " "; + } + fout << val << "\n"; + } + + elInfo = stack.traverseNext(elInfo); + } // end of: mesh traverse + + + // === Write elements. === + int numLeaves = mesh->getNumberOfLeaves(); + int vertCntr = 0; + fout << "\n"; + for (int i=0; i<numLeaves; ++i) { + + for (int j=0; j<=dim; ++j) { + + ++vertCntr; + fout << vertCntr << " "; + } + fout << "\n"; + } + + + fout.close(); +} + +void +ElementFileWriter::writeMeshDatValues(const char* filename, double time) +{ + FUNCNAME("ElementFileWriter::writeMeshDatValues()"); + ofstream fout(filename); + + TEST_EXIT(fout)("Could not open file %s !\n", filename); + + int dim = mesh->getDim(); + double val; + + // === Write header. === + fout << "mesh name: " << mesh->getName().c_str() << "\n\n"; + fout << "time: " << time << "\n\n"; + fout << "DIM: " << dim << "\n"; + fout << "DIM_OF_WORLD: " << Global::getGeo(WORLD) << "\n\n"; + fout << "number of vertices: " << (dim+1)*mesh->getNumberOfLeaves() << "\n"; + fout << "number of elements: " << mesh->getNumberOfLeaves() << "\n\n"; + + + // === Write vertex coordinates (every vertex for every element). === + fout << "vertex coordinates:\n"; + TraverseStack stack; + + ElInfo *elInfo = stack.traverseFirst(mesh, + -1, + Mesh::CALL_LEAF_EL | + Mesh::FILL_COORDS); + + while(elInfo) { + + // Write coordinates of all element vertices. + for (int i=0; i<=dim; ++i) { + + for (int j=0; j<dim; ++j) { + fout << elInfo->getCoord(i)[j] << " "; + } + fout << "\n"; + } + + elInfo = stack.traverseNext(elInfo); + } // end of: mesh traverse + + + // === Write elements. === + int numLeaves = mesh->getNumberOfLeaves(); + int vertCntr = 0; + fout << "\n"; + fout << "element vertices:\n"; + for (int i=0; i<numLeaves; ++i) { + + for (int j=0; j<=dim; ++j) { + + fout << vertCntr << " "; + ++vertCntr; + } + fout << "\n"; + } + + + // === Write values. === + + // Write values header. + fout << "\n"; + fout << "number of values: 1\n\n"; + fout << "value description: " << name.c_str() << "\n"; + fout << "number of interpolation points: 0" << "\n"; + fout << "type: scalar" << "\n"; + fout << "interpolation type: lagrange" << "\n"; + fout << "interpolation degree: 1" << "\n"; + fout << "end of description: " << name.c_str() << "\n\n"; + + // Write values. + fout << "vertex values: " << name.c_str() << "\n"; + + fout.setf(std::ios::scientific,std::ios::floatfield); + + elInfo = stack.traverseFirst(mesh, + -1, + Mesh::CALL_LEAF_EL); + + while(elInfo) { + + // Get element value. + val = (double) vec[elInfo->getElement()->getIndex()]; + + // Write value for each vertex of each element. + for (int i=0; i<=dim; ++i) { + + fout << val << "\n"; + } + + elInfo = stack.traverseNext(elInfo); + } // end of: mesh traverse + + + // Write values trailor. + fout << "\n"; + fout << "interpolation values: " << name.c_str() << "\n\n\n"; + fout << "element interpolation points: " << name.c_str() << "\n"; + + + fout.close(); +} diff --git a/AMDiS/src/ElementFileWriter.h b/AMDiS/src/ElementFileWriter.h new file mode 100644 index 0000000000000000000000000000000000000000..d46b3f3abbb15a38e1579fbeb9f90ae7dc93c86a --- /dev/null +++ b/AMDiS/src/ElementFileWriter.h @@ -0,0 +1,115 @@ +#ifndef ELEMENTFILEWRITER_H +#define ELEMENTFILEWRITER_H + +#include "FileWriter.h" +#include "FiniteElemSpace.h" +#include "MatrixVector.h" +#include "MemoryManager.h" +#include "Mesh.h" + +using namespace AMDiS; + +class ElementFileWriter : public FileWriterInterface +{ + public: + MEMORY_MANAGED(ElementFileWriter); + + /** + * Constructor. + */ + ElementFileWriter(const std::string& name_, + Mesh *mesh_, + const FiniteElemSpace *feSpace_, + std::map<int, int> &vec_); + + /** + * Implementation of FileWriterInterface::writeFiles(). + */ + void writeFiles(AdaptInfo *adaptInfo, bool force); + + protected: + /** + * Writes element data in tecplot format. + */ + void writeTecPlotValues(const char* filename); + + /** + * Writes element data in AMDiS format (1 file !). + */ + void writeMeshDatValues(const char* filename, double time); + + protected: + /** \brief + * Name. + */ + std::string name; + + /** \brief + * Used filename prefix. + */ + std::string filename; + + /** \brief + * TecPlot file extension. + */ + std::string tecplotExt; + + /** \brief + * AMDiS mesh-data-file extension. + */ + std::string amdisMeshDatExt; + + /** \brief + * 0: Don't write TecPlot files. + * 1: Write TecPlot files. + */ + int writeTecPlotFormat; + + /** \brief + * 0: Don't write AMDiS files. + * 1: Write AMDiS files. + */ + int writeAMDiSFormat; + + /** \brief + * 0: Don't append time index to filename prefix. + * 1: Append time index to filename prefix. + */ + int appendIndex; + + /** \brief + * Total length of appended time index. + */ + int indexLength; + + /** \brief + * Number of decimals in time index. + */ + int indexDecimals; + + /** \brief + * Timestep modulo: write only every tsModulo-th timestep! + */ + int tsModulo; + + /** + */ + int timestepNumber; + + /** \brief + * Mesh used for output. + */ + Mesh *mesh; + + /** \brief + * fespace used for output. + */ + const FiniteElemSpace *feSpace; + + /** \brief + * Vector that stores the solution. + */ + std::map<int, int> vec; +}; + +#endif // ELEMENTFILEWRITER_H diff --git a/AMDiS/src/ElementFunction.h b/AMDiS/src/ElementFunction.h new file mode 100644 index 0000000000000000000000000000000000000000..157696889a659125a9a1553b1b6279d36c16e069 --- /dev/null +++ b/AMDiS/src/ElementFunction.h @@ -0,0 +1,138 @@ +// ============================================================================ +// == == +// == AMDiS - Adaptive multidimensional simulations == +// == == +// ============================================================================ +// == == +// == crystal growth group == +// == == +// == Stiftung caesar == +// == Ludwig-Erhard-Allee 2 == +// == 53175 Bonn == +// == germany == +// == == +// ============================================================================ +// == == +// == http://www.caesar.de/cg/AMDiS == +// == == +// ============================================================================ + +/** \file ElementFunction.h */ + +#ifndef AMDIS_ELEMENTFUNCTION_H +#define AMDIS_ELEMENTFUNCTION_H + +#include "AbstractFunction.h" +#include "DOFVector.h" +#include "BasisFunction.h" + +namespace AMDiS { + + // ============================================================================ + // ===== class ElementFunction ================================================ + // ============================================================================ + + /** \brief + * Abstract access to functions living on elements. + */ + template<typename T> + class ElementFunction : public AbstractFunction<T, DimVec<double> > + { + public: + /** \brief + * constructor. + */ + ElementFunction() : elInfo_(NULL) {}; + + /** \brief + * destructor. + */ + virtual ~ElementFunction() {}; + + /** \brief + * sets \ref elInfo_; + */ + inline void setElInfo(const ElInfo *elInfo) { elInfo_ = elInfo; }; + + protected: + /** \brief + * ElInfo the function currently lives on. + */ + const ElInfo *elInfo_; + }; + + // ============================================================================ + // ===== class ElementFunctionAnalytic ======================================== + // ============================================================================ + + /** \brief + * ElementFunction wich encapsulates the evaluation of an analytical function. + */ + template<typename T> + class ElementFunctionAnalytic : public ElementFunction<T> + { + public: + /** \brief + * constructor + */ + ElementFunctionAnalytic(const AbstractFunction<T, WorldVector<double> > *fct) + : ElementFunction<T>(), + fct_(fct) + {}; + + /** \brief + * evaluation at given coordinates. + */ + const T& operator()(const DimVec<double>& bary) const { + const WorldVector<double> *worldCoords = this->elInfo_->coordToWorld(bary, NULL); + return (*fct_)(*worldCoords); + }; + + protected: + /** \brief + * function to be avaluated at world coordinates. + */ + const AbstractFunction<T, WorldVector<double> > *fct_; + }; + + + // ============================================================================ + // ===== class ElementFunctionDOFVec ========================================== + // ============================================================================ + + /** \brief + * ElementFunction wich encapsulates the interpolation of an DOFVector. + */ + template<typename T> + class ElementFunctionDOFVec : public ElementFunction<T> + { + public: + /** \brief + * constructor. + */ + ElementFunctionDOFVec(const DOFVector<T> *dofVector) + : ElementFunction<T>(), + dofVector_(dofVector) + {}; + + /** \brief + * evaluation at given coordinates. + */ + const T& operator()(const DimVec<double>& bary) const { + static T t; + const T* localVec = + dofVector_->getLocalVector(this->elInfo_->getElement(), NULL); + t = dofVector_->getFESpace()->getBasisFcts()->evalUh(bary, localVec); + return t; + }; + + protected: + /** \brief + * DOFVector to be interpolated. + */ + const DOFVector<T> *dofVector_; + }; + +} + +#endif diff --git a/AMDiS/src/ElementInfo.h b/AMDiS/src/ElementInfo.h new file mode 100644 index 0000000000000000000000000000000000000000..d1a15bf8bf2d63427ae5b6941e00c8fa0b65f975 --- /dev/null +++ b/AMDiS/src/ElementInfo.h @@ -0,0 +1,89 @@ +// ============================================================================ +// == == +// == AMDiS - Adaptive multidimensional simulations == +// == == +// ============================================================================ +// == == +// == crystal growth group == +// == == +// == Stiftung caesar == +// == Ludwig-Erhard-Allee 2 == +// == 53175 Bonn == +// == germany == +// == == +// ============================================================================ +// == == +// == http://www.caesar.de/cg/AMDiS == +// == == +// ============================================================================ + +/** \file ElementInfo.h */ + +#ifndef AMDIS_ELEMENTINFO_H +#define AMDIS_ELEMENTINFO_H + +#include <list> +#include <vector> + +#include "VertexInfo.h" +#include "Boundary.h" +#include "Projection.h" + +namespace AMDiS { + + class VertexInfo; + + /** \brief + * Stores information for one element. + */ + class ElementInfo + { + public: + /** \brief + * Dimension specific constructor for DimVec creation. + */ + ElementInfo(int dim) + : vertices(dim), + vertexInfo(dim, NO_INIT), + boundary(dim, NO_INIT), + projection(dim, NO_INIT), + neighbour(dim, NO_INIT), + surfaceRegions(dim, NO_INIT) + {}; + + int vertices; + + /** \brief + * Vertex infos for each element vertex. + */ + DimVec< ::std::list<VertexInfo>::iterator> vertexInfo; + + /** \brief + * Boundary type for each side. + */ + DimVec<BoundaryType> boundary; + + /** \brief + * Boundary projector for each side. + */ + DimVec<Projection*> projection; + + /** \brief + * Neighbour output index for each side. + */ + DimVec<int> neighbour; + + /** \brief + * Element type. Used in 3d. + */ + unsigned char type; + + int elementRegion; + + DimVec<int> surfaceRegions; + }; + +} + +#endif + diff --git a/AMDiS/src/ElementMatrix.h b/AMDiS/src/ElementMatrix.h new file mode 100644 index 0000000000000000000000000000000000000000..db13efb53610e1b06813d91c9e861ec24c7e2040 --- /dev/null +++ b/AMDiS/src/ElementMatrix.h @@ -0,0 +1,68 @@ +// ============================================================================ +// == == +// == AMDiS - Adaptive multidimensional simulations == +// == == +// ============================================================================ +// == == +// == crystal growth group == +// == == +// == Stiftung caesar == +// == Ludwig-Erhard-Allee 2 == +// == 53175 Bonn == +// == germany == +// == == +// ============================================================================ +// == == +// == http://www.caesar.de/cg/AMDiS == +// == == +// ============================================================================ + +/** \file ElementMatrix.h */ + +#ifndef AMDIS_ELEMENTMATRIX_H +#define AMDIS_ELEMENTMATRIX_H + +#include "MemoryManager.h" +#include "MatrixVector.h" + +namespace AMDiS { + + // ============================================================================= + // ===== class ElementMatrix =================================================== + // ============================================================================= + + /** \ingroup Assembler + * + * \brief + * Stores a single element matrix and the corresponding row and column + * dof indices. + */ + class ElementMatrix : public Matrix<double> + { + public: + MEMORY_MANAGED(ElementMatrix); + + /** \brief + * Constructor. + */ + ElementMatrix(int numRows, int numCols) + : Matrix<double>(numRows, numCols), + rowIndices(numRows), + colIndices(numCols) + {}; + + public: + /** \brief + * row dof indices. + */ + Vector<DegreeOfFreedom> rowIndices; + + /** \brief + * column dof indices. + */ + Vector<DegreeOfFreedom> colIndices; + }; + +} + +#endif // AMDIS_ELEMENTMATRIX_H diff --git a/AMDiS/src/ElementRegion_ED.h b/AMDiS/src/ElementRegion_ED.h new file mode 100644 index 0000000000000000000000000000000000000000..31ca421ab8fe8cd901215d8e65d9ed41e57ec31f --- /dev/null +++ b/AMDiS/src/ElementRegion_ED.h @@ -0,0 +1,107 @@ +// ============================================================================ +// == == +// == AMDiS - Adaptive multidimensional simulations == +// == == +// ============================================================================ +// == == +// == crystal growth group == +// == == +// == Stiftung caesar == +// == Ludwig-Erhard-Allee 2 == +// == 53175 Bonn == +// == germany == +// == == +// ============================================================================ +// == == +// == http://www.caesar.de/cg/AMDiS == +// == == +// ============================================================================ + +/** \file ElementRegion_ED.h */ + +#ifndef AMDIS_ELEMENTREGION_ED_H +#define AMDIS_ELEMENTREGION_ED_H + +#include "ElementData.h" +#include "FixVec.h" + +namespace AMDiS { + + class ElementRegion_ED : public ElementData + { + public: + MEMORY_MANAGED(ElementRegion_ED); + + inline bool isOfType(int typeID) const { + if(typeID == ELEMENT_REGION) + return true; + return false; + }; + + class Creator : public CreatorInterface<ElementData> + { + public: + ElementData* create() { + return NEW ElementRegion_ED; + }; + }; + + ElementRegion_ED(ElementData *decorated = NULL) + : ElementData(decorated), + region_(-1) + {}; + + bool refineElementData(Element* parent, + Element* child1, + Element* child2, + int elType) + { + ElementData::refineElementData(parent, child1, child2, elType); + + ElementRegion_ED *ep; + + ep = NEW ElementRegion_ED(child1->getElementData()); + ep->region_ = region_; + child1->setElementData(ep); + + ep = NEW ElementRegion_ED(child2->getElementData()); + ep->region_ = region_; + child2->setElementData(ep); + + return false; + }; + + ElementData *clone() const { + ElementRegion_ED *newObj = NEW ElementRegion_ED; + newObj->region_ = region_; + newObj->decorated_ = ElementData::clone(); + return newObj; + }; + + inline ::std::string getTypeName() const { return "ElementRegion_ED"; }; + + inline const int getTypeID() const { return ELEMENT_REGION; }; + + void serialize(::std::ostream& out) + { + ElementData::serialize(out); + out.write(reinterpret_cast<const char*>(®ion_), sizeof(int)); + }; + + void deserialize(::std::istream& in) + { + ElementData::deserialize(in); + in.read(reinterpret_cast<char*>(®ion_), sizeof(int)); + }; + + inline void setRegion(int region) { region_ = region; }; + + inline int getRegion() const { return region_; }; + + protected: + int region_; + }; + +} + +#endif diff --git a/AMDiS/src/ElementVector.h b/AMDiS/src/ElementVector.h new file mode 100644 index 0000000000000000000000000000000000000000..d437cc61d10db3743e52d4a0b31289c4fcfe681a --- /dev/null +++ b/AMDiS/src/ElementVector.h @@ -0,0 +1,61 @@ +// ============================================================================ +// == == +// == AMDiS - Adaptive multidimensional simulations == +// == == +// ============================================================================ +// == == +// == crystal growth group == +// == == +// == Stiftung caesar == +// == Ludwig-Erhard-Allee 2 == +// == 53175 Bonn == +// == germany == +// == == +// ============================================================================ +// == == +// == http://www.caesar.de/cg/AMDiS == +// == == +// ============================================================================ + +/** \file ElementVector.h */ + +#ifndef AMDIS_ELEMENTVECTOR_H +#define AMDIS_ELEMENTVECTOR_H + +#include "MemoryManager.h" +#include "MatrixVector.h" + +namespace AMDiS { + + // ============================================================================= + // ===== class ElementVector =================================================== + // ============================================================================= + + /** \ingroup Assembler + * + * \brief + * Stores a single element vector and the corresponding dof indices. + */ + class ElementVector : public Vector<double> + { + public: + MEMORY_MANAGED(ElementVector); + + /** \brief + * Constructor. + */ + ElementVector(int size) + : Vector<double>(size), + dofIndices(size) + {}; + + public: + /** \brief + * dof indices. + */ + Vector<DegreeOfFreedom> dofIndices; + }; + +} + +#endif // AMDIS_ELEMENTVECTOR_H diff --git a/AMDiS/src/EmptyElementData.h b/AMDiS/src/EmptyElementData.h new file mode 100644 index 0000000000000000000000000000000000000000..1865a51f89fb5f24f5abe8b57f13ca46572d38d2 --- /dev/null +++ b/AMDiS/src/EmptyElementData.h @@ -0,0 +1,90 @@ +// ============================================================================ +// == == +// == AMDiS - Adaptive multidimensional simulations == +// == == +// ============================================================================ +// == == +// == crystal growth group == +// == == +// == Stiftung caesar == +// == Ludwig-Erhard-Allee 2 == +// == 53175 Bonn == +// == germany == +// == == +// ============================================================================ +// == == +// == http://www.caesar.de/cg/AMDiS == +// == == +// ============================================================================ + +/** \file EmptyElementData.h */ + +#ifndef AMDIS_EMPTYELEMENTDATA_H +#define AMDIS_EMPTYELEMENTDATA_H + +#include "Element.h" +#include "ElementData.h" +#include "FixVec.h" + +namespace AMDiS { + + const int EMPTY_ED = 6; + + class EmptyElementData : public ElementData + { + public: + MEMORY_MANAGED(EmptyElementData); + + inline bool isOfType(int typeID) const { + if(typeID == EMPTY_ED) + return true; + return false; + }; + + class Creator : public CreatorInterface<ElementData> + { + public: + ElementData* create() { + return NEW EmptyElementData; + }; + }; + + EmptyElementData(ElementData *decorated = NULL) + : ElementData(decorated) + {}; + + bool refineElementData(Element* parent, + Element* child1, + Element* child2, + int elType) + { + ElementData::refineElementData(parent, child1, child2, elType); + child1->setElementData(NEW EmptyElementData(child1->getElementData())); + child2->setElementData(NEW EmptyElementData(child2->getElementData())); + return false; + }; + + ElementData *clone() const { + EmptyElementData *newObj = NEW EmptyElementData; + newObj->decorated_ = ElementData::clone(); + return newObj; + }; + + inline ::std::string getTypeName() const { return "EmptyElementData"; }; + + inline const int getTypeID() const { return EMPTY_ED; }; + + void serialize(::std::ostream& out) + { + ElementData::serialize(out); + }; + + void deserialize(::std::istream& in) + { + ElementData::deserialize(in); + }; + }; + +} + +#endif diff --git a/AMDiS/src/Error.h b/AMDiS/src/Error.h new file mode 100644 index 0000000000000000000000000000000000000000..d7988b1c7e68ae9203a2bdc101ed9b5324517f8e --- /dev/null +++ b/AMDiS/src/Error.h @@ -0,0 +1,164 @@ +// ============================================================================ +// == == +// == AMDiS - Adaptive multidimensional simulations == +// == == +// ============================================================================ +// == == +// == crystal growth group == +// == == +// == Stiftung caesar == +// == Ludwig-Erhard-Allee 2 == +// == 53175 Bonn == +// == germany == +// == == +// ============================================================================ +// == == +// == http://www.caesar.de/cg/AMDiS == +// == == +// ============================================================================ + +/** \file Error.h */ + +#ifndef AMDIS_ERROR_H +#define AMDIS_ERROR_H + +#include "Global.h" +#include "Mesh.h" +#include "MemoryManager.h" + +namespace AMDiS { + + class FastQuadrature; + + template<typename T> class DOFVector; + + // ============================================================================ + // ===== class Error ========================================================== + // ============================================================================ + + /** \ingroup Common + * \brief + * True error calculator + */ + template<typename T> + class Error + { + public: + MEMORY_MANAGED(Error<T>); + + static void setWriteLeafData() { + writeInLeafData = true; + }; + + static void unsetWriteLeafData() { + writeInLeafData = false; + }; + + static bool writeLeafData() { + return writeInLeafData; + }; + + static double maxErrAtQp(const AbstractFunction<T, WorldVector<double> >& u, + const DOFVector<T>& uh, + const Quadrature* q); + + static double H1Err(const AbstractFunction<WorldVector<T>, WorldVector<double> >& grdU, + const DOFVector<T>& uh, + int relErr, + double* max, + bool writeLeafData = false, + int comp = 0); + + static double L2Err(const AbstractFunction<T, WorldVector<double> >& u, + const DOFVector<T>& uh, + int relErr, + double* max, + bool writeLeafData = false, + int comp = 0); + + // methods for traversal + static int maxErrAtQpFct(ElInfo* elinfo); + static int H1ErrFct(ElInfo* elinfo); + static int L2ErrFct(ElInfo* elinfo); + static int relFct(ElInfo* elinfo); + + public: + static const T& errUFct(const DimVec<double>& lambda); + + static const WorldVector<T>& grdErrUFct(const DimVec<double>& lambda); + + /** \brief + * + */ + class AbstrFctErrU : public AbstractFunction<T, DimVec<double> > + { + public: + AbstrFctErrU() : AbstractFunction<T, DimVec<double> >(0) {}; + + inline const T& operator()(const DimVec<double> & x) const { + return Error<T>::errUFct(x); + }; + }; + + static AbstrFctErrU errU; + + /** \brief + * + */ + class AbstrFctGrdErrU : public AbstractFunction<WorldVector<T>, DimVec<double> > + { + public: + AbstrFctGrdErrU() : AbstractFunction<WorldVector<T>, DimVec<double> >(0) {}; + + inline const WorldVector<T>& operator()(const DimVec<double> & x) const { + return Error<T> :: grdErrUFct (x); + }; + }; + + static AbstrFctGrdErrU grdErrU; + + private: + static ElInfo* elinfo; + /* static const Parametric* el_parametric; */ + static const FastQuadrature* quadFast; + static const AbstractFunction<T, WorldVector<double> >* pU; + static const AbstractFunction<WorldVector<T>, WorldVector<double> >* pGrdU; + static const BasisFunction* basFct; + static const DOFVector<T>* errUh; + static double maxErr; + static double l2Err2; + static double l2Norm2; + static int relative; + static double relNorm2; + static double h1Err2; + static double h1Norm2; + static bool writeInLeafData; + static int component; + }; + + template<typename T> ElInfo* Error<T>::elinfo = NULL; + template<typename T> const FastQuadrature* Error<T>::quadFast = NULL; + template<typename T> const AbstractFunction<T, WorldVector<double> >* Error<T>::pU = NULL; + template<typename T> const AbstractFunction<WorldVector<T>, WorldVector<double> >* Error<T>::pGrdU = NULL; + template<typename T> const BasisFunction* Error<T>::basFct = NULL; + template<typename T> const DOFVector<T>* Error<T>::errUh = NULL; + template<typename T> double Error<T>::maxErr = 0.0; + template<typename T> double Error<T>::l2Err2 = 0.0; + template<typename T> double Error<T>::l2Norm2 = 0.0; + template<typename T> int Error<T>::relative = 0; + template<typename T> double Error<T>::relNorm2 = 0.0; + template<typename T> double Error<T>::h1Err2 = 0.0; + template<typename T> double Error<T>::h1Norm2 = 0.0; + template<typename T> typename Error<T>::AbstrFctErrU Error<T>::errU; + template<typename T> typename Error<T>::AbstrFctGrdErrU Error<T>::grdErrU; + template<typename T> bool Error<T>::writeInLeafData = false; + template<typename T> int Error<T>::component = 0; + +} + +#include "Error.hh" + +#endif // AMDIS_ERROR_H + + + diff --git a/AMDiS/src/Error.hh b/AMDiS/src/Error.hh new file mode 100644 index 0000000000000000000000000000000000000000..91cc803f9a97567d7652185c8bc62cfda85aa2c0 --- /dev/null +++ b/AMDiS/src/Error.hh @@ -0,0 +1,379 @@ +#include "Mesh.h" +#include "Parametric.h" +#include "Quadrature.h" + +namespace AMDiS { + + template<typename T> + const T& Error<T>::errUFct(const DimVec<double>& lambda) + { + WorldVector<double> x; + // if (el_parametric) { + // ERROR_EXIT("not yet\n"); + // } else { + elinfo->coordToWorld(lambda, &x); + // } + return((*pU)(x)); + } + + template<typename T> + const WorldVector<T>& Error<T>::grdErrUFct(const DimVec<double>& lambda) + { + WorldVector<double> x; + // if (el_parametric) { + // ERROR_EXIT("not yet\n"); + // } else { + elinfo->coordToWorld(lambda, &x); + // } + return((*pGrdU)(x)); + } + + + template<typename T> + int Error<T>::maxErrAtQpFct(ElInfo* el_info) + { + int i; + double err; + const double *u_vec, *uh_vec; + // Parametric *parametric = el_info->getMesh()->getParametric(); + + elinfo = el_info; + // if (parametric && parametric->initElement(el_info)) { + // el_parametric = parametric; + // } else { + // el_parametric = NULL; + // } + + u_vec = quadFast->getQuadrature()->fAtQp(errU, NULL); + + //uh_el = errUh->getLocalVector(el_info->getElement(), NULL); + //uh_vec = quadFast->uhAtQp(uh_el, NULL); + + uh_vec = errUh->getVecAtQPs(el_info, + NULL, + quadFast, + NULL); + + int numPoints = quadFast->getNumPoints(); + + for (i = 0; i < numPoints; i++) + { + err = u_vec[i] > uh_vec[i] ? u_vec[i] - uh_vec[i] : uh_vec[i] - u_vec[i]; + maxErr = max(maxErr, err); + } + + return; + } + + template<typename T> + double Error<T>::maxErrAtQp(const AbstractFunction<T, WorldVector<double> >& u, + const DOFVector<T>& uh, + const Quadrature* q) + { + FUNCNAME("Error<T>::maxErrAtQp"); + const FiniteElemSpace *fe_space; + + if (!(pU = &u)) + { + ERROR("no function u specified; doing nothing\n"); + return(-1.0); + } + if (!(errUh = &uh) || !(fe_space = uh->getFESpace())) + { + ERROR("no discrete function or no fe_space for it; doing nothing\n"); + return(-1.0); + } + + if (!(basFct = fe_space->getBasisFcts())) + { + ERROR("no basis functions at discrete solution ; doing nothing\n"); + return(-1.0); + } + + int dim = fe_space->getMesh()->getDim(); + + if (!q) + q = Quadrature::provideQuadrature(dim, + 2*fe_space->getBasisFcts()->getDegree() + - 2); + quadFast = FastQuadrature::provideFastQuadrature(basFct, *q, INIT_PHI); + + maxErr = 0.0; + + fe_space->getMesh()->traverse(-1, + Mesh::FILL_COORDS | + Mesh::CALL_LEAF_EL, + maxErrAtQpFct); + + return(maxErr); + } + + template<typename T> + int Error<T>::H1ErrFct(ElInfo* el_info) + { + int i, j; + double err, err_2, h1_err_el, norm_el, norm2, det, exact; + //int dim = el_info->getMesh()->getDim(); + //const DimVec<WorldVector<double> > &Lambda = el_info->getGrdLambda(); + //const T *uh_el; + const WorldVector<double> *grdu_vec, *grduh_vec; + // const Parametric *parametric = el_info->getMesh()->getParametric(); + + elinfo = el_info; + // if (parametric && parametric->initElement(el_info)) { + // el_parametric = parametric; + // } + // else { + // el_parametric = NULL; + // } + + grdu_vec = quadFast->getQuadrature()->grdFAtQp(grdErrU, NULL); + + //uh_el = errUh->getLocalVector(el_info->getElement(), NULL); + + // if (el_parametric) { + // el_parametric->grd_lambda(el_info, NULL, 1, NULL, &Lambda, &det); + // } + // else { + det = el_info->getDet(); + // } + + //grduh_vec = quadFast->grdUhAtQp(Lambda, uh_el, NULL); + grduh_vec = errUh->getGrdAtQPs(elinfo, NULL, quadFast, NULL); + + int numPoints = quadFast->getNumPoints(); + int dow = Global::getGeo(WORLD); + + for (h1_err_el = i = 0; i < numPoints; i++) + { + for (err_2 = j = 0; j < dow; j++) + { + err = grdu_vec[i][j] - grduh_vec[i][j]; + err_2 += sqr(err); + } + h1_err_el += quadFast->getWeight(i)*err_2; + } + + exact = det*h1_err_el; + h1Err2 += exact; + maxErr = max(maxErr, exact); + + if (writeInLeafData) + el_info->getElement()->setEstimation(exact, component); + + if (relative) { + for (norm_el = i = 0; i < numPoints; i++) { + for (norm2 = j = 0; j < dow; j++) + norm2 += sqr(grdu_vec[i][j]); + norm_el += quadFast->getWeight(i)*norm2; + } + h1Norm2 += det*norm_el; + } + + return 0; + } + + template<typename T> + double Error<T>::H1Err( + const AbstractFunction<WorldVector<T>, WorldVector<double> >& grdU, + const DOFVector<T>& uh, + //const Quadrature* quad, + int relErr, + double* max, + bool writeLeafData, + int comp) + { + FUNCNAME("Error<T>::H1Err"); + const FiniteElemSpace *fe_space; + + writeInLeafData = writeLeafData; + + component = comp; + + Quadrature *q = NULL; + + pGrdU = &grdU; + + errUh = &uh; + + if(!(fe_space = uh.getFESpace())) + { + ERROR("no fe_space for uh; doing nothing\n"); + return(0.0); + } + + if (!(basFct = fe_space->getBasisFcts())) + { + ERROR("no basis functions at discrete solution ; doing nothing\n"); + return(0.0); + } + + int dim = fe_space->getMesh()->getDim(); + int deg = grdU.getDegree(); + int degree = deg ? deg : 2 * fe_space->getBasisFcts()->getDegree() - 2; + + //if (!quad) + q = Quadrature::provideQuadrature(dim, degree); + quadFast = FastQuadrature::provideFastQuadrature(basFct, + *q, + INIT_GRD_PHI); + + relative = relErr; + + maxErr = h1Err2 = h1Norm2 = 0.0; + + + fe_space->getMesh()->traverse(-1, + Mesh::FILL_COORDS | + Mesh::CALL_LEAF_EL | + Mesh::FILL_DET | + Mesh::FILL_GRD_LAMBDA, + H1ErrFct); + + if (relative) { + relNorm2 = h1Norm2 + 1.e-15; + + fe_space->getMesh()->traverse(-1, Mesh::CALL_LEAF_EL, relFct); + + h1Err2 /= relNorm2; + maxErr /= relNorm2; + } + + if (max) *max = maxErr; + + return(sqrt(h1Err2)); + } + + template<typename T> + int Error<T>::L2ErrFct(ElInfo* el_info) + { + int i; + double err, det, l2_err_el, norm_el, exact; + const double *u_vec, *uh_vec; + // Parametric *parametric = const_cast<Parametric*>(el_info->getMesh()->getParametric()); + + elinfo = el_info; + + // if (parametric && parametric->initElement(el_info)) { + // el_parametric = parametric; + // } + // else { + // el_parametric = NULL; + // } + + u_vec = quadFast->getQuadrature()->fAtQp(errU, NULL); + + //uh_el = errUh->getLocalVector(el_info->getElement(), NULL); + //uh_vec = quadFast->uhAtQp(uh_el, NULL); + + uh_vec = errUh->getVecAtQPs(el_info, + NULL, + quadFast, + NULL); + + // if (el_parametric) { + // el_parametric->det(el_info, NULL, 1, NULL, &det); + // } + // else { + // det = el_info->calcDet(); + // } + + det = el_info->getDet(); + + int numPoints = quadFast->getNumPoints(); + + for (l2_err_el = i = 0; i < numPoints; i++) { + err = u_vec[i] - uh_vec[i]; + l2_err_el += quadFast->getWeight(i)*sqr(err); + } + + exact = det*l2_err_el; + l2Err2 += exact; + maxErr = max(maxErr, exact); + + if (writeInLeafData) { + el_info->getElement()->setEstimation(exact, component); + } + + if (relative) { + for (norm_el = i = 0; i < numPoints; i++) + norm_el += quadFast->getWeight(i)*sqr(u_vec[i]); + l2Norm2 += det*norm_el; + } + + return 0; + } + + template<typename T> + double Error<T>::L2Err(const AbstractFunction<T, WorldVector<double> >& u, + const DOFVector<T>& uh, + int relErr, + double* max, + bool writeLeafData, + int comp) + { + FUNCNAME("Error<T>::L2Err"); + const FiniteElemSpace *fe_space; + + Quadrature *q = NULL; + + writeInLeafData = writeLeafData; + + component = comp; + + if (!(pU = &u)) { + ERROR("no function u specified; doing nothing\n"); + return(0.0); + } + + if (!(errUh = &uh) || !(fe_space = uh.getFESpace())) { + ERROR("no discrete function or no fe_space for it; doing nothing\n"); + return(0.0); + } + + if (!(basFct = fe_space->getBasisFcts())) { + ERROR("no basis functions at discrete solution ; doing nothing\n"); + return(0.0); + } + + int dim = fe_space->getMesh()->getDim(); + int deg = u.getDegree(); + int degree = deg ? deg : 2 * fe_space->getBasisFcts()->getDegree() - 2; + + q = Quadrature::provideQuadrature(dim, degree); + quadFast = FastQuadrature::provideFastQuadrature(basFct, *q, INIT_PHI); + + relative = relErr; + + maxErr = l2Err2 = l2Norm2 = 0.0; + + fe_space->getMesh()->traverse(-1, + Mesh::FILL_COORDS | + Mesh::FILL_DET | + Mesh::FILL_GRD_LAMBDA | + Mesh::CALL_LEAF_EL, + L2ErrFct); + + if (relative) { + relNorm2 = l2Norm2 + 1.e-15; + fe_space->getMesh()->traverse(-1, Mesh::CALL_LEAF_EL, relFct); + l2Err2 /= relNorm2; + } + + if (max) + *max = maxErr; + + return (sqrt(l2Err2)); + } + + template<typename T> + int Error<T>::relFct(ElInfo* elinfo) + { + double exact = elinfo->getElement()->getEstimation(component); + exact /= relNorm2; + if (writeInLeafData) + elinfo->getElement()->setEstimation(exact, component); + return 0; + } + +} diff --git a/AMDiS/src/Estimator.cc b/AMDiS/src/Estimator.cc new file mode 100755 index 0000000000000000000000000000000000000000..54bdb40bc2a1be90deb3fed956a0ccefe28bfb68 --- /dev/null +++ b/AMDiS/src/Estimator.cc @@ -0,0 +1,572 @@ +#include "Estimator.h" +#include "Operator.h" +#include "DOFMatrix.h" +#include "DOFVector.h" +#include "Assembler.h" +#include "Traverse.h" +#include "Parameters.h" + +namespace AMDiS { + + void r(const ElInfo *elInfo, + int numPoints, + const double *uhIq, + const WorldVector<double> *grdUhIq, + const WorldMatrix<double> *D2UhIq, + const double *uhOldIq, + const WorldVector<double> *grdUhOldIq, + const WorldMatrix<double> *D2UhOldIq, + DOFMatrix *A, + DOFVector<double> *fh, + Quadrature *quad, + double *result) + { + ::std::vector<Operator*>::iterator it; + ::std::vector<double*>::iterator fac; + double factor; + + // lhs + for(it = const_cast<DOFMatrix*>(A)->getOperatorsBegin(), + fac = const_cast<DOFMatrix*>(A)->getOperatorEstFactorBegin(); + it != const_cast<DOFMatrix*>(A)->getOperatorsEnd(); + ++it, ++fac) + { + factor = *fac ? **fac : 1.0; + if (factor) { + if (D2UhIq) { + (*it)->evalSecondOrder(numPoints, uhIq, grdUhIq, D2UhIq, result, -factor); + } + + if (grdUhIq) { + (*it)->evalFirstOrderGrdPsi(numPoints, uhIq, grdUhIq, D2UhIq, result, factor); + (*it)->evalFirstOrderGrdPhi(numPoints, uhIq, grdUhIq, D2UhIq, result, factor); + } + + if (uhIq) { + (*it)->evalZeroOrder(numPoints, uhIq, grdUhIq, D2UhIq, result, factor); + } + } + } + + // rhs + for(it = const_cast<DOFVector<double>*>(fh)->getOperatorsBegin(), + fac = const_cast<DOFVector<double>*>(fh)->getOperatorEstFactorBegin(); + it != const_cast<DOFVector<double>*>(fh)->getOperatorsEnd(); + ++it, ++fac) + { + factor = *fac ? **fac : 1.0; + if(factor) { + if((*it)->getUhOld()) { + if(D2UhOldIq) { + (*it)->evalSecondOrder(numPoints, + uhOldIq, grdUhOldIq, D2UhOldIq, + result, factor); + } + if(grdUhOldIq) { + (*it)->evalFirstOrderGrdPsi(numPoints, + uhOldIq, grdUhOldIq, D2UhOldIq, + result, -factor); + (*it)->evalFirstOrderGrdPhi(numPoints, + uhOldIq, grdUhOldIq, D2UhOldIq, + result, -factor); + } + if(uhOldIq) { + (*it)->evalZeroOrder(numPoints, + uhOldIq, grdUhOldIq, D2UhOldIq, + result, -factor); + } + } else { + int iq; + double *fx = GET_MEMORY(double, numPoints); + for(iq = 0; iq < numPoints; iq++) { + fx[iq] = 0.0; + } + (*it)->getC(elInfo, numPoints, fx); + + for(iq = 0; iq < numPoints; iq++) { + result[iq] -= factor * fx[iq]; + } + FREE_MEMORY(fx, double, numPoints); + } + } + } + } + + double Estimator::estimate(double ts) + { + FUNCNAME("Estimator::estimate()"); + + init(ts); + + TraverseStack stack; + ElInfo *elInfo = stack.traverseFirst(mesh, -1, traverseFlag); + while(elInfo) { + estimateElement(elInfo); + elInfo = stack.traverseNext(elInfo); + } + + exit(); + return est_sum; + } + + void ResidualEstimator::init(double ts) + { + FUNCNAME("ResidualEstimator::init()"); + + timestep = ts; + + mesh = uh[row == -1 ? 0 : row]->getFESpace()->getMesh(); + + numSystems = static_cast<int>(uh.size()); + TEST_EXIT(numSystems > 0)("no system set\n"); + + dim = mesh->getDim(); + basFcts = GET_MEMORY(const BasisFunction*, numSystems); + quadFast = GET_MEMORY(FastQuadrature*, numSystems); + + degree = 0; + for(system = 0; system < numSystems; system++) { + basFcts[system] = uh[system]->getFESpace()->getBasisFcts(); + degree = ::std::max(degree, basFcts[system]->getDegree()); + } + + degree *= 2; + + quad = Quadrature::provideQuadrature(dim, degree); + numPoints = quad->getNumPoints(); + + Flag flag = INIT_PHI | INIT_GRD_PHI; + if(degree > 2) flag |= INIT_D2_PHI; + + for(system = 0; system < numSystems; system++) { + quadFast[system] = FastQuadrature::provideFastQuadrature(basFcts[system], + *quad, + flag); + } + + + + uhEl = GET_MEMORY(double*, numSystems); + uhOldEl = timestep ? GET_MEMORY(double*, numSystems) : NULL; + + for(system = 0; system < numSystems; system++) { + uhEl[system] = GET_MEMORY(double, basFcts[system]->getNumber()); + if(timestep) + uhOldEl[system] = GET_MEMORY(double, basFcts[system]->getNumber()); + } + + //const double *uhQP = NULL; + uhQP = timestep ? GET_MEMORY(double, quad->getNumPoints()) : NULL; + uhOldQP = + timestep ? GET_MEMORY(double, quad->getNumPoints()) : NULL; + + + riq = GET_MEMORY(double, numPoints); + + TraverseStack stack; + ElInfo *elInfo = NULL; + + // clear error indicators and mark elements for jumpRes + elInfo = stack.traverseFirst(mesh, -1, Mesh::CALL_LEAF_EL); + while(elInfo) { + elInfo->getElement()->setEstimation(0.0, row); + elInfo->getElement()->setMark(1); + // elInfo->getElement()->setEstimation(0.0); + elInfo = stack.traverseNext(elInfo); + } + + est_sum = est_max = est_t_sum = est_t_max = 0.0; + traverseFlag = + Mesh::FILL_NEIGH | + Mesh::FILL_COORDS | + Mesh::FILL_OPP_COORDS | + Mesh::FILL_BOUND | + Mesh::FILL_GRD_LAMBDA | + Mesh::FILL_DET | + Mesh::CALL_LEAF_EL; + } + + void ResidualEstimator::exit() + { + FUNCNAME("ResidualEstimator::exit()"); + + est_sum = sqrt(est_sum); + est_t_sum = sqrt(est_t_sum); + + for(system = 0; system < numSystems; system++) { + FREE_MEMORY(uhEl[system], double, basFcts[system]->getNumber()); + if(timestep) + FREE_MEMORY(uhOldEl[system], double, basFcts[system]->getNumber()); + } + + FREE_MEMORY(uhEl, double*, numSystems); + if(timestep) + FREE_MEMORY(uhOldEl, double*, numSystems); + + if(timestep) { + FREE_MEMORY(uhQP, double, numPoints); + FREE_MEMORY(uhOldQP, double, numPoints); + } + + MSG("estimate = %.8e\n", est_sum); + if(C3) + MSG("time estimate = %.8e\n", est_t_sum); + + FREE_MEMORY(riq, double, numPoints); + FREE_MEMORY(basFcts, const BasisFunction*, numSystems); + FREE_MEMORY(quadFast, FastQuadrature*, numSystems); + } + + void ResidualEstimator::estimateElement(ElInfo *elInfo) + { + FUNCNAME("ResidualEstimator::estimateElement()"); + + double est_el; + double val; + Element *el, *neigh; + int iq; + + TEST_EXIT(numSystems > 0)("no system set\n"); + + ::std::vector<Operator*>::iterator it; + + const WorldVector<double> *grdUh_qp = NULL; + const WorldMatrix<double> *D2uhqp = NULL; + + el = elInfo->getElement(); + + double det = elInfo->getDet(); + const DimVec<WorldVector<double> > &Lambda = elInfo->getGrdLambda(); + + est_el = el->getEstimation(row); + + double h2 = h2_from_det(det, dim); + + for(iq = 0; iq < numPoints; iq++) { + riq[iq] = 0.0; + } + + for(system = 0; system < numSystems; system++) { + + if(matrix[system] == NULL) continue; + + // init assemblers + ::std::vector<Operator*>::iterator it; + + for(it = const_cast<DOFMatrix*>(matrix[system])->getOperatorsBegin(); + it != const_cast<DOFMatrix*>(matrix[system])->getOperatorsEnd(); + ++it) + { + (*it)->getAssembler()->initElement(elInfo, quad); + } + + for(it = const_cast<DOFVector<double>*>(fh[system])->getOperatorsBegin(); + it != const_cast<DOFVector<double>*>(fh[system])->getOperatorsEnd(); + ++it) + { + (*it)->getAssembler()->initElement(elInfo, quad); + } + + //uh[system]->getLocalVector(el, uhEl); + if(timestep) { + TEST_EXIT(uhOld[system])("no uhOld\n"); + uhOld[system]->getLocalVector(el, uhOldEl[system]); + } + + // ===== time and element residuals + if (timestep && (C0 || C3)) { + //quadFast->uhAtQp(uhEl, uhQP); + uh[system]->getVecAtQPs(elInfo, NULL, quadFast[system], uhQP); + //quadFast->uhAtQp(uhOldEl, uhOldQP); + uhOld[system]->getVecAtQPs(elInfo, NULL, quadFast[system], uhOldQP); + + if(C3 && uhOldQP && system == ::std::max(row, 0)) { + for (val = iq = 0; iq < numPoints; iq++) { + double tiq = (uhQP[iq] - uhOldQP[iq]); + val += quad->getWeight(iq)*tiq*tiq; + } + double v = C3*det*val; + est_t_sum += v; + est_t_max = max(est_t_max, v); + } + } + + if (C0) { + for(it = const_cast<DOFMatrix*>(matrix[system])->getOperatorsBegin(); + it != const_cast<DOFMatrix*>(matrix[system])->getOperatorsEnd(); + ++it) + { + if((*it)->zeroOrderTerms() && !uhQP) { + //uhQP = const_cast<double*> + // (quadFast->uhAtQp(uhEl, static_cast<double*>(NULL))); + uhQP = const_cast<double*> + (uh[system]->getVecAtQPs(elInfo, NULL, quadFast[system], NULL)); + } + if((*it)->firstOrderTermsGrdPsi() || (*it)->firstOrderTermsGrdPhi() + && !grdUh_qp) + { + grdUh_qp = + //quadFast->grdUhAtQp(Lambda, + // const_cast<const double*>(uhEl), + // static_cast<WorldVector<double>*>(NULL)); + uh[system]->getGrdAtQPs(elInfo, NULL, quadFast[system], NULL); + } + if((*it)->secondOrderTerms() && !D2uhqp) { + if(degree > 2) + D2uhqp = + // quadFast->D2UhAtQp(Lambda, + // uhEl, + // static_cast<WorldMatrix<double>*>(NULL)); + uh[system]->getD2AtQPs(elInfo, NULL, quadFast[system], NULL); + } + } + + r(elInfo, + numPoints, + uhQP, + grdUh_qp, + D2uhqp, + uhOldQP, + NULL, // grdUhOldQP + NULL, // D2UhOldQP + matrix[system], + fh[system], + quad, + riq); + } + } + + // add integral over r square + for(val = iq = 0; iq < numPoints; iq++) { + val += quad->getWeight(iq)*riq[iq]*riq[iq]; + } + + if (timestep != 0.0 || norm == NO_NORM || norm == L2_NORM) + val = C0*h2*h2*det*val; + else + val = C0*h2*det*val; + + est_el += val; + + // ===== jump residuals + int neighbours = Global::getGeo(NEIGH, dim); + int face; + + if(dim > 1) { + Quadrature *surfaceQuad = Quadrature::provideQuadrature(dim-1, degree); + + int numPointsSurface = surfaceQuad->getNumPoints(); + + Vector<WorldVector<double> > jump(numPointsSurface); + + if (C1) { + for (face = 0; face < neighbours; face++) { + if ((neigh = const_cast<Element*>(elInfo->getNeighbour(face)))) { + if (neigh->getMark()) { + ElInfo *neighInfo = mesh->createNewElInfo(); + WorldVector<int> faceIndEl, faceIndNeigh; + Element *neigh = + const_cast<Element*>(elInfo->getNeighbour(face)); + int oppV = elInfo->getOppVertex(face); + DimVec<WorldVector<double> > LambdaNeigh(dim, NO_INIT); + double detNeigh; + DimVec<double> lambda(dim, NO_INIT); + + el->sortFaceIndices(face, &faceIndEl); + neigh->sortFaceIndices(oppV, &faceIndNeigh); + + neighInfo->setElement(const_cast<Element*>(neigh)); + neighInfo->setFillFlag(Mesh::FILL_COORDS); + + int dow = Global::getGeo(WORLD); + + int i, j, i1, i2; + + for (i = 0; i < dow; i++) + neighInfo->getCoord(oppV)[i] = elInfo->getOppCoord(face)[i]; + + // periodic leaf data ? + ElementData *ldp = el->getElementData()->getElementData(PERIODIC); + + bool periodicCoords = false; + + if(ldp) { + ::std::list<LeafDataPeriodic::PeriodicInfo>::iterator it; + for(it = dynamic_cast<LeafDataPeriodic*>(ldp)->getInfoList().begin(); + it != dynamic_cast<LeafDataPeriodic*>(ldp)->getInfoList().end(); + ++it) + { + if(it->elementSide == face) { + for(i=0; i < dim; i++) { + i1 = faceIndEl[i]; + i2 = faceIndNeigh[i]; + + for(j=0; j < dim; j++) { + if(i1 == el->getVertexOfPosition(INDEX_OF_DIM(dim-1, + dim), + face, + j)) + { + break; + } + } + + TEST_EXIT(j != dim)("vertex i1 not on face ???\n"); + + neighInfo->getCoord(i2) = (*(it->periodicCoords))[j]; + } + periodicCoords = true; + break; + } + } + } + + if(!periodicCoords) { + for (i = 0; i < dim; i++) { + i1 = faceIndEl[i]; + i2 = faceIndNeigh[i]; + for (j = 0; j < dow; j++) + neighInfo->getCoord(i2)[j] = elInfo->getCoord(i1)[j]; + } + } + + Parametric *parametric = mesh->getParametric(); + if(parametric) { + neighInfo = parametric->addParametricInfo(neighInfo); + } + + detNeigh = abs(neighInfo->calcGrdLambda(LambdaNeigh)); + + Vector<WorldVector<double> > grdUhEl(numPointsSurface); + Vector<WorldVector<double> > grdUhNeigh(numPointsSurface); + + for(iq = 0; iq < numPointsSurface; iq++) { + jump[iq].set(0.0); + } + + for(system = 0; system < numSystems; system++) { + if(matrix[system] == NULL) continue; + + uh[system]->getLocalVector(el, uhEl[system]); + + const double* uhNeigh; + + uhNeigh = uh[system]->getLocalVector(neigh, NULL); + + for (iq = 0; iq < numPointsSurface; iq++) { + lambda[face] = 0.0; + for (i = 0; i < dim; i++) + lambda[faceIndEl[i]] = surfaceQuad->getLambda(iq,i); + basFcts[system]->evalGrdUh(lambda, Lambda, uhEl[system], &grdUhEl[iq]); + + lambda[oppV] = 0.0; + for (i = 0; i < dim; i++) + lambda[faceIndNeigh[i]] = surfaceQuad->getLambda(iq,i); + basFcts[system]->evalGrdUh(lambda, + LambdaNeigh, + uhNeigh, + &grdUhNeigh[iq]); + + grdUhEl[iq] -= grdUhNeigh[iq]; + } + + ::std::vector<double*>::iterator fac; + + for(it = const_cast<DOFMatrix*>(matrix[system])->getOperatorsBegin(), + fac = const_cast<DOFMatrix*>(matrix[system])->getOperatorEstFactorBegin(); + it != const_cast<DOFMatrix*>(matrix[system])->getOperatorsEnd(); + ++it, ++fac) + { + int i; + Vector<WorldVector<double> > localJump(numPointsSurface); + for(iq = 0; iq < numPointsSurface; iq++) { + localJump[iq].set(0.0); + } + + (*it)->weakEvalSecondOrder(numPointsSurface, + grdUhEl.getValArray(), + localJump.getValArray()); + double factor = *fac ? **fac : 1.0; + if(factor != 1.0) { + for(i = 0; i < numPointsSurface; i++) { + localJump[i] *= factor; + } + } + + for(i = 0; i < numPointsSurface; i++) { + jump[i] += localJump[i]; + } + } + } + + for(val =iq = 0; iq < numPointsSurface; iq++) { + val += surfaceQuad->getWeight(iq)*(jump[iq]*jump[iq]); + } + + double d = 0.5*(det + detNeigh); + + if (norm == NO_NORM || norm == L2_NORM) + val *= C1*h2_from_det(d, dim) * d; + else + val *= C1*d; + + if(parametric) { + neighInfo = parametric->removeParametricInfo(neighInfo); + } + + DELETE neighInfo; + + neigh->setEstimation(neigh->getEstimation(row) + val, row); + + est_el += val; + } + } + } + + val = fh[::std::max(row, 0)]-> + getBoundaryManager()-> + boundResidual(elInfo, matrix[::std::max(row, 0)], uh[::std::max(row, 0)]); + if (norm == NO_NORM || norm == L2_NORM) + val *= C1 * h2; + else + val *= C1; + + est_el += val; + } + } + + el->setEstimation(est_el, row); + + est_sum += est_el; + est_max = max(est_max, est_el); + + elInfo->getElement()->setMark(0); + } + + Estimator::Estimator(::std::string name_, int r) + : name(name_), + norm(NO_NORM), + row(r) + { + GET_PARAMETER(0, name + "->error norm", "%d", &norm); + } + + ResidualEstimator::ResidualEstimator(::std::string name, int r) + : Estimator(name, r), + C0(1.0), + C1(1.0), + C2(1.0), + C3(1.0) + { + GET_PARAMETER(0, name + "->C0", "%f", &C0); + GET_PARAMETER(0, name + "->C1", "%f", &C1); + GET_PARAMETER(0, name + "->C2", "%f", &C2); + GET_PARAMETER(0, name + "->C3", "%f", &C3); + + C0 = C0 > 1.e-25 ? sqr(C0) : 0.0; + C1 = C1 > 1.e-25 ? sqr(C1) : 0.0; + C2 = C2 > 1.e-25 ? sqr(C2) : 0.0; + C3 = C3 > 1.e-25 ? sqr(C3) : 0.0; + } + +} diff --git a/AMDiS/src/Estimator.h b/AMDiS/src/Estimator.h new file mode 100755 index 0000000000000000000000000000000000000000..8f1cc13f9382e21391cbf5e3522ad10dbab434df --- /dev/null +++ b/AMDiS/src/Estimator.h @@ -0,0 +1,408 @@ +// ============================================================================ +// == == +// == AMDiS - Adaptive multidimensional simulations == +// == == +// ============================================================================ +// == == +// == crystal growth group == +// == == +// == Stiftung caesar == +// == Ludwig-Erhard-Allee 2 == +// == 53175 Bonn == +// == germany == +// == == +// ============================================================================ +// == == +// == http://www.caesar.de/cg/AMDiS == +// == == +// ============================================================================ + +/** \file Estimator.h */ + +/** \defgroup Estimator Estimator module + * @{ <img src="estimator.png"> @} + */ + +#ifndef AMDIS_ESTIMATOR_H +#define AMDIS_ESTIMATOR_H + +#include "Flag.h" +#include "Global.h" +#include "FixVec.h" +#include "SystemVector.h" +#include "CreatorInterface.h" + +namespace AMDiS { + + class ElInfo; + class Quadrature; + class FastQuadrature; + class BasisFunction; + + class ProblemInstat; + template<typename T> class DOFVector; + class RobinBC; + class DOFMatrix; + + /** \brief + * Returns residual square at quadrature point. Not Member of + * Estimator to avoid multiple instantiation. + */ + void r(const ElInfo *elInfo, + int numPoints, + const double *uhIq, + const WorldVector<double> *grdUhIq, + const WorldMatrix<double> *D2UhIq, + const double *uhOldIq, + const WorldVector<double> *grdUhOldIq, + const WorldMatrix<double> *D2UhOldIq, + DOFMatrix *A, + DOFVector<double> *fh, + Quadrature *quad, + double *result); + + /** \brief + * Returns pow(det,2.0/dim). Not Member of + * Estimator to avoid multiple instantiation. + */ + inline double h2_from_det(double det, int dim) { + return pow(det,2.0/dim); + }; + + + // ============================================================================ + // ===== class Estimator ====================================================== + // ============================================================================ + + /** + * \ingroup Estimator + * + * \brief + * Estimator for scalar problems. + */ + class Estimator + { + public: + MEMORY_MANAGED(Estimator); + + Estimator() {}; + + /** \brief + * Constructor. + */ + Estimator(::std::string name_, int r); + + /** \brief + * destructor + */ + virtual ~Estimator() {}; + + /** \brief + * Returns \ref name of the Estimator + */ + inline const ::std::string& getName() const { + return name; + }; + + /** \brief + * Performs the estimation and returns the final \ref est_sum + */ + virtual double estimate(double timestep = 0.0); + + virtual void init(double timestep) {}; + + virtual void estimateElement(ElInfo *elInfo) {}; + + virtual void exit() {}; + + /** \brief + * Returns \ref est_sum of the Estimator + */ + inline double getErrorSum() const { + return est_sum; + }; + + /** \brief + * Sets \ref est_sum of the Estimator + */ + inline void setErrorSum(double sum) { + est_sum = sum; + }; + + /** \brief + * Returns \ref est_max of the Estimator + */ + inline double getErrorMax() const { + return est_max; + }; + + /** \brief + * Returns the estimated time error. + */ + virtual double getTimeEst() const { + return est_t_sum; + }; + + /** \brief + * Returns the maximal time estimation. + */ + virtual double getTimeEstMax() const { + return est_t_max; + }; + + /** \brief + * Sets \ref est_max of the Estimator + */ + inline void setErrorMax(double m) { + est_max = m; + }; + + /** \brief + * Returns \ref norm. + */ + inline Norm getErrorNorm() { + return norm; + }; + + /** \brief + * Adds one system to the estimator. + */ + void addSystem(DOFMatrix *matrix_, + DOFVector<double> *uh_, + DOFVector<double> *fh_, + DOFVector<double> *uhOld_ = NULL) + { + matrix.push_back(matrix_); + uh.push_back(uh_); + fh.push_back(fh_); + uhOld.push_back(uhOld_); + }; + + /** \brief + * Adds pointer to old solution to the given system. + */ + void addUhOldToSystem(int system, DOFVector<double> *uhOld_) + { + TEST_EXIT(static_cast<int>(uhOld.size()) > system)("invalid system\n"); + TEST_EXIT(uhOld[system] == NULL)("there is already an uhOld\n"); + uhOld[system] = uhOld_; + } + + /** \brief + * Returns number of systems. + */ + inline int getNumSystems() { + return static_cast<int>(matrix.size()); + }; + + inline Flag getTraverseFlag() { return traverseFlag; }; + inline Mesh* getMesh() { return mesh; }; + + inline int getRow() { return row; }; + + protected: + /** \brief + * Name of the Estimator + */ + ::std::string name; + + /** \brief + * Used norm + */ + Norm norm; + + /** \brief + * Sum of all error estimates + */ + double est_sum; + + /** \brief + * Sum of all time error estimates + */ + double est_t_sum; + + /** \brief + * Max of all time error estimates + */ + double est_t_max; + + /** \brief + * Maximal error estimate + */ + double est_max; + + /** \brief + * Vector of DOFMatrix pointers. There can be more than one + * DOFMatrix, if the Estimator is part of a vector valued + * estimator. Then it contains also coupling matrices + * of the different vector components. + */ + ::std::vector<DOFMatrix*> matrix; + + /** \brief + * Vector of solution vectors for the different systems. + */ + ::std::vector<DOFVector<double>*> uh; + + /** \brief + * Vector of old solutions vectors for the different systems. + * Used for instationary problems. + */ + ::std::vector<DOFVector<double>*> uhOld; + + /** \brief + * Vector of RHS vectors for the different systems. + */ + ::std::vector<DOFVector<double>*> fh; + + /** \brief + * Used, if the scalar estimator builds one row of a vector valued estimator. + * Then row gives the position in the vector valued estimator, used + * for calculation of the time derivative. + */ + int row; + + Flag traverseFlag; + + Mesh *mesh; + + double timestep; + }; + + // ============================================================================ + // ===== class EstimatorCreator =============================================== + // ============================================================================ + + /** + * \ingroup Estimator + * + * \brief + * Interface for creators of concrete estimators. + */ + class EstimatorCreator : public CreatorInterface<Estimator> + { + public: + /** \brief + * constructor + */ + EstimatorCreator() : row(-1) {}; + + /** \brief + * destructor + */ + virtual ~EstimatorCreator() {}; + + /** \brief + * Sets \ref name + */ + void setName(::std::string name_) { name = name_; }; + + /** \brief + * Sets \ref row + */ + void setRow(int r) { row = r; }; + + protected: + /** \brief + * Name of the estimator to be created. + */ + ::std::string name; + + /** \brief + * Row of the estimator. + */ + int row; + }; + + // ============================================================================ + // ===== class ResidualEstimator ============================================== + // ============================================================================ + + /** + * \ingroup Estimator + * + * \brief + * Estimator for scalar problems. + */ + class ResidualEstimator : public Estimator + { + public: + MEMORY_MANAGED(ResidualEstimator); + + /** \brief + * Creator class used in the OEMSolverMap. + */ + class Creator : public EstimatorCreator + { + public: + MEMORY_MANAGED(Creator); + + Creator() : EstimatorCreator() {}; + + virtual ~Creator() {}; + + /** \brief + * Returns a new ODirSolver object. + */ + Estimator* create() { + return NEW ResidualEstimator(name, row); + }; + }; + + + /** \brief + * Constructor. + */ + ResidualEstimator(::std::string name, int r); + + virtual void init(double timestep); + + virtual void estimateElement(ElInfo *elInfo); + + virtual void exit(); + + /* /\** \brief */ + /* * Implements \ref Estimator::estimate(). */ + /* *\/ */ + /* virtual double estimate(double timestep = 0.0); */ + + protected: + /** \brief + * Constant in front of element residual + */ + double C0; + + /** \brief + * Constant in front of edge/face residual + */ + double C1; + + /** \brief + * Constant in front of coarsening term + */ + double C2; + + /** \brief + * Constant in fromt of the time + */ + double C3; + + int numSystems; + int numPoints; + int system; + int dim; + int degree; + Quadrature *quad; + FastQuadrature **quadFast; + const BasisFunction **basFcts; + + double **uhEl; + double **uhOldEl; + double *uhQP; + double *uhOldQP; + double *riq; + }; + +} + +#endif // AMDIS_ESTIMATOR_H diff --git a/AMDiS/src/FileWriter.cc b/AMDiS/src/FileWriter.cc new file mode 100644 index 0000000000000000000000000000000000000000..cc8317bc5d4738d284ea3183702bb175ff58d430 --- /dev/null +++ b/AMDiS/src/FileWriter.cc @@ -0,0 +1,177 @@ +#include "FileWriter.h" +#include "SystemVector.h" +#include "Parameters.h" +#include "TecPlotWriter.h" +#include "ValueWriter.h" +#include "MacroWriter.h" +#include "VtkWriter.h" +#include "DataCollector.h" +#include "FiniteElemSpace.h" +#include "AdaptInfo.h" +#include "Flag.h" +#include "ElInfo.h" +#include "Mesh.h" + +namespace AMDiS { + + FileWriter::FileWriter(const ::std::string &name_, + Mesh *mesh_, + DOFVector<double> *vec) + : name(name_), + tecplotExt(".tec"), + amdisMeshExt(".mesh"), + amdisDataExt(".dat"), + paraViewFileExt(".vtu"), + periodicFileExt(".per"), + writeTecPlotFormat(0), + writeAMDiSFormat(0), + writeParaViewFormat(0), + writePeriodicFormat(0), + appendIndex(0), + indexLength(5), + indexDecimals(3), + tsModulo(1), + mesh(mesh_) + { + readParameters(); + + feSpace = vec->getFESpace(); + + solutionVecs_.resize(1); + solutionVecs_[0] = vec; + } + + FileWriter::FileWriter(const ::std::string &name_, + Mesh *mesh_, + ::std::vector< DOFVector<double>* > vecs) + : name(name_), + tecplotExt(".tec"), + amdisMeshExt(".mesh"), + amdisDataExt(".dat"), + paraViewFileExt(".vtu"), + periodicFileExt(".per"), + writeTecPlotFormat(0), + writeAMDiSFormat(0), + writeParaViewFormat(0), + writePeriodicFormat(0), + appendIndex(0), + indexLength(5), + indexDecimals(3), + tsModulo(1), + mesh(mesh_) + { + FUNCNAME("FileWriter::FileWriter()"); + + readParameters(); + + for (int i = 0; i < static_cast<int>(vecs.size()); i++) { + TEST_EXIT(vecs[0]->getFESpace() == vecs[i]->getFESpace()) + ("All FESpace have to be equal!\n"); + } + + feSpace = vecs[0]->getFESpace(); + solutionVecs_ = vecs; + } + + void FileWriter::readParameters() + { + FUNCNAME("FileWriter::readParamters()"); + + GET_PARAMETER(0, name + "->filename", &filename); + GET_PARAMETER(0, name + "->TecPlot format", "%d", &writeTecPlotFormat); + GET_PARAMETER(0, name + "->TecPlot ext", &tecplotExt); + GET_PARAMETER(0, name + "->AMDiS format", "%d", &writeAMDiSFormat); + GET_PARAMETER(0, name + "->AMDiS mesh ext", &amdisMeshExt); + GET_PARAMETER(0, name + "->AMDiS data ext", &amdisDataExt); + GET_PARAMETER(0, name + "->ParaView format", "%d", &writeParaViewFormat); + GET_PARAMETER(0, name + "->ParaView ext", ¶ViewFileExt); + GET_PARAMETER(0, name + "->Periodic format", "%d", &writePeriodicFormat); + GET_PARAMETER(0, name + "->Periodic ext", &periodicFileExt); + GET_PARAMETER(0, name + "->append index", "%d", &appendIndex); + GET_PARAMETER(0, name + "->index length", "%d", &indexLength); + GET_PARAMETER(0, name + "->index decimals", "%d", &indexDecimals); + GET_PARAMETER(0, name + "->write every i-th timestep", "%d", &tsModulo); + } + + void FileWriter::writeFiles(AdaptInfo *adaptInfo, + bool force, + int level, + Flag flag, + bool (*writeElem)(ElInfo*)) + { + FUNCNAME("FileWriter::writeFiles()"); + + if ((adaptInfo->getTimestepNumber() % tsModulo != 0) && !force) + return; + + ::std::string fn = filename; + + if (appendIndex) { + TEST_EXIT(indexLength <= 99)("index lenght > 99\n"); + TEST_EXIT(indexDecimals <= 97)("index decimals > 97\n"); + TEST_EXIT(indexDecimals < indexLength)("index length <= index decimals\n"); + + char formatStr[9]; + + sprintf(formatStr, "%%0%d.%df", indexLength, indexDecimals); + + char timeStr[20]; + + sprintf(timeStr, formatStr, adaptInfo ? adaptInfo->getTime() : 0.0); + + fn += timeStr; + } + + ::std::vector< DataCollector* > dc(solutionVecs_.size()); + + if (writeElem) { + for (int i = 0; i < static_cast<int>(dc.size()); i++) { + dc[i] = NEW DataCollector(feSpace, solutionVecs_[i], + level, flag, writeElem); + } + } else { + for (int i = 0; i < static_cast<int>(dc.size()); i++) { + dc[i] = NEW DataCollector(feSpace, solutionVecs_[i], + traverseLevel, flag | traverseFlag, writeElement); + } + } + + + if (writeTecPlotFormat) { + TecPlotWriter<DOFVector<double> >::writeValues(solutionVecs_[0], + const_cast<char*>((fn + tecplotExt).c_str()), + solutionVecs_[0]->getName().c_str()); + MSG("TecPlot file written to %s\n", (fn + tecplotExt).c_str()); + } + + if (writeAMDiSFormat) { + TEST_EXIT(mesh)("no mesh\n"); + + MacroWriter::writeMacro(dc[0], + const_cast<char*>( (fn + amdisMeshExt).c_str()), + adaptInfo ? adaptInfo->getTime() : 0.0); + MSG("macro file written to %s\n", (fn + amdisMeshExt).c_str()); + + + ValueWriter::writeValues(dc[0], + (fn + amdisDataExt).c_str(), + adaptInfo ? adaptInfo->getTime() : 0.0); + MSG("value file written to %s\n", (fn + amdisDataExt).c_str()); + } + + if (writePeriodicFormat) { + MacroWriter::writePeriodicFile(dc[0], + (fn + periodicFileExt).c_str()); + MSG("periodic file written to %s\n", (fn + periodicFileExt).c_str()); + } + + if (writeParaViewFormat) { + VtkWriter::writeFile(&dc, const_cast<char*>( (fn + paraViewFileExt).c_str())); + MSG("ParaView file written to %s\n", (fn + paraViewFileExt).c_str()); + } + + for (int i = 0; i < static_cast<int>(dc.size()); i++) { + DELETE dc[i]; + } + } +} diff --git a/AMDiS/src/FileWriter.h b/AMDiS/src/FileWriter.h new file mode 100644 index 0000000000000000000000000000000000000000..f76ce925141891eded71ccfad01bfe911adae803 --- /dev/null +++ b/AMDiS/src/FileWriter.h @@ -0,0 +1,249 @@ +// ============================================================================ +// == == +// == AMDiS - Adaptive multidimensional simulations == +// == == +// ============================================================================ +// == == +// == crystal growth group == +// == == +// == Stiftung caesar == +// == Ludwig-Erhard-Allee 2 == +// == 53175 Bonn == +// == germany == +// == == +// ============================================================================ +// == == +// == http://www.caesar.de/cg/AMDiS == +// == == +// ============================================================================ + +/** \file FileWriter.h */ + +/** \defgroup Output Output module + * @{ <img src="output.png"> @} + */ + +#ifndef AMDIS_FILEWRITER_H +#define AMDIS_FILEWRITER_H + +#include <string> +#include "MemoryManager.h" +#include "MatrixVector.h" +#include "Mesh.h" + +namespace AMDiS { + + class ProblemScal; + class ProblemInstat; + class Mesh; + class SystemVector; + class FiniteElemSpace; + class AdaptInfo; + + template<typename T> class DOFVector; + + // ============================================================================ + // ===== class FileWriterInterface ============================================ + // ============================================================================ + + class FileWriterInterface + { + public: + FileWriterInterface() + : filename(""), + traverseLevel(-1), + traverseFlag(Mesh::CALL_LEAF_EL), + writeElement(NULL) + {}; + + virtual ~FileWriterInterface() {}; + + /** \brief + * Interface. Must be overridden in subclasses. + * \param time time index of solution vector. + * \param force enforces the output operation for the last timestep. + */ + virtual void writeFiles(AdaptInfo *adaptInfo, bool force, + int level = -1, + Flag traverseFlag = Mesh::CALL_LEAF_EL, + bool (*writeElem)(ElInfo*) = NULL) = 0; + + void setTraverseProperties(int level, + Flag flag, + bool (*writeElem)(ElInfo*)) + { + traverseLevel = level; + traverseFlag |= flag; + writeElement = writeElem; + }; + + ::std::string getFilename() { + return filename; + }; + + void setFilename(::std::string n) { + filename = n; + }; + + protected: + /** \brief + * Used filename prefix. + */ + ::std::string filename; + + int traverseLevel; + + Flag traverseFlag; + + bool (*writeElement)(ElInfo*); + }; + + // ============================================================================ + // ===== class FileWriter ===================================================== + // ============================================================================ + + /** + * \ingroup Output + * + * \brief + * Base class of FileWriterScal and FileWriterVec. Manages the file output + * of solution vectors. + */ + class FileWriter : public FileWriterInterface + { + public: + MEMORY_MANAGED(FileWriter); + + /** \brief + * Constructor for a filewriter for one data component. + */ + FileWriter(const ::std::string& name_, + Mesh *mesh_, + DOFVector<double> *vec); + + /** \brief + * Constructor for a filewriter with more than one data component. + */ + FileWriter(const ::std::string& name_, + Mesh *mesh_, + ::std::vector< DOFVector<double>* > vecs); + + /** \brief + * Destructor. + */ + virtual ~FileWriter() {}; + + /** \brief + * Implementation of FileWriterInterface::writeFiles(). + */ + virtual void writeFiles(AdaptInfo *adaptInfo, bool force, + int level = -1, + Flag traverseFlag = Mesh::CALL_LEAF_EL, + bool (*writeElem)(ElInfo*) = NULL); + + protected: + /** \brief + * Reads all file writer dependend parameters from the init file. + */ + void readParameters(); + + /** \brief + * Name of the writer. + */ + ::std::string name; + + /** \brief + * TecPlot file extension. + */ + ::std::string tecplotExt; + + /** \brief + * AMDiS mesh-file extension. + */ + ::std::string amdisMeshExt; + + /** \brief + * AMDiS solution-file extension. + */ + ::std::string amdisDataExt; + + /** \brief + * VTK file extension. + */ + ::std::string paraViewFileExt; + + /** \brief + * Periodic file extension. + */ + ::std::string periodicFileExt; + + /** \brief + * 0: Don't write TecPlot files. + * 1: Write TecPlot files. + */ + int writeTecPlotFormat; + + /** \brief + * 0: Don't write AMDiS files. + * 1: Write AMDiS files. + */ + int writeAMDiSFormat; + + /** \brief + * 0: Don't write ParaView files. + * 1: Write ParaView files. + */ + int writeParaViewFormat; + + /** \brief + * 0: Don't write periodic files. + * 1: Write periodic files. + */ + int writePeriodicFormat; + + /** \brief + * 0: Don't append time index to filename prefix. + * 1: Append time index to filename prefix. + */ + int appendIndex; + + /** \brief + * Total length of appended time index. + */ + int indexLength; + + /** \brief + * Number of decimals in time index. + */ + int indexDecimals; + + /** \brief + * Timestep modulo: write only every tsModulo-th timestep! + */ + int tsModulo; + + /** + */ + int timestepNumber; + + /** \brief + * Mesh used for output. + */ + Mesh *mesh; + + /** \brief + * fespace used for output. + */ + const FiniteElemSpace *feSpace; + + /** \brief + * Pointer to a vector which stores the solution. + */ + DOFVector<double> *vec_; + + ::std::vector< DOFVector<double>* > solutionVecs_; + }; + +} + +#endif // AMDIS_FILEWRITER_H diff --git a/AMDiS/src/FiniteElemSpace.cc b/AMDiS/src/FiniteElemSpace.cc new file mode 100644 index 0000000000000000000000000000000000000000..4827b8ba4da2ec6579e5d085a1a41613d1a696c3 --- /dev/null +++ b/AMDiS/src/FiniteElemSpace.cc @@ -0,0 +1,71 @@ +#include "FiniteElemSpace.h" +#include "DOFAdmin.h" +#include "DOFVector.h" +#include "BasisFunction.h" +#include "Mesh.h" +#include <algorithm> + +namespace AMDiS { + + ::std::vector<FiniteElemSpace*> FiniteElemSpace::feSpaces; + + FiniteElemSpace::FiniteElemSpace(DOFAdmin* admin_, + const BasisFunction* bas_fcts_, + Mesh* aMesh, const ::std::string& aString) + : name(aString), admin(admin_), basFcts(bas_fcts_), mesh(aMesh) + { + FUNCNAME("FiniteElemSpace::FiniteElemSpace()"); + + TEST_EXIT(mesh)("no Mesh\n"); + + if (!admin) { + const DOFAdmin *admin_local = NULL; + int i, j; + const DimVec<int> *ndof = NULL; + ndof = basFcts->getNumberOfDOFs(); + TEST_EXIT(ndof)("no n_dof or basFcts->n_dof\n"); + for (i = 0; i < mesh->getNumberOfDOFAdmin(); i++) { + admin_local = &(mesh->getDOFAdmin(i)); + for (j = 0; j <= mesh->getDim(); j++) { + if (admin_local->getNumberOfDOFs(j) != (*ndof)[j]) break; + } + if (j > mesh->getDim()) break; + admin_local = NULL; + } + if (!admin_local) { + admin_local = mesh->createDOFAdmin(name, *ndof); + } + admin = const_cast<DOFAdmin*>(admin_local); + } + + feSpaces.push_back(this); + } + + FiniteElemSpace *FiniteElemSpace::provideFESpace(DOFAdmin *admin, + const BasisFunction *basFcts, + Mesh *mesh, + const ::std::string& name_) + { + int numSpaces = static_cast<int>(feSpaces.size()); + + for (int i = 0; i < numSpaces; i++) { + if (admin) { + if (feSpaces[i]->admin == admin) { + return feSpaces[i]; + } + } else { + if (feSpaces[i]->basFcts == basFcts && feSpaces[i]->mesh == mesh) { + return feSpaces[i]; + } + } + } + + if(admin) { + ERROR_EXIT("no fespace found for this admin\n"); + return NULL; + } else { + return NEW FiniteElemSpace(NULL, basFcts, mesh, name_); + } + } + +} diff --git a/AMDiS/src/FiniteElemSpace.h b/AMDiS/src/FiniteElemSpace.h new file mode 100644 index 0000000000000000000000000000000000000000..d2d9c9eadfb5a42a5addc45d01d818a2a6619c80 --- /dev/null +++ b/AMDiS/src/FiniteElemSpace.h @@ -0,0 +1,133 @@ +// ============================================================================ +// == == +// == AMDiS - Adaptive multidimensional simulations == +// == == +// ============================================================================ +// == == +// == crystal growth group == +// == == +// == Stiftung caesar == +// == Ludwig-Erhard-Allee 2 == +// == 53175 Bonn == +// == germany == +// == == +// ============================================================================ +// == == +// == http://www.caesar.de/cg/AMDiS == +// == == +// ============================================================================ + +/** \file FiniteElemSpace.h */ + +/** \defgroup FEMSpace FEMSpace + * @{ <img src="femspace.png"> @} + */ + +#ifndef AMDIS_FINITEELEMSPACE_H +#define AMDIS_FINITEELEMSPACE_H + +#include <string> +#include <vector> +#include "MemoryManager.h" + +namespace AMDiS { + + // ============================================================================ + // ===== forward declarations ================================================= + // ============================================================================ + + class DOFAdmin; + class BasisFunction; + class Mesh; + + template<typename T> class DOFVector; + template<typename T> class DimVec; + + // ============================================================================ + // ===== class FiniteElemSpace ================================================ + // ============================================================================ + + /** \ingroup FEMSpace + * \brief + * A FiniteElemSpace is a triple of a DOFAdmin and a set of BasisFunction on a + * Mesh. + */ + class FiniteElemSpace + { + public: + MEMORY_MANAGED(FiniteElemSpace); + + + /** \brief + * + */ + static FiniteElemSpace *provideFESpace(DOFAdmin *admin, + const BasisFunction *basFcts, + Mesh *mesh, + const ::std::string& name_=""); + + /** \brief + * destructor + */ + virtual ~FiniteElemSpace() {}; + + /** \brief + * Returns \ref name + */ + inline ::std::string getName() const { return name;}; + + /** \brief + * Returns \ref admin + */ + inline DOFAdmin* getAdmin() const { return admin;}; + + /** \brief + * Returns \ref basFcts + */ + inline const BasisFunction* getBasisFcts() const { return basFcts;}; + + /** \brief + * Returns \ref mesh + */ + inline Mesh* getMesh() const { return mesh; }; + + protected: + /** \brief + * Constructs a FiniteElemSpace with name name_ and the given DOFAdmin, + * BasisFunction and Mesh. + */ + FiniteElemSpace(DOFAdmin* admin_, + const BasisFunction* basisFcts, + Mesh* mesh, + const ::std::string& name_=""); + + protected: + /** \brief + * Name of this FiniteElemSpace + */ + const ::std::string name; + + /** \brief + * DOFAdmin corresponding to this FiniteElemSpace + */ + DOFAdmin* admin; + + /** \brief + * set of BasisFunction of this FiniteElemSpace + */ + const BasisFunction* basFcts; + + /** \brief + * The Mesh this FiniteElemSpace belongs to + */ + Mesh* mesh; + + /** \brief + * + */ + static ::std::vector<FiniteElemSpace*> feSpaces; + }; + +} + +#endif // !_FINITEELEMSPACE_H_ diff --git a/AMDiS/src/FixVec.cc b/AMDiS/src/FixVec.cc new file mode 100644 index 0000000000000000000000000000000000000000..b7740449f5aa9e9d97e5c9f2cde092700b49ab77 --- /dev/null +++ b/AMDiS/src/FixVec.cc @@ -0,0 +1,35 @@ +#include <stdarg.h> +#include "FixVec.h" + +namespace AMDiS { + + VectorOfFixVecs<DimVec<double> > *createAndInit(int dim, int size, ...) + { + va_list arg; + va_start(arg, size); + VectorOfFixVecs<DimVec<double> > *result = + NEW VectorOfFixVecs<DimVec<double> >(dim, size, NO_INIT); + for(int i=0; i < size; i++) { + for(int j=0; j < dim+1; j++) { + (*result)[i][j] = va_arg(arg, double); + } + } + va_end(arg); + return result; + }; + + double* createAndInitArray(int size, ...) + { + va_list arg; + va_start(arg, size); + double *result = GET_MEMORY(double, size); + + for(int i=0; i < size; i++) { + result[i] = va_arg(arg, double); + } + + va_end(arg); + return result; + } + +} diff --git a/AMDiS/src/FixVec.h b/AMDiS/src/FixVec.h new file mode 100644 index 0000000000000000000000000000000000000000..101236db39cda2ac387f0b7260d9d28b150ef7ea --- /dev/null +++ b/AMDiS/src/FixVec.h @@ -0,0 +1,702 @@ +// ============================================================================ +// == == +// == AMDiS - Adaptive multidimensional simulations == +// == == +// ============================================================================ +// == == +// == crystal growth group == +// == == +// == Stiftung caesar == +// == Ludwig-Erhard-Allee 2 == +// == 53175 Bonn == +// == germany == +// == == +// ============================================================================ +// == == +// == http://www.caesar.de/cg/AMDiS == +// == == +// ============================================================================ + +/** \file FixVec.h */ + +#ifndef AMDIS_FIXVEC_H +#define AMDIS_FIXVEC_H + +// =========================================================================== +// ===== includes ============================================================ +// =========================================================================== + +#include "Global.h" +#include "MemoryManager.h" +#include <iostream> +#include "MatrixVector.h" + +namespace AMDiS { + + // =========================================================================== + // ===== forward declarations ================================================ + // =========================================================================== + + class Mesh; + template<typename T> class WorldVector; + template<typename T> class WorldMatrix; + + + // =========================================================================== + // ===== definitions ========================================================= + // =========================================================================== + + /** determines how to initialize a FixVec when constructed */ + enum InitType + { + NO_INIT = 0, /**< no initialisation */ + VALUE_LIST = 1, /**< a complete value list is given */ + DEFAULT_VALUE = 2, /**< all values ar set to a given default value */ + UNIT_VECTOR = 3, /**< the i-th value is 1, all other values are 0 */ + UNIT_MATRIX = 4 /**< values at the diagonal of a matrix are set to one */ + }; + + // =========================================================================== + // ===== class FixVec ======================================================== + // =========================================================================== + + /** \ingroup Common + * \brief + * A FixVec is a template vector of a fixed size. + * + * The size is determined at construction time and depends on the dimension + * and the template parameter d. So a FixVec<int, VERTEX> is a integer vector + * with 3 entries in 2d and with 4 entries in 3d. The dimension and the way + * the vector should be initialized are specified by the constructor call. + */ + template<typename T,GeoIndex d> + class FixVec : public Vector<T> + { + public: + MEMORY_MANAGED(FixVec<T COMMA d>); + + /** \brief + * constructor without initialisation. initType must be NO_INIT. If dim is + * not spezified, a FixVec for DIM_OF_WORLD is created. + */ + FixVec(int dim = -1, InitType initType = NO_INIT) + : Vector<T>(calcSize(dim)) + { + TEST_EXIT(initType == NO_INIT)("wrong initType or missing initializer\n"); + } + + /** \brief + * constructor with value list initialisation. initType must be VALUE_LIST. + * ini is an array which contains the initialisation values. + */ + FixVec(int dim, InitType initType, const T* ini) + : Vector<T>(calcSize(dim)) + { + TEST_EXIT(initType == VALUE_LIST)("wrong initType or wrong initializer\n"); + setValues(ini); + }; + + /** \brief + * constructor with default value initialisation. initType must be + * DEFAULT_VALUE. All vector entries are set to ini. + */ + FixVec(int dim, InitType initType, const T& ini) + : Vector<T>(calcSize(dim)) + { + TEST_EXIT(initType==DEFAULT_VALUE)("wrong initType or wrong initializer\n"); + this->set(ini); + } + + /** \brief + * Initialisation for dim. + */ + inline void init(int dim) + { + TEST_EXIT(this->getSize() == 0)("already initialized\n"); + resize(calcSize(dim)); + }; + + /** \brief + * Initialisation for size + */ + inline void initSize(int size) + { + //TEST_EXIT(getSize() == 0)("already initialized\n"); + this->resize(size); + }; + + /** \brief + * Returns the \ref size_ of the FixVec. + */ + inline int size() const { + return this->getSize(); + }; + + protected: + /** \brief + * Determines needed vector size. + */ + static int calcSize(int dim) { + if (dim < 0) { + //TEST_EXIT(d==WORLD)("dimension needed\n"); + return Global::getGeo(WORLD); + } else { + return Global::getGeo(d, dim); + } + }; + + public: + friend class GLWindow; + }; + + + // =========================================================================== + // ===== class VectorOfFixVecs =============================================== + // =========================================================================== + + /** \ingroup Common + * \brief + * Contains an vector of FixVecs of same type. To simply allocate an array of + * FixVecs + * isn't possible, because the FixVec constructor normally needs at least + * the corresponding dimension. So you must create an array of FixVec pointers + * and call the constructor of each FixVec manually. When you use + * VectorOfFixVecs, this work is done by VectorOfFixVecs's constructor. + */ + template<typename FixVecType> + class VectorOfFixVecs + { + public: + MEMORY_MANAGED(VectorOfFixVecs<FixVecType>); + + /** \brief + * constructs a VectorOfFixVecs without initialisation. dim is passed to + * FixVec's constructors. size_ is the number of contained FixVecs. initType + * must be NO_INIT. + */ + VectorOfFixVecs(int dim, int size, InitType initType) : size_(size) + { + TEST_EXIT(initType==NO_INIT)("wrong initType or wrong initializer\n"); + //vec = GET_MEMORY(FixVecType*, size); + vec = GET_MEMORY(FixVecType*, size_); + for(FixVecType** i=&vec[0]; i < &vec[size_]; i++) { + *i = NEW FixVecType(dim, NO_INIT); + } + } + + /** \brief + * constructs a VectorOfFixVecs via an value list. dim is passed to + * FixVec's constructors. size_ is the number of contained FixVecs. initType + * must be VALUE_LIST. ini contains the initialisation values. + */ + VectorOfFixVecs(int dim, int s, InitType initType, const FixVecType* ini) + : size_(s) + { + TEST_EXIT(initType==VALUE_LIST)("wrong initType or wrong initializer\n"); + vec = GET_MEMORY(FixVecType*, size_); + //vec = new FixVecType*[size]; + for(FixVecType** i=&vec[0]; i < &vec[size_]; i++) { + *i = NEW FixVecType(ini[i]); + } + } + + /** \brief + * constructs a VectorOfFixVecs with an default value. dim is passed to + * FixVec's constructors. size_ is the number of contained FixVecs. initType + * must be DEFAULT_VALUE. All entries are set to ini. + */ + VectorOfFixVecs(int /*dim*/, int s, InitType initType, const FixVecType& ini) + : size_(s) + { + TEST_EXIT(initType==DEFAULT_VALUE) + ("wrong initType or wrong initializer\n"); + vec = GET_MEMORY(FixVecType*, size_); + //vec = new FixVecType*[size]; + for(FixVecType** i=&vec[0]; i < &vec[size_]; i++) { + *i = NEW FixVecType(ini); + } + } + + /** \brief + * copy constructor + */ + VectorOfFixVecs(const VectorOfFixVecs<FixVecType>& rhs) + { + size_ = rhs.getSize(); + vec = GET_MEMORY(FixVecType*, size_); + int i; + + for(i=0; i < size_; i++) { + vec[i] = NEW FixVecType(*(rhs.vec[i])); + } + }; + + /** \brief + * destructor + */ + virtual ~VectorOfFixVecs() + { + for(FixVecType** i=&vec[0]; i<&vec[size_]; i++) { + DELETE *i; + } + FREE_MEMORY(vec, FixVecType*, size_); + //delete [] vec; + }; + + /** \brief + * Allows the access like in a normal array via []. Used for const objects. + */ + inline const FixVecType& operator[](int index) const + { + TEST_EXIT(index >= 0 && index < size_)("invalid index\n"); + return *(vec[index]); + }; + + /** \brief + * Allows the access like in a normal array via []. + */ + inline FixVecType& operator[](int index) + { + TEST_EXIT(index >= 0 && index < size_)("invalid index\n"); + return *(vec[index]); + }; + + /** \brief + * assignment operator + */ + VectorOfFixVecs<FixVecType>& + operator=(const VectorOfFixVecs<FixVecType>& rhs) + { + TEST_EXIT(size_==rhs.size_)("vectors of different size\n"); + if (this!=&rhs) { + FixVecType **i, **j; + for(i=&vec[0], j=&(rhs.vec[0]); i < &vec[size_]; i++, j++) { + **i = **j; + } + } + return *this; + }; + + /** \brief + * Returns the \ref size of this VectorOfFixVecs + */ + inline int getSize() const { return size_; }; + + /** \brief + * Returns the size of the contained FixVecs + */ + inline int getSizeOfFixVec() const { return vec[0]->getSize(); } + + protected: + /** \brief + * number of contained FixVecs + */ + int size_; + + /** \brief + * array of pointers to FixVecs + */ + FixVecType **vec; + }; + + // =========================================================================== + // ===== class MatrixOfFixVecs =============================================== + // =========================================================================== + + /** \ingroup Common + * \brief + * Like the class VectorOfFixVecs contains a vector of FixVecs, this class + * contains a matrix of FixVecs of same type. + */ + template<typename FixVecType> + class MatrixOfFixVecs + { + public: + MEMORY_MANAGED(MatrixOfFixVecs<FixVecType>); + + /** \brief + * Constructs the matrix without initialisation. r is the number of rows, + * c is the number of columns. The other parameters are analog to the + * VectorOfFixVecs constructors. + */ + MatrixOfFixVecs(int dim, int r, int c, InitType initType) + : rows(r), columns(c) + { + TEST_EXIT(initType==NO_INIT)("wrong initType or wrong initializer\n"); + vec = GET_MEMORY(VectorOfFixVecs<FixVecType>*, rows); + //vec = new VectorOfFixVecs<FixVecType>*[rows]; + for(VectorOfFixVecs<FixVecType>** i=&vec[0]; i<&vec[rows]; i++) { + *i = NEW VectorOfFixVecs<FixVecType>(dim, columns, NO_INIT); + } + }; + + + /** \brief + * destructor + */ + virtual ~MatrixOfFixVecs() + { + for(VectorOfFixVecs<FixVecType>** i=&vec[0]; i<&vec[rows]; i++) { + DELETE *i; + } + FREE_MEMORY(vec, VectorOfFixVecs<FixVecType>*, rows); + }; + + /** \brief + * assignment operator + */ + inline VectorOfFixVecs<FixVecType >& operator[](int index) + { + TEST_EXIT(index >= 0 && index < rows)("invalid index\n"); + return *(vec[index]); + }; + + /** \brief + * assignment operator + */ + inline const VectorOfFixVecs<FixVecType >& operator[](int index) const + { + TEST_EXIT(index >= 0 && index < rows)("invalid index\n"); + return *(vec[index]); + }; + + /** \brief + * Returns \ref rows + */ + inline int getNumberOfRows() const { + return rows; + }; + + /** \brief + * Returns \ref columns + */ + inline int getNumberOfColumns() const { + return columns; + }; + + private: + /** \brief + * number of rows of the matrix + */ + + int rows; + + /** \brief + * number of columns of the matrix + */ + int columns; + + /** \brief + * array of pointers to VectorOfFixVecs + */ + VectorOfFixVecs<FixVecType> **vec; + }; + + + // =========================================================================== + // ===== class DimVec ======================================================== + // =========================================================================== + + /** \ingroup Common + * \brief + * A DimVec is a FixVec with dim + 1 entries. It can be used for storing + * barycentric coordinates or information associated to vertices or + * parts of an element. + */ + template<typename T> + class DimVec : public FixVec<T,PARTS> { + public: + MEMORY_MANAGED(DimVec<T>); + + DimVec() {}; + + /** \brief + * Calls the corresponding constructor of FixVec + */ + DimVec(int dim, InitType initType=NO_INIT) + : FixVec<T,PARTS>(dim, initType) + {}; + + /** \brief + * Calls the corresponding constructor of FixVec + */ + DimVec(int dim, InitType initType, T* ini) + : FixVec<T,PARTS>(dim, initType, ini) + {}; + + /** \brief + * Calls the corresponding constructor of FixVec + */ + DimVec(int dim, InitType initType, const T& ini) + : FixVec<T,PARTS>(dim, initType, ini) + {}; + }; + + // =========================================================================== + // ===== class DimMat ======================================================== + // =========================================================================== + + /** \ingroup Common + * \brief + * A DimMat is a VectorOfFixVecs of dim+1 DimVecs. + */ + template<typename T> + class DimMat : public Matrix<T> + { + public: + MEMORY_MANAGED(DimMat<T>); + + /** \brief + * Calls the corresponding constructor of VectorOfFixVecs + */ + DimMat(int dim, InitType initType=NO_INIT) + : Matrix<T>(dim+1, dim+1) + {}; + + /** \brief + * Calls the corresponding constructor of VectorOfFixVecs + */ + DimMat(int dim, InitType initType, const T& ini) + : Matrix<T>(dim+1, dim+1) + { + TEST_EXIT(initType==DEFAULT_VALUE) + ("wrong initType or wrong initializer\n"); + this->set(ini); + }; + + /** \brief + * Calls the corresponding constructor of VectorOfFixVecs + */ + DimMat(int dim, InitType initType, T* ini) + : Matrix<T>(dim+1, dim+1) + { + TEST_EXIT(initType==VALUE_LIST)("wrong initType or wrong initializer\n"); + setValues(ini); + }; + }; + + // =========================================================================== + // ===== class WorldVector =================================================== + // =========================================================================== + + /** \ingroup Common + * \brief + * A WorldVector is an AlgoVec with DIM_OF_WORLD entries of type double. + * Can be used for storing world coordinates. + */ + template<typename T> + class WorldVector : public FixVec<T, WORLD> + { + public: + MEMORY_MANAGED(WorldVector<T>); + + /** \brief + * Calls the corresponding constructor of AlgoVec + */ + WorldVector() + : FixVec<T, WORLD>(Global::getGeo(WORLD), NO_INIT) + {}; + + /** \brief + * Calls the corresponding constructor of AlgoVec + */ + WorldVector(InitType initType, T* ini) + : FixVec<T, WORLD>(Global::getGeo(WORLD), initType, ini) + {}; + + /** \brief + * Calls the corresponding constructor of AlgoVec + */ + WorldVector(InitType initType, const T& ini) + : FixVec<T, WORLD>(Global::getGeo(WORLD), initType, ini) + {}; + + /** \brief + * Sets all entries to d + */ + inline const WorldVector<T>& operator=(const T& d) + { + this->set(d); + return (*this); + }; + + /** \brief + * Multplication of a matrix with a vector. + */ + void multMatrixVec(WorldMatrix<T> &m, WorldVector<T> &v); + }; + + + // =========================================================================== + // ===== class WorldMatrix =================================================== + // =========================================================================== + + /** \ingroup Common + * \brief + * A WorldMatrix is a FixVec with DIM_OF_WORLD WorldVector entries. + * So it can be seen as matrix with DIM_OF_WORLD x DIM_OF_WORLD double + * entries. + * Here it's not necessary to use the VectorOfFixVecs class, because the + * FixVec constructor assumes dim = DIM_OF_WORLD, if no dim is spezified, + * what is the right assumption in this case. + */ + template<typename T> + class WorldMatrix : public Matrix<T> + { + public: + MEMORY_MANAGED(WorldMatrix<T>); + + /** \brief + * Calls the corresponding constructor of FixVec + */ + WorldMatrix() + : Matrix<T>(Global::getGeo(WORLD), Global::getGeo(WORLD)) + {}; + + /** \brief + * Calls the corresponding constructor of FixVec + */ + WorldMatrix(InitType initType, T* ini) + : Matrix<T>(Global::getGeo(WORLD), Global::getGeo(WORLD)) + { + TEST_EXIT(initType == VALUE_LIST)("???\n"); + setValues(ini); + }; + + /** \brief + * Calls the corresponding constructor of FixVec and sets all matrix entries + * to ini + */ + WorldMatrix(InitType initType, const T& ini) + : Matrix<T>(Global::getGeo(WORLD), Global::getGeo(WORLD)) + { + TEST_EXIT(initType == DEFAULT_VALUE)("wrong initType or wrong initializer\n"); + this->set(ini); + }; + + /** \brief + * Returns true if the matrix is a diagonal matrix, returns false otherwise. + */ + bool isDiagMatrix() const; + + /** \brief + * Returns true if the matrix is symmetric, returns false otherwise. + */ + bool isSymmetric() const; + + /** \brief + * Sets the diagonal entries to the given value. + */ + void setDiag(T value); + + /** \brief + * Creates a matrix from the "multiplication" of two vectors. + * + * 2d-Example: + * + * /a\ /c\ /ac ad\ + * | | * | | = | | + * \b/ \d/ \bc bd/ + */ + void vecProduct(const WorldVector<T>& v1, const WorldVector<T>& v2); + }; + + + // =========================================================================== + // ===== global functions ==================================================== + // =========================================================================== + + + /** \brief + * returns the euclidian distance of a and b + */ + template<typename T, GeoIndex d> + double absteukl(const FixVec<T,d>& a,const FixVec<T,d>& b); + + /** \brief + * FixVec operator for stream output + */ + template<typename T, GeoIndex d> + std::ostream& operator <<(::std::ostream& out, const FixVec<T,d>& fixvec) + { + for(int i=0; i < fixvec.getSize()-1; i++) { + out << fixvec[i] << " "; + } + out << fixvec[fixvec.getSize()-1]; + return out; + } + + /** \brief + * creates and inits a VectorOfFixVecs<DimVec<double> > + */ + VectorOfFixVecs<DimVec<double> > *createAndInit(int dim, int size, ...); + + /** \brief + * creates and inits and double array + */ + double *createAndInitArray(int size, ...); + + inline WorldVector<double> operator*(const WorldVector<double>& v, double d) { + WorldVector<double> result = v; + result *= d; + return result; + }; + + inline WorldVector<double> operator+(const WorldVector<double>& v1, + const WorldVector<double>& v2) + { + WorldVector<double> result = v1; + result += v2; + return result; + }; + + inline WorldVector<int> operator+(const WorldVector<int>& v1, + const WorldVector<int>& v2) + { + WorldVector<int> result = v1; + result += v2; + return result; + }; + + inline WorldVector<double> operator-(const WorldVector<double>& v1, + const WorldVector<double>& v2) + { + WorldVector<double> result = v1; + result -= v2; + return result; + }; + + inline bool operator<(const WorldVector<double>& v1, + const WorldVector<double>& v2) + { + int i, dow = Global::getGeo(WORLD); + for(i = 0; i < dow; i++) { + if(abs(v1[i] - v2[i]) < DBL_TOL) continue; + return v1[i] < v2[i]; + } + return false; + }; + + inline bool operator==(const WorldVector<double>& v1, + const WorldVector<double>& v2) + { + int i, dow = Global::getGeo(WORLD); + for(i = 0; i < dow; i++) { + if(abs(v1[i] - v2[i]) > DBL_TOL) return false; + } + return true; + }; + + template<typename T> + const WorldMatrix<T>& operator*=(WorldMatrix<T>& m, T scal); + + template<typename T> + const WorldMatrix<T>& operator-=(WorldMatrix<T>& m1, const WorldMatrix<T>& m2); + + template<typename T> + const WorldMatrix<T>& operator+=(WorldMatrix<T>& m1, const WorldMatrix<T>& m2); +} + +#include "FixVec.hh" + +#endif // AMDIS_FIXVEC_H diff --git a/AMDiS/src/FixVec.hh b/AMDiS/src/FixVec.hh new file mode 100644 index 0000000000000000000000000000000000000000..a35d2d0ad82aa70d415f4f178685691476ff6ec7 --- /dev/null +++ b/AMDiS/src/FixVec.hh @@ -0,0 +1,121 @@ +namespace AMDiS { + + template<typename T, GeoIndex d> + double absteukl(const FixVec<T,d>& a,const FixVec<T,d>& b) + { + int i; + double erg; + + erg=0.0; + for (i=0; i < a.getSize() ; i++) + { + erg=erg+((a[i]-b[i])*(a[i]-b[i])); + } + + return sqrt(erg); + } + + template<typename T> + void WorldVector<T>::multMatrixVec(WorldMatrix<T> &m, WorldVector<T> &v) + { + FUNCNAME("WorldVector<T>::multMatrix()"); + TEST_EXIT(m.getNumRows() == this->getSize())("invalide size\n"); + TEST_EXIT(v.getSize() == this->getSize())("invalide size\n"); + + T *mIt, *thisIt; + for (thisIt = this->begin(), mIt = m.begin(); + thisIt != this->end(); + thisIt++) + { + *thisIt = 0; + + for (T* vIt = v.begin(); vIt != v.end(); vIt++, mIt++) { + *thisIt += *vIt * *mIt; + } + } + } + + template<typename T> + bool WorldMatrix<T>::isDiagMatrix() const + { + for (int i = 0; i < this->getSize(); i++) + for (int j = i + 1; j < this->getSize(); j++) + if (abs((*this)[i][j]) > DBL_TOL || abs((*this)[j][i]) > DBL_TOL) + return(false); + return(true); + } + + template<typename T> + bool WorldMatrix<T>::isSymmetric() const + { + for (int i = 0; i < this->getSize(); i++) + for (int j = i + 1; j < this->getSize(); j++) + if (abs((*this)[i][j] - (*this)[j][i]) > DBL_TOL) + return false; + + return true; + } + + template<typename T> + void WorldMatrix<T>::setDiag(T value) + { + for (int i = 0; i < this->rows; i++) { + this->valArray[i * this->cols + i] = value; + } + } + + template<typename T> + void WorldMatrix<T>::vecProduct(const WorldVector<T>& v1, const WorldVector<T>& v2) + { + FUNCNAME("WorldMatrix<T>::vecProduct()"); + + TEST_EXIT(v1.getSize() == v2.getSize())("invalid size 1\n"); + TEST_EXIT(v1.getSize() == this->getSize())("invalid size 2\n"); + + T *thisIt = this->begin(); + + for (T* v1It = v1.begin(); v1It != v1.end(); v1It++) { + for (T* v2It = v2.begin(); v2It != v2.end(); v2It++, thisIt++) { + *thisIt = *v1It * *v2It; + } + } + } + + template<typename T> + const WorldMatrix<T>& operator*=(WorldMatrix<T>& m, T scal) + { + for (T* mIt = m.begin(); mIt != m.end(); mIt++) { + *mIt *= scal; + } + + return m; + } + + template<typename T> + const WorldMatrix<T>& operator-=(WorldMatrix<T>& m1, const WorldMatrix<T>& m2) + { + T *m1It, *m2It; + for (m1It = m1.begin(), m2It = m2.begin(); + m1It != m1.end(); + m1It++, m2It++) + { + *m1It -= *m2It; + } + + return m1; + } + + template<typename T> + const WorldMatrix<T>& operator+=(WorldMatrix<T>& m1, const WorldMatrix<T>& m2) + { + T* m1It, *m2It; + for (m1It = m1.begin(), m2It = m2.begin(); + m1It != m1.end(); + m1It++, m2It++) + { + *m1It += *m2It; + } + + return m1; + } +} diff --git a/AMDiS/src/FixVecConvert.h b/AMDiS/src/FixVecConvert.h new file mode 100644 index 0000000000000000000000000000000000000000..c27c4f848b98e7c43cddcea60fb0b70ff8112471 --- /dev/null +++ b/AMDiS/src/FixVecConvert.h @@ -0,0 +1,44 @@ +// ============================================================================ +// == == +// == AMDiS - Adaptive multidimensional simulations == +// == == +// ============================================================================ +// == == +// == crystal growth group == +// == == +// == Stiftung caesar == +// == Ludwig-Erhard-Allee 2 == +// == 53175 Bonn == +// == germany == +// == == +// ============================================================================ +// == == +// == http://www.caesar.de/cg/AMDiS == +// == == +// ============================================================================ + +/** \file FixVecConvert.h */ + +#ifndef AMDIS_FIXVECCONVERT_H_ +#define AMSID_FIXVECCONVERT_H_ + +#include "Global.h" +#include "MemoryManager.h" + +namespace AMDiS { + + template<typename T,GeoIndex d1,GeoIndex d2> + class VecConv + { + public: + MEMORY_MANAGED(VecConv<T COMMA d1 COMMA d2>); + + static FixVec<T,d1>& convertVec(FixVec<T,d2>& rhs, Mesh* mesh) { + TEST_EXIT(mesh->getGeo(d1)==mesh->getGeo(d2))("Incompatible dimensions.\n"); + return reinterpret_cast<FixVec<T,d1>&>(rhs); + }; + }; + +} + +#endif diff --git a/AMDiS/src/Flag.cc b/AMDiS/src/Flag.cc new file mode 100644 index 0000000000000000000000000000000000000000..bd4afe3699a4fccd4d677b214347ef35474eb2e4 --- /dev/null +++ b/AMDiS/src/Flag.cc @@ -0,0 +1,5 @@ +#include "Flag.h" + +namespace AMDiS { + +} diff --git a/AMDiS/src/Flag.h b/AMDiS/src/Flag.h new file mode 100644 index 0000000000000000000000000000000000000000..8d0b6a255350e1ec6e04ca79ff1709b9895ea88f --- /dev/null +++ b/AMDiS/src/Flag.h @@ -0,0 +1,214 @@ +// ============================================================================ +// == == +// == AMDiS - Adaptive multidimensional simulations == +// == == +// ============================================================================ +// == == +// == crystal growth group == +// == == +// == Stiftung caesar == +// == Ludwig-Erhard-Allee 2 == +// == 53175 Bonn == +// == germany == +// == == +// ============================================================================ +// == == +// == http://www.caesar.de/cg/AMDiS == +// == == +// ============================================================================ + +/** \file Flagh.h */ + +#ifndef AMDIS_FLAG_H +#define AMDIS_FLAG_H + +#include "Global.h" +#include "MemoryManager.h" + +namespace AMDiS { + + /** \ingroup Common + * \brief + * The Flag class encapsulates flags which represents simple information. + * Used e.g. while mesh traversal to specify, which elements should be + * visited. + */ + class Flag + { + public: + MEMORY_MANAGED(Flag); + + /** \brief + * Constructs a unset Flag + */ + inline Flag() : flags(0) {}; + + /** \brief + * Constructs a Flag initialized by f + */ + inline Flag(const unsigned long f) : flags(f) {}; + + /** \brief + * Copy constructor + */ + inline Flag(const Flag& f) : flags(f.flags) {}; + + /** \brief + * Destructor + */ + inline ~Flag() {}; + + /** \brief + * Compares two Flags + */ + inline bool operator==(const Flag& f) const {return (flags==f.flags);}; + + /** \brief + * Compares two Flags + */ + inline bool operator!=(const Flag& f) const {return !(f==*this);}; + + /** \brief + * Assignment operator + */ + inline Flag& operator=(const Flag& f) { + if (this!=&f) flags=f.flags; + return *this; + }; + + /** \brief + * Typecast + */ + inline operator bool() const { return isAnySet(); }; + + /** \brief + * Set \ref flags + */ + inline void setFlags(const unsigned long f) { flags = f; }; + + /** \brief + * Set \ref flags + */ + inline void setFlags(const Flag& f) { flags = f.flags; }; + + /** \brief + * Sets \ref flags to \ref flags | f + */ + inline void setFlag(const unsigned long f) { flags |= f; }; + + /** \brief + * Sets \ref flags to \ref flags | f.flags + */ + inline void setFlag(const Flag& f) { flags |= f.flags; }; + + /** \brief + * Sets \ref flags to \ref flags & ~f + */ + inline void unsetFlag(const unsigned long f) { flags &= ~f; }; + + /** \brief + * Sets \ref flags to \ref flags & ~f.flags + */ + inline void unsetFlag(const Flag& f) { flags &= ~f.flags; }; + + inline const unsigned long getFlags() const { return flags; }; + + /** \brief + * Returns \ref flags | f.flags + */ + inline Flag operator+(const Flag& f) const { + Flag r(flags); + r.setFlag(f); + return r; + }; + + /** \brief + * Returns \ref flags & ~f.flags + */ + inline Flag operator-(const Flag& f) const { + Flag r(flags); + r.unsetFlag(f); + return r; + }; + + /** \brief + * Returns \ref flags | f.flags + */ + inline Flag operator|(const Flag& f) const { + Flag r(flags); + r.setFlag(f); + return r; + }; + + /** \brief + * Returns \ref flags & f.flags + */ + inline Flag operator&(const Flag& f) const { + Flag r(flags); + r.flags &=f.flags; + return r; + }; + + /** \brief + * Sets \ref flags to \ref flags &= f.flags + */ + inline Flag operator&=(const Flag& f) { + flags &= f.flags; + return *this; + }; + + /** \brief + * Returns \ref flags ^ f.flags + */ + inline Flag operator^(const Flag& f) const { + Flag r(flags); + r.flags ^=f.flags; + return r; + }; + + /** \brief + * Sets \ref flags to \ref flags & f.flags + */ + inline Flag& operator|=(const Flag& f) { + if (this!=&f) {flags |=f.flags;}; + return *this; + }; + + /** \brief + * Returns ~\ref flags + */ + inline Flag operator~() const { + Flag r; + r.flags = ~flags; + return r; + }; + + /** \brief + * Checks whether all set bits of f.flags are set in \ref flags too. + */ + inline bool isSet(const Flag& f) const { + return ((flags&f.flags) == f.flags); + }; + + /** \brief + * Returns !\ref isSet(f) + */ + inline bool isUnset(const Flag& f) const { return !isSet(f); }; + + /** \brief + * Returns true if \ref flags != 0 + */ + inline bool isAnySet() const { return (flags != 0); }; + + protected: + /** \brief + * Internal flag representation + */ + unsigned long flags; + }; + +} + +#endif // AMDIS_FLAG_H + + diff --git a/AMDiS/src/GMResSolver.h b/AMDiS/src/GMResSolver.h new file mode 100644 index 0000000000000000000000000000000000000000..b4412d5feb9b87923edec6071ec08401f31ea597 --- /dev/null +++ b/AMDiS/src/GMResSolver.h @@ -0,0 +1,133 @@ +// ============================================================================ +// == == +// == AMDiS - Adaptive multidimensional simulations == +// == == +// ============================================================================ +// == == +// == crystal growth group == +// == == +// == Stiftung caesar == +// == Ludwig-Erhard-Allee 2 == +// == 53175 Bonn == +// == germany == +// == == +// ============================================================================ +// == == +// == http://www.caesar.de/cg/AMDiS == +// == == +// ============================================================================ + +/** \file GMResSolver.h */ + +#ifndef AMDIS_GMRESSOLVER_H +#define AMDIS_GMRESSOLVER_H + +#include "OEMSolver.h" +#include "MemoryManager.h" + +namespace AMDiS { + + // ============================================================================ + // ===== class GMResSolver ==================================================== + // ============================================================================ + + /** + * \ingroup Solver + * + * \brief + * Solves a linear system by the GMRes method with restart and can be used for + * regular system matrices. + */ + template<typename VectorType> + class GMResSolver : public OEMSolver<VectorType> + { + public: + MEMORY_MANAGED(GMResSolver<VectorType>); + + /** \brief + * Creator class used in the OEMSolverMap. + */ + class Creator : public OEMSolverCreator<VectorType> + { + public: + MEMORY_MANAGED(Creator); + + virtual ~Creator() {}; + + /** \brief + * Returns a new GMResSolver object. + */ + OEMSolver<VectorType>* create() { + return NEW GMResSolver<VectorType>(this->name); + }; + }; + + /** \brief + * constructor + */ + GMResSolver(::std::string name); + + /** \brief + * destructor + */ + ~GMResSolver(); + + protected: + /** \brief + * realisation of OEMSolver::solveSystem + */ + int solveSystem(MatVecMultiplier<VectorType> *mv, VectorType *x, VectorType *b); + + /** \brief + * realisation of OEMSolver::init + */ + void init(); + + /** \brief + * realisation of OEMSolver::exit + */ + void exit(); + + private: + /** \brief + * internal used method + */ + double householderVector(double sigma, + VectorType *u, + VectorType *x, + int offset); + + /** \brief + * internal used method + */ + void newBasisVector(int m, int k, VectorType **U, double **LR, + MatVecMultiplier<VectorType> *matVec, + VectorType *v, VectorType *b, double* y); + + /** \brief + * internal used method + */ + int solve_k(MatVecMultiplier<VectorType> *mv, + VectorType *x, const VectorType *b); + + + private: + double TOL; + int restart; + int dim; + + // pointer to memory needed for solveSystem + VectorType *r, *v; + VectorType **U; + double **LR; + double **givens, *w, *y; + + double gmres_k_residual_0; + }; + + +} + +#include "GMResSolver.hh" + +#endif // AMDIS_GMRESSOLVER_H diff --git a/AMDiS/src/GMResSolver.hh b/AMDiS/src/GMResSolver.hh new file mode 100644 index 0000000000000000000000000000000000000000..876179bd93fe1fa7f67c149738c026095ce85313 --- /dev/null +++ b/AMDiS/src/GMResSolver.hh @@ -0,0 +1,465 @@ +#include "Preconditioner.h" +#include <algorithm> + +namespace AMDiS { + + template<typename VectorType> + GMResSolver<VectorType>::GMResSolver(::std::string name) + : OEMSolver<VectorType>(name), + TOL(1.e-25), + restart(0), + dim(0), + r(NULL), + v(NULL), + U(NULL), + LR(NULL), + givens(NULL), + w(NULL), + y(NULL), + gmres_k_residual_0(0.0) + { + FUNCNAME("GMResSolver::GMResSolver"); + GET_PARAMETER(0, name + "->restart", "%d", &restart); + TEST_EXIT(restart)("restart not set\n"); + } + + template<typename VectorType> + GMResSolver<VectorType>::~GMResSolver() + {} + + template<typename VectorType> + void GMResSolver<VectorType>::init() + { + r = this->vectorCreator->create(); + + dim = size(r); + restart = ::std::max(0, ::std::min(restart, dim)); + + v = this->vectorCreator->create(); + U = GET_MEMORY(VectorType*, restart); + LR = GET_MEMORY(double*, restart); + givens = GET_MEMORY(double*, restart); + + for (int i = 0; i < restart; i++) { + U[i] = this->vectorCreator->create(); + LR[i] = GET_MEMORY(double, restart); + givens[i] = GET_MEMORY(double, 2); + } + + w = GET_MEMORY(double, restart); + y = GET_MEMORY(double, restart); + } + + template<typename VectorType> + void GMResSolver<VectorType>::exit() + { + if (r) { + int dim = restart; + int k = ::std::max(0,::std::min(restart, dim)); + + this->vectorCreator->free(r); + this->vectorCreator->free(v); + + for (int i = 0; i < k; i++) { + this->vectorCreator->free(U[i]); + FREE_MEMORY(LR[i], double, k); + FREE_MEMORY(givens[i], double, 2); + } + FREE_MEMORY(U, VectorType*, k); + FREE_MEMORY(LR, double*, k); + FREE_MEMORY(givens, double*, k); + + FREE_MEMORY(w, double, k); + FREE_MEMORY(y, double, k); + } + } + + template<typename VectorType> + int GMResSolver<VectorType>::solve_k(MatVecMultiplier<VectorType> *matVec, + VectorType *x, const VectorType *b) + { + FUNCNAME("GMResSolver::solve_k"); + + VectorType *um1 = NULL; + double c, s, wm1; + + int k = ::std::max(0, ::std::min(restart, dim)); + + /*--------------------------------------------------------------------------*/ + /* Initialization */ + /*--------------------------------------------------------------------------*/ + + // r = Ax + matVec->matVec(NoTranspose, *x, *r); + + for (int i = 0; i < dim; i++) { + (*r)[i] -= (*b)[i]; + (*r)[i] *= -1.0; + } + + if (this->leftPrecon) + this->leftPrecon->precon(r); + + gmres_k_residual_0 = norm(r); + if (gmres_k_residual_0 < this->tolerance) { + this->residual = gmres_k_residual_0; + return(0); + } + + /*--------------------------------------------------------------------------*/ + /* construct k-dimensional Krylov space */ + /*--------------------------------------------------------------------------*/ + + wm1 = householderVector(gmres_k_residual_0, U[0], r, 0); + um1 = U[0]; + + double rj, sigma, maxi, val; + VectorType *uj; + int m = 0; + + for (m = 0; m < k; m++) { + w[m] = wm1; + + newBasisVector(m + 1, k, U, LR, matVec, r, v, y); + + if (m + 1 < dim) { + double norm = 0.0; + for (int i = m + 1; i < dim; i++) { + norm += (*r)[i] * (*r)[i]; + } + norm = sqrt(norm); + + if (norm > TOL) { + /****************************************************************************/ + /* one of the last components of r is not zero; calculate Householder */ + /* vector; if m < k-1, we need the Householder vector for the calculation */ + /* of the next basis vector => store it; if m == k-1 we do not need this */ + /* vector anymore => do not store it! */ + /****************************************************************************/ + if (m < k - 1) { + um1 = U[m + 1]; + (*r)[m + 1] = householderVector(norm, um1, r, m + 1); + } else { + (*r)[m + 1] = householderVector(norm, NULL, r, m + 1); + } + } + } + + for (int j = 0; j < m; j++) { + rj = (*r)[j]; + + c = givens[j][0]; + s = givens[j][1]; + + (*r)[j] = c * rj + s * (*r)[j + 1]; + (*r)[j+1] = -s * rj + c * (*r)[j + 1]; + } + + if (m + 1 < dim && abs((*r)[m + 1]) > TOL) { + /****************************************************************************/ + /* Find Givens rotation J_m such that, */ + /* a) (J_m r)[i] = r[i], i < m, */ + /* b) (J_m r)[m+1] = 0.0 */ + /* => (J_m r)[m] = +- sqrt(r[m]^2 + r[m+1]^2) =: sigma */ + /* */ + /* */ + /* |1 0 . . . . 0| */ + /* |0 1 . . . . .| */ + /* |. . .| c = r[m]/sigma */ + /* J_m = |. . .| s = r[m+1]/sigma */ + /* |. . .| */ + /* |. c s| m */ + /* |0 . . . . -s c| m+1 */ + /* m m+1 */ + /****************************************************************************/ + + maxi = ::std::max((*r)[m], (*r)[m+1]); + + c = (*r)[m] / maxi; + s = (*r)[m + 1] / maxi; + sigma = maxi * sqrt(c * c + s * s); + if ((*r)[m] < 0) + sigma = -sigma; + givens[m][0] = c = (*r)[m]/sigma; + givens[m][1] = s = (*r)[m+1]/sigma; + + (*r)[m] = sigma; /* r[m+1] == 0 automatically! */ + + wm1 = -s * w[m]; /* |wm1| is the new residual! */ + w[m] *= c; + } else { + wm1 = 0.0; + } + + /****************************************************************************/ + /* now, store the first m components of the column vector r in the the mth */ + /* column of LR */ + /****************************************************************************/ + + for (int j = 0; j <= m; j++) + LR[j][m] = (*r)[j]; + + /****************************************************************************/ + /* test, whether tolarance is reached or not */ + /****************************************************************************/ + + if (abs(wm1) < this->tolerance) { + m++; + break; + } + + /****************************************************************************/ + /* tolerance not reached: calculate and store (m+1)th row of matrix L; */ + /* this row is only needed for the computation of the (m+1)th column of */ + /* the orthogonal matrix Q_m; this vector is the additional basis vector */ + /* for the enlargement of the Krylov space; only needed for m < k-1 */ + /* L[m+1][j] = <u_(m+1),u_j>_2 */ + /* (m+1)th vector u = umi is allready stored at U+(m+1) */ + /****************************************************************************/ + + if (m < k-1) { + for (int j = 0; j < m + 1; j++) { + uj = U[j]; + val = 0.0; + + for (int i = m + 1; i < dim; i++) { + val += (*um1)[i] * (*uj)[i]; + } + + LR[(m+1)][j] = 2.0 * val; + } + } + } + + /****************************************************************************/ + /* and now solve the upper triangular system */ + /****************************************************************************/ + + y[m - 1] = w[m - 1] / LR[m - 1][m - 1]; /* = LR[(m-1)*k+(m-1)]! */ + for (int j = m - 2; j >= 0; j--) { + double yj = w[j]; + + for (int l = j + 1; l < m; l++) { + yj -= LR[j][l] * y[l]; + } + + y[j] = yj / LR[j][j]; + } + + /****************************************************************************/ + /* calculate v = 2 U_m^T [e_0,....,e_m-1] y */ + /****************************************************************************/ + + for (int i = 0; i < m; i++) { + val = 0.0; + + for (int j = i; j < m; j++) { + val += (*(U[i]))[j] * y[j]; + } + + (*v)[i] = 2.0 * val; + } + + /****************************************************************************/ + /* now solve L_m^T w = v in R^m (upper triagonal system, diagonal == 1.0 */ + /****************************************************************************/ + + w[m - 1] = (*v)[m - 1]; + for (int j = m - 2; j >= 0; j--) { + double wj = (*v)[j]; + + for (int l = j + 1; l < m; l++) { + wj -= LR[l][j]*w[l]; + } + + w[j] = wj; + } + + /****************************************************************************/ + /* v = [e_0,....,e_m-1] y - U_m w */ + /****************************************************************************/ + + for (int i = 0; i < dim; i++) { + double vi = 0.0; + for (int j = 0; j < ::std::min(i + 1,m); j++) + vi += (*(U[j]))[i] * w[j]; + (*v)[i] = -vi; + } + + for (int j = 0; j < m; j++) + (*v)[j] += y[j]; + + /****************************************************************************/ + /* and now, make the update of u :-) */ + /****************************************************************************/ + + if (this->rightPrecon) + this->rightPrecon->precon(v); + + for (int i = 0; i < dim; i++) + (*x)[i] += (*v)[i]; + + this->residual = abs(wm1); + return(m); + } + + template<typename VectorType> + int GMResSolver<VectorType>::solveSystem(MatVecMultiplier<VectorType> *matVec, + VectorType *x, VectorType *b) + { + FUNCNAME("GMResSolver::solveSystem()"); + + double old_res = -1.0; + + if (norm(b) < TOL) { + INFO(this->info, 2)("b == 0, x = 0 is the solution of the linear system\n"); + setValue(*x, 0.0); + this->residual = 0.0; + return(0); + } + + START_INFO(); + for (int iter = 0; iter <= this->max_iter; iter++) { + int k = solve_k(matVec, x, b); + if (SOLVE_INFO(iter, this->residual, &old_res)) + return(iter); + TEST_EXIT(k != 0)("this must not happen\n"); + } + + ERROR_EXIT("Should not be reached\n"); + return(0); + } + + template<typename VectorType> + double GMResSolver<VectorType>::householderVector(double sigma, + VectorType *u, + VectorType *x, + int offset) + { + FUNCNAME("GMResSolver::householderVector()"); + + if (dim <= 0) { + MSG("dim <= 0\n"); + return(0.0); + } + + if ((*x)[offset] >= 0) { + if (u) { + double beta = sqrt(0.5 / (sigma * (sigma + (*x)[offset]))); + (*u)[offset] = beta * ((*x)[offset] + sigma); + + for (int i = offset + 1; i < dim; i++) + (*u)[i] = beta * (*x)[i]; + } + return(-sigma); + + } else { + if (u) { + double beta = sqrt(0.5 / (sigma * (sigma - (*x)[offset]))); + (*u)[offset] = ((*x)[offset] - sigma) * beta; + + for (int i = offset + 1; i < dim; i++) + (*u)[i] = (*x)[i] * beta; + } + + return(sigma); + } + } + + template<typename VectorType> + void GMResSolver<VectorType>::newBasisVector(int m, int k, VectorType **U, + double **LR, + MatVecMultiplier<VectorType> *matVec, + VectorType *v, + VectorType *b, double* y) + { + /****************************************************************************/ + /* first calculate y = 2 U_m^T e_m */ + /****************************************************************************/ + + for (int j = 0; j < m; j++) + (*b)[j] = 2.0*(*(U[j]))[m-1]; + + + /****************************************************************************/ + /* now solve L_m^T y = b in R^m (upper triagonal system, diagonal == 1.0 */ + /****************************************************************************/ + + y[m-1] = (*b)[m-1]; + for (int j = m-2; j >= 0; j--) { + double yj = (*b)[j]; + + for (int l = j + 1; l < m; l++) + yj -= LR[l][j]*y[l]; + + y[j] = yj; + } + + /****************************************************************************/ + /* b = -U_m y + e_m */ + /****************************************************************************/ + + for (int i = 0; i < dim; i++) { + double bi = 0.0; + + for (int j = 0; j < ::std::min(i + 1,m); j++) + bi += (*(U[j]))[i] * y[j]; + + (*b)[i] = -bi; + } + (*b)[m - 1] += 1.0; + + /****************************************************************************/ + /* v = Ab */ + /****************************************************************************/ + + if (this->rightPrecon) + this->rightPrecon->precon(b); + + matVec->matVec(NoTranspose, *b, *v); + + if (this->leftPrecon) + this->leftPrecon->precon(v); + + /****************************************************************************/ + /* b = 2 U_m^T v in R^m */ + /****************************************************************************/ + + for (int j = 0; j < m; j++) { + double bj = 0.0; + + for (int i = j; i < dim; i++) + bj += (*(U[j]))[i]*(*v)[i]; + (*b)[j] = 2.0*bj; + } + + /****************************************************************************/ + /* now solve L_m y = b in R^m (lower triagonal system, diagonal == 1.0 */ + /****************************************************************************/ + + y[0] = (*b)[0]; + for (int j = 1; j < m; j++) { + double yj = (*b)[j]; + + for (int l = 0; l < j; l++) + yj -= LR[j][l] * y[l]; + + y[j] = yj; + } + + /****************************************************************************/ + /* v = v - U_m y */ + /****************************************************************************/ + + for (int i = 0; i < dim; i++) { + double vi = 0.0; + + for (int j = 0; j < ::std::min(i + 1,m); j++) + vi += (*(U[j]))[i]*y[j]; + + (*v)[i] -= vi; + } + + return; + } +} diff --git a/AMDiS/src/GMResSolver2.h b/AMDiS/src/GMResSolver2.h new file mode 100644 index 0000000000000000000000000000000000000000..204af83e91c808dc79a2f2b937279952207cea2c --- /dev/null +++ b/AMDiS/src/GMResSolver2.h @@ -0,0 +1,162 @@ +// ============================================================================ +// == AMDiS - Adaptive multidimensional simulations == +// == == +// ============================================================================ +// == == +// == crystal growth group == +// == == +// == Stiftung caesar == +// == Ludwig-Erhard-Allee 2 == +// == 53175 Bonn == +// == germany == +// == == +// ============================================================================ +// == == +// == http://www.caesar.de/cg/AMDiS == +// == == +// ============================================================================ + +/** \file GMResSolver2.h */ + +#ifndef AMDIS_GMRESSOLVER2_H +#define AMDIS_GMRESSOLVER2_H + +#include "OEMSolver.h" +#include "MemoryManager.h" + +namespace AMDiS { + + // ============================================================================ + // ===== class GMResSolver2 =================================================== + // ============================================================================ + + /** + * \ingroup Solver + * + * \brief + * Solves a linear system by the restarted GMRES(m) method (Generalized Minimal + * Residual) for general nonsymmetric system matrices. + * + * The implementation is based on the following book: "Numerik linearer + * Gleichungssystene", 2. Auflage, Andreas Meister. The algorithm is described + * on pages 150 and 154 (for the restarted version). The extension to the + * preconditioned GMRES(m) is based on the description in the book "Iterative + * Methods for Sparse Linear Systems", second edition, Yousef Saad, on page 268. + * + * The orthogonal system is build using the modified Gram Schmidt (MGS) method. + * The least square problem is solved using Givens transformations. + * + */ + template<typename VectorType> + class GMResSolver2 : public OEMSolver<VectorType> + { + public: + MEMORY_MANAGED(GMResSolver2<VectorType>); + + /** \brief + * Creator class used in the OEMSolverMap. + */ + class Creator : public OEMSolverCreator<VectorType> + { + public: + MEMORY_MANAGED(Creator); + + virtual ~Creator() {}; + + /** \brief + * Returns a new GMResSolver object. + */ + OEMSolver<VectorType>* create() { + return NEW GMResSolver2<VectorType>(this->name); + }; + }; + + /** \brief + * constructor + */ + GMResSolver2(::std::string name); + + /** \brief + * destructor + */ + ~GMResSolver2(); + + protected: + /** \brief + * realisation of OEMSolver::solveSystem + */ + int solveSystem(MatVecMultiplier<VectorType> *mv, VectorType *x, VectorType *b); + + /** \brief + * realisation of OEMSolver::init + */ + void init(); + + /** \brief + * realisation of OEMSolver::exit + */ + void exit(); + + /** \brief + * One run of the GMRES(m) method. Is called from solveSystem(). + */ + int gmres(MatVecMultiplier<VectorType> *mv, + VectorType *x, + VectorType *b); + + private: + /** \brief + * Stores the tolerance boundary for numerical computations. + */ + double TOL_; + + /** \brief + * The parameter m of GMRES(m), i.e. the number of iterations before a restart of + * the algorithm is forced. + */ + int restart_; + + /** \brief + * Stores intermediate results in the orthogonalization step. + */ + VectorType *w_; + + + VectorType *z_; + + VectorType *r_; + + /** \brief + * Pointers to the vectors of the orthogonal system. + */ + VectorType **v; + + /** \brief + * Stores the gamma values for Givens transformations. + */ + vector<double> gamma; + + /** \brief + * Stores the c values for Givens transformations. + */ + vector<double> c; + + /** \brief + * Stores the s values for Givens transformations. + */ + vector<double> s; + + vector<double> y_; + + /** \brief + * H-Matrix computed in the GMRES algorithm. + */ + vector< vector<double> > h; + }; + + +} + +#include "GMResSolver2.hh" + +#endif // AMDIS_GMRESSOLVER2_H diff --git a/AMDiS/src/GMResSolver2.hh b/AMDiS/src/GMResSolver2.hh new file mode 100644 index 0000000000000000000000000000000000000000..62edf41b3a8d20aa782ec05e438ee3287382c88d --- /dev/null +++ b/AMDiS/src/GMResSolver2.hh @@ -0,0 +1,191 @@ +#include "GMResSolver2.h" +#include "Preconditioner.h" + +namespace AMDiS { + + template<typename VectorType> + GMResSolver2<VectorType>::GMResSolver2(::std::string name) + : OEMSolver<VectorType>(name), + TOL_(1.e-25), + restart_(0), + w_(NULL) + { + FUNCNAME("GMResSolver2::GMResSolver2()"); + GET_PARAMETER(0, name + "->restart", "%d", &restart_); + TEST_EXIT(restart_)("restart not set\n"); + } + + template<typename VectorType> + GMResSolver2<VectorType>::~GMResSolver2() + {} + + template<typename VectorType> + void GMResSolver2<VectorType>::init() + { + // Create a new vector w. + w_ = this->vectorCreator->create(); + z_ = this->vectorCreator->create(); + r_ = this->vectorCreator->create(); + + // Get memory for the vector pointers and create the pointers afterwards. + v = GET_MEMORY(VectorType*, restart_ + 1); + for (int i = 0; i <= restart_; i++) { + v[i] = this->vectorCreator->create(); + } + + // Resize all fields to the corresponding size. + gamma.resize(restart_ + 1); + c.resize(restart_); + s.resize(restart_); + + y_.resize(restart_); + + h.resize(restart_ + 1); + for (int i = 0; i <= restart_; i++) { + h[i].resize(restart_); + } + } + + template<typename VectorType> + void GMResSolver2<VectorType>::exit() + { + // Empty used memory. + if (w_) { + this->vectorCreator->free(w_); + this->vectorCreator->free(z_); + this->vectorCreator->free(r_); + + for (int i = 0; i <= restart_; i++) { + this->vectorCreator->free(v[i]); + } + } + } + + + template<typename VectorType> + int GMResSolver2<VectorType>::gmres(MatVecMultiplier<VectorType> *matVec, + VectorType *x, + VectorType *b) + { + FUNCNAME("GMResSolver2::gmres()"); + + // r_0 = b - Ax, where r_0 is already stored as the first vector in the + // matrix V. + matVec->matVec(NoTranspose, *x, *v[0]); + xpay(-1.0, *b, *v[0]); + + // Left preconditioning, if required. + if (this->leftPrecon) { + this->leftPrecon->precon(v[0]); + } + + // Compute the norm of r_0 = v_0. + gamma[0] = norm(v[0]); + + // Normalize v_0. + *v[0] *= (1 / gamma[0]); + + // If the norm of gamma_0 is less than the tolerance bounday, x is already + // a good solution for Ax = b. + if (gamma[0] < this->tolerance) { + this->residual = gamma[0]; + return(0); + } + + // Main loop of the GMRES algorithm. + for (int j = 0; j < restart_; j++) { + // w_j = A * v_j; + matVec->matVec(NoTranspose, *v[j], *w_); + + // Preconditioning of w_j + if (this->leftPrecon) { + this->leftPrecon->precon(w_); + } + + // w_j = A * v_j - \sum(h_ij * v_i) + for (int i = 0; i <= j; i++) { + // h_ij = (v_i, A * v_j)_2 + h[i][j] = *w_ * (*v[i]); + + // Update w_j + axpy(-h[i][j], *v[i], *w_); + } + + // h_{j + 1}{j} = \| w_j \|_2 + h[j + 1][j] = norm(w_); + + // Compute h_ij and h_{i + 1}{j} using parameters of the Givens rotation. + for (int i = 0; i < j; i++) { + double t1 = c[i] * h[i][j] + s[i] * h[i + 1][j]; + double t2 = -s[i] * h[i][j] + c[i] * h[i + 1][j]; + h[i][j] = t1; + h[i + 1][j] = t2; + } + + // Compute new beta + double beta = sqrt(h[j][j] * h[j][j] + h[j + 1][j] * h[j + 1][j]); + // Update s_j and c_j + s[j] = h[j + 1][j] / beta; + c[j] = h[j][j] / beta; + // h_jj = beta + h[j][j] = beta; + + // Update gammas + gamma[j + 1] = -s[j] * gamma[j]; + gamma[j] *= c[j]; + + // Set v_{j + 1} to w_j and normalize it. + *v[j + 1] = *w_; + *v[j + 1] *= 1 / h[j + 1][j]; + } + + // Compute the solution. + for (int i = restart_ - 1; i >= 0; i--) { + for (int k = i + 1; k < restart_; k++) { + gamma[i] -= h[i][k] * gamma[k]; + } + gamma[i] /= h[i][i]; + axpy(gamma[i], *v[i], *x); + } + + // Update the new residual. + this->residual = abs(gamma[restart_]); + + return restart_; + } + + + template<typename VectorType> + int GMResSolver2<VectorType>::solveSystem(MatVecMultiplier<VectorType> *matVec, + VectorType *x, + VectorType *b) + { + FUNCNAME("GMResSolver2::solveSystem()"); + + double old_res = -1.0; + + // If norm of b is smaller than the tolarance, we can assume b to be zero. + // Hence, x = 0 is the solution of the linear system. + if (norm(b) < TOL_) { + INFO(this->info, 2)("b == 0, x = 0 is the solution of the linear system\n"); + setValue(*x, 0.0); + this->residual = 0.0; + return(0); + } + + START_INFO(); + for (int iter = 0; iter <= this->max_iter; iter++) { + // Solve Ax=b using GMRES(m). + int k = gmres(matVec, x, b); + // Check the new residual. + if (SOLVE_INFO(iter, this->residual, &old_res)) + return(iter); + TEST_EXIT(k != 0)("this must not happen\n"); + } + + ERROR_EXIT("Should not be reached\n"); + return(0); + } + +} + diff --git a/AMDiS/src/GNUPlotWriter.cc b/AMDiS/src/GNUPlotWriter.cc new file mode 100644 index 0000000000000000000000000000000000000000..828880f444430e9688ff358a29fbcb1bf5590f0d --- /dev/null +++ b/AMDiS/src/GNUPlotWriter.cc @@ -0,0 +1,74 @@ +#include "GNUPlotWriter.h" +#include "FiniteElemSpace.h" +#include "DOFVector.h" +#include "Mesh.h" +#include "ElInfo.h" +#include "Traverse.h" +#include "Global.h" +#include "AdaptInfo.h" + +namespace AMDiS { + + GNUPlotWriter::GNUPlotWriter(::std::string fn, + FiniteElemSpace *feSpace, + ::std::vector<DOFVector<double>*> &dofVectors) + : feSpace_(feSpace), + dofVectors_(dofVectors), + filename_(filename) + { + filename = fn; + } + + void GNUPlotWriter::writeFiles(AdaptInfo *adaptInfo, bool force) + { + DOFVector<WorldVector<double> > coords(feSpace_, "coords"); + + Mesh *mesh = feSpace_->getMesh(); + + int dow = Global::getGeo(WORLD); + + const BasisFunction *basFcts = feSpace_->getBasisFcts(); + int i, numFcts = basFcts->getNumber(); + DegreeOfFreedom *localDOFs = GET_MEMORY(DegreeOfFreedom, numFcts); + + TraverseStack stack; + ElInfo *elInfo = stack.traverseFirst(mesh, -1, + Mesh::CALL_LEAF_EL | + Mesh::FILL_COORDS); + while(elInfo) { + basFcts->getLocalIndices(elInfo->getElement(), + feSpace_->getAdmin(), + localDOFs); + for(i = 0; i < numFcts; i++) { + coords[localDOFs[i]] = elInfo->getCoord(i); + } + elInfo = stack.traverseNext(elInfo); + } + + FREE_MEMORY(localDOFs, DegreeOfFreedom, numFcts); + + FILE *file = NULL; + if (!(file = fopen(filename_.c_str(), "w"))) + { + ERROR("could not open file %s for writing\n", filename_.c_str()); + } + + fprintf(file, "# line format: time x y z val1[x,y,z] val2[x,y,z] ...\n"); + + DOFVector<WorldVector<double> >::Iterator coordsIt(&coords, USED_DOFS); + + int index, numVecs = static_cast<int>(dofVectors_.size()); + for(coordsIt.reset(); !coordsIt.end(); ++coordsIt) { + index = coordsIt.getDOFIndex(); + fprintf(file, "%e ", adaptInfo->getTime()); + for(i = 0; i < dow; i++) { + fprintf(file, "%e ", (*coordsIt)[i]); + } + for(i = 0; i < numVecs; i++) { + fprintf(file, "%e ", (*(dofVectors_[i]))[index]); + } + fprintf(file, "\n"); + } + } + +} diff --git a/AMDiS/src/GNUPlotWriter.h b/AMDiS/src/GNUPlotWriter.h new file mode 100644 index 0000000000000000000000000000000000000000..5bdaa5cf83fac2ef5e408eb10bfe52acf6ed48a3 --- /dev/null +++ b/AMDiS/src/GNUPlotWriter.h @@ -0,0 +1,79 @@ +// ============================================================================ +// == == +// == AMDiS - Adaptive multidimensional simulations == +// == == +// ============================================================================ +// == == +// == crystal growth group == +// == == +// == Stiftung caesar == +// == Ludwig-Erhard-Allee 2 == +// == 53175 Bonn == +// == germany == +// == == +// ============================================================================ +// == == +// == http://www.caesar.de/cg/AMDiS == +// == == +// ============================================================================ + +/** \file GNUPlotWriter.h */ + +#ifndef AMDIS_GNUPLOTWRITER_H +#define AMDIS_GNUPLOTWRITER_H + +#include "MemoryManager.h" +#include "FileWriter.h" +#include <vector> +#include <string> + +namespace AMDiS { + + template<typename T> class DOFVector; + class FiniteElemSpace; + + /** \brief + * + */ + class GNUPlotWriter : public FileWriterInterface + { + public: + MEMORY_MANAGED(GNUPlotWriter); + + /** \brief + * Constructor + */ + GNUPlotWriter(::std::string filename, + FiniteElemSpace *feSpace, + ::std::vector<DOFVector<double>*> &dofVectors); + + /** \brief + * Destructor + */ + virtual ~GNUPlotWriter() {}; + + /** \brief + * Implementation of FileWriter::writeFiles() + */ + virtual void writeFiles(AdaptInfo *adaptInfo, bool force); + + protected: + /** \brief + * Contains the mesh + */ + FiniteElemSpace *feSpace_; + + /** \brief + * vector of dof vectors to write + */ + ::std::vector<DOFVector<double>*> dofVectors_; + + /** \brief + * file name + */ + ::std::string filename_; + }; + +} + +#endif // AMDIS_VALUEWRITER_H diff --git a/AMDiS/src/GSSmoother.cc b/AMDiS/src/GSSmoother.cc new file mode 100755 index 0000000000000000000000000000000000000000..086a6bfe1b520cdd68c36bad254097ff6e1d8e08 --- /dev/null +++ b/AMDiS/src/GSSmoother.cc @@ -0,0 +1,148 @@ +#include "GSSmoother.h" +#include "DOFMatrix.h" +#include "DOFVector.h" +#include "SparseVector.h" +#include "MatrixVector.h" + +namespace AMDiS { + + template<> + void GSSmoother<DOFMatrix, + SparseVector<double>, + ::std::set<DegreeOfFreedom> >:: + smooth(DOFMatrix *matrix, + SparseVector<double> *solution, + SparseVector<double> *rhs, + int iterations, + const ::std::set<DegreeOfFreedom> &dofSet) + { + int i, j, rowNumber, colNumber, numCols; + + double entry, diagEntry = 0.0; + double oldSolution; + + ::std::set<DegreeOfFreedom>::iterator dofIt, + dofEnd = const_cast< ::std::set<DegreeOfFreedom>&>(dofSet).end(); + + for(i = 0; i < iterations; i++) { + for(dofIt = const_cast< ::std::set<DegreeOfFreedom>&>(dofSet).begin(); + dofIt != dofEnd; + ++dofIt) + { + rowNumber = *dofIt; + const ::std::vector<MatEntry>& row = matrix->getRow(rowNumber); + numCols = static_cast<int>(row.size()); + + oldSolution = (*solution)[rowNumber]; + + (*solution)[rowNumber] = (*rhs)[rowNumber]; + + for(j = 0; j < numCols; j++) { + colNumber = row[j].col; + if(colNumber == DOFMatrix::NO_MORE_ENTRIES) break; + if(colNumber == DOFMatrix::UNUSED_ENTRY) continue; + entry = row[j].entry; + if(colNumber == rowNumber) { + diagEntry = entry; + } else { + (*solution)[rowNumber] -= entry * (*solution)[colNumber]; + } + } + (*solution)[rowNumber] *= omega_ / diagEntry; + (*solution)[rowNumber] += (1.0 - omega_) * oldSolution; + } + } + + // dofEnd = const_cast< ::std::set<DegreeOfFreedom>&>(dofSet).begin(); + + // for(i = 0; i < iterations; i++) { + // for(dofIt = const_cast< ::std::set<DegreeOfFreedom>&>(dofSet).end(); + // dofIt != dofEnd; + // --dofIt) + // { + // rowNumber = *dofIt; + // const ::std::vector<MatEntry>& row = matrix->getRow(rowNumber); + // numCols = static_cast<int>(row.size()); + + // oldSolution = (*solution)[rowNumber]; + + // (*solution)[rowNumber] = (*rhs)[rowNumber]; + + // for(j = 0; j < numCols; j++) { + // colNumber = row[j].col; + // if(colNumber == DOFMatrix::NO_MORE_ENTRIES) break; + // if(colNumber == DOFMatrix::UNUSED_ENTRY) continue; + // entry = row[j].entry; + // if(colNumber == rowNumber) { + // diagEntry = entry; + // } else { + // (*solution)[rowNumber] -= entry * (*solution)[colNumber]; + // } + // } + // (*solution)[rowNumber] *= omega_ / diagEntry; + // (*solution)[rowNumber] += (1.0 - omega_) * oldSolution; + // } + // } + } + + template<> + void GSSmoother<Matrix<DOFMatrix*>, + Vector<SparseVector<double>*>, + Vector< ::std::set<DegreeOfFreedom>*> >:: + smooth(Matrix<DOFMatrix*> *m, + Vector<SparseVector<double>*> *s, + Vector<SparseVector<double>*> *r, + int iterations, + const Vector< ::std::set<DegreeOfFreedom>*> &dofSet) + { + int numComponents = s->getSize(); + int i, j, k, l; + int rowNumber, colNumber, numCols; + + double entry, diagEntry = 0.0; + double oldSolution; + + DOFMatrix *matrix; + SparseVector<double> *rhs; + + ::std::set<DegreeOfFreedom>::iterator dofIt, dofEnd; + + for(i = 0; i < iterations; i++) { + for(j = 0; j < numComponents; j++) { + dofEnd = dofSet[j]->end(); + rhs = (*r)[j]; + + for(dofIt = dofSet[j]->begin(); dofIt != dofEnd; ++dofIt) { + rowNumber = *dofIt; + + oldSolution = (*(*s)[j])[rowNumber]; + (*(*s)[j])[rowNumber] = (*rhs)[rowNumber]; + + for(k = 0; k < numComponents; k++) { + matrix = (*m)[j][k]; + + if(matrix) { + const ::std::vector<MatEntry>& row = matrix->getRow(rowNumber); + numCols = static_cast<int>(row.size()); + + for(l = 0; l < numCols; l++) { + colNumber = row[l].col; + if(colNumber == DOFMatrix::NO_MORE_ENTRIES) break; + if(colNumber == DOFMatrix::UNUSED_ENTRY) continue; + entry = row[l].entry; + if(j == k && colNumber == rowNumber) { + diagEntry = entry; + } else { + (*(*s)[j])[rowNumber] -= entry * (*(*s)[k])[colNumber]; + } + } + } + } + (*(*s)[j])[rowNumber] *= omega_ / diagEntry; + (*(*s)[j])[rowNumber] += (1.0 - omega_) * oldSolution; + } + } + } + } + +} diff --git a/AMDiS/src/GSSmoother.h b/AMDiS/src/GSSmoother.h new file mode 100755 index 0000000000000000000000000000000000000000..6309635e06a2c7b352c4907edefa08f40aa2b649 --- /dev/null +++ b/AMDiS/src/GSSmoother.h @@ -0,0 +1,66 @@ +// ============================================================================ +// == == +// == AMDiS - Adaptive multidimensional simulations == +// == == +// ============================================================================ +// == == +// == crystal growth group == +// == == +// == Stiftung caesar == +// == Ludwig-Erhard-Allee 2 == +// == 53175 Bonn == +// == germany == +// == == +// ============================================================================ +// == == +// == http://www.caesar.de/cg/AMDiS == +// == == +// ============================================================================ + +/** \file SmootherBase.h */ + +#ifndef AMDIS_GSSMOOTHER_H +#define AMDIS_GSSMOOTHER_H + +#include "SmootherBase.h" +#include "MemoryManager.h" +#include "Parameters.h" + +namespace AMDiS { + + template<typename MatrixType, typename VectorType, typename DOFSetType> + class GSSmoother : public SmootherBase<MatrixType, VectorType, DOFSetType> + { + public: + MEMORY_MANAGED(GSSmoother<MatrixType COMMA VectorType COMMA DOFSetType>); + + class Creator : public SmootherCreator<MatrixType, VectorType, DOFSetType> + { + public: + MEMORY_MANAGED(Creator); + + SmootherBase<MatrixType, VectorType, DOFSetType> *create() { + return NEW GSSmoother<MatrixType, VectorType, DOFSetType>(this->name); + }; + }; + + GSSmoother(::std::string name_) + : SmootherBase<MatrixType, VectorType, DOFSetType>(name_), + omega_(1.0) + { + GET_PARAMETER(0, name_ + "->omega", "%f", &omega_); + }; + + void smooth(MatrixType *matrix, + VectorType *solution, + VectorType *rhs, + int iterations, + const DOFSetType &dofSet); + + protected: + double omega_; + }; + +} + +#endif diff --git a/AMDiS/src/GaussElimination.h b/AMDiS/src/GaussElimination.h new file mode 100644 index 0000000000000000000000000000000000000000..49d3b85659a15a8d56c392a017a93e9d130052a3 --- /dev/null +++ b/AMDiS/src/GaussElimination.h @@ -0,0 +1,75 @@ +#ifndef AMDIS_GAUSSELIMINATION_H +#define AMDIS_GAUSSELIMINATION_H + +#include "DirectSolverInterface.h" +#include "Global.h" +#include "MemoryManager.h" + +namespace AMDiS +{ + template<typename MatrixType, typename VectorType> + class GaussElimination : public DirectSolverInterface<MatrixType, VectorType> + { + public: + MEMORY_MANAGED(GaussElimination<MatrixType COMMA VectorType>); + + GaussElimination() {}; + + virtual ~GaussElimination() {}; + + void solve(MatrixType &a, VectorType &b, VectorType &x, int n) + { + FUNCNAME("GaussElimination::solve()"); + + int i, j, k, row; + double a_ji, max, tmp = 0.0; + + // forward elimination + for(i = 0; i < n - 1; i++) { + + // pivoting + max = abs(a[i][i]); + row = i; + + for(j = i + 1; j < n; j++) { + if(abs(a[j][i]) > max) { + max = abs(a[j][i]); + row = j; + } + } + + TEST_EXIT(max > 0.0)("pivoting failed (max entry = 0)\n"); + + if(row != i) { + tmp = b[i]; + b[i] = b[row]; + b[row] = tmp; + for(j = 0; j < n; j++) { + tmp = a[i][j]; + a[i][j] = a[row][j]; + a[row][j] = tmp; + } + } + + // make zeros + for(j = i + 1; j < n; j++) { + a_ji = (a[j][i] /= a[i][i]); + for(k = i; k < n; k++) { + a[j][k] -= a_ji * a[i][k]; + } + b[j] -= a_ji * b[i]; + } + } + + // backward elimination + for(i = n - 1; i >= 0; i--) { + for(j = i + 1; j < n; j++) { + b[i] -= a[i][j] * x[j]; + } + x[i] = b[i] / a[i][i]; + } + }; + }; +} + +#endif diff --git a/AMDiS/src/Global.cc b/AMDiS/src/Global.cc new file mode 100644 index 0000000000000000000000000000000000000000..be40548b63cd6773b947b6b3774029ec5208dbb9 --- /dev/null +++ b/AMDiS/src/Global.cc @@ -0,0 +1,348 @@ +#include "Global.h" +#include "Parameters.h" +#include "Element.h" +#include "Line.h" +#include "Triangle.h" +#include "Tetrahedron.h" + + +#include <stdarg.h> +#include <stdio.h> + +namespace AMDiS { + + const char *funcName = NULL; + const char *Msg::oldFuncName = NULL; + ::std::ostream* Msg::out=NULL; + ::std::ostream* Msg::error=NULL; + int Global::dimOfWorld = 0; + int Msg::msgInfo = 10; + bool Msg::msgWait = true; + + Element *Global::referenceElement[4] = + { NULL, NEW Line(NULL), NEW Triangle(NULL), NEW Tetrahedron(NULL) }; + + void Msg::wait(bool w) + { + FUNCNAME("Msg::wait()"); + + if (w) { + char line[10]; + MSG("wait for <enter> ..."); + fgets(line, 9, stdin); + } + return; + } + + void Msg::change_out(::std::ostream *fp) + { + FUNCNAME("Msg::change_out()"); + + if (fp) { + if (out && *out != ::std::cout && *out != ::std::cerr) { + dynamic_cast< ::std::ofstream*>(out)->close(); + delete out; + } + + out = fp; + } else { + ERROR("file pointer is pointer to nil;\n"); + ERROR("use previous stream for errors furthermore\n"); + } + + return; + } + + void Msg::open_file(const char *filename, OPENMODE type) + { + FUNCNAME("Msg::open_file"); + ::std::ofstream *fp; + + + if (filename && (fp = new ::std::ofstream(filename, type))) + { + if (out && *out != ::std::cout && *out != ::std::cerr) + { + dynamic_cast< ::std::ofstream*>(out)->close(); + delete out; + } + + out = fp; + } + else + { + if (filename) + ERROR("can not open %s;\n", filename); + else + ERROR("no filename specified;\n"); + ERROR("use previous stream for messages furthermore\n"); + } + return; + } + + void Msg::change_error_out(::std::ofstream *fp) + { + FUNCNAME("Msg::change_error_out"); + if (fp) + { + if (error && *error != ::std::cout && *error != ::std::cerr) + { + dynamic_cast< ::std::ofstream*>(error)->close(); + delete error; + } + + error = fp; + } + else + { + ERROR("file pointer is pointer to nil;\n"); + ERROR("use previous stream for errors furthermore\n"); + } + + return; + } + + void Msg::open_error_file(const char *filename, OPENMODE type) + { + FUNCNAME("Msg::open_error_file"); + ::std::ofstream *fp; + + if (filename && (fp = new ::std::ofstream(filename, type))) + { + if (error && *error != ::std::cout && *error != ::std::cerr) + { + dynamic_cast< ::std::ofstream*>(error)->close(); + delete error; + } + + error = fp; + } + else + { + if (filename) + ERROR("can not open %s;\n", filename); + else + ERROR("no filename specified;\n"); + ERROR("use previous stream for errors furthermore\n"); + } + return; + } + + const char *generate_filename(const char * path, const char * fn, int ntime) + { + static char name[256]; + char *cp; + + if (path == NULL || path[0] == '\0') + { + sprintf(name, "./%s", fn); + } + else + { + const char* ccp = path; + while (*ccp) + ccp++; + ccp--; + if (*ccp == '/') + sprintf(name, "%s%s", path, fn); + else + sprintf(name, "%s/%s", path, fn); + } + cp = name; + while (*cp) + cp++; + sprintf(cp, "%d", 100000 + ntime); + if (ntime < 100000) *cp = '0'; + + return(const_cast<const char *>(name)); + } + + void Msg::print_funcname(const char *funcName) + { + if (!out) out = &::std::cout; + + if (funcName && oldFuncName != funcName) { + (*out)<< funcName << ":" << ::std::endl; + } else if (!funcName) { + (*out)<<"*unknown function*" << ::std::endl; + } + (*out) << " "; + oldFuncName = funcName; + } + + void Msg::print_error_funcname(const char *funcName, + const char *file, + int line) + { + static int old_line = -1; + + if (!error) error = &::std::cerr; + + if (funcName && oldFuncName != funcName) { + (*error)<<funcName<< ": "; + } + else if (!funcName) { + if (line-old_line > 5) (*error)<< "*unknown function*"; + } + if (oldFuncName != funcName) { + (*error)<<"ERROR in "<<file<<", line "<<line<<"\n"; + oldFuncName = funcName; + } else if (line - old_line > 5) + (*error)<< "ERROR in "<<file<<", line "<<line<<"\n"; + + old_line = line; + } + + void Msg::print_error_exit(const char *format, ...) + { + va_list arg; + char buff[255]; + + if (!error) error = &::std::cerr; + + va_start(arg, format); + vsprintf(buff, format, arg); + (*error)<<buff; + va_end(arg); + + exit(1); + } + + void Msg::print_error(const char *format, ...) + { + va_list arg; + char buff[255]; + + + if (!error) error = &::std::cerr; + + va_start(arg, format); + vsprintf(buff, format, arg); + (*error)<<buff; + va_end(arg); + + return; + } + + void Msg::print_warn_funcname(const char *funcName, + const char *file, + int line) + { + static int old_line = -1; + + if (!out) out = &::std::cout; + + if (funcName && oldFuncName != funcName) { + (*out)<<funcName<<": "; + } + else if (!funcName){ + (*out)<< "*unknown function*"; + } + if (oldFuncName != funcName) { + (*out)<<"WARNING in "<<file<<", line "<<line<<"\n"; + oldFuncName = funcName; + } else if (line - old_line > 5) + (*out)<<"WARNING in "<<file<<", line "<<line<<"\n"; + + old_line = line; + } + + void Msg::print_warn(const char *format, ...) + { + va_list arg; + char buff[255]; + + if (!out) out = &::std::cout; + + va_start(arg, format); + vsprintf(buff, format, arg); + (*out)<<buff; + va_end(arg); + + return; + } + + + void Msg::print(const char *format, ...) + { + va_list arg; + char buff[255]; + + if (!out) + out = &::std::cout; + + va_start(arg, format); + vsprintf(buff, format, arg); + (*out)<<buff; + va_end(arg); + } + + void Global::init() + { + int d = -1; + + // get dimension + TEST_EXIT(Parameters::initialized())("Parameters not initialized!\n"); + Parameters::getGlobalParameter(0,"dimension of world","%d",&d); + TEST_EXIT(d>0)("can not initialize dimension\n"); + TEST_EXIT((d==1)||(d==2)||(d==3))("Invalid world dimension %d!\n",d); + + // set dimension + dimOfWorld = d; + + // set msgWait + Parameters::getGlobalParameter(0,"WAIT","%d",&d); + Msg::setMsgWait(!(d==0)); + }; + + int Global::getGeo(GeoIndex p, int dim) + { + FUNCNAME("Global::getGeo"); + initTest(); + TEST_EXIT((p>=MINPART)&&(p<=MAXPART)) + ("Calling for invalid geometry value %d\n",p); + TEST_EXIT((dim>=0)&&(dim<4))("invalid dim: %d\n", dim); + + if(p == WORLD) return dimOfWorld; + + if(dim == 0) { + switch(p) { + case PARTS: + return 1; + case VERTEX: + return 1; + case EDGE: + return 0; + case FACE: + return 0; + default: + ERROR_EXIT("dim = 0\n"); + } + } + + return referenceElement[dim]->getGeo(p); + } + + + int fac(int i) + { + if(i<=1) return 1; + else return i*fac(i-1); + } + + ::std::string memSizeStr(int size) + { + ::std::string result; +// if (size > 1024) { +// if (size > 1024 * 1024) { +// result << size / (1024 * 1024) << " MByte"; +// } else { +// result << size / 1024 << " KByte"; +// } +// } else { +// result << size << " Byte"; +// } + + return result; + } +} diff --git a/AMDiS/src/Global.h b/AMDiS/src/Global.h new file mode 100644 index 0000000000000000000000000000000000000000..77d8cd81342cac956f0fee88f6a556d075ffae65 --- /dev/null +++ b/AMDiS/src/Global.h @@ -0,0 +1,497 @@ +// ============================================================================ +// == == +// == AMDiS - Adaptive multidimensional simulations == +// == == +// ============================================================================ +// == == +// == crystal growth group == +// == == +// == Stiftung caesar == +// == Ludwig-Erhard-Allee 2 == +// == 53175 Bonn == +// == germany == +// == == +// ============================================================================ +// == == +// == http://www.caesar.de/cg/AMDiS == +// == == +// ============================================================================ + +/** \file Global.h */ + +/** \mainpage AMDiS + * @{ <img src="vis.png"> @} + */ + +/** \defgroup Common Common + */ + +#ifndef AMDIS_GLOBAL_H +#define AMDIS_GLOBAL_H + +#if (__GNUC__) && (__GNUC__ > 2) +#define OPENMODE ::std::ios::openmode +#else +#define OPENMODE ::std::ios::open_mode +#endif + +/** \brief current AMDiS version */ +#define AMDIS_VERSION "AMDiS: Version 0.100" + +// ============================================================================ +// ===== includes ============================================================= +// ============================================================================ + +#include <string> +#include <vector> +#include <fstream> +#include <math.h> +#include <iostream> +#include <stdio.h> +#include <functional> +#include <float.h> + +namespace AMDiS { + // ============================================================================ + // ===== forward declarations ================================================= + // ============================================================================ + + class Mesh; + class Element; + + extern const char *funcName; + + // ============================================================================ + // ===== definitions ========================================================== + // ============================================================================ + + /** \brief used by matrix vector multiplication */ + typedef enum { NoTranspose, + Transpose, + ConjugateTranspose } MatrixTranspose; + + /** \brief speciefies the norm used by Estimator. */ + typedef enum { NO_NORM = 0, H1_NORM = 1, L2_NORM = 2 } Norm; + + + /** \brief datatype for degrees of freedom */ + typedef signed int DegreeOfFreedom; + + + /** \brief + * returns the GeoIndex of d for dimension dim. + */ +#define INDEX_OF_DIM(d, dim) (static_cast<GeoIndex>((d == dim) ? CENTER : d + 1)) + + /** \brief + * returns the dimension of GeoIndex ind for dimension dim + */ +#define DIM_OF_INDEX(ind, dim) ((static_cast<int>(ind) == 0) ? dim : static_cast<int>(ind) - 1) + + + /** \brief + * Returns boundary->getBound() if boundary is not NULL. Returns INTERIOR + * otherwise. + */ + //#define GET_BOUND(boundary) ((boundary) ? (boundary)->getBound() : INTERIOR) + + /** \brief + * Calculates factorial of i + */ + int fac(int i); + + /** \brief + * Calculates the logaritmic error progression + */ +#define EOC(e,eo) log(eo/::std::max(e,1.0e-15))/M_LN2 + + /** \brief + * Content comparision of two pointers. Used e.g. for ::std::find_if + */ + template<typename T> + struct comparePtrContents : public ::std::binary_function<T*, T*, bool> + { + /** \brief + * Overrides binary_function::operator() + */ + bool operator()(T* a, T* b) const { + return (*a == *b); + }; + }; + + // ===== some simple template functions ====================================== + + //template<typename T> T max(T a,T b ) {return ((a) > (b) ? (a) : (b));} + template<typename T,typename S> inline T max(T a,S b ) + { + return ((a) > (b) ? (a) : (b)); + } + + template<typename T> inline T min(T a,T b) + { + return ((a) < (b)) ? (a) : (b); + } + + template<typename T> inline T abs(T a) + { + return ((a) >= 0 ? (a) : -(a)); + } + + template<typename T> inline T sqr(T a) + { + return ((a)*(a)); + } + + // ===== some predefined values =============================================== + const double m_e = 2.7182818284590452354; + const double m_log2e = 1.4426950408889634074; + const double m_log10e = 0.43429448190325182765; + const double m_ln2 = 0.69314718055994530942; + const double m_ln10 = 2.30258509299404568402; + const double m_pi = 3.14159265358979323846; + const double m_pi_2 = 1.57079632679489661923; + const double m_pi_4 = 0.78539816339744830962; + const double m_1_pi = 0.31830988618379067154; + const double m_2_pi = 0.63661977236758134308; + const double m_2_sqrtpi = 1.12837916709551257390; + const double m_sqrt2 = 1.41421356237309504880; + const double m_sqrt1_2 = 0.70710678118654752440; + + // ===== tolerance for floating point comparison ============================== +#define DBL_TOL DBL_EPSILON +#define FLT_TOL FLT_EPSILON + + // ============================================================================ + // ===== class Msg ============================================================ + // ============================================================================ + + /** \brief + * Manages the output of messages, warnings, errors, ... + * Used by the macros FUNCNAME, ERROR, ERROR_EXIT, WARNING, TEST, MSG, INFO, + * PRINT_INFO, WAIT, WAIT_REALLY. + * Don't use this class directly but only via these macros! + */ + class Msg + { + public: + /** \brief + * Prints a formated message to the message stream + */ + static void print(const char *format, ...); + + /** \brief + * Prints a formated message to the error stream + */ + static void print_error(const char *format, ...); + + /** \brief + * Prints a formated message to the error stream and exits + */ + static void print_error_exit(const char *format, ...); + + /** \brief + * Prints an error message with funcname, file, and line to the error stream + */ + static void print_error_funcname(const char *funcname, + const char *file, + int line); + + /** \brief + * Prints a warning to the message stream + */ + static void print_warn(const char *format, ...); + + /** \brief + * Prints a warning with funcname, file, and line to the message stream + */ + static void print_warn_funcname(const char *funcname, + const char *file, + int line); + + /** \brief + * Prints the funcname to the message stream + */ + static void print_funcname(const char *funcname); + + /** \brief + * Changes the message stream + */ + static void change_out(::std::ostream*); + + /** \brief + * Creates a filestream and sets the message stream to this filestream + */ + static void open_file(const char *filename, OPENMODE); + + /** \brief + * Changes the error stream + */ + static void change_error_out(::std::ofstream *fp); + + /** \brief + * Creates a filestream and sets the error stream to this filestream + */ + static void open_error_file(const char *filename, OPENMODE); + + /** \brief + * Generates a filename from path, file and ntime + */ + static const char *generate_filename(const char *path, + const char *file, + int ntime); + + /** \brief + * Sets \ref msgInfo + */ + static void setMsgInfo(int info) { msgInfo = info; }; + + /** \brief + * Returns \ref msgInfo + */ + static int getMsgInfo() { return msgInfo; }; + + /** \brief + * Sets \ref msgWait + */ + static void setMsgWait(bool wait) { msgWait = wait; }; + + /** \brief + * Returns \ref msgWait + */ + static bool getMsgWait() { return msgWait; }; + + /** \brief + * Waits for enter if w is true + */ + static void wait(bool w); + + /** \brief + * Returns \ref out + */ + static ::std::ostream *getOutStream() { return out; }; + + /** \brief + * Returns \ref error + */ + static ::std::ostream *getErrorStream() { return error; }; + + protected: + /** \brief + * Message stram + */ + static ::std::ostream *out; + + /** \brief + * Error stream + */ + static ::std::ostream *error; + + /** \brief + * Remember funcName to avoid multiple output of funcName within the same + * function call + */ + static const char *oldFuncName; + + /** \brief + * Global info level + */ + static int msgInfo; + + /** \brief + * Spezifies whether to wait when WAIT is called + */ + static bool msgWait; + }; + + // ============================================================================ + // ===== message macros ======================================================= + // ============================================================================ + + /** \brief + * Should be the first call in every functions. It defines the current function + * name nn for message output via MSG, WARNING, ... + */ + +#define FUNCNAME(nn) const char *funcName; funcName = nn; + + /** \brief + * prints an error message + */ +#define ERROR Msg::print_error_funcname(funcName,__FILE__, __LINE__), \ + Msg::print_error + + /** \brief + * prints an error message and exits + */ +#define ERROR_EXIT Msg::print_error_funcname(funcName,__FILE__, __LINE__), \ + Msg::print_error_exit + + /** \brief + * prints a warning + */ +#define WARNING Msg::print_warn_funcname(funcName,__FILE__, __LINE__), \ + Msg::print_warn + + /** \brief + * if test is false, an error message is printed + */ +#define TEST(test) if ((test));else ERROR + + /** \brief + * if test is false, an error message is printed and the program exits + */ +#define TEST_EXIT(test) if ((test));else ERROR_EXIT + + /** \brief + * prints a message + */ +#define MSG Msg::print_funcname(funcName), Msg::print + + /** \brief + * prints a message, if min(Msg::msgInfo, info) >= noinfo + */ +#define INFO(info,noinfo) \ + if (Msg::getMsgInfo()&&(::std::min(Msg::getMsgInfo(),(info))>=(noinfo))) MSG + + /** \brief + * prints a message, if min(Msg::msgInfo, info) >= noinfo + */ +#define PRINT_INFO(info,noinfo) \ + if (Msg::getMsgInfo()&&(::std::min(Msg::getMsgInfo(),(info))>=(noinfo))) Msg::print + + + /** \brief + * If the value of Msg::wait is not zero the macro will produce the message + * 'wait for <enter> ...' and will continue after pressing the return or enter + * key. Otherwise the program continues without a message. + */ +#define WAIT Msg::wait(Msg::getMsgWait()) + + /** \brief + * produces the message 'wait for <enter> ...' and will continue after pressing + * the return or enter key. + */ +#define WAIT_REALLY Msg::wait(true) + +#include <time.h> +#define TIME_USED(f,s) ((double)((s)-(f))/(double)CLOCKS_PER_SEC) + + /** \brief + * internal used indices to represent the different geometrical objects. + * Used as parameter for getGeo() and as template parameter for FixVec. + */ + typedef enum + { + CENTER = 0, /**< in 1d the center is at the edge, in 2d at the face, in 3d + * at the interior of an element. So a Line has no edge but + * only a center, a Triangle has no face but only a center. + */ + VERTEX = 1, /**< index for element vertices. + * number of vertices is equal to number of parts and + * neighbours. + */ + EDGE = 2, /**< index for element edges */ + FACE = 3, /**< index for element faces */ + DIMEN =-1, /**< index for problem dimension */ + PARTS =-2, /**< index for parts of an element (vertices in 1d, edges in 2d + * , faces in 3d). Number of element parts is equal to number + * of vertices and neighbours. + */ + NEIGH =-3, /**< index for neighbours of an element. + * Number of element neighbours is equal to number of + * vertices and parts. + */ + WORLD =-4, /**< index for world dimension */ + BOUNDARY =-5, /**< index for boundary nodes of an element. This could be + * vertices, edges or faces. + */ + PROJECTION=-6 /**< index for element and boundary projections */ + } GeoIndex; + +#define MAXPART FACE +#define MINPART PROJECTION + + // ============================================================================ + // ===== class Global ========================================================= + // ============================================================================ + + /** \ingroup Common + * \brief + * Static class wich holds global information about the world and all types of + * elements. + */ + class Global + { + public: + /** \brief + * returns a pointer to \ref referenceElement [dim]. With this pointer you + * can get information about the element via Element's getGeo method. + */ + static const Element *getReferenceElement(int dim) { + FUNCNAME("Global::getReferenceElement"); + initTest(); + TEST_EXIT((dim > 0) && (dim < 4))("invalid dim\n"); + return referenceElement[dim]; + }; + + /** \brief + * returns geometrical information. Currently this is only dimOfWorld. + */ + static inline int getGeo(GeoIndex p) { + FUNCNAME("Global::getGeo"); + initTest(); + if (WORLD==p) return dimOfWorld; + ERROR_EXIT("Illegal request for geometry data: part=%d!\n",p); + return 0; + }; + + /** \brief + * returns geometrical information about elements of the dimension dim. + * getGeo(VERTEX, 3) returns 4 because a Tetrahedron has 4 vertices. + */ + static int getGeo(GeoIndex p, int dim); + + private: + /** \brief + * Global is a pure static class. So the constructor is private to avoid + * instantiation. + */ + Global(); + + /** \brief + * inits the Global class with the help of Parameters. + */ + static void init(); + + /** \brief + * calls init if Global is not yet initialized. + */ + static void initTest() { + if(dimOfWorld == 0) init(); + }; + + private: + /** \brief + * dimension of the simulated world + */ + static int dimOfWorld; + + /** \brief + * contains a pointer to a Line, a Triangle, and a Tetrahedron. + * This allows the access to information of the concrete elements via + * the dimension index. + * referenceElement[3]->getGeo(VERTEX) gives the number of vertices of a + * Tetrahedron wich is 4 => no switch statement is necessary. + */ + static Element *referenceElement[4]; + }; + +#define COMMA , + + const int RescheduleErrorCode = 23; + + ::std::string memSizeStr(int size); +} + +#endif // AMDIS_GLOBAL_H + diff --git a/AMDiS/src/GlobalDOFNumbering.cc b/AMDiS/src/GlobalDOFNumbering.cc new file mode 100644 index 0000000000000000000000000000000000000000..a3f1ff2198155771182db009ab1ca026ed6adf23 --- /dev/null +++ b/AMDiS/src/GlobalDOFNumbering.cc @@ -0,0 +1,100 @@ +#include "GlobalDOFNumbering.h" +#include "MeshStructure.h" +#include "MemoryManager.h" + +namespace AMDiS { + + GlobalDOFNumbering::GlobalDOFNumbering(::std::vector<MeshStructure*> &meshCodes, + ::std::vector< ::std::vector<DegreeOfFreedom> > &dofCodes, + int dofsPerElement) + : dofsPerElement_(dofsPerElement), + globalIndexCounter_(0) + { + int rank, mpiSize = static_cast<int>(meshCodes.size()); + + ::std::vector< ::std::vector<DegreeOfFreedom>::iterator> it(mpiSize); + + // init + for(rank = 0; rank < mpiSize; rank++) { + meshCodes[rank]->reset(); + it[rank] = dofCodes[rank].begin(); + } + + // start recursion + while(meshCodes[0]->getCurrentElement() < meshCodes[0]->getNumElements()) { + // one call for each macro element + handleRecursive(meshCodes, it); + } + } + + void GlobalDOFNumbering::handleRecursive(::std::vector<MeshStructure*> &meshCodes, + ::std::vector< ::std::vector<DegreeOfFreedom>::iterator> &it) + { + int rank, mpiSize = static_cast<int>(meshCodes.size()); + int dofNr; + + // === handle === + int firstRankUsed = -1; + for(rank = 0; rank < mpiSize; rank++) { + if(meshCodes[rank] != NULL) { + firstRankUsed = rank; + break; + } + } + + TEST_EXIT(firstRankUsed > -1)("no used rank in recursion\n"); + + for(dofNr = 0; dofNr < dofsPerElement_; dofNr++) { + bool newDOF = (localToGlobal_[firstRankUsed][*(it[firstRankUsed])] == 0); + + DegreeOfFreedom globalIndex = -1; + if(newDOF) { + globalIndex = globalIndexCounter_++; + } + + for(rank = 0; rank < mpiSize; rank++) { + if(meshCodes[rank]) { + if(newDOF) { + DegreeOfFreedom localIndex = *(it[rank]); + localToGlobal_[rank][localIndex] = globalIndex + 1; + globalToLocal_[rank][globalIndex] = localIndex + 1; + } + ++(it[rank]); + } + } + } + + // === recursion === + ::std::vector<MeshStructure*> recursiveCodes; + bool cont = false; + for(rank = 0; rank < mpiSize; rank++) { + if(meshCodes[rank]) { + if(!meshCodes[rank]->isLeafElement()) { + recursiveCodes[rank] = meshCodes[rank]; + cont = true; + } else { + recursiveCodes[rank] = NULL; + } + meshCodes[rank]->nextElement(); + } else { + recursiveCodes[rank] = NULL; + } + } + + if(cont) { + handleRecursive(recursiveCodes, it); // left tree + handleRecursive(recursiveCodes, it); // right tree + } + } + + int GlobalDOFNumbering::getLocalIndex(int rank, int globalIndex) + { + return (globalToLocal_[rank][globalIndex] - 1); + } + + int GlobalDOFNumbering::getGlobalIndex(int rank, int localIndex) + { + return (localToGlobal_[rank][localIndex] - 1); + } + +} diff --git a/AMDiS/src/GlobalDOFNumbering.h b/AMDiS/src/GlobalDOFNumbering.h new file mode 100644 index 0000000000000000000000000000000000000000..f2f25c159ce08a338bf28db516e46b6c4ec9ba38 --- /dev/null +++ b/AMDiS/src/GlobalDOFNumbering.h @@ -0,0 +1,83 @@ +// ============================================================================ +// == == +// == AMDiS - Adaptive multidimensional simulations == +// == == +// ============================================================================ +// == == +// == crystal growth group == +// == == +// == Stiftung caesar == +// == Ludwig-Erhard-Allee 2 == +// == 53175 Bonn == +// == germany == +// == == +// ============================================================================ +// == == +// == http://www.caesar.de/cg/AMDiS == +// == == +// ============================================================================ + +/** \file GlobalDOFNumbering.h */ + +#ifndef AMDIS_GLOBALDOFNUMBERING_H +#define AMDIS_GLOBALDOFNUMBERING_H + +// =========================================================================== +// ===== includes ============================================================ +// =========================================================================== +#include <map> +#include <vector> +#include "Global.h" + +namespace AMDiS { + + // ========================================================================= + // ===== forward declarations ============================================== + // ========================================================================= + class MeshStructure; + + // ========================================================================= + // ===== class GlobalDOFNumbering ====================================== + // ========================================================================= + + /** \ingroup Parallel + * \brief + * Creates a global DOF numbering. + */ + class GlobalDOFNumbering + { + public: + /** \brief + * Constructor + */ + GlobalDOFNumbering(::std::vector<MeshStructure*> &meshCodes, + ::std::vector< ::std::vector<DegreeOfFreedom> > &dofCodes, + int dofsPerElement); + + /** \brief + * Returns the local index of rank corresponding to global index. + */ + int getLocalIndex(int rank, int globalIndex); + + /** \brief + * Returns the global index corresponing to local index of rank. + */ + int getGlobalIndex(int rank, int localIndex); + + protected: + void handleRecursive(::std::vector<MeshStructure*> &meshCodes, + ::std::vector< ::std::vector<DegreeOfFreedom>::iterator> &it); + + protected: + ::std::vector< ::std::map<DegreeOfFreedom, DegreeOfFreedom> > localToGlobal_; + + ::std::vector< ::std::map<DegreeOfFreedom, DegreeOfFreedom> > globalToLocal_; + + int dofsPerElement_; + + DegreeOfFreedom globalIndexCounter_; + }; + +} + +#endif diff --git a/AMDiS/src/GlobalElementNumbering.cc b/AMDiS/src/GlobalElementNumbering.cc new file mode 100644 index 0000000000000000000000000000000000000000..cd08923472396c87b47bc47d0e15ca984b8704e7 --- /dev/null +++ b/AMDiS/src/GlobalElementNumbering.cc @@ -0,0 +1,41 @@ +#include "GlobalElementNumbering.h" +#include "MeshStructure.h" +#include "Mesh.h" +#include "Traverse.h" +#include "ElInfo.h" +#include "Element.h" + +namespace AMDiS { + + GlobalElementNumbering::GlobalElementNumbering(MeshStructure *compositeStructure, + Mesh *localMesh) + { + int localIndex, globalIndex; + compositeStructure->reset(); + TraverseStack stack; + ElInfo *elInfo = stack.traverseFirst(localMesh, -1, Mesh::CALL_EVERY_EL_PREORDER); + while(elInfo) { + Element *element = elInfo->getElement(); + localIndex = element->getIndex(); + globalIndex = compositeStructure->getCurrentElement(); + localToGlobal_[localIndex] = globalIndex + 1; + globalToLocal_[globalIndex] = localIndex + 1; + if(element->isLeaf()) { + compositeStructure->skipBranch(); + } else { + compositeStructure->nextElement(); + } + elInfo = stack.traverseNext(elInfo); + } + } + + int GlobalElementNumbering::getLocalIndex(int globalIndex) + { + return (globalToLocal_[globalIndex] - 1); + } + + int GlobalElementNumbering::getGlobalIndex(int localIndex) + { + return (localToGlobal_[localIndex] - 1); + } +} diff --git a/AMDiS/src/GlobalElementNumbering.h b/AMDiS/src/GlobalElementNumbering.h new file mode 100644 index 0000000000000000000000000000000000000000..afe9b468d654047cc9db0b362b28bfb2819f6f30 --- /dev/null +++ b/AMDiS/src/GlobalElementNumbering.h @@ -0,0 +1,79 @@ +// ============================================================================ +// == == +// == AMDiS - Adaptive multidimensional simulations == +// == == +// ============================================================================ +// == == +// == crystal growth group == +// == == +// == Stiftung caesar == +// == Ludwig-Erhard-Allee 2 == +// == 53175 Bonn == +// == germany == +// == == +// ============================================================================ +// == == +// == http://www.caesar.de/cg/AMDiS == +// == == +// ============================================================================ + +/** \file GlobalElementNumbering.h */ + +#ifndef AMDIS_GLOBALELEMENTNUMBERING_H +#define AMDIS_GLOBALELEMENTNUMBERING_H + +// =========================================================================== +// ===== includes ============================================================ +// =========================================================================== +#include <map> + +namespace AMDiS { + + // ========================================================================= + // ===== forward declarations ============================================== + // ========================================================================= + class MeshStructure; + class Mesh; + + // ========================================================================= + // ===== class GlobalElementNumbering ====================================== + // ========================================================================= + + /** \ingroup Parallel + * \brief + * Creates a global element numbering. + */ + class GlobalElementNumbering + { + public: + /** \brief + * Constructor + */ + GlobalElementNumbering(MeshStructure *compositeStructure, + Mesh *localMesh); + + /** \brief + * Returns the local index corresponding to local index. + */ + int getLocalIndex(int globalIndex); + + /** \brief + * Returns the global index corresponing to local index. + */ + int getGlobalIndex(int localIndex); + + protected: + /** \brief + * Maps each local index to its global index. + */ + ::std::map<int, int> localToGlobal_; + + /** \brief + * Stores local index for each global index. + */ + ::std::map<int, int> globalToLocal_; + }; + +} + +#endif diff --git a/AMDiS/src/GridWriter.h b/AMDiS/src/GridWriter.h new file mode 100644 index 0000000000000000000000000000000000000000..1d5f8e94597f783d9a61ddf420a5b6582d6ea0ec --- /dev/null +++ b/AMDiS/src/GridWriter.h @@ -0,0 +1,74 @@ +// ============================================================================ +// == == +// == AMDiS - Adaptive multidimensional simulations == +// == == +// ============================================================================ +// == == +// == crystal growth group == +// == == +// == Stiftung caesar == +// == Ludwig-Erhard-Allee 2 == +// == 53175 Bonn == +// == germany == +// == == +// ============================================================================ +// == == +// == http://www.caesar.de/cg/AMDiS == +// == == +// ============================================================================ + +/** \file GridWriter.h */ + +#ifndef AMDIS_GRID_WRITER_H +#define AMDIS_GRID_WRITER_H + +#include "Global.h" + +namespace AMDiS { + + template<typename T> class WorldVector; + template<typename T> class DOFVector; + + // ============================================================================ + // ===== class GridWriter ===================================================== + // ============================================================================ + + /** \ingroup Output + * \brief + * Produces a grid-based output of a dof-vector + */ + template<typename T> + class GridWriter { + public: + /** \brief + * Produces a grid-based output of a dof-vector + * \param p array of world coordinates. + * - p[0] defines origin of grid-system. + * - p[1] defines first basis vector by p[1] - p[0]. + * - p[2] defines second basis vector by p[2] - p[0] (dim >= 2). + * - p[3] defines third basis vector by p[3] - p[0] (dim == 3). + * \param numPoints number of grid points for the different dirctions + * - numPoints[0] number of grid points in the first direction + * - numPoints[1] number of grid points in the second direction + * - numPoints[2] number of grid points in the third direction + * \param dist distance between two points in the different directions + * - dist[0] distance in the first direction + * - dist[1] distance in the second direction + * - dist[2] distance in the third direction + * \param vec DOFVector which is interpolated to the grid. + * \param filename file to which the grid will be written + */ + static void writeGrid(const WorldVector<double> *p, + int *numPoints, + double *dist, + DOFVector<T> *vec, + char* filename); + + private: + }; + +} + +#include "GridWriter.hh" + +#endif diff --git a/AMDiS/src/GridWriter.hh b/AMDiS/src/GridWriter.hh new file mode 100644 index 0000000000000000000000000000000000000000..989336ee193830e368872cc4e7fb29e8f7caa8c4 --- /dev/null +++ b/AMDiS/src/GridWriter.hh @@ -0,0 +1,129 @@ +#include <fstream> + +#include "FixVec.h" +#include "DOFVector.h" +#include "BasisFunction.h" +#include "Mesh.h" + +namespace AMDiS { + + template<typename T> + void GridWriter<T>::writeGrid(const WorldVector<double> *p, + int *numPoints, + double *dist, + DOFVector<T> *vec, + char* filename) + { + FUNCNAME("GridWriter<T>::writeGrid()"); + + ::std::ofstream *outFile = new ::std::ofstream(filename); + TEST_EXIT(outFile)("can't open file %s\n", filename); + + const Mesh *mesh = vec->getFESpace()->getMesh(); + int dim = mesh->getDim(); + + TEST_EXIT(dim == Global::getGeo(WORLD)) + ("not for DIM != DIM_OF_WORLD\n"); + + + WorldVector<double> *basis = NEW WorldVector<double>[dim]; + double *lengthBasis = GET_MEMORY(double, dim); + WorldVector<double> *step = NEW WorldVector<double>[3]; + + for (int i = 0; i < dim; i++) { + TEST_EXIT(numPoints[i] > 0)("numPoints < 1\n"); + TEST_EXIT(dist[i] >= 0)("dist < 0\n"); + lengthBasis[i] = 0; + } + + WorldVector<double> curCoord; + DimVec<double> bary(dim, NO_INIT); + Element *elp; + const BasisFunction *basFcts = NULL; + int inside; + double value; + const double *uhLoc; + + TEST_EXIT(vec)("no dof vector\n"); + TEST_EXIT(filename)("no filename\n"); + TEST_EXIT(vec->getFESpace()->getBasisFcts())("no basis fcts\n"); + + mesh = vec->getFESpace()->getMesh(); + basFcts = vec->getFESpace()->getBasisFcts(); + + /* get basis of grid */ + for (int i = 0; i < dim; i++) { + for (int j = 0; j < dim; j++) { + basis[i][j] = p[i+1][j] - p[0][j]; + lengthBasis[i] += basis[i][j] * basis[i][j]; + } + lengthBasis[i] = sqrt(lengthBasis[i]); + } + + /* norm basis, get steps */ + for (int i = 0; i < dim; i++) { + for (int j = 0; j < dim; j++) { + basis[i][j] /= lengthBasis[i]; + step[i][j] = basis[i][j] * dist[j]; + } + } + + /* write grid points */ + int localNumPoints[3] = {1, 1, 1}; + for (int i = 0; i < dim; i++) { + localNumPoints[i] = numPoints[i]; + } + + // Warning "Coords not in mesh domain" should be printed at most one time. + bool warning = false; + + for (int i = 0; i < localNumPoints[0]; i++) { + for (int j = 0; j < localNumPoints[1]; j++) { // pseudo-loop for dim < 2 + for (int k = 0; k < localNumPoints[2]; k++) { // pseudo-loop for dim < 3 + /* clac current coords */ + for (int l = 0; l < dim; l++) { + curCoord[l] = p[0][l] + + (i * step[0][l]) + + (j * step[1][l]) // j = 0 for dim > 1 + + (k * step[2][l]); // k = 0 for dim > 2 + } + + inside = + (const_cast<Mesh*>(mesh))->findElementAtPoint(curCoord, + &elp, + bary, + NULL, NULL, NULL); + + /* write coords */ + for (int l = 0; l < dim; l++) { + (*outFile) << curCoord[l] << " "; + } + + if (!inside) { + if (!warning) { + WARNING("Coords not in mesh domain\n"); + warning = true; + } + /* write value */ + (*outFile) << "0.0" << ::std::endl; + } else { + /* get value at coords */ + uhLoc = vec->getLocalVector(elp, NULL); + value = basFcts->evalUh(bary, uhLoc); + + /* write value */ + (*outFile) << value << ::std::endl; + } + } + if (localNumPoints[2] > 1) (*outFile) << ::std::endl; + } + if (localNumPoints[1] > 1) (*outFile) << ::std::endl; + } + + DELETE [] basis; + FREE_MEMORY(lengthBasis, double, dim); + DELETE [] step; + delete outFile; + } + +} diff --git a/AMDiS/src/ILUPreconditioner.cc b/AMDiS/src/ILUPreconditioner.cc new file mode 100644 index 0000000000000000000000000000000000000000..972137d3ee9b418f222c3ae41cb685a144796fea --- /dev/null +++ b/AMDiS/src/ILUPreconditioner.cc @@ -0,0 +1,314 @@ +#include <iostream> +#include <sstream> +#include <vector> + +#include "ILUPreconditioner.h" +#include "DOFVector.h" +#include "DOFMatrix.h" +#include "DOFIterator.h" +#include "MatVecMultiplier.h" +#include "StlVector.h" + +namespace AMDiS { + + void ILUPreconditioner::init() + { + FUNCNAME("ILUPreconditioner::init()"); + + clock_t first = clock(); + + ilu_.resize(matrix.getSize()); + + for (int i = 0; i < matrix.getSize(); i++) { + if ((*matrix[i])) { + ilu_[i] = NEW DOFMatrix((*(*matrix[i]))); + } + } + + + DOFMatrix *ilu = ilu_[row]; + + int matrixSize = ilu->getRowFESpace()->getAdmin()->getUsedSize(); + + // Sort all rows corresponding to their position in the matrix. + diag_.resize(matrixSize); + for (int i = 0; i < matrixSize; i++) { + diag_[i] = (*ilu)[i][0].entry; + sort((*ilu)[i].begin(), (*ilu)[i].end(), CmpMatEntryCol()); + } + + // For i = 1, ..., n - 1, Do + for (int i = 1; i < matrixSize; i++) { + + // For k = 0, ..., i - 1 and for (i,k) \in NZ(ilu), Do + for (int col1 = 0; col1 < static_cast<int>((*ilu)[i].size()); col1++) { + // k is the logical index of the col1-th column in the i-th row. + int k = (*ilu)[i][col1].col; + if ((k < i) && // due to the condition that k goes up to i - 1 + (k >= 0) && // the entry is valid + ((*ilu)[i][col1].entry != 0.0)) { // the entry is non-zero, hence in NZ(ilu) + // Compute a_ik = a_ik / a_kk + (*ilu)[i][col1].entry = (*ilu)[i][col1].entry / diag_[k]; + + // For j = k + 1, ..., n - 1 and for (i,j) \in NZ(ilu), Do + for (int col2 = col1 + 1; col2 < static_cast<int>((*ilu)[i].size()); col2++) { + // j is the logical index of the col2-th column in the i-th row. + int j = (*ilu)[i][col2].col; + + // Because the rows are sorted, we start at position col1 + 1, and all non-valid + // entries have col < 0, we do not need to check for non-valid entries. + if ((*ilu)[i][col2].entry != 0.0) { + int physKJ = (*ilu).logToPhysIndex(k, j); + // If physKJ is negativ, the corresponding entry is zero and we do not need + // to compute the new element. + if (physKJ >= 0) { + // Compute a_ij = a_ij - a_ik * a_kj + (*ilu)[i][col2].entry = (*ilu)[i][col2].entry - ((*ilu)[i][col1].entry * (*ilu)[k][physKJ].entry); + // Do not forgett to update the diagonal entries, if we have computed on + // a diagonal element. + if (i == j) { + diag_[i] = (*ilu)[i][col2].entry; + } + } + } + } + } + } + } + + MSG("preconditioning of the coefficient matrix needed %.5f seconds\n", + TIME_USED(first,clock())); + } + + void ILUPreconditioner::exit() + { + for (int i = 0; i < ilu_.getSize(); i++) { + if ((*matrix[i])) { + DELETE ilu_[i]; + } + } + } + + void ILUPreconditioner::precon(DOFVector<double>* x) + { + DOFMatrix *ilu = ilu_[row]; + + // The solution of P * x = b must be calculated in the + // following. Note that the vector b is stored in x to + // saving space. + // We solve the equation with forward and backward substitution + // of the factorization P = L * U. + + DOFVector<double>::Iterator itx(x, USED_DOFS); + + // Forward substitution: L * y = b + // We use x to save the new results of y. Note that all diagonal + // elements of L are 1, hence we do not need to devide the term + // by the diagonal elements. + int i = 0; + for (itx.reset(); !itx.end(); ++itx, ++i) { + // y_i = b_i + // Must not be assigned directly, since x = b and y will take + // the results of y. + + ::std::vector<MatEntry> *m = &(*ilu)[i]; + + // y_i = b_i - \sum_{1}^{i-1} ( l_{i,k} * y_k ) + for (int col = 0; col < static_cast<int>((*m).size()); col++) { + int k = (*m)[col].col; + if (k >= 0) { + if (k < i) { + (*itx) -= (*m)[col].entry * (*x)[k]; + } else { + // If for an entry k < i does not hold, it will be also false + // for all other elements in th column, because the columns + // are sorted. + break; + } + } + } + } + + + // Backward substitution: R * x = y + do { + itx--; + i--; + + ::std::vector<MatEntry> *m = &(*ilu)[i]; + + // x_i = y_i - \sum_{i + 1}^(n} ( r_{i,k} * x_k ) + // The sum is build backwards, since the directon of calculation does not + // matter for the result, but we can break the search if k > i does not + // hold (the cols of ilu_ are sorted!) and so make the calculation faster. + for (int col = static_cast<int>((*m).size()) - 1; col >= 0; col--) { + int k = (*m)[col].col; + if (k > i) { + (*itx) -= (*m)[col].entry * (*x)[k]; + } else { + break; + } + } + + // x_i = x_i / r_{i,i} + (*itx) /= diag_[i]; + + } while (!itx.begin()); + } + + + + + + + + + + ///////////////////////////// + + void ILUPreconditionerStd::init() + { + FUNCNAME("ILUPreconditionerStd::init()"); + + clock_t first = clock(); + + ilu_ = *matrix; + + int matrixSize = ilu_.size(); + +// ilu_.resize(matrixSize); + +// for (int i = 0; i < matrixSize; i++) { +// ilu_[i] = (*matrix +// } + + ::std::vector< ::std::vector<MatEntry> > *ilu = &ilu_; + + + + // Sort all rows corresponding to their position in the matrix. + diag_.resize(matrixSize); + for (int i = 0; i < matrixSize; i++) { + diag_[i] = (*ilu)[i][0].entry; + sort((*ilu)[i].begin(), (*ilu)[i].end(), CmpMatEntryCol()); + } + + // For i = 1, ..., n - 1, Do + for (int i = 1; i < matrixSize; i++) { + + // For k = 0, ..., i - 1 and for (i,k) \in NZ(ilu), Do + for (int col1 = 0; col1 < static_cast<int>((*ilu)[i].size()); col1++) { + // k is the logical index of the col1-th column in the i-th row. + int k = (*ilu)[i][col1].col; + if ((k < i) && // due to the condition that k goes up to i - 1 + (k >= 0) && // the entry is valid + ((*ilu)[i][col1].entry != 0.0)) { // the entry is non-zero, hence in NZ(ilu) + // Compute a_ik = a_ik / a_kk + (*ilu)[i][col1].entry = (*ilu)[i][col1].entry / diag_[k]; + + // For j = k + 1, ..., n - 1 and for (i,j) \in NZ(ilu), Do + for (int col2 = col1 + 1; col2 < static_cast<int>((*ilu)[i].size()); col2++) { + // j is the logical index of the col2-th column in the i-th row. + int j = (*ilu)[i][col2].col; + + // Because the rows are sorted, we start at position col1 + 1, and all non-valid + // entries have col < 0, we do not need to check for non-valid entries. + if ((*ilu)[i][col2].entry != 0.0) { + // int physKJ = (*ilu).logToPhysIndex(k, j); + int physKJ = logToPhysIndex(ilu, k, j); + + // If physKJ is negativ, the corresponding entry is zero and we do not need + // to compute the new element. + if (physKJ >= 0) { + // Compute a_ij = a_ij - a_ik * a_kj + (*ilu)[i][col2].entry = (*ilu)[i][col2].entry - ((*ilu)[i][col1].entry * (*ilu)[k][physKJ].entry); + // Do not forgett to update the diagonal entries, if we have computed on + // a diagonal element. + if (i == j) { + diag_[i] = (*ilu)[i][col2].entry; + } + } + } + } + } + } + } + + MSG("preconditioning of the coefficient matrix needed %.5f seconds\n", + TIME_USED(first,clock())); + } + + void ILUPreconditionerStd::exit() + { + } + + void ILUPreconditionerStd::precon(::std::vector<double> *x) + { + ::std::vector< ::std::vector<MatEntry> > *ilu = &ilu_; + + // The solution of P * x = b must be calculated in the + // following. Note that the vector b is stored in x to + // saving space. + // We solve the equation with forward and backward substitution + // of the factorization P = L * U. + + // DOFVector<double>::Iterator itx(x, USED_DOFS); + + ::std::vector<double>::iterator itx; + + // Forward substitution: L * y = b + // We use x to save the new results of y. Note that all diagonal + // elements of L are 1, hence we do not need to devide the term + // by the diagonal elements. + int i = 0; + for (itx = x->begin(); itx != x->end(); ++itx, ++i) { + // y_i = b_i + // Must not be assigned directly, since x = b and y will take + // the results of y. + + ::std::vector<MatEntry> *m = &(*ilu)[i]; + + // y_i = b_i - \sum_{1}^{i-1} ( l_{i,k} * y_k ) + for (int col = 0; col < static_cast<int>((*m).size()); col++) { + int k = (*m)[col].col; + if (k >= 0) { + if (k < i) { + (*itx) -= (*m)[col].entry * (*x)[k]; + } else { + // If for an entry k < i does not hold, it will be also false + // for all other elements in th column, because the columns + // are sorted. + break; + } + } + } + } + + + // Backward substitution: R * x = y + do { + itx--; + i--; + + ::std::vector<MatEntry> *m = &(*ilu)[i]; + + // x_i = y_i - \sum_{i + 1}^(n} ( r_{i,k} * x_k ) + // The sum is build backwards, since the directon of calculation does not + // matter for the result, but we can break the search if k > i does not + // hold (the cols of ilu_ are sorted!) and so make the calculation faster. + for (int col = static_cast<int>((*m).size()) - 1; col >= 0; col--) { + int k = (*m)[col].col; + if (k > i) { + (*itx) -= (*m)[col].entry * (*x)[k]; + } else { + break; + } + } + + // x_i = x_i / r_{i,i} + (*itx) /= diag_[i]; + + } while (itx != x->begin()); + } + +} diff --git a/AMDiS/src/ILUPreconditioner.h b/AMDiS/src/ILUPreconditioner.h new file mode 100644 index 0000000000000000000000000000000000000000..8eee1ee5e841a3698a97862ee11eb71fc34d93fa --- /dev/null +++ b/AMDiS/src/ILUPreconditioner.h @@ -0,0 +1,181 @@ +// ============================================================================ +// == == +// == AMDiS - Adaptive multidimensional simulations == +// == == +// ============================================================================ +// == == +// == crystal growth group == +// == == +// == Stiftung caesar == +// == Ludwig-Erhard-Allee 2 == +// == 53175 Bonn == +// == germany == +// == == +// ============================================================================ +// == == +// == http://www.caesar.de/cg/AMDiS == +// == == +// ============================================================================ + +/** \file ILUPreconditioner.h */ + +#ifndef AMDIS_ILU_PRECONDITIONER_H +#define AMDIS_ILU_PRECONDITIONER_H + +#include <vector> +#include "Preconditioner.h" +#include "MemoryManager.h" +#include "CreatorInterface.h" +#include "DOFMatrix.h" + +namespace AMDiS { + + template<typename T> class DOFVector; + template<typename T> class OEMSolver; + + // ============================================================================ + // ===== class ILUPreconditioner ============================================== + // ============================================================================ + + /** + * \ingroup Solver + * + * \brief + * ILU (Incomplete LU factorization) preconditioner. + * + * The preconditioner is implemented following the book "Iterative Methods for + * Sparce Linear Systems", second edition, Yousef Saad. The preconditioner is + * described in chapter 10.3 (algorithm 10.4). + */ + class ILUPreconditioner : public PreconditionerScal + { + public: + MEMORY_MANAGED(ILUPreconditioner); + + /** \brief + * Creater class used in PreconditionerMap. + */ + class Creator : public PreconditionerScalCreator + { + public: + MEMORY_MANAGED(Creator); + + /** \brief + * Creates an ILUPreconditioner. + */ + PreconditionerScal *create() { + return NEW ILUPreconditioner(size, row); + }; + }; + + /** \brief + * Constructor. + */ + ILUPreconditioner(int size = 1, int row = 0) + : PreconditionerScal(size, row) + {}; + + /** \brief + * Destructor. + */ + virtual ~ILUPreconditioner() {}; + + /** \brief + * Realisation of Preconditioner::init + * + * In the initalization phase the incomplete LU factorization + * of the coefficent matrix is calculated. + */ + void init(); + + /** \brief + * Realisation of Preconditioner::exit + */ + void exit(); + + /** \brief + * Realisation of Preconditioner::precon + */ + void precon(DOFVector<double>* x); + + private: + /** \brief + * This matrix stores the incomplete LU factorization + * of the coefficient matrix. + */ + // DOFMatrix *ilu_; + Vector<DOFMatrix*> ilu_; + + /** \brief + * Here we store the diagonal elements of ilu_ matrix. This + * allows faster computations. + */ + ::std::vector<double> diag_; + }; + + + + + + + + + + + + + + + + + class ILUPreconditionerStd : public PreconditionerScalStd + { + public: + MEMORY_MANAGED(ILUPreconditionerStd); + + + /** \brief + * Constructor. + */ + ILUPreconditionerStd() {}; + + /** \brief + * Destructor. + */ + virtual ~ILUPreconditionerStd() {}; + + /** \brief + * Realisation of Preconditioner::init + * + * In the initalization phase the incomplete LU factorization + * of the coefficent matrix is calculated. + */ + void init(); + + /** \brief + * Realisation of Preconditioner::exit + */ + void exit(); + + /** \brief + * Realisation of Preconditioner::precon + */ + void precon(::std::vector<double>* x); + + private: + /** \brief + * This matrix stores the incomplete LU factorization + * of the coefficient matrix. + */ + ::std::vector< ::std::vector<MatEntry> > ilu_; + + /** \brief + * Here we store the diagonal elements of ilu_ matrix. This + * allows faster computations. + */ + ::std::vector<double> diag_; + }; + +} + +#endif // AMDIS_ILU_PRECONDITIONER_H diff --git a/AMDiS/src/ILUTPreconditioner.cc b/AMDiS/src/ILUTPreconditioner.cc new file mode 100644 index 0000000000000000000000000000000000000000..aa6fdb2d0a5b2734d58402caf3bd035e2fac2dc6 --- /dev/null +++ b/AMDiS/src/ILUTPreconditioner.cc @@ -0,0 +1,247 @@ +#include <vector> +#include "ILUTPreconditioner.h" +#include "DOFVector.h" +#include "DOFMatrix.h" +#include "DOFIterator.h" +#include "MatVecMultiplier.h" + +namespace AMDiS { + + void ILUTPreconditioner::init() + { + FUNCNAME("ILUTPreconditioner::init()"); + + TEST_EXIT(matrix[row])("no matrix\n"); + + clock_t first = clock(); + + // Make a copy of the system matrix. + ilu_ = (*(*matrix[row])); + + int matrixSize = ilu_.getRowFESpace()->getAdmin()->getUsedSize(); + + diag_.resize(matrixSize); + + // For i = 1, ..., n, Do + for (int i = 0; i < matrixSize; i++) { + // We do not make a real copy of the row, but instead w is a pointer to + // the current row. + ::std::vector<MatEntry> *w = &(ilu_[i]); + + + // Calculate tau_i by calculating the 2-norm of the current row and + // multiplying the result with the parameter tau. + double taui = 0.0; + for (int col1 = 0; col1 < static_cast<int>((*w).size()); col1++) { + taui += (*w)[col1].entry * (*w)[col1].entry; + } + taui = sqrt(taui) * tau_; + + + // For k = 1, ..., i - 1 and when w_k not= 0, Do + for (int col1 = 0; col1 < static_cast<int>((*w).size()); col1++) { + // Pointer to the w_ik element + MatEntry *w_k = &((*w)[col1]); + + // Get the logical index k of the current element of row w. + int k = (*w_k).col; + + if ((k < i) && // must be smaller than i due to the loop condition + (k >= 0) && // must be a valid entry + ((*w_k).entry != 0.0)) { // must be non zero due to the loop condition + + // w_k := w_k / a_kk (note that the diagonal elements are always stored in the first entry of a row) + (*w_k).entry /= (*(*matrix[row]))[k][0].entry; + + // Dropping rule to w_k + // It is checked if the absolute value of w_k is smaller than tau_i + if (fabs((*w_k).entry) < taui) { + // Do not delete the element yet but set it to zero, so it will be deleted + // when the second dropping rule will be applied. + (*w_k).entry = 0.0; + } else { + // w := w - w_k * u_k* + // To compute the result, all elements of u_k are multiplied with w_k. Then + // we check if there is an element in w with the same column index. If yes, + // the result of the multiplication is substracted from the corresponding + // element in w. Otherwise, a new element in w with the negative value of + // the multiplication is created. + for (int col2 = 0; col2 < static_cast<int>(ilu_[k].size()); col2++) { + + // Pointer to the current element of row u_k* + MatEntry *u_kj = &ilu_[k][col2]; + + // We are in the k-th row of matrix ilu_. The row is devided into L and + // U factorization. Hence, all elements of U in ilu_ must have a column + // index that is greater than k. + if (((*u_kj).col > k) && // must be a U element + ((*u_kj).entry != 0.0)) { // must be non zero + + // w_k * u_kj + double v = (*w_k).entry * (*u_kj).entry; + + // search for the physical index of the j-th column in row w. + int index = -1; + for (int z = 0; z < static_cast<int>((*w).size()); z++) { + if ((*w)[z].col == (*u_kj).col) { + index = z; + break; + } + } + + if (index >= 0) { + // If there is a j-th column in row w, make the substraction. + (*w)[index].entry -= v; + } else { + // Otherwise, if the absolut value of the result of the multiplication + // is greater than the relative tolerance, create a new element in w. + if (fabs(v) > taui) { + MatEntry newEntry = {(*u_kj).col, -v}; + (*w).push_back(newEntry); + } + } + } + + } + } + } + } + + // Apply second dropping rule. + // First, remove all elements which absolut value is smaller than tau_i. + (*w).erase(remove_if((*w).begin(), (*w).end(), MatEntryValueLess(taui)), + (*w).end()); + + // Calculate the number of elements in the L-part of the current row. + int nL = 0; + for (int k = 1; k < static_cast<int>((*w).size()); k++) { + if ((*w)[k].col < i) { + nL++; + } + } + // Calculate the number of elements in the U-part of the current row. + int nU = (*w).size() - nL - 1; + + // Now we check, if there are more elements in L- and U-parts of the row + // than we should store. If it is so, the final number of elements is + // reduced to p. + if (nL > p_) { + nL = p_; + } + if (nU > p_) { + nU = p_; + } + + // First, we sort the row in such a way that the first element will stay to be + // the diagonal element, then all the elements of the L-part follows and after + // them all the elements of the U-part. Because we are in the i-th row, elements + // of L must have a column index smaller than i. + // itMiddle is then an iterator to the first element of the U-part. + ::std::vector<MatEntry>::iterator itMiddle = + partition((*w).begin() + 1, (*w).end(), MatEntryColLess(i)); + + // If there are elements in the L-part: + if (nL > 0) { + // Search for the nL largest elements in the L-part of the row. + nth_element((*w).begin() + 1, + (*w).begin() + 1 + nL, + itMiddle - 1, + CmpMatEntryAbsValueGreater()); + + // Delete all the elements that do not belong to the nL largest elements + // in the L-part. + itMiddle = (*w).erase((*w).begin() + nL + 1, itMiddle); + } + + // If there are elements in the U-part: + if (nU > 0) { + // Search for the nU largest elements in the U-part of the row. + nth_element(itMiddle, + itMiddle + nU, + (*w).end(), + CmpMatEntryAbsValueGreater()); + + // Delete all the elements that do not belong to the nU largest elements + // in the L-part. + (*w).erase(itMiddle + nU, (*w).end()); + } + + // Store the diagonal element and sort the line. + diag_[i] = (*w)[0].entry; + sort((*w).begin(), (*w).end(), CmpMatEntryCol()); + } + + + MSG("preconditioning of the coefficient matrix needed %.5f seconds\n", + TIME_USED(first,clock())); + } + + + void ILUTPreconditioner::exit() + { + ilu_.clear(); + } + + void ILUTPreconditioner::precon(DOFVector<double>* x) + { + // The solution of P * x = b must be calculated in the + // following. Note that the vector b is stored in x to + // saving space. + // We solve the equation with forward and backward substitution + // of the factorization P = L * U. + + DOFVector<double>::Iterator itx(x, USED_DOFS); + + // Forward substitution: L * y = b + // We use x to save the new results of y. Note that all diagonal + // elements of L are 1, hence we do not need to devide the term + // by the diagonal elements. + int i = 0; + for (itx.reset(); !itx.end(); ++itx, ++i) + { + // y_i = b_i + // Must not be assigned directly, since x = b and y will take + // the results of y. + + // y_i = b_i - \sum_{1}^{i-1} ( l_{i,k} * y_k ) + for (int col = 0; col < static_cast<int>(ilu_[i].size()); col++) { + int k = ilu_[i][col].col; + if (k >= 0) { + if (k < i) { + (*itx) -= ilu_[i][col].entry * (*x)[k]; + } else { + // If for an entry k < i does not hold, it will be also false + // for all other elements in th column, because the columns + // are sorted. + break; + } + } + } + } + + + // Backward substitution: R * x = y + do { + itx--; + i--; + + // x_i = y_i - \sum_{i + 1}^(n} ( r_{i,k} * x_k ) + // The sum is build backwards, since the directon of calculation does not + // matter for the result, but we can break the search if k > i does not + // hold (the cols of ilu_ are sorted!) and so make the calculation faster. + for (int col = static_cast<int>(ilu_[i].size()) - 1; col >= 0; col--) { + int k = ilu_[i][col].col; + if (k > i) { + (*itx) -= ilu_[i][col].entry * (*x)[k]; + } else { + break; + } + } + + // x_i = x_i / r_{i,i} + (*itx) /= diag_[i]; + + } while (!itx.begin()); + } + +} diff --git a/AMDiS/src/ILUTPreconditioner.h b/AMDiS/src/ILUTPreconditioner.h new file mode 100644 index 0000000000000000000000000000000000000000..b313eaffb9a17e2325e553dd4b843ba15a27b2b7 --- /dev/null +++ b/AMDiS/src/ILUTPreconditioner.h @@ -0,0 +1,137 @@ +// ============================================================================ +// == == +// == AMDiS - Adaptive multidimensional simulations == +// == == +// ============================================================================ +// == == +// == crystal growth group == +// == == +// == Stiftung caesar == +// == Ludwig-Erhard-Allee 2 == +// == 53175 Bonn == +// == germany == +// == == +// ============================================================================ +// == == +// == http://www.caesar.de/cg/AMDiS == +// == == +// ============================================================================ + +/** \file ILUTPreconditioner.h */ + +#ifndef AMDIS_ILUT_PRECONDITIONER_H +#define AMDIS_ILUT_PRECONDITIONER_H + +#include <vector> +#include "Preconditioner.h" +#include "MemoryManager.h" +#include "CreatorInterface.h" +#include "DOFMatrix.h" +#include "Parameters.h" + +namespace AMDiS { + + template<typename T> class DOFVector; + template<typename T> class OEMSolver; + + // ============================================================================ + // ===== class ILUTPreconditioner ============================================== + // ============================================================================ + + /** + * \ingroup Solver + * + * \brief + * ILUT (Incomplete LU factorization with Threshold) preconditioner. + * + * The preconditioner is implemented following the book "Iterative Methods for + * Sparce Linear Systems", second edition, Yousef Saad. The preconditioner is + * described in chapter 10.4 (algorithm 10.6). + * We have changed the dropping rules of the original algorithm to that the + * absolut values of w_k are checked. + */ + class ILUTPreconditioner : public PreconditionerScal + { + public: + MEMORY_MANAGED(ILUTPreconditioner); + + /** \brief + * Creater class used in PreconditionerMap. + */ + class Creator : public PreconditionerScalCreator + { + public: + MEMORY_MANAGED(Creator); + + /** \brief + * Creates an ILUPreconditioner. + */ + PreconditionerScal *create() { + return NEW ILUTPreconditioner(this->name_, size, row); + }; + }; + + /** \brief + * Constructor. + */ + ILUTPreconditioner(::std::string name, int size = 1, int row = 0) + : PreconditionerScal(size, row), + name_(name), + tau_(0.0001), + p_(8) + { + GET_PARAMETER(0, name + "->tau", "%f", &tau_); + GET_PARAMETER(0, name + "->p", "%d", &p_); + }; + + /** \brief + * Destructor. + */ + virtual ~ILUTPreconditioner() {}; + + /** \brief + * Realisation of Preconditioner::init + * + */ + void init(); + + /** \brief + * Realisation of Preconditioner::exit + */ + void exit(); + + /** \brief + * Realisation of Preconditioner::precon + */ + void precon(DOFVector<double>* x); + + private: + ::std::string name_; + + /** \brief + * This matrix stores the incomplete LU factorization + * of the coefficient matrix. + */ + DOFMatrix ilu_; + + /** \brief + * Here we store the diagonal elements of ilu_ matrix. This + * allows faster computations. + */ + ::std::vector<double> diag_; + + /** \brief + * Stores the threshold factor for the preconditioning process. + */ + double tau_; + + /** \brief + * Stores the number of entries that are finally stored in each row + * of L and U. Hence, the total number of elements in each row of ilu_ + * is 2p + 1 (the diagonal element is always stored). + */ + int p_; + }; +} + +#endif // AMDIS_ILUT_PRECONDITIONER_H diff --git a/AMDiS/src/InterpolRestrictMatrix.cc b/AMDiS/src/InterpolRestrictMatrix.cc new file mode 100644 index 0000000000000000000000000000000000000000..2a2bf26df9d2004cbc658e1d8adae5464428fb05 --- /dev/null +++ b/AMDiS/src/InterpolRestrictMatrix.cc @@ -0,0 +1,547 @@ +#include "InterpolRestrictMatrix.h" +#include "FiniteElemSpace.h" +#include "DOFVector.h" +#include "Traverse.h" +#include "ElInfo.h" +#include "Mesh.h" +#include "BasisFunction.h" +#include "DOFAdmin.h" +#include "Element.h" +#include "SparseVector.h" +#include "ElementMatrix.h" +#include "DOFMatrix.h" +#include <set> + +namespace AMDiS { + + InterpolRestrictMatrix::InterpolRestrictMatrix(int numFcts, + int numRows, + int numCols, + bool type0Used) + : numFcts_(numFcts), + numRows_(numRows), + numCols_(numCols), + type0_used_(type0Used), + transposed_(false), + initialized_(false) + { + parentDOFs_ = GET_MEMORY(DegreeOfFreedom, numFcts_); + child0DOFs_ = GET_MEMORY(DegreeOfFreedom, numFcts_); + child1DOFs_ = GET_MEMORY(DegreeOfFreedom, numFcts_); + + rowDOFPtrs_ = GET_MEMORY(DegreeOfFreedom*, numRows_); + colDOFPtrs_ = GET_MEMORY(DegreeOfFreedom*, numCols_); + + type0_rowDOFPtrs_ = + type0_used_ ? GET_MEMORY(DegreeOfFreedom*, numRows_) : NULL; + type0_colDOFPtrs_ = + type0_used_ ? GET_MEMORY(DegreeOfFreedom*, numCols_) : NULL; + } + + + InterpolRestrictMatrix::InterpolRestrictMatrix(InterpolRestrictMatrix& matrix, + bool transposed) + : numFcts_(matrix.numFcts_), + numRows_(matrix.numCols_), + numCols_(matrix.numRows_), + parentDOFs_(matrix.parentDOFs_), + child0DOFs_(matrix.child0DOFs_), + child1DOFs_(matrix.child1DOFs_), + rowDOFPtrs_(matrix.colDOFPtrs_), + colDOFPtrs_(matrix.rowDOFPtrs_), + type0_used_(matrix.type0_used_), + type0_rowDOFPtrs_(matrix.type0_colDOFPtrs_), + type0_colDOFPtrs_(matrix.type0_rowDOFPtrs_), + transposed_(true), + initialized_(true) + { + FUNCNAME("InterpolRestrictMatrix : copy constructor"); + TEST_EXIT(transposed == true)("not yet for transposed == false\n"); + + if(!matrix.initialized_) { + matrix.initialized_ = true; + matrix.fillMemory(); + } + + // copy directCopyDOFs_ + ::std::vector<DegreeOfFreedom>::const_iterator copyIt; + ::std::vector<DegreeOfFreedom>::const_iterator copyBegin = + matrix.directCopyDOFs_.begin(); + ::std::vector<DegreeOfFreedom>::const_iterator copyEnd = + matrix.directCopyDOFs_.end(); + for(copyIt = copyBegin; copyIt != copyEnd; ++copyIt) { + directCopyDOFs_.push_back(*copyIt); + } + + // fill matrices + ::std::map<int, ::std::map<int, double> >::const_iterator rowsIt; + ::std::map<int, ::std::map<int, double> >::const_iterator rowsBegin; + ::std::map<int, ::std::map<int, double> >::const_iterator rowsEnd; + ::std::map<int, double>::const_iterator colIt; + ::std::map<int, double>::const_iterator colBegin; + ::std::map<int, double>::const_iterator colEnd; + + // unique row matrix + rowsBegin = matrix.uniqueColMatrix_.begin(); + rowsEnd = matrix.uniqueColMatrix_.end(); + for(rowsIt = rowsBegin; rowsIt != rowsEnd; ++rowsIt) { + int row = rowsIt->first; + colBegin = rowsIt->second.begin(); + colEnd = rowsIt->second.end(); + for(colIt = colBegin; colIt != colEnd; ++colIt) { + int col = colIt->first; + double entry = colIt->second; + uniqueRowMatrix_[col][row] = entry; + } + } + + // unique col matrix + rowsBegin = matrix.uniqueRowMatrix_.begin(); + rowsEnd = matrix.uniqueRowMatrix_.end(); + for(rowsIt = rowsBegin; rowsIt != rowsEnd; ++rowsIt) { + int row = rowsIt->first; + colBegin = rowsIt->second.begin(); + colEnd = rowsIt->second.end(); + for(colIt = colBegin; colIt != colEnd; ++colIt) { + int col = colIt->first; + double entry = colIt->second; + uniqueColMatrix_[col][row] = entry; + } + } + + // normal matrix + rowsBegin = matrix.matrix_.begin(); + rowsEnd = matrix.matrix_.end(); + for(rowsIt = rowsBegin; rowsIt != rowsEnd; ++rowsIt) { + int row = rowsIt->first; + colBegin = rowsIt->second.begin(); + colEnd = rowsIt->second.end(); + for(colIt = colBegin; colIt != colEnd; ++colIt) { + int col = colIt->first; + double entry = colIt->second; + matrix_[col][row] = entry; + } + } + } + + + InterpolRestrictMatrix::~InterpolRestrictMatrix() + { + if(!transposed_) { + FREE_MEMORY(parentDOFs_, DegreeOfFreedom, numFcts_); + FREE_MEMORY(child0DOFs_, DegreeOfFreedom, numFcts_); + FREE_MEMORY(child1DOFs_, DegreeOfFreedom, numFcts_); + + FREE_MEMORY(rowDOFPtrs_, DegreeOfFreedom*, numRows_); + FREE_MEMORY(colDOFPtrs_, DegreeOfFreedom*, numCols_); + + if(type0_used_) { + FREE_MEMORY(type0_rowDOFPtrs_, DegreeOfFreedom*, numRows_); + FREE_MEMORY(type0_colDOFPtrs_, DegreeOfFreedom*, numCols_); + } + } + } + + void InterpolRestrictMatrix::mv(DOFVectorBase<double> *src, + DOFVectorBase<double> *dest, + int coarseLevel) + { + FUNCNAME("InterpolRestrictMatrix::mv()"); + + if(!initialized_) { + initialized_ = true; + fillMemory(); + } + + TEST_EXIT(src)("src not set\n"); + TEST_EXIT(dest)("dest not set\n"); + TEST_EXIT(src->getFESpace() == dest->getFESpace())("invalid feSpaces\n"); + + const FiniteElemSpace *feSpace = src->getFESpace(); + + TEST_EXIT(feSpace->getBasisFcts()->getNumber() == numFcts_) + ("invalid number of basis functions\n"); + + // do matrix vector multiplication + DOFVector<int> visitedRowDOFs(feSpace, "visited row DOFs"); + DOFVector<int> visitedColDOFs(feSpace, "visited col DOFs"); + + const BasisFunction *basFcts = feSpace->getBasisFcts(); + DOFAdmin *admin = feSpace->getAdmin(); + + ::std::map<int, ::std::map<int, double> >::iterator rowsIt; + ::std::map<int, ::std::map<int, double> >::iterator rowsBegin; + ::std::map<int, ::std::map<int, double> >::iterator rowsEnd; + ::std::map<int, double>::iterator colIt; + ::std::map<int, double>::iterator colBegin; + ::std::map<int, double>::iterator colEnd; + ::std::vector<DegreeOfFreedom>::iterator dofIt; + ::std::vector<DegreeOfFreedom>::iterator dofBegin = directCopyDOFs_.begin(); + ::std::vector<DegreeOfFreedom>::iterator dofEnd = directCopyDOFs_.end(); + + // traverse mesh + TraverseStack stack; + ElInfo *elInfo = stack.traverseFirst(feSpace->getMesh(), -1, + Mesh::CALL_EVERY_EL_PREORDER); + while(elInfo) { + Element *element = elInfo->getElement(); + if(elInfo->getLevel() == coarseLevel && !element->isLeaf()) { + + DegreeOfFreedom **rowDOFPtrs; + DegreeOfFreedom **colDOFPtrs; + + if(type0_used_ && dynamic_cast<ElInfo3d*>(elInfo)->getType() == 0) { + rowDOFPtrs = type0_rowDOFPtrs_; + colDOFPtrs = type0_colDOFPtrs_; + } else { + rowDOFPtrs = rowDOFPtrs_; + colDOFPtrs = colDOFPtrs_; + } + + Element *child0 = element->getChild(0); + Element *child1 = element->getChild(1); + + basFcts->getLocalIndices(element, admin, parentDOFs_); + basFcts->getLocalIndices(child0, admin, child0DOFs_); + basFcts->getLocalIndices(child1, admin, child1DOFs_); + + // direct copy dofs from src to dest if necessary + if(src != dest) { + for(dofIt = dofBegin; dofIt != dofEnd; ++dofIt) { + DegreeOfFreedom rowDOF = *(rowDOFPtrs[*dofIt]); + if(visitedRowDOFs[rowDOF] == 0) { + DegreeOfFreedom colDOF = *(colDOFPtrs[*dofIt]); + (*dest)[rowDOF] = (*src)[colDOF]; + visitedRowDOFs[rowDOF] = 1; + } + } + } + + // treat unique rows + rowsBegin = uniqueRowMatrix_.begin(); + rowsEnd = uniqueRowMatrix_.end(); + for(rowsIt = rowsBegin; rowsIt != rowsEnd; ++rowsIt) { + int row = rowsIt->first; + DegreeOfFreedom rowDOF = *(rowDOFPtrs[row]); + if(visitedRowDOFs[rowDOF] == 0) { + visitedRowDOFs[rowDOF] = 1; + (*dest)[rowDOF] = 0.0; + colBegin = rowsIt->second.begin(); + colEnd = rowsIt->second.end(); + for(colIt = colBegin; colIt != colEnd; ++colIt) { + int col = colIt->first; + DegreeOfFreedom colDOF = *(colDOFPtrs[col]); + double entry = colIt->second; + (*dest)[rowDOF] += entry * (*src)[colDOF]; + } + } + } + + // treat unique cols + ::std::set<DegreeOfFreedom> elementColDOFs; + rowsBegin = uniqueColMatrix_.begin(); + rowsEnd = uniqueColMatrix_.end(); + for(rowsIt = rowsBegin; rowsIt != rowsEnd; ++rowsIt) { + int row = rowsIt->first; + DegreeOfFreedom rowDOF = *(rowDOFPtrs[row]); + colBegin = rowsIt->second.begin(); + colEnd = rowsIt->second.end(); + for(colIt = colBegin; colIt != colEnd; ++colIt) { + int col = colIt->first; + DegreeOfFreedom colDOF = *(colDOFPtrs[col]); + if(visitedColDOFs[colDOF] == 0) { + elementColDOFs.insert(colDOF); + double entry = colIt->second; + (*dest)[rowDOF] += entry * (*src)[colDOF]; + } + } + } + + ::std::set<DegreeOfFreedom>::iterator setIt; + ::std::set<DegreeOfFreedom>::iterator setBegin = elementColDOFs.begin(); + ::std::set<DegreeOfFreedom>::iterator setEnd = elementColDOFs.end(); + for(setIt = setBegin; setIt != setEnd; ++setIt) { + visitedColDOFs[*setIt] = 1; + } + + // treat other dofs + rowsBegin = matrix_.begin(); + rowsEnd = matrix_.end(); + for(rowsIt = rowsBegin; rowsIt != rowsEnd; ++rowsIt) { + int row = rowsIt->first; + DegreeOfFreedom rowDOF = *(rowDOFPtrs[row]); + colBegin = rowsIt->second.begin(); + colEnd = rowsIt->second.end(); + for(colIt = colBegin; colIt != colEnd; ++colIt) { + int col = colIt->first; + DegreeOfFreedom colDOF = *(colDOFPtrs[col]); + double entry = colIt->second; + (*dest)[rowDOF] += entry * (*src)[colDOF]; + } + } + } + elInfo = stack.traverseNext(elInfo); + } + } + + + void InterpolRestrictMatrix::assembleDOFMatrix(DOFMatrix *dest, + int coarseLevel) + { + FUNCNAME("InterpolRestrictMatrix::assembleDOFMatrix()"); + TEST_EXIT(dest)("dest not set\n"); + + if(!initialized_) { + initialized_ = true; + fillMemory(); + } + + dest->clear(); + + const FiniteElemSpace *feSpace = dest->getRowFESpace(); + + TEST_EXIT(feSpace->getBasisFcts()->getNumber() == numFcts_) + ("invalid number of basis functions\n"); + + DOFVector<int> visitedRowDOFs(feSpace, "visited row DOFs"); + DOFVector<int> visitedColDOFs(feSpace, "visited col DOFs"); + + const BasisFunction *basFcts = feSpace->getBasisFcts(); + DOFAdmin *admin = feSpace->getAdmin(); + + ::std::map<int, ::std::map<int, double> >::iterator rowsIt; + ::std::map<int, ::std::map<int, double> >::iterator rowsBegin; + ::std::map<int, ::std::map<int, double> >::iterator rowsEnd; + ::std::map<int, double>::iterator colIt; + ::std::map<int, double>::iterator colBegin; + ::std::map<int, double>::iterator colEnd; + ::std::vector<DegreeOfFreedom>::iterator dofIt; + ::std::vector<DegreeOfFreedom>::iterator dofBegin = directCopyDOFs_.begin(); + ::std::vector<DegreeOfFreedom>::iterator dofEnd = directCopyDOFs_.end(); + + ElementMatrix elementMatrix(numRows_, numCols_); + + int i; + TraverseStack stack; + ElInfo *elInfo = stack.traverseFirst(feSpace->getMesh(), -1, + Mesh::CALL_EVERY_EL_PREORDER); + + while (elInfo) { + Element *element = elInfo->getElement(); + if (!element->isLeaf()) { + if (elInfo->getLevel() == coarseLevel) { + + DegreeOfFreedom **rowDOFPtrs; + DegreeOfFreedom **colDOFPtrs; + + if (type0_used_ && dynamic_cast<ElInfo3d*>(elInfo)->getType() == 0) { + rowDOFPtrs = type0_rowDOFPtrs_; + colDOFPtrs = type0_colDOFPtrs_; + } else { + rowDOFPtrs = rowDOFPtrs_; + colDOFPtrs = colDOFPtrs_; + } + + Element *child0 = element->getChild(0); + Element *child1 = element->getChild(1); + + basFcts->getLocalIndices(element, admin, parentDOFs_); + basFcts->getLocalIndices(child0, admin, child0DOFs_); + basFcts->getLocalIndices(child1, admin, child1DOFs_); + + // init element matrix + elementMatrix.set(0.0); + elementMatrix.rowIndices.resize(numRows_); + for (i = 0; i < numRows_; i++) { + elementMatrix.rowIndices[i] = *(rowDOFPtrs[i]); + } + elementMatrix.colIndices.resize(numCols_); + for (i = 0; i < numCols_; i++) { + elementMatrix.colIndices[i] = *(colDOFPtrs[i]); + } + + // treat direct-copy dofs + for (dofIt = dofBegin; dofIt != dofEnd; ++dofIt) { + DegreeOfFreedom rowDOF = *(rowDOFPtrs[*dofIt]); + if (visitedRowDOFs[rowDOF] == 0) { + elementMatrix[*dofIt][*dofIt] = 1.0; + visitedRowDOFs[rowDOF] = 1; + } + } + + // treat unique rows + rowsBegin = uniqueRowMatrix_.begin(); + rowsEnd = uniqueRowMatrix_.end(); + for(rowsIt = rowsBegin; rowsIt != rowsEnd; ++rowsIt) { + int row = rowsIt->first; + DegreeOfFreedom rowDOF = *(rowDOFPtrs[row]); + if(visitedRowDOFs[rowDOF] == 0) { + visitedRowDOFs[rowDOF] = 1; + colBegin = rowsIt->second.begin(); + colEnd = rowsIt->second.end(); + for(colIt = colBegin; colIt != colEnd; ++colIt) { + int col = colIt->first; + double entry = colIt->second; + elementMatrix[row][col] += entry; + } + } + } + + // treat unique cols + ::std::set<DegreeOfFreedom> elementColDOFs; + rowsBegin = uniqueColMatrix_.begin(); + rowsEnd = uniqueColMatrix_.end(); + for(rowsIt = rowsBegin; rowsIt != rowsEnd; ++rowsIt) { + int row = rowsIt->first; + colBegin = rowsIt->second.begin(); + colEnd = rowsIt->second.end(); + for(colIt = colBegin; colIt != colEnd; ++colIt) { + int col = colIt->first; + DegreeOfFreedom colDOF = *(colDOFPtrs[col]); + if(visitedColDOFs[colDOF] == 0) { + elementColDOFs.insert(colDOF); + double entry = colIt->second; + elementMatrix[row][col] += entry; + } + } + } + + ::std::set<DegreeOfFreedom>::iterator setIt; + ::std::set<DegreeOfFreedom>::iterator setBegin = elementColDOFs.begin(); + ::std::set<DegreeOfFreedom>::iterator setEnd = elementColDOFs.end(); + for(setIt = setBegin; setIt != setEnd; ++setIt) { + visitedColDOFs[*setIt] = 1; + } + + // treat other dofs + rowsBegin = matrix_.begin(); + rowsEnd = matrix_.end(); + for(rowsIt = rowsBegin; rowsIt != rowsEnd; ++rowsIt) { + int row = rowsIt->first; + colBegin = rowsIt->second.begin(); + colEnd = rowsIt->second.end(); + for(colIt = colBegin; colIt != colEnd; ++colIt) { + int col = colIt->first; + double entry = colIt->second; + elementMatrix[row][col] += entry; + } + } + + dest->addElementMatrix(1.0, elementMatrix, NULL); + } + } + elInfo = stack.traverseNext(elInfo); + } + + // set matrix to identity for other dofs + DOFMatrix::Iterator destIt(dest, USED_DOFS); + for(destIt.reset(); !destIt.end(); ++destIt) { + if(destIt->size() == 0) { + MatEntry matEntry; + matEntry.col = destIt.getDOFIndex(); + matEntry.entry = 1.0; + destIt->push_back(matEntry); + } + } + } + + void InterpolRestrictMatrix::print() + { + FUNCNAME("InterpolRestrictMatrix::print()"); + + if(!initialized_) { + initialized_ = true; + fillMemory(); + } + + ::std::map<int, ::std::map<int, double> >::iterator rowsIt; + ::std::map<int, ::std::map<int, double> >::iterator rowsBegin; + ::std::map<int, ::std::map<int, double> >::iterator rowsEnd; + ::std::map<int, double>::iterator colIt; + ::std::map<int, double>::iterator colBegin; + ::std::map<int, double>::iterator colEnd; + ::std::vector<DegreeOfFreedom>::iterator dofIt; + ::std::vector<DegreeOfFreedom>::iterator dofBegin = directCopyDOFs_.begin(); + ::std::vector<DegreeOfFreedom>::iterator dofEnd = directCopyDOFs_.end(); + + + // treat direct-copy dofs + MSG("direct copy dofs:\n"); + for(dofIt = dofBegin; dofIt != dofEnd; ++dofIt) { + MSG("%d\n", *dofIt); + } + + // treat unique rows + MSG("unique row matrix:\n"); + rowsBegin = uniqueRowMatrix_.begin(); + rowsEnd = uniqueRowMatrix_.end(); + for(rowsIt = rowsBegin; rowsIt != rowsEnd; ++rowsIt) { + int row = rowsIt->first; + colBegin = rowsIt->second.begin(); + colEnd = rowsIt->second.end(); + for(colIt = colBegin; colIt != colEnd; ++colIt) { + int col = colIt->first; + double entry = colIt->second; + MSG("uniqueRow[%d][%d] = %e\n", row, col, entry); + } + } + + // treat unique cols + MSG("unique col matrix:\n"); + rowsBegin = uniqueColMatrix_.begin(); + rowsEnd = uniqueColMatrix_.end(); + for(rowsIt = rowsBegin; rowsIt != rowsEnd; ++rowsIt) { + int row = rowsIt->first; + colBegin = rowsIt->second.begin(); + colEnd = rowsIt->second.end(); + for(colIt = colBegin; colIt != colEnd; ++colIt) { + int col = colIt->first; + double entry = colIt->second; + MSG("uniqueCol[%d][%d] = %e\n", row, col, entry); + } + } + + // treat other dofs + MSG("matrix:\n"); + rowsBegin = matrix_.begin(); + rowsEnd = matrix_.end(); + for(rowsIt = rowsBegin; rowsIt != rowsEnd; ++rowsIt) { + int row = rowsIt->first; + colBegin = rowsIt->second.begin(); + colEnd = rowsIt->second.end(); + for(colIt = colBegin; colIt != colEnd; ++colIt) { + int col = colIt->first; + double entry = colIt->second; + MSG("matrix[%d][%d] = %e\n", row, col, entry); + } + } + + // print row dof ptrs + MSG("row DOF ptrs:\n"); + int i; + for(i = 0; i < numRows_; i++) { + MSG("row %d : %p\n", i, rowDOFPtrs_[i]); + } + + // print col dof ptrs + MSG("col DOF ptrs:\n"); + for(i = 0; i < numCols_; i++) { + MSG("col %d : %p\n", i, colDOFPtrs_[i]); + } + + // print row dof ptrs + if(type0_used_) { + MSG("type0 row DOF ptrs:\n"); + int i; + for(i = 0; i < numRows_; i++) { + MSG("row %d : %p\n", i, type0_rowDOFPtrs_[i]); + } + + // print col dof ptrs + MSG("type0 col DOF ptrs:\n"); + for(i = 0; i < numCols_; i++) { + MSG("col %d : %p\n", i, type0_colDOFPtrs_[i]); + } + } + } +} diff --git a/AMDiS/src/InterpolRestrictMatrix.h b/AMDiS/src/InterpolRestrictMatrix.h new file mode 100644 index 0000000000000000000000000000000000000000..e7f3f16e301cd3711ebfdaad345a74a2a5e57a07 --- /dev/null +++ b/AMDiS/src/InterpolRestrictMatrix.h @@ -0,0 +1,84 @@ +#ifndef AMDIS_INTERPOLRESTRICTMATRIX_H +#define AMDIS_INTERPOLRESTRICTMATRIX_H + +#include <map> +#include <vector> +#include <string> +#include "Global.h" +#include "MemoryManager.h" + +namespace AMDiS { + + class DOFMatrix; + class Element; + template<typename T> class DOFVectorBase; + + /** \brief + * Defines the data structure for a general interpolation or restriction matrix. + * Both can be used to map vectors from a fine mesh to a coarser mesh and vice + * versa. + */ + class InterpolRestrictMatrix + { + public: + MEMORY_MANAGED(InterpolRestrictMatrix); + + InterpolRestrictMatrix(int numFcts, + int numRows, + int numCols, + bool type0Used); + + + /** \brief + * Creates transposed matrix. Uses memory of original matrix. + */ + InterpolRestrictMatrix(InterpolRestrictMatrix& matrix, + bool transposed); + + virtual ~InterpolRestrictMatrix(); + + /** \brief + * dest = matrix * src without assembling global matrix + */ + void mv(DOFVectorBase<double> *src, + DOFVectorBase<double> *dest, + int coarseLevel); + + void assembleDOFMatrix(DOFMatrix *dest, + int coarseLevel); + + void print(); + + protected: + virtual void fillMemory() {}; + + protected: + int numFcts_; + int numRows_; + int numCols_; + + ::std::vector<DegreeOfFreedom> directCopyDOFs_; + + ::std::map<int, ::std::map<int, double> > uniqueRowMatrix_; + ::std::map<int, ::std::map<int, double> > uniqueColMatrix_; + ::std::map<int, ::std::map<int, double> > matrix_; + + DegreeOfFreedom *parentDOFs_; + DegreeOfFreedom *child0DOFs_; + DegreeOfFreedom *child1DOFs_; + + DegreeOfFreedom **rowDOFPtrs_; + DegreeOfFreedom **colDOFPtrs_; + + bool type0_used_; + + DegreeOfFreedom **type0_rowDOFPtrs_; + DegreeOfFreedom **type0_colDOFPtrs_; + + bool transposed_; + + bool initialized_; + }; +} + +#endif diff --git a/AMDiS/src/JacobiSmoother.cc b/AMDiS/src/JacobiSmoother.cc new file mode 100755 index 0000000000000000000000000000000000000000..a8ccc5077b410cd07a26e73e5d3fd4f1cd4f0061 --- /dev/null +++ b/AMDiS/src/JacobiSmoother.cc @@ -0,0 +1,119 @@ +#include "JacobiSmoother.h" +#include "DOFMatrix.h" +#include "DOFVector.h" +#include "SparseVector.h" +#include "MatrixVector.h" + +namespace AMDiS { + + template<> + void JacobiSmoother<DOFMatrix, + SparseVector<double>, + ::std::set<DegreeOfFreedom> >:: + smooth(DOFMatrix *matrix, + SparseVector<double> *solution, + SparseVector<double> *rhs, + int iterations, + const ::std::set<DegreeOfFreedom> &dofSet) + { + int i, j, rowNumber, colNumber, numCols; + + double entry, diagEntry = 0.0; + + SparseVector<double> oldSolution("old solution", solution); + + ::std::set<DegreeOfFreedom>::iterator dofIt, + dofEnd = const_cast< ::std::set<DegreeOfFreedom>&>(dofSet).end(); + + for(i = 0; i < iterations; i++) { + oldSolution.copy(*solution, dofSet); + for(dofIt = const_cast< ::std::set<DegreeOfFreedom>&>(dofSet).begin(); + dofIt != dofEnd; + ++dofIt) + { + rowNumber = *dofIt; + const ::std::vector<MatEntry>& row = matrix->getRow(rowNumber); + numCols = static_cast<int>(row.size()); + + (*solution)[rowNumber] = (*rhs)[rowNumber]; + + for(j = 0; j < numCols; j++) { + colNumber = row[j].col; + if(colNumber == DOFMatrix::NO_MORE_ENTRIES) break; + if(colNumber == DOFMatrix::UNUSED_ENTRY) continue; + entry = row[j].entry; + if(colNumber == rowNumber) { + diagEntry = entry; + } else { + (*solution)[rowNumber] -= entry * oldSolution[colNumber]; + } + } + (*solution)[rowNumber] *= omega_ / diagEntry; + (*solution)[rowNumber] += (1.0 - omega_) * oldSolution[rowNumber]; + } + } + } + + template<> + void JacobiSmoother<Matrix<DOFMatrix*>, + Vector<SparseVector<double>*>, + Vector< ::std::set<DegreeOfFreedom>*> >:: + smooth(Matrix<DOFMatrix*> *m, + Vector<SparseVector<double>*> *s, + Vector<SparseVector<double>*> *r, + int iterations, + const Vector< ::std::set<DegreeOfFreedom>*> &dofSet) + { + ERROR_EXIT("not yet (still gs)\n"); + + int numComponents = s->getSize(); + int i, j, k, l; + int rowNumber, colNumber, numCols; + + double entry, diagEntry = 0.0; + double oldSolution; + + DOFMatrix *matrix; + SparseVector<double> *rhs; + + ::std::set<DegreeOfFreedom>::iterator dofIt, dofEnd; + + for(i = 0; i < iterations; i++) { + for(j = 0; j < numComponents; j++) { + dofEnd = dofSet[j]->end(); + rhs = (*r)[j]; + + for(dofIt = dofSet[j]->begin(); dofIt != dofEnd; ++dofIt) { + rowNumber = *dofIt; + + oldSolution = (*(*s)[j])[rowNumber]; + (*(*s)[j])[rowNumber] = (*rhs)[rowNumber]; + + for(k = 0; k < numComponents; k++) { + matrix = (*m)[j][k]; + + if(matrix) { + const ::std::vector<MatEntry>& row = matrix->getRow(rowNumber); + numCols = static_cast<int>(row.size()); + + for(l = 0; l < numCols; l++) { + colNumber = row[l].col; + if(colNumber == DOFMatrix::NO_MORE_ENTRIES) break; + if(colNumber == DOFMatrix::UNUSED_ENTRY) continue; + entry = row[l].entry; + if(j == k && colNumber == rowNumber) { + diagEntry = entry; + } else { + (*(*s)[j])[rowNumber] -= entry * (*(*s)[k])[colNumber]; + } + } + } + } + (*(*s)[j])[rowNumber] *= omega_ / diagEntry; + (*(*s)[j])[rowNumber] += (1.0 - omega_) * oldSolution; + } + } + } + } + +} diff --git a/AMDiS/src/JacobiSmoother.h b/AMDiS/src/JacobiSmoother.h new file mode 100755 index 0000000000000000000000000000000000000000..08ac6b9f6e79c36b1439ee6accf957a6e4c574be --- /dev/null +++ b/AMDiS/src/JacobiSmoother.h @@ -0,0 +1,66 @@ +// ============================================================================ +// == == +// == AMDiS - Adaptive multidimensional simulations == +// == == +// ============================================================================ +// == == +// == crystal growth group == +// == == +// == Stiftung caesar == +// == Ludwig-Erhard-Allee 2 == +// == 53175 Bonn == +// == germany == +// == == +// ============================================================================ +// == == +// == http://www.caesar.de/cg/AMDiS == +// == == +// ============================================================================ + +/** \file SmootherBase.h */ + +#ifndef AMDIS_JACOBISMOOTHER_H +#define AMDIS_JACOBISMOOTHER_H + +#include "SmootherBase.h" +#include "MemoryManager.h" +#include "Parameters.h" + +namespace AMDiS { + + template<typename MatrixType, typename VectorType, typename DOFSetType> + class JacobiSmoother : public SmootherBase<MatrixType, VectorType, DOFSetType> + { + public: + MEMORY_MANAGED(JacobiSmoother<MatrixType COMMA VectorType COMMA DOFSetType>); + + class Creator : public SmootherCreator<MatrixType, VectorType, DOFSetType> + { + public: + MEMORY_MANAGED(Creator); + + SmootherBase<MatrixType, VectorType, DOFSetType> *create() { + return NEW JacobiSmoother<MatrixType, VectorType, DOFSetType>(this->name); + }; + }; + + JacobiSmoother(::std::string name) + : SmootherBase<MatrixType, VectorType, DOFSetType>(name), + omega_(1.0) + { + GET_PARAMETER(0, name + "->omega", "%f", &omega_); + }; + + void smooth(MatrixType *matrix, + VectorType *solution, + VectorType *rhs, + int iterations, + const DOFSetType &dofSet); + + protected: + double omega_; + }; + +} + +#endif diff --git a/AMDiS/src/Lagrange.cc b/AMDiS/src/Lagrange.cc new file mode 100644 index 0000000000000000000000000000000000000000..dcf156e3523fa50d47c9abbdd9c27d38a16d8c87 --- /dev/null +++ b/AMDiS/src/Lagrange.cc @@ -0,0 +1,5225 @@ +#include "Mesh.h" +#include "Element.h" +#include "Lagrange.h" +#include "DOFAdmin.h" +#include "RCNeighbourList.h" +#include "DOFVector.h" +#include "Traverse.h" +#include "Line.h" +#include "Triangle.h" +#include "Tetrahedron.h" +#include "Parametric.h" + +#include <stdio.h> +#include <algorithm> +#include <list> + +namespace AMDiS { + + ::std::vector<DimVec<double>* > Lagrange::baryDimDegree[MAX_DIM+1][MAX_DEGREE+1]; + DimVec<int>* Lagrange::ndofDimDegree[MAX_DIM+1][MAX_DEGREE+1]; + int Lagrange::nBasFctsDimDegree[MAX_DIM+1][MAX_DEGREE+1]; + ::std::vector<BasFctType*> Lagrange::phiDimDegree[MAX_DIM+1][MAX_DEGREE+1]; + ::std::vector<GrdBasFctType*> Lagrange::grdPhiDimDegree[MAX_DIM+1][MAX_DEGREE+1]; + ::std::vector<D2BasFctType*> Lagrange::D2PhiDimDegree[MAX_DIM+1][MAX_DEGREE+1]; + ::std::list<Lagrange*> Lagrange::allBasFcts; + + + Lagrange::Lagrange(int dim, int degree) + : BasisFunction(::std::string("Lagrange"), dim, degree) + { + // set name + char dummy[3]; + sprintf(dummy, "%d", dim); + name.append(dummy); + name.append(" "); + sprintf(dummy, "%d", degree); + name.append(dummy); + + // set nDOF + setNDOF(); + + // set barycentric coordinates + setBary(); + + // set function pointer + setFunctionPointer(); + + } + + Lagrange::~Lagrange() + { + } + + Lagrange* Lagrange::getLagrange(int dim, int degree) + { + ::std::list<Lagrange*>::iterator it; + + for(it = allBasFcts.begin(); it != allBasFcts.end(); it++) { + if(((*it)->dim == dim) && ((*it)->degree == degree)) { + return (*it); + } + } + + Lagrange* newLagrange = NEW Lagrange(dim, degree); + allBasFcts.push_back(newLagrange); + return newLagrange; + } + + void Lagrange::setFunctionPointer() + { + if(static_cast<int>( phiDimDegree[dim][degree].size()) == 0) { + // for all positions + for(int i=0; i < dim+1; i++) { + // no vertex dofs for degree 0 ? + if(degree==0 && i!=dim) continue; + // for all vertices/edges/... + for(int j=0; j < Global::getGeo(INDEX_OF_DIM(i,dim),dim); j++) { + // for all dofs at this position + for(int k=0; k < (*nDOF)[INDEX_OF_DIM(i,dim)]; k++) { + // basis function + phiDimDegree[dim][degree].push_back(NEW Phi(this, + INDEX_OF_DIM(i,dim),j,k)); + // gradients + grdPhiDimDegree[dim][degree].push_back(NEW GrdPhi(this, + INDEX_OF_DIM(i,dim), + j,k)); + // D2-Matrices + D2PhiDimDegree[dim][degree].push_back(NEW D2Phi(this, + INDEX_OF_DIM(i,dim), + j,k)); + } + } + } + } + phi = &phiDimDegree[dim][degree]; + grdPhi = &grdPhiDimDegree[dim][degree]; + d2Phi = &D2PhiDimDegree[dim][degree]; + + switch(degree) { + case 0: + refineInter_fct = refineInter0; + coarseRestr_fct = coarseRestr0; + coarseInter_fct = coarseInter0; // not yet implemented + break; + case 1: + refineInter_fct = refineInter1; + coarseRestr_fct = coarseRestr1; + coarseInter_fct = NULL; // not yet implemented + break; + case 2: + switch(dim) { + case 1: + refineInter_fct = refineInter2_1d; + coarseRestr_fct = NULL; // not yet implemented + coarseInter_fct = coarseInter2_1d; + break; + case 2: + refineInter_fct = refineInter2_2d; + coarseRestr_fct = coarseRestr2_2d; + coarseInter_fct = coarseInter2_2d; + break; + case 3: + refineInter_fct = refineInter2_3d; + coarseRestr_fct = coarseRestr2_3d; + coarseInter_fct = coarseInter2_3d; + break; + default: ERROR_EXIT("invalid dim\n"); + } + break; + case 3: + switch(dim) { + case 1: + refineInter_fct = refineInter3_1d; + coarseRestr_fct = coarseRestr3_1d; + coarseInter_fct = coarseInter3_1d; + break; + case 2: + refineInter_fct = refineInter3_2d; + coarseRestr_fct = coarseRestr3_2d; + coarseInter_fct = coarseInter3_2d; + break; + case 3: + refineInter_fct = refineInter3_3d; + coarseRestr_fct = coarseRestr3_3d; + coarseInter_fct = coarseInter3_3d; + break; + default: ERROR_EXIT("invalid dim\n"); + } + break; + case 4: + switch(dim) { + case 1: + refineInter_fct = refineInter4_1d; + coarseRestr_fct = coarseRestr4_1d; + coarseInter_fct = coarseInter4_1d; + break; + case 2: + refineInter_fct = refineInter4_2d; + coarseRestr_fct = coarseRestr4_2d; + coarseInter_fct = coarseInter4_2d; + break; + case 3: + refineInter_fct = refineInter4_3d; + coarseRestr_fct = coarseRestr4_3d; + coarseInter_fct = coarseInter4_3d; + break; + default: ERROR_EXIT("invalid dim\n"); + } + break; + default: + ERROR_EXIT("invalid degree\n"); + } + } + + void Lagrange::setNDOF() + { + if(static_cast<int>( baryDimDegree[dim][degree].size()) == 0) { + ndofDimDegree[dim][degree] = NEW DimVec<int>(dim, DEFAULT_VALUE, 0); + + if (degree!=0) (*ndofDimDegree[dim][degree])[VERTEX] = 1; + else (*ndofDimDegree[dim][degree])[VERTEX] = 0; + + for(int i=1; i < dim+1; i++) { + nBasFcts = getNumberOfDOFs(i, degree); + (*ndofDimDegree[dim][degree])[INDEX_OF_DIM(i, dim)] = nBasFcts; + for(int j=0; j < i; j++) { + (*ndofDimDegree[dim][degree])[INDEX_OF_DIM(i, dim)] -= + Global::getGeo(INDEX_OF_DIM(j, dim), i) * + (*ndofDimDegree[dim][degree])[INDEX_OF_DIM(j, dim)]; + } + } + nBasFctsDimDegree[dim][degree] = nBasFcts; + } + nBasFcts = nBasFctsDimDegree[dim][degree]; + nDOF = ndofDimDegree[dim][degree]; + } + + DimVec<double> *Lagrange::getCoords(int i) const + { + return (*bary)[i]; + } + + void Lagrange::setVertices(int dim, int degree, + GeoIndex position, int positionIndex, int nodeIndex, + int** vertices) + { + TEST_EXIT((*vertices)==NULL)("vertices != NULL\n"); + int dimOfPosition = DIM_OF_INDEX(position, dim); + + *vertices = GET_MEMORY(int, dimOfPosition + 1); + + + if((degree == 4) && (dimOfPosition==1)) { + (*vertices)[(nodeIndex != 2) ? 0 : 1] = + Global::getReferenceElement(dim)->getVertexOfPosition(position, + positionIndex, + 0); + (*vertices)[(nodeIndex != 2) ? 1 : 0] = + Global::getReferenceElement(dim)->getVertexOfPosition(position, + positionIndex, + 1); + } else if ((degree==4) && (dimOfPosition==2)) { + for(int i=0; i < dimOfPosition + 1; i++) { + (*vertices)[(i+dimOfPosition*nodeIndex) % (dimOfPosition+1)] = + Global::getReferenceElement(dim)->getVertexOfPosition(position, + positionIndex, + i); + } + } else { + for(int i=0; i < dimOfPosition + 1; i++) { + (*vertices)[(i+nodeIndex) % (dimOfPosition+1)] = + Global::getReferenceElement(dim)->getVertexOfPosition(position, + positionIndex, + i); + } + } + } + + Lagrange::Phi::Phi(Lagrange* owner_, + GeoIndex position, + int positionIndex, + int nodeIndex) + : owner(owner_), vertices(NULL) + { + FUNCNAME("Lagrange::Phi::Phi") + // get relevant vertices + Lagrange::setVertices(owner->getDim(), + owner->getDegree(), + position, + positionIndex, + nodeIndex, + &vertices); + + // set function pointer + switch(owner->getDegree()) { + case 0: + switch(position) { + case CENTER: + func = phi0c; + break; + default: + ERROR_EXIT("invalid position\n"); + } + break; + case 1: + switch(position) { + case VERTEX: + func = phi1v; + break; + default: + ERROR_EXIT("invalid position\n"); + } + break; + case 2: + switch(position) { + case VERTEX: + func = phi2v; + break; + case EDGE: + TEST_EXIT(owner->getDim() > 1)("no edge in 1d\n"); + func = phi2e; + break; + case CENTER: + TEST_EXIT(owner->getDim() == 1)("no center dofs for dim != 1\n"); + func = phi2e; + break; + default: + ERROR_EXIT("invalid position\n"); + } + break; + case 3: + switch(position) { + case VERTEX: + func = phi3v; + break; + case EDGE: + func = phi3e; + break; + case FACE: + TEST_EXIT(owner->getDim() >= 3)("no faces in dim < 3\n"); + func = phi3f; + break; + case CENTER: + switch(owner->getDim()) { + case 1: + func = phi3e; + break; + case 2: + func = phi3f; + break; + default: + ERROR_EXIT("invalid dim\n"); + break; + } + break; + default: + ERROR_EXIT("invalid position\n"); + } + break; + case 4: + switch(position) { + case VERTEX: + func = phi4v; + break; + case EDGE: + if(nodeIndex == 1) + func = phi4e1; + else + func = phi4e0; + break; + case FACE: + TEST_EXIT(owner->getDim() >= 3)("no faces in dim < 3\n"); + func = phi4f; + break; + case CENTER: + switch(owner->getDim()) { + case 1: + if(nodeIndex == 1) + func = phi4e1; + else + func = phi4e0; + break; + case 2: + func = phi4f; + break; + case 3: + func = phi4c; + break; + default: + ERROR_EXIT("invalid dim\n"); + break; + } + break; + default: + ERROR_EXIT("invalid position\n"); + } + break; + default: + ERROR_EXIT("invalid degree\n"); + } + } + + Lagrange::Phi::~Phi() { DELETE [] vertices; } + + + Lagrange::GrdPhi::GrdPhi(Lagrange* owner_, + GeoIndex position, + int positionIndex, + int nodeIndex) + : owner(owner_), vertices(NULL) + { + // get relevant vertices + Lagrange::setVertices(owner->getDim(), + owner->getDegree(), + position, + positionIndex, + nodeIndex, + &vertices); + + // set function pointer + switch(owner->getDegree()) { + case 0: + switch(position) { + case CENTER: + func = grdPhi0c; + break; + default: + ERROR_EXIT("invalid position\n"); + } + break; + case 1: + switch(position) { + case VERTEX: + func = grdPhi1v; + break; + default: + ERROR_EXIT("invalid position\n"); + } + break; + case 2: + switch(position) { + case VERTEX: + func = grdPhi2v; + break; + case EDGE: + func = grdPhi2e; + break; + case CENTER: + TEST_EXIT(owner->getDim() == 1)("no center dofs for dim != 1\n"); + func = grdPhi2e; + break; + default: + ERROR_EXIT("invalid position\n"); + } + break; + case 3: + switch(position) { + case VERTEX: + func = grdPhi3v; + break; + case EDGE: + func = grdPhi3e; + break; + case FACE: + TEST_EXIT(owner->getDim() >= 3)("no faces in dim < 3\n"); + func = grdPhi3f; + break; + case CENTER: + switch(owner->getDim()) { + case 1: + func = grdPhi3e; + break; + case 2: + func = grdPhi3f; + break; + default: + ERROR_EXIT("invalid dim\n"); + break; + } + break; + default: + ERROR_EXIT("invalid position\n"); + } + break; + case 4: + switch(position) { + case VERTEX: + func = grdPhi4v; + break; + case EDGE: + if(nodeIndex == 1) + func = grdPhi4e1; + else + func = grdPhi4e0; + break; + case FACE: + TEST_EXIT(owner->getDim() >= 3)("no faces in dim < 3\n"); + func = grdPhi4f; + break; + case CENTER: + switch(owner->getDim()) { + case 1: + if(nodeIndex == 1) + func = grdPhi4e1; + else + func = grdPhi4e0; + break; + case 2: + func = grdPhi4f; + break; + case 3: + func = grdPhi4c; + break; + default: + ERROR_EXIT("invalid dim\n"); + break; + } + break; + default: + ERROR_EXIT("invalid position\n"); + } + break; + default: + ERROR_EXIT("invalid degree\n"); + } + } + + Lagrange::GrdPhi::~GrdPhi() { DELETE [] vertices; } + + Lagrange::D2Phi::D2Phi(Lagrange* owner_, + GeoIndex position, + int positionIndex, + int nodeIndex) + : owner(owner_), vertices(NULL) + { + // get relevant vertices + Lagrange::setVertices(owner->getDim(), + owner->getDegree(), + position, + positionIndex, + nodeIndex, + &vertices); + + // set function pointer + switch(owner->getDegree()) { + case 0: + switch(position) { + case CENTER: + func = D2Phi0c; + break; + default: + ERROR_EXIT("invalid position\n"); + } + break; + case 1: + switch(position) { + case VERTEX: + func = D2Phi1v; + break; + default: + ERROR_EXIT("invalid position\n"); + } + break; + case 2: + switch(position) { + case VERTEX: + func = D2Phi2v; + break; + case EDGE: + TEST_EXIT(owner->getDim() > 1)("no edge in 1d\n"); + func = D2Phi2e; + break; + case CENTER: + TEST_EXIT(owner->getDim() == 1)("no center dofs for dim != 1\n"); + func = D2Phi2e; + break; + default: + ERROR_EXIT("invalid position\n"); + } + break; + case 3: + switch(position) { + case VERTEX: + func = D2Phi3v; + break; + case EDGE: + func = D2Phi3e; + break; + case FACE: + TEST_EXIT(owner->getDim() >= 3)("no faces in dim < 3\n"); + func = D2Phi3f; + break; + case CENTER: + switch(owner->getDim()) { + case 1: + func = D2Phi3e; + break; + case 2: + func = D2Phi3f; + break; + default: + ERROR_EXIT("invalid dim\n"); + break; + } + break; + default: + ERROR_EXIT("invalid position\n"); + } + break; + case 4: + switch(position) { + case VERTEX: + func = D2Phi4v; + break; + case EDGE: + if(nodeIndex == 1) + func = D2Phi4e1; + else + func = D2Phi4e0; + break; + case FACE: + TEST_EXIT(owner->getDim() >= 3)("no faces in dim < 3\n"); + func = D2Phi4f; + break; + case CENTER: + switch(owner->getDim()) { + case 1: + if(nodeIndex == 1) + func = D2Phi4e1; + else + func = D2Phi4e0; + break; + case 2: + func = D2Phi4f; + break; + case 3: + func = D2Phi4c; + break; + default: + ERROR_EXIT("invalid dim\n"); + break; + } + break; + default: + ERROR_EXIT("invalid position\n"); + } + break; + default: + ERROR_EXIT("invalid degree\n"); + } + } + + Lagrange::D2Phi::~D2Phi() { DELETE [] vertices; } + + void Lagrange::createCoords(int* coordInd, + int numCoords, + int dimIndex, + int rest, + DimVec<double>* vec) + { + if(vec == NULL) vec = NEW DimVec<double>(dim, DEFAULT_VALUE, 0.0); + + if(dimIndex == numCoords-1) { + (*vec)[coordInd[dimIndex]] = double(rest)/degree; + DimVec<double>* newCoords = NEW DimVec<double>(*vec); + bary->push_back(newCoords); + } else { + for(int i=rest-1; i >= 1; i--) { + (*vec)[coordInd[dimIndex]] = double(i) / degree; + createCoords(coordInd, numCoords, dimIndex+1, rest-i, vec); + } + } + } + + void Lagrange::setBary() + { + bary = &baryDimDegree[dim][degree]; + if(static_cast<int>( bary->size()) == 0) { + for(int i=0; i <= dim; i++) { // for all positions + int partsAtPos = Global::getGeo(INDEX_OF_DIM(i, dim), dim); + for(int j=0; j < partsAtPos; j++) { // for all vertices/edges/faces/... + int *coordInd = GET_MEMORY(int, i+1); // indices of relevant coords + for(int k=0; k < i+1; k++) { + coordInd[k] = Global::getReferenceElement(dim)-> + getVertexOfPosition(INDEX_OF_DIM(i,dim), j, k); + } + createCoords(coordInd, i+1, 0, degree); + FREE_MEMORY(coordInd, int, i+1); + if(static_cast<int>( bary->size()) == nBasFcts) return; + } + } + } + } + + int Lagrange::getNumberOfDOFs(int dim, int degree) + { + int result = 0; + for(int i=0; i <= degree; i++) { + result += fac(dim-1+i)/(fac(i) * fac(dim-1)); + } + return result; + } + + + const DegreeOfFreedom *Lagrange::getDOFIndices(const Element *el, + const DOFAdmin& admin, + DegreeOfFreedom *idof) const + { + WARNING("depricated: use getLocalIndices() instead\n"); + return getLocalIndices(el, &admin, idof); + + + + + static DegreeOfFreedom* index_vec = NULL; + static int size_of_index_vec = 0; + static const Element *lastElement = NULL; + static const DOFAdmin *lastAdmin = NULL; + DegreeOfFreedom* result; + int* indi; + + // set result pointer + if(idof) { + result = idof; + } else { + if((el == lastElement) && (&admin == lastAdmin)) { + return index_vec; + } else { + lastElement = el; + lastAdmin = &admin; + } + // realloc memory if neccessary + if(size_of_index_vec < nBasFcts) { + if(index_vec) FREE_MEMORY(index_vec, DegreeOfFreedom, size_of_index_vec); + index_vec = GET_MEMORY(DegreeOfFreedom, nBasFcts); + size_of_index_vec = nBasFcts; + } + result = index_vec; + } + + + + int firstNode; + GeoIndex position; + int n0; + int counter = 0; + + // for all positions + for(int i=0; i < dim+1; i++) { + position = INDEX_OF_DIM(i,dim); + // index of first vertex/edge/... + firstNode = admin.getMesh()->getNode(position); + // number of pre dofs at position + n0 = admin.getNumberOfPreDOFs(position); + // number of vertices/edges/... + int number = Global::getGeo(position, dim); + // for all vertices/edges/... + for(int j=0; j < number; j++) { + if((*nDOF)[position] > 0) { + indi = orderOfPositionIndices(el, INDEX_OF_DIM(i, dim), j); + // for all dofs + for(int k=0; k < (*nDOF)[position]; k++) { + TEST_EXIT(indi)("indi == NULL\n"); + result[counter++] = el->getDOF(firstNode + j, n0 + indi[k]); + } + } + } + } + + return result; + } + + int* Lagrange::orderOfPositionIndices(const Element* el, + GeoIndex position, + int positionIndex) const + { + static int sortedVertex = 0; + static int sortedEdgeDeg2 = 0; + static int sortedEdgeDeg3[2][2] = {{0, 1}, {1, 0}}; + static int sortedEdgeDeg4[2][3] = {{0, 1, 2}, {2, 1, 0}}; + static int sortedFaceDeg3 = 0; + static int sortedFaceDeg4[7][3] = {{0,0,0}, {0,2,1}, {1,0,2}, {0,1,2}, + {2,1,0}, {1,2,0}, {2,0,1}}; + static int sortedCenterDeg4 = 0; + + int dimOfPosition = DIM_OF_INDEX(position, dim); + + // vertex + if(dimOfPosition == 0) { + return &sortedVertex; + } + + // edge + if((dimOfPosition == 1) && (degree == 2)) { + return &sortedEdgeDeg2; + } + + int vertex[3]; + int** dof = const_cast<int**>( el->getDOF()); + int verticesOfPosition = dimOfPosition + 1; + + for(int i=0; i < verticesOfPosition; i++) { + vertex[i] = Global::getReferenceElement(dim)-> + getVertexOfPosition(position, positionIndex, i); + } + + if(dimOfPosition == 1) { + if(degree == 3) { + if(dof[vertex[0]][0] < dof[vertex[1]][0]) { + return sortedEdgeDeg3[0]; + } else { + return sortedEdgeDeg3[1]; + } + } else { // degree == 4 + if(dof[vertex[0]][0] < dof[vertex[1]][0]) { + return sortedEdgeDeg4[0]; + } else { + return sortedEdgeDeg4[1]; + } + } + } + + // face + if(dimOfPosition == 2) { + if(degree == 3) { + return &sortedFaceDeg3; + } else { // degree == 4! + int no = 0; + const Element *refElem = Global::getReferenceElement(dim); + + if (dof[refElem->getVertexOfPosition(position, positionIndex, 0)][0] < + dof[refElem->getVertexOfPosition(position, positionIndex, 1)][0]) + no++; + + if (dof[refElem->getVertexOfPosition(position, positionIndex, 1)][0] < + dof[refElem->getVertexOfPosition(position, positionIndex, 2)][0]) + no += 2; + + if (dof[refElem->getVertexOfPosition(position, positionIndex, 2)][0] < + dof[refElem->getVertexOfPosition(position, positionIndex, 0)][0]) + no += 4; + + return sortedFaceDeg4[no]; + } + } + + // center + if(dimOfPosition == 3) { + if(degree == 4) { + return &sortedCenterDeg4; + } + } + + ERROR_EXIT("should not be reached\n"); + return NULL; + } + + const BoundaryType* Lagrange::getBound(const ElInfo* el_info, + BoundaryType* bound) const + { + static BoundaryType *bound_vec = NULL; + static int bound_vec_size = 0; + + int i,j,k; + + // realloc memory if neccessary + if(bound_vec_size < nBasFcts) { + if(bound_vec) FREE_MEMORY(bound_vec, BoundaryType, bound_vec_size); + bound_vec = GET_MEMORY(BoundaryType, nBasFcts); + bound_vec_size = nBasFcts; + } + + BoundaryType *result = bound ? bound : bound_vec; + + el_info->testFlag(Mesh::FILL_BOUND); + + DimVec<int> parts(dim, NO_INIT); + for(i=0; i < dim+1; i++) + parts[i] = Global::getGeo(INDEX_OF_DIM(i, dim),dim); + + int index = 0; + + // // vertex bounds + // for(i=0; i < parts[0]; i++) { + // result[index++] = el_info->getBound(i); + // } + + // boundaries + int offset = 0; + BoundaryType boundaryType; + for(i= dim-1; i > 0; i--) + offset += parts[i]; + + for(i = 0; i < dim; i++) { + for(j = offset; j < offset + parts[i]; j++) { + boundaryType = el_info->getBoundary(j); + for(k=0; k < (*nDOF)[INDEX_OF_DIM(i, dim)]; k++) { + result[index++] = boundaryType; + } + } + offset -= parts[i+1]; + } + + // interior nodes in the center + for(i=0; i < (*nDOF)[CENTER]; i++) { + result[index++] = INTERIOR; + } + + TEST_EXIT(index == nBasFcts)("found not enough boundarys\n"); + + return result; + } + + + const double* Lagrange::interpol(const ElInfo *el_info, + int no, const int *b_no, + AbstractFunction<double, WorldVector<double> > *f, + double *vec) + { + FUNCNAME("Lagrange::interpol"); + static double *inter = NULL; + static int inter_size = 0; + + double *rvec = NULL; + + if(vec) { + rvec = vec; + } else { + if(inter) FREE_MEMORY(inter, double, nBasFcts); + inter = GET_MEMORY(double, nBasFcts); + inter_size = nBasFcts; + rvec = inter; + } + + WorldVector<double> x; + int i; + + el_info->testFlag(Mesh::FILL_COORDS); + + + if (b_no) + { + if (no <= 0 || no > getNumber()) + { + ERROR("something is wrong, doing nothing\n"); + rvec[0] = 0.0; + return(const_cast<const double *>( rvec)); + } + for (i = 0; i < no; i++) + { + if (b_no[i] < Global::getGeo(VERTEX, dim)) + { + rvec[i] = (*f)(el_info->getCoord(b_no[i])); + } + else + { + el_info->coordToWorld(*(*bary)[b_no[i]], &x); + rvec[i] = (*f)(x); + } + } + } + else + { + int vertices = Global::getGeo(VERTEX, dim); + for (i = 0; i < vertices; i++) + rvec[i] = (*f)(el_info->getCoord(i)); + for (i = vertices; i < nBasFcts; i++) + { + el_info->coordToWorld(*(*bary)[i], &x); + rvec[i] = (*f)(x); + } + } + + return(const_cast<const double *>( rvec)); + } + + const WorldVector<double>* + Lagrange::interpol(const ElInfo *el_info, int no, + const int *b_no, + AbstractFunction<WorldVector<double>, WorldVector<double> > *f, + WorldVector<double> *vec) + { + FUNCNAME("*Lagrange::interpol_d"); + static WorldVector<double> *inter; + WorldVector<double> *rvec = + vec ? vec : (inter?inter:inter= NEW WorldVector<double>[getNumber()]); + WorldVector<double> x; + int i; + + el_info->testFlag(Mesh::FILL_COORDS); + + int dow = Global::getGeo(WORLD); + int vertices = Global::getGeo(VERTEX, dim); + + if (b_no) + { + if (no <= 0 || no > getNumber()) + { + ERROR("something is wrong, doing nothing\n"); + for (i = 0; i < dow; i++) + rvec[0][i] = 0.0; + return(const_cast<const WorldVector<double> *>( rvec)); + } + for (i = 0; i < no; i++) + { + if (b_no[i] < Global::getGeo(VERTEX, dim)) + { + rvec[i] = (*f)(el_info->getCoord(b_no[i])); + } + else + { + el_info->coordToWorld(*(*bary)[b_no[i]], &x); + rvec[i] = (*f)(x); + } + } + } + else + { + for (i = 0; i < vertices; i++) + rvec[i] = (*f)(el_info->getCoord(i)); + for (i = vertices; i < nBasFcts; i++) + { + el_info->coordToWorld(*(*bary)[i], &x); + rvec[i] = (*f)(x); + } + } + + return(const_cast<const WorldVector<double> *>( rvec)); + } + + + const DegreeOfFreedom *Lagrange::getLocalIndices(const Element* el, + const DOFAdmin *admin, + DegreeOfFreedom *indices) const + { + static DegreeOfFreedom *localVec = NULL; + static int localVecSize = 0; + + const DegreeOfFreedom **dof = el->getDOF(); + const int *indi; + int pos, i, j, k, nrDOFs, n0, node0, num = 0; + GeoIndex posIndex; + + DegreeOfFreedom* result; + + if(indices) { + result = indices; + } else { + if(localVec) FREE_MEMORY(localVec, DegreeOfFreedom, localVecSize); + localVec = GET_MEMORY(DegreeOfFreedom, nBasFcts); + localVecSize = nBasFcts; + result = localVec; + } + + for(pos=0, j=0; pos <= dim; pos++) { + posIndex = INDEX_OF_DIM(pos, dim); + n0 = admin->getNumberOfPreDOFs(posIndex); + node0 = admin->getMesh()->getNode(posIndex); + num = Global::getGeo(posIndex, dim); + nrDOFs = admin->getNumberOfDOFs(posIndex); + + for (i = 0; i < num; node0++, i++) { + if(nrDOFs) { + indi = orderOfPositionIndices(el, posIndex, i); + + for (k = 0; k < nrDOFs; k++) + result[j++] = dof[node0][n0+indi[k]]; + } + } + } + + return result; + } + + // const double* Lagrange::getVec(const Element* el, const DOFVector<double> * dv, + // double * d) const + // { + // static double* localVec = NULL; + // const DOFAdmin* admin = dv->getFESpace()->getAdmin(); + + // int i; + + // double* result; + + // if(d) { + // result = d; + // } else { + // if(localVec) FREE_MEMORY(localVec, double, nBasFcts); + // localVec = GET_MEMORY(double, nBasFcts); + // result = localVec; + // } + + // const DegreeOfFreedom *localIndices = getLocalIndices(el, admin, NULL); + + // for(i = 0; i < nBasFcts; i++) { + // result[i] = (*dv)[localIndices[i]]; + // } + + // return result; + // } + + void Lagrange::l2ScpFctBas(Quadrature *q, + AbstractFunction<WorldVector<double>, WorldVector<double> >* f, + DOFVector<WorldVector<double> >* fh) + { + ERROR_EXIT("not yet\n"); + } + + void Lagrange::l2ScpFctBas(Quadrature *q, + AbstractFunction<double, WorldVector<double> >* f, + DOFVector<double>* fh) + { + FUNCNAME("Lagrange::l2ScpFctBas"); + TraverseStack stack; + ElInfo *el_info; + const FastQuadrature *quad_fast; + double *wdetf_qp = NULL; + double val, det; + WorldVector<double> x; + int iq, j, n_phi; + const DegreeOfFreedom *dof; + const Parametric *parametric; + + TEST_EXIT(fh)("no DOF_REAL_VEC fh\n"); + TEST_EXIT(fh->getFESpace())("no fe_space in DOF_REAL_VEC %s\n", + fh->getName().c_str()); + TEST_EXIT(fh->getFESpace()->getBasisFcts() == this)("wrong basis fcts for fh\n"); + + Mesh* mesh = fh->getFESpace()->getMesh(); + + n_phi = nBasFcts; + + if (!q) + q = Quadrature::provideQuadrature(dim, 2*degree-2); + quad_fast = FastQuadrature::provideFastQuadrature(this, *q, INIT_PHI); + + if ((parametric = mesh->getParametric())) + { + ERROR_EXIT("not yet implemented\n"); + } + else + { + wdetf_qp = GET_MEMORY(double, q->getNumPoints()); + } + + el_info = stack.traverseFirst(mesh, -1, Mesh::CALL_LEAF_EL | Mesh::FILL_COORDS); + + int numPoints = q->getNumPoints(); + + while(el_info) + { + dof = getLocalIndices(el_info->getElement(), (fh->getFESpace()->getAdmin()), NULL); + + // if (parametric && parametric->initElement(el_info)) + // { + // ERROR_EXIT("not yet implemented\n"); + // } + // else + // { + det = el_info->getDet(); + + for (iq = 0; iq < numPoints; iq++) { + el_info->coordToWorld(q->getLambda(iq), &x); + wdetf_qp[iq] = q->getWeight(iq)*det*((*f)(x)); + } + // } + + for (j = 0; j < n_phi; j++) + { + + for (val = iq = 0; iq < numPoints; iq++) + val += quad_fast->getPhi(iq,j)*wdetf_qp[iq]; + (*fh)[dof[j]] += val; + } + + el_info = stack.traverseNext(el_info); + } + + FREE_MEMORY(wdetf_qp, double, q->getNumPoints()); + + return; + } + + + // ===== refineInter functions ===== + + void Lagrange::refineInter0(DOFIndexed<double> *drv, RCNeighbourList* list, int n, BasisFunction* basFct) + { + FUNCNAME("Lagrange::refineInter0"); + Element *el; + DegreeOfFreedom dof_new, dof0; + int n0; + int node; + + //int dim = drv->getFESpace()->getMesh()->getDim(); + + if (n < 1) return; + n0 = drv->getFESpace()->getAdmin()->getNumberOfPreDOFs(CENTER); + el = list->getElement(0); + node=drv->getFESpace()->getMesh()->getNode(CENTER); + dof0 = el->getDOF(node, n0); /* Parent center */ + dof_new = el->getChild(0)->getDOF(node, n0); /* newest vertex is center */ + (*drv)[dof_new] = (*drv)[dof0]; + dof_new = el->getChild(1)->getDOF(node, n0); /* newest vertex is center */ + (*drv)[dof_new] = (*drv)[dof0]; + } + + void Lagrange::refineInter1(DOFIndexed<double> *drv, RCNeighbourList* list, int n, BasisFunction* basFct) + { + FUNCNAME("Lagrange::refineInter1_1d"); + Element *el; + DegreeOfFreedom dof_new, dof0, dof1; + int n0; + + int dim = drv->getFESpace()->getMesh()->getDim(); + + if (n < 1) return; + n0 = drv->getFESpace()->getAdmin()->getNumberOfPreDOFs(VERTEX); + el = list->getElement(0); + dof0 = el->getDOF(0, n0); /* 1st endpoint of refinement edge */ + dof1 = el->getDOF(1, n0); /* 2nd endpoint of refinement edge */ + dof_new = el->getChild(0)->getDOF(dim, n0); /* newest vertex is DIM */ + (*drv)[dof_new] = 0.5*((*drv)[dof0] + (*drv)[dof1]); + } + + void Lagrange::refineInter2_1d(DOFIndexed<double> *drv, RCNeighbourList* list, int n, BasisFunction* basFct) + { + FUNCNAME("Lagrange::refineInter2_1d"); + Element *el; + int node, n0; + DegreeOfFreedom cdof; + const DegreeOfFreedom *pdof; + const DOFAdmin *admin; + + if (n < 1) return; + el = list->getElement(0); + + admin = drv->getFESpace()->getAdmin(); + + pdof = basFct->getLocalIndices(el, admin, NULL); + + node = drv->getFESpace()->getMesh()->getNode(VERTEX); + n0 = admin->getNumberOfPreDOFs(VERTEX); + + /****************************************************************************/ + /* newest vertex of child[0] and child[1] */ + /****************************************************************************/ + + cdof = el->getChild(0)->getDOF(node+1, n0); /* newest vertex is DIM */ + (*drv)[cdof] = (*drv)[pdof[2]]; + + node = drv->getFESpace()->getMesh()->getNode(CENTER); + n0 = admin->getNumberOfPreDOFs(CENTER); + + /****************************************************************************/ + /* midpoint of edge on child[0] at the refinement edge */ + /****************************************************************************/ + + cdof = el->getChild(0)->getDOF(node, n0); + (*drv)[cdof] = + 0.375*(*drv)[pdof[0]] - 0.125*(*drv)[pdof[1]] + 0.75*(*drv)[pdof[2]]; + + /****************************************************************************/ + /* midpoint of edge on child[1] at the refinement edge */ + /****************************************************************************/ + + cdof = el->getChild(1)->getDOF(node, n0); + (*drv)[cdof] = + -0.125*(*drv)[pdof[0]] + 0.375*(*drv)[pdof[1]] + 0.75*(*drv)[pdof[2]]; + return; + } + + void Lagrange::refineInter2_2d(DOFIndexed<double> *drv, + RCNeighbourList* list, + int n, BasisFunction* basFct) + { + FUNCNAME("Lagrange::refineInter2_2d"); + + if (n < 1) return; + + Element *el; + int node, n0; + DegreeOfFreedom cdof; + const DegreeOfFreedom *pdof; + const DOFAdmin *admin = drv->getFESpace()->getAdmin(); + + el = list->getElement(0); + + pdof = basFct->getLocalIndices(el, admin, NULL); + + node = drv->getFESpace()->getMesh()->getNode(VERTEX); + n0 = admin->getNumberOfPreDOFs(VERTEX); + + /****************************************************************************/ + /* newest vertex of child[0] and child[1] */ + /****************************************************************************/ + + cdof = el->getChild(0)->getDOF(node+2, n0); /* newest vertex is DIM */ + (*drv)[cdof] = (*drv)[pdof[5]]; + + node = drv->getFESpace()->getMesh()->getNode(EDGE); + n0 = admin->getNumberOfPreDOFs(EDGE); + + /****************************************************************************/ + /* midpoint of edge on child[0] at the refinement edge */ + /****************************************************************************/ + + cdof = el->getChild(0)->getDOF(node, n0); + (*drv)[cdof] = + 0.375*(*drv)[pdof[0]] - 0.125*(*drv)[pdof[1]] + 0.75*(*drv)[pdof[5]]; + + /****************************************************************************/ + /* node in the common edge of child[0] and child[1] */ + /****************************************************************************/ + + cdof = el->getChild(0)->getDOF(node+1, n0); + (*drv)[cdof] = + -0.125*((*drv)[pdof[0]] + (*drv)[pdof[1]]) + 0.25*(*drv)[pdof[5]] + + 0.5*((*drv)[pdof[3]] + (*drv)[pdof[4]]); + + /****************************************************************************/ + /* midpoint of edge on child[1] at the refinement edge */ + /****************************************************************************/ + + cdof = el->getChild(1)->getDOF(node+1, n0); + (*drv)[cdof] = + -0.125*(*drv)[pdof[0]] + 0.375*(*drv)[pdof[1]] + 0.75*(*drv)[pdof[5]]; + + if (n > 1) + { + /****************************************************************************/ + /* adjust the value at the midpoint of the common edge of neigh's children */ + /****************************************************************************/ + el = list->getElement(1); + pdof = basFct->getLocalIndices(el, admin, NULL); + + cdof = el->getChild(0)->getDOF(node+1, n0); + (*drv)[cdof] = + -0.125*((*drv)[pdof[0]] + (*drv)[pdof[1]]) + 0.25*(*drv)[pdof[5]] + + 0.5*((*drv)[pdof[3]] + (*drv)[pdof[4]]); + } + return; + } + + void Lagrange::refineInter2_3d(DOFIndexed<double> *drv, + RCNeighbourList* list, + int n, BasisFunction* basFct) + { + FUNCNAME("Lagrange::refineInter2_3d"); + Element *el; + const DegreeOfFreedom *cdof; + DegreeOfFreedom pdof[10], cdofi; + int i, lr_set; + int node0, n0; + const DOFAdmin *admin; + + if (n < 1) return; + + el = list->getElement(0); + + admin = drv->getFESpace()->getAdmin(); + + basFct->getLocalIndices(el, admin, pdof); + + node0 = drv->getFESpace()->getMesh()->getNode(EDGE); + n0 = admin->getNumberOfPreDOFs(EDGE); + + /****************************************************************************/ + /* values on child[0] */ + /****************************************************************************/ + + cdof = basFct->getLocalIndices(el->getChild(0), admin, NULL); + + (*drv)[cdof[3]] = ((*drv)[pdof[4]]); + (*drv)[cdof[6]] = + (0.375*(*drv)[pdof[0]] - 0.125*(*drv)[pdof[1]] + + 0.75*(*drv)[pdof[4]]); + (*drv)[cdof[8]] = + (0.125*(-(*drv)[pdof[0]] - (*drv)[pdof[1]]) + 0.25*(*drv)[pdof[4]] + + 0.5*((*drv)[pdof[5]] + (*drv)[pdof[7]])); + (*drv)[cdof[9]] = + (0.125*(-(*drv)[pdof[0]] - (*drv)[pdof[1]]) + 0.25*(*drv)[pdof[4]] + + 0.5*((*drv)[pdof[6]] + (*drv)[pdof[8]])); + + /****************************************************************************/ + /* values on child[1] */ + /****************************************************************************/ + + cdofi = el->getChild(1)->getDOF(node0+2, n0); + (*drv)[cdofi] = + (-0.125*(*drv)[pdof[0]] + 0.375*(*drv)[pdof[1]] + + 0.75*(*drv)[pdof[4]]); + + /****************************************************************************/ + /* adjust neighbour values */ + /****************************************************************************/ + + for (i = 1; i < n; i++) + { + el = list->getElement(i); + basFct->getLocalIndices(el, admin, pdof); + + lr_set = 0; + if (list->getNeighbourElement(i, 0) && list->getNeighbourNr(i, 0) < i) + lr_set = 1; + + if (list->getNeighbourElement(i, 1) && list->getNeighbourNr(i, 1) < i) + lr_set += 2; + + TEST_EXIT(lr_set)("no values set on both neighbours\n"); + + /****************************************************************************/ + /* values on child[0] */ + /****************************************************************************/ + + switch (lr_set) + { + case 1: + cdofi = el->getChild(0)->getDOF(node0+4, n0); + (*drv)[cdofi] = + (0.125*(-(*drv)[pdof[0]] - (*drv)[pdof[1]]) + 0.25*(*drv)[pdof[4]] + + 0.5*((*drv)[pdof[5]] + (*drv)[pdof[7]])); + break; + case 2: + cdofi = el->getChild(0)->getDOF(node0+5, n0); + (*drv)[cdofi] = + (0.125*(-(*drv)[pdof[0]] - (*drv)[pdof[1]]) + 0.25*(*drv)[pdof[4]] + + 0.5*((*drv)[pdof[6]] + (*drv)[pdof[8]])); + } + } + return; + } + + void Lagrange::refineInter3_1d(DOFIndexed<double> *drv, + RCNeighbourList* list, + int n, BasisFunction* basFct) + { + FUNCNAME("Lagrange::refineInter3_1d"); + + if (n < 1) return; + + Element *el; + int dof9, node, n0; + const DegreeOfFreedom *cdof; + DegreeOfFreedom *pdof = GET_MEMORY(DegreeOfFreedom, basFct->getNumber()); + const DOFAdmin *admin; + + el = list->getElement(0); + + admin = drv->getFESpace()->getAdmin(); + + basFct->getLocalIndices(el, admin, pdof); + + /****************************************************************************/ + /* values on child[0] */ + /****************************************************************************/ + cdof = basFct->getLocalIndices(el->getChild(0), admin, NULL); + + (*drv)[cdof[2]] = + (-0.0625*((*drv)[pdof[0]] + (*drv)[pdof[1]]) + + 0.5625*((*drv)[pdof[7]] + (*drv)[pdof[8]])); + (*drv)[cdof[3]] = + (0.3125*((*drv)[pdof[0]] - (*drv)[pdof[8]]) + 0.0625*(*drv)[pdof[1]] + + 0.9375*(*drv)[pdof[7]]); + (*drv)[cdof[4]] = (*drv)[pdof[7]]; + (*drv)[cdof[5]] = (*drv)[pdof[9]]; + (*drv)[cdof[6]] = + (0.0625*((*drv)[pdof[0]] + (*drv)[pdof[1]]) + - 0.25*((*drv)[pdof[3]] + (*drv)[pdof[6]]) + + 0.5*((*drv)[pdof[4]] + (*drv)[pdof[5]] + (*drv)[pdof[9]]) + - 0.0625*((*drv)[pdof[7]] + (*drv)[pdof[8]])); + (*drv)[cdof[9]] = + (0.0625*(-(*drv)[pdof[0]] + (*drv)[pdof[1]]) - 0.125*(*drv)[pdof[3]] + + 0.375*(*drv)[pdof[6]] + 0.1875*((*drv)[pdof[7]] - (*drv)[pdof[8]]) + + 0.75*(*drv)[pdof[9]]); + + /****************************************************************************/ + /* values on child[1] */ + /****************************************************************************/ + + cdof = basFct->getLocalIndices(el->getChild(1), admin, NULL); + + (*drv)[cdof[5]] = (*drv)[pdof[8]]; + (*drv)[cdof[6]] = + (0.0625*(*drv)[pdof[0]] + 0.9375*(*drv)[pdof[8]] + + 0.3125*((*drv)[pdof[1]] - (*drv)[pdof[7]])); + (*drv)[cdof[9]] = + (0.0625*((*drv)[pdof[0]] - (*drv)[pdof[1]]) + 0.375*(*drv)[pdof[3]] + - 0.125*(*drv)[pdof[6]] + 0.1875*(-(*drv)[pdof[7]] + (*drv)[pdof[8]]) + + 0.75*(*drv)[pdof[9]]); + + if (n <= 1) { + FREE_MEMORY(pdof, DegreeOfFreedom, basFct->getNumber()); + return; + } + /****************************************************************************/ + /* adjust the value on the neihgbour */ + /****************************************************************************/ + + el = list->getElement(1); + basFct->getLocalIndices(el, admin, pdof); + + /****************************************************************************/ + /* values on neigh's child[0] */ + /****************************************************************************/ + cdof = basFct->getLocalIndices(el->getChild(0), admin, NULL); + + (*drv)[cdof[5]] = (*drv)[pdof[9]]; + (*drv)[cdof[6]] = + (0.0625*((*drv)[pdof[0]] + (*drv)[pdof[1]]) + - 0.25*((*drv)[pdof[3]] + (*drv)[pdof[6]]) + + 0.5*((*drv)[pdof[4]] + (*drv)[pdof[5]] + (*drv)[pdof[9]]) + - 0.0625*((*drv)[pdof[7]] + (*drv)[pdof[8]])); + (*drv)[cdof[9]] = + (0.0625*(-(*drv)[pdof[0]] + (*drv)[pdof[1]]) - 0.12500*(*drv)[pdof[3]] + + 0.375*(*drv)[pdof[6]] + 0.1875*((*drv)[pdof[7]] - (*drv)[pdof[8]]) + + 0.75*(*drv)[pdof[9]]); + /****************************************************************************/ + /* (*drv)alues on neigh's child[0] */ + /****************************************************************************/ + + node = drv->getFESpace()->getMesh()->getNode(CENTER); + n0 = admin->getNumberOfPreDOFs(CENTER); + dof9 = el->getChild(1)->getDOF(node, n0); + + (*drv)[dof9] = + (0.0625*((*drv)[pdof[0]] - (*drv)[pdof[1]]) + 0.375*(*drv)[pdof[3]] + - 0.125*(*drv)[pdof[6]] + 0.1875*(-(*drv)[pdof[7]] + (*drv)[pdof[8]]) + + 0.75*(*drv)[pdof[9]]); + + FREE_MEMORY(pdof, DegreeOfFreedom, basFct->getNumber()); + return; + } + + void Lagrange::refineInter3_2d(DOFIndexed<double> *drv, + RCNeighbourList* list, + int n, + BasisFunction* basFct) + { + FUNCNAME("Lagrange::refineInter3_2d"); + Element *el; + int dof9, node, n0; + const DegreeOfFreedom *cdof; + DegreeOfFreedom pdof[10]; + const DOFAdmin *admin; + + if (n < 1) return; + el = list->getElement(0); + + admin = drv->getFESpace()->getAdmin(); + + basFct->getLocalIndices(el, admin, pdof); + + /****************************************************************************/ + /* values on child[0] */ + /****************************************************************************/ + cdof = basFct->getLocalIndices(el->getChild(0), admin, NULL); + + (*drv)[cdof[2]] = + (-0.0625*((*drv)[pdof[0]] + (*drv)[pdof[1]]) + + 0.5625*((*drv)[pdof[7]] + (*drv)[pdof[8]])); + (*drv)[cdof[3]] = + (0.3125*((*drv)[pdof[0]] - (*drv)[pdof[8]]) + 0.0625*(*drv)[pdof[1]] + + 0.9375*(*drv)[pdof[7]]); + (*drv)[cdof[4]] = (*drv)[pdof[7]]; + (*drv)[cdof[5]] = (*drv)[pdof[9]]; + (*drv)[cdof[6]] = + (0.0625*((*drv)[pdof[0]] + (*drv)[pdof[1]]) + - 0.25*((*drv)[pdof[3]] + (*drv)[pdof[6]]) + + 0.5*((*drv)[pdof[4]] + (*drv)[pdof[5]] + (*drv)[pdof[9]]) + - 0.0625*((*drv)[pdof[7]] + (*drv)[pdof[8]])); + (*drv)[cdof[9]] = + (0.0625*(-(*drv)[pdof[0]] + (*drv)[pdof[1]]) - 0.125*(*drv)[pdof[3]] + + 0.375*(*drv)[pdof[6]] + 0.1875*((*drv)[pdof[7]] - (*drv)[pdof[8]]) + + 0.75*(*drv)[pdof[9]]); + + /****************************************************************************/ + /* values on child[0] */ + /****************************************************************************/ + + cdof = basFct->getLocalIndices(el->getChild(1), admin, NULL); + + (*drv)[cdof[5]] = (*drv)[pdof[8]]; + (*drv)[cdof[6]] = + (0.0625*(*drv)[pdof[0]] + 0.9375*(*drv)[pdof[8]] + + 0.3125*((*drv)[pdof[1]] - (*drv)[pdof[7]])); + (*drv)[cdof[9]] = + (0.0625*((*drv)[pdof[0]] - (*drv)[pdof[1]]) + 0.375*(*drv)[pdof[3]] + - 0.125*(*drv)[pdof[6]] + 0.1875*(-(*drv)[pdof[7]] + (*drv)[pdof[8]]) + + 0.75*(*drv)[pdof[9]]); + + if (n <= 1) return; + + /****************************************************************************/ + /* adjust the value on the neihgbour */ + /****************************************************************************/ + + el = list->getElement(1); + basFct->getLocalIndices(el, admin, pdof); + + /****************************************************************************/ + /* values on neigh's child[0] */ + /****************************************************************************/ + cdof = basFct->getLocalIndices(el->getChild(0), admin, NULL); + + (*drv)[cdof[5]] = (*drv)[pdof[9]]; + (*drv)[cdof[6]] = + (0.0625*((*drv)[pdof[0]] + (*drv)[pdof[1]]) + - 0.25*((*drv)[pdof[3]] + (*drv)[pdof[6]]) + + 0.5*((*drv)[pdof[4]] + (*drv)[pdof[5]] + (*drv)[pdof[9]]) + - 0.0625*((*drv)[pdof[7]] + (*drv)[pdof[8]])); + (*drv)[cdof[9]] = + (0.0625*(-(*drv)[pdof[0]] + (*drv)[pdof[1]]) - 0.12500*(*drv)[pdof[3]] + + 0.375*(*drv)[pdof[6]] + 0.1875*((*drv)[pdof[7]] - (*drv)[pdof[8]]) + + 0.75*(*drv)[pdof[9]]); + /****************************************************************************/ + /* values on neigh's child[0] */ + /****************************************************************************/ + + node = drv->getFESpace()->getMesh()->getNode(CENTER); + n0 = admin->getNumberOfPreDOFs(CENTER); + dof9 = el->getChild(1)->getDOF(node, n0); + + (*drv)[dof9] = + (0.0625*((*drv)[pdof[0]] - (*drv)[pdof[1]]) + 0.375*(*drv)[pdof[3]] + - 0.125*(*drv)[pdof[6]] + 0.1875*(-(*drv)[pdof[7]] + (*drv)[pdof[8]]) + + 0.75*(*drv)[pdof[9]]); + + return; + } + + void Lagrange::refineInter3_3d(DOFIndexed<double> *drv, + RCNeighbourList* list, + int n, BasisFunction* basFct) + { + FUNCNAME("Lagrange::refineInter3_3d"); + Element *el; + const DegreeOfFreedom *cd; + DegreeOfFreedom pd[20], cdi; + int i, typ, lr_set, node0, n0; + const DOFAdmin *admin; + + if (n < 1) return; + el = list->getElement(0); + typ = list->getType(0); + + admin = drv->getFESpace()->getAdmin(); + + basFct->getLocalIndices(el, admin, pd); + + /****************************************************************************/ + /* values on child[0] */ + /****************************************************************************/ + + cd = basFct->getLocalIndices(el->getChild(0), admin, NULL); + + (*drv)[cd[3]] = + (0.0625*(-(*drv)[pd[0]] - (*drv)[pd[1]]) + + 0.5625*((*drv)[pd[4]] + (*drv)[pd[5]])); + (*drv)[cd[8]] = + (0.3125*((*drv)[pd[0]] - (*drv)[pd[5]]) + 0.0625*(*drv)[pd[1]] + + 0.937500*(*drv)[pd[4]]); + (*drv)[cd[9]] = (*drv)[pd[4]]; + (*drv)[cd[12]] = + (0.0625*((*drv)[pd[0]] + (*drv)[pd[1]] - (*drv)[pd[4]] - (*drv)[pd[5]]) + + 0.25*(-(*drv)[pd[6]] - (*drv)[pd[10]]) + + 0.5*((*drv)[pd[7]] + (*drv)[pd[11]] + (*drv)[pd[19]])); + (*drv)[cd[13]] = (*drv)[pd[19]]; + (*drv)[cd[14]] = + (0.0625*((*drv)[pd[0]] + (*drv)[pd[1]] - (*drv)[pd[4]] - (*drv)[pd[5]]) + + 0.25*(-(*drv)[pd[8]] - (*drv)[pd[12]]) + + 0.5*((*drv)[pd[9]] + (*drv)[pd[13]] + (*drv)[pd[18]])); + (*drv)[cd[15]] = ((*drv)[pd[18]]); + (*drv)[cd[16]] = + (0.0625*((*drv)[pd[0]] + (*drv)[pd[1]] - (*drv)[pd[4]] - (*drv)[pd[5]]) + + 0.125*(-(*drv)[pd[6]]-(*drv)[pd[8]]-(*drv)[pd[10]]-(*drv)[pd[12]]) + + 0.5*((*drv)[pd[16]] + (*drv)[pd[17]]) + + 0.25*((*drv)[pd[18]] + (*drv)[pd[19]])); + (*drv)[cd[17]] = + (0.0625*(-(*drv)[pd[0]] + (*drv)[pd[1]]) + + 0.1875*((*drv)[pd[4]] - (*drv)[pd[5]]) + 0.375*(*drv)[pd[8]] + - 0.125*(*drv)[pd[12]] + 0.75*(*drv)[pd[18]]); + (*drv)[cd[18]] = + (0.0625*(-(*drv)[pd[0]] + (*drv)[pd[1]]) + + 0.1875*((*drv)[pd[4]] - (*drv)[pd[5]]) + 0.375*(*drv)[pd[6]] + - 0.125*(*drv)[pd[10]] + 0.75*(*drv)[pd[19]]); + + /****************************************************************************/ + /* values on child[1] */ + /****************************************************************************/ + + cd = basFct->getLocalIndices(el->getChild(1), admin, NULL); + + if (typ == 0) + { + /****************************************************************************/ + /* parent of el_type 0 */ + /****************************************************************************/ + + (*drv)[cd[8]] = + (0.0625*(*drv)[pd[0]] + 0.3125*((*drv)[pd[1]] - (*drv)[pd[4]]) + + 0.9375*(*drv)[pd[5]]); + (*drv)[cd[9]] = (*drv)[pd[5]]; + (*drv)[cd[17]] = + (0.0625*((*drv)[pd[0]] - (*drv)[pd[1]]) + + 0.1875*(-(*drv)[pd[4]] + (*drv)[pd[5]]) + - 0.125*(*drv)[pd[6]] + 0.375*(*drv)[pd[10]] + 0.75*(*drv)[pd[19]]); + (*drv)[cd[18]] = + (0.0625*((*drv)[pd[0]] - (*drv)[pd[1]]) + + 0.1875*(-(*drv)[pd[4]] + (*drv)[pd[5]]) - 0.125*(*drv)[pd[8]] + + 0.375*(*drv)[pd[12]] + 0.75*(*drv)[pd[18]]); + } + else + { + /****************************************************************************/ + /* parent of el_type 0 */ + /****************************************************************************/ + + (*drv)[cd[8]] = + (0.0625*(*drv)[pd[0]] + 0.3125*((*drv)[pd[1]] - (*drv)[pd[4]]) + + 0.9375*(*drv)[pd[5]]); + (*drv)[cd[9]] = (*drv)[pd[5]]; + (*drv)[cd[17]] = + (0.0625*((*drv)[pd[0]] - (*drv)[pd[1]]) + + 0.1875*(-(*drv)[pd[4]] + (*drv)[pd[5]]) - 0.125*(*drv)[pd[8]] + + 0.375*(*drv)[pd[12]] + 0.75*(*drv)[pd[18]]); + (*drv)[cd[18]] = + (0.0625*((*drv)[pd[0]] - (*drv)[pd[1]]) + + 0.1875*(-(*drv)[pd[4]] + (*drv)[pd[5]]) - 0.125*(*drv)[pd[6]] + + 0.375*(*drv)[pd[10]] + 0.75*(*drv)[pd[19]]); + } + + /****************************************************************************/ + /* adjust neighbour values */ + /****************************************************************************/ + + node0 = drv->getFESpace()->getMesh()->getNode(FACE); + n0 = admin->getNumberOfPreDOFs(FACE); + + for (i = 1; i < n; i++) + { + el = list->getElement(i); + typ = list->getType(i); + basFct->getLocalIndices(el, admin, pd); + + lr_set = 0; + if (list->getNeighbourElement(i, 0) && list->getNeighbourNr(i, 0) < i) + lr_set = 1; + + if (list->getNeighbourElement(i, 1) && list->getNeighbourNr(i, 1) < i) + lr_set += 2; + + TEST_EXIT(lr_set)("no values set on both neighbours\n"); + + /****************************************************************************/ + /* values on child[0] */ + /****************************************************************************/ + + cd = basFct->getLocalIndices(el->getChild(0), admin, NULL); + + switch(lr_set) + { + case 1: + (*drv)[cd[12]] = + (0.0625*((*drv)[pd[0]]+(*drv)[pd[1]]-(*drv)[pd[4]]-(*drv)[pd[5]]) + + 0.25*(-(*drv)[pd[6]] - (*drv)[pd[10]]) + + 0.5*((*drv)[pd[7]] + (*drv)[pd[11]] + (*drv)[pd[19]])); + (*drv)[cd[13]] = (*drv)[pd[19]]; + (*drv)[cd[16]] = + (0.0625*((*drv)[pd[0]]+(*drv)[pd[1]]-(*drv)[pd[4]]-(*drv)[pd[5]]) + + 0.125*(-(*drv)[pd[6]]-(*drv)[pd[8]]-(*drv)[pd[10]]-(*drv)[pd[12]]) + + 0.5*((*drv)[pd[16]] + (*drv)[pd[17]]) + + 0.25*((*drv)[pd[18]] + (*drv)[pd[19]])); + (*drv)[cd[18]] = + (0.0625*(-(*drv)[pd[0]] + (*drv)[pd[1]]) + + 0.1875*((*drv)[pd[4]] - (*drv)[pd[5]]) + 0.375*(*drv)[pd[6]] + - 0.125*(*drv)[pd[10]] + 0.75*(*drv)[pd[19]]); + break; + case 2: + (*drv)[cd[14]] = + (0.0625*((*drv)[pd[0]]+(*drv)[pd[1]]-(*drv)[pd[4]]-(*drv)[pd[5]]) + + 0.25*(-(*drv)[pd[8]] - (*drv)[pd[12]]) + + 0.5*((*drv)[pd[9]] + (*drv)[pd[13]] + (*drv)[pd[18]])); + (*drv)[cd[15]] = (*drv)[pd[18]]; + (*drv)[cd[16]] = + (0.0625*((*drv)[pd[0]]+(*drv)[pd[1]]-(*drv)[pd[4]]-(*drv)[pd[5]]) + + 0.125*(-(*drv)[pd[6]]-(*drv)[pd[8]]-(*drv)[pd[10]]-(*drv)[pd[12]]) + + 0.5*((*drv)[pd[16]] + (*drv)[pd[17]]) + + 0.25*((*drv)[pd[18]] + (*drv)[pd[19]])); + (*drv)[cd[17]] = + (0.0625*(-(*drv)[pd[0]] + (*drv)[pd[1]]) + + 0.1875*((*drv)[pd[4]] - (*drv)[pd[5]]) + 0.375*(*drv)[pd[8]] + - 0.125*(*drv)[pd[12]] + 0.75*(*drv)[pd[18]]); + break; + case 3: + (*drv)[cd[16]] = + (0.0625*((*drv)[pd[0]]+(*drv)[pd[1]]-(*drv)[pd[4]]-(*drv)[pd[5]]) + + 0.125*(-(*drv)[pd[6]]-(*drv)[pd[8]]-(*drv)[pd[10]]-(*drv)[pd[12]]) + + 0.5*((*drv)[pd[16]] + (*drv)[pd[17]]) + + 0.25*((*drv)[pd[18]] + (*drv)[pd[19]])); + break; + } + + /****************************************************************************/ + /* values on child[1] */ + /****************************************************************************/ + + cd = basFct->getLocalIndices(el->getChild(1), admin, NULL); + + if (typ == 0) + { + switch(lr_set) + { + case 1: + cdi = el->getChild(1)->getDOF(node0+1, n0); + TEST_EXIT(cdi == cd[17])("cdi != cd[17]\n"); + (*drv)[cdi] = + (0.0625*((*drv)[pd[0]] - (*drv)[pd[1]]) + + 0.1875*(-(*drv)[pd[4]] + (*drv)[pd[5]]) - 0.125*(*drv)[pd[6]] + + 0.375*(*drv)[pd[10]] + 0.75*(*drv)[pd[19]]); + break; + case 2: + cdi = el->getChild(1)->getDOF(node0+2, n0); + TEST_EXIT(cdi == cd[18])("cdi != cd[18]\n"); + (*drv)[cdi] = + (0.0625*((*drv)[pd[0]] - (*drv)[pd[1]]) + + 0.1875*(-(*drv)[pd[4]] + (*drv)[pd[5]]) - 0.125*(*drv)[pd[8]] + + 0.375*(*drv)[pd[12]] + 0.75*(*drv)[pd[18]]); + break; + } + } + else + { + switch(lr_set) + { + case 1: + cdi = el->getChild(1)->getDOF(node0+2, n0); + TEST_EXIT(cdi == cd[18])("cdi != cd[18]\n"); + (*drv)[cdi] = + (0.0625*((*drv)[pd[0]] - (*drv)[pd[1]]) + + 0.1875*(-(*drv)[pd[4]] + (*drv)[pd[5]]) - 0.125*(*drv)[pd[6]] + + 0.375*(*drv)[pd[10]] + 0.75*(*drv)[pd[19]]); + break; + case 2: + cdi = el->getChild(1)->getDOF(node0+1, n0); + TEST_EXIT(cdi == cd[17])("cdi != cd[17]\n"); + (*drv)[cdi] = + (0.0625*((*drv)[pd[0]] - (*drv)[pd[1]]) + + 0.1875*(-(*drv)[pd[4]] + (*drv)[pd[5]]) - 0.125*(*drv)[pd[8]] + + 0.375*(*drv)[pd[12]] + 0.75*(*drv)[pd[18]]); + break; + } + } + } + + return; + } + + void Lagrange::refineInter4_1d(DOFIndexed<double> *drv, + RCNeighbourList* list, + int n, BasisFunction* basFct) + { + FUNCNAME("Lagrange::refineInter4_1d"); + + if (n < 1) return; + + Element *el; + DegreeOfFreedom *pdof = GET_MEMORY(DegreeOfFreedom, basFct->getNumber()); + const DegreeOfFreedom *cdof; + const DOFAdmin *admin; + + el = list->getElement(0); + + admin = drv->getFESpace()->getAdmin(); + + basFct->getLocalIndices(el, admin, pdof); + + /****************************************************************************/ + /* values on child[0] */ + /****************************************************************************/ + + cdof = basFct->getLocalIndices(el->getChild(0), admin, NULL); + + (*drv)[cdof[2]] = (*drv)[pdof[10]]; + (*drv)[cdof[3]] = + (0.2734375*(*drv)[pdof[0]] - 0.0390625*(*drv)[pdof[1]] + + 1.09375*(*drv)[pdof[9]] - 0.546875*(*drv)[pdof[10]] + + 0.21875*(*drv)[pdof[11]]); + (*drv)[cdof[4]] = (*drv)[pdof[9]]; + (*drv)[cdof[5]] = + (-0.0390625*(*drv)[pdof[0]] + 0.0234375*(*drv)[pdof[1]] + + 0.46875*(*drv)[pdof[9]] + 0.703125*(*drv)[pdof[10]] + - 0.15625*(*drv)[pdof[11]]); + (*drv)[cdof[6]] = + (0.0234375*((*drv)[pdof[0]] + (*drv)[pdof[1]]) + + 0.0625*(-(*drv)[pdof[3]] - (*drv)[pdof[8]]) + + 0.09375*(-(*drv)[pdof[9]] - (*drv)[pdof[11]]) + 0.140625*(*drv)[pdof[10]] + + 0.5625*((*drv)[pdof[12]] + (*drv)[pdof[13]])); + (*drv)[cdof[7]] = (*drv)[pdof[14]]; + (*drv)[cdof[8]] = + (0.0390625*(-(*drv)[pdof[0]] - (*drv)[pdof[1]]) + + 0.1875*((*drv)[pdof[3]] + (*drv)[pdof[8]]-(*drv)[pdof[12]]-(*drv)[pdof[13]]) + + 0.375*(-(*drv)[pdof[4]] - (*drv)[pdof[7]]) + + 0.5*((*drv)[pdof[5]] + (*drv)[pdof[6]]) + + 0.03125*((*drv)[pdof[9]] + (*drv)[pdof[11]]) + + 0.015625*(*drv)[pdof[10]] + 0.75*(*drv)[pdof[14]]); + (*drv)[cdof[12]] = + (0.0234375*(*drv)[pdof[0]] - 0.0390625*(*drv)[pdof[1]] + + 0.125*((*drv)[pdof[3]] - (*drv)[pdof[4]] - (*drv)[pdof[8]]) + + 0.375*((*drv)[pdof[7]] + (*drv)[pdof[12]] - (*drv)[pdof[13]]) + - 0.03125*(*drv)[pdof[9]] - 0.046875*(*drv)[pdof[10]] + + 0.09375*(*drv)[pdof[11]] + 0.75*(*drv)[pdof[14]]); + (*drv)[cdof[13]] = + (0.0390625*(-(*drv)[pdof[0]] - (*drv)[pdof[1]]) + 0.0625*(*drv)[pdof[3]] + + 0.3125*((*drv)[pdof[8]] - (*drv)[pdof[13]]) + + 0.15625*((*drv)[pdof[9]] + (*drv)[pdof[11]]) + - 0.234375*(*drv)[pdof[10]] + 0.9375*(*drv)[pdof[12]]); + (*drv)[cdof[14]] = (*drv)[pdof[12]]; + + /****************************************************************************/ + /* values on child[1] */ + /****************************************************************************/ + + cdof = basFct->getLocalIndices(el->getChild(1), admin, NULL); + + (*drv)[cdof[6]] = + (0.0234375*(*drv)[pdof[0]] - 0.0390625*(*drv)[pdof[1]] + - 0.15625*(*drv)[pdof[9]] + 0.703125*(*drv)[pdof[10]] + + 0.46875*(*drv)[pdof[11]]); + (*drv)[cdof[7]] = (*drv)[pdof[11]]; + (*drv)[cdof[8]] = + (-0.0390625*(*drv)[pdof[0]] + 0.2734375*(*drv)[pdof[1]] + + 0.21875*(*drv)[pdof[9]] - 0.546875*(*drv)[pdof[10]] + + 1.09375*(*drv)[pdof[11]]); + (*drv)[cdof[12]] = + (0.0390625*(-(*drv)[pdof[0]] - (*drv)[pdof[1]]) + + 0.3125*((*drv)[pdof[3]] - (*drv)[pdof[12]]) + 0.0625*(*drv)[pdof[8]] + + 0.15625*((*drv)[pdof[9]] + (*drv)[pdof[11]]) + - 0.234375*(*drv)[pdof[10]] + 0.9375*(*drv)[pdof[13]]); + (*drv)[cdof[13]] = + (-0.0390625*(*drv)[pdof[0]] + 0.0234375*(*drv)[pdof[1]] + + 0.125*(-(*drv)[pdof[3]] - (*drv)[pdof[7]] + (*drv)[pdof[8]]) + + 0.375*((*drv)[pdof[4]] - (*drv)[pdof[12]] + (*drv)[pdof[13]]) + + 0.09375*(*drv)[pdof[9]] - 0.046875*(*drv)[pdof[10]] + - 0.03125*(*drv)[pdof[11]] + 0.75*(*drv)[pdof[14]]); + (*drv)[cdof[14]] = (*drv)[pdof[13]]; + + if (n <= 1) { + FREE_MEMORY(pdof, DegreeOfFreedom, basFct->getNumber()); + return; + } + /****************************************************************************/ + /* adjust neighbour values */ + /****************************************************************************/ + + el = list->getElement(1); + + basFct->getLocalIndices(el, admin, pdof); + + /****************************************************************************/ + /* values on neighbour's child[0] */ + /****************************************************************************/ + + cdof = basFct->getLocalIndices(el->getChild(0), admin, NULL); + + (*drv)[cdof[6]] = + (0.0234375*((*drv)[pdof[0]] + (*drv)[pdof[1]]) + + 0.0625*(-(*drv)[pdof[3]] - (*drv)[pdof[8]]) + + 0.09375*(-(*drv)[pdof[9]] - (*drv)[pdof[11]]) + + 0.140625*(*drv)[pdof[10]] + 0.5625*((*drv)[pdof[12]] + (*drv)[pdof[13]])); + (*drv)[cdof[7]] = (*drv)[pdof[14]]; + (*drv)[cdof[8]] = + (0.0390625*(-(*drv)[pdof[0]] - (*drv)[pdof[1]]) + + 0.1875*((*drv)[pdof[3]]+(*drv)[pdof[8]]-(*drv)[pdof[12]]-(*drv)[pdof[13]]) + + 0.375*(-(*drv)[pdof[4]] - (*drv)[pdof[7]]) + + 0.5*((*drv)[pdof[5]] + (*drv)[pdof[6]]) + + 0.03125*((*drv)[pdof[9]] + (*drv)[pdof[11]]) + + 0.015625*(*drv)[pdof[10]] + 0.75*(*drv)[pdof[14]]); + (*drv)[cdof[12]] = + (0.0234375*(*drv)[pdof[0]] - 0.0390625*(*drv)[pdof[1]] + + 0.125*((*drv)[pdof[3]] - (*drv)[pdof[4]] - (*drv)[pdof[8]]) + + 0.375*((*drv)[pdof[7]] + (*drv)[pdof[12]] - (*drv)[pdof[13]]) + - 0.03125*(*drv)[pdof[9]] - 0.046875*(*drv)[pdof[10]] + + 0.09375*(*drv)[pdof[11]] + 0.75*(*drv)[pdof[14]]); + (*drv)[cdof[13]] = + (0.0390625*(-(*drv)[pdof[0]] - (*drv)[pdof[1]]) + 0.0625*(*drv)[pdof[3]] + + 0.3125*((*drv)[pdof[8]] - (*drv)[pdof[13]]) + + 0.15625*((*drv)[pdof[9]] + (*drv)[pdof[11]]) + - 0.234375*(*drv)[pdof[10]] + 0.9375*(*drv)[pdof[12]]); + (*drv)[cdof[14]] = (*drv)[pdof[12]]; + + /****************************************************************************/ + /* values on neighbour's child[1] */ + /****************************************************************************/ + + cdof = basFct->getLocalIndices(el->getChild(1), admin, NULL); + + (*drv)[cdof[12]] = + (0.0390625*(-(*drv)[pdof[0]] - (*drv)[pdof[1]]) + + 0.3125*((*drv)[pdof[3]] - (*drv)[pdof[12]]) + + 0.0625*(*drv)[pdof[8]] + 0.15625*((*drv)[pdof[9]] + (*drv)[pdof[11]]) + - 0.234375*(*drv)[pdof[10]] + 0.9375*(*drv)[pdof[13]]); + (*drv)[cdof[13]] = + (-0.0390625*(*drv)[pdof[0]] + 0.0234375*(*drv)[pdof[1]] + + 0.125*(-(*drv)[pdof[3]] - (*drv)[pdof[7]] + (*drv)[pdof[8]]) + + 0.375*((*drv)[pdof[4]] - (*drv)[pdof[12]] + (*drv)[pdof[13]]) + + 0.09375*(*drv)[pdof[9]] - 0.046875*(*drv)[pdof[10]] + - 0.03125*(*drv)[pdof[11]] + 0.75*(*drv)[pdof[14]]); + (*drv)[cdof[14]] = (*drv)[pdof[13]]; + + FREE_MEMORY(pdof, DegreeOfFreedom, basFct->getNumber()); + return; + } + + void Lagrange::refineInter4_2d(DOFIndexed<double> *drv, + RCNeighbourList* list, + int n, BasisFunction* basFct) + { + FUNCNAME("Lagrange::refineInter4_2d"); + Element *el; + DegreeOfFreedom pdof[15]; + const DegreeOfFreedom *cdof; + const DOFAdmin *admin; + + if (n < 1) return; + el = list->getElement(0); + + admin = drv->getFESpace()->getAdmin(); + + basFct->getLocalIndices(el, admin, pdof); + + /****************************************************************************/ + /* values on child[0] */ + /****************************************************************************/ + + cdof = basFct->getLocalIndices(el->getChild(0), admin, NULL); + + (*drv)[cdof[2]] = (*drv)[pdof[10]]; + (*drv)[cdof[3]] = + (0.2734375*(*drv)[pdof[0]] - 0.0390625*(*drv)[pdof[1]] + + 1.09375*(*drv)[pdof[9]] - 0.546875*(*drv)[pdof[10]] + + 0.21875*(*drv)[pdof[11]]); + (*drv)[cdof[4]] = (*drv)[pdof[9]]; + (*drv)[cdof[5]] = + (-0.0390625*(*drv)[pdof[0]] + 0.0234375*(*drv)[pdof[1]] + + 0.46875*(*drv)[pdof[9]] + 0.703125*(*drv)[pdof[10]] + - 0.15625*(*drv)[pdof[11]]); + (*drv)[cdof[6]] = + (0.0234375*((*drv)[pdof[0]] + (*drv)[pdof[1]]) + + 0.0625*(-(*drv)[pdof[3]] - (*drv)[pdof[8]]) + + 0.09375*(-(*drv)[pdof[9]] - (*drv)[pdof[11]]) + 0.140625*(*drv)[pdof[10]] + + 0.5625*((*drv)[pdof[12]] + (*drv)[pdof[13]])); + (*drv)[cdof[7]] = (*drv)[pdof[14]]; + (*drv)[cdof[8]] = + (0.0390625*(-(*drv)[pdof[0]] - (*drv)[pdof[1]]) + + 0.1875*((*drv)[pdof[3]] + + (*drv)[pdof[8]]-(*drv)[pdof[12]] + -(*drv)[pdof[13]]) + + 0.375*(-(*drv)[pdof[4]] - (*drv)[pdof[7]]) + + 0.5*((*drv)[pdof[5]] + (*drv)[pdof[6]]) + + 0.03125*((*drv)[pdof[9]] + (*drv)[pdof[11]]) + + 0.015625*(*drv)[pdof[10]] + 0.75*(*drv)[pdof[14]]); + (*drv)[cdof[12]] = + (0.0234375*(*drv)[pdof[0]] - 0.0390625*(*drv)[pdof[1]] + + 0.125*((*drv)[pdof[3]] - (*drv)[pdof[4]] - (*drv)[pdof[8]]) + + 0.375*((*drv)[pdof[7]] + (*drv)[pdof[12]] - (*drv)[pdof[13]]) + - 0.03125*(*drv)[pdof[9]] - 0.046875*(*drv)[pdof[10]] + + 0.09375*(*drv)[pdof[11]] + 0.75*(*drv)[pdof[14]]); + (*drv)[cdof[13]] = + (0.0390625*(-(*drv)[pdof[0]] - (*drv)[pdof[1]]) + 0.0625*(*drv)[pdof[3]] + + 0.3125*((*drv)[pdof[8]] - (*drv)[pdof[13]]) + + 0.15625*((*drv)[pdof[9]] + (*drv)[pdof[11]]) + - 0.234375*(*drv)[pdof[10]] + 0.9375*(*drv)[pdof[12]]); + (*drv)[cdof[14]] = (*drv)[pdof[12]]; + + /****************************************************************************/ + /* values on child[1] */ + /****************************************************************************/ + + cdof = basFct->getLocalIndices(el->getChild(1), admin, NULL); + + (*drv)[cdof[6]] = + (0.0234375*(*drv)[pdof[0]] - 0.0390625*(*drv)[pdof[1]] + - 0.15625*(*drv)[pdof[9]] + 0.703125*(*drv)[pdof[10]] + + 0.46875*(*drv)[pdof[11]]); + (*drv)[cdof[7]] = (*drv)[pdof[11]]; + (*drv)[cdof[8]] = + (-0.0390625*(*drv)[pdof[0]] + 0.2734375*(*drv)[pdof[1]] + + 0.21875*(*drv)[pdof[9]] - 0.546875*(*drv)[pdof[10]] + + 1.09375*(*drv)[pdof[11]]); + (*drv)[cdof[12]] = + (0.0390625*(-(*drv)[pdof[0]] - (*drv)[pdof[1]]) + + 0.3125*((*drv)[pdof[3]] - (*drv)[pdof[12]]) + 0.0625*(*drv)[pdof[8]] + + 0.15625*((*drv)[pdof[9]] + (*drv)[pdof[11]]) + - 0.234375*(*drv)[pdof[10]] + 0.9375*(*drv)[pdof[13]]); + (*drv)[cdof[13]] = + (-0.0390625*(*drv)[pdof[0]] + 0.0234375*(*drv)[pdof[1]] + + 0.125*(-(*drv)[pdof[3]] - (*drv)[pdof[7]] + (*drv)[pdof[8]]) + + 0.375*((*drv)[pdof[4]] - (*drv)[pdof[12]] + (*drv)[pdof[13]]) + + 0.09375*(*drv)[pdof[9]] - 0.046875*(*drv)[pdof[10]] + - 0.03125*(*drv)[pdof[11]] + 0.75*(*drv)[pdof[14]]); + (*drv)[cdof[14]] = (*drv)[pdof[13]]; + + if (n <= 1) return; + + /****************************************************************************/ + /* adjust neighbour values */ + /****************************************************************************/ + + el = list->getElement(1); + + basFct->getLocalIndices(el, admin, pdof); + + /****************************************************************************/ + /* values on neighbour's child[0] */ + /****************************************************************************/ + + cdof = basFct->getLocalIndices(el->getChild(0), admin, NULL); + + (*drv)[cdof[6]] = + (0.0234375*((*drv)[pdof[0]] + (*drv)[pdof[1]]) + + 0.0625*(-(*drv)[pdof[3]] - (*drv)[pdof[8]]) + + 0.09375*(-(*drv)[pdof[9]] - (*drv)[pdof[11]]) + + 0.140625*(*drv)[pdof[10]] + 0.5625*((*drv)[pdof[12]] + (*drv)[pdof[13]])); + (*drv)[cdof[7]] = (*drv)[pdof[14]]; + (*drv)[cdof[8]] = + (0.0390625*(-(*drv)[pdof[0]] - (*drv)[pdof[1]]) + + 0.1875*((*drv)[pdof[3]]+(*drv)[pdof[8]]-(*drv)[pdof[12]]-(*drv)[pdof[13]]) + + 0.375*(-(*drv)[pdof[4]] - (*drv)[pdof[7]]) + + 0.5*((*drv)[pdof[5]] + (*drv)[pdof[6]]) + + 0.03125*((*drv)[pdof[9]] + (*drv)[pdof[11]]) + + 0.015625*(*drv)[pdof[10]] + 0.75*(*drv)[pdof[14]]); + (*drv)[cdof[12]] = + (0.0234375*(*drv)[pdof[0]] - 0.0390625*(*drv)[pdof[1]] + + 0.125*((*drv)[pdof[3]] - (*drv)[pdof[4]] - (*drv)[pdof[8]]) + + 0.375*((*drv)[pdof[7]] + (*drv)[pdof[12]] - (*drv)[pdof[13]]) + - 0.03125*(*drv)[pdof[9]] - 0.046875*(*drv)[pdof[10]] + + 0.09375*(*drv)[pdof[11]] + 0.75*(*drv)[pdof[14]]); + (*drv)[cdof[13]] = + (0.0390625*(-(*drv)[pdof[0]] - (*drv)[pdof[1]]) + 0.0625*(*drv)[pdof[3]] + + 0.3125*((*drv)[pdof[8]] - (*drv)[pdof[13]]) + + 0.15625*((*drv)[pdof[9]] + (*drv)[pdof[11]]) + - 0.234375*(*drv)[pdof[10]] + 0.9375*(*drv)[pdof[12]]); + (*drv)[cdof[14]] = (*drv)[pdof[12]]; + + /****************************************************************************/ + /* values on neighbour's child[1] */ + /****************************************************************************/ + + cdof = basFct->getLocalIndices(el->getChild(1), admin, NULL); + + (*drv)[cdof[12]] = + (0.0390625*(-(*drv)[pdof[0]] - (*drv)[pdof[1]]) + + 0.3125*((*drv)[pdof[3]] - (*drv)[pdof[12]]) + + 0.0625*(*drv)[pdof[8]] + 0.15625*((*drv)[pdof[9]] + (*drv)[pdof[11]]) + - 0.234375*(*drv)[pdof[10]] + 0.9375*(*drv)[pdof[13]]); + (*drv)[cdof[13]] = + (-0.0390625*(*drv)[pdof[0]] + 0.0234375*(*drv)[pdof[1]] + + 0.125*(-(*drv)[pdof[3]] - (*drv)[pdof[7]] + (*drv)[pdof[8]]) + + 0.375*((*drv)[pdof[4]] - (*drv)[pdof[12]] + (*drv)[pdof[13]]) + + 0.09375*(*drv)[pdof[9]] - 0.046875*(*drv)[pdof[10]] + - 0.03125*(*drv)[pdof[11]] + 0.75*(*drv)[pdof[14]]); + (*drv)[cdof[14]] = (*drv)[pdof[13]]; + + return; + } + + void Lagrange::refineInter4_3d(DOFIndexed<double> *drv, + RCNeighbourList* list, + int n, BasisFunction* basFct) + { + FUNCNAME("Lagrange::refineInter4_3d"); + DegreeOfFreedom pd[35]; + const DegreeOfFreedom *cd; + Element *el; + int i, typ, lr_set; + const DOFAdmin *admin; + + if (n < 1) return; + el = list->getElement(0); + typ = list->getType(0); + + admin = drv->getFESpace()->getAdmin(); + + basFct->getLocalIndices(el, admin, pd); + + /****************************************************************************/ + /* values on child[0] */ + /****************************************************************************/ + + cd = basFct->getLocalIndices(el->getChild(0), admin, NULL); + + (*drv)[cd[3]] = ((*drv)[pd[5]]); + (*drv)[cd[10]] = + (0.2734375*(*drv)[pd[0]] - 0.0390625*(*drv)[pd[1]] + + 1.09375*(*drv)[pd[4]] - 0.546875*(*drv)[pd[5]] + + 0.21875*(*drv)[pd[6]]); + (*drv)[cd[11]] = ((*drv)[pd[4]]); + (*drv)[cd[12]] = + (-0.0390625*(*drv)[pd[0]] + 0.0234375*(*drv)[pd[1]] + + 0.46875*(*drv)[pd[4]] + 0.703125*(*drv)[pd[5]] + - 0.15625*(*drv)[pd[6]]); + (*drv)[cd[16]] = + (0.0390625*(-(*drv)[pd[0]] - (*drv)[pd[1]]) + + 0.03125*((*drv)[pd[4]] + (*drv)[pd[6]]) + + 0.015625*(*drv)[pd[5]] + + 0.1875*((*drv)[pd[7]]+(*drv)[pd[13]]-(*drv)[pd[31]]-(*drv)[pd[32]]) + + 0.375*(-(*drv)[pd[8]] - (*drv)[pd[14]]) + + 0.5*((*drv)[pd[9]] + (*drv)[pd[15]]) + 0.75*(*drv)[pd[33]]); + (*drv)[cd[17]] = ((*drv)[pd[33]]); + (*drv)[cd[18]] = + (0.0234375*((*drv)[pd[0]] + (*drv)[pd[1]]) + + 0.09375*(-(*drv)[pd[4]] - (*drv)[pd[6]]) + 0.140625*(*drv)[pd[5]] + + 0.0625*(-(*drv)[pd[7]] - (*drv)[pd[13]]) + + 0.5625*((*drv)[pd[31]] + (*drv)[pd[32]])); + (*drv)[cd[19]] = + (0.0390625*(-(*drv)[pd[0]] - (*drv)[pd[1]]) + + 0.03125*((*drv)[pd[4]] + (*drv)[pd[6]]) + 0.015625*(*drv)[pd[5]] + + 0.1875*((*drv)[pd[10]]+(*drv)[pd[16]]-(*drv)[pd[28]]-(*drv)[pd[29]]) + + 0.375*(-(*drv)[pd[11]] - (*drv)[pd[17]]) + + 0.5*((*drv)[pd[12]] + (*drv)[pd[18]]) + 0.75*(*drv)[pd[30]]); + (*drv)[cd[20]] = ((*drv)[pd[30]]); + (*drv)[cd[21]] = + (0.0234375*((*drv)[pd[0]] + (*drv)[pd[1]]) + + 0.09375*(-(*drv)[pd[4]] - (*drv)[pd[6]]) + 0.140625*(*drv)[pd[5]] + + 0.0625*(-(*drv)[pd[10]] - (*drv)[pd[16]]) + + 0.5625*((*drv)[pd[28]] + (*drv)[pd[29]])); + (*drv)[cd[22]] = + (0.0390625*(-(*drv)[pd[0]] - (*drv)[pd[1]]) + + 0.03125*((*drv)[pd[4]] + (*drv)[pd[6]]) + 0.015625*(*drv)[pd[5]] + + 0.125*((*drv)[pd[7]] + -(*drv)[pd[8]]+(*drv)[pd[13]]-(*drv)[pd[14]] + -(*drv)[pd[31]]-(*drv)[pd[32]]) + + 0.0625*((*drv)[pd[10]]+(*drv)[pd[16]]-(*drv)[pd[28]]-(*drv)[pd[29]]) + + 0.25*(-(*drv)[pd[22]] - (*drv)[pd[25]] + (*drv)[pd[33]]) + + 0.5*((*drv)[pd[23]] + (*drv)[pd[26]] + (*drv)[pd[34]])); + (*drv)[cd[23]] = + (0.0390625*(-(*drv)[pd[0]] - (*drv)[pd[1]]) + + 0.03125*((*drv)[pd[4]] + (*drv)[pd[6]]) + 0.015625*(*drv)[pd[5]] + + 0.0625*((*drv)[pd[7]]+(*drv)[pd[13]]-(*drv)[pd[31]]-(*drv)[pd[32]]) + + 0.125*((*drv)[pd[10]]-(*drv)[pd[11]]+(*drv)[pd[16]]-(*drv)[pd[17]] + -(*drv)[pd[28]]-(*drv)[pd[29]]) + + 0.25*(-(*drv)[pd[22]] - (*drv)[pd[25]] + (*drv)[pd[30]]) + + 0.5*((*drv)[pd[24]] + (*drv)[pd[27]] + (*drv)[pd[34]])); + (*drv)[cd[24]] = ((*drv)[pd[34]]); + (*drv)[cd[25]] = + (0.0390625*(-(*drv)[pd[0]] - (*drv)[pd[1]]) + + 0.15625*((*drv)[pd[4]] + (*drv)[pd[6]]) - 0.234375*(*drv)[pd[5]] + + 0.3125*((*drv)[pd[10]] - (*drv)[pd[29]]) + 0.0625*(*drv)[pd[16]] + + 0.9375*(*drv)[pd[28]]); + (*drv)[cd[26]] = + (0.0234375*(*drv)[pd[0]] - 0.0390625*(*drv)[pd[1]] + - 0.03125*(*drv)[pd[4]] - 0.046875*(*drv)[pd[5]] + + 0.09375*(*drv)[pd[6]] + + 0.125*(-(*drv)[pd[10]] + (*drv)[pd[16]] - (*drv)[pd[17]]) + + 0.375*((*drv)[pd[11]] + (*drv)[pd[28]] - (*drv)[pd[29]]) + + 0.75*(*drv)[pd[30]]); + (*drv)[cd[27]] = ((*drv)[pd[28]]); + (*drv)[cd[28]] = + (0.0390625*(-(*drv)[pd[0]] - (*drv)[pd[1]]) + + 0.15625*((*drv)[pd[4]] + (*drv)[pd[6]]) - 0.234375*(*drv)[pd[5]] + + 0.3125*((*drv)[pd[7]] - (*drv)[pd[32]]) + 0.0625*(*drv)[pd[13]] + + 0.9375*(*drv)[pd[31]]); + (*drv)[cd[29]] = + (0.0234375*(*drv)[pd[0]] - 0.0390625*(*drv)[pd[1]] + - 0.03125*(*drv)[pd[4]] - 0.046875*(*drv)[pd[5]] + + 0.09375*(*drv)[pd[6]] + + 0.125*(-(*drv)[pd[7]] + (*drv)[pd[13]] - (*drv)[pd[14]]) + + 0.375*((*drv)[pd[8]] + (*drv)[pd[31]] - (*drv)[pd[32]]) + + 0.75*(*drv)[pd[33]]); + (*drv)[cd[30]] = ((*drv)[pd[31]]); + (*drv)[cd[34]] = + (0.0234375*(*drv)[pd[0]] - 0.0390625*(*drv)[pd[1]] + - 0.03125*(*drv)[pd[4]] - 0.046875*(*drv)[pd[5]] + + 0.09375*(*drv)[pd[6]] + + 0.0625*(-(*drv)[pd[7]]-(*drv)[pd[10]]+(*drv)[pd[13]]+(*drv)[pd[16]]) + - 0.125*(*drv)[pd[22]] + 0.375*(*drv)[pd[25]] + + 0.1875*((*drv)[pd[28]]-(*drv)[pd[29]]+(*drv)[pd[31]]-(*drv)[pd[32]]) + + 0.75*(*drv)[pd[34]]); + + /****************************************************************************/ + /* values on child[1] */ + /****************************************************************************/ + + cd = basFct->getLocalIndices(el->getChild(1), admin, NULL); + if (typ == 0) + { + /****************************************************************************/ + /* parent of el_type 0 */ + /****************************************************************************/ + + (*drv)[cd[10]] = + (-0.0390625*(*drv)[pd[0]] + 0.2734375*(*drv)[pd[1]] + + 0.21875*(*drv)[pd[4]] - 0.546875*(*drv)[pd[5]] + + 1.09375*(*drv)[pd[6]]); + (*drv)[cd[11]] = (*drv)[pd[6]]; + (*drv)[cd[12]] = + (0.0234375*(*drv)[pd[0]] - 0.0390625*(*drv)[pd[1]] + - 0.15625*(*drv)[pd[4]] + 0.703125*(*drv)[pd[5]] + + 0.46875*(*drv)[pd[6]]); + (*drv)[cd[25]] = + (0.0390625*(-(*drv)[pd[0]] - (*drv)[pd[1]]) + + 0.15625*((*drv)[pd[4]] + (*drv)[pd[6]]) + - 0.234375*(*drv)[pd[5]] + 0.0625*(*drv)[pd[7]] + + 0.3125*((*drv)[pd[13]] - (*drv)[pd[31]]) + + 0.9375*(*drv)[pd[32]]); + (*drv)[cd[26]] = + (-0.0390625*(*drv)[pd[0]] + 0.0234375*(*drv)[pd[1]] + + 0.09375*(*drv)[pd[4]] - 0.046875*(*drv)[pd[5]] + - 0.03125*(*drv)[pd[6]] + + 0.125*((*drv)[pd[7]] - (*drv)[pd[8]] - (*drv)[pd[13]]) + + 0.375*((*drv)[pd[14]] - (*drv)[pd[31]] + (*drv)[pd[32]]) + + 0.75*(*drv)[pd[33]]); + (*drv)[cd[27]] = (*drv)[pd[32]]; + (*drv)[cd[28]] = + (0.0390625*(-(*drv)[pd[0]] - (*drv)[pd[1]]) + + 0.15625*((*drv)[pd[4]] + (*drv)[pd[6]]) + - 0.234375*(*drv)[pd[5]] + 0.0625*(*drv)[pd[10]] + + 0.3125*((*drv)[pd[16]] - (*drv)[pd[28]]) + + 0.9375*(*drv)[pd[29]]); + (*drv)[cd[29]] = + (-0.0390625*(*drv)[pd[0]] + 0.0234375*(*drv)[pd[1]] + + 0.09375*(*drv)[pd[4]] - 0.046875*(*drv)[pd[5]] + - 0.03125*(*drv)[pd[6]] + + 0.125*((*drv)[pd[10]] - (*drv)[pd[11]] - (*drv)[pd[16]]) + + 0.375*((*drv)[pd[17]] - (*drv)[pd[28]] + (*drv)[pd[29]]) + + 0.75*(*drv)[pd[30]]); + (*drv)[cd[30]] = (*drv)[pd[29]]; + (*drv)[cd[34]] = + (-0.0390625*(*drv)[pd[0]] + 0.0234375*(*drv)[pd[1]] + + 0.09375*(*drv)[pd[4]] - 0.046875*(*drv)[pd[5]] + - 0.03125*(*drv)[pd[6]] + + 0.0625*((*drv)[pd[7]] + (*drv)[pd[10]] + -(*drv)[pd[13]] - (*drv)[pd[16]]) + + 0.375*(*drv)[pd[22]] - 0.125*(*drv)[pd[25]] + + 0.1875*(-(*drv)[pd[28]] + (*drv)[pd[29]] + -(*drv)[pd[31]] + (*drv)[pd[32]]) + + 0.75*(*drv)[pd[34]]); + } + else + { + /****************************************************************************/ + /* parent of el_type 1|2 */ + /****************************************************************************/ + + (*drv)[cd[10]] = + (-0.0390625*(*drv)[pd[0]] + 0.2734375*(*drv)[pd[1]] + + 0.21875*(*drv)[pd[4]] - 0.546875*(*drv)[pd[5]] + + 1.09375*(*drv)[pd[6]]); + (*drv)[cd[11]] = (*drv)[pd[6]]; + (*drv)[cd[12]] = + (0.0234375*(*drv)[pd[0]] - 0.0390625*(*drv)[pd[1]] + - 0.15625*(*drv)[pd[4]] + 0.703125*(*drv)[pd[5]] + + 0.46875*(*drv)[pd[6]]); + (*drv)[cd[25]] = + (0.0390625*(-(*drv)[pd[0]] - (*drv)[pd[1]]) + + 0.15625*((*drv)[pd[4]] + (*drv)[pd[6]]) + - 0.234375*(*drv)[pd[5]] + 0.0625*(*drv)[pd[10]] + + 0.3125*((*drv)[pd[16]] - (*drv)[pd[28]]) + + 0.9375*(*drv)[pd[29]]); + (*drv)[cd[26]] = + (-0.0390625*(*drv)[pd[0]] + 0.0234375*(*drv)[pd[1]] + + 0.09375*(*drv)[pd[4]] - 0.046875*(*drv)[pd[5]] + - 0.03125*(*drv)[pd[6]] + + 0.125*((*drv)[pd[10]] - (*drv)[pd[11]] - (*drv)[pd[16]]) + + 0.375*((*drv)[pd[17]] - (*drv)[pd[28]] + (*drv)[pd[29]]) + + 0.75*(*drv)[pd[30]]); + (*drv)[cd[27]] = (*drv)[pd[29]]; + (*drv)[cd[28]] = + (0.0390625*(-(*drv)[pd[0]] - (*drv)[pd[1]]) + + 0.15625*((*drv)[pd[4]] + (*drv)[pd[6]]) + - 0.234375*(*drv)[pd[5]] + 0.0625*(*drv)[pd[7]] + + 0.3125*((*drv)[pd[13]] - (*drv)[pd[31]]) + + 0.9375*(*drv)[pd[32]]); + (*drv)[cd[29]] = + (-0.0390625*(*drv)[pd[0]] + 0.0234375*(*drv)[pd[1]] + + 0.09375*(*drv)[pd[4]] - 0.046875*(*drv)[pd[5]] + - 0.03125*(*drv)[pd[6]] + + 0.125*((*drv)[pd[7]] - (*drv)[pd[8]] - (*drv)[pd[13]]) + + 0.375*((*drv)[pd[14]] - (*drv)[pd[31]] + (*drv)[pd[32]]) + + 0.75*(*drv)[pd[33]]); + (*drv)[cd[30]] = (*drv)[pd[32]]; + (*drv)[cd[34]] = + (-0.0390625*(*drv)[pd[0]] + 0.0234375*(*drv)[pd[1]] + + 0.09375*(*drv)[pd[4]] - 0.046875*(*drv)[pd[5]] + - 0.03125*(*drv)[pd[6]] + + 0.0625*((*drv)[pd[7]] + (*drv)[pd[10]] + - (*drv)[pd[13]] - (*drv)[pd[16]]) + + 0.375*(*drv)[pd[22]] - 0.125*(*drv)[pd[25]] + + 0.1875*(-(*drv)[pd[28]] + (*drv)[pd[29]] + - (*drv)[pd[31]] + (*drv)[pd[32]]) + + 0.75*(*drv)[pd[34]]); + } + + /****************************************************************************/ + /* adjust neighbour values */ + /****************************************************************************/ + + for (i = 1; i < n; i++) + { + el = list->getElement(i); + typ = list->getType(i); + basFct->getLocalIndices(el, admin, pd); + + lr_set = 0; + if (list->getNeighbourElement(i, 0) && list->getNeighbourNr(i, 0) < i) + lr_set = 1; + + if (list->getNeighbourElement(i, 1) && list->getNeighbourNr(i, 1) < i) + lr_set += 2; + + TEST_EXIT(lr_set)("no values set on both neighbours\n"); + + /****************************************************************************/ + /* values on child[0] */ + /****************************************************************************/ + + cd = basFct->getLocalIndices(el->getChild(0), admin, NULL); + + switch(lr_set) + { + case 1: + (*drv)[cd[16]] = + (0.0390625*(-(*drv)[pd[0]] - (*drv)[pd[1]]) + + 0.03125*((*drv)[pd[4]] + (*drv)[pd[6]]) + + 0.015625*(*drv)[pd[5]] + + 0.1875*((*drv)[pd[7]] + (*drv)[pd[13]] + - (*drv)[pd[31]] - (*drv)[pd[32]]) + + 0.375*(-(*drv)[pd[8]] - (*drv)[pd[14]]) + + 0.5*((*drv)[pd[9]] + (*drv)[pd[15]]) + + 0.75*(*drv)[pd[33]]); + (*drv)[cd[17]] = (*drv)[pd[33]]; + (*drv)[cd[18]] = + (0.0234375*((*drv)[pd[0]] + (*drv)[pd[1]]) + + 0.09375*(-(*drv)[pd[4]] - (*drv)[pd[6]]) + + 0.140625*(*drv)[pd[5]] + + 0.0625*(-(*drv)[pd[7]] - (*drv)[pd[13]]) + + 0.5625*((*drv)[pd[31]] + (*drv)[pd[32]])); + (*drv)[cd[22]] = + (0.0390625*(-(*drv)[pd[0]] - (*drv)[pd[1]]) + + 0.03125*((*drv)[pd[4]] + (*drv)[pd[6]]) + + 0.015625*(*drv)[pd[5]] + + 0.125*((*drv)[pd[7]] - (*drv)[pd[8]] + (*drv)[pd[13]] + - (*drv)[pd[14]] - (*drv)[pd[31]] - (*drv)[pd[32]]) + + 0.0625*((*drv)[pd[10]] + (*drv)[pd[16]] + - (*drv)[pd[28]] - (*drv)[pd[29]]) + + 0.25*(-(*drv)[pd[22]] - (*drv)[pd[25]] + (*drv)[pd[33]]) + + 0.5*((*drv)[pd[23]] + (*drv)[pd[26]] + (*drv)[pd[34]])); + (*drv)[cd[23]] = + (0.0390625*(-(*drv)[pd[0]] - (*drv)[pd[1]]) + + 0.03125*((*drv)[pd[4]] + (*drv)[pd[6]]) + + 0.015625*(*drv)[pd[5]] + + 0.0625*((*drv)[pd[7]] + (*drv)[pd[13]] + - (*drv)[pd[31]] - (*drv)[pd[32]]) + + 0.125*((*drv)[pd[10]] - (*drv)[pd[11]] + (*drv)[pd[16]] + - (*drv)[pd[17]] - (*drv)[pd[28]] - (*drv)[pd[29]]) + + 0.25*(-(*drv)[pd[22]] - (*drv)[pd[25]] + (*drv)[pd[30]]) + + 0.5*((*drv)[pd[24]] + (*drv)[pd[27]] + (*drv)[pd[34]])); + (*drv)[cd[24]] = (*drv)[pd[34]]; + (*drv)[cd[28]] = + (0.0390625*(-(*drv)[pd[0]] - (*drv)[pd[1]]) + + 0.15625*((*drv)[pd[4]] + (*drv)[pd[6]]) + - 0.234375*(*drv)[pd[5]] + + 0.3125*((*drv)[pd[7]] - (*drv)[pd[32]]) + + 0.0625*(*drv)[pd[13]] + 0.9375*(*drv)[pd[31]]); + (*drv)[cd[29]] = + (0.0234375*(*drv)[pd[0]] - 0.0390625*(*drv)[pd[1]] + - 0.03125*(*drv)[pd[4]] - 0.046875*(*drv)[pd[5]] + + 0.09375*(*drv)[pd[6]] + + 0.125*(-(*drv)[pd[7]] + (*drv)[pd[13]] - (*drv)[pd[14]]) + + 0.375*((*drv)[pd[8]] + (*drv)[pd[31]] - (*drv)[pd[32]]) + + 0.75*(*drv)[pd[33]]); + (*drv)[cd[30]] = (*drv)[pd[31]]; + (*drv)[cd[34]] = + (0.0234375*(*drv)[pd[0]] - 0.0390625*(*drv)[pd[1]] + - 0.03125*(*drv)[pd[4]] - 0.046875*(*drv)[pd[5]] + + 0.09375*(*drv)[pd[6]] + + 0.0625*(-(*drv)[pd[7]] - (*drv)[pd[10]] + + (*drv)[pd[13]] + (*drv)[pd[16]]) + - 0.125*(*drv)[pd[22]] + 0.375*(*drv)[pd[25]] + + 0.1875*((*drv)[pd[28]] - (*drv)[pd[29]] + + (*drv)[pd[31]] - (*drv)[pd[32]]) + + 0.75*(*drv)[pd[34]]); + break; + case 2: + (*drv)[cd[19]] = + (0.0390625*(-(*drv)[pd[0]] - (*drv)[pd[1]]) + + 0.03125*((*drv)[pd[4]] + (*drv)[pd[6]]) + + 0.015625*(*drv)[pd[5]] + + 0.1875*((*drv)[pd[10]] + (*drv)[pd[16]] + - (*drv)[pd[28]] - (*drv)[pd[29]]) + + 0.375*(-(*drv)[pd[11]] - (*drv)[pd[17]]) + + 0.5*((*drv)[pd[12]] + (*drv)[pd[18]]) + + 0.75*(*drv)[pd[30]]); + (*drv)[cd[20]] = (*drv)[pd[30]]; + (*drv)[cd[21]] = + (0.0234375*((*drv)[pd[0]] + (*drv)[pd[1]]) + + 0.09375*(-(*drv)[pd[4]] - (*drv)[pd[6]]) + + 0.140625*(*drv)[pd[5]] + + 0.0625*(-(*drv)[pd[10]] - (*drv)[pd[16]]) + + 0.5625*((*drv)[pd[28]] + (*drv)[pd[29]])); + (*drv)[cd[22]] = + (0.0390625*(-(*drv)[pd[0]] - (*drv)[pd[1]]) + + 0.03125*((*drv)[pd[4]] + (*drv)[pd[6]]) + + 0.015625*(*drv)[pd[5]] + + 0.125*((*drv)[pd[7]] - (*drv)[pd[8]] + (*drv)[pd[13]] + - (*drv)[pd[14]] - (*drv)[pd[31]] - (*drv)[pd[32]]) + + 0.0625*((*drv)[pd[10]] + (*drv)[pd[16]] + - (*drv)[pd[28]] - (*drv)[pd[29]]) + + 0.25*(-(*drv)[pd[22]] - (*drv)[pd[25]] + (*drv)[pd[33]]) + + 0.5*((*drv)[pd[23]] + (*drv)[pd[26]] + (*drv)[pd[34]])); + (*drv)[cd[23]] = + (0.0390625*(-(*drv)[pd[0]] - (*drv)[pd[1]]) + + 0.03125*((*drv)[pd[4]] + (*drv)[pd[6]]) + + 0.015625*(*drv)[pd[5]] + + 0.0625*((*drv)[pd[7]] + (*drv)[pd[13]] + - (*drv)[pd[31]] - (*drv)[pd[32]]) + + 0.125*((*drv)[pd[10]] - (*drv)[pd[11]] + (*drv)[pd[16]] + - (*drv)[pd[17]] - (*drv)[pd[28]] - (*drv)[pd[29]]) + + 0.25*(-(*drv)[pd[22]] - (*drv)[pd[25]] + (*drv)[pd[30]]) + + 0.5*((*drv)[pd[24]] + (*drv)[pd[27]] + (*drv)[pd[34]])); + (*drv)[cd[24]] = (*drv)[pd[34]]; + (*drv)[cd[25]] = + (0.0390625*(-(*drv)[pd[0]] - (*drv)[pd[1]]) + + 0.15625*((*drv)[pd[4]] + (*drv)[pd[6]]) + - 0.234375*(*drv)[pd[5]] + + 0.3125*((*drv)[pd[10]] - (*drv)[pd[29]]) + + 0.0625*(*drv)[pd[16]] + 0.9375*(*drv)[pd[28]]); + (*drv)[cd[26]] = + (0.0234375*(*drv)[pd[0]] - 0.0390625*(*drv)[pd[1]] + - 0.03125*(*drv)[pd[4]] - 0.046875*(*drv)[pd[5]] + + 0.09375*(*drv)[pd[6]] + + 0.125*(-(*drv)[pd[10]] + (*drv)[pd[16]] - (*drv)[pd[17]]) + + 0.375*((*drv)[pd[11]] + (*drv)[pd[28]] - (*drv)[pd[29]]) + + 0.75*(*drv)[pd[30]]); + (*drv)[cd[27]] = (*drv)[pd[28]]; + (*drv)[cd[34]] = + (0.0234375*(*drv)[pd[0]] - 0.0390625*(*drv)[pd[1]] + - 0.03125*(*drv)[pd[4]] - 0.046875*(*drv)[pd[5]] + + 0.09375*(*drv)[pd[6]] + + 0.0625*(-(*drv)[pd[7]] - (*drv)[pd[10]] + + (*drv)[pd[13]] + (*drv)[pd[16]]) + - 0.125*(*drv)[pd[22]] + 0.375*(*drv)[pd[25]] + + 0.1875*((*drv)[pd[28]] - (*drv)[pd[29]] + + (*drv)[pd[31]] - (*drv)[pd[32]]) + + 0.75*(*drv)[pd[34]]); + break; + case 3: + (*drv)[cd[22]] = + (0.0390625*(-(*drv)[pd[0]] - (*drv)[pd[1]]) + + 0.03125*((*drv)[pd[4]] + (*drv)[pd[6]]) + + 0.015625*(*drv)[pd[5]] + + 0.125*((*drv)[pd[7]] - (*drv)[pd[8]] + (*drv)[pd[13]] + - (*drv)[pd[14]] - (*drv)[pd[31]] - (*drv)[pd[32]]) + + 0.0625*((*drv)[pd[10]] + (*drv)[pd[16]] + - (*drv)[pd[28]] - (*drv)[pd[29]]) + + 0.25*(-(*drv)[pd[22]] - (*drv)[pd[25]] + (*drv)[pd[33]]) + + 0.5*((*drv)[pd[23]] + (*drv)[pd[26]] + (*drv)[pd[34]])); + (*drv)[cd[23]] = + (0.0390625*(-(*drv)[pd[0]] - (*drv)[pd[1]]) + + 0.03125*((*drv)[pd[4]] + (*drv)[pd[6]]) + + 0.015625*(*drv)[pd[5]] + + 0.0625*((*drv)[pd[7]] + (*drv)[pd[13]] + - (*drv)[pd[31]] - (*drv)[pd[32]]) + + 0.125*((*drv)[pd[10]] - (*drv)[pd[11]] + (*drv)[pd[16]] + - (*drv)[pd[17]] - (*drv)[pd[28]] - (*drv)[pd[29]]) + + 0.25*(-(*drv)[pd[22]] - (*drv)[pd[25]] + (*drv)[pd[30]]) + + 0.5*((*drv)[pd[24]] + (*drv)[pd[27]] + (*drv)[pd[34]])); + (*drv)[cd[24]] = (*drv)[pd[34]]; + (*drv)[cd[34]] = + (0.0234375*(*drv)[pd[0]] - 0.0390625*(*drv)[pd[1]] + - 0.03125*(*drv)[pd[4]] - 0.046875*(*drv)[pd[5]] + + 0.09375*(*drv)[pd[6]] + + 0.0625*(-(*drv)[pd[7]] - (*drv)[pd[10]] + + (*drv)[pd[13]] + (*drv)[pd[16]]) + - 0.125*(*drv)[pd[22]] + 0.375*(*drv)[pd[25]] + + 0.1875*((*drv)[pd[28]] - (*drv)[pd[29]] + + (*drv)[pd[31]] - (*drv)[pd[32]]) + + 0.75*(*drv)[pd[34]]); + break; + } + + /****************************************************************************/ + /* values on child[1] */ + /****************************************************************************/ + + cd = basFct->getLocalIndices(el->getChild(1), admin, NULL); + + if (typ == 0) + { + switch(lr_set) + { + case 1: + (*drv)[cd[25]] = + (0.0390625*(-(*drv)[pd[0]] - (*drv)[pd[1]]) + + 0.15625*((*drv)[pd[4]] + (*drv)[pd[6]]) + - 0.234375*(*drv)[pd[5]] + 0.0625*(*drv)[pd[7]] + + 0.3125*((*drv)[pd[13]] - (*drv)[pd[31]]) + + 0.9375*(*drv)[pd[32]]); + (*drv)[cd[26]] = + (-0.0390625*(*drv)[pd[0]] + 0.0234375*(*drv)[pd[1]] + + 0.09375*(*drv)[pd[4]] - 0.046875*(*drv)[pd[5]] + - 0.03125*(*drv)[pd[6]] + + 0.125*((*drv)[pd[7]] - (*drv)[pd[8]] - (*drv)[pd[13]]) + + 0.375*((*drv)[pd[14]] - (*drv)[pd[31]] + (*drv)[pd[32]]) + + 0.75*(*drv)[pd[33]]); + (*drv)[cd[27]] = (*drv)[pd[32]]; + (*drv)[cd[34]] = + (-0.0390625*(*drv)[pd[0]] + 0.0234375*(*drv)[pd[1]] + + 0.09375*(*drv)[pd[4]] - 0.046875*(*drv)[pd[5]] + - 0.03125*(*drv)[pd[6]] + + 0.0625*((*drv)[pd[7]] + (*drv)[pd[10]] + - (*drv)[pd[13]] - (*drv)[pd[16]]) + + 0.375*(*drv)[pd[22]] - 0.125*(*drv)[pd[25]] + + 0.1875*(-(*drv)[pd[28]] + (*drv)[pd[29]] + - (*drv)[pd[31]] + (*drv)[pd[32]]) + + 0.75*(*drv)[pd[34]]); + break; + case 2: + (*drv)[cd[28]] = + (0.0390625*(-(*drv)[pd[0]] - (*drv)[pd[1]]) + + 0.15625*((*drv)[pd[4]] + (*drv)[pd[6]]) + - 0.234375*(*drv)[pd[5]] + 0.0625*(*drv)[pd[10]] + + 0.3125*((*drv)[pd[16]] - (*drv)[pd[28]]) + + 0.9375*(*drv)[pd[29]]); + (*drv)[cd[29]] = + (-0.0390625*(*drv)[pd[0]] + 0.0234375*(*drv)[pd[1]] + + 0.09375*(*drv)[pd[4]] - 0.046875*(*drv)[pd[5]] + - 0.03125*(*drv)[pd[6]] + + 0.125*((*drv)[pd[10]] - (*drv)[pd[11]] - (*drv)[pd[16]]) + + 0.375*((*drv)[pd[17]] - (*drv)[pd[28]] + (*drv)[pd[29]]) + + 0.75*(*drv)[pd[30]]); + (*drv)[cd[30]] = (*drv)[pd[29]]; + (*drv)[cd[34]] = + (-0.0390625*(*drv)[pd[0]] + 0.0234375*(*drv)[pd[1]] + + 0.09375*(*drv)[pd[4]] - 0.046875*(*drv)[pd[5]] + - 0.03125*(*drv)[pd[6]] + + 0.0625*((*drv)[pd[7]] + (*drv)[pd[10]] + - (*drv)[pd[13]] - (*drv)[pd[16]]) + + 0.375*(*drv)[pd[22]] - 0.125*(*drv)[pd[25]] + + 0.1875*(-(*drv)[pd[28]] + (*drv)[pd[29]] + - (*drv)[pd[31]] + (*drv)[pd[32]]) + + 0.75*(*drv)[pd[34]]); + break; + case 3: + (*drv)[cd[34]] = + (-0.0390625*(*drv)[pd[0]] + 0.0234375*(*drv)[pd[1]] + + 0.09375*(*drv)[pd[4]] - 0.046875*(*drv)[pd[5]] + - 0.03125*(*drv)[pd[6]] + + 0.0625*((*drv)[pd[7]] + (*drv)[pd[10]] + - (*drv)[pd[13]] - (*drv)[pd[16]]) + + 0.375*(*drv)[pd[22]] - 0.125*(*drv)[pd[25]] + + 0.1875*(-(*drv)[pd[28]] + (*drv)[pd[29]] + - (*drv)[pd[31]] + (*drv)[pd[32]]) + + 0.75*(*drv)[pd[34]]); + break; + } + } else { + switch(lr_set) { + case 1: + (*drv)[cd[28]] = + (0.0390625*(-(*drv)[pd[0]] - (*drv)[pd[1]]) + + 0.15625*((*drv)[pd[4]] + (*drv)[pd[6]]) + - 0.234375*(*drv)[pd[5]] + 0.0625*(*drv)[pd[7]] + + 0.3125*((*drv)[pd[13]] - (*drv)[pd[31]]) + + 0.9375*(*drv)[pd[32]]); + (*drv)[cd[29]] = + (-0.0390625*(*drv)[pd[0]] + 0.0234375*(*drv)[pd[1]] + + 0.09375*(*drv)[pd[4]] - 0.046875*(*drv)[pd[5]] + - 0.03125*(*drv)[pd[6]] + + 0.125*((*drv)[pd[7]] - (*drv)[pd[8]] - (*drv)[pd[13]]) + + 0.375*((*drv)[pd[14]] - (*drv)[pd[31]] + (*drv)[pd[32]]) + + 0.75*(*drv)[pd[33]]); + (*drv)[cd[30]] = (*drv)[pd[32]]; + (*drv)[cd[34]] = + (-0.0390625*(*drv)[pd[0]] + 0.0234375*(*drv)[pd[1]] + + 0.09375*(*drv)[pd[4]] - 0.046875*(*drv)[pd[5]] + - 0.03125*(*drv)[pd[6]] + + 0.0625*((*drv)[pd[7]] + (*drv)[pd[10]] + - (*drv)[pd[13]] - (*drv)[pd[16]]) + + 0.375*(*drv)[pd[22]] - 0.125*(*drv)[pd[25]] + + 0.1875*(-(*drv)[pd[28]] + (*drv)[pd[29]] + - (*drv)[pd[31]] + (*drv)[pd[32]]) + + 0.75*(*drv)[pd[34]]); + break; + case 2: + (*drv)[cd[25]] = + (0.0390625*(-(*drv)[pd[0]] - (*drv)[pd[1]]) + + 0.15625*((*drv)[pd[4]] + (*drv)[pd[6]]) + - 0.234375*(*drv)[pd[5]] + 0.0625*(*drv)[pd[10]] + + 0.3125*((*drv)[pd[16]] - (*drv)[pd[28]]) + + 0.9375*(*drv)[pd[29]]); + (*drv)[cd[26]] = + (-0.0390625*(*drv)[pd[0]] + 0.0234375*(*drv)[pd[1]] + + 0.09375*(*drv)[pd[4]] - 0.046875*(*drv)[pd[5]] + - 0.03125*(*drv)[pd[6]] + + 0.125*((*drv)[pd[10]] - (*drv)[pd[11]] - (*drv)[pd[16]]) + + 0.375*((*drv)[pd[17]] - (*drv)[pd[28]] + (*drv)[pd[29]]) + + 0.75*(*drv)[pd[30]]); + (*drv)[cd[27]] = (*drv)[pd[29]]; + (*drv)[cd[34]] = + (-0.0390625*(*drv)[pd[0]] + 0.0234375*(*drv)[pd[1]] + + 0.09375*(*drv)[pd[4]] - 0.046875*(*drv)[pd[5]] + - 0.03125*(*drv)[pd[6]] + + 0.0625*((*drv)[pd[7]] + (*drv)[pd[10]] + - (*drv)[pd[13]] - (*drv)[pd[16]]) + + 0.375*(*drv)[pd[22]] - 0.125*(*drv)[pd[25]] + + 0.1875*(-(*drv)[pd[28]] + (*drv)[pd[29]] + - (*drv)[pd[31]] + (*drv)[pd[32]]) + + 0.75*(*drv)[pd[34]]); + break; + case 3: + (*drv)[cd[34]] = + (-0.0390625*(*drv)[pd[0]] + 0.0234375*(*drv)[pd[1]] + + 0.09375*(*drv)[pd[4]] - 0.046875*(*drv)[pd[5]] + - 0.03125*(*drv)[pd[6]] + + 0.0625*((*drv)[pd[7]] + (*drv)[pd[10]] + - (*drv)[pd[13]] - (*drv)[pd[16]]) + + 0.375*(*drv)[pd[22]] - 0.125*(*drv)[pd[25]] + + 0.1875*(-(*drv)[pd[28]] + (*drv)[pd[29]] + - (*drv)[pd[31]] + (*drv)[pd[32]]) + + 0.75*(*drv)[pd[34]]); + break; + } + } + } + + return; + } + + // ============ coarseRestrict fcts ================== + + void Lagrange::coarseRestr0(DOFIndexed<double> *drv, + RCNeighbourList *list, + int n, BasisFunction* basFct) + { + FUNCNAME("Lagrange::coarseRestr0"); + Element *el; + DegreeOfFreedom dof_new, dof0, dof1; + int n0; + + if (n < 1) return; + + n0 = drv->getFESpace()->getAdmin()->getNumberOfPreDOFs(CENTER); + el = list->getElement(0); + dof0 = el->getDOF(0,n0); /* 1st endpoint of refinement edge */ + dof1 = el->getDOF(1,n0); /* 2nd endpoint of refinement edge */ + dof_new = el->getChild(0)->getDOF(basFct->getDim(), n0); + /* newest vertex is DIM */ + (*drv)[dof0] += 0.5*(*drv)[dof_new]; + (*drv)[dof1] += 0.5*(*drv)[dof_new]; + } + + void Lagrange::coarseRestr1(DOFIndexed<double> *drv, + RCNeighbourList *list, + int n, BasisFunction* basFct) + { + FUNCNAME("Lagrange::coarseRestr1"); + Element *el; + DegreeOfFreedom dof_new, dof0, dof1; + int n0; + + if (n < 1) return; + + n0 = drv->getFESpace()->getAdmin()->getNumberOfPreDOFs(VERTEX); + el = list->getElement(0); + dof0 = el->getDOF(0,n0); /* 1st endpoint of refinement edge */ + dof1 = el->getDOF(1,n0); /* 2nd endpoint of refinement edge */ + dof_new = el->getChild(0)->getDOF(basFct->getDim(), n0); + /* newest vertex is DIM */ + (*drv)[dof0] += 0.5*(*drv)[dof_new]; + (*drv)[dof1] += 0.5*(*drv)[dof_new]; + } + + void Lagrange::coarseRestr2_2d(DOFIndexed<double> *drv, RCNeighbourList *list, + int n, BasisFunction* basFct) + { + FUNCNAME("Lagrange::coarseRestr2_2d"); + Element *el; + int node, n0; + DegreeOfFreedom cdof2, cdof3, cdof4; + const DegreeOfFreedom *pdof; + const DOFAdmin *admin; + + if (n < 1) return; + el = list->getElement(0); + + if (!drv->getFESpace()) + { + ERROR("no fe_space in dof_real_vec\n"); + return; + } + else if (!drv->getFESpace()->getBasisFcts()) + { + ERROR("no basis functions in fe_space %s\n", + drv->getFESpace()->getName().c_str()); + return; + } + + admin = drv->getFESpace()->getAdmin(); + + pdof = basFct->getLocalIndices(el, admin, NULL); + + /****************************************************************************/ + /* contributions of dofs located on child[0] */ + /****************************************************************************/ + + node = drv->getFESpace()->getMesh()->getNode(VERTEX); + n0 = admin->getNumberOfPreDOFs(VERTEX); + cdof2 = el->getChild(0)->getDOF(node+2, n0); + + node = drv->getFESpace()->getMesh()->getNode(EDGE); + n0 = admin->getNumberOfPreDOFs(EDGE); + cdof3 = el->getChild(0)->getDOF(node, n0); + cdof4 = el->getChild(0)->getDOF(node+1, n0); + + (*drv)[pdof[0]] += 0.375*(*drv)[cdof3] - 0.125*(*drv)[cdof4]; + (*drv)[pdof[1]] += -0.125*((*drv)[cdof3] + (*drv)[cdof4]); + (*drv)[pdof[3]] += 0.5*(*drv)[cdof4]; + (*drv)[pdof[4]] += 0.5*(*drv)[cdof4]; + (*drv)[pdof[5]] = (*drv)[cdof2] + 0.75*(*drv)[cdof3] + 0.25*(*drv)[cdof4]; + + /****************************************************************************/ + /* contributions of dofs located on child[1] and not on child[0] */ + /****************************************************************************/ + + cdof4 = el->getChild(1)->getDOF(node+1, n0); + + (*drv)[pdof[0]] += -0.125*(*drv)[cdof4]; + (*drv)[pdof[1]] += 0.375*(*drv)[cdof4]; + (*drv)[pdof[5]] += 0.75*(*drv)[cdof4]; + + if (n > 1) + { + el = list->getElement(1); + pdof = basFct->getLocalIndices(el, admin, NULL); + + /****************************************************************************/ + /* first set those values not effected by previous element */ + /****************************************************************************/ + + cdof4 = el->getChild(0)->getDOF(node+1, n0); + (*drv)[pdof[3]] += 0.5*(*drv)[cdof4]; + (*drv)[pdof[4]] += 0.5*(*drv)[cdof4]; + + /****************************************************************************/ + /* and now, update the values in the refinement edge */ + /****************************************************************************/ + + (*drv)[pdof[0]] += -0.125*(*drv)[cdof4]; + (*drv)[pdof[1]] += -0.125*(*drv)[cdof4]; + (*drv)[pdof[5]] += 0.25*(*drv)[cdof4]; + } + return; + } + + + void Lagrange::coarseRestr2_3d(DOFIndexed<double> *drv, RCNeighbourList *list, + int n, BasisFunction* basFct) + { + FUNCNAME("Lagrange::coarseRestr2_3d"); + Element *el; + const DegreeOfFreedom *cdof; + DegreeOfFreedom pdof[10], cdofi; + int i, lr_set; + int node0, n0; + const DOFAdmin *admin; + + if (n < 1) return; + el = list->getElement(0); + + if (!drv->getFESpace()) + { + ERROR("no fe_space in dof_real_vec\n"); + return; + } + else if (!drv->getFESpace()->getBasisFcts()) + { + ERROR("no basis functions in fe_space %s\n", + drv->getFESpace()->getName().c_str()); + return; + } + + admin = drv->getFESpace()->getAdmin(); + + basFct->getLocalIndices(el, admin, pdof); + + node0 = drv->getFESpace()->getMesh()->getNode(EDGE); + n0 = admin->getNumberOfPreDOFs(EDGE); + + /****************************************************************************/ + /* values on child[0] */ + /****************************************************************************/ + + cdof = basFct->getLocalIndices(el->getChild(0), admin, NULL); + + (*drv)[pdof[0]] += + (0.375*(*drv)[cdof[6]] + 0.125*(-(*drv)[cdof[8]] - (*drv)[cdof[9]])); + (*drv)[pdof[1]] += + (0.125*(-(*drv)[cdof[6]] - (*drv)[cdof[8]] - (*drv)[cdof[9]])); + (*drv)[pdof[4]] = + ((*drv)[cdof[3]] + 0.75*(*drv)[cdof[6]] + + 0.25*((*drv)[cdof[8]] + (*drv)[cdof[9]])); + (*drv)[pdof[5]] += + (0.5*(*drv)[cdof[8]]); + (*drv)[pdof[6]] += + (0.5*(*drv)[cdof[9]]); + (*drv)[pdof[7]] += + (0.5*(*drv)[cdof[8]]); + (*drv)[pdof[8]] += + (0.5*(*drv)[cdof[9]]); + + /****************************************************************************/ + /* values on child[1] */ + /****************************************************************************/ + + cdof = basFct->getLocalIndices(el->getChild(1), admin, NULL); + cdofi = el->getChild(1)->getDOF(node0+2, n0); + + (*drv)[pdof[0]] += (-0.125*(*drv)[cdofi]); + (*drv)[pdof[1]] += (0.375*(*drv)[cdofi]); + (*drv)[pdof[4]] += (0.75*(*drv)[cdofi]); + + /****************************************************************************/ + /* adjust neighbour values */ + /****************************************************************************/ + + for (i = 1; i < n; i++) + { + el = list->getElement(i); + basFct->getLocalIndices(el, admin, pdof); + + lr_set = 0; + if (list->getNeighbourElement(i,0) && list->getNeighbourNr(i,0) < i) + lr_set = 1; + + if (list->getNeighbourElement(i,1) && list->getNeighbourNr(i,1) < i) + lr_set += 2; + + TEST_EXIT(lr_set)("no values set on both neighbours\n"); + + /****************************************************************************/ + /* values on child[0] */ + /****************************************************************************/ + + cdof = basFct->getLocalIndices(el->getChild(0), admin, NULL); + + switch(lr_set) + { + case 1: + cdofi = el->getChild(0)->getDOF(node0+4, n0); + (*drv)[pdof[0]] += (-0.125*(*drv)[cdofi]); + (*drv)[pdof[1]] += (-0.125*(*drv)[cdofi]); + (*drv)[pdof[4]] += (0.25*(*drv)[cdofi]); + (*drv)[pdof[5]] += (0.5*(*drv)[cdofi]); + (*drv)[pdof[7]] += (0.5*(*drv)[cdofi]); + break; + case 2: + cdofi = el->getChild(0)->getDOF(node0+5, n0); + (*drv)[pdof[0]] += (-0.125*(*drv)[cdofi]); + (*drv)[pdof[1]] += (-0.125*(*drv)[cdofi]); + (*drv)[pdof[4]] += (0.25*(*drv)[cdofi]); + (*drv)[pdof[6]] += (0.5*(*drv)[cdofi]); + (*drv)[pdof[8]] += (0.5*(*drv)[cdofi]); + break; + } + } + return; + } + + + void Lagrange::coarseRestr3_1d(DOFIndexed<double> *drv, RCNeighbourList *list, + int n, BasisFunction* basFct) + { + FUNCNAME("Lagrange::coarseRestr3_1d"); + Element *el; + int node, n0; + const DegreeOfFreedom *cdof; + DegreeOfFreedom pdof[4], dof9; + const DOFAdmin *admin; + + if (n < 1) return; + el = list->getElement(0); + + if (!drv->getFESpace()) + { + ERROR("no fe_space in dof_real_vec\n"); + return; + } + else if (!drv->getFESpace()->getBasisFcts()) + { + ERROR("no basis functions in fe_space %s\n", + drv->getFESpace()->getName().c_str()); + return; + } + + admin = drv->getFESpace()->getAdmin(); + + basFct->getLocalIndices(el, admin, pdof); + + /****************************************************************************/ + /* values on child[0] */ + /****************************************************************************/ + cdof = basFct->getLocalIndices(el->getChild(0), admin, NULL); + + (*drv)[pdof[0]] += + (0.0625*(-(*drv)[cdof[2]] + (*drv)[cdof[6]] - (*drv)[cdof[9]]) + + 0.3125*(*drv)[cdof[3]]); + (*drv)[pdof[1]] += + 0.0625*(-(*drv)[cdof[2]] + (*drv)[cdof[3]] + + (*drv)[cdof[6]] + (*drv)[cdof[9]]); + (*drv)[pdof[3]] += + -0.25*(*drv)[cdof[6]] - 0.125*(*drv)[cdof[9]]; + (*drv)[pdof[4]] += + 0.5*(*drv)[cdof[6]]; + (*drv)[pdof[5]] += + 0.5*(*drv)[cdof[6]]; + (*drv)[pdof[6]] += + -0.25*(*drv)[cdof[6]] + 0.375*(*drv)[cdof[9]]; + (*drv)[pdof[7]] = + (0.5625*(*drv)[cdof[2]] + 0.9375*(*drv)[cdof[3]] + (*drv)[cdof[4]] + - 0.0625*(*drv)[cdof[6]] + 0.1875*(*drv)[cdof[9]]); + (*drv)[pdof[8]] = + (0.5625*(*drv)[cdof[2]] - 0.3125*(*drv)[cdof[3]] + - 0.0625*(*drv)[cdof[6]] - 0.1875*(*drv)[cdof[9]]); + (*drv)[pdof[9]] = + (*drv)[cdof[5]] + 0.5*(*drv)[cdof[6]] + 0.75*(*drv)[cdof[9]]; + + /****************************************************************************/ + /* values on child[1] */ + /****************************************************************************/ + + cdof = basFct->getLocalIndices(el->getChild(1), admin, NULL); + + (*drv)[pdof[0]] += 0.0625*(*drv)[cdof[6]] + 0.0625*(*drv)[cdof[9]]; + (*drv)[pdof[1]] += 0.3125*(*drv)[cdof[6]] - 0.0625*(*drv)[cdof[9]]; + (*drv)[pdof[3]] += 0.375*(*drv)[cdof[9]]; + (*drv)[pdof[6]] += -0.125*(*drv)[cdof[9]]; + (*drv)[pdof[7]] += -0.3125*(*drv)[cdof[6]] - 0.18750*(*drv)[cdof[9]]; + (*drv)[pdof[8]] += + (*drv)[cdof[5]] + 0.9375*(*drv)[cdof[6]] + 0.1875*(*drv)[cdof[9]]; + (*drv)[pdof[9]] += 0.75*(*drv)[cdof[9]]; + + if (n <= 1) return; + + /****************************************************************************/ + /* adjust the value on the neihgbour */ + /****************************************************************************/ + + el = list->getElement(1); + basFct->getLocalIndices(el, admin, pdof); + + /****************************************************************************/ + /* values on neigh's child[0] */ + /****************************************************************************/ + cdof = basFct->getLocalIndices(el->getChild(0), admin, NULL); + + (*drv)[pdof[0]] += 0.0625*((*drv)[cdof[6]] - (*drv)[cdof[9]]); + (*drv)[pdof[1]] += 0.0625*((*drv)[cdof[6]] + (*drv)[cdof[9]]); + (*drv)[pdof[3]] += -0.25*(*drv)[cdof[6]] - 0.12500*(*drv)[cdof[9]]; + (*drv)[pdof[4]] += 0.5*(*drv)[cdof[6]]; + (*drv)[pdof[5]] += 0.5*(*drv)[cdof[6]]; + (*drv)[pdof[6]] += -0.25*(*drv)[cdof[6]] + 0.375*(*drv)[cdof[9]]; + (*drv)[pdof[7]] += -0.0625*(*drv)[cdof[6]] + 0.1875*(*drv)[cdof[9]]; + (*drv)[pdof[8]] += -0.0625*(*drv)[cdof[6]] - 0.1875*(*drv)[cdof[9]]; + (*drv)[pdof[9]] = + (*drv)[cdof[5]] + 0.5*(*drv)[cdof[6]] + 0.75*(*drv)[cdof[9]]; + + /****************************************************************************/ + /* values on neigh's child[1] */ + /****************************************************************************/ + + node = drv->getFESpace()->getMesh()->getNode(CENTER); + n0 = admin->getNumberOfPreDOFs(CENTER); + dof9 = el->getChild(1)->getDOF(node, n0); + + (*drv)[pdof[0]] += 0.0625*(*drv)[dof9]; + (*drv)[pdof[1]] -= 0.0625*(*drv)[dof9]; + (*drv)[pdof[3]] += 0.375*(*drv)[dof9]; + (*drv)[pdof[6]] -= 0.125*(*drv)[dof9]; + (*drv)[pdof[7]] -= 0.1875*(*drv)[dof9]; + (*drv)[pdof[8]] += 0.1875*(*drv)[dof9]; + (*drv)[pdof[9]] += 0.75*(*drv)[dof9]; + + return; + } + + void Lagrange::coarseRestr3_2d(DOFIndexed<double> *drv, RCNeighbourList *list, + int n, BasisFunction* basFct) + { + FUNCNAME("Lagrange::coarseRestr3_2d"); + const Element *el; + int node, n0; + const DegreeOfFreedom *cdof; + DegreeOfFreedom pdof[10], dof9; + const DOFAdmin *admin; + + if (n < 1) return; + el = list->getElement(0); + + if (!drv->getFESpace()) + { + ERROR("no fe_space in dof_real_vec\n"); + return; + } + else if (!drv->getFESpace()->getBasisFcts()) + { + ERROR("no basis functions in fe_space %s\n", + drv->getFESpace()->getName().c_str()); + return; + } + admin = drv->getFESpace()->getAdmin(); + + basFct->getLocalIndices(el, admin, pdof); + + /****************************************************************************/ + /* values on child[0] */ + /****************************************************************************/ + cdof = basFct->getLocalIndices(el->getChild(0), admin, NULL); + + (*drv)[pdof[0]] += + (0.0625*(-(*drv)[cdof[2]] + (*drv)[cdof[6]] - (*drv)[cdof[9]]) + + 0.3125*(*drv)[cdof[3]]); + (*drv)[pdof[1]] += + 0.0625*(-(*drv)[cdof[2]] + (*drv)[cdof[3]] + + (*drv)[cdof[6]] + (*drv)[cdof[9]]); + (*drv)[pdof[3]] += -0.25*(*drv)[cdof[6]] - 0.125*(*drv)[cdof[9]]; + (*drv)[pdof[4]] += 0.5*(*drv)[cdof[6]]; + (*drv)[pdof[5]] += 0.5*(*drv)[cdof[6]]; + (*drv)[pdof[6]] += -0.25*(*drv)[cdof[6]] + 0.375*(*drv)[cdof[9]]; + (*drv)[pdof[7]] = + (0.5625*(*drv)[cdof[2]] + 0.9375*(*drv)[cdof[3]] + (*drv)[cdof[4]] + - 0.0625*(*drv)[cdof[6]] + 0.1875*(*drv)[cdof[9]]); + (*drv)[pdof[8]] = + (0.5625*(*drv)[cdof[2]] - 0.3125*(*drv)[cdof[3]] + - 0.0625*(*drv)[cdof[6]] - 0.1875*(*drv)[cdof[9]]); + (*drv)[pdof[9]] = + (*drv)[cdof[5]] + 0.5*(*drv)[cdof[6]] + 0.75*(*drv)[cdof[9]]; + + /****************************************************************************/ + /* values on child[1] */ + /****************************************************************************/ + + cdof = basFct->getLocalIndices(el->getChild(1), admin, NULL); + + (*drv)[pdof[0]] += 0.0625*(*drv)[cdof[6]] + 0.0625*(*drv)[cdof[9]]; + (*drv)[pdof[1]] += 0.3125*(*drv)[cdof[6]] - 0.0625*(*drv)[cdof[9]]; + (*drv)[pdof[3]] += 0.375*(*drv)[cdof[9]]; + (*drv)[pdof[6]] += -0.125*(*drv)[cdof[9]]; + (*drv)[pdof[7]] += -0.3125*(*drv)[cdof[6]] - 0.18750*(*drv)[cdof[9]]; + (*drv)[pdof[8]] += + (*drv)[cdof[5]] + 0.9375*(*drv)[cdof[6]] + 0.1875*(*drv)[cdof[9]]; + (*drv)[pdof[9]] += 0.75*(*drv)[cdof[9]]; + + if (n <= 1) return; + + /****************************************************************************/ + /* adjust the value on the neihgbour */ + /****************************************************************************/ + + el = list->getElement(1); + basFct->getLocalIndices(el, admin, pdof); + + /****************************************************************************/ + /* values on neigh's child[0] */ + /****************************************************************************/ + cdof = basFct->getLocalIndices(el->getChild(0), admin, NULL); + + (*drv)[pdof[0]] += 0.0625*((*drv)[cdof[6]] - (*drv)[cdof[9]]); + (*drv)[pdof[1]] += 0.0625*((*drv)[cdof[6]] + (*drv)[cdof[9]]); + (*drv)[pdof[3]] += -0.25*(*drv)[cdof[6]] - 0.12500*(*drv)[cdof[9]]; + (*drv)[pdof[4]] += 0.5*(*drv)[cdof[6]]; + (*drv)[pdof[5]] += 0.5*(*drv)[cdof[6]]; + (*drv)[pdof[6]] += -0.25*(*drv)[cdof[6]] + 0.375*(*drv)[cdof[9]]; + (*drv)[pdof[7]] += -0.0625*(*drv)[cdof[6]] + 0.1875*(*drv)[cdof[9]]; + (*drv)[pdof[8]] += -0.0625*(*drv)[cdof[6]] - 0.1875*(*drv)[cdof[9]]; + (*drv)[pdof[9]] = + (*drv)[cdof[5]] + 0.5*(*drv)[cdof[6]] + 0.75*(*drv)[cdof[9]]; + + /****************************************************************************/ + /* values on neigh's child[1] */ + /****************************************************************************/ + + node = drv->getFESpace()->getMesh()->getNode(CENTER); + n0 = admin->getNumberOfPreDOFs(CENTER); + dof9 = el->getChild(1)->getDOF(node, n0); + + (*drv)[pdof[0]] += 0.0625*(*drv)[dof9]; + (*drv)[pdof[1]] -= 0.0625*(*drv)[dof9]; + (*drv)[pdof[3]] += 0.375*(*drv)[dof9]; + (*drv)[pdof[6]] -= 0.125*(*drv)[dof9]; + (*drv)[pdof[7]] -= 0.1875*(*drv)[dof9]; + (*drv)[pdof[8]] += 0.1875*(*drv)[dof9]; + (*drv)[pdof[9]] += 0.75*(*drv)[dof9]; + + return; + } + + void Lagrange::coarseRestr3_3d(DOFIndexed<double> *drv, RCNeighbourList *list, + int n, BasisFunction* basFct) + { + FUNCNAME("Lagrange::coarseRestr3_3d"); + const Element *el; + const DegreeOfFreedom *cd; + DegreeOfFreedom pd[19], cdi; + int node0, n0, i, typ, lr_set; + const DOFAdmin *admin; + + if (n < 1) return; + el = list->getElement(0); + typ = list->getType(0); + + if (!drv->getFESpace()) + { + ERROR("no fe_space in dof_real_vec\n"); + return; + } + else if (!drv->getFESpace()->getBasisFcts()) + { + ERROR("no basis functions in fe_space %s\n", + drv->getFESpace()->getName().c_str()); + return; + } + + admin = drv->getFESpace()->getAdmin(); + + basFct->getLocalIndices(el, admin, pd); + + /****************************************************************************/ + /* values on child[0] */ + /****************************************************************************/ + + cd = basFct->getLocalIndices(el->getChild(0), admin, NULL); + + (*drv)[pd[0]] += + (0.0625*(-(*drv)[cd[3]] + (*drv)[cd[12]] + (*drv)[cd[14]] + + (*drv)[cd[16]] - (*drv)[cd[17]] - (*drv)[cd[18]]) + + 0.3125*(*drv)[cd[8]]); + (*drv)[pd[1]] += + (0.0625*(-(*drv)[cd[3]] + (*drv)[cd[8]] + (*drv)[cd[12]] + (*drv)[cd[14]] + + (*drv)[cd[16]] + (*drv)[cd[17]] + (*drv)[cd[18]])); + (*drv)[pd[4]] = + ((*drv)[cd[9]] + 0.5625*(*drv)[cd[3]] + 0.9375*(*drv)[cd[8]] + + 0.0625*(-(*drv)[cd[12]] - (*drv)[cd[14]] - (*drv)[cd[16]]) + + 0.1875*((*drv)[cd[17]] + (*drv)[cd[18]])); + (*drv)[pd[5]] = + (0.5625*(*drv)[cd[3]] - 0.3125*(*drv)[cd[8]] + + 0.0625*(-(*drv)[cd[12]] - (*drv)[cd[14]] - (*drv)[cd[16]]) + + 0.1875*(-(*drv)[cd[17]] - (*drv)[cd[18]])); + (*drv)[pd[6]] += + (-0.25*(*drv)[cd[12]] - 0.125*(*drv)[cd[16]] + 0.375*(*drv)[cd[18]]); + (*drv)[pd[7]] += 0.5*(*drv)[cd[12]]; + (*drv)[pd[8]] += + (-0.25*(*drv)[cd[14]] - 0.125*(*drv)[cd[16]] + 0.375*(*drv)[cd[17]]); + (*drv)[pd[9]] += 0.5*(*drv)[cd[14]]; + (*drv)[pd[10]] += + (-0.25*(*drv)[cd[12]] + 0.125*(-(*drv)[cd[16]] - (*drv)[cd[18]])); + (*drv)[pd[11]] += 0.5*(*drv)[cd[12]]; + (*drv)[pd[12]] += + (-0.25*(*drv)[cd[14]] + 0.125*(-(*drv)[cd[16]] - (*drv)[cd[17]])); + (*drv)[pd[13]] += 0.5*(*drv)[cd[14]]; + (*drv)[pd[16]] += 0.5*(*drv)[cd[16]]; + (*drv)[pd[17]] += 0.5*(*drv)[cd[16]]; + (*drv)[pd[18]] = + ((*drv)[cd[15]] + 0.5*(*drv)[cd[14]] + 0.25*(*drv)[cd[16]] + + 0.75*(*drv)[cd[17]]); + (*drv)[pd[19]] = + ((*drv)[cd[13]] + 0.5*(*drv)[cd[12]] + 0.25*(*drv)[cd[16]] + + 0.75*(*drv)[cd[18]]); + + /****************************************************************************/ + /* values on child[1] */ + /****************************************************************************/ + + cd = basFct->getLocalIndices(el->getChild(1), admin, NULL); + + if (typ == 0) + { + /****************************************************************************/ + /* parent of el_type 0 */ + /****************************************************************************/ + + (*drv)[pd[0]] += 0.0625*((*drv)[cd[8]] + (*drv)[cd[17]] + (*drv)[cd[18]]); + (*drv)[pd[1]] += + 0.3125*(*drv)[cd[8]] + 0.0625*(-(*drv)[cd[17]] - (*drv)[cd[18]]); + (*drv)[pd[4]] += + -0.3125*(*drv)[cd[8]] + 0.1875*(-(*drv)[cd[17]] - (*drv)[cd[18]]); + (*drv)[pd[5]] += + ((*drv)[cd[9]] + 0.9375*(*drv)[cd[8]] + + 0.1875*((*drv)[cd[17]] + (*drv)[cd[18]])); + (*drv)[pd[6]] += -0.125*(*drv)[cd[17]]; + (*drv)[pd[8]] += -0.125*(*drv)[cd[18]]; + (*drv)[pd[10]] += 0.375*(*drv)[cd[17]]; + (*drv)[pd[12]] += 0.375*(*drv)[cd[18]]; + (*drv)[pd[18]] += 0.75*(*drv)[cd[18]]; + (*drv)[pd[19]] += 0.750000*(*drv)[cd[17]]; + } else { + /****************************************************************************/ + /* parent of el_type 1|2 */ + /****************************************************************************/ + + (*drv)[pd[0]] += 0.0625*((*drv)[cd[8]] + (*drv)[cd[17]] + (*drv)[cd[18]]); + (*drv)[pd[1]] += + 0.3125*(*drv)[cd[8]] + 0.0625*(-(*drv)[cd[17]] - (*drv)[cd[18]]); + (*drv)[pd[4]] += + -0.3125*(*drv)[cd[8]] + 0.1875*(-(*drv)[cd[17]] - (*drv)[cd[18]]); + (*drv)[pd[5]] += + ((*drv)[cd[9]] + 0.9375*(*drv)[cd[8]] + + 0.1875*((*drv)[cd[17]] + (*drv)[cd[18]])); + (*drv)[pd[6]] += -0.125*(*drv)[cd[18]]; + (*drv)[pd[8]] += -0.125*(*drv)[cd[17]]; + (*drv)[pd[10]] += 0.375*(*drv)[cd[18]]; + (*drv)[pd[12]] += 0.375*(*drv)[cd[17]]; + (*drv)[pd[18]] += 0.75*(*drv)[cd[17]]; + (*drv)[pd[19]] += 0.75*(*drv)[cd[18]]; + } + + /****************************************************************************/ + /* adjust neighbour values */ + /****************************************************************************/ + + node0 = drv->getFESpace()->getMesh()->getNode(FACE); + n0 = admin->getNumberOfPreDOFs(FACE); + + for (i = 1; i < n; i++) + { + el = list->getElement(i); + typ = list->getType(i); + basFct->getLocalIndices(el, admin, pd); + + lr_set = 0; + if (list->getNeighbourElement(i, 0) && list->getNeighbourNr(i, 0) < i) + lr_set = 1; + + if (list->getNeighbourElement(i, 1) && list->getNeighbourNr(i, 1) < i) + lr_set += 2; + + TEST_EXIT(lr_set)("no values set on both neighbours\n"); + + /****************************************************************************/ + /* values on child[0] */ + /****************************************************************************/ + + cd = basFct->getLocalIndices(el->getChild(0), admin, NULL); + cdi = cd[16]; + + switch(lr_set) + { + case 1: + (*drv)[pd[0]] += 0.0625*((*drv)[cd[12]] + (*drv)[cdi] - (*drv)[cd[18]]); + (*drv)[pd[1]] += 0.0625*((*drv)[cd[12]] + (*drv)[cdi] + (*drv)[cd[18]]); + (*drv)[pd[4]] += + (0.0625*(-(*drv)[cd[12]] - (*drv)[cdi]) + 0.1875*(*drv)[cd[18]]); + (*drv)[pd[5]] += + (0.0625*(-(*drv)[cd[12]] - (*drv)[cdi]) - 0.1875*(*drv)[cd[18]]); + (*drv)[pd[6]] += + (-0.25*(*drv)[cd[12]] - 0.125*(*drv)[cdi] + 0.375*(*drv)[cd[18]]); + (*drv)[pd[7]] += 0.5*(*drv)[cd[12]]; + (*drv)[pd[8]] += -0.125*(*drv)[cdi]; + (*drv)[pd[10]] += + -0.25*(*drv)[cd[12]] + 0.125*(-(*drv)[cdi] - (*drv)[cd[18]]); + (*drv)[pd[11]] += 0.5*(*drv)[cd[12]]; + (*drv)[pd[12]] += -0.125*(*drv)[cdi]; + (*drv)[pd[16]] += 0.5*(*drv)[cdi]; + (*drv)[pd[17]] += 0.5*(*drv)[cdi]; + (*drv)[pd[18]] += 0.25*(*drv)[cdi]; + (*drv)[pd[19]] = + ((*drv)[cd[13]] + 0.5*(*drv)[cd[12]] + + 0.25*(*drv)[cdi] + 0.75*(*drv)[cd[18]]); + break; + case 2: + (*drv)[pd[0]] += 0.0625*((*drv)[cd[14]] + (*drv)[cdi] - (*drv)[cd[17]]); + (*drv)[pd[1]] += 0.0625*((*drv)[cd[14]] + (*drv)[cdi] + (*drv)[cd[17]]); + (*drv)[pd[4]] += + 0.0625*(-(*drv)[cd[14]] - (*drv)[cdi]) + 0.1875*(*drv)[cd[17]]; + (*drv)[pd[5]] += + 0.0625*(-(*drv)[cd[14]] - (*drv)[cdi]) - 0.1875*(*drv)[cd[17]]; + (*drv)[pd[6]] += -0.125*(*drv)[cdi]; + (*drv)[pd[8]] += + -0.25*(*drv)[cd[14]] - 0.125*(*drv)[cdi] + 0.375*(*drv)[cd[17]]; + (*drv)[pd[9]] += 0.5*(*drv)[cd[14]]; + (*drv)[pd[10]] += -0.125*(*drv)[cdi]; + (*drv)[pd[12]] += + -0.25*(*drv)[cd[14]] + 0.125*(-(*drv)[cdi] - (*drv)[cd[17]]); + (*drv)[pd[13]] += 0.5*(*drv)[cd[14]]; + (*drv)[pd[16]] += 0.5*(*drv)[cdi]; + (*drv)[pd[17]] += 0.5*(*drv)[cdi]; + (*drv)[pd[18]] = + ((*drv)[cd[15]] + 0.5*(*drv)[cd[14]] + + 0.25*(*drv)[cdi] + 0.75*(*drv)[cd[17]]); + (*drv)[pd[19]] += 0.25*(*drv)[cdi]; + break; + case 3: + (*drv)[pd[0]] += 0.0625*(*drv)[cdi]; + (*drv)[pd[1]] += 0.0625*(*drv)[cdi]; + (*drv)[pd[4]] += -0.0625*(*drv)[cdi]; + (*drv)[pd[5]] += -0.0625*(*drv)[cdi]; + (*drv)[pd[6]] += -0.125*(*drv)[cdi]; + (*drv)[pd[8]] += -0.125*(*drv)[cdi]; + (*drv)[pd[10]] += -0.125*(*drv)[cdi]; + (*drv)[pd[12]] += -0.125*(*drv)[cdi]; + (*drv)[pd[16]] += 0.5*(*drv)[cdi]; + (*drv)[pd[17]] += 0.5*(*drv)[cdi]; + (*drv)[pd[18]] += 0.25*(*drv)[cdi]; + (*drv)[pd[19]] += 0.25*(*drv)[cdi]; + break; + } + + /****************************************************************************/ + /* values on child[1] */ + /****************************************************************************/ + + cd = basFct->getLocalIndices(el->getChild(1), admin, NULL); + + if (typ == 0) + { + switch(lr_set) + { + case 1: + cdi = el->getChild(1)->getDOF(node0+1, n0); + TEST_EXIT(cdi == cd[17])("cdi != cd[17]\n"); + (*drv)[pd[0]] += 0.0625*(*drv)[cdi]; + (*drv)[pd[1]] += -0.0625*(*drv)[cdi]; + (*drv)[pd[4]] += -0.1875*(*drv)[cdi]; + (*drv)[pd[5]] += 0.1875*(*drv)[cdi]; + (*drv)[pd[6]] += -0.125*(*drv)[cdi]; + (*drv)[pd[10]] += 0.375*(*drv)[cdi]; + (*drv)[pd[19]] += 0.75*(*drv)[cdi]; + break; + case 2: + cdi = el->getChild(1)->getDOF(node0+2, n0); + TEST_EXIT(cdi == cd[18])("cdi != cd[18]\n"); + (*drv)[pd[0]] += 0.0625*(*drv)[cdi]; + (*drv)[pd[1]] += -0.0625*(*drv)[cdi]; + (*drv)[pd[4]] += -0.1875*(*drv)[cdi]; + (*drv)[pd[5]] += 0.1875*(*drv)[cdi]; + (*drv)[pd[8]] += -0.125*(*drv)[cdi]; + (*drv)[pd[12]] += 0.375*(*drv)[cdi]; + (*drv)[pd[18]] += 0.75*(*drv)[cdi]; + break; + } + } + else + { + switch(lr_set) + { + case 1: + cdi = el->getChild(1)->getDOF(node0+2, n0); + TEST_EXIT(cdi == cd[18])("cdi != cd[18]\n"); + (*drv)[pd[0]] += 0.0625*(*drv)[cdi]; + (*drv)[pd[1]] += -0.0625*(*drv)[cdi]; + (*drv)[pd[4]] += -0.1875*(*drv)[cdi]; + (*drv)[pd[5]] += 0.1875*(*drv)[cdi]; + (*drv)[pd[6]] += -0.125*(*drv)[cdi]; + (*drv)[pd[10]] += 0.375*(*drv)[cdi]; + (*drv)[pd[19]] += 0.75*(*drv)[cdi]; + break; + case 2: + cdi = el->getChild(1)->getDOF(node0+1, n0); + TEST_EXIT(cdi == cd[17])("cdi != cd[17]\n"); + (*drv)[pd[0]] += 0.0625*(*drv)[cdi]; + (*drv)[pd[1]] += -0.0625*(*drv)[cdi]; + (*drv)[pd[4]] += -0.1875*(*drv)[cdi]; + (*drv)[pd[5]] += 0.1875*(*drv)[cdi]; + (*drv)[pd[8]] += -0.125*(*drv)[cdi]; + (*drv)[pd[12]] += 0.375*(*drv)[cdi]; + (*drv)[pd[18]] += 0.75*(*drv)[cdi]; + break; + } + } + } + return; + } + + void Lagrange::coarseRestr4_1d(DOFIndexed<double> *drv, RCNeighbourList *list, + int n, BasisFunction* basFct) + { + FUNCNAME("Lagrange::coarseRestr4_1d"); + const Element *el; + DegreeOfFreedom pdof[5]; + const DegreeOfFreedom *cdof; + const DOFAdmin *admin; + + if (n < 1) return; + el = list->getElement(0); + + if (!drv->getFESpace()) + { + ERROR("no fe_space in dof_real_vec\n"); + return; + } + else if (!drv->getFESpace()->getBasisFcts()) + { + ERROR("no basis functions in fe_space %s\n", + drv->getFESpace()->getName().c_str()); + return; + } + + admin = drv->getFESpace()->getAdmin(); + + basFct->getLocalIndices(el, admin, pdof); + + /****************************************************************************/ + /* values on child[0] */ + /****************************************************************************/ + + cdof = basFct->getLocalIndices(el->getChild(0), admin, NULL); + + (*drv)[pdof[0]] += + (0.2734375*(*drv)[cdof[3]] + + 0.0390625*(-(*drv)[cdof[5]] - (*drv)[cdof[8]] - (*drv)[cdof[13]]) + + 0.0234375*((*drv)[cdof[6]] + (*drv)[cdof[12]])); + (*drv)[pdof[1]] += + (0.0390625*(-(*drv)[cdof[3]] - (*drv)[cdof[8]] + - (*drv)[cdof[12]] - (*drv)[cdof[13]]) + + 0.0234375*((*drv)[cdof[5]] + (*drv)[cdof[6]])); + (*drv)[pdof[3]] += + (0.0625*(-(*drv)[cdof[6]] + (*drv)[cdof[13]]) + 0.1875*(*drv)[cdof[8]] + + 0.125*(*drv)[cdof[12]]); + (*drv)[pdof[4]] += (-0.375*(*drv)[cdof[8]] - 0.125*(*drv)[cdof[12]]); + (*drv)[pdof[5]] += 0.5*(*drv)[cdof[8]]; + (*drv)[pdof[6]] += 0.5*(*drv)[cdof[8]]; + (*drv)[pdof[7]] += 0.375*(-(*drv)[cdof[8]] + (*drv)[cdof[12]]); + (*drv)[pdof[8]] += + (-0.0625*(*drv)[cdof[6]] + 0.1875*(*drv)[cdof[8]] - 0.125*(*drv)[cdof[12]] + + 0.3125*(*drv)[cdof[13]]); + (*drv)[pdof[9]] = + ((*drv)[cdof[4]] + 1.09375*(*drv)[cdof[3]] + 0.46875*(*drv)[cdof[5]] + - 0.09375*(*drv)[cdof[6]] + 0.15625*(*drv)[cdof[13]] + + 0.03125*((*drv)[cdof[8]] - (*drv)[cdof[12]])); + (*drv)[pdof[10]] = + ((*drv)[cdof[2]] - 0.546875*(*drv)[cdof[3]] + 0.703125*(*drv)[cdof[5]] + + 0.140625*(*drv)[cdof[6]] + 0.015625*(*drv)[cdof[8]] + - 0.046875*(*drv)[cdof[12]] - 0.234375*(*drv)[cdof[13]]); + (*drv)[pdof[11]] = + (0.21875*(*drv)[cdof[3]] + 0.15625*(-(*drv)[cdof[5]] + (*drv)[cdof[13]]) + + 0.09375*(-(*drv)[cdof[6]] + (*drv)[cdof[12]]) + 0.03125*(*drv)[cdof[8]]); + (*drv)[pdof[12]] = + ((*drv)[cdof[14]] + 0.5625*(*drv)[cdof[6]] - 0.1875*(*drv)[cdof[8]] + + 0.375*(*drv)[cdof[12]] + 0.9375*(*drv)[cdof[13]]); + (*drv)[pdof[13]] = + (0.5625*(*drv)[cdof[6]] - 0.1875*(*drv)[cdof[8]] - 0.375*(*drv)[cdof[12]] + - 0.3125*(*drv)[cdof[13]]); + (*drv)[pdof[14]] = + ((*drv)[cdof[7]] + 0.75*((*drv)[cdof[8]] + (*drv)[cdof[12]])); + + /****************************************************************************/ + /* values on child[1] */ + /****************************************************************************/ + + cdof = basFct->getLocalIndices(el->getChild(1), admin, NULL); + + (*drv)[pdof[0]] += + (0.0234375*(*drv)[cdof[6]] + + 0.0390625*(-(*drv)[cdof[8]] - (*drv)[cdof[12]] - (*drv)[cdof[13]])); + (*drv)[pdof[1]] += + (0.0390625*(-(*drv)[cdof[6]] - (*drv)[cdof[12]]) + + 0.2734375*(*drv)[cdof[8]] + 0.0234375*(*drv)[cdof[13]]); + (*drv)[pdof[3]] += 0.3125*(*drv)[cdof[12]] - 0.125*(*drv)[cdof[13]]; + (*drv)[pdof[4]] += 0.375*(*drv)[cdof[13]]; + (*drv)[pdof[7]] += -0.125*(*drv)[cdof[13]]; + (*drv)[pdof[8]] += 0.0625*(*drv)[cdof[12]] + 0.125*(*drv)[cdof[13]]; + (*drv)[pdof[9]] += + (0.15625*(-(*drv)[cdof[6]] + (*drv)[cdof[12]]) + 0.21875*(*drv)[cdof[8]] + + 0.09375*(*drv)[cdof[13]]); + (*drv)[pdof[10]] += + (0.703125*(*drv)[cdof[6]] - 0.546875*(*drv)[cdof[8]] + - 0.234375*(*drv)[cdof[12]] - 0.046875*(*drv)[cdof[13]]); + (*drv)[pdof[11]] += + ((*drv)[cdof[7]] + 0.46875*(*drv)[cdof[6]] + 1.09375*(*drv)[cdof[8]] + + 0.15625*(*drv)[cdof[12]] - 0.03125*(*drv)[cdof[13]]); + (*drv)[pdof[12]] += -0.3125*(*drv)[cdof[12]] - 0.375*(*drv)[cdof[13]]; + (*drv)[pdof[13]] += + (*drv)[cdof[14]] + 0.9375*(*drv)[cdof[12]] + 0.375*(*drv)[cdof[13]]; + (*drv)[pdof[14]] += 0.75*(*drv)[cdof[13]]; + + if (n <= 1) return; + + /****************************************************************************/ + /* adjust neighbour values */ + /****************************************************************************/ + + el = list->getElement(1); + + basFct->getLocalIndices(el, admin, pdof); + + /****************************************************************************/ + /* values on neighbour's child[0] */ + /****************************************************************************/ + + cdof = basFct->getLocalIndices(el->getChild(0), admin, NULL); + + (*drv)[pdof[0]] += + (0.0234375*((*drv)[cdof[6]] + (*drv)[cdof[12]]) + + 0.0390625*(-(*drv)[cdof[8]] - (*drv)[cdof[13]])); + (*drv)[pdof[1]] += + (0.0234375*(*drv)[cdof[6]] + + 0.0390625*(-(*drv)[cdof[8]] - (*drv)[cdof[12]] - (*drv)[cdof[13]])); + (*drv)[pdof[3]] += + (0.0625*(-(*drv)[cdof[6]] + (*drv)[cdof[13]]) + 0.1875*(*drv)[cdof[8]] + + 0.12500000*(*drv)[cdof[12]]); + (*drv)[pdof[4]] += -0.375*(*drv)[cdof[8]] - 0.125*(*drv)[cdof[12]]; + (*drv)[pdof[5]] += 0.5*(*drv)[cdof[8]]; + (*drv)[pdof[6]] += 0.5*(*drv)[cdof[8]]; + (*drv)[pdof[7]] += 0.375*(-(*drv)[cdof[8]] + (*drv)[cdof[12]]); + (*drv)[pdof[8]] += + (-0.0625*(*drv)[cdof[6]] + 0.1875*(*drv)[cdof[8]] - 0.125*(*drv)[cdof[12]] + + 0.3125*(*drv)[cdof[13]]); + (*drv)[pdof[9]] += + (-0.09375*(*drv)[cdof[6]] + 0.03125*((*drv)[cdof[8]] - (*drv)[cdof[12]]) + + 0.15625*(*drv)[cdof[13]]); + (*drv)[pdof[10]] += + (0.140625*(*drv)[cdof[6]] + 0.015625*(*drv)[cdof[8]] + - 0.046875*(*drv)[cdof[12]] - 0.234375*(*drv)[cdof[13]]); + (*drv)[pdof[11]] += + (0.09375*(-(*drv)[cdof[6]] + (*drv)[cdof[12]]) + + 0.03125*(*drv)[cdof[8]] + 0.15625*(*drv)[cdof[13]]); + (*drv)[pdof[12]] = + ((*drv)[cdof[14]] + 0.5625*(*drv)[cdof[6]] - 0.1875*(*drv)[cdof[8]] + + 0.375*(*drv)[cdof[12]] + 0.9375*(*drv)[cdof[13]]); + (*drv)[pdof[13]] = + (0.5625*(*drv)[cdof[6]] - 0.1875*(*drv)[cdof[8]] - 0.375*(*drv)[cdof[12]] + - 0.3125*(*drv)[cdof[13]]); + (*drv)[pdof[14]] = + (*drv)[cdof[7]] + 0.75*((*drv)[cdof[8]] + (*drv)[cdof[12]]); + + /****************************************************************************/ + /* values on neighbour's child[1] */ + /****************************************************************************/ + + cdof = basFct->getLocalIndices(el->getChild(1), admin, NULL); + + (*drv)[pdof[0]] += 0.0390625*(-(*drv)[cdof[12]] - (*drv)[cdof[13]]); + (*drv)[pdof[1]] += -0.0390625*(*drv)[cdof[12]] + 0.0234375*(*drv)[cdof[13]]; + (*drv)[pdof[3]] += 0.3125*(*drv)[cdof[12]] - 0.125*(*drv)[cdof[13]]; + (*drv)[pdof[4]] += 0.375*(*drv)[cdof[13]]; + (*drv)[pdof[7]] += -0.125*(*drv)[cdof[13]]; + (*drv)[pdof[8]] += 0.0625*(*drv)[cdof[12]] + 0.125*(*drv)[cdof[13]]; + (*drv)[pdof[9]] += 0.15625*(*drv)[cdof[12]] + 0.09375*(*drv)[cdof[13]]; + (*drv)[pdof[10]] += -0.234375*(*drv)[cdof[12]] - 0.046875*(*drv)[cdof[13]]; + (*drv)[pdof[11]] += 0.15625*(*drv)[cdof[12]] - 0.03125*(*drv)[cdof[13]]; + (*drv)[pdof[12]] += -0.3125*(*drv)[cdof[12]] - 0.375*(*drv)[cdof[13]]; + (*drv)[pdof[13]] += + (*drv)[cdof[14]] + 0.9375*(*drv)[cdof[12]] + 0.375*(*drv)[cdof[13]]; + (*drv)[pdof[14]] += 0.75*(*drv)[cdof[13]]; + + return; + } + + void Lagrange::coarseRestr4_2d(DOFIndexed<double> *drv, RCNeighbourList *list, + int n, BasisFunction* basFct) + { + FUNCNAME("Lagrange::coarseRestr4_2d"); + const Element *el; + DegreeOfFreedom pdof[15]; + const DegreeOfFreedom *cdof; + const DOFAdmin *admin; + + if (n < 1) return; + el = list->getElement(0); + + if (!drv->getFESpace()) + { + ERROR("no fe_space in dof_real_vec\n"); + return; + } + else if (!drv->getFESpace()->getBasisFcts()) + { + ERROR("no basis functions in fe_space %s\n", + drv->getFESpace()->getName().c_str()); + return; + } + + admin = drv->getFESpace()->getAdmin(); + + basFct->getLocalIndices(el, admin, pdof); + + /****************************************************************************/ + /* values on child[0] */ + /****************************************************************************/ + + cdof = basFct->getLocalIndices(el->getChild(0), admin, NULL); + + (*drv)[pdof[0]] += + (0.2734375*(*drv)[cdof[3]] + + 0.0390625*(-(*drv)[cdof[5]] - (*drv)[cdof[8]] - (*drv)[cdof[13]]) + + 0.0234375*((*drv)[cdof[6]] + (*drv)[cdof[12]])); + (*drv)[pdof[1]] += + (0.0390625*(-(*drv)[cdof[3]] - (*drv)[cdof[8]] + - (*drv)[cdof[12]] - (*drv)[cdof[13]]) + + 0.0234375*((*drv)[cdof[5]] + (*drv)[cdof[6]])); + (*drv)[pdof[3]] += + (0.0625*(-(*drv)[cdof[6]] + (*drv)[cdof[13]]) + 0.1875*(*drv)[cdof[8]] + + 0.125*(*drv)[cdof[12]]); + (*drv)[pdof[4]] += (-0.375*(*drv)[cdof[8]] - 0.125*(*drv)[cdof[12]]); + (*drv)[pdof[5]] += 0.5*(*drv)[cdof[8]]; + (*drv)[pdof[6]] += 0.5*(*drv)[cdof[8]]; + (*drv)[pdof[7]] += 0.375*(-(*drv)[cdof[8]] + (*drv)[cdof[12]]); + (*drv)[pdof[8]] += + (-0.0625*(*drv)[cdof[6]] + 0.1875*(*drv)[cdof[8]] - 0.125*(*drv)[cdof[12]] + + 0.3125*(*drv)[cdof[13]]); + (*drv)[pdof[9]] = + ((*drv)[cdof[4]] + 1.09375*(*drv)[cdof[3]] + 0.46875*(*drv)[cdof[5]] + - 0.09375*(*drv)[cdof[6]] + 0.15625*(*drv)[cdof[13]] + + 0.03125*((*drv)[cdof[8]] - (*drv)[cdof[12]])); + (*drv)[pdof[10]] = + ((*drv)[cdof[2]] - 0.546875*(*drv)[cdof[3]] + 0.703125*(*drv)[cdof[5]] + + 0.140625*(*drv)[cdof[6]] + 0.015625*(*drv)[cdof[8]] + - 0.046875*(*drv)[cdof[12]] - 0.234375*(*drv)[cdof[13]]); + (*drv)[pdof[11]] = + (0.21875*(*drv)[cdof[3]] + 0.15625*(-(*drv)[cdof[5]] + (*drv)[cdof[13]]) + + 0.09375*(-(*drv)[cdof[6]] + (*drv)[cdof[12]]) + 0.03125*(*drv)[cdof[8]]); + (*drv)[pdof[12]] = + ((*drv)[cdof[14]] + 0.5625*(*drv)[cdof[6]] - 0.1875*(*drv)[cdof[8]] + + 0.375*(*drv)[cdof[12]] + 0.9375*(*drv)[cdof[13]]); + (*drv)[pdof[13]] = + (0.5625*(*drv)[cdof[6]] - 0.1875*(*drv)[cdof[8]] - 0.375*(*drv)[cdof[12]] + - 0.3125*(*drv)[cdof[13]]); + (*drv)[pdof[14]] = + ((*drv)[cdof[7]] + 0.75*((*drv)[cdof[8]] + (*drv)[cdof[12]])); + + /****************************************************************************/ + /* values on child[1] */ + /****************************************************************************/ + + cdof = basFct->getLocalIndices(el->getChild(1), admin, NULL); + + (*drv)[pdof[0]] += + (0.0234375*(*drv)[cdof[6]] + + 0.0390625*(-(*drv)[cdof[8]] - (*drv)[cdof[12]] - (*drv)[cdof[13]])); + (*drv)[pdof[1]] += + (0.0390625*(-(*drv)[cdof[6]] - (*drv)[cdof[12]]) + + 0.2734375*(*drv)[cdof[8]] + 0.0234375*(*drv)[cdof[13]]); + (*drv)[pdof[3]] += 0.3125*(*drv)[cdof[12]] - 0.125*(*drv)[cdof[13]]; + (*drv)[pdof[4]] += 0.375*(*drv)[cdof[13]]; + (*drv)[pdof[7]] += -0.125*(*drv)[cdof[13]]; + (*drv)[pdof[8]] += 0.0625*(*drv)[cdof[12]] + 0.125*(*drv)[cdof[13]]; + (*drv)[pdof[9]] += + (0.15625*(-(*drv)[cdof[6]] + (*drv)[cdof[12]]) + 0.21875*(*drv)[cdof[8]] + + 0.09375*(*drv)[cdof[13]]); + (*drv)[pdof[10]] += + (0.703125*(*drv)[cdof[6]] - 0.546875*(*drv)[cdof[8]] + - 0.234375*(*drv)[cdof[12]] - 0.046875*(*drv)[cdof[13]]); + (*drv)[pdof[11]] += + ((*drv)[cdof[7]] + 0.46875*(*drv)[cdof[6]] + 1.09375*(*drv)[cdof[8]] + + 0.15625*(*drv)[cdof[12]] - 0.03125*(*drv)[cdof[13]]); + (*drv)[pdof[12]] += -0.3125*(*drv)[cdof[12]] - 0.375*(*drv)[cdof[13]]; + (*drv)[pdof[13]] += + (*drv)[cdof[14]] + 0.9375*(*drv)[cdof[12]] + 0.375*(*drv)[cdof[13]]; + (*drv)[pdof[14]] += 0.75*(*drv)[cdof[13]]; + + if (n <= 1) return; + + /****************************************************************************/ + /* adjust neighbour values */ + /****************************************************************************/ + + el = list->getElement(1); + + basFct->getLocalIndices(el, admin, pdof); + + /****************************************************************************/ + /* values on neighbour's child[0] */ + /****************************************************************************/ + + cdof = basFct->getLocalIndices(el->getChild(0), admin, NULL); + + (*drv)[pdof[0]] += + (0.0234375*((*drv)[cdof[6]] + (*drv)[cdof[12]]) + + 0.0390625*(-(*drv)[cdof[8]] - (*drv)[cdof[13]])); + (*drv)[pdof[1]] += + (0.0234375*(*drv)[cdof[6]] + + 0.0390625*(-(*drv)[cdof[8]] - (*drv)[cdof[12]] - (*drv)[cdof[13]])); + (*drv)[pdof[3]] += + (0.0625*(-(*drv)[cdof[6]] + (*drv)[cdof[13]]) + 0.1875*(*drv)[cdof[8]] + + 0.12500000*(*drv)[cdof[12]]); + (*drv)[pdof[4]] += -0.375*(*drv)[cdof[8]] - 0.125*(*drv)[cdof[12]]; + (*drv)[pdof[5]] += 0.5*(*drv)[cdof[8]]; + (*drv)[pdof[6]] += 0.5*(*drv)[cdof[8]]; + (*drv)[pdof[7]] += 0.375*(-(*drv)[cdof[8]] + (*drv)[cdof[12]]); + (*drv)[pdof[8]] += + (-0.0625*(*drv)[cdof[6]] + 0.1875*(*drv)[cdof[8]] - 0.125*(*drv)[cdof[12]] + + 0.3125*(*drv)[cdof[13]]); + (*drv)[pdof[9]] += + (-0.09375*(*drv)[cdof[6]] + 0.03125*((*drv)[cdof[8]] - (*drv)[cdof[12]]) + + 0.15625*(*drv)[cdof[13]]); + (*drv)[pdof[10]] += + (0.140625*(*drv)[cdof[6]] + 0.015625*(*drv)[cdof[8]] + - 0.046875*(*drv)[cdof[12]] - 0.234375*(*drv)[cdof[13]]); + (*drv)[pdof[11]] += + (0.09375*(-(*drv)[cdof[6]] + (*drv)[cdof[12]]) + + 0.03125*(*drv)[cdof[8]] + 0.15625*(*drv)[cdof[13]]); + (*drv)[pdof[12]] = + ((*drv)[cdof[14]] + 0.5625*(*drv)[cdof[6]] - 0.1875*(*drv)[cdof[8]] + + 0.375*(*drv)[cdof[12]] + 0.9375*(*drv)[cdof[13]]); + (*drv)[pdof[13]] = + (0.5625*(*drv)[cdof[6]] - 0.1875*(*drv)[cdof[8]] - 0.375*(*drv)[cdof[12]] + - 0.3125*(*drv)[cdof[13]]); + (*drv)[pdof[14]] = + (*drv)[cdof[7]] + 0.75*((*drv)[cdof[8]] + (*drv)[cdof[12]]); + + /****************************************************************************/ + /* values on neighbour's child[1] */ + /****************************************************************************/ + + cdof = basFct->getLocalIndices(el->getChild(1), admin, NULL); + + (*drv)[pdof[0]] += 0.0390625*(-(*drv)[cdof[12]] - (*drv)[cdof[13]]); + (*drv)[pdof[1]] += -0.0390625*(*drv)[cdof[12]] + 0.0234375*(*drv)[cdof[13]]; + (*drv)[pdof[3]] += 0.3125*(*drv)[cdof[12]] - 0.125*(*drv)[cdof[13]]; + (*drv)[pdof[4]] += 0.375*(*drv)[cdof[13]]; + (*drv)[pdof[7]] += -0.125*(*drv)[cdof[13]]; + (*drv)[pdof[8]] += 0.0625*(*drv)[cdof[12]] + 0.125*(*drv)[cdof[13]]; + (*drv)[pdof[9]] += 0.15625*(*drv)[cdof[12]] + 0.09375*(*drv)[cdof[13]]; + (*drv)[pdof[10]] += -0.234375*(*drv)[cdof[12]] - 0.046875*(*drv)[cdof[13]]; + (*drv)[pdof[11]] += 0.15625*(*drv)[cdof[12]] - 0.03125*(*drv)[cdof[13]]; + (*drv)[pdof[12]] += -0.3125*(*drv)[cdof[12]] - 0.375*(*drv)[cdof[13]]; + (*drv)[pdof[13]] += + (*drv)[cdof[14]] + 0.9375*(*drv)[cdof[12]] + 0.375*(*drv)[cdof[13]]; + (*drv)[pdof[14]] += 0.75*(*drv)[cdof[13]]; + + return; + } + + void Lagrange::coarseRestr4_3d(DOFIndexed<double> *drv, RCNeighbourList *list, + int n, BasisFunction* basFct) + { + FUNCNAME("Lagrange::coarseRestr4_3d"); + DegreeOfFreedom pd[32]; + const DegreeOfFreedom *cd; + const Element *el; + int i, typ, lr_set; + const DOFAdmin *admin; + + if (n < 1) return; + el = list->getElement(0); + typ = list->getType(0); + + if (!drv->getFESpace()) + { + ERROR("no fe_space in dof_real_vec\n"); + return; + } + else if (!drv->getFESpace()->getBasisFcts()) + { + ERROR("no basis functions in fe_space %s\n", + drv->getFESpace()->getName().c_str()); + return; + } + + admin = drv->getFESpace()->getAdmin(); + + basFct->getLocalIndices(el, admin, pd); + + /****************************************************************************/ + /* values on child[0] */ + /****************************************************************************/ + + cd = basFct->getLocalIndices(el->getChild(0), admin, NULL); + + (*drv)[pd[0]] += + (0.2734375*(*drv)[cd[10]] + + 0.0390625*(-(*drv)[cd[12]] - (*drv)[cd[16]] - (*drv)[cd[19]] + - (*drv)[cd[22]] - (*drv)[cd[23]] - (*drv)[cd[25]] + - (*drv)[cd[28]]) + + 0.0234375*((*drv)[cd[18]] + (*drv)[cd[21]] + (*drv)[cd[26]] + + (*drv)[cd[29]] + (*drv)[cd[34]])); + (*drv)[pd[1]] += + (0.0390625*(-(*drv)[cd[10]] - (*drv)[cd[16]] - (*drv)[cd[19]] + - (*drv)[cd[22]] - (*drv)[cd[23]] - (*drv)[cd[25]] + - (*drv)[cd[26]] - (*drv)[cd[28]] - (*drv)[cd[29]] + - (*drv)[cd[34]]) + + 0.0234375*((*drv)[cd[12]] + (*drv)[cd[18]] + (*drv)[cd[21]])); + (*drv)[pd[4]] = + ((*drv)[cd[11]] + 1.09375*(*drv)[cd[10]] + 0.46875*(*drv)[cd[12]] + + 0.03125*((*drv)[cd[16]] + (*drv)[cd[19]] + (*drv)[cd[22]] + + (*drv)[cd[23]] - (*drv)[cd[26]] - (*drv)[cd[29]] + - (*drv)[cd[34]]) + + 0.09375*(-(*drv)[cd[18]] - (*drv)[cd[21]]) + + 0.15625*((*drv)[cd[25]] + (*drv)[cd[28]])); + (*drv)[pd[5]] = + ((*drv)[cd[3]] - 0.546875*(*drv)[cd[10]] + + 0.703125*(*drv)[cd[12]] + + 0.015625*((*drv)[cd[16]] + (*drv)[cd[19]] + + (*drv)[cd[22]] + (*drv)[cd[23]]) + + 0.140625*((*drv)[cd[18]] + (*drv)[cd[21]]) + + 0.234375*(-(*drv)[cd[25]] - (*drv)[cd[28]]) + + 0.046875*(-(*drv)[cd[26]] - (*drv)[cd[29]] - (*drv)[cd[34]])); + (*drv)[pd[6]] = + (0.21875*(*drv)[cd[10]] + + 0.15625*(-(*drv)[cd[12]] + (*drv)[cd[25]] + (*drv)[cd[28]]) + + 0.03125*((*drv)[cd[16]] + (*drv)[cd[19]] + + (*drv)[cd[22]] + (*drv)[cd[23]]) + + 0.09375*(-(*drv)[cd[18]] - (*drv)[cd[21]] + (*drv)[cd[26]] + + (*drv)[cd[29]] + (*drv)[cd[34]])); + (*drv)[pd[7]] += + (0.1875*(*drv)[cd[16]] + + 0.0625*(-(*drv)[cd[18]] + (*drv)[cd[23]] - (*drv)[cd[34]]) + + 0.125*((*drv)[cd[22]] - (*drv)[cd[29]]) + 0.3125*(*drv)[cd[28]]); + (*drv)[pd[8]] += + (0.375*(-(*drv)[cd[16]] + (*drv)[cd[29]]) - 0.125*(*drv)[cd[22]]); + (*drv)[pd[9]] += 0.5*(*drv)[cd[16]]; + (*drv)[pd[10]] += + (0.1875*(*drv)[cd[19]] + + 0.0625*(-(*drv)[cd[21]] + (*drv)[cd[22]] - (*drv)[cd[34]]) + + 0.125*((*drv)[cd[23]] - (*drv)[cd[26]]) + + 0.3125*(*drv)[cd[25]]); + (*drv)[pd[11]] += + (0.375*(-(*drv)[cd[19]] + (*drv)[cd[26]]) + - 0.125*(*drv)[cd[23]]); + (*drv)[pd[12]] += 0.5*(*drv)[cd[19]]; + (*drv)[pd[13]] += + (0.1875*(*drv)[cd[16]] + + 0.0625*(-(*drv)[cd[18]] + (*drv)[cd[23]] + + (*drv)[cd[28]] + (*drv)[cd[34]]) + + 0.125*((*drv)[cd[22]] + (*drv)[cd[29]])); + (*drv)[pd[14]] += + (-0.375*(*drv)[cd[16]] + 0.125*(-(*drv)[cd[22]] - (*drv)[cd[29]])); + (*drv)[pd[15]] += 0.5*(*drv)[cd[16]]; + (*drv)[pd[16]] += + (0.1875*(*drv)[cd[19]] + + 0.0625*(-(*drv)[cd[21]] + (*drv)[cd[22]] + + (*drv)[cd[25]] + (*drv)[cd[34]]) + + 0.125*((*drv)[cd[23]] + (*drv)[cd[26]])); + (*drv)[pd[17]] += + (-0.375*(*drv)[cd[19]] + 0.125*(-(*drv)[cd[23]] - (*drv)[cd[26]])); + (*drv)[pd[18]] += 0.5*(*drv)[cd[19]]; + (*drv)[pd[22]] += + (0.25*(-(*drv)[cd[22]] - (*drv)[cd[23]]) - 0.125*(*drv)[cd[34]]); + (*drv)[pd[23]] += 0.5*(*drv)[cd[22]]; + (*drv)[pd[24]] += 0.5*(*drv)[cd[23]]; + (*drv)[pd[25]] += + (0.25*(-(*drv)[cd[22]] - (*drv)[cd[23]]) + 0.375*(*drv)[cd[34]]); + (*drv)[pd[26]] += 0.5*(*drv)[cd[22]]; + (*drv)[pd[27]] += 0.5*(*drv)[cd[23]]; + (*drv)[pd[28]] = + ((*drv)[cd[27]] + 0.1875*(-(*drv)[cd[19]] + (*drv)[cd[34]]) + + 0.5625*(*drv)[cd[21]] - 0.0625*(*drv)[cd[22]] + - 0.125*(*drv)[cd[23]] + 0.9375*(*drv)[cd[25]] + + 0.375*(*drv)[cd[26]]); + (*drv)[pd[29]] = + (0.1875*(-(*drv)[cd[19]] - (*drv)[cd[34]]) + + 0.5625*(*drv)[cd[21]] - 0.0625*(*drv)[cd[22]] + - 0.125*(*drv)[cd[23]] - 0.3125*(*drv)[cd[25]] + - 0.375*(*drv)[cd[26]]); + (*drv)[pd[30]] = + ((*drv)[cd[20]] + 0.75*((*drv)[cd[19]] + (*drv)[cd[26]]) + + 0.25*(*drv)[cd[23]]); + (*drv)[pd[31]] = + ((*drv)[cd[30]] + 0.1875*(-(*drv)[cd[16]] + (*drv)[cd[34]]) + + 0.5625*(*drv)[cd[18]] - 0.125*(*drv)[cd[22]] + - 0.0625*(*drv)[cd[23]] + 0.9375*(*drv)[cd[28]] + + 0.375*(*drv)[cd[29]]); + (*drv)[pd[32]] = + (0.1875*(-(*drv)[cd[16]] - (*drv)[cd[34]]) + + 0.5625*(*drv)[cd[18]] - 0.125*(*drv)[cd[22]] + - 0.0625*(*drv)[cd[23]] - 0.3125*(*drv)[cd[28]] + - 0.375*(*drv)[cd[29]]); + (*drv)[pd[33]] = + ((*drv)[cd[17]] + 0.75*((*drv)[cd[16]] + (*drv)[cd[29]]) + + 0.25*(*drv)[cd[22]]); + (*drv)[pd[34]] = + ((*drv)[cd[24]] + 0.5*((*drv)[cd[22]] + (*drv)[cd[23]]) + + 0.75*(*drv)[cd[34]]); + + /****************************************************************************/ + /* values on child[1] */ + /****************************************************************************/ + + cd = basFct->getLocalIndices(el->getChild(1), admin, NULL); + + if (typ == 0) + { + /****************************************************************************/ + /* parent of el_type 0 */ + /****************************************************************************/ + + (*drv)[pd[0]] += + (0.0390625*(-(*drv)[cd[10]] - (*drv)[cd[25]] - (*drv)[cd[26]] + - (*drv)[cd[28]] - (*drv)[cd[29]] - (*drv)[cd[34]]) + + 0.0234375*(*drv)[cd[12]]); + (*drv)[pd[1]] += + (0.2734375*(*drv)[cd[10]] + + 0.0390625*(-(*drv)[cd[12]] - (*drv)[cd[25]] - (*drv)[cd[28]]) + + 0.0234375*((*drv)[cd[26]] + (*drv)[cd[29]] + (*drv)[cd[34]])); + (*drv)[pd[4]] += + (0.21875*(*drv)[cd[10]] + + 0.15625*(-(*drv)[cd[12]] + (*drv)[cd[25]] + (*drv)[cd[28]]) + + 0.09375*((*drv)[cd[26]] + (*drv)[cd[29]] + (*drv)[cd[34]])); + (*drv)[pd[5]] += + (-0.546875*(*drv)[cd[10]] + 0.703125*(*drv)[cd[12]] + + 0.234375*(-(*drv)[cd[25]] - (*drv)[cd[28]]) + + 0.046875*(-(*drv)[cd[26]] - (*drv)[cd[29]] - (*drv)[cd[34]])); + (*drv)[pd[6]] += + ((*drv)[cd[11]] + 1.09375*(*drv)[cd[10]] + 0.46875*(*drv)[cd[12]] + + 0.15625*((*drv)[cd[25]] + (*drv)[cd[28]]) + + 0.03125*(-(*drv)[cd[26]] - (*drv)[cd[29]] - (*drv)[cd[34]])); + (*drv)[pd[7]] += + (0.0625*((*drv)[cd[25]] + (*drv)[cd[34]]) + 0.125*(*drv)[cd[26]]); + (*drv)[pd[8]] += -0.125*(*drv)[cd[26]]; + (*drv)[pd[10]] += + (0.0625*((*drv)[cd[28]] + (*drv)[cd[34]]) + 0.125*(*drv)[cd[29]]); + (*drv)[pd[11]] += -0.125*(*drv)[cd[29]]; + (*drv)[pd[13]] += + (0.3125*(*drv)[cd[25]] - 0.125*(*drv)[cd[26]] + - 0.0625*(*drv)[cd[34]]); + (*drv)[pd[14]] += 0.375*(*drv)[cd[26]]; + (*drv)[pd[16]] += + (0.3125*(*drv)[cd[28]] - 0.125*(*drv)[cd[29]] + - 0.0625*(*drv)[cd[34]]); + (*drv)[pd[17]] += 0.375*(*drv)[cd[29]]; + (*drv)[pd[22]] += 0.375*(*drv)[cd[34]]; + (*drv)[pd[25]] += -0.125*(*drv)[cd[34]]; + (*drv)[pd[28]] += + (-0.3125*(*drv)[cd[28]] - 0.375*(*drv)[cd[29]] + - 0.1875*(*drv)[cd[34]]); + (*drv)[pd[29]] += + ((*drv)[cd[30]] + 0.9375*(*drv)[cd[28]] + 0.375*(*drv)[cd[29]] + + 0.1875*(*drv)[cd[34]]); + (*drv)[pd[30]] += 0.75*(*drv)[cd[29]]; + (*drv)[pd[31]] += + (-0.3125*(*drv)[cd[25]] - 0.375*(*drv)[cd[26]] + - 0.1875*(*drv)[cd[34]]); + (*drv)[pd[32]] += + ((*drv)[cd[27]] + 0.9375*(*drv)[cd[25]] + + 0.375*(*drv)[cd[26]] + 0.1875*(*drv)[cd[34]]); + (*drv)[pd[33]] += 0.75*(*drv)[cd[26]]; + (*drv)[pd[34]] += 0.75*(*drv)[cd[34]]; + } else { + /****************************************************************************/ + /* parent of el_type 1|2 */ + /****************************************************************************/ + + (*drv)[pd[0]] += + (0.0390625*(-(*drv)[cd[10]] - (*drv)[cd[25]] - (*drv)[cd[26]] + - (*drv)[cd[28]] - (*drv)[cd[29]] - (*drv)[cd[34]]) + + 0.0234375*(*drv)[cd[12]]); + (*drv)[pd[1]] += + (0.2734375*(*drv)[cd[10]] + + 0.0390625*(-(*drv)[cd[12]] - (*drv)[cd[25]] - (*drv)[cd[28]]) + + 0.0234375*((*drv)[cd[26]] + (*drv)[cd[29]] + (*drv)[cd[34]])); + (*drv)[pd[4]] += + (0.21875*(*drv)[cd[10]] + + 0.15625*(-(*drv)[cd[12]] + (*drv)[cd[25]] + (*drv)[cd[28]]) + + 0.09375*((*drv)[cd[26]] + (*drv)[cd[29]] + (*drv)[cd[34]])); + (*drv)[pd[5]] += + (-0.546875*(*drv)[cd[10]] + 0.703125*(*drv)[cd[12]] + + 0.234375*(-(*drv)[cd[25]] - (*drv)[cd[28]]) + + 0.046875*(-(*drv)[cd[26]] - (*drv)[cd[29]] - (*drv)[cd[34]])); + (*drv)[pd[6]] += + ((*drv)[cd[11]] + 1.09375*(*drv)[cd[10]] + 0.46875*(*drv)[cd[12]] + + 0.15625*((*drv)[cd[25]] + (*drv)[cd[28]]) + + 0.03125*(-(*drv)[cd[26]] - (*drv)[cd[29]] - (*drv)[cd[34]])); + (*drv)[pd[7]] += + (0.0625*((*drv)[cd[28]] + (*drv)[cd[34]]) + 0.125*(*drv)[cd[29]]); + (*drv)[pd[8]] += -0.125*(*drv)[cd[29]]; + (*drv)[pd[10]] += + (0.0625*((*drv)[cd[25]] + (*drv)[cd[34]]) + 0.125*(*drv)[cd[26]]); + (*drv)[pd[11]] += -0.125*(*drv)[cd[26]]; + (*drv)[pd[13]] += + (0.3125*(*drv)[cd[28]] - 0.125*(*drv)[cd[29]] + - 0.0625*(*drv)[cd[34]]); + (*drv)[pd[14]] += 0.375*(*drv)[cd[29]]; + (*drv)[pd[16]] += + (0.3125*(*drv)[cd[25]] - 0.125*(*drv)[cd[26]] + - 0.0625*(*drv)[cd[34]]); + (*drv)[pd[17]] += 0.375*(*drv)[cd[26]]; + (*drv)[pd[22]] += 0.375*(*drv)[cd[34]]; + (*drv)[pd[25]] += -0.125*(*drv)[cd[34]]; + (*drv)[pd[28]] += + (-0.3125*(*drv)[cd[25]] - 0.375*(*drv)[cd[26]] + - 0.1875*(*drv)[cd[34]]); + (*drv)[pd[29]] += + ((*drv)[cd[27]] + 0.9375*(*drv)[cd[25]] + 0.375*(*drv)[cd[26]] + + 0.1875*(*drv)[cd[34]]); + (*drv)[pd[30]] += 0.75*(*drv)[cd[26]]; + (*drv)[pd[31]] += + (-0.3125*(*drv)[cd[28]] - 0.375*(*drv)[cd[29]] + - 0.1875*(*drv)[cd[34]]); + (*drv)[pd[32]] += + ((*drv)[cd[30]] + 0.9375*(*drv)[cd[28]] + + 0.375*(*drv)[cd[29]] + 0.1875*(*drv)[cd[34]]); + (*drv)[pd[33]] += 0.75*(*drv)[cd[29]]; + (*drv)[pd[34]] += 0.75*(*drv)[cd[34]]; + } + + /****************************************************************************/ + /* adjust neighbour values */ + /****************************************************************************/ + + for (i = 1; i < n; i++) + { + el = list->getElement(i); + typ = list->getType(i); + basFct->getLocalIndices(el, admin, pd); + + lr_set = 0; + if (list->getNeighbourElement(i,0) && list->getNeighbourNr(i,0) < i) + lr_set = 1; + + if (list->getNeighbourElement(i,1) && list->getNeighbourNr(i,1) < i) + lr_set += 2; + + TEST_EXIT(lr_set)("no values set on both neighbours\n"); + + /****************************************************************************/ + /* values on child[0] */ + /****************************************************************************/ + + cd = basFct->getLocalIndices(el->getChild(0), admin, NULL); + + switch(lr_set) + { + case 1: + (*drv)[pd[0]] += + (0.0390625*(-(*drv)[cd[16]] - (*drv)[cd[22]] + - (*drv)[cd[23]] - (*drv)[cd[28]]) + + 0.0234375*((*drv)[cd[18]] + (*drv)[cd[29]] + (*drv)[cd[34]])); + (*drv)[pd[1]] += + (0.0390625*(-(*drv)[cd[16]] - (*drv)[cd[22]] - (*drv)[cd[23]] + - (*drv)[cd[28]] - (*drv)[cd[29]] - (*drv)[cd[34]]) + + 0.0234375*(*drv)[cd[18]]); + (*drv)[pd[4]] += + (0.03125*((*drv)[cd[16]] + (*drv)[cd[22]] + (*drv)[cd[23]] + - (*drv)[cd[29]] - (*drv)[cd[34]]) + - 0.09375*(*drv)[cd[18]] + 0.15625*(*drv)[cd[28]]); + (*drv)[pd[5]] += + (0.015625*((*drv)[cd[16]] + (*drv)[cd[22]] + (*drv)[cd[23]]) + + 0.140625*(*drv)[cd[18]] - 0.234375*(*drv)[cd[28]] + + 0.046875*(-(*drv)[cd[29]] - (*drv)[cd[34]])); + (*drv)[pd[6]] += + (0.03125*((*drv)[cd[16]] + (*drv)[cd[22]] + (*drv)[cd[23]]) + + 0.09375*(-(*drv)[cd[18]] + (*drv)[cd[29]] + (*drv)[cd[34]]) + + 0.15625*(*drv)[cd[28]]); + (*drv)[pd[7]] += + (0.1875*(*drv)[cd[16]] + + 0.0625*(-(*drv)[cd[18]] + (*drv)[cd[23]] - (*drv)[cd[34]]) + + 0.125*((*drv)[cd[22]] - (*drv)[cd[29]]) + + 0.3125*(*drv)[cd[28]]); + (*drv)[pd[8]] += + (0.375*(-(*drv)[cd[16]] + (*drv)[cd[29]]) + - 0.125*(*drv)[cd[22]]); + (*drv)[pd[9]] += 0.5*(*drv)[cd[16]]; + (*drv)[pd[10]] += + (0.0625*((*drv)[cd[22]] - (*drv)[cd[34]]) + 0.125*(*drv)[cd[23]]); + (*drv)[pd[11]] += -0.125*(*drv)[cd[23]]; + (*drv)[pd[13]] += + (0.1875*(*drv)[cd[16]] + + 0.0625*(-(*drv)[cd[18]] + (*drv)[cd[23]] + + (*drv)[cd[28]] + (*drv)[cd[34]]) + + 0.125*((*drv)[cd[22]] + (*drv)[cd[29]])); + (*drv)[pd[14]] += + (-0.375*(*drv)[cd[16]] + + 0.125*(-(*drv)[cd[22]] - (*drv)[cd[29]])); + (*drv)[pd[15]] += 0.5*(*drv)[cd[16]]; + (*drv)[pd[16]] += + (0.0625*((*drv)[cd[22]] + (*drv)[cd[34]]) + 0.125*(*drv)[cd[23]]); + (*drv)[pd[17]] += -0.125*(*drv)[cd[23]]; + (*drv)[pd[22]] += + (0.25*(-(*drv)[cd[22]] - (*drv)[cd[23]]) - 0.125*(*drv)[cd[34]]); + (*drv)[pd[23]] += 0.5*(*drv)[cd[22]]; + (*drv)[pd[24]] += 0.5*(*drv)[cd[23]]; + (*drv)[pd[25]] += + (0.25*(-(*drv)[cd[22]] - (*drv)[cd[23]]) + 0.375*(*drv)[cd[34]]); + (*drv)[pd[26]] += 0.5*(*drv)[cd[22]]; + (*drv)[pd[27]] += 0.5*(*drv)[cd[23]]; + (*drv)[pd[28]] += + (-0.0625*(*drv)[cd[22]] - 0.125*(*drv)[cd[23]] + + 0.1875*(*drv)[cd[34]]); + (*drv)[pd[29]] += + (-0.0625*(*drv)[cd[22]] - 0.125*(*drv)[cd[23]] + - 0.1875*(*drv)[cd[34]]); + (*drv)[pd[30]] += 0.25*(*drv)[cd[23]]; + (*drv)[pd[31]] = + ((*drv)[cd[30]] + 0.1875*(-(*drv)[cd[16]] + (*drv)[cd[34]]) + + 0.5625*(*drv)[cd[18]] - 0.125*(*drv)[cd[22]] + - 0.0625*(*drv)[cd[23]] + 0.9375*(*drv)[cd[28]] + + 0.375*(*drv)[cd[29]]); + (*drv)[pd[32]] = + (0.1875*(-(*drv)[cd[16]] - (*drv)[cd[34]]) + + 0.5625*(*drv)[cd[18]] - 0.125*(*drv)[cd[22]] + - 0.0625*(*drv)[cd[23]] - 0.3125*(*drv)[cd[28]] + - 0.375*(*drv)[cd[29]]); + (*drv)[pd[33]] = + ((*drv)[cd[17]] + 0.75*((*drv)[cd[16]] + (*drv)[cd[29]]) + + 0.25*(*drv)[cd[22]]); + (*drv)[pd[34]] = + ((*drv)[cd[24]] + 0.5*((*drv)[cd[22]] + (*drv)[cd[23]]) + + 0.75*(*drv)[cd[34]]); + break; + case 2: + (*drv)[pd[0]] += + (0.0390625*(-(*drv)[cd[19]] - (*drv)[cd[22]] + - (*drv)[cd[23]] - (*drv)[cd[25]]) + + 0.0234375*((*drv)[cd[21]] + (*drv)[cd[26]] + (*drv)[cd[34]])); + (*drv)[pd[1]] += + (0.0390625*(-(*drv)[cd[19]] - (*drv)[cd[22]] - (*drv)[cd[23]] + - (*drv)[cd[25]] - (*drv)[cd[26]] - (*drv)[cd[34]]) + + 0.0234375*(*drv)[cd[21]]); + (*drv)[pd[4]] += + (0.03125*((*drv)[cd[19]] + (*drv)[cd[22]] + (*drv)[cd[23]] + - (*drv)[cd[26]] - (*drv)[cd[34]]) + - 0.09375*(*drv)[cd[21]] + 0.15625*(*drv)[cd[25]]); + (*drv)[pd[5]] += + (0.015625*((*drv)[cd[19]] + (*drv)[cd[22]] + (*drv)[cd[23]]) + + 0.140625*(*drv)[cd[21]] - 0.234375*(*drv)[cd[25]] + + 0.046875*(-(*drv)[cd[26]] - (*drv)[cd[34]])); + (*drv)[pd[6]] += + (0.03125*((*drv)[cd[19]] + (*drv)[cd[22]] + (*drv)[cd[23]]) + + 0.09375*(-(*drv)[cd[21]] + (*drv)[cd[26]] + (*drv)[cd[34]]) + + 0.15625*(*drv)[cd[25]]); + (*drv)[pd[7]] += + (0.125*(*drv)[cd[22]] + 0.0625*((*drv)[cd[23]] - (*drv)[cd[34]])); + (*drv)[pd[8]] += -0.125*(*drv)[cd[22]]; + (*drv)[pd[10]] += + (0.1875*(*drv)[cd[19]] + + 0.0625*(-(*drv)[cd[21]] + (*drv)[cd[22]] - (*drv)[cd[34]]) + + 0.125*((*drv)[cd[23]] - (*drv)[cd[26]]) + + 0.3125*(*drv)[cd[25]]); + (*drv)[pd[11]] += + (0.375*(-(*drv)[cd[19]] + (*drv)[cd[26]]) - 0.125*(*drv)[cd[23]]); + (*drv)[pd[12]] += 0.5*(*drv)[cd[19]]; + (*drv)[pd[13]] += + (0.125*(*drv)[cd[22]] + 0.0625*((*drv)[cd[23]] + (*drv)[cd[34]])); + (*drv)[pd[14]] += -0.125*(*drv)[cd[22]]; + (*drv)[pd[16]] += + (0.1875*(*drv)[cd[19]] + + 0.0625*(-(*drv)[cd[21]] + (*drv)[cd[22]] + + (*drv)[cd[25]] + (*drv)[cd[34]]) + + 0.125*((*drv)[cd[23]] + (*drv)[cd[26]])); + (*drv)[pd[17]] += + (-0.375*(*drv)[cd[19]] + + 0.125*(-(*drv)[cd[23]] - (*drv)[cd[26]])); + (*drv)[pd[18]] += 0.5*(*drv)[cd[19]]; + (*drv)[pd[22]] += + (0.25*(-(*drv)[cd[22]] - (*drv)[cd[23]]) - 0.125*(*drv)[cd[34]]); + (*drv)[pd[23]] += (0.5*(*drv)[cd[22]]); + (*drv)[pd[24]] += (0.5*(*drv)[cd[23]]); + (*drv)[pd[25]] += + (0.25*(-(*drv)[cd[22]] - (*drv)[cd[23]]) + 0.375*(*drv)[cd[34]]); + (*drv)[pd[26]] += (0.5*(*drv)[cd[22]]); + (*drv)[pd[27]] += (0.5*(*drv)[cd[23]]); + (*drv)[pd[28]] = + ((*drv)[cd[27]] + 0.1875*(-(*drv)[cd[19]] + (*drv)[cd[34]]) + + 0.5625*(*drv)[cd[21]] - 0.0625*(*drv)[cd[22]] + - 0.125*(*drv)[cd[23]] + 0.9375*(*drv)[cd[25]] + + 0.375*(*drv)[cd[26]]); + (*drv)[pd[29]] = + (0.1875*(-(*drv)[cd[19]] - (*drv)[cd[34]]) + + 0.5625*(*drv)[cd[21]] - 0.0625*(*drv)[cd[22]] + - 0.125*(*drv)[cd[23]] - 0.3125*(*drv)[cd[25]] + - 0.375*(*drv)[cd[26]]); + (*drv)[pd[30]] = + ((*drv)[cd[20]] + 0.75*((*drv)[cd[19]] + (*drv)[cd[26]]) + + 0.25*(*drv)[cd[23]]); + (*drv)[pd[31]] += + (-0.125*(*drv)[cd[22]] - 0.0625*(*drv)[cd[23]] + + 0.1875*(*drv)[cd[34]]); + (*drv)[pd[32]] += + (-0.125*(*drv)[cd[22]] - 0.0625*(*drv)[cd[23]] + - 0.1875*(*drv)[cd[34]]); + (*drv)[pd[33]] += 0.25*(*drv)[cd[22]]; + (*drv)[pd[34]] = + ((*drv)[cd[24]] + 0.5*((*drv)[cd[22]] + (*drv)[cd[23]]) + + 0.75*(*drv)[cd[34]]); + break; + case 3: + (*drv)[pd[0]] += + (0.0390625*(-(*drv)[cd[22]] - (*drv)[cd[23]]) + + 0.0234375*(*drv)[cd[34]]); + (*drv)[pd[1]] += + (0.0390625*(-(*drv)[cd[22]] - (*drv)[cd[23]] - (*drv)[cd[34]])); + (*drv)[pd[4]] += + (0.03125*((*drv)[cd[22]] + (*drv)[cd[23]] - (*drv)[cd[34]])); + (*drv)[pd[5]] += + (0.015625*((*drv)[cd[22]] + (*drv)[cd[23]]) + - 0.046875*(*drv)[cd[34]]); + (*drv)[pd[6]] += + (0.03125*((*drv)[cd[22]] + (*drv)[cd[23]]) + + 0.09375*(*drv)[cd[34]]); + (*drv)[pd[7]] += + (0.125*(*drv)[cd[22]] + 0.0625*((*drv)[cd[23]] - (*drv)[cd[34]])); + (*drv)[pd[8]] += -0.125*(*drv)[cd[22]]; + (*drv)[pd[10]] += + (0.0625*((*drv)[cd[22]] - (*drv)[cd[34]]) + 0.125*(*drv)[cd[23]]); + (*drv)[pd[11]] += -0.125*(*drv)[cd[23]]; + (*drv)[pd[13]] += + (0.125*(*drv)[cd[22]] + 0.0625*((*drv)[cd[23]] + (*drv)[cd[34]])); + (*drv)[pd[14]] += -0.125*(*drv)[cd[22]]; + (*drv)[pd[16]] += + (0.0625*((*drv)[cd[22]] + (*drv)[cd[34]]) + 0.125*(*drv)[cd[23]]); + (*drv)[pd[17]] += -0.125*(*drv)[cd[23]]; + (*drv)[pd[22]] += + (0.25*(-(*drv)[cd[22]] - (*drv)[cd[23]]) - 0.125*(*drv)[cd[34]]); + (*drv)[pd[23]] += 0.5*(*drv)[cd[22]]; + (*drv)[pd[24]] += 0.5*(*drv)[cd[23]]; + (*drv)[pd[25]] += + (0.25*(-(*drv)[cd[22]] - (*drv)[cd[23]]) + 0.375*(*drv)[cd[34]]); + (*drv)[pd[26]] += 0.5*(*drv)[cd[22]]; + (*drv)[pd[27]] += 0.5*(*drv)[cd[23]]; + (*drv)[pd[28]] += + (-0.0625*(*drv)[cd[22]] - 0.125*(*drv)[cd[23]] + + 0.1875*(*drv)[cd[34]]); + (*drv)[pd[29]] += + (-0.0625*(*drv)[cd[22]] - 0.125*(*drv)[cd[23]] + - 0.1875*(*drv)[cd[34]]); + (*drv)[pd[30]] += 0.25*(*drv)[cd[23]]; + (*drv)[pd[31]] += + (-0.125*(*drv)[cd[22]] - 0.0625*(*drv)[cd[23]] + + 0.1875*(*drv)[cd[34]]); + (*drv)[pd[32]] += + (-0.125*(*drv)[cd[22]] - 0.0625*(*drv)[cd[23]] + - 0.1875*(*drv)[cd[34]]); + (*drv)[pd[33]] += 0.25*(*drv)[cd[22]]; + (*drv)[pd[34]] = + ((*drv)[cd[24]] + 0.5*((*drv)[cd[22]] + (*drv)[cd[23]]) + + 0.75*(*drv)[cd[34]]); + break; + } + + /****************************************************************************/ + /* values on child[1] */ + /****************************************************************************/ + + cd = basFct->getLocalIndices(el->getChild(1), admin, NULL); + + if (typ == 0) { + switch(lr_set) { + case 1: + (*drv)[pd[0]] += + (0.0390625*(-(*drv)[cd[25]] - (*drv)[cd[26]] - (*drv)[cd[34]])); + (*drv)[pd[1]] += + (-0.0390625*(*drv)[cd[25]] + + 0.0234375*((*drv)[cd[26]] + (*drv)[cd[34]])); + (*drv)[pd[4]] += + (0.15625*(*drv)[cd[25]] + + 0.09375*((*drv)[cd[26]] + (*drv)[cd[34]])); + (*drv)[pd[5]] += + (-0.234375*(*drv)[cd[25]] + + 0.046875*(-(*drv)[cd[26]] - (*drv)[cd[34]])); + (*drv)[pd[6]] += + (0.15625*(*drv)[cd[25]] + + 0.03125*(-(*drv)[cd[26]] - (*drv)[cd[34]])); + (*drv)[pd[7]] += + (0.0625*((*drv)[cd[25]] + (*drv)[cd[34]]) + + 0.125*(*drv)[cd[26]]); + (*drv)[pd[8]] += -0.125*(*drv)[cd[26]]; + (*drv)[pd[10]] += 0.0625*(*drv)[cd[34]]; + (*drv)[pd[13]] += + (0.3125*(*drv)[cd[25]] - 0.125*(*drv)[cd[26]] + - 0.0625*(*drv)[cd[34]]); + (*drv)[pd[14]] += 0.375*(*drv)[cd[26]]; + (*drv)[pd[16]] += -0.0625*(*drv)[cd[34]]; + (*drv)[pd[22]] += 0.375*(*drv)[cd[34]]; + (*drv)[pd[25]] += -0.125*(*drv)[cd[34]]; + (*drv)[pd[28]] += -0.1875*(*drv)[cd[34]]; + (*drv)[pd[29]] += 0.1875*(*drv)[cd[34]]; + (*drv)[pd[31]] += + (-0.3125*(*drv)[cd[25]] - 0.375*(*drv)[cd[26]] + - 0.1875*(*drv)[cd[34]]); + (*drv)[pd[32]] += + ((*drv)[cd[27]] + 0.9375*(*drv)[cd[25]] + + 0.375*(*drv)[cd[26]] + 0.1875*(*drv)[cd[34]]); + (*drv)[pd[33]] += 0.75*(*drv)[cd[26]]; + (*drv)[pd[34]] += 0.75*(*drv)[cd[34]]; + break; + case 2: + (*drv)[pd[0]] += + (0.0390625*(-(*drv)[cd[28]] - (*drv)[cd[29]] - (*drv)[cd[34]])); + (*drv)[pd[1]] += + (-0.0390625*(*drv)[cd[28]] + + 0.0234375*((*drv)[cd[29]] + (*drv)[cd[34]])); + (*drv)[pd[4]] += + (0.15625*(*drv)[cd[28]] + + 0.09375*((*drv)[cd[29]] + (*drv)[cd[34]])); + (*drv)[pd[5]] += + (-0.234375*(*drv)[cd[28]] + + 0.046875*(-(*drv)[cd[29]] - (*drv)[cd[34]])); + (*drv)[pd[6]] += + (0.15625*(*drv)[cd[28]] + + 0.03125*(-(*drv)[cd[29]] - (*drv)[cd[34]])); + (*drv)[pd[7]] += 0.0625*(*drv)[cd[34]]; + (*drv)[pd[10]] += + (0.0625*((*drv)[cd[28]] + (*drv)[cd[34]]) + + 0.125*(*drv)[cd[29]]); + (*drv)[pd[11]] += -0.125*(*drv)[cd[29]]; + (*drv)[pd[13]] += -0.0625*(*drv)[cd[34]]; + (*drv)[pd[16]] += + (0.3125*(*drv)[cd[28]] - 0.125*(*drv)[cd[29]] + - 0.0625*(*drv)[cd[34]]); + (*drv)[pd[17]] += 0.375*(*drv)[cd[29]]; + (*drv)[pd[22]] += 0.375*(*drv)[cd[34]]; + (*drv)[pd[25]] += -0.125*(*drv)[cd[34]]; + (*drv)[pd[28]] += + (-0.3125*(*drv)[cd[28]] - 0.375*(*drv)[cd[29]] + - 0.1875*(*drv)[cd[34]]); + (*drv)[pd[29]] += + ((*drv)[cd[30]] + 0.9375*(*drv)[cd[28]] + 0.375*(*drv)[cd[29]] + + 0.1875*(*drv)[cd[34]]); + (*drv)[pd[30]] += 0.75*(*drv)[cd[29]]; + (*drv)[pd[31]] += -0.1875*(*drv)[cd[34]]; + (*drv)[pd[32]] += 0.1875*(*drv)[cd[34]]; + (*drv)[pd[34]] += 0.75*(*drv)[cd[34]]; + break; + case 3: + (*drv)[pd[0]] += -0.0390625*(*drv)[cd[34]]; + (*drv)[pd[1]] += 0.0234375*(*drv)[cd[34]]; + (*drv)[pd[4]] += 0.09375*(*drv)[cd[34]]; + (*drv)[pd[5]] += -0.046875*(*drv)[cd[34]]; + (*drv)[pd[6]] += -0.03125*(*drv)[cd[34]]; + (*drv)[pd[7]] += 0.0625*(*drv)[cd[34]]; + (*drv)[pd[10]] += 0.0625*(*drv)[cd[34]]; + (*drv)[pd[13]] += -0.0625*(*drv)[cd[34]]; + (*drv)[pd[16]] += -0.0625*(*drv)[cd[34]]; + (*drv)[pd[22]] += 0.375*(*drv)[cd[34]]; + (*drv)[pd[25]] += -0.125*(*drv)[cd[34]]; + (*drv)[pd[28]] += -0.1875*(*drv)[cd[34]]; + (*drv)[pd[29]] += 0.1875*(*drv)[cd[34]]; + (*drv)[pd[31]] += -0.1875*(*drv)[cd[34]]; + (*drv)[pd[32]] += 0.1875*(*drv)[cd[34]]; + (*drv)[pd[34]] += 0.75*(*drv)[cd[34]]; + break; + } + } + else { + switch(lr_set) { + case 1: + (*drv)[pd[0]] += + (0.0390625*(-(*drv)[cd[28]] - (*drv)[cd[29]] - (*drv)[cd[34]])); + (*drv)[pd[1]] += + (-0.0390625*(*drv)[cd[28]] + + 0.0234375*((*drv)[cd[29]] + (*drv)[cd[34]])); + (*drv)[pd[4]] += + (0.15625*(*drv)[cd[28]] + + 0.09375*((*drv)[cd[29]] + (*drv)[cd[34]])); + (*drv)[pd[5]] += + (-0.234375*(*drv)[cd[28]] + + 0.046875*(-(*drv)[cd[29]] - (*drv)[cd[34]])); + (*drv)[pd[6]] += + (0.15625*(*drv)[cd[28]] + + 0.03125*(-(*drv)[cd[29]] - (*drv)[cd[34]])); + (*drv)[pd[7]] += + (0.0625*((*drv)[cd[28]] + (*drv)[cd[34]]) + + 0.125*(*drv)[cd[29]]); + (*drv)[pd[8]] += -0.125*(*drv)[cd[29]]; + (*drv)[pd[10]] += 0.0625*(*drv)[cd[34]]; + (*drv)[pd[13]] += + (0.3125*(*drv)[cd[28]] - 0.125*(*drv)[cd[29]] + - 0.0625*(*drv)[cd[34]]); + (*drv)[pd[14]] += 0.375*(*drv)[cd[29]]; + (*drv)[pd[16]] += -0.0625*(*drv)[cd[34]]; + (*drv)[pd[22]] += 0.375*(*drv)[cd[34]]; + (*drv)[pd[25]] += -0.125*(*drv)[cd[34]]; + (*drv)[pd[28]] += -0.1875*(*drv)[cd[34]]; + (*drv)[pd[29]] += 0.1875*(*drv)[cd[34]]; + (*drv)[pd[31]] += + (-0.3125*(*drv)[cd[28]] - 0.375*(*drv)[cd[29]] + - 0.1875*(*drv)[cd[34]]); + (*drv)[pd[32]] += + ((*drv)[cd[30]] + 0.9375*(*drv)[cd[28]] + 0.375*(*drv)[cd[29]] + + 0.1875*(*drv)[cd[34]]); + (*drv)[pd[33]] += 0.75*(*drv)[cd[29]]; + (*drv)[pd[34]] += 0.75*(*drv)[cd[34]]; + break; + case 2: + (*drv)[pd[0]] += + (0.0390625*(-(*drv)[cd[25]] - (*drv)[cd[26]] - (*drv)[cd[34]])); + (*drv)[pd[1]] += (-0.0390625*(*drv)[cd[25]] + + 0.0234375*((*drv)[cd[26]] + (*drv)[cd[34]])); + (*drv)[pd[4]] += (0.15625*(*drv)[cd[25]] + + 0.09375*((*drv)[cd[26]] + (*drv)[cd[34]])); + (*drv)[pd[5]] += (-0.234375*(*drv)[cd[25]] + + 0.046875*(-(*drv)[cd[26]] - (*drv)[cd[34]])); + (*drv)[pd[6]] += (0.15625*(*drv)[cd[25]] + + 0.03125*(-(*drv)[cd[26]] - (*drv)[cd[34]])); + (*drv)[pd[7]] += 0.0625*(*drv)[cd[34]]; + (*drv)[pd[10]] += (0.0625*((*drv)[cd[25]] + (*drv)[cd[34]]) + + 0.125*(*drv)[cd[26]]); + (*drv)[pd[11]] += -0.125*(*drv)[cd[26]]; + (*drv)[pd[13]] += -0.0625*(*drv)[cd[34]]; + (*drv)[pd[16]] += (0.3125*(*drv)[cd[25]] - 0.125*(*drv)[cd[26]] + - 0.0625*(*drv)[cd[34]]); + (*drv)[pd[17]] += 0.375*(*drv)[cd[26]]; + (*drv)[pd[22]] += 0.375*(*drv)[cd[34]]; + (*drv)[pd[25]] += -0.125*(*drv)[cd[34]]; + (*drv)[pd[28]] += (-0.3125*(*drv)[cd[25]] - 0.375*(*drv)[cd[26]] + - 0.1875*(*drv)[cd[34]]); + (*drv)[pd[29]] += ((*drv)[cd[27]] + 0.9375*(*drv)[cd[25]] + + 0.375*(*drv)[cd[26]] + 0.1875*(*drv)[cd[34]]); + (*drv)[pd[30]] += 0.75*(*drv)[cd[26]]; + (*drv)[pd[31]] += -0.1875*(*drv)[cd[34]]; + (*drv)[pd[32]] += 0.1875*(*drv)[cd[34]]; + (*drv)[pd[34]] += 0.75*(*drv)[cd[34]]; + break; + case 3: + (*drv)[pd[0]] += -0.0390625*(*drv)[cd[34]]; + (*drv)[pd[1]] += 0.0234375*(*drv)[cd[34]]; + (*drv)[pd[4]] += 0.09375*(*drv)[cd[34]]; + (*drv)[pd[5]] += -0.046875*(*drv)[cd[34]]; + (*drv)[pd[6]] += -0.03125*(*drv)[cd[34]]; + (*drv)[pd[7]] += 0.0625*(*drv)[cd[34]]; + (*drv)[pd[10]] += 0.0625*(*drv)[cd[34]]; + (*drv)[pd[13]] += -0.0625*(*drv)[cd[34]]; + (*drv)[pd[16]] += -0.0625*(*drv)[cd[34]]; + (*drv)[pd[22]] += 0.375*(*drv)[cd[34]]; + (*drv)[pd[25]] += -0.125*(*drv)[cd[34]]; + (*drv)[pd[28]] += -0.1875*(*drv)[cd[34]]; + (*drv)[pd[29]] += 0.1875*(*drv)[cd[34]]; + (*drv)[pd[31]] += -0.1875*(*drv)[cd[34]]; + (*drv)[pd[32]] += 0.1875*(*drv)[cd[34]]; + (*drv)[pd[34]] += 0.75*(*drv)[cd[34]]; + break; + } + } + } + + return; + } + + // ====== coarseInter functions ====== + + void Lagrange::coarseInter0(DOFIndexed<double> *drv, RCNeighbourList* list, + int n, BasisFunction* basFct) + { + FUNCNAME("Lagrange::coarseInter0"); + Element *el; + DegreeOfFreedom cdof, pdof; + const DOFAdmin *admin; + const Mesh *mesh = NULL; + + if (n < 1) return; + el = list->getElement(0); + + if (!drv->getFESpace()) + { + ERROR("no fe_space in dof_real_vec\n"); + return; + } + else if (!drv->getFESpace()->getBasisFcts()) + { + ERROR("no basis functions in fe_space %s\n", + drv->getFESpace()->getName().c_str()); + return; + } + + admin = drv->getFESpace()->getAdmin(); + mesh = drv->getFESpace()->getMesh(); + + /****************************************************************************/ + /* values on child[0] */ + /****************************************************************************/ + + cdof = el->getChild(0)->getDOF(mesh->getNode(CENTER)+2, + admin->getNumberOfPreDOFs(CENTER)); + pdof = el->getDOF(mesh->getNode(CENTER)+2, admin->getNumberOfPreDOFs(CENTER)); + (*drv)[pdof] = (*drv)[cdof]; + + return; + } + + void Lagrange::coarseInter2_1d(DOFIndexed<double> *drv, RCNeighbourList *list, + int n, BasisFunction* basFct) + { + FUNCNAME("real_coarseInter2"); + Element *el; + //double *v = NULL; + DegreeOfFreedom cdof, pdof; + const DOFAdmin *admin; + Mesh *mesh = NULL; + + if (n < 1) return; + el = list->getElement(0); + + if (!drv->getFESpace()) + { + ERROR("no fe_space in dof_real_vec\n"); + return; + } + else if (!drv->getFESpace()->getBasisFcts()) + { + ERROR("no basis functions in fe_space %s\n", + drv->getFESpace()->getName().c_str()); + return; + } + + admin = drv->getFESpace()->getAdmin(); + mesh = const_cast<Mesh*>(drv->getFESpace()->getMesh()); + + /****************************************************************************/ + /* values on child[0] */ + /****************************************************************************/ + + cdof = el->getChild(0)->getDOF(mesh->getNode(VERTEX)+1, + admin->getNumberOfPreDOFs(VERTEX)); + pdof = el->getDOF(mesh->getNode(CENTER), admin->getNumberOfPreDOFs(CENTER)); + (*drv)[pdof] = (*drv)[cdof]; + + return; + } + + void Lagrange::coarseInter2_2d(DOFIndexed<double> *drv, RCNeighbourList* list, + int n, BasisFunction* basFct) + { + FUNCNAME("Lagrange::coarseInter2_2d"); + Element *el; + DegreeOfFreedom cdof, pdof; + const DOFAdmin *admin; + const Mesh *mesh = NULL; + + if (n < 1) return; + el = list->getElement(0); + + if (!drv->getFESpace()) + { + ERROR("no fe_space in dof_real_vec\n"); + return; + } + else if (!drv->getFESpace()->getBasisFcts()) + { + ERROR("no basis functions in fe_space %s\n", + drv->getFESpace()->getName().c_str()); + return; + } + + admin = drv->getFESpace()->getAdmin(); + mesh = drv->getFESpace()->getMesh(); + + /****************************************************************************/ + /* values on child[0] */ + /****************************************************************************/ + + cdof = el->getChild(0)->getDOF(mesh->getNode(VERTEX)+2, + admin->getNumberOfPreDOFs(VERTEX)); + pdof = el->getDOF(mesh->getNode(EDGE)+2, admin->getNumberOfPreDOFs(EDGE)); + (*drv)[pdof] = (*drv)[cdof]; + + return; + } + + void Lagrange::coarseInter2_3d(DOFIndexed<double> *drv, RCNeighbourList* list, + int n, BasisFunction* basFct) + { + FUNCNAME("Lagrange::coarseInter2_3d"); + Element *el; + int cdof, pdof; + const DOFAdmin *admin; + const Mesh *mesh = NULL; + + if (n < 1) return; + el = list->getElement(0); + + if (!drv->getFESpace()) + { + ERROR("no fe_space in dof_real_vec\n"); + return; + } + else if (!drv->getFESpace()->getBasisFcts()) + { + ERROR("no basis functions in fe_space %s\n", + drv->getFESpace()->getName().c_str()); + return; + } + admin = drv->getFESpace()->getAdmin(); + mesh = drv->getFESpace()->getMesh(); + + cdof = el->getChild(0)->getDOF(mesh->getNode(VERTEX)+3, + admin->getNumberOfPreDOFs(VERTEX)); + pdof = el->getDOF(mesh->getNode(EDGE), admin->getNumberOfPreDOFs(EDGE)); + (*drv)[pdof] = (*drv)[cdof]; + + return; + } + + void Lagrange::coarseInter3_1d(DOFIndexed<double> *drv, RCNeighbourList* list, + int n, BasisFunction* basFct) + { + FUNCNAME("Lagrange::coarseInter3_1d"); + const Element *el, *child; + int cdof, pdof, node, n0; + const DOFAdmin *admin; + const Mesh *mesh = NULL; + + if (n < 1) return; + el = list->getElement(0); + + if (!drv->getFESpace()) + { + ERROR("no fe_space in dof_real_vec\n"); + return; + } + else if (!drv->getFESpace()->getBasisFcts()) + { + ERROR("no basis functions in fe_space %s\n", + drv->getFESpace()->getName().c_str()); + return; + } + admin = drv->getFESpace()->getAdmin(); + mesh = drv->getFESpace()->getMesh(); + + node = mesh->getNode(EDGE); + n0 = admin->getNumberOfPreDOFs(EDGE); + + /****************************************************************************/ + /* values on child[0] */ + /****************************************************************************/ + + child = el->getChild(0); + + if (el->getDOF(0, 0) < el->getDOF(1, 0)) + pdof = el->getDOF(node+2, n0); + else + pdof = el->getDOF(node+2, n0+1); + + if (child->getDOF(1, 0) < child->getDOF(2, 0)) + cdof = child->getDOF(node, n0+1); + else + cdof = child->getDOF(node, n0); + + (*drv)[pdof] = (*drv)[cdof]; + + if (child->getDOF(2, 0) < child->getDOF(0, 0)) + cdof = child->getDOF(node+1, n0); + else + cdof = child->getDOF(node+1, n0+1); + + (*drv)[el->getDOF(mesh->getNode(CENTER), admin->getNumberOfPreDOFs(CENTER))] = + (*drv)[cdof]; + + /****************************************************************************/ + /* values on child[1] */ + /****************************************************************************/ + + child = el->getChild(1); + + if (el->getDOF(0, 0) < el->getDOF(1, 0)) + pdof = el->getDOF(node+2, n0+1); + else + pdof = el->getDOF(node+2, n0); + + if (child->getDOF(2, 0) < child->getDOF(0,0)) + cdof = child->getDOF(node+1, n0); + else + cdof = child->getDOF(node+1, n0+1); + + (*drv)[pdof] = (*drv)[cdof]; + + if (n <= 1) return; + + /****************************************************************************/ + /* adjust neighbour values */ + /****************************************************************************/ + + el = list->getElement(1); + child = el->getChild(0); + + if (child->getDOF(2,0) < child->getDOF(0, 0)) + cdof = child->getDOF(node+1, n0); + else + cdof = child->getDOF(node+1, n0+1); + + (*drv)[el->getDOF(mesh->getNode(CENTER), admin->getNumberOfPreDOFs(CENTER))] = + (*drv)[cdof]; + + return; + } + + void Lagrange::coarseInter3_2d(DOFIndexed<double> *drv, RCNeighbourList* list, + int n, BasisFunction* basFct) + { + FUNCNAME("Lagrange::coarseInter3_2d"); + const Element *el, *child; + int cdof, pdof, node, n0; + const DOFAdmin *admin; + const Mesh *mesh = NULL; + + if (n < 1) return; + el = list->getElement(0); + + if (!drv->getFESpace()) + { + ERROR("no fe_space in dof_real_vec\n"); + return; + } + else if (!drv->getFESpace()->getBasisFcts()) + { + ERROR("no basis functions in fe_space %s\n", + drv->getFESpace()->getName().c_str()); + return; + } + admin = drv->getFESpace()->getAdmin(); + mesh = drv->getFESpace()->getMesh(); + + node = mesh->getNode(EDGE); + n0 = admin->getNumberOfPreDOFs(EDGE); + + /****************************************************************************/ + /* values on child[0] */ + /****************************************************************************/ + + child = el->getChild(0); + + if (el->getDOF(0, 0) < el->getDOF(1, 0)) + pdof = el->getDOF(node+2, n0); + else + pdof = el->getDOF(node+2, n0+1); + + if (child->getDOF(1, 0) < child->getDOF(2, 0)) + cdof = child->getDOF(node, n0+1); + else + cdof = child->getDOF(node, n0); + + (*drv)[pdof] = (*drv)[cdof]; + + if (child->getDOF(2, 0) < child->getDOF(0, 0)) + cdof = child->getDOF(node+1, n0); + else + cdof = child->getDOF(node+1, n0+1); + + (*drv)[el->getDOF(mesh->getNode(CENTER), admin->getNumberOfPreDOFs(CENTER))] = + (*drv)[cdof]; + + /****************************************************************************/ + /* values on child[1] */ + /****************************************************************************/ + + child = el->getChild(1); + + if (el->getDOF(0, 0) < el->getDOF(1, 0)) + pdof = el->getDOF(node+2, n0+1); + else + pdof = el->getDOF(node+2, n0); + + if (child->getDOF(2, 0) < child->getDOF(0, 0)) + cdof = child->getDOF(node+1, n0); + else + cdof = child->getDOF(node+1, n0+1); + + (*drv)[pdof] = (*drv)[cdof]; + + if (n <= 1) return; + + /****************************************************************************/ + /* adjust neighbour values */ + /****************************************************************************/ + + el = list->getElement(1); + child = el->getChild(0); + + if (child->getDOF(2, 0) < child->getDOF(0, 0)) + cdof = child->getDOF(node+1, n0); + else + cdof = child->getDOF(node+1, n0+1); + + (*drv)[el->getDOF(mesh->getNode(CENTER), admin->getNumberOfPreDOFs(CENTER))] = + (*drv)[cdof]; + + return; + } + + void Lagrange::coarseInter3_3d(DOFIndexed<double> *drv, RCNeighbourList* list, + int n, BasisFunction* basFct) + { + FUNCNAME("Lagrange::coarseInter3_3d"); + const Element *el; + int i, lr_set; + int node_e, node_f, n0_e, n0_f; + const DegreeOfFreedom **pds, **cds; + DegreeOfFreedom pd_o[20], cd, pd; + const DOFAdmin *admin; + + if (n < 1) return; + el = list->getElement(0); + + if (!drv->getFESpace()) + { + ERROR("no fe_space in dof_real_vec\n"); + return; + } + else if (!drv->getFESpace()->getBasisFcts()) + { + ERROR("no basis functions in fe_space %s\n", + drv->getFESpace()->getName().c_str()); + return; + } + + admin = drv->getFESpace()->getAdmin(); + + node_e = drv->getFESpace()->getMesh()->getNode(EDGE); + n0_e = admin->getNumberOfPreDOFs(EDGE); + node_f = drv->getFESpace()->getMesh()->getNode(FACE); + n0_f = admin->getNumberOfPreDOFs(FACE); + + /****************************************************************************/ + /* values on child[0] */ + /****************************************************************************/ + pds = el->getDOF(); + cds = el->getChild(0)->getDOF(); + basFct->getLocalIndices(el, admin, pd_o); + + pd = (pds[0][0] < pds[1][0]) ? pds[node_e][n0_e] : pds[node_e][n0_e+1]; + cd = cds[0][0] < cds[3][0] ? cds[node_e+2][n0_e+1] : cds[node_e+2][n0_e]; + (*drv)[pd] = (*drv)[cd]; + + pd = el->getDOF(node_f+2, n0_f); + cd = cds[2][0] < cds[3][0] ? cds[node_e+5][n0_e+1] : cds[node_e+5][n0_e]; + (*drv)[pd] = (*drv)[cd]; + + pd = el->getDOF(node_f+3, n0_f); + cd = cds[1][0] < cds[3][0] ? cds[node_e+4][n0_e+1] : cds[node_e+4][n0_e]; + (*drv)[pd] = (*drv)[cd]; + + /****************************************************************************/ + /* values on child[1] */ + /****************************************************************************/ + + cds = el->getChild(1)->getDOF(); + + pd = (pds[0][0] < pds[1][0]) ? pds[node_e][n0_e+1] : pds[node_e][n0_e]; + cd = cds[0][0] < cds[3][0] ? cds[node_e+2][n0_e+1] : cds[node_e+2][n0_e]; + (*drv)[pd] = (*drv)[cd]; + + /****************************************************************************/ + /* adjust neighbour values */ + /****************************************************************************/ + + for (i = 1; i < n; i++) + { + el = list->getElement(i); + + pds = el->getDOF(); + cds = el->getChild(0)->getDOF(); + + lr_set = 0; + if (list->getNeighbourElement(i, 0) && list->getNeighbourNr(i, 0) < i) + lr_set = 1; + + if (list->getNeighbourElement(i, 1) && list->getNeighbourNr(i, 1) < i) + lr_set += 2; + + TEST_EXIT(lr_set)("no values set on both neighbours\n"); + + switch(lr_set) + { + case 1: + pd = el->getDOF(node_f+3, n0_f); + cd = cds[1][0] < cds[3][0] ? + cds[node_e+4][n0_e+1] : cds[node_e+4][n0_e]; + (*drv)[pd] = (*drv)[cd]; + break; + case 2: + pd = el->getDOF(node_f+2, n0_f); + cd = cds[2][0] < cds[3][0] ? + cds[node_e+5][n0_e+1] : cds[node_e+5][n0_e]; + (*drv)[pd] = (*drv)[cd]; + break; + } + } + return; + } + + void Lagrange::coarseInter4_1d(DOFIndexed<double> *drv, RCNeighbourList* list, + int n, BasisFunction* basFct) + { + FUNCNAME("Lagrange::coarseInter4_1d"); + Element *el; + DegreeOfFreedom pdof[5]; + const DegreeOfFreedom *cdof; + const DOFAdmin *admin; + + if (n < 1) return; + el = list->getElement(0); + + if (!drv->getFESpace()) + { + ERROR("no fe_space in dof_real_vec\n"); + return; + } + else if (!drv->getFESpace()->getBasisFcts()) + { + ERROR("no basis functions in fe_space %s\n", + drv->getFESpace()->getName().c_str()); + return; + } + + admin = drv->getFESpace()->getAdmin(); + + basFct->getLocalIndices(el, admin, pdof); + + /****************************************************************************/ + /* values on child[0] */ + /****************************************************************************/ + + cdof = basFct->getLocalIndices(el->getChild(0), admin, NULL); + + (*drv)[pdof[9]] = (*drv)[cdof[4]]; + (*drv)[pdof[10]] = (*drv)[cdof[2]]; + (*drv)[pdof[12]] = (*drv)[cdof[14]]; + (*drv)[pdof[14]] = (*drv)[cdof[7]]; + + /****************************************************************************/ + /* values on child[1] */ + /****************************************************************************/ + + cdof = basFct->getLocalIndices(el->getChild(1), admin, NULL); + + (*drv)[pdof[11]] = (*drv)[cdof[7]]; + (*drv)[pdof[13]] = (*drv)[cdof[14]]; + + if (n <= 1) return; + + /****************************************************************************/ + /* adjust neighbour values */ + /****************************************************************************/ + + el = list->getElement(1); + + basFct->getLocalIndices(el, admin, pdof); + + /****************************************************************************/ + /* values on neighbour's child[0] */ + /****************************************************************************/ + + cdof = basFct->getLocalIndices(el->getChild(0), admin, NULL); + + (*drv)[pdof[12]] = (*drv)[cdof[14]]; + (*drv)[pdof[14]] = (*drv)[cdof[7]]; + + /****************************************************************************/ + /* values on neighbour's child[1] */ + /****************************************************************************/ + + cdof = basFct->getLocalIndices(el->getChild(1), admin, NULL); + + (*drv)[pdof[13]] = (*drv)[cdof[14]]; + + return; + } + + void Lagrange::coarseInter4_2d(DOFIndexed<double> *drv, RCNeighbourList* list, + int n, BasisFunction* basFct) + { + FUNCNAME("Lagrange::coarseInter4_2d"); + const Element *el; + DegreeOfFreedom pdof[15]; + const DegreeOfFreedom *cdof; + const DOFAdmin *admin; + + if (n < 1) return; + el = list->getElement(0); + + if (!drv->getFESpace()) + { + ERROR("no fe_space in dof_real_vec\n"); + return; + } + else if (!drv->getFESpace()->getBasisFcts()) + { + ERROR("no basis functions in fe_space %s\n", + drv->getFESpace()->getName().c_str()); + return; + } + + admin = drv->getFESpace()->getAdmin(); + + basFct->getLocalIndices(el, admin, pdof); + + /****************************************************************************/ + /* values on child[0] */ + /****************************************************************************/ + + cdof = basFct->getLocalIndices(el->getChild(0), admin, NULL); + + (*drv)[pdof[9]] = (*drv)[cdof[4]]; + (*drv)[pdof[10]] = (*drv)[cdof[2]]; + (*drv)[pdof[12]] = (*drv)[cdof[14]]; + (*drv)[pdof[14]] = (*drv)[cdof[7]]; + + /****************************************************************************/ + /* values on child[1] */ + /****************************************************************************/ + + cdof = basFct->getLocalIndices(el->getChild(1), admin, NULL); + + (*drv)[pdof[11]] = (*drv)[cdof[7]]; + (*drv)[pdof[13]] = (*drv)[cdof[14]]; + + if (n <= 1) return; + + /****************************************************************************/ + /* adjust neighbour values */ + /****************************************************************************/ + + el = list->getElement(1); + + basFct->getLocalIndices(el, admin, pdof); + + /****************************************************************************/ + /* values on neighbour's child[0] */ + /****************************************************************************/ + + cdof = basFct->getLocalIndices(el->getChild(0), admin, NULL); + + (*drv)[pdof[12]] = (*drv)[cdof[14]]; + (*drv)[pdof[14]] = (*drv)[cdof[7]]; + + /****************************************************************************/ + /* values on neighbour's child[1] */ + /****************************************************************************/ + + cdof = basFct->getLocalIndices(el->getChild(1), admin, NULL); + + (*drv)[pdof[13]] = (*drv)[cdof[14]]; + + return; + } + + void Lagrange::coarseInter4_3d(DOFIndexed<double> *drv, RCNeighbourList* list, + int n, BasisFunction* basFct) + { + FUNCNAME("void Lagrange::coarseInter4_3d"); + DegreeOfFreedom pd[35]; + const DegreeOfFreedom *cd; + const Element *el; + int i, typ, lr_set; + const DOFAdmin *admin; + + if (n < 1) return; + el = list->getElement(0); + typ = list->getType(0); + + if (!drv->getFESpace()) + { + ERROR("no fe_space in dof_real_vec\n"); + return; + } + else if (!drv->getFESpace()->getBasisFcts()) + { + ERROR("no basis functions in fe_space %s\n", + drv->getFESpace()->getName().c_str()); + return; + } + + admin = drv->getFESpace()->getAdmin(); + + basFct->getLocalIndices(el, admin, pd); + + /****************************************************************************/ + /* values on child[0] */ + /****************************************************************************/ + + cd = basFct->getLocalIndices(el->getChild(0), admin, NULL); + + (*drv)[pd[4]] = (*drv)[cd[11]]; + (*drv)[pd[5]] = (*drv)[cd[3]]; + (*drv)[pd[28]] = (*drv)[cd[27]]; + (*drv)[pd[30]] = (*drv)[cd[20]]; + (*drv)[pd[31]] = (*drv)[cd[30]]; + (*drv)[pd[33]] = (*drv)[cd[17]]; + (*drv)[pd[34]] = (*drv)[cd[24]]; + + /****************************************************************************/ + /* values on child[1] */ + /****************************************************************************/ + + cd = basFct->getLocalIndices(el->getChild(1), admin, NULL); + + if (typ == 0) + { + /****************************************************************************/ + /* parent of el_type 0 */ + /****************************************************************************/ + + (*drv)[pd[6]] = (*drv)[cd[11]]; + (*drv)[pd[29]] = (*drv)[cd[30]]; + (*drv)[pd[32]] = (*drv)[cd[27]]; + } + else + { + /****************************************************************************/ + /* parent of el_type 1|2 */ + /****************************************************************************/ + + (*drv)[pd[6]] = (*drv)[cd[11]]; + (*drv)[pd[29]] = (*drv)[cd[27]]; + (*drv)[pd[32]] = (*drv)[cd[30]]; + } + + /****************************************************************************/ + /* adjust neighbour values */ + /****************************************************************************/ + + for (i = 1; i < n; i++) + { + el = list->getElement(i); + typ = list->getType(i); + basFct->getLocalIndices(el, admin, pd); + + lr_set = 0; + if (list->getNeighbourElement(i,0) && list->getNeighbourNr(i,0) < i) + lr_set = 1; + + if (list->getNeighbourElement(i,1) && list->getNeighbourNr(i,1) < i) + lr_set += 2; + + TEST_EXIT(lr_set)("no values set on both neighbours\n"); + + /****************************************************************************/ + /* values on child[0] */ + /****************************************************************************/ + + cd = basFct->getLocalIndices(el->getChild(0), admin, NULL); + + switch(lr_set) + { + case 1: + (*drv)[pd[31]] = (*drv)[cd[30]]; + (*drv)[pd[33]] = (*drv)[cd[17]]; + (*drv)[pd[34]] = (*drv)[cd[24]]; + break; + case 2: + (*drv)[pd[28]] = (*drv)[cd[27]]; + (*drv)[pd[30]] = (*drv)[cd[20]]; + (*drv)[pd[34]] = (*drv)[cd[24]]; + break; + case 3: + (*drv)[pd[34]] = (*drv)[cd[24]]; + break; + } + + /****************************************************************************/ + /* values on child[1] */ + /****************************************************************************/ + + cd = basFct->getLocalIndices(el->getChild(1), admin, NULL); + + if (typ == 0) + { + switch(lr_set) + { + case 1: + (*drv)[pd[32]] = (*drv)[cd[27]]; + break; + case 2: + (*drv)[pd[29]] = (*drv)[cd[30]]; + break; + } + } + else + { + switch(lr_set) + { + case 1: + (*drv)[pd[32]] = (*drv)[cd[30]]; + break; + case 2: + (*drv)[pd[29]] = (*drv)[cd[27]]; + break; + } + } + } + + return; + } + +} diff --git a/AMDiS/src/Lagrange.h b/AMDiS/src/Lagrange.h new file mode 100644 index 0000000000000000000000000000000000000000..c5d6183ed1fe4a36f91c91278e721635403361ed --- /dev/null +++ b/AMDiS/src/Lagrange.h @@ -0,0 +1,978 @@ +// ============================================================================ +// == == +// == AMDiS - Adaptive multidimensional simulations == +// == == +// ============================================================================ +// == == +// == crystal growth group == +// == == +// == Stiftung caesar == +// == Ludwig-Erhard-Allee 2 == +// == 53175 Bonn == +// == germany == +// == == +// ============================================================================ +// == == +// == http://www.caesar.de/cg/AMDiS == +// == == +// ============================================================================ + +/** \file Lagrange.h */ + +#ifndef AMDIS_LAGRANGE_H +#define AMDIS_LAGRANGE_H + +#include "BasisFunction.h" +#include "FixVec.h" +#include "AbstractFunction.h" +#include "MemoryManager.h" +#include <list> + +namespace AMDiS { + +#define MAX_DIM 3 +#define MAX_DEGREE 4 + + template<typename ReturnType, typename ArgumentType> class AbstractFunction; + + // ============================================================================ + // ===== class Lagrange ======================================================= + // ============================================================================ + + /** \ingroup FEMSpace + * \brief + * Lagrange basis functions. Sub class of BasisFunction + */ + class Lagrange : public BasisFunction + { + public: + MEMORY_MANAGED(Lagrange); + + protected: + /** \brief + * Constructs lagrange basis functions with the given dim and degree. + * Constructor is protected to avoid multiple instantiation of identical + * basis functions. Use \ref getLagrange instead. + */ + Lagrange(int dim_, int degree_); + + /** \brief + * destructor + */ + virtual ~Lagrange(); + + public: + /** \brief + * Returns a pointer to lagrange basis functions with the given dim and + * degree. Multiple instantiation of identical basis functions is avoided + * by rembering once created basis functions in \ref allBasFcts. + */ + static Lagrange* getLagrange(int dim_, int degree_); + + /** \brief + * Implements BasisFunction::interpol + */ + const double *interpol(const ElInfo *, int, const int *, + AbstractFunction<double, WorldVector<double> >*, double *); + + + /** \brief + * Implements BasisFunction::interpol + */ + const WorldVector<double> *interpol(const ElInfo *, int, const int *b_no, + AbstractFunction<WorldVector<double>, WorldVector<double> >*, + WorldVector<double> *); + + /** \brief + * Returns the barycentric coordinates of the i-th basis function. + */ + DimVec<double> *getCoords(int i) const; + + /** \brief + * Implements BasisFunction::getDOFIndices + */ + const DegreeOfFreedom* getDOFIndices(const Element*, const DOFAdmin&, + DegreeOfFreedom*) const; + + /** \brief + * Implements BasisFunction::getBound + */ + const BoundaryType* getBound(const ElInfo*, BoundaryType *) const; + + /** \brief + * Calculates the local vertex indices which are involved in evaluating + * the nodeIndex-th DOF at the positionIndex-th part of type position + * (VERTEX/EDGE/FACE/CENTER). nodeIndex determines the permutation + * of the involved vertices. So in 1d for lagrange4 there are two DOFs at + * the CENTER (which is an edge in this case). Then vertices[0] = {0, 1} and + * vertices[1] = {1, 0}. This allows to use the same local basis function + * for all DOFs at the same position. + */ + static void setVertices(int dim, int degree, + GeoIndex position, int positionIndex, int nodeIndex, + int** vertices); + + /** \brief + * Implements BasisFunction::refineInter + */ + inline void refineInter(DOFIndexed<double> *drv, + RCNeighbourList* list, + int n) + { + if(refineInter_fct) + (*refineInter_fct)(drv, list, n, this); + }; + + /** \brief + * Implements BasisFunction::coarseRestrict + */ + inline void coarseRestr(DOFIndexed<double> *drv, + RCNeighbourList* list, + int n) + { + if(coarseRestr_fct) + (*coarseRestr_fct)(drv, list, n, this); + }; + + /** \brief + * Implements BasisFunction::coarseInter + */ + inline void coarseInter(DOFIndexed<double> *drv, + RCNeighbourList* list, + int n) + { + if(coarseInter_fct) + (*coarseInter_fct)(drv, list, n, this); + }; + + /** \brief + * Implements BasisFunction::getLocalIndices(). + */ + const DegreeOfFreedom *getLocalIndices(const Element*, + const DOFAdmin*, + DegreeOfFreedom*) const; + + /** \brief + * Implements BasisFunction::getVec(). + */ + // const double *getVec(const Element* el, + // const DOFVector<double> * dv, + // double * d) const; + + /** \brief + * Implements BasisFunction::getVec + */ + // const WorldVector<double> *getVec(const Element* el, + // const DOFVector<WorldVector<double> > * dv, + // WorldVector<double> *d) const; + + /** \brief + * Implements BasisFunction::l2ScpFctBas + */ + void l2ScpFctBas(Quadrature* q, + AbstractFunction<double, WorldVector<double> >* f, + DOFVector<double>* fh); + + /** \brief + * Implements BasisFunction::l2ScpFctBas + */ + void l2ScpFctBas(Quadrature* q, + AbstractFunction<WorldVector<double>, WorldVector<double> >* f, + DOFVector<WorldVector<double> >* fh); + + protected: + /** \brief + * sets the barycentric coordinates (stored in \ref bary) of the local + * basis functions. + */ + void setBary(); + + /** \brief + * Recursive calculation of coordinates. Used by \ref setBary + */ + void createCoords(int* coordInd, int numCoords, int dimIndex, int rest, + DimVec<double>* vec=NULL); + + /** \brief + * Used by \ref setBary + */ + int** getIndexPermutations(int numIndices) const; + + /** \brief + * Implements BasisFunction::setNDOF + */ + void setNDOF(); + + /** \brief + * Sets used function pointers + */ + void setFunctionPointer(); + + /** \brief + * Used by \ref getDOFIndices and \ref getVec + */ + int* orderOfPositionIndices(const Element* el, GeoIndex position, + int positionIndex) const; + + /** \brief + * Calculates the number of DOFs needed for Lagrange of the given dim and + * degree. + */ + static int getNumberOfDOFs(int dim, int degree); + + private: + /** \brief + * barycentric coordinates of the locations of all basis functions + */ + ::std::vector<DimVec<double>* > *bary; + + /** \name static dim-degree-arrays + * \{ + */ + static ::std::vector<DimVec<double>* > baryDimDegree[MAX_DIM+1][MAX_DEGREE+1]; + static DimVec<int>* ndofDimDegree[MAX_DIM+1][MAX_DEGREE+1]; + static int nBasFctsDimDegree[MAX_DIM+1][MAX_DEGREE+1]; + static ::std::vector<BasFctType*> phiDimDegree[MAX_DIM+1][MAX_DEGREE+1]; + static ::std::vector<GrdBasFctType*> grdPhiDimDegree[MAX_DIM+1][MAX_DEGREE+1]; + static ::std::vector<D2BasFctType*> D2PhiDimDegree[MAX_DIM+1][MAX_DEGREE+1]; + /** \} */ + + /** \brief + * List of all used BasisFunctions in the whole program. Avoids duplicate + * instantiation of identical BasisFunctions. + */ + static ::std::list<Lagrange*> allBasFcts; + + + protected: + /** \brief + * Pointer to the used refineInter function + */ + void (*refineInter_fct)(DOFIndexed<double> *, RCNeighbourList*, int, + BasisFunction*); + + /** \name refineInter functions + * \{ + */ + static void refineInter0(DOFIndexed<double> *, RCNeighbourList*, int, + BasisFunction*); + static void refineInter1(DOFIndexed<double> *, RCNeighbourList*, int, + BasisFunction*); + static void refineInter2_1d(DOFIndexed<double> *, RCNeighbourList*, int, + BasisFunction*); + static void refineInter2_2d(DOFIndexed<double> *, RCNeighbourList*, int, + BasisFunction*); + static void refineInter2_3d(DOFIndexed<double> *, RCNeighbourList*, int, + BasisFunction*); + static void refineInter3_1d(DOFIndexed<double> *, RCNeighbourList*, int, + BasisFunction*); + static void refineInter3_2d(DOFIndexed<double> *, RCNeighbourList*, int, + BasisFunction*); + static void refineInter3_3d(DOFIndexed<double> *, RCNeighbourList*, int, + BasisFunction*); + static void refineInter4_1d(DOFIndexed<double> *, RCNeighbourList*, int, + BasisFunction*); + static void refineInter4_2d(DOFIndexed<double> *, RCNeighbourList*, int, + BasisFunction*); + static void refineInter4_3d(DOFIndexed<double> *, RCNeighbourList*, int, + BasisFunction*); + /** \} */ + + /** \brief + * Pointer to the used coarseRestr function + */ + void (*coarseRestr_fct)(DOFIndexed<double> *, RCNeighbourList*, int, + BasisFunction*); + + /** \name coarseRestr functions + * \{ + */ + static void coarseRestr0(DOFIndexed<double> *, RCNeighbourList*, int, + BasisFunction*); + static void coarseRestr1(DOFIndexed<double> *, RCNeighbourList*, int, + BasisFunction*); + static void coarseRestr2_1d(DOFIndexed<double> *, RCNeighbourList*, int, + BasisFunction*); + static void coarseRestr2_2d(DOFIndexed<double> *, RCNeighbourList*, int, + BasisFunction*); + static void coarseRestr2_3d(DOFIndexed<double> *, RCNeighbourList*, int, + BasisFunction*); + static void coarseRestr3_1d(DOFIndexed<double> *, RCNeighbourList*, int, + BasisFunction*); + static void coarseRestr3_2d(DOFIndexed<double> *, RCNeighbourList*, int, + BasisFunction*); + static void coarseRestr3_3d(DOFIndexed<double> *, RCNeighbourList*, int, + BasisFunction*); + static void coarseRestr4_1d(DOFIndexed<double> *, RCNeighbourList*, int, + BasisFunction*); + static void coarseRestr4_2d(DOFIndexed<double> *, RCNeighbourList*, int, + BasisFunction*); + static void coarseRestr4_3d(DOFIndexed<double> *, RCNeighbourList*, int, + BasisFunction*); + /** \} */ + + /** \brief + * Pointer to the used coarseInter function + */ + void (*coarseInter_fct)(DOFIndexed<double> *, RCNeighbourList*, int, + BasisFunction*); + + /** \name coarseInter functions + * \{ + */ + static void coarseInter0(DOFIndexed<double> *, RCNeighbourList*, int, + BasisFunction*); + static void coarseInter1(DOFIndexed<double> *, RCNeighbourList*, int, + BasisFunction*); + static void coarseInter2_1d(DOFIndexed<double> *, RCNeighbourList*, int, + BasisFunction*); + static void coarseInter2_2d(DOFIndexed<double> *, RCNeighbourList*, int, + BasisFunction*); + static void coarseInter2_3d(DOFIndexed<double> *, RCNeighbourList*, int, + BasisFunction*); + static void coarseInter3_1d(DOFIndexed<double> *, RCNeighbourList*, int, + BasisFunction*); + static void coarseInter3_2d(DOFIndexed<double> *, RCNeighbourList*, int, + BasisFunction*); + static void coarseInter3_3d(DOFIndexed<double> *, RCNeighbourList*, int, + BasisFunction*); + static void coarseInter4_1d(DOFIndexed<double> *, RCNeighbourList*, int, + BasisFunction*); + static void coarseInter4_2d(DOFIndexed<double> *, RCNeighbourList*, int, + BasisFunction*); + static void coarseInter4_3d(DOFIndexed<double> *, RCNeighbourList*, int, + BasisFunction*); + /** \} */ + + // ===== Phi ========================================================= + + /** \brief + * AbstractFunction which implements lagrange basis functions + */ + class Phi : public BasFctType + { + public: + MEMORY_MANAGED(Phi); + + /** \brief + * Constructs the local lagrange basis function for the given position, + * positionIndex and nodeIndex. owner_ is a pointer to the Lagrange object + * this basis function belongs to. + */ + Phi(Lagrange* owner_, GeoIndex position, int positionIndex, int nodeIndex); + + /** \brief + * Destructor + */ + virtual ~Phi(); + + private: + /** \brief + * Lagrange object this function belongs to + */ + Lagrange* owner; + + /** \brief + * vertices needed for evaluation of this function + */ + int* vertices; + + /** \brief + * Pointer to the evaluating function + */ + const double& (*func)(const DimVec<double>& lambda, int* vert); + + /** \brief + * Returns \ref func(lambda, vertices) + */ + inline const double& operator()(const DimVec<double>& lambda) const { + return func(lambda, vertices); + }; + + /** \name basis functions for different degrees + * \{ + */ + + // ====== Lagrange0 ================================================ + // center + inline static const double& phi0c(const DimVec<double>& /*lambda*/, + int* /*vertices*/) { + static double phi = 1.0; + return phi; + }; + + // ====== Lagrange1 ================================================ + // vertex + inline static const double& phi1v(const DimVec<double>& lambda, + int* vertices) { + static double phi = 0; + phi = lambda[vertices[0]]; + return phi; + }; + + // ====== Lagrange2 ================================================ + // vertex + inline static const double& phi2v(const DimVec<double>& lambda, + int* vertices) { + static double phi = 0; + phi = lambda[vertices[0]]*(2.0*lambda[vertices[0]] - 1.0); + return phi; + }; + + // edge + inline static const double& phi2e(const DimVec<double>& lambda, + int* vertices) { + static double phi = 0; + phi = (4.0*lambda[vertices[0]]*lambda[vertices[1]]); + return phi; + }; + + // ====== Lagrange3 ================================================ + // vertex + inline static const double& phi3v(const DimVec<double>& lambda, + int* vertices) { + static double phi = 0; + phi = (4.5*(lambda[vertices[0]] - 1.0)*lambda[vertices[0]] + 1.0) * + lambda[vertices[0]]; + return phi; + }; + + // edge + inline static const double& phi3e(const DimVec<double>& lambda, + int* vertices) { + static double phi = 0; + phi = (13.5*lambda[vertices[0]] - 4.5) * + lambda[vertices[0]]*lambda[vertices[1]]; + return phi; + }; + + // face + inline static const double& phi3f(const DimVec<double>& lambda, + int* vertices) { + static double phi = 0; + phi = 27.0*lambda[vertices[0]]*lambda[vertices[1]]*lambda[vertices[2]]; + return phi; + }; + + // ====== Lagrange4 ================================================ + // vertex + inline static const double& phi4v(const DimVec<double>& lambda, + int* vertices) { + static double phi = 0; + phi = (((32.0*lambda[vertices[0]] - 48.0)*lambda[vertices[0]] + 22.0) + *lambda[vertices[0]] - 3.0)*lambda[vertices[0]]/3.0; + return phi; + }; + + // edge + inline static const double& phi4e0(const DimVec<double>& lambda, + int* vertices) { + static double phi = 0; + phi = ((128.0*lambda[vertices[0]] - 96.0) * lambda[vertices[0]] + 16.0) + * lambda[vertices[0]]*lambda[vertices[1]]/3.0; + return phi; + }; + + inline static const double& phi4e1(const DimVec<double>& lambda, + int* vertices) { + static double phi = 0; + phi = (4.0*lambda[vertices[0]] - 1.0)*lambda[vertices[0]] * + (4.0*lambda[vertices[1]] - 1.0)*lambda[vertices[1]]*4.0; + return phi; + }; + + // face + inline static const double& phi4f(const DimVec<double>& lambda, + int* vertices) { + static double phi = 0; + phi = (4.0*lambda[vertices[0]] - 1.0)*lambda[vertices[0]] * + lambda[vertices[1]]*lambda[vertices[2]]*32.0; + return phi; + }; + + // center + inline static const double& phi4c(const DimVec<double>& lambda, + int* vertices) { + static double phi = 0; + phi = 256.0*lambda[vertices[0]]*lambda[vertices[1]] * + lambda[vertices[2]]*lambda[vertices[3]]; + return phi; + }; + + }; + + /** \} */ + + // ===== GrdPhi ====================================================== + + /** \brief + * AbstractFunction which implements gradients of lagrange basis functions. + * See \ref Phi + */ + class GrdPhi : public GrdBasFctType + { + public: + MEMORY_MANAGED(GrdPhi); + + GrdPhi(Lagrange* owner_, GeoIndex position, + int positionIndex, + int nodeIndex); + virtual ~GrdPhi(); + private: + Lagrange* owner; + int* vertices; + const DimVec<double>& (*func)(const DimVec<double>& lambda, + int* vertices_, + Lagrange* owner_); + + inline const DimVec<double>& operator()(const DimVec<double>& lambda) const { + return func(lambda, vertices, owner); + }; + + // ====== Lagrange0 ================================================ + // center + inline static const DimVec<double>& grdPhi0c(const DimVec<double>& /* lambda*/, + int* /*vertices*/, + Lagrange* owner) { + static DimVec<double>* grd[4]={NULL, + NEW DimVec<double>(1, DEFAULT_VALUE, 0.), + NEW DimVec<double>(2, DEFAULT_VALUE, 0.), + NEW DimVec<double>(3, DEFAULT_VALUE, 0.)}; + return(*(grd[owner->getDim()])); + }; + + // ====== Lagrange1 ================================================ + // vertex + inline static const DimVec<double>& grdPhi1v(const DimVec<double>& /*lambda*/, + int* vertices, + Lagrange* owner) { + static DimVec<double>* grd[4]={NULL, + NEW DimVec<double>(1, DEFAULT_VALUE, 0.), + NEW DimVec<double>(2, DEFAULT_VALUE, 0.), + NEW DimVec<double>(3, DEFAULT_VALUE, 0.)}; + int dim = owner->getDim(); + grd[dim]->set(0.); + (*grd[dim])[vertices[0]] = 1.0; + return(*(grd[dim])); + }; + + // ====== Lagrange2 ================================================ + // vertex + inline static const DimVec<double>& grdPhi2v(const DimVec<double>& lambda, + int* vertices, + Lagrange* owner) { + static DimVec<double>* grd[4]={NULL, + NEW DimVec<double>(1, DEFAULT_VALUE, 0.), + NEW DimVec<double>(2, DEFAULT_VALUE, 0.), + NEW DimVec<double>(3, DEFAULT_VALUE, 0.)}; + int dim = owner->getDim(); + grd[dim]->set(0.); + (*grd[dim])[vertices[0]] = 4.0*lambda[vertices[0]] - 1.0; + return(*(grd[dim])); + }; + + // edge + inline static const DimVec<double>& grdPhi2e(const DimVec<double>& lambda, + int* vertices, + Lagrange* owner) { + static DimVec<double>* grd[4]={NULL, + NEW DimVec<double>(1, DEFAULT_VALUE, 0.), + NEW DimVec<double>(2, DEFAULT_VALUE, 0.), + NEW DimVec<double>(3, DEFAULT_VALUE, 0.)}; + int dim = owner->getDim(); + grd[dim]->set(0.); + (*grd[dim])[vertices[0]] = 4.0*lambda[vertices[1]]; + (*grd[dim])[vertices[1]] = 4.0*lambda[vertices[0]]; + return(*(grd[dim])); + }; + + // ===== Lagrange3 ================================================ + // vertex + inline static const DimVec<double>& grdPhi3v(const DimVec<double>& lambda, + int* vertices, + Lagrange* owner) { + static DimVec<double>* grd[4]={NULL, + NEW DimVec<double>(1, DEFAULT_VALUE, 0.), + NEW DimVec<double>(2, DEFAULT_VALUE, 0.), + NEW DimVec<double>(3, DEFAULT_VALUE, 0.)}; + int dim = owner->getDim(); + grd[dim]->set(0.); + (*grd[dim])[vertices[0]] = (13.5*lambda[vertices[0]] - 9.0) * + lambda[vertices[0]] + 1; + return(*(grd[dim])); + }; + + // edge + inline static const DimVec<double>& grdPhi3e(const DimVec<double>& lambda, + int* vertices, + Lagrange* owner) { + static DimVec<double>* grd[4]={NULL, + NEW DimVec<double>(1, DEFAULT_VALUE, 0.), + NEW DimVec<double>(2, DEFAULT_VALUE, 0.), + NEW DimVec<double>(3, DEFAULT_VALUE, 0.)}; + int dim = owner->getDim(); + grd[dim]->set(0.); + (*grd[dim])[vertices[0]] = (27.0*lambda[vertices[0]] - 4.5) * + lambda[vertices[1]]; + (*grd[dim])[vertices[1]] = (13.5*lambda[vertices[0]] - 4.5) * + lambda[vertices[0]]; + return(*(grd[dim])); + }; + + // face + inline static const DimVec<double>& grdPhi3f(const DimVec<double>& lambda, + int* vertices, + Lagrange* owner) { + static DimVec<double>* grd[4]={NULL, + NEW DimVec<double>(1, DEFAULT_VALUE, 0.), + NEW DimVec<double>(2, DEFAULT_VALUE, 0.), + NEW DimVec<double>(3, DEFAULT_VALUE, 0.)}; + int dim = owner->getDim(); + grd[dim]->set(0.); + (*grd[dim])[vertices[0]] = 27.0*lambda[vertices[1]]*lambda[vertices[2]]; + (*grd[dim])[vertices[1]] = 27.0*lambda[vertices[0]]*lambda[vertices[2]]; + (*grd[dim])[vertices[2]] = 27.0*lambda[vertices[0]]*lambda[vertices[1]]; + return(*(grd[dim])); + }; + + + // ===== Lagrange4 ================================================ + // vertex + inline static const DimVec<double>& grdPhi4v(const DimVec<double>& lambda, + int* vertices, + Lagrange* owner) { + static DimVec<double>* grd[4]={NULL, + NEW DimVec<double>(1, DEFAULT_VALUE, 0.), + NEW DimVec<double>(2, DEFAULT_VALUE, 0.), + NEW DimVec<double>(3, DEFAULT_VALUE, 0.)}; + int dim = owner->getDim(); + grd[dim]->set(0.); + (*grd[dim])[vertices[0]] = + ((128.0*lambda[vertices[0]] - 144.0) * lambda[vertices[0]] + 44.0) * + lambda[vertices[0]]/3.0 - 1.0; + return(*(grd[dim])); + }; + + // edge + inline static const DimVec<double>& grdPhi4e0(const DimVec<double>& lambda, + int* vertices, + Lagrange* owner) { + static DimVec<double>* grd[4]={NULL, + NEW DimVec<double>(1, DEFAULT_VALUE, 0.), + NEW DimVec<double>(2, DEFAULT_VALUE, 0.), + NEW DimVec<double>(3, DEFAULT_VALUE, 0.)}; + int dim = owner->getDim(); + grd[dim]->set(0.); + (*grd[dim])[vertices[0]] = ((128*lambda[vertices[0]] - 64.0) * + lambda[vertices[0]] + 16.0/3.0)*lambda[vertices[1]]; + (*grd[dim])[vertices[1]] = ((128*lambda[vertices[0]] - 96.0) * + lambda[vertices[0]] + 16.0)*lambda[vertices[0]]/3.0; + return(*(grd[dim])); + }; + + inline static const DimVec<double>& grdPhi4e1(const DimVec<double>& lambda, + int* vertices, + Lagrange* owner) { + static DimVec<double>* grd[4]={NULL, + NEW DimVec<double>(1, DEFAULT_VALUE, 0.), + NEW DimVec<double>(2, DEFAULT_VALUE, 0.), + NEW DimVec<double>(3, DEFAULT_VALUE, 0.)}; + int dim = owner->getDim(); + grd[dim]->set(0.); + (*grd[dim])[vertices[0]] = 4.0*(8.0*lambda[vertices[0]] - 1.0) * + lambda[vertices[1]]*(4.0*lambda[vertices[1]] - 1.0); + (*grd[dim])[vertices[1]] = 4.0*lambda[vertices[0]] * + (4.0*lambda[vertices[0]] - 1.0)*(8.0*lambda[vertices[1]] - 1.0); + return(*(grd[dim])); + }; + + // face + inline static const DimVec<double>& grdPhi4f(const DimVec<double>& lambda, + int* vertices, + Lagrange* owner) { + static DimVec<double>* grd[4]={NULL, + NEW DimVec<double>(1, DEFAULT_VALUE, 0.), + NEW DimVec<double>(2, DEFAULT_VALUE, 0.), + NEW DimVec<double>(3, DEFAULT_VALUE, 0.)}; + int dim = owner->getDim(); + grd[dim]->set(0.); + (*grd[dim])[vertices[0]] = 32.0*(8.0*lambda[vertices[0]] - 1.0) * + lambda[vertices[1]]*lambda[vertices[2]]; + (*grd[dim])[vertices[1]] = 32.0*(4.0*lambda[vertices[0]] - 1.0) * + lambda[vertices[0]]*lambda[vertices[2]]; + (*grd[dim])[vertices[2]] = 32.0*(4.0*lambda[vertices[0]] - 1.0) * + lambda[vertices[0]]*lambda[vertices[1]]; + return(*(grd[dim])); + }; + + // center + inline static const DimVec<double>& grdPhi4c(const DimVec<double>& lambda, + int* vertices, + Lagrange* owner) { + static DimVec<double>* grd[4]={NULL, + NEW DimVec<double>(1, DEFAULT_VALUE, 0.), + NEW DimVec<double>(2, DEFAULT_VALUE, 0.), + NEW DimVec<double>(3, DEFAULT_VALUE, 0.)}; + int dim = owner->getDim(); + grd[dim]->set(0.); + (*grd[dim])[0] = 256.0*lambda[vertices[1]]*lambda[vertices[2]] * + lambda[vertices[3]]; + (*grd[dim])[1] = 256.0*lambda[vertices[0]]*lambda[vertices[2]] * + lambda[vertices[3]]; + (*grd[dim])[2] = 256.0*lambda[vertices[0]]*lambda[vertices[1]] * + lambda[vertices[3]]; + (*grd[dim])[3] = 256.0*lambda[vertices[0]]*lambda[vertices[1]] * + lambda[vertices[2]]; + return(*(grd[dim])); + }; + }; + + + // ===== D2Phi ======================================================= + + /** \brief + * AbstractFunction which implements second derivatives of Lagrange basis + * functions. See \ref Phi + */ + class D2Phi : public D2BasFctType + { + public: + MEMORY_MANAGED(D2Phi); + + D2Phi(Lagrange* owner_, GeoIndex position, + int positionIndex, int nodeIndex); + + virtual ~D2Phi(); + private: + Lagrange* owner; + int* vertices; + + const DimMat<double>& (*func)(const DimVec<double>& lambda, + int* vertices_, + Lagrange* owner_); + + inline const DimMat<double>& operator()(const DimVec<double>& lambda) const { + return func(lambda, vertices, owner); + }; + + // ===== Lagrange0 ================================================ + // center + inline static const DimMat<double>& D2Phi0c(const DimVec<double>& /*lambda*/, + int* /*vertices*/, + Lagrange* owner) { + static DimMat<double>* D2[4]={NULL, + NEW DimMat<double>(1, DEFAULT_VALUE, 0.0), + NEW DimMat<double>(2, DEFAULT_VALUE, 0.0), + NEW DimMat<double>(3, DEFAULT_VALUE, 0.0)}; + int dim = owner->getDim(); + return (*D2[dim]); + }; + + // ===== Lagrange1 ================================================ + // vertex + inline static const DimMat<double>& D2Phi1v(const DimVec<double>& /*lambda*/, + int* /*vertices*/, + Lagrange* owner) { + static DimMat<double>* D2[4]={NULL, + NEW DimMat<double>(1, DEFAULT_VALUE, 0.0), + NEW DimMat<double>(2, DEFAULT_VALUE, 0.0), + NEW DimMat<double>(3, DEFAULT_VALUE, 0.0)}; + int dim = owner->getDim(); + return (*D2[dim]); + }; + + // ===== Lagrange2 ================================================ + // vertex + inline static const DimMat<double>& D2Phi2v(const DimVec<double>& /*lambda*/, + int* vertices, + Lagrange* owner) { + static DimMat<double>* D2[4]={NULL, + NEW DimMat<double>(1, DEFAULT_VALUE, 0.0), + NEW DimMat<double>(2, DEFAULT_VALUE, 0.0), + NEW DimMat<double>(3, DEFAULT_VALUE, 0.0)}; + int dim = owner->getDim(); + D2[dim]->set(0.); + (*D2[dim])[vertices[0]][vertices[0]] = 4.0; + return (*D2[dim]); + }; + + // edge + inline static const DimMat<double>& D2Phi2e(const DimVec<double>& /*lambda*/, + int* vertices, + Lagrange* owner) { + static DimMat<double>* D2[4]={NULL, + NEW DimMat<double>(1, DEFAULT_VALUE, 0.0), + NEW DimMat<double>(2, DEFAULT_VALUE, 0.0), + NEW DimMat<double>(3, DEFAULT_VALUE, 0.0)}; + int dim = owner->getDim(); + D2[dim]->set(0.); + (*D2[dim])[vertices[0]][vertices[1]] = 4.0; + (*D2[dim])[vertices[1]][vertices[0]] = 4.0; + return (*D2[dim]); + }; + + + // ===== Lagrange3 ================================================ + // vertex + inline static const DimMat<double>& D2Phi3v(const DimVec<double>& lambda, + int* vertices, + Lagrange* owner) { + static DimMat<double>* D2[4]={NULL, + NEW DimMat<double>(1, DEFAULT_VALUE, 0.0), + NEW DimMat<double>(2, DEFAULT_VALUE, 0.0), + NEW DimMat<double>(3, DEFAULT_VALUE, 0.0)}; + int dim = owner->getDim(); + D2[dim]->set(0.); + (*D2[dim])[vertices[0]][vertices[0]] = 27.0*lambda[vertices[0]] - 9.0; + return (*D2[dim]); + }; + + // edge + inline static const DimMat<double>& D2Phi3e(const DimVec<double>& lambda, + int* vertices, + Lagrange* owner) { + static DimMat<double>* D2[4]={NULL, + NEW DimMat<double>(1, DEFAULT_VALUE, 0.0), + NEW DimMat<double>(2, DEFAULT_VALUE, 0.0), + NEW DimMat<double>(3, DEFAULT_VALUE, 0.0)}; + int dim = owner->getDim(); + D2[dim]->set(0.); + (*D2[dim])[vertices[0]][vertices[0]] = 27.0*lambda[vertices[1]]; + (*D2[dim])[vertices[0]][vertices[1]] = + (*D2[dim])[vertices[1]][vertices[0]] = 27.0*lambda[vertices[0]] - 4.5; + return (*D2[dim]); + }; + + // face + inline static const DimMat<double>& D2Phi3f(const DimVec<double>& lambda, + int* vertices, + Lagrange* owner) { + static DimMat<double>* D2[4]={NULL, + NEW DimMat<double>(1, DEFAULT_VALUE, 0.0), + NEW DimMat<double>(2, DEFAULT_VALUE, 0.0), + NEW DimMat<double>(3, DEFAULT_VALUE, 0.0)}; + int dim = owner->getDim(); + D2[dim]->set(0.); + (*D2[dim])[vertices[0]][vertices[1]] = + (*D2[dim])[vertices[1]][vertices[0]] = 27.0*lambda[vertices[2]]; + (*D2[dim])[vertices[0]][vertices[2]] = + (*D2[dim])[vertices[2]][vertices[0]] = 27.0*lambda[vertices[1]]; + (*D2[dim])[vertices[1]][vertices[2]] = + (*D2[dim])[vertices[2]][vertices[1]] = 27.0*lambda[vertices[0]]; + return (*D2[dim]); + }; + + + // ===== Lagrange4 ================================================ + // vertex + inline static const DimMat<double>& D2Phi4v(const DimVec<double>& lambda, + int* vertices, + Lagrange* owner) { + static DimMat<double>* D2[4]={NULL, + NEW DimMat<double>(1, DEFAULT_VALUE, 0.0), + NEW DimMat<double>(2, DEFAULT_VALUE, 0.0), + NEW DimMat<double>(3, DEFAULT_VALUE, 0.0)}; + int dim = owner->getDim(); + D2[dim]->set(0.); + (*D2[dim])[vertices[0]][vertices[0]] = + (128.0*lambda[vertices[0]] - 96.0)*lambda[vertices[0]] + 44.0/3.0; + return (*D2[dim]); + }; + + // edge + inline static const DimMat<double>& D2Phi4e0(const DimVec<double>& lambda, + int* vertices, + Lagrange* owner) { + static DimMat<double>* D2[4]={NULL, + NEW DimMat<double>(1, DEFAULT_VALUE, 0.0), + NEW DimMat<double>(2, DEFAULT_VALUE, 0.0), + NEW DimMat<double>(3, DEFAULT_VALUE, 0.0)}; + int dim = owner->getDim(); + D2[dim]->set(0.); + (*D2[dim])[vertices[0]][vertices[0]] = + (256.0*lambda[vertices[0]] - 64.0)*lambda[vertices[1]]; + (*D2[dim])[vertices[0]][vertices[1]] = + (*D2[dim])[vertices[1]][vertices[0]] = + (128.0*lambda[vertices[0]] - 64.0)*lambda[vertices[0]] + 16.0/3.0; + return (*D2[dim]); + }; + + inline static const DimMat<double>& D2Phi4e1(const DimVec<double>& lambda, + int* vertices, + Lagrange* owner) { + static DimMat<double>* D2[4]={NULL, + NEW DimMat<double>(1, DEFAULT_VALUE, 0.0), + NEW DimMat<double>(2, DEFAULT_VALUE, 0.0), + NEW DimMat<double>(3, DEFAULT_VALUE, 0.0)}; + int dim = owner->getDim(); + D2[dim]->set(0.); + (*D2[dim])[vertices[0]][vertices[0]] = + 32.0*lambda[vertices[1]]*(4.0*lambda[vertices[1]] - 1.0); + (*D2[dim])[vertices[0]][vertices[1]] = + (*D2[dim])[vertices[1]][vertices[0]] = + 4.0*(8.0*lambda[vertices[0]] - 1.0)*(8.0*lambda[vertices[1]] - 1.0); + (*D2[dim])[vertices[1]][vertices[1]] = + 32.0*lambda[vertices[0]]*(4.0*lambda[vertices[0]] - 1.0); + return (*D2[dim]); + }; + + // face + inline static const DimMat<double>& D2Phi4f(const DimVec<double>& lambda, + int* vertices, + Lagrange* owner) { + static DimMat<double>* D2[4]={NULL, + NEW DimMat<double>(1, DEFAULT_VALUE, 0.0), + NEW DimMat<double>(2, DEFAULT_VALUE, 0.0), + NEW DimMat<double>(3, DEFAULT_VALUE, 0.0)}; + int dim = owner->getDim(); + D2[dim]->set(0.); + (*D2[dim])[vertices[0]][vertices[0]] = + 256.0*lambda[vertices[1]]*lambda[vertices[2]]; + (*D2[dim])[vertices[0]][vertices[1]] = + (*D2[dim])[vertices[1]][vertices[0]] = + 32.0*(8.0*lambda[vertices[0]] - 1.0)*lambda[vertices[2]]; + (*D2[dim])[vertices[0]][vertices[2]] = + (*D2[dim])[vertices[2]][vertices[0]] = + 32.0*(8.0*lambda[vertices[0]] - 1.0)*lambda[vertices[1]]; + (*D2[dim])[vertices[1]][vertices[2]] = + (*D2[dim])[vertices[2]][vertices[1]] = + 32.0*(4.0*lambda[vertices[0]] - 1.0)*lambda[vertices[0]]; + return (*D2[dim]); + }; + + // center + inline static const DimMat<double>& D2Phi4c(const DimVec<double>& lambda, + int* vertices, + Lagrange* owner) { + static DimMat<double>* D2[4]={NULL, + NEW DimMat<double>(1, DEFAULT_VALUE, 0.0), + NEW DimMat<double>(2, DEFAULT_VALUE, 0.0), + NEW DimMat<double>(3, DEFAULT_VALUE, 0.0)}; + int dim = owner->getDim(); + D2[dim]->set(0.); + (*D2[dim])[vertices[0]][vertices[1]] = + (*D2[dim])[vertices[1]][vertices[0]] = + 256.0*lambda[vertices[2]]*lambda[vertices[3]]; + (*D2[dim])[vertices[0]][vertices[2]] = + (*D2[dim])[vertices[2]][vertices[0]] = + 256.0*lambda[vertices[1]]*lambda[vertices[3]]; + (*D2[dim])[vertices[0]][vertices[3]] = + (*D2[dim])[vertices[3]][vertices[0]] = + 256.0*lambda[vertices[1]]*lambda[vertices[2]]; + (*D2[dim])[vertices[1]][vertices[2]] = + (*D2[dim])[vertices[2]][vertices[1]] = + 256.0*lambda[vertices[0]]*lambda[vertices[3]]; + (*D2[dim])[vertices[1]][vertices[3]] = + (*D2[dim])[vertices[3]][vertices[1]] = + 256.0*lambda[vertices[0]]*lambda[vertices[2]]; + (*D2[dim])[vertices[2]][vertices[3]] = + (*D2[dim])[vertices[3]][vertices[2]] = + 256.0*lambda[vertices[0]]*lambda[vertices[1]]; + return (*D2[dim]); + }; + }; + }; + +} + +#endif // AMDIS_LAGRANGE_H diff --git a/AMDiS/src/LagrangeInterpolRestrict.cc b/AMDiS/src/LagrangeInterpolRestrict.cc new file mode 100644 index 0000000000000000000000000000000000000000..a68321ef2319d2d8fca463d26ddef5a3bb0952a4 --- /dev/null +++ b/AMDiS/src/LagrangeInterpolRestrict.cc @@ -0,0 +1,26 @@ +#include "LagrangeInterpolRestrict.h" + +namespace AMDiS { + + InterpolRestrictMatrix *interpolMatrices[3][4] = { + {new IM_1d_1, new IM_1d_2, NULL, NULL}, + {new IM_2d_1, new IM_2d_2, new IM_2d_3, new IM_2d_4}, + {new IM_3d_1, new IM_3d_2, new IM_3d_3, new IM_3d_4} + }; + + InterpolRestrictMatrix *restrictMatrices[3][4] = { + { new InterpolRestrictMatrix(*(interpolMatrices[0][0]), true), + new InterpolRestrictMatrix(*(interpolMatrices[0][1]), true), + NULL, + NULL}, + { new InterpolRestrictMatrix(*(interpolMatrices[1][0]), true), + new InterpolRestrictMatrix(*(interpolMatrices[1][1]), true), + new InterpolRestrictMatrix(*(interpolMatrices[1][2]), true), + new InterpolRestrictMatrix(*(interpolMatrices[1][3]), true) }, + { new InterpolRestrictMatrix(*(interpolMatrices[2][0]), true), + new InterpolRestrictMatrix(*(interpolMatrices[2][1]), true), + new InterpolRestrictMatrix(*(interpolMatrices[2][2]), true), + new InterpolRestrictMatrix(*(interpolMatrices[2][3]), true) } + }; + +} diff --git a/AMDiS/src/LagrangeInterpolRestrict.h b/AMDiS/src/LagrangeInterpolRestrict.h new file mode 100644 index 0000000000000000000000000000000000000000..a4740d5f6dcdabf1f4930880c037a293e4e0d9c4 --- /dev/null +++ b/AMDiS/src/LagrangeInterpolRestrict.h @@ -0,0 +1,1273 @@ +#ifndef AMDIS_LAGRANGEINTERPOLRESTRICT_H +#define AMDIS_LAGRANGEINTERPOLRESTRICT_H + +#include "InterpolRestrictMatrix.h" + +namespace AMDiS { + + /** \brief + * Defines the interpolation and restriction matrix for 1d-elements + * and 1d-lagrange basis functions. + */ + class IM_1d_1 : public InterpolRestrictMatrix + { + public: + IM_1d_1() : InterpolRestrictMatrix(2, 3, 2, false) {}; + + protected: + void fillMemory() + { + directCopyDOFs_.resize(2); + directCopyDOFs_[0] = 0; + directCopyDOFs_[1] = 1; + + uniqueRowMatrix_[2][0] = 0.5; + uniqueRowMatrix_[2][1] = 0.5; + + rowDOFPtrs_[0] = parentDOFs_ + 0; + rowDOFPtrs_[1] = parentDOFs_ + 1; + rowDOFPtrs_[2] = child0DOFs_ + 1; + + colDOFPtrs_[0] = parentDOFs_ + 0; + colDOFPtrs_[1] = parentDOFs_ + 1; + }; + }; + + + /** \brief + * Defines the interpolation and restriction matrix for 1d-elements + * and 2d-lagrange basis functions. + */ + class IM_1d_2 : public InterpolRestrictMatrix + { + public: + IM_1d_2() : InterpolRestrictMatrix(3, 5, 3, false) {}; + + protected: + void fillMemory() + { + directCopyDOFs_.push_back(0); + directCopyDOFs_.push_back(1); + + uniqueRowMatrix_[2][2] = 1.0; + + uniqueRowMatrix_[3][0] = 0.375; + uniqueRowMatrix_[3][1] = -0.125; + uniqueRowMatrix_[3][2] = 0.75; + + uniqueRowMatrix_[4][0] = -0.125; + uniqueRowMatrix_[4][1] = 0.375; + uniqueRowMatrix_[4][2] = 0.75; + + rowDOFPtrs_[0] = parentDOFs_ + 0; + rowDOFPtrs_[1] = parentDOFs_ + 1; + rowDOFPtrs_[2] = child0DOFs_ + 1; + rowDOFPtrs_[3] = child0DOFs_ + 2; + rowDOFPtrs_[4] = child1DOFs_ + 2; + + colDOFPtrs_[0] = parentDOFs_ + 0; + colDOFPtrs_[1] = parentDOFs_ + 1; + colDOFPtrs_[2] = parentDOFs_ + 2; + }; + }; + + + /** \brief + * Defines the interpolation and restriction matrix for 1d-elements + * and 4d-lagrange basis functions. + */ + class IM_1d_4 : public InterpolRestrictMatrix + { + public: + IM_1d_4() : InterpolRestrictMatrix(5, 9, 5, false) {}; + + protected: + void fillMemory() + { + directCopyDOFs_.resize(2); + directCopyDOFs_[0] = 0; + directCopyDOFs_[1] = 1; + + uniqueRowMatrix_[2][0] = 0.5; + uniqueRowMatrix_[2][1] = 0.5; + + rowDOFPtrs_[0] = parentDOFs_ + 0; + rowDOFPtrs_[1] = parentDOFs_ + 1; + rowDOFPtrs_[2] = child0DOFs_ + 1; + + colDOFPtrs_[0] = parentDOFs_ + 0; + colDOFPtrs_[1] = parentDOFs_ + 1; + }; + }; + + + /** \brief + * Defines the interpolation and restriction matrix for 2d-elements + * and 1d-lagrange basis functions. + */ + class IM_2d_1 : public InterpolRestrictMatrix + { + public: + IM_2d_1() : InterpolRestrictMatrix(3, 4, 3, false) {}; + + void fillMemory() + { + directCopyDOFs_.resize(3); + directCopyDOFs_[0] = 0; + directCopyDOFs_[1] = 1; + directCopyDOFs_[2] = 2; + + uniqueRowMatrix_[3][0] = 0.5; + uniqueRowMatrix_[3][1] = 0.5; + + rowDOFPtrs_[0] = parentDOFs_ + 0; + rowDOFPtrs_[1] = parentDOFs_ + 1; + rowDOFPtrs_[2] = parentDOFs_ + 2; + rowDOFPtrs_[3] = child0DOFs_ + 2; + + colDOFPtrs_[0] = parentDOFs_ + 0; + colDOFPtrs_[1] = parentDOFs_ + 1; + colDOFPtrs_[2] = parentDOFs_ + 2; + }; + }; + + + /** \brief + * Defines the interpolation and restriction matrix for 2d-elements + * and 2d-lagrange basis functions. + */ + class IM_2d_2 : public InterpolRestrictMatrix + { + public: + IM_2d_2() : InterpolRestrictMatrix(6, 9, 6, false) {}; + + void fillMemory() + { + directCopyDOFs_.push_back(0); + directCopyDOFs_.push_back(1); + directCopyDOFs_.push_back(2); + directCopyDOFs_.push_back(3); + directCopyDOFs_.push_back(4); + + uniqueRowMatrix_[5][5] = 1.0; + + uniqueRowMatrix_[6][0] = 0.375; + uniqueRowMatrix_[6][1] = -0.125; + uniqueRowMatrix_[6][5] = 0.75; + + uniqueRowMatrix_[7][0] = -0.125; + uniqueRowMatrix_[7][1] = -0.125; + uniqueRowMatrix_[7][3] = 0.5; + uniqueRowMatrix_[7][4] = 0.5; + uniqueRowMatrix_[7][5] = 0.25; + + uniqueRowMatrix_[8][0] = -0.125; + uniqueRowMatrix_[8][1] = 0.375; + uniqueRowMatrix_[8][5] = 0.75; + + rowDOFPtrs_[0] = parentDOFs_ + 0; + rowDOFPtrs_[1] = parentDOFs_ + 1; + rowDOFPtrs_[2] = parentDOFs_ + 2; + rowDOFPtrs_[3] = parentDOFs_ + 3; + rowDOFPtrs_[4] = parentDOFs_ + 4; + rowDOFPtrs_[5] = child0DOFs_ + 2; + rowDOFPtrs_[6] = child0DOFs_ + 3; + rowDOFPtrs_[7] = child0DOFs_ + 4; + rowDOFPtrs_[8] = child1DOFs_ + 4; + + colDOFPtrs_[0] = parentDOFs_ + 0; + colDOFPtrs_[1] = parentDOFs_ + 1; + colDOFPtrs_[2] = parentDOFs_ + 2; + colDOFPtrs_[3] = parentDOFs_ + 3; + colDOFPtrs_[4] = parentDOFs_ + 4; + colDOFPtrs_[5] = parentDOFs_ + 5; + }; + }; + + + /** \brief + * Defines the interpolation and restriction matrix for 2d-elements + * and 3d-lagrange basis functions. + */ + class IM_2d_3 : public InterpolRestrictMatrix + { + public: + IM_2d_3() : InterpolRestrictMatrix(10, 16, 10, false) {}; + + void fillMemory() + { + directCopyDOFs_.push_back(0); + directCopyDOFs_.push_back(1); + directCopyDOFs_.push_back(2); + directCopyDOFs_.push_back(3); + directCopyDOFs_.push_back(4); + directCopyDOFs_.push_back(5); + directCopyDOFs_.push_back(6); + + uniqueRowMatrix_[7][7] = 1.0; + uniqueRowMatrix_[8][8] = 1.0; + uniqueRowMatrix_[9][9] = 1.0; + + uniqueRowMatrix_[10][0] = -0.0625; + uniqueRowMatrix_[10][1] = -0.0625; + uniqueRowMatrix_[10][7] = 0.5625; + uniqueRowMatrix_[10][8] = 0.5625; + + uniqueRowMatrix_[11][0] = 0.3125; + uniqueRowMatrix_[11][1] = 0.0625; + uniqueRowMatrix_[11][7] = 0.9375; + uniqueRowMatrix_[11][8] = -0.3125; + + uniqueRowMatrix_[12][0] = 0.0625; + uniqueRowMatrix_[12][1] = 0.0625; + uniqueRowMatrix_[12][3] = -0.25; + uniqueRowMatrix_[12][4] = 0.5; + uniqueRowMatrix_[12][5] = 0.5; + uniqueRowMatrix_[12][6] = -0.25; + uniqueRowMatrix_[12][7] = -0.0625; + uniqueRowMatrix_[12][8] = -0.0625; + uniqueRowMatrix_[12][9] = 0.5; + + uniqueRowMatrix_[13][0] = -0.0625; + uniqueRowMatrix_[13][1] = 0.0625; + uniqueRowMatrix_[13][3] = -0.125; + uniqueRowMatrix_[13][6] = 0.375; + uniqueRowMatrix_[13][7] = 0.1875; + uniqueRowMatrix_[13][8] = -0.1875; + uniqueRowMatrix_[13][9] = 0.75; + + uniqueRowMatrix_[14][0] = 0.0625; + uniqueRowMatrix_[14][1] = 0.3125; + uniqueRowMatrix_[14][7] = -0.3125; + uniqueRowMatrix_[14][8] = 0.9375; + + uniqueRowMatrix_[15][0] = 0.0625; + uniqueRowMatrix_[15][1] = -0.0625; + uniqueRowMatrix_[15][3] = 0.375; + uniqueRowMatrix_[15][6] = -0.125; + uniqueRowMatrix_[15][7] = -0.1875; + uniqueRowMatrix_[15][8] = 0.1875; + uniqueRowMatrix_[15][9] = 0.75; + + rowDOFPtrs_[ 0] = parentDOFs_ + 0; + rowDOFPtrs_[ 1] = parentDOFs_ + 1; + rowDOFPtrs_[ 2] = parentDOFs_ + 2; + rowDOFPtrs_[ 3] = parentDOFs_ + 3; + rowDOFPtrs_[ 4] = parentDOFs_ + 4; + rowDOFPtrs_[ 5] = parentDOFs_ + 5; + rowDOFPtrs_[ 6] = parentDOFs_ + 6; + rowDOFPtrs_[ 7] = child0DOFs_ + 4; + rowDOFPtrs_[ 8] = child1DOFs_ + 5; + rowDOFPtrs_[ 9] = child0DOFs_ + 5; + rowDOFPtrs_[10] = child0DOFs_ + 2; + rowDOFPtrs_[11] = child0DOFs_ + 3; + rowDOFPtrs_[12] = child0DOFs_ + 6; + rowDOFPtrs_[13] = child0DOFs_ + 9; + rowDOFPtrs_[14] = child1DOFs_ + 6; + rowDOFPtrs_[15] = child1DOFs_ + 9; + + colDOFPtrs_[0] = parentDOFs_ + 0; + colDOFPtrs_[1] = parentDOFs_ + 1; + colDOFPtrs_[2] = parentDOFs_ + 2; + colDOFPtrs_[3] = parentDOFs_ + 3; + colDOFPtrs_[4] = parentDOFs_ + 4; + colDOFPtrs_[5] = parentDOFs_ + 5; + colDOFPtrs_[6] = parentDOFs_ + 6; + colDOFPtrs_[7] = parentDOFs_ + 7; + colDOFPtrs_[8] = parentDOFs_ + 8; + colDOFPtrs_[9] = parentDOFs_ + 9; + }; + }; + + + /** \brief + * Defines the interpolation and restriction matrix for 2d-elements + * and 4d-lagrange basis functions. + */ + class IM_2d_4 : public InterpolRestrictMatrix + { + public: + IM_2d_4() : InterpolRestrictMatrix(15, 25, 15, false) {}; + + void fillMemory() + { + directCopyDOFs_.push_back(0); + directCopyDOFs_.push_back(1); + directCopyDOFs_.push_back(2); + directCopyDOFs_.push_back(3); + directCopyDOFs_.push_back(4); + directCopyDOFs_.push_back(5); + directCopyDOFs_.push_back(6); + directCopyDOFs_.push_back(7); + directCopyDOFs_.push_back(8); + + uniqueRowMatrix_[ 9][ 9] = 1.0; + uniqueRowMatrix_[10][10] = 1.0; + uniqueRowMatrix_[11][11] = 1.0; + uniqueRowMatrix_[12][12] = 1.0; + uniqueRowMatrix_[13][13] = 1.0; + uniqueRowMatrix_[14][14] = 1.0; + + uniqueRowMatrix_[15][ 0] = 0.2734375; + uniqueRowMatrix_[15][ 1] = -0.0390625; + uniqueRowMatrix_[15][ 9] = 1.09375; + uniqueRowMatrix_[15][10] = -0.546875; + uniqueRowMatrix_[15][11] = 0.21875; + + uniqueRowMatrix_[16][ 0] = -0.0390625; + uniqueRowMatrix_[16][ 1] = 0.0234375; + uniqueRowMatrix_[16][ 9] = 0.46875; + uniqueRowMatrix_[16][10] = 0.703125; + uniqueRowMatrix_[16][11] = -0.15625; + + uniqueRowMatrix_[17][ 0] = 0.0234375; + uniqueRowMatrix_[17][ 1] = 0.0234375; + uniqueRowMatrix_[17][ 3] = -0.0625; + uniqueRowMatrix_[17][ 8] = -0.0625; + uniqueRowMatrix_[17][ 9] = -0.09375; + uniqueRowMatrix_[17][10] = 0.140625; + uniqueRowMatrix_[17][11] = -0.09375; + uniqueRowMatrix_[17][12] = 0.5625; + uniqueRowMatrix_[17][13] = 0.5625; + + uniqueRowMatrix_[18][ 0] = -0.0390625; + uniqueRowMatrix_[18][ 1] = -0.0390625; + uniqueRowMatrix_[18][ 3] = 0.1875; + uniqueRowMatrix_[18][ 4] = -0.375; + uniqueRowMatrix_[18][ 5] = 0.5; + uniqueRowMatrix_[18][ 6] = 0.5; + uniqueRowMatrix_[18][ 7] = -0.375; + uniqueRowMatrix_[18][ 8] = 0.1875; + uniqueRowMatrix_[18][ 9] = 0.03125; + uniqueRowMatrix_[18][10] = 0.015625; + uniqueRowMatrix_[18][11] = 0.03125; + uniqueRowMatrix_[18][12] = -0.1875; + uniqueRowMatrix_[18][13] = -0.1875; + uniqueRowMatrix_[18][14] = 0.75; + + uniqueRowMatrix_[19][ 0] = 0.0234375; + uniqueRowMatrix_[19][ 1] = -0.0390625; + uniqueRowMatrix_[19][ 3] = 0.125; + uniqueRowMatrix_[19][ 4] = -0.125; + uniqueRowMatrix_[19][ 7] = 0.375; + uniqueRowMatrix_[19][ 8] = -0.125; + uniqueRowMatrix_[19][ 9] = -0.03125; + uniqueRowMatrix_[19][10] = -0.046875; + uniqueRowMatrix_[19][11] = 0.09375; + uniqueRowMatrix_[19][12] = 0.375; + uniqueRowMatrix_[19][13] = -0.375; + uniqueRowMatrix_[19][14] = 0.75; + + uniqueRowMatrix_[20][ 0] = -0.0390625; + uniqueRowMatrix_[20][ 1] = -0.0390625; + uniqueRowMatrix_[20][ 3] = 0.0625; + uniqueRowMatrix_[20][ 8] = 0.3125; + uniqueRowMatrix_[20][13] = -0.3125; + uniqueRowMatrix_[20][ 9] = 0.15625; + uniqueRowMatrix_[20][11] = 0.15625; + uniqueRowMatrix_[20][10] = -0.234375; + uniqueRowMatrix_[20][12] = 0.9375; + + uniqueRowMatrix_[21][ 0] = 0.0234375; + uniqueRowMatrix_[21][ 1] = -0.0390625; + uniqueRowMatrix_[21][ 9] = -0.15625; + uniqueRowMatrix_[21][10] = 0.703125; + uniqueRowMatrix_[21][11] = 0.46875; + + uniqueRowMatrix_[22][ 0] = -0.0390625; + uniqueRowMatrix_[22][ 1] = 0.2734375; + uniqueRowMatrix_[22][ 9] = 0.21875; + uniqueRowMatrix_[22][10] = -0.546875; + uniqueRowMatrix_[22][11] = 1.09375; + + uniqueRowMatrix_[23][ 0] = -0.0390625; + uniqueRowMatrix_[23][ 1] = -0.0390625; + uniqueRowMatrix_[23][ 3] = 0.3125; + uniqueRowMatrix_[23][ 8] = 0.0625; + uniqueRowMatrix_[23][ 9] = 0.15625; + uniqueRowMatrix_[23][10] = -0.234375; + uniqueRowMatrix_[23][11] = 0.15625; + uniqueRowMatrix_[23][12] = -0.3125; + uniqueRowMatrix_[23][13] = 0.9375; + + uniqueRowMatrix_[24][ 0] = -0.0390625; + uniqueRowMatrix_[24][ 1] = 0.0234375; + uniqueRowMatrix_[24][ 3] = -0.125; + uniqueRowMatrix_[24][ 7] = -0.125; + uniqueRowMatrix_[24][ 8] = 0.125; + uniqueRowMatrix_[24][ 4] = 0.375; + uniqueRowMatrix_[24][12] = -0.375; + uniqueRowMatrix_[24][13] = 0.375; + uniqueRowMatrix_[24][ 9] = 0.09375; + uniqueRowMatrix_[24][10] = -0.046875; + uniqueRowMatrix_[24][11] = -0.03125; + uniqueRowMatrix_[24][14] = 0.75; + + rowDOFPtrs_[ 0] = parentDOFs_ + 0; + rowDOFPtrs_[ 1] = parentDOFs_ + 1; + rowDOFPtrs_[ 2] = parentDOFs_ + 2; + rowDOFPtrs_[ 3] = parentDOFs_ + 3; + rowDOFPtrs_[ 4] = parentDOFs_ + 4; + rowDOFPtrs_[ 5] = parentDOFs_ + 5; + rowDOFPtrs_[ 6] = parentDOFs_ + 6; + rowDOFPtrs_[ 7] = parentDOFs_ + 7; + rowDOFPtrs_[ 8] = parentDOFs_ + 8; + rowDOFPtrs_[ 9] = child0DOFs_ + 4; + rowDOFPtrs_[10] = child0DOFs_ + 2; + rowDOFPtrs_[11] = child1DOFs_ + 7; + rowDOFPtrs_[12] = child0DOFs_ + 14; + rowDOFPtrs_[13] = child1DOFs_ + 14; + rowDOFPtrs_[14] = child0DOFs_ + 7; + rowDOFPtrs_[15] = child0DOFs_ + 3; + rowDOFPtrs_[16] = child0DOFs_ + 5; + rowDOFPtrs_[17] = child0DOFs_ + 6; + rowDOFPtrs_[18] = child0DOFs_ + 8; + rowDOFPtrs_[19] = child0DOFs_ + 12; + rowDOFPtrs_[20] = child0DOFs_ + 13; + rowDOFPtrs_[21] = child1DOFs_ + 6; + rowDOFPtrs_[22] = child1DOFs_ + 8; + rowDOFPtrs_[23] = child1DOFs_ + 12; + rowDOFPtrs_[24] = child1DOFs_ + 13; + + colDOFPtrs_[ 0] = parentDOFs_ + 0; + colDOFPtrs_[ 1] = parentDOFs_ + 1; + colDOFPtrs_[ 2] = parentDOFs_ + 2; + colDOFPtrs_[ 3] = parentDOFs_ + 3; + colDOFPtrs_[ 4] = parentDOFs_ + 4; + colDOFPtrs_[ 5] = parentDOFs_ + 5; + colDOFPtrs_[ 6] = parentDOFs_ + 6; + colDOFPtrs_[ 7] = parentDOFs_ + 7; + colDOFPtrs_[ 8] = parentDOFs_ + 8; + colDOFPtrs_[ 9] = parentDOFs_ + 9; + colDOFPtrs_[10] = parentDOFs_ + 10; + colDOFPtrs_[11] = parentDOFs_ + 11; + colDOFPtrs_[12] = parentDOFs_ + 12; + colDOFPtrs_[13] = parentDOFs_ + 13; + colDOFPtrs_[14] = parentDOFs_ + 14; + }; + }; + + + + /** \brief + * Defines the interpolation and restriction matrix for 3d-elements + * and 1d-lagrange basis functions. + */ + class IM_3d_1 : public InterpolRestrictMatrix + { + public: + IM_3d_1() : InterpolRestrictMatrix(4, 5, 4, false) {}; + + void fillMemory() + { + directCopyDOFs_.resize(4); + directCopyDOFs_[0] = 0; + directCopyDOFs_[1] = 1; + directCopyDOFs_[2] = 2; + directCopyDOFs_[3] = 3; + + uniqueRowMatrix_[4][0] = 0.5; + uniqueRowMatrix_[4][1] = 0.5; + + rowDOFPtrs_[0] = parentDOFs_ + 0; + rowDOFPtrs_[1] = parentDOFs_ + 1; + rowDOFPtrs_[2] = parentDOFs_ + 2; + rowDOFPtrs_[3] = parentDOFs_ + 3; + rowDOFPtrs_[4] = child0DOFs_ + 3; + + colDOFPtrs_[0] = parentDOFs_ + 0; + colDOFPtrs_[1] = parentDOFs_ + 1; + colDOFPtrs_[2] = parentDOFs_ + 2; + colDOFPtrs_[3] = parentDOFs_ + 3; + }; + }; + + + + /** \brief + * Defines the interpolation and restriction matrix for 3d-elements + * and 2d-lagrange basis functions. + */ + class IM_3d_2 : public InterpolRestrictMatrix + { + public: + IM_3d_2() : InterpolRestrictMatrix(10, 14, 10, false) {}; + + void fillMemory() + { + directCopyDOFs_.push_back(0); + directCopyDOFs_.push_back(1); + directCopyDOFs_.push_back(2); + directCopyDOFs_.push_back(3); + directCopyDOFs_.push_back(5); + directCopyDOFs_.push_back(6); + directCopyDOFs_.push_back(7); + directCopyDOFs_.push_back(8); + directCopyDOFs_.push_back(9); + + uniqueRowMatrix_[4][4] = 1.0; + + uniqueRowMatrix_[10][0] = 0.375; + uniqueRowMatrix_[10][1] = -0.125; + uniqueRowMatrix_[10][4] = 0.75; + + uniqueRowMatrix_[11][0] = -0.125; + uniqueRowMatrix_[11][1] = -0.125; + uniqueRowMatrix_[11][4] = 0.25; + uniqueRowMatrix_[11][5] = 0.5; + uniqueRowMatrix_[11][7] = 0.5; + + uniqueRowMatrix_[12][0] = -0.125; + uniqueRowMatrix_[12][1] = -0.125; + uniqueRowMatrix_[12][4] = 0.25; + uniqueRowMatrix_[12][6] = 0.5; + uniqueRowMatrix_[12][8] = 0.5; + + uniqueRowMatrix_[13][0] = -0.125; + uniqueRowMatrix_[13][1] = 0.375; + uniqueRowMatrix_[13][4] = 0.75; + + + rowDOFPtrs_[0] = parentDOFs_ + 0; + rowDOFPtrs_[1] = parentDOFs_ + 1; + rowDOFPtrs_[2] = parentDOFs_ + 2; + rowDOFPtrs_[3] = parentDOFs_ + 3; + rowDOFPtrs_[4] = child0DOFs_ + 3; + rowDOFPtrs_[5] = parentDOFs_ + 5; + rowDOFPtrs_[6] = parentDOFs_ + 6; + rowDOFPtrs_[7] = parentDOFs_ + 7; + rowDOFPtrs_[8] = parentDOFs_ + 8; + rowDOFPtrs_[9] = parentDOFs_ + 9; + rowDOFPtrs_[10] = child0DOFs_ + 6; + rowDOFPtrs_[11] = child0DOFs_ + 8; + rowDOFPtrs_[12] = child0DOFs_ + 9; + rowDOFPtrs_[13] = child1DOFs_ + 6; + + colDOFPtrs_[0] = parentDOFs_ + 0; + colDOFPtrs_[1] = parentDOFs_ + 1; + colDOFPtrs_[2] = parentDOFs_ + 2; + colDOFPtrs_[3] = parentDOFs_ + 3; + colDOFPtrs_[4] = parentDOFs_ + 4; + colDOFPtrs_[5] = parentDOFs_ + 5; + colDOFPtrs_[6] = parentDOFs_ + 6; + colDOFPtrs_[7] = parentDOFs_ + 7; + colDOFPtrs_[8] = parentDOFs_ + 8; + colDOFPtrs_[9] = parentDOFs_ + 9; + }; + }; + + + + /** \brief + * Defines the interpolation and restriction matrix for 3d-elements + * and 3d-lagrange basis functions. + */ + class IM_3d_3 : public InterpolRestrictMatrix + { + public: + IM_3d_3() : InterpolRestrictMatrix(20, 30, 20, true) {}; + + void fillMemory() + { + directCopyDOFs_.push_back(0); + directCopyDOFs_.push_back(1); + directCopyDOFs_.push_back(2); + directCopyDOFs_.push_back(3); + directCopyDOFs_.push_back(6); + directCopyDOFs_.push_back(7); + directCopyDOFs_.push_back(8); + directCopyDOFs_.push_back(9); + directCopyDOFs_.push_back(10); + directCopyDOFs_.push_back(11); + directCopyDOFs_.push_back(12); + directCopyDOFs_.push_back(13); + directCopyDOFs_.push_back(14); + directCopyDOFs_.push_back(15); + directCopyDOFs_.push_back(16); + directCopyDOFs_.push_back(17); + + uniqueRowMatrix_[ 4][ 4] = 1.0; + uniqueRowMatrix_[ 5][ 5] = 1.0; + uniqueRowMatrix_[18][18] = 1.0; + uniqueRowMatrix_[19][19] = 1.0; + + uniqueRowMatrix_[20][ 0] = -0.0625; + uniqueRowMatrix_[20][ 1] = -0.0625; + uniqueRowMatrix_[20][ 4] = 0.5625; + uniqueRowMatrix_[20][ 5] = 0.5625; + + uniqueRowMatrix_[21][ 0] = 0.3125; + uniqueRowMatrix_[21][ 1] = 0.0625; + uniqueRowMatrix_[21][ 4] = 0.9375; + uniqueRowMatrix_[21][ 5] = -0.3125; + + uniqueRowMatrix_[22][ 0] = 0.0625; + uniqueRowMatrix_[22][ 1] = 0.0625; + uniqueRowMatrix_[22][ 4] = -0.0625; + uniqueRowMatrix_[22][ 5] = -0.0625; + uniqueRowMatrix_[22][ 6] = -0.25; + uniqueRowMatrix_[22][ 7] = 0.5; + uniqueRowMatrix_[22][10] = -0.25; + uniqueRowMatrix_[22][11] = 0.5; + uniqueRowMatrix_[22][19] = 0.5; + + uniqueRowMatrix_[23][ 0] = 0.0625; + uniqueRowMatrix_[23][ 1] = 0.0625; + uniqueRowMatrix_[23][ 4] = -0.0625; + uniqueRowMatrix_[23][ 5] = -0.0625; + uniqueRowMatrix_[23][ 8] = -0.25; + uniqueRowMatrix_[23][ 9] = 0.5; + uniqueRowMatrix_[23][12] = -0.25; + uniqueRowMatrix_[23][13] = 0.5; + uniqueRowMatrix_[23][18] = 0.5; + + uniqueRowMatrix_[24][ 0] = 0.0625; + uniqueRowMatrix_[24][ 1] = 0.0625; + uniqueRowMatrix_[24][ 4] = -0.0625; + uniqueRowMatrix_[24][ 5] = -0.0625; + uniqueRowMatrix_[24][ 6] = -0.125; + uniqueRowMatrix_[24][ 8] = -0.125; + uniqueRowMatrix_[24][10] = -0.125; + uniqueRowMatrix_[24][12] = -0.125; + uniqueRowMatrix_[24][16] = 0.5; + uniqueRowMatrix_[24][17] = 0.5; + uniqueRowMatrix_[24][18] = 0.25; + uniqueRowMatrix_[24][19] = 0.25; + + uniqueRowMatrix_[25][ 0] = -0.0625; + uniqueRowMatrix_[25][ 1] = 0.0625; + uniqueRowMatrix_[25][ 4] = 0.1875; + uniqueRowMatrix_[25][ 5] = -0.1875; + uniqueRowMatrix_[25][ 8] = 0.375; + uniqueRowMatrix_[25][12] = -0.125; + uniqueRowMatrix_[25][18] = 0.75; + + uniqueRowMatrix_[26][ 0] = -0.0625; + uniqueRowMatrix_[26][ 1] = 0.0625; + uniqueRowMatrix_[26][ 4] = 0.1875; + uniqueRowMatrix_[26][ 5] = -0.1875; + uniqueRowMatrix_[26][ 6] = 0.375; + uniqueRowMatrix_[26][10] = -0.125; + uniqueRowMatrix_[26][19] = 0.75; + + uniqueRowMatrix_[27][ 0] = 0.0625; + uniqueRowMatrix_[27][ 1] = 0.3125; + uniqueRowMatrix_[27][ 4] = -0.3125; + uniqueRowMatrix_[27][ 5] = 0.9375; + + uniqueRowMatrix_[28][ 0] = 0.0625; + uniqueRowMatrix_[28][ 1] = -0.0625; + uniqueRowMatrix_[28][ 4] = -0.1875; + uniqueRowMatrix_[28][ 5] = 0.1875; + uniqueRowMatrix_[28][ 8] = -0.125; + uniqueRowMatrix_[28][12] = 0.375; + uniqueRowMatrix_[28][18] = 0.75; + + uniqueRowMatrix_[29][ 0] = 0.0625; + uniqueRowMatrix_[29][ 1] = -0.0625; + uniqueRowMatrix_[29][ 4] = -0.1875; + uniqueRowMatrix_[29][ 5] = 0.1875; + uniqueRowMatrix_[29][ 6] = -0.125; + uniqueRowMatrix_[29][10] = 0.375; + uniqueRowMatrix_[29][19] = 0.75; + + rowDOFPtrs_[0] = parentDOFs_ + 0; + rowDOFPtrs_[1] = parentDOFs_ + 1; + rowDOFPtrs_[2] = parentDOFs_ + 2; + rowDOFPtrs_[3] = parentDOFs_ + 3; + rowDOFPtrs_[4] = child0DOFs_ + 9; + rowDOFPtrs_[5] = child1DOFs_ + 9; + rowDOFPtrs_[6] = parentDOFs_ + 6; + rowDOFPtrs_[7] = parentDOFs_ + 7; + rowDOFPtrs_[8] = parentDOFs_ + 8; + rowDOFPtrs_[9] = parentDOFs_ + 9; + rowDOFPtrs_[10] = parentDOFs_ + 10; + rowDOFPtrs_[11] = parentDOFs_ + 11; + rowDOFPtrs_[12] = parentDOFs_ + 12; + rowDOFPtrs_[13] = parentDOFs_ + 13; + rowDOFPtrs_[14] = parentDOFs_ + 14; + rowDOFPtrs_[15] = parentDOFs_ + 15; + rowDOFPtrs_[16] = parentDOFs_ + 16; + rowDOFPtrs_[17] = parentDOFs_ + 17; + rowDOFPtrs_[18] = child0DOFs_ + 15; + rowDOFPtrs_[19] = child0DOFs_ + 13; + rowDOFPtrs_[20] = child0DOFs_ + 3; + rowDOFPtrs_[21] = child0DOFs_ + 8; + rowDOFPtrs_[22] = child0DOFs_ + 12; + rowDOFPtrs_[23] = child0DOFs_ + 14; + rowDOFPtrs_[24] = child0DOFs_ + 16; + rowDOFPtrs_[25] = child0DOFs_ + 17; + rowDOFPtrs_[26] = child0DOFs_ + 18; + rowDOFPtrs_[27] = child1DOFs_ + 8; + rowDOFPtrs_[28] = child1DOFs_ + 17; + rowDOFPtrs_[29] = child1DOFs_ + 18; + + colDOFPtrs_[ 0] = parentDOFs_ + 0; + colDOFPtrs_[ 1] = parentDOFs_ + 1; + colDOFPtrs_[ 2] = parentDOFs_ + 2; + colDOFPtrs_[ 3] = parentDOFs_ + 3; + colDOFPtrs_[ 4] = parentDOFs_ + 4; + colDOFPtrs_[ 5] = parentDOFs_ + 5; + colDOFPtrs_[ 6] = parentDOFs_ + 6; + colDOFPtrs_[ 7] = parentDOFs_ + 7; + colDOFPtrs_[ 8] = parentDOFs_ + 8; + colDOFPtrs_[ 9] = parentDOFs_ + 9; + colDOFPtrs_[10] = parentDOFs_ + 10; + colDOFPtrs_[11] = parentDOFs_ + 11; + colDOFPtrs_[12] = parentDOFs_ + 12; + colDOFPtrs_[13] = parentDOFs_ + 13; + colDOFPtrs_[14] = parentDOFs_ + 14; + colDOFPtrs_[15] = parentDOFs_ + 15; + colDOFPtrs_[16] = parentDOFs_ + 16; + colDOFPtrs_[17] = parentDOFs_ + 17; + colDOFPtrs_[18] = parentDOFs_ + 18; + colDOFPtrs_[19] = parentDOFs_ + 19; + + type0_rowDOFPtrs_[0] = parentDOFs_ + 0; + type0_rowDOFPtrs_[1] = parentDOFs_ + 1; + type0_rowDOFPtrs_[2] = parentDOFs_ + 2; + type0_rowDOFPtrs_[3] = parentDOFs_ + 3; + type0_rowDOFPtrs_[4] = child0DOFs_ + 9; + type0_rowDOFPtrs_[5] = child1DOFs_ + 9; + type0_rowDOFPtrs_[6] = parentDOFs_ + 6; + type0_rowDOFPtrs_[7] = parentDOFs_ + 7; + type0_rowDOFPtrs_[8] = parentDOFs_ + 8; + type0_rowDOFPtrs_[9] = parentDOFs_ + 9; + type0_rowDOFPtrs_[10] = parentDOFs_ + 10; + type0_rowDOFPtrs_[11] = parentDOFs_ + 11; + type0_rowDOFPtrs_[12] = parentDOFs_ + 12; + type0_rowDOFPtrs_[13] = parentDOFs_ + 13; + type0_rowDOFPtrs_[14] = parentDOFs_ + 14; + type0_rowDOFPtrs_[15] = parentDOFs_ + 15; + type0_rowDOFPtrs_[16] = parentDOFs_ + 16; + type0_rowDOFPtrs_[17] = parentDOFs_ + 17; + type0_rowDOFPtrs_[18] = child0DOFs_ + 15; + type0_rowDOFPtrs_[19] = child0DOFs_ + 13; + type0_rowDOFPtrs_[20] = child0DOFs_ + 3; + type0_rowDOFPtrs_[21] = child0DOFs_ + 8; + type0_rowDOFPtrs_[22] = child0DOFs_ + 12; + type0_rowDOFPtrs_[23] = child0DOFs_ + 14; + type0_rowDOFPtrs_[24] = child0DOFs_ + 16; + type0_rowDOFPtrs_[25] = child0DOFs_ + 17; + type0_rowDOFPtrs_[26] = child0DOFs_ + 18; + type0_rowDOFPtrs_[27] = child1DOFs_ + 8; + type0_rowDOFPtrs_[28] = child1DOFs_ + 18; + type0_rowDOFPtrs_[29] = child1DOFs_ + 17; + + type0_colDOFPtrs_[ 0] = parentDOFs_ + 0; + type0_colDOFPtrs_[ 1] = parentDOFs_ + 1; + type0_colDOFPtrs_[ 2] = parentDOFs_ + 2; + type0_colDOFPtrs_[ 3] = parentDOFs_ + 3; + type0_colDOFPtrs_[ 4] = parentDOFs_ + 4; + type0_colDOFPtrs_[ 5] = parentDOFs_ + 5; + type0_colDOFPtrs_[ 6] = parentDOFs_ + 6; + type0_colDOFPtrs_[ 7] = parentDOFs_ + 7; + type0_colDOFPtrs_[ 8] = parentDOFs_ + 8; + type0_colDOFPtrs_[ 9] = parentDOFs_ + 9; + type0_colDOFPtrs_[10] = parentDOFs_ + 10; + type0_colDOFPtrs_[11] = parentDOFs_ + 11; + type0_colDOFPtrs_[12] = parentDOFs_ + 12; + type0_colDOFPtrs_[13] = parentDOFs_ + 13; + type0_colDOFPtrs_[14] = parentDOFs_ + 14; + type0_colDOFPtrs_[15] = parentDOFs_ + 15; + type0_colDOFPtrs_[16] = parentDOFs_ + 16; + type0_colDOFPtrs_[17] = parentDOFs_ + 17; + type0_colDOFPtrs_[18] = parentDOFs_ + 18; + type0_colDOFPtrs_[19] = parentDOFs_ + 19; + }; + }; + + + /** \brief + * Defines the interpolation and restriction matrix for 3d-elements + * and 4d-lagrange basis functions. + */ + class IM_3d_4 : public InterpolRestrictMatrix + { + public: + IM_3d_4() : InterpolRestrictMatrix(35, 55, 35, true) {}; + + void fillMemory() + { + directCopyDOFs_.push_back(0); + directCopyDOFs_.push_back(1); + directCopyDOFs_.push_back(2); + directCopyDOFs_.push_back(3); + directCopyDOFs_.push_back(7); + directCopyDOFs_.push_back(8); + directCopyDOFs_.push_back(9); + directCopyDOFs_.push_back(10); + directCopyDOFs_.push_back(11); + directCopyDOFs_.push_back(12); + directCopyDOFs_.push_back(13); + directCopyDOFs_.push_back(14); + directCopyDOFs_.push_back(15); + directCopyDOFs_.push_back(16); + directCopyDOFs_.push_back(17); + directCopyDOFs_.push_back(18); + directCopyDOFs_.push_back(19); + directCopyDOFs_.push_back(20); + directCopyDOFs_.push_back(21); + directCopyDOFs_.push_back(22); + directCopyDOFs_.push_back(23); + directCopyDOFs_.push_back(24); + directCopyDOFs_.push_back(25); + directCopyDOFs_.push_back(26); + directCopyDOFs_.push_back(27); + + uniqueRowMatrix_[ 4][ 4] = 1.0; + uniqueRowMatrix_[ 5][ 5] = 1.0; + uniqueRowMatrix_[ 6][ 6] = 1.0; + uniqueRowMatrix_[28][28] = 1.0; + uniqueRowMatrix_[29][29] = 1.0; + uniqueRowMatrix_[30][30] = 1.0; + uniqueRowMatrix_[31][31] = 1.0; + uniqueRowMatrix_[32][32] = 1.0; + uniqueRowMatrix_[33][33] = 1.0; + uniqueRowMatrix_[34][34] = 1.0; + + uniqueRowMatrix_[35][ 0] = 0.2734375; + uniqueRowMatrix_[35][ 1] = -0.0390625; + uniqueRowMatrix_[35][ 4] = 1.09375; + uniqueRowMatrix_[35][ 5] = -0.546875; + uniqueRowMatrix_[35][ 6] = 0.21875; + + uniqueRowMatrix_[36][ 0] = -0.0390625; + uniqueRowMatrix_[36][ 1] = 0.0234375; + uniqueRowMatrix_[36][ 4] = 0.46875; + uniqueRowMatrix_[36][ 5] = 0.703125; + uniqueRowMatrix_[36][ 6] = -0.15625; + + uniqueRowMatrix_[37][ 0] = -0.0390625; + uniqueRowMatrix_[37][ 1] = -0.0390625; + uniqueRowMatrix_[37][ 4] = 0.03125; + uniqueRowMatrix_[37][ 5] = 0.015625; + uniqueRowMatrix_[37][ 6] = 0.03125; + uniqueRowMatrix_[37][ 7] = 0.1875; + uniqueRowMatrix_[37][ 8] = -0.375; + uniqueRowMatrix_[37][ 9] = 0.5; + uniqueRowMatrix_[37][13] = 0.1875; + uniqueRowMatrix_[37][14] = -0.375; + uniqueRowMatrix_[37][15] = 0.5; + uniqueRowMatrix_[37][31] = -0.1875; + uniqueRowMatrix_[37][32] = -0.1875; + uniqueRowMatrix_[37][33] = 0.75; + + uniqueRowMatrix_[38][ 0] = 0.0234375; + uniqueRowMatrix_[38][ 1] = 0.0234375; + uniqueRowMatrix_[38][ 4] = -0.09375; + uniqueRowMatrix_[38][ 5] = 0.140625; + uniqueRowMatrix_[38][ 6] = -0.09375; + uniqueRowMatrix_[38][ 7] = -0.0625; + uniqueRowMatrix_[38][13] = -0.0625; + uniqueRowMatrix_[38][31] = 0.5625; + uniqueRowMatrix_[38][32] = 0.5625; + + uniqueRowMatrix_[39][ 0] = -0.0390625; + uniqueRowMatrix_[39][ 1] = -0.0390625; + uniqueRowMatrix_[39][ 4] = 0.03125; + uniqueRowMatrix_[39][ 5] = 0.015625; + uniqueRowMatrix_[39][ 6] = 0.03125; + uniqueRowMatrix_[39][10] = 0.1875; + uniqueRowMatrix_[39][11] = -0.375; + uniqueRowMatrix_[39][12] = 0.5; + uniqueRowMatrix_[39][16] = 0.1875; + uniqueRowMatrix_[39][17] = -0.375; + uniqueRowMatrix_[39][18] = 0.5; + uniqueRowMatrix_[39][28] = -0.1875; + uniqueRowMatrix_[39][29] = -0.1875; + uniqueRowMatrix_[39][30] = 0.75; + + uniqueRowMatrix_[40][ 0] = 0.0234375; + uniqueRowMatrix_[40][ 1] = 0.0234375; + uniqueRowMatrix_[40][ 4] = -0.09375; + uniqueRowMatrix_[40][ 5] = 0.140625; + uniqueRowMatrix_[40][ 6] = -0.09375; + uniqueRowMatrix_[40][10] = -0.0625; + uniqueRowMatrix_[40][16] = -0.0625; + uniqueRowMatrix_[40][28] = 0.5625; + uniqueRowMatrix_[40][29] = 0.5625; + + uniqueRowMatrix_[41][ 0] = -0.0390625; + uniqueRowMatrix_[41][ 1] = -0.0390625; + uniqueRowMatrix_[41][ 4] = 0.03125; + uniqueRowMatrix_[41][ 5] = 0.015625; + uniqueRowMatrix_[41][ 6] = 0.03125; + uniqueRowMatrix_[41][ 7] = 0.125; + uniqueRowMatrix_[41][ 8] = -0.125; + uniqueRowMatrix_[41][10] = 0.0625; + uniqueRowMatrix_[41][13] = 0.125; + uniqueRowMatrix_[41][14] = -0.125; + uniqueRowMatrix_[41][16] = 0.0625; + uniqueRowMatrix_[41][22] = -0.25; + uniqueRowMatrix_[41][23] = 0.5; + uniqueRowMatrix_[41][25] = -0.25; + uniqueRowMatrix_[41][26] = 0.5; + uniqueRowMatrix_[41][28] = -0.0625; + uniqueRowMatrix_[41][29] = -0.0625; + uniqueRowMatrix_[41][31] = -0.125; + uniqueRowMatrix_[41][32] = -0.125; + uniqueRowMatrix_[41][33] = 0.25; + uniqueRowMatrix_[41][34] = 0.5; + + uniqueRowMatrix_[42][ 0] = -0.0390625; + uniqueRowMatrix_[42][ 1] = -0.0390625; + uniqueRowMatrix_[42][ 4] = 0.03125; + uniqueRowMatrix_[42][ 5] = 0.015625; + uniqueRowMatrix_[42][ 6] = 0.03125; + uniqueRowMatrix_[42][ 7] = 0.0625; + uniqueRowMatrix_[42][10] = 0.125; + uniqueRowMatrix_[42][11] = -0.125; + uniqueRowMatrix_[42][13] = 0.0625; + uniqueRowMatrix_[42][16] = 0.125; + uniqueRowMatrix_[42][17] = -0.125; + uniqueRowMatrix_[42][22] = -0.25; + uniqueRowMatrix_[42][24] = 0.5; + uniqueRowMatrix_[42][25] = -0.25; + uniqueRowMatrix_[42][27] = 0.5; + uniqueRowMatrix_[42][28] = -0.125; + uniqueRowMatrix_[42][29] = -0.125; + uniqueRowMatrix_[42][30] = 0.25; + uniqueRowMatrix_[42][31] = -0.0625; + uniqueRowMatrix_[42][32] = -0.0625; + uniqueRowMatrix_[42][34] = 0.5; + + uniqueRowMatrix_[43][ 0] = -0.0390625; + uniqueRowMatrix_[43][ 1] = -0.0390625; + uniqueRowMatrix_[43][ 4] = 0.15625; + uniqueRowMatrix_[43][ 5] = -0.234375; + uniqueRowMatrix_[43][ 6] = 0.15625; + uniqueRowMatrix_[43][10] = 0.3125; + uniqueRowMatrix_[43][16] = 0.0625; + uniqueRowMatrix_[43][28] = 0.9375; + uniqueRowMatrix_[43][29] = -0.3125; + + uniqueRowMatrix_[44][ 0] = 0.0234375; + uniqueRowMatrix_[44][ 1] = -0.0390625; + uniqueRowMatrix_[44][ 4] = -0.03125; + uniqueRowMatrix_[44][ 5] = -0.046875; + uniqueRowMatrix_[44][ 6] = 0.09375; + uniqueRowMatrix_[44][10] = -0.125; + uniqueRowMatrix_[44][11] = 0.375; + uniqueRowMatrix_[44][16] = 0.125; + uniqueRowMatrix_[44][17] = -0.125; + uniqueRowMatrix_[44][28] = 0.375; + uniqueRowMatrix_[44][29] = -0.375; + uniqueRowMatrix_[44][30] = 0.75; + + uniqueRowMatrix_[45][ 0] = -0.0390625; + uniqueRowMatrix_[45][ 1] = -0.0390625; + uniqueRowMatrix_[45][ 4] = 0.15625; + uniqueRowMatrix_[45][ 5] = -0.234375; + uniqueRowMatrix_[45][ 6] = 0.15625; + uniqueRowMatrix_[45][ 7] = 0.3125; + uniqueRowMatrix_[45][13] = 0.0625; + uniqueRowMatrix_[45][31] = 0.9375; + uniqueRowMatrix_[45][32] = -0.3125; + + uniqueRowMatrix_[46][ 0] = 0.0234375; + uniqueRowMatrix_[46][ 1] = -0.0390625; + uniqueRowMatrix_[46][ 4] = -0.03125; + uniqueRowMatrix_[46][ 5] = -0.046875; + uniqueRowMatrix_[46][ 6] = 0.09375; + uniqueRowMatrix_[46][ 7] = -0.125; + uniqueRowMatrix_[46][ 8] = 0.375; + uniqueRowMatrix_[46][13] = 0.125; + uniqueRowMatrix_[46][14] = -0.125; + uniqueRowMatrix_[46][31] = 0.375; + uniqueRowMatrix_[46][32] = -0.375; + uniqueRowMatrix_[46][33] = 0.75; + + uniqueRowMatrix_[47][ 0] = 0.0234375; + uniqueRowMatrix_[47][ 1] = -0.0390625; + uniqueRowMatrix_[47][ 4] = -0.03125; + uniqueRowMatrix_[47][ 5] = -0.046875; + uniqueRowMatrix_[47][ 6] = 0.09375; + uniqueRowMatrix_[47][ 7] = -0.0625; + uniqueRowMatrix_[47][10] = -0.0625; + uniqueRowMatrix_[47][13] = 0.0625; + uniqueRowMatrix_[47][16] = 0.0625; + uniqueRowMatrix_[47][22] = -0.125; + uniqueRowMatrix_[47][25] = 0.375; + uniqueRowMatrix_[47][28] = 0.1875; + uniqueRowMatrix_[47][29] = -0.1875; + uniqueRowMatrix_[47][31] = 0.1875; + uniqueRowMatrix_[47][32] = -0.1875; + uniqueRowMatrix_[47][34] = 0.75; + + uniqueRowMatrix_[48][ 0] = -0.0390625; + uniqueRowMatrix_[48][ 1] = 0.2734375; + uniqueRowMatrix_[48][ 4] = 0.21875; + uniqueRowMatrix_[48][ 5] = -0.546875; + uniqueRowMatrix_[48][ 6] = 1.09375; + + uniqueRowMatrix_[49][ 0] = 0.0234375; + uniqueRowMatrix_[49][ 1] = -0.0390625; + uniqueRowMatrix_[49][ 4] = -0.15625; + uniqueRowMatrix_[49][ 5] = 0.703125; + uniqueRowMatrix_[49][ 6] = 0.46875; + + uniqueRowMatrix_[50][ 0] = -0.0390625; + uniqueRowMatrix_[50][ 1] = -0.0390625; + uniqueRowMatrix_[50][ 4] = 0.15625; + uniqueRowMatrix_[50][ 5] = -0.234375; + uniqueRowMatrix_[50][ 6] = 0.15625; + uniqueRowMatrix_[50][10] = 0.0625; + uniqueRowMatrix_[50][16] = 0.3125; + uniqueRowMatrix_[50][28] = -0.3125; + uniqueRowMatrix_[50][29] = 0.9375; + + uniqueRowMatrix_[51][ 0] = -0.0390625; + uniqueRowMatrix_[51][ 1] = 0.0234375; + uniqueRowMatrix_[51][ 4] = 0.09375; + uniqueRowMatrix_[51][ 5] = -0.046875; + uniqueRowMatrix_[51][ 6] = -0.03125; + uniqueRowMatrix_[51][10] = 0.125; + uniqueRowMatrix_[51][11] = -0.125; + uniqueRowMatrix_[51][16] = -0.125; + uniqueRowMatrix_[51][17] = 0.375; + uniqueRowMatrix_[51][28] = -0.375; + uniqueRowMatrix_[51][29] = 0.375; + uniqueRowMatrix_[51][30] = 0.75; + + uniqueRowMatrix_[52][ 0] = -0.0390625; + uniqueRowMatrix_[52][ 1] = -0.0390625; + uniqueRowMatrix_[52][ 4] = 0.15625; + uniqueRowMatrix_[52][ 5] = -0.234375; + uniqueRowMatrix_[52][ 6] = 0.15625; + uniqueRowMatrix_[52][ 7] = 0.0625; + uniqueRowMatrix_[52][13] = 0.3125; + uniqueRowMatrix_[52][31] = -0.3125; + uniqueRowMatrix_[52][32] = 0.9375; + + uniqueRowMatrix_[53][ 0] = -0.0390625; + uniqueRowMatrix_[53][ 1] = 0.0234375; + uniqueRowMatrix_[53][ 4] = 0.09375; + uniqueRowMatrix_[53][ 5] = -0.046875; + uniqueRowMatrix_[53][ 6] = -0.03125; + uniqueRowMatrix_[53][ 7] = 0.125; + uniqueRowMatrix_[53][ 8] = -0.125; + uniqueRowMatrix_[53][13] = -0.125; + uniqueRowMatrix_[53][14] = 0.375; + uniqueRowMatrix_[53][31] = -0.375; + uniqueRowMatrix_[53][32] = 0.375; + uniqueRowMatrix_[53][33] = 0.75; + + uniqueRowMatrix_[54][ 0] = -0.0390625; + uniqueRowMatrix_[54][ 1] = 0.0234375; + uniqueRowMatrix_[54][ 4] = 0.09375; + uniqueRowMatrix_[54][ 5] = -0.046875; + uniqueRowMatrix_[54][ 6] = -0.03125; + uniqueRowMatrix_[54][ 7] = 0.0625; + uniqueRowMatrix_[54][10] = 0.0625; + uniqueRowMatrix_[54][13] = -0.0625; + uniqueRowMatrix_[54][16] = -0.0625; + uniqueRowMatrix_[54][22] = 0.375; + uniqueRowMatrix_[54][25] = -0.125; + uniqueRowMatrix_[54][28] = -0.1875; + uniqueRowMatrix_[54][29] = 0.1875; + uniqueRowMatrix_[54][31] = -0.1875; + uniqueRowMatrix_[54][32] = 0.1875; + uniqueRowMatrix_[54][34] = 0.75; + + + rowDOFPtrs_[ 0] = parentDOFs_ + 0; + rowDOFPtrs_[ 1] = parentDOFs_ + 1; + rowDOFPtrs_[ 2] = parentDOFs_ + 2; + rowDOFPtrs_[ 3] = parentDOFs_ + 3; + rowDOFPtrs_[ 4] = child0DOFs_ + 11; + rowDOFPtrs_[ 5] = child0DOFs_ + 3; + rowDOFPtrs_[ 6] = child1DOFs_ + 11; + rowDOFPtrs_[ 7] = parentDOFs_ + 7; + rowDOFPtrs_[ 8] = parentDOFs_ + 8; + rowDOFPtrs_[ 9] = parentDOFs_ + 9; + rowDOFPtrs_[10] = parentDOFs_ + 10; + rowDOFPtrs_[11] = parentDOFs_ + 11; + rowDOFPtrs_[12] = parentDOFs_ + 12; + rowDOFPtrs_[13] = parentDOFs_ + 13; + rowDOFPtrs_[14] = parentDOFs_ + 14; + rowDOFPtrs_[15] = parentDOFs_ + 15; + rowDOFPtrs_[16] = parentDOFs_ + 16; + rowDOFPtrs_[17] = parentDOFs_ + 17; + rowDOFPtrs_[18] = parentDOFs_ + 18; + rowDOFPtrs_[19] = parentDOFs_ + 19; + rowDOFPtrs_[20] = parentDOFs_ + 20; + rowDOFPtrs_[21] = parentDOFs_ + 21; + rowDOFPtrs_[22] = parentDOFs_ + 22; + rowDOFPtrs_[23] = parentDOFs_ + 23; + rowDOFPtrs_[24] = parentDOFs_ + 24; + rowDOFPtrs_[25] = parentDOFs_ + 25; + rowDOFPtrs_[26] = parentDOFs_ + 26; + rowDOFPtrs_[27] = parentDOFs_ + 27; + rowDOFPtrs_[28] = child0DOFs_ + 27; + rowDOFPtrs_[29] = child1DOFs_ + 27; + rowDOFPtrs_[30] = child0DOFs_ + 20; + rowDOFPtrs_[31] = child0DOFs_ + 30; + rowDOFPtrs_[32] = child1DOFs_ + 30; + rowDOFPtrs_[33] = child0DOFs_ + 17; + rowDOFPtrs_[34] = child0DOFs_ + 24; + rowDOFPtrs_[35] = child0DOFs_ + 10; + rowDOFPtrs_[36] = child0DOFs_ + 12; + rowDOFPtrs_[37] = child0DOFs_ + 16; + rowDOFPtrs_[38] = child0DOFs_ + 18; + rowDOFPtrs_[39] = child0DOFs_ + 19; + rowDOFPtrs_[40] = child0DOFs_ + 21; + rowDOFPtrs_[41] = child0DOFs_ + 22; + rowDOFPtrs_[42] = child0DOFs_ + 23; + rowDOFPtrs_[43] = child0DOFs_ + 25; + rowDOFPtrs_[44] = child0DOFs_ + 26; + rowDOFPtrs_[45] = child0DOFs_ + 28; + rowDOFPtrs_[46] = child0DOFs_ + 29; + rowDOFPtrs_[47] = child0DOFs_ + 34; + rowDOFPtrs_[48] = child1DOFs_ + 10; + rowDOFPtrs_[49] = child1DOFs_ + 12; + rowDOFPtrs_[50] = child1DOFs_ + 25; + rowDOFPtrs_[51] = child1DOFs_ + 26; + rowDOFPtrs_[52] = child1DOFs_ + 28; + rowDOFPtrs_[53] = child1DOFs_ + 29; + rowDOFPtrs_[54] = child1DOFs_ + 34; + + colDOFPtrs_[ 0] = parentDOFs_ + 0; + colDOFPtrs_[ 1] = parentDOFs_ + 1; + colDOFPtrs_[ 2] = parentDOFs_ + 2; + colDOFPtrs_[ 3] = parentDOFs_ + 3; + colDOFPtrs_[ 4] = parentDOFs_ + 4; + colDOFPtrs_[ 5] = parentDOFs_ + 5; + colDOFPtrs_[ 6] = parentDOFs_ + 6; + colDOFPtrs_[ 7] = parentDOFs_ + 7; + colDOFPtrs_[ 8] = parentDOFs_ + 8; + colDOFPtrs_[ 9] = parentDOFs_ + 9; + colDOFPtrs_[10] = parentDOFs_ + 10; + colDOFPtrs_[11] = parentDOFs_ + 11; + colDOFPtrs_[12] = parentDOFs_ + 12; + colDOFPtrs_[13] = parentDOFs_ + 13; + colDOFPtrs_[14] = parentDOFs_ + 14; + colDOFPtrs_[15] = parentDOFs_ + 15; + colDOFPtrs_[16] = parentDOFs_ + 16; + colDOFPtrs_[17] = parentDOFs_ + 17; + colDOFPtrs_[18] = parentDOFs_ + 18; + colDOFPtrs_[19] = parentDOFs_ + 19; + colDOFPtrs_[20] = parentDOFs_ + 20; + colDOFPtrs_[21] = parentDOFs_ + 21; + colDOFPtrs_[22] = parentDOFs_ + 22; + colDOFPtrs_[23] = parentDOFs_ + 23; + colDOFPtrs_[24] = parentDOFs_ + 24; + colDOFPtrs_[25] = parentDOFs_ + 25; + colDOFPtrs_[26] = parentDOFs_ + 26; + colDOFPtrs_[27] = parentDOFs_ + 27; + colDOFPtrs_[28] = parentDOFs_ + 28; + colDOFPtrs_[29] = parentDOFs_ + 29; + colDOFPtrs_[30] = parentDOFs_ + 30; + colDOFPtrs_[31] = parentDOFs_ + 31; + colDOFPtrs_[32] = parentDOFs_ + 32; + colDOFPtrs_[33] = parentDOFs_ + 33; + colDOFPtrs_[34] = parentDOFs_ + 34; + + type0_rowDOFPtrs_[ 0] = parentDOFs_ + 0; + type0_rowDOFPtrs_[ 1] = parentDOFs_ + 1; + type0_rowDOFPtrs_[ 2] = parentDOFs_ + 2; + type0_rowDOFPtrs_[ 3] = parentDOFs_ + 3; + type0_rowDOFPtrs_[ 4] = child0DOFs_ + 11; + type0_rowDOFPtrs_[ 5] = child0DOFs_ + 3; + type0_rowDOFPtrs_[ 6] = child1DOFs_ + 11; + type0_rowDOFPtrs_[ 7] = parentDOFs_ + 7; + type0_rowDOFPtrs_[ 8] = parentDOFs_ + 8; + type0_rowDOFPtrs_[ 9] = parentDOFs_ + 9; + type0_rowDOFPtrs_[10] = parentDOFs_ + 10; + type0_rowDOFPtrs_[11] = parentDOFs_ + 11; + type0_rowDOFPtrs_[12] = parentDOFs_ + 12; + type0_rowDOFPtrs_[13] = parentDOFs_ + 13; + type0_rowDOFPtrs_[14] = parentDOFs_ + 14; + type0_rowDOFPtrs_[15] = parentDOFs_ + 15; + type0_rowDOFPtrs_[16] = parentDOFs_ + 16; + type0_rowDOFPtrs_[17] = parentDOFs_ + 17; + type0_rowDOFPtrs_[18] = parentDOFs_ + 18; + type0_rowDOFPtrs_[19] = parentDOFs_ + 19; + type0_rowDOFPtrs_[20] = parentDOFs_ + 20; + type0_rowDOFPtrs_[21] = parentDOFs_ + 21; + type0_rowDOFPtrs_[22] = parentDOFs_ + 22; + type0_rowDOFPtrs_[23] = parentDOFs_ + 23; + type0_rowDOFPtrs_[24] = parentDOFs_ + 24; + type0_rowDOFPtrs_[25] = parentDOFs_ + 25; + type0_rowDOFPtrs_[26] = parentDOFs_ + 26; + type0_rowDOFPtrs_[27] = parentDOFs_ + 27; + type0_rowDOFPtrs_[28] = child0DOFs_ + 27; + type0_rowDOFPtrs_[29] = child1DOFs_ + 30; + type0_rowDOFPtrs_[30] = child0DOFs_ + 20; + type0_rowDOFPtrs_[31] = child0DOFs_ + 30; + type0_rowDOFPtrs_[32] = child1DOFs_ + 27; + type0_rowDOFPtrs_[33] = child0DOFs_ + 17; + type0_rowDOFPtrs_[34] = child0DOFs_ + 24; + type0_rowDOFPtrs_[35] = child0DOFs_ + 10; + type0_rowDOFPtrs_[36] = child0DOFs_ + 12; + type0_rowDOFPtrs_[37] = child0DOFs_ + 16; + type0_rowDOFPtrs_[38] = child0DOFs_ + 18; + type0_rowDOFPtrs_[39] = child0DOFs_ + 19; + type0_rowDOFPtrs_[40] = child0DOFs_ + 21; + type0_rowDOFPtrs_[41] = child0DOFs_ + 22; + type0_rowDOFPtrs_[42] = child0DOFs_ + 23; + type0_rowDOFPtrs_[43] = child0DOFs_ + 25; + type0_rowDOFPtrs_[44] = child0DOFs_ + 26; + type0_rowDOFPtrs_[45] = child0DOFs_ + 28; + type0_rowDOFPtrs_[46] = child0DOFs_ + 29; + type0_rowDOFPtrs_[47] = child0DOFs_ + 34; + type0_rowDOFPtrs_[48] = child1DOFs_ + 10; + type0_rowDOFPtrs_[49] = child1DOFs_ + 12; + type0_rowDOFPtrs_[50] = child1DOFs_ + 28; + type0_rowDOFPtrs_[51] = child1DOFs_ + 29; + type0_rowDOFPtrs_[52] = child1DOFs_ + 25; + type0_rowDOFPtrs_[53] = child1DOFs_ + 26; + type0_rowDOFPtrs_[54] = child1DOFs_ + 34; + + type0_colDOFPtrs_[ 0] = parentDOFs_ + 0; + type0_colDOFPtrs_[ 1] = parentDOFs_ + 1; + type0_colDOFPtrs_[ 2] = parentDOFs_ + 2; + type0_colDOFPtrs_[ 3] = parentDOFs_ + 3; + type0_colDOFPtrs_[ 4] = parentDOFs_ + 4; + type0_colDOFPtrs_[ 5] = parentDOFs_ + 5; + type0_colDOFPtrs_[ 6] = parentDOFs_ + 6; + type0_colDOFPtrs_[ 7] = parentDOFs_ + 7; + type0_colDOFPtrs_[ 8] = parentDOFs_ + 8; + type0_colDOFPtrs_[ 9] = parentDOFs_ + 9; + type0_colDOFPtrs_[10] = parentDOFs_ + 10; + type0_colDOFPtrs_[11] = parentDOFs_ + 11; + type0_colDOFPtrs_[12] = parentDOFs_ + 12; + type0_colDOFPtrs_[13] = parentDOFs_ + 13; + type0_colDOFPtrs_[14] = parentDOFs_ + 14; + type0_colDOFPtrs_[15] = parentDOFs_ + 15; + type0_colDOFPtrs_[16] = parentDOFs_ + 16; + type0_colDOFPtrs_[17] = parentDOFs_ + 17; + type0_colDOFPtrs_[18] = parentDOFs_ + 18; + type0_colDOFPtrs_[19] = parentDOFs_ + 19; + type0_colDOFPtrs_[20] = parentDOFs_ + 20; + type0_colDOFPtrs_[21] = parentDOFs_ + 21; + type0_colDOFPtrs_[22] = parentDOFs_ + 22; + type0_colDOFPtrs_[23] = parentDOFs_ + 23; + type0_colDOFPtrs_[24] = parentDOFs_ + 24; + type0_colDOFPtrs_[25] = parentDOFs_ + 25; + type0_colDOFPtrs_[26] = parentDOFs_ + 26; + type0_colDOFPtrs_[27] = parentDOFs_ + 27; + type0_colDOFPtrs_[28] = parentDOFs_ + 28; + type0_colDOFPtrs_[29] = parentDOFs_ + 29; + type0_colDOFPtrs_[30] = parentDOFs_ + 30; + type0_colDOFPtrs_[31] = parentDOFs_ + 31; + type0_colDOFPtrs_[32] = parentDOFs_ + 32; + type0_colDOFPtrs_[33] = parentDOFs_ + 33; + type0_colDOFPtrs_[34] = parentDOFs_ + 34; + }; + }; + + /** \brief + * interpolMatrices[n][m] stores the interpolation matrix for + * n-dimensional elements and m-dimensional basis functions. + */ + extern InterpolRestrictMatrix *interpolMatrices[3][4]; + + /** \brief + * interpolMatrices[n][m] stores the restriction matrix for + * n-dimensional elements and m-dimensional basis functions. + */ + extern InterpolRestrictMatrix *restrictMatrices[3][4]; +} + +#endif diff --git a/AMDiS/src/LeafData.cc b/AMDiS/src/LeafData.cc new file mode 100644 index 0000000000000000000000000000000000000000..b21899031c827b12f4903ca6ece416619cdbd451 --- /dev/null +++ b/AMDiS/src/LeafData.cc @@ -0,0 +1,381 @@ +#include "LeafData.h" +#include "Element.h" +#include "Mesh.h" + +namespace AMDiS { + +bool LeafDataEstimatable::refineElementData(Element* parent, + Element* child1, + Element* child2, + int elType) + +{ + ElementData::refineElementData(parent, child1, child2, elType); + + LeafDataEstimatable *child1Data = + NEW LeafDataEstimatable(child1->getElementData()); + LeafDataEstimatable *child2Data = + NEW LeafDataEstimatable(child2->getElementData()); + + child1Data->setErrorEstimate(0, errorEstimate / 2.0); + child2Data->setErrorEstimate(0, errorEstimate / 2.0); + + child1->setElementData(child1Data); + child2->setElementData(child2Data); + + return true; +} + +void LeafDataEstimatable::coarsenElementData(Element* parent, + Element* thisChild, + Element* otherChild, + int elTypeParent) + +{ + TEST_EXIT(otherChild->deleteElementData(ESTIMATABLE)) + ("couldn't delete LeafDataEstimatable at otherChild"); + parent->setElementData(NEW LeafDataEstimatable(parent->getElementData())); + ElementData::coarsenElementData(parent, thisChild, otherChild, elTypeParent); +} + +bool LeafDataEstimatableVec::refineElementData(Element* parent, + Element* child1, + Element* child2, + int elType) + +{ + ElementData::refineElementData(parent, child1, child2, elType); + //int size = dynamic_cast<int>(errorEstimate.size()); + child1->setElementData(NEW LeafDataEstimatableVec(//size, + child1->getElementData())); + child2->setElementData(NEW LeafDataEstimatableVec(//size, + child2->getElementData())); + + return true; +} + +void LeafDataEstimatableVec::coarsenElementData(Element* parent, + Element* thisChild, + Element* otherChild, + int elTypeParent) + +{ + TEST_EXIT(otherChild->deleteElementData(ESTIMATABLE)) + ("couldn't delete LeafDataEstimatableVec at otherChild"); + //int size = errorEstimate.getSize(); + parent->setElementData(NEW LeafDataEstimatableVec(//size, + parent->getElementData())); + ElementData::coarsenElementData(parent, thisChild, otherChild, elTypeParent); +} + +bool LeafDataCoarsenable::refineElementData(Element* parent, + Element* child1, + Element* child2, + int elType) + { + ElementData::refineElementData(parent, child1, child2, elType); + child1->setElementData(NEW LeafDataCoarsenable(child1->getElementData())); + child2->setElementData(NEW LeafDataCoarsenable(child2->getElementData())); + return true; +} + +void LeafDataCoarsenable::coarsenElementData(Element* parent, + Element* thisChild, + Element* otherChild, + int elTypeParent) +{ + TEST_EXIT(otherChild->deleteElementData(COARSENABLE)) + ("couldn't delete LeafDataCoarsenable at otherChild"); + parent->setElementData(NEW LeafDataCoarsenable(parent->getElementData())); + ElementData::coarsenElementData(parent, thisChild, otherChild, elTypeParent); +} + +bool LeafDataCoarsenableVec::refineElementData(Element* parent, + Element* child1, + Element* child2, + int elType) +{ + ElementData::refineElementData(parent, child1, child2, elType); + child1->setElementData(NEW LeafDataCoarsenableVec(child1->getElementData())); + child2->setElementData(NEW LeafDataCoarsenableVec(child2->getElementData())); + return true; +} + +void LeafDataCoarsenableVec::coarsenElementData(Element* parent, + Element* thisChild, + Element* otherChild, + int elTypeParent) +{ + TEST_EXIT(otherChild->deleteElementData(COARSENABLE)) + ("couldn't delete LeafDataCoarsenableVec at otherChild"); + parent->setElementData(NEW LeafDataCoarsenableVec(parent->getElementData())); + ElementData::coarsenElementData(parent, thisChild, otherChild, elTypeParent); +} + +bool LeafDataPeriodic::refineElementData(Element* parent, + Element* child1, + Element* child2, + int elType) +{ + ElementData::refineElementData(parent, child1, child2, elType); + + int i, j; + + Element* child[2] = {child1, child2}; + + int dim = parent->getMesh()->getDim(); + + LeafDataPeriodic *ld[2] = {NULL, NULL}; + + ::std::list<LeafDataPeriodic::PeriodicInfo>::iterator it; + + for(it = periodicInfoList.begin(); + it != periodicInfoList.end(); + ++it) + { + BoundaryType type = it->type; + + int parentSide = it->elementSide; + + int mode = it->periodicMode; + + // for both children + for(i=0; i < 2; i++) { + + // get childs side + int sideOfChild = parent->getSideOfChild(i, parentSide, elType); + if(sideOfChild == -1) continue; + + // create new leaf data if necessary + if(!ld[i]) { + ld[i] = NEW LeafDataPeriodic(child[i]->getElementData()); + //ld[i]->newDOF = newDOF; + child[i]->setElementData(ld[i]); + } + + // create new periodic coords + DimVec<WorldVector<double> > coords(dim-1, NO_INIT); + + // create new periodic dofs + //DimVec<DegreeOfFreedom> dofs(dim-1, DEFAULT_VALUE, -1); + + // for each vertex of childs side + for(j=0; j < dim; j++) { + // get parents vertex nr. + int childVertex = child[i]->getVertexOfPosition(INDEX_OF_DIM(dim-1,dim), + sideOfChild, + j); + int parentVertex = child[i]->getVertexOfParent(i, childVertex, elType); + + if(parentVertex == -1) { + // create coords for new vertex + WorldVector<double> newCoords; + newCoords = (*(it->periodicCoords))[0]; + newCoords += (*(it->periodicCoords))[1]; + newCoords *= 0.5; + coords[j] = newCoords; + //dofs[j] = newDOF; + //TEST_EXIT(newDOF != -1)("newDOF not set\n"); + } else { + int posAtSide = parent->getPositionOfVertex(parentSide, + parentVertex); + coords[j] = (*(it->periodicCoords))[posAtSide]; + //dofs[j] = it->periodicDOFs[posAtSide]; + } + } + + ld[i]->addPeriodicInfo(mode, type, sideOfChild, &coords); + +// MSG("parent %d, child%d %d, periodic dofs %d %d\n", +// parent->getIndex(), +// i, +// child[i]->getIndex(), +// dofs[0], dofs[1]); + } + } + + return false; +} + +LeafDataPeriodic::PeriodicInfo::PeriodicInfo(const PeriodicInfo &rhs) +{ + periodicMode = rhs.periodicMode; + type = rhs.type; + elementSide = rhs.elementSide; + int i, dim; + if(rhs.periodicCoords) { + dim = rhs.periodicCoords->getSize() - 1; + periodicCoords = NEW DimVec<WorldVector<double> >(dim, NO_INIT); + for(i = 0; i < dim + 1; i++) { + (*periodicCoords)[i] = (*(rhs.periodicCoords))[i]; + } + + } else { + periodicCoords = NULL; + } +} + +LeafDataPeriodic::PeriodicInfo::PeriodicInfo(int mode, + BoundaryType t, + int side, + const DimVec<WorldVector<double> > *coords) + : periodicMode(mode), + type(t), + elementSide(side), + periodicCoords(NULL) +{ + int i, dim; + if(coords) { + dim = coords->getSize() - 1; + periodicCoords = NEW DimVec<WorldVector<double> >(dim, NO_INIT); + for(i = 0; i < dim + 1; i++) { + (*periodicCoords)[i] = (*coords)[i]; + } + } +} + +// void LeafDataPeriodicRefinable::refineLeafData(Element* parent, +// Element* child1, +// Element* child2) +// { +// if(decoratedLeafData) { +// LeafDataPeriodic *ldp = +// (LeafDataPeriodic*) decoratedLeafData->getDecoratedLeafData(PERIODIC); +// TEST_EXIT(ldp)("no periodic leaf data\n"); + +// LeafDataRefinable *ldr = (LeafDataRefinable*) +// decoratedLeafData->getDecoratedLeafData(REFINABLE); +// if(ldr) { +// ldr->refineLeafData(parent, child1, child2); +// } + +// int dim = parent->getMesh()->getDim(); + +// LeafDataPeriodic *ld1 = NULL; +// LeafDataPeriodic *ld2 = NULL; + +// ::std::list<LeafDataPeriodic::PeriodicInfo>::iterator it; + +// switch(dim) { +// case 1: // ----- dim = 1 ----- +// // for each periodic info +// for(it = ldp->periodicInfoList.begin(); +// it != ldp->periodicInfoList.end(); +// ++it) +// { +// switch(it->elementSide) { +// case 0: // ----- side 0 ----- +// if(!ld1) +// ld1 = NEW LeafDataPeriodic(child1->getLeafData()); +// ld1->addPeriodicInfo(0, it->periodicCoords); +// child1->setLeafData(NEW LeafDataPeriodicRefinable +// (NEW LeafDataPeriodicCoarsenable(ld1)) +// ); +// break; +// case 1: // ----- side 1 ----- +// if(!ld2) +// ld2 = NEW LeafDataPeriodic(child2->getLeafData()); +// ld2->addPeriodicInfo(0, it->periodicCoords); +// child2->setLeafData(NEW LeafDataPeriodicRefinable +// (NEW LeafDataPeriodicCoarsenable(ld2)) +// ); +// break; +// default: ERROR_EXIT("invalid element side\n"); +// } +// } +// break; +// case 2: // ----- dim = 2 ----- +// // for each periodic info +// for(it = ldp->periodicInfoList.begin(); +// it != ldp->periodicInfoList.end(); +// ++it) +// { +// switch(it->elementSide) { +// case 0: // ----- side 0 ----- +// if(!ld2) +// ld2 = NEW LeafDataPeriodic(child2->getLeafData()); +// ld2->addPeriodicInfo(2, it->periodicCoords); +// child2->setLeafData(NEW LeafDataPeriodicRefinable +// (NEW LeafDataPeriodicCoarsenable(ld2)) +// ); +// break; +// case 1: // ----- side 1 ----- +// if(!ld1) +// ld1 = NEW LeafDataPeriodic(child1->getLeafData()); +// ld1->addPeriodicInfo(2, it->periodicCoords); +// child1->setLeafData(NEW LeafDataPeriodicRefinable +// (NEW LeafDataPeriodicCoarsenable(ld1)) +// ); +// break; +// case 2: // ----- side 2 ----- +// { +// if(!ld1) +// ld1 = NEW LeafDataPeriodic(child1->getLeafData()); +// if(!ld2) +// ld2 = NEW LeafDataPeriodic(child2->getLeafData()); + +// DimVec<WorldVector<double> > coords1(it->periodicCoords); +// DimVec<WorldVector<double> > coords2(it->periodicCoords); + +// WorldVector<double> newCoords; +// newCoords = it->periodicCoords[0]; +// newCoords += it->periodicCoords[1]; +// newCoords *= 0.5; + +// coords1[1] = newCoords; +// coords2[0] = newCoords; + +// ld1->addPeriodicInfo(0, coords1); +// ld2->addPeriodicInfo(1, coords2); + +// child1->setLeafData(NEW LeafDataPeriodicRefinable +// (NEW LeafDataPeriodicCoarsenable(ld1)) +// ); +// child2->setLeafData(NEW LeafDataPeriodicRefinable +// (NEW LeafDataPeriodicCoarsenable(ld2)) +// ); +// } +// break; +// default: ERROR_EXIT("invalid element side\n"); +// } +// } +// break; +// case 3: // ----- dim = 3 ----- +// ERROR_EXIT("not yet for 3d\n"); +// // for each periodic info +// for(it = ldp->periodicInfoList.begin(); +// it != ldp->periodicInfoList.end(); +// ++it) +// { +// switch(it->elementSide) { +// case 0: // ----- side 0 ----- +// break; +// case 1: // ----- side 1 ----- +// break; +// case 2: // ----- side 2 ----- +// break; +// case 3: // ----- side 3 ----- +// break; +// default: ERROR_EXIT("invalid element side\n"); +// } +// } +// break; +// default: ERROR_EXIT("invalid dim\n"); +// } +// } +// } + +// LeafData *LeafData::createLeafData(::std::string type) +// { +// if(type == "NULL") return NULL; +// if(type == "LeafDataEstimatable") return new LeafDataEstimatable; +// if(type == "LeafDataEstimatableVec") return new LeafDataEstimatableVec; +// if(type == "LeafDataCoarsenable") return new LeafDataCoarsenable; +// if(type == "LeafDataCoarsenableVec") return new LeafDataCoarsenableVec; +// if(type == "LeafDataPeriodic") return new LeafDataPeriodic; + +// ERROR_EXIT("unknown type\n"); +// return NULL; +// } + +} diff --git a/AMDiS/src/LeafData.h b/AMDiS/src/LeafData.h new file mode 100644 index 0000000000000000000000000000000000000000..1573ab4227e78f27ca356b63bbd01b893a4607bb --- /dev/null +++ b/AMDiS/src/LeafData.h @@ -0,0 +1,655 @@ +// ============================================================================ +// == == +// == AMDiS - Adaptive multidimensional simulations == +// == == +// ============================================================================ +// == == +// == crystal growth group == +// == == +// == Stiftung caesar == +// == Ludwig-Erhard-Allee 2 == +// == 53175 Bonn == +// == germany == +// == == +// ============================================================================ +// == == +// == http://www.caesar.de/cg/AMDiS == +// == == +// ============================================================================ + +/** \file LeafData.h */ + +#ifndef AMDIS_LEAFDATA_H +#define AMDIS_LEAFDATA_H + +#include <list> +#include <map> +#include "MemoryManager.h" +#include "Serializable.h" +#include "FixVec.h" +#include "ElementData.h" +#include "Boundary.h" + + +namespace AMDiS { + + class LeafDataEstimatableInterface + { + public: + virtual ~LeafDataEstimatableInterface() {}; + virtual void setErrorEstimate(int, double) = 0; + virtual double getErrorEstimate(int) = 0; + }; + + class LeafDataEstimatable : public ElementData, + public LeafDataEstimatableInterface + { + public: + MEMORY_MANAGED(LeafDataEstimatable); + + inline bool isOfType(int type) const { + if(type == ESTIMATABLE) + return true; + return false; + }; + + class Creator : public CreatorInterface<ElementData> + { + public: + ElementData* create() { + return NEW LeafDataEstimatable; + }; + }; + + /** \brief + * constructor + */ + LeafDataEstimatable(ElementData *decorated = NULL) + : ElementData(decorated), errorEstimate(0.) + {}; + + /** \brief + * Refinement of parent to child1 and child2. + */ + bool refineElementData(Element* parent, + Element* child1, + Element* child2, + int elType); + + /** \brief + * + */ + void coarsenElementData(Element* parent, + Element* thisChild, + Element* otherChild, + int elTypeParent); + + /** \brief + * Sets \ref errorEstimate + */ + inline void setErrorEstimate(int, double est) { errorEstimate = est; }; + + /** \brief + * Returns \ref errorEstimate + */ + inline double getErrorEstimate(int) { return errorEstimate; }; + + /** \brief + * Implements ElementData::clone(). + */ + virtual ElementData *clone() const { + // create new estimatable leaf data + LeafDataEstimatable *newObj = new LeafDataEstimatable(NULL); + + newObj->errorEstimate = errorEstimate; + + // clone decorated element data (=> deep copy) + newObj->decorated_ = ElementData::clone(); + + // return the clone + return newObj; + }; + + /** \brief + * Returns the name of element data type. + */ + inline ::std::string getTypeName() const { return "LeafDataEstimatable"; }; + + inline const int getTypeID() const { return ESTIMATABLE; }; + + void serialize(::std::ostream& out) + { + ElementData::serialize(out); + out.write(reinterpret_cast<const char*>(&errorEstimate), sizeof(double)); + }; + + void deserialize(::std::istream& in) + { + ElementData::deserialize(in); + in.read(reinterpret_cast<char*>(&errorEstimate), sizeof(double)); + }; + + private: + double errorEstimate; + }; + + class LeafDataEstimatableVec : public ElementData, + public LeafDataEstimatableInterface + { + public: + MEMORY_MANAGED(LeafDataEstimatableVec); + + class Creator : public CreatorInterface<ElementData> + { + public: + ElementData* create() { + return NEW LeafDataEstimatableVec; + }; + }; + + inline bool isOfType(int type) const { + if(type == ESTIMATABLE) + return true; + return false; + }; + + /** \brief + * constructor + */ + LeafDataEstimatableVec(ElementData *decorated = NULL) + : ElementData(decorated) + { + //errorEstimate.set(0.0); + }; + + /** \brief + * Refinement of parent to child1 and child2. + */ + bool refineElementData(Element* parent, + Element* child1, + Element* child2, + int elType); + + /** \brief + * + */ + void coarsenElementData(Element* parent, + Element* thisChild, + Element* otherChild, + int elTypeParent); + + /** \brief + * Sets \ref errorEstimate + */ + inline void setErrorEstimate(int index, double est) { + // TEST_EXIT(index < static_cast<int>(errorEstimate.getSize())) + // ("invalid index\n"); + errorEstimate[index] = est; + }; + + /** \brief + * Returns \ref errorEstimate + */ + // inline double getErrorEstimate(int index) const { + // return const_cast<map<int,double,less<int>,allocator<double> >*>(&errorEstimate)->operator[](index); + // }; + + /** \brief + * Returns \ref errorEstimate + */ + inline double getErrorEstimate(int index) { + return errorEstimate[index]; + }; + + /** \brief + * Implements ElementData::clone(). + */ + virtual ElementData *clone() const { + // create new estimatable leaf data + LeafDataEstimatableVec *newObj = + new LeafDataEstimatableVec(NULL); + + newObj->errorEstimate = errorEstimate; + + // clone decorated element data (=> deep copy) + newObj->decorated_ = ElementData::clone(); + + // return the clone + return newObj; + }; + + void serialize(::std::ostream& out) + { + ElementData::serialize(out); + unsigned int size = errorEstimate.size(); + out.write(reinterpret_cast<const char*>(&size), sizeof(unsigned int)); + ::std::map<int, double>::iterator it; + for(it = errorEstimate.begin(); it != errorEstimate.end(); ++it) { + out.write(reinterpret_cast<const char*>(&(it->first)), sizeof(int)); + out.write(reinterpret_cast<const char*>(&(it->second)), sizeof(double)); + } + }; + + void deserialize(::std::istream& in) + { + ElementData::deserialize(in); + unsigned int i, size; + in.read(reinterpret_cast<char*>(&size), sizeof(unsigned int)); + for(i = 0; i < size; i++) { + int index; + double estimate; + in.read(reinterpret_cast<char*>(&index), sizeof(int)); + in.read(reinterpret_cast<char*>(&estimate), sizeof(double)); + errorEstimate[index] = estimate; + } + }; + + ::std::string getTypeName() const + { + return "LeafDataEstimatableVec"; + }; + + inline const int getTypeID() const { return ESTIMATABLE; }; + + private: + ::std::map<int, double> errorEstimate; + }; + + class LeafDataCoarsenableInterface + { + public: + virtual ~LeafDataCoarsenableInterface() {}; + + /** \brief + * Sets \ref coarseningError + */ + virtual void setCoarseningErrorEstimate(int index, double est)=0; + + /** \brief + * Returns \ref coarseningError + */ + virtual double getCoarseningErrorEstimate(int index) = 0; + }; + + class LeafDataCoarsenable : public ElementData, + public LeafDataCoarsenableInterface + { + public: + MEMORY_MANAGED(LeafDataCoarsenable); + + class Creator : public CreatorInterface<ElementData> + { + public: + ElementData* create() { + return NEW LeafDataCoarsenable; + }; + }; + + inline bool isOfType(int type) const { + if(type == COARSENABLE) + return true; + return false; + }; + + /** \brief + * constructor + */ + LeafDataCoarsenable(ElementData *decorated = NULL) + : ElementData(decorated), coarseningError(0.0) + {}; + + /** \brief + * Refinement of parent to child1 and child2. + */ + bool refineElementData(Element* parent, + Element* child1, + Element* child2, + int elType); + + /** \brief + * Refinement of parent to child1 and child2. + */ + void coarsenElementData(Element* parent, + Element* thisChild, + Element* otherChild, + int elTypeParent); + + /** \brief + * Implements ElementData::clone(). + */ + inline ElementData *clone() const { + // create new estimatable leaf data + LeafDataCoarsenable *newObj = new LeafDataCoarsenable(NULL); + + // clone decorated element data (=> deep copy) + newObj->decorated_ = ElementData::clone(); + + // return the clone + return newObj; + }; + + /** \brief + * Sets \ref coarseningError + */ + virtual void setCoarseningErrorEstimate(int , double est) { + coarseningError = est; + }; + + /** \brief + * Returns \ref coarseningError + */ + virtual double getCoarseningErrorEstimate(int) { + return coarseningError; + }; + + // ===== Serializable implementation ===== + + void serialize(::std::ostream& out) + { + ElementData::serialize(out); + out.write(reinterpret_cast<const char*>(&coarseningError), sizeof(double)); + }; + + void deserialize(::std::istream& in) + { + ElementData::deserialize(in); + in.read(reinterpret_cast<char*>(&coarseningError), sizeof(double)); + }; + + ::std::string getTypeName() const + { + return "LeafDataCoarsenable"; + }; + + inline const int getTypeID() const { return COARSENABLE; }; + + private: + double coarseningError; /**< \brief coarsening error */ + }; + + + + class LeafDataCoarsenableVec : public ElementData, + public LeafDataCoarsenableInterface + { + public: + MEMORY_MANAGED(LeafDataCoarsenableVec); + + class Creator : public CreatorInterface<ElementData> + { + public: + ElementData* create() { + return NEW LeafDataCoarsenableVec; + }; + }; + + inline bool isOfType(int type) const { + if(type == COARSENABLE) + return true; + return false; + }; + + /** \brief + * constructor + */ + LeafDataCoarsenableVec(ElementData *decorated = NULL) + : ElementData(decorated) + {}; + + /** \brief + * Implements ElementData::clone(). + */ + inline ElementData *clone() const { + // create new estimatable leaf data + LeafDataCoarsenableVec *newObj = + new LeafDataCoarsenableVec(NULL); + + newObj->coarseningError = coarseningError; + + // clone decorated leaf data (=> deep copy) + newObj->decorated_ = ElementData::clone(); + + // return the clone + return newObj; + }; + + /** \brief + * Refinement of parent to child1 and child2. + */ + bool refineElementData(Element* parent, + Element* child1, + Element* child2, + int elType); + + /** \brief + * Refinement of parent to child1 and child2. + */ + void coarsenElementData(Element* parent, + Element* thisChild, + Element* otherChild, + int elTypeParent); + + /** \brief + * Sets \ref coarseningError + */ + virtual void setCoarseningErrorEstimate(int index, double est) { + coarseningError[index] = est; + }; + + /** \brief + * Returns \ref coarseningError + */ + virtual double getCoarseningErrorEstimate(int index) { + return coarseningError[index]; + }; + + // ===== Serializable implementation ===== + + void serialize(::std::ostream& out) + { + ElementData::serialize(out); + unsigned int size = coarseningError.size(); + out.write(reinterpret_cast<const char*>(&size), sizeof(unsigned int)); + ::std::map<int, double>::iterator it; + for(it = coarseningError.begin(); it != coarseningError.end(); ++it) { + out.write(reinterpret_cast<const char*>(&(it->first)), sizeof(int)); + out.write(reinterpret_cast<const char*>(&(it->second)), sizeof(double)); + } + }; + + void deserialize(::std::istream& in) + { + ElementData::deserialize(in); + unsigned int i, size; + in.read(reinterpret_cast<char*>(&size), sizeof(unsigned int)); + for(i = 0; i < size; i++) { + int index; + double estimate; + in.read(reinterpret_cast<char*>(&index), sizeof(int)); + in.read(reinterpret_cast<char*>(&estimate), sizeof(double)); + coarseningError[index] = estimate; + } + }; + + ::std::string getTypeName() const + { + return "LeafDataCoarsenableVec"; + }; + + inline const int getTypeID() const { return COARSENABLE; }; + + private: + ::std::map<int, double> coarseningError; /**< \brief coarsening error */ + }; + + + + class LeafDataPeriodic : public ElementData + { + public: + MEMORY_MANAGED(LeafDataPeriodic); + + class Creator : public CreatorInterface<ElementData> + { + public: + ElementData* create() { + return NEW LeafDataPeriodic; + }; + }; + + inline bool isOfType(int type) const { + if(type == PERIODIC) + return true; + return false; + }; + + + class PeriodicInfo : public Serializable + { + public: + PeriodicInfo() + : periodicCoords(NULL) + {}; + + PeriodicInfo(int mode, + BoundaryType t, + int side, + const DimVec<WorldVector<double> > *coords); + + virtual ~PeriodicInfo() { + if(periodicCoords) DELETE periodicCoords; + }; + + PeriodicInfo(const PeriodicInfo &rhs); + + void serialize(::std::ostream &out) { + out.write(reinterpret_cast<const char*>(&periodicMode), sizeof(int)); + out.write(reinterpret_cast<const char*>(&type), sizeof(BoundaryType)); + out.write(reinterpret_cast<const char*>(&elementSide), sizeof(int)); + int i, size; + if(periodicCoords) { + size = periodicCoords->getSize(); + out.write(reinterpret_cast<const char*>(&size), sizeof(int)); + for(i = 0; i < size; i++) { + (*periodicCoords)[i].serialize(out); + } + } else { + size = 0; + out.write(reinterpret_cast<const char*>(&size), sizeof(int)); + } + }; + + void deserialize(::std::istream &in) + { + in.read(reinterpret_cast<char*>(&periodicMode), sizeof(int)); + in.read(reinterpret_cast<char*>(&type), sizeof(BoundaryType)); + in.read(reinterpret_cast<char*>(&elementSide), sizeof(int)); + + int i, size; + in.read(reinterpret_cast<char*>(&size), sizeof(int)); + if(periodicCoords) DELETE periodicCoords; + if(size == 0) { + periodicCoords = NULL; + } else { + periodicCoords = NEW DimVec<WorldVector<double> >(size-1, NO_INIT); + for(i = 0; i < size; i++) { + (*periodicCoords)[i].deserialize(in); + } + } + }; + + int periodicMode; + BoundaryType type; + int elementSide; + DimVec<WorldVector<double> > *periodicCoords; + }; + + public: + /** \brief + * constructor + */ + LeafDataPeriodic(ElementData *decorated = NULL) + : ElementData(decorated) + //newDOF(-1) + {}; + + /** \brief + * Destructor. + */ + ~LeafDataPeriodic() {}; + + /** \brief + * Implements LeafData::clone(). + */ + inline ElementData *clone() const { + LeafDataPeriodic *newObj = new LeafDataPeriodic; + newObj->decorated_ = ElementData::clone(); + return newObj; + }; + + inline void addPeriodicInfo(int mode, + BoundaryType type, + int side, + const DimVec<WorldVector<double> > *coords) + { + PeriodicInfo periodicInfo(mode, type, side, coords); + periodicInfoList.push_back(periodicInfo); + }; + + inline ::std::list<PeriodicInfo>& getInfoList() { + return periodicInfoList; + }; + + // ===== Serializable implementation ===== + + void serialize(::std::ostream& out) + { + ElementData::serialize(out); + //out.write(reinterpret_cast<const char*>(&newDOF), sizeof(DegreeOfFreedom)); + unsigned int size = periodicInfoList.size(); + out.write(reinterpret_cast<const char*>(&size), sizeof(unsigned int)); + ::std::list<PeriodicInfo>::iterator it; + for(it = periodicInfoList.begin(); it != periodicInfoList.end(); ++it) { + it->serialize(out); + } + }; + + void deserialize(::std::istream& in) + { + ElementData::deserialize(in); + //in.read(reinterpret_cast<char*>(&newDOF), sizeof(DegreeOfFreedom)); + unsigned int size; + in.read(reinterpret_cast<char*>(&size), sizeof(unsigned int)); + periodicInfoList.resize(size); + ::std::list<PeriodicInfo>::iterator it; + for(it = periodicInfoList.begin(); it != periodicInfoList.end(); ++it) { + it->deserialize(in); + } + }; + + ::std::string getTypeName() const + { + return "LeafDataPeriodic"; + }; + + inline const int getTypeID() const { return PERIODIC; }; + + bool refineElementData(Element* parent, + Element* child1, + Element* child2, + int elType); + + // inline void setNewDOF(DegreeOfFreedom nd) { newDOF = nd; }; + + private: + //DegreeOfFreedom newDOF; + ::std::list<PeriodicInfo> periodicInfoList; + + friend class LeafDataPeriodicRefinable; + friend class LeafDataPeriodicCoarsenable; + }; + +} + +#endif // AMDIS_LEAFDATA_H + diff --git a/AMDiS/src/Line.cc b/AMDiS/src/Line.cc new file mode 100644 index 0000000000000000000000000000000000000000..d46208179fea9e61b91655a75bfddb20c414b401 --- /dev/null +++ b/AMDiS/src/Line.cc @@ -0,0 +1,47 @@ +#include "Line.h" +#include "DOFAdmin.h" +#include "Mesh.h" +#include "CoarseningManager.h" +#include "FixVec.h" + +namespace AMDiS { + + const int Line::vertexOfEdge[1][2] = {{0, 1}}; + + const int Line::sideOfChild[2][2] = {{ 0,-1}, + {-1, 1}}; + + const int Line::vertexOfParent[2][2] = {{ 0,-1}, + {-1, 1}}; + + int Line::getVertexOfPosition(GeoIndex position, + int positionIndex, + int vertexIndex) const + { + FUNCNAME("Line::getVertexOfPosition"); + + switch(position) { + case VERTEX: + return positionIndex; + break; + case CENTER: + return vertexIndex; + break; + default: + ERROR_EXIT("invalid position\n"); + return 0; + } + } + + const FixVec<int, WORLD>& Line::sortFaceIndices(int face, + FixVec<int,WORLD> *vec) const + { + // FUNCNAME("Line::sortFaceIndices"); + // ERROR_EXIT("must not be called for dim = 1!"); + static FixVec<int, WORLD> result(1, NO_INIT); + FixVec<int, WORLD> *v = vec ? vec : &result; + (*v)[0] = face; + return *v; + } + +} diff --git a/AMDiS/src/Line.h b/AMDiS/src/Line.h new file mode 100644 index 0000000000000000000000000000000000000000..c1c85a8a86d566dca59ba6c809980b4278d57388 --- /dev/null +++ b/AMDiS/src/Line.h @@ -0,0 +1,174 @@ +// ============================================================================ +// == == +// == AMDiS - Adaptive multidimensional simulations == +// == == +// ============================================================================ +// == == +// == crystal growth group == +// == == +// == Stiftung caesar == +// == Ludwig-Erhard-Allee 2 == +// == 53175 Bonn == +// == germany == +// == == +// ============================================================================ +// == == +// == http://www.caesar.de/cg/AMDiS == +// == == +// ============================================================================ + +/** \file Line.h */ + +#ifndef AMDIS_LINE_H +#define AMDIS_LINE_H + +#include "Element.h" +#include "MemoryManager.h" + +namespace AMDiS { + +// ========================================================================== +// ===== class Line ========================================================= +// ========================================================================== + +/** \ingroup Triangulation + * \brief + * A Line is an 1-dimensional Element. + * + * A Line and its refinements: + * + * <img src = "line.png"> + */ +class Line : public Element +{ +public: + MEMORY_MANAGED(Line); + + /** \brief + * calls base class contructor. + */ + Line(Mesh* aMesh) : Element(aMesh) {}; + + /** \brief + * implements Element::getVertexOfEdge + */ + inline int getVertexOfEdge(int i, int j) const { + return vertexOfEdge[i][j]; + }; + + /** \brief + * implements Element::getVertexOfPosition + */ + virtual int getVertexOfPosition(GeoIndex position, + int positionIndex, + int vertexIndex) const; + + virtual int getPositionOfVertex(int side, int vertex) const { + static int positionOfVertex[2][2] = {{0,-1},{-1,0}}; + return positionOfVertex[side][vertex]; + }; + + /** \brief + * implements Element::getGeo + */ + inline int getGeo(GeoIndex i) const { + switch(i) { + case VERTEX: case PARTS: case NEIGH: + return 2; + break; + case EDGE: case FACE: + return 0; + break; + case CENTER: case DIMEN: + return 1; + break; + case PROJECTION: case BOUNDARY: + return 2; + break; + default: + ERROR_EXIT("invalid geo-index\n"); + return 0; + } + }; + + inline int getEdgeOfFace(int /* face */, int /*edge*/ ) const { + ERROR_EXIT("called for a line\n"); + return 0; + }; + + /** \brief + * implements Element::sortFaceIndices + */ + const FixVec<int,WORLD>& sortFaceIndices(int face, + FixVec<int,WORLD> *vec) const; + + + /** \brief + * implements Element::clone + */ + inline Element *clone() { return NEW Line(mesh); }; + + /** \brief + * implements Element::getSideOfChild() + */ + virtual int getSideOfChild(int child, int side, int ) const { + FUNCNAME("Line::getSideOfChild()"); + TEST_EXIT(child==0 || child==1)("child must be in (0,1)\n"); + TEST_EXIT(side >= 0 && side <= 1)("side must be between 0 and 1\n"); + return sideOfChild[child][side]; + }; + + /** \brief + * implements Element::getVertexOfParent() + */ + virtual int getVertexOfParent(int child, int side, int) const { + FUNCNAME("Line::getVertexOfParent()"); + TEST_EXIT(child==0 || child==1)("child must be in (0,1)\n"); + TEST_EXIT(side >= 0 && side <= 2)("side must be between 0 and 1\n"); + return vertexOfParent[child][side]; + }; + + + /** \brief + * implements Element::hasSide + */ + inline bool hasSide(Element* /*sideElem*/) const { + ERROR_EXIT("a Line has no side elements!\n"); + return false; + }; + + /** \brief + * implements Element::isLine. Returns true because this element is a Line + */ + inline bool isLine() const { return true; }; + + /** \brief + * implements Element::isTriangle. Returns false because this element is a + * Line + */ + inline bool isTriangle() const { return false; }; + + /** \brief + * implements Element::isTetrahedron. Returns false because this element is + * a Line + */ + inline bool isTetrahedron() const { return false; }; + + // ===== Serializable implementation ===== + + ::std::string getTypeName() const { return "Line"; }; + +protected: + /** \brief + * vertexOfEdge[i][j] is the local number of the j-th vertex of the i-th + * edge of this element. + */ + static const int vertexOfEdge[1][2]; + + static const int sideOfChild[2][2]; + static const int vertexOfParent[2][2]; +}; + +} + +#endif // AMDIS_LINE_H diff --git a/AMDiS/src/MacroElement.cc b/AMDiS/src/MacroElement.cc new file mode 100644 index 0000000000000000000000000000000000000000..b55b65effce43531d571099a01cf3da1e7da35b7 --- /dev/null +++ b/AMDiS/src/MacroElement.cc @@ -0,0 +1,160 @@ +#include "MacroElement.h" +#include "Boundary.h" +#include "FiniteElemSpace.h" +#include "Mesh.h" +#include <string> +#include "FixVec.h" +#include "FixVecConvert.h" +#include <map> + +namespace AMDiS { + + MacroElement::MacroElement(int dim) + : element(NULL), + coord(dim, NO_INIT), + boundary(dim, DEFAULT_VALUE, INTERIOR), + projection(dim, NO_INIT), + neighbour(dim, NO_INIT), + oppVertex(dim, NO_INIT), + index(-1), + elType(0), + deserializedNeighbourIndices_(NULL) + { + neighbour.set(NULL); + projection.set(NULL); + } + + MacroElement::~MacroElement() + { + if(element) DELETE element; + }; + + void MacroElement::serialize(::std::ostream &out) + { + // write element-tree + out << element->getTypeName() << ::std::endl; + element->serialize(out); + + // write coords + int i, size = coord.getSize(); + out.write(reinterpret_cast<const char*>(&size), sizeof(int)); + for(i = 0; i < size; i++) { + coord[i].serialize(out); + } + + // write boundary + boundary.serialize(out); + + // write projection + size = projection.getSize(); + out.write(reinterpret_cast<const char*>(&size), sizeof(int)); + for(i = 0; i < size; i++) { + int id = projection[i] ? projection[i]->getID() : -1; + out.write(reinterpret_cast<const char*>(&id), sizeof(int)); + } + + // write neighbour + size = neighbour.getSize(); + out.write(reinterpret_cast<const char*>(&size), sizeof(int)); + for(i = 0; i < size; i++) { + int index = neighbour[i] ? neighbour[i]->getIndex() : -1; + out.write(reinterpret_cast<const char*>(&index), sizeof(int)); + } + + // write oppVertex + oppVertex.serialize(out); + + // write index + out.write(reinterpret_cast<const char*>(&index), sizeof(int)); + + // write elType + out.write(reinterpret_cast<const char*>(&elType), sizeof(unsigned char)); + } + + void MacroElement::deserialize(::std::istream &in) + { + // read element-tree + ::std::string typeName; + in >> typeName; + in.get(); + + if(element) { + TEST_EXIT(typeName == element->getTypeName())("wrong element type name\n"); + } else { + if(typeName == "Line") element = NEW Line(NULL); + if(typeName == "Triangle") element = NEW Triangle(NULL); + if(typeName == "Tetrahedron") element = NEW Tetrahedron(NULL); + } + + element->deserialize(in); + + // read coords + int i, size; + in.read(reinterpret_cast<char*>(&size), sizeof(int)); + if(coord.getSize()) { + TEST_EXIT(coord.getSize() == size)("invalid size\n"); + } else { + coord.initSize(size); + } + for(i = 0; i < size; i++) { + coord[i].deserialize(in); + } + + // read boundary + boundary.deserialize(in); + + // read projection + in.read(reinterpret_cast<char*>(&size), sizeof(int)); + + if(projection.getSize()) { + TEST_EXIT(projection.getSize() == size)("invalid size\n"); + } else { + projection.initSize(size); + } + + for(i = 0; i < size; i++) { + int id; + in.read(reinterpret_cast<char*>(&id), sizeof(int)); + projection[i] = (id != -1) ? Projection::getProjection(id) : NULL; + } + + // read neighbour indices + in.read(reinterpret_cast<char*>(&size), sizeof(int)); + + TEST_EXIT(deserializedNeighbourIndices_) + ("neighbour indices for desrializing not set\n"); + + deserializedNeighbourIndices_->resize(size); + + if(neighbour.getSize()) { + TEST_EXIT(neighbour.getSize() == size)("invalid size\n"); + } else { + neighbour.initSize(size); + } + + for(i = 0; i < size; i++) { + int index; + in.read(reinterpret_cast<char*>(&index), sizeof(int)); + + // neighbour[i] = reinterpret_cast<MacroElement*>(index); + // // attention: the neighbour INDEX is stored in the neighbour vector. + // // After all macro elements are read in, the indices must be replaced + // // by the corresponding pointers. + + (*deserializedNeighbourIndices_)[i] = index; + } + + deserializedNeighbourIndices_ = NULL; + + // read oppVertex + oppVertex.deserialize(in); + + // write index + in.read(reinterpret_cast<char*>(&index), sizeof(int)); + + + // write elType + in.read(reinterpret_cast<char*>(&elType), sizeof(unsigned char)); + } + +} diff --git a/AMDiS/src/MacroElement.h b/AMDiS/src/MacroElement.h new file mode 100644 index 0000000000000000000000000000000000000000..5fd6e7ac6df32ed33bc15a38c2d7c72d37517b5e --- /dev/null +++ b/AMDiS/src/MacroElement.h @@ -0,0 +1,283 @@ +// ============================================================================ +// == == +// == AMDiS - Adaptive multidimensional simulations == +// == == +// ============================================================================ +// == == +// == crystal growth group == +// == == +// == Stiftung caesar == +// == Ludwig-Erhard-Allee 2 == +// == 53175 Bonn == +// == germany == +// == == +// ============================================================================ +// == == +// == http://www.caesar.de/cg/AMDiS == +// == == +// ============================================================================ + +/** \file MacroElement.h */ + +#ifndef AMDIS_MACROELEMENT_H +#define AMDIS_MACROELEMENT_H + +#include <deque> +#include <stdio.h> +#include "Boundary.h" +#include "Global.h" +#include "MemoryManager.h" +#include "Projection.h" +#include "FixVec.h" +#include "Serializable.h" + +namespace AMDiS { + + class Element; + class ElInfo; + class Mesh; + + template<typename T> class WorldVector; + template<typename T> class DimVec; + + // ============================================================================ + // ===== class MacroElement =================================================== + // ============================================================================ + + /** \ingroup Triangulation + * \brief + * MacroElements form the macro triangulation of a Mesh. In a MacroElement + * geometrical information are stored, which are used in mesh traversal, + * to calculate the desired information and fill it in an ElInfo object. + */ + class MacroElement : public Serializable + { + public: + MEMORY_MANAGED(MacroElement); + + /** \brief + * Creates a new MacroElement. The mesh is needed only to get the dimension + */ + MacroElement(int dim); + + /** \brief + * Destructor. + */ + virtual ~MacroElement(); + + // ===== getting methods ====================================================== + + /** \name getting methods + * \{ + */ + + /** \brief + * Returns \ref index. + */ + inline int getIndex() const + { + return index; + }; + + /** \brief + * Returns ref projection[i]. + */ + inline Projection *getProjection(int i) const + { + return projection[i]; + }; + + /** \brief + * Returns \ref el + */ + inline Element* getElement() const + { + return element; + }; + + /** \brief + * Returns the i-th neighbour of this MacroElement \ref neighbour[i] + */ + inline MacroElement* getNeighbour(int i) const + { + return neighbour[i]; + }; + + /** \brief + * Returns the i-th opp-vertex of this MacroElement \ref oppVertex[i] + */ + inline char getOppVertex(int i) const + { + return oppVertex[i]; + }; + + /** \brief + * Returns \ref coord[i] + */ + inline WorldVector<double>& getCoord(int i) + { + return coord[i]; + }; + + /** \brief + * Returns \ref coord + */ + inline FixVec<WorldVector<double>, VERTEX>& getCoord() + { + return coord; + }; + + /** \brief + * Returns \ref boundary[i] + */ + inline BoundaryType getBoundary(int i) const + { + return boundary[i]; + }; + + /** \brief + * Returns \ref elType + */ + inline unsigned char getElType() const + { + return elType; + }; + + /** \} */ + + // ===== setting methods ====================================================== + + /** \name setting methods + * \{ + */ + + /** \brief + * Sets \ref index + */ + inline void setIndex(int n) + { + index = n ; + }; + + /** \brief + * Sets \ref element if not yet set. + */ + inline void setElement(Element* element_) + { + if (!element) element=element_; + else if ((element!=element_)) ERROR("Trying to change element in MacroElement\n"); + }; + + /** \brief + * Sets \ref elType + */ + inline void setElType(unsigned char typ) + { + elType=typ; + }; + + + /** \brief + * Sets \ref projection[i] = p. + */ + inline void setProjection(int i, Projection *p) + { + projection[i] = p; + }; + + /** \brief + * Sets the i-th Neighbour to n + */ + inline void setNeighbour(int i, MacroElement *n) + { + neighbour[i] = n; + }; + + /** \brief + * Sets the i-th opp vertex to c + */ + inline void setOppVertex(int i, char c) + { + oppVertex[i]=c; + }; + + /** \brief + * Sets \ref boundary[i] to b + */ + inline void setBoundary(int i, BoundaryType b) + { + boundary[i] = b; + }; + + inline void setCoord(int i, const WorldVector<double> &c) + { + coord[i] = c; + }; + + /** \} */ + + // ===== Serializable implementation ===== + + void serialize(::std::ostream &out); + + void deserialize(::std::istream &in); + + inline void writeNeighboursTo(::std::vector<int> *indices) { + deserializedNeighbourIndices_ = indices; + }; + + protected: + /** \brief + * Element of this MacroElement. + */ + Element *element; + + /** \brief + * Coordinates of the vertices. + */ + FixVec<WorldVector<double>, VERTEX> coord; + + /** \brief + * Boundary type of each boundary part (face/edge/vertex) + */ + FixVec<BoundaryType, BOUNDARY> boundary; + + /** \brief + * Boundary projection to curved boundaries or element projections. + */ + FixVec<Projection*, PROJECTION> projection; + + /** \brief + * Pointers to all neighbours of this MacroElement + */ + FixVec<MacroElement*, NEIGH> neighbour; + + /** \brief + * opp vertices of this MacroElement + */ + FixVec<char, NEIGH> oppVertex; + + /** \brief + * index of this MacroElement + */ + int index; + + /** \brief + * Element type of the MacroElement + */ + unsigned char elType; + + ::std::vector<int> *deserializedNeighbourIndices_; + + // friend classes + friend class MacroInfo; + friend class MacroReader; + friend class ElInfo1d; + friend class ElInfo2d; + friend class ElInfo3d; + }; + +} + + +#endif // AMDIS_MACROELEMENT_H diff --git a/AMDiS/src/MacroReader.cc b/AMDiS/src/MacroReader.cc new file mode 100644 index 0000000000000000000000000000000000000000..ba9b28f7136515747135d8c0cfe0bfd20c27bc78 --- /dev/null +++ b/AMDiS/src/MacroReader.cc @@ -0,0 +1,2209 @@ +#include "MacroReader.h" +#include "MacroWriter.h" +#include "MacroElement.h" +#include "Boundary.h" +#include "FiniteElemSpace.h" +#include "Mesh.h" +#include <string> +#include "FixVec.h" +#include "FixVecConvert.h" +#include "PeriodicMap.h" +#include "ElInfo.h" +#include "Parameters.h" +#include "DOFIterator.h" +#include "SurfaceRegion_ED.h" +#include "ElementRegion_ED.h" +#include "LeafData.h" +#include "VertexVector.h" +#include <map> +#include <iostream> +#include <fstream> + +namespace AMDiS { + + MacroInfo* MacroReader::readMacro(const char *filename, + Mesh* mesh, + const char *periodicFile, + int check) + { + FUNCNAME("Mesh::readMacro()"); + + ::std::deque<MacroElement*>::iterator mel; + MacroElement *neigh; + WorldVector<double> *coords; + int **melVertex; + DegreeOfFreedom **dof; + int i, j, k; + WorldVector<double> x_min, x_max; + MacroInfo *macroInfo; + + TEST_EXIT(filename)("no file specified; filename NULL pointer\n"); + + macroInfo = NEW MacroInfo(); + macroInfo->readAMDiSMacro(filename, mesh); + + mel = macroInfo->mel.begin(); + melVertex = macroInfo->mel_vertex; + coords = macroInfo->coords; + dof = macroInfo->dof; + + // === read periodic data ================================= + if (periodicFile&&(strcmp(periodicFile, "") != 0)) { + WARNING("periodic boundaries may lead to errors in small meshes if element neighbours not set\n"); + + FILE *file = fopen(periodicFile, "r"); + TEST_EXIT(file)("can't open file %s\n", periodicFile); + + int n; + int dim = mesh->getDim(); + + int el1, el2; + int *verticesEl1 = GET_MEMORY(int, dim); + int *verticesEl2 = GET_MEMORY(int, dim); + int mode = -1; // 0: drop dofs, 1: associate dofs + BoundaryType boundaryType; + + fscanf(file, "%*s %d", &n); + + fscanf(file, "%*s %*s %*s %*s %*s %*s %*s %*s %*s %*s %*s"); + + PeriodicMap periodicMap; + + for (i = 0; i < n; i++) { + ::std::map<int, int> vertexMapEl1; + ::std::map<int, int> vertexMapEl2; + + TEST_EXIT(fscanf(file, "%d", &mode) == 1)("mode?\n"); + + TEST_EXIT(fscanf(file, "%d", &boundaryType) == 1)("boundaryType?\n"); + + TEST_EXIT(fscanf(file, "%d", &el1) == 1)("el1?\n"); + for(j = 0; j < dim; j++) { + TEST_EXIT(fscanf(file, "%d", &verticesEl1[j]) == 1)("vertEl1[%d]\n", j); + } + TEST_EXIT(fscanf(file, "%d", &el2) == 1)("el2?\n"); + for(j = 0; j < dim; j++) { + TEST_EXIT(fscanf(file, "%d", &verticesEl2[j]) == 1)("vertEl2[%d]\n", j); + } + for(j = 0; j < dim; j++) { + if(mode == 0) { + periodicMap.setEntry(melVertex[el1][verticesEl1[j]], + melVertex[el2][verticesEl2[j]]); + } + vertexMapEl1[verticesEl1[j]] = verticesEl2[j]; + vertexMapEl2[verticesEl2[j]] = verticesEl1[j]; + } + + // calculate sides of periodic vertices + int sideEl1 = 0, sideEl2 = 0; + if(dim == 1) { + sideEl1 = verticesEl1[0]; + sideEl2 = verticesEl2[0]; + } else { + for(j = 0; j < dim + 1; j++) { + sideEl1 += j; + sideEl2 += j; + } + for(j = 0; j < dim; j++) { + sideEl1 -= verticesEl1[j]; + sideEl2 -= verticesEl2[j]; + } + } + + // create periodic info + DimVec<WorldVector<double> > periodicCoordsEl1(dim-1, NO_INIT); + DimVec<WorldVector<double> > periodicCoordsEl2(dim-1, NO_INIT); + + Element *element1 = const_cast<Element*>((*(mel+el1))->getElement()); + Element *element2 = const_cast<Element*>((*(mel+el2))->getElement()); + + // for all vertices of this side + for (j = 0; j < dim; j++) { + periodicCoordsEl1[element1->getPositionOfVertex(sideEl1, verticesEl1[j])] = + coords[melVertex[el2][vertexMapEl1[verticesEl1[j]]]]; + periodicCoordsEl2[element2->getPositionOfVertex(sideEl2, verticesEl2[j])] = + coords[melVertex[el1][vertexMapEl2[verticesEl2[j]]]]; + } + + // decorate leaf data + ElementData *ld1 = element1->getElementData(); + ElementData *ld2 = element2->getElementData(); + + LeafDataPeriodic *ldp1 = dynamic_cast<LeafDataPeriodic*>(ld1->getElementData(PERIODIC)); + LeafDataPeriodic *ldp2 = dynamic_cast<LeafDataPeriodic*>(ld2->getElementData(PERIODIC)); + + if (!ldp1) { + ldp1 = NEW LeafDataPeriodic(ld1); + element1->setElementData(ldp1); + } + + if (!ldp2) { + ldp2 = NEW LeafDataPeriodic(ld2); + element2->setElementData(ldp2); + } + + // DimVec<DegreeOfFreedom> periodicDOFsEl1(dim-1, NO_INIT); + // DimVec<DegreeOfFreedom> periodicDOFsEl2(dim-1, NO_INIT); + + // for(j = 0; j < dim; j++) { + // periodicDOFsEl1[element1->getPositionOfVertex(sideEl1, verticesEl1[j])] = + // melVertex[el2][vertexMapEl1[verticesEl1[j]]]; + // periodicDOFsEl2[element2->getPositionOfVertex(sideEl2, verticesEl2[j])] = + // melVertex[el1][vertexMapEl2[verticesEl2[j]]]; + // } + + ldp1->addPeriodicInfo(mode, + boundaryType, + sideEl1, + &periodicCoordsEl1); + + ldp2->addPeriodicInfo(mode, + boundaryType, + sideEl2, + &periodicCoordsEl2); + + if (mode != 0) { + VertexVector *associated = mesh->periodicAssociations[boundaryType]; + if (!associated) { + associated = NEW VertexVector(mesh->getVertexAdmin(), "vertex vector"); + mesh->periodicAssociations[boundaryType] = associated; + VertexVector::Iterator it(associated, ALL_DOFS); + for (it.reset2(); !it.end(); ++it) { + *it = it.getDOFIndex(); + } + } + + for(j = 0; j < dim; j++) { + (*associated)[melVertex[el1][verticesEl1[j]]] = + melVertex[el2][vertexMapEl1[verticesEl1[j]]]; + (*associated)[melVertex[el2][verticesEl2[j]]] = + melVertex[el1][vertexMapEl2[verticesEl2[j]]]; + } + } + } + + FREE_MEMORY(verticesEl1, int, dim); + FREE_MEMORY(verticesEl2, int, dim); + + // change periodic vertex dofs + for (i = 0; i < mesh->getNumberOfVertices(); i++) { + if (periodicMap.getEntry(i) != -1) { + mesh->freeDOF(dof[i], VERTEX); + dof[i] = dof[periodicMap.getEntry(i)]; + + ::std::map<BoundaryType, VertexVector*>::iterator assoc; + ::std::map<BoundaryType, VertexVector*>::iterator assocEnd = + mesh->periodicAssociations.end(); + for(assoc = mesh->periodicAssociations.begin(); + assoc != assocEnd; + ++assoc) + { + DegreeOfFreedom a = (*(assoc->second))[i]; + if (a != i) { + (*(assoc->second))[i] = i; + (*(assoc->second))[a] = periodicMap.getEntry(i); + } + } + } + } + + ::std::map<BoundaryType, VertexVector*>::iterator assoc; + ::std::map<BoundaryType, VertexVector*>::iterator assocEnd = + mesh->periodicAssociations.end(); + for (assoc = mesh->periodicAssociations.begin(); + assoc != assocEnd; + ++assoc) + { + for( i = 0; i < mesh->getNumberOfVertices(); i++) { + if (i != (*(assoc->second))[i]) + MSG("association %d: vertex %d -> vertex %d\n", + assoc->first, + i, (*(assoc->second))[i]); + } + } + for (i = 0; i < mesh->getNumberOfVertices(); i++) { + if (periodicMap.getEntry(i) != -1) { + MSG("identification : vertex %d is now vertex %d\n", i, periodicMap.getEntry(i)); + } + } + } + // ========================================================= + + for (i = 0; i < mesh->getNumberOfMacros(); i++) + { + for (k = 0; k < mesh->getGeo(VERTEX); k++) + { + (*(mel+i))->setCoord(k, coords[melVertex[i][k]]); + const_cast<Element*>((*(mel+i))->getElement())-> + setDOF(k,dof[melVertex[i][k]]); + } + } + + if (!macroInfo->neigh_set) + { + TEST_EXIT(!periodicFile) + ("periodic boundary condition => element neighbours must be set\n"); + computeNeighbours(mesh); + } + else + { + /****************************************************************************/ + /* fill MEL oppVertex values when reading neighbour information form file */ + /****************************************************************************/ + + for (i = 0; i < mesh->getNumberOfMacros(); i++) + { + for (k = 0; k < mesh->getGeo(NEIGH); k++) + { + if ((neigh = const_cast<MacroElement*>(mel[i]->getNeighbour(k)))) + { + for (j = 0; j < mesh->getGeo(NEIGH); j++) + if (neigh->getNeighbour(j) == *(mel+i)) break; + + TEST_EXIT(j < mesh->getGeo(NEIGH)) + ("el %d no neighbour of neighbour %d\n", + mel[i]->getIndex(), neigh->getIndex()); + mel[i]->setOppVertex(k,j); + } + else + { + mel[i]->setOppVertex(k,-1); + } + } + } + } + + if (!macroInfo->bound_set) { + macroInfo->dirichletBoundary(); + } + + if(mesh->getDim() > 1) + boundaryDOFs(mesh); + + // initial boundary projections + //if(dim > 1) { + int numFaces = mesh->getGeo(FACE); + int dim = mesh->getDim(); + mel = mesh->firstMacroElement(); + for(i = 0; i < mesh->getNumberOfLeaves(); i++) { + MacroElement *macroEl = *(mel+i); + Projection *projector = macroEl->getProjection(0); + if(projector && projector->getType() == VOLUME_PROJECTION) { + for(j = 0; j <= dim; j++) { + projector->project(macroEl->getCoord(j)); + } + } else { + for(j = 0; j < mesh->getGeo(EDGE); j++) { + projector = macroEl->getProjection(numFaces + j); + if(projector) { + int vertex0 = Global::getReferenceElement(dim)->getVertexOfEdge(j, 0); + int vertex1 = Global::getReferenceElement(dim)->getVertexOfEdge(j, 1); + projector->project(macroEl->getCoord(vertex0)); + projector->project(macroEl->getCoord(vertex1)); + } + } + } + } + //} + + macroInfo->fillBoundaryInfo(mesh); + + if (mesh->getNumberOfDOFs(CENTER)) { + for (i = 0; i < mesh->getNumberOfMacros(); i++) + { + const_cast<Element*>(mel[i]->getElement())-> + setDOF(mesh->getNode(CENTER),mesh->getDOF(CENTER)); + } + } + + /****************************************************************************/ + /* domain size */ + /****************************************************************************/ + + for (j = 0; j < Global::getGeo(WORLD); j++) + { + x_min[j] = 1.E30; + x_max[j] = -1.E30; + } + + for (i = 0; i < mesh->getNumberOfVertices(); i++) + for (j = 0; j < Global::getGeo(WORLD); j++) + { + x_min[j] = ::std::min(x_min[j], coords[i][j]); + x_max[j] = ::std::max(x_max[j], coords[i][j]); + } + + for (j = 0; j < Global::getGeo(WORLD); j++) + mesh->setDiameter(j, x_max[j] - x_min[j]); + + if (check) { + checkMesh(mesh); + + if (mesh->getDim() > 1) { + char filenew[128]; + strncpy(filenew, filename, 128); filenew[127] = 0; + strncat(filenew, ".new", 128); filenew[127] = 0; + macroTest(mesh, filenew); + } + } + + return(macroInfo); + } + + /****************************************************************************/ + /* fill macro info structure and some pointers in mesh ... */ + /****************************************************************************/ + + void MacroInfo::fill(Mesh *pmesh, int ne, int nv) + { + FUNCNAME("MacroInfo::fill"); + int i; + int dim=pmesh->getDim(); + + TEST_EXIT(mesh = pmesh)("no mesh\n"); + + mesh->setNumberOfElements(ne); + mesh->setNumberOfLeaves(ne); + mesh->setNumberOfVertices(nv); + + + for(i = 0; i < ne; i++) { + MacroElement *newMacro = NEW MacroElement(mesh->getDim()); + mel.push_back(newMacro); + mesh->addMacroElement(mel[i]); + } + + dof = GET_MEMORY(DegreeOfFreedom*, nv); + + coords = NEW WorldVector<double>[nv]; + + mel_vertex = GET_MEMORY(int*, ne); + for (i = 0; i < ne; i++) { + mel_vertex[i]=GET_MEMORY(int, mesh->getGeo(VERTEX)); + } + + for (i = 0; i < nv; i++) + dof[i] = mesh->getDOF(VERTEX); + + for (i = 0; i < ne; i++) { + mel[i]->element = mesh->createNewElement(); + (mel)[i]->index = i; + + if (dim == 3) { + (mel)[i]->elType = 0; + } + } + neigh_set = false; + bound_set = false; + + return; + } + + void MacroInfo::clear(int ne, int nv) + { + for (int i = 0; i < mesh->getNumberOfMacros(); i++) + FREE_MEMORY(mel_vertex[i], int, mesh->getGeo(VERTEX)); + + FREE_MEMORY(mel_vertex, int*, ne); + + coords = NULL; /* must no be freed!!! still used in the mesh!!! */ + mesh = NULL; + neigh_set = false; + } + + /****************************************************************************/ + /****************************************************************************/ + /* tool for reading macro triangulations in ALBERT-format */ + /****************************************************************************/ + /****************************************************************************/ + + /****************************************************************************/ + /* read_indices() reads dim+1 indices from file into id[0-dim], */ + /* returns true if dim+1 inputs arguments could be read successfully by */ + /* fscanf(), else false */ + /****************************************************************************/ + + int MacroInfo::read_indices(FILE *file, DimVec<int> &id) + { + int dim = mesh->getDim(); + + for (int i = 0; i <= dim; i++) { + if (fscanf(file, "%d", &id[i]) != 1) + return(false); + } + + return(true); + } + +#define N_KEYS 14 +#define N_MIN_KEYS 7 + static const char *keys[N_KEYS] = { + "DIM", // 0 + "DIM_OF_WORLD", // 1 + "number of vertices", // 2 + "number of elements", // 3 + "vertex coordinates", // 4 + "element vertices", // 5 + "element boundaries", // 6 + "element neighbours", // 7 + "element type", // 8 + "projections", // 9 + "element region", // 10 + "surface region", // 11 + "mesh name", // 12 + "time" // 13 + }; + + static int get_key_no(const char *key) + { + int i; + + for (i = 0; i < N_KEYS; i++) + if (!strcmp(keys[i], key)) return(i); + + return(-1); + } + +#include <ctype.h> + + static const char *read_key(const char *line) + { + static char key[100]; + char *k = key; + + while (isspace(*line)) + line++; + while ((*k++ = *line++) != ':'); + *--k = '\0'; + + return(const_cast<const char *>( key)); + } + + /****************************************************************************/ + /* read_albert_macro(): */ + /* read macro triangulation from ascii file in ALBERT format */ + /* fills macro_info structure */ + /* called by read_macro(), fills missing information */ + /****************************************************************************/ + + + void MacroInfo::readAMDiSMacro(const char *filename, Mesh* mesh) + { + FUNCNAME("MacroInfo::readAMDiSMacro"); + FILE *file; + int dim; + int dow, nv, ne, i, j, k; + double dbl; + char name[128], line[256]; + int line_no, n_keys, i_key, sort_key[N_KEYS], nv_key, ne_key; + int key_def[N_KEYS] = {0,0,0,0,0,0,0,0,0,0,0,0}; + const char *key; + DimVec<int> *ind = NULL; + + TEST_EXIT(filename)("no file specified; filename NULL pointer\n"); + //TEST_EXIT(pmesh)("no mesh specified; mesh NULL pointer\n"); + TEST_EXIT(strlen(filename) < static_cast<unsigned int>(127)) + ("can only handle filenames up to 127 characters\n"); + + TEST_EXIT((file=fopen(filename,"r")))("cannot open file %s\n",filename); + strncpy(name, filename, 127); + + /****************************************************************************/ + /* looking for all keys in the macro file ... */ + /****************************************************************************/ + + line_no = n_keys = 0; + while (fgets(line, 255, file)) { + line_no++; + if (!strchr(line, ':')) continue; + key = read_key(line); + i_key = get_key_no(key); + TEST_EXIT(i_key >= 0) + ("macro file %s must not contain key %s on line %d\n", + name, key, line_no); + TEST_EXIT(!key_def[i_key]) + ("key %s defined second time on line %d in file %s\n"); + + sort_key[n_keys++] = i_key; + key_def[i_key] = true; + } + + fclose(file); + for (i_key = 0; i_key < N_MIN_KEYS; i_key++) { + for (j = 0; j < n_keys; j++) + if (sort_key[j] == i_key) break; + TEST_EXIT(j < n_keys)("You do not have specified data for %s in %s\n", + keys[i_key], name); + + for (j = 0; j < n_keys; j++) + if (sort_key[j] == 2) break; + nv_key = j; + for (j = 0; j < n_keys; j++) + if (sort_key[j] == 3) break; + ne_key = j; + + switch(i_key) { + case 0: + case 1: + TEST_EXIT(sort_key[i_key] < 2) + ("You have to specify DIM or mesh->getGeo(WORLD) before all other data\n"); + break; + case 4: + TEST_EXIT(nv_key < i_key) + ("Before reading data for %s, you have to specify the %s in file\n", + keys[4], keys[2], name); + break; + case 5: + TEST_EXIT(nv_key < i_key && ne_key < i_key) + ("Before reading data for %s, you have to specify the %s and %s in file %s\n", + keys[5], keys[3], keys[2], name); + case 6: + case 7: + case 8: + TEST_EXIT(ne_key < i_key) + ("Before reading data for %s, you have to specify the %s in file %s\n", + keys[i_key], keys[3], name); + } + } + + for (i_key = 0; i_key < N_KEYS; i_key++) + key_def[i_key] = false; + + /****************************************************************************/ + /* and now, reading data ... */ + /****************************************************************************/ + + TEST_EXIT((file=fopen(name,"r")))("cannot open file %s\n",name); + + for (i_key = 0; i_key < n_keys; i_key++) { + + switch(sort_key[i_key]) { + case 0: + TEST_EXIT(fscanf(file, "%*s %d", &dim) == 1) + ("cannot read DIM correctly in file %s\n", name); + + ind = NEW DimVec<int>(dim, NO_INIT); + + key_def[0] = true; + break; + case 1: + TEST_EXIT(fscanf(file, "%*s %d", &dow) == 1) + ("cannot read Global::getGeo(WORLD) correctly in file %s\n", name); + TEST_EXIT(dow == Global::getGeo(WORLD)) + ("dimension of world = %d != Global::getGeo(WORLD) = %d\n", + dow, Global::getGeo(WORLD)); + + key_def[1] = true; + break; + case 2: + TEST_EXIT(fscanf(file, "%*s %*s %*s %d", &nv) == 1) + ("cannot read number of vertices correctly in file %s\n", name); + TEST_EXIT(nv > 0) + ("number of vertices = %d must be bigger than 0\n", nv); + + key_def[2] = true; + if (key_def[3]) + fill(mesh, ne, nv); + break; + case 3: + TEST_EXIT(fscanf(file, "%*s %*s %*s %d", &ne) == 1) + ("cannot read number of elements correctly in file %s\n", name); + TEST_EXIT(ne > 0) + ("number of elements = %d must be bigger than 0\n", ne); + + key_def[3] = true; + if (key_def[2]) + fill(mesh, ne, nv); + break; + case 4: + fscanf(file, "%*s %*s"); + for (i = 0; i < nv; i++) + { + for (j = 0; j <Global::getGeo(WORLD) ; j++) + { + TEST_EXIT(fscanf(file, "%lf", &dbl) == 1) + ("error while reading coordinates, check file %s\n", name); + coords[i][j] = dbl; + } + } + key_def[4] = true; + break; + case 5: + fscanf(file, "%*s %*s"); + /****************************************************************************/ + /* global number of vertices on a single element */ + /****************************************************************************/ + + for (i = 0; i < ne; i++) { + TEST_EXIT(read_indices(file, *ind)) + ("cannot read vertex indices of element %d in file %s\n", i, name); + + for (k = 0; k < mesh->getGeo(VERTEX); k++) + mel_vertex[i][k] = (*ind)[k]; + } + + key_def[5] = true; + break; + case 6: + fscanf(file, "%*s %*s"); + /****************************************************************************/ + /* MEL boundary pointers */ + /****************************************************************************/ + + for (i = 0; i < ne; i++) { + // boundary information of ith element + + TEST_EXIT(read_indices(file, *ind)) + ("cannot read boundary type of element %d in file %s\n", i, name); + + // fill boundary of macro-element + MacroReader::fillMelBoundary(mesh, + mel[i], + VecConv<int,NEIGH,PARTS>::convertVec((*ind), mesh)); + } + + this->fillBoundaryInfo(mesh); + + bound_set = true; + key_def[6] = true; + break; + case 7: + fscanf(file, "%*s %*s"); + /****************************************************************************/ + /* fill MEL neighbour pointers: */ + /* if they are specified in the file: read them from file, */ + /* else init them by a call of fill_mel_neighbour() */ + /****************************************************************************/ + neigh_set = true; + for (i = 0; i < ne; i++) { + // neighbour information about ith element + + if (read_indices(file, *ind)) + MacroReader::fillMelNeigh(mel[i], mel, + VecConv<int,NEIGH,PARTS>::convertVec((*ind), + mesh)); + else { + neigh_set = false; /* setting of neighbours fails :-( */ + break; + } + } + + key_def[7] = true; + break; + case 8: + fscanf(file, "%*s %*s"); + /****************************************************************************/ + /* MEL elType */ + /****************************************************************************/ + + if (dim == 2 || dim == 1) + ERROR("there is no element type in 2d and 2d; ignoring data for elType\n"); + + for (i = 0; i < ne; i++) { + TEST_EXIT(fscanf(file, "%d", &j) == 1) + ("cannot read elType of element %d in file %s\n", + i, name); + if (dim == 3) { + (mel)[i]->elType = j; + } + } + + key_def[8] = true; + break; + case 9: + { + fscanf(file, "%*s"); + + int numFaces = mesh->getGeo(FACE); + int numEdgesAtBoundary = 0; + + for(k = 1; k < dim; k++) { + numEdgesAtBoundary += k; + } + + for (i = 0; i < ne; i++) { + TEST_EXIT(read_indices(file, *ind)) + ("cannot read boundary projector of element %d in file %s\n", i, name); + + Projection *projector = Projection::getProjection((*ind)[0]); + + if(projector && projector->getType() == VOLUME_PROJECTION) { + mel[i]->setProjection(0, projector); + } else { // boundary projection + for(j = 0; j < mesh->getGeo(NEIGH); j++) { + projector = Projection::getProjection((*ind)[j]); + if(projector) { + mel[i]->setProjection(j, projector); + if(dim > 2) { + for(k = 0; k < numEdgesAtBoundary; k++) { + int edgeNr = Global::getReferenceElement(dim)->getEdgeOfFace(j, k); + mel[i]->setProjection(numFaces + edgeNr, projector); + } + } + } + } + } + } + } + key_def[9] = true; + break; + case 10: + fscanf(file, "%*s %*s"); + /****************************************************************************/ + /* MEL regions */ + /****************************************************************************/ + + for (i = 0; i < ne; i++) { + TEST_EXIT(fscanf(file, "%d", &j) == 1) + ("cannot read region of element %d in file %s\n", i, name); + if(j >= 0) { + Element *el = mel[i]->getElement(); + ElementRegion_ED *elementRegion = + NEW ElementRegion_ED(el->getElementData()); + elementRegion->setRegion(j); + el->setElementData(elementRegion); + } + } + key_def[10] = true; + break; + case 11: + fscanf(file, "%*s %*s"); + for (i = 0; i < ne; i++) { + TEST_EXIT(read_indices(file, *ind)) + ("cannot read surface regions of element %d in file %s\n", i, name); + + Element *el = mel[i]->getElement(); + + for(j = 0; j < mesh->getGeo(NEIGH); j++) { + if((*ind)[j] >= 0) { + SurfaceRegion_ED *surfaceRegion = + NEW SurfaceRegion_ED(el->getElementData()); + surfaceRegion->setSide(j); + surfaceRegion->setRegion((*ind)[j]); + el->setElementData(surfaceRegion); + } + } + } + key_def[11] = true; + break; + case 12: + fscanf(file, "%*s %*s %*s"); + break; + case 13: + fscanf(file, "%*s %*s"); + break; + } + } + + fclose(file); + } + + + int macro_type(const char *filename, const char *type) + { + const char *fn, *t; + + if (strlen(filename) <= strlen(type)) + return(false); + + fn = filename; + while (*fn) fn++; + t = type; + while (*t) t++; + + while (t != type && *t == *fn) t--; + + return(t == type); + } + + + /****************************************************************************/ + /* sets the boundary of all edges/faces with no neigbour to a straight */ + /* line/face with Dirichlet boundary type */ + /****************************************************************************/ + + void MacroInfo::dirichletBoundary() + { + int i, k; + + for (i = 0; i < static_cast<int>( mel.size()); i++) { + for (k = 0; k < mesh->getGeo(NEIGH); k++) { + if (mel[i]->neighbour[k]) + mel[i]->boundary[k] = INTERIOR; + else + mel[i]->boundary[k] = DIRICHLET; + } + } + return; + } + + + void MacroInfo::fillBoundaryInfo(Mesh *mesh) + { + int i,j,k, nv = mesh->getNumberOfVertices(); + + ::std::deque<MacroElement*>::iterator melIt; + + BoundaryType *bound = GET_MEMORY(BoundaryType, nv); + + int dim = mesh->getDim(); + + switch(dim) { + case 1: + break; + case 2: + for (i = 0; i < nv; i++) + bound[i] = INTERIOR; + + for (i=0, melIt = mesh->firstMacroElement(); + melIt != mesh->endOfMacroElements(); + ++melIt, ++i) + { + for (j = 0; j < mesh->getGeo(NEIGH); j++) { + if ((*melIt)->getBoundary(j) != INTERIOR) { + if ((*melIt)->getBoundary(j) >= DIRICHLET) { + int j1 = mel_vertex[i][(j+1)%3]; + int j2 = mel_vertex[i][(j+2)%3]; + + bound[j1] = + max(bound[j1], (*melIt)->getBoundary(j)); + bound[j2] = + max(bound[j2], (*melIt)->getBoundary(j)); + } + else if ((*melIt)->getBoundary(j) <= NEUMANN) { + int j1 = mel_vertex[i][(j+1)%3]; + int j2 = mel_vertex[i][(j+2)%3]; + + if (bound[j1] != INTERIOR) + bound[j1] = + max(bound[j1], (*melIt)->getBoundary(j)); + else + bound[j1] = (*melIt)->getBoundary(j); + + if (bound[j2] != INTERIOR) + bound[j2] = + max(bound[j2], (*melIt)->getBoundary(j)); + else + bound[j2] = (*melIt)->getBoundary(j); + } + } + } + } + + for (i=0, melIt = mesh->firstMacroElement(); + melIt != mesh->endOfMacroElements(); + ++melIt, i++) + { + for (j = 0; j < mesh->getGeo(VERTEX); j++) + (*melIt)->setBoundary(3 + j, bound[mel_vertex[i][j]]); + } + break; + case 3: + for (i = 0; i < nv; i++) + bound[i] = INTERIOR; + + for (i=0, melIt = mesh->firstMacroElement(); + melIt != mesh->endOfMacroElements(); + ++melIt, i++) + { + for (j = 0; j < mesh->getGeo(NEIGH); j++) { + for (k = 1; k < 4; k++) + bound[mel_vertex[i][(j+k)%4]] = + ((*melIt)->getBoundary(j) != INTERIOR) ? + newBound((*melIt)->getBoundary(j), + bound[mel_vertex[i][(j+k)%4]]) : + //(*melIt)->getBoundary(j)-> + //newVal(bound[data->mel_vertex[i][(j+k)%4]]) : + bound[mel_vertex[i][(j+k)%4]]; + } + } + + for (i = 0, melIt = mesh->firstMacroElement(); + melIt != mesh->endOfMacroElements(); + ++melIt, i++) + { + for (j = 0; j < mesh->getGeo(VERTEX); j++) + (*melIt)->setBoundary(10 + j, bound[mel_vertex[i][j]]); + } + break; + default: ERROR_EXIT("invalid dim\n"); + } + + FREE_MEMORY(bound, BoundaryType, nv); + } + + void MacroReader::computeNeighbours(Mesh *mesh) + { + FUNCNAME("MacroReader::computeNeighbours"); + int i, j, k, l, m; + int dim = mesh->getDim(); + + FixVec<DegreeOfFreedom*, DIMEN> dof(dim, NO_INIT); + + for (i = 0; i < mesh->getNumberOfLeaves(); i++) + { + for (k = 0; k < mesh->getGeo(NEIGH); k++) + { + mesh->getMacroElement(i)->setOppVertex(k, AMDIS_UNDEFINED); + mesh->getMacroElement(i)->setNeighbour(k, NULL); + } + } + + for (i = 0; i < mesh->getNumberOfLeaves(); i++) + { + // MSG("search neighbour for element %d\n", i); + for (k = 0; k < mesh->getGeo(NEIGH); k++) + { + if(mesh->getMacroElement(i)->getBoundary(k) != INTERIOR) { + mesh->getMacroElement(i)->setNeighbour(k, NULL); + mesh->getMacroElement(i)->setOppVertex(k, -1); + continue; + } + + if (mesh->getMacroElement(i)->getOppVertex(k) == AMDIS_UNDEFINED) + { + if(dim == 1) + dof[0] = const_cast<DegreeOfFreedom*>(mesh->getMacroElement(i)-> + getElement()->getDOF(k)); + else + for (l = 0; l < dim; l++) + dof[l] = const_cast<DegreeOfFreedom*>(mesh->getMacroElement(i)-> + getElement()-> + getDOF((k+l+1)%(dim+1))); + + for (j = i+1; j < mesh->getNumberOfLeaves(); j++) + { + //MacroElement *mel0 = mesh->getMacroElement(i); + //Element *el = const_cast<Element*>(mel0->getElement()); + //m = el->oppVertex(dof); + if ((m = mesh->getMacroElement(j)->getElement()->oppVertex(dof)) != -1) + { + mesh->getMacroElement(i)->setNeighbour(k, mesh->getMacroElement(j)); + mesh->getMacroElement(j)->setNeighbour(m, mesh->getMacroElement(i)); + mesh->getMacroElement(i)->setOppVertex(k, m); + mesh->getMacroElement(j)->setOppVertex(m, k); + break; + } + } + TEST_EXIT(j < mesh->getNumberOfLeaves()) + ("could not find neighbour %d of element %d\n", k, i); + // if(j == mesh->getNumberOfLeaves()) { + // ::std::cout << "neighbour " << k << " not found" << ::std::endl; + // mesh->getMacroElement(i)->setBoundary(k, 1111); + // mesh->getMacroElement(i)->setNeighbour(k, NULL); + // mesh->getMacroElement(i)->setOppVertex(k, -1); + // } + } + } + } + + + return; + } + + + /****************************************************************************/ + /* boundaryDOFs: */ + /* adds dof's at the edges of a given macro triangulation and calculates */ + /* the number of edges */ + /****************************************************************************/ + + void MacroReader::boundaryDOFs(Mesh *mesh) + { + FUNCNAME("Mesh::boundaryDOFs"); + int i, lnode = mesh->getNode(EDGE); + int k, lne = mesh->getNumberOfLeaves(); + int max_n_neigh = 0, n_neigh, ov; + ::std::deque<MacroElement*>::iterator mel; + const MacroElement* neigh; + DegreeOfFreedom *dof; + + mesh->setNumberOfEdges(0); + mesh->setNumberOfFaces(0); + + int dim = mesh->getDim(); + + switch(dim) { + case 2: + for (mel = mesh->firstMacroElement(); mel!=mesh->endOfMacroElements(); mel++) { + + // check for periodic boundary + Element *el = const_cast<Element*>((*mel)->getElement()); + ElementData *ed = el->getElementData(PERIODIC); + + DimVec<bool> periodic(dim, DEFAULT_VALUE, false); + + if(ed) { + ::std::list<LeafDataPeriodic::PeriodicInfo> &periodicInfos = + dynamic_cast<LeafDataPeriodic*>(ed)->getInfoList(); + ::std::list<LeafDataPeriodic::PeriodicInfo>::iterator it; + ::std::list<LeafDataPeriodic::PeriodicInfo>::iterator end = periodicInfos.end(); + for(it = periodicInfos.begin(); it != end; ++it) { + if(it->type != 0) { + periodic[it->elementSide] = true; + } + } + } + + for (i = 0; i < mesh->getGeo(NEIGH); i++) { + if (!(*mel)->getNeighbour(i) || + ((*mel)->getNeighbour(i)->getIndex() < (*mel)->getIndex())) + { + mesh->incrementNumberOfEdges(1);; + if (mesh->getNumberOfDOFs(EDGE)) { + dof = el->setDOF(lnode+i, mesh->getDOF(EDGE)); + + if ((*mel)->getNeighbour(i)) { + Element *neigh = + const_cast<Element*>((*mel)->getNeighbour(i)->getElement()); + if (periodic[i]) { + neigh->setDOF(lnode+(*mel)->getOppVertex(i), mesh->getDOF(EDGE)); + } else { + neigh->setDOF(lnode+(*mel)->getOppVertex(i), dof); + } + } + } + } + } + } + break; + case 3: + lnode = mesh->getNode(FACE); + mel = mesh->firstMacroElement(); + for (i = 0; i < lne; i++) { + + // check for periodic boundary + Element *el = const_cast<Element*>((*(mel+i))->getElement()); + ElementData *ed = el->getElementData(PERIODIC); + + DimVec<bool> periodic(dim, DEFAULT_VALUE, false); + + if(ed) { + ::std::list<LeafDataPeriodic::PeriodicInfo> &periodicInfos = + dynamic_cast<LeafDataPeriodic*>(ed)->getInfoList(); + ::std::list<LeafDataPeriodic::PeriodicInfo>::iterator it; + ::std::list<LeafDataPeriodic::PeriodicInfo>::iterator end = periodicInfos.end(); + for(it = periodicInfos.begin(); it != end; ++it) { + if(it->type != 0) { + periodic[it->elementSide] = true; + } + } + } + + for (k = 0; k < mesh->getGeo(EDGE); k++) { + /*********************************************************************/ + /* check for not counted edges */ + /*********************************************************************/ + n_neigh = 1; + + // static int faceOfEdge[6][2] = { {2, 3}, + // {1, 3}, + // {1, 2}, + // {0, 3}, + // {0, 2}, + // {0, 1} }; + + // bool periodicEdge; + // if(periodic[faceOfEdge[k][0]] || periodic[faceOfEdge[k][1]]) { + // periodicEdge = true; + // } else { + // periodicEdge = false; + // } + + if (newEdge(mesh, (*(mel+i)), k, &n_neigh/*, periodicEdge*/)) { + // if(periodicEdge) { + // mesh->incrementNumberOfEdges(2); + // } else { + mesh->incrementNumberOfEdges(1); + // } + max_n_neigh = max(max_n_neigh, n_neigh); + } + } + + for (k = 0; k < mesh->getGeo(NEIGH); k++) { + neigh = (*(mel+i))->getNeighbour(k); + /*********************************************************************/ + /* face is counted and dof is added by the element with bigger index */ + /*********************************************************************/ + if (neigh && (neigh->getIndex() > (*(mel+i))->getIndex())) continue; + + mesh->incrementNumberOfFaces(1); + + if (mesh->getNumberOfDOFs(FACE)) { + TEST_EXIT(!(*(mel+i))->getElement()->getDOF(lnode+k)) + ("dof %d on element %d already set\n", + lnode+k, (*(mel+i))->getIndex()); + + const_cast<Element*>((*(mel+i))->getElement())->setDOF(lnode+k, + mesh->getDOF(FACE)); + + if (neigh) { + ov = (*(mel+i))->getOppVertex(k); + TEST_EXIT(!neigh->getElement()->getDOF(lnode+ov)) + ("dof %d on neighbour %d already set\n", + lnode+ov, neigh->getIndex()); + + Element *neighEl = + const_cast<Element*>((*(mel+i))->getNeighbour(k)->getElement()); + + if (periodic[k]) { + neighEl->setDOF(lnode+ov, mesh->getDOF(FACE)); + } else { + neighEl->setDOF(lnode+ov, const_cast<int*>((*(mel+i))->getElement()-> + getDOF(lnode+k))); + } + } + } + } + } + break; + default: ERROR_EXIT("invalid dim\n"); + } + + if (3==dim) + mesh->setMaxEdgeNeigh(::std::max(8, 2*max_n_neigh)); + else { + mesh->setMaxEdgeNeigh(dim-1); + } + + return; + } + + /* + testet mesh auf auftretende Zyklen + + wenn Zyklus auftritt: + ordnet Eintraege in MacroElement-Struktur um, so dass kein Zyklus auftritt + erzeugt neue Macro-Datei nameneu mit umgeordnetem Netz + (wenn nameneu=NULL wird keine MAcro-Datei erzeugt) + */ + + void MacroReader::macroTest(Mesh *mesh, const char *nameneu) + { + FUNCNAME("MacroReader::macroTest"); + + int i; + + i = macrotest(mesh); + + if (i >= 0) + { + ERROR("There is a cycle beginning in macro element %d\n", i); + ERROR("Entries in MacroElement structures get reordered\n"); + umb(NULL,mesh, umbVkantMacro); + + if (nameneu) + { + ERROR_EXIT("mesh->feSpace\n"); + //MacroWriter::writeMacro(mesh, nameneu); + MSG("Reordered mesh written to file %s.\n",nameneu); + } + } + return; + } + + /****************************************************************************/ + /* macro_test(): Author: Thomas Kastl (1998) */ + /****************************************************************************/ + /* + testet mesh auf auftretende Zyklen + + wenn mesh zyklenfrei -> -1 + sonst -> globaler Index des Macroelementes bei dem ein Zyklus beginnt + */ + + int MacroReader::macrotest(Mesh *mesh) + { + FUNCNAME("MacroReader::macrotest"); + + int *test; + int i; + int *zykl; + ::std::deque<MacroElement*>::const_iterator macro,mac; + int flg; + ::std::deque<MacroElement*>::const_iterator macrolfd; + int zykstart; + + int dim = mesh->getDim(); + + test=GET_MEMORY(int, mesh->getNumberOfMacros()); + zykl=GET_MEMORY(int, mesh->getNumberOfMacros()); + + for (i=0; i < mesh->getNumberOfMacros(); i++) + test[i]=0; + + zykstart=-1; + + macrolfd=mesh->firstMacroElement(); + + while (macrolfd != mesh->endOfMacroElements()) + { + if (test[(*macrolfd)->getIndex()]==1) + { + macrolfd++; + } + else + { + for (i=0; i < mesh->getNumberOfMacros(); i++) + zykl[i]=0; + + macro=macrolfd; + + flg=2; + do + { + if (zykl[(*macro)->getIndex()] == 1) + { + flg=0; + zykstart=(*macro)->getIndex(); + } + else + { + zykl[(*macro)->getIndex()]=1; + + if (test[(*macro)->getIndex()]==1) + { + flg=1; + } + else if ((*macro)->getNeighbour(dim) == NULL) + { + flg=1; + test[(*macro)->getIndex()]=1; + } + else if ((*macro) == (*macro)->getNeighbour(dim)->getNeighbour(dim)) + { + flg=1; + test[(*macro)->getIndex()]=1; + test[(*macro)->getNeighbour(dim)->getIndex()]=1; + } + else + { + for(mac=mesh->firstMacroElement(); + (*mac)!=(*macro)->getNeighbour(dim); + mac++); + macro=mac; + } + } + + } while(flg == 2); + + if (flg == 1) + { + macrolfd++; + } + else + { + macrolfd=mesh->endOfMacroElements(); + } + } + } + + FREE_MEMORY(zykl, int, mesh->getNumberOfMacros()); + FREE_MEMORY(test, int, mesh->getNumberOfMacros()); + + return zykstart; + } + + // waehlt geeignete Verfeinerungskanten, so dass kein Zyklus auftritt (recumb) + + // ele Integer-Vektor der Dimension Anzahl der Macro-Elemente + // zur Speicherung der neuen Verfeinerungskanten + // (wird nur benoetigt, wenn umbvk=umb_vkant_macrodat) + + // umbvk Fkt. zur Neuordnung der Verfeinerungskanten + // = umb_vkant_macro : + // Eintraege in MacroElement-Struktur und Eintraege in macro->el + // werden tatsaechlich umgeordnet + // -> ALBERT-Routine write_macro kann zum erzeugen einer + // neuen Macro-Datei angewendet werden + // = umb_vkant_macrodat : + // Eintraege werden nicht veraendert, es werden nur die lokalen + // Indices der Kanten, die zu Verfeinerungskanten werden im + // Integer-Vektor ele abgespeichert + // -> print_Macrodat zur Erzeugung einer zyklenfreien neuen + // Macro-Datei kann angewendet werden + + void MacroReader::umb(int *ele, Mesh *mesh, + void (*umbvk)(Mesh*,MacroElement*,int,int*)) + { + FUNCNAME("MacroReader::umb"); + + int *test; + int i; + + test=GET_MEMORY(int, mesh->getNumberOfMacros()); + + for (i=0; i < static_cast<int>(mesh->getNumberOfMacros()); i++) + test[i]=0; + + recumb(mesh, (*mesh->firstMacroElement()), NULL,test,0,0,ele,umbvk); + + FREE_MEMORY(test, int, mesh->getNumberOfMacros()); + } + + bool MacroReader::newEdge(Mesh *mesh, MacroElement *mel, + int mel_edge_no, int *n_neigh) + { + FUNCNAME("MacroElement::newEdge"); + MacroElement *nei; + const DegreeOfFreedom *dof[2]; + DegreeOfFreedom *edge_dof = NULL; + int j, k, opp_v, mel_index, node=0; + BoundaryType lbound = INTERIOR; + Projection *lproject = NULL; + const int max_no_list_el = 100; + BoundaryType *list_bound[100]; + Projection **list_project[100]; + Element *el = const_cast<Element*>(mel->getElement()); + int edge_no = mel_edge_no; + + static int next_el[6][2] = {{3,2},{1,3},{1,2},{0,3},{0,2},{0,1}}; + + int vertices = mesh->getGeo(VERTEX); + + mel_index = mel->getIndex(); + + list_bound[0] = &(mel->boundary[mesh->getGeo(FACE)+edge_no]); + list_project[0] = &(mel->projection[mesh->getGeo(FACE)+edge_no]); + + if (mesh->getNumberOfDOFs(EDGE)) { + node = mesh->getNode(EDGE); + if (el->getDOF(node+edge_no)) { + /****************************************************************************/ + /* edge was counted by another macro element and dof was added on the */ + /* complete patch */ + /****************************************************************************/ + return false; + } else { + edge_dof = el->setDOF(node+edge_no,mesh->getDOF(EDGE)); + } + } + + for (j = 0; j < 2; j++) { + dof[j] = el->getDOF(el->getVertexOfEdge(edge_no, j)); + } + + + /****************************************************************************/ + /* first look for all neighbours in one direction until a boundary is */ + /* reached :-( or we are back to mel :-) */ + /* if the index of a neighbour is smaller than the element index, the edge */ + /* is counted by this neighbour, return 0. */ + /* If we are back to element, return 1, to count the edge */ + /****************************************************************************/ + + nei = mel->getNeighbour(next_el[edge_no][0]); + opp_v = mel->getOppVertex(next_el[edge_no][0]); + + + if(mel->getBoundary(next_el[edge_no][0])) { + lbound = newBound(mel->getBoundary(next_el[edge_no][0]), lbound); + lproject = mel->getProjection(next_el[edge_no][0]); + } + + while (nei && nei != mel) { + for (j = 0; j < vertices; j++) + if (nei->getElement()->getDOF(j) == dof[0]) break; + for (k = 0; k < vertices; k++) + if (nei->getElement()->getDOF(k) == dof[1]) break; + + // check for periodic boundary + if(j == 4 || k == 4) { + nei = NULL; + break; + } + + if (mesh->getNumberOfDOFs(EDGE)) + TEST_EXIT(nei->index > mel_index) + ("neighbour index %d < element index %d\n", nei->getIndex(), mel_index); + + if (!mesh->getNumberOfDOFs(EDGE) && nei->getIndex() < mel_index) return false; + + + edge_no = Tetrahedron::edgeOfDOFs[j][k]; + + TEST_EXIT(*n_neigh < max_no_list_el) + ("too many neigbours for local list\n"); + + list_bound[(*n_neigh)] = + &(nei->boundary[mesh->getGeo(FACE)+edge_no]); + + list_project[(*n_neigh)++] = + &(nei->projection[mesh->getGeo(FACE)+edge_no]); + + if (mesh->getNumberOfDOFs(EDGE)) + { + // if(periodic) { + // nei->element->setDOF(node+edge_no, mesh->getDOF(EDGE)); + // } else { + nei->element->setDOF(node+edge_no,edge_dof); + // } + } + + if (next_el[edge_no][0] != opp_v) + { + if(nei->getBoundary(next_el[edge_no][0])) { + lbound = newBound(nei->getBoundary(next_el[edge_no][0]), lbound); + Projection *neiProject = nei->getProjection(next_el[edge_no][0]); + if(!lproject) + lproject = neiProject; + else { + if(neiProject && (lproject->getID() < neiProject->getID())) { + lproject = neiProject; + } + } + } + opp_v = nei->getOppVertex(next_el[edge_no][0]); + nei = nei->getNeighbour(next_el[edge_no][0]); + } + else + { + if(nei->getBoundary(next_el[edge_no][1])) { + lbound = newBound(nei->getBoundary(next_el[edge_no][1]), lbound); + Projection *neiProject = nei->getProjection(next_el[edge_no][1]); + if(!lproject) + lproject = neiProject; + else { + if(neiProject && (lproject->getID() < neiProject->getID())) { + lproject = neiProject; + } + } + } + opp_v = nei->getOppVertex(next_el[edge_no][1]); + nei = nei->getNeighbour(next_el[edge_no][1]); + } + } + if (!nei) + { + /****************************************************************************/ + /* while looping around the edge the domain's boundary was reached. Now, */ + /* loop in the other direction to the domain's boundary */ + /****************************************************************************/ + edge_no = mel_edge_no; + + nei = mel->getNeighbour(next_el[edge_no][1]); + opp_v = mel->getOppVertex(next_el[edge_no][1]); + if(mel->getBoundary(next_el[edge_no][1])) { + lbound = newBound(mel->getBoundary(next_el[edge_no][1]), lbound); + Projection *neiProject = mel->getProjection(next_el[edge_no][1]); + if(!lproject) + lproject = neiProject; + else { + if(neiProject && (lproject->getID() < neiProject->getID())) { + lproject = neiProject; + } + } + } + while (nei) + { + for (j = 0; j < vertices; j++) + if (nei->getElement()->getDOF(j) == dof[0]) break; + for (k = 0; k < vertices; k++) + if (nei->getElement()->getDOF(k) == dof[1]) break; + + // check for periodic boundary + if(j == 4 || k == 4) { + return false; + } + + if (mesh->getNumberOfDOFs(EDGE)) + TEST_EXIT(nei->getIndex() > mel_index) + ("neighbour index %d < element index %d\n", nei->getIndex(), + mel_index); + + if (nei->getIndex() < mel_index) return false; + + + edge_no = Tetrahedron::edgeOfDOFs[j][k]; + + TEST_EXIT(*n_neigh < max_no_list_el) + ("too many neigbours for local list\n"); + + list_bound[(*n_neigh)] = + &(nei->boundary[mesh->getGeo(FACE)+edge_no]); + + list_project[(*n_neigh)++] = + &(nei->projection[mesh->getGeo(FACE)+edge_no]); + + if (mesh->getNumberOfDOFs(EDGE)) { + TEST_EXIT(!nei->getElement()->getDOF(node+edge_no)) + ("dof %d on element %d is already set, but not on element %d\n", + node + edge_no, nei->getIndex(), mel_index); + + // if(periodic) { + // nei->element->setDOF(node+edge_no, mesh->getDOF(EDGE)); + // } else { + nei->element->setDOF(node+edge_no,edge_dof); + // } + } + + if (next_el[edge_no][0] != opp_v) + { + if(nei->getBoundary(next_el[edge_no][0])) { + lbound = newBound(nei->getBoundary(next_el[edge_no][0]), lbound); + Projection *neiProject = nei->getProjection(next_el[edge_no][0]); + if(!lproject) + lproject = neiProject; + else { + if(neiProject &&( lproject->getID() < neiProject->getID())) { + lproject = neiProject; + } + } + } + + opp_v = nei->getOppVertex(next_el[edge_no][0]); + nei = nei->getNeighbour(next_el[edge_no][0]); + } + else { + if(nei->getBoundary(next_el[edge_no][1])) { + lbound = newBound(nei->getBoundary(next_el[edge_no][1]), lbound); + Projection *neiProject = nei->getProjection(next_el[edge_no][1]); + if(!lproject) + lproject = neiProject; + else { + if(neiProject && (lproject->getID() < neiProject->getID())) { + lproject = neiProject; + } + } + } + + opp_v = nei->getOppVertex(next_el[edge_no][1]); + nei = nei->getNeighbour(next_el[edge_no][1]); + } + } + } + + for (j = 0; j < *n_neigh; j++) { + *(list_bound[j]) = lbound; + *(list_project[j]) = lproject; + } + + return true; + } + + void MacroReader::fillMelBoundary(Mesh *mesh, MacroElement *mel, + FixVec<BoundaryType ,NEIGH> ind) + { + int i; + for(i=0; i < mesh->getGeo(NEIGH); i++) { + mel->boundary[i] = ind[i]; + } + } + + + void MacroReader::fillMelNeigh(MacroElement *mel, + ::std::deque<MacroElement*>& macro_elements, + FixVec<int,NEIGH> ind) + { + int k; + int dim = mel->element->getMesh()->getDim(); + + for (k = 0; k < Global::getGeo(NEIGH, dim); k++) + { + if (ind[k] >= 0) + mel->neighbour[k] = macro_elements[ind[k]]; + else + mel->neighbour[k] = NULL; + } + return; + } + + + // ordnet Eintraege in Macro-Element macro bzgl. Verfeinerungskante ka um + // (coord, bound, boundary, neigh, oppVertex) + + // ordnet Eintraege in macro->el bzgl. Verfeinerungskante ka um + // (Element-DOF's (macro->el->dof) in Ecken und auf Kanten, + // wenn NEIGH_IN_EL macro->el->neigh, macro->el->oppVertex) + // (wird fuer ALBERT-Routine write_macro benoetigt) + + // ele wird nicht benoetigt (es kann NULL uebergeben werden) + + + void MacroReader::umbVkantMacro(Mesh *mesh, MacroElement* me, int ka, int *) + { + MacroElement* macr=NEW MacroElement(mesh->getDim()); + int i; + int n0; + DegreeOfFreedom *d[7]; + + int vertices = mesh->getGeo(VERTEX); + int facesPlusEdges = mesh->getGeo(EDGE) + mesh->getGeo(FACE); + + if (ka == 2); + else { + for (i=0; i < 3; i++) { + macr->coord[i]=me->coord[i]; + macr->setBoundary(facesPlusEdges + i, me->getBoundary(facesPlusEdges + i)); + macr->setBoundary(i, me->getBoundary(i)); + macr->setNeighbour(i, me->getNeighbour(i)); + macr->setOppVertex(i,me->getOppVertex(i)); + } + + for (i=0; i < 7; i++) { + d[i]=const_cast<int*>(me->getElement()->getDOF(i)); + } + + if (ka == 1) { + me->coord[0] = macr->coord[2]; + me->coord[1] = macr->coord[0]; + me->coord[2] = macr->coord[1]; + + me->setBoundary(facesPlusEdges + 0,macr->getBoundary(facesPlusEdges + 2)); + me->setBoundary(facesPlusEdges + 1,macr->getBoundary(facesPlusEdges + 0)); + me->setBoundary(facesPlusEdges + 2,macr->getBoundary(facesPlusEdges + 1)); + + me->setBoundary(0, macr->getBoundary(2)); + me->setBoundary(1, macr->getBoundary(0)); + me->setBoundary(2, macr->getBoundary(1)); + + me->setNeighbour(0,const_cast<MacroElement*>(macr->getNeighbour(2))); + me->setNeighbour(1,const_cast<MacroElement*>(macr->getNeighbour(0))); + me->setNeighbour(2,const_cast<MacroElement*>(macr->getNeighbour(1))); + + me->setOppVertex(0,macr->getOppVertex(2)); + me->setOppVertex(1,macr->getOppVertex(0)); + me->setOppVertex(2,macr->getOppVertex(1)); + + + if (mesh->getNumberOfDOFs(VERTEX)) /* Ecken */ + { + n0=mesh->getNode(VERTEX); + + const_cast<Element*>(me->getElement())->setDOF(n0,d[n0+2]); + const_cast<Element*>(me->getElement())->setDOF(n0+1,d[n0]); + const_cast<Element*>(me->getElement())->setDOF(n0+2,d[n0+1]); + } + + if (mesh->getNumberOfDOFs(EDGE)) /* Kanten */ + { + n0=mesh->getNode(EDGE); + + const_cast<Element*>(me->getElement())->setDOF(n0,d[n0+2]); + const_cast<Element*>(me->getElement())->setDOF(n0+1,d[n0]); + const_cast<Element*>(me->getElement())->setDOF(n0+2,d[n0+1]); + } + + } else { + me->coord[0] = macr->coord[1]; + me->coord[1] = macr->coord[2]; + me->coord[2] = macr->coord[0]; + + me->setBoundary(facesPlusEdges + 0,macr->getBoundary(facesPlusEdges + 1)); + me->setBoundary(facesPlusEdges + 1,macr->getBoundary(facesPlusEdges + 2)); + me->setBoundary(facesPlusEdges + 2,macr->getBoundary(facesPlusEdges + 0)); + + me->setBoundary(0, macr->getBoundary(1)); + me->setBoundary(1, macr->getBoundary(2)); + me->setBoundary(2, macr->getBoundary(0)); + + me->setNeighbour(0,const_cast<MacroElement*>(macr->getNeighbour(1))); + me->setNeighbour(1,const_cast<MacroElement*>(macr->getNeighbour(2))); + me->setNeighbour(2,const_cast<MacroElement*>(macr->getNeighbour(0))); + + me->setOppVertex(0,macr->getOppVertex(1)); + me->setOppVertex(1,macr->getOppVertex(2)); + me->setOppVertex(2,macr->getOppVertex(0)); + + if (mesh->getNumberOfDOFs(VERTEX)) /* Ecken */ + { + n0=mesh->getNode(VERTEX); + + const_cast<Element*>(me->getElement())->setDOF(n0,d[n0+1]); + const_cast<Element*>(me->getElement())->setDOF(n0+1,d[n0+2]); + const_cast<Element*>(me->getElement())->setDOF(n0+2,d[n0]); + } + + if (mesh->getNumberOfDOFs(EDGE)) /* Kanten */ + { + n0=mesh->getNode(EDGE); + + const_cast<Element*>(me->getElement())->setDOF(n0,d[n0+1]); + const_cast<Element*>(me->getElement())->setDOF(n0+1,d[n0+2]); + const_cast<Element*>(me->getElement())->setDOF(n0+2,d[n0]); + } + } + + + for (i=0; i < vertices; i++) /* oppVertex der Nachbarn umsetzen*/ + { + if (me->getNeighbour(i)) + { + const_cast<MacroElement*>(me->getNeighbour(i))->setOppVertex(me->getOppVertex(i),i); + } + } + } + DELETE macr; + } + + + // durchlaeuft rek. Macro-Triangulierung mit Start auf Macro-Element macro und + // waehlt geignete Verfeinerungskanten, so dass kein Zyklus auftritt + + // (Umbennenung der lokalen Indices der Macro-Elemente + // oder Speichern der neuen Verfeinerungskanten mit Fkt. umbvk) + + // waehlt als neue Verfeinerungskante die laengste Kante eines Elementes + // fuehrt "fiktiv verlaengerte" Kanten ein, + // wenn ein Element 2 laengste Kanten besitzt + + // macroalt Zeiger auf "Rekursions-Vorgaenger"-Macroelement + // lg Laenge der Verfeinerungskante von "Vorgaenger" + // ka = 1, wenn Verfeinerungskante von "Vorgaenger" fiktiv verlaengert + // ka = 0, sonst + // test Vektor von Flags, die angeben, ob Macro-Element schon getestet (=1) + // ele Integer-Vektor der Dimension Anzahl der Macro-Elemente + // zur Speicherung der neuen Verfeinerungskanten + // (wird nur benoetigt, wenn umbvk=umb_vkant_macrodat) + + void MacroReader::recumb(Mesh *mesh, + MacroElement *mel, MacroElement *macroalt, + int *test, double lg, int ka, int *ele, + void (*umbvk)(Mesh *mesh, MacroElement*, int k, int *el)) + { + int i; + double l[3]; + int v[3]; + int k = 0; + MacroElement *n; + + int vertices = mesh->getGeo(VERTEX); + + if (!mel || test[mel->getIndex()]==1) + { + return; + } + else + { + test[mel->getIndex()]=1; + + laengstekante(mel->coord,l,v); + + if (v[1] == mesh->getGeo(VERTEX)) /*nur eine laengste Kante*/ + { + umbvk(mesh,mel,v[0],ele); + + for (i=0; i < vertices; i++) { + recumb(mesh, + mel->neighbour[i], + mel, + test, + l[0], + 0, + ele, + umbvk); + } + return; + } + else + { + if (ka == 1) + { + if (fabs((l[0]-lg)/lg) < 0.0000001) + { + for (i=0; i < vertices; i++) + { + if (mel->neighbour[i] == macroalt) + { + k=i; + } + } + + umbvk(mesh,mel,k,ele); + + for (i=0; i < vertices; i++) { + recumb(mesh, + mel->neighbour[i], + mel, + test, + l[0], + 0, + ele, + umbvk); + } + return; + } + } + + n=const_cast<MacroElement*>(mel->getNeighbour(v[0])); + /*Nachbar an fiktiv verlaengerter Kante*/ + umbvk(mesh,mel,v[0],ele); + + recumb(mesh, n, mel,test,l[0],1,ele,umbvk); + for (i=0; i < vertices; i++) { + recumb(mesh, + mel->neighbour[i], + mel, + test, + l[0], + 0, + ele, + umbvk); + } + return; + } + } + } + + // berechnet aus Koord. der Eckpunkte eines Elementes + // die Laenge der laengsten Kante + + // l[0] = Laenge der laengsten Kante + // v[0] = lokaler Index der laengsten Kante + // v[1] = anderer lokaler Index, wenn ex. 2 laengste Kanten + // = 3, wenn ex. nur eine laengste Kante + // v[2] = dritter lokaler Index, wenn ex. 3 laengste Kanten + // = 3, wenn ex. nur eine oder zwei laengste Kanten + + void MacroReader::laengstekante(FixVec<WorldVector<double>,VERTEX> coord, double *l, int *v) + { + int dim = coord.getSize() - 1; + + int i; + int k; + double lg; + double eps; + double kz; + + int vertices = Global::getGeo(VERTEX,dim); + + l[0]=absteukl(coord[1],coord[2]); + l[1]=absteukl(coord[0],coord[2]); + l[2]=absteukl(coord[0],coord[1]); + + lg=l[0]; + kz=l[0]; + for (i=1; i < vertices; i++) + { + if (l[i] > lg) lg=l[i]; + if (l[i] < kz) kz=l[i]; + } + + eps=::std::min(0.000001,kz/10000); + k=0; + for (i=0; i < vertices; i++) + { + if (fabs(l[i]-lg) < eps) + { + v[k]=i; + k++; + } + } + for (i=k; i < vertices; i++) + { + v[i]=Global::getGeo(VERTEX,dim); + } + + l[0]=lg; + } + + void MacroReader::checkMesh(Mesh *mesh) + { + FUNCNAME("MacroReader::checkMesh()"); + + int i, nused, nfree; + DOFAdmin *localAdmin=mesh->admin[0]; + Flag fill_flag; + int error_detected = 0; + + MSG("checking mesh\n"); + + fill_flag = Mesh::CALL_EVERY_EL_INORDER | Mesh::FILL_NEIGH | Mesh::FILL_BOUND; + + Mesh::traversePtr = mesh; + error_detected += mesh->traverse(-1, fill_flag|Mesh::FILL_ADD_ALL, basicCheckFct); + + if (mesh->preserveCoarseDOFs) + fill_flag = Mesh::CALL_EVERY_EL_INORDER; + else + fill_flag = Mesh::CALL_LEAF_EL; + + fill_flag |= Mesh::FILL_NEIGH; + + for (mesh->iadmin = 0; + mesh->iadmin < static_cast<int>(mesh->admin.size()); + mesh->iadmin++) { + localAdmin = mesh->admin[mesh->iadmin]; + + if (localAdmin->getSize() > 0) { + if (static_cast<int>(mesh->dof_used.size()) < localAdmin->getSize()) { + mesh->dof_used.resize(localAdmin->getSize() + 1000); + } + for (i = 0; i < static_cast<int>(mesh->dof_used.size()); i++) + mesh->dof_used[i] = 0; + + nused = nfree = 0; + + Mesh::traversePtr = mesh; + error_detected += mesh->traverse(-1, + fill_flag | Mesh::FILL_ADD_ALL, + basicDOFCheckFct); + + DOFIteratorBase it(localAdmin, USED_DOFS); + for(it.reset(); !it.end(); ++it) { + nused++; + if (!mesh->dof_used[it.getDOFIndex()]) { + error_detected++; + MSG("dof[%d] not used??\n",it.getDOFIndex()); + } + } + + DOFIteratorBase freeIt(localAdmin, FREE_DOFS); + for(freeIt.reset(); !freeIt.end(); ++freeIt) { + nfree++; + if(mesh->dof_used[freeIt.getDOFIndex()]) { + error_detected++; + MSG("dof[%d] used??\n",freeIt.getDOFIndex()); + } + } + + TEST(nused + nfree == localAdmin->getSize()) + ("nused = %d, nfree = %d, admin.size = %d ????\n", + nused, nfree, localAdmin->getSize()); + TEST(nused == localAdmin->getUsedDOFs()) + ("nused = %d, admin.used_count = %d ?????\n", + nused, localAdmin->getUsedDOFs()); + } + } + + if (!error_detected) { + MSG("checking done; no error detected\n"); + } else { + MSG("checking done; %d error%s detected\n", error_detected, + error_detected == 1 ? "" : "s"); + + Mesh::traversePtr = mesh; + mesh->traverse(-1, Mesh::CALL_EVERY_EL_INORDER, basicNodeFct); + WAIT_REALLY; + } + + return; + } + + int MacroReader::basicCheckFct(ElInfo* elinfo) + { + FUNCNAME("MacroReader::basicCheckFct"); + int i, j, k, opp_v; + Element *el = elinfo->getElement(); + const Element *neig; + int error_detected=0; + + Mesh* mesh = Mesh::traversePtr; + + int dim = mesh->getDim(); + + elinfo->testFlag(Mesh::FILL_NEIGH); + + for (i = 0; i < mesh->getGeo(NEIGH); i++) + { + if ((neig = elinfo->getNeighbour(i))) + { + if(elinfo->getBoundary(i) > 0) { // < 0 => periodic boundary + if (!error_detected) + MSG("error detected!!!\n"); + error_detected++; + MSG("interior (*boundary)[%d] non NULL on element = %d\n", + i, el->getIndex()); + } + + opp_v = elinfo->getOppVertex(i); + if(opp_v < 0 || opp_v >= mesh->getGeo(NEIGH)) + { + if (!error_detected) + MSG("error detected!!!\n"); + error_detected++; + MSG("opp_v = %d\n", opp_v); + } + + if(elinfo->getBoundary(i) > 0) { // < 0 => periodic boundary + if(dim == 1) { + if(el->getDOF(i) != neig->getDOF(opp_v)) { + if (!error_detected) + MSG("error detected!!!\n"); + error_detected++; + MSG("neighbour error\n"); + } + } else { + for (j = 1; j < mesh->getGeo(VERTEX); j++) { + for (k = 1; k < mesh->getGeo(VERTEX); k++) + if (el->getDOF((i+j) % mesh->getGeo(VERTEX)) == + neig->getDOF((opp_v+k) % mesh->getGeo(VERTEX))) + break; + + if (k >= mesh->getGeo(VERTEX)) { + if (!error_detected) + MSG("error detected!!!\n"); + error_detected++; + MSG("dof %d of el %d at face %d isn't dof of neigh %d at face %d\n", + el->getDOF((i+j) % 3,0), el->getIndex(), i, neig->getIndex(), + opp_v); + } + } + } + } + } else { + if (elinfo->getBoundary(i) == INTERIOR) { + if (!error_detected) + MSG("error detected!!!\n"); + error_detected++; + MSG("(*boundary)[%d] on domains boundary is NULL on element = %d\n", + i, el->getIndex()); + } + } + } + + return error_detected; + } + + int MacroReader::basicDOFCheckFct(ElInfo* elinfo) + { + FUNCNAME("MacroReader::basicDOFCheckFct"); + + Mesh* mesh = Mesh::traversePtr; + Element* el = elinfo->getElement(); + + const DOFAdmin& adm = mesh->getDOFAdmin(mesh->iadmin); + const Element *neig; + const DegreeOfFreedom *dof; + int i, j, jdof, ndof, i0, j0, ov; + + if (0 == mesh->dof_used.size()) + return 0; + + if ((ndof = adm.getNumberOfDOFs(VERTEX))) { + j0 = adm.getNumberOfPreDOFs(VERTEX); + TEST_EXIT(j0 + ndof <= mesh->getNumberOfDOFs(VERTEX)) + ("adm.getNumberOfPreDOFs(VERTEX) %d + nDOF %d > mesh->nDOF %d\n", + j0, ndof, mesh->getNumberOfDOFs(VERTEX)); + i0 = mesh->getNode(VERTEX); + for (i = 0; i < mesh->getGeo(VERTEX); i++) + { + if ((dof = el->getDOF(i0+i)) == NULL) + ERROR("no vertex dof %d on element %d\n", i, el->getIndex()); + else + for (j = 0; j < ndof; j++) + { + jdof = dof[j0 + j]; + TEST(jdof >= 0 && jdof < static_cast<int>(mesh->dof_used.size())) + ("vertex dof=%d invalid? size=%d\n",jdof, mesh->dof_used.size()); + mesh->dof_used[jdof]++; + } + } + /* neighbour vertex dofs have been checked in check_fct() */ + } + + + if (mesh->getDim() > 1) { + if ((ndof = adm.getNumberOfDOFs(EDGE))) { + j0 = adm.getNumberOfPreDOFs(EDGE); + + TEST_EXIT(j0 + ndof <= mesh->getNumberOfDOFs(EDGE)) + ("adm.getNumberOfPreDOFs(EDGE) %d + nDOF %d > mesh->nDOF %d\n", + j0, ndof, mesh->getNumberOfDOFs(EDGE)); + + i0 = mesh->getNode(EDGE); + + for (i = 0; i < mesh->getGeo(EDGE); i++) { + if ((dof = el->getDOF(i0 + i)) == NULL) { + ERROR("no edge dof %d on element %d\n", i, el->getIndex()); + } else { + for (j = 0; j < ndof; j++) { + jdof = dof[j0 + j]; + TEST(jdof >= 0 && jdof < static_cast<int>(mesh->dof_used.size())) + ("edge dof=%d invalid? size=%d\n",jdof, mesh->dof_used.size()); + mesh->dof_used[jdof]++; + } + } + + if (el->getFirstChild() == NULL) { + if(mesh->getDim() == 2) { + if ((neig = elinfo->getNeighbour(i))) { + ov = elinfo->getOppVertex(i); + + TEST(neig->getDOF(i0 + ov) == dof) + ("el %d edge %d dof %8X: wrong dof %8X in neighbour %d edge %d\n", + el->getIndex(), i, dof, neig->getDOF(i0 + ov), + neig->getIndex(), ov); + } + } else { // dim == 3 + int in, k, found; + + for (in = 0; in < mesh->getGeo(NEIGH); in++) { + if ((in != el->getVertexOfEdge(i,0)) && + (in != el->getVertexOfEdge(i,1)) && + (neig = elinfo->getNeighbour(in))) { + found = 0; + for (k = 0; k < mesh->getGeo(EDGE); k++) + if (neig->getDOF(i0 + k) == dof) found++; + TEST(found==1)("el %d edge %d dof found=%d in neighbour %d\n", + el->getIndex(), i, found, neig->getIndex()); + } + } + } + } + } + } + } + + if(mesh->getDim()==3) { + if ((ndof = adm.getNumberOfDOFs(FACE))) { + j0 = adm.getNumberOfPreDOFs(FACE); + TEST_EXIT(j0 + ndof <= mesh->getNumberOfDOFs(FACE)) + ("admin->n0_dof[FACE] %d + nDOF %d > mesh->nDOF %d\n", + j0, ndof, mesh->getNumberOfDOFs(FACE)); + i0 = mesh->getNode(FACE); + for (i = 0; i < mesh->getGeo(FACE); i++) { + TEST(dof = el->getDOF(i0 + i))("no face dof %d ???\n", i); + for (j = 0; j < ndof; j++) { + jdof = dof[j0 + j]; + TEST(jdof >= 0 && jdof < static_cast<int>(mesh->dof_used.size())) + ("face dof=%d invalid? size=%d\n",jdof, mesh->dof_used.size()); + mesh->dof_used[jdof]++; + } + + if (el->getChild(0) == NULL) { + if ((neig = elinfo->getNeighbour(i))) { + ov = elinfo->getOppVertex(i); + TEST(neig->getDOF(i0 + ov) == dof) + ("el %d face %d dof %8X: wrong dof %8X in neighbour %d face %d\n", + el->getIndex(), i, dof, neig->getDOF(i0 + ov), neig->getIndex(), + ov); + } + } + } + } + } + + if ((ndof = adm.getNumberOfDOFs(CENTER))) { + i0 = mesh->getNode(CENTER); + TEST(dof = el->getDOF(i0))("no center dof???\n"); + j0 = adm.getNumberOfPreDOFs(CENTER); + TEST_EXIT(j0 + ndof <= mesh->getNumberOfDOFs(CENTER)) + ("adm.getNumberOfPreDOFs(CENTER) %d + nDOF %d > mesh->nDOF %d\n", + j0, ndof, mesh->getNumberOfDOFs(CENTER)); + for (j = 0; j < ndof; j++) { + jdof = dof[j0 + j]; + TEST(jdof >= 0 && jdof < static_cast<int>(mesh->dof_used.size())) + ("center dof=%d invalid? size=%d\n",jdof, mesh->dof_used.size()); + mesh->dof_used[jdof]++; + } + } + + return 0; + } + + int MacroReader::basicNodeFct(ElInfo* elinfo) + { + FUNCNAME("MacroReader::basicNodeFct()"); + + Element *el = elinfo->getElement(); + Mesh *mesh = Mesh::traversePtr; + + MSG("el %4d: ", el->getIndex()); + for (int i = 0; i < mesh->getGeo(VERTEX); i++) + Msg::print("%4d%s", el->getDOF(i,0), + i < mesh->getGeo(VERTEX)-1 ? ", " : "\n"); + + return 0; + } +} diff --git a/AMDiS/src/MacroReader.h b/AMDiS/src/MacroReader.h new file mode 100644 index 0000000000000000000000000000000000000000..a0a853cb79355fe8aa99e80a3912cc95a5d496c7 --- /dev/null +++ b/AMDiS/src/MacroReader.h @@ -0,0 +1,187 @@ +// ============================================================================ +// == == +// == AMDiS - Adaptive multidimensional simulations == +// == == +// ============================================================================ +// == == +// == crystal growth group == +// == == +// == Stiftung caesar == +// == Ludwig-Erhard-Allee 2 == +// == 53175 Bonn == +// == germany == +// == == +// ============================================================================ +// == == +// == http://www.caesar.de/cg/AMDiS == +// == == +// ============================================================================ + +/** \file MacroReader.h */ + +#ifndef AMDIS_MACROREADER_H +#define AMDIS_MACROREADER_H + +#include <deque> +#include "Global.h" +#include "FixVec.h" +#include "Boundary.h" + +namespace AMDiS { + + class Mesh; + class MacroElement; + class ElInfo; + class MacroInfo; + + /** \defgroup Input Input module */ + + // =========================================================================== + // ===== class MacroReader =================================================== + // =========================================================================== + + /** \ingroup Input + * + * \brief + * Static class which reads a macro triangulation file and creates + * the corresponding macro mesh. + */ + class MacroReader + { + public: + /** \brief + * Creates a Mesh by reading the macro file with the given filename + */ + static MacroInfo* readMacro(const char *filename, + Mesh* mesh, + const char *periodicFile, + int check); + + protected: + static void computeNeighbours(Mesh *mesh); + static void boundaryDOFs(Mesh *mesh); + + static void umb(int *ele, Mesh *mesh, + void (*umbvk)(Mesh *mesh, MacroElement*,int k, int *el)); + + static int macrotest(Mesh *mesh); + + static void macroTest(Mesh *mesh, const char *nameneu); + + static bool newEdge(Mesh *mesh, MacroElement *mel, + int mel_edge_no, int *n_neigh); + + static void fillMelBoundary(Mesh *, MacroElement *mel, + FixVec<BoundaryType ,NEIGH>); + + static void fillMelNeigh(MacroElement *mel, + ::std::deque<MacroElement*>& macro_elements, + FixVec<int,NEIGH> ind); + + static void umbVkantMacro(Mesh *mesh, + MacroElement *, + int ka, + int *ele); + + static void recumb(Mesh *mesh, + MacroElement *mel, MacroElement *macroalt, + int *test, double lg, int ka, int *ele, + void (*umbvk)(Mesh *mesh, MacroElement*,int k, int *el)); + + static void laengstekante(FixVec<WorldVector<double>,VERTEX> coord, + double *l, int *v); + + static void checkMesh(Mesh *mesh); + + static int basicCheckFct(ElInfo* e); + + static int basicDOFCheckFct(ElInfo* e); + + static int basicNodeFct(ElInfo* e); + + friend class MacroInfo; + }; + + // ========================================================================== + // ===== class MacroInfo ==================================================== + // ========================================================================== + + /** \ingroup Input + * \brief + * Used for reading a macro triangulation + */ + class MacroInfo + { + public: + MEMORY_MANAGED(MacroInfo); + + /** \brief + * Pointer to the Mesh + */ + Mesh *mesh; + + /** \brief + * list of macro elements + */ + ::std::deque<MacroElement*> mel; + + /** \brief + * vector of all vertex dofs + */ + DegreeOfFreedom **dof; + + /** \brief + * coords[j][k]: kth coordinate of global vertex j + */ + WorldVector<double> *coords; + + /** \brief + * mel_vertex[i][k]: global index of kth vertex of element i + */ + int **mel_vertex; + + /** \brief + * true, if neighbour information is in macro file + */ + bool neigh_set; + + /** \brief + * true, if boundary information is in macro file + */ + bool bound_set; + + public: + /** \brief + * Fills MacroInfo structure and some pointers in mesh + */ + void fill(Mesh *mesh, int ne, int nv); + + /** \brief + * Reads macro triangulation from ascii file in AMDiS format. + * Fills MacroInfo structure. + * Called by Mesh::readMacro(), fills missing information + */ + void readAMDiSMacro(const char *filename, Mesh* mesh); + + /** \brief + * Frees memory of MacroInfo + */ + void clear(int ne, int nv); + + /** \brief + * Sets the boundary of all edges/faces with no neigbour to a straight + * line/face with dirichlet boundary type + */ + void dirichletBoundary(); + + void fillBoundaryInfo(Mesh *mesh); + + protected: + /** \brief + * Reads indices from macro file + */ + int read_indices(FILE *file, DimVec<int> &id); + }; +} + +#endif diff --git a/AMDiS/src/MacroWriter.cc b/AMDiS/src/MacroWriter.cc new file mode 100644 index 0000000000000000000000000000000000000000..78369f63d1046d8d3f61df16d8da2fe54783a0fb --- /dev/null +++ b/AMDiS/src/MacroWriter.cc @@ -0,0 +1,672 @@ +#include <fstream> + +#include "MacroWriter.h" +#include "DataCollector.h" +#include "Mesh.h" +#include "DOFAdmin.h" +#include "FiniteElemSpace.h" +#include "DOFVector.h" +#include "DOFIterator.h" +#include "ElInfo.h" +#include "SurfaceRegion_ED.h" +#include "ElementRegion_ED.h" +#include <string> +#include "Traverse.h" + +namespace AMDiS { + + DOFVector< ::std::list<VertexInfo> >* MacroWriter::vertexInfos = NULL; + ::std::list<ElementInfo> MacroWriter::elements; + + Mesh *MacroWriter::mesh = NULL; + FILE *MacroWriter::macroFile = NULL; + FILE *MacroWriter::periodicFile = NULL; + int MacroWriter::n0 = 0; + int MacroWriter::nv = 0; + int MacroWriter::ne = 0; + int MacroWriter::nc = 0; + int MacroWriter::dim = 0; + + ::std::map<int, int> MacroWriter::outputIndices; + + ::std::vector<DimVec<bool> > MacroWriter::periodicConnections; + + bool (*MacroWriter::writeElement)(ElInfo*) = NULL; + + int MacroWriter::writeMacro(DataCollector *dc, + const char *name, + double time, + int level, + Flag traverseFlag, + bool (*writeElem)(ElInfo*)) + { + FUNCNAME("MacroWroter::writeFile"); + TEST_EXIT(dc)("no data collector\n"); + + writeElement = writeElem; + + ::std::ofstream file; + ::std::list<ElementInfo> *elements = dc->getElementInfos(); + DOFVector< ::std::list<VertexInfo> > *vertexInfos = dc->getVertexInfos(); + + int dow = Global::getGeo(WORLD); + int dim = dc->getMesh()->getDim(); + int nv = dc->getNumberVertices(); + int ne = dc->getNumberElements(); + int vertices = dc->getMesh()->getGeo(VERTEX); + + file.open(name); + + // === print file header === + file << "mesh name: " << dc->getMesh()->getName() << ::std::endl << ::std::endl; + file << "time: " << ::std::scientific << time << ::std::endl << ::std::endl; + + file << "DIM: " << dim << ::std::endl; + file << "DIM_OF_WORLD: " << dow << ::std::endl << ::std::endl; + + file << "number of vertices: " << nv << ::std::endl; + file << "number of elements: " << ne << ::std::endl << ::std::endl; + + // === print vertex coords and remember global output indices === + file << "vertex coordinates:" << ::std::endl; + + DOFVector< ::std::list<VertexInfo> >::Iterator it(vertexInfos, USED_DOFS); + int i, counter = 0; + + // for all DOFs + for(it.reset(); !it.end(); ++it) { + // for all vertex infos of this DOF + ::std::list<VertexInfo>::iterator it2; + for(it2 = it->begin(); it2 != it->end(); ++it2) { + it2->outputIndex = counter++; + for(i = 0; i < dow; i++) { + file << ::std::scientific << it2->coords[i] << " "; + } + file << ::std::endl; + } + } + + // === print element vertices === + file << ::std::endl << "element vertices:" << ::std::endl; + + // iterate the element list + ::std::list<ElementInfo>::iterator elementIt; + + for(elementIt = elements->begin(); elementIt != elements->end(); ++elementIt) { + // for all vertices + for(i = 0; i < vertices; i++) { + file << elementIt->vertexInfo[i]->outputIndex << " "; + } + file << ::std::endl; + } + + // === print boundaries === + file << ::std::endl << "element boundaries:" << ::std::endl; + + for(elementIt = elements->begin(); elementIt != elements->end(); ++elementIt) { + // for all vertices + for(i = 0; i < vertices; i++) { + file << elementIt->boundary[i] << " "; + } + file << ::std::endl; + } + + // === print neighbours === + file << ::std::endl << "element neighbours:" << ::std::endl; + + for(elementIt = elements->begin(); elementIt != elements->end(); ++elementIt) { + // for all vertices + for(i = 0; i < vertices; i++) { + file << elementIt->neighbour[i] << " "; + } + file << ::std::endl; + } + + // === print boundary projections === + file << ::std::endl << "projections:" << ::std::endl; + + for(elementIt = elements->begin(); elementIt != elements->end(); ++elementIt) { + // for all vertices + for(i = 0; i < vertices; i++) { + if(elementIt->projection[i]) + file << elementIt->projection[i]->getID() << " "; + else + file << "0 "; + } + file << ::std::endl; + } + + // === print element regions === + file << ::std::endl << "element region:" << ::std::endl; + + for(elementIt = elements->begin(); elementIt != elements->end(); ++elementIt) { + file << elementIt->elementRegion << ::std::endl; + } + + // === print surface regions === + file << ::std::endl << "surface region:" << ::std::endl; + + for(elementIt = elements->begin(); elementIt != elements->end(); ++elementIt) { + for(i = 0; i < vertices; i++) { + file << elementIt->surfaceRegions[i] << " "; + } + file << ::std::endl; + } + + // === print element types if necessary === + if (dim == 3) { + file << ::std::endl << "element type:" << ::std::endl; + + for(elementIt = elements->begin(); elementIt != elements->end(); ++elementIt) { + file << (int)(elementIt->type) << " "; + } + } + + file.close(); + + return(0); + } + + + void MacroWriter::writePeriodicFile(DataCollector *dc, + const ::std::string filename) + { + FUNCNAME("MacroWriter::writePeriodicFile2"); + TEST_EXIT(dc)("no data collector\n"); + + ::std::ofstream file; + + file.open(filename.c_str()); + + file << "associations: " << dc->getNumberConnections() << ::std::endl; + file << ::std::endl << "mode bc el1 - local vertices <-> el2 - local vertices" << ::std::endl; + + ::std::list<PeriodicInfo>::iterator periodicIt; + + // Iterate on all periodic connections + for(periodicIt = dc->getPeriodicInfos()->begin(); + periodicIt != dc->getPeriodicInfos()->end(); + ++periodicIt) { + + ::std::map<int, int>::iterator mapIt; + + // Write mode and type of periodic connection + file << periodicIt->mode << " " << periodicIt->type << " "; + + // Write index of the first element + file << periodicIt->outputIndex << " "; + + // Write local indices of the first element + for (mapIt = periodicIt->vertexMap.begin(); + mapIt != periodicIt->vertexMap.end(); + ++mapIt) { + file << mapIt->first << " "; + } + + // Write index of the second element + file << periodicIt->neighIndex << " "; + + // Write local indices of the second element + for (mapIt = periodicIt->vertexMap.begin(); + mapIt != periodicIt->vertexMap.end(); + ++mapIt) { + file << mapIt->second << " "; + } + + file << ::std::endl; + } + + + file.close(); + } + + + int MacroWriter::writeMacroOld(const FiniteElemSpace *fe_space, + const char* name, double time, + int level, + Flag traverseFlag) + { + FUNCNAME("MacroWriter::writeMacro"); + TEST_EXIT(fe_space)("no feSpace\n"); + + mesh = fe_space->getMesh(); + dim = mesh->getDim(); + int dow = Global::getGeo(WORLD); + + bool writeElType = (dim == 3); + int vertices = mesh->getGeo(VERTEX); + + // === create filename === + ::std::string filename; + if(name) { + filename = ::std::string(name); + } else { + filename = mesh->getName(); + } + + // === open file === + if (!(macroFile = fopen(filename.c_str(), "w"))) { + ERROR_EXIT("could not open file %s for writing\n", filename.c_str()); + return(0); + } + + // === get admin and fe_space === + DOFAdmin* localAdmin = const_cast<DOFAdmin*>(fe_space->getAdmin()); + + // DOFAdmin* localAdmin = const_cast<DOFAdmin*>(mesh->getVertexAdmin()); + // TEST_EXIT(localAdmin)("no dof admin for vertices\n"); + // FiniteElemSpace *fe_space = + // FiniteElemSpace::provideFESpace(localAdmin, NULL, NULL); + + // === create vertex info vector === + vertexInfos = NEW DOFVector< ::std::list<VertexInfo> >(fe_space, "vertex infos"); + + // === delete old element list === + elements.resize(0, dim); + + n0 = localAdmin->getNumberOfPreDOFs(VERTEX); + nv = ne = 0; + + // create output indices + //mesh->traverse(level, traverseFlag, indexFct); + + TraverseStack stack; + ElInfo *elInfo = stack.traverseFirst(mesh, level, traverseFlag); + while(elInfo) { + if(!writeElement || writeElement(elInfo)) indexFct(elInfo); + elInfo = stack.traverseNext(elInfo); + } + + traverseFlag |= + Mesh::FILL_NEIGH | + Mesh::FILL_COORDS | + Mesh::FILL_OPP_COORDS | + Mesh::FILL_BOUND; + + // === traverse mesh and fill vertex infos and element list === +// mesh->traverse(level, +// traverseFlag, +// traverseFct); + + elInfo = stack.traverseFirst(mesh, level, traverseFlag); + while(elInfo) { + if(!writeElement || writeElement(elInfo)) traverseFct(elInfo); + elInfo = stack.traverseNext(elInfo); + } + + // === print file header === + fprintf(macroFile, "mesh name: %s\n\n", mesh->getName().c_str()); + fprintf(macroFile, "time: %e\n\n", time); + + fprintf(macroFile, "DIM: %d\n", dim); + fprintf(macroFile, "DIM_OF_WORLD: %d\n\n", dow); + + fprintf(macroFile, "number of vertices: %d\n", nv); + fprintf(macroFile, "number of elements: %d\n\n", ne); + + // === print vertex coords and remember global output indices === + fprintf(macroFile, "vertex coordinates:\n"); + + DOFVector< ::std::list<VertexInfo> >::Iterator it(vertexInfos, USED_DOFS); + int i, counter = 0; + + // for all DOFs + for(it.reset(); !it.end(); ++it) { + // for all vertex infos of this DOF + ::std::list<VertexInfo>::iterator it2; + for(it2 = it->begin(); it2 != it->end(); ++it2) { + it2->outputIndex = counter++; + for(i=0; i < dow; i++) { + fprintf(macroFile, "%e ", it2->coords[i]); + } + fprintf(macroFile, "\n"); + } + } + + // === print element vertices === + fprintf(macroFile, "\nelement vertices:\n"); + + // iterate the element list + ::std::list<ElementInfo>::iterator elementIt; + + for(elementIt = elements.begin(); elementIt != elements.end(); ++elementIt) { + // for all vertices + for(i=0; i < vertices; i++) { + fprintf(macroFile, "%d ", elementIt->vertexInfo[i]->outputIndex); + } + fprintf(macroFile, "\n"); + } + + // === print boundaries === + fprintf(macroFile, "\nelement boundaries:\n"); + + for(elementIt = elements.begin(); elementIt != elements.end(); ++elementIt) { + // for all vertices + for(i=0; i < vertices; i++) { + fprintf(macroFile, "%d ", elementIt->boundary[i]); + } + fprintf(macroFile, "\n"); + } + + // === print neighbours === + fprintf(macroFile, "\nelement neighbours:\n"); + + for(elementIt = elements.begin(); elementIt != elements.end(); ++elementIt) { + // for all vertices + for(i=0; i < vertices; i++) { + fprintf(macroFile, "%d ", elementIt->neighbour[i]); + } + fprintf(macroFile, "\n"); + } + + // === print boundary projections === + fprintf(macroFile, "\nprojections:\n"); + + for(elementIt = elements.begin(); elementIt != elements.end(); ++elementIt) { + // for all vertices + for(i=0; i < vertices; i++) { + if(elementIt->projection[i]) + fprintf(macroFile, "%d ", elementIt->projection[i]->getID()); + else + fprintf(macroFile, "0 "); + } + fprintf(macroFile, "\n"); + } + + // === print element regions === + fprintf(macroFile, "\nelement region:\n"); + + for(elementIt = elements.begin(); elementIt != elements.end(); ++elementIt) { + fprintf(macroFile, "%d\n", elementIt->elementRegion); + } + + // === print surface regions === + fprintf(macroFile, "\nsurface region:\n"); + + for(elementIt = elements.begin(); elementIt != elements.end(); ++elementIt) { + for(i=0; i < vertices; i++) { + fprintf(macroFile, "%d ", elementIt->surfaceRegions[i]); + } + fprintf(macroFile, "\n"); + } + + // === print element types if necessary === + if (dim == 3) { + if (writeElType) { + fprintf(macroFile, "\nelement type:\n"); + + for(elementIt = elements.begin(); elementIt != elements.end(); ++elementIt) { + fprintf(macroFile, "%d ", elementIt->type); + } + } + } + + // === close file === + fclose(macroFile); + macroFile = NULL; + + DELETE vertexInfos; + + return(1); + } + + int MacroWriter::traverseFct(ElInfo* elInfo) + { + int i; + const DegreeOfFreedom **dof = elInfo->getElement()->getDOF(); + DegreeOfFreedom vertexDOF; + WorldVector<double> vertexCoords; + + // increment number of elements + //ne++; + + // create ElementInfo + ElementInfo elementInfo(dim); + + // read element region + ElementData *ed = + elInfo->getElement()->getElementData(ELEMENT_REGION); + + if(ed) { + elementInfo.elementRegion = + dynamic_cast<ElementRegion_ED*>(ed)->getRegion(); + } + else { + elementInfo.elementRegion = -1; + } + + // read surface regions to element info + ed = elInfo->getElement()->getElementData(SURFACE_REGION); + + elementInfo.surfaceRegions.set(-1); + + while(ed) { + SurfaceRegion_ED *sr = dynamic_cast<SurfaceRegion_ED*>(ed); + elementInfo.surfaceRegions[sr->getSide()] = sr->getRegion(); + ed = ed->getDecorated(SURFACE_REGION); + } + + // for all vertices + for(i=0; i < dim+1; i++) { + // get coords of this vertex + vertexCoords = elInfo->getCoord(i); + + // get dof index of this vertex + vertexDOF = dof[i][n0]; + + // search for coords at this dof + ::std::list<VertexInfo>::iterator it = + find((*vertexInfos)[vertexDOF].begin(), + (*vertexInfos)[vertexDOF].end(), + vertexCoords); + + // coords not yet in list? + if(it == (*vertexInfos)[vertexDOF].end()) { + // create new vertex info + VertexInfo newVertexInfo = {vertexCoords, -1}; + + // add new vertex info to list + (*vertexInfos)[vertexDOF].push_front(newVertexInfo); + + // set iterator to new vertex info + it = (*vertexInfos)[vertexDOF].begin(); + + // increment number of vertices + nv++; + } + + // fill element info + elementInfo.vertexInfo[i] = it; + elementInfo.boundary[i] = elInfo->getBoundary(i); + elementInfo.projection[i] = elInfo->getProjection(i); + elementInfo.neighbour[i] = + elInfo->getNeighbour(i) ? + outputIndices[elInfo->getNeighbour(i)->getIndex()] : + -1; + } + + if(dim == 3) { + elementInfo.type = (dynamic_cast<ElInfo3d*>(elInfo)->getType()); + } + + // remember element info + elements.push_back(elementInfo); + + return 0; + } + + void MacroWriter::writePeriodicFileOld(Mesh *aMesh, + const ::std::string filename, + int level, + Flag traverseFlag) + { + // === open file === + if (!(periodicFile = fopen(filename.c_str(), "w"))) { + ERROR_EXIT("could not open file %s for writing\n", filename.c_str()); + } + + mesh = aMesh; + dim = mesh->getDim(); + + // === create output indices and count connections === + + n0 = mesh->getVertexAdmin()->getNumberOfPreDOFs(VERTEX); + ne = 0; + nc = 0; + + //mesh->traverse(level, traverseFlag, periodicFct1); + + TraverseStack stack; + ElInfo *elInfo = stack.traverseFirst(mesh, level, traverseFlag); + while(elInfo) { + if(!writeElement || writeElement(elInfo)) periodicFct1(elInfo); + elInfo = stack.traverseNext(elInfo); + } + + nc /= 2; + + fprintf(periodicFile, "associations: %d\n", nc); + fprintf(periodicFile, "\nmode bc el1 - local vertices <-> el2 - local vertices\n"); + + traverseFlag |= + Mesh::FILL_COORDS | + Mesh::FILL_OPP_COORDS| + Mesh::FILL_NEIGH | + Mesh::FILL_BOUND; + + + //mesh->traverse(level, + // traverseFlag, + // periodicFct2); + + elInfo = stack.traverseFirst(mesh, level, traverseFlag); + while(elInfo) { + if(!writeElement || writeElement(elInfo)) periodicFct2(elInfo); + elInfo = stack.traverseNext(elInfo); + } + + outputIndices.clear(); + periodicConnections.clear(); + + // === close periodic file === + + fclose(periodicFile); + periodicFile = NULL; + } + + int MacroWriter::periodicFct1(ElInfo *elInfo) + { + const Element *element = elInfo->getElement(); + + outputIndices[element->getIndex()] = ne++; + + LeafDataPeriodic *ldp = dynamic_cast<LeafDataPeriodic*> + (element-> + getElementData()-> + getElementData(PERIODIC)); + + if(ldp) { + nc += dynamic_cast<LeafDataPeriodic*>(ldp)->getInfoList().size(); + } + + periodicConnections.push_back(DimVec<bool>(dim, DEFAULT_VALUE, false)); + + return 0; + } + + int MacroWriter::periodicFct2(ElInfo *elInfo) + { + FUNCNAME("MacroWriter::periodicFct2"); + + int i, j; + + const Element *element = elInfo->getElement(); + + LeafDataPeriodic *ldp = dynamic_cast<LeafDataPeriodic*> + (element-> + getElementData()-> + getElementData(PERIODIC)); + + if(ldp) { + ::std::list<LeafDataPeriodic::PeriodicInfo>::iterator it; + for(it = dynamic_cast<LeafDataPeriodic*>(ldp)->getInfoList().begin(); + it != dynamic_cast<LeafDataPeriodic*>(ldp)->getInfoList().end(); + ++it) + { + int outputIndex = outputIndices[elInfo->getElement()->getIndex()]; + int neighIndex = outputIndices[elInfo-> + getNeighbour(it->elementSide)-> + getIndex()]; + + if(!periodicConnections[outputIndex][it->elementSide]) { + + fprintf(periodicFile, "%d ", it->periodicMode); + fprintf(periodicFile, "%d ", it->type); + + + periodicConnections[outputIndex][it->elementSide] = true; + periodicConnections + [neighIndex][elInfo->getOppVertex(it->elementSide)] = true; + + int index1, index2, dof1, dof2; + ::std::map<int, int> vertexMap; + + for(i=0; i < dim; i++) { + index1 = + elInfo->getElement()->getVertexOfPosition(INDEX_OF_DIM(dim-1, dim), + it->elementSide, + i); + dof1 = elInfo->getElement()->getDOF(index1, n0); + + for(j=0; j < dim; j++) { + index2 = + elInfo->getElement()->getVertexOfPosition(INDEX_OF_DIM(dim-1, dim), + elInfo->getOppVertex(it->elementSide), + j); + dof2 = elInfo->getNeighbour(it->elementSide)->getDOF(index2, n0); + + if((dof1 == dof2) || (mesh->associated(dof1, dof2))) { + vertexMap[index1] = index2; + //MSG("%d ", outputIndices[elInfo->getElement()->getIndex()]); + + // ::std::cout << index1 << " " << index2 << " "; + break; + } + } + } + + fprintf(periodicFile, "%d ", outputIndex); + for(i=0; i < dim; i++) { + fprintf(periodicFile, "%d ", + elInfo-> + getElement()-> + getVertexOfPosition(INDEX_OF_DIM(dim-1, dim), + it->elementSide, + i) + ); + } + fprintf(periodicFile, "%d ", neighIndex); + for(i=0; i < dim; i++) { + fprintf(periodicFile, "%d", + vertexMap[elInfo-> + getElement()-> + getVertexOfPosition(INDEX_OF_DIM(dim-1, dim), + it->elementSide, + i)] + ); + fprintf(periodicFile, i < dim-1 ? " " : "\n"); + } + } + } + } + + return 0; + } + + int MacroWriter::indexFct(ElInfo *elInfo) + { + outputIndices[elInfo->getElement()->getIndex()] = ne++; + return 0; + } + +} diff --git a/AMDiS/src/MacroWriter.h b/AMDiS/src/MacroWriter.h new file mode 100644 index 0000000000000000000000000000000000000000..8ea7b4b217836407a2c549e1c6c70de3961bdf2c --- /dev/null +++ b/AMDiS/src/MacroWriter.h @@ -0,0 +1,181 @@ +// ============================================================================ +// == == +// == AMDiS - Adaptive multidimensional simulations == +// == == +// ============================================================================ +// == == +// == crystal growth group == +// == == +// == Stiftung caesar == +// == Ludwig-Erhard-Allee 2 == +// == 53175 Bonn == +// == germany == +// == == +// ============================================================================ +// == == +// == http://www.caesar.de/cg/AMDiS == +// == == +// ============================================================================ + +/** \file MacroWriter.h */ + +#ifndef AMDIS_MACROWRITER_H +#define AMDIS_MACROWRITER_H + +#include <list> +#include <vector> + +#include "VertexInfo.h" +#include "ElementInfo.h" +#include "DataCollector.h" +#include "MemoryManager.h" +#include "FixVec.h" +#include "Boundary.h" +#include "Projection.h" +#include "Flag.h" +#include "Mesh.h" + +namespace AMDiS { + + class VertexInfo; + class ElementInfo; + +class Mesh; +class ElInfo; +class FiniteElemSpace; +template<typename T> class DOFVector; +template<typename T> class DimVec; + +/** + * \ingroup Output + * + * \brief + * Writes the current leaf elements of a mesh as macro triangulation to + * a text file. Pure static class. + */ +class MacroWriter +{ +public: + /** \brief + * Stores a list of vertex infos for each dof. + */ + static DOFVector< ::std::list<VertexInfo> > *vertexInfos; + + /** \brief + * List that stores an ElementInfo for each element. + */ + static ::std::list<ElementInfo> elements; + +public: + MEMORY_MANAGED(MacroWriter); + + /** \brief + * Writes the leaf elements of a Mesh as a macro triangulation to a file. + */ + static int writeMacro(DataCollector *dc, + const char *name, + double time = 0.0, + int level = -1, + Flag traverseFlag = Mesh::CALL_LEAF_EL, + bool (*writeElem)(ElInfo*) = NULL); + + /** \brief + * Init \ref periodicFile for the next macro to be written. + */ + static void writePeriodicFile(DataCollector *dc, + const ::std::string filename); + + + // OBSOLETE + // TODO: Remove if MacroWriter::writeMacro is stable. + static int writeMacroOld(const FiniteElemSpace *aFESpace, + const char *name = NULL, + double time = 0.0, + int level = -1, + Flag traverseFlag = Mesh::CALL_LEAF_EL); + + // OBSOLETE + // TODO: Remove if MacroWriter::writePeriodic is stable. + static void writePeriodicFileOld(Mesh *aMesh, const ::std::string filename, + int level = -1, + Flag traverseFlag = Mesh::CALL_LEAF_EL); + +protected: + /** \brief + * creates output indices for each element. + */ + static int indexFct(ElInfo *elInfo); + + /** \brief + * Creates vertex infos for + */ + static int traverseFct(ElInfo* elInfo); + + /** \brief + * Used to generate global output indices and count the number of connections. + */ + static int periodicFct1(ElInfo *elInfo); + + /** \brief + * Writes periodic file entry for this element. + */ + static int periodicFct2(ElInfo *elInfo); + +protected: + /** \brief + * Mesh that should be written + */ + static Mesh *mesh; + + /** \brief + * File to which the mesh should be written + */ + static FILE *macroFile; + + /** \brief + * File in which the periodic infos are stored. + */ + static FILE *periodicFile; + + /** \brief + * vertex pre-dofs + */ + static int n0; + + /** \brief + * Number of vertices. + */ + static int nv; + + /** \brief + * Number of elements. + */ + static int ne; + + /** \brief + * Number of connections. + */ + static int nc; + + /** \brief + * Dimension of \ref mesh + */ + static int dim; + + /** \brief + * Maps internal element indices to global output indices. + */ + static ::std::map<int, int> outputIndices; + + /** \brief + * periodicConnections[i][j] stores whether the connection at side j of + * the element with output index i has already been written. + */ + static ::std::vector<DimVec<bool> > periodicConnections; + + static bool (*writeElement)(ElInfo*); +}; + +} + +#endif diff --git a/AMDiS/src/Marker.cc b/AMDiS/src/Marker.cc new file mode 100644 index 0000000000000000000000000000000000000000..1fa00a37539644c9853c0e937d6ad660cf4af6a9 --- /dev/null +++ b/AMDiS/src/Marker.cc @@ -0,0 +1,32 @@ +#include "Marker.h" + +namespace AMDiS { + + Marker *Marker::createMarker(::std::string name, int row) { + int strategy = 0; + GET_PARAMETER(0, name + "->strategy", "%d", &strategy); + + Marker *marker = NULL; + + switch(strategy) { + case 0: + break; + case 1: + marker = NEW GRMarker(name, row); + break; + case 2: + marker = NEW MSMarker(name, row); + break; + case 3: + marker = NEW ESMarker(name, row); + break; + case 4: + marker = NEW GERSMarker(name, row); + break; + default: ERROR_EXIT("invalid strategy\n"); + } + + return marker; + } + +} diff --git a/AMDiS/src/Marker.h b/AMDiS/src/Marker.h new file mode 100644 index 0000000000000000000000000000000000000000..f9e81158648341a40e5c19671e78700b2ae6abf0 --- /dev/null +++ b/AMDiS/src/Marker.h @@ -0,0 +1,569 @@ +// ============================================================================ +// == == +// == AMDiS - Adaptive multidimensional simulations == +// == == +// ============================================================================ +// == == +// == crystal growth group == +// == == +// == Stiftung caesar == +// == Ludwig-Erhard-Allee 2 == +// == 53175 Bonn == +// == germany == +// == == +// ============================================================================ +// == == +// == http://www.caesar.de/cg/AMDiS == +// == == +// ============================================================================ + +/** \file Marker.h */ + +#ifndef AMDIS_MARKER_H +#define AMDIS_MARKER_H + +#include "MemoryManager.h" +#include "Element.h" +#include "ElInfo.h" +#include "Flag.h" +#include "Mesh.h" +#include "AdaptInfo.h" +#include "Traverse.h" +#include "MatrixVector.h" + +namespace AMDiS { + + // =========================================================================== + // ===== class Marker ======================================================== + // =========================================================================== + + /** + * \ingroup Adaption + * + * \brief + * Base class for all scalar markers. + */ + class Marker + { + public: + /** \brief + * Constructor. + */ + Marker() {}; + + /** \brief + * Constructor. + */ + Marker(::std::string name_, int row_) + : name(name_), + row(row_), + maximumMarking(false), + p(2), + info(10) + { + GET_PARAMETER(0, name + "->p", "%f", &p); + GET_PARAMETER(0, name + "->info", "%d", &info); + }; + + /** \brief + * destructor + */ + virtual ~Marker() {}; + + /** \brief + * Marks element with newMark. If \ref maximumMarking is set, the element + * is marked only if the new mark is bigger than the old one. The return + * value specifies whether the element has been marked, or not. + */ + inline void setMark(Element *el, char newMark) { + char oldMark = el->getMark(); + + if (!maximumMarking || (newMark > oldMark)) { + el->setMark(newMark); + if (oldMark > 0) elMarkRefine--; else if(oldMark < 0) elMarkCoarsen--; + if (newMark > 0) elMarkRefine++; else if(newMark < 0) elMarkCoarsen++; + } + }; + + /** \brief + * Can be used by sub classes. Called before traversal. + */ + virtual void initMarking(AdaptInfo *adaptInfo, Mesh *mesh) { + elMarkRefine = 0; + elMarkCoarsen = 0; + estSum = pow(adaptInfo->getEstSum(row == -1 ? 0 : row), p); + estMax = adaptInfo->getEstMax(row == -1 ? 0 : row); + }; + + /** \brief + * Can be used by sub classes. Called after traversal. + */ + virtual void finishMarking(AdaptInfo *adaptInfo) { + FUNCNAME("Marker::finishMarking()"); + + INFO(info, 4)("%d elements marked for refinement\n", elMarkRefine); + INFO(info, 4)("%d elements marked for coarsening\n", elMarkCoarsen); + }; + + /** \brief + * Marks one element. + */ + virtual void markElement(AdaptInfo *adaptInfo, ElInfo *elInfo) { + Element *el = elInfo->getElement(); + double lError = el->getEstimation(row); + + if (adaptInfo->isRefinementAllowed(row == -1 ? 0 : row) && lError > markRLimit) { + setMark(el, adaptInfo->getRefineBisections(row == -1 ? 0 : row)); + } else { + if (adaptInfo->isCoarseningAllowed(row == -1 ? 0 : row) && lError <= markCLimit) { + if (!el->getElementData()->getElementData(COARSENABLE) || + (lError + el->getCoarseningEstimation(row)) <= markCLimit) { + setMark(el, -adaptInfo->getCoarseBisections(row == -1 ? 0 : row)); + } + } + } + }; + + /** \brief + * Marking of the mesh. + */ + virtual Flag markMesh(AdaptInfo *adaptInfo, Mesh *mesh) { + initMarking(adaptInfo, mesh); + + if (!adaptInfo->isCoarseningAllowed(row == -1 ? 0 : row) && + !adaptInfo->isRefinementAllowed(row == -1 ? 0 : row)) { + return 0; + } + + TraverseStack stack; + ElInfo *elInfo = NULL; + elInfo = stack.traverseFirst(mesh, -1, Mesh::CALL_LEAF_EL); + while (elInfo) { + markElement(adaptInfo, elInfo); + elInfo = stack.traverseNext(elInfo); + } + + finishMarking(adaptInfo); + + Flag markFlag; + if (elMarkRefine) markFlag = 1; + if (elMarkCoarsen) markFlag |= 2; + return(markFlag); + }; + + /** \brief + * Sets \ref maximumMarking. + */ + inline void setMaximumMarking(bool maxMark) { + maximumMarking = maxMark; + }; + + inline int getElMarkRefine() { + return elMarkRefine; }; + + inline int getElMarkCoarsen() { + return elMarkCoarsen; + }; + + /** \brief + * Creates a scalr marker depending on the strategy set in parameters. + */ + static Marker *createMarker(::std::string name, int row_); + + protected: + /** \brief + * Name of the scalar marker. + */ + ::std::string name; + + /** \brief + * Equal to -1 for scalar problems. Component number if marker is + * part of a vector valued marker. + */ + int row; + + /** \brief + * estimation sum + */ + double estSum; + + /** \brief + * estmation maximum + */ + double estMax; + + /** \brief + * If true, elements are marked only if the new value is bigger than + * the current marking. + */ + bool maximumMarking; + + /** \brief + * Lower limit for error estimation, from which an element is marked for + * refinement + */ + double markRLimit; + + /** \brief + * Upper limit for error estimation, from which an element is marked for + * coarsening + */ + double markCLimit; + + /** \brief + * power in estimator norm + */ + double p; + + /** \brief + * Info level. + */ + int info; + + /** \brief + * Counter for elements marked for refinement + */ + int elMarkRefine; + + /** \brief + * Counter for elements marked for coarsening + */ + int elMarkCoarsen; + + }; + + // =========================================================================== + // ===== class GRMarker ====================================================== + // =========================================================================== + + /** + * \ingroup Adaption + * + * \brief + * Global refinement. + */ + class GRMarker : public Marker + { + public: + MEMORY_MANAGED(GRMarker); + + /** \brief + * Constructor. + */ + GRMarker(::std::string name_, int row_) + : Marker(name_, row_) + {}; + + /** \brief + * Implementation of Marker::markElement(). + */ + virtual void markElement(AdaptInfo *adaptInfo, ElInfo *elInfo) { + Element *el = elInfo->getElement(); + if(adaptInfo->isRefinementAllowed(row == -1 ? 0 : row)) + setMark(el, adaptInfo->getRefineBisections(row == -1 ? 0 : row)); + }; + }; + + // =========================================================================== + // ===== class MSMarker ====================================================== + // =========================================================================== + + /** + * \ingroup Adaption + * + * \brief + * Maximum strategy. + */ + class MSMarker : public Marker + { + public: + MEMORY_MANAGED(MSMarker); + + /** \brief + * Constructor. + */ + MSMarker(::std::string name_, int row_) + : Marker(name_, row_), + MSGamma(0.5), + MSGammaC(0.1) + { + GET_PARAMETER(0, name + "->MSGamma", "%f", &MSGamma); + GET_PARAMETER(0, name + "->MSGammaC", "%f", &MSGammaC); + }; + + /** \brief + * Implementation of MarkScal::initMarking(). + */ + virtual void initMarking(AdaptInfo *adaptInfo, Mesh *mesh) { + Marker::initMarking(adaptInfo, mesh); + + double MSGammaP = pow(MSGamma, p); + double MSGammaCP = pow(MSGammaC, p); + + markRLimit = MSGammaP * adaptInfo->getEstMax(row == -1 ? 0 : row); + markCLimit = MSGammaCP * adaptInfo->getEstMax(row == -1 ? 0 : row); + }; + + protected: + /** \brief + * Marking parameter. + */ + double MSGamma; + + /** \brief + * Marking parameter. + */ + double MSGammaC; + }; + + // =========================================================================== + // ===== class ESMarker ====================================================== + // =========================================================================== + + /** + * \ingroup Adaption + * + * \brief + * Equidistribution strategy + */ + class ESMarker : public Marker + { + public: + MEMORY_MANAGED(ESMarker); + + /** \brief + * Constructor. + */ + ESMarker(::std::string name_, int row_) + : Marker(name_, row_), + ESTheta(0.9), + ESThetaC(0.2) + { + GET_PARAMETER(0, name + "->ESTheta", "%f", &ESTheta); + GET_PARAMETER(0, name + "->ESThetaC", "%f", &ESThetaC); + }; + + /** \brief + * Implementation of MarkScal::initMarking(). + */ + virtual void initMarking(AdaptInfo *adaptInfo, Mesh *mesh) { + FUNCNAME("ESMarker::initMarking()"); + + Marker::initMarking(adaptInfo, mesh); + + double ESThetaP = pow(ESTheta, p); + double ESThetaCP = pow(ESThetaC, p); + + double epsP = pow(adaptInfo->getSpaceTolerance(row == -1 ? 0 : row), p); + + markRLimit = ESThetaP * epsP / mesh->getNumberOfLeaves(); + markCLimit = ESThetaCP * epsP / mesh->getNumberOfLeaves(); + + INFO(info, 2) + ("start mark_limits: %.3le %.3le nt=%d\n", + markRLimit, markCLimit, mesh->getNumberOfLeaves()); + }; + + protected: + /** \brief + * Marking parameter. + */ + double ESTheta; + + /** \brief + * Marking parameter. + */ + double ESThetaC; + }; + + // =========================================================================== + // ===== class GERSMarker ==================================================== + // =========================================================================== + + /** + * \ingroup Adaption + * + * \brief + * Guaranteed error reduction strategy + */ + class GERSMarker : public Marker + { + public: + MEMORY_MANAGED(GERSMarker); + + /** \brief + * Constructor. + */ + GERSMarker(::std::string name_, int row_) + : Marker(name_, row_), + oldErrSum(0.0), + GERSThetaStar(0.6), + GERSNu(0.1), + GERSThetaC(0.1) + { + GET_PARAMETER(0, name + "->GERSThetaStar", "%f", &GERSThetaStar); + GET_PARAMETER(0, name + "->GERSNu", "%f", &GERSNu); + GET_PARAMETER(0, name + "->GERSThetaC", "%f", &GERSThetaC); + }; + + /** \brief + * Implementation of Marker::markMesh(). + */ + virtual Flag markMesh(AdaptInfo *adaptInfo, Mesh *mesh) { + FUNCNAME("GERSMarker::markMesh()"); + + initMarking(adaptInfo, mesh); + + if(!adaptInfo->isCoarseningAllowed(row == -1 ? 0 : row) && + !adaptInfo->isRefinementAllowed(row == -1 ? 0 : row)) + { + return 0; + } + + GERSSum = 0.0; + + double LTheta = pow(1.0 - GERSThetaStar, p); + double improv, redfac, wanted, epsP, GERSGamma; + + epsP = pow(adaptInfo->getSpaceTolerance(row == -1 ? 0 : row), p); + + if(estSum < oldErrSum) { + improv = estSum / oldErrSum; + wanted = 0.8 * epsP / estSum; + redfac = ::std::min((1.0 - wanted) / (1.0 - improv), 1.0); + redfac = ::std::max(redfac, 0.0); + + if(redfac < 1.0) { + LTheta *= redfac; + INFO(info, 1) + ("GERS: use extrapolated theta_star = %lf\n", + pow(LTheta, 1.0 / p)); + } + } + + oldErrSum = estSum; + + GERSGamma = 1.0; + + if(adaptInfo->isRefinementAllowed(row == -1 ? 0 : row)) { + if(LTheta > 0) { + do { + GERSSum = 0.0; + + GERSGamma -= GERSNu; + markRLimit = GERSGamma * estMax; + + TraverseStack stack; + ElInfo *elInfo = NULL; + elInfo = stack.traverseFirst(mesh, -1, Mesh::CALL_LEAF_EL); + while(elInfo) { + markElementForRefinement(adaptInfo, elInfo); + elInfo = stack.traverseNext(elInfo); + } + + } while((GERSGamma > 0) && (GERSSum < LTheta * estSum)); + } + + INFO(info, 2) + ("GERS refinement with gamma = %.3lf\n", GERSGamma); + } + + if(adaptInfo->isCoarseningAllowed(row == -1 ? 0 : row)) { + GERSGamma = 0.3; + LTheta = GERSThetaC * epsP; + + do { + GERSSum = 0.0; + GERSGamma -= GERSNu; + markCLimit = GERSGamma * estMax; + + TraverseStack stack; + ElInfo *elInfo = NULL; + elInfo = stack.traverseFirst(mesh, -1, Mesh::CALL_LEAF_EL); + while(elInfo) { + markElementForCoarsening(adaptInfo, elInfo); + elInfo = stack.traverseNext(elInfo); + } + + INFO(info, 6) + ("coarse loop: gamma=%.3e, sum=%.3e, limit=%.3e\n", + GERSGamma, GERSSum, LTheta); + } while(GERSSum > LTheta); + + INFO(info, 2) + ("GERS coarsening with gamma = %.3lf\n", GERSGamma); + } + + finishMarking(adaptInfo); + + Flag markFlag; + if(elMarkRefine) markFlag = 1; + if(elMarkCoarsen) markFlag |= 2; + return(markFlag); + }; + + protected: + /** \brief + * Refinement marking function. + */ + void markElementForRefinement(AdaptInfo *adaptInfo, ElInfo *elInfo) { + Element *el = elInfo->getElement(); + double lError = el->getEstimation(row); + + if (lError > markRLimit) { + GERSSum += lError; + setMark(el, adaptInfo->getRefineBisections(row == -1 ? 0 : row)); + } + }; + + /** \brief + * Coarsening marking function. + */ + void markElementForCoarsening(AdaptInfo *adaptInfo, ElInfo *elInfo) { + Element *el = elInfo->getElement(); + double lError = el->getEstimation(row); + + if(el->getMark() <= 0) { + if(el->getElementData()->getElementData(COARSENABLE)) { + lError += el->getCoarseningEstimation(row); + } + + if(lError <= markCLimit) { + GERSSum += lError; + setMark(el, -adaptInfo->getCoarseBisections(row == -1 ? 0 : row)); + } else { + setMark(el, 0); + } + } + }; + + protected: + /** \brief + * Marking parameter. + */ + double GERSSum; + + /** \brief + * Marking parameter. + */ + double oldErrSum; + + /** \brief + * Marking parameter. + */ + double GERSThetaStar; + + /** \brief + * Marking parameter. + */ + double GERSNu; + + /** \brief + * Marking parameter. + */ + double GERSThetaC; + }; + +} + +#endif diff --git a/AMDiS/src/MatVecMultiplier.cc b/AMDiS/src/MatVecMultiplier.cc new file mode 100644 index 0000000000000000000000000000000000000000..f2c3595f180b5f96bc4a5aa9ba96416805ef56c5 --- /dev/null +++ b/AMDiS/src/MatVecMultiplier.cc @@ -0,0 +1,172 @@ +#include <iostream> +#include <fstream> +#include <vector> +#include "time.h" +#include "MatVecMultiplier.h" +#include "FiniteElemSpace.h" +#include "DOFMatrix.h" +#include "DOFVector.h" +#include "MatrixVector.h" +#include "SystemVector.h" +#include "V3Vector.h" + +namespace AMDiS { + + template<> void + StandardMatVec<DOFMatrix, DOFVector<double> >::matVec(MatrixTranspose transpose, + const DOFVector<double> &x, + DOFVector<double> &result, + bool add) + { + FUNCNAME("StandardMatVec::matVec()"); + + TEST_EXIT((x.getFESpace() == matrix->getColFESpace())) + ("finite element spaces of matrix and x must be the same!\n"); + + mv(transpose, *matrix, x, result, add); + } + + template <> void + StandardMatVec<Matrix<DOFMatrix*>, SystemVector>::matVec(MatrixTranspose transpose, + const SystemVector &x, + SystemVector &result, + bool add) + { + mv(*matrix, x, result); + } + + + + template<> void + StandardMatVec< ::std::vector< ::std::vector<MatEntry> >, + ::std::vector<double> >::matVec(MatrixTranspose transpose, + const ::std::vector<double> &x, + ::std::vector<double> &result, + bool add) + { + FUNCNAME("StandardMatVec::matVec()"); + + unsigned int nRows = matrix->size(); + + TEST_EXIT(x.size() == nRows)("SIZE!\n"); + TEST_EXIT(result.size() == nRows)("SIZE!\n"); + + if (!add) { + for (unsigned int i = 0; i < nRows; i++) { + result[i] = 0.0; + } + } + + for (unsigned int row = 0; row < nRows; row++) { + for (unsigned int col = 0; col < (*matrix)[row].size(); col++) { + MatEntry *m = &(*matrix)[row][col]; + + result[row] += m->entry * x[m->col]; + } + } + } + + template<> + void MassLumpingMatVec<DOFMatrix, DOFVector<double> >::calcMassLumpingMatrix(DOFMatrix *m) + { + // create new or clear old matrix + if (!matrix) { + matrix = NEW DOFMatrix(m->getRowFESpace(), + m->getColFESpace(), + "mass lumping matrix"); + } + else { + matrix->clear(); + } + + // for all rows + DOFMatrix::Iterator rowIt1(m, USED_DOFS); + DOFMatrix::Iterator rowIt2(matrix, USED_DOFS); + for (rowIt1.reset(), rowIt2.reset(); + !rowIt1.end(); + ++rowIt1, ++rowIt2) + { + double rowSum = 0.0; + int rowSize = static_cast<int>(rowIt1->size()); + + for (int i = 0; i < rowSize; i++) { + if ((*rowIt1)[i].col == DOFMatrix::NO_MORE_ENTRIES) { + break; + } + if ((*rowIt1)[i].col == DOFMatrix::UNUSED_ENTRY) { + continue; + } + + double entry = (*rowIt1)[i].entry; + + TEST_EXIT(entry >= 0)("entries must be >= 0\n"); + + rowSum += entry; + } + + TEST_EXIT(rowSum > 1E-20)("matrix not inversable\n"); + + (*rowIt2).resize(1); + (*rowIt2)[0].col = rowIt2.getDOFIndex(); + (*rowIt2)[0].entry = 1.0 / rowSum; + } + } + + template<> + void MassLumpingMatVec<Matrix<DOFMatrix*>, SystemVector>::calcMassLumpingMatrix(Matrix<DOFMatrix*> *m) + { + int numComponents = m->getNumRows(); + // create new or clear old matrix + if(!matrix) { + matrix = NEW Matrix<DOFMatrix*>(numComponents, numComponents); + for (int i = 0; i < numComponents; i++) { + (*matrix)[i][i] = NEW DOFMatrix((*m)[i][i]->getRowFESpace(), + (*m)[i][i]->getColFESpace(), + "mass lumping matrix"); + } + } + else { + for (int i = 0; i < numComponents; i++) + (*matrix)[i][i]->clear(); + } + + // for all rows + for (int i = 0; i < numComponents; i++) { + DOFMatrix::Iterator rowIt1((*m)[i][i], USED_DOFS); + DOFMatrix::Iterator rowIt2((*matrix)[i][i], USED_DOFS); + for (rowIt1.reset(), rowIt2.reset(); + !rowIt1.end(); + ++rowIt1, ++rowIt2) + { + double rowSum = 0.0; + int rowSize = static_cast<int>(rowIt1->size()); + + for (int j = 0; j < rowSize; j++) { + if((*rowIt1)[j].col == DOFMatrix::NO_MORE_ENTRIES) { + break; + } + if((*rowIt1)[j].col == DOFMatrix::UNUSED_ENTRY) { + continue; + } + + double entry = (*rowIt1)[j].entry; + + TEST_EXIT(entry >= 0)("entries must be >= 0\n"); + + rowSum += entry; + } + + TEST_EXIT(rowSum > 1E-20)("matrix not inversable\n"); + + (*rowIt2).resize(1); + (*rowIt2)[0].col = rowIt2.getDOFIndex(); + (*rowIt2)[0].entry = 1.0 / rowSum; + } + } + } + + + StandardMatVec<Matrix<DOFMatrix*>, SystemVector> _enf_(NULL); + StandardMatVec<DOFMatrix, DOFVector<double> > _grmpf_(NULL); + +} diff --git a/AMDiS/src/MatVecMultiplier.h b/AMDiS/src/MatVecMultiplier.h new file mode 100644 index 0000000000000000000000000000000000000000..5a1e575c9fc49398ea540f68b5d83375556d316a --- /dev/null +++ b/AMDiS/src/MatVecMultiplier.h @@ -0,0 +1,188 @@ +// ============================================================================ +// == == +// == AMDiS - Adaptive multidimensional simulations == +// == == +// ============================================================================ +// == == +// == crystal growth group == +// == == +// == Stiftung caesar == +// == Ludwig-Erhard-Allee 2 == +// == 53175 Bonn == +// == germany == +// == == +// ============================================================================ +// == == +// == http://www.caesar.de/cg/AMDiS == +// == == +// ============================================================================ + +/** \file MatVecMultipler.h */ + +#ifndef AMDIS_MATVECMULTIPLIER_H +#define AMDIS_MATVECMULTIPLIER_H + +#include<vector> + +#include "Global.h" +#include "MemoryManager.h" +//#include "Boundary.h" +#include "DOFVector.h" +#include "DOFMatrix.h" +#include "MatrixVector.h" +#include "time.h" + +namespace AMDiS { + + template<typename T> class DOFVector; + + // =========================================================================== + // ===== class MatVecMultiplier ============================================== + // =========================================================================== + + /** + * \ingroup Solver + * + * \brief + * Interface for matrix-vector multiplication. + */ + template<typename Vector> + class MatVecMultiplier + { + public: + MEMORY_MANAGED(MatVecMultiplier); + + /** \brief + * Destructor. + */ + virtual ~MatVecMultiplier() {}; + + /** \brief + * To be overloaded by concrete implementations. + */ + virtual void matVec(MatrixTranspose transpose, + const Vector &vec, + Vector &result, + bool add = false) = 0; + }; + + // =========================================================================== + // ===== class StandardMatVec ================================================ + // =========================================================================== + + /** + * \ingroup Solver + * + * \brief + * Implementation of the standard matrix vector multiplication. + */ + template<typename MatrixType, typename VectorType> + class StandardMatVec : public MatVecMultiplier<VectorType> + { + public: + MEMORY_MANAGED(StandardMatVec<MatrixType COMMA VectorType>); + + /** \brief + * + */ + StandardMatVec(MatrixType *mat) + : matrix(mat) + {}; + + virtual ~StandardMatVec() {}; + + /** \brief + * Implements \ref MatVecMultiplier::matVec(). + */ + virtual void matVec(MatrixTranspose transpose, + const VectorType &x, + VectorType &result, + bool add = false) { + FUNCNAME("StandardMatVec::matVec()"); + + WARNING("Non specialised function should not be called\n"); + }; + + /** \brief + * Sets \ref matrix. + */ + virtual void setMatrix(MatrixType *m) { + matrix = m; + }; + + virtual MatrixType* getMatrix() { + return matrix; + }; + + virtual const MatrixType* getMatrix() const { + return matrix; + }; + + protected: + /** \brief + * Matrix used for matrix-vector multiplication. + */ + MatrixType *matrix; + }; + + + + template<typename MatrixType, typename VectorType> + class MassLumpingMatVec : public StandardMatVec<MatrixType, VectorType> + { + public: + /** + * Empty constructor. + */ + MassLumpingMatVec() + : StandardMatVec<MatrixType, VectorType>(NULL) + {}; + + /** \brief + * + */ + MassLumpingMatVec(MatrixType *mat) + : StandardMatVec<MatrixType, VectorType>(NULL) + { + calcMassLumpingMatrix(mat); + }; + + virtual ~MassLumpingMatVec() { + if (this->matrix) + DELETE this->matrix; + }; + + /** \brief + * Sets \ref matrix. + */ + void setMatrix(MatrixType *m) { + FUNCNAME("MassLumpingMatVec::setMatrix()"); + + ERROR_EXIT("should not be called\n"); + }; + + void calcMassLumpingMatrix(MatrixType *m); + }; + + + + template<> void + StandardMatVec<DOFMatrix, DOFVector<double> >::matVec(MatrixTranspose transpose, + const DOFVector<double> &x, + DOFVector<double> &result, + bool add); + + + class SystemVector; + + template <> void + StandardMatVec<Matrix<DOFMatrix*>, SystemVector>::matVec( + MatrixTranspose transpose, + const SystemVector &x, + SystemVector &result, + bool add + ); + + +} +#endif // AMDIS_MATVECMULTIPLIER_H diff --git a/AMDiS/src/MatrixVector.cc b/AMDiS/src/MatrixVector.cc new file mode 100644 index 0000000000000000000000000000000000000000..7cbaadb260d3bfd06073122e8875f1968b84604a --- /dev/null +++ b/AMDiS/src/MatrixVector.cc @@ -0,0 +1,9 @@ +#include "MatrixVector.h" +#include "DOFVector.h" + +namespace AMDiS { + +} + + + diff --git a/AMDiS/src/MatrixVector.h b/AMDiS/src/MatrixVector.h new file mode 100644 index 0000000000000000000000000000000000000000..f6ff2a5d9b2a962d5e503789fc4e31f689e5d05d --- /dev/null +++ b/AMDiS/src/MatrixVector.h @@ -0,0 +1,608 @@ +// ============================================================================ +// == == +// == AMDiS - Adaptive multidimensional simulations == +// == == +// ============================================================================ +// == == +// == crystal growth group == +// == == +// == Stiftung caesar == +// == Ludwig-Erhard-Allee 2 == +// == 53175 Bonn == +// == germany == +// == == +// ============================================================================ +// == == +// == http://www.caesar.de/cg/AMDiS == +// == == +// ============================================================================ + +/** \file MatrixVector.h */ + +#ifndef AMDIS_MATRIXVECTOR_H +#define AMDIS_MATRIXVECTOR_H + +#include <vector> +#include "Global.h" +#include "MemoryManager.h" +#include "Serializable.h" + +namespace AMDiS { + + template<typename T> class DOFVector; + + // ============================================================================ + // ===== class Vector ========================================================= + // ============================================================================ + + /** \brief + * Class for efficient vector operations of fixed size numerical vectors. + */ + template<typename T> + class Vector : public Serializable + { + public: + MEMORY_MANAGED(Vector<T>); + + /** \brief + * Constructor. + */ + Vector(int i = 0) + : size(i) + { + if (size == 0) + valArray = NULL; + else + valArray = new T[size]; + }; + + inline bool used() const + { + return (valArray != NULL); + }; + + /** \brief + * Change the size of the vector to newSize. + */ + inline void resize(int newSize) { + if (size != newSize) { + if (valArray) + delete [] valArray; + valArray = new T[newSize]; + size = newSize; + } + }; + + /** \brief + * Copy constructor. + */ + Vector(const Vector<T>& rhs) + : Serializable(),size(rhs.size) + { + valArray = new T[rhs.size]; + *this = rhs; // uses operator=() + }; + + /** \brief + * Destructor. + */ + virtual ~Vector() { + delete [] valArray; + }; + + /** \brief + * Assignement operator + */ + inline const Vector<T>& operator=(const Vector<T>& rhs) { + TEST_EXIT(rhs.size == size)("invalid size\n"); + T *rhsIt, *thisIt; + for(rhsIt = rhs.begin(), thisIt = this->begin(); + rhsIt != rhs.end(); + ++rhsIt, ++thisIt) + { + *thisIt = *rhsIt; + } + return *this; + }; + + /** \brief + * Assignement operator + */ + inline const Vector<T>& operator=(const T& scal) { + T *thisIt; + for(thisIt = this->begin(); + thisIt != this->end(); + ++thisIt) + { + *thisIt = scal; + } + return *this; + }; + + /** \brief + * Assignement operator + */ + inline const Vector<T>& operator=(const T* vec) { + T *thisIt; + const T *vecIt; + for(thisIt = this->begin(), vecIt = &vec[0]; + thisIt != this->end(); + ++thisIt, ++vecIt) + { + *thisIt = *vecIt; + } + return *this; + }; + + /** \brief + * Sets all entries to scal. + */ + inline const Vector<T>& set(const T& scal) { + return *this = scal; + }; + + /** \brief + * Sets all entries. + */ + inline const Vector<T>& setValues(const T* values) { + T *thisIt; + const T *valuesIt; + for(thisIt = this->begin(), valuesIt = values; + thisIt != this->end(); + ++thisIt, ++valuesIt) + { + *thisIt = *valuesIt; + } + return *this; + }; + + /** \brief + * Sets all entries. + */ + inline void fill(const T value) { + for (T *thisIt = this->begin(); thisIt != this->end(); thisIt++) { + *thisIt = value; + } + } + + /** \brief + * Comparison operator. + */ + inline bool operator==(const Vector<T>& rhs) const { + if(size != rhs.size) return false; + T *rhsIt, *thisIt; + for(rhsIt = rhs.begin(), thisIt = this->begin(); + rhsIt != rhs.end(); + ++rhsIt, ++thisIt) + { + if(*thisIt != *rhsIt) return false; + } + return true; + }; + + /** \brief + * Comparison operator. + */ + inline bool operator!=(const Vector<T>& rhs) const { + return !(*this==rhs); + } + + /** \brief + * Access to the i-th vector element. + */ + inline T& operator[](int i) { + TEST_EXIT(i < size && i >= 0)("invalid index\n"); + return valArray[i]; + }; + + /** \brief + * Access to the i-th vector element for const vectors. + */ + inline const T& operator[] (int i) const { + TEST_EXIT(i < size && i >= 0)("invalid index\n"); + return valArray[i]; + }; + + /** \brief + * Returns pointer to the first vector element. + */ + inline T *begin() const { + return valArray; + }; + + /** \brief + * Returns pointer after the last vector element. + */ + inline T *end() const { + return valArray + size; + }; + + /** \brief + * Returns \ref size. + */ + virtual int getSize() const { + return size; + }; + + /** \brief + * Returns \ref valArray as T-array + */ + inline T *getValArray() { + return valArray; + }; + + void print() const { + ::std::cout << this->size << " vector: " << ::std::endl; + for (int i = 0; i < size; i++) { + ::std::cout << this->valArray[i] << " "; + } + ::std::cout << ::std::endl; + }; + + // ===== Serializable implementation ===== + + void serialize(::std::ostream &out) { + out.write(reinterpret_cast<const char*>(&size), sizeof(int)); + out.write(reinterpret_cast<const char*>(valArray), size * sizeof(T)); + }; + + void deserialize(::std::istream &in) { + in.read(reinterpret_cast<char*>(&size), sizeof(int)); + in.read(reinterpret_cast<char*>(valArray), size * sizeof(T)); + }; + + ::std::string getTypeName() const { + return "Vector"; + }; + + protected: + /** \brief + * Size of the vector. + */ + int size; + + /** \brief + * Internal storage pointer. + */ + T *valArray; + }; + + + + // ============================================================================ + // ===== class Matrix ========================================================= + // ============================================================================ + + /** \brief + * Class for efficient matrix operations of fixed size numerical matrices. + */ + template<typename T> + class Matrix : public Vector<T> + { + public: + MEMORY_MANAGED(Matrix<T>); + + /** \brief + * Constructor. + */ + Matrix(int r, int c) + : Vector<T>(r*c), + rows(r), + cols(c) + {}; + + /** \brief + * Changes the size of the matrix to newRows x newCols. + */ + inline void resize(int newRows, int newCols) { + if ((newRows != rows) || (newCols != cols)) { + Vector<T>::resize(newRows * newCols); + rows = newRows; + cols = newCols; + } + }; + + /** \brief + * Assignement operator. + */ + inline const Matrix<T>& operator=(const T& scal) + { + return static_cast<const Matrix<T>&>(Vector<T>::operator=(scal)); + }; + + inline bool operator==(const Matrix<T>& rhs) const + { + if (rows != rhs.getNumRows()) return false; + if (cols != rhs.getNumCols()) return false; + return Vector<T>::operator == (rhs); + }; + + /** \brief + * Comparison operator. + */ + inline bool operator!=(const Matrix<T>& rhs) const + { + return !(*this==rhs); + } + + /** \brief + * Acces to i-th matrix row. + */ + inline T *operator[](int i) + { + return this->valArray + cols * i; + }; + + /** \brief + * Acces to i-th matrix row for constant matrices. + */ + inline const T *operator[](int i) const + { + return this->valArray + cols * i; + }; + + /** \brief + * Returns \ref rows. + */ + inline int getNumRows() const + { + return rows; + }; + + /** \brief + * Return \ref cols. + */ + inline int getNumCols() const + { + return cols; + }; + + /** \brief + * Returns \ref rows. + */ + inline int getSize() const + { + return rows; + }; + + /** \brief + * Returns pointer after the last vector element. + */ + inline T *end() const { + return this->valArray + (cols * rows); + }; + + void print() const { + ::std::cout << this->rows << " x " << this->cols << " matrix: " << ::std::endl; + for (int i = 0; i < rows; i++) { + for (int j = 0; j < cols; j++) { + ::std::cout << this->valArray[i * cols + j] << " "; + } + ::std::cout << ::std::endl; + } + }; + + protected: + /** \brief + * Number of matrix rows. + */ + int rows; + + /** \brief + * Number of matrix columns. + */ + int cols; + }; + + /** \brief + * Matrix vector multiplication. + */ + template<typename T> + inline const Vector<T>& mv(const Matrix<T>& m, const Vector<T>& v, Vector<T>& result) + { + TEST_EXIT(m.getNumCols() == v.getSize())("m and v not compatible\n"); + TEST_EXIT(v.getSize() == result.getSize())("wrong result size\n"); + + T *resultIt, *mIt, *vIt; + + for (resultIt = result.begin(), mIt = m.begin(); + resultIt != result.end(); + ++resultIt) + { + *resultIt = 0; + for (vIt = v.begin(); vIt != v.end(); ++vIt, ++mIt) { + *resultIt += *mIt * *vIt; + } + } + return result; + }; + + /** \brief + * Matrix vector multiplication. + */ + template<typename T> + inline const Vector<T>& operator*=(const Vector<T>& v, const Matrix<T>& m) + { + return mv(m, v, v); + }; + + /** \brief + * Matrix vector multiplication. + */ + template<typename T> + inline Vector<T> operator*(const Matrix<T>& m, const Vector<T>& v) + { + Vector<T> result(v.getSize()); + return mv(m, v, result); + }; + + + /** \brief + * Scalar product. + */ + template<typename T> + inline double operator*(const Vector<T>& v1, const Vector<T>& v2) + { + double result = 0; + + T *v1It, *v2It; + for (v1It = v1.begin(), v2It = v2.begin(); + v1It != v1.end(); + ++v1It, ++v2It) + { + result += *v1It * *v2It; + } + + return result; + }; + + /** \brief + * Vector addition. + */ + template<typename T> + inline const Vector<T>& add(const Vector<T>& v1, const Vector<T>& v2, Vector<T>& result) + { + TEST_EXIT(v1.getSize() == v2.getSize())("invalid size\n"); + TEST_EXIT(v2.getSize() == result.getSize())("invalid size\n"); + T *v1It, *v2It, *resultIt; + for (v1It = v1.begin(), v2It = v2.begin(), resultIt = result.begin(); + v1It != v1.end(); + ++v1It, ++v2It, ++resultIt) + { + *resultIt = *v1It + *v2It; + } + + return result; + }; + + /** \brief + * scalar * vector + */ + template<typename T> + inline const Vector<T>& mult(const T& scal, + const Vector<T>& v, + Vector<T>& result) + { + TEST_EXIT(v.getSize() == result.getSize())("invalid size\n"); + T *vIt, *resultIt; + for (vIt = v.begin(), resultIt = result.begin(); + vIt != v.end(); + ++vIt, ++resultIt) + { + *resultIt = scal * *vIt; + } + + return result; + }; + + /** \brief + * vector + scalar + */ + template<typename T> + inline const Vector<T>& add(const Vector<T>& v, const T& scal, Vector<T>& result) + { + TEST_EXIT(v.getSize() == result.getSize())("invalid size\n"); + T *vIt, *resultIt; + for (vIt = v.begin(), resultIt = result.begin(); + vIt != v.end(); + ++vIt, ++resultIt) + { + *resultIt = *vIt + scal; + } + + return result; + }; + + /** \brief + * y = a * x + y. + */ + template<typename T> + inline const Vector<T>& axpy(const T& a, + const Vector<T> &x, + Vector<T> &y) + { + TEST_EXIT(x.getSize() == y.getSize())("invalid size\n"); + T *xIt, *yIt; + for (xIt = x.begin(), yIt = y.begin(); + xIt != x.end(); + ++xIt, ++yIt) + { + *yIt += a * *xIt; + } + + return y; + }; + + template<typename T> + inline const Vector<T>& operator*=(Vector<T>& v, const T& scal) + { + return mult(scal, v, v); + }; + + template<typename T> + inline Vector<T> operator*(const Vector<T>& v, const T& scal) + { + Vector<T> result = v; + result *= scal; + return result; + }; + + template<typename T> + inline const Vector<T>& operator+(const Vector<T>& v1, const T& scal) + { + Vector<T> result(v1.getSize()); + return add(v1, scal, result); + }; + + template<typename T> + inline const Vector<T>& operator+=(Vector<T>& v1, const Vector<T>& v2) + { + return add(v1, v2, v1); + }; + + template<typename T> + inline Vector<T> operator+(const Vector<T>& v1, const Vector<T>& v2) + { + Vector<T> result = v1; + result += v2; + return result; + }; + + template<typename T> + const Vector<T>& operator-=(Vector<T>& v1, const Vector<T>& v2){ + return axpy(-1.0, v2, v1); + }; + + template<typename T> + Vector<T> operator-(const Vector<T>& v1, const Vector<T>& v2){ + Vector<T> result = v1; + result -= v2; + return result; + }; + + template<typename T> + inline double norm(const Vector<T> *v) + { + T *vIt; + double result = 0; + for (vIt = v->begin(); vIt != v->end(); ++vIt) { + result += *vIt * *vIt; + } + return sqrt(result); + }; + + template<typename T> + void vectorProduct(const Vector<T>& x, + const Vector<T>& y, + Vector<T>& z) + { + FUNCNAME("vectorProduct"); + TEST_EXIT(Global::getGeo(WORLD) == 3)("DIM_OF_WORLD != 3\n"); + z[0] = x[1] * y[2] - x[2] * y[1]; + z[1] = x[2] * y[0] - x[0] * y[2]; + z[2] = x[0] * y[1] - x[1] * y[0]; + }; + +} + +#endif // AMDIS_MATRIXVECTOR_H diff --git a/AMDiS/src/MemoryManager.cc b/AMDiS/src/MemoryManager.cc new file mode 100644 index 0000000000000000000000000000000000000000..b39c71bbc65f2dd0ba3a0386d1accf61972dcba9 --- /dev/null +++ b/AMDiS/src/MemoryManager.cc @@ -0,0 +1,26 @@ +#include "MemoryManager.h" + +namespace AMDiS { + + unsigned long MemoryManagerBase::byteCount = 0; + unsigned long MemoryManagerBase::idCounter = 0; + ::std::vector<MemoryManagerBase*> MemoryManagerBase::memoryManagers; + ::std::vector<MemoryMonitor*> MemoryManagerBase::memoryMonitors; + + void MemoryManagerBase::addMemoryMonitor(MemoryMonitor* monitor) { + memoryMonitors.push_back(monitor); + ::std::vector<MemoryManagerBase*>::iterator it; + for(it = memoryManagers.begin(); it != memoryManagers.end(); it++) { + monitor->addInstanceCounter((*it)->newInstanceCounter()); + } + } + + void MemoryManagerBase::removeMemoryMonitor(MemoryMonitor* monitor) { + ::std::vector<MemoryMonitor*>::iterator it; + it = find(memoryMonitors.begin(), memoryMonitors.end(), monitor); + if(it != memoryMonitors.end()) { + memoryMonitors.erase(it); + } + } + +} diff --git a/AMDiS/src/MemoryManager.h b/AMDiS/src/MemoryManager.h new file mode 100644 index 0000000000000000000000000000000000000000..d6daea3951d33860a7dffc9dbd5e4e5403abc4db --- /dev/null +++ b/AMDiS/src/MemoryManager.h @@ -0,0 +1,645 @@ +// ============================================================================ +// == == +// == AMDiS - Adaptive multidimensional simulations == +// == == +// ============================================================================ +// == == +// == crystal growth group == +// == == +// == Stiftung caesar == +// == Ludwig-Erhard-Allee 2 == +// == 53175 Bonn == +// == germany == +// == == +// ============================================================================ +// == == +// == http://www.caesar.de/cg/AMDiS == +// == == +// ============================================================================ + +/** \file MemoryManager.h */ + +/** \defgroup Memory Memory management module + * @{ <img src="memory.png"> @} + * + * \brief + * Memory monitoring and preallocation. + */ + +#ifndef AMDIS_MEMORYMANAGER_H +#define AMDIS_MEMORYMANAGER_H + +#include "Global.h" +#include "MemoryPool.h" +#include <vector> +#include <string> +#include <typeinfo> +#include <algorithm> +#include <functional> +#include <fstream> + +namespace AMDiS { + + class MemoryMonitor; + class InstanceCounterBase; + template<typename T> class InstanceCounter; + + // ============================================================================ + // ===== class MemoryManagerBase ============================================== + // ============================================================================ + + /** \ingroup Memory + * \brief + * MemoryManagerBase is the template type independent base class of + * MemoryManager. It holds a static vector of all concrete MemoryManagers, + * so a memory statistic for all managed types can be printed by + * \ref printStatistics(). A concrete MemoryManager class in general is + * a static class, so memory operations can be done without an instance of + * a MemoryManager. But MemoryManagerBase should be able to handle + * different concrete MemoryManagers without knowing their exact types. + * Therefore a concrete MemoryManager must have a singleton instance too, + * which gives MemoryManagerBase access to its static members by pointing + * to this singleton instance. + * + * <img src = "memory.png"> + */ + class MemoryManagerBase + { + public: + /** \brief + * Destructor does nothing + */ + virtual ~MemoryManagerBase() {}; + + /** \brief + * Prints the number of currently allocated bytes (\ref byteCount) and for + * all MemoryManagers in \ref memoryManagers the number of currently + * allocated instances. + */ + static void printStatistics() { + FUNCNAME("MemoryManagerBase::printStatistics()"); + + const char* pl="s\n"; + const char* sg="\n"; + + sort(memoryManagers.begin(), memoryManagers.end(), orderInstanceCount()); + ::std::vector<MemoryManagerBase*>::iterator it; + MSG("================================================================\n"); + MSG("memory statistics:\n"); + MSG("==================\n"); + MSG("byte count: %ld\n", byteCount); + for(it = memoryManagers.begin(); it != memoryManagers.end(); it++) { + if((*it)->instanceCount != 0) { + MSG("%s, id = %ld : %ld instance%s", + (*it)->getName().c_str(), (*it)->typeId, (*it)->instanceCount,((*it)->instanceCount > 1)?pl:sg); + // if((*it)->instanceCount > 1) + // MSG("s"); + // MSG("\n"); + } + } + MSG("================================================================\n"); + }; + + /** \brief + * Must be overriden for concrete MemoryManagers. Returns the name of + * the managed data type. Can be accessed via the singleton pointer of + * MemoryManager<T>. + */ + virtual ::std::string getName() = 0; + + /** \brief + * Returns the number of currently allocated instances (\ref instanceCount). + */ + inline unsigned long int getInstanceCount() { + return instanceCount; + }; + + /** \brief + * Returns the number of currently allocated bytes (\ref typedByteCount). + */ + inline unsigned long int getTypedByteCount() { + return typedByteCount; + }; + + /** \brief + * Returns a new InstanceCounter for concrete type + * Must be overloaded by a concrete MemoryManager<T>. + */ + virtual InstanceCounterBase* newInstanceCounter() = 0; + + /** \brief + * Register a new MemoryMonitor + */ + static void addMemoryMonitor(MemoryMonitor* monitor); + + /** \brief + * Remove a registered MemoryMonitor + */ + static void removeMemoryMonitor(MemoryMonitor* monitor); + + protected: + /** \brief + * Used in \ref printStatistics() to sort the MemoryManagers by the number + * of currently allocated instances. + */ + class orderInstanceCount + : public ::std::binary_function<MemoryManagerBase*,MemoryManagerBase*, bool> + { + public: + bool operator()(MemoryManagerBase *a, MemoryManagerBase *b) { + return (a->getInstanceCount() > b->getInstanceCount()); + }; + }; + + protected: + /** \brief + * Number of currently allocated instances in a concrete MemoryManager<T>. + * Note that this member is not static, so every MemoryManager<T> has + * its own instanceCount which can be accessed via the singleton pointer. + */ + unsigned long int instanceCount; + + /** \brief + * byte count for a special type + */ + unsigned long int typedByteCount; + + /** \brief + * ID of the managed data type. Usefull if no typeid is accessable. Note + * that this member is not static, so every MemoryManager<T> has + * its own typeId which can be accessed via the singleton pointer. + */ + unsigned long int typeId; + + /** \brief + * Number of totally allocated bytes by all managers in \ref memoryManagers. + */ + static unsigned long int byteCount; + + /** \brief + * Vector of all MemoryManagers. Every concrete MemoryManager must add + * a pointer to itself to this vector when constructed. + */ + static ::std::vector<MemoryManagerBase*> memoryManagers; + + /** \brief + * List of all registered MemoryMonitors + */ + static ::std::vector<MemoryMonitor*> memoryMonitors; + + /** \brief + * Used to create unique IDs for every concrete MemoryManager + */ + static unsigned long int idCounter; + }; + + + // ============================================================================ + // ===== class MemoryManager ================================================== + // ============================================================================ + + /** \ingroup Memory + * \brief + * The main task of a MemoryManager is to count the number of instances + * of the managed type T. Every instance of T then must be allocated + * by \ref MemoryManager<T>::getMemory(). + * The memory is freed by \ref MemoryManager<T>::freeMemory() + * If a class is \ref MEMORY_MANAGED + * the operators new, delete, new[] and delete[] are overloaded, so that + * the corresponding MemoryManager calls are performed. If you use then the + * \ref NEW and \ref DELETE macros additionally file name and line number + * of the macro call are passed to the MemoryManager and will be printed + * on every call of \ref getMemory() if \ref printInfo is true. if you + * allocate and deallocate memory for a MEMORY_MANAGED class by new and delete + * this information will not be present, but the calls are still passed + * through MemoryManager. + * If you want to allocate memory for scalar data types with MemoryManager + * you can use the macros \ref GET_MEMORY and \ref FREE_MEMORY which + * will call \ref MemoryManager<T>::getMemory()/ + * \ref MemoryManager<T>::freeMemory() with file name and line number + * information. In this case no new- or delete-operators are called, so + * even no constructors or destructors are called. + * If \ref preallocated is true, all memory allocation and deallocation + * operations are deligated to MemoryPool. + * + * <img src = "memory.png"> + */ + template<typename T> + class MemoryManager : public MemoryManagerBase + { + protected: + /** \brief + * Constructor + */ + MemoryManager() {}; + + public: + /** \brief + * Initialisation of the MemoryManager. Creates the \ref singleton instance + * with initialized typeId and instanceCount (see \ref MemoryManagerBase), + * and adds a pointer to \ref singleton to + * \ref MemoryManagerBase::memoryManagers + */ + static void init(); + + /** \brief + * Returns memory for one instance of T. If MemoryManager<T> is not yet + * initialized, \ref init() will be called. The byte and instance counter + * are incremented and if \ref printInfo is true, information about this + * memory allocation are printed. If \ref preallocatable is true, the + * allocation is deligated to MemoryPool, otherwise it is done here. + */ + static T* getMemory(size_t s, const char* filename, int line) { + FUNCNAME("MemoryManager<T>::getMemory()"); + if(!singleton) init(); + byteCount += s; + singleton->instanceCount += s/sizeof(T); + singleton->typedByteCount += s; + if(printInfo) { + if(filename && line) + MSG("FILE: %s, LINE: %d - ", filename, line); + Msg::print("%s::getMemory : %d instances, total : %d instances\n", + singleton->getName().c_str(), s/sizeof(T), + static_cast<int>(singleton->instanceCount)); + } + return + preallocatable ? + reinterpret_cast<T*>(MemoryPool::getMemory(s)) : + reinterpret_cast<T*>(new char[s]); + }; + + /** \brief + * Frees memory which was allocated by \ref getMemory(). If \ref printInfo + * is true, information about this deallocation is printed + */ + static void freeMemory(T* mem, size_t s) { + FUNCNAME("MemoryManager<T>::freeMemory()"); + TEST_EXIT(singleton)("not initialized\n"); + byteCount -= s; + singleton->instanceCount -= s/sizeof(T); + singleton->typedByteCount -= s; + if(printInfo) { + MSG("%s::freeMemory : %d instances, total : %d instances\n", + singleton->getName().c_str(), s/sizeof(T), + static_cast<int>(singleton->instanceCount)); + } + preallocatable ? + MemoryPool::freeMemory(mem, s) : + delete [] (reinterpret_cast<char*>(mem)); + }; + + /** \brief + * Returns name of T by demangle the mangled typeid of T. + */ + inline ::std::string getName() { +#if 0 + char result[100]; + // demangle(typeid(T).name(), result); + int status; + size_t length; + abi::__cxa_demangle(typeid(T).name(), result, &length, &status); + TEST_EXIT(status == 0)("demangling failed\n"); + return ::std::string(result); +#endif + return typeid(T).name(); + }; + + /** \brief + * Sets \ref preallocatable + */ + static void setPreallocatable(bool prealloc) { + preallocatable = prealloc; + }; + + /** \brief + * Sets \ref printInfo + */ + static void setPrintInfo(bool p) { + printInfo = p; + }; + + /** \brief + * Returns \ref printInfo + */ + static bool getPrintInfo() { return printInfo; }; + + /** \brief + * Returns the pointer to the \ref singleton instance of MemoryManager<T> + */ + static MemoryManager<T>* getSingleton() { return singleton; }; + + /** \brief + * Implementation of \ref MemoryManagerBase::newInstanceCounter() + */ + InstanceCounterBase* newInstanceCounter() { + return new InstanceCounter<T>; + }; + + protected: + /** \brief + * The one and only instance of a MemoryManager for this type T + */ + static MemoryManager<T> *singleton; + + /** \brief + * Determines whether memory allocation is deligated to MemoryPool + */ + static bool preallocatable; + + /** \brief + * Determines whether information should be printed when allocating and + * deallocationg memory. + */ + static bool printInfo; + }; + + template<typename T> + MemoryManager<T> *MemoryManager<T>::singleton = NULL; + + template<typename T> + bool MemoryManager<T>::preallocatable = false; + + template<typename T> + bool MemoryManager<T>::printInfo = false; + + // ============================================================================ + // ===== class InstanceCounterBase ============================================ + // ============================================================================ + + /** \ingroup Memory + * \brief + * Template type independent interface for InstanceCounter. A MemoryMonitor + * holds a list of InstanceCounters for the different data types. + * + * <img src = "memory.png"> + */ + class InstanceCounterBase + { + public: + /** \brief + * To be overloaded by a concrete InstanceCounter + */ + virtual long int getInstanceCount() = 0; + + /** \brief + * To be overloaded by a concrete InstanceCounter + */ + virtual ::std::string getTypeName() = 0; + + /** \brief + * Destructor + */ + virtual ~InstanceCounterBase() {}; + }; + + // ============================================================================ + // ===== class InstanceCounter ================================================ + // ============================================================================ + + /** \ingroup Memory + * \brief + * When an InstanceCounter<T> is created, it remembers the current number + * of T instances in MemoryManager<T>. After that one can get the difference + * between this remembered number and the current number in MemoryManager<T> + * by \ref getInstanceCount() at every time. A MemoryMonitor holds a list + * of InstanceCounters for the different data types. + */ + template<typename T> + class InstanceCounter : public InstanceCounterBase + { + public: + /** \brief + * Creates an InstanceCounter and stores the current instanceCount of + * MemoryManager<T> in \ref oldInstanceCount. + */ + InstanceCounter() + : oldInstanceCount(MemoryManager<T>::getSingleton()->getInstanceCount()) + {}; + + /** \brief + * Sets \ref oldInstanceCount to the current number of instances in + * MemoryManager<T> + */ + inline void reset() { + oldInstanceCount = MemoryManager<T>::getSingleton()->getInstanceCount(); + }; + + /** \brief + * Returns the difference between the current instanceCount and + * \ref oldInstanceCount + */ + long int getInstanceCount() { + return (MemoryManager<T>::getSingleton()->getInstanceCount() - + oldInstanceCount); + }; + + /** \brief + * Returns the name of T. Calls MemoryManager<T>::getName() + */ + ::std::string getTypeName() { + return MemoryManager<T>::getSingleton()->getName(); + }; + + protected: + /** \brief + * Number of instances in MemoryManager<T> at creation time of this + * InstanceCounter. Can be reseted by \ref reset() + */ + long int oldInstanceCount; + }; + + // ============================================================================ + // ===== class MemoryMonitor ================================================== + // ============================================================================ + + /** \ingroup Memory + * \brief + * A MemoryMonitor counts from its construction time the number of allocated + * instances for every memory managed data type. It holds a list with one + * InstanceCounter for every managed data type. This list is updated by + * MemoryManagerBase. Herefore MemoryManagerBase needs a list of all + * MemoryMonitors. So a MemoryMonitor must register itself when constructed + * and deregister when deleted. + * + * <img src = "memory.png"> + */ + class MemoryMonitor + { + public: + /** \brief + * Constructor. Registers itself with MemoryMonitorBase. + */ + MemoryMonitor(const char *name_, const char *filename_=NULL) + : name(name_), filename(filename_) + { + MemoryManagerBase::addMemoryMonitor(this); + }; + + /** \brief + * Destructor. Prints statistics and deregisters itself with + * MemoryManagerBase. + */ + ~MemoryMonitor() { + printStatistics(); + MemoryManagerBase::removeMemoryMonitor(this); + }; + + /** \brief + * Prints a statistic for every data type with instanceCount - + * \ref oldInstanceCount != 0. + */ + void printStatistics() { + FUNCNAME("MemoryMonitor::printStatistics()"); + ::std::ostream *oldOut; + static bool fileOpen = false; + if(filename && !fileOpen) { + oldOut = Msg::getOutStream(); + Msg::open_file(filename, ::std::ios::out); + fileOpen = true; + } + ::std::vector<InstanceCounterBase*>::iterator it; + sort(instanceCounters.begin(), + instanceCounters.end(), + orderInstanceCount()); + MSG("MemoryMonitor %s - statistics since creation:\n", name.c_str()); + for(it = instanceCounters.begin(); it != instanceCounters.end(); it++) { + if((*it)->getInstanceCount() != 0) { + MSG("%s : %d instance", + (*it)->getTypeName().c_str(), + static_cast<int>((*it)->getInstanceCount())); + if(static_cast<int>((*it)->getInstanceCount()) > 1) + Msg::print("s"); + MSG("\n"); + } + } + if(filename) { + Msg::change_out(oldOut); + } + }; + + /** \brief + * Adds a InstanceCounter to \ref instanceCounters. Used by MemoryManagerBase + * to update the list of InstanceCounters + */ + inline void addInstanceCounter(InstanceCounterBase* counter) { + instanceCounters.push_back(counter); + }; + + protected: + /** \brief + * Used in \ref printStatistics() to sort the InstanceCounters by the number + * of currently allocated instances. + */ + class orderInstanceCount + : public ::std::binary_function<InstanceCounterBase*,InstanceCounterBase*, bool> + { + public: + bool operator()(InstanceCounterBase *a, InstanceCounterBase *b) { + return (a->getInstanceCount() > b->getInstanceCount()); + }; + }; + + protected: + /** \brief + * Name of the monitor + */ + ::std::string name; + + /** \brief + * Filename + */ + const char *filename; + + /** \brief + * List with InstanceCounters for every data type + */ + ::std::vector<InstanceCounterBase*> instanceCounters; + + friend class MemoryManagerBase; + }; + + template<typename T> + void MemoryManager<T>::init() + { + FUNCNAME("MemoryManager<T>::init()"); + TEST_EXIT(singleton == NULL)("already initialized\n"); + + singleton = new MemoryManager<T>; + singleton->typeId = idCounter++; + singleton->instanceCount = 0; + memoryManagers.push_back(singleton); + ::std::vector<MemoryMonitor*>::iterator it; + for(it = memoryMonitors.begin(); it != memoryMonitors.end(); it++) { + (*it)->addInstanceCounter(new InstanceCounter<T>); + } + } + + /** \brief + * If MEMORY_MANAGED(T) is called in the public declaration of class T + * the operators new, delete, new[], and delete[] are overloaded: + * new and new[] calls \ref MemoryManager<T>::getMemory(), + * delete and delete[] calls \ref MemoryManager<T>::freeMemory(). + * If you use the macro \ref NEW for memory allocation, additional information + * about the file name and line number are given to the new operators which + * are printed if \ref MemoryManager<T>::printInfo is true. + */ +#define MEMORY_MANAGED(className) \ + void *operator new(size_t s) \ + { \ + return MemoryManager<className>::getMemory(s, NULL, 0); \ + }; \ + void *operator new(size_t s, const char *filename, int line) \ + { \ + return MemoryManager<className>::getMemory(s, filename, line); \ + }; \ + void operator delete(void *mem, size_t s) \ + { MemoryManager<className>::freeMemory(static_cast<className*>(mem), s);}; \ + void *operator new[](size_t s, const char *filename=NULL, int line=0) \ + { \ + return MemoryManager<className>::getMemory(s, filename, line); \ + }; \ + void operator delete[](void *mem, size_t s) \ + { MemoryManager<className>::freeMemory(static_cast<className*>(mem), s); }; \ + void *operator new(size_t, void *ptr) { \ + return ptr; \ + } + + /** \brief + * Calls the new operator with additional file name and line number information + */ + //#define NEW new (__FILE__,__LINE__) // leads to internal compiler error in some cases +#define NEW new + + /** \brief + * Calls the delete operator. + */ +#define DELETE delete + + /** \brief + * Allocates memory for number instances of the given type. Additionally + * file name and line number information are given to the MemoryManager. + * Use this macro to allocate scalar data types with a MemoryManager. + */ +#define GET_MEMORY(typename, number) \ + MemoryManager<typename>::getMemory((number) * sizeof(typename), \ + __FILE__,__LINE__) + + /** \brief + * Deallocation of memory allocated with \ref GET_MEMORY + */ +#define FREE_MEMORY(ptr, typename, number) \ + MemoryManager<typename>::freeMemory(ptr, (number) * sizeof(typename)) + + + // use these macros to deactivate memory management +#if 0 +#define MEMORY_MANAGED(className) ; +#define NEW new +#define DELETE delete +#define GET_MEMORY(typename, number) new typename[number] +#define FREE_MEMORY(ptr, typename, number) delete [] ptr +#endif + +} + +#endif // AMDIS_MEMORYMANAGER_H diff --git a/AMDiS/src/MemoryPool.cc b/AMDiS/src/MemoryPool.cc new file mode 100644 index 0000000000000000000000000000000000000000..0e394aabeea971ca03bed9ac7658d185071b02f5 --- /dev/null +++ b/AMDiS/src/MemoryPool.cc @@ -0,0 +1,76 @@ +#include "MemoryPool.h" + +namespace AMDiS { + + ::std::vector<MemoryPool*> MemoryPool::containerArray; + unsigned int MemoryPool::increment = 8*1024-12; + + void MemoryPool::grow() + { + int chunkSize = elementSize * localIncrement; + + char *start = new char[chunkSize]; + char *last = &start[(localIncrement - 1) * elementSize]; + + char *p; + + for(p=start; p < last; p+=elementSize) + { + reinterpret_cast<Link*>( p)->next = reinterpret_cast<Link*>(p + elementSize); + } + reinterpret_cast<Link*>( last)->next = NULL; + head = reinterpret_cast<Link*>( start); + + // create new block info and store it in the list + MemoryBlock *newBlock = new MemoryBlock; + newBlock->address = start; + newBlock->next = firstMemoryBlock; + firstMemoryBlock = newBlock; + } + + void MemoryPool::compress() + { + MemoryBlock *block; + + for(block = firstMemoryBlock; block != NULL; block = block->next) + block->usedCount = localIncrement; + + // count used memory in each block + Link *nextFree; + for(nextFree = head; nextFree != NULL; nextFree = nextFree->next) { + // get memory block of nextFree + for(block = firstMemoryBlock; block != NULL; block = block->next) { + if((reinterpret_cast<char*>(nextFree) >= block->address) && + (reinterpret_cast<char*>( nextFree) < block->address+localIncrement*elementSize)) { + // block found + break; + } + } + if(block == NULL) { + ERROR_EXIT("no memory block found for nextFree\n"); + } else { + block->usedCount--; + if(block->usedCount < 0) { + ERROR_EXIT("usedCount < 0 !\n"); + } + } + } + + // delete unused blocks + MemoryBlock *lastBlock = NULL; + for(block=firstMemoryBlock; block != NULL; block=block->next) { + if(block->usedCount == 0) { + if(lastBlock) { + lastBlock->next = block->next; + } else { + firstMemoryBlock = block->next; + } + delete[] block->address; + delete block; + } else { + lastBlock = block; + } + } + } + +} diff --git a/AMDiS/src/MemoryPool.h b/AMDiS/src/MemoryPool.h new file mode 100644 index 0000000000000000000000000000000000000000..dea94a7500712c4d8bced6ed67035fe8d3ccda21 --- /dev/null +++ b/AMDiS/src/MemoryPool.h @@ -0,0 +1,237 @@ +// ============================================================================ +// == == +// == AMDiS - Adaptive multidimensional simulations == +// == == +// ============================================================================ +// == == +// == crystal growth group == +// == == +// == Stiftung caesar == +// == Ludwig-Erhard-Allee 2 == +// == 53175 Bonn == +// == germany == +// == == +// ============================================================================ +// == == +// == http://www.caesar.de/cg/AMDiS == +// == == +// ============================================================================ + +/** \file MemoryPool.h */ + +#ifndef AMDIS_MEMORYCONTAINER_H +#define AMDIS_MEMORYCONTAINER_H + +#include "Global.h" + +namespace AMDiS { + + // ============================================================================ + // ===== class MemoryPool ===================================================== + // ============================================================================ + + /** \ingroup Memory + * \brief + * The task of MemoryPool is to speed up memory allocation and deallocation. + * This is done by allocating big blocks of memory instead of allocating memory + * for a single object on each call of \ref getMemory(). So the number of slow + * system memory allocation calls is reduced. For the user MemoryPool<T> is a + * static class and one can get objects of type T ba calling + * \ref MemoryPool::getMemory(). + * Internally for every element size a single non static MemoryPool is + * hold in \ref containerArray. Normally the MemoryPool is not visible + * for the user. If \ref MemoryManager<T>::preallocatable is true, the + * MemoryManager<T> will deligate all allocation and deallocation + * calls to MemoryPool. + * + * <img src = "memory.png"> + */ + class MemoryPool + { + protected: + /** \brief + * Creates a MemoryPool for the given element size which will be + * stored in \ref containerArray. + */ + MemoryPool(size_t s) + : firstMemoryBlock(NULL), + elementSize(align(s < sizeof(Link*) ? sizeof(Link*) : s)), + head(NULL), + localIncrement(max((increment/elementSize), static_cast<unsigned int>(1))) + {}; + + /** \brief + * Destructor + */ + ~MemoryPool() + { + compress(); + if(firstMemoryBlock != NULL) { + ERROR_EXIT("~MemoryPool(): still memory in use ?\n"); + } + }; + + public: + /** \brief + * Allocates memory for an element of size s bytes. + */ + static inline void *getMemory(size_t s) + { + if(s == 0) { + ERROR_EXIT("s == 0\n"); + } + if(containerArray.size() < s) containerArray.resize(s, NULL); + if(!containerArray[s-1]) { + containerArray[s-1] = new MemoryPool(s); + } + return containerArray[s-1]->getMemoryIntern(); + }; + + /** \brief + * Frees memory allocated by \ref getMemory() + */ + static inline void freeMemory(void *mem, size_t s) + { + if(s==0 || !containerArray[s-1]) { + ERROR_EXIT("invalid size!\n"); + }; + containerArray[s-1]->freeMemoryIntern(mem); + }; + + /** \brief + * Sets \ref increment + */ + static void setIncrement(unsigned int inc) { + increment = inc; + }; + + /** \brief + * Returns \ref increment + */ + static unsigned int getIncrement() { + return increment; + }; + + /** \brief + * Frees currently not used memory blocks on system level. + */ + void compress(); + + protected: + /** \brief + * Called by \ref getMemory() + */ + inline void *getMemoryIntern() + { + if(head == NULL) grow(); + Link* p = head; + head = p->next; + return p; + }; + + /** \brief + * called by \ref freeMemory() + */ + inline void freeMemoryIntern(void *mem) + { + Link *p = reinterpret_cast<Link*>(mem); + p->next = head; + head = p; + }; + + /** \brief + * Avoids copies + */ + MemoryPool(MemoryPool&); + + /** \brief + * Avoids copies + */ + void operator=(MemoryPool&); + + /** \brief + * Called when all currently on system level allocated memory in all blocks + * is allocated by the user. Then a new block of size \ref increment will + * be allocated. + */ + void grow(); + + /** \brief + * Used to calculate an \ref elementSize that ensures even memory addresses + */ + inline unsigned int align(unsigned int s) { + int x = s + sizeof(Link*) - 1; + x -= x % sizeof(Link*); + return x; + }; + + protected: + /** \brief + * Used to manage not user allocated memory in a memory block. If a piece + * of memory is not allocated for an instance of T, the first bytes of this + * piece are interpreted as a pointer to the next free piece of memory. + * When allocating a new block this Link pointers are initialized, so that + * every Link points to its successor Link. + */ + struct Link { + /** \brief + * Pointer to the next free piece of memory + */ + Link *next; + }; + + /** \brief + * Represents one memory block + */ + struct MemoryBlock { + /** \brief + * Pointer to the first byte of this block + */ + char *address; + + /** \brief + * Pointer to the next memory block + */ + MemoryBlock *next; + + /** \brief + * Number of currently user allocated T instances + */ + int usedCount; + }; + + /** \brief + * Pointer to the first memory block + */ + MemoryBlock *firstMemoryBlock; + + /** \brief + * Number of bytes allocated for one 'element'. + */ + unsigned int elementSize; + + /** \brief + * Pointer to the first free piece of memory + */ + Link *head; + + + /** \brief + * Size of one block + */ + static unsigned int increment; + + /** \brief + * Vector of pointers to the MemoryPool for the different element sizes. + */ + static ::std::vector<MemoryPool*> containerArray; + + /** \brief + * = max(\ref increment / \ref elementSize, 1) + */ + unsigned int localIncrement; + }; + +} + +#endif // AMDIS_MEMORYPOOL_H diff --git a/AMDiS/src/Mesh.cc b/AMDiS/src/Mesh.cc new file mode 100644 index 0000000000000000000000000000000000000000..1743d4e91fd7705765db6e15233ab487800e9de5 --- /dev/null +++ b/AMDiS/src/Mesh.cc @@ -0,0 +1,1194 @@ +#include "AdaptStationary.h" +#include "AdaptInstationary.h" +#include "FiniteElemSpace.h" +#include "ElementData.h" +#include "MacroElement.h" +#include "MacroReader.h" +#include "Mesh.h" +#include "Traverse.h" +#include "Parameters.h" +#include "FixVec.h" +#include "DOFVector.h" +#include "CoarseningManager.h" +#include "DOFIterator.h" +#include "VertexVector.h" +#include "MacroWriter.h" +#include "PeriodicMap.h" +#include "Projection.h" +#include <algorithm> +#include <set> +#include <map> + +#include "time.h" + +namespace AMDiS { + +#define TIME_USED(f,s) ((double)((s)-(f))/(double)CLOCKS_PER_SEC) + + //************************************************************************** + // flags, which information should be present in the elInfo structure + //************************************************************************** + + const Flag Mesh::FILL_NOTHING = 0X00L; + const Flag Mesh::FILL_COORDS = 0X01L; + const Flag Mesh::FILL_BOUND = 0X02L; + const Flag Mesh::FILL_NEIGH = 0X04L; + const Flag Mesh::FILL_OPP_COORDS = 0X08L; + const Flag Mesh::FILL_ORIENTATION= 0X10L; + const Flag Mesh::FILL_DET = 0X20L; + const Flag Mesh::FILL_GRD_LAMBDA = 0X40L; + const Flag Mesh::FILL_ADD_ALL = 0X80L; + + + const Flag Mesh::FILL_ANY_1D= (0X01L|0X02L|0X04L|0X08L|0x20L|0X40L|0X80L); + const Flag Mesh::FILL_ANY_2D= (0X01L|0X02L|0X04L|0X08L|0x20L|0X40L|0X80L); + const Flag Mesh::FILL_ANY_3D= (0X01L|0X02L|0X04L|0X08L|0X10L|0x20L|0X40L|0X80L); + + //************************************************************************** + // flags for Mesh traversal + //************************************************************************** + + const Flag Mesh::CALL_EVERY_EL_PREORDER = 0X0100L; + const Flag Mesh::CALL_EVERY_EL_INORDER = 0X0200L; + const Flag Mesh::CALL_EVERY_EL_POSTORDER = 0X0400L; + const Flag Mesh::CALL_LEAF_EL = 0X0800L; + const Flag Mesh::CALL_LEAF_EL_LEVEL = 0X1000L; + const Flag Mesh::CALL_EL_LEVEL = 0X2000L; + const Flag Mesh::CALL_MG_LEVEL = 0X4000L ; // used in mg methods + + + // const Flag Mesh::USE_PARAMETRIC = 0X8000L ; // used in mg methods + + // ::std::list<Mesh*> Mesh::meshes; + DOFAdmin* Mesh::compressAdmin = NULL; + Mesh* Mesh::traversePtr = NULL; + int Mesh::iadmin = 0; + ::std::vector<DegreeOfFreedom> Mesh::dof_used; + const int Mesh::MAX_DOF=100; + ::std::map<DegreeOfFreedom, DegreeOfFreedom*> Mesh::serializedDOFs; + + struct delmem { + DegreeOfFreedom* ptr; + int len; + }; + + + Mesh::Mesh(const ::std::string& aName, int dimension) + : name(aName), + dim(dimension), + nVertices(0), + nEdges(0), + nLeaves(0), + nElements(0), + parametric(NULL), + preserveCoarseDOFs(false), + nDOFEl(0), + nDOF(dimension, DEFAULT_VALUE, 0), + nNodeEl(0), + node(dimension, DEFAULT_VALUE, 0), + elementPrototype(NULL), + elementDataPrototype(NULL), + elementIndex(-1), + initialized(false), + final_lambda(dimension, DEFAULT_VALUE, 0.0) + { + + FUNCNAME("Mesh::Mesh"); + + // set default element prototype + switch(dim) { + case 1: + elementPrototype = NEW Line(this); + break; + case 2: + elementPrototype = NEW Triangle(this); + break; + case 3: + elementPrototype = NEW Tetrahedron(this); + break; + default: + ERROR_EXIT("invalid dimension\n"); + } + + elementPrototype->setIndex(-1); + + elementIndex=0; + }; + + Mesh::~Mesh() + { + }; + + void Mesh::addMacroElement(MacroElement* m) { + macroElements.push_back(m); + m->setIndex(macroElements.size()); + }; + + + + + int Mesh::traverse(int level, Flag flag, + int (*el_fct)(ElInfo*)) + { + FUNCNAME("Mesh::traverse()"); + ::std::deque<MacroElement*>::iterator mel; + ElInfo* elinfo = createNewElInfo(); + Traverse tinfo(this, flag, level, el_fct); + int sum = 0; + + elinfo->setFillFlag(flag); + + if (flag.isSet(Mesh::CALL_LEAF_EL_LEVEL) || + flag.isSet(Mesh::CALL_EL_LEVEL) || + flag.isSet(Mesh::CALL_MG_LEVEL)) { + TEST(level >= 0)("invalid level: %d\n", level); + } + + for (mel = macroElements.begin(); mel != macroElements.end(); mel++) { + elinfo->fillMacroInfo(*mel); + sum += tinfo.recursive(elinfo); + } + + DELETE elinfo; + + return (flag.isSet(Mesh::FILL_ADD_ALL)) ? sum : 0; + } + + + + void Mesh::addDOFAdmin(DOFAdmin *localAdmin) + { + FUNCNAME("Mesh::addDOFAdmin()"); + + int i, j, d, n; + ::std::vector<DOFAdmin*>::iterator dai; + + localAdmin->setMesh(this); + n = admin.size(); + + dai=::std::find(admin.begin(),admin.end(),localAdmin); + if (dai!= admin.end()) { + ERROR("admin %s is already associated to mesh %s\n", + localAdmin->getName().c_str(), this->getName().c_str()); + } + + // ===== adding dofs to already existing elements ============================ + + if (initialized) { + static bool pnd_1d_0[2] = {true, true}; + static bool pnd_1d_1[1] = {false}; + static bool pnd_2d_0[3] = {true, true, true}; + static bool pnd_2d_1[3] = {true, true, false}; + static bool pnd_2d_2[1] = {false}; + static bool pnd_3d_0[4] = {true, true, true, true}; + static bool pnd_3d_1[6] = {false, true, true, true, true, true}; + static bool pnd_3d_2[4] = {true, true, false, false}; + static bool pnd_3d_3[1] = {false}; + static bool *pnd_1d[2] = {pnd_1d_0, pnd_1d_1}; + static bool *pnd_2d[3] = {pnd_2d_0, pnd_2d_1, pnd_2d_2}; + static bool *pnd_3d[4] = {pnd_3d_0, pnd_3d_1, pnd_3d_2, pnd_3d_3}; + static bool **parentNeedsDOF[4] = {NULL, pnd_1d, pnd_2d, pnd_3d}; + + + ::std::list<struct delmem> delList; + ::std::map< ::std::set<DegreeOfFreedom>, DegreeOfFreedom*> dofPtrMap; + const DOFAdmin *vertexAdmin = getVertexAdmin(); + int vertexAdminPreDOFs = vertexAdmin->getNumberOfPreDOFs(VERTEX); + + // finding necessary node number for new admin + + int newNNode=0; + GeoIndex geoIndex; + + for(d = 0; d < dim+1; d++) { + geoIndex = INDEX_OF_DIM(d, dim); + + if (localAdmin->getNumberOfDOFs(geoIndex)>0||nDOF[geoIndex]>0) + newNNode+=getGeo(geoIndex); + }; + + bool extendNodes=(newNNode>nNodeEl); + int oldNNodes=nNodeEl; + + nNodeEl=newNNode; + + TraverseStack stack; + ElInfo *elInfo = NULL; + + WARNING("You are using untested code (adding dofs to existing mesh). Please contact\nsoftware administrator if any errors occur in this context.\n"); + + elInfo = stack.traverseFirst(this, -1, CALL_EVERY_EL_PREORDER); + while(elInfo) { + Element *element = elInfo->getElement(); + DegreeOfFreedom *newDOF, **oldDOF, **dof = + const_cast<DegreeOfFreedom**>(element->getDOF()); + + int index = 0; + + if (extendNodes) { + oldDOF=dof; + element->setDOFPtrs(); + dof=const_cast<DegreeOfFreedom**>(element->getDOF()); + int index=0,oldIndex=0; + for(d = 0; d < dim+1; d++) { + geoIndex = INDEX_OF_DIM(d, dim); + if (nDOF[geoIndex]>0) { + for(i=0;i<getGeo(geoIndex);++i) + dof[index++]=oldDOF[oldIndex++]; + } + else { + if (localAdmin->getNumberOfDOFs(geoIndex)>0) + index+=getGeo(geoIndex); + } + } + + FREE_MEMORY(oldDOF, DegreeOfFreedom*, oldNNodes); + + TEST_EXIT(index==nNodeEl)("ERROR: Number of entered nodes %f != number of nodes %f\n",index,nNodeEl); + + } + + + index=0; + + // allocate new memory at elements + for(d = 0; d < dim+1; d++) { + geoIndex = INDEX_OF_DIM(d, dim); + + int numberOfDOFs = localAdmin->getNumberOfDOFs(geoIndex); + int numberOfPreDOFs = nDOF[geoIndex]; + + if (numberOfDOFs>0||numberOfPreDOFs>0) { + + // for all vertices/edges/... + for(i = 0; i < getGeo(geoIndex); i++, index++) { + ::std::set<DegreeOfFreedom> dofSet; + for(j = 0; j < d+1; j++) { + dofSet.insert(dof[element->getVertexOfPosition(geoIndex, i, j)][vertexAdminPreDOFs]); + } + + if(element->isLeaf() || parentNeedsDOF[dim][d][i]) { + if(dofPtrMap[dofSet] == NULL) { + if(localAdmin->getNumberOfDOFs(geoIndex)) { + newDOF = GET_MEMORY(DegreeOfFreedom, numberOfPreDOFs + numberOfDOFs); + // copy old dofs to new memory and free old memory + if(dof[index]) { + for(j = 0; j < numberOfPreDOFs; j++) { + newDOF[j] = dof[index][j]; + } + // FREE_MEMORY(dof[index], DegreeOfFreedom, numberOfPreDOFs); + // Do not free memory. The information has to be used to identify the part in other elements. + // The memory is only marked for freeing. + struct delmem fm; + fm.ptr=dof[index]; + fm.len=numberOfPreDOFs; + delList.push_back(fm); + } + for(j = 0; j < numberOfDOFs; j++) { + newDOF[numberOfPreDOFs + j] = localAdmin->getDOFIndex(); + } + dof[index] = newDOF; + } + dofPtrMap[dofSet] = dof[index]; + } else { + dof[index] = dofPtrMap[dofSet]; + } + } + } + } + } + elInfo = stack.traverseNext(elInfo); + } + + // now free the old dof memory: + + ::std::list<struct delmem>::iterator it=delList.begin(); + + while(it!=delList.end()) { + FREE_MEMORY((*it).ptr, DegreeOfFreedom, (*it).len); + it++; + } + + delList.clear(); + + } + // ============================================================================ + + admin.push_back(localAdmin); + + nDOFEl = 0; + + localAdmin->setNumberOfPreDOFs(VERTEX,nDOF[VERTEX]); + nDOF[VERTEX] += localAdmin->getNumberOfDOFs(VERTEX); + nDOFEl += getGeo(VERTEX) * nDOF[VERTEX]; + + if(dim > 1) { + localAdmin->setNumberOfPreDOFs(EDGE,nDOF[EDGE]); + nDOF[EDGE] += localAdmin->getNumberOfDOFs(EDGE); + nDOFEl += getGeo(EDGE) * nDOF[EDGE]; + } + + localAdmin->setNumberOfPreDOFs(CENTER,nDOF[CENTER]); + nDOF[CENTER] += localAdmin->getNumberOfDOFs(CENTER); + nDOFEl += nDOF[CENTER]; + + TEST_EXIT(nDOF[VERTEX] > 0)("no vertex dofs\n"); + + node[VERTEX] = 0; + nNodeEl = getGeo(VERTEX); + + if(dim > 1) { + node[EDGE] = nNodeEl; + if (nDOF[EDGE] > 0) nNodeEl += getGeo(EDGE); + } + + if (3==dim){ + localAdmin->setNumberOfPreDOFs(FACE,nDOF[FACE]); + nDOF[FACE] += localAdmin->getNumberOfDOFs(FACE); + nDOFEl += getGeo(FACE) * nDOF[FACE]; + node[FACE] = nNodeEl; + if (nDOF[FACE] > 0) nNodeEl += getGeo(FACE); + } + + node[CENTER] = nNodeEl; + if (nDOF[CENTER] > 0) nNodeEl += 1; + + return; + } + + + /****************************************************************************/ + /* dofCompress: remove holes in dof vectors */ + /****************************************************************************/ + + void Mesh::dofCompress() + { + FUNCNAME("Mesh::dofCompress"); + int size; + Flag fill_flag; + + // int i; + // for(i = 0; i < periodicAssociations[-2]->getSize(); i++) { + // MSG("asso %d : dof %d -> dof %d\n", + // periodicAssociations[-2], + // i, + // (*periodicAssociations[-2])[i]); + // } + + for (iadmin = 0; iadmin < static_cast<int>(admin.size()); iadmin++) + { + TEST_EXIT((compressAdmin = admin[iadmin])) + ("no admin[%d] in mesh\n", iadmin); + + if ((size = compressAdmin->getSize()) < 1) continue; + if (compressAdmin->getUsedDOFs() < 1) continue; + if (compressAdmin->getHoleCount() < 1) continue; + + newDOF.resize(size); + + compressAdmin->compress(newDOF); + + if (preserveCoarseDOFs) { + fill_flag = Mesh::CALL_EVERY_EL_PREORDER | Mesh::FILL_NOTHING; + } + else { + fill_flag = Mesh::CALL_LEAF_EL | Mesh::FILL_NOTHING; + } + + traverse( -1, fill_flag, newDOFFct1); + traverse( -1, fill_flag, newDOFFct2); + + newDOF.resize(0); + } + + // MSG("\n"); + // for(i = 0; i < periodicAssociations[-2]->getSize(); i++) { + // MSG("asso %d : dof %d -> dof %d\n", + // periodicAssociations[-2], + // i, + // (*periodicAssociations[-2])[i]); + // } + + return; + } + + // /****************************************************************************/ + // /* fill_boundary: */ + // /* fills boundary information for the vertices of the macro triangulation */ + // /* mel_vertex[k][i] = global index of vertex k of element i */ + // /****************************************************************************/ + + // void Mesh::fillBoundary(int **mel_vertex) + // { + // FUNCNAME("Mesh::fillBoundary"); + // ::std::deque<MacroElement*>::const_iterator mel = firstMacroElement(); + // int i, j,k; + // int lne = getNumberOfLeaves(), lnv = getNumberOfVertices(); + // int ned = getNumberOfEdges(); + + // BoundaryType *bound = GET_MEMORY(BoundaryType, lnv+(3==dim)?ned:0); + + // for (i = 0; i < lnv; i++) + // bound[i] = INTERIOR; + + // int facesPlusEdges = + // (*mel)->getElement()->getGeo(FACE) + + // (*mel)->getElement()->getGeo(EDGE); + + // for (i = 0; i < lne; i++) { + // for (k = 0; k < getGeo(NEIGH); k++) { + // //if ((*(mel+i))->getBoundary(k)) { + // if ((*(mel+i))->getBoundary(k) >= DIRICHLET) { + // for (j = 1; j < dim+1; j++) + // bound[mel_vertex[i][(k+j)%(dim+1)]] = DIRICHLET; + // } + // else if ((*(mel+i))->getBoundary(k) <= NEUMANN) { + // for (j = 1; j < dim+1; j++) + // if (bound[mel_vertex[i][(k+j)%(dim+1)]] != DIRICHLET) + // bound[mel_vertex[i][(k+j)%(dim+1)]] = NEUMANN; + // } + // //} + // } + // } + + // for (i = 0; i < lne; i++) + // for (k = 0; k < getGeo(VERTEX); k++) { + // (*(mel+i))->setBoundary(facesPlusEdges + k, + // bound[mel_vertex[i][k]]); + // } + // FREE_MEMORY(bound, BoundaryType, lnv+(3==dim)?ned:0); + + // return; + // }; + + DegreeOfFreedom *Mesh::getDOF(GeoIndex position) + { + FUNCNAME("Mesh::getDOF"); + const DOFAdmin *localAdmin; + DegreeOfFreedom *dof; + int i, j, n, n0, ndof; + + TEST_EXIT(position >= CENTER && position <= FACE) + ("unknown position %d\n",position); + + ndof = getNumberOfDOFs(position); + if (ndof <= 0) return(NULL); + + dof = GET_MEMORY(DegreeOfFreedom, ndof); + + for (i = 0; i < getNumberOfDOFAdmin(); i++) + { + localAdmin = &getDOFAdmin(i); + TEST_EXIT(localAdmin)("no admin[%d]\n", i); + + n = localAdmin->getNumberOfDOFs(position); + n0 = localAdmin->getNumberOfPreDOFs(position); + + TEST_EXIT(n+n0 <= ndof)("n=%d, n0=%d too large: ndof=%d\n", n, n0, ndof); + + for (j = 0; j < n; j++) + { + dof[n0+j] = const_cast<DOFAdmin*>(localAdmin)->getDOFIndex(); + } + } + + return(dof); + } + + + // const Boundary *Mesh::defaultBoundary(int bound) + // { + // static const Boundary dn[2] = {DIRICHLET, NEUMANN}; + // if (bound >= DIRICHLET) + // return(dn); + // else if (bound <= NEUMANN) + // return(dn+1); + // else + // return(NULL); + // } + + DegreeOfFreedom **Mesh::createDOFPtrs() + { + FUNCNAME("Mesh::createDOFPtrs"); + int i; + DegreeOfFreedom **ptrs; + + if (nNodeEl <= 0) + return(NULL); + + ptrs = GET_MEMORY(DegreeOfFreedom*, nNodeEl); + for (i = 0; i < nNodeEl; i++) + ptrs[i] = NULL; + + return(ptrs); + } + + void Mesh::freeDOFPtrs(DegreeOfFreedom **ptrs) + { + FUNCNAME("Mesh::freeDOFPtrs"); + + TEST_EXIT(ptrs)("ptrs=NULL\n"); + + if (nNodeEl <= 0) + return; + + FREE_MEMORY(ptrs, DegreeOfFreedom*, nNodeEl); + } + + + const DOFAdmin *Mesh::createDOFAdmin(const ::std::string& lname,DimVec<int> lnDOF) + { + FUNCNAME("Mesh::createDOFAdmin"); + + DOFAdmin *localAdmin; + int i; + + localAdmin=NEW DOFAdmin(this,lname); + + for (i = 0; i < dim+1; i++) + localAdmin->setNumberOfDOFs(i,lnDOF[i]); + + addDOFAdmin(localAdmin); + + return(localAdmin); + } + + + + + + // int Mesh::macroType(const ::std::string& filename, const ::std::string& type) + // { + // const char *fn, *t; + + // if (3==dim) return 0; + + // if (filename.size() <= type.size()) + // return(false); + + // fn = filename.data(); + // while (*fn) fn++; + // t = type.data(); + // while (*t) t++; + + // while (t != type && *t == *fn) t--; + + // return(t == type); + // } + + const DOFAdmin* Mesh::getVertexAdmin() const + { + int i; + const DOFAdmin *localAdmin = NULL; + + for (i = 0; i < static_cast<int>(admin.size()); i++) + { + if (admin[i]->getNumberOfDOFs(VERTEX)) + { + if (!localAdmin) + localAdmin = admin[i]; + else if (admin[i]->getSize() < localAdmin->getSize()) + localAdmin = admin[i]; + } + } + return(localAdmin); + } + + void Mesh::freeDOF(DegreeOfFreedom* dof, GeoIndex position) + { + FUNCNAME("Mesh::freeDOF"); + DOFAdmin *localAdmin; + int i, j, n, n0, ndof; + + TEST_EXIT(position >= CENTER && position <= FACE) + ("unknown position %d\n",position); + + ndof = nDOF[position]; + if (ndof) + { + if (!dof) + { + MSG("dof = NULL, but ndof=%d\n", ndof); + return; + } + } + else + { + if (dof) + { + MSG("dof != NULL, but ndof=0\n"); + } + return; + } + + TEST_EXIT(ndof <= MAX_DOF) + ("ndof too big: ndof=%d, MAX_DOF=%d\n",ndof,MAX_DOF); + + for (i = 0; i < static_cast<int>(admin.size()); i++) + { + localAdmin = admin[i]; + + n = localAdmin->getNumberOfDOFs(position); + n0 = localAdmin->getNumberOfPreDOFs(position); + + TEST_EXIT(n+n0 <= ndof)("n=%d, n0=%d too large: ndof=%d\n", n, n0, ndof); + + for (j = 0; j < n; j++) + { + localAdmin->freeDOFIndex(dof[n0+j]); + } + } + + FREE_MEMORY(dof, DegreeOfFreedom, ndof); + return; + } + + void Mesh::freeElement(Element* el) + { + freeDOFPtrs(const_cast<DegreeOfFreedom**>(el->getDOF())); + DELETE el; + } + + + + + //const Boundary* defaultBoundary(Mesh* m,int i) {return m->defaultBoundary(i);}; + + Element* Mesh::createNewElement(Element *parent) + { + FUNCNAME("Mesh::createNewElement()"); + TEST_EXIT(elementPrototype)("no element prototype\n"); + + Element *el = parent ? parent->clone() : elementPrototype->clone(); + + //el->setIndex(elementIndex++); + //el->setDOFPtrs(); + + // ElementData *elementData = NULL; + + // if(parent && parent->getElementData()) { + // elementData = parent->getElementData()->clone(); + // } else if(elementDataPrototype) { + // elementData = elementDataPrototype->clone(); + // } + + if(!parent && elementDataPrototype) { + el->setElementData(elementDataPrototype->clone()); + } else { + el->setElementData(NULL); // must be done in ElementData::refineElementData() + } + + // if(!elementData) { + // WARNING("no element data!\n"); + // } + + + return el; + } + + ElInfo* Mesh::createNewElInfo() + { + switch(dim) { + case 1: + return NEW ElInfo1d(this); + break; + case 2: + return NEW ElInfo2d(this); + break; + case 3: + return NEW ElInfo3d(this); + break; + default: + ERROR_EXIT("invalid dim\n"); + return NULL; + }; + } + + + + bool Mesh::findElInfoAtPoint(const WorldVector<double>& xy, + ElInfo *el_info, + DimVec<double>& bary, + const MacroElement *start_mel, + const WorldVector<double> *xy0, + double *sp) + { + static const MacroElement *mel = NULL; + DimVec<double> lambda(dim, NO_INIT); + ElInfo *mel_info = NULL; + int i, k; + bool inside; + + mel_info = createNewElInfo(); + + if (start_mel != NULL) + mel = start_mel; + else + if((mel == NULL)||(mel->getElement()->getMesh() != this)) + mel = *(macroElements.begin()); + + mel_info->setFillFlag(Mesh::FILL_COORDS); + g_xy = &xy; + g_xy0 = xy0; + g_sp = sp; + + mel_info->fillMacroInfo(mel); + + + while ((k = mel_info->worldToCoord(xy, &lambda)) >= 0) { + if (mel->getNeighbour(k)) { + mel = mel->getNeighbour(k); + mel_info->fillMacroInfo(mel); + continue; + } + break; + } + + /* now, descend in tree to find leaf element at point */ + inside = findElementAtPointRecursive(mel_info, lambda, k, el_info); + for (i=0; i<=dim; i++) bary[i] = final_lambda[i]; + + DELETE mel_info; + + return(inside); + } + + bool Mesh::findElementAtPoint(const WorldVector<double>& xy, + Element **elp, + DimVec<double>& bary, + const MacroElement *start_mel, + const WorldVector<double> *xy0, + double *sp) + { + ElInfo *el_info = NULL; + int val; + + el_info = createNewElInfo(); + + val = findElInfoAtPoint(xy, el_info, bary, start_mel, xy0, sp); + + *elp = el_info->getElement(); + + DELETE el_info; + + return(val); + } + + + + bool Mesh::findElementAtPointRecursive(ElInfo *el_info, + const DimVec<double>& lambda, + int outside, + ElInfo* final_el_info) + { + FUNCNAME("Mesh::findElementAtPointRecursive"); + Element *el = el_info->getElement(); + ElInfo *c_el_info = NULL; + DimVec<double> c_lambda(dim, NO_INIT); + int i, inside; + int ichild, c_outside; + + if (el->isLeaf()) { + *final_el_info = *el_info; + if (outside < 0) { + for (i=0; i<=dim; i++) final_lambda[i] = lambda[i]; + return(true); + } + else + { /* outside */ + if (g_xy0) + { /* find boundary point of [xy0, xy] */ + double s; + el_info->worldToCoord(*(g_xy0), &c_lambda); + s = lambda[outside] / (lambda[outside] - c_lambda[outside]); + for (i=0; i<=dim; i++) + { + final_lambda[i] = s * c_lambda[i] + (1.0-s) * lambda[i]; + } + if (g_sp) *(g_sp) = s; + if(dim == 3) + MSG("outside finest level on el %d: s=%.3e\n", el->getIndex(), s); + + return(false); /* ??? */ + } + else return(false); + } + } + + c_el_info = createNewElInfo(); + + if(dim == 1) { + if (lambda[0] >= lambda[1]) { + c_el_info->fillElInfo(0, el_info); + if (outside >= 0) { + outside = el_info->worldToCoord(*(g_xy), &c_lambda); + if (outside >= 0) ERROR("point outside domain\n"); + } else { + c_lambda[0] = lambda[0] - lambda[1]; + c_lambda[1] = 2.0 * lambda[1]; + } + } else { + c_el_info->fillElInfo(1, el_info); + if (outside >= 0) { + outside = el_info->worldToCoord(*(g_xy), &c_lambda); + if (outside >= 0) ERROR("point outside domain\n"); + } else { + c_lambda[1] = lambda[1] - lambda[0]; + c_lambda[0] = 2.0 * lambda[0]; + } + } + } /* DIM == 1 */ + + if(dim == 2) { + if (lambda[0] >= lambda[1]) { + c_el_info->fillElInfo(0, el_info); + if (el->isNewCoordSet()) { + outside = c_el_info->worldToCoord(*(g_xy), &c_lambda); + if (outside >= 0) { + ERROR("outside curved boundary child 0\n"); + } + } else { + c_lambda[0] = lambda[2]; + c_lambda[1] = lambda[0] - lambda[1]; + c_lambda[2] = 2.0 * lambda[1]; + } + } else { + c_el_info->fillElInfo(1, el_info); + if (el->isNewCoordSet()) { + outside = c_el_info->worldToCoord(*(g_xy), &c_lambda); + if (outside >= 0) { + ERROR("outside curved boundary child 1\n"); + } + } else { + c_lambda[0] = lambda[1] - lambda[0]; + c_lambda[1] = lambda[2]; + c_lambda[2] = 2.0 * lambda[0]; + } + } + } /* DIM == 2 */ + + if(dim == 3) { + if (el->isNewCoordSet()) { + if (lambda[0] >= lambda[1]) + ichild = 0; + else + ichild = 1; + c_el_info->fillElInfo(ichild, el_info); + c_outside = c_el_info->worldToCoord(*(g_xy), &c_lambda); + + if (c_outside>=0) { /* test is other child is better... */ + DimVec<double> c_lambda2(dim, NO_INIT); + int c_outside2; + ElInfo *c_el_info2 = createNewElInfo(); + + c_el_info2->fillElInfo(1-ichild, el_info); + c_outside2 = c_el_info2->worldToCoord(*(g_xy), &c_lambda2); + + MSG("new_coord CHILD %d: outside=%d, lambda=(%.2f %.2f %.2f %.2f)\n", + ichild, c_outside, c_lambda[0],c_lambda[1],c_lambda[2],c_lambda[3]); + MSG("new_coord CHILD %d: outside=%d, lambda=(%.2f %.2f %.2f %.2f)\n", + 1-ichild, c_outside2, c_lambda2[0],c_lambda2[1],c_lambda2[2], + c_lambda2[3]); + + if ((c_outside2 < 0) || (c_lambda2[c_outside2] > c_lambda[c_outside])) { + for (i=0; i<=dim; i++) c_lambda[i] = c_lambda2[i]; + c_outside = c_outside2; + *c_el_info = *c_el_info2; + ichild = 1 - ichild; + } + DELETE c_el_info2; + } + outside = c_outside; + } else { /* no new_coord */ + if (lambda[0] >= lambda[1]) { + c_el_info->fillElInfo(0, el_info); + c_lambda[0] = lambda[0] - lambda[1]; + c_lambda[1] = lambda[Tetrahedron::childVertex[(dynamic_cast<ElInfo3d*>(el_info))-> + getType()][0][1]]; + c_lambda[2] = lambda[Tetrahedron::childVertex[(dynamic_cast<ElInfo3d*>(el_info))-> + getType()][0][2]]; + c_lambda[3] = 2.0 * lambda[1]; + } else { + c_el_info->fillElInfo(1, el_info); + c_lambda[0] = lambda[1] - lambda[0]; + c_lambda[1] = lambda[Tetrahedron::childVertex[(dynamic_cast<ElInfo3d*>(el_info))-> + getType()][1][1]]; + c_lambda[2] = lambda[Tetrahedron::childVertex[(dynamic_cast<ElInfo3d*>(el_info))-> + getType()][1][2]]; + c_lambda[3] = 2.0 * lambda[0]; + } + } + } /* DIM == 3 */ + + inside = findElementAtPointRecursive(c_el_info, c_lambda, outside, + final_el_info); + DELETE c_el_info; + + return(inside); + } + + + void Mesh::setDiameter(const WorldVector<double>& w) { diam = w; } + + void Mesh::setDiameter(int i, double w) { diam[i] = w; } + + + int Mesh::newDOFFct1(ElInfo* ei) { + ei->getElement()->newDOFFct1(compressAdmin); + return 0; + } + + int Mesh::newDOFFct2(ElInfo* ei) { + ei->getElement()->newDOFFct2(compressAdmin); + return 0; + } + + void Mesh::serialize(::std::ostream &out) + { + serializedDOFs.clear(); + + // write name + out << name << ::std::endl; + + // write dim + out.write(reinterpret_cast<const char*>(&dim), sizeof(int)); + + // write nVertices + out.write(reinterpret_cast<const char*>(&nVertices), sizeof(int)); + + // write nEdges + out.write(reinterpret_cast<const char*>(&nEdges), sizeof(int)); + + // write nLeaves + out.write(reinterpret_cast<const char*>(&nLeaves), sizeof(int)); + + // write nElements + out.write(reinterpret_cast<const char*>(&nElements), sizeof(int)); + + // write nFaces + out.write(reinterpret_cast<const char*>(&nFaces), sizeof(int)); + + // write maxEdgeNeigh + out.write(reinterpret_cast<const char*>(&maxEdgeNeigh), sizeof(int)); + + // write diam + diam.serialize(out); + + // write preserveCoarseDOFs + out.write(reinterpret_cast<const char*>(&preserveCoarseDOFs), sizeof(bool)); + + // write nDOFEl + out.write(reinterpret_cast<const char*>(&nDOFEl), sizeof(int)); + + // write nDOF + nDOF.serialize(out); + + // write nNodeEl + out.write(reinterpret_cast<const char*>(&nNodeEl), sizeof(int)); + + // write node + node.serialize(out); + + // write admins + int i, size = static_cast<int>(admin.size()); + out.write(reinterpret_cast<const char*>(&size), sizeof(int)); + for (i = 0; i < size; i++) { + admin[i]->serialize(out); + } + + // write macroElements + size = static_cast<int>(macroElements.size()); + out.write(reinterpret_cast<const char*>(&size), sizeof(int)); + for (i = 0; i < size; i++) { + macroElements[i]->serialize(out); + } + + // write elementIndex + out.write(reinterpret_cast<const char*>(&elementIndex), sizeof(int)); + + // write initialized + out.write(reinterpret_cast<const char*>(&initialized), sizeof(bool)); + + serializedDOFs.clear(); + } + + void Mesh::deserialize(::std::istream &in) + { + serializedDOFs.clear(); + + // read name + in >> name; + in.get(); + + // read dim + int oldVal = dim; + in.read(reinterpret_cast<char*>(&dim), sizeof(int)); + TEST_EXIT((oldVal == 0) || (dim == oldVal))("invalid dimension\n"); + + // read nVertices + in.read(reinterpret_cast<char*>(&nVertices), sizeof(int)); + + // read nEdges + in.read(reinterpret_cast<char*>(&nEdges), sizeof(int)); + + // read nLeaves + in.read(reinterpret_cast<char*>(&nLeaves), sizeof(int)); + + // read nElements + in.read(reinterpret_cast<char*>(&nElements), sizeof(int)); + + // read nFaces + in.read(reinterpret_cast<char*>(&nFaces), sizeof(int)); + + // read maxEdgeNeigh + in.read(reinterpret_cast<char*>(&maxEdgeNeigh), sizeof(int)); + + // diam + diam.deserialize(in); + + // read preserveCoarseDOFs + in.read(reinterpret_cast<char*>(&preserveCoarseDOFs), sizeof(bool)); + + // read nDOFEl + oldVal = nDOFEl; + in.read(reinterpret_cast<char*>(&nDOFEl), sizeof(int)); + TEST_EXIT((oldVal == 0) || (nDOFEl == oldVal))("invalid nDOFEl\n"); + + // read nDOF + nDOF.deserialize(in); + + // read nNodeEl + oldVal = nNodeEl; + in.read(reinterpret_cast<char*>(&nNodeEl), sizeof(int)); + TEST_EXIT((oldVal == 0) || (nNodeEl == oldVal))("invalid nNodeEl\n"); + + // read node + node.deserialize(in); + + // read admins + int i, size; + in.read(reinterpret_cast<char*>(&size), sizeof(int)); + admin.resize(size, NULL); + for (i = 0; i < size; i++) { + if (!admin[i]) { + admin[i] = NEW DOFAdmin(this); + } + admin[i]->deserialize(in); + } + + // read macroElements + in.read(reinterpret_cast<char*>(&size), sizeof(int)); + + ::std::vector< ::std::vector<int> > neighbourIndices(size); + + for (i = 0; i < static_cast<int>(macroElements.size()); i++) { + if (macroElements[i]) { + DELETE macroElements[i]; + } + } + macroElements.resize(size); + for(i = 0; i < size; i++) { + macroElements[i] = NEW MacroElement(dim); + macroElements[i]->writeNeighboursTo(&(neighbourIndices[i])); + macroElements[i]->deserialize(in); + } + + // read elementIndex + in.read(reinterpret_cast<char*>(&elementIndex), sizeof(int)); + + // read initialized + in.read(reinterpret_cast<char*>(&initialized), sizeof(bool)); + + // set neighbour pointer in macro elements + int j, neighs = getGeo(NEIGH); + for(i = 0; i < static_cast<int>(macroElements.size()); i++) { + for(j = 0; j < neighs; j++) { + int index = neighbourIndices[i][j]; + if(index != -1) { + macroElements[i]->setNeighbour(j, macroElements[index]); + } else { + macroElements[i]->setNeighbour(j, NULL); + } + } + } + + // set mesh pointer in elements + TraverseStack stack; + ElInfo *elInfo = stack.traverseFirst(this, -1, CALL_EVERY_EL_PREORDER); + while(elInfo) { + elInfo->getElement()->setMesh(this); + elInfo = stack.traverseNext(elInfo); + } + + serializedDOFs.clear(); + } + + void Mesh::initialize() + { + ::std::string macroFilename(""); + ::std::string valueFilename(""); + ::std::string periodicFile(""); + int check = 1; + + GET_PARAMETER(0, name + "->macro file name", ¯oFilename); + GET_PARAMETER(0, name + "->value file name", &valueFilename); + GET_PARAMETER(0, name + "->periodic file", &periodicFile); + GET_PARAMETER(0, name + "->check", "%d", &check); + GET_PARAMETER(0, name + "->preserve coarse dofs", "%d", &preserveCoarseDOFs); + + if (macroFilename.length()) { + macroFileInfo_ = MacroReader::readMacro(macroFilename.c_str(), + this, + periodicFile == "" ? NULL : periodicFile.c_str(), + check); + + // If there is no value file which should be written, we can delete + // the information of the macro file. + if (!valueFilename.length()) { + clearMacroFileInfo(); + } + } + + initialized = true; + } + + bool Mesh::associated(DegreeOfFreedom dof1, DegreeOfFreedom dof2) { + ::std::map<BoundaryType, VertexVector*>::iterator it; + ::std::map<BoundaryType, VertexVector*>::iterator end = periodicAssociations.end(); + for (it = periodicAssociations.begin(); it != end; ++it) { + if ((*(it->second))[dof1] == dof2) + return true; + } + return false; + } + + bool Mesh::indirectlyAssociated(DegreeOfFreedom dof1, DegreeOfFreedom dof2) { + ::std::vector<DegreeOfFreedom> associatedToDOF1; + int i, size; + ::std::map<BoundaryType, VertexVector*>::iterator it; + ::std::map<BoundaryType, VertexVector*>::iterator end = periodicAssociations.end(); + DegreeOfFreedom dof, assDOF; + + associatedToDOF1.push_back(dof1); + for(it = periodicAssociations.begin(); it != end; ++it) { + size = static_cast<int>(associatedToDOF1.size()); + for(i = 0; i < size; i++) { + dof = associatedToDOF1[i]; + assDOF = (*(it->second))[dof]; + if(assDOF == dof2) { + return true; + } else { + if(assDOF != dof) associatedToDOF1.push_back(assDOF); + } + } + } + return false; + } + + void Mesh::clearMacroFileInfo() + { + macroFileInfo_->clear(getNumberOfEdges(), + getNumberOfVertices()); + DELETE macroFileInfo_; + } +} diff --git a/AMDiS/src/Mesh.h b/AMDiS/src/Mesh.h new file mode 100644 index 0000000000000000000000000000000000000000..d0e7b9304dc379702165bddc74ae38993332990a --- /dev/null +++ b/AMDiS/src/Mesh.h @@ -0,0 +1,933 @@ +// ============================================================================ +// == == +// == AMDiS - Adaptive multidimensional simulations == +// == == +// ============================================================================ +// == == +// == crystal growth group == +// == == +// == Stiftung caesar == +// == Ludwig-Erhard-Allee 2 == +// == 53175 Bonn == +// == germany == +// == == +// ============================================================================ +// == == +// == http://www.caesar.de/cg/AMDiS == +// == == +// ============================================================================ + +/** \file Mesh.h */ + +/** \defgroup Triangulation Triangulation module + * @{ <img src="triangulation.png"> @} + * + * Example: + * + * @{ <img src="hierarchicalMesh.png"> @} + * + * \brief + * Contains all triangulation classes. + */ + +#ifndef AMDIS_MESH_H +#define AMDIS_MESH_H + +// ============================================================================ +// ===== includes ============================================================= +// ============================================================================ + +#include "DOFAdmin.h" +#include "Line.h" +#include "Triangle.h" +#include "Tetrahedron.h" +#include "Element.h" +#include "ElInfo.h" +#include "FixVec.h" +#include "MemoryManager.h" +#include "Serializable.h" +#include "BoundaryCondition.h" +#include <deque> +#include <set> +#include <stdio.h> + +namespace AMDiS { + + // ============================================================================ + // ===== forward declarations ================================================= + // ============================================================================ + + template <typename T> class DimVec; + template <typename T> class VectorOfFixVecs; + class Boundary; + class Projection; + class ElInfo; + class Element; + class MacroElement; + class DOFAdmin; + class MacroInfo; + template<typename T> class WorldVector; + class Quadrature; + class Parametric; + class PeriodicBC; + class DOFVectorDOF; + class VertexVector; + + // ============================================================================ + // ===== class Mesh =========================================================== + // ============================================================================ + + /** \ingroup Triangulation + * \brief + * A Mesh holds all information about a triangulation. + */ + class Mesh : public Serializable + { + public: + MEMORY_MANAGED(Mesh); + + /** \brief + * Creates a mesh with the given name of dimension dim + */ + Mesh(const ::std::string& name, int dim); + + /** \brief + * Destructor + */ + virtual ~Mesh(); + + /** \brief + * Reads macro triangulation. + */ + void initialize(); + + /** \brief + * Assignment operator + */ + Mesh& operator=(const Mesh&); + + /** \name static methods used while mesh traversal + * \{ + */ + + /** \brief + * Used while dof compress + */ + static int newDOFFct1(ElInfo* e); + + /** \brief + * Used while dof compress + */ + static int newDOFFct2(ElInfo* e); + /** \} */ + + + // ========================================================================== + /** \name getting methods + * \{ + */ + + /** \brief + * Returns geometric information about this mesh. With GeoIndex p it is + * specifiedm which information is requested. + */ + inline int getGeo(GeoIndex p) const { + return Global::getGeo(p, dim); + }; + + /** \brief + * Returns \ref name of the mesh + */ + inline const ::std::string& getName() const { + return name; + }; + + /** \brief + * Returns \ref dim of the mesh + */ + inline int getDim() const { + return dim; + }; + + /** \brief + * Returns \ref nDOFEl of the mesh + */ + inline const int getNumberOfAllDOFs() const { + return nDOFEl; + }; + + /** \brief + * Returns \ref nNodeEl of the mesh + */ + inline const int getNumberOfNodes() const { + return nNodeEl; + }; + + /** \brief + * Returns \ref nVertices of the mesh + */ + inline const int getNumberOfVertices() const { + return nVertices; + }; + + /** \brief + * Returns \ref nEdges of the mesh + */ + inline const int getNumberOfEdges() const { + return nEdges; + }; + + /** \brief + * Returns \ref nFaces of the mesh + */ + inline const int getNumberOfFaces() const { + return nFaces; + }; + + /** \brief + * Returns \ref nLeaves of the mesh + */ + inline const int getNumberOfLeaves() const { + return nLeaves; + }; + + /** \brief + * Returns \ref nElements of the mesh + */ + inline const int getNumberOfElements() const { + return nElements; + }; + + /** \brief + * Returns \ref maxEdgeNeigh of the mesh + */ + inline const int getMaxEdgeNeigh() const { + return maxEdgeNeigh; + }; + + /** \brief + * Returns \ref parametric of the mesh + */ + inline Parametric *getParametric() const { + return parametric; + }; + + /** \brief + * Returns \ref diam of the mesh + */ + inline const WorldVector<double>& getDiameter() const { + return diam; + }; + + /** \brief + * Returns nDOF[i] of the mesh + */ + inline const int getNumberOfDOFs(int i) const { + return nDOF[i]; + }; + + /** \brief + * Returns \ref elementPrototype of the mesh + */ + inline Element* getElementPrototype() { + return elementPrototype; + }; + + /** \brief + * Returns \ref leafDataPrototype of the mesh + */ + inline ElementData* getElementDataPrototype() { + return elementDataPrototype; + }; + + /** \brief + * Returns node[i] of the mesh + */ + inline int getNode(int i) const { + return node[i]; + }; + + /** \brief + * Allocates the number of DOFs needed at position and registers the DOFs + * at the DOFAdmins. The number of needed DOFs is the sum over the needed + * DOFs of all DOFAdmin objects belonging to this mesh. + * The return value is a pointer to the first allocated DOF. + */ + DegreeOfFreedom *getDOF(GeoIndex position); + + /** \brief + * Returns *(\ref admin[i]) of the mesh + */ + inline const DOFAdmin& getDOFAdmin(int i) const { + return *(admin[i]); + }; + + /** \brief + * Creates a DOFAdmin with name lname. nDOF specifies how many DOFs + * are needed at the different positions (see \ref DOFAdmin::nrDOF). + * A pointer to the created DOFAdmin is returned. + */ + const DOFAdmin* createDOFAdmin(const ::std::string& lname, DimVec<int> nDOF); + + /** \brief + * Returns the size of \ref admin which is the number of the DOFAdmins + * belonging to this mesh + */ + const int getNumberOfDOFAdmin() const {return admin.size();}; + + /** \brief + * Returns the size of \ref macroElements which is the number of + * of macro elements of this mesh + */ + const int getNumberOfMacros() const {return macroElements.size();}; + + /** \brief + * Returns a DOFAdmin which at least manages vertex DOFs + */ + const DOFAdmin* getVertexAdmin() const; + + /** \brief + * Allocates a array of DOF pointers. The array holds one pointer for + * each node. + */ + DegreeOfFreedom **createDOFPtrs(); + + /** \brief + * Returns \ref preserveCoarseDOFs of the mesh + */ + inline bool queryCoarseDOFs() const { + return preserveCoarseDOFs; + }; + + /** \brief + * Returns an iterator to the begin of \ref macroElements + */ + inline ::std::deque<MacroElement*>::iterator firstMacroElement() { + return macroElements.begin(); + }; + + /** \brief + * Returns macroElements[i]. + */ + inline MacroElement *getMacroElement(int i) { + return macroElements[i]; + }; + + /** \brief + * Returns an iterator to the end of \ref macroElements + */ + inline ::std::deque<MacroElement*>::iterator endOfMacroElements() { + return macroElements.end(); + }; + + // /** \brief + // * Returns the begin of \ref meshes + // */ + // static ::std::list<Mesh*>::iterator begin() { return meshes.begin(); }; + + // /** \brief + // * Returns the end of \ref meshes + // */ + // static ::std::list<Mesh*>::iterator end() { return meshes.end(); }; + + /** \} */ + + // ========================================================================== + /** \name setting methods + * \{ + */ + + /** \brief + * Sets \ref name of the mesh + */ + inline void setName(const ::std::string& aName) { name=aName;}; + + /** \brief + * Sets \ref nVertices of the mesh + */ + inline void setNumberOfVertices(int n) { nVertices=n; }; + + /** \brief + * Sets \ref nFaces of the mesh + */ + inline void setNumberOfFaces(int n) { nFaces=n; }; + + /** \brief + * Increments \ref nVertices by inc + */ + inline void incrementNumberOfVertices(int inc) { nVertices += inc; }; + + /** \brief + * Sets \ref nEdges of the mesh + */ + inline void setNumberOfEdges(int n) { nEdges=n; }; + + /** \brief + * Increments \ref nEdges by inc + */ + inline void incrementNumberOfEdges(int inc) { nEdges += inc; }; + + /** \brief + * Increments \ref nFaces by inc + */ + inline void incrementNumberOfFaces(int inc) { nFaces += inc; }; + + /** \brief + * Sets \ref nLeaves of the mesh + */ + inline void setNumberOfLeaves(int n) { nLeaves=n; }; + + /** \brief + * Increments \ref nLeaves by inc + */ + inline void incrementNumberOfLeaves(int inc) { + nLeaves += inc; + }; + + /** \brief + * Sets \ref nElements of the mesh + */ + inline void setNumberOfElements(int n) { nElements=n; }; + + /** \brief + * Increments \ref nElements by inc + */ + inline void incrementNumberOfElements(int inc) { nElements += inc; }; + + /** \brief + * Sets *\ref diam to w + */ + void setDiameter(const WorldVector<double>& w); + + /** \brief + * Sets (*\ref diam)[i] to d + */ + void setDiameter(int i, double d); + + /** \brief + * Sets \ref preserveCoarseDOFs = true + */ + inline void retainCoarseDOFs() {preserveCoarseDOFs=true;}; + + /** \brief + * Sets \ref preserveCoarseDOFs = b + */ + inline void setPreserveCoarseDOFs(bool b) {preserveCoarseDOFs=b;}; + + /** \brief + * Sets \ref preserveCoarseDOFs = false + */ + inline void noCoarseDOFs() {preserveCoarseDOFs=false;}; + + /** \brief + * Sets \ref elementPrototype of the mesh + */ + inline void setElementPrototype(Element* prototype) { + elementPrototype = prototype; + }; + + /** \brief + * Sets \ref elementDataPrototype of the mesh + */ + inline void setElementDataPrototype(ElementData* prototype) { + elementDataPrototype = prototype; + }; + + inline void setParametric(Parametric *param) { + parametric = param; + }; + + inline void setMaxEdgeNeigh(int m) { maxEdgeNeigh = m; }; + + /** \} */ + // ========================================================================== + + /** \brief + * Creates a new Element by cloning \ref elementPrototype + */ + Element* createNewElement(Element *parent = NULL); + + /** \brief + * Creates a new ElInfo dependent of \ref dim of the mesh + */ + ElInfo* createNewElInfo(); + + /** \brief + * Frees DOFs at the given position pointed by dof + */ + void freeDOF(DegreeOfFreedom* dof, GeoIndex position); + + /** \brief + * Frees memory for the given element el + */ + void freeElement(Element* el); + + /** \brief + * Performs DOF compression for all DOFAdmins (see \ref DOFAdmin::compress) + */ + void dofCompress(); + + /** \brief + * Adds a DOFAdmin to the mesh + */ + virtual void addDOFAdmin(DOFAdmin *admin_); + + /** \brief + * Traverses the mesh. The argument level specifies the element level if + * CALL_EL_LEVEL or CALL_LEAF_EL_LEVEL, or the multigrid level if + * CALL_MG_LEVEL is set. Otherwise this variable is ignored. By the argument + * fillFlag the elements to be traversed and data to be filled into ElInfo is + * selected, using bitwise or of one CALL_... flag and several FILL_... + * flags. The argument elFct is a pointer to a function which is called on + * every element selected by the CALL_... part of fillFlag. + * It is possible to use the recursive mesh traversal recursively, by calling + * traverse() from elFct. + */ + int traverse(int level, + const Flag fillFlag, + int (*elFct)(ElInfo*)); + + /** \brief + * Clears \ref macroElements + */ + inline void clearMacroElements() { macroElements.clear();}; + + /** \brief + * Adds a macro element to the mesh + */ + void addMacroElement(MacroElement* me); + + /** \brief + * Frees the array of DOF pointers (see \ref createDOFPtrs) + */ + void freeDOFPtrs(DegreeOfFreedom **ptrs); + + /** \brief + * Used by \ref findElementAtPoint. + */ + bool findElInfoAtPoint(const WorldVector<double>& xy, + ElInfo *el_info, + DimVec<double>& bary, + const MacroElement *start_mel, + const WorldVector<double> *xy0, + double *sp); + + /** \brief + * Access to an element at world coordinates xy. Some applications need the + * access to elements at a special location in world coordinates. Examples + * are characteristic methods for convection problems, or the implementation + * of a special right hand side like point evaluations or curve integrals. + * For such purposes, a routine is available which returns an element pointer + * and corresponding barycentric coordinates. + * + * \param xy world coordinates of point + * \param elp return address for a pointer to the element at xy + * \param pary returns barycentric coordinates of xy + * \param start_mel initial guess for the macro element containing xy or NULL + * \param xy0 start point from a characteristic method, see below, or NULL + * \param sp return address for relative distance to domain boundary in a + * characteristic method, see below, or NULL + * \return true is xy is inside the domain , false otherwise + * + * For a characteristic method, where \f$ xy = xy_0 - V\tau \f$, it may be + * convenient to know the point on the domain's boundary which lies on the + * line segment between the old point xy0 and the new point xy, in case that + * xy is outside the domain. Such information is returned when xy0 and a + * pointer sp!=NULL are supplied: *sp is set to the value s such that + * \f$ xy_0 +s (xy -xy_0) \in \partial Domain \f$, and the element and local + * coordinates corresponding to that boundary point will be returned via elp + * and bary. + * + * The implementation of findElementAtPoint() is based on the transformation + * from world to local coordinates, available via the routine worldToCoord(), + * At the moment, findElementAtPoint() works correctly only for domains with + * non-curved boundary. This is due to the fact that the implementation first + * looks for the macro-element containing xy and then finds its path through + * the corresponding element tree based on the macro barycentric coordinates. + * For non-convex domains, it is possible that in some cases a point inside + * the domain is considered as external. + */ + bool findElementAtPoint(const WorldVector<double>& xy, + Element **elp, + DimVec<double>& bary, + const MacroElement *start_mel, + const WorldVector<double> *xy0, + double *sp); + + + /** \brief + * Returns FILL_ANY_?D + */ + inline static const Flag& getFillAnyFlag(int dim) { + switch(dim) { + case 1: + return FILL_ANY_1D; + break; + case 2: + return FILL_ANY_2D; + break; + case 3: + return FILL_ANY_3D; + break; + default: + ERROR_EXIT("invalid dim\n"); + return FILL_ANY_1D; + } + }; + + // ===== Serializable implementation ===== + + void serialize(::std::ostream &out); + + void deserialize(::std::istream &in); + + /** \brief + * Returns \ref elementIndex and increments it by 1. + */ + inline int getNextElementIndex() { + return elementIndex++; + }; + + /** \brief + * Returns \ref initialized. + */ + inline bool isInitialized() { return initialized; }; + + // inline void addPeriodicBC(BoundaryType type) { + // periodicBoundaryTypes.insert(type); + // }; + + // inline bool isPeriodicBC(BoundaryType type) { + // return (periodicBoundaryTypes.find(type) != periodicBoundaryTypes.end()); + // }; + + // inline ::std::map<BoundaryType, PeriodicBC*>& getPeriodicBCMap() { + // return periodicBoundaryConditions; + // }; + + inline ::std::map<BoundaryType, VertexVector*>& getPeriodicAssociations() { + return periodicAssociations; + }; + + bool associated(DegreeOfFreedom dof1, DegreeOfFreedom dof2); + + bool indirectlyAssociated(DegreeOfFreedom dof1, DegreeOfFreedom dof2); + + inline MacroInfo* getMacroFileInfo() { + return macroFileInfo_; + }; + + void clearMacroFileInfo(); + + public: + /** \brief + * + */ + static const Flag FILL_NOTHING; + + /** \brief + * + */ + static const Flag FILL_COORDS ; + + /** \brief + * + */ + static const Flag FILL_BOUND ; + + /** \brief + * + */ + static const Flag FILL_NEIGH ; + + /** \brief + * + */ + static const Flag FILL_OPP_COORDS ; + + /** \brief + * + */ + static const Flag FILL_ORIENTATION; + + /** \brief + * + */ + static const Flag FILL_ADD_ALL ; + + /** \brief + * + */ + static const Flag FILL_ANY_1D ; + + /** \brief + * + */ + static const Flag FILL_ANY_2D ; + + /** \brief + * + */ + static const Flag FILL_ANY_3D ; + + static const Flag FILL_DET; + static const Flag FILL_GRD_LAMBDA; + + //************************************************************************** + // flags for Mesh traversal + //************************************************************************** + + /** \brief + * + */ + static const Flag CALL_EVERY_EL_PREORDER; + + /** \brief + * + */ + static const Flag CALL_EVERY_EL_INORDER; + + /** \brief + * + */ + static const Flag CALL_EVERY_EL_POSTORDER; + + /** \brief + * + */ + static const Flag CALL_LEAF_EL; + + /** \brief + * + */ + static const Flag CALL_LEAF_EL_LEVEL; + + /** \brief + * + */ + static const Flag CALL_EL_LEVEL; + + /** \brief + * + */ + static const Flag CALL_MG_LEVEL; + + protected: + bool findElementAtPointRecursive(ElInfo *elinfo, + const DimVec<double>& lambda, + int outside, + ElInfo *final_el_info); + + protected: + /** \brief + * maximal number of DOFs at one position + */ + static const int MAX_DOF; + + /** \brief + * Name of this Mesh + */ + ::std::string name; + + /** \brief + * Dimension of this Mesh. Doesn't have to be equal to dimension of world. + */ + int dim; + + /** \brief + * Number of vertices in this Mesh + */ + int nVertices; + + /** \brief + * Number of Edges in this Mesh + */ + int nEdges; + + /** \brief + * Number of leaf elements in this Mesh + */ + int nLeaves; + + /** \brief + * Total number of elements in this Mesh + */ + int nElements; + + /** \brief + * Number of faces in this Mesh + */ + int nFaces; + + /** \brief + * Maximal number of elements that share one edge; used to allocate memory + * to store pointers to the neighbour at the refinement/coarsening edge + * (only 3d); + */ + int maxEdgeNeigh; + + /** \brief + * Diameter of the mesh in the DIM_OF_WORLD directions + */ + WorldVector<double> diam; + + /** \brief + * Is pointer to NULL if mesh contains no parametric elements else pointer + * to a Parametric object containing coefficients of the parameterization + * and related information + */ + Parametric *parametric; + + /** \brief + * If the value is non zero then preserve all DOFs on all levels (can + * be used for multigrid, e.g.); otherwise all DOFs on the parent that are + * not handed over to a child are removed during refinement and added again + * on the parent during coarsening. + */ + bool preserveCoarseDOFs; + + // /** \brief + // * List of all Meshes. Can be accessed via Mesh::begin() and Mesh::end() + // */ + // static ::std::list<Mesh*> meshes; + + /** \brief + * Number of all DOFs on a single element + */ + int nDOFEl; + + /** \brief + * Number of DOFs at the different positions VERTEX, EDGE, (FACE,) CENTER on + * an element: + * + * - nDOF[VERTEX]: number of DOFs at a vertex (>= 1) + * + * - nDOF[EDGE]: number of DOFs at an edge; if no DOFs are associated to + * edges, then this value is 0 + * + * - nDOF[FACE]: number of DOFs at a face; if no DOFs are associated to + * faces, then this value is 0 (only 3d) + * + * - nDOF[CENTER]: number of DOFs at the barycenter; if no DOFs are + * associated to the barycenter, then this value is 0 + */ + DimVec<int> nDOF; + + /** \brief + * Number of nodes on a single element where DOFs are located; needed for + * the (de-) allocation of the dof-vector on the element (\ref Element::dof); + */ + int nNodeEl; + + /** \brief + * Gives the index of the first node at vertex, edge, face (only 3d), and + * barycenter: + * + * - node[VERTEX]: has always value 0; dof[0],...,dof[N_VERTICES-1] are + * always DOFs at the vertices; + * + * - node[EDGE]: dof[node[EDGE]],..., dof[node[EDGE]+N_EDGES-1] are the DOFs + * at the N_EDGES edges, if DOFs are located at edges; + * + * - node[FACE]: dof[node[FACE]],..., dof[node[FACE]+N_FACES-1] are the DOFs + * at the N_FACES faces, if DOFs are located at faces (only 3d); + * + * - node[CENTER]: dof[node[CENTER]] are the DOFs at the barycenter, if DOFs + * are located at the barycenter; + */ + DimVec<int> node; + + /** \brief + * list of all DOFAdmins + */ + ::std::vector<DOFAdmin*> admin; + + /** \brief + * List of all MacroElements of this Mesh + */ + ::std::deque<MacroElement*> macroElements; + + /** \brief + * Needed during DOF compression (\ref DOFAdmin::compress). + */ + ::std::vector<DegreeOfFreedom> newDOF; + + /** \brief + * Needed during DOF compression (\ref DOFAdmin::compress). + */ + static DOFAdmin *compressAdmin; + + /** \brief + * Used for recursive mesh traversal. Static pointer to the mesh + * that should be traversed. This allows access to the mesh even + * from the static traverse routines + */ + static Mesh* traversePtr; + + /** \brief + * Used by compress- and check functions. Number of the current DOFAdmin + */ + static int iadmin; + + /** \brief + * Used by check functions + */ + static ::std::vector<DegreeOfFreedom> dof_used; + + static ::std::map<DegreeOfFreedom, DegreeOfFreedom*> serializedDOFs; + + /** \brief + * Used while mesh refinement. To create new elements + * elementPrototype->clone() is called, which returns a Element of the + * same type as elementPrototype. So e.g. Elements of the different + * dimensions can be created in a uniform way. + */ + Element* elementPrototype; + + /** \brief + * Prototype for leaf data. Used for creation of new leaf data while + * refinement. + */ + ElementData* elementDataPrototype; + + /** \brief + * Used for enumeration of all mesh elements + */ + int elementIndex; + + /** \brief + * True if the mesh is already initialized, false otherwise. + */ + bool initialized; + + /** \brief + * Map of managed periodic vertex associations. + */ + ::std::map<BoundaryType, VertexVector*> periodicAssociations; + + /** \brief + * If the mesh has been created by reading a macro file, here + * the information are stored about the content of the file. + */ + MacroInfo *macroFileInfo_; + + protected: + // for findElement-Fcts + DimVec<double> final_lambda; + const WorldVector<double> *g_xy0, *g_xy; + double *g_sp; + + friend class MacroInfo; + friend class MacroReader; + friend class MacroWriter; + friend class MacroElement; + friend class Element; + friend void Element::newDOFFct1(const DOFAdmin*); + friend void Element::newDOFFct2(const DOFAdmin*); + }; + +} + +#endif // AMDIS_MESH_H + + diff --git a/AMDiS/src/MeshStructure.cc b/AMDiS/src/MeshStructure.cc new file mode 100644 index 0000000000000000000000000000000000000000..904ecd09403b08dc844ebe5808439fc32b8a3d08 --- /dev/null +++ b/AMDiS/src/MeshStructure.cc @@ -0,0 +1,202 @@ +#include "MeshStructure.h" +#include "MeshStructure_ED.h" +#include "PartitionElementData.h" +#include "Mesh.h" +#include "Element.h" +#include "Traverse.h" +#include "ElInfo.h" +#include "RefinementManager.h" +#include "mpi.h" + +namespace AMDiS { + + const int MeshStructure::unsignedLongSize_ = sizeof(unsigned long int) * 8; + + void MeshStructure::insertElement(bool isLeaf) { + // overflow? -> next index + if(pos_ >= unsignedLongSize_) { + code_.push_back(currentCode_); + pos_ = 0; + currentCode_ = 0; + } + + // insert element in binary code + if(!isLeaf) { + unsigned long int one = 1; + currentCode_ += (one << pos_); + } + + pos_++; + numElements_++; + } + + void MeshStructure::clear() + { + currentCode_ = 0; + code_.resize(0); + pos_ = 0; + numElements_ = 0; + currentElement_ = 0; + } + + void MeshStructure::init(Mesh *mesh) + { + clear(); + TraverseStack stack; + ElInfo *elInfo = stack.traverseFirst(mesh, -1, Mesh::CALL_EVERY_EL_PREORDER); + while(elInfo) { + insertElement(elInfo->getElement()->isLeaf()); + elInfo = stack.traverseNext(elInfo); + } + + commit(); + } + + void MeshStructure::reset() { + currentIndex_ = 0; + currentCode_ = code_[0]; + pos_ = 0; + currentElement_ = 0; + } + + bool MeshStructure::nextElement(MeshStructure *insert) + { + if(insert) { + insert->insertElement(isLeafElement()); + } + + pos_++; + currentElement_++; + + if(currentElement_ >= numElements_) return false; + + if(pos_ >= unsignedLongSize_) { + currentIndex_++; + TEST_EXIT(currentIndex_ < static_cast<int>(code_.size())) + ("end of structure reached\n"); + pos_ = 0; + currentCode_ = code_[currentIndex_]; + } else { + currentCode_ >>= 1; + } + return true; + } + + bool MeshStructure::skipBranch(MeshStructure *insert) + { + if(isLeafElement()) { + return nextElement(insert); + } else { + bool cont = nextElement(insert); + cont = skipBranch(insert); // left branch + TEST_EXIT(cont)("invalid structure\n"); + cont = skipBranch(insert); // righ branch + return cont; + } + } + + void MeshStructure::merge(MeshStructure *structure1, + MeshStructure *structure2, + MeshStructure *result) + { + result->clear(); + structure1->reset(); + structure2->reset(); + + bool cont = true; + while(cont) { + bool cont1, cont2; + if(structure1->isLeafElement() == structure2->isLeafElement()) { + cont1 = structure1->nextElement(result); + cont2 = structure2->nextElement(); + } else { + if(structure1->isLeafElement()) { + cont1 = structure1->nextElement(); + cont2 = structure2->skipBranch(result); + } else { + cont1 = structure1->skipBranch(result); + cont2 = structure2->nextElement(); + } + } + TEST_EXIT(cont1 == cont2)("structures don't match\n"); + cont = cont1; + } + + result->commit(); + } + + void MeshStructure::fitMeshToStructure(Mesh *mesh, + RefinementManager *manager, + bool checkPartition) + { + FUNCNAME("MeshStructure::fitMeshToStructure()"); + + TraverseStack stack; + ElInfo *elInfo; + + + bool cont = true; + + // decorate leaf data + reset(); + elInfo = stack.traverseFirst(mesh, -1, Mesh::CALL_EVERY_EL_PREORDER); + while(elInfo) { + TEST_EXIT(cont)("unexpected structure code end!\n"); + + Element *element = elInfo->getElement(); + + if(isLeafElement()) { + TEST_EXIT(element->isLeaf())("mesh finer than code\n"); + }; + + if(element->isLeaf() && !isLeafElement()) { + MeshStructure *structure = NEW MeshStructure(); + cont = skipBranch(structure); + structure->commit(); + + bool decorate = true; + if(checkPartition) { + PartitionElementData *partitionData = dynamic_cast<PartitionElementData*> + (element->getElementData(PARTITION_ED)); + TEST_EXIT(partitionData)("no partition element data\n"); + PartitionStatus status = partitionData->getPartitionStatus(); + if(status == OUT || status == UNDEFINED) { + decorate = false; + } + } + + if(decorate) { + MeshStructure_ED *elData = NEW MeshStructure_ED(element->getElementData()); + elData->setStructure(structure); + element->setElementData(elData); + } else { + DELETE structure; + } + } else { + cont = nextElement(); + } + + elInfo = stack.traverseNext(elInfo); + } + + // refine mesh + bool finished; + + do { + finished = true; + elInfo = stack.traverseFirst(mesh, -1, Mesh::CALL_LEAF_EL); + while(elInfo) { + Element *element = elInfo->getElement(); + if(element->getElementData(MESH_STRUCTURE) != NULL) { + element->setMark(1); + finished = false; + } else { + element->setMark(0); + } + elInfo = stack.traverseNext(elInfo); + } + manager->refineMesh(mesh); + } while(!finished); + } + +} diff --git a/AMDiS/src/MeshStructure.h b/AMDiS/src/MeshStructure.h new file mode 100644 index 0000000000000000000000000000000000000000..4690391fe4bc51ad65f17f9e47a640c3179d7218 --- /dev/null +++ b/AMDiS/src/MeshStructure.h @@ -0,0 +1,138 @@ +// ============================================================================ +// == == +// == AMDiS - Adaptive multidimensional simulations == +// == == +// ============================================================================ +// == == +// == crystal growth group == +// == == +// == Stiftung caesar == +// == Ludwig-Erhard-Allee 2 == +// == 53175 Bonn == +// == germany == +// == == +// ============================================================================ +// == == +// == http://www.caesar.de/cg/AMDiS == +// == == +// ============================================================================ + +/** \file MeshStructure.h */ + +#ifndef AMDIS_MESHSTRUCTURE_H +#define AMDIS_MESHSTRUCTURE_H + +#include <vector> +#include "MemoryManager.h" + +namespace AMDiS { + + class RefinementManager; + class TraverseStack; + class ElInfo; + + class MeshStructure + { + public: + MEMORY_MANAGED(MeshStructure); + + MeshStructure() + : currentIndex_(0), + currentCode_(0), + pos_(0), + currentElement_(0), + numElements_(0) + {}; + + void clear(); + + void init(Mesh *mesh); + + void init(const std::vector<unsigned long int>& code, + int numElements) + { + code_ = code; + numElements_ = numElements; + reset(); + }; + + void reset(); + + void insertElement(bool isLeaf); + + inline void commit() { + if(pos_ > 0) { + code_.push_back(currentCode_); + } + reset(); + }; + + bool skipBranch(MeshStructure *insert = NULL); + + ElInfo *skipBranch(ElInfo *elInfo, TraverseStack *stack); + + bool nextElement(MeshStructure *insert = NULL); + + inline bool isLeafElement() { + return (currentCode_ & 1) == 0; + }; + + void merge(MeshStructure *structure) { + MeshStructure temp(*this); + merge(&temp, structure, this); + }; + + static void merge(MeshStructure *structure1, + MeshStructure *structure2, + MeshStructure *result); + + void fitMeshToStructure(Mesh *mesh, + RefinementManager *manager, + bool checkPartition = false); + + void print() { + FUNCNAME("MeshStructure::print()"); + reset(); + bool cont = true; + while(cont) { + if(isLeafElement()) { + MSG("0"); + } else { + MSG("1"); + } + cont = nextElement(); + } + MSG("\n"); + }; + + inline const std::vector<unsigned long int>& getCode() { + return code_; + }; + + inline int getNumElements() { + return numElements_; + }; + + inline int getCurrentElement() { + return currentElement_; + }; + + protected: + std::vector<unsigned long int> code_; + + int currentIndex_; + + unsigned long int currentCode_; + + int pos_; + + int currentElement_; + + int numElements_; + + static const int unsignedLongSize_; + }; + +} + +#endif diff --git a/AMDiS/src/MeshStructure_ED.h b/AMDiS/src/MeshStructure_ED.h new file mode 100644 index 0000000000000000000000000000000000000000..2abe5938109eee78334fad4c055d716616fc26d7 --- /dev/null +++ b/AMDiS/src/MeshStructure_ED.h @@ -0,0 +1,108 @@ +// ============================================================================ +// == == +// == AMDiS - Adaptive multidimensional simulations == +// == == +// ============================================================================ +// == == +// == crystal growth group == +// == == +// == Stiftung caesar == +// == Ludwig-Erhard-Allee 2 == +// == 53175 Bonn == +// == germany == +// == == +// ============================================================================ +// == == +// == http://www.caesar.de/cg/AMDiS == +// == == +// ============================================================================ + +/** \file MeshStructure.h */ + +#ifndef AMDIS_MESHSTRUCTURE_ED_H +#define AMDIS_MESHSTRUCTURE_ED_H + +#include <vector> +#include "MeshStructure.h" +#include "ElementData.h" +#include "Element.h" + +namespace AMDiS { + + const int MESH_STRUCTURE = 10; + + class MeshStructure_ED : public ElementData + { + public: + MeshStructure_ED(ElementData *decorated = NULL) + : ElementData(decorated), + structure_(NULL) + {}; + + virtual ~MeshStructure_ED() { + DELETE structure_; + }; + + virtual bool refineElementData(Element* parent, + Element* child1, + Element* child2, + int elType) + { + ElementData::refineElementData(parent, child1, child2, elType); + + structure_->reset(); + + TEST_EXIT(structure_)("no structure\n"); + + TEST_EXIT(!structure_->isLeafElement()) + ("don't store leaf structures\n"); + + structure_->nextElement(); + + if(!structure_->isLeafElement()) { + MeshStructure *structure1 = NEW MeshStructure(); + structure_->skipBranch(structure1); + structure1->commit(); + MeshStructure_ED *elData1 = NEW MeshStructure_ED(child1->getElementData()); + elData1->setStructure(structure1); + child1->setElementData(elData1); + } else { + structure_->nextElement(); + } + + if(!structure_->isLeafElement()) { + MeshStructure *structure2 = NEW MeshStructure(); + structure_->skipBranch(structure2); + structure2->commit(); + MeshStructure_ED *elData2 = NEW MeshStructure_ED(child2->getElementData()); + elData2->setStructure(structure2); + child2->setElementData(elData2); + } + + return true; + }; + + virtual const int getTypeID() const { + return MESH_STRUCTURE; + }; + + virtual bool isOfType(int typeID) const { + if(typeID == MESH_STRUCTURE) return true; + return false; + }; + + inline void setStructure(MeshStructure *structure) { + structure_ = structure; + }; + + inline MeshStructure *getStructure() { + return structure_; + }; + + protected: + MeshStructure *structure_; + }; + +} + +#endif diff --git a/AMDiS/src/MpCCIAdapter.cc b/AMDiS/src/MpCCIAdapter.cc new file mode 100644 index 0000000000000000000000000000000000000000..6b3ad245b64f50cf25ffe56bf273ec749c3d5fc5 --- /dev/null +++ b/AMDiS/src/MpCCIAdapter.cc @@ -0,0 +1,593 @@ +#include "MpCCIAdapter.h" +#include "FiniteElemSpace.h" +#include "SMIAdapter.h" +#include "DOFVector.h" +#include "mpi.h" + +namespace AMDiS +{ + + MpCCIAdapter::MpCCIAdapter(int localComm, + int meshID, + int partitionID, + bool useMPI, + FiniteElemSpace *feSpace, + int elementRegion, + int surfaceRegion, + int numQuantities, + int *quantityIDs, + int *quantityDims, + DOFVector<double> **dofVectors, + int numSyncPoints, + int *syncPointIDs, + const char *idString, + bool (*elementFct)(ElInfo *elInfo), + bool (*surfaceFct)(ElInfo *elInfo, int side)) + : localComm_(localComm), + feSpace_(feSpace), + applicationID_(1), + meshID_(meshID), + partitionID_(partitionID), + useMPI_(useMPI) + { + FUNCNAME("MpCCIAdapter::MpCCIAdapter()"); + int i; + + mpiRank_ = useMPI_ ? MPI::COMM_WORLD.Get_rank() : 0; + mpiSize_ = useMPI_ ? MPI::COMM_WORLD.Get_size() : 1; + + TEST_EXIT(surfaceRegion == -1)("not yet for surface regions\n"); + + // create SMI adapter + smiAdapter_ = NEW SMIAdapter(applicationID_, + meshID_, + feSpace_, + elementRegion, + surfaceRegion, + elementFct, + surfaceFct); + + // MpCCI initialize + //if(useMPI_) MPI::COMM_WORLD.Barrier(); + //if(mpiRank_ == 0) { + + if(idString) { + TEST_EXIT(CCI_Init_with_id_string(NULL, NULL, idString) == 0) + ("CCI_Init_with_id_string() failed\n"); + } else { + TEST_EXIT(CCI_Init(NULL, NULL) == 0)("CCI_Init() failed\n"); + } + + //} + //if(useMPI_) MPI::COMM_WORLD.Barrier(); + + //} + //if(useMPI_) MPI::COMM_WORLD.Barrier(); + + localCodeID_ = CCI_MYCODEID; + int remoteCodeID = (localCodeID_ == 1) ? 2 : 1; + + // define communicator + int sendQuantities[CCI_MAX_NQUANTITIES]; + int sendMeshes[CCI_MAX_NQUANTITIES]; + int sendNQuantities; + int recvQuantities[CCI_MAX_NQUANTITIES]; + int recvMeshes[CCI_MAX_NQUANTITIES]; + int recvNQuantities; + + if(localComm == -1) { + localComm_ = CCI_COMM_RCODE[remoteCodeID]; + } else { + TEST_EXIT(CCI_Comm_info(localComm_, + &remoteCodeID_, + &remoteComm_, + CCI_MAX_NQUANTITIES, + sendQuantities, + sendMeshes, + &sendNQuantities, + CCI_MAX_NQUANTITIES, + recvQuantities, + recvMeshes, + &recvNQuantities) == 0) + ("CCI_Comm_info() failed\n"); + + MSG("remote comm id: %d\n", remoteComm_); + + TEST_EXIT(CCI_Def_comm(localComm_, + remoteCodeID_, + remoteComm_, + numQuantities, + quantityIDs, + 1, + &meshID_) == 0) + ("CCI_Def_comm() failed\n"); + } + + TEST_EXIT(CCI_Def_partition(meshID_, partitionID_) == 0) + ("CCI_Def_partition() failed\n"); + + + transferMeshToMpCCI(); + + //if(useMPI_) MPI::COMM_WORLD.Barrier(); + + //if(mpiRank_ == 0) { + // get sync points from input file + for(i = 0; i < numSyncPoints; i++) { + TEST_EXIT(CCI_Sync_point_info(syncPointIDs[i], + CCI_MAX_NQUANTITIES, + sendQuantities, + sendMeshes, + &sendNQuantities, + CCI_MAX_NQUANTITIES, + recvQuantities, + recvMeshes, + &recvNQuantities) == 0) + ("CCI_Sync_point_info() failed\n"); + + MSG("sync point id: %d\n", syncPointIDs[i]); + int j; + for(j = 0; j < sendNQuantities; j++) { + MSG("send quantity: %d\n", sendQuantities[j]); + } + for(j = 0; j < recvNQuantities; j++) { + MSG("recv quantity: %d\n", recvQuantities[j]); + } + + TEST_EXIT(CCI_Def_sync_point(syncPointIDs[i], + sendNQuantities, + sendQuantities, + sendNQuantities, + sendMeshes, + recvNQuantities, + recvQuantities, + recvNQuantities, + recvMeshes) == 0) + ("CCI_Def_sync_point() failed\n"); + } + //} + + // define quantities + DOFVector<double> **ptr = dofVectors; + for(i = 0; i < numQuantities; i++) { + int dim = quantityDims[i]; + smiAdapter_->addQuantity(quantityIDs[i], dim, ptr); + ptr += dim; + } + + //if(useMPI_) MPI::COMM_WORLD.Barrier(); + + // close MpCCI setup + TEST_EXIT(CCI_Close_setup(localCodeID_) == 0)("CCI_Close_setup() failed\n"); + } + + MpCCIAdapter::~MpCCIAdapter() + { + DELETE smiAdapter_; + //if(useMPI_) MPI::COMM_WORLD.Barrier(); + //if(mpiRank_ == 0) { + TEST_EXIT(CCI_Finalize() == 0)("CCI_Finalize() failed\n"); + //} + } + + void MpCCIAdapter::transferMeshToMpCCI() + { + // update SMI data + smiAdapter_->transferMeshToSMI(); + + // read SMI data + int i; + int error; + int dow = Global::getGeo(WORLD); + int dim = feSpace_->getMesh()->getDim(); + int numNodes; + int *nodeIDs; + double *coords; + int numElems; + int *elemIDs; + int numElemNodeIDs; + int *elemNodeIDs; + int elemType; + int *nodesPerElem; + + error = SMI_Begin_read_transaction(applicationID_, meshID_); + TEST_EXIT(error == SMI_OK)("SMI_Begin_read_transaction() failed\n"); + + error = SMI_Get_all_nodes(applicationID_, + meshID_, + &numNodes, + &nodeIDs); + TEST_EXIT(error == SMI_OK)("SMI_Get_all_nodes() failed\n"); + + coords = GET_MEMORY(double, numNodes * dow); + + error = SMI_Get_nodes(applicationID_, + meshID_, + numNodes, + dow, + nodeIDs, + coords); + TEST_EXIT(error == SMI_OK)("SMI_Get_nodes() failed (%d)\n", error); + + error = SMI_Get_all_elems(applicationID_, + meshID_, + &numElems, + &elemIDs); + TEST_EXIT(error == SMI_OK)("SMI_Get_all_elems() failed\n"); + + error = SMI_Get_elems(applicationID_, + meshID_, + numElems, + elemIDs, + &numElemNodeIDs, + &elemNodeIDs, + NULL, + NULL); + TEST_EXIT(error == SMI_OK)("SMI_Get_elems() failed\n"); + + switch(dim) { + case 1: + elemType = CCI_ELEM_LINE; + break; + case 2: + elemType = CCI_ELEM_TRIANGLE; + break; + case 3: + elemType = CCI_ELEM_TETRAHEDRON; + break; + default: ERROR_EXIT("invalid dim\n"); + } + + nodesPerElem = GET_MEMORY(int, numElems); + for(i = 0; i < numElems; i++) { + nodesPerElem[i] = dim + 1; + } + + error = SMI_End_read_transaction(applicationID_, meshID_); + TEST_EXIT(error == SMI_OK)("SMI_End_read_transaction() failed\n"); + +#if 0 + // copy double to float + float *floatCoords = GET_MEMORY(float, numNodes * dow); + + for(i = 0; i < numNodes * dow; i++) { + floatCoords[i] = static_cast<float>(coords[i]); + } + + // transfer data to MpCCI + error = CCI_Def_nodes(meshID_, + partitionID_, + dow, + numNodes, + numNodes, + nodeIDs, + CCI_FLOAT, + floatCoords); + TEST_EXIT(error == 0)("CCI_Def_nodes() failed\n"); + + FREE_MEMORY(floatCoords, float, numNodes * dow); +#endif + + // transfer data to MpCCI + error = CCI_Def_nodes(meshID_, + partitionID_, + dow, + numNodes, + numNodes, + nodeIDs, + CCI_DOUBLE, + coords); + TEST_EXIT(error == 0)("CCI_Def_nodes() failed\n"); + + error = CCI_Def_elems(meshID_, + partitionID_, + numElems, + numElems, + elemIDs, + 1, + &elemType, + nodesPerElem, + elemNodeIDs); + TEST_EXIT(error == 0)("CCI_Def_elems() failed\n"); + + // free memory + FREE_MEMORY(coords, double, numNodes * dow); + FREE_MEMORY(nodesPerElem, int, numElems); + } + + void MpCCIAdapter::remesh() + { + int error; + error = CCI_Remesh(); + TEST_EXIT(error == 0)("CCI_Remesh() failed\n"); + + transferMeshToMpCCI(); + + int mode = CCI_TOTAL_REMESH; + error = CCI_Close_remesh(1, &meshID_, 1, &mode); + TEST_EXIT(error == 0)("CCI_Close_remesh() failed\n"); + } + + void MpCCIAdapter::checkConvergence(int myConvergence, + int *globalConvergence) + { + int error = CCI_Check_convergence(myConvergence, + globalConvergence, + CCI_ANY_CODE); + //localComm_); + TEST_EXIT(error == 0)("CCI_Check_convergence() failed\n"); + } + + void MpCCIAdapter::putNodes(int quantityID) + { + int error; + int numNodes; + int dim; + int *nodeIDs; + double *values; + + smiAdapter_->transferQuantitiesToSMI(quantityID); + + error = SMI_Begin_read_transaction(applicationID_, meshID_); + TEST_EXIT(error == SMI_OK)("SMI_Begin_read_transaction() failed\n"); + + error = SMI_Get_all_nodes(applicationID_, + meshID_, + &numNodes, + &nodeIDs); + TEST_EXIT(error == SMI_OK)("SMI_Get_all_nodes() failed\n"); + + error = SMI_Get_quantity_info(applicationID_, + meshID_, + quantityID, + NULL, + NULL, + &dim); + + TEST_EXIT(error == SMI_OK)("SMI_Get_quantity_info() failed\n"); + + values = GET_MEMORY(double, dim * numNodes); + + error = SMI_Get_quantity_values(applicationID_, + meshID_, + quantityID, + SMI_TYPE_DOUBLE, + dim, + numNodes, + nodeIDs, + values); + + TEST_EXIT(error == SMI_OK)("SMI_Get_quantity_values() failed\n"); + + error = SMI_End_read_transaction(applicationID_, meshID_); + TEST_EXIT(error == SMI_OK)("SMI_End_read_transaction() failed\n"); + + // copy double to float + float *floatValues = GET_MEMORY(float, dim * numNodes); + +#if 0 + int i; + for(i=0; i < dim*numNodes; i++) { + floatValues[i] = static_cast<float>(values[i]); + } + + error = CCI_Put_nodes(meshID_, + partitionID_, + quantityID, + dim, + numNodes, + numNodes, + nodeIDs, + CCI_FLOAT, + floatValues); + TEST_EXIT(error == 0)("CCI_Put_nodes() failed\n"); + + FREE_MEMORY(floatValues, float, dim * numNodes); +#endif + + error = CCI_Put_nodes(meshID_, + partitionID_, + quantityID, + dim, + numNodes, + numNodes, + nodeIDs, + CCI_DOUBLE, + values); + TEST_EXIT(error == 0)("CCI_Put_nodes() failed\n"); + + FREE_MEMORY(values, double, dim * numNodes); + } + + void MpCCIAdapter::getNodes(int quantityID) + { + int error; + int numNodes; + int dim; + int *nodeIDs; + double *values; + int numEmptyNodes; + + error = SMI_Begin_read_transaction(applicationID_, meshID_); + TEST_EXIT(error == SMI_OK)("SMI_Begin_read_transaction() failed\n"); + + error = SMI_Get_all_nodes(applicationID_, + meshID_, + &numNodes, + &nodeIDs); + TEST_EXIT(error == SMI_OK)("SMI_Get_all_nodes() failed\n"); + + error = SMI_Get_quantity_info(applicationID_, + meshID_, + quantityID, + NULL, + NULL, + &dim); + + TEST_EXIT(error == SMI_OK)("SMI_Get_quantity_info() failed (%d)\n", error); + + error = SMI_End_read_transaction(applicationID_, meshID_); + TEST_EXIT(error == SMI_OK)("SMI_End_read_transaction() failed\n"); + + values = GET_MEMORY(double, dim * numNodes); + +#if 0 + // copy double to float + float *floatValues = GET_MEMORY(float, dim * numNodes); + + error = CCI_Get_nodes(meshID_, + partitionID_, + quantityID, + dim, + numNodes, + numNodes, + nodeIDs, + CCI_FLOAT, + floatValues, + 0, + NULL, + &numEmptyNodes); + TEST_EXIT(error == 0)("CCI_Get_nodes() failed\n"); + + int i; + for(i=0; i < dim*numNodes; i++) { + values[i] = static_cast<double>(floatValues[i]); + } + + FREE_MEMORY(floatValues, float, dim * numNodes); +#endif + + error = CCI_Get_nodes(meshID_, + partitionID_, + quantityID, + dim, + numNodes, + numNodes, + nodeIDs, + CCI_DOUBLE, + values, + 0, + NULL, + &numEmptyNodes); + TEST_EXIT(error == 0)("CCI_Get_nodes() failed\n"); + + + error = SMI_Begin_write_transaction(applicationID_, meshID_); + TEST_EXIT(error == SMI_OK)("SMI_Begin_write_transaction() failed\n"); + + error = SMI_Set_quantity_values(applicationID_, + meshID_, + quantityID, + SMI_TYPE_DOUBLE, + dim, + numNodes, + nodeIDs, + values); + + TEST_EXIT(error == SMI_OK)("SMI_Set_quantity_values() failed\n"); + + error = SMI_End_write_transaction(applicationID_, meshID_); + TEST_EXIT(error == SMI_OK)("SMI_End_write_transaction() failed\n"); + + smiAdapter_->getQuantitiesFromSMI(quantityID); + + FREE_MEMORY(values, double, dim * numNodes); + } + + void MpCCIAdapter::send(int numQuantities, int *quantityIDs) + { + TEST_EXIT(CCI_Send(numQuantities, + quantityIDs, + 1, + &meshID_, + localComm_) == 0) + ("CCI_Send() failed\n"); + } + + void MpCCIAdapter::isend(int numQuantities, int *quantityIDs, CCI_Request *request) + { + TEST_EXIT(CCI_Isend(numQuantities, + quantityIDs, + 1, + &meshID_, + localComm_, + request) == 0) + ("CCI_Isend() failed\n"); + } + + void MpCCIAdapter::wait(CCI_Request *request) + { + CCI_Status status; + TEST_EXIT(CCI_Wait(request, + &status) == 0) + ("CCI_Wait() failed\n"); + } + + void MpCCIAdapter::recv(int numQuantities, int *quantityIDs) + { + CCI_Status status; + MSG("numQuantities %d\n", numQuantities); + MSG("meshID %d\n", meshID_); + MSG("localComm %d\n", localComm_); + int i; + for(i = 0; i < numQuantities; i++) { + MSG("quantity %d: %d\n", i, quantityIDs[i]); + } + TEST_EXIT(CCI_Recv(numQuantities, + quantityIDs, + 1, + &meshID_, + localComm_, + &status) == 0) + ("CCI_Send() failed\n"); + } + + void MpCCIAdapter::reachSyncPoint(int syncPointID) + { + //if(useMPI_) MPI::COMM_WORLD.Barrier(); + //if(mpiRank_ == 0) { + CCI_Status status; + TEST_EXIT(CCI_Reach_sync_point(syncPointID, &status) == 0) + ("CCI_Reach_sync_point() failed\n"); + //} + } + + void MpCCIAdapter::closeCouplingStep() + { + int error; + error = CCI_Close_coupling_step(1, 0, 0, 0, 0, 0, 0); + TEST_EXIT(error == 0)("CCI_Close_coupling_step() failed\n"); + } + + void MpCCIAdapter::setIndexMappings(::std::map<DegreeOfFreedom, DegreeOfFreedom> *newNodeIndex, + ::std::map<DegreeOfFreedom, DegreeOfFreedom> *oldNodeIndex, + ::std::map<int, int> *newElementIndex, + ::std::map<int, int> *oldElementIndex) + { + smiAdapter_->setIndexMappings(newNodeIndex, + oldNodeIndex, + newElementIndex, + oldElementIndex); + } + + int MpCCIAdapter::getNumElements() + { + int numElems = 0; + int *elemIDs; + int error = SMI_Begin_read_transaction(applicationID_, meshID_); + TEST_EXIT(error == SMI_OK)("SMI_Begin_read_transaction() failed\n"); + + error = SMI_Get_all_elems(applicationID_, + meshID_, + &numElems, + &elemIDs); + + TEST_EXIT(error == SMI_OK)("SMI_Get_all_elems() failed\n"); + + error = SMI_End_read_transaction(applicationID_, meshID_); + TEST_EXIT(error == SMI_OK)("SMI_End_read_transaction() failed\n"); + + return numElems; + } + +} diff --git a/AMDiS/src/MpCCIAdapter.h b/AMDiS/src/MpCCIAdapter.h new file mode 100644 index 0000000000000000000000000000000000000000..d653f2895493fe26145a2817fdc9f012e6601b59 --- /dev/null +++ b/AMDiS/src/MpCCIAdapter.h @@ -0,0 +1,116 @@ +// ============================================================================ +// == == +// == AMDiS - Adaptive multidimensional simulations == +// == == +// ============================================================================ +// == == +// == crystal growth group == +// == == +// == Stiftung caesar == +// == Ludwig-Erhard-Allee 2 == +// == 53175 Bonn == +// == germany == +// == == +// ============================================================================ +// == == +// == http://www.caesar.de/cg/AMDiS == +// == == +// ============================================================================ + +/** \file MpCCIAdapter.h */ + +#ifndef AMDIS_MPCCIADAPTER_H +#define AMDIS_MPCCIADAPTER_H + +#include "MemoryManager.h" +#include <map> +#include "cci.h" +#include "cci_const.h" + +namespace AMDiS { + + class SMIAdapter; + class FiniteElemSpace; + class ElInfo; + template<typename T> class DOFVector; + + class MpCCIAdapter + { + public: + MEMORY_MANAGED(MpCCIAdapter); + + MpCCIAdapter(int localComm, + int meshID, + int partitionID, + bool useMPI, + FiniteElemSpace *feSpace, + int elementRegion, + int surfaceRegion, + int numQuantities, + int *quantityIDs, + int *quantityDims, + DOFVector<double> **dofVectors, + int numSyncPoints, + int *syncPointIDs, + const char *idString = NULL, + bool (*elementFct)(ElInfo *elInfo) = NULL, + bool (*surfaceFct)(ElInfo *elInfo, int side) = NULL); + + ~MpCCIAdapter(); + + void remesh(); + + void putNodes(int quantityID); + + void getNodes(int quantityID); + + void send(int numQuantities, int *quantityIDs); + + void isend(int numQuantities, int *quantityIDs, CCI_Request *request); + + void wait(CCI_Request *request); + + void recv(int numQuantities, int *quantityIDs); + + void reachSyncPoint(int syncPointID); + + void closeCouplingStep(); + + void checkConvergence(int myConvergence, + int *globalConvergence); + + void setIndexMappings(::std::map<DegreeOfFreedom, DegreeOfFreedom> *newNodeIndex, + ::std::map<DegreeOfFreedom, DegreeOfFreedom> *oldNodeIndex, + ::std::map<int, int> *newElementIndex, + ::std::map<int, int> *oldElementIndex); + + + int getNumElements(); + + protected: + void transferMeshToMpCCI(); + + protected: + int localCodeID_; + int remoteCodeID_; + + int localComm_; + int remoteComm_; + + FiniteElemSpace *feSpace_; + + int applicationID_; + int meshID_; + int partitionID_; + + SMIAdapter *smiAdapter_; + + bool useMPI_; + + int mpiRank_; + int mpiSize_; + }; + +} + +#endif diff --git a/AMDiS/src/MultiGridPreconWrapper.cc b/AMDiS/src/MultiGridPreconWrapper.cc new file mode 100644 index 0000000000000000000000000000000000000000..d0c4be01daad7e277d5bda6f2420a16783ca6ee5 --- /dev/null +++ b/AMDiS/src/MultiGridPreconWrapper.cc @@ -0,0 +1,45 @@ +#include "MultiGridPreconWrapper.h" +#include "MultiGridSolver.h" +#include "DOFVector.h" + +namespace AMDiS { + + MGPreconWrapperScal::MGPreconWrapperScal(::std::string name, int size_, int row_) + : PreconditionerScal(size_, row_), + solution_(NULL) + { + mgSolver_ = NEW MultiGridSolverScal(name); + } + + MGPreconWrapperScal::~MGPreconWrapperScal() + { + if(solution_) { + DELETE solution_; + } + DELETE mgSolver_; + } + + void MGPreconWrapperScal::init() { + FUNCNAME("MGPreconWrapperScal::init"); + TEST_EXIT(matrix[row])("no matrix\n"); + initMG_ = true; + }; + + void MGPreconWrapperScal::exit() { + mgSolver_->exitMultiGrid(); + }; + + void MGPreconWrapperScal::precon(DOFVector<double> *vec) + { + if(!solution_) { + solution_ = NEW DOFVector<double>(vec->getFESpace(), "MG precon solution"); + } + + solution_->set(0.0); + mgSolver_->solve((*(*(matrix[row]))), *solution_, *vec, initMG_, false); + initMG_ = false; + + vec->copy(*solution_); + } + +} diff --git a/AMDiS/src/MultiGridPreconWrapper.h b/AMDiS/src/MultiGridPreconWrapper.h new file mode 100644 index 0000000000000000000000000000000000000000..050dcc4052f2617cd6bd789c50b3db147155c6e7 --- /dev/null +++ b/AMDiS/src/MultiGridPreconWrapper.h @@ -0,0 +1,95 @@ +// ============================================================================ +// == == +// == AMDiS - Adaptive multidimensional simulations == +// == == +// ============================================================================ +// == == +// == crystal growth group == +// == == +// == Stiftung caesar == +// == Ludwig-Erhard-Allee 2 == +// == 53175 Bonn == +// == germany == +// == == +// ============================================================================ +// == == +// == http://www.caesar.de/cg/AMDiS == +// == == +// ============================================================================ + +/** \file MultiGridPreconWrapper.h */ + +#ifndef AMDIS_MULTIGRIDPRECONWRAPPER_H +#define AMDIS_MULTIGRIDPRECONWRAPPER_H + +#include "Preconditioner.h" +#include "MemoryManager.h" + +namespace AMDiS { + + template<typename T> class DOFVector; + template<typename M, typename V> class MultiGridSolverBase; + + // ========================================================================= + // ===== MGPreconWrqpperScal =============================================== + // ========================================================================= + + /** \brief + * \ingroup Solver + * Wrapper for using multigrid as preconditioner within other iterative + * solvers. + */ + class MGPreconWrapperScal : public PreconditionerScal + { + public: + /** \brief + * Constructor. + */ + MGPreconWrapperScal(::std::string name, int size_ = 1, int row_ = 0); + + /** \brief + * Destructor. + */ + virtual ~MGPreconWrapperScal(); + + /** \brief + * realisation of Preconditioner::init + */ + void init(); + + /** \brief + * realisation of Preconditioner::precon + */ + void precon(DOFVector<double> *vec); + + /** \brief + * realisation of Preconditioner::exit + */ + void exit(); + + // ======================================================================= + // ===== Creator ========================================================= + // ======================================================================= + + class Creator : public PreconditionerScalCreator + { + public: + MEMORY_MANAGED(Creator); + + /** \brief + * Creates a DiagonalPreconditioner. + */ + PreconditionerScal *create() { + return NEW MGPreconWrapperScal(name_, size, row); + }; + }; + + protected: + MultiGridSolverBase<DOFMatrix, DOFVector<double> > *mgSolver_; + DOFVector<double> *solution_; + bool initMG_; + }; + +} + +#endif diff --git a/AMDiS/src/MultiGridSolver.cc b/AMDiS/src/MultiGridSolver.cc new file mode 100644 index 0000000000000000000000000000000000000000..5787882e9b07207e71a9483b500f023ce7a36275 --- /dev/null +++ b/AMDiS/src/MultiGridSolver.cc @@ -0,0 +1,1689 @@ +#include "MultiGridSolver.h" +#include "FiniteElemSpace.h" +#include "DOFVector.h" +#include "DOFMatrix.h" +#include "Traverse.h" +#include "MacroWriter.h" +#include "ValueWriter.h" +#include "SparseVector.h" +#include "ElInfo.h" +#include "Parameters.h" +#include "SystemVector.h" +#include "GSSmoother.h" +#include <algorithm> +#include "InterpolRestrictMatrix.h" +#include "LagrangeInterpolRestrict.h" +#include "DirichletBC.h" + +namespace AMDiS { + + MultiGridSolverScal::MultiGridSolverScal(const ::std::string &name) + : MultiGridSolverBase<DOFMatrix, DOFVector<double> >(name), + sparseResidual_(NULL), + denseResidual_(NULL), + lastRes_(1.0), + iteration_(0), + coarseSmoothingSteps_(2), + minLevelGap_(0), + maxMGLevels_(100), + interpolMatrix_(NULL), + restrictMatrix_(NULL), + galerkin_(0) + { + FUNCNAME("MultiGridSolverScal::MultiGridSolverScal()"); + + GET_PARAMETER(0, name_ + "->coarse level smoothing steps", "%d", &coarseSmoothingSteps_); + GET_PARAMETER(0, name_ + "->min level gap", "%d", &minLevelGap_); + GET_PARAMETER(0, name_ + "->max mg levels", "%d", &maxMGLevels_); + GET_PARAMETER(0, name_ + "->use galerkin operator", "%d", &galerkin_); + + // Create smoother + ::std::string smootherType("gs"); + GET_PARAMETER(0, name_ + "->smoother", &smootherType); + SmootherCreator<DOFMatrix, SparseVector<double>, ::std::set<DegreeOfFreedom> > *smootherCreator = + dynamic_cast<SmootherCreator<DOFMatrix, SparseVector<double>, ::std::set<DegreeOfFreedom> >*>( + CreatorMap<SmootherBase<DOFMatrix, SparseVector<double>, ::std::set<DegreeOfFreedom> > >::getCreator(smootherType)); + + if (smootherCreator && !smootherCreator->isNullCreator()) { + smootherCreator->setName(name_ + "->smoother"); + smoother_ = smootherCreator->create(); + } else { + smoother_ = NULL; + ERROR_EXIT("no smoother specified\n"); + } + } + + void MultiGridSolverScal::initMaxLevel() + { + FiniteElemSpace *feSpace = + const_cast<FiniteElemSpace*>(systemMatrix_->getFESpace()); + + TraverseStack st; + ElInfo *elInfo = st.traverseFirst(feSpace->getMesh(), -1, + Mesh::CALL_LEAF_EL); + maxLevel_ = -1; + while (elInfo) { + maxLevel_ = max(elInfo->getLevel(), maxLevel_); + elInfo = st.traverseNext(elInfo); + } + } + + void MultiGridSolverScal::initMultiGrid(bool initMG) + { + FUNCNAME("MultiGridSolverScal::initMultiGrid()"); + + iteration_ = 0; + + lastRes_ = 1.0; + + if (initMG) { + FiniteElemSpace *feSpace = + const_cast<FiniteElemSpace*>(systemMatrix_->getFESpace()); + + TEST_EXIT(!galerkin_ || feSpace->getBasisFcts()->getDegree() == 1) + ("galerkin coarse grid operator only for linear finite elements\n"); + + Mesh *mesh = feSpace->getMesh(); + + int dim = mesh->getDim(); + int degree = feSpace->getBasisFcts()->getDegree(); + + // Get the interpolation and restriction matrices that correspond to + // the element dim and to the degree of the basis functions. + interpolMatrix_ = interpolMatrices[dim - 1][degree - 1]; + restrictMatrix_ = restrictMatrices[dim - 1][degree - 1]; + + sparseResidual_ = NEW SparseVector<double>(feSpace, "sparse residual"); + denseResidual_ = NEW DOFVector<double>(feSpace, "dense residual"); + + int numLevels = maxLevel_ + 1; + + isMGLevel_.resize(numLevels, false); + isMGLevel_[minLevel_] = true; + isMGLevel_[maxLevel_] = true; + if (numLevels > 2) { + double step = (static_cast<double>(maxMGLevels_) - 2.0) / (numLevels - 2.0); + double sum = 0.0; + int gap = 0; + for (int i = maxLevel_ - 1; i > minLevel_; i--) { + sum += step; + //MSG("%d %f\n", i, sum); + ++gap; + if(gap > minLevelGap_ && sum >= 1.0) { + gap = 0; + isMGLevel_[i] = true; + sum -= 1.0; + } else { + MSG("level %d skipped\n", i); + } + } + } + + TEST_EXIT(mesh->queryCoarseDOFs())("preserve coarse dofs not set in mesh\n"); + + const BasisFunction *basFcts = feSpace->getBasisFcts(); + int numDOFs = basFcts->getNumber(); + + // Allocate memory for the multigrid levels. + levels_.resize(numLevels); + + // Fill all multigrid levels with initial data. + for (int i = 0; i < numLevels; i++) { + if (isMGLevel_[i]) { + levels_[i].solution_ = NEW SparseVector<double>(feSpace, "sparse level solution"); + levels_[i].oldSolution_ = NEW SparseVector<double>("old level solution", levels_[i].solution_); + levels_[i].rhs_ = NEW SparseVector<double>("sparse level rhs", levels_[i].solution_); + levels_[i].matrix_ = NEW DOFMatrix(feSpace, feSpace, "level matrix"); + levels_[i].matrix_->setBoundaryManager(systemMatrix_->getBoundaryManager()); + } + } + + // Here, for each DOF we save the highest mesh level on which it occurs. + DOFVector<int> maxDOFLevels(feSpace, "max dof levels"); + maxDOFLevels.set(minLevel_); + + DegreeOfFreedom *dofs = GET_MEMORY(DegreeOfFreedom, numDOFs); + Element *element; + DOFAdmin *admin = feSpace->getAdmin(); + int level; + + // Iterators for all operators of the system matrix. + ::std::vector<Operator*>::iterator it; + ::std::vector<Operator*>::iterator opBegin = systemMatrix_->getOperatorsBegin(); + ::std::vector<Operator*>::iterator opEnd = systemMatrix_->getOperatorsEnd(); + + ::std::vector<double*>::iterator factorIt; + ::std::vector<double*>::iterator factorBegin = systemMatrix_->getOperatorFactorBegin(); + ElementMatrix *elementMatrix = NULL; + const BoundaryType *bound; + + TraverseStack stack; + + // Fill level elements and max-dof-level for each DOF. + ElInfo *elInfo = stack.traverseFirst(mesh, -1, Mesh::CALL_EVERY_EL_PREORDER); + while (elInfo) { + element = elInfo->getElement(); + level = elInfo->getLevel(); + levels_[level].elements_.push_back(element); + if (dim == 3) { + levels_[level].elementTypes_.push_back(dynamic_cast<ElInfo3d*>(elInfo)->getType()); + } + basFcts->getLocalIndices(element, admin, dofs); + for (int i = 0; i < numDOFs; i++) { + maxDOFLevels[dofs[i]] = max(maxDOFLevels[dofs[i]], mgLevel(level)); + } + elInfo = stack.traverseNext(elInfo); + } + + + // Assemble level matrices and create DOF sets. + elInfo = stack.traverseFirst(mesh, -1, + Mesh::CALL_EVERY_EL_PREORDER | + Mesh::FILL_BOUND | + Mesh::FILL_DET | + Mesh::FILL_GRD_LAMBDA | + Mesh::FILL_COORDS | + Mesh::FILL_NEIGH); + while (elInfo) { + element = elInfo->getElement(); + level = elInfo->getLevel(); + basFcts->getLocalIndices(element, admin, dofs); + bound = basFcts->getBound(elInfo, NULL); + elementMatrix = (*opBegin)->getAssembler()->initElementMatrix(elementMatrix, elInfo); + + bool levelUsed = isMGLevel_[level]; + + // If the element is in a level that is a multigrid level, add all element + // matrices of this element to the level matrix. + if ((levelUsed) && (!galerkin_)) { + for (it = opBegin, factorIt = factorBegin; + it != opEnd; + ++it, ++factorIt) + { + (*it)->getElementMatrix(elInfo, + elementMatrix, + *factorIt ? **factorIt : 1.0); + } + + levels_[level].matrix_->addElementMatrix(1.0, *elementMatrix, bound); + } + + if (element->isLeaf()) { + // If the element is a leaf element, but this level is not a multigrid level, + // the element matrices are added to the next possible multigrid level. + if (!levelUsed) { + level = mgLevel(level); + if(!galerkin_) { + for(it = opBegin, factorIt = factorBegin; + it != opEnd; + ++it, ++factorIt) + { + (*it)->getElementMatrix(elInfo, + elementMatrix, + *factorIt ? **factorIt : 1.0); + } + levels_[level].matrix_->addElementMatrix(1.0, *elementMatrix, bound); + } + } + + // Add nearest neighbour element matrices and dofs + int maxDOFLevel = -1; + for (int i = 0; i < dim + 1; i++) { + maxDOFLevel = max(maxDOFLevel, maxDOFLevels[dofs[i]]); + } + + // There is a DOF of the element that is included in finer levels. + if (maxDOFLevel > level) { + if (!galerkin_) { + for (int j = level + 1; j < maxDOFLevel + 1; j++) { + if (isMGLevel_[j]) { + levels_[j].matrix_->addElementMatrix(1.0, *elementMatrix, bound); + } + } + } + for (int j = 0; j < numDOFs; j++) { + for (int k = level + 1; k < maxDOFLevel + 1; k++) { + if (isMGLevel_[k]) { + if (maxDOFLevels[dofs[j]] < k) { + levels_[k].nearestNeighbourDOFs_.insert(dofs[j]); + } + } + } + } + } + + for (int i = 0; i < numDOFs; i++) { + // If the element is a leaf element and the maximum level of one of + // its DOFs is equal to the current level, the DOF is not included + // in finer levels. + if (maxDOFLevels[dofs[i]] == level) { + levels_[level].coarseDOFs_.insert(dofs[i]); + } + } + } else { + // element is not leaf + if ((level >= minLevel_) && (levelUsed)) { + // The element is not a leaf element, therefore its DOFs are also + // included in finer levels. + for (int i = 0; i < numDOFs; i++) { + levels_[level].fineDOFs_.insert(dofs[i]); + } + } + } // if-else element is leaf + elInfo = stack.traverseNext(elInfo); + } // while elInfo + + if (!galerkin_) { + // Fill boundary conditions + if (systemMatrix_->getBoundaryManager()) { + systemMatrix_->getBoundaryManager()->initMatrix(systemMatrix_); + } + + TraverseStack stack; + ElInfo *elInfo = stack.traverseFirst(mesh, -1, + Mesh::CALL_LEAF_EL | + Mesh::FILL_BOUND | + Mesh::FILL_COORDS | + Mesh::FILL_DET | + Mesh::FILL_GRD_LAMBDA | + Mesh::FILL_NEIGH); + while (elInfo) { + if (systemMatrix_->getBoundaryManager()) { + systemMatrix_->getBoundaryManager()->fillBoundaryConditions(elInfo, + systemMatrix_); + } + + elInfo = stack.traverseNext(elInfo); + } + + if (systemMatrix_->getBoundaryManager()) { + systemMatrix_->getBoundaryManager()->exitMatrix(systemMatrix_); + } + } else { + // Galerkin operator + + DegreeOfFreedom *child0DOFs = GET_MEMORY(DegreeOfFreedom, dim + 1); + DegreeOfFreedom *parentDOFs = GET_MEMORY(DegreeOfFreedom, dim + 1); + + Vector<DegreeOfFreedom> fineDOFs(dim + 2); + Matrix<double> a(dim + 2, dim + 2); + + levels_[maxLevel_].matrix_->copy(*systemMatrix_); + + DOFMatrix tmp1(feSpace, feSpace, "tmp1"); + DOFMatrix tmp2(feSpace, feSpace, "tmp2"); + + DOFMatrix *coarseMatrix = NULL; + DOFMatrix *fineMatrix = levels_[maxLevel_].matrix_; + + for (level = maxLevel_ - 1; level >= minLevel_; level--) { + ::std::map< ::std::pair<int, int>, bool> visited; + + coarseMatrix = + isMGLevel_[level] ? + levels_[level].matrix_ : + (fineMatrix == &tmp1 ? &tmp2 : &tmp1); + + coarseMatrix->clear(); + + elInfo = stack.traverseFirst(mesh, -1, Mesh::CALL_EVERY_EL_PREORDER); + while(elInfo) { + Element *element = elInfo->getElement(); + + basFcts->getLocalIndices(element, admin, parentDOFs); + + for (int i = 0; i < dim + 1; i++) { + fineDOFs[i] = parentDOFs[i]; + } + + if(elInfo->getLevel() == level && !element->isLeaf()) { + + basFcts->getLocalIndices(element->getChild(0), admin, child0DOFs); + + fineDOFs[dim + 1] = child0DOFs[dim]; + + double *ptr; + + for (int i = 0; i < dim + 2; i++) { + for (int j = 0; j < dim + 2; j++) { + ptr = fineMatrix->hasSparseDOFEntry(fineDOFs[i], fineDOFs[j]); + a[i][j] = ptr ? *ptr : 0.0; + } + } + + for (int i = 0; i < dim + 1; i++) { + for (int j = 0; j < dim + 1; j++) { + if(visited[::std::pair<int, int>(fineDOFs[i], fineDOFs[j])] == false) + coarseMatrix->addSparseDOFEntry(1.0, + parentDOFs[i], + parentDOFs[j], + 0.0, + false); + } + } + + for (int i = 0; i < dim + 1; i++) { + for (int j = 0; j < dim + 1; j++) { + if(visited[::std::pair<int, int>(fineDOFs[i], fineDOFs[j])] == false) + coarseMatrix->addSparseDOFEntry(1.0, + parentDOFs[i], + parentDOFs[j], + a[i][j], + true); + } + } + + for (int i = 0; i < dim + 1; i++) { + for (int j = 0; j < 2; j++) { + if(visited[::std::pair<int, int>(fineDOFs[i], fineDOFs[dim + 1])] == false) { + coarseMatrix->addSparseDOFEntry(0.5, + parentDOFs[i], + parentDOFs[j], + a[i][dim + 1], + true); + + coarseMatrix->addSparseDOFEntry(0.5, + parentDOFs[j], + parentDOFs[i], + a[dim + 1][i], + true); + } + } + } + + if (visited[::std::pair<int, int>(fineDOFs[dim + 1], fineDOFs[dim + 1])] == false) { + for (int i = 0; i < 2; i++) { + for (int j = 0; j < 2; j++) { + coarseMatrix->addSparseDOFEntry(0.25, + parentDOFs[i], + parentDOFs[j], + a[dim + 1][dim + 1], + true); + } + } + } + + for (int i = 0; i < dim + 2; i++) { + for (int j = 0; j < dim + 2; j++) { + visited[::std::pair<int, int>(fineDOFs[i], fineDOFs[j])] = true; + visited[::std::pair<int, int>(fineDOFs[j], fineDOFs[i])] = true; + } + } + } + if (element->isLeaf() && elInfo->getLevel() <= level) { + double *ptr; + + for (int i = 0; i < dim + 1; i++) { + for (int j = 0; j < dim + 1; j++) { + ptr = fineMatrix->hasSparseDOFEntry(fineDOFs[i], fineDOFs[j]); + a[i][j] = ptr ? *ptr : 0.0; + } + } + + for (int i = 0; i < dim + 1; i++) { + for (int j = 0; j < dim + 1; j++) { + if (!visited[::std::pair<int, int>(parentDOFs[i], parentDOFs[j])]) { + coarseMatrix->addSparseDOFEntry(1.0, + parentDOFs[i], + parentDOFs[j], + a[i][j], + false); + } + } + } + } + elInfo = stack.traverseNext(elInfo); + } + fineMatrix = coarseMatrix; + } // for level + + FREE_MEMORY(child0DOFs, DegreeOfFreedom, dim + 1); + FREE_MEMORY(parentDOFs, DegreeOfFreedom, dim + 1); + } // if-else galerkin_ + + FREE_MEMORY(dofs, DegreeOfFreedom, numDOFs); + + // Copy in each level the to sets coarseDOFs and fineDOFs to one + // set levelDOFs containing all DOFs of the level. + for (int i = minLevel_; i < numLevels; i++) { + if (isMGLevel_[i]) { + levels_[i].levelDOFs_.insert(levels_[i].coarseDOFs_.begin(), + levels_[i].coarseDOFs_.end()); + levels_[i].levelDOFs_.insert(levels_[i].fineDOFs_.begin(), + levels_[i].fineDOFs_.end()); + } + } + } // if initMG + + // Compute start residual + mv(NoTranspose, *systemMatrix_, *solution_, *denseResidual_); + axpy(-1.0, *rhs_, *denseResidual_); + + // Compute 2-norm of the residual + double res = denseResidual_->nrm2(); + MSG("residual: %e\n", res); + lastRes_ = res; + + for (int i = 0; i <= maxLevel_; i++) { + if (isMGLevel_[i]) { + levels_[i].solution_->copyFromDOFVector(*solution_, + levels_[i].coarseDOFs_); + levels_[i].solution_->copyFromDOFVector(*solution_, + levels_[i].nearestNeighbourDOFs_); + } + } + + // Copy the rhs of the equation to the finest multigrid level + // restricted to its DOFs. + levels_[maxLevel_].rhs_->copyFromDOFVector(*rhs_, + levels_[maxLevel_].coarseDOFs_); + } + + + void MultiGridSolverScal::exitMultiGrid() + { + DELETE sparseResidual_; + DELETE denseResidual_; + + // Free memory + for (int i = 0; i < maxLevel_ + 1; i++) { + if (isMGLevel_[i]) { + DELETE levels_[i].matrix_; + DELETE levels_[i].rhs_; + DELETE levels_[i].oldSolution_; + DELETE levels_[i].solution_; + } + } + + levels_.resize(0); + isMGLevel_.resize(0); + } + + + void MultiGridSolverScal::smooth(int level, int steps) + { + smoother_->smooth(levels_[level].matrix_, + levels_[level].solution_, + levels_[level].rhs_, + steps, + levels_[level].levelDOFs_); + // DOFVector<double> sol(systemMatrix_->getFESpace(), "solution"); + // levels_[level].solution_->copyToDOFVector(sol); + // MacroWriter::writeMacro(systemMatrix_->getFESpace(), "sol.mesh", 0.0, level, Mesh::CALL_EL_LEVEL); + // ValueWriter::writeValues(&sol, "sol.dat", 0.0, level, Mesh::CALL_EL_LEVEL); + // MSG("smoothed %d\n", level); + // WAIT; + } + + + void MultiGridSolverScal::prolongate(int level, int coarseLevel) + { + for (int i = coarseLevel; i < level; i++) { + interpolMatrix_->mv(sparseResidual_, + sparseResidual_, + i); + } + // DOFVector<double> cor(systemMatrix_->getFESpace(), "correction"); + // sparseResidual_->copyToDOFVector(cor); + // MacroWriter::writeMacro(systemMatrix_->getFESpace(), "cor.mesh", 0.0, coarseLevel, Mesh::CALL_EL_LEVEL); + // ValueWriter::writeValues(&cor, "cor.dat", 0.0, coarseLevel, Mesh::CALL_EL_LEVEL); + // MSG("prolongated %d\n", level); + // WAIT; + } + + + void MultiGridSolverScal::restrict(int level, int coarseLevel) + { + // MSG("%d\n", level); + // if(isMGLevel_[level]) levels_[level].rhs_->print(); + + // Copy the old solution to the coarser grid. + levels_[coarseLevel].oldSolution_->copy(*(levels_[level].solution_), + levels_[level].levelDOFs_); + levels_[coarseLevel].oldSolution_->copy(*(levels_[level].solution_), + levels_[level].nearestNeighbourDOFs_); + + ::std::vector<Element*>::iterator elIt, elBegin, elEnd; + ::std::vector<int>::iterator typeIt; + + for (int i = level; i > coarseLevel; i--) { + elBegin = levels_[i-1].elements_.begin(); + elEnd = levels_[i-1].elements_.end(); + typeIt = levels_[i-1].elementTypes_.begin(); + + // Restrict the old solution to the DOFs of the coarser gird. + for (elIt = elBegin; elIt != elEnd; ++elIt) { + Element *element = *elIt; + if (!element->isLeaf()) { + RCNeighbourList list(1); + list.setElement(0, element); + if (element->getMesh()->getDim() == 3) { + list.setType(0, levels_[i-1].elementTypes_[*typeIt]); + ++typeIt; + } + levels_[coarseLevel].oldSolution_->coarseRestrict(list, 1); + } + } + + // Restrict the residual + restrictMatrix_->mv(sparseResidual_, + sparseResidual_, + i - 1); + + // Alternative: use restriction matrix to restrict the old solution. + // restrictMatrix_->mv(levels_[coarseLevel].oldSolution_, + // levels_[coarseLevel].oldSolution_, + // i-1); + } + + + levels_[coarseLevel].solution_->copy(*(levels_[coarseLevel].oldSolution_), + levels_[coarseLevel].fineDOFs_); + + // DOFVector<double> res(systemMatrix_->getFESpace(), "residual"); + // sparseResidual_->copyToDOFVector(res); + // MacroWriter::writeMacro(systemMatrix_->getFESpace(), "res.mesh", 0.0, coarseLevel, Mesh::CALL_EL_LEVEL); + // ValueWriter::writeValues(&res, "res.dat", 0.0, coarseLevel, Mesh::CALL_EL_LEVEL); + // DOFVector<double> sol(systemMatrix_->getFESpace(), "solution"); + // levels_[coarseLevel].oldSolution_->copyToDOFVector(sol); + // MacroWriter::writeMacro(systemMatrix_->getFESpace(), "sol.mesh", 0.0, coarseLevel, Mesh::CALL_EL_LEVEL); + // ValueWriter::writeValues(&sol, "sol.dat", 0.0, coarseLevel, Mesh::CALL_EL_LEVEL); + // MSG("residual and solution restricted %d\n", level); + // WAIT; + } + + + void MultiGridSolverScal::computeResidual(int level, int coarseLevel) + { + mv(*(levels_[level].matrix_), + *(levels_[level].solution_), + *sparseResidual_, + levels_[level].levelDOFs_); + + axpy(-1.0, + *(levels_[level].rhs_), + *sparseResidual_, + levels_[level].levelDOFs_); + + // DOFVector<double> res(systemMatrix_->getFESpace(), "residual"); + // sparseResidual_->copyToDOFVector(res); + // MacroWriter::writeMacro(systemMatrix_->getFESpace(), "res.mesh", 0.0, level, Mesh::CALL_EL_LEVEL); + // ValueWriter::writeValues(&res, "res.dat", 0.0, level, Mesh::CALL_EL_LEVEL); + // MSG("residual computed %d\n", level); + // WAIT; + } + + + void MultiGridSolverScal::computeRHS(int level, int coarseLevel) + { + // First compute rhs without considering boundary conditions. + mv(*(levels_[coarseLevel].matrix_), + *(levels_[coarseLevel].oldSolution_), + *(levels_[coarseLevel].rhs_), + levels_[coarseLevel].fineDOFs_); + + axpy(-1.0, + *sparseResidual_, + *(levels_[coarseLevel].rhs_), + levels_[coarseLevel].fineDOFs_); + + levels_[coarseLevel].rhs_->copyFromDOFVector(*rhs_, + levels_[coarseLevel].coarseDOFs_); + + + // Then add boundary conditions to the solution. + if (!galerkin_) { + Mesh *mesh = rhs_->getFESpace()->getMesh(); + + if(rhs_->getBoundaryManager()) { + rhs_->getBoundaryManager()->initVector(levels_[coarseLevel].rhs_); + } + + TraverseStack stack; + ElInfo *elInfo = stack.traverseFirst(mesh, -1, + Mesh::CALL_EVERY_EL_PREORDER | + Mesh::FILL_BOUND | + Mesh::FILL_DET | + Mesh::FILL_GRD_LAMBDA | + Mesh::FILL_COORDS); + + while (elInfo) { + if (rhs_->getBoundaryManager()) + rhs_->getBoundaryManager()->fillBoundaryConditions(elInfo, + levels_[coarseLevel].rhs_); + elInfo = stack.traverseNext(elInfo); + } + + if (rhs_->getBoundaryManager()) { + rhs_->getBoundaryManager()->exitVector(levels_[coarseLevel].rhs_); + } + } + + // MSG("%d\n", level); + // levels_[level].matrix_->print(); + // levels_[level].solution_->print(); + // levels_[level].rhs_->print(); + // MSG("%d\n", coarseLevel); + // levels_[coarseLevel].matrix_->print(); + // levels_[coarseLevel].solution_->print(); + // levels_[coarseLevel].rhs_->print(); + + // DOFVector<double> rhs(systemMatrix_->getFESpace(), "rhs"); + // levels_[coarseLevel].rhs_->copyToDOFVector(rhs); + // MacroWriter::writeMacro(systemMatrix_->getFESpace(), "rhs.mesh", 0.0, coarseLevel, Mesh::CALL_EL_LEVEL); + // ValueWriter::writeValues(&rhs, "rhs.dat", 0.0, coarseLevel, Mesh::CALL_EL_LEVEL); + // MacroWriter::writeMacro(systemMatrix_->getFESpace(), "realrhs.mesh"); + // ValueWriter::writeValues(rhs_, "realrhs.dat"); + // MSG("rhs computed %d\n", level); + // WAIT; + } + + + void MultiGridSolverScal::computeCorrection(int level, int coarseLevel) + { + sparseResidual_->copy(*(levels_[coarseLevel].solution_), + levels_[coarseLevel].fineDOFs_); + axpy(-1.0, + *(levels_[coarseLevel].oldSolution_), + *sparseResidual_, + levels_[coarseLevel].fineDOFs_); + + // DOFVector<double> cor(systemMatrix_->getFESpace(), "correction"); + // sparseResidual_->copyToDOFVector(cor); + // MacroWriter::writeMacro(systemMatrix_->getFESpace(), "cor.mesh", 0.0, coarseLevel, Mesh::CALL_EL_LEVEL); + // ValueWriter::writeValues(&cor, "cor.dat", 0.0, coarseLevel, Mesh::CALL_EL_LEVEL); + // MSG("correction computed %d\n", level); + // WAIT; + } + + + void MultiGridSolverScal::fixSolution(int level, int coarseLevel) + { + levels_[level].solution_->copy(*(levels_[coarseLevel].solution_), + levels_[level].nearestNeighbourDOFs_); + + axpy(1.0, + *sparseResidual_, + *(levels_[level].solution_), + levels_[level].levelDOFs_); + + // DOFVector<double> sol(systemMatrix_->getFESpace(), "solution"); + // levels_[level].solution_->copyToDOFVector(sol); + // MacroWriter::writeMacro(systemMatrix_->getFESpace(), "sol.mesh", 0.0, level, Mesh::CALL_EL_LEVEL); + // ValueWriter::writeValues(&sol, "sol.dat", 0.0, level, Mesh::CALL_EL_LEVEL); + // MSG("solution fixed %d\n", level); + // WAIT; + } + + + void MultiGridSolverScal::exactSolve(int level) + { + smooth(level, coarseSmoothingSteps_); + } + + + bool MultiGridSolverScal::toleranceReached(double tol) + { + FUNCNAME("MultiGridSolver::toleranceReached()"); + + for (int level = minLevel_; level < maxLevel_ + 1; level++) { + if (isMGLevel_[level]) { + levels_[level].solution_->copyToDOFVector(*solution_, + levels_[level].coarseDOFs_); + } + } + + mv(NoTranspose, *systemMatrix_, *solution_, *denseResidual_); + axpy(-1.0, *rhs_, *denseResidual_); + + ++iteration_; + + double res = denseResidual_->nrm2(); + MSG("iteration %d - residual: %e (res / lastRes : %e)\n", + iteration_, res, res/lastRes_); + + lastRes_ = res; + + // levelMatrices_[maxLevel_]->print(); + + // systemMatrix_->print(); + + // MacroWriter::writeMacro(systemMatrix_->getFESpace(), "sol_iter.mesh"); + // ValueWriter::writeValues(solution_, "sol_iter.dat"); + // MacroWriter::writeMacro(systemMatrix_->getFESpace(), "res_iter.mesh"); + // ValueWriter::writeValues(denseResidual_, "res_iter.dat"); + // WAIT; + + return (res < tol); + } + + + void MultiGridSolverScal::initFullMultiGrid() + { + int coarseLevel = -1; + + for (int i = maxLevel_; i > minLevel_; i--) { + if (isMGLevel_[i]) { + coarseLevel = coarserLevel(i); + levels_[coarseLevel].rhs_->copy(*(levels_[i].rhs_), + levels_[coarseLevel].fineDOFs_); + } + + TraverseStack stack; + ElInfo *elInfo = stack.traverseFirst(sparseResidual_->getFESpace()->getMesh(), + -1, Mesh::CALL_EVERY_EL_PREORDER); + while (elInfo) { + Element *element = elInfo->getElement(); + if (elInfo->getLevel() == (i-1) && !element->isLeaf()) { + RCNeighbourList list(1); + list.setElement(0, element); + if (element->getMesh()->getDim() == 3) { + list.setType(0, dynamic_cast<ElInfo3d*>(elInfo)->getType()); + } + levels_[coarseLevel].rhs_->coarseRestrict(list, 1); + } + elInfo = stack.traverseNext(elInfo); + } + } + } + + + void MultiGridSolverScal::fmgInterpol(int level) + { + int coarseLevel = level-1; + + levels_[level].solution_->copy(*(levels_[coarseLevel].solution_), + levels_[coarseLevel].fineDOFs_); + + for (int i = coarseLevel; i < level; i++) { + + TraverseStack stack; + ElInfo *elInfo = stack.traverseFirst(sparseResidual_->getFESpace()->getMesh(), + -1, Mesh::CALL_EVERY_EL_PREORDER); + while(elInfo) { + Element *element = elInfo->getElement(); + if(elInfo->getLevel() == (i) && !element->isLeaf()) { + RCNeighbourList list(1); + list.setElement(0, element); + if(element->getMesh()->getDim() == 3) { + list.setType(0, dynamic_cast<ElInfo3d*>(elInfo)->getType()); + } + levels_[level].solution_->refineInterpol(list, 1); + } + elInfo = stack.traverseNext(elInfo); + } + } + } + + // =============================================================================== + // =============================================================================== + // =============================================================================== + // =============================================================================== + + MultiGridSolverVec::MultiGridSolverVec(const ::std::string &name) + : MultiGridSolverBase<Matrix<DOFMatrix*>, SystemVector>(name), + sparseResidual_(NULL), + denseResidual_(NULL), + lastRes_(1.0), + iteration_(0), + coarseSmoothingSteps_(3), + minLevelGap_(0), + maxMGLevels_(100), + numComponents_(0), + boxSmoothing_(false), + boxDOFs_(0), + galerkin_(0) + { + FUNCNAME("MultiGridSolverVec::MultiGridSolverVec()"); + + GET_PARAMETER(0, name_ + "->coarse level smoothing steps", "%d", + &coarseSmoothingSteps_); + GET_PARAMETER(0, name_ + "->min level gap", "%d", &minLevelGap_); + GET_PARAMETER(0, name_ + "->max mg levels", "%d", &maxMGLevels_); + GET_PARAMETER(0, name_ + "->use galerkin operator", "%d", &galerkin_); + + // Create smoother + ::std::string smootherType("gs"); + GET_PARAMETER(0, name_ + "->smoother", &smootherType); + if(smootherType == "box") { + boxSmoothing_ = true; + } + SmootherCreator<Matrix<DOFMatrix*>, Vector<SparseVector<double>*>, Vector< ::std::set<DegreeOfFreedom>*> > *smootherCreator = + dynamic_cast<SmootherCreator<Matrix<DOFMatrix*>, Vector<SparseVector<double>*>, Vector< ::std::set<DegreeOfFreedom>*> >*>( + CreatorMap<SmootherBase<Matrix<DOFMatrix*>, Vector<SparseVector<double>*>, Vector< ::std::set<DegreeOfFreedom>*> > >::getCreator(smootherType) + ); + if(smootherCreator && !smootherCreator->isNullCreator()) { + smootherCreator->setName(name_ + "->smoother"); + smoother_ = smootherCreator->create(); + } else { + smoother_ = NULL; + ERROR_EXIT("no smoother specified\n"); + } + } + + void MultiGridSolverVec::initMaxLevel() + { + int comp, numComps = solution_->getNumVectors(); + ::std::set<Mesh*> meshes; + for(comp = 0; comp < numComps; comp++) { + Mesh *mesh = solution_->getDOFVector(comp)->getFESpace()->getMesh(); + if(find(meshes.begin(), meshes.end(), mesh) == meshes.end()) { + meshes.insert(mesh); + TraverseStack st; + ElInfo *elInfo = st.traverseFirst(mesh, -1, Mesh::CALL_LEAF_EL); + maxLevel_ = -1; + while(elInfo) { + maxLevel_ = max(elInfo->getLevel(), maxLevel_); + elInfo = st.traverseNext(elInfo); + } + } + } + } + + void MultiGridSolverVec::initMultiGrid(bool initMG) + { + int numLevels = maxLevel_ + 1; + + if (initMG) { + // Get number of components + numComponents_ = solution_->getNumVectors(); + + TEST_EXIT(rhs_->getNumVectors() == numComponents_) + ("invalid number of components\n"); + TEST_EXIT(systemMatrix_->getNumRows() == numComponents_) + ("invalid number of components\n"); + TEST_EXIT(systemMatrix_->getNumCols() == numComponents_) + ("invalid number of components\n"); + + // Get fe spaces and create residual vectors + sparseResidual_ = NEW Vector<SparseVector<double>*>(numComponents_); + ::std::vector<FiniteElemSpace*> feSpaces(numComponents_); + for (int i = 0; i < numComponents_; i++) { + feSpaces[i] = const_cast<FiniteElemSpace*> + (solution_->getDOFVector(i)->getFESpace()); + (*sparseResidual_)[i] = NEW SparseVector<double>(feSpaces[i], + "sparse residual"); + } + + // Create dens residual vectors + denseResidual_ = NEW SystemVector("dense residual", + feSpaces, + numComponents_); + for (int i = 0; i < numComponents_; i++) { + denseResidual_->setDOFVector(i, NEW DOFVector<double>(feSpaces[i], + "dense residual")); + } + + Mesh *mesh = feSpaces[0]->getMesh(); + int dim = mesh->getDim(); + + TEST_EXIT(mesh->queryCoarseDOFs()) + ("preserve coarse dofs not set in mesh\n"); + + + // Check which level is a multigrid level and set the corresponding field + // to true. + isMGLevel_.resize(numLevels, false); + isMGLevel_[minLevel_] = true; + isMGLevel_[maxLevel_] = true; + if (numLevels > 2) { + double step = (static_cast<double>(maxMGLevels_) - 2.0) / (numLevels - 2.0); + double sum = 0.0; + int gap = 0; + for (int i = maxLevel_ - 1; i > minLevel_; i--) { + sum += step; + //MSG("%d %f\n", i, sum); + ++gap; + if (gap > minLevelGap_ && sum >= 1.0) { + gap = 0; + isMGLevel_[i] = true; + sum -= 1.0; + } else { + MSG("level %d skipped\n", i); + } + } + } + + levels_.resize(numLevels); + + // Create multigrid level data. + for (int i = 0; i < numLevels; i++) { + if (isMGLevel_[i]) { + levels_[i].components_.resize(numComponents_); + levels_[i].levelDOFs_.resize(numComponents_); + + ::std::map<FiniteElemSpace*, FESpaceData*> feSpaceData; + MeshData *meshData = NEW MeshData; + + levels_[i].solution_ = NEW Vector<SparseVector<double>*>(numComponents_); + levels_[i].oldSolution_ = NEW Vector<SparseVector<double>*>(numComponents_); + levels_[i].rhs_ = NEW Vector<SparseVector<double>*>(numComponents_); + levels_[i].matrix_ = NEW Matrix<DOFMatrix*>(numComponents_, + numComponents_); + + // Set component dependend data. + for (int j = 0; j < numComponents_; j++) { + if (!feSpaceData[feSpaces[j]]) { + feSpaceData[feSpaces[j]] = NEW FESpaceData; + } + levels_[i].components_[j].meshData_ = meshData; + levels_[i].components_[j].feSpaceData_ = feSpaceData[feSpaces[j]]; + + levels_[i].levelDOFs_[j] = &(feSpaceData[feSpaces[j]]->levelDOFs_); + + (*(levels_[i].solution_))[j] = + NEW SparseVector<double>(feSpaces[j], "sparse level solution"); + (*(levels_[i].oldSolution_))[j] = + NEW SparseVector<double>("old level solution", + (*(levels_[i].solution_))[j]); + (*(levels_[i].rhs_))[j] = + NEW SparseVector<double>("sparse level rhs", + (*(levels_[i].solution_))[j]); + + for (int k = 0; k < numComponents_; k++) { + if ((*systemMatrix_)[j][k]) { + (*(levels_[i].matrix_))[j][k] = NEW DOFMatrix(feSpaces[j], + feSpaces[k], + "level matrix"); + (*(levels_[i].matrix_))[j][k]-> + setBoundaryManager((*(systemMatrix_))[j][k]-> + getBoundaryManager()); + if (j != k) { + (*(levels_[i].matrix_))[j][k]->setCoupleMatrix(true); + } + } else { + (*(levels_[i].matrix_))[j][k] = NULL; + } + } + } + } // if isMGLevel_[i] + } // for numLevels + + + int degree; + + interpolMatrix_.resize(numComponents_); + restrictMatrix_.resize(numComponents_); + + // Assemble matrices + for (int row = 0; row < numComponents_; row++) { + const BasisFunction* basFcts = feSpaces[row]->getBasisFcts(); + int numDOFs = basFcts->getNumber(); + + degree = basFcts->getDegree(); + + interpolMatrix_[row] = interpolMatrices[dim-1][degree-1]; + restrictMatrix_[row] = restrictMatrices[dim-1][degree-1]; + + DegreeOfFreedom *dofs = GET_MEMORY(DegreeOfFreedom, numDOFs); + Element *element; + DOFAdmin *admin = feSpaces[row]->getAdmin(); + int level; + + TraverseStack stack; + + // fill max dof level for each dof + DOFVector<int> maxDOFLevels(feSpaces[row], "maxDOFLevel"); + maxDOFLevels.set(minLevel_); + ElInfo *elInfo = stack.traverseFirst(mesh, -1, Mesh::CALL_EVERY_EL_PREORDER); + while (elInfo) { + element = elInfo->getElement(); + level = elInfo->getLevel(); + + if (row == 0) { + levels_[level].elements_.push_back(element); + } + if (dim == 3) { + levels_[level].elementTypes_. + push_back(dynamic_cast<ElInfo3d*>(elInfo)->getType()); + } + + + basFcts->getLocalIndices(element, admin, dofs); + for (int i = 0; i < numDOFs; i++) { + maxDOFLevels[dofs[i]] = max(maxDOFLevels[dofs[i]], + level); + } + elInfo = stack.traverseNext(elInfo); + } + + for (int col = 0; col < numComponents_; col++) { + DOFMatrix *dofMatrix = (*systemMatrix_)[row][col]; + if(dofMatrix) { + ::std::vector<Operator*>::iterator it; + ::std::vector<Operator*>::iterator opBegin = dofMatrix->getOperatorsBegin(); + ::std::vector<Operator*>::iterator opEnd = dofMatrix->getOperatorsEnd(); + ::std::vector<double*>::iterator factorIt; + ::std::vector<double*>::iterator factorBegin = dofMatrix->getOperatorFactorBegin(); + ElementMatrix *elementMatrix = NULL; + const BoundaryType *bound; + + // assemble level matrices and create dof sets + elInfo = stack.traverseFirst(mesh, -1, + Mesh::CALL_EVERY_EL_PREORDER | + Mesh::FILL_BOUND | + Mesh::FILL_DET | + Mesh::FILL_GRD_LAMBDA | + Mesh::FILL_COORDS); + + while (elInfo) { + element = elInfo->getElement(); + level = elInfo->getLevel(); + basFcts->getLocalIndices(element, admin, dofs); + bound = basFcts->getBound(elInfo, NULL); + elementMatrix = (*opBegin)->getAssembler()->initElementMatrix(elementMatrix, elInfo); + + bool levelUsed = isMGLevel_[level]; + if (levelUsed) { + for (it = opBegin, factorIt = factorBegin; + it != opEnd; + ++it, ++factorIt) + { + (*it)->getElementMatrix(elInfo, + elementMatrix, + *factorIt ? **factorIt : 1.0); + } + + (*(levels_[level].matrix_))[row][col]-> + addElementMatrix(1.0, *elementMatrix, bound); + } + + if (element->isLeaf()) { + if (!levelUsed) { + level = mgLevel(level); + for (it = opBegin, factorIt = factorBegin; + it != opEnd; + ++it, ++factorIt) + { + (*it)->getElementMatrix(elInfo, + elementMatrix, + *factorIt ? **factorIt : 1.0); + } + //MSG("element %d added to level %d\n", element->getIndex(), level); + (*(levels_[level].matrix_))[row][col]-> + addElementMatrix(1.0, *elementMatrix, bound); + } + + // add nearest neighbour element matrices and dofs + int maxDOFLevel = -1; + for (int i = 0; i < dim + 1; i++) { + maxDOFLevel = max(maxDOFLevel, mgLevel(maxDOFLevels[dofs[i]])); + } + + if (maxDOFLevel > level) { + for (int j = level + 1; j < maxDOFLevel + 1; j++) { + if (isMGLevel_[j]) { + (*(levels_[j].matrix_))[row][col]-> + addElementMatrix(1.0, *elementMatrix, bound); + } + } + if (row == col) { + for (int j = 0; j < numDOFs; j++) { + for (int k = level + 1; k < maxDOFLevel + 1; k++) { + if (isMGLevel_[k]) { + if (mgLevel(maxDOFLevels[dofs[j]]) < k) { + levels_[k].components_[row].feSpaceData_-> + nearestNeighbourDOFs_.insert(dofs[j]); + //MSG("level %d comp %d nn: %d\n", k, row, dofs[j]); + } + } + } + } + } + } + if (row == col) { + for (int i = 0; i < numDOFs; i++) { + if (mgLevel(maxDOFLevels[dofs[i]]) == level) { + levels_[level].components_[row].feSpaceData_-> + coarseDOFs_.insert(dofs[i]); + levels_[level].components_[row].feSpaceData_-> + levelDOFs_.insert(dofs[i]); + //MSG("level %d comp %d coarse: %d\n", level, row, dofs[i]); + } + } + } + } else { // element is not leaf + if (row == col) { + if (level >= minLevel_) { + if (levelUsed) { + for (int i = 0; i < numDOFs; i++) { + levels_[level].components_[row].feSpaceData_-> + fineDOFs_.insert(dofs[i]); + levels_[level].components_[row].feSpaceData_-> + levelDOFs_.insert(dofs[i]); + //MSG("level %d comp %d fine: %d\n", level, row, dofs[i]); + } + } + } + } + } + elInfo = stack.traverseNext(elInfo); + } + } + } + + FREE_MEMORY(dofs, DegreeOfFreedom, numDOFs); + } + + if (galerkin_) { + int level; + TraverseStack stack; + ElInfo *elInfo; + const FiniteElemSpace *feSpace = feSpaces[0]; + const BasisFunction *basFcts = feSpace->getBasisFcts(); + DOFAdmin *admin = feSpace->getAdmin(); + Mesh *mesh = feSpace->getMesh(); + + for (int row = 0; row < numComponents_; row++) { + for (int col = 0; col < numComponents_; col++) { + if ((*(levels_[maxLevel_].matrix_))[row][col]) { + (*(levels_[maxLevel_].matrix_))[row][col]->copy(*((*systemMatrix_)[row][col])); + } + } + } + + DegreeOfFreedom *child0DOFs = GET_MEMORY(DegreeOfFreedom, dim + 1); + DegreeOfFreedom *parentDOFs = GET_MEMORY(DegreeOfFreedom, dim + 1); + + Vector<DegreeOfFreedom> fineDOFs(dim + 2); + Matrix<double> a(dim + 2, dim + 2); + + DOFMatrix tmp1(feSpace, feSpace, "tmp1"); + DOFMatrix tmp2(feSpace, feSpace, "tmp2"); + + DOFMatrix *coarseMatrix = NULL; + DOFMatrix *fineMatrix = NULL; + + for (int row = 0; row < numComponents_; row++) { + for (int col = 0; col < numComponents_; col++) { + if ((*systemMatrix_)[row][col]) { + fineMatrix = (*(levels_[maxLevel_].matrix_))[row][col]; + + for (level = maxLevel_ - 1; level >= 0; level--) { + if (level >= minLevel_) { + + ::std::map< ::std::pair<int, int>, bool> visited; + coarseMatrix = + isMGLevel_[level] ? + (*(levels_[level].matrix_))[row][col] : + (fineMatrix == &tmp1 ? &tmp2 : &tmp1); + + coarseMatrix->clear(); + + elInfo = stack.traverseFirst(mesh, -1, Mesh::CALL_EVERY_EL_PREORDER); + while (elInfo) { + Element *element = elInfo->getElement(); + + basFcts->getLocalIndices(element, admin, parentDOFs); + + for (int i = 0; i < dim + 1; i++) { + fineDOFs[i] = parentDOFs[i]; + } + + if (elInfo->getLevel() == level && !element->isLeaf()) { + basFcts->getLocalIndices(element->getChild(0), admin, child0DOFs); + + fineDOFs[dim + 1] = child0DOFs[dim]; + + double *ptr; + + for (int i = 0; i < dim + 2; i++) { + for (int j = 0; j < dim + 2; j++) { + ptr = fineMatrix->hasSparseDOFEntry(fineDOFs[i], fineDOFs[j]); + a[i][j] = ptr ? *ptr : 0.0; + } + } + + for (int i = 0; i < dim + 1; i++) { + for(int j = 0; j < dim + 1; j++) { + if (visited[::std::pair<int, int>(fineDOFs[i], fineDOFs[j])] == false) { + coarseMatrix->addSparseDOFEntry(1.0, + parentDOFs[i], + parentDOFs[j], + 0.0, + false); + } + } + } + + for (int i = 0; i < dim + 1; i++) { + for (int j = 0; j < dim + 1; j++) { + if (visited[::std::pair<int, int>(fineDOFs[i], fineDOFs[j])] == false) { + coarseMatrix->addSparseDOFEntry(1.0, + parentDOFs[i], + parentDOFs[j], + a[i][j], + true); + } + } + } + + for (int i = 0; i < dim + 1; i++) { + for (int j = 0; j < 2; j++) { + if (visited[::std::pair<int, int>(fineDOFs[i], fineDOFs[dim + 1])] == false) { + coarseMatrix->addSparseDOFEntry(0.5, + parentDOFs[i], + parentDOFs[j], + a[i][dim + 1], + true); + + coarseMatrix->addSparseDOFEntry(0.5, + parentDOFs[j], + parentDOFs[i], + a[dim + 1][i], + true); + } + } + } + + if (visited[::std::pair<int, int>(fineDOFs[dim + 1], fineDOFs[dim + 1])] == false) { + for (int i = 0; i < 2; i++) { + for (int j = 0; j < 2; j++) { + coarseMatrix->addSparseDOFEntry(0.25, + parentDOFs[i], + parentDOFs[j], + a[dim + 1][dim + 1], + true); + } + } + } + + for (int i = 0; i < dim + 2; i++) { + for (int j = 0; j < dim + 2; j++) { + visited[::std::pair<int, int>(fineDOFs[i], fineDOFs[j])] = true; + visited[::std::pair<int, int>(fineDOFs[j], fineDOFs[i])] = true; + } + } + } + + if (element->isLeaf() && elInfo->getLevel() <= level) { + double *ptr; + + for (int i = 0; i < dim + 1; i++) { + for (int j = 0; j < dim + 1; j++) { + ptr = fineMatrix->hasSparseDOFEntry(fineDOFs[i], fineDOFs[j]); + a[i][j] = ptr ? *ptr : 0.0; + } + } + + for (int i = 0; i < dim + 1; i++) { + for (int j = 0; j < dim + 1; j++) { + if (!visited[::std::pair<int, int>(parentDOFs[i], parentDOFs[j])]) { + coarseMatrix->addSparseDOFEntry(1.0, + parentDOFs[i], + parentDOFs[j], + a[i][j], + false); + } + } + } + } + elInfo = stack.traverseNext(elInfo); + } + fineMatrix = coarseMatrix; + } + } + } + } + } + + FREE_MEMORY(child0DOFs, DegreeOfFreedom, dim + 1); + FREE_MEMORY(parentDOFs, DegreeOfFreedom, dim + 1); + } + + if (boxSmoothing_) { + boxDOFs_.resize(numComponents_); + for (int i = 0; i < numComponents_; i++) { + boxDOFs_[i] = new ::std::set<DegreeOfFreedom>; + } + } + + } + + + iteration_ = 0; + + lastRes_ = 1.0; + + // compute start residual + mv(*systemMatrix_, *solution_, *denseResidual_); + axpy(-1.0, *rhs_, *denseResidual_); + + double res = norm(denseResidual_); + MSG("residual: %e\n", res); + lastRes_ = res; + + for (int row = 0; row < numComponents_; row++) { + for (int i = 0; i < numLevels; i++) { + if (isMGLevel_[i]) { + (*(levels_[i].solution_))[row]-> + copyFromDOFVector(*(solution_->getDOFVector(row)), + levels_[i].components_[row].feSpaceData_->coarseDOFs_); + (*(levels_[i].solution_))[row]-> + copyFromDOFVector(*(solution_->getDOFVector(row)), + levels_[i].components_[row].feSpaceData_->nearestNeighbourDOFs_); + } + } + + + (*(levels_[maxLevel_].rhs_))[row]-> + copyFromDOFVector(*(rhs_->getDOFVector(row)), + levels_[maxLevel_].components_[row].feSpaceData_->coarseDOFs_); + } + } + + + void MultiGridSolverVec::exitMultiGrid() + { + int numLevels = maxLevel_ + 1; + + ::std::set<FESpaceData*> deletedFESpaceData; + ::std::set<MeshData*> deletedMeshData; + + for (int i = 0; i < numLevels; i++) { + if (isMGLevel_[i]) { + for (int j = 0; j < numComponents_; j++) { + if (levels_[i].components_[j].meshData_) { + ::std::set<MeshData*>::iterator it; + it = ::std::find(deletedMeshData.begin(), + deletedMeshData.end(), + levels_[i].components_[j].meshData_); + if (it == deletedMeshData.end()) { + deletedMeshData.insert(levels_[i].components_[j].meshData_); + DELETE levels_[i].components_[j].meshData_; + levels_[i].components_[j].meshData_ = NULL; + } + } + if (levels_[i].components_[j].feSpaceData_) { + ::std::set<FESpaceData*>::iterator it; + it = ::std::find(deletedFESpaceData.begin(), + deletedFESpaceData.end(), + levels_[i].components_[j].feSpaceData_); + if (it == deletedFESpaceData.end()) { + deletedFESpaceData.insert(levels_[i].components_[j].feSpaceData_); + DELETE levels_[i].components_[j].feSpaceData_; + levels_[i].components_[j].feSpaceData_ = NULL; + } + } + DELETE (*(levels_[i].oldSolution_))[j]; + DELETE (*(levels_[i].rhs_))[j]; + DELETE (*(levels_[i].solution_))[j]; + + for (int k = 0; k < numComponents_; k++) { + if ((*(levels_[i].matrix_))[j][k]) { + DELETE (*(levels_[i].matrix_))[j][k]; + } + } + } + DELETE levels_[i].oldSolution_; + DELETE levels_[i].solution_; + DELETE levels_[i].rhs_; + DELETE levels_[i].matrix_; + } + } + levels_.resize(0); + isMGLevel_.resize(0); + + if (boxSmoothing_) { + for (int i = 0; i < numComponents_; i++) { + delete boxDOFs_[i]; + } + boxDOFs_.resize(0); + } + + for (int i = 0; i < numComponents_; i++) { + DELETE (*sparseResidual_)[i]; + DELETE denseResidual_->getDOFVector(i); + } + DELETE sparseResidual_; + DELETE denseResidual_; + + numComponents_ = 0; + } + + + void MultiGridSolverVec::smooth(int level, int steps) + { + if (boxSmoothing_) { + for (int iteration = 0; iteration < steps; iteration++) { + ::std::vector<Element*>::iterator elIt, elBegin, elEnd; + elBegin = levels_[level].elements_.begin(); + elEnd = levels_[level].elements_.end(); + for (elIt = elBegin; elIt != elEnd; ++elIt) { + Element *element = *elIt; + for (int i = 0; i < numComponents_; i++) { + boxDOFs_[i]->clear(); + const FiniteElemSpace *feSpace = + (*(levels_[level].solution_))[i]->getFESpace(); + int numDOFs = feSpace->getBasisFcts()->getNumber(); + DOFAdmin *admin = feSpace->getAdmin(); + DegreeOfFreedom *dofs = GET_MEMORY(DegreeOfFreedom, numDOFs); + feSpace->getBasisFcts()->getLocalIndices(element, + admin, + dofs); + for (int j = 0; j < numDOFs; j++) { + boxDOFs_[i]->insert(dofs[j]); + } + FREE_MEMORY(dofs, DegreeOfFreedom, numDOFs); + } + + smoother_->smooth(levels_[level].matrix_, + levels_[level].solution_, + levels_[level].rhs_, + 1, + boxDOFs_); + } + } + } else { + smoother_->smooth(levels_[level].matrix_, + levels_[level].solution_, + levels_[level].rhs_, + steps, + levels_[level].levelDOFs_); + + } + + // DOFVector<double> sol0((*(systemMatrix_))[0][0]->getFESpace(), "sol0"); + // (*(levels_[level].solution_))[0]->copyToDOFVector(sol0); + // MacroWriter::writeMacro((*(systemMatrix_))[0][0]->getFESpace(), "sol0.mesh", 0.0, level, Mesh::CALL_EL_LEVEL); + // ValueWriter::writeValues(&sol0, "sol0.dat", 0.0, level, Mesh::CALL_EL_LEVEL); + // DOFVector<double> sol1((*(systemMatrix_))[1][1]->getFESpace(), "sol1"); + // (*(levels_[level].solution_))[1]->copyToDOFVector(sol1); + // MacroWriter::writeMacro((*(systemMatrix_))[1][1]->getFESpace(), "sol1.mesh", 0.0, level, Mesh::CALL_EL_LEVEL); + // ValueWriter::writeValues(&sol1, "sol1.dat", 0.0, level, Mesh::CALL_EL_LEVEL); + // MSG("smoothed %d\n", level); + // WAIT; + } + + + void MultiGridSolverVec::prolongate(int level, int coarseLevel) + { + for (int comp = 0; comp < numComponents_; comp++) { + for (int i = coarseLevel; i < level; i++) { + interpolMatrix_[comp]->mv((*sparseResidual_)[comp], + (*sparseResidual_)[comp], + i); + } + } + } + + + void MultiGridSolverVec::restrict(int level, int coarseLevel) + { + ::std::vector<Element*>::iterator elIt, elBegin, elEnd; + ::std::vector<int>::iterator typeIt; + + for (int comp = 0; comp < numComponents_; comp++) { + (*(levels_[coarseLevel].oldSolution_))[comp]-> + copy(*((*(levels_[level].solution_))[comp]), + levels_[level].components_[comp].feSpaceData_->levelDOFs_); + (*(levels_[coarseLevel].oldSolution_))[comp]-> + copy(*((*(levels_[level].solution_))[comp]), + levels_[level].components_[comp].feSpaceData_->nearestNeighbourDOFs_); + + for (int i = level; i > coarseLevel; i--) { + SparseVector<double> visited("visited", (*sparseResidual_)[comp]); + + elBegin = levels_[i-1].elements_.begin(); + elEnd = levels_[i-1].elements_.end(); + + typeIt = levels_[i-1].elementTypes_.begin(); + for (elIt = elBegin; elIt != elEnd; ++elIt) { + Element *element = *elIt; + if (!element->isLeaf()) { + RCNeighbourList list(1); + list.setElement(0, element); + if (element->getMesh()->getDim() == 3) { + list.setType(0, *typeIt); + } + (*(levels_[coarseLevel].oldSolution_))[comp]->coarseRestrict(list, 1); + //sparseResidual_->coarseRestrict(list, 1); + } + } + + // restrictMatrix_[comp]->mv((*(levels_[coarseLevel].oldSolution_))[comp], + // (*(levels_[coarseLevel].oldSolution_))[comp], + // i-1); + restrictMatrix_[comp]->mv((*sparseResidual_)[comp], + (*sparseResidual_)[comp], + i-1); + } + + (*(levels_[coarseLevel].solution_))[comp]-> + copy(*((*(levels_[coarseLevel].oldSolution_))[comp]), + levels_[coarseLevel].components_[comp].feSpaceData_->fineDOFs_); + } + } + + + void MultiGridSolverVec::computeResidual(int level, int coarseLevel) + { + DOFMatrix *matrix; + SparseVector<double> *res, *sol, *rhs; + ::std::set<DegreeOfFreedom> *dofSet; + for (int i = 0; i < numComponents_; i++) { + res = (*sparseResidual_)[i]; + res->clear(); + rhs = (*(levels_[level].rhs_))[i]; + dofSet = levels_[level].levelDOFs_[i]; + for (int j = 0; j < numComponents_; j++) { + matrix = (*(levels_[level].matrix_))[i][j]; + if (matrix) { + sol = (*(levels_[level].solution_))[j]; + mv(*matrix, *sol, *res, *dofSet, true); + } + } + axpy(-1.0, *rhs, *res, *dofSet); + } + } + + + void MultiGridSolverVec::computeRHS(int level, int coarseLevel) + { + DOFMatrix *matrix; + SparseVector<double> *oldSol, *rhs, *res; + ::std::set<DegreeOfFreedom> *dofSet; + for (int i = 0; i < numComponents_; i++) { + rhs = (*(levels_[coarseLevel].rhs_))[i]; + rhs->clear(); + res = (*sparseResidual_)[i]; + dofSet = &(levels_[coarseLevel].components_[i].feSpaceData_->fineDOFs_); + for (int j = 0; j < numComponents_; j++) { + matrix = (*(levels_[coarseLevel].matrix_))[i][j]; + if (matrix) { + oldSol = (*(levels_[coarseLevel].oldSolution_))[j]; + mv(*matrix, *oldSol, *rhs, *dofSet, true); + } + } + axpy(-1.0, *res, *rhs, *dofSet); + dofSet = &(levels_[coarseLevel].components_[i].feSpaceData_->coarseDOFs_); + rhs->copyFromDOFVector(*(rhs_->getDOFVector(i)), *dofSet); + } + } + + + void MultiGridSolverVec::computeCorrection(int level, int coarseLevel) + { + SparseVector<double> *res, *sol, *oldSol; + ::std::set<DegreeOfFreedom> *dofSet; + for (int comp = 0; comp < numComponents_; comp++) { + dofSet = &(levels_[coarseLevel].components_[comp].feSpaceData_->fineDOFs_); + sol = (*(levels_[coarseLevel].solution_))[comp]; + oldSol = (*(levels_[coarseLevel].oldSolution_))[comp]; + res = (*sparseResidual_)[comp]; + res->copy(*sol, *dofSet); + axpy(-1.0, *oldSol, *res, *dofSet); + } + } + + + void MultiGridSolverVec::fixSolution(int level, int coarseLevel) + { + SparseVector<double> *fineSol, *coarseSol, *res; + ::std::set<DegreeOfFreedom> *dofSet; + for (int comp = 0; comp < numComponents_; comp++) { + fineSol = (*(levels_[level].solution_))[comp]; + coarseSol = (*(levels_[coarseLevel].solution_))[comp]; + res = (*sparseResidual_)[comp]; + dofSet = + &(levels_[level].components_[comp].feSpaceData_->nearestNeighbourDOFs_); + fineSol->copy(*coarseSol, *dofSet); + dofSet = + &(levels_[level].components_[comp].feSpaceData_->levelDOFs_); + axpy(1.0, *res, *fineSol, *dofSet); + } + } + + + void MultiGridSolverVec::exactSolve(int level) + { + smooth(level, coarseSmoothingSteps_); + } + + + bool MultiGridSolverVec::toleranceReached(double tol) + { + FUNCNAME("MultiGridSolverVec::toleranceReached()"); + + SparseVector<double> *sol; + ::std::set<DegreeOfFreedom> *dofSet; + for (int level = minLevel_; level < maxLevel_ + 1; level++) { + if (isMGLevel_[level]) { + for (int i = 0; i < numComponents_; i++) { + sol = (*(levels_[level].solution_))[i]; + dofSet = &(levels_[level].components_[i].feSpaceData_->coarseDOFs_); + sol->copyToDOFVector(*(solution_->getDOFVector(i)), *dofSet); + } + } + } + + mv(*systemMatrix_, *solution_, *denseResidual_); + axpy(-1.0, *rhs_, *denseResidual_); + + ++iteration_; + + double res = norm(denseResidual_); + + MSG("iteration %d - residual: %e (res/lastRes: %e)\n", + iteration_, res, res/lastRes_); + lastRes_ = res; + + return (res < tol); + } + + + void MultiGridSolverVec::initFullMultiGrid() + { + FUNCNAME("MultiGridSolverVec::initFullMultiGrid()"); + ERROR_EXIT("not yet\n"); + } + + + void MultiGridSolverVec::fmgInterpol(int level) + { + FUNCNAME("MultiGridSolverVec::fmgInterpol()"); + ERROR_EXIT("not yet\n"); + } + + +} diff --git a/AMDiS/src/MultiGridSolver.h b/AMDiS/src/MultiGridSolver.h new file mode 100644 index 0000000000000000000000000000000000000000..03b6c1d4cd8aecc7b97962f32e58d7fff37efd06 --- /dev/null +++ b/AMDiS/src/MultiGridSolver.h @@ -0,0 +1,635 @@ +// ============================================================================ +// == == +// == AMDiS - Adaptive multidimensional simulations == +// == == +// ============================================================================ +// == == +// == crystal growth group == +// == == +// == Stiftung caesar == +// == Ludwig-Erhard-Allee 2 == +// == 53175 Bonn == +// == germany == +// == == +// ============================================================================ +// == == +// == http://www.caesar.de/cg/AMDiS == +// == == +// ============================================================================ + +/** \file MultiGridSolver.h */ + +#ifndef AMDIS_MULTIGRIDSOLVER_H +#define AMDIS_MULTIGRIDSOLVER_H + +#include "MultiGridSolverBase.h" +#include <vector> +#include "Global.h" +#include "SmootherBase.h" +#include <set> +#include <map> +#include "MatrixVector.h" +#include "SystemVector.h" + +namespace AMDiS { + + class DOFMatrix; + template<typename T> class DOFVector; + template<typename T> class SparseVector; + class LevelAdmin; + class FiniteElemSpace; + class DOFAdmin; + class RCNeighbourList; + class InterpolRestrictMatrix; + + /** \brief + * Implementation of the multigrid solver base class for scalar problems. + */ + class MultiGridSolverScal : public MultiGridSolverBase<DOFMatrix, DOFVector<double> > + { + protected: + /** \brief + * Class to assemble all data of one multigrid level. + */ + class LevelData + { + public: + LevelData() + : matrix_(NULL), + solution_(NULL), + oldSolution_(NULL), + rhs_(NULL) + {}; + + /** \brief + * The level DOFMatrix. + */ + DOFMatrix *matrix_; + + /** \brief + * The solution stored in sparse format. + */ + SparseVector<double> *solution_; + + /** \brief + * The old solution stored in sparse format. + */ + SparseVector<double> *oldSolution_; + + /** \brief + * The right hand side of the level stored in sparse format. + */ + SparseVector<double> *rhs_; + + /** \brief + * Set of DOFs of all elements of the level. + */ + ::std::set<DegreeOfFreedom> levelDOFs_; + + /** \brief + * Set of DOFs of all elements of the level, which are also + * included in finer levels. + */ + ::std::set<DegreeOfFreedom> fineDOFs_; + + /** \brief + * Set of DOFs of all elements of the level, which are not + * included in finer levels. + */ + ::std::set<DegreeOfFreedom> coarseDOFs_; + + /** \brief + */ + ::std::set<DegreeOfFreedom> nearestNeighbourDOFs_; + + /** \brief + * List of all elements in the mesh on the current level. + */ + ::std::vector<Element*> elements_; + + /** \brief + * This array is only used if the elements are of dim=3. Than there + * are different element types possible. All different element types + * of the mesh are stored here. + */ + ::std::vector<int> elementTypes_; + }; + + public: + /** \brief + * Constructor of the scalar multigrid solver. + */ + MultiGridSolverScal(const ::std::string &name); + + /** \brief + * Computes the residual and checks if its norm is less than the tolerance. + */ + bool toleranceReached(double tol); + + /** \brief + * Traverses all elements and searchs for the highest level of an + * elements DOF. The result is stored in variable maxLevel_. + */ + void initMaxLevel(); + + /** \brief + * Initialize the multigrid solver. + */ + void initMultiGrid(bool initMG); + + /** \brief + * Frees all allocated memory. + */ + void exitMultiGrid(); + + /** \brief + * Solve the given level exactly. + * TODO: Implement a real exact solver. At the moment we use the smoother. + */ + void exactSolve(int level); + + /** \brief + * Call the smoother on the given level. steps is the maximum number of + * smoothing steps. + */ + void smooth(int level, int steps); + + /** \brief + * Restricts the residual and the solution from a fine multigrid level to + * a coarser multigrid level. + */ + void restrict(int level, int coarseLevel); + + /** \brief + * Prolongates the residual from a coarse multigrid level to a finer + * multigrid level. + */ + void prolongate(int level, int coarseLevel); + + /** \brief + * Computes the residual of a given leve. CoarseLevel parameter will be + * not considered. + */ + void computeResidual(int level, int coarseLevel); + + /** \brief + * Computes the rhs of the coarse level. Level parameter will be not + * considered. + */ + void computeRHS(int level, int coarseLevel); + + /** \brief + * Computes the correction of the coarse level. Level parameter will be + * not considered. + */ + void computeCorrection(int level, int coarseLevel); + + /** \brief + * Add the correction, which has been computed on the coarse grid, to the + * solution of the fine grid. + */ + void fixSolution(int level, int coarseLevel); + + /** \brief + * Returns for a given level the next coarser multigrid level. + */ + int coarserLevel(int level) { + FUNCNAME("MultiGridSolverScal::coarserLevel()"); + TEST_EXIT(level > minLevel_)("invalid level\n"); + do { + --level; + } while(!isMGLevel(level)); + return level; + }; + + /** \brief + * Returns true, if the level is a multigrid level, otherwise false. + */ + inline bool isMGLevel(int level) { + return isMGLevel_[level]; + }; + + /** \brief + * Returns for a given level the next multigrid level. + */ + inline int mgLevel(int level) { + while (!isMGLevel(level)) { + level++; + } + return level; + }; + + /** \brief + * Initialize the full multigrid cycle. + */ + void initFullMultiGrid(); + + /** \brief + * + */ + void fmgInterpol(int level); + + public: + /** \brief + * Data of all multigrid levels. + */ + ::std::vector<LevelData> levels_; + + /** \brief + * Residual stored in sparse format. + */ + SparseVector<double> *sparseResidual_; + + /** \brief + * Residual stored in dense format. + */ + DOFVector<double> *denseResidual_; + + /** \brief + * 2-Norm of the last residual. + */ + double lastRes_; + + /** \brief + * Defines for all mesh levels, if the level is a multigrid level. + * isMGLevel[0] is the coarsest grid level. + */ + ::std::vector<bool> isMGLevel_; + + /** \brief + * Counts the number of multigrid iterations. + */ + int iteration_; + + /** \brief + * Number of smoothing steps on the coarsest level. + */ + int coarseSmoothingSteps_; + + /** \brief + * Number of mesh levels that at leatst are skipped between two multigrid + * levels. + */ + int minLevelGap_; + + /** \brief + * Maximum number of allowed multigrid levels. + */ + int maxMGLevels_; + + /** \brief + * Smoother + */ + SmootherBase<DOFMatrix, + SparseVector<double>, + ::std::set<DegreeOfFreedom> > *smoother_; + + /** \brief + * Interpolation matrix for interpolating the residual between two meshes. + */ + InterpolRestrictMatrix *interpolMatrix_; + + /** \brief + * Restriction matrix for restricting the residual between two meshes. + */ + InterpolRestrictMatrix *restrictMatrix_; + + /** \brief + * + */ + int galerkin_; + }; + + + // ============================================================================ + // ============================================================================ + // ============================================================================ + // ============================================================================ + + + /** \brief + * Implementation of the multigrid solver base class for scalar problems. + */ + class MultiGridSolverVec : public MultiGridSolverBase<Matrix<DOFMatrix*>, + SystemVector> + { + public: + /** \brief + * Multigrid data that depends on the fe space. + */ + class FESpaceData + { + public: + MEMORY_MANAGED(FESpaceData); + + /** \brief + * Set of DOFs of all elements of the level. + */ + ::std::set<DegreeOfFreedom> levelDOFs_; + + /** \brief + * Set of DOFs of all elements of the level, which are also + * included in finer levels. + */ + ::std::set<DegreeOfFreedom> fineDOFs_; + + /** \brief + * Set of DOFs of all elements of the level, which are not + * included in finer levels. + */ + ::std::set<DegreeOfFreedom> coarseDOFs_; + + /** \brief + */ + ::std::set<DegreeOfFreedom> nearestNeighbourDOFs_; + }; + + /** \brief + * Multigrid data that depend on the mesh. + */ + class MeshData + { + public: + MEMORY_MANAGED(MeshData); + + MeshData() : maxLevel(0) {}; + + int maxLevel; + }; + + /** \brief + * Data for one component within one level. + */ + class ComponentData + { + public: + MEMORY_MANAGED(ComponentData); + + ComponentData() + : feSpaceData_(NULL), + meshData_(NULL) + {}; + + FESpaceData *feSpaceData_; + MeshData *meshData_; + }; + + /** \brief + * Data for one multigrid level. + */ + class LevelData + { + public: + MEMORY_MANAGED(LevelData); + + LevelData() + : matrix_(NULL), + oldSolution_(NULL), + solution_(NULL), + rhs_(NULL) + {}; + + /** \brief + * The DOF matrices. + */ + Matrix<DOFMatrix*> *matrix_; + + /** \brief + * Vector of old solutions, each stored in sparse format. + */ + Vector<SparseVector<double>*> *oldSolution_; + + /** \brief + * Vector of solutions, each stored in sparse format. + */ + Vector<SparseVector<double>*> *solution_; + + /** \brief + * Vector of rhs', each stored in sparse format. + */ + Vector<SparseVector<double>*> *rhs_; + + /** \brief + * Mesh and FE space dependend data for each component. + */ + ::std::vector<ComponentData> components_; + + /** \brief + * Stores for each component all DOFs at this level. + */ + Vector< ::std::set<DegreeOfFreedom>*> levelDOFs_; + + /** \brief + * List of all elements in the mesh on the current level. + */ + ::std::vector<Element*> elements_; + + /** \brief + * This array is only used if the elements are of dim=3. Than there + * are different element types possible. All different element types + * of the mesh are stored here. + */ + ::std::vector<int> elementTypes_; + }; + + public: + /** \brief + * Constructor of the vector multigrid solver. + */ + MultiGridSolverVec(const ::std::string &name); + + /** \brief + * Computes the residual and checks if its norm is less than the tolerance. + */ + bool toleranceReached(double tol); + + /** \brief + * Traverses all elements and searchs for the highest level of an + * elements DOF. The result is stored in variable maxLevel_. + */ + void initMaxLevel(); + + /** \brief + * Initialize the multigrid solver. + */ + void initMultiGrid(bool initMG); + + /** \brief + * Frees all allocated memory. + */ + void exitMultiGrid(); + + /** \brief + * Solve the given level exactly. + * TODO: Implement a real exact solver. At the moment we use the smoother. + */ + void exactSolve(int level); + + /** \brief + * Call the smoother on the given level. steps is the maximum number of + * smoothing steps. + */ + void smooth(int level, int steps); + + /** \brief + * Restricts the residual and the solution from a fine multigrid level to + * a coarser multigrid level. + */ + void restrict(int level, int coarseLevel); + + /** \brief + * Prolongates the residual from a coarse multigrid level to a finer + * multigrid level. + */ + void prolongate(int level, int coarseLevel); + + /** \brief + * Computes the residual of a given leve. CoarseLevel parameter will be + * not considered. + */ + void computeResidual(int level, int coarseLevel); + + /** \brief + * Computes the rhs of the coarse level. Level parameter will be not + * considered. + */ + void computeRHS(int level, int coarseLevel); + + /** \brief + * Computes the correction of the coarse level. Level parameter will be + * not considered. + */ + void computeCorrection(int level, int coarseLevel); + + /** \brief + * Add the correction, which has been computed on the coarse grid, to the + * solution of the fine grid. + */ + void fixSolution(int level, int coarseLevel); + + /** \brief + * Returns for a given level the next coarser multigrid level. + */ + int coarserLevel(int level) { + FUNCNAME("MultiGridSolverVec::coarserLevel()"); + TEST_EXIT(level > minLevel_)("invalid level\n"); + do { + --level; + } while(!isMGLevel(level)); + return level; + }; + + /** \brief + * Returns true if the level is a multigrid level, otherwise false. + */ + inline bool isMGLevel(int level) { + return isMGLevel_[level]; + }; + + void initFullMultiGrid(); + + void fmgInterpol(int level); + + inline int mgLevel(int level) { + while(!isMGLevel_[level]) { + ++level; + } + return level; + }; + + protected: + /** \brief + * Defines for all mesh levels, if the level is a multigrid level. + * isMGLevel[0] is the coarsest grid level. + */ + ::std::vector<bool> isMGLevel_; + + /** \brief + * Data of all multigrid levels. + */ + ::std::vector<LevelData> levels_; + + /** \brief + * Sparse vectors containing the residuals. + */ + Vector<SparseVector<double>*> *sparseResidual_; + + /** \brief + * Dense vectors containing the residuals. + */ + SystemVector *denseResidual_; + + /** \brief + * 2-Norm of the last residual. + */ + double lastRes_; + + /** \brief + * Counts the number of multigrid iterations. + */ + int iteration_; + + /** \brief + * Number of smoothing steps on the coarsest level. + */ + int coarseSmoothingSteps_; + + /** \brief + * Is the number of mesh levels that at least are skipped between two + * multigrid levels. + */ + int minLevelGap_; + + /** \brief + * Maximum number of multigrid levels. + */ + int maxMGLevels_; + + /** \brief + * Number of components in the vector problem. + */ + int numComponents_; + + /** \brief + * Smoother + */ + SmootherBase<Matrix<DOFMatrix*>, + Vector<SparseVector<double>*>, + Vector< ::std::set<DegreeOfFreedom>*> > *smoother_; + + /** \brief + * Vector of interpolation matrices for interpolating the residual between + * two meshes. + */ + ::std::vector<InterpolRestrictMatrix*> interpolMatrix_; + + /** \brief + * Vector of restriction matrices for restricting the residual between + * two meshes. + */ + ::std::vector<InterpolRestrictMatrix*> restrictMatrix_; + + /** \brief + * Diagonal entries in the system matrix. + */ + SystemVector *diagEntries_; + + /** \brief + * + */ + bool boxSmoothing_; + + /** \brief + * + */ + Vector< ::std::set<DegreeOfFreedom>*> boxDOFs_; + + /** \brief + * + */ + int galerkin_; + }; + +} + +#endif diff --git a/AMDiS/src/MultiGridSolverBase.h b/AMDiS/src/MultiGridSolverBase.h new file mode 100755 index 0000000000000000000000000000000000000000..e66bc52d49f5f5af2c933cd708ba173b28110f27 --- /dev/null +++ b/AMDiS/src/MultiGridSolverBase.h @@ -0,0 +1,153 @@ +// ============================================================================ +// == == +// == AMDiS - Adaptive multidimensional simulations == +// == == +// ============================================================================ +// == == +// == crystal growth group == +// == == +// == Stiftung caesar == +// == Ludwig-Erhard-Allee 2 == +// == 53175 Bonn == +// == germany == +// == == +// ============================================================================ +// == == +// == http://www.caesar.de/cg/AMDiS == +// == == +// ============================================================================ + +/** \file MultiGridSolverBase.h */ + +#ifndef AMDIS_MULTIGRIDSOLVERBASE_H +#define AMDIS_MULTIGRIDSOLVERBASE_H + +#include <string> + +namespace AMDiS { + + template<typename MatrixType, typename VectorType> + class MultiGridSolverBase + { + public: + /** \brief + * Constructor, reads all multigrid parameters from the init file. + */ + MultiGridSolverBase(const ::std::string &name) ; + + /** \brief + * Destructor + */ + virtual ~MultiGridSolverBase() {}; + + /** \brief + * Abstract function for solving an equation using multigrid method. + * This function does not need to be reimplemented by a derived class. + */ + virtual int solve(MatrixType &a, + VectorType &x, + VectorType &b, + bool initMG = true, + bool exitMG = true); + + /** \brief + * Implements one multigrid iteration. This function does not need to be + * reimplemented by a derived class. + */ + virtual void multiGridIteration(int level); + + virtual bool toleranceReached(double tol) = 0; + + virtual void initMaxLevel() = 0; + + virtual void initMultiGrid(bool createLevels) = 0; + + virtual void exitMultiGrid() = 0; + + virtual void smooth(int level, int steps) = 0; + + virtual void restrict(int level, int coarseLevel) = 0; + + virtual void prolongate(int level, int coarseLevel) = 0; + + virtual void computeResidual(int level, int coarseLevel) = 0; + + virtual void computeRHS(int level, int coarseLevel) = 0; + + virtual void computeCorrection(int level, int coarseLevel) = 0; + + virtual void fixSolution(int level, int coarseLevel) = 0; + + virtual void exactSolve(int level) = 0; + + virtual int coarserLevel(int level) = 0; + + virtual void initFullMultiGrid() {}; + + virtual void fmgInterpol(int level) {}; + + protected: + /** \brief + * Coefficent matrix + */ + MatrixType *systemMatrix_; + + /** \brief + * Vector for the computed solution. + */ + VectorType *solution_; + + /** \brief + * Right hand side of the equation. + */ + VectorType *rhs_; + + /** \brief + * Name of the problem, corresponding to the name in the init file. + */ + ::std::string name_; + + /** \brief + * Tolerance for the computation. The multigrid method finished, if the + * norm of the residual is less than the tolerance. + */ + double tolerance_; + + /** \brief + * Maximum number of multigrid iterations. + */ + int maxIterations_; + + /** \brief + * The coarsest multigrid level. + */ + int minLevel_; + + /** \brief + * The finest multigrid level. + */ + int maxLevel_; + + int numCycles_; + + /** \brief + * Number of smoothing steps on the solution before the recursive multigrid call. + */ + int preSmoothingSteps_; + + /** \brief + * Number of smoothing steps on the solution after the recursive multigrid call. + */ + int postSmoothingSteps_; + + /** \brief + * If the method of full multigrid should be used, this variable has a non + * zero value. + */ + int fmg_; + }; + +} + +#include "MultiGridSolverBase.hh" +#endif diff --git a/AMDiS/src/MultiGridSolverBase.hh b/AMDiS/src/MultiGridSolverBase.hh new file mode 100644 index 0000000000000000000000000000000000000000..c5f689c4f40c79767237fa3f6b17e5f19108b6c2 --- /dev/null +++ b/AMDiS/src/MultiGridSolverBase.hh @@ -0,0 +1,108 @@ +#include "Global.h" +#include "Parameters.h" + +namespace AMDiS { + + template<typename MatrixType, typename VectorType> + MultiGridSolverBase<MatrixType, VectorType>::MultiGridSolverBase(const ::std::string &name) + : name_(name), + tolerance_(1e-8), + maxIterations_(100), + minLevel_(0), + maxLevel_(-1), + numCycles_(1), + preSmoothingSteps_(1), + postSmoothingSteps_(1), + fmg_(0) + { + GET_PARAMETER(0, name_ + "->tolerance", "%e", &tolerance_); + GET_PARAMETER(0, name_ + "->max iteration", "%d", &maxIterations_); + GET_PARAMETER(0, name_ + "->mg cycle type", "%d", &numCycles_); + GET_PARAMETER(0, name_ + "->pre smoothing steps", "%d", &preSmoothingSteps_); + GET_PARAMETER(0, name_ + "->post smoothing steps", "%d", &postSmoothingSteps_); + GET_PARAMETER(0, name_ + "->min level", "%d", &minLevel_); + GET_PARAMETER(0, name_ + "->full mg", "%d", &fmg_); + } + + template<typename MatrixType, typename VectorType> + int MultiGridSolverBase<MatrixType, VectorType>::solve(MatrixType &a, + VectorType &x, + VectorType &b, + bool initMG, + bool exitMG) + { + int i = 0; + systemMatrix_ = &a; + solution_ = &x; + rhs_ = &b; + + initMaxLevel(); + if (minLevel_ > maxLevel_) + minLevel_ = maxLevel_; + + initMultiGrid(initMG); + + if (fmg_) { + initFullMultiGrid(); + for (int i = 1; i < maxLevel_ + 1; i++) { + fmgInterpol(i); + multiGridIteration(i); + } + } + + for (int i = 0; i < maxIterations_; i++) { + if (toleranceReached(tolerance_)) + break; + multiGridIteration(maxLevel_); + } + + if (exitMG) { + exitMultiGrid(); + } + + return i + 1; + } + + template<typename MatrixType, typename VectorType> + void MultiGridSolverBase<MatrixType, VectorType>::multiGridIteration(int level) + { + if (level <= minLevel_) { + // If we are on the coarsest possible grid, use exact solver. + exactSolve(minLevel_); + } else { + // Get the next coarser level. + int coarseLevel = coarserLevel(level); + + // Smooth the solution on the fine grid. + smooth(level, preSmoothingSteps_); + + // Compute the residual on the fine grid. + computeResidual(level, coarseLevel); + + // Restrict the residual to the coarser grid. + restrict(level, coarseLevel); + + // Compute defect equation on the coarser grid. + computeRHS(level, coarseLevel); + + // Apply multigrid on the coarser grid. + for (int i = 0; i < numCycles_; i++) { + multiGridIteration(coarseLevel); + } + + // Compute correction of the solution. + computeCorrection(level, coarseLevel); + + // Prolongate the solution to the finer grid. + prolongate(level, coarseLevel); + + // Add the correction, computed on the coarse grid, to the solution + // on the fine grid. + fixSolution(level, coarseLevel); + + // Apply smoothing on the solution on the fine grid. + smooth(level, postSmoothingSteps_); + } + } + +} diff --git a/AMDiS/src/MultiGridWrapper.h b/AMDiS/src/MultiGridWrapper.h new file mode 100644 index 0000000000000000000000000000000000000000..0ec90f4c7d2a738d91b21c64157e16feaf9900f1 --- /dev/null +++ b/AMDiS/src/MultiGridWrapper.h @@ -0,0 +1,144 @@ +// ============================================================================ +// == == +// == AMDiS - Adaptive multidimensional simulations == +// == == +// ============================================================================ +// == == +// == crystal growth group == +// == == +// == Stiftung caesar == +// == Ludwig-Erhard-Allee 2 == +// == 53175 Bonn == +// == germany == +// == == +// ============================================================================ +// == == +// == http://www.caesar.de/cg/AMDiS == +// == == +// ============================================================================ + +/** \file MultiGridWrapper.h */ + +#ifndef AMDIS_MULTIGRIDWRAPPER_H +#define AMDIS_MULTIGRIDWRAPPER_H + +#include "MultiGridSolver.h" +#include "MatVecMultiplier.h" +#include "OEMSolver.h" +#include "MemoryManager.h" + +namespace AMDiS { + + /** \brief + * Wrapper to make the multigrid solver accessible as a normal scal solver. + */ + class MultiGridWrapperScal : public OEMSolver<DOFVector<double> > + { + public: + MEMORY_MANAGED(MultiGridWrapperScal); + + /** \brief + * Creator class used in the OEMSolverMap. + */ + class Creator : public OEMSolverCreator<DOFVector<double> > + { + public: + MEMORY_MANAGED(Creator); + + virtual ~Creator() {}; + + /** \brief + * Returns a new object. + */ + OEMSolver<DOFVector<double> >* create() { + return + NEW MultiGridWrapperScal(name); + }; + }; + + MultiGridWrapperScal(::std::string name) + : OEMSolver<DOFVector<double> >(name) + { + mgSolver_ = + NEW MultiGridSolverScal(name); + }; + + ~MultiGridWrapperScal() { + DELETE mgSolver_; + }; + + void init() {}; + + void exit() {}; + + int solveSystem(MatVecMultiplier<DOFVector<double> > *mv, + DOFVector<double> *x, + DOFVector<double> *b) + { + DOFMatrix *matrix = + dynamic_cast<StandardMatVec<DOFMatrix, DOFVector<double> >*>(mv)->getMatrix(); + return mgSolver_->solve(*matrix, *x, *b); + }; + + protected: + MultiGridSolverBase<DOFMatrix, DOFVector<double> > *mgSolver_; + }; + + + /** \brief + * Wrapper to make the multigrid solver accessible as a normal vector solver. + */ + class MultiGridWrapperVec : public OEMSolver<SystemVector> + { + public: + MEMORY_MANAGED(MultiGridWrapperVec); + + /** \brief + * Creator class used in the OEMSolverMap. + */ + class Creator : public OEMSolverCreator<SystemVector> + { + public: + MEMORY_MANAGED(Creator); + + virtual ~Creator() {}; + + /** \brief + * Returns a new object. + */ + OEMSolver<SystemVector>* create() { + return NEW MultiGridWrapperVec(name); + }; + }; + + MultiGridWrapperVec(::std::string name) + : OEMSolver<SystemVector>(name) + { + mgSolver_ = + NEW MultiGridSolverVec(name); + }; + + ~MultiGridWrapperVec() { + DELETE mgSolver_; + }; + + void init() {}; + + void exit() {}; + + int solveSystem(MatVecMultiplier<SystemVector> *mv, + SystemVector *x, + SystemVector *b) + { + Matrix<DOFMatrix*> *matrix = + dynamic_cast<StandardMatVec<Matrix<DOFMatrix*>, SystemVector>*>(mv)->getMatrix(); + return mgSolver_->solve(*matrix, *x, *b); + }; + + protected: + MultiGridSolverBase<Matrix<DOFMatrix*>, SystemVector> *mgSolver_; + }; + +} + +#endif diff --git a/AMDiS/src/NEWS b/AMDiS/src/NEWS new file mode 100644 index 0000000000000000000000000000000000000000..e69de29bb2d1d6434b8b29ae775ad8c2e48c5391 diff --git a/AMDiS/src/Newton.h b/AMDiS/src/Newton.h new file mode 100644 index 0000000000000000000000000000000000000000..4fa55eb674049396485d51d5e64997cf75d9e5a5 --- /dev/null +++ b/AMDiS/src/Newton.h @@ -0,0 +1,109 @@ +// ============================================================================ +// == == +// == AMDiS - Adaptive multidimensional simulations == +// == == +// ============================================================================ +// == == +// == crystal growth group == +// == == +// == Stiftung caesar == +// == Ludwig-Erhard-Allee 2 == +// == 53175 Bonn == +// == germany == +// == == +// ============================================================================ +// == == +// == http://www.caesar.de/cg/AMDiS == +// == == +// ============================================================================ + +/** \file Newton.h */ + +#ifndef AMDIS_NEWTON_H +#define AMDIS_NEWTON_H + +#include "MemoryManager.h" +#include "CreatorInterface.h" +#include "NonLinSolver.h" + +namespace AMDiS { + + class FiniteElemSpace; + + template<typename VectorType> class OEMSolver; + + // ============================================================================ + // ===== class Newton ========================================================= + // ============================================================================ + + /** + * \ingroup Solver + * + * \brief + * Implements the newton method for solving a non linear system. Sub class of + * NonLinSolver. + */ + template<typename VectorType> + class Newton : public NonLinSolver<VectorType> + { + public: + MEMORY_MANAGED(Newton<VectorType>); + + /** \brief + * Creator class used in the NonLinSolverMap. + */ + class Creator : public NonLinSolverCreator<VectorType> + { + public: + MEMORY_MANAGED(Creator); + + virtual ~Creator() {}; + + /** \brief + * Returns a new Newton object. + */ + NonLinSolver<VectorType>* create() { + return NEW Newton(this->name, this->linearSolver, this->nonLinUpdater); + }; + }; + + /** \brief + * Calls constructor of base class NonLinSolver + */ + Newton(const ::std::string& name_, + OEMSolver<VectorType> *linSolver_, + NonLinUpdater<VectorType> *updater) + : NonLinSolver<VectorType>(name_, linSolver_, updater) + {}; + + private: + /** \brief + * realisation of NonLinSolver::init + */ + void init(); + + /** \brief + * realisation of NonLinSolver::nlsolve + */ + int nlsolve(MatVecMultiplier<VectorType> *matVec, + VectorType *x, VectorType *rhs, + Preconditioner<VectorType> *lPrecon = NULL, + Preconditioner<VectorType> *rPrecon = NULL); + + /** \brief + * realisation of NonLinSolver::exit + */ + void exit(); + + private: + /** \brief + * internal used data + */ + VectorType *b; + }; + +} + +#include "Newton.hh" + +#endif // AMDIS_NEWTON_H diff --git a/AMDiS/src/Newton.hh b/AMDiS/src/Newton.hh new file mode 100644 index 0000000000000000000000000000000000000000..b3aefe774388fc1f0be67411fe22eb80d5ec21b8 --- /dev/null +++ b/AMDiS/src/Newton.hh @@ -0,0 +1,91 @@ +#include "OEMSolver.h" +#include "NonLinUpdater.h" + +namespace AMDiS { + + template<typename VectorType> + void Newton<VectorType>::init() + { + TEST_EXIT(this->vectorCreator)("no vectorCreator\n"); + b = this->vectorCreator->create(); + } + + template<typename VectorType> + void Newton<VectorType>::exit() + { + if(b) this->vectorCreator->free(b); + } + + template<typename VectorType> + int Newton<VectorType>::nlsolve(MatVecMultiplier<VectorType> *matVec, + VectorType *x, VectorType *d, + Preconditioner<VectorType> *lPrecon, + Preconditioner<VectorType> *rPrecon) + { + FUNCNAME("Newton::nlsolve"); + + //DOFVector<T> *d = problem->getRHS(); + //DOFVector<T> *x = problem->getSolution();; + + *b = *d; + + // // copy operators from fh to b + // ::std::vector<Operator*>::iterator op; + // ::std::vector<double*>::iterator fac; + // for(op = d->getOperatorsBegin(), + // fac = d->getOperatorFactorBegin(); + // op != d->getOperatorsEnd(); + // ++op, ++fac) + // { + // b->addOperator(*op, *fac); + // } + + double err = 0.0, err_old = -1.0; + int iter, n; + + INFO(this->info,2)("iter. | this->residual | red. | n |\n"); + + for (iter = 1; iter <= this->maxIter; iter++) + { + /*--- Assemble DF(x) and F(x) ----------------------------------------------*/ + this->nonLinUpdater->update(/*x,*/true, b); + /*--- Initial guess is zero ------------------------------------------------*/ + d->set(0.0); + /*--- solve linear system --------------------------------------------------*/ + n = solveLinearSystem(matVec, b, d, lPrecon, rPrecon); + /*--- x = x - d ------------------------------------------------------------*/ + *x -= *d; + + if(this->usedNorm == NO_NORM || this->usedNorm == L2_NORM) + err = L2Norm(d); // sollte hier nicht b genommen werden (s. NewtonS) ? + else + err = H1Norm(d); // sollte hier nicht b genommen werden (s. NewtonS) ? + + + if (iter == 1) this->initial_residual = err; + + if (err_old <= 0) { + INFO(this->info,2)("%5d | %12.5e | -------- | %4d |\n", iter, err, n); + } else { + INFO(this->info,2)("%5d | %12.5e | %8.2e | %4d |\n", + iter, err, err/err_old, n); + } + + if ((this->residual = err) < this->tolerance) + { + INFO(this->info,4)("finished successfully\n"); + return(iter); + } + err_old = err; + } + + if (this->info < 2) + INFO(this->info,1)("iter. %d, residual: %12.5e\n", iter, err); + INFO(this->info,1)("tolerance %e not reached\n", this->tolerance); + + this->residual = err; + + return(iter); + } + +} diff --git a/AMDiS/src/NewtonS.h b/AMDiS/src/NewtonS.h new file mode 100644 index 0000000000000000000000000000000000000000..d372a07b0985f2886b42817868df7e57e2a0b441 --- /dev/null +++ b/AMDiS/src/NewtonS.h @@ -0,0 +1,109 @@ +// ============================================================================ +// == == +// == AMDiS - Adaptive multidimensional simulations == +// == == +// ============================================================================ +// == == +// == crystal growth group == +// == == +// == Stiftung caesar == +// == Ludwig-Erhard-Allee 2 == +// == 53175 Bonn == +// == germany == +// == == +// ============================================================================ +// == == +// == http://www.caesar.de/cg/AMDiS == +// == == +// ============================================================================ + +/** \file NewtonS.h */ + +#ifndef AMDIS_NEWTONS_H +#define AMDIS_NEWTONS_H + +#include "MemoryManager.h" +#include "CreatorInterface.h" + +namespace AMDiS { + + // ============================================================================ + // ===== class NewtonS ======================================================== + // ============================================================================ + + /** + * \ingroup Solver + * + * \brief + * Implements the newton method with step size control for solving a non linear + * system. Sub class of NonLinSolver. + */ + template<typename VectorType> + class NewtonS : public NonLinSolver<VectorType> + { + public: + MEMORY_MANAGED(NewtonS<VectorType>); + + /** \brief + * Creator class used in the NonLinSolverMap. + */ + class Creator : public NonLinSolverCreator<VectorType> + { + public: + MEMORY_MANAGED(Creator); + + virtual ~Creator() {}; + + /** \brief + * Returns a new NewtonS object. + */ + NonLinSolver<VectorType>* create() { + return NEW NewtonS(this->name, this->linearSolver, this->nonLinUpdater); + }; + }; + + /** \brief + * Calls constructor of base class NonLinSolver + */ + NewtonS(const ::std::string& name_, + OEMSolver<VectorType> *linSolver_, + NonLinUpdater<VectorType> *updater) + : NonLinSolver<VectorType>(name_, linSolver_, updater), + b(NULL), + y(NULL), + restart(0) + { + GET_PARAMETER(0, this->name + "->restart", "%d", &restart); + TEST_EXIT(restart)("restart not set!\n"); + }; + + private: + /** \brief + * realisation of NonLinSolver::init + */ + void init(); + + /** \brief + * realisation of NonLinSolver::nlsolve + */ + int nlsolve(MatVecMultiplier<VectorType> *matVec, + VectorType *x, VectorType *rhs, + Preconditioner<VectorType> *lPrecon = NULL, + Preconditioner<VectorType> *rPrecon = NULL); + + /** \brief + * realisation of NonLinSolver::exit + */ + void exit(); + + private: + VectorType *b; /**< \brief internal used data */ + VectorType *y; /**< \brief internal used data */ + int restart; /**< \brief internal used data */ + }; + +} + +#include "NewtonS.hh" + +#endif // AMDIS_NEWTONS_H diff --git a/AMDiS/src/NewtonS.hh b/AMDiS/src/NewtonS.hh new file mode 100644 index 0000000000000000000000000000000000000000..f5a92fcfad872496db3155909290c5ea9cb396f1 --- /dev/null +++ b/AMDiS/src/NewtonS.hh @@ -0,0 +1,155 @@ +#include "NonLinUpdater.h" +#include <algorithm> + +namespace AMDiS { + + template<typename VectorType> + void NewtonS<VectorType>::init() + { + TEST_EXIT(this->vectorCreator)("no vectorCreator\n"); + b = this->vectorCreator->create(); + y = this->vectorCreator->create(); + } + + template<typename VectorType> + void NewtonS<VectorType>::exit() + { + if(b) this->vectorCreator->free(b); + if(y) this->vectorCreator->free(y); + } + + template<typename VectorType> + int NewtonS<VectorType>::nlsolve(MatVecMultiplier<VectorType> *matVec, + VectorType *x, VectorType *rhs, + Preconditioner<VectorType> *lPrecon, + Preconditioner<VectorType> *rPrecon) + { + FUNCNAME("NewtonS::nlsolve"); + + *b = *rhs; + + // // copy operators from fh to b + // ::std::vector<Operator*>::iterator op; + // ::std::vector<double*>::iterator fac; + // for(op = rhs->getOperatorsBegin(), + // fac = rhs->getOperatorFactorBegin(); + // op != rhs->getOperatorsEnd(); + // ++op, ++fac) + // { + // b->addOperator(*op, *fac); + // } + + double err, err_old, tau; + int iter, j, n, m, mmax, halved; + + /*--------------------------------------------------------------------------*/ + /*--- Newton initialization ------------------------------------------------*/ + /*--------------------------------------------------------------------------*/ + + this->nonLinUpdater->update(/*x, */false, b); /*-- update F(x) ------------*/ + + if(this->usedNorm == NO_NORM || this->usedNorm == L2_NORM) { + err = err_old = L2Norm(b); + } else { + err = err_old = H1Norm(b); + } + + this->initial_residual = err; + + INFO(this->info,2)("iter. | residual | red. | n | m |\n"); + INFO(this->info,2)("%5d | %12.5e | -------- | ---- | -- |\n", 0, err); + + if ((this->residual = err) < this->tolerance) + { + INFO(this->info,4)("finished succesfully\n"); + return(0); + } + + /*--- still initalization part ---------------------------------------------*/ + + mmax = ::std::max(2,::std::min(restart,32)); + m = 0; + tau = 1.0; + halved = true; + + + /*--- start iterations -----------------------------------------------------*/ + + for (iter = 1; iter <= this->maxIter; iter++) + { + /*--- Assemble DF(x) -------------------------------------------------------*/ + this->nonLinUpdater->update(/*x, */true, NULL); + /*--- Initial guess is zero ------------------------------------------------*/ + *rhs = 0.0; + /*--- solve linear system --------------------------------------------------*/ + n = solveLinearSystem(matVec, b, rhs, lPrecon, rPrecon); + + /*--- look for step size ---------------------------------------------------*/ + if (!halved) { + m = ::std::max(m-1,0); + tau = tau < 0.5 ? 2.0*tau : 1.0; + } + + // remember original x + *y = *x; + + for (j = 0; j <= mmax; j++) { + /*--- aim: |F(u_k+\tau d)| \le (1-0.5\tau) |F(u)| --------------------------*/ + /*-- y = x ------------------------*/ + //*y = *x; + *x = *y; + + /*-- y -= tau*rhs -------------------*/ + // axpy(-tau, *rhs, *y); + axpy(-tau, *rhs, *x); + + /*-- update F(y) ------------------*/ + // nonLinUpdater->update(y, false, b); + this->nonLinUpdater->update(/*x, */false, b); + + if(this->usedNorm == NO_NORM || this->usedNorm == L2_NORM) { + err = L2Norm(b); + } else { + err = H1Norm(b); + } + + + if (err <= (1.0 - 0.5*tau)*err_old) { + halved = j > 0; + break; + } else { + if (m == mmax) break; + + m++; + tau *= 0.5; + } + } + + //*x = *y; /*-- x = y (update x!) ------------*/ + + if (err_old <= 0) { + INFO(this->info,2)("%5d | %12.5e | -------- | %4d | %2d |\n", + iter, err, n, m); + } else { + INFO(this->info,2)("%5d | %12.5e | %8.2e | %4d | %2d |\n", + iter, err, err/err_old, n, m); + } + + if ((this->residual = err) < this->tolerance && m == 0) + { + INFO(this->info,4)("finished successfully\n"); + return(iter); + } + else if (iter > this->maxIter) + { + if (this->info < 2) + INFO(this->info,1)("iter. %d, residual: %12.5e\n", iter, err); + INFO(this->info,1)("tolerance %e not reached\n", this->tolerance); + return(iter); + } + err_old = err; + } + return(iter); /*--- statement never reached -----------------------------*/ + } + +} diff --git a/AMDiS/src/NonLinSolver.h b/AMDiS/src/NonLinSolver.h new file mode 100644 index 0000000000000000000000000000000000000000..9067b3afd6b445026836bf0fa098b4fc16047830 --- /dev/null +++ b/AMDiS/src/NonLinSolver.h @@ -0,0 +1,178 @@ +// ============================================================================ +// == == +// == AMDiS - Adaptive multidimensional simulations == +// == == +// ============================================================================ +// == == +// == crystal growth group == +// == == +// == Stiftung caesar == +// == Ludwig-Erhard-Allee 2 == +// == 53175 Bonn == +// == germany == +// == == +// ============================================================================ +// == == +// == http://www.caesar.de/cg/AMDiS == +// == == +// ============================================================================ + +/** \file NonLinSolver.h */ + +#ifndef AMDIS_NONLINSOLVER_H +#define AMDIS_NONLINSOLVER_H + +#include <string> + +#include "Global.h" +#include "CreatorInterface.h" + +namespace AMDiS { + + template<typename VectorType> class OEMSolver; + template<typename VectorType> class NonLinUpdater; + + // ============================================================================ + // ===== class NonLinSolver =================================================== + // ============================================================================ + + /** + * \ingroup Solver + * + * \brief + * Pure virtual base class for Newton, NewtonS and Banach which all + * solves non linear equation systems. Sub classes must implement the methods + * \ref init, \ref exit and \ref nlsolve. + */ + template<typename VectorType> + class NonLinSolver + { + public: + /** \brief + * constructor. + * \param name name of this solver + */ + NonLinSolver(const ::std::string &name_, + OEMSolver<VectorType> *linSolver_, + NonLinUpdater<VectorType> *updater); + + /** \brief + * destructor + */ + virtual ~NonLinSolver() {}; + + /** \brief + * solves the non linear system. Uses sub class methods + */ + inline int solve(MatVecMultiplier<VectorType> *matVec, + VectorType *x, VectorType *rhs, + Preconditioner<VectorType> *lPrecon = NULL, + Preconditioner<VectorType> *rPrecon = NULL) + { + TEST_EXIT(vectorCreator)("no vectorCreator\n"); + init(); + int result = nlsolve(matVec, x, rhs, lPrecon, rPrecon); + exit(); + return result; + }; + + inline void setTolerance(double tol) { + tolerance = tol; + }; + + inline double getTolerance() { + return tolerance; + }; + + inline void setVectorCreator(CreatorInterface<VectorType> *creator) { + vectorCreator = creator; + }; + + inline OEMSolver<VectorType> *getLinearSolver() { return linSolver; }; + + inline void setNonLinUpdater(NonLinUpdater<VectorType> *up) { + nonLinUpdater = up; + }; + + inline NonLinUpdater<VectorType> *getNonLinUpdater() { + return nonLinUpdater; + }; + + protected: + /** \brief + * Allocates needed memory. Must be overriden in sub classes. + */ + virtual void init() = 0; + + /** \brief + * Solves the non linear system. Must be overriden in sub classes. + */ + virtual int nlsolve(MatVecMultiplier<VectorType> *matVec, + VectorType *x, VectorType *rhs, + Preconditioner<VectorType> *lPrecon = NULL, + Preconditioner<VectorType> *rPrecon = NULL) = 0; + + /** \brief + * Frees needed memory. Must be overriden in sub classes. + */ + virtual void exit() = 0; + + virtual int solveLinearSystem(MatVecMultiplier<VectorType> *matVec, + VectorType *fh, VectorType *x, + Preconditioner<VectorType> *lPrecon = NULL, + Preconditioner<VectorType> *rPrecon = NULL) + { + FUNCNAME("NonLinSolver::solveLinearSystem()"); + TEST_EXIT(linSolver)("no solver\n"); + return linSolver->solve(matVec, x, fh, lPrecon, rPrecon); + }; + + protected: + ::std::string name; /**< \brief name of the solver */ + OEMSolver<VectorType> *linSolver; /**< \brief linear solver*/ + NonLinUpdater<VectorType> *nonLinUpdater; /**< \brief non linear updater */ + double tolerance; /**< \brief solver tolerance */ + int maxIter; /**< \brief maximal # of iterations */ + int info; /**< \brief info level */ + double initial_residual; /**< \brief initial residual */ + double residual; /**< \brief current residual */ + Norm usedNorm; /**< \brief used norm */ + + CreatorInterface<VectorType> *vectorCreator; + }; + + // ============================================================================ + // ===== class NonLinSolverCreator ============================================ + // ============================================================================ + + /** \brief + * Interface for creators of concrete NonLinSolvers. + */ + template<typename VectorType> + class NonLinSolverCreator : public CreatorInterface<NonLinSolver<VectorType> > + { + public: + virtual ~NonLinSolverCreator() {}; + + void setName(::std::string name_) { name = name_; }; + + void setLinearSolver(OEMSolver<VectorType> *solver) { linearSolver = solver; }; + + void setNonLinUpdater(NonLinUpdater<VectorType> *updater) { + nonLinUpdater = updater; + }; + + protected: + ::std::string name; + OEMSolver<VectorType> *linearSolver; + NonLinUpdater<VectorType> *nonLinUpdater; + }; + +} + +#include "NonLinSolver.hh" + +#include "Newton.h" +#include "NewtonS.h" +#endif // AMDIS_NONLINSOLVER_H + diff --git a/AMDiS/src/NonLinSolver.hh b/AMDiS/src/NonLinSolver.hh new file mode 100644 index 0000000000000000000000000000000000000000..8de93480059e9d4d01f5028b71a449189d032665 --- /dev/null +++ b/AMDiS/src/NonLinSolver.hh @@ -0,0 +1,27 @@ +#include "OEMSolver.h" +#include "Parameters.h" + +namespace AMDiS { + + template<typename VectorType> + NonLinSolver<VectorType>::NonLinSolver(const ::std::string& name_, + OEMSolver<VectorType> *solver, + NonLinUpdater<VectorType> *updater) + : name(name_), + linSolver(solver), + nonLinUpdater(updater), + tolerance(1.e-4), + maxIter(50), + info(8), + initial_residual(0.0), + residual(0.0), + usedNorm(NO_NORM), + vectorCreator(NULL) + { + GET_PARAMETER(0, name + "->tolerance", "%e", &tolerance); + GET_PARAMETER(0, name + "->max iteration", "%d", &maxIter); + GET_PARAMETER(0, name + "->info", "%d", &info); + GET_PARAMETER(0, name + "->norm", "%d", &usedNorm); + } + +} diff --git a/AMDiS/src/NonLinUpdater.cc b/AMDiS/src/NonLinUpdater.cc new file mode 100644 index 0000000000000000000000000000000000000000..e83a2fbb7f426af1fbe85d750ca71156810c2ec9 --- /dev/null +++ b/AMDiS/src/NonLinUpdater.cc @@ -0,0 +1,133 @@ +#include "NonLinUpdater.h" +#include "Global.h" +#include "DOFMatrix.h" +#include "DOFVector.h" +#include "Traverse.h" +#include "ElInfo.h" +#include "Flag.h" +#include "Operator.h" +#include "FiniteElemSpace.h" +#include "BasisFunction.h" +#include "BoundaryManager.h" + +namespace AMDiS { + + void NonLinUpdaterScal::update(bool updateDF, + DOFVector<double> *F) + { + FUNCNAME("NonLinUpdaterScal::update()"); + + TraverseStack stack; + ElInfo *el_info; + Flag fill_flag; + + TEST_EXIT(F || df)("neither F nor df are set\n"); + + const FiniteElemSpace *feSpace = + F ? F->getFESpace() : df->getFESpace(); + + if (updateDF) { + df->clear(); + } + + BasisFunction *basFcts = const_cast<BasisFunction*>(feSpace->getBasisFcts()); + + if (F) { + F->set(0.0); + } + + fill_flag = + Mesh::CALL_LEAF_EL| + Mesh::FILL_COORDS| + Mesh::FILL_BOUND| + Mesh::FILL_DET| + Mesh::FILL_GRD_LAMBDA; + + el_info = stack.traverseFirst(feSpace->getMesh(), -1, fill_flag); + while (el_info) { + const BoundaryType *bound = basFcts->getBound(el_info, NULL); + if (updateDF) { + df->assemble(1.0, el_info, bound); + } + + if (F) { + F->assemble(1.0, el_info, bound); + } + + el_info = stack.traverseNext(el_info); + } + } + + void NonLinUpdaterVec::update(bool updateDF, + SystemVector *F) + { + FUNCNAME("NonLinUpdaterVec::update()"); + + int i, j, size = df->getNumRows(); + + TraverseStack stack; + ElInfo *el_info; + Flag fill_flag; + + TEST_EXIT(F || df)("neither F nor df are set\n"); + + if ((!updateDF) && (F==NULL)) { + WARNING("No RHS vector and no update for system matrix! Updater does nothing!\n"); + return; + } + + const FiniteElemSpace *feSpace = + F ? + F->getDOFVector(0)->getFESpace() : + (*df)[0][0]->getFESpace(); + + if (updateDF) { + TEST_EXIT(df)("df not set but update tried!\n"); + for(i = 0; i < size; i++) { + for(j = 0; j < size; j++) { + if((*df)[i][j]) { + (*df)[i][j]->clear(); + } + } + } + } + + BasisFunction *basFcts = const_cast<BasisFunction*>(feSpace->getBasisFcts()); + + if (F) { + for(i = 0; i < size; i++) { + F->getDOFVector(i)->set(0.0); + } + } + + fill_flag = + Mesh::CALL_LEAF_EL| + Mesh::FILL_COORDS| + Mesh::FILL_BOUND| + Mesh::FILL_DET| + Mesh::FILL_GRD_LAMBDA; + + el_info = stack.traverseFirst(feSpace->getMesh(), -1, fill_flag); + while (el_info) { + const BoundaryType *bound = basFcts->getBound(el_info, NULL); + if (updateDF) { + for(i = 0; i < size; i++) { + for(j = 0; j < size; j++) { + if((*df)[i][j]) { + (*df)[i][j]->assemble(1.0, el_info, bound); + } + } + } + } + + if (F) { + for(i = 0; i < size; i++) { + F->getDOFVector(i)->assemble(1.0, el_info, bound); + } + } + + el_info = stack.traverseNext(el_info); + } + }; + +} diff --git a/AMDiS/src/NonLinUpdater.h b/AMDiS/src/NonLinUpdater.h new file mode 100644 index 0000000000000000000000000000000000000000..bffe7026bc625ca25b0ecc1f112a6f3d1dcdd7f6 --- /dev/null +++ b/AMDiS/src/NonLinUpdater.h @@ -0,0 +1,121 @@ +// ============================================================================ +// == == +// == AMDiS - Adaptive multidimensional simulations == +// == == +// ============================================================================ +// == == +// == crystal growth group == +// == == +// == Stiftung caesar == +// == Ludwig-Erhard-Allee 2 == +// == 53175 Bonn == +// == germany == +// == == +// ============================================================================ +// == == +// == http://www.caesar.de/cg/AMDiS == +// == == +// ============================================================================ + +/** \file NonLinUpdater.h */ + +#ifndef AMDIS_NONLINAPDATOR_H +#define AMDIS_NONLINAPDATOR_H + +#include "MemoryManager.h" +#include "SystemVector.h" +#include "MatrixVector.h" + +namespace AMDiS { + + class DOFMatrix; + template<typename T> class DOFVector; + + // ========================================================================= + // ===== class NonLinUpdater =============================================== + // ========================================================================= + + /** \brief + * Used in non linear solvers for matrix and vector assemblage. + * Base class for NonLinUpdaterScal and NonLinUpdaterVec. + */ + template<typename Vector> + class NonLinUpdater + { + public: + virtual ~NonLinUpdater() {}; + + /** \brief + * Pure virtual update function. + */ + virtual void update(bool updateDF, + Vector *F) = 0; + }; + + // ========================================================================= + // ===== class NonLinUpdaterScal =========================================== + // ========================================================================= + + /** \brief + * NonLinUpdater for scalar problems. + */ + class NonLinUpdaterScal : public NonLinUpdater<DOFVector<double> > + { + public: + MEMORY_MANAGED(NonLinUpdaterScal); + + /** \brief + * Constructor. + */ + NonLinUpdaterScal(DOFMatrix *m) : df(m) {}; + + virtual ~NonLinUpdaterScal() {}; + + /** \brief + * Implementation of NonLinUpdater::update(). + */ + virtual void update(bool updateDF, + DOFVector<double> *F); + + protected: + /** \brief + * Matrix to be updated. + */ + DOFMatrix *df; + }; + + // ========================================================================= + // ===== class NonLinUpdaterVec ============================================ + // ========================================================================= + + /** \brief + * NonLinUpdater for vector valued problems. + */ + class NonLinUpdaterVec : public NonLinUpdater<SystemVector> + { + public: + MEMORY_MANAGED(NonLinUpdaterVec); + + /** \brief + * Constructor. + */ + NonLinUpdaterVec(Matrix<DOFMatrix*> *m) : df(m) {}; + + virtual ~NonLinUpdaterVec() {}; + + /** \brief + * Implementation of NonLinUpdater::update(). + */ + virtual void update(bool updateDF, + SystemVector *F); + + protected: + /** \brief + * Matrix to be updated. + */ + Matrix<DOFMatrix*> *df; + }; + +} + +#endif diff --git a/AMDiS/src/ODirSolver.h b/AMDiS/src/ODirSolver.h new file mode 100644 index 0000000000000000000000000000000000000000..602e9b97f0a97829a38f8e456b7a618ffd46e358 --- /dev/null +++ b/AMDiS/src/ODirSolver.h @@ -0,0 +1,100 @@ +// ============================================================================ +// == == +// == AMDiS - Adaptive multidimensional simulations == +// == == +// ============================================================================ +// == == +// == crystal growth group == +// == == +// == Stiftung caesar == +// == Ludwig-Erhard-Allee 2 == +// == 53175 Bonn == +// == germany == +// == == +// ============================================================================ +// == == +// == http://www.caesar.de/cg/AMDiS == +// == == +// ============================================================================ + +/** \file ODirSolver.h */ + +#ifndef AMDIS_ODIRSOLVER_H +#define AMDIS_ODIRSOLVER_H + +#include "OEMSolver.h" +#include "MemoryManager.h" + +namespace AMDiS { + + // ============================================================================ + // ===== class BiCGSolver ===================================================== + // ============================================================================ + + /** + * \ingroup Solver + * + * \brief + * Solves a linear system by the method of orthogonal directions and can be + * used for symmetric positive system matrices. + */ + template<typename VectorType> + class ODirSolver : public OEMSolver<VectorType> + { + public: + MEMORY_MANAGED(ODirSolver<VectorType>); + + /** \brief + * Creator class used in the OEMSolverMap. + */ + class Creator : public OEMSolverCreator<VectorType> + { + public: + MEMORY_MANAGED(Creator); + + virtual ~Creator() {}; + + /** \brief + * Returns a new ODirSolver object. + */ + OEMSolver<VectorType>* create() { + return NEW ODirSolver<VectorType>(this->name); + }; + }; + + /** \brief + * constructor + */ + ODirSolver(::std::string name); + + /** \brief + * destructor + */ + ~ODirSolver(); + + protected: + /** \brief + * realisation of OEMSolver::solveSystem + */ + int solveSystem(MatVecMultiplier<VectorType> *mv, VectorType *x, VectorType *b); + + /** \brief + * realisation of OEMSolver::init + */ + void init(); + + /** \brief + * realisation of OEMSolver::exit + */ + void exit(); + + private: + // pointer to memory needed for solveSystem + VectorType *Ad, *d, *d_old, *r, *h; + }; + +} + +#include "ODirSolver.hh" + +#endif // AMDIS_ODIR_SOLVER_H diff --git a/AMDiS/src/ODirSolver.hh b/AMDiS/src/ODirSolver.hh new file mode 100644 index 0000000000000000000000000000000000000000..044605058084963d2add50d24624d08e251dc962 --- /dev/null +++ b/AMDiS/src/ODirSolver.hh @@ -0,0 +1,167 @@ +#include "Preconditioner.h" + +namespace AMDiS { + + template<typename VectorType> + ODirSolver<VectorType>::ODirSolver(::std::string name) + : OEMSolver<VectorType>(name), + Ad(NULL), d(NULL), d_old(NULL), r(NULL), h(NULL) + { + } + + template<typename VectorType> + ODirSolver<VectorType>::~ODirSolver() + {} + + template<typename VectorType> + void ODirSolver<VectorType>::init() + { + Ad = this->vectorCreator->create(); + d = this->vectorCreator->create(); + d_old = this->vectorCreator->create(); + r = this->vectorCreator->create(); + h = this->vectorCreator->create(); + } + + template<typename VectorType> + void ODirSolver<VectorType>::exit() + { + this->vectorCreator->free(Ad); + this->vectorCreator->free(d); + this->vectorCreator->free(d_old); + this->vectorCreator->free(r); + this->vectorCreator->free(h); + } + + template<typename VectorType> + int ODirSolver<VectorType>::solveSystem(MatVecMultiplier<VectorType> *matVec, + VectorType *x, VectorType *b) + { + FUNCNAME("ODirSolver::solveSystem"); + + double res, old_res = -1.0; + double dad, dad_old, rd, alpha, gamma, sigma; + int iter; + VectorType *swap = NULL; + const double TOL = 1.e-30; + + /*--------------------------------------------------------------------------*/ + /*--- Initalization ------------------------------------------------------*/ + /*--------------------------------------------------------------------------*/ + + if (norm(b) < TOL) + { + INFO(this->info,2)("b == 0, x = 0 is the solution of the linear system\n"); + set(*x, 0.0); + return(0); + } + + // r = Ax + matVec->matVec(NoTranspose, *x, *r); + + // r = -b + r + *r -= *b; + + // h = r + *h = *r; + + if (this->leftPrecon) { + this->leftPrecon->precon(h); + } + + // d = h + *d = *h; + + // d_old = 0; + set(*d_old, 0.0); + + dad_old = 1.0; + + /*--------------------------------------------------------------------------*/ + /*--- check initial residual ---------------------------------------------*/ + /*--------------------------------------------------------------------------*/ + + res = norm(r); + + START_INFO(); + if (SOLVE_INFO(0, res, &old_res)) + return(0); + + /*--------------------------------------------------------------------------*/ + /*--- Iteration ----------------------------------------------------------*/ + /*--------------------------------------------------------------------------*/ + + for (iter = 1; iter <= this->max_iter; iter++) + { + /*--------------------------------------------------------------------------*/ + /*--- calculate r.d, A.d and d.A.d ---------------------------------------*/ + /*--------------------------------------------------------------------------*/ + // rd = r*d + rd = *r * *d; + + // Ad = A*d + matVec->matVec(NoTranspose, *d, *Ad); + + // dad = d*Ad + dad = *d * *Ad; + + if (abs(dad) < TOL) + { + BREAK_INFO("(Ad,d)_2 = 0", iter, res, &old_res); + return(iter); + } + + /*--------------------------------------------------------------------------*/ + /*--- update x and calculate new r --------------------------------------*/ + /*--------------------------------------------------------------------------*/ + alpha = rd/dad; + + // x = -alpha d + x + axpy(-alpha, *d, *x); + + // r = -alpha Ad + r + axpy(-alpha, *Ad, *r); + + res = norm(r); + if (SOLVE_INFO(iter, res, &old_res)) + return(iter); + + // h = Ad + *h = *Ad; + + if (this->leftPrecon) this->leftPrecon->precon(h); + + /*--------------------------------------------------------------------------*/ + /*--- calculate gamma and sigma ------------------------------------------*/ + /*--------------------------------------------------------------------------*/ + + // gamma = h*Ad/dad + gamma = (*h * *Ad)/dad; + sigma = dad/dad_old; + + /*--------------------------------------------------------------------------*/ + /*--- compute new d and save old values ----------------------------------*/ + /*--------------------------------------------------------------------------*/ + + // swap d and d_old + //swap(*d, *d_old); + swap = d; + d = d_old; + d_old = swap; + + // d = -sigma * d + *d *= -sigma; + + // d = -gamma d_old + d + axpy(-gamma, *d_old, *d); + + // d = h + d + *d += *h; + + dad_old= dad; + } + + return 0; // never reached ! + } + +} diff --git a/AMDiS/src/OEMSolver.h b/AMDiS/src/OEMSolver.h new file mode 100644 index 0000000000000000000000000000000000000000..bc70a618dd02213835776673a0af9c8cd113a8e9 --- /dev/null +++ b/AMDiS/src/OEMSolver.h @@ -0,0 +1,337 @@ +// ============================================================================ +// == == +// == AMDiS - Adaptive multidimensional simulations == +// == == +// ============================================================================ +// == == +// == crystal growth group == +// == == +// == Stiftung caesar == +// == Ludwig-Erhard-Allee 2 == +// == 53175 Bonn == +// == germany == +// == == +// ============================================================================ +// == == +// == http://www.caesar.de/cg/AMDiS == +// == == +// ============================================================================ + +/** \file OEMSolver.h */ + +/** + * \defgroup Solver Solver module + * @{ <img src="solver.png"> @} + * + * \brief + * Contains all classes needed for solving linear and non linear equation + * systems. + */ + +#ifndef AMDIS_OEM_SOLVER_H +#define AMDIS_OEM_SOLVER_H + +// ============================================================================ +// ===== includes ============================================================= +// ============================================================================ + +#include "Global.h" + +namespace AMDiS { + + // ============================================================================ + // ===== forward declarations ================================================= + // ============================================================================ + + template<typename VectorType> class Preconditioner; + template<typename VectorType> class CreatorInterface; + template<typename VectorType> class MatVecMultiplier; + + // ============================================================================ + // ===== definitions ========================================================== + // ============================================================================ + + /** \brief prints information before solving the system */ +#define START_INFO() this->start_info(funcName) + + /** \brief prints information after solving the system */ +#define BREAK_INFO(st,it,res,ores) \ + this->break_info(funcName,st,it,res,ores) + + /** \brief prints information while solving the system */ +#define SOLVE_INFO(it,res,ores) \ + this->solve_info(funcName,it,res,ores) + + + // ============================================================================ + // ===== class OEMSolver ====================================================== + // ============================================================================ + + /** + * \ingroup Solver + * + *\brief + * Solver for linear equation systems. + * Virtual base class for OEM solvers. + */ + template<typename VectorType> + class OEMSolver + { + public: + /** \brief + * The constructor reads needed parameters and sets solvers \ref name. + */ + OEMSolver(::std::string name); + + /** \brief + * Virtual destructor because OEMSolver is pure virtual. + */ + virtual ~OEMSolver(); + + void initParameters(); + + /** \brief + * Solves the linear system. + */ + int solve(MatVecMultiplier<VectorType> *mv, + VectorType *x, VectorType *b, + Preconditioner<VectorType> *lPrecon = NULL, + Preconditioner<VectorType> *rPrecon = NULL) + { + FUNCNAME("OEMSolver::solve()"); + TEST_EXIT(mv)("no matVec\n"); + TEST_EXIT(vectorCreator)("no vectorCreator\n"); + + leftPrecon = lPrecon; + rightPrecon = rPrecon; + + init(); + + if (leftPrecon) + leftPrecon->init(); + + if (rightPrecon) + rightPrecon->init(); + + int iter = solveSystem(mv, x, b); + + if (leftPrecon) + leftPrecon->exit(); + + if (rightPrecon) + rightPrecon->exit(); + + exit(); + + return iter; + }; + + // ===== getting-methods ====================================================== + + /** \name getting methods + * \{ + */ + + /** \brief + * Returns solvers \ref name. + */ + inline const ::std::string& getName() { return name; }; + + /** \brief + * Returns \ref tolerance + */ + inline double getTolerance() { + return tolerance; + }; + + /** \brief + * Returns \ref max_iter + */ + inline int getMaxIterations() { + return max_iter; + }; + + /** \brief + * Returns \ref residual + */ + inline double getResidual() { + return residual; + }; + + // inline Preconditioner<VectorType> *getLeftPrecon() { return leftPrecon; }; + + // inline Preconditioner<VectorType> *getRightPrecon() { return rightPrecon; }; + + /** \} */ + + // ===== setting-methods ====================================================== + + /** \name setting methods + * \{ + */ + + /** \brief + * Sets \ref tolerance + */ + inline void setTolerance(double tol) + { + tolerance = tol; + }; + + /** \brief + * Sets \ref relative + */ + inline void setRelative(bool rel) + { + relative = rel; + }; + + /** \brief + * Sets \ref max_iter + */ + inline void setMaxIterations(int i) + { + max_iter = i; + }; + + /** \brief + * Sets \ref info + */ + inline void setInfo(int i) + { + info = i; + }; + + inline void setVectorCreator(CreatorInterface<VectorType> *creator) { + vectorCreator = creator; + }; + + inline CreatorInterface<VectorType>* getVectorCreator() + { + return vectorCreator; + }; + + // inline void setLeftPrecon(Preconditioner<VectorType> *precon) { + // leftPrecon = precon; + // }; + + // inline void setRightPrecon(Preconditioner<VectorType> *precon) { + // rightPrecon = precon; + // }; + + /** \} */ + + protected: + /** \brief + * To be overloaded by concrete solvers. + */ + virtual void init() = 0; + + /** \brief + * To be overloaded by concrete solvers. + */ + virtual void exit() = 0; + + /** \brief + * To be overloaded by concrete solvers. + */ + virtual int solveSystem(MatVecMultiplier<VectorType> *mv, + VectorType *x, + VectorType *b) = 0; + + + /** \brief + * Prints start information. Uses \ref START_INFO. + */ + void start_info(const char *); + + /** \brief + * Prints break information. Uses \ref BREAK_INFO. + */ + void break_info(const char *, const char *, int, double, double *); + + /** \brief + * Prints solve information. Uses \ref SOLVE_INFO. + */ + int solve_info(const char *, int, double, double *); + + protected: + /** \brief + * solvers name. + */ + ::std::string name; + + /** \brief + * solver tolerance. Set in OEMSolver's constructor. + */ + double tolerance; + + /** \brief + * solver relative. Set in OEMSolver's constructor. + */ + bool relative; + + /** \brief + * maximal number of iterations. Set in OEMSolver's constructor. + */ + int max_iter; + + /** \brief + * info level during solving the system. Set in OEMSolver's constructor. + */ + int info; + + /** \brief + * current residual. + */ + double residual; + + Preconditioner<VectorType> *leftPrecon; + + Preconditioner<VectorType> *rightPrecon; + + CreatorInterface<VectorType> *vectorCreator; + + }; + + // ============================================================================ + // ===== class OEMSolverCreator =============================================== + // ============================================================================ + + /** + * \ingroup Solver + * + * \brief + * Interface for creators of concrete OEMSolvers. + */ + template<typename T> + class OEMSolverCreator : public CreatorInterface<OEMSolver<T> > + { + public: + virtual ~OEMSolverCreator() {}; + + /** \brief + * Sets \ref problem + */ + void setName(::std::string name_) { name = name_; }; + + protected: + /** \brief + * Pointer to the problem the solver will belong to. Needed as parameter + * when constructing an OEMSolver + */ + ::std::string name; + }; +} + +#include "OEMSolver.hh" + +#include "Preconditioner.h" +#include "BiCGSolver.h" +#include "BiCGStab_M.h" +#include "CGSolver.h" +#include "GMResSolver.h" +#include "ODirSolver.h" +#include "OResSolver.h" + +#endif // AMDIS_OEM_SOLVER_H diff --git a/AMDiS/src/OEMSolver.hh b/AMDiS/src/OEMSolver.hh new file mode 100644 index 0000000000000000000000000000000000000000..0bb86e0214291aceabf69c6411a9c83211aad563 --- /dev/null +++ b/AMDiS/src/OEMSolver.hh @@ -0,0 +1,106 @@ +#include "CreatorInterface.h" +#include "Parameters.h" +#include "Preconditioner.h" +#include "CreatorMap.h" +#include "MatVecMultiplier.h" + +namespace AMDiS { + + template<typename VectorType> + OEMSolver<VectorType>::OEMSolver(::std::string name_) + : name(name_), + tolerance(1.e-8), + relative(false), + max_iter(1000), + info(0), + residual(0), + leftPrecon(NULL), + rightPrecon(NULL), + vectorCreator(NULL) + { + FUNCNAME("OEMSolver::OEMSolver"); + } + + + template<typename VectorType> + void OEMSolver<VectorType>::initParameters() + { + FUNCNAME("OEMSolver::initParameters()"); + + GET_PARAMETER(0, name + "->tolerance", "%f", &tolerance); + GET_PARAMETER(0, name + "->relative", "%d", &relative); + GET_PARAMETER(0, name + "->max iteration", "%d", &max_iter); + GET_PARAMETER(0, name + "->info", "%d", &info); + } + + template<typename VectorType> + OEMSolver<VectorType>::~OEMSolver() + { + FUNCNAME("OEMSolver::~OEMSolver"); + } + + + template<typename VectorType> + void OEMSolver<VectorType>::start_info(const char *funcName) + { + info = info > 10 ? 10 : info; + + INFO(info,6)("with tolerance %e\n", tolerance); + PRINT_INFO(info,6)("\n"); + INFO(info,2)("iter. | residual | red.\n"); + return; + } + + template<typename VectorType> + void OEMSolver<VectorType>::break_info(const char *funcName, + const char *reason, + int iter, + double res, + double *ores) + { + if (ores && *ores > 0) { + INFO(info,2)("%5d | %12.5e | %8.2e\n", iter, res, res / (*ores)); + } else { + INFO(info,2)("%5d | %12.5e |\n", iter, res); + } + INFO(info,2)("stop due to: %s\n", reason); + + residual = res; + } + + template<typename VectorType> + int OEMSolver<VectorType>::solve_info(const char * funcName, int iter, + double res, double *ores) + { + static int step[11] = {0, 1000, 500, 200, 100, 50, 20, 10, 5, 2, 1}; + + if (res <= tolerance || (info && (iter%step[info] == 0)) || iter == max_iter) { + if (ores) { + if (*ores > 0.0) { + double red = res/(*ores); + INFO(info,2)("%5d | %12.5e | %8.2e\n", iter, res, red); + } else { + INFO(info,2)("%5d | %12.5e | --------\n", iter, res); + } + *ores = res; + } else { + INFO(info,2)("%5d | %12.5e |\n", iter, res); + } + } + + residual = res; + + if (iter == max_iter && res > tolerance) { + INFO(info,1)("tolerance %e not reached after %d iterations\n", tolerance, iter); + return(2); + } + + if (res <= tolerance) { + INFO(info,6)("finished successfully with %d iterations\n"); + return(1); + } + + return 0; + } + +} diff --git a/AMDiS/src/OResSolver.h b/AMDiS/src/OResSolver.h new file mode 100644 index 0000000000000000000000000000000000000000..64ef524b55c1b2b6b48bb7f415476662e1a523a6 --- /dev/null +++ b/AMDiS/src/OResSolver.h @@ -0,0 +1,100 @@ +// ============================================================================ +// == == +// == AMDiS - Adaptive multidimensional simulations == +// == == +// ============================================================================ +// == == +// == crystal growth group == +// == == +// == Stiftung caesar == +// == Ludwig-Erhard-Allee 2 == +// == 53175 Bonn == +// == germany == +// == == +// ============================================================================ +// == == +// == http://www.caesar.de/cg/AMDiS == +// == == +// ============================================================================ + +/** \file OResSolver.h */ + +#ifndef AMDIS_ORESSOLVER_H +#define AMDIS_ORESSOLVER_H + +#include "OEMSolver.h" +#include "MemoryManager.h" + +namespace AMDiS { + + // ============================================================================ + // ===== class OResSolver ===================================================== + // ============================================================================ + + /** + * \ingroup Solver + * + * \brief + * Solves a linear system by the method of orthogonal residuals and can be used + * for symmetric system matrices. + */ + template<typename VectorType> + class OResSolver : public OEMSolver<VectorType> + { + public: + MEMORY_MANAGED(OResSolver<VectorType>); + + /** \brief + * Creator class used in the OEMSolverMap. + */ + class Creator : public OEMSolverCreator<VectorType> + { + public: + MEMORY_MANAGED(Creator); + + virtual ~Creator() {}; + + /** \brief + * Returns a new OResSolver object. + */ + OEMSolver<VectorType>* create() { + return NEW OResSolver<VectorType>(this->name); + }; + }; + + /** \brief + * constructor + */ + OResSolver(::std::string name); + + /** \brief + * destructor + */ + ~OResSolver(); + + protected: + /** \brief + * realisation of OEMSolver::solveSystem + */ + int solveSystem(MatVecMultiplier<VectorType> *mv, VectorType *x, VectorType *b); + + /** \brief + * realisation of OEMSolver::init + */ + void init(); + + /** \brief + * realisation of OEMSolver::exit + */ + void exit(); + + private: + // pointer to memory needed for solveSystem + VectorType *Ad, *d, *d_old, *r, *h, *Ad_old, *Ah; + }; + +} + +#include "OResSolver.hh" + +#endif // AMDIS_ORESSOLVER_H diff --git a/AMDiS/src/OResSolver.hh b/AMDiS/src/OResSolver.hh new file mode 100644 index 0000000000000000000000000000000000000000..e2eb8f8f174e221db9a0c8301dcf8970da5de929 --- /dev/null +++ b/AMDiS/src/OResSolver.hh @@ -0,0 +1,159 @@ +#include "Preconditioner.h" + +namespace AMDiS { + + template<typename VectorType> + OResSolver<VectorType>::OResSolver(::std::string name) + : OEMSolver<VectorType>(name), + Ad(NULL), d(NULL), d_old(NULL), r(NULL), h(NULL), Ad_old(NULL), Ah(NULL) + { + } + + template<typename VectorType> + OResSolver<VectorType>::~OResSolver() + {} + + template<typename VectorType> + void OResSolver<VectorType>::init() + { + Ad = this->vectorCreator->create(); + d = this->vectorCreator->create(); + d_old = this->vectorCreator->create(); + r = this->vectorCreator->create(); + h = this->vectorCreator->create(); + Ad_old = this->vectorCreator->create(); + Ah = this->vectorCreator->create(); + } + + template<typename T> + void OResSolver<T>::exit() + { + this->vectorCreator->free(Ad); + this->vectorCreator->free(d); + this->vectorCreator->free(d_old); + this->vectorCreator->free(r); + this->vectorCreator->free(h); + this->vectorCreator->free(Ad_old); + this->vectorCreator->free(Ah); + } + + template<typename VectorType> + int OResSolver<VectorType>::solveSystem(MatVecMultiplier<VectorType> *matVec, + VectorType *x, VectorType *b) + { + FUNCNAME("OResSolver::solveSystem"); + + double alpha, gamma, sigma; + double daad, daad_old, rad, res, old_res = -1.0; + int iter; //, dim2; + VectorType *swap = NULL; + + /*--------------------------------------------------------------------------*/ + /*--- Initalization ------------------------------------------------------*/ + /*--------------------------------------------------------------------------*/ + + // r = Ax + matVec->matVec(NoTranspose, *x, *r); + + // r = - b + r + *r -= *b; + + // h = r + *h = *r; + + if (this->leftPrecon) this->leftPrecon->precon(h); + + // d = h + *d = *h; + + /*--- d_old = 0 and Ad_old = 0 ---------------*/ + set(*d_old, 0.0); + set(*Ad_old, 0.0); + + // Ad = A*d + matVec->matVec(NoTranspose, *d, *Ad); + + daad_old = 1.0; + + /*--------------------------------------------------------------------------*/ + /*--- check initial residual ---------------------------------------------*/ + /*--------------------------------------------------------------------------*/ + + res = norm(r); + + START_INFO(); + if (SOLVE_INFO(0, res, &old_res)) + return(0); + + for (iter = 1; iter <= this->max_iter; iter++) { + /*--- compute r.Ad and d.A.A.d ---------------------------------------------*/ + // rad = r * Ad + rad = *r * *Ad; + + // daad = Ad * Ad + daad = *Ad * *Ad; + + if (daad <= 1.e-30) { + BREAK_INFO("(Ad,d)_2 = 0", iter, res, &old_res); + return(iter); + } + + /*--- update u and r ------------------------------------------------------*/ + + alpha= rad/daad; + + // x = -alpha d + x + axpy(-alpha, *d, *x); + + // r = - alpha Ad + r + axpy(-alpha, *Ad, *r); + + res = norm(r); + + if (SOLVE_INFO(iter, res, &old_res)) + return(iter); + + // h = Ad + *h = *Ad; + + if (this->leftPrecon) this->leftPrecon->precon(h); + + // Ah = A * h + matVec->matVec(NoTranspose, *h, *Ah); + + // gamma = Ah * Ad / daad + gamma = (*Ah * *Ad)/daad; + sigma = daad/daad_old; + + /*--- compute new d.Ad, save old values! ----------------------------------*/ + // swap d and d_old + swap = d_old; + d_old = d; + d = swap; + + // swap Ad_old and Ad + swap = Ad_old; + Ad_old = Ad; + Ad = swap; + + /*--- d,Ad *= -sigma --------------*/ + *d *= -sigma; + *Ad *= -sigma; + + /*--- d,Ad -= gamma*d_old,Ad_old --*/ + axpy(-gamma, *d_old, *d); + axpy(-gamma, *Ad_old, *Ad); + + // d = h + d + *d += *h; + + // Ad = Ah + Ad + *Ad += *Ah; + + daad_old = daad; + } + + return 0; // never reached ! + } + +} diff --git a/AMDiS/src/OpenMP.h b/AMDiS/src/OpenMP.h new file mode 100644 index 0000000000000000000000000000000000000000..f76e08625d0d6c078fdadbf821970d442782f2eb --- /dev/null +++ b/AMDiS/src/OpenMP.h @@ -0,0 +1,3 @@ +#ifdef _OPENMP +#include <omp.h> +#endif diff --git a/AMDiS/src/Operator.cc b/AMDiS/src/Operator.cc new file mode 100644 index 0000000000000000000000000000000000000000..499b42c57e752b7713d19ad15f4039bdddb8eee3 --- /dev/null +++ b/AMDiS/src/Operator.cc @@ -0,0 +1,2330 @@ +#include "Operator.h" +#include "ElInfo.h" +#include "Assembler.h" +#include "FixVec.h" +#include "DOFVector.h" +#include "ElementMatrix.h" +#include "ElementVector.h" +#include "Quadrature.h" + +namespace AMDiS { + + const Flag OperatorTerm::PW_CONST = 1; + const Flag OperatorTerm::SYMMETRIC = 2; + + const Flag Operator::MATRIX_OPERATOR = 1; + const Flag Operator::VECTOR_OPERATOR = 2; + + + int Operator::getQuadratureDegree(int order, FirstOrderType firstOrderType) + { + ::std::vector<OperatorTerm*>* terms = NULL; + + switch(order) { + case 0: + terms = &zeroOrder; + break; + case 1: + if (firstOrderType == GRD_PHI) + terms = &firstOrderGrdPhi; + else + terms = &firstOrderGrdPsi; + break; + case 2: + terms = &secondOrder; + break; + } + + const BasisFunction *psi = rowFESpace->getBasisFcts(); + const BasisFunction *phi = colFESpace->getBasisFcts(); + + int psiDegree = psi->getDegree(); + int phiDegree = phi->getDegree(); + + int maxTermDegree = 0; + + int i; + for(i=0; i < static_cast<int>( terms->size()); i++) { + OperatorTerm *term = (*terms)[i]; + maxTermDegree = max(maxTermDegree, term->degree); + } + + int degree = psiDegree + phiDegree - order + maxTermDegree; + // if(type.isSet(Operator::MATRIX_OPERATOR)) + // degree += phiDegree; + + return degree; + } + + + void OperatorTerm::setSymmetric(bool symm) + { + if(symm) { + properties.setFlag(SYMMETRIC); + } else { + properties.unsetFlag(SYMMETRIC); + } + } + + bool OperatorTerm::isSymmetric() + { + return properties.isSet(SYMMETRIC); + } + + void OperatorTerm::lalt(const DimVec<WorldVector<double> >& Lambda, + const WorldMatrix<double>& matrix, + DimMat<double>& LALt, + bool symm, + double factor) + { + int i, j, k, l; + static const int dimOfWorld = Global::getGeo(WORLD); + int dim = LALt.getNumRows() - 1; + + double val = 0.0; + + if(symm) { + for (i = 0; i <= dim; i++) { + for (val = k = 0; k < dimOfWorld; k++) + for(l=0; l < dimOfWorld; l++) + val += Lambda[i][k] * matrix[k][l] * Lambda[i][l]; + val *= factor; + LALt[i][i] += val; + for (j = i+1; j <= dim; j++) { + for (val = k = 0; k < dimOfWorld; k++) + for(l=0; l < dimOfWorld; l++) + val += Lambda[i][k] * matrix[k][l] * Lambda[j][l]; + val *= factor; + LALt[i][j] += val; + LALt[j][i] += val; + } + } + } else { + for (i = 0; i <= dim; i++) { + for (j = 0; j <= dim; j++) { + for (val = k = 0; k < dimOfWorld; k++) + for(l=0; l < dimOfWorld; l++) + val += Lambda[i][k] * matrix[k][l] * Lambda[j][l]; + val *= factor; + LALt[i][j] += val; + } + } + } + } + + void OperatorTerm::lalt_kl(const DimVec<WorldVector<double> >& Lambda, + int k, int l, + DimMat<double>& LALt, + double factor) + { + int i, j; + int dim = LALt.getNumRows() - 1; + + for (i = 0; i <= dim; i++) + for (j = 0; j <= dim; j++) + LALt[i][j] += factor * Lambda[i][k] * Lambda[j][l]; + } + + void OperatorTerm::l1lt(const DimVec<WorldVector<double> >& Lambda, + DimMat<double>& LALt, + double factor) + { + int i, j, k; + static const int dimOfWorld = Global::getGeo(WORLD); + int dim = LALt.getNumRows() - 1; + + double val = 0.0; + + for (i = 0; i <= dim; i++) { + for (val = k = 0; k < dimOfWorld; k++) + val += Lambda[i][k] * Lambda[i][k]; + val *= factor; + LALt[i][i] += val; + for (j = i+1; j <= dim; j++) { + for (val = k = 0; k < dimOfWorld; k++) + val += Lambda[i][k] * Lambda[j][k]; + val *= factor; + LALt[i][j] += val; + LALt[j][i] += val; + } + } + } + + void OperatorTerm::lb(const DimVec<WorldVector<double> >& Lambda, + const WorldVector<double>& b, + DimVec<double>& Lb, + double factor) + { + int i, j; + int dim = Lb.getSize() - 1; + static const int dimOfWorld = Global::getGeo(WORLD); + + double val = 0.0; + + for(i = 0; i <= dim; i++) { + for(val = j = 0; j < dimOfWorld; j++) + val += Lambda[i][j] * b[j]; + val *= factor; + Lb[i] += val; + } + } + + Operator::Operator(Flag operatorType, + const FiniteElemSpace *rowFESpace_, + const FiniteElemSpace *colFESpace_) + : rowFESpace(rowFESpace_), + colFESpace(colFESpace_ ? colFESpace_ : rowFESpace_), + type(operatorType), + fillFlag(Mesh::CALL_LEAF_EL | Mesh::FILL_COORDS | + Mesh::FILL_DET | Mesh::FILL_GRD_LAMBDA), + assembler(NULL), + uhOld(NULL), + optimized(true) + { + nRow = rowFESpace->getBasisFcts()->getNumber(); + nCol = colFESpace->getBasisFcts()->getNumber(); + }; + + void Operator::setUhOld(const DOFVectorBase<double> *uhOld_) + { + uhOld = uhOld_; + } + + void Operator::addSecondOrderTerm(SecondOrderTerm *term) + { + secondOrder.push_back(term); + term->operat = this; + } + + void Operator::addFirstOrderTerm(FirstOrderTerm *term, + FirstOrderType type) + { + if(type == GRD_PSI) + firstOrderGrdPsi.push_back(term); + else + firstOrderGrdPhi.push_back(term); + term->operat = this; + } + + void Operator::addZeroOrderTerm(ZeroOrderTerm *term) + { + zeroOrder.push_back(term); + term->operat = this; + } + + void Operator::getElementMatrix(const ElInfo *elInfo, + ElementMatrix *userMat, + double factor) + { + if(!assembler) { + initAssembler(NULL, NULL, NULL, NULL); + } + + assembler->calculateElementMatrix(elInfo, userMat, factor); + } + + void Operator::getElementVector(const ElInfo *elInfo, + ElementVector *userVec, + double factor) + { + if(!assembler) { + initAssembler(NULL, NULL, NULL, NULL); + } + + assembler->calculateElementVector(elInfo, userVec, factor); + } + + void Operator::initAssembler(Quadrature *quad2, + Quadrature *quad1GrdPsi, + Quadrature *quad1GrdPhi, + Quadrature *quad0) + { + if(!assembler) + if(optimized) { + assembler = + NEW OptimizedAssembler(this, + quad2, quad1GrdPsi, quad1GrdPhi, quad0, + rowFESpace, colFESpace); + } else { + assembler = + NEW StandardAssembler(this, + quad2, quad1GrdPsi, quad1GrdPhi, quad0, + rowFESpace, colFESpace); + } + } + + + void MatrixFct_SOT::initElement(const ElInfo* elInfo, + SubAssembler* subAssembler, + Quadrature *quad) + { + vecAtQPs = subAssembler->getVectorAtQPs(vec, elInfo, quad); + } + + void VecAtQP_SOT::initElement(const ElInfo* elInfo, + SubAssembler* subAssembler, + Quadrature *quad) + { + vecAtQPs = subAssembler->getVectorAtQPs(vec, elInfo, quad); + } + + void CoordsAtQP_SOT::initElement(const ElInfo* elInfo, + SubAssembler* subAssembler, + Quadrature *quad) + { + coordsAtQPs = subAssembler->getCoordsAtQPs(elInfo, quad); + } + + void MatrixGradient_SOT::initElement(const ElInfo* elInfo, + SubAssembler* subAssembler, + Quadrature *quad) + { + gradAtQPs = subAssembler->getGradientsAtQPs(vec, elInfo, quad); + } + + void FctGradient_SOT::initElement(const ElInfo* elInfo, + SubAssembler* subAssembler, + Quadrature *quad) + { + gradAtQPs = subAssembler->getGradientsAtQPs(vec, elInfo, quad); + } + + // Andreas ergaenzt + void VecAndGradientAtQP_SOT::initElement(const ElInfo* elInfo, + SubAssembler* subAssembler, + Quadrature *quad) + { + vecAtQPs = subAssembler->getVectorAtQPs(vec, elInfo, quad); + gradAtQPs = subAssembler->getGradientsAtQPs(vec, elInfo, quad); + } + + void VecAndCoordsAtQP_SOT::initElement(const ElInfo* elInfo, + SubAssembler* subAssembler, + Quadrature *quad) + { + vecAtQPs = subAssembler->getVectorAtQPs(vec, elInfo, quad); + coordsAtQPs = subAssembler->getCoordsAtQPs(elInfo, quad); + } + + void MatrixGradientAndCoords_SOT::initElement(const ElInfo* elInfo, + SubAssembler* subAssembler, + Quadrature *quad) + { + gradAtQPs = subAssembler->getGradientsAtQPs(vec, elInfo, quad); + coordsAtQPs = subAssembler->getCoordsAtQPs(elInfo, quad); + } + + void VecGradCoordsAtQP_SOT::initElement(const ElInfo* elInfo, + SubAssembler* subAssembler, + Quadrature *quad) + { + vecAtQPs = subAssembler->getVectorAtQPs(vec, elInfo, quad); + gradAtQPs = subAssembler->getGradientsAtQPs(vec, elInfo, quad); + coordsAtQPs = subAssembler->getCoordsAtQPs(elInfo, quad); + } + + // Ende Andreas Ergaenzung + + void VecAtQP_FOT::initElement(const ElInfo* elInfo, + SubAssembler* subAssembler, + Quadrature *quad) + { + vecAtQPs = subAssembler->getVectorAtQPs(vec, elInfo, quad); + } + + void CoordsAtQP_FOT::initElement(const ElInfo* elInfo, + SubAssembler* subAssembler, + Quadrature *quad) + { + coordsAtQPs = subAssembler->getCoordsAtQPs(elInfo, quad); + } + + void VecCoordsAtQP_FOT::initElement(const ElInfo* elInfo, + SubAssembler* subAssembler, + Quadrature *quad) + { + coordsAtQPs = subAssembler->getCoordsAtQPs(elInfo, quad); + } + + void VectorGradient_FOT::initElement(const ElInfo* elInfo, + SubAssembler* subAssembler, + Quadrature *quad) + { + gradAtQPs = subAssembler->getGradientsAtQPs(vec, elInfo, quad); + } + + void VectorFct_FOT::initElement(const ElInfo* elInfo, + SubAssembler* subAssembler, + Quadrature *quad) + { + vecAtQPs = subAssembler->getVectorAtQPs(vec, elInfo, quad); + } + + void VecFctAtQP_FOT::initElement(const ElInfo* elInfo, + SubAssembler* subAssembler, + Quadrature *quad) + { + coordsAtQPs = subAssembler->getCoordsAtQPs(elInfo, quad); + } + + void VecAtQP_ZOT::initElement(const ElInfo* elInfo, + SubAssembler* subAssembler, + Quadrature *quad) + { + vecAtQPs = subAssembler->getVectorAtQPs(vec, elInfo, quad); + } + + // Andreas ergaenzt + + void MultVecAtQP_ZOT::initElement(const ElInfo* elInfo, + SubAssembler* subAssembler, + Quadrature *quad) + { + vecAtQPs1 = subAssembler->getVectorAtQPs(vec1, elInfo, quad); + vecAtQPs2 = subAssembler->getVectorAtQPs(vec2, elInfo, quad); + } + + void Vec2AtQP_ZOT::initElement(const ElInfo* elInfo, + SubAssembler* subAssembler, + Quadrature *quad) + { + vecAtQPs1 = subAssembler->getVectorAtQPs(vec1, elInfo, quad); + vecAtQPs2 = subAssembler->getVectorAtQPs(vec2, elInfo, quad); + } + + void VecAndCoordsAtQP_ZOT::initElement(const ElInfo* elInfo, + SubAssembler* subAssembler, + Quadrature *quad) + { + vecAtQPs = subAssembler->getVectorAtQPs(vec, elInfo, quad); + coordsAtQPs = subAssembler->getCoordsAtQPs(elInfo, quad); + } + + void FctGradientCoords_ZOT::initElement(const ElInfo* elInfo, + SubAssembler* subAssembler, + Quadrature *quad) + { + gradAtQPs = subAssembler->getGradientsAtQPs(vec, elInfo, quad); + coordsAtQPs = subAssembler->getCoordsAtQPs(elInfo, quad); + } + + void VecGradCoordsAtQP_ZOT::initElement(const ElInfo* elInfo, + SubAssembler* subAssembler, + Quadrature *quad) + { + vecAtQPs = subAssembler->getVectorAtQPs(vec, elInfo, quad); + gradAtQPs = subAssembler->getGradientsAtQPs(vec, elInfo, quad); + coordsAtQPs = subAssembler->getCoordsAtQPs(elInfo, quad); + } + + // bis hierhin erstmal + + void VecAndGradAtQP_ZOT::initElement(const ElInfo* elInfo, + SubAssembler* subAssembler, + Quadrature *quad) + { + vecAtQPs = subAssembler->getVectorAtQPs(vec, elInfo, quad); + gradAtQPs = subAssembler->getGradientsAtQPs(vec, elInfo, quad); + } + + void VecAndGradVecAtQP_ZOT::initElement(const ElInfo* elInfo, + SubAssembler* subAssembler, + Quadrature *quad) + { + vecAtQPs = subAssembler->getVectorAtQPs(vec, elInfo, quad); + gradAtQPs = subAssembler->getGradientsAtQPs(vecGrd, elInfo, quad); + } + + void VecAndGradVec2AtQP_ZOT::initElement(const ElInfo* elInfo, + SubAssembler* subAssembler, + Quadrature *quad) + { + vecAtQPs = subAssembler->getVectorAtQPs(vec, elInfo, quad); + grad1AtQPs = subAssembler->getGradientsAtQPs(vecGrd1, elInfo, quad); + grad2AtQPs = subAssembler->getGradientsAtQPs(vecGrd2, elInfo, quad); + } + + void FctGradient_ZOT::initElement(const ElInfo* elInfo, + SubAssembler* subAssembler, + Quadrature *quad) + { + gradAtQPs = subAssembler->getGradientsAtQPs(vec, elInfo, quad); + } + + void CoordsAtQP_ZOT::initElement(const ElInfo* elInfo, + SubAssembler* subAssembler, + Quadrature *quad) { + coordsAtQPs = subAssembler->getCoordsAtQPs(elInfo, quad); + } + + void MatrixFct_SOT::getLALt(const ElInfo *elInfo, int numPoints, DimMat<double> **LALt) const { + const DimVec<WorldVector<double> > &Lambda = elInfo->getGrdLambda(); + int iq; + for(iq = 0; iq < numPoints; iq++) { + lalt(Lambda, (*matrixFct)(vecAtQPs[iq]), *(LALt[iq]), symmetric, 1.0); + } + } + + void VecAtQP_SOT::getLALt(const ElInfo *elInfo, int numPoints, DimMat<double> **LALt) const { + const DimVec<WorldVector<double> > &Lambda = elInfo->getGrdLambda(); + int iq; + for(iq = 0; iq < numPoints; iq++) { + l1lt(Lambda, *(LALt[iq]), (*f)(vecAtQPs[iq])); + } + } + + void CoordsAtQP_SOT::getLALt(const ElInfo *elInfo, int numPoints, DimMat<double> **LALt) const { + const DimVec<WorldVector<double> > &Lambda = elInfo->getGrdLambda(); + int iq; + for(iq = 0; iq < numPoints; iq++) { + l1lt(Lambda, (*LALt[iq]), (*g)(coordsAtQPs[iq])); + } + } + + void MatrixGradient_SOT::getLALt(const ElInfo *elInfo, int numPoints, DimMat<double> **LALt) const { + const DimVec<WorldVector<double> > &Lambda = elInfo->getGrdLambda(); + int iq; + for(iq = 0; iq < numPoints; iq++) { + lalt(Lambda, (*f)(gradAtQPs[iq]), (*LALt[iq]), symmetric, 1.0); + } + } + + void FctGradient_SOT::getLALt(const ElInfo *elInfo, int numPoints, DimMat<double> **LALt) const { + const DimVec<WorldVector<double> > &Lambda = elInfo->getGrdLambda(); + int iq; + for(iq = 0; iq < numPoints; iq++) { + l1lt(Lambda, *(LALt[iq]), (*f)(gradAtQPs[iq])); + } + } + + // Andreas Ergaenzung + + void VecAndGradientAtQP_SOT::getLALt(const ElInfo *elInfo, int numPoints, + DimMat<double> **LALt) const { + const DimVec<WorldVector<double> > &Lambda = elInfo->getGrdLambda(); + int iq; + for(iq = 0; iq < numPoints; iq++) { + l1lt(Lambda, *(LALt[iq]), (*f)(vecAtQPs[iq], gradAtQPs[iq])); + } + } + + void VecAndCoordsAtQP_SOT::getLALt(const ElInfo *elInfo, int numPoints, DimMat<double> **LALt) + const { const DimVec<WorldVector<double> > &Lambda = elInfo->getGrdLambda(); + int iq; + for(iq = 0; iq < numPoints; iq++) { + l1lt(Lambda, *(LALt[iq]), (*f)(vecAtQPs[iq], coordsAtQPs[iq])); + } + } + + void MatrixGradientAndCoords_SOT::getLALt(const ElInfo *elInfo, int numPoints, + DimMat<double> **LALt) const { + const DimVec<WorldVector<double> > &Lambda = elInfo->getGrdLambda(); + int iq; + for(iq = 0; iq < numPoints; iq++) { + lalt(Lambda, (*f)(gradAtQPs[iq], coordsAtQPs[iq]), (*LALt[iq]), symmetric, 1.0); + } + } + + void VecGradCoordsAtQP_SOT::getLALt(const ElInfo *elInfo, int numPoints, + DimMat<double> **LALt) const { + const DimVec<WorldVector<double> > &Lambda = elInfo->getGrdLambda(); + int iq; + for(iq = 0; iq < numPoints; iq++) { + l1lt(Lambda, *(LALt[iq]), (*f)(vecAtQPs[iq], gradAtQPs[iq], coordsAtQPs[iq])); + } + } + + // Ende Andreas Ergaenzung + + void VecAtQP_FOT::getLb(const ElInfo *elInfo, int numPoints, VectorOfFixVecs<DimVec<double> >& Lb) const { + const DimVec<WorldVector<double> > &Lambda = elInfo->getGrdLambda(); + int iq; + for(iq = 0; iq < numPoints; iq++) { + if(b) + lb(Lambda, *b, Lb[iq], (*f)(vecAtQPs[iq])); + else + l1(Lambda, Lb[iq], (*f)(vecAtQPs[iq])); + } + } + + void CoordsAtQP_FOT::getLb(const ElInfo *elInfo, int numPoints, VectorOfFixVecs<DimVec<double> >& Lb) const { + const DimVec<WorldVector<double> > &Lambda = elInfo->getGrdLambda(); + int iq; + for(iq = 0; iq < numPoints; iq++) { + l1(Lambda, Lb[iq], (*g)(coordsAtQPs[iq])); + } + } + + void VecCoordsAtQP_FOT::getLb(const ElInfo *elInfo, int numPoints, + VectorOfFixVecs<DimVec<double> >& Lb) const + { + const DimVec<WorldVector<double> > &Lambda = elInfo->getGrdLambda(); + int iq; + for(iq = 0; iq < numPoints; iq++) + { + lb(Lambda, b, Lb[iq], (*g)(coordsAtQPs[iq])); + } + } + + void VectorGradient_FOT::getLb(const ElInfo *elInfo, int numPoints, VectorOfFixVecs<DimVec<double> >& Lb) const { + const DimVec<WorldVector<double> > &Lambda = elInfo->getGrdLambda(); + int iq; + if(f) { + for(iq = 0; iq < numPoints; iq++) { + lb(Lambda, (*f)(gradAtQPs[iq]), Lb[iq], 1.0); + } + } else { + for(iq = 0; iq < numPoints; iq++) { + lb(Lambda, gradAtQPs[iq], Lb[iq], 1.0); + } + } + } + + void VectorFct_FOT::getLb(const ElInfo *elInfo, int numPoints, VectorOfFixVecs<DimVec<double> >& Lb) const { + const DimVec<WorldVector<double> > &Lambda = elInfo->getGrdLambda(); + int iq; + for(iq = 0; iq < numPoints; iq++) { + lb(Lambda, (*vecFct)(vecAtQPs[iq]), Lb[iq], 1.0); + } + } + + void VecFctAtQP_FOT::getLb(const ElInfo *elInfo, int numPoints, VectorOfFixVecs<DimVec<double> >& Lb) const { + const DimVec<WorldVector<double> > &Lambda = elInfo->getGrdLambda(); + int iq; + for(iq = 0; iq < numPoints; iq++) { + lb(Lambda, (*g)(coordsAtQPs[iq]), Lb[iq], 1.0); + } + } + + void VecAtQP_ZOT::getC(const ElInfo *, int numPoints, double *C) const { + int iq; + if(f) { + for(iq = 0; iq < numPoints; iq++) { + C[iq] += (*f)(vecAtQPs[iq]); + } + } else { + for(iq = 0; iq < numPoints; iq++) { + C[iq] += vecAtQPs[iq]; + } + } + } + + void VecAtQP_ZOT::eval(int numPoints, + const double *uhAtQP, + const WorldVector<double> *grdUhAtQP, + const WorldMatrix<double> *D2UhAtQP, + double *result, + double fac) const + { + int iq; + for(iq = 0; iq < numPoints; iq++) { + result[iq] += fac * (*f)(vecAtQPs[iq]) * uhAtQP[iq]; + } + } + + // Andreas ergaenzt + + void MultVecAtQP_ZOT::getC(const ElInfo *, int numPoints, double *C) const { + int iq; + for(iq = 0; iq < numPoints; iq++) { + C[iq] += (*f1)(vecAtQPs1[iq]) * (*f2)(vecAtQPs2[iq]); + } + } + + void MultVecAtQP_ZOT::eval(int numPoints, + const double *uhAtQP, + const WorldVector<double> *grdUhAtQP, + const WorldMatrix<double> *D2UhAtQP, + double *result, + double fac) const + { + int iq; + for(iq = 0; iq < numPoints; iq++) { + result[iq] += + fac * + (*f1)(vecAtQPs1[iq]) * + (*f2)(vecAtQPs2[iq]) * + uhAtQP[iq]; + } + } + + void Vec2AtQP_ZOT::getC(const ElInfo *, int numPoints, double *C) const { + int iq; + for(iq = 0; iq < numPoints; iq++) { + C[iq] += (*f)(vecAtQPs1[iq], vecAtQPs2[iq]); + } + } + + void Vec2AtQP_ZOT::eval(int numPoints, + const double *uhAtQP, + const WorldVector<double> *grdUhAtQP, + const WorldMatrix<double> *D2UhAtQP, + double *result, + double fac) const + { + int iq; + for(iq = 0; iq < numPoints; iq++) { + result[iq] += + fac * + (*f)(vecAtQPs1[iq], vecAtQPs2[iq]) * + uhAtQP[iq]; + } + } + + void VecAndCoordsAtQP_ZOT::getC(const ElInfo *, int numPoints, double *C) const { + int iq; + for(iq = 0; iq < numPoints; iq++) { + C[iq] += (*f)(vecAtQPs[iq], coordsAtQPs[iq]); + } + } + + void VecAndCoordsAtQP_ZOT::eval(int numPoints, + const double *uhAtQP, + const WorldVector<double> *grdUhAtQP, + const WorldMatrix<double> *D2UhAtQP, + double *result, + double fac) const + { + int iq; + for(iq = 0; iq < numPoints; iq++) { + result[iq] += + fac * + (*f)(vecAtQPs[iq], coordsAtQPs[iq]) * + uhAtQP[iq]; + } + } + + + void FctGradientCoords_ZOT::getC(const ElInfo *, int numPoints, double *C) const { + int iq; + for(iq = 0; iq < numPoints; iq++) { + C[iq] += (*f)(gradAtQPs[iq], coordsAtQPs[iq]); + } + } + + void FctGradientCoords_ZOT::eval(int numPoints, + const double *uhAtQP, + const WorldVector<double> *grdUhAtQP, + const WorldMatrix<double> *D2UhAtQP, + double *result, + double fac) const + { + int iq; + for(iq = 0; iq < numPoints; iq++) { + result[iq] += + fac * + (*f)(gradAtQPs[iq], coordsAtQPs[iq]) * + uhAtQP[iq]; + } + } + + void VecGradCoordsAtQP_ZOT::getC(const ElInfo *, int numPoints, double *C) const { + int iq; + for(iq = 0; iq < numPoints; iq++) { + C[iq] += (*f)(vecAtQPs[iq], gradAtQPs[iq], coordsAtQPs[iq]); + } + } + + void VecGradCoordsAtQP_ZOT::eval(int numPoints, + const double *uhAtQP, + const WorldVector<double> *grdUhAtQP, + const WorldMatrix<double> *D2UhAtQP, + double *result, + double fac) const + { + int iq; + for(iq = 0; iq < numPoints; iq++) { + result[iq] += + fac * + (*f)(vecAtQPs[iq], gradAtQPs[iq], coordsAtQPs[iq]) * + uhAtQP[iq]; + } + } + + // bis hierhin + + void VecAndGradAtQP_ZOT::getC(const ElInfo *, int numPoints, double *C) const { + int iq; + for(iq = 0; iq < numPoints; iq++) { + C[iq] += (*f)(vecAtQPs[iq], gradAtQPs[iq]); + } + } + + void VecAndGradAtQP_ZOT::eval(int numPoints, + const double *uhAtQP, + const WorldVector<double> *grdUhAtQP, + const WorldMatrix<double> *D2UhAtQP, + double *result, + double fac) const + { + int iq; + for(iq = 0; iq < numPoints; iq++) { + result[iq] += + fac * + (*f)(vecAtQPs[iq], gradAtQPs[iq]) * + uhAtQP[iq]; + } + } + + void VecAndGradVecAtQP_ZOT::getC(const ElInfo *, int numPoints, double *C) const + { + int iq; + for(iq = 0; iq < numPoints; iq++) { + C[iq] += (*f)(vecAtQPs[iq], gradAtQPs[iq]); + } + } + + void VecAndGradVecAtQP_ZOT::eval(int numPoints, + const double *uhAtQP, + const WorldVector<double> *grdUhAtQP, + const WorldMatrix<double> *D2UhAtQP, + double *result, + double fac) const + { + int iq; + for(iq = 0; iq < numPoints; iq++) { + result[iq] += + fac * + (*f)(vecAtQPs[iq], gradAtQPs[iq]) * + uhAtQP[iq]; + } + } + + void VecAndGradVec2AtQP_ZOT::getC(const ElInfo *, int numPoints, double *C) const { + int iq; + for(iq = 0; iq < numPoints; iq++) { + C[iq] += (*f)(vecAtQPs[iq], grad1AtQPs[iq], grad2AtQPs[iq]); + } + } + + void VecAndGradVec2AtQP_ZOT::eval(int numPoints, + const double *uhAtQP, + const WorldVector<double> *grdUhAtQP, + const WorldMatrix<double> *D2UhAtQP, + double *result, + double fac) const + { + int iq; + for(iq = 0; iq < numPoints; iq++) { + result[iq] += + fac * + (*f)(vecAtQPs[iq], grad1AtQPs[iq], grad2AtQPs[iq]) * + uhAtQP[iq]; + } + } + + void FctGradient_ZOT::getC(const ElInfo *, int numPoints, double *C) const { + int iq; + for(iq = 0; iq < numPoints; iq++) { + C[iq] += (*f)(gradAtQPs[iq]); + } + } + + void FctGradient_ZOT::eval(int numPoints, + const double *uhAtQP, + const WorldVector<double> *grdUhAtQP, + const WorldMatrix<double> *D2UhAtQP, + double *result, + double fac) const + { + int iq; + for(iq = 0; iq < numPoints; iq++) { + result[iq] += + fac * + (*f)(gradAtQPs[iq]) * + uhAtQP[iq]; + } + } + + void CoordsAtQP_ZOT::getC(const ElInfo *, int numPoints, double *C) const { + for (int iq = 0; iq < numPoints; iq++) { + C[iq] += (*g)(coordsAtQPs[iq]); + } + } + + void CoordsAtQP_ZOT::eval(int numPoints, + const double *uhAtQP, + const WorldVector<double> *grdUhAtQP, + const WorldMatrix<double> *D2UhAtQP, + double *result, + double fac) const + { + for (int iq = 0; iq < numPoints; iq++) { + result[iq] += fac * (*g)(coordsAtQPs[iq]) * uhAtQP[iq]; + } + } + + void MatrixFct_SOT::eval(int numPoints, + const double *uhAtQP, + const WorldVector<double> *grdUhAtQP, + const WorldMatrix<double> *D2UhAtQP, + double *result, + double factor) const + { + int i, j, dow = Global::getGeo(WORLD); + int iq; + + for(iq = 0; iq < numPoints; iq++) { + double resultQP = 0.0; + + WorldMatrix<double> A = (*matrixFct)(vecAtQPs[iq]); + + if(D2UhAtQP) { + for(i=0; i < dow; i++) { + for(j=0; j < dow; j++) { + resultQP += A[i][j] * D2UhAtQP[iq][j][i]; + } + } + } + + if(grdUhAtQP) { + resultQP += (*divFct)(A) * grdUhAtQP[iq]; + } + + result[iq] += resultQP * factor; + } + } + + void MatrixFct_SOT::weakEval(int numPoints, + const WorldVector<double> *grdUhAtQP, + WorldVector<double> *result) const + { + int iq; + if(grdUhAtQP) { + WorldMatrix<double> A; + for(iq = 0; iq < numPoints; iq++) { + A = (*matrixFct)(vecAtQPs[iq]); + result[iq] += A * grdUhAtQP[iq]; + } + } + } + + + void Matrix_SOT::eval(int numPoints, + const double *uhAtQP, + const WorldVector<double> *grdUhAtQP, + const WorldMatrix<double> *D2UhAtQP, + double *result, + double factor) const + { + int i, j, dow = Global::getGeo(WORLD); + int iq; + + if(D2UhAtQP) { + for(iq = 0; iq < numPoints; iq++) { + double resultQP = 0.0; + for(i=0; i < dow; i++) { + for(j=0; j < dow; j++) { + resultQP += matrix[i][j] * D2UhAtQP[iq][j][i]; + } + } + result[iq] += resultQP * factor; + } + } + } + + void Matrix_SOT::weakEval(int numPoints, + const WorldVector<double> *grdUhAtQP, + WorldVector<double> *result) const + { + if(grdUhAtQP) { + int iq; + for(iq = 0; iq < numPoints; iq++) { + result[iq] += matrix * grdUhAtQP[iq]; + } + } + } + + + + void MatrixGradient_SOT::eval(int numPoints, + const double *uhAtQP, + const WorldVector<double> *grdUhAtQP, + const WorldMatrix<double> *D2UhAtQP, + double *result, + double factor) const + { + int i, j, dow = Global::getGeo(WORLD); + int iq; + + for(iq = 0; iq < numPoints; iq++) { + double resultQP = 0.0; + + WorldMatrix<double> A = (*f)(gradAtQPs[iq]); + + if(D2UhAtQP) { + for(i=0; i < dow; i++) { + for(j=0; j < dow; j++) { + resultQP += A[i][j] * D2UhAtQP[iq][j][i]; + } + } + } + + if(grdUhAtQP) { + resultQP += (*divFct)(A) * grdUhAtQP[iq]; + } + + result[iq] += resultQP * factor; + } + }; + + void MatrixGradient_SOT::weakEval(int numPoints, + const WorldVector<double> *grdUhAtQP, + WorldVector<double> *result) const + { + if(grdUhAtQP) { + int iq; + WorldMatrix<double> A; + for(iq = 0; iq < numPoints; iq++) { + A = (*f)(gradAtQPs[iq]); + result[iq] += A * grdUhAtQP[iq]; + } + } + } + + void VecAtQP_SOT::eval(int numPoints, + const double *uhAtQP, + const WorldVector<double> *grdUhAtQP, + const WorldMatrix<double> *D2UhAtQP, + double *result, + double fac) const + { + int i, dow = Global::getGeo(WORLD); + int iq; + + if(D2UhAtQP) { + for(iq = 0; iq < numPoints; iq++) { + double factor = (*f)(vecAtQPs[iq]); + double resultQP = 0.0; + for(i=0; i < dow; i++) { + resultQP += D2UhAtQP[iq][i][i]; + } + result[iq] += fac * factor * resultQP; + } + } + } + + void VecAtQP_SOT::weakEval(int numPoints, + const WorldVector<double> *grdUhAtQP, + WorldVector<double> *result) const + { + if(grdUhAtQP) { + int iq; + for(iq = 0; iq < numPoints; iq++) { + double factor = (*f)(vecAtQPs[iq]); + axpy(factor, grdUhAtQP[iq], result[iq]); + } + } + } + + void CoordsAtQP_SOT::eval(int numPoints, + const double *uhAtQP, + const WorldVector<double> *grdUhAtQP, + const WorldMatrix<double> *D2UhAtQP, + double *result, + double f) const + { + int i, dow = Global::getGeo(WORLD); + int iq; + + if(D2UhAtQP) { + for(iq = 0; iq < numPoints; iq++) { + double factor = (*g)(coordsAtQPs[iq]); + double resultQP = 0.0; + for(i=0; i < dow; i++) { + resultQP += D2UhAtQP[iq][i][i]; + } + result[iq] += factor * f * resultQP; + } + } + } + + void CoordsAtQP_SOT::weakEval(int numPoints, + const WorldVector<double> *grdUhAtQP, + WorldVector<double> *result) const + { + if(grdUhAtQP) { + int iq; + for(iq = 0; iq < numPoints; iq++) { + double factor = (*g)(coordsAtQPs[iq]); + axpy(factor, grdUhAtQP[iq], result[iq]); + } + } + } + + void FctGradient_SOT::eval(int numPoints, + const double *uhAtQP, + const WorldVector<double> *grdUhAtQP, + const WorldMatrix<double> *D2UhAtQP, + double *result, + double fac) const + { + int i, dow = Global::getGeo(WORLD); + + int iq; + + if(D2UhAtQP) { + for(iq = 0; iq < numPoints; iq++) { + double factor = (*f)(gradAtQPs[iq]); + double resultQP = 0.0; + for(i=0; i < dow; i++) { + resultQP += D2UhAtQP[iq][i][i]; + } + result[iq] += fac * factor * resultQP; + } + } + } + + void FctGradient_SOT::weakEval(int numPoints, + const WorldVector<double> *grdUhAtQP, + WorldVector<double> *result) const + { + if(grdUhAtQP) { + int iq; + for(iq = 0; iq < numPoints; iq++) { + double factor = (*f)(gradAtQPs[iq]); + axpy(factor, grdUhAtQP[iq], result[iq]); + } + } + } + + + // Andreas Ergaenzung + + void VecAndGradientAtQP_SOT::eval(int numPoints, + const double *uhAtQP, + const WorldVector<double> *grdUhAtQP, + const WorldMatrix<double> *D2UhAtQP, + double *result, + double fac) const + { + int i, dow = Global::getGeo(WORLD); + + int iq; + + if(D2UhAtQP) { + for(iq = 0; iq < numPoints; iq++) { + double factor = (*f)(vecAtQPs[iq], gradAtQPs[iq]); + double resultQP = 0.0; + for(i=0; i < dow; i++) { + resultQP += D2UhAtQP[iq][i][i]; + } + result[iq] += fac * factor * resultQP; + } + } + } + + void VecAndGradientAtQP_SOT::weakEval(int numPoints, + const WorldVector<double> *grdUhAtQP, + WorldVector<double> *result) const + { + if(grdUhAtQP) { + int iq; + for(iq = 0; iq < numPoints; iq++) { + double factor = (*f)(vecAtQPs[iq], gradAtQPs[iq]); + axpy(factor, grdUhAtQP[iq], result[iq]); + } + } + } + + + + void VecAndCoordsAtQP_SOT::eval(int numPoints, + const double *uhAtQP, + const WorldVector<double> *grdUhAtQP, + const WorldMatrix<double> *D2UhAtQP, + double *result, + double fac) const + { + int i, dow = Global::getGeo(WORLD); + int iq; + + if(D2UhAtQP) { + for(iq = 0; iq < numPoints; iq++) { + double factor = (*f)(vecAtQPs[iq], coordsAtQPs[iq]); + double resultQP = 0.0; + for(i=0; i < dow; i++) { + resultQP += D2UhAtQP[iq][i][i]; + } + result[iq] += fac * factor * resultQP; + } + } + } + + void VecAndCoordsAtQP_SOT::weakEval(int numPoints, + const WorldVector<double> *grdUhAtQP, + WorldVector<double> *result) const + { + if(grdUhAtQP) { + int iq; + for(iq = 0; iq < numPoints; iq++) { + double factor = (*f)(vecAtQPs[iq], coordsAtQPs[iq]); + axpy(factor, grdUhAtQP[iq], result[iq]); + } + } + } + + void MatrixGradientAndCoords_SOT::eval(int numPoints, + const double *uhAtQP, + const WorldVector<double> *grdUhAtQP, + const WorldMatrix<double> *D2UhAtQP, + double *result, + double factor) const + { + int i, j, dow = Global::getGeo(WORLD); + int iq; + + for(iq = 0; iq < numPoints; iq++) { + double resultQP = 0.0; + + WorldMatrix<double> A = (*f)(gradAtQPs[iq], coordsAtQPs[iq]); + + if(D2UhAtQP) { + for(i=0; i < dow; i++) { + for(j=0; j < dow; j++) { + resultQP += A[i][j] * D2UhAtQP[iq][j][i]; + } + } + } + + if(grdUhAtQP) { + resultQP += (*divFct)(A) * grdUhAtQP[iq]; + } + + result[iq] += resultQP * factor; + } + }; + + void MatrixGradientAndCoords_SOT::weakEval(int numPoints, + const WorldVector<double> *grdUhAtQP, + WorldVector<double> *result) const + { + if(grdUhAtQP) { + int iq; + WorldMatrix<double> A; + for(iq = 0; iq < numPoints; iq++) { + A = (*f)(gradAtQPs[iq], coordsAtQPs[iq]); + result[iq] += A * grdUhAtQP[iq]; + } + } + } + + void VecGradCoordsAtQP_SOT::eval(int numPoints, + const double *uhAtQP, + const WorldVector<double> *grdUhAtQP, + const WorldMatrix<double> *D2UhAtQP, + double *result, + double fac) const + { + int i, dow = Global::getGeo(WORLD); + + int iq; + + if(D2UhAtQP) { + for(iq = 0; iq < numPoints; iq++) { + double factor = (*f)(vecAtQPs[iq], gradAtQPs[iq], coordsAtQPs[iq]); + double resultQP = 0.0; + for(i=0; i < dow; i++) { + resultQP += D2UhAtQP[iq][i][i]; + } + result[iq] += fac * factor * resultQP; + } + } + } + + void VecGradCoordsAtQP_SOT::weakEval(int numPoints, + const WorldVector<double> *grdUhAtQP, + WorldVector<double> *result) const + { + if(grdUhAtQP) { + int iq; + for(iq = 0; iq < numPoints; iq++) { + double factor = (*f)(vecAtQPs[iq], gradAtQPs[iq], coordsAtQPs[iq]); + axpy(factor, grdUhAtQP[iq], result[iq]); + } + } + } + + + + // Ende Andreas Ergaenzung + + + void VecAtQP_FOT::eval(int numPoints, + const double *uhAtQP, + const WorldVector<double> *grdUhAtQP, + const WorldMatrix<double> *D2UhAtQP, + double *result, + double fac) const + { + int i, dow = Global::getGeo(WORLD); + int iq; + + if(grdUhAtQP) { + for(iq = 0; iq < numPoints; iq++) { + double factor = (*f)(vecAtQPs[iq]); + double resultQP = 0.0; + for(i=0; i < dow; i++) { + resultQP += grdUhAtQP[iq][i]; + } + result[iq] += fac * factor * resultQP; + } + } + } + + void CoordsAtQP_FOT::eval(int numPoints, + const double *uhAtQP, + const WorldVector<double> *grdUhAtQP, + const WorldMatrix<double> *D2UhAtQP, + double *result, + double f) const + { + int i, dow = Global::getGeo(WORLD); + int iq; + + if(grdUhAtQP) { + for(iq = 0; iq < numPoints; iq++) { + double factor = (*g)(coordsAtQPs[iq]); + double resultQP = 0.0; + for(i=0; i < dow; i++) { + resultQP += grdUhAtQP[iq][i]; + } + result[iq] += f * factor * resultQP; + } + } + } + + void VecCoordsAtQP_FOT::eval(int numPoints, + const double *uhAtQP, + const WorldVector<double> *grdUhAtQP, + const WorldMatrix<double> *D2UhAtQP, + double *result, + double f) const + { + int i, dow = Global::getGeo(WORLD); + int iq; + + if(grdUhAtQP) { + for(iq = 0; iq < numPoints; iq++) { + double factor = (*g)(coordsAtQPs[iq]); + double resultQP = 0.0; + for(i=0; i < dow; i++) { + resultQP += grdUhAtQP[iq][i]; + } + result[iq] += f * factor * resultQP; + } + } + } + + void VectorGradient_FOT::eval(int numPoints, + const double *uhAtQP, + const WorldVector<double> *grdUhAtQP, + const WorldMatrix<double> *D2UhAtQP, + double *result, + double factor) const + { + int iq; + + if(grdUhAtQP) { + if(f) { + for(iq = 0; iq < numPoints; iq++) { + WorldVector<double> b = (*f)(gradAtQPs[iq]); + result[iq] += b * grdUhAtQP[iq] * factor; + } + } else { + for(iq = 0; iq < numPoints; iq++) { + result[iq] += gradAtQPs[iq] * grdUhAtQP[iq] * factor; + } + } + } + } + + void VectorFct_FOT::eval(int numPoints, + const double *uhAtQP, + const WorldVector<double> *grdUhAtQP, + const WorldMatrix<double> *D2UhAtQP, + double *result, + double factor) const + { + int iq; + + if(grdUhAtQP) { + for(iq = 0; iq < numPoints; iq++) { + WorldVector<double> b = (*vecFct)(vecAtQPs[iq]); + result[iq] += b * grdUhAtQP[iq] * factor; + } + } + } + + void VecFctAtQP_FOT::eval(int numPoints, + const double *uhAtQP, + const WorldVector<double> *grdUhAtQP, + const WorldMatrix<double> *D2UhAtQP, + double *result, + double f) const + { + int i, dow = Global::getGeo(WORLD); + int iq; + + if(grdUhAtQP) { + for(iq = 0; iq < numPoints; iq++) { + double resultQP = 0.0; + const WorldVector<double> &b = (*g)(coordsAtQPs[iq]); + for(i=0; i < dow; i++) { + resultQP += b[i] * grdUhAtQP[iq][i]; + } + result[iq] += f * resultQP; + } + } + } + + Assembler *Operator::getAssembler() + { + if(!assembler) { + initAssembler(NULL, NULL, NULL, NULL); + } + + return assembler; + } + + + // Matrix<double> **OperatorVec::createElementMatrix() + // { + // int i; + // Matrix<double> **newElementMatrix = GET_MEMORY(Matrix<double>*, nRow); + // for(i=0; i < nRow; i++) { + // newElementMatrix[i] = NEW Matrix<double>[nCol](vecSize, vecSize); + // } + + // return newElementMatrix; + // } + + // void OperatorVec::freeElementMatrix(Matrix<double> **elMat) { + // int i; + // for(i = 0; i < nRow; i++) { + // DELETE [] elMat[i]; + // } + // FREE_MEMORY(elMat, Matrix<double>*, nRow); + // } + + // Vector<double> *OperatorVec::createElementVector() + // { + // return NEW Vector<double>[nRow](vecSize); + // } + + // void OperatorVec::freeElementVector(Vector<double> *elVec) + // { + // DELETE [] elVec; + // } + + + + // void OperatorVec::getElementMatrix(ElInfo *elInfo, + // Matrix<double> **userMat, + // double factor = 1.0) + // { + // int i, j, k, l; + // Operator *op = NULL; + // double **elMat = NULL; + + // for(i = 0; i < operators.getNumRows(); i++) { + // for(j = 0; j < operators.getNumCols(); j++) { + // op = operators[i][j]; + // if(op) { + // if(!elMat) elMat = op->createElementMatrix(); + // op->resetElementMatrix(elMat); + // op->getElementMatrix(elInfo, elMat, factor); + // for(k = 0; k < nRow; k++) { + // for(l = 0; l < nCol; l++) { + // userMat[i][j][k][l] += elMat[k][l]; + // } + // } + // } + // } + // } + + // if(elMat) op->freeElementMatrix(elMat); + // } + + // void OperatorVec::getElementVector(const ElInfo *elInfo, + // Vector<double> *userVec, + // double factor = 1.0) + // { + // int i, j, k; + // Operator *op = NULL; + // double *elVec = NULL; + + // for(i = 0; i < operators.getNumRows(); i++) { + // for(j = 0; j < operators.getNumCols(); j++) { + // op = operators[i][j]; + // if(op) { + // if(!elVec) elVec = op->createElementVector(); + // op->resetElementVector(elVec); + // op->getElementVector(elInfo, elVec, factor); + // for(k = 0; k < nRow; k++) { + // userVec[i][k] += elVec[k]; + // } + // } + // } + // } + + // if(elVec) op->freeElementVector(elVec); + // } + + void CoordsAtQP_IJ_SOT::initElement(const ElInfo* elInfo, + SubAssembler* subAssembler, + Quadrature *quad) + { + coordsAtQPs = subAssembler->getCoordsAtQPs(elInfo, quad); + } + + void CoordsAtQP_IJ_SOT::getLALt(const ElInfo *elInfo, + int numPoints, + DimMat<double> **LALt) const + { + const DimVec<WorldVector<double> > Lambda = elInfo->getGrdLambda(); + int iq; + for(iq = 0; iq < numPoints; iq++) { + lalt_kl(Lambda, xi, xj, *(LALt[iq]), (*g)(coordsAtQPs[iq])); + } + } + + void CoordsAtQP_IJ_SOT::eval(int numPoints, + const double *uhAtQP, + const WorldVector<double> *grdUhAtQP, + const WorldMatrix<double> *D2UhAtQP, + double *result, + double f) const + { + int iq; + + if(D2UhAtQP) { + for(iq = 0; iq < numPoints; iq++) { + double factor = (*g)(coordsAtQPs[iq]); + result[iq] = D2UhAtQP[iq][xi][xj] * factor * f; + } + } + } + + void CoordsAtQP_IJ_SOT::weakEval(int numPoints, + const WorldVector<double> *grdUhAtQP, + WorldVector<double> *result) const + { + if(grdUhAtQP) { + int iq; + for(iq = 0; iq < numPoints; iq++) { + double factor = (*g)(coordsAtQPs[iq]); + result[iq][xi] += grdUhAtQP[iq][xj] * factor; + } + } + } + + void VecAtQP_IJ_SOT::initElement(const ElInfo* elInfo, + SubAssembler* subAssembler, + Quadrature *quad) + { + vecAtQPs = subAssembler->getVectorAtQPs(vec, elInfo, quad); + } + + void VecAtQP_IJ_SOT::getLALt(const ElInfo *elInfo, + int numPoints, + DimMat<double> **LALt) const + { + const DimVec<WorldVector<double> > &Lambda = elInfo->getGrdLambda(); + int iq; + for(iq = 0; iq < numPoints; iq++) { + lalt_kl(Lambda, xi, xj, *(LALt[iq]), (*f)(vecAtQPs[iq])); + } + } + + void VecAtQP_IJ_SOT::eval(int numPoints, + const double *uhAtQP, + const WorldVector<double> *grdUhAtQP, + const WorldMatrix<double> *D2UhAtQP, + double *result, + double fac) const + { + int iq; + + if(D2UhAtQP) { + for(iq = 0; iq < numPoints; iq++) { + double factor = (*f)(vecAtQPs[iq]); + result[iq] = D2UhAtQP[iq][xi][xj] * factor * fac; + } + } + } + + void VecAtQP_IJ_SOT::weakEval(int numPoints, + const WorldVector<double> *grdUhAtQP, + WorldVector<double> *result) const + { + if(grdUhAtQP) { + int iq; + for(iq = 0; iq < numPoints; iq++) { + double factor = (*f)(vecAtQPs[iq]); + result[iq][xi] += grdUhAtQP[iq][xj] * factor; + } + } + } + + + void VecOfDOFVecsAtQP_ZOT::initElement(const ElInfo* elInfo, + SubAssembler* subAssembler, + Quadrature *quad) + { + int i ,size = static_cast<int>(vecs.size()); + for(i = 0; i < size; i++) { + vecsAtQPs[i] = subAssembler->getVectorAtQPs(vecs[i], elInfo, quad); + } + } + + void VecOfDOFVecsAtQP_ZOT::getC(const ElInfo *, int numPoints, double *C) const + { + int i ,size = static_cast<int>(vecs.size()); + + ::std::vector<double> arg(size); + + int iq; + for(iq = 0; iq < numPoints; iq++) { + for(i = 0; i < size; i++) { + arg[i] = vecsAtQPs[i][iq]; + } + C[iq] += (*f)(arg); + } + } + + void VecOfDOFVecsAtQP_ZOT::eval(int numPoints, + const double *uhAtQP, + const WorldVector<double> *grdUhAtQP, + const WorldMatrix<double> *D2UhAtQP, + double *result, + double fac) const + { + int i ,size = static_cast<int>(vecs.size()); + + ::std::vector<double> arg(size); + + int iq; + for(iq = 0; iq < numPoints; iq++) { + for(i = 0; i < size; i++) { + arg[i] = vecsAtQPs[i][iq]; + } + result[iq] += fac * (*f)(arg) * uhAtQP[iq]; + } + } + + + void VecOfGradientsAtQP_ZOT::initElement(const ElInfo* elInfo, + SubAssembler* subAssembler, + Quadrature *quad) + { + int i ,size = static_cast<int>(vecs.size()); + for(i = 0; i < size; i++) { + gradsAtQPs[i] = subAssembler->getGradientsAtQPs(vecs[i], elInfo, quad); + } + } + + void VecDivergence_ZOT::initElement(const ElInfo* elInfo, + SubAssembler* subAssembler, + Quadrature *quad) + { + int i ,size = static_cast<int>(vecs.size()); + for(i = 0; i < size; i++) { + gradsAtQPs[i] = subAssembler->getGradientsAtQPs(vecs[i], elInfo, quad); + } + } + + + void VecOfGradientsAtQP_ZOT::getC(const ElInfo *, int numPoints, double *C) const + { + int i ,size = static_cast<int>(vecs.size()); + + ::std::vector<WorldVector<double>*> arg(size); + + int iq; + for(iq = 0; iq < numPoints; iq++) { + for(i = 0; i < size; i++) { + arg[i] = &(gradsAtQPs[i][iq]); + } + C[iq] += (*f)(arg); + } + } + + void VecOfGradientsAtQP_ZOT::eval(int numPoints, + const double *uhAtQP, + const WorldVector<double> *grdUhAtQP, + const WorldMatrix<double> *D2UhAtQP, + double *result, + double fac) const + { + int i ,size = static_cast<int>(vecs.size()); + + ::std::vector<WorldVector<double>*> arg(size); + + int iq; + for(iq = 0; iq < numPoints; iq++) { + for(i = 0; i < size; i++) { + arg[i] = &(gradsAtQPs[i][iq]); + } + result[iq] += fac * (*f)(arg) * uhAtQP[iq]; + } + } + + void VecDivergence_ZOT::getC(const ElInfo *, int numPoints, double *C) const + { + int i ,size = static_cast<int>(vecs.size()); + + int iq; + for(iq = 0; iq < numPoints; iq++) { + for(i = 0; i < size; i++) { + C[iq] += gradsAtQPs[i][iq][i]; + } + } + } + + void VecDivergence_ZOT::eval(int numPoints, + const double *uhAtQP, + const WorldVector<double> *grdUhAtQP, + const WorldMatrix<double> *D2UhAtQP, + double *result, + double fac) const + { + int i ,size = static_cast<int>(vecs.size()); + + double d; + + int iq; + for(iq = 0; iq < numPoints; iq++) { + d = 0.0; + for(i = 0; i < size; i++) { + d += gradsAtQPs[i][iq][i]; + } + result[iq] += d * uhAtQP[iq] * fac; + } + } + + void VecAndGradAtQP_SOT::eval(int numPoints, + const double *uhAtQP, + const WorldVector<double> *grdUhAtQP, + const WorldMatrix<double> *D2UhAtQP, + double *result, + double fac) const + { + int i, iq, dow = Global::getGeo(WORLD); + + if(D2UhAtQP) { + for(iq = 0; iq < numPoints; iq++) { + double factor = (*f)(vecAtQPs[iq], gradAtQPs[iq]); + double resultQP = 0.0; + for(i=0; i < dow; i++) { + resultQP += D2UhAtQP[iq][i][i]; + } + result[iq] += fac * resultQP * factor; + } + } + } + + void VecAndGradAtQP_SOT::weakEval(int numPoints, + const WorldVector<double> *grdUhAtQP, + WorldVector<double> *result) const + { + if(grdUhAtQP) { + int iq; + for(iq = 0; iq < numPoints; iq++) { + double factor = (*f)(vecAtQPs[iq], gradAtQPs[iq]); + axpy(factor, grdUhAtQP[iq], result[iq]); + } + } + } + + void VecAndGradAtQP_SOT::getLALt(const ElInfo *elInfo, int numPoints, DimMat<double> **LALt) const { + const DimVec<WorldVector<double> > &Lambda = elInfo->getGrdLambda(); + int iq; + for(iq = 0; iq < numPoints; iq++) { + l1lt(Lambda, *(LALt[iq]), (*f)(vecAtQPs[iq], gradAtQPs[iq])); + } + } + + void VecAndGradAtQP_SOT::initElement(const ElInfo* elInfo, + SubAssembler* subAssembler, + Quadrature *quad) + { + vecAtQPs = subAssembler->getVectorAtQPs(vec, elInfo, quad); + gradAtQPs = subAssembler->getGradientsAtQPs(vec, elInfo, quad); + } + + void General_SOT::initElement(const ElInfo* elInfo, + SubAssembler* subAssembler, + Quadrature *quad) + { + int i; + int numVecs = static_cast<int>(vecs_.size()); + int numGrads = static_cast<int>(grads_.size()); + + coordsAtQPs_ = subAssembler->getCoordsAtQPs(elInfo, quad); + + for(i = 0; i < numVecs; i++) { + vecsAtQPs_[i] = subAssembler->getVectorAtQPs(vecs_[i], elInfo, quad); + } + for(i = 0; i < numGrads; i++) { + gradsAtQPs_[i] = subAssembler->getGradientsAtQPs(grads_[i], elInfo, quad); + } + } + + void General_SOT::getLALt(const ElInfo *elInfo, + int numPoints, + DimMat<double> **LALt) const + { + int i; + int numVecs = static_cast<int>(vecs_.size()); + int numGrads = static_cast<int>(grads_.size()); + + ::std::vector<double> vecsArg(numVecs); + ::std::vector<WorldVector<double> > gradsArg(numGrads); + + const DimVec<WorldVector<double> > &Lambda = elInfo->getGrdLambda(); + int iq; + for(iq = 0; iq < numPoints; iq++) { + for(i = 0; i < numVecs; i++) { + vecsArg[i] = vecsAtQPs_[i][iq]; + } + for(i = 0; i < numGrads; i++) { + gradsArg[i] = gradsAtQPs_[i][iq]; + } + lalt(Lambda, (*f_)(coordsAtQPs_[iq], vecsArg, gradsArg), + *(LALt[iq]), symmetric_, 1.0); + } + } + + void General_SOT::eval(int numPoints, + const double *uhAtQP, + const WorldVector<double> *grdUhAtQP, + const WorldMatrix<double> *D2UhAtQP, + double *result, + double factor) const + { + int i, j, dow = Global::getGeo(WORLD); + int numVecs = static_cast<int>(vecs_.size()); + int numGrads = static_cast<int>(grads_.size()); + int iq; + + ::std::vector<double> vecsArg(numVecs); + ::std::vector<WorldVector<double> > gradsArg(numGrads); + + for(iq = 0; iq < numPoints; iq++) { + double resultQP = 0.0; + + for(i = 0; i < numVecs; i++) { + vecsArg[i] = vecsAtQPs_[i][iq]; + } + for(i = 0; i < numGrads; i++) { + gradsArg[i] = gradsAtQPs_[i][iq]; + } + + WorldMatrix<double> A = (*f_)(coordsAtQPs_[iq], vecsArg, gradsArg); + + if(D2UhAtQP) { + for(i=0; i < dow; i++) { + for(j=0; j < dow; j++) { + resultQP += A[i][j] * D2UhAtQP[iq][j][i]; + } + } + } + + if(grdUhAtQP) { + resultQP += (*divFct_)(A) * grdUhAtQP[iq]; + } + + result[iq] += resultQP * factor; + } + } + + void General_SOT::weakEval(int numPoints, + const WorldVector<double> *grdUhAtQP, + WorldVector<double> *result) const + { + int i; + int numVecs = static_cast<int>(vecs_.size()); + int numGrads = static_cast<int>(grads_.size()); + int iq; + + ::std::vector<double> vecsArg(numVecs); + ::std::vector<WorldVector<double> > gradsArg(numGrads); + + if(grdUhAtQP) { + WorldMatrix<double> A; + for(iq = 0; iq < numPoints; iq++) { + for(i = 0; i < numVecs; i++) { + vecsArg[i] = vecsAtQPs_[i][iq]; + } + for(i = 0; i < numGrads; i++) { + gradsArg[i] = gradsAtQPs_[i][iq]; + } + A = (*f_)(coordsAtQPs_[iq], vecsArg, gradsArg); + result[iq] += A * grdUhAtQP[iq]; + } + } + } + + void General_FOT::initElement(const ElInfo* elInfo, + SubAssembler* subAssembler, + Quadrature *quad) + { + int i; + int numVecs = static_cast<int>(vecs_.size()); + int numGrads = static_cast<int>(grads_.size()); + + coordsAtQPs_ = subAssembler->getCoordsAtQPs(elInfo, quad); + + for(i = 0; i < numVecs; i++) { + vecsAtQPs_[i] = subAssembler->getVectorAtQPs(vecs_[i], elInfo, quad); + } + for(i = 0; i < numGrads; i++) { + gradsAtQPs_[i] = subAssembler->getGradientsAtQPs(grads_[i], elInfo, quad); + } + } + + void General_FOT::getLb(const ElInfo *elInfo, + int numPoints, + VectorOfFixVecs<DimVec<double> >& result) const + { + int i; + int numVecs = static_cast<int>(vecs_.size()); + int numGrads = static_cast<int>(grads_.size()); + + ::std::vector<double> vecsArg(numVecs); + ::std::vector<WorldVector<double> > gradsArg(numGrads); + + const DimVec<WorldVector<double> > &Lambda = elInfo->getGrdLambda(); + int iq; + for(iq = 0; iq < numPoints; iq++) { + for(i = 0; i < numVecs; i++) { + vecsArg[i] = vecsAtQPs_[i][iq]; + } + for(i = 0; i < numGrads; i++) { + gradsArg[i] = gradsAtQPs_[i][iq]; + } + lb(Lambda, (*f_)(coordsAtQPs_[iq], vecsArg, gradsArg), + result[iq], 1.0); + } + } + + void General_FOT::eval(int numPoints, + const double *uhAtQP, + const WorldVector<double> *grdUhAtQP, + const WorldMatrix<double> *D2UhAtQP, + double *result, + double factor) const + { + int i, dow = Global::getGeo(WORLD); + int iq; + + int numVecs = static_cast<int>(vecs_.size()); + int numGrads = static_cast<int>(grads_.size()); + + ::std::vector<double> vecsArg(numVecs); + ::std::vector<WorldVector<double> > gradsArg(numGrads); + + if(grdUhAtQP) { + for(iq = 0; iq < numPoints; iq++) { + double resultQP = 0.0; + + for(i = 0; i < numVecs; i++) { + vecsArg[i] = vecsAtQPs_[i][iq]; + } + for(i = 0; i < numGrads; i++) { + gradsArg[i] = gradsAtQPs_[i][iq]; + } + + const WorldVector<double> &b = (*f_)(coordsAtQPs_[iq], vecsArg, gradsArg); + + for(i=0; i < dow; i++) { + resultQP += grdUhAtQP[iq][i] * b[i]; + } + result[iq] += factor * resultQP; + } + } + } + + void General_ZOT::initElement(const ElInfo* elInfo, SubAssembler* subAssembler, + Quadrature *quad) + { + int i; + int numVecs = static_cast<int>(vecs_.size()); + int numGrads = static_cast<int>(grads_.size()); + + coordsAtQPs_ = subAssembler->getCoordsAtQPs(elInfo, quad); + + for(i = 0; i < numVecs; i++) { + vecsAtQPs_[i] = subAssembler->getVectorAtQPs(vecs_[i], elInfo, quad); + } + for(i = 0; i < numGrads; i++) { + gradsAtQPs_[i] = subAssembler->getGradientsAtQPs(grads_[i], elInfo, quad); + } + } + + void General_ZOT::getC(const ElInfo *, int numPoints, double *C) const + { + int iq, i; + int numVecs = static_cast<int>(vecs_.size()); + int numGrads = static_cast<int>(grads_.size()); + + ::std::vector<double> vecsArg(numVecs); + ::std::vector<WorldVector<double> > gradsArg(numGrads); + + for(iq = 0; iq < numPoints; iq++) { + for(i = 0; i < numVecs; i++) { + vecsArg[i] = vecsAtQPs_[i][iq]; + } + for(i = 0; i < numGrads; i++) { + gradsArg[i] = gradsAtQPs_[i][iq]; + } + C[iq] += (*f_)(coordsAtQPs_[iq], vecsArg, gradsArg); + } + } + + void General_ZOT::eval(int numPoints, + const double *uhAtQP, + const WorldVector<double> *grdUhAtQP, + const WorldMatrix<double> *D2UhAtQP, + double *result, + double fac) const + { + int iq, i; + int numVecs = static_cast<int>(vecs_.size()); + int numGrads = static_cast<int>(grads_.size()); + + ::std::vector<double> vecsArg(numVecs); + ::std::vector<WorldVector<double> > gradsArg(numGrads); + + for(iq = 0; iq < numPoints; iq++) { + for(i = 0; i < numVecs; i++) { + vecsArg[i] = vecsAtQPs_[i][iq]; + } + for(i = 0; i < numGrads; i++) { + gradsArg[i] = gradsAtQPs_[i][iq]; + } + result[iq] += fac * (*f_)(coordsAtQPs_[iq], vecsArg, gradsArg) * uhAtQP[iq]; + } + } + + + + + + + + //************************************ parametric general Operatorterms ***************** + void GeneralParametric_SOT::initElement(const ElInfo* elInfo, + SubAssembler* subAssembler, + Quadrature *quad) + { + int i; + int numVecs = static_cast<int>(vecs_.size()); + int numGrads = static_cast<int>(grads_.size()); + + + elInfo->getElementNormal(elementNormal_); + coordsAtQPs_ = subAssembler->getCoordsAtQPs(elInfo, quad); + + for(i = 0; i < numVecs; i++) { + vecsAtQPs_[i] = subAssembler->getVectorAtQPs(vecs_[i], elInfo, quad); + } + for(i = 0; i < numGrads; i++) { + gradsAtQPs_[i] = subAssembler->getGradientsAtQPs(grads_[i], elInfo, quad); + } + } + + void GeneralParametric_SOT::getLALt(const ElInfo *elInfo, + int numPoints, + DimMat<double> **LALt) const + { + int i; + int numVecs = static_cast<int>(vecs_.size()); + int numGrads = static_cast<int>(grads_.size()); + + ::std::vector<double> vecsArg(numVecs); + ::std::vector<WorldVector<double> > gradsArg(numGrads); + + const DimVec<WorldVector<double> > &Lambda = elInfo->getGrdLambda(); + int iq; + for(iq = 0; iq < numPoints; iq++) { + for(i = 0; i < numVecs; i++) { + vecsArg[i] = vecsAtQPs_[i][iq]; + } + for(i = 0; i < numGrads; i++) { + gradsArg[i] = gradsAtQPs_[i][iq]; + } + lalt(Lambda, (*f_)(coordsAtQPs_[iq], elementNormal_, vecsArg, gradsArg), + *(LALt[iq]), symmetric_, 1.0); + } + } + + void GeneralParametric_SOT::eval(int numPoints, + const double *uhAtQP, + const WorldVector<double> *grdUhAtQP, + const WorldMatrix<double> *D2UhAtQP, + double *result, + double factor) const + { + int i, j, dow = Global::getGeo(WORLD); + int numVecs = static_cast<int>(vecs_.size()); + int numGrads = static_cast<int>(grads_.size()); + int iq; + + ::std::vector<double> vecsArg(numVecs); + ::std::vector<WorldVector<double> > gradsArg(numGrads); + + for(iq = 0; iq < numPoints; iq++) { + double resultQP = 0.0; + + for(i = 0; i < numVecs; i++) { + vecsArg[i] = vecsAtQPs_[i][iq]; + } + for(i = 0; i < numGrads; i++) { + gradsArg[i] = gradsAtQPs_[i][iq]; + } + + WorldMatrix<double> A = (*f_)(coordsAtQPs_[iq], elementNormal_, vecsArg, gradsArg); + + if(D2UhAtQP) { + for(i=0; i < dow; i++) { + for(j=0; j < dow; j++) { + resultQP += A[i][j] * D2UhAtQP[iq][j][i]; + } + } + } + + if(grdUhAtQP) { + resultQP += (*divFct_)(A) * grdUhAtQP[iq]; + } + + result[iq] += resultQP * factor; + } + } + + void GeneralParametric_SOT::weakEval(int numPoints, + const WorldVector<double> *grdUhAtQP, + WorldVector<double> *result) const + { + int i; + int numVecs = static_cast<int>(vecs_.size()); + int numGrads = static_cast<int>(grads_.size()); + int iq; + + ::std::vector<double> vecsArg(numVecs); + ::std::vector<WorldVector<double> > gradsArg(numGrads); + + if(grdUhAtQP) { + WorldMatrix<double> A; + for(iq = 0; iq < numPoints; iq++) { + for(i = 0; i < numVecs; i++) { + vecsArg[i] = vecsAtQPs_[i][iq]; + } + for(i = 0; i < numGrads; i++) { + gradsArg[i] = gradsAtQPs_[i][iq]; + } + A = (*f_)(coordsAtQPs_[iq], elementNormal_, vecsArg, gradsArg); + result[iq] += A * grdUhAtQP[iq]; + } + } + } + + void GeneralParametric_FOT::initElement(const ElInfo* elInfo, + SubAssembler* subAssembler, + Quadrature *quad) + { + int i; + int numVecs = static_cast<int>(vecs_.size()); + int numGrads = static_cast<int>(grads_.size()); + + elInfo->getElementNormal(elementNormal_); + coordsAtQPs_ = subAssembler->getCoordsAtQPs(elInfo, quad); + + for(i = 0; i < numVecs; i++) { + vecsAtQPs_[i] = subAssembler->getVectorAtQPs(vecs_[i], elInfo, quad); + } + for(i = 0; i < numGrads; i++) { + gradsAtQPs_[i] = subAssembler->getGradientsAtQPs(grads_[i], elInfo, quad); + } + } + + void GeneralParametric_FOT::getLb(const ElInfo *elInfo, + int numPoints, + VectorOfFixVecs<DimVec<double> >& result) const + { + int i; + int numVecs = static_cast<int>(vecs_.size()); + int numGrads = static_cast<int>(grads_.size()); + + ::std::vector<double> vecsArg(numVecs); + ::std::vector<WorldVector<double> > gradsArg(numGrads); + + const DimVec<WorldVector<double> > &Lambda = elInfo->getGrdLambda(); + int iq; + for(iq = 0; iq < numPoints; iq++) { + for(i = 0; i < numVecs; i++) { + vecsArg[i] = vecsAtQPs_[i][iq]; + } + for(i = 0; i < numGrads; i++) { + gradsArg[i] = gradsAtQPs_[i][iq]; + } + lb(Lambda, (*f_)(coordsAtQPs_[iq], elementNormal_, vecsArg, gradsArg), + result[iq], 1.0); + } + } + + void GeneralParametric_FOT::eval(int numPoints, + const double *uhAtQP, + const WorldVector<double> *grdUhAtQP, + const WorldMatrix<double> *D2UhAtQP, + double *result, + double factor) const + { + int i, dow = Global::getGeo(WORLD); + int iq; + + int numVecs = static_cast<int>(vecs_.size()); + int numGrads = static_cast<int>(grads_.size()); + + ::std::vector<double> vecsArg(numVecs); + ::std::vector<WorldVector<double> > gradsArg(numGrads); + + if(grdUhAtQP) { + for(iq = 0; iq < numPoints; iq++) { + double resultQP = 0.0; + + for(i = 0; i < numVecs; i++) { + vecsArg[i] = vecsAtQPs_[i][iq]; + } + for(i = 0; i < numGrads; i++) { + gradsArg[i] = gradsAtQPs_[i][iq]; + } + + const WorldVector<double> &b = (*f_)(coordsAtQPs_[iq], elementNormal_, vecsArg, gradsArg); + + for(i=0; i < dow; i++) { + resultQP += grdUhAtQP[iq][i] * b[i]; + } + result[iq] += factor * resultQP; + } + } + } + + void GeneralParametric_ZOT::initElement(const ElInfo* elInfo, SubAssembler* subAssembler, + Quadrature *quad) + { + int i; + int numVecs = static_cast<int>(vecs_.size()); + int numGrads = static_cast<int>(grads_.size()); + + elInfo->getElementNormal(elementNormal_); + coordsAtQPs_ = subAssembler->getCoordsAtQPs(elInfo, quad); + + for(i = 0; i < numVecs; i++) { + vecsAtQPs_[i] = subAssembler->getVectorAtQPs(vecs_[i], elInfo, quad); + } + for(i = 0; i < numGrads; i++) { + gradsAtQPs_[i] = subAssembler->getGradientsAtQPs(grads_[i], elInfo, quad); + } + } + + void GeneralParametric_ZOT::getC(const ElInfo *, int numPoints, double *C) const + { + int iq, i; + int numVecs = static_cast<int>(vecs_.size()); + int numGrads = static_cast<int>(grads_.size()); + + ::std::vector<double> vecsArg(numVecs); + ::std::vector<WorldVector<double> > gradsArg(numGrads); + + for(iq = 0; iq < numPoints; iq++) { + for(i = 0; i < numVecs; i++) { + vecsArg[i] = vecsAtQPs_[i][iq]; + } + for(i = 0; i < numGrads; i++) { + gradsArg[i] = gradsAtQPs_[i][iq]; + } + C[iq] += (*f_)(coordsAtQPs_[iq], elementNormal_, vecsArg, gradsArg); + } + } + + void GeneralParametric_ZOT::eval(int numPoints, + const double *uhAtQP, + const WorldVector<double> *grdUhAtQP, + const WorldMatrix<double> *D2UhAtQP, + double *result, + double fac) const + { + int iq, i; + int numVecs = static_cast<int>(vecs_.size()); + int numGrads = static_cast<int>(grads_.size()); + + ::std::vector<double> vecsArg(numVecs); + ::std::vector<WorldVector<double> > gradsArg(numGrads); + + for(iq = 0; iq < numPoints; iq++) { + for(i = 0; i < numVecs; i++) { + vecsArg[i] = vecsAtQPs_[i][iq]; + } + for(i = 0; i < numGrads; i++) { + gradsArg[i] = gradsAtQPs_[i][iq]; + } + result[iq] += fac * (*f_)(coordsAtQPs_[iq], elementNormal_, vecsArg, gradsArg) * uhAtQP[iq]; + } + } + + void VecAndVecOfGradientsAtQP_ZOT::initElement(const ElInfo* elInfo, + SubAssembler* subAssembler, + Quadrature *quad) + { + int i, size = static_cast<int>(vecs.size()); + for (i = 0; i < size; i++) + { + gradsAtQPs[i] = subAssembler->getGradientsAtQPs(vecs[i], elInfo, quad); + } + vecAtQPs = subAssembler->getVectorAtQPs(vec, elInfo, quad); + } + + void VecAndVecOfGradientsAtQP_ZOT::getC(const ElInfo *, int numPoints, + double *C) const + { + int i, size = static_cast<int>(vecs.size()); + + std::vector<WorldVector<double>*> arg(size); + + int iq; + for (iq = 0; iq < numPoints; iq++) + { + for (i = 0; i < size; i++) + { + arg[i] = &(gradsAtQPs[i][iq]); + } + C[iq] += (*f)(vecAtQPs[iq], arg); + } + } + + void VecAndVecOfGradientsAtQP_ZOT::eval(int numPoints, + const double *uhAtQP, + const WorldVector<double> *grdUhAtQP, + const WorldMatrix<double> *D2UhAtQP, + double *result, + double fac) const + { + int i, size = static_cast<int>(vecs.size()); + + std::vector<WorldVector<double>*> arg(size); + + int iq; + for (iq = 0; iq < numPoints; iq++) + { + for (i = 0; i < size; i++) + { + arg[i] = &(gradsAtQPs[i][iq]); + } + result[iq] += fac * (*f)(vecAtQPs[iq], arg) * uhAtQP[iq]; + } + } + + +} diff --git a/AMDiS/src/Operator.h b/AMDiS/src/Operator.h new file mode 100644 index 0000000000000000000000000000000000000000..e83b7fc4dede578f39a810322891d161c514b02c --- /dev/null +++ b/AMDiS/src/Operator.h @@ -0,0 +1,3825 @@ +// ============================================================================ +// == == +// == AMDiS - Adaptive multidimensional simulations == +// == == +// ============================================================================ +// == == +// == crystal growth group == +// == == +// == Stiftung caesar == +// == Ludwig-Erhard-Allee 2 == +// == 53175 Bonn == +// == germany == +// == == +// ============================================================================ +// == == +// == http://www.caesar.de/cg/AMDiS == +// == == +// ============================================================================ + +/** \file Operator.h */ + +#ifndef AMDIS_OPERATOR_H +#define AMDIS_OPERATOR_H + +#include <vector> +#include "FixVec.h" +#include "Flag.h" +#include "MemoryManager.h" +#include "MatrixVector.h" +#include "ElInfo.h" +#include "AbstractFunction.h" + +namespace AMDiS { + + class Assembler; + class ElInfo; + class FiniteElemSpace; + class Operator; + class SubAssembler; + class ElementMatrix; + class ElementVector; + class Quadrature; + template<typename T> class DOFVectorBase; + + /** + * \ingroup Assembler + * \brief + * Specifies the type of a FirstOrderTerm + */ + enum FirstOrderType { + GRD_PSI, + GRD_PHI + }; + + // ============================================================================ + // ===== class OperatorTerm =================================================== + // ============================================================================ + + /** + * \ingroup Assembler + * + * \brief + * Base class for ZeroOrderTerm, FirstOrderTerm and SecondOrderTerm. + * OperatorTerms are the building blocks of an Operator. Each OperatorTerm + * has its properties which are regarded, when constructing + * an Assembler for the corresponding Operator. + */ + class OperatorTerm + { + public: + MEMORY_MANAGED(OperatorTerm); + + /** \brief + * Constructs an OperatorTerm with initially no properties. + * degree_ is used to determine the degree of the needed quadrature + * for the assemblage. + */ + OperatorTerm(int degree_) + : properties(0), + degree(degree_) + {}; + + /** \brief + * Destructor. + */ + virtual ~OperatorTerm() {}; + + /** \brief + * Virtual method. It's called by SubAssembler::initElement() for + * each OperatorTerm belonging to this SubAssembler. Here e.g. vectors + * and coordinates at quadrature points can be calculated. + */ + virtual void initElement(const ElInfo*, + SubAssembler* , + Quadrature *quad= NULL) + {}; + + /** \brief + * Specifies whether the matrix of the term is symmetric + */ + void setSymmetric(bool symm); + + /** \brief + * Returns true, if the term is piecewise constant, returns false otherwise + */ + inline bool isPWConst() { return (degree == 0);}; + + /** \brief + * Returns true, if the term has a symmetric matrix, + * returns false otherwise. + */ + bool isSymmetric(); + + /** \brief + * Returns \ref degree. + */ + inline int getDegree() { return degree; }; + + /** \brief + * Evaluation of the OperatorTerm at all quadrature points. + */ + virtual void eval(int numPoints, + const double *uhAtQP, + const WorldVector<double> *grdUhAtQP, + const WorldMatrix<double> *D2UhAtQP, + double *result, + double factor) const = 0; + + protected: + /** \brief + * Evaluation of \f$ \Lambda \cdot A \cdot \Lambda^t\f$. + */ + static void lalt(const DimVec<WorldVector<double> >& Lambda, + const WorldMatrix<double>& matrix, + DimMat<double>& LALt, + bool symm, + double factor); + + /** \brief + * Evaluation of \f$ \Lambda \cdot A \cdot \Lambda^t\f$ for \f$ A \f$ + * the matrix having a ONE in the position \f$ (K,L) \f$ + * and ZEROS in all other positions. + */ + static void lalt_kl(const DimVec<WorldVector<double> >& Lambda, + int k, int l, + DimMat<double>& LALt, + double factor); + + /** \brief + * Evaluation of \f$ \Lambda \cdot A \cdot \Lambda^t\f$ for A equal to the + * identity. + */ + static void l1lt(const DimVec<WorldVector<double> >& Lambda, + DimMat<double>& LALt, + double factor); + + /** \brief + * Evaluation of \f$ \Lambda \cdot b\f$. + */ + static void lb(const DimVec<WorldVector<double> >& Lambda, + const WorldVector<double>& b, + DimVec<double>& Lb, + double factor); + + /** \brief + * Evaluation of \f$ \Lambda \cdot b\f$ if b contains the value 1.0 in + * each component. + */ + static void l1(const DimVec<WorldVector<double> >& Lambda, + DimVec<double>& Lb, + double factor) + { + int dim = Lb.getSize() - 1; + static const int dimOfWorld = Global::getGeo(WORLD); + + for (int i = 0; i <= dim; i++) { + double val = 0.0; + + for (int j = 0; j < dimOfWorld; j++) { + val += Lambda[i][j]; + } + val *= factor; + Lb[i] += val; + } + }; + + protected: + /** \brief + * Stores the properties of this OperatorTerm + */ + Flag properties; + + /** \brief + * Polynomial degree of the term. Used to detemine the degree of the + * quadrature. + */ + int degree; + + /** \brief + * Pointer to the Operator this OperatorTerm belongs to. + */ + Operator* operat; + + /** \brief + * Constant Flag for piecewise constant terms + */ + static const Flag PW_CONST; + + /** \brief + * Constant Flag for symmetric terms + */ + static const Flag SYMMETRIC; + + friend class SubAssembler; + friend class ZeroOrderAssembler; + friend class FirstOrderAssembler; + friend class SecondOrderAssembler; + friend class Operator; + }; + + // ============================================================================ + // ===== class SecondOrderTerm =============================================== + // ============================================================================ + + /** + * \ingroup Assembler + * + * \brief + * Describes the second order terms: \f$ \nabla \cdot A \nabla u(\vec{x}) \f$ + */ + class SecondOrderTerm : public OperatorTerm + { + public: + /** \brief + * Constructor. + */ + SecondOrderTerm(int deg) : OperatorTerm(deg) {}; + + /** \brief + * Destructor. + */ + virtual ~SecondOrderTerm() {}; + + /** \brief + * Evaluation of \f$ \Lambda A \Lambda^t \f$ at all quadrature points. + */ + virtual void getLALt(const ElInfo *elInfo, + int numPoints, + DimMat<double> **result) const = 0; + + /** \brief + * Evaluation of \f$ A \nabla u(\vec{x}) \f$ at all quadrature points. + */ + virtual void weakEval(int numPoints, + const WorldVector<double> *grdUhAtQP, + WorldVector<double> *result) const = 0; + + }; + + // ============================================================================ + + /** + * \ingroup Assembler + * + * \brief + * Implements the laplace operator: \f$ \Delta u(\vec{x}) \f$ + */ + class Laplace_SOT : public SecondOrderTerm + { + public: + /** \brief + * Constructor. + */ + Laplace_SOT() + : SecondOrderTerm(0) + { + setSymmetric(true); + }; + + /** \brief + * Implenetation of SecondOrderTerm::getLALt(). + */ + inline void getLALt(const ElInfo *elInfo, int numPoints, DimMat<double> **LALt) const + { + const DimVec<WorldVector<double> > &Lambda = elInfo->getGrdLambda(); + + for (int iq = 0; iq < numPoints; iq++) { + l1lt(Lambda, *(LALt[iq]), 1.0); + } + }; + + /** \brief + * Implementation of SecondOrderTerm::eval(). + */ + inline void eval(int numPoints, + const double * // uhAtQP + , const WorldVector<double>*// grdUhAtQP + , const WorldMatrix<double> *D2UhAtQP, + double *result, + double factor) const + { + int dow = Global::getGeo(WORLD); + + if (D2UhAtQP) { + for (int iq = 0; iq < numPoints; iq++) { + double resultQP = 0.0; + for (int i = 0; i < dow; i++) { + resultQP += D2UhAtQP[iq][i][i]; + } + result[iq] += factor * resultQP; + } + } + }; + + /** \brief + * Implenetation of SecondOrderTerm::weakEval(). + */ + void weakEval(int numPoints, + const WorldVector<double> *grdUhAtQP, + WorldVector<double> *result) const + { + if (grdUhAtQP) { + for (int iq = 0; iq < numPoints; iq++) { + result[iq] += grdUhAtQP[iq]; + } + } + }; + }; + + // ============================================================================ + + /** + * \ingroup Assembler + * + * \brief + * Implements the laplace operator multiplied with a scalar factor: + * \f$ f \cdot \Delta u(\vec{x}) \f$ + */ + class FactorLaplace_SOT : public SecondOrderTerm + { + public: + /** \brief + * Constructor. + */ + FactorLaplace_SOT(double f) + : SecondOrderTerm(0) { + factor = new double; + *factor = f; + + setSymmetric(true); + }; + + /** \brief + * Constructor. + */ + FactorLaplace_SOT(double *fptr) + : SecondOrderTerm(0), factor(fptr) + { + setSymmetric(true); + }; + + /** \brief + * Implements SecondOrderTerm::getLALt(). + */ + inline void getLALt(const ElInfo *elInfo, int numPoints, DimMat<double> **LALt) const + { + const DimVec<WorldVector<double> > &Lambda = elInfo->getGrdLambda(); + //double det = elInfo->getDet(); + int iq; + for(iq = 0; iq < numPoints; iq++) + l1lt(Lambda, *(LALt[iq]), (*factor)); + }; + + + /** \brief + * Implenetation of SecondOrderTerm::eval(). + */ + void eval(int numPoints, + const double *, + const WorldVector<double> *, + const WorldMatrix<double> *D2UhAtQP, + double *result, + double f) const + { + int i, dow = Global::getGeo(WORLD); + int iq; + + if(D2UhAtQP) { + for(iq = 0; iq < numPoints; iq++) { + double resultQP = 0.0; + for(i=0; i < dow; i++) { + resultQP += D2UhAtQP[iq][i][i]; + } + result[iq] += resultQP * f * (*factor); + } + } + }; + + /** \brief + * Implenetation of SecondOrderTerm::weakEval(). + */ + void weakEval(int numPoints, + const WorldVector<double> *grdUhAtQP, + WorldVector<double> *result) const + { + int iq; + if(grdUhAtQP) { + for(iq = 0; iq < numPoints; iq++) { + axpy(*factor, grdUhAtQP[iq], result[iq]); + } + } + }; + + private: + /** \brief + * Pointer to the factor. + */ + double *factor; + }; + + // ============================================================================ + + /** + * \ingroup Assembler + * + * \brief + * SecondOrderTerm where A is a function which maps a DOFVector evaluated at + * a given quadrature point to a WolrdMatrix: + * \f$ \nabla \cdot A(v(\vec{x})) \nabla u(\vec{x}) \f$ + */ + class MatrixFct_SOT : public SecondOrderTerm + { + public: + /** \brief + * Constructor. + */ + MatrixFct_SOT(DOFVectorBase<double> *dv, + AbstractFunction<WorldMatrix<double>, double> *fct, + AbstractFunction<WorldVector<double>, WorldMatrix<double> > *div, + bool sym = false) + : SecondOrderTerm(fct->getDegree()), + vec(dv), + matrixFct(fct), + divFct(div), + symmetric(sym) + { + setSymmetric(symmetric); + }; + + /** \brief + * Implementation of \ref OperatorTerm::initElement(). + */ + void initElement(const ElInfo* elInfo, SubAssembler* subAssembler, + Quadrature *quad = NULL); + + /** \brief + * Implements SecondOrderTerm::getLALt(). + */ + void getLALt(const ElInfo *elInfo, int numPoints, DimMat<double> **LALt) const; + + /** \brief + * Implenetation of SecondOrderTerm::eval(). + */ + void eval(int numPoints, + const double *uhAtQP, + const WorldVector<double> *grdUhAtQP, + const WorldMatrix<double> *D2UhAtQP, + double *result, + double factor) const; + + /** \brief + * Implenetation of SecondOrderTerm::weakEval(). + */ + void weakEval(int numPoints, + const WorldVector<double> *grdUhAtQP, + WorldVector<double> *result) const; + + protected: + /** \brief + * DOFVector to be evaluated at quadrature points. + */ + DOFVectorBase<double>* vec; + + /** \brief + * Pointer to the values of the DOFVector at quadrature points. + */ + double* vecAtQPs; + + /** \brief + * Function for A. + */ + AbstractFunction<WorldMatrix<double>, double>* matrixFct; + + AbstractFunction<WorldVector<double>, WorldMatrix<double> >* divFct; + + /** \brief + * True, if \ref matrixFct produces always symmetric matrices. + */ + bool symmetric; + }; + + // ============================================================================ + + /** + * \ingroup Assembler + * + * \brief + * SecondOrderTerm where A is a given fixed WorldMatrix<double>: + * \f$ \nabla \cdot A \nabla u(\vec{x}) \f$ + */ + class Matrix_SOT : public SecondOrderTerm { + public: + /** \brief + * Constructor + */ + Matrix_SOT(WorldMatrix<double> mat) + : SecondOrderTerm(0), matrix(mat) + { + symmetric = matrix.isSymmetric(); + setSymmetric(symmetric); + }; + + /** \brief + * Implements SecondOrderTerm::getLALt(). + */ + inline void getLALt(const ElInfo *elInfo, int numPoints, DimMat<double> **LALt) const{ + const DimVec<WorldVector<double> >& Lambda = elInfo->getGrdLambda(); + //double det = elInfo->getDet(); + int iq; + for(iq = 0; iq < numPoints; iq++) + lalt(Lambda, matrix, *(LALt[iq]), symmetric, 1.0); + }; + + /** \brief + * Implenetation of SecondOrderTerm::eval(). + */ + void eval(int numPoints, + const double *uhAtQP, + const WorldVector<double> *grdUhAtQP, + const WorldMatrix<double> *D2UhAtQP, + double *result, + double factor) const; + + /** \brief + * Implenetation of SecondOrderTerm::weakEval(). + */ + void weakEval(int numPoints, + const WorldVector<double> *grdUhAtQP, + WorldVector<double> *result) const; + + protected: + /** \brief + * Matrix stroring A. + */ + WorldMatrix<double> matrix; + + /** \brief + * True, if \ref matrix is symmetric. + */ + bool symmetric; + }; + + // ============================================================================ + + /** + * \ingroup Assembler + * + * \brief + * SecondOrderTerm where A is a WorldMatrix<double> having a ONE in position IJ + * and ZERO in all other positions + * \f$ \nabla \cdot A \nabla u(\vec{x}) \f$ + */ + class FactorIJ_SOT : public SecondOrderTerm + { + public: + /** \brief + * Constructor. + */ + FactorIJ_SOT(int x_i, int x_j, double f) + : SecondOrderTerm(0), xi(x_i), xj(x_j) + { + factor = new double; + *factor = f; + + setSymmetric(xi == xj); + }; + + /** \brief + * Constructor. + */ + FactorIJ_SOT(int x_i, int x_j, double *fptr) + : SecondOrderTerm(0), xi(x_i), xj(x_j), factor(fptr) + { + setSymmetric(xi == xj); + }; + + /** \brief + * Implements SecondOrderTerm::getLALt(). + */ + inline void getLALt(const ElInfo *elInfo, int numPoints, DimMat<double> **LALt) const + { + const DimVec<WorldVector<double> > &Lambda = elInfo->getGrdLambda(); + int iq; + for(iq = 0; iq < numPoints; iq++) + lalt_kl(Lambda, xi, xj, *(LALt[iq]), (*factor)); + }; + + /** \brief + * Implenetation of SecondOrderTerm::eval(). + */ + void eval(int numPoints, + const double *, + const WorldVector<double> *, + const WorldMatrix<double> *D2UhAtQP, + double *result, + double fac) const + { + int iq; + if(D2UhAtQP) { + for(iq = 0; iq < numPoints; iq++) { + result[iq] += (*factor) * D2UhAtQP[iq][xi][xj] * fac; + } + } + }; + + /** \brief + * Implenetation of SecondOrderTerm::weakEval(). + */ + void weakEval(int numPoints, + const WorldVector<double> *grdUhAtQP, + WorldVector<double> *result) const + { + if(grdUhAtQP) { + int iq; + for(iq = 0; iq < numPoints; iq++) { + result[iq][xi] += (*factor) * grdUhAtQP[iq][xj]; + } + } + }; + + private: + /** \brief + * Directions for the derivatives. + */ + int xi, xj; + + /** \brief + * Pointer to the factor. + */ + double *factor; + }; + + // ============================================================================ + + /** + * \ingroup Assembler + * + * \brief + * Laplace operator multiplied with a function evaluated at the quadrature + * points of a given DOFVector: + * \f$ f(v(\vec{x})) \Delta u(\vec{x}) \f$ + */ + class VecAtQP_SOT : public SecondOrderTerm { + public: + /** \brief + * Constructor. + */ + VecAtQP_SOT(DOFVectorBase<double> *dv, + AbstractFunction<double, double> *f_) + : SecondOrderTerm(f_->getDegree()), vec(dv), f(f_) + { + setSymmetric(true); + }; + + /** \brief + * Implementation of \ref OperatorTerm::initElement(). + */ + void initElement(const ElInfo* elInfo, SubAssembler* subAssembler, + Quadrature *quad = NULL); + + /** \brief + * Implements SecondOrderTerm::getLALt(). + */ + void getLALt(const ElInfo *elInfo, int numPoints, DimMat<double> **LALt) const; + + /** \brief + * Implenetation of SecondOrderTerm::eval(). + */ + void eval(int numPoints, + const double *uhAtQP, + const WorldVector<double> *grdUhAtQP, + const WorldMatrix<double> *D2UhAtQP, + double *result, + double factor) const; + + /** \brief + * Implenetation of SecondOrderTerm::weakEval(). + */ + void weakEval(int numPoints, + const WorldVector<double> *grdUhAtQP, + WorldVector<double> *result) const; + + protected: + /** \brief + * DOFVector to be evaluated at quadrature points. + */ + DOFVectorBase<double>* vec; + + /** \brief + * Pointer to an array containing the DOFVector evaluated at quadrature + * points. + */ + double* vecAtQPs; + + /** \brief + * Function evaluated at \ref vecAtQPs. + */ + AbstractFunction<double, double> *f; + }; + + // ============================================================================ + + /** + * \ingroup Assembler + * + * \brief + * Laplace multiplied with a function evaluated at each quadrature point: + * \f$ f(\vec{x}) \Delta u(\vec{x}) \f$ + */ + class CoordsAtQP_SOT : public SecondOrderTerm { + public: + /** \brief + * Constructor. + */ + CoordsAtQP_SOT(AbstractFunction<double, WorldVector<double> > *g_) + : SecondOrderTerm(g_->getDegree()), g(g_) + { + setSymmetric(true); + }; + + /** \brief + * Implementation of \ref OperatorTerm::initElement(). + */ + void initElement(const ElInfo* elInfo, SubAssembler* subAssembler, + Quadrature *quad = NULL); + + /** \brief + * Implements SecondOrderTerm::getLALt(). + */ + void getLALt(const ElInfo *elInfo, int numPoints, DimMat<double> **LALt) const; + + /** \brief + * Implenetation of SecondOrderTerm::eval(). + */ + void eval(int numPoints, + const double *uhAtQP, + const WorldVector<double> *grdUhAtQP, + const WorldMatrix<double> *D2UhAtQP, + double *result, + double factor) const; + + /** \brief + * Implenetation of SecondOrderTerm::weakEval(). + */ + void weakEval(int numPoints, + const WorldVector<double> *grdUhAtQP, + WorldVector<double> *result) const; + + + protected: + /** \brief + * Stores coordinates at quadrature points. Set in \ref initElement(). + */ + WorldVector<double>* coordsAtQPs; + + /** \brief + * Function evaluated at quadrature points. + */ + AbstractFunction<double, WorldVector<double> > *g; + }; + + // ============================================================================ + + /** + * \ingroup Assembler + * + * \brief + * SecondOrderTerm where A is a function which maps the gradient of a + * DOFVector at each quadrature point to WorldMatrix<double>: + * \f$ \nabla \cdot A(\nabla v(\vec{x})) \nabla u(\vec{x})\f$ + */ + class MatrixGradient_SOT : public SecondOrderTerm + { + public: + /** \brief + * Constructor. + */ + MatrixGradient_SOT(DOFVectorBase<double> *dv, + AbstractFunction<WorldMatrix<double>, WorldVector<double> > *f_, + AbstractFunction<WorldVector<double>, WorldMatrix<double> > *divFct_, + bool symm = false) + : SecondOrderTerm(f_->getDegree()), vec(dv), f(f_), divFct(divFct_), symmetric(symm) + { + setSymmetric(symmetric); + }; + + /** \brief + * Implementation of \ref OperatorTerm::initElement(). + */ + void initElement(const ElInfo* elInfo, SubAssembler* subAssembler, + Quadrature *quad = NULL); + + /** \brief + * Implements SecondOrderTerm::getLALt(). + */ + void getLALt(const ElInfo *elInfo, int numPoints, DimMat<double> **LALt) const; + + /** \brief + * Implenetation of SecondOrderTerm::eval(). + */ + void eval(int numPoints, + const double *uhAtQP, + const WorldVector<double> *grdUhAtQP, + const WorldMatrix<double> *D2UhAtQP, + double *result, + double factor) const; + + /** \brief + * Implenetation of SecondOrderTerm::weakEval(). + */ + void weakEval(int numPoints, + const WorldVector<double> *grdUhAtQP, + WorldVector<double> *result) const; + + protected: + DOFVectorBase<double>* vec; + + /** \brief + * Function which maps each entry in \ref gradAtQPs to a WorldMatrix<double>. + */ + AbstractFunction<WorldMatrix<double>, WorldVector<double> > *f; + + AbstractFunction<WorldVector<double>, WorldMatrix<double> > *divFct; + + /** \brief + * Pointer to a WorldVector<double> array containing the gradients of the DOFVector + * at each quadrature point. + */ + WorldVector<double>* gradAtQPs; + + /** \brief + * True, if \ref f provides always a symmetric WorldMatrix<double>. + */ + bool symmetric; + }; + + // ============================================================================ + + /** + * \ingroup Assembler + * + * \brief + * Laplace multiplied with a function which maps the gradient of a DOFVector + * at each quadrature point to a double: + * \f$ f(\nabla v(\vec{x})) \Delta u(\vec{x}) \f$ + */ + class FctGradient_SOT : public SecondOrderTerm + { + public: + /** \brief + * Constructor. + */ + FctGradient_SOT(DOFVectorBase<double> *dv, + AbstractFunction<double, WorldVector<double> > *f_) + : SecondOrderTerm(f_->getDegree()), vec(dv), f(f_) + { + }; + + /** \brief + * Implementation of \ref OperatorTerm::initElement(). + */ + void initElement(const ElInfo* elInfo, SubAssembler* subAssembler, + Quadrature *quad = NULL); + + /** \brief + * Implements SecondOrderTerm::getLALt(). + */ + void getLALt(const ElInfo *elInfo, int numPoints, DimMat<double> **LALt) const; + + /** \brief + * Implenetation of SecondOrderTerm::eval(). + */ + void eval(int numPoints, + const double *uhAtQP, + const WorldVector<double> *grdUhAtQP, + const WorldMatrix<double> *D2UhAtQP, + double *result, + double factor) const; + + /** \brief + * Implenetation of SecondOrderTerm::weakEval(). + */ + void weakEval(int numPoints, + const WorldVector<double> *grdUhAtQP, + WorldVector<double> *result) const; + + protected: + DOFVectorBase<double>* vec; + + /** \brief + * Function wich maps \ref gradAtQPs to a double. + */ + AbstractFunction<double, WorldVector<double> > *f; + + /** \brief + * Pointer to a WorldVector<double> array containing the gradients of the DOFVector + * at each quadrature point. + */ + WorldVector<double>* gradAtQPs; + }; + + + // Ergaenzung Andreas + + // ============================================================================ + + /** + * \ingroup Assembler + * + * \brief + * Laplace multiplied with a function which maps the gradient of a DOFVector + * at each quadrature point to a double: + * \f$ f(\nabla v(\vec{x})) \Delta u(\vec{x}) \f$ + */ + class VecAndGradientAtQP_SOT : public SecondOrderTerm + { + public: + /** \brief + * Constructor. + */ + VecAndGradientAtQP_SOT(DOFVectorBase<double> *dv, + BinaryAbstractFunction<double, double, + WorldVector<double> > *f_) + : SecondOrderTerm(f_->getDegree()), vec(dv), f(f_) + { + }; + + /** \brief + * Implementation of \ref OperatorTerm::initElement(). + */ + void initElement(const ElInfo* elInfo, SubAssembler* subAssembler, + Quadrature *quad = NULL); + + /** \brief + * Implements SecondOrderTerm::getLALt(). + */ + void getLALt(const ElInfo *elInfo, int numPoints, DimMat<double> **LALt) const; + + /** \brief + * Implenetation of SecondOrderTerm::eval(). + */ + void eval(int numPoints, + const double *uhAtQP, + const WorldVector<double> *grdUhAtQP, + const WorldMatrix<double> *D2UhAtQP, + double *result, + double factor) const; + + /** \brief + * Implenetation of SecondOrderTerm::weakEval(). + */ + void weakEval(int numPoints, + const WorldVector<double> *grdUhAtQP, + WorldVector<double> *result) const; + + protected: + DOFVectorBase<double>* vec; + + /** \brief + * Function wich maps \ref gradAtQPs to a double. + */ + BinaryAbstractFunction<double, double, WorldVector<double> > *f; + + /** \brief + * Pointer to a WorldVector<double> array containing the gradients of the DOFVector + * at each quadrature point. + */ + double* vecAtQPs; + WorldVector<double>* gradAtQPs; + }; + + + // ============================================================================ + + /** + * \ingroup Assembler + * + * \brief + * Laplace multiplied with a function which maps the gradient of a DOFVector + * at each quadrature point to a double: + * \f$ f(\nabla v(\vec{x})) \Delta u(\vec{x}) \f$ + */ + class VecGradCoordsAtQP_SOT : public SecondOrderTerm + { + public: + /** \brief + * Constructor. + */ + VecGradCoordsAtQP_SOT(DOFVectorBase<double> *dv, + TertiaryAbstractFunction<double, double, + WorldVector<double>, + WorldVector<double> > *f_) + : SecondOrderTerm(f_->getDegree()), vec(dv), f(f_) + { + }; + + /** \brief + * Implementation of \ref OperatorTerm::initElement(). + */ + void initElement(const ElInfo* elInfo, SubAssembler* subAssembler, + Quadrature *quad = NULL); + + /** \brief + * Implements SecondOrderTerm::getLALt(). + */ + void getLALt(const ElInfo *elInfo, int numPoints, DimMat<double> **LALt) const; + + /** \brief + * Implenetation of SecondOrderTerm::eval(). + */ + void eval(int numPoints, + const double *uhAtQP, + const WorldVector<double> *grdUhAtQP, + const WorldMatrix<double> *D2UhAtQP, + double *result, + double factor) const; + + /** \brief + * Implenetation of SecondOrderTerm::weakEval(). + */ + void weakEval(int numPoints, + const WorldVector<double> *grdUhAtQP, + WorldVector<double> *result) const; + + protected: + DOFVectorBase<double>* vec; + + /** \brief + * Function wich maps \ref gradAtQPs to a double. + */ + TertiaryAbstractFunction<double, double, WorldVector<double>, + WorldVector<double> > *f; + + /** \brief + * Pointer to a WorldVector<double> array containing the gradients of the DOFVector + * at each quadrature point. + */ + double* vecAtQPs; + WorldVector<double>* gradAtQPs; + WorldVector<double>* coordsAtQPs; + + }; + + + // ============================================================================ + + /** + * \ingroup Assembler + * + * \brief + * Laplace operator multiplied with a function evaluated at the quadrature + * points of a given DOFVector: + * \f$ -f(v(\vec{x})) \Delta u(\vec{x}) \f$ + */ + class VecAndCoordsAtQP_SOT : public SecondOrderTerm { + public: + /** \brief + * Constructor. + */ + VecAndCoordsAtQP_SOT(DOFVectorBase<double> *dv, + BinaryAbstractFunction<double, double, WorldVector<double> > *f_) + : SecondOrderTerm(f_->getDegree()), vec(dv), f(f_) + { + setSymmetric(true); + }; + + /** \brief + * Implementation of \ref OperatorTerm::initElement(). + */ + void initElement(const ElInfo* elInfo, SubAssembler* subAssembler, + Quadrature *quad = NULL); + + /** \brief + * Implements SecondOrderTerm::eval(). + */ + void getLALt(const ElInfo *elInfo, int numPoints, DimMat<double> **LALt) const; + + void eval(int numPoints, + const double *uhAtQP, + const WorldVector<double> *grdUhAtQP, + const WorldMatrix<double> *D2UhAtQP, + double *result, + double factor) const; + + void weakEval(int numPoints, + const WorldVector<double> *grdUhAtQP, + WorldVector<double> *result) const; + + protected: + /** \brief + * DOFVector to be evaluated at quadrature points. + */ + DOFVectorBase<double>* vec; + + /** \brief + * Pointer to an array containing the DOFVector evaluated at quadrature + * points. + */ + double* vecAtQPs; + + WorldVector<double>* coordsAtQPs; + + /** \brief + * Function evaluated at \ref vecAtQPs. + */ + BinaryAbstractFunction<double, double, WorldVector<double> > *f; + }; + + // ============================================================================ + + /** + * \ingroup Assembler + * + * \brief + * SecondOrderTerm where A is a function which maps the gradient of a + * DOFVector at each quadrature point to WorldMatrix<double>: + * \f$ \nabla \cdot A(\nabla v(\vec{x})) \nabla u(\vec{x})\f$ + */ + class MatrixGradientAndCoords_SOT : public SecondOrderTerm + { + public: + /** \brief + * Constructor. + */ + MatrixGradientAndCoords_SOT(DOFVectorBase<double> *dv, + BinaryAbstractFunction<WorldMatrix<double>, + WorldVector<double> , + WorldVector<double> > *f_, + AbstractFunction<WorldVector<double>, + WorldMatrix<double> > *divFct_, + bool symm = false) + : SecondOrderTerm(f_->getDegree()), vec(dv), f(f_), divFct(divFct_), symmetric(symm) + { + setSymmetric(symmetric); + }; + + /** \brief + * Implementation of \ref OperatorTerm::initElement(). + */ + void initElement(const ElInfo* elInfo, SubAssembler* subAssembler, + Quadrature *quad = NULL); + + /** \brief + * Implements SecondOrderTerm::getLALt(). + */ + void getLALt(const ElInfo *elInfo, int numPoints, DimMat<double> **LALt) const; + + /** \brief + * Implenetation of SecondOrderTerm::eval(). + */ + void eval(int numPoints, + const double *uhAtQP, + const WorldVector<double> *grdUhAtQP, + const WorldMatrix<double> *D2UhAtQP, + double *result, + double factor) const; + + /** \brief + * Implenetation of SecondOrderTerm::weakEval(). + */ + void weakEval(int numPoints, + const WorldVector<double> *grdUhAtQP, + WorldVector<double> *result) const; + + protected: + DOFVectorBase<double>* vec; + + /** \brief + * Function which maps each entry in \ref gradAtQPs to a WorldMatrix<double>. + */ + BinaryAbstractFunction<WorldMatrix<double>, + WorldVector<double>, WorldVector<double> > *f; + + AbstractFunction<WorldVector<double>, WorldMatrix<double> > *divFct; + + /** \brief + * Pointer to a WorldVector<double> array containing the gradients of the DOFVector + * at each quadrature point. + */ + WorldVector<double>* gradAtQPs; + + WorldVector<double>* coordsAtQPs; + + /** \brief + * True, if \ref f provides always a symmetric WorldMatrix<double>. + */ + bool symmetric; + }; + + // Ende Andreas Ergaenzung + + // ============================================================================ + + class General_SOT : public SecondOrderTerm + { + public: + General_SOT(::std::vector<DOFVectorBase<double>*> vecs, + ::std::vector<DOFVectorBase<double>*> grads, + TertiaryAbstractFunction<WorldMatrix<double>, + WorldVector<double>, + ::std::vector<double>, + ::std::vector<WorldVector<double> > > *f, + AbstractFunction<WorldVector<double>, + WorldMatrix<double> > *divFct, + bool symmetric) + : SecondOrderTerm(f->getDegree()), + vecs_(vecs), + grads_(grads), + f_(f), + divFct_(divFct), + symmetric_(symmetric) + { + vecsAtQPs_.resize(vecs_.size()); + gradsAtQPs_.resize(grads_.size()); + }; + + /** \brief + * Implementation of \ref OperatorTerm::initElement(). + */ + void initElement(const ElInfo*, + SubAssembler* , + Quadrature *quad= NULL); + + /** \brief + * Implements SecondOrderTerm::getLALt(). + */ + void getLALt(const ElInfo *elInfo, int numPoints, DimMat<double> **LALt) const; + + /** \brief + * Implenetation of SecondOrderTerm::eval(). + */ + void eval(int numPoints, + const double *uhAtQP, + const WorldVector<double> *grdUhAtQP, + const WorldMatrix<double> *D2UhAtQP, + double *result, + double factor) const; + + /** \brief + * Implenetation of SecondOrderTerm::weakEval(). + */ + void weakEval(int numPoints, + const WorldVector<double> *grdUhAtQP, + WorldVector<double> *result) const; + + protected: + ::std::vector<DOFVectorBase<double>*> vecs_; + + ::std::vector<DOFVectorBase<double>*> grads_; + + TertiaryAbstractFunction<WorldMatrix<double>, + WorldVector<double>, + ::std::vector<double>, + ::std::vector<WorldVector<double> > > *f_; + + AbstractFunction<WorldVector<double>, + WorldMatrix<double> > *divFct_; + + WorldVector<double> *coordsAtQPs_; + + ::std::vector<double*> vecsAtQPs_; + + ::std::vector<WorldVector<double>*> gradsAtQPs_; + + bool symmetric_; + }; + + + // ============================================================================ + + class GeneralParametric_SOT : public SecondOrderTerm + { + public: + GeneralParametric_SOT(::std::vector<DOFVectorBase<double>*> vecs, + ::std::vector<DOFVectorBase<double>*> grads, + QuartAbstractFunction<WorldMatrix<double>, + WorldVector<double>, + WorldVector<double>, + ::std::vector<double>, + ::std::vector<WorldVector<double> > > *f, + AbstractFunction<WorldVector<double>, + WorldMatrix<double> > *divFct, + bool symmetric) + : SecondOrderTerm(f->getDegree()), + vecs_(vecs), + grads_(grads), + f_(f), + divFct_(divFct), + symmetric_(symmetric) + { + vecsAtQPs_.resize(vecs_.size()); + gradsAtQPs_.resize(grads_.size()); + }; + + /** \brief + * Implementation of \ref OperatorTerm::initElement(). + */ + void initElement(const ElInfo*, + SubAssembler* , + Quadrature *quad= NULL); + + /** \brief + * Implements SecondOrderTerm::getLALt(). + */ + void getLALt(const ElInfo *elInfo, int numPoints, DimMat<double> **LALt) const; + + /** \brief + * Implenetation of SecondOrderTerm::eval(). + */ + void eval(int numPoints, + const double *uhAtQP, + const WorldVector<double> *grdUhAtQP, + const WorldMatrix<double> *D2UhAtQP, + double *result, + double factor) const; + + /** \brief + * Implenetation of SecondOrderTerm::weakEval(). + */ + void weakEval(int numPoints, + const WorldVector<double> *grdUhAtQP, + WorldVector<double> *result) const; + + protected: + ::std::vector<DOFVectorBase<double>*> vecs_; + + ::std::vector<DOFVectorBase<double>*> grads_; + + QuartAbstractFunction<WorldMatrix<double>, + WorldVector<double>, + WorldVector<double>, + ::std::vector<double>, + ::std::vector<WorldVector<double> > > *f_; + + AbstractFunction<WorldVector<double>, + WorldMatrix<double> > *divFct_; + + WorldVector<double> *coordsAtQPs_; + WorldVector<double> elementNormal_; + + ::std::vector<double*> vecsAtQPs_; + + ::std::vector<WorldVector<double>*> gradsAtQPs_; + + bool symmetric_; + }; + + + // ============================================================================ + // ===== class FirstOrderTerm ================================================= + // ============================================================================ + + /** + * \ingroup Assembler + * + * \brief + * Describes the first order terms: \f$ b \cdot \nabla u(\vec{x}) \f$ + */ + class FirstOrderTerm : public OperatorTerm + { + public: + /** \brief + * Constructor. + */ + FirstOrderTerm(int deg) + : OperatorTerm(deg) + {}; + + /** \brief + * Destructor. + */ + virtual ~FirstOrderTerm() {}; + + /** \brief + * Evaluation of \f$ \Lambda b \f$. + */ + virtual void getLb(const ElInfo *elInfo, + int numPoints, + VectorOfFixVecs<DimVec<double> >& result) const = 0; + + /** \brief + * Implenetation of FirstOrderTerm::eval(). + */ + void eval(int numPoints, + const double *, + const WorldVector<double> *grdUhAtQP, + const WorldMatrix<double> *, + double *result, + double factor) const + { + int dow = Global::getGeo(WORLD); + + if (grdUhAtQP) { + for (int iq = 0; iq < numPoints; iq++) { + double resultQP = 0.0; + for (int i = 0; i < dow; i++) { + resultQP += grdUhAtQP[iq][i]; + } + result[iq] += resultQP * factor; + } + } + }; + }; + + // ============================================================================ + + /** + * \ingroup Assembler + * + * \brief + * First order term: \f$ b \cdot \nabla u(\vec{x}) \f$ with a vector b which + * only consits of entries equal to one. + */ + class Simple_FOT : public FirstOrderTerm + { + public: + /** \brief + * Constructor. + */ + Simple_FOT() + : FirstOrderTerm(0) + {}; + + /** \brief + * Implements FirstOrderTerm::getLb(). + */ + inline void getLb(const ElInfo *elInfo, + int numPoints, + VectorOfFixVecs<DimVec<double> >& Lb) const + { + const DimVec<WorldVector<double> > &Lambda = elInfo->getGrdLambda(); + + for (int iq = 0; iq < numPoints; iq++) { + l1(Lambda, Lb[iq], 1.0); + } + }; + }; + + // ============================================================================ + + /** + * \ingroup Assembler + * + * \brief + * First order term: \f$ b \cdot \nabla u(\vec{x}) \f$ with a vector b which + * only consits of entries equal to one. + */ + class FactorSimple_FOT : public FirstOrderTerm + { + public: + /** \brief + * Constructors. + */ + FactorSimple_FOT(double f) : + FirstOrderTerm(0) + { + factor = NEW double; + *factor = f; + }; + + FactorSimple_FOT(double *fptr) + : FirstOrderTerm(0), + factor(fptr) + {}; + + /** \brief + * Implements FirstOrderTerm::getLb(). + */ + inline void getLb(const ElInfo *elInfo, int numPoints, VectorOfFixVecs<DimVec<double> >& Lb) const + { + const DimVec<WorldVector<double> > &Lambda = elInfo->getGrdLambda(); + + for (int iq = 0; iq < numPoints; iq++) { + l1(Lambda, Lb[iq], (*factor)); + } + }; + + private: + /** \brief + * Pointer to the factor. + */ + double *factor; + }; + + // ============================================================================ + + /** + * \ingroup Assembler + * + * \brief + * First order term: \f$ b \cdot \nabla u(\vec{x}) \f$ with a given vector b. + */ + class Vector_FOT : public FirstOrderTerm + { + public: + /** \brief + * Constructor. + */ + Vector_FOT(WorldVector<double> b_) + : FirstOrderTerm(0), b(b_) + { + }; + + /** \brief + * Implements FirstOrderTerm::getLb(). + */ + inline void getLb(const ElInfo *elInfo, + int numPoints, + VectorOfFixVecs<DimVec<double> >&Lb) const + { + const DimVec<WorldVector<double> > &Lambda = elInfo->getGrdLambda(); + + for (int iq = 0; iq < numPoints; iq++) { + lb(Lambda, b, Lb[iq], 1.0); + } + }; + + /** \brief + * Implements FirstOrderTerm::eval(). + */ + void eval(int numPoints, + const double *, + const WorldVector<double> *grdUhAtQP, + const WorldMatrix<double> *, + double *result, + double factor) const + { + if (grdUhAtQP) { + for(int iq = 0; iq < numPoints; iq++) { + result[iq] += b * grdUhAtQP[iq] * factor; + } + } + }; + + protected: + /** \brief + * Vector which is multiplied with \f$ \nabla u(\vec{x}) \f$ + */ + WorldVector<double> b; + }; + + // ============================================================================ + + /** + * \ingroup Assembler + * + * \brief + * Simple_FOT multiplied with \f$ f(v(\vec{x})) \f$. + */ + class VecAtQP_FOT : public FirstOrderTerm + { + public: + /** \brief + * Constructor. + */ + VecAtQP_FOT(DOFVectorBase<double> *dv, + AbstractFunction<double, double> *f_, + WorldVector<double> *b_) + : FirstOrderTerm(f_->getDegree()), vec(dv), f(f_), b(b_) + { + }; + + /** \brief + * Implementation of \ref OperatorTerm::initElement(). + */ + void initElement(const ElInfo* elInfo, SubAssembler* subAssembler, + Quadrature *quad = NULL); + + /** \brief + * Implements FirstOrderTerm::getLb(). + */ + void getLb(const ElInfo *elInfo, int numPoints, VectorOfFixVecs<DimVec<double> >& Lb) const; + + /** \brief + * Implements FirstOrderTerm::eval(). + */ + void eval(int numPoints, + const double *uhAtQP, + const WorldVector<double> *grdUhAtQP, + const WorldMatrix<double> *D2UhAtQP, + double *result, + double factor) const; + + protected: + /** \brief + * DOFVector to be evaluated at quadrature points. + */ + DOFVectorBase<double>* vec; + + /** \brief + * v at quadrature points. + */ + double *vecAtQPs; + + /** \brief + * Function f. + */ + AbstractFunction<double, double> *f; + + /** + */ + WorldVector<double> *b; + }; + + // ============================================================================ + + /** + * \ingroup Assembler + * + * \brief + * Simple_FOT multiplied with \f$ f(\vec{x}) \f$. + */ + class CoordsAtQP_FOT : public FirstOrderTerm + { + public: + /** \brief + * Constructor. + */ + CoordsAtQP_FOT(AbstractFunction<double, WorldVector<double> > *g_) + : FirstOrderTerm(g_->getDegree()), g(g_) + { + }; + + /** \brief + * Implementation of \ref OperatorTerm::initElement(). + */ + void initElement(const ElInfo* elInfo, SubAssembler* subAssembler, + Quadrature *quad = NULL); + + /** \brief + * Implements FistOrderTerm::getLb(). + */ + void getLb(const ElInfo *elInfo, int numPoints,VectorOfFixVecs<DimVec<double> >&Lb) const; + + /** \brief + * Implements FirstOrderTerm::eval(). + */ + void eval(int numPoints, + const double *uhAtQP, + const WorldVector<double> *grdUhAtQP, + const WorldMatrix<double> *D2UhAtQP, + double *result, + double factor) const; + + protected: + /** \brief + * Stores coordinates at quadrature points. Set in \ref initElement(). + */ + WorldVector<double>* coordsAtQPs; + + /** \brief + * Function avaluated at world coordinates. + */ + AbstractFunction<double, WorldVector<double> > *g; + }; + + /** + * \ingroup Assembler + * + * \brief + * Vector_FOT multiplied with \f$ f(\vec{x}) \f$. + */ + class VecCoordsAtQP_FOT : public FirstOrderTerm + { + public: + /** \brief + * Constructor. + */ + VecCoordsAtQP_FOT(AbstractFunction<double, WorldVector<double> > *g_, + WorldVector<double> b_) + : FirstOrderTerm(g_->getDegree()), g(g_), b(b_) + {}; + + /** \brief + * Implementation of \ref OperatorTerm::initElement(). + */ + void initElement(const ElInfo* elInfo, SubAssembler* subAssembler, + Quadrature *quad = NULL); + + /** \brief + * Implements FistOrderTerm::getLb(). + */ + void getLb(const ElInfo *elInfo, int numPoints,VectorOfFixVecs<DimVec<double> >& Lb) const; + + /** \brief + * Implements FirstOrderTerm::eval(). + */ + void eval(int numPoints, + const double *uhAtQP, + const WorldVector<double> *grdUhAtQP, + const WorldMatrix<double> *D2UhAtQP, + double *result, + double factor) const; + + protected: + /** \brief + * Stores coordinates at quadrature points. Set in \ref initElement(). + */ + WorldVector<double>* coordsAtQPs; + + /** \brief + * Function evaluated at world coordinates. + */ + AbstractFunction<double, WorldVector<double> > *g; + + /** \brief + * Coefficient vector. + */ + WorldVector<double> b; + }; + + // ============================================================================ + + /** + * \ingroup Assembler + * + * \brief + * First order term: \f$ b(\nabla v(\vec{x})) \cdot \nabla u(\vec{x})\f$. + */ + class VectorGradient_FOT : public FirstOrderTerm + { + public: + /** \brief + * Constructor. + */ + VectorGradient_FOT(DOFVectorBase<double> *dv, + AbstractFunction<WorldVector<double>, WorldVector<double> > *f_) + : FirstOrderTerm(f_->getDegree()), vec(dv), f(f_) + { + }; + + /** \brief + * Implementation of \ref OperatorTerm::initElement(). + */ + void initElement(const ElInfo* elInfo, SubAssembler* subAssembler, + Quadrature *quad = NULL); + + /** \brief + * Implements FirstOrderTerm::getLb(). + */ + void getLb(const ElInfo *elInfo, int numPoints, VectorOfFixVecs<DimVec<double> >& Lb) const; + + /** \brief + * Implements FirstOrderTerm::eval(). + */ + void eval(int numPoints, + const double *uhAtQP, + const WorldVector<double> *grdUhAtQP, + const WorldMatrix<double> *D2UhAtQP, + double *result, + double factor) const; + + protected: + DOFVectorBase<double>* vec; + + /** \brief + * Function for b. + */ + AbstractFunction<WorldVector<double>, WorldVector<double> > *f; + + /** \brief + * Gradient of v at quadrature points. + */ + WorldVector<double> *gradAtQPs; + }; + + // ============================================================================ + + /** + * \ingroup Assembler + * + * \brief + * First order term: \f$ b(v(\vec{x})) \cdot \nabla u(\vec{x})\f$. + */ + class VectorFct_FOT : public FirstOrderTerm + { + public: + /** \brief + * Constructor. + */ + VectorFct_FOT(DOFVectorBase<double> *dv, + AbstractFunction<WorldVector<double>, double> *vecFct_) + : FirstOrderTerm(vecFct_->getDegree()), vec(dv), vecFct(vecFct_) + { + }; + + /** \brief + * Implementation of \ref OperatorTerm::initElement(). + */ + void initElement(const ElInfo* elInfo, SubAssembler* subAssembler, + Quadrature *quad = NULL); + + /** \brief + * Implements FirstOrderTerm::getLb(). + */ + void getLb(const ElInfo *elInfo, int qPoint, VectorOfFixVecs<DimVec<double> >& Lb) const; + + /** \brief + * Implements FirstOrderTerm::eval(). + */ + void eval(int numPoints, + const double *uhAtQP, + const WorldVector<double> *grdUhAtQP, + const WorldMatrix<double> *D2UhAtQP, + double *result, + double factor) const; + + protected: + /** \brief + * DOFVector to be evaluated at quadrature points. + */ + DOFVectorBase<double>* vec; + + /** \brief + * Vector v at quadrature points. + */ + double *vecAtQPs; + + /** \brief + * Function for b. + */ + AbstractFunction<WorldVector<double>, double> *vecFct; + }; + + + // ============================================================================ + + /** + * \ingroup Assembler + * + * \brief + * + */ + class VecFctAtQP_FOT : public FirstOrderTerm + { + public: + /** \brief + * Constructor. + */ + VecFctAtQP_FOT(AbstractFunction<WorldVector<double>, WorldVector<double> > *g_) + : FirstOrderTerm(g_->getDegree()), g(g_) + { + }; + + /** \brief + * Implementation of \ref OperatorTerm::initElement(). + */ + void initElement(const ElInfo* elInfo, SubAssembler* subAssembler, + Quadrature *quad = NULL); + + /** \brief + * Implements FistOrderTerm::getLb(). + */ + void getLb(const ElInfo *elInfo, int numPoints,VectorOfFixVecs<DimVec<double> >&Lb) const; + + /** \brief + * Implements FirstOrderTerm::eval(). + */ + void eval(int numPoints, + const double *uhAtQP, + const WorldVector<double> *grdUhAtQP, + const WorldMatrix<double> *D2UhAtQP, + double *result, + double factor) const; + + protected: + /** \brief + * Stores coordinates at quadrature points. Set in \ref initElement(). + */ + WorldVector<double>* coordsAtQPs; + + /** \brief + * Function avaluated at world coordinates. + */ + AbstractFunction<WorldVector<double>, WorldVector<double> > *g; + }; + + // ============================================================================ + + class General_FOT : public FirstOrderTerm + { + public: + /** /brief + * Constructor + */ + General_FOT(::std::vector<DOFVectorBase<double>*> vecs, + ::std::vector<DOFVectorBase<double>*> grads, + TertiaryAbstractFunction<WorldVector<double>, + WorldVector<double>, + ::std::vector<double>, + ::std::vector<WorldVector<double> > > *f) + : FirstOrderTerm(f->getDegree()), + vecs_(vecs), + grads_(grads), + f_(f) + { + vecsAtQPs_.resize(vecs_.size()); + gradsAtQPs_.resize(grads_.size()); + }; + + /** \brief + * Implementation of \ref OperatorTerm::initElement(). + */ + void initElement(const ElInfo*, + SubAssembler* , + Quadrature *quad= NULL); + + /** \brief + * Implements FirstOrderTerm::getLb(). + */ + void getLb(const ElInfo *elInfo, int numPoints, + VectorOfFixVecs<DimVec<double> >& result) const; + + /** \brief + * Implenetation of FirstOrderTerm::eval(). + */ + void eval(int numPoints, + const double *uhAtQP, + const WorldVector<double> *grdUhAtQP, + const WorldMatrix<double> *D2UhAtQP, + double *result, + double factor) const; + + protected: + ::std::vector<DOFVectorBase<double>*> vecs_; + + ::std::vector<DOFVectorBase<double>*> grads_; + + TertiaryAbstractFunction<WorldVector<double>, + WorldVector<double>, + ::std::vector<double>, + ::std::vector<WorldVector<double> > > *f_; + + WorldVector<double> *coordsAtQPs_; + + ::std::vector<double*> vecsAtQPs_; + + ::std::vector<WorldVector<double>*> gradsAtQPs_; + }; + + + + // ============================================================================ + + class GeneralParametric_FOT : public FirstOrderTerm + { + public: + /** /brief + * Constructor + */ + GeneralParametric_FOT(::std::vector<DOFVectorBase<double>*> vecs, + ::std::vector<DOFVectorBase<double>*> grads, + QuartAbstractFunction<WorldVector<double>, + WorldVector<double>, + WorldVector<double>, + ::std::vector<double>, + ::std::vector<WorldVector<double> > > *f) + : FirstOrderTerm(f->getDegree()), + vecs_(vecs), + grads_(grads), + f_(f) + { + vecsAtQPs_.resize(vecs_.size()); + gradsAtQPs_.resize(grads_.size()); + }; + + /** \brief + * Implementation of \ref OperatorTerm::initElement(). + */ + void initElement(const ElInfo*, + SubAssembler* , + Quadrature *quad= NULL); + + /** \brief + * Implements FirstOrderTerm::getLb(). + */ + void getLb(const ElInfo *elInfo, int numPoints, + VectorOfFixVecs<DimVec<double> >& result) const; + + /** \brief + * Implenetation of FirstOrderTerm::eval(). + */ + void eval(int numPoints, + const double *uhAtQP, + const WorldVector<double> *grdUhAtQP, + const WorldMatrix<double> *D2UhAtQP, + double *result, + double factor) const; + + protected: + ::std::vector<DOFVectorBase<double>*> vecs_; + + ::std::vector<DOFVectorBase<double>*> grads_; + + QuartAbstractFunction<WorldVector<double>, + WorldVector<double>, + WorldVector<double>, + ::std::vector<double>, + ::std::vector<WorldVector<double> > > *f_; + + WorldVector<double> *coordsAtQPs_; + WorldVector<double> elementNormal_; + + ::std::vector<double*> vecsAtQPs_; + + ::std::vector<WorldVector<double>*> gradsAtQPs_; + }; + + + // ============================================================================ + // ===== class ZeroOrderTerm ================================================== + // ============================================================================ + + /** + * \ingroup Assembler + * + * \brief + * Describes zero order terms: \f$ cu(\vec{x}) \f$. + */ + class ZeroOrderTerm : public OperatorTerm + { + public: + /** \brief + * Constructor. + */ + ZeroOrderTerm(int deg) : OperatorTerm(deg) {}; + + /** \brief + * Destructor. + */ + virtual ~ZeroOrderTerm() {}; + + /** \brief + * Evaluates \f$ c \f$ + */ + virtual void getC(const ElInfo *elInfo, + int numPoints, + double *result) const = 0; + + }; + + // ============================================================================ + + /** + * \ingroup Assembler + * + * \brief + * Simple zero order term + */ + class Simple_ZOT : public ZeroOrderTerm + { + public: + /** \brief + * Constructor. + */ + Simple_ZOT(double f = 1.0) : ZeroOrderTerm(0), factor(f) {}; + + /** \brief + * Implements ZeroOrderTerm::getC(). + */ + inline void getC(const ElInfo *, int numPoints, double *C) const + { + int iq; + for(iq = 0; iq < numPoints; iq++) { + C[iq] += factor; + } + }; + + /** \brief + * Implements ZeroOrderTerm::eval(). + */ + inline void eval(int numPoints, + const double *uhAtQP, + const WorldVector<double> *, + const WorldMatrix<double> *, + double *result, + double fac) const + { + int iq; + for(iq = 0; iq < numPoints; iq++) { + result[iq] += fac * factor * uhAtQP[iq]; + } + }; + + protected: + /** \brief + * Constant factor of zero order term. + */ + double factor; + }; + + // ============================================================================ + + /** + * \ingroup Assembler + * + * \brief + * Zero order term: \f$ f(v(\vec{x})) u(\vec{x})\f$ + */ + class VecAtQP_ZOT : public ZeroOrderTerm + { + public: + /** \brief + * Constructor. + */ + VecAtQP_ZOT(DOFVectorBase<double> *dv, + AbstractFunction<double, double> *f_) + : ZeroOrderTerm(f_ ? f_->getDegree() : 0), vec(dv), f(f_) + { + }; + + /** \brief + * Implementation of \ref OperatorTerm::initElement(). + */ + void initElement(const ElInfo* elInfo, SubAssembler* subAssembler, + Quadrature *quad = NULL); + + /** \brief + * Implements ZeroOrderTerm::getC(). + */ + void getC(const ElInfo *, int numPoints, double *C) const; + + /** \brief + * Implements ZeroOrderTerm::eval(). + */ + void eval(int numPoints, + const double *uhAtQP, + const WorldVector<double> *grdUhAtQP, + const WorldMatrix<double> *D2UhAtQP, + double *result, + double fac) const; + + protected: + /** \brief + * DOFVector to be evaluated at quadrature points. + */ + DOFVectorBase<double>* vec; + + /** \brief + * Vector v at quadrature points. + */ + double *vecAtQPs; + + /** \brief + * Function for c. + */ + AbstractFunction<double, double> *f; + }; + + // Andreas ergaenzt: + + + /** + * \ingroup Assembler + * + * \brief + * Zero order term: \f$ f(v(\vec{x})) g(w(\vec{x})) u(\vec{x})\f$ + */ + class MultVecAtQP_ZOT : public ZeroOrderTerm + { + public: + /** \brief + * Constructor. + */ + MultVecAtQP_ZOT(DOFVectorBase<double> *dv1, + DOFVectorBase<double> *dv2, + AbstractFunction<double, double> *f1_, + AbstractFunction<double, double> *f2_) + : ZeroOrderTerm(f1->getDegree()+f2_->getDegree()), + vec1(dv1), vec2(dv2), f1(f1_), f2(f2_) + { + }; + + /** \brief + * Implementation of \ref OperatorTerm::initElement(). + */ + void initElement(const ElInfo* elInfo, SubAssembler* subAssembler, + Quadrature *quad = NULL); + + /** \brief + * Implements ZeroOrderTerm::getC(). + */ + void getC(const ElInfo *, int numPoints, double *C) const; + + /** \brief + * Implements ZeroOrderTerm::eval(). + */ + void eval(int numPoints, + const double *uhAtQP, + const WorldVector<double> *grdUhAtQP, + const WorldMatrix<double> *D2UhAtQP, + double *result, + double fac) const; + + protected: + /** \brief + * DOFVectorBase to be evaluated at quadrature points. + */ + DOFVectorBase<double>* vec1; + DOFVectorBase<double>* vec2; + + /** \brief + * Vector v at quadrature points. + */ + double *vecAtQPs1; + double *vecAtQPs2; + + /** \brief + * Function for c. + */ + AbstractFunction<double, double> *f1; + AbstractFunction<double, double> *f2; + }; + + // ============================================================================ + + + + /** + * \ingroup Assembler + * + * \brief + * Zero order term: \f$ f(v(\vec{x}), w(\vec{x})) u(\vec{x})\f$ + */ + class Vec2AtQP_ZOT : public ZeroOrderTerm + { + public: + /** \brief + * Constructor. + */ + Vec2AtQP_ZOT(DOFVectorBase<double> *dv1, + DOFVectorBase<double> *dv2, + BinaryAbstractFunction<double, double, double> *f_) + : ZeroOrderTerm(f_->getDegree()), + vec1(dv1), vec2(dv2), f(f_) + { + }; + + /** \brief + * Implementation of \ref OperatorTerm::initElement(). + */ + void initElement(const ElInfo* elInfo, SubAssembler* subAssembler, + Quadrature *quad = NULL); + + /** \brief + * Implements ZeroOrderTerm::getC(). + */ + void getC(const ElInfo *, int numPoints, double *C) const; + + /** \brief + * Implements ZeroOrderTerm::eval(). + */ + void eval(int numPoints, + const double *uhAtQP, + const WorldVector<double> *grdUhAtQP, + const WorldMatrix<double> *D2UhAtQP, + double *result, + double fac) const; + + protected: + /** \brief + * DOFVector to be evaluated at quadrature points. + */ + DOFVectorBase<double>* vec1; + DOFVectorBase<double>* vec2; + + /** \brief + * Vector v at quadrature points. + */ + double *vecAtQPs1; + double *vecAtQPs2; + + /** \brief + * Function for c. + */ + BinaryAbstractFunction<double, double, double> *f; + }; + + // ============================================================================ + + /** + * \ingroup Assembler + * + * \brief + * + */ + class FctGradientCoords_ZOT : public ZeroOrderTerm + { + public: + /** \brief + * Constructor. + */ + FctGradientCoords_ZOT(DOFVectorBase<double> *dv, + BinaryAbstractFunction<double, + WorldVector<double>, WorldVector<double> > *f_) + : ZeroOrderTerm(f_->getDegree()), vec(dv), f(f_) + { + }; + + /** \brief + * Implementation of \ref OperatorTerm::initElement(). + */ + void initElement(const ElInfo* elInfo, SubAssembler* subAssembler, + Quadrature *quad = NULL); + + /** \brief + * Implements SecondOrderTerm::getC(). + */ + void getC(const ElInfo *elInfo, int numPoints, double *C) const; + + /** \brief + * Implements ZeroOrderTerm::eval(). + */ + void eval(int numPoints, + const double *uhAtQP, + const WorldVector<double> *grdUhAtQP, + const WorldMatrix<double> *D2UhAtQP, + double *result, + double fac) const; + + protected: + DOFVectorBase<double>* vec; + + /** \brief + * Function wich maps \ref gradAtQPs to a double. + */ + BinaryAbstractFunction<double, WorldVector<double>, WorldVector<double> > *f; + + /** \brief + * Pointer to a WorldVector<double> array containing the gradients of the DOFVector + * at each quadrature point. + */ + WorldVector<double>* gradAtQPs; + + WorldVector<double>* coordsAtQPs; + + }; + + // ============================================================================ + + /** + * \ingroup Assembler + * + * \brief + */ + class VecGradCoordsAtQP_ZOT : public ZeroOrderTerm + { + public: + /** \brief + * Constructor. + */ + VecGradCoordsAtQP_ZOT(DOFVectorBase<double> *dv, + TertiaryAbstractFunction<double, double, WorldVector<double>, WorldVector<double> > *f_) + : ZeroOrderTerm(f_->getDegree()), vec(dv), f(f_) + {}; + + /** \brief + * Implementation of \ref OperatorTerm::initElement(). + */ + void initElement(const ElInfo* elInfo, SubAssembler* subAssembler, + Quadrature *quad = NULL); + + /** \brief + * Implements ZeroOrderTerm::getC(). + */ + void getC(const ElInfo *, int numPoints, double *C) const; + + /** \brief + * Implements ZeroOrderTerm::eval(). + */ + void eval(int numPoints, + const double *uhAtQP, + const WorldVector<double> *grdUhAtQP, + const WorldMatrix<double> *D2UhAtQP, + double *result, + double fac) const; + + protected: + /** \brief + * DOFVector to be evaluated at quadrature points. + */ + DOFVectorBase<double>* vec; + + /** \brief + * Vector v at quadrature points. + */ + double *vecAtQPs; + + /** \brief + * Gradient at quadrature points. + */ + WorldVector<double>* gradAtQPs; + + WorldVector<double>* coordsAtQPs; + + /** \brief + * Function for c. + */ + TertiaryAbstractFunction<double, double, WorldVector<double>, WorldVector<double> > *f; + }; + + + // ============================================================================ + + /** + * \ingroup Assembler + * + * \brief + */ + class VecAndCoordsAtQP_ZOT : public ZeroOrderTerm + { + public: + /** \brief + * Constructor. + */ + VecAndCoordsAtQP_ZOT(DOFVectorBase<double> *dv, + BinaryAbstractFunction<double, double, WorldVector<double> > *f_) + : ZeroOrderTerm(f_->getDegree()), vec(dv), f(f_) + { + }; + + /** \brief + * Implementation of \ref OperatorTerm::initElement(). + */ + void initElement(const ElInfo* elInfo, SubAssembler* subAssembler, + Quadrature *quad = NULL); + + /** \brief + * Implements ZeroOrderTerm::getC(). + */ + void getC(const ElInfo *, int numPoints, double *C) const; + + /** \brief + * Implements ZeroOrderTerm::eval(). + */ + void eval(int numPoints, + const double *uhAtQP, + const WorldVector<double> *grdUhAtQP, + const WorldMatrix<double> *D2UhAtQP, + double *result, + double fac) const; + + protected: + /** \brief + * DOFVector to be evaluated at quadrature points. + */ + DOFVectorBase<double>* vec; + + /** \brief + * Vector v at quadrature points. + */ + double *vecAtQPs; + + /** \brief + * Gradient at quadrature points. + */ + WorldVector<double>* coordsAtQPs; + + /** \brief + * Function for c. + */ + BinaryAbstractFunction<double, double, WorldVector<double> > *f; + }; + + + // Ende Andreas Ergaenzungen + + // ============================================================================ + + /** + * \ingroup Assembler + * + * \brief + * + */ + class FctGradient_ZOT : public ZeroOrderTerm + { + public: + /** \brief + * Constructor. + */ + FctGradient_ZOT(DOFVectorBase<double> *dv, + AbstractFunction<double, WorldVector<double> > *f_) + : ZeroOrderTerm(f_->getDegree()), vec(dv), f(f_) + { + }; + + /** \brief + * Implementation of \ref OperatorTerm::initElement(). + */ + void initElement(const ElInfo* elInfo, SubAssembler* subAssembler, + Quadrature *quad = NULL); + + /** \brief + * Implements SecondOrderTerm::getC(). + */ + void getC(const ElInfo *elInfo, int numPoints, double *C) const; + + /** \brief + * Implements ZeroOrderTerm::eval(). + */ + void eval(int numPoints, + const double *uhAtQP, + const WorldVector<double> *grdUhAtQP, + const WorldMatrix<double> *D2UhAtQP, + double *result, + double fac) const; + + protected: + DOFVectorBase<double>* vec; + + /** \brief + * Function wich maps \ref gradAtQPs to a double. + */ + AbstractFunction<double, WorldVector<double> > *f; + + /** \brief + * Pointer to a WorldVector<double> array containing the gradients of the DOFVector + * at each quadrature point. + */ + WorldVector<double>* gradAtQPs; + + }; + + // ============================================================================ + + /** + * \ingroup Assembler + * + * \brief + */ + class VecAndGradAtQP_ZOT : public ZeroOrderTerm + { + public: + /** \brief + * Constructor. + */ + VecAndGradAtQP_ZOT(DOFVectorBase<double> *dv, + BinaryAbstractFunction<double, double, WorldVector<double> > *f_) + : ZeroOrderTerm(f_->getDegree()), vec(dv), f(f_) + { + }; + + /** \brief + * Implementation of \ref OperatorTerm::initElement(). + */ + void initElement(const ElInfo* elInfo, SubAssembler* subAssembler, + Quadrature *quad = NULL); + + /** \brief + * Implements ZeroOrderTerm::getC(). + */ + void getC(const ElInfo *, int numPoints, double *C) const; + + /** \brief + * Implements ZeroOrderTerm::eval(). + */ + void eval(int numPoints, + const double *uhAtQP, + const WorldVector<double> *grdUhAtQP, + const WorldMatrix<double> *D2UhAtQP, + double *result, + double fac) const; + + protected: + /** \brief + * DOFVector to be evaluated at quadrature points. + */ + DOFVectorBase<double>* vec; + + /** \brief + * Vector v at quadrature points. + */ + double *vecAtQPs; + + /** \brief + * Gradient at quadrature points. + */ + WorldVector<double> *gradAtQPs; + + /** \brief + * Function for c. + */ + BinaryAbstractFunction<double, double, WorldVector<double> > *f; + }; + + // ============================================================================ + + /** + * \ingroup Assembler + * + * \brief + */ + class VecAndGradAtQP_SOT : public SecondOrderTerm + { + public: + /** \brief + * Constructor. + */ + VecAndGradAtQP_SOT(DOFVectorBase<double> *dv, + BinaryAbstractFunction<double, double, WorldVector<double> > *f_) + : SecondOrderTerm(f_->getDegree()), vec(dv), f(f_) + { + }; + + /** \brief + * Implementation of \ref OperatorTerm::initElement(). + */ + void initElement(const ElInfo* elInfo, SubAssembler* subAssembler, + Quadrature *quad = NULL); + + + /** \brief + * Implements SecondOrderTerm::getLALt(). + */ + inline void getLALt(const ElInfo *elInfo, int numPoints, DimMat<double> **LALt) const; + + /** \brief + * Implements SecondOrderTerm::eval(). + */ + void eval(int numPoints, + const double *uhAtQP, + const WorldVector<double> *grdUhAtQP, + const WorldMatrix<double> *D2UhAtQP, + double *result, + double factor) const; + + /** \brief + * Implements SecondOrderTerm::weakEval(). + */ + void weakEval(int numPoints, + const WorldVector<double> *grdUhAtQP, + WorldVector<double> *result) const; + + protected: + /** \brief + * DOFVector to be evaluated at quadrature points. + */ + DOFVectorBase<double>* vec; + + /** \brief + * Vector v at quadrature points. + */ + double *vecAtQPs; + + /** \brief + * Gradient at quadrature points. + */ + WorldVector<double> *gradAtQPs; + + /** \brief + * Function for c. + */ + BinaryAbstractFunction<double, double, WorldVector<double> > *f; + }; + + + // ============================================================================ + + /* + * \ingroup Assembler + * + * \brief + * Zero order term: \f$ f(\vec{x}) u(\vec{x})\f$ + */ + class CoordsAtQP_ZOT : public ZeroOrderTerm + { + public: + /** \brief + * Constructor. + */ + CoordsAtQP_ZOT(AbstractFunction<double, WorldVector<double> > *g_) + : ZeroOrderTerm(g_->getDegree()), + g(g_) + {}; + + /** \brief + * Implementation of \ref OperatorTerm::initElement(). + */ + void initElement(const ElInfo* elInfo, + SubAssembler* subAssembler, + Quadrature *quad = NULL); + + /** \brief + * Implements ZeroOrderTerm::getC(). + */ + void getC(const ElInfo *, int numPoints, double *C) const; + + /** \brief + * Implements ZeroOrderTerm::eval(). + */ + void eval(int numPoints, + const double *uhAtQP, + const WorldVector<double> *grdUhAtQP, + const WorldMatrix<double> *D2UhAtQP, + double *result, + double fac) const; + + protected: + /** \brief + * Stores coordinates at quadrature points. Set in \ref initElement(). + */ + WorldVector<double>* coordsAtQPs; + + /** \brief + * Function for c. + */ + AbstractFunction<double, WorldVector<double> > *g; + }; + + // ============================================================================ + + /** + * \ingroup Assembler + * + * \brief + * SecondOrderTerm where A(x) is a WorldMatrix having a in all positions + * except possibly the position IJ + * \f$ \nabla \cdot A(x) \nabla u(\vec{x}) \f$ + */ + class CoordsAtQP_IJ_SOT : public SecondOrderTerm + { + public: + /** \brief + * Constructor. + */ + CoordsAtQP_IJ_SOT(AbstractFunction<double, WorldVector<double> > *g_, + int x_i, int x_j) + : SecondOrderTerm(g_->getDegree()), g(g_), xi(x_i), xj(x_j) + { + setSymmetric(xi == xj); + }; + + /** \brief + * Implementation of \ref OperatorTerm::initElement(). + */ + void initElement(const ElInfo* elInfo, SubAssembler* subAssembler, + Quadrature *quad = NULL); + + /** \brief + * Implements SecondOrderTerm::getLALt(). + */ + inline void getLALt(const ElInfo *elInfo, int numPoints, DimMat<double> **LALt) const; + + /** \brief + * Implements SecondOrderTerm::eval(). + */ + void eval(int numPoints, + const double *uhAtQP, + const WorldVector<double> *grdUhAtQP, + const WorldMatrix<double> *D2UhAtQP, + double *result, + double factor) const; + + /** \brief + * Implements SecondOrderTerm::weakEval(). + */ + void weakEval(int numPoints, + const WorldVector<double> *grdUhAtQP, + WorldVector<double> *result) const; + + private: + /** \brief + * Stores coordinates at quadrature points. Set in \ref initElement(). + */ + WorldVector<double>* coordsAtQPs; + + /** \brief + * Function evaluated at quadrature points. + */ + AbstractFunction<double, WorldVector<double> > *g; + + /** \brief + * Directions for the derivatives. + */ + int xi, xj; + }; + + // ============================================================================ + + /** + * \ingroup Assembler + * + * \brief + * SecondOrderTerm where A is a WorldMatrix having a in all positions + * except possibly the position IJ, multiplied with a function + * evaluated at the quadrature points of a given DOFVector: + * \f$ \nabla \cdot f(v(\vec{x})) A \nabla u(\vec{x}) \f$ + */ + class VecAtQP_IJ_SOT : public SecondOrderTerm + { + public: + /** \brief + * Constructor. + */ + VecAtQP_IJ_SOT(DOFVectorBase<double> *dv, + AbstractFunction<double, double> *f_, + int x_i, int x_j) + : SecondOrderTerm(f_->getDegree()), vec(dv), f(f_), xi(x_i), xj(x_j) + { + setSymmetric(xi == xj); + }; + + /** \brief + * Implementation of \ref OperatorTerm::initElement(). + */ + void initElement(const ElInfo* elInfo, SubAssembler* subAssembler, + Quadrature *quad = NULL); + + /** \brief + * Implements SecondOrderTerm::getLALt(). + */ + void getLALt(const ElInfo *elInfo, int numPoints, DimMat<double> **LALt) const; + + /** \brief + * Implements SecondOrderTerm::eval(). + */ + void eval(int numPoints, + const double *uhAtQP, + const WorldVector<double> *grdUhAtQP, + const WorldMatrix<double> *D2UhAtQP, + double *result, + double factor) const; + + /** \brief + * Implements SecondOrderTerm::weakEval(). + */ + void weakEval(int numPoints, + const WorldVector<double> *grdUhAtQP, + WorldVector<double> *result) const; + + protected: + /** \brief + * DOFVector to be evaluated at quadrature points. + */ + DOFVectorBase<double>* vec; + + /** \brief + * Pointer to an array containing the DOFVector evaluated at quadrature + * points. + */ + double* vecAtQPs; + + /** \brief + * Function evaluated at \ref vecAtQPs. + */ + AbstractFunction<double, double> *f; + + private: + /** \brief + * Directions for the derivatives. + */ + int xi, xj; + }; + + // ============================================================================ + + class VecAndGradVecAtQP_ZOT : public ZeroOrderTerm + { + public: + /** \brief + * Constructor. + */ + VecAndGradVecAtQP_ZOT(DOFVectorBase<double> *dv, + DOFVectorBase<double> *dGrd, + BinaryAbstractFunction<double, double, WorldVector<double> > *f_) + : ZeroOrderTerm(f_->getDegree()), vec(dv), vecGrd(dGrd), f(f_) + { + }; + + /** \brief + * Implementation of \ref OperatorTerm::initElement(). + */ + void initElement(const ElInfo* elInfo, SubAssembler* subAssembler, + Quadrature *quad = NULL); + + /** \brief + * Implements ZeroOrderTerm::getC(). + */ + void getC(const ElInfo *, int numPoints, double *C) const; + + /** \brief + * Implements ZeroOrderTerm::eval(). + */ + void eval(int numPoints, + const double *uhAtQP, + const WorldVector<double> *grdUhAtQP, + const WorldMatrix<double> *D2UhAtQP, + double *result, + double fac) const; + + protected: + /** \brief + * DOFVector to be evaluated at quadrature points. + */ + DOFVectorBase<double>* vec; + + /** \brief + * Vector v at quadrature points. + */ + double *vecAtQPs; + + /** \brief + * First DOFVector whose gradient is evaluated at quadrature points. + */ + DOFVectorBase<double>* vecGrd; + + /** \brief + * Gradient of first vector at quadrature points. + */ + WorldVector<double> *gradAtQPs; + + /** \brief + * Function for c. + */ + BinaryAbstractFunction<double, double, WorldVector<double> > *f; + }; + + // ============================================================================ + + class VecAndGradVec2AtQP_ZOT : public ZeroOrderTerm + { + public: + /** \brief + * Constructor. + */ + VecAndGradVec2AtQP_ZOT(DOFVectorBase<double> *dv, + DOFVectorBase<double> *dGrd1, DOFVectorBase<double> *dGrd2, + TertiaryAbstractFunction<double, + double, WorldVector<double>, WorldVector<double> > *f_) + : ZeroOrderTerm(f_->getDegree()), vec(dv), vecGrd1(dGrd1), vecGrd2(dGrd2), f(f_) + { + }; + + /** \brief + * Implementation of \ref OperatorTerm::initElement(). + */ + void initElement(const ElInfo* elInfo, SubAssembler* subAssembler, + Quadrature *quad = NULL); + + /** \brief + * Implements ZeroOrderTerm::getC(). + */ + void getC(const ElInfo *, int numPoints, double *C) const; + + /** \brief + * Implements ZeroOrderTerm::eval(). + */ + void eval(int numPoints, + const double *uhAtQP, + const WorldVector<double> *grdUhAtQP, + const WorldMatrix<double> *D2UhAtQP, + double *result, + double fac) const; + + protected: + /** \brief + * DOFVector to be evaluated at quadrature points. + */ + DOFVectorBase<double>* vec; + + /** \brief + * Vector v at quadrature points. + */ + double *vecAtQPs; + + /** \brief + * First DOFVector whose gradient is evaluated at quadrature points. + */ + DOFVectorBase<double>* vecGrd1; + + /** \brief + * Gradient of first vector at quadrature points. + */ + WorldVector<double> *grad1AtQPs; + + /** \brief + * Second DOFVector whose gradient is evaluated at quadrature points. + */ + DOFVectorBase<double>* vecGrd2; + + /** \brief + * Gradient of second vector at quadrature points. + */ + WorldVector<double> *grad2AtQPs; + + /** \brief + * Function for c. + */ + TertiaryAbstractFunction<double, double, WorldVector<double>, WorldVector<double> > *f; + }; + + + class VecOfDOFVecsAtQP_ZOT : public ZeroOrderTerm + { + public: + /** \brief + * Constructor. + */ + VecOfDOFVecsAtQP_ZOT(const ::std::vector<DOFVectorBase<double>*>& dv, + AbstractFunction<double, ::std::vector<double> > *f_) + : ZeroOrderTerm(f_->getDegree()), vecs(dv), f(f_) + { + vecsAtQPs.resize(vecs.size()); + }; + + /** \brief + * Implementation of \ref OperatorTerm::initElement(). + */ + void initElement(const ElInfo* elInfo, SubAssembler* subAssembler, + Quadrature *quad = NULL); + + /** \brief + * Implements ZeroOrderTerm::getC(). + */ + void getC(const ElInfo *, int numPoints, double *C) const; + + /** \brief + * Implements ZeroOrderTerm::eval(). + */ + void eval(int numPoints, + const double *uhAtQP, + const WorldVector<double> *grdUhAtQP, + const WorldMatrix<double> *D2UhAtQP, + double *result, + double fac) const; + + protected: + /** \brief + * Vector of DOFVectors to be evaluated at quadrature points. + */ + ::std::vector<DOFVectorBase<double>*> vecs; + + /** \brief + * Vectors at quadrature points. + */ + ::std::vector<double*> vecsAtQPs; + + /** \brief + * Function for c. + */ + AbstractFunction<double, ::std::vector<double> > *f; + }; + + class VecOfGradientsAtQP_ZOT : public ZeroOrderTerm + { + public: + /** \brief + * Constructor. + */ + VecOfGradientsAtQP_ZOT(const ::std::vector<DOFVectorBase<double>*>& dv, + AbstractFunction<double, ::std::vector<WorldVector<double>*> > *f_) + : ZeroOrderTerm(f_->getDegree()), vecs(dv), f(f_) + { + gradsAtQPs.resize(vecs.size()); + }; + + /** \brief + * Implementation of \ref OperatorTerm::initElement(). + */ + void initElement(const ElInfo* elInfo, SubAssembler* subAssembler, + Quadrature *quad = NULL); + + /** \brief + * Implements ZeroOrderTerm::getC(). + */ + void getC(const ElInfo *, int numPoints, double *C) const; + + /** \brief + * Implements ZeroOrderTerm::eval(). + */ + void eval(int numPoints, + const double *uhAtQP, + const WorldVector<double> *grdUhAtQP, + const WorldMatrix<double> *D2UhAtQP, + double *result, + double fac) const; + + protected: + /** \brief + * Vector of DOFVectors to be evaluated at quadrature points. + */ + ::std::vector<DOFVectorBase<double>*> vecs; + + /** \brief + * Vectors at quadrature points. + */ + ::std::vector<WorldVector<double>*> gradsAtQPs; + + /** \brief + * Function for c. + */ + AbstractFunction<double, ::std::vector<WorldVector<double>*> > *f; + }; + + + class VecDivergence_ZOT : public ZeroOrderTerm + { + public: + /** \brief + * Constructor. + */ + VecDivergence_ZOT(int numComponents, + DOFVectorBase<double> *vec0, + DOFVectorBase<double> *vec1 = NULL, + DOFVectorBase<double> *vec2 = NULL) + : ZeroOrderTerm(0) + { + vecs.resize(numComponents); + gradsAtQPs.resize(numComponents); + vecs[0] = vec0; + vecs[1] = vec1; + vecs[2] = vec2; + }; + + /** \brief + * Implementation of \ref OperatorTerm::initElement(). + */ + void initElement(const ElInfo* elInfo, SubAssembler* subAssembler, + Quadrature *quad = NULL); + + /** \brief + * Implements ZeroOrderTerm::getC(). + */ + void getC(const ElInfo *, int numPoints, double *C) const; + + /** \brief + * Implements ZeroOrderTerm::eval(). + */ + void eval(int numPoints, + const double *uhAtQP, + const WorldVector<double> *grdUhAtQP, + const WorldMatrix<double> *D2UhAtQP, + double *result, + double fac) const; + + protected: + /** \brief + * Vector of DOFVectors to be evaluated at quadrature points. + */ + ::std::vector<DOFVectorBase<double>*> vecs; + + /** \brief + * Vectors at quadrature points. + */ + ::std::vector<WorldVector<double>*> gradsAtQPs; + }; + + + + class VecAndVecOfGradientsAtQP_ZOT : public ZeroOrderTerm + { + public: + /** \brief + * Constructor. + */ + VecAndVecOfGradientsAtQP_ZOT(DOFVector<double> *vec_, + const std::vector<DOFVector<double>*>& dv, + BinaryAbstractFunction<double, double, std::vector<WorldVector<double>*> > *f_) + : ZeroOrderTerm(f_->getDegree()), vec(vec_), vecs(dv), f(f_) + { + gradsAtQPs.resize(vecs.size()); + }; + + /** \brief + * Implementation of \ref OperatorTerm::initElement(). + */ + void initElement(const ElInfo* elInfo, SubAssembler* subAssembler, + Quadrature *quad = NULL); + + /** \brief + * Implements ZeroOrderTerm::getC(). + */ + void getC(const ElInfo *, int numPoints, double *C) const; + + /** \brief + * Implements ZeroOrderTerm::eval(). + */ + void eval(int numPoints, + const double *uhAtQP, + const WorldVector<double> *grdUhAtQP, + const WorldMatrix<double> *D2UhAtQP, + double *result, + double fac) const; + + protected: + /** \brief + * DOFVector to be evaluated at quadrature points. + */ + DOFVector<double>* vec; + + /** \brief + * Vector v at quadrature points. + */ + double *vecAtQPs; + + /** \brief + * Vector of DOFVectors to be evaluated at quadrature points. + */ + std::vector<DOFVector<double>*> vecs; + + /** \brief + * Vectors at quadrature points. + */ + std::vector<WorldVector<double>*> gradsAtQPs; + + /** \brief + * Function for c. + */ + BinaryAbstractFunction<double, double, std::vector<WorldVector<double>*> > *f; + }; + + + + // ============================================================================ + + class General_ZOT : public ZeroOrderTerm + { + public: + /** \brief + * Constructor. + */ + General_ZOT(::std::vector<DOFVectorBase<double>*> vecs, + ::std::vector<DOFVectorBase<double>*> grads, + TertiaryAbstractFunction<double, + WorldVector<double>, + ::std::vector<double>, + ::std::vector<WorldVector<double> > > *f) + : ZeroOrderTerm(f->getDegree()), + vecs_(vecs), + grads_(grads), + f_(f) + { + vecsAtQPs_.resize(vecs_.size()); + gradsAtQPs_.resize(grads_.size()); + }; + + /** \brief + * Implementation of \ref OperatorTerm::initElement(). + */ + void initElement(const ElInfo* elInfo, SubAssembler* subAssembler, + Quadrature *quad = NULL); + + /** \brief + * Implements ZeroOrderTerm::getC(). + */ + void getC(const ElInfo *, int numPoints, double *C) const; + + /** \brief + * Implements ZeroOrderTerm::eval(). + */ + void eval(int numPoints, + const double *uhAtQP, + const WorldVector<double> *grdUhAtQP, + const WorldMatrix<double> *D2UhAtQP, + double *result, + double fac) const; + + protected: + ::std::vector<DOFVectorBase<double>*> vecs_; + + ::std::vector<DOFVectorBase<double>*> grads_; + + TertiaryAbstractFunction<double, + WorldVector<double>, + ::std::vector<double>, + ::std::vector<WorldVector<double> > > *f_; + + WorldVector<double> *coordsAtQPs_; + + ::std::vector<double*> vecsAtQPs_; + + ::std::vector<WorldVector<double>*> gradsAtQPs_; + }; + + + // ============================================================================ + + class GeneralParametric_ZOT : public ZeroOrderTerm + { + public: + /** \brief + * Constructor. + */ + GeneralParametric_ZOT(::std::vector<DOFVectorBase<double>*> vecs, + ::std::vector<DOFVectorBase<double>*> grads, + QuartAbstractFunction<double, + WorldVector<double>, + WorldVector<double>, + ::std::vector<double>, + ::std::vector<WorldVector<double> > > *f) + : ZeroOrderTerm(f->getDegree()), + vecs_(vecs), + grads_(grads), + f_(f) + { + vecsAtQPs_.resize(vecs_.size()); + gradsAtQPs_.resize(grads_.size()); + }; + + /** \brief + * Implementation of \ref OperatorTerm::initElement(). + */ + void initElement(const ElInfo* elInfo, SubAssembler* subAssembler, + Quadrature *quad = NULL); + + /** \brief + * Implements ZeroOrderTerm::getC(). + */ + void getC(const ElInfo *, int numPoints, double *C) const; + + /** \brief + * Implements ZeroOrderTerm::eval(). + */ + void eval(int numPoints, + const double *uhAtQP, + const WorldVector<double> *grdUhAtQP, + const WorldMatrix<double> *D2UhAtQP, + double *result, + double fac) const; + + protected: + ::std::vector<DOFVectorBase<double>*> vecs_; + + ::std::vector<DOFVectorBase<double>*> grads_; + + QuartAbstractFunction<double, + WorldVector<double>, + WorldVector<double>, + ::std::vector<double>, + ::std::vector<WorldVector<double> > > *f_; + + WorldVector<double> *coordsAtQPs_; + + WorldVector<double> elementNormal_; + + ::std::vector<double*> vecsAtQPs_; + + ::std::vector<WorldVector<double>*> gradsAtQPs_; + }; + + + + /*****************************************************************************/ + /****** Operators for the least-square finite element method *******/ + /*****************************************************************************/ + + + // ============================================================================ + // ===== class Operator ======================================================= + // ============================================================================ + + /** \brief + * An Operator holds all information needed to assemble the system matrix + * and the right hand side. It consists of four OperatorTerm lists each storing + * Terms of a specific order and type. You can define your own Operator by + * creating an empty Operator and than adding OperatorTerms to it. + * An Operator can by of type MATRIX_OPERATOR, if it's used to assemble the + * system matrix on the left hand side, or it can be of type VECTOR_OPERATOR, + * if it's used to assemble the right hand side vector. If an Operator gives + * contributions to both sides of the system it is a MATRIX_OPERATOR and a + * VECTOR_OPERATOR in one instance. This allows to efficiently reuse element + * matrices once calculated. + * By calling \ref getElementMatrix() or \ref getElementVector() one can + * initiate the assembling procedure. Therefor each Operator has its own + * Assembler, especially created for this Operator, by the first call of + * \ref getElementMatrix() or \ref getElementVector(). + */ + class Operator + { + public: + MEMORY_MANAGED(Operator); + + /** \brief + * Constructs an empty Operator of type operatorType for the given + * FiniteElemSpace. + * The type is given by a Flag that can contain the values MATRIX_OPERATOR, + * VECTOR_OPERATOR, or MATRIX_OPERATOR | VECTOR_OPERATOR. This type specifies + * whether the Operator is used on the left hand side, the right hand side, + * or on both sides of the system. + */ + Operator(Flag operatorType, + const FiniteElemSpace *rowFESpace_, + const FiniteElemSpace *colFESpace_ = NULL); + + /** \brief + * Destructor. + */ + virtual ~Operator() {}; + + /** \brief + * Sets \ref optimized. + */ + inline void useOptimizedAssembler(bool opt) { + optimized = opt; + }; + + /** \brief + * Returns \ref optimized. + */ + inline bool isOptimized() { + return optimized; + }; + + /** \brief + * Adds a SecondOrderTerm to the Operator + */ + void addSecondOrderTerm(SecondOrderTerm *term); + + /** \brief + * Adds a FirstOrderTerm to the Operator + */ + void addFirstOrderTerm(FirstOrderTerm *term, + FirstOrderType type = GRD_PHI); + /** \brief + * Adds a ZeroOrderTerm to the Operator + */ + void addZeroOrderTerm(ZeroOrderTerm *term); + + + /** \brief + * Calculates the element matrix for this ElInfo and adds it multiplied by + * factor to userMat. + */ + virtual void getElementMatrix(const ElInfo *elInfo, + ElementMatrix *userMat, + double factor = 1.0); + + /** \brief + * Calculates the element vector for this ElInfo and adds it multiplied by + * factor to userVec. + */ + virtual void getElementVector(const ElInfo *elInfo, + ElementVector *userVec, + double factor = 1.0); + + + + /** \brief + * Returns \ref rowFESpace + */ + inline const FiniteElemSpace *getRowFESpace() { + return rowFESpace; + }; + + /** \brief + * Returns \ref colFESpace + */ + inline const FiniteElemSpace *getColFESpace() { + return colFESpace; + }; + + /** \brief + * Sets \ref uhOld. + */ + void setUhOld(const DOFVectorBase<double> *uhOld); + + /** \brief + * Returns \ref uhOld. + */ + inline const DOFVectorBase<double> *getUhOld() { + return uhOld; + }; + + /** \brief + * Returns \ref assembler + */ + Assembler *getAssembler(); + + /** \brief + * Sets \ref assembler + */ + void setAssembler(Assembler *ass) { + assembler = ass; + }; + + /** \brief + * Returns whether this is a matrix operator. + */ + inline const bool isMatrixOperator() { + return type.isSet(MATRIX_OPERATOR); + }; + + /** \brief + * Returns whether this is a vector operator + */ + inline const bool isVectorOperator() { + return type.isSet(VECTOR_OPERATOR); + }; + + /** \brief + * Sets \ref fillFlag, the flag used for this Operator while mesh traversal. + */ + inline void setFillFlag(Flag f) { + fillFlag = f; + }; + + /** \brief + * Returns \ref fillFlag + */ + inline Flag getFillFlag() { + return fillFlag; + }; + + /** \brief + * Initialization of the needed SubAssemblers using the given quadratures. + */ + void initAssembler(Quadrature *quad2, + Quadrature *quad1GrdPsi, + Quadrature *quad1GrdPhi, + Quadrature *quad0); + + + /** \brief + * Calculates the needed quadrature degree for the given order. + */ + int getQuadratureDegree(int order, FirstOrderType firstOrderType = GRD_PHI); + + /** \brief + * Evaluation of all terms in \ref zeroOrder. + */ + void evalZeroOrder(int numPoints, + const double *uhAtQP, + const WorldVector<double> *grdUhAtQP, + const WorldMatrix<double> *D2UhAtQP, + double *result, + double factor) const + { + ::std::vector<OperatorTerm*>::const_iterator termIt; + for(termIt = zeroOrder.begin(); + termIt != zeroOrder.end(); + ++termIt) + { + (*termIt)->eval(numPoints, uhAtQP, grdUhAtQP, D2UhAtQP, result, factor); + } + }; + + + /** \brief + * Evaluation of all terms in \ref firstOrderGrdPsi. + */ + void evalFirstOrderGrdPsi(int numPoints, + const double *uhAtQP, + const WorldVector<double> *grdUhAtQP, + const WorldMatrix<double> *D2UhAtQP, + double *result, + double factor) const + { + ::std::vector<OperatorTerm*>::const_iterator termIt; + for(termIt = firstOrderGrdPsi.begin(); + termIt != firstOrderGrdPsi.end(); + ++termIt) + { + (*termIt)->eval(numPoints, uhAtQP, grdUhAtQP, D2UhAtQP, result, factor); + } + }; + + /** \brief + * Evaluation of all terms in \ref firstOrderGrdPhi. + */ + void evalFirstOrderGrdPhi(int numPoints, + const double *uhAtQP, + const WorldVector<double> *grdUhAtQP, + const WorldMatrix<double> *D2UhAtQP, + double *result, + double factor) const + { + ::std::vector<OperatorTerm*>::const_iterator termIt; + for(termIt = firstOrderGrdPhi.begin(); + termIt != firstOrderGrdPhi.end(); + ++termIt) + { + (*termIt)->eval(numPoints, uhAtQP, grdUhAtQP, D2UhAtQP, result, factor); + } + }; + + + /** \brief + * Evaluation of all terms in \ref secondOrder. + */ + void evalSecondOrder(int numPoints, + const double *uhAtQP, + const WorldVector<double> *grdUhAtQP, + const WorldMatrix<double> *D2UhAtQP, + double *result, + double factor) const + { + ::std::vector<OperatorTerm*>::const_iterator termIt; + for(termIt = secondOrder.begin(); + termIt != secondOrder.end(); + ++termIt) + { + (*termIt)->eval(numPoints, uhAtQP, grdUhAtQP, D2UhAtQP, result, factor); + } + }; + + /** \brief + * Weak evaluation of all terms in \ref secondOrder. + */ + void weakEvalSecondOrder(int numPoints, + const WorldVector<double> *grdUhAtQP, + WorldVector<double> *result) const + { + ::std::vector<OperatorTerm*>::const_iterator termIt; + for(termIt = secondOrder.begin(); + termIt != secondOrder.end(); + ++termIt) + { + static_cast<SecondOrderTerm*>(*termIt)->weakEval(numPoints, + grdUhAtQP, + result); + } + }; + + /** \brief + * Calls getLALt() for each term in \ref secondOrder + * and adds the results to LALt. + */ + void getLALt(const ElInfo *elInfo, int numPoints, DimMat<double> **LALt) const + { + ::std::vector<OperatorTerm*>::const_iterator termIt; + for(termIt = secondOrder.begin(); + termIt != secondOrder.end(); + ++termIt) + { + static_cast<SecondOrderTerm*>(*termIt)->getLALt(elInfo, + numPoints, + LALt); + } + }; + + /** \brief + * Calls getLb() for each term in \ref firstOrderGrdPsi + * and adds the results to Lb. + */ + void getLbGrdPsi(const ElInfo *elInfo, int numPoints, VectorOfFixVecs<DimVec<double> >& Lb) const + { + ::std::vector<OperatorTerm*>::const_iterator termIt; + for(termIt = firstOrderGrdPsi.begin(); + termIt != firstOrderGrdPsi.end(); + ++termIt) + { + static_cast<FirstOrderTerm*>(*termIt)->getLb(elInfo, + numPoints, + Lb); + } + }; + + /** \brief + * Calls getLb() for each term in \ref firstOrderGrdPhi + * and adds the results to Lb. + */ + void getLbGrdPhi(const ElInfo *elInfo, int numPoints, VectorOfFixVecs<DimVec<double> >& Lb) const + { + ::std::vector<OperatorTerm*>::const_iterator termIt; + for(termIt = firstOrderGrdPhi.begin(); + termIt != firstOrderGrdPhi.end(); + ++termIt) + { + static_cast<FirstOrderTerm*>(*termIt)->getLb(elInfo, + numPoints, + Lb); + } + }; + + /** \brief + * Calls getC() for each term in \ref zeroOrder + * and adds the results to c. + */ + void getC(const ElInfo *elInfo, int numPoints, double *c) const + { + ::std::vector<OperatorTerm*>::const_iterator termIt; + for(termIt = zeroOrder.begin(); + termIt != zeroOrder.end(); + ++termIt) + { + static_cast<ZeroOrderTerm*>(*termIt)->getC(elInfo, + numPoints, + c); + } + }; + + /** \brief + * Returns true, if there are second order terms. Returns false otherwise. + */ + inline bool secondOrderTerms() { + return secondOrder.size() != 0; + }; + + /** \brief + * Returns true, if there are first order terms (grdPsi). + * Returns false otherwise. + */ + inline bool firstOrderTermsGrdPsi() { + return firstOrderGrdPsi.size() != 0; + }; + + /** \brief + * Returns true, if there are first order terms (grdPhi). + * Returns false otherwise. + */ + inline bool firstOrderTermsGrdPhi() { + return firstOrderGrdPhi.size() != 0; + }; + + /** \brief + * Returns true, if there are zero order terms. + * Returns false otherwise. + */ + inline bool zeroOrderTerms() { + return zeroOrder.size() != 0; + }; + + public: + /** \brief + * Constant type flag for matrix operators + */ + static const Flag MATRIX_OPERATOR; + + /** \brief + * Constant type flag for vector operators + */ + static const Flag VECTOR_OPERATOR; + + protected: + /** \brief + * FiniteElemSpace for matrix rows and element vector + */ + const FiniteElemSpace *rowFESpace; + + /** \brief + * FiniteElemSpace for matrix columns. Can be equal to \rowFESpace. + */ + const FiniteElemSpace *colFESpace; + + /** \brief + * Number of rows in the element matrix + */ + int nRow; + + /** \brief + * Number of columns in the element matrix + */ + int nCol; + + /** \brief + * Type of this Operator. + */ + Flag type; + + /** \brief + * Flag for mesh traversal + */ + Flag fillFlag; + + /** \brief + * Calculates the element matrix and/or the element vector. It is + * created especially for this Operator, when \ref getElementMatrix() + * or \ref getElementVector is called for the first time. + */ + Assembler *assembler; + + /** \brief + * List of all second order terms + */ + ::std::vector<OperatorTerm*> secondOrder; + + /** \brief + * List of all first order terms derived to psi + */ + ::std::vector<OperatorTerm*> firstOrderGrdPsi; + + /** \brief + * List of all first order terms derived to phi + */ + ::std::vector<OperatorTerm*> firstOrderGrdPhi; + + /** \brief + * List of all zero order terms + */ + ::std::vector<OperatorTerm*> zeroOrder; + + /** \brief + * Pointer to the solution of the last timestep. Can be used if the + * Operator is MATRIX_OPERATOR and VECTOR_OPERATOR for a more efficient + * assemblage of the element vector when the element matrix was already + * computed. + */ + const DOFVectorBase<double> *uhOld; + + /** \brief + * Spezifies whether optimized assemblers are used or not. + */ + bool optimized; + + friend class Assembler; + friend class SubAssembler; + friend class ZeroOrderAssembler; + friend class FirstOrderAssembler; + friend class SecondOrderAssembler; + }; + +} + +#endif // AMDIS_OPERATOR_H diff --git a/AMDiS/src/ParMetisPartitioner.cc b/AMDiS/src/ParMetisPartitioner.cc new file mode 100644 index 0000000000000000000000000000000000000000..d5da44333ca1fc47379402a7086d42bb936299b8 --- /dev/null +++ b/AMDiS/src/ParMetisPartitioner.cc @@ -0,0 +1,655 @@ +#include "ParMetisPartitioner.h" +#include "Mesh.h" +#include "Traverse.h" +#include "ElInfo.h" +#include "Element.h" +#include "FixVec.h" +#include "PartitionElementData.h" +#include "DOFVector.h" +#include "mpi.h" + +#include <queue> + +namespace AMDiS { + + ParMetisMesh::ParMetisMesh(Mesh *mesh) + : numElements_(0) + { + FUNCNAME("ParMetisMesh::ParMetisMesh()"); + int i; + int mpiSize = MPI::COMM_WORLD.Get_size(); + + int nodeCounter = 0; + int elementCounter = 0; + + dim_ = mesh->getDim(); + int dow = Global::getGeo(WORLD); + + TraverseStack stack; + ElInfo *elInfo = stack.traverseFirst(mesh, -1, + Mesh::CALL_EVERY_EL_PREORDER); + while(elInfo) { + Element *element = elInfo->getElement(); + + // get partition data + PartitionElementData *partitionData = dynamic_cast<PartitionElementData*> + (element->getElementData(PARTITION_ED)); + + if(partitionData && + partitionData->getPartitionStatus() == IN && + partitionData->getLevel() == 0) + { + elementCounter++; + } + + elInfo = stack.traverseNext(elInfo); + } + + numElements_ = elementCounter; + + TEST_EXIT(numElements_ > 0)("no elements in ParMETIS mesh\n"); + + // allocate memory + eptr_ = GET_MEMORY(int, numElements_ + 1); + eind_ = GET_MEMORY(int, numElements_ * (dim_ + 1)); + elmdist_ = GET_MEMORY(int, mpiSize + 1); + + elem_p2a_ = GET_MEMORY(int, numElements_); + + if(dim_ == dow) { + xyz_ = GET_MEMORY(float, numElements_ * dim_); + } else { + xyz_ = NULL; + } + + eptr_[0] = 0; + + int *ptr_eptr = eptr_ + 1; + int *ptr_eind = eind_; + float *ptr_xyz = xyz_; + + // gather element numbers and create elmdist + MPI::COMM_WORLD.Allgather(&numElements_, 1, MPI_INT, + elmdist_ + 1, 1, MPI_INT); + elmdist_[0] = 0; + for(i = 2; i < mpiSize + 1; i++) { + elmdist_[i] += elmdist_[i - 1]; + } + + // traverse mesh and fill distributed ParMETIS data + DimVec<double> bary(dim_, DEFAULT_VALUE, 1.0 / (dim_ + 1)); + WorldVector<double> world; + + elementCounter = 0; + + elInfo = stack.traverseFirst(mesh, -1, + Mesh::CALL_EVERY_EL_PREORDER | + Mesh::FILL_COORDS); + while(elInfo) { + Element *element = elInfo->getElement(); + int index = element->getIndex(); + + // get partition data + PartitionElementData *partitionData = dynamic_cast<PartitionElementData*> + (element->getElementData(PARTITION_ED)); + + // if element in partition + if(partitionData && + partitionData->getPartitionStatus() == IN && + partitionData->getLevel() == 0) + { + // remember index + setParMetisIndex(index, elementCounter); + setAMDiSIndex(elementCounter, index); + + // write eptr entry + nodeCounter += dim_ + 1; + *ptr_eptr = nodeCounter; + ptr_eptr++; + + // write eind entries (element nodes) + for(i = 0; i < dim_ + 1; i++) { + *ptr_eind = element->getDOF(i, 0); + ptr_eind++; + } + + // write xyz element coordinates + if(ptr_xyz) { + elInfo->coordToWorld(bary, &world); + for(i = 0; i < dim_; i++) { + *ptr_xyz = static_cast<float>(world[i]); + ptr_xyz++; + } + } + + elementCounter++; + } + elInfo = stack.traverseNext(elInfo); + } + } + + ParMetisMesh::~ParMetisMesh() + { + if(eptr_) FREE_MEMORY(eptr_, int, numElements_ + 1); + if(eind_) FREE_MEMORY(eind_, int, numElements_ * (dim_ + 1)); + if(elmdist_) FREE_MEMORY(elmdist_, int, MPI::COMM_WORLD.Get_size() + 1); + if(xyz_) FREE_MEMORY(xyz_, float, numElements_ * dim_); + if(elem_p2a_) FREE_MEMORY(elem_p2a_, int, numElements_); + } + + ParMetisGraph::ParMetisGraph(ParMetisMesh *parMetisMesh, + int ncommonnodes) + : parMetisMesh_(parMetisMesh) + { + int numflag = 0; + + if(ncommonnodes == -1) ncommonnodes = parMetisMesh->getDim(); + + MPI_Comm comm = MPI_COMM_WORLD; + + ParMETIS_V3_Mesh2Dual(parMetisMesh_->getElementDist(), + parMetisMesh_->getElementPtr(), + parMetisMesh_->getElementInd(), + &numflag, + &ncommonnodes, + &xadj_, + &adjncy_, + &comm); + } + + ParMetisGraph::~ParMetisGraph() + { + free(xadj_); + free(adjncy_); +// if(xadj_) delete [] xadj_; +// if(adjncy_) delete [] adjncy_; + } + + void ParMetisPartitioner::deletePartitionData() + { + TraverseStack stack; + ElInfo *elInfo; + elInfo = stack.traverseFirst(mesh_, -1, Mesh::CALL_EVERY_EL_PREORDER); + while(elInfo) { + Element *element = elInfo->getElement(); + element->deleteElementData(PARTITION_ED); + elInfo = stack.traverseNext(elInfo); + } + } + + void ParMetisPartitioner::createPartitionData() { + int mpiRank = MPI::COMM_WORLD.Get_rank(); + int mpiSize = MPI::COMM_WORLD.Get_size(); + + TraverseStack stack; + ElInfo *elInfo; + + // === create initial partitioning on AMDiS mesh === + int totalElementCounter = 0; + elInfo = stack.traverseFirst(mesh_, -1, Mesh::CALL_LEAF_EL); + while(elInfo) { + Element *element = elInfo->getElement(); + //int index = element->getIndex(); + + TEST_EXIT(element->getElementData(PARTITION_ED) == NULL) + ("mesh already partitioned\n"); + + PartitionElementData *elData = + NEW PartitionElementData(element->getElementData()); + element->setElementData(elData); + + if(totalElementCounter % mpiSize == mpiRank) { + elData->setPartitionStatus(IN); + } else { + elData->setPartitionStatus(UNDEFINED); + } + totalElementCounter++; + + elInfo = stack.traverseNext(elInfo); + } + +// elInfo = stack.traverseFirst(mesh_, -1, Mesh::CALL_LEAF_EL); +// while(elInfo) { +// Element *element = elInfo->getElement(); +// int index = element->getIndex(); + +// TEST_EXIT(element->getElementData(PARTITION_ED) == NULL) +// ("mesh already partitioned\n"); + +// PartitionElementData *elData = +// NEW PartitionElementData(element->getElementData()); +// element->setElementData(elData); +// elData->setPartitionStatus(UNDEFINED); +// elData->setLevel(0); +// elInfo = stack.traverseNext(elInfo); +// } + } + + void ParMetisPartitioner::partition(std::map<int, double> *elemWeights, + PartitionMode mode, + float itr) + { + int mpiSize = MPI::COMM_WORLD.Get_size(); + + TraverseStack stack; + ElInfo *elInfo; + + // === create initial partitioning on AMDiS mesh === + +// if(mode == INITIAL) { +// int totalElementCounter = 0; +// elInfo = stack.traverseFirst(mesh_, -1, Mesh::CALL_EVERY_EL_PREORDER); +// while(elInfo) { +// Element *element = elInfo->getElement(); +// int index = element->getIndex(); + +// // get partition data +// PartitionElementData *partitionData = dynamic_cast<PartitionElementData*> +// (element->getElementData(PARTITION_ED)); + +// if(partitionData && partitionData->getLevel() == 0) { +// if(totalElementCounter % mpiSize == mpiRank) { +// partitionData->setPartitionStatus(IN); +// } else { +// partitionData->setPartitionStatus(UNDEFINED); +// } +// totalElementCounter++; +// } +// elInfo = stack.traverseNext(elInfo); +// } +// } + + // === create parmetis mesh === + if(parMetisMesh_) DELETE parMetisMesh_; + parMetisMesh_ = NEW ParMetisMesh(mesh_); + + int numElements = parMetisMesh_->getNumElements(); + + // === create weight array === + int *wgts = elemWeights ? GET_MEMORY(int, numElements) : NULL; + float *floatWgts = elemWeights ? GET_MEMORY(float, numElements) : NULL; + float maxWgt = 0.0; + + float *ptr_floatWgts = floatWgts; + //int *ptr_wgts = wgts; + + elInfo = stack.traverseFirst(mesh_, -1, Mesh::CALL_EVERY_EL_PREORDER); + while(elInfo) { + Element *element = elInfo->getElement(); + + // get partition data + PartitionElementData *partitionData = dynamic_cast<PartitionElementData*> + (element->getElementData(PARTITION_ED)); + + if(partitionData && + partitionData->getPartitionStatus() == IN && + partitionData->getLevel() == 0) + { + int index = element->getIndex(); + + // get weight + float wgt = static_cast<float>((*elemWeights)[index]); + maxWgt = max(wgt, maxWgt); + + // write float weight + *ptr_floatWgts = wgt; + ptr_floatWgts++; + } + elInfo = stack.traverseNext(elInfo); + } + + float tmp; + MPI::COMM_WORLD.Allreduce(&maxWgt, + &tmp, + 1, + MPI_FLOAT, + MPI_MAX); + maxWgt = tmp; + + // === create dual graph === + ParMetisGraph parMetisGraph(parMetisMesh_); + + // === partitioning of dual graph === + MPI_Comm comm = MPI_COMM_WORLD; + + int i; + int wgtflag = elemWeights ? 2 : 0; // weights at vertices only! + int numflag = 0; // c numbering style! + //int ndims = mesh_->getDim(); + int ncon = elemWeights ? 1 : 0; // one weight at each vertex! + int nparts = mpiSize; // number of partitions + float *tpwgts = elemWeights ? GET_MEMORY(float, mpiSize) : NULL; + float ubvec = 1.05; + int options[3] = {0, 0, 0}; // default options + int edgecut = -1; + int *part = GET_MEMORY(int, numElements); + + if(elemWeights) { + for(i = 0; i < mpiSize; i++) { + // set tpwgts + tpwgts[i] = 1.0/nparts; + } + + float scale = 10000 / maxWgt; + for(i = 0; i < numElements; i++) { + // scale wgts + wgts[i] = static_cast<int>(floatWgts[i] * scale); + } + } + + switch(mode) { + case INITIAL: +// if(parMetisMesh_->getXYZ()) { +// ParMETIS_V3_PartGeomKway(parMetisMesh_->getElementDist(), +// parMetisGraph.getXAdj(), +// parMetisGraph.getAdjncy(), +// wgts, +// NULL, +// &wgtflag, +// &numflag, +// &ndims, +// parMetisMesh_->getXYZ(), +// &ncon, +// &nparts, +// tpwgts, +// &ubvec, +// options, +// &edgecut, +// part, +// &comm); + ParMETIS_V3_PartKway(parMetisMesh_->getElementDist(), + parMetisGraph.getXAdj(), + parMetisGraph.getAdjncy(), + wgts, + NULL, + &wgtflag, + &numflag, + &ncon, + &nparts, + tpwgts, + &ubvec, + options, + &edgecut, + part, + &comm); +// } else { +// ERROR_EXIT("not yet dim != dow (no xyz)\n"); +// } + break; + case ADAPTIVE_REPART: + { + int *vsize = GET_MEMORY(int, numElements); + for(i = 0; i < numElements; i++) { + vsize[i] = 1; + } + ParMETIS_V3_AdaptiveRepart(parMetisMesh_->getElementDist(), + parMetisGraph.getXAdj(), + parMetisGraph.getAdjncy(), + wgts, + NULL, + vsize, + &wgtflag, + &numflag, + &ncon, + &nparts, + tpwgts, + &ubvec, + &itr, + options, + &edgecut, + part, + &comm); + FREE_MEMORY(vsize, int, numElements); + } + break; + case REFINE_PART: + ParMETIS_V3_RefineKway(parMetisMesh_->getElementDist(), + parMetisGraph.getXAdj(), + parMetisGraph.getAdjncy(), + wgts, + NULL, + &wgtflag, + &numflag, + &ncon, + &nparts, + tpwgts, + &ubvec, + options, + &edgecut, + part, + &comm); + break; + default: + ERROR_EXIT("unknown partitioning mode\n"); + } + + // === distribute new partition data === + distributePartitioning(part); + + if(floatWgts) FREE_MEMORY(floatWgts, float, numElements); + if(wgts) FREE_MEMORY(wgts, int, numElements); + if(tpwgts) FREE_MEMORY(tpwgts, float, mpiSize); + FREE_MEMORY(part, int, numElements); + } + + void ParMetisPartitioner::fillCoarsePartitionVec(std::map<int, int> *partitionVec) + { + TEST_EXIT(partitionVec)("no partition vector\n"); + + partitionVec->clear(); + + // update ParMETIS mesh to new partitioning + if(!parMetisMesh_) parMetisMesh_ = NEW ParMetisMesh(mesh_); + + int i, j; + //int dim = mesh_->getDim(); + int mpiRank = MPI::COMM_WORLD.Get_rank(); + int mpiSize = MPI::COMM_WORLD.Get_size(); + + int *numPartitionElements = GET_MEMORY(int, mpiSize); + + int *elmdist = parMetisMesh_->getElementDist(); + for(i = 0; i < mpiSize; i++) { + numPartitionElements[i] = elmdist[i+1] - elmdist[i]; + } + + // === count number of elements === + int numElements = 0; + int localElements = parMetisMesh_->getNumElements(); + MPI::COMM_WORLD.Allreduce(&localElements, + &numElements, + 1, + MPI_INT, + MPI_SUM); + + int *partitionElements = GET_MEMORY(int, numElements); + + // distribute partition elements + MPI::COMM_WORLD.Allgatherv(parMetisMesh_->getAMDiSIndices(), + numPartitionElements[mpiRank], + MPI_INT, + partitionElements, + numPartitionElements, + elmdist, + MPI_INT); + + // fill partitionVec + for(i = 0; i < mpiSize; i++) { + for(j = 0; j < numPartitionElements[i]; j++) { + (*partitionVec)[partitionElements[elmdist[i] + j]] = i; + } + } + + FREE_MEMORY(partitionElements, int, numElements); + FREE_MEMORY(numPartitionElements, int, mpiSize); + } + + void ParMetisPartitioner::distributePartitioning(int *part) + { + int i; + int mpiSize = MPI::COMM_WORLD.Get_size(); + int mpiRank = MPI::COMM_WORLD.Get_rank(); + + int numElements = parMetisMesh_->getNumElements(); + + // count elements per partition in this rank + int *numPartitionElements = GET_MEMORY(int, mpiSize); + for(i = 0; i < mpiSize; i++) + numPartitionElements[i] = 0; + for(i = 0; i < numElements; i++) { + numPartitionElements[part[i]]++; + } + + // collect number of partition elements from all ranks for this rank + int *numRankElements = GET_MEMORY(int, mpiSize); + MPI::COMM_WORLD.Alltoall(numPartitionElements, 1, MPI_INT, + numRankElements, 1, MPI_INT); + + // sum up partition elements over all ranks + int *sumPartitionElements = GET_MEMORY(int, mpiSize); + + MPI::COMM_WORLD.Allreduce(numPartitionElements, + sumPartitionElements, + mpiSize, + MPI_INT, + MPI_SUM); + + + // prepare distribution (fill partitionElements with AMDiS indices) + int *bufferOffset = GET_MEMORY(int, mpiSize); + bufferOffset[0] = 0; + for(i = 1; i < mpiSize; i++) { + bufferOffset[i] = bufferOffset[i - 1] + numPartitionElements[i - 1]; + } + + int *partitionElements = GET_MEMORY(int, numElements); + int **partitionPtr = GET_MEMORY(int*, mpiSize); + + for(i = 0; i < mpiSize; i++) { + partitionPtr[i] = partitionElements + bufferOffset[i]; + } + + for(i = 0; i < numElements; i++) { + int partition = part[i]; + int amdisIndex = parMetisMesh_->getAMDiSIndex(i); + *(partitionPtr[partition]) = amdisIndex; + ++(partitionPtr[partition]); + } + + // all to all: partition elements to rank elements + int *rankElements = GET_MEMORY(int, sumPartitionElements[mpiRank]); + int *recvBufferOffset = GET_MEMORY(int, mpiSize); + recvBufferOffset[0] = 0; + for(i = 1; i < mpiSize; i++) { + recvBufferOffset[i] = recvBufferOffset[i - 1] + numRankElements[i - 1]; + } + + MPI::COMM_WORLD.Alltoallv(partitionElements, + numPartitionElements, + bufferOffset, + MPI_INT, + rankElements, + numRankElements, + recvBufferOffset, + MPI_INT); + + + // === partition AMDiS mesh === + + // write data in stl map + std::map<int, bool> elementInPartition; + for(i = 0; i < mpiSize; i++) { + int *rankPtr; + int *rankStart = rankElements + recvBufferOffset[i]; + int *rankEnd = rankStart + numRankElements[i]; + for(rankPtr = rankStart; rankPtr < rankEnd; ++rankPtr) { + elementInPartition[*rankPtr] = true; + } + } + + TraverseStack stack; + ElInfo *elInfo = stack.traverseFirst(mesh_, -1, Mesh::CALL_EVERY_EL_PREORDER); + while(elInfo) { + Element *element = elInfo->getElement(); + + // get partition data + PartitionElementData *partitionData = dynamic_cast<PartitionElementData*> + (element->getElementData(PARTITION_ED)); + + if(partitionData && partitionData->getLevel() == 0) { + int amdisIndex = element->getIndex(); + if(elementInPartition[amdisIndex]) { + partitionData->setPartitionStatus(IN); + } else { + partitionData->setPartitionStatus(OUT); + } + descendPartitionData(element); + } + + elInfo = stack.traverseNext(elInfo); + } + + DELETE parMetisMesh_; + parMetisMesh_ = NULL; + //parMetisMesh_ = NEW ParMetisMesh(mesh_); + +// MSG("rank %d partition elements: %d\n", +// mpiRank, sumPartitionElements[mpiRank]); + + FREE_MEMORY(rankElements, int, sumPartitionElements[mpiRank]); + FREE_MEMORY(numPartitionElements, int, mpiSize); + FREE_MEMORY(numRankElements, int, mpiSize); + FREE_MEMORY(sumPartitionElements, int, mpiSize); + FREE_MEMORY(partitionElements, int, numElements); + FREE_MEMORY(partitionPtr, int*, mpiSize); + FREE_MEMORY(bufferOffset, int, mpiSize); + FREE_MEMORY(recvBufferOffset, int, mpiSize); + } + + void ParMetisPartitioner::descendPartitionData(Element *element) + { + if(!element->isLeaf()) { + Element *child0 = element->getChild(0); + Element *child1 = element->getChild(1); + + // get partition data + PartitionElementData *parentData = dynamic_cast<PartitionElementData*> + (element->getElementData(PARTITION_ED)); + PartitionElementData *child0Data = dynamic_cast<PartitionElementData*> + (child0->getElementData(PARTITION_ED)); + PartitionElementData *child1Data = dynamic_cast<PartitionElementData*> + (child1->getElementData(PARTITION_ED)); + + TEST_EXIT(parentData && child0Data && child1Data)("no partition data\n"); + + child0Data->setPartitionStatus(parentData->getPartitionStatus()); + child1Data->setPartitionStatus(parentData->getPartitionStatus()); + + descendPartitionData(child0); + descendPartitionData(child1); + } + } + + + void ParMetisPartitioner::fillLeafPartitionVec(std::map<int, int> *coarseVec, + std::map<int, int> *fineVec) + { + int partition = -1; + TraverseStack stack; + ElInfo *elInfo = stack.traverseFirst(mesh_, -1, Mesh::CALL_EVERY_EL_PREORDER); + while(elInfo) { + Element *element = elInfo->getElement(); + PartitionElementData *partitionData = dynamic_cast<PartitionElementData*> + (element->getElementData(PARTITION_ED)); + if(partitionData) { + if(partitionData->getLevel() == 0) { + partition = (*(coarseVec))[element->getIndex()]; + } + if(element->isLeaf()) { + (*(fineVec))[element->getIndex()] = partition; + } + } + elInfo = stack.traverseNext(elInfo); + } + } +} diff --git a/AMDiS/src/ParMetisPartitioner.h b/AMDiS/src/ParMetisPartitioner.h new file mode 100644 index 0000000000000000000000000000000000000000..2a203c74cc48f7021a11fb8a243526279acb20db --- /dev/null +++ b/AMDiS/src/ParMetisPartitioner.h @@ -0,0 +1,155 @@ +// ============================================================================ +// == == +// == AMDiS - Adaptive multidimensional simulations == +// == == +// ============================================================================ +// == == +// == crystal growth group == +// == == +// == Stiftung caesar == +// == Ludwig-Erhard-Allee 2 == +// == 53175 Bonn == +// == germany == +// == == +// ============================================================================ +// == == +// == http://www.caesar.de/cg/AMDiS == +// == == +// ============================================================================ + +/** \file ParMetisPartitioner.h */ + +#ifndef AMDIS_PARMETISADAPTER_H +#define AMDIS_PARMETISADAPTER_H + +#include "parmetis.h" +#include <map> +#include <set> +#include "MemoryManager.h" + +namespace AMDiS { + + class FiniteElemSpace; + + enum PartitionMode { + INITIAL = 0, // initial partitioning of a unpartitioned mesh + ADAPTIVE_REPART = 1, // repartitioning of a adaptively refined mesh + REFINE_PART = 2 // quality improvement of the current partitioning + }; + + class ParMetisGraph; + class Mesh; + template<typename T > class DOFVector; + + class ParMetisMesh + { + public: + MEMORY_MANAGED(ParMetisMesh); + + ParMetisMesh(Mesh *mesh); + + ~ParMetisMesh(); + + inline void setParMetisIndex(int amdisIndex, + int parMetisIndex) + { +// if(MPI::COMM_WORLD.Get_rank() == 0) +// MSG("set %p %d %d\n", this, amdisIndex, parMetisIndex); + elem_a2p_[amdisIndex] = parMetisIndex + 1; + }; + + inline int getParMetisIndex(int amdisIndex) { + int result = elem_a2p_[amdisIndex]; +// if(MPI::COMM_WORLD.Get_rank() == 0) +// MSG("get %p %d %d\n", this, amdisIndex, result - 1); + TEST_EXIT(result > 0)("invalid index\n"); + return result - 1; + }; + + inline void setAMDiSIndex(int parMetisIndex, + int amdisIndex) + { + elem_p2a_[parMetisIndex] = amdisIndex; + }; + + inline int getAMDiSIndex(int parMetisIndex) { + return elem_p2a_[parMetisIndex]; + }; + + inline int *getAMDiSIndices() { + return elem_p2a_; + }; + + inline int *getElementPtr() { return eptr_; }; + inline int *getElementInd() { return eind_; }; + inline int *getElementDist() { return elmdist_; }; + inline int getDim() { return dim_; }; + inline float *getXYZ() { return xyz_; }; + inline int getNumElements() { return numElements_; }; + + protected: + int *eptr_; + int *eind_; + int *elmdist_; + int dim_; + float *xyz_; + + int numElements_; + + std::map<int, int> elem_a2p_; + int *elem_p2a_; + }; + + class ParMetisGraph + { + public: + MEMORY_MANAGED(ParMetisGraph); + + ParMetisGraph(ParMetisMesh *parMetisMesh, + int ncommonnodes = -1); + + ~ParMetisGraph(); + + inline int *getXAdj() { return xadj_; }; + inline int *getAdjncy() { return adjncy_; }; + + protected: + ParMetisMesh *parMetisMesh_; + + int *xadj_; + int *adjncy_; + }; + + class ParMetisPartitioner + { + public: + ParMetisPartitioner(Mesh *mesh) + : mesh_(mesh), + parMetisMesh_(NULL) + {}; + + void partition(std::map<int, double> *elemWeights, + PartitionMode mode = INITIAL, + float itr = 1000000.0); + + void fillCoarsePartitionVec(std::map<int, int> *partitionVec); + + void fillLeafPartitionVec(std::map<int, int> *coarseVec, + std::map<int, int> *fineVec); + + void createPartitionData(); + + void deletePartitionData(); + + protected: + void distributePartitioning(int *part); + + void descendPartitionData(Element *element); + + protected: + Mesh *mesh_; + ParMetisMesh *parMetisMesh_; + }; +} + +#endif diff --git a/AMDiS/src/ParallelError.h b/AMDiS/src/ParallelError.h new file mode 100644 index 0000000000000000000000000000000000000000..560fe7a8d68e4653fba598396edb1838e5ce606f --- /dev/null +++ b/AMDiS/src/ParallelError.h @@ -0,0 +1,159 @@ +// ============================================================================ +// == == +// == AMDiS - Adaptive multidimensional simulations == +// == == +// ============================================================================ +// == == +// == crystal growth group == +// == == +// == Stiftung caesar == +// == Ludwig-Erhard-Allee 2 == +// == 53175 Bonn == +// == germany == +// == == +// ============================================================================ +// == == +// == http://www.caesar.de/cg/AMDiS == +// == == +// ============================================================================ + +/** \file ParallelError.h */ + +#ifndef AMDIS_PARALLELERROR_H +#define AMDIS_PARALLELERROR_H + +#include "Global.h" +#include "Mesh.h" +#include "MemoryManager.h" + +namespace AMDiS { + + class FastQuadrature; + + template<typename T> class DOFVector; + + // ============================================================================ + // ===== class ParallelError ========================================================== + // ============================================================================ + + /** \ingroup Common + * \brief + * True error calculator + */ + template<typename T> + class ParallelError + { + public: + MEMORY_MANAGED(ParallelError<T>); + + static void setWriteLeafData() { writeInLeafData = true; }; + static void unsetWriteLeafData() { writeInLeafData = false; }; + static bool writeLeafData() { return writeInLeafData; }; + + static double maxErrAtQp(const AbstractFunction<T, WorldVector<double> >& u, + const DOFVector<T>& uh, + const Quadrature* q); + static double + H1Err(const AbstractFunction<WorldVector<T>, WorldVector<double> >& grdU, + const DOFVector<T>& uh, + //const Quadrature* quad, + int relErr, + double* max, + bool writeLeafData = false, + int comp = 0); + + static double L2Err(const AbstractFunction<T, WorldVector<double> >& u, + const DOFVector<T>& uh, + //Quadrature* quad, + int relErr, + double* max, + bool writeLeafData = false, + int comp = 0); + + // methods for traversal + static int maxErrAtQpFct(ElInfo* elinfo); + static int H1ErrFct(ElInfo* elinfo); + static int L2ErrFct(ElInfo* elinfo); + static int relFct(ElInfo* elinfo); + + public: + static const T& errUFct(const DimVec<double>& lambda); + + static const WorldVector<T>& grdErrUFct(const DimVec<double>& lambda); + + /** \brief + * + */ + class AbstrFctErrU : public AbstractFunction<T, DimVec<double> > + { + public: + AbstrFctErrU() : AbstractFunction<T, DimVec<double> >(0) {}; + + inline const T& operator()(const DimVec<double> & x) const { + return ParallelError<T>::errUFct(x); + }; + }; + + static AbstrFctErrU errU; + + /** \brief + * + */ + class AbstrFctGrdErrU : public AbstractFunction<WorldVector<T>, DimVec<double> > + { + public: + AbstrFctGrdErrU() : AbstractFunction<WorldVector<T>, DimVec<double> >(0) {}; + + inline const WorldVector<T>& operator()(const DimVec<double> & x) const { + return ParallelError<T> :: grdErrUFct (x); + }; + }; + + static AbstrFctGrdErrU grdErrU; + + private: + static ElInfo* elinfo; + /* static const Parametric* el_parametric; */ + static const FastQuadrature* quadFast; + static const AbstractFunction<T, WorldVector<double> >* pU; + static const AbstractFunction<WorldVector<T>, WorldVector<double> >* pGrdU; + static const BasisFunction* basFct; + static const DOFVector<T>* errUh; + static double maxErr; + static double l2Err2; + static double l2Norm2; + static int relative; + static double relNorm2; + static double h1Err2; + static double h1Norm2; + static bool writeInLeafData; + static int component; + }; + + template<typename T> ElInfo* ParallelError<T>::elinfo = NULL; + /* template<typename T> const Parametric* ParallelError<T>::el_parametric = NULL; */ + template<typename T> const FastQuadrature* ParallelError<T>::quadFast = NULL; + template<typename T> const AbstractFunction<T, WorldVector<double> >* ParallelError<T>::pU = NULL; + template<typename T> const AbstractFunction<WorldVector<T>, WorldVector<double> >* ParallelError<T>::pGrdU = NULL; + template<typename T> const BasisFunction* ParallelError<T>::basFct = NULL; + template<typename T> const DOFVector<T>* ParallelError<T>::errUh = NULL; + template<typename T> double ParallelError<T>::maxErr = 0.0; + template<typename T> double ParallelError<T>::l2Err2 = 0.0; + template<typename T> double ParallelError<T>::l2Norm2 = 0.0; + template<typename T> int ParallelError<T>::relative = 0; + template<typename T> double ParallelError<T>::relNorm2 = 0.0; + template<typename T> double ParallelError<T>::h1Err2 = 0.0; + template<typename T> double ParallelError<T>::h1Norm2 = 0.0; + template<typename T> typename ParallelError<T>::AbstrFctErrU ParallelError<T>::errU; + template<typename T> typename ParallelError<T>::AbstrFctGrdErrU ParallelError<T>::grdErrU; + template<typename T> bool ParallelError<T>::writeInLeafData = false; + template<typename T> int ParallelError<T>::component = 0; + +} + +#include "ParallelError.hh" + +#endif // AMDIS_ERROR_H + + + diff --git a/AMDiS/src/ParallelError.hh b/AMDiS/src/ParallelError.hh new file mode 100644 index 0000000000000000000000000000000000000000..e72b53efbe9bb64d87559fc43c528bf7b62c0036 --- /dev/null +++ b/AMDiS/src/ParallelError.hh @@ -0,0 +1,475 @@ +#include "Mesh.h" +#include "Parametric.h" +#include "Quadrature.h" +#include "PartitionElementData.h" + +namespace AMDiS { + + template<typename T> + const T& ParallelError<T>::errUFct(const DimVec<double>& lambda) + { + WorldVector<double> x; + // if (el_parametric) { + // ERROR_EXIT("not yet\n"); + // } else { + elinfo->coordToWorld(lambda, &x); + // } + return((*pU)(x)); + } + + template<typename T> + const WorldVector<T>& ParallelError<T>::grdErrUFct(const DimVec<double>& lambda) + { + WorldVector<double> x; + // if (el_parametric) { + // ERROR_EXIT("not yet\n"); + // } else { + elinfo->coordToWorld(lambda, &x); + // } + return((*pGrdU)(x)); + } + + + template<typename T> + int ParallelError<T>::maxErrAtQpFct(ElInfo* el_info) + { + int i; + double err; + const double *u_vec, *uh_vec; + // Parametric *parametric = el_info->getMesh()->getParametric(); + + elinfo = el_info; + // if (parametric && parametric->initElement(el_info)) { + // el_parametric = parametric; + // } else { + // el_parametric = NULL; + // } + + u_vec = quadFast->getQuadrature()->fAtQp(errU, NULL); + + //uh_el = errUh->getLocalVector(el_info->getElement(), NULL); + //uh_vec = quadFast->uhAtQp(uh_el, NULL); + + uh_vec = errUh->getVecAtQPs(el_info, + NULL, + quadFast, + NULL); + + int numPoints = quadFast->getNumPoints(); + + for (i = 0; i < numPoints; i++) + { + err = u_vec[i] > uh_vec[i] ? u_vec[i] - uh_vec[i] : uh_vec[i] - u_vec[i]; + maxErr = max(maxErr, err); + } + + return; + } + + template<typename T> + double ParallelError<T>::maxErrAtQp(const AbstractFunction<T, WorldVector<double> >& u, + const DOFVector<T>& uh, + const Quadrature* q) + { + FUNCNAME("ParallelError<T>::maxErrAtQp"); + const FiniteElemSpace *fe_space; + + if (!(pU = &u)) + { + ERROR("no function u specified; doing nothing\n"); + return(-1.0); + } + if (!(errUh = &uh) || !(fe_space = uh->getFESpace())) + { + ERROR("no discrete function or no fe_space for it; doing nothing\n"); + return(-1.0); + } + + if (!(basFct = fe_space->getBasisFcts())) + { + ERROR("no basis functions at discrete solution ; doing nothing\n"); + return(-1.0); + } + + int dim = fe_space->getMesh()->getDim(); + + if (!q) + q = Quadrature::provideQuadrature(dim, + 2*fe_space->getBasisFcts()->getDegree() + - 2); + quadFast = FastQuadrature::provideFastQuadrature(basFct, *q, INIT_PHI); + + maxErr = 0.0; + + + TraverseStack stack; + ElInfo *elInfo = stack.traverseFirst(fe_space->getMesh(), -1, + Mesh::FILL_COORDS | + Mesh::CALL_LEAF_EL); + while(elInfo) { + PartitionElementData *partitionData = dynamic_cast<PartitionElementData*> + (elInfo->getElement()->getElementData(PARTITION_ED)); + TEST_EXIT(partitionData)("no partition data\n"); + if(partitionData && partitionData->getPartitionStatus() == IN) { + maxErrAtQpFct(elInfo); + } + elInfo = stack.traverseNext(elInfo); + } + + // fe_space->getMesh()->traverse(-1, + // Mesh::FILL_COORDS | + // Mesh::CALL_LEAF_EL, + // maxErrAtQpFct); + + return(maxErr); + } + + template<typename T> + int ParallelError<T>::H1ErrFct(ElInfo* el_info) + { + int i, j; + double err, err_2, h1_err_el, norm_el, norm2, det, exact; + //int dim = el_info->getMesh()->getDim(); + //const DimVec<WorldVector<double> > &Lambda = el_info->getGrdLambda(); + //const T *uh_el; + const WorldVector<double> *grdu_vec, *grduh_vec; + // const Parametric *parametric = el_info->getMesh()->getParametric(); + + elinfo = el_info; + // if (parametric && parametric->initElement(el_info)) { + // el_parametric = parametric; + // } + // else { + // el_parametric = NULL; + // } + + grdu_vec = quadFast->getQuadrature()->grdFAtQp(grdErrU, NULL); + + //uh_el = errUh->getLocalVector(el_info->getElement(), NULL); + + // if (el_parametric) { + // el_parametric->grd_lambda(el_info, NULL, 1, NULL, &Lambda, &det); + // } + // else { + det = el_info->getDet(); + // } + + //grduh_vec = quadFast->grdUhAtQp(Lambda, uh_el, NULL); + grduh_vec = errUh->getGrdAtQPs(elinfo, NULL, quadFast, NULL); + + int numPoints = quadFast->getNumPoints(); + int dow = Global::getGeo(WORLD); + + for (h1_err_el = i = 0; i < numPoints; i++) + { + for (err_2 = j = 0; j < dow; j++) + { + err = grdu_vec[i][j] - grduh_vec[i][j]; + err_2 += sqr(err); + } + h1_err_el += quadFast->getWeight(i)*err_2; + } + + exact = det*h1_err_el; + h1Err2 += exact; + maxErr = max(maxErr, exact); + + if(writeInLeafData) + el_info->getElement()->setEstimation(exact, component); + + if (relative) + { + for (norm_el = i = 0; i < numPoints; i++) + { + for (norm2 = j = 0; j < dow; j++) + norm2 += sqr(grdu_vec[i][j]); + norm_el += quadFast->getWeight(i)*norm2; + } + h1Norm2 += det*norm_el; + } + + return 0; + } + + template<typename T> + double ParallelError<T>::H1Err( + const AbstractFunction<WorldVector<T>, WorldVector<double> >& grdU, + const DOFVector<T>& uh, + //const Quadrature* quad, + int relErr, + double* max, + bool writeLeafData, + int comp) + { + FUNCNAME("ParallelError<T>::H1Err"); + const FiniteElemSpace *fe_space; + + writeInLeafData = writeLeafData; + + component = comp; + + Quadrature *q = NULL; + + pGrdU = &grdU; + + errUh = &uh; + + if(!(fe_space = uh.getFESpace())) + { + ERROR("no fe_space for uh; doing nothing\n"); + return(0.0); + } + + if (!(basFct = fe_space->getBasisFcts())) + { + ERROR("no basis functions at discrete solution ; doing nothing\n"); + return(0.0); + } + + int dim = fe_space->getMesh()->getDim(); + int deg = grdU.getDegree(); + int degree = deg ? deg : 2 * fe_space->getBasisFcts()->getDegree() - 2; + + //if (!quad) + q = Quadrature::provideQuadrature(dim, degree); + quadFast = FastQuadrature::provideFastQuadrature(basFct, + *q, + INIT_GRD_PHI); + + relative = relErr; + + maxErr = h1Err2 = h1Norm2 = 0.0; + + + TraverseStack stack; + ElInfo *elInfo = stack.traverseFirst(fe_space->getMesh(), -1, + Mesh::FILL_COORDS | + Mesh::CALL_LEAF_EL | + Mesh::FILL_DET | + Mesh::FILL_GRD_LAMBDA); + while(elInfo) { + PartitionElementData *partitionData = dynamic_cast<PartitionElementData*> + (elInfo->getElement()->getElementData(PARTITION_ED)); + TEST_EXIT(partitionData)("no partition data\n"); + if(partitionData && partitionData->getPartitionStatus() == IN) { + H1ErrFct(elInfo); + } + elInfo = stack.traverseNext(elInfo); + } + + // fe_space->getMesh()->traverse(-1, + // Mesh::FILL_COORDS | + // Mesh::CALL_LEAF_EL | + // Mesh::FILL_DET | + // Mesh::FILL_GRD_LAMBDA, + // H1ErrFct); + + if (relative) { + relNorm2 = h1Norm2+1.e-15; + + TraverseStack stack; + ElInfo *elInfo = stack.traverseFirst(fe_space->getMesh(), -1, + Mesh::CALL_LEAF_EL); + while(elInfo) { + PartitionElementData *partitionData = dynamic_cast<PartitionElementData*> + (elInfo->getElement()->getElementData(PARTITION_ED)); + TEST_EXIT(partitionData)("no partition data\n"); + if(partitionData && partitionData->getPartitionStatus() == IN) { + relFct(elInfo); + } + elInfo = stack.traverseNext(elInfo); + } + + // fe_space->getMesh()->traverse(-1, + // Mesh::CALL_LEAF_EL, + // relFct); + + h1Err2 /= relNorm2; + maxErr /= relNorm2; + } + + if (max) { + double totalMax; + MPI::COMM_WORLD.Allreduce(&maxErr, &totalMax, 1, MPI_DOUBLE, MPI_MAX); + *max = totalMax; + } + + double totalH1Err2; + MPI::COMM_WORLD.Allreduce(&h1Err2, &totalH1Err2, 1, MPI_DOUBLE, MPI_SUM); + + return(sqrt(totalH1Err2)); + } + + template<typename T> + int ParallelError<T>::L2ErrFct(ElInfo* el_info) + { + int i; + double err, det, l2_err_el, norm_el, exact; + const double *u_vec, *uh_vec; + // Parametric *parametric = const_cast<Parametric*>(el_info->getMesh()->getParametric()); + + elinfo = el_info; + + // if (parametric && parametric->initElement(el_info)) { + // el_parametric = parametric; + // } + // else { + // el_parametric = NULL; + // } + + u_vec = quadFast->getQuadrature()->fAtQp(errU, NULL); + + //uh_el = errUh->getLocalVector(el_info->getElement(), NULL); + //uh_vec = quadFast->uhAtQp(uh_el, NULL); + + uh_vec = errUh->getVecAtQPs(el_info, + NULL, + quadFast, + NULL); + + // if (el_parametric) { + // el_parametric->det(el_info, NULL, 1, NULL, &det); + // } + // else { + // det = el_info->calcDet(); + // } + + det = el_info->getDet(); + + int numPoints = quadFast->getNumPoints(); + + for (l2_err_el = i = 0; i < numPoints; i++) + { + err = u_vec[i] - uh_vec[i]; + l2_err_el += quadFast->getWeight(i)*sqr(err); + } + + exact = det*l2_err_el; + l2Err2 += exact; + maxErr = max(maxErr, exact); + + if(writeInLeafData) { + el_info->getElement()->setEstimation(exact, component); + } + + if (relative) + { + for (norm_el = i = 0; i < numPoints; i++) + norm_el += quadFast->getWeight(i)*sqr(u_vec[i]); + l2Norm2 += det*norm_el; + } + + return 0; + } + + template<typename T> + double ParallelError<T>::L2Err(const AbstractFunction<T, WorldVector<double> >& u, + const DOFVector<T>& uh, + //Quadrature* quad, + int relErr, + double* max, + bool writeLeafData, + int comp) + { + FUNCNAME("ParallelError<T>::L2Err"); + const FiniteElemSpace *fe_space; + + Quadrature *q = NULL; + + writeInLeafData = writeLeafData; + + component = comp; + + if (!(pU = &u)) + { + ERROR("no function u specified; doing nothing\n"); + return(0.0); + } + if (!(errUh = &uh) || !(fe_space = uh.getFESpace())) + { + ERROR("no discrete function or no fe_space for it; doing nothing\n"); + return(0.0); + } + + if (!(basFct = fe_space->getBasisFcts())) + { + ERROR("no basis functions at discrete solution ; doing nothing\n"); + return(0.0); + } + + int dim = fe_space->getMesh()->getDim(); + int deg = u.getDegree(); + int degree = deg ? deg : 2 * fe_space->getBasisFcts()->getDegree() - 2; + + //if (!quad) + q = Quadrature::provideQuadrature(dim, degree); + quadFast = FastQuadrature::provideFastQuadrature(basFct, *q, INIT_PHI); + + relative = relErr; + + maxErr = l2Err2 = l2Norm2 = 0.0; + + TraverseStack stack; + ElInfo *elInfo = stack.traverseFirst(fe_space->getMesh(), -1, + Mesh::FILL_COORDS | + Mesh::FILL_DET | + Mesh::FILL_GRD_LAMBDA | + Mesh::CALL_LEAF_EL); + while(elInfo) { + PartitionElementData *partitionData = dynamic_cast<PartitionElementData*> + (elInfo->getElement()->getElementData(PARTITION_ED)); + TEST_EXIT(partitionData)("no partition data\n"); + if(partitionData && partitionData->getPartitionStatus() == IN) { + L2ErrFct(elInfo); + } + elInfo = stack.traverseNext(elInfo); + } + + // fe_space->getMesh()->traverse(-1, + // Mesh::FILL_COORDS | + // Mesh::FILL_DET | + // Mesh::FILL_GRD_LAMBDA | + // Mesh::CALL_LEAF_EL, + // L2ErrFct); + + if (relative) { + relNorm2 = l2Norm2+1.e-15; + elInfo = stack.traverseFirst(fe_space->getMesh(), -1, + Mesh::CALL_LEAF_EL); + while(elInfo) { + PartitionElementData *partitionData = dynamic_cast<PartitionElementData*> + (elInfo->getElement()->getElementData(PARTITION_ED)); + TEST_EXIT(partitionData)("no partition data\n"); + if(partitionData && partitionData->getPartitionStatus() == IN) { + relFct(elInfo); + } + elInfo = stack.traverseNext(elInfo); + } + + // fe_space->getMesh()->traverse(-1, Mesh::CALL_LEAF_EL, relFct); + l2Err2 /= relNorm2; + } + + if (max) { + double totalMax; + MPI::COMM_WORLD.Allreduce(&maxErr, &totalMax, 1, MPI_DOUBLE, MPI_MAX); + *max = totalMax; + } + + double totalL2Err2; + MPI::COMM_WORLD.Allreduce(&l2Err2, &totalL2Err2, 1, MPI_DOUBLE, MPI_SUM); + + return(sqrt(totalL2Err2)); + } + + template<typename T> + int ParallelError<T>::relFct(ElInfo* elinfo) + { + double exact = elinfo->getElement()->getEstimation(component); + exact /= relNorm2; + if(writeInLeafData) + elinfo->getElement()->setEstimation(exact, component); + return 0; + } + +} diff --git a/AMDiS/src/ParallelProblem.cc b/AMDiS/src/ParallelProblem.cc new file mode 100644 index 0000000000000000000000000000000000000000..99f736724a4ac058854c66535276fcca2767286d --- /dev/null +++ b/AMDiS/src/ParallelProblem.cc @@ -0,0 +1,2107 @@ +#include "ParallelProblem.h" +#include "ProblemScal.h" +#include "ProblemVec.h" +#include "ProblemInstat.h" +#include "AdaptInfo.h" +#include "AdaptStationary.h" +#include "ConditionalEstimator.h" +#include "ConditionalMarker.h" +#include "Traverse.h" +#include "ElInfo.h" +#include "Element.h" +#include "PartitionElementData.h" +#include "ParMetisPartitioner.h" +#include "Mesh.h" +#include "DualTraverse.h" +#include "MeshStructure.h" +#include "DOFVector.h" +#include "FiniteElemSpace.h" +#include "RefinementManager.h" +#include "CoarseningManager.h" +#include "Lagrange.h" +#include "ElementFileWriter.h" +#include "MacroWriter.h" +#include "ValueWriter.h" +#include "SystemVector.h" +#include "mpi.h" +#include <queue> + +namespace AMDiS { + + bool elementInPartition(ElInfo *elInfo) + { + PartitionElementData *elementData = dynamic_cast<PartitionElementData*> + (elInfo->getElement()->getElementData(PARTITION_ED)); + if(elementData && elementData->getPartitionStatus() == IN) { + return true; + } else { + return false; + } + } + + class MyDualTraverse : public DualTraverse + { + public: + MyDualTraverse(int coarseLevel) + : coarseLevel_(coarseLevel) + {}; + + bool skipEl1(ElInfo *elInfo) + { + PartitionElementData *elementData = dynamic_cast<PartitionElementData*> + (elInfo->getElement()->getElementData(PARTITION_ED)); + if(elementData) { + if(elInfo->getElement()->isLeaf() && + elementData->getLevel() < coarseLevel_) + return false; + if(elementData->getLevel() == coarseLevel_) + return false; + } + return true; + }; + private: + int coarseLevel_; + }; + + // ========================================================================= + // ===== class ParallelProblemBase ========================================= + // ========================================================================= + + ParallelProblemBase::ParallelProblemBase(ProblemIterationInterface *iterationIF, + ProblemTimeInterface *timeIF) + : iterationIF_(iterationIF), + timeIF_(timeIF) + { + mpiRank_ = MPI::COMM_WORLD.Get_rank(); + mpiSize_ = MPI::COMM_WORLD.Get_size(); + } + + // ========================================================================= + // ===== class ParallelProblem ============================================= + // ========================================================================= + + ParallelProblem::ParallelProblem(const std::string& name, + ProblemIterationInterface *iterationIF, + ProblemTimeInterface *timeIF, + std::vector<DOFVector<double>*> vectors, + Mesh *mesh, + RefinementManager *rm, + CoarseningManager *cm) + : ParallelProblemBase(iterationIF, timeIF), + name_(name), + mesh_(mesh), + refinementManager_(rm), + coarseningManager_(cm), + repartitionSteps_(1), + puEveryTimestep_(false), + dofVectors_(vectors), + upperPartThreshold_(1.5), + lowerPartThreshold_(2.0/3.0), + globalCoarseGridLevel_(0), + localCoarseGridLevel_(0), + globalRefinements_(0), + adaptiveThresholds_(0), + thresholdIncFactor_(2.0), + thresholdDecFactor_(0.5), + repartTimeFactor_(10.0) + { + GET_PARAMETER(0, name_ + "->upper part threshold", "%f", + &upperPartThreshold_); + GET_PARAMETER(0, name_ + "->lower part threshold", "%f", + &lowerPartThreshold_); + GET_PARAMETER(0, name_ + "->global coarse grid level", "%d", + &globalCoarseGridLevel_); + GET_PARAMETER(0, name_ + "->local coarse grid level", "%d", + &localCoarseGridLevel_); + GET_PARAMETER(0, name_ + "->global refinements", "%d", + &globalRefinements_); + + + TEST_EXIT(localCoarseGridLevel_ >= globalCoarseGridLevel_) + ("local coarse grid level < global coarse grid level\n"); + + partitioner_ = NEW ParMetisPartitioner(mesh_); + + GET_PARAMETER(0, name_ + "->adaptive thresholds", "%d", + &adaptiveThresholds_); + GET_PARAMETER(0, name_ + "->threshold inc factor", "%f", + &thresholdIncFactor_); + GET_PARAMETER(0, name_ + "->threshold dec factor", "%f", + &thresholdDecFactor_); + GET_PARAMETER(0, name_ + "->repart time factor", "%f", + &repartTimeFactor_); + + + TEST_EXIT(lowerPartThreshold_ <= 1.0)("invalid lower part threshold\n"); + TEST_EXIT(upperPartThreshold_ >= 1.0)("invalid upper part threshold\n"); + + if (adaptiveThresholds_) { + TEST_EXIT(thresholdDecFactor_ <= 1.0)("invalid threshold dec factor\n"); + TEST_EXIT(thresholdIncFactor_ >= 1.0)("invalid threshold inc factor\n"); + } + minUpperTH_ = upperPartThreshold_; + maxLowerTH_ = lowerPartThreshold_; + } + + ParallelProblem::~ParallelProblem() + { + DELETE partitioner_; + } + + bool ParallelProblem::doPartitioning(AdaptInfo *adaptInfo, double localWeightSum) + { + FUNCNAME("ParallelProblem::doPartitioning()"); + + double *weightSum = GET_MEMORY(double, mpiSize_); + int *partArray = GET_MEMORY(int, mpiSize_); + int part; + + //weightSum[mpiRank_] = localWeightSum; + + MPI::COMM_WORLD.Gather(&localWeightSum, 1, MPI_DOUBLE, + weightSum, 1, MPI_DOUBLE, 0); + + if(mpiRank_ == 0) { + + double average = 0.0; + int i; + for(i = 0; i < mpiSize_; i++) { + average += weightSum[i]; + } + + average /= mpiSize_; + + //MSG("average weight: %f\n", average); + + part = 0; + for(i = 0; i < mpiSize_; i++) { + //MSG("weight sum %d: %f\n", i, weightSum[i]); + + if((weightSum[i] / average) > upperPartThreshold_) { + part = 1; + break; + } + if((weightSum[i] / average) < lowerPartThreshold_) { + part = 1; + break; + } + } + + //MSG("upper threshold initial: %f\n", upperPartThreshold_); + //MSG("lower threshold initial: %f\n", lowerPartThreshold_); + //MSG("part initial: %d\n", part); + + double computationTime = TIME_USED(computationStart, clock()); + if (adaptiveThresholds_) { + + bool timeOver = ((computationTime / partitioningTime) >= repartTimeFactor_); + + if (part == 1 && !timeOver) { + // inc thresholds + upperPartThreshold_ *= thresholdIncFactor_; + lowerPartThreshold_ /= thresholdIncFactor_; + + // avoid repartitioning + part = 0; + } + + if (part == 0 && timeOver) { + // dec thresholds + upperPartThreshold_ *= thresholdDecFactor_; + lowerPartThreshold_ /= thresholdDecFactor_; + + upperPartThreshold_ = max(minUpperTH_, upperPartThreshold_); + lowerPartThreshold_ = min(maxLowerTH_, lowerPartThreshold_); + } + } + + //MSG("comp time: %f\n", computationTime); + //MSG("part time: %f\n", partitioningTime); + //MSG("time quotient: %f\n", computationTime/partitioningTime); + //MSG("upper threshold final: %f\n", upperPartThreshold_); + //MSG("lower threshold final: %f\n", lowerPartThreshold_); + //MSG("part final: %d\n", part); + + for(i = 0; i < mpiSize_; i++) { + partArray[i] = part; + } + } + + MPI::COMM_WORLD.Scatter(partArray, 1, MPI_INT, + &part, 1, MPI_INT, 0); + + + //MSG("rank %d: part: %d\n", mpiRank_, part); + + + FREE_MEMORY(weightSum, double, mpiSize_); + FREE_MEMORY(partArray, int, mpiSize_); + + return (part == 1); + } + + bool ParallelProblem::doBuildGlobalSolution(AdaptInfo *adaptInfo) { + return true; +// (puEveryTimestep_ || !timeIF_ || +// (adaptInfo->getTimestepNumber() % repartitionSteps_ == 0) || +// adaptInfo->getTime() >= adaptInfo->getEndTime()); + } + + void ParallelProblem::partitionMesh(AdaptInfo *adaptInfo) + { + static bool initial = true; + if(initial) { + initial = false; + partitioner_->fillCoarsePartitionVec(&oldPartitionVec_); + partitioner_->partition(&elemWeights_, INITIAL); + } else { + oldPartitionVec_ = partitionVec_; + partitioner_->partition(&elemWeights_, ADAPTIVE_REPART, 100.0 /*0.000001*/); + } + + partitioner_->fillCoarsePartitionVec(&partitionVec_); + } + + void ParallelProblem::refineOverlap(AdaptInfo *adaptInfo) + { + int i, dim = mesh_->getDim(); + + bool finished = (localCoarseGridLevel_ == 0); + + //for(j = globalCoarseGridLevel_; j < localCoarseGridLevel_; j++) { + while(!finished) { + std::map<DegreeOfFreedom, int> inOut; // 1: in, 2: out, 3: border dof + + // mark in/out/border dofs + TraverseStack stack; + ElInfo *elInfo = stack.traverseFirst(mesh_, -1, Mesh::CALL_LEAF_EL); + while(elInfo) { + Element *element = elInfo->getElement(); + PartitionElementData *partitionData = + dynamic_cast<PartitionElementData*>(elInfo->getElement()->getElementData(PARTITION_ED)); + + const DegreeOfFreedom **dofs = element->getDOF(); + + if(partitionData->getPartitionStatus() == IN) { + for(i = 0; i < dim + 1; i++) { + DegreeOfFreedom dof = dofs[i][0]; + if(inOut[dof] == 2) inOut[dof] = 3; + if(inOut[dof] == 0) inOut[dof] = 1; + } + } else { + for(i = 0; i < dim + 1; i++) { + DegreeOfFreedom dof = dofs[i][0]; + if(inOut[dof] == 1) inOut[dof] = 3; + if(inOut[dof] == 0) inOut[dof] = 2; + } + } + + elInfo = stack.traverseNext(elInfo); + } + + // refine overlap-border and inner elements + finished = true; + bool marked = false; + elInfo = stack.traverseFirst(mesh_, -1, Mesh::CALL_LEAF_EL); + while(elInfo) { + Element *element = elInfo->getElement(); + PartitionElementData *partitionData = + dynamic_cast<PartitionElementData*>(elInfo->getElement()->getElementData(PARTITION_ED)); + + int level = partitionData->getLevel(); + + if(level < localCoarseGridLevel_) { + if(partitionData->getPartitionStatus() != IN) { + const DegreeOfFreedom **dofs = element->getDOF(); + for(i = 0; i < dim + 1; i++) { + DegreeOfFreedom dof = dofs[i][0]; + if(inOut[dof] == 3) { + element->setMark(1); + marked = true; + if((level + 1) < localCoarseGridLevel_) finished = false; + break; + } + } + } else { + element->setMark(1); + marked = true; + if((level + 1) < localCoarseGridLevel_) finished = false; + } + } + + elInfo = stack.traverseNext(elInfo); + } + if(marked) refinementManager_->refineMesh(mesh_); + } + } + + void ParallelProblem::globalRefineOutOfPartition(AdaptInfo *adaptInfo) + { + TraverseStack stack; + ElInfo *elInfo = stack.traverseFirst(mesh_, -1, Mesh::CALL_LEAF_EL); + while(elInfo) { + PartitionElementData *partitionData = + dynamic_cast<PartitionElementData*>(elInfo->getElement()->getElementData(PARTITION_ED)); + int refinements = globalCoarseGridLevel_ - partitionData->getLevel(); + elInfo->getElement()->setMark(max(0, refinements)); + elInfo = stack.traverseNext(elInfo); + } + + refinementManager_->refineMesh(mesh_); + } + + void ParallelProblem::coarsenOutOfPartition(AdaptInfo *adaptInfo) + { + Flag meshCoarsened = 1; + while(meshCoarsened.getFlags() != 0) { + TraverseStack stack; + ElInfo *elInfo = stack.traverseFirst(mesh_, -1, Mesh::CALL_LEAF_EL); + while(elInfo) { + Element *element = elInfo->getElement(); + PartitionElementData *partitionData = + dynamic_cast<PartitionElementData*> + (element->getElementData(PARTITION_ED)); + if(partitionData->getPartitionStatus() == OUT) { + int mark = min(0, -partitionData->getLevel() + globalCoarseGridLevel_); + //int mark = -partitionData->getLevel(); + element->setMark(mark); + } + elInfo = stack.traverseNext(elInfo); + } + meshCoarsened = coarseningManager_->coarsenMesh(mesh_); + } + MPI::COMM_WORLD.Barrier(); + } + + void ParallelProblem::exchangeMeshStructureCodes(MeshStructure *structures) + { + structures[mpiRank_].init(mesh_); + const std::vector<unsigned long int>& myCode = structures[mpiRank_].getCode(); + int rank; + + + // broadcast code sizes + int *codeSize = GET_MEMORY(int, mpiSize_); + int tmp = static_cast<int>(myCode.size()); + + MPI::COMM_WORLD.Allgather(&tmp, 1, MPI_INT, + codeSize, 1, MPI_INT); + + // broadcast number of elements + int *elements = GET_MEMORY(int, mpiSize_); + tmp = structures[mpiRank_].getNumElements(); + MPI::COMM_WORLD.Allgather(&tmp, 1, MPI_INT, + elements, 1, MPI_INT); + + // broadcast codes + int *codeOffset = GET_MEMORY(int, mpiSize_); + int codeSizeSum = 0; + for(rank = 0; rank < mpiSize_; rank++) { + codeOffset[rank] = codeSizeSum; + codeSizeSum += codeSize[rank]; + } + + unsigned long int *code = GET_MEMORY(unsigned long int, codeSizeSum); + unsigned long int *localCode = GET_MEMORY(unsigned long int, codeSize[mpiRank_]); + + unsigned long int *ptr; + std::vector<unsigned long int>::const_iterator it, end = myCode.end(); + + for(ptr = localCode, it = myCode.begin(); + it != end; + ++it, ++ptr) + { + *ptr = *it; + } + + MPI::COMM_WORLD.Allgatherv(localCode, codeSize[mpiRank_], + MPI_UNSIGNED_LONG, + code, codeSize, codeOffset, + MPI_UNSIGNED_LONG); + + for(rank = 0; rank < mpiSize_; rank++) { + if(rank != mpiRank_) { + std::vector<unsigned long int> remoteCode; + unsigned long int *ptr; + unsigned long int *begin = code + codeOffset[rank]; + unsigned long int *end = begin + codeSize[rank]; + for(ptr = begin; ptr != end; ++ptr) { + remoteCode.push_back(*ptr); + } + structures[rank].init(remoteCode, elements[rank]); + } + } + + // free memory + FREE_MEMORY(elements, int, mpiSize_); + FREE_MEMORY(code, unsigned long int, codeSizeSum); + FREE_MEMORY(localCode, unsigned long int, codeSize[mpiRank_]); + FREE_MEMORY(codeOffset, int, mpiSize_); + FREE_MEMORY(codeSize, int, mpiSize_); + + } + + void ParallelProblem::synchronizeMeshes(AdaptInfo *adaptInfo) + { + FUNCNAME("ParallelProblem::synchronizeMeshes()"); + + MeshStructure *structures = NEW MeshStructure[mpiSize_]; + + // === build composite mesh structure === + exchangeMeshStructureCodes(structures); + + // merge codes + int rank; + for(rank = 0; rank < mpiSize_; rank++) { + if(rank != mpiRank_) { + structures[mpiRank_].merge(&structures[rank]); + } + } + + // === build finest mesh === + structures[mpiRank_].fitMeshToStructure(mesh_, + refinementManager_, + true); + + DELETE [] structures; + +#if 0 + // === count partition elements (only for debug) === + int partitionElements = 0; + TraverseStack stack; + ElInfo *elInfo = stack.traverseFirst(mesh_, -1, Mesh::CALL_LEAF_EL); + while(elInfo) { + Element *element = elInfo->getElement(); + PartitionElementData *partitionData = dynamic_cast<PartitionElementData*> + (element->getElementData(PARTITION_ED)); + if(partitionData && partitionData->getPartitionStatus() == IN) { + partitionElements++; + } + elInfo = stack.traverseNext(elInfo); + } + MSG("rank %d partition elements: %d\n", mpiRank_, partitionElements); +#endif + } + + + bool ParallelProblem::writeElement(ElInfo *elInfo) + { + Element *element = elInfo->getElement(); + PartitionElementData *partitionData = dynamic_cast<PartitionElementData*> + (element->getElementData(PARTITION_ED)); + TEST_EXIT(partitionData)("no partition data\n"); + PartitionStatus status = partitionData->getPartitionStatus(); + if(status == IN) + return true; + else + return false; + } + + void ParallelProblem::exchangeRankSolutions(AdaptInfo *adaptInfo, + std::vector<DOFVector<double>*> rankSolutions) + { + FUNCNAME("ParallelProblem::exchangeRankSolutions()"); + + int level = localCoarseGridLevel_, overlap = 1; + bool openOverlap = true; + ParallelProblem::fillVertexPartitions(level, overlap, openOverlap, + overlapDistance_); + overlapDistance_.clear(); + + + const FiniteElemSpace *feSpace = rankSolutions[0]->getFESpace(); + TEST_EXIT(feSpace->getMesh() == mesh_)("invalid mesh\n"); + int i, dim = mesh_->getDim(); + const BasisFunction *basFcts = feSpace->getBasisFcts(); + int numFcts = basFcts->getNumber(); + DegreeOfFreedom *coarseDOFs = GET_MEMORY(DegreeOfFreedom, numFcts); + DegreeOfFreedom *fineDOFs = GET_MEMORY(DegreeOfFreedom, numFcts); + DOFAdmin *admin = feSpace->getAdmin(); + int partition; + +// std::vector<std::map<WorldVector<double>, DegreeOfFreedom> > sortedSendDOFs; +// std::vector<std::map<WorldVector<double>, DegreeOfFreedom> > sortedRecvDOFs; +// sortedSendDOFs.resize(mpiSize_); +// sortedRecvDOFs.resize(mpiSize_); + + std::vector<std::vector<DegreeOfFreedom> > sendOrder; + std::vector<std::vector<DegreeOfFreedom> > recvOrder; + sendOrder.resize(mpiSize_); + recvOrder.resize(mpiSize_); + + std::set<int>::iterator setIt, setBegin, setEnd; + + //std::map<Element*, std::set<int> > elementPartitions; + elementPartitions_.clear(); + + +// if(mpiRank_ == 0) { +// bool wait = true; +// while(wait) {} +// } + + int elementPartition = -1; + Element *coarseElement = NULL; + TraverseStack stack; + ElInfo *elInfo = stack.traverseFirst(mesh_, -1, Mesh::CALL_EVERY_EL_PREORDER); + while(elInfo) { + Element *element = elInfo->getElement(); + + PartitionElementData *partitionData = dynamic_cast<PartitionElementData*> + (element->getElementData(PARTITION_ED)); + + if(partitionData) { + if(partitionData->getLevel() == 0) { + elementPartition = partitionVec_[element->getIndex()]; + } + + PartitionStatus status = partitionData->getPartitionStatus(); + + if(status != OUT) { + if(partitionData->getLevel() == localCoarseGridLevel_) { + basFcts->getLocalIndices(element, + admin, + coarseDOFs); + + // collect other partitions element belongs to + for(i = 0; i < dim + 1; i++) { + setBegin = vertexPartitions_[coarseDOFs[i]].begin(); + setEnd = vertexPartitions_[coarseDOFs[i]].end(); +// setBegin = vertexPartitions_[element->getDOF(i, 0)].begin(); +// setEnd = vertexPartitions_[element->getDOF(i, 0)].end(); + for(setIt = setBegin; setIt != setEnd; ++setIt) { + elementPartitions_[element].insert(*setIt/* - 1*/); + } + } + + coarseElement = element; + } + + + if(element->isLeaf()) { + basFcts->getLocalIndices(element, + admin, + fineDOFs); + + for(i = 0; i < numFcts; i++) { + if(status == OVERLAP) { + // send dofs + sendOrder[elementPartition].push_back(fineDOFs[i]); + } + if(status == IN) { + // recv dofs + TEST_EXIT(elementPartition == mpiRank_)("???\n"); + setBegin = elementPartitions_[coarseElement].begin(); + setEnd = elementPartitions_[coarseElement].end(); + for(setIt = setBegin; setIt != setEnd; ++setIt) { + if(*setIt != mpiRank_) { + recvOrder[*setIt].push_back(fineDOFs[i]); + //recvOrder[*setIt].push_back(element->getDOF(i, 0)); + } + } + } + } + } + } + } + + elInfo = stack.traverseNext(elInfo); + } + + +#if 0 + MyDualTraverse dualTraverse(localCoarseGridLevel_);//localCoarseGridLevel_); + + ElInfo *elInfo1, *elInfo2; + ElInfo *large, *small; + + bool cont = dualTraverse.traverseFirst(mesh_, mesh_, + -1, -1, + Mesh::CALL_EVERY_EL_PREORDER | + Mesh::FILL_COORDS | + Mesh::FILL_DET, + Mesh::CALL_LEAF_EL | + Mesh::FILL_COORDS, + &elInfo1, &elInfo2, + &small, &large); + + while (cont) { + TEST_EXIT(elInfo1 == large && elInfo2 == small) + ("error in dual traverse\n"); + + Element *element1 = elInfo1->getElement(); + Element *element2 = elInfo2->getElement(); + + // get partition status of element2 + PartitionElementData *partitionData = dynamic_cast<PartitionElementData*> + (element2->getElementData(PARTITION_ED)); + TEST_EXIT(partitionData)("no partition data\n"); + PartitionStatus status = partitionData->getPartitionStatus(); + + if(status != OUT) { + basFcts->getLocalIndices(element1, + admin, + coarseDOFs); + basFcts->getLocalIndices(element2, + admin, + fineDOFs); + + // collect other partitions element2 belongs to + for(i = 0; i < dim + 1; i++) { + setBegin = vertexPartitions_[coarseDOFs[i]].begin(); + setEnd = vertexPartitions_[coarseDOFs[i]].end(); + for(setIt = setBegin; setIt != setEnd; ++setIt) { + elementPartitions_[element1].insert(*setIt/* - 1*/); + } + } + + int elementPartition = partitionVec_[element1->getIndex()]; + + // collect send- and recv-dofs for every rank + WorldVector<double> worldCoords; + for(i = 0; i < numFcts; i++) { + elInfo2->coordToWorld(*(basFcts->getCoords(i)), &worldCoords); + if(status == OVERLAP) { + // send dofs + //sortedSendDOFs[elementPartition][worldCoords] = fineDOFs[i]; + sendOrder[elementPartition].push_back(fineDOFs[i]); + } + if(status == IN) { + // recv dofs + TEST_EXIT(elementPartition == mpiRank_)("???\n"); + setBegin = elementPartitions_[element1].begin(); + setEnd = elementPartitions_[element1].end(); + for(setIt = setBegin; setIt != setEnd; ++setIt) { + //sortedRecvDOFs[*setIt][worldCoords] = fineDOFs[i]; + if(*setIt != mpiRank_) { + recvOrder[*setIt].push_back(fineDOFs[i]); + } + } + } + } + } + + cont = dualTraverse.traverseNext(&elInfo1, &elInfo2, + &small, &large); + } +#endif + + // create send and recv buffers and fill send buffers + DOFVector<double> *solution = rankSolutions[mpiRank_]; + + std::map<int, double*> sendBuffer; + std::map<int, double*> recvBuffer; + std::map<int, int> sendBufferSize; + std::map<int, int> recvBufferSize; + + for(partition = 0; partition < mpiSize_; partition++) { + if(partition != mpiRank_) { + //int sendSize = static_cast<int>(sortedSendDOFs[partition].size()); + //int recvSize = static_cast<int>(sortedRecvDOFs[partition].size()); + int sendSize = static_cast<int>(sendOrder[partition].size()); + int recvSize = static_cast<int>(recvOrder[partition].size()); + + sendBufferSize[partition] = sendSize; + recvBufferSize[partition] = recvSize; + if(sendSize > 0) { + sendBuffer[partition] = GET_MEMORY(double, sendSize); + //std::map<WorldVector<double>, DegreeOfFreedom>::iterator dofIt; + std::vector<DegreeOfFreedom>::iterator dofIt; + //dofIt = sortedSendDOFs[partition].begin(); + dofIt = sendOrder[partition].begin(); + double *bufferIt, *bufferBegin, *bufferEnd; + bufferBegin = sendBuffer[partition]; + bufferEnd = bufferBegin + sendSize; + for(bufferIt = bufferBegin; + bufferIt < bufferEnd; + ++bufferIt, ++dofIt) + { + //*bufferIt = (*solution)[dofIt->second]; + *bufferIt = (*solution)[*dofIt]; + } + } + if(recvSize > 0) + recvBuffer[partition] = GET_MEMORY(double, recvSize); + } + } + +// for(partition = 0; partition < mpiSize_; partition++) { +// MSG("rank %d -> rank %d: %d", +// mpiRank_, partition, sendBufferSize[partition]); +// MSG("rank %d <- rank %d: %d", +// mpiRank_, partition, recvBufferSize[partition]); +// } + + // non-blocking sends + for(partition = 0; partition < mpiSize_; partition++) { + if(partition != mpiRank_) { + if(sendBufferSize[partition] > 0) { + MPI::COMM_WORLD.Isend(sendBuffer[partition], + sendBufferSize[partition], + MPI_DOUBLE, + partition, + 0); + } + } + } + + //MPI::COMM_WORLD.Barrier(); + + // blocking recieves + for(partition = 0; partition < mpiSize_; partition++) { + if(partition != mpiRank_) { + if(recvBufferSize[partition] > 0) { + MPI::COMM_WORLD.Recv(recvBuffer[partition], + recvBufferSize[partition], + MPI_DOUBLE, + partition, + 0); + } + } + } + +// if(mpiRank_ == 1) { +// for(i = 0; i < recvBufferSize[0]; i++) { +// MSG("recv: %f", recvBuffer[0][i]); +// } +// } + +// if(mpiRank_ == 0) { +// for(i = 0; i < sendBufferSize[1]; i++) { +// MSG("send: %f", sendBuffer[1][i]); +// } +// } + + // wait for end of communication + MPI::COMM_WORLD.Barrier(); + + // copy values into rank solutions + for(partition = 0; partition < mpiSize_; partition++) { + if(partition != mpiRank_) { + //std::map<WorldVector<double>, DegreeOfFreedom>::iterator dofIt; + //dofIt = sortedRecvDOFs[partition].begin(); + std::vector<DegreeOfFreedom>::iterator dofIt = recvOrder[partition].begin(); + for(i = 0; i < recvBufferSize[partition]; i++) { + //(*(rankSolutions[partition]))[dofIt->second] = + (*(rankSolutions[partition]))[*dofIt] = + recvBuffer[partition][i]; + ++dofIt; + } + } + } + + // free send and recv buffers + for(partition = 0; partition < mpiSize_; partition++) { + if(partition != mpiRank_) { + if(sendBufferSize[partition] > 0) + FREE_MEMORY(sendBuffer[partition], + double, + sendBufferSize[partition]); + if(recvBufferSize[partition] > 0) + FREE_MEMORY(recvBuffer[partition], + double, + recvBufferSize[partition]); + } + } + FREE_MEMORY(coarseDOFs, DegreeOfFreedom, numFcts); + FREE_MEMORY(fineDOFs, DegreeOfFreedom, numFcts); + } + +#if 0 + void ParallelProblem::exchangeElementMarkings(AdaptInfo *adaptInfo) + { + FUNCNAME("ParallelProblem::exchangeElementMarkings()"); + int i; + + partitioner_->fillLeafPartitionVec(&oldPartitionVec_, &oldPartitionVec_); + partitioner_->fillLeafPartitionVec(&partitionVec_, &partitionVec_); + + //std::map<int, Element*> elementWithIndex; + + // === get send and recieve orders === + std::vector<std::vector<Element*> > recvOrder; + std::vector<std::vector<int> > markings; + + markings.resize(mpiSize_); + recvOrder.resize(mpiSize_); + + TraverseStack stack; + ElInfo *elInfo; + + elInfo = stack.traverseFirst(mesh_, -1, Mesh::CALL_LEAF_EL); + while(elInfo) { + Element *element = elInfo->getElement(); + int index = element->getIndex(); + int oldPartition = oldPartitionVec_[index]; + int newPartition = partitionVec_[index]; + int mark = element->getMark(); + +// if(mark!=0) +// MSG("rank %d: index %d mark %d\n", +// mpiRank_, index, mark); + + if(oldPartition != newPartition) { + if(oldPartition == mpiRank_) { + markings[newPartition].push_back(mark); +// MSG("rank %d: index %d %d -> %d mark %d\n", +// mpiRank_, index, oldPartition, newPartition, mark); + } + if(newPartition == mpiRank_) { + recvOrder[oldPartition].push_back(element); +// MSG("rank %d: index %d %d <- %d mark %d\n", +// mpiRank_, index, oldPartition, newPartition, mark); + //elementWithIndex[index] = element; + } + } + elInfo = stack.traverseNext(elInfo); + } + + // === create send and recv buffers and fill send buffers === + std::map<int, int*> sendBuffer; + std::map<int, int*> recvBuffer; + std::map<int, int> sendBufferSize; + std::map<int, int> recvBufferSize; + + int partition; + for(partition = 0; partition < mpiSize_; partition++) { + if(partition != mpiRank_) { + int sendSize = static_cast<int>(markings[partition].size()); + int recvSize = static_cast<int>(recvOrder[partition].size()); + + sendBufferSize[partition] = sendSize; + recvBufferSize[partition] = recvSize; + if(sendSize > 0) { + sendBuffer[partition] = GET_MEMORY(int, sendSize); + std::vector<int>::iterator it; + it = markings[partition].begin(); + int *bufferIt, *bufferBegin, *bufferEnd; + bufferBegin = sendBuffer[partition]; + bufferEnd = bufferBegin + sendSize; + for(bufferIt = bufferBegin; + bufferIt < bufferEnd; + ++bufferIt, ++it) + { + *bufferIt = *it; + } + } + if(recvSize > 0) + recvBuffer[partition] = GET_MEMORY(int, recvSize); + } + } + + // === non-blocking sends === + for(partition = 0; partition < mpiSize_; partition++) { + if(partition != mpiRank_) { + if(sendBufferSize[partition] > 0) { + MPI::COMM_WORLD.Isend(sendBuffer[partition], + sendBufferSize[partition], + MPI_INT, + partition, + 0); + } + } + } + + // === blocking receives === + for(partition = 0; partition < mpiSize_; partition++) { + if(partition != mpiRank_) { + if(recvBufferSize[partition] > 0) { + MPI::COMM_WORLD.Recv(recvBuffer[partition], + recvBufferSize[partition], + MPI_INT, + partition, + 0); + } + } + } + + // === wait for end of MPI communication === + MPI::COMM_WORLD.Barrier(); + + // === copy received values into elements === + for(partition = 0; partition < mpiSize_; partition++) { + if(partition != mpiRank_) { + std::vector<Element*>::iterator it = recvOrder[partition].begin(); + for(i = 0; i < recvBufferSize[partition]; i++) { + (*it)->setMark(recvBuffer[partition][i]); +// MSG(" *** rank %d, index %d from %d mark %d\n", +// mpiRank_, (*it)->getIndex(), i, recvBuffer[partition][i]); + ++it; + } + } + } + + // === free send and receive buffers === + for(partition = 0; partition < mpiSize_; partition++) { + if(partition != mpiRank_) { + if(sendBufferSize[partition] > 0) + FREE_MEMORY(sendBuffer[partition], + int, + sendBufferSize[partition]); + if(recvBufferSize[partition] > 0) + FREE_MEMORY(recvBuffer[partition], + int, + recvBufferSize[partition]); + } + } + } +#endif + + void ParallelProblem::exchangeDOFVector(AdaptInfo *adaptInfo, + DOFVector<double> *values) + { + partitioner_->fillLeafPartitionVec(&oldPartitionVec_, &oldPartitionVec_); + partitioner_->fillLeafPartitionVec(&partitionVec_, &partitionVec_); + + // === get send and recieve orders === + std::vector<std::vector<DegreeOfFreedom> > sendOrder; + std::vector<std::vector<DegreeOfFreedom> > recvOrder; + sendOrder.resize(mpiSize_); + recvOrder.resize(mpiSize_); + + int i; + const FiniteElemSpace *feSpace = values->getFESpace(); + const BasisFunction *basFcts = feSpace->getBasisFcts(); + int numFcts = basFcts->getNumber(); + DegreeOfFreedom *dofs = GET_MEMORY(DegreeOfFreedom, numFcts); + DOFAdmin *admin = feSpace->getAdmin(); + + Mesh *mesh = feSpace->getMesh(); + TraverseStack stack; + ElInfo *elInfo; + + elInfo = stack.traverseFirst(mesh, -1, Mesh::CALL_LEAF_EL); + while(elInfo) { + Element *element = elInfo->getElement(); + int index = element->getIndex(); + int oldPartition = oldPartitionVec_[index]; + int newPartition = partitionVec_[index]; + + if(oldPartition != newPartition) { + // get dof indices + basFcts->getLocalIndices(element, admin, dofs); + + if(oldPartition == mpiRank_) { + for(i = 0; i < numFcts; i++) { + // send element values to new partition + sendOrder[newPartition].push_back(dofs[i]); + } + } + if(newPartition == mpiRank_) { + for(i = 0; i < numFcts; i++) { + // recv element values from old partition + recvOrder[oldPartition].push_back(dofs[i]); + } + } + } + + elInfo = stack.traverseNext(elInfo); + } + + FREE_MEMORY(dofs, DegreeOfFreedom, numFcts); + + // === create send and recv buffers and fill send buffers === + std::map<int, double*> sendBuffer; + std::map<int, double*> recvBuffer; + std::map<int, int> sendBufferSize; + std::map<int, int> recvBufferSize; + + int partition; + for(partition = 0; partition < mpiSize_; partition++) { + if(partition != mpiRank_) { + int sendSize = static_cast<int>(sendOrder[partition].size()); + int recvSize = static_cast<int>(recvOrder[partition].size()); + + sendBufferSize[partition] = sendSize; + recvBufferSize[partition] = recvSize; + if(sendSize > 0) { + sendBuffer[partition] = GET_MEMORY(double, sendSize); + std::vector<DegreeOfFreedom>::iterator dofIt; + dofIt = sendOrder[partition].begin(); + double *bufferIt, *bufferBegin, *bufferEnd; + bufferBegin = sendBuffer[partition]; + bufferEnd = bufferBegin + sendSize; + for(bufferIt = bufferBegin; + bufferIt < bufferEnd; + ++bufferIt, ++dofIt) + { + *bufferIt = (*values)[*dofIt]; + } + } + if(recvSize > 0) + recvBuffer[partition] = GET_MEMORY(double, recvSize); + } + } + +// MSG("rank %d: send %d %d %d %d recv %d %d %d %d\n", +// mpiRank_, +// sendBufferSize[0], +// sendBufferSize[1], +// sendBufferSize[2], +// sendBufferSize[3], +// recvBufferSize[0], +// recvBufferSize[1], +// recvBufferSize[2], +// recvBufferSize[3]); + + // === non-blocking sends === + for(partition = 0; partition < mpiSize_; partition++) { + if(partition != mpiRank_) { + if(sendBufferSize[partition] > 0) { + MPI::COMM_WORLD.Isend(sendBuffer[partition], + sendBufferSize[partition], + MPI_DOUBLE, + partition, + 0); + } + } + } + + // === blocking receives === + for(partition = 0; partition < mpiSize_; partition++) { + if(partition != mpiRank_) { + if(recvBufferSize[partition] > 0) { + MPI::COMM_WORLD.Recv(recvBuffer[partition], + recvBufferSize[partition], + MPI_DOUBLE, + partition, + 0); + } + } + } + + // === wait for end of MPI communication === + MPI::COMM_WORLD.Barrier(); + + // === copy received values into DOFVector === + for(partition = 0; partition < mpiSize_; partition++) { + if(partition != mpiRank_) { + std::vector<DegreeOfFreedom>::iterator dofIt = recvOrder[partition].begin(); + for(i = 0; i < recvBufferSize[partition]; i++) { + (*values)[*dofIt] = recvBuffer[partition][i]; + ++dofIt; + } + } + } + + // === free send and receive buffers === + for(partition = 0; partition < mpiSize_; partition++) { + if(partition != mpiRank_) { + if(sendBufferSize[partition] > 0) + FREE_MEMORY(sendBuffer[partition], + double, + sendBufferSize[partition]); + if(recvBufferSize[partition] > 0) + FREE_MEMORY(recvBuffer[partition], + double, + recvBufferSize[partition]); + } + } + } + + void ParallelProblem::buildGlobalSolution(AdaptInfo *adaptInfo, + std::vector<DOFVector<double>*> rankSolutions, + DOFVector<double> *globalSolution) + { + FUNCNAME("ParallelProblem::buildGlobalSolution()"); + + const FiniteElemSpace *feSpace = globalSolution->getFESpace(); + int i, dim = mesh_->getDim(); + const BasisFunction *basFcts = feSpace->getBasisFcts(); + int numFcts = basFcts->getNumber(); + DegreeOfFreedom *coarseDOFs = GET_MEMORY(DegreeOfFreedom, numFcts); + DegreeOfFreedom *fineDOFs = GET_MEMORY(DegreeOfFreedom, numFcts); + DOFAdmin *admin = feSpace->getAdmin(); + + Lagrange *linearFunctions = Lagrange::getLagrange(dim, 1); + + MSG("Building global solution\n"); + + int j; + +// DOFVector<double> wtest0(feSpace, "wtest0"); +// wtest0.set(0.0); +// DOFVector<double> wtest1(feSpace, "wtest1"); +// wtest1.set(0.0); +// DOFVector<double> wtest2(feSpace, "wtest2"); +// wtest2.set(0.0); +// DOFVector<double> wtest3(feSpace, "wtest3"); +// wtest3.set(0.0); + + // compute w[DOF][partition]->value + std::map<DegreeOfFreedom, std::map<int, double> > w; + std::map<DegreeOfFreedom, std::map<int, double> >::iterator wIt, wBegin, wEnd; + + std::map<DegreeOfFreedom, double> sumW; + + Element *lastCoarseElement = NULL; + + WorldVector<double> worldCoord; + DimVec<double> baryCoord(dim, NO_INIT); + + std::set<int>::iterator partIt, partBegin, partEnd; + + std::map<DegreeOfFreedom, bool> visited; + + +#if 0 + TraverseStack stack; + ElInfo *elInfo = stack.traverseFirst(mesh_, -1, + Mesh::CALL_EVERY_EL_PREORDER | + Mesh::FILL_COORDS); + while(elInfo) { + Element *element = elInfo->getElement(); + + PartitionElementData *partitionData = dynamic_cast<PartitionElementData*> + (element->getElementData(PARTITION_ED)); + + if(partitionData) { + PartitionStatus status = partitionData->getPartitionStatus(); + + if(status == IN) { + if(partitionData->getLevel() == localCoarseGridLevel_) { + basFcts->getLocalIndices(element, admin, coarseDOFs); + } + + if(element->isLeaf()) { + if(elementPartitions_[element].size() > 1) { + // get fine dofs + basFcts->getLocalIndices(element, admin, fineDOFs); + + // for all fine DOFs + for(i = 0; i < numFcts; i++) { + if(!visited[fineDOFs[i]]) { + visited[fineDOFs[i]] = true; + + elInfo2->coordToWorld(*(basFcts->getCoords(i)), &worldCoord); + elInfo1->worldToCoord(worldCoord, &baryCoord); + + // for all coarse vertex DOFs + for(j = 0; j < dim + 1; j++) { + partBegin = (*vertexPartitions)[coarseDOFs[j]].begin(); + partEnd = (*vertexPartitions)[coarseDOFs[j]].end(); + for(partIt = partBegin; partIt != partEnd; ++partIt) { + int partition = *partIt/* - 1*/; + double val = (*(linearFunctions->getPhi(j)))(baryCoord); + w[fineDOFs[i]][partition] += val; + sumW[fineDOFs[i]] += val; + } + } + } + } + } + } + } + } + + elInfo = stack.traverseNext(elInfo); + } +#endif + + MyDualTraverse dualTraverse(localCoarseGridLevel_);//localCoarseGridLevel_); + ElInfo *elInfo1, *elInfo2; + ElInfo *large, *small; + + bool cont; + + cont = dualTraverse.traverseFirst(mesh_, mesh_, + -1, -1, + Mesh::CALL_EVERY_EL_PREORDER | + Mesh::FILL_COORDS | + Mesh::FILL_DET, + Mesh::CALL_LEAF_EL | + Mesh::FILL_COORDS, + &elInfo1, &elInfo2, + &small, &large); + + while (cont) { + Element *element1 = elInfo1->getElement(); + Element *element2 = elInfo2->getElement(); + PartitionElementData *partitionData = + dynamic_cast<PartitionElementData*> + (element1->getElementData(PARTITION_ED)); + if(partitionData->getPartitionStatus() == IN) { + + // get coarse dofs + if(element1 != lastCoarseElement) { + basFcts->getLocalIndices(element1, admin, coarseDOFs); + lastCoarseElement = element1; + } + + if(elementPartitions_[element1].size() > 1) { + // get fine dofs + basFcts->getLocalIndices(element2, admin, fineDOFs); + + // for all fine DOFs + for(i = 0; i < numFcts; i++) { + if(!visited[fineDOFs[i]]) { + visited[fineDOFs[i]] = true; + + elInfo2->coordToWorld(*(basFcts->getCoords(i)), &worldCoord); + elInfo1->worldToCoord(worldCoord, &baryCoord); + + // for all coarse vertex DOFs + for(j = 0; j < dim + 1; j++) { + partBegin = vertexPartitions_[coarseDOFs[j]].begin(); + partEnd = vertexPartitions_[coarseDOFs[j]].end(); + for(partIt = partBegin; partIt != partEnd; ++partIt) { + int partition = *partIt/* - 1*/; + double val = (*(linearFunctions->getPhi(j)))(baryCoord); + w[fineDOFs[i]][partition] += val; + +// if(partition == 0) { +// wtest0[fineDOFs[i]] += val; +// } +// if(partition == 1) { +// wtest1[fineDOFs[i]] += val; +// } +// if(partition == 2) { +// wtest2[fineDOFs[i]] += val; +// } +// if(partition == 3) { +// wtest3[fineDOFs[i]] += val; +// } + + sumW[fineDOFs[i]] += val; + } + } + } + } + } + } + cont = dualTraverse.traverseNext(&elInfo1, &elInfo2, + &small, &large); + } + + +// if(mpiRank_ == 0) { +// MacroWriter::writeMacro(feSpace, "output/wtest0.mesh"); +// ValueWriter::writeValues(&wtest0, "output/wtest0.dat"); +// MacroWriter::writeMacro(feSpace, "output/wtest1.mesh"); +// ValueWriter::writeValues(&wtest1, "output/wtest1.dat"); +// MacroWriter::writeMacro(feSpace, "output/wtest2.mesh"); +// ValueWriter::writeValues(&wtest2, "output/wtest2.dat"); +// MacroWriter::writeMacro(feSpace, "output/wtest3.mesh"); +// ValueWriter::writeValues(&wtest3, "output/wtest3.dat"); +// } + + FREE_MEMORY(coarseDOFs, DegreeOfFreedom, numFcts); + FREE_MEMORY(fineDOFs, DegreeOfFreedom, numFcts); + + MSG("PU ...\n"); + + wBegin = w.begin(); + wEnd = w.end(); + + for(wIt = wBegin; wIt != wEnd; ++wIt) { + DegreeOfFreedom dof = wIt->first; + (*globalSolution)[dof] = 0.0; + } + + for(wIt = wBegin; wIt != wEnd; ++wIt) { + DegreeOfFreedom dof = wIt->first; + std::map<int, double>::iterator partIt, partBegin, partEnd; + partBegin = wIt->second.begin(); + partEnd = wIt->second.end(); + + for(partIt = partBegin; partIt != partEnd; ++partIt) { + int partition = partIt->first; + double wDOF = partIt->second; + (*globalSolution)[dof] += wDOF / sumW[dof] * (*(rankSolutions[partition]))[dof]; + } + } + } + + double ParallelProblem::errors2map(std::map<int, double> &errVec, + int comp, + bool add) + { + int elNum = -1; + double totalErr, error; + + if(!add) errVec.clear(); + + TraverseStack stack; + ElInfo *elInfo = stack.traverseFirst(mesh_, + -1, + Mesh::CALL_EVERY_EL_PREORDER); + totalErr = 0.0; + while(elInfo) { + Element *element = elInfo->getElement(); + + // get partition data + PartitionElementData *partitionData = dynamic_cast<PartitionElementData*> + (element->getElementData(PARTITION_ED)); + + if(partitionData && partitionData->getPartitionStatus() == IN) { + if(partitionData->getLevel() == 0) { + elNum = element->getIndex(); + } + TEST_EXIT(elNum != -1)("invalid element number\n"); + if(element->isLeaf()) { + error = element->getEstimation(comp); + errVec[elNum] += error; + totalErr += error; + } + } + elInfo = stack.traverseNext(elInfo); + } + +// double total_sum = 0.0; +// MPI::COMM_WORLD.Allreduce(&totalErr, +// &total_sum, +// 1, +// MPI_DOUBLE, +// MPI_SUM); +// total_sum = sqrt(total_sum); + +// MSG("error rank %d = %e (total %e)\n", mpiRank_, totalErr, total_sum); + + return totalErr; + } + +// void ParallelProblem::writeRankMacroAndValues(DOFVector<double> *vec, +// const char *name, +// double time) +// { +// char number[3]; +// sprintf(number, "%d", MPI::COMM_WORLD.Get_rank()); + +// std::string macroFile(name); +// macroFile += number; +// macroFile += ".mesh"; + +// ConditionalMacroWriter::writeMacro(vec->getFESpace(), +// const_cast<char*>(macroFile.c_str()), +// time, +// -1, +// Mesh::CALL_LEAF_EL, +// &writeElement); + +// std::string valueFile(name); +// valueFile += number; +// valueFile += ".dat"; + +// ConditionalValueWriter::writeValues(vec, +// const_cast<char*>(valueFile.c_str()), +// time, +// -1, +// Mesh::CALL_LEAF_EL, +// &writeElement); +// } + + + double ParallelProblem::setElemWeights(AdaptInfo *adaptInfo) + { + double localWeightSum = 0.0; + int elNum = -1; + + elemWeights_.clear(); + + TraverseStack stack; + ElInfo *elInfo = stack.traverseFirst(mesh_, + -1, + Mesh::CALL_EVERY_EL_PREORDER); + while(elInfo) { + Element *element = elInfo->getElement(); + + // get partition data + PartitionElementData *partitionData = dynamic_cast<PartitionElementData*> + (element->getElementData(PARTITION_ED)); + + if(partitionData && partitionData->getPartitionStatus() == IN) { + if(partitionData->getLevel() == 0) { + elNum = element->getIndex(); + } + TEST_EXIT(elNum != -1)("invalid element number\n"); + if(element->isLeaf()) { + elemWeights_[elNum] += 1.0; + localWeightSum += 1.0; + } + } + + elInfo = stack.traverseNext(elInfo); + } + + return localWeightSum; + } + + + void ParallelProblem::globalRefinements() + { + if (globalRefinements_ <= 0) + return; + + TraverseStack stack; + ElInfo *elInfo = stack.traverseFirst(mesh_, -1, Mesh::CALL_LEAF_EL); + while (elInfo) { + Element *element = elInfo->getElement(); + PartitionElementData *partitionData = dynamic_cast<PartitionElementData*> + (element->getElementData(PARTITION_ED)); + + if (partitionData && partitionData->getPartitionStatus() == IN) { + element->setMark(globalRefinements_); + } + + elInfo = stack.traverseNext(elInfo); + } + + refinementManager_->refineMesh(mesh_); + } + + + void ParallelProblem::createOverlap(int level, int overlap, bool openOverlap, + std::map<Element*, int> &overlapDistance) + { + int i, dim = mesh_->getDim(); + + // === create dual graph (one common node) and prepare breadth-first search === + std::map<DegreeOfFreedom, std::vector<Element*> > vertexElements; + std::queue<Element*> overlapQueue; + + TraverseStack stack; + ElInfo *elInfo = stack.traverseFirst(mesh_, -1, Mesh::CALL_EVERY_EL_PREORDER); + while(elInfo) { + Element *element = elInfo->getElement(); + PartitionElementData *partitionData = + dynamic_cast<PartitionElementData*>(element->getElementData(PARTITION_ED)); + + if(partitionData) { + if(partitionData->getLevel() == level) { + for(i = 0; i < dim + 1; i++) { + vertexElements[element->getDOF(i, 0)].push_back(element); + } + + if(partitionData->getPartitionStatus() == IN) { + overlapDistance[element] = 0; + overlapQueue.push(element); + } else { + overlapDistance[element] = -1; // still unknown + } + } + } + elInfo = stack.traverseNext(elInfo); + } + + // === breadth-first search on dual graph === + std::vector<Element*>::iterator it, itBegin, itEnd; + + while(!overlapQueue.empty()) { + // get first element in queue + Element *element = overlapQueue.front(); + overlapQueue.pop(); + + // get distance + int distance = overlapDistance[element]; + TEST_EXIT(distance >= 0)("invalid distance\n"); + + if(distance >= overlap) continue; + + // get all adjacent elements + for(i = 0; i < dim + 1; i++) { + itBegin = vertexElements[element->getDOF(i, 0)].begin(); + itEnd = vertexElements[element->getDOF(i, 0)].end(); + for(it = itBegin; it != itEnd; ++it) { + if(overlapDistance[*it] == -1) { + // set distance for new member + overlapDistance[*it] = distance + 1; + // push neighbour to queue + overlapQueue.push(*it); + // mark as overlap on AMDiS mesh + PartitionElementData *partitionData = + dynamic_cast<PartitionElementData*>((*it)->getElementData(PARTITION_ED)); + TEST_EXIT(partitionData)("no partition data\n"); + partitionData->setPartitionStatus(OVERLAP); + partitionData->descend(*it); + } + } + } + } + } + + void ParallelProblem::fillVertexPartitions(int level, int overlap, + bool openOverlap, + std::map<Element*, int> &overlapDistance) + { + int i, dim = mesh_->getDim(); + + TraverseStack stack; + ElInfo *elInfo; + + // clear partition dof vector + vertexPartitions_.clear(); + + // first: partition elements ... + int index, partition; + elInfo = stack.traverseFirst(mesh_, -1, Mesh::CALL_EVERY_EL_PREORDER); + while(elInfo) { + Element *element = elInfo->getElement(); + PartitionElementData *partitionData = + dynamic_cast<PartitionElementData*>(element->getElementData(PARTITION_ED)); + if(partitionData) { + if(partitionData->getLevel() == 0) { + index = element->getIndex(); + partition = partitionVec_[index]; + } + if(partitionData->getLevel() == level) { + for(i = 0; i < dim + 1; i++) { + vertexPartitions_[element->getDOF(i, 0)].insert(partition/* + 1*/); + } + } + } + elInfo = stack.traverseNext(elInfo); + } + + if(overlap > 1 || openOverlap == false) { + // exchange mesh structure codes + MeshStructure *structures = NEW MeshStructure[mpiSize_]; + exchangeMeshStructureCodes(structures); + + // merge codes + int rank; + for(rank = 0; rank < mpiSize_; rank++) { + if(rank != mpiRank_) { + structures[mpiRank_].merge(&structures[rank]); + } + } + + MeshStructure &compositeStructure = structures[mpiRank_]; + compositeStructure.reset(); + + // get composite indices of local overlap elements + std::map<int, Element*> indexElement; + std::vector<int> innerOverlapElements; // not at open overlap boundary + + elInfo = stack.traverseFirst(mesh_, -1, Mesh::CALL_EVERY_EL_PREORDER); + while(elInfo) { + Element *element = elInfo->getElement(); + PartitionElementData *partitionData = + dynamic_cast<PartitionElementData*>(element->getElementData(PARTITION_ED)); + + if(partitionData && partitionData->getLevel() == level) { + int compositeIndex = compositeStructure.getCurrentElement(); + indexElement[compositeIndex] = element; + if(partitionData->getPartitionStatus() == OVERLAP) { + int distance = overlapDistance[element]; + if(distance < overlap || !openOverlap) { + innerOverlapElements.push_back(compositeIndex); + } + } + } + + if(element->isLeaf()) { + compositeStructure.skipBranch(); + } else { + compositeStructure.nextElement(); + } + elInfo = stack.traverseNext(elInfo); + } + + // === exchange 'inner' overlap elements === + + // exchange number of overlap elements + int *numOverlapElements = GET_MEMORY(int, mpiSize_); + int tmp = static_cast<int>(innerOverlapElements.size()); + MPI::COMM_WORLD.Allgather(&tmp, 1, MPI_INT, + numOverlapElements, 1, MPI_INT); + + // exchange overlap elements + int *offset = GET_MEMORY(int, mpiSize_); + int sum = 0; + for(rank = 0; rank < mpiSize_; rank++) { + offset[rank] = sum; + sum += numOverlapElements[rank]; + } + + int *recvBuffer = GET_MEMORY(int, sum); + int *sendBuffer = GET_MEMORY(int, numOverlapElements[mpiRank_]); + + int *ptr; + std::vector<int>::iterator elemIt, elemEnd = innerOverlapElements.end(); + + for(ptr = sendBuffer, elemIt = innerOverlapElements.begin(); + elemIt != elemEnd; + ++elemIt, ++ptr) + { + *ptr = *elemIt; + } + + MPI::COMM_WORLD.Allgatherv(sendBuffer, numOverlapElements[mpiRank_], + MPI_INT, + recvBuffer, numOverlapElements, offset, + MPI_INT); + + + + // fill vertexPartitions for 'inner' overlap elements + int el; + for(rank = 0; rank < mpiSize_; rank++) { + int numElements = numOverlapElements[rank]; + // MSG("rank %d overlap elements with %d: %d\n", + // mpiRank_, rank, numOverlapElements[rank]); + int *elements = recvBuffer + offset[rank]; + for(el = 0; el < numElements; el++) { + Element *element = indexElement[elements[el]]; + for(i = 0; i < dim + 1; i++) { + vertexPartitions_[element->getDOF(i, 0)].insert(rank/* + 1*/); + } + } + } + + // free memory + DELETE [] structures; + FREE_MEMORY(recvBuffer, int, sum); + FREE_MEMORY(sendBuffer, int, numOverlapElements[mpiRank_]); + FREE_MEMORY(numOverlapElements, int, mpiSize_); + } + } + + void ParallelProblem::createOverlap(AdaptInfo *adaptInfo) + { + int level = localCoarseGridLevel_, overlap = 1; + bool openOverlap = true; + + ParallelProblem::createOverlap(level, overlap, openOverlap, overlapDistance_); + +// ParallelProblem::fillVertexPartitions(level, overlap, openOverlap, +// overlapDistance_); + } + + // ========================================================================= + // ===== class ParallelProblemScal ========================================= + // ========================================================================= + + ParallelProblemScal::ParallelProblemScal(const std::string& name, + ProblemScal *problem, + ProblemInstatScal *problemInstat, + std::vector<DOFVector<double>*> vectors) + : ParallelProblem(name, + problem, + problemInstat, + vectors, + problem->getMesh(), + problem->getRefinementManager(), + problem->getCoarseningManager()), + problem_(problem), + problemInstat_(problemInstat), + oldEstimator_(NULL), + oldMarker_(NULL), + rankSolution_(mpiSize_), + usersEstimator_(NULL), + usersMarker_(NULL) + { + int i; + for(i = 0; i < mpiSize_; i++) { + rankSolution_[i] = NEW DOFVector<double>(problem_->getFESpace(), "rank solution"); + } + + //vertexPartitions_ = NEW std::map<DegreeOfFreedom, std::set<int> >(problem_->getFESpace(), + // "partition dof"); + + if(problemInstat_) { + dofVectors_.push_back(problemInstat_->getOldSolution()); + } + } + + ParallelProblemScal::~ParallelProblemScal() + { + int i; + for(i = 0; i < mpiSize_; i++) { + DELETE rankSolution_[i]; + } + //DELETE vertexPartitions_; + } + + + void ParallelProblemScal::initParallelization(AdaptInfo *adaptInfo) + { + if (mpiSize_ > 1) { + clock_t partitioningStart = clock(); + + partitioner_->createPartitionData(); + setElemWeights(adaptInfo); + partitionMesh(adaptInfo); + + globalRefineOutOfPartition(adaptInfo); + + refineOverlap(adaptInfo); + createOverlap(adaptInfo); + + globalRefinements(); + + oldEstimator_ = problem_->getEstimator(); + oldMarker_ = problem_->getMarker(); + + ConditionalEstimator *condEstimator = NULL; + if (usersEstimator_) { + problem_->setEstimator(usersEstimator_); + } else { + condEstimator = NEW ConditionalEstimator(oldEstimator_); + problem_->setEstimator(condEstimator); + } + + if (usersMarker_) { + problem_->setMarker(usersMarker_); + } else { + ConditionalMarker *newMarker = NEW ConditionalMarker("parallel marker", + -1, + oldMarker_, + globalCoarseGridLevel_, + localCoarseGridLevel_); + problem_->setMarker(newMarker); + } + + if (mpiRank_ == 0) { + clock_t partitioningEnd = clock(); + partitioningTime = TIME_USED(partitioningStart, + partitioningEnd); + computationStart = partitioningEnd; + } + + // modify file writers + char number[10]; + sprintf(number, "%d", MPI::COMM_WORLD.Get_rank()); + ::std::list<FileWriterInterface*> fileWriters = problem_->getFileWriterList(); + ::std::list<FileWriterInterface*>::iterator fwIt, fwBegin, fwEnd; + fwBegin = fileWriters.begin(); + fwEnd = fileWriters.end(); + for(fwIt = fwBegin; fwIt != fwEnd; ++fwIt) { + (*fwIt)->setFilename((*fwIt)->getFilename() + "_proc" + + ::std::string(number) + "_"); + (*fwIt)->setTraverseProperties(-1, 0, elementInPartition); + } + } + } + + void ParallelProblemScal::exitParallelization(AdaptInfo *adaptInfo) + { + if (mpiSize_ > 1) { + ParallelProblem::exitParallelization(adaptInfo); + + if (!timeIF_) problem_->writeFiles(adaptInfo, true); + + partitioner_->deletePartitionData(); + + if (!usersEstimator_) DELETE problem_->getEstimator(); + if (!usersMarker_) DELETE problem_->getMarker(); + + problem_->setEstimator(oldEstimator_); + problem_->setMarker(oldMarker_); + } + } + + int ParallelProblemScal::getNumProblems() { return 1; } + + ProblemStatBase *ParallelProblemScal::getProblem(int number) + { + return problem_; + } + + ProblemStatBase *ParallelProblemScal::getProblem(const std::string& name) + { + return problem_; + } + + + void ParallelProblemScal::exchangeDOFVectors(AdaptInfo *adaptInfo) + { + std::vector<DOFVector<double>*>::iterator it, itBegin, itEnd; + itBegin = dofVectors_.begin(); + itEnd = dofVectors_.end(); + for(it = itBegin; it != itEnd; ++it) { + ParallelProblem::exchangeDOFVector(adaptInfo, *it); + } + } + + void ParallelProblemScal::exchangeRankSolutions(AdaptInfo *adaptInfo) + { + rankSolution_[mpiRank_]->copy(*(problem_->getSolution())); + ParallelProblem::exchangeRankSolutions(adaptInfo, + rankSolution_); + } + + void ParallelProblemScal::buildGlobalSolution(AdaptInfo *adaptInfo) + { + ParallelProblem::buildGlobalSolution(adaptInfo, + rankSolution_, + problem_->getSolution()); + +// ParallelProblem::writeRankMacroAndValues(problem_->getSolution(), +// "output/debug_rank"); + + +// { +// char number[3]; +// sprintf(number, "%d", MPI::COMM_WORLD.Get_rank()); +// std::string meshfile = "output/debug_" + std::string(number) + ".mesh"; +// std::string datfile = "output/debug_" + std::string(number) + ".dat"; + +// MacroWriter::writeMacro(problem_->getFESpace(), (char*)meshfile.c_str()); +// ValueWriter::writeValues(problem_->getSolution(), (char*)datfile.c_str()); + +// if(mpiRank_ == 0) { +// std::map<int, int> finePartitionVec; +// partitioner_->fillLeafPartitionVec(&partitionVec_, +// &finePartitionVec); +// ElementFileWriter elemFW("partition", +// problem_->getMesh(), +// problem_->getFESpace(), +// finePartitionVec); +// elemFW.writeFiles(NULL, true); + +// bool wait=true; +// while(wait) {} +// } + +// } + } + + void ParallelProblemScal::coarsenOutOfPartition(AdaptInfo *adaptInfo) + { + bool coarsenAllowed = adaptInfo->isCoarseningAllowed(0); + adaptInfo->allowCoarsening(true, 0); + ParallelProblem::coarsenOutOfPartition(adaptInfo); + adaptInfo->allowCoarsening(coarsenAllowed, 0); + +// int level = localCoarseGridLevel_, overlap = 1; +// bool openOverlap = true; + +// problem_->getMesh()->dofCompress(); + +// ParallelProblem::fillVertexPartitions(level, overlap, openOverlap, +// overlapDistance_); + +// overlapDistance_.clear(); +// if(mpiRank_ == 0) { +// problem_->writeFiles(adaptInfo, true); +// bool wait=true; +// while(wait) {} +// } + +// ParallelProblem::writeRankMacroAndValues(problem_->getSolution(), +// "output/debug_rank", +// 0.0); + +// if(mpiRank_ == 0) { +// std::map<int, int> finePartitionVec; +// partitioner_->fillLeafPartitionVec(&partitionVec_, +// &finePartitionVec); +// ElementFileWriter elemFW("partition", +// problem_->getMesh(), +// problem_->getFESpace(), +// finePartitionVec); +// elemFW.writeFiles(NULL, true); +// bool wait = true; +// while(wait) {} +// } + } + + + // ========================================================================= + // ===== class ParallelProblemVec ========================================== + // ========================================================================= + + ParallelProblemVec::ParallelProblemVec(const std::string& name, + ProblemVec *problem, + ProblemInstatVec *problemInstat, + std::vector<DOFVector<double>*> vectors) + : ParallelProblem(name, + problem, + problemInstat, + vectors, + problem->getMesh(0), + problem->getRefinementManager(0), + problem->getCoarseningManager(0)), + problem_(problem), + problemInstat_(problemInstat) + { + numComponents_ = problem_->getNumComponents(); + + std::vector<FiniteElemSpace*> feSpaces(numComponents_); + int i, j; + for(i = 0; i < numComponents_; i++) { + feSpaces[i] = problem_->getFESpace(i); + } + rankSolution_.resize(mpiSize_); + for(i = 0; i < mpiSize_; i++) { + rankSolution_[i] = NEW SystemVector("rank solution", feSpaces, numComponents_); + for(j = 0; j < numComponents_; j++) { + rankSolution_[i]->setDOFVector(j, NEW DOFVector<double>(feSpaces[j], + "rank solution")); + } + } + if(problemInstat_) { + for(i = 0; i < numComponents_; i++) { + dofVectors_.push_back(problemInstat_->getOldSolution()->getDOFVector(i)); + } + } + } + + ParallelProblemVec::~ParallelProblemVec() + { + int i, j; + for(i = 0; i < mpiSize_; i++) { + for(j = 0; j < numComponents_; j++) { + DELETE rankSolution_[i]->getDOFVector(j); + } + DELETE rankSolution_[i]; + } + } + + void ParallelProblemVec::initParallelization(AdaptInfo *adaptInfo) + { + FUNCNAME("ParallelProblem::initParallelization()"); + + if(mpiSize_ > 1) { + int i; + partitioner_->createPartitionData(); + setElemWeights(adaptInfo); + partitionMesh(adaptInfo); + + refineOverlap(adaptInfo); + createOverlap(adaptInfo); + + oldEstimator_ = problem_->getEstimator(); + oldMarker_ = problem_->getMarker(); + + std::vector<ConditionalEstimator*> condEstimator; + if(static_cast<int>(usersEstimator_.size()) == numComponents_) { + problem_->setEstimator(usersEstimator_); + } else { + for(i = 0; i < numComponents_; i++) { + condEstimator.push_back(NEW ConditionalEstimator(oldEstimator_[i])); + problem_->setEstimator(condEstimator[i], i); + } + } + + if(static_cast<int>(usersMarker_.size()) == numComponents_) { + for(i = 0; i < numComponents_; i++) { + problem_->setMarker(usersMarker_[i], i); + } + } else { + TEST_EXIT(static_cast<int>(condEstimator.size()) == numComponents_) + ("use conditional marker only together with conditional estimator\n"); + for(i = 0; i < numComponents_; i++) { + ConditionalMarker *newMarker = + NEW ConditionalMarker("parallel marker", + i, + oldMarker_[i], + globalCoarseGridLevel_, + localCoarseGridLevel_); + problem_->setMarker(newMarker, i); + } + } + + // modify file writers + char number[10]; + sprintf(number, "%d", MPI::COMM_WORLD.Get_rank()); + ::std::list<FileWriterInterface*> fileWriters = problem_->getFileWriterList(); + ::std::list<FileWriterInterface*>::iterator fwIt, fwBegin, fwEnd; + fwBegin = fileWriters.begin(); + fwEnd = fileWriters.end(); + for(fwIt = fwBegin; fwIt != fwEnd; ++fwIt) { + (*fwIt)->setFilename((*fwIt)->getFilename() + "_proc" + + ::std::string(number) + "_"); + (*fwIt)->setTraverseProperties(-1, 0, elementInPartition); + } + } + } + + void ParallelProblemVec::exitParallelization(AdaptInfo *adaptInfo) + { + FUNCNAME("ParallelProblem::exitParallelization()"); + + if(mpiSize_ > 1) { + ParallelProblem::exitParallelization(adaptInfo); + + if(!timeIF_) problem_->writeFiles(adaptInfo, true); + + partitioner_->deletePartitionData(); + + int i; + for(i = 0; i < numComponents_; i++) { + if(static_cast<int>(usersEstimator_.size()) == numComponents_) + DELETE problem_->getEstimator(i); + if(static_cast<int>(usersMarker_.size()) == numComponents_) + DELETE problem_->getMarker(i); + + problem_->setEstimator(oldEstimator_[i], i); + problem_->setMarker(oldMarker_[i], i); + } + + usersEstimator_.resize(0); + usersMarker_.resize(0); + } + } + + void ParallelProblemVec::exchangeDOFVectors(AdaptInfo *adaptInfo) + { + std::vector<DOFVector<double>*>::iterator it, itBegin, itEnd; + itBegin = dofVectors_.begin(); + itEnd = dofVectors_.end(); + for(it = itBegin; it != itEnd; ++it) { + ParallelProblem::exchangeDOFVector(adaptInfo, *it); + } + } + + void ParallelProblemVec::exchangeRankSolutions(AdaptInfo *adaptInfo) + { + rankSolution_[mpiRank_]->copy(*(problem_->getSolution())); + + std::vector<DOFVector<double>*> rankSol(mpiSize_); + + int i, j; + for(i = 0; i < numComponents_; i++) { + for(j = 0; j < mpiSize_; j++) { + rankSol[j] = rankSolution_[j]->getDOFVector(i); + } + + ParallelProblem::exchangeRankSolutions(adaptInfo, + rankSol); + } + } + + void ParallelProblemVec::buildGlobalSolution(AdaptInfo *adaptInfo) + { + std::vector<DOFVector<double>*> rankSol(mpiSize_); + + int i, j; + for(i = 0; i < numComponents_; i++) { + for(j = 0; j < mpiSize_; j++) { + rankSol[j] = rankSolution_[j]->getDOFVector(i); + } + + ParallelProblem::buildGlobalSolution(adaptInfo, + rankSol, + problem_->getSolution()->getDOFVector(i)); + } + } + + int ParallelProblemVec::getNumProblems() { return 1; } + + ProblemStatBase *ParallelProblemVec::getProblem(int number) + { + return problem_; + } + + ProblemStatBase *ParallelProblemVec::getProblem(const std::string& name) + { + return problem_; + } + + void ParallelProblemVec::coarsenOutOfPartition(AdaptInfo *adaptInfo) + { + std::vector<bool> coarsenAllowed(numComponents_); + int i; + for(i = 0; i < numComponents_; i++) { + coarsenAllowed[i] = adaptInfo->isCoarseningAllowed(i); + adaptInfo->allowCoarsening(true, i); + } + + ParallelProblem::coarsenOutOfPartition(adaptInfo); + for(i = 0; i < numComponents_; i++) { + adaptInfo->allowCoarsening(coarsenAllowed[i], i); + } + } + +} diff --git a/AMDiS/src/ParallelProblem.h b/AMDiS/src/ParallelProblem.h new file mode 100644 index 0000000000000000000000000000000000000000..947707bb12f8dd0f9a1b0e4d2884978041baab47 --- /dev/null +++ b/AMDiS/src/ParallelProblem.h @@ -0,0 +1,416 @@ +// ============================================================================ +// == == +// == AMDiS - Adaptive multidimensional simulations == +// == == +// ============================================================================ +// == == +// == crystal growth group == +// == == +// == Stiftung caesar == +// == Ludwig-Erhard-Allee 2 == +// == 53175 Bonn == +// == germany == +// == == +// ============================================================================ +// == == +// == http://www.caesar.de/cg/AMDiS == +// == == +// ============================================================================ + +/** \file ParallelProblem.h */ + +#ifndef AMDIS_PARALLELPROBLEM_H +#define AMDIS_PARALLELPROBLEM_H + +#include "ProblemTimeInterface.h" +#include "ProblemIterationInterface.h" +#include "AdaptInfo.h" +#include "mpi.h" +#include <map> +#include <vector> +#include <set> + +namespace AMDiS { + + // ========================================================================= + // ===== class ParallelProblemInterface ==================================== + // ========================================================================= + + /** \brief + * Interface for parallel problems + */ + class ParallelProblemInterface + { + public: + virtual void initParallelization(AdaptInfo *adaptInfo) = 0; + virtual void exitParallelization(AdaptInfo *adaptInfo) = 0; + }; + + // ========================================================================= + // ===== class ParallelProblemBase ========================================= + // ========================================================================= + + /** \brief + * Schablonen Klasse + */ + class ParallelProblemBase : public ParallelProblemInterface, + public ProblemIterationInterface, + public ProblemTimeInterface + { + public: + ParallelProblemBase(ProblemIterationInterface *iterationIF, + ProblemTimeInterface *timeIF); + + virtual ~ParallelProblemBase() {}; + + virtual bool doPartitioning(AdaptInfo *adaptInfo, double localWeightSum) = 0; + virtual bool doBuildGlobalSolution(AdaptInfo *adaptInfo) = 0; + virtual double setElemWeights(AdaptInfo *adaptInfo) = 0; + virtual void partitionMesh(AdaptInfo *adaptInfo) = 0; + virtual void refineOverlap(AdaptInfo *adaptInfo) = 0; + virtual void globalRefineOutOfPartition(AdaptInfo *adaptInfo) = 0; + virtual void createOverlap(AdaptInfo *adaptInfo) = 0; + virtual void exchangeDOFVectors(AdaptInfo *adaptInfo) = 0; + virtual void coarsenOutOfPartition(AdaptInfo *adaptInfo) = 0; + virtual void synchronizeMeshes(AdaptInfo *adaptInfo) = 0; + virtual void exchangeRankSolutions(AdaptInfo *adaptInfo) = 0; + virtual void buildGlobalSolution(AdaptInfo *adaptInfo) = 0; + + virtual void exitParallelization(AdaptInfo *adaptInfo) + { + if (!timeIF_) + closeTimestep(adaptInfo); + }; + + virtual void setTime(AdaptInfo *adaptInfo) + { + if (timeIF_) + timeIF_->setTime(adaptInfo); + }; + + virtual void initTimestep(AdaptInfo *adaptInfo) + { + if (timeIF_) + timeIF_->initTimestep(adaptInfo); + }; + + virtual void closeTimestep(AdaptInfo *adaptInfo) + { + if (mpiSize_ > 1 && doBuildGlobalSolution(adaptInfo)) { + synchronizeMeshes(adaptInfo); + exchangeRankSolutions(adaptInfo); + buildGlobalSolution(adaptInfo); + } + if (timeIF_) + timeIF_->closeTimestep(adaptInfo); + }; + + virtual void solveInitialProblem(AdaptInfo *adaptInfo) + { + if (timeIF_) + timeIF_->solveInitialProblem(adaptInfo); + }; + + virtual void transferInitialSolution(AdaptInfo *adaptInfo) + { + if (timeIF_) + timeIF_->transferInitialSolution(adaptInfo); + }; + + + virtual void beginIteration(AdaptInfo *adaptInfo) + { + iterationIF_->beginIteration(adaptInfo); + }; + + virtual Flag oneIteration(AdaptInfo *adaptInfo, Flag toDo = FULL_ITERATION) + { + Flag flag; + + if(mpiSize_ > 1 && toDo.isSet(MARK | ADAPT)) { + flag = iterationIF_->oneIteration(adaptInfo, MARK | ADAPT); + + double localWeightSum = setElemWeights(adaptInfo); + if(doPartitioning(adaptInfo, localWeightSum)) { + + clock_t partitioningStart = clock(); + + synchronizeMeshes(adaptInfo); + partitionMesh(adaptInfo); + refineOverlap(adaptInfo); + createOverlap(adaptInfo); + synchronizeMeshes(adaptInfo); + exchangeDOFVectors(adaptInfo); + coarsenOutOfPartition(adaptInfo); + + clock_t partitioningEnd = clock(); + partitioningTime = TIME_USED(partitioningStart, + partitioningEnd); + computationStart = partitioningEnd; + } + + flag |= iterationIF_->oneIteration(adaptInfo, toDo & ~(MARK | ADAPT)); + } else { + flag = iterationIF_->oneIteration(adaptInfo, toDo); + } + + // synchronize adaption flag + unsigned long *flagBuffer = GET_MEMORY(unsigned long, mpiSize_); + + unsigned long localFlag = flag.getFlags(); + + MPI::COMM_WORLD.Allgather(&localFlag, 1, MPI_UNSIGNED_LONG, + flagBuffer, 1, MPI_UNSIGNED_LONG); + int i; + for(i = 0; i < mpiSize_; i++) { + flag.setFlag(flagBuffer[i]); + } + FREE_MEMORY(flagBuffer, unsigned long, mpiSize_); + return flag; + }; + + virtual void endIteration(AdaptInfo *adaptInfo) + { + iterationIF_->endIteration(adaptInfo); + }; + + protected: + int mpiRank_; + int mpiSize_; + ProblemIterationInterface *iterationIF_; + ProblemTimeInterface *timeIF_; + clock_t computationStart; + double partitioningTime; + }; + + // ========================================================================= + // ===== class ParallelProblem ============================================= + // ========================================================================= + + class ParMetisPartitioner; + class RefinementManager; + class CoarseningManager; + class ElInfo; + class MeshStructure; + + class ParallelProblem : public ParallelProblemBase + { + public: + ParallelProblem(const std::string& name, + ProblemIterationInterface *iterationIF, + ProblemTimeInterface *timeIF, + std::vector<DOFVector<double>*> vectors, + Mesh *mesh, + RefinementManager *rm, + CoarseningManager *cm); + + virtual ~ParallelProblem(); + + virtual bool doPartitioning(AdaptInfo *adaptInfo, double localWeightSum); + + virtual bool doBuildGlobalSolution(AdaptInfo *adaptInfo); + + virtual void partitionMesh(AdaptInfo *adaptInfo); + virtual void refineOverlap(AdaptInfo *adaptInfo); + virtual void createOverlap(AdaptInfo *adaptInfo); + virtual void globalRefineOutOfPartition(AdaptInfo *adaptInfo); + virtual void coarsenOutOfPartition(AdaptInfo *adaptInfo); + virtual void synchronizeMeshes(AdaptInfo *adaptInfo); + virtual double setElemWeights(AdaptInfo *adaptInfo); + + virtual void globalRefinements(); + + void exchangeRankSolutions(AdaptInfo *adaptInfo, + std::vector<DOFVector<double>*> rankSolutions); + + void exchangeDOFVector(AdaptInfo *adaptInfo, + DOFVector<double> *vec); + + void buildGlobalSolution(AdaptInfo *adaptInfo, + std::vector<DOFVector<double>*> rankSolutions, + DOFVector<double> *globalSolution); + + void createOverlap(int level, int overlap, bool openOverlap, + std::map<Element*, int> &overlapDistance); + + void fillVertexPartitions(int level, int overlap, bool openOverlap, + std::map<Element*, int> &overlapDistance); + + void setRepartitionSteps(int steps) { repartitionSteps_ = steps; }; + + void puEveryTimestep(bool pu) { puEveryTimestep_ = pu; }; + + void addDOFVector(DOFVector<double> *vec) + { + dofVectors_.push_back(vec); + }; + + void exchangeMeshStructureCodes(MeshStructure *structures); + + static bool writeElement(ElInfo *elInfo); + + // static void writeRankMacroAndValues(DOFVector<double> *vec, + // const char *name = NULL, + // double time = 0.0); + + + virtual void serialize(std::ostream&) {}; + + virtual void deserialize(std::istream&) {}; + + protected: + double errors2map(std::map<int, double> &errMap, int comp, bool add); + + protected: + std::string name_; + Mesh *mesh_; + RefinementManager *refinementManager_; + CoarseningManager *coarseningManager_; + ParMetisPartitioner *partitioner_; + std::map<int, int> partitionVec_; + std::map<int, int> oldPartitionVec_; + std::map<int, double> elemWeights_; + std::map<Element*, std::set<int> > elementPartitions_; + std::map<DegreeOfFreedom, std::set<int> > vertexPartitions_; + int repartitionSteps_; + bool puEveryTimestep_; + std::vector<DOFVector<double>*> dofVectors_; + double upperPartThreshold_; + double lowerPartThreshold_; + int globalCoarseGridLevel_; + int localCoarseGridLevel_; + int globalRefinements_; + std::map<Element*, int> overlapDistance_; + + int adaptiveThresholds_; + double thresholdIncFactor_; + double thresholdDecFactor_; + double repartTimeFactor_; + double minUpperTH_; + double maxLowerTH_; + }; + + // ========================================================================= + // ===== class ParallelProblemScal ========================================= + // ========================================================================= + + class FiniteElemSpace; + class ProblemScal; + class ProblemInstatScal; + class Estimator; + class Marker; + + class ParallelProblemScal : public ParallelProblem + { + public: + ParallelProblemScal(const std::string& name, + ProblemScal *problem, + ProblemInstatScal *problemInstat, + std::vector<DOFVector<double>*> vectors); + + virtual ~ParallelProblemScal(); + + virtual void initParallelization(AdaptInfo *adaptInfo); + + virtual void exitParallelization(AdaptInfo *adaptInfo); + + virtual void exchangeDOFVectors(AdaptInfo *adaptInfo); + + virtual void exchangeRankSolutions(AdaptInfo *adaptInfo); + + virtual void buildGlobalSolution(AdaptInfo *adaptInfo); + + virtual void coarsenOutOfPartition(AdaptInfo *adaptInfo); + + virtual int getNumProblems(); + + virtual ProblemStatBase *getProblem(int number = 0); + + virtual ProblemStatBase *getProblem(const std::string& name); + + void setEstimator(Estimator *est) { usersEstimator_ = est; }; + + void setMarker(Marker *marker) { usersMarker_ = marker; }; + + protected: + ProblemScal *problem_; + + ProblemInstatScal *problemInstat_; + + Estimator *oldEstimator_; + + Marker *oldMarker_; + + std::vector<DOFVector<double>*> rankSolution_; + + Estimator *usersEstimator_; + + Marker *usersMarker_; + }; + + // ========================================================================= + // ===== class ParallelProblemVec ========================================== + // ========================================================================= + + class ProblemVec; + class ProblemInstatVec; + class SystemVector; + + class ParallelProblemVec : public ParallelProblem + { + public: + ParallelProblemVec(const std::string& name, + ProblemVec *problem, + ProblemInstatVec *problemInstat, + std::vector<DOFVector<double>*> vectors); + + virtual ~ParallelProblemVec(); + + virtual void initParallelization(AdaptInfo *adaptInfo); + + virtual void exitParallelization(AdaptInfo *adaptInfo); + + virtual void exchangeDOFVectors(AdaptInfo *adaptInfo); + + virtual void exchangeRankSolutions(AdaptInfo *adaptInfo); + + virtual void buildGlobalSolution(AdaptInfo *adaptInfo); + + virtual void coarsenOutOfPartition(AdaptInfo *adaptInfo); + + virtual int getNumProblems(); + + virtual ProblemStatBase *getProblem(int number = 0); + + virtual ProblemStatBase *getProblem(const std::string& name); + + void setEstimator(std::vector<Estimator*> est) { + usersEstimator_ = est; + }; + + void setMarker(std::vector<Marker*> marker) + { + usersMarker_ = marker; + }; + + protected: + ProblemVec *problem_; + + ProblemInstatVec *problemInstat_; + + std::vector<Estimator*> oldEstimator_; + + std::vector<Marker*> oldMarker_; + + std::vector<SystemVector*> rankSolution_; + + std::vector<Estimator*> usersEstimator_; + + std::vector<Marker*> usersMarker_; + + int numComponents_; + }; + +} + +#endif diff --git a/AMDiS/src/Parameters.cc b/AMDiS/src/Parameters.cc new file mode 100644 index 0000000000000000000000000000000000000000..217b0bc0de1d70ed5ebc4219d6dd30f10f103e80 --- /dev/null +++ b/AMDiS/src/Parameters.cc @@ -0,0 +1,816 @@ +#include "Parameters.h" +#include <fstream> +#include <sstream> +#include <algorithm> +#include <stdarg.h> +#include <time.h> +#include <sys/types.h> +#include <sys/stat.h> +#include <unistd.h> + +namespace AMDiS { + + const char Parameters::comment='%'; + Parameters* Parameters::singlett = NULL; + const char* Parameters::param_call_fct = NULL; + const char* Parameters::param_call_file = NULL; + int Parameters::param_call_line = 0; + + + int Parameters::getGlobalParameter(int info, const ::std::string& key, + const char *format, ...) + { + FUNCNAME("Parameters::getGlobalParameter"); + int count, *ival; + ::std::vector<struct Parameters::param>::iterator i; + char *sval, *cval; + const char *word; + ::std::string s; + const char *p; + double *rval; + unsigned char *Uval; + char *Sval; + double dval; + param tParam(key); + const char* funcName2 = param_call_fct ? param_call_fct : funcName; + + va_list arg; + + Parameters::initIntern(); + + if (Parameters::singlett->paramInfo) + { + if (Parameters::singlett->paramInfo > 1) + info = max(info, Parameters::singlett->paramInfo-1); + } + else + info = 0; + + if (0==Parameters::singlett->allParam.size()) + { + if (0==Parameters::singlett->filename.size()) + { + INFO(info,1)("no parameters defined\n"); + return(0); + } + else + { + Parameters::singlett->read(Parameters::singlett->filename,key); + } + } + + i = ::std::find(Parameters::singlett->allParam.begin(),Parameters::singlett->allParam.end(),tParam); + + if (i == Parameters::singlett->allParam.end()) + { + if (funcName != funcName2) + { + INFO(info,1)("initialization of parameter `%s'\n", key.data()); + INFO(info,1)("fails on line %d of file %s\n", param_call_line, + param_call_file); + } + else + INFO(info,1)("initialization of parameter `%s' fails\n", key.data()); + + // param_call_fct = NULL; + return(0); + } + + va_start(arg, format); + count = 0; + + INFO(info,2)("parameter `%s' initialized with: ", key.data()); + + s = (*i).parameters; + + for (p = format; *p; p++) + { + if (*p != '%') continue; + + word = Parameters::singlett->getNextWord(&s); + if (!*word) + { + PRINT_INFO(info,2)("\n"); + if (0<(*i).funcName.size()) + { + INFO(info,4)("parameter initialized by %s()\n", + (*i).funcName.data()); + INFO(info,4)("on line %d of file \"%s\"\n", (*i).lineNo, + (*i).filename.data()); + } + else if (0<(*i).filename.size()) + { + INFO(info,4) + ("parameter initialized on line %2d of init file \"%s\"\n", + (*i).lineNo, (*i).filename.data()); + } + else + { + INFO(info,4)("location of initialization unknown\n"); + } + va_end(arg); + return(count); + } + count++; + + switch(*++p) + { + case 'S': + Sval = va_arg(arg, char *); + *Sval = static_cast<char>(atoi(word)); + INFO(info,2)("%d ", *Sval); + break; + case 'U': + Uval = va_arg(arg, unsigned char *); + *Uval = static_cast<unsigned char>(atoi(word)); + INFO(info,2)("%d ", *Uval); + break; + case 'c': + cval = va_arg(arg, char *); + *cval = *word; + INFO(info,2)("%c ", *cval); + break; + case 's': + sval = va_arg(arg, char *); + strcpy(sval, word); + INFO(info,2)("%s ", sval); + break; + case 'd': + ival = va_arg(arg, int *); + *ival = atoi(word); + INFO(info,2)("%d ", *ival); + break; + case 'e': + case 'f': + case 'g': + rval = va_arg(arg, double *); + *rval = dval = atof(word); + INFO(info,2)("%g ", dval); + break; + case '*': + break; + default: + INFO(info,2)("\n"); + INFO(info,2) + ("unknow format specifier `%%%c', skipping initialization of %s\n", + *p, key.data()); + } + } + + INFO(info,2)("\n"); + // if (funcName != func_name) + // INFO(info,2)("on line %d of file %s\n", param_call_line, param_call_file); + + if ((*i).funcName.size()>0) + { + INFO(info,4)("parameter initialized by %s()\n", (*i).funcName.data()); + INFO(info,4)("on line %d of file \"%s\"\n", (*i).lineNo, + (*i).filename.data()); + } + else if ((*i).filename.size()>0) + { + INFO(info,4) + ("parameter initialized on line %2d of init file \"%s\"\n", + (*i).lineNo, (*i).filename.data()); + } + else + { + INFO(info,4)("location of initialization unknown\n"); + } + + va_end(arg); + // param_call_fct = NULL; + return(count); + } + + int Parameters::getGlobalParameter(int flag, const ::std::string& key, ::std::string* param) + { + static char tempParam[255]; + TEST_EXIT(param)("no parameter\n"); + strcpy(tempParam, param->c_str()); + int result = getGlobalParameter(flag, key, "%s", tempParam); + param->assign(tempParam); + return result; + } + + void Parameters::read(const ::std::string& aFilename, + const ::std::string& maxKey) + { + FUNCNAME("Parameters::read()"); + + char line[256]; + int nLine = 0; + ::std::string key, parameter; + ::std::string actfile; + + if (aFilename.size() == 0) + return; + + singlett->inputFile.open(aFilename.c_str(), ::std::ios::in); + if (!inputFile.is_open()) { + ERROR("init-file can't be opened\n"); + return; + } + + if (!cppRead) { + INFO(paramInfo,2)("reading from file %s\n", aFilename.data()); + actfile = getActFile(aFilename); + } + + while (!inputFile.eof()) { + inputFile.getline(line, 255); + nLine++; + + key = getKey(line, nLine, aFilename); + + if (key == "") + continue; + + if (cppRead && key[0] == '#') { + int pos=0; + + sscanf(key.data(), "#%d", &nLine); + nLine--; + pos=key.find('\"'); + pos=key.find('\"',pos+1); + key.resize(pos); + actfile = getActFile(key); + + continue; + } + + parameter = getPar(key, line, &nLine, aFilename); + if (parameter == "") + continue; + + addParam(key, parameter, actfile, nLine, funcName); + } + + singlett->inputFile.close(); + + + return; + } + + const ::std::string& Parameters::getActFile(const ::std::string& aFilename) + { + FUNCNAME("Parameters::getActFile"); + ::std::list< ::std::string>::iterator i; + ::std::string actfile; + + for (i = filenames.begin(); i != filenames.end(); i++) + if (aFilename==*i) break; + + if (i != filenames.end()) + { + return(const_cast<const ::std::string&>(*i)); + } + else + { + filenames.push_back(aFilename); + return(const_cast<const ::std::string&>(aFilename)); + } + } + + void Parameters::swap(int i, int j) + { + param tmp(allParam[i]); + allParam[i] = allParam[j]; + allParam[j] = tmp; + return; + } + + void Parameters::qsort(int left, int right) + { + int i, last; + + if (left >= right) return; + + swap(left, (left+right)/2); + last = left; + for (i = left+1; i <= right; i++) + if (allParam[i].key.compare(allParam[left].key) < 0) + swap(++last, i); + + swap(left, last); + qsort(left, last-1); + qsort(last+1, right); + return; + } + + + const ::std::string Parameters::getKey(const ::std::string& s, int nLine, + const ::std::string& aFilename) + { + FUNCNAME("Parameters::getKey"); + ::std::string fn,key=""; + char c; + int i,pos,epos; + ::std::string h=" \t\r\f"; + + if (cppRead) + { + if (s[0] == '#') /* Praeprozessor line */ + return(s); + } + pos=0; + pos=s.find_first_not_of(" \t\f\r"); //skip Blank + + if(pos < 0) + return key; + + if (s[pos] == comment || s[pos] == '\0' || s[pos] == '\n') + return(key); + + if (s[pos] == '#') + { + if (static_cast<int>(s.find("#include")) == pos) + /****************************************************************************/ + /* another init file has to be included */ + /****************************************************************************/ + { + pos += strlen("#include"); + pos=s.find_first_not_of(" \t\f\r"); + + i = 0; + switch (c = s[pos++]) + { + case '<': + c = '>'; + case '\"': + h+=c; + epos=s.find_first_not_of(h,pos); + fn = s.substr(pos,epos-1); + + if (s[epos] != c) + { + ERROR("aFilename of include not terminated by %c\n", c); + ERROR("skipping line %d of file %s\n", nLine, aFilename.c_str()); + return(""); + } + break; + default: + ERROR("no aFilename of include file found\n"); + ERROR("skipping line %d of file %s\n", nLine, aFilename.c_str()); + return(""); + } + + read(fn); + return(""); + } + else + { + ERROR("# must not be the first character on a line; except #include\n"); + return(""); + } + } + + /****************************************************************************/ + /* now get the key */ + /****************************************************************************/ + i = 0; + epos=s.find_first_of(":#",pos+1); + if (s[epos] == '#') + { + ERROR("key must not contain '%c'.\n", '#'); + ERROR("Skipping line %d of file %s\n", nLine, aFilename.c_str()); + return(""); + } + + key= s.substr(pos,epos); + + if (s[epos] != ':') + { + ERROR("key was not terminated by ':'.\n"); + ERROR("Skipping line %d of file %s\n", nLine, aFilename.c_str()); + return(""); + } + + if (key.size() == 0) + { + ERROR("use of ':' without key.\n"); + ERROR("Skipping line %d of file %s\n", nLine, aFilename.c_str()); + return(""); + } + return(key); + } + + const ::std::string Parameters::getPar(const ::std::string& key, + const ::std::string& si, int *nl, + const ::std::string& fn) + { + FUNCNAME("Parameters::getPar"); + int i, pos,ol = *nl; + ::std::string inp; + ::std::string s=si; + ::std::string parameter=""; + + pos=s.find(':'); + pos=s.find_first_not_of(" \r\f\t",pos+1); + + i=pos; + while(i < static_cast<int>(s.length()) && s[i]!='#' && s[i]!='%' && s[i]!='\n') { + if (s[i] == '\\' && i+1 < static_cast<int>( s.length()) && s[i+1] == '\n') + { + s = s.substr(0, i); + (*nl)++; + inputFile >> inp; + s+=inp; + if (inputFile.eof()) + { + ERROR("EOF reached while reading parameters of key %s\n", key.c_str()); + if (ol == *nl-1) ERROR("Skipping line %d of file %s\n", *nl, fn.c_str()); + else ERROR("Skipping lines %d-%d of file %s\n", ol, *nl, fn.c_str()); + + return(""); + } + } + else + { + if (isBlankChar(static_cast<char>(s[i]))) + { + parameter+= ' '; + i=pos=s.find_first_not_of(" \r\t\f", i); + if(i == static_cast<int>(::std::string::npos)) { + i = parameter.length()-1; + break; + } + } + else + { + parameter+= s.substr(i++,1); + } + } + } + + i=parameter.find_last_not_of(" \r\t\f"); + parameter.resize(i+1); + + if (i == 0 && isBlankChar(parameter[0])) + { + ERROR("no parameter of key %s.\n", key.c_str()); + if (ol == *nl) ERROR("Skipping line %d of file %s\n", *nl, fn.c_str()); + else ERROR("Skipping lines %d-%d of file %s\n", ol, *nl, fn.c_str()); + + return(""); + } + + return(parameter); + } + + void Parameters::addParam(const ::std::string& key, + const ::std::string& parameter, + const ::std::string& actfile, + int nLine, + const ::std::string& fname) + { + FUNCNAME("Parameters::addParam()"); + unsigned size_k, size_p; + int scmp = 0; + param newPar; + + size_k = key.size()+1; + size_p = parameter.size()+1; + + ::std::vector<param>::iterator it; + for (it = allParam.begin(); it != allParam.end(); it++) { + if ((scmp = key.compare((*it).key)) >=0 ) + break; + } + + + if (it != allParam.end() && scmp == 0) { + /****************************************************************************/ + /* key does already exist: save new parameters */ + /****************************************************************************/ + (*it).parameters = parameter; + (*it).filename = actfile; + (*it).funcName = fname; + (*it).lineNo = nLine; + + return; + } + + newPar.key = key; + newPar.parameters = parameter; + newPar.filename = actfile; + newPar.funcName.assign(fname); + newPar.lineNo = nLine; + allParam.insert(it, newPar); + + return; + } + + + + void Parameters::initIntern() + { + if (NULL == singlett) { + singlett = NEW Parameters; + } + } + + void Parameters::printParameters() + { + FUNCNAME("Parameters::printParameters()"); + + initIntern(); + + ::std::cout << "SIZE: " << singlett->allParam.size() << ::std::endl; + + ::std::vector<param>::iterator it; + for (it = singlett->allParam.begin(); it != singlett->allParam.end(); it++) { + MSG("%s: %s\n", (*it).key.data(), (*it).parameters.data()); + if (0 < (*it).funcName.size()) { + MSG("initialized by %s() on line %3d of file \"%s\"\n", + (*it).funcName.data(), (*it).lineNo, (*it).filename.data()); + } else if (0 < (*it).filename.size()) { + MSG("initialized on line %2d of file \"%s\"\n", + (*it).lineNo, (*it).filename.data()); + } else { + MSG("can not locate initialization location\n"); + } + } + } + + + void Parameters::init(int p, ::std::string fn, const char *flags) + { + FUNCNAME("Parameters::init()"); + + int val; + ::std::ostringstream tmp_file; + ::std::ofstream cpp_flags; + ::std::ofstream call_cpp; + ::std::string file; + ::std::ofstream outFile; + ::std::string lfn = fn; + ::std::string::size_type fpos= lfn.find('/'); + + if (fpos == ::std::string::npos) { + fpos = 0; + } else { + ++fpos; + } + lfn.insert(fpos,".#"); + + + struct stat buf; + + if ((val = lstat(lfn.c_str(), &buf)) == 0) { + if ((buf.st_mode&S_IFLNK) && (buf.st_size>0)) { + ERROR_EXIT("Unsaved version of init file exists\n"); + } + } + + initIntern(); + if (0 == fn.size()) { + return; + } + + if (NULL == flags) { + singlett->read(fn); + } else { + singlett->inputFile.open(fn.data(),::std::ios::in); + if (!(singlett->inputFile.rdstate())) { + ERROR("can not read from file %s\n", fn.data()); + return; + } + singlett->inputFile.close(); +#ifndef CPP + ERROR("no cpp available; reading file %s without help of cpp\n", + fn.c_str()); + init(p, fn); + + return; +#else + time(&act_time); + if (sys_test("test -w", "/tmp")) /* you may write to /tmp */ + { + file = fn.substr(fn.find_last_of("/\\")); + tmp_file << "/tmp/"<<file<< ".cpp"; + if (sys_test("test -f", tmp_file.str())) /* file exists :-( */ + { + tmp_file.freeze(false); + tmp_file<< "."<< static_cast<int>( act_time); + if (sys_test("test -f", tmp_file.str())) /* file exists :-( */ + *(tmp_file.str()) = '\0'; + } + } + + if (*(tmp_file.str()) == '\0') + { + if (sys_test("test -f", tmp_file.str()+5)) + { + *(tmp_file.str()) = '\0'; + } + } + + if (*(tmp_file.str())!='\0' && (outFile.open(tmp_file.str()))) + outFile.close(); + else + { + ERROR("could not open temporary file for CPP\n"); + ERROR("can not write to /tmp and files %s.cpp and\n", fn); + ERROR_EXIT("%s.cpp.%d either exist or are not writable\n", + fn, act_time); + } + + tmp_file.freeze(false); + + cpp_flags<< "-DDIM="<<DIM<<" -DDIM_OF_WORLD="<<Global::getGeo(WORLD); + if (flags) + cpp_flags << flags; + + call_cpp << CPP <<" "<<cpp_flags<<" "<<fn<< " > "<<tmp_file; + + /****************************************************************************/ + /* invoke cpp: */ + /****************************************************************************/ + + val = system(call_cpp.str()); + if (val) + { + MSG("val = %d\n", val); + ERROR("error during cpp call; reading file %s without help of cpp\n", + fn); + WAIT; + init(p, fn); + return; + } + + /**********************************************************************/ + /* read parameters from temp file */ + /**********************************************************************/ + + cpp_read = true; + singlett->read(tmp_file); + cpp_read = false; + /**********************************************************************/ + /* remove temp file */ + /**********************************************************************/ + + sprintf(call_cpp.str(), "/bin/rm %s", tmp_file.str()); + val = system(call_cpp.str()); + call_cpp.freeze(false); + tmp_file.freeze(false); + +#endif + } + + val = 10; // default for level of information + getGlobalParameter(0, "level of information", "%d", &val); + singlett->msgInfo=val; + + val = 1; // default for WAIT + getGlobalParameter(0, "WAIT", "%d", &val); + singlett->msgWait=val; + + val = 1; // default for parameter information + getGlobalParameter(0, "parameter information", "%d", &val); + singlett->paramInfo = val; + + if (!singlett->msgInfo) + singlett->paramInfo = 0; + + if (p && singlett->msgInfo) + printParameters(); + + return; + } + + void Parameters::readArgv(int argc, char **argv) + { + FUNCNAME("Parameters::readArgv()"); + + for (int i = 0; i < argc; i++) { + if (strcmp("-rs", argv[i]) == 0) { + ADD_PARAMETER(0, "argv->rs", argv[i + 1]); + } + } + } + + int Parameters::initFuncName(const char * call_fct, const char * call_file, + int call_line) + { + param_call_fct = call_fct; + param_call_file = call_file; + param_call_line = call_line; + + return(1); + } + + int Parameters::binSearch(const ::std::string& key, int n_keys) + { + int cond, left, right, mid; + + left = 0; + right = n_keys-1; + + while (left <= right) { + mid = (left+right)/2; + + if ((cond = allParam[mid].key.compare(key)) < 0) { + left = mid + 1; + } else if (cond > 0) { + right = mid - 1; + } else { + return(mid); + } + } + + return(-1); + } + + + + void Parameters::addGlobalParameter(int p, const ::std::string key, + const ::std::string par, const char *fname, + const char *file, int line) + { + FUNCNAME("Parameters::addGlobalParameter()"); + + int val; + + initIntern(); + + if ((0 == key.size()) || (0 == par.size())) + return; + + singlett->addParam(key, par, ::std::string(file), line, fname); + + val = 10; // defualt for level of information + getGlobalParameter(0, "level of information", "%d", &val); + singlett->msgInfo = val; + + val = 1; // default for WAIT + getGlobalParameter(0, "WAIT", "%d", &val); + singlett->msgWait = val; + + val = 1; // default for parameter information + getGlobalParameter(0, "parameter information", "%d", &val); + singlett->paramInfo = val; + + if (!singlett->msgInfo) + singlett->paramInfo = 0; + + if (p && singlett->msgInfo) + printParameters(); + } + + + + const char *Parameters::getNextWord(::std::string *s) const + { + static char Val[512]; + int wb1,wb2; + + wb1 = s->find_first_not_of(" "); + if (wb1 == static_cast<int>(::std::string::npos)) { + return NULL; + } + + wb2 = s->find_first_of(" "); + if (wb2 == static_cast<int>(::std::string::npos)) { + wb2 = s->length(); + } + + s->copy(Val, wb2-wb1, wb1); + + Val[wb2-wb1] = '\0'; + + return(Val); + } + + void Parameters::save(const ::std::string file, int info) + { + ::std::ofstream fp; + ::std::vector<param>::iterator it; + + initIntern(); + + fp.open(file.data(), ::std::ios::out); + if (0 != fp.rdstate()) + return; + + for (it = singlett->allParam.begin(); it !=singlett->allParam.end(); it++) { + fp << (*it).key << ": " << (*it).parameters << ::std::endl; + + if (info) { + if (((*it).funcName.size()) > 0) { + fp << "%initialized by " << (*it).funcName << "() on line " << + (*it).lineNo << " of file \"" << (*it).filename << "\"" << ::std::endl; + } else if ((*it).filename.size() > 0) { + fp << "%initialized on line "<< (*it).lineNo << + " of file \""<< (*it).filename << "\""<< ::std::endl; + } + } + } + fp.close(); + } + + int Parameters::param::operator==(const param& aParam)const{ + return key == aParam.key; + } + +} diff --git a/AMDiS/src/Parameters.h b/AMDiS/src/Parameters.h new file mode 100644 index 0000000000000000000000000000000000000000..00612d0367e4677e5042ee44094975654ead2ace --- /dev/null +++ b/AMDiS/src/Parameters.h @@ -0,0 +1,397 @@ +// ============================================================================ +// == == +// == AMDiS - Adaptive multidimensional simulations == +// == == +// ============================================================================ +// == == +// == crystal growth group == +// == == +// == Stiftung caesar == +// == Ludwig-Erhard-Allee 2 == +// == 53175 Bonn == +// == germany == +// == == +// ============================================================================ +// == == +// == http://www.caesar.de/cg/AMDiS == +// == == +// ============================================================================ + +/** \file Parameters.h */ + +#ifndef AMDIS_PARAMETERS_H +#define AMDIS_PARAMETERS_H + +#include <stdio.h> +#include <string> +#include <list> +#include <fstream> +#include "Global.h" +#include "MemoryManager.h" +#include "Serializable.h" + +namespace AMDiS { + + // ============================================================================ + // ===== class Parameters ===================================================== + // ============================================================================ + + /** \ingroup Common + * \brief + * Many procedures need parameters, for example the maximal number of + * iterations for an iterative solver, the tolerance for the error in the + * adaptive procedure, etc. It is often very helpful to change the values of + * these parameters without recompiling the program by initializing them from + * a parameter file. + * In order to avoid a fixed list of parameters, we use the following concept: + * Every parameter consists of two strings: a key string by which the parameter + * is identified, and a second string containing the parameter values. These + * values are stored as ASCII-characters and can be converted to int, double, + * etc. according to a format specified by the user. Using this concept, + * parameters can be accessed at any point of the program. + * Usually parameters are initialized from parameter files. Each line of the + * file describes either a single parameter: the key definition terminated by + * a ':' character followed by the parameter values, or specifies another + * parameter file to be included at that point (this can also be done + * recursively). + */ + class Parameters : public Serializable + { + public: + MEMORY_MANAGED(Parameters); + + /** \brief + * Initializes parameters from a file; filename is a string holding the name + * of the file and if values of the argument print and the global variable + * msg info are not zero, a list of all defined parameters is printed to the + * message stream; if init() can not open the input file, no parameter is + * defined. + * One call of this function should be the first executable statement in the + * main program. Several calls of init() are possible. If a key is defined + * more than once, parameter values from the latest definition are valid. + * Parameter values from previous definition(s) are ignored. + * If flags are set, the file is first processed by the C-preprocessor with + * argument flags, replacing macros by their definitions in the parameter + * file and including files specified by \#include"...". + */ + static void init(int print, + ::std::string filename, + const char *flags=NULL); + + /** \brief + * Reads all arguments which are provided to the program. The init filenames + * are ignored. The functions search for the following parameters: + * + * -rs filename: The program is restarted with the given serialization. + * + * All found parameters are added to the global parameter list with the prefix + * argv-> (e.g. argv->rs). + */ + static void readArgv(int argc, char **argv); + + /** \brief + * Initializes a parameter identified by key with values vpar; if the + * parameter already exists, the old values are replaced by the new one; + * if fname is not NULL it contains the name of the calling function. + * file and line specifies source file and line number of the function + * call. If one uses the macro \ref ADD_PARAMETER these last three arguments + * are filled automatically. + * + * If p is non zero, the parameter list is printed. + */ + static void addGlobalParameter(int p, + const ::std::string key, + const ::std::string par, + const char *fname = NULL, + const char *file = NULL, + int line = 0); + + /** \brief + * Looks for a parameter which matches the identifying key string key and + * converts the values of the corresponding string containing the parameter + * values according to the control string format. Pointers to variable(s) of + * suitable types are placed in the unnamed argument list (compare the syntax + * of scanf()). The first argument flag defines the level of information + * during the initialization of parameters with a range of 0 to 4: no to full + * information. The return value is the number of successfully matched and + * assigned input items. + * If there is no parameter key matching key, getGlobalParameter() returns + * without an initialization. The return value is zero. It will also return + * without an initialization and return value zero if no parameter has been + * defined by init parameters(). + * In the case that a parameter matching the key is found, + * getGlobalParameter() acts like a simplified version of sscanf(). The input + * string is the string containing the parameter values. The function reads + * characters from this string, interprets them according to a format, and + * stores the results in its arguments. It expects, as arguments, a control + * string, format (described below) and a set of pointer arguments indicating + * where the converted input should be stored. If there are insufficient + * arguments for the format, the behavior is undefined. If the format is + * exhausted while arguments remain, the excess arguments are simply ignored. + * The return value is the number of converted arguments. + * + * The control string must only contain the following characters used as + * conversion specification: \%s, \%c, \%d, \%e, \%f, \%g, \%U, \%S, or \%*. + * All other characters are ignored. In contrast to scanf(), a numerical + * value for a field width is not allowed. For each element of the control + * string the next word of the parameter string is converted as follows: + * + * -\%s: a character string is expected; the corresponding argument should + * be a character pointer pointing to an array of characters large + * enough to accept the string and a terminating `\0', which will be + * added automatically; the string is one single word of the parameter + * string; as mentioned above strings enclosed in single or double + * quotes are not supported at the moment; + * + * -\%c: matches a single character; the corresponding argument should be a + * pointer to a char variable; if the corresponding word of the + * parameter string consists of more than one character, the rest of + * the word is ignored; no space character is possible as argument; + * + * -\%d: matches an decimal integer, whose format is the same as expected for + * the subject sequence of the atoi() function; the corresponding + * argument should be a pointer to an int variable; + * + * -\%e,%f,%g: matches an optionally signed floating point number, whose + * format is the same as expected for the subject string of the atof() + * function; the corresponding argument should be a pointer to a double + * variable; + * + * -\%U: matches an unsigned decimal integer in the range [0,255], whose + * format is the same as expected for the subject sequence of the + * atoi() function; the corresponding argument should be a pointer to + * an unsigned char variable; + * + * -\%S: matches an optionally signed decimal integer in the range + * [-128,127], whose format is the same as expected for the subject + * sequence of the atoi() function; the corresponding argument should + * be a pointer to an signed char variable; + * + * -\%*: next word of parameter string should be skipped; there must not be + * a corresponding argument. + * + * getGlobalParameter() will always finish its work, successfully or not. + * It may fail if a misspelled key is handed over or there are not so many + * parameter values as format specifiers (the remaining variables are not + * initialized!). If flag is zero, getGlobalParameter() works silently; no + * error message is produced. Otherwise the key and the initialized values + * and error messages are printed. The second way to influence messages + * produced by get parameter() namely by is a parameter parameter information + * specified in a parameter file. + * \see GET_PARAMETER + */ + static int getGlobalParameter(int flag, + const ::std::string& key, + const char *format, + ...); + + /** \brief + * Like getGlobalParameter(flag, key, "%s", param->c_str()). + */ + static int getGlobalParameter(int flag, + const ::std::string& key, + ::std::string *param); + + /** \brief + * Prints all defined parameters to the message stream + */ + static void printParameters(); + + /** \brief + * Used by macro \ref GET_PARAMETER to generate infos about the calling + * function. + */ + static int initFuncName(const char *, + const char *, + int call_line); + + /** \brief + * Returns specified info level + */ + static int getMsgInfo() { return (singlett)?singlett->msgInfo:0; }; + + /** \brief + * Returns specified wait value + */ + static int getMsgWait() { return (singlett)?singlett->msgWait:0; }; + + /** \brief + * Writes all up to now initialized parameters to file according to the + * parameter file format; if the value of info is different from zero, the + * location of the initialization is supplied for each parameter as a + * comment; no original comment is written, since these are not stored. + */ + static void save(const ::std::string file, int info); + + /** \brief + * Checks whether parameters are initialized. if not, call init() + */ + static bool initialized() { return (singlett != NULL); }; + + static Parameters *getSingleton() { return singlett; }; + + // ===== Serializable implementation ===== + + void serialize(::std::ostream &out) { + out.write(reinterpret_cast<const char*>(¶mInfo), sizeof(int)); + out.write(reinterpret_cast<const char*>(&msgInfo), sizeof(int)); + out.write(reinterpret_cast<const char*>(&msgWait), sizeof(int)); + int i, size = static_cast<int>(allParam.size()); + out.write(reinterpret_cast<const char*>(&size), sizeof(int)); + for(i = 0; i < size; i++) { + allParam[i].serialize(out); + } + }; + + void deserialize(::std::istream &in) { + in.read(reinterpret_cast<char*>(¶mInfo), sizeof(int)); + in.read(reinterpret_cast<char*>(&msgInfo), sizeof(int)); + in.read(reinterpret_cast<char*>(&msgWait), sizeof(int)); + int i, size; + in.read(reinterpret_cast<char*>(&size), sizeof(int)); + allParam.resize(size); + for(i = 0; i < size; i++) { + allParam[i].deserialize(in); + } + }; + + private: + static Parameters * singlett; + + static const char *param_call_fct; + + static const char *param_call_file; + + static int param_call_line; + + + /** \brief + * Used internally. + */ + class param : public Serializable + { + public: + param() {}; + + virtual ~param() {}; + + param(const ::std::string& nkey, + const ::std::string& nparameters, + const ::std::string& nfilename, + const ::std::string& nfuncName, + int line) + : key(nkey), + parameters(nparameters), + filename(nfilename), + funcName(nfuncName), + lineNo(line) + {}; + + param(const ::std::string& k): key(k) {}; + + int operator==(const class param& aParam) const; + + int operator!=(const class param& aParam) const { + return !(aParam==*this); + }; + + // ===== Serializable implementation ===== + + void serialize(::std::ostream &out) { + out << key << ::std::endl; + out << parameters << ::std::endl; + out << filename << ::std::endl; + out << funcName << ::std::endl; + out.write(reinterpret_cast<const char*>(&lineNo), sizeof(int)); + }; + + void deserialize(::std::istream &in) { + in >> key; in.get(); + in >> parameters; in.get(); + in >> filename; in.get(); + in >> funcName; in.get(); + in.read(reinterpret_cast<char*>(&lineNo), sizeof(int)); + }; + + public: + ::std::string key; + ::std::string parameters; + ::std::string filename; + ::std::string funcName; + int lineNo; + }; + + static const char comment; + + ::std::string buffer; + + inline bool isBlankChar(const char s) {return (s==' '||s=='\t'||s =='\f'||s=='\r'); }; + const char *getNextWord(::std::string *s) const; + + void read(const ::std::string& filename,const ::std::string& maxKey=""); + + const ::std::string& getActFile(const ::std::string& filename); + + const ::std::string getKey(const ::std::string& s, + int nLine, + const ::std::string& filename); + + const ::std::string getPar(const ::std::string& key, + const ::std::string& s, + int *nl, + const ::std::string& fn); + + void addParam(const ::std::string& key, + const ::std::string& parameter, + const ::std::string& actfile, + int nLine, + const ::std::string& fname); + + Parameters() {}; + + virtual ~Parameters() {}; + + static void initIntern(); + + int binSearch(const ::std::string& key, int n_keys); + + void swap(int i, int j); + + void qsort(int left, int right); + + private: + ::std::string cppFlags; + bool cppRead; + ::std::ifstream inputFile; + ::std::list< ::std::string> filenames; + size_t maxFiles; + ::std::string filename; + int paramInfo; + int msgInfo; + int msgWait; + ::std::vector<param> allParam; + + }; + + + /** \brief + * Acts as add parameter(flag, key, value) but the function is additionally + * supplied with the name of the calling function, source file and line, which + * results in more detailed messages during parameter definition. + */ +#define ADD_PARAMETER(p, key, param) \ + Parameters::addGlobalParameter(p, key, param, funcName, __FILE__, __LINE__); + + /** \brief + * Is a macro and acts in the same way as the function + * getGlobalParameter() but the function is additionally supplied with the + * name of the calling function, source file and line, which results in more + * detailed messages during parameter definition. + */ +#define GET_PARAMETER \ + Parameters::initFuncName(funcName, __FILE__, __LINE__); \ + Parameters::getGlobalParameter + +} + +#endif // AMDIS_PARAMETERS_H diff --git a/AMDiS/src/Parametric.cc b/AMDiS/src/Parametric.cc new file mode 100644 index 0000000000000000000000000000000000000000..a3571c704082e9d934f5fc2b9b95eb7b94dabd12 --- /dev/null +++ b/AMDiS/src/Parametric.cc @@ -0,0 +1,42 @@ +#include "Parametric.h" +#include "ElInfo.h" +#include "DOFVector.h" +#include "FixVec.h" + +namespace AMDiS { + +ElInfo *ParametricFirstOrder::addParametricInfo(ElInfo *elInfo) +{ + elInfo->setParametric(true); + int i, j, dow = Global::getGeo(WORLD); + Element *element = elInfo->getElement(); + const DegreeOfFreedom **dof = element->getDOF(); + + for(i = 0; i < elInfo->getElement()->getGeo(VERTEX); i++) { + if(elInfo->getFillFlag().isSet(Mesh::FILL_COORDS)) { + for(j = 0; j < dow; j++) { + elInfo->getCoord(i)[j] = (*(*dofCoords_)[j])[dof[i][0]]; + } + } + if(elInfo->getFillFlag().isSet(Mesh::FILL_OPP_COORDS)) { + TEST_EXIT(elInfo->getFillFlag().isSet(Mesh::FILL_NEIGH)) + ("FILL_NEIGH not set\n"); + if(elInfo->getNeighbour(i)) { + const DegreeOfFreedom **neighDof = elInfo->getNeighbour(i)->getDOF(); + for(j = 0; j < dow; j++) { + elInfo->getOppCoord(i)[j] = + (*(*dofCoords_)[j])[neighDof[elInfo->getOppVertex(i)][0]]; + } + } + } + } + return elInfo; +} + +ElInfo *ParametricFirstOrder::removeParametricInfo(ElInfo *elInfo) +{ + elInfo->setParametric(false); + return elInfo; +} + +} diff --git a/AMDiS/src/Parametric.h b/AMDiS/src/Parametric.h new file mode 100644 index 0000000000000000000000000000000000000000..9b1356895775b49f98a2f6deb9d1b6bee716d4db --- /dev/null +++ b/AMDiS/src/Parametric.h @@ -0,0 +1,115 @@ +// ============================================================================ +// == == +// == AMDiS - Adaptive multidimensional simulations == +// == == +// ============================================================================ +// == == +// == crystal growth group == +// == == +// == Stiftung caesar == +// == Ludwig-Erhard-Allee 2 == +// == 53175 Bonn == +// == germany == +// == == +// ============================================================================ +// == == +// == http://www.caesar.de/cg/AMDiS == +// == == +// ============================================================================ + +/** \file Parametric.h */ + +#ifndef AMDIS_PARAMETRIC_H +#define AMDIS_PARAMETRIC_H + +#include "MemoryManager.h" + +namespace AMDiS { + + // ============================================================================ + // ===== forward declarations ================================================= + // ============================================================================ + + class ElInfo; + template<typename T> class DOFVector; + template<typename T> class WorldVector; + + // ============================================================================ + // ===== class Parametric ===================================================== + // ============================================================================ + + /** \brief + * Interface for parametric elements. A Parametric object can be given to + * a Mesh. + * Mesh traversal then adds parametric info automatically. + */ + class Parametric { + public: + virtual ~Parametric() {}; + + /** \brief + * Can return a pointer to a new parametric ElInfo or the original pointer + * given with elinfo. If the returned ElInfo is newly created, + * it must be deallocated in removeParametricInfo. + * If the element is not parametric, elinfo is returned with unchanged + * content: + * addParametricInfo(elinfo) == elinfo and + * *addParametricInfo(elInfo) == *elinfo. + * If parametric information are added to the returned elinfo + * ElInfo::parametric must be set true. + */ + virtual ElInfo *addParametricInfo(ElInfo *elInfo) = 0; + + /** \brief + * Must free memory which was allocated in addParametricInfo() for this + * ElInfo. Must set ElInfo::parametric to false if the result is no longer + * parametric. + * Must return the corresponding original ElInfo pointer given to + * addParametricInfo(). + * removeParametricInfo(addParametricInfo(elinfo)) == elinfo !!! + * It is not necessary to reset any data on the original ElInfo to their + * original values in any case. + * *(removeParametricInfo(addParametricInfo(elinfo))) != *elinfo is ok!!! + */ + virtual ElInfo *removeParametricInfo(ElInfo *elInfo) = 0; + }; + + // ============================================================================ + // ===== class ParametricFirstOrder =========================================== + // ============================================================================ + + /** \brief + * Implementation of linear parametric elements. + */ + class ParametricFirstOrder : public Parametric + { + public: + MEMORY_MANAGED(ParametricFirstOrder); + + /** \brief + * Constructor. \ref dofCoords are set to coords. + */ + ParametricFirstOrder(WorldVector<DOFVector<double>*> *coords) + : dofCoords_(coords) + {}; + + /** \brief + * Implementation of \ref Parametric::addParametricInfo(). + */ + ElInfo *addParametricInfo(ElInfo *elInfo); + + /** \brief + * Implementation of \ref Parametric::removeParametricInfo(). + */ + ElInfo *removeParametricInfo(ElInfo *elInfo); + + protected: + /** \brief + * Pointer to a DOFVector of world coordinates. + */ + WorldVector<DOFVector<double>*> *dofCoords_; + }; + +} + +#endif diff --git a/AMDiS/src/PartitionElementData.h b/AMDiS/src/PartitionElementData.h new file mode 100644 index 0000000000000000000000000000000000000000..ef537bb7f479f55c6419933924f9fa89ae5a9724 --- /dev/null +++ b/AMDiS/src/PartitionElementData.h @@ -0,0 +1,149 @@ +// ============================================================================ +// == == +// == AMDiS - Adaptive multidimensional simulations == +// == == +// ============================================================================ +// == == +// == crystal growth group == +// == == +// == Stiftung caesar == +// == Ludwig-Erhard-Allee 2 == +// == 53175 Bonn == +// == germany == +// == == +// ============================================================================ +// == == +// == http://www.caesar.de/cg/AMDiS == +// == == +// ============================================================================ + +/** \file PartitionElementData.h */ + +#ifndef AMDIS_EMPTYELEMENTDATA_H +#define AMDIS_EMPTYELEMENTDATA_H + +#include "Element.h" +#include "ElementData.h" +#include "FixVec.h" + +namespace AMDiS { + + const int PARTITION_ED = 6; + + enum PartitionStatus { + UNDEFINED = -1, + IN = 0, + OVERLAP = 1, + OUT = 2 + }; + + class PartitionElementData : public ElementData + { + public: + MEMORY_MANAGED(PartitionElementData); + + inline bool isOfType(int typeID) const { + if(typeID == PARTITION_ED) + return true; + return false; + }; + + class Creator : public CreatorInterface<ElementData> + { + public: + ElementData* create() { + return NEW PartitionElementData; + }; + }; + + PartitionElementData(ElementData *decorated = NULL) + : ElementData(decorated), + status_(UNDEFINED), + level_(0) + {}; + + bool refineElementData(Element* parent, + Element* child1, + Element* child2, + int elType) + { + ElementData::refineElementData(parent, child1, child2, elType); + PartitionElementData *child1Data = NEW PartitionElementData(child1->getElementData()); + PartitionElementData *child2Data = NEW PartitionElementData(child2->getElementData()); + child1Data->setPartitionStatus(status_); + child2Data->setPartitionStatus(status_); + child1Data->setLevel(level_ + 1); + child2Data->setLevel(level_ + 1); + child1->setElementData(child1Data); + child2->setElementData(child2Data); + return false; + }; + + ElementData *clone() const { + PartitionElementData *newObj = NEW PartitionElementData; + newObj->decorated_ = ElementData::clone(); + return newObj; + }; + + inline std::string getTypeName() const { return "PartitionElementData"; }; + + inline const int getTypeID() const { return PARTITION_ED; }; + + void serialize(std::ostream& out) + { + ElementData::serialize(out); + out.write(reinterpret_cast<const char*>(&status_), + sizeof(PartitionStatus)); + out.write(reinterpret_cast<const char*>(&level_), sizeof(int)); + }; + + void deserialize(std::istream& in) + { + ElementData::deserialize(in); + in.read(reinterpret_cast<char*>(&status_), + sizeof(PartitionStatus)); + in.read(reinterpret_cast<char*>(&level_), sizeof(int)); + }; + + inline void setPartitionStatus(PartitionStatus status) { + status_ = status; + }; + + inline PartitionStatus getPartitionStatus() { return status_; }; + + inline void setLevel(int level) { + level_ = level; + }; + + inline int getLevel() { return level_; }; + + void descend(Element *element) + { + if(!element->isLeaf()) { + Element *child0 = element->getChild(0); + Element *child1 = element->getChild(1); + + // get partition data + PartitionElementData *child0Data = dynamic_cast<PartitionElementData*> + (child0->getElementData(PARTITION_ED)); + PartitionElementData *child1Data = dynamic_cast<PartitionElementData*> + (child1->getElementData(PARTITION_ED)); + + TEST_EXIT(child0Data && child1Data)("no partition data\n"); + + child0Data->setPartitionStatus(this->getPartitionStatus()); + child1Data->setPartitionStatus(this->getPartitionStatus()); + + child0Data->descend(child0); + child1Data->descend(child1); + } + }; + + protected: + PartitionStatus status_; + int level_; + }; + +} + +#endif diff --git a/AMDiS/src/PeriodicBC.cc b/AMDiS/src/PeriodicBC.cc new file mode 100644 index 0000000000000000000000000000000000000000..96a14871895cdc59d3901a5c4491437b5282b133 --- /dev/null +++ b/AMDiS/src/PeriodicBC.cc @@ -0,0 +1,389 @@ +#include "PeriodicBC.h" +#include "BasisFunction.h" +#include "DOFVector.h" +#include "LeafData.h" +#include "DOFMatrix.h" +#include "Traverse.h" +#include "Boundary.h" +#include "VertexVector.h" + +namespace AMDiS { + + ::std::vector<PeriodicDOFMapping*> PeriodicDOFMapping::mappings_; + + PeriodicDOFMapping* + PeriodicDOFMapping::providePeriodicDOFMapping(const BasisFunction *basFcts) + { + ::std::vector<PeriodicDOFMapping*>::iterator it; + ::std::vector<PeriodicDOFMapping*>::iterator end = mappings_.end(); + for(it = mappings_.begin(); it != end; ++it) { + if((*it)->basFcts_ == basFcts) { + return *it; + } + } + PeriodicDOFMapping *newMapping = NEW PeriodicDOFMapping(basFcts); + mappings_.push_back(newMapping); + return newMapping; + } + + + PeriodicDOFMapping::PeriodicDOFMapping(const BasisFunction *basFcts) + : basFcts_(basFcts) + { + FUNCNAME("PeriodicDOFMapping::PeriodicDOFMapping()"); + TEST_EXIT(basFcts_->getDim() > 1)("dim == 1\n"); + int i, num = basFcts_->getNumber(); + DimVec<double> *lambda; + for(i = 0; i < num; i++) { + lambda = basFcts_->getCoords(i); + indexOfCoords_[*lambda] = i; + } + } + + PeriodicDOFMapping::~PeriodicDOFMapping() + { + ::std::map<DimVec<int>, DegreeOfFreedom*, DimVecLess<int> >::iterator it; + for(it = dofPermutation_.begin(); it != dofPermutation_.end(); ++it) { + if(it->second) { + FREE_MEMORY(it->second, DegreeOfFreedom, basFcts_->getNumber()); + } + } + } + + const DegreeOfFreedom + *PeriodicDOFMapping::getDOFPermutation(const DimVec<int> &vertexPermutation) + { + FUNCNAME("PeriodicDOFMapping::getDOFPermutation()"); + + if(dofPermutation_[vertexPermutation] == NULL) { + //MSG("new dof permutation needed\n"); + + int i, j; + int dim = basFcts_->getDim(); + int num = basFcts_->getNumber(); + + int sum = 0; + for(i = 0; i < dim + 1; i++) { + sum += i - vertexPermutation[i]; + TEST_EXIT(vertexPermutation[i] < dim + 1) + ("invalid vertexPermuation\n"); + } + TEST_EXIT(sum == 0)("invalid vertexPermutation\n"); + + // create dof permutation + DimVec<double> *lambda; + DimVec<double> newLambda(dim, NO_INIT); + + DegreeOfFreedom *mapping = GET_MEMORY(DegreeOfFreedom, num); + + for(i = 0; i < num; i++) { + lambda = basFcts_->getCoords(i); + for(j = 0; j < dim + 1; j++) { + newLambda[vertexPermutation[j]] = (*lambda)[j]; + } + mapping[i] = indexOfCoords_[newLambda]; + } + + dofPermutation_[vertexPermutation] = mapping; + + // MSG("vertex permutation: "); + // for(i = 0; i < dim+1; i++) { + // MSG("%d ", vertexPermutation[i]); + // } + // MSG("\n"); + + // MSG("dof permutation: "); + // for(i = 0; i < num; i++) { + // MSG("%d ", dofPermutation_[vertexPermutation][i]); + // } + // MSG("\n"); + // WAIT; + } + + return dofPermutation_[vertexPermutation]; + } + + + PeriodicBC::PeriodicBC(BoundaryType type, FiniteElemSpace *rowFESpace_) + : BoundaryCondition(type, rowFESpace_, NULL), + masterMatrix_(NULL) + { + if(rowFESpace->getMesh()->getDim() > 1) { + periodicDOFMapping_ = + PeriodicDOFMapping::providePeriodicDOFMapping(rowFESpace_->getBasisFcts()); + } else { + periodicDOFMapping_ = NULL; + } + } + + PeriodicBC::~PeriodicBC() + {} + + void PeriodicBC::initMatrix(DOFMatrix* matrix) + { + FUNCNAME("PeriodicBC::initMatrix()"); + + // MSG("begin initMatrix...\n"); + + if(!masterMatrix_) { + masterMatrix_ = matrix; + + Mesh *mesh = matrix->getRowFESpace()->getMesh(); + + associated_ = mesh->getPeriodicAssociations()[boundaryType]; + + TEST_EXIT(associated_)("no associations for periodic boundary condition %d\n", + boundaryType); + + const BasisFunction *basFcts = rowFESpace->getBasisFcts(); + int num = basFcts->getNumber(); + + neighIndices_ = GET_MEMORY(DegreeOfFreedom, num); + } + + //MSG("end initMatrix...\n"); + } + + void PeriodicBC::fillBoundaryCondition(DOFMatrix *matrix, + ElInfo *elInfo, + const DegreeOfFreedom *dofIndices, + const BoundaryType *localBound, + int nBasFcts) + { + if(matrix == masterMatrix_) { + + int dim = rowFESpace->getMesh()->getDim(); + if(dim > 1) { + int i, j; + DOFAdmin *admin = rowFESpace->getAdmin(); + + FixVec<int, WORLD> elFace(dim, NO_INIT); + FixVec<int, WORLD> neighFace(dim, NO_INIT); + DimVec<int> vertexPermutation(dim, NO_INIT); + + const BasisFunction *basFcts = rowFESpace->getBasisFcts(); + int num = basFcts->getNumber(); + + Element *element = elInfo->getElement(); + + DimVec<DegreeOfFreedom> periodicDOFs(dim-1, NO_INIT); + + int vertex, index, side; + + GeoIndex sideGeoIndex = INDEX_OF_DIM(dim-1, dim); + + for(side = 0; side < dim + 1; side++) { + + if(elInfo->getBoundary(sideGeoIndex, side) == boundaryType) { + + for(vertex = 0; vertex < dim; vertex++) { + index = element->getVertexOfPosition(sideGeoIndex, + side, + vertex); + periodicDOFs[vertex] = (*associated_)[dofIndices[index]]; + } + + Element *neigh = elInfo->getNeighbour(side); + + basFcts->getLocalIndices(neigh, admin, neighIndices_); + + int oppVertex = 0; + for(i = 0; i < dim + 1; i++) { + // get vertex permutation + if(i == side) { + vertexPermutation[i] = 0; + } else { + DegreeOfFreedom periodicDOF = + periodicDOFs[element->getPositionOfVertex(side, i)]; + + for(j = 0; j < dim + 1; j++) { + if(neigh->getDOF(j, 0) == periodicDOF) break; + } + vertexPermutation[i] = j; + } + oppVertex += i - vertexPermutation[i]; + } + vertexPermutation[side] = oppVertex; + + // get DOF permutation + const DegreeOfFreedom *dofPermutation = + periodicDOFMapping_->getDOFPermutation(vertexPermutation); + + // set associated dofs + for(i = 0; i < num; i++) { + if((*(basFcts->getCoords(i)))[side] == 0) { + (*associated_)[dofIndices[i]] = neighIndices_[dofPermutation[i]]; + } + } + } + } + } + } + } + + void PeriodicBC::exitMatrix(DOFMatrix* matrix) + { + FUNCNAME("PeriodicBC::exitMatrix()"); + + TEST_EXIT(matrix)("no matrix\n"); + + if(matrix == masterMatrix_) { + const BasisFunction *basFcts = rowFESpace->getBasisFcts(); + int num = basFcts->getNumber(); + FREE_MEMORY(neighIndices_, DegreeOfFreedom, num); + masterMatrix_ = NULL; + } + // ---------- different assemblage style -------- + + // DOFMatrix::Iterator matrixRow(matrix, USED_DOFS); + // for(matrixRow.reset(); !matrixRow.end(); ++matrixRow) { + // row = matrixRow.getDOFIndex(); + + // rowSize = matrixRow->size(); + // newRow = ((*associated_)[row] == -1) ? row : (*associated_)[row]; + + // if(row < newRow) { + // for(i = 0; i < rowSize; i++) { + // col = (*matrixRow)[i].col; + // if(col == DOFMatrix::NO_MORE_ENTRIES) break; + // if(col == DOFMatrix::UNUSED_ENTRY) continue; + // newCol = ((*associated_)[col] == -1) ? col : (*associated_)[col]; + // if(col < newCol) { + // entry = (*matrixRow)[i].entry; + // (*matrixRow)[i].col = DOFMatrix::UNUSED_ENTRY; + // (*matrixRow)[i].entry = 0.0; + // matrix->addSparseDOFEntry(1.0, row, newCol, entry, true); + // } + // } + // rowSize = matrixRow->size(); + // for(i = 0; i < rowSize; i++) { + // col = (*matrixRow)[i].col; + // if(col == DOFMatrix::NO_MORE_ENTRIES) break; + // if(col == DOFMatrix::UNUSED_ENTRY) continue; + // entry = (*matrixRow)[i].entry; + // matrix->addSparseDOFEntry(1.0, newRow, col, entry, true); + // } + // matrixRow->resize(2); + // (*matrixRow)[0].col = row; + // (*matrixRow)[0].entry = 100.0;1.0; + // (*matrixRow)[1].col = newRow; + // (*matrixRow)[1].entry = -100.0;-1.0; + // } + // } + + + // --- method 2 --- + + // for(matrixRow.reset(); !matrixRow.end(); ++matrixRow) { + // row = matrixRow.getDOFIndex(); + // newRow = ((*associated_)[row] == -1) ? row : (*associated_)[row]; + // if(row < newRow) { + // // remember old row matrix[row] + // ::std::vector<MatEntry> oldMatrixRow = *matrixRow; + // // add new row to old row + // ::std::vector<MatEntry> &newMatrixRow = matrix->getRow(newRow); + // rowSize = newMatrixRow.size(); + // for(i = 0; i < rowSize; i++) { + // col = newMatrixRow[i].col; + // if(col == DOFMatrix::NO_MORE_ENTRIES) break; + // if(col == DOFMatrix::UNUSED_ENTRY) continue; + // newCol = ((*associated_)[col] == -1) ? col : (*associated_)[col]; + // entry = newMatrixRow[i].entry; + // matrix->addSparseDOFEntry(1.0, row, newCol, entry, true); + // } + // // add old row to new row + // rowSize = oldMatrixRow.size(); + // for(i = 0; i < rowSize; i++) { + // col = oldMatrixRow[i].col; + // if(col == DOFMatrix::NO_MORE_ENTRIES) break; + // if(col == DOFMatrix::UNUSED_ENTRY) continue; + // newCol = ((*associated_)[col] == -1) ? col : (*associated_)[col]; + // entry = oldMatrixRow[i].entry; + // matrix->addSparseDOFEntry(1.0, newRow, newCol, entry, true); + // } + // } + // } + + + // DOFVector<DegreeOfFreedom>::Iterator rowIt(associated_, USED_DOFS); + // DOFVector<DegreeOfFreedom>::Iterator colIt(associated_, USED_DOFS); + + + // Mesh *mesh = matrix->getRowFESpace()->getMesh(); + + ::std::vector< ::std::vector<MatEntry> >::iterator rowIt; + ::std::vector< ::std::vector<MatEntry> >::iterator rowEnd = matrix->end(); + int colIndex, rowSize; + int row, col, newRow, newCol; + double entry, *newEntryPtr; + + for(rowIt = matrix->begin(), row = 0; rowIt != rowEnd; ++rowIt, ++row) { + rowSize = static_cast<int>(rowIt->size()); + newRow = (*associated_)[row]; + for(colIndex = 0; colIndex < rowSize; colIndex++) { + col = (*rowIt)[colIndex].col; + if(col == DOFMatrix::UNUSED_ENTRY) continue; + if(col == DOFMatrix::NO_MORE_ENTRIES) break; + newCol = (*associated_)[col]; + + newEntryPtr = matrix->hasSparseDOFEntry(newRow, newCol); + + if((row < newRow) || + ((row == newRow) && (col < newCol)) || + !newEntryPtr) + { + if(!newEntryPtr) { + entry = 0.5 * (*rowIt)[colIndex].entry; + (*rowIt)[colIndex].entry = entry; + matrix->addSparseDOFEntry(1.0, newRow, newCol, entry, false); + } else { + entry = 0.5 * ((*rowIt)[colIndex].entry + *newEntryPtr); + (*rowIt)[colIndex].entry = *newEntryPtr = entry; + } + } + } + } + + //MSG("end exitMatrix...\n"); + } + + void PeriodicBC::exitVector(DOFVectorBase<double>* vector) + { + FUNCNAME("PeriodicBC::exitVector()"); + + double entry; + + DegreeOfFreedom dof; + DegreeOfFreedom newDOF; + + DOFIterator<double> vecIt(vector, USED_DOFS); + + Mesh *mesh = vector->getFESpace()->getMesh(); + VertexVector *associated_ = mesh->getPeriodicAssociations()[boundaryType]; + + for(vecIt.reset(); !vecIt.end(); ++vecIt) { + dof = vecIt.getDOFIndex(); + + newDOF = (*associated_)[dof]; + + if(dof < newDOF) { + // ---------- different assemblage style -------- + // (*vector)[newDOF] += (*vector)[dof]; + // (*vector)[dof] = 0.0; + + + // --- method 2 ---- + // //entry = (*vector)[dof]; + // (*vector)[dof] += (*vector)[newDOF]; + // (*vector)[newDOF] = (*vector)[dof]; + + entry = ((*vector)[dof] + (*vector)[newDOF]) * 0.5; + (*vector)[dof] = entry; + (*vector)[newDOF] = entry; + } + } + + //MSG("end exitVector...\n"); + } + +} diff --git a/AMDiS/src/PeriodicBC.h b/AMDiS/src/PeriodicBC.h new file mode 100644 index 0000000000000000000000000000000000000000..3783582bf304b8bc2b666697f771337783c18502 --- /dev/null +++ b/AMDiS/src/PeriodicBC.h @@ -0,0 +1,132 @@ +// ============================================================================ +// == == +// == AMDiS - Adaptive multidimensional simulations == +// == == +// ============================================================================ +// == == +// == crystal growth group == +// == == +// == Stiftung caesar == +// == Ludwig-Erhard-Allee 2 == +// == 53175 Bonn == +// == germany == +// == == +// ============================================================================ +// == == +// == http://www.caesar.de/cg/AMDiS == +// == == +// ============================================================================ + +/** \file PeriodicBC.h */ + +#ifndef AMDIS_PERIODICBC_H +#define AMDIS_PERIODICBC_H + +#include "BoundaryCondition.h" +#include "MemoryManager.h" +#include "FixVec.h" +#include <map> +#include <vector> + +namespace AMDiS { + + class ElInfo; + class DOFMatrix; + class BasisFunction; + class VertexVector; + class LeafDataPeriodic; + + template<typename T> + class DimVecLess + { + public: + bool operator()(const DimVec<T> &v1, const DimVec<T> &v2) { + int i, size = v1.getSize(); + for(i = 0; i < size; i++) { + if(v1[i] < v2[i]) return true; + if(v1[i] > v2[i]) return false; + } + return false; + }; + }; + + class PeriodicDOFMapping + { + public: + MEMORY_MANAGED(PeriodicDOFMapping); + + PeriodicDOFMapping(const BasisFunction *basFcts); + + ~PeriodicDOFMapping(); + + public: + static PeriodicDOFMapping* providePeriodicDOFMapping(const BasisFunction *basFcts); + + const DegreeOfFreedom *getDOFPermutation(const DimVec<int> &vertexPermutation); + + protected: + const BasisFunction *basFcts_; + ::std::map<DimVec<int>, DegreeOfFreedom*, DimVecLess<int> > dofPermutation_; + ::std::map<DimVec<double>, int, DimVecLess<double> > indexOfCoords_; + + static ::std::vector<PeriodicDOFMapping*> mappings_; + }; + + // ============================================================================ + // ===== class PeriodicBC ===================================================== + // ============================================================================ + + /** + * \ingroup Assembler + * + * \brief + * Sub class of BoundaryCondition. Implements Periodic boundary conditions. + */ + class PeriodicBC : public BoundaryCondition + { + public: + MEMORY_MANAGED(PeriodicBC); + + /** \brief + * Constructor. + */ + PeriodicBC(BoundaryType type, FiniteElemSpace *rowFESpace_); + + ~PeriodicBC(); + + void initMatrix(DOFMatrix* matrix); + + void fillBoundaryCondition(DOFMatrix *matrix, + ElInfo *elInfo, + const DegreeOfFreedom *dofIndices, + const BoundaryType *localBound, + int nBasFcts); + + void exitMatrix(DOFMatrix* matrix); + + void exitVector(DOFVectorBase<double>* vector); + + // DOFVectorDOF *getAssociatedDOFs() { return associated_; }; + + // void updateAssociatedDOFs(); + + // void clearPeriodicElementData(); + + // void refinePeriodicData(LeafDataPeriodic *pd, Element *parent, int newDOF, + // int elType); + + // inline LeafDataPeriodic *getPeriodicElementData(int index) { + // return periodicElementData_[index]; + // }; + + protected: + VertexVector *associated_; + PeriodicDOFMapping *periodicDOFMapping_; + DegreeOfFreedom *neighIndices_; + // ::std::map<int, LeafDataPeriodic*> periodicElementData_; + DOFMatrix *masterMatrix_; + }; + +} + +#endif diff --git a/AMDiS/src/PeriodicConnection.h b/AMDiS/src/PeriodicConnection.h new file mode 100644 index 0000000000000000000000000000000000000000..9e37fc3d6f7b04eb661ea77ec375254e57ab4d51 --- /dev/null +++ b/AMDiS/src/PeriodicConnection.h @@ -0,0 +1,99 @@ +#ifndef AMDIS_PERIODICCONNECTION_H +#define AMDIS_PERIODICCONNECTION_H + +#include "FixVec.h" +#include "MemoryManager.h" + +namespace AMDiS { + + class Element; + + class PeriodicConnection + { + public: + PeriodicConnection(int dim; + Element *el0, + Element *el1, + DimVec<int> &vertices0, + DimVec<int> &vertices1) + { + FUNCNAME("PeriodicConnection::PeriodicConnection()"); + TEST_EXIT(el0)("element0 not set\n"); + TEST_EXIT(el1)("element1 not set\n"); + TEST_EXIT(el0->getMesh()->getDim() == dim)("invalid dim of el0\n"); + TEST_EXIT(el1->getMesh()->getDim() == dim)("invalid dim of el1\n"); + TEST_EXIT(vertices0.getSize() == dim)("invalid size of vertices0\n"); + TEST_EXIT(vertices1.getSize() == dim)("invalid size of vertices1\n"); + int i; + for(i = 0; i < dim + 1; i++) { + TEST_EXIT(vertices0[i] < dim + 1 && vertices0[i] >= 0) + ("invalid value in vertices0\n"); + TEST_EXIT(vertices1[i] < dim + 1 && vertices1[i] >= 0) + ("invalid value in vertices1\n"); + } + + el_[0] = el0; + el_[1] = el1; + vertices_[0] = NEW DimVec<int>(vertices0); + vertices_[1] = NEW DimVec<int>(vertices1); + child_[0] = child_[1] = NULL; + }; + + ~PeriodicConnection() { + DELETE vertices_[0]; + DELETE vertices_[1]; + }; + + Element *getElement(int index) { + FUNCNAME("PeriodicConnection::getElement()"); + TEST_EXIT(index >= 0 && index <= 2)("invalid index\n"); + return el_[index]; + }; + + const DimVec<int>& getVertices(int index) { + FUNCNAME("PeriodicConnection::getVertices()"); + TEST_EXIT(index >= 0 && index <= 2)("invalid index\n"); + return *(vertices_[index]); + }; + + bool removeElement(int index) { + FUNCNAME("PeriodicConnection::removeElement()"); + TEST_EXIT(index >= 0 && index <= 2)("invalid index\n"); + TEST_EXIT(el_[index])("element already removed\n"); + el_[index] = NULL; + return (el_[abs(index-1)] == NULL); + }; + + bool refineElement(int index, + PeriodicConnection **child0, + PeriodicConnection **child1) + { + FUNCNAME("PeriodicConnection::refineElement()"); + + if(child_[0] || child_[1]) { + TEST_EXIT(child_[0] && child_[1]) + ("only one child\n"); + + TEST_EXIT(el_[abs(index-1)] == NULL) + ("connection already refined but other element != NULL\n"); + + *child0 = child_[0]; + *child1 = child_[1]; + + return true; + } + + + + return false; + }; + + protected: + Element *el_[2]; + DimVec<int> *vertices_[2]; + PeriodicConnection *child_[2]; + }; + +} + +#endif diff --git a/AMDiS/src/PeriodicInfo.h b/AMDiS/src/PeriodicInfo.h new file mode 100644 index 0000000000000000000000000000000000000000..d0cf030e92f440a5d97adef279dbc9c6747a55f8 --- /dev/null +++ b/AMDiS/src/PeriodicInfo.h @@ -0,0 +1,45 @@ +// ============================================================================ +// == == +// == AMDiS - Adaptive multidimensional simulations == +// == == +// ============================================================================ +// == == +// == crystal growth group == +// == == +// == Stiftung caesar == +// == Ludwig-Erhard-Allee 2 == +// == 53175 Bonn == +// == germany == +// == == +// ============================================================================ +// == == +// == http://www.caesar.de/cg/AMDiS == +// == == +// ============================================================================ + +/** \file PeriodicInfo.h */ + +#ifndef AMDIS_PERIODICINFO_H +#define AMDIS_PERIODICINFO_H + +#include <map> + +namespace AMDiS { + + class PeriodicInfo + { + public: + int mode; + + int type; + + int outputIndex; + + int neighIndex; + + ::std::map<int, int> vertexMap; + }; + +} + +#endif diff --git a/AMDiS/src/PeriodicMap.h b/AMDiS/src/PeriodicMap.h new file mode 100644 index 0000000000000000000000000000000000000000..dade895cc93fa0e8572ea78cb9e81e14ebc4c02e --- /dev/null +++ b/AMDiS/src/PeriodicMap.h @@ -0,0 +1,85 @@ +// ============================================================================ +// == == +// == AMDiS - Adaptive multidimensional simulations == +// == == +// ============================================================================ +// == == +// == crystal growth group == +// == == +// == Stiftung caesar == +// == Ludwig-Erhard-Allee 2 == +// == 53175 Bonn == +// == germany == +// == == +// ============================================================================ +// == == +// == http://www.caesar.de/cg/AMDiS == +// == == +// ============================================================================ + +/** \file PeriodicMap.h */ + +#ifndef AMDIS_PERIODICMAP_H +#define AMDIS_PERIODICMAP_H + +#include "Global.h" + +#include <map> + +namespace AMDiS { + + class PeriodicMap + { + public: + void setEntry(DegreeOfFreedom key, DegreeOfFreedom entry) { + // no trivial entries! + if(key == entry) + return; + + // if a key equal to entry exists ... + if(getEntry(entry) >= 0) { + if(getEntry(entry) == key) { + return; + } + // ... let it be equal entries + setEntry(key, getEntry(entry)); + return; + } + + // replace entries equal to key + ::std::map<DegreeOfFreedom, DegreeOfFreedom>::iterator it; + for(it = periodicMap.begin(); it != periodicMap.end(); ++it) { + if(it->second == key) { + it->second = entry; + } + } + + // if key exists already + if(getEntry(key) >= 0) { + // insert new entry with old entry as key + setEntry(getEntry(key), entry); + } + + // set entry + periodicMap[key] = entry; + }; + + DegreeOfFreedom getEntry(DegreeOfFreedom key) { + ::std::map<DegreeOfFreedom, DegreeOfFreedom>::iterator it; + it = periodicMap.find(key); + if(it != periodicMap.end()) { + return it->second; + } else { + return -1; + } + }; + + + + protected: + ::std::map<DegreeOfFreedom, DegreeOfFreedom> periodicMap; + }; + +} + +#endif diff --git a/AMDiS/src/Preconditioner.h b/AMDiS/src/Preconditioner.h new file mode 100644 index 0000000000000000000000000000000000000000..5f8d2ca96bc291aa6869846924b9df439e310bc5 --- /dev/null +++ b/AMDiS/src/Preconditioner.h @@ -0,0 +1,297 @@ +// ============================================================================ +// == == +// == AMDiS - Adaptive multidimensional simulations == +// == == +// ============================================================================ +// == == +// == crystal growth group == +// == == +// == Stiftung caesar == +// == Ludwig-Erhard-Allee 2 == +// == 53175 Bonn == +// == germany == +// == == +// ============================================================================ +// == == +// == http://www.caesar.de/cg/AMDiS == +// == == +// ============================================================================ + +/** \file Preconditioner.h */ + +#ifndef AMDIS_PRECONDITIONER_H +#define AMDIS_PRECONDITIONER_H + +#include <vector> + +#include "DOFVector.h" +#include "MatrixVector.h" +#include "SystemVector.h" +#include <string> + +namespace AMDiS { + + // ============================================================================ + // ===== class Preconditioner ================================================= + // ============================================================================ + + /** + * \ingroup Solver + * + * \brief + * Pure virtual base class for all preconditioners. + * A Preconditioner is used by an OEMSolver before solving the linear system to + * reduce the number of needed iterations. + */ + template<typename Vector> + class Preconditioner + { + public: + /** \brief + * Destructor. + */ + virtual ~Preconditioner() {}; + + /** \brief + * Initialisation of the preconditioner + */ + virtual void init() = 0; + + /** \brief + * Precondition function which should be implemented. + */ + virtual void precon(Vector *x) = 0; + + /** \brief + * Frees needed memory. + */ + virtual void exit() = 0; + }; + + // ============================================================================ + // ===== class PreconditionerScal ============================================= + // ============================================================================ + + /** + * \ingroup Solver + * + * Base class for DOFVector preconditioners. + */ + class PreconditionerScal : public Preconditioner<DOFVector<double> > + { + public: + /** \brife + * Constructor. + */ + PreconditionerScal(int numSystems = 1, int r = 0) + : matrix(numSystems), + bound(NULL), + row(r) + { + TEST_EXIT(r < numSystems)("r must be smaller than numSystems\n"); + matrix.set(NULL); + }; + + /** \brief + * Sets \ref matrix. + */ + inline void setMatrix(DOFMatrix **m, int system = 0) { + TEST_EXIT(system < matrix.getSize())("invalid system number\n"); + matrix[system] = m; + }; + + /** \brief + * Sets \ref bound. + */ + inline void setBound(DOFVector<BoundaryType> *b) { bound = b; }; + + protected: + /** \brief + * Matrix used for preconditioning. + */ + Vector<DOFMatrix**> matrix; + + /** \brief + * Boundary vector + */ + DOFVector<BoundaryType> *bound; + + /** \brief + * Row of the component in vector valued problems. + */ + int row; + }; + + + + // ============================================================================ + // ===== class PreconditionerScalStd ========================================== + // ============================================================================ + + /** + * \ingroup Solver + * + * Base class for DOFVector preconditioners. + */ + class PreconditionerScalStd : public Preconditioner< ::std::vector<double> > + { + public: + /** \brife + * Constructor. + */ + PreconditionerScalStd() + {}; + + /** \brief + * Sets \ref matrix. + */ + inline void setMatrix(::std::vector< ::std::vector<MatEntry> > *m) { + matrix = m; + }; + + protected: + /** \brief + * Matrix used for preconditioning. + */ + + ::std::vector< ::std::vector<MatEntry> > *matrix; + }; + + + // ============================================================================ + // ===== PreconditionerScalCreator ============================================ + // ============================================================================ + + /** + * \ingroup Solver + * + * \brief + * Interface for creators of concrete scalar preconditioners. + */ + class PreconditionerScalCreator + : public CreatorInterface<PreconditionerScal> + { + public: + PreconditionerScalCreator() + : size(1), row(0) + {}; + + virtual ~PreconditionerScalCreator() {}; + + /** \brief + * Sets \ref problem + */ + void setSizeAndRow(int size_, int row_) { + size = size_; + row = row_; + }; + + /** \brief + * Sets \ref problem + */ + void setName(::std::string name) { + name_ = name; + }; + + protected: + int size; + int row; + + ::std::string name_; + }; + + + + // ============================================================================ + // ===== class PreconditionerVec ============================================== + // ============================================================================ + + /** + * \ingroup Solver + * + * \brief + * Base class for vector valued preconditioners. + */ + class PreconditionerVec : public Preconditioner<SystemVector> + { + public: + MEMORY_MANAGED(PreconditionerVec); + + /** \brief + * Constructor. + */ + PreconditionerVec(int numSystems) + : scalPrecons(numSystems) + { + scalPrecons.set(NULL); + }; + + /** \brief + * Destructor. + */ + virtual ~PreconditionerVec() {}; + + /** \brief + * Initialisation of the preconditioner + */ + virtual void init() { + int i; +#ifdef _OPENMP +#pragma omp parallel for schedule(static, 1) default(shared) private(i) +#endif + for (i = 0; i < scalPrecons.getSize(); i++) { + scalPrecons[i]->init(); + } + }; + + /** \brief + * Preconditioning method + */ + virtual void precon(SystemVector *x) { + int i; +#ifdef _OPENMP +#pragma omp parallel for schedule(static, 1) default(shared) private(i) +#endif + for (i = 0; i < scalPrecons.getSize(); i++) { + scalPrecons[i]->precon(x->getDOFVector(i)); + } + }; + + /** \brief + * Frees needed memory. + */ + virtual void exit() { + int i; +#ifdef _OPENMP +#pragma omp parallel for schedule(static, 1) default(shared) private(i) +#endif + for (i = 0; i < scalPrecons.getSize(); i++) { + scalPrecons[i]->exit(); + } + }; + + /** \brief + * Sets scalar preconditioner for system i. + */ + inline void setScalarPrecon(int i, PreconditionerScal *p) { + scalPrecons[i] = p; + }; + + /** \brief + * Gets i-th scalar preconditioner. + */ + inline PreconditionerScal *getScalarPrecon(int i) { + return scalPrecons[i]; + }; + + protected: + /** \brief + * Scalar Preconditioners. + */ + Vector<PreconditionerScal*> scalPrecons; + }; + +} + +#endif // AMDIS_PRECONDITIONER_H + diff --git a/AMDiS/src/ProblemInstat.cc b/AMDiS/src/ProblemInstat.cc new file mode 100644 index 0000000000000000000000000000000000000000..5a5c43611843e9cd74363cf4bd77f06e92062e42 --- /dev/null +++ b/AMDiS/src/ProblemInstat.cc @@ -0,0 +1,236 @@ +#include "ProblemInstat.h" +#include "FileWriter.h" +#include "AdaptStationary.h" +#include "AdaptInstationary.h" +#include "Estimator.h" +#include "ProblemScal.h" +#include "StandardProblemIteration.h" + +namespace AMDiS { + + // === ProblemInstat ================================= + + ProblemInstat::~ProblemInstat() + { + } + + void ProblemInstat::initialize(Flag initFlag, + ProblemInstat *adoptProblem/* = NULL*/, + Flag adoptFlag /* = INIT_NOTHING*/) + { + FUNCNAME("ProblemInstat::initialize()"); + } + + void ProblemInstat::solveInitialProblem(AdaptInfo *adaptInfo) + { + AdaptStationary initialAdapt((name + "->initial->adapt").c_str(), + NEW StandardProblemIteration(initialProblem), + adaptInfo); + + initialAdapt.adapt(); + } + + // void ProblemInstatVec::solveInitialProblem(AdaptInfo *adaptInfo) + // { + // } + + void ProblemInstatScal::transferInitialSolution(AdaptInfo *adaptInfo) + { + TEST_EXIT(adaptInfo->getTime() == + adaptInfo->getStartTime()) + ("after initial solution: time != start time\n"); + problemStat->writeFiles(adaptInfo, true); + } + + void ProblemInstatVec::transferInitialSolution(AdaptInfo *adaptInfo) + { + TEST_EXIT(adaptInfo->getTime() == + adaptInfo->getStartTime()) + ("after initial solution: time != start time\n"); + problemStat->writeFiles(adaptInfo, true); + } + + + ProblemInstatScal::ProblemInstatScal(char* name_, + ProblemScal *prob, + ProblemStatBase *initialProb) + : ProblemInstat(name_, initialProb), + problemStat(prob),oldSolution(NULL) + { + // create instationary adapt + // int maxSpaceIter = problemStat->getAdapt()->getAdaptInfo()->getMaxSpaceIteration(); + + // adaptInstat = NEW AdaptInstationary((name+"->adapt").c_str(), + // problemStat, + // this, + // problemStat->getAdaptInfo(), + // maxSpaceIter); + + // create oldSolution + /* oldSolution = NEW DOFVector<double>(problemStat->getFESpace(), name + "->uOld"); + oldSolution->refineInterpol(true); + oldSolution->setCoarsenOperation(COARSE_INTERPOL); + if(problemStat->getEstimator()) { + dynamic_cast<Estimator*>(problemStat->getEstimator()) + ->addUhOldToSystem(0, oldSolution); + } */ + }; + + + ProblemInstatScal::~ProblemInstatScal() + { + DELETE oldSolution; + } + + void ProblemInstatScal::initialize(Flag initFlag, + ProblemInstat *adoptProblem/* = NULL*/, + Flag adoptFlag /* = INIT_NOTHING*/) + { + FUNCNAME("ProblemInstat::initialize()"); + + ProblemInstat::initialize(initFlag, adoptProblem, adoptFlag); + + // === create vector for old solution === + if (oldSolution) { + WARNING("oldSolution already created\n"); + } else { + if (initFlag.isSet(INIT_UH_OLD)) { + createUhOld(); + } + if (adoptProblem && adoptFlag.isSet(INIT_UH_OLD)) { + ProblemInstatScal* _adoptProblem = dynamic_cast<ProblemInstatScal*>(adoptProblem); + TEST_EXIT(_adoptProblem)("can't adopt oldSolution from problem which is not instationary and scalar"); + TEST_EXIT(!oldSolution)("oldSolution already created"); + oldSolution = _adoptProblem->getOldSolution(); + } + } + + if (!oldSolution) + WARNING("no oldSolution created\n"); + } + + void ProblemInstatScal::createUhOld() { + if (oldSolution) { + WARNING("oldSolution already created\n"); + } else { + // create oldSolution + oldSolution = NEW DOFVector<double>(problemStat->getFESpace(), name + "->uOld"); + oldSolution->refineInterpol(true); + oldSolution->setCoarsenOperation(COARSE_INTERPOL); + if(problemStat->getEstimator()) { + dynamic_cast<Estimator*>(problemStat->getEstimator()) + ->addUhOldToSystem(0, oldSolution); + } + } + } + + + void ProblemInstatScal::closeTimestep(AdaptInfo *adaptInfo) + { + bool force = (adaptInfo->getTime() >= adaptInfo->getEndTime()); + problemStat->writeFiles(adaptInfo, force); + } + + void ProblemInstatVec::closeTimestep(AdaptInfo *adaptInfo) + { + bool force = (adaptInfo->getTime() >= adaptInfo->getEndTime()); + problemStat->writeFiles(adaptInfo, force); + } + + ProblemInstatVec::ProblemInstatVec(char* name_, + ProblemVec *prob, + ProblemStatBase *initialProb) + : ProblemInstat(name_, initialProb), + problemStat(prob),oldSolution(NULL) + { + // create instationary adapt + // int maxSpaceIter = problemStat->getAdapt()->getAdaptInfo()->getMaxSpaceIteration(); + + // adaptInstat = NEW AdaptInstationary((name+"->adapt").c_str(), + // problemStat, + // this, + // problemStat->getAdaptInfo(), + // maxSpaceIter); + + + + // create oldSolution + /* oldSolution = NEW SystemVector(problemStat->getFESpace(), size); + int i; + for(i = 0; i < size; i++) { + oldSolution->setDOFVector(i, NEW DOFVector<double>(problemStat->getFESpace(), + name + "->uOld")); + oldSolution->getDOFVector(i)->refineInterpol(true); + oldSolution->getDOFVector(i)->setCoarsenOperation(COARSE_INTERPOL); + + if(problemStat->getEstimator()) { + dynamic_cast<EstimatorVec*>(problemStat->getEstimator()) + ->getScalarEstimator(i) + ->addUhOldToSystem(i, oldSolution->getDOFVector(i)); + } + } */ + }; + + ProblemInstatVec::~ProblemInstatVec() + { + DELETE oldSolution; + } + + void ProblemInstatVec::initialize(Flag initFlag, + ProblemInstat *adoptProblem/* = NULL*/, + Flag adoptFlag /* = INIT_NOTHING*/) + { + FUNCNAME("ProblemInstatVec::initialize()"); + + ProblemInstat::initialize(initFlag,adoptProblem,adoptFlag); + + // === create vector for old solution === + if(oldSolution) { + WARNING("oldSolution already created\n"); + } else { + if(initFlag.isSet(INIT_UH_OLD)) { + createUhOld(); + } + if(adoptProblem && adoptFlag.isSet(INIT_UH_OLD)) { + ProblemInstatVec* _adoptProblem=dynamic_cast<ProblemInstatVec*>(adoptProblem); + TEST_EXIT(_adoptProblem)("can't adopt oldSolution from problem which is not instationary and vectorial"); + TEST_EXIT(!oldSolution)("oldSolution already created"); + oldSolution = _adoptProblem->getOldSolution(); + } + } + + if(!oldSolution) WARNING("no oldSolution created\n"); + + } + + void ProblemInstatVec::createUhOld() { + if (oldSolution) WARNING("oldSolution already created\n"); + else { + int size = problemStat->getNumComponents(); + // create oldSolution + oldSolution = NEW SystemVector("old solution", + problemStat->getFESpaces(), + size); + int i; + for(i = 0; i < size; i++) { + oldSolution->setDOFVector(i, NEW DOFVector<double>(problemStat->getFESpace(i), + name + "->uOld")); + oldSolution->getDOFVector(i)->refineInterpol(true); + oldSolution->getDOFVector(i)->setCoarsenOperation(COARSE_INTERPOL); + + if(problemStat->getEstimator(i)) { + problemStat->getEstimator(i)->addUhOldToSystem(i, oldSolution->getDOFVector(i)); + } + } + } + } + + void ProblemInstatScal::initTimestep(AdaptInfo *adaptInfo) { + oldSolution->copy(*(problemStat->getSolution())); + } + + void ProblemInstatVec::initTimestep(AdaptInfo *adaptInfo) { + oldSolution->copy(*(problemStat->getSolution())); + } + +} diff --git a/AMDiS/src/ProblemInstat.h b/AMDiS/src/ProblemInstat.h new file mode 100644 index 0000000000000000000000000000000000000000..799aef40cd18c9d35fd85b91797e7eadc7042e0a --- /dev/null +++ b/AMDiS/src/ProblemInstat.h @@ -0,0 +1,294 @@ +// ============================================================================ +// == == +// == AMDiS - Adaptive multidimensional simulations == +// == == +// ============================================================================ +// == == +// == crystal growth group == +// == == +// == Stiftung caesar == +// == Ludwig-Erhard-Allee 2 == +// == 53175 Bonn == +// == germany == +// == == +// ============================================================================ +// == == +// == http://www.caesar.de/cg/AMDiS == +// == == +// ============================================================================ + +/** \file ProblemInstat.h */ + +#ifndef AMDIS_PROBLEM_INSTAT_H_ +#define AMDIS_PROBLEM_INSTAT_H_ + +#include "ProblemScal.h" +#include "ProblemVec.h" +#include "MemoryManager.h" +#include "ProblemTimeInterface.h" +#include "AdaptInstationary.h" + +namespace AMDiS { + + // =========================================================================== + // ===== class ProblemInstat ================================================= + // =========================================================================== + + /** + * \ingroup Problem + * + * \brief + * Base class for ProblemInstatScal and ProblemInstatVec. + */ + class ProblemInstat : public ProblemTimeInterface, + public ProblemStatBase + { + public: + /** \brief + * Constructor. + */ + ProblemInstat(::std::string name_, + ProblemStatBase *initialProb) + : name(name_), + initialProblem(initialProb ? initialProb : this) + {}; + + /** \brief + * Destructor. + */ + virtual ~ProblemInstat(); + + + /** \brief + * Initialisation of the problem. + */ + virtual void initialize(Flag initFlag, + ProblemInstat *adoptProblem = NULL, + Flag adoptFlag = INIT_NOTHING); + + /** \brief + */ + virtual void solve(AdaptInfo *adaptInfo) {}; + + /** \brief + */ + virtual void estimate(AdaptInfo *adaptInfo) {}; + + /** \brief + */ + virtual void buildBeforeRefine(AdaptInfo *adaptInfo, Flag) {}; + + /** \brief + */ + virtual void buildBeforeCoarsen(AdaptInfo *adaptInfo, Flag) {}; + + /** \brief + */ + virtual void buildAfterCoarsen(AdaptInfo *adaptInfo, Flag) {}; + + /** \brief + */ + virtual Flag markElements(AdaptInfo *adaptInfo) { return 0; }; + + /** \brief + */ + virtual Flag refineMesh(AdaptInfo *adaptInfo) { return 0; }; + + /** \brief + */ + virtual Flag coarsenMesh(AdaptInfo *adaptInfo) { return 0; }; + + /** \brief + * Implementation of ProblemTimeInterface::closeTimestep(). + */ + virtual void closeTimestep() {}; + + /** \brief + * Returns \ref name. + */ + inline const ::std::string& getName() { return name; }; + + /** \brief + * Used by \ref problemInitial + */ + virtual void solveInitialProblem(AdaptInfo *adaptInfo); + + protected: + /** \brief + * Name of the problem. + */ + ::std::string name; + + ProblemStatBase *initialProblem; + }; + + // =========================================================================== + // ===== class ProblemInstatScal ============================================= + // =========================================================================== + + /** + * \ingroup Problem + * + * \brief + * Standard implementation of ProblemTimeInterface for a time dependent problems. + */ + class ProblemInstatScal : public ProblemInstat + { + public: + MEMORY_MANAGED(ProblemInstatScal); + + /** \brief + * Constructs a ProblemInstatScal with prob as its stationary problem. + */ + ProblemInstatScal(char* name_, + ProblemScal *prob, + ProblemStatBase *initialProb = NULL); + + /** \brief + * Destructor. + */ + virtual ~ProblemInstatScal(); + + /** \brief + * Initialisation of the problem. + */ + virtual void initialize(Flag initFlag, + ProblemInstat *adoptProblem = NULL, + Flag adoptFlag = INIT_NOTHING); + + + /** \brief + * Used in \ref initialize(). + */ + virtual void createUhOld(); + + + + /** \brief + * Implementation of ProblemTimeInterface::initTimestep(). + */ + virtual void initTimestep(AdaptInfo *adaptInfo); + + /** \brief + * Implementation of ProblemTimeInterface::closeTimestep(). + */ + virtual void closeTimestep(AdaptInfo *adaptInfo); + + /** \brief + * Returns \ref problemStat. + */ + inline ProblemScal* getStatProblem() { return problemStat; }; + + /** \brief + * Returns \ref oldSolution. + */ + inline DOFVector<double> *getOldSolution() { return oldSolution; }; + + /** \brief + * Used by \ref problemInitial + */ + virtual void transferInitialSolution(AdaptInfo *adaptInfo); + + + virtual void serialize(::std::ostream &out) {}; + + + virtual void deserialize(::std::istream &in) {}; + + protected: + /** \brief + * Space problem solved in each timestep. + */ + ProblemScal* problemStat; + + /** \brief + * Solution of the last timestep. + */ + DOFVector<double>* oldSolution; + }; + + + // =========================================================================== + // ===== class ProblemInstatVec ============================================== + // =========================================================================== + + /** + * \ingroup Problem + * + * \brief + * Standard implementation of ProblemTimeInterface for a time dependent + * vector valued problems. + */ + class ProblemInstatVec : public ProblemInstat + { + public: + MEMORY_MANAGED(ProblemInstatVec); + + /** \brief + * Constructs a ProblemInstatVec with prob as its stationary problem. + */ + ProblemInstatVec(char *name_, + ProblemVec *prob, + ProblemStatBase *initialProb = NULL); + + /** \brief + * Destructor. + */ + virtual ~ProblemInstatVec(); + + /** \brief + * Initialisation of the problem. + */ + virtual void initialize(Flag initFlag, + ProblemInstat *adoptProblem = NULL, + Flag adoptFlag = INIT_NOTHING); + + /** \brief + * Used in \ref initialize(). + */ + virtual void createUhOld(); + + /** \brief + * Implementation of ProblemTimeInterface::initTimestep(). + */ + virtual void initTimestep(AdaptInfo *adaptInfo); + + /** \brief + * Implementation of ProblemTimeInterface::closeTimestep(). + */ + virtual void closeTimestep(AdaptInfo *adaptInfo); + + /** \brief + * Returns \ref problemStat. + */ + inline ProblemVec* getStatProblem() { return problemStat; }; + + /** \brief + * Returns \ref oldSolution. + */ + inline SystemVector *getOldSolution() { return oldSolution; }; + + /** \brief + * Used by \ref problemInitial + */ + virtual void transferInitialSolution(AdaptInfo *adaptInfo); + + virtual void serialize(::std::ostream &out) {}; + + virtual void deserialize(::std::istream &in) {}; + + protected: + /** \brief + * Space problem solved in each timestep. + */ + ProblemVec* problemStat; + + /** \brief + * Solution of the last timestep. + */ + SystemVector *oldSolution; + }; + +} + +#endif diff --git a/AMDiS/src/ProblemInterpolScal.cc b/AMDiS/src/ProblemInterpolScal.cc new file mode 100644 index 0000000000000000000000000000000000000000..e419e3f6c5c9c1123a28b6067d7ceb1d6600ed3e --- /dev/null +++ b/AMDiS/src/ProblemInterpolScal.cc @@ -0,0 +1,63 @@ +#include "ProblemInterpolScal.h" +#include "Mesh.h" +#include "DOFVector.h" +#include "Parameters.h" +#include "AdaptInfo.h" + +namespace AMDiS { + + ProblemInterpolScal::ProblemInterpolScal(const char *name, + ProblemScal *spaceProblem, + AbstractFunction<double, WorldVector<double> > *fct, + AbstractFunction<WorldVector<double>, WorldVector<double> > *grdFct) + : ProblemScal(name), + interpolFct_(fct), + grdInterpolFct_(grdFct) + { + Flag adoptFlag = + INIT_SYSTEM | + INIT_MESH | + INIT_FE_SPACE; + + Flag initFlag = INIT_ALL & ~adoptFlag & ~INIT_SOLVER & ~INIT_ESTIMATOR; + + initialize(initFlag, spaceProblem, adoptFlag); + } + + void ProblemInterpolScal::solve(AdaptInfo *adaptInfo) { + mesh_->dofCompress(); + solution_->interpol(interpolFct_); + } + + void ProblemInterpolScal::estimate(AdaptInfo *adaptInfo, double) { + FUNCNAME("ProblemIterpolScal::estimate()"); + double errMax = 0.0, errSum = 0.0; + int errorNorm = 0; + + int relErr = 0; + GET_PARAMETER(0, name_ + "->rel error", "%d", &relErr); + + if (grdInterpolFct_) + errorNorm = 1; + else + if (interpolFct_) + errorNorm = 2; + + switch (errorNorm) { + case 1: + errSum = Error<double>::H1Err(*grdInterpolFct_, *solution_, relErr, &errMax, true); + break; + case 2: + errSum = Error<double>::L2Err(*interpolFct_, *solution_, relErr, &errMax, true); + break; + default: + ERROR_EXIT("invalid error norm\n"); + } + + MSG("estimate: %e\n", errSum); + + adaptInfo->setEstSum(errSum, 0); + adaptInfo->setEstMax(errMax, 0); + } + +} diff --git a/AMDiS/src/ProblemInterpolScal.h b/AMDiS/src/ProblemInterpolScal.h new file mode 100644 index 0000000000000000000000000000000000000000..0f0adfc2a2f854f9a5375db45a9b7cfb00d0c103 --- /dev/null +++ b/AMDiS/src/ProblemInterpolScal.h @@ -0,0 +1,90 @@ +// ============================================================================ +// == == +// == AMDiS - Adaptive multidimensional simulations == +// == == +// ============================================================================ +// == == +// == crystal growth group == +// == == +// == Stiftung caesar == +// == Ludwig-Erhard-Allee 2 == +// == 53175 Bonn == +// == germany == +// == == +// ============================================================================ +// == == +// == http://www.caesar.de/cg/AMDiS == +// == == +// ============================================================================ + +/** \file ProblemInterpolScal.h */ + +#ifndef AMDIS_PROBLEMINTERPOLSCAL_H +#define AMDIS_PROBLEMINTERPOLSCAL_H + +#include "ProblemScal.h" + +namespace AMDiS { + +class AdaptInfo; + +// ============================================================================ +// ===== class ProblemInterpolScal ============================================ +// ============================================================================ + +/** \brief + * Interpolates a given function adaptive on spaceProblems mesh. + */ +class ProblemInterpolScal : public ProblemScal +{ +public: + /** \brief + * Constructor. fct will be interpolated on the mesh of spaceProblem. + * grdFct is used, if H1 error should be used for estimation. It points + * to the gradient of fct. + */ + ProblemInterpolScal(const char *name_, + ProblemScal *spaceProblem, + AbstractFunction<double, WorldVector<double> > *fct, + AbstractFunction<WorldVector<double>, WorldVector<double> > *grdFct); + + /** \brief + * no system assemblage. + */ + virtual void buildbeforeRefine(AdaptInfo *adaptInfo, Flag) {}; + + /** \brief + * no system assemblage. + */ + virtual void buildbeforeCoarsen(AdaptInfo *adaptInfo, Flag) {}; + + /** \brief + * no system assemblage. + */ + virtual void buildAfterCoarsen(AdaptInfo *adaptInfo, Flag) {}; + + /** \brief + * no equation system ins solved. Instead fct is interpolated to uh. + */ + virtual void solve(AdaptInfo *adaptInfo); + + /** \brief + * True H1 or L2 error is calculated. + */ + virtual void estimate(AdaptInfo *adaptInfo, double); + +protected: + /** \brief + * function to interpolate. + */ + AbstractFunction<double, WorldVector<double> > *interpolFct_; + + /** \brief + * gradient of \ref interpolFct_. Used for H1 error in estimate(). + */ + AbstractFunction<WorldVector<double>, WorldVector<double> > *grdInterpolFct_; +}; + +} + +#endif diff --git a/AMDiS/src/ProblemInterpolVec.cc b/AMDiS/src/ProblemInterpolVec.cc new file mode 100644 index 0000000000000000000000000000000000000000..a4bc0c66aa9d8483418f32609e0231ca16942a08 --- /dev/null +++ b/AMDiS/src/ProblemInterpolVec.cc @@ -0,0 +1,77 @@ +#include "ProblemInterpolVec.h" +#include "Mesh.h" +#include "Error.h" +#include "SystemVector.h" +#include "AdaptInfo.h" + +namespace AMDiS { + + ProblemInterpolVec::ProblemInterpolVec(const char *name_, + ProblemVec *spaceProblem, + ::std::vector<AbstractFunction<double, WorldVector<double> >*> *fct, + ::std::vector<AbstractFunction<WorldVector<double>, WorldVector<double> >*> *grdFct) + : ProblemVec(name_), + interpolFct_(fct), + grdInterpolFct_(grdFct) + { + Flag adoptFlag = + INIT_SYSTEM | + INIT_MESH | + INIT_FE_SPACE; + + Flag initFlag = INIT_ALL & ~adoptFlag & ~INIT_SOLVER & ~INIT_ESTIMATOR; + + initialize(initFlag, spaceProblem, adoptFlag); + } + + void ProblemInterpolVec::solve(AdaptInfo *adaptInfo) { + int i, size = static_cast<int>(meshes_.size()); + for(i = 0; i < size; i++) { + meshes_[i]->dofCompress(); + } + solution_->interpol(interpolFct_); + } + + void ProblemInterpolVec::estimate(AdaptInfo *adaptInfo, double) { + FUNCNAME("ProblemIterpolVec::estimate()"); + double errMax = 0.0, errSum = 0.0; + int errorNorm = 0; + int i; + int size = static_cast<int>(interpolFct_ ? + interpolFct_->size() : + grdInterpolFct_->size()); + + int relErr = 0; + GET_PARAMETER(0, name_ + "->rel error", "%d", &relErr); + + if(grdInterpolFct_) + errorNorm = 1; + else + if(interpolFct_) errorNorm = 2; + + switch(errorNorm) { + case 1: + for(i = 0; i < size; i++) { + errSum = Error<double>::H1Err((*(*grdInterpolFct_)[i]), + *(solution_->getDOFVector(i)), + relErr, &errMax, true, i); + adaptInfo->setEstSum(errSum, i); + adaptInfo->setEstMax(errMax, i); + } + break; + case 2: + for(i = 0; i < size; i++) { + errSum = Error<double>::L2Err((*(*interpolFct_)[i]), + *(solution_->getDOFVector(i)), + relErr, &errMax, true, i); + adaptInfo->setEstSum(errSum, i); + adaptInfo->setEstMax(errMax, i); + } + break; + default: ERROR_EXIT("invalid error norm\n"); + } + + MSG("estimate: %e\n", errSum); + } + +} diff --git a/AMDiS/src/ProblemInterpolVec.h b/AMDiS/src/ProblemInterpolVec.h new file mode 100644 index 0000000000000000000000000000000000000000..6b29853c99a17c0cb1e310261126ba02ad94419f --- /dev/null +++ b/AMDiS/src/ProblemInterpolVec.h @@ -0,0 +1,88 @@ +// ============================================================================ +// == == +// == AMDiS - Adaptive multidimensional simulations == +// == == +// ============================================================================ +// == == +// == crystal growth group == +// == == +// == Stiftung caesar == +// == Ludwig-Erhard-Allee 2 == +// == 53175 Bonn == +// == germany == +// == == +// ============================================================================ +// == == +// == http://www.caesar.de/cg/AMDiS == +// == == +// ============================================================================ + +/** \file ProblemInterpolVec.h */ + +#ifndef AMDIS_PROBLEMINTERPOLVEC_H +#define AMDIS_PROBLEMINTERPOLVEC_H + +#include "ProblemVec.h" + +namespace AMDiS { + + // ============================================================================ + // ===== class ProblemInterpolVec ============================================= + // ============================================================================ + + /** \brief + * Interpolates a given function adaptive on spaceProblems mesh. + */ + class ProblemInterpolVec : public ProblemVec + { + public: + /** \brief + * Constructor. fct will be interpolated on the mesh of spaceProblem. + * grdFct is used, if H1 error should be used for estimation. It points + * to the gradient of fct. + */ + ProblemInterpolVec(const char *name_, + ProblemVec *spaceProblem, + ::std::vector<AbstractFunction<double, WorldVector<double> >*> *fct, + ::std::vector<AbstractFunction<WorldVector<double>, WorldVector<double> >*> *grdFct); + + /** \brief + * no system assemblage. + */ + virtual void buildbeforeRefine(AdaptInfo *adaptInfo, Flag) {}; + + /** \brief + * no system assemblage. + */ + virtual void buildbeforeCoarsen(AdaptInfo *adaptInfo, Flag) {}; + + /** \brief + * no system assemblage. + */ + virtual void buildAfterCoarsen(AdaptInfo *adaptInfo, Flag) {}; + + /** \brief + * no equation system ins solved. Instead fct is interpolated to uh. + */ + virtual void solve(AdaptInfo *adaptInfo); + + /** \brief + * True H1 or L2 error is calculated. + */ + virtual void estimate(AdaptInfo *adaptInfo, double); + + protected: + /** \brief + * function to interpolate. + */ + ::std::vector<AbstractFunction<double, WorldVector<double> >*> *interpolFct_; + + /** \brief + * gradient of \ref interpolFct_. Used for H1 error in estimate(). + */ + ::std::vector<AbstractFunction<WorldVector<double>, WorldVector<double> >*> *grdInterpolFct_; + }; + +} + +#endif diff --git a/AMDiS/src/ProblemIterationInterface.h b/AMDiS/src/ProblemIterationInterface.h new file mode 100644 index 0000000000000000000000000000000000000000..d8d6c266230223724708acaf49cf2bc1606ca59c --- /dev/null +++ b/AMDiS/src/ProblemIterationInterface.h @@ -0,0 +1,108 @@ +// ============================================================================ +// == == +// == AMDiS - Adaptive multidimensional simulations == +// == == +// ============================================================================ +// == == +// == crystal growth group == +// == == +// == Stiftung caesar == +// == Ludwig-Erhard-Allee 2 == +// == 53175 Bonn == +// == germany == +// == == +// ============================================================================ +// == == +// == http://www.caesar.de/cg/AMDiS == +// == == +// ============================================================================ + +/** \file ProblemIterationInterface.h */ + +#ifndef AMDIS_PROBLEMITERATIONINTERFACE_H +#define AMDIS_PROBLEMITERATIONINTERFACE_H + +#include "Flag.h" + +namespace AMDiS { + + class AdaptInfo; + class ProblemStatBase; + + const Flag BUILD = 0x01L; + const Flag ADAPT = 0x02L; + const Flag SOLVE = 0x04L; + const Flag ESTIMATE = 0x08L; + const Flag MARK = 0x10L; + + const Flag FULL_ITERATION = BUILD | ADAPT | SOLVE | ESTIMATE | MARK; + const Flag NO_ADAPTION = BUILD | SOLVE | ESTIMATE; + + // ============================================================================ + // ===== class ProblemIterationInterface ====================================== + // ============================================================================ + + /** \brief + * Interface for master problems needed by the adaption loop. A master problem + * can handle one single or multiple coupled problems. In the latter case, + * the master problem can determine the execution order of the build, solve, + * estimate, and adapt steps of the single problems in \ref oneIteration(). + */ + class ProblemIterationInterface + { + public: + virtual ~ProblemIterationInterface() {}; + + /** \brief + * Called before each adaption loop iteration. + */ + virtual void beginIteration(AdaptInfo *adaptInfo) {}; + + /** \brief + * Determines the execution order of the single adaption steps. If adapt is + * true, mesh adaption will be performed. This allows to avoid mesh adaption, + * e.g. in timestep adaption loops of timestep adaptive strategies. + */ + virtual Flag oneIteration(AdaptInfo *adaptInfo, Flag toDo = FULL_ITERATION) = 0; + + /** \brief + * Called after each adaption loop iteration. + */ + virtual void endIteration(AdaptInfo *adaptInfo) {}; + + /** \brief + * Returns number of managed problems + */ + virtual int getNumProblems() = 0; + + /** \brief + * Returns the problem with the given number. If only one problem + * is managed by this master problem, the number hasn't to be given. + */ + virtual ProblemStatBase *getProblem(int number = 0) = 0; + + /** \brief + * Returns the problem with the given name. + */ + virtual ProblemStatBase *getProblem(const ::std::string& name) { return NULL; }; + + /** \brief + * Returns the name of the problem. + */ + virtual const ::std::string& getName() = 0; + + /** \brief + * Function that serializes the problem plus information about the iteration. + */ + virtual void serialize(::std::ostream &out) = 0; + + /** \brief + * Function that deserializes the problem plus information about the iteration. + */ + virtual void deserialize(::std::istream &in) = 0; + }; + +} + +#endif + diff --git a/AMDiS/src/ProblemNonLin.cc b/AMDiS/src/ProblemNonLin.cc new file mode 100644 index 0000000000000000000000000000000000000000..9f28709e00fc8347ee4a5f91f241854c1fc81509 --- /dev/null +++ b/AMDiS/src/ProblemNonLin.cc @@ -0,0 +1,207 @@ +#include "ProblemNonLin.h" +#include "NonLinSolver.h" +#include "CreatorMap.h" +#include "NonLinUpdater.h" +#include "Traverse.h" +#include "AdaptInfo.h" + +namespace AMDiS { + + void ProblemNonLinScal::initialize(Flag initFlag, + ProblemScal *adoptProblem /*= NULL*/, + Flag adoptFlag /*= INIT_NOTHING*/) { + + ProblemScal::initialize(initFlag, adoptProblem, adoptFlag); + + // === create Updater === + if(updater_) { + WARNING("updater already created\n"); + } else { + if(initFlag.isSet(INIT_UPDATER) || + ((!adoptFlag.isSet(INIT_UPDATER))&& + (initFlag.isSet(INIT_NONLIN_SOLVER)))) + { + createUpdater(); + } + if(adoptProblem && + (adoptFlag.isSet(INIT_UPDATER) || + ((!initFlag.isSet(INIT_UPDATER))&& + (adoptFlag.isSet(INIT_NONLIN_SOLVER))))) + { + TEST_EXIT(updater_==NULL)("updater already created\n"); + updater_ = dynamic_cast<ProblemNonLinScal*>(adoptProblem)->getUpdater(); + } + } + + if(updater_==NULL) WARNING("no updater created\n"); + + // === create nonlinear solver === + if(nonLinSolver_) { + WARNING("nonlinear solver already created\n"); + } else { + if(initFlag.isSet(INIT_NONLIN_SOLVER)) + { + createNonLinSolver(); + } + if(adoptProblem && + (adoptFlag.isSet(INIT_NONLIN_SOLVER))) + { + TEST_EXIT(nonLinSolver_==NULL)("nonlinear solver already created\n"); + nonLinSolver_ = dynamic_cast<ProblemNonLinScal*>(adoptProblem)->getNonLinSolver(); + } + } + + if(nonLinSolver_==NULL) WARNING("no nonlinear solver created\n"); + } + + void ProblemNonLinScal::createNonLinSolver() { + // create non-linear solver + ::std::string nonLinSolverType("no"); + + GET_PARAMETER(0, name_ + "->nonlin solver", &nonLinSolverType); + + NonLinSolverCreator<DOFVector<double> > *nonLinSolverCreator = + dynamic_cast<NonLinSolverCreator<DOFVector<double> >*>( + CreatorMap<NonLinSolver<DOFVector<double> > >::getCreator(nonLinSolverType)); + nonLinSolverCreator->setLinearSolver(solver_); + nonLinSolverCreator->setName(name_ + "->nonlin solver"); + nonLinSolverCreator->setNonLinUpdater(updater_); + nonLinSolver_ = nonLinSolverCreator->create(); + nonLinSolver_->setVectorCreator(NEW DOFVector<double>::Creator(feSpace_)); + } + + void ProblemNonLinScal::solve(AdaptInfo *adaptInfo) { + TEST_EXIT(nonLinSolver_)("no non-linear solver!\n"); + int iter = nonLinSolver_->solve(matVec_, solution_, rhs_, leftPrecon_, rightPrecon_); + adaptInfo->setSolverIterations(iter); + } + + + void ProblemNonLinScal::buildAfterCoarsen(AdaptInfo *adaptInfo, Flag) { + feSpace_->getMesh()->dofCompress(); + MSG("%d DOFs for %s\n", feSpace_->getAdmin()->getUsedSize(), feSpace_->getName().c_str()); + + TraverseStack stack; + ElInfo *elInfo = stack.traverseFirst(mesh_, -1, + Mesh::CALL_LEAF_EL | + Mesh::FILL_BOUND | + Mesh::FILL_COORDS | + Mesh::FILL_DET | + Mesh::FILL_GRD_LAMBDA); + // for all elements ... + while(elInfo) { + if(solution_->getBoundaryManager()) + solution_->getBoundaryManager()->fillBoundaryConditions(elInfo, solution_); + + elInfo = stack.traverseNext(elInfo); + } + } + + void ProblemNonLinVec::initialize(Flag initFlag, + ProblemVec *adoptProblem /*= NULL*/, + Flag adoptFlag /*= INIT_NOTHING*/) { + ProblemVec::initialize(initFlag, adoptProblem, adoptFlag); + + // === create Updater === + if(updater_) { + WARNING("updater already created\n"); + } else { + if(initFlag.isSet(INIT_UPDATER) || + ((!adoptFlag.isSet(INIT_UPDATER))&& + (initFlag.isSet(INIT_NONLIN_SOLVER)))) + { + createUpdater(); + } + if(adoptProblem && + (adoptFlag.isSet(INIT_UPDATER) || + ((!initFlag.isSet(INIT_UPDATER))&& + (adoptFlag.isSet(INIT_NONLIN_SOLVER))))) + { + TEST_EXIT(updater_==NULL)("updater already created\n"); + updater_ = dynamic_cast<ProblemNonLinVec*>(adoptProblem)->getUpdater(); + } + } + + if(updater_==NULL) WARNING("no updater created\n"); + + // === create nonlinear solver === + if(nonLinSolver_) { + WARNING("nonlinear solver already created\n"); + } else { + if(initFlag.isSet(INIT_NONLIN_SOLVER)) + { + createNonLinSolver(); + } + if(adoptProblem && + (adoptFlag.isSet(INIT_NONLIN_SOLVER))) + { + TEST_EXIT(nonLinSolver_==NULL)("nonlinear solver already created\n"); + nonLinSolver_ = dynamic_cast<ProblemNonLinVec*>(adoptProblem)->getNonLinSolver(); + } + } + + if(nonLinSolver_==NULL) WARNING("no nonlinear solver created\n"); + + } + + void ProblemNonLinVec::createNonLinSolver() { + // create non-linear solver + ::std::string nonLinSolverType("no"); + + GET_PARAMETER(0, name_ + "->nonlin solver", &nonLinSolverType); + + NonLinSolverCreator<SystemVector> *nonLinSolverCreator = + dynamic_cast<NonLinSolverCreator<SystemVector>*>( + CreatorMap<NonLinSolver<SystemVector> >::getCreator(nonLinSolverType)); + nonLinSolverCreator->setLinearSolver(solver_); + nonLinSolverCreator->setName(name_ + "->nonlin solver"); + nonLinSolverCreator->setNonLinUpdater(updater_); + nonLinSolver_ = nonLinSolverCreator->create(); + nonLinSolver_->setVectorCreator(NEW SystemVector::Creator("temp", + componentSpaces_, + numComponents_)); + } + + + void ProblemNonLinVec::solve(AdaptInfo *adaptInfo) { + TEST_EXIT(nonLinSolver_)("no non-linear solver!\n"); + nonLinSolver_->solve(matVec_, solution_, rhs_, leftPrecon_, rightPrecon_); + } + + void ProblemNonLinVec::buildAfterCoarsen(AdaptInfo *adaptInfo, Flag) + { + FUNCNAME("ProblemNonLinVec::buildAfterCoarsen()"); + int i, numMeshes = static_cast<int>(meshes_.size()); + + for(i = 0; i < numMeshes; i++) { + meshes_[i]->dofCompress(); + } + + for(i = 0; i < numComponents_; i++) { + MSG("%d DOFs for %s\n", + componentSpaces_[i]->getAdmin()->getUsedSize(), + componentSpaces_[i]->getName().c_str()); + } + + TraverseStack stack; + ElInfo *elInfo; + + // for all elements ... + for(i = 0; i < numComponents_; i++) { + elInfo = stack.traverseFirst(componentMeshes_[i], -1, + Mesh::CALL_LEAF_EL | + Mesh::FILL_BOUND | + Mesh::FILL_COORDS | + Mesh::FILL_DET | + Mesh::FILL_GRD_LAMBDA); + while(elInfo) { + if(solution_->getDOFVector(i)->getBoundaryManager()) { + solution_->getDOFVector(i)-> + getBoundaryManager()->fillBoundaryConditions(elInfo, solution_->getDOFVector(i)); + } + elInfo = stack.traverseNext(elInfo); + } + } + } + +} diff --git a/AMDiS/src/ProblemNonLin.h b/AMDiS/src/ProblemNonLin.h new file mode 100644 index 0000000000000000000000000000000000000000..605ac6392bb4d0d96b37905a0b4b58f7febf9bab --- /dev/null +++ b/AMDiS/src/ProblemNonLin.h @@ -0,0 +1,271 @@ +// ============================================================================ +// == == +// == AMDiS - Adaptive multidimensional simulations == +// == == +// ============================================================================ +// == == +// == crystal growth group == +// == == +// == Stiftung caesar == +// == Ludwig-Erhard-Allee 2 == +// == 53175 Bonn == +// == germany == +// == == +// ============================================================================ +// == == +// == http://www.caesar.de/cg/AMDiS == +// == == +// ============================================================================ + +/** \file ProblemNonLin.h */ + +#ifndef AMDIS_PROBLEMNONLIN_H_ +#define AMDIS_PROBLEMNONLIN_H_ + +#include "MemoryManager.h" +#include "ProblemScal.h" +#include "ProblemVec.h" +#include "NonLinUpdater.h" +#include "DOFVector.h" +#include "SystemVector.h" +#include "MatrixVector.h" + +namespace AMDiS { + + template<typename Vector> class NonLinSolver; + + // ========================================================================== + // ===== class ProblemNonLinScal ============================================ + // ========================================================================== + + /** + * \ingroup Problem + * + * \brief + * Standard implementation for a non linear problem. + */ + class ProblemNonLinScal : public ProblemScal + { + public: + /** \brief + * Constructs a ProblemNonLin with given name. + */ + ProblemNonLinScal(const ::std::string& name_) + : ProblemScal(name_.c_str()), + u0_(NULL), + nonLinSolver_(NULL), + updater_(NULL) + {}; + + /** \brief + * Destructor. + */ + virtual ~ProblemNonLinScal() {}; + + /** \brief + * Initialisation of the problem. + */ + virtual void initialize(Flag initFlag, + ProblemScal *adoptProblem = NULL, + Flag adoptFlag = INIT_NOTHING); + + /** \brief + * Used in \ref initialize(). + */ + virtual void createUpdater() { + updater_ = NEW NonLinUpdaterScal(systemMatrix_); + }; + + /** \brief + * Used in \ref initialize(). + */ + virtual void createNonLinSolver(); + + /** \brief + * Returns \ref nonLinSolver_. + */ + inline NonLinSolver<DOFVector<double> >* getNonLinSolver() { + return nonLinSolver_; + } + + /** \brief + * Returns \ref updater_. + */ + inline NonLinUpdaterScal* getUpdater() { + return updater_; + } + + /** \brief + * Sets \ref u0_ and interpolates it to \ref uh_. + */ + inline void setU0(AbstractFunction<double, WorldVector<double> > *u0Fct) { + u0_ = u0Fct; + solution_->interpol(u0_); + }; + + /** \brief + * Sets \ref nonLinSolver_. + */ + inline void setNonLinSolver(NonLinSolver<DOFVector<double> > *nonLinSolver) { + nonLinSolver_=nonLinSolver; + } + + /** \brief + * Sets \ref updater. + */ + inline void setUpdater(NonLinUpdaterScal *updater) { + updater_=updater; + } + + /** \brief + * Overrides ProblemScal::solve(). Uses the non linear solver + * \ref nonLinSolver_. + */ + virtual void solve(AdaptInfo *adaptInfo); + + /** \brief + * Overrides Problem::buildAfterCoarsen(). Sets dirichlet boundaries + * in \ref A_ and \ref rhs_. + */ + virtual void buildAfterCoarsen(AdaptInfo *adaptInfo, Flag); + + protected: + /** \brief + * Initial guess for the solution. + */ + AbstractFunction<double, WorldVector<double> > *u0_; + + /** \brief + * Non linear solver. Used in \ref solve(). + */ + NonLinSolver<DOFVector<double> > *nonLinSolver_; + + /** \brief + * Updator + */ + NonLinUpdaterScal *updater_; + }; + + // ========================================================================== + // ===== class ProblemNonLinScal ============================================ + // ========================================================================== + + /** + * \ingroup Problem + * + * \brief + * Standard implementation for a vector valued non linear problem. + */ + class ProblemNonLinVec : public ProblemVec + { + public: + /** \brief + * Constructs a ProblemNonLin with given name. + */ + ProblemNonLinVec(const ::std::string& name_) + : ProblemVec(name_.c_str()), + nonLinSolver_(NULL), + updater_(NULL) + { + u0_.resize(numComponents_); + u0_.set(NULL); + }; + + /** \brief + * Sets \ref u0_ and interpolates it to \ref solution_. + */ + inline void setU0(AbstractFunction<double, WorldVector<double> > *u0Fct, + int index) + { + FUNCNAME("ProblemNonLinVec::setU0()"); + TEST_EXIT(index < numComponents_)("invalid index\n"); + u0_[index] = u0Fct; + solution_->getDOFVector(index)->interpol(u0Fct); + }; + + /** \brief + * Destructor. + */ + virtual ~ProblemNonLinVec() {}; + + /** \brief + * Initialisation of the problem. + */ + virtual void initialize(Flag initFlag, + ProblemVec *adoptProblem = NULL, + Flag adoptFlag = INIT_NOTHING); + + /** \brief + * Used in \ref initialize(). + */ + virtual void createUpdater() { + updater_ = NEW NonLinUpdaterVec(systemMatrix_); + }; + + /** \brief + * Used in \ref initialize(). + */ + virtual void createNonLinSolver(); + + /** \brief + * Overrides ProblemVec::solve(). Uses the non linear solver + * \ref nonLinSolver_. + */ + virtual void solve(AdaptInfo *adaptInfo); + + /** \brief + * Overrides Problem::buildAfterCoarsen(). Sets dirichlet boundaries + * in \ref A_ and \ref rhs_. + */ + virtual void buildAfterCoarsen(AdaptInfo *adaptInfo, Flag); + + /** \brief + * Returns /ref nonLinSolver_. + */ + inline NonLinSolver<SystemVector> *getNonLinSolver() { + return nonLinSolver_; + }; + + /** \brief + * Returns \ref updater. + */ + inline NonLinUpdaterVec* getUpdater() { + return updater_; + } + + /** \brief + * Sets \ref nonLinSolver_. + */ + inline void setNonLinSolver(NonLinSolver<SystemVector> *nonLinSolver) { + nonLinSolver_=nonLinSolver; + } + + /** \brief + * Sets \ref updater. + */ + inline void setUpdater(NonLinUpdaterVec *updater) { + updater_=updater; + } + + + protected: + /** \brief + * Initial guess for the solution. + */ + Vector<AbstractFunction<double, WorldVector<double> >*> u0_; + + /** \brief + * Non linear solver. Used in \ref solve(). + */ + NonLinSolver<SystemVector> *nonLinSolver_; + + /** \brief + * Updator + */ + NonLinUpdaterVec *updater_; + }; + +} + +#endif + diff --git a/AMDiS/src/ProblemScal.cc b/AMDiS/src/ProblemScal.cc new file mode 100644 index 0000000000000000000000000000000000000000..621d8af946b6724d5a51732e3628c06d2c7979d1 --- /dev/null +++ b/AMDiS/src/ProblemScal.cc @@ -0,0 +1,638 @@ +#include "ProblemScal.h" +#include "AbstractFunction.h" +#include "DirichletBC.h" +#include "RobinBC.h" +#include "FixVec.h" +#include "Flag.h" +#include "Serializer.h" +#include "RecoveryEstimator.h" +#include "Operator.h" +#include "DOFMatrix.h" +#include "FiniteElemSpace.h" +#include "Estimator.h" +#include "OEMSolver.h" +#include "Preconditioner.h" +#include "MatVecMultiplier.h" +#include "DOFVector.h" +#include "Marker.h" +#include "AdaptInfo.h" +#include "ElInfo.h" +#include "FileWriter.h" +#include "RefinementManager.h" +#include "CoarseningManager.h" +#include "Lagrange.h" +#include "PeriodicBC.h" +#include "ValueReader.h" + +namespace AMDiS { + + ProblemScal *ProblemScal::traversePtr_ = NULL; + + void ProblemScal::writeFiles(AdaptInfo *adaptInfo, bool force) { + ::std::list<FileWriterInterface*>::iterator it; + for(it = fileWriters_.begin(); it != fileWriters_.end(); ++it) { + (*it)->writeFiles(adaptInfo, force); + } + } + + void ProblemScal::interpolInitialSolution(AbstractFunction<double, WorldVector<double> > *fct) + { + solution_->interpol(fct); + } + + void ProblemScal::addMatrixOperator(Operator *op, + double *factor, + double *estFactor) + { + systemMatrix_->addOperator(op, factor, estFactor); + } + + void ProblemScal::addVectorOperator(Operator *op, + double *factor, + double *estFactor) + { + rhs_->addOperator(op, factor, estFactor); + } + + void ProblemScal::addDirichletBC(BoundaryType type, + AbstractFunction<double, WorldVector<double> >* b) + { + DirichletBC *dirichlet = new DirichletBC(type, b, feSpace_); + if(systemMatrix_) + systemMatrix_->getBoundaryManager()->addBoundaryCondition(dirichlet); + if(rhs_) + rhs_->getBoundaryManager()->addBoundaryCondition(dirichlet); + if(solution_) + solution_->getBoundaryManager()->addBoundaryCondition(dirichlet); + } + + void ProblemScal::addDirichletBC(BoundaryType type, + DOFVector<double> *vec) + { + DirichletBC *dirichlet = new DirichletBC(type, vec); + if(systemMatrix_) + systemMatrix_->getBoundaryManager()->addBoundaryCondition(dirichlet); + if(rhs_) + rhs_->getBoundaryManager()->addBoundaryCondition(dirichlet); + if(solution_) + solution_->getBoundaryManager()->addBoundaryCondition(dirichlet); + } + + void ProblemScal::addRobinBC(BoundaryType type, + AbstractFunction<double, WorldVector<double> > *n, + AbstractFunction<double, WorldVector<double> > *r) + { + RobinBC *robin = new RobinBC(type, n, r, feSpace_); + if(rhs_) + rhs_->getBoundaryManager()->addBoundaryCondition(robin); + if(systemMatrix_) + systemMatrix_->getBoundaryManager()->addBoundaryCondition(robin); + } + + void ProblemScal::addNeumannBC(BoundaryType type, + AbstractFunction<double, WorldVector<double> > *n) + { + NeumannBC *neumann = new NeumannBC(type, n, feSpace_); + if(rhs_) + rhs_->getBoundaryManager()->addBoundaryCondition(neumann); + } + + void ProblemScal::addRobinBC(BoundaryType type, + DOFVector<double> *n, + DOFVector<double> *r) + { + RobinBC *robin = new RobinBC(type, n, r, feSpace_); + if(rhs_) + rhs_->getBoundaryManager()->addBoundaryCondition(robin); + if(systemMatrix_) + systemMatrix_->getBoundaryManager()->addBoundaryCondition(robin); + } + + void ProblemScal::addPeriodicBC(BoundaryType type) + { + PeriodicBC *periodic = new PeriodicBC(type, feSpace_); + + // TEST_EXIT(mesh_->getPeriodicBCMap()[type] == NULL) + // ("periodic condition already set in mesh\n"); + // mesh_->getPeriodicBCMap()[type] = periodic; + + if(systemMatrix_) + systemMatrix_->getBoundaryManager()->addBoundaryCondition(periodic); + if(rhs_) + rhs_->getBoundaryManager()->addBoundaryCondition(periodic); + } + + void ProblemScal::createMesh() + { + TEST_EXIT(Parameters::initialized())("parameters not initialized\n"); + + // === create problems mesh === + ::std::string meshName(""); + + GET_PARAMETER(0, name_ + "->info", "%d", &info_); + + GET_PARAMETER(0, name_ + "->mesh", &meshName); + + TEST_EXIT(meshName != "") + ("no mesh name spezified\n"); + + // get problem dimension + int dim = 0; + GET_PARAMETER(0, name_ + "->dim", "%d", &dim); + TEST_EXIT(dim)("no problem dimension spezified!\n"); + + // create the mesh + mesh_ = NEW Mesh(meshName, dim); + + switch(dim) { + case 1: + coarseningManager_ = NEW CoarseningManager1d(); + refinementManager_ = NEW RefinementManager1d(); + break; + case 2: + coarseningManager_ = NEW CoarseningManager2d(); + refinementManager_ = NEW RefinementManager2d(); + break; + case 3: + coarseningManager_ = NEW CoarseningManager3d(); + refinementManager_ = NEW RefinementManager3d(); + break; + default: + ERROR_EXIT("invalid dim!\n"); + } + } + + Flag ProblemScal::markElements(AdaptInfo *adaptInfo) + { + if(marker_) + return marker_->markMesh(adaptInfo, mesh_); + else + WARNING("no marker\n"); + return 0; + } + + Flag ProblemScal::refineMesh(AdaptInfo *adaptInfo) + { + return refinementManager_->refineMesh(mesh_); + } + + Flag ProblemScal::coarsenMesh(AdaptInfo *adaptInfo) + { + if(adaptInfo->isCoarseningAllowed(0)) + return coarseningManager_->coarsenMesh(mesh_); + else { + WARNING("coarsening not allowed\n"); + return 0; + } + } + + void ProblemScal::solve(AdaptInfo *adaptInfo) + { + FUNCNAME("Problem::solve()"); + if(!solver_) { + WARNING("no solver\n"); + return; + } + +#ifdef _OPENMP + double wtime = omp_get_wtime(); +#endif + + clock_t first = clock(); + int iter = solver_->solve(matVec_, solution_, rhs_, leftPrecon_, rightPrecon_); + +#ifdef _OPENMP + INFO(info_, 8)("solution of discrete system needed %.5f seconds system time / %.5f seconds wallclock time\n", + TIME_USED(first, clock()), + omp_get_wtime() - wtime); +#else + INFO(info_, 8)("solution of discrete system needed %.5f seconds\n", + TIME_USED(first, clock())); +#endif + + adaptInfo->setSolverIterations(iter); + adaptInfo->setMaxSolverIterations(solver_->getMaxIterations()); + adaptInfo->setSolverTolerance(solver_->getTolerance()); + adaptInfo->setSolverResidual(solver_->getResidual()); + } + + void ProblemScal::initialize(Flag initFlag, + ProblemScal *adoptProblem, + Flag adoptFlag) + { + FUNCNAME("Problem::initialize()"); + + // === create mesh === + if(mesh_) { + WARNING("mesh already created\n"); + } else { + if(initFlag.isSet(CREATE_MESH) || + ((!adoptFlag.isSet(INIT_MESH))&& + (initFlag.isSet(INIT_SYSTEM)||initFlag.isSet(INIT_FE_SPACE)))) + { + createMesh(); + } + if(adoptProblem && + (adoptFlag.isSet(INIT_MESH) || + adoptFlag.isSet(INIT_SYSTEM) || + adoptFlag.isSet(INIT_FE_SPACE))) + { + TEST_EXIT(!mesh_)("mesh already created\n"); + mesh_ = adoptProblem->getMesh(); + refinementManager_ = adoptProblem->refinementManager_; + coarseningManager_ = adoptProblem->coarseningManager_; + } + } + + if(!mesh_) WARNING("no mesh created\n"); + + // === create fespace === + if(feSpace_) { + WARNING("feSpace already created\n"); + } else { + if(initFlag.isSet(INIT_FE_SPACE) || (initFlag.isSet(INIT_SYSTEM)&&!adoptFlag.isSet(INIT_FE_SPACE))) { + createFESpace(); + } + if(adoptProblem && + (adoptFlag.isSet(INIT_FE_SPACE) || adoptFlag.isSet(INIT_SYSTEM))) + { + TEST_EXIT(!feSpace_)("feSpace already created"); + feSpace_ = dynamic_cast<ProblemScal*>(adoptProblem)->getFESpace(); + } + } + + if(!feSpace_) WARNING("no feSpace created\n"); + + // === create system === + if (initFlag.isSet(INIT_SYSTEM)) { + createMatricesAndVectors(); + } + if (adoptProblem && adoptFlag.isSet(INIT_SYSTEM)) { + TEST_EXIT(!solution_)("solution already created\n"); + TEST_EXIT(!rhs_)("rhs already created\n"); + TEST_EXIT(!systemMatrix_)("systemMatrix already created\n"); + solution_ = adoptProblem->getSolution(); + rhs_ = adoptProblem->getRHS(); + systemMatrix_ = adoptProblem->getSystemMatrix(); + } + + // === create solver === + if (solver_) { + WARNING("solver already created\n"); + } else { + if (initFlag.isSet(INIT_SOLVER)) { + createSolver(); + } + if (adoptProblem && adoptFlag.isSet(INIT_SOLVER)) { + TEST_EXIT(!solver_)("solver already created\n"); + solver_ = adoptProblem->getSolver(); + } + } + + if (!solver_) + WARNING("no solver created\n"); + + // === create estimator === + if(estimator_) { + WARNING("estimator already created\n"); + } else { + if(initFlag.isSet(INIT_ESTIMATOR)) { + createEstimator(); + } + if(adoptProblem && adoptFlag.isSet(INIT_ESTIMATOR)) { + TEST_EXIT(!estimator_)("estimator already created\n"); + estimator_ = adoptProblem->getEstimator(); + } + } + + if(!estimator_) WARNING("no estimator created\n"); + + // === create marker === + if(marker_) { + WARNING("marker already created\n"); + } else { + if(initFlag.isSet(INIT_MARKER)) { + createMarker(); + } + if(adoptProblem && adoptFlag.isSet(INIT_MARKER)) { + TEST_EXIT(!marker_)("marker already created\n"); + marker_ = adoptProblem->getMarker(); + } + } + + if(!marker_) WARNING("no marker created\n"); + + // === create file writer === + if(initFlag.isSet(INIT_FILEWRITER)) { + createFileWriter(); + } + + + + // === read serialization and init mesh === + + // There are two possiblities where the user can define a serialization + // to be read from disk. Either by providing the parameter -rs when executing + // the program or in the init file. The -rs parameter is always checked first, + // because it can be added automatically when rescheduling the program + // before timeout of the runqueue. + + int readSerialization = 0; + ::std::string serializationFilename = ""; + GET_PARAMETER(0, "argv->rs", &serializationFilename); + + // If the parameter -rs is set, we do nothing here, because the problem will be + // deserialized in the constructor of a following AdaptInstationary initialization. + if (!serializationFilename.compare("")) { + GET_PARAMETER(0, name_ + "->input->read serialization", "%d", + &readSerialization); + if (readSerialization) { + GET_PARAMETER(0, name_ + "->input->serialization filename", + &serializationFilename); + TEST_EXIT(serializationFilename != "")("no serialization file\n"); + + MSG("Deserialization from file: %s\n", serializationFilename.c_str()); + ::std::ifstream in(serializationFilename.c_str()); + deserialize(in); + in.close(); + } else { + if (initFlag.isSet(INIT_MESH) && mesh_ && !mesh_->isInitialized()) { + mesh_->initialize(); + } + + // === read value file and use it for the mesh values === + ::std::string valueFilename(""); + GET_PARAMETER(0, mesh_->getName() + "->value file name", &valueFilename); + if (valueFilename.length()) { + ValueReader::readValue(valueFilename.c_str(), + mesh_, + solution_, + mesh_->getMacroFileInfo()); + mesh_->clearMacroFileInfo(); + } + + + // === do global refinements === + int globalRefinements = 0; + GET_PARAMETER(0, mesh_->getName() + "->global refinements", "%d", &globalRefinements); + refinementManager_->globalRefine(mesh_, globalRefinements); + } + } + } + + void ProblemScal::createFESpace() + { + // create finite element space + int degree = 1; + GET_PARAMETER(0, name_ + "->polynomial degree" ,"%d", °ree); + feSpace_ = FiniteElemSpace::provideFESpace(NULL, + Lagrange::getLagrange(mesh_->getDim(), degree), + mesh_, + name_ + "->feSpace"); + + // create dof admin for vertex dofs if neccessary + if (mesh_->getNumberOfDOFs(VERTEX) == 0) { + DimVec<int> ln_dof(mesh_->getDim(), DEFAULT_VALUE, 0); + ln_dof[VERTEX]= 1; + mesh_->createDOFAdmin("vertex dofs", ln_dof); + } + } + + void ProblemScal::createMatricesAndVectors() + { + // === create vectors and system matrix === + systemMatrix_ = NEW DOFMatrix(feSpace_, feSpace_, "system matrix"); + rhs_ = NEW DOFVector<double>(feSpace_, "rhs"); + solution_ = NEW DOFVector<double>(feSpace_, "solution"); + + solution_->refineInterpol(true); + solution_->setCoarsenOperation(COARSE_INTERPOL); + solution_->set(0.0); /* initialize u_h ! */ + + // === create matVec === + matVec_ = NEW StandardMatVec<DOFMatrix, DOFVector<double> >(systemMatrix_); + } + + void ProblemScal::createSolver() + { + // === create solver === + ::std::string solverType("no"); + GET_PARAMETER(0, name_ + "->solver", &solverType); + OEMSolverCreator<DOFVector<double> > *solverCreator = + dynamic_cast<OEMSolverCreator<DOFVector<double> >*>( + CreatorMap<OEMSolver<DOFVector<double> > >::getCreator(solverType)); + TEST_EXIT(solverCreator)("no solver type\n"); + solverCreator->setName(name_ + "->solver"); + solver_ = solverCreator->create(); + solver_->initParameters(); + + // === create preconditioners === + ::std::string preconType("no"); + Preconditioner<DOFVector<double> > *precon; + GET_PARAMETER(0, name_ + "->solver->left precon", &preconType); + CreatorInterface<PreconditionerScal> *preconCreator = + CreatorMap<PreconditionerScal>::getCreator(preconType); + + if (!preconCreator->isNullCreator()) { + dynamic_cast<PreconditionerScalCreator*>(preconCreator)->setSizeAndRow(1, 0); + dynamic_cast<PreconditionerScalCreator*>(preconCreator)->setName(name_ + "->solver->left precon"); + } + + precon = preconCreator->create(); + + if (precon) { + dynamic_cast<PreconditionerScal*>(precon)->setMatrix(&systemMatrix_); + leftPrecon_ = precon; + } + + preconType.assign("no"); + GET_PARAMETER(0, name_ + "->solver->right precon", &preconType); + preconCreator = CreatorMap<PreconditionerScal>::getCreator(preconType); + + if (!preconCreator->isNullCreator()) { + dynamic_cast<PreconditionerScalCreator*>(preconCreator)->setSizeAndRow(1, 0); + dynamic_cast<PreconditionerScalCreator*>(preconCreator)->setName(name_ + "->solver->left precon"); + } + + precon = preconCreator->create(); + if (precon) { + dynamic_cast<PreconditionerScal*>(precon)->setMatrix(&systemMatrix_); + rightPrecon_ = precon; + } + + // === create vector creator === + solver_->setVectorCreator(new DOFVector<double>::Creator(feSpace_)); + + } + + void ProblemScal::createEstimator() + { + // create and set leaf data prototype + mesh_-> + setElementDataPrototype(NEW LeafDataEstimatable(NEW LeafDataCoarsenable)); + + // create estimator + //estimator = NEW ResidualEstimator(name + "->estimator"); + + // === create estimator === + ::std::string estimatorType("no"); + GET_PARAMETER(0, name_ + "->estimator", &estimatorType); + EstimatorCreator *estimatorCreator = + dynamic_cast<EstimatorCreator*>( + CreatorMap<Estimator>::getCreator(estimatorType)); + if(estimatorCreator) { + estimatorCreator->setName(name_ + "->estimator"); + if(estimatorType == "recovery") { + dynamic_cast<RecoveryEstimator::Creator*>(estimatorCreator)->setSolution(solution_); + } + estimator_ = estimatorCreator->create(); + + // init estimator + estimator_->addSystem(systemMatrix_, solution_, rhs_); + } + } + + void ProblemScal::createMarker() + { + marker_ = dynamic_cast<Marker*>(Marker::createMarker(name_ + "->marker", -1)); + } + + void ProblemScal::createFileWriter() + { + fileWriters_.push_back(NEW FileWriter(name_ + "->output", mesh_, solution_)); + int writeSerialization = 0; + GET_PARAMETER(0, name_ + "->output->write serialization", "%d", + &writeSerialization); + if(writeSerialization) { + fileWriters_.push_back(NEW Serializer<ProblemScal>(this)); + } + } + + void ProblemScal::estimate(AdaptInfo *adaptInfo) + { + FUNCNAME("Problem::estimate()"); + + if(estimator_) { + clock_t first = clock(); + estimator_->estimate(adaptInfo->getTimestep()); + INFO(info_,8)("estimation of the error needed %.5f seconds\n", + TIME_USED(first,clock())); + + adaptInfo->setEstSum(estimator_->getErrorSum(), 0); + + adaptInfo-> + setTimeEstSum(estimator_->getTimeEst(), 0); + + adaptInfo-> + setEstMax(estimator_->getErrorMax(), 0); + + adaptInfo-> + setTimeEstMax(estimator_->getTimeEstMax(), 0); + + } else { + WARNING("no estimator\n"); + } + } + + void ProblemScal::buildAfterCoarsen(AdaptInfo *adaptInfo, Flag flag) + { + FUNCNAME("ProblemScal::buildAfterCoarsen"); + + clock_t first = clock(); + + mesh_->dofCompress(); + + MSG("%d DOFs for %s\n", + feSpace_->getAdmin()->getUsedSize(), + feSpace_->getName().c_str()); + + Flag assembleFlag = + flag | + systemMatrix_->getAssembleFlag() | + rhs_->getAssembleFlag(); + + if (useGetBound_) + assembleFlag |= Mesh::FILL_BOUND; + + systemMatrix_->clear(); + rhs_->set(0.0); + + traversePtr_ = this; + + mesh_->traverse(-1, assembleFlag, &buildAfterCoarsenFct); + + // fill boundary conditions + if (systemMatrix_->getBoundaryManager()) + systemMatrix_->getBoundaryManager()->initMatrix(systemMatrix_); + if (rhs_->getBoundaryManager()) + rhs_->getBoundaryManager()->initVector(rhs_); + if (solution_->getBoundaryManager()) + solution_->getBoundaryManager()->initVector(solution_); + + TraverseStack stack; + ElInfo *elInfo = stack.traverseFirst(mesh_, -1, + Mesh::CALL_LEAF_EL | + Mesh::FILL_BOUND | + Mesh::FILL_COORDS | + Mesh::FILL_DET | + Mesh::FILL_GRD_LAMBDA | + Mesh::FILL_NEIGH); + // for all elements ... + while (elInfo) { + if (systemMatrix_->getBoundaryManager()) + systemMatrix_->getBoundaryManager()->fillBoundaryConditions(elInfo, systemMatrix_); + if (rhs_->getBoundaryManager()) + rhs_->getBoundaryManager()->fillBoundaryConditions(elInfo, rhs_); + if (solution_->getBoundaryManager()) + solution_->getBoundaryManager()->fillBoundaryConditions(elInfo, solution_); + + elInfo = stack.traverseNext(elInfo); + } + + if (systemMatrix_->getBoundaryManager()) + systemMatrix_->getBoundaryManager()->exitMatrix(systemMatrix_); + if (rhs_->getBoundaryManager()) + rhs_->getBoundaryManager()->exitVector(rhs_); + if (solution_->getBoundaryManager()) + solution_->getBoundaryManager()->exitVector(solution_); + + INFO(info_, 8)("buildAfterCoarsen needed %.5f seconds\n", + TIME_USED(first,clock())); + + // ::std::cout << "Speicherverbrauch: " << memSizeStr(systemMatrix_->memsize()) << ::std::endl; + + return; + } + + int ProblemScal::buildAfterCoarsenFct(ElInfo *elInfo) + { + const BoundaryType *bound; + + if (traversePtr_->getBoundUsed()) + bound = traversePtr_->getFESpace()->getBasisFcts()->getBound(elInfo, NULL); + else + bound = NULL; + + traversePtr_->getSystemMatrix()->assemble(1.0, elInfo, bound); + traversePtr_->getRHS()->assemble(1.0, elInfo, bound); + + return 0; + } + + void ProblemScal::serialize(::std::ostream &out) + { + FUNCNAME("ProblemScal::serialize()"); + + mesh_->serialize(out); + solution_->serialize(out); + } + + void ProblemScal::deserialize(::std::istream &in) + { + FUNCNAME("ProblemScal::deserialize()"); + + mesh_->deserialize(in); + solution_->deserialize(in); + } + +} diff --git a/AMDiS/src/ProblemScal.h b/AMDiS/src/ProblemScal.h new file mode 100644 index 0000000000000000000000000000000000000000..f41883473fa15fa37f03e49bcb58b0652c9db593 --- /dev/null +++ b/AMDiS/src/ProblemScal.h @@ -0,0 +1,521 @@ +// ============================================================================ +// == == +// == AMDiS - Adaptive multidimensional simulations == +// == == +// ============================================================================ +// == == +// == crystal growth group == +// == == +// == Stiftung caesar == +// == Ludwig-Erhard-Allee 2 == +// == 53175 Bonn == +// == germany == +// == == +// ============================================================================ +// == == +// == http://www.caesar.de/cg/AMDiS == +// == == +// ============================================================================ + +/** \file ProblemScal.h */ + +#ifndef AMDIS_PROBLEMSCAL_H +#define AMDIS_PROBLEMSCAL_H + +#include "Global.h" +#include "ProblemStatBase.h" +#include "MemoryManager.h" +#include "AbstractFunction.h" +#include "FixVec.h" +#include "Boundary.h" +#include "StandardProblemIteration.h" +#include <list> + +namespace AMDiS { + + class Operator; + class DOFMatrix; + class FiniteElemSpace; + class Estimator; + template<typename T> class OEMSolver; + template<typename T> class Preconditioner; + template<typename T> class MatVecMultiplier; + template<typename T> class DOFVector; + class Marker; + class AdaptInfo; + class ElInfo; + class FileWriterInterface; + class RefinementManager; + class CoarseningManager; + + class ProblemScal : public ProblemStatBase, + public StandardProblemIteration + { + public: + MEMORY_MANAGED(ProblemScal); + + ProblemScal(const char *name, + ProblemIterationInterface *problemIteration = NULL) + : StandardProblemIteration(this) , + name_(name), + feSpace_(NULL), + mesh_(NULL), + marker_(NULL), + estimator_(NULL), + solver_(NULL), + solution_(NULL), + rhs_(NULL), + systemMatrix_(NULL), + matVec_(NULL), + leftPrecon_(NULL), + rightPrecon_(NULL), + useGetBound_(true), + refinementManager_(NULL), + coarseningManager_(NULL), + info_(10) + { + }; + + /** \brief + * Destructor + */ + virtual ~ProblemScal() { + FUNCNAME("~ProblemScal"); + }; + + /** \brief + * Initialisation of the problem. + */ + virtual void initialize(Flag initFlag, + ProblemScal *adoptProblem = NULL, + Flag adoptFlag = INIT_NOTHING); + + /** \brief + * Used in \ref initialize(). + */ + virtual void createMesh(); + + /** \brief + * Used in \ref initialize(). + */ + virtual void createFESpace(); + + /** \brief + * Used in \ref initialize(). + */ + virtual void createMatricesAndVectors(); + + /** \brief + * Used in \ref initialize(). + */ + virtual void createSolver(); + + /** \brief + * Used in \ref initialize(). + */ + virtual void createEstimator(); + + /** \brief + * Used in \ref initialize(). + */ + virtual void createMarker(); + + /** \brief + * Used in \ref initialize(). + */ + virtual void createFileWriter(); + + /** \brief + * Implementation of ProblemStatBase::solve(). Deligates the solving + * of problems system to \ref solver. + */ + virtual void solve(AdaptInfo *adaptInfo); + + /** \brief + * Implementation of ProblemStatBase::estimate(). Deligates the estimation + * to \ref estimator. + */ + virtual void estimate(AdaptInfo *adaptInfo); + + /** \brief + * Implementation of ProblemStatBase::markElements(). + * Deligated to \ref adapt. + */ + virtual Flag markElements(AdaptInfo *adaptInfo); + + /** \brief + * Implementation of ProblemStatBase::refineMesh(). Deligated to the + * RefinementManager of \ref adapt. + */ + virtual Flag refineMesh(AdaptInfo *adaptInfo); + + /** \brief + * Implementation of ProblemStatBase::coarsenMesh(). Deligated to the + * CoarseningManager of \ref adapt. + */ + virtual Flag coarsenMesh(AdaptInfo *adaptInfo); + + /** \brief + * Implementation of ProblemStatBase::buildBeforeRefine(). + * Does nothing here. + */ + virtual void buildBeforeRefine(AdaptInfo *adaptInfo, Flag) {}; + + /** \brief + * Implementation of ProblemStatBase::buildBeforeCoarsen(). + * Does nothing here. + */ + virtual void buildBeforeCoarsen(AdaptInfo *adaptInfo, Flag) {}; + + /** \brief + * Implementation of ProblemStatBase::buildAfterCoarsen(). + * Assembles \ref A and \ref rhs. + */ + virtual void buildAfterCoarsen(AdaptInfo *adaptInfo, Flag flag); + + /** \brief + * Returns number of managed problems + */ + virtual int getNumProblems() { return 1; }; + + /** \brief + * Implementation of ProblemStatBase::getNumComponents() + */ + virtual int getNumComponents() { return 1; }; + + /** \brief + * Returns the problem with the given number. If only one problem + * is managed by this master problem, the number hasn't to be given. + */ + virtual ProblemStatBase *getProblem(int number = 0) { return this; }; + + /** \brief + * Writes output files. + */ + void writeFiles(AdaptInfo *adaptInfo, bool force); + + /** \brief + * Interpolates fct to \ref solution. + */ + void + interpolInitialSolution(AbstractFunction<double, WorldVector<double> > *fct); + + /** \brief + * Adds an Operator to \ref systemMatrix_. + */ + void addMatrixOperator(Operator *op, + double *factor = NULL, + double *estFactor = NULL); + + /** \brief + * Adds an Operator to \ref rhs_. + */ + void addVectorOperator(Operator *op, + double *factor = NULL, + double *estFactor = NULL); + + /** \brief + * Adds dirichlet boundary conditions. + */ + virtual void addDirichletBC(BoundaryType type, + AbstractFunction<double, WorldVector<double> >* b); + + /** \brief + * Adds dirichlet boundary conditions. + */ + virtual void addDirichletBC(BoundaryType type, + DOFVector<double> *vec); + + /** \brief + * Adds robin boundary conditions. + */ + virtual void addRobinBC(BoundaryType type, + AbstractFunction<double, WorldVector<double> > *n, + AbstractFunction<double, WorldVector<double> > *r); + + /** \brief + * Adds robin boundary conditions. + */ + virtual void addRobinBC(BoundaryType type, + DOFVector<double> *n, + DOFVector<double> *r); + + /** \brief + * Adds Neumann boundary conditions. + */ + virtual void addNeumannBC(BoundaryType type, + AbstractFunction<double, WorldVector<double> > *n); + + + virtual void addPeriodicBC(BoundaryType type); + + // ===== getting-methods ====================================================== + + /** \name getting methods + * \{ + */ + + /** \brief + * Returns \ref solution_. + */ + inline DOFVector<double>* getSolution() { + return solution_; + }; + + /** \brief + * Returns \ref rhs_. + */ + inline DOFVector<double>* getRHS() { + return rhs_; + }; + + /** \brief + * Returns \ref systemMatrix_. + */ + inline DOFMatrix *getSystemMatrix() { + return systemMatrix_; + }; + + /** \brief + * Returns \ref mesh_ + */ + inline Mesh* getMesh() { + return mesh_; + }; + + /** \brief + * Returns \ref feSpace_. + */ + inline FiniteElemSpace* getFESpace() { + return feSpace_; + }; + + /** \brief + * Returns \ref estimator_. + */ + inline Estimator* getEstimator() { + return estimator_; + }; + + /** \brief + * Returns \ref refinementManager_. + */ + inline RefinementManager* getRefinementManager() { + return refinementManager_; + }; + + /** \brief + * Returns \ref solver_. + */ + inline OEMSolver<DOFVector<double> >* getSolver() { + return solver_; + }; + + /** \brief + * Returns \ref marker_. + */ + inline Marker *getMarker() { + return marker_; + }; + + /** \brief + * Returns \ref name_. + */ + virtual inline const ::std::string& getName() { + return name_; + }; + + /** \brief + * Returns \ref useGetBound_. + */ + inline bool getBoundUsed() { + return useGetBound_; + }; + + /** \brief + * Returns \ref leftPrecon_. + */ + inline Preconditioner<DOFVector<double> > *getLeftPrecon() { + return leftPrecon_; + }; + + /** \brief + * Returns \ref rightPrecon_. + */ + inline Preconditioner<DOFVector<double> > *getRightPrecon() { + return rightPrecon_; + }; + + inline CoarseningManager *getCoarseningManager() { + return coarseningManager_; + }; + + /** \} */ + + // ===== setting-methods ====================================================== + + /** \name setting methods + * \{ + */ + + /** \brief + * Sets \ref feSpace_. + */ + inline void setFESpace(FiniteElemSpace* fe) { + feSpace_ = fe; + }; + + /** \brief + * Sets \ref estimator_. + */ + inline void setEstimator(Estimator* est) { + estimator_ = est; + }; + + /** \brief + * Sets \ref solver_. + */ + inline void setSolver(OEMSolver<DOFVector<double> >* sol) { solver_ = sol; }; + + /** \brief + * Sets \ref leftPrecon_. + */ + inline void setLeftPrecon(Preconditioner<DOFVector<double> > *p) { + leftPrecon_ = p; + }; + + /** \brief + * Sets \ref rightPrecon_. + */ + inline void setRightPrecon(Preconditioner<DOFVector<double> > *p) { + rightPrecon_ = p; + }; + + + inline void setMarker(Marker *marker) { + marker_ = marker; + }; + + /** \} */ + + // ===== Serializable implementation ===== + + /** \brief + * serialization + */ + virtual void serialize(::std::ostream &out); + + /** \brief + * deserialization + */ + virtual void deserialize(::std::istream &in); + + ::std::list<FileWriterInterface*> getFileWriterList() { + return fileWriters_; + }; + + protected: + /** \brief + * Used by \ref buildAfterCoarsen(). + */ + static int buildAfterCoarsenFct(ElInfo *elInfo); + + protected: + /** \brief + * Name of this problem. + */ + ::std::string name_; + + /** \brief + * FiniteElemSpace of this problem. + */ + FiniteElemSpace *feSpace_; + + /** \brief + * Mesh of this problem. + */ + Mesh *mesh_; + + /** \brief + * Responsible for element marking. + */ + Marker *marker_; + + /** \brief + * Estimator of this problem. Used in \ref estimate(). + */ + Estimator *estimator_; + + /** \brief + * Linear solver of this problem. Used in \ref solve(). + */ + OEMSolver<DOFVector<double> > *solver_; + + /** \brief + * DOFVector storing the calculated solution of the problem. + */ + DOFVector<double> *solution_; + + /** \brief + * DOFVector for the right hand side + */ + DOFVector<double> *rhs_; + + /** \brief + * System matrix + */ + DOFMatrix *systemMatrix_; + + /** \brief + * Matrix-vector multiplication + */ + MatVecMultiplier<DOFVector<double> > *matVec_; + + /** \brief + * Left preconditioner. Used in \ref solver. + */ + Preconditioner<DOFVector<double> > *leftPrecon_; + + /** \brief + * Right preconditioner. Used in \ref solver. + */ + Preconditioner<DOFVector<double> > *rightPrecon_; + + /** \brief + * Determines whether domain boundaries should be considered at assembling. + */ + bool useGetBound_; + + /** \brief + * Writes the meshes and solution after the adaption loop. + */ + ::std::list<FileWriterInterface*> fileWriters_; + + /** \brief + * All actions of mesh refinement are performed by refinementManager. + * If new refinement algorithms should be realized, one has to override + * RefinementManager and give one instance of it to AdaptStationary. + */ + RefinementManager *refinementManager_; + + /** \brief + * All actions of mesh coarsening are performed by coarseningManager. + * If new coarsening algorithms should be realized, one has to override + * CoarseningManager and give one instance of it to AdaptStationary. + */ + CoarseningManager *coarseningManager_; + + /** \brief + * Info level. + */ + int info_; + + /** \brief + * Used for mesh traversal. + */ + static ProblemScal *traversePtr_; + }; + +} + +#endif diff --git a/AMDiS/src/ProblemStatBase.h b/AMDiS/src/ProblemStatBase.h new file mode 100644 index 0000000000000000000000000000000000000000..4a6731baed959f9a2882ee9f2ee506e507f1107b --- /dev/null +++ b/AMDiS/src/ProblemStatBase.h @@ -0,0 +1,146 @@ +// ============================================================================ +// == == +// == AMDiS - Adaptive multidimensional simulations == +// == == +// ============================================================================ +// == == +// == crystal growth group == +// == == +// == Stiftung caesar == +// == Ludwig-Erhard-Allee 2 == +// == 53175 Bonn == +// == germany == +// == == +// ============================================================================ +// == == +// == http://www.caesar.de/cg/AMDiS == +// == == +// ============================================================================ + +/** \file ProblemStatBase.h */ + +/** + * \defgroup Problem Problem module + * @{ <img src="problem.png"> @} + */ + +#ifndef AMDIS_PROBLEMSTATBASE_H +#define AMDIS_PROBLEMSTATBASE_H + +#include "Flag.h" + +namespace AMDiS { + + // Flags for controling which part of the problem should be initialized + + // For all problems + const Flag INIT_FE_SPACE = 0X01L; + const Flag INIT_MESH = 0X02L; + const Flag CREATE_MESH = 0X04L; + const Flag INIT_SYSTEM = 0X08L; + const Flag INIT_SOLVER = 0X10L; + const Flag INIT_ESTIMATOR = 0X20L; + const Flag INIT_MARKER = 0X40L; + const Flag INIT_ADAPT = 0X80L; + const Flag INIT_FILEWRITER = 0X100L; + + // For time dependent problems + const Flag INIT_INITIAL_PROBLEM = 0X200L; + const Flag INIT_UH_OLD = 0X400L; + + // For non linear problems + const Flag INIT_UPDATER = 0x800L; + const Flag INIT_NONLIN_SOLVER = 0x1000L; + + // Combined Flags + const Flag INIT_NOTHING = 0X00L; + const Flag INIT_ALL = INIT_FE_SPACE | INIT_MESH | CREATE_MESH | INIT_SYSTEM | + INIT_SOLVER | INIT_ESTIMATOR | INIT_MARKER | + INIT_ADAPT | INIT_FILEWRITER | INIT_INITIAL_PROBLEM | + INIT_UH_OLD | INIT_UPDATER | INIT_NONLIN_SOLVER ; + + const Flag MESH_REFINED = 1; + const Flag MESH_COARSENED = 2; + + class AdaptInfo; + + // ============================================================================ + // ===== class ProblemStatBase ================================================ + // ============================================================================ + + /** + * \ingroup Problem + * + * \brief + * Interface for time independent problems. Concrete problems must override + * all pure virtual methods. The method \ref adaptMethodStat() should + * initiate the adaption loop which in turn uses the other pure virtual + * functions. The default stationary adaption loop is implemented in the class + * AdaptStationary. + */ + class ProblemStatBase + { + public: + virtual ~ProblemStatBase() {}; + + /** \brief + * Marks mesh elements for refinement and coarsening. + */ + virtual Flag markElements(AdaptInfo *adaptInfo) = 0; + + /** \brief + * Assembling of system matrices and vectors before refinement. + */ + virtual void buildBeforeRefine(AdaptInfo *adaptInfo, Flag flag) = 0; + + /** \brief + * Assembling of system matrices and vectors before coarsening. + */ + virtual void buildBeforeCoarsen(AdaptInfo *adaptInfo, Flag flag) = 0; + + /** \brief + * Assembling of system matrices and vectors after coarsening. + */ + virtual void buildAfterCoarsen(AdaptInfo *adaptInfo, Flag flag) = 0; + + /** \brief + * Refinement of the mesh. + */ + virtual Flag refineMesh(AdaptInfo *adaptInfo) = 0; + + /** \brief + * Coarsening of the mesh. + */ + virtual Flag coarsenMesh(AdaptInfo *adaptInfo) = 0; + + /** \brief + * Solves the assembled system. The result is an approximative solution. + */ + virtual void solve(AdaptInfo *adaptInfo) = 0; + + /** \brief + * A posteriori error estimation of the calculated solution. Should store + * a local error estimation at each elements leaf data and return the + * total error sum. + */ + virtual void estimate(AdaptInfo *adaptInfo) = 0; + + /** \brief + * Returns the name of the problem. + */ + virtual const ::std::string& getName() = 0; + + /** \brief + * Function that serializes the problem plus information about the iteration. + */ + virtual void serialize(::std::ostream &out) = 0; + + /** \brief + * Function that deserializes the problem plus information about the iteration. + */ + virtual void deserialize(::std::istream &in) = 0; + }; + +} + +#endif diff --git a/AMDiS/src/ProblemTimeInterface.h b/AMDiS/src/ProblemTimeInterface.h new file mode 100644 index 0000000000000000000000000000000000000000..f248cac44dec551fa06903a9b8c7210312011d69 --- /dev/null +++ b/AMDiS/src/ProblemTimeInterface.h @@ -0,0 +1,85 @@ +// ============================================================================ +// == == +// == AMDiS - Adaptive multidimensional simulations == +// == == +// ============================================================================ +// == == +// == crystal growth group == +// == == +// == Stiftung caesar == +// == Ludwig-Erhard-Allee 2 == +// == 53175 Bonn == +// == germany == +// == == +// ============================================================================ +// == == +// == http://www.caesar.de/cg/AMDiS == +// == == +// ============================================================================ + +/** \file ProblemTimeInterface.h */ + +#ifndef AMDIS_PROBLEMTIMEINTERFACE_H +#define AMDIS_PROBLEMTIMEINTERFACE_H + +#include "Flag.h" + +namespace AMDiS { + + class AdaptInfo; + + // ============================================================================ + // ===== class ProblemTimeInterface =========================================== + // ============================================================================ + + /** + * \ingroup Problem + * + * \brief + * Interface for time dependent problems. Concrete problems must override + * all pure virtual methods. + */ + class ProblemTimeInterface + { + public: + virtual ~ProblemTimeInterface() {}; + + /** \brief + * Executes all needed operations when the simulation time changes. + */ + virtual void setTime(AdaptInfo *adaptInfo) = 0; + + /** \brief + * Called at the beginning of each timestep + */ + virtual void initTimestep(AdaptInfo *adaptInfo) = 0; + + /** \brief + * Called at the end of each timestep. + */ + virtual void closeTimestep(AdaptInfo *adaptInfo) = 0; + + /** \brief + * Solves the initial problem. + */ + virtual void solveInitialProblem(AdaptInfo *adaptInfo) = 0; + + /** \brief + * Solves the initial problem. + */ + virtual void transferInitialSolution(AdaptInfo *adaptInfo) = 0; + + /** \brief + * Function that serializes the problem plus information about the iteration. + */ + virtual void serialize(::std::ostream &out) = 0; + + /** \brief + * Function that deserializes the problem plus information about the iteration. + */ + virtual void deserialize(::std::istream &in) = 0; + }; + +} + +#endif diff --git a/AMDiS/src/ProblemVec.cc b/AMDiS/src/ProblemVec.cc new file mode 100644 index 0000000000000000000000000000000000000000..d92c48adb7b17a9dd2722ed9739940463b5e1897 --- /dev/null +++ b/AMDiS/src/ProblemVec.cc @@ -0,0 +1,921 @@ +#include "ProblemVec.h" +#include "RecoveryEstimator.h" +#include "Serializer.h" +#include "DualTraverse.h" +#include "AbstractFunction.h" +#include "Operator.h" +#include "SystemVector.h" +#include "DOFMatrix.h" +#include "FiniteElemSpace.h" +#include "Estimator.h" +#include "Marker.h" +#include "AdaptInfo.h" +#include "FileWriter.h" +#include "CoarseningManager.h" +#include "RefinementManager.h" +#include "Mesh.h" +#include "OEMSolver.h" +#include "Preconditioner.h" +#include "MatVecMultiplier.h" +#include "DirichletBC.h" +#include "RobinBC.h" +#include "PeriodicBC.h" +#include "Lagrange.h" + +namespace AMDiS { + + ProblemVec *ProblemVec::traversePtr_ = NULL; + + void ProblemVec::initialize(Flag initFlag, + ProblemVec *adoptProblem, + Flag adoptFlag) + { + FUNCNAME("ProblemVec::initialize()"); + + // === create meshes === + if (meshes_.size() != 0) { + WARNING("meshes already created\n"); + } else { + if (initFlag.isSet(CREATE_MESH) || + ((!adoptFlag.isSet(INIT_MESH))&& + (initFlag.isSet(INIT_SYSTEM) || initFlag.isSet(INIT_FE_SPACE)))) { + createMesh(); + } + if (adoptProblem && + (adoptFlag.isSet(INIT_MESH) || + adoptFlag.isSet(INIT_SYSTEM) || + adoptFlag.isSet(INIT_FE_SPACE))) { + meshes_ = adoptProblem->getMeshes(); + componentMeshes_ = adoptProblem->componentMeshes_; + refinementManager_ = adoptProblem->refinementManager_; + coarseningManager_ = adoptProblem->coarseningManager_; + } + } + + if (meshes_.size() == 0) + WARNING("no mesh created\n"); + + // === create fespace === + if (feSpaces_.size() != 0) { + WARNING("feSpaces already created\n"); + } else { + if (initFlag.isSet(INIT_FE_SPACE) || + (initFlag.isSet(INIT_SYSTEM)&&!adoptFlag.isSet(INIT_FE_SPACE))) { + createFESpace(); + } + if (adoptProblem && + (adoptFlag.isSet(INIT_FE_SPACE) || adoptFlag.isSet(INIT_SYSTEM))) { + feSpaces_ = adoptProblem->getFESpaces(); + componentSpaces_ = adoptProblem->componentSpaces_; + } + } + + if (feSpaces_.size() == 0) + WARNING("no feSpace created\n"); + + // === create system === + if (initFlag.isSet(INIT_SYSTEM)) { + createMatricesAndVectors(); + } + if (adoptProblem && adoptFlag.isSet(INIT_SYSTEM)) { + solution_ = adoptProblem->getSolution(); + rhs_ = adoptProblem->getRHS(); + systemMatrix_ = adoptProblem->getSystemMatrix(); + } + + // === create solver === + if (solver_) { + WARNING("solver already created\n"); + } else { + if (initFlag.isSet(INIT_SOLVER)) { + createSolver(); + } + if (adoptProblem && adoptFlag.isSet(INIT_SOLVER)) { + TEST_EXIT(!solver_)("solver already created\n"); + solver_ = adoptProblem->getSolver(); + } + } + + if (!solver_) + WARNING("no solver created\n"); + + // === create estimator === + if (initFlag.isSet(INIT_ESTIMATOR)) { + createEstimator(); + } + if (adoptProblem && adoptFlag.isSet(INIT_ESTIMATOR)) { + estimator_ = adoptProblem->getEstimator(); + } + + // === create marker === + if (initFlag.isSet(INIT_MARKER)) { + createMarker(); + } + if (adoptProblem && adoptFlag.isSet(INIT_MARKER)) { + marker_ = adoptProblem->getMarker(); + } + + + // === create file writer === + if (initFlag.isSet(INIT_FILEWRITER)) { + createFileWriter(); + } + + + // === read serialization and init mesh === + + // There are two possiblities where the user can define a serialization + // to be read from disk. Either by providing the parameter -rs when executing + // the program or in the init file. The -rs parameter is always checked first, + // because it can be added automatically when rescheduling the program + // before timeout of the runqueue. + + int readSerialization = 0; + ::std::string serializationFilename = ""; + GET_PARAMETER(0, "argv->rs", &serializationFilename); + + // If the parameter -rs is set, we do nothing here, because the problem will be + // deserialized in the constructor of a following AdaptInstationary initialization. + if (!serializationFilename.compare("")) { + int readSerializationWithAdaptInfo = 0; + + GET_PARAMETER(0, name_ + "->input->read serialization", "%d", + &readSerialization); + GET_PARAMETER(0, name_ + "->input->serialization with adaptinfo", "%d", + &readSerializationWithAdaptInfo); + + // The serialization file is only read, if the adaptInfo part should not be used. + // If the adaptInfo part should be also read, the serialization file will be read + // in the constructor of the AdaptInstationary problem, because we do not have here + // the adaptInfo object. + if (readSerialization && !readSerializationWithAdaptInfo) { + GET_PARAMETER(0, name_ + "->input->serialization filename", + &serializationFilename); + TEST_EXIT(serializationFilename != "")("no serialization file\n"); + + MSG("Deserialization from file: %s\n", serializationFilename.c_str()); + ::std::ifstream in(serializationFilename.c_str()); + deserialize(in); + in.close(); + } else { + // Initialize the meshes if there is no serialization file. + for (int i = 0; i < static_cast<int>(meshes_.size()); i++) { + if (initFlag.isSet(INIT_MESH) && + meshes_[i] && + !(meshes_[i]->isInitialized())) { + meshes_[i]->initialize(); + + // do global refinements + int globalRefinements = 0; + GET_PARAMETER(0, meshes_[0]->getName() + "->global refinements", "%d", + &globalRefinements); + for (int gr = 0; gr < static_cast<int>(meshes_.size()); gr++) { + refinementManager_->globalRefine(meshes_[gr], globalRefinements); + } + } + } + } + } + + doOtherStuff(); + } + + void ProblemVec::createMesh() + { + FUNCNAME("ProblemVec::createMesh()"); + + componentMeshes_.resize(numComponents_); + ::std::map<int, Mesh*> meshForRefinementSet; + char number[3]; + + ::std::string meshName(""); + GET_PARAMETER(0, name_ + "->mesh", &meshName); + TEST_EXIT(meshName != "")("no mesh name spezified\n"); + int dim = 0; + GET_PARAMETER(0, name_ + "->dim", "%d", &dim); + TEST_EXIT(dim)("no problem dimension spezified!\n"); + + int i, refSet; + for(i = 0; i < numComponents_; i++) { + sprintf(number, "%d", i); + refSet = -1; + GET_PARAMETER(0, name_ + "->refinement set[" + number + "]","%d", &refSet); + if(refSet < 0) { + WARNING("refinement set for component %d not set\n", i); + refSet = 0; + } + if(meshForRefinementSet[refSet] == NULL) { + Mesh *newMesh = NEW Mesh(meshName, dim); + meshForRefinementSet[refSet] = newMesh; + meshes_.push_back(newMesh); + } + componentMeshes_[i] = meshForRefinementSet[refSet]; + } + switch(dim) { + case 1: + coarseningManager_ = NEW CoarseningManager1d(); + refinementManager_ = NEW RefinementManager1d(); + break; + case 2: + coarseningManager_ = NEW CoarseningManager2d(); + refinementManager_ = NEW RefinementManager2d(); + break; + case 3: + coarseningManager_ = NEW CoarseningManager3d(); + refinementManager_ = NEW RefinementManager3d(); + break; + default: + ERROR_EXIT("invalid dim!\n"); + } + } + + void ProblemVec::createFESpace() + { + FUNCNAME("ProblemVec::createFESpace()"); + + int degree = 1; + char number[3]; + + ::std::map< ::std::pair<Mesh*, int>, FiniteElemSpace*> feSpaceMap; + int i, dim = -1; + GET_PARAMETER(0, name_ + "->dim", "%d", &dim); + TEST_EXIT(dim != -1)("no problem dimension spezified!\n"); + + componentSpaces_.resize(numComponents_, NULL); + + for(i = 0; i < numComponents_; i++) { + sprintf(number, "%d", i); + GET_PARAMETER(0, name_ + "->polynomial degree[" + number + "]","%d", °ree); + + TEST_EXIT(componentSpaces_[i] == NULL)("feSpace already created\n"); + + if (feSpaceMap[::std::pair<Mesh*, int>(componentMeshes_[i], degree)] == NULL) { + FiniteElemSpace *newFESpace = + FiniteElemSpace::provideFESpace(NULL, + Lagrange::getLagrange(dim, degree), + componentMeshes_[i], + name_ + "->feSpace"); + feSpaceMap[::std::pair<Mesh*, int>(componentMeshes_[i], degree)] = newFESpace; + feSpaces_.push_back(newFESpace); + } + componentSpaces_[i] = + feSpaceMap[::std::pair<Mesh*, int>(componentMeshes_[i], degree)]; + } + + // create dof admin for vertex dofs if neccessary + for (i = 0; i < static_cast<int>(meshes_.size()); i++) { + if (meshes_[i]->getNumberOfDOFs(VERTEX) == 0) { + DimVec<int> ln_dof(meshes_[i]->getDim(), DEFAULT_VALUE, 0); + ln_dof[VERTEX]= 1; + meshes_[i]->createDOFAdmin("vertex dofs", ln_dof); + } + } + } + + void ProblemVec::createMatricesAndVectors() + { + FUNCNAME("ProblemVec::createMatricesAndVectors()"); + + int i; + + // === create vectors and system matrix === + + systemMatrix_ = NEW Matrix<DOFMatrix*>(numComponents_, numComponents_); + systemMatrix_->set(NULL); + rhs_ = NEW SystemVector("rhs", componentSpaces_, numComponents_); + solution_ = NEW SystemVector("solution", componentSpaces_, numComponents_); + + char number[10]; + ::std::string numberedName; + for (i = 0; i < numComponents_; i++) { + (*systemMatrix_)[i][i] = NEW DOFMatrix(componentSpaces_[i], + componentSpaces_[i], "A_ii"); + (*systemMatrix_)[i][i]->setCoupleMatrix(false); + sprintf(number, "[%d]", i); + numberedName = "rhs" + ::std::string(number); + rhs_->setDOFVector(i, NEW DOFVector<double>(componentSpaces_[i], numberedName)); + numberedName = name_ + ::std::string(number); + solution_->setDOFVector(i, NEW DOFVector<double>(componentSpaces_[i], + numberedName)); + solution_->getDOFVector(i)->refineInterpol(true); + solution_->getDOFVector(i)->setCoarsenOperation(COARSE_INTERPOL); + solution_->getDOFVector(i)->set(0.0); + } + + // === create matVec === + matVec_ = NEW StandardMatVec<Matrix<DOFMatrix*>, SystemVector>(systemMatrix_); + } + + void ProblemVec::createSolver() + { + FUNCNAME("ProblemVec::createSolver()"); + + // === create solver === + ::std::string solverType("no"); + GET_PARAMETER(0, name_ + "->solver", &solverType); + OEMSolverCreator<SystemVector> *solverCreator = + dynamic_cast<OEMSolverCreator<SystemVector>*>( + CreatorMap<OEMSolver<SystemVector> > + ::getCreator(solverType) + ); + TEST_EXIT(solverCreator)("no solver type\n"); + solverCreator->setName(name_ + "->solver"); + solver_ = solverCreator->create(); + solver_->initParameters(); + + // === create preconditioners === + ::std::string preconType("no"); + + PreconditionerScal *scalPrecon; + PreconditionerVec *vecPrecon = NEW PreconditionerVec(numComponents_); + + GET_PARAMETER(0, name_ + "->solver->left precon", &preconType); + CreatorInterface<PreconditionerScal> *preconCreator = + CreatorMap<PreconditionerScal>::getCreator(preconType); + + int i, j; + + if (!preconCreator->isNullCreator()) { + dynamic_cast<PreconditionerScalCreator*>(preconCreator)-> + setName(name_ + "->solver->left precon"); + + for(i = 0; i < numComponents_; i++) { + dynamic_cast<PreconditionerScalCreator*>(preconCreator)-> + setSizeAndRow(numComponents_, i); + + scalPrecon = preconCreator->create(); + for(j = 0; j < numComponents_; j++) { + scalPrecon->setMatrix(&(*systemMatrix_)[i][j], j); + } + vecPrecon->setScalarPrecon(i, scalPrecon); + } + leftPrecon_ = vecPrecon; + } + + + vecPrecon = NEW PreconditionerVec(numComponents_); + + GET_PARAMETER(0, name_ + "->solver->right precon", &preconType); + preconCreator = + CreatorMap<PreconditionerScal>::getCreator(preconType); + + if(!preconCreator->isNullCreator()) { + dynamic_cast<PreconditionerScalCreator*>(preconCreator)-> + setName(name_ + "->solver->left precon"); + + + for(i = 0; i < numComponents_; i++) { + dynamic_cast<PreconditionerScalCreator*>(preconCreator)-> + setSizeAndRow(numComponents_, i); + + scalPrecon = preconCreator->create(); + for(j = 0; j < numComponents_; j++) { + scalPrecon->setMatrix(&(*systemMatrix_)[i][j], j); + } + vecPrecon->setScalarPrecon(i, scalPrecon); + } + rightPrecon_ = vecPrecon; + } + + + // === create vector creator === + solver_->setVectorCreator(NEW SystemVector::Creator("temp", + componentSpaces_, + numComponents_)); + } + + void ProblemVec::createEstimator() + { + FUNCNAME("ProblemVec::createEstimator()"); + + int i, j; + + // create and set leaf data prototype + for(i = 0; i < static_cast<int>(meshes_.size()); i++) { + meshes_[i]->setElementDataPrototype + (NEW LeafDataEstimatableVec(NEW LeafDataCoarsenableVec)); + } + + char number[3]; + ::std::string estName; + + for(i = 0; i < numComponents_; i++) { + TEST_EXIT(estimator_[i] == NULL)("estimator already created\n"); + sprintf(number, "%d", i); + estName = name_ + "->estimator[" + ::std::string(number) + "]"; + + // === create estimator === + ::std::string estimatorType("no"); + GET_PARAMETER(0, estName, &estimatorType); + EstimatorCreator *estimatorCreator = + dynamic_cast<EstimatorCreator*>( + CreatorMap<Estimator>::getCreator(estimatorType)); + if(estimatorCreator) { + estimatorCreator->setName(estName); + estimatorCreator->setRow(i); + if(estimatorType == "recovery") { + dynamic_cast<RecoveryEstimator::Creator*>(estimatorCreator)-> + setSolution(solution_->getDOFVector(i)); + } + estimator_[i] = estimatorCreator->create(); + } + + + if(estimator_[i]) { + for(j=0; j < numComponents_; j++) { + estimator_[i]->addSystem((*systemMatrix_)[i][j], + solution_->getDOFVector(j), + rhs_->getDOFVector(j)); + } + } + } + } + + void ProblemVec::createMarker() + { + FUNCNAME("ProblemVec::createMarker()"); + + ::std::string numberedName; + char number[10]; + int i; + int numMarkersCreated = 0; + // marker_.resize(numComponents_); + for(i = 0; i < numComponents_; i++) { + sprintf(number, "[%d]", i); + numberedName = name_ + "->marker" + ::std::string(number); + if((marker_[i] = Marker::createMarker(numberedName, i))) { + ++numMarkersCreated; + if(numMarkersCreated > 1) + marker_[i]->setMaximumMarking(true); + } + } + } + + void ProblemVec::createFileWriter() + { + FUNCNAME("ProblemVec::createFileWriter()"); + + + // Create one filewriter for all components of the problem + ::std::string numberedName = name_ + "->output"; + ::std::string filename = ""; + GET_PARAMETER(0, numberedName + "->filename", &filename); + + if (filename != "") { + ::std::vector< DOFVector<double>* > solutionList(numComponents_); + + for (int i = 0; i < numComponents_; i++) { + TEST_EXIT(componentMeshes_[0] == componentMeshes_[i]) + ("All Meshes have to be equal to write a vector file.\n"); + + solutionList[i] = solution_->getDOFVector(i); + } + + fileWriters_.push_back(NEW FileWriter(numberedName, + componentMeshes_[0], + solutionList)); + } + + + // Create own filewriters for each components of the problem + char number[10]; + for (int i = 0; i < numComponents_; i++) { + sprintf(number, "[%d]", i); + numberedName = name_ + "->output" + ::std::string(number); + filename = ""; + GET_PARAMETER(0, numberedName + "->filename", &filename); + + if (filename != "") { + fileWriters_.push_back(NEW FileWriter(numberedName, + componentMeshes_[i], + solution_->getDOFVector(i))); + } + } + + + // Check for serializer + int writeSerialization = 0; + GET_PARAMETER(0, name_ + "->write serialization", "%d", &writeSerialization); + if (writeSerialization) { + MSG("Use are using the obsolete parameter: %s->write serialization\n", name_.c_str()); + MSG("Please use instead the following parameter: %s->output->write serialization\n", name_.c_str()); + ERROR_EXIT("Usage of an obsolete parameter (see message above)!\n"); + } + + GET_PARAMETER(0, name_ + "->output->write serialization", "%d", &writeSerialization); + if (writeSerialization) { + fileWriters_.push_back(NEW Serializer<ProblemVec>(this)); + } + } + + void ProblemVec::doOtherStuff() + { + } + + void ProblemVec::solve(AdaptInfo *adaptInfo) + { + FUNCNAME("Problem::solve()"); + + if (!solver_) { + WARNING("no solver\n"); + return; + } + +#ifdef _OPENMP + double wtime = omp_get_wtime(); +#endif + + clock_t first = clock(); + int iter = solver_->solve(matVec_, solution_, rhs_, leftPrecon_, rightPrecon_); + +#ifdef _OPENMP + INFO(info_, 8)("solution of discrete system needed %.5f seconds system time / %.5f seconds wallclock time\n", + TIME_USED(first, clock()), + omp_get_wtime() - wtime); +#else + INFO(info_, 8)("solution of discrete system needed %.5f seconds\n", + TIME_USED(first, clock())); +#endif + + + adaptInfo->setSolverIterations(iter); + adaptInfo->setMaxSolverIterations(solver_->getMaxIterations()); + adaptInfo->setSolverTolerance(solver_->getTolerance()); + adaptInfo->setSolverResidual(solver_->getResidual()); + } + + void ProblemVec::estimate(AdaptInfo *adaptInfo) + { + FUNCNAME("ProblemVec::estimate()"); + + clock_t first = clock(); + + for (int i = 0; i < numComponents_; i++) { + Estimator *scalEstimator = estimator_[i]; + + if (scalEstimator) { + scalEstimator->estimate(adaptInfo->getTimestep()); + adaptInfo->setEstSum(scalEstimator->getErrorSum(), i); + adaptInfo->setEstMax(scalEstimator->getErrorMax(), i); + adaptInfo->setTimeEstSum(scalEstimator->getTimeEst(), i); + adaptInfo->setTimeEstMax(scalEstimator->getTimeEstMax(), i); + } else { + WARNING("no estimator for component %d\n" , i); + } + } + + INFO(info_,8)("estimation of the error needed %.5f seconds\n", + TIME_USED(first,clock())); + } + + Flag ProblemVec::markElements(AdaptInfo *adaptInfo) + { + FUNCNAME("ProblemVec::markElements()"); + + // to enforce albert-like behavior: refinement even if space tolerance + // here is reached already because of time adaption + allowFirstRefinement(); + + Flag markFlag = 0; + for (int i = 0; i < numComponents_; i++) { + if (marker_[i]) { + markFlag |= marker_[i]->markMesh(adaptInfo, componentMeshes_[i]); + } else { + WARNING("no marker for component %d\n", i); + } + } + return markFlag; + } + + Flag ProblemVec::refineMesh(AdaptInfo *adaptInfo) + { + FUNCNAME("ProblemVec::refineMesh()"); + + int numMeshes = static_cast<int>(meshes_.size()); + Flag refineFlag = 0; + for (int i = 0; i < numMeshes; i++) { + refineFlag |= refinementManager_->refineMesh(meshes_[i]); + } + return refineFlag; + } + + Flag ProblemVec::coarsenMesh(AdaptInfo *adaptInfo) + { + FUNCNAME("ProblemVec::coarsenMesh()"); + + int i, numMeshes = static_cast<int>(meshes_.size()); + Flag coarsenFlag = 0; + for(i = 0; i < numMeshes; i++) { + if(adaptInfo->isCoarseningAllowed(i)) { + coarsenFlag |= coarseningManager_->coarsenMesh(meshes_[i]); + + WARNING("coarsening for component %d no allowed\n", i); + } + } + return coarsenFlag; + } + + Flag ProblemVec::oneIteration(AdaptInfo *adaptInfo, Flag toDo) + { + FUNCNAME("ProblemVec::oneIteration()"); + + if (allowFirstRef_) { + for (int i = 0; i < numComponents_; i++) { + adaptInfo->allowRefinement(true, i); + } + allowFirstRef_ = false; + } else { + for (int i = 0; i < numComponents_; i++) { + if (adaptInfo->spaceToleranceReached(i)) { + adaptInfo->allowRefinement(false, i); + } else { + adaptInfo->allowRefinement(true, i); + } + } + } + + return StandardProblemIteration::oneIteration(adaptInfo, toDo); + } + + void ProblemVec::buildAfterCoarsen(AdaptInfo *adaptInfo, Flag flag) + { + FUNCNAME("ProblemVec::buildAfterCoarsen()"); + + clock_t first = clock(); + + int numMeshes = static_cast<int>(meshes_.size()); + for (int i = 0; i < numMeshes; i++) { + meshes_[i]->dofCompress(); + } + + Flag assembleFlag = + flag | + (*systemMatrix_)[0][0]->getAssembleFlag() | + rhs_->getDOFVector(0)->getAssembleFlag() | + Mesh::CALL_LEAF_EL | + Mesh::FILL_COORDS | + Mesh::FILL_DET | + Mesh::FILL_GRD_LAMBDA | + Mesh::FILL_NEIGH; + + if (useGetBound_) { + assembleFlag |= Mesh::FILL_BOUND; + } + + for (int i = 0; i < numComponents_; i++) { + MSG("%d DOFs for %s\n", + componentSpaces_[i]->getAdmin()->getUsedSize(), + componentSpaces_[i]->getName().c_str()); + + rhs_->getDOFVector(i)->set(0.0); + for (int j = 0; j < numComponents_; j++) { + if ((*systemMatrix_)[i][j]) + (*systemMatrix_)[i][j]->clear(); + } + } + + TraverseStack stack; + DualTraverse dualStack; + ElInfo *elInfo; + + for (int i = 0; i < numComponents_; i++) { + for (int j = 0; j < numComponents_; j++) { + DOFMatrix *matrix = (*systemMatrix_)[i][j]; + + if (componentMeshes_[i] != componentMeshes_[j]) { + ERROR_EXIT("not yet\n"); + } else { + if (matrix && matrix->getBoundaryManager()) + matrix->getBoundaryManager()->initMatrix(matrix); + + elInfo = stack.traverseFirst(componentMeshes_[i], -1, assembleFlag); + while (elInfo) { + const BoundaryType *bound = + useGetBound_ ? + componentSpaces_[i]->getBasisFcts()->getBound(elInfo, NULL) : + NULL; + if (matrix) { + matrix->assemble(1.0, elInfo, bound); + if (matrix->getBoundaryManager()) { + matrix-> + getBoundaryManager()-> + fillBoundaryConditions(elInfo, matrix); + } + } + if (i == j) { + rhs_->getDOFVector(i)->assemble(1.0, elInfo, bound); + } + elInfo = stack.traverseNext(elInfo); + } + + if (matrix && matrix->getBoundaryManager()) + matrix->getBoundaryManager()->exitMatrix(matrix); + } + } + + // fill boundary conditions + if (rhs_->getDOFVector(i)->getBoundaryManager()) + rhs_->getDOFVector(i)->getBoundaryManager()->initVector(rhs_->getDOFVector(i)); + if (solution_->getDOFVector(i)->getBoundaryManager()) + solution_->getDOFVector(i)->getBoundaryManager()->initVector(solution_->getDOFVector(i)); + + elInfo = stack.traverseFirst(componentMeshes_[i], -1, assembleFlag); + while (elInfo) { + if(rhs_->getDOFVector(i)->getBoundaryManager()) + rhs_->getDOFVector(i)->getBoundaryManager()-> + fillBoundaryConditions(elInfo, rhs_->getDOFVector(i)); + if(solution_->getDOFVector(i)->getBoundaryManager()) + solution_->getDOFVector(i)->getBoundaryManager()-> + fillBoundaryConditions(elInfo, solution_->getDOFVector(i)); + elInfo = stack.traverseNext(elInfo); + } + if (rhs_->getDOFVector(i)->getBoundaryManager()) + rhs_->getDOFVector(i)->getBoundaryManager()->exitVector(rhs_->getDOFVector(i)); + if (solution_->getDOFVector(i)->getBoundaryManager()) + solution_->getDOFVector(i)->getBoundaryManager()->exitVector(solution_->getDOFVector(i)); + } + INFO(info_, 8)("buildAfterCoarsen needed %.5f seconds\n", + TIME_USED(first,clock())); + + +// int memsize = 0; +// for (int i = 0; i < numComponents_; i++) { +// for (int j = 0; j < numComponents_; j++) { +// DOFMatrix *matrix = (*systemMatrix_)[i][j]; +// memsize += (*matrix).memsize(); +// } +// } + +// ::std::cout << "SIZE: " << memsize << ::std::endl; + + } + + void ProblemVec::writeFiles(AdaptInfo *adaptInfo, bool force) + { + FUNCNAME("ProblemVec::writeFiles()"); + + ::std::list<FileWriterInterface*>::iterator it; + for(it = fileWriters_.begin(); it != fileWriters_.end(); ++it) { + (*it)->writeFiles(adaptInfo, force); + } + } + + void ProblemVec::interpolInitialSolution(::std::vector<AbstractFunction<double, WorldVector<double> >*> *fct) + { + FUNCNAME("ProblemVec::interpolInitialSolution()"); + + solution_->interpol(fct); + } + + void ProblemVec::addMatrixOperator(Operator *op, + int i, int j, + double *factor, + double *estFactor) + { + FUNCNAME("ProblemVec::addMatrixOperator()"); + + if(!(*systemMatrix_)[i][j]) { + TEST_EXIT(i != j)("should have been created already\n"); + (*systemMatrix_)[i][j] = NEW DOFMatrix(componentSpaces_[i], + componentSpaces_[j], + ""); + (*systemMatrix_)[i][j]->setCoupleMatrix(true); + + (*systemMatrix_)[i][j]->getBoundaryManager()-> + setBoundaryConditionMap((*systemMatrix_)[i][i]->getBoundaryManager()-> + getBoundaryConditionMap()); + } + (*systemMatrix_)[i][j]->addOperator(op, factor, estFactor); + } + + void ProblemVec::addVectorOperator(Operator *op, int i, + double *factor, + double *estFactor) + { + FUNCNAME("ProblemVec::addVectorOperator()"); + + rhs_->getDOFVector(i)->addOperator(op, factor, estFactor); + } + + void ProblemVec::addDirichletBC(BoundaryType type, int system, + AbstractFunction<double, WorldVector<double> >* b) + { + FUNCNAME("ProblemVec::addDirichletBC()"); + + DirichletBC *dirichlet = new DirichletBC(type, + b, + componentSpaces_[system]); + for (int i = 0; i < numComponents_; i++) { + if (systemMatrix_ && (*systemMatrix_)[system][i]) { + (*systemMatrix_)[system][i]->getBoundaryManager()->addBoundaryCondition(dirichlet); + } + } + if (rhs_) + rhs_->getDOFVector(system)->getBoundaryManager()->addBoundaryCondition(dirichlet); + if (solution_) + solution_->getDOFVector(system)->getBoundaryManager()->addBoundaryCondition(dirichlet); + } + + void ProblemVec::addNeumannBC(BoundaryType type, int row, int col, + AbstractFunction<double, WorldVector<double> > *n) + { + FUNCNAME("ProblemVec::addNeumannBC()"); + + NeumannBC *neumann = + new NeumannBC(type, n, + componentSpaces_[row], + componentSpaces_[col]); + if(rhs_) + rhs_->getDOFVector(row)->getBoundaryManager()->addBoundaryCondition(neumann); + } + + void ProblemVec::addRobinBC(BoundaryType type, int row, int col, + AbstractFunction<double, WorldVector<double> > *n, + AbstractFunction<double, WorldVector<double> > *r) + { + FUNCNAME("ProblemVec::addRobinBC()"); + + RobinBC *robin = + new RobinBC(type, n, r, + componentSpaces_[row], + componentSpaces_[col]); + if(rhs_) + rhs_->getDOFVector(row)->getBoundaryManager()->addBoundaryCondition(robin); + if(systemMatrix_ && (*systemMatrix_)[row][col]) { + (*systemMatrix_)[row][col]->getBoundaryManager()->addBoundaryCondition(robin); + } + } + + void ProblemVec::addPeriodicBC(BoundaryType type, int row, int col) + { + FUNCNAME("ProblemVec::addPeriodicBC()"); + + FiniteElemSpace *feSpace = componentSpaces_[row]; + + PeriodicBC *periodic = new PeriodicBC(type, feSpace); + + // TEST_EXIT(mesh->getPeriodicBCMap()[type] == NULL) + // ("periodic condition already set in mesh\n"); + // mesh->getPeriodicBCMap()[type] = periodic; + + if(systemMatrix_ && (*systemMatrix_)[row][col]) + (*systemMatrix_)[row][col]->getBoundaryManager()->addBoundaryCondition(periodic); + if(rhs_) + rhs_->getDOFVector(row)->getBoundaryManager()-> + addBoundaryCondition(periodic); + } + + void ProblemVec::serialize(::std::ostream &out) + { + FUNCNAME("ProblemVec::serialize()"); + + SerializerUtil::serializeBool(out, &allowFirstRef_); + + for (int i = 0; i < static_cast<int>(meshes_.size()); i++) { + meshes_[i]->serialize(out); + } + + solution_->serialize(out); + } + + void ProblemVec::deserialize(::std::istream &in) + { + FUNCNAME("ProblemVec::deserialize()"); + + SerializerUtil::deserializeBool(in, &allowFirstRef_); + + for (int i = 0; i < static_cast<int>(meshes_.size()); i++) { + meshes_[i]->deserialize(in); + } + + solution_->deserialize(in); + } + + void axpy(double a, + const Matrix<DOFMatrix*> &x, + Matrix<DOFMatrix*> &y) + { + FUNCNAME("ProblemVec::axpy()"); + + int numRows = x.getNumRows(), numCols = x.getNumCols(); + int i, j; + const DOFMatrix *xMatrix; + DOFMatrix *yMatrix; + + for(i = 0; i < numRows; i++) { + for(j = 0; j < numCols; j++) { + xMatrix = x[i][j]; + yMatrix = y[i][j]; + if(!xMatrix) continue; + if(!yMatrix) { + yMatrix = NEW DOFMatrix(xMatrix->getRowFESpace(), + xMatrix->getColFESpace(), ""); + y[i][j] = yMatrix; + } + yMatrix->axpy(a, *xMatrix, *yMatrix); + } + } + } + +} + diff --git a/AMDiS/src/ProblemVec.h b/AMDiS/src/ProblemVec.h new file mode 100644 index 0000000000000000000000000000000000000000..dfc649e6dd59e4ea93ade77e70d77efd4b6ea7af --- /dev/null +++ b/AMDiS/src/ProblemVec.h @@ -0,0 +1,596 @@ +// ============================================================================ +// == == +// == AMDiS - Adaptive multidimensional simulations == +// == == +// ============================================================================ +// == == +// == crystal growth group == +// == == +// == Stiftung caesar == +// == Ludwig-Erhard-Allee 2 == +// == 53175 Bonn == +// == germany == +// == == +// ============================================================================ +// == == +// == http://www.caesar.de/cg/AMDiS == +// == == +// ============================================================================ + +/** \file ProblemVec.h */ + +#ifndef AMDIS_PROBLEMVEC_H +#define AMDIS_PROBLEMVEC_H + +#include "ProblemStatBase.h" +#include "Parameters.h" +#include "Boundary.h" +#include "MatrixVector.h" +#include "StandardProblemIteration.h" +#include <vector> +#include <list> + +namespace AMDiS { + + template<typename t1, typename t2> class AbstractFunction; + class Operator; + class SystemVector; + class DOFMatrix; + class FiniteElemSpace; + class Estimator; + class Marker; + class AdaptStationary; + class AdaptInfo; + class FileWriterInterface; + class CoarseningManager; + class RefinementManager; + class Mesh; + template<typename T> class OEMSolver; + template<typename T> class Preconditioner; + template<typename T> class MatVecMultiplier; + + class ProblemVec : public ProblemStatBase, + public StandardProblemIteration + { + public: + /** \brief + * constructor + */ + ProblemVec(const char* name, + ProblemIterationInterface *problemIteration = NULL) + : StandardProblemIteration(this), + name_(name), + numComponents_(-1), + solver_(NULL), + solution_(NULL), + rhs_(NULL), + systemMatrix_(NULL), + matVec_(NULL), + leftPrecon_(NULL), + rightPrecon_(NULL), + useGetBound_(true), + info_(10), + allowFirstRef_(false) + { + GET_PARAMETER(0, name_ + "->components", "%d", &numComponents_); + TEST_EXIT(numComponents_ > 0)("components not set!\n"); + estimator_.resize(numComponents_, NULL); + marker_.resize(numComponents_, NULL); + }; + + /** \brief + * destructor + */ + virtual ~ProblemVec() {}; + + /** \brief + * Initialisation of the problem. + */ + virtual void initialize(Flag initFlag, + ProblemVec *adoptProblem = NULL, + Flag adoptFlag = INIT_NOTHING); + + + /** \brief + * Used in \ref initialize(). + */ + virtual void createMesh(); + + /** \brief + * Used in \ref initialize(). + */ + virtual void createFESpace(); + + /** \brief + * Used in \ref initialize(). + */ + virtual void createMatricesAndVectors(); + + /** \brief + * Used in \ref initialize(). + */ + virtual void createSolver(); + + /** \brief + * Used in \ref initialize(). + */ + virtual void createEstimator(); + + /** \brief + * Used in \ref initialize(). + */ + virtual void createMarker(); + + /** \brief + * Used in \ref initialize(). + */ + virtual void createFileWriter(); + + /** \brief + * Used in \ref initialize(). + */ + virtual void doOtherStuff(); + + /** \brief + * Implementation of ProblemStatBase::solve(). Deligates the solving + * of problems system to \ref solver. + */ + virtual void solve(AdaptInfo *adaptInfo); + + /** \brief + * Implementation of ProblemStatBase::estimate(). Deligates the estimation + * to \ref estimator. + */ + virtual void estimate(AdaptInfo *adaptInfo); + + /** \brief + * Implementation of ProblemStatBase::markElements(). + * Deligated to \ref adapt. + */ + virtual Flag markElements(AdaptInfo *adaptInfo); + + /** \brief + * Implementation of ProblemStatBase::refineMesh(). Deligated to the + * RefinementManager of \ref adapt. + */ + virtual Flag refineMesh(AdaptInfo *adaptInfo); + + /** \brief + * Implementation of ProblemStatBase::coarsenMesh(). Deligated to the + * CoarseningManager of \ref adapt. + */ + virtual Flag coarsenMesh(AdaptInfo *adaptInfo); + + /** \brief + * Implementation of ProblemStatBase::buildBeforeRefine(). + * Does nothing here. + */ + virtual void buildBeforeRefine(AdaptInfo *adaptInfo, Flag) {}; + + /** \brief + * Implementation of ProblemStatBase::buildBeforeCoarsen(). + * Does nothing here. + */ + virtual void buildBeforeCoarsen(AdaptInfo *adaptInfo, Flag) {}; + + /** \brief + * Implementation of ProblemStatBase::buildAfterCoarsen(). + * Assembles \ref A and \ref rhs. + */ + virtual void buildAfterCoarsen(AdaptInfo *adaptInfo, Flag flag); + + /** \brief + * Determines the execution order of the single adaption steps. If adapt is + * true, mesh adaption will be performed. This allows to avoid mesh adaption, + * e.g. in timestep adaption loops of timestep adaptive strategies. + */ + virtual Flag oneIteration(AdaptInfo *adaptInfo, Flag toDo = FULL_ITERATION); + + /** \brief + * Returns number of managed problems + */ + virtual int getNumProblems() { + return 1; + }; + + /** \brief + * Implementation of ProblemStatBase::getNumComponents() + */ + virtual int getNumComponents() { + return numComponents_; + }; + + /** \brief + * Returns the problem with the given number. If only one problem + * is managed by this master problem, the number hasn't to be given. + */ + virtual ProblemStatBase *getProblem(int number = 0) { return this; }; + + /** \brief + * Writes output files. + */ + void writeFiles(AdaptInfo *adaptInfo, bool force); + + /** \brief + * Interpolates fct to \ref solution. + */ + void + interpolInitialSolution(::std::vector<AbstractFunction<double, WorldVector<double> >*> *fct); + + /** \brief + * Adds an Operator to \ref A. + */ + void addMatrixOperator(Operator *op, int i, int j, + double *factor = NULL, + double *estFactor = NULL); + + /** \brief + * Adds an Operator to \ref rhs. + */ + void addVectorOperator(Operator *op, int i, + double *factor = NULL, + double *estFactor = NULL); + + /** \brief + * Adds dirichlet boundary conditions. + */ + virtual void addDirichletBC(BoundaryType type, int system, + AbstractFunction<double, WorldVector<double> > *b); + + /** \brief + * Adds neumann boundary conditions. + */ + virtual void addNeumannBC(BoundaryType type, int row, int col, + AbstractFunction<double, WorldVector<double> > *n); + + /** \brief + * Adds robin boundary conditions. + */ + virtual void addRobinBC(BoundaryType type, int row, int col, + AbstractFunction<double, WorldVector<double> > *n, + AbstractFunction<double, WorldVector<double> > *r); + + /** \brief + * Adds periodic boundary conditions. + */ + virtual void addPeriodicBC(BoundaryType type, int row, int col); + + + /** \brief + * Implementation of ProblemStatBase::allowFirstRefinement(). + */ + inline void allowFirstRefinement() { + allowFirstRef_ = true; + }; + + // ===== getting-methods ====================================================== + + /** \name getting methods + * \{ + */ + + /** \brief + * Returns \ref solution_. + */ + inline SystemVector* getSolution() { + return solution_; + }; + + /** \brief + * Returns \ref rhs_. + */ + inline SystemVector* getRHS() { + return rhs_; + }; + + /** \brief + * Returns \ref systemMatrix_. + */ + inline Matrix<DOFMatrix*> *getSystemMatrix() { + return systemMatrix_; + }; + + /** \brief + * Returns mesh of given component + */ + inline Mesh* getMesh(int comp) { + FUNCNAME("ProblemVec::getMesh()"); + TEST_EXIT(comp < static_cast<int>(componentMeshes_.size()) && comp >= 0) + ("invalid component number\n"); + return componentMeshes_[comp]; + }; + + /** \brief + * Returns \ref meshes_ + */ + inline ::std::vector<Mesh*> getMeshes() { + return meshes_; + }; + + /** \brief + * Returns \ref feSpace_. + */ + inline FiniteElemSpace* getFESpace(int comp) { + FUNCNAME("ProblemVec::getFESpace()"); + TEST_EXIT(comp < static_cast<int>(componentSpaces_.size()) && comp >= 0) + ("invalid component number\n"); + return componentSpaces_[comp]; + }; + + /** \brief + * Returns \ref feSpaces_. + */ + inline ::std::vector<FiniteElemSpace*> getFESpaces() { + return feSpaces_; + }; + + /** \brief + * Returns \ref estimator_. + */ + inline ::std::vector<Estimator*> getEstimator() { + return estimator_; + }; + + /** \brief + * Returns \ref estimator_. + */ + inline Estimator* getEstimator(int comp) { + return estimator_[comp]; + }; + + /** \brief + * Returns \ref refinementManager_. + */ + inline RefinementManager* getRefinementManager(int comp) { + return refinementManager_; + }; + + /** \brief + * Returns \ref refinementManager_. + */ + inline CoarseningManager* getCoarseningManager(int comp) { + return coarseningManager_; + }; + + /** \brief + * Returns \ref solver_. + */ + inline OEMSolver<SystemVector>* getSolver() { + return solver_; + }; + + /** \brief + * Returns \ref marker_. + */ + inline Marker *getMarker(int comp) { + return marker_[comp]; + }; + + /** \brief + * Returns \ref marker_. + */ + inline ::std::vector<Marker*> getMarker() { + return marker_; + }; + + /** \brief + * Returns \ref name_. + */ + inline virtual const ::std::string& getName() { + return name_; + }; + + /** \brief + * Returns \ref useGetBound_. + */ + inline bool getBoundUsed() { + return useGetBound_; + }; + + /** \brief + * Returns \ref leftPrecon_. + */ + inline Preconditioner<SystemVector> *getLeftPrecon() { + return leftPrecon_; + }; + + /** \brief + * Returns \ref rightPrecon_. + */ + inline Preconditioner<SystemVector> *getRightPrecon() { + return rightPrecon_; + }; + + /** \} */ + + // ===== setting-methods ====================================================== + + /** \name setting methods + * \{ + */ + + /** \brief + * Sets \ref estimator_. + */ + inline void setEstimator(::std::vector<Estimator*> est) { + estimator_ = est; + }; + + inline void setFESpace(FiniteElemSpace *feSpace, int comp) { + feSpaces_[comp] = feSpace; + }; + + /** \brief + * Sets \ref estimator_. + */ + inline void setEstimator(Estimator* est, int comp) { + estimator_[comp] = est; + }; + + inline void setMarker(Marker* marker, int comp) { + marker_[comp] = marker; + }; + + /** \brief + * Sets \ref solver_. + */ + inline void setSolver(OEMSolver<SystemVector>* sol) { solver_ = sol; }; + + /** \brief + * Sets \ref leftPrecon_. + */ + inline void setLeftPrecon(Preconditioner<SystemVector> *p) { + leftPrecon_ = p; + }; + + /** \brief + * Sets \ref rightPrecon_. + */ + inline void setRightPrecon(Preconditioner<SystemVector> *p) { + rightPrecon_ = p; + }; + + /** \} */ + + // ===== Serializable implementation ===== + + /** \brief + * serialization + */ + virtual void serialize(::std::ostream &out); + + /** \brief + * deserialization + */ + virtual void deserialize(::std::istream &in); + + ::std::list<FileWriterInterface*> getFileWriterList() { + return fileWriters_; + }; + + protected: + /** \brief + * Name of this problem. + */ + ::std::string name_; + + /** \brief + * number of problem components + */ + int numComponents_; + + /** \brief + * fe spaces of this problem. + */ + ::std::vector<FiniteElemSpace*> feSpaces_; + + /** \brief + * meshes of this problem. + */ + ::std::vector<Mesh*> meshes_; + + /** \brief + * Pointer to the fe spaces for the different problem components + */ + ::std::vector<FiniteElemSpace*> componentSpaces_; + + /** \brief + * Pointer to the meshes for the different problem components + */ + ::std::vector<Mesh*> componentMeshes_; + + /** \brief + * Responsible for element marking. + */ + ::std::vector<Marker*> marker_; + + /** \brief + * Estimator of this problem. Used in \ref estimate(). + */ + ::std::vector<Estimator*> estimator_; + + /** \brief + * Linear solver of this problem. Used in \ref solve(). + */ + OEMSolver<SystemVector> *solver_; + + /** \brief + * system vector storing the calculated solution of the problem. + */ + SystemVector *solution_; + + /** \brief + * system vector for the right hand side + */ + SystemVector *rhs_; + + /** \brief + * System matrix + */ + Matrix<DOFMatrix*> *systemMatrix_; + + /** \brief + * Matrix-vector multiplication + */ + MatVecMultiplier<SystemVector> *matVec_; + + /** \brief + * Left preconditioner. Used in \ref solver. + */ + Preconditioner<SystemVector> *leftPrecon_; + + /** \brief + * Right preconditioner. Used in \ref solver. + */ + Preconditioner<SystemVector> *rightPrecon_; + + /** \brief + * Determines whether domain boundaries should be considered at assembling. + */ + bool useGetBound_; + + /** \brief + * Writes the meshes and solution after the adaption loop. + */ + ::std::list<FileWriterInterface*> fileWriters_; + + /** \brief + * All actions of mesh refinement are performed by refinementManager. + * If new refinement algorithms should be realized, one has to override + * RefinementManager and give one instance of it to AdaptStationary. + */ + RefinementManager *refinementManager_; + + /** \brief + * All actions of mesh coarsening are performed by coarseningManager. + * If new coarsening algorithms should be realized, one has to override + * CoarseningManager and give one instance of it to AdaptStationary. + */ + CoarseningManager *coarseningManager_; + + /** \brief + * Info level. + */ + int info_; + + /** \brief + * Allows one refinement although the adapt tolerance is reached already. + */ + bool allowFirstRef_; + + ProblemIterationInterface *problemIteration_; + + /** \brief + * Used for mesh traversal. + */ + static ProblemVec *traversePtr_; + }; + + + void axpy(double a, + const Matrix<DOFMatrix*> &x, + Matrix<DOFMatrix*> &y); + +} + +#endif diff --git a/AMDiS/src/Projection.cc b/AMDiS/src/Projection.cc new file mode 100644 index 0000000000000000000000000000000000000000..1acec969c25476133cadb70039b5c275ca8d4331 --- /dev/null +++ b/AMDiS/src/Projection.cc @@ -0,0 +1,7 @@ +#include "Projection.h" + +namespace AMDiS { + + ::std::map<int, Projection*> Projection::projectionMap_; + +} diff --git a/AMDiS/src/Projection.h b/AMDiS/src/Projection.h new file mode 100644 index 0000000000000000000000000000000000000000..7bd0f4662ecadf4a6bb6f9f9490a444e2d13f390 --- /dev/null +++ b/AMDiS/src/Projection.h @@ -0,0 +1,112 @@ +// ============================================================================ +// == == +// == AMDiS - Adaptive multidimensional simulations == +// == == +// ============================================================================ +// == == +// == crystal growth group == +// == == +// == Stiftung caesar == +// == Ludwig-Erhard-Allee 2 == +// == 53175 Bonn == +// == germany == +// == == +// ============================================================================ +// == == +// == http://www.caesar.de/cg/AMDiS == +// == == +// ============================================================================ + +/** \file Projection.h */ + +#ifndef AMDIS_PROJECTION_H +#define AMDIS_PROJECTION_H + +#include "FixVec.h" +#include <map> + +namespace AMDiS { + + /** \brief + * Different possible types for a \ref Projection. + */ + enum ProjectionType { + BOUNDARY_PROJECTION = 0, /**< Projection of boundary parts of an element. */ + VOLUME_PROJECTION = 1 /**< Projection of whole elements. */ + }; + + // ============================================================================== + // ===== class Projection ======================================================= + // ============================================================================== + + /** \brief + * A Projection is a mapping from world coordinates to world coordinates. + * It must fullfill the condition \ref project(project(x)) == project(x). + * Each projection object has its own unique \ref projectionID. This is + * used to connect the projection indices used in the macro file with the + * corresponding projection object. See \ref getProjection(int id). + */ + class Projection + { + public: + /** \brief + * Constructs a prjection with given id and type. + */ + Projection(int id, ProjectionType type) + : projectionID_(id), + projectionType_(type) + { + TEST_EXIT(id != 0) + ("don't use 0 as projection id. is used as no projection\n"); + TEST_EXIT(projectionMap_[id] == NULL) + ("there is already a projection with this id\n"); + projectionMap_[id] = this; + }; + + virtual ~Projection() {}; + + /** \brief + * Projection method. Must be overriden in sub classes. + */ + virtual void project(WorldVector<double>& x) = 0; + + /** \brief + * Returns \ref projectionID. + */ + inline int getID() { return projectionID_; }; + + /** \brief + * Returns \ref projectionType; + */ + inline ProjectionType getType() { return projectionType_; }; + + /** \brief + * Returns the projection with the given id, if existing. + * Returns NULL otherwise. + */ + static Projection* getProjection(int id) { + return projectionMap_[id]; + }; + + protected: + /** \brief + * Unique projection id. + */ + int projectionID_; + + /** \brief + * Type of this projection. + */ + ProjectionType projectionType_; + + /** \brief + * Static mapping from ids to projection objects. Used in \ref getProjection(). + */ + static ::std::map<int, Projection*> projectionMap_; + }; + +} + +#include "BallProject.h" +#include "CylinderProject.h" +#endif diff --git a/AMDiS/src/QPInfo.cc b/AMDiS/src/QPInfo.cc new file mode 100644 index 0000000000000000000000000000000000000000..fe4171bdb959dd1dd5fbf42f5f975ecc491940d5 --- /dev/null +++ b/AMDiS/src/QPInfo.cc @@ -0,0 +1,352 @@ +#include "QPInfo.h" +#include "Quadrature.h" +#include "DOFVector.h" + +namespace AMDiS { + + ::std::map<const Quadrature*, QPInfo*> QPInfo::qpInfos_; + + QPInfo::QPInfo(const Quadrature *quad) + : quadrature_(quad), + currentElInfo_(NULL), + coordsAtQPs_(NULL), + coordsNumPointsValid_(0), + elementNormalAtQPs_(NULL), + elementNormalConst_(NULL), + elementNormalNumPointsValid_(0), + grdLambdaAtQPs_(NULL), + grdLambdaConst_(NULL), + grdLambdaNumPointsValid_(0) + { + numPoints_ = quadrature_->getNumPoints(); + } + + QPInfo::~QPInfo() + { + int i; + + if(coordsAtQPs_) DELETE [] coordsAtQPs_; + + if(elementNormalAtQPs_) { + for(i = 0; i < numPoints_; i++) { + DELETE elementNormalAtQPs_[i]; + } + FREE_MEMORY(elementNormalAtQPs_, + WorldVector<double>*, + numPoints_); + } + + if(elementNormalConst_) { + FREE_MEMORY(elementNormalConst_, + WorldVector<double>*, + numPoints_); + } + + if(grdLambdaAtQPs_) { + for(i = 0; i < numPoints_; i++) { + DELETE grdLambdaAtQPs_[i]; + } + FREE_MEMORY(grdLambdaAtQPs_, + DimVec<WorldVector<double> >*, + numPoints_); + } + + if(grdLambdaConst_) { + FREE_MEMORY(grdLambdaConst_, + DimVec<WorldVector<double> >*, + numPoints_); + } + + ::std::map<const DOFVector<double>*, VecQPInfo*>::iterator + it, itEnd = vecQPInfos_.end(); + + for(it = vecQPInfos_.begin(); it != itEnd; ++it) { + if(it->second->valAtQPs_) + FREE_MEMORY(it->second->valAtQPs_, double, numPoints_); + if(it->second->grdAtQPs_) + DELETE [] it->second->grdAtQPs_; + if(it->second->D2AtQPs_) + DELETE [] it->second->D2AtQPs_; + DELETE it->second; + } + } + + void QPInfo::initElement(const ElInfo *elInfo) + { + currentElInfo_ = elInfo; + + coordsNumPointsValid_ = 0; + + elementNormalNumPointsValid_ = 0; + + grdLambdaNumPointsValid_ = 0; + + ::std::map<const DOFVector<double>*, VecQPInfo*>::iterator + it, itEnd = vecQPInfos_.end(); + + for(it = vecQPInfos_.begin(); it != itEnd; ++it) { + it->second->valNumPointsValid_ = 0; + it->second->grdNumPointsValid_ = 0; + it->second->D2NumPointsValid_ = 0; + } + } + + WorldVector<double> *QPInfo::getCoordsAtQPs(int numPoints) + { + if(coordsNumPointsValid_ < numPoints) { + if(!coordsAtQPs_) { + coordsAtQPs_ = NEW WorldVector<double>[numPoints_]; + } + int i; + for(i = 0; i < numPoints; i++) { + const DimVec<double>& lambda = quadrature_->getLambda(i); + TEST_EXIT(currentElInfo_)("currentElInfo_ not set\n"); + currentElInfo_->coordToWorld(lambda, &coordsAtQPs_[i]); + } + coordsNumPointsValid_ = numPoints; + } + return coordsAtQPs_; + } + + double *QPInfo::getVecAtQPs(const DOFVector<double>* vec, + int numPoints, + const FastQuadrature *quadFast) + { + // check fast quadrature + if(quadFast) { + TEST_EXIT(quadrature_ == quadFast->getQuadrature()) + ("quadrature_ != quadFast->quadrature\n"); + } + + // create new info if necessary + if(vecQPInfos_[vec] == NULL) { + vecQPInfos_[vec] = NEW VecQPInfo; + } + + VecQPInfo *localVecQPInfo = vecQPInfos_[vec]; + + // update values if necessary + if(localVecQPInfo->valNumPointsValid_ < numPoints) { + + // allocate memory if necessary + if(localVecQPInfo->valAtQPs_ == NULL) { + localVecQPInfo->valAtQPs_ = GET_MEMORY(double, numPoints_); + } + + // fill memory + vec->getVecAtQPs(currentElInfo_, + quadrature_, + quadFast, + localVecQPInfo->valAtQPs_, + numPoints); + + localVecQPInfo->valNumPointsValid_ = numPoints; + } + + // return values + return localVecQPInfo->valAtQPs_; + } + + WorldVector<double> *QPInfo::getGrdAtQPs(const DOFVector<double>* vec, + int numPoints, + const FastQuadrature *quadFast) + { + // check fast quadrature + if(quadFast) { + TEST_EXIT(quadrature_ == quadFast->getQuadrature()) + ("quadrature_ != quadFast->quadrature\n"); + } + + // create new info if necessary + if(vecQPInfos_[vec] == NULL) { + vecQPInfos_[vec] = NEW VecQPInfo; + } + + VecQPInfo *localVecQPInfo = vecQPInfos_[vec]; + + // update values if necessary + if(localVecQPInfo->grdNumPointsValid_ < numPoints) { + + // allocate memory if necessary + if(localVecQPInfo->grdAtQPs_ == NULL) { + localVecQPInfo->grdAtQPs_ = NEW WorldVector<double>[numPoints_]; + } + + // fill memory + vec->getGrdAtQPs(currentElInfo_, + quadrature_, + quadFast, + localVecQPInfo->grdAtQPs_, + numPoints); + + localVecQPInfo->grdNumPointsValid_ = numPoints; + } + + // return values + return localVecQPInfo->grdAtQPs_; + } + + WorldMatrix<double> *QPInfo::getD2AtQPs(const DOFVector<double>* vec, + int numPoints, + const FastQuadrature *quadFast) + { + // check fast quadrature + if(quadFast) { + TEST_EXIT(quadrature_ == quadFast->getQuadrature()) + ("quadrature_ != quadFast->quadrature\n"); + } + + // create new info if necessary + if(vecQPInfos_[vec] == NULL) { + vecQPInfos_[vec] = NEW VecQPInfo; + } + + VecQPInfo *localVecQPInfo = vecQPInfos_[vec]; + + // update values if necessary + if(localVecQPInfo->D2NumPointsValid_ < numPoints) { + + // allocate memory if necessary + if(localVecQPInfo->D2AtQPs_ == NULL) { + localVecQPInfo->D2AtQPs_ = NEW WorldMatrix<double>[numPoints_]; + } + + // fill memory + vec->getD2AtQPs(currentElInfo_, + quadrature_, + quadFast, + localVecQPInfo->D2AtQPs_, + numPoints); + + localVecQPInfo->D2NumPointsValid_ = numPoints; + } + + // return values + return localVecQPInfo->D2AtQPs_; + } + + WorldVector<double> **QPInfo::getElementNormalAtQPs(int numPoints) + { + TEST_EXIT(currentElInfo_)("currentElInfo_ not set\n"); + + int i; + if(currentElInfo_->getParametricOrder() > 1) { + if(!elementNormalAtQPs_) { + elementNormalAtQPs_ = GET_MEMORY(WorldVector<double>*, + numPoints_); + for(i = 0; i < numPoints_; i++) { + elementNormalAtQPs_[i] = NEW WorldVector<double>; + } + } + + if(elementNormalNumPointsValid_ < numPoints) { + for(i = 0; i < numPoints; i++) { + const DimVec<double>& lambda = quadrature_->getLambda(i); + currentElInfo_->getElementNormal(*(elementNormalAtQPs_[i]), &lambda); + } + elementNormalNumPointsValid_ = numPoints; + } + return elementNormalAtQPs_; + } else { + if(!elementNormalConst_) { + elementNormalConst_ = GET_MEMORY(WorldVector<double>*, + numPoints_); + elementNormalConst_[0] = NEW WorldVector<double>; + + for(i = 1; i < numPoints_; i++) { + elementNormalConst_[i] = elementNormalConst_[0]; + } + } + currentElInfo_->getElementNormal(*(elementNormalConst_[0])); + return elementNormalConst_; + } + } + + DimVec<WorldVector<double> > **QPInfo::getGrdLambdaAtQPs(int numPoints) + { + TEST_EXIT(currentElInfo_)("currentElInfo_ not set\n"); + + int i; + if(currentElInfo_->getParametricOrder() > 1) { + if(!grdLambdaAtQPs_) { + grdLambdaAtQPs_ = GET_MEMORY(DimVec<WorldVector<double> >*, + numPoints_); + for(i = 0; i < numPoints_; i++) { + grdLambdaAtQPs_[i] = + NEW DimVec<WorldVector<double> >(quadrature_->getDim()); + } + } + + if(grdLambdaNumPointsValid_ < numPoints) { + for(i = 0; i < numPoints; i++) { + const DimVec<double>& lambda = quadrature_->getLambda(i); + currentElInfo_->calcGrdLambda(*(grdLambdaAtQPs_[i]), &lambda); + } + grdLambdaNumPointsValid_ = numPoints; + } + return grdLambdaAtQPs_; + } else { + if(!grdLambdaConst_) { + grdLambdaConst_ = GET_MEMORY(DimVec<WorldVector<double> >*, + numPoints_); + grdLambdaConst_[0] = + NEW DimVec<WorldVector<double> >(quadrature_->getDim()); + + for(i = 1; i < numPoints_; i++) { + grdLambdaConst_[i] = grdLambdaConst_[0]; + } + } + currentElInfo_->calcGrdLambda(*(grdLambdaConst_[0])); + return grdLambdaConst_; + } + } + + QPInfo *QPInfo::provideQPInfo(const Quadrature *quad, + const FastQuadrature *quadFast) + { + if(quadFast) { + if(quad && (quad != quadFast->getQuadrature())) { + ERROR_EXIT("quad != quadFast->quadrature\n"); + } else { + quad = quadFast->getQuadrature(); + } + } + if(quad) { + if(qpInfos_[quad]) return qpInfos_[quad]; + QPInfo *newQPInfo = NEW QPInfo(quad); + qpInfos_[quad] = newQPInfo; + return newQPInfo; + } else { + return NULL; + } + } + + void QPInfo::clearQPInfo(const Quadrature *quad, + const FastQuadrature *quadFast) + { + if(quadFast) { + if(quad && (quad != quadFast->getQuadrature())) { + ERROR_EXIT("quad != quadFast->quadrature\n"); + } else { + quad = quadFast->getQuadrature(); + } + } + TEST_EXIT(quad)("no quadrature\n"); + if(qpInfos_[quad]) { + DELETE qpInfos_[quad]; + qpInfos_.erase(quad); + } + } + + void QPInfo::clearAllQPInfos() + { + ::std::map<const Quadrature*, QPInfo*>::iterator + it, itEnd = qpInfos_.end(); + + for(it = qpInfos_.begin(); it != itEnd; ++it) { + DELETE it->second; + qpInfos_.erase(it); + } + } + +} diff --git a/AMDiS/src/QPInfo.h b/AMDiS/src/QPInfo.h new file mode 100644 index 0000000000000000000000000000000000000000..2b3c94cfb81e9d47134e2558441a045299c2222c --- /dev/null +++ b/AMDiS/src/QPInfo.h @@ -0,0 +1,241 @@ +// ============================================================================ +// == == +// == AMDiS - Adaptive multidimensional simulations == +// == == +// ============================================================================ +// == == +// == crystal growth group == +// == == +// == Stiftung caesar == +// == Ludwig-Erhard-Allee 2 == +// == 53175 Bonn == +// == germany == +// == == +// ============================================================================ +// == == +// == http://www.caesar.de/cg/AMDiS == +// == == +// ============================================================================ + +/** \file QPInfo.h */ + +#ifndef AMDIS_QPINFO_H +#define AMDIS_QPINFO_H + +#include <map> +#include "MemoryManager.h" +#include "FixVec.h" + +namespace AMDiS { + + class Quadrature; + class FastQuadrature; + class ElInfo; + template<typename T> class WorldVector; + template<typename T> class WorldMatrix; + template<typename T> class DOFVector; + + // ============================================================================ + // ===== class QPInfo ========================================================= + // ============================================================================ + + /** \brief + * Stores informations at quadrature points of the current element. + */ + class QPInfo + { + public: + MEMORY_MANAGED(QPInfo); + + /** \brief + * Sets \ref currentElInfo_ to elInfo and all valid flags to false. + */ + void initElement(const ElInfo *elInfo); + + /** \brief + * Returns coordinates at quadrature points. + */ + WorldVector<double> *getCoordsAtQPs(int numPoints); + + /** \brief + * Returns vector values at quadrature points. If quadFast is set it will be + * used for a more efficient evaluation. + */ + double *getVecAtQPs(const DOFVector<double>*, + int numPoints, + const FastQuadrature *quadFast = NULL); + + /** \brief + * Returns gradient values at quadrature points. If quadFast is set it will be + * used for a more efficient evaluation. + */ + WorldVector<double> *getGrdAtQPs(const DOFVector<double>*, + int numPoints, + const FastQuadrature *quadFast = NULL); + + /** \brief + * Returns D2 values at quadrature points. If quadFast is set it will be + * used for a more efficient evaluation. + */ + WorldMatrix<double> *getD2AtQPs(const DOFVector<double>*, + int numPoints, + const FastQuadrature *quadFast = NULL); + + + /** \brief + * Returns element normals at quadrature points. + */ + WorldVector<double> **getElementNormalAtQPs(int numPoints); + + /** \brief + * + */ + DimVec<WorldVector<double> > **getGrdLambdaAtQPs(int numPoints); + + /** \brief + * Returns a QPInfo instance for the given quadrature. + */ + static QPInfo *provideQPInfo(const Quadrature*, const FastQuadrature*); + + /** \brief + * Deletes the QPInfo instance for the given quadrature. + */ + static void clearQPInfo(const Quadrature*, const FastQuadrature*); + + /** \brief + * Deletes all QPInfo instances. + */ + static void clearAllQPInfos(); + + protected: + /** \brief + * Constructor. Called by \ref provideQPInfo(). + */ + QPInfo(const Quadrature*); + + /** \brief + * Destructor. Called by \ref clearQPInfo() and \ref clearAllQPInfos(). + */ + ~QPInfo(); + + protected: + /** \brief + * Structure which stores infos about one DOFVector. + */ + class VecQPInfo + { + public: + MEMORY_MANAGED(VecQPInfo); + + /** \brief + * Constructor. + */ + VecQPInfo() + : valAtQPs_(NULL), + grdAtQPs_(NULL), + D2AtQPs_(NULL), + valNumPointsValid_(0), + grdNumPointsValid_(0), + D2NumPointsValid_(0) + {}; + + /** \brief + * Values at quadrature points + */ + double *valAtQPs_; + + /** \brief + * Gradients at quadrature points + */ + WorldVector<double> *grdAtQPs_; + + /** \brief + * D2 at quadrature points + */ + WorldMatrix<double> *D2AtQPs_; + + /** \brief + * valid flag for values + */ + int valNumPointsValid_; + + /** \brief + * valid flag for gradients + */ + int grdNumPointsValid_; + + /** \brief + * valid flag for D2 + */ + bool D2NumPointsValid_; + }; + + /** \brief + * Quadrature of this QPInfo + */ + const Quadrature *quadrature_; + + /** \brief + * Set to \ref quadrature_->getNumPoints(). + */ + int numPoints_; + + /** \brief + * ElInfo of the current element + */ + const ElInfo *currentElInfo_; + + /** \brief + * Coords at quadrature points + */ + WorldVector<double> *coordsAtQPs_; + + /** \brief + * Valid flag for coords + */ + int coordsNumPointsValid_; + + /** \brief + * Map of all vector infos + */ + ::std::map<const DOFVector<double>*, VecQPInfo*> vecQPInfos_; + + /** \brief + * element normal at quadrature points (array of pointers) + */ + WorldVector<double> **elementNormalAtQPs_; + + /** \brief + * for constant values at all QPs (all entries point to same memory) + */ + WorldVector<double> **elementNormalConst_; + + /** \brief + * valid flag for element normals + */ + int elementNormalNumPointsValid_; + + /** \brief + * gradient of barycentric coordinates at QPs (array of pointers) + */ + DimVec<WorldVector<double> > **grdLambdaAtQPs_; + + /** \brief + * for constant values at all QPs (all entries point to same memory) + */ + DimVec<WorldVector<double> > **grdLambdaConst_; + + /** \brief + * number of valid points of grdLambdaAtQPs_ + */ + int grdLambdaNumPointsValid_; + + /** \brief + * Static map of all QPInfos. Used by \ref provideQPInfo(). + */ + static ::std::map<const Quadrature*, QPInfo*> qpInfos_; + }; + +} + +#endif diff --git a/AMDiS/src/QPsiPhi.cc b/AMDiS/src/QPsiPhi.cc new file mode 100644 index 0000000000000000000000000000000000000000..0951d1de5530e0378403f62190eec1ecf61b6089 --- /dev/null +++ b/AMDiS/src/QPsiPhi.cc @@ -0,0 +1,854 @@ +#include <algorithm> +#include <functional> + +#include "QPsiPhi.h" +#include "BasisFunction.h" +#include "ElInfo.h" +#include "FiniteElemSpace.h" +#include "Quadrature.h" +#include "Mesh.h" +#include "FixVec.h" +#include "DOFMatrix.h" +#include "DOFVector.h" +#include "Global.h" + +namespace AMDiS { + + const double TOO_SMALL = 1.e-15; + ::std::list<Q11PsiPhi*> Q11PsiPhi::preList; + ::std::list<Q01PsiPhi*> Q01PsiPhi::preList; + ::std::list<Q00PsiPhi*> Q00PsiPhi::preList; + ::std::list<Q10PsiPhi*> Q10PsiPhi::preList; + + ::std::list<Q0Psi*> Q0Psi::preList; + ::std::list<Q1Psi*> Q1Psi::preList; + + /****************************************************************************/ + /* information about precomputed integrals of basis functions on the */ + /* standard element; */ + /****************************************************************************/ + + /****************************************************************************/ + /* second order term: */ + /****************************************************************************/ + + Q11PsiPhi::Q11PsiPhi(const BasisFunction *ps, const BasisFunction *ph, + const Quadrature *quadrat) + : psi(ps), + phi(ph), + quadrature(quadrat), + nrEntries(NULL), + values(NULL), + k(NULL), + l(NULL) + { + FUNCNAME("Q11PsiPhi::Q11PsiPhi"); + const FastQuadrature *q_phi, *q_psi; + int i, j, lk, ll, n, iq, all_entries, n_psi, n_phi; + double val, grdi, grdj; + int d=ps->getDim(); + + if (!psi) psi = phi; + if (!phi) phi = psi; + + if (!quadrature) + quadrature = Quadrature::provideQuadrature(d, psi->getDegree() + + phi->getDegree() - 2); + + n_psi = psi->getNumber(); + q_psi = FastQuadrature::provideFastQuadrature(psi, *quadrature, INIT_GRD_PHI); + n_phi = phi->getNumber(); + q_phi = FastQuadrature::provideFastQuadrature(phi, *quadrature, INIT_GRD_PHI); + + nrEntries = GET_MEMORY(int*, n_psi); + values = GET_MEMORY(double**, n_psi); + k = GET_MEMORY(int**, n_psi); + l = GET_MEMORY(int**, n_psi); + for(i=0;i<n_psi;i++){ + nrEntries[i]=GET_MEMORY(int, n_phi); + values[i]= GET_MEMORY(double*, n_phi); + k[i]= GET_MEMORY(int*, n_phi); + l[i]= GET_MEMORY(int*, n_phi); + }; + + + //**************************************************************************** + //* compute first the number of all non zero entries * + //**************************************************************************** + + int numPoints = quadrature->getNumPoints(); + + all_entries = 0; + for(i = 0; i < n_psi; i++) { + for(j = 0; j < n_phi; j++) { + for(lk = 0; lk < d+1; lk++) { + for(ll = 0; ll < d+1; ll++) { + for(val = iq = 0; iq < numPoints; iq++) { + grdi = q_psi->getGradient(iq,i,lk); + grdj = q_phi->getGradient(iq,j,ll); + + val += quadrature->getWeight(iq)*grdi*grdj; + } + if (abs(val) > TOO_SMALL) + all_entries++; + } + } + } + } + + //**************************************************************************** + //* now, access memory for all information * + //**************************************************************************** + allEntries = all_entries; + + val_vec = GET_MEMORY(double, all_entries); + k_vec = GET_MEMORY(int, all_entries); + l_vec = GET_MEMORY(int, all_entries); + + //*************************************************************************** + // and now, fill information * + //*************************************************************************** + + for(i = 0; i < n_psi; i++) { + for(j = 0; j < n_phi; j++) { + values[i][j] = val_vec; + k[i][j] = k_vec; + l[i][j] = l_vec; + + for(n = lk = 0; lk < d+1; lk++) { + for(ll = 0; ll < d+1; ll++) { + for(val = iq = 0; iq < numPoints; iq++) { + grdi = q_psi->getGradient(iq,i,lk); + grdj = q_phi->getGradient(iq,j,ll); + + val += quadrature->getWeight(iq)*grdi*grdj; + } + if (abs(val) > TOO_SMALL) { + TEST_EXIT(all_entries-- > 0) + ("now more entries found than counted before\n"); + n++; + *val_vec = val; + val_vec++; + *k_vec = lk; + k_vec++; + *l_vec = ll; + l_vec++; + } + } + } + nrEntries[i][j] = n; + } + } + } + + Q11PsiPhi::~Q11PsiPhi() + { + if(nrEntries) { + for(int i=0; i < psi->getNumber(); i++) { + FREE_MEMORY(nrEntries[i], int, phi->getNumber()); + FREE_MEMORY(values[i], double*, phi->getNumber()); + FREE_MEMORY(k[i], int*, phi->getNumber()); + FREE_MEMORY(l[i], int*, phi->getNumber()); + } + FREE_MEMORY(nrEntries, int*, psi->getNumber()); + FREE_MEMORY(values, double**, psi->getNumber()); + FREE_MEMORY(k, int**, psi->getNumber()); + FREE_MEMORY(l, int**, psi->getNumber()); + + FREE_MEMORY(val_vec, double, allEntries); + FREE_MEMORY(k_vec, int, allEntries); + FREE_MEMORY(l_vec, int, allEntries); + } + } + + + const bool Q11PsiPhi::operator==(const Q11PsiPhi& q11pp) const + { + return (q11pp.psi == psi && q11pp.phi == phi && q11pp.quadrature == quadrature); + } + + + const Q11PsiPhi* Q11PsiPhi::provideQ11PsiPhi(const BasisFunction *ps, + const BasisFunction *ph, + const Quadrature *quadrat) + { + FUNCNAME("Q11PsiPhi::provideQ11PsiPhi"); + ::std::list<Q11PsiPhi*>::iterator list; + + if (!ps && !ph) return NULL; + + if (!ps) ps = ph; + if (!ph) ph = ps; + + if (!quadrat) + quadrat = Quadrature::provideQuadrature(ps->getDim(), + ps->getDegree() + + ph->getDegree() - 2); + + compareQPsiPhi<Q11PsiPhi> comp(ps,ph,quadrat); + + //*************************************************************************** + // look for an existing entry in the list * + //*************************************************************************** + + list = find_if(preList.begin(), + preList.end(), + comp); + + if (list==preList.end()) { + Q11PsiPhi *newQ11PsiPhi = NEW Q11PsiPhi(ps,ph,quadrat); + preList.push_back(newQ11PsiPhi); + return newQ11PsiPhi; + } else { + return *list; + } + } + + /****************************************************************************/ + /* first order term */ + /****************************************************************************/ + + Q10PsiPhi::Q10PsiPhi(const BasisFunction *ps, const BasisFunction *ph, + const Quadrature *quadrat):psi(ps),phi(ph),quadrature(quadrat) + { + FUNCNAME("Q10PsiPhi::Q10PsiPhi"); + const FastQuadrature *q_phi, *q_psi; + int i, j, lk, n=0, iq, all_entries, n_psi, n_phi; + double val, psij, grdi; + int d=quadrature->getDim(); + + int numPoints = quadrature->getNumPoints(); + + if (!psi && !phi) + { + nrEntries=NULL; + k=NULL; + values=NULL; + } + + if (!psi) psi = phi; + if (!phi) phi = psi; + + if (!quadrature) + quadrature = Quadrature::provideQuadrature(psi->getDim(), + psi->getDegree()+phi->getDegree()-1); + + /****************************************************************************/ + /* create a new one */ + /****************************************************************************/ + n_psi = psi->getNumber(); + q_psi = FastQuadrature::provideFastQuadrature(psi, *quadrature, INIT_PHI); + n_phi = phi->getNumber(); + q_phi = FastQuadrature::provideFastQuadrature(phi, *quadrature, INIT_GRD_PHI); + + nrEntries = GET_MEMORY(int*, n_psi); + values = GET_MEMORY(double**, n_psi); + k = GET_MEMORY(int**, n_psi); + for(i=0;i<n_psi;i++){ + nrEntries[i]= GET_MEMORY(int, n_phi); + values[i] = GET_MEMORY(double*, n_phi); + k[i] = GET_MEMORY(int*, n_phi); + }; + + /****************************************************************************/ + /* compute first the number of all non zero entries */ + /****************************************************************************/ + + all_entries = 0; + for(i = 0; i < n_psi; i++) { + for(j = 0; j < n_phi; j++) { + for(lk = 0; lk < d+1; lk++) { + for(val = iq = 0; iq < numPoints; iq++) { + psij = q_psi->getPhi(iq,j); + grdi = q_phi->getGradient(iq,i,lk); + + val += quadrature->getWeight(iq)*psij*grdi; + } + if (abs(val) > TOO_SMALL) + all_entries++; + } + } + } + + /****************************************************************************/ + /* now, access memory for all information */ + /****************************************************************************/ + + val_vec = GET_MEMORY(double, all_entries); + k_vec = GET_MEMORY(int, all_entries); + + /****************************************************************************/ + /* and now, fill information */ + /****************************************************************************/ + + for(i = 0; i < n_psi; i++) { + for(j = 0; j < n_phi; j++) { + values[i][j] = val_vec; + k[i][j] = k_vec; + + for(n = lk = 0; lk < d+1; lk++) { + for(val = iq = 0; iq < numPoints; iq++) { + psij = q_psi->getPhi(iq,j); + grdi = q_phi->getGradient(iq,i,lk); + + val += quadrature->getWeight(iq)*psij*grdi; + } + if (abs(val) > TOO_SMALL) { + TEST_EXIT(all_entries-- > 0) + ("now more entries found than counted before\n"); + n++; + *val_vec++ = val; + *k_vec++ = lk; + } + } + nrEntries[i][j] = n; + } + } + } + + Q10PsiPhi::~Q10PsiPhi() + { + if(nrEntries) { + for(int i=0; i < psi->getNumber(); i++) { + FREE_MEMORY(nrEntries[i], int, phi->getNumber()); + FREE_MEMORY(values[i], double*, phi->getNumber()); + FREE_MEMORY(k[i], int*, phi->getNumber()); + } + FREE_MEMORY(nrEntries, int*, psi->getNumber()); + FREE_MEMORY(values, double**, psi->getNumber()); + FREE_MEMORY(k, int**, psi->getNumber()); + + FREE_MEMORY(val_vec, double, allEntries); + FREE_MEMORY(k_vec, int, allEntries); + } + } + + const bool Q10PsiPhi::operator==(const Q10PsiPhi& q10pp) const + { + return (q10pp.psi == psi && q10pp.phi == phi && q10pp.quadrature == quadrature); + } + + + const Q10PsiPhi* Q10PsiPhi::provideQ10PsiPhi(const BasisFunction *ps, + const BasisFunction *ph, + const Quadrature *quadrat) + { + FUNCNAME("Q10PsiPhi::provideQ10PsiPhi"); + ::std::list<Q10PsiPhi*>::iterator list; + + if (!ps && !ph) return NULL; + + if (!ps) ps = ph; + if (!ph) ph = ps; + + if (!quadrat) quadrat = + Quadrature::provideQuadrature(ps->getDim(), + ps->getDegree() + + ph->getDegree() - 1); + + compareQPsiPhi<Q10PsiPhi> comp(ps,ph,quadrat); + + /****************************************************************************/ + /* look for an existing entry in the list */ + /****************************************************************************/ + + list = find_if(preList.begin(), + preList.end(), + comp); + + if (list==preList.end()) { + Q10PsiPhi *newQ10PsiPhi = NEW Q10PsiPhi(ps,ph,quadrat); + preList.push_back(newQ10PsiPhi); + return newQ10PsiPhi; + } else { + return *list; + } + } + + + Q01PsiPhi::Q01PsiPhi(const BasisFunction *ps, const BasisFunction *ph, + const Quadrature *quadrat) + : psi(ps),phi(ph),quadrature(quadrat) + { + FUNCNAME("Q01PsiPhi::Q01PsiPhi"); + const FastQuadrature *q_phi, *q_psi; + int i, j, ll, n=0, iq, all_entries, n_psi, n_phi; + double val, grdj, psii; + int d=quadrature->getDim(); + + int numPoints = quadrature->getNumPoints(); + + if (!psi && !phi) + { + nrEntries=NULL; + l=NULL; + values=NULL; + } + + if (!psi) psi = phi; + if (!phi) phi = psi; + + if (!quadrature) + quadrature = Quadrature::provideQuadrature(psi->getDim(), + psi->getDegree() + + phi->getDegree() - 1); + + /****************************************************************************/ + /* create a new one */ + /****************************************************************************/ + n_psi = psi->getNumber(); + q_psi = FastQuadrature::provideFastQuadrature(psi, *quadrature, INIT_GRD_PHI); + n_phi = phi->getNumber(); + q_phi = FastQuadrature::provideFastQuadrature(phi, *quadrature, INIT_PHI); + + nrEntries = GET_MEMORY(int*, n_psi); + values = GET_MEMORY(double**, n_psi); + l = GET_MEMORY(int**, n_psi); + for(i=0;i<n_psi;i++){ + nrEntries[i]=GET_MEMORY(int, n_phi); + values[i]= GET_MEMORY(double*, n_phi); + l[i]= GET_MEMORY(int*, n_phi); + }; + + + /****************************************************************************/ + /* compute first the number of all non zero entries */ + /****************************************************************************/ + + all_entries = 0; + for(i = 0; i < n_psi; i++) { + for(j = 0; j < n_phi; j++) { + for(ll = 0; ll < d+1; ll++) { + for(val = iq = 0; iq < numPoints; iq++) { + grdj = q_phi->getGradient(iq,j,ll); + psii = q_psi->getPhi(iq,i); + + val += quadrature->getWeight(iq)*grdj*psii; + } + if(abs(val) > TOO_SMALL) + all_entries++; + } + } + } + + /****************************************************************************/ + /* now, access memory for all information */ + /****************************************************************************/ + + val_vec = GET_MEMORY(double, all_entries); + l_vec = GET_MEMORY(int, all_entries); + + /****************************************************************************/ + /* and now, fill information */ + /****************************************************************************/ + + for(i = 0; i < n_psi; i++) { + for(j = 0; j < n_phi; j++) { + values[i][j] = val_vec; + l[i][j] = l_vec; + + for(n = ll = 0; ll < d+1; ll++) { + for(val = iq = 0; iq < numPoints; iq++) { + grdj = q_phi->getGradient(iq,j,ll); + psii = q_psi->getPhi(iq,i); + + val += quadrature->getWeight(iq)*grdj*psii; + } + if (abs(val) > TOO_SMALL) { + TEST_EXIT(all_entries-- > 0) + ("now more entries found than counted before\n"); + n++; + *val_vec++ = val; + *l_vec++ = ll; + } + } + nrEntries[i][j] = n; + } + } + } + + Q01PsiPhi::~Q01PsiPhi() + { + if(nrEntries) { + for(int i=0; i < psi->getNumber(); i++) { + FREE_MEMORY(nrEntries[i], int, phi->getNumber()); + FREE_MEMORY(values[i], double*, phi->getNumber()); + FREE_MEMORY(l[i], int*, phi->getNumber()); + } + FREE_MEMORY(nrEntries, int*, psi->getNumber()); + FREE_MEMORY(values, double**, psi->getNumber()); + FREE_MEMORY(l, int**, psi->getNumber()); + + FREE_MEMORY(val_vec, double, allEntries); + FREE_MEMORY(l_vec, int, allEntries); + } + } + + const bool Q01PsiPhi::operator==(const Q01PsiPhi& q01pp) const + { + return (q01pp.psi == psi && q01pp.phi == phi && q01pp.quadrature == quadrature); + } + + + const Q01PsiPhi* Q01PsiPhi::provideQ01PsiPhi(const BasisFunction *ps, + const BasisFunction *ph, + const Quadrature *quadrat) + { + FUNCNAME("Q01PsiPhi::provideQ01PsiPhi"); + ::std::list<Q01PsiPhi*>::iterator list; + + if (!ps && !ph) return NULL; + + if (!ps) ps = ph; + if (!ph) ph = ps; + + if (!quadrat) quadrat = Quadrature::provideQuadrature(ps->getDim(), + ps->getDegree() + + ph->getDegree() - 1); + + compareQPsiPhi<Q01PsiPhi> comp(ps,ph,quadrat); + + /****************************************************************************/ + /* look for an existing entry in the list */ + /****************************************************************************/ + + list = find_if(preList.begin(), + preList.end(), + comp); + + if (list==preList.end()) { + Q01PsiPhi *newQ01PsiPhi = NEW Q01PsiPhi(ps,ph,quadrat); + preList.push_back(newQ01PsiPhi); + return newQ01PsiPhi; + } else { + return *list; + } + } + + /****************************************************************************/ + /* first order term: */ + /****************************************************************************/ + + const double Q00PsiPhi::getValue(unsigned int i,unsigned int j) const + { + if ((values)&&(values[i])) return values[i][j]; + return 0.; + } + + const double *Q00PsiPhi::getValVec(unsigned int i) const + { + if ((values)&&(values[i])) return values[i]; + return NULL; + } + + + Q00PsiPhi::Q00PsiPhi(const BasisFunction *ps, + const BasisFunction *ph, + const Quadrature *quadrat) + : psi(ps), phi(ph), quadrature(quadrat) + { + FUNCNAME("Q00PsiPhi::Q00PsiPhi"); + const FastQuadrature *q_phi, *q_psi; + int i, j,iq, n_psi, n_phi; + double val; + + int numPoints = quadrature->getNumPoints(); + + if (!psi && !phi) { + values=NULL; + } + + if (!psi) psi = phi; + if (!phi) phi = psi; + + if (!quadrature) + quadrature = Quadrature::provideQuadrature(psi->getDim(), + psi->getDegree() + + phi->getDegree()); + + /****************************************************************************/ + /* create a new one */ + /****************************************************************************/ + n_psi = psi->getNumber(); + q_psi = FastQuadrature::provideFastQuadrature(psi, *quadrature, INIT_PHI); + n_phi = phi->getNumber(); + q_phi = FastQuadrature::provideFastQuadrature(phi, *quadrature, INIT_PHI); + + values = GET_MEMORY(double*, n_psi); + for(i=0;i<n_psi;i++){ + values[i]= GET_MEMORY(double, n_phi); + }; + + + /****************************************************************************/ + /* compute first the number of all non zero entries */ + /****************************************************************************/ + + for(i = 0; i < n_psi; i++) { + for(j = 0; j < n_phi; j++) { + for(val = iq = 0; iq < numPoints; iq++) + val += quadrature->getWeight(iq)*q_psi->getPhi(iq,i)*q_phi->getPhi(iq,j); + + if (abs(val) < TOO_SMALL) + values[i][j]=0.0; + else + values[i][j]=val; + } + } + } + + Q00PsiPhi::~Q00PsiPhi() + { + for(int i=0; i < psi->getNumber(); i++) { + FREE_MEMORY(values[i], double, phi->getNumber()); + } + FREE_MEMORY(values, double*, psi->getNumber()); + } + + const bool Q00PsiPhi::operator==(const Q00PsiPhi& q00pp) const + { + return (q00pp.psi == psi && q00pp.phi == phi && q00pp.quadrature == quadrature); + } + + + Q00PsiPhi* Q00PsiPhi::provideQ00PsiPhi(const BasisFunction *ps, + const BasisFunction *ph, + const Quadrature *quadrat) + { + FUNCNAME("Q00PsiPhi::provideQ00PsiPhi"); + ::std::list<Q00PsiPhi*>::iterator list; + + if (!ps && !ph) return NULL; + + if (!ps) ps = ph; + if (!ph) ph = ps; + + if (!quadrat) + quadrat = Quadrature::provideQuadrature(ps->getDim(), + ps->getDegree()+ph->getDegree()); + + compareQPsiPhi<Q00PsiPhi> comp(ps,ph,quadrat); + + /****************************************************************************/ + /* look for an existing entry in the list */ + /****************************************************************************/ + + list = find_if(preList.begin(), + preList.end(), + comp); + + if (list==preList.end()) { + Q00PsiPhi *newQ00PsiPhi = NEW Q00PsiPhi(ps,ph,quadrat); + preList.push_back(newQ00PsiPhi); + return newQ00PsiPhi; + } else { + return *list; + } + } + + + Q0Psi::Q0Psi(const BasisFunction *ps, const Quadrature *quadrat) + : psi(ps), quadrature(quadrat) + { + FUNCNAME("Q0Psi::Q0Psi"); + const FastQuadrature *q_psi; + + int i,iq, n_psi; + double val, psii = 0.0; + + int numPoints = quadrature->getNumPoints(); + + if (!psi) { + values = NULL; + } + + if (!quadrature) + quadrature = Quadrature::provideQuadrature(psi->getDim(), 2*psi->getDegree()); + + + n_psi = psi->getNumber(); + q_psi = FastQuadrature::provideFastQuadrature(psi, *quadrature, INIT_PHI); + + values = GET_MEMORY(double, n_psi); + + for(i = 0; i < n_psi; i++) { + for(val = iq = 0; iq < numPoints; iq++) { + psii = q_psi->getPhi(iq,i); + val += quadrature->getWeight(iq)*psii; + } + + if (abs(val) < TOO_SMALL) + values[i]=0.0; + else + values[i]=val; + } + } + + Q0Psi::~Q0Psi() + { + FREE_MEMORY(values, double, psi->getNumber()); + } + + const bool Q0Psi::operator==(const Q0Psi& q0p) const + { + return (q0p.psi == psi && q0p.quadrature == quadrature); + } + + Q0Psi* Q0Psi::provideQ0Psi(const BasisFunction *ps, const Quadrature *quadrat) + { + FUNCNAME("Q0Psi::provideQ0Psi"); + ::std::list<Q0Psi*>::iterator list; + + if (!ps) return NULL; + if (!quadrat) quadrat = Quadrature::provideQuadrature(ps->getDim(), + 2*ps->getDegree()); + + compareQPsi<Q0Psi> comp(ps, quadrat); + + /****************************************************************************/ + /* look for an existing entry in the list */ + /****************************************************************************/ + + list = find_if(preList.begin(), + preList.end(), + comp); + + if (list==preList.end()) { + Q0Psi *newQ0Psi = NEW Q0Psi(ps, quadrat); + preList.push_back(newQ0Psi); + return newQ0Psi; + } + else { + return *list; + } + } + + + Q1Psi::Q1Psi(const BasisFunction *ps, const Quadrature *quadrat) + : psi(ps), quadrature(quadrat),nrEntries(NULL),values(NULL),k(NULL) + { + FUNCNAME("Q1Psi::Q1Psi"); + const FastQuadrature *q_psi; + int i, lk, n, iq, all_entries, n_psi; + double val, grdi; + + if (!quadrature) quadrature = Quadrature::provideQuadrature(psi->getDim(), + 2*psi->getDegree() - 1); + + n_psi = psi->getNumber(); + q_psi = FastQuadrature::provideFastQuadrature(psi, *quadrature, INIT_GRD_PHI); + + nrEntries = GET_MEMORY(int, n_psi); + values = GET_MEMORY(double*, n_psi); + k = GET_MEMORY(int*, n_psi); + + //**************************************************************************** + //* compute first the number of all non zero entries * + //**************************************************************************** + + int numPoints = quadrature->getNumPoints(); + int d = psi->getDim(); + + all_entries = 0; + for(i = 0; i < n_psi; i++) { + for(lk = 0; lk < d+1; lk++) { + for(val = iq = 0; iq < numPoints; iq++) { + grdi = q_psi->getGradient(iq,i,lk); + //psii = q_psi->getPhi(iq, i); + val += quadrature->getWeight(iq)*grdi; + } + if (abs(val) > TOO_SMALL) + all_entries++; + } + } + + + + //**************************************************************************** + //* now, access memory for all information * + //**************************************************************************** + allEntries = all_entries; + + val_vec = GET_MEMORY(double, all_entries); + k_vec = GET_MEMORY(int, all_entries); + + //*************************************************************************** + // and now, fill information * + //*************************************************************************** + + for(i = 0; i < n_psi; i++) { + values[i] = val_vec; + k[i] = k_vec; + + for(n = lk = 0; lk < d+1; lk++) { + for(val = iq = 0; iq < numPoints; iq++) { + grdi = q_psi->getGradient(iq,i,lk); + //psii = q_psi->getPhi(iq, i); + val += quadrature->getWeight(iq)*grdi; + } + if (abs(val) > TOO_SMALL) { + TEST_EXIT(all_entries-- > 0) + ("now more entries found than counted before\n"); + n++; + *val_vec = val; + val_vec++; + *k_vec = lk; + k_vec++; + } + nrEntries[i] = n; + } + } + } + + Q1Psi::~Q1Psi() + { + if(nrEntries) { + FREE_MEMORY(nrEntries, int, psi->getNumber()); + FREE_MEMORY(values, double*, psi->getNumber()); + FREE_MEMORY(k, int*, psi->getNumber()); + + FREE_MEMORY(val_vec, double, allEntries); + FREE_MEMORY(k_vec, int, allEntries); + } + } + + + const bool Q1Psi::operator==(const Q1Psi& q1p) const + { + return (q1p.psi == psi && q1p.quadrature == quadrature); + } + + + const Q1Psi* Q1Psi::provideQ1Psi(const BasisFunction *ps, + const Quadrature *quadrat) + { + FUNCNAME("Q1Psi::provideQ1Psi"); + ::std::list<Q1Psi*>::iterator list; + + if (!ps) return NULL; + + if (!quadrat) + quadrat = Quadrature::provideQuadrature(ps->getDim(), + 2 * ps->getDegree() - 1); + + compareQPsi<Q1Psi> comp(ps, quadrat); + + //*************************************************************************** + // look for an existing entry in the list * + //*************************************************************************** + + list = find_if(preList.begin(), + preList.end(), + comp); + + if (list==preList.end()) { + Q1Psi *newQ1Psi = NEW Q1Psi(ps, quadrat); + preList.push_back(newQ1Psi); + return newQ1Psi; + } + else { + return *list; + } + } + +} diff --git a/AMDiS/src/QPsiPhi.h b/AMDiS/src/QPsiPhi.h new file mode 100644 index 0000000000000000000000000000000000000000..acfa4cb5e7042d8406be5fdcdbd4da014c0d5145 --- /dev/null +++ b/AMDiS/src/QPsiPhi.h @@ -0,0 +1,968 @@ +// ============================================================================ +// == == +// == AMDiS - Adaptive multidimensional simulations == +// == == +// ============================================================================ +// == == +// == crystal growth group == +// == == +// == Stiftung caesar == +// == Ludwig-Erhard-Allee 2 == +// == 53175 Bonn == +// == germany == +// == == +// ============================================================================ +// == == +// == http://www.caesar.de/cg/AMDiS == +// == == +// ============================================================================ + +/** \file QPsiPhi.h */ + +#ifndef AMDIS_ASSEMBLE_H +#define AMDIS_ASSEMBLE_H + +#include <list> + +#include "DOFAdmin.h" +#include "MemoryManager.h" + +namespace AMDiS { + + class BasisFunction; + class Quadrature; + class FastQuadrature; + class FiniteElemSpace; + class ElInfo; + class Operator; + class ElMatrixInfo; + + // ============================================================================ + + /** + * \ingroup Integration + * + * \brief + * Used for the comparison of two QPsiPhi objects in find_if. + */ + template<typename T> + class compareQPsiPhi : public ::std::unary_function<bool, T*> + { + public: + /** \brief + * Constructor. + */ + compareQPsiPhi(const BasisFunction* psi_, + const BasisFunction* phi_, + const Quadrature* quad_) + : psi(psi_), phi(phi_), quadrature(quad_) + {}; + + /** \brief + * Returns true, if *q is equivalent to *this. + */ + bool operator()(T* q) { + return (q->psi == psi) && (q->phi == phi) && (q->quadrature == quadrature); + }; + + private: + /** \brief + * Basis functions of QPsiPhi. + */ + const BasisFunction *psi, *phi; + + /** \brief + * Quadrature of QPsiPhi. + */ + const Quadrature *quadrature; + }; + + // ============================================================================ + + /** + * \ingroup Integration + * + * \brief + * Used for the comparison of two QPsi objects in find_if. + */ + template<typename T> + class compareQPsi : public ::std::unary_function<bool, T*> + { + public: + /** \brief + * Constructor. + */ + compareQPsi(const BasisFunction* psi_, + const Quadrature* quad_) + : psi(psi), quadrature(quad_) + {}; + + /** \brief + * Returns true, if *q is equivalent to *this. + */ + bool operator()(T* q) { + return (q->psi == psi) && (q->quadrature == quadrature); + }; + + private: + /** \brief + * Basis functions of the QPsi object. + */ + const BasisFunction *psi; + + /** \brief + * Quadrature of the QPsi object. + */ + const Quadrature *quadrature; + }; + + // =========================================================================== + // ===== class Q11PsiPhi ===================================================== + // =========================================================================== + + /** \ingroup Integration + * \brief + * Calculates element stiffness matrices by preevaluated integrals over the + * the reference element (integral of the product of the derivatives of psi + * and phi). + */ + class Q11PsiPhi + { + public: + MEMORY_MANAGED(Q11PsiPhi); + + protected: + /** \brief + * Constructor + */ + Q11PsiPhi(const BasisFunction *psi, + const BasisFunction *phi, + const Quadrature *q); + + + public: + /** \brief + * Destructor + */ + ~Q11PsiPhi(); + + /** \brief + * Returns a Q11PsiPhi object. + */ + static const Q11PsiPhi* provideQ11PsiPhi(const BasisFunction *, + const BasisFunction *, + const Quadrature*); + + /** \brief + * Compares two Q11PsiPhi objects. + */ + const bool operator==(const Q11PsiPhi&) const; + + /** \brief + * Compares two Q11PsiPhi objects. + */ + const bool operator!=(const Q11PsiPhi& q11pp) const { + return !(operator==(q11pp)); + }; + + /** \brief + * Returns \ref values[i][j][k] + */ + inline const double getValue(unsigned int i, + unsigned int j, + unsigned int v) const + { + if ((values)&&(values[i])&&(values[i][j])&&((static_cast<int>(v))<nrEntries[i][j])) + return values[i][j][v]; + return 0.; + }; + + /** \brief + * Returns \ref nrEntries[i][j] + */ + inline const int getNumberEntries(unsigned int i, unsigned int j) const + { + if ((nrEntries)&&(nrEntries[i])) return nrEntries[i][j]; + return 0; + }; + + /** \brief + * Returns \ref nrEntries + */ + inline const int** getNumberEntries() const { + return const_cast<const int**>( nrEntries); + }; + + /** \brief + * Returns \ref k[i1][i2][i3] + */ + inline const int + getK(unsigned int i1, unsigned int i2, unsigned int i3) const + { + if ((k)&&(k[i1])&&(k[i1][i2])&&((static_cast<int>(i3))<nrEntries[i1][i2])) + return k[i1][i2][i3]; + return 0; + }; + + /** \brief + * Returns \ref l[i][j][v] + */ + inline const int getL(unsigned int i, unsigned int j, unsigned int v) const + { + if ((l)&&(l[i])&&(l[i][j])&&((static_cast<int>(v))<nrEntries[i][j])) return l[i][j][v]; + return 0; + }; + + /** \brief + * Returns \values[i][j] + */ + inline const double *getValVec(unsigned int i, unsigned int j) const { + if ((values)&&(values[i])&&(values[i][j])) return values[i][j]; + return NULL; + }; + + /** \brief + * Returns \ref k[i][j] + */ + inline const int *getKVec(unsigned int i, unsigned int j) const { + if ((k)&&(k[i])&&(k[i][j])) return k[i][j]; + return NULL; + }; + + /** \brief + * Returns \ref l[i][j] + */ + inline const int *getLVec(unsigned int i,unsigned int j) const { + if ((l)&&(l[i])&&(l[i][j])) return l[i][j]; + return NULL; + }; + + protected: + /** \brief + * List of pointers to all Q11PsiPhi objects + */ + static ::std::list<Q11PsiPhi*> preList; + + /** \brief + * Pointer to the first set of basis functions + */ + const BasisFunction *psi; + + /** \brief + * pointer to the second set of basis functions + */ + const BasisFunction *phi; + + /** \brief + * Pointer to the Quadrature which is used for the integration + */ + const Quadrature *quadrature; + + /** \brief + * Matrix of size psi->getNumber() * phi->getNumber() storing the count of + * non zero integrals; nrEntries[i][j] is the count of non zero values of + * \f$ \hat{Q}_{ij,kl}^{11} \f$ + * (0 <= k,l <= DIM) for the pair (psi[i], phi[j]), 0 <= i < + * psi->getNumber(), 0 <= j < phi->getNumber() + */ + int **nrEntries; + + /** \brief + * tensor storing the non zero integrals; values[i][j] is a vector of length + * \ref nrEntries[i][j] storing the non zero values for the pair (psi[i], + * phi[j]) + */ + double ***values; + + /** \brief + * tensor storing the indices k of the non zero integrals; + */ + int ***k; + + /** \brief + * tensor storing the indices l of the non zero integrals; + */ + int ***l; + + /** \brief + * Number of non zero entries. + */ + int allEntries; + + /** \brief + * Pointer to an array in values. + */ + double *val_vec; + + /** \brief + * Pointer to an array in k. + */ + int *k_vec; + + /** \brief + * Pointer to an array in l. + */ + int *l_vec; + + friend class compareQPsiPhi<Q11PsiPhi>; + }; + + + + // =========================================================================== + // ===== class Q10PsiPhi ===================================================== + // =========================================================================== + + /** \ingroup Integration + * \brief + * Calculates element stiffness matrices by preevaluated integrals over the + * the reference element (integral of the product of the derivative of psi + * and phi). + */ + class Q10PsiPhi + { + public: + MEMORY_MANAGED(Q10PsiPhi); + + protected: + /** \brief + * Constructor + */ + Q10PsiPhi(const BasisFunction *psi, + const BasisFunction *phi, + const Quadrature *q); + + public: + /** \brief + * Destructor + */ + ~Q10PsiPhi(); + + /** \brief + * Returns a Q10PsiPhi object. + */ + static const Q10PsiPhi* provideQ10PsiPhi(const BasisFunction *, + const BasisFunction *, + const Quadrature*); + + /** \brief + * Compares two Q10PsiPhi objects. + */ + const bool operator==(const Q10PsiPhi&) const; + + /** \brief + * Compares two Q10PsiPhi objects. + */ + const bool operator!=(const Q10PsiPhi& q10pp) const { + return !(operator==(q10pp)); + }; + + + /** \brief + * Returns \ref values[i][j][k] + */ + inline const double getValue(unsigned int i, + unsigned int j, + unsigned int v) const + { + if ((values)&&(values[i])&&(values[i][j])&&((static_cast<int>(v))<nrEntries[i][j])) return values[i][j][v]; + return 0.; + }; + + /** \brief + * Returns \ref nrEntries[i][j] + */ + inline const int getNumberEntries(unsigned int i, unsigned int j) const { + if ((nrEntries)&&(nrEntries[i])) return nrEntries[i][j]; + return 0; + }; + + /** \brief + * Returns \ref nrEntries + */ + inline const int** getNumberEntries() const { + return const_cast<const int**>(nrEntries); + }; + + /** \brief + * Returns \ref k[i1][i2][i3] + */ + inline const int + getK(unsigned int i1, unsigned int i2, unsigned int i3) const + { + if ((k)&&(k[i1])&&(k[i1][i2])&&((static_cast<int>(i3))<nrEntries[i1][i2])) + return k[i1][i2][i3]; + return 0; + }; + + /** \brief + * Returns \values[i][j] + */ + inline const double *getValVec(unsigned int i, unsigned int j) const { + if ((values)&&(values[i])&&(values[i][j])) return values[i][j]; + return NULL; + }; + + /** \brief + * Returns \ref k[i][j] + */ + inline const int *getKVec(unsigned int i, unsigned int j) const { + if ((k)&&(k[i])&&(k[i][j])) return k[i][j]; + return NULL; + }; + + protected: + /** \brief + * List of pointers to all Q11PsiPhi objects + */ + static ::std::list<Q10PsiPhi*> preList; + + /** \brief + * Pointer to the first set of basis functions + */ + const BasisFunction *psi; + + /** \brief + * pointer to the second set of basis functions + */ + const BasisFunction *phi; + + /** \brief + * Pointer to the Quadrature which is used for the integration + */ + const Quadrature *quadrature; + + /** \brief + * Matrix of size psi->getNumber() * phi->getNumber() storing the count of + * non zero integrals; nrEntries[i][j] is the count of non zero values of + * \f$ \hat{Q}_{ij,kl}^{11} \f$ + * (0 <= k,l <= DIM) for the pair (psi[i], phi[j]), 0 <= i < + * psi->getNumber(), 0 <= j < phi->getNumber() + */ + int **nrEntries; + + /** \brief + * tensor storing the non zero integrals; values[i][j] is a vector of length + * \ref nrEntries[i][j] storing the non zero values for the pair (psi[i], + * phi[j]) + */ + double ***values; + + /** \brief + * tensor storing the indices k of the non zero integrals; + */ + int ***k; + + /** \brief + * Number of all non zero entries. + */ + int allEntries; + + /** \brief + * Pointer to an array in values. + */ + double *val_vec; + + /** \brief + * Pointer to an array in k. + */ + int *k_vec; + + friend class compareQPsiPhi<Q10PsiPhi>; + }; + + // =========================================================================== + // ===== class Q01PsiPhi ===================================================== + // =========================================================================== + + /** \ingroup Integration + * \brief + * Calculates element stiffness matrices by preevaluated integrals over the + * the reference element (integral of the product of psi and the derivative + * of phi). + */ + class Q01PsiPhi + { + public: + MEMORY_MANAGED(Q01PsiPhi); + + protected: + /** \brief + * Constructor + */ + Q01PsiPhi(const BasisFunction *psi, + const BasisFunction *phi, + const Quadrature *q); + + public: + /** \brief + * Destructor + */ + ~Q01PsiPhi(); + + /** \brief + * Returns a Q01PsiPhi object. + */ + static const Q01PsiPhi* provideQ01PsiPhi(const BasisFunction *, + const BasisFunction *, + const Quadrature*); + + /** \brief + * Compares two Q01PsiPhi objects. + */ + const bool operator==(const Q01PsiPhi&) const; + + /** \brief + * Compares two Q01PsiPhi objects. + */ + const bool operator!=(const Q01PsiPhi& q01pp) const { + return !(operator==(q01pp)); + }; + + + /** \brief + * Returns \ref values[i][j][k] + */ + inline const double getValue(unsigned int i, + unsigned int j, + unsigned int v) const + { + if ((values)&&(values[i])&&(values[i][j])&&((static_cast<int>(v))<nrEntries[i][j])) + return values[i][j][v]; + return 0.; + }; + + /** \brief + * Returns \ref nrEntries[i][j] + */ + inline const int getNumberEntries(unsigned int i, unsigned int j) const + { + if ((nrEntries)&&(nrEntries[i])) return nrEntries[i][j]; + return 0; + }; + + /** \brief + * Returns \ref nrEntries + */ + inline const int** getNumberEntries() const { + return const_cast<const int**>(nrEntries); + }; + + /** \brief + * Returns \ref k[i1][i2][i3] + */ + inline const int + getK(unsigned int i1, unsigned int i2, unsigned int i3) const; + + /** \brief + * Returns \values[i][j] + */ + inline const double *getValVec(unsigned int i, unsigned int j) const { + if ((values)&&(values[i])&&(values[i][j])) return values[i][j]; + return NULL; + }; + + /** \brief + * Returns \ref k[i][j] + */ + inline const int *getLVec(unsigned int i, unsigned int j) const { + if ((l)&&(l[i])&&(l[i][j])) return l[i][j]; + return NULL; + }; + + /** \brief + * Returns \ref k[i][j][v] + */ + inline const int getL(unsigned int i, + unsigned int j, + unsigned int v) const + { + if ((l)&&(l[i])&&(l[i][j])&&((static_cast<int>(v))<nrEntries[i][j])) return l[i][j][v]; + return 0; + }; + + protected: + /** \brief + * List of pointers to all Q11PsiPhi objects + */ + static ::std::list<Q01PsiPhi*> preList; + + /** \brief + * Pointer to the first set of basis functions + */ + const BasisFunction *psi; + + /** \brief + * pointer to the second set of basis functions + */ + const BasisFunction *phi; + + /** \brief + * Pointer to the Quadrature which is used for the integration + */ + const Quadrature *quadrature; + + /** \brief + * Matrix of size psi->getNumber() * phi->getNumber() storing the count of + * non zero integrals; nrEntries[i][j] is the count of non zero values of + * \f$ \hat{Q}_{ij,kl}^{11} \f$ + * (0 <= k,l <= DIM) for the pair (psi[i], phi[j]), 0 <= i < + * psi->getNumber(), 0 <= j < phi->getNumber() + */ + int **nrEntries; + + /** \brief + * tensor storing the non zero integrals; values[i][j] is a vector of length + * \ref nrEntries[i][j] storing the non zero values for the pair (psi[i], + * phi[j]) + */ + double ***values; + + /** \brief + * tensor storing the indices l of the non zero integrals; + */ + int ***l; + + /** \brief + * Number of all non zero entries. + */ + int allEntries; + + /** \brief + * Pointer to an array in values + */ + double *val_vec; + + /** \brief + * Pointer to an array in l. + */ + int *l_vec; + + friend class compareQPsiPhi<Q01PsiPhi>; + }; + + // =========================================================================== + // ===== class Q00PsiPhi ===================================================== + // =========================================================================== + + /** \ingroup Integration + * \brief + * Calculates element stiffness matrices by preevaluated integrals over the + * the reference element (integral of the product of psi and phi). + */ + class Q00PsiPhi + { + protected: + MEMORY_MANAGED(Q00PsiPhi); + + /** \brief + * List of pointers to all Q11PsiPhi objects + */ + static ::std::list<Q00PsiPhi*> preList; + + /** \brief + * Pointer to the first set of basis functions + */ + const BasisFunction *psi; + + /** \brief + * pointer to the second set of basis functions + */ + const BasisFunction *phi; + + /** \brief + * Pointer to the Quadrature which is used for the integration + */ + const Quadrature *quadrature; + + /** \brief + * Matrix storing the integrals + * \f[ values[i][j] = \hat{Q}_{ij}^{00} = \hat{Q}(\overline{\psi}^i + * \overline{\phi}^j) \f] + * for the pair (psi[i], phi[j]), 0 <= i <= psi->getNumber(), + * 0 <= j <= phi->getNumber() + */ + double **values; + + protected: + /** \brief + * Constructor + */ + Q00PsiPhi(const BasisFunction *, + const BasisFunction *, + const Quadrature*); + + public: + /** \brief + * Destructor + */ + ~Q00PsiPhi(); + + /** \brief + * Returns a Q00PsiPhi object. + */ + static Q00PsiPhi* provideQ00PsiPhi(const BasisFunction *, + const BasisFunction *, + const Quadrature*); + + + /** \brief + * Compares two Q00PsiPhi objects. + */ + const bool operator==(const Q00PsiPhi&) const; + + /** \brief + * Compares two Q00PsiPhi objects. + */ + const bool operator!=(const Q00PsiPhi& q00pp) const { + return !(operator==(q00pp)); + }; + + /** \brief + * Returns \ref values[i][j] + */ + const double getValue(unsigned int i,unsigned int j) const; + + /** \brief + * Returns \ref values[i] + */ + const double *getValVec(unsigned int i) const; + + friend class compareQPsiPhi<Q00PsiPhi>; + }; + + + // =========================================================================== + // ===== class Q0Psi ========================================================= + // =========================================================================== + + /** \ingroup Integration + * \brief + * Integral of psi. + */ + class Q0Psi + { + public: + MEMORY_MANAGED(Q0Psi); + + protected: + /** \brief + * List of pointers to all Q0Psi objects + */ + static ::std::list<Q0Psi*> preList; + + /** \brief + * Pointer to the first set of basis functions + */ + const BasisFunction *psi; + + /** \brief + * Pointer to the Quadrature which is used for the integration + */ + const Quadrature *quadrature; + + /** \brief + * Vector storing the integrals + */ + double* values; + + protected: + /** \brief + * Constructor + */ + Q0Psi(const BasisFunction *, + const Quadrature*); + + public: + /** \brief + * Destructor + */ + ~Q0Psi(); + + /** \brief + * Returns a Q0Psi object. + */ + static Q0Psi* provideQ0Psi(const BasisFunction *, const Quadrature*); + + /** \brief + * Compares two Q0Psi objects. + */ + const bool operator==(const Q0Psi&) const; + + /** \brief + * Compares two Q0Psi objects. + */ + const bool operator!=(const Q0Psi& q0p) const { + return !(operator==(q0p)); + }; + + /** \brief + * Returns \ref value + */ + inline const double getValue(int i) const { return values[i]; }; + + /** \brief + * Returns \ref values[i] + */ + inline const double *getValVec() const { + return values; + }; + + friend class compareQPsi<Q0Psi>; + }; + + // =========================================================================== + // ===== class Q1Psi ========================================================= + // =========================================================================== + + /** \ingroup Integration + * \brief + * Integral of the derivative of psi. + */ + class Q1Psi + { + public: + MEMORY_MANAGED(Q1Psi); + + protected: + /** \brief + * Constructor + */ + Q1Psi(const BasisFunction *psi, + const Quadrature *q); + + + public: + /** \brief + * Destructor + */ + ~Q1Psi(); + + /** \brief + * Returns a Q1Psi object. + */ + static const Q1Psi* provideQ1Psi(const BasisFunction *, + const Quadrature*); + + /** \brief + * Compares two Q1Psi objects. + */ + const bool operator==(const Q1Psi&) const; + + /** \brief + * Compares two Q1Psi objects. + */ + const bool operator!=(const Q1Psi& q1p) const { + return !(operator==(q1p)); + }; + + /** \brief + * Returns \ref values[i][j] + */ + inline const double getValue(unsigned int i, + unsigned int j) const + { + if ((values)&&(values[i])&&((static_cast<int>(j))<nrEntries[i])) + return values[i][j]; + return 0.; + }; + + /** \brief + * Returns \ref nrEntries[i] + */ + inline const int getNumberEntries(unsigned int i) const + { + if (nrEntries) return nrEntries[i]; + return 0; + }; + + /** \brief + * Returns \ref nrEntries + */ + inline const int* getNumberEntries() const { + return const_cast<const int*>(nrEntries); + }; + + /** \brief + * Returns \ref k[i1][i2] + */ + inline const int + getK(unsigned int i1, unsigned int i2) const + { + if ((k)&&(k[i1])&&((static_cast<int>(i2))<nrEntries[i1])) + return k[i1][i2]; + return 0; + }; + + /** \brief + * Returns \ref k[i] + */ + inline const int *getKVec(unsigned int i) const { + if ((k)&&(k[i])) return k[i]; + return NULL; + }; + + /** \brief + * Returns \values[i] + */ + inline const double *getValVec(unsigned int i) const { + if ((values)&&(values[i])) return values[i]; + return NULL; + }; + + protected: + /** \brief + * List of pointers to all Q1Psi objects + */ + static ::std::list<Q1Psi*> preList; + + /** \brief + * Pointer to the first set of basis functions + */ + const BasisFunction *psi; + + /** \brief + * Pointer to the Quadrature which is used for the integration + */ + const Quadrature *quadrature; + + /** \brief + * Array of size psi->getNumber() storing the count of + * non zero integrals; nrEntries[i] is the count of non zero values of + * \f$ \hat{Q}_{i,kl}^{11} \f$ + * (0 <= k <= DIM) for psi[i], 0 <= i < psi->getNumber(). + */ + int *nrEntries; + + /** \brief + * Number of all non zero entries. + */ + int allEntries; + + /** \brief + * tensor storing the non zero integrals; values[i] is a vector of length + * \ref nrEntries[i] storing the non zero values for psi[i]. + */ + double **values; + + /** \brief + * Matrix storing the indices k of the non zero integrals; + */ + int **k; + + /** \brief + * Pointer to an array in values. + */ + double *val_vec; + + /** \brief + * Pointer to an array in k. + */ + int *k_vec; + + friend class compareQPsi<Q1Psi>; + }; + +} + +#endif // AMDIS_ASSEMBLE_H diff --git a/AMDiS/src/Quadrature.cc b/AMDiS/src/Quadrature.cc new file mode 100644 index 0000000000000000000000000000000000000000..7e67028accec4e7b6cbb141e1cc665b0e289f035 --- /dev/null +++ b/AMDiS/src/Quadrature.cc @@ -0,0 +1,2143 @@ +#include "Quadrature.h" +#include "FixVec.h" +#include "AbstractFunction.h" +#include <algorithm> + +namespace AMDiS { + + const int Quadrature::maxNQuadPoints[4] = {0, 10, 61, 64}; + + ::std::list<FastQuadrature*> FastQuadrature::fastQuadList; + int FastQuadrature::max_points = 0; + + Quadrature::Quadrature(const Quadrature& q) + { + name = q.name; + degree = q.degree; + dim = q.dim; + n_points = q.n_points; + + // copy barycentric coordinates + lambda = NEW VectorOfFixVecs<DimVec<double> >(*(q.lambda)); + + // copy weights + w = GET_MEMORY(double, n_points); + + int i; + for(i=0; i < n_points; i++) { + w[i] = q.w[i]; + } + } + + /****************************************************************************/ + /* initialize gradient values of a function f in local coordinates at the */ + /* quadrature points */ + /****************************************************************************/ + + const WorldVector<double> + *Quadrature::grdFAtQp(const AbstractFunction<WorldVector<double>, DimVec<double> >& f, + WorldVector<double>* vec) const + { + FUNCNAME("Quadrature::grdFAtQp"); + static WorldVector<double> *quad_vec_d = NULL; + static size_t size = 0; + WorldVector<double> *val; + int i, j; + WorldVector<double> grd; + + if (vec) + { + val = vec; + } + else + { + if (static_cast<int>( size) < n_points) + { + size_t new_size = ::std::max(maxNQuadPoints[dim], n_points); + DELETE [] quad_vec_d; + quad_vec_d=NEW WorldVector<double>[new_size]; + size=new_size; + } + val = quad_vec_d; + } + + int dow = Global::getGeo(WORLD); + + for (i = 0; i < n_points; i++) + { + grd = f((*lambda)[i]); + for (j = 0; j < dow; j++) + val[i][j] = grd[j]; + } + + return val; + } + + const double + *Quadrature::fAtQp(const AbstractFunction<double, DimVec<double> >& f, + double *vec) const + { + FUNCNAME("Quadrature::fAtQp"); + + static double *quad_vec = NULL; + static size_t size = 0; + double *val; + int i; + + if (vec) + { + val = vec; + } + else + { + if (static_cast<int>( size) < n_points) + { + size_t new_size = ::std::max(maxNQuadPoints[dim], n_points); + FREE_MEMORY(quad_vec, double, size); + quad_vec = GET_MEMORY(double, new_size); + size = new_size; + } + val = quad_vec; + } + + for (i = 0; i < n_points; i++) + val[i] = f((*lambda)[i]); + + return(const_cast<const double *>(val)); + } + + + Quadrature **Quadrature::quad_nd[4]; + Quadrature *Quadrature::quad_0d[1]; + Quadrature *Quadrature::quad_1d[20]; + Quadrature *Quadrature::quad_2d[18]; + Quadrature *Quadrature::quad_3d[8]; + + VectorOfFixVecs<DimVec<double> > *Quadrature::x_0d; + double *Quadrature::w_0d; + + VectorOfFixVecs<DimVec<double> > *Quadrature::x0_1d = NULL; + VectorOfFixVecs<DimVec<double> > *Quadrature::x1_1d; + VectorOfFixVecs<DimVec<double> > *Quadrature::x2_1d; + VectorOfFixVecs<DimVec<double> > *Quadrature::x3_1d; + VectorOfFixVecs<DimVec<double> > *Quadrature::x4_1d; + VectorOfFixVecs<DimVec<double> > *Quadrature::x5_1d; + VectorOfFixVecs<DimVec<double> > *Quadrature::x6_1d; + VectorOfFixVecs<DimVec<double> > *Quadrature::x7_1d; + VectorOfFixVecs<DimVec<double> > *Quadrature::x8_1d; + VectorOfFixVecs<DimVec<double> > *Quadrature::x9_1d; + double *Quadrature::w0_1d; + double *Quadrature::w1_1d; + double *Quadrature::w2_1d; + double *Quadrature::w3_1d; + double *Quadrature::w4_1d; + double *Quadrature::w5_1d; + double *Quadrature::w6_1d; + double *Quadrature::w7_1d; + double *Quadrature::w8_1d; + double *Quadrature::w9_1d; + + VectorOfFixVecs<DimVec<double> > *Quadrature::x1_2d; + VectorOfFixVecs<DimVec<double> > *Quadrature::x2_2d; + VectorOfFixVecs<DimVec<double> > *Quadrature::x3_2d; + VectorOfFixVecs<DimVec<double> > *Quadrature::x4_2d; + VectorOfFixVecs<DimVec<double> > *Quadrature::x5_2d; + VectorOfFixVecs<DimVec<double> > *Quadrature::x7_2d; + VectorOfFixVecs<DimVec<double> > *Quadrature::x8_2d; + VectorOfFixVecs<DimVec<double> > *Quadrature::x9_2d; + VectorOfFixVecs<DimVec<double> > *Quadrature::x10_2d; + VectorOfFixVecs<DimVec<double> > *Quadrature::x11_2d; + VectorOfFixVecs<DimVec<double> > *Quadrature::x12_2d; + VectorOfFixVecs<DimVec<double> > *Quadrature::x17_2d; + double *Quadrature::w1_2d; + double *Quadrature::w2_2d; + double *Quadrature::w3_2d; + double *Quadrature::w4_2d; + double *Quadrature::w5_2d; + double *Quadrature::w7_2d; + double *Quadrature::w8_2d; + double *Quadrature::w9_2d; + double *Quadrature::w10_2d; + double *Quadrature::w11_2d; + double *Quadrature::w12_2d; + double *Quadrature::w17_2d; + + VectorOfFixVecs<DimVec<double> > *Quadrature::x1_3d; + VectorOfFixVecs<DimVec<double> > *Quadrature::x2_3d; + VectorOfFixVecs<DimVec<double> > *Quadrature::x3_3d; + VectorOfFixVecs<DimVec<double> > *Quadrature::x4_3d; + VectorOfFixVecs<DimVec<double> > *Quadrature::x5_3d; + VectorOfFixVecs<DimVec<double> > *Quadrature::x7_3d; + double *Quadrature::w1_3d; + double *Quadrature::w2_3d; + double *Quadrature::w3_3d; + double *Quadrature::w4_3d; + double *Quadrature::w5_3d; + double *Quadrature::w7_3d; + + + void Quadrature::initStaticQuadratures() + { + + TEST_EXIT(x0_1d==NULL)("static quadratures already initialized\n"); + +#define zero 0.0 +#define one 1.0 +#define half 0.5 +#define third 1.0/3.0 +#define quart 1.0/4.0 + +#define StdVol 1.0 + + x_0d = + createAndInit(0, 1, 1.0); + + w_0d = + createAndInitArray(1, StdVol*1.0); + + Quadrature::quad_0d[0]= NEW Quadrature("0d", 0, 0, 1, Quadrature::x_0d, Quadrature::w_0d); + + /****************************************************************************/ + /* 1d quadrature formulas using 2 barycentric coordinates */ + /****************************************************************************/ + +#define MAX_QUAD_DEG_1d 19 + + /****************************************************************************/ + /* quadrature exact on P_1 */ + /****************************************************************************/ + + x0_1d = + createAndInit(1, 1, + 0.5, 0.5); + w0_1d = createAndInitArray(1, StdVol*1.0); + + /****************************************************************************/ + /* quadrature exact on P_3 */ + /****************************************************************************/ + + x1_1d = + createAndInit(1, 2, + 0.788675134594813, 0.211324865405187, + 0.211324865405187, 0.788675134594813); + w1_1d = createAndInitArray(2, StdVol*0.5, StdVol*0.5); + + /****************************************************************************/ + /* quadrature exact on P_5 */ + /****************************************************************************/ + + + x2_1d = + createAndInit(1, 3, + 0.887298334620741, 0.112701665379259, + 0.500000000000000, 0.500000000000000, + 0.112701665379259, 0.887298334620741); + w2_1d = createAndInitArray(3, StdVol*0.277777777777778, + StdVol*0.444444444444444, + StdVol*0.277777777777778); + + /****************************************************************************/ + /* quadrature exact on P_7 */ + /****************************************************************************/ + + x3_1d = + createAndInit(1, 4, + 0.930568155797026, 0.069431844202973, + 0.669990521792428, 0.330009478207572, + 0.330009478207572, 0.669990521792428, + 0.069431844202973, 0.930568155797026); + w3_1d = createAndInitArray(4, StdVol*0.173927422568727, + StdVol*0.326072577431273, + StdVol*0.326072577431273, + StdVol*0.173927422568727); + + /****************************************************************************/ + /* quadrature exact on P_9 */ + /****************************************************************************/ + + x4_1d = + createAndInit(1, 5, + 0.953089922969332, 0.046910077030668, + 0.769234655052841, 0.230765344947159, + 0.500000000000000, 0.500000000000000, + 0.230765344947159, 0.769234655052841, + 0.046910077030668, 0.953089922969332); + w4_1d = createAndInitArray(5, StdVol*0.118463442528095, + StdVol*0.239314335249683, + StdVol*0.284444444444444, + StdVol*0.239314335249683, + StdVol*0.118463442528095); + + /****************************************************************************/ + /* quadrature exact on P_11 */ + /****************************************************************************/ + + x5_1d = + createAndInit(1, 6, + 0.966234757101576, 0.033765242898424, + 0.830604693233133, 0.169395306766867, + 0.619309593041598, 0.380690406958402, + 0.380690406958402, 0.619309593041598, + 0.169395306766867, 0.830604693233133, + 0.033765242898424, 0.966234757101576); + w5_1d = createAndInitArray(6, StdVol*0.085662246189585, + StdVol*0.180380786524069, + StdVol*0.233956967286345, + StdVol*0.233956967286345, + StdVol*0.180380786524069, + StdVol*0.085662246189585); + + /****************************************************************************/ + /* quadrature exact on P_13 */ + /****************************************************************************/ + + x6_1d = + createAndInit(1, 7, + 0.974553956171380, 0.025446043828620, + 0.870765592799697, 0.129234407200303, + 0.702922575688699, 0.297077424311301, + 0.500000000000000, 0.500000000000000, + 0.297077424311301, 0.702922575688699, + 0.129234407200303, 0.870765592799697, + 0.025446043828620, 0.974553956171380); + w6_1d = createAndInitArray(7, StdVol*0.064742483084435, + StdVol*0.139852695744614, + StdVol*0.190915025252559, + StdVol*0.208979591836735, + StdVol*0.190915025252559, + StdVol*0.139852695744614, + StdVol*0.064742483084435); + + /****************************************************************************/ + /* quadrature exact on P_15 */ + /****************************************************************************/ + + x7_1d = + createAndInit(1, 8, + 0.980144928248768, 0.019855071751232, + 0.898333238706813, 0.101666761293187, + 0.762766204958164, 0.237233795041836, + 0.591717321247825, 0.408282678752175, + 0.408282678752175, 0.591717321247825, + 0.237233795041836, 0.762766204958164, + 0.101666761293187, 0.898333238706813, + 0.019855071751232, 0.980144928248768); + w7_1d = createAndInitArray(8, StdVol*0.050614268145188, + StdVol*0.111190517226687, + StdVol*0.156853322938943, + StdVol*0.181341891689181, + StdVol*0.181341891689181, + StdVol*0.156853322938943, + StdVol*0.111190517226687, + StdVol*0.050614268145188); + + /****************************************************************************/ + /* quadrature exact on P_17 */ + /****************************************************************************/ + + x8_1d = + createAndInit(1, 9, + 0.984080119753813, 0.015919880246187, + 0.918015553663318, 0.081984446336682, + 0.806685716350295, 0.193314283649705, + 0.662126711701905, 0.337873288298095, + 0.500000000000000, 0.500000000000000, + 0.337873288298095, 0.662126711701905, + 0.193314283649705, 0.806685716350295, + 0.081984446336682, 0.918015553663318, + 0.015919880246187, 0.984080119753813); + w8_1d = createAndInitArray(9, StdVol*0.040637194180787, + StdVol*0.090324080347429, + StdVol*0.130305348201467, + StdVol*0.156173538520001, + StdVol*0.165119677500630, + StdVol*0.156173538520001, + StdVol*0.130305348201467, + StdVol*0.090324080347429, + StdVol*0.040637194180787); + + /****************************************************************************/ + /* quadrature exact on P_19 */ + /****************************************************************************/ + + x9_1d = + createAndInit(1, 10, + 0.986953264258586, 0.013046735741414, + 0.932531683344493, 0.067468316655508, + 0.839704784149512, 0.160295215850488, + 0.716697697064623, 0.283302302935377, + 0.574437169490815, 0.425562830509185, + 0.425562830509185, 0.574437169490815, + 0.283302302935377, 0.716697697064623, + 0.160295215850488, 0.839704784149512, + 0.067468316655508, 0.932531683344493, + 0.013046735741414, 0.986953264258586); + w9_1d = createAndInitArray(10, StdVol*0.033335672154344, + StdVol*0.074725674575291, + StdVol*0.109543181257991, + StdVol*0.134633359654998, + StdVol*0.147762112357376, + StdVol*0.147762112357376, + StdVol*0.134633359654998, + StdVol*0.109543181257991, + StdVol*0.074725674575291, + StdVol*0.033335672154344); + + Quadrature::quad_1d[0]= NEW Quadrature("1d-Gauss: P_1", 1, 1, 1, Quadrature::x0_1d, Quadrature::w0_1d); /* P_0 */ + Quadrature::quad_1d[1]= NEW Quadrature("1d-Gauss: P_1", 1, 1, 1, Quadrature::x0_1d, Quadrature::w0_1d); /* P_1 */ + Quadrature::quad_1d[2]= NEW Quadrature("1d-Gauss: P_3", 3, 1, 2, Quadrature::x1_1d, Quadrature::w1_1d); /* P_2 */ + Quadrature::quad_1d[3]= NEW Quadrature("1d-Gauss: P_3", 3, 1, 2, Quadrature::x1_1d, Quadrature::w1_1d); /* P_3 */ + Quadrature::quad_1d[4]= NEW Quadrature("1d-Gauss: P_5", 5, 1, 3, Quadrature::x2_1d, Quadrature::w2_1d); /* P_4 */ + Quadrature::quad_1d[5]= NEW Quadrature("1d-Gauss: P_5", 5, 1, 3, Quadrature::x2_1d, Quadrature::w2_1d); /* P_5 */ + Quadrature::quad_1d[6]= NEW Quadrature("1d-Gauss: P_7", 7, 1, 4, Quadrature::x3_1d, Quadrature::w3_1d); /* P_6 */ + Quadrature::quad_1d[7]= NEW Quadrature("1d-Gauss: P_7", 7, 1, 4, Quadrature::x3_1d, Quadrature::w3_1d); /* P_7 */ + Quadrature::quad_1d[8]= NEW Quadrature("1d-Gauss: P_9", 9, 1, 5, Quadrature::x4_1d, Quadrature::w4_1d); /* P_8 */ + Quadrature::quad_1d[9]= NEW Quadrature("1d-Gauss: P_9", 9, 1, 5, Quadrature::x4_1d, Quadrature::w4_1d); /* P_9 */ + Quadrature::quad_1d[10]= NEW Quadrature("1d-Gauss: P_11", 11, 1, 6, Quadrature::x5_1d, Quadrature::w5_1d); /* P_10 */ + Quadrature::quad_1d[11]= NEW Quadrature("1d-Gauss: P_11", 11, 1, 6, Quadrature::x5_1d, Quadrature::w5_1d); /* P_11 */ + Quadrature::quad_1d[12]= NEW Quadrature("1d-Gauss: P_13", 13, 1, 7, Quadrature::x6_1d, Quadrature::w6_1d); /* P_12 */ + Quadrature::quad_1d[13]= NEW Quadrature("1d-Gauss: P_13", 13, 1, 7, Quadrature::x6_1d, Quadrature::w6_1d); /* P_13 */ + Quadrature::quad_1d[14]= NEW Quadrature("1d-Gauss: P_15", 15, 1, 8, Quadrature::x7_1d, Quadrature::w7_1d); /* P_14 */ + Quadrature::quad_1d[15]= NEW Quadrature("1d-Gauss: P_15", 15, 1, 8, Quadrature::x7_1d, Quadrature::w7_1d); /* P_15 */ + Quadrature::quad_1d[16]= NEW Quadrature("1d-Gauss: P_17", 17, 1, 9, Quadrature::x8_1d, Quadrature::w8_1d); /* P_16 */ + Quadrature::quad_1d[17]= NEW Quadrature("1d-Gauss: P_17", 17, 1, 9, Quadrature::x8_1d, Quadrature::w8_1d); /* P_17 */ + Quadrature::quad_1d[18]= NEW Quadrature("1d-Gauss: P_19", 19, 1, 10, Quadrature::x9_1d, Quadrature::w9_1d); /* P_18 */ + Quadrature::quad_1d[19]= NEW Quadrature("1d-Gauss: P_19", 19, 1, 10, Quadrature::x9_1d, Quadrature::w9_1d);/* P_19 */ + +#undef StdVol + /****************************************************************************/ + /****************************************************************************/ + /****************************************************************************/ + /* 2d quadrature formulas using 3 barycentric coordinates */ + /****************************************************************************/ + /****************************************************************************/ + /****************************************************************************/ + +#define CYCLE(c1,c2,c3) c1, c2, c3, c2, c3, c1, c3, c1, c2 + +#define ALL_COMB(c1,c2,c3) CYCLE(c1,c2,c3), CYCLE(c1,c3,c2) +#define W_CYCLE(w1) w1, w1, w1 +#define W_ALL_COMB(w1) W_CYCLE(w1), W_CYCLE(w1) + +#define MAX_QUAD_DEG_2d 17 + +#define StdVol 0.5 + + /****************************************************************************/ + /* quadrature exact on P 1 */ + /****************************************************************************/ + +#define N1 1 + +#define c1 1.0/3.0 +#define w1 StdVol*1.0 + + x1_2d = + createAndInit(2, 1, + c1, c1, c1); + w1_2d = createAndInitArray(N1, w1); + +#undef c1 +#undef w1 + + /****************************************************************************/ + /* quadrature exact on P 2 */ + /* Stroud, A.H.: Approximate calculation of multiple integrals */ + /* Prentice-Hall Series in Automatic Computation. (1971) */ + /* optimal number of points: 3, number of points: 3 */ + /* interior points, completly symmetric in barycentric coordinates */ + /****************************************************************************/ + +#define N2 3 + +#define c1 2.0/3.0 +#define c2 1.0/6.0 +#define w1 StdVol/3.0 + + x2_2d = + createAndInit(2, 3, + CYCLE(c1, c2, c2)); + w2_2d = createAndInitArray(3, W_CYCLE(w1)); + +#undef c1 +#undef c2 +#undef w1 + + /****************************************************************************/ + /* quadrature exact on P_3 */ + /****************************************************************************/ + + +#if 0 + /* optimales von Hillon, P mit 4 St"utzstellen */ + irgendwas stimmt hier mit den Gewichten nicht!!! +#define N3 4 + +#define c1 1.0/3.0 +#define c2 3.0/5.0 +#define c3 1.0/5.0 +#define w1 StdVol*7.0/32.0 +#define w2 StdVol*25.0/96.0 + + const double w3_2d[N3] = createAndInit(N3, w1, W_CYCLE(w2)); + +#undef c1 +#undef c2 +#undef c3 +#undef w1 +#undef w2 +#else + +#define N3 6 + +#define c1 0.0 +#define c2 1.0/2.0 +#define c3 4.0/6.0 +#define c4 1.0/6.0 +#define w1 StdVol*1.0/30.0 +#define w2 StdVol*9.0/30.0 + + x3_2d = + createAndInit(2, N3, + CYCLE(c1,c2,c2), CYCLE(c3,c4,c4)); + w3_2d = createAndInitArray(N3, W_CYCLE(w1), W_CYCLE(w2)); + +#undef c1 +#undef c2 +#undef c3 +#undef c4 +#undef w1 +#undef w2 +#endif + + /****************************************************************************/ + /* quadrature exact on P 4 */ + /* Dunavant, D.A.: High degree efficient symmetrical Gaussian quadrature */ + /* rules for the triangle. Int. J. Numer. Methods Eng. 21, 1129-1148 (1985) */ + /* nearly optimal number of (interior) points, positive wheights (PI) */ + /* number of points: 6, optimal number of points: 6 */ + /****************************************************************************/ + +#define N4 6 + +#define c1 0.816847572980459 +#define c2 0.091576213509771 +#define c3 0.108103018168070 +#define c4 0.445948490915965 +#define w1 StdVol*0.109951743655322 +#define w2 StdVol*0.223381589678011 + + x4_2d = + createAndInit(2, 6, + CYCLE(c1,c2,c2), CYCLE(c3,c4,c4)); + w4_2d = createAndInitArray(6, W_CYCLE(w1), W_CYCLE(w2)); + +#undef c1 +#undef c2 +#undef c3 +#undef c4 +#undef w1 +#undef w2 + + + /****************************************************************************/ + /* quadrature exact on P 5 */ + /****************************************************************************/ + +#if 0 + /****************************************************************************/ + /* Stroud, A.H.: Approximate calculation of multiple integrals */ + /* Prentice-Hall Series in Automatic Computation. (1971) */ + /* number of points: 7, optimal number of points: 7 */ + /****************************************************************************/ + +#define N5 7 + +#define c1 1.0/3.0 +#define c2 0.0 +#define c3 1.0/2.0 +#define c4 1.0 +#define c5 0.0 +#define w1 StdVol*0.45 +#define w2 StdVol*4.0/30.0 +#define w3 StdVol*0.05 +#else + + /****************************************************************************/ + /* Dunavant, D.A.: High degree efficient symmetrical Gaussian quadrature */ + /* rules for the triangle. Int. J. Numer. Methods Eng. 21, 1129-1148 (1985) */ + /* nealy optimal number of (interior) points, positive wheights (PI) */ + /* number of points: 7, optimal number of points: 7 */ + /****************************************************************************/ + +#define N5 7 + +#define c1 1.0/3.0 +#define c2 0.797426985353087 +#define c3 0.101286507323456 +#define c4 0.059715871789770 +#define c5 0.470142064105115 +#define w1 StdVol*0.225000000000000 +#define w2 StdVol*0.125939180544827 +#define w3 StdVol*0.132394152788506 +#endif + + x5_2d = + createAndInit(2, 7, + c1, c1, c1, + CYCLE(c2,c3,c3), CYCLE(c4,c5,c5)); + w5_2d = createAndInitArray(N5, w1, W_CYCLE(w2), W_CYCLE(w3)); + +#undef c1 +#undef c2 +#undef c3 +#undef c4 +#undef c5 +#undef w1 +#undef w2 +#undef w3 + + /****************************************************************************/ + /* quadrature exact on P 6: only 12 point rule available in the literature */ + /* -> use quadrature exact on P 7 with 12 points */ + /****************************************************************************/ + + /****************************************************************************/ + /* quadrature exact on P 7 */ + /****************************************************************************/ + +#if 1 + /****************************************************************************/ + /* Gatermann, Karin: The construction of symmetric cubature formulas for */ + /* the square and the triangle. Computing 40, No.3, 229-240 (1988) */ + /* optimal number of points: 12, number of points: 12 */ + /* only interior points, not completly symmetric in barycentric coordinates */ + /****************************************************************************/ + +#define N7 12 + +#define c1 0.06238226509439084 +#define c2 0.06751786707392436 +#define c3 0.87009986783168480 +#define c4 0.05522545665692000 +#define c5 0.32150249385201560 +#define c6 0.62327204949106440 +#define c7 0.03432430294509488 +#define c8 0.66094919618679800 +#define c9 0.30472650086810720 +#define c10 0.5158423343536001 +#define c11 0.2777161669764050 +#define c12 0.2064414986699949 +#define w1 0.02651702815743450 +#define w2 0.04388140871444811 +#define w3 0.02877504278497528 +#define w4 0.06749318700980879 + + x7_2d = + createAndInit(2, 12, + CYCLE(c1,c2,c3), CYCLE(c4,c5,c6), + CYCLE(c7,c8,c9), CYCLE(c10,c11,c12)); + w7_2d = createAndInitArray(N7, W_CYCLE(w1), W_CYCLE(w2), + W_CYCLE(w3), W_CYCLE(w4)); + +#undef c1 +#undef c2 +#undef c3 +#undef c4 +#undef c5 +#undef c6 +#undef c7 +#undef c8 +#undef c9 +#undef c10 +#undef c11 +#undef c12 +#undef w1 +#undef w2 +#undef w3 +#undef w4 + +#else + + /****************************************************************************/ + /* Stroud, A.H.: Approximate calculation of multiple integrals */ + /* Prentice-Hall Series in Automatic Computation. (1971) */ + /* optimal number of points: 12, number of points: 16 */ + /* only interior points, not symmetric in barycentric coordinates */ + /****************************************************************************/ + +#define N7 16 + + const double w7_2d[N7] = createAndInitArray(N7, StdVol*0.047136736384287, + StdVol*0.070776135805325, + StdVol*0.045168098569998, + StdVol*0.010846451805605, + StdVol*0.088370177015713, + StdVol*0.132688432194675, + StdVol*0.084679449030002, + StdVol*0.020334519094395, + StdVol*0.088370177015713, + StdVol*0.132688432194675, + StdVol*0.084679449030002, + StdVol*0.020334519094395, + StdVol*0.047136736384287, + StdVol*0.070776135805325, + StdVol*0.045168098569998, + StdVol*0.010846451805605); + +#endif + + + /****************************************************************************/ + /* quadrature exact on P 8 */ + /* Dunavant, D.A.: High degree efficient symmetrical Gaussian quadrature */ + /* rules for the triangle. Int. J. Numer. Methods Eng. 21, 1129-1148 (1985) */ + /* nealy optimal number of (interior) points, positive wheights (PI) */ + /* number of points: 16, optimal number of points: 15 */ + /* only interior points, completly symmetric in barycentric coordinates */ + /****************************************************************************/ + +#define N8 16 + +#define c1 1.0/3.0 +#define c2 0.081414823414554 +#define c3 0.459292588292723 +#define c4 0.658861384496480 +#define c5 0.170569307751760 +#define c6 0.898905543365938 +#define c7 0.050547228317031 +#define c8 0.008394777409958 +#define c9 0.263112829634638 +#define c10 0.728492392955404 +#define w1 StdVol*0.144315607677787 +#define w2 StdVol*0.095091634267285 +#define w3 StdVol*0.103217370534718 +#define w4 StdVol*0.032458497623198 +#define w5 StdVol*0.027230314174435 + + x8_2d = + createAndInit(2, 16, + c1, c1, c1, + CYCLE(c2,c3,c3), + CYCLE(c4,c5,c5), + CYCLE(c6,c7,c7), + ALL_COMB(c8,c9,c10)); + w8_2d = createAndInitArray(N8, w1, W_CYCLE(w2), W_CYCLE(w3), + W_CYCLE(w4), W_ALL_COMB(w5)); + + +#undef c1 +#undef c2 +#undef c3 +#undef c4 +#undef c5 +#undef c6 +#undef c7 +#undef c8 +#undef c9 +#undef c10 +#undef w1 +#undef w2 +#undef w3 +#undef w4 +#undef w5 + + /****************************************************************************/ + /* quadrature exact on P 9 */ + /* Dunavant, D.A.: High degree efficient symmetrical Gaussian quadrature */ + /* rules for the triangle. Int. J. Numer. Methods Eng. 21, 1129-1148 (1985) */ + /* nealy optimal number of (interior) points, positive wheights (PI) */ + /* optimal number of points: ?, number of points: 19 */ + /* only interior points, completly symmetric in barycentric coordinates */ + /****************************************************************************/ + +#define N9 19 + +#define c1 1.0/3.0 +#define c2 0.020634961602525 +#define c3 0.489682519198738 +#define c4 0.125820817014127 +#define c5 0.437089591492937 +#define c6 0.623592928761935 +#define c7 0.188203535619033 +#define c8 0.910540973211095 +#define c9 0.044729513394453 +#define c10 0.036838412054736 +#define c11 0.221962989160766 +#define c12 0.741198598784498 +#define w1 StdVol*0.097135796282799 +#define w2 StdVol*0.031334700227139 +#define w3 StdVol*0.077827541004774 +#define w4 StdVol*0.079647738927210 +#define w5 StdVol*0.025577675658698 +#define w6 StdVol*0.043283539377289 + + x9_2d = + createAndInit(2, 19, + c1, c1, c1, + CYCLE(c2,c3,c3), + CYCLE(c4,c5,c5), + CYCLE(c6,c7,c7), + CYCLE(c8,c9,c9), + ALL_COMB(c10,c11,c12)); + w9_2d = createAndInitArray(N9, w1, + W_CYCLE(w2), + W_CYCLE(w3), + W_CYCLE(w4), + W_CYCLE(w5), + W_ALL_COMB(w6)); + +#undef c1 +#undef c2 +#undef c3 +#undef c4 +#undef c5 +#undef c6 +#undef c7 +#undef c8 +#undef c9 +#undef c10 +#undef c11 +#undef c12 +#undef w1 +#undef w2 +#undef w3 +#undef w4 +#undef w5 +#undef w6 + + /****************************************************************************/ + /* quadrature exact on P 10 */ + /* Dunavant, D.A.: High degree efficient symmetrical Gaussian quadrature */ + /* rules for the triangle. Int. J. Numer. Methods Eng. 21, 1129-1148 (1985) */ + /* nealy optimal number of (interior) points, positive wheights (PI) */ + /* optimal number of points: ?, number of points: 25 */ + /* only interior points, completly symmetric in barycentric coordinates */ + /****************************************************************************/ + +#define N10 25 + +#define c1 1.0/3.0 + +#define c2 0.028844733232685 +#define c3 0.485577633383657 + +#define c4 0.781036849029926 +#define c5 0.109481575485037 + +#define c6 0.141707219414880 +#define c7 0.307939838764121 +#define c8 0.550352941820999 + +#define c9 0.025003534762686 +#define c10 0.246672560639903 +#define c11 0.728323904597411 + +#define c12 0.009540815400299 +#define c13 0.066803251012200 +#define c14 0.923655933587500 + +#define w1 StdVol*0.090817990382754 +#define w2 StdVol*0.036725957756467 +#define w3 StdVol*0.045321059435528 +#define w4 StdVol*0.072757916845420 +#define w5 StdVol*0.028327242531057 +#define w6 StdVol*0.009421666963733 + + x10_2d = + createAndInit(2, 25, + c1, c1, c1, + CYCLE(c2,c3,c3), + CYCLE(c4,c5,c5), + ALL_COMB(c6,c7,c8), + ALL_COMB(c9,c10,c11), + ALL_COMB(c12,c13,c14)); + w10_2d = createAndInitArray(N10, w1, + W_CYCLE(w2), + W_CYCLE(w3), + W_ALL_COMB(w4), + W_ALL_COMB(w5), + W_ALL_COMB(w6)); + +#undef c1 +#undef c2 +#undef c3 +#undef c4 +#undef c5 +#undef c6 +#undef c7 +#undef c8 +#undef c9 +#undef c10 +#undef c11 +#undef c12 +#undef c13 +#undef c14 +#undef w1 +#undef w2 +#undef w3 +#undef w4 +#undef w5 +#undef w6 + + /****************************************************************************/ + /* quadrature exact on P 11 */ + /* Dunavant, D.A.: High degree efficient symmetrical Gaussian quadrature */ + /* rules for the triangle. Int. J. Numer. Methods Eng. 21, 1129-1148 (1985) */ + /* nealy optimal number of (interior) points, positive wheights (PI) */ + /* optimal number of points: ?, number of points: 27 */ + /* only interior points, completly symmetric in barycentric coordinates */ + /****************************************************************************/ + +#define N11 27 + +#define c1 -0.069222096541517 +#define c2 0.534611048270758 + +#define c3 0.202061394068290 +#define c4 0.398969302965855 + +#define c5 0.593380199137435 +#define c6 0.203309900431282 + +#define c7 0.761298175434837 +#define c8 0.119350912282581 + +#define c9 0.935270103777448 +#define c10 0.032364948111276 + +#define c11 0.050178138310495 +#define c12 0.356620648261293 +#define c13 0.593201213428213 + +#define c14 0.021022016536166 +#define c15 0.171488980304042 +#define c16 0.807489003159792 + +#define w1 StdVol*0.000927006328961 +#define w2 StdVol*0.077149534914813 +#define w3 StdVol*0.059322977380774 +#define w4 StdVol*0.036184540503418 +#define w5 StdVol*0.013659731002678 +#define w6 StdVol*0.052337111962204 +#define w7 StdVol*0.020707659639141 + + x11_2d = createAndInit(2, 27, + CYCLE(c1,c2,c2), + CYCLE(c3,c4,c4), + CYCLE(c5,c6,c6), + CYCLE(c7,c8,c8), + CYCLE(c9,c10,c10), + ALL_COMB(c11,c12,c13), + ALL_COMB(c14,c15,c16)); + w11_2d = createAndInitArray(N11, W_CYCLE(w1), + W_CYCLE(w2), + W_CYCLE(w3), + W_CYCLE(w4), + W_CYCLE(w5), + W_ALL_COMB(w6), + W_ALL_COMB(w7)); + +#undef c1 +#undef c2 +#undef c3 +#undef c4 +#undef c5 +#undef c6 +#undef c7 +#undef c8 +#undef c9 +#undef c10 +#undef c11 +#undef c12 +#undef c13 +#undef c14 +#undef c15 +#undef c16 +#undef w1 +#undef w2 +#undef w3 +#undef w4 +#undef w5 +#undef w6 +#undef w7 + + /****************************************************************************/ + /* quadrature exact on P 12 */ + /* Dunavant, D.A.: High degree efficient symmetrical Gaussian quadrature */ + /* rules for the triangle. Int. J. Numer. Methods Eng. 21, 1129-1148 (1985) */ + /* nealy optimal number of (interior) points, positive wheights (PI) */ + /* optimal number of points: 2, number of points: 25 */ + /* only interior points, completly symmetric in barycentric coordinates */ + /****************************************************************************/ + +#define N12 33 + +#define c1 0.023565220452390 +#define c2 0.488217389773805 + +#define c3 0.120551215411079 +#define c4 0.439724392294460 + +#define c5 0.457579229975768 +#define c6 0.271210385012116 + +#define c7 0.744847708916828 +#define c8 0.127576145541586 + +#define c9 0.957365299093579 +#define c10 0.021317350453210 + +#define c11 0.115343494534698 +#define c12 0.275713269685514 +#define c13 0.608943235779788 + +#define c14 0.022838332222257 +#define c15 0.281325580989940 +#define c16 0.695836086787803 + +#define c17 0.025734050548330 +#define c18 0.116251915907597 +#define c19 0.858014033544073 + +#define w1 StdVol*0.025731066440455 +#define w2 StdVol*0.043692544538038 +#define w3 StdVol*0.062858224217885 +#define w4 StdVol*0.034796112930709 +#define w5 StdVol*0.006166261051559 +#define w6 StdVol*0.040371557766381 +#define w7 StdVol*0.022356773202303 +#define w8 StdVol*0.017316231108659 + + x12_2d = createAndInit(2, 33, + CYCLE(c1,c2,c2), + CYCLE(c3,c4,c4), + CYCLE(c5,c6,c6), + CYCLE(c7,c8,c8), + CYCLE(c9,c10,c10), + ALL_COMB(c11,c12,c13), + ALL_COMB(c14,c15,c16), + ALL_COMB(c17,c18,c19)); + w12_2d = createAndInitArray(N12, W_CYCLE(w1), + W_CYCLE(w2), + W_CYCLE(w3), + W_CYCLE(w4), + W_CYCLE(w5), + W_ALL_COMB(w6), + W_ALL_COMB(w7), + W_ALL_COMB(w8)); + +#undef c1 +#undef c2 +#undef c3 +#undef c4 +#undef c5 +#undef c6 +#undef c7 +#undef c8 +#undef c9 +#undef c10 +#undef c11 +#undef c12 +#undef c13 +#undef c14 +#undef c15 +#undef c16 +#undef c17 +#undef c18 +#undef c19 +#undef w1 +#undef w2 +#undef w3 +#undef w4 +#undef w5 +#undef w6 +#undef w7 +#undef w8 + + /****************************************************************************/ + /* quadrature exact on P 17 */ + /* Dunavant, D.A.: High degree efficient symmetrical Gaussian quadrature */ + /* rules for the triangle. Int. J. Numer. Methods Eng. 21, 1129-1148 (1985) */ + /* nealy optimal number of (interior) points, positive wheights (PI) */ + /* optimal number of points: ?, number of points: 61 */ + /* only interior points, completly symmetric in barycentric coordinates */ + /****************************************************************************/ + +#define N17 61 + +#define c1 1.0/3.0 + +#define c2 0.005658918886452 +#define c3 0.497170540556774 + +#define c4 0.035647354750751 +#define c5 0.482176322624625 + +#define c6 0.099520061958437 +#define c7 0.450239969020782 + +#define c8 0.199467521245206 +#define c9 0.400266239377397 + +#define c10 0.495717464058095 +#define c11 0.252141267970953 + +#define c12 0.675905990683077 +#define c13 0.162047004658461 + +#define c14 0.848248235478508 +#define c15 0.075875882260746 + +#define c16 0.968690546064356 +#define c17 0.015654726967822 + +#define c18 0.010186928826919 +#define c19 0.334319867363658 +#define c20 0.655493203809423 + +#define c21 0.135440871671036 +#define c22 0.292221537796944 +#define c23 0.572337590532020 + +#define c24 0.054423924290583 +#define c25 0.319574885423190 +#define c26 0.626001190286228 + +#define c27 0.012868560833637 +#define c28 0.190704224192292 +#define c29 0.796427214974071 + +#define c30 0.067165782413524 +#define c31 0.180483211648746 +#define c32 0.752351005937729 + +#define c33 0.014663182224828 +#define c34 0.080711313679564 +#define c35 0.904625504095608 + +#define w1 StdVol*0.033437199290803 +#define w2 StdVol*0.005093415440507 +#define w3 StdVol*0.014670864527638 +#define w4 StdVol*0.024350878353672 +#define w5 StdVol*0.031107550868969 +#define w6 StdVol*0.031257111218620 +#define w7 StdVol*0.024815654339665 +#define w8 StdVol*0.014056073070557 +#define w9 StdVol*0.003194676173779 +#define w10 StdVol*0.008119655318993 +#define w11 StdVol*0.026805742283163 +#define w12 StdVol*0.018459993210822 +#define w13 StdVol*0.008476868534328 +#define w14 StdVol*0.018292796770025 +#define w15 StdVol*0.006665632004165 + + x17_2d = createAndInit(2, 61, + c1, c1, c1, + CYCLE(c2,c3,c3), + CYCLE(c4,c5,c5), + CYCLE(c6,c7,c7), + CYCLE(c8,c9,c9), + CYCLE(c10,c11,c11), + CYCLE(c12,c13,c13), + CYCLE(c14,c15,c15), + CYCLE(c16,c17,c17), + ALL_COMB(c18,c19,c20), + ALL_COMB(c21,c22,c23), + ALL_COMB(c24,c25,c26), + ALL_COMB(c27,c28,c29), + ALL_COMB(c30,c31,c32), + ALL_COMB(c33,c34,c35)); + w17_2d = createAndInitArray(N17, w1, + W_CYCLE(w2), + W_CYCLE(w3), + W_CYCLE(w4), + W_CYCLE(w5), + W_CYCLE(w6), + W_CYCLE(w7), + W_CYCLE(w8), + W_CYCLE(w9), + W_ALL_COMB(w10), + W_ALL_COMB(w11), + W_ALL_COMB(w12), + W_ALL_COMB(w13), + W_ALL_COMB(w14), + W_ALL_COMB(w15)); + +#undef c1 +#undef c2 +#undef c3 +#undef c4 +#undef c5 +#undef c6 +#undef c7 +#undef c8 +#undef c9 +#undef c10 +#undef c11 +#undef c12 +#undef c13 +#undef c14 +#undef c15 +#undef c16 +#undef c17 +#undef c18 +#undef c19 +#undef c20 +#undef c21 +#undef c22 +#undef c23 +#undef c24 +#undef c25 +#undef c26 +#undef c27 +#undef c28 +#undef c29 +#undef c30 +#undef c31 +#undef c32 +#undef c33 +#undef c34 +#undef c35 + +#undef w1 +#undef w2 +#undef w3 +#undef w4 +#undef w5 +#undef w6 +#undef w7 +#undef w8 +#undef w9 +#undef w10 +#undef w11 +#undef w12 +#undef w13 +#undef w14 +#undef w15 + +#if 0 + /****************************************************************************/ + /* quadrature exact on P 1? */ + /* Dunavant, D.A.: High degree efficient symmetrical Gaussian quadrature */ + /* rules for the triangle. Int. J. Numer. Methods Eng. 21, 1129-1148 (1985) */ + /* nealy optimal number of (interior) points, positive wheights (PI) */ + /* optimal number of points: ?, number of points: 25 */ + /* only interior points, completly symmetric in barycentric coordinates */ + /****************************************************************************/ + +#define N1? 25 + +#define c1 0. + +#define c2 0. +#define c3 0. + +#define c4 0. +#define c5 0. + +#define c6 0. +#define c7 0. +#define c8 0. + +#define c9 0. +#define c10 0. +#define c11 0. + +#define c12 0. +#define c13 0. +#define c14 0. + +#define w1 StdVol*0.0 +#define w2 StdVol*0.0 +#define w3 StdVol*0.0 +#define w4 StdVol*0.0 +#define w5 StdVol*0.0 +#define w6 StdVol*0.0 + + const double w1?_2d[N1?] = createAndInit(N1?, w1, + W_CYCLE(w2), + W_CYCLE(w3), + W_ALL_COMB(w4), + W_ALL_COMB(w5), + W_ALL_COMB(w6)); + +#undef c1 +#undef c2 +#undef c3 +#undef c4 +#undef c5 +#undef c6 +#undef c7 +#undef c8 +#undef c9 +#undef c10 +#undef c11 +#undef c12 +#undef c13 +#undef c14 +#undef w1 +#undef w2 +#undef w3 +#undef w4 +#undef w5 +#undef w6 +#endif + + + Quadrature::quad_2d[0] = NEW Quadrature("2d-P_1", 1, 2, N1, Quadrature::x1_2d, Quadrature::w1_2d); /* P 0 */ + Quadrature::quad_2d[1] = NEW Quadrature("2d-P_1", 1, 2, N1, Quadrature::x1_2d, Quadrature::w1_2d); /* P 1 */ + Quadrature::quad_2d[2] = NEW Quadrature("2d Stroud: P_2", 2, 2, N2, Quadrature::x2_2d, Quadrature::w2_2d); /* P 2 */ + Quadrature::quad_2d[3] = NEW Quadrature("2d Stroud: P_3", 3, 2, N3, Quadrature::x3_2d, Quadrature::w3_2d); /* P 3 */ + Quadrature::quad_2d[4] = NEW Quadrature("2d Dunavant: P_4", 4, 2, N4, Quadrature::x4_2d, Quadrature::w4_2d); /* P 4 */ + Quadrature::quad_2d[5] = NEW Quadrature("2d Dunavant: P_5", 5, 2, N5, Quadrature::x5_2d, Quadrature::w5_2d); /* P 5 */ + Quadrature::quad_2d[6] = NEW Quadrature("2d Gattermann: P_7", 7, 2, N7, Quadrature::x7_2d, Quadrature::w7_2d); /* P 6 */ + Quadrature::quad_2d[7] = NEW Quadrature("2d Gattermann: P_7", 7, 2, N7, Quadrature::x7_2d, Quadrature::w7_2d); /* P 7 */ + Quadrature::quad_2d[8] = NEW Quadrature("2d Dunavant: P_8", 8, 2, N8, Quadrature::x8_2d, Quadrature::w8_2d); /* P 8 */ + Quadrature::quad_2d[9] = NEW Quadrature("2d Dunavant: P_9", 9, 2, N9, Quadrature::x9_2d, Quadrature::w9_2d); /* P 9 */ + Quadrature::quad_2d[10] = NEW Quadrature("2d Dunavant: P_10", 10, 2, N10, Quadrature::x10_2d, Quadrature::w10_2d);/* P 10 */ + Quadrature::quad_2d[11] = NEW Quadrature("2d Dunavant: P_11", 11, 2, N11, Quadrature::x11_2d, Quadrature::w11_2d);/* P 11 */ + Quadrature::quad_2d[12] = NEW Quadrature("2d Dunavant: P_12", 12, 2, N12, Quadrature::x12_2d, Quadrature::w12_2d);/* P 12 */ + Quadrature::quad_2d[13] = NEW Quadrature("2d Dunavant: P_17", 17, 2, N17, Quadrature::x17_2d, Quadrature::w17_2d);/* P 13 */ + Quadrature::quad_2d[14] = NEW Quadrature("2d Dunavant: P_17", 17, 2, N17, Quadrature::x17_2d, Quadrature::w17_2d);/* P 14 */ + Quadrature::quad_2d[15] = NEW Quadrature("2d Dunavant: P_17", 17, 2, N17, Quadrature::x17_2d, Quadrature::w17_2d);/* P 15 */ + Quadrature::quad_2d[16] = NEW Quadrature("2d Dunavant: P_17", 17, 2, N17, Quadrature::x17_2d, Quadrature::w17_2d);/* P 16 */ + Quadrature::quad_2d[17] = NEW Quadrature("2d Dunavant: P_17", 17, 2, N17, Quadrature::x17_2d, Quadrature::w17_2d); /* P 17 */ + + +#undef StdVol +#undef N1 +#undef N2 +#undef N3 +#undef N4 +#undef N5 +#undef N6 +#undef N7 +#undef N8 +#undef N9 +#undef N10 +#undef N11 +#undef N12 +#undef N17 + + /****************************************************************************/ + /* 3d quadrature formulas using 4 barycentric coordinates */ + /****************************************************************************/ + +#define MAX_QUAD_DEG_3d 7 + +#define StdVol (1.0/6.0) + + /****************************************************************************/ + /* quadrature exact on P_1 */ + /****************************************************************************/ + + x1_3d = createAndInit(3, 1, + quart, quart, quart, quart); + w1_3d = createAndInitArray(1, StdVol*one); + + + + /****************************************************************************/ + /* Quad quadrature exact on P_2 */ + /****************************************************************************/ + +#define c14 0.585410196624969 +#define c15 0.138196601125011 + + x2_3d = createAndInit(3, 4, + c14, c15, c15, c15, + c15, c14, c15, c15, + c15, c15, c14, c15, + c15, c15, c15, c14); + w2_3d = createAndInitArray(4, StdVol*quart, StdVol*quart, + StdVol*quart, StdVol*quart); + + /****************************************************************************/ + /* quadrature exact on P_3 */ + /****************************************************************************/ + +#define w8 1.0/40.0 +#define w9 9.0/40.0 + + x3_3d = createAndInit(3, 8, + one, zero, zero, zero, + zero, one, zero, zero, + zero, zero, one, zero, + zero, zero, zero, one, + zero, third, third, third, + third, zero, third, third, + third, third, zero, third, + third, third, third, zero); + w3_3d = createAndInitArray(8, StdVol*w8, StdVol*w8, StdVol*w8, StdVol*w8, + StdVol*w9, StdVol*w9, StdVol*w9, StdVol*w9); + + /****************************************************************************/ + /* quadrature exact on P_4 */ + /****************************************************************************/ + +#define c18 0.091971078 +#define c19 0.724086765 +#define c20 0.319793627 +#define c21 0.040619116 +#define c22 0.056350832 +#define c23 0.443649167 + +#if 0 +#define w10 0.019753086*6.0 +#define w11 0.011989513*6.0 +#define w12 0.011511367*6.0 +#define w13 0.008818342152*6.0 +#else +#define w10 0.118518515999999990 +#define w11 0.071937078000000002 +#define w12 0.069068201999999995 +#define w13 0.052910052911999995 +#endif + + x4_3d = createAndInit(3, 15, + quart, quart, quart, quart, + c18, c18, c18, c19, + c18, c18, c19, c18, + c18, c19, c18, c18, + c19, c18, c18, c18, + c20, c20, c20, c21, + c20, c20, c21, c20, + c20, c21, c20, c20, + c21, c20, c20, c20, + c22, c22, c23, c23, + c22, c23, c22, c23, + c23, c22, c22, c23, + c22, c23, c23, c22, + c23, c22, c23, c22, + c23, c23, c22, c22); + w4_3d = createAndInitArray(15, StdVol*w10, + StdVol*w11, StdVol*w11, + StdVol*w11, StdVol*w11, + StdVol*w12, StdVol*w12, + StdVol*w12, StdVol*w12, + StdVol*w13, StdVol*w13, StdVol*w13, + StdVol*w13, StdVol*w13, StdVol*w13); + + /****************************************************************************/ + /* quadrature exact on P_5 */ + /****************************************************************************/ + + x5_3d = createAndInit(3, 15, + 0.250000000000000, 0.250000000000000, 0.250000000000000, 0.250000000000000, + 0.091971078052723, 0.091971078052723, 0.091971078052723, 0.724086765841831, + 0.724086765841831, 0.091971078052723, 0.091971078052723, 0.091971078052723, + 0.091971078052723, 0.724086765841831, 0.091971078052723, 0.091971078052723, + 0.091971078052723, 0.091971078052723, 0.724086765841831, 0.091971078052723, + 0.319793627829630, 0.319793627829630, 0.319793627829630, 0.040619116511110, + 0.040619116511110, 0.319793627829630, 0.319793627829630, 0.319793627829630, + 0.319793627829630, 0.040619116511110, 0.319793627829630, 0.319793627829630, + 0.319793627829630, 0.319793627829630, 0.040619116511110, 0.319793627829630, + 0.443649167310371, 0.056350832689629, 0.056350832689629, 0.443649167310371, + 0.056350832689629, 0.443649167310371, 0.056350832689629, 0.443649167310371, + 0.056350832689629, 0.056350832689629, 0.443649167310371, 0.443649167310371, + 0.443649167310371, 0.056350832689629, 0.443649167310371, 0.056350832689629, + 0.443649167310371, 0.443649167310371, 0.056350832689629, 0.056350832689629, + 0.056350832689629, 0.443649167310371, 0.443649167310371, 0.056350832689629); + w5_3d = createAndInitArray(15, StdVol*0.118518518518519, + StdVol*0.071937083779019, + StdVol*0.071937083779019, + StdVol*0.071937083779019, + StdVol*0.071937083779019, + StdVol*0.069068207226272, + StdVol*0.069068207226272, + StdVol*0.069068207226272, + StdVol*0.069068207226272, + StdVol*0.052910052910053, + StdVol*0.052910052910053, + StdVol*0.052910052910053, + StdVol*0.052910052910053, + StdVol*0.052910052910053, + StdVol*0.052910052910053); + + /****************************************************************************/ + /* quadrature exact on P_7 */ + /****************************************************************************/ + + x7_3d = createAndInit(3, 64, + 0.0485005494, 0.0543346112, 0.0622918076, 0.8348730318, + 0.0485005494, 0.0543346112, 0.2960729005, 0.6010919389, + 0.0485005494, 0.0543346112, 0.6010919389, 0.2960729005, + 0.0485005494, 0.0543346112, 0.8348730300, 0.0622918093, + 0.0485005494, 0.2634159753, 0.0477749033, 0.6403085720, + 0.0485005494, 0.2634159753, 0.2270740686, 0.4610094066, + 0.0485005494, 0.2634159753, 0.4610094066, 0.2270740686, + 0.0485005494, 0.2634159753, 0.6403085706, 0.0477749047, + 0.0485005494, 0.5552859758, 0.0275098315, 0.3687036433, + 0.0485005494, 0.5552859758, 0.1307542021, 0.2654592727, + 0.0485005494, 0.5552859758, 0.2654592727, 0.1307542021, + 0.0485005494, 0.5552859758, 0.3687036425, 0.0275098323, + 0.0485005494, 0.8185180165, 0.0092331459, 0.1237482881, + 0.0485005494, 0.8185180165, 0.0438851337, 0.0890963004, + 0.0485005494, 0.8185180165, 0.0890963004, 0.0438851337, + 0.0485005494, 0.8185180165, 0.1237482879, 0.0092331462, + 0.2386007376, 0.0434790928, 0.0498465199, 0.6680736497, + 0.2386007376, 0.0434790928, 0.2369204606, 0.4809997090, + 0.2386007376, 0.0434790928, 0.4809997090, 0.2369204606, + 0.2386007376, 0.0434790928, 0.6680736482, 0.0498465214, + 0.2386007376, 0.2107880664, 0.0382299497, 0.5123812464, + 0.2386007376, 0.2107880664, 0.1817069135, 0.3689042825, + 0.2386007376, 0.2107880664, 0.3689042825, 0.1817069135, + 0.2386007376, 0.2107880664, 0.5123812453, 0.0382299508, + 0.2386007376, 0.4443453248, 0.0220136390, 0.2950402987, + 0.2386007376, 0.4443453248, 0.1046308045, 0.2124231331, + 0.2386007376, 0.4443453248, 0.2124231331, 0.1046308045, + 0.2386007376, 0.4443453248, 0.2950402980, 0.0220136396, + 0.2386007376, 0.6549862048, 0.0073884546, 0.0990246030, + 0.2386007376, 0.6549862048, 0.0351173176, 0.0712957400, + 0.2386007376, 0.6549862048, 0.0712957400, 0.0351173176, + 0.2386007376, 0.6549862048, 0.0990246028, 0.0073884548, + 0.5170472951, 0.0275786260, 0.0316174612, 0.4237566177, + 0.5170472951, 0.0275786260, 0.1502777622, 0.3050963168, + 0.5170472951, 0.0275786260, 0.3050963168, 0.1502777622, + 0.5170472951, 0.0275786260, 0.4237566168, 0.0316174621, + 0.5170472951, 0.1337020823, 0.0242491141, 0.3250015085, + 0.5170472951, 0.1337020823, 0.1152560157, 0.2339946069, + 0.5170472951, 0.1337020823, 0.2339946069, 0.1152560157, + 0.5170472951, 0.1337020823, 0.3250015078, 0.0242491148, + 0.5170472951, 0.2818465779, 0.0139631689, 0.1871429581, + 0.5170472951, 0.2818465779, 0.0663669280, 0.1347391990, + 0.5170472951, 0.2818465779, 0.1347391990, 0.0663669280, + 0.5170472951, 0.2818465779, 0.1871429577, 0.0139631693, + 0.5170472951, 0.4154553004, 0.0046864691, 0.0628109354, + 0.5170472951, 0.4154553004, 0.0222747832, 0.0452226213, + 0.5170472951, 0.4154553004, 0.0452226213, 0.0222747832, + 0.5170472951, 0.4154553004, 0.0628109352, 0.0046864693, + 0.7958514179, 0.0116577407, 0.0133649937, 0.1791258477, + 0.7958514179, 0.0116577407, 0.0635238021, 0.1289670393, + 0.7958514179, 0.0116577407, 0.1289670393, 0.0635238021, + 0.7958514179, 0.0116577407, 0.1791258473, 0.0133649941, + 0.7958514179, 0.0565171087, 0.0102503252, 0.1373811482, + 0.7958514179, 0.0565171087, 0.0487197855, 0.0989116879, + 0.7958514179, 0.0565171087, 0.0989116879, 0.0487197855, + 0.7958514179, 0.0565171087, 0.1373811479, 0.0102503255, + 0.7958514179, 0.1191391593, 0.0059023608, 0.0791070620, + 0.7958514179, 0.1191391593, 0.0280539153, 0.0569555075, + 0.7958514179, 0.1191391593, 0.0569555075, 0.0280539153, + 0.7958514179, 0.1191391593, 0.0791070618, 0.0059023610, + 0.7958514179, 0.1756168040, 0.0019810139, 0.0265507642, + 0.7958514179, 0.1756168040, 0.0094157572, 0.0191160209, + 0.7958514179, 0.1756168040, 0.0191160209, 0.0094157572, + 0.7958514179, 0.1756168040, 0.0265507642, 0.0019810140); + w7_3d = createAndInitArray(64, StdVol*0.0156807540, StdVol*0.0293976870, + StdVol*0.0293976870, StdVol*0.0156807540, + StdVol*0.0235447608, StdVol*0.0441408300, + StdVol*0.0441408300, StdVol*0.0235447608, + StdVol*0.0150258564, StdVol*0.0281699100, + StdVol*0.0281699100, StdVol*0.0150258564, + StdVol*0.0036082374, StdVol*0.0067645878, + StdVol*0.0067645878, StdVol*0.0036082374, + StdVol*0.0202865376, StdVol*0.0380324358, + StdVol*0.0380324358, StdVol*0.0202865376, + StdVol*0.0304603764, StdVol*0.0571059660, + StdVol*0.0571059660, StdVol*0.0304603764, + StdVol*0.0194392824, StdVol*0.0364440336, + StdVol*0.0364440336, StdVol*0.0194392824, + StdVol*0.0046680564, StdVol*0.0087514968, + StdVol*0.0087514968, StdVol*0.0046680564, + StdVol*0.0097055322, StdVol*0.0181955664, + StdVol*0.0181955664, StdVol*0.0097055322, + StdVol*0.0145729242, StdVol*0.0273207684, + StdVol*0.0273207684, StdVol*0.0145729242, + StdVol*0.0093001866, StdVol*0.0174356394, + StdVol*0.0174356394, StdVol*0.0093001866, + StdVol*0.0022333026, StdVol*0.0041869110, + StdVol*0.0041869110, StdVol*0.0022333026, + StdVol*0.0014639124, StdVol*0.0027444882, + StdVol*0.0027444882, StdVol*0.0014639124, + StdVol*0.0021980748, StdVol*0.0041208678, + StdVol*0.0041208678, StdVol*0.0021980748, + StdVol*0.0014027730, StdVol*0.0026298660, + StdVol*0.0026298660, StdVol*0.0014027730, + StdVol*0.0003368550, StdVol*0.0006315234, + StdVol*0.0006315234, StdVol*0.0003368550); + + /****************************************************************************/ + /* build a vector of Quad' quadrature formulars. For quadrature of degree */ + /* use that of degree (only on function evaluation also) */ + /****************************************************************************/ + + Quadrature::quad_3d[0] = NEW Quadrature("3d Stroud: P_1", 1, 3, 1, Quadrature::x1_3d, Quadrature::w1_3d); /* P_0 */ + Quadrature::quad_3d[1] = NEW Quadrature("3d Stroud: P_1", 1, 3, 1, Quadrature::x1_3d, Quadrature::w1_3d); /* P_1 */ + Quadrature::quad_3d[2] = NEW Quadrature("3d Stroud: P_2", 2, 3, 4, Quadrature::x2_3d, Quadrature::w2_3d); /* P_2 */ + Quadrature::quad_3d[3] = NEW Quadrature("3d Stroud: P_3", 3, 3, 8, Quadrature::x3_3d, Quadrature::w3_3d); /* P_3 */ + Quadrature::quad_3d[4] = NEW Quadrature("3d ???: P_5", 5, 3, 15, Quadrature::x5_3d, Quadrature::w5_3d); /* P_4 */ + Quadrature::quad_3d[5] = NEW Quadrature("3d ???: P_5", 5, 3, 15, Quadrature::x5_3d, Quadrature::w5_3d); /* P_5 */ + Quadrature::quad_3d[6] = NEW Quadrature("3d ???: P_7", 7, 3, 64, Quadrature::x7_3d, Quadrature::w7_3d); /* P_6 */ + Quadrature::quad_3d[7] = NEW Quadrature("3d ???: P_7", 7, 3, 64, Quadrature::x7_3d, Quadrature::w7_3d); /* P_7 */ + + +#undef StdVol + + /****************************************************************************/ + /* integration in different dimensions */ + /****************************************************************************/ + + Quadrature::quad_nd[0] = Quadrature::quad_0d; + Quadrature::quad_nd[1] = Quadrature::quad_1d; + Quadrature::quad_nd[2] = Quadrature::quad_2d; + Quadrature::quad_nd[3] = Quadrature::quad_3d; + + //static const unsigned char max_quad_deg[4] = {0, MAX_QUAD_DEG_1d, MAX_QUAD_DEG_2d, + // MAX_QUAD_DEG_3d}; + + + }; + + // Quadrature::Quadrature(int dim_, int degree_, ::std::string aName) + // : name(aName), degree(degree_),dim(dim_) + // { + // FUNCNAME("Quadrature::Quadrature"); + + // if(degree > max_quad_deg[dim]) + // { + // MSG("degree %d too large; changing to %d\n", degree, max_quad_deg[dim]); + // degree = max_quad_deg[dim]; + // } + + // QUAD* newQUAD = (quad_nd[dim] + degree); + + // if(aName=="") + // name = newQUAD->name; + // else + // name = aName; + + // degree = degree_; + // dim = dim_; + // n_points = newQUAD->n_points; + + // lambda = new VectorOfFixVecs<DimVec<double> >(dim, n_points, NO_INIT); + // w = new double[n_points]; + // for(int i=0; i < n_points; i++) { + // for(int j=0; j < dim + 1; j++) { + // (*lambda)[i][j] = newQUAD->lambda[i][j]; + // } + // w[i] = newQUAD->w[i]; + // } + // } + + Quadrature* Quadrature::provideQuadrature(int dim_, int degree_) + { + FUNCNAME("Quadrature::provideQuadrature()"); + switch(dim_) { + case 0: + degree_ = 0; + break; + case 1: + degree_ = ::std::min(degree_, 19); + break; + case 2: + degree_ = ::std::min(degree_, 17); + break; + case 3: + degree_ = ::std::min(degree_, 7); + break; + default: + ERROR_EXIT("invalid dim\n"); + } + if(x0_1d == NULL) initStaticQuadratures(); + return (quad_nd[dim_][degree_]); + } + + Quadrature::~Quadrature() + { + DELETE lambda; + DELETE[] w; + } + + double Quadrature::integrateStdSimplex(AbstractFunction<double, DimVec<double> > *f) + { + FUNCNAME("Quadrature::integrateStdSimplex"); + if(!f) { + ERROR("no function specified\n"); + return 0; + } + + + double result = 0; + // calculate weighted sum over all quadrature-points + for(int i=0; i < n_points; i++) { + result += w[i] * (*f)((*lambda)[i]); + } + return result; + } + + FastQuadrature* FastQuadrature::provideFastQuadrature(const BasisFunction* bas_fcts, + const Quadrature& quad, + Flag init_flag) + { + FUNCNAME("FastQuadrature::FastQuadrature"); + + ::std::list<FastQuadrature*>::iterator fast = fastQuadList.begin(); + + FastQuadrature *quad_fast; + //BasisFunction *bas_fct; + + //if (quad.getDim() != Global::getGeo(DIMEN)) + //{ + // ERROR("QUAD_FAST not for %d < DIM\n"); + // return(NULL); + //} + + for (fast = fastQuadList.begin(); fast != fastQuadList.end(); fast++) + if ((*fast)->basisFunctions == bas_fcts && (*fast)->quadrature == &quad) break; + + if ((fast != fastQuadList.end()) && (((*fast)->init_flag & init_flag) == init_flag)) + return(*fast); + + + if (fast == fastQuadList.end()) + { + quad_fast = NEW FastQuadrature(const_cast<BasisFunction*>( bas_fcts), const_cast<Quadrature*>( &quad), 0); + + fastQuadList.push_front(quad_fast); + + max_points = ::std::max(max_points, quad.getNumPoints()); + } + else + quad_fast = (*fast); + + quad_fast->init(init_flag); + + return quad_fast; + } + + void FastQuadrature::init(Flag init_flag) + { + int i, j; + + int dim = quadrature->getDim(); + + int n_points = quadrature->getNumPoints(); + int nBasFcts = basisFunctions->getNumber(); + + DimVec<double> lambda(dim, NO_INIT); + + // ----- initialize phi --------------------------------------------- + + if (!phi && init_flag.isSet(INIT_PHI)) { // check flag + + // allocate memory + phi = GET_MEMORY(double*, n_points); + for(i=0; i < n_points; i++) { + phi[i] = GET_MEMORY(double, nBasFcts); + } + + // fill memory + for(i=0; i< n_points; i++) { + lambda = quadrature->getLambda(i); + for(j=0; j < nBasFcts; j++) { + phi[i][j] = (*(basisFunctions->getPhi(j)))(lambda); + } + } + + // update flag + init_flag |= INIT_PHI; + } + + // initialize grd_phi + + if (!grdPhi && init_flag.isSet(INIT_GRD_PHI)) { // check flag + + // allocate memory + grdPhi = NEW MatrixOfFixVecs<DimVec<double> >(dim, n_points, nBasFcts, NO_INIT); + + // fill memory + for(i=0; i< n_points; i++) { + lambda = quadrature->getLambda(i); + for(j=0; j < nBasFcts; j++) { + (*(grdPhi))[i][j] = (*(basisFunctions->getGrdPhi(j)))(lambda); + } + } + + // update flag + init_flag |= INIT_GRD_PHI; + } + + // initialize D2_phi + + if (!D2Phi && init_flag.isSet(INIT_D2_PHI)) { // check flag + + // allocate memory + D2Phi = NEW MatrixOfFixVecs<DimMat<double> >(dim, n_points, nBasFcts, NO_INIT); + + // fill memory + for(i=0; i< n_points; i++) { + lambda = quadrature->getLambda(i); + for(j=0; j < nBasFcts; j++) { + (*(D2Phi))[i][j] = (*(basisFunctions->getD2Phi(j)))(lambda); + } + } + + // update flag + init_flag |= INIT_D2_PHI; + } + } + + FastQuadrature::FastQuadrature(const FastQuadrature& fastQuad) + { + int i,j; + + TEST_EXIT(quadrature)("no quadrature!\n"); + + int dim = quadrature->getDim(); + + if(max_points == 0) + max_points = Quadrature::maxNQuadPoints[dim]; + + init_flag = fastQuad.init_flag; + basisFunctions = fastQuad.basisFunctions; + quadrature = fastQuad.quadrature; + + int n_points = quadrature->getNumPoints(); + int nBasFcts = basisFunctions->getNumber(); + + if(fastQuad.phi) { + phi = GET_MEMORY(double*, n_points); + for(i=0; i < n_points; i++) { + phi[i] = GET_MEMORY(double, nBasFcts); + for(j=0; j < nBasFcts; j++) { + phi[i][j] = fastQuad.phi[i][j]; + } + } + } + + if(fastQuad.grdPhi) { + grdPhi = NEW MatrixOfFixVecs<DimVec<double> >(dim, n_points, nBasFcts, NO_INIT); + for(i=0; i < n_points; i++) { + for(j=0; j < nBasFcts; j++) { + (*grdPhi)[i][j] = (*(fastQuad.grdPhi))[i][j]; + } + } + } + + if(fastQuad.D2Phi) { + D2Phi = NEW MatrixOfFixVecs<DimMat<double> >(dim, n_points, nBasFcts, NO_INIT); + for(i=0; i < n_points; i++) { + for(j=0; j < nBasFcts; j++) { + (*D2Phi)[i][j] = (*(fastQuad.D2Phi))[i][j]; + } + } + } + } + + FastQuadrature::~FastQuadrature() + { + int i; + int n_points = quadrature->getNumPoints(); + int n_bas_fcts = basisFunctions->getNumber(); + + for(i=0; i < n_points; i++) { + FREE_MEMORY(phi[i], double, n_bas_fcts); + } + + FREE_MEMORY(phi, double*, n_points); + DELETE grdPhi; + DELETE D2Phi; + } + + const double FastQuadrature::getSecDer(int q,int i ,int j, int m) const { + return (D2Phi)?(*D2Phi)[q][i][j][m]:0; + } + + const VectorOfFixVecs<DimMat<double> > *FastQuadrature::getSecDer(int q) const { + return D2Phi ? (&((*D2Phi)[q])) : NULL; + } + + const double FastQuadrature::getGradient(int q,int i ,int j) const { + return (grdPhi)?(*grdPhi)[q][i][j]:0; + } + + VectorOfFixVecs<DimVec<double> >* FastQuadrature::getGradient(int q) const { + return (grdPhi)?&((*grdPhi)[q]):NULL; + } + + /****************************************************************************/ + /* standard routines for getting values of a finite element function and */ + /* its first (and second) derivatives at the quadrature points */ + /****************************************************************************/ + + // const double *FastQuadrature::uhAtQp(const double *uhLoc, double *vec) const + // { + // FUNCNAME("uhAtQp()"); + // static double *quadVec = NULL; + // static int size = 0; + // double *val; + // int i, j; + + // int n_points = quadrature->getNumPoints(); + // int nBasFcts = basisFunctions->getNumber(); + // int dim = getDim(); + + // if (vec) { + // val = vec; + // } else { + // if (size < n_points) { + // int newSize = ::std::max(Quadrature::maxNQuadPoints[dim], n_points); + // if(quadVec) FREE_MEMORY(quadVec, double, size); + // quadVec = GET_MEMORY(double, newSize); + // size = newSize; + // } + // val = quadVec; + // } + + // for (i = 0; i < n_points; i++) { + // for (val[i] = j = 0; j < nBasFcts; j++) { + // val[i] += uhLoc[j] * phi[i][j]; + // } + // } + // return(const_cast<const double*>(val)); + // } + + // const WorldVector<double>* + // FastQuadrature::grdUhAtQp(const DimVec<WorldVector<double> >& grdLambda, + // const double *uhLoc, WorldVector<double> *vec) const + // { + // FUNCNAME("grdUhAtQp()"); + + // int i, j, k, l; + + // int dim = getDim(); + // int dow = Global::getGeo(WORLD); + // int parts = Global::getGeo(PARTS, dim); + // int n_points = quadrature->getNumPoints(); + // int nBasFcts = basisFunctions->getNumber(); + + // static WorldVector<double> *quadVec = NULL; + // static int size = 0; + // WorldVector<double> *val; + // DimVec<double> grd1(dim, NO_INIT); + + // if (vec) { + // val = vec; + // } else { + // if(size < n_points) { + // int newSize = ::std::max(Quadrature::maxNQuadPoints[dim], n_points); + // if(quadVec) DELETE [] quadVec; + // quadVec = NEW WorldVector<double>[newSize]; + // size = newSize; + // } + // val = quadVec; + // } + + // for (i = 0; i < n_points; i++) { + // for(j = 0; j < dim+1; j++) + // grd1[j] = 0.0; + + // for (j = 0; j < nBasFcts; j++) { + // for (k = 0; k < parts; k++) { + // grd1[k] += (*grdPhi)[i][j][k] * uhLoc[j]; + // } + // } + + // for(l=0; l < dow; l++) { + // for (val[i][l] = k = 0; k < parts; k++) { + // val[i][l] += grdLambda[k][l] * grd1[k]; + // } + // } + // } + + // return(const_cast<const WorldVector<double>*>(val)); + // } + + // const WorldMatrix<double>* + // FastQuadrature::D2UhAtQp( + // const DimVec<WorldVector<double> >& grdLambda, + // const double *uhLoc, WorldMatrix<double> *vec) const + // { + // FUNCNAME("D2UhAtQp()"); + + // int i, j, k, l, iq; + + // int nBasFcts = basisFunctions->getNumber(); + // int dim = getDim(); + // int n_points = quadrature->getNumPoints(); + // int parts = Global::getGeo(PARTS, dim); + // int dow = Global::getGeo(WORLD); + + // static WorldMatrix<double> *quadVec = NULL; + // static int size = 0; + // WorldMatrix<double> *val; + // DimMat<double> D2Tmp(dim, DEFAULT_VALUE, 0.); + + // if (vec) { + // val = vec; + // } else { + // if(size < n_points) { + // int newSize = ::std::max(Quadrature::maxNQuadPoints[dim], n_points); + // if(quadVec) DELETE [] quadVec; + // quadVec = NEW WorldMatrix<double>[newSize]; + // size = newSize; + // } + // val = quadVec; + // } + + // for (iq = 0; iq < n_points; iq++) { + // for (k = 0; k < parts; k++) + // for (l = 0; l < parts; l++) + // D2Tmp[k][l] = 0.0; + + // for (i = 0; i < nBasFcts; i++) { + // for (k = 0; k < parts; k++) + // for (l = 0; l < parts; l++) + // D2Tmp[k][l] += uhLoc[i]*(*D2Phi)[iq][i][k][l]; + // } + + // for (i = 0; i < dow; i++) + // for (j = 0; j < dow; j++) { + // val[iq][i][j] = 0.0; + // for (k = 0; k < parts; k++) + // for (l = 0; l < parts; l++) + // val[iq][i][j] += grdLambda[k][i]*grdLambda[l][j]*D2Tmp[k][l]; + // } + // } + + // return(const_cast<const WorldMatrix<double>*>(val)); + // } + + + // const double *Quadrature::uhAtQp(const BasisFunction *basFcts, + // const double *uhLoc, double *vec) const + // { + // FUNCNAME("uhAtQp()"); + // static double *quadVec = NULL; + // static int size = 0; + // double *val; + + // int i, j; + + // int nBasFcts = basFcts->getNumber(); + + // if (vec) { + // val = vec; + // } else { + // if(size < n_points) { + // int newSize = ::std::max(Quadrature::maxNQuadPoints[dim], n_points); + // if(quadVec) FREE_MEMORY(quadVec, double, size); + // quadVec = GET_MEMORY(double, newSize); + // size = newSize; + // } + // val = quadVec; + // } + + // for (i = 0; i < n_points; i++) { + // for (val[i] = j = 0; j < nBasFcts; j++) { + // val[i] += uhLoc[j] * (*(basFcts->getPhi(j)))((*lambda)[i]); + // } + // } + + // return(const_cast<const double*>(val)); + // } + + // const WorldVector<double>* + // Quadrature::grdUhAtQp(const BasisFunction *basFcts, + // const DimVec<WorldVector<double> >& grdLambda, + // const double *uhLoc, WorldVector<double> *vec) const + // { + // FUNCNAME("grdUhAtQp()"); + + // int i, j, k, l; + + // int nBasFcts = basFcts->getNumber(); + // int dow = Global::getGeo(WORLD); + // int parts = Global::getGeo(PARTS, dim); + + // static WorldVector<double> *quadVec = NULL; + // static int size = 0; + // WorldVector<double> *val; + // DimVec<double> grd1(dim, NO_INIT); + // DimVec<double> grdPhi(dim, NO_INIT); + + // if (vec) { + // val = vec; + // } else { + // if(size < n_points) { + // int newSize = ::std::max(Quadrature::maxNQuadPoints[dim], n_points); + // if(quadVec) DELETE [] quadVec; + // quadVec = NEW WorldVector<double>[newSize]; + // size = newSize; + // } + // val = quadVec; + // } + + // for (i = 0; i < n_points; i++) { + // for(j = 0; j < dim+1; j++) + // grd1[j] = 0.0; + // for (j = 0; j < nBasFcts; j++) { + // grdPhi = (*(basFcts->getGrdPhi(j)))((*lambda)[i]); + // for(k = 0; k < parts; k++) { + // grd1[k] += grdPhi[k] * uhLoc[j]; + // } + // } + + // for(l=0; l < dow; l++) { + // for (val[i][l] = k = 0; k < parts; k++) { + // val[i][l] += grdLambda[k][l] * grd1[k]; + // } + // } + // } + + // return(const_cast<const WorldVector<double>*>(val)); + // } + + // const WorldMatrix<double>* + // Quadrature::D2UhAtQp(const BasisFunction *basFcts, + // const DimVec<WorldVector<double> >& grdLambda, + // const double *uhLoc, WorldMatrix<double> *vec) const + // { + // FUNCNAME("D2UhAtQp()"); + + // int i, j, k, l, iq; + + // int nBasFcts = basFcts->getNumber(); + // int parts = Global::getGeo(PARTS, dim); + // int dow = Global::getGeo(WORLD); + + // static WorldMatrix<double> *quadVec = NULL; + // static int size = 0; + // WorldMatrix<double> *val; + // DimMat<double> D2Phi(dim, NO_INIT); + // DimMat<double> D2Tmp(dim, DEFAULT_VALUE, 0.); + + // if (vec) { + // val = vec; + // } else { + // if (size < n_points) { + // int newSize = ::std::max(Quadrature::maxNQuadPoints[dim], n_points); + // if(quadVec) DELETE [] quadVec; + // quadVec = NEW WorldMatrix<double>[newSize]; + // size = newSize; + // } + // val = quadVec; + // } + + // for (iq = 0; iq < n_points; iq++) { + // for (k = 0; k < parts; k++) + // for (l = 0; l < parts; l++) + // D2Tmp[k][l] = 0.0; + + // for (i = 0; i < nBasFcts; i++) { + // D2Phi = (*(basFcts->getD2Phi(j)))((*lambda)[i]); + // for (k = 0; k < parts; k++) + // for (l = 0; l < parts; l++) + // D2Tmp[k][l] += uhLoc[i] * D2Phi[k][l]; + // } + + // for (i = 0; i < dow; i++) + // for (j = 0; j < dow; j++) { + // val[iq][i][j] = 0.0; + // for (k = 0; k < parts; k++) + // for (l = 0; l < parts; l++) + // val[iq][i][j] += grdLambda[k][i]*grdLambda[l][j]*D2Tmp[k][l]; + // } + // } + + // return(const_cast<const WorldMatrix<double>*>(val)); + // } + +} diff --git a/AMDiS/src/Quadrature.h b/AMDiS/src/Quadrature.h new file mode 100644 index 0000000000000000000000000000000000000000..3372091273df737e7fd0ac17560eb13cc54353b2 --- /dev/null +++ b/AMDiS/src/Quadrature.h @@ -0,0 +1,655 @@ +// ============================================================================ +// == == +// == AMDiS - Adaptive multidimensional simulations == +// == == +// ============================================================================ +// == == +// == crystal growth group == +// == == +// == Stiftung caesar == +// == Ludwig-Erhard-Allee 2 == +// == 53175 Bonn == +// == germany == +// == == +// ============================================================================ +// == == +// == http://www.caesar.de/cg/AMDiS == +// == == +// ============================================================================ + +/** \file Quadrature.h */ + +#ifndef AMDIS_QUADRATURE_H +#define AMDIS_QUADRATURE_H + +#include "BasisFunction.h" +#include "Flag.h" +#include "MemoryManager.h" +#include "FixVec.h" +#include <list> + +namespace AMDiS { + + template<typename T> class WorldVector; + template<typename T> class DimVec; + template<typename T> class VectorOfFixVecs; + template<typename T> class MatrixOfFixVecs; + + // ============================================================================ + // ===== class Quadrature ===================================================== + // ============================================================================ + + /** + * \ingroup Assembler + * + * \brief + * For the assemblage of the system matrix and right hand side vector of the + * linear system, we have to compute integrals, for example: + * \f[ \int_{\Omega} f(x)\varphi_i(x) dx \f] + * For general data A, b, c, and f, these integrals can not be calculated + * exactly. Quadrature formulas have to be used in order to calculate the + * integrals approximately. Numerical integration in finite element methods is + * done by looping over all grid elements and using a quadrature formula on + * each element. + */ + class Quadrature + { + public: + MEMORY_MANAGED(Quadrature); + + protected: + /** \brief + * Avoids call of default constructor + */ + Quadrature(); + + /** \brief + * Constructs a Quadrature with name name_ of degree degree_ for dim dim_. + * The Quadrature has n_points_ quadrature points with barycentric + * coordinates lambda_ and weights w_. The constructor is protected because + * access to a Quadrature should be done via \ref provideQuadrature. + */ + Quadrature(const char* name_, + int degree_, + int dim_, + int n_points_, + VectorOfFixVecs<DimVec<double> > *lambda_, + double* w_) + : name(name_), + degree(degree_), + dim(dim_), + n_points(n_points_), + lambda(lambda_), + w(w_) + {}; + + /** \brief + * Destructor + */ + ~Quadrature(); + + public: + /** \brief + * Copy constructor + */ + Quadrature(const Quadrature&); + + /** \brief + * Returns a Quadrature for dimension dim_ exact for degree degree_. + */ + static Quadrature *provideQuadrature(int dim_, int degree_); + + /** \brief + * Approximates an integral by the numerical quadrature described by quad; + * f is a pointer to an AbstractFunction to be integrated, evaluated in + * barycentric coordinates; the return value is + * \f[ \sum_{k = 0}^{n_points-1} w[k] * (*f)(lambda[k]) \f] + * For the approximation of \f$ \int_S f\f$ we have to multiply this value + * with d!|S| for a simplex S; for a parametric simplex f should be a pointer + * to a function which calculates + * \f$ f(\lambda)|det DF_S(\hat{x}(\lambda))| \f$. + */ + double integrateStdSimplex(AbstractFunction<double, DimVec<double> > *f); + + /** \brief + * Returns \ref name + */ + inline const ::std::string& getName() { return name; }; + + /** \brief + * Returns \ref n_points + */ + inline int getNumPoints() const { return n_points;}; + + /** \brief + * Returns \ref w[p] + */ + inline double getWeight(int p) const {return w[p];}; + + /** \brief + * Returns \ref w. + */ + inline double* getWeight() const { return w; }; + + /** \brief + * Returns \ref dim + */ + inline int getDim() const { return dim; }; + + /** \brief + * Returns \ref degree + */ + inline int getDegree() const { return degree; }; + + /** \brief + * Returns a pointer to a vector storing the values of a doubled valued + * function at all quadrature points; f is that AbstractFunction + * , evaluated in barycentric coordinates; if vec is not NULL, the values are + * stored in this vector, otherwise the values are stored in some static + * local vector, which is overwritten on the next call + */ + const double *fAtQp(const AbstractFunction<double, DimVec<double> >& f, + double *vec) const ; + + /** \brief + * Returns a pointer to a vector storing the gradient (with respect to world + * coordinates) of a double valued function at all quadrature points; + * grdF is a pointer to a AbstractFunction, evaluated in barycentric + * coordinates and returning a pointer to a WorldVector storing the gradient; + * if vec is not NULL, the values are stored in this vector, otherwise the + * values are stored in some local static vector, which is overwritten on the + * next call + */ + const WorldVector<double> *grdFAtQp(const AbstractFunction<WorldVector<double>, + DimVec<double> >& grdF, + WorldVector<double>* vec) const; + + + + /** \brief + * Returns \ref lambda[a][b] which is the b-th coordinate entry of the a-th + * quadrature point + */ + inline double getLambda(int a,int b) const { + return (lambda ? (*lambda)[a][b] : 0.0); + }; + + /** \brief + * Returns \ref lambda[a] which is a DimVec<double> containing the + * coordiantes of the a-th quadrature point + */ + inline const DimVec<double>& getLambda(int a) const { + return (*lambda)[a]; + }; + + /** \brief + * Returns \ref lambda which is a VectorOfFixvecs<DimVec<double> >. + */ + VectorOfFixVecs<DimVec<double> > *getLambda() const { return lambda; }; + + /** \brief + * The function returns a pointer ptr to a vector of length + * \ref n_points storing the values of \f$ u_h \f$ at all + * quadrature points, i.e. + * \f[ ptr[l] = u_h(lambda[l]) \f] where + * l = 0, . . . , n_points - 1. vec is an optional memory pointer + */ + // const double *uhAtQp(const BasisFunction *basFcts, + // const double *uh_loc, double *vec) const; + + + /** \brief + * The function returns a pointer ptr to a vector of length + * \ref n_points WorldVectors storing \f$ \nabla u_h \f$ at all + * quadrature points, i.e. + * \f[ ptr[l][i] = u_{h,xi}(lambda[l]) \f] + * where l = 0, ... , n_points - 1, and i = 0, ... , + * DIM_OF_WORLD - 1; vec is an optional memory pointer + */ + // const WorldVector<double> *grdUhAtQp(const BasisFunction *basFcts, + // const DimVec<WorldVector<double> >& Lambda, + // const double *uh_loc, + // WorldVector<double> *vec) const; + + /** \brief + * The function returns a pointer ptr to a vector of length + * \ref n_points of WorldMatrices storing D2uh at all quadrature + * points, i.e. + * \f[ ptr[l][i][j] = u_{h,x_ix_j}(lambda[l]) \f] + * where l = 0, ... , n_points - 1, and i, j = 0, ... , + * DIM_OF_WORLD - 1; vec is an optional memory pointer + */ + // const WorldMatrix<double> *D2UhAtQp(const BasisFunction *basFcts, + // const DimVec<WorldVector<double> >& Lambda, + // const double *uh_loc, + // WorldMatrix<double> *vec) const; + + + public: + /** \brief + * Maximal number of quadrature points for the different dimensions + */ + static const int maxNQuadPoints[4]; + + protected: + /** \brief + * Name of this Quadrature + */ + ::std::string name; + + /** \brief + * Quadrature is exact of this degree + */ + int degree; + + /** \brief + * Quadrature for dimension dim + */ + int dim; + + /** \brief + * Number of quadrature points + */ + int n_points; + + /** \brief + * Vector of quadrature points given in barycentric coordinates + */ + VectorOfFixVecs<DimVec<double> > *lambda; + + /** \brief + * Vector of quadrature weights + */ + double *w; + + protected: + /** \brief + * Initialisation of all static Quadrature objects which will be returned + * by \ref provideQuadrature() + */ + static void initStaticQuadratures(); + + /** \name static quadratures, used weights, and barycentric coords + * \{ + */ + static Quadrature **quad_nd[4]; + static Quadrature *quad_0d[1]; + static Quadrature *quad_1d[20]; + static Quadrature *quad_2d[18]; + static Quadrature *quad_3d[8]; + + static VectorOfFixVecs<DimVec<double> > *x_0d; + static double *w_0d; + + static VectorOfFixVecs<DimVec<double> > *x0_1d; + static VectorOfFixVecs<DimVec<double> > *x1_1d; + static VectorOfFixVecs<DimVec<double> > *x2_1d; + static VectorOfFixVecs<DimVec<double> > *x3_1d; + static VectorOfFixVecs<DimVec<double> > *x4_1d; + static VectorOfFixVecs<DimVec<double> > *x5_1d; + static VectorOfFixVecs<DimVec<double> > *x6_1d; + static VectorOfFixVecs<DimVec<double> > *x7_1d; + static VectorOfFixVecs<DimVec<double> > *x8_1d; + static VectorOfFixVecs<DimVec<double> > *x9_1d; + static double *w0_1d; + static double *w1_1d; + static double *w2_1d; + static double *w3_1d; + static double *w4_1d; + static double *w5_1d; + static double *w6_1d; + static double *w7_1d; + static double *w8_1d; + static double *w9_1d; + + static VectorOfFixVecs<DimVec<double> > *x1_2d; + static VectorOfFixVecs<DimVec<double> > *x2_2d; + static VectorOfFixVecs<DimVec<double> > *x3_2d; + static VectorOfFixVecs<DimVec<double> > *x4_2d; + static VectorOfFixVecs<DimVec<double> > *x5_2d; + static VectorOfFixVecs<DimVec<double> > *x7_2d; + static VectorOfFixVecs<DimVec<double> > *x8_2d; + static VectorOfFixVecs<DimVec<double> > *x9_2d; + static VectorOfFixVecs<DimVec<double> > *x10_2d; + static VectorOfFixVecs<DimVec<double> > *x11_2d; + static VectorOfFixVecs<DimVec<double> > *x12_2d; + static VectorOfFixVecs<DimVec<double> > *x17_2d; + static double *w1_2d; + static double *w2_2d; + static double *w3_2d; + static double *w4_2d; + static double *w5_2d; + static double *w7_2d; + static double *w8_2d; + static double *w9_2d; + static double *w10_2d; + static double *w11_2d; + static double *w12_2d; + static double *w17_2d; + + static VectorOfFixVecs<DimVec<double> > *x1_3d; + static VectorOfFixVecs<DimVec<double> > *x2_3d; + static VectorOfFixVecs<DimVec<double> > *x3_3d; + static VectorOfFixVecs<DimVec<double> > *x4_3d; + static VectorOfFixVecs<DimVec<double> > *x5_3d; + static VectorOfFixVecs<DimVec<double> > *x7_3d; + static double *w1_3d; + static double *w2_3d; + static double *w3_3d; + static double *w4_3d; + static double *w5_3d; + static double *w7_3d; + + /** \} */ + }; + + // ============================================================================ + // ===== class FastQuadrature ================================================= + // ============================================================================ + + /** \brief + * Pre-compute the values of all basis functions at all quadrature nodes; + */ + const Flag INIT_PHI=1; + + /** \brief + * Pre-compute the gradients (with respect to the barycentric coordinates) of + * all basis functions at all quadrature nodes + */ + const Flag INIT_GRD_PHI=2; + + /** \brief + * pre-compute all 2nd derivatives (with respect to the barycentric + * coordinates) of all basis functions at all quadrature nodes; + */ + const Flag INIT_D2_PHI=4; + + // ============================================================================ + + /** + * \ingroup Integration + * + *\brief + * Often numerical integration involves basis functions, such as the assembling + * of the system matrix and right hand side, or the integration of finite + * element functions. Since numerical quadrature involves only the values at + * the quadrature points and the values of basis functions and its derivatives + * are the same at these points for all elements of the grid, such routines can + * be much more efficient, if they can use pre-computed values of the basis + * functions at the quadrature points. In this case the basis functions do not + * have to be evaluated for each quadrature point on every element newly. + * Information that should be pre-computed can be specified by the following + * symbolic constants: + * \ref INIT_PHI, \ref INIT_GRD_PHI, \ref INIT_D2_PHI + */ + class FastQuadrature + { + public: + MEMORY_MANAGED(FastQuadrature); + + protected: + /** \brief + * Constructs a FastQuadrature for the given Quadrature, BasisFunction, and + * flag. + */ + FastQuadrature(BasisFunction* basFcts, + Quadrature* quad, + Flag flag) + : init_flag(flag), + phi(NULL), + grdPhi(NULL), + D2Phi(NULL), + quadrature(quad), + basisFunctions(basFcts) + {}; + + /** \brief + * Copy constructor + */ + FastQuadrature(const FastQuadrature&); + + /** \brief + * Extended copy constructor + */ + FastQuadrature(const FastQuadrature&,const Flag); + + /** \brief + * Destructor + */ + ~FastQuadrature(); + + public: + /** \brief + * Returns a FastQuadrature for the given BasisFunction, Quadrature, and + * flags + */ + static FastQuadrature* provideFastQuadrature(const BasisFunction*, + const Quadrature&, + Flag); + + /** \brief + * inits FastQuadrature like speciefied in flag + */ + void init(Flag init_flag); + + inline bool initialized(Flag flag) { + if(flag == INIT_PHI) { + return (phi != NULL); + } + + if(flag == INIT_GRD_PHI) { + return (grdPhi != NULL); + } + + if(flag == INIT_D2_PHI) { + return (D2Phi != NULL); + } + + ERROR_EXIT("invalid flag\n"); + return false; + }; + + /** \brief + * Returns \ref quadrature + */ + inline const Quadrature* getQuadrature() const { return quadrature; }; + + /** \brief + * Returns \ref max_points + */ + inline int getMaxQuadPoints() { return max_points; }; + + /** \brief + * Returns (*\ref D2Phi)[q][i][j][m] + */ + const double getSecDer(int q,int i ,int j, int m) const; + + /** \brief + * Returns (*\ref D2Phi)[q] + */ + const VectorOfFixVecs<DimMat<double> > *getSecDer(int q) const; + + /** \brief + * Returns (*\ref grdPhi)[q][i][j] + */ + const double getGradient(int q, int i ,int j) const; + + /** \brief + * Returns (*\ref grdPhi)[q] + */ + VectorOfFixVecs<DimVec<double> >* getGradient(int q) const; + + /** \brief + * Returns \ref phi[q][i] + */ + inline const double getPhi(int q,int i) const {return (phi)?phi[q][i]:0;}; + + /** \brief + * Returns \ref phi[q] + */ + inline const double *getPhi(int q) const {return (phi)?phi[q]:0;}; + + /** \brief + * Returns \ref quadrature ->integrateStdSimplex(f) + */ + inline double + integrateStdSimplex(AbstractFunction<double, DimVec<double> > *f) { + return quadrature->integrateStdSimplex(f); + }; + + /** \brief + * Returns \ref quadrature ->getNumPoints() + */ + inline int getNumPoints() const { return quadrature->getNumPoints();}; + + /** \brief + * Returns \ref quadrature ->getWeight(p) + */ + inline double getWeight(int p) const {return quadrature->getWeight(p);}; + + /** \brief + * Returns \ref quadrature ->getDim() + */ + inline int getDim() const { return quadrature->getDim(); }; + + /** \brief + * Returns \ref quadrature ->getDegree() + */ + inline int getDegree() const { return quadrature->getDegree(); }; + + /** \brief + * Returns \ref quadrature ->grdFAtQp(f, vec) + */ + inline const WorldVector<double> + *grdFAtQp(const AbstractFunction<WorldVector<double>, + DimVec<double> >& f, + WorldVector<double>* vec) const + { + return quadrature->grdFAtQp(f, vec); + }; + + /** \brief + * Returns \ref quadrature ->fAtQp(f, vec) + */ + inline const double *fAtQp(const AbstractFunction<double, + DimVec<double> >& f,double *vec) const + { + return quadrature->fAtQp(f, vec); + }; + + /** \brief + * Returns \ref quadrature ->getLambda(a,b) + */ + inline double getLambda(int a,int b) const { + return quadrature->getLambda(a,b); + }; + + /** \brief + * Returns \ref quadrature ->getLambda(a) + */ + inline const DimVec<double>& getLambda(int a) const { + return quadrature->getLambda(a); + }; + + /** \brief + * Returns \ref basisFunctions + */ + inline BasisFunction* getBasisFunctions() const { return basisFunctions; }; + + /** \brief + * The function returns a pointer ptr to a vector of length + * \ref quadrature->n_points storing the values of \f$ u_h \f$ at all + * quadrature points of \ref quadrature, i.e. + * \f[ ptr[l] = u_h(quadrature->lambda[l]) \f] where + * l = 0, . . . , quadrature->n_points - 1; the \ref INIT_PHI flag must + * be set in \ref init_flag; vec is an optional memory pointer + */ + // const double *uhAtQp(const double *uh_loc, double *vec) const; + + /** \brief + * The function returns a pointer ptr to a vector of length + * quadrature->n_points WorldVectors storing \f$ \nabla u_h \f$ at all + * quadrature points of \ref quadrature, i.e. + * \f[ ptr[l][i] = u_{h,xi}(quadrature->lambda[l]) \f] + * where l = 0, ... , quadrature->n_points - 1, and i = 0, ... , + * DIM_OF_WORLD - 1; the \ref INIT_GRD_PHI flag must be set in + * \ref init flag; vec is an optional memory pointer + */ + // const WorldVector<double> *grdUhAtQp(const DimVec<WorldVector<double> >& Lambda, + // const double *uh_loc, + // WorldVector<double> *vec) const; + + + /** \brief + * The function returns a pointer ptr to a vector of length + * quadrarure->n_points of WorldMatrices storing D2uh at all quadrature + * points of \ref quadrature, i.e. + * \f[ ptr[l][i][j] = u_{h,x_ix_j}(quadrature->lambda[l]) \f] + * where l = 0, ... , quadrature->n_points - 1, and i, j = 0, ... , + * DIM_OF_WORLD - 1; the \ref INIT_D2_PHI flag must be set in + * \ref init flag; vec is an optional memory pointer + */ + // const WorldMatrix<double> *D2UhAtQp(const DimVec<WorldVector<double> >& Lambda, + // const double *uh_loc, + // WorldMatrix<double> *vec) const; + + protected: + /** \brief + * Specifies which information should be pre-computed. Can be \ref INIT_PHI, + * \ref INIT_GRD_PHI, or \ref INIT_D2_PHI + */ + Flag init_flag; + + /** \brief + * Matrix storing function values if the flag \ref INIT_PHI is set; + * phi[i][j] stores the value \ref basisFunctions->phi[j] + * (quadrature->lambda[i]), 0 <= j < basisFunctions->getNumber() and + * 0 <= i < n_points + */ + double **phi; + + /** \brief + * Matrix storing all gradients (with respect to the barycentric coordinates) + * if the flag \ref INIT_GRD_PHI is set; grdPhi[i][j][k] stores the value + * basisFunctions->grdPhi[j](quadrature->lambda[i])[k] + * for 0 <= j < basisFunctions->getNumber(), + * 0 <= i < . . . , n_points, and 0 <= k < DIM + */ + MatrixOfFixVecs<DimVec<double> > *grdPhi; + + /** \brief + * Matrix storing all second derivatives (with respect to the barycentric + * coordinates) if the flag \ref INIT_D2_PHI is set; D2Phi[i][j][k][l] stores + * the value basisFunctions->D2Phi[j](quadrature->lambda[i])[k][l] + * for 0 <= j < basisFunctions->getNumber(), + * 0 <= i < n_points, and 0 <= k,l < DIM + */ + MatrixOfFixVecs<DimMat<double> > *D2Phi; + + /** \brief + * List of all used FastQuadratures + */ + static ::std::list<FastQuadrature*> fastQuadList; + + /** \brief + * Maximal number of quadrature points for all yet initialised FastQuadrature + * objects. This value may change after a new initialisation of a + * FastQuadrature + */ + static int max_points; + + /** \brief + * This FastQuadrature stores values for Quadrature quadrature + */ + Quadrature* quadrature; + + /** \brief + * Values stored for basis functions basisFunctions + */ + BasisFunction* basisFunctions; + + }; + +} + +#endif // AMDIS_QUADRATURE_H diff --git a/AMDiS/src/Quadrature.hh b/AMDiS/src/Quadrature.hh new file mode 100644 index 0000000000000000000000000000000000000000..80a50a2e832608f364550053b40d33e84c45a161 --- /dev/null +++ b/AMDiS/src/Quadrature.hh @@ -0,0 +1,168 @@ +namespace AMDiS { + + /****************************************************************************/ + /* standard routines for getting values of a finite element function and */ + /* its first (and second) derivatives at the quadrature points */ + /****************************************************************************/ + + template<typename T> + const T *uhAtQp(const FastQuadrature *quadFast, + const T *uhLoc, T *vec) + { + FUNCNAME("uhAtQp()"); + static T *quadVec = NULL; + static int size = 0; + T *val; + const double *phi; + int i, j, k; + + int nPoints = quadFast->getQuadrature()->getNumPoints(); + int nBasFcts = quadFast->getBasisFunctions()->getNumber(); + int dim = quadFast->getDim(); + + int vecSize = uhLoc[0].size(); + + if (vec) { + val = vec; + } else { + if (size < nPoints) { + int newSize = ::std::max(Quadrature::maxNQuadPoints[dim], nPoints); + if(quadVec) DELETE [] quadVec; + quadVec = NEW T[size](vecSize); + size = newSize; + } + val = quadVec; + } + + for (i = 0; i < nPoints; i++) { + phi = quadFast->getPhi(i); + for(k = 0; k < vecSize; k++) { + for (val[i][k] = j = 0; j < nBasFcts; j++) { + val[i][k] += uhLoc[j][k] * phi[j]; + } + } + } + return(const_cast<const T*>(val)); + } + + template<typename T, typename GrdT> + const GrdT *grdUhAtQp(const FastQuadrature *quadFast, + const DimVec<WorldVector<double> >& grdLambda, + const T *uhLoc, GrdT *vec) + { + FUNCNAME("grdUhAtQp()"); + + int i, j, k, l, m; + + int dim = quadFast->getDim(); + int dow = Global::getGeo(WORLD); + int parts = Global::getGeo(PARTS, dim); + + int nPoints = quadFast->getQuadrature()->getNumPoints(); + int nBasFcts = quadFast->getBasisFunctions()->getNumber(); + + static GrdT *quadVec = NULL; + static int size = 0; + GrdT *val; + VectorOfFixVecs<DimVec<double> > *gradPhi; + DimVec<double> grd1(dim, NO_INIT); + + int vecSize = uhLoc[0].size(); + + if (vec) { + val = vec; + } else { + if(size < nPoints) { + int newSize = ::std::max(Quadrature::maxNQuadPoints[dim], nPoints); + if(quadVec) DELETE [] quadVec; + quadVec = NEW GrdT[newSize](vecSize); + size = newSize; + } + val = quadVec; + } + + for (i = 0; i < nPoints; i++) { + gradPhi = quadFast->getGradient(i); + for(m = 0; m < vecSize; m++) { + grd1 = 0.0; + for (j = 0; j < nBasFcts; j++) { + for (k = 0; k < parts; k++) { + grd1[k] += (*gradPhi)[j][k] * uhLoc[j][m]; + } + } + + for(l=0; l < dow; l++) { + for (val[i][m][l] = k = 0; k < parts; k++) { + val[i][m][l] += grdLambda[k][l] * grd1[k]; + } + } + } + } + + return(const_cast<const GrdT*>(val)); + } + + template<typename T, typename D2T> + const D2T* D2UhAtQp(const FastQuadrature *quadFast, + const DimVec<WorldVector<double> >& grdLambda, + const T *uhLoc, D2T *vec) + { + FUNCNAME("D2UhAtQp()"); + + int i, j, k, l, m, iq; + + int nPoints = quadFast->getQuadrature()->getNumPoints(); + int nBasFcts = quadFast->getBasisFunctions()->getNumber(); + int dim = quadFast->getDim(); + + int parts = Global::getGeo(PARTS, dim); + int dow = Global::getGeo(WORLD); + + static D2T *quadVec = NULL; + static int size = 0; + D2T *val; + const VectorOfFixVecs<DimMat<double> > *D2Phil; + DimMat<double> D2Tmp(dim, DEFAULT_VALUE, 0.); + + int vecSize = uhLoc[0].size(); + + if (vec) { + val = vec; + } else { + if(size < nPoints) { + int newSize = ::std::max(Quadrature::maxNQuadPoints[dim], nPoints); + if(quadVec) DELETE [] quadVec; + quadVec = NEW D2T[newSize](vecSize); + size = newSize; + } + val = quadVec; + } + + for (iq = 0; iq < nPoints; iq++) { + for(m = 0; m < vecSize; m++) { + D2Tmp = 0.0; + //for (k = 0; k < parts; k++) + // for (l = 0; l < parts; l++) + // D2Tmp[k][l] = 0.0; + + D2Phil = quadFast->getSecDer(iq); + for (i = 0; i < nBasFcts; i++) { + for (k = 0; k < parts; k++) + for (l = 0; l < parts; l++) + D2Tmp[k][l] += uhLoc[i][m]*(*D2Phil)[i][k][l]; + } + + for (i = 0; i < dow; i++) + for (j = 0; j < dow; j++) { + val[iq][m][i][j] = 0.0; + for (k = 0; k < parts; k++) + for (l = 0; l < parts; l++) + val[iq][m][i][j] += grdLambda[k][i]*grdLambda[l][j]*D2Tmp[k][l]; + } + } + } + + return(const_cast<const D2T*>(val)); + } + +} diff --git a/AMDiS/src/RCNeighbourList.cc b/AMDiS/src/RCNeighbourList.cc new file mode 100644 index 0000000000000000000000000000000000000000..dc2f83c5d807386c2c3c6d4bd808bb316df37aac --- /dev/null +++ b/AMDiS/src/RCNeighbourList.cc @@ -0,0 +1,418 @@ +#include "RCNeighbourList.h" +#include "Element.h" +#include "Line.h" +#include "Triangle.h" +#include "Tetrahedron.h" +#include "MacroElement.h" +#include "Mesh.h" +#include "Traverse.h" +#include "FixVec.h" +#include "CoarseningManager.h" +#include "PeriodicBC.h" +#include "DOFVector.h" +#include "LeafData.h" + +namespace AMDiS { + + RCNeighbourList::RCNeighbourList(int maxEdgeNeigh) { + rclist.resize(maxEdgeNeigh); + int i; + for(i = 0; i < maxEdgeNeigh; i++) + rclist[i] = new RCListElement; + } + + RCNeighbourList::~RCNeighbourList() { + int i, size = static_cast<int>(rclist.size()); + for(i = 0; i < size; i++) + delete rclist[i]; + } + + /****************************************************************************/ + /* do_coarse_patch: if patch can be coarsend return true, else false and */ + /* reset the element marks */ + /****************************************************************************/ + + bool RCNeighbourList::doCoarsePatch(int n_neigh) + { + FUNCNAME("RCNeighbourList::doCoarsePatch"); + int i, j; + Element *lel; + + for (i = 0; i < n_neigh; i++) + { + lel =rclist[i]->el; + + if (lel->getMark() >= 0 || lel->isLeaf()) + { + /****************************************************************************/ + /* element must not be coarsend or element is a leaf element, reset the */ + /* the coarsening flag on all those elements that have to be coarsend with */ + /* this element */ + /****************************************************************************/ + lel->setMark(0); + for (j = 0; j < n_neigh; j++) + if (rclist[j]->flag) rclist[j]->el->setMark(0); + return(false); + } + else if (lel->getFirstChild()->getMark() >= 0 || + lel->getSecondChild()->getMark() >= 0) + { + /****************************************************************************/ + /* one of the element's children must not be coarsend; reset the coarsening*/ + /* flag on all those elements that have to be coarsend with this element */ + /****************************************************************************/ + lel->setMark(0); + for (j = 0; j < n_neigh; j++) + if (rclist[j]->flag) rclist[j]->el->setMark(0); + return(false); + } + else if (!lel->getFirstChild()->isLeaf() || + !lel->getSecondChild()->isLeaf()) + { + /****************************************************************************/ + /* one of the element's children is not a leaf element; */ + /* element may be coarsend after coarsening one of the children; try again */ + /****************************************************************************/ + coarseningManager->doMore = true; + return(false); + } + else + { + /****************************************************************************/ + /* either one element is a macro element or we can coarsen the patch */ + /****************************************************************************/ + if (rclist[i]->flag == 0) { + + ::std::deque<MacroElement*>::const_iterator mel; + + Mesh* coarse_mesh = coarseningManager->getMesh(); + // set in Mesh::coarsen() + for (mel = coarse_mesh->firstMacroElement(); + mel!=coarse_mesh->endOfMacroElements(); + mel++) + if ((*mel)->getElement() == lel) break; + + TEST_EXIT(mel!=coarse_mesh->endOfMacroElements()) + ("incompatible coarsening patch found\n"); + } + } + } + + return(true); + } + + + void RCNeighbourList::getNeighOnPatch(int n_neigh, int bound) + { + FUNCNAME("RCNeighbourList::getNeighOnPatch"); + + int i, j, k, dir; + Element *el, *neigh; + + //Mesh *mesh = rclist[0]->el->getMesh(); + + for (i = 0; i < n_neigh; i++) + { + el = rclist[i]->el; + rclist[i]->no = i; + + for (dir = 0; dir < 2; dir++) + { + for (j = 0; j < n_neigh; j++) + { + if ((neigh = rclist[j]->el) == el) continue; + + for (k = 0; k < 2; k++) + { + if (neigh->getDOF(2+k) == el->getDOF(3-dir)) + { + rclist[i]->neigh[dir] = rclist[j]; + rclist[i]->oppVertex[dir] = 3-k; + break; + } + } + + if (k < 2) break; + } + + if (j >= n_neigh) + { + // TEST_EXIT(bound) + // ("neighbour of element %d in list not found\n", el->getIndex()); + rclist[i]->neigh[dir] = NULL; + rclist[i]->oppVertex[dir] = -1; + } + } + } + return; + } + + void RCNeighbourList::addDOFParent(int elIndex, DegreeOfFreedom* dof) // 3d + { + Element *el = rclist[elIndex]->el; + RCListElement *neighbour; + int node; + + Mesh *coarse_mesh = coarseningManager->getMesh(); + RCListElement *coarse_list = rclist[elIndex]; + + if (coarse_mesh->getNumberOfDOFs(EDGE)) + { + node = coarse_mesh->getNode(EDGE); + + /****************************************************************************/ + /* set the dof in the coarsening edge */ + /****************************************************************************/ + + el->setDOF(node, dof); + + /****************************************************************************/ + /* and now those handed on by the children */ + /****************************************************************************/ + + el->setDOF(node+1, const_cast<int*>( el->getFirstChild()->getDOF(node))); + el->setDOF(node+2, const_cast<int*>( el->getFirstChild()->getDOF(node+1))); + el->setDOF(node+5, const_cast<int*>( el->getFirstChild()->getDOF(node+3))); + + if (coarse_list->elType) + { + el->setDOF(node+3, const_cast<int*>( el->getSecondChild()->getDOF(node))); + el->setDOF(node+4, const_cast<int*>( el->getSecondChild()->getDOF(node+1))); + } + else + { + el->setDOF(node+3, const_cast<int*>( el->getSecondChild()->getDOF(node+1))); + el->setDOF(node+4, const_cast<int*>( el->getSecondChild()->getDOF(node))); + } + } + + if (coarse_mesh->getNumberOfDOFs(FACE)) + { + node = coarse_mesh->getNode(FACE); + /****************************************************************************/ + /* dof's at the faces within the patch: add new dof's if it is a boundary */ + /* face or neighbour is an element behind this element in the corsen list */ + /****************************************************************************/ + + neighbour = coarse_list->neigh[0]; + if ((!neighbour) || (neighbour > coarse_list)) + { + if (!el->getDOF(node+2)) + { + el->setDOF(node+2, const_cast<int*>( coarse_mesh->getDOF(FACE))); /* face 2 */ + if (neighbour) + neighbour->el->setDOF(node+coarse_list->oppVertex[0], + const_cast<int*>( el->getDOF(node+2))); + } + } + neighbour = coarse_list->neigh[1]; + if ((!neighbour) || (neighbour > coarse_list)) + { + if (!el->getDOF(node+3)) + { + el->setDOF(node+3, const_cast<int*>( coarse_mesh->getDOF(FACE))); /* face 3 */ + if (neighbour) + neighbour->el->setDOF(node+coarse_list->oppVertex[1], + const_cast<int*>( el->getDOF(node+3))); + } + } + /****************************************************************************/ + /* and now those handed on by the children */ + /****************************************************************************/ + + el->setDOF(node, const_cast<int*>( el->getSecondChild()->getDOF(node+3))); + el->setDOF(node+1, const_cast<int*>( el->getFirstChild()->getDOF(node+3))); + } + + if (coarse_mesh->getNumberOfDOFs(CENTER)) + { + node = coarse_mesh->getNode(CENTER); + if (!el->getDOF(node)) + el->setDOF(node, const_cast<int*>( coarse_mesh->getDOF(CENTER))); + } + return; + } + + void RCNeighbourList::addDOFParents(int n_neigh) // 2d + { + int i, node; + + Mesh *coarse_mesh = coarseningManager->getMesh(); + + if (coarse_mesh->getNumberOfDOFs(EDGE)) + { + node = coarse_mesh->getNode(EDGE); + + /****************************************************************************/ + /* get dofs on the boundary of the coarsening patch from the children */ + /****************************************************************************/ + for (i = 0; i < n_neigh; i++) + { + rclist[i]->el-> + setDOF(node, const_cast<int*>( rclist[i]->el->getSecondChild()->getDOF(node+2))); + rclist[i]->el-> + setDOF(node+1, const_cast<int*>( rclist[i]->el->getFirstChild()->getDOF(node+2))); + } + } + + if (coarse_mesh->getNumberOfDOFs(CENTER)) + { + int node = coarse_mesh->getNode(CENTER); + + /****************************************************************************/ + /* get new dof on parents at the barycenter */ + /****************************************************************************/ + for (i = 0; i < n_neigh; i++) + { + if (!rclist[i]->el->getDOF(node)) + rclist[i]->el->setDOF(node, const_cast<int*>( coarse_mesh->getDOF(CENTER))); + } + } + + return; + } + + + void RCNeighbourList::removeDOFParents(int n_neigh) + { + int i, j, node; + Mesh *mesh = rclist[0]->el->getMesh(); + int edges = mesh->getGeo(EDGE); + + if (mesh->getNumberOfDOFs(EDGE)) + { + node = mesh->getNode(EDGE); + + for (i = 0; i < n_neigh; i++) + { + for (j = 0; j < edges; j++) + rclist[i]->el->setDOF(node+j, NULL); + } + } + + if (mesh->getNumberOfDOFs(CENTER)) + { + node = mesh->getNode(CENTER); + for (i = 0; i < n_neigh; i++) + { + mesh->freeDOF(const_cast<int*>( rclist[i]->el->getDOF(node)), CENTER); + rclist[i]->el->setDOF(node, NULL); + } + } + } + + void RCNeighbourList::removeDOFParent(int index) + { + Tetrahedron *el = dynamic_cast<Tetrahedron*>(rclist[index]->el); + RCListElement *neigh; + int j, node; + Mesh *mesh = el->getMesh(); + int edges = mesh->getGeo(EDGE); + int faces = mesh->getGeo(FACE); + + + if (mesh->getNumberOfDOFs(EDGE)) + { + node = mesh->getNode(EDGE); + for (j = 0; j < edges; j++) + el->setDOF(node+j, NULL); + } + + if (mesh->getNumberOfDOFs(FACE)) + { + node = mesh->getNode(FACE); + + neigh = rclist[index]->neigh[0]; + if ((!neigh) || (neigh > rclist[index])) + mesh->freeDOF(const_cast<int*>( el->getDOF(node+2)), FACE); /* face 2 */ + + neigh = rclist[index]->neigh[1]; + if ((!neigh) || (neigh > rclist[index])) + mesh->freeDOF(const_cast<int*>( el->getDOF(node+3)), FACE); /* face 3 */ + + for (j = 0; j < faces; j++) + el->setDOF(node+j, NULL); + } + + if (mesh->getNumberOfDOFs(CENTER)) + { + node = mesh->getNode(CENTER); + mesh->freeDOF(const_cast<int*>( el->getDOF(node)), CENTER); + el->setDOF(node, NULL); + } + return; + } + + RCNeighbourList *RCNeighbourList::periodicSplit(DegreeOfFreedom *edge[2], + DegreeOfFreedom *nextEdge[2], + int *n_neigh, + int *n_neigh_periodic) + { + static RCNeighbourList *periodicList = NULL; + + if(periodicList) { + DELETE periodicList; + periodicList = NULL; + } + + *n_neigh_periodic = 0; + + int count = 0, n_neigh_old = *n_neigh; + + bool secondPart = false; + + nextEdge[0] = NULL; + nextEdge[1] = NULL; + + ::std::vector<RCListElement*>::iterator it = rclist.begin(); + ::std::vector<RCListElement*>::iterator insertIt; + + while(count < n_neigh_old) { + DegreeOfFreedom *dof0 = const_cast<DegreeOfFreedom*>((*it)->el->getDOF(0)); + DegreeOfFreedom *dof1 = const_cast<DegreeOfFreedom*>((*it)->el->getDOF(1)); + + if(dof0 != edge[0] && dof0 != edge[1]) { + secondPart = true; + if(!nextEdge[0]) { + nextEdge[0] = dof0; + nextEdge[1] = dof1; + } + ++it; + } else { + (*n_neigh)--; + (*n_neigh_periodic)++; + + if(!periodicList) { + periodicList = NEW RCNeighbourList; + insertIt = periodicList->rclist.end(); + periodicList->coarseningManager = coarseningManager; + } else { + if(edge[0]) { + TEST_EXIT((dof0 == edge[0] && dof1 == edge[1]) || + (dof1 == edge[0] && dof0 == edge[1])) + ("invalid macro file?\n"); + } + } + + if(secondPart) { + insertIt = periodicList->rclist.begin(); + secondPart = false; + } + + insertIt = periodicList->rclist.insert(insertIt, *it); + ++insertIt; + + it = rclist.erase(it); + } + ++count; + } + + int i; + for(i = 0; i < *n_neigh_periodic; i++) { + periodicList->rclist[i]->no = i; + } + + return periodicList; + } + +} diff --git a/AMDiS/src/RCNeighbourList.h b/AMDiS/src/RCNeighbourList.h new file mode 100644 index 0000000000000000000000000000000000000000..8646c9ae58222bf1334780e4b6b9dd0e46e39e56 --- /dev/null +++ b/AMDiS/src/RCNeighbourList.h @@ -0,0 +1,266 @@ +// ============================================================================ +// == == +// == AMDiS - Adaptive multidimensional simulations == +// == == +// ============================================================================ +// == == +// == crystal growth group == +// == == +// == Stiftung caesar == +// == Ludwig-Erhard-Allee 2 == +// == 53175 Bonn == +// == germany == +// == == +// ============================================================================ +// == == +// == http://www.caesar.de/cg/AMDiS == +// == == +// ============================================================================ + +/** \file RCNeighbourList.h */ + +#ifndef AMDIS_RCNEIGHBOURLIST_H +#define AMDIS_RCNEIGHBOURLIST_H + +#include <vector> +#include <deque> +#include "Global.h" +#include "MemoryManager.h" + +namespace AMDiS { + + class Element; + class ElInfo; + class CoarseningManager; + + // =========================================================================== + // ===== class RCNeighbourList =============================================== + // =========================================================================== + + /** \ingroup Adaption + * \brief + * Stores information about coarsening and refinement patches. For refining + * and coarsening we need information of the elements at the refinement and + * coarsening edge. Thus, we have to collect all elements at this edge. In 2d + * we have at most the current element and its neighbour across this edge, if + * the edge is not part of the boundary. In 3d we have to loop around this + * edge to collect all the elements. Every element at the edge has at most two + * neighbours sharing the same edge. Defining an orientation for this edge, + * we can define the right and left neighbour. + * For every element at the refinement/coarsening edge we have an entry in a + * vector. The elements of this vector build the refinement/coarsening patch. + * In 2d the vector has length 2 and in 3d length mesh->getMaxEdgeNeigh() + * since this is the maximal number of elements sharing the same edge in the + * Mesh. + */ + class RCNeighbourList + { + public: + MEMORY_MANAGED(RCNeighbourList); + + /** \brief + * Constructs a RCNeighbourList of size maxEdgeNeigh + */ + RCNeighbourList(int maxEdgeNeigh); + + RCNeighbourList() {}; + + /** \brief + * Destructor + */ + virtual ~RCNeighbourList(); + + /** \brief + * Sets flag of \ref rclist[i] = true + */ + inline void setCoarsePatch(int i) {rclist[i]->flag=true;}; + + /** \brief + * Sets flag of \ref rclist[i] = f + */ + inline void setCoarsePatch(int i,bool f) {rclist[i]->flag=f;}; + + /** \brief + * Returns \ref rclist[i].flag + */ + inline const bool isPatchCoarse(int i) const {return rclist[i]->flag;}; + + /** \brief + * If \ref rclist[i].neigh[j] is not a NULL pointer + * \ref rclist[i].neigh[j]->no will be returned. Otherwise the return value + * is -1 + */ + inline int getNeighbourNr(int i, int j) const { + return (rclist[i]->neigh[j])?rclist[i]->neigh[j]->no:-1; + }; + + /** \brief + * If \ref rclist[i].neigh[j] is not a NULL pointer + * \ref rclist[i].neigh[j]->el will be returned. Otherwise the return value + * is NULL + */ + inline Element* getNeighbourElement(int i, int j) const { + return rclist[i]->neigh[j]? rclist[i]->neigh[j]->el : NULL; + }; + + /** \brief + * Returns \ref rclist[i].el + */ + inline Element* getElement(int i) const { + if(static_cast<int>(rclist.size()) <= i) return NULL; + return rclist[i]->el; + }; + + /** \brief + * Sets \ref rclist[i].el to el and \ref rclist[i].flag to cp. + */ + inline const Element* setElement(int i,const Element* el,bool cp=false) { + rclist[i]->el=const_cast<Element*>(el); + rclist[i]->flag=cp; + return el; + }; + + /** \brief + * Returns \ref rclist[i].elType + */ + inline int getType(int i) const {return rclist[i]->elType;}; + + inline void setType(int i, int type) const { + rclist[i]->elType = type; + }; + + /** \brief + * If patch can be coarsend return true, else false and reset the element + * marks + */ + virtual bool doCoarsePatch(int n_neigh); + + /** \brief + * Sets \ref rclist[i].oppVertex[j] = k + */ + inline void setOppVertex(int i,int j,int k) {rclist[i]->oppVertex[j]=k;}; + + /** \brief + * Returns \ref rclist[i].oppVertex[j] + */ + inline int getOppVertex(int i, int j) { return rclist[i]->oppVertex[j]; }; + + /** \brief + * Sets \ref rclist[i].elType = t + */ + inline void setElType(int i,unsigned char t) {rclist[i]->elType=t;}; + + /** \brief + * Sets \ref coarseningManager = cm + */ + inline void setCoarseningManager(CoarseningManager *cm) { + coarseningManager = cm; + }; + + /** \brief + * Fills \ref rclist[i].neigh and \ref rclist[i].oppVertex infos ( 0 <= i + * < n_neigh) + */ + void getNeighOnPatch(int n_neigh, int bound); + + /** \brief + * Adds those dof's on the parent that are handed on by the + * children and adds the dof in the midpoint of the coarsening edge (3d) + */ + void addDOFParent(int elIndex, DegreeOfFreedom* dof); + + /** \brief + * If DOFs for higher order are been removed on parents during refinement + * they are now added again (2d) + */ + void addDOFParents(int n_neigh); + + /** \brief + * Removes DOFs during refinement (3d) + */ + void removeDOFParent(int index); + + /** \brief + * Removes DOFs during refinement (2d) + */ + void removeDOFParents(int n_neigh); + + // /** \brief + // * Sets \ref newCoords. + // */ + // inline void setNewCoords(int i, bool n) { rclist[i].newCoords = n; }; + + // /** \brief + // * Returns \ref newCoords. + // */ + // inline bool getNewCoords(int i) const { return rclist[i].newCoords; }; + + RCNeighbourList *periodicSplit(DegreeOfFreedom *edge[2], + DegreeOfFreedom *nextEdge[2], + int *n_neigh, + int *n_neigh_periodic); + + protected: + /** \brief + * Information about one Element of the patch + */ + class RCListElement + { + public: + /** \brief + * Pointer to the Element + */ + Element* el; + + /** \brief + * This is the no-th entry in the RCNeighbourList + */ + int no; + + /** \brief + * Only used in the coarsening module: flag is true if the coarsening + * edge of the Element is the coarsening edge of the patch, otherwise + * flag is false; + */ + bool flag; + + /** \brief + * neigh[0/1] neighbour of element to the right/left in the orientation + * of the edge, or a NULL pointer in the case of a boundary face (only 3d) + */ + RCListElement* neigh[2]; + + /** \brief + * opp vertex[0/1] the opposite vertex of neigh[0/1] (only 3d) + */ + int oppVertex[2]; + + /** \brief + * The element type; is set during looping around the + * refinement/coarsening edge; if neighbour information is produced by the + * traversal routines, information about the type of an element can not be + * accessed via el->getType() and thus has to be stored in the + * RCListElement vector (only 3d) + */ + unsigned char elType; + + // /** \brief + // * Stores whether coordinate interpolation must be done. + // */ + // bool newCoords; + }; + + /** \brief + * Refinement/coarsening patch + */ + ::std::vector<RCListElement*> rclist; + + /** \brief + * Pointer to the CoarseningManager + */ + CoarseningManager *coarseningManager; + }; + +} + +#endif // AMDIS_RCNEIGHBOURLIST_H diff --git a/AMDiS/src/Recovery.cc b/AMDiS/src/Recovery.cc new file mode 100644 index 0000000000000000000000000000000000000000..6c23ea09fbf17812f864427722744937237e92c3 --- /dev/null +++ b/AMDiS/src/Recovery.cc @@ -0,0 +1,1093 @@ +#include "Recovery.h" + +RecoveryStructure& RecoveryStructure::operator=(const RecoveryStructure& rhs) { + + + if (rhs.coords) { + if (!coords) + coords=NEW WorldVector<double>; + *coords=*rhs.coords; + } + else { + if (coords) { + DELETE coords; + coords=NULL; + } + } + + if (rhs.A) { + if (!A) + A=NEW Matrix<double>(rhs.A->getNumRows(), rhs.A->getNumCols()); + *A=*rhs.A; + } + else { + if (A) { + DELETE A; + A=NULL; + } + } + + if (rhs.rec_uh) { + if (!rec_uh) + rec_uh=NEW Vector<double>(rhs.rec_uh->getSize()); + *rec_uh=*rhs.rec_uh; + } + else { + if (rec_uh) { + DELETE rec_uh; + rec_uh=NULL; + } + } + + if (rhs.rec_grdUh) { + if (!rec_grdUh) + rec_grdUh = NEW Vector<WorldVector<double> >(rhs.rec_grdUh->getSize()); + *rec_grdUh=*rhs.rec_grdUh; + } + else { + if (rec_grdUh) { + DELETE rec_grdUh; + rec_grdUh=NULL; + } + } + + if (rhs.neighbors) { + if (!neighbors) + neighbors = NEW ::std::set<DegreeOfFreedom>; + *neighbors=*rhs.neighbors ; + } + else { + if (neighbors) { + DELETE neighbors; + neighbors=NULL; + } + } + + return *this; +}; + + + +void RecoveryStructure::print() +{ + FUNCNAME("RecoveryStructure::print"); + + int i, j; + + ::std::cout << ::std::endl; + + MSG("Coordinates of the node: "); + ::std::cout << *coords << ::std::endl; + + if (A) + { + MSG("Interior vertex: printing system information.\n\n"); + + int n = A->getNumRows(); + + MSG("System matrix:\n"); + for (i=0; i<n; i++) + { + MSG("( "); + for (j=0; j<i; j++) + ::std::cout << "* "; + for (j=i; j<n; j++) + ::std::cout << (*A)[i][j] << " "; + ::std::cout << ")" << ::std::endl; + } + + MSG("Right hand side:\n"); + for (i=0; i<n; i++) + { + MSG("( "); + if (rec_grdUh) + ::std::cout << (*rec_grdUh)[i]; + else + ::std::cout << (*rec_uh)[i]; + ::std::cout << " )" << ::std::endl; + } + + if (neighbors) + { + MSG("Printing neighbors vertices\n\n"); + + MSG("Number of neighbors: "); + ::std::cout << neighbors->size() << ::std::endl << ::std::endl; + + MSG("List of neighbors: "); + ::std::set<DegreeOfFreedom>::const_iterator setIterator; + + for (setIterator = neighbors->begin(); + setIterator != neighbors->end(); + ++setIterator) + ::std::cout << " " << *setIterator; + + ::std::cout << ::std::endl << ::std::endl; + } + } + else + { + MSG("Boundary vertex or not a vertex node: printing interior neighbors\n\n"); + + MSG("Number of neighbors: "); + ::std::cout << neighbors->size() << ::std::endl << ::std::endl; + + MSG("List of neighbors: "); + ::std::set<DegreeOfFreedom>::const_iterator setIterator; + + for (setIterator = neighbors->begin(); + setIterator != neighbors->end(); + ++setIterator) + ::std::cout << " " << *setIterator; + + ::std::cout << ::std::endl << ::std::endl; + } + + WAIT; + + return; +} + +/*****************************************************************************/ + +void Recovery::set_feSpace(const FiniteElemSpace *fe_space) +{ + FUNCNAME("Recovery::set_feSpace"); + + if (!feSpace || (feSpace != fe_space)) + { + if (struct_vec) + { + DELETE struct_vec; + struct_vec = NULL; + } + + feSpace = fe_space; + + // create new structure vector + struct_vec = NEW DOFVector<RecoveryStructure>(feSpace, "struct vec"); + } + + return; +} + +int Recovery::set_exponents(int degree) +{ + FUNCNAME("Recovery::set_exponents"); + + int dow = Global::getGeo(WORLD); + int number_monomials = degree + 1; + + // Computing number of monomials. + if (dow > 1) + { + number_monomials *= (degree + 2); + number_monomials /= 2; + } + + if (dow == 3) + { + number_monomials *= (degree + 3); + number_monomials /= 3; + } + + // Allocating memory. + if (n_monomials != number_monomials) + { + n_monomials = number_monomials; + exponents.resize(n_monomials); + + if (matrix_fcts) + matrix_fcts->resize(n_monomials, n_monomials); + else + matrix_fcts = NEW Matrix<Monomial*>(n_monomials, n_monomials); + } + + // Setting vector of exponents. + int i, j, k, count = 0; + + switch (dow) + { + case 1: // 1D monomials. + for (i=0; i<=degree; i++) + exponents[count++][0] = i; + break; + + case 2: // 2D monomials. + for (i=0; i<=degree; i++) + for (j=0; j<=i; j++) + { + exponents[count][0] = i - j; + exponents[count++][1] = j; + } + break; + + case 3: // 3D monomials. + for (i=0; i<=degree; i++) + for (j=0; j<=i; j++) + for (k=0; k<=j; k++) + { + exponents[count][0] = i - j; + exponents[count][1] = j - k; + exponents[count++][2] = k; + } + break; + + default: + ERROR_EXIT("Which dimension have your world???\n"); + } + + TEST_EXIT(count==n_monomials)("There must be an error!\n"); + + // Setting matrix of monomials. + WorldVector<int> sum; + + for (i=0; i<n_monomials; i++) + for (j=i; j<n_monomials; j++) + { + // Computing exponent vector of monomial. + sum = exponents[i] + exponents[j]; + (*matrix_fcts)[i][j] = NEW Monomial(sum); + } + + return n_monomials; +} + +void Recovery::compute_integrals(DOFVector<double> *uh, ElInfo *elInfo, + RecoveryStructure *rec_struct, + AbstractFunction<double, WorldVector<double> > *f_vec, + AbstractFunction<double, double> *f_scal, + DOFVector<double> *aux_vec) +{ + FUNCNAME("Recovery::compute_integrals"); + + TEST_EXIT(!(f_vec && f_scal))("Only one diffusion function, please!\n"); + + int i, j, k; + double sum; + WorldVector<double> vec_sum; + + Quadrature *quad; + int n_points; + WorldVector<double> quad_pts; // For world coordinates of quadrature points. + + int deg_f = 0; + if (f_vec) + deg_f = f_vec->getDegree(); + if (f_scal) + deg_f = f_scal->getDegree(); + + if (gradient) + deg_f += feSpace->getBasisFcts()->getDegree() - 1; + else + deg_f += feSpace->getBasisFcts()->getDegree(); + + for (i=0; i<n_monomials; i++) + { + // Computing contributions to system matrix. + for (j=i; j<n_monomials; j++) + { + sum = 0.0; + quad = Quadrature::provideQuadrature(Global::getGeo(WORLD), + (*matrix_fcts)[i][j]->getDegree()); + n_points = quad->getNumPoints(); + + for (k=0; k<n_points; k++) + { + elInfo->coordToWorld(quad->getLambda(k), &quad_pts); + sum += quad->getWeight(k) * + (*(*matrix_fcts)[i][j])(quad_pts, *rec_struct->coords); + } + (*(rec_struct->A))[i][j] += sum * elInfo->getDet(); + } + + quad = Quadrature:: + provideQuadrature(Global::getGeo(WORLD), + (*matrix_fcts)[0][i]->getDegree() + deg_f); + n_points = quad->getNumPoints(); + + double *uhAtQP = GET_MEMORY(double, n_points); + + // Computing contributions to right hand side. + if (gradient) // For gradient recovery. + { + double fAtQP = 1.0; + if (f_scal) + { + if (aux_vec) + aux_vec->getVecAtQPs(elInfo, quad, NULL, uhAtQP); + else + uh->getVecAtQPs(elInfo, quad, NULL, uhAtQP); + } + + // Get gradient at quadrature points + WorldVector<double> *grdAtQP = NEW WorldVector<double>[n_points]; + uh->getGrdAtQPs(elInfo, quad, NULL, grdAtQP); + vec_sum = 0.0; + for (k=0; k<n_points; k++) + { + elInfo->coordToWorld(quad->getLambda(k), &quad_pts); + if (f_vec) + fAtQP = (*f_vec)(quad_pts); + if (f_scal) + fAtQP = (*f_scal)(uhAtQP[k]); + + vec_sum = vec_sum + grdAtQP[k] * fAtQP * quad->getWeight(k) + * (*(*matrix_fcts)[0][i])(quad_pts, *rec_struct->coords); + } + (*rec_struct->rec_grdUh)[i] = (*rec_struct->rec_grdUh)[i] + + vec_sum * elInfo->getDet(); + + DELETE [] grdAtQP; + } + else // For recovery of DOFVector. + { + // Get uh at quadrature points + uh->getVecAtQPs(elInfo, quad, NULL, uhAtQP); + sum = 0.0; + for (k=0; k<n_points; k++) + { + elInfo->coordToWorld(quad->getLambda(k), &quad_pts); + sum += uhAtQP[k] * quad->getWeight(k) + * (*(*matrix_fcts)[0][i])(quad_pts, *rec_struct->coords); + } + (*rec_struct->rec_uh)[i] += sum * elInfo->getDet(); + } + FREE_MEMORY(uhAtQP, double, n_points); + } + + return; +} + +void Recovery::compute_interior_sums(DOFVector<double> *uh, ElInfo *elInfo, + RecoveryStructure *rec_struct, Quadrature *quad, + AbstractFunction<double, WorldVector<double> > *f_vec, + AbstractFunction<double, double> *f_scal, + DOFVector<double> *aux_vec) +{ + FUNCNAME("Recovery::compute_sums"); + + TEST_EXIT(gradient)("SPR of solution need computing node sums.\n"); + + TEST_EXIT(!(f_vec && f_scal))("Only one diffusion function, please!\n"); + + int i, j, k; + double sum; + WorldVector<double> vec_sum; + + int n_points = quad->getNumPoints(); + WorldVector<double> quad_pts; // For world coordinates of quadrature points. + + double *uhAtQP = GET_MEMORY(double, n_points); + WorldVector<double> *grdAtQP = NEW WorldVector<double>[n_points]; + + for (i=0; i<n_monomials; i++) + { + // Computing contributions to system matrix. + for (j=i; j<n_monomials; j++) + { + sum = 0.0; + for (k=0; k<n_points; k++) + { + elInfo->coordToWorld(quad->getLambda(k), &quad_pts); + sum += (*(*matrix_fcts)[i][j])(quad_pts, *rec_struct->coords); + } + (*(rec_struct->A))[i][j] += sum; + } + + // Computing contributions to right hand side. + double fAtQP = 1.0; + if (f_scal) + { + if (aux_vec) + aux_vec->getVecAtQPs(elInfo, quad, NULL, uhAtQP); + else + uh->getVecAtQPs(elInfo, quad, NULL, uhAtQP); + } + + // Get gradient at quadrature points + uh->getGrdAtQPs(elInfo, quad, NULL, grdAtQP); + vec_sum = 0.0; + for (k=0; k<n_points; k++) + { + elInfo->coordToWorld(quad->getLambda(k), &quad_pts); + if (f_vec) + fAtQP = (*f_vec)(quad_pts); + if (f_scal) + fAtQP = (*f_scal)(uhAtQP[k]); + + vec_sum = vec_sum + grdAtQP[k] * fAtQP + * (*(*matrix_fcts)[0][i])(quad_pts, *rec_struct->coords); + } + (*rec_struct->rec_grdUh)[i] = (*rec_struct->rec_grdUh)[i] + vec_sum; + } + + FREE_MEMORY(uhAtQP, double, n_points); + DELETE [] grdAtQP; + + return; +} + +void Recovery::compute_node_sums(DOFVector<double> *uh, ElInfo *elInfo, + RecoveryStructure *rec_struct, DimVec<int> preDOFs, + int n_vertices, int n_edges, int n_faces) +{ + FUNCNAME("Recovery::compute_sums"); + + TEST_EXIT(!gradient) + ("SPR of flux or gradient need computing interior sums\n"); + + TEST_EXIT(feSpace->getMesh()->getDim()==1) + ("At the moment only for linear finite elements.\n"); + + int i, j, l; + + WorldVector<double> node; // For world coordinates at nodes. + + const DegreeOfFreedom **dof = elInfo->getElement()->getDOF(); + const double *uh_loc = uh->getLocalVector(elInfo->getElement(), NULL); + + for (l=0; l<n_vertices; l++) + { + // Computing contributions of vertex nodes + if (rec_struct->neighbors->insert(dof[l][preDOFs[VERTEX]]).second) + { + node = elInfo->getCoord(l); + for (i=0; i<n_monomials; i++) + { + // Computing contributions to system matrix. + for (j=i; j<n_monomials; j++) + (*(rec_struct->A))[i][j] += (*(*matrix_fcts)[i][j])(node, + *rec_struct->coords); + + // Computing contributions to right hand side. + (*rec_struct->rec_uh)[i] += uh_loc[l] + * (*(*matrix_fcts)[0][i])(node, *rec_struct->coords); + } + } + } + + return; +} + +void Recovery::compute_sums_linear(DOFVector<double> *uh, ElInfo *elInfo, + RecoveryStructure *rec_struct, + int vertex, DimVec<int> preDOFs, + int n_vertices) +{ + FUNCNAME("Recovery::compute_sums_linear"); + + TEST_EXIT(!gradient) + ("SPR of flux or gradient need computing interior sums\n"); + + int i, j, l; + DegreeOfFreedom k; + + WorldVector<double> node; // For world coordinates at nodes. + + const DegreeOfFreedom **dof = elInfo->getElement()->getDOF(); + const double *uh_loc = uh->getLocalVector(elInfo->getElement(), NULL); + + for (l=0; l<n_vertices; l++) + { + // Computing contributions of vertex nodes + k = dof[l][preDOFs[VERTEX]]; + if (rec_struct->neighbors->insert(k).second) + { + node = elInfo->getCoord(l); + for (i=0; i<n_monomials; i++) + { + // Computing contributions to system matrix. + for (j=i; j<n_monomials; j++) + (*(rec_struct->A))[i][j] += (*(*matrix_fcts)[i][j])(node, + *rec_struct->coords); + + // Computing contributions to right hand side. + (*rec_struct->rec_uh)[i] += uh_loc[l] + * (*(*matrix_fcts)[0][i])(node, *rec_struct->coords); + } + } + } + + if (vertex>1) + if (elInfo->getNeighbour(vertex)) + { + int oppVertex = elInfo->getOppVertex(vertex); + k = elInfo->getNeighbour(vertex)->getDOF(oppVertex)[preDOFs[VERTEX]]; + + if (rec_struct->neighbors->insert(k).second) + { + node = elInfo->getOppCoord(vertex); + for (i=0; i<n_monomials; i++) + { + // Computing contributions to system matrix. + for (j=i; j<n_monomials; j++) + (*(rec_struct->A))[i][j] += (*(*matrix_fcts)[i][j])(node, + *rec_struct->coords); + + // Computing contributions to right hand side. + (*rec_struct->rec_uh)[i] += (*uh)[k] + * (*(*matrix_fcts)[0][i])(node, *rec_struct->coords); + } + } + } + + return; +} + +void Recovery::fill_struct_vec(DOFVector<double> *uh, + AbstractFunction<double, WorldVector<double> > *f_vec, + AbstractFunction<double, double> *f_scal, + DOFVector<double> *aux_vec) +{ + FUNCNAME("Recovery::fill_struct_vec"); + + // Information on the mesh. + Mesh *mesh = feSpace->getMesh(); + int dim = mesh->getDim(); + + // Geometric information. + int n_vertices = Global::getGeo(VERTEX, dim); + int n_edges = Global::getGeo(EDGE, dim); + int n_faces = Global::getGeo(FACE, dim); + + // Information concerning the finite element space. + const BasisFunction *basis_fcts = feSpace->getBasisFcts(); + DimVec<int> *nDOFs = basis_fcts->getNumberOfDOFs(); + + // Information from DOFAdmin. + const DOFAdmin *admin = feSpace->getAdmin(); + DimVec<int> preDOFs = admin->getNumberOfPreDOFs(); + + // Variables for storing temporary information. + DimVec<DegreeOfFreedom> interior_vertices(dim); + WorldVector<double> coordinates; + + // Variables for passing information to integration routines. + int degree = basis_fcts->getDegree(); + Quadrature *quad = NULL; + if (gradient && !method) + quad = Quadrature::provideQuadrature(Global::getGeo(WORLD), degree); + + DimVec<int> pre_dofs(dim, NO_INIT); + if (!gradient) + pre_dofs = uh->getFESpace()->getAdmin()->getNumberOfPreDOFs(); + + // Auxiliar variables. + int i, j, l, m, n_neighbors, n_count; + DegreeOfFreedom k; + + // Variables for traversing the mesh. + TraverseStack stack; + ElInfo *el_info; + Flag fill_flag; + + fill_flag = + Mesh::CALL_LEAF_EL | + Mesh::FILL_COORDS | + Mesh::FILL_BOUND | + Mesh::FILL_DET | + Mesh::FILL_GRD_LAMBDA; + + if (degree==2 && dim>1) + fill_flag |= Mesh::FILL_NEIGH | Mesh::FILL_OPP_COORDS; + + el_info = stack.traverseFirst(mesh, -1, fill_flag); + + while (el_info) // traversing the mesh. + { + const DegreeOfFreedom **dof = el_info->getElement()->getDOF(); + + n_neighbors = 0; // counting interior vertices of element + for (i=0; i<n_vertices; i++) + { + k = dof[i][preDOFs[VERTEX]]; + if (el_info->getBoundary(VERTEX, i) == INTERIOR) + interior_vertices[n_neighbors++] = k; + } + + TEST_EXIT(n_neighbors) + ("Each element should have a least one interior vertex!\n"); + + for (i=0; i<n_vertices; i++) // Handling nodes on vertices. + { + k = dof[i][preDOFs[VERTEX]]; + + // Setting world coordinates of node. + if (!(*struct_vec)[k].coords) + { + (*struct_vec)[k].coords = NEW WorldVector<double>; + *(*struct_vec)[k].coords = el_info->getCoord(i); + } + + if (el_info->getBoundary(VERTEX, i) == INTERIOR) + { + // Allocating memory for matrix and right hand side. + if (!(*struct_vec)[k].A) + { + (*struct_vec)[k].A = NEW Matrix<double>(n_monomials, n_monomials); + *(*struct_vec)[k].A = 0.0; + + if (gradient) + { + (*struct_vec)[k].rec_grdUh + = NEW Vector<WorldVector<double> >(n_monomials); + for (j=0; j<n_monomials; j++) + (*(*struct_vec)[k].rec_grdUh)[j] = 0.0; + } + else + { + (*struct_vec)[k].rec_uh = NEW Vector<double>(n_monomials); + *(*struct_vec)[k].rec_uh = 0.0; + } + } + + // Computing the integrals. + if (method) + compute_integrals(uh, el_info, &(*struct_vec)[k], + f_vec, f_scal, aux_vec); + else if (gradient) + compute_interior_sums(uh, el_info, &(*struct_vec)[k], quad, + f_vec, f_scal, aux_vec); + else + { + if (!(*struct_vec)[k].neighbors) + (*struct_vec)[k].neighbors = NEW ::std::set<DegreeOfFreedom>; + + if (degree==2 && dim>1) + compute_sums_linear(uh, el_info, &(*struct_vec)[k], + i, pre_dofs, n_vertices); + else + compute_node_sums(uh, el_info, &(*struct_vec)[k], + pre_dofs, n_vertices, n_edges, n_faces); + } + } + else // Setting list of adjacent interior vertices. + { + if (!(*struct_vec)[k].neighbors) + (*struct_vec)[k].neighbors = NEW ::std::set<DegreeOfFreedom>; + + for (j=0; j<n_neighbors; j++) + (*struct_vec)[k].neighbors->insert(interior_vertices[j]); + } + } + + n_count = n_vertices; + + if (dim > 1) // Handling nodes on edges. + for (i=0; i<n_edges; i++) + for (j=0; j<(*nDOFs)[EDGE]; j++) + { + k = dof[n_vertices+i][preDOFs[EDGE]+j]; + + if (!(*struct_vec)[k].coords) + { + // Setting world coordinates of node. + el_info->coordToWorld(*basis_fcts->getCoords(n_count), + &coordinates); + (*struct_vec)[k].coords = NEW WorldVector<double>; + *(*struct_vec)[k].coords = coordinates; + + // Setting list of adjacent interior vertices. + (*struct_vec)[k].neighbors = NEW ::std::set<DegreeOfFreedom>; + + if (el_info->getBoundary(EDGE, i) == INTERIOR) + for (m=0; m<2; m++) + { + l = Global::getReferenceElement(dim)->getVertexOfEdge(i, m); + if (el_info->getBoundary(VERTEX, l) == INTERIOR) + (*struct_vec)[k].neighbors->insert(dof[l][preDOFs[VERTEX]]); + } + else + for (m=0; m<n_neighbors; m++) + (*struct_vec)[k].neighbors->insert(interior_vertices[m]); + } + + n_count++; + } + + if (dim == 3) // Handling nodes on faces. + for (i=0; i<n_faces; i++) + for (j=0; j<(*nDOFs)[FACE]; j++) + { + k = dof[n_vertices+n_edges+i][preDOFs[FACE]+j]; + + if (!(*struct_vec)[k].coords) + { + // Setting world coordinates of node. + el_info->coordToWorld(*basis_fcts->getCoords(n_count), + &coordinates); + (*struct_vec)[k].coords = NEW WorldVector<double>; + *(*struct_vec)[k].coords = coordinates; + + // Setting list of adjacent interior vertices. + (*struct_vec)[k].neighbors = NEW ::std::set<DegreeOfFreedom>; + + if (el_info->getBoundary(FACE, i) == INTERIOR) + for (m=0; m<3; m++) + { + l = Global::getReferenceElement(dim) + ->getVertexOfPosition(FACE, i, m); + if (el_info->getBoundary(VERTEX, l) == INTERIOR) + (*struct_vec)[k].neighbors->insert(dof[l][preDOFs[VERTEX]]); + } + else + for (m=0; m<n_neighbors; m++) + (*struct_vec)[k].neighbors->insert(interior_vertices[m]); + } + + n_count++; + } + + if ((*nDOFs)[CENTER]) // Handling nodes on center of element. + for (j=0; j<(*nDOFs)[CENTER]; j++) + { + k = dof[n_vertices+n_edges+n_faces][preDOFs[CENTER]+j]; + + // Setting world coordinates of node. + el_info->coordToWorld(*basis_fcts->getCoords(n_count), &coordinates); + (*struct_vec)[k].coords = NEW WorldVector<double>; + *(*struct_vec)[k].coords = coordinates; + + // Setting list of adjacent interior vertices. + (*struct_vec)[k].neighbors = NEW ::std::set<DegreeOfFreedom>; + + for (m=0; m<n_neighbors; m++) + (*struct_vec)[k].neighbors->insert(interior_vertices[m]); + + n_count++; + } + + el_info = stack.traverseNext(el_info); + } + + return; +} + +void Recovery::recoveryUh(DOFVector<double> *uh, DOFVector<double> &rec_vec) +{ + FUNCNAME("Recovery::recoveryUh"); + + clear(); + + gradient = false; + + const FiniteElemSpace *fe_space = rec_vec.getFESpace(); + set_feSpace(fe_space); // Setting feSpace. + set_exponents(feSpace->getBasisFcts()->getDegree()); // Setting exponents. + fill_struct_vec(uh); // Filling vector of recovery structures. + + DOFVector<RecoveryStructure>::Iterator SV_it(struct_vec, USED_DOFS); + + // Solving local systems. + for (SV_it.reset(); !SV_it.end(); ++SV_it) + { + if ((*SV_it).A) + { + TEST(Cholesky::solve((*SV_it).A, (*SV_it).rec_uh, (*SV_it).rec_uh)) + ("There must be an error, matrix is not positive definite.\n"); + } + } + + // define result vector + DOFVector<double> *result = &rec_vec; + + result->set(0.0); + + DOFVector<double>::Iterator result_it(result, USED_DOFS); + ::std::set<DegreeOfFreedom>::const_iterator setIterator; + int i; + + for (SV_it.reset(), result_it.reset(); !result_it.end(); + ++SV_it, ++result_it) + { + if ((*SV_it).rec_uh) + *result_it = (*(*SV_it).rec_uh)[0]; + else + { + if ((*SV_it).neighbors) { + for (setIterator = (*SV_it).neighbors->begin(); + setIterator != (*SV_it).neighbors->end(); + ++setIterator) + { + for (i=0; i<n_monomials; i++) + *result_it = *result_it + (*(*struct_vec)[*setIterator].rec_uh)[i] * + (*(*matrix_fcts)[0][i])(*(*SV_it).coords, + *(*struct_vec)[*setIterator].coords); + } + *result_it /= (*SV_it).neighbors->size(); + } + else + *result_it=0.0; + } + } + + return; +} + +DOFVector<double>* +Recovery::recoveryUh(DOFVector<double> *uh, const FiniteElemSpace *fe_space) +{ + FUNCNAME("Recovery::recoveryUh"); + + clear(); + + gradient = false; + + set_feSpace(fe_space); // Setting feSpace. + set_exponents(feSpace->getBasisFcts()->getDegree()); // Setting exponents. + fill_struct_vec(uh); // Filling vector of recovery structures. + + DOFVector<RecoveryStructure>::Iterator SV_it(struct_vec, USED_DOFS); + + // Solving local systems. + for (SV_it.reset(); !SV_it.end(); ++SV_it) + { + if ((*SV_it).A) + { + TEST(Cholesky::solve((*SV_it).A, (*SV_it).rec_uh, (*SV_it).rec_uh)) + ("There must be an error, matrix is not positive definite.\n"); + } + } + + // define result vector + static DOFVector<double> *vec = NULL; + DOFVector<double> *result = NULL; + + // Allocate memory for result vector + if (vec && vec->getFESpace() != feSpace) + { + DELETE vec; + vec = NULL; + } + if (!vec) + vec = NEW DOFVector<double>(feSpace, "gradient"); + result = vec; + + result->set(0.0); + + DOFVector<double>::Iterator result_it(result, USED_DOFS); + ::std::set<DegreeOfFreedom>::const_iterator setIterator; + int i; + + for (SV_it.reset(), result_it.reset(); !result_it.end(); + ++SV_it, ++result_it) + { + if ((*SV_it).rec_uh) + *result_it = (*(*SV_it).rec_uh)[0]; + else + { + if ((*SV_it).neighbors) { + for (setIterator = (*SV_it).neighbors->begin(); + setIterator != (*SV_it).neighbors->end(); + ++setIterator) + { + for (i=0; i<n_monomials; i++) + *result_it = *result_it + (*(*struct_vec)[*setIterator].rec_uh)[i] * + (*(*matrix_fcts)[0][i])(*(*SV_it).coords, + *(*struct_vec)[*setIterator].coords); + } + *result_it /= (*SV_it).neighbors->size(); + } + else + *result_it=0.0; + } + } + + return result; +} + +DOFVector<WorldVector<double> >* +Recovery::recovery(DOFVector<double> *uh, const FiniteElemSpace *fe_space, + AbstractFunction<double, WorldVector<double> > *f_vec, + AbstractFunction<double, double> *f_scal, + DOFVector<double> *aux_vec) +{ + FUNCNAME("Recovery::recovery"); + + clear(); + + gradient = true; + + set_feSpace(fe_space); // Setting feSpace. + set_exponents(feSpace->getBasisFcts()->getDegree()); // Setting exponents. + fill_struct_vec(uh, f_vec, f_scal, aux_vec); // Filling vec. of rec. struct. + + DOFVector<RecoveryStructure>::Iterator SV_it(struct_vec, USED_DOFS); + + // Solving local systems. + for (SV_it.reset(); !SV_it.end(); ++SV_it) + { + if ((*SV_it).A) + TEST_EXIT(Cholesky::solve((*SV_it).A, (*SV_it).rec_grdUh, + (*SV_it).rec_grdUh)) + ("There must be some error, matrix is not positive definite.\n"); + } + + // define result vector + static DOFVector<WorldVector<double> > *vec = NULL; + DOFVector<WorldVector<double> > *result = NULL; + + // Allocate memory for result vector + if (vec && vec->getFESpace() != feSpace) + { + DELETE vec; + vec = NULL; + } + if (!vec) + vec = NEW DOFVector<WorldVector<double> >(feSpace, "gradient"); + result = vec; + + result->set(WorldVector<double>(DEFAULT_VALUE, 0.0)); + + DOFVector<WorldVector<double> >::Iterator grdIt(result, USED_DOFS); + ::std::set<DegreeOfFreedom>::const_iterator setIterator; + int i; + + for (SV_it.reset(), grdIt.reset(); !grdIt.end(); ++SV_it, ++grdIt) + { + if ((*SV_it).rec_grdUh) + *grdIt = (*(*SV_it).rec_grdUh)[0]; + else + { + for (setIterator = (*SV_it).neighbors->begin(); + setIterator != (*SV_it).neighbors->end(); + ++setIterator) + { + for (i=0; i<n_monomials; i++) + *grdIt = *grdIt + (*(*struct_vec)[*setIterator].rec_grdUh)[i] * + (*(*matrix_fcts)[0][i])(*(*SV_it).coords, + *(*struct_vec)[*setIterator].coords); + } + *grdIt = *grdIt * (1.0/(*SV_it).neighbors->size()); + } + } + + return result; +} + +DOFVector<WorldVector<double> >* +Recovery::recovery(DOFVector<double> *uh, + AbstractFunction<double, WorldVector<double> > *f_vec, + AbstractFunction<double, double> *f_scal, + DOFVector<double> *aux_vec) +{ + FUNCNAME("Recovery::simpleAveraging"); + + TEST_EXIT(!(f_vec && f_scal))("Only one diffusion function, please!\n"); + + const FiniteElemSpace *fe_space = uh->getFESpace(); + + // define result vector + static DOFVector<WorldVector<double> > *vec = NULL; + DOFVector<WorldVector<double> > *result = NULL; + + // Allocate memory for result vector + if (vec && vec->getFESpace() != fe_space) + { + DELETE vec; + vec = NULL; + } + if (!vec) + vec = NEW DOFVector<WorldVector<double> >(fe_space, "gradient"); + result = vec; + + result->set(WorldVector<double>(DEFAULT_VALUE, 0.0)); + + DOFVector<double> volume(fe_space, "volume"); + volume.set(0.0); + + int i; + + Mesh *mesh = fe_space->getMesh(); + int dim = mesh->getDim(); + + const BasisFunction *basFcts = fe_space->getBasisFcts(); + DOFAdmin *admin = fe_space->getAdmin(); + + int numPreDOFs = admin->getNumberOfPreDOFs(0); + + DimVec<double> bary(dim, DEFAULT_VALUE, (1.0 / (dim + 1.0))); + WorldVector<double> barycenter; // For world coordinates at barycenter + + // traverse mesh + TraverseStack stack; + + Flag fillFlag = + Mesh::CALL_LEAF_EL | Mesh::FILL_DET | Mesh::FILL_GRD_LAMBDA | Mesh::FILL_COORDS; + + ElInfo *elInfo = stack.traverseFirst(mesh, -1, fillFlag); + + while (elInfo) + { + double det = elInfo->getDet(); + const DegreeOfFreedom **dof = elInfo->getElement()->getDOF(); + const double *localUh = uh->getLocalVector(elInfo->getElement(), NULL); + const DimVec<WorldVector<double> > &grdLambda = elInfo->getGrdLambda(); + const WorldVector<double> &grd = basFcts->evalGrdUh(bary, + grdLambda, + localUh, + NULL); + + double fAtBary = 1.0; + + if (f_vec) + { + elInfo->coordToWorld(bary, &barycenter); + fAtBary = (*f_vec)(barycenter); + } + + if (f_scal) + { + if (aux_vec) + localUh = aux_vec->getLocalVector(elInfo->getElement(), NULL); + + fAtBary = basFcts->evalUh(bary, localUh); + fAtBary = (*f_scal)(fAtBary); + } + + for (i=0; i<dim+1; i++) + { + DegreeOfFreedom dofIndex = dof[i][numPreDOFs]; + (*result)[dofIndex] += grd * fAtBary * det; + volume[dofIndex] += det; + } + + elInfo = stack.traverseNext(elInfo); + } + + DOFVector<double>::Iterator volIt(&volume, USED_DOFS); + DOFVector<WorldVector<double> >::Iterator grdIt(result, USED_DOFS); + + for (volIt.reset(), grdIt.reset(); !volIt.end(); ++volIt, ++grdIt) + *grdIt *= 1.0/(*volIt); + + return result; +} + + +void Recovery::test(DOFVector<double> *uh, const FiniteElemSpace *fe_space) +{ + FUNCNAME("Recovery::test"); + + clear(); + + set_feSpace(fe_space); // Setting feSpace. + set_exponents(feSpace->getBasisFcts()->getDegree()); // Setting exponents. + fill_struct_vec(uh); // Filling vector of recovery structures. + + DOFVector<RecoveryStructure>::Iterator LM_iterator(struct_vec, USED_DOFS); + int position; + WorldVector<double> coord; + + // for every DOFs + for (LM_iterator.reset(); !LM_iterator.end(); ++LM_iterator) + { + position = LM_iterator.getDOFIndex(); + MSG("Node: "); + ::std::cout << position << ::std::endl; + (*struct_vec)[position].print(); + } + + return; +} diff --git a/AMDiS/src/Recovery.h b/AMDiS/src/Recovery.h new file mode 100644 index 0000000000000000000000000000000000000000..919beb9582307027d5e3085cbd5fde93c269450d --- /dev/null +++ b/AMDiS/src/Recovery.h @@ -0,0 +1,279 @@ +// ============================================================================ +// == == +// == AMDiS - Adaptive multidimensional simulations == +// == == +// ============================================================================ +// == == +// == crystal growth group == +// == == +// == Stiftung caesar == +// == Ludwig-Erhard-Allee 2 == +// == 53175 Bonn == +// == germany == +// == == +// ============================================================================ +// == == +// == http://www.caesar.de/cg/AMDiS == +// == == +// ============================================================================ + +/** \file Recovery.h */ + +#ifndef AMDIS_RECOVERY_H +#define AMDIS_RECOVERY_H + +#include "set" +#include "Lagrange.h" +#include "Traverse.h" +#include "DOFVector.h" +#include "Cholesky.h" + +using namespace std; +using namespace AMDiS; + +// ============================================================================ +// ===== class Monomial ======================================================= +// ============================================================================ + +class Monomial : public +BinaryAbstractFunction<double, WorldVector<double>, WorldVector<double> > +{ +public: + + // Constructor. + Monomial(WorldVector<int> expon) + : BinaryAbstractFunction<double, WorldVector<double>, WorldVector<double> >(), + exponent(expon) + { + degree_ = exponent[0]; + for (int i=1; i<exponent.size(); i++) + degree_ += exponent[i]; + }; + + virtual ~Monomial() {}; + + const double& operator()(const WorldVector<double>& y, + const WorldVector<double>& z) const + { + static double result; + result = pow(y[0]-z[0], exponent[0]); + for (int i=1; i<exponent.size(); i++) + result *= pow(y[i]-z[i], exponent[i]); + + return result; + }; + +private: + WorldVector<int> exponent; +}; + + +// ============================================================================ +// ===== class RecoveryStructure ============================================== +// ============================================================================ + +class RecoveryStructure +{ +public: // construtor, destructor + MEMORY_MANAGED(RecoveryStructure); + + // constructor + RecoveryStructure() : + coords(NULL), + A(NULL), rec_uh(NULL), rec_grdUh(NULL), + neighbors(NULL) + {}; + + // Destructor? + ~RecoveryStructure() + { + clear(); + }; + + RecoveryStructure(const RecoveryStructure& rhs) : + coords(NULL), + A(NULL), rec_uh(NULL), rec_grdUh(NULL), + neighbors(NULL) { + *this=rhs; + }; + + RecoveryStructure& operator=(const RecoveryStructure& rhs); + + + // Clear recovery structure + inline void clear() + { + if (coords) + { + DELETE coords; + coords = NULL; + } + + if (A) + { + DELETE A; + A = NULL; + } + + if (rec_uh) + { + DELETE rec_uh; + rec_uh = NULL; + } + + if (rec_grdUh) + { + DELETE rec_grdUh; + rec_grdUh = NULL; + } + + if (neighbors) + { + DELETE neighbors; + neighbors = NULL; + } + }; + + // Prints recovery structure (for test purposes) + void print(); + + +private: // members + + // World coordinates of the node. + WorldVector<double> *coords; + + // For interior nodes. + Matrix<double> *A; + Vector<double> *rec_uh; + Vector<WorldVector<double> > *rec_grdUh; + + // For boundary, edge, face, of center nodes: interior neighbors nodes. + // For interior vertices in uh-recovery: neighbors nodes. + ::std::set<DegreeOfFreedom> *neighbors; + + friend class Recovery; +}; + + +// ============================================================================ +// ===== class Recovery ======================================================= +// ============================================================================ + +/** + * \ingroup Recovery + * + * \brief + * Recovering the gradient of a finite element function. + */ + +class Recovery +{ +public: + MEMORY_MANAGED(Recovery); + + // constructor + Recovery(int norm, int method_) + : struct_vec(NULL), feSpace(NULL), matrix_fcts(NULL), method(method_) + { + n_monomials = 0; + gradient = (norm == H1_NORM); + }; + + // Destructor? + + // Clear vector of recovery structures + inline void clear() + { + if (struct_vec) + { + DOFVector<RecoveryStructure>::Iterator SV_it(struct_vec, ALL_DOFS); + for (SV_it.reset(); !SV_it.end(); ++SV_it) + (*SV_it).clear(); + } + }; + + /** \brief + * Recovers flux or gradient of given DOFVector. + */ + DOFVector<WorldVector<double> >* + recovery(DOFVector<double> *uh, + AbstractFunction<double, WorldVector<double> > *f_vec = NULL, + AbstractFunction<double, double> *f_scal = NULL, + DOFVector<double> *aux_vec = NULL); + + DOFVector<WorldVector<double> >* + recovery(DOFVector<double> *uh, const FiniteElemSpace *fe_space, + AbstractFunction<double, WorldVector<double> > *f_vec = NULL, + AbstractFunction<double, double> *f_scal = NULL, + DOFVector<double> *aux_vec = NULL); + + /** \brief + * Computes higher order approximation of given DOFVector. + */ + void recoveryUh(DOFVector<double> *uh, DOFVector<double> &rec_vec); + DOFVector<double>* recoveryUh(DOFVector<double> *uh, + const FiniteElemSpace *fe_space); + + // for test purposes + void test(DOFVector<double> *uh, const FiniteElemSpace *fe_space); + + +private: // Private functions. + + // Defines a new finite element space if necessary. + void set_feSpace(const FiniteElemSpace *fe_space); + + // Fills vector of exponents of the monomials. + int set_exponents(int degree); + + // Fills vector of recovery structures. + void fill_struct_vec(DOFVector<double> *uh, + AbstractFunction<double, WorldVector<double> > *f_vec = NULL, + AbstractFunction<double, double> *f = NULL, + DOFVector<double> *aux_vec = NULL); + + // Compute integrals defining matrix and vector on element + // (continuous ZZ-recovery) + void compute_integrals(DOFVector<double> *uh, ElInfo *elInfo, + RecoveryStructure *rec_struct, + AbstractFunction<double, WorldVector<double> > *f_vec = NULL, + AbstractFunction<double, double> *f_scal = NULL, + DOFVector<double> *aux_vec = NULL); + + // Compute integrals defining matrix and vector on element + // (superconvergent patch recovery) + void compute_interior_sums(DOFVector<double> *uh, ElInfo *elInfo, + RecoveryStructure *rec_struct, Quadrature *quad, + AbstractFunction<double, WorldVector<double> > *f_vec = NULL, + AbstractFunction<double, double> *f_scal = NULL, + DOFVector<double> *aux_vec = NULL); + + void compute_node_sums(DOFVector<double> *uh, ElInfo *elInfo, + RecoveryStructure *rec_struct, DimVec<int> preDOFs, + int n_vertices, int n_edges, int n_faces); + + void compute_sums_linear(DOFVector<double> *uh, ElInfo *elInfo, + RecoveryStructure *rec_struct, + int vertex, DimVec<int> preDOFs, int n_vertices); + +private: // Private members. + + // Structure storing needed information. + DOFVector<RecoveryStructure> *struct_vec; + + const FiniteElemSpace *feSpace; // Working finite element space. + + int n_monomials; // Number of monomials. + Vector<WorldVector<int> > exponents; // Exponents of the monomials. + Matrix<Monomial*> *matrix_fcts; // Functions for system matrix. + + bool gradient; // True if gradient or flux should be recovered; + // false if seeking for higher order approximation of uh. + + int method; // 0: superconvergent patch recovery (discrete ZZ) + // 1: local L2-averaging (continuous ZZ-recovery) + // 2: simple averaging +}; + +#endif diff --git a/AMDiS/src/RecoveryEstimator.cc b/AMDiS/src/RecoveryEstimator.cc new file mode 100644 index 0000000000000000000000000000000000000000..1ccc1d3a2751bd8860ffe0e2dc9b914c4a2af1f4 --- /dev/null +++ b/AMDiS/src/RecoveryEstimator.cc @@ -0,0 +1,222 @@ +#include "RecoveryEstimator.h" +#include "Parameters.h" + +RecoveryEstimator::RecoveryEstimator(::std::string name, DOFVector<double> *uh, int r) + : Estimator(name, r), + uh_(uh), + relative_(0), + C(1.0), + method(0), + feSpace(NULL), + f_vec(NULL), + f_scal(NULL), + aux_vec(NULL), + rec_struct(NULL) +{ + FUNCNAME("RecoveryEstimator::constructor()"); + + GET_PARAMETER(0, name + "->rec method", "%d", &method); + GET_PARAMETER(0, name + "->rel error", "%d", &relative_); + + GET_PARAMETER(0, name + "->C", "%f", &C); + C = C > 1e-25 ? sqr(C) : 1.0; + + if (norm == H1_NORM) { + feSpace = uh->getFESpace(); + degree = feSpace->getBasisFcts()->getDegree(); + + if ((degree <= 2) && (C != 1.0)) { + WARNING("Recovery estimators in the H1_NORM usually very good for linear and quadratic finite element; normally you do not need to overwrite the default value of C\n"); + WAIT; + } + } + else { + degree = uh->getFESpace()->getBasisFcts()->getDegree() + 1; + + feSpace = FiniteElemSpace::provideFESpace(NULL, + Lagrange::getLagrange(uh->getFESpace()->getMesh()->getDim(), degree), + uh->getFESpace()->getMesh(), + name + "->feSpace"); + + + if (method == 2) { + ERROR("Simple averaging only for the H1_NORM; using SPR instead\n"); + WAIT; + method = 0; + } + } + + if ((method == 2) && (degree !=1)) { + ERROR("Simple averaging only for linear elements; using SPR instead\n"); + WAIT; + method = 0; + } + + rec_struct = NEW Recovery(norm, method); +} + +double RecoveryEstimator::estimate(double timestep) +{ + FUNCNAME("RecoveryEstimator::estimate()"); + + const BasisFunction *basFcts = uh_->getFESpace()->getBasisFcts(); + Mesh *mesh = uh_->getFESpace()->getMesh(); + int dim = mesh->getDim(); + int dow = Global::getGeo(WORLD); + double h1Norm2 = 0.0; + Flag flag = + Mesh::CALL_LEAF_EL | Mesh::FILL_COORDS | Mesh::FILL_DET | Mesh::FILL_GRD_LAMBDA; + TraverseStack stack; + ElInfo *elInfo = NULL; + + int i, j; + double det, estEl, errEl, normEl; + Element *el = NULL; + + if (norm == H1_NORM) // sets recovery gradient. + { + if (method == 2) + rec_grd = rec_struct->recovery(uh_, f_vec, f_scal, aux_vec); + else + rec_grd = rec_struct->recovery(uh_, feSpace, f_vec, f_scal, aux_vec); + rec_basFcts = rec_grd->getFESpace()->getBasisFcts(); + } + else // sets higher-order recovery solution. + { + rec_uh = rec_struct->recoveryUh(uh_, feSpace); + rec_basFcts = rec_uh->getFESpace()->getBasisFcts(); + } + + int deg = 2 * ::std::max(basFcts->getDegree(), + rec_basFcts->getDegree()); + Quadrature *quad = Quadrature::provideQuadrature(dim, deg); + int numPoints = quad->getNumPoints(); + + WorldVector<double> quad_pt; + WorldVector<double> *grdAtQP = NEW WorldVector<double>[numPoints]; + WorldVector<double> *recoveryGrdAtQP = NEW WorldVector<double>[numPoints]; + + double *uhAtQP = GET_MEMORY(double, numPoints); + double *recoveryUhAtQP = GET_MEMORY(double, numPoints); + + FastQuadrature *quadFast = + FastQuadrature::provideFastQuadrature(basFcts, *quad, + INIT_PHI | INIT_GRD_PHI); + FastQuadrature *rec_quadFast = + FastQuadrature::provideFastQuadrature(rec_basFcts, *quad, + INIT_PHI | INIT_GRD_PHI); + + // clear error indicators + elInfo = stack.traverseFirst(mesh, -1, Mesh::CALL_LEAF_EL); + while (elInfo) + { + elInfo->getElement()->setEstimation(0.0, row); + elInfo = stack.traverseNext(elInfo); + } + + // traverse mesh + est_sum = est_max = est_t_sum = 0.0; + + elInfo = stack.traverseFirst(mesh, -1, flag); + while (elInfo) + { + el = elInfo->getElement(); + det = elInfo->getDet(); + errEl = 0.0; + + if (norm == H1_NORM) + { + // get gradient and recovery gradient at quadrature points + uh_->getGrdAtQPs(elInfo, NULL, quadFast, grdAtQP); + rec_grd->getVecAtQPs(elInfo, NULL, rec_quadFast, recoveryGrdAtQP); + if (f_scal) + { + if (aux_vec) + aux_vec->getVecAtQPs(elInfo, NULL, quadFast, uhAtQP); + else + uh_->getVecAtQPs(elInfo, NULL, quadFast, uhAtQP); + } + + // calc h1 error + for (i=0; i<numPoints; i++) + { + double err2 = 0.0; + double fAtQP = 1.0; + if (f_scal) + fAtQP = (*f_scal)(uhAtQP[i]); + if (f_vec) + { + elInfo->coordToWorld(quad->getLambda(i), &quad_pt); + fAtQP = (*f_vec)(quad_pt); + } + + for (j=0; j<dow; j++) + err2 += sqr(recoveryGrdAtQP[i][j] - fAtQP * grdAtQP[i][j]); + errEl += quad->getWeight(i) * err2; + } + } + else + { + // get vector and recovery vector at quadrature points + uh_->getVecAtQPs(elInfo, NULL, quadFast, uhAtQP); + rec_uh->getVecAtQPs(elInfo, NULL, rec_quadFast, recoveryUhAtQP); + + // calc l2 error + for (i=0; i<numPoints; i++) + errEl += quad->getWeight(i) * sqr(recoveryUhAtQP[i] - uhAtQP[i]); + } + + estEl = C * det * errEl; + el->setEstimation(estEl, row); + est_sum += estEl; + est_max = ::std::max(est_max, estEl); + + if (relative_) + { + normEl = 0.0; + + if (norm == H1_NORM) + for (i=0; i<numPoints; i++) + { + double norm2 = 0.0; + for (j = 0; j < dow; j++) + norm2 += sqr(recoveryGrdAtQP[i][j]); + normEl += quad->getWeight(i) * norm2; + } + else + for (i=0; i<numPoints; i++) + normEl += quad->getWeight(i) * sqr(recoveryUhAtQP[i]); + + h1Norm2 += det * normEl; + } + + elInfo = stack.traverseNext(elInfo); + } + + // Computing relative errors + if (relative_) + { + elInfo = stack.traverseFirst(mesh, -1, Mesh::CALL_LEAF_EL); + while (elInfo) + { + estEl = elInfo->getElement()->getEstimation(row); + estEl /= h1Norm2; + elInfo->getElement()->setEstimation(estEl, row); + elInfo = stack.traverseNext(elInfo); + } + + est_max /= h1Norm2; + est_sum /= h1Norm2; + } + + est_sum = sqrt(est_sum); + + MSG("estimate = %.8e\n", est_sum); + + DELETE [] grdAtQP; + DELETE [] recoveryGrdAtQP; + FREE_MEMORY(uhAtQP, double, numPoints); + FREE_MEMORY(recoveryUhAtQP, double, numPoints); + + return(est_sum); +} diff --git a/AMDiS/src/RecoveryEstimator.h b/AMDiS/src/RecoveryEstimator.h new file mode 100644 index 0000000000000000000000000000000000000000..e662602ec9754ac00d903a85f8d3785567ae9baa --- /dev/null +++ b/AMDiS/src/RecoveryEstimator.h @@ -0,0 +1,194 @@ +// ============================================================================ +// == == +// == AMDiS - Adaptive multidimensional simulations == +// == == +// ============================================================================ +// == == +// == crystal growth group == +// == == +// == Stiftung caesar == +// == Ludwig-Erhard-Allee 2 == +// == 53175 Bonn == +// == germany == +// == == +// ============================================================================ +// == == +// == http://www.caesar.de/cg/AMDiS == +// == == +// ============================================================================ + +/** \file RecoveryEstimator.h */ + +#ifndef AMDIS_MYRECOVERYESTIMATOR_H +#define AMDIS_MYRECOVERYESTIMATOR_H + +#include "Estimator.h" +#include "Recovery.h" + +namespace AMDiS { + + // ============================================================================ + // ===== class RecoveryEstimator ============================================ + // ============================================================================ + + /** \brief + * Error estimator using the recovery gradient of the finite element solution. + */ + class RecoveryEstimator : public Estimator + { + public: + MEMORY_MANAGED(RecoveryEstimator); + + /** \brief + * Creator class. + */ + class Creator : public EstimatorCreator + { + public: + MEMORY_MANAGED(Creator); + + Creator() : EstimatorCreator(), uh(NULL) {}; + + virtual ~Creator() {}; + + inline void setSolution(DOFVector<double> *uh_) + { + uh = uh_; + }; + + /** \brief + * Returns a new Estimator object. + */ + Estimator* create() + { + return NEW RecoveryEstimator(name, uh, row); + }; + + protected: + DOFVector<double> *uh; + }; + + /** \brief + * constructor + */ + RecoveryEstimator(::std::string name, DOFVector<double> *uh, int r = -1); + + /** \brief + * destructor. + */ + virtual ~RecoveryEstimator() {}; + + /** \brief + * implements \ref Estimator::estimate(). + */ + virtual double estimate(double timestep = 0.0); + + + /*----- Setting functions -----*/ + + // Sets uh. + inline void setUh(DOFVector<double> *uh) + { + uh_ = uh; + }; + + // Sets f. + inline void setFct(AbstractFunction<double, WorldVector<double> > *fct) + { + f_vec = fct; + }; + + inline void setFct(AbstractFunction<double, double> *fct) + { + f_scal = fct; + }; + + // Sets auxiliar vector. + inline void setAuxVec(DOFVector<double> *uh) + { + aux_vec = uh; + }; + + + /*----- Getting functions -----*/ + + // Gets recovery gradient. + inline DOFVector<WorldVector<double> >* getRecGrd() + { + return rec_grd; + }; + + // Gets higher-order recovery solution. + inline DOFVector<double>* getRecUh() + { + return rec_uh; + }; + + + protected: // protected members + + /** \brief + * finite element solution + */ + DOFVector<double> *uh_; + + /** \brief + * absolute or relative error? + */ + int relative_; + + /** \brief + * constant for scaling the estimator + */ + double C; + + /** \brief + * recovery method + */ + int method; + + /** \brief + * Working finite element space + */ + const FiniteElemSpace *feSpace; + + /** \brief + * Degree of corresponding basic functions + */ + int degree; + + /** \brief + * Basis functions for recovery vector. + */ + const BasisFunction *rec_basFcts; + + /** \brief + * Recovery gradient + */ + DOFVector<WorldVector<double> > *rec_grd; + + /** \brief + * Higher-order recovery solution + */ + DOFVector<double> *rec_uh; + + /** \brief + * Diffusion coefficient (for flux recovery) + */ + AbstractFunction<double, WorldVector<double> > *f_vec; + AbstractFunction<double, double> *f_scal; + + /** \brief + * auxiliar vector + */ + DOFVector<double> *aux_vec; + + /** \brief + * Recovery structure. + */ + Recovery *rec_struct; + }; + +} + +#endif diff --git a/AMDiS/src/RefinementManager.cc b/AMDiS/src/RefinementManager.cc new file mode 100644 index 0000000000000000000000000000000000000000..1cec9c2e30fd514c7c728445c50c90ef9d083e57 --- /dev/null +++ b/AMDiS/src/RefinementManager.cc @@ -0,0 +1,119 @@ +#include "RefinementManager.h" +#include "Mesh.h" +#include "Traverse.h" +#include "ElInfo.h" +#include "DOFAdmin.h" +#include "AdaptStationary.h" +#include "AdaptInstationary.h" +#include "FixVec.h" +#include "RCNeighbourList.h" +#include "ProblemStatBase.h" +#include "PeriodicBC.h" + +namespace AMDiS { + + RefinementManager* RefinementManager::traversePtr = NULL; + bool RefinementManager::doMoreRecursiveRefine = false; + int RefinementManager::callRefineInterpol = 0; + + RCNeighbourList* RefinementManager3d::refList = NULL; + + int RefinementManager::globalMark = 0; + + int RefinementManager::globalRefineFct(ElInfo* elinfo) + { + FUNCNAME("RefineManager::globalRefineFct"); + + elinfo->getElement()->setMark(globalMark); + return 0; + } + + Flag RefinementManager::globalRefine(Mesh *aMesh, int mark) + { + FUNCNAME("RefinementManager::globalRefine()"); + + if(mark <= 0) return static_cast<Flag>(0); + globalMark = mark; + aMesh->traverse(-1, + Mesh::CALL_LEAF_EL | + Mesh::FILL_COORDS | + Mesh::FILL_BOUND, + globalRefineFct); + return refineMesh(aMesh); + } + + + + + Flag RefinementManager::refineMesh(Mesh *aMesh) + { + FUNCNAME("RefinementManager::refineMesh()"); + + mesh = aMesh; + + // if(mesh->getDim() == 3) { + // ::std::map<BoundaryType, PeriodicBC*> &periodicBCs = + // mesh->getPeriodicBCMap(); + + // ::std::map<BoundaryType, PeriodicBC*>::iterator it; + // ::std::map<BoundaryType, PeriodicBC*>::iterator end = periodicBCs.end(); + // for(it = periodicBCs.begin(); it != end; ++it) { + // it->second->updateAssociatedDOFs(); + // } + // } + + int n_elements = mesh->getNumberOfLeaves(); + ElInfo *el_info; + + newCoords = false; + + stack = NEW TraverseStack; + doMoreRecursiveRefine = true; + while (doMoreRecursiveRefine) + { + doMoreRecursiveRefine = false; + el_info = stack->traverseFirst(mesh, -1, + Mesh::CALL_LEAF_EL | Mesh::FILL_NEIGH| Mesh::FILL_BOUND); + while (el_info) + { + if (el_info->getElement()->getMark() > 0) + { + doMoreRecursiveRefine = doMoreRecursiveRefine || + (el_info->getElement()->getMark() > 1); + el_info = refineFunction(el_info); + } + el_info = stack->traverseNext(el_info); + } + } + + if(newCoords) { + setNewCoords(); // call of sub-class method + } + + DELETE stack; + + n_elements = mesh->getNumberOfLeaves() - n_elements; + + // if(mesh->getDim() == 3) { + // ::std::map<BoundaryType, PeriodicBC*> &periodicBCs = + // mesh->getPeriodicBCMap(); + + // ::std::map<BoundaryType, PeriodicBC*>::iterator it; + // ::std::map<BoundaryType, PeriodicBC*>::iterator end = periodicBCs.end(); + // for(it = periodicBCs.begin(); it != end; ++it) { + // it->second->clearPeriodicElementData(); + // } + // } + + return(n_elements ? MESH_REFINED : Flag(0)); + } + + + // void RefinementManager::refineElement(Element *element) + // { + // FUNCNAME("RefinementManager::refineElement"); + // element->incrementMark(); + // refineMesh(); + // } + +} diff --git a/AMDiS/src/RefinementManager.h b/AMDiS/src/RefinementManager.h new file mode 100644 index 0000000000000000000000000000000000000000..d4ccc4c619df6e56726c2212629ed70602f2e279 --- /dev/null +++ b/AMDiS/src/RefinementManager.h @@ -0,0 +1,176 @@ +// ============================================================================ +// == == +// == AMDiS - Adaptive multidimensional simulations == +// == == +// ============================================================================ +// == == +// == crystal growth group == +// == == +// == Stiftung caesar == +// == Ludwig-Erhard-Allee 2 == +// == 53175 Bonn == +// == germany == +// == == +// ============================================================================ +// == == +// == http://www.caesar.de/cg/AMDiS == +// == == +// ============================================================================ + +/** \file RefinementManager.h */ + +#ifndef AMDIS_REFINEMENTMANAGER_H +#define AMDIS_REFINEMENTMANAGER_H + +// ============================================================================ +// ===== includes ============================================================= +// ============================================================================ + +#include "Global.h" +#include "Flag.h" + +namespace AMDiS { + + // ============================================================================ + // ===== forward declarations ================================================= + // ============================================================================ + + class Element; + class Line; + class Triangle; + class Tetrahedron; + class Mesh; + class ElInfo; + class TraverseStack; + class RCNeighbourList; + + // ============================================================================ + // ===== class RefinementManager ============================================== + // ============================================================================ + + /** \ingroup Adaption + * \brief + * Base class of RefinementManager1d, RefinementManager2d, RefinementManager3d. + * A RefinementManager contains all functionality to perform refinement + * operations on the mesh. + */ + class RefinementManager + { + public: + /** \brief + * Constructs a RefinementManager which belongs to aMesh + */ + RefinementManager() + : mesh(NULL), newCoords(false), + stack(NULL) + {}; + + /** \brief + * destructor + */ + virtual ~RefinementManager() {}; + + // /** \brief + // * Refines a single Element by increment its mark and then refine + // * the mesh. + // */ + // virtual void refineElement(Element *element); + + /** \brief + * Generates new coordinates on curved boundaries. Can be overriden by + * sub classes if used. + */ + virtual void setNewCoords() { + FUNCNAME("RefinementManager::setNewCoords"); + ERROR_EXIT("called for base class!\n"); + }; + + /** \brief + * Fulfills the refinement for all positive marked elements of the mesh. + * The default implementation of the base class uses \ref refineFunction + * for the refinement of a single element while traversing the mesh. + * Sub classes can overload refineMesh and/or refineFunction to implement + * their own refinement routines. + */ + virtual Flag refineMesh(Mesh *aMesh); + + /** \brief + * All elements of the mesh will be refined. + */ + Flag globalRefine(Mesh *aMesh, int mark); + + /** \brief + * set \ref newCoords + */ + inline void newCoord(bool nc) { newCoords = nc; }; + + inline bool newCoord() { return newCoords; }; + + /** \brief + * Implements the refinement of el_info->el. Can be overriden by sub + * classes if used. + */ + virtual ElInfo* refineFunction(ElInfo* ) { + FUNCNAME("RefinementManager::refineFunction\n"); + ERROR_EXIT("called for base class!\n"); + return NULL; + }; + + inline void setMesh(Mesh *m) { mesh = m; }; + + inline void setStack(TraverseStack *s) { stack = s; }; + + inline TraverseStack *getStack() { return stack; }; + + protected: + /** \brief + * Used by \ref globalRefine + */ + static int globalRefineFct(ElInfo* elinfo); + + + protected: + /** \brief + * The Mesh to be refined + */ + Mesh *mesh; + + /** \brief + * Number of new vertices on a boundary edge + */ + bool newCoords; + + /** \brief + * Still more refinement to do? + */ + static bool doMoreRecursiveRefine; + + /** \brief + * number of DOFVectors which must be interpolated during refinement + */ + static int callRefineInterpol; + + /** \brief + * Used for non recursive traversal + */ + TraverseStack* stack; + + /** \brief + * Used while mesh traversal to have a pointer to this RefinementManager + * from a static method + */ + static RefinementManager* traversePtr; + + /** \brief + * Used by globalRefine to remember the given mark value + */ + static int globalMark; + }; + +} + +#include "RefinementManager1d.h" +#include "RefinementManager2d.h" +#include "RefinementManager3d.h" + +#endif // AMDIS_REFINEMENTMANAGER_H diff --git a/AMDiS/src/RefinementManager1d.cc b/AMDiS/src/RefinementManager1d.cc new file mode 100644 index 0000000000000000000000000000000000000000..867764384ddb7a9175977cd94a58d08d8874194d --- /dev/null +++ b/AMDiS/src/RefinementManager1d.cc @@ -0,0 +1,163 @@ +#include "RefinementManager.h" +#include "Mesh.h" +#include "Traverse.h" +#include "ElInfo.h" +#include "DOFAdmin.h" +#include "AdaptStationary.h" +#include "AdaptInstationary.h" +#include "FixVec.h" +#include "RCNeighbourList.h" +#include "ProblemStatBase.h" +#include "DOFIndexed.h" +#include "Projection.h" + +namespace AMDiS { + + int RefinementManager1d::recursiveRefineFunction(ElInfo* el_info) + { + Line *el = dynamic_cast<Line*>(const_cast<Element*>( el_info->getElement())), *child[2]; + + Mesh* mesh = el_info->getMesh(); + + if(el_info->getProjection(0)) { + traversePtr->newCoord(true); + } + + if (el->getMark() <= 0) + return 0; + + child[0] = dynamic_cast<Line*>( mesh->createNewElement(el)); + child[1] = dynamic_cast<Line*>( mesh->createNewElement(el)); + + int mark = max(0, el->getMark() - 1); + child[0]->setMark(mark); + child[1]->setMark(mark); + el->setMark(0); + + /*--------------------------------------------------------------------------*/ + /* transfer hided data from parent to children */ + /*--------------------------------------------------------------------------*/ + + el->refineElementData(child[0], child[1]); + + el->setFirstChild(child[0]); + el->setSecondChild(child[1]); + + if (child[0]->getMark() > 0) traversePtr->doMoreRecursiveRefine = true; + + DegreeOfFreedom *newVertexDOFs = mesh->getDOF(VERTEX); + child[0]->setDOF(1, newVertexDOFs); + child[1]->setDOF(0, newVertexDOFs); + + /*--------------------------------------------------------------------------*/ + /* the other vertices are handed on from the parent */ + /*--------------------------------------------------------------------------*/ + child[0]->setDOF(0, const_cast<int*>( el->getDOF(0))); + child[1]->setDOF(1, const_cast<int*>( el->getDOF(1))); + + /*--------------------------------------------------------------------------*/ + /* there is one more leaf element, two hierachical elements, */ + /* one more vertex */ + /*--------------------------------------------------------------------------*/ + + mesh->incrementNumberOfLeaves(1); + mesh->incrementNumberOfVertices(1); + mesh->incrementNumberOfElements(2); + + if (mesh->getNumberOfDOFs(CENTER)) + { + /*--------------------------------------------------------------------------*/ + /* there are dofs at the barycenter of the triangles */ + /*--------------------------------------------------------------------------*/ + child[0]->setDOF(mesh->getNode(CENTER), const_cast<int*>( mesh->getDOF(CENTER))); + child[1]->setDOF(mesh->getNode(CENTER), const_cast<int*>( mesh->getDOF(CENTER))); + } + + /*--------------------------------------------------------------------------*/ + /* if there are functions to interpolate data to the finer grid, do so */ + /*--------------------------------------------------------------------------*/ + + RCNeighbourList ref_list(1); // = {{nil, 0, 0}}; + ref_list.setElement(0, el); + + int iadmin; + int nrAdmin = mesh->getNumberOfDOFAdmin(); + for(iadmin = 0; iadmin < nrAdmin; iadmin++) { + ::std::list<DOFIndexedBase*>::iterator it; + DOFAdmin* admin = const_cast<DOFAdmin*>(&mesh->getDOFAdmin(iadmin)); + ::std::list<DOFIndexedBase*>::iterator end = admin->endDOFIndexed(); + for(it = admin->beginDOFIndexed(); it != end; it++) + (*it)->refineInterpol(ref_list, 1); + } + + if (!mesh->queryCoarseDOFs() && mesh->getNumberOfDOFs(CENTER)) + { + mesh->freeDOF(const_cast<int*>( el->getDOF(mesh->getNode(CENTER))), CENTER); + el->setDOF(mesh->getNode(CENTER), NULL); + } + + return 0; + } + + Flag RefinementManager1d::refineMesh(Mesh *aMesh) + { + int n_elements; + + mesh = aMesh; + + n_elements = mesh->getNumberOfLeaves(); + + doMoreRecursiveRefine = true; + while (doMoreRecursiveRefine) + { + doMoreRecursiveRefine = false; + traversePtr = this; + mesh->traverse(-1, + Mesh::CALL_LEAF_EL | + Mesh::FILL_BOUND | + Mesh::FILL_COORDS, + recursiveRefineFunction); + } + + n_elements = mesh->getNumberOfLeaves() - n_elements; + + if(newCoords) { + setNewCoords(); // call of sub-class method + } + + return(n_elements ? MESH_REFINED : Flag(0)); + } + + int RefinementManager1d::newCoordsFct(ElInfo *el_info) + { + Element *el = el_info->getElement(); + int j; + int dow = Global::getGeo(WORLD); + + Projection *projector = el_info->getProjection(0); + + if (el->getFirstChild() && projector && (!el->isNewCoordSet())) + { + WorldVector<double> *new_coord = NEW WorldVector<double>; + + for (j = 0; j < dow; j++) + (*new_coord)[j] = (el_info->getCoord(0)[j] + el_info->getCoord(1)[j])*0.5; + + projector->project(*new_coord); + + el->setNewCoord(new_coord); + } + + return 0; + } + + void RefinementManager1d::setNewCoords() + { + Flag fillFlag = Mesh::CALL_EVERY_EL_PREORDER| + Mesh::FILL_BOUND| + Mesh::FILL_COORDS; + + mesh->traverse(-1, fillFlag, newCoordsFct); + } + +} diff --git a/AMDiS/src/RefinementManager1d.h b/AMDiS/src/RefinementManager1d.h new file mode 100644 index 0000000000000000000000000000000000000000..7e3918ea72c9dde0b3c39eb62da042cc8b51ef27 --- /dev/null +++ b/AMDiS/src/RefinementManager1d.h @@ -0,0 +1,78 @@ +// ============================================================================ +// == == +// == AMDiS - Adaptive multidimensional simulations == +// == == +// ============================================================================ +// == == +// == crystal growth group == +// == == +// == Stiftung caesar == +// == Ludwig-Erhard-Allee 2 == +// == 53175 Bonn == +// == germany == +// == == +// ============================================================================ +// == == +// == http://www.caesar.de/cg/AMDiS == +// == == +// ============================================================================ + +/** \file RefinementManager1d.h */ + +#ifndef AMDIS_REFINEMENT_MANAGER_1D_H +#define AMDIS_REFINEMENT_MANAGER_1D_H + +#include "MemoryManager.h" + +namespace AMDiS { + + // ============================================================================ + // ===== class RefinementManager1d ============================================ + // ============================================================================ + + /** \ingroup Adaption + * \brief + * Implements a RefinementManager for 1-dimensional meshes. + */ + class RefinementManager1d : public RefinementManager + { + public: + MEMORY_MANAGED(RefinementManager1d); + + /** \brief + * Calls base class constructor. + */ + RefinementManager1d() + : RefinementManager() + {}; + + /** \brief + * destructor + */ + virtual ~RefinementManager1d() {}; + + /** \brief + * Implements RefinementManager::refineMesh. + */ + Flag refineMesh(Mesh *aMesh); + + /** \brief + * Implements RefinementManager::setNewCoords + */ + void setNewCoords(); + + protected: + /** \brief + * Used by refineMesh while mesh traversal + */ + static int recursiveRefineFunction(ElInfo* el_info); + + /** \brief + * Used by \ref setNewCoords + */ + static int newCoordsFct(ElInfo *el_info); + }; + +} + +#endif // AMDIS_REFINEMENT_MANAGER_1D_H diff --git a/AMDiS/src/RefinementManager2d.cc b/AMDiS/src/RefinementManager2d.cc new file mode 100644 index 0000000000000000000000000000000000000000..e1c9aa81351255eff1d3a3c9d35506cd17c16e12 --- /dev/null +++ b/AMDiS/src/RefinementManager2d.cc @@ -0,0 +1,474 @@ +#include "RefinementManager.h" +#include "Mesh.h" +#include "Traverse.h" +#include "ElInfo.h" +#include "DOFAdmin.h" +#include "AdaptStationary.h" +#include "AdaptInstationary.h" +#include "FixVec.h" +#include "RCNeighbourList.h" +#include "ProblemStatBase.h" +#include "DOFIndexed.h" +#include "Projection.h" +#include "LeafData.h" +#include "VertexVector.h" + +namespace AMDiS { + + ElInfo* RefinementManager2d::refineFunction(ElInfo* el_info) + { + FUNCNAME("RefinementManager::refineFunction"); + int n_neigh; + bool bound = false; + + DegreeOfFreedom *edge[2]; + + RCNeighbourList* refineList = NEW RCNeighbourList(2); + + if (el_info->getElement()->getMark() <= 0) + return(el_info); /* element may not be refined */ + + refineList->setElement(0, el_info->getElement()); + n_neigh = 1; + + if(el_info->getProjection(0) && + el_info->getProjection(0)->getType() == VOLUME_PROJECTION) + { + newCoords = true; + } + + /****************************************************************************/ + /* give the refinement edge the right orientation */ + /****************************************************************************/ + + if (el_info->getElement()->getDOF(0,0) < el_info->getElement()->getDOF(1, 0)) + { + edge[0] = const_cast<int*>( el_info->getElement()->getDOF(0)); + edge[1] = const_cast<int*>( el_info->getElement()->getDOF(1)); + } + else + { + edge[1] = const_cast<int*>( el_info->getElement()->getDOF(0)); + edge[0] = const_cast<int*>( el_info->getElement()->getDOF(1)); + } + + /****************************************************************************/ + /* get the refinement patch */ + /****************************************************************************/ + if (getRefinePatch(&el_info, edge, 0, refineList, &n_neigh)) + { + /****************************************************************************/ + /* domain's boundary was reached while looping around the refinement edge */ + /****************************************************************************/ + getRefinePatch(&el_info, edge, 1, refineList, &n_neigh); + bound = true; + } + + // ========================================================================== + // === check for periodic boundary ========================================== + // ========================================================================== + + DegreeOfFreedom *next_edge[2]; + DegreeOfFreedom *first_edge[2] = {edge[0], edge[1]}; + DegreeOfFreedom *last_edge[2] = {NULL, NULL}; + int n_neigh_periodic; + + DegreeOfFreedom newDOF = -1; + DegreeOfFreedom lastNewDOF = -1; + DegreeOfFreedom firstNewDOF = -1; + + RCNeighbourList *periodicList; + ::std::map<int, VertexVector*>::iterator it; + ::std::map<int, VertexVector*>::iterator end = mesh->getPeriodicAssociations().end(); + + while(edge[0] != NULL) { + periodicList = refineList->periodicSplit(edge, + next_edge, + &n_neigh, + &n_neigh_periodic); + + TEST_EXIT(periodicList)("periodicList = NULL\n"); + + newDOF = + refinePatch(edge, periodicList, n_neigh_periodic, bound); + + if(firstNewDOF == -1) { + firstNewDOF = newDOF; + } + + if(lastNewDOF != -1) { + for(it = mesh->getPeriodicAssociations().begin(); it != end; ++it) { + if(it->second) { + if(((*(it->second))[edge[0][0]] == last_edge[0][0] && + (*(it->second))[edge[1][0]] == last_edge[1][0]) || + ((*(it->second))[edge[0][0]] == last_edge[1][0] && + (*(it->second))[edge[1][0]] == last_edge[0][0])) + { + (*(it->second))[lastNewDOF] = newDOF; + (*(it->second))[newDOF] = lastNewDOF; + } + } + } + } + lastNewDOF = newDOF; + + last_edge[0] = edge[0]; + last_edge[1] = edge[1]; + + edge[0] = next_edge[0]; + edge[1] = next_edge[1]; + } + + if(lastNewDOF != firstNewDOF) { + for(it = mesh->getPeriodicAssociations().begin(); it != end; ++it) { + if(it->second) { + if(((*(it->second))[first_edge[0][0]] == last_edge[0][0] && + (*(it->second))[first_edge[1][0]] == last_edge[1][0]) || + ((*(it->second))[first_edge[0][0]] == last_edge[1][0] && + (*(it->second))[first_edge[1][0]] == last_edge[0][0])) + { + (*(it->second))[lastNewDOF] = firstNewDOF; + (*(it->second))[firstNewDOF] = lastNewDOF; + } + } + } + } + + + /****************************************************************************/ + /* and now refine the patch */ + /****************************************************************************/ + + //newDOF = refinePatch(edge, refineList, n_neigh, bound); + + DELETE refineList; + + return(el_info); + } + + + int RefinementManager2d::newCoordsFct(ElInfo *el_info) + { + Element *el = el_info->getElement(); + int j; + int dow = Global::getGeo(WORLD); + + Projection *projector = el_info->getProjection(0); + + if(!projector || projector->getType() != VOLUME_PROJECTION) { + projector = el_info->getProjection(2); + } + + if (el->getFirstChild() && projector && (!el->isNewCoordSet())) + { + WorldVector<double> *new_coord = NEW WorldVector<double>; + + for (j = 0; j < dow; j++) + (*new_coord)[j] = (el_info->getCoord(0)[j] + el_info->getCoord(1)[j])*0.5; + + projector->project(*new_coord); + + el->setNewCoord(new_coord); + } + + return 0; + } + + void RefinementManager2d::setNewCoords() + { + Flag fillFlag = Mesh::CALL_EVERY_EL_PREORDER| + Mesh::FILL_BOUND| + Mesh::FILL_COORDS; + + mesh->traverse(-1, fillFlag, newCoordsFct); + } + + + DegreeOfFreedom RefinementManager2d::refinePatch(DegreeOfFreedom *edge[2], + RCNeighbourList* refineList, + int n_neigh, bool bound) + { + FUNCNAME("RefinementManager2d::refinePatch()"); + DegreeOfFreedom *dof[3] = {NULL, NULL, NULL}; + Triangle *el = dynamic_cast<Triangle*>(const_cast<Element*>( refineList->getElement(0))); + Triangle *neigh = dynamic_cast<Triangle*>(const_cast<Element*>( refineList->getElement(1))); + + /****************************************************************************/ + /* there is one new vertex in the refinement edge */ + /****************************************************************************/ + + dof[0] = mesh->getDOF(VERTEX); + + mesh->incrementNumberOfVertices(1); + mesh->incrementNumberOfEdges(1); + + if (mesh->getNumberOfDOFs(EDGE)) + { + /****************************************************************************/ + /* there are two additional dofs in the refinement edge */ + /****************************************************************************/ + dof[1] = mesh->getDOF(EDGE); + dof[2] = mesh->getDOF(EDGE); + } + + /****************************************************************************/ + /* first refine the element */ + /****************************************************************************/ + + // check for periodic boundary + // DegreeOfFreedom *periodicDOF[3] = {NULL, NULL, NULL}; + // RCNeighbourList *periodicRefineList = NULL; + // int n_neigh_periodic; + + // if (neigh && + // (neigh->getDOF(0) != el->getDOF(1)) && + // (neigh->getDOF(0) != el->getDOF(0))) + // { + // periodicDOF[0] = mesh->getDOF(VERTEX); + // mesh->incrementNumberOfVertices(1); + // mesh->incrementNumberOfEdges(1); + // if (mesh->getNumberOfDOFs(EDGE)) { + // periodicDOF[1] = mesh->getDOF(EDGE); + // periodicDOF[2] = mesh->getDOF(EDGE); + // } + + // DegreeOfFreedom *edge[2] = { + // const_cast<DegreeOfFreedom*>(el->getDOF(0)), + // const_cast<DegreeOfFreedom*>(el->getDOF(1)) + // }; + // DegreeOfFreedom *periodicEdge[2] = { + // const_cast<DegreeOfFreedom*>(neigh->getDOF(0)), + // const_cast<DegreeOfFreedom*>(neigh->getDOF(1)) + // }; + + // periodicRefineList = refineList->periodicSplit(edge, + // &n_neigh, + // periodicEdge, + // &n_neigh_periodic); + + // // dynamic_cast<LeafDataPeriodic*>(neigh->getElementData(PERIODIC))-> + // // setNewDOF(dof[0][0]); + // // dynamic_cast<LeafDataPeriodic*>(el->getElementData(PERIODIC))-> + // // setNewDOF(periodicDOF[0][0]); + + // // MSG("el %d new dof %d periodic dof %d\n", + // // el->getIndex(), + // // dof[0][0], + // // periodicDOF[0][0]); + // } + + + bisectTriangle(el, dof); + + // MSG("el %d -> %d %d\n", + // el->getIndex(), + // el->getChild(0)->getIndex(), + // el->getChild(1)->getIndex()); + + if (neigh) { + // if(periodicDOF[0]) { + // dof[0] = periodicDOF[0]; + // dof[1] = periodicDOF[1]; + // dof[2] = periodicDOF[2]; + // } else { + DegreeOfFreedom *tmp = dof[1]; + /****************************************************************************/ + /* there is a neighbour; refine it also, but first exchange dof[1] and */ + /* dof[2]; thus, dof[1] is always added on child[0]! */ + /****************************************************************************/ + dof[1] = dof[2]; + dof[2] = tmp; + // } + + bisectTriangle(neigh, dof); + + // MSG("neigh %d -> %d %d\n", + // neigh->getIndex(), + // neigh->getChild(0)->getIndex(), + // neigh->getChild(1)->getIndex()); + } + else + { + newCoords = true; + } + + /****************************************************************************/ + /* if there are functions to interpolate data to the finer grid, do so */ + /****************************************************************************/ + + int iadmin; + int nrAdmin = mesh->getNumberOfDOFAdmin(); + for(iadmin = 0; iadmin < nrAdmin; iadmin++) { + ::std::list<DOFIndexedBase*>::iterator it; + DOFAdmin* admin = const_cast<DOFAdmin*>(&mesh->getDOFAdmin(iadmin)); + ::std::list<DOFIndexedBase*>::iterator end = admin->endDOFIndexed(); + for(it = admin->beginDOFIndexed(); it != end; it++) { + (*it)->refineInterpol(*refineList, n_neigh); + // if(periodicRefineList) { + // (*it)->refineInterpol(*periodicRefineList, n_neigh_periodic); + // } + } + } + + + if (!mesh->queryCoarseDOFs()) + { + /****************************************************************************/ + /* if there should be no dof information on interior leaf elements remove */ + /* dofs from edges and the centers of parents */ + /****************************************************************************/ + if (mesh->getNumberOfDOFs(EDGE)) { + + int node = mesh->getNode(EDGE); + + /****************************************************************************/ + /* the only DOF that can be freed is that in the refinement edge; all other*/ + /* DOFs are handed on the children */ + /****************************************************************************/ + + mesh->freeDOF(const_cast<int*>( el->getDOF(node+2)), EDGE); + } + if (mesh->getNumberOfDOFs(EDGE) || mesh->getNumberOfDOFs(CENTER)) { + refineList->removeDOFParents(n_neigh); + // if(periodicRefineList) { + // periodicRefineList->removeDOFParents(n_neigh_periodic); + // } + } + } + + // if(periodicRefineList) DELETE periodicRefineList; + + return dof[0][0]; + } + + + void RefinementManager2d::bisectTriangle(Triangle *el, + DegreeOfFreedom* newDOFs[3]) + { + FUNCNAME("RefinementManager2d::bisectTriangle"); + TEST_EXIT(mesh)("no mesh!\n"); + + Triangle *child[2]; + int i_child; + + child[0] = dynamic_cast<Triangle*>(mesh->createNewElement(el)); + child[1] = dynamic_cast<Triangle*>(mesh->createNewElement(el)); + + signed char newMark = max(0, el->getMark()-1); + child[0]->setMark(newMark); + child[1]->setMark(newMark); + el->setMark(0); + + /****************************************************************************/ + /* transfer hidden data from parent to children */ + /****************************************************************************/ + + el->refineElementData(child[0], child[1]); // call of subclass-method + // el->freeElementData(); + el->setFirstChild(child[0]); + el->setSecondChild(child[1]); + + if (newMark > 0) doMoreRecursiveRefine = true; + + /****************************************************************************/ + /* vertex 2 is the newest vertex */ + /****************************************************************************/ + + child[0]->setDOF(2, newDOFs[0]); + child[1]->setDOF(2, newDOFs[0]); + + /****************************************************************************/ + /* the other vertices are handed on from the parent */ + /****************************************************************************/ + + for (i_child = 0; i_child < 2; i_child++) + { + child[i_child]->setDOF(i_child, const_cast<int*>( el->getDOF(2))); + child[i_child]->setDOF(1-i_child, const_cast<int*>( el->getDOF(i_child))); + } + + /****************************************************************************/ + /* there is one more leaf element, two hierachical elements and one more */ + /* edge */ + /****************************************************************************/ + + mesh->incrementNumberOfEdges(1); + mesh->incrementNumberOfLeaves(1); + mesh->incrementNumberOfElements(2); + + if (mesh->getNumberOfDOFs(EDGE)) + { + /****************************************************************************/ + /* there are dof's in the midpoint of the edges */ + /****************************************************************************/ + DegreeOfFreedom* newEdgeDOFs = mesh->getDOF(EDGE); + + child[0]->setDOF(4, newEdgeDOFs); + child[1]->setDOF(3, newEdgeDOFs); + + /****************************************************************************/ + /* dofs handed on by the parent */ + /****************************************************************************/ + child[0]->setDOF(5, const_cast<int*>( el->getDOF(4))); + child[1]->setDOF(5, const_cast<int*>( el->getDOF(3))); + + /****************************************************************************/ + /* dofs in the refinement edge */ + /****************************************************************************/ + child[0]->setDOF(3, newDOFs[1]); + child[1]->setDOF(4, newDOFs[2]); + } + + if (mesh->getNumberOfDOFs(CENTER)) + { + int node = mesh->getNode(CENTER); + + /****************************************************************************/ + /* there are dofs at the barycenter of the triangles */ + /****************************************************************************/ + child[0]->setDOF(node, mesh->getDOF(CENTER)); + child[1]->setDOF(node, mesh->getDOF(CENTER)); + } + } + + int RefinementManager2d::getRefinePatch(ElInfo **el_info, + DegreeOfFreedom *edge[2], + int dir, RCNeighbourList* refineList, + int *n_neigh) + { + FUNCNAME("RefinementManager2d::getRefinePatch"); + Triangle *el = dynamic_cast<Triangle*>(const_cast<Element*>( (*el_info)->getElement())); + + ElInfo *neigh_info; + int opp_vertex = 0; + + if ((*el_info)->getNeighbour(2) && (*el_info)->getOppVertex(2) != 2) + { + /****************************************************************************/ + /* neighbour is not compatible devisible; refine neighbour first, store the*/ + /* opp_vertex to traverse back to el */ + /****************************************************************************/ + opp_vertex = (*el_info)->getOppVertex(2); + + neigh_info = stack->traverseNeighbour2d(*el_info, 2); + neigh_info->getElement()->setMark(max(neigh_info->getElement()->getMark(), + 1)); + neigh_info = refineFunction(neigh_info); + + /****************************************************************************/ + /* now go back to the original element and refine the patch */ + /****************************************************************************/ + *el_info = neigh_info = stack->traverseNeighbour2d(neigh_info, opp_vertex); + TEST_EXIT(neigh_info->getElement() == el)("invalid traverse_neighbour1\n"); + } + + if (refineList->setElement(1, (*el_info)->getNeighbour(2))) { + TEST_EXIT((*el_info)->getOppVertex(2) == 2) + ("no compatible ref. edge after recursive refinement of neighbour\n"); + *n_neigh = 2; + } + + return(0); + } + +} diff --git a/AMDiS/src/RefinementManager2d.h b/AMDiS/src/RefinementManager2d.h new file mode 100644 index 0000000000000000000000000000000000000000..fd36e4187df3f4879a323c246ca536f24ec94353 --- /dev/null +++ b/AMDiS/src/RefinementManager2d.h @@ -0,0 +1,95 @@ +// ============================================================================ +// == == +// == AMDiS - Adaptive multidimensional simulations == +// == == +// ============================================================================ +// == == +// == crystal growth group == +// == == +// == Stiftung caesar == +// == Ludwig-Erhard-Allee 2 == +// == 53175 Bonn == +// == germany == +// == == +// ============================================================================ +// == == +// == http://www.caesar.de/cg/AMDiS == +// == == +// ============================================================================ + +/** \file RefinementManager2d.h */ + +#ifndef AMDIS_REFINEMENT_MANAGER_2D_H +#define AMDIS_REFINEMENT_MANAGER_2D_H + +#include "MemoryManager.h" + +namespace AMDiS { + + // ============================================================================ + // ===== class RefinementManager2d ============================================ + // ============================================================================ + + /** \ingroup Adaption + * \brief + * Implements a RefinementManager for 2-dimensional meshes. + */ + class RefinementManager2d : public RefinementManager + { + public: + MEMORY_MANAGED(RefinementManager2d); + + /** \brief + * Calls base class constructor. + */ + RefinementManager2d() + : RefinementManager() + {}; + + /** \brief + * destructor + */ + virtual ~RefinementManager2d() {}; + + protected: + /** \brief + * Used by \ref setNewCoords + */ + static int newCoordsFct(ElInfo *el_info); + + /** \brief + * Implements RefinementManager::setNewCoords + */ + void setNewCoords(); + + /** \brief + * gets the elements around the refinement edge with vertices node[0] and + * node[1] ; refines those elements at this edge are not compatible + * devisible; + * dir determines the direction of the first neighbour + * get_refine_patch returns 1 if the domain's boundary is reached while + * looping around the refinement edge, otherwise 0 + */ + int getRefinePatch(ElInfo **el_info, DegreeOfFreedom *edge[2], int dir, + RCNeighbourList* refineList, int *n_neigh); + + /** \brief + * Refines all elements in the patch. + */ + DegreeOfFreedom refinePatch(DegreeOfFreedom *edge[2], RCNeighbourList* refineList, + int n_neigh, bool bound); + + /** \brief + * Implements RefinementManager::refineFunction. + */ + ElInfo* refineFunction(ElInfo* el_info); + + /** \brief + * Refines one Triangle. + */ + void bisectTriangle(Triangle *el, DegreeOfFreedom* newDofs[3]); + }; + +} + +#endif // AMDIS_REFINEMENT_MANAGER_2D_H diff --git a/AMDiS/src/RefinementManager3d.cc b/AMDiS/src/RefinementManager3d.cc new file mode 100644 index 0000000000000000000000000000000000000000..17a1f2850071d1a559bd6259dcd3a8327d004bbf --- /dev/null +++ b/AMDiS/src/RefinementManager3d.cc @@ -0,0 +1,762 @@ +#include "RefinementManager.h" +#include "Mesh.h" +#include "Traverse.h" +#include "ElInfo.h" +#include "DOFAdmin.h" +#include "AdaptStationary.h" +#include "AdaptInstationary.h" +#include "FixVec.h" +#include "RCNeighbourList.h" +#include "ProblemStatBase.h" +#include "DOFIndexed.h" +#include "Projection.h" +#include "DOFVector.h" +#include "PeriodicBC.h" +#include "VertexVector.h" + +namespace AMDiS { + + void RefinementManager3d::bisectTetrahedron(RCNeighbourList* ref_list, + int index, + DegreeOfFreedom* dof[3], + DegreeOfFreedom *edge[2]) + { + Tetrahedron *el = dynamic_cast<Tetrahedron*>(const_cast<Element*>( ref_list->getElement(index))), *child[2]; + int i, node; + int el_type = ref_list->getType(index); + + child[0] = dynamic_cast<Tetrahedron*>(mesh->createNewElement(el)); + child[1] = dynamic_cast<Tetrahedron*>(mesh->createNewElement(el)); + + int mark = max(0, el->getMark()-1); + child[0]->setMark(mark); + child[1]->setMark(mark); + el->setMark(0); + + /****************************************************************************/ + /* transfer hidden data from parent to children */ + /****************************************************************************/ + + el->refineElementData(child[0], child[1], el_type); + + el->setFirstChild(child[0]); + el->setSecondChild(child[1]); + + if (child[0]->getMark() > 0) doMoreRecursiveRefine = true; + + int n_vertices = mesh->getGeo(VERTEX); + child[0]->setDOF(n_vertices-1, dof[0]); + child[1]->setDOF(n_vertices-1, dof[0]); + + for (i = 0; i < n_vertices-1; i++) + { + child[0]-> + setDOF(i, const_cast<int*>( el->getDOF(Tetrahedron::childVertex[el_type][0][i]))); + child[1]-> + setDOF(i, const_cast<int*>( el->getDOF(Tetrahedron::childVertex[el_type][1][i]))); + } + /****************************************************************************/ + /* there is one more leaf element and two more hierachical elements */ + /****************************************************************************/ + + mesh->incrementNumberOfLeaves(1); + mesh->incrementNumberOfElements(2); + + /****************************************************************************/ + /* first set those dof pointers for higher order without neighbour */ + /* information */ + /****************************************************************************/ + + if (mesh->getNumberOfDOFs(EDGE)) + { + node = mesh->getNode(EDGE); + + /****************************************************************************/ + /* set pointers to those dof's that are handed on from the parant */ + /****************************************************************************/ + + child[0]-> + setDOF(node, + const_cast<int*>( el->getDOF(node+Tetrahedron::childEdge[el_type][0][0]))); + child[1]-> + setDOF(node, + const_cast<int*>( el->getDOF(node+Tetrahedron::childEdge[el_type][1][0]))); + child[0]-> + setDOF(node+1, + const_cast<int*>( el->getDOF(node+Tetrahedron::childEdge[el_type][0][1]))); + child[1]-> + setDOF(node+1, + const_cast<int*>( el->getDOF(node+Tetrahedron::childEdge[el_type][1][1]))); + child[0]-> + setDOF(node+3, + const_cast<int*>( el->getDOF(node+Tetrahedron::childEdge[el_type][0][3]))); + child[1]-> + setDOF(node+3, + const_cast<int*>( el->getDOF(node+Tetrahedron::childEdge[el_type][1][3]))); + + /****************************************************************************/ + /* adjust pointers to the dof's in the refinement edge */ + /****************************************************************************/ + + if (el->getDOF(0) == edge[0]) + { + child[0]->setDOF(node+2, dof[1]); + child[1]->setDOF(node+2, dof[2]); + } + else + { + child[0]->setDOF(node+2, dof[2]); + child[1]->setDOF(node+2, dof[1]); + } + } + + if (mesh->getNumberOfDOFs(FACE)) + { + node = mesh->getNode(FACE); + + /****************************************************************************/ + /* set pointers to those dof's that are handed on from the parant */ + /****************************************************************************/ + + child[0]->setDOF(node+3, const_cast<int*>( el->getDOF(node+1))); + child[1]->setDOF(node+3, const_cast<int*>( el->getDOF(node+0))); + + /****************************************************************************/ + /* get new dof for the common face of child0 and child1 */ + /****************************************************************************/ + + DegreeOfFreedom *newDOF = mesh->getDOF(FACE); + child[0]->setDOF(node, static_cast<int*>( newDOF)); + child[1]->setDOF(node, static_cast<int*>( newDOF)); + } + + if (mesh->getNumberOfDOFs(CENTER)) + { + node = mesh->getNode(CENTER); + child[0]->setDOF(node, const_cast<int*>( mesh->getDOF(CENTER))); + child[1]->setDOF(node, const_cast<int*>( mesh->getDOF(CENTER))); + } + + if (mesh->getNumberOfDOFs(EDGE) || mesh->getNumberOfDOFs(FACE)) + fillPatchConnectivity(ref_list, index); + + // MSG("%d -> %d %d\n", + // el->getIndex(), + // child[0]->getIndex(), + // child[1]->getIndex()); + } + + void RefinementManager3d::fillPatchConnectivity(RCNeighbourList* ref_list, + int index) + { + FUNCNAME("RefinementManager3d::fillPatchConnectivity"); + Element *el = ref_list->getElement(index), *neigh; + int dir, el_type = ref_list->getType(index), n_type = 0; + int adjc, i, j, i_neigh, j_neigh; + int node0, node1, opp_v = 0; + + for (dir = 0; dir < 2; dir++) + { + neigh = ref_list->getNeighbourElement(index, dir); + if (neigh) + { + n_type = ref_list->getType( ref_list->getNeighbourNr(index, dir) ); + opp_v = ref_list->getOppVertex(index, dir); + } + + if (!neigh || neigh->isLeaf()) + { + + /****************************************************************************/ + /* get new dof's in the midedge of the face of el and for the two midpoints*/ + /* of the sub-faces. If face is an interior face those pointers have to be */ + /* adjusted by the neighbour element also (see below) */ + /****************************************************************************/ + + if (mesh->getNumberOfDOFs(EDGE)) + { + node0 = node1 = mesh->getNode(EDGE); + node0 += Tetrahedron::nChildEdge[el_type][0][dir]; + node1 += Tetrahedron::nChildEdge[el_type][1][dir]; + DegreeOfFreedom *newDOF = mesh->getDOF(EDGE); + (const_cast<Element*>( el->getFirstChild()))->setDOF(node0, newDOF); + (const_cast<Element*>( el->getSecondChild()))->setDOF(node1, newDOF); + } + if (mesh->getNumberOfDOFs(FACE)) + { + node0 = mesh->getNode(FACE) + Tetrahedron::nChildFace[el_type][0][dir]; + (const_cast<Element*>( el->getFirstChild()))->setDOF(node0, mesh->getDOF(FACE)); + node1 = mesh->getNode(FACE) + Tetrahedron::nChildFace[el_type][1][dir]; + (const_cast<Element*>( el->getSecondChild()))->setDOF(node1, mesh->getDOF(FACE)); + } + } + else /* if (!neigh || !neigh->child[0]) */ + { + /****************************************************************************/ + /* interior face and neighbour has been refined, look for position at the */ + /* refinement edge */ + /****************************************************************************/ + + if (el->getDOF(0) == neigh->getDOF(0)) + { + /****************************************************************************/ + /* same position at refinement edge */ + /****************************************************************************/ + adjc = 0; + } + else + { + /****************************************************************************/ + /* different position at refinement edge */ + /****************************************************************************/ + adjc = 1; + } + + for (i = 0; i < 2; i++) + { + j = Tetrahedron::adjacentChild[adjc][i]; + + i_neigh = Tetrahedron::nChildFace[el_type][i][dir]; + j_neigh = Tetrahedron::nChildFace[n_type][j][opp_v-2]; + + /****************************************************************************/ + /* adjust dof pointer in the edge in the common face of el and neigh and */ + /* the dof pointer in the sub-face child_i-child_j (allocated by neigh!) */ + /****************************************************************************/ + + if (mesh->getNumberOfDOFs(EDGE)) + { + node0 = + mesh->getNode(EDGE) + Tetrahedron::nChildEdge[el_type][i][dir]; + node1 = + mesh->getNode(EDGE) + Tetrahedron::nChildEdge[n_type][j][opp_v-2]; + + TEST_EXIT(neigh->getChild(j)->getDOF(node1)) + ("no dof on neighbour %d at node %d\n", + neigh->getChild(j)->getIndex(), node1); + + (const_cast<Element*>( el->getChild(i)))-> + setDOF(node0, const_cast<int*>( neigh->getChild(j)->getDOF(node1))); + } + if (mesh->getNumberOfDOFs(FACE)) + { + node0 = mesh->getNode(FACE) + i_neigh; + node1 = mesh->getNode(FACE) + j_neigh; + + TEST_EXIT(neigh->getChild(j)->getDOF(node1)) + ("no dof on neighbour %d at node %d\n", + neigh->getChild(j)->getIndex(), node1); + + (const_cast<Element*>( el->getChild(i)))-> + setDOF(node0, const_cast<int*>( neigh->getChild(j)->getDOF(node1))); + } + + } /* for (i = 0; i < 2; i++) */ + } /* else of if (!neigh || !neigh->child[0]) */ + } /* for (dir = 0; dir < 2; dir++) */ + } + + + int RefinementManager3d::newCoordsFct(ElInfo *el_info) + { + Element *el = el_info->getElement(); + int i, j, n_neigh; + DegreeOfFreedom *edge[2]; + ElInfo *elinfo = el_info; + + int dow = Global::getGeo(WORLD); + + Projection *projector = el_info->getProjection(0); + + if(!projector || projector->getType() != VOLUME_PROJECTION) { + projector = el_info->getProjection(4); + } + + if (el->getFirstChild() && projector && (!el->isNewCoordSet())) { + WorldVector<double> *new_coord = NEW WorldVector<double>; + + for (j = 0; j < dow; j++) + (*new_coord)[j] = (el_info->getCoord(0)[j] + el_info->getCoord(1)[j])*0.5; + + projector->project(*new_coord); + + el->setNewCoord(new_coord); + /****************************************************************************/ + /* now, information should be passed on to patch neighbours... */ + /* get the refinement patch */ + /****************************************************************************/ + refList->setElement(0, el); + refList->setElType(0, dynamic_cast<ElInfo3d*>(el_info)->getType()); + n_neigh = 1; + for (i = 0; i < 2; i++) + edge[i] = const_cast<int*>( el_info->getElement()->getDOF(i)); + if (getRefinePatch(&elinfo, edge, 0, refList, &n_neigh)) + { + /****************************************************************************/ + /* domain's boundary was reached while looping around the refinement edge */ + /****************************************************************************/ + getRefinePatch(&elinfo, edge, 1, refList, &n_neigh); + } + for (i = 1; i < n_neigh; i++) /* start with 1, as list[0]=el */ + { + TEST(!refList->getElement(i)->isNewCoordSet()) + ("non-nil new_coord in el %d ref_list[%d] el %d (n_neigh=%d)\n", + el->getIndex(), i, refList->getElement(i)->getIndex(), n_neigh); + + refList->getElement(i)->setNewCoord(el->getNewCoord()); + } + } + + return 0; + } + + void RefinementManager3d::setNewCoords() + { + ElInfo *el_info; + + Flag fillFlag = Mesh::CALL_EVERY_EL_PREORDER| + Mesh::FILL_BOUND| + Mesh::FILL_COORDS; + + if (refList) + DELETE refList; + + refList = NEW RCNeighbourList(mesh->getMaxEdgeNeigh()); + + fillFlag |= Mesh::FILL_NEIGH; + el_info = stack->traverseFirst(mesh, -1, fillFlag); + while (el_info) { + newCoordsFct(el_info); + el_info = stack->traverseNext(el_info); + } + } + + + DegreeOfFreedom RefinementManager3d::refinePatch(DegreeOfFreedom *edge[2], + RCNeighbourList* refineList, + int n_neigh, bool bound) + { + int i; + Tetrahedron *el = dynamic_cast<Tetrahedron*>(const_cast<Element*>( refineList->getElement(0))); + /* first element in the list */ + DegreeOfFreedom *dof[3] = {NULL, NULL, NULL}; + + /****************************************************************************/ + /* get new dof's in the refinement edge */ + /****************************************************************************/ + + dof[0] = mesh->getDOF(VERTEX); + mesh->incrementNumberOfVertices(1); + + if (mesh->getNumberOfDOFs(EDGE)) + { + dof[1] = mesh->getDOF(EDGE); + dof[2] = mesh->getDOF(EDGE); + } + + for (i = 0; i < n_neigh; i++) { + bisectTetrahedron(refineList, i, dof, edge); + } + + /****************************************************************************/ + /* if there are functions to interpolate data to the finer grid, do so */ + /****************************************************************************/ + int iadmin; + int nrAdmin = mesh->getNumberOfDOFAdmin(); + for(iadmin = 0; iadmin < nrAdmin; iadmin++) { + ::std::list<DOFIndexedBase*>::iterator it; + DOFAdmin* admin = const_cast<DOFAdmin*>(&mesh->getDOFAdmin(iadmin)); + ::std::list<DOFIndexedBase*>::iterator end = admin->endDOFIndexed(); + for(it = admin->beginDOFIndexed(); it != end; it++) + (*it)->refineInterpol(*refineList, n_neigh); + } + + if (!mesh->queryCoarseDOFs()) + { + /****************************************************************************/ + /* if there should be no dof information on interior leaf elements remove */ + /* dofs from edges, faces and the centers of parents */ + /****************************************************************************/ + if (mesh->getNumberOfDOFs(EDGE)) + { + /****************************************************************************/ + /* remove dof of the midpoint of the common refinement edge */ + /****************************************************************************/ + + el = dynamic_cast<Tetrahedron*>(const_cast<Element*>( refineList->getElement(0))); + mesh->freeDOF(const_cast<int*>( el->getDOF(mesh->getNode(EDGE))), EDGE); + } + + if (mesh->getNumberOfDOFs(EDGE) || + mesh->getNumberOfDOFs(FACE) || + mesh->getNumberOfDOFs(CENTER)) + { + for (i = 0; i < n_neigh; i++) + refineList->removeDOFParent(i); + } + } + + + /****************************************************************************/ + /* update the number of edges and faces; depends whether refinement edge */ + /* is a boundary edge or not */ + /****************************************************************************/ + + if (bound) + { + mesh->incrementNumberOfEdges(n_neigh + 2); + mesh->incrementNumberOfFaces(2*n_neigh + 1); + newCoords = true; + } + else + { + mesh->incrementNumberOfEdges(n_neigh + 1); + mesh->incrementNumberOfFaces(2*n_neigh); + } + + return dof[0][0]; + } + + + int RefinementManager3d::getRefinePatch(ElInfo **el_info, + DegreeOfFreedom *edge[2], + int dir, + RCNeighbourList* refineList, + int *n_neigh) + { + FUNCNAME("RefinementManager3d::getRefinePatch"); + ElInfo *neigh_info; + + Tetrahedron *el, *neigh; + int i, j, k, opp_v = 0; + int edge_no, neigh_el_type; + + el = dynamic_cast<Tetrahedron*>(const_cast<Element*>( (*el_info)->getElement())); + + if ((*el_info)->getNeighbour(3-dir) == NULL) {return(1);} + + opp_v = (*el_info)->getOppVertex(3-dir); + neigh_info = stack->traverseNeighbour3d((*el_info), 3-dir); + neigh_el_type = dynamic_cast<ElInfo3d*>(neigh_info)->getType(); + + neigh = dynamic_cast<Tetrahedron*>(const_cast<Element*>( neigh_info->getElement())); + + int vertices = mesh->getGeo(VERTEX); + + while (neigh != el) { + for (j = 0; j < vertices; j++) + if (neigh->getDOF(j) == edge[0]) break; + for (k = 0; k < vertices; k++) + if (neigh->getDOF(k) == edge[1]) break; + + + if(j > 3 || k > 3) { + for (j = 0; j < vertices; j++) + if (mesh->associated(neigh->getDOF(j, 0), edge[0][0])) break; + for (k = 0; k < vertices; k++) + if (mesh->associated(neigh->getDOF(k, 0), edge[1][0])) break; + + if(j > 3 || k > 3) { + for (j = 0; j < vertices; j++) + if (mesh->indirectlyAssociated(neigh->getDOF(j, 0), edge[0][0])) break; + for (k = 0; k < vertices; k++) + if (mesh->indirectlyAssociated(neigh->getDOF(k, 0), edge[1][0])) break; + + TEST_EXIT(j < vertices && k < vertices) + ("dof %d or dof %d not found on element %d with nodes (%d %d %d %d)\n", + edge[0][0], edge[1][0], neigh->getIndex(), neigh->getDOF(0,0), + neigh->getDOF(1,0), neigh->getDOF(2,0), neigh->getDOF(3,0)); + + } + } + + // LeafDataPeriodic *pd = + // dynamic_cast<LeafDataPeriodic*>(el->getElementData(PERIODIC)); + + // if(pd) { + // ::std::list<LeafDataPeriodic::PeriodicInfo>::iterator it; + // ::std::list<LeafDataPeriodic::PeriodicInfo>::iterator end = + // pd->getInfoList().end(); + + // for(it = pd->getInfoList().begin(); it != end; ++it) { + // if(it->periodicMode != 0) { + // PeriodicBC *periodicCondition = mesh->getPeriodicBCMap()[it->type]; + // if(periodicCondition) { + // VertexVector *associated = mesh->getPeriodicAssociations()[it->type]; + // for (j = 0; j < vertices; j++) + // if (neigh->getDOF(j, 0) == (*associated)[edge[0][0]]) break; + // for (k = 0; k < vertices; k++) + // if (neigh->getDOF(k, 0) == (*associated)[edge[1][0]]) break; + + // TEST_EXIT(j < vertices && k < vertices) + // ("dof %d or dof %d not found on element %d with nodes (%d %d %d %d)\n", + // edge[0][0], edge[1][0], neigh->getIndex(), neigh->getDOF(0,0), + // neigh->getDOF(1,0), neigh->getDOF(2,0), neigh->getDOF(3,0)); + + // } else { + // ERROR_EXIT("???\n"); + // } + // } + // } + // } + + TEST_EXIT(j < mesh->getGeo(VERTEX) && + k < mesh->getGeo(VERTEX)) + ("dof %d or dof %d not found on element %d with nodes (%d %d %d %d)\n", + edge[0][0], edge[1][0], neigh->getIndex(), neigh->getDOF(0,0), + neigh->getDOF(1,0), neigh->getDOF(2,0), neigh->getDOF(3,0)); + + if ((edge_no = Tetrahedron::edgeOfDOFs[j][k])) + { + /****************************************************************************/ + /* neigh has not a compatible refinement edge */ + /****************************************************************************/ + neigh->setMark(max(neigh->getMark(), 1)); + neigh_info = refineFunction(neigh_info); + + /****************************************************************************/ + /* now, go to a child at the edge and determine the opposite vertex for */ + /* this child; continue the looping around the edge with this element */ + /****************************************************************************/ + + neigh_info = stack->traverseNext(neigh_info); + neigh_el_type = dynamic_cast<ElInfo3d*>(neigh_info)->getType(); + + switch (edge_no) + { + case 1: + opp_v = opp_v == 1 ? 3 : 2; + break; + case 2: + opp_v = opp_v == 2 ? 1 : 3; + break; + case 3: + neigh_info = stack->traverseNext(neigh_info); + neigh_el_type = dynamic_cast<ElInfo3d*>(neigh_info)->getType(); + if (neigh_el_type != 1) + opp_v = opp_v == 0 ? 3 : 2; + else + opp_v = opp_v == 0 ? 3 : 1; + break; + case 4: + neigh_info = stack->traverseNext(neigh_info); + neigh_el_type = dynamic_cast<ElInfo3d*>(neigh_info)->getType(); + if (neigh_el_type != 1) + opp_v = opp_v == 0 ? 3 : 1; + else + opp_v = opp_v == 0 ? 3 : 2; + break; + case 5: + if (neigh_el_type != 1) + { + neigh_info = stack->traverseNext(neigh_info); + neigh_el_type = (dynamic_cast<ElInfo3d*>(neigh_info))->getType(); + } + opp_v = 3; + break; + } + neigh = dynamic_cast<Tetrahedron*>(const_cast<Element*>( neigh_info->getElement())); + } + else + { + /****************************************************************************/ + /* neigh is compatible devisible; put neigh to the list of patch elements; */ + /* go to next neighbour */ + /****************************************************************************/ + TEST_EXIT(*n_neigh < mesh->getMaxEdgeNeigh()) + ("too many neighbours %d in refine patch\n", *n_neigh); + + + refineList->setElement(*n_neigh, neigh); + refineList->setElType(*n_neigh, neigh_el_type); + + /****************************************************************************/ + /* we have to go back to the starting element via opp_v values */ + /* correct information is produce by get_neigh_on_patch() */ + /****************************************************************************/ + refineList->setOppVertex(*n_neigh, 0, opp_v); + + ++*n_neigh; + + if (opp_v != 3) + i = 3; + else + i = 2; + + if (neigh_info->getNeighbour(i)) + { + opp_v = neigh_info->getOppVertex(i); + neigh_info = stack->traverseNeighbour3d(neigh_info, i); + neigh_el_type = (dynamic_cast<ElInfo3d*>(neigh_info))->getType(); + neigh = dynamic_cast<Tetrahedron*>(const_cast<Element*>( neigh_info->getElement())); + } + else + break; + } + } + + if (neigh == el) + { + (*el_info) = neigh_info; + return(0); + } + + /****************************************************************************/ + /* the domain's boundary is reached; loop back to the starting el */ + /****************************************************************************/ + + i = *n_neigh-1; + opp_v = refineList->getOppVertex(i, 0); + do + { + TEST_EXIT(neigh_info->getNeighbour(opp_v) && i > 0) + ("while looping back domains boundary was reached or i == 0\n"); + opp_v = refineList->getOppVertex(i--, 0); + neigh_info = stack->traverseNeighbour3d(neigh_info, opp_v); + } while(neigh_info->getElement() != el); + (*el_info) = neigh_info; + + return(1); + } + + + ElInfo* RefinementManager3d::refineFunction(ElInfo* el_info) + { + FUNCNAME("RefinementManager3d::refineFunction()"); + int n_neigh, bound = false; + DegreeOfFreedom *edge[2]; + RCNeighbourList *ref_list; + + if (el_info->getElement()->getMark() <= 0) + return(el_info); /* element may not be refined */ + + /****************************************************************************/ + /* get memory for a list of all elements at the refinement edge */ + /****************************************************************************/ + ref_list = NEW RCNeighbourList(mesh->getMaxEdgeNeigh()); + ref_list->setElType(0, (dynamic_cast<ElInfo3d*>(el_info))->getType()); + ref_list->setElement(0, el_info->getElement()); + n_neigh = 1; + + /****************************************************************************/ + /* give the refinement edge the right orientation */ + /****************************************************************************/ + + if (el_info->getElement()->getDOF(0,0) < el_info->getElement()->getDOF(1,0)) + { + edge[0] = const_cast<int*>( el_info->getElement()->getDOF(0)); + edge[1] = const_cast<int*>( el_info->getElement()->getDOF(1)); + } + else + { + edge[1] = const_cast<int*>( el_info->getElement()->getDOF(0)); + edge[0] = const_cast<int*>( el_info->getElement()->getDOF(1)); + } + + /****************************************************************************/ + /* get the refinement patch */ + /****************************************************************************/ + // MSG("index %d\n", el_info->getElement()->getIndex()); + if (getRefinePatch(&el_info, edge, 0, ref_list, &n_neigh)) + { + /****************************************************************************/ + /* domain's boundary was reached while looping around the refinement edge */ + /****************************************************************************/ + getRefinePatch(&el_info, edge, 1, ref_list, &n_neigh); + bound = true; + } + + /****************************************************************************/ + /* fill neighbour information inside the patch in the refinement list */ + /****************************************************************************/ + ref_list->getNeighOnPatch(n_neigh, bound); + + // ========================================================================== + // === check for periodic boundary ========================================== + // ========================================================================== + + DegreeOfFreedom *next_edge[2]; + DegreeOfFreedom *first_edge[2] = {edge[0], edge[1]}; + DegreeOfFreedom *last_edge[2] = {NULL, NULL}; + int n_neigh_periodic; + + DegreeOfFreedom newDOF = -1; + DegreeOfFreedom lastNewDOF = -1; + DegreeOfFreedom firstNewDOF = -1; + + RCNeighbourList *periodicList; + ::std::map<int, VertexVector*>::iterator it; + ::std::map<int, VertexVector*>::iterator end = mesh->getPeriodicAssociations().end(); + + // for(int i = 0; i < n_neigh; i++) { + // MSG("%d ", ref_list->getElement(i)->getIndex()); + // } + // MSG("\n"); + + while(edge[0] != NULL) { + periodicList = ref_list->periodicSplit(edge, + next_edge, + &n_neigh, + &n_neigh_periodic); + + TEST_EXIT(periodicList)("periodicList = NULL\n"); + + newDOF = + refinePatch(edge, periodicList, n_neigh_periodic, bound); + + if(firstNewDOF == -1) { + firstNewDOF = newDOF; + } + + if(lastNewDOF != -1) { + for(it = mesh->getPeriodicAssociations().begin(); it != end; ++it) { + if(it->second) { + if(((*(it->second))[edge[0][0]] == last_edge[0][0] && + (*(it->second))[edge[1][0]] == last_edge[1][0]) || + ((*(it->second))[edge[0][0]] == last_edge[1][0] && + (*(it->second))[edge[1][0]] == last_edge[0][0])) + { + (*(it->second))[lastNewDOF] = newDOF; + (*(it->second))[newDOF] = lastNewDOF; + } + } + } + } + lastNewDOF = newDOF; + + last_edge[0] = edge[0]; + last_edge[1] = edge[1]; + + edge[0] = next_edge[0]; + edge[1] = next_edge[1]; + } + + if(lastNewDOF != firstNewDOF) { + for(it = mesh->getPeriodicAssociations().begin(); it != end; ++it) { + if(it->second) { + if(((*(it->second))[first_edge[0][0]] == last_edge[0][0] && + (*(it->second))[first_edge[1][0]] == last_edge[1][0]) || + ((*(it->second))[first_edge[0][0]] == last_edge[1][0] && + (*(it->second))[first_edge[1][0]] == last_edge[0][0])) + { + (*(it->second))[lastNewDOF] = firstNewDOF; + (*(it->second))[firstNewDOF] = lastNewDOF; + } + } + } + } + + + /****************************************************************************/ + /* and now refine the patch */ + /****************************************************************************/ + //refinePatch(edge, ref_list, n_neigh, bound); + + stack->update(); + + DELETE ref_list; + + return(el_info); + } + +} diff --git a/AMDiS/src/RefinementManager3d.h b/AMDiS/src/RefinementManager3d.h new file mode 100644 index 0000000000000000000000000000000000000000..0707a8047c309711abcd9710392d441909e819ff --- /dev/null +++ b/AMDiS/src/RefinementManager3d.h @@ -0,0 +1,107 @@ +// ============================================================================ +// == == +// == AMDiS - Adaptive multidimensional simulations == +// == == +// ============================================================================ +// == == +// == crystal growth group == +// == == +// == Stiftung caesar == +// == Ludwig-Erhard-Allee 2 == +// == 53175 Bonn == +// == germany == +// == == +// ============================================================================ +// == == +// == http://www.caesar.de/cg/AMDiS == +// == == +// ============================================================================ + +/** \file RefinementManager3d.h */ + +#ifndef AMDIS_REFINEMENT_MANAGER_3D_H +#define AMDIS_REFINEMENT_MANAGER_3D_H + +#include "MemoryManager.h" + +namespace AMDiS { + + // ============================================================================ + // ===== class RefinementManager3d ============================================ + // ============================================================================ + + /** \ingroup Adaption + * \brief + * Implements a RefinementManager for 3-dimensional meshes. + */ + class RefinementManager3d : public RefinementManager + { + public: + MEMORY_MANAGED(RefinementManager3d); + + /** \brief + * Calls base class constructor. + */ + RefinementManager3d() + : RefinementManager() + {}; + + /** \brief + * destructor + */ + virtual ~RefinementManager3d() {}; + + protected: + /** \brief + * Used by \ref setNewCoords + */ + int newCoordsFct(ElInfo *el_info); + + /** \brief + * Implements RefinementManager::setNewCoords + */ + void setNewCoords(); + + /** \brief + * gets the elements around the refinement edge with vertices node[0] and + * node[1] ; refines those elements at this edge are not compatible + * devisible; + * dir determines the direction of the first neighbour + * get_refine_patch returns 1 if the domain's boundary is reached while + * looping around the refinement edge, otherwise 0 + */ + int getRefinePatch(ElInfo **el_info, DegreeOfFreedom *edge[2], int dir, + RCNeighbourList* refineList, int *n_neigh); + + /** \brief + * Refines all elements in the patch. + */ + DegreeOfFreedom refinePatch(DegreeOfFreedom *edge[2], RCNeighbourList* refineList, + int n_neigh, bool bound); + + /** \brief + * Implements RefinementManager::refineFunction. + */ + ElInfo* refineFunction(ElInfo* el_info); + + /** \brief + * Refines one Tetrahedron. + */ + void bisectTetrahedron(RCNeighbourList* refineList, int index, + DegreeOfFreedom *dof[3], DegreeOfFreedom *edge[2]); + + /** \brief + * Used by \ref bisectTetrahedron + */ + void fillPatchConnectivity(RCNeighbourList* ref_list, int index); + + private: + /** \brief + * Refinement patch + */ + static RCNeighbourList* refList; + }; + +} + +#endif // AMDIS_REFINEMENT_MANAGER_3D_H diff --git a/AMDiS/src/RobinBC.cc b/AMDiS/src/RobinBC.cc new file mode 100644 index 0000000000000000000000000000000000000000..0b88b951e68ef80a92f14cb50b034bb39915b1d2 --- /dev/null +++ b/AMDiS/src/RobinBC.cc @@ -0,0 +1,347 @@ +#include "RobinBC.h" +#include "Estimator.h" +#include "Assembler.h" +#include "DOFVector.h" +#include "DOFMatrix.h" +#include "SurfaceOperator.h" +#include <math.h> + +namespace AMDiS { + + RobinBC::RobinBC(BoundaryType type, + AbstractFunction<double, WorldVector<double> > *j, + AbstractFunction<double, WorldVector<double> > *alpha, + FiniteElemSpace *rowFESpace_, + FiniteElemSpace *colFESpace_) + : BoundaryCondition(type, rowFESpace_, colFESpace_), + neumannOperators(NULL), + robinOperators(NULL) + //matrix(dofMatrix) + { + int i, k, dim = rowFESpace->getMesh()->getDim(); + + // create barycentric coords for each vertex of each side + const Element *refElement = Global::getReferenceElement(dim); + + coords = new VectorOfFixVecs<DimVec<double> >*[dim+1]; + + // for all element sides + for(i=0; i < dim+1; i++) { + coords[i] = + NEW VectorOfFixVecs<DimVec<double> >(dim, + dim, + DEFAULT_VALUE, + DimVec<double>(dim, + DEFAULT_VALUE, + 0.0)); + // for each vertex of the side + for(k=0; k < dim; k++) { + int index = + refElement->getVertexOfPosition(INDEX_OF_DIM(dim-1, dim), i, k); + (*coords[i])[k][index] = 1.0; + } + } + + if(j) { + Operator *jOp = NEW Operator(Operator::VECTOR_OPERATOR, rowFESpace); + jOp->addZeroOrderTerm(new CoordsAtQP_ZOT(j)); + neumannOperators = NEW DimVec<SurfaceOperator*>(dim, NO_INIT); + + for(i=0; i < dim+1; i++) { + (*neumannOperators)[i] = NEW SurfaceOperator(jOp, *coords[i]); + } + + DELETE jOp; + } + + if(alpha) { + Operator *alphaOp = NEW Operator(Operator::MATRIX_OPERATOR, + rowFESpace, colFESpace); + alphaOp->addZeroOrderTerm(new CoordsAtQP_ZOT(alpha)); + robinOperators = NEW DimVec<SurfaceOperator*>(dim, NO_INIT); + + for(i=0; i < dim + 1; i++) { + (*robinOperators)[i] = NEW SurfaceOperator(alphaOp, *coords[i]); + } + + DELETE alphaOp; + } + } + + RobinBC::RobinBC(BoundaryType type, + DOFVectorBase<double> *j, + DOFVectorBase<double> *alpha, + FiniteElemSpace *rowFESpace_, + FiniteElemSpace *colFESpace_) + : BoundaryCondition(type, rowFESpace_, colFESpace_), + neumannOperators(NULL), + robinOperators(NULL) + //matrix(dofMatrix) + { + int i, k, dim = rowFESpace->getMesh()->getDim(); + + // create barycentric coords for each vertex of each side + const Element *refElement = Global::getReferenceElement(dim); + + coords = new VectorOfFixVecs<DimVec<double> >*[dim+1]; + + // for all element sides + for(i=0; i < dim+1; i++) { + coords[i] = + NEW VectorOfFixVecs<DimVec<double> >(dim, + dim, + DEFAULT_VALUE, + DimVec<double>(dim, + DEFAULT_VALUE, + 0.0) + ); + // for each vertex of the side + for(k=0; k < dim; k++) { + int index = + refElement->getVertexOfPosition(INDEX_OF_DIM(dim-1, dim), i, k); + (*coords[i])[k][index] = 1.0; + } + } + + if(j) { + Operator *jOp = NEW Operator(Operator::VECTOR_OPERATOR, rowFESpace); + jOp->addZeroOrderTerm(new VecAtQP_ZOT(j, NULL)); + neumannOperators = NEW DimVec<SurfaceOperator*>(dim, NO_INIT); + + for(i=0; i < dim+1; i++) { + (*neumannOperators)[i] = NEW SurfaceOperator(jOp, *coords[i]); + } + + DELETE jOp; + } + + if(alpha) { + Operator *alphaOp = NEW Operator(Operator::MATRIX_OPERATOR, + rowFESpace, colFESpace); + alphaOp->addZeroOrderTerm(new VecAtQP_ZOT(alpha, NULL)); + robinOperators = NEW DimVec<SurfaceOperator*>(dim, NO_INIT); + + for(i=0; i < dim + 1; i++) { + (*robinOperators)[i] = NEW SurfaceOperator(alphaOp, *coords[i]); + } + + DELETE alphaOp; + } + } + + RobinBC::RobinBC(BoundaryType type, + Operator* jOp, Operator* alphaOp, + FiniteElemSpace *rowFESpace_, + FiniteElemSpace *colFESpace_) + : BoundaryCondition(type, rowFESpace_, colFESpace_), + neumannOperators(NULL), + robinOperators(NULL) + //matrix(dofMatrix) + { + int i, k, dim = rowFESpace->getMesh()->getDim(); + + // create barycentric coords for each vertex of each side + const Element *refElement = Global::getReferenceElement(dim); + + coords = new VectorOfFixVecs<DimVec<double> >*[dim+1]; + + // for all element sides + for(i=0; i < dim+1; i++) { + coords[i] = + NEW VectorOfFixVecs<DimVec<double> >(dim, + dim, + DEFAULT_VALUE, + DimVec<double>(dim, + DEFAULT_VALUE, + 0.0)); + // for each vertex of the side + for(k=0; k < dim; k++) { + int index = + refElement->getVertexOfPosition(INDEX_OF_DIM(dim-1, dim), i, k); + (*coords[i])[k][index] = 1.0; + } + } + + neumannOperators = NEW DimVec<SurfaceOperator*>(dim, NO_INIT); + robinOperators = NEW DimVec<SurfaceOperator*>(dim, NO_INIT); + + for(i=0; i < dim + 1; i++) { + if(jOp) + (*neumannOperators)[i] = NEW SurfaceOperator(jOp, *coords[i]); + if(alphaOp) + (*robinOperators)[i] = NEW SurfaceOperator(alphaOp, *coords[i]); + } + } + + void RobinBC::fillBoundaryCondition(DOFVectorBase<double>* vector, + ElInfo* elInfo, + const DegreeOfFreedom* dofIndices, + const BoundaryType* localBound, + int nBasFcts) + { + FUNCNAME("RobinBC::fillBoundaryCondition()"); + TEST_EXIT(vector->getFESpace() == rowFESpace) + ("invalid row fe space\n"); + + int dim = elInfo->getMesh()->getDim(); + int i; + + if(neumannOperators) { + for(i=0; i < dim+1; i++) { + if(elInfo->getBoundary(i) == boundaryType) { + vector->assemble(1.0, elInfo, localBound, (*neumannOperators)[i]); + } + } + } + } + + void RobinBC::fillBoundaryCondition(DOFMatrix* matrix, + ElInfo* elInfo, + const DegreeOfFreedom* dofIndices, + const BoundaryType* localBound, + int nBasFcts) + { + int dim = elInfo->getMesh()->getDim(); + int i; + + if(robinOperators) { + for(i=0; i < dim+1; i++) { + if(elInfo->getBoundary(i) == boundaryType) { + matrix->assemble(-1.0, elInfo, localBound, (*robinOperators)[i]); + } + } + } + } + + double RobinBC::boundResidual(ElInfo *elInfo, + DOFMatrix *matrix, + const DOFVectorBase<double> *dv) + { + FUNCNAME("RobinBC::fillBoundaryCondition()"); + TEST_EXIT(matrix->getRowFESpace() == rowFESpace) + ("invalid row fe space\n"); + TEST_EXIT(matrix->getColFESpace() == colFESpace) + ("invalid col fe space\n"); + + int dim = elInfo->getMesh()->getDim(); + int iq; + DimVec<double> lambda(dim, NO_INIT); + double n_A_grdUh, val = 0.0; + WorldVector<double> normal; + + const DimVec<WorldVector<double> > &Lambda = elInfo->getGrdLambda(); + double det = elInfo->getDet(); + + int numPoints; + + bool neumannQuad = false; + + const BasisFunction *basFcts = dv->getFESpace()->getBasisFcts(); + + TEST_EXIT(basFcts == rowFESpace->getBasisFcts())("invalid basFcts\n"); + + double *uhEl = GET_MEMORY(double, basFcts->getNumber()); + + dv->getLocalVector(elInfo->getElement(), uhEl); + + TEST_EXIT(neumannOperators || robinOperators) + ("neither neumann nor robin operators set!\n"); + + if(!robinOperators) + neumannQuad = true; + else { + if(neumannOperators) { + if((*neumannOperators)[0]->getAssembler()-> + getZeroOrderAssembler()->getQuadrature()->getNumPoints() > + (*robinOperators)[0]->getAssembler()-> + getZeroOrderAssembler()->getQuadrature()->getNumPoints()) + { + neumannQuad = true; + } + } + } + + Quadrature *quadrature = NULL; + + int face; + + ::std::vector<Operator*>::iterator op; + for(op=matrix->getOperatorsBegin(); op != matrix->getOperatorsEnd(); ++op) { + (*op)->getAssembler()->initElement(elInfo); + } + + for(face = 0; face < dim+1; face++) { + + elInfo->getNormal(face, normal); + + quadrature = + neumannQuad ? + (*neumannOperators)[face]->getAssembler()-> + getZeroOrderAssembler()->getQuadrature() : + (*robinOperators)[face]->getAssembler()-> + getZeroOrderAssembler()->getQuadrature(); + + numPoints = quadrature->getNumPoints(); + + if(elInfo->getBoundary(face) == boundaryType) { + + (*neumannOperators)[face]->getAssembler()->getZeroOrderAssembler()-> + initElement(elInfo); + + //const double *uhAtQp = quadrature->uhAtQp(basFcts, uhEl, NULL); + const double *uhAtQp = dv->getVecAtQPs(elInfo, + quadrature, + NULL, + NULL); + + double *f = GET_MEMORY(double, numPoints); + for (iq = 0; iq < numPoints; iq++) { + f[iq] = 0.0; + } + + if(robinOperators) { + (*robinOperators)[face]->evalZeroOrder(numPoints, + uhAtQp, + NULL, + NULL, + f, + 1.0); + } + + WorldVector<double> *grdUh = NEW WorldVector<double>[numPoints]; + WorldVector<double> *A_grdUh = NEW WorldVector<double>[numPoints]; + + for (iq = 0; iq < numPoints; iq++) { + A_grdUh[iq].set(0.0); + lambda = quadrature->getLambda(iq); + basFcts->evalGrdUh(lambda, Lambda, uhEl, &grdUh[iq]); + } + + for(op=matrix->getOperatorsBegin(); op != matrix->getOperatorsEnd(); ++op) { + (*op)->weakEvalSecondOrder(numPoints, + grdUh, + A_grdUh); + } + + + if(neumannOperators) + (*neumannOperators)[face]->getC(elInfo, numPoints, f); + + for (val = iq = 0; iq < numPoints; iq++) { + n_A_grdUh = (normal*A_grdUh[iq]) - f[iq]; + val += quadrature->getWeight(iq)*sqr(n_A_grdUh); + } + + DELETE [] grdUh; + DELETE [] A_grdUh; + + FREE_MEMORY(f, double, numPoints); + } + } + + FREE_MEMORY(uhEl, double, basFcts->getNumber()); + + return det * val; + } + +} diff --git a/AMDiS/src/RobinBC.h b/AMDiS/src/RobinBC.h new file mode 100644 index 0000000000000000000000000000000000000000..5f910a39c514bb64d14febd72e208591d5af061a --- /dev/null +++ b/AMDiS/src/RobinBC.h @@ -0,0 +1,128 @@ +// ============================================================================ +// == == +// == AMDiS - Adaptive multidimensional simulations == +// == == +// ============================================================================ +// == == +// == crystal growth group == +// == == +// == Stiftung caesar == +// == Ludwig-Erhard-Allee 2 == +// == 53175 Bonn == +// == germany == +// == == +// ============================================================================ +// == == +// == http://www.caesar.de/cg/AMDiS == +// == == +// ============================================================================ + +/** \file RobinBC.h */ + +#ifndef AMDIS_ROBINBC_H +#define AMDIS_ROBINBC_H + +#include "BoundaryCondition.h" +#include "AbstractFunction.h" +#include "DOFMatrix.h" + +namespace AMDiS { + + class SurfaceOperator; + + // ============================================================================ + // ===== class RobinBC ======================================================== + // ============================================================================ + + /** + * \ingroup Assembler + * + * \brief + * Sub class of BoundaryCondition. Implements Robin and Neumann boundary conditions. + * The flux in normal direction is given by \f$ j = j_0 + \alpha u\f$ where + * \f$ j_0 \f$ and \f$ alpha \f$ are functions evaluated at world coordinates + * and \f$ u \f$ is the problem solution. + */ + class RobinBC : public BoundaryCondition + { + public: + /** \brief + * Constructor. \f$ j \f$ and \f$ alpha \f$ are given as AbstractFunction + * objects. + */ + RobinBC(BoundaryType type, + AbstractFunction<double, WorldVector<double> > *j, + AbstractFunction<double, WorldVector<double> > *alpha, + FiniteElemSpace *rowFESpace, + FiniteElemSpace *colFESpace = NULL); + + /** \brief + * Constructor. \f$ j \f$ and \f$ alpha \f$ are given as DOFVectors. + */ + RobinBC(BoundaryType type, + DOFVectorBase<double> *j, + DOFVectorBase<double> *alpha, + FiniteElemSpace *rowFESpace, + FiniteElemSpace *colFESpace = NULL); + + /** \brief + * Constructor. \f$ j \f$ and \f$ alpha \f$ are given as Operator objects. + */ + RobinBC(BoundaryType type, + Operator* jOp, Operator* alphaOp, + FiniteElemSpace *rowFESpace, + FiniteElemSpace *colFESpace = NULL); + + /** \brief + * Implements BoundaryCondition::fillBoundaryCondition(); + */ + virtual void fillBoundaryCondition(DOFMatrix* matrix, + ElInfo* elInfo, + const DegreeOfFreedom* dofIndices, + const BoundaryType* localBound, + int nBasFcts); + + /** \brief + * Implements BoundaryCondition::fillBoundaryCondition(); + */ + virtual void fillBoundaryCondition(DOFVectorBase<double>* vector, + ElInfo* elInfo, + const DegreeOfFreedom* dofIndices, + const BoundaryType* localBound, + int nBasFcts); + + /** \brief + * Implements BoundaryCondition::boundResidual(); + */ + virtual double boundResidual(ElInfo *elInfo, + DOFMatrix *matrix, + const DOFVectorBase<double> *dv); + + protected: + /** \brief + * Surface operators for each element side for the Neumann part. + */ + DimVec<SurfaceOperator*>* neumannOperators; + + /** \brief + * Surface operators for each element side for the Robin part. + */ + DimVec<SurfaceOperator*>* robinOperators; + + VectorOfFixVecs<DimVec<double> >**coords; + }; + + class NeumannBC : public RobinBC + { + public: + NeumannBC(BoundaryType type, + AbstractFunction<double, WorldVector<double> > *j, + FiniteElemSpace *rowFESpace, + FiniteElemSpace *colFESpace = NULL) + : RobinBC(type, j, NULL, rowFESpace, colFESpace) + {}; + }; + +} + +#endif diff --git a/AMDiS/src/RobinBC.hh b/AMDiS/src/RobinBC.hh new file mode 100644 index 0000000000000000000000000000000000000000..883a1331bfff3ff912eacec69b6dbb8b95a0ad46 --- /dev/null +++ b/AMDiS/src/RobinBC.hh @@ -0,0 +1,135 @@ +#include "Estimator.h" +#include "Assembler.h" + +template<typename T> +void RobinBC<T>::fillLocalBC(DOFVector<T>* vector, + ElInfo* elInfo, + const DegreeOfFreedom* dofIndices, + const BoundaryType* localBound, + int nBasFcts) +{ + int dim = elInfo->getMesh()->getDim(); + int i; + + if(neumannOperators) { + for(i=0; i < dim+1; i++) { + if(elInfo->getBoundOfBoundary(i) == boundaryType) { + vector->assemble(1.0, elInfo, localBound, (*neumannOperators)[i]); + } + } + } +} + +template<typename T> +void RobinBC<T>::fillLocalBC(DOFMatrix* matrix, + ElInfo* elInfo, + const DegreeOfFreedom* dofIndices, + const BoundaryType* localBound, + int nBasFcts) +{ + int dim = elInfo->getMesh()->getDim(); + int i; + + if(robinOperators) { + for(i=0; i < dim+1; i++) { + if(elInfo->getBoundOfBoundary(i) == boundaryType) { + matrix->assemble(-1.0, elInfo, localBound, (*robinOperators)[i]); + } + } + } +} + +template<typename T> +double RobinBC<T>::boundResidual(ElInfo *elInfo, Estimator<T> *estimator) +{ + int dim = elInfo->getMesh()->getDim(); + int i, j, iq; + DimVec<double> lambda(dim, NO_INIT); + double n_A_grdUh, val, f; + WorldVector normal, grdUh, A_grdUh; + + const DimVec<WorldVector> &Lambda = elInfo->getGrdLambda(); + double det = elInfo->getDet(); + + int numPoints; + int dow = Global::getGeo(WORLD); + + bool neumannQuad = false; + + TEST_EXIT(neumannOperators || robinOperators) + ("neither neumann nor robin operators set!\n"); + + if(!robinOperators) + neumannQuad = true; + else { + if(neumannOperators) { + if((*neumannOperators)[0]->getAssembler()-> + getZeroOrderAssembler()->getQuadrature()->getNumPoints() > + (*robinOperators)[0]->getAssembler()-> + getZeroOrderAssembler()->getQuadrature()->getNumPoints()) + { + neumannQuad = true; + } + } + } + + Quadrature *quadrature = NULL; + + int face; + for(face = 0; face < dim+1; face++) { + + elInfo->getNormal(face, normal); + + quadrature = + neumannQuad ? + (*neumannOperators)[face]->getAssembler()-> + getZeroOrderAssembler()->getQuadrature() : + (*robinOperators)[face]->getAssembler()-> + getZeroOrderAssembler()->getQuadrature(); + + numPoints = quadrature->getNumPoints(); + + if(elInfo->getBoundOfBoundary(face) == boundaryType) { + + (*neumannOperators)[face]->getAssembler()->getZeroOrderAssembler()-> + initElement(elInfo); + + for (val = iq = 0; iq < numPoints; iq++) { + lambda = quadrature->getLambda(iq); + + estimator->bas_fcts->evalGrdUh(lambda, Lambda, estimator->uhEl, &grdUh); + + if (estimator->isDiag) { + for (i = 0; i < dow; i++) + A_grdUh[i] = (*(estimator->A))[i][i]*grdUh[i]; + } else { + for (i = 0; i < dow; i++) + for (A_grdUh[i] = j = 0; j < dow; j++) + A_grdUh[i] += (*(estimator->A))[i][j]*grdUh[j]; + } + + f = 0.0; + + if(robinOperators) { + double uhAtQp = 0.0; + for(i=0; i < estimator->bas_fcts->getNumber(); i++) + uhAtQp += estimator->uhEl[i]* + (*(estimator->bas_fcts->getPhi(i)))(lambda); + (*robinOperators)[face]->evalZeroOrder(elInfo, iq, &f); + f *= uhAtQp; + } + + if(neumannOperators) + (*neumannOperators)[face]->evalZeroOrder(elInfo, iq, &f); + + n_A_grdUh = (normal*A_grdUh) - f; + val += quadrature->getWeight(iq)*sqr(n_A_grdUh); + } + } + } + + if (estimator->norm == NO_NORM || estimator->norm == L2_NORM) + return(estimator->C1*estimator->h2_from_det(det, dim)*det*val); + else + return(estimator->C1*det*val); +} diff --git a/AMDiS/src/SMIAdapter.cc b/AMDiS/src/SMIAdapter.cc new file mode 100644 index 0000000000000000000000000000000000000000..512b2c7f2365457ddc17b0c74fdf046418a0de66 --- /dev/null +++ b/AMDiS/src/SMIAdapter.cc @@ -0,0 +1,675 @@ +#include "SMIAdapter.h" +#include "Mesh.h" +#include "Traverse.h" +#include "ElInfo.h" +#include "Flag.h" +#include "FiniteElemSpace.h" +#include "BasisFunction.h" +#include "DOFVector.h" +#include "DOFAdmin.h" +#include "ElementRegion_ED.h" +#include "SurfaceRegion_ED.h" +#include "Flag.h" + +namespace AMDiS { + + SMIAdapter::SMIAdapter(int smiApplicationId, + int smiMeshId, + FiniteElemSpace *feSpace, + int elementRegion, + int surfaceRegion, + bool (*elementFct)(ElInfo *elInfo), + bool (*surfaceFct)(ElInfo *elInfo, int side)) + : smiApplicationId_(smiApplicationId), + smiMeshId_(smiMeshId), + feSpace_(feSpace), + elementRegion_(elementRegion), + surfaceRegion_(surfaceRegion), + addNeighbourInfo_(false), + newNodeIndex_(NULL), + oldNodeIndex_(NULL), + newElementIndex_(NULL), + oldElementIndex_(NULL), + elementFct_(elementFct), + surfaceFct_(surfaceFct) + { + TEST_EXIT(!surfaceFct_)("surfaceFct not yet supported\n"); + TEST_EXIT(elementFct_ == NULL || elementRegion_ == -1) + ("don't use elementRegion AND elementFct\n"); + + Mesh *mesh = feSpace_->getMesh(); + int dim = mesh->getDim(); + + if(surfaceRegion > -1) { + dim -= 1; + } + + TEST_EXIT(dim > 0 && dim < 4)("invalid dim\n"); + + elementType_ = dim * 10 + 1; // linear elements only + + int smiError = SMI_Add_application(smiApplicationId_, + SMI_APP_MODE_DEFAULT); + + smiError = SMI_Add_mesh(smiApplicationId_, + smiMeshId_, SMI_MESH_MODE_DEFAULT); + + TEST_EXIT(smiError == SMI_OK) + ("SMI_Add_mesh() failed with error %d\n", smiError); + + smiError = SMI_Begin_write_transaction(smiApplicationId_, + smiMeshId_); + + TEST_EXIT(smiError == SMI_OK) + ("SMI_Begin_modification() failed with error %d\n", smiError); + + smiError = SMI_Add_elem_type(smiApplicationId_, + smiMeshId_, + elementType_, + dim + 1); + + TEST_EXIT(smiError == SMI_OK) + ("SMI_Add_elem_type() failed with error %d\n", smiError); + + smiError = SMI_End_write_transaction(smiApplicationId_, + smiMeshId_); + + TEST_EXIT(smiError == SMI_OK) + ("SMI_End_modification() failed with error %d\n", smiError); + } + + void SMIAdapter::addQuantity(int quantityId, DOFVector<double> *dofVector) { + TEST_EXIT(dofVectors_[quantityId].size() == 0) + ("quantityId already added\n"); + + dofVectors_[quantityId].push_back(dofVector); + + static double defaultValue = 0.0; + + int smiError; + + smiError = SMI_Begin_write_transaction(smiApplicationId_, + smiMeshId_); + + TEST_EXIT(smiError == SMI_OK) + ("SMI_Begin_modification() failed with error %d\n", smiError); + + smiError = SMI_Add_quantity(smiApplicationId_, + smiMeshId_, + quantityId, + SMI_LOC_NODE, + SMI_TYPE_DOUBLE, + 1, + &defaultValue); + + TEST_EXIT(smiError == SMI_OK) + ("SMI_Add_quantity faild with error %d\n", smiError); + + smiError = SMI_End_write_transaction(smiApplicationId_, + smiMeshId_); + + TEST_EXIT(smiError == SMI_OK) + ("SMI_End_modification() failed with error %d\n", smiError); + } + + void SMIAdapter::addQuantity(int quantityId, + int quantityDim, + DOFVector<double> **dofVector) + { + TEST_EXIT(dofVectors_[quantityId].size() == 0) + ("quantityId already added\n"); + + dofVectors_[quantityId].resize(quantityDim); + + int comp; + for(comp = 0; comp < quantityDim; comp++) { + dofVectors_[quantityId][comp] = dofVector[comp]; + } + + TEST_EXIT(quantityDim < 4)("quantityDim > 3\n"); + + static double defaultValue[3] = {0.0, 0.0, 0.0}; + + int smiError; + + smiError = SMI_Begin_write_transaction(smiApplicationId_, + smiMeshId_); + + TEST_EXIT(smiError == SMI_OK) + ("SMI_Begin_modification() failed with error %d\n", smiError); + + smiError = SMI_Add_quantity(smiApplicationId_, + smiMeshId_, + quantityId, + SMI_LOC_NODE, + SMI_TYPE_DOUBLE, + quantityDim, + defaultValue); + + TEST_EXIT(smiError == SMI_OK) + ("SMI_Add_quantity faild with error %d\n", smiError); + + smiError = SMI_End_write_transaction(smiApplicationId_, + smiMeshId_); + + TEST_EXIT(smiError == SMI_OK) + ("SMI_End_modification() failed with error %d\n", smiError); + } + + void SMIAdapter::transferMeshToSMI() + { + int smiError = SMI_Begin_write_transaction(smiApplicationId_, + smiMeshId_); + + TEST_EXIT(smiError == SMI_OK) + ("SMI_Begin_modification() failed with error %d\n", smiError); + + smiError = SMI_Clear_mesh(smiApplicationId_, + smiMeshId_); + + TEST_EXIT(smiError == SMI_OK) + ("SMI_Clear_mesh() failed with error %d\n", smiError); + + int i, j; + Mesh *mesh = feSpace_->getMesh(); + int dim = mesh->getDim(); + DOFAdmin *admin = feSpace_->getAdmin(); + const BasisFunction *basFcts = feSpace_->getBasisFcts(); + int numBasFcts = basFcts->getNumber(); + + Element *element; + ElementData *elementData; + ElementData *regionData; + int region; + int side; + int numNewNodes; + int numNodes; + bool validElement; + double *nodeCoords = GET_MEMORY(double, numBasFcts * dim); + + DOFVector<char> alreadyAdded(feSpace_, "already added nodes"); + alreadyAdded.set(0); + + int elementCounter[1] = { 0 }; + int elementIndex; + + DimVec<double> *bary = NULL; + const WorldVector<double> *world = NULL; + + const DegreeOfFreedom *elementDofs = NULL; + DegreeOfFreedom dof; + DegreeOfFreedom *nodeIndices = GET_MEMORY(int, numBasFcts); + DegreeOfFreedom *newNodeIndices = GET_MEMORY(int, numBasFcts); + + Flag fillFlag = Mesh::CALL_LEAF_EL | Mesh::FILL_COORDS; + + if(addNeighbourInfo_) { + fillFlag |= Mesh::FILL_NEIGH; + } + + TraverseStack stack; + ElInfo *elInfo = stack.traverseFirst(mesh, -1, fillFlag); + + while(elInfo) { + + element = elInfo->getElement(); + elementData = element->getElementData(); + elementDofs = basFcts->getLocalIndices(element, admin, NULL); + + // check element region + if(elementRegion_ > -1) { + regionData = elementData->getElementData(ELEMENT_REGION); + if(regionData) { + region = dynamic_cast<ElementRegion_ED*>(regionData)->getRegion(); + } else { + region = -1; + } + validElement = (region == elementRegion_); + } else { + validElement = true; + } + + if(elementFct_) { + validElement = (*elementFct_)(elInfo); + } + + if(validElement) { + + // check surface region + if(surfaceRegion_ > -1) { + regionData = elementData->getElementData(SURFACE_REGION); + while(regionData) { + region = dynamic_cast<SurfaceRegion_ED*>(regionData)->getRegion(); + + // surface region found ? + if(region == surfaceRegion_) { + // add surface element + side = dynamic_cast<SurfaceRegion_ED*>(regionData)->getSide(); + numNewNodes = 0; + numNodes = 0; + for(i = 0; i < numBasFcts; i++) { + bary = basFcts->getCoords(i); + if((*bary)[side] == 0) { + dof = elementDofs[i]; + + if(newNodeIndex_) { + dof = (*(newNodeIndex_))[dof] - 1; + TEST_EXIT(dof >= 0)("invalid node index\n"); + } + + if(!alreadyAdded[dof]) { + newNodeIndices[numNewNodes] = dof; + world = elInfo->coordToWorld(*bary, NULL); + for(j = 0; j < dim; j++) { + nodeCoords[numNewNodes * dim + j] = (*world)[j]; + } + numNewNodes++; + alreadyAdded[dof] = 1; + } + nodeIndices[numNodes] = dof; + numNodes++; + } + } + + smiError = SMI_Add_nodes(smiApplicationId_, + smiMeshId_, + numNewNodes, + newNodeIndices, + nodeCoords, + dim); + + TEST_EXIT(smiError == SMI_OK) + ("SMI_Add_nodes faild with error %d\n", smiError); + + smiError = SMI_Add_elems(smiApplicationId_, + smiMeshId_, + 1, + &elementType_, + dim+1, + nodeIndices, + elementCounter); + + (elementCounter[0])++; + + TEST_EXIT(smiError == SMI_OK) + ("SMI_Add_elems faild with error %d\n", smiError); + } + regionData = regionData->getDecorated(SURFACE_REGION); + } + } else { + // add volume element + + + numNewNodes = 0; + for(i = 0; i < numBasFcts; i++) { + bary = basFcts->getCoords(i); + dof = elementDofs[i]; + + if(newNodeIndex_) { + dof = (*(newNodeIndex_))[dof] - 1; + TEST_EXIT(dof >= 0)("invalid node index\n"); + } + + if(!alreadyAdded[dof]) { + newNodeIndices[numNewNodes] = dof; + world = elInfo->coordToWorld(*bary, NULL); + for(j = 0; j < dim; j++) { + nodeCoords[numNewNodes * dim + j] = (*world)[j]; + } + numNewNodes++; + alreadyAdded[dof] = 1; + } + } + + smiError = SMI_Add_nodes(smiApplicationId_, + smiMeshId_, + numNewNodes, + newNodeIndices, + nodeCoords, + dim); + + TEST_EXIT(smiError == SMI_OK) + ("SMI_Add_nodes faild with error %d\n", smiError); + + elementIndex = element->getIndex(); + + if(newElementIndex_) { + elementIndex = (*(newElementIndex_))[elementIndex] - 1; + TEST_EXIT(elementIndex >= 0)("invalid element index\n"); + } + + smiError = SMI_Add_elems(smiApplicationId_, + smiMeshId_, + 1, + &elementType_, + dim+1, + const_cast<int*>(elementDofs), + &elementIndex); + + if(addNeighbourInfo_) { + DimVec<int> neighbours(dim, NO_INIT); + DimVec<int> oppVertices(dim, NO_INIT); + for(i = 0; i < dim + 1; i++) { + if(elInfo->getNeighbour(i)) { + neighbours[i] = elInfo->getNeighbour(i)->getIndex(); + if(newElementIndex_) { + neighbours[i] = (*(newElementIndex_))[neighbours[i]] - 1; + TEST_EXIT(neighbours[i] >= 0)("invalid element index\n"); + } + oppVertices[i] = elInfo->getOppVertex(i); + } else { + neighbours[i] = -1; + oppVertices[i] = -1; + } + } + SMI_Set_quantity_values(smiApplicationId_, + smiMeshId_, + SMI_NEIGH_QUANTITY, + SMI_TYPE_INT, + dim+1, + 1, + &elementIndex, + neighbours.getValArray()); + SMI_Set_quantity_values(smiApplicationId_, + smiMeshId_, + SMI_OPP_V_QUANTITY, + SMI_TYPE_INT, + dim+1, + 1, + &elementIndex, + oppVertices.getValArray()); + } + + + (elementCounter[0])++; + + TEST_EXIT(smiError == SMI_OK) + ("SMI_Add_elems faild with error %d\n", smiError); + } + } + + elInfo = stack.traverseNext(elInfo); + } + + FREE_MEMORY(nodeCoords, double, numBasFcts * dim); + FREE_MEMORY(nodeIndices, int, numBasFcts); + FREE_MEMORY(newNodeIndices, int, numBasFcts); + + smiError = SMI_End_write_transaction(smiApplicationId_, + smiMeshId_); + + TEST_EXIT(smiError == SMI_OK) + ("SMI_End_modification() failed with error %d\n", smiError); + } + + void SMIAdapter::transferQuantitiesToSMI(int quantityID) + { + int smiError; + + smiError = SMI_Begin_write_transaction(smiApplicationId_, + smiMeshId_); + + TEST_EXIT(smiError == SMI_OK) + ("SMI_Begin_modification() failed with error %d\n", smiError); + + int numNodes; + int *nodeIndices; + + smiError = SMI_Get_all_nodes(smiApplicationId_, + smiMeshId_, + &numNodes, + &nodeIndices); + + TEST_EXIT(smiError == SMI_OK) + ("SMI_Get_all_nodes() failed with error %d\n", smiError); + + //double *values = GET_MEMORY(double, numNodes); + + if(quantityID == -1) { + ::std::map<int, ::std::vector<DOFVector<double>*> >::iterator quantityIt; + ::std::map<int, ::std::vector<DOFVector<double>*> >::iterator quantityEnd = + dofVectors_.end(); + + for(quantityIt = dofVectors_.begin(); quantityIt != quantityEnd; ++quantityIt) { + int quantityDim = static_cast<int>(quantityIt->second.size()); + + double *values = GET_MEMORY(double, numNodes * quantityDim); + + int i, comp; + for(i = 0; i < numNodes; i++) { + DegreeOfFreedom index = nodeIndices[i]; + if(oldNodeIndex_) { + index = (*(oldNodeIndex_))[index] - 1; + } + for(comp = 0; comp < quantityDim; comp++) { + DOFVector<double> *dofVector = (quantityIt->second)[comp]; + values[i * quantityDim + comp] = (*dofVector)[index]; + } + } + + smiError = SMI_Set_quantity_values(smiApplicationId_, + smiMeshId_, + (*quantityIt).first, + SMI_TYPE_DOUBLE, + quantityDim, + numNodes, + nodeIndices, + values); + + TEST_EXIT(smiError == SMI_OK) + ("SMI_Set_quantity_values() failed with error %d\n", smiError); + + FREE_MEMORY(values, double, numNodes * quantityDim); + } + } else { + int quantityDim = static_cast<int>(dofVectors_[quantityID].size()); + + double *values = GET_MEMORY(double, numNodes * quantityDim); + + int i, comp; + for(i = 0; i < numNodes; i++) { + DegreeOfFreedom index = nodeIndices[i]; + if(oldNodeIndex_) { + index = (*(oldNodeIndex_))[index] - 1; + } + for(comp = 0; comp < quantityDim; comp++) { + DOFVector<double> *dofVector = dofVectors_[quantityID][comp]; + values[i*quantityDim + comp] = (*dofVector)[index]; + } + } + + smiError = SMI_Set_quantity_values(smiApplicationId_, + smiMeshId_, + quantityID, + SMI_TYPE_DOUBLE, + quantityDim, + numNodes, + nodeIndices, + values); + + TEST_EXIT(smiError == SMI_OK) + ("SMI_Set_quantity_values() failed with error %d\n", smiError); + + FREE_MEMORY(values, double, numNodes * quantityDim); + } + + //FREE_MEMORY(values, double, numNodes); + + smiError = SMI_End_write_transaction(smiApplicationId_, + smiMeshId_); + + TEST_EXIT(smiError == SMI_OK) + ("SMI_End_modification() failed with error %d\n", smiError); + } + + void SMIAdapter::getQuantitiesFromSMI(int quantityID) + { + int smiError; + + smiError = SMI_Begin_read_transaction(smiApplicationId_, + smiMeshId_); + + TEST_EXIT(smiError == SMI_OK) + ("SMI_Begin_modification() failed with error %d\n", smiError); + + int numNodes; + int *nodeIndices; + + smiError = SMI_Get_all_nodes(smiApplicationId_, + smiMeshId_, + &numNodes, + &nodeIndices); + + TEST_EXIT(smiError == SMI_OK) + ("SMI_Get_all_nodes() failed with error %d\n", smiError); + + //double *values = GET_MEMORY(double, numNodes); + + if(quantityID == -1) { + ::std::map<int, ::std::vector<DOFVector<double>*> >::iterator quantityIt; + ::std::map<int, ::std::vector<DOFVector<double>*> >::iterator quantityEnd = + dofVectors_.end(); + for(quantityIt = dofVectors_.begin(); quantityIt != quantityEnd; ++quantityIt) { + int quantityDim = static_cast<int>(quantityIt->second.size()); + + double *values = GET_MEMORY(double, numNodes * quantityDim); + + smiError = SMI_Get_quantity_values(smiApplicationId_, + smiMeshId_, + (*quantityIt).first, + SMI_TYPE_DOUBLE, + quantityDim, + numNodes, + nodeIndices, + values); + + TEST_EXIT(smiError == SMI_OK) + ("SMI_Set_quantity_values() failed with error %d\n", smiError); + + int i, comp; + for(i = 0; i < numNodes; i++) { + DegreeOfFreedom index = nodeIndices[i]; + if(oldNodeIndex_) { + index = (*(oldNodeIndex_))[index] - 1; + } + for(comp = 0; comp < quantityDim; comp++) { + DOFVector<double> *dofVector = (quantityIt->second)[comp]; + (*dofVector)[index] = values[i * quantityDim + comp]; + } + } + + FREE_MEMORY(values, double, numNodes * quantityDim); + } + } else { + int quantityDim = static_cast<int>(dofVectors_[quantityID].size()); + + double *values = GET_MEMORY(double, numNodes * quantityDim); + + smiError = SMI_Get_quantity_values(smiApplicationId_, + smiMeshId_, + quantityID, + SMI_TYPE_DOUBLE, + quantityDim, + numNodes, + nodeIndices, + values); + + TEST_EXIT(smiError == SMI_OK) + ("SMI_Set_quantity_values() failed with error %d\n", smiError); + + int i, comp; + for(i = 0; i < numNodes; i++) { + DegreeOfFreedom index = nodeIndices[i]; + if(oldNodeIndex_) { + index = (*(oldNodeIndex_))[index] - 1; + } + for(comp = 0; comp < quantityDim; comp++) { + DOFVector<double> *dofVector = dofVectors_[quantityID][comp]; + (*dofVector)[index] = values[i * quantityDim + comp]; + } + } + + FREE_MEMORY(values, double, numNodes * quantityDim); + } + + //FREE_MEMORY(values, double, numNodes); + + smiError = SMI_End_read_transaction(smiApplicationId_, + smiMeshId_); + + TEST_EXIT(smiError == SMI_OK) + ("SMI_End_modification() failed with error %d\n", smiError); + } + + void SMIAdapter::addNeighbourInfo() + { + TEST_EXIT(surfaceRegion_ == -1) + ("no neighbour info available for surface meshes\n"); + + int dim = feSpace_->getMesh()->getDim(); + + if(SMI_OK != SMI_Get_quantity_info(smiApplicationId_, + smiMeshId_, + SMI_NEIGH_QUANTITY, + NULL, NULL, NULL)) + { + int defaultValue[3] = {-1, -1, -1}; + + SMI_Begin_write_transaction(smiApplicationId_, + smiMeshId_); + + SMI_Add_quantity(smiApplicationId_, + smiMeshId_, + SMI_NEIGH_QUANTITY, + SMI_LOC_ELEM, + SMI_TYPE_INT, + dim+1, + defaultValue); + + SMI_Add_quantity(smiApplicationId_, + smiMeshId_, + SMI_OPP_V_QUANTITY, + SMI_LOC_ELEM, + SMI_TYPE_INT, + dim+1, + defaultValue); + + SMI_End_write_transaction(smiApplicationId_, + smiMeshId_); + } + + addNeighbourInfo_ = true; + } + + void SMIAdapter::getNeighbourInfo(int elementIndex, + int *neighbours, + int *oppVertices) + { + int i, dim = feSpace_->getMesh()->getDim(); + + TEST_EXIT(addNeighbourInfo_)("no neighbour info added\n"); + SMI_Get_quantity_values(smiApplicationId_, + smiMeshId_, + SMI_NEIGH_QUANTITY, + SMI_TYPE_INT, + dim+1, + 1, + &elementIndex, + neighbours); + SMI_Get_quantity_values(smiApplicationId_, + smiMeshId_, + SMI_OPP_V_QUANTITY, + SMI_TYPE_INT, + dim+1, + 1, + &elementIndex, + oppVertices); + + if(oldElementIndex_) { + for(i = 0; i < dim + 1; i++) { + neighbours[i] = (*(oldElementIndex_))[neighbours[i]] - 1; + } + } + } + +} diff --git a/AMDiS/src/SMIAdapter.h b/AMDiS/src/SMIAdapter.h new file mode 100644 index 0000000000000000000000000000000000000000..ea2f1ed3fe466b99d9370a5146e6dbd703663f35 --- /dev/null +++ b/AMDiS/src/SMIAdapter.h @@ -0,0 +1,174 @@ +// ============================================================================ +// == == +// == AMDiS - Adaptive multidimensional simulations == +// == == +// ============================================================================ +// == == +// == crystal growth group == +// == == +// == Stiftung caesar == +// == Ludwig-Erhard-Allee 2 == +// == 53175 Bonn == +// == germany == +// == == +// ============================================================================ +// == == +// == http://www.caesar.de/cg/AMDiS == +// == == +// ============================================================================ + +/** \file SMIAdapter.h */ + +#ifndef AMDIS_SMIADAPTER_H +#define AMDIS_SMIADAPTER_H + +#include "Global.h" +#include "smi.h" +#include "MemoryManager.h" +#include "Flag.h" +#include <map> +#include <vector> + +namespace AMDiS { + + class FiniteElemSpace; + class ElInfo; + template<typename T> class DOFVector; + +#define SMI_NEIGH_QUANTITY 10001 +#define SMI_OPP_V_QUANTITY 20002 + + // ============================================================================ + // ===== class SMIAdapter ===================================================== + // ============================================================================ + + /** \brief + * SMI adapter for an AMDiS mesh. + */ + class SMIAdapter + { + public: + MEMORY_MANAGED(SMIAdapter); + + /** \brief + * constructor + */ + SMIAdapter(int smiApplicationId, + int smiMeshId, + FiniteElemSpace *feSpace, + int elementRegion = -1, + int surfaceRegion = -1, + bool (*elementFct)(ElInfo *elInfo) = NULL, + bool (*surfaceFct)(ElInfo *elInfo, int side) = NULL); + + /** \brief + * destructor + */ + virtual ~SMIAdapter() {}; + + /** \brief + * Add DOFVector<double> as smi quantity. + */ + void addQuantity(int quantityId, DOFVector<double> *dofVector); + + /** \brief + * Add DOFVector<double> as smi quantity. + */ + void addQuantity(int quantityId, + int quantityDim, + DOFVector<double> **dofVector); + + /** \brief + * If called before the first call of \ref transferMeshToSMI() + * neighbourhood information are stored in SMI as quantities. + */ + void addNeighbourInfo(); + + /** \brief + * Get neighbourhood information about the element. + * \param neighbours array of the neighbour element indices + * \param oppVertices array of the corresponding opp vertices + */ + void getNeighbourInfo(int elementIndex, + int *neighbours, + int *oppVertices); + + /** \brief + * Transfer mesh data from AMDiS to SMI. + */ + void transferMeshToSMI(); + + /** \brief + * Transfer quantity values from AMDiS to SMI. + */ + void transferQuantitiesToSMI(int quantityID = -1); + + /** \brief + * Transfer quantity values from SMI to AMDiS. + */ + void getQuantitiesFromSMI(int quantityID = -1); + + void setIndexMappings(::std::map<DegreeOfFreedom, DegreeOfFreedom> *newNodeIndex, + ::std::map<DegreeOfFreedom, DegreeOfFreedom> *oldNodeIndex, + ::std::map<int, int> *newElementIndex, + ::std::map<int, int> *oldElementIndex) + { + newNodeIndex_ = newNodeIndex; + oldNodeIndex_ = oldNodeIndex; + newElementIndex_ = newElementIndex; + oldElementIndex_ = oldElementIndex; + }; + + protected: + /** \brief + * SMI application id + */ + int smiApplicationId_; + + /** \brief + * SMI mesh id + */ + int smiMeshId_; + + /** \brief + * FESpace containing the mesh + */ + FiniteElemSpace *feSpace_; + + /** \brief + * smi element type of all elements in the mesh + */ + int elementType_; + + /** \brief + * mapping from quantity ids to DOFVector pointers + */ + ::std::map<int, ::std::vector<DOFVector<double>*> > dofVectors_; + + /** \brief + * element region the adapter is defined on + */ + int elementRegion_; + + /** \brief + * surface region the adapter is defined on + */ + int surfaceRegion_; + + /** \brief + * store neighbourhood information? + */ + bool addNeighbourInfo_; + + ::std::map<DegreeOfFreedom, DegreeOfFreedom> *newNodeIndex_; + ::std::map<DegreeOfFreedom, DegreeOfFreedom> *oldNodeIndex_; + ::std::map<int, int> *newElementIndex_; + ::std::map<int, int> *oldElementIndex_; + + bool (*elementFct_)(ElInfo*); + bool (*surfaceFct_)(ElInfo*, int); + }; + +} + +#endif diff --git a/AMDiS/src/Serializable.h b/AMDiS/src/Serializable.h new file mode 100644 index 0000000000000000000000000000000000000000..56be90d32d3a43dc1ef958c14b459c80feec29bb --- /dev/null +++ b/AMDiS/src/Serializable.h @@ -0,0 +1,62 @@ +// ============================================================================ +// == == +// == AMDiS - Adaptive multidimensional simulations == +// == == +// ============================================================================ +// == == +// == crystal growth group == +// == == +// == Stiftung caesar == +// == Ludwig-Erhard-Allee 2 == +// == 53175 Bonn == +// == germany == +// == == +// ============================================================================ +// == == +// == http://www.caesar.de/cg/AMDiS == +// == == +// ============================================================================ + +/** \file Serializable.h */ + +#ifndef AMDIS_SERIALIZABLE_H +#define AMDIS_SERIALIZABLE_H + +#include <iostream> +#include <string> + +namespace AMDiS { + + // =============================================================================== + // ===== class Serializable ====================================================== + // =============================================================================== + + /** \brief + * Interface for JAVA-like serialization of objects. Serializable objects can be + * written to an out stream and read from an in stream. So i.e. they can be stored + * on hard disk. + */ + class Serializable + { + public: + /** \brief + * Streams the object to output stream out. + */ + virtual void serialize(::std::ostream &out) = 0; + + /** \brief + * Reads the object from input stream in. + */ + virtual void deserialize(::std::istream &in) = 0; + + /** \brief + * Returns the type name for this serializable object. + */ + virtual ::std::string getTypeName() const { return ""; }; + + virtual ~Serializable() {}; + }; + +} + +#endif diff --git a/AMDiS/src/Serializer.h b/AMDiS/src/Serializer.h new file mode 100644 index 0000000000000000000000000000000000000000..d623e72ad37c79b63bfcef236ff676e24886e036 --- /dev/null +++ b/AMDiS/src/Serializer.h @@ -0,0 +1,131 @@ + +// == == +// == AMDiS - Adaptive multidimensional simulations == +// == == +// ============================================================================ +// == == +// == crystal growth group == +// == == +// == Stiftung caesar == +// == Ludwig-Erhard-Allee 2 == +// == 53175 Bonn == +// == germany == +// == == +// ============================================================================ +// == == +// == http://www.caesar.de/cg/AMDiS == +// == == +// ============================================================================ + +/** \file Serializer.h */ + +#ifndef AMDIS_SERIALIZER_H +#define AMDIS_SERIALIZER_H + +#include "FileWriter.h" +#include "MemoryManager.h" +#include "Parameters.h" +#include "AdaptInfo.h" +#include "ProblemStatBase.h" + +namespace AMDiS { + + template<typename ProblemType> + class Serializer : public FileWriterInterface + { + public: + MEMORY_MANAGED(Serializer); + + Serializer(ProblemType *problem) + : name_(""), + problem_(problem), + tsModulo_(1), + timestepNumber_(-1) + { + GET_PARAMETER(0, problem_->getName() + "->output->serialization filename", + &name_); + GET_PARAMETER(0, problem_->getName() + "->output->write every i-th timestep", + "%d", &tsModulo_); + TEST_EXIT(name_ != "")("no filename\n"); + }; + + virtual ~Serializer() {}; + + virtual void writeFiles(AdaptInfo *adaptInfo, + bool force, + int level = -1, + Flag traverseFlag = Mesh::CALL_LEAF_EL, + bool (*writeElem)(ElInfo*) = NULL) + { + FUNCNAME("Serializer::writeFiles()"); + + timestepNumber_++; + timestepNumber_ %= tsModulo_; + if ((timestepNumber_ != 0) && !force) { + return; + } + + TEST_EXIT(adaptInfo)("No AdaptInfo\n"); + + ::std::ofstream out(name_.c_str()); + problem_->serialize(out); + adaptInfo->serialize(out); + out.close(); + + MSG("problem serialized to %s \n", name_.c_str()); + }; + + + protected: + /** \brief + * Name of file to which the problem is serialized. + */ + ::std::string name_; + + /** \brief + * Pointer to the problem. + */ + ProblemType *problem_; + + /** \brief + * The problem is serialized every tsModulo-th timestep. + */ + int tsModulo_; + + /** \brief + * Current timestep number. + */ + int timestepNumber_; + }; + + + class SerializerUtil { + public: + static void serializeInt(::std::ostream &out, int* ptrInt) { + out.write(reinterpret_cast<const char*>(ptrInt), sizeof(int)); + }; + + static void serializeDouble(::std::ostream &out, double* ptrInt) { + out.write(reinterpret_cast<const char*>(ptrInt), sizeof(double)); + }; + + static void serializeBool(::std::ostream &out, bool* ptrBool) { + out.write(reinterpret_cast<const char*>(ptrBool), sizeof(bool)); + } + + + static void deserializeInt(::std::istream &in, int* ptrInt) { + in.read(reinterpret_cast<char*>(ptrInt), sizeof(int)); + }; + + static void deserializeDouble(::std::istream &in, double* ptrInt) { + in.read(reinterpret_cast<char*>(ptrInt), sizeof(double)); + }; + + static void deserializeBool(::std::istream &in, bool* ptrBool) { + in.read(reinterpret_cast<char*>(ptrBool), sizeof(bool)); + }; + + }; +} +#endif diff --git a/AMDiS/src/SmootherBase.h b/AMDiS/src/SmootherBase.h new file mode 100644 index 0000000000000000000000000000000000000000..cefa87c313b82de2dfdcb6bc1b4349249b4e1b6d --- /dev/null +++ b/AMDiS/src/SmootherBase.h @@ -0,0 +1,67 @@ +// ============================================================================ +// == == +// == AMDiS - Adaptive multidimensional simulations == +// == == +// ============================================================================ +// == == +// == crystal growth group == +// == == +// == Stiftung caesar == +// == Ludwig-Erhard-Allee 2 == +// == 53175 Bonn == +// == germany == +// == == +// ============================================================================ +// == == +// == http://www.caesar.de/cg/AMDiS == +// == == +// ============================================================================ + +/** \file SmootherBase.h */ + +#include "Global.h" +#include <set> +#include <string> +#include "CreatorInterface.h" + +#ifndef AMDIS_SMOOTHERBASE_H +#define AMDIS_SMOOTHERBASE_H + +namespace AMDiS { + + template<typename MatrixType, typename VectorType, typename DOFSetType> + class SmootherBase + { + public: + SmootherBase(::std::string name) : name_(name) {}; + + virtual ~SmootherBase() {}; + + virtual void smooth(MatrixType *matrix, + VectorType *solution, + VectorType *rhs, + int iterations, + const DOFSetType &dofSet) = 0; + + protected: + const ::std::string name_; + }; + + + template<typename MatrixType, typename VectorType, typename DOFSetType> + class SmootherCreator : public CreatorInterface<SmootherBase<MatrixType, + VectorType, + DOFSetType> > + { + public: + virtual ~SmootherCreator() {}; + + void setName(::std::string name_) { name = name_; }; + + protected: + ::std::string name; + }; + +} + +#endif diff --git a/AMDiS/src/SparseVector.cc b/AMDiS/src/SparseVector.cc new file mode 100644 index 0000000000000000000000000000000000000000..5ec91c2b43bb1d6cda26890a2ab18ac423eb6562 --- /dev/null +++ b/AMDiS/src/SparseVector.cc @@ -0,0 +1,78 @@ +#include "SparseVector.h" +#include "DOFVector.h" +#include "FiniteElemSpace.h" + +namespace AMDiS { + + template<> + void SparseVector<double>::refineInterpol(RCNeighbourList& list, int n) + { + (const_cast<BasisFunction*>(this->getFESpace()->getBasisFcts()))->refineInter(this, &list, n); + } + + template<> + void SparseVector<double>::coarseRestrict(RCNeighbourList& list, int n) + { + (const_cast<BasisFunction*>(this->getFESpace()->getBasisFcts()))->coarseInter(this, &list, n); + } + + template<> + void SparseVector<double>::print() + { + FUNCNAME("SparseVector::print()"); + int i, size = static_cast<int>(vec_.size()); + for(i = 0; i < size; i++) { + MSG("dof %d - %e\n", (*physToLog_)[i], vec_[i]); + } + } + + template<> + void axpy<double>(double a, SparseVector<double>& x, SparseVector<double>& y, + ::std::set<DegreeOfFreedom> &dofSet) + { + ::std::set<DegreeOfFreedom>::iterator dofIt, dofEnd = dofSet.end(); + for(dofIt = dofSet.begin(); dofIt != dofEnd; ++dofIt) { + y[*dofIt] += a * x[*dofIt]; + } + } + + template<> + void mv<double>(DOFMatrix &a, + SparseVector<double> &x, + SparseVector<double> &result, + ::std::set<DegreeOfFreedom> &dofSet, + bool add) + { + //DOFMatrix::Iterator matIt(const_cast<DOFMatrix*>(&a), USED_DOFS); + ::std::vector<MatEntry>::iterator rowIt, rowEnd; + + DegreeOfFreedom row, col; + + if(!add) result.clear(); + + // for(matIt.reset(); !matIt.end(); ++matIt) { + ::std::set<DegreeOfFreedom>::iterator dofIt, dofEnd = dofSet.end(); + for(dofIt = dofSet.begin(); dofIt != dofEnd; ++dofIt) { + row = *dofIt; + rowEnd = a[row].end(); + for(rowIt = a[row].begin(); rowIt != rowEnd; ++rowIt) { + col = rowIt->col; + if(col == DOFMatrix::UNUSED_ENTRY) continue; + if(col == DOFMatrix::NO_MORE_ENTRIES) break; + result[row] += rowIt->entry * const_cast<SparseVector<double>&>(x)[col]; + } + } + } + + template<> + double SparseVector<double>::norm() + { + double norm = 0.0; + ::std::vector<double>::iterator it, end = vec_.end(); + for(it = vec_.begin(); it != end; ++it) { + norm += *it * *it; + } + return sqrt(norm); + } + +} diff --git a/AMDiS/src/SparseVector.h b/AMDiS/src/SparseVector.h new file mode 100644 index 0000000000000000000000000000000000000000..78a9d5c6a61cf592b59e221f4240b1658b94e0f4 --- /dev/null +++ b/AMDiS/src/SparseVector.h @@ -0,0 +1,182 @@ +// ============================================================================ +// == == +// == AMDiS - Adaptive multidimensional simulations == +// == == +// ============================================================================ +// == == +// == crystal growth group == +// == == +// == Stiftung caesar == +// == Ludwig-Erhard-Allee 2 == +// == 53175 Bonn == +// == germany == +// == == +// ============================================================================ +// == == +// == http://www.caesar.de/cg/AMDiS == +// == == +// ============================================================================ + +/** \file SparseVector.h */ + +#ifndef AMDIS_SPARSEVECTOR_H +#define AMDIS_SPARSEVECTOR_H + +#include "MemoryManager.h" +#include "DOFVector.h" +#include <set> +#include <string> +#include <vector> + +namespace AMDiS +{ + + template<typename T> class SparseVector; + + template<typename T> + void axpy(double a, SparseVector<T>& x, SparseVector<T>& y, + ::std::set<DegreeOfFreedom> &dofSet); + + template<typename T> + void mv(DOFMatrix &a, + SparseVector<T> &x, + SparseVector<T> &result, + ::std::set<DegreeOfFreedom> &dofSet, + bool add = false); + + class FiniteElemSpace; + + template<typename T> + class SparseVector : public DOFVectorBase<T> + { + public: + MEMORY_MANAGED(SparseVector); + + SparseVector(const FiniteElemSpace *feSpace, const char *name) + : DOFVectorBase<T>(feSpace, name), + // feSpace_(feSpace), + // name_(name), + master_(NULL) + { + logToPhys_ = new ::std::map<DegreeOfFreedom, int>; + physToLog_ = new ::std::vector<DegreeOfFreedom>; + }; + + SparseVector(const char *name, SparseVector *master) + : DOFVectorBase<T>(master->getFESpace(), name), + // feSpace_(master->feSpace_), + // name_(name), + logToPhys_(master->logToPhys_), + physToLog_(master->physToLog_), + master_(master) + { + master_->clients_.push_back(this); + vec_.resize(physToLog_->size(), 0.0); + }; + + virtual ~SparseVector() { + if(master_) { + typename ::std::vector<SparseVector<T>*>::iterator clientIt, clientEnd = master_->clients_.end(); + for(clientIt = master_->clients_.begin(); clientIt != clientEnd; ++clientIt) { + if(*clientIt == this) { + master_->clients_.erase(clientIt); + break; + } + } + } else { + TEST_EXIT(clients_.empty())("delete clients first\n"); + delete logToPhys_; + delete physToLog_; + } + }; + + //void createSparseIndices(::std::set<DegreeOfFreedom> &dofs); + + void copyToDOFVector(DOFVector<T> &dofVec); + + void copyToDOFVector(DOFVector<T> &dofVec, + ::std::set<DegreeOfFreedom> &dofs); + + void copyFromDOFVector(DOFVector<T> &dofVec, + ::std::set<DegreeOfFreedom> &dofs); + + void clear(bool eraseEntries = true); + + T norm(); + + void copy(SparseVector &x, const ::std::set<DegreeOfFreedom> &dofSet); + + void copy(SparseVector &x, const ::std::vector<DegreeOfFreedom> &dofSet); + + void print(); + + inline void synchronize() { + vec_.resize(physToLog_->size(), 0.0); + }; + + virtual int getSize() const { + return static_cast<int>(physToLog_->size()); + }; + + virtual void resize(int size) {}; + + virtual void compressDOFIndexed(int first, int last, + ::std::vector<DegreeOfFreedom> &newDOF) + { + ERROR_EXIT("compress called\n"); + }; + + virtual void freeDOFContent(int) {}; + + virtual void refineInterpol(RCNeighbourList&, int); + + virtual void coarseRestrict(RCNeighbourList&, int); + + virtual typename ::std::vector<T>::iterator begin() { + static typename ::std::vector<T>::iterator dummy; + return dummy; + }; + + virtual typename ::std::vector<T>::iterator end() { + static typename ::std::vector<T>::iterator dummy; + return dummy; + }; + + virtual T& operator[](DegreeOfFreedom i); + + virtual const T& operator[](DegreeOfFreedom i) const; + + inline bool isSparseIndex(int i) { + return (*logToPhys_)[i] != 0; + }; + + protected: + /* const FiniteElemSpace *feSpace_; */ + + /* ::std::string name_; */ + + ::std::map<DegreeOfFreedom, int> *logToPhys_; + + ::std::vector<DegreeOfFreedom> *physToLog_; + + ::std::vector<T> vec_; + + SparseVector *master_; + + ::std::vector<SparseVector*> clients_; + + friend void axpy<>(double a, SparseVector<T>& x, SparseVector<T>& y, + ::std::set<DegreeOfFreedom> &dofSet); + + friend void mv<>(DOFMatrix &a, + SparseVector<T> &x, + SparseVector<T> &result, + ::std::set<DegreeOfFreedom> &dofSet, + bool add); + + }; + +} + +#include "SparseVector.hh" +#endif diff --git a/AMDiS/src/SparseVector.hh b/AMDiS/src/SparseVector.hh new file mode 100644 index 0000000000000000000000000000000000000000..0add7cb2c5b3ef14a3da3260ffcbb7057fb46d75 --- /dev/null +++ b/AMDiS/src/SparseVector.hh @@ -0,0 +1,126 @@ +#include "DOFVector.h" +#include "FiniteElemSpace.h" + +namespace AMDiS { + +template<typename T> +void SparseVector<T>::refineInterpol(RCNeighbourList& list, int n) +{} + +template<typename T> +void SparseVector<T>::coarseRestrict(RCNeighbourList& list, int n) +{} + +template<typename T> +void SparseVector<T>::copyToDOFVector(DOFVector<T> &dofVec, + ::std::set<DegreeOfFreedom> &dofs) +{ + ::std::set<DegreeOfFreedom>::iterator dofsIt; + ::std::set<DegreeOfFreedom>::iterator dofsEnd = dofs.end(); + + for(dofsIt = dofs.begin(); dofsIt != dofsEnd; ++dofsIt) { + dofVec[*dofsIt] = operator[](*dofsIt); + } +} + +template<typename T> +void SparseVector<T>::copyToDOFVector(DOFVector<T> &dofVec) +{ + int i, size = static_cast<int>((*physToLog_).size()); + +// vec_.resize(size, 0.0); + + for(i = 0; i < size; i++) { + dofVec[(*physToLog_)[i]] = vec_[i]; + } +} + +template<typename T> +void SparseVector<T>::copyFromDOFVector(DOFVector<T> &dofVec, + ::std::set<DegreeOfFreedom> &dofs) +{ + ::std::set<DegreeOfFreedom>::iterator dofsIt; + ::std::set<DegreeOfFreedom>::iterator dofsEnd = dofs.end(); + + for(dofsIt = dofs.begin(); dofsIt != dofsEnd; ++dofsIt) { + operator[](*dofsIt) = dofVec[*dofsIt]; + } +} + +template<typename T> +T& SparseVector<T>::operator[](DegreeOfFreedom i) +{ + int physIndex = (*logToPhys_)[i]; + +// vec_.resize(physToLog_->size(), 0.0); + + if(physIndex == 0) { + vec_.push_back(0.0); + (*physToLog_).push_back(i); + physIndex = (*logToPhys_)[i] = static_cast<int>(vec_.size()); + + typename ::std::vector<SparseVector<T>*>::iterator clientIt, clientEnd; + if(master_) { + clientEnd = master_->clients_.end(); + master_->vec_.resize(physToLog_->size(), 0.0); + for(clientIt = master_->clients_.begin(); clientIt != clientEnd; ++clientIt) { + (*clientIt)->vec_.resize(physToLog_->size(), 0.0); + } + } else { + clientEnd = clients_.end(); + for(clientIt = clients_.begin(); clientIt != clientEnd; ++clientIt) { + (*clientIt)->vec_.resize(physToLog_->size(), 0.0); + } + } + } + + return vec_[physIndex-1]; +} + +template<typename T> +const T& SparseVector<T>::operator[](DegreeOfFreedom i) const +{ + return (*const_cast<SparseVector*>(this))[i]; +} + +template<typename T> +void SparseVector<T>::clear(bool eraseEntries) +{ +// if(master_ && eraseEntries) { +// (*logToPhys_).clear(); +// (*physToLog_).resize(0); +// vec_.resize(0); +// } else { +// vec_.resize(physToLog_->size(), 0.0); + typename ::std::vector<T>::iterator vecIt, vecEnd = vec_.end(); + for(vecIt = vec_.begin(); vecIt != vecEnd; ++vecIt) { + *vecIt = 0; + } +// } +} + +template<typename T> +void SparseVector<T>::copy(SparseVector<T> &x, + const ::std::set<DegreeOfFreedom> &dofSet) +{ + ::std::set<DegreeOfFreedom>::iterator dofIt, dofEnd = dofSet.end(); + for(dofIt = dofSet.begin(); dofIt != dofEnd; ++dofIt) { + operator[](*dofIt) = x[*dofIt]; + } +} + +template<typename T> +void SparseVector<T>::copy(SparseVector<T> &x, + const ::std::vector<DegreeOfFreedom> &dofSet) +{ + ::std::vector<DegreeOfFreedom>::iterator dofIt, + dofEnd = const_cast< ::std::vector<DegreeOfFreedom>&>(dofSet).end(); + for(dofIt = const_cast< ::std::vector<DegreeOfFreedom>&>(dofSet).begin(); + dofIt != dofEnd; + ++dofIt) + { + operator[](*dofIt) = x[*dofIt]; + } +} + +} diff --git a/AMDiS/src/StandardProblemIteration.cc b/AMDiS/src/StandardProblemIteration.cc new file mode 100644 index 0000000000000000000000000000000000000000..480cd4af94a1a106f344714baaaf0ad270382b46 --- /dev/null +++ b/AMDiS/src/StandardProblemIteration.cc @@ -0,0 +1,94 @@ +#include "StandardProblemIteration.h" +#include "AdaptInfo.h" +#include "ProblemStatBase.h" +#include "Global.h" + +namespace AMDiS { + + int StandardProblemIteration::info_ = 10; + + void StandardProblemIteration::beginIteration(AdaptInfo *adaptInfo) + { + FUNCNAME("StandardProblemIteration::beginIteration()"); + + INFO(info_,4)("\n"); + INFO(info_,4)("begin of iteration number: %d\n", adaptInfo->getSpaceIteration() + 1); + INFO(info_,4)("=============================\n"); + } + + Flag StandardProblemIteration::oneIteration(AdaptInfo *adaptInfo, Flag toDo) + { + FUNCNAME("StandardProblemIteration::oneIteration()"); + + Flag flag = buildAndAdapt(adaptInfo, toDo); + + if (toDo.isSet(SOLVE)) + problem_->solve(adaptInfo); + + if (toDo.isSet(ESTIMATE)) + problem_->estimate(adaptInfo); + + return flag; + } + + void StandardProblemIteration::endIteration(AdaptInfo *adaptInfo) + { + FUNCNAME("StandardProblemIteration::endIteration()"); + + INFO(info_,4)("\n"); + INFO(info_,4)("end of iteration number: %d\n", adaptInfo->getSpaceIteration() + 1); + INFO(info_,4)("=============================\n"); + } + + Flag StandardProblemIteration::buildAndAdapt(AdaptInfo *adaptInfo, Flag toDo) + { + FUNCNAME("StandardProblemIteration::buildAndAdapt()"); + + Flag flag = 0, markFlag = 0; + + if (toDo.isSet(MARK)) { + markFlag = problem_->markElements(adaptInfo); + } else { + markFlag = 3; + } + + if (toDo.isSet(BUILD)) { + problem_->buildBeforeRefine(adaptInfo, markFlag); + } + + // refine + if (toDo.isSet(ADAPT) && markFlag.isSet(MESH_REFINED)) { + flag = problem_->refineMesh(adaptInfo); + } + + if (toDo.isSet(BUILD)) { + problem_->buildBeforeCoarsen(adaptInfo, markFlag); + } + + // coarsen + if (toDo.isSet(ADAPT) && markFlag.isSet(MESH_COARSENED)) { + flag |= problem_->coarsenMesh(adaptInfo); + } + + if (toDo.isSet(BUILD)) { + problem_->buildAfterCoarsen(adaptInfo, markFlag); + } + + return flag; + } + + const ::std::string& StandardProblemIteration::getName() + { + return problem_->getName(); + } + + void StandardProblemIteration::serialize(::std::ostream &out) + { + problem_->serialize(out); + } + + void StandardProblemIteration::deserialize(::std::istream &in) + { + problem_->deserialize(in); + } +}; diff --git a/AMDiS/src/StandardProblemIteration.h b/AMDiS/src/StandardProblemIteration.h new file mode 100644 index 0000000000000000000000000000000000000000..a506caafee3a28ae5ecbecae17e468e2d66f5689 --- /dev/null +++ b/AMDiS/src/StandardProblemIteration.h @@ -0,0 +1,120 @@ +// ============================================================================ +// == == +// == AMDiS - Adaptive multidimensional simulations == +// == == +// ============================================================================ +// == == +// == crystal growth group == +// == == +// == Stiftung caesar == +// == Ludwig-Erhard-Allee 2 == +// == 53175 Bonn == +// == germany == +// == == +// ============================================================================ +// == == +// == http://www.caesar.de/cg/AMDiS == +// == == +// ============================================================================ + +/** \file StandardProblemIteration.h */ + +#ifndef AMDIS_STANDARDPROBLEMITERATION_H +#define AMDIS_STANDARDPROBLEMITERATION_H + +#include "ProblemIterationInterface.h" +#include "MemoryManager.h" + +namespace AMDiS { + + class AdaptInfo; + class ProblemStatBase; + + // ============================================================================ + // ===== class StandardProblemIteration ======================================= + // ============================================================================ + + /** \brief + * A master problem for a single non coupled problem. + */ + class StandardProblemIteration : public ProblemIterationInterface + { + public: + MEMORY_MANAGED(StandardProblemIteration); + + /** \brief + * constructor + */ + StandardProblemIteration(ProblemStatBase *problem) + : problem_(problem) + {}; + + virtual ~StandardProblemIteration() {}; + + /** \brief + * implementation of \ref ProblemIterationIterface::beginIteration() + */ + virtual void beginIteration(AdaptInfo *adaptInfo); + + /** \brief + * implementation of \ref ProblemIterationInterface::oneIteration() + */ + virtual Flag oneIteration(AdaptInfo *adaptInfo, Flag toDo); + + /** \brief + * implementation of \ref ProblemIterationInterface::endIteration() + */ + virtual void endIteration(AdaptInfo *adaptInfo); + + /** \brief + * implementation of \ref ProblemIterationInterface::getNumProblems() + */ + int getNumProblems() { + return 1; + }; + + /** \brief + * implementation of \ref ProblemIterationInterface::getProblem(int) + */ + ProblemStatBase *getProblem(int number = 0) { + return problem_; + }; + + /** \brief + * Returns the name of the problem. + */ + virtual const ::std::string& getName(); + + /** \brief + * Function that serializes the problem plus information about the iteration. + */ + virtual void serialize(::std::ostream &out); + + /** \brief + * Function that deserializes the problem plus information about the iteration. + */ + virtual void deserialize(::std::istream &in); + + + protected: + /** \brief + * nested assemblage and mesh adaption + */ + Flag buildAndAdapt(AdaptInfo *adaptInfo, Flag toDo); + + protected: + /** \brief + * the problem to solve + */ + ProblemStatBase *problem_; + + /** \brief + * info level + */ + static int info_; + }; + +} + +#endif + diff --git a/AMDiS/src/StlVector.cc b/AMDiS/src/StlVector.cc new file mode 100644 index 0000000000000000000000000000000000000000..4809570bebafa6f1586a6ebf9d52eb64d77904bc --- /dev/null +++ b/AMDiS/src/StlVector.cc @@ -0,0 +1,81 @@ +#include <vector> +#include <math.h> +#include "StlVector.h" + +namespace AMDiS { + + double norm(::std::vector<double> *vec) { + double v = 0; + for (int i = 0; i < static_cast<int>(vec->size()); i++) { + v += (*vec)[i] * (*vec)[i]; + } + return sqrt(v); + }; + + void setValue(::std::vector<double>& x, double value) { + for (int i = 0; i < static_cast<int>(x.size()); i++) { + x[i] = value; + } + }; + + const ::std::vector<double>& operator*=(::std::vector<double>& x, double scal) { + for (int i = 0; i < static_cast<int>(x.size()); i++) { + x[i] *= scal; + } + + return x; + }; + + const ::std::vector<double>& operator+=(::std::vector<double>& x1, + const ::std::vector<double>& x2) { + for (int i = 0; i < static_cast<int>(x1.size()); i++) { + x1[i] += x2[i]; + } + + return x1; + }; + + double operator*(::std::vector<double>& x1, ::std::vector<double>& x2) { + double result = 0.0; + + for (int i = 0; i < static_cast<int>(x1.size()); i++) { + result += x1[i] * x2[i]; + } + + return result; + }; + + void axpy(double alpha, const ::std::vector<double>& x, ::std::vector<double>& y) { + for (int i = 0; i < static_cast<int>(y.size()); i++) { + y[i] += alpha * x[i]; + } + } + + void xpay(double alpha, const ::std::vector<double>& x, ::std::vector<double>& y) { + for (int i = 0; i < static_cast<int>(y.size()); i++) { + y[i] = alpha * y[i] + x[i]; + } + } + + int logToPhysIndex(::std::vector< ::std::vector<MatEntry> > *matrix, int a, int b) + { + int j; + + for (j = 0; j < static_cast<int>((*matrix)[a].size()); j++) + if (b == (*matrix)[a][j].col) + break; + + return (j == static_cast<int>((*matrix)[a].size())) ? -1 : j; + } + + void print(::std::vector<double> *vec) + { + ::std::cout << "["; + + for (int i = 0; i < vec->size(); i++) { + ::std::cout << (*vec)[i] << " , "; + } + + ::std::cout << "]" << ::std::endl; + } +} diff --git a/AMDiS/src/StlVector.h b/AMDiS/src/StlVector.h new file mode 100644 index 0000000000000000000000000000000000000000..e3c6ec2f1b6b8e0377b772c0d35a69d42dc14ded --- /dev/null +++ b/AMDiS/src/StlVector.h @@ -0,0 +1,60 @@ +#ifndef AMDIS_STLVECTOR_H +#define AMDIS_STLVECTOR_H + +#include <vector> +#include "CreatorInterface.h" +#include "MemoryManager.h" +#include "DOFMatrix.h" + +namespace AMDiS { + + class StlVectorCreator : public CreatorInterface< ::std::vector<double> > { + public: + MEMORY_MANAGED(StlVectorCreator); + + StlVectorCreator(int size) + : size_(size) + {}; + + virtual ~StlVectorCreator() {}; + + ::std::vector<double> *create() { + ::std::vector<double> *vec = new ::std::vector<double>(size_, 0.0); + + return vec; + }; + + void free(::std::vector<double> *vec) { + delete vec; + }; + + private: + int size_; + }; + + double norm(::std::vector<double> *vec); + + inline int size(::std::vector<double> *vec) + { + return vec->size(); + } + + void setValue(::std::vector<double>& x, double value); + + const ::std::vector<double>& operator*=(::std::vector<double>& x, double scal); + + const ::std::vector<double>& operator+=(::std::vector<double>& x1, + const ::std::vector<double>& x2); + + double operator*(::std::vector<double>& x1, ::std::vector<double>& x2); + + void axpy(double alpha, const ::std::vector<double>& x, ::std::vector<double>& y); + + void xpay(double alpha, const ::std::vector<double>& x, ::std::vector<double>& y); + + int logToPhysIndex(::std::vector< ::std::vector<MatEntry> > *m, int a, int b); + + void print(::std::vector<double> *vec); +} + +#endif diff --git a/AMDiS/src/SubQuadrature.cc b/AMDiS/src/SubQuadrature.cc new file mode 100644 index 0000000000000000000000000000000000000000..513373bee1501f25e4e8da5a63f3386d3dac9c59 --- /dev/null +++ b/AMDiS/src/SubQuadrature.cc @@ -0,0 +1 @@ +#include "SubQuadrature.h" diff --git a/AMDiS/src/SubQuadrature.h b/AMDiS/src/SubQuadrature.h new file mode 100644 index 0000000000000000000000000000000000000000..5eefd01d252a3433b80b0fabf510fc187174d36c --- /dev/null +++ b/AMDiS/src/SubQuadrature.h @@ -0,0 +1,87 @@ +// ============================================================================ +// == == +// == AMDiS - Adaptive multidimensional simulations == +// == == +// ============================================================================ +// == == +// == crystal growth group == +// == == +// == Stiftung caesar == +// == Ludwig-Erhard-Allee 2 == +// == 53175 Bonn == +// == germany == +// == == +// ============================================================================ +// == == +// == http://www.caesar.de/cg/AMDiS == +// == == +// ============================================================================ + +/** \file SubQuadrature.h */ + +#ifndef AMDIS_SUBQUADRATURE_H +#define AMDIS_SUBQUADRATURE_H + +#include "Quadrature.h" +#include "FixVec.h" +#include "Global.h" +#include "MemoryManager.h" + +namespace AMDiS { + + // ============================================================================ + // ===== class SubQuadrature ================================================== + // ============================================================================ + + class SubQuadrature : public Quadrature + { + public: + MEMORY_MANAGED(SubQuadrature); + + SubQuadrature(Quadrature *quad, int dim_) + : Quadrature((quad->getName() + " sub").c_str(), + quad->getDegree(), + dim_, + quad->getNumPoints(), + NULL, + quad->getWeight()), + quad_(quad), + subDim_(quad_->getDim()) + { + if(dim == subDim_) lambda = quad_->getLambda(); + }; + + inline void scaleQuadrature(VectorOfFixVecs<DimVec<double> > &coords) + { + if(!lambda || (lambda == quad_->getLambda())) { + lambda = NEW VectorOfFixVecs<DimVec<double> >(dim, n_points, NO_INIT); + } + + TEST_EXIT(coords.getSize() == (subDim_ + 1)) + ("invalid number of scale coords or invalid quadrature dim\n"); + TEST_EXIT(coords.getSizeOfFixVec() == (dim + 1)) + ("invalid coord dimension\n"); + int i, j, k; + for(i=0; i < n_points; i++) { + DimVec<double> origin = quad_->getLambda(i); + for(j=0; j < dim + 1; j++) + (*lambda)[i][j] = 0.0; + for(j = 0; j < dim + 1; j++) { + for(k = 0; k < subDim_ + 1; k++) { + (*lambda)[i][j] += origin[k] * coords[k][j]; + } + } + } + }; + + inline int getSubDim() { return subDim_; }; + + protected: + Quadrature *quad_; + + int subDim_; + }; + +} + +#endif diff --git a/AMDiS/src/SurfaceAssembler.h b/AMDiS/src/SurfaceAssembler.h new file mode 100644 index 0000000000000000000000000000000000000000..1c1458d4a078d34bb92bb587cc3c3df75befba13 --- /dev/null +++ b/AMDiS/src/SurfaceAssembler.h @@ -0,0 +1,170 @@ +// ============================================================================ +// == == +// == AMDiS - Adaptive multidimensional simulations == +// == == +// ============================================================================ +// == == +// == crystal growth group == +// == == +// == Stiftung caesar == +// == Ludwig-Erhard-Allee 2 == +// == 53175 Bonn == +// == germany == +// == == +// ============================================================================ +// == == +// == http://www.caesar.de/cg/AMDiS == +// == == +// ============================================================================ + +/** \file SurfaceAssembler.h */ + +#ifndef AMDIS_SURFACEASSEMBLER_H +#define AMDIS_SURFACEASSEMBLER_H + +#include "FiniteElemSpace.h" +#include "Mesh.h" +#include "Assembler.h" +#include "SubQuadrature.h" +#include "ElementMatrix.h" +#include "QPInfo.h" + +namespace AMDiS { + + // ============================================================================ + // ===== class SurfaceAssembler ================================================ + // ============================================================================ + + /** + * \ingroup Integration + * + * \brief + */ + class SurfaceAssembler : public Assembler + { + public: + MEMORY_MANAGED(SurfaceAssembler); + + /** \brief + * Creates a SurfaceAssembler conforming to operat for the given \ref coords. + */ + SurfaceAssembler(Operator *operat, + const FiniteElemSpace *rowFESpace, + const FiniteElemSpace *colFESpace, + VectorOfFixVecs<DimVec<double> > &coords) + : Assembler(operat, rowFESpace, colFESpace, -1), + coords_(coords) + { + TEST_EXIT(rowDim_ == colDim_)("rowDim_ != colDim_\n"); + + SubQuadrature *subQuadrature; + + if(rowQuad11_) { + subQuadrature = NEW SubQuadrature(rowQuad11_, rowDim_); + rowQuad11_ = colQuad11_ = subQuadrature; + subQuadrature->scaleQuadrature(coords_); + rowQPInfo11_ = colQPInfo11_ = QPInfo::provideQPInfo(rowQuad11_, NULL); + } + if(rowQuad10_) { + subQuadrature = NEW SubQuadrature(rowQuad10_, rowDim_); + rowQuad10_ = colQuad10_ = subQuadrature; + subQuadrature->scaleQuadrature(coords_); + rowQPInfo10_ = colQPInfo10_ = QPInfo::provideQPInfo(rowQuad10_, NULL); + } + if(rowQuad01_) { + subQuadrature = NEW SubQuadrature(rowQuad01_, rowDim_); + rowQuad01_ = colQuad01_ = subQuadrature; + subQuadrature->scaleQuadrature(coords_); + rowQPInfo01_ = colQPInfo01_ = QPInfo::provideQPInfo(rowQuad01_, NULL); + } + if(rowQuad00_) { + subQuadrature = NEW SubQuadrature(rowQuad00_, rowDim_); + rowQuad00_ = colQuad00_ = subQuadrature; + subQuadrature->scaleQuadrature(coords_); + rowQPInfo00_ = colQPInfo00_ = QPInfo::provideQPInfo(rowQuad00_, NULL); + } + }; + + /** \brief + * Destructor + */ + ~SurfaceAssembler() + { + if(rowQuad11_) DELETE rowQuad11_; + if(rowQuad10_) DELETE rowQuad10_; + if(rowQuad01_) DELETE rowQuad01_; + if(rowQuad00_) DELETE rowQuad00_; + }; + + /** \brief + * Adapt surface quadratures to \ref coords. + */ + void adaptSurfaceAssembler(VectorOfFixVecs<DimVec<double> > &coords) + { + coords_ = coords; + if(rowQuad11_) + dynamic_cast<SubQuadrature*>(rowQuad11_)->scaleQuadrature(coords_); + if(rowQuad10_) + dynamic_cast<SubQuadrature*>(rowQuad10_)->scaleQuadrature(coords_); + if(rowQuad01_) + dynamic_cast<SubQuadrature*>(rowQuad01_)->scaleQuadrature(coords_); + if(rowQuad00_) + dynamic_cast<SubQuadrature*>(rowQuad00_)->scaleQuadrature(coords_); + }; + + + /** \brief + * + */ + bool initElementMatrix(const ElInfo *elInfo1, + const ElInfo *elInfo2, + const ElInfo *smaller) + { + if(Assembler::initElementMatrix(elInfo1, elInfo2, smaller)) { + int i; + FixVec<WorldVector<double>, VERTEX> worldCoords(rowDim_-1, NO_INIT); + + // transform barycentric coords to world coords + for(i = 0; i < rowDim_; i++) { + elInfo1->coordToWorld(coords_[i], &worldCoords[i]); + } + + // set determinant for world coords of the side + det_ = ElInfo::calcDet(worldCoords); + + return true; + } else { + return false; + } + }; + + /** \brief + * + */ + bool initElementVector(const ElInfo *elInfo) + { + if(Assembler::initElementVector(elInfo)) { + int i; + FixVec<WorldVector<double>, VERTEX> worldCoords(rowDim_-1, NO_INIT); + + // transform barycentric coords to world coords + for(i = 0; i < rowDim_; i++) { + elInfo->coordToWorld(coords_[i], &worldCoords[i]); + } + + // set determinant for world coords of the side + det_ = ElInfo::calcDet(worldCoords); + + return true; + } else { + return false; + } + }; + + protected: + VectorOfFixVecs<DimVec<double> > coords_; + }; + +} + +#endif diff --git a/AMDiS/src/SurfaceOperator.h b/AMDiS/src/SurfaceOperator.h new file mode 100644 index 0000000000000000000000000000000000000000..8d3df5ba67c230a912ae6e05295a025d3191b19f --- /dev/null +++ b/AMDiS/src/SurfaceOperator.h @@ -0,0 +1,206 @@ +// ============================================================================ +// == == +// == AMDiS - Adaptive multidimensional simulations == +// == == +// ============================================================================ +// == == +// == crystal growth group == +// == == +// == Stiftung caesar == +// == Ludwig-Erhard-Allee 2 == +// == 53175 Bonn == +// == germany == +// == == +// ============================================================================ +// == == +// == http://www.caesar.de/cg/AMDiS == +// == == +// ============================================================================ + +/** \file SurfaceOperator.h */ + +#ifndef AMDIS_SURFACEOPERATOR_H +#define AMDIS_SURFACEOPERATOR_H + +#include "FiniteElemSpace.h" +#include "Mesh.h" +#include "Operator.h" +#include "SurfaceQuadrature.h" +#include "ElementMatrix.h" + +namespace AMDiS { + + // ============================================================================ + // ===== class SurfaceOperator ================================================ + // ============================================================================ + + /** + * \ingroup Integration + * + * \brief + * A SurfaceOperator is a Operator used for surface integration. Instead of a + * normal Quadrature it uses a SurfaceQuadrature with integration points at + * one element side instead of integration points in the inner of the element. + * The determinant in ElInfo is replaced by the surface determinant, so the + * assemblage can be done with the standard Assembler classes. + * The SurfaceQuadrature is used for the implementation of Neumann and Robin + * boundary conditions. + */ + class SurfaceOperator : public Operator + { + public: + MEMORY_MANAGED(SurfaceOperator); + + /** \brief + * Creates a SurfaceOperator conforming to operat for the given \ref coords. + */ + SurfaceOperator(Operator *operat, + VectorOfFixVecs<DimVec<double> > &coords) + : Operator(*operat), + coords_(coords), + quad2(NULL), + quad1GrdPsi(NULL), + quad1GrdPhi(NULL), + quad0(NULL) + { + assembler = NULL; + + int dim = rowFESpace->getMesh()->getDim(); + int degree; + + // create surface quadratures + if(secondOrder.size() > 0) { + degree = getQuadratureDegree(2); + // quad2 = SurfaceQuadrature::provideSurfaceQuadrature(dim, degree, coords); + quad2 = NEW SurfaceQuadrature(Quadrature::provideQuadrature(dim-1, + degree), + coords); + } + + if(firstOrderGrdPsi.size() > 0) { + degree = getQuadratureDegree(1, GRD_PSI); + quad1GrdPsi = NEW SurfaceQuadrature(Quadrature::provideQuadrature(dim-1, + degree), + coords); + //SurfaceQuadrature::provideSurfaceQuadrature(dim, degree, coords); + } + + if(firstOrderGrdPhi.size() > 0) { + degree = getQuadratureDegree(1, GRD_PHI); + quad1GrdPhi = NEW SurfaceQuadrature(Quadrature::provideQuadrature(dim-1, + degree), + coords); + //SurfaceQuadrature::provideSurfaceQuadrature(dim, degree, coords); + } + + if(zeroOrder.size() > 0) { + degree = getQuadratureDegree(0); + quad0 = NEW SurfaceQuadrature(Quadrature::provideQuadrature(dim-1, + degree), + coords); + //SurfaceQuadrature::provideSurfaceQuadrature(dim, degree, coords); + } + + // initialize assembler with surface quadratures + optimized = false; + initAssembler(quad2, quad1GrdPsi, quad1GrdPhi, quad0); + }; + + /** \brief + * Adapt surface quadratures to \ref coords. + */ + void adaptSurfaceOperator(VectorOfFixVecs<DimVec<double> > &coords) + { + coords_ = coords; + + if (quad2) { + quad2->scaleSurfaceQuadrature(coords); + } + + if (quad1GrdPsi) { + quad1GrdPsi->scaleSurfaceQuadrature(coords); + } + + if (quad1GrdPhi) { + quad1GrdPhi->scaleSurfaceQuadrature(coords); + } + + if (quad0) { + quad0->scaleSurfaceQuadrature(coords); + } + }; + + /** \brief + * Implementation of \ref Operator::getElementMatrix(). Repalces the + * determinant by the surface determinant and deligates the call to + * the base class function. + */ + virtual void getElementMatrix(const ElInfo *elInfo, + ElementMatrix *userMat, + double factor = 1.0) + { + int i; + int dim = rowFESpace->getMesh()->getDim(); + double origDet = elInfo->getDet(); + + FixVec<WorldVector<double>, VERTEX> worldCoords(dim-1, NO_INIT); + + // transform barycentric coords to world coords + for(i = 0; i < dim; i++) { + elInfo->coordToWorld(coords_[i], &worldCoords[i]); + } + + // set determinant for world coords of the side + const_cast<ElInfo*>(elInfo)->setDet(ElInfo::calcDet(worldCoords)); + + // calc element matrix + Operator::getElementMatrix(elInfo, userMat, factor); + + // set determinant for world coords of the side + const_cast<ElInfo*>(elInfo)->setDet(origDet); + }; + + /** \brief + * Implementation of \ref Operator::getElementVector(). Repalces the + * determinant by the surface determinant and deligates the call to + * the base class function. + */ + virtual void getElementVector(const ElInfo *elInfo, + ElementVector *userVec, + double factor = 1.0) + { + int i; + int dim = rowFESpace->getMesh()->getDim(); + double origDet = elInfo->getDet(); + + FixVec<WorldVector<double>, VERTEX> worldCoords(dim-1, NO_INIT); + + // transform barycentric coords to world coords + for(i = 0; i < dim; i++) { + elInfo->coordToWorld(coords_[i], &worldCoords[i]); + } + + // set determinant for world coords of the side + const_cast<ElInfo*>(elInfo)->setDet(ElInfo::calcDet(worldCoords)); + + // calc element vector + Operator::getElementVector(elInfo, userVec, factor); + + const_cast<ElInfo*>(elInfo)->setDet(origDet); + }; + + protected: + VectorOfFixVecs<DimVec<double> > coords_; + + /** \brief + * Surface quadratures + */ + SurfaceQuadrature *quad2; + SurfaceQuadrature *quad1GrdPsi; + SurfaceQuadrature *quad1GrdPhi; + SurfaceQuadrature *quad0; + }; + +} + +#endif diff --git a/AMDiS/src/SurfaceQuadrature.cc b/AMDiS/src/SurfaceQuadrature.cc new file mode 100644 index 0000000000000000000000000000000000000000..56168ac28a3a9bacd218eb408c061b32e81b1f45 --- /dev/null +++ b/AMDiS/src/SurfaceQuadrature.cc @@ -0,0 +1,87 @@ +#include <algorithm> + +#include "SurfaceQuadrature.h" +#include "Quadrature.h" + +namespace AMDiS { + + //::std::list<SurfaceQuadrature*> SurfaceQuadrature::surfaceQuadratureList; + + SurfaceQuadrature::SurfaceQuadrature(Quadrature *quad, + VectorOfFixVecs<DimVec<double> > &coords) + : Quadrature((quad->getName() + " surface").c_str(), + quad->getDegree(), + quad->getDim() + 1, + quad->getNumPoints(), + NULL, + quad->getWeight()), + quad_(quad), + coords_(coords) + { + int i, j, k; + + // copy coords + // coords_ = NEW DimVec<double>[dim](dim, NO_INIT); + // for(i = 0; i < dim; i++) { + // coords_[i] = coords[i]; + // } + + lambda = NEW VectorOfFixVecs<DimVec<double> >(dim, n_points, NO_INIT); + + // for each integration point + for(i=0; i < n_points; i++) { + // get coords of quadrature point in dim-1 + DimVec<double> origin = quad->getLambda(i); + + for(j=0; j < dim+1; j++) + (*lambda)[i][j] = 0.0; + + for(j = 0; j < dim; j++) { + for(k = 0; k < dim+1; k++) { + (*lambda)[i][k] += origin[j] * coords_[j][k]; + } + } + + // // create barycentric coords for dim + // if(dim > 1) { + // for (j = 0; j < side; j++) + // (*lambda)[i][j] = origin[j]; + + // (*lambda)[i][side] = 0.0; + + // for (j = side+1; j <= dim; j++) + // (*lambda)[i][j] = origin[j-1]; + // } else { + // (*lambda)[i][side] = 1.0; + // (*lambda)[i][1-side] = 0.0; + // } + } + } + + void + SurfaceQuadrature::scaleSurfaceQuadrature(VectorOfFixVecs<DimVec<double> >&coords) + { + int i, j, k; + + // copy coords + for(i = 0; i < dim; i++) { + coords_[i] = coords[i]; + } + + // for each integration point + for(i=0; i < n_points; i++) { + // get coords of quadrature point in dim-1 + DimVec<double> origin = quad_->getLambda(i); + + for(j=0; j < dim+1; j++) + (*lambda)[i][j] = 0.0; + + for(j = 0; j < dim; j++) { + for(k = 0; k < dim+1; k++) { + (*lambda)[i][k] += origin[j] * coords_[j][k]; + } + } + } + } + +} diff --git a/AMDiS/src/SurfaceQuadrature.h b/AMDiS/src/SurfaceQuadrature.h new file mode 100644 index 0000000000000000000000000000000000000000..134680308f760b0238ce563d4ae1f401b25f9d0a --- /dev/null +++ b/AMDiS/src/SurfaceQuadrature.h @@ -0,0 +1,94 @@ +// ============================================================================ +// == == +// == AMDiS - Adaptive multidimensional simulations == +// == == +// ============================================================================ +// == == +// == crystal growth group == +// == == +// == Stiftung caesar == +// == Ludwig-Erhard-Allee 2 == +// == 53175 Bonn == +// == germany == +// == == +// ============================================================================ +// == == +// == http://www.caesar.de/cg/AMDiS == +// == == +// ============================================================================ + +/** \file SurfaceQuadrature.h */ + +#ifndef AMDIS_SURFACEQAUDRATURE_H +#define AMDIS_SURFACEQAUDRATURE_H + +#include <list> + +#include "FixVec.h" +#include "MemoryManager.h" +#include "Quadrature.h" + +namespace AMDiS { + + // ============================================================================ + // ===== class SurfaceQuadrature ============================================== + // ============================================================================ + + /** + * \ingroup Integration + * + * \brief + * Quadrature for element surfaces. Uses the functionality of the standard + * Quadrature class for dim-1 but calculates new barycentric coordinates + * for the element sides. + */ + class SurfaceQuadrature : public Quadrature + { + public: + MEMORY_MANAGED(SurfaceQuadrature); + + /** \brief + * Returns a SurfaceQuadrature for given dim and degree of the given + * side number. + */ + //static SurfaceQuadrature* + // provideSurfaceQuadrature(int dim, + // int degree, + // DimVec<double> *coords); + + /** \brief + * Constructs a SurfaceQuadrature based on a standard Quadrature of dim-1. + */ + SurfaceQuadrature(Quadrature *quad, VectorOfFixVecs<DimVec<double> >& coords); + + /** \brief + * Destructor. + */ + ~SurfaceQuadrature() + { + }; + + /** \brief + * Adapts SurfaceQuadrature to \ref coords. + */ + void scaleSurfaceQuadrature(VectorOfFixVecs<DimVec<double> > &coords); + + protected: + /** \brief + * Pointer to the original quadrature + */ + Quadrature *quad_; + + VectorOfFixVecs<DimVec<double> > coords_; + + /** \brief + * List of all existing surface quadratures. Used by + * \ref provideSurfaceQuadrature(). If the needed quadrature is not in the + * list, a new list entry is created. + */ + //static ::std::list<SurfaceQuadrature*> surfaceQuadratureList; + }; + +} + +#endif // AMDIS_SURFACEQAUDRATURE_H diff --git a/AMDiS/src/SurfaceRegion_ED.h b/AMDiS/src/SurfaceRegion_ED.h new file mode 100644 index 0000000000000000000000000000000000000000..02c0653db52329cd4666d229c52a3f9bb8c1737e --- /dev/null +++ b/AMDiS/src/SurfaceRegion_ED.h @@ -0,0 +1,125 @@ +// ============================================================================ +// == == +// == AMDiS - Adaptive multidimensional simulations == +// == == +// ============================================================================ +// == == +// == crystal growth group == +// == == +// == Stiftung caesar == +// == Ludwig-Erhard-Allee 2 == +// == 53175 Bonn == +// == germany == +// == == +// ============================================================================ +// == == +// == http://www.caesar.de/cg/AMDiS == +// == == +// ============================================================================ + +/** \file SurfaceRegion_ED.h */ + +#ifndef AMDIS_SURFACEREGION_H +#define AMDIS_SURFACEREGION_H + +#include "ElementData.h" +#include "FixVec.h" + +namespace AMDiS { + + class SurfaceRegion_ED : public ElementData + { + public: + MEMORY_MANAGED(SurfaceRegion_ED); + + inline bool isOfType(int typeID) const { + if(typeID == SURFACE_REGION) + return true; + return false; + }; + + class Creator : public CreatorInterface<ElementData> + { + public: + ElementData* create() { + return NEW SurfaceRegion_ED; + }; + }; + + SurfaceRegion_ED(ElementData *decorated = NULL) + : ElementData(decorated), + side_(-1), + region_(-1) + {}; + + bool refineElementData(Element* parent, + Element* child1, + Element* child2, + int elType) + { + ElementData::refineElementData(parent, child1, child2, elType); + + int sideOfChild; + SurfaceRegion_ED *surfaceRegion; + + sideOfChild = parent->getSideOfChild(0, side_, elType); + if(sideOfChild >= 0) { + surfaceRegion = NEW SurfaceRegion_ED(child1->getElementData()); + surfaceRegion->setSide(sideOfChild); + surfaceRegion->setRegion(region_); + child1->setElementData(surfaceRegion); + } + + sideOfChild = parent->getSideOfChild(1, side_, elType); + if(sideOfChild >= 0) { + surfaceRegion = NEW SurfaceRegion_ED(child2->getElementData()); + surfaceRegion->side_ = sideOfChild; + surfaceRegion->region_ = region_; + child2->setElementData(surfaceRegion); + } + + return false; + }; + + ElementData *clone() const { + SurfaceRegion_ED *newObj = NEW SurfaceRegion_ED; + newObj->side_ = side_; + newObj->region_ = region_; + newObj->decorated_ = ElementData::clone(); + return newObj; + }; + + inline ::std::string getTypeName() const { return "SurfaceRegion_ED"; }; + + inline const int getTypeID() const { return SURFACE_REGION; }; + + void serialize(::std::ostream& out) + { + ElementData::serialize(out); + out.write(reinterpret_cast<const char*>(&side_), sizeof(int)); + out.write(reinterpret_cast<const char*>(®ion_), sizeof(int)); + }; + + void deserialize(::std::istream& in) + { + ElementData::deserialize(in); + in.read(reinterpret_cast<char*>(&side_), sizeof(int)); + in.read(reinterpret_cast<char*>(®ion_), sizeof(int)); + }; + + inline void setSide(int side) { side_ = side; }; + + inline int getSide() const { return side_; }; + + inline void setRegion(int region) { region_ = region; }; + + inline int getRegion() const { return region_; }; + + protected: + int side_; + int region_; + }; + +} + +#endif diff --git a/AMDiS/src/SystemVector.h b/AMDiS/src/SystemVector.h new file mode 100644 index 0000000000000000000000000000000000000000..d06cef478410c78387f0ef92c90b76775ab0cb79 --- /dev/null +++ b/AMDiS/src/SystemVector.h @@ -0,0 +1,549 @@ +// ============================================================================ +// == == +// == AMDiS - Adaptive multidimensional simulations == +// == == +// ============================================================================ +// == == +// == crystal growth group == +// == == +// == Stiftung caesar == +// == Ludwig-Erhard-Allee 2 == +// == 53175 Bonn == +// == germany == +// == == +// ============================================================================ +// == == +// == http://www.caesar.de/cg/AMDiS == +// == == +// ============================================================================ + +/** \file SystemVector.h */ + +#ifndef AMDIS_SYSTEMVECTOR_H +#define AMDIS_SYSTEMVECTOR_H + +#include "MemoryManager.h" +#include "MatrixVector.h" +#include "DOFVector.h" +#include "CreatorInterface.h" +#include "Serializable.h" +#include "OpenMP.h" + +namespace AMDiS { + + // ============================================================================ + // ===== class SystemVector =================================================== + // ============================================================================ + + /** \brief + * A system vector is a vector of dof vectors used for vector valued + * problems. + */ + class SystemVector : public Serializable + { + public: + MEMORY_MANAGED(SystemVector); + + /** \brief + * Creator. + */ + class Creator + : public CreatorInterface<SystemVector> { + public: + MEMORY_MANAGED(Creator); + + /** \brief + * Creators constructor. + */ + Creator(const ::std::string &name_, + ::std::vector<FiniteElemSpace*> feSpace_, + int size_) + : name(name_), feSpace(feSpace_), size(size_) + {}; + + /** \brief + * Destructor + */ + virtual ~Creator() {}; + + /** \brief + * Implementation of CreatorInterface::create(). + */ + SystemVector *create() { + int i; + char number[10]; + ::std::string numberedName; + SystemVector *result = NEW SystemVector(name, feSpace, size); + for(i=0; i < size; i++) { + sprintf(number, "[%d]", i); + numberedName = name + ::std::string(number); + result->setDOFVector(i, NEW DOFVector<double>(feSpace[i], numberedName)); + } + return result; + }; + + /** \brief + * Implementation of CreatorInterface::free(). + */ + void free(SystemVector *vec) { + for (int i = 0; i < size; i++) { + DELETE vec->getDOFVector(i); + vec->setDOFVector(i, NULL); + } + DELETE vec; + }; + + private: + /** \brief + * Name of the system vector + */ + ::std::string name; + + /** \brief + * Finite element space used for creation. + */ + ::std::vector<FiniteElemSpace*> feSpace; + + /** \brief + * Number of component vectors to be created + */ + int size; + }; + + public: + /** \brief + * Constructor. + */ + SystemVector(const ::std::string& name_, + ::std::vector<FiniteElemSpace*> feSpace_, + int size) + : name(name_), + feSpace(feSpace_), + vectors(size) + + { + vectors.set(NULL); + }; + + /** \brief + * Copy Constructor. + */ + SystemVector(const SystemVector& rhs) + : name(rhs.name), + feSpace(rhs.feSpace), + vectors(rhs.vectors.getSize()) + + { + int i; + for (i=0;i<vectors.getSize();i++) { + vectors[i]=new DOFVector<double>(*rhs.vectors[i]); + } + }; + + virtual ~SystemVector() { + // int i, size = vectors.getSize(); + // for(i = 0; i < size; i++) { + // if(vectors[i]) DELETE vectors[i]; + // } + }; + + /** \brief + * Sets \ref vectors[index] = vec. + */ + inline void setDOFVector(int index, DOFVector<double> *vec) { + TEST_EXIT(index < vectors.getSize())("invalid index\n"); + vectors[index] = vec; + }; + + /** \brief + * Returns \ref vectors[index]. + */ + inline DOFVector<double> *getDOFVector(int index) { + TEST_EXIT(index < vectors.getSize())("invalid index\n"); + return vectors[index]; + }; + + /** \brief + * Returns \ref vectors[index]. + */ + inline const DOFVector<double> *getDOFVector(int index) const { + TEST_EXIT(index < vectors.getSize())("invalid index\n"); + return vectors[index]; + }; + + /** \brief + * Returns sum of used vector sizes. + */ + inline int getUsedSize() const { + int i, totalSize = 0, size = vectors.getSize(); + for(i = 0; i < size; i++) { + totalSize += vectors[i]->getUsedSize(); + } + return totalSize; + }; + + /** \brief + * Returns number of contained vectors. + */ + inline int getNumVectors() const { + return vectors.getSize(); + }; + + inline int getSize() const { + return vectors.getSize(); + }; + + /** \brief + * Returns \ref feSpace. + */ + inline FiniteElemSpace *getFESpace(int i) const { return feSpace[i]; }; + + /** \brief + * Here the system vector is interpreted as one large vector. The given + * is used as a global index which indicates a local vector number and + * a local index on this vector. The operator returns this local vector + * at the local index. + */ + inline double& operator[](int index) { + int localIndex = index; + int vectorIndex = 0; + + while(localIndex >= vectors[vectorIndex]->getUsedSize()) { + localIndex -= vectors[vectorIndex++]->getUsedSize(); + } + + return (*(vectors[vectorIndex]))[localIndex]; + }; + + /** \brief + * For const access. + */ + inline double operator[](int index) const { + int localIndex = index; + int vectorIndex = 0; + + while(localIndex >= vectors[vectorIndex]->getUsedSize()) { + localIndex -= vectors[vectorIndex++]->getUsedSize(); + } + + return (*(vectors[vectorIndex]))[localIndex]; + }; + + /** \brief + * Sets all entries in all vectors to value. + */ + inline void set(double value) { + int size = vectors.getSize(); + for (int i = 0; i < size; i++) { + vectors[i]->set(value); + } + }; + + /** \brief + * Sets all entries in all vectors to value. + */ + inline SystemVector& operator=(double value) { + int size = vectors.getSize(); + for (int i = 0; i < size; i++) { + (*(vectors[i])) = value; + } + return *this; + }; + + /** \brief + * Assignement operator. + */ + inline SystemVector& operator=(const SystemVector& rhs) { + TEST_EXIT(rhs.vectors.getSize() == vectors.getSize()) + ("invalied sizes\n"); + int i, size = vectors.getSize(); + for(i = 0; i < size; i++) { + (*(vectors[i])) = (*(rhs.getDOFVector(i))); + } + return *this; + }; + + void serialize(::std::ostream &out) { + int i, size = vectors.getSize(); + out.write(reinterpret_cast<const char*>(&size), sizeof(int)); + for(i = 0; i < size; i++) { + vectors[i]->serialize(out); + } + }; + + void deserialize(::std::istream &in) { + int i, size, oldSize = vectors.getSize(); + in.read(reinterpret_cast<char*>(&size), sizeof(int)); + vectors.resize(size); + for(i = oldSize; i < size; i++) { + vectors[i] = NEW DOFVector<double>(feSpace[i], ""); + } + for(i = 0; i < size; i++) { + vectors[i]->deserialize(in); + } + }; + + void copy(const SystemVector& rhs) { + int i, size = vectors.getSize(); + TEST_EXIT(size == rhs.getNumVectors())("invalid sizes\n"); + for(i = 0; i < size; i++) { + vectors[i]->copy(*(const_cast<SystemVector&>(rhs).getDOFVector(i))); + } + }; + + void interpol(::std::vector<AbstractFunction<double, WorldVector<double> >*> *f) { + int i, size = vectors.getSize(); + for(i = 0; i < size; i++) { + vectors[i]->interpol((*f)[i]); + } + }; + + void print() { + int i, size = vectors.getSize(); + for(i = 0; i < size; i++) { + vectors[i]->print(); + } + }; + + + + protected: + /** \brief + * Name of the system vector + */ + ::std::string name; + + /** \brief + * Finite element space. + */ + ::std::vector<FiniteElemSpace*> feSpace; + + /** \brief + * Local dof vectors. + */ + Vector<DOFVector<double>*> vectors; + }; + + /** \brief + * multiplication with scalar + */ + inline const SystemVector& operator*=(SystemVector& x, double d) { + int i, size = x.getNumVectors(); + for(i = 0; i < size; i++) { + *(x.getDOFVector(i)) *= d; + } + return x; + }; + + /** \brief + * scalar product + */ + inline double operator*(SystemVector& x, SystemVector& y) { + TEST_EXIT(x.getNumVectors() == y.getNumVectors()) + ("invalid size\n"); + double result = 0.0; + int i, size = x.getNumVectors(); + for(i = 0; i < size; i++) { + result += (*x.getDOFVector(i)) * (*y.getDOFVector(i)); + }; + return result; + }; + + /** \brief + * addition of two system vectors + */ + inline const SystemVector& operator+=(SystemVector& x, + const SystemVector& y) + { + TEST_EXIT(x.getNumVectors() == y.getNumVectors()) + ("invalid size\n"); + int i, size = x.getNumVectors(); + for(i = 0; i < size; i++) { + (*(x.getDOFVector(i))) += (*(y.getDOFVector(i))); + } + return x; + }; + + /** + * subtraction of two system vectors. + */ + inline const SystemVector& operator-=(SystemVector& x, + SystemVector& y) + { + TEST_EXIT(x.getNumVectors() == y.getNumVectors()) + ("invalid size\n"); + int i, size = x.getNumVectors(); + for(i = 0; i < size; i++) { + (*(x.getDOFVector(i))) -= (*(y.getDOFVector(i))); + } + return x; + }; + + /** \brief + * multiplication with a scalar + */ + inline SystemVector operator*(SystemVector& x, double d) { + SystemVector result = x; + int i, size = x.getNumVectors(); + for(i = 0; i < size; i++) { + (*(result.getDOFVector(i))) *= d; + } + return result; + }; + + /** \brief + * multiplication with a scalar + */ + inline SystemVector operator*(double d, SystemVector& x) { + SystemVector result = x; + int i, size = x.getNumVectors(); + for(i = 0; i < size; i++) { + (*(result.getDOFVector(i))) *= d; + } + return result; + }; + + /** \brief + * addition of two system vectors + */ + inline SystemVector operator+(const SystemVector& x, + const SystemVector& y) + { + TEST_EXIT(x.getNumVectors() == y.getNumVectors()) + ("invalid size\n"); + SystemVector result = x; + int i, size = x.getNumVectors(); + for(i = 0; i < size; i++) { + (*(result.getDOFVector(i))) += (*(y.getDOFVector(i))); + } + return result; + }; + + /** \brief + * Calls SystemVector::set(). Used for solving. + */ + inline void set(SystemVector& x, double value) { + x.set(value); + }; + + /** \brief + * Calls SystemVector::set(). Used for solving. + */ + inline void setValue(SystemVector& x, double value) { + x.set(value); + }; + + /** \brief + * Norm of system vector. + */ + inline double norm(SystemVector* x) { + double result = 0.0; + int i, size = x->getNumVectors(); + for(i = 0; i < size; i++) { + result += x->getDOFVector(i)->squareNrm2(); + } + return sqrt(result); + }; + + /** \brief + * L2 norm of system vector. + */ + inline double L2Norm(SystemVector* x) { + double result = 0.0; + int i, size = x->getNumVectors(); + for(i = 0; i < size; i++) { + result += x->getDOFVector(i)->L2NormSquare(); + } + return sqrt(result); + }; + + /** \brief + * H1 norm of system vector. + */ + inline double H1Norm(SystemVector* x) { + double result = 0.0; + int i, size = x->getNumVectors(); + for(i = 0; i < size; i++) { + result += x->getDOFVector(i)->H1NormSquare(); + } + return sqrt(result); + }; + + inline void mv(Matrix<DOFMatrix*> &matrix, + const SystemVector &x, + SystemVector &result, + bool add = false) + { + int size = x.getNumVectors(); + + TEST_EXIT(size == result.getNumVectors())("incompatible sizes\n"); + TEST_EXIT(size == matrix.getNumRows())("incompatible sizes\n"); + TEST_EXIT(size == matrix.getNumCols())("incompatible sizes\n"); + + int i, j; + +#ifdef _OPENMP +#pragma omp parallel for schedule(static, 1) default(shared) private(i,j) +#endif + for (i = 0; i < size; i++) { + if (!add) result.getDOFVector(i)->set(0.0); + for (j = 0; j < size; j++) { + if (matrix[i][j]) { + mv<double>(NoTranspose, + *(matrix[i][j]), + *(x.getDOFVector(j)), + *(result.getDOFVector(i)), + true); + } + } + } + }; + + /** \brief + * y = a*x + y; + */ + inline void axpy(double a, SystemVector& x, SystemVector& y) + { + TEST_EXIT(x.getNumVectors() == y.getNumVectors()) + ("invalid size\n"); + int i, size = x.getNumVectors(); + +#ifdef _OPENMP +#pragma omp parallel for schedule(static, 1) default(shared) private(i) +#endif + for (i = 0; i < size; i++) { + axpy(a, *(x.getDOFVector(i)), *(y.getDOFVector(i))); + } + }; + + /** \brief + * y = x + a*y + */ + inline void xpay(double a, SystemVector& x, SystemVector& y) + { + TEST_EXIT(x.getNumVectors() == y.getNumVectors()) + ("invalid size\n"); + int i, size = x.getNumVectors(); + +#ifdef _OPENMP +#pragma omp parallel for schedule(static, 1) default(shared) private(i) +#endif + for (i = 0; i < size; i++) { + xpay(a, *(x.getDOFVector(i)), *(y.getDOFVector(i))); + } + } + + /** \brief + * Returns SystemVector::getUsedSize(). + */ + inline int size(SystemVector* vec) { + return vec->getUsedSize(); + }; + + inline void print(SystemVector* vec) { + vec->print(); + }; + +} + +#endif // AMDIS_SYSTEMVECTOR_H diff --git a/AMDiS/src/TFQMR.h b/AMDiS/src/TFQMR.h new file mode 100644 index 0000000000000000000000000000000000000000..66c1933cf13f26e53b160161c257508e7451e28c --- /dev/null +++ b/AMDiS/src/TFQMR.h @@ -0,0 +1,114 @@ +// == AMDiS - Adaptive multidimensional simulations == +// == == +// ============================================================================ +// == == +// == crystal growth group == +// == == +// == Stiftung caesar == +// == Ludwig-Erhard-Allee 2 == +// == 53175 Bonn == +// == germany == +// == == +// ============================================================================ +// == == +// == http://www.caesar.de/cg/AMDiS == +// == == +// ============================================================================ + +/** \file TFQMR.h */ + +#ifndef AMDIS_TFQMR_H +#define AMDIS_TFQMR_H + +#include "OEMSolver.h" +#include "MemoryManager.h" + +namespace AMDiS { + + // ============================================================================ + // ===== class TFQMR ========================================================== + // ============================================================================ + + /** + * \ingroup Solver + * + * \brief + */ + template<typename VectorType> + class TFQMR : public OEMSolver<VectorType> + { + public: + MEMORY_MANAGED(GMResSolver2<VectorType>); + + /** \brief + * Creator class used in the OEMSolverMap. + */ + class Creator : public OEMSolverCreator<VectorType> + { + public: + MEMORY_MANAGED(Creator); + + virtual ~Creator() {}; + + /** \brief + * Returns a new TFQMR object. + */ + OEMSolver<VectorType>* create() { + return NEW TFQMR<VectorType>(this->name); + }; + }; + + /** \brief + * constructor + */ + TFQMR(::std::string name); + + /** \brief + * destructor + */ + ~TFQMR(); + + protected: + /** \brief + * realisation of OEMSolver::solveSystem + */ + int solveSystem(MatVecMultiplier<VectorType> *mv, VectorType *x, VectorType *b); + + /** \brief + * realisation of OEMSolver::init + */ + void init(); + + /** \brief + * realisation of OEMSolver::exit + */ + void exit(); + + private: + /** \brief + * Stores the tolerance boundary for numerical computations. + */ + double TOL_; + + VectorType *r0_; + + /** \brief + * Stores intermediate results in the orthogonalization step. + */ + VectorType *w_; + + /** \brief + * Pointers to the vectors of the orthogonal system. + */ + VectorType *y1_, *y2_; + + VectorType *v_, *d_, *tmp_; + + }; + + +} + +#include "TFQMR.hh" + +#endif // AMDIS_TFQMR_H diff --git a/AMDiS/src/TFQMR.hh b/AMDiS/src/TFQMR.hh new file mode 100644 index 0000000000000000000000000000000000000000..ae8ea1f23e825c60661805bb0d8c72724015d7b6 --- /dev/null +++ b/AMDiS/src/TFQMR.hh @@ -0,0 +1,183 @@ +#include "TFQMR.h" +#include "Preconditioner.h" + +namespace AMDiS { + + template<typename VectorType> + TFQMR<VectorType>::TFQMR(::std::string name) + : OEMSolver<VectorType>(name), + TOL_(1.e-25) + { + FUNCNAME("TFQMR::TFQMR()"); + } + + template<typename VectorType> + TFQMR<VectorType>::~TFQMR() + {} + + template<typename VectorType> + void TFQMR<VectorType>::init() + { + r0_ = this->vectorCreator->create(); + w_ = this->vectorCreator->create(); + y1_ = this->vectorCreator->create(); + y2_ = this->vectorCreator->create(); + v_ = this->vectorCreator->create(); + d_ = this->vectorCreator->create(); + tmp_ = this->vectorCreator->create(); + } + + template<typename VectorType> + void TFQMR<VectorType>::exit() + { + if (r0_) { + this->vectorCreator->free(r0_); + this->vectorCreator->free(w_); + this->vectorCreator->free(y1_); + this->vectorCreator->free(y2_); + this->vectorCreator->free(v_); + this->vectorCreator->free(d_); + this->vectorCreator->free(tmp_); + } + } + + template<typename VectorType> + int TFQMR<VectorType>::solveSystem(MatVecMultiplier<VectorType> *matVec, + VectorType *x, + VectorType *b) + { + DOFMatrix *m = (dynamic_cast<StandardMatVec<DOFMatrix, VectorType> *>(matVec))->getMatrix(); + + matVec->matVec(NoTranspose, *x, *r0_); + xpay(-1.0, *b, *r0_); + double tau = norm(r0_); + ::std::cout << "NORM: " << tau << ::std::endl; + + for (int iter = 0; iter < 1000; iter++) { + for (int i = 0; i < x->getSize(); i++) { + (*y1_)[i] = (*b)[i]; + + for (int j = 0; j < static_cast<int>((*m)[i].size()); j++) { + MatEntry a = (*m)[i][j]; + + if (a.col != i) { + (*y1_)[i] -= (*x)[i] * a.entry; + } + } + + (*y1_)[i] /= (*m)[i][0].entry; + } + + *x = *y1_; + } + + matVec->matVec(NoTranspose, *x, *r0_); + xpay(-1.0, *b, *r0_); + tau = norm(r0_); + ::std::cout << "NORM: " << tau << ::std::endl; + + return 1000; + } + + // template<typename VectorType> +// int TFQMR<VectorType>::solveSystem(MatVecMultiplier<VectorType> *matVec, +// VectorType *x, +// VectorType *b) +// { +// FUNCNAME("TFQMR::solveSystem()"); + +// double old_res = -1.0; + +// // If norm of b is smaller than the tolarance, we can assume b to be zero. +// // Hence, x = 0 is the solution of the linear system. +// if (norm(b) < TOL_) { +// INFO(this->info, 2)("b == 0, x = 0 is the solution of the linear system\n"); +// set(*x, 0.0); +// this->residual = 0.0; +// return(0); +// } + +// // r_0 = b - Ax, where r_0 is already stored as the first vector in the +// // matrix V. +// matVec->matVec(NoTranspose, *x, *r0_); +// xpay(-1.0, *b, *r0_); + +// if (this->leftPrecon) +// this->leftPrecon->precon(r0_); + +// *y1_ = *r0_; +// *w_ = *r0_; +// double tau = norm(r0_); + +// if (tau < this->tolerance) { +// this->residual = tau; +// return(0); +// } + +// matVec->matVec(NoTranspose, *y1_, *v_); +// d_->set(0.0); +// double eta = 0.0; +// double theta = 0.0; +// double rho1 = tau * tau; +// double rho2 = 0.0; +// double alpha = 0.0; +// double beta = 0.0; +// double c = 0.0; + +// START_INFO(); +// for (int j = 1; j <= this->max_iter; j++) { +// rho2 = *v_ * *r0_; +// alpha = rho1 / rho2; +// *y2_ = *y1_; +// axpy(-alpha, *v_, *y2_); + +// for (int m = 2 * j - 1; m <= 2 * j; m++) { +// matVec->matVec(NoTranspose, *y1_, *tmp_); +// axpy(-alpha, *tmp_, *w_); + +// if (this->leftPrecon) +// this->leftPrecon->precon(w_); + +// xpay(theta * theta * eta / alpha, *y1_, *d_); + + +// theta = norm(w_) / tau; +// c = 1 / sqrt(theta * theta + 1); +// eta = c * c * alpha; +// axpy(eta, *d_, *x); +// tau = tau * theta * c; +// this->residual = sqrt(m + 1) * tau; +// *y1_ = *y2_; +// } + +// if (SOLVE_INFO(j - 1, this->residual, &old_res)) +// return(j - 1); + +// rho2 = *w_ * *r0_; +// beta = rho2 / rho1; +// *y1_ = *w_; +// axpy(beta, *y2_, *y1_); + + +// matVec->matVec(NoTranspose, *y2_, *tmp_); + +// if (this->leftPrecon) +// this->leftPrecon->precon(tmp_); + +// xpay(beta, *tmp_, *v_); + +// matVec->matVec(NoTranspose, *y1_, *tmp_); + +// if (this->leftPrecon) +// this->leftPrecon->precon(tmp_); + + +// xpay(beta, *tmp_, *v_); + +// rho1 = rho2; +// } + +// return 0; +// } + +} diff --git a/AMDiS/src/TecPlotWriter.cc b/AMDiS/src/TecPlotWriter.cc new file mode 100644 index 0000000000000000000000000000000000000000..cbaa0a32e3e587e8d5085910bc9d0cf6a4bb281d --- /dev/null +++ b/AMDiS/src/TecPlotWriter.cc @@ -0,0 +1,133 @@ +#include "TecPlotWriter.h" +#include "DOFVector.h" +#include "SystemVector.h" + +namespace AMDiS { + + template<> + int TecPlotWriter<DOFVector<double> >::writeValuesFct(ElInfo* elinfo) + { + const DOFAdmin* admin = values->getFESpace()->getAdmin(); + int n0 = admin->getNumberOfPreDOFs(VERTEX); + const DegreeOfFreedom **dof = elinfo->getElement()->getDOF(); + + int dim = elinfo->getMesh()->getDim(); + int dow = Global::getGeo(WORLD); + + // for every vertex + for(int i=0; i < dim+1; i++) { + + // search for coords of this vertex in the coord-list of this dof + DOFCoords::iterator coords = find(dofCoords[dof[i][n0]].begin(), + dofCoords[dof[i][n0]].end(), + elinfo->getCoord(i)); + + if(coords == dofCoords[dof[i][n0]].end()) { // coords not found + // add coords to list + VertexInfo newCoords; + newCoords.coord = elinfo->getCoord(i); + newCoords.vertex_index = nv++; + dofCoords[dof[i][n0]].push_back(newCoords); + + // write coords of vertex + if(writeCoords) { + for(int j=0; j < dow; j++) { + (*outFile) << elinfo->getCoord(i)[j] << " "; + } + } + + // write value + (*outFile) << (*values)[dof[i][n0]] << ::std::endl; + + } + } + return 0; + } + + template<> + int TecPlotWriter<SystemVector>::writeValuesFct(ElInfo* elinfo) + { + const DOFAdmin* admin = values->getDOFVector(0)->getFESpace()->getAdmin(); + int n0 = admin->getNumberOfPreDOFs(VERTEX); + const DegreeOfFreedom **dof = elinfo->getElement()->getDOF(); + + int dim = elinfo->getMesh()->getDim(); + int dow = Global::getGeo(WORLD); + + // for every vertex + for(int i=0; i < dim+1; i++) { + + // search for coords of this vertex in the coord-list of this dof + DOFCoords::iterator coords = find(dofCoords[dof[i][n0]].begin(), + dofCoords[dof[i][n0]].end(), + elinfo->getCoord(i)); + + if(coords == dofCoords[dof[i][n0]].end()) { // coords not found + // add coords to list + VertexInfo newCoords; + newCoords.coord = elinfo->getCoord(i); + newCoords.vertex_index = nv++; + dofCoords[dof[i][n0]].push_back(newCoords); + + // write coords of vertex + if(writeCoords) { + for(int j=0; j < dow; j++) { + (*outFile) << elinfo->getCoord(i)[j] << " "; + } + } + + // write value + for(int j=0; j < values->getNumVectors(); j++) { + (*outFile) << (*(values->getDOFVector(i)))[dof[i][n0]] << " "; + } + (*outFile) << ::std::endl; + } + } + return 0; + } + + template<> + void TecPlotWriter<DOFVector<double> >::writeVarName(int dim) + { + switch(Global::getGeo(WORLD)) { + case 1: + (*outFile) << "VARIABLES = \"x\""; + break; + case 2: + (*outFile) << "VARIABLES = \"x\",\"y\""; + break; + case 3: + (*outFile) << "VARIABLES = \"x\",\"y\",\"z\""; + break; + default: + ERROR_EXIT("invalid dim of world\n"); + } + (*outFile) << ",\"" << values->getName() << "\"" << ::std::endl; + } + + template<> + void TecPlotWriter<SystemVector>::writeVarName(int dim) + { + switch(Global::getGeo(WORLD)) { + case 1: + (*outFile) << "VARIABLES = \"x\""; + break; + case 2: + (*outFile) << "VARIABLES = \"x\",\"y\""; + break; + case 3: + (*outFile) << "VARIABLES = \"x\",\"y\",\"z\""; + break; + default: + ERROR_EXIT("invalid dim of world\n"); + } + + int i, number = values->getNumVectors(); + for(i = 0; i < number; i++) { + (*outFile) << ",\"" << values->getDOFVector(i)->getName() << "\""; + } + (*outFile) << ::std::endl; + } + +} + diff --git a/AMDiS/src/TecPlotWriter.h b/AMDiS/src/TecPlotWriter.h new file mode 100644 index 0000000000000000000000000000000000000000..0d0afad9ce31935a8605998255e66d383d306a54 --- /dev/null +++ b/AMDiS/src/TecPlotWriter.h @@ -0,0 +1,91 @@ +// ============================================================================ +// == == +// == AMDiS - Adaptive multidimensional simulations == +// == == +// ============================================================================ +// == == +// == crystal growth group == +// == == +// == Stiftung caesar == +// == Ludwig-Erhard-Allee 2 == +// == 53175 Bonn == +// == germany == +// == == +// ============================================================================ +// == == +// == http://www.caesar.de/cg/AMDiS == +// == == +// ============================================================================ + +/** \file TecPlotWriter.h */ + +#ifndef AMDIS_TEC_PLOT_WRITER_H +#define AMDIS_TEC_PLOT_WRITER_H + +#include "FixVec.h" +#include <fstream> +#include <vector> + +namespace AMDiS { + + class ElInfo; + class Mesh; + + // ============================================================================ + // ===== class TecPlotWriter ================================================== + // ============================================================================ + + /** \ingroup Output + * \brief + * Writes a DOFVector in TecPlot format to a ascii file + */ + template<typename T> + class TecPlotWriter + { + public: + /** \brief + * Writes the DOFVector values to the file with given name. Different + * DOFVectors belonging to the same triangulation can be written to one + * file by setting additional=true for all DOFVectors except for the first + * one. + */ + static void writeValues(T* values, + const char* filename, + const char* plotTitle, + bool additional=false); + + private: + static int writeValuesFct(ElInfo* elinfo); + static int writeIndicesFct(ElInfo* elinfo); + static void writeVarName(int dim); + + private: + class VertexInfo { + public: + WorldVector<double> coord; + int vertex_index; + + public: + inline bool operator==(const WorldVector<double>& coor) { + return (coor == coord); + }; + + inline bool operator!=(const WorldVector<double>& coor) { + return !(*this == coor); + }; + }; + + typedef ::std::vector<VertexInfo> DOFCoords; + + static T* values; + static int nv; + static ::std::ofstream* outFile; + static bool writeCoords; + static ::std::vector<DOFCoords> dofCoords; + }; + +} + +#include "TecPlotWriter.hh" + +#endif diff --git a/AMDiS/src/TecPlotWriter.hh b/AMDiS/src/TecPlotWriter.hh new file mode 100644 index 0000000000000000000000000000000000000000..0105a1051a245ba09e98a31a7363e4898a1b42ce --- /dev/null +++ b/AMDiS/src/TecPlotWriter.hh @@ -0,0 +1,137 @@ +#include <fstream> +#include <algorithm> + +#include "FixVec.h" +#include "Mesh.h" +#include "Flag.h" + +namespace AMDiS { + + template<typename T> T* TecPlotWriter<T>::values = NULL; + + template<typename T> int TecPlotWriter<T>::nv = 1; + + template<typename T> ::std::ofstream* TecPlotWriter<T>::outFile = NULL; + + template<typename T> bool TecPlotWriter<T>::writeCoords = false; + + template<typename T> ::std::vector<typename TecPlotWriter<T>::DOFCoords> + TecPlotWriter<T>::dofCoords; + + template<typename T> + int TecPlotWriter<T>::writeIndicesFct(ElInfo* elinfo) + { + const DOFAdmin* admin = values->getFESpace()->getAdmin(); + int n0 = admin->getNumberOfPreDOFs(VERTEX); + const DegreeOfFreedom **dof = elinfo->getElement()->getDOF(); + + int dim = elinfo->getMesh()->getDim(); + // int dow = Global::getGeo(WORLD); + + for(int i=0; i < dim+1; i++) { + typename DOFCoords::iterator coords = find(dofCoords[dof[i][n0]].begin(), + dofCoords[dof[i][n0]].end(), + elinfo->getCoord(i)); + TEST_EXIT(coords != dofCoords[dof[i][n0]].end())("coords not found"); + (*outFile) << coords->vertex_index << " "; + if(dim == 1 && i == 1) { + (*outFile) << coords->vertex_index; + } + } + (*outFile) << ::std::endl; + + return 0; + } + + template<typename T> + void TecPlotWriter<T>::writeValues(T* val, + const char* filename, + const char* plotTitle, + bool additional) + { + values = val; + + TEST_EXIT(values)("no values\n"); + TEST_EXIT(filename)("no filename\n"); + TEST_EXIT(plotTitle)("no plotTitle\n"); + TEST_EXIT(values->getFESpace())("no fe-space\n"); + TEST_EXIT(values->getFESpace()->getMesh())("no mesh\n"); + + if(!additional) + outFile = new ::std::ofstream(filename); + else + outFile = new ::std::ofstream(filename, ::std::ios::app); + + TEST_EXIT(outFile)("can't open file %s\n", filename); + + outFile->setf(::std::ios::scientific,::std::ios::floatfield); + + const DOFAdmin* admin = values->getFESpace()->getAdmin(); + Mesh* mesh = values->getFESpace()->getMesh(); + + mesh->dofCompress(); + dofCoords.resize(admin->getUsedSize()); + + int dim = mesh->getDim(); + int dow = Global::getGeo(WORLD); + + writeCoords = !additional; + + if(dim == 1 && dow == 1) { // use ordered plot + if(!additional) { + (*outFile) << "TITLE = \"" << plotTitle << "\"" << ::std::endl; + } + + // write file header + if(!additional) { + writeVarName(dim); + } + (*outFile) << "ZONE T=\"" << values->getName() << "\", I=" << + mesh->getNumberOfVertices(); + (*outFile) << ", F=POINT"; + if(additional) { + (*outFile) << ", D=(1)"; + } + (*outFile) << ::std::endl << ::std::endl; + + + // write data + mesh->traverse(-1, Mesh::CALL_LEAF_EL|Mesh::FILL_COORDS, writeValuesFct); + + } else { // dow !=1 => use FE-plot + for(int i=0; i < 150; i++) + (*outFile) << " "; + (*outFile) << ::std::endl; + + // write data + nv = 1; + mesh->traverse(-1, Mesh::CALL_LEAF_EL|Mesh::FILL_COORDS, writeValuesFct); + (*outFile) << ::std::endl; + mesh->traverse(-1, Mesh::CALL_LEAF_EL|Mesh::FILL_COORDS, writeIndicesFct); + + // write file header + outFile->seekp(0); + + if(!additional) { + (*outFile) << "TITLE = \"" << plotTitle << "\"" << ::std::endl; + writeVarName(dim); + } + + (*outFile) << "ZONE T=\"" << values->getName() << "\", N=" << nv-1; + (*outFile) << ", E=" << mesh->getNumberOfLeaves(); + (*outFile) << ", F=FEPOINT"; + (*outFile) << ((dim==3) ? ", ET=TETRAHEDRON" : ", ET=TRIANGLE"); + if(additional) { + (*outFile) << ", D=("; + (*outFile) << ((dim==3) ? "1,2,3" : "1,2"); + (*outFile) << ",FECONNECT)"; + } + (*outFile) << ::std::endl; + + } + + dofCoords.resize(0); + delete outFile; + } + +} diff --git a/AMDiS/src/Tetrahedron.cc b/AMDiS/src/Tetrahedron.cc new file mode 100644 index 0000000000000000000000000000000000000000..d8acb41de0e9179633f79e6b9dce4de7644a923f --- /dev/null +++ b/AMDiS/src/Tetrahedron.cc @@ -0,0 +1,177 @@ +#include "Tetrahedron.h" +#include "DOFAdmin.h" +#include "Mesh.h" +#include "CoarseningManager.h" +#include "FixVec.h" + +namespace AMDiS { + + const unsigned char Tetrahedron::nChildEdge[3][2][2] = {{{5,4},{4,5}}, + {{5,4},{5,4}}, + {{5,4},{5,4}}}; + const unsigned char Tetrahedron::nChildFace[3][2][2] = {{{1,2},{2,1}}, + {{1,2},{1,2}}, + {{1,2},{1,2}}}; + const int Tetrahedron::childVertex[3][2][4] = {{{0,2,3,4},{1,3,2,4}}, + {{0,2,3,4},{1,2,3,4}}, + {{0,2,3,4},{1,2,3,4}}}; + const int Tetrahedron::childEdge[3][2][6] = {{{1,2,0,5,5,4},{4,3,0,5,5,4}}, + {{1,2,0,5,4,5},{3,4,0,5,4,5}}, + {{1,2,0,5,4,5},{3,4,0,5,4,5}}}; + const unsigned char Tetrahedron::adjacentChild[2][2] = {{0,1}, {1,0}}; + + const signed char Tetrahedron::childOrientation[3][2] = {{1,1}, + {1,-1}, + {1,-1}}; + + const unsigned char Tetrahedron::edgeOfDOFs[4][4] = {{255,0,1,2}, + {0,255,3,4}, + {1,3,255,5}, + {2,4,5,255}}; + + const int Tetrahedron::vertexOfEdge[6][2] = {{0,1}, + {0,2}, + {0,3}, + {1,2}, + {1,3}, + {2,3}}; + const int Tetrahedron::vertexOfFace[4][3] = {{1,2,3}, + {0,2,3}, + {0,1,3}, + {0,1,2}}; + + + const int Tetrahedron::sideOfChild[3][2][4] = {{{-1, 3, 1, 2}, // type 0 + {3, -1, 2, 1}}, + {{-1, 3, 1, 2}, // type 1 + {3, -1, 1, 2}}, + {{-1, 3, 1, 2}, // type 2 + {3, -1, 1, 2}}}; + + const int Tetrahedron::vertexOfParent[3][2][4] = {{{0, 2, 3, -1}, // type 0 + {1, 3, 2, -1}}, + {{0, 2, 3, -1}, // type 1 + {1, 2, 3, -1}}, + {{0, 2, 3, -1}, // type 2 + {1, 2, 3, -1}}}; + + const int Tetrahedron::edgeOfFace[4][3] = {{5, 4, 3}, // face 0 + {5, 2, 1}, // face 1 + {4, 2, 0}, // face 2 + {3, 1, 0}}; // face 3 + + bool Tetrahedron::hasSide(Element* sideElem) const + { + FUNCNAME("Tetrahedron::hasSide"); + TEST_EXIT(sideElem->isTriangle())("called for sideElem-type != Triangle\n"); + ERROR_EXIT("not yet\n"); + return false; + } + + int Tetrahedron::getVertexOfPosition(GeoIndex position, + int positionIndex, + int vertexIndex) const + { + FUNCNAME("Triangle::getVertexOfPosition"); + switch(position) { + case VERTEX: + return positionIndex; + break; + case EDGE: + return vertexOfEdge[positionIndex][vertexIndex]; + break; + case FACE: + return vertexOfFace[positionIndex][vertexIndex]; + break; + case CENTER: + return vertexIndex; + break; + default: + ERROR_EXIT("invalid position\n"); + return 0; + } + } + + const FixVec<int, WORLD>& + Tetrahedron::sortFaceIndices(int face, FixVec<int,WORLD> *vec) const + { + static MatrixOfFixVecs<FixVec<int,WORLD> > *sorted_3d = NULL; + int no=0; + FixVec<int,WORLD> *val = NULL; + const int *vof = NULL; + + vof = vertexOfFace[face]; + + if(NULL == sorted_3d) { + sorted_3d = NEW MatrixOfFixVecs<FixVec<int,WORLD> >(3,4,7,NO_INIT); + + (*sorted_3d)[0][0][0]=(*sorted_3d)[0][0][1]= + (*sorted_3d)[0][0][2]=(*sorted_3d)[1][0][0]= + (*sorted_3d)[1][0][1]=(*sorted_3d)[1][0][2]= + (*sorted_3d)[1][1][0]=(*sorted_3d)[1][2][1]= + (*sorted_3d)[1][3][0]=(*sorted_3d)[1][4][2]= + (*sorted_3d)[1][5][1]=(*sorted_3d)[1][6][2]= + (*sorted_3d)[2][0][0]=(*sorted_3d)[2][0][1]= + (*sorted_3d)[2][0][2]=(*sorted_3d)[2][1][0]= + (*sorted_3d)[2][2][1]=(*sorted_3d)[2][3][0]= + (*sorted_3d)[2][4][2]=(*sorted_3d)[2][5][1]= + (*sorted_3d)[2][6][2]=(*sorted_3d)[3][0][0]= + (*sorted_3d)[3][0][1]=(*sorted_3d)[3][0][2]= + (*sorted_3d)[3][1][0]=(*sorted_3d)[3][2][1]= + (*sorted_3d)[3][3][0]=(*sorted_3d)[3][4][2]= + (*sorted_3d)[3][5][1]=(*sorted_3d)[3][6][2]=0; + + (*sorted_3d)[0][1][0]=(*sorted_3d)[0][2][1]= + (*sorted_3d)[0][3][0]=(*sorted_3d)[0][4][2]= + (*sorted_3d)[0][5][1]=(*sorted_3d)[0][6][2]= + (*sorted_3d)[2][1][2]=(*sorted_3d)[2][2][0]= + (*sorted_3d)[2][3][1]=(*sorted_3d)[2][4][1]= + (*sorted_3d)[2][5][2]=(*sorted_3d)[2][6][0]= + (*sorted_3d)[3][1][2]=(*sorted_3d)[3][2][0]= + (*sorted_3d)[3][3][1]=(*sorted_3d)[3][4][1]= + (*sorted_3d)[3][5][2]=(*sorted_3d)[3][6][0]=1; + + (*sorted_3d)[0][1][2]=(*sorted_3d)[0][2][0]= + (*sorted_3d)[0][3][1]=(*sorted_3d)[0][4][1]= + (*sorted_3d)[0][5][2]=(*sorted_3d)[0][6][0]= + (*sorted_3d)[1][1][2]=(*sorted_3d)[1][2][0]= + (*sorted_3d)[1][3][1]=(*sorted_3d)[1][4][1]= + (*sorted_3d)[1][5][2]=(*sorted_3d)[1][6][0]= + (*sorted_3d)[3][1][1]=(*sorted_3d)[3][2][2]= + (*sorted_3d)[3][3][2]=(*sorted_3d)[3][4][0]= + (*sorted_3d)[3][5][0]=(*sorted_3d)[3][6][1]=2; + + (*sorted_3d)[0][1][1]=(*sorted_3d)[0][2][2]= + (*sorted_3d)[0][3][2]=(*sorted_3d)[0][4][0]= + (*sorted_3d)[0][5][0]=(*sorted_3d)[0][6][1]= + (*sorted_3d)[1][1][1]=(*sorted_3d)[1][2][2]= + (*sorted_3d)[1][3][2]=(*sorted_3d)[1][4][0]= + (*sorted_3d)[1][5][0]=(*sorted_3d)[1][6][1]= + (*sorted_3d)[2][1][1]=(*sorted_3d)[2][2][2]= + (*sorted_3d)[2][3][2]=(*sorted_3d)[2][4][0]= + (*sorted_3d)[2][5][0]=(*sorted_3d)[2][6][1]=3; + } + + if (dof[vof[0]][0] < dof[vof[1]][0]) + no++; + if (dof[vof[1]][0] < dof[vof[2]][0]) + no += 2; + if (dof[vof[2]][0] < dof[vof[0]][0]) + no += 4; + + if (!(no >= 1 && no <= 6)){ + ERROR_EXIT("can not sort face indices of element %d at face %d\n", + getIndex(), face); + } + + if (vec) { + val = vec; + *val = (*sorted_3d)[face][no]; + } + else + val = &((*sorted_3d)[face][no]); + + return(*(const_cast<const FixVec<int,WORLD>* >(val))); + } + +} diff --git a/AMDiS/src/Tetrahedron.h b/AMDiS/src/Tetrahedron.h new file mode 100644 index 0000000000000000000000000000000000000000..330a9a70735c41777a71ea473a8f98263222c696 --- /dev/null +++ b/AMDiS/src/Tetrahedron.h @@ -0,0 +1,246 @@ +// ============================================================================ +// == == +// == AMDiS - Adaptive multidimensional simulations == +// == == +// ============================================================================ +// == == +// == crystal growth group == +// == == +// == Stiftung caesar == +// == Ludwig-Erhard-Allee 2 == +// == 53175 Bonn == +// == germany == +// == == +// ============================================================================ +// == == +// == http://www.caesar.de/cg/AMDiS == +// == == +// ============================================================================ + +/** \file Tetrahedron.h */ + +#ifndef AMDIS_TETRAHEDRON_H +#define AMDIS_TETRAHEDRON_H + +#include "Element.h" +#include "MemoryManager.h" + +namespace AMDiS { + + /** \ingroup Triangulation + * \brief + * A Tetrahedron is a 3-dimensional Element. + * + * A Tetrahedron and its refinements: + * + * <img src = "tetrahedron.png"> + */ + class Tetrahedron : public Element + { + public: + MEMORY_MANAGED(Tetrahedron); + + /** \brief + * calls base class contructor. + */ + Tetrahedron(Mesh* aMesh) : Element(aMesh) {}; + + /** \brief + * implements Element::clone + */ + inline Element *clone() { return NEW Tetrahedron(mesh); }; + + /** \brief + * implements Element::getVertexOfEdge + */ + inline int getVertexOfEdge(int i, int j) const { + return vertexOfEdge[i][j]; + }; + + /** \brief + * implements Element::getVertexOfPosition + */ + int getVertexOfPosition(GeoIndex position, + int positionIndex, + int vertexIndex) const; + + + virtual int getPositionOfVertex(int side, int vertex) const { + static int positionOfVertex[4][4] = {{-1,0,1,2}, + {0,-1,1,2}, + {0,1,-1,2}, + {0,1,2,-1}}; + return positionOfVertex[side][vertex]; + }; + + /** \brief + * implements Element::getGeo + */ + inline int getGeo(GeoIndex i) const { + switch(i) { + case VERTEX: case PARTS: case NEIGH: + return 4; + break; + case EDGE: + return 6; + case FACE: + return 4; + case CENTER: + return 1; + break; + case DIMEN: + return 3; + break; + case BOUNDARY: + return 14; + break; + case PROJECTION: + return 10; + break; + default: + ERROR_EXIT("invalid geo-index\n"); + return 0; + } + }; + + /** \brief + * implements Element::sideOfChild + */ + //int sideOfChild(int child, + // int side, bool *isVirtual, + // unsigned char elementType=0); + + /** \brief + * implements Element::hasSide + */ + bool hasSide(Element* sideElem) const; + + /** \brief + * implements Element::sortFaceIndices + */ + const FixVec<int,WORLD>& sortFaceIndices(int face, + FixVec<int,WORLD> *vec) const; + + /** \brief + * implements Element::isLine. Returns false because this element is a + * Tetrahedron + */ + inline bool isLine() const { return false; }; + + /** \brief + * implements Element::isTriangle. Returns false because this element is a + * Tetrahedron + */ + inline bool isTriangle() const { return false; }; + + /** \brief + * implements Element::isTetrahedron. Returns true because this element is a + * Tetrahedron + */ + inline bool isTetrahedron() const { return true; }; + + // ===== Serializable implementation ===== + + ::std::string getTypeName() const { return "Tetrahedron"; }; + + public: + /** \brief + * nChildEdge[el_type][ichild][dir] + * gives local index of new edge on child[ichild] part of face [2+dir] on + * the parent + */ + static const unsigned char nChildEdge[3][2][2]; + + /** \brief + * nChildFace[el_type][ichild][dir] + * gives local index of sub-face on child[ichild] part of face [2+dir] on + * the parent + */ + static const unsigned char nChildFace[3][2][2]; + + /** \brief + * childVertex[el_type][child][i] = + * parent's local vertex index of new vertex i. + * 4 stands for the newly generated vertex + */ + static const int childVertex[3][2][4]; + + /** \brief + * childEdge[el_type][child][i] = + * parent's local edge index of new edge i + * new edge 2 is half of old edge 0, + * new edges 4,5 are really new edges, and value is different: + * childEdge[][][4,5] = index of same edge in other child + */ + static const int childEdge[3][2][6]; + + /** \brief + * adjacentChild[position][ichild] + * gives number of the adjacent child on a neighbour element: + * position = 0 same position of element and neigh at refinement edge, + * position = 1 different ... + */ + static const unsigned char adjacentChild[2][2]; + + /** \brief + * childOrientation[el_type][child] = + * +1 if orientation is not changed during refinement, + * -1 if orientation is changed during refinement + */ + static const signed char childOrientation[3][2]; + + /** \brief + * edgeOfDOFs[i][j]: gives the local index of edge with vertices i and j + */ + static const unsigned char edgeOfDOFs[4][4]; + + static const int edgeOfFace[4][3]; + + /** \brief + * implements Element::getSideOfChild() + */ + virtual int getSideOfChild(int child, int side, int elType = 0) const { + FUNCNAME("Tetrahedron::getSideOfChild()"); + TEST_EXIT(child==0 || child==1)("child must be in (0,1)\n"); + TEST_EXIT(side >= 0 && side <= 3)("side must be between 0 and 3\n"); + TEST_EXIT(elType >= 0 && elType <= 2)("elType must be between 0 and 2\n"); + return sideOfChild[elType][child][side]; + }; + + /** \brief + * implements Element::getVertexOfParent() + */ + virtual int getVertexOfParent(int child, int side, int elType = 0) const { + FUNCNAME("Tetrahedron::getVertexOfParent()"); + TEST_EXIT(child==0 || child==1)("child must be in (0,1)\n"); + TEST_EXIT(side >= 0 && side <= 3)("side must be between 0 and 3\n"); + TEST_EXIT(elType >= 0 && elType <= 2)("elType must be between 0 and 2\n"); + return vertexOfParent[elType][child][side]; + }; + + inline int getEdgeOfFace(int face, int edge) const { + TEST_EXIT(face >= 0 && face < 4)("invalid face\n"); + TEST_EXIT(edge >= 0 && edge < 3)("invalid edge\n"); + return edgeOfFace[face][edge]; + }; + + protected: + + /** \brief + * vertexOfEdge[i][j] is the local number of the j-vertex of edge i + */ + static const int vertexOfEdge[6][2]; + + /** \brief + * vertexOfFace[i][j] is the local number of the j-vertex of face i + */ + static const int vertexOfFace[4][3]; + + static const int sideOfChild[3][2][4]; + + static const int vertexOfParent[3][2][4]; + }; + +} + +#endif // AMDIS_TETRAHEDRON_H diff --git a/AMDiS/src/TimedObject.h b/AMDiS/src/TimedObject.h new file mode 100644 index 0000000000000000000000000000000000000000..df73b4f41a473b76856792d2eb77badcaa0d836c --- /dev/null +++ b/AMDiS/src/TimedObject.h @@ -0,0 +1,63 @@ +// ============================================================================ +// == == +// == AMDiS - Adaptive multidimensional simulations == +// == == +// ============================================================================ +// == == +// == crystal growth group == +// == == +// == Stiftung caesar == +// == Ludwig-Erhard-Allee 2 == +// == 53175 Bonn == +// == germany == +// == == +// ============================================================================ +// == == +// == http://www.caesar.de/cg/AMDiS == +// == == +// ============================================================================ + +/** \file TimedObject.h */ + +#ifndef AMDIS_TIMEDOBJECT_H +#define AMDIS_TIMEDOBJECT_H + +namespace AMDiS { + + // =========================================================================== + // ===== class TimedObject =================================================== + // =========================================================================== + + /** \brief + * This class can be used as base class for time dependent objects where + * different objects refer to the same time. Herefore a pointer to + * a double value is stored, pointing to a time value, which can be + * managed in one central object, maybe the problem class. + */ + class TimedObject + { + public: + /** \brief + * Constructor. + */ + TimedObject() : timePtr(NULL) {}; + + /** \brief + * Sets the time pointer. + */ + inline void setTimePtr(double *timePtr_) { timePtr = timePtr_; }; + + /** \brief + * Returns the time pointer. + */ + inline double *getTimePtr() { return timePtr; }; + protected: + /** \brief + * Pointer to the externally managed time value. + */ + double *timePtr; + }; + +} + +#endif // AMDIS_TIMEDOBJECT_H diff --git a/AMDiS/src/Traverse.cc b/AMDiS/src/Traverse.cc new file mode 100644 index 0000000000000000000000000000000000000000..83a39215173ddc0234f75e6670dde28449bc8334 --- /dev/null +++ b/AMDiS/src/Traverse.cc @@ -0,0 +1,1123 @@ +#include "Traverse.h" +#include "Element.h" +#include "Line.h" +#include "Triangle.h" +#include "Tetrahedron.h" +#include "ElInfo.h" +#include "Mesh.h" +#include "Flag.h" +#include "MacroElement.h" +#include "FixVec.h" +#include "Parametric.h" + +namespace AMDiS { + + ElInfo* TraverseStack::traverseFirst(Mesh *mesh, int level, + Flag fill_flag) + { + FUNCNAME("TraverseStack::traverseFirst"); + int i; + + traverse_mesh = mesh; + traverse_level = level; + traverse_fill_flag = fill_flag; + + if (stack_size < 1) + enlargeTraverseStack(); + + Flag FILL_ANY = Mesh::getFillAnyFlag(mesh->getDim()); + + for (i=0; i<stack_size; i++) + elinfo_stack[i]->setFillFlag(fill_flag & FILL_ANY); + + elinfo_stack[0]->setMesh(mesh); + elinfo_stack[1]->setMesh(mesh); + + if (fill_flag.isSet(Mesh::CALL_LEAF_EL_LEVEL)) { + TEST_EXIT(level >= 0)("invalid level: %d\n",level); + } + + traverse_mel = NULL; + stack_used = 0; + el_count = 0; + + return(traverseNext(NULL)); + } + + + ElInfo* TraverseStack::traverseNext(ElInfo* elinfo_old) + { + FUNCNAME("TraverseStack::traverseNext"); + ElInfo *elinfo=NULL; + + ElInfo::traverseId = id; + + Parametric *parametric = traverse_mesh->getParametric(); + + if (stack_used) { + if (parametric) + elinfo_old = parametric->removeParametricInfo(elinfo_old); + + TEST_EXIT(elinfo_old == elinfo_stack[stack_used])("invalid old elinfo\n"); + } + else { + TEST_EXIT(elinfo_old == NULL)("invalid old elinfo != nil\n"); + } + + if (traverse_fill_flag.isSet(Mesh::CALL_LEAF_EL)) + elinfo = traverseLeafElement(); + else + if (traverse_fill_flag.isSet(Mesh::CALL_LEAF_EL_LEVEL)) + elinfo = traverseLeafElementLevel(); + else if (traverse_fill_flag.isSet(Mesh::CALL_EL_LEVEL)) + elinfo = traverseElementLevel(); + else if (traverse_fill_flag.isSet(Mesh::CALL_MG_LEVEL)) + elinfo = traverseMultiGridLevel(); + else + if (traverse_fill_flag.isSet(Mesh::CALL_EVERY_EL_PREORDER)) + elinfo = traverseEveryElementPreorder(); + else if (traverse_fill_flag.isSet(Mesh::CALL_EVERY_EL_INORDER)) + elinfo = traverseEveryElementInorder(); + else if (traverse_fill_flag.isSet(Mesh::CALL_EVERY_EL_POSTORDER)) + elinfo = traverseEveryElementPostorder(); + else + ERROR_EXIT("invalid traverse_flag\n"); + + if (elinfo) + el_count++; + else { + /* MSG("total element count:%d\n",el_count); */ + } + + if(elinfo) { + if(parametric) { + elinfo = parametric->addParametricInfo(elinfo); + } + elinfo->fillDetGrdLambda(); + } + + return(elinfo); + } + + + + /****************************************************************************/ + /* common (static) traversal routines for 2d and 3d */ + /* to be #included in traverse_r.c */ + /****************************************************************************/ + + /* traverse hierarchical mesh, call el_fct() for each/some element */ + + /****************************************************************************/ + /* recursive_traverse: */ + /* ------------------- */ + /* recursively traverse the mesh hierarchy tree */ + /* call the routine traverse_info->el_fct(el_info) with */ + /* - all tree leaves */ + /* - all tree leaves at a special level */ + /* - all tree elements in pre-/in-/post-order */ + /* depending on the traverse_info->level variable */ + /****************************************************************************/ + + int Traverse::recursive(ElInfo *elinfo) + { + FUNCNAME("Traverse::recursive"); + Element *el = elinfo->getElement(); + int mg_level,sum=0; + + Parametric *parametric = mesh->getParametric(); + + ElInfo::traverseId = id; + + if (flag.isSet(Mesh::CALL_LEAF_EL)) { + if (el->getFirstChild()) { + ElInfo* elinfo_new = mesh->createNewElInfo(); + elinfo_new->fillElInfo(0, elinfo); + sum+=recursive(elinfo_new); + elinfo_new->fillElInfo(1, elinfo); + sum+=recursive(elinfo_new); + DELETE elinfo_new; + } + else { + if (el_fct!=NULL) { + if(parametric) elinfo = parametric->addParametricInfo(elinfo); + elinfo->fillDetGrdLambda(); + sum+=el_fct(elinfo); + if(parametric) elinfo = parametric->removeParametricInfo(elinfo); + } + } + return (flag.isSet(Mesh::FILL_ADD_ALL))?sum:0;; + } + + if (flag.isSet(Mesh::CALL_LEAF_EL_LEVEL)) { + if (el->getFirstChild()) { + if ((elinfo->getLevel() >= level)) { + return (flag.isSet(Mesh::FILL_ADD_ALL))?sum:0; + } + ElInfo* elinfo_new = mesh->createNewElInfo(); + elinfo_new->fillElInfo(0, elinfo); + sum+=recursive(elinfo_new); + elinfo->fillElInfo(1, elinfo); + sum+=recursive(elinfo_new); + DELETE elinfo_new; + } + else { + if ((elinfo->getLevel() == level)&&(el_fct!=NULL)) { + if(parametric) elinfo = parametric->addParametricInfo(elinfo); + elinfo->fillDetGrdLambda(); + sum+=el_fct(elinfo); + if(parametric) elinfo = parametric->removeParametricInfo(elinfo); + } + } + return (flag.isSet(Mesh::FILL_ADD_ALL))?sum:0; + } + + if (flag.isSet(Mesh::CALL_EL_LEVEL)) { + if (elinfo->getLevel() == level) { + if (NULL!=el_fct) { + if(parametric) elinfo = parametric->addParametricInfo(elinfo); + elinfo->fillDetGrdLambda(); + sum+=el_fct(elinfo); + if(parametric) elinfo = parametric->removeParametricInfo(elinfo); + } + } + else { + if (elinfo->getLevel() > level){ + return(flag.isSet(Mesh::FILL_ADD_ALL))?sum:0; + } + else + if (el->getFirstChild()) { + ElInfo* elinfo_new = mesh->createNewElInfo(); + elinfo_new->fillElInfo(0, elinfo); + sum+=recursive(elinfo_new); + elinfo_new->fillElInfo(1, elinfo); + sum+=recursive(elinfo_new); + DELETE elinfo_new; + } + } + + return (flag.isSet(Mesh::FILL_ADD_ALL))?sum:0; + } + + if (flag.isSet(Mesh::CALL_MG_LEVEL)) { + + mg_level = (static_cast<int>(elinfo->getLevel()) + + mesh->getDim()-1) / mesh->getDim(); + + if (mg_level > static_cast<int>(level)) { + return 0; + } + + if (!(el->getFirstChild())) { + if (el_fct!=NULL) { + if(parametric) elinfo = parametric->addParametricInfo(elinfo); + elinfo->fillDetGrdLambda(); + sum+=el_fct(elinfo); + if(parametric) elinfo = parametric->removeParametricInfo(elinfo); + } + return (flag.isSet(Mesh::FILL_ADD_ALL))?sum:0; + } + + if ((mg_level == level) && ((elinfo->getLevel() % mesh->getDim()) == 0)) + { + if (el_fct!=NULL) { + if(parametric) elinfo = parametric->addParametricInfo(elinfo); + elinfo->fillDetGrdLambda(); + sum+=el_fct(elinfo); + if(parametric) elinfo = parametric->removeParametricInfo(elinfo); + } + return(flag.isSet(Mesh::FILL_ADD_ALL))?sum:0;; + } + + ElInfo* elinfo_new = mesh->createNewElInfo(); + + elinfo_new->fillElInfo(0, elinfo); + sum+=recursive(elinfo_new); + + elinfo_new->fillElInfo(1, elinfo); + sum+=recursive(elinfo_new); + + DELETE elinfo_new; + return(flag.isSet(Mesh::FILL_ADD_ALL))?sum:0; + + } + + if (flag.isSet(Mesh::CALL_EVERY_EL_PREORDER)) + if (el_fct != NULL) { + if(parametric) elinfo = parametric->addParametricInfo(elinfo); + elinfo->fillDetGrdLambda(); + sum+=el_fct(elinfo); + if(parametric) elinfo = parametric->removeParametricInfo(elinfo); + } + if (el->getFirstChild()) { + ElInfo* elinfo_new = mesh->createNewElInfo(); + + elinfo_new->fillElInfo(0, elinfo); + sum+= recursive(elinfo_new); + + if (flag.isSet(Mesh::CALL_EVERY_EL_INORDER)) + if (el_fct!=NULL) { + if(parametric) elinfo = parametric->addParametricInfo(elinfo); + elinfo->fillDetGrdLambda(); + sum+=el_fct(elinfo); + if(parametric) elinfo = parametric->removeParametricInfo(elinfo); + } + elinfo_new->fillElInfo(1, elinfo); + sum+= recursive(elinfo_new); + + DELETE elinfo_new; + } + else { + if (flag.isSet(Mesh::CALL_EVERY_EL_INORDER)) + if (el_fct!=NULL) { + if(parametric) elinfo = parametric->addParametricInfo(elinfo); + elinfo->fillDetGrdLambda(); + sum+=el_fct(elinfo); + if(parametric) elinfo = parametric->removeParametricInfo(elinfo); + } + } + + if (flag.isSet(Mesh::CALL_EVERY_EL_POSTORDER)) + if (el_fct!=NULL) { + if(parametric) elinfo = parametric->addParametricInfo(elinfo); + elinfo->fillDetGrdLambda(); + sum+=el_fct(elinfo); + if(parametric) elinfo = parametric->removeParametricInfo(elinfo); + } + return(flag.isSet(Mesh::FILL_ADD_ALL))?sum:0; + + } + + void TraverseStack::enlargeTraverseStack() + { + FUNCNAME("TraverseStack::enlargeTraverseStack"); + int i; + int new_stack_size = stack_size + 10; + + elinfo_stack.resize(new_stack_size, NULL); + + // create new elinfos + for(i=stack_size; i < new_stack_size; i++) { + TEST_EXIT(elinfo_stack[i]==NULL)("???\n"); + elinfo_stack[i] = traverse_mesh->createNewElInfo(); + } + + if (stack_size > 0) + for (i=stack_size; i<new_stack_size; i++) + elinfo_stack[i]->setFillFlag( elinfo_stack[0]->getFillFlag() ); + + info_stack.resize(new_stack_size); + save_elinfo_stack.resize(new_stack_size, NULL); + + // create new elinfos + for(i=stack_size; i < new_stack_size; i++) { + TEST_EXIT(save_elinfo_stack[i]==NULL)("???\n"); + save_elinfo_stack[i] = traverse_mesh->createNewElInfo(); + } + save_info_stack.resize(new_stack_size); + + stack_size = new_stack_size; + } + + + ElInfo* TraverseStack::traverseLeafElement() + { + FUNCNAME("TraverseStack::traverseLeafElement"); + + Element *el; + int i; + + if (stack_used == 0) /* first call */ + { + currentMacro = traverse_mesh->firstMacroElement(); + if(currentMacro == traverse_mesh->endOfMacroElements()) return NULL; + traverse_mel = *currentMacro; + + stack_used = 1; + elinfo_stack[stack_used]->fillMacroInfo(traverse_mel); + info_stack[stack_used] = 0; + + el = elinfo_stack[stack_used]->getElement(); + if ((el == NULL) || (el->getFirstChild() == NULL)) { + return(elinfo_stack[stack_used]); + } + } + else + { + el = elinfo_stack[stack_used]->getElement(); + + /* go up in tree until we can go down again */ + while((stack_used > 0) && + ((info_stack[stack_used] >= 2) || (el->getFirstChild()==NULL))) + { + stack_used--; + el = elinfo_stack[stack_used]->getElement(); + } + + /* goto next macro element */ + if (stack_used < 1) { + currentMacro++; + if(currentMacro == traverse_mesh->endOfMacroElements()) return NULL; + traverse_mel = *currentMacro; + + stack_used = 1; + elinfo_stack[stack_used]->fillMacroInfo(traverse_mel); + info_stack[stack_used] = 0; + + el = elinfo_stack[stack_used]->getElement(); + if ((el == NULL) || (el->getFirstChild() == NULL)) { + return(elinfo_stack[stack_used]); + } + } + } + + /* go down tree until leaf */ + while (el->getFirstChild()) + { + if (stack_used >= stack_size-1) enlargeTraverseStack(); + i = info_stack[stack_used]; + el = const_cast<Element*>( ((i==0) ? el->getFirstChild() : el->getSecondChild())); + info_stack[stack_used]++; + elinfo_stack[stack_used + 1]->fillElInfo(i, elinfo_stack[stack_used]); + stack_used++; + + + TEST_EXIT(stack_used < stack_size) + ("stack_size=%d too small, level=(%d,%d)\n", + stack_size, elinfo_stack[stack_used]->getLevel()); + + info_stack[stack_used] = 0; + } + + return elinfo_stack[stack_used]; + } + + ElInfo* TraverseStack::traverseLeafElementLevel() + { + FUNCNAME("TraverseStack::traverseLeafElementLevel"); + ERROR_EXIT("not yet implemented\n"); + return NULL; + } + + ElInfo* TraverseStack::traverseElementLevel() + { + FUNCNAME("TraverseStack::traverseElementLevel"); + + ElInfo *elInfo; + do { + elInfo = traverseEveryElementPreorder(); + } while (elInfo != NULL && elInfo->getLevel() != traverse_level); + return elInfo; + + // Element *el; + // int i; + + // if (stack_used == 0) /* first call */ + // { + // currentMacro = traverse_mesh->firstMacroElement(); + // traverse_mel = *currentMacro; + // if (traverse_mel == NULL) return NULL; + + // stack_used = 1; + // elinfo_stack[stack_used]->fillMacroInfo(traverse_mel); + // info_stack[stack_used] = 0; + + // if(elinfo_stack[stack_used]->getLevel() == traverse_level) + // return(elinfo_stack[stack_used]); + // } + + // el = elinfo_stack[stack_used]->getElement(); + + // /* go up in tree until we can go down again */ + // while((stack_used > 0) && + // ((info_stack[stack_used] >= 2) || + // (el->getFirstChild()==NULL) || + // (elinfo_stack[stack_used]->getLevel() == traverse_level))) + // { + // stack_used--; + // el = elinfo_stack[stack_used]->getElement(); + // } + + + // /* goto next macro element */ + // if (stack_used < 1) { + // currentMacro++; + // if (currentMacro == traverse_mesh->endOfMacroElements()) return(NULL); + // traverse_mel = *currentMacro; + + // stack_used = 1; + // elinfo_stack[stack_used]->fillMacroInfo(traverse_mel); + // info_stack[stack_used] = 0; + + // if(elinfo_stack[stack_used]->getLevel() == traverse_level) + // return(elinfo_stack[stack_used]); + // } + + + // /* go down tree */ + + // if (stack_used >= stack_size-1) enlargeTraverseStack(); + // i = info_stack[stack_used]; + // info_stack[stack_used]++; + + // elinfo_stack[stack_used + 1]->fillElInfo(i, elinfo_stack[stack_used]); + // stack_used++; + + // TEST_EXIT(stack_used < stack_size) + // ("stack_size=%d too small, level=%d\n", + // stack_size, elinfo_stack[stack_used]->getLevel()); + + // info_stack[stack_used] = 0; + + // if(elinfo_stack[stack_used]->getLevel() == traverse_level) + // return(elinfo_stack[stack_used]); + + // return traverseElementLevel(); + } + + ElInfo* TraverseStack::traverseMultiGridLevel() + { + FUNCNAME("TraverseStack::traverseMultiGridLevel"); + Element *el; + int i; + + if (stack_used == 0) /* first call */ + { + currentMacro = traverse_mesh->firstMacroElement(); + traverse_mel = *currentMacro; + if (traverse_mel == NULL) return NULL; + + stack_used = 1; + elinfo_stack[stack_used]->fillMacroInfo(traverse_mel); + info_stack[stack_used] = 0; + + if((elinfo_stack[stack_used]->getLevel() == traverse_level) || + (elinfo_stack[stack_used]->getLevel() < traverse_level && + elinfo_stack[stack_used]->getElement()->isLeaf())) + return(elinfo_stack[stack_used]); + } + + el = elinfo_stack[stack_used]->getElement(); + + /* go up in tree until we can go down again */ + while((stack_used > 0) && + ((info_stack[stack_used] >= 2) || (el->getFirstChild()==NULL))) + { + stack_used--; + el = elinfo_stack[stack_used]->getElement(); + } + + + /* goto next macro element */ + if (stack_used < 1) { + currentMacro++; + if (currentMacro == traverse_mesh->endOfMacroElements()) return(NULL); + traverse_mel = *currentMacro; + + stack_used = 1; + elinfo_stack[stack_used]->fillMacroInfo(traverse_mel); + info_stack[stack_used] = 0; + + if((elinfo_stack[stack_used]->getLevel() == traverse_level) || + (elinfo_stack[stack_used]->getLevel() < traverse_level && + elinfo_stack[stack_used]->getElement()->isLeaf())) + return(elinfo_stack[stack_used]); + } + + + /* go down tree */ + + if (stack_used >= stack_size-1) enlargeTraverseStack(); + i = info_stack[stack_used]; + info_stack[stack_used]++; + + elinfo_stack[stack_used + 1]->fillElInfo(i, elinfo_stack[stack_used]); + stack_used++; + + TEST_EXIT(stack_used < stack_size) + ("stack_size=%d too small, level=%d\n", + stack_size, elinfo_stack[stack_used]->getLevel()); + + info_stack[stack_used] = 0; + + if((elinfo_stack[stack_used]->getLevel() == traverse_level) || + (elinfo_stack[stack_used]->getLevel() < traverse_level && + elinfo_stack[stack_used]->getElement()->isLeaf())) + return(elinfo_stack[stack_used]); + + return traverseMultiGridLevel(); + } + + ElInfo* TraverseStack::traverseEveryElementPreorder() + { + FUNCNAME("TraverseStack::traverseEveryElementPreorder"); + + Element *el; + int i; + + if (stack_used == 0) /* first call */ + { + currentMacro = traverse_mesh->firstMacroElement(); + traverse_mel = *currentMacro; + if (traverse_mel == NULL) return NULL; + + stack_used = 1; + elinfo_stack[stack_used]->fillMacroInfo(traverse_mel); + info_stack[stack_used] = 0; + + return(elinfo_stack[stack_used]); + } + + el = elinfo_stack[stack_used]->getElement(); + + /* go up in tree until we can go down again */ + while((stack_used > 0) && + ((info_stack[stack_used] >= 2) || (el->getFirstChild()==NULL))) + { + stack_used--; + el = elinfo_stack[stack_used]->getElement(); + } + + + /* goto next macro element */ + if (stack_used < 1) { + currentMacro++; + if (currentMacro == traverse_mesh->endOfMacroElements()) return(NULL); + traverse_mel = *currentMacro; + + stack_used = 1; + elinfo_stack[stack_used]->fillMacroInfo(traverse_mel); + info_stack[stack_used] = 0; + + return(elinfo_stack[stack_used]); + } + + + /* go down tree */ + + if (stack_used >= stack_size-1) enlargeTraverseStack(); + i = info_stack[stack_used]; + info_stack[stack_used]++; + + elinfo_stack[stack_used + 1]->fillElInfo(i, elinfo_stack[stack_used]); + stack_used++; + + TEST_EXIT(stack_used < stack_size) + ("stack_size=%d too small, level=%d\n", + stack_size, elinfo_stack[stack_used]->getLevel()); + + info_stack[stack_used] = 0; + + return(elinfo_stack[stack_used]); + } + + ElInfo* TraverseStack::traverseEveryElementInorder() + { + FUNCNAME("TraverseStack::traverseEveryElementInorder"); + ERROR_EXIT("not yet implemented\n"); + return NULL; + } + + ElInfo* TraverseStack::traverseEveryElementPostorder() + { + FUNCNAME("TraverseStack::traverseEveryElementPostorder"); + + Element *el; + int i; + + if (stack_used == 0) /* first call */ + { + currentMacro = traverse_mesh->firstMacroElement(); + if(currentMacro == traverse_mesh->endOfMacroElements()) return NULL; + traverse_mel = *currentMacro; + + stack_used = 1; + elinfo_stack[stack_used]->fillMacroInfo(traverse_mel); + info_stack[stack_used] = 0; + + //return(elinfo_stack[stack_used]); + } + else { /* don't go up on first call */ + + el = elinfo_stack[stack_used]->getElement(); + + /* go up in tree until we can go down again */ /* postorder!!! */ + while((stack_used > 0) && + ((info_stack[stack_used] >= 3) || (el->getFirstChild()==NULL))) + { + stack_used--; + el = elinfo_stack[stack_used]->getElement(); + } + + + /* goto next macro element */ + if (stack_used < 1) { + currentMacro++; + if(currentMacro == traverse_mesh->endOfMacroElements()) return NULL; + traverse_mel = *currentMacro; + + stack_used = 1; + elinfo_stack[stack_used]->fillMacroInfo(traverse_mel); + info_stack[stack_used] = 0; + + /* return(elinfo_stack+stack_used); */ + } + } + /* go down tree */ + + while(elinfo_stack[stack_used]->getElement()->getFirstChild() + && (info_stack[stack_used] < 2)) { + if (stack_used >= stack_size-1) enlargeTraverseStack(); + i = info_stack[stack_used]; + info_stack[stack_used]++; + elinfo_stack[stack_used + 1]->fillElInfo(i, elinfo_stack[stack_used]); + stack_used++; + info_stack[stack_used] = 0; + } + + info_stack[stack_used]++; /* postorder!!! */ + + return(elinfo_stack[stack_used]); + } + + ElInfo* TraverseStack::traverseNeighbour(ElInfo* elinfo_old, int neighbour) + { + int dim = elinfo_old->getMesh()->getDim(); + switch(dim) { + case 1: + ERROR_EXIT("invalid dim\n"); + break; + case 2: + return traverseNeighbour2d(elinfo_old, neighbour); + break; + case 3: + return traverseNeighbour3d(elinfo_old, neighbour); + break; + default: ERROR_EXIT("invalid dim\n"); + } + return NULL; + } + + ElInfo* TraverseStack::traverseNeighbour3d(ElInfo* elinfo_old, int neighbour) + { + FUNCNAME("traverse_neighbour"); + Element *el, *el2; + ElInfo *old_elinfo, *elinfo, *elinfo2; + const DegreeOfFreedom *dof; + int i, nb, opp_vertex, stack2_used, typ = 0; + int sav_index, sav_neighbour = neighbour; + + static int coarse_nb[3][3][4] = {{{-2,-2,-2,-2}, {-1,2,3,1}, {-1,3,2,0}}, + {{-2,-2,-2,-2}, {-1,2,3,1}, {-1,2,3,0}}, + {{-2,-2,-2,-2}, {-1,2,3,1}, {-1,2,3,0}}}; + + TEST_EXIT(stack_used > 0)("no current element\n"); + + Parametric *parametric = traverse_mesh->getParametric(); + + if(parametric) elinfo_old = parametric->removeParametricInfo(elinfo_old); + + TEST_EXIT(elinfo_old == elinfo_stack[stack_used]) + ("invalid old elinfo\n"); + + TEST_EXIT(elinfo_stack[stack_used]->getFillFlag().isSet(Mesh::FILL_NEIGH)) + ("FILL_NEIGH not set"); + el = elinfo_stack[stack_used]->getElement(); + sav_index = el->getIndex(); + + /* first, goto to leaf level, if necessary... */ + if ((traverse_fill_flag & Mesh::CALL_LEAF_EL).isAnySet()) { + if ((el->getChild(0)) && (neighbour < 2)) { + if (stack_used >= stack_size-1) + enlargeTraverseStack(); + i = 1 - neighbour; + elinfo_stack[stack_used+1]->fillElInfo(i, elinfo_stack[stack_used]); + info_stack[stack_used] = i+1; + stack_used++; + info_stack[stack_used] = 0; + neighbour = 3; + } + } + + + /* save information about current element and its position in the tree */ + save_traverse_mel = traverse_mel; + save_stack_used = stack_used; + + nb = neighbour; + + while (stack_used > 1) /* go up in tree until we can go down again */ + { + stack_used--; + typ = dynamic_cast<ElInfo3d*>( elinfo_stack[stack_used])->getType(); + nb = coarse_nb[typ][info_stack[stack_used]][nb]; + if (nb == -1) break; + TEST_EXIT(nb >= 0)("invalid coarse_nb %d\n",nb); + } + + /* save hierarchy information about current element */ + + for (i=stack_used; i<=save_stack_used; i++) { + save_info_stack[i] = info_stack[i]; + *(save_elinfo_stack[i]) = *(elinfo_stack[i]); + } + + old_elinfo = save_elinfo_stack[save_stack_used]; + opp_vertex = old_elinfo->getOppVertex(neighbour); + + if (nb >= 0) { /* go to macro element neighbour */ + + i = traverse_mel->getOppVertex(nb); + traverse_mel = traverse_mel->getNeighbour(nb); + if (traverse_mel == NULL) return(NULL); + + if ((nb < 2) && (save_stack_used > 1)) { + stack2_used = 2; /* go down one level in OLD hierarchy */ + } + else { + stack2_used = 1; + } + elinfo2 = save_elinfo_stack[stack2_used]; + el2 = elinfo2->getElement(); + + stack_used = 1; + elinfo_stack[stack_used]->fillMacroInfo(traverse_mel); + info_stack[stack_used] = 0; + nb = i; + } + else { /* goto other child */ + stack2_used = stack_used + 1; + if (save_stack_used > stack2_used) { + stack2_used++; /* go down one level in OLD hierarchy */ + } + elinfo2 = save_elinfo_stack[stack2_used]; + el2 = elinfo2->getElement(); + + if (stack_used >= stack_size-1) + enlargeTraverseStack(); + i = 2 - info_stack[stack_used]; + info_stack[stack_used] = i+1; + elinfo_stack[stack_used+1]->fillElInfo(i, elinfo_stack[stack_used]); + stack_used++; + info_stack[stack_used] = 0; + nb = 0; + + } + + + elinfo = elinfo_stack[stack_used]; + el = elinfo->getElement(); + + while(el->getChild(0)) { + + if (nb < 2) { /* go down one level in hierarchy */ + if (stack_used >= stack_size-1) + enlargeTraverseStack(); + info_stack[stack_used] = 2-nb; + elinfo_stack[stack_used+1]->fillElInfo(1-nb, elinfo_stack[stack_used]); + stack_used++; + info_stack[stack_used] = 0; + elinfo = elinfo_stack[stack_used]; + el = elinfo->getElement(); + nb = 3; + } + + if (save_stack_used > stack2_used) { /* `refine' both el and el2 */ + TEST_EXIT(el->getChild(0))("invalid NEW refinement?\n"); + + if (el->getDOF(0) == el2->getDOF(0)) + i = save_info_stack[stack2_used] - 1; + else if (el->getDOF(1) == el2->getDOF(0)) + i = 2 - save_info_stack[stack2_used]; + else { + if (traverse_mesh->associated(el->getDOF(0, 0), el2->getDOF(0, 0))) + i = save_info_stack[stack2_used] - 1; + else if (traverse_mesh->associated(el->getDOF(1, 0), el2->getDOF(0, 0))) + i = 2 - save_info_stack[stack2_used]; + else { + ERROR_EXIT("no common refinement edge\n"); + } + } + + if (el->getChild(0) && + (el->getChild(i)->getDOF(1) == el->getDOF(nb) || + traverse_mesh->associated(el->getChild(i)->getDOF(1, 0), el->getDOF(nb, 0)))) + { /* el->child[0] Kuni 22.08.96 */ + nb = 1; + } + else { + nb = 2; + } + + info_stack[stack_used] = i+1; + if (stack_used >= stack_size-1) + enlargeTraverseStack(); + elinfo_stack[stack_used+1]->fillElInfo(i, elinfo_stack[stack_used]); + stack_used++; + info_stack[stack_used] = 0; + + elinfo = elinfo_stack[stack_used]; + el = elinfo->getElement(); + + stack2_used++; + elinfo2 = save_elinfo_stack[stack2_used]; + el2 = elinfo2->getElement(); + if (save_stack_used > stack2_used) { + dof = el2->getDOF(1); + if (dof != el->getDOF(1) && dof != el->getDOF(2) && + !traverse_mesh->associated(dof[0], el->getDOF(1, 0)) && + !traverse_mesh->associated(dof[0], el->getDOF(2, 0))) + { + stack2_used++; /* go down one level in OLD hierarchy */ + elinfo2 = save_elinfo_stack[stack2_used]; + el2 = elinfo2->getElement(); + } + // else { + // // --- debug --- + // if(dof != el->getDOF(1) && dof != el->getDOF(2)) { + // MSG("dof %d, dof1 %d, dof2 %d\n\n", + // dof[0], el->getDOF(1,0), el->getDOF(2,0)); + // } + // // ------------- + // } + } + + } + else { /* now we're done... */ + elinfo = elinfo_stack[stack_used]; + el = elinfo->getElement(); + break; + } + } + + + if (elinfo->getNeighbour(opp_vertex) != old_elinfo->getElement()) { + MSG(" looking for neighbour %d of element %d at %p\n", + neighbour, old_elinfo->getElement()->getIndex(), reinterpret_cast<void*>( old_elinfo->getElement())); + MSG(" originally: neighbour %d of element %d at %p\n", + sav_neighbour, sav_index, reinterpret_cast<void*>( old_elinfo->getElement())); + MSG(" got element %d at %p with opp_vertex %d neigh %d\n", + elinfo->getElement()->getIndex(), reinterpret_cast<void*>( elinfo->getElement()), + opp_vertex, (elinfo->getNeighbour(opp_vertex))?(elinfo->getNeighbour(opp_vertex))->getIndex():-1); + TEST_EXIT(elinfo->getNeighbour(opp_vertex) == old_elinfo->getElement()) + ("didn't succeed !?!?!?\n"); + } + + + if ((traverse_fill_flag & Mesh::CALL_EVERY_EL_POSTORDER).isAnySet()) + info_stack[stack_used] = 3; + else if ((traverse_fill_flag & Mesh::CALL_EVERY_EL_INORDER).isAnySet()) + info_stack[stack_used] = 1; /* ??? */ + + if(elinfo) { + if(parametric) elinfo = parametric->addParametricInfo(elinfo); + elinfo->fillDetGrdLambda(); + } + return(elinfo); + } + + ElInfo* TraverseStack::traverseNeighbour2d(ElInfo* elinfo_old, int neighbour) + { + FUNCNAME("TraverseStack::traverseNeighbour2d"); + Triangle *el, *el2, *sav_el; + ElInfo *old_elinfo, *elinfo, *elinfo2; + int i, nb, opp_vertex, stack2_used; + + static int coarse_nb[3][3] = {{-2,-2,-2}, {2,-1,1}, {-1,2,0}}; + /* father.neigh[coarse_nb[i][j]] == child[i-1].neigh[j] */ + + int sav_index, sav_neighbour = neighbour; + + TEST_EXIT(stack_used > 0)("no current element"); + TEST_EXIT(traverse_fill_flag.isSet(Mesh::CALL_LEAF_EL))("invalid traverse_fill_flag"); + + Parametric *parametric = traverse_mesh->getParametric(); + + if (parametric) + elinfo_old = parametric->removeParametricInfo(elinfo_old); + + TEST_EXIT(elinfo_old == elinfo_stack[stack_used])("invalid old elinfo"); + + elinfo_stack[stack_used]->testFlag(Mesh::FILL_NEIGH); + el = dynamic_cast<Triangle*>(const_cast<Element*>( elinfo_stack[stack_used]->getElement())); + sav_index = el->getIndex(); + sav_el = el; + + /* first, goto to leaf level, if necessary... */ + if (!(el->isLeaf()) && (neighbour < 2)) { + if (stack_used >= static_cast<int>( elinfo_stack.size())-1) enlargeTraverseStack(); + i = 1 - neighbour; + elinfo_stack[stack_used+1]->fillElInfo(i, elinfo_stack[stack_used]); + info_stack[stack_used] = i + 1; + stack_used++; + neighbour = 2; + } + + /* save information about current element and its position in the tree */ + save_traverse_mel = traverse_mel; + save_stack_used = stack_used; + for (i=0; i<=stack_used; i++) + save_info_stack[i] = info_stack[i]; + for (i=0; i<=stack_used; i++) + (*(save_elinfo_stack[i])) = (*(elinfo_stack[i])); + old_elinfo = save_elinfo_stack[stack_used]; + opp_vertex = old_elinfo->getOppVertex(neighbour); + + + /****************************************************************************/ + /* First phase: go up in tree until we can go down again. */ + /* */ + /* During this first phase, nb is the neighbour index which points from an */ + /* element of the OLD hierarchy branch to the NEW branch */ + /****************************************************************************/ + + nb = neighbour; + + while (stack_used > 1) + { + stack_used--; + nb = coarse_nb[info_stack[stack_used]][nb]; + if (nb == -1) break; + TEST_EXIT(nb >= 0)("invalid coarse_nb %d\n",nb); + } + + /****************************************************************************/ + /* Now, goto neighbouring element at the local hierarchy entry */ + /* This is either a macro element neighbour or the other child of parent. */ + /* initialize nb for second phase (see below) */ + /****************************************************************************/ + + if (nb >= 0) { /* go to macro element neighbour */ + + if ((nb < 2) && (save_stack_used > 1)) { + stack2_used = 2; /* go down one level in OLD hierarchy */ + } + else { + stack2_used = 1; + } + elinfo2 = save_elinfo_stack[stack2_used]; + el2 = dynamic_cast<Triangle*>(const_cast<Element*>( elinfo2->getElement())); + + i = traverse_mel->getOppVertex(nb); + traverse_mel = traverse_mel->getNeighbour(nb); + if (traverse_mel == NULL) return NULL; + nb = i; + + stack_used = 1; + elinfo_stack[stack_used]->fillMacroInfo(const_cast<MacroElement*>( traverse_mel)); + info_stack[stack_used] = 0; + + } + else { /* goto other child */ + + stack2_used = stack_used + 1; + if (save_stack_used > stack2_used) { + stack2_used++; /* go down one level in OLD hierarchy */ + } + elinfo2 = save_elinfo_stack[stack2_used]; + el2 = dynamic_cast<Triangle*>(const_cast<Element*>( elinfo2->getElement())); + + + if (stack_used >= stack_size-1) + enlargeTraverseStack(); + i = 2 - info_stack[stack_used]; + info_stack[stack_used] = i+1; + elinfo_stack[stack_used+1]->fillElInfo(i, elinfo_stack[stack_used]); + stack_used++; + nb = 1-i; + } + + /****************************************************************************/ + /* Second phase: go down in a new hierarchy branch until leaf level. */ + /* Now, nb is the neighbour index which points from an element of the */ + /* NEW hierarchy branch to the OLD branch. */ + /****************************************************************************/ + + elinfo = elinfo_stack[stack_used]; + el = dynamic_cast<Triangle*>(const_cast<Element*>( elinfo->getElement())); + + while(el->getFirstChild()) { + + if (nb < 2) { /* go down one level in hierarchy */ + if (stack_used >= stack_size-1) + enlargeTraverseStack(); + elinfo_stack[stack_used+1]->fillElInfo(1-nb, elinfo_stack[stack_used]); + info_stack[stack_used] = 2-nb; + stack_used++; + nb = 2; + } + + if (save_stack_used > stack2_used) { /* `refine' both el and el2 */ + TEST_EXIT(el->getFirstChild())("invalid NEW refinement?"); + + /* use child i, neighbour of el2->child[nb-1] */ + i = 2 - save_info_stack[stack2_used]; + TEST_EXIT(i < 2)("invalid OLD refinement?"); + info_stack[stack_used] = i+1; + elinfo_stack[stack_used+1]->fillElInfo(i, elinfo_stack[stack_used]); + stack_used++; + nb = i; + + elinfo = elinfo_stack[stack_used]; + el = dynamic_cast<Triangle*>(const_cast<Element*>( elinfo->getElement())); + + stack2_used++; + if (save_stack_used > stack2_used) { + stack2_used++; /* go down one level in OLD hierarchy */ + } + elinfo2 = save_elinfo_stack[stack2_used]; + el2 = dynamic_cast<Triangle*>(const_cast<Element*>( elinfo2->getElement())); + + } + else { /* now we're done... */ + elinfo = elinfo_stack[stack_used]; + el = dynamic_cast<Triangle*>(const_cast<Element*>( elinfo->getElement())); + } + } + + + if (elinfo->getNeighbour(opp_vertex) != old_elinfo->getElement()) { + MSG(" looking for neighbour %d of element %d at %8X\n", + neighbour, old_elinfo->getElement()->getIndex(), old_elinfo->getElement()); + MSG(" originally: neighbour %d of element %d at %8X\n", + sav_neighbour, sav_index, sav_el); + MSG(" got element %d at %8X with opp_vertex %d neigh %d\n", + elinfo->getElement()->getIndex(), elinfo->getElement(), opp_vertex, + elinfo->getNeighbour(opp_vertex)?elinfo->getNeighbour(opp_vertex)->getIndex():-1); + TEST_EXIT(elinfo->getNeighbour(opp_vertex) == old_elinfo->getElement()) + ("didn't succeed !?!?!?"); + } + if (elinfo->getElement()->getFirstChild()) + { + MSG(" looking for neighbour %d of element %d at %8X\n", + neighbour, old_elinfo->getElement()->getIndex(), old_elinfo->getElement()); + MSG(" originally: neighbour %d of element %d at %8X\n", + sav_neighbour, sav_index, sav_el); + MSG(" got element %d at %8X with opp_vertex %d neigh %d\n", + elinfo->getElement()->getIndex(), elinfo->getElement(), opp_vertex, + elinfo->getNeighbour(opp_vertex)->getIndex()); + MSG("got no leaf element\n"); + WAIT_REALLY; + } + + if(elinfo) { + if(parametric) elinfo = parametric->addParametricInfo(elinfo); + elinfo->fillDetGrdLambda(); + } + + return(elinfo); + } + + void TraverseStack::update() + { + FUNCNAME("TraverseStack::update"); + int i; + + TEST_EXIT(traverse_mesh->getDim() == 3)("update only in 3d\n"); + + for (i=stack_used; i > 0; i--) { + dynamic_cast<ElInfo3d*>( elinfo_stack[i])->update(); + } + } + +} diff --git a/AMDiS/src/Traverse.h b/AMDiS/src/Traverse.h new file mode 100644 index 0000000000000000000000000000000000000000..ed60c08480d867e5dbcdacbe135214600f92dbc7 --- /dev/null +++ b/AMDiS/src/Traverse.h @@ -0,0 +1,311 @@ +// ============================================================================ +// == == +// == AMDiS - Adaptive multidimensional simulations == +// == == +// ============================================================================ +// == == +// == crystal growth group == +// == == +// == Stiftung caesar == +// == Ludwig-Erhard-Allee 2 == +// == 53175 Bonn == +// == germany == +// == == +// ============================================================================ +// == == +// == http://www.caesar.de/cg/AMDiS == +// == == +// ============================================================================ + +/** \file Traverse.h */ + +/** \defgroup Traverse Traverse module + * @{ <img src="traverse.png"> @} + * + * \brief + * Contains classes used for mesh traversal. + */ + +#ifndef AMDIS_TRAVERSE_H +#define AMDIS_TRAVERSE_H + +#include "Flag.h" +#include "Global.h" +#include "ElInfo.h" +#include "MemoryManager.h" +#include <vector> +#include <deque> + +namespace AMDiS { + + class MacroElement; + class Mesh; + + // =========================================================================== + // ===== class TraverseStack ================================================= + // =========================================================================== + + /** \ingroup Traverse + * \brief + * Mesh refinement and coarsening routines are examples of functions which + * need a non-recursive access to the mesh elements. + * The implementation of the non-recursive mesh traversal routines uses a + * stack to save the tree path from a macro element to the current element. + * TraverseStack holds such information. Before calling the non-recursive mesh + * traversal routines, such a stack must be allocated. The stack is + * initialized by each call to \ref traverseFirst(). + */ + class TraverseStack + { + public: + MEMORY_MANAGED(TraverseStack); + + /** \brief + * Creates an empty TraverseStack + */ + TraverseStack() : traverse_mel(NULL),stack_size(0),stack_used(0), + save_stack_used(0),el_count(0) + { + id = ElInfo::traverseIdCounter++; + }; + + /** \brief + * Destructor + */ + ~TraverseStack() + { + int i; + for(i = 0; i < static_cast<int>(elinfo_stack.size()); i++) { + DELETE elinfo_stack[i]; + } + for(i = 0; i < static_cast<int>(save_elinfo_stack.size()); i++) { + DELETE save_elinfo_stack[i]; + } + }; + + public: + /** \brief + * Returns the first ElInfo of a non recursive traversal which fullfills the + * selection criterion specified by level and fill_flag and initializes the + * stack. After a call of traverseFirst the next Elements are traversed via + * \ref traverseNext(). + */ + ElInfo* traverseFirst(Mesh *mesh, int level, Flag fill_flag); + + /** \brief + * Returns the next ElInfo in a traversal initiated by \ref traverseFirst() + * If NULL is returned, the traversal is finished. + */ + ElInfo* traverseNext(ElInfo* elinfo_old); + + /** \brief + * Returns the neighbour-th neighbour of elInfoOld + */ + ElInfo* traverseNeighbour(ElInfo* elInfoOld, int neighbour); + + /** \brief + * Returns the neighbour-th neighbour of elInfoOld + */ + ElInfo* traverseNeighbour3d(ElInfo* elInfoOld, int neighbour); + + /** \brief + * Returns the neighbour-th neighbour of elInfoOld + */ + ElInfo* traverseNeighbour2d(ElInfo* elInfoOld, int neighbour); + + /** \brief + * Not yet implemented + */ + ElInfo* traverseMultiGridLevel(); + + /** \brief + * Preorder traversal of all elements + */ + ElInfo* traverseEveryElementPreorder(); + + /** \brief + * Inorder traversal of all elements + */ + ElInfo* traverseEveryElementInorder(); + + /** \brief + * Postorder traversal of all elements + */ + ElInfo* traverseEveryElementPostorder(); + + /** \brief + * Only for 3d: Calls update of all ElInfo3d onjects in \ref elinfo_stack + */ + void update(); + + private: + /** \brief + * Enlargement of the stack + */ + void enlargeTraverseStack(); + + /** \brief + * Used by \ref traverseFirst() \ref traverseNext() + */ + ElInfo* traverseLeafElement(); + + /** \brief + * Used by \ref traverseFirst() \ref traverseNext() + */ + ElInfo* traverseLeafElementLevel(); + + /** \brief + * Used by \ref traverseFirst() \ref traverseNext() + */ + ElInfo* traverseElementLevel(); + + /** \brief + * Avoids copy of a traverse stack. If copy should be possible + * the operator must be implemented (deep copy not flat copy!) + */ + void operator=(const TraverseStack& /*rhs*/) { + FUNCNAME("TraverseStack::operator="); + ERROR_EXIT("not implemented"); + }; + + /** \brief + * Avoids copy of a traverse stack. If copy should be possible + * the operator must be implemented (deep copy not flat copy!) + */ + TraverseStack(const TraverseStack&) { + FUNCNAME("TraverseStack::TraverseStack(const TraverseStack&)"); + ERROR_EXIT("not implemented"); + }; + + private: + /** \brief + * Iterator to the current MacroElement + */ + ::std::deque<MacroElement*>::const_iterator currentMacro; + + /** \brief + * Mesh which is currently traversed + */ + Mesh* traverse_mesh; + + /** \brief + * Traverse level. Used if CALL_EL_LEVEL or CALL_LEAF_EL_LEVEL are set in + * \ref traverse_fill_flag + */ + int traverse_level; + + /** \brief + * Flags for traversal. Specifies which elements are visited and which + * information are filled to the ElInfo objects. + */ + Flag traverse_fill_flag; + + /** \brief + * current macro element + */ + const MacroElement *traverse_mel; + + /** \brief + * Current size of the stack + */ + int stack_size; + + /** \brief + * Used size of the stack + */ + int stack_used; + + /** \brief + * + */ + ::std::vector<ElInfo*> elinfo_stack; + + /** \brief + * + */ + ::std::vector<ElInfo*> par_elinfo_stack; + + /** \brief + * + */ + ::std::vector<unsigned char> info_stack; + + /** \brief + * + */ + const MacroElement *save_traverse_mel; + + /** \brief + * + */ + ::std::vector<ElInfo*> save_elinfo_stack; + + /** \brief + * + */ + ::std::vector<unsigned char> save_info_stack; + + /** \brief + * + */ + int save_stack_used; + + /** \brief + * + */ + int el_count; + + int id; + }; + + // ============================================================================ + // ===== class Traverse ======================================================= + // ============================================================================ + + /** \ingroup Traverse + * \brief + * Class for recursive mesh traversal. Used in \ref Mesh::traverse() + */ + class Traverse + { + public: + MEMORY_MANAGED(Traverse); + + /** \brief + * Creates a Traverse object for Mesh m with fill flags f and level l. + * el_fct is a pointer to a the function that will be called for every + * visited element. + */ + Traverse(Mesh* m, + const Flag f, + const unsigned char l, + int (*ef)(ElInfo*)) + :mesh(m),flag(f),level(l),el_fct(ef) + { + TEST_EXIT(m)("No traverse without mesh!\n"); + id = ElInfo::traverseIdCounter++; + }; + + /** \brief + * Performs the recursive traversal + */ + int recursive(ElInfo*); + + private: + Mesh *mesh; + Flag flag; + unsigned char level; + int (*el_fct)(ElInfo*); + + //static int idCounter; + int id; + + Traverse(); + Traverse(const Traverse&); + + }; + +} + +#endif // AMDIS_TRAVERSE_H + diff --git a/AMDiS/src/Triangle.cc b/AMDiS/src/Triangle.cc new file mode 100644 index 0000000000000000000000000000000000000000..87cdc3188fde0ecfe5f52f4bbe7185d3182ec11c --- /dev/null +++ b/AMDiS/src/Triangle.cc @@ -0,0 +1,78 @@ +#include "Triangle.h" +#include "DOFAdmin.h" +#include "Mesh.h" +#include "CoarseningManager.h" +#include "FixVec.h" + +namespace AMDiS { + + const int Triangle::vertexOfEdge[3][2] = {{1,2}, {2,0}, {0,1}}; + const int Triangle::sideOfChild[2][3] = {{-1,2,0}, {2,-1,1}}; + const int Triangle::vertexOfParent[2][3] = {{2,0,-1}, {1,2,-1}}; + + bool Triangle::hasSide(Element* sideElem) const + { + FUNCNAME("Triangle::hasSide"); + TEST_EXIT(sideElem->isLine())("called for sideElem-type != Line\n"); + ERROR_EXIT("not yet\n"); + return false; + } + + int Triangle::getVertexOfPosition(GeoIndex position, + int positionIndex, + int vertexIndex) const + { + FUNCNAME("Triangle::getVertexOfPosition"); + switch(position) { + case VERTEX: + return positionIndex; + break; + case EDGE: + return vertexOfEdge[positionIndex][vertexIndex]; + break; + case CENTER: + return vertexIndex; + break; + default: + ERROR_EXIT("invalid position\n"); + return 0; + } + } + + const FixVec<int, WORLD>& + Triangle::sortFaceIndices(int face, FixVec<int,WORLD> *vec) const + { + static MatrixOfFixVecs<FixVec<int,WORLD> > *sorted_2d = NULL; + + int no = 0; + const int *vof = NULL; + FixVec<int,WORLD> *val = NULL; + vof = vertexOfEdge[face]; + + if (NULL==sorted_2d) { + sorted_2d = new MatrixOfFixVecs<FixVec<int,WORLD> >(2,3,2,NO_INIT); + + (*sorted_2d)[1][0][1]=(*sorted_2d)[1][1][0]= + (*sorted_2d)[2][0][0]=(*sorted_2d)[2][1][1]=0; + (*sorted_2d)[0][0][0]=(*sorted_2d)[0][1][1]= + (*sorted_2d)[2][0][1]=(*sorted_2d)[2][1][0]=1; + (*sorted_2d)[0][0][1]=(*sorted_2d)[0][1][0]= + (*sorted_2d)[1][0][0]=(*sorted_2d)[1][1][1]=2; + } + + if (dof[vof[0]][0] < dof[vof[1]][0]) + no = 0; + else + no = 1; + + if (vec) { + val = vec; + *val = (*sorted_2d)[face][no]; + } + else + val = &((*sorted_2d)[face][no]); + + return(*(const_cast<const FixVec<int,WORLD>* >(val))); + } + +} diff --git a/AMDiS/src/Triangle.h b/AMDiS/src/Triangle.h new file mode 100644 index 0000000000000000000000000000000000000000..deee73684ba8d4825a9d9b6ca60c790395753ad8 --- /dev/null +++ b/AMDiS/src/Triangle.h @@ -0,0 +1,185 @@ +// ============================================================================ +// == == +// == AMDiS - Adaptive multidimensional simulations == +// == == +// ============================================================================ +// == == +// == crystal growth group == +// == == +// == Stiftung caesar == +// == Ludwig-Erhard-Allee 2 == +// == 53175 Bonn == +// == germany == +// == == +// ============================================================================ +// == == +// == http://www.caesar.de/cg/AMDiS == +// == == +// ============================================================================ + +/** \file Triangle.h */ + +#ifndef AMDIS_TRIANGLE_H +#define AMDIS_TRIANGLE_H + +#include "Element.h" +#include "MemoryManager.h" + +namespace AMDiS { + + /** \ingroup Triangulation + * \brief + * A Triangle is a 2-dimensional Element. + * + * A Triangle and its refinements: + * + * <img src = "triangle.png"> + */ + class Triangle : public Element + { + public: + MEMORY_MANAGED(Triangle); + + /** \brief + * calls base class contructor. + */ + Triangle(Mesh* aMesh) : Element(aMesh) {}; + + /** \brief + * implements Element::clone + */ + inline Element *clone() { return NEW Triangle(mesh); }; + + + /** \brief + * implements Element::getVertexOfEdge + */ + inline int getVertexOfEdge(int i, int j) const { + return vertexOfEdge[i][j]; + }; + + /** \brief + * implements Element::getVertexOfPosition + */ + int getVertexOfPosition(GeoIndex position, + int positionIndex, + int vertexIndex) const; + + /** \brief + * implements Element::getGeo + */ + inline int getGeo(GeoIndex i) const { + switch(i) { + case VERTEX: case PARTS: case NEIGH: + return 3; + break; + case EDGE: + return 3; + case FACE: + return 0; + case CENTER: + return 1; + break; + case DIMEN: + return 2; + break; + case BOUNDARY: + return 6; + break; + case PROJECTION: + return 3; + break; + default: + ERROR_EXIT("invalid geo-index\n"); + return 0; + } + }; + + + /** \brief + * implements Element::sideOfChild + */ + //int sideOfChild(int child, + // int side, + // bool *isVirtual, + // unsigned char elementType=0); + + /** \brief + * implements Element::hasSide + */ + bool hasSide(Element* sideElem) const; + + /** \brief + * implements Element::sortFaceIndices + */ + const FixVec<int,WORLD>& sortFaceIndices(int face, + FixVec<int,WORLD> *vec) const; + + /** \brief + * implements Element::isLine. Returns false because this element is a + * Triangle + */ + inline bool isLine() const { return false; }; + + /** \brief + * implements Element::isTriangle. Returns true because this element is a + * Triangle + */ + inline bool isTriangle() const { return true; }; + + /** \brief + * implements Element::isTetrahedron. Returns false because this element is a + * Triangle + */ + inline bool isTetrahedron() const { return false; }; + + /** \brief + * implements Element::getSideOfChild() + */ + virtual int getSideOfChild(int child, int side, int) const { + FUNCNAME("Triangle::getSideOfChild()"); + TEST_EXIT(child==0 || child==1)("child must be in (0,1)\n"); + TEST_EXIT(side >= 0 && side <= 2)("side must be between 0 and 2\n"); + return sideOfChild[child][side]; + }; + + /** \brief + * implements Element::getVertexOfParent() + */ + virtual int getVertexOfParent(int child, int side, int=0) const { + FUNCNAME("Triangle::getVertexOfParent()"); + TEST_EXIT(child==0 || child==1)("child must be in (0,1)\n"); + TEST_EXIT(side >= 0 && side <= 2)("side must be between 0 and 2\n"); + return vertexOfParent[child][side]; + }; + + virtual int getPositionOfVertex(int side, int vertex) const { + static int positionOfVertex[3][3] = {{-1,0,1},{1,-1,0},{0,1,-1}}; + return positionOfVertex[side][vertex]; + }; + + inline int getEdgeOfFace(int face, int edge) const { + TEST_EXIT(face == 0)("face must be zero at triangle\n"); + TEST_EXIT(edge >= 0 && edge < 3)("invalid edge\n"); + return edge; + }; + + // ===== Serializable implementation ===== + + ::std::string getTypeName() const { return "Triangle"; }; + + protected: + /** \brief + * vertexOfEdge[i][j] is the local number of the j-th vertex of the i-th + * edge of this element. + */ + static const int vertexOfEdge[3][2]; + + static const int sideOfChild[2][3]; + + static const int vertexOfParent[2][3]; + }; + +} + +#endif // AMDIS_TRIANGLE_H diff --git a/AMDiS/src/UmfPackSolver.h b/AMDiS/src/UmfPackSolver.h new file mode 100644 index 0000000000000000000000000000000000000000..19282bc187e32dbbcb2f920e4ff6967d6a292189 --- /dev/null +++ b/AMDiS/src/UmfPackSolver.h @@ -0,0 +1,113 @@ +// ============================================================================ +// == == +// == AMDiS - Adaptive multidimensional simulations == +// == == +// ============================================================================ +// == == +// == crystal growth group == +// == == +// == Stiftung caesar == +// == Ludwig-Erhard-Allee 2 == +// == 53175 Bonn == +// == germany == +// == == +// ============================================================================ +// == == +// == http://www.caesar.de/cg/AMDiS == +// == == +// ============================================================================ + +/** \file UmfPackSolver.h */ + +#ifndef AMDIS_UMFPACKSOLVER_H +#define AMDIS_UMFPACKSOLVER_H + +#ifdef HAVE_UMFPACK + +#include "OEMSolver.h" +#include "MemoryManager.h" + +namespace AMDiS { + + // ============================================================================ + // ===== class UmfPackSolver ================================================== + // ============================================================================ + + /** + * \ingroup Solver + * + * \brief + * Wrapper for the external UMFPACK solver: + * http://www.cise.ufl.edu/research/sparse/umfpack/ + * + * This is a direct solver for large sparse matrices. + */ + template<typename VectorType> + class UmfPackSolver : public OEMSolver<VectorType> + { + public: + MEMORY_MANAGED(UmfPackSolver<VectorType>); + + /** \brief + * Creator class used in the OEMSolverMap. + */ + class Creator : public OEMSolverCreator<VectorType> + { + public: + MEMORY_MANAGED(Creator); + + virtual ~Creator() {}; + + /** \brief + * Returns a new UmfPackSolver object. + */ + OEMSolver<VectorType>* create() { + return NEW UmfPackSolver<VectorType>(this->name); + }; + }; + + /** \brief + * constructor + */ + UmfPackSolver(::std::string name); + + /** \brief + * destructor + */ + ~UmfPackSolver(); + protected: + /** \brief + * Implements OEMSolver<VectorType>::init(). + */ + void init() { + p = this->vectorCreator->create(); + r = this->vectorCreator->create(); + }; + + /** \brief + * Implements OEMSolver<VectorType>::exit(). + */ + void exit() { + this->vectorCreator->free(p); + this->vectorCreator->free(r); + }; + + /** \brief + * Implements OEMSolver<VectorType>::solve(). + */ + int solveSystem(MatVecMultiplier<VectorType> *mv, VectorType *x, VectorType *b); + + private: + /** \brief + * These vectors are justed to calculate the final residual of the solution. + */ + VectorType *r, *p; + }; + +} + +#include "UmfPackSolver.hh" + +#endif // HAVE_UMFPACK + +#endif // AMDIS_UMFPACKSOLVER_H diff --git a/AMDiS/src/UmfPackSolver.hh b/AMDiS/src/UmfPackSolver.hh new file mode 100644 index 0000000000000000000000000000000000000000..c03458d657436f54d55a38144000428a087ea007 --- /dev/null +++ b/AMDiS/src/UmfPackSolver.hh @@ -0,0 +1,166 @@ +#include <vector> + +#include "UmfPackSolver.h" +#include "DOFMatrix.h" +#include "MatVecMultiplier.h" + +#include "umfpack.h" + + +namespace AMDiS { + + template<typename VectorType> + UmfPackSolver<VectorType>::UmfPackSolver(::std::string name) + : OEMSolver<VectorType>(name) + {} + + template<typename VectorType> + UmfPackSolver<VectorType>::~UmfPackSolver() {} + + template<typename VectorType> + int UmfPackSolver<VectorType>::solveSystem(MatVecMultiplier<VectorType> *matVec, + VectorType *x, VectorType *b) + { + FUNCNAME("UmfPackSolver::solveSystem()"); + + TEST_EXIT(x->getSize() == b->getSize())("Vectors x and b must have the same size!"); + + // Extract the matrix of DOF-matrices. + StandardMatVec<Matrix<DOFMatrix*>, SystemVector> *stdMatVec = + dynamic_cast<StandardMatVec<Matrix<DOFMatrix*>, SystemVector> *>(matVec); + Matrix<DOFMatrix*> *m = stdMatVec->getMatrix(); + + // Number of systems. + int nComponents = m->getSize(); + // Size of the new composed matrix. + int newMatrixSize = ((*m)[0][0])->getFESpace()->getAdmin()->getUsedSize() * nComponents; + + // The new matrix has to be stored in compressed col format, therefore + // the cols are collected. + ::std::vector< ::std::vector< MatEntry > > cols(newMatrixSize, ::std::vector<MatEntry>(0)); + + // Counter for the number of non-zero elements in the new matrix. + int nElements = 0; + + for (int stencilRow = 0; stencilRow < nComponents; stencilRow++) { + for (int stencilCol = 0; stencilCol < nComponents; stencilCol++) { + + if (!(*m)[stencilRow][stencilCol]) { + continue; + } + + DOFMatrix::Iterator matrixRow((*m)[stencilRow][stencilCol], USED_DOFS); + int rowIndex = 0; + for (matrixRow.reset(); !matrixRow.end(); matrixRow++, rowIndex++) { + for (int i = 0; i < static_cast<int>((*matrixRow).size()); i++) { + if ((*matrixRow)[i].col >= 0) { + MatEntry me; + me.entry = (*matrixRow)[i].entry; + // The col field is used to store the row number of the new element. + me.col = (rowIndex * nComponents) + stencilRow; + + // And save the new element in the corresponding column. + cols[((*matrixRow)[i].col * nComponents) + stencilCol].push_back(me); + + nElements++; + } + } + } + + } + } + + // Data fields for UMFPack. + int *Ap = (int*)malloc(sizeof(int) * (newMatrixSize + 1)); + int *Ai = (int*)malloc(sizeof(int) * nElements); + double *Ax = (double*)malloc(sizeof(double) * nElements); + double *bvec = (double*)malloc(sizeof(double) * newMatrixSize); + double *xvec = (double*)malloc(sizeof(double) * newMatrixSize); + + // Resort the right hand side of the linear system. + for (int i = 0; i < b->getSize(); i++) { + DOFVector<double>::Iterator it(b->getDOFVector(i), USED_DOFS); + + int counter = 0; + for (it.reset(); !it.end(); ++it, counter++) { + bvec[counter * nComponents + i] = *it; + } + } + + // Create fields Ap, Ai and Ax. + int elCounter = 0; + Ap[0] = 0; + for (int i = 0; i < newMatrixSize; i++) { + Ap[i + 1] = Ap[i] + cols[i].size(); + + // The cols has to be sorted for using them in UMFPack. + sort(cols[i].begin(), cols[i].end(), CmpMatEntryCol()); + + for (int j = 0; j < static_cast<int>(cols[i].size()); j++) { + Ai[elCounter] = cols[i][j].col; + Ax[elCounter] = cols[i][j].entry; + + elCounter++; + } + } + + + void *Symbolic, *Numeric; + double Control[UMFPACK_CONTROL]; + double Info[UMFPACK_INFO]; + int status = 0; + + MSG("solving system with UMFPack ...\n"); + + // Use default setings. + umfpack_di_defaults(Control); + + // Run UMFPack. + status = umfpack_di_symbolic(newMatrixSize, newMatrixSize, Ap, Ai, Ax, &Symbolic, Control, Info); + if (!status == UMFPACK_OK) { + ERROR_EXIT("UMFPACK Error in function umfpack_di_symbolic"); + } + + status = umfpack_di_numeric(Ap, Ai, Ax, Symbolic, &Numeric, Control, Info); + if (!status == UMFPACK_OK) { + ERROR_EXIT("UMFPACK Error in function umfpack_di_numberic"); + } + + status = umfpack_di_solve(UMFPACK_A, Ap, Ai, Ax, xvec, bvec, Numeric, Control, Info); + if (!status == UMFPACK_OK) { + ERROR_EXIT("UMFPACK Error in function umfpack_di_solve"); + } + + + umfpack_di_free_symbolic(&Symbolic); + umfpack_di_free_numeric(&Numeric); + + + // Copy and resort solution. + for (int i = 0; i < x->getSize(); i++) { + DOFVector<double>::Iterator it(x->getDOFVector(i), USED_DOFS); + + int counter = 0; + for (it.reset(); !it.end(); it++, counter++) { + *it = xvec[counter * nComponents + i]; + } + } + + free(Ap); + free(Ai); + free(Ax); + free(bvec); + free(xvec); + + // Calculate and print the residual. + *p = *x; + *p *= -1.0; + matVec->matVec(NoTranspose, *p, *r); + *r += *b; + + MSG("Residual: %e\n", norm(r)); + + return(1); + } +} + diff --git a/AMDiS/src/V3Vector.cc b/AMDiS/src/V3Vector.cc new file mode 100644 index 0000000000000000000000000000000000000000..d4f01014dfd34a9cfe70cd2b824d96ccf35f218e --- /dev/null +++ b/AMDiS/src/V3Vector.cc @@ -0,0 +1,173 @@ +#include "V3Vector.h" +#include "StlVector.h" + +namespace AMDiS { + + M33::M33() + { + data.resize(9); + for (int i = 0; i < 9; i++) { + data[i] = 0.0; + } + }; + + M33::~M33() + {}; + + void M33::set(int row, int col, double value) + { + data[row * 3 + col] = value; + }; + + void M33::print() + { + ::std::cout << "["; + + for (int i = 0; i < 9; i++) { + ::std::cout << data[i] << ","; + } + + ::std::cout << "]" << ::std::endl; + }; + +/* double norm(::std::vector<V3> *v) { + double result = 0.0; + + ::std::vector<V3>::iterator it; + + for (it = v->begin(); it < v->end(); ++it) { + result += (*it)[0] * (*it)[0] + (*it)[1] * (*it)[1] + (*it)[2] * (*it)[2]; + } + + return(sqrt(result)); + }; + + void setValue(::std::vector<V3>& v, double value) + { + ::std::vector<V3>::iterator it; + + for (it = v.begin(); it < v.end(); ++it) { + (*it)[0] = value; + (*it)[1] = value; + (*it)[2] = value; + }; + }; + + const V3& operator += (V3& x1, const V3 x2) + { + x1[0] += x2[0]; + x1[1] += x2[1]; + x1[2] += x2[2]; + + return(x1); + } + + const ::std::vector<V3>& operator*=(::std::vector<V3>& x, double scal) + { + ::std::vector<V3>::iterator it; + + for (it = x.begin(); it < x.end(); ++it) { + (*it)[0] *= scal; + (*it)[1] *= scal; + (*it)[2] *= scal; + } + + return(x); + }; + + const ::std::vector<V3>& operator+=(::std::vector<V3>& x1, + const ::std::vector<V3>& x2) + { + ::std::vector<V3>::iterator it1; + ::std::vector<V3>::const_iterator it2; + + for (it1 = x1.begin(), it2 = x2.begin(); + it1 < x1.end(); + ++it1, ++it2) { + (*it1)[0] += (*it2)[0]; + (*it1)[1] += (*it2)[1]; + (*it1)[2] += (*it2)[2]; + }; + + return(x1); + }; + + double operator*(::std::vector<V3>& x1, ::std::vector<V3>& x2) + { + double result = 0.0; + + ::std::vector<V3>::iterator it1, it2; + + for (it1 = x1.begin(), it2 = x2.begin(); + it1 < x1.end(); + ++it1, ++it2) { + result += (*it1)[0] * (*it2)[0] + + (*it1)[1] * (*it2)[1] + + (*it1)[2] * (*it2)[2]; + } + + return(result); + }; + + + void axpy(double alpha, const ::std::vector<V3>& x, ::std::vector<V3>& y) + { + ::std::vector<V3>::const_iterator it1; + ::std::vector<V3>::iterator it2; + + for (it1 = x.begin(), it2 = y.begin(); + it1 < x.end(); + ++it1, ++it2) { + (*it2)[0] += alpha * (*it1)[0]; + (*it2)[1] += alpha * (*it1)[1]; + (*it2)[2] += alpha * (*it1)[2]; + } + }; + + void xpay(double alpha, const ::std::vector<V3>& x, ::std::vector<V3>& y) + { + ::std::vector<V3>::const_iterator it1; + ::std::vector<V3>::iterator it2; + + for (it1 = x.begin(), it2 = y.begin(); + it1 < x.end(); + ++it1, ++it2) { + (*it2)[0] = alpha * (*it2)[0] + (*it1)[0]; + (*it2)[1] = alpha * (*it2)[1] + (*it1)[1]; + (*it2)[2] = alpha * (*it2)[2] + (*it1)[2]; + } + }; + + V3 mult(M33 mat, V3 vec) + { + V3 result(3); + + result[0] = mat[0] * vec[0] + mat[1] * vec[1] + mat[2] * vec[2]; + result[1] = mat[3] * vec[0] + mat[4] * vec[1] + mat[5] * vec[2]; + result[2] = mat[6] * vec[0] + mat[7] * vec[1] + mat[8] * vec[2]; + +// ::std::cout << "------------------------" << ::std::endl; +// ::std::cout << "M = "; +// mat.print(); +// ::std::cout << "v = "; +// print(&vec); +// ::std::cout << "r = "; +// print(&result); + + return(result); + }; + + void print(::std::vector<V3> *v) + { + ::std::vector<V3>::const_iterator it; + + ::std::cout << "["; + + for (it = v->begin(); it < v->end(); ++it) { + ::std::cout << "(" << (*it)[0] << "," << (*it)[1] << "," << (*it)[2] << ") "; + } + + ::std::cout << "]" << ::std::endl; + }; +*/ +} diff --git a/AMDiS/src/V3Vector.h b/AMDiS/src/V3Vector.h new file mode 100644 index 0000000000000000000000000000000000000000..4543740eb98670865bb0e8e91dceecb06d83e654 --- /dev/null +++ b/AMDiS/src/V3Vector.h @@ -0,0 +1,117 @@ +// ============================================================================ +// == == +// == AMDiS - Adaptive multidimensional simulations == +// == == +// ============================================================================ +// == == +// == crystal growth group == +// == == +// == Stiftung caesar == +// == Ludwig-Erhard-Allee 2 == +// == 53175 Bonn == +// == germany == +// == == +// ============================================================================ +// == == +// == http://www.caesar.de/cg/AMDiS == +// == == +// ============================================================================ + +/** \file V3Vector.h */ + +#ifndef AMDIS_V3VECTOR_H +#define AMDIS_V3VECTOR_H + +#include <vector> +#include "Global.h" +#include "MemoryManager.h" +#include "CreatorInterface.h" + +namespace AMDiS { + + class M33 { + public: + M33(); + + ~M33(); + + void set(int row, int col, double value); + + bool operator==(const M33 &a) const { + return data == a.getData(); + }; + + bool operator!=(const M33 &a) const { + return data != a.getData(); + }; + + ::std::vector<double> getData() const { + return data; + }; + + inline double operator[](int i) const { + return(data[i]); + } + + void print(); + + private: + ::std::vector<double> data; + }; + + struct MatEntry33 + { + DegreeOfFreedom col; + + M33 entry; + }; +/* + typedef ::std::vector<double> V3; + + class V3Creator : public CreatorInterface< ::std::vector<V3> > { + public: + MEMORY_MANAGED(V3Creator); + + V3Creator(int size) + : size_(size) + {}; + + virtual ~V3Creator() {}; + + ::std::vector<V3> *create() { + ::std::vector<V3> *vec = new ::std::vector<V3>(size_, V3(3)); + + return vec; + }; + + void free(::std::vector<V3> *vec) { + delete vec; + }; + + private: + int size_; + }; + + double norm(::std::vector<V3> *v); + + void setValue(::std::vector<V3>& v, double value); + + const V3& operator += (V3& x1, const V3 x2); + + const ::std::vector<V3>& operator*=(::std::vector<V3>& x, double scal); + + const ::std::vector<V3>& operator+=(::std::vector<V3>& x1, + const ::std::vector<V3>& x2); + + double operator*(::std::vector<V3>& x1, ::std::vector<V3>& x2); + + void axpy(double alpha, const ::std::vector<V3>& x, ::std::vector<V3>& y); + + void xpay(double alpha, const ::std::vector<V3>& x, ::std::vector<V3>& y); + + V3 mult(M33 mat, V3 vec); + + void print(::std::vector<V3> *v);*/ +} + +#endif diff --git a/AMDiS/src/ValueReader.cc b/AMDiS/src/ValueReader.cc new file mode 100644 index 0000000000000000000000000000000000000000..78b4cf55a51a3a70609df562c6b679995b30330f --- /dev/null +++ b/AMDiS/src/ValueReader.cc @@ -0,0 +1,65 @@ +#include "ValueReader.h" +#include "MacroReader.h" + +namespace AMDiS { + + /** \brief + * Copies the values of a value file to a DOF vector. + * + * The DOF vector must have been created by a corresponding mesh file. The + * information about this file and the macro triangulation are stored in + * macroFileInfo. The function now reads the corresponding value file and + * copies the values to the correct positions in the DOF vector. + */ + void ValueReader::readValue(const char *filename, + Mesh *mesh, + DOFVector<double> *dofVector, + MacroInfo *macroFileInfo) + { + FUNCNAME("ValueReader::readValue()"); + + TEST_EXIT(filename)("no file specified; filename NULL pointer\n"); + TEST_EXIT(strlen(filename) < static_cast<unsigned int>(127)) + ("can only handle filenames up to 127 characters\n"); + TEST_EXIT(mesh)("no mesh specified\n"); + TEST_EXIT(dofVector)("no DOF vector specified\n"); + TEST_EXIT(macroFileInfo)("no MacroInfo specified\n"); + + ::std::string line; + + // open the file and read the data to the vector values. + ::std::ifstream file(filename, ::std::ifstream::in); + + while (!file.eof()) { + getline(file, line); + if (line.find("vertex values:") != ::std::string::npos) + break; + } + // A vertex value cannot be the last line of the file, if the file is correct. + TEST_EXIT(!file.eof())("Value file does not contain vertex values\n"); + + double value; + ::std::vector<double> values; + values.clear(); + + while (!file.eof()) { + file >> value; + if (!file.good()) { + break; + } + values.push_back(value); + } + + file.close(); + + // Using the macroFileInfo structure, copy the values to the + // correct positions in the DOF vector. + for (int i = 0; i < mesh->getNumberOfMacros(); i++) { + for (int j = 0; j < mesh->getGeo(VERTEX); j++) { + int fileIndex = macroFileInfo->mel_vertex[i][j]; + int dofIndex = *(macroFileInfo->dof[fileIndex]); + (*dofVector)[dofIndex] = values[fileIndex]; + } + } + } +} diff --git a/AMDiS/src/ValueReader.h b/AMDiS/src/ValueReader.h new file mode 100644 index 0000000000000000000000000000000000000000..f907587618057824630bdc74eff71536a6f228c2 --- /dev/null +++ b/AMDiS/src/ValueReader.h @@ -0,0 +1,54 @@ +// ============================================================================ +// == == +// == AMDiS - Adaptive multidimensional simulations == +// == == +// ============================================================================ +// == == +// == crystal growth group == +// == == +// == Stiftung caesar == +// == Ludwig-Erhard-Allee 2 == +// == 53175 Bonn == +// == germany == +// == == +// ============================================================================ +// == == +// == http://www.caesar.de/cg/AMDiS == +// == == +// ============================================================================ + +/** \file ValueReader.h */ + +#ifndef AMDIS_VALUEREADER_H +#define AMDIS_VALUEREADER_H + +#include "DOFVector.h" +#include "Mesh.h" + +namespace AMDiS { + + // =========================================================================== + // ===== class ValueReader =================================================== + // =========================================================================== + + /** \ingroup Input + * + * \brief + * Static class which reads a value file in AMDiS format and copies + * the data to a DOF vector. + */ + class ValueReader + { + public: + /** \brief + * Copies the values of a value file to a DOF vector. + */ + static void readValue(const char *filename, + Mesh *mesh, + DOFVector<double> *dofVector, + MacroInfo *macroFileInfo); + }; + +} + +#endif diff --git a/AMDiS/src/ValueWriter.cc b/AMDiS/src/ValueWriter.cc new file mode 100644 index 0000000000000000000000000000000000000000..5772d628d00b867a6f7d670a4b59ff2630da0da0 --- /dev/null +++ b/AMDiS/src/ValueWriter.cc @@ -0,0 +1,280 @@ +#include <algorithm> + +#include "ValueWriter.h" +#include "DOFVector.h" +#include "DOFAdmin.h" +#include "ElInfo.h" +#include "BasisFunction.h" + +namespace AMDiS { + + const DOFAdmin* ValueWriter::admin = NULL; + FILE* ValueWriter::valueFile = NULL; + DOFVector<double>* ValueWriter::valueVec = NULL; + DOFVector<int>* ValueWriter::interpPointInd = NULL; + DOFVector< ::std::list<WorldVector<double> > >* ValueWriter::dofCoords = NULL; + int ValueWriter::ni = 0; + + int ValueWriter::markFct(ElInfo *el_info) { + int i, j, k; + int node_offset, dof_offset, num_dofs, node, dof_index; + const DegreeOfFreedom **dof = el_info->getElement()->getDOF(); + const Mesh *mesh = admin->getMesh(); + int dim = mesh->getDim(); + + /* vertex dofs */ + dof_offset = admin->getNumberOfPreDOFs(VERTEX); + + for (i = 0; i < mesh->getGeo(VERTEX); i++) { + (*interpPointInd)[dof[i][dof_offset]] = -2; // mark as vertex + + // get coords of this vertex + WorldVector<double> vertexCoords = el_info->getCoord(i); + + // search for coords at this dof + ::std::list<WorldVector<double> >::iterator it = + find((*dofCoords)[dof[i][dof_offset]].begin(), + (*dofCoords)[dof[i][dof_offset]].end(), + vertexCoords); + + // coords not yet in list? + if(it == (*dofCoords)[dof[i][dof_offset]].end()) { + // add new coords to list + (*dofCoords)[dof[i][dof_offset]].push_back(vertexCoords); + } + } + + for(i = 1; i <= dim; i++) { + num_dofs = admin->getNumberOfDOFs(INDEX_OF_DIM(i, dim)); + node_offset = mesh->getNode(INDEX_OF_DIM(i, dim)); + dof_offset = admin->getNumberOfPreDOFs(INDEX_OF_DIM(i, dim)); + for (j = 0; j < mesh->getGeo(INDEX_OF_DIM(i, dim)); j++) { + node = node_offset + j; + for(k = 0; k < num_dofs; k++) { + dof_index = dof_offset + k; + if ((*interpPointInd)[dof[node][dof_index]] == -1) { + (*interpPointInd)[dof[node][dof_index]] = -3; + // mark as interp. point + ni++; + } + } + } + } + + return 0; + } + + int ValueWriter::writeInterpolPoints(ElInfo *el_info) + { + int i, j, k; + int node_offset, dof_offset, num_dofs, node, dof_index; + const DegreeOfFreedom **dof = el_info->getElement()->getDOF(); + + const Mesh *mesh = admin->getMesh(); + int dim = mesh->getDim(); + + for(i = 1; i <= mesh->getDim(); i++) { + num_dofs = admin->getNumberOfDOFs(INDEX_OF_DIM(i, dim)); + node_offset = mesh->getNode(INDEX_OF_DIM(i, dim)); + dof_offset = admin->getNumberOfPreDOFs(INDEX_OF_DIM(i, dim)); + for (j = 0; j < mesh->getGeo(INDEX_OF_DIM(i, dim)); j++) { + node = node_offset + j; + for(k = 0; k < num_dofs; k++) { + dof_index = dof_offset + k; + fprintf(valueFile, "%d ", (*interpPointInd)[dof[node][dof_index]]); + } + } + } + + fprintf(valueFile, "\n"); + return 0; + } + + void ValueWriter::writeValuesOld(DOFVector<double> *values, + char* fn, + double time, + int level, + Flag traverseFlag) + { + FUNCNAME("ValueWriter::writeValues()"); + TEST_EXIT(values)("no values specified\n"); + + ::std::string filename; + if(fn) { + filename.assign(fn); + } else { + filename.assign(values->getName()); + } + + const FiniteElemSpace *feSpace = values->getFESpace(); + Mesh *mesh = feSpace->getMesh(); + + interpPointInd = NEW DOFVector<int>(feSpace, "interpolation point indices"); + dofCoords = NEW DOFVector< ::std::list<WorldVector<double> > >(feSpace, "dof coords"); + + admin = feSpace->getAdmin(); + + valueVec = values; + + DOFVector<int>::Iterator intPointIt(interpPointInd, USED_DOFS); + + for(intPointIt.reset(); !intPointIt.end(); ++intPointIt) { + (*intPointIt) = -1; + } + + if (!(valueFile = fopen(filename.c_str(), "w"))) + { + ERROR("could not open file %s for writing\n", filename.c_str()); + } + + ni = 0; + mesh->traverse(level, traverseFlag | Mesh::FILL_COORDS, markFct); + + fprintf(valueFile, "mesh name: %s\n\n", + values->getFESpace()->getMesh()->getName().c_str()); + fprintf(valueFile, "time: %e\n\n", time); + fprintf(valueFile, "number of values: 1\n\n"); + fprintf(valueFile, "value description: %s\n", values->getName().c_str()); + fprintf(valueFile, "number of interpolation points: %d\n", ni); + fprintf(valueFile, "type: scalar\n"); + fprintf(valueFile, "interpolation type: lagrange\n"); + fprintf(valueFile, "interpolation degree: %d\n", + feSpace->getBasisFcts()->getDegree()); + fprintf(valueFile, "end of description: %s\n\n", values->getName().c_str()); + + + /* ----- write vertex values -----*/ + DOFVector<double>::Iterator valueIt(valueVec, USED_DOFS); + DOFVector< ::std::list<WorldVector<double> > >::Iterator coordIt(dofCoords, USED_DOFS); + + int i; + + fprintf(valueFile, "vertex values: %s\n", values->getName().c_str()); + + for(intPointIt.reset(), valueIt.reset(), coordIt.reset(); + !intPointIt.end(); + ++intPointIt, ++valueIt, ++coordIt) + { + if(*intPointIt == -2) { + for(i=0; i < (int) coordIt->size(); i++) { + fprintf(valueFile, "%e\n", *valueIt); + } + } + } + + fprintf(valueFile, "\n\n"); + + /* ----- write interpolation values ----- */ + fprintf(valueFile, "interpolation values: %s\n", values->getName().c_str()); + + + int nd = 0; + for(intPointIt.reset(), valueIt.reset(); + !intPointIt.end(); + ++intPointIt, ++valueIt) + { + if(*intPointIt == -3) { + fprintf(valueFile, "%e\n", *valueIt); + *intPointIt = nd++; + } + } + + fprintf(valueFile, "\n\n"); + + /* ----- write interpolation points for each simplex */ + fprintf(valueFile, "element interpolation points: %s\n", + values->getName().c_str()); + mesh->traverse(level, traverseFlag, + writeInterpolPoints); + fprintf(valueFile, "\n"); + + fclose(valueFile); + DELETE interpPointInd; + DELETE dofCoords; + } + + void ValueWriter::writeValues(DataCollector *dc, + const ::std::string filename, + double time, + int level, + Flag traverseFlag, + bool (*writeElem)(ElInfo*)) + { + FUNCNAME("ValueWriter::writeValues2"); + TEST_EXIT(dc)("no data collector\n"); + + ::std::ofstream file; + + file.open(filename.c_str()); + + file << "mesh name: " << dc->getMesh()->getName() << ::std::endl << ::std::endl; + file << "time: " << ::std::scientific << time << ::std::endl << ::std::endl; + file << "number of values: 1" << ::std::endl << ::std::endl; + file << "value description: " << dc->getValues()->getName() << ::std::endl; + file << "number of interpolation points: " << dc->getNumberInterpPoints() + << ::std::endl; + file << "type: scalar" << ::std::endl; + file << "interpolation type: lagrange" << ::std::endl; + file << "interpolation degree: " << dc->getFeSpace()->getBasisFcts()->getDegree() + << ::std::endl; + file << "end of description: " << dc->getValues()->getName() + << ::std::endl << ::std::endl; + + /* ----- write vertex values -----*/ + DOFVector<int>::Iterator intPointIt(dc->getInterpPointInd(), USED_DOFS); + DOFVector<double>::Iterator valueIt(dc->getValues(), USED_DOFS); + DOFVector< ::std::list<WorldVector<double> > >::Iterator + coordIt(dc->getDofCoords(), USED_DOFS); + + int i; + + file << "vertex values: " << dc->getValues()->getName() << ::std::endl; + + for(intPointIt.reset(), valueIt.reset(), coordIt.reset(); + !intPointIt.end(); + ++intPointIt, ++valueIt, ++coordIt) + { + if(*intPointIt == -2) { + for(i=0; i < (int) coordIt->size(); i++) { + file << ::std::scientific << *valueIt << ::std::endl; + } + } + } + + file << ::std::endl << ::std::endl; + + /* ----- write interpolation values ----- */ + file << "interpolation values: " << dc->getValues()->getName() << ::std::endl; + + for(intPointIt.reset(), valueIt.reset(); + !intPointIt.end(); + ++intPointIt, ++valueIt) + { + if(*intPointIt >= 0) { + file << ::std::scientific << *valueIt << ::std::endl; + } + } + + file << ::std::endl << ::std::endl; + + /* ----- write interpolation points for each simplex */ + file << "element interpolation points: " << dc->getValues()->getName() << ::std::endl; + + ::std::list< ::std::list<int> >* interpPoints = dc->getInterpPoints(); + ::std::list< ::std::list<int> >::iterator it1; + ::std::list<int>::iterator it2; + + for(it1 = interpPoints->begin(); it1 != interpPoints->end(); ++it1) { + for(it2 = it1->begin(); it2 != it1->end(); ++it2) { + file << (*it2) << " "; + } + file << ::std::endl; + } + + file << ::std::endl; + + file.close(); + } + + +} diff --git a/AMDiS/src/ValueWriter.h b/AMDiS/src/ValueWriter.h new file mode 100644 index 0000000000000000000000000000000000000000..eb62fcef87b08f416e7c565e2fe3910c44235f55 --- /dev/null +++ b/AMDiS/src/ValueWriter.h @@ -0,0 +1,120 @@ +// ============================================================================ +// == == +// == AMDiS - Adaptive multidimensional simulations == +// == == +// ============================================================================ +// == == +// == crystal growth group == +// == == +// == Stiftung caesar == +// == Ludwig-Erhard-Allee 2 == +// == 53175 Bonn == +// == germany == +// == == +// ============================================================================ +// == == +// == http://www.caesar.de/cg/AMDiS == +// == == +// ============================================================================ + +/** \file ValueWriter.h */ + +#ifndef AMDIS_VALUEWRITER_H +#define AMDIS_VALUEWRITER_H + +#include <list> + +#include "Global.h" +#include "FixVec.h" +#include "Flag.h" +#include "Mesh.h" +#include "DataCollector.h" + +namespace AMDiS { + +class DOFAdmin; +class ElInfo; + +template<typename T> class DOFVector; + +// ============================================================================ +// ===== class ValueWriter ==================================================== +// ============================================================================ + +/** \ingroup Output + * \brief + * ValueWriter is a static class which writes the values of a DOFVector + * values to an ascii file named values->name.'dat'. This output is done + * via two leaf-traversals of values->feSpace->mesh. In the first traversal + * the values at the vertices are printed, in the second these at the + * interpolation points of each element. For a closer disription of the + * output format see (...link fehlt noch) + */ +class ValueWriter +{ +public: + /** \brief + * Writes DOFVector values to values->feSpace->mesh. + */ + static void writeValues(DataCollector *dc, + const ::std::string filename, + double time = 0.0, + int level = -1, + Flag traverseFlag = Mesh::CALL_LEAF_EL, + bool (*writeElem)(ElInfo*) = NULL); + + + // OBSOLETE + // TODO: Remove if ValueWriter::writeValues is stable. + static void writeValuesOld(DOFVector<double> *values, + char* fn = NULL, + double time = 0.0, + int level = -1, + Flag traverseFlag = Mesh::CALL_LEAF_EL); + +protected: + /** \brief + * Marks vertices and interpolation points in \ref interpPointInd + */ + static int markFct(ElInfo *el_info); + + /** \brief + * Writes indices of interpolation points of element + */ + static int writeInterpolPoints(ElInfo *el_info); + +protected: + /** \brief + * File to which the values should be written + */ + static FILE *valueFile; + + /** \brief + * Global interpolation point indexing + */ + static DOFVector<int> *interpPointInd; + + /** \brief + * list of coords for each dof + */ + static DOFVector< ::std::list<WorldVector<double> > > *dofCoords; + + /** \brief + * DOFAdmin of values + */ + static const DOFAdmin *admin; + + /** \brief + * Pointer to have a global access to values + */ + static DOFVector<double> *valueVec; + + /** \brief + * Total number of interpolation points. + */ + static int ni; +}; + +} + +#endif // AMDIS_VALUEWRITER_H diff --git a/AMDiS/src/VecSymSolver.h b/AMDiS/src/VecSymSolver.h new file mode 100644 index 0000000000000000000000000000000000000000..dabe18e2a06bcb0af5aa5bec206eca74c98ce67d --- /dev/null +++ b/AMDiS/src/VecSymSolver.h @@ -0,0 +1,102 @@ +// ============================================================================ +// == == +// == AMDiS - Adaptive multidimensional simulations == +// == == +// ============================================================================ +// == == +// == crystal growth group == +// == == +// == Stiftung caesar == +// == Ludwig-Erhard-Allee 2 == +// == 53175 Bonn == +// == germany == +// == == +// ============================================================================ +// == == +// == http://www.caesar.de/cg/AMDiS == +// == == +// ============================================================================ + +/** \file VecSymSolver.h */ + +#ifndef AMDIS_VECSYMSOLVER_H +#define AMDIS_VECSYMSOLVER_H + +#include "OEMSolver.h" +#include "MemoryManager.h" +#include "V3Vector.h" + +namespace AMDiS { + + // ============================================================================ + // ===== class VecSymSolver =================================================== + // ============================================================================ + + /** + * \ingroup Solver + * + * \brief + */ + template<typename VectorType> + class VecSymSolver : public OEMSolver<VectorType> + { + public: + MEMORY_MANAGED(VecSymSolver<VectorType>); + + /** \brief + * Creator class used in the OEMSolverMap. + */ + class Creator : public OEMSolverCreator<VectorType> + { + public: + MEMORY_MANAGED(Creator); + + virtual ~Creator() {}; + + /** \brief + * Returns a new CGSolver object. + */ + OEMSolver<VectorType>* create() { + return NEW VecSymSolver<VectorType>(this->name); + }; + }; + + /** \brief + * constructor + */ + VecSymSolver(::std::string name); + + /** \brief + * destructor + */ + ~VecSymSolver(); + protected: + /** \brief + * Implements OEMSolver<VectorType>::init(). + */ + void init() { + p = this->vectorCreator->create(); + r = this->vectorCreator->create(); + }; + + /** \brief + * Implements OEMSolver<VectorType>::exit(). + */ + void exit() { + this->vectorCreator->free(p); + }; + + /** \brief + * Implements OEMSolver<VectorType>::solve(). + */ + int solveSystem(MatVecMultiplier<VectorType> *mv, VectorType *x, VectorType *b); + + private: + VectorType *r, *p; + }; +} + +#include "VecSymSolver.hh" + +#endif // AMDIS_VECSYMSOLVER_H + diff --git a/AMDiS/src/VecSymSolver.hh b/AMDiS/src/VecSymSolver.hh new file mode 100644 index 0000000000000000000000000000000000000000..15332bcb9674452562e15728e69cc8c886540aea --- /dev/null +++ b/AMDiS/src/VecSymSolver.hh @@ -0,0 +1,443 @@ +//#include <fstream> + +#include <vector> + +#include "VecSymSolver.h" +#include "DOFMatrix.h" +#include "DiagonalPreconditioner.h" +#include "ILUPreconditioner.h" +#include "MatVecMultiplier.h" + +namespace AMDiS { + + template<typename VectorType> + VecSymSolver<VectorType>::VecSymSolver(::std::string name) + : OEMSolver<VectorType>(name) + {} + + template<typename VectorType> + VecSymSolver<VectorType>::~VecSymSolver() {} + +/* template<typename VectorType> + int VecSymSolver<VectorType>::solveSystem(MatVecMultiplier<VectorType> *matVec, + VectorType *x, VectorType *b) + { + FUNCNAME("VecSymSolver::solveSystem()"); + + StandardMatVec<Matrix<DOFMatrix*>, SystemVector> *stdMatVec = + dynamic_cast<StandardMatVec<Matrix<DOFMatrix*>, SystemVector> *>(matVec); + + Matrix<DOFMatrix*> *m = stdMatVec->getMatrix(); + + DOFMatrix* dofm = (*m)[0][0]; + + int nComponents = m->getSize(); + int oneMatrixSize = dofm->getFESpace()->getAdmin()->getUsedSize(); + int bigMatrixSize = oneMatrixSize; + + ::std::vector< ::std::vector< MatEntry33 > > newm; + newm.resize(bigMatrixSize); + + ::std::vector<V3> xvec(bigMatrixSize); + ::std::vector<V3> bvec(bigMatrixSize); + for (int i = 0; i < bigMatrixSize; i++) { + xvec[i].resize(3); + bvec[i].resize(3); + } + + for (int stencilRow = 0; stencilRow < nComponents; stencilRow++) { + for (int stencilCol = 0; stencilCol < nComponents; stencilCol++) { + + if (!(*m)[stencilRow][stencilCol]) { +// ::std::cout << "Matrix " << stencilRow << "-" << stencilCol << " ist 0!" << ::std::endl; + continue; + } else { + (*m)[stencilRow][stencilCol]->print(); + + if ((*m)[stencilRow][stencilCol]->symmetric()) { + ::std::cout << "Matrix " << stencilRow << "-" << stencilCol << " ist symmetrisch!" << ::std::endl; + } else { + ::std::cout << "Matrix " << stencilRow << "-" << stencilCol << " ist nicht symmetrisch!" << ::std::endl; + } + }; + + DOFMatrix::Iterator matrixRow((*m)[stencilRow][stencilCol], USED_DOFS); + int rowIndex = 0; + for (matrixRow.reset(); !matrixRow.end(); ++matrixRow, rowIndex++) { + for (int i = 0; i < static_cast<int>((*matrixRow).size()); i++) { + if ((*matrixRow)[i].col >= 0) { + MatEntry33 *newMe = NULL; + +// if ((stencilRow == 0) && (stencilCol == 0) && +// (rowIndex == 0) && ((*matrixRow)[i].col == 0)) { +// ::std::cout << "Dich habe ich: " << (*matrixRow)[i].entry << ::std::endl; +// } + + for (int j = 0; j < static_cast<int>(newm[rowIndex].size()); j++) { + if (newm[rowIndex][j].col == (*matrixRow)[i].col) { + newMe = &(newm[rowIndex][j]); + } + } + + if (newMe == NULL) { +// if ((rowIndex == 0) && ((*matrixRow)[i].col == 0)) { +// ::std::cout << "0-Matrix neu anlegen!" << ::std::endl; +// }; + + MatEntry33 newMe; + newMe.col = (*matrixRow)[i].col; + newMe.entry.set(stencilRow, stencilCol, (*matrixRow)[i].entry); + newm[rowIndex].push_back(newMe); + +// if ((rowIndex == 0) && ((*matrixRow)[i].col == 0)) { +// ::std::cout << "0-Matrix: " << ::std::endl; +// newMe.entry.print(); +// } + + } else { + newMe->entry.set(stencilRow, stencilCol, (*matrixRow)[i].entry); + +// if ((rowIndex == 0) && ((*matrixRow)[i].col == 0)) { +// ::std::cout << "0-Matrix: " << ::std::endl; +// newMe->entry.print(); +// } + } + + } + } + } + + } + } + + + for (int i = 0; i < static_cast<int>(newm.size()); i++) { + + for (int j = 0; j < static_cast<int>(newm[j].size()); j++) { + if (newm[i][j].col == i) { + MatEntry33 tmp = newm[i][0]; + newm[i][0] = newm[i][j]; + newm[i][j] = tmp; + + break; + } + } + } + + + ::std::cout << "Gesuchter Vektor ist: " << ::std::endl; + + for (int i = 0; i < x->getSize(); i++) { + DOFVector<double>::Iterator it(x->getDOFVector(i), USED_DOFS); + + int counter = 0; + for (it.reset(); !it.end(); it++, counter++) { + ::std::cout << (*it) << ::std::endl; + + xvec[counter][i] = *it; + } + } + + ::std::cout << "Rechte Seite ist: " << ::std::endl; + + for (int i = 0; i < b->getSize(); i++) { + DOFVector<double>::Iterator it(b->getDOFVector(i), USED_DOFS); + + int counter = 0; + for (it.reset(); !it.end(); it++, counter++) { + ::std::cout << (*it) << ::std::endl; + + bvec[counter][i] = *it; + } + } + + + bool isSym = true; + + for (int i = 0; i < static_cast<int>(newm.size()); i++) { + +// ::std::cout << "Zeile " << i << ": " << ::std::endl; + + for (int j = 0; j < static_cast<int>(newm[i].size()); j++) { + int col = newm[i][j].col; + +// ::std::cout << col << ": [ "; +// for (int k = 0; k < 9; k++) { +// ::std::cout << newm[i][j].entry[k] << " "; +// } +// ::std::cout << "], "; + + if (col != i) { + for (int k = 0; k < static_cast<int>(newm[col].size()); k++) { + if (newm[col][k].col == i) { + if (newm[i][j].entry != newm[col][k].entry) { + isSym = false; + } + } + } + } + } + +// ::std::cout << ::std::endl; + } + + if (isSym) { + ::std::cout << "Gesamtmatrix ist symmetrisch!" << ::std::endl; + } else { + ::std::cout << "Gesamtmatrix ist nicht symmetrisch!" << ::std::endl; + } + + CGSolver< ::std::vector<V3> > solver2(this->name); + solver2.initParameters(); + solver2.setVectorCreator(NEW V3Creator(bigMatrixSize)); + + StandardMatVec< ::std::vector< ::std::vector<MatEntry33> >, ::std::vector<V3> > mv(&newm); + + *p = *x; + *p *= -1.0; + matVec->matVec(NoTranspose, *p, *r); + *r += *b; + + ::std::cout << "Checking res 1: " << norm(r) << ::std::endl; + + solver2.solve(&mv, &xvec, &bvec); + + for (int i = 0; i < x->getSize(); i++) { + DOFVector<double>::Iterator it(x->getDOFVector(i), USED_DOFS); + + int counter = 0; + for (it.reset(); !it.end(); it++, counter++) { + *it = xvec[counter][i]; + } + } + + *p = *x; + *p *= -1.0; + matVec->matVec(NoTranspose, *p, *r); + *r += *b; + + ::std::cout << "Checking res 2: " << norm(r) << ::std::endl; + + ERROR_EXIT("na, dass wars wohl!\n"); + + return(0); + } +*/ + + + template<typename VectorType> + int VecSymSolver<VectorType>::solveSystem(MatVecMultiplier<VectorType> *matVec, + VectorType *x, VectorType *b) + { + FUNCNAME("VecSymSolver::solveSystem()"); + + StandardMatVec<Matrix<DOFMatrix*>, SystemVector> *stdMatVec = + dynamic_cast<StandardMatVec<Matrix<DOFMatrix*>, SystemVector> *>(matVec); + + Matrix<DOFMatrix*> *m = stdMatVec->getMatrix(); + + DOFMatrix* dofm = (*m)[0][0]; + + int nComponents = m->getSize(); + int oneMatrixSize = dofm->getFESpace()->getAdmin()->getUsedSize(); + int bigMatrixSize = oneMatrixSize * nComponents; + + ::std::vector< ::std::vector< MatEntry > > newm(bigMatrixSize, ::std::vector<MatEntry>(0)); + ::std::vector<double> xvec(bigMatrixSize); + ::std::vector<double> bvec(bigMatrixSize); + + int nElements = 0; + + for (int stencilRow = 0; stencilRow < nComponents; stencilRow++) { + for (int stencilCol = 0; stencilCol < nComponents; stencilCol++) { + + if (!(*m)[stencilRow][stencilCol]) { + continue; + } + + // ::std::cout << "------------------------------" << ::std::endl; + // ::std::cout << "Matrix " << stencilRow << " - " << stencilCol << ::std::endl; + + // (*m)[stencilRow][stencilCol]->print(); + + DOFMatrix::Iterator matrixRow((*m)[stencilRow][stencilCol], USED_DOFS); + int rowIndex = 0; + for (matrixRow.reset(); !matrixRow.end(); matrixRow++, rowIndex++) { + for (int i = 0; i < static_cast<int>((*matrixRow).size()); i++) { + if ((*matrixRow)[i].col >= 0) { + MatEntry newMe; + newMe.entry = (*matrixRow)[i].entry; + newMe.col = ((*matrixRow)[i].col * nComponents) + stencilCol; + + newm[(rowIndex * nComponents) + stencilRow].push_back(newMe); + + nElements++; + } + } + } + +// if ((*m)[stencilRow][stencilCol]->symmetric()) { +// ::std::cout << "Matrix " << stencilRow << "-" << stencilCol << " ist symmetrisch!" << ::std::endl; +// } else { +// ::std::cout << "Matrix " << stencilRow << "-" << stencilCol << " ist nicht symmetrisch!" << ::std::endl; +// } + + + } + } + + + for (int i = 0; i < static_cast<int>(newm.size()); i++) { + for (int j = 0; j < static_cast<int>(newm[i].size()); j++) { + if (newm[i][j].col == i) { + MatEntry tmp = newm[i][0]; + newm[i][0] = newm[i][j]; + newm[i][j] = tmp; + + break; + } + } + } + +// ::std::cout << "-------------------------------" << ::std::endl; +// for (int i = 0; i < static_cast<int>(newm.size()); i++) { +// ::std::cout << "row : " << i << ::std::endl; +// for (int j = 0; j < static_cast<int>(newm[i].size()); j++) { +// ::std::cout << " ( " << newm[i][j].col << ", " << newm[i][j].entry << ")"; +// } +// ::std::cout << ::std::endl; +// } + + for (int i = 0; i < x->getSize(); i++) { + DOFVector<double>::Iterator it(x->getDOFVector(i), USED_DOFS); + + int counter = 0; + for (it.reset(); !it.end(); it++, counter++) { + xvec[counter * nComponents + i] = *it; + } + } + + for (int i = 0; i < b->getSize(); i++) { + DOFVector<double>::Iterator it(b->getDOFVector(i), USED_DOFS); + + int counter = 0; + for (it.reset(); !it.end(); it++, counter++) { + bvec[counter * nComponents + i] = *it; + } + } + + /* ======= CHOLMOD ========= + ::std::fstream file; + + file.open("matrix.m", fstream::out); + file << newm.size() << " " << newm.size() << " " << nElements << ::std::endl; + for (int i = 0; i < static_cast<int>(newm.size()); i++) { + for (int j = 0; j < static_cast<int>(newm[i].size()); j++) { + file << i + 1 << " " << newm[i][j].col + 1 << " " << newm[i][j].entry << ::std::endl; + } + } + file.close(); + + file.open("vector.m", fstream::out); + file << bvec.size() << " 1" << ::std::endl; + for (int i = 0; i < static_cast<int>(bvec.size()); i++) { + file << bvec[i] << ::std::endl; + } + file.close(); + */ + + bool isSym = true; + + for (int i = 0; i < static_cast<int>(newm.size()); i++) { + for (int j = 0; j < static_cast<int>(newm[i].size()); j++) { + int col = newm[i][j].col; + + if (col != i) { + for (int k = 0; k < static_cast<int>(newm[col].size()); k++) { + if (newm[col][k].col == i) { + if (newm[i][j].entry != newm[col][k].entry) { + isSym = false; + } + } + } + } + } + } + + if (isSym) { + ::std::cout << "Matrix is symmetrisch!" << ::std::endl; + } else { + ::std::cout << "Matrix ist nicht symmetrisch!" << ::std::endl; + } + + + + /* ======= CHOLMOD ========= + + double one [2] = {1,0}, m1 [2] = {-1,0}; + cholmod_sparse *A; + cholmod_dense *ch_b; + cholmod_dense *ch_x; + cholmod_dense *ch_r; + cholmod_common c; + cholmod_factor *L; + cholmod_start(&c); + + FILE *f = fopen("matrix.m", "r"); + A = cholmod_read_sparse(f, &c); + fclose(f); + + f = fopen("vector.m", "r"); + ch_b = cholmod_read_dense(f, &c); + fclose(f); + + L = cholmod_analyze(A, &c); + cholmod_factorize(A, L, &c); + + ch_x = cholmod_solve(CHOLMOD_A, L, ch_b, &c); + ch_r = cholmod_copy_dense(ch_b, &c); + cholmod_sdmult (A, 0, m1, one, ch_x, ch_r, &c) ; + ::std::cout << "NORM: " << cholmod_norm_dense(ch_r, 2, &c) << ::std::endl; + + cholmod_finish(&c); + */ + + //GMResSolver2< ::std::vector<double> > solver2(this->name); + //CGSolver< ::std::vector<double> > solver2(this->name); + // BiCGStab< ::std::vector<double> > solver2(this->name); + + // solver2.initParameters(); + // solver2.setVectorCreator(NEW StlVectorCreator(bigMatrixSize)); + + // StandardMatVec< ::std::vector< ::std::vector<MatEntry> >, ::std::vector<double> > mv(&newm); + + // ILUPreconditionerStd ilu; + // ilu.setMatrix(&newm); + + // DiagonalPreconditionerStd diag; + // diag.setMatrix(&newm); + + // solver2.solve(&mv, &xvec, &bvec, &diag); + + for (int i = 0; i < x->getSize(); i++) { + DOFVector<double>::Iterator it(x->getDOFVector(i), USED_DOFS); + + int counter = 0; + for (it.reset(); !it.end(); it++, counter++) { + *it = xvec[counter * nComponents + i]; + } + } + + *p = *x; + *p *= -1.0; + matVec->matVec(NoTranspose, *p, *r); + *r += *b; + + ::std::cout << "NORM: " << norm(r) << ::std::endl; + + // ERROR_EXIT("DA\n"); + + return(1); + } + +} diff --git a/AMDiS/src/VertexInfo.h b/AMDiS/src/VertexInfo.h new file mode 100644 index 0000000000000000000000000000000000000000..45306eaf9fa29818afbc120b413c1fc4e6da2282 --- /dev/null +++ b/AMDiS/src/VertexInfo.h @@ -0,0 +1,60 @@ +// ============================================================================ +// == == +// == AMDiS - Adaptive multidimensional simulations == +// == == +// ============================================================================ +// == == +// == crystal growth group == +// == == +// == Stiftung caesar == +// == Ludwig-Erhard-Allee 2 == +// == 53175 Bonn == +// == germany == +// == == +// ============================================================================ +// == == +// == http://www.caesar.de/cg/AMDiS == +// == == +// ============================================================================ + +/** \file VertexInfo.h */ + +#ifndef AMDIS_VERTEXINFO_H +#define AMDIS_VERTEXINFO_H + +#include "FixVec.h" + +namespace AMDiS { + /** \brief + * Stores coordinates and output index for one vertex. + */ + class VertexInfo + { + public: + /** \brief + * Coordinates for this vertex. + */ + WorldVector<double> coords; + + /** \brief + * Index for the output file. + */ + int outputIndex; + + /** \brief + * Used to check, whether coords are already stored for a given dof. + */ + bool operator==(const WorldVector<double>& c) { + return (c == coords); + }; + + /** \brief + * Used to check, whether coords are already stored for a given dof. + */ + bool operator!=(const WorldVector<double>& c) { + return (c != coords); + }; + }; +} + +#endif diff --git a/AMDiS/src/VertexVector.cc b/AMDiS/src/VertexVector.cc new file mode 100644 index 0000000000000000000000000000000000000000..effe10df0e567fc75292d2b9d71d251dd59fddeb --- /dev/null +++ b/AMDiS/src/VertexVector.cc @@ -0,0 +1,31 @@ +#include "VertexVector.h" +#include "DOFAdmin.h" +#include "DOFIterator.h" + +namespace AMDiS { + + VertexVector::VertexVector(const DOFAdmin *admin_, ::std::string name_) + : DOFVectorDOF() + { + name = name_; + feSpace = NULL; + admin = admin_; + const_cast<DOFAdmin*>(admin)->addDOFIndexed(this); + const_cast<DOFAdmin*>(admin)->addDOFContainer(this); + } + + VertexVector::~VertexVector() + { + const_cast<DOFAdmin*>(admin)->removeDOFIndexed(this); + const_cast<DOFAdmin*>(admin)->removeDOFContainer(this); + } + + void VertexVector::set(DegreeOfFreedom val) + { + DOFIteratorBase it(const_cast<DOFAdmin*>(admin), USED_DOFS); + for(it.reset(); !it.end(); ++it) { + if(!it.isDOFFree()) operator[](it.getDOFIndex()) = val; + } + } + +} diff --git a/AMDiS/src/VertexVector.h b/AMDiS/src/VertexVector.h new file mode 100644 index 0000000000000000000000000000000000000000..99e3e07b2caa86302255d17757fc45cf8d86b633 --- /dev/null +++ b/AMDiS/src/VertexVector.h @@ -0,0 +1,52 @@ +#ifndef AMDIS_VERTEXVECTOR_H +#define AMDIS_VERTEXVECTOR_H + +#include "DOFVector.h" + +namespace AMDiS { + + class VertexVector : public DOFVectorDOF + { + public: + MEMORY_MANAGED(VertexVector); + + class Iterator : public DOFIterator<DegreeOfFreedom> { + public: + Iterator(VertexVector *c, DOFIteratorType type) + : DOFIterator<DegreeOfFreedom>(const_cast<DOFAdmin*>(c->getAdmin()), + dynamic_cast<DOFIndexed<DegreeOfFreedom>*>(c), + type) + {}; + }; + + VertexVector(const DOFAdmin *admin_, ::std::string name_); + + ~VertexVector(); + + const DOFAdmin *getAdmin() { return admin; }; + + void resize(int size) { + int i, oldSize = static_cast<int>(vec.size()); + vec.resize(size); + for(i = oldSize; i < size; i++) { + vec[i] = i; + } + }; + + void set(DegreeOfFreedom val); + + void compressDOFContainer(int size, ::std::vector<DegreeOfFreedom> &newDOF) { + DOFContainer::compressDOFContainer(size, newDOF); + int totalSize = getAdmin()->getSize(); + for(int i = size; i < totalSize; i++) { + vec[i] = i; + } + }; + + protected: + const DOFAdmin *admin; + }; + +} + +#endif diff --git a/AMDiS/src/VtkWriter.cc b/AMDiS/src/VtkWriter.cc new file mode 100644 index 0000000000000000000000000000000000000000..104b7844d3513f114ce90f40f2341bbbacfd1d49 --- /dev/null +++ b/AMDiS/src/VtkWriter.cc @@ -0,0 +1,135 @@ +#include <string> +#include <fstream> + +#include "VtkWriter.h" +#include "DataCollector.h" +#include "DOFVector.h" +#include "SurfaceRegion_ED.h" +#include "ElementRegion_ED.h" + +namespace AMDiS { + int VtkWriter::writeFile(::std::vector<DataCollector*> *dc, + const char *name) + { + ::std::ofstream file; + ::std::list<ElementInfo> *elements = (*dc)[0]->getElementInfos(); + + DOFVector< ::std::list<VertexInfo> > *vertexInfos = (*dc)[0]->getVertexInfos(); + + int nv = (*dc)[0]->getNumberVertices(); + int ne = (*dc)[0]->getNumberElements(); + int vertices = (*dc)[0]->getMesh()->getGeo(VERTEX); + + file.open(name); + + file << "<?xml version=\"1.0\"?>" << ::std::endl; + file << "<VTKFile type=\"UnstructuredGrid\" version=\"0.1\" byte_order=\"LittleEndian\">" << ::std::endl; + file << " <UnstructuredGrid>" << ::std::endl; + file << " <Piece NumberOfPoints=\"" << nv << "\" NumberOfCells=\"" << ne << "\">" << ::std::endl; + file << " <Points>" << ::std::endl; + file << " <DataArray type=\"Float32\" NumberOfComponents=\"3\" format=\"ascii\">" << ::std::endl; + + + DOFVector< ::std::list<VertexInfo> >::Iterator it(vertexInfos, USED_DOFS); + int counter = 0; + + // for all DOFs + for (it.reset(); !it.end(); ++it) { + // for all vertex infos of this DOF + ::std::list<VertexInfo>::iterator it2; + for (it2 = it->begin(); it2 != it->end(); ++it2) { + it2->outputIndex = counter++; + for (int i = 0; i < Global::getGeo(WORLD); i++) { + file << " " << ::std::scientific << it2->coords[i]; + } + for (int i = Global::getGeo(WORLD); i < 3; i++) { + file << " 0.0"; + } + file << ::std::endl; + } + } + + file << " </DataArray>" << ::std::endl; + file << " </Points>" << ::std::endl; + file << " <Cells>" << ::std::endl; + + file << " <DataArray type=\"Int32\" Name=\"offsets\">" << ::std::endl; + for (int i = 0; i < ne; i++) { + file << " " << (i + 1) * vertices << ::std::endl; + } + file << " </DataArray>" << ::std::endl; + + file << " <DataArray type=\"UInt8\" Name=\"types\">" << ::std::endl; + for (int i = 0; i < ne; i++) { + switch (vertices) { + case 2: + file << " 3" << ::std::endl; + break; + case 3: + file << " 5" << ::std::endl; + break; + case 4: + file << " 10" << ::std::endl; + break; + default: + break; + } + } + file << " </DataArray>" << ::std::endl; + + file << " <DataArray type=\"Int32\" Name=\"connectivity\">" << ::std::endl; + ::std::list<ElementInfo>::iterator elementIt; + + for (elementIt = elements->begin(); elementIt != elements->end(); ++elementIt) { + // for all vertices + for (int i = 0; i < vertices; i++) { + file << " " << elementIt->vertexInfo[i]->outputIndex; + } + file << ::std::endl; + } + file << " </DataArray>" << ::std::endl; + + file << " </Cells>" << ::std::endl; + file << " <PointData>" << ::std::endl; + + /* ----- write vertex values -----*/ + for (int i = 0; i < static_cast<int>(dc->size()); i++) { + file << " <DataArray type=\"Float32\" Name=\"value" << i + << "\" format=\"ascii\">" << ::std::endl; + + DOFVector<int> *interpPointInd = (*dc)[i]->getInterpPointInd(); + DOFVector<double> *values = (*dc)[i]->getValues(); + DOFVector< ::std::list<WorldVector<double> > > *dofCoords = (*dc)[i]->getDofCoords(); + + DOFVector<int>::Iterator intPointIt(interpPointInd, USED_DOFS); + DOFVector<double>::Iterator valueIt(values, USED_DOFS); + DOFVector< ::std::list<WorldVector<double> > >::Iterator coordIt(dofCoords, USED_DOFS); + + for (intPointIt.reset(), valueIt.reset(), coordIt.reset(); + !intPointIt.end(); + ++intPointIt, ++valueIt, ++coordIt) + { + if (*intPointIt == -2) { + for (int j = 0; j < static_cast<int>(coordIt->size()); j++) { + if (*valueIt < 1e-40) { + file << " " << 0.0 << ::std::endl; + } else { + file << " " << *valueIt << ::std::endl; + } + } + } + } + + file << " </DataArray>" << ::std::endl; + } + + file << " </PointData>" << ::std::endl; + file << " </Piece>" << ::std::endl; + file << " </UnstructuredGrid>" << ::std::endl; + file << "</VTKFile>" << ::std::endl; + + file.close(); + + return 0; + } +} diff --git a/AMDiS/src/VtkWriter.h b/AMDiS/src/VtkWriter.h new file mode 100644 index 0000000000000000000000000000000000000000..24e7ed532d15e353ac6186d04353cfa1113462f5 --- /dev/null +++ b/AMDiS/src/VtkWriter.h @@ -0,0 +1,37 @@ +// ============================================================================ +// == == +// == AMDiS - Adaptive multidimensional simulations == +// == == +// ============================================================================ +// == == +// == crystal growth group == +// == == +// == Stiftung caesar == +// == Ludwig-Erhard-Allee 2 == +// == 53175 Bonn == +// == germany == +// == == +// ============================================================================ +// == == +// == http://www.caesar.de/cg/AMDiS == +// == == +// ============================================================================ + +/** \file VtkWriter.h */ + +#ifndef AMDIS_VTKWRITER_H +#define AMDIS_VTKWRITER_H + +#include "DataCollector.h" + +namespace AMDiS { + + class VtkWriter + { + public: + static int writeFile(::std::vector<DataCollector*> *dc, + const char *name); + }; +} + +#endif diff --git a/AMDiS/src/demangle.cc b/AMDiS/src/demangle.cc new file mode 100644 index 0000000000000000000000000000000000000000..b7e8fd71a9380beb71380cd2689a8f77bff8b7f2 --- /dev/null +++ b/AMDiS/src/demangle.cc @@ -0,0 +1,173 @@ +#include "demangle.h" +#include <typeinfo> +#include <math.h> +#include <stdio.h> +#include "Global.h" + +namespace AMDiS { + +void demangle_rec(char**, char**); + +void demangle(const char* in, char* result) +{ + //printf("mangled name: %s ", in); + char** inptr = const_cast<char**>(&in); + char** resultptr = &result; + + demangle_rec(inptr, resultptr); + sprintf((*resultptr), "\0"); +} + +void demangle_template(char **in, char **result) +{ + demangle_rec(in, result); + + sprintf((*result), "<"); + (*result)++; + + // template parameters + char c = (*in)[0]; + + if((c >= '0') && c <= '9') { + int n; + sscanf((*in), "%d", &n); + (*in) += (static_cast<int>(log10(n))) + 1; + for(int i=0; i < n; i++) { + if((*in)[0] == 'Z') { + (*in)++; + demangle_rec(in, result); + } else { + demangle_rec(in, result); + sprintf((*result), " = "); + (*result) += 3; + if((*in)[0] == 'm') { + (*in)++; + } + int n; + sscanf((*in), "%d", &n); + sprintf((*result), "%d", n); + (*in) += static_cast<int>(log10(n)) + 1; + (*result) += static_cast<int>(log10(n)) + 1; + } + if(i != n-1) { + sprintf((*result), ", "); + (*result) += 2; + } + } + } else { + ERROR_EXIT("number expected\n"); + } + + sprintf((*result), ">"); + (*result)++; +} + +void demangle_qualified(char** in, char** result) +{ + char c = (*in)[0]; + + if((c >= '0') && c <= '9') { + int n = static_cast<int>(c - '0'); + (*in)++; + for(int i=0; i < n; i++) { + demangle_rec(in, result); + if(i != n-1) { + sprintf((*result), "::"); + (*result) += 2; + } + } + } else { + ERROR_EXIT("number expected\n"); + } +}; + +void demangle_rec(char** in, char** result) +{ + char c; + + c = (*in)[0]; + + if((c >= '0') && (c <= '9')) { + int l; + // type name + sscanf((*in), "%d", &l); + (*in) += (static_cast<int>(log10(l)) + 1); + strncpy((*result), (*in), l); + (*in) += l; + (*result) += l; + } else { + (*in)++; + switch(c) { + case 'A': // array + break; + case 'b': // bool + sprintf((*result), "bool"); + (*result) += 4; + break; + case 'c': // char + sprintf((*result), "char"); + (*result) += 4; + break; + case 'C': // const + sprintf((*result), "const "); + (*result) += 6; + demangle_rec(in, result); + break; + case 'd': // double + sprintf((*result), "double"); + (*result) += 6; + break; + case 'f': // float + sprintf((*result), "float"); + (*result) += 5; + break; + case 'i': // int + sprintf((*result), "int"); + (*result) += 3; + break; + case 'J': // complex type + break; + case 'l': // long + break; + case 'P': // pointer + demangle_rec(in, result); + sprintf((*result), "*"); + (*result)++; + break; + case 'Q': // qualified name + demangle_qualified(in, result); + break; + case 'r': // long double + break; + case 'R': // reference + demangle_rec(in, result); + sprintf((*result), "&"); + (*result)++; + break; + case 's': // short + break; + case 'S': // signed + sprintf((*result), "signed "); + (*result) += 7; + demangle_rec(in, result); + break; + case 't': // template + demangle_template(in, result); + break; + case 'U': // unsigned + sprintf((*result), "unsigned "); + (*result) += 9; + demangle_rec(in, result); + break; + case 'v': // void + break; + case 'x': // long long + break; + default: + ; + //instream.unget(); + } + } +} + +} diff --git a/AMDiS/src/demangle.h b/AMDiS/src/demangle.h new file mode 100644 index 0000000000000000000000000000000000000000..6dae3c805cab4dcb6b73d2f18139de7f2daef169 --- /dev/null +++ b/AMDiS/src/demangle.h @@ -0,0 +1,31 @@ +// ============================================================================ +// == == +// == AMDiS - Adaptive multidimensional simulations == +// == == +// ============================================================================ +// == == +// == crystal growth group == +// == == +// == Stiftung caesar == +// == Ludwig-Erhard-Allee 2 == +// == 53175 Bonn == +// == germany == +// == == +// ============================================================================ +// == == +// == http://www.caesar.de/cg/AMDiS == +// == == +// ============================================================================ + +/** \file demangle.h */ + +#ifndef AMDIS_DEMANGLE_H +#define AMDIS_DEMANGLE_H + +namespace AMDiS { + +void demangle(const char* in, char* result); + +} + +#endif