diff --git a/doc/README b/doc/README index 57a496e1..488cacad 100644 --- a/doc/README +++ b/doc/README @@ -1,73 +1,72 @@ - ## ##### ## ##### ## ## - /#### /##### /## /##### /## /#### - / ### // / / ### // / / ### / ### - /## / / / ### / / / ### /## - / ## / / ### / / ### / ## - / ## ## ## ## ## ## ## / ## - / ## ## ## ## ## ## ## / ## - / ## ## ## ## ## ## ## / ## - / ## ## ## ## ## ## ## / ## - /######## ## ## ## ## ## ## /######## - / ## # ## ## # ## ## / ## - # ## / / / / # ## - /#### ## /###/ / /###/ / /#### ## - / #### ## / / ########/ / ########/ / #### ## / - / ## #/ / #### / #### / ## #/ - # # # # - ## ## ## ## - - - - Maxim A. Yurkin - - Institute of Chemical Kinetics and Combustion, - Siberian Branch of the Russian Academy of Sciences, - Institutskaya 3, Novosibirsk, 630090, Russia, - tel: +7-383-333-3240, fax: +7-383-334-2350 - - Alfons G. Hoekstra - - Faculty of Science, Section Computational Science, - of the University of Amsterdam, + ADDA 0.74 + ********* + "Amsterdam DDA" + + Maxim A. Yurkin(1,2) and Alfons G. Hoekstra(1) + + (1) Faculty of Science, Section Computational Science, + of the University of Amsterdam, Kruislaan 403, 1098 SJ, Amsterdam, The Netherlands, tel: +31-20-525-7530, fax: +31-20-525-7490 - - email: adda@science.uva.nl - - $Date:: $ - - Copyright (C) 2006-2008 University of Amsterdam + (2) Institute of Chemical Kinetics and Combustion, + Siberian Branch of the Russian Academy of Sciences, + Institutskaya 3, Novosibirsk 630090 Russia, + tel: +7-3832-333240, fax: +7-3832-342350 + + email: myurkin@science.uva.nl, alfons@science.uva.nl + + last revised: 28 March 2006 + + Copyright (C) 2006 M.A. Yurkin and A.G. Hoekstra This software package is covered by the GNU General Public License. - - 1. INTRODUCTION - *************** - - ADDA is a C software package to calculate scattering and absorption of -electromagnetic waves by particles of arbitrary geometry using the Discrete -Dipole Approximation (DDA). In this approximation the volume of the scatterer + ## ##### ## ##### ## ## + /#### /##### /## /##### /## /#### + / ### // / / ### // / / ### / ### + /## / / / ### / / / ### /## + / ## / / ### / / ### / ## + / ## ## ## ## ## ## ## / ## + / ## ## ## ## ## ## ## / ## + / ## ## ## ## ## ## ## / ## + / ## ## ## ## ## ## ## / ## + /######## ## ## ## ## ## ## /######## + / ## # ## ## # ## ## / ## + # ## / / / / # ## + /#### ## /###/ / /###/ / /#### ## + / #### ## / / ########/ / ########/ / #### ## / + / ## #/ / #### / #### / ## #/ + # # # # + ## ## ## ## + + + 1. INTRODUCTION + *************** + + ADDA is a C software package to calculate scattering and absorption of +electromagnetic waves by particles of arbitrary geometry using the Discrete +Dipole Approximation (DDA). In this approximation the volume of the scatterer is divided into small cubical subvolumes ("dipoles"), interaction of which is considered approximately based on the integral equation for the electric field. Initially DDA (sometimes referred to as the "coupled dipole approximation") was proposed replacing the scatterer by a set of point dipoles (hence the name of -the technique). +the technique). ADDA is a C implementation of the DDA developed by the authors. The -development has been conducted by Hoekstra and coworkers for more than 10 years -at the University of Amsterdam. From the very beginning the code was intended to -run on a multiprocessor system (parallelizing a single DDA simulation). Recently -the code was significantly rewritten and improved by Yurkin. ADDA is intended to -be a versatile tool, suitable for a wide variety of applications ranging from +development was conducted by Hoekstra and coworkers for more than 10 years in +University of Amsterdam. From the very beginning the code was intended to run on +a multiprocessor system (parallelizing a single DDA simulation). Recently the +code was significantly rewritten and improved by Yurkin. ADDA is intended to be +a versatile tool, suitable for a wide variety of applications ranging from interstellar dust and atmospheric aerosols to biological particles; its applicability is limited only by available computer resources. As provided, ADDA should be usable for many applications without modification, but the program is written in a modular form, so that modifications, if required, should be fairly -straightforward. +straightforward. - Detailed instructions for using ADDA and all relevant issues are contained in -the User Manual for ADDA. The User Manual is in the file "manual.pdf" in PDF + Detailed instructions for using ADDA and all relevant issuse are contained in +the User Manual for ADDA. The User Manual is in the file "manual.pdf" in PDF format. It contains instructions for: * compiling and linking the code; * running a sample simulation; @@ -77,7 +76,6 @@ format. It contains instructions for: * specifying what scattering quantities should be calculated; * understanding the computational aspects and timing of the code; * understanding the command line options and formats of input and output files. -* modifying the source code for added functionality 2. AVAILABILITY @@ -86,11 +84,8 @@ format. It contains instructions for: The authors make this code openly available to others, in the hope that it will prove to be a useful tool. We ask only that: -* If you publish results obtained using ADDA, you should acknowledge the source - of the code. We recommend the following general reference: - M. A. Yurkin, V. P. Maltsev, and A.G. Hoekstra, "The discrete dipole - approximation for simulation of light scattering by particles much larger than - the wavelength", J. Quant. Spectros. Radiat. Transf. 106, 546-557 (2007). +* If you publish results obtained using ADDA, please consider acknowledging the + source of the code. * If you discover any errors in the code, please promptly communicate them to the authors. @@ -99,7 +94,7 @@ it will prove to be a useful tool. We ask only that: Public License) of the Free Software Foundation: you may copy, distribute, and/or modify the software identified as coming under this agreement. If you distribute copies of this software, you must give the recipients all the - rights which you have. See the file "copyleft" distributed with the ADDA + rights which you have. See the file "copyleft" distributed with the ADDA software. We also strongly encourage you to send email to the authors identifying @@ -110,50 +105,44 @@ bugs, corrections, or improvements in ADDA. 3. OBTAINING THE SOURCE CODE **************************** - The recent version can be downloaded from: -http://www.science.uva.nl/research/scs/Software/adda/ -The package contains the following: + We are currently working to make a www page for ADDA, where it will be +possible to download it. Currently, the latest version of ADDA can be obtained +by sending a request to the authors: adda@science.uva.nl. The package contains +the following: doc/ - documentation copyleft - GNU General Public License history - complete history of ADDA development - faq - frequently asked questions - manual.doc - source of User Manual in MS Word format - manual.pdf - user Manual for ADDA in PDF format + manual.pdf - User Manual for ADDA in PDF format. README - this file - todo.xls - source of the todo list in MS Excel format - todo.pdf - todo list in PDF format input/ - default input files tables/ - 10 auxiliary files with tables of integrals alldir_params.dat - parameters for integral scattering quantities avg_params.dat - parameters for orientation averaging scat_params.dat - parameters for grid of scattering angles -misc/ - additional files, not supported by the authors. sample/ - sample output and other files run000_sphere_g16m1_5/ - sample output directory, contains "log", "mueller", and "CrossSec-Y". - test.pbs - sample PBS script for MPI system - test.sge - sample SGE script for MPI system + batch - sample PBS script for MPI system stdout - stdout of a sample simulation src/ Makefile, make_seq, make_mpi - makefiles - ADDAmain.c, CalculateE.c, calculator.c, cmplx.h, const.h, crosssec.c/h, - comm.c/h, debug.c/h, fft.c, function.h, GenerateB.c, io.c/h, iterative.c, - make_particle.c, matvec.c, memory.c/h, os.h, param.c/h, parbas.h, - prec_time.c/h, Romberg.c/h, sinint.c, timing.c/h, types.h, vars.c/h + ADDAmain.c, CalculateE.c, calculator.c, cmplx.h, const.h, crosssec.c/h, + comm.c/h, debug.c/h, fft.c, GenerateB.c, io.c/h, iterative.c, make_particle.c, + matvec.c, memory.c/h, param.c/h, prec_time.c/h, Romberg.c/h, timing.c, + types.h, vars.c/h - source and header files of ADDA - cfft99D.f - source file for Temperton FFT - mt19937ar.c/h - source and header files for Mersenne Twister random generator. + cfft99D.f - source file for Temperton FFT - 4. COMPILING AND LINKING - ************************ + 4. COMPILING AND LINKING + ************************ - On Unix systems, while positioned in src/, type + On Unix systems, while positioned in src/, type > make seq -or +or > make mpi -for sequential and MPI versions respectively. By default you need FFTW to be +for sequential and MPI versions respectively. By default you need FFTW to be installed (www.fftw.org) on your system. Please read the User Manual (manual.pdf). diff --git a/doc/copyleft b/doc/copyleft index d511905c..3c68f02b 100644 --- a/doc/copyleft +++ b/doc/copyleft @@ -1,40 +1,37 @@ GNU GENERAL PUBLIC LICENSE - Version 2, June 1991 + Version 1, February 1989 - Copyright (C) 1989, 1991 Free Software Foundation, Inc., - 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA + Copyright (C) 1989 Free Software Foundation, Inc. + 675 Mass Ave, Cambridge, MA 02139, 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 + The license agreements of most software companies try to keep users +at the mercy of those companies. By contrast, our 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 Lesser General Public License instead.) You can apply it to -your programs, too. +software--to make sure the software is free for all its users. The +General Public License applies to the Free Software Foundation's +software and to any other program whose authors commit to using it. +You can use it for 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. +price. Specifically, the General Public License is designed to make +sure that you have the freedom to give away or sell copies of free +software, 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 + For example, if you distribute copies of a 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. +source code. And you must tell them 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, @@ -47,207 +44,120 @@ 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 + 0. This License Agreement 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 work containing the +Program or a portion of it, either verbatim or with modifications. Each +licensee is addressed as "you". + + 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 +General Public License and to the absence of any warranty; and give any +other recipients of the Program a copy of this General Public License +along with the Program. You may charge a fee for the physical act of +transferring a copy. + + 2. You may modify your copy or copies of the Program or any portion of +it, and copy and distribute such modifications under the terms of Paragraph +1 above, provided that you also do the following: + + a) cause the modified files to carry prominent notices stating that + you changed the files and the date of any change; and + + b) cause the whole of any work that you distribute or publish, that + in whole or in part contains the Program or any part thereof, either + with or without modifications, to be licensed at no charge to all + third parties under the terms of this General Public License (except + that you may choose to grant warranty protection to some or all + third parties, at your option). + + c) If the modified program normally reads commands interactively when + run, you must cause it, when started running for such interactive use + in the simplest and most usual 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 General + Public License. + + d) 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. + +Mere aggregation of another independent work with the Program (or its +derivative) on a volume of a storage or distribution medium does not bring +the other work under the scope of these terms. + + 3. You may copy and distribute the Program (or a portion or derivative of +it, under Paragraph 2) in object code or executable form under the terms of +Paragraphs 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 + Paragraphs 1 and 2 above; or, + + b) accompany it with a written offer, valid for at least three + years, to give any third party free (except for a nominal charge + for the cost of distribution) a complete machine-readable copy of the + corresponding source code, to be distributed under the terms of + Paragraphs 1 and 2 above; or, + + c) accompany it with the information you received as to where the + corresponding source code may be obtained. (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. + received the program in object code or executable form alone.) + +Source code for a work means the preferred form of the work for making +modifications to it. For an executable file, complete source code means +all the source code for all modules it contains; but, as a special +exception, it need not include source code for modules which are standard +libraries that accompany the operating system on which the executable +file runs, or for standard header files or definitions files that +accompany that operating system. + + 4. You may not copy, modify, sublicense, distribute or transfer the +Program except as expressly provided under this General Public License. +Any attempt otherwise to copy, modify, sublicense, distribute or transfer +the Program is void, and will automatically terminate your rights to use +the Program under this License. However, parties who have received +copies, or rights to use copies, from you under this General Public +License will not have their licenses terminated so long as such parties +remain in full compliance. + + 5. By copying, distributing or modifying 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. 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 +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. + + 7. 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 +specifies a version number of the 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 +the 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 + 8. 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 @@ -257,7 +167,7 @@ of promoting the sharing and reuse of software generally. NO WARRANTY - 11. BECAUSE THE PROGRAM IS LICENSED FREE OF CHARGE, THERE IS NO WARRANTY + 9. 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 @@ -267,7 +177,7 @@ 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 + 10. 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 @@ -278,62 +188,61 @@ 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 + + Appendix: 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. +possible use to humanity, 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. + 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. - Copyright (C) + Copyright (C) 19yy 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. + the Free Software Foundation; either version 1, 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. + 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., 675 Mass Ave, Cambridge, MA 02139, USA. Also add information on how to contact you by electronic and paper mail. If the program is interactive, make it output a short notice like this when it starts in an interactive mode: - Gnomovision version 69, Copyright (C) year name of author + Gnomovision version 69, Copyright (C) 19xx 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. +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: +necessary. Here 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. + Yoyodyne, Inc., hereby disclaims all copyright interest in the + program `Gnomovision' (a program to direct compilers to make passes + at assemblers) written by James Hacker. , 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 Lesser General -Public License instead of this License. +That's all there is to it! diff --git a/doc/faq b/doc/faq deleted file mode 100644 index 40fcc872..00000000 --- a/doc/faq +++ /dev/null @@ -1,84 +0,0 @@ - Frequently Asked Questions - about ADDA - - $Date:: $ - -Q: I have found a bug in ADDA. What should I do? -A: 1) Make sure you are using the latest version of ADDA (check the ADDA - homepage). If you have modified the code yourself, try the original release. - 2) Look at the list of known bugs at the ADDA homepage, maybe your bug is - already known. - 3) Try to understand how exactly the bug occurs, write down the sequence of - actions that lead to it. - 4) Please try to localize the bug, i.e. try to remove as much command line - parameters as possible without removing the bug. Also try to use defautl - versions of input files, that you have modified. - 5) Send the results of (3) and (4) to the authors, together with all input - - files and Makefiles that you have used for compilation. Do not forget to - include all the relevant output files, at least 'log'. Please also include - a brief description of your operation system and hardware. We will try to - fix the bug as soon as possible. - -Q: I do not understand how to ...? I run ADDA and get strange output or - something different from what I have expected. What should I do? -A: 1) Make sure you are using the latest version of ADDA (check the ADDA - homepage). Read carefully the relevant parts of the manual. - 2) Check the FAQ section of ADDA homepage. - 3) If that does not help, you're encouraged to send your question to the - authors. Please try to make your question as specific as possible. If your - question is based on a particular run, provide all relevant input and output - files, at least 'log'. - -Q: Can I use ADDA to calculate scattering by a particle near the infinite - dielectric plane surface? -A: Basically, no. ADDA can not rigorously solve such light scattering problem. - Such a rigorous solution requires a significant modification of the code, - therefore it will not be implemented in the near future. However, you may - approach this problem using the current version of ADDA. - 1) You may completely ignore the surface, this may be accurate enough if - particle is far from the surface and the refractive index change when - crossing the surface is small. - 2) A little more accurate approach is to consider the "incident field" in - ADDA as a sum of incident and reflected plane waves. However, currently - such incident field is not implemented, therefore it need first to be coded - into ADDA. - 3) Another approach is to take a large computational box around the - particle, and discretize the surface that falls into it. This is rigorous - in the limit of infinite size of computational box, but requires enormous - computational time. It also requires you to specify the shape files for all - different sizes of the computational box. - -Q: Can I calculate near-field using ADDA? -A: We are currently working to implement this feature in a convenient manner. - For now there are two possible workarounds: - 1) You may save dipole polarizations to file by ADDA and then compute the - near-field yourself, using a simple formula. - 2) Or you may extend the computational box with "dummy" dipoles located at - points where you wish to calculate near-field. Saving the internal fields - by ADDA will then produce the desired result, but at expense of extra - computational time. - Please see the manual for details. - -Q: How can I simulate light scattering by a particle which shape can not be - described by any of the ADDA predefined shapes? -A: The simplest is to specify your particle by a shape file. However, if your - shape can easily be described in some parametric form and you are going to - simulate a lot of particles with shapes from this class or if you think - other users will probably simulate the same shapes, you are encouraged to - implement new shape inside ADDA. There is an extensive instruction in the - appendix of the manual on how to do it. Afterwards, please send modified - source files to the authors so they would be incorporated in the next - release for the benefit of the community. - -Q: How is the Mueller matrix, produced by ADDA, defined and/or normalized? -A: It is defined as in Bohren & Huffman "Absorption and scattering of Light by - Small Particles" (1983), and it is not normalized. Some other codes may - compute Stokes scattering matrix, which is normalized so that 1,1-element - is equal to 1 after averaging over the whole solid angle. This matrix - should be multiplied by (pi*Csca/(lambda^2)) to get Mueller matrix. Csca is - the scattering cross section for unpolarized light, equal to average of - scattering cross sections for any two perpendicular incident polarizations. - -This list is far from being complete. Please send your questions to -adda@science.uva.nl diff --git a/doc/history b/doc/history index ee5ec513..9d3537bd 100644 --- a/doc/history +++ b/doc/history @@ -15,262 +15,25 @@ Ver. 0.74 - 29.03.06 + User manual improved. * 'buggy' beam type removed (obsolete). * '-nosym' and '-sym_enf' options combined to '-sym {no|enf}'. -- In documentation there was option '-pol ldr avg' while actually it was - '-pol ldr avgpol'. It is averaging over incident polarizations +- In documentation there was option '-pol ldr avg' while actually it was + '-pol ldr avgpol'. It is averaging over incident polarizations (not directions). Documentation corrected. -+ Internal fields are now automatically collected into one file, when running ++ Internal fields are now automatically collected into one file, when running in parallel mode ('IntField-X' and 'IntField-Y') - Saving of geometry in parallel mode could produce incomplete results (parts of some processors could be lost). Fixed. -+ MPI-specific command line options are enabled. Before they could cause ++ MPI-specific command line options are enabled. Before they could cause segmentation fault. -* Geometry filename given to the command line option '-save_geom' is now - specified relative to the output directory (i.e. if no path is given, it is +* Geometry filename given to the command line option '-save_geom' is now + specified relative to the output directory (i.e. if no path is given, it is saved into this directory). + Some warnings are now duplicated in the log. -+ In parallel mode each processor (except root) produces a separate logfile, if - any errors or warnings were detected (on this specific processor). These files ++ In parallel mode each processor (except root) produces a separate logfile, if + any errors or warnings were detected (on this specific processor). These files are named 'logerr.n' where n - is a number of processor. * Minor changes to output format to stdout. + Added source files 'param.c/h'. + Overall robustness of the code is improved (added many consistency checks). + Help system added (new command line option -h). -- Fixed small bug in file locking (it could fail unexpectedly under certain - circumstances). - ----------------------------------- -Ver. 0.74.2 - 05.04.06 - -+ Makefiles are more robust now. Option of using Intel compiler added. -+ Release option added to Makefiles (turns on/of all warnings automatically). -- A number of minor inaccuracies in the code fixed. -+ Section describing FFTW 3 installation added to the manual. - ----------------------------------- -Ver. 0.75 - 24.05.06 - -- Small bug in logging of command line fixed. -- Function 'system' (more precisely everything that calls 'fork') could fail - unexpectedly under certain MPI implementations. All system calls removed. -+ Added source file 'os.h'. -+ Checking of errors in stdout has been added. -+ Possible size of FFT-grid (and non-weird number of processors) has been - extended to full range of FFTW. One possible divisor of either 11 or 13 - has been added. -+ Increased robustness of makefiles with Intel compilers 8.1 and 9.0 in - conjunction with MPICH. -* Sample file 'batch' renamed to 'test.pbs' in 'sample/'. -+ Added sample script for SGE 'sample/test.sge'. -+ Different descriptions of Gaussian beam are now fully operational. Help, - references added. Evaluation of extinction crosssection is modified to be - compliant with Gaussian beams. -- Origin is now always in the center of the computational box (before it was - not so when jagged>1). -- When x_0=E_inc was used, more iterations than necessary to reach epsilon were - performed. Fixed. -* Progress reported in the first iteration after checkpoint loading was - incorrect in certain cases. To fix it required loss of checkpoint - compatibility (!!!) with earlier versions. Some additional information is - shown after checkpoint loading. -- Sometimes in parallel mode program could die of some error before producing an - error message. Fixed. -* Copyright statement changed in code description and output. Now it is with - University of Amsterdam. -+ Precision increased to 10 in ouput of several variables into log. -- Calculation of Csca or g caused both polarizations to be calculated even for - particles that are symmetric for 90 degree rotation over the z-axis. That is - not necessary - fixed. -+ Integration module significantly improved. It automatically uses trapezoid - rule for periodic function. Error estimates now seem to be reliable. -* Format of parameters for integration module changed because of improvement. - It affects parameter files alldir_params.dat, avg_params.dat, - scat_params.dat, making them incompatible with previous versions. -- Integration logs for Csca and g.x-g.z were saved in the same file for both - incident polarizations. Now suffix "-X" or "-Y" is added to file names. -+ www page of ADDA is now available at - http://www.science.uva.nl/research/scs/Software/adda/ - ----------------------------------- -Ver. 0.76 - 14.10.06 - -+ Makefiles modified to include new compiler 'compaq'. New variables added to - set path for FFTW3 header and library. -* Default dpl is now calculated based on the maximum absolute value among given - refractive indices, not the first one. dpl=10*max(|m|) -- Removed requirement of full set of refractive indices to be given for multi- - domain scatterers, if '-prognose' option is used. Produces information - message when relevant. -+ Added information about distribution of occupied dipoles among different - domains to the log file for multi-domain particles. -* GPL license changed to version 2 - file 'copyleft' replaced. -+ New option '-V' added to show version, compiler used, and copyright - information. A head with information and copyright is no more shown at every - run (redundant). -+ All memory allocation routines are now called by similar-typed macros - much - more cleaner. Robustness of memory handling improved. -+ Timing is now produced also when '-prognose' option is used. Communication - times are shown only in parallel mode. Redundant calls to calculate - communication timing in sequential mode removed. -* All timing in parallel mode is now done through MPI_Wtime, which measures - wall time. No more timer overflows in parallel runs. New header 'timing.h' for - this task. -+ Function attributes moved from 'const.h' to new header 'function.h'. Just for - convenience. -- Communication timing now measures exactly communication times (synchronization - before some communications is added for that). -- Memory requirement in the manual slightly corrected. The values produced by - the program itself were correct. -+ New option '-granul []' to granulate one of the - domains. When this option is used '_gran' is added to shapename. Currently it - may easily fail for volume fraction larger than 30-40%. Separate timing is - produced for granule generator. - Two files added - 'mt19937ar.c/h' - for a random generator (Mersenne Twister). - The header file slightly modified from the original. -- Bug in checkpointer fixed. Was not portable to systems where size_t!=int. -+ Added check if file system does not support file locking; error output of file - locking and file removal is now more informative (errno string is shown). -- Orientation averaging did not work in parallel (reported by Antti Penttila). - Fixed. -- Symmetries were not switched off by non-symmetric Gaussian beams. Fixed. - Improved hadling of symmetries. -+ Computation of scattering of a tightly focused Gaussian beam was compared to - multiple multipole method (data by Roman Schuh and Thomas Wriedt). Perfect - aggreement. Results of the comparison are added to the manual. -+ Added chapter to the manual to facilitate adding a new predefined shape. -+ New file 'doc/faq' added for frequently asked questions. -+ New option '-store_beam' to save incident electric fields to a file. -+ Starting from this release ADDA executable for WIN32 is available. It is - compiled with MinGW, and distributed with FFTW3 dll. Thanks to Alexander - Shvalov for information on MinGW. -- ADDA crashed when one of the given refractive indices was equal to one. Check - for this was added, now error message is produced in this case. -+ Added support for anisotropic refractive index (option '-anisotr'). Currently - it is limited to refractive index tensors that are diagonal in the particle - reference frame. Thanks to Michiel Min for fruitful discussions. - ----------------------------------- -Ver. 0.77 - (05.06.07) - -- Calculation of radiation forces gave segmentation fault. The bug was - introduced in version 0.76. Fixed. -+ Improved handling of large integers throughout the program. 'size_t' type is - used wherever possible, so it should work for any problem that would fit into - memory. Checks of integer overflow where necessary to avoid crashes. -+ Improved handling of input parameters to check for possible very large - numbers, etc. Overall robustness improved. -+ Added checks to indicate incompatibility of orientation averaging and - checkpoints with some other features. -- Consistency check for coated sphere was inaccurate. Fixed. -- Lack of EOL in the end of the input files could cause crash, as well - as EOL conversion in geometry files. Fixed. -+ Makefiles improved (overall clarity + more flexibility for MPI compiling), - included option for intel compilers without use of static linking. -+ Command line option '-store_dip_pol' was added to save dipole polarizations - to file. -- Computer name was not properly shown when running MPI version on Windows. - Fixed. -+ Improved the code that detects breakdowns of iterative solvers. Now it should - be much more sensitive. Thanks to Sorin Pulbere for reporting a test problem. -- A minor bug in Romberg integration for angles that are sampled uniformly - in their cos values, if both min and max values are exactly equal to 90 - degrees. Reported by Antti Penttila. Fixed. -+ Locking of files made more flexible. Added compile option to independently - turn off the advanced file locking. -- Minor change in comm.c to remove a warning. -+ Manual was significantly improved: "DDA formulation" section was rewritten to - be self-contained, sections "Near-field" and "Comparison with other DDA codes" - were added. Sections on compiling and running the code were extended to - discuss in detail multi-core PCs. Sections "Applicability of DDA" and "System - requirements" were extended to include recent benchmarking results and - discussion. Thanks to Vitezslav Karasek and Liviu Clime for their feedback. - ----------------------------------- -Ver. 0.78 - (19.03.08) - -* Makefiles were improved to enable automatic compilation of both sequential and - MPI versions from the same source folder. Name of MPI executable is now - adda_mpi. -+ New file parbas.h added. MPI version is now checked for conformity both during - compilation and at runtime. -+ Parallel executable for Win32, compiled with MPICH 2, is included in the - package. -+ sample/test.sge file was updated to run on DAS-3 cluster. -+ Added explicit description of the used notation for the Euler angles in the - manual, source code, help system, and parameter file. -+ sample/test.pbs was slightly improved. -+ File sinint.c added to calculate sine and cosine integrals. -+ Function cEqual was added to cmplx.h, it replaces memcpy calls in many other - files. -+ Filtered coupled dipoles implemented (both full and quasistatic version). New - arguments 'fcd' and 'fcd_st' for interaction term ('-int' command line option) - and 'fcd' for polarization term ('-pol' command line option). -+ To-do list added (both in xls and pdf format). -+ Hands-on tutorial was added to the manual. It is based on the one carried out - during the DDA Workshop in Bremen. -- ADDA was crashing for certain incorrect parameters given with the -h command - line option. Fixed. -+ A few explicit statements that angles are specified in degrees were added to - the help and input files. -+ New command line option '-opt {speed|mem}' added. It allows to choose whether - ADDA will optimize itself for maximum speed or for minimum memory usage. -+ Stability of complex arithmetics slightly improved. -+ Calculation of scattered fields is accelerated by more than 4 times (compiled - with gcc). Thanks to R. Scott Brock for this idea. This may also significantly - accelerate orientation averaging, depending on the problem. Intel compiler is - now only 10-20% faster than gcc, for all parts of the code. -- Minor bug in symmetry initialization of shape 'spherebox' is fixed. -- Information messages, when no real dipoles were allocated to one of the - processors, did not work. Fixed. -* Information messages ("INFO:...") are now given without references to source - files, which looks simpler. -+ New command line option '-eq_rad ' was added, it allows one to specify - volume-equivalent radius. -* Format of shape definitions in 'make_particle.c' was slightly changed. -* Shapes 'box' and 'spherebox' no longer depend on the second and third argument - of '-grid' option. -+ Shape 'box' now accepts two optional arguments (y/x and z/x aspect ratios) - defining a rectangular parallelepiped. -+ Automatic line wrapping was added for most output to stdout and sderr. ADDA - tries to get terminal width from COLUMNS environmental variables and, if - fails, uses the default value. -* '-pedantic' option for gcc was removed from Makefile, since it gave warnings - about long predefined strings. -- Shape 'line' was not working correcty in combination with '-jagged' or - explicitely specified grid sizes along y- and z-axes. Fixed. -+ Two new shapes were added: capsule and egg. They were implemented by Daniel - Hahn and Richard I. Joseph. -+ Description of predefined shapes in the manual was improved. -* Now, if grid size is auto-initialized from default dpl, ADDA ensures that it - is not smaller than 16. -+ Limitation on positiveness of dipole coordinates in shape file was removed. - Now ADDA automatically determines the minimum box around the particle and - centers it as usual. It also ignores blank lines in the middle or in the end - of shape file. -+ Orientation averaging was optimized. When beta=0 or 180, gamma angle is not - relevant but only combinations alpha+-gamma. If alpha is varied in a full - range [0,360), only one value of gamma for these specific beta values is - calculated, saving a few evaluations of internal fields. Thanks to Antti - Penttila for this idea. -+ Limited two-way compatibility with DDSCAT 6.1 geometry format was added, - corresponding to its shape option FRMFIL and output of 'calltarget' utility. - ADDA automatically detects DDSCAT format during reading of dipole file. When - saving geometry to the file, the format is determined by new command line - option '-sg_format {text|text_ext|ddscat}'. -+ New argument 'auto' was added to '-sym' command line option to correspond to - the general rule that one of the possible arguments is the default one. No - functionality is changed for other arguments. - ----------------------------------- -Ver. 0.78.1 - 08.04.08 - -- Critical bug in cDiv and cDivSelf functions in source file cmplx.h was fixed - (introduced in version 0.78). This bug made BiCGSTAB and BiCG iterative - solvers to fail. However, even when other two iterative solvers were used, - erroneous results were calculated for certain values of refractive index. - ----------------------------------- -Ver. 0.78.2 - 11.04.08 - -- An implementation of a new FCD polarization prescription (-pol fcd) was - somewhat faulty. Correction terms of orders (kd)^2 and ln(...)(kd)^3 were - interchanged. Fixed. +- Fixed small bug in file locking (it could fail unexpectedly under certain + circumstances). \ No newline at end of file diff --git a/doc/manual.doc b/doc/manual.doc deleted file mode 100644 index e83a8fa1..00000000 Binary files a/doc/manual.doc and /dev/null differ diff --git a/doc/manual.pdf b/doc/manual.pdf index b6f42ceb..17741105 100644 Binary files a/doc/manual.pdf and b/doc/manual.pdf differ diff --git a/doc/todo.pdf b/doc/todo.pdf deleted file mode 100644 index 2b3cfc37..00000000 Binary files a/doc/todo.pdf and /dev/null differ diff --git a/doc/todo.xls b/doc/todo.xls deleted file mode 100644 index 51610c5d..00000000 Binary files a/doc/todo.xls and /dev/null differ diff --git a/input/alldir_params.dat b/input/alldir_params.dat index de8a50e7..1eac2c33 100644 --- a/input/alldir_params.dat +++ b/input/alldir_params.dat @@ -2,45 +2,43 @@ # # This file should be manually modified by user. # Program does not assume any symmetries of the particle. -# Therefore, possible symmetries should be considered by user and this can lead -# to decrease of integration limits +# Therefore, possible symmetries should be considered by user and this can lead to +# decrease of integration limits theta: -# default: min=0;max=180;Jmin=2;Jmax=6;eps=0;equiv=false;periodic=false min=0 +# default max=180 +# xy - symmetry plane max=90 max=180 -Jmin=2 Jmax=6 +K=6 eps=0 equiv=false -periodic=false phi: -# default: min=0;max=360;Jmin=2;Jmax=5;eps=0;equiv=true;periodic=true -# axysymmmetrical: max=90;equiv=false;Jmax=3 -> discard values of g.x and g.y -# (consider them zero) min=0 +# default max=360 +# axysymmmetrical max=0 max=360 -Jmin=2 -Jmax=5 +Jmax=6 +K=6 eps=0 equiv=true -periodic=true -# all angles are specified in degrees -# all values are precalculated; so high 'eps' does not decrease computational -# time, but may decrease accuracy. If eps=0, Jmin is not used. +# all values are precalculated; so high 'eps' does not decrease computational time, +# but may decrease accuracy -# Jmin,Jmax are minimum and maximum numbers of refinement stages -# Nmax = 2^Jmax + 1 -# for those with equiv=true Nmax is effectively less by 1 -# total calls of function <= Nmax_theta * Nmax_phi +# K is maximum number of interpolation points +# interpolation starts with ROMB_KMIN (defined in Romberg.h). +# Jmax must be >= ROMB_KMIN # equiv means whether it is assumed that max and min values # are completely equivalent. If true only one of them is calculated. -# periodic means whether function is periodic in the integrated interval. -# If true trapezoid rule is used; it is possible that interval is half of the -# function period. +# interval of theta must be a subinterval of [0,180] + +# Nmax = 2^(Jmax-1) + 1 +# for those with equiv=true Nmax is effectively less by 1 +# total calls of calc_field <= Nmax_theta * Nmax_phi # axysymmetrical <=> particle with z - axis of symmetry diff --git a/input/avg_params.dat b/input/avg_params.dat index b8079fe2..f7696ccd 100644 --- a/input/avg_params.dat +++ b/input/avg_params.dat @@ -2,62 +2,53 @@ # # This file should be manually modified by user. # Program does not assume any symmetries of the particle. -# Therefore, possible symmetries should be considered by user and this can lead -# to decrease of integration limits. -# Here zyz-notation (or y-convention) is used for the Euler angles. +# Therefore, possible symmetries should be considered by user and this can lead to +# decrease of integration limits alpha: # calculation for alpha is cheap but only precalculated, therefore -# Jmax should be rather large. -# Jmin and eps are really not used; -# Do not change the range from default unless you have a good reason; -# using only one value of gamma for beta=0,pi is done only when full -# range is specified here to avoid possible inaccuracies. -# default: min=0;max=360;Jmax=5;equiv=true;periodic=true +# Jmax should be rather large +# K is actually how many interpolation points used +# eps is really not used min=0 +# default max=360 max=360 -Jmin=2 Jmax=5 +K=5 eps=0 equiv=true -periodic=true beta: -# default: min=0;max=180;Jmin=2;Jmax=4;eps=1e-3;equiv=false;periodic=false -# xy - symmetry plane: max=90;Jmax=3 -# Do not use periodic=true since the function is multiplied by sin(beta) before -# integration. min=0 +# default max=180 +# xy - symmetry plane max=90 max=180 -Jmin=2 Jmax=4 -eps=1e-3 +K=4 +eps=0 equiv=false -periodic=false gamma: -# default: min=0;max=360;Jmin=2;Jmax=4;eps=1e-3;equiv=true;periodic=true -# axysymmetrical: max=0 -# more precisely: max=45;Jmax=2;equiv=false min=0 +# default max=360 +# axysymmmetrical max=0 max=360 -Jmin=2 Jmax=4 -eps=1e-3 +K=4 +eps=0 equiv=true -periodic=true -# all angles are specified in degrees -# Jmin,Jmax are minimum and maximum numbers of refinement stages -# Nmax = 2^Jmax + 1 -# for those with equiv=true Nmax is effectively less by 1 -# total calls of function <= Nmax_theta * Nmax_phi +# K is maximum number of interpolation points (except for alpha), +# interpolation starts with ROMB_KMIN (defined in Romberg.h). +# Jmax must be >= ROMB_KMIN # equiv means whether it is assumed that max and min values # are completely equivalent. If true only one of them is calculated. -# periodic means whether function is periodic in the integrated interval. -# If true trapezoid rule is used; it is possible that interval is half of the -# function period. +# interval of beta must be a subinterval of [0,180] + +# Nmax = 2^(Jmax-1) + 1 +# for those with equiv=true Nmax is effectively less by 1 +# total calls for single orientation <= Nmax_beta * Nmax_gamma -# axysymmetrical <=> particle with z - axis of symmetry +# axysymmetrical <=> particle with z - axis of symmetry \ No newline at end of file diff --git a/input/scat_params.dat b/input/scat_params.dat index c5e4c61d..5f6ba826 100644 --- a/input/scat_params.dat +++ b/input/scat_params.dat @@ -39,33 +39,24 @@ values= 90 phi_integr: -# default: min=0;max=360;Jmin=2;Jmax=5;eps=0;equiv=true;periodic=true -# axysymmetrical: max=0 -# more precisely: max=45;Jmax=3;equiv=false -# then discard values of some Mueller matrix elements integrated with -# cos/sin multipliers (those that should be =0). -# xz - symmetry plane: min=-90;max=90;Jmax=5;equiv=false min=0 +# default max=360 +# axysymmmetrical max=0 max=360 -Jmin=2 -Jmax=5 +Jmax=7 +K=4 eps=0 equiv=true -periodic=true -# all angles are specified in degrees -# all values are precalculated; so high 'eps' does not decrease computational -# time, but may decrease accuracy -# Jmin,Jmax are minimum and maximum numbers of refinement stages -# Nmax = 2^Jmax + 1 -# for those with equiv=true Nmax is effectively less by 1 -# total calls of function <= Nmax_theta * Nmax_phi +# all values are precalculated; so high 'eps' does not decrease computational time, +# but may decrease accuracy +# K is maximum number of interpolation points +# interpolation starts with ROMB_KMIN (defined in Romberg.h). +# Jmax must be >= ROMB_KMIN # when equiv=true, it is assumed that max and min values -# are completely equivalent (together with values of cos/sin multipliers, -# when applicable). Only one of them is calculated. -# periodic means whether function is periodic in the integrated interval. -# If true trapezoid rule is used; it is possible that interval is half of the -# function period. +# are completely equivalent (together with values of cos/sin multipliers, when applicable). +# Only one of them is calculated. +# Nmax = 2^(Jmax-1) [+1] # axysymmetrical <=> particle with z - axis of symmetry # parameters that are not needed are just ignored (can be omitted) \ No newline at end of file diff --git a/sample/batch b/sample/batch new file mode 100644 index 00000000..3b197e50 --- /dev/null +++ b/sample/batch @@ -0,0 +1,41 @@ +# This is sample batch file to run ADDA +# it was designed for Dutch national compute cluster LISA +# +# job name (default is name of pbs script file) +#PBS -N ADDA +# +# request nodes, ppn - processor per node +#PBS -l nodes=2:ppn=2 +# +# max. wall clock time +#PBS -l walltime=0:05:00 +# +# Request that regular output and terminal output go to the same file +#PBS -j oe +# +# send me mail when job begins (b), ends (e), aborts (a) +#PBS -m bea +# +# specify e-mail address +#PBS -M myurkin@science.uva.nl +# +# shell to be used for this script +#PBS -S /bin/bash +# +# export all my environment variables to the job +#PBS -V +# +### + +# cd to the work directory +cd $PBS_O_WORKDIR +# echo number of processors assigned +n=`wc -l < $PBS_NODEFILE` +echo job running on $n processors +# echo names of the nodes +echo nodes: +cat $PBS_NODEFILE +# add the GNU environment for MPICH, using Infiniband: +module load gnu-mpich-ib +# run the program +mpiexec ./adda \ No newline at end of file diff --git a/sample/run000_sphere_g16m1_5/CrossSec-Y b/sample/run000_sphere_g16m1_5/CrossSec-Y index 5772d4af..c373ad93 100644 --- a/sample/run000_sphere_g16m1_5/CrossSec-Y +++ b/sample/run000_sphere_g16m1_5/CrossSec-Y @@ -1,4 +1,4 @@ Cext = 135.0449046 -Qext = 3.79114961 -Cabs = 0 -Qabs = 0 +Qext = 3.791149609 +Cabs = 1.36464414e-16 +Qabs = 3.830999855e-18 diff --git a/sample/run000_sphere_g16m1_5/log b/sample/run000_sphere_g16m1_5/log index ab02904e..cd181c87 100644 --- a/sample/run000_sphere_g16m1_5/log +++ b/sample/run000_sphere_g16m1_5/log @@ -1,30 +1,27 @@ -Generated by ADDA v.0.78.2 +Generated by ADDA v.0.74 The program was run on: dda command: './adda ' -lambda: 6.283185307 -shape: sphere; diameter:6.734551818 +lambda: 6.28319 +shape: sphere; diameter:6.73455 box dimensions: 16x16x16 refractive index: 1.5+0i Dipoles/lambda: 15 - (Volume correction used) -Required relative residual norm: 1e-05 + (Volume correction used) +Required relative error: 1e-05 Total number of occupied dipoles: 2176 -Volume-equivalent size parameter: 3.367275909 +Volume-equivalent size parameter: 3.36728 ----In laboratory reference frame:--- -Incident beam: Plane wave Incident propagation vector: (0,0,1) Incident polarization Y(par): (0,1,0) Incident polarization X(per): (1,0,0) -Particle orientation: default +Particle orientation (deg): alpha=0, beta=0, gamma=0 Polarization relation: 'Lattice Dispersion Relation' Scattering quantities formulae: 'by Draine' Interaction term prescription: 'as Point dipoles' FFT algorithm: FFTW3 Iterative Method: QMR (complex symmetric) -Optimization is done for maximum speed The FFT grid is: 32x32x32 Memory usage for MatVec matrices: 1.3 Mb Total memory usage: 2.2 Mb @@ -48,14 +45,14 @@ RE_011 = 2.4111231314E-02 + progress = 0.193557 RE_012 = 3.8307716444E-03 + progress = 0.841121 RE_013 = 3.0434605426E-03 + progress = 0.205523 RE_014 = 1.3101400518E-03 + progress = 0.569523 -RE_015 = 8.2588869902E-04 + progress = 0.369618 -RE_016 = 5.0452779281E-04 + progress = 0.389109 -RE_017 = 1.1339755335E-04 + progress = 0.775240 -RE_018 = 9.3640503439E-05 + progress = 0.174228 -RE_019 = 6.8748633527E-05 + progress = 0.265824 -RE_020 = 2.2386152530E-05 + progress = 0.674377 -RE_021 = 1.5169835168E-05 + progress = 0.322356 -RE_022 = 3.1682277704E-06 + progress = 0.791149 +RE_015 = 8.2588869898E-04 + progress = 0.369618 +RE_016 = 5.0452779301E-04 + progress = 0.389109 +RE_017 = 1.1339755205E-04 + progress = 0.775240 +RE_018 = 9.3640501846E-05 + progress = 0.174228 +RE_019 = 6.8748640198E-05 + progress = 0.265824 +RE_020 = 2.2386150971E-05 + progress = 0.674377 +RE_021 = 1.5169802499E-05 + progress = 0.322358 +RE_022 = 3.1681098360E-06 + progress = 0.791157 ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ Timing Results @@ -63,19 +60,22 @@ RE_022 = 3.1682277704E-06 + progress = 0.791149 Total number of iterations: 22 Total planes of E field calculation (each 181 points): 2 -Total wall time: 1 ---Everything below is processor times-- -Total time: 0.6300 - Initialization time: 0.2100 - init Dmatrix 0.0100 - FFT setup: 0.2000 - make particle: 0.0000 - Internal fields: 0.3700 - one solution: 0.3700 - init solver: 0.0200 - one iteration: 0.0200 - Scattered fields: 0.0300 - one plane: 0.0200 - Other sc.quantities: 0.0100 - File I/O: 0.0100 -Integration: 0.0000 +total time: 0.5800 +Wall time: 0.0 +Initialization time: 0.0800 + init Dmatrix 0.0200 + FFT setup: 0.0600 + make particle: 0.0000 +Internal fields: 0.3700 + one solution: 0.3700 + init solver: 0.0100 + one iteration: 0.0200 + calculation: 0.0200 + communication: 0.0000 +E field calculation: 0.1100 + one plane: 0.0500 + calculation: 0.0500 + communication: 0.0000 +Other scat.quantities: 0.0000 +file io: 0.0100 +Integration: 0.0000 diff --git a/sample/run000_sphere_g16m1_5/mueller b/sample/run000_sphere_g16m1_5/mueller index 8a6212e8..ff4322be 100644 --- a/sample/run000_sphere_g16m1_5/mueller +++ b/sample/run000_sphere_g16m1_5/mueller @@ -1,182 +1,182 @@ theta s11 s12 s13 s14 s21 s22 s23 s24 s31 s32 s33 s34 s41 s42 s43 s44 -0.00 1.4154797789E+02 0.0000000000E+00 0.0000000000E+00 3.5749017610E-12 0.0000000000E+00 1.4154797789E+02 2.4833453038E-11 0.0000000000E+00 0.0000000000E+00 -2.4833453038E-11 1.4154797789E+02 0.0000000000E+00 3.5749017610E-12 0.0000000000E+00 0.0000000000E+00 1.4154797789E+02 -1.00 1.4140075333E+02 -5.8903788370E-03 -2.5905502680E-12 6.1574667152E-12 -5.8903788370E-03 1.4140075333E+02 2.7406571296E-11 -2.5823155380E-12 -2.5889752434E-12 -2.7406281619E-11 1.4140075286E+02 9.9513430584E-03 6.1575413674E-12 2.5839878114E-12 -9.9513430584E-03 1.4140075286E+02 -2.00 1.4095992069E+02 -2.3466973151E-02 -5.1674411963E-12 8.7382127259E-12 -2.3466973151E-02 1.4095992069E+02 2.9938675024E-11 -5.1562086803E-12 -5.1599956563E-12 -2.9936361936E-11 1.4095991314E+02 3.9706967217E-02 8.7388083073E-12 5.1631869880E-12 -3.9706967217E-02 1.4095991314E+02 -3.00 1.4022799582E+02 -5.2447619491E-02 -7.7202012859E-12 1.1311565239E-11 -5.2447619491E-02 1.4022799582E+02 3.2418388739E-11 -7.7152769005E-12 -7.7009000507E-12 -3.2410604444E-11 1.4022795779E+02 8.8972730354E-02 1.1313568780E-11 7.7316123645E-12 -8.8972730354E-02 1.4022795779E+02 -4.00 1.3920914780E+02 -9.2366898463E-02 -1.0238134096E-11 1.3870818725E-11 -9.2366898463E-02 1.3920914780E+02 3.4835541767E-11 -1.0253521783E-11 -1.0199354112E-11 -3.4817161269E-11 1.3920902833E+02 1.5726195874E-01 1.3875549320E-11 1.0283659451E-11 -1.5726195874E-01 1.3920902833E+02 -5.00 1.3790916316E+02 -1.4258333019E-01 -1.2710426378E-11 1.6409266712E-11 -1.4258333019E-01 1.3790916316E+02 3.7180333056E-11 -1.2764955283E-11 -1.2642975367E-11 -3.7144607953E-11 1.3790887377E+02 2.4390074516E-01 1.6418463436E-11 1.2813709243E-11 -2.4390074516E-01 1.3790887377E+02 -6.00 1.3633539636E+02 -2.0228928127E-01 -1.5127685863E-11 1.8921948960E-11 -2.0228928127E-01 1.3633539636E+02 3.9441520952E-11 -1.5242415826E-11 -1.5020885435E-11 -3.9380150955E-11 1.3633480206E+02 3.4803527390E-01 1.8937760521E-11 1.5314936068E-11 -3.4803527390E-01 1.3633480206E+02 -7.00 1.3449670714E+02 -2.7052342025E-01 -1.7479147239E-11 2.1401254117E-11 -2.7052342025E-01 1.3449670714E+02 4.1610532167E-11 -1.7681429084E-11 -1.7320935377E-11 -4.1513747215E-11 1.3449561860E+02 4.6864108165E-01 2.1426216694E-11 1.7783177780E-11 -4.6864108165E-01 1.3449561860E+02 -8.00 1.3240338522E+02 -3.4618551692E-01 -1.9755216752E-11 2.3842007127E-11 -3.4618551692E-01 1.3240338522E+02 4.3678609286E-11 -2.0074763991E-11 -1.9532255725E-11 -4.3535276744E-11 1.3240155253E+02 6.0453413972E-01 2.3879030997E-11 2.0211481379E-11 -6.0453413972E-01 1.3240155253E+02 -9.00 1.3006706346E+02 -4.2805334300E-01 -2.1946798039E-11 2.6237583906E-11 -4.2805334300E-01 1.3006706346E+02 4.5635800073E-11 -2.2418013011E-11 -2.1644610470E-11 -4.5433528936E-11 1.3006417137E+02 7.5438362075E-01 2.6289928189E-11 2.2595679615E-11 -7.5438362075E-01 1.3006417137E+02 -10.00 1.2750062014E+02 -5.1480139799E-01 -2.4044931971E-11 2.8582174228E-11 -5.1480139799E-01 1.2750062014E+02 4.7474418148E-11 -2.4704522121E-11 -2.3648034042E-11 -4.7199696940E-11 1.2749628516E+02 9.1672619285E-01 2.8653429268E-11 2.4929329839E-11 -9.1672619285E-01 1.2749628516E+02 -11.00 1.2471807163E+02 -6.0502115559E-01 -2.6042060358E-11 3.0870243750E-11 -6.0502115559E-01 1.2471807163E+02 4.9185770380E-11 -2.6929289549E-11 -2.5534115778E-11 -4.8824094074E-11 1.2471184098E+02 1.0899816662E+00 3.0964310759E-11 2.7207595149E-11 -1.0899816662E+00 1.2471184098E+02 -12.00 1.2173445652E+02 -6.9724250229E-01 -2.7929596400E-11 3.3095229081E-11 -6.9724250229E-01 1.2173445652E+02 5.0763428888E-11 -2.9087861107E-11 -2.7293579981E-11 -5.0299446479E-11 1.2172580901E+02 1.2724698007E+00 3.3216281098E-11 2.9426167867E-11 -1.2724698007E+00 1.2172580901E+02 -13.00 1.1856571241E+02 -7.8995602266E-01 -2.9698210199E-11 3.5254644255E-11 -7.8995602266E-01 1.1856571241E+02 5.2202114221E-11 -3.1171766726E-11 -2.8916527161E-11 -5.1619842445E-11 1.1855406122E+02 1.4624280725E+00 3.5407104444E-11 3.1576678002E-11 -1.4624280725E+00 1.1855406122E+02 -14.00 1.1522854673E+02 -8.8163577391E-01 -3.1343396869E-11 3.7339548575E-11 -8.8163577391E-01 1.1522854673E+02 5.3493319964E-11 -3.3179867033E-11 -3.0398152594E-11 -5.2776206835E-11 1.1521324418E+02 1.6580301824E+00 3.7528067586E-11 3.3658044683E-11 -1.6580301824E+00 1.1521324418E+02 -15.00 1.1174030293E+02 -9.7076218725E-01 -3.2858849386E-11 3.9347453945E-11 -9.7076218725E-01 1.1174030293E+02 5.4632711946E-11 -3.5105075652E-11 -3.1731932945E-11 -5.3763890571E-11 1.1172064700E+02 1.8574050885E+00 3.9576899309E-11 3.5663202803E-11 -1.8574050885E+00 1.1172064700E+02 -16.00 1.0811882336E+02 -1.0558447343E+00 -3.4240063741E-11 4.1270618889E-11 -1.0558447343E+00 1.0811882336E+02 5.5613173095E-11 -3.6945676097E-11 -3.2913439777E-11 -5.4575548308E-11 1.0809406593E+02 2.0586563345E+00 4.1546030103E-11 3.7590407256E-11 -2.0586563345E+00 1.0809406593E+02 -17.00 1.0438231032E+02 -1.1354440038E+00 -3.5478493296E-11 4.3107815394E-11 -1.1354440038E+00 1.0438231032E+02 5.6434821503E-11 -3.8693945569E-11 -3.3934216457E-11 -5.5211400783E-11 1.0435166703E+02 2.2598814475E+00 4.3434340732E-11 3.9431934928E-11 -2.2598814475E+00 1.0435166703E+02 -18.00 1.0054918664E+02 -1.2081928470E+00 -3.6570922334E-11 4.4852724710E-11 -1.2081928470E+00 1.0054918664E+02 5.7092577732E-11 -4.0347921889E-11 -3.4791466713E-11 -5.5666511341E-11 1.0051184797E+02 2.4591911807E+00 4.5235620252E-11 4.1185737449E-11 -2.4591911807E+00 1.0051184797E+02 -19.00 9.6637957129E+01 -1.2728162689E+00 -3.7516071620E-11 4.6501054309E-11 -1.2728162689E+00 9.6637957129E+01 5.7581955121E-11 -4.1904165317E-11 -3.5484492371E-11 -5.5936718215E-11 9.6593100758E+01 2.6547283798E+00 4.6945716027E-11 4.2848219944E-11 -2.6547283798E+00 9.6593100758E+01 -20.00 9.2667072328E+01 -1.3281497661E+00 -3.8309284218E-11 4.8048334910E-11 -1.3281497661E+00 9.2667072328E+01 5.7902529178E-11 -4.3359302906E-11 -3.6009371893E-11 -5.6022145610E-11 9.2613876239E+01 2.8446862593E+00 4.8560177225E-11 4.4415911185E-11 -2.8446862593E+00 9.2613876239E+01 -21.00 8.8654795770E+01 -1.3731558411E+00 -3.8945941605E-11 4.9492693486E-11 -1.3731558411E+00 8.8654795770E+01 5.8055432238E-11 -4.4708877951E-11 -3.6362303720E-11 -5.5924708848E-11 8.8592452015E+01 3.0273258868E+00 5.0077098202E-11 4.5884242834E-11 -3.0273258868E+00 8.8592452015E+01 -22.00 8.4619076012E+01 -1.4069384560E+00 -3.9429775765E-11 5.0827453999E-11 -1.4069384560E+00 8.4619076012E+01 5.8034882164E-11 -4.5953072546E-11 -3.6548285591E-11 -5.5639312504E-11 8.4546804761E+01 3.2009926846E+00 5.1489939279E-11 4.7253074586E-11 -3.2009926846E+00 8.4546804761E+01 -23.00 8.0577424585E+01 -1.4287552243E+00 -3.9755708940E-11 5.2053986626E-11 -1.4287552243E+00 8.0577424585E+01 5.7845387070E-11 -4.7085389849E-11 -3.6563245039E-11 -5.5171699340E-11 8.0494488188E+01 3.3641317733E+00 5.2799966247E-11 4.8515767960E-11 -3.3641317733E+00 8.0494488188E+01 -24.00 7.6546800901E+01 -1.4380271804E+00 -3.9925944799E-11 5.3167062482E-11 -1.4380271804E+00 7.6546800901E+01 5.7485329882E-11 -4.8105367649E-11 -3.6410895437E-11 -5.4521330702E-11 7.6452517668E+01 3.5153019993E+00 5.4001975861E-11 4.9671552715E-11 -3.5153019993E+00 7.6452517668E+01 -25.00 7.2543505095E+01 -1.4343460064E+00 -3.9939228739E-11 5.4166233441E-11 -1.4343460064E+00 7.2543505095E+01 5.6958296001E-11 -4.9009767515E-11 -3.6091367385E-11 -5.3693209407E-11 7.2437262488E+01 3.6531885071E+00 5.5095401162E-11 5.0716972014E-11 -3.6531885071E+00 7.2437262488E+01 -26.00 6.8583079622E+01 -1.4174786400E+00 -3.9797764021E-11 5.5045705126E-11 -1.4174786400E+00 6.8583079622E+01 5.6265985260E-11 -4.9800579096E-11 -3.5608698348E-11 -5.2690281849E-11 6.8464346585E+01 3.7766137382E+00 5.6074339583E-11 5.1653772931E-11 -3.7766137382E+00 6.8464346585E+01 -27.00 6.4680220338E+01 -1.3873692293E+00 -3.9503063068E-11 5.5805777792E-11 -1.3873692293E+00 6.4680220338E+01 5.5411788843E-11 -5.0473945757E-11 -3.4966047327E-11 -5.1517633312E-11 6.4548558513E+01 3.8845467581E+00 5.6939013588E-11 5.2477784903E-11 -3.8845467581E+00 6.4548558513E+01 -28.00 6.0848697688E+01 -1.3441384465E+00 -3.9057971687E-11 5.6446328449E-11 -1.3441384465E+00 6.0848697688E+01 5.4399157626E-11 -5.1028370524E-11 -3.4168026142E-11 -5.0180416712E-11 6.0703771257E+01 3.9761108385E+00 5.7689203937E-11 5.3187158611E-11 -3.9761108385E+00 6.0703771257E+01 -29.00 5.7101288435E+01 -1.2880802112E+00 -3.8466152997E-11 5.6964013998E-11 -1.2880802112E+00 5.7101288435E+01 5.3232439835E-11 -5.1464999898E-11 -3.3220366629E-11 -4.8684609988E-11 5.6942872400E+01 4.0505892419E+00 5.8321427520E-11 5.3782761787E-11 -4.0505892419E+00 5.6942872400E+01 -30.00 5.3449718316E+01 -1.2196559178E+00 -3.7729148731E-11 5.7360122084E-11 -1.2196559178E+00 5.3449718316E+01 5.1918754634E-11 -5.1781725087E-11 -3.2126418434E-11 -4.7039333958E-11 5.3277705028E+01 4.1074291802E+00 5.8836683514E-11 5.4262279858E-11 -4.1074291802E+00 5.3277705028E+01 -31.00 4.9904615804E+01 -1.1394862984E+00 -3.6856270927E-11 5.7632138760E-11 -1.1394862984E+00 4.9904615804E+01 5.0458822427E-11 -5.1980851832E-11 -3.0897793274E-11 -4.5246922375E-11 4.9719019607E+01 4.1462439429E+00 5.9232625378E-11 5.4627347978E-11 -4.1462439429E+00 4.9719019607E+01 -32.00 4.6475477089E+01 -1.0483410890E+00 -3.5847016314E-11 5.7781363871E-11 -1.0483410890E+00 4.6475477089E+01 4.8864793530E-11 -5.2061144267E-11 -2.9535837553E-11 -4.3321682066E-11 4.6276436977E+01 4.1668132119E+00 5.9509960449E-11 5.4876854459E-11 -4.1668132119E+00 4.6276436977E+01 -33.00 4.3170642217E+01 -9.4712669645E-01 -3.4711777027E-11 5.7807660266E-11 -9.4712669645E-01 4.3170642217E+01 4.7138506583E-11 -5.2023938745E-11 -2.8053161747E-11 -4.1267255790E-11 4.2958422446E+01 4.1690816022E+00 5.9668775809E-11 5.5011382875E-11 -4.1690816022E+00 4.2958422446E+01 -34.00 3.9997282245E+01 -8.3687209590E-01 -3.3451986094E-11 5.7712079712E-11 -8.3687209590E-01 3.9997282245E+01 4.5291954445E-11 -5.1869910936E-11 -2.6453158056E-11 -3.9097710603E-11 3.9772270888E+01 4.1531554882E+00 5.9709488185E-11 5.5031725902E-11 -4.1531554882E+00 3.9772270888E+01 -35.00 3.6961397116E+01 -7.1871320644E-01 -3.2077635348E-11 5.7494977838E-11 -7.1871320644E-01 3.6961397116E+01 4.3329686700E-11 -5.1600990071E-11 -2.4748004109E-11 -3.6819421954E-11 3.6724102582E+01 4.1192981977E+00 5.9632575060E-11 5.4939190406E-11 -4.1192981977E+00 3.6724102582E+01 -36.00 3.4067823897E+01 -5.9387601623E-01 -3.0596917588E-11 5.7158550338E-11 -5.9387601623E-01 3.4067823897E+01 4.1258617060E-11 -5.1218257457E-11 -2.2947831703E-11 -3.4441285727E-11 3.3818869487E+01 4.0679236684E+00 5.9440193910E-11 5.4734354893E-11 -4.0679236684E+00 3.3818869487E+01 -37.00 3.1320254873E+01 -4.6365873922E-01 -2.9013590091E-11 5.6703878697E-11 -4.6365873922E-01 3.1320254873E+01 3.9091206547E-11 -5.0724098873E-11 -2.1058384839E-11 -3.1977644014E-11 3.1060371476E+01 3.9995886845E+00 5.9132780832E-11 5.4419757357E-11 -3.9995886845E+00 3.1060371476E+01 -38.00 2.8721264945E+01 -3.2941329582E-01 -2.7337228861E-11 5.6133218776E-11 -3.2941329582E-01 2.8721264945E+01 3.6834424770E-11 -5.0120723919E-11 -1.9091134548E-11 -2.9437279735E-11 2.8451282021E+01 3.9149838186E+00 5.8712577432E-11 5.3997075950E-11 -3.9149838186E+00 2.8451282021E+01 -39.00 2.6272347671E+01 -1.9252641296E-01 -2.5576873532E-11 5.5449117771E-11 -1.9252641296E-01 2.6272347671E+01 3.4497210562E-11 -4.9410579753E-11 -1.7056890664E-11 -2.6830903550E-11 2.5993182694E+01 3.8149232236E+00 5.8182039676E-11 5.3468417609E-11 -3.8149232236E+00 2.5993182694E+01 -40.00 2.3973959233E+01 -5.4400638051E-02 -2.3738380437E-11 5.4653656546E-11 -5.4400638051E-02 2.3973959233E+01 3.2090974017E-11 -4.8597373578E-11 -1.4963317538E-11 -2.4171466466E-11 2.3686605802E+01 3.7003334223E+00 5.7542650104E-11 5.2837487772E-11 -3.7003334223E+00 2.3686605802E+01 -41.00 2.1825569554E+01 8.3564445098E-02 -2.1833618310E-11 5.3750250434E-11 8.3564445098E-02 2.1825569554E+01 2.9622783268E-11 -4.7683394428E-11 -1.2823791645E-11 -2.1467740853E-11 2.1531084408E+01 3.5722412556E+00 5.6798074831E-11 5.2105912542E-11 -3.5722412556E+00 2.1531084408E+01 -42.00 1.9825719751E+01 2.1999052082E-01 -1.9869814849E-11 5.2741199140E-11 2.1999052082E-01 1.9825719751E+01 2.7103975948E-11 -4.6673486615E-11 -1.0647180180E-11 -1.8732273935E-11 1.9525208915E+01 3.4317611526E+00 5.5950158697E-11 5.1278463837E-11 -3.4317611526E+00 1.9525208915E+01 -43.00 1.7972085047E+01 3.5353810429E-01 -1.7855044413E-11 5.1632848780E-11 3.5353810429E-01 1.7972085047E+01 2.4545815052E-11 -4.5568685567E-11 -8.4424485672E-12 -1.5978056910E-11 1.7666689405E+01 3.2800818907E+00 5.5004767254E-11 5.0356226154E-11 -3.2800818907E+00 1.7666689405E+01 -44.00 1.6261542294E+01 4.8292311889E-01 -1.5800897539E-11 5.0425808713E-11 4.8292311889E-01 1.6261542294E+01 2.1955974762E-11 -4.4375792508E-11 -6.2228538486E-12 -1.3213527050E-11 1.5952422820E+01 3.1184530133E+00 5.3962786985E-11 4.9345255427E-11 -3.1184530133E+00 1.5952422820E+01 -45.00 1.4690241190E+01 6.0693226741E-01 -1.3716420871E-11 4.9126294289E-11 6.0693226741E-01 1.4690241190E+01 1.9344625159E-11 -4.3097250689E-11 -3.9980487078E-12 -1.0450230777E-11 1.4378564141E+01 2.9481710728E+00 5.2830112106E-11 4.8247822362E-11 -2.9481710728E+00 1.4378564141E+01 -46.00 1.3253678319E+01 7.2443700151E-01 -1.1609581603E-11 4.7737248274E-11 7.2443700151E-01 1.3253678319E+01 1.6723364152E-11 -4.1738894916E-11 -1.7771791302E-12 -7.7003131756E-12 1.2940600636E+01 2.7705658607E+00 5.1609283289E-11 4.7069742551E-11 -2.7705658607E+00 1.2940600636E+01 -47.00 1.1946773127E+01 8.3440592188E-01 -9.4893912952E-12 4.6264502327E-11 8.3440592188E-01 1.1946773127E+01 1.4102585405E-11 -4.0304032782E-11 4.3026254855E-13 -4.9751009658E-12 1.1633428312E+01 2.5869867845E+00 5.0305751457E-11 4.5814270449E-11 -2.5869867845E+00 1.1633428312E+01 -48.00 1.0763944985E+01 9.3591547133E-01 -7.3662382582E-12 4.4711927907E-11 9.3591547133E-01 1.0763944985E+01 1.1490909458E-11 -3.8798589153E-11 2.6133069355E-12 -2.2836374694E-12 1.0451429692E+01 2.3987895399E+00 4.8923465375E-11 4.4486777750E-11 -2.3987895399E+00 1.0451429692E+01 -49.00 9.6991904995E+00 1.0281588143E+00 -5.2486206153E-12 4.3085646149E-11 1.0281588143E+00 9.6991904995E+00 8.8987719932E-12 -3.7226392912E-11 4.7633149212E-12 3.6307581076E-13 9.3885520716E+00 2.2073232198E+00 4.7468060545E-11 4.3091132111E-11 -2.2073232198E+00 9.3885520716E+00 -50.00 8.7461602923E+00 1.1104528279E+00 -3.1459583164E-12 4.1390264039E-11 1.1104528279E+00 8.7461602923E+00 6.3353975332E-12 -3.5593174375E-11 6.8706629623E-12 2.9556690265E-12 8.4383854322E+00 2.0139179905E+00 4.5944034713E-11 4.1632735544E-11 -2.0139179905E+00 8.4383854322E+00 -51.00 7.8982344984E+00 1.1822431623E+00 -1.0673657723E-12 3.9631001096E-11 1.1822431623E+00 7.8982344984E+00 3.8098516079E-12 -3.3904390076E-11 8.9263221792E-12 5.4850053084E-12 7.5942392583E+00 1.8198734530E+00 4.4356437185E-11 4.0116761862E-11 -1.8198734530E+00 7.5942392583E+00 -52.00 7.1485962931E+00 1.2431073592E+00 9.8014732704E-13 3.7813758530E-11 1.2431073592E+00 7.1485962931E+00 1.3326739277E-12 -3.2165239314E-11 1.0923364993E-11 7.9408910504E-12 6.8492175194E+00 1.6264477942E+00 4.2710551392E-11 3.8548553401E-11 -1.6264477942E+00 6.8492175194E+00 -53.00 6.4903028116E+00 1.2927560486E+00 2.9864015964E-12 3.5943716647E-11 1.2927560486E+00 6.4903028116E+00 -1.0890604164E-12 -3.0381560622E-11 1.2852223538E-11 1.0316289252E-11 6.1962911586E+00 1.4348478188E+00 4.1011721377E-11 3.6933332286E-11 -1.4348478188E+00 6.1962911586E+00 -54.00 5.9163528904E+00 1.3310322738E+00 4.9441377974E-12 3.4027214852E-11 1.3310322738E+00 5.9163528904E+00 -3.4463746993E-12 -2.8558490854E-11 1.4706263443E-11 1.2602719386E-11 5.6283674787E+00 1.2462199386E+00 3.9265745542E-11 3.5276245135E-11 -1.2462199386E+00 5.6283674787E+00 -55.00 5.4197511217E+00 1.3579090204E+00 6.8463172703E-12 3.2069687156E-11 1.3579090204E+00 5.4197511217E+00 -5.7305056726E-12 -2.6702108040E-11 1.6478966723E-11 1.4792265820E-11 5.1383558846E+00 1.0616421791E+00 3.7477744729E-11 3.3583194319E-11 -1.0616421791E+00 5.1383558846E+00 -56.00 4.9935677817E+00 1.3734850538E+00 8.6852427671E-12 3.0077359346E-11 1.3734850538E+00 4.9935677817E+00 -7.9341225991E-12 -2.4817798179E-11 1.8163652131E-11 1.6878244532E-11 4.7192295086E+00 8.8211725030E-01 3.5653645639E-11 3.1859346953E-11 -8.8211725030E-01 4.7192295086E+00 -57.00 4.6309942636E+00 1.3779791890E+00 1.0453371020E-11 2.8055816305E-11 1.3779791890E+00 4.6309942636E+00 -1.0050775587E-11 -2.2911733262E-11 1.9753990040E-11 1.8855020250E-11 4.3640823138E+00 7.0856671017E-01 3.3798903331E-11 3.0110430370E-11 -7.0856671017E-01 4.3640823138E+00 -58.00 4.3253937129E+00 1.3717231380E+00 1.2144343670E-11 2.6011923935E-11 1.3717231380E+00 4.3253937129E+00 -1.2073610548E-11 -2.0988826630E-11 2.1244919025E-11 2.0716711565E-11 4.0661813452E+00 5.4182623856E-01 3.1919780698E-11 2.8341391834E-11 -5.4182623856E-01 4.0661813452E+00 -59.00 4.0703466364E+00 1.3551530974E+00 1.3753249705E-11 2.3950990464E-11 1.3551530974E+00 4.0703466364E+00 -1.3995270929E-11 -1.9055429440E-11 2.2632448952E-11 2.2457540649E-11 3.8190138659E+00 3.8264201984E-01 3.0021292341E-11 2.6558233850E-11 -3.8264201984E-01 3.8190138659E+00 -60.00 3.8596913200E+00 1.3288002517E+00 1.5272694695E-11 2.1878908255E-11 1.3288002517E+00 3.8596913200E+00 -1.5811892647E-11 -1.7117441344E-11 2.3911190632E-11 2.4074405067E-11 3.6163291901E+00 2.3166822239E-01 2.8109174878E-11 2.4766402403E-11 -2.3166822239E-01 3.6163291901E+00 -61.00 3.6875589602E+00 1.2932803771E+00 1.6698861295E-11 1.9802123848E-11 1.2932803771E+00 3.6875589602E+00 -1.7517024599E-11 -1.5179967089E-11 2.5078534770E-11 2.5562573509E-11 3.4521750922E+00 8.9465547951E-02 2.6189224335E-11 2.2970953121E-11 -8.9465547951E-02 3.4521750922E+00 -62.00 3.5484034751E+00 1.2492827384E+00 1.8026679807E-11 1.7726293094E-11 1.2492827384E+00 3.5484034751E+00 -1.9106579162E-11 -1.3248844230E-11 2.6131204259E-11 2.6919299608E-11 3.3209287379E+00 -4.3499187623E-02 2.4266789484E-11 2.1177318184E-11 4.3499187623E-02 3.3209287379E+00 -63.00 3.4370260221E+00 1.1975584757E+00 1.9252762978E-11 1.5657681074E-11 1.1975584757E+00 3.4370260221E+00 -2.0575867643E-11 -1.1329167797E-11 2.7067323128E-11 2.8141653993E-11 3.2173221504E+00 -1.6685249201E-01 2.2347606230E-11 1.9390392192E-11 1.6685249201E-01 3.2173221504E+00 -64.00 3.3485943058E+00 1.1389086740E+00 2.0372270553E-11 1.3601056298E-11 1.1389086740E+00 3.3485943058E+00 -2.1922770062E-11 -9.4272797500E-12 2.7884269606E-11 2.9228680046E-11 3.1364622811E+00 -2.8031271200E-01 2.0436255833E-11 1.7615919435E-11 2.8031271200E-01 3.1364622811E+00 -65.00 3.2786568107E+00 1.0741723104E+00 2.1383486652E-11 1.1562617035E-11 1.0741723104E+00 3.2786568107E+00 -2.3143174501E-11 -7.5478128998E-12 2.8581765821E-11 3.0178299910E-11 3.0738458131E+00 -3.8368769522E-01 1.8538332770E-11 1.5858301466E-11 3.8368769522E-01 3.0738458131E+00 -66.00 3.2231521408E+00 1.0042142633E+00 2.2283740878E-11 9.5488103884E-12 1.0042142633E+00 3.2231521408E+00 -2.4235016464E-11 -5.6948499062E-12 2.9158950963E-11 3.0990155612E-11 3.0253688772E+00 -4.7687167342E-01 1.6659520850E-11 1.4121500008E-11 4.7687167342E-01 3.0253688772E+00 -67.00 3.1784136916E+00 9.2991356071E-01 2.3070757026E-11 7.5637390858E-12 9.2991356071E-01 3.1784136916E+00 -2.5197097516E-11 -3.8746531804E-12 2.9615642818E-11 3.1664502967E-11 2.9873319060E+00 -5.5984144864E-01 1.4803794883E-11 1.2411066678E-11 5.5984144864E-01 2.9873319060E+00 -68.00 3.1411699150E+00 8.5215203324E-01 2.3743104844E-11 5.6123080833E-12 8.5215203324E-01 3.1411699150E+00 -2.6028367919E-11 -2.0921996213E-12 2.9952320801E-11 3.2201888099E-11 2.9564398919E+00 -6.3265196781E-01 1.2975565736E-11 1.0731516041E-11 6.3265196781E-01 2.9564398919E+00 -69.00 3.1085404720E+00 7.7180352312E-01 2.4300517268E-11 3.6999435211E-12 7.7180352312E-01 3.1085404720E+00 -2.6727876055E-11 -3.5165071132E-13 3.0170369832E-11 3.2603190133E-11 2.9297983533E+00 -6.9543137458E-01 1.1179694727E-11 9.0866428447E-12 6.9543137458E-01 2.9297983533E+00 -70.00 3.0780285915E+00 6.8972378446E-01 2.4742508514E-11 1.8320542101E-12 6.8972378446E-01 3.0780285915E+00 -2.7295932010E-11 1.3433871905E-12 3.0271029341E-11 3.2870424292E-11 2.9049053392E+00 -7.4837562875E-01 9.4208404622E-12 7.4797795764E-12 7.4837562875E-01 2.9049053392E+00 -71.00 3.0475099779E+00 6.0674119351E-01 2.5069464636E-11 1.2314874163E-14 6.0674119351E-01 3.0475099779E+00 -2.7733237672E-11 2.9877772781E-12 3.0256568763E-11 3.3005697866E-11 2.8796398306E+00 -7.9174278363E-01 7.7024014914E-12 5.9153974043E-12 7.9174278363E-01 2.8796398306E+00 -72.00 3.0152186234E+00 5.2364836850E-01 2.5282654013E-11 -1.7543974723E-12 5.2364836850E-01 3.0152186234E+00 -2.8040462380E-11 4.5783585956E-12 3.0129696872E-11 3.3011441305E-11 2.8522469120E+00 -8.2584701129E-01 6.0286429273E-12 4.3961694240E-12 8.2584701129E-01 2.8522469120E+00 -73.00 2.9797298944E+00 4.4119477955E-01 2.5382375637E-11 -3.4646843444E-12 4.4119477955E-01 2.9797298944E+00 -2.8220477233E-11 6.1105957729E-12 2.9892646448E-11 3.2891543968E-11 2.8213201016E+00 -8.5105246271E-01 4.4023448099E-12 2.9262556735E-12 8.5105246271E-01 2.8213201016E+00 -74.00 2.9399412647E+00 3.6008040918E-01 2.5371385207E-11 -5.1143276858E-12 3.6008040918E-01 2.9399412647E+00 -2.8274778295E-11 7.5817010678E-12 2.9549400617E-11 3.2649175197E-11 2.7857812353E+00 -8.6776704713E-01 2.8272683404E-12 1.5078546967E-12 8.6776704713E-01 2.7857812353E+00 -75.00 2.8950510724E+00 2.8095050402E-01 2.5252009473E-11 -6.6995609452E-12 2.8095050402E-01 2.8950510724E+00 -2.8205969343E-11 8.9886582006E-12 2.9103568236E-11 3.2288216843E-11 2.7448583016E+00 -8.7643621019E-01 1.3066182305E-12 1.4342919474E-13 8.7643621019E-01 2.7448583016E+00 -76.00 2.8445356718E+00 2.0439143844E-01 2.5026704463E-11 -8.2174777603E-12 2.0439143844E-01 2.8445356718E+00 -2.8018008773E-11 1.0328275366E-11 2.8559023581E-11 3.1813619557E-11 2.6980616224E+00 -8.7753678538E-01 -1.5727066029E-13 -1.1642092762E-12 8.7753678538E-01 2.6980616224E+00 -77.00 2.7881253471E+00 1.3092769173E-01 2.4698750571E-11 -9.6653435212E-12 1.3092769173E-01 2.7881253471E+00 -2.7714410118E-11 1.1597759539E-11 2.7920195711E-11 3.1229877274E-11 2.6451587674E+00 -8.7157098731E-01 -1.5621839623E-12 -2.4128659373E-12 8.7157098731E-01 2.6451587674E+00 -78.00 2.7257793438E+00 6.1019921902E-02 2.4271995876E-11 -1.1040133687E-11 6.1019921902E-02 2.7257793438E+00 -2.7299225682E-11 1.2795158549E-11 2.7191784898E-11 3.0542058060E-11 2.5861485787E+00 -8.5906060859E-01 -2.9056090241E-12 -3.6010954902E-12 8.5906060859E-01 2.5861485787E+00 -79.00 2.6576603570E+00 -4.9358979502E-03 2.3750499946E-11 -1.2339735477E-11 -4.9358979502E-03 2.6576603570E+00 -2.6777087625E-11 1.3918325618E-11 2.6378755617E-11 2.9755513512E-11 2.5212346655E+00 -8.4054147516E-01 -4.1859206294E-12 -4.7272598205E-12 8.4054147516E-01 2.5212346655E+00 -80.00 2.5841088034E+00 -6.6608330888E-02 2.3138724604E-11 -1.3561996186E-11 -6.6608330888E-02 2.5841088034E+00 -2.6153043302E-11 1.4965479541E-11 2.5486210562E-11 2.8875887876E-11 2.4507987132E+00 -8.1655820704E-01 -5.4014528612E-12 -5.7900480333E-12 8.1655820704E-01 2.4507987132E+00 -81.00 2.5056171822E+00 -1.2372937929E-01 2.2441553765E-11 -1.4705130750E-11 -1.2372937929E-01 2.5056171822E+00 -2.5432216205E-11 1.5935400275E-11 2.4519535689E-11 2.7908853538E-11 2.3753739271E+00 -7.8765932415E-01 -6.5508465856E-12 -6.7887784467E-12 7.8765932415E-01 2.3753739271E+00 -82.00 2.4228048079E+00 -1.7609251697E-01 2.1663926340E-11 -1.5767847323E-11 -1.7609251697E-01 2.4228048079E+00 -2.4620414131E-11 1.6826709499E-11 2.3484079756E-11 2.6860465434E-11 2.2956189087E+00 -7.5439272854E-01 -7.6332964527E-12 -7.7224895115E-12 7.5439272854E-01 2.2956189087E+00 -83.00 2.3363931765E+00 -2.2354993807E-01 2.0811355657E-11 -1.6748956390E-11 -2.2354993807E-01 2.3363931765E+00 -2.3723578026E-11 1.7638731095E-11 2.2385518718E-11 2.5736890753E-11 2.2122922352E+00 -7.1730158678E-01 -8.6479723511E-12 -8.5909401706E-12 7.1730158678E-01 2.2122922352E+00 -84.00 2.2471822016E+00 -2.6600911889E-01 1.9889490558E-11 -1.7647578797E-11 -2.6600911889E-01 2.2471822016E+00 -2.2747770876E-11 1.8370973567E-11 2.1229524041E-11 2.4544245259E-11 2.1262279884E+00 -6.7692062848E-01 -9.5943501060E-12 -9.3941017247E-12 6.7692062848E-01 2.1262279884E+00 -85.00 2.1560275310E+00 -3.0342879611E-01 1.8904059266E-11 -1.8463156453E-11 -3.0342879611E-01 2.1560275310E+00 -2.1699529656E-11 1.9023231300E-11 2.0021674068E-11 2.3288977570E-11 2.0383124467E+00 -6.3377286922E-01 -1.0472233373E-11 -1.0132124236E-11 6.3377286922E-01 2.0383124467E+00 -86.00 2.0638191280E+00 -3.3581446865E-01 1.7861102595E-11 -1.9195994689E-11 -3.3581446865E-01 2.0638191280E+00 -2.0585428506E-11 1.9595110358E-11 1.8767897462E-11 2.1977261831E-11 1.9494621289E+00 -5.8836675941E-01 -1.1282256839E-11 -1.0804919048E-11 5.8836675941E-01 1.9494621289E+00 -87.00 1.9714612752E+00 -3.6321353360E-01 1.6767115815E-11 -1.9845577355E-11 -3.6321353360E-01 1.9714612752E+00 -1.9412025005E-11 2.0087489007E-11 1.7474073072E-11 2.0615409964E-11 1.8606033456E+00 -5.4119375346E-01 -1.2023992236E-11 -1.1413820881E-11 5.4119375346E-01 1.8606033456E+00 -88.00 1.8798541335E+00 -3.8571016669E-01 1.5628166370E-11 -2.0412448008E-11 -3.8571016669E-01 1.8798541335E+00 -1.8186426035E-11 2.0500932756E-11 1.6145708097E-11 1.9210008812E-11 1.7726533885E+00 -4.9272628782E-01 -1.2698247668E-11 -1.1959584578E-11 4.9272628782E-01 1.7726533885E+00 -89.00 1.7898769591E+00 -4.0342005633E-01 1.4450172783E-11 -2.0897935559E-11 -4.0342005633E-01 1.7898769591E+00 -1.6915836489E-11 2.0835500874E-11 1.4788166122E-11 1.7767462344E-11 1.6865034552E+00 -4.4341615069E-01 -1.3306799134E-11 -1.2442285120E-11 4.4341615069E-01 1.6865034552E+00 -90.00 1.7023730595E+00 -4.1648509719E-01 1.3240505919E-11 -2.1302137967E-11 -4.1648509719E-01 1.7023730595E+00 -1.5606548752E-11 2.1093327719E-11 1.3407820921E-11 1.6293428062E-11 1.6030033827E+00 -3.9369322125E-01 -1.3849353763E-11 -1.2864650122E-11 3.9369322125E-01 1.6030033827E+00 -91.00 1.6181365418E+00 -4.2506814384E-01 1.2005159766E-11 -2.1626756068E-11 -4.2506814384E-01 1.6181365418E+00 -1.4266016154E-11 2.1275246840E-11 1.2009768138E-11 1.4794403570E-11 1.5229482355E+00 -3.4396455220E-01 -1.4327919730E-11 -1.3227408799E-11 3.4396455220E-01 1.5229482355E+00 -92.00 1.5379008847E+00 -4.2934791870E-01 1.0750702636E-11 -2.1873028644E-11 -4.2934791870E-01 1.5379008847E+00 -1.2901104578E-11 2.1383119056E-11 1.0599460288E-11 1.3276320272E-11 1.4470667659E+00 -2.9461376570E-01 -1.4743622087E-11 -1.3532611032E-11 2.9461376570E-01 1.4470667659E+00 -93.00 1.4623293397E+00 -4.2951416049E-01 9.4834051609E-12 -2.2043065828E-11 -4.2951416049E-01 1.4623293397E+00 -1.1518832386E-11 2.1418447870E-11 9.1820693570E-12 1.1745079030E-11 1.3760117457E+00 -2.4600073014E-01 -1.5098635269E-11 -1.3781654015E-11 2.4600073014E-01 1.3760117457E+00 -94.00 1.3920071496E+00 -4.2576309020E-01 8.2097282825E-12 -2.2138393060E-11 -4.2576309020E-01 1.3920071496E+00 -1.0126003332E-11 2.1383605233E-11 7.7627089441E-12 1.0206396727E-11 1.3103521416E+00 -1.9846148324E-01 -1.5394222823E-11 -1.3977039844E-11 1.9846148324E-01 1.3103521416E+00 -95.00 1.3274355494E+00 -4.1829326162E-01 6.9358145989E-12 -2.2161282433E-11 -4.1829326162E-01 1.3274355494E+00 -8.7294341785E-12 2.1280882316E-11 6.3461917681E-12 8.6659049130E-12 1.2505670901E+00 -1.5230836559E-01 -1.5632465068E-11 -1.4120949548E-11 1.5230836559E-01 1.2505670901E+00 -96.00 1.2690274980E+00 -4.0730185244E-01 5.6679026548E-12 -2.2114317771E-11 -4.0730185244E-01 1.2690274980E+00 -7.3356369534E-12 2.1112474043E-11 4.9374426456E-12 7.1287644641E-12 1.1970416083E+00 -1.0783032848E-01 -1.5815758927E-11 -1.4215387657E-11 1.0783032848E-01 1.1970416083E+00 -97.00 1.2171050709E+00 -3.9298144097E-01 4.4119710221E-12 -2.2000065567E-11 -3.9298144097E-01 1.2171050709E+00 -5.9509351728E-12 2.0880926002E-11 3.5410369105E-12 5.5999935297E-12 1.1500639614E+00 -6.5293379751E-02 -1.5946390219E-11 -1.4262703207E-11 6.5293379751E-02 1.1500639614E+00 -98.00 1.1718984324E+00 -3.7551730142E-01 3.1736884435E-12 -2.1821194699E-11 -3.7551730142E-01 1.1718984324E+00 -4.5816826703E-12 2.0589189576E-11 2.1611173706E-12 4.0846926037E-12 1.1098245952E+00 -2.4941132599E-02 -1.6026610254E-11 -1.4265611025E-11 2.4941132599E-02 1.1098245952E+00 -99.00 1.1335462889E+00 -3.5508523923E-01 1.9586568167E-12 -2.1580763001E-11 -3.5508523923E-01 1.1335462889E+00 -3.2337742699E-12 2.0240059060E-11 8.0184659533E-13 2.5874115762E-12 1.0764165286E+00 1.3004576361E-02 -1.6059094983E-11 -1.4226538916E-11 -1.3004576361E-02 1.0764165286E+00 -100.00 1.1020977174E+00 -3.3184997639E-01 7.7184538459E-13 -2.1281159005E-11 -3.3184997639E-01 1.1020977174E+00 -1.9133802094E-12 1.9837122607E-11 -5.3341150614E-13 1.1131167889E-12 1.0498370936E+00 4.8343031423E-02 -1.6045519317E-11 -1.4148963646E-11 -4.8343031423E-02 1.0498370936E+00 -101.00 1.0775152511E+00 -3.0596408518E-01 -3.8080087128E-13 -2.0926415607E-11 -3.0596408518E-01 1.0775152511E+00 -6.2499420251E-13 1.9382753699E-11 -1.8398386744E-12 -3.3529461705E-13 1.0299909029E+00 8.0893973462E-02 -1.5989727246E-11 -1.4034451913E-11 -8.0893973462E-02 1.0299909029E+00 -102.00 1.0596790996E+00 -2.7756745831E-01 -1.4957778891E-12 -2.0519333406E-11 -2.7756745831E-01 1.0596790996E+00 6.2485618274E-13 1.8880713885E-11 -3.1157872710E-12 -1.7521414564E-12 1.0166939184E+00 1.1049695293E-01 -1.5893625104E-11 -1.3886571095E-11 -1.1049695293E-01 1.0166939184E+00 -103.00 1.0483923722E+00 -2.4678729303E-01 -2.5677031594E-12 -2.0063384574E-11 -2.4678729303E-01 1.0483923722E+00 1.8322208827E-12 1.8334182896E-11 -4.3569358716E-12 -3.1349877652E-12 1.0096784933E+00 1.3701072273E-01 -1.5760174306E-11 -1.3707831039E-11 -1.3701072273E-01 1.0096784933E+00 -104.00 1.0433871721E+00 -2.1373855806E-01 -3.5925781242E-12 -1.9562106680E-11 -2.1373855806E-01 1.0433871721E+00 2.9923622720E-12 1.7746554412E-11 -5.5606765465E-12 -4.4801789540E-12 1.0085992570E+00 1.6031268977E-01 -1.5592199871E-11 -1.3501022448E-11 -1.6031268977E-01 1.0085992570E+00 -105.00 1.0443314257E+00 -1.7852490337E-01 -4.5665974604E-12 -1.9018960340E-11 -1.7852490337E-01 1.0443314257E+00 4.1010732815E-12 1.7121264943E-11 -6.7244397832E-12 -5.7845692933E-12 1.0130397119E+00 1.8029844022E-01 -1.5392407236E-11 -1.3268944930E-11 -1.8029844022E-01 1.0130397119E+00 -106.00 1.0508363100E+00 -1.4123996610E-01 -5.4863817369E-12 -1.8437457217E-11 -1.4123996610E-01 1.0508363100E+00 5.1543522226E-12 1.6461891462E-11 -7.8460051834E-12 -7.0451458998E-12 1.0225194163E+00 1.9688134916E-01 -1.5163467982E-11 -1.3014510439E-11 -1.9688134916E-01 1.0225194163E+00 -107.00 1.0624641440E+00 -1.0196901985E-01 -6.3483452601E-12 -1.7821095825E-11 -1.0196901985E-01 1.0624641440E+00 6.1491774934E-12 1.5772016149E-11 -8.9227618016E-12 -8.2598447141E-12 1.0365016247E+00 2.0999228162E-01 -1.4908136000E-11 -1.2740451159E-11 -2.0999228162E-01 1.0365016247E+00 -108.00 1.0787366105E+00 -6.0790909473E-02 -7.1503733847E-12 -1.7174075375E-11 -6.0790909473E-02 1.0787366105E+00 7.0817204007E-12 1.5054573541E-11 -9.9537323203E-12 -9.4254264323E-12 1.0544012675E+00 2.1957938744E-01 -1.4629618411E-11 -1.2449020137E-11 -2.1957938744E-01 1.0544012675E+00 -109.00 1.0991431796E+00 -1.7780210436E-02 -7.8896219693E-12 -1.6499014122E-11 -1.7780210436E-02 1.0991431796E+00 7.9496742085E-12 1.4314044246E-11 -1.0936628285E-11 -1.0540503308E-11 1.0755931521E+00 2.2560798872E-01 -1.4329657439E-11 -1.2143817005E-11 -2.2560798872E-01 1.0755931521E+00 -110.00 1.1231496102E+00 2.6990450726E-02 -8.5640216197E-12 -1.5800447881E-11 2.6990450726E-02 1.1231496102E+00 8.7507762374E-12 1.3552917118E-11 -1.1870272233E-11 -1.1603129727E-11 1.0994202772E+00 2.2806055466E-01 -1.4011862134E-11 -1.1826413298E-11 -2.2806055466E-01 1.0994202772E+00 -111.00 1.1502064109E+00 7.3447979274E-02 -9.1720049894E-12 -1.5081122012E-11 7.3447979274E-02 1.1502064109E+00 9.4828850911E-12 1.2775433526E-11 -1.2753473440E-11 -1.2611732027E-11 1.1252021556E+00 2.2693675515E-01 -1.3677987588E-11 -1.1500153881E-11 -2.2693675515E-01 1.1252021556E+00 -112.00 1.1797571493E+00 1.2151636251E-01 -9.7123043938E-12 -1.4345037347E-11 1.2151636251E-01 1.1797571493E+00 1.0144473143E-11 1.1984466991E-11 -1.3585452137E-11 -1.3564947780E-11 1.1522430520E+00 2.2225358079E-01 -1.3331001470E-11 -1.1166966147E-11 -2.2225358079E-01 1.1522430520E+00 -113.00 1.2112465075E+00 1.7111425017E-01 -1.0183901027E-11 -1.3595763280E-11 1.7111425017E-01 1.2112465075E+00 1.0734350630E-11 1.1183241912E-11 -1.4365438770E-11 -1.4461689409E-11 1.1798400455E+00 2.1404551469E-01 -1.2973432431E-11 -1.0829122001E-11 -2.1404551469E-01 1.1798400455E+00 -114.00 1.2441279869E+00 2.2215262502E-01 -1.0586025212E-11 -1.2836116065E-11 2.2215262502E-01 1.2441279869E+00 1.1252017642E-11 1.0375542149E-11 -1.5092699467E-11 -1.5301467940E-11 1.2072908397E+00 2.0236473820E-01 -1.2607148573E-11 -1.0489271744E-11 -2.0236473820E-01 1.2072908397E+00 -115.00 1.2778711790E+00 2.7453262041E-01 -1.0918951191E-11 -1.2069763458E-11 2.7453262041E-01 1.2778711790E+00 1.1696622800E-11 9.5641292024E-12 -1.5767417063E-11 -1.6083257181E-11 1.2339012464E+00 1.8728135126E-01 -1.2234629945E-11 -1.0149252016E-11 -1.8728135126E-01 1.2339012464E+00 -116.00 1.3119685252E+00 3.2814353684E-01 -1.1182413676E-11 -1.1300049458E-11 3.2814353684E-01 1.3119685252E+00 1.2068481329E-11 8.7519075501E-12 -1.6389153327E-11 -1.6806937580E-11 1.2589922815E+00 1.6888358585E-01 -1.1858160178E-11 -9.8109017290E-12 -1.6888358585E-01 1.2589922815E+00 -117.00 1.3459414989E+00 3.8286110432E-01 -1.1377102596E-11 -1.0529833218E-11 3.8286110432E-01 1.3459414989E+00 1.2367842896E-11 7.9420522514E-12 -1.6958145119E-11 -1.7472323870E-11 1.2819068168E+00 1.4727799044E-01 -1.1479524621E-11 -9.4762835949E-12 -1.4727799044E-01 1.2819068168E+00 -118.00 1.3793461546E+00 4.3854603170E-01 -1.1504149015E-11 -9.7617172333E-12 4.3854603170E-01 1.3793461546E+00 1.2595048193E-11 7.1377914999E-12 -1.7474824723E-11 -1.8079207098E-11 1.3020157417E+00 1.2258956241E-01 -1.1100331346E-11 -9.1474512522E-12 -1.2258956241E-01 1.3020157417E+00 -119.00 1.4117779978E+00 4.9504287704E-01 -1.1564081495E-11 -8.9989291247E-12 4.9504287704E-01 1.4117779978E+00 1.2751867590E-11 6.3414450880E-12 -1.7939226303E-11 -1.8628332492E-11 1.3187235952E+00 9.4961805379E-02 -1.0722668570E-11 -8.8256465354E-12 -9.4961805379E-02 1.3187235952E+00 -120.00 1.4428761403E+00 5.5217926680E-01 -1.1559049723E-11 -8.2444956141E-12 5.5217926680E-01 1.4428761403E+00 1.2838990589E-11 5.5552589784E-12 -1.8352413428E-11 -1.9119609818E-11 1.3314736375E+00 6.4556689069E-02 -1.0348318888E-11 -8.5121410975E-12 -6.4556689069E-02 1.3314736375E+00 -121.00 1.4723267149E+00 6.0976548403E-01 -1.1490568557E-11 -7.5007746240E-12 6.0976548403E-01 1.4723267149E+00 1.2858422793E-11 4.7819414340E-12 -1.8714925019E-11 -1.9553886192E-11 1.3397523368E+00 3.1554489975E-02 -9.9786456146E-12 -8.2084429961E-12 -3.1554489975E-02 1.3397523368E+00 -122.00 1.4998655342E+00 6.6759443860E-01 -1.1360737343E-11 -6.7700896082E-12 6.6759443860E-01 1.4998655342E+00 1.2812142041E-11 4.0238585523E-12 -1.9027650725E-11 -1.9931905143E-11 1.3430932546E+00 -3.8465071781E-03 -9.6149091722E-12 -7.9157490426E-12 3.8465071781E-03 1.3430932546E+00 -123.00 1.5252799870E+00 7.2544202500E-01 -1.1171548641E-11 -6.0546284699E-12 7.2544202500E-01 1.5252799870E+00 1.2702760386E-11 3.2832796419E-12 -1.9291373518E-11 -2.0254751579E-11 1.3410803196E+00 -4.1430465414E-02 -9.2582696709E-12 -7.6351627135E-12 4.1430465414E-02 1.3410803196E+00 -124.00 1.5484101758E+00 7.8306786634E-01 -1.0926391365E-11 -5.3568493853E-12 7.8306786634E-01 1.5484101758E+00 1.2532125211E-11 2.5619012233E-12 -1.9507731846E-11 -2.0523095444E-11 1.3333504861E+00 -8.0964624744E-02 -8.9100194850E-12 -7.3673766691E-12 8.0964624744E-02 1.3333504861E+00 -125.00 1.5691493071E+00 8.4021643584E-01 -1.0627450069E-11 -4.6787247650E-12 8.4021643584E-01 1.5691493071E+00 1.2303696080E-11 1.8615507162E-12 -1.9677571239E-11 -2.0738525213E-11 1.3195957791E+00 -1.2220011776E-01 -8.5710525395E-12 -7.1131196648E-12 1.2220011776E-01 1.3195957791E+00 -126.00 1.5874433545E+00 8.9661854062E-01 -1.0278523500E-11 -4.0211377693E-12 8.9661854062E-01 1.5874433545E+00 1.2019730301E-11 1.1848673544E-12 -1.9802670766E-11 -2.0901852440E-11 1.2995647335E+00 -1.6487298157E-01 -8.2417039831E-12 -6.8734453840E-12 1.6487298157E-01 1.2995647335E+00 -127.00 1.6032900229E+00 9.5199314663E-01 -9.8818360029E-12 -3.3873032321E-12 9.5199314663E-01 1.6032900229E+00 1.1684535305E-11 5.3184600959E-13 -1.9883841293E-11 -2.1015183414E-11 1.2730632403E+00 -2.0870537282E-01 -7.9234145045E-12 -6.6480393786E-12 2.0870537282E-01 1.2730632403E+00 -128.00 1.6167370482E+00 1.0060495174E+00 -9.4419318281E-12 -2.7777876442E-12 1.0060495174E+00 1.6167370482E+00 1.1300409773E-11 -9.5156784006E-14 -1.9923196278E-11 -2.1079391341E-11 1.2399548175E+00 -2.5340698868E-01 -7.6163234340E-12 -6.4376648175E-12 2.5340698868E-01 1.2399548175E+00 -129.00 1.6278798743E+00 1.0584896351E+00 -8.9609372850E-12 -2.1941317630E-12 1.0584896351E+00 1.6278798743E+00 1.0872416825E-11 -6.9521027609E-13 -1.9921623588E-11 -2.1096838325E-11 1.2001603269E+00 -2.9867669338E-01 -7.3207175159E-12 -6.2423999994E-12 2.9867669338E-01 1.2001603269E+00 -130.00 1.6368587549E+00 1.1090108666E+00 -8.4444745457E-12 -1.6374909150E-12 1.1090108666E+00 1.6368587549E+00 1.0402407920E-11 -1.2672033706E-12 -1.9881652017E-11 -2.1068377065E-11 1.1536571630E+00 -3.4420434549E-01 -7.0370559925E-12 -6.0621035868E-12 3.4420434549E-01 1.1536571630E+00 -131.00 1.6438553309E+00 1.1573088357E+00 -7.8951534826E-12 -1.1088290032E-12 1.1573088357E+00 1.6438553309E+00 9.8954091419E-12 -1.8101188965E-12 -1.9804362985E-11 -2.0996250246E-11 1.1004779429E+00 -3.8967281778E-01 -6.7653421427E-12 -5.8968487677E-12 3.8967281778E-01 1.1004779429E+00 -132.00 1.6490887423E+00 1.2030804580E+00 -7.3169026352E-12 -6.0860436592E-13 1.2030804580E+00 1.6490887423E+00 9.3554660842E-12 -2.3227629074E-12 -1.9691650900E-11 -2.0882321003E-11 1.0407087308E+00 -4.3476019730E-01 -6.5054878241E-12 -5.7466221625E-12 4.3476019730E-01 1.0407087308E+00 -133.00 1.6528113318E+00 1.2460270927E+00 -6.7138161792E-12 -1.3871957788E-13 1.2460270927E+00 1.6528113318E+00 8.7863986717E-12 -2.8057854107E-12 -1.9545082048E-11 -2.0728501160E-11 9.7448683068E-01 -4.7914214977E-01 -6.2577195401E-12 -5.6104534879E-12 4.7914214977E-01 9.7448683068E-01 -134.00 1.6553040065E+00 1.2858577670E+00 -6.0904639421E-12 3.0141203744E-13 1.2858577670E+00 1.6553040065E+00 8.1918422116E-12 -3.2574910801E-12 -1.9366847637E-11 -2.0536444716E-11 9.0199818682E-01 -5.2249442875E-01 -6.0215988381E-12 -5.4883335440E-12 5.2249442875E-01 9.0199818682E-01 -135.00 1.6568713192E+00 1.3222924235E+00 -5.4502474532E-12 7.1030252675E-13 1.3222924235E+00 1.6568713192E+00 7.5765475092E-12 -3.6786487731E-12 -1.9158336595E-11 -2.0308515686E-11 8.2347443062E-01 -5.6449550684E-01 -5.7969810148E-12 -5.3793905381E-12 5.6449550684E-01 8.2347443062E-01 -136.00 1.6578363389E+00 1.3550651468E+00 -4.7977495220E-12 1.0888159688E-12 1.3550651468E+00 1.6578363389E+00 6.9441384509E-12 -4.0679142980E-12 -1.8921737694E-11 -2.0046379303E-11 7.3918961653E-01 -6.0482930284E-01 -5.5832140507E-12 -5.2831977255E-12 6.0482930284E-01 7.3918961653E-01 -137.00 1.6585353760E+00 1.3839273206E+00 -4.1362986479E-12 1.4357312256E-12 1.3839273206E+00 1.6585353760E+00 6.2994250331E-12 -4.4262648421E-12 -1.8658421600E-11 -1.9752381494E-11 6.4945668933E-01 -6.4318797665E-01 -5.3799315995E-12 -5.1988529031E-12 6.4318797665E-01 6.4945668933E-01 -138.00 1.6593126288E+00 1.4086506737E+00 -3.4704557212E-12 1.7523181927E-12 1.4086506737E+00 1.6593126288E+00 5.6459387245E-12 -4.7524775748E-12 -1.8370610204E-11 -1.9428154483E-11 5.5462372739E-01 -6.7927476072E-01 -5.1863403320E-12 -5.1256457068E-12 6.7927476072E-01 5.5462372739E-01 -139.00 1.6605148199E+00 1.4290301706E+00 -2.8039096874E-12 2.0374319252E-12 1.4290301706E+00 1.6605148199E+00 4.9880160258E-12 -5.0479401875E-12 -1.8059773482E-11 -1.9076050003E-11 4.5507000630E-01 -7.1280679563E-01 -5.0020535315E-12 -5.0625329312E-12 7.1280679563E-01 4.5507000630E-01 -140.00 1.6624858846E+00 1.4448867089E+00 -2.1402209629E-12 2.2917430558E-12 1.4448867089E+00 1.6624858846E+00 4.3298945120E-12 -5.3125153686E-12 -1.7727750553E-11 -1.8698028778E-11 3.5120192810E-01 -7.4351793557E-01 -4.8260759096E-12 -5.0085968270E-12 7.4351793557E-01 3.5120192810E-01 -141.00 1.6655617769E+00 1.4560695872E+00 -1.4841841052E-12 2.5159141899E-12 1.4560695872E+00 1.6655617769E+00 3.6744347140E-12 -5.5462470005E-12 -1.7376487466E-11 -1.8295907360E-11 2.4344886095E-01 -7.7116148885E-01 -4.6578400551E-12 -4.9625864324E-12 7.7116148885E-01 2.4344886095E-01 -142.00 1.6700654511E+00 1.4624587099E+00 -8.3858041493E-13 2.7098813054E-12 1.4624587099E+00 1.6700654511E+00 3.0263091297E-12 -5.7500493434E-12 -1.7007368838E-11 -1.7871796147E-11 1.3225893375E-01 -7.9551285809E-01 -4.4964199129E-12 -4.9236399025E-12 7.9551285809E-01 1.3225893375E-01 -143.00 1.6763020785E+00 1.4639665024E+00 -2.0699703161E-13 2.8740496444E-12 1.4639665024E+00 1.6763020785E+00 2.3890629732E-12 -5.9246825025E-12 -1.6622149872E-11 -1.7427792902E-11 1.8094829407E-02 -8.1637204485E-01 -4.3408183502E-12 -4.8905092155E-12 8.1637204485E-01 1.8094829407E-02 -144.00 1.6845545506E+00 1.4605395111E+00 4.0769056550E-13 3.0098543787E-12 1.4605395111E+00 1.6845545506E+00 1.7667324641E-12 -6.0699181845E-12 -1.6222597649E-11 -1.6965478894E-11 -9.8570380886E-02 -8.3356598447E-01 -4.1900380608E-12 -4.8622458507E-12 8.3356598447E-01 -9.8570380886E-02 -145.00 1.6950793193E+00 1.4521596692E+00 1.0010646828E-12 3.1178821924E-12 1.4521596692E+00 1.6950793193E+00 1.1614673714E-12 -6.1865865505E-12 -1.5810235925E-11 -1.6486770285E-11 -2.1725732134E-01 -8.4695067753E-01 -4.0434958381E-12 -4.8372889013E-12 8.4695067753E-01 -2.1725732134E-01 -146.00 1.7081026194E+00 1.4388452133E+00 1.5705455535E-12 3.1971769572E-12 1.4388452133E+00 1.7081026194E+00 5.7689414858E-13 -6.2772048421E-12 -1.5386100538E-11 -1.5994006725E-11 -3.3748427436E-01 -8.5641308676E-01 -3.8999583699E-12 -4.8146721156E-12 8.5641308676E-01 -3.3748427436E-01 -147.00 1.7238171117E+00 1.4206512400E+00 2.1146662914E-12 3.2510164963E-12 1.4206512400E+00 1.7238171117E+00 1.7451896962E-14 -6.3401785570E-12 -1.4952445679E-11 -1.5488088118E-11 -4.5877098563E-01 -8.6187276987E-01 -3.7583776576E-12 -4.7934755400E-12 8.6187276987E-01 -4.5877098563E-01 -148.00 1.7423789821E+00 1.3976698973E+00 2.6285754879E-12 3.2785820112E-12 1.3976698973E+00 1.7423789821E+00 -5.1632962903E-13 -6.3781083748E-12 -1.4509946782E-11 -1.4971503247E-11 -5.8064227745E-01 -8.6328322184E-01 -3.6181121139E-12 -4.7719739155E-12 8.6328322184E-01 -5.8064227745E-01 -149.00 1.7639055265E+00 1.3700302090E+00 3.1108238275E-12 3.2816212101E-12 1.3700302090E+00 1.7639055265E+00 -1.0208010008E-12 -6.3910892629E-12 -1.4060148623E-11 -1.4445477128E-11 -7.0263143903E-01 -8.6063290302E-01 -3.4781088423E-12 -4.7492109840E-12 8.6063290302E-01 -7.0263143903E-01 -150.00 1.7884732431E+00 1.3378975361E+00 3.5597080820E-12 3.2607520582E-12 1.3378975361E+00 1.7884732431E+00 -1.4930832681E-12 -6.3805029838E-12 -1.3604370503E-11 -1.3911632254E-11 -8.2428336586E-01 -8.5394593325E-01 -3.3372384765E-12 -4.7242603479E-12 8.5394593325E-01 -8.2428336586E-01 -151.00 1.8161164503E+00 1.3014726812E+00 3.9729073109E-12 3.2173968729E-12 1.3014726812E+00 1.8161164503E+00 -1.9313497413E-12 -6.3469619333E-12 -1.3143832886E-11 -1.3371417062E-11 -9.4515742341E-01 -8.4328243549E-01 -3.1948133408E-12 -4.6958261718E-12 8.4328243549E-01 -9.4515742341E-01 -152.00 1.8468264417E+00 1.2609906487E+00 4.3484101593E-12 3.1524398328E-12 1.2609906487E+00 1.8468264417E+00 -2.3338744668E-12 -6.2916275597E-12 -1.2679424332E-11 -1.2826288739E-11 -1.0648300145E+00 -8.2873851721E-01 -3.0500318294E-12 -4.6628116325E-12 8.2873851721E-01 -1.0648300145E+00 -153.00 1.8805511826E+00 1.2167190744E+00 4.6851000542E-12 3.0661594327E-12 1.2167190744E+00 1.8805511826E+00 -2.6986205194E-12 -6.2163881087E-12 -1.2212132593E-11 -1.2277767648E-11 -1.1828968331E+00 -8.1044588142E-01 -2.9016859913E-12 -4.6245997957E-12 8.1044588142E-01 -1.1828968331E+00 -154.00 1.9171955473E+00 1.1689563434E+00 4.9814163129E-12 2.9607851990E-12 1.1689563434E+00 1.9171955473E+00 -3.0243899789E-12 -6.1210966293E-12 -1.1743017251E-11 -1.1726816582E-11 -1.2989747920E+00 -7.8857106432E-01 -2.7494723865E-12 -4.5797190568E-12 7.8857106432E-01 -1.2989747920E+00 -155.00 1.9566220904E+00 1.1180294177E+00 5.2363408371E-12 2.8370485602E-12 1.1180294177E+00 1.9566220904E+00 -3.3099907248E-12 -6.0072584351E-12 -1.1272845045E-11 -1.1174786701E-11 -1.4127036152E+00 -7.6331430062E-01 -2.5926172083E-12 -4.5274633280E-12 7.6331430062E-01 -1.4127036152E+00 -156.00 1.9986523393E+00 1.0642913963E+00 5.4493639866E-12 2.6952952105E-12 1.0642913963E+00 1.9986523393E+00 -3.5541654642E-12 -5.8766697404E-12 -1.0802260969E-11 -1.0622765158E-11 -1.5237470904E+00 -7.3490802256E-01 -2.4300481993E-12 -4.4674368425E-12 7.3490802256E-01 -1.5237470904E+00 -157.00 2.0430685883E+00 1.0081188350E+00 5.6199445152E-12 2.5381665036E-12 1.0081188350E+00 2.0430685883E+00 -3.7562489638E-12 -5.7288616688E-12 -1.0332323123E-11 -1.0071393168E-11 -1.6317939817E+00 -7.0361500299E-01 -2.2619546850E-12 -4.3981332983E-12 7.0361500299E-01 -1.6317939817E+00 -158.00 2.0896161718E+00 9.4990885242E-01 5.7476583734E-12 2.3655101598E-12 9.4990885242E-01 2.0896161718E+00 -3.9159179607E-12 -5.5661538503E-12 -9.8632270279E-12 -9.5219336454E-12 -1.7365586058E+00 -6.6972615755E-01 -2.0872811031E-12 -4.3194949388E-12 6.6972615755E-01 -1.7365586058E+00 -159.00 2.1380061856E+00 8.9007605284E-01 5.8321310532E-12 2.1784043963E-12 8.9007605284E-01 2.1380061856E+00 -4.0333166373E-12 -5.3894898358E-12 -9.3952410317E-12 -8.9753653313E-12 -1.8377810801E+00 -6.3355802518E-01 -1.9055956108E-12 -4.2308050410E-12 6.3355802518E-01 -1.8377810801E+00 -160.00 2.1879186236E+00 8.2904929498E-01 5.8745617616E-12 1.9786155607E-12 8.2904929498E-01 2.1879186236E+00 -4.1075707592E-12 -5.1993934831E-12 -8.9295660506E-12 -8.4318089869E-12 -1.9352272545E+00 -5.9544995032E-01 -1.7168493605E-12 -4.1315558199E-12 5.9544995032E-01 -1.9352272545E+00 -161.00 2.2390058902E+00 7.6726833854E-01 5.8745527040E-12 1.7668732938E-12 7.6726833854E-01 2.2390058902E+00 -4.1397287877E-12 -4.9970621769E-12 -8.4658711309E-12 -7.8923359380E-12 -2.0286883423E+00 -5.5576099428E-01 -1.5207492864E-12 -4.0212510449E-12 5.5576099428E-01 -2.0286883423E+00 -162.00 2.2908966464E+00 7.0518039943E-01 5.8331349251E-12 1.5440559473E-12 7.0518039943E-01 2.2908966464E+00 -4.1299913095E-12 -4.7837312669E-12 -8.0045950633E-12 -7.3573407008E-12 -2.1179802706E+00 -5.1486660627E-01 -1.3169940537E-12 -3.8998582675E-12 5.1486660627E-01 -2.1179802706E+00 -163.00 2.3431999431E+00 6.4323664531E-01 5.7513805058E-12 1.3113417629E-12 6.4323664531E-01 2.3431999431E+00 -4.0790475044E-12 -4.5600915539E-12 -7.5460569020E-12 -6.8271762765E-12 -2.2029427713E+00 -4.7315508832E-01 -1.1055660408E-12 -3.7669594780E-12 4.7315508832E-01 -2.2029427713E+00 -164.00 2.3955095922E+00 5.8188866244E-01 5.6300169083E-12 1.0695545490E-12 5.8188866244E-01 2.3955095922E+00 -3.9882594647E-12 -4.3272882458E-12 -7.0899954747E-12 -6.3024989847E-12 -2.2834382401E+00 -4.3102389076E-01 -8.8645739580E-13 -3.6225610957E-12 4.3102389076E-01 -2.2834382401E+00 -165.00 2.4474087248E+00 5.2158492453E-01 5.4708645322E-12 8.1974166613E-13 5.2158492453E-01 2.4474087248E+00 -3.8584371753E-12 -4.0861563543E-12 -6.6367902350E-12 -5.7832850201E-12 -2.3593503900E+00 -3.8887577728E-01 -6.5977207320E-13 -3.4666661573E-12 3.8887577728E-01 -2.3593503900E+00 -166.00 2.4984744813E+00 4.6276729327E-01 5.2753002267E-12 5.6269182627E-13 4.6276729327E-01 2.4984744813E+00 -3.6911210488E-12 -3.8377386571E-12 -6.1862019014E-12 -5.2698089811E-12 -2.4305827309E+00 -3.4711490054E-01 -4.2562971774E-13 -3.2994796481E-12 3.4711490054E-01 -2.4305827309E+00 -167.00 2.5482827796E+00 4.0586757936E-01 5.0452259314E-12 2.9969285972E-13 4.0586757936E-01 2.5482827796E+00 -3.4878760549E-12 -3.5823855451E-12 -5.7382716154E-12 -4.7620794499E-12 -2.4970569077E+00 -3.0614283059E-01 -1.8459554794E-13 -3.1207500733E-12 3.0614283059E-01 -2.4970569077E+00 -168.00 2.5964131055E+00 3.5130419160E-01 4.7824247207E-12 3.1365019211E-14 3.5130419160E-01 2.5964131055E+00 -3.2506954723E-12 -3.3212666652E-12 -5.2926341563E-12 -4.2603194218E-12 -2.5587109289E+00 -2.6635457930E-01 6.3120024404E-14 -2.9310240900E-12 2.6635457930E-01 -2.5587109289E+00 -169.00 2.6424532695E+00 2.9947890017E-01 4.4892980010E-12 -2.4163237444E-13 2.9947890017E-01 2.6424532695E+00 -2.9813400400E-12 -3.0552733471E-12 -4.8492614114E-12 -3.7642868619E-12 -2.6154973227E+00 -2.2813466410E-01 3.1726164358E-13 -2.7307574994E-12 2.2813466410E-01 -2.6154973227E+00 -170.00 2.6860040744E+00 2.5077373892E-01 4.1679103929E-12 -5.1833028003E-13 2.5077373892E-01 2.6860040744E+00 -2.6821998123E-12 -2.7850431184E-12 -4.4076653077E-12 -3.2740440996E-12 -2.6673812529E+00 -1.9185325449E-01 5.7713778280E-13 -2.5202687159E-12 1.9185325449E-01 -2.6673812529E+00 -171.00 2.7266838406E+00 2.0554806948E-01 3.8207396607E-12 -7.9795701706E-13 2.0554806948E-01 2.7266838406E+00 -2.3555757206E-12 -2.5112880737E-12 -3.9675181013E-12 -2.7893897427E-12 -2.7143386315E+00 -1.5786244371E-01 8.4216028349E-13 -2.3000557599E-12 1.5786244371E-01 -2.7143386315E+00 -172.00 2.7641327353E+00 1.6413582887E-01 3.4505355231E-12 -1.0798938093E-12 1.6413582887E-01 2.7641327353E+00 -2.0038900027E-12 -2.2348471687E-12 -3.5285794011E-12 -2.3100514649E-12 -2.7563542603E+00 -1.2649268701E-01 1.1117913508E-12 -2.0708369810E-12 1.2649268701E-01 -2.7563542603E+00 -173.00 2.7980168574E+00 1.2684297992E-01 3.0597367713E-12 -1.3634054721E-12 1.2684297992E-01 2.7980168574E+00 -1.6298854614E-12 -1.9563538886E-12 -3.0901577663E-12 -1.8358498898E-12 -2.7934200362E+00 -9.8049445981E-02 1.3852803889E-12 -1.8332254425E-12 9.8049445981E-02 -2.7934200362E+00 -174.00 2.8280320292E+00 9.3945182396E-02 2.6515627746E-12 -1.6477354098E-12 9.3945182396E-02 2.8280320292E+00 -1.2359723375E-12 -1.6763147528E-12 -2.6521798264E-12 -1.3661419037E-12 -2.8255332512E+00 -7.2810076533E-02 1.6618003817E-12 -1.5878086410E-12 7.2810076533E-02 -2.8255332512E+00 -175.00 2.8539072523E+00 6.5685700769E-02 2.2285167455E-12 -1.9323335519E-12 6.5685700769E-02 2.8539072523E+00 -8.2537780338E-13 -1.3955356619E-12 -2.2137604920E-12 -9.0092807711E-13 -2.8526950155E+00 -5.1020995123E-02 1.9406148337E-12 -1.3355218119E-12 5.1020995123E-02 -2.8526950155E+00 -176.00 2.8754077880E+00 4.2273562573E-02 1.7938457271E-12 -2.2164439603E-12 4.2273562573E-02 2.8754077880E+00 -4.0083741410E-13 -1.1145190065E-12 -1.7746409737E-12 -4.3960849648E-13 -2.8749088337E+00 -3.2895155044E-02 2.2207461160E-12 -1.0770910794E-12 3.2895155044E-02 -2.8749088337E+00 -177.00 2.8923378253E+00 2.3881979596E-02 1.3505403414E-12 -2.4995427649E-12 2.3881979596E-02 2.8923378253E+00 3.4658623024E-14 -8.3385239316E-13 -1.3342329091E-12 1.8274820197E-14 -2.8921793547E+00 -1.8609861027E-02 2.5013794239E-12 -8.1337586349E-13 1.8609861027E-02 -2.8921793547E+00 -178.00 2.9045427081E+00 1.0647042141E-02 9.0170042420E-13 -2.7810622430E-12 1.0647042141E-02 2.9045427081E+00 4.7805229208E-13 -5.5418942731E-13 -8.9200424072E-13 4.7319275766E-13 -2.9045113206E+00 -8.3049466902E-03 2.7816113405E-12 -5.4535391289E-13 8.3049466902E-03 -2.9045113206E+00 -179.00 2.9119106936E+00 2.6666947620E-03 4.5048317808E-13 -3.0603987652E-12 2.6666947620E-03 2.9119106936E+00 9.2614038004E-13 -2.7603127228E-13 -4.4744781223E-13 9.2553268965E-13 -2.9119087287E+00 -2.0813352948E-03 3.0604678646E-12 -2.7389031811E-13 2.0813352948E-03 -2.9119087287E+00 -180.00 2.9143742238E+00 5.8438497097E-17 -3.4482375626E-17 -3.3370309259E-12 5.8438497097E-17 2.9143742238E+00 1.3759201813E-12 6.8119948021E-19 3.4482375626E-17 1.3759201813E-12 -2.9143742238E+00 2.7826048757E-16 3.3370309259E-12 6.8119948041E-19 -2.7826048757E-16 -2.9143742238E+00 +0.00 1.4154797788E+02 0.0000000000E+00 0.0000000000E+00 -5.4378623975E-11 0.0000000000E+00 1.4154797788E+02 -4.4699850464E-11 0.0000000000E+00 0.0000000000E+00 4.4699850464E-11 1.4154797788E+02 0.0000000000E+00 -5.4378623975E-11 0.0000000000E+00 0.0000000000E+00 1.4154797788E+02 +1.00 1.4140075332E+02 -5.8903788409E-03 -2.1360205695E-12 -5.0978006572E-11 -5.8903788409E-03 1.4140075332E+02 -4.2530243561E-11 -3.3819056580E-12 -2.1413799454E-12 4.2530570631E-11 1.4140075285E+02 9.9513430501E-03 -5.0977996920E-11 3.3810361087E-12 -9.9513430501E-03 1.4140075285E+02 +2.00 1.4095992068E+02 -2.3466973166E-02 -4.2632738080E-12 -4.7538781303E-11 -2.3466973166E-02 1.4095992068E+02 -4.0297773426E-11 -6.7636072117E-12 -4.2833739670E-12 4.0300389603E-11 1.4095991314E+02 3.9706967185E-02 -4.7538703269E-11 6.7601696110E-12 -3.9706967185E-02 1.4095991314E+02 +3.00 1.4022799582E+02 -5.2447619522E-02 -6.3718303759E-12 -4.4070138494E-11 -5.2447619522E-02 1.4022799582E+02 -3.8013383255E-11 -1.0136665323E-11 -6.4140114840E-12 3.8022203466E-11 1.4022795779E+02 8.8972730285E-02 -4.4069872128E-11 1.0129026476E-11 -8.8972730285E-02 1.4022795779E+02 +4.00 1.3920914780E+02 -9.2366898519E-02 -8.4514051659E-12 -4.0580992278E-11 -9.2366898519E-02 1.3920914780E+02 -3.5687113843E-11 -1.3490671401E-11 -8.5209341580E-12 3.5707977113E-11 1.3920902833E+02 1.5726195861E-01 -4.0580352384E-11 1.3477270300E-11 -1.5726195861E-01 1.3920902833E+02 +5.00 1.3790916315E+02 -1.4258333027E-01 -1.0492367990E-11 -3.7081578896E-11 -1.4258333027E-01 1.3790916315E+02 -3.3330077801E-11 -1.6817413227E-11 -1.0592428739E-11 3.3370701919E-11 1.3790887377E+02 2.4390074497E-01 -3.7080310757E-11 1.6796768745E-11 -2.4390074497E-01 1.3790887377E+02 +6.00 1.3633539636E+02 -2.0228928139E-01 -1.2485784377E-11 -3.3580678968E-11 -2.0228928139E-01 1.3633539636E+02 -3.0952437148E-11 -2.0107211175E-11 -1.2617484070E-11 3.1022352999E-11 1.3633480205E+02 3.4803527363E-01 -3.3578449904E-11 2.0077930963E-11 -3.4803527363E-01 1.3633480205E+02 +7.00 1.3449670713E+02 -2.7052342042E-01 -1.4421499861E-11 -3.0088430613E-11 -2.7052342042E-01 1.3449670713E+02 -2.8564429084E-11 -2.3351463161E-11 -1.4583899434E-11 2.8674897573E-11 1.3449561860E+02 4.6864108129E-01 -3.0084826448E-11 2.3312256003E-11 -4.6864108129E-01 1.3449561860E+02 +8.00 1.3240338522E+02 -3.4618551714E-01 -1.6290099085E-11 -2.6612880862E-11 -3.4618551714E-01 1.3240338522E+02 -2.6177074782E-11 -2.6539696301E-11 -1.6480255897E-11 2.6340978475E-11 1.3240155253E+02 6.0453413925E-01 -2.6607394177E-11 2.6489376742E-11 -6.0453413925E-01 1.3240155253E+02 +9.00 1.3006706346E+02 -4.2805334327E-01 -1.8082739052E-11 -2.3164664197E-11 -4.2805334327E-01 1.3006706346E+02 -2.3799724074E-11 -2.9665794095E-11 -1.8295779120E-11 2.4031467044E-11 1.3006417136E+02 7.5438362016E-01 -2.3156695059E-11 2.9603306195E-11 -7.5438362016E-01 1.3006417136E+02 +10.00 1.2750062014E+02 -5.1480139833E-01 -1.9792034780E-11 -1.9750799831E-11 -5.1480139833E-01 1.2750062014E+02 -2.1443955691E-11 -3.2717340059E-11 -2.0021225794E-11 2.1759301910E-11 1.2749628515E+02 9.1672619214E-01 -1.9739619660E-11 3.2641747633E-11 -9.1672619214E-01 1.2749628515E+02 +11.00 1.2471807163E+02 -6.0502115599E-01 -2.1408855446E-11 -1.6382020432E-11 -6.0502115599E-01 1.2471807163E+02 -1.9118649902E-11 -3.5689667098E-11 -2.1645722200E-11 1.9534612724E-11 1.2471184098E+02 1.0899816653E+00 -1.6366798413E-11 3.5600192587E-11 -1.0899816653E+00 1.2471184098E+02 +12.00 1.2173445652E+02 -6.9724250277E-01 -2.2925668186E-11 -1.3066819360E-11 -6.9724250277E-01 1.2173445652E+02 -1.6833262123E-11 -3.8573859301E-11 -2.3160100887E-11 1.7367923498E-11 1.2172580900E+02 1.2724697997E+00 -1.3046591939E-11 3.8469889170E-11 -1.2724697997E+00 1.2172580900E+02 +13.00 1.1856571240E+02 -7.8995602321E-01 -2.4336186406E-11 -9.8129539282E-12 -7.8995602321E-01 1.1856571240E+02 -1.4598145306E-11 -4.1361292237E-11 -2.4556572258E-11 1.5270485055E-11 1.1855406122E+02 1.4624280713E+00 -9.7866006671E-12 4.1242373697E-11 -1.4624280713E+00 1.1855406122E+02 +14.00 1.1522854672E+02 -8.8163577454E-01 -2.5631998932E-11 -6.6284616725E-12 -8.8163577454E-01 1.1522854672E+02 -1.2420502910E-11 -4.4044613843E-11 -2.5825352170E-11 1.3250208663E-11 1.1521324418E+02 1.6580301811E+00 -6.5947287993E-12 4.3910502853E-11 -1.6580301811E+00 1.1521324418E+02 +15.00 1.1174030292E+02 -9.7076218798E-01 -2.6810386012E-11 -3.5205830195E-12 -9.7076218798E-01 1.1174030292E+02 -1.0311677428E-11 -4.6616342295E-11 -2.6962526366E-11 1.1318985837E-11 1.1172064699E+02 1.8574050870E+00 -3.4779968819E-12 4.6466951776E-11 -1.8574050870E+00 1.1172064699E+02 +16.00 1.0811882335E+02 -1.0558447351E+00 -2.7862541412E-11 -4.9771708199E-13 -1.0558447351E+00 1.0811882335E+02 -8.2768195507E-12 -4.9070008402E-11 -2.7958238335E-11 9.4822796689E-12 1.0809406593E+02 2.0586563328E+00 -4.4467279931E-13 4.8905518372E-11 -2.0586563328E+00 1.0809406593E+02 +17.00 1.0438231031E+02 -1.1354440047E+00 -2.8785321449E-11 2.4353797171E-12 -1.1354440047E+00 1.0438231031E+02 -6.3253138736E-12 -5.1397592198E-11 -2.8808442958E-11 7.7495878705E-12 1.0435166702E+02 2.2598814456E+00 2.5007280346E-12 5.1218357922E-11 -2.2598814456E+00 1.0435166702E+02 +18.00 1.0054918663E+02 -1.2081928480E+00 -2.9573693587E-11 5.2660087676E-12 -1.2081928480E+00 1.0054918663E+02 -4.4631476545E-12 -5.3598047422E-11 -2.9507538390E-11 6.1269303252E-12 1.0051184796E+02 2.4591911787E+00 5.3456464070E-12 5.3404753120E-11 -2.4591911787E+00 1.0051184796E+02 +19.00 9.6637957120E+01 -1.2728162700E+00 -3.0224571513E-11 7.9935258289E-12 -1.2728162700E+00 9.6637957120E+01 -2.6971903210E-12 -5.5661082075E-11 -3.0051813675E-11 4.6208082333E-12 9.6593100749E+01 2.6547283776E+00 8.0897193684E-12 5.5454602252E-11 -2.6547283776E+00 9.6593100749E+01 +20.00 9.2667072319E+01 -1.3281497673E+00 -3.0736143875E-11 1.0611241966E-11 -1.3281497673E+00 9.2667072319E+01 -1.0349718550E-12 -5.7581368402E-11 -3.0439169103E-11 3.2382749393E-12 9.2613876231E+01 2.8446862569E+00 1.0726534425E-11 5.7362804057E-11 -2.8446862569E+00 9.2613876231E+01 +21.00 8.8654795761E+01 -1.3731558425E+00 -3.1102564942E-11 1.3110617407E-11 -1.3731558425E+00 8.8654795761E+01 5.2235113437E-13 -5.9357356313E-11 -3.0663665821E-11 1.9798555030E-12 8.8592452006E+01 3.0273258842E+00 1.3247642328E-11 5.9128261985E-11 -3.0273258842E+00 8.8592452006E+01 +22.00 8.4619076003E+01 -1.4069384575E+00 -3.1326719113E-11 1.5486893957E-11 -1.4069384575E+00 8.4619076003E+01 1.9649000982E-12 -6.0984536706E-11 -3.0728331047E-11 8.5462882415E-13 8.4546804752E+01 3.2009926819E+00 1.5648685169E-11 6.0746593492E-11 -3.2009926819E+00 8.4546804752E+01 +23.00 8.0577424575E+01 -1.4287552259E+00 -3.1403868397E-11 1.7738109650E-11 -1.4287552259E+00 8.0577424575E+01 3.2930057606E-12 -6.2456353771E-11 -3.0628509825E-11 -1.3895661066E-13 8.0494488179E+01 3.3641317704E+00 1.7927869674E-11 6.2211665668E-11 -3.3641317704E+00 8.0494488179E+01 +24.00 7.6546800891E+01 -1.4380271821E+00 -3.1338362640E-11 1.9858016569E-11 -1.4380271821E+00 7.6546800891E+01 4.4987194070E-12 -6.3771196179E-11 -3.0369137468E-11 -9.9405547476E-13 7.6452517659E+01 3.5153019962E+00 2.0079386048E-11 6.3522029657E-11 -3.5153019962E+00 7.6452517659E+01 +25.00 7.2543505086E+01 -1.4343460082E+00 -3.1126935165E-11 2.1841680606E-11 -1.4343460082E+00 7.2543505086E+01 5.5830195853E-12 -6.4927836006E-11 -2.9947561850E-11 -1.7130391632E-12 7.2437262478E+01 3.6531885039E+00 2.2098394108E-11 6.4676965539E-11 -3.6531885039E+00 7.2437262478E+01 +26.00 6.8583079611E+01 -1.4174786419E+00 -3.0773781970E-11 2.3690341342E-11 -1.4174786419E+00 6.8583079611E+01 6.5404047436E-12 -6.5918954130E-11 -2.9368592094E-11 -2.2921799139E-12 6.8464346575E+01 3.7766137348E+00 2.3986669955E-11 6.5669231201E-11 -3.7766137348E+00 6.8464346575E+01 +27.00 6.4680220328E+01 -1.3873692314E+00 -3.0276126918E-11 2.5395847498E-11 -1.3873692314E+00 6.4680220328E+01 7.3745347507E-12 -6.6748288220E-11 -2.8630580261E-11 -2.7366566531E-12 6.4548558503E+01 3.8845467545E+00 2.5735994055E-11 6.6503285921E-11 -3.8845467545E+00 6.4548558503E+01 +28.00 6.0848697677E+01 -1.3441384487E+00 -2.9643055018E-11 2.6957718561E-11 -1.3441384487E+00 6.0848697677E+01 8.0780581746E-12 -6.7412922767E-11 -2.7743748076E-11 -3.0409180719E-12 6.0703771246E+01 3.9761108348E+00 2.7346603821E-11 6.7176134112E-11 -3.9761108348E+00 6.0703771246E+01 +29.00 5.7101288424E+01 -1.2880802135E+00 -2.8872474118E-11 2.8372899387E-11 -1.2880802135E+00 5.7101288424E+01 8.6555869834E-12 -6.7913087482E-11 -2.6707241258E-11 -3.2115719244E-12 5.6942872389E+01 4.0505892381E+00 2.8815400458E-11 6.7688664494E-11 -4.0505892381E+00 5.6942872389E+01 +30.00 5.3449718305E+01 -1.2196559202E+00 -2.7970558796E-11 2.9643251752E-11 -1.2196559202E+00 5.3449718305E+01 9.1057855944E-12 -6.8245624350E-11 -2.5528410294E-11 -3.2495103622E-12 5.3277705017E+01 4.1074291762E+00 3.0144755912E-11 6.8037877421E-11 -4.1074291762E+00 5.3277705017E+01 +31.00 4.9904615792E+01 -1.1394863010E+00 -2.6941373414E-11 3.0765045566E-11 -1.1394863010E+00 4.9904615792E+01 9.4300202276E-12 -6.8413155639E-11 -2.4213004506E-11 -3.1580914737E-12 4.9719019596E+01 4.1462439389E+00 3.1331167851E-11 6.8226810275E-11 -4.1462439389E+00 4.9719019596E+01 +32.00 4.6475477077E+01 -1.0483410917E+00 -2.5791952298E-11 3.1737354716E-11 -1.0483410917E+00 4.6475477077E+01 9.6281182656E-12 -6.8417241045E-11 -2.2769743616E-11 -2.9392422648E-12 4.6276436965E+01 4.1668132078E+00 3.2374172756E-11 6.8257191465E-11 -4.1668132078E+00 4.6276436965E+01 +33.00 4.3170642206E+01 -9.4712669927E-01 -2.4523836574E-11 3.2561518164E-11 -9.4712669927E-01 4.3170642206E+01 9.7060445702E-12 -6.8258290241E-11 -2.1201674665E-11 -2.6013351477E-12 4.2958422435E+01 4.1690815980E+00 3.3275056016E-11 6.8130051221E-11 -4.1690815980E+00 4.2958422435E+01 +34.00 3.9997282233E+01 -8.3687209884E-01 -2.3146730969E-11 3.3237674209E-11 -8.3687209884E-01 3.9997282233E+01 9.6638359593E-12 -6.7937942652E-11 -1.9520335304E-11 -2.1466418119E-12 3.9772270876E+01 4.1531554840E+00 3.4034572964E-11 6.7847086983E-11 -4.1531554840E+00 3.9772270876E+01 +35.00 3.6961397104E+01 -7.1871320951E-01 -2.1665032928E-11 3.3767061984E-11 -7.1871320951E-01 3.6961397104E+01 9.5066701052E-12 -6.7458555184E-11 -1.7731873135E-11 -1.5826753498E-12 3.6724102570E+01 4.1192981934E+00 3.4654006939E-11 6.7411126513E-11 -4.1192981934E+00 3.6724102570E+01 +36.00 3.4067823884E+01 -5.9387601942E-01 -2.0088036303E-11 3.4151360735E-11 -5.9387601942E-01 3.4067823884E+01 9.2364854114E-12 -6.6822539386E-11 -1.5847414797E-11 -9.1368047907E-13 3.3818869475E+01 4.0679236642E+00 3.5135542121E-11 6.6824635084E-11 -4.0679236642E+00 3.3818869475E+01 +37.00 3.1320254860E+01 -4.6365874253E-01 -1.8420704290E-11 3.4391747177E-11 -4.6365874253E-01 3.1320254860E+01 8.8605227431E-12 -6.6034570488E-11 -1.3873832879E-11 -1.4901804773E-13 3.1060371464E+01 3.9995886802E+00 3.5480271284E-11 6.6092884830E-11 -3.9995886802E+00 3.1060371464E+01 +38.00 2.8721264933E+01 -3.2941329924E-01 -1.6672943093E-11 3.4489779496E-11 -3.2941329924E-01 2.8721264933E+01 8.3815241699E-12 -6.5098599147E-11 -1.1823030256E-11 7.0642841201E-13 2.8451282009E+01 3.9149838143E+00 3.5690227310E-11 6.5219805013E-11 -3.9149838143E+00 2.8451282009E+01 +39.00 2.6272347659E+01 -1.9252641650E-01 -1.4853351453E-11 3.4449960178E-11 -1.9252641650E-01 2.6272347659E+01 7.8047649489E-12 -6.4017167569E-11 -9.7052093295E-12 1.6450150413E-12 2.5993182681E+01 3.8149232194E+00 3.5770185382E-11 6.4208110623E-11 -3.8149232194E+00 2.5993182681E+01 +40.00 2.3973959220E+01 -5.4400641702E-02 -1.2966729211E-11 3.4274279858E-11 -5.4400641702E-02 2.3973959220E+01 7.1396028213E-12 -6.2796303992E-11 -7.5271673508E-12 2.6555391548E-12 2.3686605790E+01 3.7003334181E+00 3.5721751979E-11 6.3064548852E-11 -3.7003334181E+00 2.3686605790E+01 +41.00 2.1825569541E+01 8.3564441340E-02 -1.1025412743E-11 3.3966945884E-11 8.3564441340E-02 2.1825569541E+01 6.3889233640E-12 -6.1440047556E-11 -5.3029094975E-12 3.7330109256E-12 2.1531084395E+01 3.5722412514E+00 3.5549784710E-11 6.1792858147E-11 -3.5722412514E+00 2.1531084395E+01 +42.00 1.9825719738E+01 2.1999051696E-01 -9.0392599123E-12 3.3530589431E-11 2.1999051696E-01 1.9825719738E+01 5.5581377586E-12 -5.9955469535E-11 -3.0441780207E-12 4.8704087984E-12 1.9525208903E+01 3.4317611485E+00 3.5257220484E-11 6.0400002561E-11 -3.4317611485E+00 1.9525208903E+01 +43.00 1.7972085034E+01 3.5353810032E-01 -7.0138387804E-12 3.2972153203E-11 3.5353810032E-01 1.7972085034E+01 4.6581499106E-12 -5.8345637855E-11 -7.5780657137E-13 6.0547492726E-12 1.7666689392E+01 3.2800818867E+00 3.4850412605E-11 5.8889901823E-11 -3.2800818867E+00 1.7666689392E+01 +44.00 1.6261542281E+01 4.8292311482E-01 -4.9599256684E-12 3.2293044680E-11 4.8292311482E-01 1.6261542281E+01 3.6941002520E-12 -5.6619792748E-11 1.5433419306E-12 7.2798525148E-12 1.5952422808E+01 3.1184530094E+00 3.4331141132E-11 5.7271446754E-11 -3.1184530094E+00 1.5952422808E+01 +45.00 1.4690241177E+01 6.0693226325E-01 -2.8876583346E-12 3.1500142947E-11 6.0693226325E-01 1.4690241177E+01 2.6729389486E-12 -5.4782527790E-11 3.8480523310E-12 8.5370107292E-12 1.4378564129E+01 2.9481710690E+00 3.3706374272E-11 5.5549248405E-11 -2.9481710690E+00 1.4378564129E+01 +46.00 1.3253678306E+01 7.2443699727E-01 -8.0586555105E-13 3.0598327568E-11 7.2443699727E-01 1.3253678306E+01 1.6025028685E-12 -5.2841172495E-11 6.1460898182E-12 9.8172786901E-12 1.2940600624E+01 2.7705658571E+00 3.2980875960E-11 5.3730662522E-11 -2.7705658571E+00 1.2940600624E+01 +47.00 1.1946773114E+01 8.3440591756E-01 1.2769919990E-12 2.9594178624E-11 8.3440591756E-01 1.1946773114E+01 4.9137078794E-13 -5.0801429767E-11 8.4279234403E-12 1.1110833726E-11 1.1633428299E+01 2.5869867811E+00 3.2160857055E-11 5.1821622790E-11 -2.5869867811E+00 1.1633428299E+01 +48.00 1.0763944972E+01 9.3591546693E-01 3.3503825165E-12 2.8491553210E-11 9.3591546693E-01 1.0763944972E+01 -6.5383843371E-13 -4.8672724165E-11 1.0681654076E-11 1.2410532892E-11 1.0451429680E+01 2.3987895366E+00 3.1250463932E-11 4.9831072817E-11 -2.3987895366E+00 1.0451429680E+01 +49.00 9.6991904868E+00 1.0281588098E+00 5.4060398818E-12 2.7297549085E-11 1.0281588098E+00 9.6991904868E+00 -1.8243746427E-12 -4.6461362771E-11 1.2898207375E-11 1.3706802311E-11 9.3885520597E+00 2.2073232167E+00 3.0256345542E-11 4.7765457075E-11 -2.2073232167E+00 9.3885520597E+00 +50.00 8.7461602797E+00 1.1104528233E+00 7.4349712118E-12 2.6018925699E-11 1.1104528233E+00 8.7461602797E+00 -3.0124910819E-12 -4.4174537560E-11 1.5067904737E-11 1.4991339030E-11 8.4383854205E+00 2.0139179876E+00 2.9184956335E-11 4.5631839358E-11 -2.0139179876E+00 8.4383854205E+00 +51.00 7.8982344860E+00 1.1822431577E+00 9.4273705588E-12 2.4661921055E-11 1.1822431577E+00 7.8982344860E+00 -4.2113103163E-12 -4.1819985378E-11 1.7180396279E-11 1.6256821109E-11 7.5942392468E+00 1.8198734503E+00 2.8042424391E-11 4.3437541313E-11 -1.8198734503E+00 7.5942392468E+00 +52.00 7.1485962809E+00 1.2431073545E+00 1.1375509302E-11 2.3232005556E-11 1.2431073545E+00 7.1485962809E+00 -5.4122537306E-12 -3.9407118290E-11 1.9227152784E-11 1.7495006523E-11 6.8492175081E+00 1.6264477917E+00 2.6833948065E-11 4.1191674985E-11 -1.6264477917E+00 6.8492175081E+00 +53.00 6.4903027996E+00 1.2927560439E+00 1.3270952048E-11 2.1737340011E-11 1.2927560439E+00 6.4903027996E+00 -6.6077891572E-12 -3.6942195567E-11 2.1199708320E-11 1.8698089891E-11 6.1962911475E+00 1.4348478165E+00 2.5567037823E-11 3.8900399254E-11 -1.4348478165E+00 6.1962911475E+00 +54.00 5.9163528786E+00 1.3310322690E+00 1.5105718044E-11 2.0184585179E-11 1.3310322690E+00 5.9163528786E+00 -7.7904880992E-12 -3.4433792431E-11 2.3089903320E-11 1.9859061353E-11 5.6283674678E+00 1.2462199366E+00 2.4247976066E-11 3.6571891259E-11 -1.2462199366E+00 5.6283674678E+00 +55.00 5.4197511101E+00 1.3579090156E+00 1.6872021642E-11 1.8580445519E-11 1.3579090156E+00 5.4197511101E+00 -8.9530721386E-12 -3.1890059420E-11 2.4889902707E-11 2.0971096995E-11 5.1383558740E+00 1.0616421774E+00 2.2883004175E-11 3.4213850240E-11 -1.0616421774E+00 5.1383558740E+00 +56.00 4.9935677704E+00 1.3734850490E+00 1.8562559719E-11 1.6931797957E-11 1.3734850490E+00 4.9935677704E+00 -1.0088633243E-11 -2.9319276112E-11 2.6592588182E-11 2.2027965199E-11 4.7192294982E+00 8.8211724884E-01 2.1478482297E-11 3.1834034685E-11 -8.8211724884E-01 4.7192294982E+00 +57.00 4.6309942526E+00 1.3779791842E+00 2.0170824790E-11 1.5245601338E-11 1.3779791842E+00 4.6309942526E+00 -1.1189985283E-11 -2.6729529942E-11 2.8191660834E-11 2.3023391480E-11 4.3640823038E+00 7.0856670898E-01 2.0040720961E-11 2.9440052491E-11 -7.0856670898E-01 4.3640823038E+00 +58.00 4.3253937022E+00 1.3717231332E+00 2.1689977968E-11 1.3529289188E-11 1.3717231332E+00 4.3253937022E+00 -1.2250992655E-11 -2.4128585114E-11 2.9680892428E-11 2.3952091314E-11 4.0661813355E+00 5.4182623765E-01 1.8576484449E-11 2.7039177168E-11 -5.4182623765E-01 4.0661813355E+00 +59.00 4.0703466259E+00 1.3551530926E+00 2.3114342413E-11 1.1789557091E-11 1.3551530926E+00 4.0703466259E+00 -1.3265299702E-11 -2.1524550748E-11 3.1055116853E-11 2.4808943281E-11 3.8190138565E+00 3.8264201921E-01 1.7091755954E-11 2.4638845694E-11 -3.8264201921E-01 3.8190138565E+00 +60.00 3.8596913099E+00 1.3288002469E+00 2.4438761377E-11 1.0034067678E-11 1.3288002469E+00 3.8596913099E+00 -1.4226649253E-11 -1.8924679326E-11 3.2309811198E-11 2.5589035709E-11 3.6163291811E+00 2.3166822205E-01 1.5593261299E-11 2.2245907800E-11 -2.3166822205E-01 3.6163291811E+00 +61.00 3.6875589504E+00 1.2932803723E+00 2.5657657145E-11 8.2687892996E-12 1.2932803723E+00 3.6875589504E+00 -1.5130304006E-11 -1.6337581710E-11 3.3440396085E-11 2.6288913180E-11 3.4521750835E+00 8.9465547898E-02 1.4086469317E-11 1.9867968712E-11 -8.9465547898E-02 3.4521750835E+00 +62.00 3.5484034656E+00 1.2492827337E+00 2.6767120878E-11 6.5008758517E-12 1.2492827337E+00 3.5484034656E+00 -1.5970661221E-11 -1.3770404306E-11 3.4443769219E-11 2.6904615942E-11 3.3209287296E+00 -4.3499187387E-02 1.2577546256E-11 1.7511580640E-11 4.3499187387E-02 3.3209287296E+00 +63.00 3.4370260130E+00 1.1975584710E+00 2.7762612151E-11 4.7373962320E-12 1.1975584710E+00 3.4370260130E+00 -1.6743818853E-11 -1.1230082435E-11 3.5316650775E-11 2.7433672558E-11 3.2173221425E+00 -1.6685249149E-01 1.1072533004E-11 1.5183052520E-11 1.6685249149E-01 3.2173221425E+00 +64.00 3.3485942971E+00 1.1389086693E+00 2.8641824281E-11 2.9843646630E-12 1.1389086693E+00 3.3485942971E+00 -1.7444502416E-11 -8.7242140020E-12 3.6057529054E-11 2.7872814615E-11 3.1364622735E+00 -2.8031271119E-01 9.5766792517E-12 1.2889004473E-11 2.8031271119E-01 3.1364622735E+00 +65.00 3.2786568024E+00 1.0741723058E+00 2.9401106750E-11 1.2483320294E-12 1.0741723058E+00 3.2786568024E+00 -1.8069931008E-11 -6.2596464330E-12 3.6664234482E-11 2.8220745021E-11 3.0738458059E+00 -3.8368769412E-01 8.0955286306E-12 1.0635572082E-11 3.8368769412E-01 3.0738458059E+00 +66.00 3.2231521328E+00 1.0042142588E+00 3.0038810168E-11 -4.6420174804E-13 1.0042142588E+00 3.2231521328E+00 -1.8616359021E-11 -3.8426079206E-12 3.7136186955E-11 2.8475730240E-11 3.0253688704E+00 -4.7687167204E-01 6.6344982171E-12 8.4282023399E-12 4.7687167204E-01 3.0253688704E+00 +67.00 3.1784136839E+00 9.2991355627E-01 3.0552620272E-11 -2.1484785342E-12 9.2991355627E-01 3.1784136839E+00 -1.9081652466E-11 -1.4806069406E-12 3.7472683489E-11 2.8637140849E-11 2.9873318996E+00 -5.5984144698E-01 5.1975624943E-12 6.2732702781E-12 5.5984144698E-01 2.9873318996E+00 +68.00 3.1411699077E+00 8.5215202888E-01 3.0942574058E-11 -3.7976692680E-12 8.5215202888E-01 3.1411699077E+00 -1.9462507796E-11 8.2129098817E-13 3.7674677648E-11 2.8703916480E-11 2.9564398859E+00 -6.3265196587E-01 3.7903593862E-12 4.1751510453E-12 6.3265196587E-01 2.9564398859E+00 +69.00 3.1085404652E+00 7.7180351886E-01 3.1207500072E-11 -5.4064786507E-12 7.7180351886E-01 3.1085404652E+00 -1.9757906838E-11 3.0572884758E-12 3.7742564750E-11 2.8676693262E-11 2.9297983477E+00 -6.9543137239E-01 2.4170537005E-12 2.1387915547E-12 6.9543137239E-01 2.9297983477E+00 +70.00 3.0780285851E+00 6.8972378032E-01 3.1347941533E-11 -6.9697817154E-12 6.8972378032E-01 3.0780285851E+00 -1.9966175088E-11 5.2218720043E-12 3.7678131407E-11 2.8555704095E-11 2.9049053340E+00 -7.4837562629E-01 1.0818109979E-12 1.6871374121E-13 7.4837562629E-01 2.9049053340E+00 +71.00 3.0475099718E+00 6.0674118949E-01 3.1363893442E-11 -8.4830998055E-12 6.0674118949E-01 3.0475099718E+00 -2.0087148990E-11 7.3095160296E-12 3.7482926182E-11 2.8342301349E-11 2.8796398258E+00 -7.9174278093E-01 -2.1199855665E-13 -1.7304443852E-12 7.9174278093E-01 2.8796398258E+00 +72.00 3.0152186177E+00 5.2364836461E-01 3.1257119472E-11 -9.9409766494E-12 5.2364836461E-01 3.0152186177E+00 -2.0120019507E-11 9.3163357531E-12 3.7159705614E-11 2.8037685230E-11 2.8522469075E+00 -8.2584700836E-01 -1.4600664931E-12 -3.5556272079E-12 8.2584700836E-01 2.8522469075E+00 +73.00 2.9797298891E+00 4.4119477579E-01 3.1029623125E-11 -1.1339804210E-11 4.4119477579E-01 2.9797298891E+00 -2.0064868239E-11 1.1237423301E-11 3.6711861538E-11 2.7643490297E-11 2.8213200975E+00 -8.5105245955E-01 -2.6596506874E-12 -5.3030097741E-12 8.5105245955E-01 2.8213200975E+00 +74.00 2.9399412598E+00 3.6008040557E-01 3.0683143975E-11 -1.2676012446E-11 3.6008040557E-01 2.9399412598E+00 -1.9922767466E-11 1.3068357643E-11 3.6142522154E-11 2.7162099085E-11 2.7857812316E+00 -8.6776704376E-01 -3.8083040389E-12 -6.9690372275E-12 8.6776704376E-01 2.7857812316E+00 +75.00 2.8950510679E+00 2.8095050057E-01 3.0220402230E-11 -1.3944860043E-11 2.8095050057E-01 2.8950510679E+00 -1.9695202558E-11 1.4806683851E-11 3.5455285140E-11 2.6596710146E-11 2.7448582983E+00 -8.7643620662E-01 -4.9025232361E-12 -8.5518445773E-12 8.7643620662E-01 2.7448582983E+00 +76.00 2.8445356676E+00 2.0439143516E-01 2.9645513717E-11 -1.5143747240E-11 2.0439143516E-01 2.8445356676E+00 -1.9382773744E-11 1.6448515118E-11 3.4655359816E-11 2.5949174942E-11 2.6980616195E+00 -8.7753678163E-01 -5.9403802128E-12 -1.0048801149E-11 8.7753678163E-01 2.6980616195E+00 +77.00 2.7881253433E+00 1.3092768863E-01 2.8961581894E-11 -1.6269410033E-11 1.3092768863E-01 2.7881253433E+00 -1.8988404621E-11 1.7991621503E-11 3.3746833916E-11 2.5223656207E-11 2.6451587649E+00 -8.7157098338E-01 -6.9198094547E-12 -1.1458217816E-11 8.7157098338E-01 2.6451587649E+00 +78.00 2.7257793404E+00 6.1019918987E-02 2.8172722378E-11 -1.7319788497E-11 6.1019918987E-02 2.7257793404E+00 -1.8514427217E-11 1.9432947836E-11 3.2734822776E-11 2.4423332717E-11 2.5861485765E+00 -8.5906060451E-01 -7.8396585984E-12 -1.2777942133E-11 8.5906060451E-01 2.5861485765E+00 +79.00 2.6576603539E+00 -4.9359006696E-03 2.7283906940E-11 -1.8292192457E-11 -4.9359006696E-03 2.6576603539E+00 -1.7963563159E-11 2.0771081089E-11 3.1624894369E-11 2.3551999691E-11 2.5212346636E+00 -8.4054147093E-01 -8.6980699460E-12 -1.4007326775E-11 8.4054147093E-01 2.5212346636E+00 +80.00 2.5841088006E+00 -6.6608333404E-02 2.6300179720E-11 -1.9185030193E-11 -6.6608333404E-02 2.5841088006E+00 -1.7338992939E-11 2.2004328575E-11 3.0422825768E-11 2.2613514885E-11 2.4507987116E+00 -8.1655820269E-01 -9.4942622860E-12 -1.5145448294E-11 8.1655820269E-01 2.4507987116E+00 +81.00 2.5056171798E+00 -1.2372938159E-01 2.5226319456E-11 -1.9996998166E-11 -1.2372938159E-01 2.5056171798E+00 -1.6644922838E-11 2.3131262289E-11 2.9134002794E-11 2.1612534554E-11 2.3753739259E+00 -7.8765931970E-01 -1.0227920869E-11 -1.6191369822E-11 7.8765931970E-01 2.3753739259E+00 +82.00 2.4228048058E+00 -1.7609251906E-01 2.4068410754E-11 -2.0726457140E-11 -1.7609251906E-01 2.4228048058E+00 -1.5884973458E-11 2.4151682401E-11 2.7764726110E-11 2.0553260508E-11 2.2956189078E+00 -7.5439272399E-01 -1.0898029254E-11 -1.7145619347E-11 7.5439272399E-01 2.2956189078E+00 +83.00 2.3363931747E+00 -2.2354993993E-01 2.2832436839E-11 -2.1372708044E-11 -2.2354993993E-01 2.3363931747E+00 -1.5063430158E-11 2.5065317063E-11 2.6321272509E-11 1.9440213555E-11 2.2122922346E+00 -7.1730158217E-01 -1.1504541878E-11 -1.8008503373E-11 7.1730158217E-01 2.2122922346E+00 +84.00 2.2471822001E+00 -2.6600912052E-01 2.1524595520E-11 -2.1935908371E-11 -2.6600912052E-01 2.2471822001E+00 -1.4184891315E-11 2.5871579196E-11 2.4810182432E-11 1.8277816387E-11 2.1262279881E+00 -6.7692062381E-01 -1.2048276470E-11 -1.8779909736E-11 6.7692062381E-01 2.1262279881E+00 +85.00 2.1560275298E+00 -3.0342879750E-01 2.0151319403E-11 -2.2415243691E-11 -3.0342879750E-01 2.1560275298E+00 -1.3254314107E-11 2.6571674409E-11 2.3237634379E-11 1.7071151299E-11 2.0383124467E+00 -6.3377286451E-01 -1.2528937459E-11 -1.9461490659E-11 6.3377286451E-01 2.0383124467E+00 +86.00 2.0638191270E+00 -3.3581446979E-01 1.8719494806E-11 -2.2811267438E-11 -3.3581446979E-01 2.0638191270E+00 -1.2276483835E-11 2.7166193002E-11 2.1610522699E-11 1.5824593580E-11 1.9494621291E+00 -5.8836675469E-01 -1.2947477084E-11 -2.0054295846E-11 5.8836675469E-01 1.9494621291E+00 +87.00 1.9714612745E+00 -3.6321353450E-01 1.7235485505E-11 -2.3124690198E-11 -3.6321353450E-01 1.9714612745E+00 -1.1257183438E-11 2.7656182977E-11 1.9934938089E-11 1.4543459495E-11 1.8606033461E+00 -5.4119374873E-01 -1.3305182653E-11 -2.0559494315E-11 5.4119374873E-01 1.8606033461E+00 +88.00 1.8798541331E+00 -3.8571016733E-01 1.5706622990E-11 -2.3356136493E-11 -3.8571016733E-01 1.8798541331E+00 -1.0201477436E-11 2.8043495834E-11 1.8217782740E-11 1.3232232519E-11 1.7726533893E+00 -4.9272628311E-01 -1.3602821634E-11 -2.0979348650E-11 4.9272628311E-01 1.7726533893E+00 +89.00 1.7898769590E+00 -4.0342005672E-01 1.4139955452E-11 -2.3507171726E-11 -4.0342005672E-01 1.7898769590E+00 -9.1149247670E-12 2.8329732905E-11 1.6465730474E-11 1.1895570294E-11 1.6865034561E+00 -4.4341614601E-01 -1.3842243699E-11 -2.1315570724E-11 4.4341614601E-01 1.6865034561E+00 +90.00 1.7023730595E+00 -4.1648509732E-01 1.2542189505E-11 -2.3579133428E-11 -4.1648509732E-01 1.7023730595E+00 -8.0036604283E-12 2.8517205831E-11 1.4684716834E-11 1.0538794316E-11 1.6030033839E+00 -3.9369321662E-01 -1.4025058892E-11 -2.1570455667E-11 3.9369321662E-01 1.6030033839E+00 +91.00 1.6181365421E+00 -4.2506814371E-01 1.0920947372E-11 -2.3573757175E-11 -4.2506814371E-01 1.6181365421E+00 -6.8728681124E-12 2.8608595200E-11 1.2881746375E-11 9.1659414858E-12 1.5229482368E+00 -3.4396454764E-01 -1.4152871961E-11 -2.1746898805E-11 3.4396454764E-01 1.5229482368E+00 +92.00 1.5379008852E+00 -4.2934791830E-01 9.2830795522E-12 -2.3493249872E-11 -4.2934791830E-01 1.5379008852E+00 -5.7287381450E-12 2.8606447446E-11 1.1062799613E-11 7.7819902424E-12 1.4470667674E+00 -2.9461376123E-01 -1.4228036033E-11 -2.1847244522E-11 2.9461376123E-01 1.4470667674E+00 +93.00 1.4623293403E+00 -4.2951415983E-01 7.6358614962E-12 -2.3339756829E-11 -4.2951415983E-01 1.4623293403E+00 -4.5768264401E-12 2.8514139078E-11 9.2342581618E-12 6.3911876496E-12 1.3760117474E+00 -2.4600072578E-01 -1.4252458633E-11 -2.1874863641E-11 2.4600072578E-01 1.3760117474E+00 +94.00 1.3920071504E+00 -4.2576308928E-01 5.9862756897E-12 -2.3116104945E-11 -4.2576308928E-01 1.3920071504E+00 -3.4230117993E-12 2.8334703589E-11 7.4021590163E-12 4.9979139384E-12 1.3103521435E+00 -1.9846147899E-01 -1.4228899541E-11 -2.1832476481E-11 1.9846147899E-01 1.3103521435E+00 +95.00 1.3274355504E+00 -4.1829326043E-01 4.3410063002E-12 -2.2824728160E-11 -4.1829326043E-01 1.3274355504E+00 -2.2731866863E-12 2.8071948085E-11 5.5719965548E-12 3.6066807709E-12 1.2505670921E+00 -1.5230836147E-01 -1.4159485999E-11 -2.1723699936E-11 1.5230836147E-01 1.2505670921E+00 +96.00 1.2690274991E+00 -4.0730185098E-01 2.7071764562E-12 -2.2468827977E-11 -4.0730185098E-01 1.2690274991E+00 -1.1327163567E-12 2.7729523529E-11 3.7499307840E-12 2.2211011069E-12 1.1970416103E+00 -1.0783032451E-01 -1.4047062289E-11 -2.1551824428E-11 1.0783032451E-01 1.1970416103E+00 +97.00 1.2171050722E+00 -3.9298143926E-01 1.0912559021E-12 -2.2051635528E-11 -3.9298143926E-01 1.2171050722E+00 -7.3961692133E-15 2.7311270825E-11 1.9411848562E-12 8.4536787011E-13 1.1500639635E+00 -6.5293375945E-02 -1.3894521461E-11 -2.1320210559E-11 6.5293375945E-02 1.1500639635E+00 +98.00 1.1718984338E+00 -3.7551729944E-01 -5.0031622919E-13 -2.1576030640E-11 -3.7551729944E-01 1.1718984338E+00 1.0974527528E-12 2.6821775106E-11 1.5100365554E-13 -5.1687004179E-13 1.1098245974E+00 -2.4941128968E-02 -1.3704066205E-11 -2.1033156822E-11 2.4941128968E-02 1.1098245974E+00 +99.00 1.1335462904E+00 -3.5508523699E-01 -2.0613112231E-12 -2.1045831166E-11 -3.5508523699E-01 1.1335462904E+00 2.1766276091E-12 2.6264878773E-11 -1.6155396681E-12 -1.8621801191E-12 1.0764165309E+00 1.3004579805E-02 -1.3479116414E-11 -2.0693824784E-11 -1.3004579805E-02 1.0764165309E+00 +100.00 1.1020977190E+00 -3.3184997390E-01 -3.5857809825E-12 -2.0464479829E-11 -3.3184997390E-01 1.1020977190E+00 3.2249272877E-12 2.5645146485E-11 -3.3537591779E-12 -3.1870745650E-12 1.0498370960E+00 4.8343034669E-02 -1.3222417560E-11 -2.0306243296E-11 -4.8343034669E-02 1.0498370960E+00 +101.00 1.0775152529E+00 -3.0596408244E-01 -5.0679825125E-12 -1.9835783283E-11 -3.0596408244E-01 1.0775152529E+00 4.2376003589E-12 2.4967017631E-11 -5.0590822561E-12 -4.4885431497E-12 1.0299909053E+00 8.0893976499E-02 -1.2937103667E-11 -1.9874164787E-11 -8.0893976499E-02 1.0299909053E+00 +102.00 1.0596791015E+00 -2.7756745532E-01 -6.5025201130E-12 -1.9163230054E-11 -2.7756745532E-01 1.0596791015E+00 5.2099529270E-12 2.4235318605E-11 -6.7272812834E-12 -5.7636147023E-12 1.0166939208E+00 1.1049695575E-01 -1.2625820147E-11 -1.9401817360E-11 -1.1049695575E-01 1.0166939208E+00 +103.00 1.0483923741E+00 -2.4678728981E-01 -7.8840773197E-12 -1.8450924947E-11 -2.4678728981E-01 1.0483923741E+00 6.1378350605E-12 2.3454384333E-11 -8.3541456971E-12 -7.0098233131E-12 1.0096784958E+00 1.3701072532E-01 -1.2291989536E-11 -1.8892670306E-11 -1.3701072532E-01 1.0096784958E+00 +104.00 1.0433871741E+00 -2.1373855461E-01 -9.2082935581E-12 -1.7702494446E-11 -2.1373855461E-01 1.0433871741E+00 7.0167214461E-12 2.2629167116E-11 -9.9364745276E-12 -8.2241714913E-12 1.0085992594E+00 1.6031269213E-01 -1.1938227288E-11 -1.8351032790E-11 -1.6031269213E-01 1.0085992594E+00 +105.00 1.0443314277E+00 -1.7852489969E-01 -1.0470406737E-11 -1.6921971324E-11 -1.7852489969E-01 1.0443314277E+00 7.8431057243E-12 2.1764253806E-11 -1.1470459028E-11 -9.4047500956E-12 1.0130397143E+00 1.8029844233E-01 -1.1567739333E-11 -1.7780585469E-11 -1.8029844233E-01 1.0130397143E+00 +106.00 1.0508363121E+00 -1.4123996221E-01 -1.1666443977E-11 -1.6113005518E-11 -1.4123996221E-01 1.0508363121E+00 8.6134364433E-12 2.0864514114E-11 -1.2953026495E-11 -1.0549459180E-11 1.0225194187E+00 1.9688135102E-01 -1.1183180041E-11 -1.7185391963E-11 -1.9688135102E-01 1.0225194187E+00 +107.00 1.0624641462E+00 -1.0196901575E-01 -1.2792527539E-11 -1.5279902520E-11 -1.0196901575E-01 1.0624641462E+00 9.3245830444E-12 1.9934336718E-11 -1.4381229066E-11 -1.1656452267E-11 1.0365016270E+00 2.0999228323E-01 -1.0787939422E-11 -1.6568885130E-11 -2.0999228323E-01 1.0365016270E+00 +108.00 1.0787366128E+00 -6.0790905167E-02 -1.3845525936E-11 -1.4426176459E-11 -6.0790905167E-02 1.0787366128E+00 9.9735629693E-12 1.8978591592E-11 -1.5752620560E-11 -1.2723985425E-11 1.0544012697E+00 2.1957938880E-01 -1.0384441376E-11 -1.5935106324E-11 -2.1957938880E-01 1.0544012697E+00 +109.00 1.0991431819E+00 -1.7780205939E-02 -1.4822468228E-11 -1.3555787606E-11 -1.7780205939E-02 1.0991431819E+00 1.0557847082E-11 1.8001777628E-11 -1.7064883990E-11 -1.3750597744E-11 1.0755931543E+00 2.2560798981E-01 -9.9756139142E-12 -1.5287622152E-11 -2.2560798981E-01 1.0755931543E+00 +110.00 1.1231496126E+00 2.6990455406E-02 -1.5720772421E-11 -1.2672316955E-11 2.6990455406E-02 1.1231496126E+00 1.1075386503E-11 1.7008424904E-11 -1.8315904308E-11 -1.4735178438E-11 1.0994202793E+00 2.2806055550E-01 -9.5639837647E-12 -1.4630005259E-11 -2.2806055550E-01 1.0994202793E+00 +111.00 1.1502064133E+00 7.3447984126E-02 -1.6538161523E-11 -1.1779599407E-11 7.3447984126E-02 1.1502064133E+00 1.1524438201E-11 1.6002948772E-11 -1.9503825068E-11 -1.5676748480E-11 1.1252021577E+00 2.2693675573E-01 -9.1523289886E-12 -1.3965714153E-11 -2.2693675573E-01 1.1252021577E+00 +112.00 1.1797571518E+00 1.2151636753E-01 -1.7273207854E-11 -1.0881075007E-11 1.2151636753E-01 1.1797571518E+00 1.1903279855E-11 1.4989569645E-11 -2.0627404128E-11 -1.6574194322E-11 1.1522430539E+00 2.2225358111E-01 -8.7429380819E-12 -1.3298068152E-11 -2.2225358111E-01 1.1522430539E+00 +113.00 1.2112465100E+00 1.7111425534E-01 -1.7924483895E-11 -9.9800810169E-12 1.7111425534E-01 1.2112465100E+00 1.2210884357E-11 1.3972707198E-11 -2.1685277739E-11 -1.7426961118E-11 1.1798400473E+00 2.1404551474E-01 -8.3381058942E-12 -1.2630495237E-11 -2.1404551474E-01 1.1798400473E+00 +114.00 1.2441279894E+00 2.2215263033E-01 -1.8490628310E-11 -9.0802826175E-12 2.2215263033E-01 1.2441279894E+00 1.2446988076E-11 1.2955987714E-11 -2.2676142472E-11 -1.8234887933E-11 1.2072908414E+00 2.0236473800E-01 -7.9404138146E-12 -1.1965648043E-11 -2.0236473800E-01 1.2072908414E+00 +115.00 1.2778711816E+00 2.7453262585E-01 -1.8971743771E-11 -8.1846072608E-12 2.7453262585E-01 1.2778711816E+00 1.2610552038E-11 1.1943542094E-11 -2.3599727933E-11 -1.8997121324E-11 1.2339012480E+00 1.8728135080E-01 -7.5516390097E-12 -1.1306774712E-11 -1.8728135080E-01 1.2339012480E+00 +116.00 1.3119685279E+00 3.2814354239E-01 -1.9367551686E-11 -7.2962474556E-12 3.2814354239E-01 1.3119685279E+00 1.2701814413E-11 1.0938999776E-11 -2.4455424895E-11 -1.9713730193E-11 1.2589922829E+00 1.6888358514E-01 -7.1739036532E-12 -1.0656550219E-11 -1.6888358514E-01 1.2589922829E+00 +117.00 1.3459415016E+00 3.8286110998E-01 -1.9677794335E-11 -6.4180149678E-12 3.8286110998E-01 1.3459415016E+00 1.2721575144E-11 9.9459497660E-12 -2.5242532282E-11 -2.0385044442E-11 1.2819068180E+00 1.4727798949E-01 -6.8090133726E-12 -1.0017581899E-11 -1.4727798949E-01 1.2819068180E+00 +118.00 1.3793461574E+00 4.3854603746E-01 -1.9903571162E-11 -5.5528456073E-12 4.3854603746E-01 1.3793461574E+00 1.2670075062E-11 8.9674962152E-12 -2.5961359025E-11 -2.1010831539E-11 1.3020157427E+00 1.2258956122E-01 -6.4587272599E-12 -9.3921685143E-12 -1.2258956122E-01 1.3020157427E+00 +119.00 1.4117780006E+00 4.9504288288E-01 -2.0046184659E-11 -4.7033737377E-12 4.9504288288E-01 1.4117780006E+00 1.2548119351E-11 8.0067516311E-12 -2.6612265803E-11 -2.1591248357E-11 1.3187235961E+00 9.4961803959E-02 -6.1246012714E-12 -8.7825709982E-12 -9.4961803959E-02 1.3187235961E+00 +120.00 1.4428761432E+00 5.5217927271E-01 -2.0106456048E-11 -3.8712207042E-12 5.5217927271E-01 1.4428761432E+00 1.2357567521E-11 7.0674067439E-12 -2.7195154735E-11 -2.2127072146E-11 1.3314736383E+00 6.4556687425E-02 -5.8075039482E-12 -8.1913374956E-12 -6.4556687425E-02 1.3314736383E+00 +121.00 1.4723267178E+00 6.0976549000E-01 -2.0086598995E-11 -3.0594884875E-12 6.0976549000E-01 1.4723267178E+00 1.2099613795E-11 6.1513641552E-12 -2.7710946513E-11 -2.2618463339E-11 1.3397523374E+00 3.1554488115E-02 -5.5092656180E-12 -7.6198219448E-12 -3.1554488115E-02 1.3397523374E+00 +122.00 1.4998655372E+00 6.6759444461E-01 -1.9987886154E-11 -2.2699208561E-12 6.6759444461E-01 1.4998655372E+00 1.1777000440E-11 5.2613721053E-12 -2.8159832898E-11 -2.3066547690E-11 1.3430932550E+00 -3.8465092453E-03 -5.2307283089E-12 -7.0698463462E-12 3.8465092453E-03 1.3430932550E+00 +123.00 1.5252799901E+00 7.2544203105E-01 -1.9813315383E-11 -1.5043362754E-12 7.2544203105E-01 1.5252799901E+00 1.1391419631E-11 4.3997591627E-12 -2.8543140986E-11 -2.3471702903E-11 1.3410803198E+00 -4.1430467678E-02 -4.9727520596E-12 -6.5429466633E-12 4.1430467678E-02 1.3410803198E+00 +124.00 1.5484101790E+00 7.8306787241E-01 -1.9565883065E-11 -7.6437470257E-13 7.8306787241E-01 1.5484101790E+00 1.0945041665E-11 3.5686512707E-12 -2.8862079064E-11 -2.3834517139E-11 1.3333504861E+00 -8.0964627196E-02 -4.7360909719E-12 -6.0404568068E-12 8.0964627196E-02 1.3333504861E+00 +125.00 1.5691493104E+00 8.4021644192E-01 -1.9247702881E-11 -5.1693824167E-14 8.4021644192E-01 1.5691493104E+00 1.0441545856E-11 2.7696613925E-12 -2.9117376089E-11 -2.4156442453E-11 1.3195957788E+00 -1.2220012038E-01 -4.5213673218E-12 -5.5633448959E-12 1.2220012038E-01 1.3195957788E+00 +126.00 1.5874433579E+00 8.9661854670E-01 -1.8862942093E-11 6.3309574209E-13 8.9661854670E-01 1.5874433579E+00 9.8830203589E-12 2.0051508773E-12 -2.9310940647E-11 -2.4437887700E-11 1.2995647330E+00 -1.6487298437E-01 -4.3287063362E-12 -5.1129161678E-12 1.6487298437E-01 1.2995647330E+00 +127.00 1.6032900263E+00 9.5199315270E-01 -1.8413811097E-11 1.2875000896E-12 9.5199315270E-01 1.6032900263E+00 9.2739313524E-12 1.2751369826E-12 -2.9443462036E-11 -2.4680592250E-11 1.2730632395E+00 -2.0870537576E-01 -4.1590191809E-12 -4.6892371339E-12 2.0870537576E-01 1.2730632395E+00 +128.00 1.6167370517E+00 1.0060495235E+00 -1.7905024827E-11 1.9122287723E-12 1.0060495235E+00 1.6167370517E+00 8.6167692553E-12 5.8238756072E-13 -2.9517239868E-11 -2.4885078575E-11 1.2399548165E+00 -2.5340699177E-01 -4.0116095478E-12 -4.2935625825E-12 2.5340699177E-01 1.2399548165E+00 +129.00 1.6278798779E+00 1.0584896411E+00 -1.7340379432E-11 2.5056095401E-12 1.0584896411E+00 1.6278798779E+00 7.9152337885E-12 -7.3044679562E-14 -2.9533819369E-11 -2.5052590627E-11 1.2001603257E+00 -2.9867669660E-01 -3.8869100389E-12 -3.9257715838E-12 2.9867669660E-01 1.2001603257E+00 +130.00 1.6368587586E+00 1.1090108726E+00 -1.6724018119E-11 3.0664124562E-12 1.1090108726E+00 1.6368587586E+00 7.1730656994E-12 -6.9103899886E-13 -2.9494931332E-11 -2.5184406754E-11 1.1536571615E+00 -3.4420434882E-01 -3.7850324421E-12 -3.5857830852E-12 3.4420434882E-01 1.1536571615E+00 +131.00 1.6438553348E+00 1.1573088416E+00 -1.6059246107E-11 3.5961877062E-12 1.1573088416E+00 1.6438553348E+00 6.3950787500E-12 -1.2691219912E-12 -2.9402275717E-11 -2.5281847019E-11 1.1004779412E+00 -3.8967282122E-01 -3.7046533409E-12 -3.2744825991E-12 3.8967282122E-01 1.1004779412E+00 +132.00 1.6490887462E+00 1.2030804638E+00 -1.5351410953E-11 4.0930488579E-12 1.2030804638E+00 1.6490887462E+00 5.5844143562E-12 -1.8085825777E-12 -2.9258079818E-11 -2.5346042064E-11 1.0407087288E+00 -4.3476020083E-01 -3.6461474539E-12 -2.9909137473E-12 4.3476020083E-01 1.0407087288E+00 +133.00 1.6528113359E+00 1.2460270985E+00 -1.4604541719E-11 4.5577347355E-12 1.2460270985E+00 1.6528113359E+00 4.7456073389E-12 -2.3084875271E-12 -2.9064262278E-11 -2.5378264908E-11 9.7448682849E-01 -4.7914215337E-01 -3.6084628946E-12 -2.7350201942E-12 4.7914215337E-01 9.7448682849E-01 +134.00 1.6553040107E+00 1.2858577726E+00 -1.3823322677E-11 4.9904114316E-12 1.2858577726E+00 1.6553040107E+00 3.8828207261E-12 -2.7687324614E-12 -2.8823018100E-11 -2.5379776841E-11 9.0199818437E-01 -5.2249443243E-01 -3.5909410081E-12 -2.5063673728E-12 5.2249443243E-01 9.0199818437E-01 +135.00 1.6568713236E+00 1.3222924291E+00 -1.3012022140E-11 5.3902962479E-12 1.3222924291E+00 1.6568713236E+00 3.0006737434E-12 -3.1905773923E-12 -2.8536210885E-11 -2.5352156029E-11 8.2347442792E-01 -5.6449551056E-01 -3.5928976343E-12 -2.3039624441E-12 5.6449551056E-01 8.2347442792E-01 +136.00 1.6578363435E+00 1.3550651522E+00 -1.2176384023E-11 5.7589231091E-12 1.3550651522E+00 1.6578363435E+00 2.1024202502E-12 -3.5731524507E-12 -2.8206490902E-11 -2.5296144330E-11 7.3918961356E-01 -6.0482930660E-01 -3.6132893181E-12 -2.1272368993E-12 6.0482930660E-01 7.3918961356E-01 +137.00 1.6585353807E+00 1.3839273260E+00 -1.1320190801E-11 6.0957086733E-12 1.3839273260E+00 1.6585353807E+00 1.1933404957E-12 -3.9181021742E-12 -2.7835676334E-11 -2.5213602792E-11 6.4945668609E-01 -6.4318798044E-01 -3.6511369062E-12 -1.9751238250E-12 6.4318798044E-01 6.4945668609E-01 +138.00 1.6593126336E+00 1.4086506790E+00 -1.0448001133E-11 6.4025307547E-12 1.4086506790E+00 1.6593126336E+00 2.7782690947E-13 -4.2248143973E-12 -2.7426185617E-11 -2.5105464363E-11 5.5462372389E-01 -6.7927476452E-01 -3.7049045151E-12 -1.8468218184E-12 6.7927476452E-01 5.5462372389E-01 +139.00 1.6605148249E+00 1.4290301757E+00 -9.5648388799E-12 6.6789722145E-12 1.4290301757E+00 1.6605148249E+00 -6.4013904188E-13 -4.4952091724E-12 -2.6980137062E-11 -2.4973181192E-11 4.5507000254E-01 -7.1280679943E-01 -3.7737121913E-12 -1.7409168780E-12 7.1280679943E-01 4.5507000254E-01 +140.00 1.6624858898E+00 1.4448867139E+00 -8.6756549729E-12 6.9263077174E-12 1.4448867139E+00 1.6624858898E+00 -1.5566565096E-12 -4.7297651086E-12 -2.6499914973E-11 -2.4817858464E-11 3.5120192407E-01 -7.4351793935E-01 -3.8561820636E-12 -1.6560992188E-12 7.4351793935E-01 3.5120192407E-01 +141.00 1.6655617822E+00 1.4560695920E+00 -7.7841672639E-12 7.1458787051E-12 1.4560695920E+00 1.6655617822E+00 -2.4666533202E-12 -4.9290988598E-12 -2.5987843187E-11 -2.4640776445E-11 2.4344885665E-01 -7.7116149261E-01 -3.9507702678E-12 -1.5913098766E-12 7.7116149261E-01 2.4344885665E-01 +142.00 1.6700654566E+00 1.4624587146E+00 -6.8956107110E-12 7.3376374849E-12 1.4624587146E+00 1.6700654566E+00 -3.3668568313E-12 -5.0953736635E-12 -2.5445949753E-11 -2.4443227186E-11 1.3225892919E-01 -7.9551286181E-01 -4.0562236334E-12 -1.5447137194E-12 7.9551286181E-01 1.3225892919E-01 +143.00 1.6763020842E+00 1.4639665069E+00 -6.0144544715E-12 7.5034824550E-12 1.4639665069E+00 1.6763020842E+00 -4.2533428807E-12 -5.2290051275E-12 -2.4876729427E-11 -2.4226271147E-11 1.8094824574E-02 -8.1637204853E-01 -4.1710773876E-12 -1.5148757768E-12 8.1637204853E-01 1.8094824574E-02 +144.00 1.6845545565E+00 1.4605395155E+00 -5.1441711173E-12 7.6437677308E-12 1.4605395155E+00 1.6845545565E+00 -5.1214952792E-12 -5.3320306108E-12 -2.4282138013E-11 -2.3991178596E-11 -9.8570385985E-02 -8.3356598809E-01 -4.2935897445E-12 -1.5003571821E-12 8.3356598809E-01 -9.8570385985E-02 +145.00 1.6950793254E+00 1.4521596734E+00 -4.2899008443E-12 7.7607244009E-12 1.4521596734E+00 1.6950793254E+00 -5.9685731405E-12 -5.4047810058E-12 -2.3664667684E-11 -2.3738815460E-11 -2.1725732671E-01 -8.4695068108E-01 -4.4225992476E-12 -1.4993171277E-12 8.4695068108E-01 -2.1725732671E-01 +146.00 1.7081026257E+00 1.4388452174E+00 -3.4545883840E-12 7.8541693518E-12 1.4388452174E+00 1.7081026257E+00 -6.7900266049E-12 -5.4500671856E-12 -2.3026150657E-11 -2.3470546948E-11 -3.3748427999E-01 -8.5641309023E-01 -4.5561634950E-12 -1.5103649794E-12 8.5641309023E-01 -3.3748427999E-01 +147.00 1.7238171182E+00 1.4206512439E+00 -2.6426163696E-12 7.9262227379E-12 1.4206512439E+00 1.7238171182E+00 -7.5830494847E-12 -5.4684797800E-12 -2.2368925645E-11 -2.3187180697E-11 -4.5877099152E-01 -8.6187277325E-01 -4.6929581417E-12 -1.5316084262E-12 8.6187277325E-01 -4.5877099152E-01 +148.00 1.7423789888E+00 1.3976699010E+00 -1.8576217550E-12 7.9775908140E-12 1.3976699010E+00 1.7423789888E+00 -8.3444309655E-12 -5.4620716391E-12 -2.1694884563E-11 -2.2889814265E-11 -5.8064228359E-01 -8.6328322512E-01 -4.8314253156E-12 -1.5614514605E-12 8.6328322512E-01 -5.8064228359E-01 +149.00 1.7639055334E+00 1.3700302126E+00 -1.1028041187E-12 8.0095424405E-12 1.3700302126E+00 1.7639055334E+00 -9.0710038435E-12 -5.4323558686E-12 -2.1006124684E-11 -2.2579362372E-11 -7.0263144543E-01 -8.6063290621E-01 -4.9698967843E-12 -1.5981855891E-12 8.6063290621E-01 -7.0263144543E-01 +150.00 1.7884732502E+00 1.3378975395E+00 -3.8165595142E-13 8.0242091641E-12 1.3378975395E+00 1.7884732502E+00 -9.7602004925E-12 -5.3800299582E-12 -2.0304777961E-11 -2.2256490651E-11 -8.2428337252E-01 -8.5394593632E-01 -5.1072601977E-12 -1.6399331339E-12 8.5394593632E-01 -8.2428337252E-01 +151.00 1.8161164576E+00 1.3014726845E+00 3.0314072826E-13 8.0210619675E-12 1.3014726845E+00 1.8161164576E+00 -1.0409184906E-11 -5.3084007942E-12 -1.9592357651E-11 -2.1922447630E-11 -9.4515743031E-01 -8.4328243845E-01 -5.2414867454E-12 -1.6854885251E-12 8.4328243845E-01 -9.4515743031E-01 +152.00 1.8468264492E+00 1.2609906518E+00 9.4868183540E-13 8.0027613154E-12 1.2609906518E+00 1.8468264492E+00 -1.1015710270E-11 -5.2175992420E-12 -1.8871042455E-11 -2.1577605530E-11 -1.0648300216E+00 -8.2873852004E-01 -5.3716510812E-12 -1.7328724565E-12 8.2873852004E-01 -1.0648300216E+00 +153.00 1.8805511903E+00 1.2167190773E+00 1.5525612306E-12 7.9702253419E-12 1.2167190773E+00 1.8805511903E+00 -1.1577590636E-11 -5.1094115342E-12 -1.8142579685E-11 -2.1222724461E-11 -1.1828968404E+00 -8.1044588412E-01 -5.4963002566E-12 -1.7805149230E-12 8.1044588412E-01 -1.1828968404E+00 +154.00 1.9171955551E+00 1.1689563461E+00 2.1125463570E-12 7.9242089157E-12 1.1689563461E+00 1.9171955551E+00 -1.2092948737E-11 -4.9858355535E-12 -1.7408640179E-11 -2.0858624271E-11 -1.2989747996E+00 -7.8857106689E-01 -5.6140675440E-12 -1.8271089379E-12 7.8857106689E-01 -1.2989747996E+00 +155.00 1.9566220985E+00 1.1180294202E+00 2.6263249021E-12 7.8654928735E-12 1.1180294202E+00 1.9566220985E+00 -1.2560406358E-11 -4.8485986596E-12 -1.6670559533E-11 -2.0485975456E-11 -1.4127036230E+00 -7.6331430306E-01 -5.7236326546E-12 -1.8712273404E-12 7.6331430306E-01 -1.4127036230E+00 +156.00 1.9986523475E+00 1.0642913987E+00 3.0921948908E-12 7.7963083188E-12 1.0642913987E+00 1.9986523475E+00 -1.2978591203E-11 -4.6980525687E-12 -1.5930230855E-11 -2.0105114804E-11 -1.5237470984E+00 -7.3490802486E-01 -5.8244260997E-12 -1.9110175655E-12 7.3490802486E-01 -1.5237470984E+00 +157.00 2.0430685967E+00 1.0081188372E+00 3.5091581403E-12 7.7161258897E-12 1.0081188372E+00 2.0430685967E+00 -1.3345958485E-11 -4.5371354296E-12 -1.5189007642E-11 -1.9716702710E-11 -1.6317939899E+00 -7.0361500515E-01 -5.9145532808E-12 -1.9460072264E-12 7.0361500515E-01 -1.6317939899E+00 +158.00 2.0896161804E+00 9.4990885445E-01 3.8755343539E-12 7.6267852116E-12 9.4990885445E-01 2.0896161804E+00 -1.3662044758E-11 -4.3663090755E-12 -1.4448214911E-11 -1.9321089000E-11 -1.7365586143E+00 -6.6972615957E-01 -5.9936369923E-12 -1.9744926163E-12 6.6972615957E-01 -1.7365586143E+00 +159.00 2.1380061944E+00 8.9007605470E-01 4.1904473405E-12 7.5293292363E-12 8.9007605470E-01 2.1380061944E+00 -1.3926265696E-11 -4.1867449883E-12 -1.3709245409E-11 -1.8918675166E-11 -1.8377810888E+00 -6.3355802705E-01 -6.0609348971E-12 -1.9952778327E-12 6.3355802705E-01 -1.8377810888E+00 +160.00 2.1879186326E+00 8.2904929669E-01 4.4534363315E-12 7.4241890932E-12 8.2904929669E-01 2.1879186326E+00 -1.4138093373E-11 -4.0000679269E-12 -1.2973349641E-11 -1.8509742453E-11 -1.9352272634E+00 -5.9544995205E-01 -6.1154547335E-12 -2.0076281024E-12 5.9544995205E-01 -1.9352272634E+00 +161.00 2.2390058994E+00 7.6726834010E-01 4.6636932376E-12 7.3119014720E-12 7.6726834010E-01 2.2390058994E+00 -1.4297834868E-11 -3.8076437499E-12 -1.2241335543E-11 -1.8094807229E-11 -2.0286883514E+00 -5.5576099587E-01 -6.1564991935E-12 -2.0107273924E-12 5.5576099587E-01 -2.0286883514E+00 +162.00 2.2908966558E+00 7.0518040084E-01 4.8215151382E-12 7.1939302657E-12 7.0518040084E-01 2.2908966558E+00 -1.4405365924E-11 -3.6098871891E-12 -1.1514706171E-11 -1.7673794379E-11 -2.1179802799E+00 -5.1486660772E-01 -6.1840211178E-12 -2.0034419587E-12 5.1486660772E-01 -2.1179802799E+00 +163.00 2.3431999526E+00 6.4323664658E-01 4.9267816041E-12 7.0699720173E-12 6.4323664658E-01 2.3431999526E+00 -1.4461256403E-11 -3.4086639457E-12 -1.0794015529E-11 -1.7247035788E-11 -2.2029427808E+00 -4.7315508963E-01 -6.1970253588E-12 -1.9856727835E-12 4.7315508963E-01 -2.2029427808E+00 +164.00 2.3955096019E+00 5.8188866357E-01 4.9802354135E-12 6.9413920485E-12 5.8188866357E-01 2.3955096019E+00 -1.4466049476E-11 -3.2041401477E-12 -1.0080568994E-11 -1.6814443341E-11 -2.2834382498E+00 -4.3102389194E-01 -6.1957699325E-12 -1.9563651537E-12 4.3102389194E-01 -2.2834382498E+00 +165.00 2.4474087346E+00 5.2158492554E-01 4.9820891465E-12 6.8077428016E-12 5.2158492554E-01 2.4474087346E+00 -1.4421020735E-11 -2.9980732549E-12 -9.3746304014E-12 -1.6376416591E-11 -2.3593503998E+00 -3.8887577833E-01 -6.1794603798E-12 -1.9157539913E-12 3.8887577833E-01 -2.3593503998E+00 +166.00 2.4984744913E+00 4.6276729415E-01 4.9335316479E-12 6.6704520644E-12 4.6276729415E-01 2.4984744913E+00 -1.4327137785E-11 -2.7903020145E-12 -8.6772524961E-12 -1.5932681335E-11 -2.4305827409E+00 -3.4711490146E-01 -6.1488181187E-12 -1.8628842668E-12 3.4711490146E-01 -2.4305827409E+00 +167.00 2.5482827897E+00 4.0586758013E-01 4.8356691410E-12 6.5292651285E-12 4.0586758013E-01 2.5482827897E+00 -1.4185921354E-11 -2.5820589549E-12 -7.9889178342E-12 -1.5483357969E-11 -2.4970569177E+00 -3.0614283140E-01 -6.1034403910E-12 -1.7980024220E-12 3.0614283140E-01 -2.4970569177E+00 +168.00 2.5964131157E+00 3.5130419225E-01 4.6899786909E-12 6.3844947033E-12 3.5130419225E-01 2.5964131157E+00 -1.3998912191E-11 -2.3739847894E-12 -7.3102133457E-12 -1.5028271055E-11 -2.5587109391E+00 -2.6635458000E-01 -6.0435383897E-12 -1.7211386039E-12 2.6635458000E-01 -2.5587109391E+00 +169.00 2.6424532798E+00 2.9947890073E-01 4.4979137888E-12 6.2366133019E-12 2.9947890073E-01 2.6424532798E+00 -1.3768207568E-11 -2.1662982857E-12 -6.6414505863E-12 -1.4567482620E-11 -2.6154973330E+00 -2.2813466469E-01 -5.9696389686E-12 -1.6320904973E-12 2.2813466469E-01 -2.6154973330E+00 +170.00 2.6860040848E+00 2.5077373938E-01 4.2615770141E-12 6.0856406172E-12 2.5077373938E-01 2.6860040848E+00 -1.3495606418E-11 -1.9596102928E-12 -5.9831870211E-12 -1.4100615746E-11 -2.6673812633E+00 -1.9185325498E-01 -5.8820164436E-12 -1.5312363228E-12 1.9185325498E-01 -2.6673812633E+00 +171.00 2.7266838511E+00 2.0554806985E-01 3.9829873619E-12 5.9314427172E-12 2.0554806985E-01 2.7266838511E+00 -1.3183444559E-11 -1.7545715396E-12 -5.3356560565E-12 -1.3627559990E-11 -2.7143386420E+00 -1.5786244412E-01 -5.7809729100E-12 -1.4191591637E-12 1.5786244412E-01 -2.7143386420E+00 +172.00 2.7641327459E+00 1.6413582917E-01 3.6641080156E-12 5.7744865266E-12 1.6413582917E-01 2.7641327459E+00 -1.2834424811E-11 -1.5510340213E-12 -4.6988039658E-12 -1.3148304199E-11 -2.7563542709E+00 -1.2649268733E-01 -5.6675092089E-12 -1.2958783158E-12 1.2649268733E-01 -2.7563542709E+00 +173.00 2.7980168681E+00 1.2684298015E-01 3.3077485394E-12 5.6143569159E-12 1.2684298015E-01 2.7980168681E+00 -1.2450875273E-11 -1.3496253101E-12 -4.0730802041E-12 -1.2662359773E-11 -2.7934200469E+00 -9.8049446229E-02 -5.5419136156E-12 -1.1623310235E-12 9.8049446229E-02 -2.7934200469E+00 +174.00 2.8280320399E+00 9.3945182564E-02 2.9165014001E-12 5.4512387104E-12 9.3945182564E-02 2.8280320399E+00 -1.2035582355E-11 -1.1503421005E-12 -3.4585316953E-12 -1.2169454473E-11 -2.8255332619E+00 -7.2810076716E-02 -5.4051853066E-12 -1.0190157936E-12 7.2810076716E-02 -2.8255332619E+00 +175.00 2.8539072632E+00 6.5685700886E-02 2.4929965107E-12 5.2851627471E-12 6.5685700886E-02 2.8539072632E+00 -1.1591618929E-11 -9.5309105193E-13 -2.8550082216E-12 -1.1669445243E-11 -2.8526950264E+00 -5.1020995251E-02 -5.2582920028E-12 -8.6648112109E-13 5.1020995251E-02 -2.8526950264E+00 +176.00 2.8754077989E+00 4.2273562648E-02 2.0402599447E-12 5.1157645172E-12 4.2273562648E-02 2.8754077989E+00 -1.1121941549E-11 -7.5817088467E-13 -2.2625314420E-12 -1.1161948421E-11 -2.8749088445E+00 -3.2895155126E-02 -5.1019125283E-12 -7.0580952349E-13 3.2895155126E-02 -2.8749088445E+00 +177.00 2.8923378362E+00 2.3881979638E-02 1.5613475597E-12 4.9430856805E-12 2.3881979638E-02 2.8923378362E+00 -1.0629753218E-11 -5.6546149237E-13 -1.6809762951E-12 -1.0646688895E-11 -2.8921793656E+00 -1.8609861074E-02 -4.9372094676E-12 -5.3780306925E-13 1.8609861074E-02 -2.8921793656E+00 +178.00 2.9045427190E+00 1.0647042160E-02 1.0594689418E-12 4.7668583880E-12 1.0647042160E-02 2.9045427190E+00 -1.0118251220E-11 -3.7498040232E-13 -1.1101957835E-12 -1.0123283650E-11 -2.9045113315E+00 -8.3049467109E-03 -4.7651100509E-12 -3.6351251133E-13 8.3049467109E-03 -2.9045113315E+00 +179.00 2.9119107046E+00 2.6666947666E-03 5.3787728602E-13 4.5869351149E-12 2.6666947666E-03 2.9119107046E+00 -9.5908193260E-12 -1.8653409795E-13 -5.4993925003E-13 -9.5914498106E-12 -2.9119087397E+00 -2.0813353001E-03 -4.5867159578E-12 -1.8387924116E-13 2.0813353001E-03 -2.9119087397E+00 +180.00 2.9143742348E+00 4.6913428003E-16 1.7535128407E-18 4.4031933351E-12 4.6913428003E-16 2.9143742348E+00 -9.0508461148E-12 1.1446640038E-18 -1.7535128444E-18 -9.0508461148E-12 -2.9143742348E+00 -1.4542403740E-15 -4.4031933351E-12 1.1446640076E-18 1.4542403740E-15 -2.9143742348E+00 diff --git a/sample/stdout b/sample/stdout index 876288bd..7586343f 100644 --- a/sample/stdout +++ b/sample/stdout @@ -1,7 +1,10 @@ +'Amsterdam DDA' v.0.74 +Copyright (C) 2006 M.A. Yurkin and A.G. Hoekstra + all data is saved in 'run000_sphere_g16m1_5' -0 : 0 16 16 4096 32 -lambda: 6.283185307 Dipoles/lambda: 15 -Required relative residual norm: 1e-05 +0 : 0 16 16 4096 32 0 +lambda: 6.28319 m0: 1.5+0i Dipoles/lambda: 15 +Required relative error: 1e-05 Total number of occupied dipoles: 2176 Memory usage for MatVec matrices: 1.3 Mb Calculating Dmatrix...... @@ -27,15 +30,15 @@ RE_011 = 2.4111231314E-02 + RE_012 = 3.8307716444E-03 + RE_013 = 3.0434605426E-03 + RE_014 = 1.3101400518E-03 + -RE_015 = 8.2588869902E-04 + -RE_016 = 5.0452779281E-04 + -RE_017 = 1.1339755335E-04 + -RE_018 = 9.3640503439E-05 + -RE_019 = 6.8748633527E-05 + -RE_020 = 2.2386152530E-05 + -RE_021 = 1.5169835168E-05 + -RE_022 = 3.1682277704E-06 + +RE_015 = 8.2588869898E-04 + +RE_016 = 5.0452779301E-04 + +RE_017 = 1.1339755205E-04 + +RE_018 = 9.3640501846E-05 + +RE_019 = 6.8748640198E-05 + +RE_020 = 2.2386150971E-05 + +RE_021 = 1.5169802499E-05 + +RE_022 = 3.1681098360E-06 + Cext = 135.0449046 -Qext = 3.79114961 -Cabs = 0 -Qabs = 0 +Qext = 3.791149609 +Cabs = 1.36464414e-16 +Qabs = 3.830999855e-18 diff --git a/sample/test.pbs b/sample/test.pbs deleted file mode 100644 index f74ec3c7..00000000 --- a/sample/test.pbs +++ /dev/null @@ -1,56 +0,0 @@ -# This is sample batch file to run ADDA using PBS -# it was designed for Dutch national compute cluster LISA -# based on the sample script located at -# https://subtrac.sara.nl/userdoc/wiki/lisa/usage/batch/jobmpich4 -# Auth: Maxim Yurkin - -# ----- start of PBS parameters - -# job name (default is name of pbs script file) -#PBS -N ADDA -# -# request nodes, ppn - processor per node -#PBS -l nodes=4:ppn=2:infiniband:cores2 -# -# max. wall clock time -#PBS -l walltime=0:05:00 -# -# Request that regular output and terminal output go to the same file -#PBS -j oe -# -# shell to be used for this script -#PBS -S /bin/sh -# -# export all my environment variables to the job -#PBS -V - -# ---- end of PBS parameters - -# add the GNU environment for MPICH, using Infiniband: -module load gnu-mpich-openib - -# ---- start of MVAPICH related code: - -# test if ~/.mpd.conf exists, create it if not: -if [ ! -e ~/.mpd.conf ] - then - echo MPD_SECRETWORD=$USER$RANDOM$PPID$$ > ~/.mpd.conf - chmod 600 ~/.mpd.conf -fi -# determine the number of processes to start: -nprocs=`wc -l < $PBS_NODEFILE` -# determine the number of nodes: -nnodes=`sort -u $PBS_NODEFILE | wc -l` -# start the mpd daemons: -mpdboot -n $nnodes -f $PBS_NODEFILE - -# ---- End of MVAPICH related code - -# cd to the work directory -cd $PBS_O_WORKDIR -# show information about used cores -echo "Job executes on $nnodes nodes ($nprocs cores)" -echo "cores:" -cat $PBS_NODEFILE -# execute ADDA -mpiexec -n $nprocs ./adda_mpi diff --git a/sample/test.sge b/sample/test.sge deleted file mode 100644 index 302dfc31..00000000 --- a/sample/test.sge +++ /dev/null @@ -1,53 +0,0 @@ -#!/bin/sh -# This is sample batch file to run ADDA using SGE -# it was designed for DAS-3 cluster -# (http://www.cs.vu.nl/das3/) -# Auth: Adianto Wibisono -# -# Choose shell -#$ -S /bin/sh -# Work from the current working directory -#$ -cwd -# Name of the job -#$ -N ADDA -# Set requested execution time -#$ -l h_rt=0:15:00 -# Set parallel environment and number of nodes -# (number of processors is a multiple of that number) -#$ -pe mpich 4 -# Merge stderr with stdout -#$ -j yes - -PROG=adda_mpi -ARGS="" - -# The number of cores per node can be different on the various DAS sites. -# Here we will use every cpu core there is on the first compute node, -# and assume this will be the same on the other nodes in the same cluster: -cpuspernode=`cat /proc/cpuinfo | grep processor | wc -l` -ncpus=`expr $NSLOTS \* $cpuspernode` - -export MPICH_PROCESS_GROUP=no -. /etc/profile.d/modules.sh -module add default-ethernet # or "default-myrinet" - -#$ -v MPI_HOME -#$ -v LD_LIBRARY_PATH - -echo "Got $NSLOTS nodes." -echo "Original machines file:" -cat $TMPDIR/machines -for i in `cat $TMPDIR/machines`; do - j=0 - while [ $j -lt $cpuspernode ]; do - echo $i - j=`expr $j + 1` - done -done > $TMPDIR/machines2 -echo "Using following machines file:" -cat $TMPDIR/machines2 - -cmd="$MPI_HOME/bin/mpirun -np $ncpus -machinefile \ -$TMPDIR/machines2 $PROG $ARGS" -echo Will run: $cmd -$cmd diff --git a/src/ADDAmain.c b/src/ADDAmain.c index d20c5715..e297f207 100644 --- a/src/ADDAmain.c +++ b/src/ADDAmain.c @@ -3,70 +3,76 @@ * DESCR: Main. All the work moved to other modules. * * Previous versions were developed by Alfons Hoekstra. - * Sequential version, Michel Grimminck January 1995 - * - * Copyright (C) 2006-2008 University of Amsterdam + * Sequential version, Michel Grimminck Jan 1995 + * + * Copyright (C) 2006 M.A. Yurkin and A.G. Hoekstra * This code is covered by the GNU General Public License. */ #include #include #include "vars.h" +#include "const.h" #include "comm.h" #include "debug.h" #include "io.h" -// EXTERNAL FUNCTIONS +/* EXTERNAL FUNCTIONS */ -// calculator.c +/* calculator.c */ void Calculator(void); -// make_particle.c +/* make_particle.c */ void InitShape(void); int MakeParticle(void); -// param.c +/* param.c */ void InitVariables(void); void ParseParameters(int argc,char **argv); void VariablesInterconnect(void); void DirectoryLog(int argc,char **argv); void PrintInfo(void); +/* timing.c */ +void StartTime(void); +void InitTiming(void); +void FinalStatistics(void); -//============================================================ +/*============================================================*/ int main(int argc,char **argv) { - // Initialize error handling and line wrapping - logfile=NULL; - term_width=DEF_TERM_WIDTH; - // Start global time - StartTime(); - // Initialize communications - InitComm(&argc,&argv); - // Initialize and parse input parameters - InitVariables(); - ParseParameters(argc,argv); - D("Reading command line finished"); - VariablesInterconnect(); // also initializes beam - // Initialize symmetries and box's; get number of dipoles; set some variables - InitShape(); - // !!! before this line errors should be printed in simple format, after - in advanced one - // Create directory and start logfile (print command line) - DirectoryLog(argc,argv); - // Initialize FFT grid and its subdivision over processors - ParSetup(); - // MakeParticle; initialize dpl and nlocalRows - MakeParticle(); - // Print info to stdout and logfile - PrintInfo(); - // Main calculation part - D("Calculator started"); - Calculator(); - D("Calculator finished"); - // Print timing and statistics; close logfile - FinalStatistics(); - // check error on stdout - if (ferror(stdout)) LogError(EC_WARN,ALL_POS, - "Some errors occurred while writing to stdout during the execution of ADDA"); - // finish execution normally - Stop(0); - // never actually reached; just to make the compiler happy - return 0; + /* initialize error handling */ + logfile=NULL; + /* start global time */ + StartTime(); + /* initialize communications */ + InitComm(&argc,&argv); + /* welcome; initialize and printout version and copyright */ + PRINTZ("'Amsterdam DDA' v." ADDA_VERSION "\n"\ + "Copyright (C) 2006 M.A. Yurkin and A.G. Hoekstra\n\n"); + /* initialize and parse input parameters */ + InitVariables(); + ParseParameters(argc,argv); + D("finished reading command line"); + VariablesInterconnect(); + /* initialize symmetries and box's; get number of dipoles; set some variables */ + InitShape(); + /* Create directory and start logfile (print command line) */ + DirectoryLog(argc,argv); + /* initialize FFT grid and its subdivision over processors */ + ParSetup(); + /* MakeParticle; initialize dpl and nlocalRows */ + MakeParticle(); + /* print info to stdout and logfile */ + PrintInfo(); + /* initialize times and counters */ + /* Main calculation part */ + D("calculator started"); + Calculator(); + D("calculator finished"); + /* print timing and statistics; close logfile */ + FinalStatistics(); + /* finish execution normally */ + Stop(0); + /* never actually reached */ + return 0; } + + diff --git a/src/CalculateE.c b/src/CalculateE.c index 9e1e4220..c8994278 100644 --- a/src/CalculateE.c +++ b/src/CalculateE.c @@ -3,18 +3,17 @@ * DESCR: The module that will calculate the E field and all scattering quantities. * Routines for most scattering quantities are in crosssec.c * Also saves internal fields to file (optional). - * + * * January 2004 : include module to compute full Mueller Matrix over * full space angle, not very efficient, must be improved (A. Hoekstra) * * Previous versions by Alfons Hoekstra * - * Copyright (C) 2006-2008 University of Amsterdam + * Copyright (C) 2006 M.A. Yurkin and A.G. Hoekstra * This code is covered by the GNU General Public License. */ #include -#include -#include +#include #include "cmplx.h" #include "const.h" #include "comm.h" @@ -23,54 +22,62 @@ #include "Romberg.h" #include "io.h" #include "vars.h" -#include "memory.h" -#include "timing.h" -#include "function.h" -// SEMI-GLOBAL VARIABLES +/* SEMI-GLOBAL VARIABLES */ -// defined and initialized in calculator.c -extern double *muel_phi,*muel_phi_buf; +/* defined and initialized in calculator.c */ +extern double *muel_phi,*muel_phi1; extern doublecomplex *EplaneX, *EplaneY; extern double *Eplane_buffer; extern const double dtheta_deg,dtheta_rad; extern doublecomplex *ampl_alphaX,*ampl_alphaY; extern double *muel_alpha; -// defined and initialized in crosssec.c +/* defined and initialized in crosssec.c */ extern const Parms_1D phi_sg; -// defined and initialized in param.c -extern const int store_int_field,store_dip_pol,store_beam,store_scat_grid,calc_Cext,calc_Cabs, -calc_Csca,calc_vec,calc_asym,calc_mat_force,store_force,phi_int_type; -// defined and initialized in timing.c -extern TIME_TYPE Timing_EFieldPlane,Timing_comm_EField, -Timing_IntField,Timing_IntFieldOne,Timing_ScatQuan; +/* defined and initialized in param.c */ +extern const int store_int_field; +extern const int store_scat_grid; +extern const int calc_Cext; +extern const int calc_Cabs; +extern const int calc_Csca; +extern const int calc_vec; +extern const int calc_asym; +extern const int calc_mat_force; +extern const int store_force; +extern const int phi_int_type; +/* defined and initialized in timing.c */ +extern clock_t Timing_EFieldPlane,Timing_calc_EField,Timing_comm_EField, + Timing_IntField,Timing_IntFieldOne,Timing_ScatQuan; extern unsigned long TotalEFieldPlane; -// used in iterative.c -TIME_TYPE tstart_CE; +/* used in iterative.c */ +clock_t tstart_CE; -// EXTERNAL FUNCTIONS +/* EXTERNAL FUNCTIONS */ -// GenerateB.c +/* GenerateB.c */ void GenerateB(char which,doublecomplex *x); -// iterative.c +/* iterative.c */ int IterativeSolver(int method); -//============================================================ +/*============================================================*/ -static void ComputeMuellerMatrix(double matrix[4][4], const doublecomplex s1,const doublecomplex s2, - const doublecomplex s3,const doublecomplex s4) -/* computer mueller matrix from scattering matrix elements s1, s2, s3, s4, according to formula - * 3.16 from Bohren and Huffman - */ +static void ComputeMuellerMatrix(double matrix[4][4], const doublecomplex s1, + const doublecomplex s2,const doublecomplex s3,const doublecomplex s4) +/* computer mueller matrix from scattering matrix elements s1, s2, s3, s4, accoording + to formula 3.16 from Bohren and Huffman */ { - matrix[0][0] = 0.5*(cMultConRe(s1,s1)+cMultConRe(s2,s2)+cMultConRe(s3,s3)+cMultConRe(s4,s4)); - matrix[0][1] = 0.5*(cMultConRe(s2,s2)-cMultConRe(s1,s1)+cMultConRe(s4,s4)-cMultConRe(s3,s3)); + matrix[0][0] = 0.5*(cMultConRe(s1,s1)+cMultConRe(s2,s2)+ + cMultConRe(s3,s3)+cMultConRe(s4,s4)); + matrix[0][1] = 0.5*(cMultConRe(s2,s2)-cMultConRe(s1,s1)+ + cMultConRe(s4,s4)-cMultConRe(s3,s3)); matrix[0][2] = cMultConRe(s2,s3)+cMultConRe(s1,s4); matrix[0][3] = cMultConIm(s2,s3)-cMultConIm(s1,s4); - - matrix[1][0] = 0.5*(cMultConRe(s2,s2)-cMultConRe(s1,s1)+cMultConRe(s3,s3)-cMultConRe(s4,s4)); - matrix[1][1] = 0.5*(cMultConRe(s2,s2)+cMultConRe(s1,s1)-cMultConRe(s3,s3)-cMultConRe(s4,s4)); + + matrix[1][0] = 0.5*(cMultConRe(s2,s2)-cMultConRe(s1,s1)+ + cMultConRe(s3,s3)-cMultConRe(s4,s4)); + matrix[1][1] = 0.5*(cMultConRe(s2,s2)+cMultConRe(s1,s1)+ + -cMultConRe(s3,s3)-cMultConRe(s4,s4)); matrix[1][2] = cMultConRe(s2,s3)-cMultConRe(s1,s4); matrix[1][3] = cMultConIm(s2,s3)+cMultConIm(s1,s4); @@ -85,27 +92,24 @@ static void ComputeMuellerMatrix(double matrix[4][4], const doublecomplex s1,con matrix[3][3] = cMultConRe(s1,s2)-cMultConRe(s3,s4); } -//============================================================ -// this function is currently not used -static void ComputeMuellerMatrixNorm(double [4][4],const doublecomplex,const doublecomplex, - const doublecomplex,const doublecomplex) ATT_UNUSED; +/*============================================================*/ static void ComputeMuellerMatrixNorm(double matrix[4][4],const doublecomplex s1, - const doublecomplex s2,const doublecomplex s3,const doublecomplex s4) -/* computer mueller matrix from scattering matrix elements s1, s2, s3, s4, according to formula - * 3.16 from Bohren and Huffman; normalize all elements to S11 (except itself) - */ + const doublecomplex s2,const doublecomplex s3,const doublecomplex s4) +/* computer mueller matrix from scattering matrix elements s1, s2, s3, s4, accoording to + formula 3.16 from Bohren and Huffman; normalize all elements to S11 (except itself)*/ { - matrix[0][0] = 0.5*(cMultConRe(s1,s1)+cMultConRe(s2,s2)+cMultConRe(s3,s3)+cMultConRe(s4,s4)); - matrix[0][1] = 0.5*(cMultConRe(s2,s2)-cMultConRe(s1,s1)+cMultConRe(s4,s4)-cMultConRe(s3,s3)) - / matrix[0][0]; + matrix[0][0] = 0.5*(cMultConRe(s1,s1)+cMultConRe(s2,s2)+ + cMultConRe(s3,s3)+cMultConRe(s4,s4)); + matrix[0][1] = 0.5*(cMultConRe(s2,s2)-cMultConRe(s1,s1)+ + cMultConRe(s4,s4)-cMultConRe(s3,s3))/matrix[0][0]; matrix[0][2] = (cMultConRe(s2,s3)+cMultConRe(s1,s4))/matrix[0][0]; matrix[0][3] = (cMultConIm(s2,s3)-cMultConIm(s1,s4))/matrix[0][0]; - matrix[1][0] = 0.5*(cMultConRe(s2,s2)-cMultConRe(s1,s1)+cMultConRe(s3,s3)-cMultConRe(s4,s4)) - / matrix[0][0]; - matrix[1][1] = 0.5*(cMultConRe(s2,s2)+cMultConRe(s1,s1)-cMultConRe(s3,s3)-cMultConRe(s4,s4)) - / matrix[0][0]; + matrix[1][0] = 0.5*(cMultConRe(s2,s2)-cMultConRe(s1,s1)+ + cMultConRe(s3,s3)-cMultConRe(s4,s4))/matrix[0][0]; + matrix[1][1] = 0.5*(cMultConRe(s2,s2)+cMultConRe(s1,s1)+ + -cMultConRe(s3,s3)-cMultConRe(s4,s4))/matrix[0][0]; matrix[1][2] = (cMultConRe(s2,s3)-cMultConRe(s1,s4))/matrix[0][0]; matrix[1][3] = (cMultConIm(s2,s3)+cMultConIm(s1,s4))/matrix[0][0]; @@ -120,582 +124,609 @@ static void ComputeMuellerMatrixNorm(double matrix[4][4],const doublecomplex s1, matrix[3][3] = (cMultConRe(s1,s2)-cMultConRe(s3,s4))/matrix[0][0]; } -//============================================================== -INLINE void InitMuellerIntegrFile(const int type,const char *fname,FILE **file,char *buf, - double **mult) -/* If 'phi_int_type' matches 'type', appropriate file (name given by 'fname') is created (with - * handle '*file'), and heading line is put into it. String buffer 'buf' is used. Vector of - * multipliers '*mult' is allocated if its pointer is specified. - */ -{ - if (phi_int_type & type) { - sprintf(buf,"%s/%s",directory,fname); - (*file)=FOpenErr(buf,"w",ONE_POS); - fprintf(*file,"theta s11 s12 s13 s14 s21 s22 s23 s24 s31 s32 s33 s34 s41 s42 s43 s44 " - "RMSE(integr)\n"); - if (mult!=NULL) MALLOC_VECTOR(*mult,double,angles.phi.N,ALL); - } -} - -//============================================================== - -INLINE void PrintToIntegrFile(const int type,FILE *file,double *maxerr,const double *muel, - double *muel_buf,const double *mult,double matrix[4][4],const double theta) -/* If 'phi_int_type' matches 'type', array 'muel' is integrated over phi (possibly using multiplier - * 'mult' and buffer 'muel_buf') and saved to 'file' together with 'theta'. Maximum error '*maxerr' - * is updated, 'matrix' buffer is used. - */ -{ - int k; - size_t j; - double err; - - if (phi_int_type & type) { - if (mult==NULL) err=Romberg1D(phi_sg,16,muel,matrix[0]); - else { - for (j=0;j*maxerr) *maxerr=err; - fprintf(file,"%.2f %.10E %.10E %.10E %.10E %.10E %.10E %.10E %.10E %.10E %.10E %.10E %.10E" - " %.10E %.10E %.10E %.10E %.3E\n",theta,matrix[0][0],matrix[0][1],matrix[0][2], - matrix[0][3],matrix[1][0],matrix[1][1],matrix[1][2],matrix[1][3],matrix[2][0], - matrix[2][1],matrix[2][2],matrix[2][3],matrix[3][0],matrix[3][1],matrix[3][2], - matrix[3][3],err); - } -} - -//============================================================== - -INLINE void CloseIntegrFile(const int type,FILE *file,const char *fname,double *mult) -/* If 'phi_int_type' matches 'type', appropriate 'file' (named 'fname') is closed and array 'mult' - * is freed. - */ -{ - if (phi_int_type & type) { - FCloseErr(file,fname,ONE_POS); - Free_general(mult); - } -} -//============================================================== +/*==============================================================*/ void MuellerMatrix(void) { - FILE *mueller,*mueller_int,*mueller_int_c2,*mueller_int_s2,*mueller_int_c4,*mueller_int_s4; - double *cos2,*sin2,*cos4,*sin4; - double matrix[4][4]; - double theta,phi,ph, - max_err,max_err_c2,max_err_s2,max_err_c4,max_err_s4; - doublecomplex s1,s2,s3,s4,s10,s20,s30,s40; - char fname[MAX_FNAME]; - int i; - size_t index,index1,k_or,j,n,ind; - double co,si; - double alph; - TIME_TYPE tstart; - - if (ringid!=ROOT) return; - - if (orient_avg) { // Amplitude matrix stored in ampl_alplha is - index1=index=0; // transformed into Mueller matrix stored in muel_alpha - for (k_or=0;k_or %.3E\n",max_err); - if (phi_int_type & PHI_COS2) fprintf(logfile," cos(2*phi) -> %.3E\n",max_err_c2); - if (phi_int_type & PHI_SIN2) fprintf(logfile," cos(2*phi) -> %.3E\n",max_err_c2); - if (phi_int_type & PHI_COS4) fprintf(logfile," cos(2*phi) -> %.3E\n",max_err_c2); - if (phi_int_type & PHI_SIN4) fprintf(logfile," cos(2*phi) -> %.3E\n",max_err_c2); - } - // close files; free arrays - if (store_scat_grid) FCloseErr(mueller,F_MUEL_SG,ONE_POS); - if (phi_integr) { - CloseIntegrFile(PHI_UNITY,mueller_int,F_MUEL_INT,NULL); - CloseIntegrFile(PHI_COS2,mueller_int_c2,F_MUEL_C2,cos2); - CloseIntegrFile(PHI_SIN2,mueller_int_s2,F_MUEL_S2,sin2); - CloseIntegrFile(PHI_COS4,mueller_int_c4,F_MUEL_C4,cos4); - CloseIntegrFile(PHI_SIN4,mueller_int_s4,F_MUEL_S4,sin4); - } - } - Timing_FileIO += GET_TIME() - tstart; - } + FILE *mueller,*mueller_int,*mueller_int_c2,*mueller_int_s2,*mueller_int_c4,*mueller_int_s4; + double *cos2,*sin2,*cos4,*sin4; + double matrix[4][4]; + double theta,phi,ph,err, + max_err,max_err_c2,max_err_s2,max_err_c4,max_err_s4; + doublecomplex s1,s2,s3,s4,s10,s20,s30,s40; + char fname[MAX_FNAME]; + int index,index1,i,j,k,n,k_or; + double co,si; + double alph; + clock_t tstart; + + if (ringid!=ROOT) return; + + if (orient_avg) { /* Amplitude matrix stored in ampl_alplha is */ + index1=index=0; /* transformed into Mueller matrix stored in muel_alpha */ + for (k_or=0;k_ormax_err) max_err=err; + fprintf(mueller_int, + "%.2f %.10E %.10E %.10E %.10E %.10E %.10E %.10E %.10E %.10E"\ + " %.10E %.10E %.10E %.10E %.10E %.10E %.10E %.3E\n", + theta,matrix[0][0],matrix[0][1],matrix[0][2],matrix[0][3], + matrix[1][0],matrix[1][1],matrix[1][2],matrix[1][3], + matrix[2][0],matrix[2][1],matrix[2][2],matrix[2][3], + matrix[3][0],matrix[3][1],matrix[3][2],matrix[3][3],err); + } + if (phi_int_type & PHI_COS2) { + for (j=0;jmax_err_c2) max_err_c2=err; + fprintf(mueller_int_c2, + "%.2f %.10E %.10E %.10E %.10E %.10E %.10E %.10E %.10E %.10E"\ + " %.10E %.10E %.10E %.10E %.10E %.10E %.10E %.3E\n", + theta,matrix[0][0],matrix[0][1],matrix[0][2],matrix[0][3], + matrix[1][0],matrix[1][1],matrix[1][2],matrix[1][3], + matrix[2][0],matrix[2][1],matrix[2][2],matrix[2][3], + matrix[3][0],matrix[3][1],matrix[3][2],matrix[3][3],err); + } + if (phi_int_type & PHI_SIN2) { + for (j=0;jmax_err_s2) max_err_s2=err; + fprintf(mueller_int_s2, + "%.2f %.10E %.10E %.10E %.10E %.10E %.10E %.10E %.10E %.10E"\ + " %.10E %.10E %.10E %.10E %.10E %.10E %.10E %.3E\n", + theta,matrix[0][0],matrix[0][1],matrix[0][2],matrix[0][3], + matrix[1][0],matrix[1][1],matrix[1][2],matrix[1][3], + matrix[2][0],matrix[2][1],matrix[2][2],matrix[2][3], + matrix[3][0],matrix[3][1],matrix[3][2],matrix[3][3],err); + } + if (phi_int_type & PHI_COS4) { + for (j=0;jmax_err_c4) max_err_c4=err; + fprintf(mueller_int_c4, + "%.2f %.10E %.10E %.10E %.10E %.10E %.10E %.10E %.10E %.10E"\ + " %.10E %.10E %.10E %.10E %.10E %.10E %.10E %.3E\n", + theta,matrix[0][0],matrix[0][1],matrix[0][2],matrix[0][3], + matrix[1][0],matrix[1][1],matrix[1][2],matrix[1][3], + matrix[2][0],matrix[2][1],matrix[2][2],matrix[2][3], + matrix[3][0],matrix[3][1],matrix[3][2],matrix[3][3],err); + } + if (phi_int_type & PHI_SIN4) { + for (j=0;jmax_err_s4) max_err_s4=err; + fprintf(mueller_int_s4, + "%.2f %.10E %.10E %.10E %.10E %.10E %.10E %.10E %.10E %.10E"\ + " %.10E %.10E %.10E %.10E %.10E %.10E %.10E %.3E\n", + theta,matrix[0][0],matrix[0][1],matrix[0][2],matrix[0][3], + matrix[1][0],matrix[1][1],matrix[1][2],matrix[1][3], + matrix[2][0],matrix[2][1],matrix[2][2],matrix[2][3], + matrix[3][0],matrix[3][1],matrix[3][2],matrix[3][3],err); + } + } + } + if (phi_integr) { + fprintf(logfile,"\nMaximum relative mean-square error of Mueller integration:\n"); + if (phi_int_type & PHI_UNITY) fprintf(logfile," 1 -> %.3E\n",max_err); + if (phi_int_type & PHI_COS2) fprintf(logfile," cos(2*phi) -> %.3E\n",max_err_c2); + if (phi_int_type & PHI_SIN2) fprintf(logfile," cos(2*phi) -> %.3E\n",max_err_c2); + if (phi_int_type & PHI_COS4) fprintf(logfile," cos(2*phi) -> %.3E\n",max_err_c2); + if (phi_int_type & PHI_SIN4) fprintf(logfile," cos(2*phi) -> %.3E\n",max_err_c2); + } + /* close files; free arrays */ + if (store_scat_grid) FCloseErr(mueller,F_MUEL_SG,ONE_POS); + if (phi_integr) { + if (phi_int_type & PHI_UNITY) FCloseErr(mueller_int,F_MUEL_INT,ONE_POS); + if (phi_int_type & PHI_COS2) { + FCloseErr(mueller_int_c2,F_MUEL_C2,ONE_POS); + free(cos2); + } + if (phi_int_type & PHI_SIN2) { + FCloseErr(mueller_int_s2,F_MUEL_S2,ONE_POS); + free(sin2); + } + if (phi_int_type & PHI_COS4) { + FCloseErr(mueller_int_c4,F_MUEL_C4,ONE_POS); + free(cos4); + } + if (phi_int_type & PHI_SIN4) { + FCloseErr(mueller_int_s4,F_MUEL_S4,ONE_POS); + free(sin4); + } + } + } + Timing_FileIO += clock() - tstart; + } } -//============================================================ +/*============================================================*/ static void CalcEplane(const char which,const int type) -// calculates scattered electric field in a plane + /* calculates scattered electric field in a plane */ { - double *incPol,*incPolper,*incPolpar; - // where to store calculated field for one plane (actually points to different other arrays) - doublecomplex *Eplane; - int i; - doublecomplex ebuff[3]; // small vector to hold E fields - double robserver[3]; // small vector for observer in E calculation - double epar[3]; // unit vector in direction of Epar - double theta; // scattering angle - double co,si; // temporary, cos and sin of some angle - double incPol_tmp1[3],incPol_tmp2[3]; // just allocated memory for incPolper, incPolpar - double alph; - TIME_TYPE tstart; - size_t k_or; - int orient,Norient; - char choice; - - incPolper=incPol_tmp1; // initialization of per and par polarizations - incPolpar=incPol_tmp2; - - if (type==CE_NORMAL) Norient=1; // initialize # orientations - else if (type==CE_PARPER) Norient=2; - - for (k_or=0;k_or X - memcpy(incPolpar,incPolY,3*sizeof(double)); // par <=> Y - } - - for(orient=0;orient -IncPolX; incPolX -> IncPolY - * */ - if (which=='X') choice='Y'; - else if (which=='Y') choice='X'; - incPol=incPolper; - incPolper=incPolpar; - incPolpar=incPol; - MultScal(-1,incPolpar,incPolpar); - } - // initialize Eplane - if (orient_avg) { - if (choice=='X') Eplane=ampl_alphaX + 2*nTheta*k_or; - else if (choice=='Y') Eplane=ampl_alphaY + 2*nTheta*k_or; - } - else { - if (choice=='X') Eplane=EplaneX; - else if (choice=='Y') Eplane=EplaneY; - } - - for (i=0;i X */ + memcpy(incPolpar,incPolY,3*sizeof(double)); /* par <=> Y */ + } + + for(orient=0;orient -IncPolX; incPolX -> IncPolY */ + if (which=='X') choice='Y'; + else if (which=='Y') choice='X'; + incPol=incPolper; + incPolper=incPolpar; + incPolpar=incPol; + MultScal(-1,incPolpar,incPolpar); + } + /* initialize Eplane */ + if (orient_avg) { + if (choice=='X') Eplane=ampl_alphaX + 2*nTheta*k_or; + else if (choice=='Y') Eplane=ampl_alphaY + 2*nTheta*k_or; + } + else { + if (choice=='X') Eplane=EplaneX; + else if (choice=='Y') Eplane=EplaneY; + } + + for (i=0;i -#include #include "vars.h" #include "cmplx.h" #include "const.h" #include "comm.h" -// SEMI-GLOBAL VARIABLES +/* SEMI-GLOBAL VARIABLES */ -// defined and initialized in param.c -extern const int beam_Npars; -extern const double beam_pars[]; +/* defined and initialized in param.c */ +extern const int beamtype; +extern const double beam_w0,beam_x0,beam_y0,beam_z0; -// used in crosssec.c -double beam_center_0[3]; // position of the beam center in laboratory reference frame -// used in param.c -char beam_descr[MAX_PARAGRAPH]; // string for log file with beam parameters +/*============================================================*/ -// LOCAL VARIABLES -double s,s2; // beam confinement factor and its square -double scale_x,scale_z; // multipliers for scaling coordinates +void GenerateB (const char which, /* x - or y polarized incident light */ + doublecomplex *b) /* the b vector for the incident field */ + /* generates incident beam at every dipole */ +{ + int i; + + int p1,p2,p3; + doublecomplex psi0, Q; + double l = WaveNum * beam_w0 * beam_w0; /* spreading length */ + double hplus, Qdenom, xsidiff; + double x, y, z; + double co, si, ex, tmpArg; + doublecomplex ctemp; + double const *incPol; /*used incident polarization*/ + + /* polarisation is in the p1 direction - old version; new - choose from one of the basic + (latter only for plane wave, for now) */ + if (which=='Y') {p1=1; p2=0; p3=2; incPol=incPolY;} + if (which=='X') {p1=0; p2=1; p3=2; incPol=incPolX;} + if (beamtype==B_PLANE) + for (i=0;inul -qipa=level=2 -qhot - DEPFLAG = -qmakedep=gcc -qsyntaxonly - CWARN = -qsuppress=1506-224:1506-342:1500-036 -endif -ifeq ($(COMPILER),other) -endif -# if 'release' turn off warningns -ifdef RELEASE - CWARN = -w - LWARN = -w -endif -# Finalize option flags (almost) -CFLAGS += $(COPT) $(CWARN) -FFLAGS += $(FOPT) $(FWARN) -LFLAGS += $(COPT) $(LWARN) +# for faster recompiling turn on in debug.h +#CFLAGS += -DDEBUG -#=============================================================================== -# Main action part -#=============================================================================== +# for faster recompiling turn on in fft.h +#CFLAGS += -DFFT_TEMPERTON -.EXPORT_ALL_VARIABLES: -.PHONY: seq mpi clean +# for faster recompiling turn on in timing.h +#CFLAGS += -DPRECISE_TIMING + +# for faster recompiling turn on in io.h +#CFLAGS += -DNOT_USE_LOCK + +export CSOURCE +export COBJECTS +export FOBJECTS +export CFLAGS +export FFLAGS +export LDLIBS +export PROG +export SHELL seq: - rm -f $(LASTMPI) $(MAKE) -f make_seq mpi: - rm -f $(LASTSEQ) $(MAKE) -f make_mpi +reset: + rm -f ExpCount + clean: - rm -f *.o *.d $(PROGSEQ) $(PROGMPI) $(LASTSEQ) $(LASTMPI) + rm -f *.o + rm -f *.d + rm -f $(PROG) diff --git a/src/Romberg.c b/src/Romberg.c index 995aa847..2b578280 100644 --- a/src/Romberg.c +++ b/src/Romberg.c @@ -1,533 +1,479 @@ /* FILE : Romberg.c * AUTH : Maxim Yurkin - * DESCR: 1D Romberg integration routine based on - * Davis P.J., Rabinowitz P. "Methods of numerical integration", Academic Press, 1975. - * Chapter 6.3 - * When function is periodic simple trapezoidal rule is more suitable (Chapter 2.9), it - * is implemented inside the general Romberg framework. - * - * Error estimates (for both cases) are based on the "bracketing" criterion (pp.330-331), - * they seems to be reliable (it is not so certain for trapezoid rule). - * - * 1D Romberg works on precalculated array of data. - * - * 2D Romberg is two-level integration, where final error is estimated based on both - * the errors of outer and inner integration. It uses function pointer to calculate values - * as needed. Therefore it is adaptive, but can be used in non-adaptive regime on - * precalculated values. - * Two instances of Romberg 2D should not be used in parallel (they use common storage). - * E.g. calculation of Csca inside orientation averaging must not be done. - * - * Integration parameters are described in a special structure Parms_1D defined in types.h - * They must be set outside of the Romberg routine. - * + * DESCR: 2D-integration routine, based on the qromb-routine from + * Numerical Recipes. The main differences from the original + * code are : + * 1) Romberg1D works with precalculated values + * Romberg2D is adaptive, works through pointer to a function, + * can handle also precalculated values + * 2) From 1D-integration to 2D-integration. The function-values for + * OuterQromb are themselves the result of an integration + * performed by InnerQromb. + * The types declared in types.h deserve some attention : + * - Parms_1D : this structure holds the parameters for integration + * in one dimension. They must be set outside of the + * Romberg routine. * All the routines normalize the result on the interval width, i.e. - * actually averaging takes place. + * actually averaging takes place. * - * Different implementation of Romberg integration was first coded by Martin Frijlink + * Previous version by Martin Frijlink * - * Copyright (C) 2006-2008 University of Amsterdam + * Copyright (C) 2006 M.A. Yurkin and A.G. Hoekstra * This code is covered by the GNU General Public License. */ #include -#include -#include #include "vars.h" +#include "cmplx.h" #include "types.h" +#include "comm.h" #include "const.h" #include "Romberg.h" #include "memory.h" #include "io.h" -// SEMI-GLOBAL VARIABLES - -// defined and initialized in crosssec.c -extern const int full_al_range; - -// LOCAL VARIABLES - -static int dim; // dimension of the data (integrated simultaneously) -static int N_eval; // number of function evaluations in inner cycle -static int N_tot_eval; // total number of function evaluation -static int no_convergence; // number of inner integrals that did not converge -static FILE *file; // file to print info -// used in inner loop -static int size_in; // size of M array -static double **M_in, // array of M values - *T_in, // T_m^0 - *dummy_in; // save function values -// used in outer loop -static int size_out; -static double **M_out,*T_out,*dummy_out; // analogous to the above -// common arrays with frequently used values -static double *tv1, // 4^m - *tv2, // 1/(4^m-1) - *tv3; // 2*4^m-1 -// pointer to the function that is integrated -static double (*func)(int theta,int phi,double *res); -static const Parms_1D *input; // parameters of integration - -//============================================================ - -double Romberg1D(const Parms_1D param, // parameters of integration - const int size, // size of block of data - const double *data, // written as sequential blocks - double *res) // where to put result -/* Performs integration of data. Since all values are already calculated, no adaptation is used - * (all data is used). Result is normalized on the interval width, i.e. actually averaging takes - * place. Returns relative mean-square error; if function is periodic then only the first column of - * the table is used - i.e. trapezoid rule. This function is completely independent of others. - */ -{ - int m,m0,comp,i,step,index,Msize; - size_t j; - double abs_res,abs_err; // norms (squared) of result and error - double temp; - double **M1,*T1,*t1,*t2,*t3; // analogous to those used in 2D Romberg - - // allocate memory - Msize = param.periodic ? 0 : param.Jmax; - MALLOC_DMATRIX(M1,Msize+1,size,ONE); - MALLOC_VECTOR(T1,double,size,ONE); - // common to fasten calculations; needed only for really Romberg - if (Msize!=0) { - MALLOC_VECTOR(t1,double,Msize+1,ONE); - MALLOC_DVECTOR2(t2,1,Msize,ONE); - MALLOC_VECTOR(t3,double,Msize+1,ONE); - t1[0]=1; - for (i=1;i>m; - for (comp=0;comp>1;j=0;i--) for (comp=0;comp M[k] -new-> M_(m-k)^k - */ +static void PolInterp(const double xa[],const double ya[],const int n, + const double x,double *y,double *dy) + /* Inter- or extrapolate the n function-values ya[], at + * corresponding gridpoints xa[], to y, at gridpoint x + * with Neville's algorithm. The estimated error in y + * will be stored in dy. */ { - int k,comp; - - for (k=m-1;k>=0;k--) for (comp=0;comp> (n-2); + + for (j=step>>1;j>n; - // init sum - for (comp=0;comp>1;j=input[PHI].Jmin-1) { - abs_res=0.5*fabs(M_in[0][0]+T_in[0]); - abs_err=0.5*fabs(M_in[0][0]-T_in[0])+int_err; - if (abs_res==0) err=0; - else err=abs_err/abs_res; - if (err=input[PHI].eps) { - fprintf(file,"Inner_qromb converged only to d=%g for cosine value #%d\n",err,fixed); - fflush(file); - no_convergence++; - } - return (abs_err); + int j,comp,step; + double tnm; + + if (n == 1) { /* Initialise the algorithm */ + (*func)(fixed,0,dummy_in); + N_eval ++; + + if (input[PHI].equival) + for (comp=0;comp> (n-2); + + for (j=step>>1;j= ROMB_KMIN) { + k = MIN(j,input[PHI].K); + for (comp=0; comp>n; - // init sum - for (comp=0;comp>1;j> (n-2); + + for (j=step>>1;j=input[THETA].Jmin-1) { - abs_res=0.5*fabs(M_out[0][0]+T_out[0]); - // absolute error is sum of the errors for current integration and accumulated inner error - abs_err=0.5*fabs(M_out[0][0]-T_out[0])+int_err; - if (abs_res==0) err=0; - else err=abs_err/abs_res; - if (err= ROMB_KMIN) { + k = MIN(j,input[THETA].K); + for (comp=0; comp -#include -#include +#include #include "vars.h" #include "cmplx.h" #include "Romberg.h" @@ -21,605 +20,585 @@ #include "crosssec.h" #include "io.h" #include "fft.h" -#include "timing.h" -// SEMI-GLOBAL VARIABLES +/* SEMI-GLOBAL VARIABLES */ -// defined and initialized in crosssec.c +/* defined and initialized in crosssec.c */ extern const Parms_1D parms[2],parms_alpha; extern const angle_set beta_int,gamma_int,theta_int,phi_int; -// defined and initialized in param.c -extern const int avg_inc_pol; +/* defined and initialized in param.c */ +extern const int PolRelation,avg_inc_pol; extern const char alldir_parms[],scat_grid_parms[]; -// defined and initialized in timing.c -extern TIME_TYPE Timing_Init; +/* defined and initialized in timing.c */ +extern clock_t Timing_Init, tstart_main; extern unsigned long TotalEval; -// used in CalculateE.c -double *muel_phi; // used to store values of Mueller matrix for different phi (to integrate) -double *muel_phi_buf; // additional for integrating with different multipliers - // scattered E (for scattering in one plane) for two incident polarizations -doublecomplex *EplaneX, *EplaneY; -double *Eplane_buffer; // buffer to accumulate Eplane -double dtheta_deg,dtheta_rad; // delta theta in degrees and radians -doublecomplex *ampl_alphaX,*ampl_alphaY; // storing amplitude matrix for different values of alpha -double *muel_alpha; // storing mueller matrix for different values of alpha -// used in fft.c -double *tab1,*tab2,*tab3,*tab4,*tab5,*tab6,*tab7,*tab8,*tab9,*tab10; // tables of integrals -int **tab_index; // matrix for indexing of table arrays -// used in crosssec.c -double *E2_alldir; // square of E, calculated for alldir -double *E2_alldir_buffer; // buffer to accumulate E2_alldir -doublecomplex cc[MAX_NMAT][3]; // couple constants -doublecomplex *expsX,*expsY,*expsZ; // arrays of exponents along 3 axes (for calc_field) -// used in iterative.c -doublecomplex *rvec,*vec1,*vec2,*vec3,*Avecbuffer; // vectors for iterative solvers - -// LOCAL VARIABLES - -static size_t block_theta; // size of one block of mueller matrix - 16*nTheta -static int finish_avg; // whether to stop orientation averaging - // used to collect both mueller matrix and integral scattering quantities when orient_avg -static double *out; - -// EXTERNAL FUNCTIONS - -// CalculateE.c +/* used in CalculateE.c */ +double *muel_phi; /* used to store values of Mueller matrix for different phi (to integrate) */ +double *muel_phi1; /* additional for integrating with different multipliers */ +doublecomplex *EplaneX, *EplaneY; /* scattered E (for scattering in one plane) + for two incident polarizations */ +double *Eplane_buffer; /* buffer to accumulate Eplane */ +double dtheta_deg,dtheta_rad; /* delta theta in deg and radians */ +doublecomplex *ampl_alphaX,*ampl_alphaY; /* storing amplitude matrix for + different values of alpha */ +double *muel_alpha; /* storing mueller matrix for different values of alpha */ +/* used in fft.c */ +double *tab1,*tab2,*tab3,*tab4,*tab5,*tab6,*tab7,*tab8,*tab9,*tab10; /* tables of integrals */ +int **tab_index; /* matrix for indexation of table arrays */ +/* used in crosssec.c */ +double *E2_alldir; /* square of E, calculated for alldir */ +double *E2_alldir_buffer; /* buffer to accumulate E2_alldir */ +doublecomplex cc[MAX_NMAT][3]; /* couple constants */ +/* used in iterative.c */ +doublecomplex *xvec,*rvec,*vec1,*vec2,*vec3,*Avecbuffer; /* vectors for iterative solvers */ + +/* LOCAL VARIABLES */ + +static int block_theta; /* size of one block of mueller matrix - 16*nTheta */ +static int finish_avg; /* whether to stop orientation averaging */ +static double *out; /* used to collect both mueller matrix and integral + scattering quantities when orient_avg */ +/* EXTERNAL FUNCTIONS */ + +/* CalculateE.c */ extern int CalculateE(char which,int type); extern void MuellerMatrix(void); -//============================================================ +/*============================================================*/ -static void CoupleConstant(doublecomplex *mrel,const char which,doublecomplex *res) +static void CoupleConstant(const doublecomplex mrel,const char which,doublecomplex *res) { - doublecomplex coup_con[3]; - doublecomplex tempa,tempb,cm,m2,t1; - double temp,V,b1,b2,b3; - int i,imax,j,jmax; // counters: i is for 'asym', j is for 'anysotropy' - double S,prop2[3]; - int asym; // whether polarizability is asymmetric (for isotropic m) - const double *incPol; - int pol_avg=TRUE; - - asym = (PolRelation==POL_CLDR || PolRelation==POL_SO); - // !!! this should never happen - if (asym && anisotropy) LogError(EC_ERROR,ONE_POS,"Incompatibility error in CoupleConstant"); - if (asym) imax=3; - else imax=1; - if (anisotropy) jmax=3; - else jmax=1; - if (PolRelation==POL_LDR || PolRelation==POL_CLDR) { - b1=LDR_B1; - b2=LDR_B2; - b3=LDR_B3; - } - else if (PolRelation==POL_SO) { - b1=SO_B1; - b2=SO_B2; - b3=SO_B3; - } - // calculate the CM couple constant CC=(3V/4pi)*(m^2-1)/(m^2+2) - V=gridspace*gridspace*gridspace; // volume of one dipole - temp = (3*V)/(4*PI); - for (j=0;j // for memcpy -#include // for cos, sin -#include "const.h" // for math constants -#include "types.h" // for doublecomplex -#include "function.h" // for INLINE +#include +#include +#include "const.h" +#include "io.h" -//============================================================ -// operations on complex numbers - -INLINE void cEqual(const doublecomplex a,doublecomplex b) -// performs b=a -{ - memcpy(b,a,sizeof(doublecomplex)); -} - -//============================================================ +/*============================================================*/ +/* operations on complex numbers */ INLINE double cAbs2(const doublecomplex a) -// square of absolute value of complex number; |a|^2 + /* square of absolute value of complex number; |a|^2 */ { - return (a[RE]*a[RE] + a[IM]*a[IM]); -} - -//============================================================ - -INLINE double cAbs(const doublecomplex a) -// absolute value of complex number |a|, specially designed to avoid overflow -{ - double u,v,w; - u=fabs(a[RE]); - v=fabs(a[IM]); - - if (u==0 && v==0) return 0; - else { - if (u>=v) { - w=v/u; - return (u*sqrt(1+w*w)); - } - else { - w=u/v; - return (v*sqrt(1+w*w)); - } - } + return (a[RE]*a[RE] + a[IM]*a[IM]); } -//============================================================ +/*============================================================*/ INLINE void cConj(const doublecomplex a,doublecomplex b) -// complex conjugate; b=a* + /* complex conjugate; b=a* */ { - b[RE] = a[RE]; - b[IM] = - a[IM]; + b[RE] = a[RE]; + b[IM] = - a[IM]; } -//============================================================ +/*============================================================*/ INLINE void cAdd(const doublecomplex a,const doublecomplex b,doublecomplex c) -// add two complex numbers; c=a+b + /* add two complex numbers; c=a+b */ { - c[RE] = a[RE] + b[RE]; - c[IM] = a[IM] + b[IM]; + c[RE] = a[RE] + b[RE]; + c[IM] = a[IM] + b[IM]; } -//============================================================ +/*============================================================*/ INLINE void cSubtr(const doublecomplex a,const doublecomplex b,doublecomplex c) -// subtract two complex numbers; c=a-b + /* subtract two complex numbers; c=a-b */ { - c[RE] = a[RE] - b[RE]; - c[IM] = a[IM] - b[IM]; + c[RE] = a[RE] - b[RE]; + c[IM] = a[IM] - b[IM]; } -//============================================================ +/*============================================================*/ INLINE void cSquare(const doublecomplex a,doublecomplex b) -// square of complex number; b=a^2 + /* square of complex number; b=a^2 */ { - b[RE]=a[RE]*a[RE] - a[IM]*a[IM]; - b[IM]=2*a[IM]*a[RE]; + b[RE]=a[RE]*a[RE] - a[IM]*a[IM]; + b[IM]=2*a[IM]*a[RE]; } -//============================================================ +/*============================================================*/ INLINE void cMultReal(const double a,const doublecomplex b,doublecomplex c) -// complex multiplication by real; c=ab + /* complex multiplication by real; c=ab */ { - c[RE]=a*b[RE]; - c[IM]=a*b[IM]; + c[RE]=a*b[RE]; + c[IM]=a*b[IM]; } -//============================================================ +/*============================================================*/ INLINE void cMult_i(doublecomplex c) -// complex multiplication by i; c=i*c + /* complex multiplication by i; c=i*c */ { - double tmp; - tmp=c[RE]; - c[RE]=-c[IM]; - c[IM]=tmp; + double tmp; + tmp=c[RE]; + c[RE]=-c[IM]; + c[IM]=tmp; } -//============================================================ - -INLINE void cMult_i2(doublecomplex a,doublecomplex b) -// complex multiplication by i; b=i*a; !!! b and c should be different !!! -{ - b[RE]=-a[IM]; - b[IM]=a[RE]; -} -//============================================================ +/*============================================================*/ INLINE void cMult(const doublecomplex a,const doublecomplex b,doublecomplex c) -// complex multiplication; c=ab; !!! c should be different from a and b !!! + /* complex multiplication; c=ab */ + /* !!! c should be different from a and b !!! */ { - c[RE]=a[RE]*b[RE] - a[IM]*b[IM]; - c[IM]=a[IM]*b[RE] + a[RE]*b[IM]; + c[RE]=a[RE]*b[RE] - a[IM]*b[IM]; + c[IM]=a[IM]*b[RE] + a[RE]*b[IM]; } -//============================================================ +/*============================================================*/ INLINE void cMultSelf(doublecomplex a,const doublecomplex b) -// complex multiplication; a*=b + /* complex multiplication; a*=b */ { - double tmp; - - tmp=a[RE]; - a[RE]=a[RE]*b[RE] - a[IM]*b[IM]; - a[IM]=a[IM]*b[RE] + tmp*b[IM]; + double tmp; + tmp=a[RE]; + a[RE]=a[RE]*b[RE] - a[IM]*b[IM]; + a[IM]=a[IM]*b[RE] + tmp*b[IM]; } -//============================================================ +/*============================================================*/ INLINE double cMultConRe(const doublecomplex a,const doublecomplex b) -// complex multiplication; returns real(a*b_conjugated) + /* complex multiplication; returns real(a*b_conjugated) */ { - return (a[RE]*b[RE] + a[IM]*b[IM]); + return (a[RE]*b[RE] + a[IM]*b[IM]); } -//============================================================ +/*============================================================*/ INLINE double cMultConIm(const doublecomplex a,const doublecomplex b) -// complex multiplication; returns imag(a*b_conjugated) + /* complex multiplication; returns imag(a*b_conjugated) */ { - return (a[IM]*b[RE] - a[RE]*b[IM]); + return (a[IM]*b[RE] - a[RE]*b[IM]); } -//============================================================ +/*============================================================*/ INLINE void cLinComb(const doublecomplex a,const doublecomplex b, const double c1,const double c2,doublecomplex c) -// linear combination of two complex numbers; c=c1*a+c2*b + /* linear combination of two complex numbers; c=c1*a+c2*b */ { - c[RE]=c1*a[RE]+c2*b[RE]; - c[IM]=c1*a[IM]+c2*b[IM]; + c[RE]=c1*a[RE]+c2*b[RE]; + c[IM]=c1*a[IM]+c2*b[IM]; } -//============================================================ +/*============================================================*/ INLINE void cInvSign(doublecomplex a) -// change sign of complex number; a*=-1; + /* change sign of complex number; a*=-1; */ { - a[RE] = - a[RE]; - a[IM] = - a[IM]; + a[RE] = - a[RE]; + a[IM] = - a[IM]; } -//============================================================ +/*============================================================*/ INLINE void cInvSign2(const doublecomplex a,doublecomplex b) -// change sign of complex number and store to different address; b=-a; + /* change sign of complex number and store to different address; b=-a; */ { - b[RE] = - a[RE]; - b[IM] = - a[IM]; + b[RE] = - a[RE]; + b[IM] = - a[IM]; } -//============================================================ +/*============================================================*/ INLINE void cInv(const doublecomplex a,doublecomplex b) -// complex inversion; b=1/a; designed to avoid under and overflows + /* complex inversion; b=1/a */ { - double tmp; - - if (fabs(a[RE])>=fabs(a[IM])) { - tmp=a[IM]/a[RE]; - b[RE]=1/(a[RE]+a[IM]*tmp); - b[IM]=-b[RE]*tmp; - } - else { - tmp=a[RE]/a[IM]; - b[IM]=-1/(a[RE]*tmp+a[IM]); - b[RE]=-b[IM]*tmp; - } + double tmp; + tmp=1/(a[RE]*a[RE] + a[IM]*a[IM]); + b[RE]= a[RE] * tmp; + b[IM]= - a[IM] * tmp; } -//============================================================ - -INLINE double cInvIm(const doublecomplex a) -// returns Im of inverse of a; designed to avoid under and overflows -{ - double tmp; - - if (fabs(a[RE])>=fabs(a[IM])) { - tmp=a[IM]/a[RE]; - return (-tmp/(a[RE]+a[IM]*tmp)); - } - else { - tmp=a[RE]/a[IM]; - return (-1/(a[RE]*tmp+a[IM])); - } -} - -//============================================================ +/*============================================================*/ INLINE void cDiv(const doublecomplex a,const doublecomplex b,doublecomplex c) -/* complex division; c=a/b; designed to avoid under and overflows - * !!! c should be different from a !!! - */ + /* complex division; c=a/b */ + /* !!! c should be different from a and b !!! */ { - double u,v; - - if (fabs(b[RE])>=fabs(b[IM])) { - u=b[IM]/b[RE]; - v=1/(b[RE]+b[IM]*u); - c[RE]=(a[RE]+a[IM]*u)*v; - c[IM]=(a[IM]-a[RE]*u)*v; - } - else { - u=b[RE]/b[IM]; - v=1/(b[RE]*u+b[IM]); - c[RE]=(a[RE]*u+a[IM])*v; - c[IM]=(a[IM]*u-a[RE])*v; - } + double tmp; + tmp=1/(b[RE]*b[RE] + b[IM]*b[IM]); + c[RE]=(a[RE]*b[RE] + a[IM]*b[IM])*tmp; + c[IM]=(a[IM]*b[RE] - a[RE]*b[IM])*tmp; } -//============================================================ +/*============================================================*/ INLINE void cDivSelf(doublecomplex a,const doublecomplex b) -// complex division; a/=b; designed to avoid under and overflows + /* complex division; a/=b */ { - double u,v,w; - - w=a[RE]; - if (fabs(b[RE])>=fabs(b[IM])) { - u=b[IM]/b[RE]; - v=1/(b[RE]+b[IM]*u); - a[RE]=(w+a[IM]*u)*v; - a[IM]=(a[IM]-w*u)*v; - } - else { - u=b[RE]/b[IM]; - v=1/(b[RE]*u+b[IM]); - a[RE]=(w*u+a[IM])*v; - a[IM]=(a[IM]*u-w)*v; - } + double tmp, tmp2; + tmp=1/(b[RE]*b[RE] + b[IM]*b[IM]); + tmp2=a[RE]; + a[RE]=(a[RE]*b[RE] + a[IM]*b[IM])*tmp; + a[IM]=(a[IM]*b[RE] - tmp2*b[IM])*tmp; } -//============================================================ +/*============================================================*/ INLINE void cSqrt(const doublecomplex a,doublecomplex b) -/* complex square root; b=sqrt(a); designed to avoid under and overflows; - * branch cut discontinuity is (-inf,0) - b[RE]>=0 - */ -{ - double u,v,w,r; - - u=fabs(a[RE]); - v=fabs(a[IM]); - if (u==0 && v==0) b[RE]=b[IM]=0; - else { - // first determine w - if (u>=v) { - r=v/u; - w=sqrt(u)*sqrt((1+sqrt(1+r*r))/2); - } - else { - r=u/v; - w=sqrt(v)*sqrt((r+sqrt(1+r*r))/2); - } - // compute the result - if (a[RE]>=0) { - b[RE]=w; - b[IM]=a[IM]/(2*w); - } - else { - b[RE]=v/(2*w); - if (a[IM]>=0) b[IM]=w; - else b[IM]=-w; - } - } -} - -//============================================================ - -INLINE void imExp(const double arg,doublecomplex c) -// exponent of imaginary argument c=Exp(i*arg); optimization is performed by compiler -{ - c[RE]=cos(arg); - c[IM]=sin(arg); -} - -//============================================================ - -INLINE void imExp_arr(const double arg,const int size,doublecomplex *c) -/* construct an array of exponent of imaginary argument c=Exp(i*k*arg) - * where k=0,1,...,size-1. Uses stable recurrence from Numerical Recipes. - * Optimization of the initial simultaneous calculation of sin and cos is performed - * by compiler; It is assumed that size is at least 1 - */ -{ - int k; - double a,b; - - c[0][RE]=1; - c[0][IM]=0; - if (size>1) { - // set a=2*sin^2(arg/2), b=sin(arg) - a=sin(arg/2); - b=cos(arg/2); - b*=2*a; - a*=2*a; - // this a bit faster than in the main cycle - c[1][RE]=1-a; - c[1][IM]=b; - // main cycle - for (k=2;k=0 */ { - c[RE]=c[IM]=exp(arg[RE]); - c[RE]*=cos(arg[IM]); - c[IM]*=sin(arg[IM]); + double tmp; + + tmp=sqrt(a[RE]*a[RE]+a[IM]*a[IM]); + b[RE]=sqrt(0.5*(tmp+a[RE])); + b[IM]=sqrt(0.5*(tmp-a[RE])); + if (a[IM]<0) b[RE]=-b[RE]; } -//============================================================ +/*============================================================*/ -INLINE void cExpSelf(doublecomplex arg) -/* complex exponent of complex argument arg=Exp(arg); result is stored in the argument itself - * Optimization is performed by compiler - */ +INLINE void cExp(const double arg,doublecomplex c) + /* complex exponent c=Exp(i*arg) + Optimization is performed by compiler */ { - double tmp; - - tmp=arg[IM]; - arg[RE]=arg[IM]=exp(arg[RE]); - arg[RE]*=cos(tmp); - arg[IM]*=sin(tmp); + c[RE]=cos(arg); + c[IM]=sin(arg); } - -//============================================================ -// operations on complex vectors +/*============================================================*/ +/* operations on complex vectors */ INLINE void cvMultScal(const double a,doublecomplex *b,doublecomplex *c) -// multiplication of vector by real scalar; c=ab + /* multiplication of vector by real scalar; c=ab */ { - c[0][RE] = a*b[0][RE]; - c[0][IM] = a*b[0][IM]; - c[1][RE] = a*b[1][RE]; - c[1][IM] = a*b[1][IM]; - c[2][RE] = a*b[2][RE]; - c[2][IM] = a*b[2][IM]; + c[0][RE] = a*b[0][RE]; + c[0][IM] = a*b[0][IM]; + c[1][RE] = a*b[1][RE]; + c[1][IM] = a*b[1][IM]; + c[2][RE] = a*b[2][RE]; + c[2][IM] = a*b[2][IM]; } -//============================================================ +/*============================================================*/ INLINE void cScalMultRVec(const double *a,const doublecomplex b,doublecomplex *c) -// complex scalar- real vector[3] multiplication; c=b*a -{ - c[0][RE] = b[RE]*a[0]; - c[0][IM] = b[IM]*a[0]; - c[1][RE] = b[RE]*a[1]; - c[1][IM] = b[IM]*a[1]; - c[2][RE] = b[RE]*a[2]; - c[2][IM] = b[IM]*a[2]; -} - -//============================================================ - -INLINE void cvMultScal_cmplx(const doublecomplex a,doublecomplex *b,doublecomplex *c) -// multiplication of vector[3] by complex scalar; c=ab + /* complex scalar- real vector[3] multiplication; c=b*a */ { - c[0][RE] = a[RE]*b[0][RE] - a[IM]*b[0][IM]; - c[0][IM] = a[RE]*b[0][IM] + a[IM]*b[0][RE]; - c[1][RE] = a[RE]*b[1][RE] - a[IM]*b[1][IM]; - c[1][IM] = a[RE]*b[1][IM] + a[IM]*b[1][RE]; - c[2][RE] = a[RE]*b[2][RE] - a[IM]*b[2][IM]; - c[2][IM] = a[RE]*b[2][IM] + a[IM]*b[2][RE]; + c[0][RE] = b[RE]*a[0]; + c[0][IM] = b[IM]*a[0]; + c[1][RE] = b[RE]*a[1]; + c[1][IM] = b[IM]*a[1]; + c[2][RE] = b[RE]*a[2]; + c[2][IM] = b[IM]*a[2]; } -//============================================================ +/*============================================================*/ INLINE double cvNorm2(doublecomplex *a) -// square of the norm of a complex vector[3] + /* square of the norm of a complex vector[3] */ { - return ( a[0][RE]*a[0][RE] + a[0][IM]*a[0][IM] - + a[1][RE]*a[1][RE] + a[1][IM]*a[1][IM] - + a[2][RE]*a[2][RE] + a[2][IM]*a[2][IM] ); + return (a[0][RE]*a[0][RE] + a[0][IM]*a[0][IM] + + a[1][RE]*a[1][RE] + a[1][IM]*a[1][IM] + + a[2][RE]*a[2][RE] + a[2][IM]*a[2][IM]); } -//============================================================ +/*============================================================*/ INLINE void cDotProd(doublecomplex *a,doublecomplex *b,doublecomplex c) -// conjugate dot product of two complex vector[3]; c=a.b = a[0]*b*[0]+...+a[2]*b*[2]*/ + /* conjugate dot product of two complex vector[3]; c=a.b */ { - c[RE] = a[0][RE]*b[0][RE] + a[0][IM]*b[0][IM] - + a[1][RE]*b[1][RE] + a[1][IM]*b[1][IM] - + a[2][RE]*b[2][RE] + a[2][IM]*b[2][IM]; - c[IM] = a[0][IM]*b[0][RE] - a[0][RE]*b[0][IM] - + a[1][IM]*b[1][RE] - a[1][RE]*b[1][IM] - + a[2][IM]*b[2][RE] - a[2][RE]*b[2][IM]; + c[RE] = a[0][RE]*b[0][RE] + a[0][IM]*b[0][IM] + + a[1][RE]*b[1][RE] + a[1][IM]*b[1][IM] + + a[2][RE]*b[2][RE] + a[2][IM]*b[2][IM]; + c[IM] = a[0][IM]*b[0][RE] - a[0][RE]*b[0][IM] + + a[1][IM]*b[1][RE] - a[1][RE]*b[1][IM] + + a[2][IM]*b[2][RE] - a[2][RE]*b[2][IM]; } -//============================================================ - -INLINE double cDotProd_Re(doublecomplex *a,doublecomplex *b) -// real part of dot product of two complex vector[3]; c=Re(a.b) -{ - return ( a[0][RE]*b[0][RE] + a[0][IM]*b[0][IM] - + a[1][RE]*b[1][RE] + a[1][IM]*b[1][IM] - + a[2][RE]*b[2][RE] + a[2][IM]*b[2][IM] ); -} - -//============================================================ - -INLINE double cDotProd_Im(doublecomplex *a,doublecomplex *b) -// imaginary part of dot product of two complex vector[3]; c=Im(a.b) -{ - return ( a[0][IM]*b[0][RE] - a[0][RE]*b[0][IM] - + a[1][IM]*b[1][RE] - a[1][RE]*b[1][IM] - + a[2][IM]*b[2][RE] - a[2][RE]*b[2][IM] ); -} - -//============================================================ +/*============================================================*/ INLINE void cDotProd_conj(doublecomplex *a,doublecomplex *b,doublecomplex c) -// dot product of two complex vector[3]; c=a.b* = a[0]*b[0]+...+a[2]*b[2] -{ - c[RE] = a[0][RE]*b[0][RE] - a[0][IM]*b[0][IM] - + a[1][RE]*b[1][RE] - a[1][IM]*b[1][IM] - + a[2][RE]*b[2][RE] - a[2][IM]*b[2][IM]; - c[IM] = a[0][IM]*b[0][RE] + a[0][RE]*b[0][IM] - + a[1][IM]*b[1][RE] + a[1][RE]*b[1][IM] - + a[2][IM]*b[2][RE] + a[2][RE]*b[2][IM]; -} - -//============================================================ - -INLINE double cDotProd_conj_Re(doublecomplex *a,doublecomplex *b) -// real part of dot product of two complex vector[3]; c=Re(a.b*) -{ - return ( a[0][RE]*b[0][RE] - a[0][IM]*b[0][IM] - + a[1][RE]*b[1][RE] - a[1][IM]*b[1][IM] - + a[2][RE]*b[2][RE] - a[2][IM]*b[2][IM] ); -} - -//============================================================ - -INLINE double cDotProd_conj_Im(doublecomplex *a,doublecomplex *b) -// imaginary part of dot product of two complex vector[3]; c=Im(a.b*) -{ - return ( a[0][IM]*b[0][RE] + a[0][RE]*b[0][IM] - + a[1][IM]*b[1][RE] + a[1][RE]*b[1][IM] - + a[2][IM]*b[2][RE] + a[2][RE]*b[2][IM] ); -} - -//============================================================ - -INLINE void cvAdd(doublecomplex *a,doublecomplex *b,doublecomplex *c) -// add two complex vector[3]; c=a+b + /* dot product of two complex vector[3]; c=a.b* */ { - c[0][RE] = a[0][RE] + b[0][RE]; - c[0][IM] = a[0][IM] + b[0][IM]; - c[1][RE] = a[1][RE] + b[1][RE]; - c[1][IM] = a[1][IM] + b[1][IM]; - c[2][RE] = a[2][RE] + b[2][RE]; - c[2][IM] = a[2][IM] + b[2][IM]; + c[RE] = a[0][RE]*b[0][RE] - a[0][IM]*b[0][IM] + + a[1][RE]*b[1][RE] - a[1][IM]*b[1][IM] + + a[2][RE]*b[2][RE] - a[2][IM]*b[2][IM]; + c[IM] = a[0][IM]*b[0][RE] + a[0][RE]*b[0][IM] + + a[1][IM]*b[1][RE] + a[1][RE]*b[1][IM] + + a[2][IM]*b[2][RE] + a[2][RE]*b[2][IM]; } -//============================================================ +/*============================================================*/ INLINE void cvSubtr(doublecomplex *a,doublecomplex *b,doublecomplex *c) -// subtraction of two complex vector[3]; c=a-b + /* subtraction of two complex vector[3]; c=a-b */ { - c[0][RE] = a[0][RE] - b[0][RE]; - c[0][IM] = a[0][IM] - b[0][IM]; - c[1][RE] = a[1][RE] - b[1][RE]; - c[1][IM] = a[1][IM] - b[1][IM]; - c[2][RE] = a[2][RE] - b[2][RE]; - c[2][IM] = a[2][IM] - b[2][IM]; + c[0][RE] = a[0][RE] - b[0][RE]; + c[0][IM] = a[0][IM] - b[0][IM]; + c[1][RE] = a[1][RE] - b[1][RE]; + c[1][IM] = a[1][IM] - b[1][IM]; + c[2][RE] = a[2][RE] - b[2][RE]; + c[2][IM] = a[2][IM] - b[2][IM]; } -//============================================================ +/*============================================================*/ INLINE void crDotProd(doublecomplex *a,const double *b,doublecomplex c) -// dot product of complex and real vectors[3]; c=a.b + /* dot product of complex and real vectors[3]; c=a.b */ { - c[RE] = a[0][RE]*b[0] + a[1][RE]*b[1] + a[2][RE]*b[2]; - c[IM] = a[0][IM]*b[0] + a[1][IM]*b[1] + a[2][IM]*b[2]; + c[RE] = a[0][RE]*b[0] + a[1][RE]*b[1] + a[2][RE]*b[2]; + c[IM] = a[0][IM]*b[0] + a[1][IM]*b[1] + a[2][IM]*b[2]; } -//============================================================ +/*============================================================*/ -INLINE double crDotProd_Re(doublecomplex *a,const double *b) -// real part of dot product of complex and real vectors[3]; c=Re(a.b) +INLINE void cvIncremScaled_cmplx(doublecomplex *a,doublecomplex b,doublecomplex *c) + /* increment of complex vectors[3] by complex-scaled other vector; c+=b*a */ { - return (a[0][RE]*b[0] + a[1][RE]*b[1] + a[2][RE]*b[2]); + c[0][RE] += b[RE]*a[0][RE] - b[IM]*a[0][IM]; + c[0][IM] += b[RE]*a[0][IM] + b[IM]*a[0][RE]; + c[1][RE] += b[RE]*a[1][RE] - b[IM]*a[1][IM]; + c[1][IM] += b[RE]*a[1][IM] + b[IM]*a[1][RE]; + c[2][RE] += b[RE]*a[2][RE] - b[IM]*a[2][IM]; + c[2][IM] += b[RE]*a[2][IM] + b[IM]*a[2][RE]; } - -//============================================================ - -INLINE double crDotProd_Im(doublecomplex *a,const double *b) -// imaginary part of dot product of complex and real vectors[3]; c=Im(a.b) -{ - return (a[0][IM]*b[0] + a[1][IM]*b[1] + a[2][IM]*b[2]); -} - -//============================================================ - -INLINE void cvIncremScaled_cmplx(doublecomplex *a,const doublecomplex b,doublecomplex *c) -// increment of complex vectors[3] by complex-scaled other vector; c+=b*a -{ - c[0][RE] += b[RE]*a[0][RE] - b[IM]*a[0][IM]; - c[0][IM] += b[RE]*a[0][IM] + b[IM]*a[0][RE]; - c[1][RE] += b[RE]*a[1][RE] - b[IM]*a[1][IM]; - c[1][IM] += b[RE]*a[1][IM] + b[IM]*a[1][RE]; - c[2][RE] += b[RE]*a[2][RE] - b[IM]*a[2][IM]; - c[2][IM] += b[RE]*a[2][IM] + b[IM]*a[2][RE]; -} -//============================================================ +/*============================================================*/ INLINE void cvMultAdd(doublecomplex *a,const doublecomplex b,doublecomplex *c) -// multiply complex vectors[3] with complex constant and add another vector; c=b*c+a + /* multiply complex vectors[3] with complex constant and add another vector; + c=b*c+a */ { - double tmp; - tmp=c[0][RE]; - c[0][RE] = c[0][RE]*b[RE] - c[0][IM]*b[IM] + a[0][RE]; - c[0][IM] = tmp*b[IM] + c[0][IM]*b[RE] + a[0][IM]; - tmp=c[1][RE]; - c[1][RE] = c[1][RE]*b[RE] - c[1][IM]*b[IM] + a[1][RE]; - c[1][IM] = tmp*b[IM] + c[1][IM]*b[RE] + a[1][IM]; - tmp=c[2][RE]; - c[2][RE] = c[2][RE]*b[RE] - c[2][IM]*b[IM] + a[2][RE]; - c[2][IM] = tmp*b[IM] + c[2][IM]*b[RE] + a[2][IM]; + double tmp; + tmp=c[0][RE]; + c[0][RE] = c[0][RE]*b[RE] - c[0][IM]*b[IM] + a[0][RE]; + c[0][IM] = tmp*b[IM] + c[0][IM]*b[RE] + a[0][IM]; + tmp=c[1][RE]; + c[1][RE] = c[1][RE]*b[RE] - c[1][IM]*b[IM] + a[1][RE]; + c[1][IM] = tmp*b[IM] + c[1][IM]*b[RE] + a[1][IM]; + tmp=c[2][RE]; + c[2][RE] = c[2][RE]*b[RE] - c[2][IM]*b[IM] + a[2][RE]; + c[2][IM] = tmp*b[IM] + c[2][IM]*b[RE] + a[2][IM]; } -//============================================================ +/*============================================================*/ INLINE void cvLinComb1(doublecomplex *a,doublecomplex *b, const double c1,doublecomplex *c) -// linear combination of complex vectors[3]; second coefficient is unity; c=c1*a+b + /* linear combination of complex vectors[3]; second coef is unity; c=c1*a+b */ { - c[0][RE] = c1*a[0][RE] + b[0][RE]; - c[0][IM] = c1*a[0][IM] + b[0][IM]; - c[1][RE] = c1*a[1][RE] + b[1][RE]; - c[1][IM] = c1*a[1][IM] + b[1][IM]; - c[2][RE] = c1*a[2][RE] + b[2][RE]; - c[2][IM] = c1*a[2][IM] + b[2][IM]; + c[0][RE] = c1*a[0][RE] + b[0][RE]; + c[0][IM] = c1*a[0][IM] + b[0][IM]; + c[1][RE] = c1*a[1][RE] + b[1][RE]; + c[1][IM] = c1*a[1][IM] + b[1][IM]; + c[2][RE] = c1*a[2][RE] + b[2][RE]; + c[2][IM] = c1*a[2][IM] + b[2][IM]; } -//============================================================ +/*============================================================*/ INLINE void cvLinComb1_cmplx(doublecomplex *a,doublecomplex *b, const doublecomplex c1,doublecomplex *c) -/* linear combination of complex vectors[3] with complex coefficients; - * second coefficient is unity; c=c1*a+b !!! c!=a - */ + /* linear combination of complex vectors[3] with complex coefficients; + second coef is unity; c=c1*a+b !!! c!=a */ { - c[0][RE] = a[0][RE]*c1[RE] - a[0][IM]*c1[IM] + b[0][RE]; - c[0][IM] = a[0][RE]*c1[IM] + a[0][IM]*c1[RE] + b[0][IM]; - c[1][RE] = a[1][RE]*c1[RE] - a[1][IM]*c1[IM] + b[1][RE]; - c[1][IM] = a[1][RE]*c1[IM] + a[1][IM]*c1[RE] + b[1][IM]; - c[2][RE] = a[2][RE]*c1[RE] - a[2][IM]*c1[IM] + b[2][RE]; - c[2][IM] = a[2][RE]*c1[IM] + a[2][IM]*c1[RE] + b[2][IM]; + c[0][RE] = a[0][RE]*c1[RE] - a[0][IM]*c1[IM] + b[0][RE]; + c[0][IM] = a[0][RE]*c1[IM] + a[0][IM]*c1[RE] + b[0][IM]; + c[1][RE] = a[1][RE]*c1[RE] - a[1][IM]*c1[IM] + b[1][RE]; + c[1][IM] = a[1][RE]*c1[IM] + a[1][IM]*c1[RE] + b[1][IM]; + c[2][RE] = a[2][RE]*c1[RE] - a[2][IM]*c1[IM] + b[2][RE]; + c[2][IM] = a[2][RE]*c1[IM] + a[2][IM]*c1[RE] + b[2][IM]; } -//============================================================ +/*============================================================*/ INLINE void cSymMatrVec(doublecomplex *matr,doublecomplex *vec,doublecomplex *res) -// multiplication of complex symmetric matrix[6] by complex vec[3]; res=matr.vec -{ - res[0][RE] = matr[0][RE]*vec[0][RE] - matr[0][IM]*vec[0][IM] - + matr[1][RE]*vec[1][RE] - matr[1][IM]*vec[1][IM] - + matr[2][RE]*vec[2][RE] - matr[2][IM]*vec[2][IM]; - res[0][IM] = matr[0][RE]*vec[0][IM] + matr[0][IM]*vec[0][RE] - + matr[1][RE]*vec[1][IM] + matr[1][IM]*vec[1][RE] - + matr[2][RE]*vec[2][IM] + matr[2][IM]*vec[2][RE]; - - res[1][RE] = matr[1][RE]*vec[0][RE] - matr[1][IM]*vec[0][IM] - + matr[3][RE]*vec[1][RE] - matr[3][IM]*vec[1][IM] - + matr[4][RE]*vec[2][RE] - matr[4][IM]*vec[2][IM]; - res[1][IM] = matr[1][RE]*vec[0][IM] + matr[1][IM]*vec[0][RE] - + matr[3][RE]*vec[1][IM] + matr[3][IM]*vec[1][RE] - + matr[4][RE]*vec[2][IM] + matr[4][IM]*vec[2][RE]; - - res[2][RE] = matr[2][RE]*vec[0][RE] - matr[2][IM]*vec[0][IM] - + matr[4][RE]*vec[1][RE] - matr[4][IM]*vec[1][IM] - + matr[5][RE]*vec[2][RE] - matr[5][IM]*vec[2][IM]; - res[2][IM] = matr[2][RE]*vec[0][IM] + matr[2][IM]*vec[0][RE] - + matr[4][RE]*vec[1][IM] + matr[4][IM]*vec[1][RE] - + matr[5][RE]*vec[2][IM] + matr[5][IM]*vec[2][RE]; -} - -//============================================================ -// operations on real vectors + /* multiplication of complex symmetric matrix[6] by complex vec[3] + res=matr.vec */ +{ + res[0][RE] = matr[0][RE] * vec[0][RE] - matr[0][IM] * vec[0][IM] + + matr[1][RE] * vec[1][RE] - matr[1][IM] * vec[1][IM] + + matr[2][RE] * vec[2][RE] - matr[2][IM] * vec[2][IM]; + res[0][IM] = matr[0][RE] * vec[0][IM] + matr[0][IM] * vec[0][RE] + + matr[1][RE] * vec[1][IM] + matr[1][IM] * vec[1][RE] + + matr[2][RE] * vec[2][IM] + matr[2][IM] * vec[2][RE]; + + res[1][RE] = matr[1][RE] * vec[0][RE] - matr[1][IM] * vec[0][IM] + + matr[3][RE] * vec[1][RE] - matr[3][IM] * vec[1][IM] + + matr[4][RE] * vec[2][RE] - matr[4][IM] * vec[2][IM]; + res[1][IM] = matr[1][RE] * vec[0][IM] + matr[1][IM] * vec[0][RE] + + matr[3][RE] * vec[1][IM] + matr[3][IM] * vec[1][RE] + + matr[4][RE] * vec[2][IM] + matr[4][IM] * vec[2][RE]; + + res[2][RE] = matr[2][RE] * vec[0][RE] - matr[2][IM] * vec[0][IM] + + matr[4][RE] * vec[1][RE] - matr[4][IM] * vec[1][IM] + + matr[5][RE] * vec[2][RE] - matr[5][IM] * vec[2][IM]; + res[2][IM] = matr[2][RE] * vec[0][IM] + matr[2][IM] * vec[0][RE] + + matr[4][RE] * vec[1][IM] + matr[4][IM] * vec[1][RE] + + matr[5][RE] * vec[2][IM] + matr[5][IM] * vec[2][RE]; +} + +/*============================================================*/ +/* operations on real vectors */ INLINE void MultScal(const double a,const double *b,double *c) -// multiplication of vector by scalar; c=a*b + /* multiplication of vector by scalar; c=a*b */ { - c[0]=a*b[0]; - c[1]=a*b[1]; - c[2]=a*b[2]; + c[0]=a*b[0]; + c[1]=a*b[1]; + c[2]=a*b[2]; } -//============================================================ +/*============================================================*/ INLINE void vMult(const double *a,const double *b,double *c) -// multiplication of two vectors (by elements); c[i]=a[i]*b[i] + /* multiplication of two vectors (by elements); c[i]=a[i]*b[i] */ { - c[0]=a[0]*b[0]; - c[1]=a[1]*b[1]; - c[2]=a[2]*b[2]; + c[0]=a[0]*b[0]; + c[1]=a[1]*b[1]; + c[2]=a[2]*b[2]; } -//============================================================ +/*============================================================*/ INLINE double DotProd(const double *a,const double *b) -// dot product of two real vectors[3] + /* dot product of two real vectors[3] */ { - return (a[0]*b[0]+a[1]*b[1]+a[2]*b[2]); + return (a[0]*b[0]+a[1]*b[1]+a[2]*b[2]); } -//============================================================ +/*============================================================*/ INLINE void LinComb(const double *a,const double *b, - const double c1,const double c2, double *c) -// linear combination of real vectors[3]; c=c1*a+c2*b + const double c1,const double c2, double *c) + /* linear combination of real vectors[3]; c=c1*a+c2*b */ { - c[0]=c1*a[0]+c2*b[0]; - c[1]=c1*a[1]+c2*b[1]; - c[2]=c1*a[2]+c2*b[2]; + c[0]=c1*a[0]+c2*b[0]; + c[1]=c1*a[1]+c2*b[1]; + c[2]=c1*a[2]+c2*b[2]; } -//============================================================ +/*============================================================*/ INLINE double TrSym(const double *a) -// trace of a symmetric matrix stored as a vector of size 6 + /* trace of a symmetric matrix stored as a vector of size 6 */ { - return (a[0]+a[2]+a[5]); + return (a[0]+a[2]+a[5]); } -//============================================================ +/*============================================================*/ INLINE double QuadForm(const double *matr,const double *vec) -// value of a quadratic form matr (symmetric matrix stored as a vector of size 6) over a vector vec + /* value of a quadratic form matr (symmetric matrix stored as + a vector of size 6) over a vector vec */ { - return ( vec[0]*vec[0]*matr[0] + vec[1]*vec[1]*matr[2] + vec[2]*vec[2]*matr[5] - + 2*(vec[0]*vec[1]*matr[1] + vec[0]*vec[2]*matr[3] + vec[1]*vec[2]*matr[4]) ); + return (vec[0]*vec[0]*matr[0]+vec[1]*vec[1]*matr[2]+vec[2]*vec[2]*matr[5]+ + 2*(vec[0]*vec[1]*matr[1]+vec[0]*vec[2]*matr[3]+vec[1]*vec[2]*matr[4])); } -//============================================================ +/*============================================================*/ INLINE void MatrVec(double matr[3][3],const double *vec, double *res) -// multiplication of matrix[3][3] by vec[3] (all real); res=matr.vec + /* multiplication of matrix[3][3] by vec[3] (all real) + res=matr.vec */ { - res[0]=matr[0][0]*vec[0]+matr[0][1]*vec[1]+matr[0][2]*vec[2]; - res[1]=matr[1][0]*vec[0]+matr[1][1]*vec[1]+matr[1][2]*vec[2]; - res[2]=matr[2][0]*vec[0]+matr[2][1]*vec[1]+matr[2][2]*vec[2]; + res[0]=matr[0][0]*vec[0]+matr[0][1]*vec[1]+matr[0][2]*vec[2]; + res[1]=matr[1][0]*vec[0]+matr[1][1]*vec[1]+matr[1][2]*vec[2]; + res[2]=matr[2][0]*vec[0]+matr[2][1]*vec[1]+matr[2][2]*vec[2]; } -//============================================================ +/*============================================================*/ INLINE void Permutate(double *vec,const int *ord) -// permutate double vector vec using permutation ord + /* permutate double vector vec using permutation ord */ { - double buf[3]; + double buf[3]; - memcpy(buf,vec,3*sizeof(double)); - vec[0]=buf[ord[0]]; - vec[1]=buf[ord[1]]; - vec[2]=buf[ord[2]]; + memcpy(buf,vec,3*sizeof(double)); + vec[0]=buf[ord[0]]; + vec[1]=buf[ord[1]]; + vec[2]=buf[ord[2]]; } -//============================================================ +/*============================================================*/ INLINE void Permutate_i(int *vec,const int *ord) -// permutate int vector vec using permutation ord + /* permutate int vector vec using permutation ord */ { - int buf[3]; + int buf[3]; - memcpy(buf,vec,3*sizeof(int)); - vec[0]=buf[ord[0]]; - vec[1]=buf[ord[1]]; - vec[2]=buf[ord[2]]; + memcpy(buf,vec,3*sizeof(int)); + vec[0]=buf[ord[0]]; + vec[1]=buf[ord[1]]; + vec[2]=buf[ord[2]]; } -//============================================================ -// Auxiliary functions +/*=====================================================================*/ +/* Auxillary functions */ INLINE double Deg2Rad(const double deg) -// transforms angle in degrees to radians + /* transforms angle in degrees to radians */ { - return (PI_OVER_180*deg); + return (PI_OVER_180*deg); } -//============================================================ +/*=====================================================================*/ INLINE double Rad2Deg(const double rad) -// transforms angle in radians to degrees + /* transforms angle in radians to degrees */ { - return (INV_PI_180*rad); + return (INV_PI_180*rad); } -#endif // __cmplx_h +#endif /*__cmplx_h*/ diff --git a/src/comm.c b/src/comm.c index cd24b65d..6668293b 100644 --- a/src/comm.c +++ b/src/comm.c @@ -1,669 +1,488 @@ /* FILE : comm.c - * AUTH : Maxim Yurkin + * AUTH : Maxim Yurkin * DESCR: The main intention of this library is to incorporate all - * parallelization related code, so most of it is directly - * involved in or closely related to interprocess communication, + * parallelisation related code, so most of it is directly + * involved in or closely related to inter-proces communication, * hence its name. * * Previous versions were by Martijn Frijlink * - * Copyright (C) 2006-2008 University of Amsterdam + * Copyright (C) 2006 M.A. Yurkin and A.G. Hoekstra * This code is covered by the GNU General Public License. */ #include -#include -#include #include "vars.h" +#include "debug.h" +#include "cmplx.h" #include "comm.h" #include "const.h" #include "io.h" #include "fft.h" -#include "memory.h" -#include "timing.h" -#include "function.h" -#include "parbas.h" - -// for getch in Stop +/* for getch in Stop */ #ifdef RUN_BCB # include #endif #ifdef MPI -MPI_Datatype mpi_dcomplex; + #include + MPI_Datatype mpi_dcomplex; #endif -/* whether a synchronize call should be performed before parallel timing. It makes communication - * timing more accurate, but may deteriorate overall performance by introducing unnecessary - * delays (test showed only slight difference for granule generator) */ -#define SYNCHRONIZE_TIMING - -// SEMI-GLOBAL VARIABLES +/* SEMI-GLOBAL VARIABLES */ -// defined and allocated in fft.c +/* defined and allocated in fft.c */ extern double *BT_buffer, *BT_rbuffer; -// defined and initialized in timing.c -extern TIME_TYPE Timing_Dm_Init_comm; -// LOCAL VARIABLES +/* LOCAL VARIABLES */ -#ifdef PARALLEL -static int Ntrans; // number of transmissions; used in CalcPartner -static int *gr_comm_size; // sizes of transmissions for granule generator communications -static int *gr_comm_overl; // shows whether two sequential transmissions overlap -static unsigned char *gr_comm_ob; // buffer for overlaps -static void *gr_comm_buf; // buffer for MPI transfers +static int Ntrans; /* number of transmissions; used in CalcPartner */ -// First several functions are defined only in parallel mode -//=========================================== +#ifdef PARALLEL +/* First funtions that are defined only in parallel mode */ +/*===========================================*/ static void RecoverCommandLine(int *argc_p,char ***argv_p) -/* eliminate all NULL pointers from argv, shift the rest, and adjust argc accordingly. - * Used in InitComm - * */ + /* eliminate all NULL pointers from argv, shift the rest, and + adjust argc accordingly. Used in InitComm */ { - int i,j; + int i,j; - for (i=0,j=0;i<(*argc_p);i++) { - if ((*argv_p)[i]==NULL) j++; - else if (j!=0) (*argv_p)[i-j]=(*argv_p)[i]; - } - (*argc_p)-=j; + for (i=0,j=0;i<(*argc_p);i++) { + if ((*argv_p)[i]==NULL) j++; + else if (j!=0) (*argv_p)[i-j]=(*argv_p)[i]; + } + (*argc_p)-=j; } -//============================================================ +/*============================================================*/ -INLINE size_t IndexBlock(const size_t x,const size_t y,const size_t z,const size_t lengthY) -// index block; used in BlockTranspose +INLINE int IndexBlock(const int x,const int y,const int z,const int lengthY) + /* index block; used in BlockTranspose */ { - return((z*lengthY+y)*gridX+x); + return((z*lengthY+y)*gridX+x); } -//============================================================ +/*============================================================*/ INLINE int CalcPartner(const int tran) -/* calculate ringid of partner processor for current transmission; used in BlockTranspose. Many - * different implementations are possible; the only requirements are - * 1) f(tran,f(tran,ringid))=ringid - * 2) f({1,2,Ntrans},ringid)={0,1,Ntrans}\ringid - * where f=nprocs is equivalent to skipping this transmission (relevant for odd nprocs) - */ + /* calculate ringid of partner processor for current transmission; + used in BlockTranspose + many different implementations are possible; the only requirements are + 1) f(tran,f(tran,ringid))=ringid + 2) f({1,2,Ntrans},ringid)={0,1,Ntrans}\ringid + where f=nprocs <=> skip this transmission (for odd nprocs) */ { - int part; - - if (ringid==0) part=tran; - else if (ringid==tran) part=0; - else { - part=2*tran-ringid; - if (part<=0) part+=Ntrans; - else if (part>Ntrans) part-=Ntrans; - } - return part; + int part; + + if (ringid==0) part=tran; + else if (ringid==tran) part=0; + else { + part=2*tran-ringid; + if (part<=0) part+=Ntrans; + else if (part>Ntrans) part-=Ntrans; + } + return part; } -//============================================================ +/*===========================================*/ void CatNFiles(const char *dir,const char *tmpl,const char *dest) -/* cat several temporary files (one for each processor, names defined by the template 'tmpl' that - * should contain %d to be replaced by ringid). Files are located in directory 'dir'. Combined into - * 'dest' in the same directory. Afterwards temporary files are removed. - */ + /* cat several temporary files (one for each processor, names defines by the template 'temp' + that should contain %d to be replaced by ringid). Files are located in directory 'dir'. + Combined into 'dest' in the same directory. Afterwards temporary files are removed. + Employs system call to cat (not portable to windows), but the routine itself is used + only in parallel mode */ { - int i,c; - FILE *in,*out; - char fname_out[MAX_TMP_FNAME],fname_in[MAX_TMP_FNAME]; - - // produce full path of destination file and open it - sprintf(fname_out,"%s/%s",directory,dest); - out=FOpenErr(fname_out,"w",ONE_POS); - for (i=0;i %s",dest); + /* execute command */ + if (system(buf)) { /* check for system error */ + sprintf(buf,"Failed to combine files '%s ... %s' in directory '%%s' into file '%%s'."\ + "You can do it manually",tmpl,tmpl); + LogError(EC_WARN,ONE_POS,buf,0,nprocs-1,dir,dest); + } + else for (i=0;i boxZ) local_z1_coer=boxZ; - else local_z1_coer=local_z1; - unitX=gridX/nprocs; - local_x0=ringid*unitX; - local_x1=(ringid+1)*unitX; + int unitZ,unitX; + + unitZ=ceil(((double)smallZ)/((double)nprocs)); + local_z0=ringid*unitZ; + local_z1=(ringid+1)*unitZ; + if (local_z1 > boxZ) local_z1_coer=boxZ; + else local_z1_coer=local_z1; + unitX=ceil(((double)gridX)/((double)nprocs)); + local_x0=ringid*unitX; + local_x1=(ringid+1)*unitX; #else - local_z0=0; - local_z1=smallZ; - local_z1_coer=boxZ; - local_x0=0; - local_x1=gridX; + local_z0=0; + local_z1=smallZ; + local_z1_coer=boxZ; + local_x0=0; + local_x1=gridX; #endif - if (local_z1_coer<=local_z0) { - LogError(EC_INFO,ALL_POS,"No real dipoles are assigned"); - local_z1_coer=local_z0; - } - local_Nz=local_z1-local_z0; - local_Nx=local_x1-local_x0; - local_Ndip=MultOverflow(boxX*(size_t)boxY,local_z1_coer-local_z0,ALL_POS,"local_Ndip"); - /* conversions to (unsigned long) are needed (to remove warnings) because %z printf argument is - * not yet supported by all target compiler environments - */ - printf("%i : %i %i %i %lu %lu \n", - ringid,local_z0,local_z1_coer,local_z1,(unsigned long)local_Ndip,(unsigned long)local_Nx); + if (local_z1_coer<=local_z0) { + LogError(EC_INFO,ONE_POS,"No real dipoles are assigned"); + local_z1_coer=local_z0; + } + local_Nz=local_z1-local_z0; + local_Nx=local_x1-local_x0; + local_d0=boxX*boxY*local_z0; + local_d1=boxX*boxY*local_z1_coer; + local_Ndip=local_d1-local_d0; + printf("%i : %i %i %i %i %i %i\n", + ringid,local_z0,local_z1_coer,local_z1,local_Ndip,local_Nx); } -//============================================================ +/*===========================================*/ -void AllGather(void *x_from,void *x_to,const var_type type,size_t n_elem) -// Gather distributed arrays; works for all types +void AllGather(void *x_from,void *x_to,const var_type type,int n_elem) + /* Gather distributed arrays; works for all types */ { #ifdef MPI - // TODO: need to be rewritten when n_elem are unequal on each processor - MPI_Datatype mes_type; - - if (type==char_type) mes_type = MPI_CHAR; - else if (type==int_type) mes_type = MPI_INT; - else if (type==double_type) mes_type = MPI_DOUBLE; - else if (type==cmplx_type) { - mes_type = MPI_DOUBLE; - n_elem *= 2; - } - else LogError(EC_ERROR,ONE_POS,"AllGather: variable type %u is not supported",type); - - MPI_Allgather(x_from,n_elem,mes_type,x_to,n_elem,mes_type,MPI_COMM_WORLD); -#endif -} - - -//============================================================ - -#ifdef PARALLEL -void CalcLocalGranulGrid(const double z0,const double z1,const double gdZ,const int gZ, - const int id,int *lz0,int *lz1) -/* calculates starting and ending (+1) cell of granule grid (lz0 & lz1) on a processor with - * ringid=id - */ -{ - int dzl,dzh; // similar to local_z0 and local_z1 - - dzl=local_Nz*id; - // should not be coerced because the result differs only for dzh>boxZ, then dzh-1>z0 - dzh=dzl+local_Nz; - if (dzl>z1) *lz0=*lz1=gZ; - else { - if (dzl>z0) *lz0=(int)floor((dzl-z0)/gdZ); - else *lz0=0; - if (dzh>z1) *lz1=gZ; - else if (dzh-1>z0) *lz1=(int)floor((dzh-z0-1)/gdZ)+1; - else *lz1=0; - } -} -#endif - -//============================================================ - -void SetGranulComm(const double z0,const double z1,const double gdZ,const int gZ,const size_t gXY, - size_t max_gran,int *lz0,int *lz1,const int sm_gr) -/* sets communication for granule generator; max_gran - maximum number of granules in one set - * (used to allocate buffer); sm_gr - whether granules are small (simpler) - */ -{ -#ifdef PARALLEL - int i,loc0,loc1,loc1_prev=0; - - MALLOC_VECTOR(gr_comm_buf,void,max_gran*sizeof(char),ALL); - if (!sm_gr) { - if (ringid==ROOT) { - MALLOC_VECTOR(gr_comm_size,int,nprocs,ONE); - MALLOC_VECTOR(gr_comm_overl,int,nprocs-1,ONE); - // always allocated, not to mess with its freeing - MALLOC_VECTOR(gr_comm_ob,uchar,gXY,ONE); - /* The following is very inefficient (may be significantly optimized), but using one - * common function is more robust. - */ - for (i=0;i=0;i--) { - if (gr_comm_size[i]!=0) { - if (gr_comm_overl[i]) { - memcpy(gr_comm_ob,dom+index,unit); - index+=gXY; - } - MPI_Recv(dom+index-gXY*gr_comm_size[i],unit*gr_comm_size[i],MPI_UNSIGNED_CHAR,i,0, - MPI_COMM_WORLD,&status); - if (gr_comm_overl[i]) for (j=0;j (B)) ? (B) : (A)) #define MAX(A,B) (((A) < (B)) ? (B) : (A)) -#define IS_EVEN(A) (((A)%2) == 0) -#define LENGTH(A) ((int)(sizeof(A)/sizeof(A[0]))) // length of any array (converted to int) - -// parallel definitions -#ifdef MPI -#define PARALLEL -#endif - -/* ringid of root processor. Using ROOT!=0 should work, however it was not thoroughly tested. - * Hence do not change without necessity. - */ -#define ROOT 0 - -// math constants rounded for 32 decimals -#define PI 3.1415926535897932384626433832795 -#define TWO_PI 6.283185307179586476925286766559 -#define FOUR_PI 12.566370614359172953850573533118 -#define EIGHT_PI 25.132741228718345907701147066236 -#define FOUR_PI_OVER_THREE 4.1887902047863909846168578443727 -#define PI_OVER_TWO 1.5707963267948966192313216916398 -#define PI_OVER_FOUR 0.78539816339744830961566084581988 -#define PI_OVER_SIX 0.52359877559829887307710723054658 -#define INV_PI 0.31830988618379067153776752674503 -#define TWO_OVER_PI 0.63661977236758134307553505349006 -#define THREE_OVER_FOUR_PI 0.23873241463784300365332564505877 -#define SIX_OVER_PI 1.9098593171027440292266051604702 -#define ONE_THIRD 0.33333333333333333333333333333333 -#define PI_OVER_180 0.017453292519943295769236907684886 -#define INV_PI_180 57.295779513082320876798154814105 -#define EULER 0.57721566490153286060651209008241 -#define FULL_ANGLE 360.0 - -// determines the maximum number representable by size_t -#ifndef SIZE_MAX -#define SIZE_MAX ((size_t)-1) -#endif - -// sets the maximum box size; otherwise 'position' should be changed -#define BOX_MAX USHRT_MAX - -// sizes of some arrays -#define MAX_NMAT 15 // maximum number of different refractive indices (<256) -#define MAX_N_SH_PARMS 25 // maximum number of shape parameters -#define MAX_N_BEAM_PARMS 4 // maximum number of beam parameters - -// sizes of filenames and other strings -#define MAX_DIRNAME 300 // maximum length of dirname; increase THIS if any errors appear -#define MAX_FNAME_SH 100 // maximum length of filename (used for known names) -#define MAX_TMP_FNAME_SH 15 // maximum length of names of temporary files (short) -#define MAX_SYSTEM_CALL 10 // maximum string length of system call (itself) -#define MAX_WORD 10 // maximum length of a short word -#define MAX_LINE 50 // maximum length of a line - // size of buffer for reading lines (longer lines are handled robustly) -#define BUF_LINE 150 -#define MAX_PARAGRAPH 600 // maximum length of a paragraph (few lines) - -// derived sizes - // maximum string to create directory +#define LENGTH(A) (sizeof(A)/sizeof(A[0])) /* length of any array */ + +/* complex numbers */ +typedef double doublecomplex[2]; /* complies with FFTW3 definition */ +#define RE 0 +#define IM 1 + +/* math constants rounded for 32 decimals. */ +#define PI 3.1415926535897932384626433832795 +#define TWO_PI 6.283185307179586476925286766559 +#define PI_OVER_TWO 1.5707963267948966192313216916398 +#define PI_OVER_FOUR 0.78539816339744830961566084581988 +#define TWO_OVER_PI 0.63661977236758134307553505349006 +#define ONE_THIRD 0.33333333333333333333333333333333 +#define PI_OVER_180 0.017453292519943295769236907684886 +#define INV_PI_180 57.295779513082320876798154814105 + +/* sizes of some arrays */ +#define MAX_NMAT 10 /* maximum different materials (<128) */ +#define MAX_N_SH_PARMS 25 /* maximum shape parameters */ + +/* sizes of filenames and other strings */ + /* maximum length of dirname; increase THIS if any errors appear */ +#define MAX_DIRNAME 300 +#define MAX_FNAME_SH 100 /* maximum length of filename (used for known names) */ +#define MAX_TMP_FNAME 15 /* maximum length of names of temporary files (short) */ +#define MAX_SYSTEM_CALL 10 /* maximum string length of system call (itself) */ +#define MAX_WORD 10 /* maximum length of a short word */ +#define MAX_LINE 50 /* maximum length of a line */ + /* size of buffer for reading lines (longer lines are handled robustly) */ +#define BUF_LINE 100 +#define MAX_PARAGRAPH 300 /* maximum length of a paragraph (few lines) */ +/* derived sizes */ + /* maximum string to create directory */ #define MAX_DIRSYS (MAX_DIRNAME + MAX_SYSTEM_CALL) - // maximum length of filename (including directory name) + /* maximum length of filename (including directory name) */ #define MAX_FNAME (MAX_DIRNAME + MAX_FNAME_SH) - // maximum length of temporary filename (including directory name) -#define MAX_TMP_FNAME (MAX_DIRNAME + MAX_TMP_FNAME_SH) - // maximum message that may include a filename (for PrintError) -#define MAX_MESSAGE (MAX_FNAME + MAX_PARAGRAPH) - // maximum message that may include 2 filenames (for LogError) -#define MAX_MESSAGE2 (2*MAX_FNAME + MAX_PARAGRAPH) - -// widths of terminal used for output -#define DEF_TERM_WIDTH 80 // default -#define MIN_TERM_WIDTH 20 // ADDA never takes value less than that from environmental variables - -// shape types -#define SH_SPHERE 0 // sphere -#define SH_BOX 1 // box (may be rectangular) -#define SH_PRISMA 2 // prisma (triangular) -- not operational -#define SH_LINE 3 // line with width of one dipole -#define SH_COATED 4 // coated sphere -#define SH_SPHEREBOX 5 // sphere in a box -#define SH_RBC 6 // Red Blood Cell -#define SH_ELLIPSOID 7 // general ellipsoid -#define SH_SDISK_ROT 8 // disc cut of a sphere -- not operational -#define SH_CYLINDER 9 // cylinder -#define SH_READ 10 // read from file -#define SH_EGG 11 // egg -#define SH_CAPSULE 12 // capsule -#define SH_AXISYMMETRIC 13 // axisymmetric -/* TO ADD NEW SHAPE - * add a define starting with 'SH_' here; the number should be different from any others in this - * list. Add a descriptive comment. - */ - -// which way to calculate coupleconstant -#define POL_CM 0 // Clausius-Mossotti -#define POL_RR 1 // Radiative Reaction correction -#define POL_LDR 2 // Lattice Dispersion Relation -#define POL_CLDR 3 // Corrected Lattice Dispersion Relation -#define POL_FCD 4 // Filtered Coupled Dipoles -#define POL_SO 5 // Second Order formulation - -// how to calculate scattering quantities -#define SQ_DRAINE 0 // classical, as Draine -#define SQ_SO 1 // Second Order formulation - -// how to calculate interaction term -#define G_POINT_DIP 0 // as point dipoles -#define G_FCD 1 // Filtered Green's tensor (Filtered Coupled Dipoles) -#define G_FCD_ST 2 // quasi-static version of FCD -#define G_SO 3 // Second Order formulation - -// ldr constants -#define LDR_B1 1.8915316 -#define LDR_B2 -0.1648469 -#define LDR_B3 1.7700004 - -// 2nd_order constants -#define SO_B1 1.5867182 -#define SO_B2 0.13488017 -#define SO_B3 0.11895826 - -// two boundaries for separation between G_SO 'close', 'median', and 'far' -#define G_BOUND_CLOSE 1 // k*R^2/d < GB_CLOSE => 'close' -#define G_BOUND_MEDIAN 1 // k*R < GB_MEDIAN => 'median' - -// iterative methods; see iterative.c for info -#define IT_CGNR 0 -#define IT_BICGSTAB 1 -#define IT_BICG_CS 2 -#define IT_QMR_CS 3 - -// type of E field calculation -#define CE_NORMAL 0 // normal -#define CE_PARPER 1 // use symmetry to calculate both incident polarizations - // from one calculation of internal fields - -// path and size of tables + /* maximum message that may include 2 filenames */ +#define MAX_MESSAGE (2*MAX_FNAME + MAX_PARAGRAPH) + +/* shape types */ +#define SH_SPHERE 0 /* sphere */ +#define SH_BOX 1 /* box (may be rectangular) */ +#define SH_PRISMA 3 /* prisma (triangular) */ +#define SH_LINE 4 /* line with width of one dipole */ +#define SH_COATED 5 /* coated sphere */ +#define SH_SPHEREBOX 6 /* sphere in a box */ +#define SH_RBC 8 /* Red Blood Cell */ +#define SH_ELLIPSOID 11 /* general ellipsoid */ +#define SH_SDISK_ROT 14 /* disc cut of a sphere */ +#define SH_CYLINDER 18 /* cylinder */ +#define SH_READ 20 /* read from file */ + +/* which way to calculate coupleconstant */ +#define POL_CM 0 /* Clausius Mossotti */ +#define POL_RR 1 /* Radiative Reaction correction */ +#define POL_LDR 2 /* Lattice Dispersion Relation */ +#define POL_CLDR 3 /* Corrected Lattice Dispersion Relation */ +#define POL_SO 4 /* Second Order formulation */ + +/* how to calculate scattering quantities */ +#define SQ_DRAINE 0 /* classical, as Draine */ +#define SQ_SO 1 /* Second Order formulation */ + +/* how to calculate interaction term */ +#define G_POINT_DIP 0 /* as point dipoles */ +#define G_SO 1 /* Second Order formulation */ + +/* ldr constants */ +#define LDR_B1 1.8915316 +#define LDR_B2 -0.1648469 +#define LDR_B3 1.7700004 + +/* 2nd_order constants */ +#define SO_B1 1.5867182 +#define SO_B2 0.13488017 +#define SO_B3 0.11895826 + +/* two boundaries for separation between G_SO 'close', 'median', and 'far' */ +#define G_BOUND_CLOSE 1 /* k*R^2/d < GB_CLOSE => 'close' */ +#define G_BOUND_MEDIAN 1 /* k*R < GB_MEDIAN => 'median' */ + +/* iterative methods; see iterative.c for info */ +#define IT_CGNR 0 +#define IT_BICGSTAB 1 +#define IT_BICG_CS 2 +#define IT_QMR_CS 3 + +/* type of E field calculation */ +#define CE_NORMAL 0 /* normal */ +#define CE_PARPER 1 /* use symmetry to calculate both incident polarizations + from one calculation of internal fields */ + +/* path and size of tables */ #define TAB_PATH "tables/" -#define TAB_FNAME(a) "t" #a "f.dat" // a is a number, e.g. TAB_FNAME(2) -> "t2f.dat" +#define TAB_FNAME(a) "t" #a "f.dat" /* a is a number, e.g. TAB_FNAME(2) -> "t2f.dat" */ #define TAB_SIZE 142 #define TAB_RMAX 10 -// beam types -#define B_PLANE 0 -#define B_LMINUS 1 -#define B_DAVIS3 2 -#define B_BARTON5 3 - -// types of scattering grid -#define SG_GRID 0 // grid of angles -#define SG_PAIRS 1 // set of independent pairs -// types of angles set -#define SG_RANGE 0 // range with uniformly spaced points -#define SG_VALUES 1 // any set of values - -// types of phi_integr (should be different one-bit numbers) -#define PHI_UNITY 1 // just integrate -#define PHI_COS2 2 // integrate with cos(2*phi) -#define PHI_SIN2 4 // integrate with sin(2*phi) -#define PHI_COS4 8 // integrate with cos(4*phi) -#define PHI_SIN4 16 // integrate with sin(4*phi) - -// ways to treat particle symmetries -#define SYM_AUTO 0 // automatic -#define SYM_NO 1 // do not take into account -#define SYM_ENF 2 // enforce - -// types of checkpoint (to save) -#define CHP_NONE 0 // do not save checkpoint -#define CHP_NORMAL 1 // save checkpoint if not finished in time and exit -#define CHP_REGULAR 2 // save checkpoints in regular time intervals (until finished or halted) -#define CHP_ALWAYS 3 /* save checkpoint either if finished or time elapsed - * and calculate all scattering quantities - */ -// return values for functions -#define CHP_EXIT -2 // exit after saving checkpoint - -// default values; other are specified in InitVariables (param.c) -#define DEF_GRID (16*jagged) -#define MIN_AUTO_GRID 16 // minimum grid, when set from default dpl - -// numbers less than this value (compared to unity) are considered to be zero +/* beam types */ +#define B_PLANE 0 +#define B_LMINUS 1 +#define B_DAVIS1 2 +#define B_DAVIS3 3 +#define B_DAVIS5 4 +#define B_BARTON1 5 +#define B_BARTON3 6 +#define B_BARTON5 7 + +/* types of scattering grid */ +#define SG_GRID 0 /* grid of angles */ +#define SG_PAIRS 1 /* set of independent pairs */ +/* types of angles set */ +#define SG_RANGE 0 /* range with uniformly spaced points */ +#define SG_VALUES 1 /* any set of values */ + +/* types of phi_integr (should be different one-bit numbers) */ +#define PHI_UNITY 1 /* just integrate */ +#define PHI_COS2 2 /* integrate with cos(2*phi) */ +#define PHI_SIN2 4 /* integrate with sin(2*phi) */ +#define PHI_COS4 8 /* integrate with cos(4*phi) */ +#define PHI_SIN4 16 /* integrate with sin(4*phi) */ + +/* types of checkpoint (to save) */ +#define CHP_NONE 0 /* do not save checkpoint */ +#define CHP_NORMAL 1 /* save checkpoint if not finished in time and exit */ +#define CHP_REGULAR 2 /* save checkpoints in regular time intervals + (until finished or halted) */ +#define CHP_ALWAYS 3 /* save checkpoint either if finished or time elapsed + and calculate all the scattering quantities */ + +/* return values for functions */ +#define CHP_EXIT -2 /* exit after saving checkpoint */ + +/* default values; other are specified in InitVariables (param.c) */ +#define DEF_GRID (16*jagged) +#define DEF_DPL (10*sqrt(cAbs2(ref_index[0]))) + +/* numbers less than this value (compared to unity) are considered to be zero */ #define ROUND_ERR 1E-15 -// output and input file and directory names (can only be changed at compile time) +/* output and input file and dir names (can only be changed in compile time) */ #define F_EXPCOUNT "ExpCount" #define F_EXPCOUNT_LCK F_EXPCOUNT ".lck" #define F_CS "CrossSec" #define F_FRP "VisFrp" #define F_INTFLD "IntField" -#define F_DIPPOL "DipPol" -#define F_BEAM "IncBeam" -#define F_GRANS "granules" - // suffixes + /* suffixes */ #define F_XSUF "-X" #define F_YSUF "-Y" - // logs + /* logs */ #define F_LOG "log" -#define F_LOG_ERR "logerr.%d" // ringid as argument +#define F_LOG_ERR "logerr.%d" /* ringid as argument */ #define F_LOG_ORAVG "log_orient_avg" #define F_LOG_INT_CSCA "log_int_Csca" #define F_LOG_INT_ASYM "log_int_asym" - // log suffixes + /* log suffixes */ #define F_LOG_X "_x" #define F_LOG_Y "_y" #define F_LOG_Z "_z" - // Mueller files + + /* mueller files */ #define F_MUEL "mueller" #define F_MUEL_SG "mueller_scatgrid" #define F_MUEL_INT "mueller_integr" @@ -235,42 +194,31 @@ #define F_MUEL_S2 "mueller_integr_s2" #define F_MUEL_C4 "mueller_integr_c4" #define F_MUEL_S4 "mueller_integr_s4" - // temporary files; used in printf with ringid as argument -#define F_BEAM_TMP "b%d.tmp" + /* temporary files; used in printf with ringid as argument */ #define F_INTFLD_TMP "f%d.tmp" -#define F_DIPPOL_TMP "p%d.tmp" #define F_GEOM_TMP "g%d.tmp" - // checkpoint files + /* checkpoint files */ #define F_CHP_LOG "chp.log" -#define F_CHP "chp.%d" // ringid as argument +#define F_CHP "chp.%d" /* ringid as argument */ -// default file and directory names; can be changed by command line options +/* default file and dir names; can be changed by command line options */ #define FD_ALLDIR_PARMS "alldir_params.dat" #define FD_AVG_PARMS "avg_params.dat" #define FD_SCAT_PARMS "scat_params.dat" #define FD_CHP_DIR "chpoint" -// number of components of D -#define NDCOMP 6 - -// shape formats; numbers should be nonnegative -#define SF_TEXT 0 // ADDA text format for one-domain particles -#define SF_TEXT_EXT 1 // ADDA text format for multi-domain particles -#define SF_DDSCAT 2 // DDSCAT 6.1 format (FRMFIL), produced by calltarget - -//************* Global Defines and Data structures (all for LogError) ***************** - -#define POSIT __FILE__,__LINE__ // position of the error in source code -// who definitions -#define ALL 0 // each processor may report this error -#define ONE 1 // only root processor reports an error - -// derived; for simplicity -#define ALL_POS ALL,POSIT -#define ONE_POS ONE,POSIT -// error codes -#define EC_ERROR 1 // error -#define EC_WARN 2 // warning -#define EC_INFO 3 // slight warning, that does not interfere at all with normal execution - -#endif // __const_h +/************** Global Defines and Data structures (all for LogError) *****************/ + +#define POSIT __FILE__,__LINE__ /* position of the error in source code */ +/* who definitions */ +#define ALL 0 /* each processor may report this error */ +#define ONE 1 /* only root processor reports an error */ + /* derived; for simplicity */ +#define ALL_POS ALL,POSIT +#define ONE_POS ONE,POSIT +/* error codes */ +#define EC_ERROR 1 /* error */ +#define EC_WARN 2 /* warning */ +#define EC_INFO 3 /* slight warning, that does not interfere at all with normal execution */ + +#endif /*__const_h*/ diff --git a/src/crosssec.c b/src/crosssec.c index b8a23081..64341c09 100644 --- a/src/crosssec.c +++ b/src/crosssec.c @@ -1,18 +1,16 @@ /* FILE : crosssec.c * AUTH : Maxim Yurkin - * DESCR: All the functions to calculate scattering quantities (except Mueller matrix). + * DESCR: All the functions to calculate scattering qunatities (except Mueller matrix). * Functions to read different parameters from files. * Initialization of orientation of the particle. * * Previous versions by Martijn Frijlink * - * Copyright (C) 2006-2008 University of Amsterdam + * Copyright (C) 2006 M.A. Yurkin and A.G. Hoekstra * This code is covered by the GNU General Public License. */ #include -#include -#include -#include +#include #include "vars.h" #include "cmplx.h" #include "const.h" @@ -22,1045 +20,940 @@ #include "debug.h" #include "memory.h" #include "io.h" -#include "timing.h" -#include "function.h" -// SEMI-GLOBAL VARIABLES +/* SEMI-GLOBAL VARIABLES */ -// defined and initialized in calculator.c +/* defined and initialized in calculator.c */ extern double *E2_alldir,*E2_alldir_buffer; extern const doublecomplex cc[][3]; -extern doublecomplex *expsX,*expsY,*expsZ; -// defined and initialized in GenerateB.c -extern const double beam_center_0[3]; -// defined and initialized in param.c +/* defined and initialized in param.c */ extern const double prop_0[3],incPolX_0[3],incPolY_0[3]; extern const int ScatRelation; -// defined and initialized in timing.c -extern TIME_TYPE Timing_EField_ad,Timing_comm_EField_ad,Timing_EField_sg,Timing_comm_EField_sg, -Timing_ScatQuan_comm; +/* defined and initialized in timing.c */ +extern clock_t Timing_EField_ad, Timing_calc_EField_ad, Timing_comm_EField_ad, + Timing_EField_sg, Timing_calc_EField_sg, Timing_comm_EField_sg; -// used in CalculateE.c +/* used in CalculateE.c */ Parms_1D phi_sg; -// used in calculator.c -Parms_1D parms_alpha; // parameters of integration over alpha -Parms_1D parms[2]; // parameters for integration over theta,phi or beta,gamma -angle_set beta_int,gamma_int,theta_int,phi_int; // sets of angles -// used in param.c -char avg_string[MAX_PARAGRAPH]; // string for output of function that reads averaging parameters -// used in Romberg.c -int full_al_range; // whether full range of alpha angle is used +/* used in calculator.c */ +Parms_1D parms_alpha; /* parameters of integration over alpha */ +Parms_1D parms[2]; /* parameters for integration over theta,phi or beta,gamma */ +angle_set beta_int,gamma_int,theta_int,phi_int; /* sets of angles */ +/* used in param.c */ +char avg_string[MAX_PARAGRAPH]; /* string for output of function that reads averaging parameters */ -//===================================================================== +/*=====================================================================*/ INLINE int AlldirIndex(const int theta,const int phi) -// Convert the (theta,phi) couple into a linear array index + /* Convert the (theta,phi) couple into a linear array index */ { - return (theta*phi_int.N + phi); + return (theta*phi_int.N + phi); } -//===================================================================== +/*=====================================================================*/ void InitRotation (void) -/* initialize matrices used for reference frame transformation; based on Mishchenko M.I. - * "Calculation of the amplitude matrix for a nonspherical particle in a fixed orientation", - * Applied Optics 39(6):1026-1031. This is so-called zyz-notation or y-convention. - */ -{ - double ca,sa,cb,sb,cg,sg; - double beta_matr[3][3]; - double alph,bet,gam; // in radians - - // initialization of angle values in radians - alph=Deg2Rad(alph_deg); - bet=Deg2Rad(bet_deg); - gam=Deg2Rad(gam_deg); - // calculation of rotation matrix - ca=cos(alph); - sa=sin(alph); - cb=cos(bet); - sb=sin(bet); - cg=cos(gam); - sg=sin(gam); - - beta_matr[0][0]=ca*cb*cg-sa*sg; - beta_matr[0][1]=sa*cb*cg+ca*sg; - beta_matr[0][2]=-sb*cg; - beta_matr[1][0]=-ca*cb*sg-sa*cg; - beta_matr[1][1]=-sa*cb*sg+ca*cg; - beta_matr[1][2]=sb*sg; - beta_matr[2][0]=ca*sb; - beta_matr[2][1]=sa*sb; - beta_matr[2][2]=cb; - // rotation of incident field - MatrVec(beta_matr,prop_0,prop); - MatrVec(beta_matr,incPolY_0,incPolY); - MatrVec(beta_matr,incPolX_0,incPolX); - if (beam_asym) MatrVec(beta_matr,beam_center_0,beam_center); -} - -//===================================================================== -// currently not used -static int ReadLine(FILE *,const char *,char *,const int) ATT_UNUSED; - -static int ReadLine(FILE *file,const char *fname, // opened file and filename - char *buf,const int buf_size) // buffer for line and its size -// reads the first uncommented line; returns 1 if EOF reached + /* initialize matrices used for reference frame transformation */ { - while (!feof(file)) { - fgets(buf,buf_size,file); - if (*buf!='#') { // if uncommented - if (strstr(buf,"\n")==NULL && !feof(file)) LogError(EC_ERROR,ONE_POS, - "Buffer overflow while reading '%s' (size of uncommented line > %d)", - fname,buf_size-1); - else return 0; // complete line is read - } // finish reading the commented line - else while (strstr(buf,"\n")==NULL && !feof(file)) fgets(buf,buf_size,file); - } - return 1; + double ca,sa,cb,sb,cg,sg; + double beta_matr[3][3]; + double alph,bet,gam; /* in radians */ + + /* initialization of angle values in radians */ + alph=Deg2Rad(alph_deg); + bet=Deg2Rad(bet_deg); + gam=Deg2Rad(gam_deg); + /* calculation of rotation matrix */ + ca=cos(alph); + sa=sin(alph); + cb=cos(bet); + sb=sin(bet); + cg=cos(gam); + sg=sin(gam); + + beta_matr[0][0]=ca*cb*cg-sa*sg; + beta_matr[0][1]=sa*cb*cg+ca*sg; + beta_matr[0][2]=-sb*cg; + beta_matr[1][0]=-ca*cb*sg-sa*cg; + beta_matr[1][1]=-sa*cb*sg+ca*cg; + beta_matr[1][2]=sb*sg; + beta_matr[2][0]=ca*sb; + beta_matr[2][1]=sa*sb; + beta_matr[2][2]=cb; + /* rotation of incident field */ + MatrVec(beta_matr,prop_0,prop); + MatrVec(beta_matr,incPolY_0,incPolY); + MatrVec(beta_matr,incPolX_0,incPolX); } -//===================================================================== +/*=====================================================================*/ -static void ReadLineStart(FILE *file,const char *fname, // opened file and filename - char *buf,const int buf_size, // buffer for line and its size - const char *start) // beginning of the line to search -// reads the first line that starts with 'start' +static int ReadLine(FILE *file,const char *fname, /* opened file and filename */ + char *buf,const int buf_size) /* buffer for line and its size */ + /* reads the first uncommented line; returns 1 if EOF reached */ { - while (!feof(file)) { - fgets(buf,buf_size,file); - if (strstr(buf,start)==buf) { // if correct beginning - if (strstr(buf,"\n")==NULL && !feof(file)) LogError(EC_ERROR,ONE_POS, - "Buffer overflow while reading '%s' (size of essential line > %d)", - fname,buf_size-1); - else return; // line found and fits into buffer - } // finish reading unmatched line - else while (strstr(buf,"\n")==NULL && !feof(file)) fgets(buf,buf_size,file); - } - LogError(EC_ERROR,ONE_POS,"String '%s' is not found (in correct place) in file '%s'", - start,fname); + while (!feof(file)) { + fgets(buf,buf_size,file); + if (*buf!='#') { /* if uncommented */ + if (strstr(buf,"\n")==NULL) LogError(EC_ERROR,ONE_POS, + "Buffer overflow while reading '%s' (size of uncommented line > %d)", + fname,buf_size-1); + else return 0; /* complete line is read */ + } /* finish reading the commented line */ + else while (strstr(buf,"\n")==NULL && !feof(file)) fgets(buf,buf_size,file); + } + return 1; } +/*=====================================================================*/ -//===================================================================== - -INLINE void ScanDouble(FILE *file,const char *fname,char *buf,const int buf_size,const char *start, - double *res) -/* scans double value from a line starting with exactly 'start'; contains the same arguments as - * ReadLineStart function, plus pointer to where the result should be placed - */ -{ - ReadLineStart(file,fname,buf,buf_size,start); - if (sscanf(buf+strlen(start),"%lf",res)!=1) LogError(EC_ERROR,ONE_POS, - "Error reading value after '%s' in file '%s'",start,fname); -} - -//===================================================================== - -INLINE void ScanInt(FILE *file,const char *fname,char *buf,const int buf_size,const char *start, - int *res) -/* scans integer value from a line starting with exactly 'start'; contains the same arguments as - * ReadLineStart function, plus pointer to where the result should be placed - */ -{ - double tmp; - - ReadLineStart(file,fname,buf,buf_size,start); - if (sscanf(buf+strlen(start),"%lf",&tmp)!=1) LogError(EC_ERROR,ONE_POS, - "Error reading value after '%s' in file '%s'",start,fname); - if (tmpINT_MAX) LogError(EC_ERROR,ONE_POS, - "Value after '%s' in file '%s' is out of integer bounds",start,fname); - if (sscanf(buf+strlen(start),"%d",res)!=1) LogError(EC_ERROR,ONE_POS, - "Error reading value after '%s' in file '%s'",start,fname); -} - -//===================================================================== - -INLINE void ScanSizet(FILE *file,const char *fname,char *buf,const int buf_size,const char *start, - size_t *res) -/* scans large integer value from a line starting with exactly 'start'; contains the same arguments - * as ReadLineStart function, plus pointer to where the result should be placed. Conversion from - * (unsigned long) is needed (to remove warnings) because %z printf argument is not yet supported by - * all target compiler environments - */ - +static void ReadLineStart(FILE *file,const char *fname, /* opened file and filename */ + char *buf,const int buf_size, /* buffer for line and its size */ + const char *start) /* beginning of the line to search */ + /* reads the first line that starts with 'start' */ { - double tmp; - unsigned long res_tmp; - - ReadLineStart(file,fname,buf,buf_size,start); - if (sscanf(buf+strlen(start),"%lf",&tmp)!=1) LogError(EC_ERROR,ONE_POS, - "Error reading value after '%s' in file '%s'",start,fname); - if (tmp<0 || tmp>SIZE_MAX) LogError(EC_ERROR,ONE_POS, - "Value after '%s' in file '%s' is out of size_t bounds",start,fname); - if (sscanf(buf+strlen(start),"%lu",&res_tmp)!=1) LogError(EC_ERROR,ONE_POS, - "Error reading value after '%s' in file '%s'",start,fname); - *res=(size_t)res_tmp; + while (!feof(file)) { + fgets(buf,buf_size,file); + if (strstr(buf,start)==buf) { /* if correct beginning */ + if (strstr(buf,"\n")==NULL) LogError(EC_ERROR,ONE_POS, + "Buffer overflow while reading '%s' (size of essential line > %d)", + fname,buf_size-1); + else return; /* line found and fits into buffer */ + } /* finish reading unmatched line */ + else while (strstr(buf,"\n")==NULL && !feof(file)) fgets(buf,buf_size,file); + } + LogError(EC_ERROR,ONE_POS, + "String '%s' is not found (in correct place) in file '%s'",start,fname); } -//===================================================================== +/*=====================================================================*/ -INLINE void ScanString(FILE *file,const char *fname,char *buf,const int buf_size,const char *start, - char *res) -/* scans string value from a line starting with exactly 'start'; contains the same arguments as - * ReadLineStart function, plus pointer to where the result should be placed - */ +static int ScanIntegrParms( + FILE *file,const char *fname, /* opened file and filename */ + angle_set *a, /* pointer to angle set */ + Parms_1D *b, /* pointer to parameters of integration */ + const int ifcos, /* if space angles equally in cos */ + char *buf,char* temp, /* 2 buffers */ + const int buf_size) /* and their size */ + /* scan integration parameters for angles from file */ { - ReadLineStart(file,fname,buf,buf_size,start); - if (sscanf(buf+strlen(start),"%s",res)!=1) LogError(EC_ERROR,ONE_POS, - "Error reading value after '%s' in file '%s'",start,fname); + int i; + double unit; + + /* scan file */ + ReadLineStart(file,fname,buf,buf_size,"min="); + if (sscanf(buf,"min=%lf",&(a->min))!=1) return 1; + ReadLineStart(file,fname,buf,buf_size,"max="); + if (sscanf(buf,"max=%lf",&(a->max))!=1) return 1; + ReadLineStart(file,fname,buf,buf_size,"Jmax="); + if (sscanf(buf,"Jmax=%d",&(b->Jmax))!=1) return 1; + ReadLineStart(file,fname,buf,buf_size,"K="); + if (sscanf(buf,"K=%d",&(b->K))!=1) return 1; + ReadLineStart(file,fname,buf,buf_size,"eps="); + if (sscanf(buf,"eps=%lf",&(b->eps))!=1) return 1; + + ReadLineStart(file,fname,buf,buf_size,"equiv="); + if (sscanf(buf,"equiv=%s",temp)!=1) return 1; + if (strcmp(temp,"true")==0) b->equival=TRUE; + else if (strcmp(temp,"false")==0) b->equival=FALSE; + else LogError(EC_ERROR,ONE_POS,"Wrong argument of 'equiv' option in file %s",fname); + + /* fill all parameters */ + if (a->min==a->max) { + a->N=b->Grid_size=1; + b->Jmax=1; + } + else { + /* consistency check */ + if (a->min>a->max) LogError(EC_ERROR,ONE_POS, + "Wrong range (min=%g, max=%g) in file %s (max must be >= min)",a->min,a->max,fname); + if (b->Jmax=%d)",b->Jmax,fname,ROMB_KMIN); + if (b->K<1) LogError(EC_ERROR,ONE_POS, + "Wrong K (%d) in file %s (must be >=1)",b->K,fname); + if (b->eps<0) LogError(EC_ERROR,ONE_POS, + "Wrong eps (%g) in file %s (must be >=0)",b->eps,fname); + + a->N=b->Grid_size=(1 << (b->Jmax-1)) + 1; + if (b->equival && a->N>1) (a->N)--; + } + /* initialize points of integration */ + if ((a->val=(double *) malloc(a->N*sizeof(double)))==NULL) + LogError(EC_ERROR,ONE_POS,"Could not malloc integration array"); + memory += a->N*sizeof(double); + + if (ifcos) { /* make equal intervals in cos(angle) */ + /* consistency check */ + if (a->min<0) LogError(EC_ERROR,ONE_POS, + "Wrong min (%g) in file %s (must be >=0 for this angle)",a->min,fname); + if (a->max>180) LogError(EC_ERROR,ONE_POS, + "Wrong max (%g) in file %s (must be <=180 for this angle)",a->max,fname); + b->min=cos(Deg2Rad(a->max)); + if (fabs(b->min)min=0; /* just for convenience */ + b->max=cos(Deg2Rad(a->min)); + if (b->Grid_size==1) a->val[0]=a->min; + else { + unit = (b->max - b->min)/(b->Grid_size-1); + for (i=0;iN;i++) a->val[i] = Rad2Deg(acos(b->min+unit*i)); + } + } + else { /* make equal intervals in angle */ + b->min=Deg2Rad(a->min); + b->max=Deg2Rad(a->max); + if (b->Grid_size==1) a->val[0]=a->min; + else { + unit = (a->max - a->min)/(b->Grid_size-1); + for (i=0;iN;i++) a->val[i] = a->min + unit*i; + } + } + + return 0; } -//===================================================================== +/*=====================================================================*/ -static void ScanIntegrParms( - FILE *file,const char *fname, // opened file and filename - angle_set *a, // pointer to angle set - Parms_1D *b, // pointer to parameters of integration - const int ifcos, // if space angles equally in cos - char *buf,char* temp, // 2 buffers - const int buf_size) // and their size -// scan integration parameters for angles from file +static int ScanAngleSet(FILE *file,const char *fname, /* opened file and filename */ + angle_set *a, /* pointers to angle set */ + char *buf,char *temp, /* 2 buffers */ + const int buf_size) /* and their size */ + /* scan range or set of angles (theta or phi) from file (used for scat_grid) */ { - size_t i; - double unit; - - // scan file - ScanDouble(file,fname,buf,buf_size,"min=",&(a->min)); - ScanDouble(file,fname,buf,buf_size,"max=",&(a->max)); - ScanInt(file,fname,buf,buf_size,"Jmin=",&(b->Jmin)); - ScanInt(file,fname,buf,buf_size,"Jmax=",&(b->Jmax)); - ScanDouble(file,fname,buf,buf_size,"eps=",&(b->eps)); - ScanString(file,fname,buf,buf_size,"equiv=",temp); - if (strcmp(temp,"true")==0) b->equival=TRUE; - else if (strcmp(temp,"false")==0) b->equival=FALSE; - else LogError(EC_ERROR,ONE_POS,"Wrong argument of 'equiv' option in file %s",fname); - ScanString(file,fname,buf,buf_size,"periodic=",temp); - if (strcmp(temp,"true")==0) b->periodic=TRUE; - else if (strcmp(temp,"false")==0) b->periodic=FALSE; - else LogError(EC_ERROR,ONE_POS,"Wrong argument of 'periodic' option in file %s",fname); - - // fill all parameters - if (a->min==a->max) { - a->N=b->Grid_size=1; - b->Jmax=1; - } - else { - // consistency check - if (a->min>a->max) LogError(EC_ERROR,ONE_POS, - "Wrong range (min=%g, max=%g) in file %s (max must be >= min)",a->min,a->max,fname); - if (b->JmaxJmin) LogError(EC_ERROR,ONE_POS, - "Wrong Jmax (%d) in file %s; it must be >= Jmin (%d)",b->Jmax,fname,b->Jmin); - if (b->Jmin<1) LogError(EC_ERROR,ONE_POS, - "Wrong Jmin (%d) in file %s (must be >=1)",b->Jmin,fname); - if (b->eps<0) LogError(EC_ERROR,ONE_POS, - "Wrong eps (%g) in file %s (must be >=0)",b->eps,fname); - if (b->Jmax >= (int)(8*sizeof(int))) LogError(EC_ERROR,ONE_POS, - "Too large Jmax(%d) in file %s, it will cause integer overflow",b->Jmax,fname); - - a->N=b->Grid_size=(1 << b->Jmax) + 1; - if (b->equival && a->N>1) (a->N)--; - } - // initialize points of integration - MALLOC_VECTOR(a->val,double,a->N,ALL); - memory += a->N*sizeof(double); - - if (ifcos) { // make equal intervals in cos(angle) - // consistency check - if (a->min<0) LogError(EC_ERROR,ONE_POS, - "Wrong min (%g) in file %s (must be >=0 for this angle)",a->min,fname); - if (a->max>180) LogError(EC_ERROR,ONE_POS, - "Wrong max (%g) in file %s (must be <=180 for this angle)",a->max,fname); - b->min=cos(Deg2Rad(a->max)); - b->max=cos(Deg2Rad(a->min)); - if (fabs(b->min)min=0; // just for convenience of display in log file - if (fabs(b->max)max=0; - if (b->Grid_size==1) a->val[0]=a->min; - else { - unit = (b->max - b->min)/(b->Grid_size-1); - for (i=0;iN;i++) a->val[i] = Rad2Deg(acos(b->min+unit*i)); - } - } - else { // make equal intervals in angle - b->min=Deg2Rad(a->min); - b->max=Deg2Rad(a->max); - if (b->Grid_size==1) a->val[0]=a->min; - else { - unit = (a->max - a->min)/(b->Grid_size-1); - for (i=0;iN;i++) a->val[i] = a->min + unit*i; - } - } + int i; + double unit; + + ReadLineStart(file,fname,buf,buf_size,"type="); + if (sscanf(buf,"type=%s",temp)!=1) return -1; + ReadLineStart(file,fname,buf,buf_size,"N="); + if (sscanf(buf,"N=%d",&(a->N))!=1) return -1; + /* initialize angle array */ + if ((a->val=(double *) malloc(a->N*sizeof(double)))==NULL) + LogError(EC_ERROR,ONE_POS,"Could not malloc angle array"); + memory += a->N*sizeof(double); + + if (strcmp(temp,"range")==0) { + ReadLineStart(file,fname,buf,buf_size,"min="); + if (sscanf(buf,"min=%lf",&(a->min))!=1) return -1; + ReadLineStart(file,fname,buf,buf_size,"max="); + if (sscanf(buf,"max=%lf",&(a->max))!=1) return -1; + if (a->N==1) a->val[0]=(a->max + a->min)/2; + else { + unit = (a->max - a->min)/(a->N - 1); + for (i=0;iN;i++) a->val[i] = a->min + unit*i; + } + return SG_RANGE; + } + else if (strcmp(temp,"values")==0) { + ReadLineStart(file,fname,buf,buf_size,"values="); + for (i=0;iN;i++) { + fgets(buf,buf_size,file); + if (strstr(buf,"\n")==NULL) LogError(EC_ERROR,ONE_POS, + "Buffer overflow while scanning lines in file '%s' (line size > %d)",fname,buf_size-1); + if (sscanf(buf,"%lf\n",a->val+i)!=1) LogError(EC_ERROR,ONE_POS, + "Failed scanning values from line '%s' in file '%s'",buf,fname); + } + return SG_VALUES; + } + else LogError(EC_ERROR,ONE_POS,"Unknown type '%s' in file '%s'",temp,fname); + /* not actually reached */ + return -1; } -//===================================================================== - -static int ScanAngleSet(FILE *file,const char *fname, // opened file and filename - angle_set *a, // pointers to angle set - char *buf,char *temp, // 2 buffers - const int buf_size) // and their size -// scan range or set of angles (theta or phi) from file (used for scat_grid) -{ - size_t i; - double unit; - - ScanString(file,fname,buf,buf_size,"type=",temp); - ScanSizet(file,fname,buf,buf_size,"N=",&(a->N)); - // initialize angle array - MALLOC_VECTOR(a->val,double,a->N,ALL); - memory += a->N*sizeof(double); - - if (strcmp(temp,"range")==0) { - ScanDouble(file,fname,buf,buf_size,"min=",&(a->min)); - ScanDouble(file,fname,buf,buf_size,"max=",&(a->max)); - if (a->min>a->max) LogError(EC_ERROR,ONE_POS, - "Wrong range (min=%g, max=%g) in file %s (max must be >= min)",a->min,a->max,fname); - if (a->N==1) a->val[0]=(a->max + a->min)/2; - else { - unit = (a->max - a->min)/(a->N - 1); - for (i=0;iN;i++) a->val[i] = a->min + unit*i; - } - return SG_RANGE; - } - else if (strcmp(temp,"values")==0) { - ReadLineStart(file,fname,buf,buf_size,"values="); - for (i=0;iN;i++) { - fgets(buf,buf_size,file); - if (strstr(buf,"\n")==NULL && !feof(file)) LogError(EC_ERROR,ONE_POS, - "Buffer overflow while scanning lines in file '%s' (line size > %d)", - fname,buf_size-1); - if (sscanf(buf,"%lf\n",a->val+i)!=1) LogError(EC_ERROR,ONE_POS, - "Failed scanning values from line '%s' in file '%s'",buf,fname); - } - return SG_VALUES; - } - else LogError(EC_ERROR,ONE_POS,"Unknown type '%s' in file '%s'",temp,fname); - // not actually reached - return -1; -} +/*=====================================================================*/ -//===================================================================== +/* for convenience common error in functions + ReadAvgParms, ReadAlldirParms, and Read ScatGridParms */ +#define READ_ERROR LogError(EC_ERROR,ONE_POS,"Wrong format of file '%s'",fname); void ReadAvgParms(const char *fname) -// read parameters of orientation averaging from a file + /* read parameters of orientation averaging from a file */ { - FILE *input; - char buf[BUF_LINE],temp[BUF_LINE]; - - // open file - input=FOpenErr(fname,"r",ALL_POS); - //scan file - ReadLineStart(input,fname,buf,BUF_LINE,"alpha:"); - ScanIntegrParms(input,fname,&alpha_int,&parms_alpha,FALSE,buf,temp,BUF_LINE); - full_al_range=fabs(alpha_int.max-alpha_int.min-FULL_ANGLE) %d)", - fname,BUF_LINE-1); - if (sscanf(buf,"%lf %lf\n",angles.theta.val+i,angles.phi.val+i)!=2) LogError(EC_ERROR, - ONE_POS,"Failed scanning values from line '%s' in file '%s'",buf,fname); - } - } - else LogError(EC_ERROR,ONE_POS,"Unknown global_type '%s' in file '%s'",temp,fname); - // close file - FCloseErr(input,fname,ALL_POS); - /* print info; conversions to (unsigned long) are needed (to remove warnings) because %z printf - * argument is not yet supported by all target compiler environmets - */ - if (ringid==ROOT) { - fprintf(logfile,"\nScattered field is calculated for multiple directions\n"); - if (angles.type==SG_GRID) { - if (theta_type==SG_RANGE) - fprintf(logfile,"theta: from %g to %g in %lu steps\n",angles.theta.min, - angles.theta.max,(unsigned long)angles.theta.N); - else if (theta_type==SG_VALUES) - fprintf(logfile,"theta: %lu given values\n",(unsigned long)angles.theta.N); - if (phi_type==SG_RANGE) { - fprintf(logfile,"phi: from %g to %g in %lu steps\n",angles.phi.min,angles.phi.max, - (unsigned long)angles.phi.N); - if (phi_integr) fprintf(logfile,"(Mueller matrix is integrated over phi)\n"); - } - else if (phi_type==SG_VALUES) - fprintf(logfile,"phi: %lu given values\n",(unsigned long)angles.phi.N); - } - else if (angles.type==SG_PAIRS) - fprintf(logfile,"Total %lu given (theta,phi) pairs\n",(unsigned long)angles.N); - fprintf(logfile,"\n"); - } - D("ReadScatGridParms finished"); + FILE *input; + char buf[BUF_LINE],temp[BUF_LINE]; + int theta_type,phi_type,i; + + /* open file */ + input=FOpenErr(fname,"r",ALL_POS); + /* scan file */ + ReadLineStart(input,fname,buf,BUF_LINE,"global_type="); + if (sscanf(buf,"global_type=%s",temp)!=1) READ_ERROR; + if (strcmp(temp,"grid")==0) { + angles.type = SG_GRID; + ReadLineStart(input,fname,buf,BUF_LINE,"theta:"); + if ((theta_type=ScanAngleSet(input,fname,&(angles.theta),buf,temp,BUF_LINE))<0) READ_ERROR; + if (phi_integr) { + ReadLineStart(input,fname,buf,BUF_LINE,"phi_integr:"); + if (ScanIntegrParms(input,fname,&(angles.phi),&phi_sg,FALSE,buf,temp,BUF_LINE)) READ_ERROR; + phi_type = SG_RANGE; + } + else { + ReadLineStart(input,fname,buf,BUF_LINE,"phi:"); + if ((phi_type=ScanAngleSet(input,fname,&(angles.phi),buf,temp,BUF_LINE))<0) READ_ERROR; + } + angles.N=angles.theta.N*angles.phi.N; + } + else if (strcmp(temp,"pairs")==0) { + if (phi_integr) + LogError(EC_ERROR,ONE_POS,"Integration over phi can't be done with 'global_type=pairs'"); + angles.type = SG_PAIRS; + ReadLineStart(input,fname,buf,BUF_LINE,"N="); + if (sscanf(buf,"N=%d",&(angles.N))!=1) READ_ERROR; + angles.theta.N=angles.phi.N=angles.N; + /* malloc angle arrays */ + if ((angles.theta.val=(double *) malloc(angles.N*sizeof(double)))==NULL) + LogError(EC_ERROR,ONE_POS,"Could not malloc angles.theta.val"); + if ((angles.phi.val=(double *) malloc(angles.N*sizeof(double)))==NULL) + LogError(EC_ERROR,ONE_POS,"Could not malloc angles.phi.val"); + memory += 2*angles.N*sizeof(double); + + ReadLineStart(input,fname,buf,BUF_LINE,"pairs="); + for (i=0;i %d)",fname,BUF_LINE-1); + if (sscanf(buf,"%lf %lf\n",angles.theta.val+i,angles.phi.val+i)!=2) + LogError(EC_ERROR,ONE_POS,"Failed scanning values from line '%s' in file '%s'",buf,fname); + } + } + else LogError(EC_ERROR,ONE_POS,"Unknown global_type '%s' in file '%s'",temp,fname); + /* close file */ + FCloseErr(input,fname,ALL_POS); + /* print info */ + if (ringid==ROOT) { + fprintf(logfile,"\nScattered field is calculated for multiple directions\n",fname); + if (angles.type==SG_GRID) { + if (theta_type==SG_RANGE) + fprintf(logfile,"theta: from %g to %g in %d steps\n", + angles.theta.min,angles.theta.max,angles.theta.N); + else if (theta_type==SG_VALUES) + fprintf(logfile,"theta: %d given values\n",angles.theta.N); + if (phi_type==SG_RANGE) { + fprintf(logfile,"phi: from %g to %g in %d steps\n", + angles.phi.min,angles.phi.max,angles.phi.N); + if (phi_integr) fprintf(logfile,"(Mueller matrix is integrated over phi)\n"); + } + else if (phi_type==SG_VALUES) + fprintf(logfile,"phi: %d given values\n",angles.phi.N); + } + else if (angles.type==SG_PAIRS) + fprintf(logfile,"Total %d given (theta,phi) pairs\n",angles.N); + fprintf(logfile,"\n"); + } + D("ReadScatGridParms complete"); +#undef READ_ERROR } -//=====================================================================*/ +/*=====================================================================*/ -void CalcField (doublecomplex *ebuff, // where to write calculated scattering amplitude - const double *n) // scattering direction -/* Near-optimal routine to compute the scattered fields at one specific angle (more exactly - - * scattering amplitude); Specific optimization are possible when e.g. n[0]=0 for scattering in - * yz-plane, however in this case it is very improbable that the routine will become a bottleneck. - * The latter happens mostly for cases, when grid of scattering angles is used with only small - * fraction of n, allowing simplifications. - */ +void CalcField (doublecomplex *ebuff, /* where to write calculated scattering amplitude */ + const double *n) /* scattering direction */ + /* Near-optimal routine to compute the scattered fields at one specific + angle (more exactly - scattering amplitude) */ { - double kkk; - doublecomplex a,m2,dpr; - doublecomplex sum[3],tbuff[3],tmp; - int i; - unsigned short ix,iy1,iy2,iz1,iz2; - size_t j,jjj; - double temp, na; - doublecomplex mult_mat[MAX_NMAT]; - const int scat_avg=TRUE; - - if (ScatRelation==SQ_SO) { - // !!! this should never happen - if (anisotropy) LogError(EC_ERROR,ONE_POS,"Incompatibility error in CalcField"); - // calculate correction coefficient - if (scat_avg) na=0; - else na=DotProd(n,prop); - temp=kd*kd/24; - for(i=0;i materialT; b) DipoleCoord -> rdipT; - * c) pvec -> pT - */ - // initialize local_nvoid_d0 and local_nvoid_d1 - MALLOC_VECTOR(nvoid_array,double,nprocs,ALL); - nvoid_array[ringid]=local_nvoid_Ndip; - AllGather(nvoid_array+ringid,nvoid_array,double_type,nprocs); - local_nvoid_d0=0; - for (i=0;i materialT + b) DipoleCoord -> rdipT + c) pvec -> pT + */ + /* initialize local_nvoid_d0 and local_nvoid_d1 */ + nvoid_array=iVector(0,nprocs-1); + nvoid_array[ringid]=local_nvoid_Ndip; + AllGather(nvoid_array+ringid,nvoid_array,int_type,nprocs); + local_nvoid_d0=0; + for (i=0;i #include -#include -#include "types.h" +#include "cmplx.h" +#include "comm.h" #include "debug.h" #include "const.h" #ifdef DEBUG -//============================================================ +/*============================================================*/ void DebugPrintf(const char *fname,const int line,const char *fmt, ... ) -{ - va_list args; - char pr_line[MAX_PARAGRAPH]; - extern int ringid; +{ + va_list args; + char pr_line[MAX_PARAGRAPH]; + extern int ringid; - va_start(args, fmt); - sprintf(pr_line,"DEBUG: %s:%d: ",fname,line); - vsprintf(pr_line+strlen(pr_line),fmt,args); - strcat(pr_line, "\n"); - printf("(ringID=%i) %s",ringid,pr_line); - fflush(stdout); - va_end(args); + va_start(args, fmt); + sprintf(pr_line,"DEBUG: %s:%d: ", fname, line); + vsprintf(pr_line+strlen(pr_line), fmt, args); + strcat(pr_line, "\n"); + printf("(ringID=%i) %s",ringid,pr_line); + fflush(stdout); + va_end(args); } -//======================================================= +/*=======================================================*/ void FieldPrint (doublecomplex *x) -/* print current field at certain dipole -- not used; left for deep debug; NOT ROBUST, since - * DipoleCoord is not always available - */ + /* print current field at certain dipole -- not used; left for deep debug */ { - extern FILE *logfile; - extern double *DipoleCoord; - int i=9810; + extern FILE *logfile; + extern double *DipoleCoord; + int i=9810; - i*=3; - fprintf(logfile,"Dipole coordinates = %.10E, %.10E, %.10E\n",DipoleCoord[i],DipoleCoord[i+1], - DipoleCoord[i+2]); - fprintf(logfile,"E = %.10E%+.10Ei, %.10E%+.10Ei, %.10E%+.10Ei\n",x[i][RE],x[i][IM],x[i+1][RE], - x[i+1][IM],x[i+2][RE],x[i+2][IM]); + i*=3; + fprintf(logfile,"Dipole coords = %.10E, %.10E, %.10E\n", + DipoleCoord[i],DipoleCoord[i+1],DipoleCoord[i+2]); + fprintf(logfile,"E = %.10E%+.10Ei, %.10E%+.10Ei, %.10E%+.10Ei\n", + x[i][RE],x[i][IM],x[i+1][RE],x[i+1][IM],x[i+2][RE],x[i+2][IM]); } -#endif // DEBUG +#endif /* DEBUG */ diff --git a/src/debug.h b/src/debug.h index 70e0c78e..24d5cd52 100644 --- a/src/debug.h +++ b/src/debug.h @@ -4,30 +4,30 @@ * * Previous versions by "vesseur" * - * Copyright (C) 2006,2008 University of Amsterdam + * Copyright (C) 2006 M.A. Yurkin and A.G. Hoekstra * This code is covered by the GNU General Public License. */ #ifndef __debug_h #define __debug_h -/* Debugging implies turning on additional information messages during the code execution. A simple - * and convenient tool to generate such messages is used. - */ +/* Debugging implies turning on additional information messages + during the code execution. A simple and convenient tool to + generate such messages is used. */ -//#define DEBUG // uncomment to degug +/*#define DEBUG /* uncomment to degug */ #ifdef DEBUG - -# include "function.h" // for function attributes -# define D(p) DebugPrintf(__FILE__,__LINE__,p) -# define D2(p,a) DebugPrintf(__FILE__,__LINE__,p,a) -# define D2z(p,a) if (ringid==ROOT) DebugPrintf(__FILE__,__LINE__,p,a) -void DebugPrintf(const char *fname,int line,const char *fmt,...) ATT_PRINTF(3,4); -void FieldPrint(doublecomplex *x) ATT_UNUSED; +# define D(p) DebugPrintf(__FILE__, __LINE__, p) +# define D2(p,a) DebugPrintf(__FILE__, __LINE__, p,a) +# define D3(p,a,b) DebugPrintf(__FILE__, __LINE__, p,a,b) +# define D4(p,a,b,c) DebugPrintf(__FILE__, __LINE__, p,a,b,c) +void DebugPrintf(const char *fname,int line,const char *fmt, ...); +void FieldPrint(doublecomplex *x); #else -# define D(p) -# define D2(p,a) -# define D2z(p,a) +# define D(p) +# define D2(p,a) +# define D3(p,a,b) +# define D4(p,a,b,c) #endif -#endif // __debug_h +#endif /*__debug_h*/ diff --git a/src/fft.c b/src/fft.c index 397102d5..83558524 100644 --- a/src/fft.c +++ b/src/fft.c @@ -6,12 +6,11 @@ * * Previous versions by Michel Grimminck and Alfons Hoekstra * - * Copyright (C) 2006-2008 University of Amsterdam + * Copyright (C) 2006 M.A. Yurkin and A.G. Hoekstra * This code is covered by the GNU General Public License. */ #include -#include -#include +#include #include "vars.h" #include "cmplx.h" #include "const.h" @@ -21,1143 +20,1094 @@ #include "fft.h" #include "prec_time.h" #include "io.h" -#include "function.h" #ifdef FFTW3 -# include -/* define level of planning for usual and Dmatrix (DM) FFT: FFTW_ESTIMATE (heuristics), - * FFTW_MEASURE (default), FTW_PATIENT, or FFTW_EXHAUSTIVE - */ -# define PLAN_FFTW FFTW_MEASURE -# define PLAN_FFTW_DM FFTW_ESTIMATE +# include +/* define level of planning for usual and Dmatrix (DM) FFT */ +/* FFTW_ESTIMATE (heuristics), FFTW_MEASURE (def), FTW_PATIENT, or FFTW_EXHAUSTIVE */ +# define PLAN_FFTW FFTW_MEASURE +# define PLAN_FFTW_DM FFTW_ESTIMATE #endif -// for transpose YZ +/* for transpose YZ */ #define TR_BLOCK 64 -// SEMI-GLOBAL VARIABLES +/* SEMI-GLOBAL VARIABLES */ -// defined ant initialized in calculator.c +/* defined ant initialized in calculator.c */ extern const double *tab1,*tab2,*tab3,*tab4,*tab5,*tab6,*tab7,*tab8,*tab9,*tab10; extern const int **tab_index; -// defined and initialized in timing.c -extern TIME_TYPE Timing_FFT_Init,Timing_Dm_Init; - -// used in matvec.c -doublecomplex *Dmatrix; // holds FFT of the interaction matrix -doublecomplex *Xmatrix; // holds input vector (on expanded grid) to matvec -doublecomplex *slices; // used in inner cycle of matvec - holds 3 components (for fixed x) -doublecomplex *slices_tr; // additional storage space for slices to accelerate transpose -size_t DsizeY,DsizeZ,DsizeYZ; // size of the 'matrix' D - -// used in comm.c -double *BT_buffer, *BT_rbuffer; // buffers for BlockTranspose - -// LOCAL VARIABLES - -// D2 matrix and its two slices; used only temporary for InitDmatrix +/* defined and initialized in timing.c */ +extern clock_t Timing_FFT_Init,Timing_Dm_Init; + +/* used in matvec.c */ +doublecomplex *Dmatrix; /* holds FFT of the interaction matrix */ +doublecomplex *Xmatrix; /* holds input vector (on expanded grid) to matvec */ +doublecomplex *slices; /* used in inner cycle of matvec - holds 3 components (for fixed x) */ +doublecomplex *slices_tr; /* additional storage space for slices to accelerate transpose */ +int DsizeY,DsizeZ,DsizeYZ; /* size of the 'matrix' D */ +int NDcomp; /* number of components of D; equals to 6 */ +/* used in comm.c */ +double *BT_buffer, *BT_rbuffer; /* buffers for BlockTranspose */ + +/* LOCAL VARIABLES */ + +/* D2 matrix and its two slices; used only temporary for InitDmatrix */ static doublecomplex *slice,*slice_tr,*D2matrix; -static size_t D2sizeX,D2sizeY,D2sizeZ; // size of the 'matrix' D2 -static size_t blockTr=TR_BLOCK; // block size for TransposeYZ; see fft.h -static int weird_nprocs; // whether weird number of processors is used +static int D2sizeX,D2sizeY,D2sizeZ; /* size of the 'matrix' D2 */ +static int blockTr=TR_BLOCK; /* block size for TransposeYZ; see fft.h */ +static int weird_nprocs; /* whether weird number of processors is used */ #ifdef FFTW3 -// FFTW3 plans: f - FFT_FORWARD; b - FFT_BACKWARD -static fftw_plan planXf,planXb,planYf,planYb,planZf,planZb,planXf_Dm,planYf_Dm,planZf_Dm; + /* FFTW3 plans: f - FFT_FORWARD; b - FFT_BACKWARD */ + static fftw_plan planXf,planXb,planYf,planYb,planZf,planZb,planXf_Dm,planYf_Dm,planZf_Dm; #elif defined(FFT_TEMPERTON) # define IFAX_SIZE 20 -static double *trigsX,*trigsY,*trigsZ,*work; // arrays for Temperton FFT -static int ifaxX[IFAX_SIZE],ifaxY[IFAX_SIZE],ifaxZ[IFAX_SIZE]; -// Fortran routines from cfft99D.f -void cftfax_(const int *nn,int *ifax,double *trigs); -void cfft99_(double *data,double *_work,const double *trigs,const int *ifax,const int *inc, - const int *jump,const int *nn,const int *lot,const int *isign); + static double *trigsX,*trigsY,*trigsZ,*work; /* arrays for Temperton FFT */ + static int ifaxX[IFAX_SIZE],ifaxY[IFAX_SIZE],ifaxZ[IFAX_SIZE]; #endif -// EXTERNAL FUNCTIONS +/*============================================================*/ -// sinint.c -void cisi(double x,double *ci,double *si); - -//============================================================ - -INLINE size_t IndexDmatrix(const size_t x,size_t y,size_t z) -// index D matrix to store final result +INLINE int IndexDmatrix(const int x,int y,int z) + /* index D matrix to store final result */ { - if (y>=DsizeY) y=gridY-y; - if (z>=DsizeZ) z=gridZ-z; + if (y>=DsizeY) y=gridY-y; + if (z>=DsizeZ) z=gridZ-z; - return(NDCOMP*(x*DsizeYZ+z*DsizeY+y)); + return(NDcomp*(x*DsizeYZ+z*DsizeY+y)); } -//============================================================ +/*============================================================*/ -INLINE size_t IndexGarbledD(const size_t x,int y,int z,const size_t lengthN) -// index D2 matrix after BlockTranspose +INLINE int IndexGarbledD(const int x,int y,int z,const int lengthN) + /* index D2 matrix after BlockTranspose */ { - if (y<0) y+=D2sizeY; - if (z<0) z+=D2sizeZ; + if (y<0) y+=D2sizeY; + if (z<0) z+=D2sizeZ; #ifdef PARALLEL - return(((z%lengthN)*D2sizeY+y)*gridX+(z/lengthN)*local_Nx+x%local_Nx); + return(((z%lengthN)*D2sizeY+y)*gridX+(z/lengthN)*local_Nx+x%local_Nx); #else - return((z*D2sizeY+y)*gridX+x); + return((z*D2sizeY+y)*gridX+x); #endif } -//============================================================ +/*============================================================*/ -INLINE size_t IndexD2matrix(int x,int y,int z,const int nnn) -// index D2 matrix to store calculated elements +INLINE int IndexD2matrix(int x,int y,int z,const int nnn) + /* index D2 matrix to store calculate elements */ { - if (x<0) x+=gridX; - if (y<0) y+=D2sizeY; - // if (z<0) z+=D2sizeZ; - return(((z-nnn*local_z0)*D2sizeY+y)*gridX+x); + if (x<0) x+=gridX; + if (y<0) y+=D2sizeY; + if (z<0) z+=D2sizeZ; + return(((z-nnn*local_z0)*D2sizeY+y)*gridX+x); } -//============================================================ +/*============================================================*/ -INLINE size_t IndexSliceD2matrix(int y,int z) -// index slice of D2 matrix +INLINE int IndexSliceD2matrix(int y,int z) + /* index slice of D2 matrix */ { - if (y<0) y+=gridY; - if (z<0) z+=gridZ; + if (y<0) y+=gridY; + if (z<0) z+=gridZ; - return(y*gridZ+z); + return(y*gridZ+z); } -//============================================================ +/*============================================================*/ -INLINE size_t IndexSlice_zyD2matrix(const size_t y,const size_t z) -// index transposed slice of D2 matrix +INLINE int IndexSlice_zyD2matrix(const int y,const int z) + /* index transposed slice of D2 matrix */ { - return (z*gridY+y); + return (z*gridY+y); } -//============================================================ +/*============================================================*/ void TransposeYZ(const int direction) -// optimized routine to transpose y and z; forward: slices->slices_tr; backward: slices_tr->slices + /* optimised routine to transpose y and z + forward: slices -> slices_tr + backward: slices_tr -> slices */ { - size_t y,z,Y,Z,y1,y2,z1,z2,i,j,y0,z0,Xcomp; - doublecomplex *t0,*t1,*t2,*t3,*t4,*w0,*w1,*w2,*w3; - - if (direction==FFT_FORWARD) { - Y=gridY; - Z=gridZ; - w0=slices; - t0=slices_tr-Y; - } - else { // direction==FFT_BACKWARD - Y=gridZ; - Z=gridY; - w0=slices_tr; - t0=slices-Y; - } - - y1=Y/blockTr; - y2=Y%blockTr; - z1=Z/blockTr; - z2=Z%blockTr; - - for(Xcomp=0;Xcomp<3;Xcomp++) { - w1=w0+Xcomp*gridYZ; - t1=t0+Xcomp*gridYZ; - for(i=0;i<=y1;i++) { - if (i==y1) y0=y2; - else y0=blockTr; - w2=w1; - t2=t1; - for(j=0;j<=z1;j++) { - if (j==z1) z0=z2; - else z0=blockTr; - w3=w2; - t3=t2; - for (y=0;y trans + /* optimised routine to transpose y and z for Dmatrix: data -> trans */ { - size_t y,z,Y,Z,y1,y2,z1,z2,i,j,y0,z0; - doublecomplex *t1,*t2,*t3,*t4,*w1,*w2,*w3; - - Y=gridY; - Z=gridZ; - - y1=Y/blockTr; - y2=Y%blockTr; - z1=Z/blockTr; - z2=Z%blockTr; - - w1=data; - t1=trans-Y; - - for(i=0;i<=y1;i++) { - if (i==y1) y0=y2; - else y0=blockTr; - w2=w1; - t2=t1; - for(j=0;j<=z1;j++) { - if (j==z1) z0=z2; - else z0=blockTr; - w3=w2; - t3=t2; - for (y=0;y=x divisible by 2,3,5 only (if FFTW3 7 and one of 11 or 13 are allowed), - * and also divisible by 2 and divis. If weird_nprocs is used, only the latter condition is required - */ +int fftFit(int x,int div) + /* find the first number >=x divisible by 2,3,5 and 7 (last only if FFTW3) + only, and divisible by 2 and div + if weird_nprocs is used, only the latter condition is required */ { - int y; - - if (weird_nprocs) { - if (!IS_EVEN(divis)) divis*=2; - return (divis*((x+divis-1)/divis)); - } - else while (TRUE) { - y=x; - while (y%2==0) y/=2; - while (y%3==0) y/=3; - while (y%5==0) y/=5; + int y; + + if (weird_nprocs) { + if (div%2!=0) div*=2; + return (div*((x+div-1)/div)); + } + else do { + y=x; + while (y%2==0) y/=2; + while (y%3==0) y/=3; + while (y%5==0) y/=5; #ifdef FFTW3 - while (y%7==0) y/=7; - // one multiplier of either 11 or 13 is allowed - if (y%11==0) y/=11; - else if (y%13==0) y/=13; + while (y%7==0) y/=7; #endif - if (y==1 && IS_EVEN(x) && x%divis==0) return(x); - x++; - } + if (y==1 && x%2==0 && x%div==0) return(x); + x++; + } while(TRUE); } -//============================================================= +/*=============================================================*/ static void fftInitBeforeD(const int lengthZ) -// initialize fft before initialization of Dmatrix + /* initialize fft before initialization of Dmatrix */ { #ifdef FFTW3 - int grXint=gridX,grYint=gridY,grZint=gridZ; // this is needed to provide 'int *' to grids - - planYf_Dm=fftw_plan_many_dft(1,&grYint,gridZ,slice_tr,NULL,1,gridY, - slice_tr,NULL,1,gridY,FFT_FORWARD,PLAN_FFTW_DM); - planZf_Dm=fftw_plan_many_dft(1,&grZint,gridY,slice,NULL,1,gridZ, - slice,NULL,1,gridZ,FFT_FORWARD,PLAN_FFTW_DM); - planXf_Dm=fftw_plan_many_dft(1,&grXint,lengthZ*D2sizeY,D2matrix,NULL,1,gridX, - D2matrix,NULL,1,gridX,FFT_FORWARD,PLAN_FFTW_DM); + planYf_Dm=fftw_plan_many_dft(1,&gridY,gridZ,slice_tr,NULL,1,gridY, + slice_tr,NULL,1,gridY,FFT_FORWARD,PLAN_FFTW_DM); + planZf_Dm=fftw_plan_many_dft(1,&gridZ,gridY,slice,NULL,1,gridZ, + slice,NULL,1,gridZ,FFT_FORWARD,PLAN_FFTW_DM); + planXf_Dm=fftw_plan_many_dft(1,&gridX,lengthZ*D2sizeY,D2matrix,NULL,1,gridX, + D2matrix,NULL,1,gridX,FFT_FORWARD,PLAN_FFTW_DM); #elif defined(FFT_TEMPERTON) - int size,nn; - - // allocate memory - MALLOC_VECTOR(trigsX,double,2*gridX,ALL); - MALLOC_VECTOR(trigsY,double,2*gridY,ALL); - MALLOC_VECTOR(trigsZ,double,2*gridZ,ALL); - size=MAX(gridX*D2sizeY,3*gridYZ); - MALLOC_VECTOR(work,double,2*size,ALL); - // initialize ifax and trigs - nn=gridX; - cftfax_ (&nn,ifaxX,trigsX); - nn=gridY; - cftfax_ (&nn,ifaxY,trigsY); - nn=gridZ; - cftfax_ (&nn,ifaxZ,trigsZ); + int size,nn; + + /* allocate memory */ + if ((trigsX = (double *) malloc(2*gridX*sizeof(double))) == NULL) + LogError(EC_ERROR,ALL_POS,"could not malloc trigsX"); + if ((trigsY = (double *) malloc(2*gridY*sizeof(double))) == NULL) + LogError(EC_ERROR,ALL_POS,"could not malloc trigsY"); + if ((trigsZ = (double *) malloc(2*gridZ*sizeof(double))) == NULL) + LogError(EC_ERROR,ALL_POS,"could not malloc trigsZ"); + size=MAX(gridX*D2sizeY,3*gridYZ); + if ((work = (double *) malloc(2*size*sizeof(double))) == NULL) + LogError(EC_ERROR,ALL_POS,"could not malloc work"); + /* initialize ifax and trigs */ + nn=gridX; + cftfax_ (&nn,ifaxX,trigsX); + nn=gridY; + cftfax_ (&nn,ifaxY,trigsY); + nn=gridZ; + cftfax_ (&nn,ifaxZ,trigsZ); #endif } -//============================================================ +/*============================================================*/ static void fftInitAfterD(void) -// second part of fft initialization + /* second part of fft initialization */ { #ifdef FFTW3 - int lot; - fftw_iodim dims,howmany_dims[2]; - int grYint=gridY; // this is needed to provide 'int *' to gridY -# ifdef PRECISE_TIMING - SYSTEM_TIME tvp[13]; -# endif - PRINTZ("Initializing FFTW3\n"); - FFLUSHZ(stdout); -# ifdef PRECISE_TIMING - GetTime(tvp); -# endif - lot=3*gridZ; - planYf=fftw_plan_many_dft(1,&grYint,lot,slices_tr,NULL,1,gridY, - slices_tr,NULL,1,gridY,FFT_FORWARD,PLAN_FFTW); -# ifdef PRECISE_TIMING - GetTime(tvp+1); -# endif - planYb=fftw_plan_many_dft(1,&grYint,lot,slices_tr,NULL,1,gridY, - slices_tr,NULL,1,gridY,FFT_BACKWARD,PLAN_FFTW); -# ifdef PRECISE_TIMING - GetTime(tvp+2); -# endif - dims.n=gridZ; - dims.is=dims.os=1; - howmany_dims[0].n=3; - howmany_dims[0].is=howmany_dims[0].os=gridZ*gridY; - howmany_dims[1].n=boxY; - howmany_dims[1].is=howmany_dims[1].os=gridZ; - planZf=fftw_plan_guru_dft(1,&dims,2,howmany_dims,slices,slices,FFT_FORWARD,PLAN_FFTW); -# ifdef PRECISE_TIMING - GetTime(tvp+3); -# endif - planZb=fftw_plan_guru_dft(1,&dims,2,howmany_dims,slices,slices,FFT_BACKWARD,PLAN_FFTW); -# ifdef PRECISE_TIMING - GetTime(tvp+4); -# endif - dims.n=gridX; - dims.is=dims.os=1; - howmany_dims[0].n=3*local_Nz; - howmany_dims[0].is=howmany_dims[0].os=smallY*gridX; - howmany_dims[1].n=boxY; - howmany_dims[1].is=howmany_dims[1].os=gridX; - planXf=fftw_plan_guru_dft(1,&dims,2,howmany_dims,Xmatrix,Xmatrix,FFT_FORWARD,PLAN_FFTW); -# ifdef PRECISE_TIMING - GetTime(tvp+5); -# endif - planXb=fftw_plan_guru_dft(1,&dims,2,howmany_dims,Xmatrix,Xmatrix,FFT_BACKWARD,PLAN_FFTW); -# ifdef PRECISE_TIMING - GetTime(tvp+6); - // print precise timing of FFT planning - SetTimerFreq(); - PRINTBOTHZ(logfile, - "~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~\n" - " FFTW3 planning \n" - "~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~\n" - "Yf = %4.4f Total = %4.4f\n" - "Yb = %4.4f\n" - "Zf = %4.4f\n" - "Zb = %4.4f\n" - "Xf = %4.4f\n" - "Xb = %4.4f\n\n", - DiffSec(tvp,tvp+1),DiffSec(tvp,tvp+6),DiffSec(tvp+1,tvp+2),DiffSec(tvp+2,tvp+3), - DiffSec(tvp+3,tvp+4),DiffSec(tvp+4,tvp+5),DiffSec(tvp+5,tvp+6)); -# endif - // destroy old plans - fftw_destroy_plan(planXf_Dm); - fftw_destroy_plan(planYf_Dm); - fftw_destroy_plan(planZf_Dm); + int lot; + fftw_iodim dims,howmany_dims[2]; +# ifdef PRECISE_TIMING + SYSTEM_TIME tvp[13]; +# endif + PRINTZ("Initializing FFTW3\n"); + FFLUSHZ(stdout); +# ifdef PRECISE_TIMING + GetTime(tvp); +# endif + lot=3*gridZ; + planYf=fftw_plan_many_dft(1,&gridY,lot,slices_tr,NULL,1,gridY, + slices_tr,NULL,1,gridY,FFT_FORWARD,PLAN_FFTW); +# ifdef PRECISE_TIMING + GetTime(tvp+1); +# endif + planYb=fftw_plan_many_dft(1,&gridY,lot,slices_tr,NULL,1,gridY, + slices_tr,NULL,1,gridY,FFT_BACKWARD,PLAN_FFTW); +# ifdef PRECISE_TIMING + GetTime(tvp+2); +# endif + dims.n=gridZ; + dims.is=dims.os=1; + howmany_dims[0].n=3; + howmany_dims[0].is=howmany_dims[0].os=gridZ*gridY; + howmany_dims[1].n=boxY; + howmany_dims[1].is=howmany_dims[1].os=gridZ; + planZf=fftw_plan_guru_dft(1,&dims,2,howmany_dims,slices,slices,FFT_FORWARD,PLAN_FFTW); +# ifdef PRECISE_TIMING + GetTime(tvp+3); +# endif + planZb=fftw_plan_guru_dft(1,&dims,2,howmany_dims,slices,slices,FFT_BACKWARD,PLAN_FFTW); +# ifdef PRECISE_TIMING + GetTime(tvp+4); +# endif + dims.n=gridX; + dims.is=dims.os=1; + howmany_dims[0].n=3*local_Nz; + howmany_dims[0].is=howmany_dims[0].os=smallY*gridX; + howmany_dims[1].n=boxY; + howmany_dims[1].is=howmany_dims[1].os=gridX; + planXf=fftw_plan_guru_dft(1,&dims,2,howmany_dims,Xmatrix,Xmatrix,FFT_FORWARD,PLAN_FFTW); +# ifdef PRECISE_TIMING + GetTime(tvp+5); +# endif + planXb=fftw_plan_guru_dft(1,&dims,2,howmany_dims,Xmatrix,Xmatrix,FFT_BACKWARD,PLAN_FFTW); +# ifdef PRECISE_TIMING + GetTime(tvp+6); + /* print precise timing of FFT planning */ + SetTimerFreq(); + PRINTBOTHZ(logfile, + "~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~\n"\ + " FFTW3 planning \n"\ + "~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~\n"\ + "Yf = %4.4f Total = %4.4f\n"\ + "Yb = %4.4f\n"\ + "Zf = %4.4f\n"\ + "Zb = %4.4f\n"\ + "Xf = %4.4f\n"\ + "Xb = %4.4f\n\n", + DiffSec(tvp,tvp+1),DiffSec(tvp,tvp+6),DiffSec(tvp+1,tvp+2),DiffSec(tvp+2,tvp+3), + DiffSec(tvp+3,tvp+4),DiffSec(tvp+4,tvp+5),DiffSec(tvp+5,tvp+6)); +# endif + /* destroy old plans */ + fftw_destroy_plan(planXf_Dm); + fftw_destroy_plan(planYf_Dm); + fftw_destroy_plan(planZf_Dm); #endif } -//============================================================ +/*============================================================*/ static void CalcInterTerm(int i,int j,int k,int mu,int nu,doublecomplex result) -/* calculates interaction term between two dipoles; given integer distance vector {i,j,k} - * (in units of d), and component indices mu,nu. - */ + /* calculates interaction term between two dipoles; given integer distance vector {i,j,k} + (in units of d), and component indices mu,nu */ { - double rr,rtemp[3],qvec[3],q2[3],invr,invr3,qavec[3],av[3]; - double rr2,kr,kr2,kr3,kd2,q4,rn; - double temp,qmunu,qa,qamunu,invrn,invrn2,invrn3,invrn4,dmunu; - double kfr,ci,si,ci1,si1,ci2,si2,brd,cov,siv,g0,g2; - doublecomplex expval,br,br1,m,m2,Gf1,Gm0,Gm1,Gc1,Gc2; - int ind0,ind1,ind2,ind2m,ind3,ind4,indmunu; - int sigV[3],ic,sig,ivec[3],ord[3],invord[3]; - double t3q,t3a,t4q,t4a,t5tr,t5aa,t6tr,t6aa; - //int pr; - const int inter_avg=TRUE; - - // self interaction; self term is computed in different subroutine - if (i==0 && j==0 && k==0) { - result[RE]=result[IM]=0.0; - return; - } - - // for debugging - //pr=(i==1 && j==1 && k==1); - //if (pr) PRINTZ("%d,%d: ",mu,nu); - - // initialize rtemp - rtemp[0]=i*gridspace; - rtemp[1]=j*gridspace; - rtemp[2]=k*gridspace; - //====== calculate some basic constants ====== - rr2 = DotProd(rtemp,rtemp); - rr = sqrt(rr2); - rn=rr/gridspace; // normalized r - invr = 1/rr; - invr3 = invr*invr*invr; - MultScal(invr,rtemp,qvec); - kr = WaveNum * rr; - kr2 = kr*kr; - kfr=PI*rn; // k_F*r, for FCD - qmunu=qvec[mu]*qvec[nu]; - // cov=cos(kr); siv=sin(kr); expval=Exp(ikr)/r^3 - imExp(kr,expval); - cov=expval[RE]; - siv=expval[IM]; - cMultReal(invr3,expval,expval); - //====== calculate Gp ======== - // br=delta[mu,nu]*(-1+ikr+kr^2)-qmunu*(-3+3ikr+kr^2) - br[RE]=(3-kr2)*qmunu; - br[IM]=-3*kr*qmunu; - if(mu==nu) { - br[RE]+=kr2-1; - br[IM]+=kr; - } - // result=Gp=expval*br - cMult(br,expval,result); - //====== FCD (static and full) ======== - /* !!! speed of FCD can be improved by using faster version of sici routine, using predefined - * tables, etc (e.g. as is done in GSL library). But currently this do not seem to consume a - * significant portion of the total simulation time. - */ - if (IntRelation==G_FCD_ST) { - /* FCD is based on Gay-Balmaz P., Martin O.J.F. "A library for computing the filtered and - * non-filtered 3D Green's tensor associated with infinite homogeneous space and surfaces", - * Comp. Phys. Comm. 144:111-120 (2002), and Piller N.B. "Increasing the performance of the - * coupled-dipole approximation: A spectral approach", IEEE Trans.Ant.Propag. 46(8): - * 1126-1137. Here it differs by a factor of 4*pi*k^2. - */ - // result = Gp*[3*Si(k_F*r)+k_F*r*cos(k_F*r)-4*sin(k_F*r)]*2/(3*pi) - cisi(kfr,&ci,&si); - brd=TWO_OVER_PI*ONE_THIRD*(3*si+kfr*cos(kfr)-4*sin(kfr)); - cMultReal(brd,result,result); - } - else if (IntRelation==G_FCD) { - // ci,si_1,2 = ci,si_+,- = Ci,Si((k_F +,- k)r) - cisi(kfr+kr,&ci1,&si1); - cisi(kfr-kr,&ci2,&si2); - // ci=ci1-ci2; si=pi-si1-si2 - ci=ci1-ci2; - si=PI-si1-si2; - g0=INV_PI*(siv*ci+cov*si); - g2=INV_PI*(kr*(cov*ci-siv*si)+2*ONE_THIRD*(kfr*cos(kfr)-4*sin(kfr)))-g0; - temp=g0*kr2; - // brd=(delta[mu,nu]*(-g0*kr^2-g2)+qmunu*(g0*kr^2+3g2))/r^3 - brd=qmunu*(temp+3*g2); - if (mu==nu) brd-=temp+g2; - brd*=invr3; - // result=Gp+brd - result[RE]+=brd; - } - //======= second order corrections ======== - else if (IntRelation==G_SO) { - // !!! this should never happen - if (anisotropy) LogError(EC_ERROR,ONE_POS,"Incompatibility error in CalcInterTerm"); - kd2=kd*kd; - kr3=kr2*kr; - // only one refractive index can be used for FFT-compatible algorithm !!! - cEqual(ref_index[0],m); - cSquare(m,m2); - if (!inter_avg) { - qa=DotProd(qvec,prop); - // qamunu=qvec[mu]*prop[nu] + qvec[nu]*prop[mu] - qamunu=qvec[mu]*prop[nu]; - if (mu==nu) qamunu*=2; - else qamunu+=qvec[nu]*prop[mu]; - } - if (kr*rn < G_BOUND_CLOSE) { - //====== G close ============= - // check if inside the table bounds; needed to recompute to make an integer comparison - if ((i*i+j*j+k*k) > TAB_RMAX*TAB_RMAX) LogError(EC_ERROR,ALL_POS, - "Not enough table size (available only up to R/d=%d)",TAB_RMAX); - - // av is copy of propagation vector - if (!inter_avg) memcpy(av,prop,3*sizeof(double)); - ivec[0]=i; - ivec[1]=j; - ivec[2]=k; - // transformation of negative coordinates - for (ic=0;ic<3;ic++) { - if (ivec[ic]<0) { - sigV[ic]=-1; - av[ic]*=-1; - qvec[ic]*=-1; - ivec[ic]*=-1; - } - else sigV[ic]=1; - } - i=ivec[0]; - j=ivec[1]; - k=ivec[2]; - sig=sigV[mu]*sigV[nu]; // sign of some terms below - // transformation to case i>=j>=k>=0 - // building of ord; ord[x] is x-th largest coordinate (0-th - the largest) - if (i>=j) { - if (i>=k) { - ord[0]=0; - if (j>=k) { - ord[1]=1; - ord[2]=2; - } - else { - ord[1]=2; - ord[2]=1; - } - } - else { - ord[0]=2; - ord[1]=0; - ord[2]=1; - } - } - else { - if (i>=k) { - ord[0]=1; - ord[1]=0; - ord[2]=2; - } - else { - ord[2]=0; - if (j>=k) { - ord[0]=1; - ord[1]=2; - } - else { - ord[0]=2; - ord[1]=1; - } - } - } - // change parameters according to coordinate transforms - Permutate(qvec,ord); - if (!inter_avg) Permutate(av,ord); - Permutate_i(ivec,ord); - i=ivec[0]; - j=ivec[1]; - k=ivec[2]; - // compute inverse permutation - memcpy(invord,ord,3*sizeof(int)); - Permutate_i(invord,ord); - if (invord[0]==0 && invord[1]==1 && invord[2]==2) memcpy(invord,ord,3*sizeof(int)); - // compute transformed indices mu and nu - mu=invord[mu]; - nu=invord[nu]; - // indexes for tables of different dimensions - // indmunu is a number of component[mu,nu] in symmetric matrix - indmunu=mu+nu; - if (mu==2 || nu==2) indmunu++; - - ind0=tab_index[i][j]+k; - ind1=3*ind0; - ind2m=6*ind0; - ind2=ind2m+indmunu; - ind3=3*ind2; - ind4=6*ind2; - // computing several quantities with table integrals - t3q=DotProd(qvec,tab3+ind1); - t4q=DotProd(qvec,tab4+ind3); - t5tr=TrSym(tab5+ind2m); - t6tr=TrSym(tab6+ind4); - if (inter_avg) { - // =1/3*delta[mu,nu] - t5aa=ONE_THIRD*t5tr; - t6aa=ONE_THIRD*t6tr; - } - else { - t3a=DotProd(av,tab3+ind1); - t4a=DotProd(av,tab4+ind3); - t5aa=QuadForm(tab5+ind2m,av); - t6aa=QuadForm(tab6+ind4,av); - } - //====== computing Gc0 ===== - // temp = kr/24 - temp=kr/24; - /* br = delta[mu,nu]*(-I7-I9/2-kr*(i+kr)/24+2*t3q+t5tr) - * - (-3I8[mu,nu]-3I10[mu,nu]/2-qmunu*kr*(i+kr)/24+2*t4q+t6tr) - */ - br[RE]=sig*(3*(tab10[ind2]/2+tab8[ind2])-2*t4q-t6tr)+temp*qmunu*kr; - br[IM]=3*temp*qmunu; - if (mu==nu) { - br[RE]+=2*t3q+t5tr-temp*kr-tab9[ind0]/2-tab7[ind0]; - br[IM]-=temp; - } - // br*=kd^2 - cMultReal(kd2,br,br); - // br+=I1*delta[mu,nu]*(-1+ikr+kr^2)-sig*I2[mu,nu]*(-3+3ikr+kr^2) - br[RE]+=sig*tab2[ind2]*(3-kr2); - br[IM]-=sig*tab2[ind2]*3*kr; - if (mu==nu) { - br[RE]+=tab1[ind0]*(kr2-1); - br[IM]+=tab1[ind0]*kr; - } - // Gc0=expval*br - cMult(expval,br,result); - //==== computing Gc1 ====== - if (!inter_avg) { - // br=(kd*kr/24)*(qa*(delta[mu,nu]*(-2+ikr)-qmunu*(-6+ikr))-qamunu) - br[RE]=6*qmunu; - br[IM]=-kr*qmunu; - if (mu==nu) { - br[RE]-=2; - br[IM]+=kr; - } - cMultReal(qa,br,br); - br[RE]-=qamunu; - cMultReal(2*temp*kd,br,br); - // br1=(d/r)*(delta[mu,nu]*t3h*(-1+ikr)-sig*t4h*(-3+3ikr)) - br1[RE]=3*sig*t4a; - br1[IM]=-kr*br1[RE]; - if (mu==nu) { - br1[RE]-=t3a; - br1[IM]+=t3a*kr; - } - cMultReal(1/rn,br1,br1); - // Gc1=expval*i*m*kd*(br1+br) - cAdd(br,br1,Gc1); - cMultSelf(Gc1,m); - cMultReal(kd,Gc1,Gc1); - cMultSelf(Gc1,expval); - cMult_i(Gc1); - } - //==== computing Gc2 ====== - // br=delta[mu,nu]*t5aa-3*sig*t6aa-(kr/12)*(delta[mu,nu]*(i+kr)-qmunu*(3i+kr)) - br[RE]=-kr*qmunu; - br[IM]=-3*qmunu; - if (mu==nu) { - br[RE]+=kr; - br[IM]+=1; - } - cMultReal(-2*temp,br,br); - br[RE]-=3*sig*t6aa; - if (mu==nu) br[RE]+=t5aa; - // Gc2=expval*(kd^2/2)*m^2*br - cMult(m2,br,Gc2); - cMultReal(kd2/2,Gc2,Gc2); - cMultSelf(Gc2,expval); - // result = Gc0 + [ Gc1 ] + Gc2 - if (!inter_avg) cAdd(Gc2,Gc1,Gc2); - cAdd(Gc2,result,result); - } - else { - //====== Gfar (and part of Gmedian) ======= - // temp=kd^2/24 - temp=kd2/24; - // br=1-(1+m^2)*kd^2/24 - br[RE]=1-(1+m2[RE])*temp; - br[IM]=-m2[IM]*temp; - // Gf0 + Gf2 = Gp*br - cMultSelf(result,br); - //==== compute and add Gf1 === - if (!inter_avg) { - /* br = {delta[mu,nu]*(3-3ikr-2kr^2+ikr^3)-qmunu*(15-15ikr-6kr^2+ikr^3)}*qa - * + qamunu*(3-3ikr-kr^2) - */ - br[RE]=(6*kr2-15)*qmunu; - br[IM]=(15*kr-kr3)*qmunu; - if(mu==nu) { - br[RE]+=3-2*kr2; - br[IM]+=kr3-3*kr; - } - cMultReal(qa,br,br); - br[RE]+=(3-kr2)*qamunu; - br[IM]-=3*kr*qamunu; - // temp = kd^2/(12*kr) - temp*=2/kr; - // Gf1=expval*i*m*temp*br - cMult(m,br,Gf1); - cMultReal(temp,Gf1,Gf1); - cMultSelf(Gf1,expval); - cMult_i(Gf1); - // result = Gf - cAdd(Gf1,result,result); - } - if (kr < G_BOUND_MEDIAN) { - //===== G median ======== - vMult(qvec,qvec,q2); - q4=DotProd(q2,q2); - invrn=1/rn; - invrn2=invrn*invrn; - invrn3=invrn2*invrn; - invrn4=invrn2*invrn2; - // Gm0=expval*br*temp - temp=qmunu*(33*q4-7-12*(q2[mu]+q2[nu])); - if (mu == nu) temp+=(1-3*q4+4*q2[mu]); - temp*=7*invrn4/64; - br[RE]=-1; - br[IM]=kr; - cMultReal(temp,br,Gm0); - cMultSelf(Gm0,expval); - if (!inter_avg) { - // Gm1=expval*i*m*temp - vMult(qvec,prop,qavec); - if (mu == nu) dmunu=1; - else dmunu=0; - temp = 3*qa*(dmunu-7*qmunu) + 6*dmunu*qvec[mu]*prop[mu] - - 7*(dmunu-9*qmunu)*DotProd(qavec,q2) - + 3*(prop[mu]*qvec[nu]*(1-7*q2[mu])+prop[nu]*qvec[mu]*(1-7*q2[nu])); - temp*=kd*invrn3/48; - cMultReal(temp,m,Gm1); - cMult_i(Gm1); - cMultSelf(Gm1,expval); - // add Gm1 to Gm0 - cAdd(Gm0,Gm1,Gm0); - } - // result = Gf + Gm0 + [ Gm1 ] - cAdd(Gm0,result,result); - } - } - } - // if (pr) PRINTZ("%d,%d: %f+%fi\n",mu,nu,result[RE],result[IM]); + double rr, rtemp[3], qvec[3], q2[3], invr, invr3, qavec[3], av[3]; + double rr2, kr, kr2, kr3, kd2, q4, rn; + double temp, qmunu, qa, qamunu, invrn, invrn2, invrn3, invrn4, dmunu; + doublecomplex expval, br, br1, m, m2, Gf1, Gm0, Gm1, Gc1, Gc2; + int ind0, ind1, ind2, ind2m, ind3, ind4, indmunu; + int sigV[3], ic, sig, ivec[3], ord[3], invord[3]; + double t3q, t3a, t4q, t4a, t5tr, t5aa, t6tr, t6aa; + int pr; + const int inter_avg=TRUE; + + /* self interaction; self term is computed in different subroutine */ + if (i==0 && j==0 && k==0) { + result[RE]=result[IM]=0.0; + return; + } + +/* pr=(i==1 && j==1 && k==1); + if (pr) PRINTZ("%d,%d: ",mu,nu); /* for debugging */ + + /* initialize rtemp */ + rtemp[0]=i*gridspace; + rtemp[1]=j*gridspace; + rtemp[2]=k*gridspace; + /* calculate some basic constants */ + rr2 = DotProd(rtemp,rtemp); + rr = sqrt(rr2); + invr = 1/rr; + invr3 = invr*invr*invr; + MultScal(invr,rtemp,qvec); + kr = WaveNum * rr; + kr2 = kr*kr; + qmunu=qvec[mu]*qvec[nu]; + /*====== calculate Gp ========*/ + /* br=delta[mu,nu]*(-1+ikr+kr^2)-qmunu*(-3+3ikr+kr^2) */ + br[RE]=(3-kr2)*qmunu; + br[IM]=-3*kr*qmunu; + if(mu==nu) { + br[RE]+=kr2-1; + br[IM]+=kr; + } + /* expval=Exp(ikr)/rr^3 */ + cExp(kr,expval); + cMultReal(invr3,expval,expval); + /* result=Gp */ + cMult(br,expval,result); + /*======= second order corrections ========*/ + if (IntRelation==G_SO) { + kd2=kd*kd; + kr3=kr2*kr; + rn=rr/gridspace; /* normalized r */ + /* only one refractive index can be used for FFT-compatible algorithm !!! */ + memcpy(m,ref_index[0],sizeof(doublecomplex)); + cSquare(m,m2); + if (!inter_avg) { + qa=DotProd(qvec,prop); + /* qamunu=qvec[mu]*prop[nu] + qvec[nu]*prop[mu] */ + qamunu=qvec[mu]*prop[nu]; + if (mu==nu) qamunu*=2; + else qamunu+=qvec[nu]*prop[mu]; + } + if (kr*rn < G_BOUND_CLOSE) { + /*====== G close =============*/ + /* check if inside the table bounds; needed to recompute to mske an integer comparison */ + if ((i*i+j*j+k*k) > TAB_RMAX*TAB_RMAX) LogError(EC_ERROR,ALL_POS, + "Not enough table size (available only up to R/d=%d)",TAB_RMAX); + + /* av is copy of propagation vector */ + if (!inter_avg) memcpy(av,prop,3*sizeof(double)); + ivec[0]=i; + ivec[1]=j; + ivec[2]=k; + /* transformation of negative coordinates */ + for (ic=0;ic<3;ic++) { + if (ivec[ic]<0) { + sigV[ic]=-1; + av[ic]*=-1; + qvec[ic]*=-1; + ivec[ic]*=-1; + } + else sigV[ic]=1; + } + i=ivec[0]; + j=ivec[1]; + k=ivec[2]; + sig=sigV[mu]*sigV[nu]; /* sign of some terms below */ + /* transformation to case i>=j>=k>=0 */ + /* building of ord; ord[x] is x-th largest coordinate (0-th - the largest) */ + if (i>=j) { + if (i>=k) { + ord[0]=0; + if (j>=k) { + ord[1]=1; + ord[2]=2; + } + else { + ord[1]=2; + ord[2]=1; + } + } + else { + ord[0]=2; + ord[1]=0; + ord[2]=1; + } + } + else { + if (i>=k) { + ord[0]=1; + ord[1]=0; + ord[2]=2; + } + else { + ord[2]=0; + if (j>=k) { + ord[0]=1; + ord[1]=2; + } + else { + ord[0]=2; + ord[1]=1; + } + } + } + /* change parameters according to coordinate transforms */ + Permutate(qvec,ord); + if (!inter_avg) Permutate(av,ord); + Permutate_i(ivec,ord); + i=ivec[0]; + j=ivec[1]; + k=ivec[2]; + /* compute inverse permutation */ + memcpy(invord,ord,3*sizeof(int)); + Permutate_i(invord,ord); + if (invord[0]==0 && invord[1]==1 && invord[2]==2) memcpy(invord,ord,3*sizeof(int)); + /* compute transformed indices mu and nu */ + mu=invord[mu]; + nu=invord[nu]; + /* indexes for tables of different dimensions */ + /* indmunu is a number of component[mu,nu] in symmetric matrix */ + indmunu=mu+nu; + if (mu==2 || nu==2) indmunu++; + + ind0=tab_index[i][j]+k; + ind1=3*ind0; + ind2m=6*ind0; + ind2=ind2m+indmunu; + ind3=3*ind2; + ind4=6*ind2; + /* computing several quantities with table integrals */ + t3q=DotProd(qvec,tab3+ind1); + t4q=DotProd(qvec,tab4+ind3); + t5tr=TrSym(tab5+ind2m); + t6tr=TrSym(tab6+ind4); + if (inter_avg) { + /* =1/3*delta[mu,nu] */ + t5aa=ONE_THIRD*t5tr; + t6aa=ONE_THIRD*t6tr; + } + else { + t3a=DotProd(av,tab3+ind1); + t4a=DotProd(av,tab4+ind3); + t5aa=QuadForm(tab5+ind2m,av); + t6aa=QuadForm(tab6+ind4,av); + } + /*====== computing Gc0 =====*/ + /* temp = kr/24 */ + temp=kr/24; + /* br=delta[mu,nu]*(-I7-I9/2-kr*(i+kr)/24+2*t3q+t5tr)- + (-3I8[mu,nu]-3I10[mu,nu]/2-qmunu*kr*(i+kr)/24+2*t4q+t6tr) */ + br[RE]=sig*(3*(tab10[ind2]/2+tab8[ind2])-2*t4q-t6tr)+temp*qmunu*kr; + br[IM]=3*temp*qmunu; + if (mu==nu) { + br[RE]+=2*t3q+t5tr-temp*kr-tab9[ind0]/2-tab7[ind0]; + br[IM]-=temp; + } + /* br*=kd^2 */ + cMultReal(kd2,br,br); + /* br+=I1*delta[mu,nu]*(-1+ikr+kr^2)-sig*I2[mu,nu]*(-3+3ikr+kr^2) */ + br[RE]+=sig*tab2[ind2]*(3-kr2); + br[IM]-=sig*tab2[ind2]*3*kr; + if (mu==nu) { + br[RE]+=tab1[ind0]*(kr2-1); + br[IM]+=tab1[ind0]*kr; + } + /* Gc0=expval*br */ + cMult(expval,br,result); + /*==== computing Gc1 ======*/ + if (!inter_avg) { + /* br=(kd*kr/24)*(qa*(delta[mu,nu]*(-2+ikr)-qmunu*(-6+ikr))-qamunu)*/ + br[RE]=6*qmunu; + br[IM]=-kr*qmunu; + if (mu==nu) { + br[RE]-=2; + br[IM]+=kr; + } + cMultReal(qa,br,br); + br[RE]-=qamunu; + cMultReal(2*temp*kd,br,br); + /* br1=(d/r)*(delta[mu,nu]*t3h*(-1+ikr)-sig*t4h*(-3+3ikr)) */ + br1[RE]=3*sig*t4a; + br1[IM]=-kr*br1[RE]; + if (mu==nu) { + br1[RE]-=t3a; + br1[IM]+=t3a*kr; + } + cMultReal(1/rn,br1,br1); + /* Gc1=expval*i*m*kd*(br1+br) */ + cAdd(br,br1,Gc1); + cMultSelf(Gc1,m); + cMultReal(kd,Gc1,Gc1); + cMultSelf(Gc1,expval); + cMult_i(Gc1); + } + /*==== computing Gc2 ======*/ + /* br=delta[mu,nu]*t5aa-3*sig*t6aa-(kr/12)*(delta[mu,nu]*(i+kr)-qmunu*(3i+kr)) */ + br[RE]=-kr*qmunu; + br[IM]=-3*qmunu; + if (mu==nu) { + br[RE]+=kr; + br[IM]+=1; + } + cMultReal(-2*temp,br,br); + br[RE]-=3*sig*t6aa; + if (mu==nu) br[RE]+=t5aa; + /* Gc2=expval*(kd^2/2)*m^2*br */ + cMult(m2,br,Gc2); + cMultReal(kd2/2,Gc2,Gc2); + cMultSelf(Gc2,expval); + /* result = Gc0 + [ Gc1 ] + Gc2 */ + if (!inter_avg) cAdd(Gc2,Gc1,Gc2); + cAdd(Gc2,result,result); + } + else { + /*====== Gfar (and part of Gmedian) =======*/ + /* temp=kd^2/24 */ + temp=kd2/24; + /* br=1-(1+m^2)*kd^2/24 */ + br[RE]=1-(1+m2[RE])*temp; + br[IM]=-m2[IM]*temp; + /* Gf0 + Gf2 = Gp*br */ + cMultSelf(result,br); + /*==== compute and add Gf1 ===*/ + if (!inter_avg) { + /* br={delta[mu,nu]*(3-3ikr-2kr^2+ikr^3)-qmunu*(15-15ikr-6kr^2+ikr^3)}*qa + +qamunu*(3-3ikr-kr^2) */ + br[RE]=(6*kr2-15)*qmunu; + br[IM]=(15*kr-kr3)*qmunu; + if(mu==nu) { + br[RE]+=3-2*kr2; + br[IM]+=kr3-3*kr; + } + cMultReal(qa,br,br); + br[RE]+=(3-kr2)*qamunu; + br[IM]-=3*kr*qamunu; + /* temp = kd^2/(12*kr) */ + temp*=2/kr; + /* Gf1=expval*i*m*temp*br */ + cMult(m,br,Gf1); + cMultReal(temp,Gf1,Gf1); + cMultSelf(Gf1,expval); + cMult_i(Gf1); + /* result = Gf */ + cAdd(Gf1,result,result); + } + if (kr < G_BOUND_MEDIAN) { + /*===== G median ========*/ + vMult(qvec,qvec,q2); + q4=DotProd(q2,q2); + invrn=1/rn; + invrn2=invrn*invrn; + invrn3=invrn2*invrn; + invrn4=invrn2*invrn2; + /* Gm0=expval*br*temp */ + temp=qmunu*(33*q4-7-12*(q2[mu]+q2[nu])); + if (mu == nu) temp+=(1-3*q4+4*q2[mu]); + temp*=7*invrn4/64; + br[RE]=-1; + br[IM]=kr; + cMultReal(temp,br,Gm0); + cMultSelf(Gm0,expval); + if (!inter_avg) { + /* Gm1=expval*i*m*temp */ + vMult(qvec,prop,qavec); + if (mu == nu) dmunu=1; + else dmunu=0; + temp=3*qa*(dmunu-7*qmunu)+6*dmunu*qvec[mu]*prop[mu]-7*(dmunu-9*qmunu)*DotProd(qavec,q2)+ + 3*(prop[mu]*qvec[nu]*(1-7*q2[mu])+prop[nu]*qvec[mu]*(1-7*q2[nu])); + temp*=kd*invrn3/48; + cMultReal(temp,m,Gm1); + cMult_i(Gm1); + cMultSelf(Gm1,expval); + /* add Gm1 to Gm0 */ + cAdd(Gm0,Gm1,Gm0); + } + /* result = Gf + Gm0 + [ Gm1 ]*/ + cAdd(Gm0,result,result); + } + } + } + /* if (pr) PRINTZ("%d,%d: %f+%fi\n",mu,nu,result[RE],result[IM]); */ } -//============================================================ +/*============================================================*/ void InitDmatrix(void) -/* Initializes the matrix D. D[i][j][k]=A[i1-i2][j1-j2][k1-k2]. Actually D=-FFT(G)/Ngrid. - * Then -G.x=invFFT(D*FFT(x)) for practical implementation of FFT such that invFFT(FFT(x))=Ngrid*x. - * G is exactly Green's tensor. The routine is called only once, so needs not to be very fast, - * however we tried to optimize it. - */ + /* initialises the matrix D. D[i][j][k]=A[i1-i2][j1-j2][k1-k2] + The routine is called only once, so needs not to be very fast */ { - int i,j,k,kcor,Dcomp; - size_t x,y,z,indexfrom,indexto,ind,index,D2sizeTot; - double invNgrid,mem; - int nnn; // multiplier used for reduced_FFT or not reduced; 1 or 2 - int jstart, kstart; - size_t lengthN; - int mu, nu; // indices for interaction term - TIME_TYPE start,time1; -#ifdef PARALLEL - size_t bufsize; -#endif + int y,z,i,j,k,ind,kcor,index,mem,Dcomp,indexfrom,indexto,D2sizeTot; + double Ngrid,invNgrid; + + int nnn; /* multiplier used for reduced_FFT or not reduced; 1 or 2 */ + int jstart, kstart; + int lengthN, bufsize; + + int mu, nu; /* indices for interaction term */ + clock_t start,time1; #ifdef PRECISE_TIMING - // precise timing of the Dmatrix computation - SYSTEM_TIME tvp[13]; - SYSTEM_TIME Timing_fftX,Timing_fftY,Timing_fftZ,Timing_ar1,Timing_ar2,Timing_ar3, - Timing_BT,Timing_TYZ,Timing_beg; - double t_fftX,t_fftY,t_fftZ,t_ar1,t_ar2,t_ar3, - t_TYZ,t_beg,t_Arithm,t_FFT,t_BT; - - InitTime(&Timing_fftX); - InitTime(&Timing_fftY); - InitTime(&Timing_fftZ); - InitTime(&Timing_ar1); - InitTime(&Timing_ar2); - InitTime(&Timing_ar3); - InitTime(&Timing_BT); - InitTime(&Timing_TYZ); - GetTime(tvp); + /* precise timing of the Dmatrix computation */ + SYSTEM_TIME tvp[13]; + SYSTEM_TIME Timing_fftX,Timing_fftY,Timing_fftZ,Timing_ar1,Timing_ar2,Timing_ar3, + Timing_BT,Timing_TYZ,Timing_beg; + double t_fftX,t_fftY,t_fftZ,t_ar1,t_ar2,t_ar3, + t_TYZ,t_beg,t_Arithm,t_FFT,t_BT; + + InitTime(&Timing_fftX); + InitTime(&Timing_fftY); + InitTime(&Timing_fftZ); + InitTime(&Timing_ar1); + InitTime(&Timing_ar2); + InitTime(&Timing_ar3); + InitTime(&Timing_BT); + InitTime(&Timing_TYZ); + GetTime(tvp); #endif - start=GET_TIME(); - // initialize sizes of D and D2 matrices - D2sizeX=gridX; - if (reduced_FFT) { - D2sizeY=gridY/2; - D2sizeZ=gridZ/2; - DsizeY=gridY/2+1; - DsizeZ=gridZ/2+1; - nnn=1; - jstart=0; - kstart=0; - } - else { - D2sizeY=DsizeY=gridY; - D2sizeZ=DsizeZ=gridZ; - nnn=2; - jstart=1-boxY; - kstart=1-boxZ; - } - // auxiliary parameters - lengthN=nnn*local_Nz; - DsizeYZ=DsizeY*DsizeZ; - invNgrid=1.0/(gridX*((double)gridYZ)); - local_Nsmall=(gridX/2)*(gridYZ/(2*nprocs)); // size of X vector (for 1 component) - /* calculate size of matvec matrices (X,D,slices,slices_tr) and BT buffers (if parallel); - * uses complex expression to avoid overflows and enable prognosis for large grids - */ - mem = sizeof(doublecomplex)*(3*(2+(gridX/(4.0*nprocs)))*((double)gridYZ) - + NDCOMP*local_Nx*((double)DsizeYZ)); + start=clock(); + /* initialize sizes of D and D2 matrices */ + D2sizeX=gridX; + if (reduced_FFT) { + D2sizeY=gridY/2; + D2sizeZ=gridZ/2; + DsizeY=gridY/2+1; + DsizeZ=gridZ/2+1; + nnn=1; + jstart=0; + kstart=0; + } + else { + D2sizeY=DsizeY=gridY; + D2sizeZ=DsizeZ=gridZ; + nnn=2; + jstart=1-boxY; + kstart=1-boxZ; + } + /* auxiliary parameters */ + lengthN=nnn*local_Nz; + DsizeYZ=DsizeY*DsizeZ; + Ngrid=gridX*gridY*gridZ; + invNgrid=1.0/Ngrid; + local_Nsmall=gridX*gridY*gridZ/(4*nprocs); /* size of X vector (for 1 component) */ + NDcomp=6; + /* calculate size of matvec matrices (X,D,slices,slices_tr) and BT buffers (if parallel) */ + mem=sizeof(doublecomplex)*(3*(local_Nsmall+2*gridYZ)+NDcomp*local_Nx*DsizeY*DsizeZ); #ifdef PARALLEL - mem+=12*smallY*((double)(local_Nz*local_Nx))*sizeof(double); + mem+=12*smallY*local_Nz*local_Nx*sizeof(double); #endif - // printout some information - /* conversions to (unsigned long) are needed (to remove warnings) because %z printf argument is not - * yet supported by all target compiler environmets - */ - FPRINTZ(logfile,"The FFT grid is: %lux%lux%lu\n",(unsigned long)gridX,(unsigned long)gridY, - (unsigned long)gridZ); + /* printout some information */ + FPRINTZ(logfile,"The FFT grid is: %ix%ix%i\n",gridX,gridY,gridZ); #ifdef PARALLEL - PRINTBOTHZ(logfile,"Memory usage for MatVec matrices (per processor): %.1f Mb\n",mem/MBYTE); + PRINTBOTHZ(logfile,"Memory usage for MatVec matrices (per processor): %.1f Mb\n",mem/MBYTE); #else - PRINTBOTHZ(logfile,"Memory usage for MatVec matrices: %.1f Mb\n",mem/MBYTE); + PRINTBOTHZ(logfile,"Memory usage for MatVec matrices: %.1f Mb\n",mem/MBYTE); #endif - FFLUSHZ(logfile); - memory+=mem; - if (prognose) return; - // allocate memory for Dmatrix - MALLOC_VECTOR(Dmatrix,complex,MultOverflow(NDCOMP*local_Nx,DsizeYZ,ONE_POS,"Dmatrix"),ALL); - // allocate memory for D2matrix components - D2sizeTot=nnn*local_Nz*D2sizeY*D2sizeX; - MALLOC_VECTOR(D2matrix,complex,D2sizeTot,ALL); - MALLOC_VECTOR(slice,complex,gridYZ,ALL); - MALLOC_VECTOR(slice_tr,complex,gridYZ,ALL); - // actually allocation of Xmatrix, slices, slices_tr is below after freeing of Dmatrix and its slice + FFLUSHZ(logfile); + memory+=mem; + if (prognose) return; + /* allocate memory for Dmatrix */ + if ((Dmatrix = cVector(NDcomp*local_Nx*DsizeY*DsizeZ)) == NULL) + LogError(EC_ERROR,ALL_POS,"Could not malloc Dmatrix"); + /* allocate memory for D2matrix components */ + D2sizeTot=nnn*local_Nz*D2sizeY*D2sizeX; + if ((D2matrix = cVector(D2sizeTot)) == NULL) + LogError(EC_ERROR,ALL_POS,"Could not malloc D2matrix"); + if ((slice = cVector(gridYZ)) == NULL) + LogError(EC_ERROR,ALL_POS,"Could not malloc slice"); + if ((slice_tr = cVector(gridYZ)) == NULL) + LogError(EC_ERROR,ALL_POS,"Could not malloc slice_tr"); + /* actually allocation of Xmatrix, slices, slices_tr is below; + after freeing of Dmatrix and its slice */ #ifdef PARALLEL - // allocate buffer for BlockTranspose_Dm - bufsize = 2*lengthN*D2sizeY*local_Nx; - MALLOC_VECTOR(BT_buffer,double,bufsize,ALL); - MALLOC_VECTOR(BT_rbuffer,double,bufsize,ALL); + /* allocate buffer for BlockTranspose_Dm */ + bufsize = 2*lengthN*D2sizeY*local_Nx; + if ((BT_buffer = dVector(0,bufsize-1)) == NULL) + LogError(EC_ERROR,ALL_POS,"Could not malloc BT_buffer"); + if ((BT_rbuffer = dVector(0,bufsize-1)) == NULL) + LogError(EC_ERROR,ALL_POS,"Could not malloc BT_rbuffer"); #endif - D("Initialize FFT (1st part)"); - fftInitBeforeD(lengthN); + D("init FFT (1st part)"); + fftInitBeforeD(lengthN); #ifdef PRECISE_TIMING - GetTime(tvp+1); - elapsed(tvp,tvp+1,&Timing_beg); + GetTime(tvp+1); + elapsed(tvp,tvp+1,&Timing_beg); #endif - PRINTZ("Calculating Dmatrix"); - FFLUSHZ(stdout); + PRINTZ("Calculating Dmatrix"); + FFLUSHZ(stdout); - for(Dcomp=0;Dcomp(int)smallZ) kcor=k-gridZ; - else kcor=k; - for (j=jstart;jsmallZ) kcor=k-gridZ; + else kcor=k; + for (j=jstart;j @@ -10,294 +10,195 @@ #include #include #include -// the following is for MkDirErr -#include "os.h" -#ifdef POSIX -# include -# include -#endif - #include "io.h" #include "comm.h" #include "const.h" #include "vars.h" -#include "memory.h" - -// SEMI-GLOBAL VARIABLES - -// defined and initialized in param.c -extern const char logname[]; - -// LOCAL VARIABLES - - // error buffer for warning message generated before logfile is opened -static char warn_buf[MAX_MESSAGE2]=""; -//============================================================ +#include "crosssec.h" -void WrapLines(char *str) -/* wraps long lines in a string without breaking words; it replaces a number of spaces in string by - * '\n' characters; line width is determined by variable term_width. - */ -{ - char *left,*right,*mid,*end; - int divided; - - end=str+strlen(str); - left=str; - while (leftterm_width) { - divided=FALSE; - mid=left+term_width; - // search backward for space - while (mid>=left) { - if(mid[0]==' ') { - mid[0]='\n'; - left=mid+1; - divided=TRUE; - break; - } - mid--; - } - // if backward search failed (too long word), search forward for space - if (!divided) { - mid=left+term_width+1; - while (mid // for file -#include "function.h" // for function attributes +#include -/* File locking is made quite robust, however it is a complex operation that can cause unexpected - * behavior (permanent locks) especially when program is terminated externally (e.g. because of MPI - * failure). Moreover, it is not ANSI C, hence may have problems on some particular systems. - * Currently file locking functions are only in param.c - */ +/* file locking is made quite robust, however it is a complex operation that + can cause unexpected behaviour (permanent locks) especially when + program is terminated externally (e.g. because of MPI failure). + Moreover, it is not ANSI C, hence may have problems on some particular systems. + Currently file locking functions are only in param.c */ -//#define NOT_USE_LOCK // uncomment to disable file locking -//#define ONLY_LOCKFILE // uncomment to use only lock file, without file locking over NFS +/*#define NOT_USE_LOCK /* uncomment to disable file locking */ #ifndef NOT_USE_LOCK -# define USE_LOCK -# ifndef ONLY_LOCKFILE -# define LOCK_FOR_NFS // currently this works only for POSIX -# endif +# define USE_LOCK #endif -void WrapLines(char *str); -char *WrapLinesCopy(const char *str); -void LogError(int ErrCode,int who,const char *fname,int line,const char *fmt,...) ATT_PRINTF(5,6); -void PrintError(const char *fmt, ... ) ATT_PRINTF(1,2) ATT_NORETURN; +void LogError(int ErrCode,int who,const char *fname,int line,const char *fmt,...); +void PrintError(const char *fmt, ... ); void LogPending(void); -void PrintBoth(FILE *file,const char *fmt, ... ) ATT_PRINTF(2,3); +void PrintBoth(FILE *file,const char *fmt, ... ); -FILE *FOpenErr(const char *fname,const char *mode,int who,const char *err_fname, - int lineN) ATT_MALLOC; +FILE *FOpenErr(const char *fname,const char *mode,int who,const char *err_fname,int lineN); void FCloseErr(FILE *file,const char *fname,int who,const char *err_fname,int lineN); void RemoveErr(const char *fname,int who,const char *err_fname,int lineN); void MkDirErr(const char *dirname,int who,const char *err_fname,int lineN); -#endif // __io_h +#endif /* __io_h */ + + + + diff --git a/src/iterative.c b/src/iterative.c index 72854fb2..4ebc5324 100644 --- a/src/iterative.c +++ b/src/iterative.c @@ -1,13 +1,13 @@ /* FILE: iterative.c * AUTH: Maxim Yurkin * DESCR: Few iterative techniques to solve DDA equations - * Currently CGNR,BiCGStab,BiCG-CS,QMR-CS are implemented + * Currently CGNR,BiCGStab,BiCG-CS,QMR-CS implemented * * CGNR and BiCGStab are based on "Templates for the Solution of Linear Systems: * Building Blocks for Iterative Methods" * http://www.netlib.org/templates/Templates.html * - * BiCG-CS and QMR-CS are based on: Freund R.W. "Conjugate gradient-type methods for linear + * BiCG-CS and QMR-CS are based on: Freund,R.W. "Conjugate gradient-type methods for linear * systems with complex symmetric coefficient matrices", * SIAM Journal of Scientific Statistics and Computation, 13(1):425-448, 1992. * @@ -24,715 +24,700 @@ * non-symmetric (e.g. -int so), however they do it much slowly than usually. * It is recommended then to use BiCGStab * - * Copyright (C) 2006-2008 University of Amsterdam + * Copyright (C) 2006 M.A. Yurkin and A.G. Hoekstra * This code is covered by the GNU General Public License. */ #include -#include // for time_t & time -#include -#include +#include #include "vars.h" #include "cmplx.h" #include "const.h" #include "comm.h" +#include "debug.h" #include "linalg.h" #include "io.h" -#include "timing.h" -#include "function.h" -#include "debug.h" -// maximum allowed iterations without residual decrease +/* maximum allowed iterations without residual decrease */ #define MAXCOUNT_CGNR 10 -#define MAXCOUNT_BICGSTAB 30000 -#define MAXCOUNT_BICG_CS 50000 -#define MAXCOUNT_QMR_CS 50000 -// zero value for checks -#define EPS_BICGSTAB1 1E-16 // for (r~.r)/(r.r) -#define EPS_BICGSTAB2 1E-10 // for 1/|beta_k| -#define EPS_BICG_CS1 1E-10 // for (rT.r)/(r.r) -#define EPS_BICG_CS2 1E-10 // for (pT.A.p)/(rT.r) -#define EPS_QMR_CS1 1E-10 // for (vT.v)/(r.r) -#define EPS_QMR_CS2 1E-40 // for overflow of exponent number - -// SEMI-GLOBAL VARIABLES - -// defined and initialized in CalculateE.c -extern const TIME_TYPE tstart_CE; -// defined and initialized in calculator.c -extern doublecomplex *rvec,*vec1,*vec2,*vec3,*Avecbuffer; -// defined and initialized in param.c +#define MAXCOUNT_BICGSTAB 10000 +#define MAXCOUNT_BICG_CS 10000 +#define MAXCOUNT_QMR_CS 10000 +/* zero value for checks */ +#define EPS_BICGSTAB 1E-30 +#define EPS_BICG_CS 1E-30 +#define EPS_QMR_CS 1E-30 +#define EPS_QMR_CS_1 1E-40 /* problem can only occur if overflow of exponent number */ + +/* SEMI-GLOBAL VARIABLES */ + +/* defined and initialized in CalculateE.c */ +extern const clock_t tstart_CE; +/* defined and initialized in calculator.c */ +extern doublecomplex *xvec,*rvec,*vec1,*vec2,*vec3,*Avecbuffer; +/* defined and initialized in param.c */ extern const double eps; -// defined and initialized in timing.c -extern TIME_TYPE Timing_OneIter,Timing_InitIter,Timing_InitIter_comm; +/* defined and initialized in timing.c */ +extern clock_t Timing_OneIter,Timing_OneIterCalc,Timing_InitIter; extern unsigned long TotalIter; -// LOCAL VARIABLES - -static double inprodR; // used as r_0 (and main residual) in each method -static double epsB; // stopping criterion -static double resid_scale; // scale to get square of relative error -static double prev_err; /* previous relative error; used in ProgressReport, initialized in - * IterativeSolver - */ -static int method; // iteration method -static int count; // iteration count -static int counter; // number of successive iterations without residual decrease -static int max_count; // maximum allowed value of counter -static int chp_exit; // checkpoint occurred - exit -static int chp_skip; // skip checkpoint, even if it is time to do -typedef struct // data for checkpoints +/* LOCAL VARIABLES */ + +static double inprodR; /* uses as r_0 (and main residual) in each method */ +static double inprodR_0; /* r_0; saved and load on checkpoint */ +static double epsB; /* stopping criterion */ +static double resid_scale; /* scale to get square of relative error */ +static double prev_err; /* previous Rel.Error; used in ProgressReport, + initilized in IterativeSolver */ +static int method; /* iteration method */ +static int count; /* iteration count */ +static int counter; /* number of successive iterations without residual decrease */ +static int max_count; /* maximum allowed value of counter */ +static int chp_exit; /* checkpoint occured - exit */ +static int chp_skip; /* skip checkpoint, even if it is time to do */ +typedef struct /* data for checkpoints */ { - void *ptr; // pointer to the data - int size; // size of one element + void *ptr; /* pointer to the data */ + int size; /* size of one element */ } chp_data; -typedef struct // structure to hold information about different scalars and vectors +typedef struct /* structure to hold information about different scalars and vectors */ { - chp_data *sc; // array of scalar data - int sc_N; // number of scalars - chp_data *vec; // array of vector data - int vec_N; // number of vectors + chp_data *sc; /* array of scalar data */ + int sc_N; /* number of scalars */ + chp_data *vec; /* array of vector data */ + int vec_N; /* number of vectors */ } iter_data_type; -static iter_data_type iter_data; // actually the structure +static iter_data_type iter_data; /* actually the structure */ -// EXTERNAL FUNCTIONS +/* EXTERNAL FUNCTIONS */ -// matvec.c +/* matvec.c */ void MatVec(doublecomplex *in,doublecomplex *out,double *inprod,int her); -//============================================================ +/*============================================================*/ INLINE void SwapPointers(doublecomplex **a,doublecomplex **b) -/* swap two pointers of (doublecomplex *) type; should work for others but will give - * "Suspicious pointer conversion" warning. - */ + /* swap two pointers of (doublecomplex *) type; + should work for others but will give "Suspisious pointer conversion" warning */ { - doublecomplex *tmp; + doublecomplex *tmp; - tmp=*a; - *a=*b; - *b=tmp; + tmp=*a; + *a=*b; + *b=tmp; } -//============================================================ +/*============================================================*/ static void SaveIterChpoint(void) -/* save a binary checkpoint; only limitedly foolproof - user should take care to load checkpoints - * on the same machine (number of processors) and with the same command line. - */ + /* save a binary checkpoint; + only limitedly foolproof - user should take care to load checkpoints + on the same machine (number of processors) and with the same command line */ { - int i; - char fname[MAX_FNAME]; - FILE *chp_file; - TIME_TYPE tstart; - - tstart=GET_TIME(); - if (ringid==ROOT) { - // create directory "chp_dir" if needed and open info file - sprintf(fname,"%s/" F_CHP_LOG,chp_dir); - if ((chp_file=fopen(fname,"w"))==NULL) { - MkDirErr(chp_dir,ONE_POS); - chp_file=FOpenErr(fname,"w",ONE_POS); - } - // write info and close file - fprintf(chp_file, - "Info about the run, which produced the checkpoint, can be found in ../%s",directory); - FCloseErr(chp_file,fname,ONE_POS); - } - // wait to ensure that directory exists - Synchronize(); - // open output file; writing errors are checked only for vectors - sprintf(fname,"%s/" F_CHP,chp_dir,ringid); - chp_file=FOpenErr(fname,"wb",ALL_POS); - // write common scalars - fwrite(&method,sizeof(int),1,chp_file); - fwrite(&nlocalRows,sizeof(size_t),1,chp_file); - fwrite(&count,sizeof(int),1,chp_file); - fwrite(&counter,sizeof(int),1,chp_file); - fwrite(&inprodR,sizeof(double),1,chp_file); - fwrite(&prev_err,sizeof(double),1,chp_file); // written on ALL processors but used only on ROOT - fwrite(&resid_scale,sizeof(double),1,chp_file); - // write specific scalars - for (i=0;i0) strcpy(temp,"-+"); - else strcpy(temp,"- "); - sprintf(progr_string,"RE_%03d = %.10E %s",count,err,temp); - if (!orient_avg) { - fprintf(logfile,"%s progress = %.6f\n",progr_string,progr); - fflush(logfile); - } - printf("%s\n",progr_string); - fflush(stdout); - - prev_err=err; - } - count++; - TotalIter++; - // check condition for checkpoint; checkpoint is saved at first time - if (chp_type!=CHP_NONE && chp_time!=UNDEF && !chp_skip) { - time(&wt); - elapsed=difftime(wt,last_chp_wt); - if (chp_time0) strcpy(temp,"-+"); + else strcpy(temp,"- "); + sprintf(progr_string,"RE_%03d = %.10E %s",count,err,temp); + if (!orient_avg) { + fprintf(logfile,"%s progress = %.6f\n",progr_string,progr); + fflush(logfile); + } + printf("%s\n",progr_string); + fflush(stdout); + + prev_err=err; + } + count++; + TotalIter++; + + /* check condition for checkpoint; checkpoint is saved at first time */ + if (chp_type!=CHP_NONE && chp_time!=UNDEF && !chp_skip) { + time(&wt); + elapsed=difftime(wt,last_chp_wt); + if (chp_time=epsB && count<=maxiter && counter<=max_count && !chp_exit) { - Timing_OneIterComm=0; // initialize time - tstart=GET_TIME(); - // p_1=Ah.r_0 and ro_new=ro_0=|Ah.r_0|^2 - if (count==1) MatVec(rvec,pvec,&ro_new,TRUE); - else { - // Avecbuffer=AH.r_k-1, ro_new=ro_k-1=|AH.r_k-1|^2 - MatVec(rvec,Avecbuffer,&ro_new,TRUE); - // beta_k-1=ro_k-1/ro_k-2 - beta=ro_new/ro_old; - // p_k=beta_k-1*p_k-1+AH.r_k-1 - nIncrem10(pvec,Avecbuffer,beta,NULL,&Timing_OneIterComm); - } - // alpha_k=ro_k-1/|A.p_k|^2 - // Avecbuffer=A.p_k - MatVec(pvec,Avecbuffer,&denumeratorAlpha,FALSE); - alpha=ro_new/denumeratorAlpha; - // x_k=x_k-1+alpha_k*p_k - nIncrem01(xvec,pvec,alpha,NULL,&Timing_OneIterComm); - // r_k=r_k-1-alpha_k*A.p_k and |r_k|^2 - nIncrem01(rvec,Avecbuffer,-alpha,&inprodRplus1,&Timing_OneIterComm); - // initialize ro_old -> ro_k-2 for next iteration - ro_old=ro_new; - - Timing_OneIter=GET_TIME()-tstart; - // check progress - ProgressReport(inprodRplus1); - } // end of the big while loop - AfterIterFinished(); + double inprodRplus1; /* inner product of rk+1 */ + double alpha, denumeratorAlpha; + double beta,ro_new,ro_old=0; /* initialization to remove compiler warning */ + clock_t tstart; + chp_data scalars[1]; + + max_count=mc; + /* initialize data structure for checkpoints */ + scalars[0].ptr=&ro_old; + scalars[0].size=sizeof(double); + iter_data.sc=scalars; + iter_data.sc_N=1; + iter_data.vec=NULL; + iter_data.vec_N=0; + /* initialization of constants and vectors */ + if (load_chpoint) LoadIterChpoint(); + Timing_InitIter = clock() - tstart_CE; /* initialization complete */ + /* main iteration cycle */ + while (inprodR>=epsB && count<=maxiter && counter<=max_count && !chp_exit) { + Timing_OneIterComm=0; /* initialize time */ + tstart=clock(); + /* p_1=Ah.r_0 and ro_new=ro_0=|Ah.r_0|^2 */ + if (count==1) MatVec(rvec,pvec,&ro_new,TRUE); + else { + /* Avecbuffer=AH.r_k-1, ro_new=ro_k-1=|AH.r_k-1|^2 */ + MatVec(rvec,Avecbuffer,&ro_new,TRUE); + /* beta_k-1=ro_k-1/ro_k-2 */ + beta=ro_new/ro_old; + /* p_k=beta_k-1*p_k-1+AH.r_k-1 */ + nIncrem10(pvec,Avecbuffer,beta,NULL); + } + /* alpha_k=ro_k-1/|A.p_k|^2 */ + /* Avecbuffer=A.p_k */ + MatVec(pvec,Avecbuffer,&denumeratorAlpha,FALSE); + alpha=ro_new/denumeratorAlpha; + /* x_k=x_k-1+alpha_k*p_k */ + nIncrem01(xvec,pvec,alpha,NULL); + /* r_k=r_k-1-alpha_k*A.p_k and |r_k|^2 */ + nIncrem01(rvec,Avecbuffer,-alpha,&inprodRplus1); + /* initialize ro_old -> ro_k-2 for next iteration */ + ro_old=ro_new; + + Timing_OneIter=clock()-tstart; + /* check progress */ + ProgressReport(inprodRplus1); + } /* end of the big while loop */ + AfterIterFinished(); } -//============================================================ +/*============================================================*/ static void BiCGStab(const int mc) -// Bi-Conjugate Gradient Stabilized + /* Bi-Conjugate Gradient Stabilized */ { - double inprodRplus1; // inner product of r_k+1 - double denumOmega,dtmp; - doublecomplex beta,ro_new,ro_old,omega,alpha,temp1,temp2; - doublecomplex *v,*s,*rtilda; - TIME_TYPE tstart; - chp_data scalars[3],vectors[3]; - - max_count=mc; - // rename some vectors - v=vec1; - s=vec2; - rtilda=vec3; - // initialize data structure for checkpoints - scalars[0].ptr=&ro_old; - scalars[1].ptr=ω - scalars[2].ptr=α - scalars[0].size=scalars[1].size=scalars[2].size=sizeof(doublecomplex); - vectors[0].ptr=v; - vectors[1].ptr=s; - vectors[2].ptr=rtilda; - vectors[0].size=vectors[1].size=vectors[2].size=sizeof(doublecomplex); - iter_data.sc=scalars; - iter_data.sc_N=3; - iter_data.vec=vectors; - iter_data.vec_N=3; - // initialization of constants and vectors - if (load_chpoint) LoadIterChpoint(); - else nCopy(rtilda,rvec); // r~=r_0 - Timing_InitIter=GET_TIME()-tstart_CE; // initialization complete - // main iteration cycle - while (inprodR>=epsB && count<=maxiter && counter<=max_count && !chp_exit) { - Timing_OneIterComm = 0; // initialize time - tstart = GET_TIME(); - // ro_k-1=r_k-1.r~ ; check for ro_k-1!=0 - nDotProd(rvec,rtilda,ro_new,&Timing_OneIterComm); - dtmp=cAbs(ro_new)/inprodR; - D2z("(r~.r)/(r.r)=%.2g",dtmp); - if (dtmp ro_k-2 for next iteration - cEqual(ro_new,ro_old); - /* take time stamp here, not to measure time of incomplete iteration - * (interrupted at the check above). - */ - Timing_OneIter=GET_TIME()-tstart; - } - // check progress - ProgressReport(inprodRplus1); - } // end of the big while loop - AfterIterFinished(); + double inprodRplus1; /* inner product of rk+1 */ + double denumOmega; + doublecomplex beta,ro_new,ro_old,omega,alpha,temp1,temp2; + doublecomplex *v,*s,*rtilda; + clock_t tstart; + chp_data scalars[3],vectors[3]; + + max_count=mc; + /* rename some vectors */ + v=vec1; + s=vec2; + rtilda=vec3; + /* initialize data structure for checkpoints */ + scalars[0].ptr=&ro_old; + scalars[1].ptr=ω + scalars[2].ptr=α + scalars[0].size=scalars[1].size=scalars[2].size=sizeof(doublecomplex); + vectors[0].ptr=v; + vectors[1].ptr=s; + vectors[2].ptr=rtilda; + vectors[0].size=vectors[1].size=vectors[2].size=sizeof(doublecomplex); + iter_data.sc=scalars; + iter_data.sc_N=3; + iter_data.vec=vectors; + iter_data.vec_N=3; + /* initialization of constants and vectors */ + if (load_chpoint) LoadIterChpoint(); + else nCopy(rtilda,rvec); /* r~=r_0 */ + Timing_InitIter=clock()-tstart_CE; /* initialization complete */ + /* main iteration cycle */ + while (inprodR>=epsB && count<=maxiter && counter<=max_count && !chp_exit) { + Timing_OneIterComm = 0; /* initialize time */ + tstart = clock(); + /* ro_k-1=r_k-1.r~ ; check for ro_k-1!=0 */ + nDotProd(rvec,rtilda,ro_new); + if (sqrt(cAbs2(ro_new)) ro_k-2 for next iteration */ + memcpy(ro_old,ro_new,sizeof(doublecomplex)); + /* take time stamp here, not to measure time of incomplete iteration + (interrupted at the check above */ + Timing_OneIter=clock()-tstart; + } + /* check progress */ + ProgressReport(inprodRplus1); + } /* end of the big while loop */ + AfterIterFinished(); } -//============================================================ +/*============================================================*/ static void BiCG_CS(const int mc) -// Bi-Conjugate Gradient for Complex Symmetric systems + /* Bi-Conjugate Gradient for Complex Symmetric systems */ { - double inprodRplus1; // inner product of r_k+1 - doublecomplex alpha, mu; - doublecomplex beta,ro_new,ro_old,temp; - double dtmp,abs_ro_new; - TIME_TYPE tstart; - chp_data scalars[1]; - - max_count=mc; - // initialize data structure for checkpoints - scalars[0].ptr=&ro_old; - scalars[0].size=sizeof(doublecomplex); - iter_data.sc=scalars; - iter_data.sc_N=1; - iter_data.vec=NULL; - iter_data.vec_N=0; - // initialization of constants and vectors - if (load_chpoint) LoadIterChpoint(); - Timing_InitIter = GET_TIME() - tstart_CE; // initialization complete - // main iteration cycle - while (inprodR>=epsB && count<=maxiter && counter<=max_count && !chp_exit) { - Timing_OneIterComm=0; // initialize time - tstart=GET_TIME(); - // ro_k-1=r_k-1(*).r_k-1; check for ro_k-1!=0 - nDotProdSelf_conj(rvec,ro_new,&Timing_OneIterComm); - abs_ro_new=cAbs(ro_new); - dtmp=abs_ro_new/inprodR; - D2z("(rT.r)/(r.r)=%.2g",dtmp); - if (dtmp ro_k-2 for next iteration - cEqual(ro_new,ro_old); - Timing_OneIter=GET_TIME()-tstart; - // check progress - ProgressReport(inprodRplus1); - } // end of the big while loop - AfterIterFinished(); + double inprodRplus1; /* inner product of rk+1 */ + doublecomplex alpha, mu; + doublecomplex beta,ro_new,ro_old,temp; + clock_t tstart; + chp_data scalars[1]; + + max_count=mc; + /* initialize data structure for checkpoints */ + scalars[0].ptr=&ro_old; + scalars[0].size=sizeof(doublecomplex); + iter_data.sc=scalars; + iter_data.sc_N=1; + iter_data.vec=NULL; + iter_data.vec_N=0; + /* initialization of constants and vectors */ + if (load_chpoint) LoadIterChpoint(); + Timing_InitIter = clock() - tstart_CE; /* initialization complete */ + /* main iteration cycle */ + while (inprodR>=epsB && count<=maxiter && counter<=max_count && !chp_exit) { + Timing_OneIterComm=0; /* initialize time */ + tstart=clock(); + /* ro_k-1=r_k-1(*).r_k-1; check for ro_k-1!=0 */ + nDotProdSelf_conj(rvec,ro_new); + if (sqrt(cAbs2(ro_new)) ro_k-2 for next iteration */ + memcpy(ro_old,ro_new,sizeof(doublecomplex)); + + Timing_OneIter=clock()-tstart; + /* check progress */ + ProgressReport(inprodRplus1); + } /* end of the big while loop */ + AfterIterFinished(); } -//============================================================ +/*============================================================*/ static void QMR_CS(const int mc) -// Quasi Minimum Residual for Complex Symmetric systems + /* Quasi Minimum Residual for Complex Symmetric systems */ { - double inprodRplus1; // inner product of r_k+1 - double c_old,c_new,omega_old,omega_new,zetaabs,dtmp1,dtmp2; - doublecomplex alpha,beta,theta,eta,zeta,zetatilda,tau,tautilda; - doublecomplex s_new,s_old,temp1,temp2,temp3,temp4; - doublecomplex *v,*vtilda,*p_new,*p_old; - TIME_TYPE tstart; - chp_data scalars[8],vectors[3]; - - max_count=mc; - // rename some vectors - v=vec1; // v_k - vtilda=vec2; // also v_k-1 - p_new=pvec; // p_k - p_old=vec3; // p_k-1 - // initialize data structure for checkpoints - scalars[0].ptr=&omega_old; - scalars[1].ptr=&omega_new; - scalars[2].ptr=&c_old; - scalars[3].ptr=&c_new; - scalars[4].ptr=β - scalars[5].ptr=&tautilda; - scalars[6].ptr=&s_old; - scalars[7].ptr=&s_new; - scalars[0].size=scalars[1].size=scalars[2].size=scalars[3].size=sizeof(double); - scalars[4].size=scalars[5].size=scalars[6].size=scalars[7].size=sizeof(doublecomplex); - vectors[0].ptr=v; - vectors[1].ptr=vtilda; - vectors[2].ptr=p_old; - vectors[0].size=vectors[1].size=vectors[2].size=sizeof(doublecomplex); - iter_data.sc=scalars; - iter_data.sc_N=8; - iter_data.vec=vectors; - iter_data.vec_N=3; - // initialization of constants and vectors - if (load_chpoint) { - LoadIterChpoint(); - // change pointers names according to count parity - if (IS_EVEN(count)) SwapPointers(&v,&vtilda); - else SwapPointers(&p_old,&p_new); - } - else { - // omega_0=||v_0||=0 - omega_old=0.0; - // beta_1=sqrt(v~_1(*).v~_1); omega_1=||v~_1||/|beta_1|; (v~_1=r_0) - nDotProdSelf_conj(rvec,temp1,&Timing_InitIter_comm); - cSqrt(temp1,beta); - omega_new=sqrt(inprodR)/cAbs(beta); // inprodR=nNorm2(r_0) - // v_1=v~_1/beta_1 - cInv(beta,temp1); - nMult_cmplx(v,rvec,temp1); - // tau~_1=omega_1*beta_1 - cMultReal(omega_new,beta,tautilda); - // c_0=c_-1=1; s_0=s_-1=0 - c_new=c_old=1.0; - s_new[RE]=s_new[IM]=s_old[RE]=s_old[IM]=0.0; - } - Timing_InitIter = GET_TIME() - tstart_CE; // initialization complete - // main iteration cycle - while (inprodR>=epsB && count<=maxiter && counter<=max_count && !chp_exit) { - Timing_OneIterComm=0; // initialize time - tstart=GET_TIME(); - // check for zero beta - dtmp1=cAbs2(beta)/inprodR; - D2z("(vT.v)/(r.r)=%.2g",dtmp1); - if (dtmp1=epsB && count<=maxiter && counter<=max_count && !chp_exit) { + Timing_OneIterComm=0; /* initialize time */ + tstart=clock(); + /* check for zero beta */ + if (sqrt(cAbs2(beta))maxiter) LogError(EC_ERROR,ONE_POS, - "Iterations haven't converged in maximum allowed number of iterations (%d)",maxiter); - else if (counter>max_count) LogError(EC_ERROR,ONE_POS, - "Residual norm haven't decreased for maximum allowed number of iterations (%d)",max_count); - // post-processing - /* x is a solution of a modified system, not exactly internal field; should not be used further - * except for adaptive technique (as starting vector for next system) - */ - nMult_mat(pvec,xvec,cc_sqrt); /* p is now vector of polarizations. Can be used to calculate - * e.g. scattered field faster. - */ - if (chp_exit) return CHP_EXIT; // check if exiting after checkpoint - return count; + double temp; + char tmp_str[MAX_LINE]; + + method=method_in; + chp_exit=FALSE; + chp_skip=FALSE; + /* instead of solving system (I+D.C).x=b , C - diagonal matrix with couple constants + * D - symmetric interaction matrix of Green's tensor + * we solve system (I+S.D.S).(S.x)=(S.b), S=sqrt(C), them + * total interaction matrix is symmetric and Jacobi-preconditioned for any discribution of m */ + + /* p=b=(S.Einc) is right part of the linear system; used only here, + in iteration methods themselves p is completely different vector */ + if (!load_chpoint) { + nMult_mat(pvec,Einc,cc_sqrt); + + temp=nNorm2(pvec); /* |r_0|^2 when x_0=0 */ + resid_scale=1/temp; + /* calculate A.(x_0=b), r_0=b-A.(x_0=b) and |r_0|^2 */ + MatVec(pvec,Avecbuffer,NULL,FALSE); + nSubtr(rvec,pvec,Avecbuffer,&inprodR); + /* check which x_0 is better */ + if (tempmaxiter) LogError(EC_ERROR,ONE_POS, + "Iterations haven't converged in maximum allowed number of iterations (%d)",maxiter); + else if (counter>max_count) LogError(EC_ERROR,ONE_POS, + "Residual norm haven't decreased for maximum allowed number of iterations (%d)",max_count); + /* postprocessing */ + /* x is a solution of a modified system, not exactly internal field + should not be used further except fot adaptive technique + (as starting vector for next system) */ + nMult_mat(pvec,xvec,cc_sqrt); /* p is now vector of polarizations - */ + /* faster to calculate ,e.g. scattered field */ + /* check if exiting after checkpoint */ + if (chp_exit) return CHP_EXIT; + return count; } diff --git a/src/linalg.c b/src/linalg.c index 04a51eeb..09bd2bd9 100644 --- a/src/linalg.c +++ b/src/linalg.c @@ -8,501 +8,479 @@ * to be a principal limitation of C standard (some compilers may work, some produce * warnings) * - * Copyright (C) 2006-2008 University of Amsterdam + * Copyright (C) 2006 M.A. Yurkin and A.G. Hoekstra * This code is covered by the GNU General Public License. */ -#include +#include #include "vars.h" -#include "types.h" +#include "cmplx.h" #include "comm.h" #include "linalg.h" -//============================================================ +/*============================================================*/ void nInit(doublecomplex *a) -// initialize vector a with null values + /* initialize vector a with null values */ { - size_t i; -#pragma loop count (100000) -#pragma ivdep - for (i=0;i $(LASTMPI) -# Dependencies are only generated for C sources; -# we assume that each Fortran file is completely independent - -$(CDEPEND): %.d: %.c $(MFILES) - $(MPICC) $(DEPFLAG) $(CFLAGS) $< $(DFFLAG) $@.$$$$; \ - sed 's,\($*\)\.o[ :]*,\1.o $@ : ,g' < $@.$$$$ > $@; \ - rm -f $@.$$$$ +%.d: %.c + $(SHELL) -ec '$(CC) -M $(CFLAGS) $< \ + | sed '\''s/\($*\)\.o[ :]*/\1.o $@ : /g'\'' > $@; \ + [ -s $@ ] || rm -f $@' -include $(CDEPEND) +include $(CSOURCE:.c=.d) diff --git a/src/make_particle.c b/src/make_particle.c index e49c387a..5110a196 100644 --- a/src/make_particle.c +++ b/src/make_particle.c @@ -1,35 +1,27 @@ /* FILE: make_particlce.c * AUTH: Alfons Hoekstra - * DESCR: This module initializes the dipole set, either using predefined shapes - * or reading from a file. Includes granule generator. + * DESCR: This module initializes the dipole set, either using predefined shapes + * or reding from a file. * * rewriten, * Michel Grimminck 1995 * ----------------------------------------------------------- * included ellipsoidal particle for work with Victor Babenko * september 2002 - * ----------------------------------------------------------- + * -------------------------------------------------------- * included many more new particles: * leucocyte, stick, rotatable oblate spheroid, lymphocyte, * rotatable RBC, etc etc etc * December 2003 - February 2004, by Konstantin Semyanov * (not used now) - * ----------------------------------------------------------- - * Shapes 'capsule' and 'egg' are implemented by Daniel Hahn and Richard Joseph. - * ----------------------------------------------------------- - * Shape 'axisymmetric' is based on the code by Konstantin Gilev * * Currently is developed by Maxim Yurkin * - * Copyright (C) 2006-2008 University of Amsterdam + * Copyright (C) 2006 M.A. Yurkin and A.G. Hoekstra * This code is covered by the GNU General Public License. */ #include -#include -#include -#include // for time and clock (used for random seed) -#include -#include +#include #include "vars.h" #include "const.h" #include "cmplx.h" @@ -39,1831 +31,585 @@ #include "memory.h" #include "io.h" #include "param.h" -#include "timing.h" -#include "mt19937ar.h" -// SEMI-GLOBAL VARIABLES +/* SEMI-GLOBAL VARIABLES */ -// defined and initialized in param.c +/* defined and initialized in param.c */ extern const int shape,sh_Npars; extern const double sh_pars[]; -extern const int sym_type; +extern const int NoSymmetry,symmetry_enforced; extern const double lambda; -extern double sizeX,dpl,a_eq; +extern double sizeX,dpl; extern const int jagged; -extern const char shape_fname[]; -extern char shapename[]; +extern const char aggregate_file[],shapename[]; extern char save_geom_fname[]; extern const int volcor,save_geom; extern opt_index opt_sh; -extern const double gr_vf; -extern double gr_d; -extern const int gr_mat; -extern int sg_format; -extern int store_grans; -// defined and initialized in timing.c -extern TIME_TYPE Timing_Particle,Timing_Granul,Timing_Granul_comm; +/* defined and initialized in timing.c */ +extern clock_t Timing_Particle; -// used in param.c -int volcor_used; // volume correction was actually employed -char sh_form_str[MAX_PARAGRAPH]; // string for log file with shape parameters -size_t gr_N; // number of granules -double gr_vf_real; // actual granules volume fraction -double mat_count[MAX_NMAT+1]; // number of dipoles in each domain +/* used in param.c */ +int volcor_used; /* volume correction was actually employed */ +char sh_form_str[MAX_PARAGRAPH]; /* string for log file with shape parameters */ -// LOCAL VARIABLES +/* LOCAL VARIABLES */ -static const char geom_format[]="%d %d %d\n"; // format of the geom file -static const char geom_format_ext[]="%d %d %d %d\n"; // extended format of the geom file -/* C99 allows use of %zu for size_t variables, but this is not supported by MinGW due to dependence - * on Microsoft libraries - */ -static const char ddscat_format[]="%ld %d %d %d %d %d %d\n";// DDSCAT shape format (FRMFIL) -// ratio of scatterer volume to enclosing cube; used for dpl correction and initialization by a_eq -static double volume_ratio; -static double Ndip; // total number of dipoles (in a circumscribing cube) -static double dpl_def; // default value of dpl -static int minX,minY,minZ; // minimum values of dipole positions in dipole file -static FILE *dipfile; // handle of dipole file -static int read_format; // format of dipole file, which is read -static char linebuf[BUF_LINE]; // buffer for reading lines from dipole file -double cX,cY,cZ; // center for DipoleCoord, it is sometimes used in PlaceGranules -// shape parameters +static char geom_format[] = "%d %d %d\n"; /* format of the geom file */ +static char geom_format_ext[] = "%d %d %d %d\n"; /* extended format of the geom file */ +static double volume_ratio; /* ratio of scatterer volume to enclosing cube; + used for dpl correction */ +static int Ndip; /* total number of dipoles (in a circumscribing cube) */ +/* shape parameters */ static double coat_ratio,coat_x,coat_y,coat_z,coat_r2; -static double ad2,egnu,egeps,egz0; // for egg -static double hdratio,invsqY,invsqZ,haspY,haspZ; -static double P,Q,R,S; // for RBC -// for axisymmetric; all coordinates defined here are relative -static double *contSegRoMin,*contSegRoMax,*contRo,*contZ; -static double contCurRo, contCurZ, contRoSqMin; -static int contNseg; -struct segment { - bool single; // whether segment consists of a single joint - int first; // index of the first point in the segment - int last; // index of the last point in the segment - double zmin; // minimum z-coordinate of the segment points - double zmax; // maximum z-coordinate of the segment points - double romid; // ro-coordinate of the point in the middle - struct segment *left; // pointer to left subsegment - struct segment *right; // pointer to right subsegment - double slope; // only for single; (z[i+1]-z[i])/(ro[i+1]-ro[i]) - double add; // only for single; ro[i](1-slope); -}; -struct segment *contSeg; -/* TO ADD NEW SHAPE - * Add here all internal variables (aspect ratios, etc.), which you initialize in InitShape() - * and use in MakeParticle() afterwards. If you need local, intermediate variables, put them into - * the beginning of the corresponding function. - * Add descriptive comments, use 'static'. - */ - -// temporary arrays before their real counterparts are allocated -static unsigned char *material_tmp; +static double diskratio,ellipsY,ellipsZ; +static double P,Q,R,S; /* for RBC */ +/* temporary arrays before their real counterparts are allocated */ +static char *material_tmp; static double *DipoleCoord_tmp; -static unsigned short *position_tmp; +static short int *position_tmp; -//============================================================ +/*============================================================*/ static void SaveGeometry(void) -// saves dipole configuration to .geom file + /* saves dipole configuration to .geom file */ { - char fname[MAX_FNAME]; - FILE *geom; - size_t i,j; - int mat; - - // create save_geom_fname if not specified - if (save_geom_fname[0]==0) sprintf(save_geom_fname,"%s.geom",shapename); - // automatically change format if needed - if (sg_format==SF_TEXT && Nmat>1) sg_format=SF_TEXT_EXT; - // choose filename + char fname[MAX_FNAME]; + FILE *geom; + int i,j,buf_size; + + /* create save_geom_fname if not specified */ + if (save_geom_fname[0]==0) + sprintf(save_geom_fname,"%s.geom",shapename); + /* choose filename */ #ifdef PARALLEL - sprintf(fname,"%s/" F_GEOM_TMP,directory,ringid); + sprintf(fname,"%s/" F_GEOM_TMP,directory,ringid); #else - sprintf(fname,"%s/%s",directory,save_geom_fname); + sprintf(fname,"%s/%s",directory,save_geom_fname); #endif - geom=FOpenErr(fname,"w",ALL_POS); - // print head of file + geom=FOpenErr(fname,"w",ALL_POS); + /* print head of file */ #ifdef PARALLEL - if (ringid==0) { // this condition can be different from being ROOT + if (ringid==0) { /* this condition can be different from being ROOT */ #endif - if (sg_format==SF_TEXT || sg_format==SF_TEXT_EXT) { - fprintf(geom,"#generated by ADDA v." ADDA_VERSION "\n" - "#shape: '%s'\n" - "#box size: %dx%dx%d\n",shapename,boxX,boxY,boxZ); - if (sg_format==SF_TEXT_EXT) fprintf(geom,"Nmat=%d\n",Nmat); - } - else if (sg_format==SF_DDSCAT) - fprintf(geom,"shape: '%s'; box size: %dx%dx%d; generated by ADDA v." ADDA_VERSION "\n" - "%0.f = NAT\n" - "1 0 0 = A_1 vector\n" - "0 1 0 = A_2 vector\n" - "1 1 1 = lattice spacings (d_x,d_y,d_z)/d\n" - "JA IX IY IZ ICOMP(x,y,z)\n",shapename,boxX,boxY,boxZ,nvoid_Ndip); + fprintf(geom,"#generated by ADDA v." ADDA_VERSION "\n"\ + "#shape: '%s'\n"\ + "#box size: %dx%dx%d\n", + shapename,boxX,boxY,boxZ); + if (Nmat>1) fprintf(geom,"Nmat=%d\n",Nmat); #ifdef PARALLEL - } // end of if + } /* end of if */ #endif - // save geometry - if (sg_format==SF_TEXT) for(i=0;i1) for(i=0;i %d)", - fname,*line,BUF_LINE-1); - } - return res; -} - -//=========================================================== - -INLINE void SkipNLines(FILE *file,int n) -// skips n lines from the file starting from current position in a file -{ - while (n>0) { - SkipFullLine(file); - n--; - } -} - -//=========================================================== +/*===========================================================*/ static int SkipComments(FILE *file) -/* skips comments (#...), all lines, starting from current position in a file. - * returns number of lines skipped - */ + /* skips comments (#...), all lines, starting from current position in a file + returns number of lines skipped */ { - int lines=0,ch; + int lines=0; + char buf[BUF_LINE]; - while ((ch=fgetc(file))=='#') { - SkipFullLine(file); - lines++; - } - if (ch!=EOF) ungetc(ch,file); + while (fgetc(file)=='#') { + do fgets(buf,BUF_LINE,file); while (strstr(buf,"\n")==NULL); + lines++; + } + fseek(file,-1,SEEK_CUR); - return lines; + return lines; } -//=========================================================== -#define DDSCAT_HL 6 // number of header lines in DDSCAT format +/*===========================================================*/ -static void InitDipFile(const char *fname,int *bX,int *bY,int *bZ,int *Nm) -/* read dipole file first to determine box sizes and Nmat; input is not checked for very large - * numbers (integer overflows) to increase speed; this function opens file for reading, the file is - * closed in ReadDipFile. - */ +static void InitDipFile(const char *fname, int *maxX, int *maxY, int *maxZ, int *Nm) + /* read dipole file first to determine box sizes and Nmat */ { - int x,y,z,mat,line,scanned,mustbe,skiplines,anis_warned; - long tl; // dumb variable - int t2,t3; // dumb variables - int maxX,maxY,maxZ,maxN; - char formtext[MAX_LINE]; - - dipfile=FOpenErr(fname,"r",ALL_POS); - read_format=UNDEF; - /* test for DDSCAT format; in not-DDSCAT format, the line scanned below may be a long comment; - * therefore we first skip all comments - */ - line=SkipComments(dipfile); - if (line<=DDSCAT_HL) { - SkipNLines(dipfile,DDSCAT_HL-line); - if (FgetsError(dipfile,fname,&line,POSIT)!=NULL - && sscanf(linebuf,ddscat_format,&tl,&x,&y,&z,&mat,&t2,&t3)==7) { - read_format=SF_DDSCAT; - strcpy(formtext,"DDSCAT format (FRMFIL)"); - mustbe=7; - line=DDSCAT_HL; - fseek(dipfile,0,SEEK_SET); - SkipNLines(dipfile,line); - } - } - // if format is not yet determined, test for ADDA text formats - if (read_format==UNDEF) { - fseek(dipfile,0,SEEK_SET); - line=SkipComments(dipfile); - /* scanf and analyze Nmat; if there is blank line between comments and Nmat, it fails later; - * the value of Nmat obtained here is not actually relevant, the main factor is maximum - * domain number among all dipoles. - */ - scanned=fscanf(dipfile,"Nmat=%d\n",Nm); - if (scanned==EOF) LogError(EC_ERROR,ONE_POS,"No dipole positions are found in %s",fname); - else if (scanned==0) { // no "Nmat=..." - read_format=SF_TEXT; - strcpy(formtext,"ADDA text format (single domain)"); - *Nm=1; - mustbe=3; - } - else { // "Nmat=..." present - read_format=SF_TEXT_EXT; - strcpy(formtext,"ADDA text format (multi-domain)"); - mustbe=4; - line++; - } - } - // scan main part of the file - skiplines=line; - maxX=maxY=maxZ=INT_MIN; - minX=minY=minZ=INT_MAX; - maxN=1; - anis_warned=FALSE; - // reading is performed in lines - while(FgetsError(dipfile,fname,&line,POSIT)!=NULL) { - // scan numbers in a line - if (read_format==SF_TEXT) scanned=sscanf(linebuf,geom_format,&x,&y,&z); - else if (read_format==SF_TEXT_EXT) scanned=sscanf(linebuf,geom_format_ext,&x,&y,&z,&mat); - // for ddscat format, only first material is used, other two are ignored - else if (read_format==SF_DDSCAT) { - scanned=sscanf(linebuf,ddscat_format,&tl,&x,&y,&z,&mat,&t2,&t3); - if (!anis_warned && (t2!=mat || t3!=mat)) { - LogError(EC_WARN,ONE_POS,"Anisotropic dipoles are detected in file %s (first on " - "line %d). ADDA ignores this anisotropy, using only the identifier of " - "x-component of refractive index as domain number",fname,line); - anis_warned=TRUE; - } - } - // if sscanf returns EOF, that is a blank line -> just skip - if (scanned!=EOF) { - if (scanned!=mustbe) // this in most cases indicates wrong format - LogError(EC_ERROR,ONE_POS,"%s was detected, but error occurred during scanning " - "of line %d from dipole file %s",formtext,line,fname); - if (read_format!=SF_TEXT) { - if (mat<=0) LogError(EC_ERROR,ONE_POS,"%s was detected, but nonpositive material " - "number (%d) encountered during scanning of line %d from dipole file %s", - formtext,mat,line,fname); - else if (mat>maxN) maxN=mat; - } - // update maxima and minima - if (x>maxX) maxX=x; - if (xmaxY) maxY=y; - if (ymaxZ) maxZ=z; - if (z just skip - if (scanned!=EOF) { - // shift dipole position to be nonnegative - x0-=minX; - y0-=minY; - z0-=minZ; - // initialize box jagged*jagged*jagged instead of one dipole - for (z=jagged*z0;z=local_z0 && zfirst]==contRo[seg->first+1]) (seg->first)++; - while (contRo[seg->last-1]==contRo[seg->last]) (seg->last)--; - if (seg->first+1 == seg->last) { // segment with a single fragment - seg->single=true; - seg->zmin=MIN(contZ[seg->first],contZ[seg->last]); - seg->zmax=MAX(contZ[seg->first],contZ[seg->last]); - seg->slope=(contZ[seg->last]-contZ[seg->first])/(contRo[seg->last]-contRo[seg->first]); - seg->add=contZ[seg->first]-contRo[seg->first]*seg->slope; - } - else { // divide segment into two, and initialize each of them - seg->single=false; - i=(seg->first+seg->last)/2; - seg->romid=contRo[i]; - // construct subsegments - s1=ALLOCATE_SEGMENTS(1); - s2=ALLOCATE_SEGMENTS(1); - s1->first=seg->first; - s1->last=s2->first=i; - s2->last=seg->last; - // initialize subsegments - InitContourSegment(s1,increasing); - InitContourSegment(s2,increasing); - // calculate zmax and zmin - seg->zmax=MAX(s1->zmax,s2->zmax); - seg->zmin=MIN(s1->zmin,s2->zmin); - // assign new segments to left and right based on 'increasing' - if (increasing) { - seg->left=s1; - seg->right=s2; - } - else { - seg->left=s2; - seg->right=s1; - } - } + FILE *input; + int x, y, z, ext=FALSE, cond, mat, line=0; + char buf[BUF_LINE]; + + input=FOpenErr(fname,"r",ALL_POS); + + line=SkipComments(input)+1; + /* read Nmat if present */ + if (fscanf(input,"Nmat=%d\n",Nm)!=1) *Nm=1; + else { + ext=TRUE; + if (*Nm<=0) LogError(EC_ERROR,ONE_POS,"Nmat is nonpositive, as given in %s",fname); + if (*Nm==1) LogError(EC_INFO,ONE_POS, + "Nmat is given in dipole file - %s, but is trivial (=1)",fname); + line++; + } + /* scan main part of the file */ + *maxX=*maxY=*maxZ=0; + /* reading is performed in lines */ + while(fgets(buf,BUF_LINE,input)!=NULL) { + if (strstr(buf,"\n")==NULL) LogError(EC_ERROR,ONE_POS, + "Buffer overflow while scanning lines in file '%s' (size of line %d > %d)", + fname,line,BUF_LINE-1); + if (ext) cond=(sscanf(buf,geom_format_ext,&x,&y,&z,&mat)!=4); + else cond=(sscanf(buf,geom_format,&x,&y,&z)!=3); + if (cond) + LogError(EC_ERROR,ONE_POS,"Could not scan from dipole file - %s - line %d",fname,line); + /* check for errors in values */ + if (x<0) + LogError(EC_ERROR,ONE_POS,"Negative coordinate - %s - line %d: x=%d",fname,line,x); + if (y<0) + LogError(EC_ERROR,ONE_POS,"Negative coordinate - %s - line %d: y=%d",fname,line,y); + if (z<0) + LogError(EC_ERROR,ONE_POS,"Negative coordinate - %s - line %d: z=%d",fname,line,z); + if (ext) if (mat>*Nm) LogError(EC_ERROR,ONE_POS, + "Given material number - %s - line %d: mat=%d is greater than provided Nmat (%d)", + fname,line,mat,*Nm); + /* update maximums */ + if (x>*maxX) *maxX=x; + if (y>*maxY) *maxY=y; + if (z>*maxZ) *maxZ=z; + line++; + } + *maxX=jagged*(*maxX+1); + *maxY=jagged*(*maxY+1); + *maxZ=jagged*(*maxZ+1); + FCloseErr(input,fname,ALL_POS); } -//=========================================================== -#define CHUNK_SIZE 128 // how many numbers are allocated at once for adjustable arrays - -static void InitContour(const char *fname,double *ratio,double *shSize) -/* Reads a contour from the file, rotates it so that it starts from a local minimum in ro, - * then divides it into monotonic (over ro) segments. It produces data, which are later used to - * test each dipole for being inside the contour. Segments are either increasing or non-decreasing. - */ -{ - int line; // current line number - int nr; // number of contour points read from the file - int size; // current size of the allocated memory for contour - int i,j,scanned; - double *bufRo,*bufZ; // temporary buffers - int *index; - double ro,z,romin,romax,zmin,zmax,mult,zmid; - FILE* file; - bool increasing; +/*===========================================================*/ - D("InitContour has started"); - // Read contour from file - file=FOpenErr(fname,"r",ALL_POS); - line=SkipComments(file); - size=CHUNK_SIZE; - MALLOC_VECTOR(bufRo,double,size,ALL); - MALLOC_VECTOR(bufZ,double,size,ALL); - nr=0; - // reading is performed in lines - while(FgetsError(file,fname,&line,POSIT)!=NULL) { - // scan numbers in a line - scanned=sscanf(linebuf,"%lf %lf",&ro,&z); - // if sscanf returns EOF, that is a blank line -> just skip - if (scanned!=EOF) { - if (scanned!=2) // this in most cases indicates wrong format - LogError(EC_ERROR,ONE_POS,"Error occurred during scanning of line %d from contour " - "file %s",line,fname); - // check for consistency of input - if (ro<0) LogError(EC_ERROR,ONE_POS,"Negative ro-coordinate is found on line %d in " - "contour file %s",line,fname); - // update extreme values - if (nr==0) { - zmax=zmin=z; - romax=romin=ro; - } - else { - if (z>zmax) zmax=z; - if (zromax) romax=ro; - if (ro= size) { - size+=CHUNK_SIZE; - REALLOC_DVECTOR(bufRo,size,ALL); - REALLOC_DVECTOR(bufZ,size,ALL); - } - bufRo[nr]=ro; - bufZ[nr]=z; - nr++; - } - } - FCloseErr(file,fname,ALL_POS); - // Check number of points read - if (nr<3) LogError(EC_ERROR,ONE_POS, - "Contour from file %s contains less than three points",fname); - - // Determine initial point with local minimum ro[i-1]>=ro[i]=bufRo[i+1]) i++; - if (i==0) { // first point is a minimum candidate - if (bufRo[0]>bufRo[nr-1]) { // if required, search backwards; guaranteed to converge - i=nr-1; - while (bufRo[i]>bufRo[i-1]) i--; - } - } - // if the whole contour is non-decreasing, check for constancy - else if (i==nr-1 && bufRo[nr-1]==bufRo[0]) LogError(EC_ERROR,ONE_POS, - "Contour from file %s has zero area. Hence the scatterer is void",fname); - /* Construct working contour so that its first point = last and is a local minimum. It is done - * by rotating buf and adding one extra point. Then free the buffer. - */ - MALLOC_VECTOR(contRo,double,nr+1,ALL); - memcpy(contRo,bufRo+i,(nr-i)*sizeof(double)); - memcpy(contRo+nr-i,bufRo,i*sizeof(double)); - contRo[nr]=contRo[0]; - Free_general(bufRo); - // same for Z vectors - MALLOC_VECTOR(contZ,double,nr+1,ALL); - memcpy(contZ,bufZ+i,(nr-i)*sizeof(double)); - memcpy(contZ+nr-i,bufZ,i*sizeof(double)); - contZ[nr]=contZ[0]; - Free_general(bufZ); - // scale coordinates to be relative to total diameter, and centered (by z) around 0 - mult=1/(2*romax); - zmid=(zmax+zmin)/2; - *ratio=(zmax-zmin)*mult; - *shSize=2*romax; - contRoSqMin=romin*romin*mult*mult; - for (i=0;i<=nr;i++) { - contRo[i]*=mult; - contZ[i]=(contZ[i]-zmid)*mult; - } - - /* divide the contour into the segments; actually only the index is constructed marking end - * points of the segments - */ - MALLOC_VECTOR(index,int,nr+1,ALL); // this is enough, even if all segments are of one joint - index[0]=0; - i=j=1; - increasing=true; - while (izmin) return true; - else if (contCurZ > seg->zmax) return false; - else if (seg->single) return (contCurZ < seg->add + contCurRo*seg->slope); - else seg=(contCurRoromid ? seg->left : seg->right); - } -} - -//========================================================== - -void FreeContourSegment(struct segment *seg) -/* recursively frees memory allocated for contour segments - * Recursive function calls incurs certain overhead, however here it is not critical. - */ -{ - if (!(seg->single)) { - FreeContourSegment(seg->left); - FreeContourSegment(seg->right); - } -} - -//========================================================== - -#define KEY_LENGTH 2 // length of key for initialization of random generator -#define MAX_ZERO_FITS 1E4 // maximum number of zero fits in a row (each - many granules) -#define MAX_FALSE_SKIP 10 // number of false skips in granule placement to complete the set -#define MAX_FALSE_SKIP_SMALL 10 // the same for small granules -#define MAX_GR_SET USHRT_MAX // maximum size of granule set -#define MIN_CELL_SIZE 4.0 // minimum cell size for small granules - -INLINE int CheckCell(const double *gr,const double *vgran,const unsigned short *tree_index, - const double Di2,const int start,int *fits) -// function that checks whether granule intersects anything in the cell +static void ReadDipFile(const char *fname) + /* read dipole file; + no consistency checks are made since they are made in InitDipFile */ { - int index,last,index1; - double t1,t2,t3; - - last=index=start; - while (index!=MAX_GR_SET && (*fits)) { - last=index; - index1=3*index; - t1=gr[0]-vgran[index1]; - t2=gr[1]-vgran[index1+1]; - t3=gr[2]-vgran[index1+2]; - if ((t1*t1+t2*t2+t3*t3)=local_z0 && zMIN(boxX,MIN(boxY,boxZ))) LogError(EC_WARN,ONE_POS, - "Granule size is larger than minimum particle dimension"); - x0=R-0.5; - x1=boxX-R-0.5; - y0=R-0.5; - y1=boxY-R-0.5; - z0=R-0.5; - z1=boxZ-R-0.5; - // initialize auxiliary grid - CheckOverflow(MAX(boxX,MAX(boxY,boxZ))*10/Di,ONE_POS,"PlaceGranules()"); - tmp1=sqrt(3)/Di; - gX=(int)ceil((x1-x0)*tmp1); - gdX=(x1-x0)/gX; - gY=(int)ceil((y1-y0)*tmp1); - gdY=(y1-y0)/gY; - gZ=(int)ceil((z1-z0)*tmp1); - gdZ=(z1-z0)/gZ; - sm_gr=(gdX<2 || gdY<2 || gdZ<2); // sets the discrimination for small or large granules - if (sm_gr) { - PRINTZ("Using algorithm for small granules\n"); - // redefine auxiliary grid - tmp1=1/MAX(2*Di,MIN_CELL_SIZE); - gX=(int)floor((x1-x0)*tmp1); - gdX=(x1-x0)/gX; - gY=(int)floor((y1-y0)*tmp1); - gdY=(y1-y0)/gY; - gZ=(int)floor((z1-z0)*tmp1); - gdZ=(z1-z0)/gZ; - } - else { - PRINTZ("Using algorithm for large granules\n"); - gX2=2*gX; - gdXh=gdX/2; - gY2=2*gY; - gdYh=gdY/2; - gZ2=2*gZ; - gdZh=gdZ/2; - /* this sets maximum distance of neighboring cells to check; condition gdX3 can only occur if - * gX<=2 and then it doesn't make sense to take bigger sx. Absolutely analogous for y, z. - */ - if (gdX=ginZ[1]) indZ++; - kd1=MIN(ginZ[locgZ2],local_z1_coer); - } - n=count=count_gr=false_count=0; - nd=0; - // crude estimate of the probability to place a small granule into domain - if (sm_gr) overhead=Ndip/mat_count[gr_mat]; - else overhead=1; - // main cycle - while (nMAX_FALSE_SKIP_SMALL) break; - } - // real number of placed granules for this set - cur_Ngr=ig; - } - } - else { // large granules - // generate domain pattern - if (locgZ!=0) { - for (i=0;itmp1) cur_Ngr=(int)ceil(tmp1); - // generate points and quick check - ig=false_count=0; - for (ui=0;uigZ) i1=gX; - if ((j0=indY-sy)<0) j0=0; - if ((j1=indY+sy+1)>gY) j1=gY; - if ((k0=indZ-sz)<0) k0=0; - if ((k1=indZ+sz+1)>gZ) k1=gZ; - dom_index2=k0*gXY; - for (k=k0;kMAX_FALSE_SKIP) break; - } - } - // real number of placed granules for this set - cur_Ngr=ig; - } - } // end of large granules - // cast to all processors - MyBcast(&cur_Ngr,int_type,1,&Timing_Granul_comm); - MyBcast(vgran,double_type,3*cur_Ngr,&Timing_Granul_comm); - count_gr+=cur_Ngr; - // final check if granules belong to the domain - for (ig=0;ig=gr_N) break; - } - } - // save correct granule positions to file - if (store_grans && ringid==ROOT) for (ig=0;igMAX_ZERO_FITS) { - MyInnerProduct(&nd,double_type,1,&Timing_Granul_comm); - LogError(EC_ERROR,ONE_POS,"The granule generator failed to reach required volume " - "fraction (%g) of granules. %zu granules were successfully placed up to a " - "volume fraction of %g.",gr_vf,n,nd/mat_count[gr_mat]); - } - } - } - /* conversions to (unsigned long) are needed (to remove warnings) because %z printf argument is - * not yet supported by all target compiler environments - */ - PRINTZ("Granule generator: total random placements= %lu (efficiency 1 = %g)\n" - " possible granules= %lu (efficiency 2 = %g)\n", - (unsigned long)count,count_gr/(double)count,(unsigned long)count_gr, - gr_N/(double)count_gr); - MyInnerProduct(&nd,double_type,1,&Timing_Granul_comm); - // free everything - if (ringid==ROOT) { - Free_general(occup); - if (sm_gr) Free_general(tree_index); - else Free_general(dom); - } - else if (!sm_gr && locgZ!=0) Free_general(dom); - FreeGranulComm(sm_gr); - Free_general(vgran); - Free_general(vfit); - if (!sm_gr && locgZ!=0) { - Free_general(ginX); - Free_general(ginY); - Free_general(ginZ); - } - // close granule file if needed and print info - if (store_grans && ringid==ROOT) { - FCloseErr(file,fname,ONE_POS); - printf("Granule coordinates saved to file\n"); - } - return nd; -} -#undef KEY_LENGTH -#undef MAX_ZERO_FITS -#undef MAX_FALSE_SKIP -#undef MAX_FALSE_SKIP_SMALL -#undef MAX_GR_SET -#undef MIN_CELL_SIZE -//========================================================== +/*==========================================================*/ static int FitBox(const int box) -/* finds the smallest value for which program would work (should be even and divide jagged); - * the limit is also checked - */ + /* finds the smallest value for which program would work + (should be even and divide jagged) */ { - int res; - - if (IS_EVEN(jagged)) res=jagged*((box+jagged-1)/jagged); - else res=2*jagged*((box+2*jagged-1)/(2*jagged)); - if (res>BOX_MAX) LogError(EC_ERROR,ONE_POS, - "Derived grid size (%d) is too large (>%d)",res,BOX_MAX); - return res; + if (jagged%2==0) return (jagged*((box+jagged-1)/jagged)); + else return (2*jagged*((box+2*jagged-1)/(2*jagged))); } -//========================================================== +/*==========================================================*/ void InitShape(void) -/* perform of initialization of symmetries and boxY, boxZ. Estimate the volume of the particle, when - * not discretized. Check whether enough refractive indices are specified. - */ + /* perform of initialization of symmetries and boxY, boxZ + * Estimate the volume of the particle, when not discretisized. + * Check whether enough refractive indices are specified + */ { - int n_boxX,n_boxY,n_boxZ; // new values for dimensions - double n_sizeX; // new value for size - double h_d,b_d,c_d,h2,b2,c2; - double yx_ratio,zx_ratio,tmp1,tmp2,tmp3; - double diskratio,aspectY,aspectZ; - double ad,ct,ct2; // cos(theta0) and its square - TIME_TYPE tstart; - int Nmat_need,i,temp; - int dpl_def_used; // if default dpl is used for grid initialization - bool box_det_sh; // if boxX is determined by shape itself - bool size_det_sh; // if size is determined by shape itself - bool size_given_cmd; // if size is given in the command line - char sizename[MAX_LINE]; // type of input size, used in diagnostic messages - /* TO ADD NEW SHAPE - * Add here all intermediate variables, which are used only inside this function. You may as - * well use 'tmp1'-'tmp3' variables defined above. - */ - - tstart=GET_TIME(); - - box_det_sh=(shape==SH_READ); - size_det_sh=(shape==SH_AXISYMMETRIC); - /* TO ADD NEW SHAPE - * If new shape defines dimension of the computational grid or absolute size of the particle, - * change corresponding definition in one of two lines above. In many cases this is not - * relevant. - */ - - size_given_cmd=(sizeX!=UNDEF || a_eq!=UNDEF); - if (sizeX!=UNDEF) strcpy(sizename,"size"); - else if (a_eq!=UNDEF) strcpy(sizename,"eq_rad"); - // check for redundancy of input data - if (dpl!=UNDEF) { - if (size_given_cmd) { - if (boxX!=UNDEF) PrintError("Extra information is given by setting '-dpl', '-grid', " - "and '-%s'",sizename); - else if (box_det_sh) PrintError("Extra information is given by setting both '-dpl' and " - "'-%s', while shape '%s' sets the size of the grid",sizename,shapename); - } - else if (size_det_sh) { - if (boxX!=UNDEF) PrintError("Extra information is given by setting '-dpl' and '-grid', " - "while shape '%s' sets the particle size",shapename); - // currently this can't happen, but may become relevant in the future - else if (box_det_sh) PrintError("Extra information is given by setting '-dpl', while " - "shape '%s' sets both the particle size and the size of the grid",shapename); - } - } - /* calculate default dpl - 10*sqrt(max(|m|)); - * for anisotropic each component is considered separately - */ - tmp2=0; - for (i=0;i0.25*(1-coat_ratio)*(1-coat_ratio)) - PrintErrorHelp("Inner sphere is not fully inside the outer"); - SPRINTZ(sh_form_str+strlen(sh_form_str), - "\n position of inner sphere center r/d= {%.10g,%.10g,%.10g}", - coat_x,coat_y,coat_z); - } - else coat_x=coat_y=coat_z=0; // initialize default values - coat_r2=0.25*coat_ratio*coat_ratio; - volume_ratio=PI_OVER_SIX; - if (coat_x!=0) symX=symR=FALSE; - if (coat_y!=0) symY=symR=FALSE; - if (coat_z!=0) symZ=FALSE; - yx_ratio=zx_ratio=1; - Nmat_need=2; - } - else if(shape==SH_CYLINDER) { - diskratio=sh_pars[0]; - TestPositive(diskratio,"height to diameter ratio"); - SPRINTZ(sh_form_str,"cylinder; diameter(d):%%.10g, height h/d=%.10g",diskratio); - hdratio=diskratio/2; - volume_ratio=PI_OVER_FOUR*diskratio; - yx_ratio=1; - zx_ratio=diskratio; - Nmat_need=1; - } - else if (shape==SH_EGG) { - /* determined by equation: (a/r)^2=1+nu*cos(theta)-(1-eps)cos^2(theta) - * or equivalently: a^2=r^2+nu*r*z-(1-eps)z^2. Parameters must be 00). Although it may overflow faster for nu->eps, volume_ratio (below) will - * overflow even faster. It is used to shift coordinates from the computational reference - * frame (centered at z0) to the natural one - */ - egz0=-ad*egnu*(tmp1*tmp1*tmp2*tmp2)/(tmp1+tmp2); - /* (V/d^3)=(4*pi/3)*(a/d)^3*{[2(1-eps)-nu]/sqrt(eps+nu)+[2(1-eps)+nu]/sqrt(eps-nu)}/ - * /[nu^2+4(1-eps)] - */ - volume_ratio=FOUR_PI_OVER_THREE*ad2*ad*((tmp3-egnu)*tmp1+(tmp3+egnu)*tmp2) - /(egnu*egnu+2*tmp3); - SPRINTZ(sh_form_str,"egg; diameter(d):%%.10g, epsilon=%.10g, nu=%.10g, a/d=%.10g", - egeps,egnu,ad); - Nmat_need=1; - yx_ratio=1; - zx_ratio=ad*(tmp1+tmp2); // (a/d)*[1/sqrt(eps+nu)+1/sqrt(eps-nu)] - } - else if (shape==SH_ELLIPSOID) { - aspectY=sh_pars[0]; - TestPositive(aspectY,"aspect ratio y/x"); - aspectZ=sh_pars[1]; - TestPositive(aspectZ,"aspect ratio z/x"); - SPRINTZ(sh_form_str,"ellipsoid; size along x-axis:%%.10g, aspect ratios y/x=%.10g, " - "z/x=%.10g",aspectY,aspectZ); - if (aspectY!=1) symR=FALSE; - // set inverse squares of aspect ratios - invsqY=1/(aspectY*aspectY); - invsqZ=1/(aspectZ*aspectZ); - volume_ratio=PI_OVER_SIX*aspectY*aspectZ; - yx_ratio=aspectY; - zx_ratio=aspectZ; - Nmat_need=1; - } - else if (shape==SH_LINE) { - STRCPYZ(sh_form_str,"line; length:%g"); - symY=symZ=symR=FALSE; - n_boxY=n_boxZ=jagged; - yx_ratio=zx_ratio=UNDEF; - volume_ratio=UNDEF; - Nmat_need=1; - } - else if(shape==SH_RBC) { - /* three-parameter shape; developed by K.A.Semyanov,P.A.Tarasov,P.A.Avrorov - * based on work by P.W.Kuchel and E.D.Fackerell, "Parametric-equation representation - * of biconcave erythrocytes," Bulletin of Mathematical Biology 61, 209-220 (1999). - * ro^4+2S*ro^2*z^2+z^4+P*ro^2+Q*z^2+R=0, ro^2=x^2+y^2, P,Q,R,S are determined by d,h,b,c - * given in the command line. - */ - h_d=sh_pars[0]; - TestPositive(h_d,"ratio of maximum width to diameter"); - b_d=sh_pars[1]; - TestNonNegative(b_d,"ratio of minimum width to diameter"); - if (h_d<=b_d) PrintErrorHelp("given RBC is not biconcave; maximum width is in the center"); - c_d=sh_pars[2]; - TestRangeII(c_d,"relative diameter of maximum width",0,1); - SPRINTZ(sh_form_str, - "red blood cell; diameter(d):%%.10g, maximum and minimum width h/d=%.10g, b/d=%.10g\n" - " diameter of maximum width c/d=%.10g",h_d,b_d,c_d); - // calculate shape parameters - h2=h_d*h_d; - b2=b_d*b_d; - c2=c_d*c_d; - /* P={(b/d)^2*[c^4/(h^2-b^2)-h^2]-d^2}/4; Q=(d/b)^2*(P+d^2/4)-b^2/4; R=-d^2*(P+d^2/4)/4; - * S=-(2P+c^2)/h^2; here P,Q,R,S are made dimensionless dividing by respective powers of d - * Calculation is performed so that Q is well defined even for b=0. - */ - tmp1=((c2*c2/(h2-b2))-h2)/4; - P=b2*tmp1-0.25; - Q=tmp1-(b2/4); - R=-b2*tmp1/4; - S=-(2*P+c2)/h2; - yx_ratio=1; - zx_ratio=h_d; - volume_ratio=UNDEF; - Nmat_need=1; - } - else if (shape==SH_READ) { - SPRINTZ(sh_form_str,"specified by file %s; size along x-axis:%%.10g",shape_fname); - symX=symY=symZ=symR=FALSE; // input file is assumed asymmetric - InitDipFile(shape_fname,&n_boxX,&n_boxY,&n_boxZ,&Nmat_need); - yx_ratio=zx_ratio=UNDEF; - volume_ratio=UNDEF; - } - else if (shape==SH_SPHERE) { - STRCPYZ(sh_form_str,"sphere; diameter:%.10g"); - volume_ratio=PI_OVER_SIX; - yx_ratio=zx_ratio=1; - Nmat_need=1; - } - else if (shape==SH_SPHEREBOX) { - coat_ratio=sh_pars[0]; - TestRangeII(coat_ratio,"sphere diameter/cube edge ratio",0,1); - SPRINTZ(sh_form_str, - "sphere in cube; size of cube edge(a):%%.10g, diameter of sphere d/a=%.10g",coat_ratio); - coat_r2=0.25*coat_ratio*coat_ratio; - yx_ratio=zx_ratio=1; - volume_ratio=1; - Nmat_need=2; - } - /* TO ADD NEW SHAPE - * add an option here (in the end of 'else if' sequence). Identifier ('SH_...') should be - * defined in const.h. The option should - * 1) save all the input parameters from array 'sh_pars' to local variables - * (defined in the beginning of this source files) - * 2) test all input parameters (for that you're encouraged to use functions from param.h since - * they would automatically produce informative output in case of error). If the shape can - * accept different number of parameters (UNDEF was set in array shape_opt) then also test - * the number of parameters. - * 3) if shape breaks any symmetry, corresponding variable should be set to FALSE. Do not set - * any of them to TRUE, as they can be set to FALSE by some other factors. - * symX, symY, symZ - symmetries of reflection over planes YZ, XZ, XY respectively. - * symR - symmetry of rotation for 90 degrees over the Z axis - * 4) initialize the following: - * sh_form_str - descriptive string, should contain %g - it would be replaced by box size along - * x-axis afterwards (in param.c). - * Either yx_ratio (preferably) or n_boxY. The former is a ratio of particle sizes along y and x - * axes. Initialize n_boxY directly only if it is not proportional to boxX, like in - * shape LINE above, since boxX is not initialized at this moment. If yx_ratio is not - * initialized, set it explicitly to UNDEF. - * Analogously either zx_ratio (preferably) or n_boxZ. - * Nmat_need - number of different domains in this shape (void is not included) - * volume_ratio - ratio of particle volume to (boxX)^3. Initialize it if it can be calculated - * analytically or set to UNDEF otherwise. This parameter is crucial if one wants - * to initialize computational grid from '-eq_rad' and '-dpl'. - * n_sizeX - absolute size of the particle, defined by shape; initialize only when relevant, - * e.g. for shapes such as 'axisymmetric'. - * all other auxiliary variables, which are used in shape generation (MakeParticle(), see - * below), should be defined in the beginning of this file. If you need temporary local - * variables (which are used only in this part of the code), either use 'tmp1'-'tmp3' or - * define your own (with more informative names) in the beginning of this function. - * Also (rarely) if the shape defines dimension of the computational grid or absolute size of - * the particle, correct values of box_det_sh and size_det_sh in the beginning of this function. - */ - - // initialize domain granulation - if (sh_granul) { - symX=symY=symZ=symR=FALSE; // no symmetry with granules - if (gr_mat+1>Nmat_need) - PrintError("Specified domain number to be granulated (%d) is larger than total number " - "of domains (%d) for the given shape (%s)",gr_mat+1,Nmat_need,shapename); - else Nmat_need++; - strcat(shapename,"_gran"); - } - // check if enough refractive indices or extra - if (NmatNmat_need) LogError(EC_INFO,ONE_POS, - "More refractive indices are given (%d) than actually used (%d)",Nmat,Nmat_need); - Nmat=Nmat_need; - - // check anisotropic refractive indices for symmetries - if (anisotropy) for (i=0;iboxX) - PrintError("Particle (boxX=%d) does not fit into specified boxX=%d",n_boxX,boxX); - } - // if shape is determined by ratios, calculate proposed grid sizes along y and z axes - if (yx_ratio!=UNDEF) n_boxY=(int)ceil(yx_ratio*boxX); - if (zx_ratio!=UNDEF) n_boxZ=(int)ceil(zx_ratio*boxX); - // set boxY and boxZ - if (boxY==UNDEF) { // assumed that boxY and boxZ are either both defined or both not defined - boxY=FitBox(n_boxY); - boxZ=FitBox(n_boxZ); - } - else { - temp=boxY; - if ((boxY=FitBox(boxY))!=temp) - LogError(EC_WARN,ONE_POS,"boxY has been adjusted from %i to %i",temp,boxY); - temp=boxZ; - if ((boxZ=FitBox(boxZ))!=temp) - LogError(EC_WARN,ONE_POS,"boxZ has been adjusted from %i to %i",temp,boxZ); - // this error is not duplicated in the log file since it does not yet exist - if (n_boxY>boxY || n_boxZ>boxZ) - PrintError("Particle (boxY,Z={%d,%d}) does not fit into specified boxY,Z={%d,%d}", - n_boxY,n_boxZ,boxY,boxZ); - } - // initialize number of dipoles - Ndip=boxX*((double)boxY)*boxZ; - // initialize maxiter; not very realistic - if (maxiter==UNDEF) maxiter=MIN(INT_MAX,3*Ndip); - // some old, not really logical heuristics for Ntheta, but better than constant value - if (nTheta==UNDEF) { - if (Ndip<1000) nTheta=91; - else if (Ndip<10000) nTheta=181; - else if (Ndip<100000) nTheta=361; - else nTheta=721; - } - // this limitation should be removed in the future - if (chp_type!=CHP_NONE && (!symR || scat_grid)) LogError(EC_ERROR,ONE_POS, - "Currently checkpoints can be used when internal fields are calculated only once," - "i.e. for a single incident polarization."); - Timing_Particle = GET_TIME() - tstart; + int n_boxX, n_boxYi, n_boxZi, temp; /* new values for dimensions */ + double h_d,b_d,c_d,h2,b2,c2; + double n_boxY, n_boxZ; + clock_t tstart; + int Nmat_need; + + tstart=clock(); + /* for some shapes volume_ratio is initialized below; + if not, volume correction is not used */ + volume_ratio=UNDEF; + /* if box is not defined by command line or read from file; + if size is defined, dpl is initialized to default, and grid is calculated + (dpl is slightly corrected aferwards) + else grid is initialized to default + then (in make_particle() ) the dpl is determined from size (if it is defined) + or set by default (after it size is determined */ + if (boxX==UNDEF) { + if (shape!=SH_READ) { + if (sizeX!=UNDEF) { + if (dpl==UNDEF) dpl=DEF_DPL; /* default value of dpl */ + boxX=FitBox(ceil(sizeX*dpl/lambda)); + dpl=UNDEF; /* dpl is given correct value in make_particle() */ + } + else boxX=DEF_GRID; /* default value for boxX */ + } + } + else { + temp=boxX; + if ((boxX=FitBox(boxX))!=temp) + LogError(EC_WARN,ONE_POS,"boxX has been adjusted from %i to %i",temp,boxX); + } + n_boxX=boxX; + + /* initialization of global option index for error messages */ + opt=opt_sh; + /* shape initialization */ + if (shape==SH_BOX) { + strcpy(sh_form_str,"cube; size of edge:%g"); + symX=symY=symZ=TRUE; + if (boxY==UNDEF || boxX==boxY) symR=TRUE; + else symR=FALSE; + n_boxY=n_boxZ=boxX; + Nmat_need=1; + } + else if (shape==SH_COATED) { + coat_ratio=sh_pars[0]; + TestRange(coat_ratio,"innner/outer diameter ratio",0,1); + sprintf(sh_form_str,"coated sphere; diameter(d):%%g, inner diameter d_in/d=%g",coat_ratio); + if (sh_Npars==4) { + coat_x=sh_pars[1]; + coat_y=sh_pars[2]; + coat_z=sh_pars[3]; + if (coat_x*coat_x+coat_y*coat_y+coat_z*coat_z>(1-coat_ratio)*(1-coat_ratio)) + PrintErrorHelp("Inner sphere is not fully inside the outer"); + sprintf(sh_form_str+strlen(sh_form_str), + "\n position of inner sphere center r/d={%g, %g, %g}",coat_x,coat_y,coat_z); + } + coat_r2=0.25*coat_ratio*coat_ratio; + symX=symY=symZ=symR=TRUE; + volume_ratio=PI/6; + if (coat_x!=0) {symX=FALSE; symR=FALSE;} + if (coat_y!=0) {symY=FALSE; symR=FALSE;} + if (coat_z!=0) symZ=FALSE; + n_boxY=n_boxZ=boxX; + Nmat_need=2; + } + else if(shape==SH_CYLINDER) { + diskratio=sh_pars[0]; + TestPositive(diskratio,"height to diameter ratio"); + sprintf(sh_form_str,"cylinder; diameter(d):%%g, height h/d=%g",diskratio); + symX=symY=symZ=symR=TRUE; + volume_ratio=PI/4*diskratio; + n_boxY=boxX; + n_boxZ=diskratio*boxX; + Nmat_need=1; + } + else if (shape==SH_ELLIPSOID) { + ellipsY=sh_pars[0]; + TestPositive(ellipsY,"aspect ratio y/x"); + ellipsZ=sh_pars[1]; + TestPositive(ellipsZ,"aspect ratio z/x"); + sprintf(sh_form_str,"ellipsoid; size along X:%%g, aspect ratios y/x=%g, z/x=%g", + ellipsY,ellipsZ); + symX=symY=symZ=TRUE; + if (1==ellipsY) symR=TRUE; else symR=FALSE; + volume_ratio=PI/6*ellipsY*ellipsZ; + n_boxY=ellipsY*boxX; + n_boxZ=ellipsZ*boxX; + Nmat_need=1; + } + else if (shape==SH_LINE) { + strcpy(sh_form_str,"line; legth:%g"); + symX=TRUE; + symY=symZ=symR=FALSE; + n_boxY=n_boxZ=jagged; + Nmat_need=1; + } + else if(shape==SH_RBC) { + /* three-parameter shape; developed by K.A.Semyanov,P.A.Tarasov,P.A.Avrorov + based on work by P.W.Kuchel and E.D.Fackerell, "Parametric-equation representation + of biconcave erythrocytes," Bulletin of Mathematical Biology 61, 209-220 (1999). */ + h_d=sh_pars[0]; + TestPositive(h_d,"ratio of maximum width to diameter"); + b_d=sh_pars[1]; + TestPositive(b_d,"ratio of minimum width to diameter"); + if (h_d <= b_d) PrintErrorHelp("given RBC is not biconcave; maximum width is in the center"); + c_d=sh_pars[2]; + TestRange(c_d,"relative diameter of maximum width",0,1); + sprintf(sh_form_str, + "red blood cell; diameter(d):%%g, maximum and minimum width h/d=%g, b/d=%g\n"\ + " diameter of maximum width c/d=%g",h_d,b_d,c_d); + /* calculate shape parameters */ + h2=h_d*h_d; + b2=b_d*b_d; + c2=c_d*c_d; + P=(b2*((c2*c2/(h2-b2))-h2)-1)/4; + R=-(P+0.25)/4; + Q=((P+0.25)/b2)-(b2/4); + S=-(2*P+c2)/h2; + + symX=symY=symZ=symR=TRUE; + n_boxY=boxX; + n_boxZ=h_d*boxX; + volume_ratio=UNDEF; + Nmat_need=1; + } + else if (shape==SH_READ) { + sprintf(sh_form_str,"specified by file %s; size along X:%%g",aggregate_file); + symX=symY=symZ=symR=FALSE; /* input file is assumed assymetric */ + InitDipFile(aggregate_file,&n_boxX,&n_boxYi,&n_boxZi,&Nmat_need); + n_boxY=n_boxYi; + n_boxZ=n_boxZi; + } + else if (shape==SH_SPHERE) { + strcpy(sh_form_str,"sphere; diameter:%g"); + symX=symY=symZ=symR=TRUE; + volume_ratio=PI/6; + n_boxY=n_boxZ=boxX; + Nmat_need=1; + } + else if (shape==SH_SPHEREBOX) { + coat_ratio=sh_pars[0]; + TestRange(coat_ratio,"sphere diameter/cube edge ratio",0,1); + sprintf(sh_form_str, + "sphere in cube; size of cube edge(a):%%g, diameter of sphere d/a=%g",coat_ratio); + coat_r2=0.25*coat_ratio*coat_ratio; + symX=symY=symZ=TRUE; + if (boxY==UNDEF || boxX==boxY) symR=TRUE; + else symR=FALSE; + n_boxY=n_boxZ=boxX; + Nmat_need=2; + } +/* else if(shape==SH_SDISK_ROT) { + symX=symY=symZ=FALSE; + symR=FALSE; + volume_ratio=boxX*boxX*boxX; + } + else if (shape==SH_PRISMA) { + symX=TRUE; + symY=symZ=FALSE; + symR=FALSE; + volume_ratio=.5*boxX*boxY*boxZ; + } */ + + /* check if enough refr. indices or extra*/ + if (NmatNmat_need) { + LogError(EC_INFO,ONE_POS, + "More refractive indices is given (%d) than actually used (%d)",Nmat,Nmat_need); + Nmat=Nmat_need; + } + + if (symmetry_enforced) symX=symY=symZ=symR=TRUE; + else if (NoSymmetry) symX=symY=symZ=symR=FALSE; + + if (boxX==UNDEF) boxX=FitBox(n_boxX); + else if (n_boxX>boxX) LogError(EC_ERROR,ONE_POS, + "Particle (boxX=%d) does not fit into specified boxX=%d", n_boxX, boxX); + + n_boxY=ceil(n_boxY); + n_boxZ=ceil(n_boxZ); + if (boxY==UNDEF) { /* assumed that boxY and boxZ are either both defined or both not defined */ + boxY=FitBox(n_boxY); + boxZ=FitBox(n_boxZ); + } + else { + temp=boxY; + if ((boxY=FitBox(boxY))!=temp) + LogError(EC_WARN,ONE_POS,"boxY has been adjusted from %i to %i",temp,boxY); + temp=boxZ; + if ((boxZ=FitBox(boxZ))!=temp) + LogError(EC_WARN,ONE_POS,"boxZ has been adjusted from %i to %i",temp,boxZ); + /* this error is not duplicated in the logfile since it does not yet exist */ + if (n_boxY>boxY || n_boxZ>boxZ) LogError(EC_ERROR,ONE_POS, + "Particle (boxY,Z={%d,%d}) does not fit into specified boxY,Z={%d,%d}", + (int)n_boxY,(int)n_boxZ,boxY,boxZ); + } + /* initialize number of dipoles */ + Ndip=boxX*boxY*boxZ; + /* initialize maxiter; not very realistic */ + if (maxiter==UNDEF) maxiter=3*Ndip; + /* initialize nTheta */ + if (nTheta==UNDEF) { + if (Ndip<1000) nTheta=91; + else if (Ndip<10000) nTheta=181; + else if (Ndip<100000) nTheta=361; + else nTheta=721; + } + Timing_Particle = clock() - tstart; } -//========================================================== +/*==========================================================*/ void MakeParticle(void) -// creates a particle; initializes all dipoles counts, dpl, gridspace + /* creates a particle; initializes all dipoles counts, dpl, gridspace */ { - int i,j,k,ns; - size_t index,dip,nlocalRows_tmp; - double tmp1,tmp2,tmp3; - double xr,yr,zr,xcoat,ycoat,zcoat,r2,z2,zshift; - double jcX,jcY,jcZ; // center for jagged - int local_z0_unif; // should be global or semi-global - int largerZ,smallerZ; // number of larger and smaller z in intersections with contours - int xj,yj,zj; - int mat; - unsigned short us_tmp; - TIME_TYPE tstart,tgran; - /* TO ADD NEW SHAPE - * Add here all intermediate variables, which are used only inside this function. You may as - * well use 'tmp1'-'tmp3' variables defined above. - */ - - tstart=GET_TIME(); - - index=0; - // assumed that box's are even - jcX=jcY=jcZ=jagged/2.0; - cX=(boxX-1)/2.0; - cY=(boxY-1)/2.0; - cZ=(boxZ-1)/2.0; - nlocalRows_tmp=MultOverflow(3,local_Ndip,ALL_POS,"nlocalRows_tmp"); - /* allocate temporary memory; even if prognosis, since they are needed for exact estimation - * they will be reallocated afterwards (when nlocalRows is known). - */ - MALLOC_VECTOR(material_tmp,uchar,local_Ndip,ALL); - MALLOC_VECTOR(DipoleCoord_tmp,double,nlocalRows_tmp,ALL); - MALLOC_VECTOR(position_tmp,ushort,nlocalRows_tmp,ALL); - - for(k=local_z0;k=contRoSqMin && r2<=0.25) { - largerZ=smallerZ=0; - contCurRo=sqrt(r2); - contCurZ=zr; - for (ns=0;ns=contSegRoMin[ns] && contCurRo<=contSegRoMax[ns]) - CheckContourSegment(contSeg+ns) ? largerZ++ : smallerZ++; - // check for consistency; if the code is perfect, this is not needed - if (!IS_EVEN(largerZ+smallerZ)) LogError(EC_ERROR,ALL_POS, - "Point (ro,z)=(%g,%g) produced weird result when checking whether it lies " - "inside the contour. Larger than z %d intersections, smaller - %d.", - contCurRo,contCurZ,largerZ,smallerZ); - if (!IS_EVEN(largerZ)) mat=0; - } - } - else if (shape==SH_BOX) { - if (fabs(yr)<=haspY && fabs(zr)<=haspZ) mat=0; - } - else if (shape==SH_CAPSULE) { - r2=xr*xr+yr*yr; - if (r2<=0.25) { - tmp1=fabs(zr)-hdratio; - if (tmp1<=0 || tmp1*tmp1+r2<=0.25) mat=0; - } - } - else if (shape==SH_COATED) { - if (xr*xr+yr*yr+zr*zr<=0.25) { // first test to skip some dipoles immediately) - xcoat=xr-coat_x; - ycoat=yr-coat_y; - zcoat=zr-coat_z; - if (xcoat*xcoat+ycoat*ycoat+zcoat*zcoat<=coat_r2) mat=1; - else mat=0; - } - } - else if (shape==SH_CYLINDER) { - if(xr*xr+yr*yr<=0.25 && fabs(zr)<=hdratio) mat=0; - } - else if (shape==SH_EGG) { - r2=xr*xr+yr*yr; - zshift=zr+egz0; - z2=zshift*zshift; - if (r2+egeps*z2+egnu*zshift*sqrt(r2+z2)<=ad2) mat=0; - } - else if (shape==SH_ELLIPSOID) { - if (xr*xr+yr*yr*invsqY+zr*zr*invsqZ<=0.25) mat=0; - } - else if (shape==SH_LINE) { - if (yj==0 && zj==0) mat=0; - } - else if (shape==SH_RBC) { - r2=xr*xr+yr*yr; - z2=zr*zr; - if (r2*r2+2*S*r2*z2+z2*z2+P*r2+Q*z2+R<=0) mat=0; - } - else if (shape==SH_SPHERE) { - if (xr*xr+yr*yr+zr*zr<=0.25) mat=0; - } - else if (shape==SH_SPHEREBOX) { - if (xr*xr+yr*yr+zr*zr<=coat_r2) mat=1; - else if (fabs(yr)<=0.5 && fabs(zr)<=0.5) mat=0; - } - /* TO ADD NEW SHAPE - * add an option here (in the end of 'else if' sequence). Identifier ('SH_...') - * should be defined in const.h. This option should set 'mat' - index of domain for - * a point, specified by {xr,yr,zr} - coordinates divided by grid size along X (xr - * from -0.5 to 0.5, others - depending on aspect ratios). C array indexing used: - * mat=0 - first domain, etc. If point corresponds to void, do not set 'mat'. If you - * need temporary local variables (which are used only in this part of the code), - * either use 'tmp1'-'tmp3' or define your own (with more informative names) in the - * beginning of this function. - */ - - position_tmp[3*index]=(unsigned short)i; - position_tmp[3*index+1]=(unsigned short)j; - position_tmp[3*index+2]=(unsigned short)k; - // afterwards multiplied by gridspace - DipoleCoord_tmp[3*index]=i-cX; - DipoleCoord_tmp[3*index+1]=j-cY; - DipoleCoord_tmp[3*index+2]=k-cZ; - material_tmp[index]=(unsigned char)mat; - index++; - } // End box loop - if (shape==SH_READ) ReadDipFile(shape_fname); - // initialization of mat_count and dipoles counts - for(i=0;i<=Nmat;i++) mat_count[i]=0; - for(dip=0;dip=0 && yr<=jagged/2.0 && zr>=0 && zr<=jagged/2.0) mat=0; + } + else if (shape==SH_SPHERE) { + if (xr*xr+yr*yr+zr*zr <= 0.25) mat=0; + } + else if (shape==SH_SPHEREBOX) { + if (xr*xr+yr*yr+zr*zr <= coat_r2) mat=1; + else mat=0; + } + else if (shape==SH_RBC) { + r2=xr*xr+yr*yr; + z2=zr*zr; + if (r2*r2+2*S*r2*z2+z2*z2+P*r2+Q*z2+R <= 0) mat=0; + } +/* else if (shape==SH_SDISK_ROT) { + xr= (i+centreX)/(boxX); + yr= (j+centreY)/(boxY); + zr= (k+centreZ)/(boxZ); + CY=cos(PI/180*betaY); SY=sin(PI/180*betaY); + CZ=cos(PI/180*betaZ); SZ=sin(PI/180*betaZ); + xr_=xr*CY*CZ-yr*SZ-zr*SY*CZ; + yr_=xr*CY*SZ+yr*CZ-zr*SY*SZ; + zr_=xr*SY+zr*CY; + cthick=(aspect_r)/2.0; + radius=(xr_*xr_+yr_*yr_+zr_*zr_)/0.25; + if (radius <1.0000001 && xr_-cthick) mat=0; + } + else if (shape==SH_PRISMA && y*boxZ>=-z*boxY) mat=0;*/ + + position_tmp[3*index]=(short int)(i+boxX/2); + position_tmp[3*index+1]=(short int)(j+boxY/2); + position_tmp[3*index+2]=(short int)(k+boxZ/2); + /* afterwards multiplied by gridspace */ + DipoleCoord_tmp[3*index] = x; + DipoleCoord_tmp[3*index+1] = y; + DipoleCoord_tmp[3*index+2] = z; + material_tmp[index]=(char)mat; + index++; + } /* End box loop */ + if (shape==SH_READ) ReadDipFile(aggregate_file); + + /* initialization of mat_count and dipoles counts */ + for(i=0;i<=Nmat;i++) mat_count[i]=0; + for(i=0;i $(LASTSEQ) - -# Dependencies are only generated for C sources; -# we assume that each Fortran file is completely independent - -$(CDEPEND): %.d: %.c $(MFILES) - $(CC) $(DEPFLAG) $(CFLAGS) $< $(DFFLAG) $@.$$$$; \ - sed 's,\($*\)\.o[ :]*,\1.o $@ : ,g' < $@.$$$$ > $@; \ - rm -f $@.$$$$ +%.d: %.c + $(SHELL) -ec '$(CC) -M $(CFLAGS) $< \ + | sed '\''s/\($*\)\.o[ :]*/\1.o $@ : /g'\'' > $@; \ + [ -s $@ ] || rm -f $@' -include $(CDEPEND) +include $(CSOURCE:.c=.d) diff --git a/src/matvec.c b/src/matvec.c index 7f3dddf9..fd9ac160 100644 --- a/src/matvec.c +++ b/src/matvec.c @@ -1,350 +1,356 @@ /* FILE: matvec.c * AUTH: Maxim Yurkin * DESCR: calculate local matrix vector product of decomposed interaction - * matrix with r_k or p_k, using a FFT based convolution algorithm + * matrix with rk or pk, using a FFT based convolution algorithm * * Previous version by Michel Grimminck * - * Copyright (C) 2006-2008 University of Amsterdam + * Copyright (C) 2006 M.A. Yurkin and A.G. Hoekstra * This code is covered by the GNU General Public License. */ #include -#include +#include #include "vars.h" #include "cmplx.h" #include "const.h" #include "comm.h" +#include "debug.h" +#include "memory.h" #include "fft.h" #include "prec_time.h" #include "linalg.h" -#include "function.h" -#include "io.h" -// SEMI-GLOBAL VARIABLES +/* SEMI-GLOBAL VARIABLES */ -// defined and initialized in fft.c +/* defined and initialized in fft.c */ extern const doublecomplex *Dmatrix; extern doublecomplex *Xmatrix,*slices,*slices_tr; -extern const size_t DsizeY,DsizeZ,DsizeYZ; +extern const int DsizeY,DsizeZ,DsizeYZ,NDcomp; -//============================================================ +/*============================================================*/ -INLINE size_t IndexSliceZY(const size_t y,const size_t z) +INLINE int IndexSliceZY(const int y,const int z) { - return (z*gridY+y); + return (z*gridY+y); } -//============================================================ +/*============================================================*/ -INLINE size_t IndexSliceYZ(const size_t y,const size_t z) +INLINE int IndexSliceYZ(const int y,const int z) { - return(y*gridZ+z); + return(y*gridZ+z); } -//============================================================ +/*============================================================*/ -INLINE size_t IndexGarbledX(const size_t x,const size_t y,const size_t z) +INLINE int IndexGarbledX(const int x,const int y,const int z) { #ifdef PARALLEL - return(((z%local_Nz)*smallY+y)*gridX+(z/local_Nz)*local_Nx+x%local_Nx); + return(((z%local_Nz)*smallY+y)*gridX+(z/local_Nz)*local_Nx+x%local_Nx); #else - return((z*smallY+y)*gridX+x); + return((z*smallY+y)*gridX+x); #endif } -//============================================================ +/*============================================================*/ -INLINE size_t IndexXmatrix(const size_t x,const size_t y,const size_t z) +INLINE int IndexXmatrix(const int x,const int y,const int z) { - return((z*smallY+y)*gridX+x); + return((z*smallY+y)*gridX+x); } -//============================================================ +/*============================================================*/ -INLINE size_t IndexDmatrix_mv(size_t x,size_t y,size_t z,const int transposed) +INLINE int IndexDmatrix_mv(int x,int y,int z,const int transposed) { - if (transposed) { // used only for G_SO - if (x>0) x=gridX-x; - if (y>0) y=gridY-y; - if (z>0) z=gridZ-z; - } - else { - if (y>=DsizeY) y=gridY-y; - if (z>=DsizeZ) z=gridZ-z; - } - - return(NDCOMP*(x*DsizeYZ+z*DsizeY+y)); + if (transposed) { /* used only for G_SO */ + if (x>0) x=gridX-x; + if (y>0) y=gridY-y; + if (z>0) z=gridZ-z; + } + else { + if (y>=DsizeY) y=gridY-y; + if (z>=DsizeZ) z=gridZ-z; + } + + return(NDcomp*(x*DsizeYZ+z*DsizeY+y)); } -//============================================================ +/*============================================================*/ -void MatVec (doublecomplex *argvec, // the argument vector - doublecomplex *resultvec, // the result vector - double *inprod, // the resulting inner product - const int her) // 0 for non-Hermitian, 1 for Hermitian -/* This function implements both MatVec_nim and MatVecAndInp_nim. The difference is that when we - * want to calculate the inner product as well, we pass 'inprod' as a non-NULL pointer. if 'inprod' - * is NULL, we don't calculate it. 'argvec' always remains unchanged afterwards, however it is not - * strictly const - some manipulations may occur during the execution. - */ +void MatVec (doublecomplex *argvec, /* the argument vector */ + doublecomplex *resultvec, /* the result vector */ + double *inprod, /* the result inner product */ + const int her) /* 0 for non-hermitic, 1 for hermetic */ +/* This function implements both MatVec_nim and MatVecAndInp_nim. + the difference is that when we want to calculate the inproduct + as well, we pass 'inprod' as a non-null pointer. if 'inprod' is + a NULL, we don't calculate it. + argvec allways remains unchanged afterwards, however it is not + strictly const - some manipulations may occur during the execution */ { - size_t i,j; - doublecomplex fmat[6],xv[3],yv[3]; - doublecomplex temp; - size_t index,x,y,z,Xcomp; - int ipr; - unsigned char mat; - int transposed; - size_t boxY_st=boxY,boxZ_st=boxZ; // copies with different type + int i, j; + + doublecomplex fmat[6],xvec[3],yvec[3]; + doublecomplex temp; + int index,x,y,z,Xcomp,ipr; + char mat; + + clock_t tstart; #ifdef PRECISE_TIMING - SYSTEM_TIME tvp[18]; - SYSTEM_TIME Timing_FFTXf,Timing_FFTYf,Timing_FFTZf,Timing_FFTXb,Timing_FFTYb,Timing_FFTZb, - Timing_Mult1,Timing_Mult2,Timing_Mult3,Timing_Mult4,Timing_Mult5, - Timing_BTf,Timing_BTb,Timing_TYZf,Timing_TYZb,Timing_ipr; - double t_FFTXf,t_FFTYf,t_FFTZf,t_FFTXb,t_FFTYb,t_FFTZb, - t_Mult1,t_Mult2,t_Mult3,t_Mult4,t_Mult5,t_ipr, - t_BTf,t_BTb,t_TYZf,t_TYZb,t_Arithm,t_FFT,t_Comm; + SYSTEM_TIME tvp[18]; + SYSTEM_TIME Timing_FFTXf,Timing_FFTYf,Timing_FFTZf,Timing_FFTXb,Timing_FFTYb,Timing_FFTZb, + Timing_Mult1,Timing_Mult2,Timing_Mult3,Timing_Mult4,Timing_Mult5, + Timing_BTf,Timing_BTb,Timing_TYZf,Timing_TYZb,Timing_ipr; + double t_FFTXf,t_FFTYf,t_FFTZf,t_FFTXb,t_FFTYb,t_FFTZb, + t_Mult1,t_Mult2,t_Mult3,t_Mult4,t_Mult5,t_ipr, + t_BTf,t_BTb,t_TYZf,t_TYZb,t_Arithm,t_FFT,t_Comm; #endif + int transposed; -/* A = I + S.D.S - * S = sqrt(C) - * A.x = x + S.D.(S.x) - * A(H).x = x + (S(T).D(T).S(T).x(*))(*) - * C,S - diagonal => symmetric - * (!! will change if tensor (non-diagonal) polarizability is used !!) - * D - symmetric (except for G_SO) - * - * D.x=F(-1)(F(D).F(X)) - * F(D) is just a vector - * - * G_SO: F(D(T)) (k) = F(D) (-k) - * k - vector index - * - * For (her) three additional operations of nConj are used. Should not be a problem, - * but can be avoided by a more complex code. - */ + /* A = I + S.D.S + * S = sqrt(C) + * A.x = x + S.D.(S.x) + * A(H).x = x + (S(T).D(T).S(T).x(*))(*) + * C,S - diagonal => symmetric + * (!! will change if tensor (non-diagonal) polarizability is used !!) + * D - symmetric (except for G_SO) + * + * D.x=F(-1)(F(D).F(X)) + * F(D) is just a vector + * + * G_SO: F(D(T)) (k) = F(D) (-k) + * k - vector index + * + * For (her) three additional operations of nConj are used. Should not be a problem, + * but can be avoided by a more complex code. + */ - transposed=(!reduced_FFT) && her; - if (inprod) ipr=TRUE; - else ipr=FALSE; + transposed=(!reduced_FFT) && her; + if (inprod) ipr=TRUE; + else ipr=FALSE; #ifdef PRECISE_TIMING - InitTime(&Timing_FFTYf); - InitTime(&Timing_FFTZf); - InitTime(&Timing_FFTYb); - InitTime(&Timing_FFTZb); - InitTime(&Timing_Mult2); - InitTime(&Timing_Mult3); - InitTime(&Timing_Mult4); - InitTime(&Timing_TYZf); - InitTime(&Timing_TYZb); - GetTime(tvp); + InitTime(&Timing_FFTYf); + InitTime(&Timing_FFTZf); + InitTime(&Timing_FFTYb); + InitTime(&Timing_FFTZb); + InitTime(&Timing_Mult2); + InitTime(&Timing_Mult3); + InitTime(&Timing_Mult4); + InitTime(&Timing_TYZf); + InitTime(&Timing_TYZb); + GetTime(tvp); #endif - // FFT_matvec code - if (ipr) *inprod = 0.0; + /* FFT_matvec code */ + if (ipr) *inprod = 0.0; - // fill Xmatrix with 0.0 - for (i=0;i<3*local_Nsmall;i++) Xmatrix[i][RE]=Xmatrix[i][IM]=0.0; + /* fill Xmatrix with 0.0 */ + for (i=0;i<3*local_Nsmall;i++) Xmatrix[i][RE]=Xmatrix[i][IM]=0.0; - // transform from coordinates to grid and multiply with coupling constant - if (her) nConj(argvec); // conjugated back afterwards + /* transform from coordinates to grid and multiply with coupling constant */ + if (her) nConj(argvec); /* conjugated back afterwards */ - for (i=0;ismallY) { - cInvSign(fmat[1]); // fmat[1]*=-1 - if (z>smallZ) cInvSign(fmat[2]); // fmat[2]*=-1 - else cInvSign(fmat[4]); // fmat[4]*=-1 - } - else if (z>smallZ) { - cInvSign(fmat[2]); // fmat[2]*=-1 - cInvSign(fmat[4]); // fmat[4]*=-1 - } - } - cSymMatrVec(fmat,xv,yv); // yv=fmat*xv - for (Xcomp=0;Xcomp<3;Xcomp++) - cEqual(yv[Xcomp],slices_tr[i+Xcomp*gridYZ]); - } + j=IndexDmatrix_mv(x-local_x0,y,z,transposed); + memcpy(fmat,Dmatrix[j],6*sizeof(doublecomplex)); + if (reduced_FFT) { + if (y>smallY) { + cInvSign(fmat[1]); /* fmat[1]*=-1 */ + if (z>smallZ) cInvSign(fmat[2]); /* fmat[2]*=-1 */ + else cInvSign(fmat[4]); /* fmat[4]*=-1 */ + } + else if (z>smallZ) { + cInvSign(fmat[2]); /* fmat[2]*=-1 */ + cInvSign(fmat[4]); /* fmat[4]*=-1 */ + } + } + cSymMatrVec(fmat,xvec,yvec); /* yvec=fmat*xvec */ + for (Xcomp=0;Xcomp<3;Xcomp++) + memcpy(slices_tr[i+Xcomp*gridYZ],yvec[Xcomp],sizeof(doublecomplex)); + } #ifdef PRECISE_TIMING - GetTime(tvp+9); - ElapsedInc(tvp+8,tvp+9,&Timing_Mult3); + GetTime(tvp+9); + ElapsedInc(tvp+8,tvp+9,&Timing_Mult3); #endif - // fft_invY&Z - fftY(FFT_BACKWARD); // fftY slices_tr + /* fft_invY&Z */ + fftY(FFT_BACKWARD); /* fftY slices_tr */ #ifdef PRECISE_TIMING - GetTime(tvp+10); - ElapsedInc(tvp+9,tvp+10,&Timing_FFTYb); + GetTime(tvp+10); + ElapsedInc(tvp+9,tvp+10,&Timing_FFTYb); #endif - TransposeYZ(FFT_BACKWARD); + TransposeYZ(FFT_BACKWARD); #ifdef PRECISE_TIMING - GetTime(tvp+11); - ElapsedInc(tvp+10,tvp+11,&Timing_TYZb); + GetTime(tvp+11); + ElapsedInc(tvp+10,tvp+11,&Timing_TYZb); #endif - fftZ(FFT_BACKWARD); // fftZ slices + fftZ(FFT_BACKWARD); /* fftZ slices */ #ifdef PRECISE_TIMING - GetTime(tvp+12); - ElapsedInc(tvp+11,tvp+12,&Timing_FFTZb); + GetTime(tvp+12); + ElapsedInc(tvp+11,tvp+12,&Timing_FFTZb); #endif - // copy slice back to Xmatrix - for(y=0;y #include -#include "types.h" +#include "cmplx.h" #include "memory.h" #include "fft.h" -#include "io.h" -#include "const.h" #ifdef FFTW3 -# include // for fftw_malloc +# include /* for fftw_malloc */ #endif -// common error check -#define MALLOC_ERROR LogError(EC_ERROR,who,fname,line,"Could not malloc %s",name) -#define CHECK_NULL(size,v) if ((size)!=0 && (v)==NULL) MALLOC_ERROR -#define CHECK_SIZE(size,type) if ((SIZE_MAX/sizeof(type))<(size)) MALLOC_ERROR -#define IF_FREE(v) if((v)!=NULL) free(v) -#define OVERFLOW LogError(EC_ERROR,who,fname,line,"Integer overflow in '%s'",name); +/*============================================================*/ +/******************* Complex matrices and vectors ***************/ -//============================================================ - -void CheckOverflow(const double size,OTHER_ARGUMENTS) -// checks if size can fit into size_t type, otherwise overflow will happen before memory allocation -{ - if (size>SIZE_MAX) OVERFLOW; +/* cMatrix(nrl, nrh, ncl, nch) + * Allocate a double complex matrix with range + * [nrl..nrh][ncl..nch] + */ +doublecomplex **cMatrix (const int nrl,const int nrh,const int ncl,const int nch) +{ + register int i; + doublecomplex **m; + + m = (doublecomplex **) malloc ((nrh-nrl+1)*sizeof(doublecomplex)); + if (m == NULL) + return (m); + m -= nrl; + + for (i=nrl; i<=nrh; i++) { + m[i] = (doublecomplex *) malloc ((nch-ncl+1)*sizeof(doublecomplex)); + if (m[i] == NULL) + return (NULL); + m[i] -= ncl; + } + + return (m); +} + +/*============================================================*/ + +/* Free_cMatrix(m, nrl, nrh, ncl) + * Frees a double complex matrix allocated with cMatrix + */ +void Free_cMatrix (doublecomplex **m,const int nrl,const int nrh,const int ncl) +{ + register int i; + for (i=nrh; i>=nrl; i--) free((char *)(m[i]+ncl)); + free((char *)(m+nrl)); } -//============================================================ +/*============================================================*/ -size_t MultOverflow(const size_t a,const size_t b,OTHER_ARGUMENTS) -// multiplies two integers and checks for overflow -{ - if ((SIZE_MAX/a)=nl -{ - double *v; - size_t size; +/*============================================================*/ - if (nh=nrl; nch>=ncl +/* Free_cVector(m) + * Frees a double complex vector allocated with cVector */ -{ - register size_t i; - size_t rows,cols; - int **m; - - if (nrh=nrl; i--) free((char *)(m[i]+ncl)); + free((char *)(m+nrl)); } -//============================================================ - -void *voidVector(const size_t size,OTHER_ARGUMENTS) -// allocates void vector -{ - void *v; - - v=malloc(size); - CHECK_NULL(size,v); - return v; -} +/*============================================================*/ -//============================================================ - -void Free_cVector (doublecomplex *v) -// frees complex vector +/* dVector(nl, nh) + * return a pointer to space for a real vector in double precision + * having indices ranging from nl to nh + */ +double *dVector(const int nl,const int nh) { -#ifdef FFTW3 - if (v!=NULL) fftw_free(v); -#else - IF_FREE(v); -#endif + double *v; + + v = (double *) malloc( (nh-nl+1) * sizeof(double) ); + if ( v == NULL ) + return( v ); + v -= nl; + return( v ); } -//============================================================ +/*============================================================*/ -void Free_dMatrix(double **m,const size_t rows) -// frees double matrix (rows x cols) +/* Free_dVector(v, nl) + * Frees a double vector allocated with dVector + */ +void Free_dVector (double *v,const int nl) { - register size_t i; - - for (i=0;i=nrl;i--) IF_FREE(m[i]+ncl); - IF_FREE(m+nrl); +/* Free_iVector(m, nl) + * Frees an integer vector allocated with iVector + */ +void Free_iVector (int *v,const int nl) +{ + free((char *) (v+nl)); } -//============================================================ +/*============================================================*/ -void Free_general(void *v) -// frees general vector; kept in a special function for future development -{ - IF_FREE(v); +/* iMatrix(nrl, nrh, ncl, nch) + * Allocate an int matrix with range [nrl..nrh][ncl..nch] + */ +int **iMatrix (const int nrl,const int nrh,const int ncl,const int nch) +{ + register int i; + int **m; + + m = (int **) malloc ((nrh-nrl+1)*sizeof(int)); + if (m == NULL) + return (m); + m -= nrl; + + for (i=nrl; i<=nrh; i++) { + m[i] = (int *) malloc ((nch-ncl+1)*sizeof(int)); + if (m[i] == NULL) + return (NULL); + m[i] -= ncl; + } + + return (m); +} + +/*============================================================*/ + +void Free_iMatrix (int **m,const int nrl,const int nrh,const int ncl) +{ + register int i; + for (i=nrh; i>=nrl; i--) free((char *)(m[i]+ncl)); + free((char *)(m+nrl)); } - diff --git a/src/memory.h b/src/memory.h index f3aee821..edbcc203 100644 --- a/src/memory.h +++ b/src/memory.h @@ -2,48 +2,28 @@ * AUTH: Maxim Yurkin * DESCR: definitions of functions for * memory allocation and freeing - * also includes overflows checks * - * Copyright (C) 2006-2008 University of Amsterdam + * Copyright (C) 2006 M.A. Yurkin and A.G. Hoekstra * This code is covered by the GNU General Public License. */ #ifndef __memory_h #define __memory_h -#include // for size_t -#include "function.h" // for function attributes - #define MBYTE 1048576.0 -// for conciseness -#define OTHER_ARGUMENTS const int who,const char *fname,const int line,const char *name -void CheckOverflow(double size,OTHER_ARGUMENTS); -size_t MultOverflow(size_t a,size_t b,OTHER_ARGUMENTS); -// allocate -doublecomplex *complexVector(size_t size,OTHER_ARGUMENTS) ATT_MALLOC; -double **doubleMatrix(size_t rows,size_t cols,OTHER_ARGUMENTS) ATT_MALLOC; -double *doubleVector(size_t size,OTHER_ARGUMENTS) ATT_MALLOC; -double *doubleVector2(size_t nl,size_t nh,OTHER_ARGUMENTS) ATT_MALLOC; -int **intMatrix (size_t nrl,size_t nrh,size_t ncl,size_t nch,OTHER_ARGUMENTS) ATT_MALLOC; -int *intVector(size_t size,OTHER_ARGUMENTS) ATT_MALLOC; -unsigned short *ushortVector(size_t size,OTHER_ARGUMENTS) ATT_MALLOC; -char *charVector(size_t size,OTHER_ARGUMENTS) ATT_MALLOC; -unsigned char *ucharVector(size_t size,OTHER_ARGUMENTS) ATT_MALLOC; -void *voidVector(size_t size,OTHER_ARGUMENTS) ATT_MALLOC; -// reallocate -double *doubleRealloc(double *ptr,const size_t size,OTHER_ARGUMENTS) ATT_MALLOC; -// free -void Free_cVector(doublecomplex *v); -void Free_dMatrix(double **m,size_t rows); -void Free_dVector2(double *v,size_t nl); -void Free_iMatrix(int **m,size_t nrl,size_t nrh,size_t ncl); -void Free_general(void *v); +doublecomplex **cMatrix (int nrl, int nrh, int ncl, int nch); +void Free_cMatrix (doublecomplex **m, int nrl, int nrh, int ncl); +doublecomplex *cVector(int size); +void Free_cVector (doublecomplex *v); + +double **dMatrix (int nrl, int nrh, int ncl, int nch); +void Free_dMatrix (double **m, int nrl, int nrh, int ncl); +double *dVector(int nl,int nh); +void Free_dVector (double *v, int nl); -// macros to use for allocation and reallocation -#define MALLOC_VECTOR(vec,type,size,who) vec=type##Vector(size,who,POSIT,#vec) -#define MALLOC_DVECTOR2(vec,nl,nh,who) vec=doubleVector2(nl,nh,who,POSIT,#vec) -#define MALLOC_DMATRIX(vec,rows,cols,who) vec=doubleMatrix(rows,cols,who,POSIT,#vec) -#define MALLOC_IMATRIX(vec,nrl,nrh,ncl,nch,who) vec=intMatrix(nrl,nrh,ncl,nch,who,POSIT,#vec) -#define REALLOC_DVECTOR(vec,size,who) vec=doubleRealloc(vec,size,who,POSIT,#vec) +int *iVector(int nl, int nh); +void Free_iVector (int *v, int nl); +int **iMatrix (int nrl, int nrh, int ncl, int nch); +void Free_iMatrix (int **m, int nrl, int nrh, int ncl); -#endif //__memory_h +#endif /*__memory_h*/ diff --git a/src/mt19937ar.c b/src/mt19937ar.c deleted file mode 100644 index 211aefde..00000000 --- a/src/mt19937ar.c +++ /dev/null @@ -1,175 +0,0 @@ -/* - A C-program for MT19937, with initialization improved 2002/1/26. - Coded by Takuji Nishimura and Makoto Matsumoto. - - Before using, initialize the state by using init_genrand(seed) - or init_by_array(init_key, key_length). - - Copyright (C) 1997 - 2002, Makoto Matsumoto and Takuji Nishimura, - All rights reserved. - Copyright (C) 2005, Mutsuo Saito, - All rights reserved. - - Redistribution and use in source and binary forms, with or without - modification, are permitted provided that the following conditions - are met: - - 1. Redistributions of source code must retain the above copyright - notice, this list of conditions and the following disclaimer. - - 2. Redistributions in binary form must reproduce the above copyright - notice, this list of conditions and the following disclaimer in the - documentation and/or other materials provided with the distribution. - - 3. The names of its contributors may not be used to endorse or promote - products derived from this software without specific prior written - permission. - - THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS - "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT - LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR - A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR - CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, - EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, - PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR - PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF - LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING - NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS - SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. - - - Any feedback is very welcome. - http://www.math.sci.hiroshima-u.ac.jp/~m-mat/MT/emt.html - email: m-mat @ math.sci.hiroshima-u.ac.jp (remove space) -*/ - -#include -#include "mt19937ar.h" - -/* Period parameters */ -#define N 624 -#define M 397 -#define MATRIX_A 0x9908b0dfUL /* constant vector a */ -#define UPPER_MASK 0x80000000UL /* most significant w-r bits */ -#define LOWER_MASK 0x7fffffffUL /* least significant r bits */ - -static unsigned long mt[N]; /* the array for the state vector */ -static int mti=N+1; /* mti==N+1 means mt[N] is not initialized */ - -/* initializes mt[N] with a seed */ -void init_genrand(unsigned long s) -{ - mt[0]= s & 0xffffffffUL; - for (mti=1; mti> 30)) + mti); - /* See Knuth TAOCP Vol2. 3rd Ed. P.106 for multiplier. */ - /* In the previous versions, MSBs of the seed affect */ - /* only MSBs of the array mt[]. */ - /* 2002/01/09 modified by Makoto Matsumoto */ - mt[mti] &= 0xffffffffUL; - /* for >32 bit machines */ - } -} - -/* initialize by an array with array-length */ -/* init_key is the array for initializing keys */ -/* key_length is its length */ -/* slight change for C++, 2004/2/26 */ -void init_by_array(unsigned long init_key[], int key_length) -{ - int i, j, k; - init_genrand(19650218UL); - i=1; j=0; - k = (N>key_length ? N : key_length); - for (; k; k--) { - mt[i] = (mt[i] ^ ((mt[i-1] ^ (mt[i-1] >> 30)) * 1664525UL)) - + init_key[j] + j; /* non linear */ - mt[i] &= 0xffffffffUL; /* for WORDSIZE > 32 machines */ - i++; j++; - if (i>=N) { mt[0] = mt[N-1]; i=1; } - if (j>=key_length) j=0; - } - for (k=N-1; k; k--) { - mt[i] = (mt[i] ^ ((mt[i-1] ^ (mt[i-1] >> 30)) * 1566083941UL)) - - i; /* non linear */ - mt[i] &= 0xffffffffUL; /* for WORDSIZE > 32 machines */ - i++; - if (i>=N) { mt[0] = mt[N-1]; i=1; } - } - - mt[0] = 0x80000000UL; /* MSB is 1; assuring non-zero initial array */ -} - -/* generates a random number on [0,0xffffffff]-interval */ -unsigned long genrand_int32(void) -{ - unsigned long y; - static unsigned long mag01[2]={0x0UL, MATRIX_A}; - /* mag01[x] = x * MATRIX_A for x=0,1 */ - - if (mti >= N) { /* generate N words at one time */ - int kk; - - if (mti == N+1) /* if init_genrand() has not been called, */ - init_genrand(5489UL); /* a default initial seed is used */ - - for (kk=0;kk> 1) ^ mag01[y & 0x1UL]; - } - for (;kk> 1) ^ mag01[y & 0x1UL]; - } - y = (mt[N-1]&UPPER_MASK)|(mt[0]&LOWER_MASK); - mt[N-1] = mt[M-1] ^ (y >> 1) ^ mag01[y & 0x1UL]; - - mti = 0; - } - - y = mt[mti++]; - - /* Tempering */ - y ^= (y >> 11); - y ^= (y << 7) & 0x9d2c5680UL; - y ^= (y << 15) & 0xefc60000UL; - y ^= (y >> 18); - - return y; -} - -/* generates a random number on [0,0x7fffffff]-interval */ -long genrand_int31(void) -{ - return (long)(genrand_int32()>>1); -} - -/* generates a random number on [0,1]-real-interval */ -double genrand_real1(void) -{ - return genrand_int32()*(1.0/4294967295.0); - /* divided by 2^32-1 */ -} - -/* generates a random number on [0,1)-real-interval */ -double genrand_real2(void) -{ - return genrand_int32()*(1.0/4294967296.0); - /* divided by 2^32 */ -} - -/* generates a random number on (0,1)-real-interval */ -double genrand_real3(void) -{ - return (((double)genrand_int32()) + 0.5)*(1.0/4294967296.0); - /* divided by 2^32 */ -} - -/* generates a random number on [0,1) with 53-bit resolution*/ -double genrand_res53(void) -{ - unsigned long a=genrand_int32()>>5, b=genrand_int32()>>6; - return(a*67108864.0+b)*(1.0/9007199254740992.0); -} -/* These real versions are due to Isaku Wada, 2002/01/09 added */ diff --git a/src/mt19937ar.h b/src/mt19937ar.h deleted file mode 100644 index 769cd048..00000000 --- a/src/mt19937ar.h +++ /dev/null @@ -1,76 +0,0 @@ -/* - A C-program for MT19937, with initialization improved 2002/1/26. - Coded by Takuji Nishimura and Makoto Matsumoto. - - Before using, initialize the state by using init_genrand(seed) - or init_by_array(init_key, key_length). - - Copyright (C) 1997 - 2002, Makoto Matsumoto and Takuji Nishimura, - All rights reserved. - Copyright (C) 2005, Mutsuo Saito - All rights reserved. - - Redistribution and use in source and binary forms, with or without - modification, are permitted provided that the following conditions - are met: - - 1. Redistributions of source code must retain the above copyright - notice, this list of conditions and the following disclaimer. - - 2. Redistributions in binary form must reproduce the above copyright - notice, this list of conditions and the following disclaimer in the - documentation and/or other materials provided with the distribution. - - 3. The names of its contributors may not be used to endorse or promote - products derived from this software without specific prior written - permission. - - THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS - "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT - LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR - A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR - CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, - EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, - PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR - PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF - LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING - NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS - SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. - - - Any feedback is very welcome. - http://www.math.sci.hiroshima-u.ac.jp/~m-mat/MT/emt.html - email: m-mat @ math.sci.hiroshima-u.ac.jp (remove space) -*/ - -/* initializes mt[N] with a seed */ -void init_genrand(unsigned long s); - -/* initialize by an array with array-length */ -/* init_key is the array for initializing keys */ -/* key_length is its length */ -/* slight change for C++, 2004/2/26 */ -void init_by_array(unsigned long init_key[], int key_length); - -/* generates a random number on [0,0xffffffff]-interval */ -unsigned long genrand_int32(void); - -/* generates a random number on [0,0x7fffffff]-interval */ -long genrand_int31(void); - -/* These real versions are due to Isaku Wada, 2002/01/09 added */ -/* generates a random number on [0,1]-real-interval */ -double genrand_real1(void); - -/* generates a random number on [0,1)-real-interval */ -double genrand_real2(void); - -/* generates a random number on (0,1)-real-interval */ -double genrand_real3(void); - -/* generates a random number on [0,1) with 53-bit resolution*/ -double genrand_res53(void); - -/* macro to quickly get random double from range [a,b) - added by Maxim Yurkin */ -#define genrand(a,b) (genrand_int32()*(1.0/4294967296.0)*((b)-(a))+(a)) diff --git a/src/os.h b/src/os.h deleted file mode 100644 index 6de078eb..00000000 --- a/src/os.h +++ /dev/null @@ -1,24 +0,0 @@ -/* FILE: os.h - * AUTH: Maxim Yurkin - * DESCR: determines which operation system is used - * - * Copyright (C) 2006-2008 University of Amsterdam - * This code is covered by the GNU General Public License. - */ -#ifndef __os_h -#define __os_h - -/* If neither WINDOWS nor POSIX is found, some parts of the program, such as precise timing and - * file locking, will fail to compile - */ -#ifdef _WIN32 -# define WINDOWS -# include // all windows functions need this -/* this list is not exhaustive. gcc always defines __POSIX__ on POSIX-compliant systems, - * however other compilers do not necessarily do the same. You may define it manually - */ -#elif defined(__POSIX__) || defined(unix) || defined (__unix) || defined (__unix__) -# define POSIX -#endif - -#endif // __os_h diff --git a/src/param.c b/src/param.c index ed5b7bad..a493d4f8 100644 --- a/src/param.c +++ b/src/param.c @@ -3,7 +3,7 @@ * DESCR: Initialization, parsing and handling of input parameters. * Also printout general information. Contains file locking routines. * - * Copyright (C) 2006-2008 University of Amsterdam + * Copyright (C) 2006 M.A. Yurkin and A.G. Hoekstra * This code is covered by the GNU General Public License. */ #include @@ -12,8 +12,10 @@ #include #include #include -#include -#include "os.h" +#ifdef _WIN32 /* Windows */ +# include +#endif + #include "io.h" #include "const.h" #include "comm.h" @@ -21,198 +23,155 @@ #include "crosssec.h" #include "fft.h" #include "param.h" -#include "cmplx.h" -#include "function.h" -#include "parbas.h" -// definitions for file locking +/* definitions for file locking */ #ifdef USE_LOCK -# ifdef WINDOWS -# define FILEHANDLE HANDLE -# elif defined(POSIX) -# include -# include -# ifdef LOCK_FOR_NFS -# include // for error handling of fcntl call -# endif -# define FILEHANDLE int -# else -# error *** Unknown operation system. Creation of lock files is not supported. *** -# endif -# define LOCK_WAIT 1 // in seconds -# define MAX_LOCK_WAIT_CYCLES 60 +# ifdef _WIN32 /* Windows */ +# define FILEHANDLE HANDLE +# else /* UNIX - may depend on which exactly */ +# include +# include +# include /* for error handling of fcntl call */ +# define FILEHANDLE int +# endif +# define LOCK_WAIT 1 /* in seconds */ +# define MAX_LOCK_WAIT_CYCLES 60 #else -# define FILEHANDLE int +# define FILEHANDLE int #endif -// GLOBAL VARIABLES +/* GLOBAL VARIABLES */ -opt_index opt; // main option index +opt_index opt; /* main option index */ -// SEMI-GLOBAL VARIABLES +/* SEMI-GLOBAL VARIABLES */ -// defined and initialized in crosssec.c +/* defined and initialized in crosssec.c */ extern const char avg_string[]; -// defined and initialized in GenerateB.c -extern const char beam_descr[]; -// defined and initialized in make_particle.c +/* defined and initialized in make_particle.c */ extern const int volcor_used; extern const char sh_form_str[]; -extern const int gr_N; -extern const double gr_vf_real; -extern const double mat_count[]; - -// used in CalculateE.c -int store_int_field; // save full internal fields to text file -int store_dip_pol; // save dipole polarizations to text file -int store_beam; // save incident beam to file -int store_scat_grid; // Store the scattered field for grid of angles -int calc_Cext; // Calculate the extinction cross-section - always do -int calc_Cabs; // Calculate the absorption cross-section - always do -int calc_Csca; // Calculate the scattering cross-section by integration -int calc_vec; // Calculate the unnormalized asymmetry-parameter -int calc_asym; // Calculate the asymmetry-parameter -int calc_mat_force; // Calculate the scattering force by matrix-evaluation -int store_force; // Write radiation pressure per dipole to file + +/* used in CalculateE.c */ +int store_int_field; /* save full internal fields to text file */ +int store_scat_grid; /* Store the scattered field for grid of angles */ +int calc_Cext; /* Calculate the extinction cross-section - allways do */ +int calc_Cabs; /* Calculate the absorption cross-section - allways do */ +int calc_Csca; /* Calculate the scattering cross-section by integration */ +int calc_vec; /* Calculate the unnormalized asymmetry-parameter */ +int calc_asym; /* Calculate the asymmetry-parameter */ +int calc_mat_force; /* Calculate the scattering force by matrix-evaluation */ +int store_force; /* Write radiation pressure per dipole to file */ int phi_int_type; /* type of phi integration (each bit determines - * whether to calculate with different multipliers) - */ -// used in calculator.c -int avg_inc_pol; // whether to average CC over incident polarization -char alldir_parms[MAX_FNAME]; // name of file with alldir parameters -char scat_grid_parms[MAX_FNAME]; // name of file with parameters of scattering grid -// used in crosssec.c -double prop_0[3]; // initial incident direction (in laboratory reference frame) -double incPolX_0[3],incPolY_0[3]; // initial incident polarizations (in lab RF) -int ScatRelation; // type of formulae for scattering quantities -// used in GenerateB.c -int beam_Npars; -double beam_pars[MAX_N_BEAM_PARMS]; // beam parameters -// used in io.c -char logname[MAX_FNAME]=""; // name of logfile -// used in iterative.c -double eps; // relative error to reach -// used in make_particle.c -int shape; // particle shape definition -int sh_Npars; // number of shape parameters -double sh_pars[MAX_N_SH_PARMS]; // storage for shape parameters -int sym_type; // how to treat particle symmetries -double sizeX; // size of particle along x-axis -double dpl; // number of dipoles per lambda (wavelength) -double lambda; // incident wavelength (in vacuum) -int jagged; // size of big dipoles, used to construct a particle -char shape_fname[MAX_FNAME]; // name of file, defining the shape -char save_geom_fname[MAX_FNAME]; // geometry file name to save dipole configuration -char shapename[MAX_LINE]; // name of the used shape -int volcor; // whether to use volume correction -int save_geom; // whether to save dipole configuration in .geom file -opt_index opt_sh; // option index of shape option used -double gr_vf; // granules volume fraction -double gr_d; // granules diameter -int gr_mat; // domain number to granulate -double a_eq; // volume-equivalent radius of the particle -int sg_format; // format for saving geometry files -int store_grans; // whether to save granule positions to file - -// LOCAL VARIABLES - -static char run_name[MAX_WORD]; // first part of the dir name ('run' or 'test') -static char avg_parms[MAX_FNAME]; // name of file with orientation averaging parameters -static char *exename; // name of executable (adda, adda.exe, adda_mpi,...) -static int Nmat_given; // number of refractive indices given in the command line -// structure definitions + whether to calculate with different multipliers) */ +/* used in calculator.c */ +int PolRelation; /* type of polarization relation */ +int avg_inc_pol; /* whether to average CC over incident polarization */ +char alldir_parms[MAX_FNAME]; /* name of file with alldir parameters */ +char scat_grid_parms[MAX_FNAME]; /* name of file with parameters of scattering grid */ +/* used in crosssec.c */ +double prop_0[3]; /* initial incident direction (in laboratory reference frame) */ +double incPolX_0[3],incPolY_0[3]; /* initial incident polarizations (in lab RF)*/ +int ScatRelation; /* type of formulae for scattering quantities */ +/* used in GenerateB.c */ +int beamtype; /* type of incident beam */ +double beam_w0,beam_x0,beam_y0,beam_z0; /* beam properties (microns) */ +/* used in io.c */ +char logname[MAX_FNAME]=""; /* name of logfile */ +/* used in iterative.c */ +double eps; /* relative error to reach */ +/* used in make_particle.c */ +int shape; /* particle shape definition */ +int sh_Npars; /* number of shape parameters */ +double sh_pars[MAX_N_SH_PARMS]; /* storage for shape parameters */ +int NoSymmetry; /* do not use particle symmetries */ +int symmetry_enforced; /* enforce use of all symmetries; suppresses NoSymmetry */ +double sizeX; /* size of particle along x-axis */ +double dpl; /* number of dipoles per lambda (wavelength) */ +double lambda; /* incident wavelength (in vacuum) */ +int jagged; /* size of big dipoles, used to construct a particle */ +char aggregate_file[MAX_FNAME]; /* name of aggregate file */ +char save_geom_fname[MAX_FNAME]; /* geometry file name to save dipole configuration */ +char shapename[MAX_LINE]; /* name of the shape used */ +int volcor; /* whether to use volume correction */ +int save_geom; /* whether to save dipole configuration in .geom file */ +opt_index opt_sh; /* option index of shape option used */ + +/* LOCAL VARIABLES */ + +static char run_name[MAX_WORD]; /* first part of the dir name ('run' or 'test') */ +static char avg_parms[MAX_FNAME]; /* name of file with orientation averaging parameters */ +static char *exename; /* name of executable (adda or adda.exe) */ + /* structure definitions */ struct subopt_struct { - const char *name; // name of option - const char *usage; // how to use (argument list) - const char *help; // help string - const int narg; /* possible number of arguments; UNDEF -> should not be checked; - * may contain also some special negative codes, like FNAME_ARG - */ - const int type; // type of suboption + const char *name; /* name of option */ + const char *usage; /* how to use (argument list) */ + const char *help; /* help string */ + const int narg; /* possible number of argumetns ; UNDEF -> should not be checked */ + const int type; /* type of suboption */ }; struct opt_struct { - const char *name; // name of option - void (*func)(int Narg,char **argv); // pointer to a function, that parse this parameter - int used; // flag to indicate, if the option was already used - const char *usage; // how to use (argument list) - const char *help; // help string - const int narg; // possible number of arguments; UNDEF -> should not be checked - const struct subopt_struct *sub; // suboptions + const char *name; /* name of option */ + void (*func)(int Narg,char **argv); /* pointer to a function, that parse this parameter */ + int used; /* flag to indicate, if the option was allready used */ + const char *usage; /* how to use (argument list) */ + const char *help; /* help string */ + const int narg; /* possible number of argumetns ; UNDEF -> should not be checked */ + const struct subopt_struct *sub; /* suboptions */ }; -// const string for usage of ADDA -static const char exeusage[]="[- [] [- ]...]]"; -/* initializations of suboptions; should be 'NULL terminated' - * each row contains: suboption name, usage string, help string, number of arguments - * (UNDEF = not checked automatically), identifier (number) - */ + /* initializations of suboptions; should be 'NULL terminated' */ +static const char exeusage[]="[- [] [- []...]]"; static const struct subopt_struct beam_opt[]={ - {"plane","","Infinite plane wave",0,B_PLANE}, - {"lminus"," [ ]","Simplest approximation of the Gaussian beam. The beam " - "width is obligatory and x, y, z coordinates of the center of the beam are optional " - "parameters (all in um). By default beam center coincides with the center of the " - "computational box.",UNDEF,B_LMINUS}, - {"davis3"," [ ]","3rd order approximation of the Gaussian beam (by Davis). " - "The beam width is obligatory and x, y, z coordinates of the center of the beam are " - "optional parameters (all in um). By default beam center coincides with the center of the " - "computational box.",UNDEF,B_DAVIS3}, - {"barton5"," [ ]","5th order approximation of the Gaussian beam (by Barton). " - "The beam width is obligatory and x, y, z coordinates of the center of the beam are " - "optional parameters (all in um). By default beam center coincides with the center of the " - "computational box. This option is recommended for the description of the Gaussian beam.", - UNDEF,B_BARTON5}, - {NULL,NULL,NULL,0,0} + {"plane","","Infinite plane wave",0,B_PLANE}, + {"barton1"," ", + "Gaussian beam by Barton, 1st order. The width and x, y, z coordinates \n"\ + "of the center of the beam must be specified (all in um).",4,B_BARTON1}, + {"barton3"," ", + "Gaussian beam by Barton, 3rd order. The width and x, y, z coordinates \n"\ + "of the center of the beam must be specified (all in um).",4,B_BARTON3}, + {"barton5"," ", + "Gaussian beam by Barton, 5th order. The width and x, y, z coordinates \n"\ + "of the center of the beam must be specified (all in um).",4,B_BARTON5}, + {"davis1"," ", + "Gaussian beam by Davis, 1st order. The width and x, y, z coordinates \n"\ + "of the center of the beam must be specified (all in um).",4,B_DAVIS1}, + {"davis3"," ", + "Gaussian beam by Davis, 3rd order. The width and x, y, z coordinates \n"\ + "of the center of the beam must be specified (all in um).",4,B_DAVIS3}, + {"lminus"," ", + "Gaussian beam by 'L-' approximation. The width and x, y, z coordinates \n"\ + "of the center of the beam must be specified (all in um).",4,B_LMINUS}, + {NULL,NULL,NULL,0,0} }; static const struct subopt_struct shape_opt[]={ - {"axisymmetric","","Axisymmetric homogeneous shape, defined by its contour in " - "ro-z plane of the cylindrical coordinate system. Its symmetry axis coincides with the " - "z-axis, and the contour is read from file.",FNAME_ARG,SH_AXISYMMETRIC}, - {"box","[ ]","Homogeneous cube (if no arguments are given) or a rectangular " - "parallelepiped with edges x,y,z.",UNDEF,SH_BOX}, - {"capsule","","Homogeneous capsule (cylinder with half-spherical end caps) with cylinder " - "height h and diameter d (its axis of symmetry coincides with the z-axis).",1,SH_CAPSULE}, - {"coated"," [ ]","Sphere with a spherical inclusion; outer sphere has " - "a diameter d (first domain). The included sphere has a diameter d_in (optional position " - "of the center: x,y,z).",UNDEF,SH_COATED}, - {"cylinder","","Homogeneous cylinder with height (length) h and diameter d (its axis of " - "symmetry coincides with the z-axis).",1,SH_CYLINDER}, - {"egg"," ","Axisymmetric egg shape given by a^2=r^2+nu*r*z-(1-eps)z^2, where 'a' is " - "scaling factor. Parameters must satisfy 0 ","Homogeneous general ellipsoid with semi-axes x,y,z",2,SH_ELLIPSOID}, - {"line","","Line along the x-axis with the width of one dipole",0,SH_LINE}, - {"rbc"," ","Red Blood Cell, an axisymmetric (over z-axis) biconcave " - "homogeneous particle, which is characterized by diameter d, maximum and minimum width h, " - "b, and diameter at the position of the maximum width c. The surface is described by " - "ro^4+2S*ro^2*z^2+z^4+P*ro^2+Q*z^2+R=0, ro^2=x^2+y^2, P,Q,R,S are determined by the " - "described parameters.",3,SH_RBC}, - {"read","","Read a particle geometry from file ",FNAME_ARG,SH_READ}, - {"sphere","","Homogeneous sphere",0,SH_SPHERE}, - {"spherebox","","Sphere (diameter d_sph) in a cube (size Dx, first domain)", - 1,SH_SPHEREBOX}, -/* TO ADD NEW SHAPE - * add a row here, before null-terminating element. It contains: - * shape name (used in command line), usage string (what command line parameters can be used - * for this shape), help string (shown when -h option is used), possible number of float parameters, - * shape identifier (constant defined in const.h). Instead of number of parameters UNDEF can be - * used (if shape can accept variable number of parameters, then check it explicitly in - * function InitShape) or FNAME_ARG (if the shape accepts a single string argument with file name). - * Number of parameters should not be greater than MAX_N_SH_PARMS (defined in const.h). It is - * recommended to use dimensionless shape parameters, e.g. aspect ratios. - */ - {NULL,NULL,NULL,0,0} + {"box","","Homogenous cube (edges along the axes)",0,SH_BOX}, + {"coated"," [ ]", + "Sphere with a spherical inclusion; outer sphere has a diameter d (first domain).\n"\ + "The included sphere has a diameter d_in (optional position of the center: x,y,z).", + UNDEF,SH_COATED}, + {"cylinder","", + "Homogenous cylinder with height (length) h and diameter d (its axis of symmetry\n"\ + "coincides with the z-axis).",1,SH_CYLINDER}, + {"ellipsoid"," ","Homogenous general ellipsoid with semi-axes x,y,z",2,SH_ELLIPSOID}, + {"line","","Line along the x-axis with the width of one dipole",0,SH_LINE}, + {"rbc"," ", + "Red Blood Cell, an axisymmetric (over z-axis) biconcave homogenous particle,\n"\ + "which is characterized by diameter d, maximum and minimum width h, b, and\n"\ + "diameter at the position of the maximum width c.",3,SH_RBC}, + {"read","","Read a particle geometry from file ",1,SH_READ}, + {"sphere","","Homogenous sphere",0,SH_SPHERE}, + {"spherebox","", + "Sphere (diameter d_sph) in a cube (size Dx, first domain)",1,SH_SPHEREBOX}, + {NULL,NULL,NULL,0,0} }; -// EXTERNAL FUNCTIONS - -// GenerateB.c -void InitBeam(void); - -//======================================================================== -// declarations of parsing functions; definitions are given below. defines are for conciseness +/*========================================================================*/ + /* declarations of parsing functions; definitions are given below. + defines are for conciseness */ #define PARSE_NAME(a) parse_##a #define PARSE_FUNC(a) void PARSE_NAME(a)(int Narg,char **argv) #define PAR(a) #a,PARSE_NAME(a),FALSE PARSE_FUNC(alldir_inp); -PARSE_FUNC(anisotr); PARSE_FUNC(asym); PARSE_FUNC(beam); PARSE_FUNC(chp_dir); @@ -224,10 +183,8 @@ PARSE_FUNC(Csca); PARSE_FUNC(dir); PARSE_FUNC(dpl); PARSE_FUNC(eps); -PARSE_FUNC(eq_rad); -PARSE_FUNC(granul); PARSE_FUNC(grid); -PARSE_FUNC(h) ATT_NORETURN; +PARSE_FUNC(h); PARSE_FUNC(int); PARSE_FUNC(iter); PARSE_FUNC(jagged); @@ -237,7 +194,6 @@ PARSE_FUNC(maxiter); PARSE_FUNC(no_reduced_fft); PARSE_FUNC(no_vol_cor); PARSE_FUNC(ntheta); -PARSE_FUNC(opt); PARSE_FUNC(orient); PARSE_FUNC(phi_integr); PARSE_FUNC(pol); @@ -246,1465 +202,1123 @@ PARSE_FUNC(prop); PARSE_FUNC(save_geom); PARSE_FUNC(scat); PARSE_FUNC(scat_grid_inp); -PARSE_FUNC(sg_format); PARSE_FUNC(shape); PARSE_FUNC(size); -PARSE_FUNC(store_beam); -PARSE_FUNC(store_dip_pol); PARSE_FUNC(store_force); -PARSE_FUNC(store_grans); PARSE_FUNC(store_int_field); PARSE_FUNC(store_scat_grid); PARSE_FUNC(sym); PARSE_FUNC(test); -PARSE_FUNC(V) ATT_NORETURN; PARSE_FUNC(vec); PARSE_FUNC(yz); -/* initialization of options, their usage and help; - * each row contains: PAR(option name),usage string, help string, number of arguments - * (UNDEF = not checked automatically),pointer to suboption (if exist) - */ + /* initialization of options, their usage and help */ static struct opt_struct options[]={ - {PAR(alldir_inp),"","Specifies a file with parameters of the grid of scattering " - "angles for calculating integral scattering quantities.\n" - "Default: " FD_ALLDIR_PARMS,1,NULL}, - {PAR(anisotr),"","Specifies that refractive index is anisotropic (its tensor is limited to be " - "diagonal in particle reference frame). '-m' then accepts 6 arguments per each domain. " - "Can not be used with CLDR polarizability and all SO formulations.",0,NULL}, - {PAR(asym),"","Calculate the asymmetry vector. Implies '-Csca' and '-vec'",0,NULL}, - {PAR(beam)," [...]","Sets a type of the incident beam. Four other float arguments " - "must be specified for all beam types except 'plane'. These are the width and x, y, z " - "coordinates of the center of the beam respectively (all in um).\n" - "Default: plane",UNDEF,beam_opt}, - {PAR(chp_dir),"","Sets directory for the checkpoint (both for saving and loading).\n" - "Default: " FD_CHP_DIR,1,NULL}, - {PAR(chp_load),"","Restart a simulation from a checkpoint",0,NULL}, - {PAR(chp_type),"{normal|regular|always}", - "Sets type of the checkpoint. All types, except 'always', require '-chpoint'.\n" - "Default: normal",1,NULL}, - {PAR(chpoint),"