pax_global_header00006660000000000000000000000064150277305770014527gustar00rootroot0000000000000052 comment=c7f6c2c3ff144b46d4674a4903444f1485144003 bim-1.1.8/000077500000000000000000000000001502773057700123055ustar00rootroot00000000000000bim-1.1.8/.hgignore000066400000000000000000000014231502773057700141100ustar00rootroot00000000000000syntax: regexp # The recurrent (^|/) idiom in the regexps below should be understood # to mean "at any directory" while the ^ idiom means "from the # project's top-level directory". (^|/).*\.dvi$ (^|/).*\.pdf$ (^|/).*\.o$ (^|/).*\.oct$ (^|/).*\.octlink$ (^|/)octave-core$ (^|/)octave-workspace$ (^|/).*\.tar\.gz$ ## Our Makefile target ^target/ ## Files generated automatically by autoconf and the configure script ^src/aclocal\.m4$ ^src/configure$ ^src/autom4te\.cache($|/) ^src/config\.log$ ^src/config\.status$ ^src/Makefile$ ^src/.*\.m$ # e.g. doc/faq/OctaveFAQ.info # doc/interpreter/octave.info-4 ^doc/.*\.info(-\d)?$ ^doc/\w*/stamp-vti$ ^doc/\w*/version\.texi$ # Emacs tools create these (^|/)TAGS$ (^|/)semantic.cache$ # Other text editors often create these (^|/)~.* bim-1.1.8/COPYING000066400000000000000000000430771502773057700133530ustar00rootroot00000000000000 GNU GENERAL PUBLIC LICENSE Version 2, June 1991 Copyright (C) 1989, 1991 Free Software Foundation, Inc. Everyone is permitted to copy and distribute verbatim copies of this license document, but changing it is not allowed. Preamble The licenses for most software are designed to take away your freedom to share and change it. By contrast, the GNU General Public License is intended to guarantee your freedom to share and change free software--to make sure the software is free for all its users. This General Public License applies to most of the Free Software Foundation's software and to any other program whose authors commit to using it. (Some other Free Software Foundation software is covered by the GNU Library General Public License instead.) You can apply it to your programs, too. When we speak of free software, we are referring to freedom, not price. Our General Public Licenses are designed to make sure that you have the freedom to distribute copies of free software (and charge for this service if you wish), that you receive source code or can get it if you want it, that you can change the software or use pieces of it in new free programs; and that you know you can do these things. To protect your rights, we need to make restrictions that forbid anyone to deny you these rights or to ask you to surrender the rights. These restrictions translate to certain responsibilities for you if you distribute copies of the software, or if you modify it. For example, if you distribute copies of such a program, whether gratis or for a fee, you must give the recipients all the rights that you have. You must make sure that they, too, receive or can get the source code. And you must show them these terms so they know their rights. We protect your rights with two steps: (1) copyright the software, and (2) offer you this license which gives you legal permission to copy, distribute and/or modify the software. Also, for each author's protection and ours, we want to make certain that everyone understands that there is no warranty for this free software. If the software is modified by someone else and passed on, we want its recipients to know that what they have is not the original, so that any problems introduced by others will not reflect on the original authors' reputations. Finally, any free program is threatened constantly by software patents. We wish to avoid the danger that redistributors of a free program will individually obtain patent licenses, in effect making the program proprietary. To prevent this, we have made it clear that any patent must be licensed for everyone's free use or not licensed at all. The precise terms and conditions for copying, distribution and modification follow. GNU GENERAL PUBLIC LICENSE TERMS AND CONDITIONS FOR COPYING, DISTRIBUTION AND MODIFICATION 0. This License applies to any program or other work which contains a notice placed by the copyright holder saying it may be distributed under the terms of this General Public License. The "Program", below, refers to any such program or work, and a "work based on the Program" means either the Program or any derivative work under copyright law: that is to say, a work containing the Program or a portion of it, either verbatim or with modifications and/or translated into another language. (Hereinafter, translation is included without limitation in the term "modification".) Each licensee is addressed as "you". Activities other than copying, distribution and modification are not covered by this License; they are outside its scope. The act of running the Program is not restricted, and the output from the Program is covered only if its contents constitute a work based on the Program (independent of having been made by running the Program). Whether that is true depends on what the Program does. 1. You may copy and distribute verbatim copies of the Program's source code as you receive it, in any medium, provided that you conspicuously and appropriately publish on each copy an appropriate copyright notice and disclaimer of warranty; keep intact all the notices that refer to this License and to the absence of any warranty; and give any other recipients of the Program a copy of this License along with the Program. You may charge a fee for the physical act of transferring a copy, and you may at your option offer warranty protection in exchange for a fee. 2. You may modify your copy or copies of the Program or any portion of it, thus forming a work based on the Program, and copy and distribute such modifications or work under the terms of Section 1 above, provided that you also meet all of these conditions: a) You must cause the modified files to carry prominent notices stating that you changed the files and the date of any change. b) You must cause any work that you distribute or publish, that in whole or in part contains or is derived from the Program or any part thereof, to be licensed as a whole at no charge to all third parties under the terms of this License. c) If the modified program normally reads commands interactively when run, you must cause it, when started running for such interactive use in the most ordinary way, to print or display an announcement including an appropriate copyright notice and a notice that there is no warranty (or else, saying that you provide a warranty) and that users may redistribute the program under these conditions, and telling the user how to view a copy of this License. (Exception: if the Program itself is interactive but does not normally print such an announcement, your work based on the Program is not required to print an announcement.) These requirements apply to the modified work as a whole. If identifiable sections of that work are not derived from the Program, and can be reasonably considered independent and separate works in themselves, then this License, and its terms, do not apply to those sections when you distribute them as separate works. But when you distribute the same sections as part of a whole which is a work based on the Program, the distribution of the whole must be on the terms of this License, whose permissions for other licensees extend to the entire whole, and thus to each and every part regardless of who wrote it. Thus, it is not the intent of this section to claim rights or contest your rights to work written entirely by you; rather, the intent is to exercise the right to control the distribution of derivative or collective works based on the Program. In addition, mere aggregation of another work not based on the Program with the Program (or with a work based on the Program) on a volume of a storage or distribution medium does not bring the other work under the scope of this License. 3. You may copy and distribute the Program (or a work based on it, under Section 2) in object code or executable form under the terms of Sections 1 and 2 above provided that you also do one of the following: a) Accompany it with the complete corresponding machine-readable source code, which must be distributed under the terms of Sections 1 and 2 above on a medium customarily used for software interchange; or, b) Accompany it with a written offer, valid for at least three years, to give any third party, for a charge no more than your cost of physically performing source distribution, a complete machine-readable copy of the corresponding source code, to be distributed under the terms of Sections 1 and 2 above on a medium customarily used for software interchange; or, c) Accompany it with the information you received as to the offer to distribute corresponding source code. (This alternative is allowed only for noncommercial distribution and only if you received the program in object code or executable form with such an offer, in accord with Subsection b above.) The source code for a work means the preferred form of the work for making modifications to it. For an executable work, complete source code means all the source code for all modules it contains, plus any associated interface definition files, plus the scripts used to control compilation and installation of the executable. However, as a special exception, the source code distributed need not include anything that is normally distributed (in either source or binary form) with the major components (compiler, kernel, and so on) of the operating system on which the executable runs, unless that component itself accompanies the executable. If distribution of executable or object code is made by offering access to copy from a designated place, then offering equivalent access to copy the source code from the same place counts as distribution of the source code, even though third parties are not compelled to copy the source along with the object code. 4. You may not copy, modify, sublicense, or distribute the Program except as expressly provided under this License. Any attempt otherwise to copy, modify, sublicense or distribute the Program is void, and will automatically terminate your rights under this License. However, parties who have received copies, or rights, from you under this License will not have their licenses terminated so long as such parties remain in full compliance. 5. You are not required to accept this License, since you have not signed it. However, nothing else grants you permission to modify or distribute the Program or its derivative works. These actions are prohibited by law if you do not accept this License. Therefore, by modifying or distributing the Program (or any work based on the Program), you indicate your acceptance of this License to do so, and all its terms and conditions for copying, distributing or modifying the Program or works based on it. 6. Each time you redistribute the Program (or any work based on the Program), the recipient automatically receives a license from the original licensor to copy, distribute or modify the Program subject to these terms and conditions. You may not impose any further restrictions on the recipients' exercise of the rights granted herein. You are not responsible for enforcing compliance by third parties to this License. 7. If, as a consequence of a court judgment or allegation of patent infringement or for any other reason (not limited to patent issues), conditions are imposed on you (whether by court order, agreement or otherwise) that contradict the conditions of this License, they do not excuse you from the conditions of this License. If you cannot distribute so as to satisfy simultaneously your obligations under this License and any other pertinent obligations, then as a consequence you may not distribute the Program at all. For example, if a patent license would not permit royalty-free redistribution of the Program by all those who receive copies directly or indirectly through you, then the only way you could satisfy both it and this License would be to refrain entirely from distribution of the Program. If any portion of this section is held invalid or unenforceable under any particular circumstance, the balance of the section is intended to apply and the section as a whole is intended to apply in other circumstances. It is not the purpose of this section to induce you to infringe any patents or other property right claims or to contest validity of any such claims; this section has the sole purpose of protecting the integrity of the free software distribution system, which is implemented by public license practices. Many people have made generous contributions to the wide range of software distributed through that system in reliance on consistent application of that system; it is up to the author/donor to decide if he or she is willing to distribute software through any other system and a licensee cannot impose that choice. This section is intended to make thoroughly clear what is believed to be a consequence of the rest of this License. 8. If the distribution and/or use of the Program is restricted in certain countries either by patents or by copyrighted interfaces, the original copyright holder who places the Program under this License may add an explicit geographical distribution limitation excluding those countries, so that distribution is permitted only in or among countries not thus excluded. In such case, this License incorporates the limitation as if written in the body of this License. 9. The Free Software Foundation may publish revised and/or new versions of the General Public License from time to time. Such new versions will be similar in spirit to the present version, but may differ in detail to address new problems or concerns. Each version is given a distinguishing version number. If the Program specifies a version number of this License which applies to it and "any later version", you have the option of following the terms and conditions either of that version or of any later version published by the Free Software Foundation. If the Program does not specify a version number of this License, you may choose any version ever published by the Free Software Foundation. 10. If you wish to incorporate parts of the Program into other free programs whose distribution conditions are different, write to the author to ask for permission. For software which is copyrighted by the Free Software Foundation, write to the Free Software Foundation; we sometimes make exceptions for this. Our decision will be guided by the two goals of preserving the free status of all derivatives of our free software and of promoting the sharing and reuse of software generally. NO WARRANTY 11. BECAUSE THE PROGRAM IS LICENSED FREE OF CHARGE, THERE IS NO WARRANTY FOR THE PROGRAM, TO THE EXTENT PERMITTED BY APPLICABLE LAW. EXCEPT WHEN OTHERWISE STATED IN WRITING THE COPYRIGHT HOLDERS AND/OR OTHER PARTIES PROVIDE THE PROGRAM "AS IS" WITHOUT WARRANTY OF ANY KIND, EITHER EXPRESSED OR IMPLIED, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE. THE ENTIRE RISK AS TO THE QUALITY AND PERFORMANCE OF THE PROGRAM IS WITH YOU. SHOULD THE PROGRAM PROVE DEFECTIVE, YOU ASSUME THE COST OF ALL NECESSARY SERVICING, REPAIR OR CORRECTION. 12. IN NO EVENT UNLESS REQUIRED BY APPLICABLE LAW OR AGREED TO IN WRITING WILL ANY COPYRIGHT HOLDER, OR ANY OTHER PARTY WHO MAY MODIFY AND/OR REDISTRIBUTE THE PROGRAM AS PERMITTED ABOVE, BE LIABLE TO YOU FOR DAMAGES, INCLUDING ANY GENERAL, SPECIAL, INCIDENTAL OR CONSEQUENTIAL DAMAGES ARISING OUT OF THE USE OR INABILITY TO USE THE PROGRAM (INCLUDING BUT NOT LIMITED TO LOSS OF DATA OR DATA BEING RENDERED INACCURATE OR LOSSES SUSTAINED BY YOU OR THIRD PARTIES OR A FAILURE OF THE PROGRAM TO OPERATE WITH ANY OTHER PROGRAMS), EVEN IF SUCH HOLDER OR OTHER PARTY HAS BEEN ADVISED OF THE POSSIBILITY OF SUCH DAMAGES. END OF TERMS AND CONDITIONS How to Apply These Terms to Your New Programs If you develop a new program, and you want it to be of the greatest possible use to the public, the best way to achieve this is to make it free software which everyone can redistribute and change under these terms. To do so, attach the following notices to the program. It is safest to attach them to the start of each source file to most effectively convey the exclusion of warranty; and each file should have at least the "copyright" line and a pointer to where the full notice is found. Copyright (C) This program is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free Software Foundation; either version 2 of the License, or (at your option) any later version. This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details. You should have received a copy of the GNU General Public License along with this program; if not, see . Also add information on how to contact you by electronic and paper mail. If the program is interactive, make it output a short notice like this when it starts in an interactive mode: Gnomovision version 69, Copyright (C) year name of author Gnomovision comes with ABSOLUTELY NO WARRANTY; for details type `show w'. This is free software, and you are welcome to redistribute it under certain conditions; type `show c' for details. The hypothetical commands `show w' and `show c' should show the appropriate parts of the General Public License. Of course, the commands you use may be called something other than `show w' and `show c'; they could even be mouse-clicks or menu items--whatever suits your program. You should also get your employer (if you work as a programmer) or your school, if any, to sign a "copyright disclaimer" for the program, if necessary. Here is a sample; alter the names: Yoyodyne, Inc., hereby disclaims all copyright interest in the program `Gnomovision' (which makes passes at compilers) written by James Hacker. , 1 April 1989 Ty Coon, President of Vice This General Public License does not permit incorporating your program into proprietary programs. If your program is a subroutine library, you may consider it more useful to permit linking proprietary applications with the library. If this is what you want to do, use the GNU Library General Public License instead of this License. bim-1.1.8/DESCRIPTION000066400000000000000000000006531502773057700140170ustar00rootroot00000000000000Name: bim Version: 1.1.8 Date: 2025-06-28 Author: Carlo de Falco, and others Maintainer: Carlo de Falco Title: PDE Solver using a Finite Element/Finite Volume approach Description: Package for solving Diffusion Advection Reaction (DAR) Partial Differential Equations Depends: octave (>= 3.8.0), fpl, msh Url: https://github.com/carlodefalco/bim Autoload: no License: GPLv2+ Tracker: https://github.com/carlodefalco/bim/issues bim-1.1.8/INDEX000066400000000000000000000022661502773057700131050ustar00rootroot00000000000000BIM >> BIM - Diffusion Advection Reaction PDE Solver Matrix assembly bim1a_advection_diffusion bim1a_advection_upwind bim1a_axisymmetric_advection_diffusion bim1a_axisymmetric_advection_upwind bim2a_advection_diffusion bim2a_advection_upwind bim2a_axisymmetric_advection_diffusion bim2a_axisymmetric_advection_upwind bim3a_advection_diffusion bim3a_osc_advection_diffusion bim1a_laplacian bim1a_axisymmetric_laplacian bim2a_laplacian bim2a_axisymmetric_laplacian bim3a_laplacian bim3a_osc_laplacian bim1a_reaction bim1a_axisymmetric_reaction bim2a_reaction bim2a_axisymmetric_reaction bim3a_reaction bim1a_rhs bim1a_axisymmetric_rhs bim2a_rhs bim2a_axisymmetric_rhs bim3a_rhs bim2a_boundary_mass bim2a_axisymmetric_boundary_mass bim3a_boundary_mass Pre-processing and Post-processing computations bim2c_mesh_properties bim3c_mesh_properties bim2c_unknowns_on_side bim3c_unknowns_on_faces bim2c_pde_gradient bim3c_pde_gradient bim2c_global_flux bim3c_global_flux bim1c_elem_to_nodes bim2c_tri_to_nodes bim3c_tri_to_nodes bim2c_intrp bim3c_intrp bim1c_norm bim2c_norm bim3c_norm Utilities bimu_bernoulli bimu_logm bim-1.1.8/NEWS000066400000000000000000000036431502773057700130120ustar00rootroot00000000000000Summary of important user-visible changes for bim 1.1.6: ------------------------------------------------------------------- ** Avoid complex conjugate when changing array shape in bim2a_reaction and bim2a_rhs. Summary of important user-visible changes for bim 1.1.5: ------------------------------------------------------------------- ** Improvement of the functions for stiffness matrix assembly in 2D axisymmetric configuration. Summary of important user-visible changes for bim 1.1.4: ------------------------------------------------------------------- ** Added new functions for cylindrical coordinates in axisymmetric configuration. ** Fixed some bugs in 1d upwind discretization. Summary of important user-visible changes for bim 1.1.3: ------------------------------------------------------------------- ** Added new projection functions. ** A function for the generation of 3D boundary matrices has been added that can be used in the implementation of Robin boundary condition and interface conditions. ** Added a set of functions for the computation of inf, L2 and H1 norms of piecewise constant and elementwise constant functions. Summary of important user-visible changes for bim 1.1.2: ------------------------------------------------------------------- ** Fixed a bug in 1d upwind discretization. ** Added function to compute gradient of a 3d scalar field. Summary of important user-visible changes for bim 1.1.1: ------------------------------------------------------------------- ** Added new functions to perform interpolation at arbitrary nodes. Summary of important user-visible changes for bim 1.1.0: ------------------------------------------------------------------- ** Added new functions implementing the Orthogonal Subdomain Collocation method in 3D. ** More functions for 3d problems were added. ** Demostrations of how to use the package are now in the wiki. bim-1.1.8/README000077700000000000000000000000001502773057700146662DESCRIPTIONustar00rootroot00000000000000bim-1.1.8/doc/000077500000000000000000000000001502773057700130525ustar00rootroot00000000000000bim-1.1.8/doc/fiume.geo000066400000000000000000000011061502773057700146510ustar00rootroot00000000000000Point (1) = {0, 0, 0, 0.1}; Point (2) = {1, 1, 0, 0.1}; Point (3) = {1, 0.9, 0, 0.1}; Point (4) = {0, 0.1, 0, 0.1}; Point (5) = {0.3,0.1,-0,0.1}; Point (6) = {0.4,0.4,-0,0.1}; Point (7) = {0.5,0.6,0,0.1}; Point (8) = {0.6,0.9,0,0.1}; Point (9) = {0.8,0.8,0,0.1}; Point (10) = {0.2,0.2,-0,0.1}; Point (11) = {0.3,0.5,0,0.1}; Point (12) = {0.4,0.7,0,0.1}; Point (13) = {0.5,1,0,0.1}; Point (14) = {0.8,0.9,0,0.1}; Line (1) = {3, 2}; Line (2) = {4, 1}; CatmullRom(3) = {1,5,6,7,8,9,3}; CatmullRom(4) = {4,10,11,12,13,14,2}; Line Loop(15) = {3,1,-4,2}; Plane Surface(16) = {15}; bim-1.1.8/doc/tutorial.html000066400000000000000000000060361502773057700156100ustar00rootroot00000000000000

This is a short example on how to use bim to solve a DAR problem.
The data for this example can be found in the doc directory inside the bim installation directory.

Create the mesh and precompute the mesh properties
The geometry of the domain was created using gmsh and is stored in the file fiume.geo

[mesh] = msh2m_gmsh("fiume","scale",1,"clscale",.1);
[mesh] = bim2c_mesh_properties(mesh);

Construct an initial guess
For a linear problem only the values at boundary nodes are actually relevant

xu     = mesh.p(1,:).';
yu     = mesh.p(2,:).';
nelems = columns(mesh.t);
nnodes = columns(mesh.p);
uin    = 3*xu;

Set the coefficients for the problem: -div ( \alpha \gamma ( \eta \nabla u - \beta u ) )+ \delta \zeta u = f g

epsilon = .1;
alfa    = ones(nelems,1);
gamma   = ones(nnodes,1);
eta     = epsilon*ones(nnodes,1);
beta    = xu+yu;
delta   = ones(nelems,1);
zeta    = ones(nnodes,1);
f       = ones(nelems,1);
g       = ones(nnodes,1);

Construct the discretized operators
AdvDiff = bim2a_advection_diffusion(mesh,alfa,gamma,eta,beta);
Mass    = bim2a_reaction(mesh,delta,zeta);
b       = bim2a_rhs(mesh,f,g);
A       = AdvDiff + Mass;

To Apply Boundary Conditions, partition LHS and RHS
The tags of the sides are assigned by gmsh

Dlist = bim2c_unknowns_on_side(mesh, [8 18]); 	   ## DIRICHLET NODES LIST
Nlist = bim2c_unknowns_on_side(mesh, [23 24]); 	   ## NEUMANN NODES LIST
Nlist = setdiff(Nlist,Dlist);
Fn    = zeros(length(Nlist),1);           	   ## PRESCRIBED NEUMANN FLUXES
Ilist = setdiff(1:length(uin),union(Dlist,Nlist)); ## INTERNAL NODES LIST

Add = A(Dlist,Dlist);
Adn = A(Dlist,Nlist); ## shoud be all zeros hopefully!!
Adi = A(Dlist,Ilist); 

And = A(Nlist,Dlist); ## shoud be all zeros hopefully!!
Ann = A(Nlist,Nlist);
Ani = A(Nlist,Ilist); 

Aid = A(Ilist,Dlist);
Ain = A(Ilist,Nlist); 
Aii = A(Ilist,Ilist); 

bd = b(Dlist);
bn = b(Nlist); 
bi = b(Ilist); 

ud = uin(Dlist);
un = uin(Nlist); 
ui = uin(Ilist); 

Solve for the displacements

temp = [Ann Ani ; Ain Aii ] \ [ Fn+bn-And*ud ; bi-Aid*ud];
un   = temp(1:length(un));
ui   = temp(length(un)+1:end);
u(Dlist) = ud;
u(Ilist) = ui;
u(Nlist) = un;

Compute the fluxes through Dirichlet sides

Fd = Add * ud + Adi * ui + Adn*un - bd;

Compute the gradient of the solution

[gx, gy] = bim2c_pde_gradient(mesh,u);

Compute the internal Advection-Diffusion flux

[jxglob,jyglob] = bim2c_global_flux(mesh,u,alfa,gamma,eta,beta);

Save data for later visualization

fpl_dx_write_field("dxdata",mesh,[gx; gy]',"Gradient",1,2,1);
fpl_vtk_write_field ("vtkdata", mesh, {}, {[gx; gy]', "Gradient"}, 1);

bim-1.1.8/docs/000077500000000000000000000000001502773057700132355ustar00rootroot00000000000000bim-1.1.8/docs/assets/000077500000000000000000000000001502773057700145375ustar00rootroot00000000000000bim-1.1.8/docs/assets/bim.png000066400000000000000000000304561502773057700160240ustar00rootroot00000000000000PNG  IHDR pHYs.#.#x?vtEXtSoftwareAdobe ImageReadyqe< IDATxy\}}ྂP(SEb3YY93'<g %%G:LNg286IKD*EZ$J$.@7v}ޝ?^uuUuU}zwWҥK.]tҥK.]tҥK.]tҥK.]tҥK.]tҥK.]tҥK.].ÃDEUq[?|GN+|SbByXz1F[[;xAp>YNIxKJy Ƈh~nrr0=<,#\S}GϮɍ_vC,\⸎~f&Ol]B=A^fIl2/RC]^>};~K Bp:ly.^Q&fd 4⸢i&ڇ籋U|5SOl$LrbKpG_8@OO(CKH)3M/|W.~ˁ-}4Bmy;۬Uy$R&#O21!"+%3B;6OȂ>E.v !!DO  (RY8qD2 r$fM>(R7v+w (RJ %LNGH5 0ms\;Y8 $u+ؼ̈́e7;zm6 ဟްpPKz=EwOᣑ*k&z?x=c!M vkY.Y:H0Rűlw~~|cƀn܋T -%}'QQPu0[f YGj;keMe!>!֍K $09-dtY_1HޑuMӢ֓`:R Ŝn۬"V[íᨗf{   QIQUũ|xbٚ ^я5| A"ߞؽN\N܃T:[%FJ"AǀE{\t@zb׮((&) !ӈBz~|^7fi &#q≒5AfgFw).vJyz'bw1 ƇSCm8\JL,L# ";☆~o2?6X-f6vnbH)IgLbqLq峫(VQϿmٮ<.E xe6M}#.=u󇮇\Mۨ=[a2-s0~.29w>([ )ut Zo"AlM`4]5' D+ϽrCng? Xz>5L/ wcdSUBdm&J8+żbj6TX)s:snyP!F&w[t?>MP)ӳ\2H⸮G+OkyE!NC <.gˆitUxQN}r]/[(YO?tA.M $WdD`.%|m.e^ oZmIlYٽ ~Oygcq"d9MQc;wݺQjeD.Y`B}/GʝuoKd?#薰Gtqd[ovvlـp~/_غqE~څLaxLf$,lO? f9Vv'6(DbQf#Q344Ho 2L~H,QJG{iKs}ٽkl.KDc1"(Xl:ILfn7}=aza?5y3󓟝$5wI_Ci.fw]7VM,i "(ht*eA2'Zf3`ޞz!\Ngג&9_RTj$ѯ>x`xPHǟ \M3fFu≤!XT" ji$Z\N'=aaBK3Y><{1RJ$RCʯ?w]H⣳RR>ٿltMSokvY+m+Y nMtr Umقe9nCO(Ͷy7Ţʱɹ1kϿtb-/+ }sk-m[FqK&%ňEmJB !{wƧ39^}$38>t]_kvYAK۶iݻnf]$ƈQ&ZZ-Z, = %w輙`6'?;1ǁD7{||)ׯ//??[尳;8֤P,ƈqr,* bY x.z{z k6\/)K SRSiIM_* LK۱y& AdiF@*1LFSrɺ]x'+KKG.u+#/4[N+߂8"ķ&Qvy.{[3KGtD9HRIGR 8RXP:jJR{s̅^)57`VL;ln TLJ"F2]v j$T" }۱SU5N E__2}۾Flf@ݥrT*M)%'?8KR /-ebFjGn ^;xf63f騚ڷhNNmZkBY.\¥+WIR躎fCY6U88s\Ӻq߫nA}>l İɤoϭx] g *TD2C"Cold1}^zzd\WvR-Pȹv۪O6&۟--Cu` z zJI$3SY27RJ8XOFFX,BFK)9Ls$Sk Αv۪Z}(`߶,?XHS,lAa1^J1L,!ܑnmaiU,!Pv*s޷Ὰk^UHs;̖w:7R; }nB>7~"t}|A(H'kU3w|!^ؾ!;7ϖ+X2C*osy.,R)^=1KDUU?nߞml$o#㴱wϭMVi:tx҈]J_Ff-Y!%V/ExニH9=sS+.mSOl9- .!vʥ jY,trUFb&unk/?:{;?{bտ iQJwnqnY|}hN:'2b\k%fU#\xko.ehn>BluкJҩb4'3y\^Ysc;!mV=t;K ]@9"{Ca/;)"UsWg>5:Aa\98 x,m矲t[?mÊT^B8m3vnn9wm˓KjDt6/B6zM?#{A{DX&|΍87o{{R]*Bh62C,ys< &.]IEvb4%Ynoy;%q;u=scկ6  0 7ߔ@ELkd3Z'%(Nm06`l&nRH:bVJi,ڢX,^ig&QAp =>\nJH \)D'yK@JI2d1"Lt#x_AW0dl"LIUV3ak-ocR:˻\彑1gގAGs#p|s]{^iʯ+[D.z} _1/&WPM}v,ϝ?s1 ,&~3w`vl$se*΅Dfԑ|,%!ts?:%mG1rmlR,NUjp, xt4ïX7K=2۶T …\IraݺoWMC:[dK1f*QH)@AOC=zg?un2/ Pkiyc 9ϫŏ 3 A$N32*H!5X!F%-pu*ƥ(3Lը(B?9u.h{}; OJɗ|Al2) Z[L<͏~a[\LLAɤOo]WL8&LUMRJ)R7Es{勢Uwc@*/ įK)88"!"us›.r;حBpql{`;aw;\qq]7܈ѫu7\; j~J,e ;c|S4M-X#jV(6Ig^xydѾVѱ౛Ml BMkDbg.Os4v"6.9{b*BTFA?:@ՖڝL`DBQ-&,fo|8ѠoSQN P $Q49 "M !{ x:\WKKn:af8ht\A vݲ\BIc l^ۆ"LnQv3lAJTMhD*&,NŹ:G^?z}xYzd2)bUBn3 T^KTNBQX͊a)n[)2xԵ:D nC}H^^MxV%ReTDHHw\%q8:E,2I0cXʆF6|4fo3}[z#_T6D-f^~ێV>^ÿ[g.;H0fBn $:tHH^H DH"xư}~>WGTN 9E:QNJnn"63R<c"?i]קPԸ6xD]Kw̻OuQs$(BTl鱓DREfE2y_a53T#|W=n+.y-|jQ1d#V%U}k-fQ iDk0=^;}~;A S@{9⨸p^#yѹz¨W`5 6v4]'VID%3Ig^{}܎W3-VL l ̒ͫ>?};u3>x8ZQ(V)L wW)}IDATڗCG*$& ]J"3"UGJgg1|.;}s[VYEP|F^Q%ka"V ;øKkU5'\NPT6ʢZ<LEoV/$AۊdNe&Q`6Y S0*I<#~>8KA~oDT&թ8GynZ/t*:8u%K~qf_wKòTMg|6Wul1)Jo(+,7}3oXFWi細E13(=\3g8syP^au}3W7<h,F1a&0,ã=U+klKQ.OZ{N֊Vf*{qVkADo]>1zI,F݌nfcE^ՙMN䉥H c.E0)>z|kUC ~iwL`6UDJ8UN&gS\fk8E@cg#a65wjeQt@\n|r7:gmr2tjTxHV Nǹ:G-a/#9vU}˿,مƽ\1pڊJNkŬ(-zX#f|tD7L,88tI$U`:g&='?1̉f65^UGpT@^P1X1É)?rݨY㵤cҞ~띫o-*udxH#.01ȓ+ъ%C{\_~{i^٤p/Wgs.OU֫Q/MnWV [fBpm2$IfUKb)j:}~;qn;onke_񔐢UIVJG`⋹-Z\ti봲m@Ή\Sw[oXoszUcJ((Y"ω݊z{+R[z9]HWu}ZfY1έj,|/+G+x"E4+T% h`E9yΥZYſ;U-Hg*I3UUVa9T_8?^ :H *bl Drɿkojwj(eM" Y>^ht0Y"^rjY_.ҏkA*XvXFVZN QYClkʨ]a5 ,^V&>4ycTyrGƎʶ@_E/ ~ysyҥZJ`+ހ =SVIGr4#F:,5*:0\^-q4c}Z+Qo&Ra,ݞ߮/kֻKㅖe  si\ W|XՉVXropRiL/xa_zkCgh,s7^|+bVl7؏W(b2k*D\ Q?Z9i`-u_fYu.?8$ }`K( q+cuYo.~вTw-HUU2[,OZՈ/.Y{R+a7gbpW0KOIaPj 2y0-1iBO_xnYyK"DuYӁ?baPdVʬLwm^[sJGM7o$04WP,0sgݧV<7{Zүbq߯c ՂX[RE+ ~sʭFr*^Yʛom^QCܜΉ/|yxCmc`r7.d?XX^%śqm^h3=iiRsͻWcطY+?{iOzM<5eZI3VQWvY[Hw!Bk#cX`:;XZ4jjo +X=;ԤORfyfy a&uZ*\0:1XXPFK*Vf{]yP$9_Ͽ4~UJ~(W4ZY )'9u)D4KQ* Ҁ鋝uc+zubZSNzQyΘ+ڬyW.=̗6dc^yxУޭJe/p`-:,,]Vz|vz|v\vsn*TWFy[6!uPc3YA]*!J,5l4ߤݟ= O'g>}bģ@@H*O$̵8.NAm,< f5WBWGt2 BqgrΎ.7_X2l$DQ(%UWZg-ג9oi{%<`*bRzl}v{o>^Y9iNbh4Wuρ'o{/%!uВPZt$ 55M}2ҹ"$IiruW{yc]CoMJP<jM!wsuZ}u#7:תrw8E)ԊC{28q(Lɒ$>6Nb|b&C}a4{<301d<"-o%Q|,яJTotj֝@jy=ND#D_mDAIc/ l ݥF Hw85Q,V»QJA3ƈMƐUDV&c $y&)g3 .औRt/¥:{TmN QgAc/i_̟[Zz@Xق^SW Rw H=G.$>6A|l4jVӱ4\,R+<.d5xtU\J 5oݱEW>awpsbssWX㺹o1B;AP#%ij>GbrqcIׯX M׉rLDRL̦ruFJ]5_| ̍,*zbfs`q âf1\ω2cm㋥cVGQcl&%vuصqR33HMV#+25t,MfcPRGL#S/cGrCbθ-W^U$!xl\x:MUߌ0+@e;>^lv\p=M3IpROG'WuӛVrS nD > Xept8*gyhfU $Hk+~#KHfeA& kƥ√~GGϭj_E; pM=Rg/B<ru\>A}[ I^ޅI,jA~Xt,d$d,M6Od8D\xV@(ٽ;n$RF{e!t3ts;+Ij/zuI43D4MA;}RK`@ЍeCQW sDh*t4T,C<_0OJ)#O#kS8t<~a>rF}.a[C{r&lxxb>(ѢG/;,f뜮@֐Cng#BOH-_NLL,(~:[ C8JɭۥI+QSRFrMO/]\۽i Cލ]XC5<=9}tҥK.]tҥK.]tҥK.]tҥK.])IENDB`bim-1.1.8/docs/assets/bim2a_laplacian_101.png000066400000000000000000010037321502773057700206320ustar00rootroot00000000000000PNG  IHDReIDATxu\@^\KTThK(RZ$xGnz9}sO9av癙ggYDo .?888888/}4 qppppp~_p?iO~888888/}4 qppppp~_p?iO~888888/}4 qppppp~_p?iO~wל8qbΝ>vw|<򛎧tfQ*`kkwDe8pL&:t r=:w{H$رw88888駿~zi1cFpp]yoBѿׯĿD888888y'Oep'7{YǏ@ǎ[hgVV}888888a444ą eOO޸q UVV֦Mpppppp;T*J5k]1ׯ_@׮]̖#>}dffw"11+Wh <. ο ?-_ yud2&88بTM"ի:ꓛiXWWgjjj VZUUUVVV쨨i9߿Դ,OÛ*؄*T...F?n޼رM6D"wttCH$T-eeevvv(V$5ˆǖ-[H2JOJJkjj8Ktyyy07 ]r(%E闊CA3uAg*6l}+x⢨A,T$[9M,ML.aL B//T:cbIrH.Ąx+U̜`}:aYXs7sTs4ˆbr^qXʶ+TFGbV۲k]+ۏ4cx 9wk8~ Ʉ5m4>]zxᆸBRߠAԅb UȎ /19qB4 |i;v lӦ̈́ ;&JeBrKC׋v In\rMv4ucM|wѐ]M|MBDYv؟24 p,DYqdd6| ׋v 90us&vhC7e|7 9F"|zѐ>]h"ˎ8c95yUwQ-h)ߍFEY xry).XKnYH~zrD"S?D)͔I@7#!^s$a(3(ٽFЃatnO:GYZ`rʹܞ>k9 w 0BA>>s47#DGDoOJ\9$Owv $!;V=6.{mDw0A7A:Icbw`O HnnA S,2SY7!<@"gkC31<*aZ[|7: ;m9/8[$2z)z܌piNk)*З`Of[ :%_ }va%bmmECerPRL5d83^1%A0-d2r)]+:zӍwu/;vྌQ$&>H$bb,sxpބّ@:ӝc oOLQё4s3F [ͶQH|H 0 wMҗӡ y`5Qwc`v<ڌH7" Ble%2 1mR[(ZHpV̷jߚ>o9 :;N[ز*wק%Illȑ#޽[\\,ɄBwvգG%JmJrmO,(7<`\U.saѻ8`}}h{||8b}Hk|yuk.Wz1|#gj\?!۳m}" St79Mj1V]0&46645yrBӟl8rG b~x8`M'@rJآSɍ{h:n =y~qb7B2s˫Q]#֖PP-ضq ƒn^6/6:YÅnՃˬ]Աfd+'lw(^Zb݆gFΡ'K399y?`(/_O0sYE }G <&t5-C,SxgY'O325O TDffoObv i_yC}[h 62ff¯o,%فlœk6CT36ϗ ٖUV+Xն7Z)mv2Q6.{YO_a.PRUf_k4'.2e~y1X$;pgO6{yA?#ֆPضq[h E?Y}Ѧ='";p,zxf׫M]=9T3-M;Zx}EYˬIfZ2Ө±31'F/q{!ٗ|s65%X5O|a3w(t~[@uKxn8{uY͞=Y^i u}[8s&?fO!+_ڵ9 sʆL~z޴R?'ف`y-;9:Ӝf%q(LZ^ߴSVZݽ`p|("Cg^6ՁewaLs7 MܴsI s0;FGJ>7ّ\PZuT:xqp&űQ3-O;tȟs2$7-t,hA:F[+ 6D}+zxaԬŢ? ZXz`%C 'Oغa^"~*PeeIP0(iٍobTUh{g7YTԪJUU[c(-Si3jU8̈́J~A惤sUzdds8\$Rk4@qNob~@+f]bT6Ɂt縉BF:W5*@,@#Vk%-F1P8*vlP*őkcM<{ΔI(A*`䥼tRtvoJ^>ϢOw/Ů[jپ5;߄4H4<ҹ)Ny!Y/+)N Ԏ ւUZAwdFkm- qI=i,,Vm*)‰؛RiP;rVcn\n k`0ntN+$ibYĢwd(*թ48pgM1_kջٓ;S\{LE)غ]k:T9r}kKbx݆]5P]֊]6עC4ȵ$V*[p]ya|E첊7N4QTkV=h1ua%A J 7SUQYY Pm@Kv TVs`'ͭ@;!;a>բE gtu^^^^^^M!4t:ZRDBPkiB"qN-R?@-#L] yd?Y=z4nDDFL-kO*)AW_nGhR3w<}EJC i򃙙Y?/^3f̿p A%FjP;z(Usm{v1OB5L;څ.l@?ʈAةODd'ϮAUVv].+8ZF2GL.!|Hzb˞%/׉܌:lQjn5s 7JE޺`}/im3`P6= ğ9ނû6k^wpt jpBؔlTgL%,WX4 m;s6q+3[2׼nGN.t iÓ22UB!eNm5{x+4YF}4u=SھvG 6mT΍;k|}A,͢)/Tg̫_]l}ի/eǘ6~Rl G% tŸum*u}gn꼊#{_|#9wcP4O(?#vr+䡓铘MOmK{F3\1E;߇s=VNmڧIK9yxO,Sjenncl"/OrOZ9:Ex-C\\ǠA~aYYYYYYֲiWǭ&wTe)s+:-~+Eк%[t+LI\\a)Y2cO2P݉Uj+!uKA]k-s'/t.ƕYV(p=E.E;7Y2j{qżGq@fl^_(8b1tZ1y]m6q,Pf5 3[~1|f7v9ol֢x:ϲrD[B;[7 n=w _ڨeT|pvÈIWԙ8lޭ'W&7Z TZz$+*1FES4^mZXX /69cz/)eJO17Oa-dGt)SHׁՊ+6,YU,ꬫ6L+/{=ӱAuP)S4f3$`avŗw+oخřN8<.&vҁf)&ӿ\BEyT![ԈFާ$Tq }gɩ2SNANO,.ŵ"ui=:1߹_/!z}wfu.+ ]0b',} >EDg6E:oޯ8Ǵ^6b8aSՖ{kwM fM1c/j\y~8Sǂ;QZB$ae: L V/{..?ı1a $}#K~Wp8lTӐ 1qQzfj=BKmt]j?f΅#_a ?n+Ȓ{jcUkVE p;j]lnė,='H"U ض:sϮ˾WuTV'>k` Ǝd~M3L .]eKK[naIs ­'ͩ9<úxı`L'7+tvoй4h$YMGԳ+|r]۞!Nm\iymF$dFg:KԽ8q՛CbCݺ7nl^ Ρu$UٗUNfZŒIN7Vّ&Up~;{O0|x&gƿtܥΎbIH[C>7q,<}{e;8\cpbxO_6;GQъ4~VW-6߸$w k`+~sKM6| Ϝ9u֝;w^zU -K>ɪ 9ƫqwgN25q,̶|5P%ЎVs~^U@I{ nU#;4ցV/ڵon*L9]:Қ4xVR^;t@3h\*E۱Y".>$A[D XXƽ:Aco664q,=4N$g-!/ݠkU9D/2ٺ*'9.g V/6q k, }|bB)65#cW fN2ޱ2}:;J3V/~陸BqjwT`tCwwLaGMnBa.\lC64F;_QmP{0c3_?{TB]DAw', =8GGa]?>g_naTڅf٩rC)y.Vg%٩buwR[Ϣ +-n]iZOp];h.&)\"yxㆳgգ^sHxΧ/eg979:wPHw:xM~ l;Y5!;8X$s9JH5i_řNC^jhP SawhӒvRݻ nI;uA\Xt'i"i<)ϊYYSLBC:r}@9#ۑt|9aQWl{i[ODjGGR?۾TPY:%M`2 ّDr! J5c$<%1mhhid3S’Fv4k!枓S56t2Pm'ʄBU'e`̎ $lFau&$ig-ZlIV՛k ͐X薴DW*qˎ; ;1QټV\1|A T7HԡAC915]&͘ޞtr]m1&*TW13Uժ?5w5egbE$^&FLM 1-qlПE^]5:3sL$)kȸryEXiI[4y6FxVBPjh2Ѿ5uΤZz ̎R&5]^RvU;m{kw>~v~y󦺺ϝ;?K*\غx{$^fwcfJ(,Rh?-(dOiIpa9ysrF9f!'ȻtKU*ޅMn$œXSk3S"h:5-X(DİPjjq5ZJ%iM54RxeJ=vi' Ci鲖bB]]݃鶮N#,SY[,- 朘 D&)MŎ@s<a̔babE"TE!#nuPecC^]M IDeoOоTi *PUT gDL*/obGieruգiJmmb%VNC;>%%+*$ba݂X Tf~}FbyJy5aVq"?jȲ'h@YJf{/ VW[W붼\mkiFb% bQ j ]YTHd\{{Iؔ_6Wo_o-ֺ޽ g eʼnﯫ˖-x/3ܺj/7!#+Lb;Q?y"QhWI- Wjݹ/:dTpL|/ݹբi6-FVd`eI@O1p n}5:Q*PѨw%L~Me⟗\;6s{tt(p_Y8phe}GW٦ZΞ|Ը+#ݻeMV(ϟ?~~Dk72Q?tVtwCT[! ǹkM~NZ4Nl?ph%ZSgꗬټ|k*ٳB?uH>[^iQ8TVhlm_ ^:P%l&ZO[dgPҷifAB]Sϙ_mTn={~uHe8޼۳ð/SF^:g(oB %o6 d/)qOEEDڲ\TsIpx9! i4̫nX}h,d*놣c\qMקodi y===tט1c>|RJJիWh4t `lra+?2cF,_j(زCwV^ʵp[P)Eg{j}P ]ʒ5ͅ0uV+4_aERT;GMQ™5ТE+ݪɟ'Y UN|Jnas3䉌N|a rri S[щ1mr0KuJ=][vlؼuX6l*w-XRMlY>Au}wU{ z.|uTR['ް!&qm] iWk@9tV ݇j}K vA3/rJt;%6l{lٹf|nVm>~@v>m:qZ(Tsb6Xc yEE*|o$!AF g*Jn6rڂ*=lؼ+u N `HddN UtKoޖ<b;z\ՇD9\Skmx$`%~Hqxzz |UWKOD^*Krw5vއDWbIlx7J9[Nv\1?|@NeuJNIk&̜SreTdf*b \`ٯk|&)a Y1ln?)Y#2~㑣9\v JqI`*KXfnrJ}p a'9DFIL?cS87ӝuM;ٰy7` Z _μvm~_}]8G-P~D}ϱB5kmxC6OmΛ__gނu_нo9tUw`t^S֝f~`iJxJ?ja6oU׶w+M.L&o߾"4Z`͛7s[2 [ B>e3V֛{5:{0b^Qqp5[vZ=dq-ػ&|(y)*u01!|,ϬKkMBnRۮSVbvԺi_Dlݹa;Ԇͻzҫac.X7ml4ׯ?ht@mF4u=y&A3oh~MWԠwB8^Хp^oabg޹a/l{t^Kd$LJi;d0pk`bB(uUͱb?h;Z C>ddŦm|c{G 8q s7/b %KlؼS簆`.35.v~iv z_8kw3lm Zg_TBjJOmGO]5Kjxxf:lXĆ͛0Ayv`+,NpVW{/_Փ^s<}{uW~8V ?~j_yHa֬29 5hߥՕt̯?ջE/ڮ^W_kEn۷B^%xXl浊žx.24ޮcfҌNy,^Z:A*(2.mD;wz~}WtJ۩UXT:j8¢Dkfڼ,wEFd(rK?ߢiN  r:tqڢ_ر]'ٓVݻaT*5~=Ӷo Xd03#4-(FCڶ6_Kfian,A͕dH$B_*cPZW"`\=&M`hljGA"@,ljH&#Fboқ MoD2dl6 1M.]lۋ 4UxӚݞӨT˖ib| $thO5*9lzX668sAH0.&Iޅ//8zq{Rl< BZ7{S?DB<= n" Fэ6{;C#-(l8Q 7{v7o~ʕ_橫kѢČxZ]^^~ 4:֌cbhfТ" .DRzQ&$ܮAԩPzT:Fow2غ͜W'm[뎟fA?q,(P&%ɇF7o6(60G8{?ZvŞd*~f)/5dd((s[ڜܭ+͢:z+#YomkLV RMfb='GyTZ [mìP(4&ۉ|)78~XVMf YzE&e)z;{buzTۇ5e׏Lի/_fMht{w%5jGb=|$B&7oש7KC={LMuwVC@ ʬ@` Vklmu-ycGLgpDoߒP7YB7?.2ĸ6m6׫ U,'bSޤj|'o'Od:L ϟK_<XU,.Q]8LnabZgIrt$+3:ieE &sY [`@RtFEO!S}tv<}A`4խ;fS3$"-fXEL5VV= .[}|0e!C0MbvG$6-fɘ؞=i .Ain`כY[&Lf--1;oO;d8_&nlFa |LعYHgǧq6$ LZngG%qYبSSt$&S8llu+ƌ3ڶvAPOL̰&^o6%AL3ǘp ZDwLnnĵڶM Bg1b0XF\]h)E6I15vN0-f)XݨT*f_XX7'G-- GNX0;FGSn̞Q^ 2sLUkFL&r7:4山!, k: !3>7Wi p~,YaڹNownKJ'Ma\ibI-LHlbh# 1*޿g|H[6ѻsgJ.1=srBˋ6#33?ǎ޼[ܭCG]8@69IfVÆUX!2*mRUF=Moǹ!n\׽kšc;vkrWҮil-]I/j #^PjX+V |j^]+1M"o-~溱cRҩ3YN!EmC(,9I~%N6. ) oeG.`/ig=er͊vfΕV0J6؀X. `{v(*<7Wko[7;" 7z` }SnC9{vqX.4mP#i׉5XP œ61Υ($$]8<޻S{P@JInaUg۷$Ev _T}  ܺukuuREEE'Nr=ibֹ }Ƞz ͑4ݎ*P j_$qv*<8B-mP pufԓ2R֬M볎 *[)K>م充9f_[|fY5ڔ;1*ح\Kc:R0E]~b7pY{<.[ĺ}SҳNd.wj HBR(4?~ڲW^ NP}ҕ$|˲P1.ަu4 iW<ΘVhYs v%d(Qg_&T7zz Y˥+L|SySݷv&`so6n1;tSxEݵ4<⭁a*#^wXqibaBֳ.t')Q\ڥ;Q5՗٧W+"V.X׼rhؐK׬nft.!#o(ΦKw3.*=#  sY=% EQw3!ˑ1Xᇎ[lbf`qLۼn\?}ϧl ӓg#m=H<Y̵ofa`hhƴmʾ=-˷4;pPvs)mM1[V&3 6_c.qㆺ^=*ܺ8szmC.\l{lIU7XZkpJG1q~>BSS$q{KMrӦMh4nz䉯c^^^vvB:m6"_9,/W={ڽxrɂkW ͣ̔i%9*pv*0JҞARk {>/{1vl{jj4W._Pk+Gs;uIݎܻܜPSA޼g5cJMXY(T%~:/O[^}|}NVvF5Nn܏ݹ|raOG% ZҴ*_yx_ {chɌF$JspРƞhS֬7=J5W9hA@@+A@ᄡ(6I֩ 4X9:?(̲wYqy ,)A+pnGʼ\ -ן)%sEQ̴)nݷJKTWkΙϼ|@@nA 9-[x -- IXz-jՕ)k>**XmjgOxx_{#g2n`;'%K<8}b:P(4CTmf01#M0AŪp9BCaBx@zuW-XyZ.+PuwmոRh#Ȗ R Y.$s/pRilB75q xMڣKi3Ө‚ Ub߱=ƆR^޺}]é766 Zաu|S(ݱl㺺fH%%G SUe֙Z[N9+7!TczjooRNHyu=6~O+a8^J 'KYZ&0y$"R&T7e'4yn.AkGOhsw+=zRިym0 tFHsL274 ݻ֭khhhz(""bƍ譭G&PAC"QTjZR)戨ӡ@ho) qt"K $h|sщX$@5J D"Th@JQllk"VUVkZ JCXƥU5N$DZVTӡFQ*‚P_oPJ  lZJщTVpND^B[;*X ֶR򗚱%j 6J0 LCf D,.T2+X`lGd i"T| oS3FmdG-6Ċ&H2HX v gWc HjF3sX4N.$>X3C%hF Tj58\ZFkV'VTQ{ԞN$nY ش&jg#u#bѦچCQ+J/:|ᅵw<_~o~@ D=zӧϿ](Jb1޼^<%>qY` w:e6KU9pZ7_|L~+Z4[lw ޾i񡋶'ں4nA|R4"0zH]H8%$2{6'&H8ɱ-<'Wdɬ)sf7zUhF_Z#i)MtF|掽3-E>v@v\PwkYھ }q?_cdžEJ~cVkjN09HOEVi|E#<{],(nef(]-WzL.U/le*{ʿ~yגwmmt3L׍nukaNqztL_>n8sHBKq*{wƘ$Nߥz/Jh;yLŰe1޿NfB`eM◨$] ^?SWwo=wL9`;5=I!vx2^e[X,wr5vocwhuf/HO0ˬRf*aȶgVieMyzQ*/j?2و`s U*A.0h?wh2٦ /;zO֙ =4̙3oݺÇw;vo߾{' ȱ=ş=AҙE#C7=]kَvKIUՍCw7x3|YN+T%۱vT}glk8:G[&oZ GVFb](Pꖔ({|ORټځMֶoG9?'{D=} rGPB(p]Gyt _QZ(Pm]' v}L͸vh!Txfyw:Ywb}3{BP7WTs)7~GIW}E-͞P9eDo{3G1K6X6@e]tKt:uKZ gVyKtڈ_9-r!șwq{ΔDٔeEC,xE*{oNjֱJ4;y/1ZXn gjо1yStb˚`WM˰/.ރWR|,?t6ܽ_ܳ.ȅn&3=UnQUr"ĕqΎfTo'!uHic*kqUzW^J]CThe=[jQ ^-҄e[yeZ`#șWnJ{@7%AμЪ>fNډucթ2u '"ԝ|~QB tj\SyVU˞-C'ɾWV-ЭL}umܫg ޞml7a_݊l=8a |n7 ru{!ș݉q!Њ;ڄV/ q7![k=9o׵)#*F@K?- /s+Vy}(9嚥sW[ݼ* r95 Ctvخf%(U]'ll"8{`c@vڣIJe;,q#Ǖތ?oy픹Aμ[ ã|f~@(S'!^ڿP?YUV}0m6<}nXf3/q{Ί2ՂgOS~iŒ\'9gOܾ6+{dlx}樸}s c\esw~P:E>d9EO^q@]j!Pl{%+ -ԍE/^˪G,Vy(fsphڨ [8ݯBNtheun6yρBΙbm4J0Qqj!@Z{Zͺ]VhثOY&k,MAѻεNNX5Ufdev׺#gD6L/0^~].r <}ˠYŎO,^g6D{hӗ_[ gy/6$ɑBoBFhtERx!cKT߸=R>q6[WnlN.VU\?9ؾBN};7ް4!6iןoN)i~gCVmsvx/[_B΅Swb=~8UVb{*b^˪{kab&p{1#|vr÷%ƥqݒwUFidjMU'G} ٙrFN2E/EFZ 7߻V߶-OυTKJp B\'ZaQ{"u.VeWYE:#]?JUV"GDcb-, I烙}MR]:YgfN=7.rMt^&Br ՀJ ٙ)UHLg"4TX$Kk $&HsA)r=?H D2@lJ1Px$GY~"qEʰ(Jf+Τq%=`jF3@ O`+6Nk<%ǕD`6O& B~A7 N]}Z M&)))FCL(wĜL)* ^(SU4d(O5{T 6ķ~Ap*jG* YJoOBun a Y1h41YXm^,RQZ|oՃJpoF~rށMF{t@ߡ̯zbG` Ҋ\_>4̗OQiHL6FQ\7kZV/Vn䨶XkB'9%ը܎wX>Q*-v,S(SU4T.W`cGVh7M)=RX@zk< LuJ4x_18X* r-14*c}`o'k*UZ}IGj ?s<|D&Q|ɤhCTm%I9(*m3H!(Vl[h}Cb hN#Fj GoDʢ<3EJJ5QL̈?Qt} Z!M% /;q"Zi $~X5Ǎ4 V^,W `Z9fK)deȤ x*qڎhDl,nJԩkT3  uJ3j@P(-Q:yPl ^&$Sw t\pLh*VZR #dw+AF/g^4p$ s MX 3ڢkZl\ "#v`fFDD >- PLc$Lձ7Ӹ!I7j8@Kv,&&!kFŮQjp=zGv2 WGu`7 I'RCgITi@Z4@W^!T`lnR-6A RM FjjT&Ev. JVhv=h}CͱzL/3BEnxâtz;7@B"#1|GmHΞܒ9e ,3`(,@ @ߑhej{s+wV^t7 Y`]s"qFYk>\ɴ u6%رI0uݾۮK&w.&ϸ>M]Wb{p5ӚmANU~3vy[XOr/>[F <];{pIӂuZ'{T'2;x*^W _hgau]͞f]h M,ɗ?]'*ߨ0mA7,XIC*n:Mwu٪;5 }>O\iDꛋx*./-=nvyhiϻ'~MjҌ #MKr>3N_[;dEݚ&~|Yup'K.>yiH>rk,#G;h0m]$\5Mp%v]=~Fv`\=^=gfǜ߽*ʔ# ;%Jd{gb53;]z9|&Xp\M7_vOsgk޹> WZgrVy?ӫ]O,!ma:헭rLNp3_p5ʞ gΰǫ|}0qݑn .jl87%19m}6C܌D! f~uy{Ǘ:;V+co;dZ,N¹%.Čݯ^aPn^?(P;nWnv8q lԦ?.j3|K΃r9"uW\;'ʕKFcS-U8;VVMYUv-s$k5NסM&aCP8;lx'6\zvtɭPjuh ʧ>5*G/Xa~_*֖y2]?}Di^6T,G%e*C+/x3oA ѱ6r\V({i4p;~N` h?y2I=}ún9}ZaK.Ӓt=S?E;3)}t\+f*5:kۻ匞g<- '9ބ9{D'^WUj@Au2νyfGϜo"S\ n/V>bXؐ.ʇz;+v.\qn '.ĽyM'~+8{Rd{K)Зp壧#o5<-;.9n-M,lBl_ԣ(YOp6CmpT[am-ڻ$<';^2mnZw3AgYKs]h<0,S觷6'ؾc ʟAѪCyY[_8602TyF@8v|V1g; 6LXl-9̎}dp'K?/I珒1;YU`dɮ.3DœzKLl qk19_i9R|4hb Hd{;{RКj`kɞCaJ7O N]nXWO;C_?-m)AX9(*_g};5՗Ӭu^IWUE[1=ڸ<8~:9az '9󷰚edz_e2tu=hh*adX_2[N1F.OQװgdl))Mg^kEXmOfęAo%nM>uqb| >{ hJx;3OQCL~(~⑇nz S1?7+k ԾP.PTl=h`PT~D S7hZSC[{tͽKqy>~^,gU J&=@\)[ژNvN9MYn;W*æ[_Mܳ@o1ϥIVl7-Z^׌~<&LXd{Yr?y4]s]h f]U5kG@ujp9XF~nXīǪ|: 0oZN| :xjz~EcyRkg\Mky?JP519݇Zs1K#*= 80d, ;Dzўx~8]_C%yZ@֝r L^fw)F#;eSTO;؎.N|kR_]a̎fht~HkƩvlO";0E!-lc{3 p JM{N^fGq(J 1p4AG!ĸ<ĖLJC2YD2H4 Ց:6ifp-: `t-bTA?F'ƥ%SK?фA$#T: ^#bIdՋ˂ia9IdD?ԂH~p:&qA6F Gm0:!@ FE7!PFԿK "@BX27@0m@ M~!cElp/N`1vS =[4-;FJ#5Vlӆ Ok*6H/֬Fv\A[#45'~%)B##;vkT3,ٸ=b0~p{5-bP=|(x: :K;>o:޻|}vuA\M>sب^AǺUilecָRfd# @934馷?N}-J7NW|yiT3MYڑejrCV&6&MhB0X8$Sz=[\*Ȃ9{\єcˋx TWqㅍW^~ƓfeOcV`w2Z]ƱҎl\ yiD[8hFgK>?vL\` J|^k0`}@Kl~B$1:l-uOlwt.JzqlTtn3$,8mp#5 [%Ȏȯ|ZY6=ƤL4}-[lPڮ#m[15=:S>q;ӌĠold㫊]no/T;4D3iF[^Ң{ݸwS*`̀v\7:wT贰$ݍcj9.񗷢IK3%4/e2w&g+;]3K/mӰLsGIqث/VfJukR/RZhj= O||H.m,J>)A^VIuUTBX7Art]7bwPr5W>Fg03rsP{0@mg0cALfh#Sk%]ZMMrѣGȵò&4_>0 ͳkfwuk]͏Uu>; ծ_$ۦpѣkgyvjl7,)V/ZMPn\?:n*aqv䃋vG 5>3)4g\*tsBD̓kGJ ˅je}D4kG8|o8ذ|`VQT$-vhqYA p 01#Ȳ"hi,;A;{Ym奋̪͗,U9W&QWΎ2ݔ=8]vjm1*/ˣ0Gy" v1f6DF<;gשOgk̍r/lGWnSkzQyRծWV O.UM"\%9[\>0+]]c :~s}f僲H}U'~?Lw$kg[ؑu l:ro324؊g+'훑N[ppa)oWidfjJh ]ɝFػ'-=‚ݱAm~1O;ڑ9yuvҰzhv)QhaG^3<-tdI+g+ JIT/z*SYmܔarpB-ɖ 1%l'hN} Q37ͽ(MuK|ZshQMͭIDDbpV6۟7ޗg0cDnatÝo\;(Ƒo~޹·L>P]YX>0+E{0s<4φUBkB)ՂzXeC84OΗ_x7 iuvsj@ ݨkG8z%J;w ]; ;Q9flxٿv?)ᄰ#;;uk.JX(2JNo˗njުGx~1 Cp}`NSvxy~]Haimͷ<MޛZ}<n@To>}[J}qmbzXώ|t|l4@_ZV&G}Ek[DNf0F9p#:cjcV^{s̬Hdd`'kuLWwGkn-y1˜54sO-1=bDʑ_Xn=oBt} lꨀ/ um6󎦆u>8h lBMHy%ZS!h +Y}?fq59sW:a^C:Xn~3Yg- +bP+":[i5y{fK [o|v䃓µ#0;)e)-JŶg>} rgo6a6ln':,2:;:eh7c_ZUig[QMh鎨ş^(eB'HU|_ۛ;>DT܎2:fLȽwkxQm2&lr-EazgdӚE~I[eDz8fkGd?8)<ٺ.cZ%g}׎>XuC>j~`{]-$Iv\gsY!-ē6Yqo*3uq5Cenj=ZUbwZ@'AFBqmnؑ]V_f z{b<<MG]ѵs^L4ulOWϖ\S|}h)ƻ^g_17şUQnYGS7˽Wp63p1Skn7.Oj,(V}k$jdo#<jz1qȼJCxy2+mb缯b 2)ȴX:xu{B@-vnFrd==yb W&U{3[肜݃7;7}P7q6{ OϪjST ook0b :Tud\G R3+-׷5 Z&UZAVv[a4au2i&=yhnN S 1/n,RИvl@ګ7_;$ a־f赜u 4 mPǝ/ը5;[q> 2)-9ӆ.tF5Z,"S SFK U)(S55kcˡb\ moݭq 'lpCoݝϯJMR w\ѫ\# rruP[ Z9l-P3!_JHD(j={j_荶2oYqob)n/.1,cVcգX@Bfr]=lIDATy{.M/2up;1;^Pv × gCN:  0x\Όli2 *|n4_C{snJ #;3cmrZ@t6fK*oZ=2>6*rUfd3L.,+|3Ȥf͙&;b?.+ƭX[Dz8Rh(tZ?-k|=y}g݄ͨqZ4_]ƨdN."`Oקj4Pl]LJ~qVQLhnaDRk^kfMvgU"H\v5Nli^Z-);< J}hz:`gJ\i QiK~MmuBH˃aT0i0+S+djll_%* H$\HP8R la[X3RKT.jG25XFC7p%jb)t"VHUNtZnJraiFRhF)ȥ*PR^(JFZ H*" 11r$^^'_@"vT*5fMk5R#kPYi:(0 h G.U+ w5-&s5,1"$pM[юvuI)(jVM kHIwZa{Q&Q*E;TY̖oC$<(\q 23*B'QpK[h@*VRh ㎢A4*-4'+ҲJQ{,& ;@i =¯:@B?~ o_`X CrĦh} 6R͵uC`_DN9"R䃁M%ZR (LgB,g.ͭ?2-єU?ouoςWZk#%l雼^9&snDi#>ؓn?^X`B@,Pyt6\T>f?6ͥՋy޷&t6Sm|SjǼO~o>;ZuwCE]fyTC4ga[ےڠ{&$M3襛;=˞qtH=#?O;#ªfy95Naɓ_7 jnx=yC7 䯟%>YsmVfVͿG}eǟ_p%9P7DaZ'kPQMt;IvtJn75wt{uL Gi\nfkMK+d0b{`ev5[W=\(I.Xy%"}N{a[ǚEZDaY# Z3*ן=f6̧M{I'K\?>hrhO {fiǡ\[eP5s_&H9+[E#Ļ?$|3--\[][7DW_> H!.,~}`6-`ȴ% JtowCr~ț#32`Y !WN{nRs|.oƥ}>ㅰ૮F:S<7uaQzb8*gNog93_'=n4/VT&ۖo'k/%6J^AXQ$)Mnk~q{9DqY]4͊6nYQ,]MX9q}Dm[B(3*/y97IźȄTє-VG->X\\}ycӿ^4"ce}]#Mp°&Voۯ{Ys}kku˺4=3?=kbwWy}z[Ŋ*غ3Wl4LN|>[=:;|yT1-l韲{ܔqS |fI9*?ܯn;5>rSuJ~yvhGf `}5?j4TuCCnjmkvZ1?{n7usERm|jN?iؘ{_4+oTlx2"C̪W%EY9/.-ye?ϒ<8B^oڦ0v~tsC|Z=IF:NN KZ54Ux{k}祭i*tZ A=pi]t䚎\/jļjXTk:H∄)vnXpFOQV^<7m/)cEnP𹦦t]0،=nIk;< zXohw"8rKZS`}R uŎ)WfOpwO\[w`P>W0F=.jv߸tX)hJ]`Jnr;1%3JUQQG}YV :@r~蛪R}j?&=͂u-3/F272a:[$*R񇰀)ۿwP:{-b> %:1,gߑ%r0~:{ ;kGfx{F6 @ ƔjhNXW휀E߰[swOxu~hbPm]?4 bZQu*͗^Ҹ6sTcSWe5Zd؛Z=eƅp4ޝkgnuZ6Lz۷N-YKEwڻkپ]g{N>aZl5rsd}k;,.ޚɊ4 IڌFOhj߱CRn׮-`>Td?w1-b_$WOm_+gtv @'97US%0},|۷?Woi`]i_;ۻcO*3.Gq{Y#lɒȄK|6)':Dti%ࡉo5shXОf u9m>hmt!qrcJǦ˧B1* b8VTHOV_Tokz GBw=+lp.^N'`SJǺ*=lfNk ;jWа-^I?U.VK=gY\GsByc\~ K~fw`noYء_lu; G]fD57K咧F*J?w-T?=Rh. 7JbKUbkմV8xήawdv l4Ɲ&Xٱ7ts![\>\QN2)cu\[Zŏ^ovo5VΛ>wKCU?X/{fԕ 7^_ܢL^V/,X4|L}뜝Tsy{ ߶cg~>xپuUrz,h6VuƤ8]#KX4@oO@ٱc- IJwwp?._{lNgooOS 򋱋-b<5pMt[&}U=k(h 6qNQ|o|)[8z ;!m/ʼ.{1ܚf^񪭍ni@!S zo,MӜ]fx,}}anФ}R7_GVQQ QIj5˥ fv<  ݌Ԭuan%[pF}یvNֻYTx(j2T 7j.;EeJDJnr݌L[B2 LPW D֠JJfZS[X3assaN!WQM43=2u}@BLm J딲z5H,ńF?\`1}'J,lČ$[8МQ ӌ4&ɫ3^^Lz:Ӓ!R= {E4{5y!E00b9`*9GPTT`@0E2Ðf֏L]-Rvn'+Q O SJ>zv|˥ * <{XNv&MV$jP0-(^, 4z?PQN\mS̻LK[ L )OĊlclE{á8X"L;cK*L|0k(Z*PE3"7c"wj{zT2Lu" GKgSTϤc?G˒4+25ÔB5 rL T />i4 DZsdFfޖnb8H} ѩBG̒FFkɴog&tfg4[R={+b*Fܨ1UsL2wk5p$ =LW~q-R#jPL*vbiN$2 L\W,j]1?EcgGzX|$WK7THխ'/ o?Ƒv?3{S}D!u++sai3;Ŗ|-Lp 89-_-VLY!7DZK$Pm*vxY(zZc%(컐W.bg5PHF;UըEun&&VT%6yz#ù+JS"ʤ >S8E\ :8Ғ<#JC"qI iRx v($Kj;[LtĶ(KjyvAv MlIUn#ӚT'툷\ ҐpB+OԌZᗶ7}D"f&xM/Ŏ Cv_^)̝5/ ?{i~;xVHŜʜ&XH|2Tj!nPהea;}VOpm7$͊߸_th.y¦q(ͫ'] e,I/z2`ۘ]]uO:,ܑ ֢O 傺bQ3Kz7?^- Ip4/IKAVt$|5#qom'+DOOzqfǸ+gvgcݲ_?[Ok487v .MLTHkL2D)I^7*3O͙KS@-'rz |;]Zs#z/X#S^ 1lȊUep7&m˅}Wvt.on9KlAWt2! qjЫ!ۻ?ʹ.{,[_ϒje,RUhcߟ5T )̜ݧ{ځc}'*\ZFîPȯmԛ%h)~|P>ڠ,z-=Rl|:y$i%C|gV1#n5x]~K=kKN zv YT_]rP+5kּalCT6wM:=:KHt}ynk%ǽ4XocwwEJ6eߘV^/ٟmD+)  |+^7Ex"K?d mɃ-/iG ?ryBb3ozYDdCIJJX'ٔ<J~μ1D-5`yթL7?_K8'bL[4|mK>p6e3-m2=ouӽ/S$|թA4U rp0YM\0PǿKX,Oܜ5=ү jUr2I]c6D?l$n>7 _V`kq>ksSǔ ƿs(pޗ=1t}aQO}BJW2%/7Lv~R8W`.qUD zO\ơ*~]cVut}zҏW՛:YG?s#f%*?\7ܙc8cEg0tI3) 2qۜ3=Vɭ fƔ[iŠx=[z.{= wȽ=ύLtPדP פ=Ӕns݌TnHܫ-}9PZ\]? G{ǥGc;)'ߟhcQ7fWd4\!k7x7i]6LOW~sMF:yR{izý^:/Oa[ƍ,ܐ H~ہ.x #zL>7ܔ0V.s-DXeIG/ү9؋ߍ{;V+ xaQ .ci ]ݜ2€0JC@X߱ns Nj=/^ &hryxG#^.iAK:;}WuvItsswevJQb֤\l9/Ez@OwgnOJ5[Z;ڹg">Xa=ύLtmrיlU0el6SwK_jg~s~ra GbUK7fOW'O4̊wl3gD 97?G3 Z?/f䣍_Bmv$ъw/MxWۘlo7{qK0{ݲlrC6EC=[3_rAm~,hN|rJ}`i]g{eJbY,Bgljs^|g nJeקMmeZ1buxǵIN' >g)oOǬICN xT 8sw=+$خKA}Wu |8_jcfng_(nSVc F=֌OG[˜צAL:녉#2iIZ E/ҥQ24j 7MWJ \r^d @Kg v>Z1;ZJ90tLXb5^`+?G:tW[?`eJP]{p9퍉-a1Mk?O1镥+SԄԵDwU-<ꍕ',HfG7k'VV?"g!N:JvŠ/ nOѪ*J%EBStY2)bKck:^+'_/fD N>SB4 o'7'?p4zc(Z6?}Wvjs Y>;$q{N7v l? I{o#ST)x:=KwYwٍk?5_fNU'F 쪒ka[gҙnǚa G8~oϤ8Z4!BU!h$}>ʷ&mR ;dp\M2jrŻ# (5修HA5B yfѿY}1pj {dɨu`X[-N ͼ=ׁR3v%mz5 bq)󣁗ǝ~3bݝֆrRB?cx!ifŒ[Wu-w*U ]}a1 EvU a+fĪdj"8AAn;d)ԣ_{lSnF7 svmt"h"9ȍ˸w@ݣ_ox/h} FjnCg=a%W4x36lci 8߾؂ǿbo kޚ_O1KA@;#-uxMnTܴ'S~>V]KO[J!Rt;4 D5UotLi ?p/xˌy/=/-HFMMOxMA\yD`T<Gcb)Ql(iRHاsW$|Yn+Vry֔H=Fj^$"0.Ǝ&$Fbɫ)0IxR̎O벹?-T똉ےW|f\ϛo{ϯG(nmjj!*6f⣟ EO?VAOy3qr4j>eɻ>NeYcHX∞Q ;7l 71v2| cûo}{xo7O=m9`)v> Xcق}n[u8/؇pV)rc*&l;ˢʏUOf>>X_!35LP9=/VT'դ3˚g}X6BžY6BOâD|w.ѥl(j}ˮӄihW38<~s{–^͈7>;AdEB\ez͉#zEU}Ƌ}6?(tnb~kߎ:߯"ɄmN`nv3ܜ>;-g-.hn<-qN~ ZtݟǾN{=\ s8Mea{#>[8+e>ks|4ir[}\ݛj37ٟr?ϟbiT;UatZ5gg]VbtÜ=ND9d#A%ac a{] =|gtq8-痴88k͜ϋ|d S~xbp}vxdX\wQs#JZ["<3y';ꁎ)𝩇7A-}jPVif~~F<֊g&ϧ0(ssoM[5@S#VXx9 k29>o^3ח ;?ƷCkk" v|3H!|9k|^H(yY3on .-(|&?#qB$EOvr DD98isoBG%ͳ>,012H!fZ^d6r>.Anh_<*LbR݇aeiTʤ %`5fGkc.'Nd*And-vF2PQǙT3r6ZĮ+7cv̹&7t?-g 1zY}*3rлpזe߳1@F"R08Z7JZIq N"]b Ȳfm,E:($3_[ *6Э1Mȴ*m(BN+jJ$#G=%2zw?+RX8]sWʠ)It\p\)$ NF#iL'&( *Tط PD*Q(50Vwl-˲C"ّD',h&B%o0-;ص®[k;jUj'V7IL<,M'ZШ4zY{C;Jj-Vh#_+y "-h@! i .5ca \IѫtzPTSlEGEZ-9phЦb9IÕ7I425F7TRgcdh (2\M5hفܴ#4& B˪{m6h١u(t2n'BʬAbLe?$%6=\X0QB%㉩ 2j^T[wsncjqҪ @8ȻPhJ5^]H0(oHD P)e/>7Ӹ%$$5ymPE@G6~fcLmP$R(W1[^ecAy㰤 Ynӻ$ɭ%d_s{AC3h'acKν 7&w1/AaO+xT4ݴexHnlf89_*OWQ5يO_F6Ke\0b)ʢXm2 8GؠÒ6=,8n'[vsvW53uXt_%SKP:e,كƷ\5 S?;>jsǀ#b36ԡ$:Sw\i^5}wn3ZdzyE?:2ΦBu- |" %3~]Kmd$²c쇵:Ͳ8/r&!%m$Jj.Ww=4.yfbn~n罬gc{(+e]cbU$k].y$#|NVe6_&ICتr\֋LY{F&R8-b]fʨ> ).vZa_ӷ}ִqyoN銊i47uiFTڗC. > ~/,UvIX{MA/V.ݔ[3olzN8| ~r 9wsW!y!#o!gq5r3e? d.{_B,!KY:fqAݐ3@|٫a% ac?Ljۍo]Hq3ތ{*,oW5/0ϺA]7JŽxϨ6 /wSoC^ݍmm-A%%Y_}&D:PLӏA@ ’zJjĕ"Kb6?щ^Z/)@C/I lٱϸ叐$ f5-4يQhm?,_T͌hC6JFF~qхwt̬=o^\-` O{-pd!MڬAO$L(ތ[5T7"e}Aҫu̒qA_2ee +n_WWUbw2^AI럖Au%5e{ƶ[> .<+&~ЅhוrUiKQYq?Д[-o_&i@DBݧ켗O~VR\-y9R֘W7ѷūWnP'̸oP;Ԩ(^_G?.f)‚S"K|ݯ#@/qsӐevSMzM ?"M~!2dU;]q) "tO&R]hQ&.F~Q}]DO{.x;)2eQ ߐt/ks n`ϟ?\xQ;2^9w7,ҡk', 1Ϫ{ EN;Gw 4NaquiX҆6=k%qA]&uy^/zi{C.(K5]/ty;0謑зpPgPg[E{?vOз댜1?1 Qf} > f7rϾ_B|Y=pt68YaIt=~(Sb=C$L WBw90s?zpd&쓈H&~Z };)/O|n-1n1BUt?͚_WӾn λwq@b͙Azhb^:{ps%yǓ3vag*b{-p|$/]bYY~ƭ! k鸅o[t.u*<4q}mJهzꁱ TWwSnH8א=:Āʶz =dUJ*au=;ӊ?`Quy?MCM1Kc!C^xMfuJ;J<׿`aN$_NG{뾧MMM?a}^Kc7'ee\uE[Gs!F.m1t54li\g1]}jʤ3YVVk~ 2Ī]wUi^h;]z(̰"6ț5yu.ր4NcŒkQ_a~ioo #h6&_hY#.ŷ2l ?A}+>z<,+sȏ Cpxh?~oK $RɃ_F*|aU dqA}VtкΓ82Lo4k! kS!ӄ W$!dh,Vy?Y'ǎ;F$ ~gG x4{[At&U-S4F!P(0[\64^>SѸ^zպV:8vC߭4#€dYt^f8H^DAvCۧquԫ~@چ'bx "<l@szy-уYĠ |:?Roo"?Jό3 p8>>>S:Ɉut Ӏ@3IFTf)]$"d'}= Ēb4rkT # F@  $9p2d06-HSLlB7fm 4+fkc㳷[ڟbB#bIFT z]LHFT,:I3,>k3=t) hD%I jkLJmG`g_[]TsdCJnC3F.zvt0#N[+w=:LgHD`[qkAO鉵5 xm@/ZNlz#Ұ#h⣧p)jndp[%7p\,@$9זA31u(} D1@ 4C;u]NS)B2(˦z}gUF6$#*I3mս8"H!"[ώtЍJ\_ iiio?]QQ1rH:u G{ 4rE?رVg7+汛H@D#l5Z}biŲYDTۑ](Fr ]%QP-7wn|IlٴM aV2I5~[jA%2!7ىT2A-(F!y osmGF oy:ZaDQh9Ow@5*M݋ #o'"Ik;՘R BjJ-f m+4e EbAu2 %ȩb̾3@ .fWpKc@{ZKdst~z';vqXmRD쨖(HtN\acPW$#JEQ693-waXDYD6LIfDgf??ɦtۑƭHv]<V2u2FP W))j$2Q2?(#RH E QD4F.O)38:L Dusso\HL:**s)hŴZK21q&ĥo IW )Nqg"8qY J{n7ˮ1@R,Ui-uZ`G$.*%co;Q+z5LdlhX,9w?wyzzפjt#Wh;cpcpVV u ~neZָ/;ꃴKXy=ĠfL޻<>@&2bR u ttؔZ,* (TU75MUW-;2٤W[VژTI'[e(!9듐)W;vdIXLbtbifד%WDK*{ #gniʫIhI)"ʊ%gWzS45 e}wL4Kav _@[{FD umwM0MQ)s vqe]Bu|#h4;j*Σ/*T^O"RLj-{;γ iJ,'k7$cvL΍B=:XCbPQ;6~.pC:*yBN\iFh5;2I$[%bkhKfuy)N6$Pce:KIúeJGt:.**'PH發7XMQuONi]6}+ըF]n hNM|ؑnW6L˛$5LP51iJUFD{&тd\HWݣ2U.옘/^OXNdG$%rh~:dSIV Av.؀;vSP̙׹Jk L#tr'U> X7YTR*ȷaQ>zGu폶# P#SyM]mj4ƽ7?Hp ]vM᧕Jerr78p…7otyvZ>"sG@6Y|i[9Yv}MXX2FVY)j-2}q">0~րs_|Z_lŎoߗA:Z(?p A__Gc O靣7ikoT/:\[0[l>G:kEyM_UyE]m9X]oQ4IfCHj.0mQ@6uLcw}Wh K{w?ćZ2Qs^s2}gaSNfvܛOѼtWϷ sc`+zYJ>b1ԿEs=ǙN(e歾 nI1|YNXö{;2I'fNw7fBsĖzY&}sDR%Q^ۦ;歊`G&q%q)k6)|zXy=-6zuأ oc2;v>fͬ.OB42b삐5C-"X7\mS4by_10O?)-ӮK3 :5V\H^#sW;2vrﯣS*C},.$fV.q;>䭾acqb..s?8YhzP4+W@#SO ex@lt./ub3ҧt\4sόPE!?F75 >mX,E"VY-?{?̿~Ƕ)En`#3gyA76I<ޢlm" 7~:??ȑ˗/?|[Ξ=nݺFGGZZ`;gW|}|@߳ w۸c*ezvZ6"34>ޝnd]zWV5~ua=|7:E(Me]_`pG}wub@TPuaY|w#ш1$\b>Ɣŀl9{YuӷqG|:\7 [s&aǮ7*'LCkd;Chg<ɻ<ڂ/ۜ̀Px͸]bo Ȗ]cYy;F{}L-byhh$L]e^yBzgp:l3W? /,Yge'^v\X:üA^g>u 0;.$ҹX[p4+G;8gȽ X\>^ʪ6(kkz(_z[!n&xl@o$筈>m|ʯci{AV9JANw\pZrpG|J-sXxnAY2q6 ~ӿxoO_pSXo߾WIƓY1}鵉ZmflA Vú2}2!f. ޼ÕNL5r%*ҰTkPZrw,.Z,ËߓfouaX)ѺT;3Z*#T~9P#+] !Hlmi0LF+CnH Y};-#@.l8Fjg5W;yD IQ׬kD7cZic+ j5 _ǬI >.v}uYf$'S4J5 ߳K?`zi5X57 Lnj$Uks'(L~f9шwy9oyj-pua}M:ѽERlL=Vۑ]e&yubGRDloJA4h(*zv7S"HS&C&WGhK#L{:ZԸDՕg.V2puG:P _Gq> N #=D%UzAXU ~oy}tY_G!U?ѝڟ^XLPd Z{$ 2ZbL]h湋 A\kjjL&/X`ĉBɓ'9ӧ߿T8#klj2H67V5/k@KJ67Q5 #L;JA67Q %Zlł@%2̠2d0@ HA,ٔj0%`X[HѶ -Lh[5-U{5dMT|1ٔI iT\aX^HFtHچm6@"m D%0܎!2mؑB&1vDF"5LW`hG~jԀilnjD)umɖm0MU"1%H&F*F+ Q( jZ ֪5zx[mh $ɌZ5eE$#Ў P -LjC3UQ۝Ji={ _uIKK#=-kkkڵkݺ!t:tӦMѣGVU@H<q#^9X&HHC;8] KO`+;] ՞`s܎`a^xwgm:,iheq#^./2pvNU n=oZ鉗%)u܄Z8є`sb+wߐy mQkv+5ɏ vM6Wv7`×)YƁȱy%ruӘ=ԃX0xݝKj>~s9V{dJHdK3:z:lk{b{7ݟR?F4Ǝ;a2Bnݺ&k M/R8d34ݾlA(]vb=m6kUjms9\E3Jw kҟ,X8pW_Kﭽܠ>R[Jf3 9 G)e+Os=dNÍB$՞~\qni=7j@˥b rsGYaesJ~԰ɺҟH#©afz;_Z4[(s@^u:d.Y8ޚԣsOnnm~Q852xKQ5| J \<@S|Cwf+ K$S#X^=\)-*_|J؈L\cx.vOiRT#)Go~QB_Ysxʹb1(YpITNۃJ+Yx"*-E~daXu{kQ԰ouOkN>D.,*ex!d.y˫|{mU;1L\ت])VG Yg߿t>([sl]85L#ST}P4seC[ ] 5vPdշ©a /5=Nlu@,u;ųqgV8m:/C0oOVU8jxpjX\^ԫEGuLy%hޚg1e78u܊i{RZƛ٫x% h*ϛ%3vKT vzduW\cgIX =ރ 拾@ K o\F.ũxVKҢ*d}eim|EѬCH?@3$[AѶ 9+-*x^E3$UW4ťqQ4Dz dy/?j~OP?M LLLLLLrc|׿* ۼ5t_B*_[zuܵrڐ©a 6jP3jO?=6Oo}(b:7 kUmsmWL#Rbuq9}X/iۜ+/P&k;}\֖+xϫ8/?ZKt9ʸoi{ y\M{?"r^$SjpLuܹMHf8X_BBZ([uZZ\uw M\}.7gvXGE3)FmQDݳJPp&Q]Db+!dkYL *O'.YxT-{FD9 ?w~Ul҃yDl'Ш:O8p]]*w@"zD~~bkU]:|J빣Diț©ac:]O\<V|YΉʼcD֜xPw!fing6܋s\ayͲ K7뉵n 42Ep=;9+Yuo/Y ӽVpJt;εh>E5v˖h>M-<-\,F6`kUo%z 3Lp'h~eeE{:{j; o; yyytK$X?SYyk C!d±y^΍x XOu7t~y βhrEٵ>YUmK6NqOQd`DG+6\e{KolzK#K¯],J7CjP b0 7򥁋Glsآhh>Z;s̚1&;aDc#]A(oaj2#FV\w6aw=u.l;؇~Rö?/ [w yy].QYpS"ASt?.<:t ?Em5@ξ|92{iduc/l]X$+)f9s=y'[z3eu^wmA_vko7t`8? D:n% Q丒g.PqQ > ۘ{#+:҂#Z 6~C >Ut [[jFH SLXDW̌@om(ZbX5Vj^0ANa)g<]\0صpͲ N+w '0)sXM/>b/lj-Zf@=_nnݺujClWNߨ8/רi=[ A̶Y4d!2J`\mr2#sqdv*J ''`MMM4/'.ҟ,AzQK_42ŔҟC6]-R,IܧT |  uHY[s]?+t|0%lab2(G!s&J-bUHR1jyu=ʸO'rla,VuookLarIH LGT/SM+jєҟ$&MYDuekhDdL@MORt٘&7U|hW5 hnF>hb,/ډ*ZbJTBU]F05cM{Iu3H@j*M+W}JYӁL(kyXtZ՟HIr d CTZFC4m`G FWVחtV#AV@ufڑdf,E17IOd>7^E+WuoMBe}3ٖ#*Yug7=Bi6)^ttkDREeW%Ѩk;̎Df(~4?UnhOyyVBKyYGqatDjyi5$+jJ 1H飧 G ?Qg/UvJX)};bf/y+3] H LG2:x_ir.4r\F [tK V-br^ 1S$q}*1;}*̞j!IL+QQͅ@;{ERl>矴*qΪF>nNȢ8Xidʿ8h}Z.sBoMP?! 00ruuuSS#VyyOU4/)"xNoH}=?jHm$2GUzOGNZ f$UfPBEEW7 U Dc#걺I5P ք6ŰL.K#o^[ʕ. %h t?ٯrOc-dinH [Z ]*8TgCe5G#Ѽ݀ɤz >׺ %S 0዁fTF@MY[/Œ*.ԢZJݦn龞xI4 gF𣏕5Q7Vb t_YRaS3 :=d4w' Nh?K[5R9AUhWVq)ζx;ڹ ^~08&5_Di1CQ/S(uDc#=(*H&ޝŕ'[Fdд\,"tL_U€4,&ȕ.ԭg~\ٸm s5{Ј$JN#Ըe9!$'6(lkJZh^|f.%~O{߹sիWs?47z >`PU^ƲۆUjRTan?߽bShȼ_8h-MۍȂ$mEE]DKA[f'"95\#2Um8L"߷^1Pv/7ev&~߽D^tI'n](9KѨ~#+XrTD0ȀY.dY;= Ú߶znR&735B(.6atnofUMusğJYēhyepZG?Muq;%;K"[VJt6MBs9LG #ˋ߽Hh~`>mDR8/m[O+>e@0E”Tȭ 9j[|^/į.޳݌Qum[A/5ӊ/L*Nftng6 >dhjuj)e"{% |6Z$'ϨKe%q3˒*W0;f䞹m:vԑ]3x%}}p>&8ee,#F @dddsssb1o9k֬,ؐH=[Ee4owּoyȴ*QO kjDP8 j vܜlمExXUsryb:ds44 4yY%k6fh g-Uq@QVZ1|suM^F qw=a-UTT4@7lp}XdgW#*ؠT. CbUk*XՎ6ވ=Uԟ_h D)hwCւPEQ5mU548;kvD`#/g@c5[XQuօ_%uRld{w~ÕNBLF h CyW+x qFǬ}s:p^g/G5{>hI`. DrVI6kU.ۡ@ժ=fv%*a /bKUJg"mB1H3~moybbW 3-NrpDrq_ʣʅ v-*ּH@7 vF\{&%@͖՛ڰPn]_aWt#a-ǰmy9 w<*f/lE:neTKn6ikvlhXTּSGn\T~V5 *898Vvs Y0!1|3;E9=qs,~"Zdy;o# ʅ;y^nr\VXfc$W;VU Q @'kG - !+,=jpCQOfMޑV rqJ[L_4LA@Pj@5o{SL퓗[GQVciu]nW.ޥ@QYFxW֟vܿbp֢LUTh'"LlU2Tm8\ Xw*%#!_|Hz;ּX !9UQz~O\?555K,)..?9s`ԩBh9o X󶋒sI#miût݋y]?$-َaOʤz]?$-O&G˛0aիW5jƌm۶ma`:*lXRl]DQW(9Ai `"E[f{.ڮ[`phثÍzu1p3td1:N9-0S˝,fo-S^Pi9GwسިgV ٮ_vAU#f:gYd7|ƻ],J6+X- 6Mqz@ɢj+y:no:Fqq2ka1vWtd6vƛx'G/Uk5bE.dAx0Ŵ7֟R͚urv7lL5-0TY=}aZc۰'gWPq]oQ)̰YGm - .@\`b1yTy ujyY_6ؖB=T |pA\[f?,/ =c%PYT=hԭ mNI=Ժ#T.ڥY{-m*yۍz9\Ӷυ9aZf)-O۴XƠX󶛎db1iZshbՍ7cN:q;.Eqqt:? t}!4O-v];rDĎG۬Ӻ,Ճ6'@%A{Bo_ѷoo~Ϟ=b&XZZDޟ2Ȗxռ)@ |9D"Шu3$3@pP(@$XۛT--'WT[NH43&Ш:Z,j~٫8#f74@-鉾7=ynl&ZOh9;NyI0F&'h&C<k +j}-ڲrшn6f8jJU=O.rTXBd">L @&R)8;"5Q63" T(,@fǠTٯ_l6:R1mC=?fi[-ZQ[? `W͊hU%Yt=^d+Tnjj{KtS K\ɀ>cU $+ )QA\B0bʚ:D]M0&CtfR<%z v[4zL1`_ @l5hPexZ@_IfƌN0;F?~]vlg56p}LeFqv:"bQdKK ݯSlmIP{ih%9ƽ @K?gvFl銈d f< Фin.f /`1ï@-]hU„4o/~@+74+bśOVz)?~VkVS:wJx77J cԩW\y]NNNNNNBB7N%VKftetetlϋM67w9$"c{_81ZEF_C:ʚjey$^V( /%,̓XI/+U)qfh:{$xoIDATIs;qjf;|,pF"s;u/VA~(#Y wZNrɖ$ Ν\$h['t)} >: ͅѡ=c{YAaCT٢o}5")/6EQSjl֩ѱ=F4p=v@UCj~JzhcjsT*^ͻhy71{tp/F(_uWVTcR#~;hM !Q(I&&]F\]pE+s/\WtYTFp=qV HVM56#yysz(N(-C݀cC\ahǷIg3h^K> Ӫ¤OnWQSnhF#Ȯ|}/x72|9}uv(hY@^Zn2F EٱClD[6KE1{ ?_ͻ hkQMC=,KƇ_*æY ˋ-x*sԬI\CC4V-dRD\\ip/\WVRHI5aqF68 vUF2cc7?{ͽ~SU^jD K4B!ge,ST‹k=k(=SG½)jjVkRTlӘވ>;޾)+KdE%F4@Eu83[{1 f 1\Wl/NMv ٨=$JZl05+F&ܰliyiu=4(k9!ݻVH n?w[N`lQ8r6svy^z@ẝ8L46@ޤ9ߺ>j$Y0z݇:0*ƭ`Yk2|}vlN[jDczɟg`[M_;o|լ`Ud3[ZPZqFQ74NpZ=tZ~S_lP֪-T\֪-A6foI2bأ64.4&,:a:~YHruLYIVq\iMqqjzѳq=J{KAO^Ԃm{M]#`~ !3"RnU۱oUcέt/5[յ:UJmͳ9:u"Ό /` 1i\̎!{42sig3 WحXb1~ ka|Ji~kuq`O? ?a؛wdCz[OI9Foq*Xe[k׭j~Wn%i}"/)jj\oؓ:D_+LZbK"aUu){B5أ42EU4uQ5! \V3.Nj޽N䜹MP}Iv ^;uI~8'`dմm{oѲLoz{IL-aTC=+NMw?sx u,MpGp޽!>/2ڠM@5'$9Ftq61 ZE 6^l~L.w0h͞# SG(vv-OCO]̆274n"ט Zv S&:l\˽895ǽq?}Ԥ?(/}zLUoqںW#;m{N /j[zt|Jņdx P{[c x>BƵS&EU k75P!=.EF7ܼkãU[G[G-ƍq'g,;1Ip.)4]xæu&}{VWNt,9s}z>m;ngFMI3mϫ=p ƽz`ΞY݉v+Y͘ !ƽz8?l6=^D^n?^eqU[L_ D]XQÜ60o7y'|0Gۭ\j ~*Y(*1\q[6p/ĺň^#j4?Z㢏fL[  @\qs=z@#UV0D\p}|8{v!j^ZŤooMza;1gѽ<|۩# vúiU[̆_@@l#b 8fm 74WWGe?j#*IٛvYLo"O#VFurrH鿉&4;SQFRTՈs@[PQVIQg Rt"ɻ̆ $ aNtG9 ++-De Q&Lnx,&! qTw*Bf KLuvoGsvB5xBqvh4P!jOF)!t0#S(=f>$Y KF sQf4hT x`:;qD BR0~J%+$c\Pr$ߵj¹*.r>liɍD6 @DpG%4uc3zv0*V^i*ۥ P&A}7iTރ'QÉt6oF4UCj̎u\罡: Tg'Tf@k`9eM~PP,-uuZ>Q7jo/h]$2 R ٰ,d --ThFC}[SRmmXk+0N*H#1X $PFCst3jV98*yn^^WGP(VVbZI jZ@&4 D[4J%hjZmh*V*F3#hT**V!R(x&^VYIPq&P\.QRFCwummGuu2bmm(VQ3|"%ЗHT$&QVpVe-V RTáLzi@$GKR)憵Uv$8V\|ŽʦֱHjph4Z褨'E"V6ai[ZMPV 7VˇMи6r߽׀CPdmkfɎM&]ez75ŋ W#!OLƐҊښ .d~ueA2S-դoo<_jڻOk m6A__I̹s`LI r 7&1u6* ,)\G>c?r\SR~$I ðe4'#I@comuݹ-ر %>+)''8?}K$P/ gXB^}i@~'ڬXkfË8AzuԖ惇 "QAC߾8Vn$L`FM$E6$X Eb4zٔ0w!C=j#Qm?&)c~g>ȗ/)?ӒU26b6;_a@C\ӚD*WW]T[gگ?y%5SGAju=*Evw_qStqeF]Yiќ0oIӧ$Ƈe>ZeXךkW.͟슿@ZOnS^jx< / AL &۶H`[6CF2(++Dދ:{eFIq] GYaYeeV BTRF$S\`*<|X¥efQَuQ>EV^{ SJC6 ˶!ۮ^N( ,l~TY*=C0n5׮Qy(O"_v 䕕۶i Jvld/_ll|Z^RQ'ȵҲҪHAދg[5}x_w;T?[<#kY) @^Pu('xYA:Ґ}l]Ws;ico-,QzfiD>v6F( ^P^(HK- l9|Šaj8vlEUBQ*Ǫ]Ue;ݎBLQę5'/߹üoLׯlV4}WYD^5Sǹ1QO![_U 5^>@VQ^O2f” dubnka;U z<19س<)mPd, j`=Z/ OP"si}(R(ZsRK?y^~`7Og#oՊښ{nAm; *߹9=Ҋejo {bl׍?TFyҖjn.۱s+J7peCϟ]7T:"ceC8ѷuOnݬ,ݶEV`'(oh?1ϟN]ѵ4;Z ζ;_Ru /9ݤK͟>T_<[y䐬k1 tݰըo-*6lRfD?0Ԇl{PI66wTɭg\wq^uS›#g[ q߱[7]<K< mas˲m-lދU:_ БՈ1rǢE=7UgN0j֜W7@Sټzw 1`̎ǏJ Ïӝ~8wpsj9|M- l9lBbI@'S/c*b^Y7#x/y>`o ʴvtS=yd3s}GCzyc^YK|y תTc&8\_{:; %Rhzq|'{.m[Fѽ/V_8{~ӿV* F1tfpX1z8!l멞BQ=egBmLweYsjӛM1@:r6x62njվ_[oF$sg21Jiҥn9[b=f":W9%4p:ys-BOFN~r޿yQheccifˡ#-۱bm*gX4=+ܼu}WLuwG?XA㼢:{OaF:QMelѮۦ /tbnTvusgͽpE)x$CاYw(^ƎE9]h3aj>db:wFL_8++l6 }n jG9.Za9t$p~ʫJC6[ D_lnm}#+/ ?Fmuʨ]{'DYUg~74⦖1P*~B4'Q~"3CZ\ nje?:ZHdn_?1ȷ#ZCN t3Es;,TFP @9)R+@ 쵝)]#3}<ܽ*Nw]TV$2ڵG2<Y!#.KM$:ݳL䢑I1J3,PQ(4r2&Ȫ(SZ";)jѮ=Hh G9i&;.xvcF*!R$S *Z bmKwuni-))>p]{ $q&t*eabvԯLƪ 5UZcr.SxEHX\3NxpɈ)a{LL HR;ukZ0IQ[)bev{Foj4ds 7p'l ]O9c?< UTfphJޥԺ2jSG25ãȖVҒ"bܩ Vd`8d}dv))B&hrPHRbr5JEu[X}H˩vZXVYAљ;cb\D?@1/S7MHJeٱgXd8RZ_O"aZjoM~8H®H*Kn^YZ h*RZ-͏Tk D\ex0߸}'RV)҆sr2Hh3hk_R^d5A!J5 ݘ)%gkݶ$ij!V%l6MOᕥD*`,1sjM $&≳BgѳJl1ϑVkrC/@2(Rh{Bdu3r~jgxbjN65V|d ]Шk"iҪJ [9oG*"SZQֺ osKFL <8 &DѨ6'@Ш޸OVI%ӐIЂTKkP67 w\ }q(4Rq/Yu%HX$q^>1l {SnVxI\2?skFYn3p'Z˷UE;LU(tMY$ZRVlkٵ#=6gq^<2x=4RIɽ>+vԾ{J(;{ZUe׏rn] K ES;^øq1} GKK4rWG1ڭ yFR$Bvo ) NU?E"ф? BKnҋy^ʺzRmm/ҨT^$Z8ym5J\lfnî 4#..wݲ@evF%GBi6^˶@+VqF&~^bfAnŸ9hJA^V;6A?&PL ޚwhg?qgàVn?Qz LƩn d彋7oH}4s:Ms^?g|Dz>ܳ9JsH" @dlcps4l`2 %$r\IUؠ ڜaF3+\>O555USOW_LgEYB/A@JxaDFb"K*iMiǞ_?ԙLGJfNZPhk|/4ZߡIrlbǧj#]/t:ޑmiF9"һgDĠzmp|W9v.iўϷM^%"&@_sh0q|=aEiz# ɱݵk48,mx) qv,]w=:[YɊڲd!ܝ>@ʾ/RB,-jdDW4 ϪUŮA5jxcKn^8Sx'yw'm:-4"wQ ۼ,b`$/mYlmWs{(>~px;ǽG_p94!IW_F-HXWVv +_o d$m8,/-:li}bxb A^ia{ZȶKh0s9EY]VygE]3UC w*_|kd}a2t]O}]x[8ԟY!b-n.X5ҞO"=_쀙{ZzPXcsqOwYGdzPc#Ir&L0#6Q7|[LA5  5V{܄O~HtLNtTQU:x+LL]ف|FfDl5fhn ׂ}Bg _UxD+,pRޑ#~rV멨k:d%?d }nzt]g7 Þ/ow*lY7w~]Y{=7~,칷zD>4mUuT.~x#Iyܝm0 F<JWuS;R^lwУφ_=kia oye,9t 2\^z/ WÝV6['[OzsGB:wj> !O/?vDVxezN_47Lхgb;C꫸;W- |z~[bY$H\q~Խ ,Х>}mگP&-  _wY=jH}]X_C[fsjlM@`6e'l%'}2w'JSݹ>9rJNHKtT 9f|rVQWjZpw 2 EC?`9_7{7O1mbDuq5tYyG+p{̄UdWgoS g4c(nʊn$;%4)/}+gCz, b,|Ft4Ǡ .Q੯UIz$4x#I3p.|}wWE-ΌJHxDQU{ '{̠G h Ij+\^w0c[`_]rh{huAT[uCY*Np5 /ݹ-ĊJq ;WB,HUs/iQd 0xM HɊzc_zw2nֶ6$m<ŒN+NxDpܝs#^| NT7  x郾/ٍ$騺MzXՃ*h(q!Kݾjdd8wO.ur=$2S>z#qN5R^('c='q'aVOpsoB Դ5T%m:N]ř{p8;Ws&G.B`<8jkLɨg/W8o c I k`4ĆeVyMX9ڿ~u\_ Y ɘHyit@)GFcDMNX{@rYfVT$m:6ql(^pnz!Tl o˜6/3Ap׶7q+vh(QG{ף[Q_[zgF p^ όzcGJwjO!D D#iIc׬{qnAol$Z<0D$vT&ZZ+2>_? =$Ͷt3޳6G~;/281y@¸W(eLŭW: 샙eW>dUȹǷKn!w~ kYݤ7w=j(`q/_3J®r1|Uxg@~[teV˱\r?af4rcᯒ7RIu7;lz5|uf7=WTLfvT-nc+$Vp'yCiշ  T4;yPbVa imSs&. 0@Ǘg ^=)*-mz-̔~4t x`}C]Ƿ3|BB͎H؏_;еzh_ vw Oi *LV}j7:5_n}tŗ%%AYkU:ݬ"v}8<8%ݬn: 6?o,jpe[Mþg;&fڌz7;%WT[OGZm mT jQ*<]8`fcNTu|;+l@XHyo_︎n#~3pE|vcۼSľ(*7;$7nn1 zT[ެ =*Զ:~Wױmjayd,v.-BLZJ̏|iLP߅ .}' F6v41 ׋n~|3ZU?=es+4&G1nK.s0aAo Rf+"!MHp ,D_V sK[/A8p5ϟF>F謴Z2.i_k|EL#Ñ/[z 7qv[D¹y MOKU>c0$yHZztmۢ~꽀IsێR!za_EqZpgD L,vTO.⁴d3Y!1 xIy}i[Bf>x)E%k|-?"u ]V<탃ݫa|G˯bGGg`lt ;"1u uldH}eM#M+z!{U}2rS?DRqJL|nί6CJyuWcGؚ/O=2hセ4}=߻*d 2(h1K?o;J/Fؼ燫oH4FJx/ZTxi;󩪽6}vo+ퟮ鱷@W}r߁2}ҦtXRuKV%v&1Xi|bF=yW,r{V˃f,7qv[;Ew/4`H4w@G B~}`/zKp1dlj|-?-Q{~<1iUAީ2\}rk릖⨪w3njAfzv|GC ?[ J|m.2Cc?>Ƃ=?5E+za}~w䶣8dˍpr:وG+ (oIs+vaiR??tRZu[$}QN"[>زy/ +=tγK\݄29+4byg>Sצ8:  ve/z9l'݃C课>Ph?s"$͠ՋR#(Fv)TY}) lz!" \pج)S Q[VLg"<2!јA3׋GM2=$5w?>a% 'бa5yfpHKO4c Z~æ@DR蜥z2dgD dLw:(Qo^-vHc" +`BT3NE{ D_2GB~v %,5 aG5kD2Z7H=2%nPt D2ϪӠJw [!8ߦxA'{xQkHyc"=jV1E'!@LquFPU̬YTAz6z`no7QkK 6MFMC՚Bɐ&%YyC !cp;a& w;AI p)l b{R?8>fkx?qdN k`GIk ݨ4Uk74}25x֓}%WZxpf&bGɛ9v\L G5XJL@ r9U K/:m6 )+9,&OO ̏JUL|c+Gt*ڪqx0t,Nh-<2#ԩZLఘ^݀a5b7׏ n5bpfXq^IQaoQSp~YTFLS1Tx.}kXQK/9l_E/u:(KyK …?oz6:6 ỳU_ Љ{ ogGh=87>86"=“^=VDcOftڭ6@)Ta|@hG4м !vpY{F$%.8lV.n D f4Vp[`U " u:Hq9f VP4V-;ȨJktmJ86"x&̀`Gx8jB28 Afm\?i,(LP;ȢWQa˘͏p j3t 7 6Dg-%G ӛ#tbpǡl&=p%qfn#3<4[9)1U 1=ڱ{%x|V>~ǡ0,zTc{4רcv{j7^6 68`ju7-Fpi.h'RhxDgAw0*0BnLl?yCZp\+lv_bZK:Yc >ȷн TO_Y;f7~Mm멭>00g1ަy!'\Ҩ^~wV>9N4AVq U̠I\I9L ??![/+I8T~~&ܧaqD}9{'`seJu Fn;)HeU3V#ZJim-:P\"9nĹc O&/!j2u\Od9'&ˠf6,Za 0x|H'jnHzb%ҧH OO'\,{ z$r~^:`B&> o@CmwWU񱼽GUb5l%A:~ӛQ#k;'w;ލcK _}wl f77_%ozYgM9G3m*׾n9 j!H(QN~nPYJgJN~uv ke[Nm] qmW1CB&=VrvO?mf2*M|K\#3 Jmf :m< 2xdx̜#/m=Cte|ej- -Ea{g- q#?l[^uuHGU#TeO{v`Y4؃?9.~|qj>V Hx샀㫔Xz;\2 z~㰲{=`SҒd7_P.xh5:XN:wps.j63_?Ha`Sмߊjndv/C&L^~D\_{m6}%MaV&r1D[`V_p$f޲ρtSTˑ3_@G0%d/?$~p[֎#I4V*)H}v3sj5hKB}E% e8Y>#hisiݟRGB+?n]PH/B wgX2^Èh [:eI7Ęaώ3,9{֍?ᕽN͍jNdz7v5 n!`7GC,JN{oy7#r$e19#](ziY]+B<>VC܂`l>Def_NAYDn_N{!0%<~`,؏Nu4OadePp@˻w^6zz{شc,+>Ev~EӢUXn#>qPI%`W"gbYzNjNX*rF>q43 Zk,Z)wzI~rt`k(LW;gcS|*ՙE)2_g] uv]83gYdxoVs"ӓt oT8?>Spk KIhzyyh," 8 De  vp )xɨf"Aar GA>.D du2 qI2 xɐT"G%y2^K dHT$ @퍚He0|Ca`<'視L Hso`, sAs $ D 9HaxWRY^$*"R0@$@p"f!R0W ? cd:d١ ?Dst @bc]] n~2x#uPZN-7ԽAD:DeP"fp5O*He$Dq,#&Y ,pD*;& @؎C &nLg86㢖B^" 6\dn>Kǁ)LxW;H@jLPh@ _?RD "/dZ_oBU"tε[ D V{$T%9/F: "0`@sV3.VLsѠj%H-%/J>"0}lhrXը$Y>Ns.n8%wl~nv'2se4j3d}N#8u[g"d-'l,s';YĠDԹAl֑z"'̴ܑz6h6F⦼I$Aɳ6 an_D|QXMO8eͬ'pox~ $Vod@rNՆdnw8l꼃&?b[aT4>< cUӁ78@ΫнXcV ;:Wh*ҏ QhT b5 btScKWR7*d#it,:H*ӛ@sAk$:zIK焸 7T?i+Cd #t#Fma'֋Hmcr;iwXxH!z’?q>Q٘Ub2Ky>K$Q$]2v iRKҞjY^uXMl():{ը@9HLȐN?e'Oann,{ۋ>F0ԂYo *i6+S+39vLf@ WEmw}=EwߩVH|ui)ODC^LЫN30! Ov:ߠhF%-FjR [`2:_7aZopĢWWmED2MΫU ӫz)_­@a[1?Ubw(Hw.ud*Ks_#Ɗ7B$S0?Aa37_w'(鴳9],cy"2!IbIKvLPWq*S3+ K]dY _Q[D/z2?/Rv;85N]14o53j6$ÝGkMEeF&mG#[QbѫnD =P`œD%xCO!I(ӬnB',F?} \#vdҒ]VXlHOxӁ"2̽լs*p/zU1D"П2^-HA m7Ŝ$ڄ]屓SweHXj2ܧXSpl͈/j"|Dc٭f 34TtpgQ%xEC&x,(1Ddѫ~!" 2~Y7=Ԭ')r^r[e./@wFsou:>bG*Az$|'4y^ϫe!6]mTI<}i>SD%l~MRztWjϬOX*piͨ>R&<{HWvS7 n8㍘6H',ppanaqgyGWnRg9;=V ?eLd;mC7uU[sa .od= =mb;^UU>|`҃$@A|*Wo=~و42^Bk~^-{Vv4)O﷚wZ<{8  LZ@ ?=SN>P{fW`҄k\De=2뽎`7NyW~=@;O{+:{i=}SkάJ܄o!hFZ~s=,j/,d_/ݥ'筈X@ QgãKZtK;Ew4\;wO}WL]zP4]0\: -ts-F]zG@c[XN+{ ԥ lwk*6^4akwcڳ<|2mo X>oEwɾ_ܪYQ{qγ",]EP-nZi_͙5> V~Dg/M{/ \ʫyw02^pqRVꀨ)isWp~M})nʋZ3v8ly/@Ц<ߤ7.{PYu$L_DmR7kRg>4ԥCd/Jg֝ۀ&Hy P[rx`/@agOC78 &=yVRX{f܄E0 9^;9:|%,yo86:pg b&a0MZy͙5>N$h~@[m>=y'0/DjZ$bՁR|v򓻁^&\?tN}O8^2fs _oytAqzkj~^ط<:ߔ!π8|[~*y滸`Fk~^7#eca5_;WZj2{I[wn={<\U{vդC ^zTU^xigT \=xiE~" -;Wg>Q[aG/lsX͓t 2x?](:yQO g@\3FZobQ>u3@dy+}#k~Ơs}`ux>a9p+ 9TgNX+0 D{?kg/2=%;wAU{v=#8QG6kϺ6/\R~f}'Κ΁ːm,ZO FًҘ>`lK9 jZ@U?2vKͣSgxWѽϰlȚWl 46p: xًXMZo6K˵_=aͬëxLbPz M7T@% DRc[Z ? ?O$QFj㧽**t~{ ։JRVvgGt2v:Z6i6dtuWPRT֓㪥{d/tWQ-d/ފZf59 [f{!ͫ Igpk~^M -dFn3c~!a3"n twpJh|egqڳ(L/pD n [SsDNx\ʯ8KOÓ׏$25--w>5gS|H F-ckN?&fҳZd/\p[тzbr: wDd,3<.n'+b[&'({ns*Q)a5j~^3WDsyDž?pW9@p-Vݨ֏ ] >#^ݯpyu`̴9V;8R{vuŏVT8QOXƸj3=ckϬ%#MD5XiVp̷yuYԅq085?!QJ2FIk5i(h]gw{QO}#KD ŏ 3~Q5?&6 fBomuDQ^h|dC{1Wnmy$v dz՟J{Hlp(1LwI Hc!0hZw i ]D#xqBcJKq79^)-jam[Ani!D/m2HWe?B ǞE=Xf|T0ec['Q;{XIxLcjGKK/?$2q;joxO;wy,..yP[ٞ.ӼVF!]Aƿ@CѬ|lӤV9|﫴Io!y0ᰵ4!8a[Vg Ky-#폗4V~i3>x%ˬcOibҗVArcD:}=onj+m6(6]ʜ~O%H}4u'޶o<<#-mŕu?f?m(0z08l*6w7V NN7c'P({|QZ.$?9}oUiorF^mu'H4v|ܣtǪm;["-C&3g2V<:))MWH *`+=&iqϝs"g[Z}5anf݈r1C|U[ym) d&^Ϧ{}YYZ+cf{xEVD"6f^aU} tr Zٛy#8HĻWumSPdQY[@ELE嵍ڟPwgQ+]^V[Q[z􋈙S}sp֖t8oidzR wܻPt$YZ%rmۮ72uYP,שd=Wz9E鰛 *y͗Xwobŕur$ǧ\\qe'"2aAmڂ=L7P|D)隱hK5v4 \v)iʺ,E5v6#kFz@sٗ5vwU^h!c:jN]6wxF+Ww kzٌEu?V FՂ-5Fr_dT<8WyuA#A HayolF]VՕFsՈG䢖{6>+^vIFҳ4Uss~n6', xBŕub~jp)*%]WdgNȠ%!"+-UݿXW6{w:Urkʺ΢޻Uwjon, j1*` w vNP[^TOU6Y4b~Uŕu{ZPssGs9+/UN[}|i>o;hgPKŕuHʎ_zY#:klD٠-i,pֆ|`W^h!.k=m%}5W zKafg>ʫ}Rg P_xAQ^qe\d.-k̗u$ͬ5ɭGx[P${ŕu7GfX)l/N.lFh1&.k(>tftݩ*Q˨е?Ajw6ϧcqȑ#7|ia1PWQ}c[tң \yB9WEx uw܅{)T3w c0E $?VԩW7xMs Ts{ͬ`7zHf#-@ N_jvAN[yu^⮾83ʾ5=r/e6_l]f1ɋ` ,k [$F\?uf^:m܆sf?W 3LqoƥlCtϔ.i*f,Ggb4ĆF̜ۈ.iMN1܁AB,itӳo@r#%Ltح5vZ`Y璲^n(9q eL{䠰8G%wAU[4sWT ˾ !g;m.~=;jNeM(:Q 띒 bBs햴I#T\Y';g =v= O=N!";MBa=bV]dLw׫D ^({~iwDbYrm'@&VRyuWԤ.8ڂ=*wt3o`Z#{.eknOGhE^Hx;(3(lr#w۪k\n<>ؔ'BfҬua`ۈJ\&X鈨}ƢQ0pV1)7>U7,x:ᰥM~3"nnŕu~dN#?in9n=.-'|ƢJIJ&1`6mbyOw >?/iVrJۘ"gHrFӕ@@S2y;wRdykIAQyuO<5w[M v\=r?8EM_d(?(=+%G1Lv{5nD]^quŌDLH&%RX-ﭸ.8|ڄ޿DC,rkƢlp$e˅(j"Ph Ԓ;ȈAAb`}tpeщT[;bd +m <:6Ģ>YW5(3*aQI?RyuKE)gvD/OBv}W˿J<.)}R91~t,n>{|R*3K| }*WօDfL}M'D]bPagƢ,7WR-حaB"sosYT1rӫ,( U܅h /7h zJk vǥ>7*s!1ݐ\Tm#I/%f<iv[Ϝq@HV༖+'9(W2l,7|:"j耧w4?GWօGJ6*t:oR= `B)ٯ$?^}kF% ʛ6w;*tߌhu߭+4)%)ʕ+oF$4zB`yFNZ'S!U b =rDj-&a 6H8> 'j6ɤѼ|Qth>H Jr|AaS+KZFlT԰Y4xSg DtZNM4`6*:7 $ UB$QҮ܅{Fl&"Ҩ(;znXtft-n%>GP ]u'FP+v @EOa`0Da9sjFw:Q :Ń5fN44xyzG= #$ èa't:$Jxi 娵nQt8lQ؏2m6V5APdʭVBfb̏ŁS7'Z.i'QJ)@$)= 8Sp<}'15"@{Xjq2i0u!G_P:V54mN2~D3'Z_ Y )n19s֞a(;H㢶AaLFΏ8t TG&h(l6N%p:D5<&͏S䕠vMJ ՃDb i1Q d2].i]ϥ٬F"F4" d #D2-kǨY׊!ſT^7WS}s|%IqON;l2*&~FH$%DĠCw8lc(,/+|Ϧ3qܹs۷ok?(dQ_v:9^*iE,KG'jd& `| 7&<=#FLbDeQ'`6nc2$M,vB*$tZ$z0DntcjCaǪͲBy:7Fu czq t:v`v t{nϏ]>>\G`mVɤ"h47^ R*y~)BtM*B&3pOћj`Ln436`+PV+rDp̀ղXbQ,2[ͱیF7ld3NͶ2i`iIc |\?4?b5;H$uRd;Rl_j3$2mlo2 ?DI-cѸw-f5[MFff%R( MQ)lY\b4RGgb4qJ[Txa޻{3f,[ #2I/!lsXpnV{T*2Cdw0.OPC?2^Wr\ "Qmpd֟ zinc,?D &&!zTKZCGHƸ>E"m O#U'Ieecxz\._D>(:|X Dz[М&0?Ts }}wO][[դIY*mmo;184xJ@i(GD2i{U<&5[[YYxr"Q=qAAHf֖ zYu _(n%??T>9R 5T( v&euqDdA:,bԶ 0̳g+4ww_:ie]ޜhA d[b?sdȹ\@Tp˶77!TU z;{n,e[r#f:u@X~W'Vv3ģw{Ô7}ᨸ_ZI&2W륳f&T3f;4T{@jUV j%bNZVjI O߯ )fA_ޞNO}51IiSְApGB2^^t|3sswskkö!6.Q9hm6Bof<||:"dc0;FClt$vHT[R1*2B2iJi>ӧ˪Ҫv1To{Ţ_ah0JKxr&@%X[Ye65~/=s/:\I"Pf0h!;aďG} {l6\Zh贼y7[ &-K_6e-WVba4 vdD)k:/ak:/8)hlDTR1,47k[x e)$Vn ;6z[[~꼈2bf#}212_Gt+7m OtZѬh4j/3  @ie%)f;`ď}JK6G#4r٤DAAg/njeHY3v#U˙ڃVZ`Pvm.ܼ{F O~.z 0MN)+݆_WfLsIZW\ڞ2=ءyGF`SM$"l{/@d_qg 7ҟJk.^xwN/];uʎv8˿t 3e͸3m"iwB'mw8(3> o778Ғ^웚N?CNiJO}9)ᩱ^@Ewv*n=swX /$?unP$%)Y3vGM'ƆX2^^xd>sznoFyXfLU*y=fLe Y v> /dɃ3e5fLLHo#Ĭ(Kk$=`*+جF$5C 2^Ob3'e?v2sT<{/i)/%-ٌ%BXh4Y3vƆcJeo~n6e´)k"Qn.)9o.ĢfV*{yܜN,VzoMh*+'-IKqGs<"Nț}Ξ7( kdBi=}=IDATᰕlI< ֙ >i>UȞgSGvxcpĉYG8F)=a5.;S_}nVxcD茬 oeJ3.Sič7"K]ёsN ;/qC?Qfff||s=g`p|||||>E&3"`\ ϧRg3d&@ .,"ꦖLTOюh,@yY@ =[oXX?qyӷ \ .Aq_4XUx7@{VkoorJp0/H[&r V΋7QF/>N{J@۫OPɠOqiy2C|jMgQuBt ފ N%#h5'}bRcһj >|b9$UPJ-_(mJ$q;o؋n݃51qH<.Fc{+(󈕪<"$J-b`0~=iI rMpl\8- Vˤ-#U >οp8Cf1hh-zwB&1^EN--ٱo bQ : 0tT RJ8~d0a&u8/F?ej(dRrr:̤Bv΢ 5p3!MO&1Q~+bZnn$ݏ[p38\>qytȬnF 9I%VII"'LnH,k9i1K &9G"B#E+4ޡB tK5p#1Q'ދa1iB}RB&3{o;ÚG4#>M##^#F dbPE NUy ;#Nͪnf`PȀn^`}[ϑ,|7t^p=Y0`0Ik[El;'݋q2Fj^{%&'7-7b5w ˛fnr8A)by,fXH .{$~dΎ8PXl6qB݃AivՇ,UÒi6I%NkBOae8q+yKw@Ao BJmby ߓ5۴ߢg(|&dt͎Fx|hJ'yUځѺ8G8,_M ](Uq&M\ŦGv"F ̐zwZPw \ AƻH!:t{=ʞ;O U?==YVE +gfnN2.r @PW҆ 4 nxvًLىmȢ26w!wn2>eH[wZky^]8; E*Rhx7;;x_\ڭ{" %]2D#M:wLdwXiDwZ?3J[y9xf7 ojZnMUAif :ʿM$k@oi:pX!q Pj$G/(ggnbJH+j_  OXbw0?h~MrYʻ`ad2f77ʔ"iÌJ 3 "ZF͋VoC3`xY:>7s󈆗ΰu`4bsn;XѢ x)dhmׂZfIZTѬJd~}t.V4 3byGMSi{/Zw8}K/͟?_(%̘kھ,%XɃ}$yVZEkNFUWրG|@6ޥSޏ ]5 =ziJ䒊=t2gf*^Xs37덲{G}ƬQf%BgƾGFn.FЌԏj.*|(]4t*57T6Dz޳@q!s%k* M[i:N goFS *.Uv%GԼšiSٝ@ipOXoc;Pkڎe-zkPNĢJm?$ša~&'#,yg/xЁ!ҜMf[Z{/.~< e  kʎc: ̍=\,&17k0|S7M3۳3G~QeY'Ia&<҇%7ɋjwqI6#p^VC`YlY髩$fm^0)aYd@Navf*!rn>wfG&in[iڿHgo S (!Wu%šS.sgoHڿKΞf35`iFɴp#R( (+UMUl6?{Vk@C6~q@KzRgIlכG6cv˰$j7:΄$ ]Mw$"#>"`*LOROx\gO‘&4-=`,_Xk͓қddVofo6t:-,d:H͌}U1ŊfÖmJzwfU>2H2|(#E*|7?c-j[#8 )o9N{M"8Ӈ<G=(/oZEmRiAi- L 'NJ|㰢Um^AezEMJ7(i͢QT+ Ŏ>zDEt٢ 2d^1C~%Q8-~ N%y4F/"h1ϣJᰢmezp鴧D`;njL/wJfMr B7-Y/H$&piwXnCĖɺwdɬQ<ӢB .Uujh WNn: 3>du_DLC{@LdF.8Xl,VCVhLVut&?A S>T鐹;G$P<!^ɘE`'h1AXʚAiM&<ÁdFc}NΞ^2:E"RZ!q}q=" pأN%UvDюCO ˇg"ݯ?qZTA d"j71w8m%}3hd}2%MigPKNp:T2jsB$d L ePLVZB!1 7PH U3 ɪtYENN"Pi1u21E1ds:vJ#{AێGjpSK$dzR-̤S%uGR7c`wX-SIcO\48 Zf,A6G܄Uc5!b)tNQHp @P =_03+{ʦ>IW$[lܰ-!K,v_ @v u$hZrbLUs?;aB >e2Ri߰9I ؀<rKGR@299Lk=ji&n"ink q}`}ںI2ߞE#{OZ~H#)){ Y2ZT==xn-l;`sJeHu|4EqM;;ھ%AP%{\68Cdev/,h+T"sj]%w!@+ev~QՃ$j!lSaAYj#%=_t&~_Q0 J:>!,IoQNxYw`ֽ6KxN>Y(-86 z?+-_^@J Z+#w\(Ӷ}AIguW 65}? ?q-:l̎_Aw;\R9q&jׇaN ?9⥺:E%Ymy 񍭦Ay¤A:W\T}v3AleD # Ļ1|Xպ0i/3uYFCW-2 3Ee]_I+">F94uZ(erռwc!@Xк7wƤQfY n,H\WtdˏJb_%& Ozȝ^\RiFj^Z'X1r"_L+h'b ;mY.)0i㐢w vkobS(S-h♖: d,L'c hIڼF 0 7\F$YO'/ 0B%1q~TtS$G"b?`P0)X{Fii (3cOzЂ r-o4#nvdnK*P4fb#Ā96C=5FkNe&m F&=%U=d<i(;S]"⎣mn PѴ0i?;{FˌӶ_mRMwA0΄HwC/!܁nӢH.h݇?15찥{䑲0i〬WR2`?;Έyۗym݁DZܯM;>q- XL27=hG:La$F_ H'dqN ~,#;m}Q1o149h4 7/ Mha 6HFw̪qC,8n!+.)hVC,o{ý&Nxn!26;nۣZނ tϴIB_к757= ZmO\;3v -CW\[D\,XnXFȒ`;m.!Pf3M'yjiQ?{%e5'=p gނS.| 9Mpqe Ǫf33sgiC>$ݎ{爖Wк7oİb! }:9p^I8(ɳ)BvTme_-ćXf~ȠxD$`R13p~ilɓ i\2Y5wZG/wbF80iXL̲qCݎD<;~zaCך/N~3xHF߈#?L.&bj ƙOabMn`Q]]-*J%ɸ  UI!27dG Z0 d<P٘[Zjp:FFbdI%1GDI"Tٝ6 誶D{Uicq@0B$Pr߬5NtHfsX=Sw7#hUBȎ'Qڍ4/#j7JH(Y8 (r'jaCFAAooFذM;6\bD04z(F5xDꎅIzy3ԦaITI3Ro@:t2[0)>HT-‘j{ToF'?%NF1Y6D؉VlպNdql[ZN?;΀9&M b"MmKX[4Zve<75$@VE"]Er TZŦ'(!n~L ?]6nXd"v6‘j{|ѨwXӉ#& Njt؛&TVF;3c?t{e⋪0 #И խJ#6g@!A,$Ҵ;v Np㌘M2 ,6c;Nn=|v@&Ҕ!*W#lP07aUuiTޢPEv5#Qk|ˠ86H"D2Xs̰b7U͛&tޫ,y#Z' 62A/= /ϡ*ܘZl7(>4"5XUI7=GQC3=r?0y؝V"dUipzP)DÂdZozTϊ֛g#v%c,t \9FҍMVfjYݖ$$ZѦaKȀnj1!@y؅tdt J2C#ڭ Xig*`s?* H$rBVMa `ƻ8MxVɦl ͧmgoy؟W253c쳼ic s VSn5fIpZcr&`rN%)^f7- 7) nË,uS@n7XU;Hs8v\ q:JQcX8\W?*-v7=t=9ZMu[纩5ȍq 7#1Kcb83 /ii V%O@ގ$:d?}nlЂu`W?t8gF?.)@|h̏d;t*LC‹|FGQLyi̒YIi>Ʈ6i"cA ҫjL冽_GE27 Y6Să&(3e>KQHwg_kߖrBl-xMD!izɮ3Yrb3>tU{w${ZKL ~SQ4 =(~C)z%:4-vC~$-д* TkZ+hP᎔bwscef9j/z dUV( EBj1Kf].;UV*&>"3q(=4E!l%ޣYYsm]WNsz2U.cv*4 jEL y . 鑙' }Gw_>y᯷*GӺ0bEŦ75h)jźfX^U/#c!s/JĀ'J89YI+Ch%%W+he5MD]ʲPhP:="oq_MGo(6t#3ÑcxjBh2anVTDq&YF*?1}=& g-_@Ϊp:aZID5~5ʮQ_Bi)޳}٣)NZȭ'`fgU9'2 ݤ80dk'=@>eG9 \҃79pi +$Ej22_oSC^ésEbe؍h p8?1ZU6uVP׋4 2Gb {o8hEqϬ(D3/#2k?Cd䅿9S*GL d(*.3-@+0C/>myTl% ^yE$#Uә|D0b#ޑ@F*Do҉¾l+*𤀧c<'jtaL ~IrEzY}mpvʄ'C!B">QESg{`ɮK59B7Mmɓ.| iǠR pzKm4U)G #VUu_P,٦-wL (8n((u&=3t8OY&٫*< wQW$u~G:ljڍs>*+Pf쀪~aJ69yVț;Mۼ#iA/}Jd} 8PœFydj;4ԋ/=W0%uȜl˽U f$ z!rwX繩m\o Y0i;31b7aZl[ix~Grʬ_K熽遁S3 H?4Z%MaE *;Nh-L)_UnQܫ~# 4 xGѹ/W ] y2&wt̠yaJevʋkL x:{v /zmfJN SpK愽:RlGma br_jq+Pqw8#krRwN愽9(iA/3o 0hSLۉE Yr@U_#<,M{SwfuKW}i#ԑΪ]|D;!>0beNtel, WI03d'%Nߧ輋"<{fpaow6 _?J8 +p!5>?e9$Զ.X鏛6l>L,`>m]V8AXd+A\E&W8j'<9 q4Iჽ5xA 0|C~wvQ.Gsc{D;djԟ0bPz_)au Ӄ^`(،jp/-"7Ud3ilGCldL3_aF8&L z/yw9'N#u m;p O"36CxN]V$2+DqC쐦6pgΤ\RW0<bAW^27Hs^a&ヽޢ(;E y/Y2phU Rԉ~)F alI ~şUs= wa#C(Vˆ{h+D*K9a9N|)kJ{/{`Ȍ7 j7G(gAw`J[q.S!W7^>ؑME/iv;J+ZA=-"wLn*cF{L}mumt~7xSA4 \iv;DVQ!`H¥PE)kƴA]odϢt_ d?=*73,n熽ƣ9 #V~W?oww;F𡅍}Vh8qC}OT=?eYaXb`fX Ԧaˬ7DkMkZt~GrrB^ouC{0;m2Dbjl/vU5 #V0> }/?'=t֋.ӂ^ f$iHtK4A,tO8ڝ I$x/// <\ A20b%!B0vKы@@h7I:,"DLjnߧD3q%{j#xI"Dn>D eBD a&^i\#X?B@3B^+ GY̤#,Fyc[qku>Sq$Y~8L@t Or ǐr贷P )BG'fogwvCϡ{m}]]] rwo4|?Я^e'_SkTȗ-$m_ퟁ^ޥ/8;j&\v"+?_^*Rp-eT:NqJ/w|?@;JAHEF~Ч /S1Cb&=O/$So3Q^ óEez$3]Pnxx,Lߌ=[mn-%7hS=Gnk`xog픵k9t@Ipqg*Isɐ3k SAKdZq{aR Kk"͘WĮg,1F:,T^mV{ͥL죖5 Tm3*ObHVpoWA%7Y9̤rvlZy*$s14eJ6dG%&'4)c4*B˰vyg$aӽ0bi8\'C_AU/PyVpy!;iR0lFݿ{J-f[o#`Ȓ'gc33TCs1w&wݴg1ü撽vM;Ҡ'B `c#ƣm9j1Ra4*B Ǎk$͌X">rުkZ-U\jhX* m<Ӱzc% X]B;]ۼv@6nsU]Ileļm~KiS.)i] E[+Q?4=goxx8¬"bI]e6Lu+isկ~bݼM Q:hSͧ_{Zk3h?4o-;ҥ "r?ԛ -]k ?6^n/踵v[3 Q?t/ԭArg,fZ{/F$Z㙋7:vkYߖI񆵯b+/PKv*JvşE]J7;fԺ~hR9@mزO4 ;z={!O)Zl\~.}s|ɆLo:"Tő,U+>s蒥s/ڑiƳ7eAtEX;69s_s0]s'g) vfşVp,_f .6@0q!Oݳ\/0E]'B٣x%T.0>zcqVUşj /-ˆ 7}*PVy3aNum=h;Q?UԶloH!-Ǡv,mƓ)h] .*]b"ݻ[v1'ֶ v.V247#)!ڹҥrpvHkgʗ?u%LګW>O7e\ c3¿%ʖF̯0O+~s=m9 C y}tOݫ?{4 -X)[wߗ.@GU-{尶z]lbC.s?8-~ݥ٧ 9{{$%U,_XbE::F%u9|{'BQHo8u:콮ͧ_b0Uξ0KW9gx}LoJex`KZGjV~ͬu ["~TT,'z:d8y_Cu^uӦ^Ʉm[:1ks3JŜdDr®+*,Ѱl^3(up^:2tŶ暑\>safe_tmUtm>=~ş&貲Cߖ3˖? PM0E #~W,{8k}c7%5qξ8򟰼rٳ1d^y1p`bٯf6bԏǬ> })kŨjS;!Əx|NۺA;>rG!tԬ]|;g^u [7߮ ֦J؆QCz )T+1=Apl®o0 2dZ1 hS^Tv5` Dؚ$I3i n̵fIBV ֦I:RI¸[)Bj<#>(ZtEhoU .0&IBʽL|pE(Mh0S'%PMܨ@ԡzz*GxO91<"{$!#&;Մ>pBRA%ظ5, @Ɇ,vI*C"{aRBGJ8:jmW\{9$M ʑ^յUz3'q,5fC`/?uhӆ{6N[ bCTl]"ҍy6~SxARf8]6;$m=ohB#8YtGQvأ?Hr8054^mऑj֗Pz=oMq R $lpճ]~x[$Θ !mɐdC$ΙՂOu o<߇Q[!쪬 Q&UTle4NʕE"jցjqr;8m*EׇQ(M]߫ϒ$%φ/[I=RyvCndzaϻ}`j K12=FC`l2 FU}@BtDVYQħyg0oRE>@{YՑAR+FHz;,Ѵ_O]62EF*9V Doq+ 0Ka"Ec,9 Z!aclHvȷR`DaFNZ8֯ *<K_(B J$9xkbYF (? 0:`*R!.9̆PޢxT:2H!nf0N@ظ-JaG`WT@o&*Z.^TۃMn A) XPV`1; [+" 7jFlu4k%*B*mnUAaG1jX@m9`BbX3& /Mv)޵X,WD*" T#Ž'Zк垥@mnôSQ6  壊 Šb<յ.f[Gudp@`^f1O/o#aθ=f_ָ8Uʶq𚟔 0hcFu9Q*6rXf&/Ufa$\Zo[mB4)`'{'ݽG hOe=hyUb}J_/&S|]ڐd>ZcvHz,1$MЭ_1v 9R;ŋn೬;m%RaЇ=j3/7HY/]z]Q1Mo(0XfO/I8(:9Pat36{q8̀.#&úHj;K?7@ۜ[_X@+5}a+yr`uJl~vgƛ,[yK:K̟ͺ%ҳ,wA7eYrTX[ 'ϵȐkVnb{4Y<.[Y>!צ}_jS4먣*%RfQ}aQ.4~omz;fne_ֿVmJWٳ^ͭF9Uj)Vݓ%D[ܪ ;}m/o=]6sdÎfãadS@w6,)m[l<*aW+;˷>ﴕW;l- `mfu e-+|ߗ.F|*vw=vk[<+5g W @V g[WYbLl]2(~ajg::P&}6Z7rsP(F%YwvozK`+2~d{D!U>{u]n@d v^[.5l^%Tmjl7efו[_@ֿ`E2/VYj;`MW/|9}­os} 3u> Ƈzt*NQ#Ȍ?tt X~.?.16vM 4YnA?p6ڟ@lwvX}`to%?"L +E3\"Cf T8xo0Y}[2DFdںH)+iӮ A?E`2[I"~H[_X(4e9m>XdF/0mYt4tXe_?VgUN}x"nQ\lr(]ju S=]դ[bƫR>uvxX?9{FTfK=+NQ+3.9{vUl:ΗH-[757v*Ig A?}{)c owc bޕ-0~@`$D:J.17.|Ʒ17s!sf_:BGJNcG%fB'ao=kؾ+9{Xb&K̟ūO};)P?v6-w6AaR ?+HӜC%ϒUGKLa,[ݾ)[}­@' 'ӝOV)16\=UۿNӜ:EdO6z_|h)8'ǫK̟-1sIN[̭IşֿoCOE'y!Gc1TZegK̟ŪO/%Tld/[ûTlg*Ҟ۾5%_ḳLb o}FuV`3w".>~(}o:jF-AQ=kmKJBF5\ ,G^Ӄl=tu_a,,+F)$ӝߧ:\b/}ꬳOd&Eg/\`Fڬ.iNAпJ+1Ƃo[Mş,6mXcgme oJ̟Ug_ |V]qUG{/p=(\dHX2)Guʽ"Dbm}_C|)6~_ 0lrK57ҵ=+:ήؖ68r^a ^82/sLFs Zh$LRHֹ A?~%.접JP!UT#qF2l[ "ՑfnB'X vH-}QM1,vRv~K# "vgdp aT,$=+Xf5HDəB*enAf~1؍APQt;*`!-= 8Ȑ7jybyDS(-7_=J&k; pX0Nt 6I4m!@8Lŭ؅%ŖB2Rc }NnՁyv.Z@1A"D~-kb/@Q1 īҖY\SKU0 UH"r.C]bf8UsY DKD)vcGCyc&lHe cԄK^+I U7v"@ YH*^.ָy(Ўti 57vhGȰpm@#M\ va.b `hz<;*`>ݖE0`jώ|85J0maЇ{&+4yar򊉵#/7ս‘}]ӆ 7$P,(AsnZ9[&È]*7e'Qh"X.P繱87_0"BKdb\ؑ:%.`bi `dC-(n"bWx;:ʒ*0R0tMv_0T\)$q[X|1܌k (DKQ].lOO`뛛 Uۦ\63Ǐ*s? ,lAd6up'pQbE'*`Р|rlva@DL v/!@qv\&}d_AZ !"*I"U07e_g (x7?P3,[0]^scKXStVp D5nwu"P!DD`V(*1+ox+~ѝ$M&*\C#8LoVMi7H/ڱ5_ ݳpֳ4,sӧTp8T%i)Q<;FRIWJDVT7WŒCL떰Fjˎ=yfء=fd8[Hriե>1C:@QU~pV v+jZb'>s=tNېLMzC&ӧٶ5n!2GIbm`9uCbUA'SDga aUO?@{UΛz|N}ynVa@N<椒L?2' (H~+SS&>5~b3,β#~jձTd"NR*zcXauךu&%,;YAdr{ٺ nzD,+3K:"6QC?uӧ٦}(Kk\OɄ גJ{Ry8РS_m`Imwل]_J1kRv35{ =faUG&clת0K!ig!]ůxVZ\ؚ~o5AazT"BUٲXj_SEv)إ:T:2UVfKb6]}Kb3KIkM“82F_JW-wz}ZldrU~FqZ@5-r.vfJǍdaU~1RMė:~)xnz:}*dT<]1vi>Mf lo~:}}@dZ2ǯˆ3Xy-8 5[%fd:h 1GَfêtT.UkD!_6V9oa 4x9zͮyGo-vitUP?@r{3/vUژ28*NK_,rg5 ŚDDk>\g\%RT1UQ3N^#:X%x|ͯk>Y湱3ivq},K ",G LFף1K!]>|GBƩL!-9~NĜV_e MkwX_x@(!~UE,|a=5q# SlN*Iֻ3KDLWRfKXˠdԻg{eSlyG9v5efЧkݞYX-s*}Zf%V;o-\_}iq=k>$|a!UzLUJgWo9e-_*_@ߛ`z]rb͇B]&K_$PU-Gopj檯sEzf~XM 9h_ѷNH]Fhj^LYE<{Ly+iF(b4=QdB4JoEg_mx;jjDmR`>@U~8+:~OH_"U9o鑱@wr b >DLֺI~]HGeKJDy{;zc?Ӥ9-zT~:f8`Ƴ;E<#1 ,v8]% W0@{8r\=LU ?Ésw܏C``NߤOT\hGvR@*}|*u|A=@*8N1y˂wt:H#X4:P^ѷDiښl 0` {o&’] }G/z֎^$ExɊVf ;}f~hG>++ž|۱E|_(\WyCO@1u_zMX)VlŴo߾ %M(B!z:;Xb),̬LEo➱-G(SF\Y4ԩnxIL4 :>@q*>@J[Eoȋ/[۝c|w2%A{+9A+-f>uC4=`&Ct(|o|o}]ǑM|{cF5Tw,x=[拨k|͂095_Ygj= EiUIس!9-'=|ɪٯW7\~sͬ0RފCV^=@Uau·*coUWIV5-AL 4"[Ό=\~Ea286e7qb9`۹*֗U2ƪ 2۹ I즰\~O竸{PkJ*bʸp+WRNdoV~eniJ$+\{c7|,`hҴ)Z{ `oZk*go`k'=|"?Qޘ<)҆mX`*[:0.ܣzV;wgu.co hm/߰=k9{3Fvv`[!uoOc૪P=|_{cIjRxU*qT.a&\ݔ7kJ_i'F:A"{^n_='bq/ 8[3|Y-uuZ~%fY_-$̔7BQ$| IghFiW޴>e ^q/co"soU=ܝoLJij \m{Kvq~UH_yp6.got"ۉ};kK |9w+S-kc|Oq t_ ,@ˆ|e5{ǬhGʕ.r+ʗ‚|z6^i+ }iG1%a+󗄩2Fzwg]YbQE4sn]Ğb ?U #Uda6l+C!J`;DN#د'E|8[HGx6jRWxKtҎγԛF;{78璉CYaT.+ᇋdsQ{E椑 }z[Z=F$KjDIb/_77˟5ķvT~ẉ!;{ 8,%ʝoGy|07L}|$ASyʝ="/DXcA!ttci~Prgj~pcVМ\*%'R+|W_#/9!63s bЮӤߡ 5})_FD"=zso%GV0y.86/xV.V^(nea& -| | %<]P*ms)_!8v<ʕ~zA9zS#ɧp];M^ Cށ dxB(H,O}6OV;l7C ɚE'Ww@.0!9{ƽ. y$_ESYђ3% CXum]XjkB{#؛M˃U<y&٪0[D]3!ɪh7"+蕟P.$zA,^"dOrҍ%/ gHexbw颳gzGg9{_6>"v8DN#ױ_o%H.ȽQ5{WA1R]KT1u=)a&#U~igK|i"ڦ"웸kbu-b%g/g&' |݂lgBEԵUaVBh[(Ӂ2>)9{FrDl1u]dr;r2gWM}8—(c/6'3HeU*]ٷqsX1u=JiZ4· v=}!os=9 EaJr{cdb{!,Qׂ1p"q^/co$2CԵe%{dś{ZP&=&`l@!1(Ak[y;X2#~\3SLhM(b3F@ 1 ev c$Cr#B쒘@$`s [f`'% T{h"7G$9KxZ4’vD $PIAX"&3У0 E cj倉Q~ h@bqp?7QqxHbmaّƎ-ےXM !vbZzq/haE C\p @;Y ?m`& ;iWyIDsNvDGюa(ZP'BbU".>"t#@D5QDaD43b4Iaۦﺟ6Б.A "pGBl`>?xpnp@Ѡ)x!L!6HՀN>cX0Al A!x_EhBu0Q6-t r_"Y\:0 K0є$k@!!lu`$X``4+(P@i f53 #ke r-Bvd]r&np6cK"c`Y$!<G!o6`QQ, l03A-?BA`[ŗ8Z00x֎G#@$Pr>6X'8b!A^[714̎"l8_B" $0l`7ׂPb`xB!BZNJ~i t6^f6676}މˑ(&<(`)v l'w+`)BWލ1ho8G"r|g <B\6m^#-_.ɓZq)tjYu[ii6? C Y:'X3U#Y$ @ ~؊=,3Jhŕg` ?kD8cuVh*%j<\ Ќm;}#'0=*ye+wQ1W9S@[|]#`]%q{z=B%KeUQPz?X4Rכp tBتA{ 0\,p;XEmIWA\ۢ43E*u+lr|gVŎ#G2i*@¨| JQ-\'a@| W]kXQH2[+镟8P\9+uq^,DWL V4xWbbO (ߵʢXp2 O녦!y)M@ tَ-q739P5~0 > ^8+f.9P)Qlճx]*^Pt\ $DF1ho9#"GйN\#9{.\w@\Bzǜ4ftGً3Щf\6ٻ ]# | ;%'!it1Wv!8ǒh=[{]tي$'U{(Lazām]񎉐z6EbTlU1HtB*@=Q@2: {p`pat6|9/aم@~2ʙp0:ۆG qE%BQEj%x]1`k}2Π!UbҠ*@:ߎgk(ߓ/5gVU.k@'nhýyxkTtϢ7tH/~ZI#p.; K5x]卦 `+DWvD#Zr"Gq(YyQ~=@w'9St1ho6×@E`DgZpx֋N}j&ﴟI.Yk,zc3YtLtZ߈$:쁥vl)@٪E ,i*:'KAR )! :.~b*~]TsaG>z_QX2~Yʗ@9G<^q"bх>ܺ-8U<_(㢋MŦ@!]]ž\#.1BtEuIZYYIII &`1"LUYɐt&pK!V\3I EH' *Bg%i@"Ӡ҂^^1HyLt`LGǽbMr>$WF^9uQ(VEIqZP ʔ<Lh'2E.D`mw|@bAh#蜼pp:ZhA/V@4͋W+(b^pBD!H.AZ hExV"JC " CbT!t_5#BP,J k(eU {]HhHF0SB LP[(ք  ޻zjjjrr$={$$$\t̙3Lセnth@ x`rfc6,),9M t"; -7€k/!yWH !Y1,5"9<|% x]gxpJ0$/}`؝Q@Nk/Ţ$ I x6)7,O@@&؏P7xm ֵF> 2ۍdai/@jfŠ9xOH ) ub:(&^KF(tXWiWB"J T#g0/i# h9VyT:|Mna  M l23"SdC `"thvGYZau7iIDATCV9 INl7i̲V^hGpS#B٫MQ܇QN`0h(ن`/<d"E`Ƃ4L'8fX8 p`sQB(!Xo2 xw@X7 5`#4|9s Ly9`w }ׯ6Qǽgff~ٟٽ{777߿O?= =Iqׇ i/BtQܻU'4`N!r F$ nE=i<*8BQ1pIe(BWa(1Út}M-qWAohA/*wI$aK:$FpBx-&e<7%qsOL8HKx4h[Q[d"@øk7Jb!"3Fqo0 EoXa{wWFnU޲bs$ĊLa܅ r!w 8H"B@UGn,ts #lZBFp I:$$1U.K],*/@B!jltu$0 G9u-@|N?ne5hPt`ŽFVؒVv8 c`3<6-sx܍] 'Stq /E@8_scQr[,0 ZlVTøXHٰÎd1"3GpGjhaT.@Q#xo)<W?Nv\F(*;;ʕ+oFj糴v]&e.jC<i?KaĵGP~ 2`Q;2\`khͧ}pPB!yakBnWk,zcʚ? @`6ldXY`ͻ[; ~I?u`kzW1v?2 ]" vw=itф%7aMv'S2`dGqM] i:qq>k(8_*F*ql¥x] ][.vY< !Czc$2\}FpO?lmFk(+NwA=%R~NăE|z=M$el -bѮ輈"tu|9y` @ֈoBtEpZ5~er-,zSU>%>8pe .2d(n#2d.i&(*RP, ]32(%Gʃ}$đXϧ~v]HtN"J;=Kڥ-[30ZGp|` Dc:M.a'DX9l ?0ޑ3p<(BWqQnU dH}!ů\[X%dWBq#2yּ~C&@`W7ˑb6`eGdx#lMBqKM]Җ-} ~c^[kŕ O%0t""`eK$6C_ѷG<>|v$xeO)$%%=}[IfS(:0'Y`?H p]*Mq`yZ0fzp׍pZ-~r8o"xZpy&:=ɐ!26DBl~ƀ(GnpBtEV)< )!d7n@Bbd0<.ᖽa芁!܁@i͸4n=}ZA Ti< PX1q{uPhqeg Ρ7v|e3XXdǡׂ#B1ғ@ՉiPqA{[`sOa|V)MEFl^( 7Q@xe[(IA2;vDxHEz965ĠOfǪDб;QtNz8:'qz$:/w%WyC dۙ&&&RRRRRR> pwСV6L@4EQ4M4h0 **1REQ_ HLLLJ&&&TK.Q2*++bccc 88811Q,)Jb)h4RIQltttbbT11Ν(?$U{@~~pttB*) Ek U?_]^[d"Bbh4v\]+Y n[~g}W8rBHomvi&I^rllLR cbb $$$Ў'OT6>>>$$c,MLLv\]b3gΈHUMLL ZISKBhyyY^ۿpRmZB,AAPŲ`t;MboqY/ ܳgBHjR%WK.!vo۷bhv܎"/,VLl ;]O^8JKŽjZqPbD!㓨xFxq(-@vC|9lUTރR60øA[q2qN CoAKx&X jc»vCq60t`"aȑՌL(܆X@ ۱V63PYܬF8NOuX"f MM2;62-`Ѕksdvc^i 6#  'P,{06;=](J|/݂+ȚS~R60#KFh̰&'a`3J46ғf\V\j>msjkkkkklsss mYa#%Җ_.:؍gMd>}-,֘b`=Q].9 CW';rg]‚.mO``Ww'UIa<*[k^vq+甓I"Rjqqw&erC23vITح Y ݈K\"IpAUu83b#`k^.1Edx ړ M[pJlm'7CQR9Czz9^+ɐ9sGhG?2\# ;BEg/ve4t!`K~|g ŭLj pYp&_X^HށTZZiXj_r ڐG _|yPiw@GKF#?R$Jԏ[waXы0E-=8VW8X< c!(R. 9&يTM&2+]Xp3npf9r r]rvz\BZ8چh +^ ۱>X2V j%'8:BV ;EErj]jDtI %; ߪwӉr&̊ S8-2`VWm48+@ ib9Ī@+WBQ(MW۰1 D1$M7ӀLr!Pl U f.]31DEAܮAjy"`sL(r0`l˜ w5hw-~B%N[d"K$=1Dg–mÄ )6\5Gg`Tt Q1H/wl3.pȓmxbF \*`WȬ`?IDw1w~p\vͩ?\[:zqо8(L{y;$zhQ)I!F XP/<#`Ԃ> ypքyqSx^xNfܭ#D"Il0V#{#uB P6^ qtD{ clRIQ"\]lq|7!G` v(L# *ȃB .QxQ2SgaBEO-x0)P e9-BçSgpPT-ܧK#g6 %xF"=M|HE*n% REsQx׋ >Ppgr4$b% JN =HRW.\;FNFi:q"'1-`nTZ! LuEx,\?B U#WL]m_0W#(DLp;-l( /ONlUG@M \D]lݏ3QwGnD.VӒitX)e@#Bw>t'ZHyWm?2?-Qxx?gLwϟbϐ%Rs^(u "DpoPI|b#S_~k!ŚPDum /6 w a)%Ȝ*, bl,<bxUS˝bԣlW%ռJp zpðЙK@fx,v?E1NW w(4zS.6H. ݸNZҀz[:ĉC/gbO~Z!nPP9NJфg[4=BYy.}lh"$TN&2OR{A&-b kJw DT ~I(O1g/ 8vm*Gqλ0,X9ܢwȋ g#س%yoQɑ Ng/,2G.!9@`ֻ:UFtgu$M&!d:B%­jF~{=uX*n{ObkI.6Ṗ.'bUHK!$+K>hMCBYN ᶴe J+G$S'p?O)Pu1'O$ PoQhpMOd)}+VG0 "v,}ݻ[ɗεk#^Fl=8|7;p {~2V{I%l8NFmm;蜂_'.|4{GO;܍ŦtE pPu,9.#2u~) E-n^򕧅!iJ%|m&/;v6[.S1^soKEg/U<8r؋KeώoxM"Hi" "_ȾuN3}{̼LGGXwmyCCCCCѥ?h3䋩K@JOtdv',u)Y/FX1H^H]%>K<>Y?_v SmD=JX[T$Pb_yb:  رcTh(R"@$Ё"T2m&*BĒb g1T.Ǣė[YCQWtl3Ў\Gz(`_T qP;݊Vc_M$‹ЯGvСN Q]^XfM 3B*A>!6y\B}[Lp@]~,0ĵ p{ۂ ؛)# WXt]l-E–L3hY^fXΠΨgC FB;SzKZD@pɎlq^3 kTHfkaӽ7 b$oT!La:W*_|Mt=XYXlQ]u0`:d`꘯3gؑ1IHr_+|e97\س3ŒW'37E;aÀst [,9UoQ r`W3քy~Ay"[^b0AHe2R72iB{4#40Fj34 $x`;jmxe9z0VP$wUg-`QU!ž晱p"ZRx=0]}jO%dvB&vc1PR`;[ ,ǎT[$iD^&"K"Js5Hs B5 s=||Ne)yDEpR3-L)>ꐤ&h3SYG2g`؛_ѷJәh__sXfB@nnKVT&"DDS-aEbGl0m""LD@ l/[/ޢEzDjf{K  z,'@Z2_`;CYƹ^Q!XҌWژlEqF3(b)$W2} >zAi"ďG5a}vZsJAcES{D(D[hP"MDd[*hoNʫ=D!042OPHH-2?4<"FɪxF9Ϗ yz &"DD '똇R@bG}\Ê0#'+^uEC\{} oG(2y$;+V<5]Y&&>`a%fYJj%=dhIn`jHgK;[p@'z"[[P~؎*P!"MDd3|Y^+%uRH&to7vC1 SH>Iis(ו@%2xy|XFZ=T'éX?vsu܎vF"Xf Uל dl=R/Fu3x#b $p ml\$dD=XR$dD8~bA+\f3ڷŹ^/c}:D8MS 6<[fi=8MaL8]<`GQ p^Q?״,L%hs`[ #L1#066տZZZ_qqq.]ݞI'<ˏo%Q źVF)Ȳ{i]-qBZ\rUcl*7B3Ƥ@w]@BsWQ6|>8Ȼ~Pu:S>%72(j)oYP5}dQz7R]ޓ EDg//y'(seKUeWM\g[+ܷhBo+љ/qDѼ6~Wu K 2tЂ7tb]l0YJrM{,uhg+󺏃 \.weVڇ2=.bK_"H@2}x$sZFW &"XQYKRƸ)~0KI*c'4]/sAV1wuX(I>ykY%2C\zsj}X$JGv ͮ1D՛=\=uU;=4U9Q1 '5/y3Uu"*'SJQɎȄCd ׺O\D52leʉ$w7''ym,/WjCX #v- 3@HAQ-sAu?}txV:ovK|cijǝ5a1[Uʖ0>w>gޚ1?T]aׄs·lKkJcZǽ5a!L@>XUyF؄&.*j ۣ?RH>77՜}RRo)@74D`9L8 T]1VD"mU s՜v@u|;aKU mȌV9O(Yad#AS]TB]\B(F*i¯giy$f3U/w,7GiLka$'|`n<8bWAE Hg o^὿ur?w9|pfffaa+M&)LdF}r~0T'H%gj OQ&[7Bj &d $(E OtD"NR*@,F:sbRB9 F@>U$2SKP0!סX@BhEmE)04H"H0hGoG@AXz|b朜'BZERmy1 )/L!T` C4)MdX2Wͱag RئPt|*srv-m-fAG5ۊ }n.QgDUYoWOPyk]I]k={7gY~u[xpq5 WؾU'ok+2+6G>W}] Z%PR-b[3E@ΪAWSnZ7vVn*R1_Xy rj'ݽb;ecGIwOAʳHYp ~gŧhY5l)<_Cf[*"Zx@Iv#|xȎ_C]MlF}͔X?߭Nݧ9竜16!_ !α%|+3/̯ʙ1wgv9+AW'Wn)R/m_TjWة&CP*m_$~M#;|鰻_짳PctWsH4GC8Wj:qwB8,Utm3(hr@{4#?ۜ%L܎[ZNv4_DZOD 97;̱B>VWE1 +lIPa@1Ѩ+l~bBȧxc\KdgM'ZXbH4@_>C1-I%W9ߒ[qΒ!TI_tov㭵߶ [!hd z=suE>FBȧSlZm΢ȁogSOw| KYgN+LvC\9tq>bNZrk ?3_sC~d| \u=Κ+)㧍t;+HTӍN #NXUr5Oӝ9fx69(zυOؑg_cm,ȿ/: ]^>~_cU)B>dzۜ~ nl_]}9l{&*KۚOΧ|i;׹/v26cq}ndH q+ҀY~o}q٠uZLE:pHS$N t^+T܅- 'QqtV ?NPp麜#'rgM'^tT8حh;t%!L&}{$H,X H 6TRH/{&3L?fr̙x/~+Y^k{u2C HgN \),{;.autXZN0E d<ܮjP",.v).3ȗ⎣-.VD !_=C`1)VeڬD( |2}vDf/akRz }@o‹ꖒ@[p#X" ( HT91٬g~.~d1VT.d˼ˏnf`@X_JhEf%f` 0I` <ȡRu#GmT(Lc0QT/':b301Jtc0ح`@n@ViSeD4&[,\W-hlxCflsIp&$. &amX̗[*>kF@"Jn2.l29a9 0Ƌ ~F7LK2֧730)5FXgN&0x Iau+c!|:a ޔRY`r,ʎ4~&)BxwRŽ*|QOlA<a!uׄ16~V eµh:1 CBxOĘ=d16 ls/5Vm#Fެ$MZzYD7F26}?6&^)/Fћ]& Lыo(* Fn! ƱV´,s@ոxC-v*HxvyI #hÞ#Y.9g[0mJ@Xjb{9 /2t3!yQ'zl^"rLL F2_>^9B QLW.An5#9 <[|81`-AkRyRz M欆98V#E,s#ܮ(Ef !`a6uLBTM fݥl^monZ;XZY|O?=o-1<_5бR8EVvyixճV8=;5·j@mW22xa,˶DҔƹ>Um:׺./8x m|az :NN~DO$[7%;r(5PeJ4u{y@kRȁYތn(ikHݒ/&sR_]H~=3RpydWFywuOYQu'Ap]ʺb5OA [W oHժ7k,15ߍ}p',qV7v)*{uI*% ͛қOG_Yvp*4F'%|Lݑ)54`s'?%xS`3\c-2.ҹVy8W<_$ˏf /8JAI7?-~HL1֖3)קNdLj,#̙ІND/: Pdei=na,֨J>P0}2g]VAVxf޺rϙ QiɋP YW(v)qT#;ҋ %ZCZSu(}Z&)eKA4Fyf'ѩKOM~YG1rlkBۛ;e zLt}-fTՁBl|%TCyS_ercHniCt7rt&ỦzҀ2S9֬A k \2oMԉe-vda;´ W%=*A3i9|7.MXf)@ #[^ =2I_OO-DҒX ut7m9Ѵ&uL&ϺЫYM~YKYB\8߅ \]r;ZgB`ܔn [ c#8j"O#@˝6hM"i۵YT]?IḤnEU] I]pG:Q7sBcRhgW%+CU٭nd-Hy~TbM)x^첩{QrӠ?A_-mPՔ#h_K얎Oa \7]A_NkPx˜;GcÚѴWIb9=c4 ŧIlgue튲[ʹUSt#EDAQ7/X· V-)/=2_4oU,ZN冓M=SyX!OJx^CҰ5G95(In$wK ]BϝRC*WHΏkzs/Pq X*%{;nЛo`*!qk8kY^MT]M-Kx08nϛʏMmZ\,6)*KO+eBOJ8@q2q}knÇ;TE&Y~|b#<gNR(>m49=coNjÚFDp㸦Bj%30O!Z!'w.J4 Ʌ.]Xp㠪Zz8ֿ`Lӝ;5*s D,5J~3F`*w)uBϵm14].9ץbI7si;=\Q>ȸ!Oe}fM!]g&r pܼXļ鯇խ0C<&/ni30f `s'>s52wq'5Ȯȋ8op.ROA쓸QC9r5UҋTΎfxP@]>.ۢY"Y+,bGq>o+&η ǽ!^epz~n]U7-;SsYkADX&xKQQ'J]X+gg!tZziHݚ#($Y߳iɝJ] $/-n a]r,(/<ǐa'Cn]I^pҐ$꺹+b[IEm F8*_Z#U h03033Xr8IW9""|0, J (Ctudbh@DH<|'MtA5EWd` X_Ge%j҄zdÊ,dH 6OKV^=};=ToT9?bFc_pt"b[+N KfsL$? j,wl$ɴzar`v,;r0l9lAIw} ǰo X­|[RrG#% c_0$6~FѣGhx|m25 3;_]6oL7}m( Go |`v-܂+ ҉39Mӗ#t;9BR$z(y»H`F;1("89TÓjj/d^k ؎_9ÿG*T4d>+cUd #cxZ&JijEA,IGf p'u&M12wd4KB/HIHڥ5M_AjLa 6zD, !.8 ňYhpRGVY1#jt&!h8 ;r8@hSBu#`F=X'Ib27i\hFUL "7Uh(}mHpu8!dd~^6y!a ,,GVҜWŇ"˃|֤ck#GbR4vU,wՉifD;|B@)^NE_4<ÓYKDtk 1MhSQ<[lynr{[^*c*GN+Й8!S0u ǎq2O07zItvYWUx]I[8~bQYUędD0L7ym%Zߧ57g~]jaErϗX\5K8Śܑ#.`բviq}\X,8[%?27`1x;!wձUKR|ZĚPbx 숮 aEsQ?v2t%lm3*Ɉ ΊbN{\ W0ڢCYlѫS?uΕ.P4~Rc'X$&u9dk#Gu3KF8Q|dg=J PanofB m7LŸ.|IkR9u] 7>;J9d-Nrxsulѫb0Id?GR~{ µܑnĠ7g~훯mr۾+*6wGv,}.ܑ#b]4~/Ê&:ιʩ_b.E}ؗdy-VL8F`U_7{C[/ 2[,\DaQy;~'g^%a^إϵKv}ad[Ep@3 aZ=2ŷ.xQİŖfE l?]2m*\mrقsDUSgmq ()GԀܑ#[^oE=S?vʐ ި>'\] NigMO#2&`*;\ LqyDH6rD .֋tJ mLg]y+K'HcٞZ3 aEcP/w͕׉c\¹ٰ,"K4/o3 ~v 1sm(,ptG[\ 5UWp#&w4ʮRR\lϾDk+Y/` \ؗH/+=$wf09AOt/RwۣRUӚlklkĀ-%QlωU6}c^GQ w8<ʀ{6d#`g ]Z8vb`@1F?cKl[lˍ*tag=CF!cVrG(le%.q{E4{IЛt쯍s{g(p_=33C;~ c/Ol. uQ|Iѓz+P_zg]Q:os`1+T3&82~&5g/KRBs]E[&*$fXIQT@ui\HgP£֩\ON\Cv[^OL|ByzK^lfMG,XSwԍ5)kRy=}S)]8O2. uqcZ!ʇNqXWxli fXzWyWp@S-݄삈#[FbANw2C-WX2<ڱ>~q94H|4 i<勤QĎ g\MP3p&ݺ&<12uf0ޏ}x)i$mtKreG+}\멊g--s y=8csMpte^!$m{SY,Nw>?faN|?{(g>E1er{ZjFTg}$A^G݇K{?sd(;bx]3cȘ5#?ʼnl,.֝d瓽74_jXW7S;Җ?/l`mc-z|!q׌1}ݑd+ztEv 0~m*/ɺ D}@E]nq 0$^B?< xQc/?؀ي/C]vX`;KfnՍmNh$^^!.ͪ?=\\⻱eJ"9+oށ6uvD8qr?#~Z{?aIkeC'Ū; LAaT.be? י4y=(DvI2䊠m"x~L(DV%{LczoWvqF;foپd{lYWa2lA+ { Hf>_?Hpxs;8k9y=P_v8*krd(; AXOZC/Z$gպ O08!oPMb,.FY̎֊oQf`FѶhq~t/-֠9D#">(Y=a]⢬-`@RUYs;ǖ|bP`nqI"I͎⒲n֍vOjo,4k6dn[*mU]7蛵}}σ[\\;fKdmqnD'b0SS;z-.6{ $p-`]gd-#i݋rq xyD MsN;maf;9sCS|7L^i5vOeu՛4y=v݋rQN\nr[jD'/NN Hk {9}~ĤڅU\.z`3BFPvΡ:K3-z(ޤ ܂LCsu; [Ԃ+rۂ 87Tzϑ}- x Fr^Q{x@ZWMtt=8qtv^!=ٗ ~-V DleJFbc=KYW']0X7vK\ٓk #T vΉt{ɐ }G`Q1a~YVd(џ$;]Y֓cu}fYVQUm \5fa/L;o*qd gfwsk~K ( h / v}#B+!j yrnGɖEh$<%v](;%v`E"xR$}\ȱkށ 3Oj:WZT9uuQf\Q(ur(u9ׂPxe$io#.-qfv|?;xbtAeÿ!ty?̰΃23W0Ð2CZ>:Jcr<MoJD@I*|8ɷZ^ щf\.^#CqnVmw}ϙoǑzqd8 6'_vN*:1IxƢ !C391֑ T]c,eBvaѺJc1EiW@+@ua:Vr#eQ;RlGP@_Ԏx,iQ82ptǒ,!W?AX䢭%`)ǦEG¢jcI v#⨋.j4ߑֱ!w$n1͐N|oGT%LO`GZZ,u "/Bq%(2))8vN[Q8+;:R qd>Mܨ$B0iT>dfz^e=t!䄖YdE_.𲶣f`[}z SK[LZS 2rE;Gb|ϫ&,|_U `6G=4!ntFY疡hdNw]3HJd2{A7Y tCoP 54梷0kNFSF]]ZA52syF'C7s罖NY4Sz`r^JL[6܅9L9n6v lX0-] 0\ 禁 fEsgD0=8JjKz SFF&qyԛ ]`Rz~qtCiaҽg3(D rVmX  ?0sR=.Zet26n TIiM^R"熾XfS`ʎ`;6f)3b+lJӯ8ҎN/0{9XYˌF}=f|l6SoLZ lq˒-Vw4Bv(\d\=e&`6GzIF% 0(G..~}.Qoa寴\=&dFH{ S=*/a0Pi\Ӗ8 waK09@8 -̷\¤  Ѩ8@Ь|wEB8"[/´D<gDoE(eow i4j,T,2T/~_>, >,+ 5bSCO|f,VE-Hx}laN9aD֠&c8)-rscϮ0@ }?aD axbn]^P;l/a3'4]aBvR#vG!%a/#h6K[o2|7qʹQ9yD΢ɤ/o?b5 .1#H5!0t}3"}AYu*9_u{ 7Z"^ް&@2|,2jodI%-L AXR#.i=aK"4uZHA"WOMW%7%2Tv\E6%õt 5(<1vi̮xՎ4O!JZ? z Cg]_PO_oϢ{قDliJT -gx:W5Ql"aj^q]0jRƦsbkuنq{d}F6 _!j(>YW~t^iY6&ڞo;F"q{Gg1-'ge69<>*:+DL(]K/nI {Eް_2ywq'v)3coKּzM'KJ[{.̫&72al)7Z>KcD7OMW/ ǮWu~ޅ`ǧ)l[go3!i$N~{UȔCmQ)a ^lDt.Kt^:3zp .7}SvCQ͈|jRڶ+X6qaki̛:FH䰗 7ZK Hd BPzd^=2GzCO=c1;tт7ѩ usHZfqL1r/Vsfa]}{ *: YmwHgVhfJZNhhgF\Dy,I>tik,mr|6}w~B ~nC66k-Ld}bELuVvm6PΞIu)klN9,mͽ\ȟK"x9[NX;pyꮓ4-<3zIH0*gmE=c…ۼP9i፭Cҽ+:,äZϬx2xybr˾c}^1k0h#8iv眹yn+,.6=j0_'N#5]d@\oxAuK a1OZiVnԫR0Uez'n[C\1M|-(Y1ZiI4@:{nZ;MU}[\lߣA"}wY[sʱuBX X.䰗/ ^d<ּ}@YMȭ(ۜxt}<=U_[tE~{T2?-ͫG"/!3'lyݧd'r1p-uKcvL6>?3VXEZHӲbv+48FG v7iXڨ@?^bcA f,`Ƣl ̱z.nqX>kZ90jLd*"_@2X4$sbmZ6]0 byK( P%GPew#٨xP8wVh22CF3fGIz>JX2ax_nuy"HK' qȦ9xY䒆b^:z8mьT>H;l)XbvKed20-R@j=εz9o7Z}?j0O϶y8'@jB:rpTV_8f,[r[Ԏ.dPQcMuvɰAk6qnO:X9@Ų_4LbHaHI Pn.D=+m?dBX,a1,.[+DIl-A$Ah AD$4`pv$"CGi (u2R#Wv| &D/щJO&Ş bl?TkD[kF!kP`V~{: )5dlijyZS-}k;5 "QW6#AҨxJV  xCo%Z:0Xϳs双W>_kfdoq@IDATm疩R{dݓL&4ᬸ3*)6Ӻgw,Q^ dO}pq²BC *nb2ESMQ/Ѩ֭s(ڲitWXd(*1ݺ;pml&O}'w4hD2T`a08'ΰ Puuy#"iq{A.*Չ% X#X7FKopABqTu`Рhۺb0x_|fj>(IoDȣU$-djɮ?ZNEGoCd3]..qB5Yqd]uIgjdK[γ Z^ߗfkk: T_Y颺D6?ZPkr Y\K?w_D];%n?(myAz&>޺]P[,FDFwnln"-6giS▚;g3[ExأA\_AnSx\KHw$m7i|bqi\-Tgomc ŭ\bүި؇SRSXUwdVڝ."#}Z#)9LJ`RۢUQ ljHKK݅r 73bSQ(ܢ=z U² D[4Ą[;!=鞙SS)7*!A|l7o+&ƶӝvk^@ Kv]d\Kݒ9 \hM=04r_`KJźFG= &F>z.<)i+RTF#ANQTJ$'yHH}L@l SH{ E'zp vϞ=m?(JԩS*Drf)ss]焂H3 tu_QYiW56R('8 "+k QYƪxS#M<}Ef㗒yV61Qgp|oI|ԋ*,#^ή_'tWA|~cTcOalH%K&XJ, +C+,GM1/2 ;G 䍌U$Ƽ:1,Q:u!,щjO%0 5~E&žm5"1kPL DhiW㓵IM[;ΈۻzwƆT6BԚ`;{18XVp_l]a-wvk>Ipa2=LujjI$TNc7^V (dNmW>+[ciXк h4j]]n*GTŎA(¯o:yN6H$ZNsǂLO ŋDCE#%|nF; pwKi%ZˍA Od\?斎BCZ\SDK{sG+,_A-Fd@)=`0"y30 \=i I+t/,97?ɐ D l6heCnHOu^Q6%Lg{HuzG`DtFbpịczFoP#08Ѩ=LD2]HxΡH1:ۣsoy7G*kD!qO5ҡTdd6uCv+hR5jjq9 ydl⦛w$RX]T$-tZ+kj7JV*Qv=$:䳳NG2 |N#b6Qãe*x5 G VuRl0ō}hG*Sho9`Si,$6AfdEYEoU 368QFqllhb9l0HLd6s!v@ T2hH|' ;;FȦE?rCH Q.vO ),$wB91:^x?VсbgGTP${D !,Yt9ِ5 ~*ӹZ+AV#R @RBh4vx .ONNJ$㓞#H9tu嗶\ҦFkSݓ'Z:1R|"erlgj#t7j;Ӊmo#^2:];] hê?`$&#xXMt6)1K?!ݺ1<;>;ݞϝ K o#%t%,s ǙlOߠ{-`cq|-ԨK[Hp8zsNʮ䬷ߨYjYrTz&L U!P_yT28"=mkOdVDT~e{-x卵w$W`M 3>\) Wd <p]gtJkɱmk~AASz}g\$CMA:ǃD 3헜cfz`|tkBK7n>i5sNc|?> bl'ޖKnTn#ŕv96k[;R7(ڒg+ Mn+:S1_bh (1+o&eF_+:F`ZWѾRsx` _ *j>MFTa0؄+v4L ]SK+HeXoݖj975^65RBrY&"68# ǯ.?}h4ڵk͚5?SSSԔ^9xwqڵn~$o]z&nOe KzW=헐`c7+?s.@H=hqJmI햏b-*r|&/bIsV3WY.J.C)[3 _Uy"L_rm;%'^$^Qd6$n é4Mf)& ){s|E+j-&%xbbHO3w[\}ҋsMOE-yۮi+?l+GƋY+)9(J}d&3=msK<Vd(Of=YTқz(8wx)B=SZmΝ;gA٫V$W^y%77XN3_&.RtGt:[~0^w(n-)6/Ϸ"ec3-} KzL\08msA]Wk? }?r!:usHɵ2m/0 r]P죵w_ *Ni+ hʂЙ=헚n~M|+-a>hF>cH|裱5H+(?5ٚw-}ّtuNzּט^#G 0nd_H{ŎTWCAd]8@a]N-&Z2҉]07[sB+oOq08<+1ڑHg- d?'}h2ڊ-ſ2sܐwP:,4<>KkՊ?iGU]NbN> ?(g-8`-R3y`}vxC?a8*{x-O|e6^Ⱦx"Vk!>`6/1D{͟m#$(V 2+?6-LP2Yq:,v-{xxőlp23\Wq~KPFpF4 Uv)laqLB1tU;}.m'oN;3lN:ds=v`uWUO$9;ʾXvl~`Z(հ5P{$~ݎjiO$d3}=ۆ-z6L׶!Ybla9uVd{U C Ƭڋdh~H2ޚA5s#vz=lˍc ;Tv}vV`~v0a݇nĝ[خAga1ߤ~7\;8jG#m%Ǒ`ժ? KiGtG꯾_#0;˿A1c^[cwΫÀ|5lE-SvZ"s`ƒSyvI(c߃%/j@_ݹ+^zX^< ]rGɾ:hćΌ7bh;(Lx=r6qEQʦl9ս,y` :e$:/^+# >-Gٿ 7#? I;;]k/ގX=ZquFi=zA}à|vVkPĝ[[}o쪋;PQZn x+v.έ] v,6IU{1boH]Aڟ;+NqWb?V_ډ'cy6\; Ix΃tM?tZZZ{{;y|UJJJ,s=xEWw{$ d_EïKBW2t'Q\w! .a-/QL= Ζj`O|XT&?ቢ}mgHTn}8 b׷_׼|PӞfJpKF:HKO}|>;^7֨$HZ߻ʐ|SdKR;Q&J~ xA: 7\;u?`zGĝ.Ka1Q_^O]*˥>Å)K|`Ž~S=MyŮr%.֪pBR] Wj{Dˍc> ^p[^wtrEw[}z=q+4wn9_yЌL'Ɍ8<Tv(korwSȦ{JE6`ɓ}5- %0]WD33 y >lG߱cwpJNU]{-xPs7*oYp Z֘w`$̜@ԃEkBJG&X'v(,Ɏ/U1ѯ0i4z"r<Nu Kmv|qN]S!d&kCPj!Ƃd#@8 oN-(Xw'8ܘ_3Hn!H8R'^Afr4s$9j~]%0HhCxFD7)LDK(ՄeH(?^=goG#X`&-⤒O;@x"-OqEjA''RfTK S! 8Nj`~[Zh- qa8\ 1&:|.bKb. a!n嘭? E:`K _ PXč`.P.Z@a8WfF.B@^%-9 *%D0dS!ZH69R4D2cx#0X<䑬 ,mֺ-7xIo;f5,Ɏ߸q޼p~>!~+dx5B{d)CCCs%{͚5&_e{s8-̀ B$!}sx@N` $$! v,GPn0H .R7I'Eœt.ad3@o,p<A'ax$!␗SxnXv7rD5@ciI5\7A(:a.(t h1x [wc?hg;^$HL>R'q/D Lw %mL@)@`pxTkY!c $k #МP] PY>yR8'38 =n9.;Hfn'jltOHI^hȎ–GF>;^DJz?`q@vF'9eUL7OpP"9%*)I.(ZԎ%:n{_Vw}gj_Z'꯹Fa :Y_-)$D?jEq0Hĵpկf"Of|Y΍՞pRώ>{id P wy$No]ҟk~#Ⱥf{kkOmR7t`{GhdSH P<la./8uop='u I=r6(\"ig{G; =y'fD $uz/"O]W?7 0jvV(̨U}_^O2-?CNNֵ?r V'zjOoay+?fDvV"GAX,8_#!s\j꙼ӹюЇ;ú,f.$Hb Y(aOwWמLw)etQ;Jbt `!jOmh܀S[Vl` s\2V~=l>Ujm/0<^o<6jx8GgO] e*,y3ʙ[n$xm( g$QvͩUۈt.\կq8Zč#B*@-hҸLϏv` U#n@C WlnZb]6:w:@)<<wV,}ii-Rr3zZ_?Pv6쑽?AIۓr Gr;[Ӭv_;nЪ`al7X^ava Dw{TVO4݃¨7|µI|}.Q9.ekSe x6?m>^Cdxbvv-N:##̙3wb6>l-꺊N5tv6&a1KC-%KZT҉sQdsݙm +vǑo+΅ T (nk,-Bb\Q#54S%}uHM[pjc&ysZ fNozE 7ݫSg@|gU,օ) =(d_-lLQh-Adžuf§C%" ^3Ԟ Jv OG24|K lXzOjWΎϱUv ;;^x_1=n'l7]o_ه#[ǺZ/q$j;0!AAhZ͒F$p߫׿*0;PB"0ҧR<\wz+-#T8ѷw!/qH + Ώw՞vN?˚ 3c}2>k}8"|wz\5Gdۥix`~+t[B7()dNTyQrj> ?Lwޑ'?goڊ ֭NHw;U5;nc[j'&&<>:~8_x=]_57u1z=ZgCloVk-C</'s]h~WମOEok |!Oz?^ zJw~tCHڎ?>Do CrEaGjK)1QK F?s*}ow'<{jjOmvZ Qn; [o(O~SH޷-Y$ lFڊx5^l[^F|7|킨yG3?-_f;|{1ٵtr;䄬1Pc0H{D=ه?ku2R{G|r\?l ՞mQ fĪ3l]C 71s=y_[}f$M6 Byy*TG.Oo*ANoUΎLWe1پw>vبy#7|oga'iפ{xs NjȦ}$ YgS#A ه@݈p~wfqO L;ږ`*~p+ꅵ#]>fy`kOmX%pK]׾D:{Gp=5|x]ɀrAla{GԞ"9{􇼗?!]GjlSS@ <>, \`?2w~1vGә],QbvaHq7Qb˟;nW/=Erc:f[53bP1tlIe9UcZF22jD۠G_, C|y& 5Ue*QzvGף9~;IOC?KG|<Ch>yvn/.$G%ݵnId2LGZ44(;\-[ky9~ pnbvYc{C2gno J4Ӝ} 7 Q  ҂d?ӟwe`6A{~caPHLf~&dv{;b VBoG&VM*c -K -?es[# 91jUDϲEm1"w.::1/l/Aw8ZsY~2C8rO\;w궟 vϞ=mXt'xuԩ;@ @T:uJVScp. z[9g]3׶}diL`2Zp_. ‘g-ҾF8A9?|'? fvNw(d;0S5io8@+%D6à^!UB8^%E.1r_+.A_\w׽db_ΏwS=|f3;060Iv"`5~S4`P97Z 3熧 XE+ È{#߾ ̦B[#0t] /R=3S$͎Na ނu뒾}&N37%2 H;2B$ \i s~Y/)9SJ$}u3 SmM S0x ʇ:LŃ|V991L&='8f AlFPJ.agg fa|JzůB_=.x=?h k*١zkĜ$Yo[Znް򢩚XZ?eB^E;s7l kljO j%?J51ԛv7c%3*3x㻭nY #,[muɼ2>w 0L}QГ=וAϿzxk#LRLV]8Ω2,“]2+n3fGȴ:h;-ɷ$ @#cF>9 ;\ )R"cMs^)c*{|zlGs 'mnh>g; ՛,,C^Kjg`|w#?fks{[>}47?Xo>!?:9Śd&&i$}VY?2K~%n*w>ߵ,F&xo/o;S#͎e4Ψ p6_|-Gxt|_#͟mv^ou]C ?`~Q&.Esg[+6} Zmx'P5} LK6v|'` w2HOCWN=kۚv6}锔 棯u}+CWN䣳 J[.Lk/pضvCX!G_#/~_?/F+bݖFb3c-ǶP}}f c3 76}Lv$7mx6(IhOg.vN2E|* tl|o(n3@|uNx0.DR6;:%42Z x͑}C_H>:{Inb ` [E-i>\wRWz=Pvbs} f[m%  [8O378< O<9$n϶EYk,c϶߱{SvT>Lǩ}}&@FNi(FI2׾ }rrC4,FA棯KګQԛ2`~7l~3vakgUMr K_8oCҎ_>E5m'vZllb zTُ'-iVMg~ Šll3'eHF61-_yQ ~YA1vP?oFNN[ho>:+$gkV m_rz\7{,ŏ4t#[i􍰋^ndZLT\{ʱW?"{]==ZK e_l%>Md<{2>w }#ho]^'&+ 1қ׼ċIo>\ȖsJG6^f$%ڡƞ:vKq(!ϕOe?5k./H[O6 ( y=^uE,qҗk_rɴ9i<*BߠN b(H yCl7ַV@Hù?Mr',+n>:?~j/+C^?QziIob=P՛z4RRNgZYr$oǧs6} O/y]w"S#-m߆!iW]Y-wᨸ4l̅U}s={u1wYh!vn-o[%ǶV=. znX?OC%0)4B^ϋ/l?<ﱭ h-ǶREOS]Da u2C ߉σr“.k\2^ëJt`ؖHQΞtb߅ޫwͲ}![>|t3+8w]H+(&l3 7~=]飹ưQ*qdt:JcaWW_Œ<AX׿(#87țȱb6V#PH9k!h;+d~ǟ%̰(rlk؋Qde @9MswTB'2 2_>]6x׽ϡC^um<ݑa_nz,E-:#y;Av<3lbF‹K {8f8*:i>(pSʝ(kj-DF/f g%̌Vu_O3x/JW&vuZoG]Xd=$t?[qz* ?.v^-^^~e[.˗/W-yC-ڂ"< Kئr$H rZAc-0XǶ.BX[F@XrC,?_ 1wd_/p a||QR9\ǹ +kfZ3Y;oPƑUVV hn ܌O%Hz_dkzKx#/r4 y+BU7I~Oc Ē)8*j[ 7bſ>*JC$5{ޚI#5śeb@DRi\˸b~PQW]0lR)H_х9nz Gd/ܔb4n]00l¶fu{{x8(.`0R&Mwt; O^<4- f qd.CPɹC8u U]P_m r4~x!v̦Y~BtGӗ ?3zF; c@KQ'foJ.Dm.ETSy4gpӻ$]@X" _o|te$)"1Nb_f|Qg;{j5}ZkwksX]9=< 6~Yɭ}`fq{KU'0-6S1H CNSa[{)mŽBmht IEp:@6՛đ) Wѐp+ᵺO׼0xcĸk<%2'ɘoY k*̶4#}qMw8`08eT/4&=." X&]fp4:Fy_r3> 3Y K~T~3kf lFOGYAh$KwSplW ρSp|t\f>/'YAPt6V{it<* ` KXq{z /=YV`]aWx2.e/q_u(l.Gk* O?r{l1lOxCc-(n~UŚng0Gϋ+joE+'l:z0B݋O-߬;Qa;d.duA8"lhV-GpE7ezϪj+Eqf roB3a)ۥa;<7ܳDŭ;u>{٦^(Eq|O?3a{" ՞CbawAR*7 {r{vU#[E1ak6~Q_V<+`}X-:Rl>5iޑ=.˯jfEWݬQւ3~־]UEgC2xmf^^_t)GQc'm_F(n}e%-bɔ(_ Q6^1)7܃]zkfuI[3?{h9M4ZƵ 9{%;{,S]y' -Ga6(wN"9f5ߦ\t:hs*]?kiCߥ;?k\FnncitwoW)fl]=axtFogYAaO {wh-thf-(nf^~37܃1x"l#"򣔢ۏ h/Dҫ\y|l~C6f})?;d.|"2tzÞEzNY ֖^:ZS.X;as}ޑ=j&f[m!ZWDּU37}PnH{R{mEKWUyaO 4m~D]){ECL`Ƹ6zc(i^ܫ}dl3clk0*X~e {c4fy0m&˷EvUZ 5yX4wOAQ;gC4.Ri"]ӟk J!msnn1]Wn3Gi;MqFK7NG67vаk ,Б8u 5z`3=m-&˷uS-Zc'>Nhn95sVlkg}j,#8O{DQ$'y?4GÐԨՌ*Lj|°/)<(R[W Їhv~{^/Ѯ螖ʤZ3?k;Mn3WqT" -*8%oJ?>Կ~)>LtvUk` sTV߿i܎⨴0x|gE "S_DsSs]5;xhbNСHs3@sĸš75f|j v'TZ{I`{ClbAdϹqV\Sf.+>wǵ "C5k˷;Pl¦LCFH{z*nuy Q8:܆bѯƙ^+HbXZt:HmK QQZ}ixHsضoR%9aŀsmKL^&d#s"S_{KŹd#sNvZ-tqJ*dk 1f}!Lχчd-_x%mmq?,*nѿ2Mm@giwr<2^>d@܎jk0DRgyzDm=2۔n?s󬠮t^A-Lv!;K^ml`@Ok3/IU\=1ڋs4l54)&~C87 [qkҢNG0V h%w& - _uipn8-`̀%S(VcD&˶uTRLZ:c'<֞I5f\^qL[Ok!@P1ӪWXV&Jҟkrp8uA$=Êk"-22۔k=vr孋)k+': }ub^ޫ}^1  Z>#&@:)n[t<'u_WYwSS  [݋Rn^t㤽wȓ#Kl`¯)W@GQղ6l/n$SV]|ȇ Y]ݸ? (z[7(XzOW;1x$7*[[7~u}GA6z JTHSUV(Wc/Qj,.ni$glΊ"urؚX:ʔ9T(+*t Z +E]=M ̩noJ%xM >-q-_ӤʊU34iJA1S:;٭0b`2* aÄ-rt~HR)ҎbGI1JNvkx'B!cI #Ռb6^[Dd}Ձ#wVKR:8;٭ lmG-f IeGac=r Ɛah;RP=(jnӇ߿(Qŭ66cQ J!utJ@խ]y]Nvkx@ @0]f5zlHm?3U/2&Ba~{o\ '#{)xoMMM 4E U#[Dai8uNfEadD?ː(@[Ao L!jƦHdnt-dhzC$aDpj^XE"9Շ8"#au$#c%kic:}ر A" i!aV<l@ la `وC<2` 1LᵴQX:RlmRgACA"cTH"s|0I6iJ 4)LFbZDaD IM 8uOCRCp Ro DLV#f ūkO dIi0 <8u ln RQtMGTA# HFN7`tG'A JgzADC!Ad]=QFԞ< @~{:I'h3!,Ф `ɖN0C_)fށ~~_W΁ zv^q^Ƹ -sjϚې`|-F]"NKK1Zg<ݎLe=qSLx!몺x($6=O8AP=ZESg~vx$s!a#Kʳ1d5,U)NU\˫򣫼]p/+75!>jhL.FmB<H`_<ԇ`qpX6@P0" #飜dS, UZL:Lw"~%Vر[|`/y< $lYD0`oHnr=RqV2``eIH's2*&*/AI[~j;BUʊpt~hJy}Fij%EENm^WRcaԩX :Ծ-=M{,gO5t𨎎y}"$ؗ>n`Ӷf{`zrJB1ƎoyTwBH.ۧ"?L *::e|;nxu<ȟs*K 5F0gˣ>8͍NA1l_/kk 9g1FӞ2KS~iӧ)˱Jv Ps.[Yey7Q_NfΑ~tF,/`<º>ӱd2R{5.Mޞσ6ܱw⥜0H$E^;ðuWSY]QFl7_~\UJwF~U#vlE*9_s}Wt_sBSCC8"U@9Da}]qs|e_W)ޙ]>|T"%V)TDGnyQ7[v8I21-#lGu/ ?}Ga]f"VZ{3m}㙺Ł{Eȕy)uDa","{/@CUhy,2Xg"E/BYo0ܺ{Y?90$dj]2KJv,?"4 !.]3QYdp˛41QM/\>s LL({ qv\=mFIO'gw1wڛw?:Q#Fl{u[;՟ʃWg]?j sDo0-ERD5u^VEĈlGgμ?d7SړggY|$A8\}}BE~f UR}ر2Dt76Z^>qo%-F9PS*FJRʠKԌMI"bW+%4x" @)m(QW#~UbwcYq}#^KϟPyCaTn1,Dh8ߌ~fy ON3ܶ0"Py>aGE)HJWNtcǫںQ?,Xx&*ΙbwWU&'"E\. ou)JE"C%E)$'2 G֣#W="4\jOK3F>1Ý^a$jtZ7EĪkPDIw7 }Kh)V T5SsG(jmA7A,&"`$[fnT!zHH av`)hW""7$^棪Ӛ:9%h`L*BN!Ź^kdx/ LQfJ@-U5#!R 1m7P{fJ1D"n\sT$QD(Q:L .?*: zQmj]x^OUkN ӧ",dJ,u(6 ,jmSSAwuaPM8tZ@#tuݣ [@dp ,VO ^ڼ]iFʎ'"Ol<7Y@"^\(xiU01mro/oByD 3 ۶c9P03 0mܘ0X1iՐ/ Mo3DceOcJe53AZ z`+@*U5DR6a,H*|ds=ᥥK@e9Upvz?}R:^XR4 X*hΙ <~f60p+\*d%S«DŝDSc #@KG=D$"AXlVaǐpq{%NG&6\U\ jOa] Sh%)RH$iw7D*֘8.+ijRB7R^Z:`JE*>f"E41j>r8Js8:cG?H%U 5%JC[ߤ)  5vvMORXs Dʁ sq~HkΚ^wT$b,#Χp1kΚ^}$ GS(|5 :M ќ5Mީᗮ& }dne"R)-Ҟ?9po]]T{;Pj}\܂k1kb}09z2x@͉6p>QӵO#tKB hRΎ&`X5Ksej&FWnw xT ;77hΚ=}s }ɳk5'݃pxŮ][N/^UY{$Ը)=mM~ _G8] aݥ0Bݩ3ݕcNŘ1>QJkG]5K wqZ܂%E-\&*pn˭FQ*yi-pT3+lΆ=䧆 +*$">^gf#˶y1W.ǏTxP;,>6b08'D?H6/7o"p=8Žq9y޻j奥WxZŽ-rOo۬0P@\~lC>}_ "*˯>}a#ۼ)D\.:w<}twnn}2.wxrO.+H)ܩ2萰aE _lyJ4/^Wi.,?2g'e^\TuA=FQbԙoOE'qAIiٮ=dہ<b9X(dGSm/_םR5 r+AR`phnZ-GUWxaE:OvdH˃G/8%4]I,c>b2/}Ɣ{y> o$4\$GVBG+3̠:(z;\*7:!ԝmI~j|*hncʋʃZ Ue- D5O{6:T$8Q̍k#9 ۔ޫzziUagJJ8ٚ.ht,@J_e;:ynGvW a<#8 5^x[m|0U++toԘ:lWG(nwW g$YӀBdyÛhl T<dt, ^6>[Mq$;"X*T*E`^Koct/PbU\n|*6:ra-)`bW^~ٮ=޻v\`hk BuıOFiW*]X:o*.Å1gF~T:/(4> 4:qXPRVt04(߳ŭs3m^_!{6]iw AN_Z~iuy:ºroʀnQT@ӭ;ukSԑHf'MMҲ]{4اt=;)#;{K՞BG2_ȍmXvdHG/jȃqZF +*ɂ{>h{]XoziX2gO06kv%Y[ ],Pn32kcR \Aru1Z!l,OFt|YqLR i2jdltZK079{<eHwOQ VhFrgo]{o7М3+ g(rRKc e؛0Aam̍k5ͪ Q^\w_Ddˣp:F' *8aPoTb1T @wF)e;?~OUk\Fk#sֽ.V`~R#Ux+ܮXӫ3# \Bb7Zf+(۵2Nb`X ;{YMı?OF3Hf&M p2Td[.$0Ta]IDAT/ڢl^aub[tag/aQƧ"[֟% r/0V>A۪fw{ ]X!MI qWSyd FG%U0=-\0ј.FƵ7- a,vCCi/QƌD"zNTuGNxD DztQvīQ{:1o_K,@Վ\}}֧/C"$@% #8C=am]rQ*܄5+z۫EǫwT'3^ՉU Rf2 U1ٿ##8}ίyS^kΝه#>"Zw|F@*}=U5=LaL Kܸ1k 9m1pLa}j7ew.zLj\c8uCV #1MၣJ),Q%p8"[C{ҩ14b!FZvLt{//h"`0r|хD3#^.$]C D IHDAjP>VCa$2@Zc5h  CQx=&C"BX Š`KfldjOj1AvaHD8,}dbipAjLP0$"H И6>H, 7a?{? ;@(cXڎvCksBP8 T[)Q2EL(pLm q!h0<ǣJ7EPaX{O{!^K2[,C`BKњa.cTJӇq8Azv) vW :;7o(82ƴ"UT6ՙ>Ox(jR6_]P"nm\=5ڀ(DDʭxK^ӦMg񞾑XՑDr~[WхxKqϙPGªʍ8] IWhfg̰\qN[0x^bսjG jA!Z3ud">oTw [՟>2낣P^ u1T sKyH!:+7rMLQ_$+ ^nr+@I": As"]6œU;`5Jvljܴo'w#{K5gֆ%08ݛ6}lm@ʎIc:ҾĆqOȩ޸/Az!uLJ‹M1W{j9Zkoc~B8,ن]9(ʹV  Jgw u!" [b| =?Ym&=ICj.4DvH6yD3=ڔq R=6]{Z^:?{Ӧ:lK|_BOV^/fc?ާLΦƊ"q+r~RjZ0$J'.&=1<{f!5sqzMĞʍ~J՞V~| €QӺ:ۖiº K9})J_UJE=I0ʭȌ]piv>*woJ`HxmK|dYӕ]ZWowo gc}: HU;Xm9|ʁ]l ̭ܴ`b@=Hް]Hbñm_G~ͷ=zYsX}NW!Ts6 /'vsj|8]~Ns\8o ƗÛ/$4*te)CUچRwq{e*-HQ-CU޴I *0<+S#y-g ܽ.cպ$~8]Mƒi!Y{cpXm6ЂWȩVE={[cüz!QS~`bPiY9km_*R7r^SUW,Si|@&<Z+{G[-އ2zR6 zcUq9]?sPy}so PG XQ>9/-h? ιMgf֘Xe.ikܼeE)4W^_\ˍH&)yOT{j}9LX)⼮z͕ab/PdZG7#SoUPxWq|ڴ^X M>NgL۷6y4ݻ/X2]?pkct|K| Mg\:OcŽ1×iܮ5׸1=ԅp9)_oZ7_gb]ZbX BP"i0:tƗ)C`"]+)U"ٕy*Vi.Q "6u,?SuŅvqj| ʝ=2{lwGzogMb{6lUmMh ϛ#+[c^Ś/w!ܚfmn8vHaO"=OyPs .Er>9Z7ke]Im%gpKTgE&`AjNa)lkmpHuֺ5m^DuG) BHOm}R"a܎2ˎQjNdLJ(nlOjX2&v~{&ۿIaG w(n)^mKDkS_9`1 (uTnޏ7`"'.uYk|CXP_|7=zq\>{z穖|8>jGh]QTsjP lh#5DVT_Zޓ7+%K:8}'D:H-UpLl L$Zԅ56!aZn5)Bψ&U;gv48.䤸T8\7/˨DcŽ##*7dL uхߨ='%"6Yq~sת7v/TdMKcW.ZcZuf0[5(N1plW '04Eo[Z+kd|)jסڀ(R?y2SchX4!ꂰT8G/,ELJUm .(%ZhYPeh*E?xG>Zk&>jVm%2j(é"V>;r?QB:V~ ܳBgE쳇Z.xM?`+L=]XZI1t)[ =G%Ɨnf"t4Qjps+3TPTP(Pjv* ?!R?mwŹ] mo8ތ p|Xbk*cwez&=/Ő(ЦL=y%٘LYD1kMzFhAeHUڪ]a#=. پ Ty`/G8²jIcJPU45PDiHJ%pA)hF=jn=*G8DK##cu*Ka sT KvdzneICԥ?Uw6Ф҇k(3CL !ژT#!twbn+^O3X 8Sx& L.,55!a X1+`N]% ²Ot93G=}l^.nMza^sېqOwaYm{+J%p-$vGdDtB!R*}UBa*GPXJbT8шY|W4* W.9za}0 A^`%;h4Pfe R3$+VwQ)R-+7Vx=z/%]r, aEMf%(Qk#:?t@w9Bc+$&>pKng~A^۪ﻢ#3eNo\}@*nMzBaˉ2 XjE+ƨṷRTBmwԷ|R H}-RCC1PR }#gOWf~Oma)XPѼ_}kS"5  M-p.c;vVj.6BlPʇj%D-Jq<_WN^+!V}B+ rAkQU/?%<^W=  9r=:֕_8ejL`; DIH;2捫X]A V}Uۃ W޵xһ S?׽R)y5c<)>&0VcwY,#x~5rkkkCG +jGMUާL:cjo?7m_k:e4zj(Vi-|AkQMu3iD sWCu6oc;rU5Run]م%+)}29ls +NbX 9xQZiH{لJX9lX %ͳb(Zod ),R3Xu5&("q4-7|55t Mcv/:` Ca=' Zx=M!cA kǐIi?JitŽ|AŦZ'4]{ڷ:94R!{>ձ{z&ey0AÉ*v2klAv)@+QlS.&.ݵ2Rq1sG:vY~iv7 gQM0ti +6]\ĹXA^5[*aמ=@6'ܕURğqfه<B6X}7ǠT2U׆_֘`-4fwƣFyĄu3aW1: 9z;MZ9Mc"R}!V`Ƴw%%&;ʷ`oBwe(Wl=̵3Q~FX *ުxe`Vy0A} d_j}^;oa؞*S:=R9[PYwI4{w4Ԇ^tv>{AXVkdMIlj" %KתWS9dB*)q́X)f_Kg6~ӿRsSI~Ky(ΎwFi-BDDe uoӮǻrJ,1DR_Ys rѿk$o%HWK }l6$5O0>*|]ðV#>;?e!'@@{uGHتxQ؏>Qk-巟XbvA)$}aM29=\6ζt/Ŗjr@[n82)sMy~(_r2gF*]]lnc(ԅ]ziD5d.V} }-hgoz pCDb~Y*}1oZ>XSvb?ᆡkY7XY`y J0Ejiy`۟y)b>C/[4=tAwe4_K𫏼lɊ5?I[{&3;ȃJt)sy,:(Xzkˤ H tw9 kA4+[~@ +6I]ה 8{2)(R͗gdnTJrgQDe`\Tد=L^j|lkƘ;M~ƽ^qJbg8S$j'*]YŖfQ:C}PUuG"6u)?Wƴa(bWIXO~Ǡ!R¿8UU4M3E X>b9 ߪ |ּ1(b͡k7'aSH*BwEXYWٻzF *2cIU"/mܐD–.9:B)aZ BteR&AІ>7.FEMTEj8w_^ ;E7TSSC&LC `8EiDhTa!RTɜŘᨪpGKBXL}C3UkJ2bzZD,>gLNX8,ȃ6R!bl/Vzvf9,Bcv}vL*C&>!T:tvpQ#aG>h|b; =ԄnRb#?Й}*pӳe@նjjӃ/n!@g#H*dS}Yg(]Ft]T-h{σaۿwf=K5Ͱd50CP{ w΄w?E4hGᰢ.Ӡe ˯6>̟9+Y}ܥG! 5qPGaEY]֞<`"JϦ Sag2 ! >v?=Ii6 tq_lϹ2% %UlW"@uk]e !T{R;*S*=&ȓaNiyNxcڲ;ðwՇ[°EI$`MնwvFaĊ$AAKza;K,KUYr@X5"'T"5X? F-3;D{pXM o 82z=܋*V; kt6NgedkCXք%&Ú:=k8VsU"1 U֘A"9<-?d ˖=aC-Yq H =~E|Wiq4p ;b-e7!21[1p6P,t*Nmޙ,w&ܴP 9r@y؊;'f/>AS!܄-g%]oD&^CbT,empHmT5mY HK~y#k455[M(`-)ߥ=bc%u#Te=d)-_͊P# [5s=  [X}6MCMWۺkM>K=#IFuiO?-J Z괡&%{x-l3FgK-O<px[XwCJۙY9rwȍD+2gR<R`Bmk^߻6G935-E|iCnWF!:.ji논jݏO|)Te wĚx(uX,.{&9o˓o{Qu{q_rxֻ1;}EP~~SACEB6$]W==uܼJ.nd nF[^fd _ht &lnG2oryCI5g^N*?'c`̙!-~"N=}:n=!7w@oOzL7kfj:MVndK[!$gRak5ϜL^=e ׿ɵH%G!dpz:sWCI[uq+ߑ5c1=TͷQ-, p빎>y&AP,t [a6uE4>PJ~n{}{͙POw?܋SWSDܪ9|Hnu[ceQF&Z(q[H!هpy$qHN, H)ư_*C2g}RJbo}dYߵ3O`r_d{!ztm#]dG@M󒽗Bk(N+ɜ2 ̜ő,4$Q<=We]OoŞq7ִ̙!nl,G1q;Ze4]m 6], (]9ro rW5yao6X:f͕qߥ OCd =GޝJ 6!)d e5"dK&.; zzV-W}/}R F!&}sv^ЙrGʶ(KI؅Ҍ)^}Nhl2'΀wjg;~W("fgaYC 23`әiFWJy:v 9}^xne(lh˚F1tIqI[]hw^;1$agg!_$ý]5OYD uqUtrypb d ѝ3&Be>u^v4sHlg_^ہl"f03  kZ$d@M&:K6҄k9#w~AТFN- w~ad8DB8 AH"Q. I2@AB!")qu9CP(Ts "My{  q!I4[%P:c-cBrZl:Iys=ŒH"HS oqT"Jd#M df !,mqYx @1BۇuXtz" p8BfQJCD KYl2:`T&$kth$q̃-"Ncq5G!m@1xŦq.H+ke(Ͱd,_oFVUz(X}QUz8L jɔO񫑏R(1 $ 5n%-) vG[Ò }[@l]d#M^Վf,ohTTԹsVZo߾ `|۩і' Q.}ykuRuO. vyؔH^syue֖U6񘦝a'xj F&3C#`h9jz˭*x6y恦%pÇͷQn#?- #OW%(}IJ.˪K6H%sQe!M~nY"$d}毜~۝~(qI=:%op|=3'8tFt4 _]3dOļ4ԐO "k0=R;i:#mKl0BvÚ?pX6(m{;p.$Xm;fK!?|uBWWhRa5I|L \>ޘJɎi[>yeNݛ3,Ώ}7'9܈4mF|9?#a?.:hRc91DI}!E+3N07+ ifAܐ?i$&?j.ؓnC7P3^1xOłA-_3JD}^@}+wǢO#~l#bZ~U[lo8W-x;5ZG-֌HUD9!}$.mzWŞ5=k>s8"mpKTCj!̂,߻Q/TakSrR]W89+ND·ӢAJ{̟WrXEpOSW%x7V'-S{|\+j}i)@Sv W>~Z~qоE &fdE)iɇg<3 v3I/Ȗ%&s/~}ࡪT \L(d}iѢNW8Dզ(,'q^SU؆T(#3N5HE{.QM<#NܓTx*lmrf(5#t(n<N5NE2Z~ Cx46Y-Âs(PVڤJ L8:20Bzork&c2rWz팘/qz]O?{wX ?ٖFއJ}J-[VڤeT54h GB>Tzm־Ho6-]N;uS)' g_2/%dъU%.xlhV:_oSu﹓OJGD7Y s0Qv u3qb;?-/mr+H^i[g[)T\q{& =uHl1%mGÌە]n@Kcӿn:4x _EP[FUczG)%N?7F#r}IF);[co6l1@VBg9ü`" 6Ťf=#^m(@;𔜠1ˬ+g9.QS\tmvӵyaOBD~zl~)2B â/s7[ݬS6[>Ⱦbа)%I/wOIa4{\ۨ K \R]q(`;Rчgm)ğCEqJٷ߷\9p".zjԅ%Hwsb qy#Awcl 7>|͖1fȣia=/Ξj56^vqHؼ'yaOXH[8+%b͈a// JWd)g 2f{W},E1m_)>;8PF/67M{}R|듍1HK-&kP;qho=kr)i;*g[zξ;" Tn\Śoy/-g233׭[7d=H H8ULcQ>"\WV;]T?yhR F[Mw-TcM$l^ӡQu$g"vV4kIg] 6 QeN_}c؅}H&jLg)GuPppvF}jOim ="f#)=Ze>use[RΪV!էu@S%V*gg>DKz>Q%8W@7eHƴBqV/u} UqnDiliO*OC|d<lݟnCC;֧:??7@kT5H\;.[ZZ ^|P_>xnqv9+$bHx3 QR)4&n (hiԴjy(7֬%l0UQޜ&|~+5UP!K?'B5mYZX/B$E1wU~xE}SD!q4x06 | ߐD1 QJP`ťY^zJb'݉LdUpuQ&BS8\t'}T.*黪fըJm^. 'ފ&t0GvTѴeqj4"'O8u"vryihXeD=Wk۳ lf3HR|}_UZ3?e5(XqWP J>Yzx{?UMi1 2)]H*K'l"=gKպDxtSEK߭5gNF뎢:{׹]JxNaZC VӖ$-_\me MOOV1C qrrO;;;/]Sŝ2Nty;WӮզWx?sOI?g[\^.c6ͮzUR|}N\ؒ dx@FD qp1^uvw6[sfW,V(#N<7AO ,ݔ^Mta<`mqR0s3θY2.bRk~#WE$щd\Or5,^0`?R Qpʥ9M?jexnf/;`X:]Mc\NNe3`ZZUj9ۦ' 7zUoAv܄WKo4gTwcq,CZig^ gb ˆBΆS(76Wːy>*/n~ &֦WT?vָa~~-uVn6lf  kxnfx^ISGi)azL[&Ha q (:d Bգ6gurZ tny^dj&e8yZi3k(Ij ; [Xr3V$%4}h ;`le* hʉomjޭ_> tT(A¦|}{%JSJ$/9꼗e?7^bٕ\핬cW~eɣ@†ȈCplџ^1'K44Yrcܕ9OWH8̻ #5eŝ^.]:,$$QsU̺m_ӻ.jָKEIJqÅ_}_inŇ5 k,-[ ,xMNI"DyARYWf{?iMҔw,z ܙxY' bkޣ3}I{bFΊh؁ڮK^^EbE,}嗰dEs_0pyWt$q᳥ k<ڊ<[s"x姵d֓M{ɷ#JV~Z[\|}$qR+O&~\q A?t0un|\ϔ"Up{\G[_=0jsnD!_˸?=( *Zo9]$u{PӂqklA)Vnڕyۓ%Zo)SG_`1us.nԕ?yۊ(V5?rS ``!݌~{\\Wb/Ĥ[n+pw&^1/C>iÚog`%d-R҄K( X:01∈a{=Px5+>aXɿԴrkz, bk>T(4-,Dr>rKh+iYnYW>i)1_̺m8BsV=Lt:8)ۙ1,fY67۟` Xy%zkͦ)w{g@[N9m.ýFޟ/?}NԐ]|4l-O&6Kw)C܇^w2A \;5+>a" Sh$x(}\;pJHvzqFF`@GÕVΞn .RT،+M'1.G'>_wggCtk _mo4Rw=͊Zk7YxvV |v;71qىnHNk7땟f~O&_{Qabk/m/ʖu_G]0d6R >]=;p4L߯nʬ{'/VףIWٚtzU $x0E)i㚚egRe$qřsceas.w%y~bKn4$}Źk^5r|"fv@wDM=*'9~ֲ5rߞ,tP㸰 ~8FN/hҴ1_< Kx ]&p=_wcc' m)OMAR*PIW%OPOtJ{p쟩aS:]y)j̼ctwcR8ns=KdZG4NC|s-bG@}*y4Ĥ,`?4c07>a18*`j]$ M7+U+"P p&Erv \5H0X CZL$P ٙv WuZ6ڪD,&9pd__)GSҪ F?5$0d&z8{ 3 sLU`XUfx=r՟R_S7taEƝu)Mͼ n\ χ_f?uYdžqz 쵭g)j.hx ;/r\rs2죝oneASmO K4!48躝g& Lcø8&`yu]n&cwk̒E"}}T Ҹ܉A#n.Ip/ܰTX fqj:ޜ"W\5|8!nk(%k.N~,nl0yOLВ'!&T(nXd+_|z!gS[!k{.aŵoca^u{bdv*Io&^_pRʈi5XT]_WrFUqVpgk&ӱaXB<š%VN Eg9mn|8قc[S9j1$u/ҁItI=;V.6 _!1ܞRFCẮK@ ]бK"N]VtCO3?}@ƍXmyq6 ?3)e9sŇd? ?+>]tYX5 `h.@5ٟ'?"Os֪(X_rO(%:h5^_oܻ^3K׻gg^e?Qt‘l{KX: :Χ:fx3}t6KY-iKZ 28ަ0`X,is{"xuk\TRͯ{xu╹uD 8,3KV#5׼;2ojḞSNexg̃ @dw5+^,L R 85,d6Rڋw5'ɤ{Tz;R36Hp$y¸)O1+KRTүk3D5IgݒߏN`\,y~suӪo2"ΘLJui I W4!m07jL(1,rlwƼߏ?0tjZ$Yߒ D*X3kZ1nW5Ue>cIjɫ'R@ MbO eHX v[jA GWٟGg&x~ TF\~k jX#Ҵ#Kb׷+^U8A&2Qݣ{i#ddOnE{]2s:̊qecuB3?|x Mji5r)rKS?9G0bokP'޿faSʧY~z~W=R)`Ԇ~S =Fn[!)RXo{5]]xftH(:[\wyg̷?z$v4OŴmzlwqQ܋:?!!N L/>~DP{m:I w_1Ob"gs9N Bp!z"k-W8cg, s\ID'Do}%uq>CvL(HZt`ݭ a Ӎ/O:!g'>DΘl-/s8iLR#n_5,IO"ӆc6+3D;$YE(;1esEpSu4NQѮo#Li4L&~D!naV\tf)ګ;<|ơa(1cn3V"@Yf.D|Q6=?ܪ_u{o#?}eqㆯK(xZ{ Z0G˃mu&8UޟnFeLL:7 Rm0|Ҹq& ]tvLWi?ܟϑ'3e%^eτw)uݝh1VCb]Zߙ ~,kf1{̋x&_Ξi|ˍpJݜȑvɜ}Wvɻ..b^66_7PqϖӴL(1eUN:$ZV*1LiߓwWL#$x<ه`mʬ԰6YzqD嗝G%.{l_u~-UW}[m>-Kp(ơ =|U:ѥTÓu J̨tPΘq i+%;ʜ("M2sdؐH6i3? spir9d-yӂK~:1o3 ݺ&+O5ػ?j۫a{c1gUyF7 njaXn];:.!a)•}.bCt+Kk"i{ "{̀(zQm`|ege<3&LobyJW<wdY@5]]Y'7|Z(KRGgca{yfrCn׷ eLm䏝og_i WO3#B()`N䈩vqS~_Ob!0Mo^Θ7մMO2hG겚O:$Z_ww"]Oqc~uS8ƱzwZ+j֭haH\)*倬/0s6lWD> =~"mCʂ78kYB.[ݽԽBh@-5@#X}~u;swvfwg=U^"lCTQXWGnSi9skɯ 2FAl RD@MmxWQ(I_Ϥhr*^\ƪu4d J!d=ab߮ LR5`CS&2&P1=B65um&|(O{&Ye-@'sʗʂ=_3(L KS̫ޝL1S?ìb!%ra>cgS>6/]7t*v~NLZvV7_k:vO2yͶ~&F0OwReJmohϡq/~XqvlՂ_o/saiU;Ķ<5{!땻/}u1(r CJȠzC?ٟVҵeq ~Yd7s8 Xh;[­+s}gΙIR> 4gg=4n%ɱhcXv,M]uQ^+oOg&ЃPAIPح;{sK]DOz5;4'V=ٝ|tי'= :GM>o|y7w]T3ooym9O[UԴچ]8vvӹ1&M*CM`(v$vS`3ۺ+m;S}:c.*9vG}}ow3JInFҶktq ˏǂ- G/1|vyU//esqe``w%zbXkt X%E_elycGn\?Uc%v;g*QKy7V{Dbxgۗl._2VE+8a,fWq yB8uk׷U1?~%;4pq;삎8,8q<&t>G`7A@#C>-<7i ufgoq b~`+mg?ŐSK0růqsa>曡zY&w)l ޵w`G_6#㕴 &Ͽ `\V#[O; $&hp搘OŢ{T=|XcqAnCL9W-KqĿ2i.'CI*j2b|W,lIGwHt!k,u~˟<5*A,HִC1_QxnYcLf|[Doޫ ҥk <f'5Y/Z*3EK?m3ݧ"N߄MTn막 ;w*I1 .ҡOae%2UKs&17v?YF$nKׂSFlv 1wDyډjktoUmc^V8!7sT]?R?Nh ';ھ(as6  M@hijciFNxXLN $|w%fOͬ.i&1jZ99?jPf[LdY|cc7’u91gkski69-Yf%vH?JQ0M3(6&0㙴DaC$3?[% T/ygKʯ7zJI*¯7"]5VKIK2"IlIay#TJ/颩ܖ6:ӌ>_׳ ^[.u!R3_L7rVtg%m3̘*ՎJ?"6%u-$?i~=?=er lߓ .es47<?7AWmԪ$*#xi_+jJՉؙWӚjZIMu,.VR-?CCrl{djl'7շzB6]ƯVß8w{6uurh,[5Pi`Ӵ *]S3Z)kjfSZ{tޗפH =T$)+J[c2km>F9֙6e;\Τw0[۠D]!/8ij ZL Ґ)[2jQ+Ӄo;~[VaKw {q(ILjIR`Ƚ9ΤD,k''QbߘVnMyEHA7@ZGOzi/D[QQmrB<&jC%/m _ M M9hƻ"A”f(o"PĚtezA.7 O8fBfsv/QU}b^D42OIZwrE׶gS]vxkwN[zOkm欮u)MKʌiiG<.ґ)v8"A `oasjjcV+tlڊ[>*,1Й18lB >33gUX{LTBpǥL6ΤwGAz g~6Z&~Fĕ6;uз׊rZP(ȹNhA#-ir"כn6e@:(Hv|]eqF(-IЙ߽HgJҼfc2/~}2q஺\|z@SQ|kong2Yi '8OIl(oOwpz'-BeT~<CfZ\y*O.O.mA;039~#e\Npk=yYʍ+Ѳ RELl|+@ϔ=q2toWZ vsh/ 82Jؔک6_5;9ȚzYXyʭڤmV>;]7•-Y&~`rpʌ}ShuQ#29wVܒ|yA.i[g:EY"~uW,>_kQCsS~}Zq2dG-ƱX/Xt{_1GwT[tx~JS ;5)#f~ىYc]Z~ۢ0 0B=36d66aN;0­Z LlFPc 3&1RpXEG]{ Uvfe:~juAkA5-n+J* *fs2LzfIcfG-SnRDdY.ԓ_=wN}lq:tS>Ouַ.D8pS{ RS^|l݀w`L+|/%~1xiv3T6]Fm}rcWvdRYwBr yXMjճ7{I0z~w׋|xfU%8.o5)~ekʡdu7R)ځV_# #:zU=={ ѮD>#tA69RS~<_7.[$w61= BpƱNNXJΫK.V P:!Ԇ}=!wfYi ܘtܐIwHyt,;LNFmXd_Z%B a oy+!&g֮M>%)zW١c<@o ypbIixo+NéH5.2loj\T Z6&]ܐIj'Xe~]hu9R # ؁{Yzf2Cg&ok۩Q.L&2ǝG f|kPOF:q % nz|Yeya'NûAv=LUtVN)/7 ibE܄+چMlלj5=;}V;&_ݚ5iճƍ4w7h+A)C,Kާ=A6XtaqwZy@ZLmMg/ާX8<ڥ_neϡIDATX7snfT4Yl91~EiY<ݿ:b\,TFCD=ABS.ꁟ/3Wt|}Y2[䳲@'koa4b_MrOVo"ãZ#!sUu?T^Qdu" j+Zg8F2~t[AC_ڟo,  ?( @!w8:;B7Ki*#OulV; uƄf9&k"ί>1NW ޲!ݾ/@.՝Jn\$U崥ݿƄ6CzU؅f8DBUnD1(;ٍ]:m}Ta"@%r^ݬ=FH53cv#rYfs}*B~He6܁bp~{uC74MnT$lZDR7YBXFgS(- ;+M_v C 7+$\=k SZkYʓeFo~m?E 6RUJ~uhmUm5bq%GPM;;+}I FYwUؤZ[ T18$bT?ӿ@)  GQ4{yi?v%{L{ݓGbڸ4@!a71BpB&i?DtKf#Y~-MТQT`l$i7@B`Jq Hb:ZH $X6BTW$k&HPVl.dBX}PaVGRi}a8Wގ<#Kr-Ef,3Yf3 >ʹWQ&-&1VAGXT:f*BRi@Dc)*r-> a%/O*:l Q +dt $}Um0v]3!'2(*|($?vw̏T}SuiVq۰&a*LodgHwpg'5>2pPc8Rzt^x՘Ou$;MΡ`zϸq/ Y+^A63XwT~<0te>* 2ɖb4l87Ž%^LPB[00Ӛ{1yk­3n|5S1X`0r;!F8$i&γzTdlNfXU-@0ugWze`ׂ| ҏϵ{wp\%lsnWTKف#f ukNj`D'/vy' ftf|e/-TCxT_1bʰ\>2"R zzb(r^}Mxϔ:Av|<>ם3̏ kJMsP7 #eof ?ں0X'Jre[`0nیhj Oѣ-S15az4ҽbc0jl_0ifYBN-)hjhi>U7yA>҆K!%oɃC&>?􌄦]={&zԔ}`PL& ŋd 3ФdQܡXdYl Ǣ!oU=#t# d_dUʽ:AҮ&~)dC`NeW3<{ߋ1gq0nI 5l&s:=-5;:zI]qf V.ɑNua P5; :Tʁ=u7 YtX&,S|Ўvjk_57c>4O=GLC3>=ݜF'r|rdZ^tx\`0"Hz {RX&7XgN^2R-QZ`eb9=R1*!h残؂yeiPD plf-:RnGi)egn6yW^H퟾le!pH²ܓm~[:<3fL.}:㪅cփ8s"J\N<2=7I[z+ Au] %Lv;W=GG8$Z-q6``פg6Ըmvbd,o)ꗺ|Ά#؃Wfb`DMSZ&`LtE{ٝŋgl9b_'t= 0KFdW:\:ͽCKXMYw ;/#xQ6;eV'IZ&ֱҵ}Pfcr)ϒ,K}R@yo_X1*ރTԦ)gjԜ{JdY , V R`?pM%'gۺ)]&Ф=Od5O9rج{dYaݹ] el>r/b -pO=%Ȝf~ڑ拇f[:ӪSTq4p샷 o$=h+ --0e5)Et04ߋ1rNI[?l--ؽ +t^ݮ 0K8O*q KW zB*l㊵SOpZ$fI1.IEδw9۱X'8BgJTIVdK&ykW`D)1W*CCXUxd,{J6L͹EE)MSR8'_Ybś,+eD#_@Ly5;Y8L ~;LK:>Xl AUhy3VN=3>7kI Butvk_[Y;)n^{)g+Y$L]E.--{i16M:!n9yo*6=͸\>K{fZ9 ʤ3pjem?5aEXmSZC`! ɯbۺ}q3^覲r<>ɋl10c|XoSg75%N=Ԫk(C@ VK۴ ظsH^\b!?JF?[C:0xmubso+CwXVWA6cxXݜ`-,2vLqׂ|Vm##j'm3X%G6D?f3Uaυ{\R$~& 6*Fn v .,:Q Gf9CsŅm:3-sP~T%1=:ЄZ[a'*X$e * csO5=Gi4` @nVG7^I o뽺;եVtRY?".úCzS{e[^Yqhr9|xZp6+@{xÄڪ~ljlVҺ= 㧫khRI wGcfEG71;ue>)*93HG8qS/9tOapl.xaP>!=+k` _@12سb>߿I;O$GߧȔC37-)[;{/vFZ+r~˲ xOԽT'N݌%|+;Gt/tt ajSIOW_^"hr> s57WNy-K"w`tQ T0}2p" SC~E* ^Q&{M# v7dY05PoN'upDG4wg98[+fmh]5~w)xmi|~$ne

Z9pTMxw3Y(_Eus\~kam-X?zJA<HL-~ɐGW{uY|ls'%kU@9'OCDuW{nmË_EMr,]Gx)c'*tqjt/;f4_RΖ9w2>~ݲ|<0GaƘLnsҭ+ʟ:bn*BcYqemamQX*)djɡ_M̱Y݅^;bGdH}s=(Gk/"aUu#g`u2ˉ%#~kdӣ{%O$?w[iq~v@o2 En^!n&Ao+:ȋwcsc~ke&Ssk˃s\#a64ȺꉩOj 1{aܷ 1jv5対飑xdqΛgX IAk\[;ڎݫ2^֢V`~<{zo11?&K}r:2wa~~f(&+{ ɗcON o67b=jq[8;M:؇q`ڊ/U|t-}ލs8?׷]_9rDZ 6|4`a'xQYtݔ2yzu*u uqee>a|B$;tF~TMoU+ ~֜1{7T nLSp ' 13Pr{cw2͉$̐ $Gw^(1tfX,EE/hjaR9mXѱ^Fo9?џ8 p祎ov'ӜQX8@Q}l/6n[Y|Z 8gt.3胮ynVmc˄ x[+'! 6E*̒^ P߂xiTXN-92"LUj>=-Ȯ5Et#UŚ$wP%6ewemPšA&|ht()"]{;Z>;3߂%3ƕ-Em2{2lSޙZ=?lk*PUnuYªVatV vòWșvhl_K>CK*"-٭ r h5?tgo_" %d?R(`jN7P$3 kϞP6FF"_ִѥy95<ȏݜ uiy܏U=GPU֯I.ft2R_GUWyC2*[SZ44)]) n@ -rpaĜVTx:oDI)# TA2dkufzы"|d2Y #$ja0m_*U* )67ə, ~w-G~n& pwo7W_¥./1uXSZRˉ´%SM]:-MT̯;<v?~4cWq֞zY/{rF}fruR9LYaNr\ɹECokO߼Y.Rr2 C!?[[1'bb#pPmϬ4edLCܷMS3D>^B!I; GX[{4J#؉j޶rLoj5#ME}-]y`[Iht,+~l/3chLEK_2R&{z3de͘\qp d,՟ٯ{ijfNr9̙4K U2k4)c6Z};k45]M]b^1,\CLt5/'C"i Ga߼jljŗU[+?~ߊbI>v+2jcKG0oF lW ]TQ&36= ڮ\\mue[+Uŋ: l[{=m+~,y3*nnw)}r66h(ǵqD"%0ڋͳsQ}J[F-WYRvV(B]|1@e<55ٙ ̊o2U&fԞYhn.)YHvyޝ5-h&p81pve~,sK P\RԦNYԤZZufjّ:\fզ@&)S9_JQGklG^N۝[ DGNkˊ5Gh@ܜ;юjSJ73ZhK.G VagMj975XJΟSMcږEkYzsUlhW,ػˇq"!YD!jgVi έF16LX&\[GC4Lq?b#};dZ~D3uYyJ?~eoOs0/*ǖy^Xf[|,yӱX&<-K7OW#)VE ij_GOh;Im%}2բ۹Q3) (kzpcʯnFH(hPtrZzG7" l7xOذI˱),H̜C{kp͜i F+C9jo x(e@>]K#iYVքe+ߋ.Z*®nlozΞ b%}9i2P XA}Ċ{jt'Mx`O}Gc~Lo5tB zB4pX=j P{[}j(;uVc>r9ޞm :$#=uIS8YyNXž5YJ&MVX?}Ѳ9`Ex.ŗ@1UKT~/Zr+kZZntOR!jeNE&ԯQd_%=GPrN#u7δʭ51?g&s}ax zwbܺ`lBy/աܚҪjW>ۃB*+;Аjjjj+ T]aӐ!,R^&&1ECIVղv]GMSԁZ--i$X>We͛]utrg& HہfȈ--B=z~|.%`ΛSJflBp`r(f4_DA[QVվ--r:KV۷ծ^NUvт$oUTu$>CsCB!XLRx\ 3ut"xa @$zִ>Y%zFFTm$_݋ h! T>Ir8K&$\fb1BQUG` &!r :R/I!AӁ%Î5 NII(K,*^$qȕݶUh$h >qd.d" T*Z hkS`62p-}ݸz:OT*y V!P`z9$ ۞3CՅ!i˗/TF:Ǿm/_7ݽ%4otWV{,P&O8]|= ΝִxO*sZ[Dgُ qUtJHbeI0xEԼǛYR"k۩KIGOSV^`cM|=gb#t.5gԯ;9!HGbnU$-HoTߵkDŽ6VX$}{w:US4pp 9i :-4JƎMX쵶+b0uU,cIw#~Jw%8X7jl'65U9opil.6sVq;p/ԛZH֯V팭L̋l{ ԢrU\bW*ݡunO}[R\Jd)iS $ք+V "B*6 1`p;fx|W/r72踹գƖ?e>ՙCCGdeSUܼ4xw?/Bb: -wo NffYd$]88;Ѝ͊:x9hF٩|bVQ*flVY43ˢ: {֖ٸCu\zҏaa=zBGR\Q! {BH2L}&GwF-_7 lO$[bVvXb#IDTU'LxHK=?^7|d~.P]حGw?u)9#p,>t3]ڠg YTݿrՉegC71+u`)Aj2y\?;QgTs23[L<[7t%B û$= S۞M)OOk&tu^>%k9%|KgYN岜4bC>]_V :k?}n7 yFxg֡X.Dtfš{*C]8+[,ɓF=ɴ@1?.xp[4btu`߭G雷Źbw7?3YW5HV,U{ceԢ܄38cGq G Ec`Peƚ_zfc'N$9۫>J[ Yݚf!ԕ'W3ҵG<{Xһ;gGydiD y"uTV0%AGT*|Jje@aa>k -na˫[5=q6n^GbR&)9b6(&IFM(}\Tު)tXZq/ni5Oɔ~Gx52I-U6G?~zy2:o"[a#T޾f*uRY "IjΣnz+{B*H͂y\s4I?l$ G2YwU؜Vt7A!%%urd`nj=Y'V)y'9&Rj%;{3Fatx}VA),,ԘK".>̳](GZ"qy/DˆV1ًGZQs).zDx A?i'sB#{yLIQ-I%3pFENN+C9yςQ)F\lldwa>xԨ!@to=oߒ1wnWϕ=Ic]FYV(ӓ%EM )- ?xwp)CShz@L:65TO ka'܆<S4t0GUF9xOIKo%ek߸yNý+5Ux򴱫Wa!#u(99lme6hSV4 @@|GkznTS?ζr;4RX=|ʥCȰ]|.YӡWa*?r8w7Ƣ: a ;'gyi:VQ18G:ܼ0u~G:FbښT'SMInB;34xHG4<uݦjowv`_{qVfHG6bc ][GWo._k`=X- X33&qf 79uXQ13L8x@"$6c,ePڊة:toe S^e#g  htyan^ۍ[ $|ZUwܜ g@::u~s3Z\ote]f!GOyS]- jő;suyN Ah=&ٷM@Nhh@2keAܟ#S:y1K0S=B  C!GCT*<7 :qңAsSZ]XxRDcr[BDtPPt:o&e934^,G;F] ;5,ЈB(21\VQWi4dudvl2fFCSWa>_NȀl'ZLhcG91zul2DfMDM8u8OncNG.JS&rMiaRSC&Q3S 5-*g:T*դP=^u}= \7UXŦ*2)J_[~\X>m!:&o2;IZʳ OZy7q/ P^ hM>!$ ;TȒj ,%܍۫}_=#2Y0oh{6tqaY҅l^B؟d?.]S9xLɋ{:bO7 &q jxy:1Ls_|ڱQжiBF5g\ÈoR7_—+&5|⌲%k*3 |;).תe8sq= [˲ tkǗnS]Wh؞1%Kא;NO(W7=-] ei(gh[0rUŷ/iMujF(I7ˬ\~nok-0:#'};|Ǎ|q ?JO1zzTg$+_:_@hkY_HR^!1Ϸ0]>IHp,Vw M-[*7S9ԝT6wiiHh{y0~!$zf綖f )smT{v?.:ko1Ra^oibN55!Gj =jL׋*߰7ƚyG}|CkRzciZ}EWON$Č7tfWL )xŗoQwc-[[9hLɋ:! 1Kݑ9wCo_P~K>=5uR`ǘbȷzp[|q޲q/:u>%Ϙ­+4ڶzI:ڔ,ÔV{Bw"ZXk2wv`$D:WaJjky6Ɗwq$9*xq?B<옏?ZɊ ;&iXOOm@-Uo_B'[S o`ΗB _4dJ#C/y?ᬮ&D2aK!*)Y? sSoo<]҂6}~qW`oj\ZY|cEL<܄C+I7ظjԤ2*@]2nj٪ fc~NԘ9۪q<}*2tcJ3[2 r'{FUM];ȲTr@woߛܘ$51AΊHF uXV\ʜ!B\IH*^V&U:,(V]#S~Grm5:D& ss@gWmܱQZ%UIy"7|LCK\*›= aWc*wONR)͝ΣR@OJӡR(@Qai d$&iUFjϧl K WR_cCb޻eB=߂U+4ڙj )=%1x\DjQ5ZܺB#[F : #?Hf$nPe*TPLU5A^W KvEUS#k wT$ ܜij(Ј˥2m,&; wlP2tZQG>5:(-m,2?<ӥQ1RX2TNOҟ?pnhUUեK޿&]\\Əooo? TWԧ^N).itL[,* (J7mE|RˊM4iY}d="EF\s HH )> mXD|?>Gѡj@8#1h`cɈy'Fa*xAG$mhڷEg*3?LD BfNQ5peÕ> u`aEBN+>y{6 QyMy/5\>ۧo! Vh* R` uҶ<z4=[Ȁҽ`Z ';j;S<á 6;V7_&]ZF fq3KBȉ3 Y×:$qNMԏK:y0c~H~š٫q(OQHm 2 >,ԶZV96ҳgIBݿI*)`TDJD89\\.hߨrufjr8]X? ?u&:NqtPɞ5 m[׉GOjOiy=Qxj&6}{_Rh?wTƽb#:?۰b:!Z. G Tل쭬>)OjsŰ %mm_mּY $xux?Qd"-*gᴥ?7z_xqM ~Νٳg/ZBm 5(~l@dߋyBMC) kT[5@'gnJ779%5HM\sDTK5[\-)kfg>߶S\9mp!>,Ml()Q]DMNt+9DM.&-OOٷYsBS ~ THnUpUE(˷&Aִ¶VoklH[1xmySqKǵUa/?q&>ܰs Rۧ%sQߛrTX&ю1u}m휉4L&7Ph2leYMM2}\NlG[ylqւ=ޢ㵻uqҷ;:ZJ?;WL{zVMoQW9wu]V_V i;(=ݏ4ǥx1]h`jLWkf4qQӘ2e.(5a 4Ŭbǫc!A%?|it˟RT܆s,L g\2 (m-N6fg\\̕ڤC^IԷ4Uip|_ "c)(ž9 ?~TuF-K? [* W0kjdfl 3{u(C6k:޽ **y N\eБL~mYuqi`1T"Ua~R+>blD]PobQ`f A.ƒ1{]}KZՍLΎڴ(C usd,@N9߹Л"~t_['og.׼ҏ\Ο rll3AZ]]G 06V6'Nu0 ݤfЇ14m5s#U3k LmD{ <{xcϱ&$:և ջޓ|S393 *X;EnK?kl{XP}"HC"ޜ,?_#0ٺFX`z^O_BFnQLzvX2xtc4Qv2;Wt65Or|X>a~,K3.+oSD&>V3|BtOB/MajQ B9MR9:*w@u6X5eGw`y=[5}'`-%?ޣƆ|Scn\gg]%oYN=џ0d(5mhaJe^ zvCwRK?ZT| _ NWzvSwȤu*ҍM#1六"A#ف,{O`pknaQkE )χg$huSQ̯+={\?uRSsķ+>`њ~%/؎/i?=JNv m5!z3=z<~Аoś QUFe tVK?k|~mln*jUЊXkL+ ~vV\/ߚ93ș-!v[w|>K?:9Y3/9MZeEU>;p|M3`~~;+'Qf ftc4cRp L/\ (J2\KuO;NkjMhgj]?٫`J4{t(nSi>#$~p(&E&֖t5;P#\En>[d斷MS/K7^bȤ>aS.(@ţPZ~ֺg71?@,܄cH*kbAjeef-فQgs_ 8pZ쐳Ex}Oo,>K?ƽ:|\ܹCNGM@Ѫes$? ,K3~np.>P[[@fƴ̜9_w oe63H-|n0!>'[jV==ӿ;/iرVVVVVV/_TZ[[leeekk[]]ކ4Z$Z""13g' x9xW(pwaT"1wq`9u::xXLBHbam,4B¨\`RtDWtwf)6mx)$wg& FChTBY<.EGQUP(v<s"< m]ڊB* V DbΙG, ~d D?hS  v(I|#Ɍ<.e`.K5,B#3&! $ 567B u$G+M+yʀFWxUB*ܘX}9$> ng\qqs"蠧C#=T \Go7lXu v^;+ FH.PƒAbh3&o/I2U$ݻ[t;0-i + '}15G}rObe;kT*t!HH̵ET uZݝ;y\ O F[[[+++gg疖e,Xaaa*>iH'pq yAhXLmߩ 4+sƠ>jc&ziT1ϜF= d£QGYL zĈx?[ e354f1i87p:@3CMGݾV^lF2h:z~-EASm'MC@ ^*Dxz]evay1=S(0f(O1@?p"NL/7fn5eVު"  K+ qՕ~3Cq Q̏FL agzX2p8,TxqCf!)%#"H܏q`)hc&:NNG$ <8@#ѴE%4]ןdڐF #,Mb#@ubua)WaV]6WW:2x6 * 5( M5㙓thjy%VY|mMbן2c"I, NGnƪ?~8܄njD=p-'pMb9<@ e>OBҌP}{6i@WMb9i4t6I,$'~6&M ە93*q(mK|j3r\{𸔝hLPdBO!P$; %N[߭˿LIIIiGGGtwwwg-+2I%Zua]/ctʍA}X/QM]^oȎ6@&ZgT T6ؼBshlgic~BtxccU{˒̗o,6À2p9S{P_l<)U1:{@ϴi)8}F]$|>E}Sީe,1/[kml3ź{ )94e|3RhγܲB*=W7ڹN4nW5tc^9cf--묃'((ihMȩ}##TvJ?M39vq_'._ f[g[g;{(y\2 :"xw?ڊsoWz~ƬɂK #=vS=yِgq~,*n3t&1p؆?:tݔՄJ9@m'HH $$K=YQNvLqf^!՝D|Ӭ窉n[ٜg\r7+֥3dxѠe\S *mp3UmK.o*ҏl&EdERIA6Yۄ'D36 奃'J>5D3oٓ >S}^VzzAS׼z4)S')> =+nC lU枔{W#Ui^ MЯ"y<\D(Ukޯ4AՃƫ ,3^k  .©{kNv,)gTat\sTVaî+o~dƔ1|#g_ԃvM Ui*Ę*ffEcXꗷ `9VhNsEc: POW4=˩[XJ{ҶKSaҫwj_801Ipn%[Vj[55t쳻zsbrʒkf$q3gGi)EkKCj-.@% $֝rQu#sN?1# (6Üá|P+7쪸pHg(̏&kZgkxvCE϶c枓բRuAu?Y1Jʔ6QgLR?K9d|G8"żs@]vq"fo+e3^(Pa\-+/w.:Ra39;$hQ1032 :wv{Ζ5sA:/6<SXVN8Q&gHƙ)^?|J4S-dbQ֝l~ KҶͲd%`*Q`g#qJ?yT?nV+~԰Ί~ٮ[^mr|^xnz[C?%]'[d.푃x=ϙ&L.pCΜ9w^X`;IJJ:t(>znhI(ļޣn铘l _&<@yoQҚ *w(=bb!^z{ipTT-rȮܮ8D!-ҌG0 =RWϙWń$iUjNbvX=GV^ʈ$ϐwhU\w }944E\ {ΏzeZ#kE_jl:&1R?vJAJ^^4ȖlmTжcfmoZUqڭw%h7-۸BHbU@zU0na)ᔒV_:+Gyy:pAjobtak|*eUUS?_m {נZ:Ns&E>$wZfK&Ukhs8_J~m"շB)ta3)Uj Ҭ7´%HTW45WY!%hߒc*BuC3չMIhެ [\ڦ*AST !Y"UoAVC=\Xv^]jY9wdibJ33jlkRIi>%%;a6=×FʶG8LDL:$  g崐R zjDFn?𤣣?CQ5L,llT.[ftzC迄CSKrTP(?Ci efu^^_ɠ,--??GqRLwAM]a@BѲXA" (AhZQ VQǪP,SqՖ e1P6iP%@!p,ٓKߧC$'sp̣GHܜv^BP:IDHutt!z'N… I#::}o|||mm-888hkkB[]\\  %%ȑ#mlذvRB]Q}N OOONIMM-///9933&&& ǢQQQδSwEtjj_]]JIIIIIɅ ꫍7 =XA&ܹ… mZSSSSS~頠 @ o}w}GڷoߦvS)AKK y#ƴ*_?O0;t9LKK?I-[H$##[ҎvRH׷&;99uu.22=444--v~#[//TUUH;%%vF~=WVVH;o%&&,}SrlرXVX1r7z>3NNN?\.9"S:Dnx?CΜ9d2ÇiEPQQ!J`„ %iTWW]EEEٙ>|||>#qS>ܾa Ǐgщ5sJOOO l߾===/Kvy`666Rzb]iW^^~z2ulꄑ0.]v;w++ӎӟ4TUU===,Y2zhHTXXxūW@VVVxx={h.HDZ[[cccoݺ/tqERfw]Liae.]rvv E)&&fᴣIDDD~~>OLLܶmnKKٳg ?Φ賑_,Xxb&Ykʔ)ǍLMM ##Y^2lРA| ,=ur!C΋ޔtҠ rfcǎtFt{cǎuww|d1+ܼy(777v-x+C_5,À|@MM-<4440][,Xbx߾}̃#mNdS}333}zHH{o6773+ڭi=%0k֬k׮%'' f}}}[[[WWI&N_+''';;3gdggs2ɓ'/Y< )iӦ]zڵk7n(--}%ظ|駶/^uVUUU]]ĉ?ŋt4l0F\B),eGBiBHqaF!iBHqaF!iBHqaF!iBHqaF!8φIENDB`bim-1.1.8/docs/assets/bim2a_laplacian_102.png000066400000000000000000010052001502773057700206230ustar00rootroot00000000000000PNG  IHDReIDATxu\@^\KTThK(RZ$xGnz9}sO9av癙ggYDo .?888888/}4 qppppp~_p?iO~888888/}4 qppppp~_p?iO~888888/}4 qppppp~_p?iO~wל8qbΝ>vw|<򛎧tfQ*`kkwDe8pL&:t r=:w{H$رw88888駿~zi1cFpp]yoBѿׯĿD888888y'Oep'7{YǏ@ǎ[hgVV}888888a444ą eOO޸q UVV֦Mpppppp;T*J5k]1ׯ_@׮]̖#>}dffw"11+Wh <. ο ?-_ yud2&88بTM"ի:ꓛiXWWgjjj VZUUUVVV쨨i9߿Դ,OÛ*؄*T...F?n޼رM6D"wttCH$T-eeevvv(V$5ˆǖ-[H2JOJJkjj8Ktyyy07 ]r(%E闊CA3uAg*6l}+x⢨A,T$[9M,ML.aL B//T:cbIrH.Ąx+U̜`ς@ӓ&ќO%JnL8~#GG& 6 s{֡ =hEY Ŀ?>-HbccGybL& ߽{k׮=z/UjS<W7n{7F0eAQJ篪w; {u?gCSGW F\˫\s Ћ!9S۶7(mUٞ=hY ivӜiR̎5lq0aaWu|4TsΗeő;bSchO>LWJn7Dt+e˷7[^UZZrXx ӝwEx .vss!@x0ˆF=zVp[j2eW>0uف{a6篲;Ɵct n%hbVBE{|2r:'u$-ӌEplͳn%KW@5Rۨ!L 2׵\ .0ʙ(}1R^GM-(ܴ(s%.$<^]`cMw%7gG {,Eӭi4rMlޡqCvHIM.B|N9Iy;ylGR~ֽ5aeKeF2tϜEZ^ X{a QqpS#3Se{7[t<Hl[+EnSeY.?w)/}1lnBD"; WlD~j|@E}IDv.kM/>;ՌrG%CeՇJ'/7sWVd̛n8~k?P(Ǝ3AAA{Ү#̘1C H ?zg fQݞnl9 |yM%CwWKnF:ߴmջǎ6:4)͉۵=Q1.g;rVwm{xͽ螼kt}W+TTUفکs{:͉L_ocmk V"ٓ^uOȳ!;'-~A\HOu~:+{=Gk)Gω5K^fjScǎtpqqٻw6l…III555K,9|*_kj9\H$gǜ<$9Nk4'k ʒsH$'VZ\2 Ex}1Eu螼K(Zh?=n3uc֑}0*.ى֩}~Fy+,+cb5n?P[QbœgGQ)\[ku&&HQseZ[lB OMm:fD ] yNʂ 7iߊƩe7^X05+GhmŏD'BwAV*56Xwk%Sze kW98BJ(TYY*L pZv㛘 *pڞM%5jRUU`kXJTlN3乻_ )\U23&) PǛo_=Њ4}Y:ur {*U 7 H!wlC ]<"2JqX^3e pP .y)/4@vn\n٧;b-lߚfoBG$mNm's,͕ jG kJנ; mgTָ֖v}x+K6~DvP4n9XXQ[ PܱL7.50nit:'ϕC4Z,{bWy;2J}gT P/5ѩl=I&Isl]Ү5_9M%Q[la{znîǀUk.k!NqZYkte8kSˮ0Zn"vYE'V5oj]Lr̘P^ڒu ʩVԨ, J(6 %r*T9gV ~̝PprjѢ3:Z[[ۺuk/////Gt}@:C-QPI"!(NGAԵW!8?)@ _&j?<^HDڟZ~Y=^ AHS@""@RȎ&5 O' /T_GʿS#|};xJ!C4}̬Ǐ/^3_ WD5K*͹ö=J&ڝzBQ6SvQe fTl 'gS̓gW: *.T{(ԞvmFH$ [ Bu+X׮X}hNҏat-##&>$?leOגD`nF?6]H7Iֹ`Hmoj%"o]m0پzKuY|ęL0(F\ELo]VvԊ5;8:?i8yelJ63_XZRzwc,M9d8cVK-kT#'_:vIdj ^*א2g'6F=4>ACF}4u=SھvG 6mT΍;k|}A,͢)/Tg̫_]l}ի/eǘ6~Rl G% tŸum*u}gn꼊#{_|#9wcP4O(?#vr;4 NOb6==-/-p)2X3B8ii'-]޶]V?Lꗙ (͢<ə?jupk qqq e deeeeekNZ˦]5כ8Q D"r̭G]Xd:@n|@lҭ0%M>sq)g[X oȸ&?Cu'VV -}x:wY(E Wf^XU d`Z+VIxٳyq~<]ǐҭ{k|jSt%_ıC-btI2S++ž-V<*9Q\Ë{L"Qw-`_p]V]/J0>^ͫ-콰[!YhG'Pli+;ߴ۹_`OܿͲYetk>Ҿʵr,%pփz`̎Eʬ\ݭZ6mAn7TqNcݺz2kqerB[7G2SodIP49Egź i+82zZyA2S'옛0w2C#:)݇j|jM vgGEuUwRS`펉Žnxv۞XР:w)3Hf zNޣ"N@ W~Ju%^;t@3|J_YXI~Wo:E아.1"" 3"Q7׋Jc`/N_1x0)kj=u}ܵ;&ݱ5ܿo?yc(n-!my bݰKzn}suZܽluX0 ̾%_˫ 8n4?Cw>p\ԹaZВ}۬.yZOsaHw97d4qXfUڭ}G`;,;Be>G;Zۻ=%KO (H,;)8sܳ+U>i{%삱#bv|rnL3ǂKu[$t9|pIs*FN)Ozn:;^.6q,7M t.67/!(>IVSх;J9\׶A術"fEWZ޺`k8/YљNu?)ﳾp&#f,l~PmAb,91WotBshIw%|ե6Yy<0ciiFcvIU$Lv>&0;޽lzcsu/ݬ9w頳cp9>AŐM &5}y^<쩦&4ӗ aT"U>~fU7:@" =}1؄.xJpR~S? t3glݺuΝW^#B@˒OiB*@]LM ~d-k,_?f {s :ߩwP9^CwՈF2u`v9 SNA.F.1;L9?#svlVd 6Ixj;z.qgb`X'ͫ f>M fO58?`YhkKK7g-| -vы ?vn꼊IKcՋ?u7C!KBfP M}UlwlkgΎ<̹U$˻_0PjG8X+;b^ޑFmQӨP@)-W~о ͬюWTuT- v׏`yhP K{OE%QX|xY[vaYv%k8;h޻DwIevXl]ֳhJ[lsZ'+\WN4 F lw2޸b}ARn:KuFYN jNN;&0^:1|tF a;d2 \N1Oj`/[ER͜uCإ} `itLNc]W^i?>}-tb'.;[K̍2/g=q<]ÑJ4nΤTЪ$)UV] ]+gfaiW[}4V8};r8Oʕ+k׮QF3fʕF#G.X__VV֦M@?ʰR@$RMWyqqo>jزG)hڴX+c wezZ 2U->$jAU*u۴ŽO_c;fNv$<_gaNXk^;vd"ё?n}4p\IJ#NN>pLdp6׫G bh2=k uhP3GaeNLM9I3&bv'\W[E e8UU EU*bcM@G ,;dXQ,SS²vLKp\|WרrMNt\)Ix2\bw9aQ,pZEVlg9M$~LhMyd3V>TIMu]kU*pZqݻ~d5>~]_~o޼e6GGs9;;Ϥ@Rh.Wa0.5^-#6ݘ 4A?,eD $SZFR/\n=¤if\QbNA|}).iej wI0'+̔:H$iM 2181,fhmM4R mZSfe+^YRhZl%ljhb`jZeئ*PWW{g`TK 9'&ɡEsJScF`rPOmFX23%XXH#(UQȈa]*(T:wcWרkk4}zӾ~nAҠ)*Qo#jbBJD"TU+*lG"a0 Ѹ8˛QmZ+\ݧ7ihjR[keIUGSЎ-#_I$h{ 5XX` k_Xnp^MXUsZ;ff!gҫq^K;«-ƺ-/WbQ(XI$"ÇwZ;sWV++գG0>ޞ(l6 e$kq?W{DwٳCCClvqqqbb|e.^˭ j˿}n6lȊ)NO<|T-ڕ$}yi ÕEwK41i$(/_KwnhMQU2XYS<\C[sMNf hD4*]ɀ~?S_&j%4=׎z 8bW/ZY_ѕ6w?'5. Hnd|S}:x`OOO:5f̘j?r*f.Ane>غflLdQ&˗z Нr\Vk;}JQ^ZBdEM`s!LU) 5MnmؼGu;**+NQ*Epfl h%lJ:mvu'cB_}G~[?pX܌?y"cd_X\+j-"ctbGlۡ p҅e]Rq"6C] >y h=vOcw]k{U@޺K,_]ky'։7lIc[f'uZrP#<}hs7D'vZR]PmK*\ݎm 7}*-'7Avn-8ƪU۲eв08BgǤOFNV/)?$++p؆;XB{g^Q j;Ǜ9>4BvQ|= \ eoG` `:6uB{2*X.<ٳ/t:ݺқ%ϟ؎W!Q}W||=C{Z['8 رuev^綞/_(S7W ҫ+@]<}de!Qjq['ͺr"hEpQw ;Q_sPge+`Z['P*n&Afח򙭻a]t[{UXy锼u_),XZci;RklؼtյmGaq ~S?mm!۷oob,X}\t1篤"ǰPleO/zzmEGvQ:n8!ޮc3/U׭GZDn!BsaRsܱ[4pq;HyӺ"EP+qզ^C صWTs9\@ GY>` ).$'~^7Z/oj],YdYfUb("ǸM7+̌zb-Lwӵb6Ѻ`΂Q+?] ;6o!CsIػYN=lEy&N]Ph`G۰y˗]d]h3OVy[$߁'Əe;n&2-ua[-N2*Y.  h^ sLL;33kҚqPԶTvՁ.Gw[wnX4a^Ǣ*xAXحK㺸7M-+o,PgCQ#MlxOI[6߽iop5ݺЄ%/7t5lؼؙwn( iF!I/t!iL/9?\" s|U@s,X'$rz厭aPYi$qX,l瞺Q}-N5lMbKXùzz369,LM_=iZ5fCmZe/,[[٣(àZS*c`Mw#*޳ٴ(a&ce<i `e(?ۡS7]߼]TP,Y*=i2zA+ 8:=upf.Μ6$4\ؽ A8Κg:b?z\UL2[׬۰y'L X|4GS^>3.ּN K;:5юEݴ޼_zbv@8(!%ƚY6/d"mѫc#J%\hB]tv\vlIxUnX!J_hiy=8ϡU[3BJXb 6'Wq }=̙:$pZspf=z"--u{f~QeftZ_g")Ŏͅ~Z~f ҵs_SYK(6M7b$Znn]h'Y¯t8Ku&+[%HOlI2~vkO2OFM$ 'hߏsdd22xXVFbH`mM0!dD&gGP~!V`HlR(d<Ų7PMK@4JѐmM ҮYZEps%%г;JpՅH WI-$ڑabH6ttu1q"ɈX&&H[ 2??2M;;kiGL{jSK"M޴&h4*ղ%ftBSJenN6۠d1V 8N9ܰF `aA`FwaeK;e?p4д͞C&O[`&&q{ti θH(//h}C ޅ]t͛_ryZhD"1##4{8Cf+5#'X.ڴ{%HuB LJԢ6|9s^T !kgu*=ћF{@ n3UlGtֺg,YePi5w IICQ͛ );̑?C~]YqK J}%$&ܖ6'wJh|kN>yʆ"voZ TӬ{`Q>UVÖmF0 v/_J;/)VհqB!m^Q~IYz ?}ΞX]=rMp(?aنu#Sq˗zYS;]]IuсE>_D[ugrϞ4SS]Up8 $d] ŒXe>sUn=V=^>{:+z ·oJX}&)pj\Kw"ޝ5ɸg鳙MK #FbsG$gVŀd@Zk߾E^! ΧO۷$!M;wօ;Oˇ 11.Mj&bˉT7IE*"YSem;VKT78;OOrHLLWpp?+yF;߿T8:ӏF&CVQ +vܜe9,_aM|JX&3^R̵.Y"L:vvBR/_Gnj5#6n1 AU KC ˁ̋&r8M[ZGS MߟLDl֌@H$}ߚH#Q7o5Mmcƙ4#c؉]ٙJTҝ:Qi4$|Lu9a\6k qY!!D"<|+L&&uk pYWK= [ ֙yxʌZYb%a3XFg76fG"]QSdOD2-fu pY,q2S@MUCD"<|fC ¹˖DLl6q(tm{*ݑ&rYd2&gOKCx6fք !dKK̎Sǎ73΄@׭6hcbt:=h1v575E.i ӹŬ-0||Ib)&6%Tg9,:N!6w݊@1LŬz($铮$'3 כ fhI1&\mE"l6SqFtxClL>>${{"E g6D" ֳo괷s9,ZfbGDRL0ݺ< /!rYd k7*$6QKK‘d++̎є@,#Ó-f [glW\{&ilMb %GFayll~dn1K+vD'Oa `C~82ٳ'H$[6=*޽{o.Ş1*vކ sYG 2ߣ{;"VŵTߺgbic,l0 *;zHINKKS+g/6ЌBd[WP X͞tv*|Iz&UUfB7d[op(9/[0zZQZ݄ɺ!э֣Ǚ8;>|(/*p+ mN~`{*ѢX=LÇV/ڱ]ܡ}C[ Tز޽*7lOЇ4?p[ڸoӺ ͥ7_pJ}h}KeڹC޻,Ue4͎HB )>8)}on.PmΞni"օ `dubMh0=CML'sij& rNiOPRiҾxX٣-In]{q2~_?=anZ|y]TQQĉ\.oá{OulC{%~a_#2Bss$9 Fcxyv+8`šZgs/IJc1_6PgBpü2;ejYpA䩌t5E'GCl0;vOuv!zyb@Dxya{2_3&vV6eqL=,vEx*WҘ'/ BFQؿo bV;nߔSx+ Gz+#o ;͏'T{lt%߲+*TajiMqsBcU{/.`c33,Z(zv+mm 99Jٗ <^Dh88yr S?ToTݸ 7𰲍[^Qvw- xk EX@ȶ-5}g3}ZXnx%쩬K'IJ:vN}gG beUy$թ 5\!65l tƛ>ҝ)KgOe9bCcO&&HF@jmLr$~L1VX|o?6oOj)[YD[O/R3DE(3sYso?.Z(1Foum;(\J[GSmuՄ g'Ǘ4f tvܸW-44Ĝ^ۿк 47޸%0.[R;zdՍ;֫4gґcLn5IbqR~xoܴiӼy4ͭ[}k#55E2n&47'hP7Y͘RF {v>SiŖ<6s~4__S)@]fajsbw5_.$\X:}S|} V4o233Gޗ ;6:q2Q,I\,C.\D74'ڔ5MGR{ZJ#л/-2ARu '!eO) ,Gy\E~*uJ ܾ>G2/WnK'pJIdd\Qdy*3p7\i[ii}s3/_l(,Pi4"l|zAHcNK+>^BKK½{R;V^FKZuef䚇OJ)|Je+Vޗ gHL=Cc|R&"DNX ͐!U1L @.qLPj5\8/G_DРf>{lUj V^ˡkG,j][5n4%ŹBF֬ %܋5Ԡlj{8;[cqlk y\F>^ef2|R4*?d% jըwfOn}ߺDpjk5 G/ m8ÇVuD3m8 Aiw1۸Y3RIz;j&E٪uA:uMd"Xi>0ۛ,.RbmJ=cWRRA ">`ީc yhlj%MKڑS"mJ7j^ )7S` 7#C{uظq?zk럃Ƒ5F(hhАHcZVDžTo9"tP*4[lJDB &ߜqt"+I$dMRC ,4pp4Rij [iڳUƻaBqij3I?Q֨`"UthJ .R/4C$C2Rqt"A8WPΠJF1V-fm @PkF#;:: ʆ`$!Q+BjZg,5U`GG'"& QQ=. &R/6B"XB1RZQ)̜ i0m&F)MS 7֌P چC$fZ lVQچ(U(``V=;)6e*YĦmH]H,Xii)vԊmjGR0!/Okׯ_dd۷_z%D"=/oDF 7/OO\:G2BݷFxRpzՅj}"ӿ0ʭV`$A!4M֪9]tZ|lŻ.[߸T?x~&  =RN ^I /Y2j\Y^ѹֈD-uJƅk/comLKP~ݡm5f)++ZByOjرv*l&R=_i՚&LcSQ7U{-aF|}c7_qѫ?O^;n"pp" o[DCmӤgUm:`2[E޸_^][; өucyZS\ݯ|(ӗܰ1R^1"5ISwiދkŎ-;r^'!+S1gYA$Ӱ;XY% F׏;Uݛk=e#F5+εCwORh޻Wz˝uݛEg؝=$ZݸY'S&2TfJ;<-ٽ{znZYS^qԦJmk>L6w؜B s4 "̬iiˎ^u_>0s[n}!##ݻwǎ۷I#rlOme5{gOЭtf|GOZx~g&vRUx3~uPE3 (_1Cӊ9hvշ|[2Α:[䑕QX} T%%=ߓp6/v`Qq{:iOHyԀ bQ}WT T[׉]xt3Z4,Yr^ݷ?)t֭ݸX;s޵ƭ*-\ō_-<R|C6CuQK'TNQ^lqLs )myзCY(NRV™a"6"}WN\hr]hܞ3%Q6enuvQPA2 ^ A[SŽu,*͎6|:‹/nV+)V=[8șop]ز6ؕb2laKi `z_>] w/(l rzLO[Tqm\U m`Do?4jE7ژJhZ\U޸6ĕҸcWP,Zg1tϖZT3ûj4anYV%0kYXrU5~.[.wMI3ā:v@]+fuuL]u-_c:w?e0EղgKe;GQ$B\y\yʪ k,ٷ"==]vzCJgIߕnU t+id][.$ȅgG0[Mėipba8r@=[D>9N-~/[xf笂\dE^orEws\%*bGx<6a.ŵkC\ymmgeAμu-hʈQO0qK/a|wa.rfƕ~sGE7Jyg` g9ޓ]]= ѾES@f| ?O՘Y>d9:GqP;O3Y Jt} ,ۅ5ؘ):P$]({tGRizq%7[h;ey3e(_%y*JI(ϹdVw8L,O߲2̋kܞL`ř;T_Z/G0"1׉E*5^9*n\x)?WܝF`#N%EYNzᓇW?PZ;|ɊjC ue6~K--<U4)6F+q>ӡ;@ hm殲h x f>7AݳJR9-ZaQTVϙTy?X$ș7zXͬX Wۻ-4)'5^i&Ė~ꃜyX8 <~nҰM+1;DO)ܹր:{-o2Rm([OY;{htͣh>|s #sXۭ#& )?sTZ9ޭ8jnڡ.S 2xapF.s!Ӷpieͤaǯ-Yo.vٻM-44L%9A֧AY1zqYt˭794;zSXؤ|j'IurHMܸ'؀)q+U{Oc g&C (߶{НZȹq~t?b]@?辺kwYm9dlZo>hݯH-?P7yA(Oէrq 4w녡:nxe3GwosV7+,{xj7Z9OW˃yC1O2)|f#6Y d|^+=ֵ4ș7uዶM%d9i;.o|{7f"M+MGƛSDЄUۭˠo$sTXC"N^J-ZI9^ lzDlq)v\&,9^=WzQb=I\$/>Mvw$En~~fA<79rڄa|Ϋ-j%h}+Cg}`^ Ǯ١CE5 H.n_iH)댹w& 8vnz`^s [5qZ^=~F pzgYgӢBe3o cWp~pt&iw;aj%<1'$j /?W*Te** 4œc^={ -w_%4ڑJn۟@A%o] FzV M~ nVߨaTm!_Du ܛܭw`b^9] w(#QmiXñ"||+7rtG9ėO$M+SuT8Q;W h;Ջռ"'9-&چAIoI5j8&ojkeJs  *T** q(j51AArM{rg~ggʽ(hE% "&a#0Oՠ(2OA)*Mbb"GWi:V+ʂ\yv X-i$9JոV_$Q@i9Oܟ2*:%u*0*ULE@H]̲+JKN[; $]Cp==(?ӥ:2֫T@H"2 JFPQ˙- +2Iz\4Ci)-;8amB,*(l;W?H]a;z+eeyhKn)TD. ,Su4`DҍR`ɄI@ZQkk+@O(ƷDѪL.HQ ';C`lT:Y(/U9 PĕWt7۫Tg˃"haMЂiDTHuA U@IQ˼Rj#,Dx_߽!߃vP++qs^7̤P)İh݄ ?/ŻHLo<%;t['%.'#šOEmamGBk+NBq=J$"s7;  h&:pȝљĸ<M4A`9tjA ѻ(0n.vVc,?S-lHqy>^TgOVݼ{ȥ׮h:L[i3Wڢ%)T$ M ?czȹ7&LL7١',0 LVѕښamOr󢠇O4$NYb `LkX=J 9w9A܊p6M}Cf}לzD @Qqy>;ϳt<*2wZbbv 'N&.FZXf脈v 41InT&v.{|r&>A#qy>Wḑ<0=q S̎s5 72i4.g;4ݞMvrcXْ<|2hiaMԿ ,ޥSX!u1Z}qy>zY^Af{y̭0;ϳmX^, 8p M'`5[iN&! ض+}G )|m%M7aBZ z7/=).+I~$r2ΝG-nۢa&an!!Q6d225t2s-ndt]Id}/Ӹ<|x=[[s̳isr-gV)\a>^Yğ9-2OƹO?y2-HM;kpɭsqy>vlL]a ˰&k;3uSzX!\ f[akSz_heƓmĖqy>7O\Ҵ`ɞ'89?Jȗg/0}}|]tW>wW.CKxɇ7*? o[M8;1g|І_A'{]]jNrg_SW>z9Q(G. 3q lOƹ]i^)Z02yEn_n41=1;HsE{όSז+v9v}f?_Ǹtl~h.IˡOhjo)t7j5Lc[ WMy6q]Wqy>WW1w2[Os}% Ԏ敮]z2}.?Oڻ amNH7ΉrEG|K>N}սU{V]K8zuhSŲIXP%T>&޶ {)]|r+Z,;iOD;lMʑ tX={>Wi-?J;x愵esO8vס 'Ѫ;{pɭqy>zJkƊ7b0gtM{W!y Nk'4'uø.Z'O sR=g[N߱V{nl=˴$]OOlюhJ];ʽJ Cn9l=: kI~Ň7a^;` $UUngsoކ3'.+,׷9l|5[2f6? !ʱ w\ kI{qoA_ Ξ'Rb %\iHꛫ} OˎKæ[wyr :3u痢b'(,~n[$\9Up%vVwۥp9 'ƙkw]uY0d*,`{tǂ%Or NL}(#b-0J4f֗LngEb5l۸eJt|Wco<:VbrS3qb[{ӥh]G_hC^&ZގwGS_0x[^f}jZw3o1 c:.tb5< s:<]sRm\Ot_|(>'wURq4=_=ß6S݆SNSwΕJqW=,+[siFy5E͟kaK5#%Or=hv@\-Os}= @\/emC-zrzDZg%P]2&&_%.V? `jAD@Qi91.G?e'S3fD M-"Dud꟎ }b\ ]KFOI "qi@Dn~O4a$H,ipXq`F6~XiNO1 R_(a}mP8@$B[3Ngq45}M@1TQ!脦ֆa1̍ejA$unt_=ح}(܄ X{TBMKNip0HM۴ xӚ o0kj񋆣5nw:Hv=Mdj/kf _GF Ȏ5 C6n$X2&_4;^M FT< 6^ Ҏ"O.//|]]f~,W6*Wnfj([ztY5T:H~6}7Pw lS_M7U=9_{LcbSavdPaչID ^F {uJ8 wW42B!UU-xaCF`ٟXfyVauq즥#@C^;(cu,Y?"pϫ(`#ŸhZ=M(+L"gQ*5ǖ(^7n%fݳ X{3׍]sk<:-9ɡuwXv ebl$#Eh|lRƒL ;n̝NKx$4lj}D.Ӝds˫Gݚhԋ=/dB//-%i~1RO(q@вUfRw0loU*i(V+hhccͽ.\M9{{Q f\kG8T$A?@P ;vD6xCIaWi4pfoӄ\葥e%roil0 ͗B욙]`ZWvoUώ|tB0fkɶ)\ok]Z9$=M2Kfik*f2׏ν[JX秅]Ģ,BoqjŠDL 4>$36;GQRrjZq~+oy75}m2ڑ9n'6,U-&f&wDZ\kV{\Lv?=ZZ(Nkް|`Vvybv3k*KhΕIĕoL7%*iaNZ[˧(̑n)<{Cyi ⪡>-- %4yu{0s [yѕߟ^l;zBKUd:%fI,)JWX*ł_8&F\߇q57R_츴> dvd3NhLa M<Ŋafd;v\XU߼+'3Ÿ-*@ Gr57eyPhGK|L ۧI%SkT cs/G5JSs]ZT8~Gzsk6Q*Qղ<[#p'`vh⩵[&1ʰq_w.-O/kW*J|Q1=ͳalnPPJt?},7M7 H~Zq]mj.)-5CG7ڑ9Ca%ݣoB׎NsTfDyjGOkyxJ8!zګ F0w )adeZ꾣Q!?:EExCSkwL5Qr}ϛІ:݀f_B5:*KC8odͼa醏q<;'4[Pӳ?#R^TilH:JV_f7sr\~+e9mU)+~Lhj & JȰVZuM{ْ?.n[9p̎d DzxerJohRYOpŸx/M>MC྽[5s/ΎbnG9;>VUj{YV}g#jʇx~y {u7RU*fU膀77b-r/y60}tF govyKFfQFVY<N`N gGmYߵ#O+?{bP-Zm^ys IzR\VdH{ 4ꢍcrV\eLݢor\1V_pNe%b <سp4#읓qРymtwr;W  ɬFgjR>px~~~`+G5:bc޷:a|o?sːJ>VN} 7? cs+=32fzO1c6VUmIsv<>!V ~||vdTl ch-{ۮ`$vr7O}s jc~.+2^~?3M Si`|XDsc&nr{y]3;#= σ6ABϺ0lfսMS3htO'E~uahǼ/ui K'lÖ } Vlꨀ/K8sn:~-b_8٢ fWZ|g:@Xs?fL0.4@&N3\Vd B&~]z}O=`Ž?Xh=;=oBЛ$yB'} 6{ܧEca3eΈrL21vΣ1 1~F O ^<-Uh],;abQ}fnmb29Mmatoٹ5,7fQ海5N1tǏO/DgFzC-&sQkti;Mpӳ*Z5B5XU' T2`J mBIգVh⯕{F@X(M|XA]ưL sd}.TA̋ 4& [͗N%Bz-'OssNg?JPiFQ4Fڣ|iSYhc7U9yP^zL^ϨO]f5+ HqK5jMV/O|LAJ e Qpg%TTAo.:3EU77jF r)qC[;ww+lȥE ЛzwjRg6~)h`*׺j*Ȃ\\ւcV+[ 9ol׻R_+#;=JpduCzǧLem+XkʫۋKe X(/%=$Y{1;\IDAThGqgG_ 'oKL΢p̎6ݩb.h)ِ&>N@m"j  ^,3#@Dwo=*߻ m8ܭnH$!w@X[xs\h4ƆJqpV J\3zD! 6 4ClhL)h42YsfɎϯˊ&q0;֖)><8jF<8ڸD Vsrf_apd^YD7!p3mVb-͗~{W1ٴ˸f9i4Xxfu{o鿚v? [ooj(<[%jѨo;ךYS%bx477 CkVK D ÂR_cu+/4ؙR!W+jhTڒbSr]`LZ1 ڳ?W)5rB'I*.R*4,T<[V+`Th xQLMn"V rZX H"cU4z]"2D|FԩQ5r=ԼkRѿFRHBti`G&47D!HFƭJkYZ1|sMTVl8 B'ڹqÑKJ|M \M*K1I6zVf㥝;{akR5 bZ;RhD<"VjvIT*ƨ FĎ*FV2(eƛ& Wh\̌jJЉv*ҁ*Vy4%ȸh)J5IlCRm f$;PZ0nP(d}Crj4h4)lE_k Tsm]5mSNHT0``S TC6J<8aG}`(K#!KsLEK4eUv[ j0}ZH [&/{{ɜQrŏ1?>.Kg&T8/ճφMsinhަI$]9 T[.ߔ1S_ώtPxnQfY/mY=2}嶤6hƞI2zSjnjG%-zNEŲmvζjmoNhGDX$M%??^xOMy)5C6geOf~lEYU󯆡=i_Y>'\ sM-?Qr刴gz3M.-w{G;2dw҉W~yυZ,B+^YqVj -RVvq,I8_8L~ eV) WO#w ˢoM|?oux52mId6'PȌ XBު[ 91ہqik߷x!,ѯs]X^?.ʙYuNI+g?>[+Kɶet9>2tIW|&VIjJuS9.j\^C燼yuVM~VTj慼91KWcӿvN\5Q񖠼P7Loa΍E~qRn82!'U4tQj 򹁯/-$&h_^o"MX*|kO76f$xxyph57^7 ("H%*UwQ~tNt˺{F|3Bp{qُ9/-е{}㛵i5`_|+7OQS>v M&ޚ.5lyiwĺJl?]{HiGl\@7W ;(1/':=?=R8"!fQS<'GբGfo~OIhOu]̋G u/Jg!,`ʻ]>=^˪BN Kwdt':h߄#ڑޞ,1Z<=>hm;'u7lbS'k>h5i[FGM"V-iJ%ײ4ܠ7UYǦ{1Fqq!Mwglڙ&BM=~S9z g|g]fxo|ٞO`qX3:'Y_w`+f|-wCR6cE+ڼw4[?7ksK8ee<iLlx=vX9ýy{'Z?zO0)=j6&w6i}ciN{yhGf潱m>=2dډ$Wʚw1I?wV3h8KD6Zںg\ |o|ˡY#%, Kf׾oO]C-'ºzwT};Luzs7՛zq}Dnhؓʌ c\fƧ>^ֈ?[$2#Fq:p?cɰγ3η80^k焫]:5ͼ!qj4/Ev_, 0@:׵:keL#lJX]&זeh[mvMzϝ~yϦ.e^uB=/v<(UK' tm:g'\^evƙo7uo|] ͻll1i/N`{>=2t{=EvlX|iwrfC܏Kw|[[T{bb_˥Om +xS/ݣ䖾__Ul-Z=);3iF@T.a3!&^ŽmƸlHp{n2^}$Wjk[P8/k4gKE_XG94)ၼm_;q WǑUTT4ETAZ r) $DB7#5ki]t 6'l_6SnaU<,D!($Z `jMoQ\E7# beaD0>S*r15(RRL{-l-SUT"LOL]_-'S:^ifGu 0K1!O$;zE_k߬ [31# 4 sT'4E9Ijme{>Sδ~qQ-hMa9gQ (&s1眳(b9'PT (&PHCa0 w?wX??HM]ʹgp Q*Tta#)P ̂ cJ:~|ǡ* ){Nv%]V$l3(,z~Kgڦ:g_ NL#n=(AWYRzqsL߈Y(ЂM7$q&3;zyV3{wTNP0,Rf@jΈ5)<Sgc>~0" N]Q Fė%nV(*1jAfN_|RA4cK L(}#Hd5ݙũڝi6wd7S{fs"KW|4*"w7~tRO@unS ˎVҹd+'gsA n֥gcJA+va;56gFCקl^4Ұ(3fqɼ{z;>&z}g3h^E|<>*I\pf[!eSƄ[ޠdO?xGD-3B+ܖ6Ji=> nLߛ4S{ƒ{[?7늄-"ջQjAPxrV\2\}xیa޻dux8 OLv޻>=QP/-`̏Y?^Tξ3άwǹd={ dp.,Q~|v .MJKTN2򥘯.N^;*3N ɞxP`ΐmI'{{' ZsT%S_2nK̖Vs6% ]Vu|.w>9kLOV&w41 Iqj?bS?FrP«nuReyqUhc?b1P̘rzLw&:L\FhӦ@nՂh)oxX6'hYIu7^a_ zLwCK`5I"W}/:]>y+'Cw9^q ~ZaXyjkǞSGj%_Δ@P}YzJS8V -1%1 f1Jݙ^C-VvC|~]O |eb1mڃ% RP'ޜ4 d|̼1ނ b 8L7?_K87bH[8˅O/Ya>1vq}ȭ鈉R/V̕'&F5\/}fQ̘[@Ek;d;`/M|_ݔhl/k~K1{ccnzC6Ʉ=_X3]j^m}"OzrNp6if1wejBY,CgI[^tg)nJe74H 2o- ZJ8ڌĉ pw'MEN |OSxSW#^خKVwxk|b|=f۬u:Car@4&8F_ץET<=2i EyeS R*5 =EʓT 5\ުd @CϾ:xsK7#Bev2_49rkv h'k?W}>D&U&eiGR2UKmA!VvҩS_uW[xCVOSj} VH˓fD 0nQ7]{|9h`́yˎ|A5 T"'q1Ө5JJ)S1>O1ZeSV2"_<.Ќk?M֖L#i4j'($ J֏CzQ«~mKxL+5IqjTPZkp-xUR`' շ OthzJhsh&yqF4PkОK\/`rB+1x]{xt95a2lL13SP ܭ$WeLRrG̏oք?$M2JR72WZR6?7`u$D eN=$OВ}CN(*x.x廉z͎؀8j{ ?ZkA~:9pF*gKcU2d4S87Wͽ7ĞU|:=SYw Y>5O&&E⬔qKgo` G8?Ϥ?85ܔ%4>BU&h$]>ʷ,W'hd;XQYؒ]LDYqQ:Y8u>|$y,:XW^.}eYjXI>]62Z딩Kڏ?,SeB94F}?gٝ{&־~m5;}"}Glq%+;΃eJzl>R&g73= OfČ; eI FR  ~908Zd?:{r@F j#>VDψQJUD2q@zwړ) 3Sד)Ǿܷu݄o۹g=X= #'*7bf=ft~z~i Uߪzwp"2yW'Eɼ=?~Z8Xkj=z׼%yΛ a^3_>Ɨ5a@0C\jQJs iT)/r^[8d̏T 5F 1>S4ڄ o{\f;.fPX+|e6FaQ 栜esG$#8׋_.}eiW.aew>[z{їyΦ9(C?O,|ϊʸ D"d\z8!jL![+J _ÿM7 Fj׺,v]&[~Q^ӼG]؛@[C i^3zR=7^VnM#ʵ>$)/ #˛9HYR!G2}oj<}8N|nۇw<Փ s9/DE%Vhߚ;iՏȾM2 c D3󅱨^QrBk㳮$\8ϭZuo(\'t-໨-hja\スKϤ)n56 Xz-)VJUD3Zͨfq*<UP-h,BP|<#&98ǣi_prGSqRxFL浜I13c& l5(Z)Sjళ?)궲'IC+nxlJ Qpwܣgs^b).~sBٌȲfke'XȾO2A@;}"4-uxmNT%i'S~s?V]KO]Z.w3?7<qpkWjF)~X _-~Qˍʚ>æe~Q9rog jPt-I.VjyQĚu+'xG(hڳ,E#:jhoDk/ Z+.3عDl#)n囩/fh?9xzԏBۦ,&?!jLzq˿6s{=WeG2 "J:L-P rقΏ;y?~o£^=jIsy[}VBHT'W%sSd8 ip67uɯ_.y0_W@O֠dfK;gWI>&4{#i b"zEuY;nrUƗpxꋙZFG{yѿjmr7s:S=~M}TeX}o[t$G|`VB1rLVb=OUOg>>X_!3ճLRbly>#{ݗ*ʡܔ%%YR#zG{s\%и=ukc#b~?Ӂ|scR~Y|^o"zEuy $Elz:DPؠ+kxph&>ɎuqAlO "zEu[cؙ,,nlRLTÐ#} _M ϦHaF'TqNT1{tdX@;nŌ=|o#Axf0滺׸S?lOCEY2peo }nt`*93;G*}[&7%ngc>6ﮁ sj"{#!Vݲi=$1T>_[[27eC FpʛuF^ksWhE6'@j nC7M7WCcoNrς-!]M]>6?ǝy 鼻R¿M{3\ 8M0뢌+(<`VBt}RKr.i7=x ?H~:ٟ?ϟrqԀ;Uv^-WϺ:4Ģ[u=NE9dH5~S˜ȉc{] :4>Z /[/iI`Lշ9_[tD$l#iy'WDU= D?lӎKqbYfsD\/}Lk;$Ǻ(Ӻ𯃎 xWrb~+2a}'*,`e< ŐnrI1 Ⱦ{~;!'E{k'c99lIfSU @:;$+>J5H4GT'Ԟ=}ά%2̾.TY(״TChqޖH͘Ot_ۻW=)_ MۙyMF5HZ1($z%_BP W2".=Vj\ 72m6sz1,]`a3$31סgFaFȪSJªHT_k*idXte䒸ٟUլ B 8QyR(7D#9æu~%! PklOv^Ѝ_B%*v~X&#;fjaXBi@^ZRHn{46b~=<226Zn+{4a~̾68-c1{X}.5ӹp״5[Z=UjHx*B(67iy')';iPe6}][#.vlVKGL:XiP~./(U~.", J, $:jШ$JY u`lM[,I"v*J qiE29OJV8 j+3-} o7@#Wb.@1DYDϕǾ_] ,ݴ֏$:fDR˕F1ԼM+?mF"qj% Y\tR-?$Jn'P?h+Ҁ)ιfư2m~'P$*zKkTI1Vt4*^р &1mQ%4\)JYD#, P*YH%ux&^V M?B UTT:ޏ]_ʌYI!)kt=,ZiÏ]Z7B'v"4,LY J^N&wM*/ÒJ)WD5cT=yBeݱCK|`>(Txs!=ϰQD &@P*~'N{GGG߿qqqkڠ~ыl9ʐn!B S0[K@s>Y/ qxƊ.ӻ KUdjm2~YnL' Ǔ|Yq>tވ_\_RL>v"[lʛ nvz`R(346\O O|ev{zo0_l4Tuu۶Mfs>wH/+\BlxƼ=Ð%g>=ݏfWJ7ֿud`/}e&zWMHU#-~yYĪ y:GgȸN?;v.m>(QQnOꍀ_Kː鿯v1\"Z[Ai%l2Ͳ/]&#)'n/Yr}%nFcoAL ߶`z\>@Xµ2s8k=xf%}8 WYt'rcKj׆I0\8!Q JnzN-WxLE1aǬlʨ/^/~^nw!vLֶqyN򿻈қ8ZNTAQ}JͫEfPecϗG^ $(CVގRRnʩ?B6N'v z=Ⲝ/_C@ݜX0$nEnJYc nŬ[ȇ~zLlf0ٮ7bc4nE-X۹~E rqq0vc>{ػǩik5/?]Lx?R$ʊt/5/7Ղo6S7FOܨH]ÉqC.j?Byy-(g] Y8悠^TyVi-O qntB k+'հK:+~,~+|c0q-_Xw};H|eʂ(߯N,a;zeX 95 [YYB r+3gF4"%Is "Br;Zf޷]jsg==:&qmf] y" /~">@V 9HY߷̿epj"ze-vzW~iTQ\;+͘J|oR6M~\&ξSt;E>$EZaxiF_c"ŬA~ENed:!0<&O伜ݱ)㲇#=Is“_hYj:Z^a}ܐf=F-Hw.x792yH[}!_>}3 .~A׃AͨtAS܁??:NWT &33~BP-z _kLщsD`W'n,=u-PTir^uС}52MZ;(~X>^=;)m'5p2n}O64R 쵫hfnn#fqyg??_2,?]&DWC/{^/}b&aS7=/6sՕnk<4~]sa= J4Kⱸ_<>߯9GesތnnLհKLnE;!0JP84~iผX|?lN(ݹo|m{_m7{0)_V?A=_iك&t Щ̪Al{]Ak] ~ !6ZaI߶<ϖ!?)fe4jh=[9RVYt+)=lGz{o6'O5|YH Ͳ)82Av a=Ӳ0?`;C҄K1$RC^AʟaU rۺڏ]XKݺVv;ڍ4uWHsG%W{&P7#/_?iJ֒|v4jag<4~׹7_"(mv6"!0Qv#t:u>uYF^6ޯ<#Bty6t^F,H^DU6ڧ~`7kǀޫ@Ƨ"h"xE:h^nsz{,Ձ]Ġ z6;\?o"? ׌3+g^^^c:ɀ3dG6g $L:%$"'ȖԒj4rkT3 xIGS zd8@O3[זL$)x&ɀJ6Y O܈Y͂ZK[6bD#zjIT z_mHT̺9I/^kgYh%h@%zwҍHiۏ"F24!F^K j)$"܆e thgB$&6x9:63ֺ4!tS 4Kj.Qkmtk#< FV:53h-l,z#\#hcp1jjgp[%3p@$x֖A1uڵ(=v#:1bɎ@$i~bcF[c"W ujoIT2feݪk}'n=pDBj=DVFd d#z+SSSߎ.޻|ԨQpС|nkb;vQڌroi`$#dkyYkg8a/*9bXg oǼ2^f9Fq78A3h9̍˩fLA؛;'.S$2hy&@\i\h7kSU?FTk4U")PR]@oD*`hE"|hw9|vOwyGJoJ[a5DQhTjG3C-JutO"Ic;՘/clM}uRj i;ӢF =mJk?ꙋ].a5DRP?6gʁ@p^2}\q~R fQ49* QMyi%2nobc)k!J9J,'>ٱfGG^j"j JIF `0ѕaiHd`ٰ ~3ĥ]&ӭG92"y`ԏ2ӠQJoJq G-yR"__TsC sios P4?&@15(=i@PJbQU_ڇNE+@=Մ4 *a7/!PHڲ^`HvՏ; m744I]v6i`RMhI+"y(z[3,A&26U'meDŃp?xᅴ(&Fc9;İ'Q]4 J ,T ֨4;>JJZI@$6&>er2|}]4"aao\Zwt$iJ%rcgm֬$og8[ k͌=.mF IݞN8۰"M"D4ʈ$UK6+8Ͼ2nb~A˴1Fq"Ry5/lxjnO^V9j7y@-W`@i^,*UhA*'HDsm&VTe]]J:Zv jVO|eJJ%T^O$hR-4* G;tI9R$#k5$a~D{MvĠ~lR(*fƅUSp,]d5sCm KVdIbG)jkU5M˪$H-QX*Dj)憕͇wSId&ϺgiX'yHTPu3ٴD:J*#*eeu\6fBwZ"\y=zj_@L6BUɉUrݨhSYu٘h9~RWdh @!_dp`7g=K :ZOQ D7.DTt,e5n&utggE[q`U$aE&2\,QcBEuy Pe gX&;xJ>{ 3ꊋ0?&T<ڪ6欈DXvJm1[llPy=btwD*>n;η'M@_)U[&G!vIiрV^`2ħ'A fPu룠&Y]}HdTKeg``V97gڰ7G1n/7BHJJq/\[@Ҏ#=+FfL?[;9뜜'd4nw j]FeQm&W !ml3O`w50w{{ɏxμ)Be#~.oXNu|Ays)'.yߊou7*P|EA:[b:1GyYZkyƻN[Uy탞Eݞٙ]l73gCeą5ޗWus>} ̭p1yÄLc{t{̊;K{wƅX2YQr]s6uۤ wiSOŤ luۢgV^s``+)IڤjK9j6̧Ŭs=Ns0e殹17vQ1|UI3K 17Giwt~ّhqOMlhLƆp܀?)=ӍM痙kmQAK.' ]LKNT+ch/zR'۬&Ҋucr1;;w>eORb5S}Ḃ!XN7ќ&xock1O?*}mnE0/R̂֌m\U~-η#DT(aɰg{RzsQWW؝ s3WIxl ɛڟ^l6ۘKPKiNL:И;ƅc3nso`u1iSO/wFqy'm:E,Fv %KH%w}]Z˚{A .9ocj;q娌gk}w{NMO)@3|PwC@5jԊ+9r֭gϮ_~РA-GƅTEFoc=WxKP@#3O%t}oXu|ηSm&G9?V\oJ+r'=(9K+ oyP?n'Qbu3W _,dC{,K?f>ù`/iBǻ[wz"47.iQB[>sYP6|A?7ffƅ[5f;f2ln-f="^S *c &c*=p9,9mɽg؍xexY^3M 1 /i1%أ`v2[WV ?&n?o..\hH$ڿllիW4I^,D߻ƺƨJmd!*hd,wcz9dL?C " ִUiOl2e%F* ϰY#*jB/G$bg.Nnh%6&xyU<j\) ujZ$ +mld#)HnmapLZJEAD$2Ց Qs\q\>djc5w;iΒD I^׬mD?JY-xjՕxvL:h4F9e݆MpbDW~G&gi$#'iSmL  ׄgxѨ1kn&o S|^$^ޙiNP̘2 9կ LJ{* bp4m:ѾERVU&YuGw(yDmmhJF4xT:~?3"HS&\TGNJUi"zԹDUgNR*9tf9e"Ŕ<Ҳmگu@1 WWO=E5DEu .Ց{)d#j?p,ژiNގv M6(U:=]wAQUp0'9W  XOlkF\W̥;p<,?ܸNJLpqB?KCNfXa~ .岴bjRV/:7/=ُς kioٷ1G4rtG!^1QU$*Y蠒*~w L6B&@BKβ +4g;蟋#2dHMM N4Y <}4.9g<}*GqdMMY4 ɦfݥu:dS#e@q :G)ȦF*XVMZh4D&C-U@& z/%3B!C-K 5jMH, UR0ZW}&@JXO1FU$Jl1J'E26o m6&FJv AoÏ2?#= b_581d=^KY@ Iֵ%46T ED"ᯌG2tZު *HRmuz<T!H$fkטl T"}?(d}#52 VkTmwf*7pZ8iZ&55L&CCk׮uܣNӭ 0lذ͛7Çnjӯ_YA,g bi]I*\8c'zV'ɾ(Y·R+r'kT3ߒon]6jT*bŚ. /8S'JeS{Qpl?Kqr9 F^h}l|X]zxh$LĶϹ5gVD{9e jR4Bem`7:^JsFr 3zvӠKVdx]c[֟8;SR)evpʩip܉9r~|*9EUGN Qz[.wbo V{v9yM=աE?.z)ٍ8UawĿ"v94$~3 !S]bdq1SbV!+sfblV"kЛ&,ys;Ǐ?o;-WTT!:d61{yi}jMA^-Ԟ}*tr3q{z_~d+A-,=n e\4JMKKKOO 4nܸr֭3-_KhzR4Ղ1TWŇd ȶӬQv̕sD*y@Z\ŹX*IJ~UER6c_F]I~W, _Z\S ,>Ko.*(`G)W:>QR0m/' IT{IrJ eGe#ʷ\.YWb$cŶ"B#y K~! _ BMFqX-UQ`|,mÍz])dNWs6F, W4 |=2tf]fk1wtѼChxRrvǝ=Ė2ǽ}_hCx%liR4; AqCblpc*=jaxz/| -"@j#J̢i{us:hac2+v\m1@݅#;Z?(5aRpќ$S#e?'-]Ysa݅ [̦ Fw9Z8}%er-3O,Yv)tl[9F˪:͹~kX쐷-TG|g(m~f^Rw!C=7}|xh|EͳlLW 0NE݅`?-kq7.Z2^N,L]jsNyk׋:3OeuwLA6kl7Dd PZXflY5 lCbd0nՒFLۋ_Z>!dAN&/9hAv$GBͭ:Xm_W-mOYXyCmR)ttp>bK+ Pnl!`+AWM?o.Pn$ dgg3 ztSS$K87vVAWTn6uWv~attKS %s!:ReHD#vxC,T5p@Wɯr-bk.H& E+]МډR*H'ҩ{,d*$*EV]O0YL k!{WSl1}eU-|WޫZTRĤ2 -# h"(ѵi2N5_4 %ӯUryF> &ɲj]@VRQ(&D .(P5er> n3ִT'k5.0 Di T~_jd z|RTs)Z..c'h"DtDJVV h&d8%þ]-iHS-}:~$L uQ4@"냾2:6}=ګq$U@QLufN*YiF0OVZ(VpivCBNnoЭG"QV^~3?p_|(.hOYYFjB+sYiKrbtvGjTjYI5ȿJ?!Hc  .G /AevJX(jɖ&¯ Á]H G0:^%22\/ZlKPKZN~B'$II~Wb~+:W#3B]F4|DK왢J_|(U(y9!bg*HQLi/ pd7CtzzP(??* 4qZM*+y?L 4'ϴv:C3= F"AiHiwti5"fߥzuȕ\U@L44JnpaM(f}pZ,3J-_TDl(R)H8DᯒaDFuS7U5ޏv.WI-qZ;Fp0KrV@:OhYQ%hm44h.2W *-,c*ٍds 2JUكl2~PH*BH26lYAle.EuE jZ*57/Zlm`BΪF8=ٷkk ɷ7Cwy5ڵk޼ymʤk%KtbfVISG hcg5YKܑyzqЀKQι֛IΙӻ:7ۃNGr*j8{dʫxHD^or:Rcjan#e34To>.HbgNӺ8aR&?AoQGW6ŔD3zej{7xocPu\#YfjjHv7PU2Z;_^QMuqD3JZ}lzbѴ'oLU6`>wr͇K!~tf;ұu.Vvmy+fF&GS ާT6 miqJdYį\`648z1A|}2dys&;<"^d;Hs*l *kՁ^fqiAUkZXCWY+g'_Ƿ|X U7F=U֟#+(G tj G 0>rY(?V@#W(k@b~px`; +ezbvuiApN߮\[VQ=pQbNfv{֡%ӭ̫ 9 dyUH:_S66[9 gYk1jüI(fI뇩XbZՃ-:Xe` hq?Lp)sfNF+eRZ2嬺E!t/7:bV6/ %{n.ӹP X+Q?n:f vJ4ryT ڋbY0l]p'T=xIÁ\"`Š+0 Oپz|XkjN ʜ8`J58&Xr.Cdp#>^2.$? dѣGrss'N8}[Yf3f'';vo 1N4~)+AY KOd0٪%d/.G~:Wh~ŢiKf 3U/bj&ґ5Xїl#-wn8oچ65 .GDNR>s5 IZ,f~AmW}iʥ{V'vl:Ģdj@yhH_,r.ÑBwKZ덋̦\K%qCN4ތ8h=ZIB,J6Aˍ XMcw`Sh(T v2!V!|7D{c*8oY%Q^ا+9:ChнVՆQ@|=\"c4%)v!S{x֩՚yTUzaSִ-{+xΗdȣX k5OXrj<PYVW;dнm.Q^Ժ펕#V.ޭƽəggm {Z۶υ>n:fz l^]cPK Z޶ڋ- 97ZXyYuS;Mn/Gx? ~\dͲn;Wo;s&"~6Wo9fd٭'X8_;(+?x"lmYtվBo_߇ o~޽"f{yyD?-2}xł)@ |)D"Шzllg @ D3DCO-F%[i de /A'"2:M03M&enHjbDCZScpzϴ\6tZ $djЫoG i\> # NNm [t( #?Z*bcp? jmڏNw6cpȣ2VMt&u P[6R(@8dc# ^YDFD65nۏ4j~426/ # "NljS1LSk4@"Mˍ#xIUk?jŽH4.7ZEdЉL,tlՑv?C(I$W^Ǘp\ٳg@@@=j2fom34>r) H"@ Z/_i]ܔ!*g* 0?EY*zTW?3WZTlahnc F~'jbT8+WaTWG5DWxͱo)V~wC}PH7x'NB//`0hbHQlH%wOQzŰZ I^J 4 mzRL4rvRATFь%6=#hhz_C4E4RYO6LJD*G&z. 7=~NRJ1%lD#mݠhև:sVdSQ1mC=y4(c~j"aJaTg*V555ǾZ\\hZtU+ h`_̏1q UZ&&0lEMmUΪy/Z:3)izSo;-Uo9w&ɐ7pbfA髚/X0Cw4AMZ2_ϏDCC _gpo$CF玘Je~uk?6DݳX0 8?~ ?0{u8QC*9ʼnJ4'( mb4lt= zVQMO^0{t'[tED3AE|M5_hRD4'2 >|4Hn{il8 ͥ-aWFӗ0FIDAT1N@ 7TC{E٠Qi:΅*nSãE)WnRlE3FTmjQZ~GqFL/+h|$C67JK7 tvڷHajo 88jjJ2:u~OrhçT'FN Q,~7JG5ufsoD z.ZV/ߝaO)ͱoQ+ [ ܛwrocNsr\$P(Z 57ꮴXˤ::GD1;p#?5rh`<ȹpݨ__\A22BX5h8 _Ĺp]Ϊ>BRr#wϨZXBhzʅ_DQmer}?Kgp={\NpEXRpyEmF$~v\5u&Lm=|)Sޫxͻ K^Z?J~7Y-Y(+)3Op#Xp6p"mH񕼜z&{û]ޫxkQjmC=쑘׍^v j'/b{Or9û76]"jps$c яG5*Xbo[%tp/UusẢF+ DJ,cgѷ GDY4WdYU 7lhHeOڎ Me sẲqZ$V ?乞=.A0GNa17´ e3W b47ceSŹp]-jkƬV)9PÃLɏ_/^[X*-,&7ʫkEY_E@tfP66Nծgq](-.>h_z0{m&#ۮ]uRiƝdss KV embV&Hw'|dmc>eōZ ܆;Nrl/*䠒q9qhhI]Žs=}̨?Idp圙{`T[^Xa6I}Z(vׁ՝ Hz8ۢnz6͊%WlI~AŚ f6 SZ 8A}kiQZpFdOvJ*VopeTf?nZ{^j֦]$@r:H6c٩ɟ67ߧb6qN)-.16vj+Œ]; aPΥM_:9`<Kbg1m҅r`z8?>3"R.UηavGZ%e֋[̜Vr&FW 2!x(+c^T|L׏R]gvExYl؊_񒒼5A~n|~bmM l:%z&CW&l~u(rc),T-@6ȝ'ɬ-|I^Sku_5A|ZA׊&Y_̫\Ls"A;ʫ*8:V : 5/MBuAӬF?>]I`MP_$p9~H֝ďOr={ N^b֎}wIhYC5=~ɹ&ֶPP( j9o}Ӧ]cF: nύ֫-kn"th(1PEM 񏟮giZƵ*Voe`gD-8#"Ӂ=& ZQ  P%3PḼ%ͻ'OYXOnZ+VoC]Ivq.`0Nkͱo]O3:J3j!pU5ZB,oIsAl=|]\w4=yY{͊%%uh!L3 x>BݦuS'yUMmF6og.C4{Z]ʍnyqӱ:G+Vo33f }C\ k{ ݝz&\&L'ӡ}D y7iyQ>xU;ÔF;Zϲ\zzaޠK;63}|*֠$ܙVK<=`Oh|EU-fNbMa[umX04gqV퇜7m44/YzAVhSk:zސ;f;lU4nXm*޾kx !RKj5 eIkC+ٽ_/T-'|xT(Z&ӈ%fLKsfBLa!7(-TGFCI :޹O4V VgjzQFFZ8GE z?2M63cZ5F Ǯ|:ډ2 H %~Fc>C˫~G 4jA'o!ewer!bFV[vWڞ@ut|&Qm׮@ŀHh|)Xf2с çG;IvF^2Ux rmB6 >Ql1_2Ӌlj#hZ8Uln|IrLW ѝoJɈD*E22uy-[kEs|6ܜ8j]"ә抪O$if@TBZ\Q(-DD{xQLG iXMdД MdK SQ ߅:̏_R8 -fJT~~xq '{[y Oď=q`9318`ا7㵛}e%fƢghm> V |uds3#LGDZH&2x v)05 N ?ML87aс{WnOڒHK$A.'1ŏ-k4J}#h4r9J=-x <##"Qo<9J15կRI#D0W6k~T45EJ44TG֨Tt{y=GOdh J DJ$٣oi56Z}  2Z?h{TmuE8w?4o迍\ YӚYsQ*f E q\5kf'VS09.nuY'eSSm&h+WwnLIR ZoGj-fY%A[99ydsGLޗ 7}N_܏$.]yݴ AVk(,\f (s e;}RfcE(y 0iN$+_b|ror]KKt~1%Qe~v\͊f6姥8YOm8lN`:d(* /a-^w&jT{7jz/.(t\19lQqjm)Q( nҾE1x)_* k&4Ɗ ;]G{sEE)8uWpQg7|⧤:Z/gثǿUWt.c߽CЬL׵f?x i9eanZk2!8 q//m\lwSkKZs ީsR]?zZ4{%۷J+޿. E62Ey?J4FeV4FɎm2tve{w7C JKKko"Y99ΞvZI\T eUްd;rZ". Qw#wm#Xʣ+0IyYXs{]OjO%A[_SEy;mWE48}CH*?$m![͵+evkoET9aY'|Fo;t ʒۈ4դi;7WKre߿lZ[RZRuI4}dVI~aٲRC6XZ3'ٞO4ǡkoD8ڀdm1o=U皿]$}% r2i%A[<+hm B^\$HVOM) b>b*طJwnG˕Q呃*U.JKU ҝnG}̚>iϟlblnKwa IJkk߽/ "D2aZ֩QN![o^=Ah?@Z^V}+id5qj9^oWuȪgR<lTu]uI֔lO2pmYIS'H:P`:!yD}\v\O^+jymMw48HFPǥAtGg~ev6'}@,pݽ[4dG dϾY5yާGte(KwngߊI)rD0ޗ/*OV)9A_nݬn/ǫ K) b>|"boOC'/cǾ#JNY7#/9hʴzC`r648ydS䵵upI5W/7%n ʖ[AfFIC &Dp=`7lczw.پUZ^2mΘ:qkiɦ5W/c~=U66VA޹lIwv{hJx_q鶳C^[[ce3D18.B\Xڔ܎_nx:un"iؕFl ܿǾ{e=Î XuGb0vW3rDUjo\G=!D -Dg`<.yqe߹aȱE2~ g/_wz(!;(;Ҳ2%fO32buz(D#]j]vVC,k_mz3츱W*m;Λxoyה߫C7y褡HoM%۷ub[vZUgN 33B66aҲ2Σx뎽dSS%Ķ ?wpuٲ|hTFX|(+ϖNrݮpX): M/30uUGʆF}G<(^ =uy6`B-up@?QK[ʴ@Gqqx&c1YM ^vSŏ=D 9O0ۡQVf] u[,G|6k:,[k6pHIĞ~T\\vfojA͆` ܒ-#/l#MF{lߊGNXMxeXnfgC')_4VK:Y?71wD%HY}bsr硓F2\ZV:uvB|E v,n"N2;yXXxX:0l{(VdxQ{`SVUUl0:ҐdS3{LΣҲ2pjW{M%LW]GwP pj-x/&K% :tBˢ 2$axGag)UU>PmhΨ0LRVBstXZu\{mg PdL/o9wRIӝ7%Q(FƌvQ 7~fkKhAҲEs@@-D"980tq=/K%r"c QjήgďdJgkO 0? RmliN:J ݘXT*kRAXZӝ]0[ <7A^lW y9FI*{|1?Vlb"(8u*y]w'THILLLT{J@@/IE ܊ rRP`5x_\Vh5A.T2S-3JLGֶmI"TJ}Rlܹ+KT: cg(HL&*y#׬H+mԱ#)/Ref_c67PL{iMѼ9IOu3pqyfblJ66V)<ˁ ]PkTBqJ 8a[\]cҹZ1k/m)S @$2\ Kd9M  umK&13%*n@R\^ϖ7phxHDP[Vg_VZd="P@\ή#[ $%Ty4{'@J fwIyi&SL5j5^3@0ppkcػjDER1ۜA|wڟ8w:[)OC+oko9XxrAS-@Xz&nL`G#'}`ӴŬǑL3(VWuNSC =7jIU7ӂզWNͣ(#B+Vt$abGulݔ9h);D񥃨dhqi׎Uۜ~zNb˒ tgPK'y9Y)!h+YlLIa7vzvg>07j^Z|ld~n]h3B)xlA{|c&iHw2-&e9d?^Zthyޜ/.sҊ'U*RAտVtAOud37pq^NkQQ~ս ;ø ->BXZ+'Rw<6!u/s\lF%OXO10jQp(r9@Dq8sCdm L2Pi%Vaծ61ٕ|\sgyXtWuOMw]풜/}9O}$A<ۛ7ٱɣ {}Mo]rIg EY=/A@taD2)F#!Kћh=齛~='q. -i&aT/H=4Wҁ_i ?}cV6̎NT5^0h4#9m sBw@5Fx=p;V&nϷE_rBɽ:tGfwcrqVlRd_}>s}Ph3G_] Q|-fz% ɱxpLAϾ)ʻ3S vV(ܰw=i:ZX`F!]>HX/2RtCPI~Ɉ2x[tϬVDEU&h y#ao]Ș5ty9w'iH Z`Hy"dHZt'ΦwS<> wvu84!Ew_F瓭jYWRr_o fm<,-;٬QŮ$>\u|3ɑmz@3+|>}pĩ˿.FY: g*՞3n7͠ڻp5la>`_CFߣV}1 ˶&PVO>0$tYG |ol.QIV9⼸G9Qq(̩^5 썵.u; RQU(+,xטB8fJ;3x?/M̐Ȯk2"AS=|g _;?tDk|:Z71u{3wjNWħm>**ŷu@ Ĭojxpgom`pw5i$wd\/3qr~q o'Gn_Z4l AIs>_=hA9 oy~lJb$1X(scR$bpi[c!;ݦŬ\UdJ :w{!'C^~1͋(瓭Dv;Ŭ ,OZdkr,c<I 隘1>9un}s7A̚}v쇯ǰksZSrB^r@#`',::~O4IP ͌=f.]4.ػOz$,mJx{ -{I͘ұO?{dYS9sAĻ[DW//(vaA9pkYEq森 MC^mL\KB_[9tkQ3b6Q4}w!z{ gی&$W:?6b&$v'kImpk 'iJ8)$H &"a+t^ 0$C [;wMe]N\%yc!6/3||Xڻ %1` 'ej棣IFY"-xw3= =tGJ,(|5)c|(npl!T~X,1kkˆw73~pW5Q+whc(1[̮Э(~zgީ p j4kl&gCK?}bqtt;rFGi͸/SB&!Nt"{g#qP1gj)^jό`,'a$DϊxxT/?[ }r$|BNG!5.7O'A}'n``"\ %!!5k7@̳ Nd0Wd9eE%Qzu<ɩ .xJKq_Ï/%Gfm2{KRTUok[A6)J!. )`l ~=VJncPFH܊6q$b3&LK(]eF~>p2ʌ"^&l󥢭Z 7-63hVt \vR;pTcYz"yXaqgɚ p[;<[m$dlmR nL yg8 y58'Z : ;!t6FDN{Og8 i^f3'(w)p2 ^;I QtFSny_XJCx!rYTtsR6͋7W\~gƣs_f;K'GkG<Z*dWgF^`c w~ l8M]:pju;gL .p;'4at6fooxA0 Fb9Ѥv2el|캢6U#W}g/q(T(*&,i {߻ Cf6O~!66i,avbEy]O+w%&=uM%s2YD6+t G//~o=mۥE$` w;I4F!`O WmSI V{}3I V7[M*0﷮v;LuH<]3bA"Do>u(᝽n"1X_/|^~j nur=['ylnf\Y&1Rqy HŽQJ3EW/za~D <(W w#1XF+Ϲebo>@1ϋĿGXjKopi*᫃7~qfUwjyUq_^ 1[H닓WCP`~2xPyl_5]$?޻3!}¢?rܢULIuO m*Ӊ7y|# g~dQs9\z L }x|դSo@WXZIq$wV֬Qb~oiT —ϮTqyŜ{|A*.nͨ:a^<8VH%6C"NP>4^^J [iK~4׃>76Dg%$pwHwPL d}|_oa(n7?^F-TͭGW{$ψ\nIbţ ڶI9Ի>]-oEV[CEaςۿ"Jv_hGGԽ?9dtm_lzĭp@uܧ'}x]'d ]KJ;0+dmH1L I!9@TlK?H۽4^puTh] W8@ۧk!/5cۭ]km,O^y5 ٫ꑒ'ⲛ}Tb$kv% t|P_(;?:ԇ6pDԳf>.w@KNCIfqڿĀ]&,b^9GW+kƒ7O坍}m0ews47ԻNя>8Dqq4w^KJj ;Yfd4}v[NRA;[iG q٭?JЂFDNotkXBK,:\&_Xg댣fT򀜥vJjPܢ _G<wl u%l~"t1  mcx9X?,#j^[Cpi.K^y=C{ۻNB0ZbԲWUU|'nv|^P\wX: [G[a9%'ϋ}}P>!X!7vh O< ol/,ձ3t L舲 J Wu*)G~x5/9 ;f7݇g\\kDTrz*wr: //z'0%yQikz~>Cl$^rɨe=)9OwþDۿHfNb{>!8~|sjr$U?, :^ʁ@wZ5#-J^yT=-=?ylyм8gY7y>Wv5LNtjʣ Xxޙm+NDUB^ BI`:O +cV佲Zao{NY"*+-xA;1Æ.,f 0qmNCX!C<2&ј~3׊M2]Uw?:LߐvMfcMewlL2ovE^9KBd ;Haa’bmV+ZZu'0Hϴf첶*es&$(/lgl&gTɈd ƥ$9OjC.B{C'DLf:0C4ۙ!nl6A .qڑ~V9^DcOf[@)Ta|@2G4|tAY6fk,f.jtD 4S`WkX " ޵۬6Hq8ڢW _Q7^-O/Jk4mJ"x&L@Kpj AF6eB?i,(L`'ϤUSaɏp 9l1詮tw?' Dg9-%G MЛC4"pǡ,-p$AqFj!3\4(Z8! qU 1]:jh|lf:qǡ0LZT{4S/#w{l5n68`;j5'[Mz`io#RhxDgAg0*0}mNLh5*++鿚yCZ +bl~WlRC:IC>/ȷTWOuwEwf$7Fꤶ6 t01 vfwĢhnI5WˆW=zl?ЉzMZ/o22n|O-38 {"F;bPʫ zfG]WkpxH}P͍5BQ?x0Pz!pbԜ :^Ä_0RBuu?ɻy0?x`y|%$7 䦓 X 5X Z!];i`+' s7Ŀs( $];am֮+{MαY-J?~TIt=kVw( xj5[~ڞn2e~Hw_m?jn7 {DӉ `R6ߤyĆG;DUTF?+DRxjD!}G4bV2mIZHŤ xp| 曵J 5j'^"6=/p/=K{jAW)d̨6~?yjWH@#u'j%j~[5CZq' 4" }~^4f@ѹGL W4rEgmhmfcn!.Z7鸞Jʋہ 5HSqղV6Rp|tb.YGUk7c{nM_qĨ$@NlYLbH]Aղ1? ZNo^: hxP=̃Mycc64 T]I$VSgz[M&jw&D-?mޢwt^B]Z~U-cC:j{@NUj ߭T\A_w]5ý?T[ZN#?bz`֢߆tb#I~~G/ucs mA;?TկjP +߯8"kl8zD颶_wdé-U˻]Ӊ6EXwEl:^ v4jn-?*aik_A8'. j~Q9iKZNmi|rR^%(ԛwe\}Җ淟s4jY'w^_꼆G;ŞE O XC?&h'7ᙱ?p|ߌ2w,ŧ8,Vs/JZ lgi?34#Wi*꾆$H7kUhM IkH4&jDuy+x`ǼfzPXu}`׎ 4~50.iZV. oN~F4|S$=})Ģı zPO[.3(q0]Wq^kXO&7|`[bVv,ĢdHHYʾ+G.x#$ KRa& `?Y2)L״Fю?>2p5D-xM'7̔v /m!IC;tt"GM n7s"LD Hyi74nJ[~49KO:z;]c_Q2eN! GdcP; }9tn ߭%+GN59}q=<@z[==I'D 4ABS 💶2SO'- W[8!9ۯ-?DwgiETDe"Fcjc;~S x+{oPI&K/FݡYτ羂=fm;S7YL}u2N>zj⑈9C4|Coap0"#Gx L?p+S tnu5858{"Q&H9v 'A2D@8U Lg,xaW0op" h|!na'I @wGs pqPKr.o. D2u|7ȏ ݡ&QC4`{'1@Nq(4 lw"G~tzYԇyC {K$Hc{Eᯎ{BPnOk5 K9SOcSPI+ |A3:Iم]eV:Oc3p1,b` @tt(jҩGz9XBHzH_qmf}x2bI/A)V;6_`1碶{PѾ:1G=BS[@cF[m8e{&(LҺp3G|Ғ?qua"P;/aGW}7*H;,AXMORu-p鮴5U{GLYޓ3SHED2ejG5ҾK?sV b $j+d{$P %=UdZjq^!\vf12>^ K ŧ?K1%oע:Pt S)T>"ia[!Bvߘ,7/l- x|=ʯ7&JZ)lj d42 fuOQ[I+G4)Z!hOiGbn6ՌQ=2dpgIP"QCFD]Xd "L{擾6^v_EV6'ple,DD& NV>yN2lq~_CT tU%.ZL HX> sOL|f7qL`1 pGOZӄmP^%JpT̠ڋj)zU-Z@3V<1O^7N.2jb#MxS.I3}g wӘSc6`k_oTN^٠f+baH sN+rm3LXs9}M: wSk A jl=>iŤ9L_MY>҃$@wATF/N v$TF[TwTҩO7 [f.;&/E k;gjHϬs󍛴p]oE@Xړ m/FqCweGxmw]iU\Ko,XXufzIV&?`3+4#saa[aGNuL2$eq՝E]<êϮ+,3 w 9ih~P)'LV&ha42Ac[.>56MzU͹ tǶ ڱbWjeiK nקߠ6.uM@lNwKbf,M}vQ{p޴g>}4ǴҁkC+/Fgy֜ۈ&PHO+{O6+:o|ҿi=}J~Y3\&-Nam4{9 ~kQGiÞ,@۟d-%4Ugz$w;e,E"jc۟J{k3%RHy[x_ 4W7rzNyr7Z.`Фi|KFL~6fk4 (nIOUկkr8@ M}jYe!v|9r3 W Æu]$vwug׳݂Sq8ػWu@|#$њ/Ư}'eс3|c:JvX)O9LA=鯻Җe73%]39$hic-5f>s' ߖҟ.؃Ѿ_FL}ƺbB">rCP`o6kmsg6=ªϮ74(3faiO7\ƒ . K:fQg׳=R9.2iSO$a!0xơ̗#>t 'JQWu,h6qʓdrc_ogDe>shve-i򒏝&[^+}pkJ\vX-o,6QowR;i:7ߘ3hįx[@TOeZv;sL:E LG/Sv >،<4uI݅mn;{kt Xtrauޑc/@o1=!sAYn6ȩ1\|AϠlЪ_lI —46 Hx鋷 jomS3^]aŨ IyLWk)=O3UkPI\}uO/ 9I1Z uf{GfSkG%)tyڋ y_k6+֬ǫb.4^j.>鋷5Wy鋷 vⶰAHj08U!&f=C|Psn#i1?[i|5y:{ ?!0a>2ܳ81LN@r"h5ᅓ:B'=>¯2ػO܃歚Џ$25w?u4Ug|@ ,kP;2 nwDeZ/֔wbт%~dۭv,v3]/ 63b[&/}B ~_Dd0;-/O⁚΂Iә.魵?&f,_2ԔE&M_&OFkx@[˿WH{B{5R:sz֜ iXrΚ'4^mOIIu2>sՄ1p_-AwqBƫn A+kUDs7hBS˚=i{N̾[Fͨ|2|'T[~}ӌ)]$F^鯦{?cIIZ@m.nbŨŧlYͥ_Wƀ$T<:O~]97M1yTĠ_ĭթ 5wՒ{5h?<lL9v rluAֶH'pۛjb@I#{0Uw.k,FS "dN!.t Jw`@j)ߍ%Lk0زQ)MHOPS.Иw4=b1l[}s͕ܺ3sYFGO}UeWׇDe?(Pu{WS)FHJom4|Yu{'zWMz =Tosw2LVvu}_;tI\[KKɨWMRnM^f4k zywku*1e@ ~ps`rr+nliD<"6߿PWIM>Z Z%[; v9A>ʮ+PMQ.,' =uƇ:.I= YvujjMlź{eWK %; zU3ɨ)-p;4Й?%gcu'ZR_*o6de=83EEy7 ΦRivT[_+^ |if7H?s3!,N9r_DէyMn 2ʛMXn!pIg]]/5ݧWP?we-%I~&.%Q_nQ3cn%G6a_8cnASu51k-#F]y{ۧۉg6|12XwtE/Sr6\+oF3Lnn#sCPDδ-5۸ug&Z=fNBq*nl,&]ō-t\hղ љ8 a(3sv"x'uASʮ 5wKAq_5lVs]xZ>P~mwlF66l\KEGoLGuHd-c)Qgsu +Qvط]yk"d>BvGdwÅSi3> }T4zlb|*o6\V)ieW׋DΙ2{cw_j;kn8?eƐH 4mV A]q}335W_f-K̶m78 ҕ9o"0k]&r V1Y =}9(W4w0cVrX;︋2d?rp{;^SߊLxbd<{k>v"9ס6}:*l耫{̡3=g.ܧ =`jf:ãIOGl)oD-^܇lcѨBO[[k h\܉{sI |uY.Srp/KqZVZ2.-H5wT⬅{)t%twZ?8 #{-4d6yDed;$PlXxlPOi#SQTXEBIⲫӲr4}.`VF~e6XNĘg_i(FҞO|HD>xMˇ;g.:v v*@\IKktScV %k^R\sTg.Gg:O'f,}b/V8!Q\~}kДH!o.^Fa1gF> kݽB,Jv D~2:mTuQO9铐Abr 3P~ߞl\T>Qvu}@XVʴwtHԬ{L:9Vt\$rTyl_@hJ4[}Z6V!ZpsR{OAwqu'^vXyւ=$\"RkS_x$.ؔg!8}Nr 3> H+|X"p_r#E1^1c E [f.: 🣢g'O} 7Rlqz`XG!W#S%eOr _:k}jYS`pf4vݫ4.E)٪UnF$4zL&cx&)ƦvR'S32b d?rxMf L7H8C}ef CZ-ANyģj a"Jr<]y~AS:-q5zԨԠ4hSo6 fitZvye5R|K0z(*!(ά{F[,"GV)(=^Pxjl.n!^_  o[jN=ߦ ج&5_|?<6aW>V7ͬՌdݎ,*n, T*a4su{2FI^# KnIG?r󒦬KQk$]n1!- eZ,zbhG?:"ԨE{ }nGTF0#\&G$vg-؃cwfqǟĠU &Fc`N/Y.^~ɨZjPp{KlV1mrŤI@mVN+͜l6J>`Y DrH]yv; l+p~,xDv`28A#G!`4 n#9N~LH P]H$:*&$XV'0@&ӥ֬:NoŬ B`xF%D;@OjYA7J$f|j0ZHM!m!QsU87#\ר z٠Hd f}6eKK#L>w܎;O?41Ηv[B4j! zx8I4aԉ AW^'!މ5p8ax l SLp#pHP8I-dtx=Od"l;15jxZFfYj܍fZNJgx:rF DϤj]ǹmv+ 06E@d:=j5MN؉ !S`PH4/fyi$~HP9ZhG,^_;^m}ݱtdV&nj1(032z aQ}oU}=y2~iik=_?8=]X#?vV2Җ9e571yA/CTAYvZۮPT{٣N+ɞ<'KTaQ݄z{%KC]RiG{۹ut^-]W`'xa|T|6ޏp}fdr&wg$9᥶e ~cS#lL߮V }3zxcN'vZIoCgE3H0^_j`O2k_-棿;/mѩEdo jGAU5 xuYmm6I’QCQ>>ŢhtfhjDпR(uڑ3wu>cJGFepLߌmf6*@m_=8T T|RUSUS%-#@$a!ED"l>j0(2YwQ枮=*PQYW{k뿿_,j4Ȳ1{sөwBnlM|]@I.3lj8Z3wgL[/Dkk;۴)}qxȉ (:z|pHd<0x6WG- ,.B`nEҭ,oMM'N*~^6{+hll0w^"vpӐY,FP*6wu(7ǃUl^譩]_mgDžYY;~NWTI,n{^nMH{C&/[C55_twߘ9}x)*<:X’-psw1o憓/~Dǿ7}꺁A3O] 78[GFZ&x[[/G>cV# ODPMx3w0E[ÂMcj7Ө346| 6* 5~c#M 0_ZTI(DN-*ܤIIqֶs0n^o@uHj krg;;zil>5G Klbh Iu ̚3vs|o8U*Zw_hmujG~S`$ܢ=76ֵ_Jݻy<@8|XfBS VTidCqWUQ*9ٻ l=:wm0ef;'TTY.ڑ3wQp>)@ ge04ep-n&?+1T|{@3w?@Oښo_yaԵ,ѵW"/݉FG@H ][[ehxvFFŵdЛ"$(UJ9ٻ]X"$Vn ͙eͺtnjitl*3.w^'?ڬfu:IqVvP(~|Ҥ?Ɔe$eVNA 0b=cf|4[(/cfe9g܄$uwݨ;6)iyL m&6/}cfNw`Lb[+RKEc;ƢMAYik(-A!2 ܑ '|tsȝgdK9$,*:/%5i2J1^ӧ:6w">/I̞K;6nl81>ĢJD ېY327tq3v:)TB\>sƖ@,Ŭ+;:Qx!O.̩kD4sD2EV;RUy4!eo=:<*/c1B,JS2>+UuR^~bS'7v2kNHS=nnㅓ^ZR^` 7Nw 0hng~=9ٻ,eΎӧ A9VpSxI埓[.27QH:ps+{Ǝ@GIW^?&jIR32mP|Q)TIDAT@ثo8w^?1O$\R\#nJ3+k;}ԌȞe q#iTT7##݉{)9u ;agTrKё ln 6 LmWTˌ̉wI͘NsۤST;m?p/m,?xN_HhRSS}Y3}gpP7772A  <̥P\|* ;k/I&3τwaT'd@4^-#tOzA 'htS`:i "`xdӳ /:ȉwА'#@q|c Q<^-@rb™,'4M{nd| hT'd2}\i𷧦Џpfi9:":=+ʄ~ BP 'ϧPXIϤ?#2d Ɍ$I-FErU_,ggg D" t˵f%T J+5!I@y1h`S/o]1xƒӣ3cuBtϢ^AQOk ;x':dјF0(QjOj*Hk[#6'(rc-:ol?wWmj WV`6 P+Rb(j3 zF(\Bݱ$r5dx`0>}aIKj5X4  YmL,sjLV/+kd$"%o{ff=Zt  r0?햤exp'/c9M!YChDt#Ѭ"jc|`&VV{bSFBf:{ycٝ3 Yl G@g߭GfQm鹘鄆lՓ(-8n’َNFu%IZ?xEoH sHfL|FgiD*ҚFQ$S`zV 3;WVw#6QFz`h֍q fҼP=HD F]yvmQeϨlG`s`%BNweWJ{"##Ucu(+tިo߃|2L /&ݳ{LabSf֍3x7XĢxv˔XtԍZlT\Xdj@o:#u3VU|wp_$_dUs1{٢gaI7v7fPΤZ-O`B=8+y5Zaihܴ*^fҖ~Q93Y Zd2i}7cFjAk% 4Z'ξI5?K GjTި;x {im 4[uӐ \rKn 癬PJS#_u!4N߻w_|qF F>_rP$2{zI0'm٬)s>&RsGV} HXDY㧽"b(M'sfQj 57mV'_{Ik|}1AS^hE:z^.̤# .*|V/]w 腝+(*o,1䰥 =gL|+2* ]"|Sik~=wl(05@#䨒_=qZ[a4(lI,VljU1i~vOx-ʌ5r\A^ļ=TsOOx$*H n6U}w9+(S ͯ7;=`s6wmh(.sӶu:m!'e Jj-ls/r -af%}$ yeފ/{M5T0&,̯."9yqo5vmvgO.mlƩ5 5wxsiqoW*REW~iqoJn3v 55%sS7Y,:,Z/kTAz/,6Wnɜ;# kPɬ)k:1DMۢ7K2:hVGf`A.a?(WqT@nZK}W!>6r4ro8 MF`:;'ms6ޯ?XJIJx}ht₪E2 UZhTIۂ=iHQL]5%rxnru_L©qo4t{ͩŵlVsn*EŵtQM=1rǨA} ; =q~уks^7s‡87mٰaÿ&Oר;D&4Wnw|+T@y LC?;EjNEFvF.U;Q.bp=k2OžHw,>#<Y;'m35m'DͶXtyiʾF W..v?sR,Qs';z5tzl$bc_3 k )xG2_kp-Zz.e%|$;ij.u{ ?SiҶ2(jIY"2'mѨt Y BxXoMLe}8OMJ܊/ßN 8Rv?XT{iӢ^ɯܮPci1gL^λ fK6pk(fg@_tiqo6r1S{3ߊtΙ}x=R+!Ӣ_nðݿL^p\~(ܴ(g  F,aQROW4bCln`8*{8ĺB?K2sҶqg~uJIJ0lK(/͉L @z+~+9Y\j龀2]ҷ**3r{WԸ74ثuXؠSV4t:D6SaneV̇iB]/,X|dtB(Y,w-ON_X (%9X,2sn~!)R!h١s4XIsEۛOC,w[57:b^V؁UU<]Q=F"ҒžG(if>=eX`軇 v{L֮{Ⓣ#I'f 3o@3(P6Oɝ! `'9[BBb ϲ7$[i2D6VxGs]zNL.gMXZL߫ UNM~^.pLB#}/DFviI ~ =d#UWu!Ȝ7R/Uj(,gۢh$4:/fcYSʎ3B_jxƁKy#,B74/[yshVD}4ksm.:nfGH4$Db7;~e} fPV>t;gΐuzdіt~ŎP}=\#=y-fF=Htjkc;@8#{|iWj3[J'^p\8'x,ѹ1ǛkRR6 8¼Ѻ)/!gV[? 䍽iPI&iR:2T?ލ/P5gF>ov̤P+D@J{Utb7c*O>,䠗ޑnqIcep3A礿k D9C7iqi6$ŏ/LJJ{2?nC}>d[\rS@9XI';IoRd69nl̡3ʇ̓ڼұ|]Ǎunս4# NP%\ q{mJnʼ΃:/.k;$GAܯ׵Z-yjIϷ/*#Ȓfo;h0*Sq@G2Z~S5!iXKn>YL7(j&j^a;kk;m'"xG:Y3=# 6ҼòVh6dWm6xVkȋ3cZ+ޘޟFkmVP eߨ;޼}.Ö[mf@cޤ)ZzNtD(  Mz-x0lk尒ZvLD}q@k+R `/[75$fR1@qg?ԛ5WEzIq TZ͏]_ُ*?ύT<(,w'3 05en C/ʻpgu|=\ _i[l Apʻ+D63>yHQǧVin̚|!qdHڐײ/Av7IWv<Тuw^.=f4]o=NhJ؀cA[ZhD-›D~ It3u)h`]uW\6+S*}mCHy-A.R"Yzlѧ,ӱls쓪ķ*m`u}纆Ǭk0^HyI ~mUmmOӱ?g mݏwaDGV{K*mc +H xFvU b5E ۏV(uF=7 b֘:uN eE ۺ_씀'gK;6?nC=}Xci R4+]o~=nqHޔײ7s` _aН~," v\;p-^mN4kA' =*_Z}HgPIIz7+!_RI:t~:tȍ^I%3C_ Lk;B^1gkz::>3[tbi¸M~.:WTPcz3~,6eT #D;1HѲ0n'3uYsEw֦>෨ޑr{mznG(Fr^r%6^iN6$ZFzΜʌ1;VM4Z4d.GNGT}ė<(4w~Z 6~GwdG8A]ިD@5_{Gm ZkR^>;Xm͊ ^cmWN57fjr + oV} eJ=y-\2C_CqzGjܚD͋Y7*`SFCax oZ:>E=LmPIe]dЩw|L~.sf^^e,փ,HlÕ vT HˍLks!65 }?v|n4Ŭş4Z3_`aܦWld=\T]jSI~҃9)*-l?jY8dv8$k\ɛdmݯԋPUW^ ΤPgCo!܁n^skهHz=?sIX_R#.Ap7!+ڙoy2Bڰ}Hkj>t''0L*5?v qϊ|υ~ÔLw.j;-.!& cdeEє=2_h3h$55vc-(V"tFń!vhE4[!﷼nB^kvLFtzT[ѕ20n~iZF8Xv(u;ws1v ̓W>zz6k6j CL3Xu,%`I }L ;gLэΝAKx3K]8^xN*jz3`o)|f=WC@ŭ -vnPw ÛyAui b7|nG=稚ײ7kvFгx>;Sx Sǔt>֒/C,J#?`P[a09ϙ8?2>J_QFJ̪-|3W8I]ÅYbql _Q$G&r4FɄ!^a"D΍^5^cGXaƁK3߈ ҿ79#Jf3 "q&wFHiXTmWzj7Sl2nHgS :E b 'Vl،d"%7-)F56YA# 2ʤ>"D$nRZ 먶D&EnbEq@0D$P(rTv`wPj]w;#HoV*Cfї1aUOz2BV=D(B͊H 4(ovqg ;4ol+&@EšHlT Kl_ ;#HiVv`pITDy0C& C'%^ E2)uvcFbdYmHlfk8fPH _Ƿ!EnfGp4`V>nTB) y1pzj3MdH, N$z!HodQ<\Dp*հkhJkȰyWEc$͠pFOf8EVu @DA (:vg )[6#h6<+}|K(mv{[*2݀8 ڐ%Q (DL7@"Pq6J!1}1N~VwczɢaGiq~4[uT#j3D\7H%|2 <8pc ƬU5ɔzfuU(_2vł;tf-34YuNUsgTˋji cC"E1BIsh~= '4bX{ E$qd^؝-+.ToˊJhfޢB DxNjA#noVx #*l5[VIe C`jo^K+kEC]Rcݲ!ϱ=,Gvk-$c?m,2Yz -󰶫_Y?9XH$ə֣d~FyS^*7\SMZD $!vgR@+;jlĺꔗ$M,!^}wz0zK0 Kc+-vI߂Q&KVƙ Vc-LjN\8k vtcd xewYf[NiPӑޘU^5HnCsc)Ntjt'`fWY>'蝒Ac3G_QˌS5d=@>eFK9T?\҅5wiް  8i`ՠe;$:8*J돇=J "ݧGMGlѪ8a[P!:7+,v߯dXד<ް]xvYa0Nv~6f_!2L)rȣhefz Sz!u^SQ߷Ff^E$wBs$ywب~ wė527Dv~giqxStfLQ|yӳڮ;iϖ M| b#7 >N;,vLU>{3 m|'U)}.|nǠR2 }Qy#2=vZIS+;Z {C+j~CjȼuQ߷`יd?Ҵ&y=18O^$#(8 sQ$u~j 1[sPf~EUl u7$w/Ju}wxG^/ &EұPES|R;ihܭ]{.-;K;:wY{+9({>pwxDsR$2r;;`y+Nk@tw853BwAY>甮JX:exn{..&='kq@ެ, o2 57_^QtDmz-Np)v*@~<I\?4a(wěRW LVCgM CV1HX.iao>O' bD˻;L{Tx . œwZFS}i:aU떝\rSwx\Ҧ.-``Nл;84ff-DO<:)v"QWU uz)9+e@+<tHcx.JXP:pGό]G^^#r,L~ WA0+`+n輋4xW}ZT8%#7v+ccӱGo9.|-/^D/Cꖅ!qӆmZ)Ĺk _=$ EX\/(%P(Jg:^]'= 3#Fu|w/Y9_i z+%6 Vᑱ`}BCzR<8@k |y#268;I /76LWiy01re9i$ՎUrNt x '90o+$y(lGwAJW :j0GfNq%Ÿe{ajͣ!EsEs uq8h9f<>kMޣnEfH8,Eoi:7,ӖP~w8%m3x Ӳn@+gAJlÐ6Ifpu,` =! CV 5k'*?17Q$⃽/3z`?/}U_琿 cGv@$?}+iaGZ\Co#:^D!& zdE6 Bhy BVQ'ȵ{[ mCI$<+u22&ɗ ?bǫ w@ zyM9T(x HA @DR\Oww#&e#v_݇؇V=ES4"{o (_d~֭[Z= >{Nf'y2(Y@#U%IUXij4"DûP-vWh oߔ,I#VBJ!0`u Q*B2遞W ؎]HqpaU]Yѯ}[]şѻQ*F=vtHp3^mbC҃[VZH 8.xu)Vuɴ^U 92pvLn?FW І`'J1pMW^qcQu}6Y4F>ӱ`Rjii}x[?hJ=<jl  ,OnL^ɜЀT;6DJ pwlȎ4[7h(]GNa{pTd{5zFpq`.M99 \qM3%-i6'Wbֶd)/DE4Cǃg);fg6Nb(-дjl[ xC3SCvr0nm!0_Rٱy蛲E;՘kHl'04JxD[Y6 +Ã_AC4ߢ)i[qte_95Lzhޔ+ѐe[*2C Ux_?mjSLDsgu_0OĞ,M24?xs΁uTڗܪ02ˮVC$Ƶ[S#c62f;FܾuT*id"ֿ ?]۲~OfX^lpsˎ/Ebvc^p5ݚuz"a1md+U=zr"GOf5}E(=ïDW7'%K)_/_A[ NGwEΉ 6{[~oXrӳ 13NaGzȘ+?k<40a+m^+֍I,;ĤnZ]$иvk) G"$y؟O::m\ql?rz=C k_:1kKw4ݚw Hb)DW,v`zR=ۥn跔m<_sɚgv۸vn9ak0Z7,9G%; իRر}㡑17l~RZ{wֳ[Sn u/X5#i#:s#tV76~57ZO6vn>Ѳ~/5$i,_lf־,y$v9ld̝O嘟5ߑ53jmܩ.鐵N v}]y2o@Wl|~6aSƵ[3nI8!nsYN]=#cnܼc-խe][߬' k_Eowۅ-LC\o@flW'|H!Zz1б8;ʜRIӰe>|Me7}~% zD5~$]&J_&׿R\?@Q?و C/~枑8~b;~|؟;[6Ė/+Pq+b{-Q4o(w XET9 0$/\z 1C3W7~"jB?LЇ$CVqOG [i tٸQr؏ٮ^K [1jakk j5>](.[N"ʯ|ʧ3nI{GgGLï 3 LO/_%a襟]1)XjV^? u2Cs+>@HvAwjf2wNBv8^K~g3T_tXEJȉSf._;=e*31ڤ?_t}qOE"Vx{*V!ӹO<һ%x}WC' ߵ6-Q5,;ӥdbKTIgץ %U Db%9zEe/u5b#VI8d<{.o^]}QO+c/O_ˈ-Ϗ ծv9gڟBd=bm($Cay7cIK%S + +_G>j'm6?*ُZ~Vr,H.mK+FySՀ$CVqX@˖{s?& G@-ԷݳUjm~ }i[؟' p7 Ortb{%AOzzccC4}ɏ96J7"+ۼ7ة![lakO3eb̚8ؔF.9GXJ{$\I{'BT))(@]Xkcu)v~@qY[Brk]-Vk)o7v{X93kȯgi=':~hD-:F(D +FlGt٩fM\lzE[5*IBQ˯<3p 8(h-M/hSv:Ci\E%SQn` eU h&n w v3KiU66.dg)("-@ 0(6*~2QLxP,:mLS ,F OOx'QI[p @p&)ZUu1HcCUxQkxL(61F&.l40*;C0##n8XDLi2Q[2ZpAc6vR!P1)DioԌXSJR84J;2Q;K52pL|pk `("j)}p P&j_`&(.: *;j(=]jAPWc5h|l knI'v"xA8[ZlO.G .l~{u"+Uj}ն[#6AtUle/~hz12/w9nāwV^+/94]t+mN~/kKX:7(@6lϤ_9*|*|Wݶr}n-;Zz;ePfC6Zmj{QM, F-O7x/_fK7~l MGV8ਫfCَlGRf尣ʬ֩jmU۟@ yk3ZŊ.s>{U*1=OsbI#xMO&9?Qc]U.w-V1N:m pY6οr˯B)E,~hSoꑱb3prb^}ay;je7+u L0Vn`lOgWBdugNa{.;{a^ ɢgLvUm .2d9m=ZƮ$Yr6vڞ熼zXLrӥOjY(`M?`gΗJykL\,}ڝ=2s&$GcN h|D-r+' %iڜrgO?0([kvS)1FqhJOY^6{ŀßbLrQLy;J)BWDgBHФZ>]${p07%'[@:""e'ᵣ27y%Hƿ_27ܗ=,sSOihg@SlK`/\${x0Cwzn Z>M՜1\TcQs[)nU( AN1\N՜(|:ݽ;Н6xS"0:r'B5 V}*WiZ>]d!ݩ3!otKegaf߹ ِ7)^g$jn{cOk\MꙐ7*"t) [y;QLB*_:XsgO$ WWRBgZd7܆su0:*%k8în;-2Q%M=2ot贗Tv#sY5KOO#m' Ň乸fKv~Dm ˡ?:%?tSϝ2\MdK1U.V"3+9{o|F K-:2zc Zg/~be^GuZvUBފeY~LxTwḡPY2=x%' {ZRvKvK'\]WBWs(XEF*\@2/#\,][tDE\D^.q-' %J+Sn+4GJ--7`b]>z y#MG?H[85Ksҟ㮎G㍃ߎaJKC|W!(QNWxz%'VvZ~`}} tGB?uy1o=WB*Jyq^ UI1\>.|A Od$g/ȍ۞dByu&)cEul>VH:?c/?g|+M+gGPjHn+uѝ?a(i=V8ПyUMYj4M{A}H\,X͒?Q!*ҕL0l ˵;6rG9Ukw%'AxI@SǑyE噫0:zCX )2ˑjm\*nE%C6Ezeu&:rSX" T 0z%Y,XU>k2Ax"8-PQ{C2Z(& ׄ9 # a1QȏPR8!Ucꔳ,ȏar] H y]MaIA%VAB0Eq֮ tӞ>d.gUtKqƚF@=l e !y+Ȏu~fmaM.!nT4,) ҅1*s{5qYd 0AF*\yX+["D2*d2mk`"8nkIŦ)ź*n0]8=>W麳=* ' 8L);3v"9Ȏ麳nelxB4 BT&"1>LX`;ư5i󦰌#{kW;@G%@"8/ 0tykJ%pMz8i`8?$("XGG$ S(RU~F$}-⪑2;aRkDE&`;n /qd?4iN4P (Ԡy~t/^- S [⊋M("fG!nPDƿ H8 nМƁcbd# 0L+qM5!s,ANbDUR v% *A-Ѻ9l ̒0c/D`5ՃZ%"qIv0gA]R:*3/:s8i8 .l%tv}t7 sƎ jqI,b[PJP([2d%aR5FLt/Z%S6lQD\(l/{(X3▓X =ss=x*JP^V.,`N6n*e ʎ*ҜM¼duTH4q`;ީ쥟O ,nKb+{|Ϝ0Rs+Yͫs0tqIlF{Ru@uލbi_j,ªRamY^5Q7ì7o,?<1"Μս&[ ^:J ?4wfg$&kc}:၉ ֹ3>j|mť wת8;O `;5{D?Ǐ86 vz4>;W91uoa8&Hisp{℆h&LMT>`C\T%i)q ͔hDڸRN2+85 5W[H?=$Z2MINEվWeݏE">ܓ}:}Ȍ{d6 {\uCw=4MaYyMQT=+y*6)q$֎LܐКzSy׺hȭe/e8='\j!T(XZ,NMgs5< 9w#S-ywZϝV}w=vJ^\)<96ota܆*W&*┦mfSxJtU{iY>y?K$isrlr|I?IOKN-s~&Ϊ~jp->֦QTeKd[y9ay+4yYkqԾ2[pGسٚf1KUWr)}z#cz#iÛ/"7y?uσ]E7lw×ud&[Sp=[Pxծ;pE^%a(ʿ;ĵt+Ok.fs=ޤfl\͕vNiJ#eϗ)U]M'b#i2S1%ĹfSUEay2)nӚWe.^;%%V a\%vq97z/';JEi[ =~2w$tz*&˺@S{߅;xENF_Yt6uogG.:'% t\ԾB+_]PyqcorM}\ >y%=Qǖ2ç4۸R8>\|YVIht?KtI_oTeG+L0Z swzQ(\ջZVCKx^msPj],Rk8}#/w~!Ghz&{>Ss߫).>Nxq$Ks!=W-xE ^Kq _,~ _}C\[,GSV{E5=+__Q@hߝG ysGb]ʜ'1GNiJZ90[Z_^J -JC@Y08d4y1 znhp?fi. k*_+Bi[ 9̞:eL}+9]rطLqӂH jwٰ.5w'4QT_b&KTLۗ[߸]%؋T:Yg{=uуqeIid6+@|7%+S2s4Inp?ZC(qދⲵvI{t*2xr= q)_w{ۘR8:|s@tĶ&z16O%@n;WV]h;=J3|wG\(9j-q%Msgǻ:dPi_ʝ_Hk50w#'5T,NISܷ7d-}yZɷ"lq?sexHM8零V3}\} s,ތ$}葱XazC9$#b25a.O!)C'7y# uQTq"|NRԀnO\{QIO|L+q]Gd({m\i붼[_gqq8jϝ-q%E=2)HX}=)9??@g&yDhov?刻$Ȏٚqyo,Lsd&>MZޟ$Z7WSŢzjŅk:8 ##\a>:`+h:1Ks1؎ %' !nb13=, =EKHxϣiQ|B.iIPX$z/о= 2>A <)w~@LcT|7EڷG (LjK{/N!TTT:oӒ* 4ydtFYL\ԾyNGpJe/R:Y!:J=\VuaN@{CMXv< V9obN*If+h߫]@x78` ! g64'{6Վ_`oՃR36W| wQ)^@tZ*s\iG戙)w~Euq*Ծ#VN&>@Nh &XEySe\H*P^硙vaxV* ;Es4#|s>25q#gGI!5)@yڷڹ2#AqMgr޺Pe]Z0\^//w)_p "u({. 8ƞ9Lp;B Qt"'4owreч2Y*;". ^㉧ D=e@ʝ>d$j?)Q)\3}4vb |N:ώєeq9 0mr>uka$%0(s~FS Sm,s~ǽ/մ4٬҆;o,!mu}&mN*!ɦ/ b>qHlc^WH yW#w[&}&:?2t%P%IKY17Ħt v8D9Yy#Oļ="v^ =J6 hp+ZvJbc|0,fMBz/t = |mef+f3#ͪQhwNsBy 0(~0z駽tyFvbÐ~y 'XA'/)TQ>ؽ:y/|3?T#Bzg92SכdYfRJoTǀU3ŘؽKQH3x:V>@e\`۔L3mUye,| R%VvJf*u'/*qfS̼d+4 Ovf1I+5WJ'SQP8.zR/an&RDdz:IlC\:$L!sMʾ]KC;&e3(68|.JBwmdAɑ]l.i*/or"XhmbPP5U96|O(]DbI:_ϐ]rʽ 佡AW?\Iɽd[vJbU`0$]`8oR=8?I#[__kt1`2O! hP:Ɉ¦ L2uDr71ܓAZ'۰.Œ7Ȓq-蒨òX2^g,aT2KhjF+d8Qt,J%>yMA<Qbf=0CgFыd7Gܑ(. ;"6 ًL Qkxh- +p uFvdd'P!֌4 Y Aa(YK[zsMkBaxAI6ɲb (6Mg## GIXxgޖq lf\,Wh(z,pA@(3ɢ C ;8 AR(D G2sƠ@ 6U<>*U vϲ9@E4)'p", me2)Z 40)QX $*ݮ08UŒv n (lc_܌pa*{b# QؑAdp[d TC8tT8CP^a5GU<r6vc]?mU0) ʎ4W<!Q#1)a4}YVB(Fq7 dBl(A [cD;xTBXȣg"AhBaMSxe>bсV r!Z/O JT1@L+pU`EPJ'+ׁAbGѫdĦjl!+FTpNi`)y8^!Q(V@ 0P\Pr<7 ֵLf3dS7SZ"*o8H PЄO%XCPQt:Uyj&UpF,hYˡtH&I_UhoBo<,v-w)mg(֚ y4JȄL.* Sd0҃N1Kd,uU>SkAau3D"fxB"JY ӧBy&P0ʡ !J!bW@,޵'(L;C@J}Gle,CW (Tn"/.u̜'cSd0ʎEތ3d$ ҾU }ICQ&)~J|u3ps ~AȀ]چ YO11IpHRyJlJۏfɘj!,aLjC%2%"JG9ҫ 2 %%! 4wC?G@0+[;GAn}&@~5j:v8NAG%wڱ4F!t| #PĜ"[dzm %ߡw(2%rrQ*^j##ߵ578+=X!3NUvb?} L3"hMmب'O4U{.c62T;IITI!*|4Iv ^؄7g0mp u@LHW,ÌTcߊIO(xE2yCk )N\]y0on 6gT& -dߕE @-~Ԇ+$*hػ7KF#a0 e؂ |7%F %mwIB+.:hػ);Njc$A Pj ~8C.p䣷qml{7`tԓgG} lJ|WR@dG7W{YV|B#flk0Є^XĽ .pJڮwV`V vld"%(i^ؼZH9t*َ 0YE8w6`E+lV,h*Zq9tEյ!VY%8YT; "Y#s$P y @Л-\~3~!qȀ!ދO8CW`هrP~%yOU~/񆈷ɺ ,Y2S6lȸ~<Ыa!`ߍC{P%K8pW!(4ZOIvO כI)tj@naΐ |gL@Yw"Z8+ ]'ѥ-*N6ؖw`-;WG2FAsP~;ފ p HgUSnpV`:,U;&KERzI?4Qq,Jwa .]'KEY}^( tJgѕ#u2LiOɐ#Møz= L- 5ّ=QPyK:yX ~02C Šu YoU6T(, @DCjq;!]_# ->'!%& $$E(ߑ&wC t ׌.}tvS(? +%䣷D^3$^#p*m_fbtc` ;n┝DpU:;p Φ:x^8/7?I 蚍XdgNU{a(BeIlɐ~2eg&0[dUv]DkVv}(Y?*FE~$`lt!9/7`كFJ|GU2D6ЎȞbtcLc6+0'XrDY-BM ؚbϣWq`ASq[CϣWPD%'FF, r! 7x2Rc^3*|_s.& |gI;I )F7@AaYo ;"VeS T;kGA)ߍvD ל@C\Rr()N8G d@N:ߊljp:HpTr^p'wP~7Pzm[r92beʀ,tN.HrdTjE~ ;jL"KN~r2LpDH)D&q}!f';$dTzňmhY7DH|g-~DOe\@k-NKQ=.Q*dA%}Ѫg. KEz02rQQg= ЉkW\11J>1#PCU.V)FWP/7ŖnSXq׎+TdC"@̄dz/\WQ=NI_H%ΡQagȰ*%gC(?RCE%ZHo8QH+.S#;{e8r]ǭr<^W"t]K$\lw  QWn,&B֊uy%_:!ڿ IyC#""`i&0K \& P(F7%Óa h h(XiWɤ ,hT8:,yJ> =(F-<)ʒG)Xk5K5SAjmzU!t\z_I%tsz ( e)KF% |fXI*d*BX{ tQY:%i4и(i]0Y&cWk.,B4gUɎQRU t$ z<{о`CguhU3+)܄%`F Otbϡ+*9.؎5  AEb( e?+{LOOOMM47xL アrDL`VF`]$ eLLtڮJ4,)΍p^#KG,mu(S̑Hh'.@Uu~ K.W`alHL*)2%WIDATAt4v#\1KƣўPۨ.PdVBB ,&46 )LaD d,ìXX*.pΑ(Qt}̚P M:kQң"ď Rx_"3uʎ">kۗx޳?O;;;[[[>? g C1q)E"2w]ŀ!emš+ C t0I=0'}q_.ɃG~pv!&(3`&2=S ѵE OUX(@oKK@\^ !6Jz`U<2pFȬt}$b'V;XGIOJL !)لy2yN2 .ph@+?H\@( (WXuX$ћuI,˿#3dL (Etc7e;rˬmyH#X3^SbkzLA ;402sLۉ] 2ۣ' -d=""V 2?Ad6Hêjc rK$&}H t)62]RF-j4b.70R;,|6/kf*Ƚ$t$\ PMzm QE:YTb2=H+&ޚص ޽^R7I|ۋ~b磷D"JHQ%Mp#y.!;I-.R>u)G<mC&. b- ϡfUIa D=y6 #*jO]mY2 Cgi8 K*W{{Q)T0 L4Q1L6J.ν.H ^`vy;\yh@<,bU)OB(Go*ga<9gnhEjƠG䙋8 ;n $ 6L{r;D~s]aHbtc I|%2UnĀ?K &w X h Y*ZCH`:zIiT ǚ s GΡ]G"t}HY"78/7X ʺ`d12I^HߩNb _J~.5lVS*$wyQ ,vͶ|ξ<E戮iH PmxS%_X^JӢ(fgg{<_xo>Uo-|oq'# 0hHx2@wbtC^2MFuq(8 b{IS U:D8|0bc+Ba22eݤA^,tN> y,\1[+Z5MF(:-#d!b麈'a趒-9eL-,jmOZ`1`=SrkgHDR `"(q @ ʔVm49`gK^0vZQ m \:};Kv܁TȔp8~[l6B$# ֡D$dJ1dP* PQhd1!ϓRXX]JY%ЀN{+fBRe]X3Vրn/:j?C*(Gbt#%@ڣⳠWڏ*Do+RJ]P)KЂ^ kTI؏tюy]E@E{IS`7;j"UՁVCH,JTYH ,)T=a!]D+[+T+̕LD=IqeQtZɼ^LdJ6o{^' %,,* lVoL1uB#P{H JUu1|f(G,D׾Ŏc!z[Bwjc謒0}iб1o] 4m0n7t B!c 2P2y1GtSڒ)B;aR@F'ū,S֒96ؑ]`3D'd9:F*QJr? $Jy8<;qkJr?Erĥ<. } N";SXd,V{Ȭ%:Q_pf(l!e Ð* =^wj;I-& a0JD^DA*,( Mdf?J& ;Jj"kG)y+nY\@A|.6iYkd:ް rrv#Ad"J9Kb.Rl'U*;&CF-yL4J$sP`=(#!o%!˧PQiP#Oо4BWaP8!D~8$ЗЛ=Ш( +Z)|}`*#2nat"Gaxu KA<&*87Qِ'Q(ZO Gv['KT[fN@P2s6;HMtg6a47;HubFyEe=h:xW,E+jב +܈!n TbA2V{&Ф}:s0NIhɷQR"zT*VG(]0YEI: +')'1ho,ʳ4棷[HR|d#ݟxb]]]]]__Z`~~~kk å߽.fl49CP@=y!\_n$^Lqo%Y謼ǼN;7 Pإ"'%]M@$ $'>4mlMkϒ1 "*PBvT.Ɇ݀]źQE9]I2E땏I^&}ТEdDxTR3G ƠTGoWI`;ƣ䞜S" 5l-lWG,G^TJ(L:@ϡp0MJD^\L=8Fz ;Z09Fz{QUJ,=37q ]P7E hyM@3)DGdؚPԒ's!lMIQlM #8Sfi:zIiTQ `kQ\\Mi>g[I[w탖aҙ^M.K"'71%Cadž WIvH9B{IUll*&@/PHy|KAO ؐ_e'ui@WϣWL(KеQ2 p+Ul+ R8%C3d鿡 M,%/q8.4૵yb !5;qN<0{B.*ꂺ#+% p np~;梢vR* @2:Bfe4D~墢jH%! As2}>=ʤ]~h}8GIYU3=).ۖ(%HYduXVuߠ @(zYQ  fG%ܹhᄪV*VRQ,{WU܁rP~~Z?4ƽw%'/{9Qineɳ%J9MPB撨J . JJ7JYL^yIVS%4sI*9 XK0̀Fxs lp4`Xd4BAŶj )Ŧ+};Xh*a&=:\PJh92ir(MPT X_^A kQ(^G8x&(oDR6ib4b rNe]'KU,*K0\D [Bڎא4҃ry# sc]Ie( bH(9TIyE7E(faLK Ez*=O3k\)Uu4ʒ&d#Mn2!R* vjHAle2@%+zd":ER!6%'qD%<_# s0JE(jP3̙J*YNLSdRVD#ff&< c6؎H2&LRl;TϒYReyB V\ +b8+Ŷ@1eR6n@l[L9U۰QK+b L777n{iio߾===g)]oK'io8WlKx4]R-<(`ui&:pQH/"KDRqz0 8 ^uH\ rux^xr.1oUwNfkj㨽b3BQjld;!rq"N ey1N1EmBA*!W"S@}X&('$vwv5Tkx7zekC.bW2+6Lܕ½T8SAxfF!.X3w{ ]z3xdOX+#+:ӇSҨ㒄e2hNX=QY%L&y3,vmبO*ZꀓB9%h+#vw-4d[Ϣz>ꐓsx< ey6HWJKŶ!::GW+{7EJbUd*c 2&p+!d U2*J xR{9'4[Y*Q~x״Ngg=ϟނ^xb"]9 D 4F$AKI`Bb2SJunp2ו:ĪLG\\l;>@P vbO07u0jNKz6Rp;:Fe)gjT>RlXJ5?p${Cx\NO3e;:V/< h׎lb=y]-<%Q^,[16hbX)gK-֍B0ϱQ}%Oݿ_ZZ ]yUP T%a+6CBv{$cDa㸷E(͢(|bcijt@~Q5bu,z% N$]pXBp;Jɥʒt(Ā`5 bHH.6J@J r3pzuyK›cCqy+|τ"וbQEqC%w݀lN9d+$Ï92וW͑f=Ho.?N_̠[d\GWxRYg˽q(yoϷ}2yU- =M{tm0t*}Wno[$+{{kG߽h*B#;{8^`P> iAKbo`}_FOlmط_p~%Uw#[pU B LeD*9ZMX7{ Te1hڭ* ƒŞ vm- `Vy& *Hصd:u2Xl,QYER]ЪRSOe f7tX~[]ޙwa 07P[CQ7R2pgAAS}W8H]@J@1-TSL4*wu{Un~J /a?`}7@8cǎuuu@% {'&&~*E>uUUwNsgMs 7q4rOR4Y16MCNZOmx+}Cb"˧+LES08fF3f*s+5PNAl%.+Ί#Vu-v 05Cp·#Tti4aЈC:dhK5ƎsW9ݵ!ByO+xrCi  7tʦ|,vLƀ|BzZx Z Bn!@`)xK8)4' &:8B3hϬYx22O,8\JӜXf2;*hů#BGhGXz_vT6{w|A p{(tL+ hFpxRllє08#Kb`+)s#, *2|P=um4ȫ3½X3zohzw52H M3_7Jvds= 3H.~4(,]ҀFb:v=4[[Ez*s; b#ԯ]8# ]ņ/6Y<8  $_>7Ĕ8'L ld<*1 x0(4) Cb *vpoIn[b gP((| >氯Hgxޛ|{ us5*.+_i)C, M+ MGB4#]_F~$55_~-..@bbo"Ӝ8Z*U}Bߊ+1|o@;_MUO^IdR<_yy]䫆6l)܊ٔ 71՜U# ? sYKqGYr {n2E<ĶrKxG!?ưW]>QTņƅ.F%s|2 ] pB[ɮܙǔ/Se/9Z\綞2]\K=&%4ȻN:)|gbi쉳{>Zbx7sC-6|(Ȟֽ,|(t铺vbD@rϭH:οYhx_&Ўto{=v?D1m^#lB@o2ϭ=́3:ņ%g,{;.| Vy\ɭ< 7GnSWz6Ў%Dqd<_.23={o2>ˍgT=bGҲXjF7_;"tnF\fPA&6_f^6|gZ8AZ ņ::iaGa9-lKG O|b4/q"6 B={=H2Il)ՈWRKzKzXᾥDqhKe/ŀDL>.4y6=mdG5IJ͛(>|811QqQ@?5\Q sbT6.w{*=w.im4?P+T {gqs׺:0S1%k],&#zšڂZ?{e.|yTB5w߀L1ˆUlq tJ&}nXh_'rtս>̵{nEFEVyґZ?'n+1|zAi-8s ߒʞ8Q^ZyWh*= >főڢ(Z ;{u,|y͗ӱVw>:M>KN:F miUٻtNRl25y1Fd fL`&0_mHj 4ņO긇ǘ< N mؓY5@6Q zXLǜ?SFcDxX"T&B`uf=LQ.j_Gxojjjz~~~_vw74ҶP6;T0:0rTsފO TLsF:ƜBNJ7兵,vJTUfVn'1wb/-cfv{¨4n!CCT3{}XtֆRVq#XsRe[ Q809l= 1/v5NUŎk`JHf31EUV8&)X^6ͬ0?Ȏk" S|@ZV=ju($\~XsjaQOל m(̌eVY% +D `%, S{dFN U4< ИU8+P  ;- di.}aNKV #~VL%'bpEa"9A8%Uokmd6sӢ>{_W~;;;;++?X[[fYBXJ~ QL•П+?2qJ f*ZʐUMthL**&t<|1U+O T(*MQ&H,E؋!7`"%<$ʒ5 Ed y >Q5 X&NZ dbJP:RY Ȩd慼. GZdP6*,`G'R@  -`PH{Px)f{LwQPV0{\[ʒi, 4`Õ YtT2RU Mpa)PMd3HRJ(yTدV+m@Q SP:g88Q2c)Pb4pD7'Q seHR>o)1K_h0 (+D3{HURMJoK&ڬPHBPd1H(5*rzY M*K}%@qo4'|_^mI=քnge&?),x3f~jΗE2  gob\rE~hvUا\O꽡qMAu֯_BzB1:=C/"'tcGi̐z]X8e|M}9_cKy#:=3.F#f|/2뒞$o ʆ9oUiRfz:Oho8Wo =l0[eM'RBT]ΨEMa)Y^U4X/l?;v( &PlO\țF*V)^~)] U 7XmĻ}.uMyq+lVY~7ZWUfv9 ,}vLwiu=u΀G@;VۿJФxN/WپTA݉qwI}V7ж_~X#6VYXKi匸O*mȰ!,hˣrݶO*}Z°k_)c3C.;j1PtdCSIZocݠu~!lo Kβw~cxQ`z_GA.6鯱ߎ`x3N&{7kWpvf?pXboW۾ܣI>`hϚr6dggqOg~Ͷepu8JڕawKHG0+It^Tʄ{R:A#}%G#SY} €l_jY?V!M<b{\UCKIDG>w〻tm_7%js>ᇮA"48v!),1N|XI~ r|O\ )@;]eLfU-}W~Pw\$hJm {9ƫV%JO$+E\S2B =]DݮaOKAGZE5;bf&Ov0v|5pMp=W*8u]Rf2?FjWRg+´]AwS|nv(E%BkOxSO/87%<7ZjǃZ/!I,~#\r~ӭ;t8չ Zd0:NlU2TZ=Q^S\ҎZE\-~K{m.E~[O+?wׄFڎ TھMPi5c@n&׫lA؇RJOfǓǗRh348MrMa ^^ir9'R Z37jZ&;:ciٜsR9$&83 'p0`m# PP9J1Y^KS[tMUOLwuuJ:M^^qZD<:nv륪3**CԂh*N1ɧ@͜iˢ++ޕytVqqIoծd?fj. s8 KNޓ`^PqXu+;X`oFB,:H#!0'@l$Dwyt5.^ UW֬κ+b?7ʼI[ܦW\Ws6U:p1H$3os#+OΠ}(--[ԩ{1+許1_UQ[VB1:ZV=B}H9G -״ADѪ_~`DSjT_V_evLo\H)L)g90*ɌۂEJlk}EW0j#2x6Q UߣI[;_yʟ{I@Yξ@PASإ]&ctSB] V0Z%J4]^0#NރyXAW%&q6,{{DV})Jl#Yv5GF!v9!3u*TBgq'0nrp&G$2,Teq ڒ6mE&kK3 ȸ^SСÖܿAG}%JR<áF4X026ӵbURRjTr8e6|EWIYO҅6^l8me(ա:0/S-H6w=?|5tZs!}-&ra]W1:Ԥ."\W?iJiiJ^R \hɟV#mk6LSI"XxI5L4`6wkBh]X,S! T8 <^/c^1i /iה_ xA`! 1l&꘮;'~1&% O< yd7iX];1tkc┐1obSYwU.8|z&h1geʳ;K03e1LU1ذ0&)CM1əX+~c[0X3 Bh,8L[Xΰ y4jCNQg[OWs)[p[4XkThA]s}9jDw'?ZYz&GM$?:y,cmR3Zfl֌6$*XV 0!MRՄ;KZU8?Z8hI? 0sKփ ;l^ҳX ߈ηJK8Lz7 N=Fy^o`]* کbX"DIaގ΢v~4Z @̵_Y]dUODHbqz3 Zy$T&lj7 X1Ax.AdpUQ~^RYx#Nj6gU͐Vn]N aV%ͶUd.ѥ]Y4Y FR>3ppVEkVlݠClC2U+FfgSXy^cVғ1]p9ǑBi%Vl0]TlX %Y0ɬ)ܵ(iW1!b2ُ`M6,4.ѥSU'[-17N[|d5Cg \o $Ũ6#ʹ_8 2FTU#6DCL-b~.4ϢhPf(E@~CDJʏ B~SHjR@=0#Xم3MVS#${5+. |#ar.m+xY5Fދn葶ysq*;DQ"G_ZlOV`KՙUڇ1+ε |g Kó5M+ OjX,zzKtP#9"XsgE@tY4 4ғP=٧=6xbb0јB'R&ݦ2#(xMB`](aQ4rh"w͘7tf %PcRi x@H݅ H- %8 FzƋ4$d?DXa>8ZDXRՇ]1wُ\KLHZ,D akx9 Tu} ﮪ_WI/—HD;n@" 9 UՙU^qmg/x.9'> d$bDW-\%*4k36eƼ4ײPԬ((0Ǵy/x͝GF`@FⰦF`G0mږ}3i > 'L^B_ኘ$|VFm+o 87kwI&-GC ޫV6w:MBSb7޴`F꒶-}J 3h5˾Y.I]*$ޝ5smIŝr@M'p%>(xάS_$TJlႩ/yi6@iS!mM_qoi@y,g14[(d5I(st=_f#(a R9opf;5`X3ePX-<[FE<*X_8}lQ9 ٫%d_ď$ϗ~Z֫,d.g+wmѢCkOYi=٫-)EJ ѣүiQE3Vp~U=OVFuE[";--" #SֲB΢VW<7?=qæݠn٨pk<L[5߇4͹YD"SS9GppknԐ<R0_%u\ד+yN"uTr\W3[ŲK8"-Ң9s?a \yiUǵfe[4s^.%_$SɓDȾWAס*_.zO4NҼScVHdE˄\FbÔ2} y>ҹӑ4{m8I/=* { B^<> B܈-W4&t}s\ea4O+50iˁJwI*~JXGms~leߠ{d|Qk$ge>5L[  ^sDQ 2K/!f !"ACG:T lAMcTk- K Ϻ<Ljϓ~1uU!YQزPCl47ǃDp8pbIոRώ:r%O#'r%OOz*Kr+ŏYHvLlPGg u~b7Wڭr˕<=iqoN74I$@`<O>_)~ ,EA"MQB˗3ؗ#c9sgU\ f1L!,*K{& c89a+5/i6_%!pv)[4ě1me g3Ы[үFmӏ%z]yIQXd')=GD><`LIllT*KXۦ™ !G  )u`1xfbO]G,q$QGF{6~$ge4g5a?j /Da!;YZ& _Ч˕墇`t ɓrtE bC `/Ipס% g o {ypwy_L!$ޝuڕsBWq]OWMt1؟7_E2,΂͒8,X$=\!B>R330i]Pe2s*SpIEG{,I6 4Fy@-*n(: d.8D $֥-C8 0U?>,¡]qy˕%jkhR\'WZ-D ưU682vJJ Kgl8jp #pm %LoPgD1F,WfNe nC8BBi$8%bש#~lqVU9ðV7[Y`!H& mmYE1,OlQM[~u(s-"8L2&+P72-9\ݏ+Ai}䋁>ṽc3xǎG>U?#fph8X ; {Gx4ɽ]12 "_D0yd7g4V<6Qt !xJ`҂1lO(E|7#y10L& 1 у 6]~SxJI=CsC8RDXr=^A(^.I8? \D(хtxF`s.&c~E3…r12o`3#o85Y >Xv_: OAU+A'h!ec h ƎPL&I`Nobm uk+<fSQ4lBMԷQ+A?zB`qp8b ܕdalX[P8s'q0kBlI'mTMs%ɢ \W.m+J`AV:y!JgU4l料xjr"DzMT<\pe8 +<bF}LoQG+Ыӻ S( xK EF? p_J H^j/;ſIB5Aӹ7fh=]Ӎu#B0|5$T9~1B.[cG6,Vg$ۙxêUO#zЛ ''vN?~(\D:u V+K&D@sy2"`?L+_li:Ϳٺ87P)VAXႜS'PBgnܒTM4j_eVcEcG -!$~ΊP> ?!|O淋шB`^aWw~N`\l/´b{̵(./^ wXX8yw 5-aEHvTV5Xf*r_bTW'ODVS 9^/O}ףh;8@{f̐qͦ]eUӧ'(rd =O-ӣ8 A <΢6>WT7s.Q<Qb@ V喹ˋ];-: te.ǓgXfBە77A6ηbTTN;Y ƿ G, *Ǐ𲨋i`0FT-ҟ1Fdr%@lT&28Wi|Dt__Y[/ՉZes~Z=sF2ො\- m鲩S%hp+ YOq$ ?nJ'c6Hx?Ƕ@ O}iMAXtщ):ES0vNxm &4]ӧ8gr8B]WaULKUӧ˖NqYfi[t%02#8A܌OGTɨ,;lneih caՉU^ps=U/y} 5W'O VE oAkSxp eJ&-U^Ϣp~5mҨZWz>cǿJOV@\#c\q$ !,ә%g\[ac6~w3\7+v3eHaW{=`b}c4"`:JyT $~NBr'9/#  O<@}&I6xbF?:6[BuKLy}o"7E Vx>[G(^Wzp!!Z9%&~i|iq;+Vz>c苝/ [0Z9ä'e>6WX?G`}a  Ŷy<&,_2HK-ÇULQ!6^bOxF^Ԅ* YIdL. etϗzΛew;PW<~,2FtrϧxJ!v8Ⱦ\;Z7}T`EXޢ ~sFhZXƏgЃG)`18XiqclT6Jbk&OsPZcEYOrk#q3w`dE|{^;AB,LG$Ad ^|g 7 8=̣zf=ȄpCl/pu`Ja~2͊CzP=ٟb)D(R\qc~2hF?dF&ؗՙDaDyǓ3A|;n0E-cv?z=G sO~׫XBOiDvoC HӚJ&sQHGŊn //?6PcGd2w>ze$_0,hDnاxnJQ<N2GZ g/I`βcF~ݏiM5ҟUM/I聘\6xb@0/3折D+h @#WNtz(za``?LjzF?b$lmF8b_f%t4CJM)<[ا4/k# G[$2qKvt}d1>6?eRK|{=! !Iy+J&kU/ .\bG'HqF?W fs$_&dM=&Ʌ3UOwʯJ k[!I.w͜m3|)lWwTM#%UL0yGp=ԨpDO:{ffft])MkvZYoR2Bq ޅJL1&׎b܂]ؼ"0r89@>BS:5aʰErJD\sd7n̙٧S9~RMuӿuXf'7F$b0L.En0F.j2.` 촦/ܖ8 :$FpW/;k0}ND L{C'3sNb01|~BB t;u&ُ2)jbzΌf(*7` .Yd1ѣ:¬ٕl[.u gd0W5~`^Viu$Wcf9:vKanlΩ|;-Lm0|:6a~Nk4 lL `2u1|~ ]:W<[s|g _ $rF(B0]V&X18Z~-:q#ow"ۿ|o./H_38OS~S" E.P@e f @8<7x;B7 %iF Qۉx*0L6@04 ˥y8+ "~d渲 a#$P*4?HE04t F3x CuC2ƎD# ~ ގôE@4fCm: Յ GBKz #Ѱh$?v4mhX@#h;; GF`EA8< bc4bF IHx Gv# #DX 9qh?@;Jd#8ӳ sōf _4,"LPp$L7v$ @B?LcnvuxisI|L 3Ĩ'7x;cNeo{ =`lՕO8QRewme}_ ?i f?|L+{#?ԃ FĺۖW]as(`\30o P;'zh&3nw.=V,ci!3@"Reo^׻j4laGDn*sC7^rBOv$pIe'7myI#Xύ%=C%()KGT7lE)8[tnZ< 38w[RXUD[QQ}0@--~L'ɋҞqVPjOTI"׌n#fW4ZwQCmQ~\Ầe(\Xe6W }#akz(=aZLECE]m_~I&0D&m*~g!_mA~Rv-xv 46_>tA 4!7Xd[_ly "` M)a1)b"ƍU *F4u|CAO^|3r @qfTj<7GLWzq+M 2?6w=0[u<"*L~af$oSo-XQ9;u_&ET}Pgr8H*Pay3Bq'f)ۡX7НD#0 ےS}77NmViexLiƉi~T45]AЖ˖uoӗaKkVlG6m |A!]ɵcˢH"nC2̮ yәJ8+7[qp[y\Pܒ# Wo햖ԏ9(]mA?uà כʬ3 7n4DMʡݏSyu?%CRqN~Y%6\_VJbp͍me qY]C; ~uvD^HvW>4-_az^׻cMEC.Vou|+gɶKc&>ĥ{ ɅwIBap%1-cBV9tiVg? ؋MAՌ|P?v[Z"x+..;K >yނ\]bjgjh.l[.[h_ 7q"x @QD wJgtա;:BAAE,jg*lUȫdMKn&LGBl}n:6w)׌|?4[nȜНյ#&GZֈ OqiTŒv9{Wo=q E?~HS^D@WRu"?azӭS6O0'x٫-$nfÇrw'>H"_ۦ/-OB\V#1,~ŲiW>B^%a7y]5m^qZ 9,?[^hB2u+-S3ݰ>'teZpD;{*UQ~S4lQ9|(x qY]1:𓝃=b=y ̀$nAFT/8&S- <{ G﹘h xJaχ趒|u OT?v[Z"x߾Sc`HKn]h[VKQ'hfIqae+Tk#g+sBwq"a"\-*7jV7kJ;2"T=|jt)'txwߞG$~`u<nx/Bِbu:wZ,W?aK2?Z3J/ck[&Gql#i 3.P,BE49A..A& `Smw:tz&dT }0%|I'فEi ps&7n46q!VLCKhkeY nKwM懈WaUS|\{w Y,3pڡo}m̕ a3B `w#߽@!$#c"\@ǥy8 I'bV0Z pF Ç vAxgXD[ a9'𴥴%r6GHa<]k9kwn(gKF:3E%HS3tD<NBQ,c>/- Oci1YF' rEy(#voZL°Bv@u1`F3)kr,K `TBjb1GEV qѤ@h.}'=6@-i9hQE_IzMWL͆[ft 6Ax ɋ_,K7XWHŦmVl6zYL_|R(*4,I"E݊ p[n6V|%Gf-*2}[hYupV#t~tUfpᛂ-Sɬ|ڙ # jFㅫbw#|omj p]n]3d\Z0{ F%@K{G=V0&kXͫb^X6ݥaOMWQW(ad>ӇIsA8] &55!7#~Uc+w 42eW@VqY#bw㒩NGz}%='Lfɬ6F?;%KF24yW@]Z60^%W^yp"NqbɎzqPyG1' >4<ebpEb-ks2Eo>aijY3k{NX > i=}1EEsi:+hq"J̈́J'3[_@mÿݣX4 Z&R#(?.JheѾXrPkT0ېGgP6٭m2+ˣ_ψ(js_17-Nt7[n8TR;m`Fn@)$V900@ZvM<_I:WvHٱ;'>t}G+I}(f,l8ҩB6 gfhJfC}W`I>DGl:Lf\+h6} * "(h}O d Rci!;KZzY,Ȉzy|q^=hT2OoRu\Dx*@Ɉ4? Qx8"~wci< 3y,7ڇPj|͎xG /l|SB%sзPZ'sƠT}WR#Cj5N ,g]n v_~$8؏?0binhXISu<%&a]~^C$D:@Vwk Ò:|C([äcN968F`[Pbc"Nz4J'm: @+h  h/&ͥi'wA,dVH8\7`U֡sJFcP*{K"~lHcwEb4죒yK>Ӥ'4SxLGeuQ-c0kO?EGЇ68 _8hsSˢ8:F`!Pdma xM?m~ BZQjՙ~$ɅMogj KhUx*JEI)NAq'6?2(m(!"[_Ris^ieQ[;F.6XE'Uu&m~[^аobΡgJgچbkMU {T}V6Xj(1q7alA> P]7U {fk{'Z5k/1>\а%=.!鷱b tE]Cqis^tUCnCz O+__Nӗ TiYۡP;=D|/a^y䰴fU^3~ME?>%I)h79׊<9ƁڇU {p}bcb^8iyGA>wqbBIM̘WI*;>-_ {߻*:>훸A.o?PO=6 5 ~[G_n|K]'+-M;dglkp, :. #j +lzAHnjLxulo>1*[I]˯>x ߶q !1wqbAþi96g8,Vw}9%o_FɎa֒ ) /YC6~tꮯzƱ**:>U8<5I}! -59>r~P; Lem+_'4/̎ez/%&ݥ-a 8ѯt<=54ޠ㴟KfxQe~}6IqUҶOqocw"bnh$Ċ8U|\eDmnYqk2 ަRxQ'\ oAK_1/lUQٵL]n|EwOqҶzݘOuk;>훼hKsƭJ?u;_m@[[}LAt!El 򼩤t bcvGWƿ>/o?L"x tHnS#k::tL͵4$f5K$3_Q7%<}ESXgb+`R6M 3y7甃>wD{$к"V%sIKXDְw >!ʎ#6`@"nJ'+m\iy8ޠWOd0{fׁ[Lz`q$+)l0)$L0F8~kz%IJZΰZJfc"S_T2GWXU$)$LQ[.ӻ$ʕC&yiFӂ-8ZFONģyhrgQ gfX 2[:L>G 1s w9\oTǜމvOT SΘ$];+J=)d,GLJb\0}>Gjpd''nONdH$"x66Q43-a+'I$@ %a&G&IΊ"A8'-ǴAQyC3!^ hh&H \Db2hb ,  Z%fF>3#I$Pǩ̔]}hfD&b epK|$ $]KXFu @ PԄq#`<AFy\gX&>f&D? A8mhE%(aDG3"Np'?I*1#W~L~L}G0-"c?H4G*_s0ڒ,j /caA1=2)/% #-H@T ,@ <ɠb#A_q!{PCE!7pD &I }=0T El[@p ɬ+&.۶o;MoyTԾ`e.p,.Ҿ{"kĘgtR\{ ly{ Y|?PL,mo0|H#l;w劁 lF#VbpklWD+L[}uhTQTNS񤢲]aA%"X(D" ͼL: l{<30XLmgDmn/*~϶o(b>#}WoyxDh3Uu=V7̄齀dq,[QsN~<`"1 ƶӳmE-vC" @tA9^|p38enG5rZށKMQL9yoc)C(*{=v7[/,Ãv%<sx{UeꚿTT+?`v7&7&&5;z Lsw:BnX h43oXnV`MMyukOf.{Pn/ڃm]]&'S_>f&92O7g=OAK6]TP(]kft '-x'U`XJ*^O@Mttw~B`Eeh4!H|lZӕ}lAO$ A^lipr&^ZZ~\gMRʶ:'V$ZS7qx &֯#!*tqw̱XMoc°rZM5 +v an h~i96ơ>ɵ'e.-wDlf2ČlkHhۿLU^ä/\WztK{/m]?&%/~NlJb%m[Yba$%y+ ^TkJڌn?!ٖ;zb6|$lEAv&1Ѷ[T[6׃zXO[׹Ot4]Q2-F'2p$5}q?jO)$bWvH:mlj)#}7:\S'$&l?;Cθ搾PuYyoZ6{EQٮkh-]wafj<9ɶ@RTK*k{ blj?{sLSmgK– A8lYr`Ѝ5щcvwZו*2!!*}00\p=Em'j~~}AmçӲ~9}B$"cW-?`U,T}d[U>+RS^E?m?v,c7c5%{|Wض%.TF@_ 78 ./_d J^ŀ0c,*59݈.yOoX\V}ޚ@{*i8)4druI(*%W -:ȷ8@ ]Tݵ/а} gBb̰=mW+5 g:bfG/]?&%盃0^fs_WkdRBᦥ:V}XOq2Tj&1>5U:C\R`P"Ln &5%Ş<5:Bt/WW9ZLOA$3TX,Ȱb쟰~7%?]gYZ\췦ew0ȈC7sEeEȄsJJ޲벌hfmgҦoS]}7}" )rwKu(zrHKOscuYyOv[lrY{hɔ-,Gq=hҔTiFOό]`OT0>-u/c4ςhg`Pj&2$,N7`޲7RS(+{M%@7o%={:HV8qBP(.\/#m~~D='H"K?+Yp]]ZNԓ Ģ誺$`"*G<=3d]]=\%qa5}17ߟ~0,/6|%4d8+<A PW&ǽ0)mt~tt|d2D뛾R81u-okhD(e0$d2{ywembQ$YGwn?+2hV7gW>g  <=fG*\-ǩ4>]3mRieAjT_XH8Vpj@LKJYj;p+irڊ:Mȭmv/kb2*K )oV\0Od+ 31\rKy7TP:H[]?v663ބJ/m 3 6Y˻Vw!L@mA&ϓB㡙 :Ή=gzPYEwrӾ ;_m9JcCeD\S6Wl8f.?A7zbӀu=M?G?p.Iީx%O U !؞ uu%g'G+.N[,29TV=> Em}15Rte+?ީ7/;-"QÕ~sI ^k0CClﺠ'Q]/em_K ۣSamcqt}%*c ^=N1ۏ7ohb[ [(4"liD-_Zj]4頸{HȴeTH'!JyגBFf\_r0(b=~яuniceB(ۮk_K>˰eTpջ+Q~X,H+pM(CkP1epp!*ɶ,zF:1=ZT5z`مmQ |n-GO]v_Fqvv7tS~~U[JߟH]<6)J*M&u2dK}̌5Ʈ5VqJ5vbTDmW9L?P_`%jdY7 jIy^7_]F%-ۡV:G.y{#(.p ͯ*kRrc7%.͠[@y61RM^&N ͯ:HNyͬ/H&H=6Yzit!A/f t:ToXTKC:_̺ǃ 鷾plҪL„Co~6:\YN-(aYw4[Fgk-XsƲMmVP/[*cey;ȻV;W}zԨg0G{=Aja{˩ ay.Afz,mr#<3RziOwp wfʖH+pn;w9UWKf&[bϴ}+=xcCCXJ^Y+ `E^.a7V{`| D5%oksi7Nn=6WaX{p_!v U3u7:ľo譕*C3Vm?p ~; Jb"ӹ]6?(mzs҉KyF`7 Mx-|پ[߅wT$ɥɦbO\;׎UqV۶m;s .rrr֮]M&?|^^n<5:K!;ج- vla}o}O&m/-OlEpe |-#Hy˾ߙۮ\$4ćZ$D!ݗ? 0z#!6eKXYvܾ1$/EDG|ƚ#WZj9LG_/#SDit{mtD#V>)7VP(:ڂ K<GM&}y.2j- +v׀vKپRIwɌR'r(ZUbBh[q77UvṙKq1qDo:ػx8{vL͕wm%Ngia/rV[@t6z&a@HUyk!Ij Byk48qC5Pܸ-?t|y鷾'vWnYiiͶ-7o~饗xۧ޽{\`X#Hn%`sZHýLVg1d/(6e gk߄&g_0/d#m[OyY:%`S)?Yüpyd; %m޼900000p޽οƻ ؽ{r!Xs?ÏL{#$܉\Ogw3lXC,L Pt \{A8lVUt[կƮ%ms,_}8<s CFBgu*ۢb.jvmUC-[#Fv~5H5;"?5Pe) jyo"^S&zZ̦,#⠦V>-q ʶ[P6-Av~)LZ4ּoflHec0xu{i#vpޱcB15BffFAdQDZƞ!vl!8!D!] /MAnlXLf&4IζɨW fZ742-J[ &%E:KW5)V=D[rfO`Fݲm7vݏ!Id}^5KZ>v)kG.MMOTeXtH"u%pj8)mc]`m*i!P2gSXBN5 JY`o3Cuhu42-?b^Mz#2͜+*L @>\B?dF/p¨, }UguI˴k?';dD"3mNpUg^IXGq|X򇳣͏ݕ'cx78=5e[+8\` Wiij$QqwسX~]}L8.s;=oβ/8߶S9.19,za2iYp۟f;:.0֋_aO[H\oO55*G\vLpfq*OU?^5‘qk.07і|A3{twwQ7u}$xOΡ/7tgw;֐PݨrB~}E9;l H1HC6~=vE37]@(r=?o9QpCwlk µ{uz{(LA&TwHn+:=P%~L|eܝ{j͹0 ן89m+uVwOhCK鮤;W꾉=RthbK>Xvl#d`do`>kz!]{x@!IXj_:Kc4j<{ޯuL7U> _ߓfu+Tjxֳ8څD*+Gʧ)g?H 4y⛡/%ޱc Z7#oE~q &4{S>͌6(LAοp؛v 6 ޾Dkd?1u~q!+ L`e=>M# ;t9ZoLM7ْecco{Ew\>"Nd }ukp=Yeό4L\j^䗄ܾN5X>#?^ oGdK'XGUs#$%{óɌQ:Ps/Fxa'nlGjoܺZ 6:ա'CgKmS]]yƬ(to嵳oxFrCNP⤍5vwd=5߻G万.rVଦGЯ۹^COW4{$ȞGi-46%$0Ap>OivvvݺuO>$77t9>-\"V+'Е (tN-]~vbJ6oa@ءq\:KY;"t`pb4,UJ"ZOw[ Ho?$EθxOWD*s 'N/ 7PwĈ uC;} ;w'Y1R8|tw~͆ 1\ bנxώ4il;BS=htLw<K5J)ەW=C䅶$0': mrLZqfp$۠Q SX쑄fi%8w9`s!Vdg†%8u A{;}ҾYBeG"F4cN77) w  Im6Us-f3Cg/nra5!`c@GXߝB÷v~z?Ey<•$HeAD砙'\"W7:HZ_O|bT a|x+TAhpHhfPXB&pǓ ї{$ptF &pwfta\zcb,C2!~g|3E#< '?x_wnz@V hID'?6; CD*ӹ{n <G ݃J G bx? O@8|w`nD`k 4;( lB8|oaK=8boL_hɀU>XK1=@PMϠ%}3C(,cIkO$s< ,@-'Q6Hn{ ?tHGj??/̍Sr͙lw%ʖ$5pIUK_m6ZμV'x2kE#տ B*KҶu~Gvv<݃Oƒ5@=3yP;~~ԟ|3:eGj'1fNlaro1)mKy̼]"-7Bo%q# j9~oX@=LO6^YgpPXX3;^wY ]c?_ǽ\YgU[OCkqx867Vw;s2GJ9[wr+3T5=ma7/v -qchp/e?<*ϵWR R:3?~kCf֕SrBdpw\m) ߏ_$hIYOM݉-L?ZxN֒5C8\}{~m[n{§~~PR݉7݂_Py!wm8d6h,P~|=\bs&oy.%ty}zf+lpD0V#lԺjmd&in"q{v sLJ4X78Tpl;S̰#>l ݽ_Ef/0F@# \nHc=d]U~zrZOӡ뷏Jh,1⾽]g? [x|@󃒦[Jr`ʬ55N1]ͫp$~r'&یbiU5Vw;%1&E߶%!@PMFۦ';7Prfԃo~ ~nuNyddXΞ=sA8Hgee:u &# T[I%B{ &À} no/*-9Tcɐ[H#l9Hԟڶ8@m{@3Ty&|ũZnr"p]đYu'ף-vK_щl.lMenS3;Qgp{ څ;lhOvyd]e66Vw}W?BσRNםrO\;U%rVDzkQ Wڝ4g12g(n;E*D#4~Onv{~|phe1gG[yY+Apj;]}G%۸@Ho#PmI mg ờXLQxF݉-sMhf/]jg `CPSjHW鶠;ua}_ Fkp?:/L!̅[yqd pW֦_ޞh,@np)'(!r7=}kin'Bq(vxw!|7Xz:lN"sT_!7n2zv4tvy ]mwc:aW$Jw;R>j.x-#gW,9^>G^-s1b\躓[~mtUdDlk.12]O7_Hk׮ݾ}$@ G'Qm~pk+7V[đفSN,&S÷; vĽ{yV@o.L<>av0\yE+D|V>䕾}-Eby.8$ٯy6X0{-flYiĬ g`%˩|_k!9gSm%?.t慎2Aʩ>8ĆeOpe>|а?n0~ |4;P}přނn=2su'3o{n)tg)PC1݃OE3Uu'^qIiҩNmh8H惵!iwe9>3!u'ȇ[9+wlw` hب߲XL`rVoTɭ){ʼw| 7o<2^o'~'e!uN|9tM 8Uȳj4ʓOa_g׾*;r g~s[U d {eGA=R gN]Wm1?ur0쎭K0LH: L։|טg؞pG LyaKJ ϣNG)b SV* _O5e|O8ՙ9Y#H^wkeTM2>Kjk1qkm}5kGjκg x: $`>Gs sROK5[ ǭ{;?p&ds!0:2wO]GHGwtǛ$~,gBƂ] bav4PMaoM0s #w^SgAzj:lnfH|53&GrxA!g,F=#Y[Lav+ush)^KfpMF켟A9 B jZ>lÎ+?('z{.+fMz5֨' B7h8rctyAR%'2o62M ÓƑ8sHgavžN?I;`Yq\O{~X&=3!ufZ :Lzf:9L]kL 7O\8 ~r6* $,{ſhD+ SyUuVZ/籁tA8߅ΥQ"L~4Ԣb;-C⫑k =厱s?ec/(LN2K/Q;XLz-ѝzsHBMubA>3V{;kHe ȹ?sF gϞK`x衇ZZZ111'N馛H$j'Z-=0@@cLK_Y570-{C{-&N>%3gD+! {naUH2(<14F!.4m~{nBēHC+$sӨ& ѨQYF'2O+=Ss i =tO? CI~T:$29)L +De f[\wӃ z @VȏLC^!%B89}Z7" "/v@vfL7?M)OIG^Gl뚹}A7?-[a~d)4!E_@3[Q9?ZzƠUYvlk~~Zhl#r9cPΪ b&!$P39S̈P[xY˥v?t@9 6Lt$vd+e¸?ݷmVKXjWYA`V ?"G2U;;aP c&+D5֫O b3Ղ2xlWKQgyo#%28E Ztq[nP_Zf6h1_8LEnNZĹ{_A#Jʙm)u|[~M0 ([]3ف1C9lb%<tAdP c +;s$G $Helx ͠ ~59_A'ECGrOa2bHX<A5?S.w>>x~kZAm x<#b+ql77<ѨUX<'y/e琶,&CE)e tbp@v~;1\Gb5[?Ymr,74Ϊ5(孟y%m$`Ҩۄ1YT;ǯ a1_]~x[o)4N6@rk1ϛ^<)22Gk+FOw?S`|OcᗽxllHX,m_&J\%߿g1i?hn+O\-䉽oI{b|Of+~"-Z(Cf}A1}rdͥʑv~KS2Q{S?)I%8e{Y f+%m*|xGW߁mxCd*w*/ q s`{ᗹI bCGwBBSt'I-mom) d}[Y)yW] X")n9|Ymh!ʠ풌[~or1iq5re`r߻UYpu_meΌ~Xh_Xˑ-! Bo4^xC.0nxc$Uc-G]eC~ cygmK8ߞ,}: P~*IG<ݏܖOζUłymoWt|fk>Fb71Z<ӈ_cgy . aBx=␶ybn~&Hzם|2Y;v&7mEڋiGZlezXsn=U3=M]ޞq8>k~w89@.w5x#9V~h+A`)l|x= {U-_!6אel[U˧[ũD&W\acik]HGß?[/Ưh䝵}?f>bn? ;0X/u#?~8YY i zr_v0jc7.c&]OrB h.,,Op8k[ -_%mzƲ@aB,G =Q= I-<=牀J2;(茰ޝ0xz;ާm`0}B/+9x${EٖϷKoMdV={K߰|z;*/M9DZaϽ 2[s79uz;U))x;&AV-Zj.20N=M*REqק}H9uk>c SqTAe'1UNbI,$~=VhԐ^]Sm>B uw 2)6h)̡m4zזHt$y7Xş2CO?cc8 }4꾽8  L&7n#p0l]"@I%q4OAڎvXG'QV2Cxqp6{ޕV <1ʢ ۜE=2 .f^t4wM.%5ˮJ49/f2KK?2&gٓ1s0Ĝ 6K|0jV@Sf3WcT GyqfmŁSwV/=w8u]6nhe.2o-H#S@8]zmDy7Mf!5Jy Kf]zGA8m]wa9C <؎ϟ.wa{m"4є-7%"p6irr5 kkgIu K}O5)&/v]_@D?^tRaS.vw.+MP.\QvE52E%M[ ٵQU_3]xGE ܄?r<78W g($~C $Lh_&Ȕ;ۛjmwFV_6;K 2ٙGMeZ:ZyitU1D&;h J#Й6e*z\@Pw2Q(pdJ'  ?4V)D♶X٩$^o,^ͻxHob>]$D`2z}h2n]0Mt˕0l[:E &+\\?e{~zxb6x0ۡsiO!0 tr/O@4f|yT.m3pʴ@α Ac&·GoEmxjbɛUG?Oђ57vϥpM1==C 'S%d`MG^8@ ujIJl.̒4/2T5_;N28w.*a$[Z8' 6P`*߂;|=2 [jĎ1@ u"#dɆڗ3#v<ʰ;G "X8YZ[eԓ@)'`Qvrv^{EBe.W~xZ޽V>#7}7_)o(!7E6"2Y٧Hd"oδ r((+9'Ű쮴=6QJ~@bG@drBDH -{cվ78xRƬ(_<:@.v";#S EvK [rL][ȊKcg+# V-w۷!LL tcWa " "r+d  >SR]W&a쀈 OϏlDdB82"=LNdUN׈L ܘf/ A@P)'5n=Dm6g_0Qw4_TT$ GVDKJϹ'Mn&PhYЬEU UҶ 2=XC\C5;FB gʎ]:p"Mwjڎ8J-9vrGt1RS{|QT"/z~!y+ &"-{==`]D6'+[.i{µ )Hވk].[##܃t fQ(YQjQ`6g{4夠ew/?japPυ1М2qZnF"Wy1zgl 9 Y^p~h/r?x2I2mYGXC5%*YK '=\^-F3MC"]ZK2zmzMFە_ۿSwED,C\ ZE쾃&̫|zIµCrI8dvCf_: |YvYkU _ߙ-Xp.;eI䖂7={9dMƟHlNH]ѰwKzݣ/G5d\=VSnh(7aכ@g:zzGvInwb>GU7euжŗغM9 m-ݶgɕf 74fѭXac+\oLưɛ@p#!- @RY֒;t4ϩC"=M12 hѭkX_9!C7q~Α@ڤw3EmG:CE?9C\l!%qg=R>:İM3(|L!˥mFfS,;gvU/l8zœ2QvgIyIٝK:꿿6ї@g_:#[\C-c3%WO medvע:yVOǖ\A#:?w0V#']:B33{;غT3+f/ՓҺ*ś Ԟv3O2l݆/_XmEHkRvdho/z/Jf; &4K;U'E 827-XPG{J+J&8G5\Nai_ryF*Ծy̰w*ݞ e{7XƖŝoˠX&/,|9/gr1UPZZ\`;U:ϰސ3;37[uUݻg˳t<{UʧwZ mtt-"ȫzytfVUvE+|G0&P,k'%6TjpMr+w3u :Qwacڽ*td7k'j̭hLdܓ23E4e(' QOnѐ G bOLu+Oѭl4-\C!qt-s)+na˛ډ;"(IdƊ7J^Z@Mz ^C2uB*ߜo;|lɍY49o‹Zm}u<٫*ݮx_ oBM,vV[m<'u2޻Va H6tQB}A܌/` 3@89`&97nM?vFvvVA +KGX97`T'lVCo%j 1voG ,Qڄd$LI*h:1R9;n#*$3RJcT\܌QZ<3.3^ߗ:k[s(Tqt@sN:ݦFሜ YK U^[?CUM/CbrsAp8 ZX-cڤ4 .cgDU)Bc!գF\Q A@@۱C$"Й cgT?G3TbqD]XkY1iB'BH-S8EGA[T1qr[ݎtq?vFv6V?'9ujpzNcpL:ƎҚ*uic->vCGaZrvChվ}J3SˌěB֎ ckaI:thr]T?Sܬ>c21L'jub _("{)xoΨxgG"ᵨ!Qx`L($*YD{‘ȴn=a:[O 25G#@9D @"w {4t6$WMB8FZ-sKeD(AAǍWW&&dCD { H=(42^J7r[bǑ)820ޭ'S~{AhNFGA$}C4 "TM]<#QW ;v G2:WmBj;:uFF#ZxVP브hL-sKAD.Og@x<ͮF0/5; h6vhd<П:MNp8 &@墭@e21QhL(hi;:=`p-l uhz(L͎:] ]M;z2A& (tY(/p;{Oh uLnp9N]>#` 7I]sVsFiiUE^6W/ W+ ؁Lx*={%7&>I(>A^]8ub򧖬1h=[ ĒqT-<款_zUGsW3FTGWE>Uߏ_ho̯,+n7'>jp\)2j+`D߿y0jI7{^pX6D(@χDmAJbwȆ<Z_\~'}B ۵5bS4laD0tϪbx%9+Lѳ$ki*ܹ `_z0 Z |ݾ/ DG[ s ,6~M'|jc^[#ss=YC?3X8,p5;?c4CckqSCG(*pYDwrj4\{Cx<$Fk6 ؾ ׹=ldG0uW6tE_?y04Κ]M 0 -kL֝8N% H<)vȝ}tW2pjvmc %|cծ2 &?ٜJ% N`;n[|OGWs.D1,Q\`qnڭdCdfe˝ITkkYCВ<{ah;yu%8bTUc/)0)GsSoyn0^vXƑð^=!!޻,q ߚx@ , mؒk?Lp{Wt_~Lm==])|po޴Y 0QZUbnj*TR ߔ"8YoG".vSvF~-Y{vޚ hbC,ãmN҂=dy0 W.2*F4gZ:{13mҚ*4Qoڬ]7]-:Z\`'k1nED .kF+@%[m5UXgګ)@˧z *rz3({-TݾXoJ!8A!;5RXz>1OZ&8 2l?Ͳ) T[/I@`_J1\ <0",U}v5Zi~wj9ܮrNS+6"t!p8yj;]y{zW޼\yS-2,%;>ͺ']@s rvzg :$b޺ME?8T(~u)],#gʵ,^.8Ux_YplS˰ KgoQs*ʰA>8:`ZrC{ٖ{"k㕱⯚nIWR<]e Byu'Lm)mIy2ZbOdkqA0 ^G..~_7Kv"x/uuٹ[GtӇG/X̝IF{"yn3deRx<$2<ֽ'?ٳyWdy04^  f`a q@GK]Z 68I~|`C T2c[Q{lܹ [382 k-9uhJ\Oz?hX3 BVHGs:]uGb7v:i4E?>9{%`: }iSZSbfnM=ۏlhkQqIA> gbcWݛbwtYMM?s 5N~h+&lSw}?͟QA貮;aձWsYy%k%aa8Y5wS.;v^v0o$2@K1/*"NIw雷Pc+ ;yZ/:"vSsy bfJ@~K=ͩ^@[~y?ɥR?RBӇʀ Oހa1[oU5D^?aRi2Np;#Tj^b2=`a럲daM]ǧ:ǡ)Z=ѵŽ\ ?O6a~қ=5L3o+-KEʄBCo^#5U[9Td5s;RhAd-F*eQmi:}bƛJ"(fmeشn$}iU%ghw45b6 )XXLcvۄA!+ Gc$Z֚M2/"rtVG#(diGqN6UxYc:-puqN:u d#c`  M%" z;h+/S-{Teni\"P b1VS3 YDP *v{3UgOkj5?G&f'(dvu;ʥRAbdhmZKGAB{] ;ufxMykYXjEWc{"U댙P!ӧ8,bQ,1g%%E6*kh@hmkiaPg7P.,b%@"cGk+N(83yz.v7%;|}o?Wn3tTtL+NIrymE@L&zX3ov{U5PID6 k=PH߾Ο#[M?2?1- StthQ'kf&u7\.4<~^S0N"|AgΌZEP06̤ B,a&Ud</%ΔE@ ނmRɅ;EIaJTt)/b8a@ޡL ;D4LÃVƸ{)G!p^e%ߺB67Rᖍ0Awh;ۥMoE+Vtt-'-@ԬecMӅg/A$i02G#'={r8WTh;6NF67SHڴG kB3&B: p&B+:~"^e ҙ21iUmX~ӻ \oB"DhH| Ӑ;(Rqmy!NJ~0@ѡ3u "khC9kb@uL,޾S!gOe:*uL,E`2FFxxE&!0QOMtLhjAzKQ:l62pnަXyUyIA!LatZAtgMoGÍk0BɮVC?PjxDVWgi=e"2tȚ޾7ۿֻGmư!p>I;ky9Fh̒KC3c ҟ['Ea-+OU^J:^'\J[<8m&ynF5t\f c|p'O鿺 Q_=^e4tB&e =w/Z^K4{`"OkEtLEE>i}tHLk݆Dּ|-+>/ 6ܶbiwd5|w,%'@Ө{GOqW.19x{h$/צ'W"Vn"r$wTKU0ly:7nD)ř=9T4%5pުuc55„G;T ۊ2&# 7xq/9ަ{8W>p$##pg\&͚0O+7 Wm"?bs陆[*N*3غIĎ"Oo)MD@I`D"ڋ3y!śm@63H p]ħ%A{ VDk%eQ9n>&ۊwU11:v6{|zz)atN5gea-;}!hi}z$S cA5c0>,mml\ϼe!&n^^{*@ZY K%zZD$^nOugÓg ^eh}fthp'h+*hl4ڢّ%a-3EoxmDC}^ZSIiiH N{J O_̛:2dm3m^ Lu%A &Q{jg/MFLU'Ȑi`.-ۨ=vxr`ǮSLF6>{QyT-$*](, @).y S] {tȐNp\^sNOjoU/؏h--&+ܺ]=۽ D$9{ѿI;&1]G()[3G:nj\*29TOxdz4li1iP΂aC`pvv]0uU>.zh$੿{l!eAF~( nGp>z O+BMԖ 3pcFtlwU8<\!4=fWj.^{kRS8E^r1إqх>Eqk.^xǖW9_bJbQ#aJ~YMm7ԄU+@mz$ȃh6~DB./U.O*9_`2h՛1<]6&ffnF`ス%Cb"4iz$BN`$PrDc^u.iw*Хt>qv}LC{%!jClm;Q2G,+pg͹5cC~4<}Q3oJ$XZYUM47ڥiIIDATQ.l0 SHGO4>{az4>̞:ףlL͕X@RPXeVF;ntbm3mP-*gȭ.vő̝ɥen `m3цuF;z(ܲMRPu],,Bbe hpsHj8 $*^XG`KCJ L#V.ՙ;C࿻rd9r?2g]TҒҒ= 2v^>ʏ3pNM=a /WI&iYy[+ww45Œ܊_1=I믺bI݄UK9 MD4Qq@ž~Ha?j8nkW(=RƋhۊGi}z#v! a-ܺM LRsj+FXM>n窿qu@.n-rCID*  L%]\gbK$:Xy2_G39WR,( :`P-Wks-᳒,|$$MwkMt.y0 iQxnd8;njINp.Rص+8na-h\,굂耝=ʢ<@G"T 7*O3ܶ=c2ZZ~G#_8|xf}6N*ܺ]ZV 8nsJv6<~OxTu23ț|\`?fxA;FE>2abǵFǺBkc]dW%'/( E” MGc~kjjˑoZ@24:p=oPt2 4iVP^m5VT5R:@G02uծp j.^55gO$CÚ紧N۰-*8:b*\PsUuSYaɜnP&h{YE'+EuRy_j0Bݕd[TqZ. 0E{i%ذY^ p ؁"C2 -nX09M q&8+6-EBdmP_ ,@FQqX-n ƨXb`9YB0n-F3WEd"hn DseV 0ՕnM4j2(JfdaKf{VxeaԦҍH|}?p4R?lhU'rSgɚYD5;Ey?3BEj AcCk_=MR΃0YR]xmkK mhz0.nY5{3'ؑ9ֹg>X}\$ *tW/W7(`\whXヾU wٗn}P9Թ10!_ 1o?S8Cgෑd&?@+l$= [wZ'Ϝ8l{FZ~=uWVm{Hm/ dK6E:D%kwg(o/0 SKTs|CC/˷,N0@6˪JVR3G}yv4 Uh-YS) *mXH ir +}=iNj_[v+d;TIpڴ]p|**6rR 7}jo[5؍p%)]>ІiM֬W7sCU6 HZ5XQm|]kl X',YdfĜ: Hj-hb^z}rg=LW}j9HPr< 딬Ԟ"pn~M4^wz]Z^[@kj]pt ,[5US⯩woڒF]Kw<4" 55RA>\4wУ4뒷Ku'd޶"^շVO+*_LAM: 'xOtFDm{duOQɚ:yJ7jzvHBx۵/J`ykZGULN!~{U+UVK O-I@=TqZҍ؍pw<]WdT/\^|wK?OCsn+17y"KcM%kwy($LgT}UN_f9t^x!Ts <,z+Tgt aŒFY[PGC`c$lmVy7Pўm!G:hEw~;iOvE8b }ջ$i$sB1A39\Umc`J:/b{k%w#g [4Ti7k9a}hRpIJ&C=se^wgM[cP(L!7=v5-D2~$5H,z-{*(ݬګUʌW.t{3ZƻO?]76eogV!-lmY6# 4a++}8昜oz\56/mpߒ\^xOU* a^:hYw&NWw\=}5 XO@r "Y]5c\za0a࿩<ꐂ!U4^vvLAү|۾֔LAMO_H&yկg[aJvTG/Y뎜kY՘R^W̢N_Z޵<.i뱬dC0Y5:g˄q۲ pT# qD_b`)vGI$sQ,SzZat"˱GҔtKC >Au.*P"JQ1fX[n>F6hiۨB%-2嗐-uLoz]v[lm^vz,-^cz>`̿@{8lCiA)Iݎ\ǯ鮛_uOaõzUT0Ջ,muf뱴:2Fd;Rl2D$)ڥbW[!If>5뱬DڹQ1jv,(cNpX\VUON\eXVsBށ18ֺ-;̞7Uxf{^;;;HL"э6.=y.$-;&+ґJ !]jmT H]KD&A$":@Mʪ\V {X|gQ o6Mi zzlUIN1 h kwY&5%t!-(dTG`&@EkjΫsW~{ :ËB 9)C!l[=55h8 }U%b8(y: 쪈SUhXmm*aChXс8cӳD.j)֢aC{/8CE0|iaIǟD}Y@4`&gAh5=^^huB$mSP(p:(v2piA o+RT K9F*Cq׫4T^s6cpּ2XE9n/L[b~v \=l^sq6}jScT_QXFhܺ$31;$n=hvds(E>60dž=[_l$fvQ%*؆{I%հ$EkVc~#(p% ,RxOג䖒-y~8E/iQ0O}b͙Ƿeh#$#@ḓ@b;8*y~K^|Q,)^3oT'ʂ/讜tQ-eѝ7%nRTm+*7=xQMIU [:lq{0F:譜cյ¸Muf &|menkV 0ާ7,^ګ-]ђB-[Bv.?j|5a55`?wOy 䅬&[:w4lqN6R)U]~A{TYǷorLGLZ\!V8hi{TPeyVX hJ_}l=U5'oo*pP ݚ Q$.^OwkͅhiLtMUUQW}~RѪ=:sG 5^G'V۶Q)LίL+TT[#>!z^ZXa-YYtj2gÛ/S)bC+6Ahqޤ9+'W' j ~ӿRscIn%ESs梢|e%AD6[k|@U^s -deXS@iJF~uW+v5*ظ.Ge{c~dj5O͵`a):G͉[Շbр7[J<a*"hKL-5٩`_d*0ٻrS5-Z-/" hy&gAg1bxwE^"hY0B-NXRݚqXOZC62d!gNDZx7QOp2PYau5@V]/XO*j{(F0!KƱ-]HTˇju}W[~ifl5PpqY*\.V q5=#7gNaMi £.'g.1ls!<7?E4@9{E@.vuَo~X XVcZ v=fgX]h.f`:taG"H58*Eq@ci @2s\ ;jwaGC$^M7o(Z~|ӝs$ՙtcNkϒ:^,o;MT(&zf&WQ(Lk^KjQdkVɰYGr7Ew4!^jijB!mo)SBup ^9V˔uDګZ_@(;+($ҲSv66')>YA8kXjw>\{֊#v-miͯ>u=+ @jWXTKܭgNrhΩ4\lD="+b{e\!i79^| G% 'a(&zc܆6, kY2Xðygefy,`MվģMvSaq̃6s"۶T[t勳KeZdA-\ar NKy|T|)`12`I6" _u\!4+^T8Yh6MDiM,[ڬ9Yt(4+qq,gA6yg^(:ɦ\=L,;^(ok}Ww?%(&:_ՕI O~O?P(HY=Tn(vѷ'}~m|jc dR=MMbqM)t+|̾_ ,D;V}Q֮$RtAes!%0{ OJ -埬a=f%qh^&7=<8d#ߢЛ-4.D63:x.B #E*\ۜ2%Ȣv6 LJh)saEO0T2Hۄb_ڐ:5lQJeB8ᾷ`_RjbOPe[휁%HVV`LD&%m>qD|xu\3n+5?]z(f6S'Dҥ(8&)$< _ d2)5#|1uO~6IGw$"W[5pt)SBM֌&| ^_Yt@9VrGA#*-}w:|&d>d}fڬvhzx!hA$n-mǎ!TLdNNᱩ6[5o[ sm3NN D&DKi05"u=Oa_nE'TRv?\gx)M? UgaʔPݻYOR -ώƖE0Җ}PZuvd-}{Lr?Zu {T]~]pT<*]hVäU 0ulQis#j%?ģ=qجZsm'0姟ʰ79kn}XefU_ㄻ`ﭒ(DŽ >9N}oSsb E-'erHG$].;H ir9TPenjvG?~&d95?eJK3EPX$yj[^ wKo? ,'LJO~yS7NK?ݾYN6)SC[W*K#]^}kD֑֙Bw۫1sA oNe |o醱KVǽ=^-OjHwK *܏ 0Ng e,9(SimhkKE륚V[~d=A1 В.H3ئ1$dO%g,D  <'|/kZ FF3>I鹛Dnym6@ύS}oht8y/G?4YPuW;o sxO5ca82uj8bmSלtǬ=q`"gisW Սh#|JkFTF~uN3㢐&ު/r O֜<Xz$Έ}k~`UX4Y63b}q.Ki['f$?כo嗅Һ~wd.?LҊat;^gtD3s~wH  T_Or|7Z-S= A=a_H2fUEq+6pStDW9u'#YgT@*g/Л锻LcRF3^cZjn:=erv:mR&o(隚+k_jʭb QMWc"Xrٚ _Xղ҇IJ>$CO˂+)S%qL[5VW=qu3H[!EG׏TGsj'ӻaߤ`2J"ַn٣1ZSr/: ML\捑d]q_6.9ǟOv@ۚ@FkiVu UF]5ХE!։t)fVm&hu(|NsQ=3G jJkv_ :#{T?lEA} "M\M't;tnݮ5$8L#eZf?MW`^Cr ׶^Ld4萷5J):5^fySol_N[4uKw`b\0DY;ԪZV$Ŷ)+oMMbJ)aKO0!Rz[{//@NQ{lh$ Mc{xG<O5с8Y܃ġzLE@?>⹇*_ p8"@#(L4gT6 bIcx`%H43tK=!t{aő 1 MX錧0zìoAsZm Z?Mtm%Sh"D&hڑ@'ct @5@tp:WKHdR43֎.7F58 hRoEj5QA8 hf<`f8qkD[1eCġwFǵx,VwMVkl6/.WƷc4ß@bQ1lG?#RMtp pXF]ؑAC[͎=O%Q؎D檦 pBOǻMi$L ׏SVԆð[C0ᩤ.- @5VkQ[ .^iGC?74**ԩSK,ٱc\GQR Ͽ/sԭ{% fa̰h^#3zo=3ˊ 1:lZ3nKY h0 H4"٭]guz?<ʫ(|%72~ȇp8{ޯ$*D+kI+(nVLKeI4̟׶SE*Kb?dW^L5Qh9sѶv+OȚo&h*ho_~L̈NҸoo[袉7c0ohE?̏հc7x2M,E!CPs1gB%jv|=IӶѫ|3p51o0eǯk.z~*whsO9&GbQ}'.G` if:B9( "b<1N,["1XFZ.P}ݫsQ0U_Lطqw=qʷs d\2 #ż/sO;[?VM<ڲcOJ.$5KT4Ӊ٩jV$r\h0:HL8L5d Rc(l%衜^n iSڭw8JH~.LJђ!݀Ґ cޏ{Zp.³vdiʩz=^ujIK:!:1mcntrYbmvӔJ#W!̈́ò,9rHT[%zaAzȃGկr^Dm4;4YZO%mg)r=ׄHHy5:j@ȍg|>mΩt @_W_*N`~qCloz?{=`sBwm>̋.N$ ƽTx&)ŷG6qWznƉtw[%?a kDuˋ9cSUߠ =F{*5 hM7;T&g쫍~7Ig_,Kټ#7VK ]0mƾؠGvpIQe6[`͸C jΈ j<[O"0Sv.~xLKOmT݈π]e$yq7KQ-њ̓ n :˪K}'EBK_>`0r9W\FZ(mܫM!Ktz{P,B'u<̓%_a~=*.,|Cs6g'% Y`*r\8rѵAΗg= }}Q (]r=y ,vQuCa_i -؇ђ1OדP)޷ cލ{dj/gؼr= .vENv4G'El->&Co6v$.I]3obGuќQR|n9mav놾r4ɣi8{ghgO7}AVi94lf̰Η[-GRV}jw+1N<ۖj?8  B =7CԴ7J1ȭ" 琳n/gE O.00V67%x7JX\\mMU.^sYow4:}䖖ϋb8ӎ6g>2iuyքK3*IT"J{Dяq?ޞWTd6/}wEBXQ IHTHvDIr\"7qO_s5nVeΪz[@ӥ93F>/.}z6GηӐUCU=i)msVJho7ZObE2vsEͻ,k;?{RWOM~4泠iNo~m50,A1L#`LG*l-kj.(A>6{{nsueExPBJ"ò񐤶E2f̺$ʪi\+Qۆ3|h_n}J Ί;[iRaK=G85F_\Pg2tt?\Pq(yK"|gn@KlLCD$BޡlQlB&'i!v6JDXKAEn4 ١N;z]X J+{s $J.cከ:lz bG~F5?+.j+z6J}jEsaQ#< vVζ!هwm dvQVN6Zs-X!?Rab lԱ 3uҫЊyә;RIU# n''̨[u{:(Jћ 뭧"Z&nhQbSڛDlvxH)*jȪ=A5tvVK˥8kX.&vRO0‹ׄ?JވXGyo42uZDQ^-Ǝ> v4/.j[l2.Z\~@x#z.{;{ʕiWx2 0‹i6Nv@_$'fB1yڌ.EkhK9[sЈ^^|qйac(SNֳPm*_eogV}+Z0ر?Rm %+GYW냣Gy~`s;c0WNoQU\m[ʛ-mqʼny[8&=gð2,n}.$GF"Tf/%F5x r28w(l @,M=v}}9n׾ki6,0Hōr'\SŶ$XX?ԫ#bf=[75#̩zg} w&]1s1WЁ7H%JH>9JЀa`bg ˡ6%wuOW40Ϯstqצ=TŔ(,yQ0KN]rwFl>نe w鱠W @Jݞ#_oMԵL<-nr씻[>Ypyh̄kGiguߣ 1vk.|TSC^]ʹyO\=$̕?BmXЈ7~,vsܮ2~6AN1)B_h$d?|~gзsο4#+)96[ۯGh[q\N>%kS`/aI=xz 4/FE~twZc*:j*Z ߔ۹&)LcЫR'O9 nΡAg7<%Bsy0~_@V gbX9_~qڣE A93/(*jH\?)ڥ׿_TBBBQ%<7N#μ77v-z[y7U+PSuq#˥|#OWͿr:O5$'B_~\V q-O>XM>86CЧo}N8d]w)炞+UdbИ`o /%|x9,iֽFx0wHbq^o 糢4q6;.e]N07Cv[ZY0k̺?WDs >^'Ӱc/5r${y3fxmRK k'+$d/f\1u߻=5|{ʼnyi;!]cH4œʡXg*?CuΏ5킄Nѽ齢rN ^35 Kv9Z @u8jAҒfAýiX;M,hX"&-o}-Ùv[¬!lgvML {geicK$&>ם hN>_>,+[ha<8FwZn'-z /7=O &{P!wQ[\ǒEd!ݯ2_iy+,H$76ўu.9aVl}fwK roڵw&\ͩ|$Y!JwXo ;'VKoc71J9#lۂo)~)UCO6Mc^{&ۊho4ݟ<s^1}9~.7q/Oױ,z+p>Cu=Ԅn=;E?F8l?ӍU_HݬV2KKn{̼7>&Lhu}pt%E\rs9+̻sМg\o̯_v U_5Q =v{2 !gR`#λr+V\jOx!$/bZ~zp>$@GF tgsӅ~HJ)Xcgti:kĻ=5aڷ#=.I0\Eq9)LRKo<ȾscjHv뭉_“&`@#''Ξey[Ļ9\v*lũciP'C|OsbӞQmRt^mym3fᩱ3bfۅY5C M洝ao<"hV잯rKgq{ư%+@gXLsq9x)mswKkS*;Y #ȑ1\b)AaCa$Eq}XVT>v#i]/Nf{)u"mqg\lgI[QR{P.̺|g^FF 1MgzNW;e1 v褗rn SN}8sjcȽWc~D9^/N>2>[u/VOMG*go{Ԍ}8ݐ884E*kIx@tMbnb+M1W0>KXqaJ]5"msv5TJXO 0gt;aKߖUKI~`*M`t՚U+wY{؄Mdכmn 4 %DDMR949' Wi`r|녙ϖh"?/4u10k5꣫ {}y5>1]6cO Z.0o3#?(x̺g1V?nY Ji3&Μ[֤K$ jˣb+.7Z6N !9/ZDJW:Ūyo'D7ʭ[llllllBCCC(eP$թG98XN?-66p0\i 0t͟R-xj?"?u \װ] .4c4? @װ8NA7W. %vb͊Htr(d&rD]=S;$G_$: .;a?Pfjm.Q~f?RK2x A]uEY8Nʥu΀m~ejjOk2G{_R[J"7tqUr|SuM̄Ek^O}>85!zv#FpڲRu9_0t3ͱW|)}ZٻroBW #8rg MJ0PgǎsL#hYGϷ+MVEP≯W WG2 2ﱕa%Jx"QX޲X\RitF{S'-C9;sÒNgua/|hއ0/nӷy^UH;ꋛW<$$?V}> Ov}`/f 05imƓiĻ^S 2';~d8 $P?\1wګ#/U_ymapD'Y:?>A+~>nspeL;>??ao]`Z<4fI-ʟKw|XygE#y81BK[P=Ja|QxuIQ?$BICiˢ6IϧӤa[pؾ.L:9ҧZ 5َDa uGlwWfC@A_xnBm AW&?!) /Lώ}u^"Ir kgxR[s{P:>|04^joNfXSGIX.@/0Lm(nUxU񣦹N2p-{7%+–,amEbV(2M5[v'ӈ'U.twGSMJK8jW<+/0s6BC"Juf,4 X']0\;+clTW uς| K ,ь j]&]HY&^}.ΈA Hc٨f66SZyH ˘DOߟ&Q ZGWߨgֳc*oܤT E*lx QY2z)'Lmn!i)<3^sEUҏKb`FQ#*Tu9ܰihЃ mzʗJp]=${||Y׊-TEӂp;螝'a2D2AwiOY9BAMW% qPVߥ/L{XzY+G)Y}{KDZ"Ӊ =lTD8.<ﺰ ;$R3?<NRޖ.z6 @ ztF+kO)mW5hkqU#sHznܽUv:ԄWehfCh3%>χ5xN̤$QpG%iZSYqwU cy}t!,R)qiO3w]B3oN&-jG0+h垯׽r;?էZ)׳㖫q뇩m m]<;M3Sxaj§i;~:vg+ NksM\ywYݣcksGZ0vZ$03->k=261{y4k}d*,7w$9iI=X_/dv;ڧόNn}Q´@{47 Ӑuz]:{oVω'$$][(ziiK)uwwWZ.ԍ(b=$?빯s|Ξ=> rץCv{ Nu̧|#J!'5-2$e%X# g:鯆OCƟh~(}ȍNj?]QWxObi >Ґ=,7dqHe[<ϭ)o>1Bm> θ9*ːlbfS1sf/BrӨc4,q!he3g~Zq♥X}h]A~432t^`׃R<&/8OsU1R.V\qqm;K>s^T7R| -))E<( f.i;=B&\:ˍW(r {>ͶhGQMWG=P".XϙšyϬ7r.=}˙j q+'\}'U!-g ÝFtQ[inNw7^)tg#~wB$\2aurWcnuֱ{xOcSn->v m }mC j> ~ZT,fbB v|}?~1RO?)8 L$[ՙ~ ~RetKO'LlDڬ4-T{nmjɯzL"{[k~y' !.oW(fQB9 =}\M4_\WHK7]c oi@Tlݹ*0 DV]{au~=($L>I~UoQ qx&DKv n"ljCWʢ& f3W:EJt }4Nq$koP !# Sߗ5xX`PLSeYF]IO1! cg g]EeC8H*KS*}G5sőTѡk`X_XXFɨ*X`w20º$IS;: ILY +JIzOMBTF!c/m-Kzsv$P}ϹNvqqDIer2j5TYϹNQG -Q_ӧRdZ0LČ01ӱdi_Nkq`Cegl9R`*?Ÿ|݉l ?ﭦ{OGv'ghl>}wR `{VG.ME =cSKPّ57EkH"#k1)$tت?!vxNTB´.Ew%3t ^ç[t,y$IgQILcW5X1bYTR[bhldpzᅍUTEކTYy1pj:l*Q'tEwBS. c#4Z.837~ 3)rQ\!T_hNcPcRj}ҳRO7Hqm>}]ᐸkny 5(bgY.1wg|o^ӈ dԯv>Jypl~;ZL9`{hկzr]@ځanvA7qa/ZF+x-yvdmW=5(jӷ>JUx-Ԕv<p5b⮫g,ʦG=_/ͦi=ٝk3c}_3=6K׻>V,I ОGxyQܧYFnj](?4u~}+3o 0 Kc_.Mq9ɛ/dXvV6JP:K"IyfĤoY*j +m_b>\qnf !3b `OK6Z[gNgqiS ʚdGR{|7}EUJnߗ47c}Eo^qYh7V|[ی+f 1\8dOj/N1뒢DIj aO&.|*5ԾBϋT6 xO7w{k'*Jk@k^vZӶHM_ڮuzt+;a_;𣹗Y5B=ɤVGF86!DTt(xWj#G~[ ѿ?>T7t#Ήyz rsbΆr5BQ=Z:._n|-lt \-i68?Otmi5ֿ&2Өy_.0-֗u~cʙIJ <׷GǑzlklCܓ}h}DNM]MqӲԔOg<#rβ;[>¡u򞏌\ogѱ_O>׫9)<,ԣc8h&sT:<m~CEdsλG|IxVt  w7$^6d z55pZu8$ٓ뻟dlV#7Zv@%k#L\k_tڃN^䖻gJ)}u>1ۣ)(3G* ?[|޶5&dv~xJ/؎)'B9muqZz*^wkχ} -쎧sbw<6zV!إԺ5ϼn{W_ּGO|Y''t>;<[6*9fG~}ow+J񉄏nFֱ;xYW;D$bb_q ^]EdcċcY\!coy99]遤cg삳~^[W",,^J}g -_yU{|1/*W 5KYF+m_D.. \d׵e 7Vu{Db x_:ζ/=\ )/}xWeq.IaX(HYa#\po[wx|+9)bazga׉#쓓 '86yA@F~{Zt nn?f=b\(W<5ϾkaA"'cח'\s]wy&gѦnJK@CwGX&ϻ`\V߷#YN= 蟦<<I!?;ݎ$&d$49rHw`ѽEJ*LCKL>"U˒D_Z2z٥$TxZIwGwHo0w"_k"q|˟<=㜻2㰌KH]ִK_V񼀙e&;ra吝|r"t}M7œfKEKPfƿ(uꯉy&4e= t)*}2-4W=<1ve׿ǃ#tӹ%~yT[%9{~ v$OH^m飬mJZ$]VX*E׮R0_^5;h''ƶ(7zYS`9?U 5w04U}s˧d֔UBW|\>%*sf o܄Z&r]wGX2'floi/!%H<x.iR)rIqtf<^Z(!lLb:3WQ@Qw,aVIZ~)S1He TJb^ZUA \dzgo6я{\VjdUwue綵tЉGZ|Vc%.@CG2loN9 J&*YG698Gem:J*H~&zAa|{Ie@A6{m77$'\,ӈ:ߔsзOթtvxs}y|uTAKs4Ն(7Xc/nT0~\|5L {}gzOF76]aY\ޔE T2yIf|pzEUXܕiB^-*i2`R~*s/oΦ3)bQ'o6 ɉ'OPov) Ȑyz(SCX8kƮ 2)I5T-P s'#gn*<9Й+8l i3=;HDPk,=UEb&*ya}eL6ΤwEAjJ Y[̵͓֠+Zz{kyɍ ȅmwJ)\ZK|cZ2LmMWYڠ-$'mrTFGL3jAY~ #0T+30 $-#Ӊ.wUT*PiIFn;"{Ђ{4յZ,Nn<8\5e׶缿YBgPKoi)2PiȰo^|i){ذaÆ ?(TW\aϚ֠/qk|//l#nC4 qyUgfFvܕOOk3J Zn X90ֱ[982Z4oZnYLkoⓊ;Low0[e5embfF/[rI.cc&m2 x;"-0qM͆ u6(AĪQyeYOv;A|S bƘkn_]7ܽ&7X__/h@s|RGkǶ;֡bNpeK خJBqo*C,.=jvdi=ᢺʶ7[//H8|\Nj7Ar2gVf1(3~٩k[왑n$F o#뾿S*+IۤCAz3Q%mneoYQ2.jjǧK{`G_լ&65òEL/BzxlVKfͰ3qn.A7wV~lw"Nq/&1{ҽ'87ZŹ%[y4[{^>OHGe6,jLɯc-b_@mE޹!_0;(āY߃k{Qڎޣ5>=8aUƻ6*p$뺋;b^himbkex@&$LZ"ק'fc}٢y[nYm)yAi~~yx`KŵEnn{d 39*|wu]" 1a@VBݶ1Iv]ޙEm}8j'$AaI,lZFX11 Z:@{̊ ?T=ƒ'W 2j+6VbT6Y]:x֋Kέ<0#umu#R !TKHC#Kg:}SO~us.Zxe+9/آ32upSOsnmh֭?*Ԕ4Y;0<7w圏sP^RYؼؗpak;kWT&|b+/rvξpY1IDAT+'|f*;ayk',:d0 i1uSyb QtCm^[3+3/Ndpys.[)QjYNIY'kX|zRNRl}PBLDn"=lWb;珢I.L\:nشnYqQ<:VǬ&hKn폰/j-[[r1s|RĹnƶd)qu+/xIb{ڮG6hbm"a/N,N;,ϼ5m@-28IrJ4 9 -kM}SR.n"ϓO,N {aK2?. ᛖ>gNm\ ʖSߜa~|qh{XvXIn4(3Ρ/v/[x9хVNIyx8F"rKQzҞ\*ZI]Xz!g8vlya<㑎Zwq 1؅{Yvf%@Y3Rߵtv%Q*YNjԓQf@|kνinolI^C(zIͷQtלW$;o8-Kj쪩O~Ϻg˯ﱽi[ ^1>/}nQuT@SWb\G>u ZEea~>&k=g uVQ{bh~`āuT⇛%7аg»%{u-nRdwhu3'|f\!W]sR u]ؗY{UX{bBPn`~݃VZ3kO|F AC!k 4C,~{/p6nު3Xu]%b(Lk*R;H6-NXލt7y4[ѱ=cg0Zt;0:΋?p4eaҖ?YC9>٢n>CӗiLo8cfwKbջ`cQyҶs?wzkojǙfU cW]ܘ7$yu4]T-هFbŦ,y_I >;hg8|k/#/[ *_VwJC,Y_3oׄwUkE{^'.3jT0NМߗdrR̊Esܢ'_qKO4Rqs/8Mer_1US%agśjm.:l:sҞ?L3X!1PŸZְ_uLz~Θ[7ˊlߞX|0Is +j5˳O8<ښ񉟪r?7^ b5"ݍP#ꮹ&lnMטy2 .OxcMLAi* !šY"Ns99Kf|A VAO6$䘴h|i3q~AUXm*vpdWw$acI hKz  ʾ;/q3ɡ|P [iq+fۆe#DZڥKJe$&Yg$kF8̖eͲ x$3[I# oC_›b,[!KOf)j4 -$m}@]c_)0vIRSLR}CWi)WΜA+Ԥ1Y u8]*4‘-Ҧ,8A+%,tH=Ͳ օs3µ$Z3Yu.hb"iۭ*E!ya:m>pti 2q&C *<2Eq>4POl"MQP?LyI.)p}X]!ww_U\F[ABOUُ~A|u͈E9m(k p)`%hxXum'tUv55PA/4iգZ(^^//}rprو,*x@'H>"ܧvQr0UoՃ[iy%xB{iLɅ"A{]9P"sR,uifawMj=UR2;V:Hǔi+C _6B naYn+3ž70v6xbۯ0uFkmYX@"+j_q=:Osq,tH3fȈ.;0P(g+pmyGڍy_X5 3[ET ynl|FxxbC Oċ[{ SrJ!>iں4R[q5;qMT /4EψC 4IZG{@ΏܰaJt{\ +A(0j*L<Ȥni>)xz̓n;gHJg ތ 9[kKKÖǺ-nbk@7b2KuCBť}VԑD!+1aEc~aO8qM͒ɖ[׀<̦v~?n'6"1OÆ#:sd\[寣RiTXNve~zZ{/?o _YuF&*=kMFLX9b7dpuujyfȺkAaLSHzvq7 w/"%|է*`sJ^*4I𨋓i-A#OOj v;'_fSG.)||ilD֩hr岑䬽ڎq,ɚq9TX_{F+0?ʁ*];1Aįhb,mU.@vfDs46EKTǴi=Iϊ lRk~&I7)mU 3xI+h>} !Jd[ȓL$}~̤ d!Ş kێ>0+&퐎qI쎒ECFS`iEC2(RxKCacᐬ:ΑE'\dUZ~NɶV!$˲fˈy_w v Ś87fUI&L9uEgw ;gzZ|wFt)]&IV+?.mbl<^ oyQ/k$wF:t3zޯ-ҦL5ro ߡqjɰ,E*(e#ο6a'c? 2M3KJCdk2?=ÔF'_ 2 |qdY^d8x\h42pғD`$ MԦfΪӯ&m;Y[tɸ磋Rf8c+GrvZwzhg6FPcrbdLo)⛶lֆ#؋WVrsyK7Fx ۞&aTtޅ{ٝ% 2]c—AI=qO>bA&I_"~ѐ7^gY*^OZ=ٵ!ISトmN6$X;OPƈ4s4\<-̎G?͆b#</ڪ.ITd[:Vf|ιlL*YyiA$4;wl{;c{WVE.n1jI[4{{d͒|ynH*Kǀfq_' %Y/Wɲ'^Gw_֛X}YU<4ihLNkrLa1.{m*P K1o"4I .ioiZEf~cԂmS4=7ls{AAI)bp۔+E;s d?&#m8kOMKk~\NXl{qOl!jC` ɶztݤk<8ߚ}tlT=L9dͧtWBlQv SO~40eD0?SSECܭze*2/Z7)myɟ`]*:h}K YcipHr{] bM\dC=V%{e1Ձ&I ]:Na6)J!VN̤1.VX ?԰g wYRQv+<8W1)ezѶ3G6!Vk=M<\Nٛd,%AE]w r$xbvqO)(Hy^Z4;WfGf?X&_bxJp۔+_UꢝsSVjvNA|DClo 6j+En`y%+xh]@bw07ǺW5qV--h"fISᆲʮE^R?uPZܡE"-Me~;ӌ;3e'0iL pç7֐oǭ(  zƌll ]@>co* +S<81yܬ6=&9d`w.+mo!ge{!)Ѹ`@D WuhhRr&4F#|})(Ax okUVJ u5sּuݙC{`cy}%ٌk`18k/d2̏(/o WfEXr}|Ncf)S\X/!ha[TWYJ#Ƞ %"]t[‡u~<ډEg sᨵEƐbԢCK|: F܅IKLl7֖Ɖ* vĢ}9ʊ55J[Me+'_$}GOrٻ–N*+[ e2X{HgJ3[ _*K!<.u hb2~D6_(7o-}I_ ylkmy'w"ۿjjj|P߈\3x$F{!k֍Pɝ2[3-ٓ52Xm' 9h$AF'=PW6` syM]I1*JCHLs 7! Gn &Є^9* êkP VVhK/}I(?B['&ו4KUF;D6h$B-"|YfR(dOԢPF Lxn=|5\C _sOQ79FG(rUDR?KE^=sI FMD($GX1tD[Lc d, (?U> 㦩SI 5wG7ocbAGգ1z@[qT l$#:'7wO6Y[L(Vɢ76:dԊ\SxL xLC`sȣKP B_{64iR?=kUެ'U}՞_?Z/^V~Ps.<3e(QiaBuԜg@ů/{1٤+߽h|A{h@ cuZr{OLzHo!}vJSP 39R2[[:o|Ռ֩ bF:0d[Q$TCw.]P–-^߽`! =3\ʘSg.9E:K맦WN2YHW'iRR}c!pƄ*zg.ږ*ǴzQ*sH-G̶w/?,|WS!Eﴛ|,*˃޽BxY{ҊsɗkMYz,皹e[W<Զ.ݔys<3 ڮÊ%.Gգ TRwC;$b Gk= ]94͓ibջ}nZp1 9;7eGGeПj,;w[ao9m<ɰNnfyلL}"/.A]"W!GohH̫&,\0}p(a#?7E[b2 ܊YeVWFѓoaw`$mh;b~|v~ \JpgY '[o!>FOm\ 33F5E\U1lp/Inj"9m>:( ꅓ:3i ork*L(pW[E57Yߞ6|U)|#Ku /xNEa9\ܧw_ZQWz#+"I9]iWNq_I0qoh]wC ςo%g«st^^ƹq!3p|]zV\|b]|V؁-US(=o4Y0i;/s 1aգ=Olݶbҫ5A:aai\4fmg7F7Ӽtl;sI .ωV- L>B@O&}yiE9WNA>ib]=l^2Ў$(|h@u;a'ھURqmGAIa{T5cJ.,/$\yH#\8gՆLX\3&`c; Sfs(aC}M8~Fbcӵq3yt6V.%<_:X̐X+ڳHɥnٿ[50]zbjt+ܼWm1"=m VPY5p'̑ ث(vTM$ ?#ڴW /问]ۑ{VAlOܘH,Hlګ~F4yЎ*v癨]k*O(pWs&kax%a~L7?]hx5Ko{X;y <P_~#1Gaҏ 3?uo:;WW8 ptmoguU^֙Sf <[$sd{q|lveϺ<Uw|I&qVǔPެг/;.G)C>'4J: >B? y%r| }eŒ+5M#+//!uoo60 Te̼tnt޿+fo\T9\,zqd#q2WNNƈ~%"t*k*!}|ܣ  (Nw`[e]:8)Bͮw\,xMo~Y}$`I6 d+K1Gok)PS|Lxئ՛ȣ-9>vE q ~;ˊaw˂~&vX1D )=[kW#^}D1-= Ȯy57/ʊ5K#?=NˠZOĽJ;%=3")ѡvlhx[LlI}Ĝ>,1hjN/)Zْad ydfGPvo~p觩MnV fSVzFΤ]Cmu~NʰCI6575htU5ӏXP"!BcS:y<'IH/x_s$77*m%灷eW~TFs,ҥk?n_[ُÅkWYг3Ȱ**HCÿ%Vn\9SdjAOKiSSv ZaxRtVOC\FWS4K\%BuJa>va[k2ڎ^ "!WAh"XR]%"W,MYdfSsѿ\5%=\lpx8OtL& z0%I^G48/L`4KV]dOZZ.J~k_8%ZfrvR;OspŸ2M˱M P,[7ik ,lSPX]u[m2T~IX9fT 20e+)/PW bŴhHʯ֝՝#-}⨊cj%eOB ϯFjaIH]^ߐi* gUVM@\ f+<, 9[ üFRϭJehY'U=\f!gYܫʹ@&sT;BgU^ZOZV.#|lMIlVaκa2gsWi׬$ 02MáMΐH:oᣰo^5fug˪?\oEb1ɨX-jeMG0wz՘l#L!T),EPmW,޶^ R EAxxa-}fHe@/fVVe<|41* -k#{jZe^V_b5Te{;;HD] Sye<. ԯmTb|%Ewo5="Ɇ $&.\SQژI Vbbi-62B+uCMiBr2 ͣŗnnAs6*4ugcgUUJ"<:e0#HߵVR)LujUTὦYqyvܹՈ/A~,ܰU l]W[8s GupOX6RSS{TW~mq9 J{z3<p`o/ECW27yNf#Aq,Kig!~q!alHSLSmkvn}AW2M mu" VVt[ڏmbL O]ʣW-9&ی-t|X'mmGbwX߁ַϲfٺ jӲ,.Z-;u,r\rpjXjgZЋYY)miŊ.ea #Qɕ߾k:aF8~G'cGUS'aʶ_܈J@wRuudHMZ[wG@Vf;v _Z8̜vNu5`~ ) ̚RX|LoO!\~ѕYyfF#Fsoi{0UDik54(uyӫ?J$_5M ]veMxmW,޳6懦Kckw~0zEw76T(h-^ݾuUߵ$jYMWIT*SccV,ĊϳA&pNhHI2/^QUkyq߱s* /}ʚ zbE\.vn0q+R=Qؿ<;OܸxpզmjR"ؠNEu+15:e~l41(>rZO?D~lWmʚj?Giz@䧖܎;юlUL32ۿjJ.TbMAd^uij?5]JQ-%WoͮfْyՑ ӂMs5,hp\^S"?Jֲ)IHr+fHHKfgۘo»s@ )S'TҦz* 6dleB\(M|mKӒ^}+r$' NlߡVr(an+Es!%C+_j׶Vr"4hfee:+jKsL%./,SMү\mC#loS+?m>d/6]]5OgVYN;+O٣! q4p#_|bd XQiά܂9 L^l30cruI5=+ Ou/پK)*nc,b%>nEiZ{';_[޷.oٱjb;ߣZ %02}~jnX;{*ُ#Wܾޘmnw #Cyq5n=uE\ }ɭ!ŦÆ pF-{$W,^8+Q~'NXK`N\|ze1[ӳE>)퐹ۓxluɚs0?tؙ>~!WiVF{jV[ ;/HHXLJl62^ ngk)񋆭-δ[={AmZuų{wi,! 3xzv־=ե8Z7~B_2q2,+YU+Wثۖm]]*~$hrbSLuB_`u?^%4bN?vjۧg|kZ.1sjq?5uWl?)?ie(E:vR-oپu$zxekiZ%7g W~?~bg)]%'Uoib*ߙZIm] C'N>y~J5˥$iI }Jy Cٖ( {w[vw)9u T~&kZ;3j6;>5-S+95[(m{;8Y4(`˾~nѶSL<T^ZƂE\x;{zF-` q"uU7dݾ' ʱЗ;_{HE4H=lWeGO;cZJc>%BEcIsg26RLU}*jzpI+nFH(QRҵ{x :Gb ~4xOS۰Iþ),H̘u}U & }ɬ*o xhE@̾=bgk[X.~/Z2zc ;3s?i UfdB;b['\xI }Iijf@`թ*מ8уޥ919Hҭ;! Ѡ,KCIT$$:<|ZOoƍ껷,?uVm>r9%$-TK:ɜ|{NtraϚ-%')B,hL `ڪ<'˒K `%_-]Nx%-=[;[keb}*H̋ _~K8k&`nU[&hΘEÓ*eprS3 nkRD51!VFlSzS8itu5:g}2o_oTamCmFoE$mǴ2|o鳹cU\И8pۈ|S'tp-a)'XnnݥR6xpQ| %hlq8Ĭ'}XߒD&! d'GVSgpgLܵlƗ:4eu( i)kQA[櫷4%ə3׮#_-YT"Ң*WD׀VX; ʰVΙG=d<H^[7 ڞ?߸q#<>naҔZ&9\Z~+[&2HewӔ-EMKkGt`p>l2EbvB*ʥ\$u)hW.k׎Ukx+;E]1=ܜFU#UYGOHLWֿpbDb?-*jiw)[T!=0ssgWR9etѺ:rr++]/@[Nmu֩R]8z06 emV>G6xj?yd8/DPP ST@x<._ZZTrXLE KKZ>,&URgBXKuu*I$m9Ѐ ۽;Fs<.xz2|J(_C` &!p &^R] <B2*qq&+@K= **]FN&PXL$q4ȕݶULMh$h. >aC_ $. ̈h!oўGؾ+lҦVf̬Z&;ac3ɺU>ݰUْi%=|@15WVV,Qѓ\K\;tŽdc޵RZ\,}L1$M'y4O\QQbɠS /ikwE"*~1+UZS3rLţ;zΜm\]U1Wr=}Yz]yu+ ;@>-woݘ]^jb^l ]88 M8:j՚4]U>Iq:ԄNR04)vc錬byq}TYxʽ{ l^PU1"%wtEN%҈'!g6f2<1rLŪ5d?^8pPg%}Xەdජ HZXfgDhd=v>xD~4,VP]TP]K| {.%~&+Wu$+PSR=ȉ]6Vt#bIqZ~Sm~.c'mJvn㻹b#UVVq cFž{i^nGiLlĤvbcwm+ iqi)o]]jh"^hiX4B`-Q7Zq(le>1{WGOr!HX3萞͋|e⇏#dq/^ZZf}~w7I=9`nC*6l‚} vyCKoݺZ#!cSɺ`+%R#bkKzwYޥI)Eٺzblm¤ʭrtfLŒzwr- %@c\>c ֡ ,̝M~cmH(!H8rP4 ^Qk9~0Job^N Uhv̏/"u%ƫbu K.h){yb{ՙ:2)Xojѓ, 8&zA-0?./>0su++g̭J6_MΜޯ]z ::yd#G?4G{@o?i0hȜ<0##-9NC^>2(m}cyͯ)㹌<2-TaB>ߩm,T˕qDT&u1S#-ijԵj<]xAN%Y"5*@Lksڻz|Z e>V'S"!5` ̝KHhū:y_؆>Ƞ!vǩjG;xھ~eb-W_ϟmzkѤKQ4d$H\XW'Qy?:ۊJyjCsyxL6mz`|i־tR]l\lpgϛaM[kDTdRm *+~ܼaB:IG{2 Ӄ5`PzCgpSSۯ^'ߗz朂Pd_DaGwEU5 e;Uv<#-| 65^lbl !!"q!x]7-qdqf4qjjdj|澭j:Es\}^~3J$1q~paVF0ڥ| †&i>i <hz/;wap6^[K)%x?jQvFg4(*(|4$98EeZZS/>à# f [ HjL&rt&RF{,dD&enYaE |J͋":!\#}`ѝRF t1E47&g#|x [_43Cyl׹_o%Ȁ22͋"kgD  1е4>^L7g?ZF \.fSp*s qg !UP=/ @̝SR | <ޏ1:Lo>Q_:y,Œ4#S΃M1SϛCؾ^``~MA2 )`ў!e9c'd k9ȀAJ2?֪|} a˥l^)oiA6qP,2cCϹOF[Z-| )_ E[>x̱0l<\Jhx3O6Ҭ\˲ ]`]}M@NӢ?/!~!ԡ^*IC9ߕ.yXj@p㛚c+ CX,mv#Õ)2*H$YR9>pSQy$] dB^]?% sX]\3ُ7ƺBm-/\Q9bb'9 ?ng6"QlQ Pӿ|_e@˴zBpAM?R/R-3c哄 nظ֪\})+7T%y+ȗC,OvQBҩ[QN^{YY)htٞuE(leA߶Or|AǶ aGH3u( =ߗU[hpQo?Eh+}|C.lyI?n88[f!%6Vwޫӷjj^_/ ?:=wTQum{k;J|\o`M_Jy~V!؟PeyU,;TRܡiR`cH.KV/ƶLiUqNAwԈeZPٙŝڦnXŌL0H+ͫ@?3hdY"q#a*v-zZt !fy53?2+lnK\Q_WhWZjw¶bƗ#8wK o_XnK޽F4tPűa\P9yVŷ:p[ |qq/:xIvçOlS>&=rSՎ岆+}pJ+:͙#uY%/ݨ4/-KU{g~6^\&`}|o5<_ײ4I+dv㢿n&ͨșSy.=$'~\j&rX:d#o>6;euip5\}eqw/{7J_}i<*tt Pt vX.Icdfu )G6 Q %D@Q>M{ݲF@߂U/2эleU)]=&1x\DlQ6";kG( : +?Hf$ݦ̔_l&~_66UE-EKP.K]y習/2pqd(3N*k&(w".̴XclvӺ t:"T,oiz _6Uɏ[MQFt?@Z]]}ҥvttb''q(3CTSl7TU)%iwޟEAIzy߱HLi[FC6:*ާui y< c WZԜxw̉K7nAh(03 =M`GN#hG7ٞ1'T.爄T RQ%R(cr5o7&*oS.zMU Ff`Ϡ9#7tۢn۹nG^d2U<6 1Y5?gb3]Ǡ*)t )V (}\slf9s_k|\Sn_w"6,WCU \` Ҳ4<:4=[@Գp5j+S4áWC`S -33V#v,/a{7 oo8Sc`36'9Z51R Prt=y-4B( lih~A"R_c~,~@PmGw@O8BU<&Y9_pQ{:h&.v|n<>*B۲&(i0{Y|ej&9Ym5,r9lgqB/տUS>=`WmkE)suhT|BSsّaPzvgL&ԥژh̏BKPcbN*Oiܙq-x~&t|[Zh?[/F>k%ikaWBv [3jpزNzj@!9l"͕Ɨvto\Z` 뗩ݼ_L&Ն£W}|_t`*5쳗n[C###-ZT[medddddܹsg֬Y .PG[B5/Rz2fPX`˞5EuVuəM0qvgdC#< UpRuP(`K;9}:ڴ@ηʧP+'4Pfwjr\gxqZ \65ɯp 4&.j|ʾ꣧6^$|LP.aW1o/ߛ9zS' :rQ]>m<5Eƪ9Cr.T]ąHn  mjdGhinZV6)xV7gO;O5RܸWklLNe2)>EdCf+jnx5l@ZF܏'}EPع_әUo3/G(xӄ-=LA~#$E"?[^Faui~#3b:HCx\ ӹgaG=cCZ7Sme(Ogrk]['gkU8^^p *KoՌkkfL_0CuJ}`Qn^{I!K7d UgԥD{.uuW4YL Q)~FsB`}5ZNl_4Ln|F𣼬7XOohR)Y[+U3aЯ߫Gaw]SVaThwFֹ(=ԙ˥v+B,{xsUEAf91 :NbJG/Ot/L'֥ u :Re޿M]>.)@2C%ɿ[2gI%??)J14),J4`(HMs ckeΘ5Eu.̏ $9񆪆FtG{ YV~f]zsB*m@QILb S| \ OQx?:,E>5w3knDG.O_m常ӧ˃j@@ ĉ?R˵Ԟ6{ >jCNRkK\bSeq_w,_44ylthITx:-wYًf_r_orYjjy.wufOQef}DZIGWPB2rS Rб! %vTVfP[ѽ맰IbJ+ כtydB)^o?~\5r?~ie T~Mҵmn#|]QThle%/X]>`T:aY 7&~|O ְP  ǮO^65)q[{>K7 ,9|*w3BK9z4t \%詥 WW&NմݽQxqrUrQ]RsF-޼}e?qgµ ?~gcXa$)n7r"'=_o ']r~J^[Cx u;*L  :6R)`~Locȣ+Z[W &n={껇$;y\t~|}Og,>K7]Qѡ%XQ))&%2ӭ˗/??~6mRpԩ?OJYTm+%Ɇ g3r 4f9l2x9/XõdWe Tܽ5`TE!cǷ<\vW9(xL $|mQ؇㝘ݢG׵{-P:Xo"㡁DeoC%O:C,~VܝZV :R)=}X`Ös}X3RbUÅ3nM Y&-'ݰ\|cG;ń3Kg--O_HAN1ftINѳkX֡2l2_oֳC&VYa8w*ُ? y.  Qef{cFyEFη_oVᒰ5EF*22cmr]xƙCTltmN^>pՖhE=L^C%>^H+s`;bh`W*904-sU8t (|' @_.(7,xj,znyT&+9qWWZ[l,uyF_7u/pqd3;7C,.)y|n[0c{~jzkuU.qśwW6Ϙq*K4D UE?; &tCǼtCRr /\ ,J_»O;NkЁ*Qhgj\?޻p*4{tHnsqњ%p(FEFyt=+D#\En<[dⒿNU-0\rĒެ疅/YO#W:n%g71?vHA$ԈO*k"AZg-юQoso8pFlEx}OgL>K7ƽz蟡{>|b sJM'N~:t ..//_2g X:oۭ t<c,_BW[% NB'›MqZIWԍóQƴbОl~԰}VNw5 } s:ֹ Hb]@Pr;l8v;$st͂|<& AeX T[Fʚ|dծ<8z#4~_F48 sz|cرeXOW-$-7nKE9 naFOu1JK%|[l+˖"Xh[r}BQ6Is.KI~V &t tZVBX޺ I?zf4>Q/pgrDZ6o!oSq ֢C[0V83l:鏄ixބ^:G@t#|sI^6@71evIK.l0x.˷,>E2DMKL 읇 $?Qu`k?8ƌcaaaaaK_-,,kjjh.ǥmS UM@i35۝Y<: :|mM*o:1Ĝ2VtixY,&BVNe1ɰV  !Uad,T֢1]YMk ojLg1ɰ{sՑIPKQQx*| ȡ=)\1_ \[g;bJsS-@;яZTlpB8t@F2#Ke)BtdDUT8da:RdpF+@6ps&/vSG3EE۔oU̜ 2g¥Qem)edd@ݭ2  ~H8Uy?;y A3= I[:7w!t`Z1$TџNאOW6{ b  (^A=Y.L)=+ ?:@Q G*[USDbeB8U)s:00ȥ'̌CMOP`m&ۘAfL4gnB3KlR@&'c~53cd StMbjk#ľ'MSD]87h~[٘4e6#R6ĬtJqgvsg!,#@ڼRW%$T U\[ 6 9k3&hѬ9yV™|MU^F_q NGnƪ?.gjD76'p-'d@. ra)x{_Aj1?4=7Ҍ!oBOj2 Yd4yF~<.<ӣRal0OȻ~` \{a󸔝h P`BO  SP;$= ΚJѿ[6_?"ߙѺNJwuu#11^̥eC&J<ӳ2Rn=dΟ&Xz0`LіUMsKO VMf55c~`l]':P"g$\.6P/T=ewgEa1e6I%9iZe^&ѣo{%F,&?kYYקe 2[0ř߻?GȐd_Cis)O0i4=ˆ [[0M=|R̺ (ko-2SWwtd99yBFM-^@m*B"Ձ)I23%IF}F -+0O_zA}{} FiyM420pD#jkzN9>xݺ忍h$cž_)|y[WMg5 Tqt`:uym:P ,âdwO`>L]X%8}vkU Sƹ)cx:v9/6>),vբUe:NF\ìQ_9zF89S=}"#yl~ SX:ʜQJW_ޝEqe ?M H""(ԧ1#Q>eẌDF'~KШƨҮAYliYT:5 6S]p~].N[*)qpgzGW,{9^}Uh-c?>Uȼw ٫M.vaud3嗒9O~qMpy ֯y)TTTX\ :-G6lPYxٲe0o޼ǏԺO*YY{xl*6Θ[趵s NQ'GX\*lj ߷+o/ʹQޮa4YX,xnvXJ%y=Tr k6Umr#oxFH&\#V'OU|BQK$E%*5*]]aQZ㣬yaUK@vL-y9*Xz-mTVP,+o#ivi~ǒߕ~Q1gAn3hiE" VF6$C/B Z:/_C>cj:4 !b-vvvP]]ޞxBWBK󴽽=뜗'#Rptt;^B;;ɓ'&&&AAA#F;>KHH8t}||莺7+O߿?""RVVVVVv…>hӦM::C' 2l޽.\ӧOGFFjL%>?xƦK.͙3g߾}VVVt98N:u]^PcǎׯS[XWWWcQ d`llf``c>'N͛7@]~(ǎ;~gR677wqq5jTEEEqqX,ݸq_|;iDkVUU̙3E"y]ܹsLl((((Nw%T]1cfIҠkjjHJJ \bE^}FKNN&m۶ljK'''hii!}! ɒf8q޾ٳgg|m={ $/֖XS]]SLv=z44322jkkv0I۷b;w <}YR ~'BBBHrs Ƞ;A# [k*WՍ t1a s!*++;::获Ξ= AAAt2P555~ĉe0%''׵r+566~I`ϋlv66yZ$0gܹ ~md>;^RL|!Ix5HA]ˌf9r9s4ۿ?xzzYpD645>PYa֭%%%%%%t;h >}:hdX#+..&NNN_+XXXpBChꟗ.];'N$r`~޽{`hhBuuuSSh2F ˆHdffK}L=OKWVV֚yxxc555'O~< IDAT7?D*FEEiӦ_p45,tYY)ؐBcc#",**Ix#G$e6nHtO~iyyΡCƎˠu<]XX-5j֭[W^wU QcIݿAWWҒ0Ybbbii)ܹSy,,,աv WOʫV;qFNNNKKoVTTt?sJJ O;A/Ryo{{'|rʕ'O2aMuYݻwgffvbn˕%<{ɓ0|777aH!wگ*<}::O?uttbbb/_Nw\ ...t3tuu{ &\xի駟Z[[I?PՕ|֭O rȑ6m6caIA___]===R6ѣGB!ڞ8qYl6?r|Ϟ==ڵk9J7onoo766>|0:{'0!!a̙dٜ9sϟe8wܢE<<<Y#Ė˗/ExxeuuÇ[[[kkkwܙ_YYY`ʕ8,{S^Pe.]񉋋#I;))iرt6 qqqEEEyyyv233׮]K%oF}1ĨDkVV$ŋ.]Jdr<#tv͘1+8C``+WLLL ++\qqq2lĈ6l;>yDS?5x˗GFFC+Vf``0q˗/kI3͛7IgtbXFFFFFF<#Π5 bccoB7n֭|;wO"OS̓'Oy))0}6ĈիWG}7o.Y^ SSӰ0Rhm& ɢN&Mڱc֖t wttPwٴ9)L4ۛr9!?@ +V;H,Ka)GDϟ[L _fͺu cƌ9xH@'|qUlھkRf%ȑ#mhh yzܸqTZ .$yoYdz]Zrg'O FH$ edQI&19j0|}}I$==رcw bQ6"zq\;3,X@@FDDJ!{rJ.\Hn֮]:I'k{[t~!ޒE|UUU_`ԩ}(ޙ&K{ZWWR/}^aa!%S ׯ_O A*(( +WI̖gΜ;d߿O&ݻwʪ痖"9|p/! .]4aPX^^@hkkk=f̘11117oJIIIMM2jժ۷3qE}utttttdgggggS{gϞJw874̛7ڵkgϞr@"XXXM6п2n8sLnnnUUiN>#BGZe֬YW^vڍ7˟={nnn˖-swwx[ZZZLLLN?yҥ  MdeeQ S0 ' BZk#C!4B!0O#B 4B!0O#B 4B!0O#B 4B!0O#BY,чIENDB`bim-1.1.8/docs/assets/octave-logo.svg000066400000000000000000000075711502773057700175110ustar00rootroot00000000000000 image/svg+xml bim-1.1.8/docs/bim1a_advection_diffusion.html000066400000000000000000000324561502773057700212300ustar00rootroot00000000000000 PDE Solver using a Finite Element/Finite Volume approach: bim1a_advection_diffusion

Function Reference: bim1a_advection_diffusion

Function File: [A] = bim1a_advection_diffusion(mesh,alpha,gamma,eta,beta)

Build the Scharfetter-Gummel stabilized stiffness matrix for a diffusion-advection problem.

The equation taken into account is:

- div (alpha * gamma (eta grad (u) - beta u)) = f

where alpha is an element-wise constant scalar function, eta and gamma are piecewise linear conforming scalar functions, beta is an element-wise constant vector function.

Instead of passing the vector field beta directly one can pass a piecewise linear conforming scalar function phi as the last input. In such case beta = grad phi is assumed.

If phi is a single scalar value beta is assumed to be 0 in the whole domain.

See also: bim1a_rhs, bim1a_reaction, bim1a_laplacian, bim2a_advection_diffusion

Source Code: bim1a_advection_diffusion

bim-1.1.8/docs/bim1a_advection_upwind.html000066400000000000000000000317611502773057700205460ustar00rootroot00000000000000 PDE Solver using a Finite Element/Finite Volume approach: bim1a_advection_upwind

Function Reference: bim1a_advection_upwind

Function File: [A] = bim1a_advection_upwind (mesh, beta)

Build the UW stabilized stiffness matrix for an advection problem.

The equation taken into account is:

(beta u)’ = f

where beta is an element-wise constant.

Instead of passing the vector field beta directly one can pass a piecewise linear conforming scalar function phi as the last input. In such case beta = grad phi is assumed.

If phi is a single scalar value beta is assumed to be 0 in the whole domain.

See also: bim1a_rhs, bim1a_reaction, bim1a_laplacian, bim2a_advection_diffusion

Source Code: bim1a_advection_upwind

bim-1.1.8/docs/bim1a_axisymmetric_advection_diffusion.html000066400000000000000000000336001502773057700240160ustar00rootroot00000000000000 PDE Solver using a Finite Element/Finite Volume approach: bim1a_axisymmetric_advection_diffusion

Function Reference: bim1a_axisymmetric_advection_diffusion

Function File: [A] = bim1a_axisymmetric_advection_diffusion(mesh,alpha,gamma,eta,beta)

Build the Scharfetter-Gummel stabilized stiffness matrix for a diffusion-advection problem in cylindrical coordinates with axisymmetric configuration. Rotational symmetry is assumed with respect to be the vertical axis r=0. Only grids that DO NOT contain r=0 are admissible.

 
   |   |-------|   OK       |-------|   |   OK        |--|-----|   NO!
  r=0                                  r=0              r=0

The equation taken into account is:

- 1/r * d/dr (alpha * gamma (eta du/dr - beta u)) = f

where alpha is an element-wise constant scalar function, eta and gamma are piecewise linear conforming scalar functions, beta is an element-wise constant vector function.

Instead of passing the vector field beta directly one can pass a piecewise linear conforming scalar function phi as the last input. In such case beta = grad phi is assumed.

If phi is a single scalar value beta is assumed to be 0 in the whole domain.

See also: bim1a_axisymmetric_rhs, bim1a_axisymmetric_reaction, bim1a_axisymmetric_laplacian, bim2a_axisymmetric_advection_diffusion

Source Code: bim1a_axisymmetric_advection_diffusion

bim-1.1.8/docs/bim1a_axisymmetric_advection_upwind.html000066400000000000000000000323431502773057700233410ustar00rootroot00000000000000 PDE Solver using a Finite Element/Finite Volume approach: bim1a_axisymmetric_advection_upwind

Function Reference: bim1a_axisymmetric_advection_upwind

Function File: [A] = bim1a_axisymmetric_advection_upwind (mesh, beta)

Build the Upwind stabilized stiffness matrix for an advection problem in cylindrical coordinates with axisymmetric configuration.

The equation taken into account is:

1/r * (r * beta u)’ = f

where beta is an element-wise constant.

Instead of passing the vector field beta directly one can pass a piecewise linear conforming scalar function phi as the last input. In such case beta = grad phi is assumed.

If phi is a single scalar value beta is assumed to be 0 in the whole domain.

See also: bim1a_axisymmetric_advection_diffusion, bim1a_axisymmetric_rhs, bim1a_axisymmetric_reaction, bim1a_axisymmetric_laplacian

Source Code: bim1a_axisymmetric_advection_upwind

bim-1.1.8/docs/bim1a_axisymmetric_laplacian.html000066400000000000000000000325251502773057700217250ustar00rootroot00000000000000 PDE Solver using a Finite Element/Finite Volume approach: bim1a_axisymmetric_laplacian

Function Reference: bim1a_axisymmetric_laplacian

Function File: A = bim1a_axisymmetric_laplacian (mesh,epsilon,kappa)

Build the standard finite element stiffness matrix for a diffusion problem in cylindrical coordinates with axisymmetric configuration. Rotational symmetry is assumed with respect to be the vertical axis r=0. Only grids that DO NOT contain r=0 are admissible.

 
   |   |-------|   OK       |--|-----|   NO!
  r=0                         r=0

The equation taken into account is:

- 1/r * (r * epsilon * kappa ( u’ ))’ = f

where epsilon is an element-wise constant scalar function, while kappa is a piecewise linear conforming scalar function.

See also: bim1a_axisymmetric_rhs, bim1a_axisymmetric_reaction, bim1a_axisymmetric_advection_diffusion, bim2a_laplacian, bim3a_laplacian

Source Code: bim1a_axisymmetric_laplacian

bim-1.1.8/docs/bim1a_axisymmetric_reaction.html000066400000000000000000000317541502773057700216100ustar00rootroot00000000000000 PDE Solver using a Finite Element/Finite Volume approach: bim1a_axisymmetric_reaction

Function Reference: bim1a_axisymmetric_reaction

Function File: [C] = bim1a_axisymmetric_reaction(mesh,delta,zeta)

Build the lumped finite element mass matrix for a diffusion problem in cylindrical coordinates with axisymmetric configuration.

The equation taken into account is:

delta * zeta * u = f

where delta is an element-wise constant scalar function, while zeta is a piecewise linear conforming scalar function.

See also: bim1a_axisymmetric_rhs, bim1a_axisymmetric_advection_diffusion, bim1a_axisymmetric_laplacian, bim2a_reaction, bim3a_reaction

Source Code: bim1a_axisymmetric_reaction

bim-1.1.8/docs/bim1a_axisymmetric_rhs.html000066400000000000000000000314771502773057700206020ustar00rootroot00000000000000 PDE Solver using a Finite Element/Finite Volume approach: bim1a_axisymmetric_rhs

Function Reference: bim1a_axisymmetric_rhs

Function File: [b] = bim1a_rhs(mesh,f, g)

Build the finite element right-hand side of a diffusion problem employing mass-lumping.

The equation taken into account is:

delta * u = f * g

where f is an element-wise constant scalar function, while g is a piecewise linear conforming scalar function.

See also: bim1a_reaction, bim1a_advection_diffusion, bim1a_laplacian, bim2a_reaction, bim3a_reaction

Source Code: bim1a_axisymmetric_rhs

bim-1.1.8/docs/bim1a_laplacian.html000066400000000000000000000315131502773057700171230ustar00rootroot00000000000000 PDE Solver using a Finite Element/Finite Volume approach: bim1a_laplacian

Function Reference: bim1a_laplacian

Function File: A = bim1a_laplacian (mesh,epsilon,kappa)

Build the standard finite element stiffness matrix for a diffusion problem.

The equation taken into account is:

- (epsilon * kappa ( u’ ))’ = f

where epsilon is an element-wise constant scalar function, while kappa is a piecewise linear conforming scalar function.

See also: bim1a_rhs, bim1a_reaction, bim1a_advection_diffusion, bim2a_laplacian, bim3a_laplacian

Source Code: bim1a_laplacian

bim-1.1.8/docs/bim1a_reaction.html000066400000000000000000000314421502773057700170040ustar00rootroot00000000000000 PDE Solver using a Finite Element/Finite Volume approach: bim1a_reaction

Function Reference: bim1a_reaction

Function File: [C] = bim1a_reaction(mesh,delta,zeta)

Build the lumped finite element mass matrix for a diffusion problem.

The equation taken into account is:

delta * zeta * u = f

where delta is an element-wise constant scalar function, while zeta is a piecewise linear conforming scalar function.

See also: bim1a_rhs, bim1a_advection_diffusion, bim1a_laplacian, bim2a_reaction, bim3a_reaction

Source Code: bim1a_reaction

bim-1.1.8/docs/bim1a_rhs.html000066400000000000000000000314131502773057700157720ustar00rootroot00000000000000 PDE Solver using a Finite Element/Finite Volume approach: bim1a_rhs

Function Reference: bim1a_rhs

Function File: [b] = bim1a_rhs(mesh,f, g)

Build the finite element right-hand side of a diffusion problem employing mass-lumping.

The equation taken into account is:

delta * u = f * g

where f is an element-wise constant scalar function, while g is a piecewise linear conforming scalar function.

See also: bim1a_reaction, bim1a_advection_diffusion, bim1a_laplacian, bim2a_reaction, bim3a_reaction

Source Code: bim1a_rhs

bim-1.1.8/docs/bim1c_elem_to_nodes.html000066400000000000000000000316361502773057700200230ustar00rootroot00000000000000 PDE Solver using a Finite Element/Finite Volume approach: bim1c_elem_to_nodes

Function Reference: bim1c_elem_to_nodes

Function File: u_nod = bim1c_elem_to_nodes (mesh, u_el)
Function File: u_nod = bim1c_elem_to_nodes (m_el, u_el)
Function File: [u_nod, m_el] = bim1c_elem_to_nodes ( ... )

Compute interpolated values at nodes u_nod given values at element mid-points u_el. If called with more than one output, also return the interpolation matrix m_el such that u_nod = m_el * u_el. If repeatedly performing interpolation on the same mesh the matrix m_el obtained by a previous call to bim1c_elem_to_nodes may be passed as input to avoid unnecessary computations.

Source Code: bim1c_elem_to_nodes

bim-1.1.8/docs/bim1c_norm.html000066400000000000000000000315761502773057700161650ustar00rootroot00000000000000 PDE Solver using a Finite Element/Finite Volume approach: bim1c_norm

Function Reference: bim1c_norm

Function File: [norm_u] = bim1c_norm(mesh,u,norm_type)

Compute the norm_type-norm of function u on the domain described by the triangular grid mesh.

The input function u can be either a piecewise linear conforming scalar function or an elementwise constant scalar or vector function.

The string parameter norm_type can be one among ’L2’, ’H1’ and ’inf’.

Should the input function be piecewise constant, the H1 norm will not be computed and the function will return an error message.

See also: bim2c_norm, bim3c_norm

Source Code: bim1c_norm

bim-1.1.8/docs/bim2a_advection_diffusion.html000066400000000000000000000337421502773057700212300ustar00rootroot00000000000000 PDE Solver using a Finite Element/Finite Volume approach: bim2a_advection_diffusion

Function Reference: bim2a_advection_diffusion

Function File: [A] = bim2a_advection_diffusion(mesh,alpha,gamma,eta,beta)

Build the Scharfetter-Gummel stabilized stiffness matrix for a diffusion-advection problem.

The equation taken into account is:

- div (alpha * gamma (eta grad (u) - beta u )) = f

where alpha is an element-wise constant scalar function, eta and gamma are piecewise linear conforming scalar functions, beta is an element-wise constant vector function.

Instead of passing the vector field beta directly one can pass a piecewise linear conforming scalar function phi as the last input. In such case beta = grad phi is assumed.

If phi is a single scalar value beta is assumed to be 0 in the whole domain.

Example:

 
 mesh = msh2m_structured_mesh([0:1/3:1],[0:1/3:1],1,1:4);
 mesh = bim2c_mesh_properties(mesh);
 x    = mesh.p(1,:)';

 Dnodes    = bim2c_unknowns_on_side(mesh,[2,4]);
 Nnodes    = columns(mesh.p);
 Nelements = columns(mesh.t);
 Varnodes  = setdiff(1:Nnodes,Dnodes);

 alpha  = ones(Nelements,1);
 eta    = .1*ones(Nnodes,1);
 beta   = [ones(1,Nelements);zeros(1,Nelements)];
 gamma  = ones(Nnodes,1);
 f      = bim2a_rhs(mesh,ones(Nnodes,1),ones(Nelements,1));

 S   = bim2a_advection_diffusion(mesh,alpha,gamma,eta,beta);
 u   = zeros(Nnodes,1);
 uex = x - (exp(10*x)-1)/(exp(10)-1);
 
 u(Varnodes) = S(Varnodes,Varnodes)\f(Varnodes);
 
 assert(u,uex,1e-7)
 

See also: bim2a_rhs, bim2a_reaction, bim2c_mesh_properties

Source Code: bim2a_advection_diffusion

bim-1.1.8/docs/bim2a_advection_upwind.html000066400000000000000000000316771502773057700205550ustar00rootroot00000000000000 PDE Solver using a Finite Element/Finite Volume approach: bim2a_advection_upwind

Function Reference: bim2a_advection_upwind

Function File: [A] = bim2a_advection_upwind (mesh, beta)

Build the UW stabilized stiffness matrix for an advection problem.

The equation taken into account is:

div (beta u) = f

where beta is an element-wise constant vector function.

Instead of passing the vector field beta directly one can pass a piecewise linear conforming scalar function phi as the last input. In such case beta = grad phi is assumed.

If phi is a single scalar value beta is assumed to be 0 in the whole domain.

See also: bim2a_rhs, bim2a_reaction, bim2c_mesh_properties

Source Code: bim2a_advection_upwind

bim-1.1.8/docs/bim2a_axisymmetric_advection_diffusion.html000066400000000000000000000337511502773057700240260ustar00rootroot00000000000000 PDE Solver using a Finite Element/Finite Volume approach: bim2a_axisymmetric_advection_diffusion

Function Reference: bim2a_axisymmetric_advection_diffusion

Function File: [A] = bim2a_axisymmetric_advection_diffusion(mesh,alpha,gamma,eta,beta)

Build the Scharfetter-Gummel stabilized stiffness matrix for a diffusion-advection problem in cylindrical coordinates with axisymmetric configuration. Rotational symmetry is assumed with respect to be the vertical axis r=0. Only plane geometries that DO NOT intersect the symmetry axis are admitted.

 
    |   ____                 _|____ 
    |  |    \               \ |    |
  z |  |     \  OK           \|    |   NO!
    |  |______\               |\___|
    |     r                   |

The equation taken into account is:

1/r * d(r * Fr)/dr + dFz/dz = f

with

F = [Fr, Fz]’ = - alpha * gamma ( eta grad (u) - beta u )

where alpha is an element-wise constant scalar function, eta and gamma are piecewise linear conforming scalar functions, beta is an element-wise constant vector function.

Instead of passing the vector field beta directly, one can pass a piecewise linear conforming scalar function phi as the last input. In such case beta = grad phi is assumed.

If phi is a single scalar value beta is assumed to be 0 in the whole domain.

See also: bim2a_axisymmetric_rhs, bim2a_axisymmetric_reaction, bim2a_advection_diffusion, bim2c_mesh_properties

Source Code: bim2a_axisymmetric_advection_diffusion

bim-1.1.8/docs/bim2a_axisymmetric_advection_upwind.html000066400000000000000000000324031502773057700233370ustar00rootroot00000000000000 PDE Solver using a Finite Element/Finite Volume approach: bim2a_axisymmetric_advection_upwind

Function Reference: bim2a_axisymmetric_advection_upwind

Function File: [A] = bim2a_axisymmetric_advection_upwind (mesh, beta)

Build the Upwind stabilized stiffness matrix for an advection problem in cylindrical coordinates with axisymmetric configuration.

The equation taken into account is:

1/r * d/dr (r * beta_r u) + d/dz (beta_z u) = f

where beta is an element-wise constant vector function.

Instead of passing the vector field beta directly one can pass a piecewise linear conforming scalar function phi as the last input. In such case beta = grad phi is assumed.

If phi is a single scalar value beta is assumed to be 0 in the whole domain.

See also: bim2a_axisymmetric_rhs, bim2a_axisymmetric_reaction, bim2a_axisymmetric_advection_diffusion, bim2c_mesh_properties

Source Code: bim2a_axisymmetric_advection_upwind

bim-1.1.8/docs/bim2a_axisymmetric_boundary_mass.html000066400000000000000000000320751502773057700226500ustar00rootroot00000000000000 PDE Solver using a Finite Element/Finite Volume approach: bim2a_axisymmetric_boundary_mass

Function Reference: bim2a_axisymmetric_boundary_mass

Function File: [M] = bim2a_axisymmetric_boundary_mass(mesh,sidelist,nodelist)

Build the lumped boundary mass matrix needed to apply Robin and Neumann boundary conditions in a problem in cylindrical coordinates with axisymmetric configuration.

The vector sidelist contains the list of the side edges contributing to the mass matrix.

The optional argument nodelist contains the list of the degrees of freedom on the boundary.

See also: bim2a_axisymmetric_rhs, bim2a_axisymmetric_advection_diffusion, bim2a_axisymmetric_laplacian, bim2a_axisymmetric_reaction, bim2a_boundary_mass

Source Code: bim2a_axisymmetric_boundary_mass

bim-1.1.8/docs/bim2a_axisymmetric_laplacian.html000066400000000000000000000331021502773057700217160ustar00rootroot00000000000000 PDE Solver using a Finite Element/Finite Volume approach: bim2a_axisymmetric_laplacian

Function Reference: bim2a_axisymmetric_laplacian

Function File: A = bim2a_axisymmetric_laplacian (mesh,epsilon,kappa)

Build the standard finite element stiffness matrix for a diffusion problem in cylindrical coordinates with axisymmetric configuration. Rotational symmetry is assumed with respect to be the vertical axis r=0. Only plane geometries that DO NOT intersect the symmetry axis are admitted.

 
    |   ____                 _|____ 
    |  |    \               \ |    |
  z |  |     \  OK           \|    |   NO!
    |  |______\               |\___|
    |     r                   |

The equation taken into account is:

1/r * d(r * Fr)/dr + dFz/dz = f

with

F = [Fr, Fz]’ = - epsilon * kappa grad (u)

where epsilon is an element-wise constant scalar function, while kappa is a piecewise linear conforming scalar function.

See also: bim2a_axisymmetric_rhs, bim2a_axisymmetric_reaction, bim2a_axisymmetric_advection_diffusion, bim2a_laplacian, bim1a_laplacian, bim3a_laplacian

Source Code: bim2a_axisymmetric_laplacian

bim-1.1.8/docs/bim2a_axisymmetric_reaction.html000066400000000000000000000320061502773057700216000ustar00rootroot00000000000000 PDE Solver using a Finite Element/Finite Volume approach: bim2a_axisymmetric_reaction

Function Reference: bim2a_axisymmetric_reaction

Function File: [C] = bim2a_axisymmetric_reaction(mesh,delta,zeta)

Build the lumped finite element mass matrix for a diffusion problem in cylindrical coordinates with axisymmetric configuration.

The equation taken into account is:

delta * zeta * u = f

where delta is an element-wise constant scalar function, while zeta is a piecewise linear conforming scalar function.

See also: bim2a_rhs, bim2a_axisymmetric_advection_diffusion, bim2a_axisymmetric_laplacian, bim2a_reaction, bim1a_reaction, bim3a_reaction

Source Code: bim2a_axisymmetric_reaction

bim-1.1.8/docs/bim2a_axisymmetric_rhs.html000066400000000000000000000316601502773057700205750ustar00rootroot00000000000000 PDE Solver using a Finite Element/Finite Volume approach: bim2a_axisymmetric_rhs

Function Reference: bim2a_axisymmetric_rhs

Function File: [b] = bim2a_axisymmetric_rhs(mesh,f,g)

Build the finite element right-hand side of a diffusion problem in cylindrical coordinates with axisymmetric configuration employing mass-lumping.

The equation taken into account is:

delta * u = f * g

where f is an element-wise constant scalar function, while g is a piecewise linear conforming scalar function.

See also: bim2a_axisymmetric_reaction, bim2a_axisymmetric_advection_diffusion, bim2a_axisymmetric_laplacian, bim1a_axisymmetric_rhs

Source Code: bim2a_axisymmetric_rhs

bim-1.1.8/docs/bim2a_boundary_mass.html000066400000000000000000000314021502773057700200430ustar00rootroot00000000000000 PDE Solver using a Finite Element/Finite Volume approach: bim2a_boundary_mass

Function Reference: bim2a_boundary_mass

Function File: [M] = bim2a_boundary_mass(mesh,sidelist,nodelist)

Build the lumped boundary mass matrix needed to apply Robin boundary conditions.

The vector sidelist contains the list of the side edges contributing to the mass matrix.

The optional argument nodelist contains the list of the degrees of freedom on the boundary.

See also: bim2a_rhs, bim2a_advection_diffusion, bim2a_laplacian, bim2a_reaction

Source Code: bim2a_boundary_mass

bim-1.1.8/docs/bim2a_laplacian.html000066400000000000000000000350251502773057700171260ustar00rootroot00000000000000 PDE Solver using a Finite Element/Finite Volume approach: bim2a_laplacian

Function Reference: bim2a_laplacian

Function File: A = bim2a_laplacian (mesh,epsilon,kappa)

Build the standard finite element stiffness matrix for a diffusion problem.

The equation taken into account is:

- div (epsilon * kappa grad (u)) = f

where epsilon is an element-wise constant scalar function, while kappa is a piecewise linear conforming scalar function.

See also: bim2a_rhs, bim2a_reaction, bim2a_advection_diffusion, bim1a_laplacian, bim3a_laplacian

Source Code: bim2a_laplacian

Example: 1

 

 m = msh2m_structured_mesh (0:.1:2*pi, 0:.1:2*pi, 1, 1:4, 'random');
 m = bim2c_mesh_properties (m);
 kappa = 2 + sin (m.p(1, :)');
 f     = kappa .* cos (m.p(2, :)');
 uex   = cos (m.p(2, :)');
 A = bim2a_laplacian (m, 3./(sum(1./kappa(m.t(1:3, :)), 1)), 1);
 b = bim2a_rhs (m, 1, f);
 dnodes = bim2c_unknowns_on_side (m, 1:4);
 inodes = setdiff (1:columns(m.p), dnodes);
 u = uex;
 u(inodes) = A(inodes, inodes) \ (b(inodes)-A(inodes, dnodes) * u(dnodes));
 h = pdesurf (m.p, m.t, u)
 figure
 pdesurf (m.p, m.t, uex)

h = -39.365
                    
plotted figure

plotted figure

bim-1.1.8/docs/bim2a_reaction.html000066400000000000000000000314421502773057700170050ustar00rootroot00000000000000 PDE Solver using a Finite Element/Finite Volume approach: bim2a_reaction

Function Reference: bim2a_reaction

Function File: [C] = bim2a_reaction(mesh,delta,zeta)

Build the lumped finite element mass matrix for a diffusion problem.

The equation taken into account is:

delta * zeta * u = f

where delta is an element-wise constant scalar function, while zeta is a piecewise linear conforming scalar function.

See also: bim2a_rhs, bim2a_advection_diffusion, bim2a_laplacian, bim1a_reaction, bim3a_reaction

Source Code: bim2a_reaction

bim-1.1.8/docs/bim2a_rhs.html000066400000000000000000000314121502773057700157720ustar00rootroot00000000000000 PDE Solver using a Finite Element/Finite Volume approach: bim2a_rhs

Function Reference: bim2a_rhs

Function File: [b] = bim2a_rhs(mesh,f,g)

Build the finite element right-hand side of a diffusion problem employing mass-lumping.

The equation taken into account is:

delta * u = f * g

where f is an element-wise constant scalar function, while g is a piecewise linear conforming scalar function.

See also: bim2a_reaction, bim2a_advection_diffusion, bim2a_laplacian, bim1a_reaction, bim3a_reaction

Source Code: bim2a_rhs

bim-1.1.8/docs/bim2c_global_flux.html000066400000000000000000000325631502773057700175060ustar00rootroot00000000000000 PDE Solver using a Finite Element/Finite Volume approach: bim2c_global_flux

Function Reference: bim2c_global_flux

Function File: [jx,jy] = bim2c_global_flux(mesh,u,alpha,gamma,eta,beta)

Compute the flux associated with the Scharfetter-Gummel approximation of the scalar field u.

The vector field is defined as:

J(u) = alpha* gamma * (eta * grad u - beta * u))

where alpha is an element-wise constant scalar function, eta and gamma are piecewise linear conforming scalar functions, while beta is element-wise constant vector function.

J(u) is an element-wise constant vector function.

Instead of passing the vector field beta directly one can pass a piecewise linear conforming scalar function phi as the last input. In such case beta = grad phi is assumed. If phi is a single scalar value beta is assumed to be 0 in the whole domain.

See also: bim2c_pde_gradient, bim2a_advection_diffusion

Source Code: bim2c_global_flux

bim-1.1.8/docs/bim2c_intrp.html000066400000000000000000000307331502773057700163410ustar00rootroot00000000000000 PDE Solver using a Finite Element/Finite Volume approach: bim2c_intrp bim-1.1.8/docs/bim2c_mesh_properties.html000066400000000000000000000312441502773057700204130ustar00rootroot00000000000000 PDE Solver using a Finite Element/Finite Volume approach: bim2c_mesh_properties bim-1.1.8/docs/bim2c_norm.html000066400000000000000000000317541502773057700161640ustar00rootroot00000000000000 PDE Solver using a Finite Element/Finite Volume approach: bim2c_norm

Function Reference: bim2c_norm

Function File: [norm_u] = bim2c_norm(mesh,u,norm_type)

Compute the norm_type-norm of function u on the domain described by the triangular grid mesh.

The input function u can be either a piecewise linear conforming scalar function or an elementwise constant scalar or vector function.

The string parameter norm_type can be one among ’L2’, ’H1’ and ’inf’.

Should the input function be piecewise constant, the H1 norm will not be computed and the function will return an error message.

For the numerical integration of the L2 norm the second order middle point quadrature rule is used.

See also: bim1c_norm, bim3c_norm

Source Code: bim2c_norm

bim-1.1.8/docs/bim2c_pde_gradient.html000066400000000000000000000306551502773057700176350ustar00rootroot00000000000000 PDE Solver using a Finite Element/Finite Volume approach: bim2c_pde_gradient bim-1.1.8/docs/bim2c_tri_to_nodes.html000066400000000000000000000316511502773057700176750ustar00rootroot00000000000000 PDE Solver using a Finite Element/Finite Volume approach: bim2c_tri_to_nodes

Function Reference: bim2c_tri_to_nodes

Function File: u_nod = bim2c_tri_to_nodes (mesh, u_tri)
Function File: u_nod = bim2c_tri_to_nodes (m_tri, u_tri)
Function File: [u_nod, m_tri] = bim2c_tri_to_nodes ( ... )

Compute interpolated values at triangle nodes u_nod given values at triangle mid-points u_tri. If called with more than one output, also return the interpolation matrix m_tri such that u_nod = m_tri * u_tri. If repeatedly performing interpolation on the same mesh the matrix m_tri obtained by a previous call to bim2c_tri_to_nodes may be passed as input to avoid unnecessary computations.

Source Code: bim2c_tri_to_nodes

bim-1.1.8/docs/bim2c_unknowns_on_side.html000066400000000000000000000310461502773057700205650ustar00rootroot00000000000000 PDE Solver using a Finite Element/Finite Volume approach: bim2c_unknowns_on_side bim-1.1.8/docs/bim3a_advection_diffusion.html000066400000000000000000000315001502773057700212170ustar00rootroot00000000000000 PDE Solver using a Finite Element/Finite Volume approach: bim3a_advection_diffusion

Function Reference: bim3a_advection_diffusion

Function File: [A] = bim3a_advection_diffusion (mesh, alpha, v)

Build the Scharfetter-Gummel stabilized stiffness matrix for a diffusion-advection problem.

The equation taken into account is:

- div (alpha ( grad (u) - grad (v) u)) = f

where v is a piecewise linear continuous scalar functions and alpha is a piecewise constant scalar function.

See also: bim3a_rhs, bim3a_reaction, bim3a_laplacian, bim3c_mesh_properties

Source Code: bim3a_advection_diffusion

bim-1.1.8/docs/bim3a_boundary_mass.html000066400000000000000000000314711502773057700200520ustar00rootroot00000000000000 PDE Solver using a Finite Element/Finite Volume approach: bim3a_boundary_mass

Function Reference: bim3a_boundary_mass

Function File: [M] = bim3a_boundary_mass(mesh,facelist,nodelist)

Build the lumped boundary mass matrix needed to apply Robin boundary conditions.

The vector facelist contains the list of the faces contributing to the mass matrix.

The optional argument nodelist contains the list of the degrees of freedom on the boundary.

See also: bim3a_rhs, bim3a_advection_diffusion, bim3a_laplacian, bim3a_reaction, bim2a_boundary_mass

Source Code: bim3a_boundary_mass

bim-1.1.8/docs/bim3a_laplacian.html000066400000000000000000000314021502773057700171220ustar00rootroot00000000000000 PDE Solver using a Finite Element/Finite Volume approach: bim3a_laplacian

Function Reference: bim3a_laplacian

Function File: A = bim3a_laplacian (mesh, epsilon, kappa)

Build the standard finite element stiffness matrix for a diffusion problem.

The equation taken into account is:

- (epsilon * kappa ( u’ ))’ = f

where epsilon is an element-wise constant scalar function, while kappa is a piecewise linear conforming scalar function.

See also: bim3a_rhs, bim3a_reaction, bim2a_laplacian, bim3a_laplacian

Source Code: bim3a_laplacian

bim-1.1.8/docs/bim3a_osc_advection_diffusion.html000066400000000000000000000320571502773057700220730ustar00rootroot00000000000000 PDE Solver using a Finite Element/Finite Volume approach: bim3a_osc_advection_diffusion

Function Reference: bim3a_osc_advection_diffusion

Function File: [A] = bim3a_osc_advection_diffusion (mesh, alpha, v)

Build the Scharfetter-Gummel stabilized OSC stiffness matrix for a diffusion-advection problem.

For details on the Orthogonal Subdomain Collocation (OSC) method see: M.Putti and C.Cordes, SIAM J.SCI.COMPUT. Vol.19(4), pp.1154-1168, 1998.

The equation taken into account is:

- div (alpha ( grad (u) - grad (v) u)) = f

where v is a piecewise linear continuous scalar functions and alpha is a piecewise constant scalar function.

See also: bim3a_rhs, bim3a_osc_laplacian, bim3a_reaction, bim3a_laplacian, bim3c_mesh_properties

Source Code: bim3a_osc_advection_diffusion

bim-1.1.8/docs/bim3a_osc_laplacian.html000066400000000000000000000314641502773057700177760ustar00rootroot00000000000000 PDE Solver using a Finite Element/Finite Volume approach: bim3a_osc_laplacian

Function Reference: bim3a_osc_laplacian

Function File: A = bim3a_osc_laplacian (mesh, epsilon)

Build the osc finite element stiffness matrix for a diffusion problem.

For details on the Orthogonal Subdomain Collocation (OSC) method see: M.Putti and C.Cordes, SIAM J.SCI.COMPUT. Vol.19(4), pp.1154-1168, 1998.

The equation taken into account is:

- div (epsilon grad (u)) = f

where epsilon is an element-wise constant scalar function.

See also: bim3a_rhs, bim3a_reaction, bim2a_laplacian, bim3a_laplacian

Source Code: bim3a_osc_laplacian

bim-1.1.8/docs/bim3a_reaction.html000066400000000000000000000313271502773057700170100ustar00rootroot00000000000000 PDE Solver using a Finite Element/Finite Volume approach: bim3a_reaction

Function Reference: bim3a_reaction

Function File: [C] = bim3a_reaction (mesh,delta,zeta)

Build the lumped finite element mass matrix for a diffusion problem.

The equation taken into account is:

delta * zeta * u = f

where delta is an element-wise constant scalar function, while zeta is a piecewise linear conforming scalar function.

See also: bim3a_rhs, bim3a_laplacian, bim2a_reaction, bim3a_reaction

Source Code: bim3a_reaction

bim-1.1.8/docs/bim3a_rhs.html000066400000000000000000000312631502773057700157770ustar00rootroot00000000000000 PDE Solver using a Finite Element/Finite Volume approach: bim3a_rhs

Function Reference: bim3a_rhs

Function File: [b] = bim3a_rhs (mesh, f, g)

Build the finite element right-hand side of a diffusion problem employing mass-lumping.

The equation taken into account is:

delta * u = f * g

where f is an element-wise constant scalar function, while g is a piecewise linear conforming scalar function.

See also: bim3a_reaction, bim3_laplacian, bim1a_reaction, bim2a_reaction

Source Code: bim3a_rhs

bim-1.1.8/docs/bim3c_global_flux.html000066400000000000000000000315471502773057700175100ustar00rootroot00000000000000 PDE Solver using a Finite Element/Finite Volume approach: bim3c_global_flux

Function Reference: bim3c_global_flux

Function File: [F] = bim3c_global_flux (mesh, u, alpha, v)

Compute the flux associated with the Scharfetter-Gummel approximation of the scalar field u.

The vector field is defined as:

F =- alpha ( grad (u) - grad (v) u )

where v is a piecewise linear continuous scalar functions and alpha is a piecewise constant scalar function.

See also: bim3a_rhs, bim3a_reaction, bim3a_laplacian, bim3c_mesh_properties

Source Code: bim3c_global_flux

bim-1.1.8/docs/bim3c_intrp.html000066400000000000000000000307471502773057700163470ustar00rootroot00000000000000 PDE Solver using a Finite Element/Finite Volume approach: bim3c_intrp bim-1.1.8/docs/bim3c_mesh_properties.html000066400000000000000000000310321502773057700204070ustar00rootroot00000000000000 PDE Solver using a Finite Element/Finite Volume approach: bim3c_mesh_properties bim-1.1.8/docs/bim3c_norm.html000066400000000000000000000321031502773057700161520ustar00rootroot00000000000000 PDE Solver using a Finite Element/Finite Volume approach: bim3c_norm

Function Reference: bim3c_norm

Function File: [norm_u] = bim3c_norm(mesh,u,norm_type)

Compute the norm_type-norm of function u on the domain described by the tetrahedral grid mesh.

The input function u can be either a piecewise linear conforming scalar function or an elementwise constant scalar or vector function.

The string parameter norm_type can be one among ’L2’, ’H1’ and ’inf’.

Should the input function be piecewise constant, the H1 norm will not be computed and the function will return an error message.

For the numerical integration of the L2 norm the second order quadrature rule by Keast is used (ref. P. Keast, Moderate degree tetrahedral quadrature formulas, CMAME 55: 339-348 1986).

See also: bim1c_norm, bim2c_norm

Source Code: bim3c_norm

bim-1.1.8/docs/bim3c_pde_gradient.html000066400000000000000000000306751502773057700176400ustar00rootroot00000000000000 PDE Solver using a Finite Element/Finite Volume approach: bim3c_pde_gradient bim-1.1.8/docs/bim3c_tri_to_nodes.html000066400000000000000000000316611502773057700176770ustar00rootroot00000000000000 PDE Solver using a Finite Element/Finite Volume approach: bim3c_tri_to_nodes

Function Reference: bim3c_tri_to_nodes

Function File: u_nod = bim3c_tri_to_nodes (mesh, u_tri)
Function File: u_nod = bim3c_tri_to_nodes (m_tri, u_tri)
Function File: [u_nod, m_tri] = bim3c_tri_to_nodes ( ... )

Compute interpolated values at triangle nodes u_nod given values at tetrahedral centers of mass u_tri. If called with more than one output, also return the interpolation matrix m_tri such that u_nod = m_tri * u_tri. If repeatedly performing interpolation on the same mesh the matrix m_tri obtained by a previous call to bim2c_tri_to_nodes may be passed as input to avoid unnecessary computations.

Source Code: bim3c_tri_to_nodes

bim-1.1.8/docs/bim3c_unknowns_on_faces.html000066400000000000000000000310531502773057700207210ustar00rootroot00000000000000 PDE Solver using a Finite Element/Finite Volume approach: bim3c_unknowns_on_faces bim-1.1.8/docs/bimu_bernoulli.html000066400000000000000000000305031502773057700171330ustar00rootroot00000000000000 PDE Solver using a Finite Element/Finite Volume approach: bimu_bernoulli bim-1.1.8/docs/bimu_logm.html000066400000000000000000000304671502773057700161070ustar00rootroot00000000000000 PDE Solver using a Finite Element/Finite Volume approach: bimu_logm bim-1.1.8/docs/index.html000066400000000000000000000533361502773057700152440ustar00rootroot00000000000000 PDE Solver using a Finite Element/Finite Volume approach
bim

bim

1.1.6 2022-07-22

Package for solving Diffusion Advection Reaction (DAR) Partial Differential Equations

Select Category:

Matrix assembly

bim1a_advection_diffusion Build the Scharfetter-Gummel stabilized stiffness matrix for a diffusion-advection problem.
bim1a_advection_upwind Build the UW stabilized stiffness matrix for an advection problem.
bim1a_axisymmetric_advection_diffusion Build the Scharfetter-Gummel stabilized stiffness matrix for a diffusion-advection problem in cylindrical coordinates with axisymmetric configuration.
bim1a_axisymmetric_advection_upwind Build the Upwind stabilized stiffness matrix for an advection problem in cylindrical coordinates with axisymmetric configuration.
bim2a_advection_diffusion Build the Scharfetter-Gummel stabilized stiffness matrix for a diffusion-advection problem.
bim2a_advection_upwind Build the UW stabilized stiffness matrix for an advection problem.
bim2a_axisymmetric_advection_diffusion Build the Scharfetter-Gummel stabilized stiffness matrix for a diffusion-advection problem in cylindrical coordinates with axisymmetric configuration.
bim2a_axisymmetric_advection_upwind Build the Upwind stabilized stiffness matrix for an advection problem in cylindrical coordinates with axisymmetric configuration.
bim3a_advection_diffusion Build the Scharfetter-Gummel stabilized stiffness matrix for a diffusion-advection problem.
bim3a_osc_advection_diffusion Build the Scharfetter-Gummel stabilized OSC stiffness matrix for a diffusion-advection problem.
bim1a_laplacian Build the standard finite element stiffness matrix for a diffusion problem.
bim1a_axisymmetric_laplacian Build the standard finite element stiffness matrix for a diffusion problem in cylindrical coordinates with axisymmetric configuration.
bim2a_laplacian Build the standard finite element stiffness matrix for a diffusion problem.
bim2a_axisymmetric_laplacian Build the standard finite element stiffness matrix for a diffusion problem in cylindrical coordinates with axisymmetric configuration.
bim3a_laplacian Build the standard finite element stiffness matrix for a diffusion problem.
bim3a_osc_laplacian Build the osc finite element stiffness matrix for a diffusion problem.
bim1a_reaction Build the lumped finite element mass matrix for a diffusion problem.
bim1a_axisymmetric_reaction Build the lumped finite element mass matrix for a diffusion problem in cylindrical coordinates with axisymmetric configuration.
bim2a_reaction Build the lumped finite element mass matrix for a diffusion problem.
bim2a_axisymmetric_reaction Build the lumped finite element mass matrix for a diffusion problem in cylindrical coordinates with axisymmetric configuration.
bim3a_reaction Build the lumped finite element mass matrix for a diffusion problem.
bim1a_rhs Build the finite element right-hand side of a diffusion problem employing mass-lumping.
bim1a_axisymmetric_rhs Build the finite element right-hand side of a diffusion problem employing mass-lumping.
bim2a_rhs Build the finite element right-hand side of a diffusion problem employing mass-lumping.
bim2a_axisymmetric_rhs Build the finite element right-hand side of a diffusion problem in cylindrical coordinates with axisymmetric configuration employing mass-lumping.
bim3a_rhs Build the finite element right-hand side of a diffusion problem employing mass-lumping.
bim2a_boundary_mass Build the lumped boundary mass matrix needed to apply Robin boundary conditions.
bim2a_axisymmetric_boundary_mass Build the lumped boundary mass matrix needed to apply Robin and Neumann boundary conditions in a problem in cylindrical coordinates with axisymmetric configuration.
bim3a_boundary_mass Build the lumped boundary mass matrix needed to apply Robin boundary conditions.

Pre-processing and Post-processing computations

bim2c_mesh_properties Compute the properties of IMESH needed by BIM method and append them to OMESH as fields.
bim3c_mesh_properties Compute the properties of IMESH needed by BIM method and append them to OMESH as fields.
bim2c_unknowns_on_side Return the list of the mesh nodes that lie on the geometrical sides specified in SIDELIST.
bim3c_unknowns_on_faces Return the list of the mesh nodes that lie on the geometrical faces specified in FACELIST.
bim2c_pde_gradient Compute the gradient of the piecewise linear conforming scalar function U.
bim3c_pde_gradient Compute the gradient of the piecewise linear conforming scalar function U.
bim2c_global_flux Compute the flux associated with the Scharfetter-Gummel approximation of the scalar field U.
bim3c_global_flux Compute the flux associated with the Scharfetter-Gummel approximation of the scalar field U.
bim1c_elem_to_nodes Compute interpolated values at nodes U_NOD given values at element mid-points U_EL.
bim2c_tri_to_nodes Compute interpolated values at triangle nodes U_NOD given values at triangle mid-points U_TRI.
bim3c_tri_to_nodes Compute interpolated values at triangle nodes U_NOD given values at tetrahedral centers of mass U_TRI.
bim2c_intrp Compute interpolated values of multicomponent node centered field N_DATA and/or cell centered field N_DATA at an arbitrary set of points whose coordinates are given in the n_by_2 matrix POINTS.
bim3c_intrp Compute interpolated values of node centered multicomponent node centered field N_DATA and cell centered field N_DATA at an arbitrary set of points whos coordinates are given in the n_by_3 matrix POINTS.
bim1c_norm Compute the NORM_TYPE-norm of function U on the domain described by the triangular grid MESH.
bim2c_norm Compute the NORM_TYPE-norm of function U on the domain described by the triangular grid MESH.
bim3c_norm Compute the NORM_TYPE-norm of function U on the domain described by the tetrahedral grid MESH.

Utilities

bimu_bernoulli Compute the values of the Bernoulli function corresponding to X and - X arguments.
bimu_logm Input: − T1: − T2:
bim-1.1.8/inst/000077500000000000000000000000001502773057700132625ustar00rootroot00000000000000bim-1.1.8/inst/bim1a_advection_diffusion.m000066400000000000000000000077171502773057700205470ustar00rootroot00000000000000## Copyright (C) 2006,2007,2008,2009,2010 Carlo de Falco, Massimiliano Culpo ## ## This file is part of: ## BIM - Diffusion Advection Reaction PDE Solver ## ## BIM 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. ## ## BIM 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 BIM; If not, see . ## ## author: Carlo de Falco ## author: Massimiliano Culpo ## -*- texinfo -*- ## ## @deftypefn {Function File} @ ## {[@var{A}]} = @ ## bim1a_advection_diffusion(@var{mesh},@var{alpha},@var{gamma},@var{eta},@var{beta}) ## ## Build the Scharfetter-Gummel stabilized stiffness matrix for a ## diffusion-advection problem. ## ## The equation taken into account is: ## ## - div (@var{alpha} * @var{gamma} (@var{eta} grad (u) - @var{beta} u)) = f ## ## where @var{alpha} is an element-wise constant scalar function, ## @var{eta} and @var{gamma} are piecewise linear conforming scalar ## functions, @var{beta} is an element-wise constant vector function. ## ## Instead of passing the vector field @var{beta} directly one can pass ## a piecewise linear conforming scalar function @var{phi} as the last ## input. In such case @var{beta} = grad @var{phi} is assumed. ## ## If @var{phi} is a single scalar value @var{beta} is assumed to be 0 ## in the whole domain. ## ## @seealso{bim1a_rhs, bim1a_reaction, bim1a_laplacian, bim2a_advection_diffusion} ## @end deftypefn function A = bim1a_advection_diffusion (x,alpha,gamma,eta,beta) ## Check input if (nargin != 5) error ("bim1a_advection_diffusion: wrong number of input parameters."); elseif (! isvector (x)) error ("bim1a_advection_diffusion: first argument is not a valid vector."); endif nnodes = numel (x); nelem = nnodes - 1; ## Turn scalar input to a vector of appropriate size if (isscalar (alpha)) alpha = alpha * ones (nelem, 1); endif if (isscalar (gamma)) gamma = gamma * ones (nnodes, 1); endif if (isscalar (eta)) eta = eta * ones (nnodes, 1); endif if (! (isvector (alpha) && isvector (gamma) && isvector (eta))) error ("bim1a_advection_diffusion: coefficients are not valid vectors."); elseif (numel (alpha) != nelem) error ("bim1a_advection_diffusion: length of alpha is not equal to the number of elements."); elseif (numel (gamma) != nnodes) error ("bim1a_advection_diffusion: length of gamma is not equal to the number of nodes."); elseif (numel (eta) != nnodes) error ("bim1a_advection_diffusion: length of eta is not equal to the number of nodes."); endif areak = reshape (diff (x), [], 1); if (numel (beta) == 1) vk = 0; elseif (numel (beta) == nelem) vk = beta .* areak; elseif (numel (beta) == nnodes) vk = diff (beta); else error ("bim1a_advection_diffusion: coefficient beta has wrong dimensions."); endif gammaetak = bimu_logm ((gamma .* eta)(1:end-1), (gamma .* eta)(2:end)); veta = diff (eta); etak = bimu_logm (eta(1:end-1), eta(2:end)); ck = alpha .* gammaetak .* etak ./ areak; [bpk, bmk] = bimu_bernoulli ((vk - veta) ./ etak); dm1 = [-(ck.*bmk); NaN]; dp1 = [NaN; -(ck.*bpk)]; d0 = [(ck(1).*bmk(1)); ((ck.*bmk)(2:end) + (ck.*bpk)(1:end-1)); (ck(end).*bpk(end))]; A = spdiags([dm1, d0, dp1],-1:1,nnodes,nnodes); endfunction %!test %! x = linspace(0,1,101); %! A = bim1a_advection_diffusion(x,1,1,1,0); %! alpha = ones(100,1); %! gamma = ones(101,1); %! eta = gamma; %! B = bim1a_advection_diffusion(x,alpha,gamma,eta,0); %! assert(A,B) bim-1.1.8/inst/bim1a_advection_upwind.m000066400000000000000000000060751502773057700200630ustar00rootroot00000000000000## Copyright (C) 2010-2014 Carlo de Falco ## ## This file is part of: ## BIM - Diffusion Advection Reaction PDE Solver ## ## BIM 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. ## ## BIM 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 BIM; If not, see . ## ## author: Carlo de Falco ## author: Massimiliano Culpo ## author: Matteo Porro ## -*- texinfo -*- ## ## @deftypefn {Function File} @ ## {[@var{A}]} = bim1a_advection_upwind (@var{mesh}, @var{beta}) ## ## Build the UW stabilized stiffness matrix for an advection problem. ## ## The equation taken into account is: ## ## (@var{beta} u)' = f ## ## where @var{beta} is an element-wise constant. ## ## Instead of passing the vector field @var{beta} directly one can pass ## a piecewise linear conforming scalar function @var{phi} as the last ## input. In such case @var{beta} = grad @var{phi} is assumed. ## ## If @var{phi} is a single scalar value @var{beta} is assumed to be 0 ## in the whole domain. ## ## @seealso{bim1a_rhs, bim1a_reaction, bim1a_laplacian, bim2a_advection_diffusion} ## @end deftypefn function A = bim1a_advection_upwind (x, beta) ## Check input if nargin != 2 error("bim1a_advection_upwind: wrong number of input parameters."); endif nnodes = length(x); nelem = nnodes-1; if (length(beta) == 1) vk = zeros(nelem,1); elseif (length(beta) == nelem) vk = beta; elseif (length(beta) == nnodes) vk = diff(beta); else error("bim1a_advection_upwind: coefficient beta has wrong dimensions."); endif bmk = (vk+abs(vk))/2; bpk = -(vk-abs(vk))/2; dm1 = [-bmk; NaN]; dp1 = [NaN; -bpk]; d0 = [bmk(1); bmk(2:end) + bpk(1:end-1); bpk(end)]; A = spdiags([dm1, d0, dp1],-1:1,nnodes,nnodes); endfunction %!test %! n = 200; %! mesh = linspace(0,1,n+1)'; %! uex = @(r) - r.^2 + 1; %! Nnodes = numel(mesh); %! Nelements = Nnodes-1; %! D = 1; v = 1; sigma = 0; %! alpha = D*ones(Nelements,1); %! gamma = ones(Nnodes,1); %! eta = ones(Nnodes,1); %! beta = 1/D*v*ones(Nelements,1); %! delta = ones(Nelements,1); %! zeta = sigma*ones(Nnodes,1); %! f = @(r) 2*D - 2*v.*r + sigma*uex(r); %! rhs = bim1a_rhs(mesh, ones(Nelements,1), f(mesh)); %! S = bim1a_laplacian(mesh,alpha,gamma); %! A = bim1a_advection_upwind(mesh, beta); %! R = bim1a_reaction(mesh, delta, zeta); %! S += (A+R); %! u = zeros(Nnodes,1); u([1 end]) = uex(mesh([1 end])); %! u(2:end-1) = S(2:end-1,2:end-1)\(rhs(2:end-1) - S(2:end-1,[1 end])*u([1 end])); %! assert(u,uex(mesh),1e-3) bim-1.1.8/inst/bim1a_axisymmetric_advection_diffusion.m000066400000000000000000000151561502773057700233410ustar00rootroot00000000000000## Copyright (C) 2006-2014 Carlo de Falco, Massimiliano Culpo ## ## This file is part of: ## BIM - Diffusion Advection Reaction PDE Solver ## ## BIM 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. ## ## BIM 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 BIM; If not, see . ## ## author: Carlo de Falco ## author: Massimiliano Culpo ## author: Matteo Porro ## author: Emanuela Abbate ## -*- texinfo -*- ## ## @deftypefn {Function File} @ ## {[@var{A}]} = @ ## bim1a_axisymmetric_advection_diffusion(@var{mesh},@var{alpha},@var{gamma},@var{eta},@var{beta}) ## ## Build the Scharfetter-Gummel stabilized stiffness matrix for a ## diffusion-advection problem in cylindrical coordinates with axisymmetric ## configuration. Rotational symmetry is assumed with respect to be the vertical ## axis r=0. Only grids that DO NOT contain r=0 are admissible. ## ##@example ##@group ## | |-------| OK |-------| | OK |--|-----| NO! ## r=0 r=0 r=0 #@end group #@end example ## ## The equation taken into account is: ## ## - 1/r * d/dr (@var{alpha} * @var{gamma} (@var{eta} du/dr - @var{beta} u)) = f ## ## where @var{alpha} is an element-wise constant scalar function, ## @var{eta} and @var{gamma} are piecewise linear conforming scalar ## functions, @var{beta} is an element-wise constant vector function. ## ## Instead of passing the vector field @var{beta} directly one can pass ## a piecewise linear conforming scalar function @var{phi} as the last ## input. In such case @var{beta} = grad @var{phi} is assumed. ## ## If @var{phi} is a single scalar value @var{beta} is assumed to be 0 ## in the whole domain. ## ## @seealso{bim1a_axisymmetric_rhs, bim1a_axisymmetric_reaction, ## bim1a_axisymmetric_laplacian, bim2a_axisymmetric_advection_diffusion} ## @end deftypefn function A = bim1a_axisymmetric_advection_diffusion (x,alpha,gamma,eta,beta) ## Check input if nargin != 5 error("bim1a_axisymmetric_advection_diffusion: wrong number of input parameters."); elseif !isvector(x) error("bim1a_axisymmetric_advection_diffusion: first argument is not a valid vector."); endif nnodes = length(x); nelem = nnodes-1; ## Turn scalar input to a vector of appropriate size if isscalar(alpha) alpha = alpha*ones(nelem,1); endif if isscalar(gamma) gamma = gamma*ones(nnodes,1); endif if isscalar(eta) eta = eta*ones(nnodes,1); endif if !( isvector(alpha) && isvector(gamma) && isvector(eta) ) error("bim1a_axisymmetric_advection_diffusion: coefficients are not valid vectors."); elseif (length(alpha) != nelem) error("bim1a_axisymmetric_advection_diffusion: length of alpha is not equal to the number of elements."); elseif (length(gamma) != nnodes) error("bim1a_axisymmetric_advection_diffusion: length of gamma is not equal to the number of nodes."); elseif (length(eta) != nnodes) error("bim1a_axisymmetric_advection_diffusion: length of eta is not equal to the number of nodes."); endif areak = reshape(diff(x),[],1); cm = reshape((x(1:end-1)+x(2:end))/2,[],1); if (length(beta) == 1) vk = 0; elseif (length(beta) == nelem) vk = beta .* areak; elseif (length(beta) == nnodes) vk = diff(beta); else error("bim1a_axisymmetric_advection_diffusion: coefficient beta has wrong dimensions."); endif gammaetak = bimu_logm ( (gamma.*eta)(1:end-1), (gamma.*eta)(2:end)); veta = diff(eta); etak = bimu_logm ( eta(1:end-1), eta(2:end)); ck = alpha .* gammaetak .* etak ./ areak .* abs(cm); [bpk, bmk] = bimu_bernoulli( (vk - veta)./etak); dm1 = [-(ck.*bmk); NaN]; dp1 = [NaN; -(ck.*bpk)]; d0 = [(ck(1).*bmk(1)); ((ck.*bmk)(2:end) + (ck.*bpk)(1:end-1)); (ck(end).*bpk(end))]; A = spdiags([dm1, d0, dp1],-1:1,nnodes,nnodes); endfunction %!test %! n = 3; %! mesh = linspace(1,2,n+1)'; %! uex = @(r) exp(r); %! duexdr = @(r) uex(r); %! d2uexdr2 = @(r) uex(r); %! Nnodes = numel(mesh); %! Nelements = Nnodes-1; %! D = 1; v = 1; %! alpha = D*ones(Nelements,1); %! gamma = ones(Nnodes,1); %! eta = ones(Nnodes,1); %! beta = 1/D*v*ones(Nelements,1); %! f = @(r) -D./r.*duexdr(r) - D.*d2uexdr2(r) ... %! + v./r .* uex(r) + v * duexdr(r); %! rhs = bim1a_axisymmetric_rhs(mesh, ones(Nelements,1), f(mesh)); %! S = bim1a_axisymmetric_advection_diffusion(mesh,alpha,gamma,eta,beta); %! u = zeros(Nnodes,1); u([1,end]) = uex(mesh([1 end])); %! u(2:end-1) = S(2:end-1,2:end-1)\(rhs(2:end-1) - S(2:end-1,[1 end])*u([1 end])); %! assert(u,uex(mesh),1e-7) %!test %! n = 100; %! mesh = linspace(0,1,n+1)'; %! cm = (mesh(1:end-1) + mesh(2:end))/2; %! uex = @(r) - r.^2 + 1; %! Nnodes = numel(mesh); %! Nelements = Nnodes-1; %! D = 1; v = 0; %! alpha = D*ones(Nelements,1); %! gamma = ones(Nnodes,1); %! eta = ones(Nnodes,1); %! beta = v; %! f = @(r) 4*D; %! rhs = bim1a_axisymmetric_rhs(mesh, ones(Nelements,1), f(mesh)); %! S = bim1a_axisymmetric_advection_diffusion(mesh,alpha,gamma,eta,beta); %! u = zeros(Nnodes,1); u(end) = uex(mesh(end)); %! u(1:end-1) = S(1:end-1,1:end-1)\(rhs(1:end-1) - S(1:end-1,end)*u(end)); %! assert(u,uex(mesh),1e-3) %!test %! n = 100; %! mesh = linspace(0,1,n+1)'; %! cm = (mesh(1:end-1) + mesh(2:end))/2; %! uex = @(r) - r.^2 + 1; %! Nnodes = numel(mesh); %! Nelements = Nnodes-1; %! D = 1; v = cm; %! alpha = D*ones(Nelements,1); %! gamma = ones(Nnodes,1); %! eta = ones(Nnodes,1); %! beta = 1/D*v; %! f = @(r) 4*D + 2 - 4*r.^2; %! rhs = bim1a_axisymmetric_rhs(mesh, ones(Nelements,1), f(mesh)); %! S = bim1a_axisymmetric_advection_diffusion(mesh,alpha,gamma,eta,beta); %! u = zeros(Nnodes,1); u(end) = uex(mesh(end)); %! u(1:end-1) = S(1:end-1,1:end-1)\(rhs(1:end-1) - S(1:end-1,end)*u(end)); %! assert(u,uex(mesh),1e-3) %!test %! x = linspace(0,1,101); %! A = bim1a_axisymmetric_advection_diffusion(x,1,1,1,0); %! alpha = ones(100,1); %! gamma = ones(101,1); %! eta = gamma; %! B = bim1a_axisymmetric_advection_diffusion(x,alpha,gamma,eta,0); %! assert(A,B) bim-1.1.8/inst/bim1a_axisymmetric_advection_upwind.m000066400000000000000000000065721502773057700226630ustar00rootroot00000000000000## Copyright (C) 2010-2014 Carlo de Falco ## ## This file is part of: ## BIM - Diffusion Advection Reaction PDE Solver ## ## BIM 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. ## ## BIM 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 BIM; If not, see . ## ## author: Carlo de Falco ## author: Massimiliano Culpo ## author: Matteo porro ## author: Emanuela Abbate ## -*- texinfo -*- ## ## @deftypefn {Function File} @ ## {[@var{A}]} = bim1a_axisymmetric_advection_upwind (@var{mesh}, @var{beta}) ## ## Build the Upwind stabilized stiffness matrix for an advection problem ## in cylindrical coordinates with axisymmetric configuration. ## ## The equation taken into account is: ## ## 1/r * (r * @var{beta} u)' = f ## ## where @var{beta} is an element-wise constant. ## ## Instead of passing the vector field @var{beta} directly one can pass ## a piecewise linear conforming scalar function @var{phi} as the last ## input. In such case @var{beta} = grad @var{phi} is assumed. ## ## If @var{phi} is a single scalar value @var{beta} is assumed to be 0 ## in the whole domain. ## ## @seealso{bim1a_axisymmetric_advection_diffusion, bim1a_axisymmetric_rhs, ## bim1a_axisymmetric_reaction, bim1a_axisymmetric_laplacian} ## @end deftypefn function A = bim1a_axisymmetric_advection_upwind (x, beta) ## Check input if nargin != 2 error("bim1a_axisymmetric_advection_upwind: wrong number of input parameters."); endif nnodes = length(x); nelem = nnodes-1; cm = reshape((x(1:end-1)+x(2:end))/2,[],1); if (length(beta) == 1) vk = 0;#zeros(nelem,1); elseif (length(beta) == nelem) vk = beta; elseif (length(beta) == nnodes) vk = diff(beta); else error("bim1a_axisymmetric_advection_upwind: coefficient beta has wrong dimensions."); endif bmk = (vk+abs(vk))/2 .* abs(cm); bpk = -(vk-abs(vk))/2 .* abs(cm); dm1 = [-bmk; NaN]; dp1 = [NaN; -bpk]; d0 = [bmk(1); bmk(2:end) + bpk(1:end-1); bpk(end)]; A = spdiags([dm1, d0, dp1],-1:1,nnodes,nnodes); endfunction %!test %! nn = 20; %! mesh = linspace(1,2,nn+1)'; %! D = 1; v = 0; sigma = 0; %! uex = @(r) exp(r); %! duexdr = @(r) uex(r); %! d2uexdr2 = @(r) uex(r); %! f = @(r,z) -D./r.*duexdr(r) - D.*d2uexdr2(r) ... %! + v./r .* uex(r) + v * duexdr(r) ... %! + sigma * uex(r); %! uex_left = uex(mesh(1)); uex_right = uex(mesh(end)); %! Ar = bim1a_axisymmetric_laplacian (mesh, D, 1); %! Adv = bim1a_axisymmetric_advection_upwind (mesh, v*ones(nn,1)); %! R = bim1a_axisymmetric_reaction (mesh, sigma, 1); %! M = Ar + Adv + R; %! M(1,:) *= 0; M(1,1) = 1; %! M(end,:) *= 0; M(end, end) = 1; %! rhs = bim1a_axisymmetric_rhs (mesh, 1, f(mesh)); %! rhs(1) = uex_left; rhs(end) = uex_right; %! uh = M \ rhs; %! assert(uh, uex(mesh), 1e-3); bim-1.1.8/inst/bim1a_axisymmetric_laplacian.m000066400000000000000000000047011502773057700212350ustar00rootroot00000000000000## Copyright (C) 2006-2014 Carlo de Falco ## ## This file is part of: ## BIM - Diffusion Advection Reaction PDE Solver ## ## BIM 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. ## ## BIM 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 BIM; If not, see . ## ## author: Carlo de Falco ## author: Massimiliano Culpo ## author: Matteo Porro ## author: Emanuela Abbate ## -*- texinfo -*- ## ## @deftypefn {Function File} @ ## {@var{A}} = bim1a_axisymmetric_laplacian (@var{mesh},@var{epsilon},@var{kappa}) ## ## Build the standard finite element stiffness matrix for a diffusion ## problem in cylindrical coordinates with axisymmetric configuration. ## Rotational symmetry is assumed with respect to be the vertical ## axis r=0. Only grids that DO NOT contain r=0 are admissible. ## ##@example ##@group ## | |-------| OK |--|-----| NO! ## r=0 r=0 #@end group #@end example ## ## The equation taken into account is: ## ## - 1/r * (r * @var{epsilon} * @var{kappa} ( u' ))' = f ## ## where @var{epsilon} is an element-wise constant scalar function, ## while @var{kappa} is a piecewise linear conforming scalar function. ## ## @seealso{bim1a_axisymmetric_rhs, bim1a_axisymmetric_reaction, ## bim1a_axisymmetric_advection_diffusion, bim2a_laplacian, bim3a_laplacian} ## @end deftypefn function [A] = bim1a_axisymmetric_laplacian(mesh,epsilon,kappa) ## Check input if nargin != 3 error("bim1a_axisymmetric_laplacian: wrong number of input parameters."); elseif !isvector(mesh) error("bim1a_axisymmetric_laplacian: first argument is not a valid vector."); endif ## Input-type check inside bim1a_axisymmetric_advection_diffusion nnodes = length(mesh); nelem = nnodes - 1; A = bim1a_axisymmetric_advection_diffusion (mesh, epsilon, kappa, ones(nnodes,1), 0); endfunction bim-1.1.8/inst/bim1a_axisymmetric_reaction.m000066400000000000000000000107271502773057700211220ustar00rootroot00000000000000## Copyright (C) 2006-2014 Carlo de Falco ## ## This file is part of: ## BIM - Diffusion Advection Reaction PDE Solver ## ## BIM 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. ## ## BIM 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 BIM; If not, see . ## ## author: Carlo de Falco ## author: Massimiliano Culpo ## author: Matteo Porro ## author: Emanuela Abbate ## -*- texinfo -*- ## @deftypefn {Function File} {[@var{C}]} = @ ## bim1a_axisymmetric_reaction(@var{mesh},@var{delta},@var{zeta}) ## ## Build the lumped finite element mass matrix for a diffusion ## problem in cylindrical coordinates with axisymmetric configuration. ## ## The equation taken into account is: ## ## @var{delta} * @var{zeta} * u = f ## ## where @var{delta} is an element-wise constant scalar function, while ## @var{zeta} is a piecewise linear conforming scalar function. ## ## @seealso{bim1a_axisymmetric_rhs, bim1a_axisymmetric_advection_diffusion, bim1a_axisymmetric_laplacian, ## bim2a_reaction, bim3a_reaction} ## @end deftypefn function [C] = bim1a_axisymmetric_reaction(mesh,delta,zeta) ## Check input if nargin != 3 error("bim1a_axisymmetric_reaction: wrong number of input parameters."); elseif !isvector(mesh) error("bim1a_axisymmetric_reaction: first argument is not a valid vector."); endif mesh = reshape(mesh,[],1); nnodes = length(mesh); nelems = nnodes-1; ## Turn scalar input to a vector of appropriate size if isscalar(delta) delta = delta*ones(nelems,1); endif if isscalar(zeta) zeta = zeta*ones(nnodes,1); endif if !( isvector(delta) && isvector(zeta) ) error("bim1a_axisymmetric_reaction: coefficients are not valid vectors."); elseif length(delta) != nelems error("bim1a_axisymmetric_reaction: length of delta is not equal to the number of elements."); elseif length(zeta) != nnodes error("bim1a_axisymmetric_reaction: length of zeta is not equal to the number of nodes."); endif h = (mesh(2:end)-mesh(1:end-1)).*delta; d0 = zeta.*[h(1)/2; (h(1:end-1)+h(2:end))/2; h(end)/2]; C = spdiags(d0.*abs(mesh), 0, nnodes,nnodes); endfunction %!test %! n = 100; %! mesh = linspace(0,1,n+1)'; %! cm = (mesh(1:end-1) + mesh(2:end))/2; %! uex = @(r) - r.^2 + 1; %! Nnodes = numel(mesh); %! Nelements = Nnodes-1; %! D = 1; v = cm; sigma = 1; %! alpha = D*ones(Nelements,1); %! gamma = ones(Nnodes,1); %! eta = ones(Nnodes,1); %! beta = 0; %! delta = ones(Nelements,1); %! zeta = sigma*ones(Nnodes,1); %! f = @(r) 4*D + sigma*uex(r); %! rhs = bim1a_axisymmetric_rhs(mesh, ones(Nelements,1), f(mesh)); %! S = bim1a_axisymmetric_advection_diffusion(mesh,alpha,gamma,eta,beta); %! R = bim1a_axisymmetric_reaction(mesh, delta, zeta); %! S += R; %! u = zeros(Nnodes,1); u(end) = uex(mesh(end)); %! u(1:end-1) = S(1:end-1,1:end-1)\(rhs(1:end-1) - S(1:end-1,end)*u(end)); %! assert(u,uex(mesh),1e-3) %!test %! n = 100; %! mesh = linspace(0,1,n+1)'; %! cm = (mesh(1:end-1) + mesh(2:end))/2; %! uex = @(r) - r.^2 + 1; %! Nnodes = numel(mesh); %! Nelements = Nnodes-1; %! D = 1; v = cm; sigma = 1; %! alpha = D*ones(Nelements,1); %! gamma = ones(Nnodes,1); %! eta = ones(Nnodes,1); %! beta = 1/D*v; %! delta = ones(Nelements,1); %! zeta = sigma*ones(Nnodes,1); %! f = @(r) 4*D + 2 - 4*r.^2 + sigma*uex(r); %! rhs = bim1a_axisymmetric_rhs(mesh, ones(Nelements,1), f(mesh)); %! S = bim1a_axisymmetric_advection_diffusion(mesh,alpha,gamma,eta,beta); %! R = bim1a_axisymmetric_reaction(mesh, delta, zeta); %! S += R; %! u = zeros(Nnodes,1); u(end) = uex(mesh(end)); %! u(1:end-1) = S(1:end-1,1:end-1)\(rhs(1:end-1) - S(1:end-1,end)*u(end)); %! assert(u,uex(mesh),1e-3) %!test %! x = linspace(0,1,101); %! A = bim1a_axisymmetric_reaction(x,1,1); %! delta = ones(100,1); %! zeta = ones(101,1); %! B = bim1a_axisymmetric_reaction(x,delta,zeta); %! assert(A,B) bim-1.1.8/inst/bim1a_axisymmetric_rhs.m000066400000000000000000000052261502773057700201100ustar00rootroot00000000000000## Copyright (C) 2006-2014 Carlo de Falco ## ## This file is part of: ## BIM - Diffusion Advection Reaction PDE Solver ## ## BIM 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. ## ## BIM 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 BIM; If not, see . ## ## author: Carlo de Falco ## author: Massimiliano Culpo ## author: Matteo Porro ## author: Emanuela Abbate ## -*- texinfo -*- ## @deftypefn {Function File} {[@var{b}]} = @ ## bim1a_rhs(@var{mesh},@var{f}, @var{g}) ## ## Build the finite element right-hand side of a diffusion problem ## employing mass-lumping. ## ## The equation taken into account is: ## ## @var{delta} * u = f * g ## ## where @var{f} is an element-wise constant scalar function, while ## @var{g} is a piecewise linear conforming scalar function. ## ## @seealso{bim1a_reaction, bim1a_advection_diffusion, bim1a_laplacian, ## bim2a_reaction, bim3a_reaction} ## @end deftypefn function b = bim1a_axisymmetric_rhs(mesh,f,g) ## Check input if nargin != 3 error("bim1a_rad_rhs: wrong number of input parameters."); elseif !isvector(mesh) error("bim1a_rad_rhs: first argument is not a valid vector."); endif mesh = reshape(mesh,[],1); nnodes = length(mesh); nelem = nnodes-1; ## Turn scalar input to a vector of appropriate size if isscalar(f) f = f*ones(nelem,1); endif if isscalar(g) g = g*ones(nnodes,1); endif if !( isvector(f) && isvector(g) ) error("bim1a_rad_rhs: coefficients are not valid vectors."); elseif (length(f) != nelem && length(f) != 1) error("bim1a_rad_rhs: length of f is not equal to the number of elements."); elseif (length(g) != nnodes && length(g) != 1) error("bim1a_rad_rhs: length of g is not equal to the number of nodes."); endif h = (mesh(2:end)-mesh(1:end-1)).*f; b = g.*[h(1)/2; (h(1:end-1)+h(2:end))/2; h(end)/2] .* abs(mesh); endfunction %!test %! x = linspace(0,1,101); %! A = bim1a_axisymmetric_rhs(x,1,1); %! delta = ones(100,1); %! zeta = ones(101,1); %! B = bim1a_axisymmetric_rhs(x,delta,zeta); %! assert(A,B) bim-1.1.8/inst/bim1a_laplacian.m000066400000000000000000000036321502773057700164410ustar00rootroot00000000000000## Copyright (C) 2006,2007,2008,2009,2010 Carlo de Falco, Massimiliano Culpo ## ## This file is part of: ## BIM - Diffusion Advection Reaction PDE Solver ## ## BIM 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. ## ## BIM 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 BIM; If not, see . ## ## author: Carlo de Falco ## author: Massimiliano Culpo ## -*- texinfo -*- ## ## @deftypefn {Function File} @ ## {@var{A}} = bim1a_laplacian (@var{mesh},@var{epsilon},@var{kappa}) ## ## Build the standard finite element stiffness matrix for a diffusion ## problem. ## ## The equation taken into account is: ## ## - (@var{epsilon} * @var{kappa} ( u' ))' = f ## ## where @var{epsilon} is an element-wise constant scalar function, ## while @var{kappa} is a piecewise linear conforming scalar function. ## ## @seealso{bim1a_rhs, bim1a_reaction, bim1a_advection_diffusion, ## bim2a_laplacian, bim3a_laplacian} ## @end deftypefn function [A] = bim1a_laplacian(mesh,epsilon,kappa) ## Check input if nargin != 3 error("bim1a_laplacian: wrong number of input parameters."); elseif !isvector(mesh) error("bim1a_laplacian: first argument is not a valid vector."); endif ## Input-type check inside bim1a_advection_diffusion nnodes = numel (mesh); nelem = nnodes - 1; A = bim1a_advection_diffusion (mesh, epsilon, kappa, ones(nnodes,1), 0); endfunction bim-1.1.8/inst/bim1a_reaction.m000066400000000000000000000051371502773057700163230ustar00rootroot00000000000000## Copyright (C) 2006,2007,2008,2009,2010 Carlo de Falco, Massimiliano Culpo ## ## This file is part of: ## BIM - Diffusion Advection Reaction PDE Solver ## ## BIM 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. ## ## BIM 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 BIM; If not, see . ## ## author: Carlo de Falco ## author: Massimiliano Culpo ## -*- texinfo -*- ## @deftypefn {Function File} {[@var{C}]} = @ ## bim1a_reaction(@var{mesh},@var{delta},@var{zeta}) ## ## Build the lumped finite element mass matrix for a diffusion ## problem. ## ## The equation taken into account is: ## ## @var{delta} * @var{zeta} * u = f ## ## where @var{delta} is an element-wise constant scalar function, while ## @var{zeta} is a piecewise linear conforming scalar function. ## ## @seealso{bim1a_rhs, bim1a_advection_diffusion, bim1a_laplacian, ## bim2a_reaction, bim3a_reaction} ## @end deftypefn function [C] = bim1a_reaction(mesh,delta,zeta) ## Check input if nargin != 3 error("bim1a_reaction: wrong number of input parameters."); elseif !isvector(mesh) error("bim1a_reaction: first argument is not a valid vector."); endif mesh = reshape (mesh, [], 1); nnodes = numel (mesh); nelems = nnodes - 1; ## Turn scalar input to a vector of appropriate size if isscalar(delta) delta = delta*ones(nelems,1); endif if isscalar(zeta) zeta = zeta*ones(nnodes,1); endif if !( isvector(delta) && isvector(zeta) ) error("bim1a_reaction: coefficients are not valid vectors."); elseif numel (delta) != nelems error("bim1a_reaction: length of delta is not equal to the number of elements."); elseif numel (zeta) != nnodes error("bim1a_reaction: length of zeta is not equal to the number of nodes."); endif h = (mesh(2:end)-mesh(1:end-1)).*delta; d0 = zeta.*[h(1)/2; (h(1:end-1)+h(2:end))/2; h(end)/2]; C = spdiags(d0, 0, nnodes,nnodes); endfunction %!test %! x = linspace(0,1,101); %! A = bim1a_reaction(x,1,1); %! delta = ones(100,1); %! zeta = ones(101,1); %! B = bim1a_reaction(x,delta,zeta); %! assert(A,B) bim-1.1.8/inst/bim1a_rhs.m000066400000000000000000000047511502773057700153140ustar00rootroot00000000000000## Copyright (C) 2006,2007,2008,2009,2010 Carlo de Falco, Massimiliano Culpo ## ## This file is part of: ## BIM - Diffusion Advection Reaction PDE Solver ## ## BIM 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. ## ## BIM 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 BIM; If not, see . ## ## author: Carlo de Falco ## author: Massimiliano Culpo ## -*- texinfo -*- ## @deftypefn {Function File} {[@var{b}]} = @ ## bim1a_rhs(@var{mesh},@var{f}, @var{g}) ## ## Build the finite element right-hand side of a diffusion problem ## employing mass-lumping. ## ## The equation taken into account is: ## ## @var{delta} * u = f * g ## ## where @var{f} is an element-wise constant scalar function, while ## @var{g} is a piecewise linear conforming scalar function. ## ## @seealso{bim1a_reaction, bim1a_advection_diffusion, bim1a_laplacian, ## bim2a_reaction, bim3a_reaction} ## @end deftypefn function b = bim1a_rhs(mesh,f,g) ## Check input if nargin != 3 error("bim1a_rhs: wrong number of input parameters."); elseif !isvector(mesh) error("bim1a_rhs: first argument is not a valid vector."); endif mesh = reshape(mesh,[],1); nnodes = numel (mesh); nelem = nnodes-1; ## Turn scalar input to a vector of appropriate size if isscalar(f) f = f*ones(nelem,1); endif if isscalar(g) g = g*ones(nnodes,1); endif if !( isvector(f) && isvector(g) ) error("bim1a_rhs: coefficients are not valid vectors."); elseif (numel (f) != nelem && numel (f) != 1) error("bim1a_rhs: length of f is not equal to the number of elements."); elseif (numel (g) != nnodes && numel (g) != 1) error("bim1a_rhs: length of g is not equal to the number of nodes."); endif h = (mesh(2:end)-mesh(1:end-1)).*f; b = g.*[h(1)/2; (h(1:end-1)+h(2:end))/2; h(end)/2]; endfunction %!test %! x = linspace(0,1,101); %! A = bim1a_rhs(x,1,1); %! delta = ones(100,1); %! zeta = ones(101,1); %! B = bim1a_rhs(x,delta,zeta); %! assert(A,B) bim-1.1.8/inst/bim1c_elem_to_nodes.m000066400000000000000000000054121502773057700173310ustar00rootroot00000000000000## Copyright (C) 2013 Carlo de Falco ## ## This program is free software; you can redistribute it and/or modify ## it under the terms of the GNU General Public License as published by ## the Free Software Foundation; either version 3 of the License, or ## (at your option) any later version. ## ## This program is distributed in the hope that it will be useful, ## but WITHOUT ANY WARRANTY; without even the implied warranty of ## MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the ## GNU General Public License for more details. ## ## You should have received a copy of the GNU General Public License ## along with Octave; see the file COPYING. If not, see ## . ## -*- texinfo -*- ## ## @deftypefn {Function File} {@var{u_nod}} = bim1c_elem_to_nodes (@var{mesh}, @var{u_el}) ## @deftypefnx {Function File} {@var{u_nod}} = bim1c_elem_to_nodes (@var{m_el}, @var{u_el}) ## @deftypefnx {Function File} {[@var{u_nod}, @var{m_el}]} = bim1c_elem_to_nodes ( ... ) ## ## Compute interpolated values at nodes @var{u_nod} given values at element mid-points @var{u_el}. ## If called with more than one output, also return the interpolation matrix @var{m_el} such that ## @code{u_nod = m_el * u_el}. ## If repeatedly performing interpolation on the same mesh the matrix @var{m_el} obtained by a previous call ## to @code{bim1c_elem_to_nodes} may be passed as input to avoid unnecessary computations. ## ## @end deftypefn ## Author: Carlo de Falco ## Author: Matteo Porro ## Created: 2013-11-04 function [u_nod, m_el] = bim1c_elem_to_nodes (m, u_el) if (nargout > 1 ) if (isvector (m)) nel = numel (m) - 1; nnod = numel (m); m_el = spalloc (nnod, nel, 2 * nel); h = diff (m); for iel = 1:nel m_el([iel, iel+1], iel) = h(iel); endfor m_el = diag (sum (m_el, 2)) \ m_el; elseif (ismatrix (m)) m_el = m; else error (["bim1c_elem_to_nodes: first input ", ... "parameter is of incorrect type"]); endif u_nod = m_el * u_el; else if (isvector (m)) rhs = bim1a_rhs (m, u_el, 1); mass = bim1a_reaction (m, 1, 1); u_nod = full (mass \ rhs); elseif (ismatrix (m)) u_nod = m * u_el; else error (["bim1c_elem_to_nodes: first input ", ... "parameter is of incorrect type"]); endif endif endfunction %!test %! n = 10; msh = linspace (0, 1, n+1); %! nel = n; %! nnod = n+1; %! u_el = randn (nel, 1); %! un1 = bim1c_elem_to_nodes (msh, u_el); %! [un2, m] = bim1c_elem_to_nodes (msh, u_el); %! un3 = bim1c_elem_to_nodes (m, u_el); %! [un4, m] = bim1c_elem_to_nodes (m, u_el); %! assert (un1, un2, 1e-10) %! assert (un1, un3, 1e-10) %! assert (un1, un4, 1e-10) bim-1.1.8/inst/bim1c_norm.m000066400000000000000000000072321502773057700154720ustar00rootroot00000000000000## Copyright (C) 2006-2013 Carlo de Falco ## ## This file is part of: ## BIM - Diffusion Advection Reaction PDE Solver ## ## BIM 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. ## ## BIM 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 BIM; If not, see . ## ## author: Carlo de Falco ## author: Matteo Porro ## -*- texinfo -*- ## ## @deftypefn {Function File} {[@var{norm_u}]} = @ ## bim1c_norm(@var{mesh},@var{u},@var{norm_type}) ## ## Compute the @var{norm_type}-norm of function @var{u} on the domain described ## by the triangular grid @var{mesh}. ## ## The input function @var{u} can be either a piecewise linear conforming scalar ## function or an elementwise constant scalar or vector function. ## ## The string parameter @var{norm_type} can be one among 'L2', 'H1' and 'inf'. ## ## Should the input function be piecewise constant, the H1 norm will not be ## computed and the function will return an error message. ## ## @seealso{bim2c_norm, bim3c_norm} ## ## @end deftypefn function [norm_u] = bim1c_norm (m, u, norm_type) ## Check input if (nargin != 3) error ("bim1c_norm: wrong number of input parameters."); elseif (! isvector (m)) error ("bim1c_norm: first input is not a valid mesh."); endif nnodes = numel (m); nel = numel (m) - 1; if (isrow (u)) u = u'; endif if (isrow (m)) m = m'; endif if ((numel (u) != nnodes) && (numel (u) != nel)) error ("bim1c_norm: numel(u) != nnodes and numel(u) != nel."); endif if (! (strcmp (norm_type, 'L2') || strcmp (norm_type, 'inf') || strcmp (norm_type, 'H1'))) error ("bim1c_norm: invalid norm type parameter."); endif if (strcmp (norm_type,'inf')) norm_u = max (abs (u)); else if (numel (u) == nnodes) M = __mass_matrix__ (m); if (strcmp (norm_type, 'H1')) A = bim1a_laplacian (m, 1, 1); M += A; endif norm_u = sqrt(u' * M * u); else if (strcmp (norm_type, 'H1')) error (["bim1c_norm: cannot compute the ", ... "H1 norm of an elementwise constant function."]); endif norm_u = diff(m)' * u.^2; norm_u = sqrt (norm_u); endif endif endfunction function M = __mass_matrix__ (m) nnodes = numel(m); h = diff(m); d0 = 1/3*[h(1); h(1:end-1)+h(2:end); h(end)]; d1 = [0; 1/6*h]; dm1 = [1/6*h; 0]; M = spdiags([dm1 d0 d1], -1:1, nnodes, nnodes); endfunction %!test %!shared L, V, m %! L = rand (1); V = rand (1); m = linspace (0,1,5).^2; m *= L; %! u = V * ones (size (m))'; %! uinf = bim1c_norm (m, u, 'inf'); %! uL2 = bim1c_norm (m, u, 'L2'); %! uH1 = bim1c_norm (m, u, 'H1'); %! assert ([uinf, uL2, uH1], [V, V*sqrt(L), V*sqrt(L)], sqrt(eps)); %!test %! u = V * m'; %! uinf = bim1c_norm (m, u, 'inf'); %! uL2 = bim1c_norm (m, u, 'L2'); %! uH1 = bim1c_norm (m, u, 'H1'); %! assert ([uinf, uL2, uH1], %! [L*V, V*sqrt(L^3/3), V*sqrt(L^3/3 + L)], %! 1e-12); %!test %! u = V * ones (size (diff (m)))'; %! uinf = bim1c_norm (m, u, 'inf'); %! uL2 = bim1c_norm (m, u, 'L2'); %! assert ([uinf, uL2], [V, V*sqrt(L)], 1e-12); bim-1.1.8/inst/bim2a_advection_diffusion.m000066400000000000000000000275211502773057700205430ustar00rootroot00000000000000## Copyright (C) 2006,2007,2008,2009,2010 Carlo de Falco, Massimiliano Culpo ## ## This file is part of: ## BIM - Diffusion Advection Reaction PDE Solver ## ## BIM 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. ## ## BIM 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 BIM; If not, see . ## ## author: Carlo de Falco ## author: Massimiliano Culpo ## -*- texinfo -*- ## ## @deftypefn {Function File} @ ## {[@var{A}]} = @ ## bim2a_advection_diffusion(@var{mesh},@var{alpha},@var{gamma},@var{eta},@var{beta}) ## ## Build the Scharfetter-Gummel stabilized stiffness matrix for a ## diffusion-advection problem. ## ## The equation taken into account is: ## ## - div (@var{alpha} * @var{gamma} (@var{eta} grad (u) - @var{beta} u )) = f ## ## where @var{alpha} is an element-wise constant scalar function, ## @var{eta} and @var{gamma} are piecewise linear conforming scalar ## functions, @var{beta} is an element-wise constant vector function. ## ## Instead of passing the vector field @var{beta} directly one can pass ## a piecewise linear conforming scalar function @var{phi} as the last ## input. In such case @var{beta} = grad @var{phi} is assumed. ## ## If @var{phi} is a single scalar value @var{beta} is assumed to be 0 ## in the whole domain. ## ## Example: ## @example ## mesh = msh2m_structured_mesh([0:1/3:1],[0:1/3:1],1,1:4); ## mesh = bim2c_mesh_properties(mesh); ## x = mesh.p(1,:)'; ## ## Dnodes = bim2c_unknowns_on_side(mesh,[2,4]); ## Nnodes = columns(mesh.p); ## Nelements = columns(mesh.t); ## Varnodes = setdiff(1:Nnodes,Dnodes); ## ## alpha = ones(Nelements,1); ## eta = .1*ones(Nnodes,1); ## beta = [ones(1,Nelements);zeros(1,Nelements)]; ## gamma = ones(Nnodes,1); ## f = bim2a_rhs(mesh,ones(Nnodes,1),ones(Nelements,1)); ## ## S = bim2a_advection_diffusion(mesh,alpha,gamma,eta,beta); ## u = zeros(Nnodes,1); ## uex = x - (exp(10*x)-1)/(exp(10)-1); ## ## u(Varnodes) = S(Varnodes,Varnodes)\f(Varnodes); ## ## assert(u,uex,1e-7) ## @end example ## ## @seealso{bim2a_rhs, bim2a_reaction, bim2c_mesh_properties} ## @end deftypefn function [A] = bim2a_advection_diffusion (mesh, alpha, gamma, eta, beta) ## Check input if nargin != 5 error("bim2a_advection_diffusion: wrong number of input parameters."); elseif !(isstruct(mesh) && isfield(mesh,"p") && isfield (mesh,"t") && isfield(mesh,"e")) error("bim2a_advection_diffusion: first input is not a valid mesh structure."); endif nnodes = columns(mesh.p); nelem = columns(mesh.t); ## Turn scalar input to a vector of appropriate size if isscalar(alpha) alpha = alpha*ones(nelem,1); endif if isscalar(gamma) gamma = gamma*ones(nnodes,1); endif if isscalar(eta) eta = eta*ones(nnodes,1); endif if !( isvector(alpha) && isvector(gamma) && isvector(eta) ) error("bim2a_advection_diffusion: coefficients are not valid vectors."); elseif (numel (alpha) != nelem) error("bim2a_advection_diffusion: length of alpha is not equal to the number of elements."); elseif (numel (gamma) != nnodes) error("bim2a_advection_diffusion: length of gamma is not equal to the number of nodes."); elseif (numel (eta) != nnodes) error("bim2a_advection_diffusion: length of eta is not equal to the number of nodes."); endif alphaareak = reshape (alpha.*mesh.area,1,1,nelem); shg = mesh.shg(:,:,:); ## Build local Laplacian matrix Lloc = zeros(3,3,nelem); for inode = 1:3 for jnode = 1:3 ginode(inode,jnode,:) = mesh.t(inode,:); gjnode(inode,jnode,:) = mesh.t(jnode,:); Lloc(inode,jnode,:) = sum( shg(:,inode,:) .* shg(:,jnode,:),1) .* alphaareak; endfor endfor x = mesh.p(1,:); x = x(mesh.t(1:3,:)); y = mesh.p(2,:); y = y(mesh.t(1:3,:)); if all(size(beta)==1) v12 = 0; v23 = 0; v31 = 0; elseif all(size(beta)==[2,nelem]) v12 = beta(1,:) .* (x(2,:)-x(1,:)) + beta(2,:) .* (y(2,:)-y(1,:)); v23 = beta(1,:) .* (x(3,:)-x(2,:)) + beta(2,:) .* (y(3,:)-y(2,:)); v31 = beta(1,:) .* (x(1,:)-x(3,:)) + beta(2,:) .* (y(1,:)-y(3,:)); elseif all(size(beta)==[nnodes,1]) betaloc = beta(mesh.t(1:3,:)); v12 = betaloc(2,:)-betaloc(1,:); v23 = betaloc(3,:)-betaloc(2,:); v31 = betaloc(1,:)-betaloc(3,:); else error("bim2a_advection_diffusion: coefficient beta has wrong dimensions."); endif etaloc = eta(mesh.t(1:3,:)); eta12 = etaloc(2,:) - etaloc(1,:); eta23 = etaloc(3,:) - etaloc(2,:); eta31 = etaloc(1,:) - etaloc(3,:); etalocm1 = bimu_logm(etaloc(2,:),etaloc(3,:)); etalocm2 = bimu_logm(etaloc(3,:),etaloc(1,:)); etalocm3 = bimu_logm(etaloc(1,:),etaloc(2,:)); gammaloc = gamma(mesh.t(1:3,:)); geloc = gammaloc.*etaloc; gelocm1 = bimu_logm (geloc(2,:), geloc(3,:)); gelocm2 = bimu_logm (geloc(3,:), geloc(1,:)); gelocm3 = bimu_logm (geloc(1,:), geloc(2,:)); [bp12,bm12] = bimu_bernoulli ((v12 - eta12) ./ etalocm3); [bp23,bm23] = bimu_bernoulli ((v23 - eta23) ./ etalocm1); [bp31,bm31] = bimu_bernoulli ((v31 - eta31) ./ etalocm2); bp12 = reshape(gelocm3.*etalocm3.*bp12,1,1,nelem).*Lloc(1,2,:); bm12 = reshape(gelocm3.*etalocm3.*bm12,1,1,nelem).*Lloc(1,2,:); bp23 = reshape(gelocm1.*etalocm1.*bp23,1,1,nelem).*Lloc(2,3,:); bm23 = reshape(gelocm1.*etalocm1.*bm23,1,1,nelem).*Lloc(2,3,:); bp31 = reshape(gelocm2.*etalocm2.*bp31,1,1,nelem).*Lloc(3,1,:); bm31 = reshape(gelocm2.*etalocm2.*bm31,1,1,nelem).*Lloc(3,1,:); Sloc(1,1,:) = (-bm12-bp31)./reshape(etaloc(1,:),1,1,nelem); Sloc(1,2,:) = bp12./reshape(etaloc(2,:),1,1,nelem); Sloc(1,3,:) = bm31./reshape(etaloc(3,:),1,1,nelem); Sloc(2,1,:) = bm12./reshape(etaloc(1,:),1,1,nelem); Sloc(2,2,:) = (-bp12-bm23)./reshape(etaloc(2,:),1,1,nelem); Sloc(2,3,:) = bp23./reshape(etaloc(3,:),1,1,nelem); Sloc(3,1,:) = bp31./reshape(etaloc(1,:),1,1,nelem); Sloc(3,2,:) = bm23./reshape(etaloc(2,:),1,1,nelem); Sloc(3,3,:) = (-bm31-bp23)./reshape(etaloc(3,:),1,1,nelem); A = sparse(ginode(:),gjnode(:),Sloc(:)); endfunction %!test %! [mesh] = msh2m_structured_mesh([0:1/3:1],[0:1/3:1],1,1:4); %! mesh = bim2c_mesh_properties(mesh); %! x = mesh.p(1,:)'; %! Dnodes = bim2c_unknowns_on_side(mesh,[2,4]); %! Nnodes = columns(mesh.p); %! Nelements = columns(mesh.t); %! Varnodes = setdiff(1:Nnodes,Dnodes); %! alpha = ones(Nelements,1); %! eta = .1*ones(Nnodes,1); %! beta = [ones(1,Nelements);zeros(1,Nelements)]; %! gamma = ones(Nnodes,1); %! f = bim2a_rhs(mesh,ones(Nelements,1),ones(Nnodes,1)); %! S = bim2a_advection_diffusion(mesh,alpha,gamma,eta,beta); %! u = zeros(Nnodes,1); %! u(Varnodes) = S(Varnodes,Varnodes)\f(Varnodes); %! uex = x - (exp(10*x)-1)/(exp(10)-1); %! assert(u,uex,1e-7) %!test %! [mesh] = msh2m_structured_mesh([0:1/3:1],[0:1/3:1],1,1:4); %! mesh = bim2c_mesh_properties(mesh); %! x = mesh.p(1,:)'; %! Dnodes = bim2c_unknowns_on_side(mesh,[2,4]); %! Nnodes = columns(mesh.p); Nelements = columns(mesh.t); %! Varnodes = setdiff(1:Nnodes,Dnodes); %! alpha = ones(Nelements,1); %! eta = .1*ones(Nnodes,1); %! beta = x; %! gamma = ones(Nnodes,1); %! f = bim2a_rhs(mesh,ones(Nelements,1),ones(Nnodes,1)); %! S = bim2a_advection_diffusion(mesh,alpha,gamma,eta,beta); %! u = zeros(Nnodes,1); %! u(Varnodes) = S(Varnodes,Varnodes)\f(Varnodes); %! uex = x - (exp(10*x)-1)/(exp(10)-1); %! assert(u,uex,1e-7) %!test %! [mesh] = msh2m_structured_mesh([0:1/3:1],[0:1/3:1],1,1:4); %! mesh = bim2c_mesh_properties(mesh); %! x = mesh.p(1,:)'; %! Dnodes = bim2c_unknowns_on_side(mesh,[2,4]); %! Nnodes = columns(mesh.p); Nelements = columns(mesh.t); %! Varnodes = setdiff(1:Nnodes,Dnodes); %! alpha = 10*ones(Nelements,1); %! eta = .01*ones(Nnodes,1); %! beta = x/10; %! gamma = ones(Nnodes,1); %! f = bim2a_rhs(mesh,ones(Nelements,1),ones(Nnodes,1)); %! S = bim2a_advection_diffusion(mesh,alpha,gamma,eta,beta); %! u = zeros(Nnodes,1); %! u(Varnodes) = S(Varnodes,Varnodes)\f(Varnodes); %! uex = x - (exp(10*x)-1)/(exp(10)-1); %! assert(u,uex,1e-7) %!test %! [mesh] = msh2m_structured_mesh([0:1/3:1],[0:1/3:1],1,1:4); %! mesh = bim2c_mesh_properties(mesh); %! x = mesh.p(1,:)'; %! Dnodes = bim2c_unknowns_on_side(mesh,[2,4]); %! Nnodes = columns(mesh.p); Nelements = columns(mesh.t); %! Varnodes = setdiff(1:Nnodes,Dnodes); %! alpha = 10*ones(Nelements,1); eta = .001*ones(Nnodes,1); %! beta = x/100; %! gamma = 10*ones(Nnodes,1); %! f = bim2a_rhs(mesh,ones(Nelements,1),ones(Nnodes,1)); %! S = bim2a_advection_diffusion(mesh,alpha,gamma,eta,beta); %! u = zeros(Nnodes,1); %! u(Varnodes) = S(Varnodes,Varnodes)\f(Varnodes); %! uex = x - (exp(10*x)-1)/(exp(10)-1); %! assert(u,uex,1e-7) %!test %! [mesh] = msh2m_structured_mesh([0:1/1e3:1],[0:1/2:1],1,1:4); %! mesh = bim2c_mesh_properties(mesh); %! x = mesh.p(1,:)'; %! Dnodes = bim2c_unknowns_on_side(mesh,[2,4]); %! Nnodes = columns(mesh.p); Nelements = columns(mesh.t); %! Varnodes = setdiff(1:Nnodes,Dnodes); %! alpha = 3*ones(Nelements,1); eta = x+1; %! beta = [ones(1,Nelements);zeros(1,Nelements)]; %! gamma = 2*x; %! ff = 2*(6*x.^2+6*x) - (6*x+6).*(1-2*x)+6*(x-x.^2); %! f = bim2a_rhs(mesh,ones(Nelements,1),ff); %! S = bim2a_advection_diffusion(mesh,alpha,gamma,eta,beta); %! u = zeros(Nnodes,1); %! u(Varnodes) = S(Varnodes,Varnodes)\f(Varnodes); %! uex = x - x.^2; %! assert(u,uex,5e-3) %!test %! [mesh] = msh2m_structured_mesh([0:1/1e3:1],[0:1/2:1],1,1:4); %! mesh = bim2c_mesh_properties(mesh); %! x = mesh.p(1,:)'; %! Dnodes = bim2c_unknowns_on_side(mesh,[2,4]); %! Nnodes = columns(mesh.p); Nelements = columns(mesh.t); %! Varnodes = setdiff(1:Nnodes,Dnodes); %! alpha = ones(Nelements,1); eta = ones(Nnodes,1); %! beta = 0; %! gamma = x+1; %! ff = 4*x+1; %! f = bim2a_rhs(mesh,ones(Nelements,1),ff); %! S = bim2a_advection_diffusion(mesh,alpha,gamma,eta,beta); %! u = zeros(Nnodes,1); %! u(Varnodes) = S(Varnodes,Varnodes)\f(Varnodes); %! uex = x - x.^2; %! assert(u,uex,1e-7) %!test %! [mesh] = msh2m_structured_mesh([0:.1:1],[0:.1:1],1,1:4); %! mesh = bim2c_mesh_properties(mesh); %! x = mesh.p(1,:)';y = mesh.p(2,:)'; %! Dnodes = bim2c_unknowns_on_side(mesh,[1:4]); %! Nnodes = columns(mesh.p); Nelements = columns(mesh.t); %! Varnodes = setdiff(1:Nnodes,Dnodes); %! alpha = ones(Nelements,1); diff = 1e-2; eta=diff*ones(Nnodes,1); %! beta =[ones(1,Nelements);ones(1,Nelements)]; %! gamma = x*0+1; %! ux = y.*(1-exp((y-1)/diff)) .* (1-exp((x-1)/diff)-x.*exp((x-1)/diff)/diff); %! uy = x.*(1-exp((x-1)/diff)) .* (1-exp((y-1)/diff)-y.*exp((y-1)/diff)/diff); %! uxx = y.*(1-exp((y-1)/diff)) .* (-2*exp((x-1)/diff)/diff-x.*exp((x-1)/diff)/(diff^2)); %! uyy = x.*(1-exp((x-1)/diff)) .* (-2*exp((y-1)/diff)/diff-y.*exp((y-1)/diff)/(diff^2)); %! ff = -diff*(uxx+uyy)+ux+uy; %! f = bim2a_rhs(mesh,ones(Nelements,1),ff); %! S = bim2a_advection_diffusion(mesh,alpha,gamma,eta,beta); %! u = zeros(Nnodes,1); %! u(Varnodes) = S(Varnodes,Varnodes)\f(Varnodes); %! uex = x.*y.*(1-exp((x-1)/diff)).*(1-exp((y-1)/diff)); %! assert(u,uex,1e-7) %!test %! [mesh] = msh2m_structured_mesh([0:.1:1],[0:.1:1],1,1:4); %! mesh = bim2c_mesh_properties(mesh); %! x = mesh.p(1,:)'; y = mesh.p(2,:)'; %! Dnodes = bim2c_unknowns_on_side(mesh,[1:4]); %! Nnodes = columns(mesh.p); Nelements = columns(mesh.t); %! alpha = ones(Nelements,1); eta=ones(Nnodes,1); %! beta = 0; %! gamma = ones(Nnodes,1); %! A = bim2a_advection_diffusion(mesh,1,1,1,0); %! B = bim2a_advection_diffusion(mesh,alpha,gamma,eta,beta); %! assert(A,B) bim-1.1.8/inst/bim2a_advection_upwind.m000066400000000000000000000075321502773057700200630ustar00rootroot00000000000000## Copyright (C) 2006,2007,2008,2009,2010 Carlo de Falco, Massimiliano Culpo ## ## This file is part of: ## BIM - Diffusion Advection Reaction PDE Solver ## ## BIM 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. ## ## BIM 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 BIM; If not, see . ## ## author: Carlo de Falco ## author: Massimiliano Culpo ## -*- texinfo -*- ## ## @deftypefn {Function File} @ ## {[@var{A}]} = @ ## bim2a_advection_upwind (@var{mesh}, @var{beta}) ## ## Build the UW stabilized stiffness matrix for an advection problem. ## ## The equation taken into account is: ## ## div (@var{beta} u) = f ## ## where @var{beta} is an element-wise constant vector function. ## ## Instead of passing the vector field @var{beta} directly one can pass ## a piecewise linear conforming scalar function @var{phi} as the last ## input. In such case @var{beta} = grad @var{phi} is assumed. ## ## If @var{phi} is a single scalar value @var{beta} is assumed to be 0 ## in the whole domain. ## ## @seealso{bim2a_rhs, bim2a_reaction, bim2c_mesh_properties} ## @end deftypefn function A = bim2a_advection_upwind (mesh, beta) ## Check input if nargin != 2 error("bim2a_advection_upwind: wrong number of input parameters."); elseif !(isstruct(mesh) && isfield(mesh,"p") && isfield (mesh,"t") && isfield(mesh,"e")) error("bim2a_advection_upwind: first input is not a valid mesh structure."); endif nnodes = columns(mesh.p); nelem = columns(mesh.t); alphaareak = reshape (mesh.area, 1, 1, nelem); shg = mesh.shg(:,:,:); ## Build local Laplacian matrix Lloc = zeros(3,3,nelem); for inode = 1:3 for jnode = 1:3 ginode(inode,jnode,:) = mesh.t(inode,:); gjnode(inode,jnode,:) = mesh.t(jnode,:); Lloc(inode,jnode,:) = sum( shg(:,inode,:) .* shg(:,jnode,:),1) .* alphaareak; endfor endfor x = mesh.p(1,:); x = x(mesh.t(1:3,:)); y = mesh.p(2,:); y = y(mesh.t(1:3,:)); if all(size(beta)==1) v12 = 0; v23 = 0; v31 = 0; elseif all(size(beta)==[2,nelem]) v12 = beta(1,:) .* (x(2,:)-x(1,:)) + beta(2,:) .* (y(2,:)-y(1,:)); v23 = beta(1,:) .* (x(3,:)-x(2,:)) + beta(2,:) .* (y(3,:)-y(2,:)); v31 = beta(1,:) .* (x(1,:)-x(3,:)) + beta(2,:) .* (y(1,:)-y(3,:)); elseif all(size(beta)==[nnodes,1]) betaloc = beta(mesh.t(1:3,:)); v12 = betaloc(2,:)-betaloc(1,:); v23 = betaloc(3,:)-betaloc(2,:); v31 = betaloc(1,:)-betaloc(3,:); else error("bim2a_advection_upwind: coefficient beta has wrong dimensions."); endif [bp12, bm12] = deal (- (v12 - abs (v12))/2, (v12 + abs (v12))/2); [bp23, bm23] = deal (- (v23 - abs (v23))/2, (v23 + abs (v23))/2); [bp31, bm31] = deal (- (v31 - abs (v31))/2, (v31 + abs (v31))/2); bp12 = reshape(bp12,1,1,nelem).*Lloc(1,2,:); bm12 = reshape(bm12,1,1,nelem).*Lloc(1,2,:); bp23 = reshape(bp23,1,1,nelem).*Lloc(2,3,:); bm23 = reshape(bm23,1,1,nelem).*Lloc(2,3,:); bp31 = reshape(bp31,1,1,nelem).*Lloc(3,1,:); bm31 = reshape(bm31,1,1,nelem).*Lloc(3,1,:); Sloc(1,1,:) = (-bm12-bp31); Sloc(1,2,:) = bp12; Sloc(1,3,:) = bm31; Sloc(2,1,:) = bm12; Sloc(2,2,:) = (-bp12-bm23); Sloc(2,3,:) = bp23; Sloc(3,1,:) = bp31; Sloc(3,2,:) = bm23; Sloc(3,3,:) = (-bm31-bp23); A = sparse(ginode(:), gjnode(:), Sloc(:)); endfunction bim-1.1.8/inst/bim2a_axisymmetric_advection_diffusion.m000066400000000000000000000340661502773057700233430ustar00rootroot00000000000000## Copyright (C) 2006-2014 Carlo de Falco, Massimiliano Culpo ## ## This file is part of: ## BIM - Diffusion Advection Reaction PDE Solver ## ## BIM 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. ## ## BIM 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 BIM; If not, see . ## ## author: Carlo de Falco ## author: Massimiliano Culpo ## author: Matteo porro ## author: Emanuela Abbate ## -*- texinfo -*- ## @deftypefn {Function File} @ ## {[@var{A}]} = @ ## bim2a_axisymmetric_advection_diffusion(@var{mesh},@var{alpha},@var{gamma},@var{eta},@var{beta}) ## ## Build the Scharfetter-Gummel stabilized stiffness matrix for a ## diffusion-advection problem in cylindrical coordinates with axisymmetric ## configuration. Rotational symmetry is assumed with respect to be the vertical ## axis r=0. Only plane geometries that DO NOT intersect the symmetry axis ## are admitted. ## ##@example ##@group ## | ____ _|____ ## | | \ \ | | ## z | | \ OK \| | NO! ## | |______\ |\___| ## | r | #@end group #@end example ## ## The equation taken into account is: ## ## 1/r * d(r * Fr)/dr + dFz/dz = f ## ## with ## ## F = [Fr, Fz]' = - @var{alpha} * @var{gamma} ( @var{eta} grad (u) - @var{beta} u ) ## ## where @var{alpha} is an element-wise constant scalar function, ## @var{eta} and @var{gamma} are piecewise linear conforming scalar ## functions, @var{beta} is an element-wise constant vector function. ## ## Instead of passing the vector field @var{beta} directly, one can pass ## a piecewise linear conforming scalar function @var{phi} as the last ## input. In such case @var{beta} = grad @var{phi} is assumed. ## ## If @var{phi} is a single scalar value @var{beta} is assumed to be 0 ## in the whole domain. ## ## @seealso{bim2a_axisymmetric_rhs, bim2a_axisymmetric_reaction, ## bim2a_advection_diffusion, bim2c_mesh_properties} ## @end deftypefn function [A] = bim2a_axisymmetric_advection_diffusion (mesh, alpha, gamma, eta, beta) ## Check input if nargin != 5 error("bim2a_axisymmetric_advection_diffusion: wrong number of input parameters."); elseif !(isstruct(mesh) && isfield(mesh,"p") && isfield (mesh,"t") && isfield(mesh,"e")) error("bim2a_axisymmetric_advection_diffusion: first input is not a valid mesh structure."); elseif !(all(mesh.p(1,:) >= 0) || all(mesh.p(1,:) <= 0)) error("bim2a_axisymmetric_advection_diffusion: the input mesh cannot intersect the rotation axis r=0."); endif nnodes = columns(mesh.p); nelem = columns(mesh.t); ## Turn scalar input to a vector of appropriate size if isscalar(alpha) alpha = alpha*ones(nelem,1); endif if isscalar(gamma) gamma = gamma*ones(nnodes,1); endif if isscalar(eta) eta = eta*ones(nnodes,1); endif if !( isvector(alpha) && isvector(gamma) && isvector(eta) ) error("bim2a_axisymmetric_advection_diffusion: coefficients are not valid vectors."); elseif length(alpha) != nelem error("bim2a_axisymmetric_advection_diffusion: length of alpha is not equal to the number of elements."); elseif length(gamma) != nnodes error("bim2a_axisymmetric_advection_diffusion: length of gamma is not equal to the number of nodes."); elseif length(eta) != nnodes error("bim2a_axisymmetric_advection_diffusion: length of eta is not equal to the number of nodes."); endif x = abs(mesh.p(1,:)); x = x(mesh.t(1:3,:)); y = mesh.p(2,:); y = y(mesh.t(1:3,:)); alphaareak = reshape (alpha.*mesh.area,1,1,nelem); shg = mesh.shg(:,:,:); ## Build local Laplacian matrix Lloc = zeros(3,3,nelem); for inode = 1:3 for jnode = 1:3 ginode(inode,jnode,:) = mesh.t(inode,:); gjnode(inode,jnode,:) = mesh.t(jnode,:); Lloc(inode,jnode,:) = sum( shg(:,inode,:) .* shg(:,jnode,:),1) .* alphaareak; endfor endfor if all(size(beta)==1) v12 = 0; v23 = 0; v31 = 0; elseif all(size(beta)==[2,nelem]) v12 = beta(1,:) .* (x(2,:)-x(1,:)) + beta(2,:) .* (y(2,:)-y(1,:)); v23 = beta(1,:) .* (x(3,:)-x(2,:)) + beta(2,:) .* (y(3,:)-y(2,:)); v31 = beta(1,:) .* (x(1,:)-x(3,:)) + beta(2,:) .* (y(1,:)-y(3,:)); elseif all(size(beta)==[nnodes,1]) betaloc = beta(mesh.t(1:3,:)); v12 = betaloc(2,:)-betaloc(1,:); v23 = betaloc(3,:)-betaloc(2,:); v31 = betaloc(1,:)-betaloc(3,:); else error("bim2a_axisymmetric_advection_diffusion: coefficient beta has wrong dimensions."); endif etaloc = eta(mesh.t(1:3,:)); eta12 = etaloc(2,:) - etaloc(1,:); eta23 = etaloc(3,:) - etaloc(2,:); eta31 = etaloc(1,:) - etaloc(3,:); r12 = (x(2,:) + x(1,:)) / 2; r23 = (x(3,:) + x(2,:)) / 2; r31 = (x(1,:) + x(3,:)) / 2; etalocm1 = bimu_logm(etaloc(2,:),etaloc(3,:)); etalocm2 = bimu_logm(etaloc(3,:),etaloc(1,:)); etalocm3 = bimu_logm(etaloc(1,:),etaloc(2,:)); gammaloc = gamma(mesh.t(1:3,:)); geloc = gammaloc.*etaloc; gelocm1 = bimu_logm (geloc(2,:), geloc(3,:)); gelocm2 = bimu_logm (geloc(3,:), geloc(1,:)); gelocm3 = bimu_logm (geloc(1,:), geloc(2,:)); [bp12,bm12] = bimu_bernoulli ((v12 - eta12) ./ etalocm3); [bp23,bm23] = bimu_bernoulli ((v23 - eta23) ./ etalocm1); [bp31,bm31] = bimu_bernoulli ((v31 - eta31) ./ etalocm2); bp12 = reshape(r12.*gelocm3.*etalocm3.*bp12,1,1,nelem).*Lloc(1,2,:); bm12 = reshape(r12.*gelocm3.*etalocm3.*bm12,1,1,nelem).*Lloc(1,2,:); bp23 = reshape(r23.*gelocm1.*etalocm1.*bp23,1,1,nelem).*Lloc(2,3,:); bm23 = reshape(r23.*gelocm1.*etalocm1.*bm23,1,1,nelem).*Lloc(2,3,:); bp31 = reshape(r31.*gelocm2.*etalocm2.*bp31,1,1,nelem).*Lloc(3,1,:); bm31 = reshape(r31.*gelocm2.*etalocm2.*bm31,1,1,nelem).*Lloc(3,1,:); Sloc(1,1,:) = (-bm12-bp31)./reshape(etaloc(1,:),1,1,nelem); Sloc(1,2,:) = bp12./reshape(etaloc(2,:),1,1,nelem); Sloc(1,3,:) = bm31./reshape(etaloc(3,:),1,1,nelem); Sloc(2,1,:) = bm12./reshape(etaloc(1,:),1,1,nelem); Sloc(2,2,:) = (-bp12-bm23)./reshape(etaloc(2,:),1,1,nelem); Sloc(2,3,:) = bp23./reshape(etaloc(3,:),1,1,nelem); Sloc(3,1,:) = bp31./reshape(etaloc(1,:),1,1,nelem); Sloc(3,2,:) = bm23./reshape(etaloc(2,:),1,1,nelem); Sloc(3,3,:) = (-bm31-bp23)./reshape(etaloc(3,:),1,1,nelem); A = sparse(ginode(:),gjnode(:),Sloc(:)); endfunction %!test %! n = 3; %! [mesh] = msh2m_structured_mesh(linspace(1,2,n+1),linspace(0,1,n+1),1,1:4); %! mesh = bim2c_mesh_properties(mesh); %! uex = @(r,z) exp(r); %! duexdr = @(r,z) uex(r,z); %! d2uexdr2 = @(r,z) uex(r,z); %! duexdz = @(r,z) 0*uex(r,z); %! d2uexdz2 = @(r,z) 0*uex(r,z); %! Dnodes = bim2c_unknowns_on_side(mesh,[2,4]); %! Nnodes = columns(mesh.p); %! Nelements = columns(mesh.t); %! Varnodes = setdiff(1:Nnodes,Dnodes); %! D = 1; vr = 1; vz = 0; %! alpha = D*ones(Nelements,1); %! gamma = ones(Nnodes,1); %! eta = ones(Nnodes,1); %! beta = 1/D*[vr*ones(1,Nelements); vz*ones(1,Nelements)]; %! f = @(r,z) -D./r.*duexdr(r,z) - D.*d2uexdr2(r,z) ... %! + vr./r .* uex(r,z) + vr * duexdr(r,z) ... %! - D.*d2uexdz2(r,z) + vz * duexdz(r,z); %! rhs = bim2a_axisymmetric_rhs(mesh, ones(Nelements,1), f(mesh.p(1,:), mesh.p(2,:))); %! S = bim2a_axisymmetric_advection_diffusion(mesh,alpha,gamma,eta,beta); %! u = zeros(Nnodes,1); u(Dnodes) = uex(mesh.p(1,Dnodes), mesh.p(2,Dnodes)); %! u(Varnodes) = S(Varnodes,Varnodes)\(rhs(Varnodes) - S(Varnodes,Dnodes)*u(Dnodes)); %! assert(u,uex(mesh.p(1,:), mesh.p(2,:))',1e-7) %!test %! n = 20; %! [mesh] = msh2m_structured_mesh(linspace(1,2,n+1),linspace(0,1,n+1),1,1:4); %! mesh = bim2c_mesh_properties(mesh); %! uex = @(r,z) exp(r) .* exp(1-z); %! duexdr = @(r,z) uex(r,z); %! d2uexdr2 = @(r,z) uex(r,z); %! duexdz = @(r,z) -uex(r,z); %! d2uexdz2 = @(r,z) uex(r,z); %! Dnodes = bim2c_unknowns_on_side(mesh,[1,2,3,4]); %! Nnodes = columns(mesh.p); %! Nelements = columns(mesh.t); %! Varnodes = setdiff(1:Nnodes,Dnodes); %! D = 1; vr = 1; vz = 1; %! alpha = D*ones(Nelements,1); %! gamma = ones(Nnodes,1); %! eta = ones(Nnodes,1); %! beta = 1/D*[vr*ones(1,Nelements); vz*ones(1,Nelements)]; %! f = @(r,z) -D./r.*duexdr(r,z) - D.*d2uexdr2(r,z) ... %! + vr./r .* uex(r,z) + vr * duexdr(r,z) ... %! - D.*d2uexdz2(r,z) + vz * duexdz(r,z); %! rhs = bim2a_axisymmetric_rhs(mesh, ones(Nelements,1), f(mesh.p(1,:), mesh.p(2,:))); %! S = bim2a_axisymmetric_advection_diffusion(mesh,alpha,gamma,eta,beta); %! u = zeros(Nnodes,1); u(Dnodes) = uex(mesh.p(1,Dnodes), mesh.p(2,Dnodes)); %! u(Varnodes) = S(Varnodes,Varnodes)\(rhs(Varnodes) - S(Varnodes,Dnodes)*u(Dnodes)); %! assert(u,uex(mesh.p(1,:), mesh.p(2,:))',1e-3) %!test %! n = 10; %! [mesh] = msh2m_structured_mesh(linspace(1,2,n+1),linspace(0,1,n+1),1,1:4); %! mesh = bim2c_mesh_properties(mesh); %! uex = @(r,z) exp(r) .* exp(1-z); %! duexdr = @(r,z) uex(r,z); %! d2uexdr2 = @(r,z) uex(r,z); %! duexdz = @(r,z) -uex(r,z); %! d2uexdz2 = @(r,z) uex(r,z); %! Dnodes = bim2c_unknowns_on_side(mesh,[1,2,3,4]); %! Nnodes = columns(mesh.p); %! Nelements = columns(mesh.t); %! Varnodes = setdiff(1:Nnodes,Dnodes); %! D = 1; %! alpha = D*ones(Nelements,1); %! gamma = ones(Nnodes,1); %! eta = ones(Nnodes,1); %! beta = 1/D * mesh.p(1,:)'; %! f = @(r,z) -D./r.*duexdr(r,z) - D.*d2uexdr2(r,z) ... %! + 1./r .* uex(r,z) + duexdr(r,z) ... %! - D.*d2uexdz2(r,z); %! rhs = bim2a_axisymmetric_rhs(mesh, ones(Nelements,1), f(mesh.p(1,:), mesh.p(2,:))); %! S = bim2a_axisymmetric_advection_diffusion(mesh,alpha,gamma,eta,beta); %! u = zeros(Nnodes,1); u(Dnodes) = uex(mesh.p(1,Dnodes), mesh.p(2,Dnodes)); %! u(Varnodes) = S(Varnodes,Varnodes)\(rhs(Varnodes) - S(Varnodes,Dnodes)*u(Dnodes)); %! assert(u,uex(mesh.p(1,:), mesh.p(2,:))',1e-3) %!test %! n = 10; %! [mesh] = msh2m_structured_mesh(linspace(1,2,n+1),linspace(0,1,n+1),1,1:4); %! mesh = bim2c_mesh_properties(mesh); %! uex = @(r,z) exp(r) .* exp(1-z); %! duexdr = @(r,z) uex(r,z); %! d2uexdr2 = @(r,z) uex(r,z); %! duexdz = @(r,z) -uex(r,z); %! d2uexdz2 = @(r,z) uex(r,z); %! Dnodes = bim2c_unknowns_on_side(mesh,[1,2,3,4]); %! Nnodes = columns(mesh.p); %! Nelements = columns(mesh.t); %! Varnodes = setdiff(1:Nnodes,Dnodes); %! D = 1; %! alpha = D*ones(Nelements,1); %! gamma = ones(Nnodes,1); %! eta = ones(Nnodes,1); %! beta = 1/D * 1/2*(mesh.p(1,:)').^2; %! f = @(r,z) 1./r.*(1+r).*(r-D) .* uex(r,z); %! rhs = bim2a_axisymmetric_rhs(mesh, ones(Nelements,1), f(mesh.p(1,:), mesh.p(2,:))); %! S = bim2a_axisymmetric_advection_diffusion(mesh,alpha,gamma,eta,beta); %! u = zeros(Nnodes,1); u(Dnodes) = uex(mesh.p(1,Dnodes), mesh.p(2,Dnodes)); %! u(Varnodes) = S(Varnodes,Varnodes)\(rhs(Varnodes) - S(Varnodes,Dnodes)*u(Dnodes)); %! assert(u,uex(mesh.p(1,:), mesh.p(2,:))',1e-3) %!test %! n = 3; %! [mesh] = msh2m_structured_mesh(linspace(-2,-1,n+1),linspace(0,1,n+1),1,1:4); %! mesh = bim2c_mesh_properties(mesh); %! uex = @(r,z) exp(r); %! duexdr = @(r,z) uex(r,z); %! d2uexdr2 = @(r,z) uex(r,z); %! duexdz = @(r,z) 0*uex(r,z); %! d2uexdz2 = @(r,z) 0*uex(r,z); %! Dnodes = bim2c_unknowns_on_side(mesh,[2,4]); %! Nnodes = columns(mesh.p); %! Nelements = columns(mesh.t); %! Varnodes = setdiff(1:Nnodes,Dnodes); %! D = 1; vr = 1; vz = 0; %! alpha = D*ones(Nelements,1); %! gamma = ones(Nnodes,1); %! eta = ones(Nnodes,1); %! beta = 1/D*[vr*ones(1,Nelements); vz*ones(1,Nelements)]; %! f = @(r,z) -D./r.*duexdr(r,z) - D.*d2uexdr2(r,z) ... %! + vr./r .* uex(r,z) + vr * duexdr(r,z) ... %! - D.*d2uexdz2(r,z) + vz * duexdz(r,z); %! rhs = bim2a_axisymmetric_rhs(mesh, ones(Nelements,1), f(abs(mesh.p(1,:)), mesh.p(2,:))); %! S = bim2a_axisymmetric_advection_diffusion(mesh,alpha,gamma,eta,beta); %! u = zeros(Nnodes,1); u(Dnodes) = uex(abs(mesh.p(1,Dnodes)), mesh.p(2,Dnodes)); %! u(Varnodes) = S(Varnodes,Varnodes)\(rhs(Varnodes) - S(Varnodes,Dnodes)*u(Dnodes)); %! assert(u,uex(abs(mesh.p(1,:)), mesh.p(2,:))',1e-7) %!test %! n = 10; %! [mesh] = msh2m_structured_mesh(linspace(-2,-1,n+1),linspace(0,1,n+1),1,1:4); %! mesh = bim2c_mesh_properties(mesh); %! uex = @(r,z) exp(r) .* exp(1-z); %! duexdr = @(r,z) uex(r,z); %! d2uexdr2 = @(r,z) uex(r,z); %! duexdz = @(r,z) -uex(r,z); %! d2uexdz2 = @(r,z) uex(r,z); %! Dnodes = bim2c_unknowns_on_side(mesh,[1,2,3,4]); %! Nnodes = columns(mesh.p); %! Nelements = columns(mesh.t); %! Varnodes = setdiff(1:Nnodes,Dnodes); %! D = 1; %! alpha = D*ones(Nelements,1); %! gamma = ones(Nnodes,1); %! eta = ones(Nnodes,1); %! beta = 1/D * 1/2*(mesh.p(1,:)').^2; %! f = @(r,z) 1./r.*(1+r).*(r-D) .* uex(r,z); %! rhs = bim2a_axisymmetric_rhs(mesh, ones(Nelements,1), f(abs(mesh.p(1,:)), mesh.p(2,:))); %! S = bim2a_axisymmetric_advection_diffusion(mesh,alpha,gamma,eta,beta); %! u = zeros(Nnodes,1); u(Dnodes) = uex(abs(mesh.p(1,Dnodes)), mesh.p(2,Dnodes)); %! u(Varnodes) = S(Varnodes,Varnodes)\(rhs(Varnodes) - S(Varnodes,Dnodes)*u(Dnodes)); %! assert(u,uex(abs(mesh.p(1,:)), mesh.p(2,:))',1e-3) %!test %! [mesh] = msh2m_structured_mesh([0:.1:1],[0:.1:1],1,1:4); %! mesh = bim2c_mesh_properties(mesh); %! x = mesh.p(1,:)'; y = mesh.p(2,:)'; %! Dnodes = bim2c_unknowns_on_side(mesh,[1:4]); %! Nnodes = columns(mesh.p); Nelements = columns(mesh.t); %! alpha = ones(Nelements,1); eta=ones(Nnodes,1); %! beta = 0; %! gamma = ones(Nnodes,1); %! A = bim2a_axisymmetric_advection_diffusion(mesh,1,1,1,0); %! B = bim2a_axisymmetric_advection_diffusion(mesh,alpha,gamma,eta,beta); %! assert(A,B) bim-1.1.8/inst/bim2a_axisymmetric_advection_upwind.m000066400000000000000000000107601502773057700226560ustar00rootroot00000000000000## Copyright (C) 2006-2014 Carlo de Falco, Massimiliano Culpo ## ## This file is part of: ## BIM - Diffusion Advection Reaction PDE Solver ## ## BIM 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. ## ## BIM 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 BIM; If not, see . ## ## author: Carlo de Falco ## author: Massimiliano Culpo ## author: Matteo porro ## author: Emanuela Abbate ## -*- texinfo -*- ## ## @deftypefn {Function File} @ ## {[@var{A}]} = @ ## bim2a_axisymmetric_advection_upwind (@var{mesh}, @var{beta}) ## ## Build the Upwind stabilized stiffness matrix for an advection problem ## in cylindrical coordinates with axisymmetric configuration. ## ## The equation taken into account is: ## ## 1/r * d/dr (r * @var{beta}_r u) + d/dz (@var{beta}_z u) = f ## ## where @var{beta} is an element-wise constant vector function. ## ## Instead of passing the vector field @var{beta} directly one can pass ## a piecewise linear conforming scalar function @var{phi} as the last ## input. In such case @var{beta} = grad @var{phi} is assumed. ## ## If @var{phi} is a single scalar value @var{beta} is assumed to be 0 ## in the whole domain. ## ## @seealso{bim2a_axisymmetric_rhs, bim2a_axisymmetric_reaction, ## bim2a_axisymmetric_advection_diffusion, bim2c_mesh_properties} ## @end deftypefn function A = bim2a_axisymmetric_advection_upwind (mesh, beta) ## Check input if nargin != 2 error("bim2a_axisymmetric_advection_upwind: wrong number of input parameters."); elseif !(isstruct(mesh) && isfield(mesh,"p") && isfield (mesh,"t") && isfield(mesh,"e")) error("bim2a_axisymmetric_advection_upwind: first input is not a valid mesh structure."); elseif !(all(mesh.p(1,:) >= 0) || all(mesh.p(1,:) <= 0)) error("bim2a_axisymmetric_advection_upwind: the input mesh cannot intersect the rotation axis r=0."); endif nnodes = columns(mesh.p); nelem = columns(mesh.t); x = abs (mesh.p(1,:)); x = x(mesh.t(1:3,:)); y = mesh.p(2,:); y = y(mesh.t(1:3,:)); alphaareak = reshape (mesh.area, 1, 1, nelem); shg = mesh.shg(:,:,:); ## Build local Laplacian matrix Lloc = zeros(3,3,nelem); for inode = 1:3 for jnode = 1:3 ginode(inode,jnode,:) = mesh.t(inode,:); gjnode(inode,jnode,:) = mesh.t(jnode,:); Lloc(inode,jnode,:) = sum( shg(:,inode,:) .* shg(:,jnode,:),1) .* alphaareak; endfor endfor if all(size(beta)==1) v12 = 0; v23 = 0; v31 = 0; elseif all(size(beta)==[2,nelem]) v12 = beta(1,:) .* (x(2,:)-x(1,:)) + beta(2,:) .* (y(2,:)-y(1,:)); v23 = beta(1,:) .* (x(3,:)-x(2,:)) + beta(2,:) .* (y(3,:)-y(2,:)); v31 = beta(1,:) .* (x(1,:)-x(3,:)) + beta(2,:) .* (y(1,:)-y(3,:)); elseif all(size(beta)==[nnodes,1]) betaloc = beta(mesh.t(1:3,:)); v12 = betaloc(2,:)-betaloc(1,:); v23 = betaloc(3,:)-betaloc(2,:); v31 = betaloc(1,:)-betaloc(3,:); else error("bim2a_axisymmetric_advection_upwind: coefficient beta has wrong dimensions."); endif [bp12, bm12] = deal (- (v12 - abs (v12))/2, (v12 + abs (v12))/2); [bp23, bm23] = deal (- (v23 - abs (v23))/2, (v23 + abs (v23))/2); [bp31, bm31] = deal (- (v31 - abs (v31))/2, (v31 + abs (v31))/2); r12 = (x(2,:) + x(1,:)) / 2; r23 = (x(3,:) + x(2,:)) / 2; r31 = (x(1,:) + x(3,:)) / 2; bp12 = reshape(r12 .* bp12,1,1,nelem).*Lloc(1,2,:); bm12 = reshape(r12 .* bm12,1,1,nelem).*Lloc(1,2,:); bp23 = reshape(r23 .* bp23,1,1,nelem).*Lloc(2,3,:); bm23 = reshape(r23 .* bm23,1,1,nelem).*Lloc(2,3,:); bp31 = reshape(r31 .* bp31,1,1,nelem).*Lloc(3,1,:); bm31 = reshape(r31 .* bm31,1,1,nelem).*Lloc(3,1,:); Sloc(1,1,:) = (-bm12-bp31); Sloc(1,2,:) = bp12; Sloc(1,3,:) = bm31; Sloc(2,1,:) = bm12; Sloc(2,2,:) = (-bp12-bm23); Sloc(2,3,:) = bp23; Sloc(3,1,:) = bp31; Sloc(3,2,:) = bm23; Sloc(3,3,:) = (-bm31-bp23); A = sparse(ginode(:), gjnode(:), Sloc(:)); endfunction bim-1.1.8/inst/bim2a_axisymmetric_boundary_mass.m000066400000000000000000000144731502773057700221670ustar00rootroot00000000000000## Copyright (C) 2006-2014 Carlo de Falco, Massimiliano Culpo ## ## This file is part of: ## BIM - Diffusion Advection Reaction PDE Solver ## ## BIM 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. ## ## BIM 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 BIM; If not, see . ## ## author: Carlo de Falco ## author: Massimiliano Culpo ## author: Matteo porro ## author: Emanuela Abbate ## -*- texinfo -*- ## @deftypefn {Function File} {[@var{M}]} = @ ## bim2a_axisymmetric_boundary_mass(@var{mesh},@var{sidelist},@var{nodelist}) ## ## Build the lumped boundary mass matrix needed to apply Robin and Neumann ## boundary conditions in a problem in cylindrical coordinates with ## axisymmetric configuration. ## ## The vector @var{sidelist} contains the list of the side edges ## contributing to the mass matrix. ## ## The optional argument @var{nodelist} contains the list of the ## degrees of freedom on the boundary. ## ## @seealso{bim2a_axisymmetric_rhs, bim2a_axisymmetric_advection_diffusion, ## bim2a_axisymmetric_laplacian, bim2a_axisymmetric_reaction, bim2a_boundary_mass} ## @end deftypefn function [M] = bim2a_axisymmetric_boundary_mass(mesh,sidelist,nodelist) ## Check input if (nargin > 3) error ("bim2a_axisymmetric_boundary_mass: wrong number of input parameters."); elseif !(isstruct(mesh) && isfield(mesh,"p") && isfield (mesh,"t") && isfield(mesh,"e")) error("bim2a_axisymmetric_boundary_mass: first input is not a valid mesh structure."); elseif !( isvector(sidelist) && isnumeric(sidelist) ) error("bim2a_axisymmetric_boundary_mass: second input is not a valid numeric vector."); elseif !(all(mesh.p(1,:) >= 0) || all(mesh.p(1,:) <= 0)) error("bim2a_axisymmetric_boundary_mass: the input mesh cannot intersect the rotation axis r=0."); endif if (nargin < 3) [nodelist] = bim2c_unknowns_on_side(mesh,sidelist); endif r = abs (mesh.p(1,nodelist)); edges = []; for ie = sidelist edges = [ edges, mesh.e([1:2 5],mesh.e(5,:)==ie)]; endfor l = sqrt((mesh.p(1,edges(1,:))-mesh.p(1,edges(2,:))).^2 + (mesh.p(2,edges(1,:))-mesh.p(2,edges(2,:))).^2); dd = zeros(size(nodelist)); for in = 1:length(nodelist) dd (in) = ( sum(r(in).*l(edges(1,:)==nodelist(in))) ... + sum(r(in).*l(edges(2,:)==nodelist(in))) )/2; endfor M = sparse(diag(dd)); endfunction %!test %! n = 3; %! [mesh] = msh2m_structured_mesh(linspace(1,2,n+1),linspace(0,1,n+1),1,1:4); %! mesh = bim2c_mesh_properties(mesh); %! uex = @(r,z) exp(r); %! duexdr = @(r,z) uex(r,z); %! d2uexdr2 = @(r,z) uex(r,z); %! duexdz = @(r,z) 0*uex(r,z); %! d2uexdz2 = @(r,z) 0*uex(r,z); %! Rnodesr = bim2c_unknowns_on_side(mesh,[2]); %! Rnodesl = bim2c_unknowns_on_side(mesh,[4]); %! Nnodes = columns(mesh.p); %! Nelements = columns(mesh.t); %! D = 1; vr = 1; vz = 0; %! alpha = D*ones(Nelements,1); %! gamma = ones(Nnodes,1); %! eta = ones(Nnodes,1); %! beta = 1/D*[vr*ones(1,Nelements); vz*ones(1,Nelements)]; %! f = @(r,z) -D./r.*duexdr(r,z) - D.*d2uexdr2(r,z) ... %! + vr./r .* uex(r,z) + vr * duexdr(r,z) ... %! - D.*d2uexdz2(r,z) + vz * duexdz(r,z); %! gr = @(r,z) uex(r,z) - 1 * (-D*duexdr(r,z) + vr*uex(r,z)); %! gl = @(r,z) uex(r,z) - (-1) * (-D*duexdr(r,z) + vr*uex(r,z)); %! rhs = bim2a_axisymmetric_rhs(mesh, ones(Nelements,1), f(mesh.p(1,:), mesh.p(2,:))); %! S = bim2a_axisymmetric_advection_diffusion(mesh,alpha,gamma,eta,beta); %! Mr = bim2a_axisymmetric_boundary_mass(mesh,2); Ml = bim2a_axisymmetric_boundary_mass(mesh,4); %! S(Rnodesr,Rnodesr) += Mr; %! rhs(Rnodesr) += diag(Mr) .* gr(mesh.p(1,Rnodesr), mesh.p(2,Rnodesr))'; %! S(Rnodesl,Rnodesl) += Ml; %! rhs(Rnodesl) += diag(Ml) .* gl(mesh.p(1,Rnodesl), mesh.p(2,Rnodesl))'; %! u = S\rhs; %! assert(u,uex(mesh.p(1,:), mesh.p(2,:))',1e-7) %!test %! n = 10; %! [mesh] = msh2m_structured_mesh(linspace(1,2,n+1),linspace(0,1,n+1),1,1:4); %! mesh = bim2c_mesh_properties(mesh); %! uex = @(r,z) exp(r); %! duexdr = @(r,z) uex(r,z); %! d2uexdr2 = @(r,z) uex(r,z); %! duexdz = @(r,z) 0*uex(r,z); %! d2uexdz2 = @(r,z) 0*uex(r,z); %! Rnodesr = bim2c_unknowns_on_side(mesh,[2]); %! Rnodesl = bim2c_unknowns_on_side(mesh,[4]); %! Rnodesb = bim2c_unknowns_on_side(mesh,[1]); %! Rnodest = bim2c_unknowns_on_side(mesh,[3]); %! Nnodes = columns(mesh.p); %! Nelements = columns(mesh.t); %! D = 1; vr = 1; vz = 0; %! alpha = D*ones(Nelements,1); %! gamma = ones(Nnodes,1); %! eta = ones(Nnodes,1); %! beta = 1/D*[vr*ones(1,Nelements); vz*ones(1,Nelements)]; %! f = @(r,z) -D./r.*duexdr(r,z) - D.*d2uexdr2(r,z) ... %! + vr./r .* uex(r,z) + vr * duexdr(r,z) ... %! - D.*d2uexdz2(r,z) + vz * duexdz(r,z); %! gr = @(r,z) uex(r,z) - 1 * (-D*duexdr(r,z) + vr*uex(r,z)); %! gl = @(r,z) uex(r,z) - (-1) * (-D*duexdr(r,z) + vr*uex(r,z)); %! gb = @(r,z) uex(r,z) - (-1) * (-D*duexdz(r,z) + vz*uex(r,z)); %! gt = @(r,z) uex(r,z) - 1 * (-D*duexdz(r,z) + vz*uex(r,z)); %! rhs = bim2a_axisymmetric_rhs(mesh, ones(Nelements,1), f(mesh.p(1,:), mesh.p(2,:))); %! S = bim2a_axisymmetric_advection_diffusion(mesh,alpha,gamma,eta,beta); %! Mr = bim2a_axisymmetric_boundary_mass(mesh,2); Ml = bim2a_axisymmetric_boundary_mass(mesh,4); %! Mb = bim2a_axisymmetric_boundary_mass(mesh,1); Mt = bim2a_axisymmetric_boundary_mass(mesh,3); %! S(Rnodesr,Rnodesr) += Mr; %! rhs(Rnodesr) += diag(Mr) .* gr(mesh.p(1,Rnodesr), mesh.p(2,Rnodesr))'; %! S(Rnodesl,Rnodesl) += Ml; %! rhs(Rnodesl) += diag(Ml) .* gl(mesh.p(1,Rnodesl), mesh.p(2,Rnodesl))'; %! S(Rnodesb,Rnodesb) += Mb; %! rhs(Rnodesb) += diag(Mb) .* gb(mesh.p(1,Rnodesb), mesh.p(2,Rnodesb))'; %! S(Rnodest,Rnodest) += Mt; %! rhs(Rnodest) += diag(Mt) .* gt(mesh.p(1,Rnodest), mesh.p(2,Rnodest))'; %! u = S\rhs; %! assert(u,uex(mesh.p(1,:), mesh.p(2,:))',1e-7) bim-1.1.8/inst/bim2a_axisymmetric_laplacian.m000066400000000000000000000053241502773057700212400ustar00rootroot00000000000000## Copyright (C) 2006-2014 Carlo de Falco, Massimiliano Culpo ## ## This file is part of: ## BIM - Diffusion Advection Reaction PDE Solver ## ## BIM 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. ## ## BIM 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 BIM; If not, see . ## ## author: Carlo de Falco ## author: Massimiliano Culpo ## author: Matteo porro ## author: Emanuela Abbate ## -*- texinfo -*- ## ## @deftypefn {Function File} @ ## {@var{A}} = bim2a_axisymmetric_laplacian (@var{mesh},@var{epsilon},@var{kappa}) ## ## Build the standard finite element stiffness matrix for a diffusion ## problem in cylindrical coordinates with axisymmetric configuration. ## Rotational symmetry is assumed with respect to be the vertical axis r=0. ## Only plane geometries that DO NOT intersect the symmetry axis are admitted. ## ##@example ##@group ## | ____ _|____ ## | | \ \ | | ## z | | \ OK \| | NO! ## | |______\ |\___| ## | r | #@end group #@end example ## ## The equation taken into account is: ## ## 1/r * d(r * Fr)/dr + dFz/dz = f ## ## with ## ## F = [Fr, Fz]' = - @var{epsilon} * @var{kappa} grad (u) ## ## where @var{epsilon} is an element-wise constant scalar function, ## while @var{kappa} is a piecewise linear conforming scalar function. ## ## @seealso{bim2a_axisymmetric_rhs, bim2a_axisymmetric_reaction, ## bim2a_axisymmetric_advection_diffusion, bim2a_laplacian, bim1a_laplacian, ## bim3a_laplacian} ## @end deftypefn function [A] = bim2a_axisymmetric_laplacian(mesh,epsilon,kappa) ## Check input if nargin != 3 error("bim2a_axisymmetric_laplacian: wrong number of input parameters."); elseif !(all(mesh.p(1,:) >= 0) || all(mesh.p(1,:) <= 0)) error("bim2a_axisymmetric_laplacian: the input mesh cannot intersect the rotation axis r=0."); endif ## Input check inside bim2a_axisymmetric_advection_diffusion nnodes = columns(mesh.p); nelem = columns(mesh.t); A = bim2a_axisymmetric_advection_diffusion (mesh,epsilon,kappa,ones(nnodes,1),0); endfunction bim-1.1.8/inst/bim2a_axisymmetric_reaction.m000066400000000000000000000122021502773057700211110ustar00rootroot00000000000000## Copyright (C) 2006-2014 Carlo de Falco, Massimiliano Culpo ## ## This file is part of: ## BIM - Diffusion Advection Reaction PDE Solver ## ## BIM 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. ## ## BIM 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 BIM; If not, see . ## ## author: Carlo de Falco ## author: Massimiliano Culpo ## author: Matteo porro ## author: Emanuela Abbate ## -*- texinfo -*- ## @deftypefn {Function File} {[@var{C}]} = @ ## bim2a_axisymmetric_reaction(@var{mesh},@var{delta},@var{zeta}) ## ## Build the lumped finite element mass matrix for a diffusion ## problem in cylindrical coordinates with axisymmetric configuration. ## ## The equation taken into account is: ## ## @var{delta} * @var{zeta} * u = f ## ## where @var{delta} is an element-wise constant scalar function, while ## @var{zeta} is a piecewise linear conforming scalar function. ## ## @seealso{bim2a_rhs, bim2a_axisymmetric_advection_diffusion, ## bim2a_axisymmetric_laplacian, bim2a_reaction, bim1a_reaction, bim3a_reaction} ## @end deftypefn function [C] = bim2a_axisymmetric_reaction(mesh,delta,zeta) ## Check input if nargin != 3 error("bim2a_axisymmetric_reaction: wrong number of input parameters."); elseif !(isstruct(mesh) && isfield(mesh,"p") && isfield (mesh,"t") && isfield(mesh,"e")) error("bim2a_axisymmetric_reaction: first input is not a valid mesh structure."); elseif !(all(mesh.p(1,:) >= 0) || all(mesh.p(1,:) <= 0)) error("bim2a_axisymmetric_reaction: the input mesh cannot intersect the rotation axis r=0."); endif nnodes = size(mesh.p,2); nelem = size(mesh.t,2); r = abs (mesh.p(1,:)); ## Turn scalar input to a vector of appropriate size if isscalar(delta) delta = delta*ones(nelem,1); endif if isscalar(zeta) zeta = zeta*ones(nnodes,1); endif if !( isvector(delta) && isvector(zeta) ) error("bim2a_axisymmetric_reaction: coefficients are not valid vectors."); elseif length(delta) != nelem error("bim2a_axisymmetric_reaction: length of alpha is not equal to the number of elements."); elseif length(zeta) != nnodes error("bim2a_axisymmetric_reaction: length of gamma is not equal to the number of nodes."); endif wjacdet = mesh.wjacdet(:,:); coeff = zeta(mesh.t(1:3,:)); coeffe = delta(:); ## Local matrix Blocmat = zeros(3,nelem); for inode = 1:3 Blocmat(inode,:) = coeffe'.*coeff(inode,:).*wjacdet(inode,:) .* r(mesh.t(inode,:)); endfor gnode = (mesh.t(1:3,:)); ## Global matrix C = sparse(gnode(:),gnode(:),Blocmat(:)); endfunction %!shared mesh,delta,zeta,nnodes,nelem % x = y = linspace(0,1,4); % [mesh] = msh2m_structured_mesh(x,y,1,1:4); % [mesh] = bim2c_mesh_properties(mesh); % nnodes = columns(mesh.p); % nelem = columns(mesh.t); % delta = ones(columns(mesh.t),1); % zeta = ones(columns(mesh.p),1); %!test % [C] = bim2a_axisymmetric_reaction(mesh,delta,zeta); % assert(size(C),[nnodes, nnodes]); %!test % [C1] = bim2a_axisymmetric_reaction(mesh,3*delta,zeta); % [C2] = bim2a_axisymmetric_reaction(mesh,delta,3*zeta); % assert(C1,C2); %!test % [C1] = bim2a_axisymmetric_reaction(mesh,3*delta,zeta); % [C2] = bim2a_axisymmetric_reaction(mesh,3,1); % assert(C1,C2); %!test %! n = 20; %! [mesh] = msh2m_structured_mesh(linspace(1,2,n+1),linspace(0,1,n+1),1,1:4); %! mesh = bim2c_mesh_properties(mesh); %! uex = @(r,z) exp(r) .* exp(1-z); %! duexdr = @(r,z) uex(r,z); %! d2uexdr2 = @(r,z) uex(r,z); %! duexdz = @(r,z) -uex(r,z); %! d2uexdz2 = @(r,z) uex(r,z); %! Dnodes = bim2c_unknowns_on_side(mesh,[1,2,3,4]); %! Nnodes = columns(mesh.p); %! Nelements = columns(mesh.t); %! Varnodes = setdiff(1:Nnodes,Dnodes); %! D = 1; vr = 1; vz = 1; sigma = 1; %! alpha = D*ones(Nelements,1); %! gamma = ones(Nnodes,1); %! eta = ones(Nnodes,1); %! delta = sigma*ones(columns(mesh.t),1); %! zeta = ones(columns(mesh.p),1); %! beta = 1/D*[vr*ones(1,Nelements); vz*ones(1,Nelements)]; %! f = @(r,z) -D./r.*duexdr(r,z) - D.*d2uexdr2(r,z) ... %! + vr./r .* uex(r,z) + vr * duexdr(r,z) ... %! - D.*d2uexdz2(r,z) + vz * duexdz(r,z) ... %! + sigma * uex(r,z); %! rhs = bim2a_axisymmetric_rhs(mesh, ones(Nelements,1), f(mesh.p(1,:), mesh.p(2,:))); %! S = bim2a_axisymmetric_advection_diffusion(mesh,alpha,gamma,eta,beta); %! C = bim2a_axisymmetric_reaction(mesh,delta,zeta); %! S += C; %! u = zeros(Nnodes,1); u(Dnodes) = uex(mesh.p(1,Dnodes), mesh.p(2,Dnodes)); %! u(Varnodes) = S(Varnodes,Varnodes)\(rhs(Varnodes) - S(Varnodes,Dnodes)*u(Dnodes)); %! assert(u,uex(mesh.p(1,:), mesh.p(2,:))',1e-3) bim-1.1.8/inst/bim2a_axisymmetric_rhs.m000066400000000000000000000071441502773057700201120ustar00rootroot00000000000000## Copyright (C) 2006-2014 Carlo de Falco, Massimiliano Culpo ## ## This file is part of: ## BIM - Diffusion Advection Reaction PDE Solver ## ## BIM 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. ## ## BIM 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 BIM; If not, see . ## ## author: Carlo de Falco ## author: Massimiliano Culpo ## author: Matteo porro ## author: Emanuela Abbate ## -*- texinfo -*- ## @deftypefn {Function File} {[@var{b}]} = @ ## bim2a_axisymmetric_rhs(@var{mesh},@var{f},@var{g}) ## ## Build the finite element right-hand side of a diffusion problem ## in cylindrical coordinates with axisymmetric configuration ## employing mass-lumping. ## ## The equation taken into account is: ## ## @var{delta} * u = f * g ## ## where @var{f} is an element-wise constant scalar function, while ## @var{g} is a piecewise linear conforming scalar function. ## ## @seealso{bim2a_axisymmetric_reaction, bim2a_axisymmetric_advection_diffusion, ## bim2a_axisymmetric_laplacian, bim1a_axisymmetric_rhs} ## @end deftypefn function b = bim2a_axisymmetric_rhs(mesh,f,g) ## Check input if (nargin != 3) error("bim2a_axisymmetric_rhs: wrong number of input parameters."); elseif !(isstruct(mesh) && isfield(mesh,"p") && isfield (mesh,"t") && isfield(mesh,"e")) error("bim2a_axisymmetric_rhs: first input is not a valid mesh structure."); elseif !(all(mesh.p(1,:) >= 0) || all(mesh.p(1,:) <= 0)) error("bim2a_axisymmetric_rhs: the input mesh cannot intersect the rotation axis r=0."); endif nnodes = columns(mesh.p); nelem = columns(mesh.t); r = abs (mesh.p(1,:)); ## Turn scalar input to a vector of appropriate size if isscalar(f) f = f*ones(nelem,1); endif if isscalar(g) g = g*ones(nnodes,1); endif if !( isvector(f) && isvector(g) ) error("bim2a_axisymmetric_rhs: coefficients are not valid vectors."); elseif length(f) != nelem error("bim2a_axisymmetric_rhs: length of f is not equal to the number of elements."); elseif length(g) != nnodes error("bim2a_axisymmetric_rhs: length of g is not equal to the number of nodes."); endif g = g(mesh.t(1:3,:)); wjacdet = mesh.wjacdet; ## Build local matrix Blocmat = zeros(3,nelem); for inode = 1:3 Blocmat(inode,:) = f'.*g(inode,:).*wjacdet(inode,:) .* r(mesh.t(inode,:)); endfor gnode = (mesh.t(1:3,:)); ## Assemble global matrix b = sparse(gnode(:),1,Blocmat(:)); endfunction %!shared mesh,f,g,nnodes,nelem % x = y = linspace(0,1,4); % [mesh] = msh2m_structured_mesh(x,y,1,1:4); % [mesh] = bim2c_mesh_properties(mesh); % nnodes = columns(mesh.p); % nelem = columns(mesh.t); % g = ones(columns(mesh.t),1); % f = ones(columns(mesh.p),1); %!test % [b] = bim2a_axisymmetric_rhs(mesh,f,g); % assert(size(b),[nnodes, 1]); %!test % [b1] = bim2a_axisymmetric_rhs(mesh,3*f,g); % [b2] = bim2a_axisymmetric_rhs(mesh,f,3*g); % assert(b1,b2); %!test % [b1] = bim2a_axisymmetric_rhs(mesh,3*f,g); % [b2] = bim2a_axisymmetric_rhs(mesh,3,1); % assert(b1,b2); bim-1.1.8/inst/bim2a_boundary_mass.m000066400000000000000000000046131502773057700173640ustar00rootroot00000000000000## Copyright (C) 2006,2007,2008,2009,2010 Carlo de Falco, Massimiliano Culpo ## ## This file is part of: ## BIM - Diffusion Advection Reaction PDE Solver ## ## BIM 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. ## ## BIM 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 BIM; If not, see . ## ## author: Carlo de Falco ## author: Massimiliano Culpo ## -*- texinfo -*- ## @deftypefn {Function File} {[@var{M}]} = @ ## bim2a_boundary_mass(@var{mesh},@var{sidelist},@var{nodelist}) ## ## Build the lumped boundary mass matrix needed to apply Robin boundary ## conditions. ## ## The vector @var{sidelist} contains the list of the side edges ## contributing to the mass matrix. ## ## The optional argument @var{nodelist} contains the list of the ## degrees of freedom on the boundary. ## ## @seealso{bim2a_rhs, bim2a_advection_diffusion, bim2a_laplacian, ## bim2a_reaction} ## @end deftypefn function [M] = bim2a_boundary_mass(mesh,sidelist,nodelist) ## Check input if nargin > 3 error("bim2a_boundary_mass: wrong number of input parameters."); elseif !(isstruct(mesh) && isfield(mesh,"p") && isfield (mesh,"t") && isfield(mesh,"e")) error("bim2a_boundary_mass: first input is not a valid mesh structure."); elseif !( isvector(sidelist) && isnumeric(sidelist) ) error("bim2a_boundary_mass: second input is not a valid numeric vector."); endif if nargin<3 [nodelist] = bim2c_unknowns_on_side(mesh,sidelist); endif edges = []; for ie = sidelist edges = [ edges, mesh.e([1:2 5],mesh.e(5,:)==ie)]; endfor l = sqrt((mesh.p(1,edges(1,:))-mesh.p(1,edges(2,:))).^2 + (mesh.p(2,edges(1,:))-mesh.p(2,edges(2,:))).^2); dd = zeros(size(nodelist)); for in = 1:numel (nodelist) dd (in) = (sum(l(edges(1,:)==nodelist(in)))+sum(l(edges(2,:)==nodelist(in))))/2; endfor M = sparse(diag(dd)); endfunction bim-1.1.8/inst/bim2a_laplacian.m000066400000000000000000000077401502773057700164460ustar00rootroot00000000000000## Copyright (C) 2006,2007,2008,2009,2010 Carlo de Falco, Massimiliano Culpo, Copyright (C) 2025 Carlo de Falco ## ## ## This file is part of: ## BIM - Diffusion Advection Reaction PDE Solver ## ## BIM 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. ## ## BIM 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 BIM; If not, see . ## ## author: Carlo de Falco ## author: Massimiliano Culpo ## -*- texinfo -*- ## ## @deftypefn {Function File} @ ## {@var{A}} = bim2a_laplacian (@var{mesh},@var{epsilon},@var{kappa}) ## ## Build the standard finite element stiffness matrix for a diffusion ## problem. ## ## The equation taken into account is: ## ## - div (@var{epsilon} * @var{kappa} grad (u)) = f ## ## where @var{epsilon} is an element-wise constant scalar function, ## while @var{kappa} is a piecewise linear conforming scalar function. ## ## @seealso{bim2a_rhs, bim2a_reaction, bim2a_advection_diffusion, bim1a_laplacian, bim3a_laplacian} ## @end deftypefn function A = bim2a_laplacian (mesh, epsilon, kappa) ## Check input if nargin != 3 error("bim2a_laplacian: wrong number of input parameters."); elseif !(isstruct(mesh) && isfield(mesh,"p") && isfield (mesh,"t") && isfield(mesh,"e")) error("bim2a_laplacian: first input is not a valid mesh structure."); endif p = mesh.p; t = mesh.t; nnodes = columns(p); nelem = columns(t); ## Turn scalar input to a vector of appropriate size if isscalar(epsilon) epsilon = epsilon * ones (nelem, 1); endif if isscalar(kappa) kappa = kappa * ones (nnodes, 1); endif if !( isvector (epsilon) && isvector (kappa) && (numel (epsilon) == nelem) && (numel (kappa) == nnodes)) error("bim2a_laplacian: coefficients are vectors of correct size."); endif ## Local element matrices (one 3x3 matrix for each triangle in the mesh) Lloc = zeros(3, 3, nelem); ## To integrate constants over each triangle we need to multiply by ## the triangle area. Multiply by the diffusion coefficient now tu ## simplify subsequent computations. Use inverse average for the ## diffusion coefficient. kappaepsilonareak = reshape (3./sum (1./kappa(:)(mesh.t (1:3)), 1)(:) .* epsilon(:) .* mesh.area(:), 1, 1, nelem); shg = mesh.shg(:,:,:); ## Computation for inode = 1:3 for jnode = 1:3 ginode(inode,jnode,:) = mesh.t(inode,:); gjnode(inode,jnode,:) = mesh.t(jnode,:); Lloc(inode,jnode,:) = sum (shg(:,inode,:) .* shg(:,jnode,:), 1) .* kappaepsilonareak; endfor endfor ## Assemble the local (full) matrices into one global (sparse) matrix A = sparse (ginode(:), gjnode(:), Lloc(:)); endfunction %!test %! m = msh2m_structured_mesh (0:.1:5, 0:.1:1, 1, 1:4, 'random'); %! m = bim2c_mesh_properties (m); %! A = bim2a_laplacian (m, 1, 3); %! dnodes = bim2c_unknowns_on_side (m, 1:4); %! inodes = setdiff (1:columns(m.p), dnodes); %! u = m.p(1,:)'; %! u(inodes) = A(inodes, inodes) \ (-A(inodes, dnodes) * u(dnodes)); %! assert (u, m.p(1,:)', sqrt(eps)) %!demo %! m = msh2m_structured_mesh (0:.1:2*pi, 0:.1:2*pi, 1, 1:4, 'random'); %! m = bim2c_mesh_properties (m); %! kappa = 2 + sin (m.p(1, :)'); %! f = kappa .* cos (m.p(2, :)'); %! uex = cos (m.p(2, :)'); %! A = bim2a_laplacian (m, 3./(sum(1./kappa(m.t(1:3, :)), 1)), 1); %! b = bim2a_rhs (m, 1, f); %! dnodes = bim2c_unknowns_on_side (m, 1:4); %! inodes = setdiff (1:columns(m.p), dnodes); %! u = uex; %! u(inodes) = A(inodes, inodes) \ (b(inodes)-A(inodes, dnodes) * u(dnodes)); %! h = pdesurf (m.p, m.t, u) %! figure %! pdesurf (m.p, m.t, uex) bim-1.1.8/inst/bim2a_reaction.m000066400000000000000000000063311502773057700163210ustar00rootroot00000000000000## Copyright (C) 2006,2007,2008,2009,2010 Carlo de Falco, Massimiliano Culpo ## ## This file is part of: ## BIM - Diffusion Advection Reaction PDE Solver ## ## BIM 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. ## ## BIM 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 BIM; If not, see . ## ## author: Carlo de Falco ## author: Massimiliano Culpo ## -*- texinfo -*- ## @deftypefn {Function File} {[@var{C}]} = @ ## bim2a_reaction(@var{mesh},@var{delta},@var{zeta}) ## ## Build the lumped finite element mass matrix for a diffusion ## problem. ## ## The equation taken into account is: ## ## @var{delta} * @var{zeta} * u = f ## ## where @var{delta} is an element-wise constant scalar function, while ## @var{zeta} is a piecewise linear conforming scalar function. ## ## @seealso{bim2a_rhs, bim2a_advection_diffusion, bim2a_laplacian, ## bim1a_reaction, bim3a_reaction} ## @end deftypefn function [C] = bim2a_reaction(mesh,delta,zeta) ## Check input if nargin != 3 error("bim2a_reaction: wrong number of input parameters."); elseif !(isstruct(mesh) && isfield(mesh,"p") && isfield (mesh,"t") && isfield(mesh,"e")) error("bim2a_reaction: first input is not a valid mesh structure."); endif nnodes = size(mesh.p,2); nelem = size(mesh.t,2); ## Turn scalar input to a vector of appropriate size if isscalar(delta) delta = delta*ones(nelem,1); endif if isscalar(zeta) zeta = zeta*ones(nnodes,1); endif if !( isvector(delta) && isvector(zeta) ) error("bim2a_reaction: coefficients are not valid vectors."); elseif (numel (delta) != nelem) error("bim2a_: length of alpha is not equal to the number of elements."); elseif (numel (zeta) != nnodes) error("bim2a_: length of gamma is not equal to the number of nodes."); endif wjacdet = mesh.wjacdet(:,:); coeff = zeta(mesh.t(1:3,:)); coeffe = delta(:); ## Local matrix Blocmat = zeros(3,nelem); for inode = 1:3 Blocmat(inode,:) = coeffe.'.*coeff(inode,:).*wjacdet(inode,:); endfor gnode = (mesh.t(1:3,:)); ## Global matrix C = sparse(gnode(:),gnode(:),Blocmat(:)); endfunction %!shared mesh,delta,zeta,nnodes,nelem % x = y = linspace(0,1,4); % [mesh] = msh2m_structured_mesh(x,y,,1:4; % [mesh] = bim2c_mesh_properties(mesh); % nnodes = columns(mesh.p); % nelem = columns(mesh.t); % delta = ones(columns(mesh.t),1); % zeta = ones(columns(mesh.p),1); %!test % [C] = bim2a_reaction(mesh,delta,zeta); % assert(size(C),[nnodes, nnodes]); %!test % [C1] = bim2a_reaction(mesh,3*delta,zeta); % [C2] = bim2a_reaction(mesh,delta,3*zeta); % assert(C1,C2); %!test % [C1] = bim2a_reaction(mesh,3*delta,zeta); % [C2] = bim2a_reaction(mesh,3,1); % assert(C1,C2); bim-1.1.8/inst/bim2a_rhs.m000066400000000000000000000060531502773057700153120ustar00rootroot00000000000000## Copyright (C) 2006,2007,2008,2009,2010 Carlo de Falco, Massimiliano Culpo ## ## This file is part of: ## BIM - Diffusion Advection Reaction PDE Solver ## ## BIM 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. ## ## BIM 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 BIM; If not, see . ## ## author: Carlo de Falco ## author: Massimiliano Culpo ## -*- texinfo -*- ## @deftypefn {Function File} {[@var{b}]} = @ ## bim2a_rhs(@var{mesh},@var{f},@var{g}) ## ## Build the finite element right-hand side of a diffusion problem ## employing mass-lumping. ## ## The equation taken into account is: ## ## @var{delta} * u = f * g ## ## where @var{f} is an element-wise constant scalar function, while ## @var{g} is a piecewise linear conforming scalar function. ## ## @seealso{bim2a_reaction, bim2a_advection_diffusion, bim2a_laplacian, ## bim1a_reaction, bim3a_reaction} ## @end deftypefn function b = bim2a_rhs(mesh,f,g) ## Check input if nargin != 3 error("bim2a_rhs: wrong number of input parameters."); elseif !(isstruct(mesh) && isfield(mesh,"p") && isfield (mesh,"t") && isfield(mesh,"e")) error("bim2a_rhs: first input is not a valid mesh structure."); endif nnodes = columns(mesh.p); nelem = columns(mesh.t); ## Turn scalar input to a vector of appropriate size if isscalar(f) f = f*ones(nelem,1); endif if isscalar(g) g = g*ones(nnodes,1); endif if !( isvector(f) && isvector(g) ) error("bim2a_rhs: coefficients are not valid vectors."); elseif (numel (f) != nelem) error("bim2a_rhs: length of f is not equal to the number of elements."); elseif (numel (g) != nnodes) error("bim2a_rhs: length of g is not equal to the number of nodes."); endif g = g(mesh.t(1:3,:)); wjacdet = mesh.wjacdet; ## Build local matrix Blocmat=zeros(3,nelem); for inode=1:3 Blocmat(inode,:) = f.' .* g(inode,:) .* wjacdet(inode,:); endfor gnode=(mesh.t(1:3,:)); ## Assemble global matrix b = sparse(gnode(:),1,Blocmat(:)); endfunction %!shared mesh,f,g,nnodes,nelem % x = y = linspace(0,1,4); % [mesh] = msh2m_structured_mesh(x,y,1,1:4); % [mesh] = bim2c_mesh_properties(mesh); % nnodes = columns(mesh.p); % nelem = columns(mesh.t); % g = ones(columns(mesh.t),1); % f = ones(columns(mesh.p),1); %!test % [b] = bim2a_rhs(mesh,f,g); % assert(size(b),[nnodes, 1]); %!test % [b1] = bim2a_rhs(mesh,3*f,g); % [b2] = bim2a_rhs(mesh,f,3*g); % assert(b1,b2); %!test % [b1] = bim2a_rhs(mesh,3*f,g); % [b2] = bim2a_rhs(mesh,3,1); % assert(b1,b2); bim-1.1.8/inst/bim2c_global_flux.m000066400000000000000000000134531502773057700170200ustar00rootroot00000000000000## Copyright (C) 2006,2007,2008,2009,2010 Carlo de Falco, Massimiliano Culpo ## ## This file is part of: ## BIM - Diffusion Advection Reaction PDE Solver ## ## BIM 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. ## ## BIM 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 BIM; If not, see . ## ## author: Carlo de Falco ## author: Massimiliano Culpo ## -*- texinfo -*- ## @deftypefn {Function File} {[@var{jx},@var{jy}]} = @ ## bim2c_global_flux(@var{mesh},@var{u},@var{alpha},@var{gamma},@var{eta},@var{beta}) ## ## Compute the flux associated with the Scharfetter-Gummel approximation ## of the scalar field @var{u}. ## ## The vector field is defined as: ## ## J(@var{u}) = @var{alpha}* @var{gamma} * (@var{eta} * grad @var{u} - @var{beta} * @var{u})) ## ## where @var{alpha} is an element-wise constant scalar function, ## @var{eta} and @var{gamma} are piecewise linear conforming scalar ## functions, while @var{beta} is element-wise constant vector function. ## ## J(@var{u}) is an element-wise constant vector function. ## ## Instead of passing the vector field @var{beta} directly one can pass ## a piecewise linear conforming scalar function @var{phi} as the last ## input. In such case @var{beta} = grad @var{phi} is assumed. If ## @var{phi} is a single scalar value @var{beta} is assumed to be 0 in ## the whole domain. ## ## @seealso{bim2c_pde_gradient,bim2a_advection_diffusion} ## @end deftypefn function [jx, jy] = bim2c_global_flux(mesh,u,alpha,gamma,eta,beta) ## Check input if nargin != 6 error("bim2c_global_flux: wrong number of input parameters."); elseif !(isstruct(mesh) && isfield(mesh,"p") && isfield (mesh,"t") && isfield(mesh,"e")) error("bim2c_global_flux: first input is not a valid mesh structure."); endif nnodes = columns(mesh.p); nelem = columns(mesh.t); if !( isvector(u) && isvector(alpha) && isvector(gamma) && isvector(eta) ) error("bim2c_global_flux: coefficients are not valid vectors."); elseif (numel (u) != nnodes) error("bim2c_global_flux: length of u is not equal to the number of nodes."); elseif (numel (alpha) != nelem) error("bim2c_global_flux: length of alpha is not equal to the number of elements."); elseif (numel (gamma) != nnodes) error("bim2c_global_flux: length of gamma is not equal to the number of nodes."); elseif (numel (eta) != nnodes) error("bim2c_global_flux: length of eta is not equal to the number of nodes."); endif nelem = columns(mesh.t); nnodes = columns(mesh.p); uloc = u(mesh.t(1:3,:)); shgx = reshape(mesh.shg(1,:,:),3,nelem); shgy = reshape(mesh.shg(2,:,:),3,nelem); x = reshape(mesh.p(1,mesh.t(1:3,:)),3,[]); dx = [ (x(3,:)-x(2,:)) ; (x(1,:)-x(3,:)) ; (x(2,:)-x(1,:)) ]; y = reshape(mesh.p(2,mesh.t(1:3,:)),3,[]); dy = [ (y(3,:)-y(2,:)) ; (y(1,:) -y(3,:)) ; (y(2,:) -y(1,:)) ]; if all(size(beta)==1) v12=0;v23=0;v31=0; elseif all(size(beta)==[2,nelem]) v23 = beta(1,:) .* dx(1,:) + beta(2,:) .* dy(1,:); v31 = beta(1,:) .* dx(2,:) + beta(2,:) .* dy(2,:); v12 = beta(1,:) .* dx(3,:) + beta(2,:) .* dy(3,:); elseif all(size(beta)==[nnodes,1]) betaloc = beta(mesh.t(1:3,:)); v23 = betaloc(3,:)-betaloc(2,:); v31 = betaloc(1,:)-betaloc(3,:); v12 = betaloc(2,:)-betaloc(1,:); else error("bim2c_global_flux: coefficient beta has wrong dimensions."); endif etaloc = eta(mesh.t(1:3,:)); eta23 = etaloc(3,:)-etaloc(2,:); eta31 = etaloc(1,:)-etaloc(3,:); eta12 = etaloc(2,:)-etaloc(1,:); etalocm1 = bimu_logm(etaloc(2,:),etaloc(3,:)); etalocm2 = bimu_logm(etaloc(3,:),etaloc(1,:)); etalocm3 = bimu_logm(etaloc(1,:),etaloc(2,:)); gammaloc = gamma(mesh.t(1:3,:)); geloc = gammaloc.*etaloc; gelocm1 = bimu_logm(geloc(2,:),geloc(3,:)); gelocm2 = bimu_logm(geloc(3,:),geloc(1,:)); gelocm3 = bimu_logm(geloc(1,:),geloc(2,:)); [bp23,bm23] = bimu_bernoulli( (v23 - eta23)./etalocm1); [bp31,bm31] = bimu_bernoulli( (v31 - eta31)./etalocm2); [bp12,bm12] = bimu_bernoulli( (v12 - eta12)./etalocm3); gfigfj = [ shgx(3,:) .* shgx(2,:) + shgy(3,:) .* shgy(2,:) ; shgx(1,:) .* shgx(3,:) + shgy(1,:) .* shgy(3,:) ; shgx(2,:) .* shgx(1,:) + shgy(2,:) .* shgy(1,:) ]; jx = - alpha' .* ( gelocm1 .* etalocm1 .* dx(1,:) .* ... gfigfj(1,:) .* ... ( bp23 .* uloc(3,:)./etaloc(3,:) -... bm23 .* uloc(2,:)./etaloc(2,:)) +... %% 1 gelocm2 .* etalocm2 .* dx(2,:) .* ... gfigfj(2,:) .* ... (bp31 .* uloc(1,:)./etaloc(1,:) -... bm31 .* uloc(3,:)./etaloc(3,:)) +... %% 2 gelocm3 .* etalocm3 .* dx(3,:) .* ... gfigfj(3,:) .* ... (bp12 .* uloc(2,:)./etaloc(2,:) -... bm12 .* uloc(1,:)./etaloc(1,:)) ... %% 3 ); jy = - alpha' .* ( gelocm1 .* etalocm1 .* dy(1,:) .* ... gfigfj(1,:) .* ... ( bp23 .* uloc(3,:)./etaloc(3,:) -... bm23 .* uloc(2,:)./etaloc(2,:)) +... %% 1 gelocm2 .* etalocm2 .* dy(2,:) .* ... gfigfj(2,:) .* ... (bp31 .* uloc(1,:)./etaloc(1,:) -... bm31 .* uloc(3,:)./etaloc(3,:)) +... %% 2 gelocm3 .* etalocm3 .* dy(3,:) .* ... gfigfj(3,:) .* ... (bp12 .* uloc(2,:)./etaloc(2,:) -... bm12 .* uloc(1,:)./etaloc(1,:)) ... %% 3 ); endfunction bim-1.1.8/inst/bim2c_intrp.m000066400000000000000000000041611502773057700156520ustar00rootroot00000000000000## Copyright (C) 2011, 2012 Carlo de Falco ## ## This program is free software; you can redistribute it and/or modify ## it under the terms of the GNU General Public License as published by ## the Free Software Foundation; either version 3 of the License, or ## (at your option) any later version. ## ## This program is distributed in the hope that it will be useful, ## but WITHOUT ANY WARRANTY; without even the implied warranty of ## MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the ## GNU General Public License for more details. ## ## You should have received a copy of the GNU General Public License ## along with Octave; see the file COPYING. If not, see ## . ## -*- texinfo -*- ## ## @deftypefn {Function File} {@var{data}} = bim2c_intrp (@var{msh}, @var{n_data}, @var{e_data}, @var{points}) ## ## Compute interpolated values of multicomponent node centered field @var{n_data} and/or ## cell centered field @var{n_data} at an arbitrary set of points whose coordinates are given in the ## n_by_2 matrix @var{points}. ## ## @end deftypefn ## Author: Carlo de Falco ## Created: 2012-10-01 function data = bim2c_intrp (msh, n_data, e_data, p) %% for each point, find the enclosing tetrahedron [t_list, b_list] = tsearchn (msh.p.', msh.t(1:3, :)', p); %% only keep points within tetrahedra invalid = isnan (t_list); t_list = t_list (! invalid); ntl = numel (t_list); b_list = b_list(! invalid, :); points(invalid,:) = []; data = []; if (! isempty (n_data)) data = cat (1, data, squeeze ( sum (reshape (n_data(msh.t(1:3, t_list), :), [3, ntl, (columns (n_data))]) .* repmat (b_list.', [1, 1, (columns (n_data))]), 1))); endif if (! isempty (e_data)) data = cat (1, data, e_data(t_list, :)); endif endfunction %!test %! msh = bim2c_mesh_properties (msh2m_structured_mesh (linspace (0, 1, 11), linspace (0, 1, 13), 1, 1:4)); %! x = y = linspace (0, 1, 100).'; %! u = msh.p(1, :).'; %! ui = bim2c_intrp (msh, u, [], [x, y]); %! assert (ui, linspace (0, 1, 100), 10*eps); bim-1.1.8/inst/bim2c_mesh_properties.m000066400000000000000000000040701502773057700177250ustar00rootroot00000000000000## Copyright (C) 2006,2007,2008,2009,2010 Carlo de Falco, Massimiliano Culpo ## ## This file is part of: ## BIM - Diffusion Advection Reaction PDE Solver ## ## BIM 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. ## ## BIM 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 BIM; If not, see . ## ## author: Carlo de Falco ## author: Massimiliano Culpo ## -*- texinfo -*- ## @deftypefn {Function File} {[@var{omesh}]} = @ ## bim2c_mesh_properties(@var{imesh}) ## ## Compute the properties of @var{imesh} needed by BIM method and append ## them to @var{omesh} as fields. ## ## @seealso{bim2a_reaction, bim2a_advection_diffusion, bim2a_rhs, ## bim2a_laplacian, bim2a_boundary_mass} ## @end deftypefn function [omesh] = bim2c_mesh_properties(imesh) ## Check input if nargin != 1 error("bim2c_mesh_properties: wrong number of input parameters."); elseif !(isstruct(imesh) && isfield(imesh,"p") && isfield (imesh,"t") && isfield(imesh,"e")) error("bim2c_mesh_properties: first input is not a valid mesh structure."); endif omesh = imesh; [omesh.wjacdet,omesh.area,omesh.shg] = ... msh2m_geometrical_properties(imesh,"wjacdet","area","shg"); endfunction %!shared mesh % x = y = linspace(0,1,4); % [mesh] = msh2m_structured_mesh(x,y,1,1:4); % [mesh] = bim2c_mesh_properties(mesh); %!test % tmp = msh2m_geometrical_properties(mesh,"wjacdet"); % assert(mesh.wjacdet,tmp); %!test % tmp = msh2m_geometrical_properties(mesh,"shg"); % assert(mesh.shg,tmp); %!test % assert(mesh.area,sum(mesh.wjacdet,1));bim-1.1.8/inst/bim2c_norm.m000066400000000000000000000107741502773057700155000ustar00rootroot00000000000000## Copyright (C) 2006-2013 Carlo de Falco, Massimiliano Culpo ## ## This file is part of: ## BIM - Diffusion Advection Reaction PDE Solver ## ## BIM 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. ## ## BIM 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 BIM; If not, see . ## ## author: Carlo de Falco ## author: Matteo Porro ## -*- texinfo -*- ## ## @deftypefn {Function File} {[@var{norm_u}]} = @ ## bim2c_norm(@var{mesh},@var{u},@var{norm_type}) ## ## Compute the @var{norm_type}-norm of function @var{u} on the domain described ## by the triangular grid @var{mesh}. ## ## The input function @var{u} can be either a piecewise linear conforming scalar ## function or an elementwise constant scalar or vector function. ## ## The string parameter @var{norm_type} can be one among 'L2', 'H1' and 'inf'. ## ## Should the input function be piecewise constant, the H1 norm will not be ## computed and the function will return an error message. ## ## For the numerical integration of the L2 norm the second order middle point ## quadrature rule is used. ## ## @seealso{bim1c_norm, bim3c_norm} ## ## @end deftypefn function [norm_u] = bim2c_norm (m, u, norm_type) ## Check input if (nargin != 3) error ("bim2c_norm: wrong number of input parameters."); elseif (! (isstruct (m) && isfield (m,"p") && isfield (m, "t") && isfield (m, "e"))) error ("bim2c_norm: first input is not a valid mesh structure."); endif nnodes = columns (m.p); nel = columns (m.t); if (isequal (size (u), [2, nel])) u = u'; endif if ((numel (u) != nnodes) && (rows (u) != nel)) error ("bim2c_norm: numel(u) != nnodes and rows(u) != nel."); endif if (! (strcmp (norm_type,'L2') || strcmp (norm_type,'inf') || strcmp (norm_type,'H1'))) error ("bim2c_norm: invalid norm type parameter."); endif if (strcmp (norm_type,'inf')) norm_u = max (abs (u(:))); else if (numel (u) == nnodes) M = __mass_matrix__ (m); if (strcmp (norm_type, 'H1')) A = bim2a_laplacian (m, 1, 1); M += A; endif norm_u = sqrt(u' * M * u); else if (strcmp (norm_type, 'H1')) error (["bim2c_norm: cannot compute the H1 norm ", ... "of an elementwise constant function."]); endif norm_u = m.area' * (norm (u, 2, 'rows').^2); norm_u = sqrt (norm_u); endif endif endfunction function M = __mass_matrix__ (mesh) t = mesh.t; nnodes = columns (mesh.p); nelem = columns (t); ## Local contributions Mref = 1/12 * [2 1 1; 1 2 1; 1 1 2]; area = reshape (mesh.area, 1, 1, nelem); ## Computation for inode = 1:3 for jnode = 1:3 ginode(inode,jnode,:) = t(inode,:); gjnode(inode,jnode,:) = t(jnode,:); endfor endfor Mloc = area .* Mref; ## assemble global matrix M = sparse (ginode(:), gjnode(:), Mloc(:), nnodes, nnodes); endfunction %!test %!shared L, V, x, y, m %! L = rand (1); V = rand (1); x = linspace (0,L,4); y = x; %! m = msh2m_structured_mesh (x,y,1,1:4); %! m.area = msh2m_geometrical_properties (m, 'area'); %! m.shg = msh2m_geometrical_properties (m, 'shg'); %! u = V * ones (columns(m.p),1); %! uinf = bim2c_norm (m, u, 'inf'); %! uL2 = bim2c_norm (m, u, 'L2'); %! uH1 = bim2c_norm (m, u, 'H1'); %! assert ([uinf, uL2, uH1], [V, V*L, V*L], 1e-12); %!test %! u = V * (m.p(1,:) + 2*m.p(2,:))'; %! uinf = bim2c_norm (m, u, 'inf'); %! uL2 = bim2c_norm (m, u, 'L2'); %! uH1 = bim2c_norm (m, u, 'H1'); %! assert ([uinf, uL2, uH1], %! [3*L*V, V*L^2*sqrt(8/3), V*sqrt(8/3*L^4 + 5*L^2)], %! 1e-12); %!test %! u = V * ones (columns(m.t),1); %! uinf = bim2c_norm (m, u, 'inf'); %! uL2 = bim2c_norm (m, u, 'L2'); %! assert ([uinf, uL2], [V, V*L], 1e-12); %!test %! u = V * ones (columns(m.t),1); %! uvect = [u, 2*u]; %! uinf = bim2c_norm (m, uvect, 'inf'); %! uL2 = bim2c_norm (m, uvect, 'L2'); %! assert ([uinf, uL2], [2*V, V*L*sqrt(5)], 1e-12); bim-1.1.8/inst/bim2c_pde_gradient.m000066400000000000000000000034321502773057700171430ustar00rootroot00000000000000## Copyright (C) 2006,2007,2008,2009,2010 Carlo de Falco, Massimiliano Culpo ## ## This file is part of: ## BIM - Diffusion Advection Reaction PDE Solver ## ## BIM 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. ## ## BIM 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 BIM; If not, see . ## ## author: Carlo de Falco ## author: Massimiliano Culpo ## -*- texinfo -*- ## ## @deftypefn {Function File} {[@var{gx},@var{gy}]} = @ ## bim2c_pde_gradient(@var{mesh},@var{u}) ## ## Compute the gradient of the piecewise linear conforming scalar ## function @var{u}. ## ## @seealso{bim2c_global_flux} ## @end deftypefn function [gx, gy] = bim2c_pde_gradient(mesh,u) ## Check input if nargin != 2 error("bim2c_pde_gradient: wrong number of input parameters."); elseif !(isstruct(mesh) && isfield(mesh,"p") && isfield (mesh,"t") && isfield(mesh,"e")) error("bim2c_pde_gradient: first input is not a valid mesh structure."); endif nnodes = columns(mesh.p); if (numel (u) != nnodes) error("bim2c_pde_gradient: length(u) != nnodes."); endif shgx = reshape(mesh.shg(1,:,:),3,[]); gx = sum(shgx.*u(mesh.t(1:3,:)),1); shgy = reshape(mesh.shg(2,:,:),3,[]); gy = sum(shgy.*u(mesh.t(1:3,:)),1); endfunction bim-1.1.8/inst/bim2c_tri_to_nodes.m000066400000000000000000000052021502773057700172030ustar00rootroot00000000000000## Copyright (C) 2011 Carlo de Falco ## ## This program is free software; you can redistribute it and/or modify ## it under the terms of the GNU General Public License as published by ## the Free Software Foundation; either version 3 of the License, or ## (at your option) any later version. ## ## This program is distributed in the hope that it will be useful, ## but WITHOUT ANY WARRANTY; without even the implied warranty of ## MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the ## GNU General Public License for more details. ## ## You should have received a copy of the GNU General Public License ## along with Octave; see the file COPYING. If not, see ## . ## -*- texinfo -*- ## ## @deftypefn {Function File} {@var{u_nod}} = bim2c_tri_to_nodes (@var{mesh}, @var{u_tri}) ## @deftypefnx {Function File} {@var{u_nod}} = bim2c_tri_to_nodes (@var{m_tri}, @var{u_tri}) ## @deftypefnx {Function File} {[@var{u_nod}, @var{m_tri}]} = bim2c_tri_to_nodes ( ... ) ## ## Compute interpolated values at triangle nodes @var{u_nod} given values at triangle mid-points @var{u_tri}. ## If called with more than one output, also return the interpolation matrix @var{m_tri} such that ## @code{u_nod = m_tri * u_tri}. ## If repeatedly performing interpolation on the same mesh the matrix @var{m_tri} obtained by a previous call ## to @code{bim2c_tri_to_nodes} may be passed as input to avoid unnecessary computations. ## ## @end deftypefn ## Author: Carlo de Falco ## Created: 2011-03-07 function [u_nod, m_tri] = bim2c_tri_to_nodes (m, u_tri) if (nargout > 1) if (isstruct (m)) nel = columns (m.t); nnod = columns (m.p); ii = m.t(1:3, :); jj = repmat (1:nel, 3, 1); vv = repmat (m.area(:)', 3, 1) / 3; m_tri = bim2a_reaction (m, 1, 1) \ sparse (ii, jj, vv, nnod, nel); elseif (ismatrix (m)) m_tri = m; else error ("bim2c_tri_to_nodes: first input parameter is of incorrect type"); endif u_nod = m_tri * u_tri; else if (isstruct (m)) rhs = bim2a_rhs (m, u_tri, 1); mass = bim2a_reaction (m, 1, 1); u_nod = full (mass \ rhs); elseif (ismatrix (m)) u_nod = m * u_tri; else error ("bim2c_tri_to_nodes: first input parameter is of incorrect type"); endif endif endfunction %!test %! msh = bim2c_mesh_properties (msh2m_structured_mesh (linspace (0, 1, 3), linspace (0, 1, 3), 1, 1:4, "random")); %! nel = columns (msh.t); %! nnod = columns (msh.p); %! u_tri = randn (nel, 1); %! un1 = bim2c_tri_to_nodes (msh, u_tri); %! [un2, m] = bim2c_tri_to_nodes (msh, u_tri); %! assert (un1, un2, 1e-10) bim-1.1.8/inst/bim2c_unknowns_on_side.m000066400000000000000000000034031502773057700200760ustar00rootroot00000000000000## Copyright (C) 2006,2007,2008,2009,2010 Carlo de Falco, Massimiliano Culpo ## ## This file is part of: ## BIM - Diffusion Advection Reaction PDE Solver ## ## BIM 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. ## ## BIM 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 BIM; If not, see . ## ## author: Carlo de Falco ## author: Massimiliano Culpo ## -*- texinfo -*- ## @deftypefn {Function File} {[@var{nodelist}]} = @ ## bim2c_unknowns_on_side(@var{mesh},@var{sidelist}) ## ## Return the list of the mesh nodes that lie on the geometrical sides ## specified in @var{sidelist}. ## ## @seealso{bim3c_unknown_on_faces, bim2c_pde_gradient, ## bim2c_global_flux} ## @end deftypefn function [nodelist] = bim2c_unknowns_on_side(mesh, sidelist) ## Check input if nargin != 2 error("bim2c_unknowns_on_side: wrong number of input parameters."); elseif !(isstruct(mesh) && isfield(mesh,"p") && isfield (mesh,"t") && isfield(mesh,"e")) error("bim2c_unknowns_on_side: first input is not a valid mesh structure."); elseif !isnumeric(sidelist) error("bim2c_unknowns_on_side: second input is not a valid numeric vector."); endif [nodelist] = msh2m_nodes_on_sides(mesh,sidelist); endfunction bim-1.1.8/inst/bim3a_advection_diffusion.m000066400000000000000000000072221502773057700205400ustar00rootroot00000000000000## Copyright (C) 2010 Carlo de Falco ## ## This file is part of: ## BIM - Diffusion Advection Reaction PDE Solver ## ## BIM 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. ## ## BIM 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 BIM; If not, see . ## ## author: Carlo de Falco ## -*- texinfo -*- ## ## @deftypefn {Function File} @ ## {[@var{A}]} = @ ## bim3a_advection_diffusion (@var{mesh}, @var{alpha}, @var{v}) ## ## Build the Scharfetter-Gummel stabilized stiffness matrix for a ## diffusion-advection problem. ## ## The equation taken into account is: ## ## - div (@var{alpha} ( grad (u) - grad (@var{v}) u)) = f ## ## where @var{v} is a piecewise linear continuous scalar ## functions and @var{alpha} is a piecewise constant scalar function. ## ## @seealso{bim3a_rhs, bim3a_reaction, bim3a_laplacian, bim3c_mesh_properties} ## @end deftypefn function SG = bim3a_advection_diffusion (mesh, acoeff, v) t = mesh.t; nnodes = columns (mesh.p); nelem = columns(t); ## Local contributions Lloc = zeros(4,4,nelem); epsilonareak = reshape (acoeff .* mesh.area', 1, 1, nelem); shg = mesh.shg(:,:,:); ## Computation for inode = 1:4 for jnode = 1:4 ginode(inode,jnode,:) = t(inode,:); gjnode(inode,jnode,:) = t(jnode,:); Lloc(inode,jnode,:) = ... sum( shg(:,inode,:) .* shg(:,jnode,:), 1) .* epsilonareak; endfor endfor vloc = v(t(1:4, :)); [bp12,bm12] = bimu_bernoulli (vloc(2,:)-vloc(1,:)); [bp13,bm13] = bimu_bernoulli (vloc(3,:)-vloc(1,:)); [bp14,bm14] = bimu_bernoulli (vloc(4,:)-vloc(1,:)); [bp23,bm23] = bimu_bernoulli (vloc(3,:)-vloc(2,:)); [bp24,bm24] = bimu_bernoulli (vloc(4,:)-vloc(2,:)); [bp34,bm34] = bimu_bernoulli (vloc(4,:)-vloc(3,:)); bp12 = reshape (bp12, 1, 1, nelem) .* Lloc(1,2,:); bm12 = reshape (bm12, 1, 1, nelem) .* Lloc(1,2,:); bp13 = reshape (bp13, 1, 1, nelem) .* Lloc(1,3,:); bm13 = reshape (bm13, 1, 1, nelem) .* Lloc(1,3,:); bp14 = reshape (bp14, 1, 1, nelem) .* Lloc(1,4,:); bm14 = reshape (bm14, 1, 1, nelem) .* Lloc(1,4,:); bp23 = reshape (bp23, 1, 1, nelem) .* Lloc(2,3,:); bm23 = reshape (bm23, 1, 1, nelem) .* Lloc(2,3,:); bp24 = reshape (bp24, 1, 1, nelem) .* Lloc(2,4,:); bm24 = reshape (bm24, 1, 1, nelem) .* Lloc(2,4,:); bp34 = reshape (bp34, 1, 1, nelem) .* Lloc(3,4,:); bm34 = reshape (bm34, 1, 1, nelem) .* Lloc(3,4,:); ## SGloc=[... ## -bm12-bm13-bm14,bp12 ,bp13 ,bp14 ## bm12 ,-bp12-bm23-bm24 ,bp23 ,bp24 ## bm13 ,bm23 ,-bp13-bp23-bm34,bp34 ## bm14 ,bm24 ,bm34 ,-bp14-bp24-bp34... ## ]; Sloc(1,1,:) = -bm12-bm13-bm14; Sloc(1,2,:) = bp12; Sloc(1,3,:) = bp13; Sloc(1,4,:) = bp14; Sloc(2,1,:) = bm12; Sloc(2,2,:) = -bp12-bm23-bm24; Sloc(2,3,:) = bp23; Sloc(2,4,:) = bp24; Sloc(3,1,:) = bm13; Sloc(3,2,:) = bm23; Sloc(3,3,:) = -bp13-bp23-bm34; Sloc(3,4,:) = bp34; Sloc(4,1,:) = bm14; Sloc(4,2,:) = bm24; Sloc(4,3,:) = bm34; Sloc(4,4,:) = -bp14-bp24-bp34; ## assemble global matrix SG = sparse(ginode(:),gjnode(:),Sloc(:), nnodes, nnodes); endfunction bim-1.1.8/inst/bim3a_boundary_mass.m000066400000000000000000000047751502773057700173760ustar00rootroot00000000000000## Copyright (C) 2006,2007,2008,2009,2010 Carlo de Falco, Massimiliano Culpo ## ## This file is part of: ## BIM - Diffusion Advection Reaction PDE Solver ## ## BIM 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. ## ## BIM 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 BIM; If not, see . ## ## author: Carlo de Falco ## author: Matteo Porro ## -*- texinfo -*- ## @deftypefn {Function File} {[@var{M}]} = @ ## bim3a_boundary_mass(@var{mesh},@var{facelist},@var{nodelist}) ## ## Build the lumped boundary mass matrix needed to apply Robin boundary ## conditions. ## ## The vector @var{facelist} contains the list of the faces contributing ## to the mass matrix. ## ## The optional argument @var{nodelist} contains the list of the ## degrees of freedom on the boundary. ## ## @seealso{bim3a_rhs, bim3a_advection_diffusion, bim3a_laplacian, ## bim3a_reaction, bim2a_boundary_mass} ## @end deftypefn function [M] = bim3a_boundary_mass (mesh, facelist, nodelist) ## Check input if (nargin > 3) error ("bim3a_boundary_mass: wrong number of input parameters."); elseif (! ((isstruct (mesh)) && (isfield (mesh, "p")) && (isfield (mesh, "t")) && isfield(mesh, "e"))) error (["bim3a_boundary_mass: first input", ... " is not a valid mesh structure."]); elseif (! ((isvector (facelist)) && (isnumeric (facelist)))) error (["bim3a_boundary_mass: second ", ... "input is not a valid numeric vector."]); endif if (nargin < 3) [nodelist] = bim3c_unknowns_on_faces (mesh, facelist); endif p = mesh.p; t = []; for ie = facelist t = [t, mesh.e([1:3 10], mesh.e(10,:) == ie)]; endfor area = 1/2 * norm (cross (p(:,t(2,:))-p(:,t(1,:)), p(:,t(3,:))-p(:,t(1,:))), 2, 'columns'); dd = zeros (size (nodelist)); for in = 1:numel (nodelist) dd (in) = 1/3 * sum (area (any (t(1:3,:) == nodelist(in)))); endfor M = sparse (diag (dd)); endfunction bim-1.1.8/inst/bim3a_laplacian.m000066400000000000000000000070051502773057700164410ustar00rootroot00000000000000## Copyright (C) 2006,2007,2008,2009,2010 Carlo de Falco, Massimiliano Culpo ## ## This file is part of: ## BIM - Diffusion Advection Reaction PDE Solver ## ## BIM 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. ## ## BIM 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 BIM; If not, see . ## ## author: Carlo de Falco ## author: Massimiliano Culpo ## -*- texinfo -*- ## @deftypefn {Function File} @ ## {@var{A}} = bim3a_laplacian (@var{mesh}, @var{epsilon}, @var{kappa}) ## ## Build the standard finite element stiffness matrix for a diffusion ## problem. ## ## The equation taken into account is: ## ## - (@var{epsilon} * @var{kappa} ( u' ))' = f ## ## where @var{epsilon} is an element-wise constant scalar function, ## while @var{kappa} is a piecewise linear conforming scalar function. ## ## @seealso{bim3a_rhs, bim3a_reaction, bim2a_laplacian, bim3a_laplacian} ## @end deftypefn function [A] = bim3a_laplacian (mesh,epsilon,kappa) ## Check input if nargin != 3 error("bim3a_laplacian: wrong number of input parameters."); elseif !(isstruct(mesh) && isfield(mesh,"p") && isfield (mesh,"t") && isfield(mesh,"e")) error("bim3a_laplacian: first input is not a valid mesh structure."); endif p = mesh.p; t = mesh.t; nnodes = columns(p); nelem = columns(t); ## Turn scalar input to a vector of appropriate size if isscalar(epsilon) epsilon = epsilon * ones(nelem,1); endif if isscalar(kappa) kappa = kappa*ones(nnodes,1); endif if !( isvector(epsilon) && isvector(kappa) ) error("bim3a_laplacian: coefficients are not valid vectors."); elseif (numel (epsilon) != nelem) error("bim3a_laplacian: length of epsilon is not equal to the number of elements."); elseif (numel (kappa) != nnodes) error("bim2a_laplacian: length of kappa is not equal to the number of nodes."); endif ## Local contributions Lloc = zeros(4,4,nelem); kappaepsilonareak = reshape (4./sum (1./kappa(:)(mesh.t (1:4)), 1)(:) .* epsilon(:) .* mesh.area(:), 1, 1, nelem); shg = mesh.shg(:,:,:); ## Computation for inode = 1:4 for jnode = 1:4 ginode(inode,jnode,:) = mesh.t(inode,:); gjnode(inode,jnode,:) = mesh.t(jnode,:); Lloc(inode,jnode,:) = sum( kappa(inode) * shg(:,inode,:) .* shg(:,jnode,:),1) .* kappaepsilonareak; endfor endfor ## Assembly A = sparse(ginode(:),gjnode(:),Lloc(:)); endfunction %!shared mesh,epsilon,kappa,nnodes,nelem % x = y = z = linspace(0,1,4); % [mesh] = msh3m_structured_mesh(x,y,z,1,1:6); % [mesh] = bim3c_mesh_properties(mesh); % nnodes = columns(mesh.p); % nelem = columns(mesh.t); % epsilon = ones(columns(mesh.t),1); % kappa = ones(columns(mesh.p),1); %!test % [A] = bim3a_laplacian(mesh,epsilon,kappa); % assert(size(A),[nnodes, nnodes]); %!test % [A1] = bim3a_laplacian(mesh,3*epsilon,kappa); % [A2] = bim3a_laplacian(mesh,epsilon,3*kappa); % assert(A1,A2); %!test % [A1] = bim3a_laplacian(mesh,epsilon,kappa); % [A2] = bim3a_laplacian(mesh,1,1); % assert(A1,A2); bim-1.1.8/inst/bim3a_osc_advection_diffusion.m000066400000000000000000000266771502773057700214230ustar00rootroot00000000000000## Copyright (C) 2012 Carlo de Falco ## ## This file is part of: ## BIM - Diffusion Advection Reaction PDE Solver ## ## BIM 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. ## ## BIM 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 BIM; If not, see . ## ## author: Carlo de Falco ## -*- texinfo -*- ## ## @deftypefn {Function File} @ ## {[@var{A}]} = bim3a_osc_advection_diffusion (@var{mesh}, @var{alpha}, @var{v}) ## ## Build the Scharfetter-Gummel stabilized OSC stiffness ## matrix for a diffusion-advection problem. ## ## For details on the Orthogonal Subdomain Collocation (OSC) method ## see: M.Putti and C.Cordes, SIAM J.SCI.COMPUT. Vol.19(4), pp.1154-1168, 1998. ## ## The equation taken into account is: ## ## - div (@var{alpha} ( grad (u) - grad (@var{v}) u)) = f ## ## where @var{v} is a piecewise linear continuous scalar ## functions and @var{alpha} is a piecewise constant scalar function. ## ## @seealso{bim3a_rhs, bim3a_osc_laplacian, bim3a_reaction, bim3a_laplacian, bim3c_mesh_properties} ## @end deftypefn function M = bim3a_osc_advection_diffusion (msh, epsilon, v) ## Check input if (nargin != 3) print_usage (); elseif (! (isstruct (msh) && isfield (msh, "p") && isfield (msh, "t") && isfield (msh, "e"))) error (["bim3a_laplacian: first input ", ... "is not a valid msh structure"]); endif nnodes = columns (msh.p); nelem = columns (msh.t); ## Turn scalar input to a vector of appropriate size if (isscalar (epsilon)) epsilon = epsilon * ones(nelem, 1); endif if (! isvector (epsilon)) error ("bim3a_laplacian: coefficient is not a vector"); elseif (numel (epsilon) != nelem) error (["bim3a_laplacian: length of epsilon is ", ... "not equal to the number of mesh elements"]); endif ## Avoid warnings for broadcasting warning ("off", "Octave:broadcast", "local") ## Local contributions Lloc = __osc_local_laplacian__ (msh.p, msh.t, msh.shg, epsilon, msh.area, nnodes, nelem); ## Stabilization if (isscalar (v)) v = zeros (nelem, 1); endif vloc = v(msh.t(1:4, :)); [bp12, bm12] = bimu_bernoulli (vloc(2,:)-vloc(1,:)); [bp13, bm13] = bimu_bernoulli (vloc(3,:)-vloc(1,:)); [bp14, bm14] = bimu_bernoulli (vloc(4,:)-vloc(1,:)); [bp23, bm23] = bimu_bernoulli (vloc(3,:)-vloc(2,:)); [bp24, bm24] = bimu_bernoulli (vloc(4,:)-vloc(2,:)); [bp34, bm34] = bimu_bernoulli (vloc(4,:)-vloc(3,:)); bp12 = reshape (bp12, 1, 1, nelem) .* Lloc(1,2,:); bm12 = reshape (bm12, 1, 1, nelem) .* Lloc(1,2,:); bp13 = reshape (bp13, 1, 1, nelem) .* Lloc(1,3,:); bm13 = reshape (bm13, 1, 1, nelem) .* Lloc(1,3,:); bp14 = reshape (bp14, 1, 1, nelem) .* Lloc(1,4,:); bm14 = reshape (bm14, 1, 1, nelem) .* Lloc(1,4,:); bp23 = reshape (bp23, 1, 1, nelem) .* Lloc(2,3,:); bm23 = reshape (bm23, 1, 1, nelem) .* Lloc(2,3,:); bp24 = reshape (bp24, 1, 1, nelem) .* Lloc(2,4,:); bm24 = reshape (bm24, 1, 1, nelem) .* Lloc(2,4,:); bp34 = reshape (bp34, 1, 1, nelem) .* Lloc(3,4,:); bm34 = reshape (bm34, 1, 1, nelem) .* Lloc(3,4,:); Sloc(1,1,:) = -bm12-bm13-bm14; Sloc(1,2,:) = bp12; Sloc(1,3,:) = bp13; Sloc(1,4,:) = bp14; Sloc(2,1,:) = bm12; Sloc(2,2,:) = -bp12-bm23-bm24; Sloc(2,3,:) = bp23; Sloc(2,4,:) = bp24; Sloc(3,1,:) = bm13; Sloc(3,2,:) = bm23; Sloc(3,3,:) = -bp13-bp23-bm34; Sloc(3,4,:) = bp34; Sloc(4,1,:) = bm14; Sloc(4,2,:) = bm24; Sloc(4,3,:) = bm34; Sloc(4,4,:) = -bp14-bp24-bp34; ## Assembly for inode = 1:4 for jnode = 1:4 ginode(inode, jnode,:) = msh.t(inode, :); gjnode(inode, jnode,:) = msh.t(jnode, :); endfor endfor M = sparse (ginode(:), gjnode(:), Sloc(:), nnodes, nnodes); endfunction %!shared msh, epsilon, M, nnodes, nelem, x, y, z %!test %! msh = bim3c_mesh_properties (msh3m_structured_mesh (0:5, 0:5, 0:5, 1, 1:6)); %! x = msh.p (1, :).'; %! y = msh.p (2, :).'; %! z = msh.p (3, :).'; %! u = ones (size (x)); %! M = bim3a_osc_advection_diffusion (msh, 1, 0); %! assert (M * u, zeros (size (u)), eps * 100) %!test %! u = x; %! bnd = bim3c_unknowns_on_faces (msh, [1, 2]); %! int = setdiff (1:columns (msh.p), bnd); %! assert (M(int, int) * u(int), -M(int, bnd) * u(bnd), 100 * eps) %!test %! u = y; %! bnd = bim3c_unknowns_on_faces (msh, [3, 4]); %! int = setdiff (1:columns (msh.p), bnd); %! assert (M(int, int) * u(int), -M(int, bnd) * u(bnd), 100 * eps) %!test %! u = z; %! bnd = bim3c_unknowns_on_faces (msh, [5, 6]); %! int = setdiff (1:columns (msh.p), bnd); %! assert (M(int, int) * u(int), -M(int, bnd) * u(bnd), 100 * eps) %!test %! u = z; %! bnd = bim3c_unknowns_on_faces (msh, [5, 6]); %! int = setdiff (1:columns (msh.p), bnd); %! M = bim3a_osc_advection_diffusion (msh, pi, 0); %! assert (M(int, int) * u(int), -M(int, bnd) * u(bnd), 100 * eps) %!test %! M = bim3a_osc_advection_diffusion (msh, 1, x); %! assert (norm (sum (M, 1), inf), 0, eps * 100) %!test %! M = bim3a_osc_advection_diffusion (msh, 1, y); %! assert (norm (sum (M, 1), inf), 0, eps * 100) %!test %! M = bim3a_osc_advection_diffusion (msh, 1, z); %! assert (norm (sum (M, 1), inf), 0, eps * 100) %!demo %! gmsh_input = [["Point(1) = {0, 0, 0, .1}; \n"], ... %! ["Point(2) = {1, 0, 0, .1}; \n"], ... %! ["Point(3) = {0, -.3, 0, .1}; \n"], ... %! ["Point(4) = {0, +.3, 0, .1}; \n"], ... %! ["Point(5) = {1, -.3, 0, .1}; \n"], ... %! ["Point(6) = {1, 0.3, 0, .1}; \n"], ... %! ["Point(7) = {0, 0, -.3, .1}; \n"], ... %! ["Point(8) = {0, 0, +.3, .1}; \n"], ... %! ["Point(9) = {1, 0, -.3, .1}; \n"], ... %! ["Point(10) = {1, 0, 0.3, .1}; \n"], ... %! ["Circle(1) = {4, 1, 7}; \n"], ... %! ["Circle(2) = {7, 1, 3}; \n"], ... %! ["Circle(3) = {3, 1, 8}; \n"], ... %! ["Circle(4) = {8, 1, 4}; \n"], ... %! ["Circle(5) = {6, 2, 9}; \n"], ... %! ["Circle(6) = {9, 2, 5}; \n"], ... %! ["Circle(7) = {5, 2, 10}; \n"], ... %! ["Circle(8) = {10, 2, 6}; \n"], ... %! ["Line(9) = {4, 6}; \n"], ... %! ["Line(10) = {3, 5}; \n"], ... %! ["Line(11) = {8, 10}; \n"], ... %! ["Line(12) = {7, 9}; \n"], ... %! ["Line Loop(13) = {4, 1, 2, 3}; \n"], ... %! ["Plane Surface(14) = {13}; \n"], ... %! ["Line Loop(15) = {5, 6, 7, 8}; \n"], ... %! ["Plane Surface(16) = {15}; \n"], ... %! ["Line Loop(17) = {9, -8, -11, 4}; \n"], ... %! ["Ruled Surface(18) = {17}; \n"], ... %! ["Line Loop(19) = {12, -5, -9, 1}; \n"], ... %! ["Ruled Surface(20) = {19}; \n"], ... %! ["Line Loop(21) = {12, 6, -10, -2}; \n"], ... %! ["Ruled Surface(22) = {21}; \n"], ... %! ["Line Loop(23) = {11, -7, -10, 3}; \n"], ... %! ["Ruled Surface(24) = {23}; \n"], ... %! ["Surface Loop(25) = {18, 20, 22, 16, 24, 14}; \n"], ... %! ["Volume(26) = {25}; \n"]]; %! fname = tmpnam (); %! [fid, msg] = fopen (strcat (fname, ".geo"), "w"); %! if (fid < 0); error (msg); endif %! fputs (fid, gmsh_input); %! fclose (fid); %! msh = bim3c_mesh_properties (msh3m_gmsh (fname, "clscale", ".25")); %! x = msh.p (1, :).'; %! u = x; %! bnd = bim3c_unknowns_on_faces (msh, [14, 16]); %! int = setdiff (1:columns (msh.p), bnd); %! Mosc = bim3a_osc_advection_diffusion (msh, 1, msh.p(1,:)'*0); %! Mgal = bim3a_advection_diffusion (msh, 1, msh.p(1,:)'*0); %! u(int) = Mosc(int, int) \ ( - Mosc(int, bnd) * u(bnd)); %! uosc = u; %! u(int) = Mgal(int, int) \ ( - Mgal(int, bnd) * u(bnd)); %! ugal = u; %! fname_out = tmpnam (); %! printf ("saving results to %s \n", strcat (fname_out, ".vtu")); %! fpl_vtk_raw_write_field (fname_out, msh, {uosc, "u_osc"; ugal, "u_galerkin"}, {}); %! unlink (fname); %!demo %! gmsh_input = [["Point(1) = {0, 0, 0, .1}; \n"], ... %! ["Point(2) = {1, 0, 0, .1}; \n"], ... %! ["Point(3) = {0, -.3, 0, .1}; \n"], ... %! ["Point(4) = {0, +.3, 0, .1}; \n"], ... %! ["Point(5) = {1, -.3, 0, .1}; \n"], ... %! ["Point(6) = {1, 0.3, 0, .1}; \n"], ... %! ["Point(7) = {0, 0, -.3, .1}; \n"], ... %! ["Point(8) = {0, 0, +.3, .1}; \n"], ... %! ["Point(9) = {1, 0, -.3, .1}; \n"], ... %! ["Point(10) = {1, 0, 0.3, .1}; \n"], ... %! ["Circle(1) = {4, 1, 7}; \n"], ... %! ["Circle(2) = {7, 1, 3}; \n"], ... %! ["Circle(3) = {3, 1, 8}; \n"], ... %! ["Circle(4) = {8, 1, 4}; \n"], ... %! ["Circle(5) = {6, 2, 9}; \n"], ... %! ["Circle(6) = {9, 2, 5}; \n"], ... %! ["Circle(7) = {5, 2, 10}; \n"], ... %! ["Circle(8) = {10, 2, 6}; \n"], ... %! ["Line(9) = {4, 6}; \n"], ... %! ["Line(10) = {3, 5}; \n"], ... %! ["Line(11) = {8, 10}; \n"], ... %! ["Line(12) = {7, 9}; \n"], ... %! ["Line Loop(13) = {4, 1, 2, 3}; \n"], ... %! ["Plane Surface(14) = {13}; \n"], ... %! ["Line Loop(15) = {5, 6, 7, 8}; \n"], ... %! ["Plane Surface(16) = {15}; \n"], ... %! ["Line Loop(17) = {9, -8, -11, 4}; \n"], ... %! ["Ruled Surface(18) = {17}; \n"], ... %! ["Line Loop(19) = {12, -5, -9, 1}; \n"], ... %! ["Ruled Surface(20) = {19}; \n"], ... %! ["Line Loop(21) = {12, 6, -10, -2}; \n"], ... %! ["Ruled Surface(22) = {21}; \n"], ... %! ["Line Loop(23) = {11, -7, -10, 3}; \n"], ... %! ["Ruled Surface(24) = {23}; \n"], ... %! ["Surface Loop(25) = {18, 20, 22, 16, 24, 14}; \n"], ... %! ["Volume(26) = {25}; \n"]]; %! fname = tmpnam (); %! [fid, msg] = fopen (strcat (fname, ".geo"), "w"); %! if (fid < 0); error (msg); endif %! fputs (fid, gmsh_input); %! fclose (fid); %! msh = bim3c_mesh_properties (msh3m_gmsh (fname, "clscale", ".25")); %! x = msh.p (1, :).'; %! u = x; %! bnd = bim3c_unknowns_on_faces (msh, [14, 16]); %! int = setdiff (1:columns (msh.p), bnd); %! Mosc = bim3a_osc_advection_diffusion (msh, 1, msh.p(1,:)'*0); %! Mgal = bim3a_advection_diffusion (msh, 1, msh.p(1,:)'*0); %! f = bim3a_rhs (msh, 10, 1); %! u(int) = Mosc(int, int) \ (f(int) - Mosc(int, bnd) * u(bnd)); %! uosc = u; %! u(int) = Mgal(int, int) \ (f(int) - Mgal(int, bnd) * u(bnd)); %! ugal = u; %! fname_out = tmpnam (); %! printf ("saving results to %s \n", strcat (fname_out, ".vtu")); %! fpl_vtk_raw_write_field (fname_out, msh, {uosc, "u_osc"; ugal, "u_galerkin"}, {}); %! unlink (fname); bim-1.1.8/inst/bim3a_osc_laplacian.m000066400000000000000000000073101502773057700173040ustar00rootroot00000000000000## Copyright (C) 2012 Carlo de Falco ## ## This file is part of: ## BIM - Diffusion Advection Reaction PDE Solver ## ## BIM 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. ## ## BIM 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 BIM; If not, see . ## ## author: Carlo de Falco ## -*- texinfo -*- ## @deftypefn {Function File} @ ## {@var{A}} = bim3a_osc_laplacian (@var{mesh}, @var{epsilon}) ## ## Build the osc finite element stiffness matrix for a diffusion ## problem. ## ## For details on the Orthogonal Subdomain Collocation (OSC) method ## see: M.Putti and C.Cordes, SIAM J.SCI.COMPUT. Vol.19(4), pp.1154-1168, 1998. ## ## The equation taken into account is: ## ## - div (@var{epsilon} grad (u)) = f ## ## where @var{epsilon} is an element-wise constant scalar function. ## ## @seealso{bim3a_rhs, bim3a_reaction, bim2a_laplacian, bim3a_laplacian} ## @end deftypefn function M = bim3a_osc_laplacian (msh, epsilon) ## Check input if (nargin != 2) print_usage (); elseif (! (isstruct (msh) && isfield (msh, "p") && isfield (msh, "t") && isfield (msh, "e"))) error (["bim3a_osc_laplacian: first input ", ... "is not a valid msh structure"]); endif nnodes = columns (msh.p); nelem = columns (msh.t); ## Turn scalar input to a vector of appropriate size if (isscalar (epsilon)) epsilon = epsilon * ones (nelem, 1); endif if (! isvector (epsilon)) error ("bim3a_osc_laplacian: coefficient is not a vector"); elseif (numel (epsilon) != nelem) error (["bim3a_osc_laplacian: length of epsilon is ", ... "not equal to the number of mesh elements"]); endif ## Avoid warnings for broadcasting warning ("off", "Octave:broadcast", "local") ## Local contributions Lloc = __osc_local_laplacian__ (msh.p, msh.t, msh.shg, epsilon, msh.area, nnodes, nelem); ## Assembly for inode = 1:4 for jnode = 1:4 ginode(inode, jnode,:) = msh.t(inode, :); gjnode(inode, jnode,:) = msh.t(jnode, :); endfor endfor M = sparse (ginode(:), gjnode(:), Lloc(:), nnodes, nnodes); endfunction %!shared msh, epsilon, M, nnodes, nelem, x, y, z %!test %! msh = bim3c_mesh_properties (msh3m_structured_mesh (0:5, 0:5, 0:5, 1, 1:6)); %! x = msh.p (1, :).'; %! y = msh.p (2, :).'; %! z = msh.p (3, :).'; %! u = ones (size (x)); %! M = bim3a_osc_laplacian (msh, 1); %! assert (M * u, zeros (size (u)), eps * 100) %!test %! u = x; %! bnd = bim3c_unknowns_on_faces (msh, [1, 2]); %! int = setdiff (1:columns (msh.p), bnd); %! assert (M(int, int) * u(int), -M(int, bnd) * u(bnd), 100 * eps) %!test %! u = y; %! bnd = bim3c_unknowns_on_faces (msh, [3, 4]); %! int = setdiff (1:columns (msh.p), bnd); %! assert (M(int, int) * u(int), -M(int, bnd) * u(bnd), 100 * eps) %!test %! u = z; %! bnd = bim3c_unknowns_on_faces (msh, [5, 6]); %! int = setdiff (1:columns (msh.p), bnd); %! assert (M(int, int) * u(int), -M(int, bnd) * u(bnd), 100 * eps) %!test %! u = z; %! bnd = bim3c_unknowns_on_faces (msh, [5, 6]); %! int = setdiff (1:columns (msh.p), bnd); %! M = bim3a_osc_laplacian (msh, pi); %! assert (M(int, int) * u(int), -M(int, bnd) * u(bnd), 100 * eps) bim-1.1.8/inst/bim3a_reaction.m000066400000000000000000000062401502773057700163210ustar00rootroot00000000000000## Copyright (C) 2006,2007,2008,2009,2010 Carlo de Falco, Massimiliano Culpo ## ## This file is part of: ## BIM - Diffusion Advection Reaction PDE Solver ## ## BIM 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. ## ## BIM 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 BIM; If not, see . ## ## author: Carlo de Falco ## author: Massimiliano Culpo ## -*- texinfo -*- ## @deftypefn {Function File} @ ## {[@var{C}]} = bim3a_reaction (@var{mesh},@var{delta},@var{zeta}) ## ## Build the lumped finite element mass matrix for a diffusion ## problem. ## ## The equation taken into account is: ## ## @var{delta} * @var{zeta} * u = f ## ## where @var{delta} is an element-wise constant scalar function, while ## @var{zeta} is a piecewise linear conforming scalar function. ## ## @seealso{bim3a_rhs, bim3a_laplacian, bim2a_reaction, bim3a_reaction} ## @end deftypefn function [C] = bim3a_reaction (mesh,delta,zeta); ## Check input if nargin != 3 error("bim3a_reaction: wrong number of input parameters."); elseif !(isstruct(mesh) && isfield(mesh,"p") && isfield (mesh,"t") && isfield(mesh,"e")) error("bim3a_reaction: first input is not a valid mesh structure."); endif nnodes = columns (mesh.p); nelem = columns (mesh.t); ## Turn scalar input to a vector of appropriate size if isscalar(delta) delta = delta*ones(nelem,1); endif if isscalar(zeta) zeta = zeta*ones(nnodes,1); endif if !( isvector(delta) && isvector(zeta) ) error("bim3a_reaction: coefficients are not valid vectors."); elseif (numel (delta) != nelem) error("bim3a_: length of alpha is not equal to the number of elements."); elseif (numel (zeta) != nnodes) error("bim3a_: length of gamma is not equal to the number of nodes."); endif Cloc = zeros(4,nelem); coeff = zeta(mesh.t(1:4,:)); coeffe = delta; wjacdet = mesh.wjacdet; for inode = 1:4 Cloc(inode,:) = coeffe'.*coeff(inode,:).*wjacdet(inode,:); endfor gnode = (mesh.t(1:4,:)); ## Global matrix C = sparse(gnode(:),gnode(:),Cloc(:)); endfunction %!shared mesh,delta,zeta,nnodes,nelem % x = y = z = linspace(0,1,4); % [mesh] = msh3m_structured_mesh(x,y,z,1,1:6); % [mesh] = bim3c_mesh_properties(mesh); % nnodes = columns(mesh.p); % nelem = columns(mesh.t); % delta = ones(columns(mesh.t),1); % zeta = ones(columns(mesh.p),1); %!test % [C] = bim3a_reaction(mesh,delta,zeta); % assert(size(C),[nnodes, nnodes]); %!test % [C1] = bim3a_reaction(mesh,3*delta,zeta); % [C2] = bim3a_reaction(mesh,delta,3*zeta); % assert(C1,C2); %!test % [C1] = bim2a_reaction(mesh,3*delta,zeta); % [C2] = bim2a_reaction(mesh,3,1); % assert(C1,C2); bim-1.1.8/inst/bim3a_rhs.m000066400000000000000000000060401502773057700153070ustar00rootroot00000000000000## Copyright (C) 2006,2007,2008,2009,2010 Carlo de Falco, Massimiliano Culpo ## ## This file is part of: ## BIM - Diffusion Advection Reaction PDE Solver ## ## BIM 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. ## ## BIM 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 BIM; If not, see . ## ## author: Carlo de Falco ## author: Massimiliano Culpo ## -*- texinfo -*- ## @deftypefn {Function File} {[@var{b}]} = @ ## bim3a_rhs (@var{mesh}, @var{f}, @var{g}) ## ## Build the finite element right-hand side of a diffusion problem ## employing mass-lumping. ## ## The equation taken into account is: ## ## @var{delta} * u = @var{f} * @var{g} ## ## where @var{f} is an element-wise constant scalar function, while ## @var{g} is a piecewise linear conforming scalar function. ## ## @seealso{bim3a_reaction, bim3_laplacian, bim1a_reaction, ## bim2a_reaction} ## @end deftypefn function [b] = bim3a_rhs (mesh,f,g); ## Check input if nargin != 3 error("bim3a_rhs: wrong number of input parameters."); elseif !(isstruct(mesh) && isfield(mesh,"p") && isfield (mesh,"t") && isfield(mesh,"e")) error("bim3a_rhs: first input is not a valid mesh structure."); endif nnodes = columns (mesh.p); nelem = columns (mesh.t); ## Turn scalar input to a vector of appropriate size if isscalar(f) f = f*ones(nelem,1); endif if isscalar(g) g = g*ones(nnodes,1); endif if !( isvector(f) && isvector(g) ) error("bim3a_rhs: coefficients are not valid vectors."); elseif (numel (f) != nelem) error("bim3a_rhs: length of f is not equal to the number of elements."); elseif (numel (g) != nnodes) error("bim3a_rhs: length of g is not equal to the number of nodes."); endif bloc = zeros(4,nelem); coeff = g(mesh.t(1:4,:)); coeffe = f; wjacdet = mesh.wjacdet; for inode = 1:4 bloc(inode,:) = coeffe'.*coeff(inode,:).*wjacdet(inode,:); endfor gnode = (mesh.t(1:4,:)); ## Global matrix b = sparse(gnode(:),1,bloc(:)); endfunction %!shared mesh,f,g,nnodes,nelem % x = y = z = linspace(0,1,4); % [mesh] = msh3m_structured_mesh(x,y,z,1,1:6); % [mesh] = bim3c_mesh_properties(mesh); % nnodes = columns(mesh.p); % nelem = columns(mesh.t); % g = ones(columns(mesh.t),1); % f = ones(columns(mesh.p),1); %!test % [b] = bim3a_rhs(mesh,f,g); % assert(size(b),[nnodes, 1]); %!test % [b1] = bim3a_rhs(mesh,3*f,g); % [b2] = bim3a_rhs(mesh,f,3*g); % assert(b1,b2); %!test % [b1] = bim2a_rhs(mesh,3*f,g); % [b2] = bim2a_rhs(mesh,3,1); % assert(b1,b2); bim-1.1.8/inst/bim3c_global_flux.m000066400000000000000000000101371502773057700170150ustar00rootroot00000000000000## Copyright (C) 2012 Carlo de Falco ## ## This file is part of: ## BIM - Diffusion Advection Reaction PDE Solver ## ## BIM 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. ## ## BIM 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 BIM; If not, see . ## ## author: Carlo de Falco ## -*- texinfo -*- ## ## @deftypefn {Function File} @ ## {[@var{F}]} = @ ## bim3c_global_flux (@var{mesh}, @var{u}, @var{alpha}, @var{v}) ## ## Compute the flux associated with the Scharfetter-Gummel approximation ## of the scalar field @var{u}. ## ## The vector field is defined as: ## ## F =- @var{alpha} ( grad (u) - grad (@var{v}) u ) ## ## where @var{v} is a piecewise linear continuous scalar ## functions and @var{alpha} is a piecewise constant scalar function. ## ## @seealso{bim3a_rhs, bim3a_reaction, bim3a_laplacian, bim3c_mesh_properties} ## @end deftypefn function F = bim3c_global_flux (mesh, u, acoeff, v) t = mesh.t; nelem = columns (mesh.t); F = zeros (3, nelem); ## Local contributions Lloc = zeros (4,4,nelem); epsilonareak = reshape (acoeff .* mesh.area', 1, 1, nelem); shg = mesh.shg(:,:,:); ## Computation for inode = 1:4 for jnode = 1:4 ginode(inode,jnode,:) = t(inode,:); gjnode(inode,jnode,:) = t(jnode,:); Lloc(inode,jnode,:) = sum (shg(:,inode,:) .* shg(:,jnode,:), 1) ... .* epsilonareak; endfor endfor uloc = u(t(1:4, :)); vloc = v(t(1:4, :)); [bp12,bm12] = bimu_bernoulli (vloc(2,:)-vloc(1,:)); [bp13,bm13] = bimu_bernoulli (vloc(3,:)-vloc(1,:)); [bp14,bm14] = bimu_bernoulli (vloc(4,:)-vloc(1,:)); [bp23,bm23] = bimu_bernoulli (vloc(3,:)-vloc(2,:)); [bp24,bm24] = bimu_bernoulli (vloc(4,:)-vloc(2,:)); [bp34,bm34] = bimu_bernoulli (vloc(4,:)-vloc(3,:)); bp12 = reshape (bp12, 1, 1, nelem) .* Lloc(1,2,:); bm12 = reshape (bm12, 1, 1, nelem) .* Lloc(1,2,:); bp13 = reshape (bp13, 1, 1, nelem) .* Lloc(1,3,:); bm13 = reshape (bm13, 1, 1, nelem) .* Lloc(1,3,:); bp14 = reshape (bp14, 1, 1, nelem) .* Lloc(1,4,:); bm14 = reshape (bm14, 1, 1, nelem) .* Lloc(1,4,:); bp23 = reshape (bp23, 1, 1, nelem) .* Lloc(2,3,:); bm23 = reshape (bm23, 1, 1, nelem) .* Lloc(2,3,:); bp24 = reshape (bp24, 1, 1, nelem) .* Lloc(2,4,:); bm24 = reshape (bm24, 1, 1, nelem) .* Lloc(2,4,:); bp34 = reshape (bp34, 1, 1, nelem) .* Lloc(3,4,:); bm34 = reshape (bm34, 1, 1, nelem) .* Lloc(3,4,:); ## SGloc=[... ## -bm12-bm13-bm14,bp12 ,bp13 ,bp14 ## bm12 ,-bp12-bm23-bm24 ,bp23 ,bp24 ## bm13 ,bm23 ,-bp13-bp23-bm34,bp34 ## bm14 ,bm24 ,bm34 ,-bp14-bp24-bp34 ## ]; Sloc(1,1,:) = -bm12-bm13-bm14; Sloc(1,2,:) = bp12; Sloc(1,3,:) = bp13; Sloc(1,4,:) = bp14; Sloc(2,1,:) = bm12; Sloc(2,2,:) = -bp12-bm23-bm24; Sloc(2,3,:) = bp23; Sloc(2,4,:) = bp24; Sloc(3,1,:) = bm13; Sloc(3,2,:) = bm23; Sloc(3,3,:) = -bp13-bp23-bm34; Sloc(3,4,:) = bp34; Sloc(4,1,:) = bm14; Sloc(4,2,:) = bm24; Sloc(4,3,:) = bm34; Sloc(4,4,:) = -bp14-bp24-bp34; r = zeros (4, nelem); f = zeros (3, nelem); for iel = 1:nelem r(:,iel) = Sloc(:,:,iel) * uloc(:,iel); f(:,iel) = Lloc(1:3, 1:3, iel) \ r(1:3, iel); F(:,iel) = shg(:,1:3, iel) * f(:, iel); endfor endfunction %!test %! N = 10; pp = linspace (0, 1, N); msh = bim3c_mesh_properties (msh3m_structured_mesh (pp, pp, pp, 1, 1:6)); %! u = ones (N^3, 1); %! v = ones (N^3, 1); %! alpha = ones (columns (msh.t), 1); %! F = bim3c_global_flux (msh, u, alpha, v); %! assert (norm (F(:), inf), 0, 100*eps); bim-1.1.8/inst/bim3c_intrp.m000066400000000000000000000042271502773057700156560ustar00rootroot00000000000000## Copyright (C) 2011, 2012 Carlo de Falco ## ## This program is free software; you can redistribute it and/or modify ## it under the terms of the GNU General Public License as published by ## the Free Software Foundation; either version 3 of the License, or ## (at your option) any later version. ## ## This program is distributed in the hope that it will be useful, ## but WITHOUT ANY WARRANTY; without even the implied warranty of ## MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the ## GNU General Public License for more details. ## ## You should have received a copy of the GNU General Public License ## along with Octave; see the file COPYING. If not, see ## . ## -*- texinfo -*- ## ## @deftypefn {Function File} {@var{data}} = bim3c_intrp (@var{msh}, @var{n_data}, @var{e_data}, @var{points}) ## ## Compute interpolated values of node centered multicomponent node centered field @var{n_data} and ## cell centered field @var{n_data} at an arbitrary set of points whos coordinates are given in the ## n_by_3 matrix @var{points}. ## ## @end deftypefn ## Author: Carlo de Falco ## Created: 2012-10-01 function data = bim3c_intrp (msh, n_data, e_data, p) %% for each point, find the enclosing tetrahedron [t_list, b_list] = tsearchn (msh.p.', msh.t(1:4, :)', p); %% only keep points within tetrahedra invalid = isnan (t_list); t_list = t_list (! invalid); ntl = numel (t_list); b_list = b_list(! invalid, :); points(invalid,:) = []; data = []; if (! isempty (n_data)) data = cat (1, data, squeeze ( sum (reshape (n_data(msh.t(1:4, t_list), :), [4, ntl, (columns (n_data))]) .* repmat (b_list.', [1, 1, (columns (n_data))]), 1))); endif if (! isempty (e_data)) data = cat (1, data, e_data(t_list, :)); endif endfunction %!test %! msh = bim3c_mesh_properties (msh3m_structured_mesh (linspace (0, 1, 11), linspace (0, 1, 9), linspace (0, 1, 13), 1, 1:6)); %! x = y = z = linspace (0, 1, 100).'; %! u = msh.p(1, :).'; %! ui = bim3c_intrp (msh, u, [], [x, y, z]); %! assert (ui, linspace (0, 1, 100), 10*eps);bim-1.1.8/inst/bim3c_mesh_properties.m000066400000000000000000000041571502773057700177340ustar00rootroot00000000000000## Copyright (C) 2006,2007,2008,2009,2010 Carlo de Falco, Massimiliano Culpo ## ## This file is part of: ## BIM - Diffusion Advection Reaction PDE Solver ## ## BIM 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. ## ## BIM 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 BIM; If not, see . ## ## author: Carlo de Falco ## author: Massimiliano Culpo ## -*- texinfo -*- ## @deftypefn {Function File} {[@var{omesh}]} = @ ## bim3c_mesh_properties(@var{imesh}) ## ## Compute the properties of @var{imesh} needed by BIM method and append ## them to @var{omesh} as fields. ## ## @seealso{bim3a_reaction, bim3a_rhs, bim3a_laplacian} ## @end deftypefn function [omesh] = bim3c_mesh_properties (imesh) ## Check input if nargin != 1 error("bim3c_mesh_properties: wrong number of input parameters."); elseif (! isstruct (imesh) || any (! isfield (imesh, {"p", "e", "t"}))) error ("bim3c_mesh_properties: first input is not a valid mesh structure."); endif ## Compute properties omesh = imesh; [omesh.wjacdet,omesh.area,omesh.shg,omesh.shp] = ... msh3m_geometrical_properties (imesh, "wjacdet", "area", "shg", "shp"); endfunction %!shared mesh % x = y = z = linspace(0,1,4); % mesh = msh3m_structured_mesh(x,y,z,1,1:6); % mesh = bim3c_mesh_properties (mesh); %!test % tmp = msh3m_geometrical_properties (mesh, "wjacdet"); % assert(mesh.wjacdet,tmp); %!test % tmp = msh3m_geometrical_properties(mesh,"shg"); % assert(mesh.shg,tmp); %!test % tmp = msh3m_geometrical_properties(mesh,"shp"); % assert(mesh.shp,tmp); %!test % assert(mesh.area,sum(mesh.wjacdet,1)); bim-1.1.8/inst/bim3c_norm.m000066400000000000000000000115521502773057700154740ustar00rootroot00000000000000## Copyright (C) 2006-2013 Carlo de Falco, Massimiliano Culpo ## ## This file is part of: ## BIM - Diffusion Advection Reaction PDE Solver ## ## BIM 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. ## ## BIM 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 BIM; If not, see . ## ## author: Carlo de Falco ## author: Matteo Porro ## -*- texinfo -*- ## ## @deftypefn {Function File} {[@var{norm_u}]} = @ ## bim3c_norm(@var{mesh},@var{u},@var{norm_type}) ## ## Compute the @var{norm_type}-norm of function @var{u} on the domain described ## by the tetrahedral grid @var{mesh}. ## ## The input function @var{u} can be either a piecewise linear conforming scalar ## function or an elementwise constant scalar or vector function. ## ## The string parameter @var{norm_type} can be one among 'L2', 'H1' and 'inf'. ## ## Should the input function be piecewise constant, the H1 norm will not be ## computed and the function will return an error message. ## ## For the numerical integration of the L2 norm the second order quadrature rule ## by Keast is used (ref. P. Keast, Moderate degree tetrahedral quadrature ## formulas, CMAME 55: 339-348 1986). ## ## @seealso{bim1c_norm, bim2c_norm} ## ## @end deftypefn function [norm_u] = bim3c_norm (m, u, norm_type) ## Check input if (nargin != 3) error ("bim3c_norm: wrong number of input parameters."); elseif (! (isstruct (m) && isfield (m,"p")) && isfield (m, "t") && isfield (m, "e")) error ("bim3c_norm: first input is not a valid mesh structure."); endif nnodes = columns (m.p); nel = columns (m.t); if (isequal (size (u), [3, nel])) u = u'; endif if ((numel (u) != nnodes) && (rows (u) != nel)) error ("bim3c_norm: length(u) != nnodes and rows(u) != nel."); endif if (! (strcmp (norm_type,'L2') || strcmp (norm_type,'inf') || strcmp (norm_type,'H1'))) error ("bim3c_norm: invalid norm type parameter."); endif if (strcmp (norm_type,'inf')) norm_u = max (abs (u(:))); else if (numel (u) == nnodes) M = __mass_matrix__ (m); if (strcmp (norm_type, 'H1')) A = bim3a_laplacian (m, 1, 1); M += A; endif norm_u = sqrt(u' * M * u); else if (strcmp (norm_type, 'H1')) error (["bim3c_norm: cannot compute the H1 norm", ... "of an elementwise constant function."]); endif norm_u = m.area * (norm (u', 2, 'cols').^2)'; norm_u = sqrt (norm_u); endif endif endfunction function M = __mass_matrix__ (mesh) t = mesh.t; nnodes = columns (mesh.p); nelem = columns (t); ## Local contributions a = (5 + 3 * sqrt (5)) / 20; b = (5 - sqrt (5)) / 20; l1 = (1 - 3*b)^2 + 3*(1 - 2*b - a)^2; l2 = (1 - 3*b)*b + (1 - 2*b - a)*(a + 2*b); Mref = 1/4 * [l1 l2 l2 l2; l2 l1 l2 l2; l2 l2 l1 l2; l2 l2 l2 l1]; area = reshape (mesh.area, 1, 1, nelem); ## Computation for inode = 1:4 for jnode = 1:4 ginode(inode,jnode,:) = t(inode,:); gjnode(inode,jnode,:) = t(jnode,:); endfor endfor Mloc = area .* Mref; ## assemble global matrix M = sparse (ginode(:), gjnode(:), Mloc(:), nnodes, nnodes); endfunction %!test %!shared L, V, x, y, z, m %! L = rand (1); V = rand (1); x = linspace (0,L,4); y = x; z = x; %! m = msh3m_structured_mesh (x,y,z,1,1:6); %! m.area = msh3m_geometrical_properties (m, 'area'); %! m.shg = msh3m_geometrical_properties (m, 'shg'); %! u = V * ones (columns(m.p),1); %! uinf = bim3c_norm (m, u, 'inf'); %! uL2 = bim3c_norm (m, u, 'L2'); %! uH1 = bim3c_norm (m, u, 'H1'); %! assert ([uinf, uL2, uH1], [V, V*sqrt(L^3), V*sqrt(L^3)], 1e-12); %!test %! u = V * (m.p(1,:) + 2*m.p(2,:) + 3*m.p(3,:))'; %! uinf = bim3c_norm (m, u, 'inf'); %! uL2 = bim3c_norm (m, u, 'L2'); %! uH1 = bim3c_norm (m, u, 'H1'); %! assert ([uinf, uL2, uH1], %! [6*L*V, V*sqrt(61/6*L^5), V*sqrt(61/6*L^5 + 14*L^3)], %! 1e-12); %!test %! u = V * ones (columns(m.t),1); %! uinf = bim3c_norm (m, u, 'inf'); %! uL2 = bim3c_norm (m, u, 'L2'); %! assert ([uinf, uL2], [V, V*sqrt(L^3)], 1e-12); %!test %! u = V * ones (columns(m.t),1); %! uvect = [u, 2*u, 3*u]; %! uinf = bim3c_norm (m, uvect, 'inf'); %! uL2 = bim3c_norm (m, uvect, 'L2'); %! assert ([uinf, uL2], [3*V, V*sqrt(14*L^3)], 1e-12); bim-1.1.8/inst/bim3c_pde_gradient.m000066400000000000000000000035261502773057700171500ustar00rootroot00000000000000## Copyright (C) 2006,2007,2008,2009,2010 Carlo de Falco, Massimiliano Culpo ## ## This file is part of: ## BIM - Diffusion Advection Reaction PDE Solver ## ## BIM 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. ## ## BIM 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 BIM; If not, see . ## ## author: Carlo de Falco ## author: Massimiliano Culpo ## -*- texinfo -*- ## ## @deftypefn {Function File} {[@var{gx}, @var{gy}, @var{gz}]} = @ ## bim3c_pde_gradient(@var{mesh},@var{u}) ## ## Compute the gradient of the piecewise linear conforming scalar ## function @var{u}. ## ## @seealso{bim3c_global_flux} ## @end deftypefn function [gx, gy, gz] = bim3c_pde_gradient (mesh, u) ## Check input if (nargin != 2) error("bim3c_pde_gradient: wrong number of input parameters."); elseif (! (isstruct (mesh) && isfield (mesh,"p")) && isfield (mesh, "t") && isfield(mesh, "e")) error ("bim3c_pde_gradient: first input is not a valid mesh structure."); endif nnodes = columns (mesh.p); if (numel (u) != nnodes) error ("bim3c_pde_gradient: length(u) != nnodes."); endif gx = sum (squeeze (mesh.shg(1,:,:)) .* u(mesh.t(1:4,:)), 1); gy = sum (squeeze (mesh.shg(2,:,:)) .* u(mesh.t(1:4,:)), 1); gz = sum (squeeze (mesh.shg(3,:,:)) .* u(mesh.t(1:4,:)), 1); endfunction bim-1.1.8/inst/bim3c_tri_to_nodes.m000066400000000000000000000052261502773057700172120ustar00rootroot00000000000000## Copyright (C) 2011, 2012 Carlo de Falco ## ## This program is free software; you can redistribute it and/or modify ## it under the terms of the GNU General Public License as published by ## the Free Software Foundation; either version 3 of the License, or ## (at your option) any later version. ## ## This program is distributed in the hope that it will be useful, ## but WITHOUT ANY WARRANTY; without even the implied warranty of ## MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the ## GNU General Public License for more details. ## ## You should have received a copy of the GNU General Public License ## along with Octave; see the file COPYING. If not, see ## . ## -*- texinfo -*- ## ## @deftypefn {Function File} {@var{u_nod}} = bim3c_tri_to_nodes (@var{mesh}, @var{u_tri}) ## @deftypefnx {Function File} {@var{u_nod}} = bim3c_tri_to_nodes (@var{m_tri}, @var{u_tri}) ## @deftypefnx {Function File} {[@var{u_nod}, @var{m_tri}]} = bim3c_tri_to_nodes ( ... ) ## ## Compute interpolated values at triangle nodes @var{u_nod} given values at tetrahedral centers of mass @var{u_tri}. ## If called with more than one output, also return the interpolation matrix @var{m_tri} such that ## @code{u_nod = m_tri * u_tri}. ## If repeatedly performing interpolation on the same mesh the matrix @var{m_tri} obtained by a previous call ## to @code{bim2c_tri_to_nodes} may be passed as input to avoid unnecessary computations. ## ## @end deftypefn ## Author: Carlo de Falco ## Created: 2011-03-07 function [u_nod, m_tri] = bim3c_tri_to_nodes (m, u_tri) if (nargout > 1) if (isstruct (m)) nel = columns (m.t); nnod = columns (m.p); ii = m.t(1:4, :); jj = repmat (1:nel, 4, 1); vv = repmat (m.area(:)', 4, 1) / 4; m_tri = bim3a_reaction (m, 1, 1) \ sparse (ii, jj, vv, nnod, nel); elseif (ismatrix (m)) m_tri = m; else error ("bim3c_tri_to_nodes: first input parameter is of incorrect type"); endif u_nod = m_tri * u_tri; else if (isstruct (m)) rhs = bim3a_rhs (m, u_tri, 1); mass = bim3a_reaction (m, 1, 1); u_nod = full (mass \ rhs); elseif (ismatrix (m)) u_nod = m * u_tri; else error ("bim3c_tri_to_nodes: first input parameter is of incorrect type"); endif endif endfunction %!test %! msh = bim3c_mesh_properties (msh3m_structured_mesh (linspace (0, 1, 31), linspace (0, 1, 13), linspace (0, 1, 13), 1, 1:6)); %! nel = columns (msh.t); %! nnod = columns (msh.p); %! u_tri = randn (nel, 1); %! un1 = bim3c_tri_to_nodes (msh, u_tri); %! [un2, m] = bim3c_tri_to_nodes (msh, u_tri); %! assert (un1, un2, 1e-10) bim-1.1.8/inst/bim3c_unknowns_on_faces.m000066400000000000000000000040351502773057700202360ustar00rootroot00000000000000## Copyright (C) 2006,2007,2008,2009,2010 Carlo de Falco, Massimiliano Culpo ## ## This file is part of: ## BIM - Diffusion Advection Reaction PDE Solver ## ## BIM 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. ## ## BIM 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 BIM; If not, see . ## ## author: Carlo de Falco ## author: Massimiliano Culpo ## -*- texinfo -*- ## @deftypefn {Function File} {[@var{nodelist}]} = @ ## bim3c_unknowns_on_faces(@var{mesh},@var{facelist}) ## ## Return the list of the mesh nodes that lie on the geometrical faces ## specified in @var{facelist}. ## ## @seealso{bim3c_unknown_on_faces, bim2c_pde_gradient, ## bim2c_global_flux} ## ## @end deftypefn function [nodelist] = bim3c_unknowns_on_faces(mesh,facelist) ## Check input if nargin != 2 error("bim3c_unknowns_on_faces: wrong number of input parameters."); elseif !(isstruct(mesh) && isfield(mesh,"p") && isfield (mesh,"t") && isfield(mesh,"e")) error("bim3c_unknowns_on_faces: first input is not a valid mesh structure."); elseif !isnumeric(facelist) error("bim3c_unknowns_on_faces: second input is not a valid numeric vector."); endif [nodelist] = msh3m_nodes_on_faces(mesh,facelist); endfunction %!shared mesh % x = y = z = linspace(0,1,2); % [mesh] = msh3m_structured_mesh(x,y,z,1,1:6); %!test % assert( bim3c_unknowns_on_faces(mesh, 1),[1 2 5 6] ) %!test % assert( bim3c_unknowns_on_faces(mesh, 2),[3 4 7 8] ) %!test % assert( bim3c_unknowns_on_faces(mesh, [1 2]),1:8)bim-1.1.8/inst/bimu_bernoulli.m000066400000000000000000000041371502773057700164540ustar00rootroot00000000000000## Copyright (C) 2006,2007,2008,2009,2010 Carlo de Falco, Massimiliano Culpo ## ## This file is part of: ## BIM - Diffusion Advection Reaction PDE Solver ## ## BIM 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. ## ## BIM 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 BIM; If not, see . ## ## author: Carlo de Falco ## author: Massimiliano Culpo ## -*- texinfo -*- ## ## @deftypefn {Function File} @ ## {[@var{bp}, @var{bn}]} = bimu_bernoulli (@var{x}) ## ## Compute the values of the Bernoulli function corresponding to @var{x} ## and - @var{x} arguments. ## ## @seealso{bimu_logm} ## @end deftypefn function [bp,bn] = bimu_bernoulli(x) ## Check input if nargin != 1 error("bimu_bernoulli: wrong number of input parameters."); endif xlim= 1e-2; ax = abs(x); bp = zeros(size(x)); bn = bp; block1 = find(~ax); block21 = find((ax>80)&x>0); block22 = find((ax>80)&x<0); block3 = find((ax<=80)&(ax>xlim)); block4 = find((ax<=xlim)&(ax~=0)); ## X=0 bp(block1)=1.; bn(block1)=1.; ## ASYMPTOTICS bp(block21)=0.; bn(block21)=x(block21); bp(block22)=-x(block22); bn(block22)=0.; ## INTERMEDIATE VALUES bp(block3)=x(block3)./(exp(x(block3))-1); bn(block3)=x(block3)+bp(block3); ## SMALL VALUES if(any(block4))jj=1; fp=1.*ones(size(block4)); fn=fp; df=fp; segno=1.; while (norm(df,inf) > eps), jj=jj+1; segno=-segno; df=df.*x(block4)/jj; fp=fp+df; fn=fn+segno*df; endwhile; bp(block4)=1./fp; bn(block4)=1./fn; endif endfunction bim-1.1.8/inst/bimu_logm.m000066400000000000000000000031211502773057700154070ustar00rootroot00000000000000## Copyright (C) 2006,2007,2008,2009,2010 Carlo de Falco, Massimiliano Culpo ## ## This file is part of: ## BIM - Diffusion Advection Reaction PDE Solver ## ## BIM 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. ## ## BIM 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 BIM; If not, see . ## ## author: Carlo de Falco ## author: Massimiliano Culpo ## -*- texinfo -*- ## @deftypefn {Function File} @ ## {[@var{T}]} = bimu_logm (@var{t1},@var{t2}) ## ## Input: ## @itemize @minus ## @item @var{t1}: ## @item @var{t2}: ## @end itemize ## ## Output: ## @itemize @minus ## @item @var{T}: ## @end itemize ## ## @seealso{bimu_bern} ## @end deftypefn function [T] = bimu_logm(t1,t2) ## Check input if nargin != 2 error("bimu_logm: wrong number of input parameters."); elseif size(t1) != size(t2) error("bimu_logm: t1 and t2 are of different size."); endif T = zeros(size(t2)); sing = abs(t2-t1)< 100*eps ; T(sing) = (t2(sing)+t1(sing))/2; T(~sing) = (t2(~sing)-t1(~sing))./log(t2(~sing)./t1(~sing)); endfunction bim-1.1.8/inst/private/000077500000000000000000000000001502773057700147345ustar00rootroot00000000000000bim-1.1.8/inst/private/__osc_local_laplacian__.m000066400000000000000000000100451502773057700216500ustar00rootroot00000000000000## Copyright (C) 2012 Carlo de Falco ## ## This file is part of: ## BIM - Diffusion Advection Reaction PDE Solver ## ## BIM 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. ## ## BIM 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 BIM; If not, see . ## ## author: Carlo de Falco ## -*- texinfo -*- ## ## @deftypefn {Function File} @ ## {@var{Lloc}} = __osc_local_laplacian__ @ ## (@var{p}, @var{t}, @var{shg}, @var{epsilon}, @var{area}, @var{nnodes}, @var{nelem}) ## ## Unocumented private function. ## ## @end deftypefn function Lloc = __osc_local_laplacian__ (p, t, shg, epsilon, area, nnodes, nelem) Lloc = zeros (4, 4, nelem); epsilonbyareak = epsilon(:) ./ abs (area(:)) / 48; A = zeros (3, 4, nelem); ## Computation for inode = 1:4 A(:, inode, :) = 3 * abs (area) .* squeeze (shg (:, inode, :)); endfor Ann = squeeze (sum (A .^ 2, 1)); r12 = p(:, t (2, :)) - p(:, t (1, :)); r13 = p(:, t (3, :)) - p(:, t (1, :)); r14 = p(:, t (4, :)) - p(:, t (1, :)); r23 = p(:, t (3, :)) - p(:, t (2, :)); r24 = p(:, t (4, :)) - p(:, t (2, :)); r34 = p(:, t (4, :)) - p(:, t (3, :)); s12 = - epsilonbyareak .* (2 * (dot (r13, r23, 1) .* dot (r14, r24, 1))(:) + squeeze (dot (A(:, 3, :), A(:, 4, :), 1)) .* (dot ( r13, r23, 1) .^ 2 ./ Ann(4, :) + dot ( r14, r24, 1).^ 2 ./ Ann(3, :))(:)); s13 = - epsilonbyareak .* (2 * (dot (r12, -r23, 1) .* dot (r14, r34, 1))(:) + squeeze (dot (A(:, 2, :), A(:, 4, :), 1)) .* (dot ( r12, -r23, 1) .^ 2 ./ Ann(4, :) + dot ( r14, r34, 1).^ 2 ./ Ann(2, :))(:)); s14 = - epsilonbyareak .* (2 * (dot ( r12, -r24, 1) .* dot ( r13, -r34, 1))(:) + squeeze (dot (A(:, 2, :), A(:, 3, :), 1)) .* (dot ( r12, -r24, 1) .^ 2 ./ Ann(3, :) + dot ( r13, -r34, 1).^ 2 ./ Ann(2, :))(:)); s23 = - epsilonbyareak .* (2 * (dot (-r12, -r13, 1) .* dot ( r24, r34, 1))(:) + squeeze (dot (A(:, 1, :), A(:, 4, :), 1)) .* (dot (-r12, -r13, 1) .^ 2 ./ Ann(4, :) + dot ( r24, r34, 1).^ 2 ./ Ann(1, :))(:)); s24 = - epsilonbyareak .* (2 * (dot (-r12, -r14, 1) .* dot ( r23, -r34, 1))(:) + squeeze (dot (A(:, 1, :), A(:, 3, :), 1)) .* (dot (-r12, -r14, 1) .^ 2 ./ Ann(3, :) + dot ( r23, -r34, 1).^ 2 ./ Ann(1, :))(:)); s34 = - epsilonbyareak .* (2 * (dot (-r13, -r14, 1) .* dot (-r23, -r24, 1))(:) + squeeze (dot (A(:, 1, :), A(:, 2, :), 1)) .* (dot (-r13, -r14, 1) .^ 2 ./ Ann(2, :) + dot (-r23, -r24, 1).^ 2 ./ Ann(1, :))(:)); Lloc(1, 2, :) = s12; Lloc(2, 1, :) = s12; Lloc(1, 3, :) = s13; Lloc(3, 1, :) = s13; Lloc(1, 4, :) = s14; Lloc(4, 1, :) = s14; Lloc(1, 1, :) = -(s12+s13+s14); Lloc(2, 3, :) = s23; Lloc(3, 2, :) = s23; Lloc(2, 4, :) = s24; Lloc(4, 2, :) = s24; Lloc(2, 2, :) = -(s12+s23+s24); Lloc(3, 4, :) = s34; Lloc(4, 3, :) = s34; Lloc(3, 3, :) = -(s13+s23+s34); Lloc(4, 4, :) = -(s14+s24+s34); endfunction