From 2a14a3c264e46314854b7ebffade32949c5cfbe6 Mon Sep 17 00:00:00 2001 From: BenYuan Date: Mon, 28 Oct 2024 20:40:28 +0000 Subject: [PATCH 1/8] added CI for the branch --- .github/workflows/test.yml | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/.github/workflows/test.yml b/.github/workflows/test.yml index 53f536b1f..0ca460bd0 100644 --- a/.github/workflows/test.yml +++ b/.github/workflows/test.yml @@ -3,9 +3,9 @@ name: unit testing on: workflow_dispatch: push: - branches: [ develop, main, release-candidate/* ] + branches: [ develop, main, release-candidate/*, BenY/OrganizingAndDocumentation ] pull_request: - branches: [ develop, main, release-candidate/* ] + branches: [ develop, main, release-candidate/*, BenY/OrganizingAndDocumentation ] workflow_call: jobs: From da4cacfa757cbaec12e7309ba80a55ace860070c Mon Sep 17 00:00:00 2001 From: angranl-flex Date: Mon, 28 Oct 2024 16:55:11 -0400 Subject: [PATCH 2/8] Flow360 2.0 documentation for volume_models, solver_numerics and outputs modules (#519) * Test edit on VolumeOutput * Re-commit documentation change * Address comments --------- Co-authored-by: Ben <106089368+benflexcompute@users.noreply.github.com> --- .../simulation/models/solver_numerics.py | 385 ++++++++---------- .../simulation/models/volume_models.py | 308 ++++++++++---- .../component/simulation/outputs/outputs.py | 131 ++++-- 3 files changed, 494 insertions(+), 330 deletions(-) diff --git a/flow360/component/simulation/models/solver_numerics.py b/flow360/component/simulation/models/solver_numerics.py index ed2ca61bb..6ebdf44cd 100644 --- a/flow360/component/simulation/models/solver_numerics.py +++ b/flow360/component/simulation/models/solver_numerics.py @@ -33,29 +33,6 @@ class LinearSolver(Flow360BaseModel): """:class:`LinearSolver` class for setting up linear solver for heat equation - - Parameters - ---------- - - max_iterations : PositiveInt, optional - Maximum number of linear solver iterations, by default 50 - - absolute_tolerance : PositiveFloat, optional - The linear solver converges when the final residual of the pseudo steps below this value. Either absolute - tolerance or relative tolerance can be used to determine convergence, by default 1e-10 - - relative_tolerance : - The linear solver converges when the ratio of the final residual and the initial - residual of the pseudo step is below this value. - - validation: tolerance settings only available to HeatEquationSolver - - Returns - ------- - :class:`LinearSolver` - An instance of the component class LinearSolver. - - Example ------- >>> ls = LinearSolver( @@ -64,9 +41,19 @@ class LinearSolver(Flow360BaseModel): ) """ - max_iterations: PositiveInt = pd.Field(30) - absolute_tolerance: Optional[PositiveFloat] = pd.Field(None) - relative_tolerance: Optional[PositiveFloat] = pd.Field(None) + max_iterations: PositiveInt = pd.Field( + 30, description="Maximum number of linear solver iterations" + ) + absolute_tolerance: Optional[PositiveFloat] = pd.Field( + None, + description="The linear solver converges when the final residual of the pseudo steps below this value." + + "Either absolute tolerance or relative tolerance can be used to determine convergence", + ) + relative_tolerance: Optional[PositiveFloat] = pd.Field( + None, + description="The linear solver converges when the ratio of the final residual and the initial " + + "residual of the pseudo step is below this value.", + ) model_config = pd.ConfigDict( conflicting_fields=[Conflicts(field1="absolute_tolerance", field2="relative_tolerance")] @@ -77,94 +64,77 @@ class GenericSolverSettings(Flow360BaseModel, metaclass=ABCMeta): """:class:`GenericSolverSettings` class""" absolute_tolerance: PositiveFloat = pd.Field(1.0e-10) - relative_tolerance: NonNegativeFloat = pd.Field(0) - order_of_accuracy: Literal[1, 2] = pd.Field(2) - equation_evaluation_frequency: PositiveInt = pd.Field(1) + relative_tolerance: NonNegativeFloat = pd.Field( + 0, + description="Tolerance to the relative residual, below which the solver goes to the next physical step. " + + "Relative residual is defined as the ratio of the current pseudoStep's residual to the maximum " + + "residual present in the first 10 pseudoSteps within the current physicalStep. " + + "NOTE: relativeTolerance is ignored in steady simulations and only absoluteTolerance is " + + "used as the convergence criterion", + ) + order_of_accuracy: Literal[1, 2] = pd.Field(2, description="Order of accuracy in space") + equation_evaluation_frequency: PositiveInt = pd.Field( + 1, description="Frequency at which to solve the equation" + ) linear_solver: LinearSolver = pd.Field(LinearSolver()) class NavierStokesSolver(GenericSolverSettings): - """:class:`NavierStokesSolver` class for setting up compressible Navier-Stokes solver - - Parameters - ---------- - - absolute_tolerance : - Tolerance for the NS residual, below which the solver goes to the next physical step - - relative_tolerance : - Tolerance to the relative residual, below which the solver goes to the next physical step. Relative residual is - defined as the ratio of the current pseudoStep’s residual to the maximum residual present in the first - 10 pseudoSteps within the current physicalStep. NOTE: relativeTolerance is ignored in steady simulations and - only absoluteTolerance is used as the convergence criterion - - CFL_multiplier : - Factor to the CFL definitions defined in “timeStepping” section - - kappa_MUSCL : - Kappa for the MUSCL scheme, range from [-1, 1], with 1 being unstable. The default value of -1 leads to a 2nd - order upwind scheme and is the most stable. A value of 0.33 leads to a blended upwind/central scheme and is - recommended for low subsonic flows leading to reduced dissipation - - update_jacobian_frequency : - Frequency at which the jacobian is updated. - - equation_evaluation_frequency : - Frequency at which to update the compressible NS equation in loosely-coupled simulations - - max_force_jac_update_physical_steps : - When which physical steps, the jacobian matrix is updated every pseudo step - - order_of_accuracy : - Order of accuracy in space - - limit_velocity : - Limiter for velocity - - limit_pressure_density : - Limiter for pressure and density - - numerical_dissipation_factor : - A factor in the range [0.01, 1.0] which exponentially reduces the dissipation of the numerical flux. - The recommended starting value for most low-dissipation runs is 0.2 - - linear_solver: - Linear solver settings - - low_mach_preconditioner: - Uses preconditioning for accelerating low Mach number flows. - - low_mach_preconditioner_threshold: - For flow regions with Mach numbers smaller than threshold, the input Mach number to the preconditioner is - assumed to be the threshold value if it is smaller than the threshold. - The default value for the threshold is the freestream Mach number. - - Returns - ------- - :class:`NavierStokesSolver` - An instance of the component class NavierStokesSolver. + """:class:`NavierStokesSolver` class for setting up compressible Navier-Stokes solver. + For more information on setting up the numerical parameters for the Navier-Stokes solver, + refer to :ref:`Navier-Stokes solver knowledge base `. Example ------- >>> ns = NavierStokesSolver(absolute_tolerance=1e-10) """ - absolute_tolerance: PositiveFloat = pd.Field(1.0e-10) + absolute_tolerance: PositiveFloat = pd.Field( + 1.0e-10, + description="Tolerance for the NS residual, below which the solver goes to the next physical step", + ) - CFL_multiplier: PositiveFloat = pd.Field(1.0) - kappa_MUSCL: pd.confloat(ge=-1, le=1) = pd.Field(-1) + CFL_multiplier: PositiveFloat = pd.Field( + 1.0, description="Factor to the CFL definitions defined in :code:`time_stepping` section" + ) + kappa_MUSCL: pd.confloat(ge=-1, le=1) = pd.Field( + -1, + description="Kappa for the MUSCL scheme, range from [-1, 1], with 1 being unstable. " + + "The default value of -1 leads to a 2nd order upwind scheme and is the most stable. " + + "A value of 0.33 leads to a blended upwind/central scheme and is recommended for low " + + "subsonic flows leading to reduced dissipation", + ) - numerical_dissipation_factor: pd.confloat(ge=0.01, le=1) = pd.Field(1) - limit_velocity: bool = pd.Field(False) - limit_pressure_density: bool = pd.Field(False) + numerical_dissipation_factor: pd.confloat(ge=0.01, le=1) = pd.Field( + 1, + description="A factor in the range [0.01, 1.0] which exponentially reduces the " + + "dissipation of the numerical flux. The recommended starting value for most " + + "low-dissipation runs is 0.2", + ) + limit_velocity: bool = pd.Field(False, description="Limiter for velocity") + limit_pressure_density: bool = pd.Field(False, description="Limiter for pressure and density") type_name: Literal["Compressible"] = pd.Field("Compressible", frozen=True) - low_mach_preconditioner: bool = pd.Field(False) - low_mach_preconditioner_threshold: Optional[NonNegativeFloat] = pd.Field(None) + low_mach_preconditioner: bool = pd.Field( + False, description="Use preconditioning for accelerating low Mach number flows" + ) + low_mach_preconditioner_threshold: Optional[NonNegativeFloat] = pd.Field( + None, + description="For flow regions with Mach numbers smaller than threshold, the input " + + "Mach number to the preconditioner is assumed to be the threshold value if it is " + + "smaller than the threshold. The default value for the threshold is the freestream " + + "Mach number.", + ) - update_jacobian_frequency: PositiveInt = pd.Field(4) - max_force_jac_update_physical_steps: NonNegativeInt = pd.Field(0) + update_jacobian_frequency: PositiveInt = pd.Field( + 4, description="Frequency at which the jacobian is updated" + ) + max_force_jac_update_physical_steps: NonNegativeInt = pd.Field( + 0, + description="When physical step is less than this value, the jacobian matrix is " + + "updated every pseudo step", + ) class SpalartAllmarasModelConstants(Flow360BaseModel): @@ -209,93 +179,79 @@ class KOmegaSSTModelConstants(Flow360BaseModel): class TurbulenceModelSolver(GenericSolverSettings, metaclass=ABCMeta): - """:class:`TurbulenceModelSolver` class for setting up turbulence model solver - - Parameters - ---------- - absoluteTolerance : - Tolerance for the NS residual, below which the solver goes to the next physical step - - relativeTolerance : - Tolerance to the relative residual, below which the solver goes to the next physical step. Relative residual is - defined as the ratio of the current pseudoStep’s residual to the maximum residual present in the first - 10 pseudoSteps within the current physicalStep. NOTE: relativeTolerance is ignored in steady simulations and - only absoluteTolerance is used as the convergence criterion - - CFL_multiplier : - Factor to the CFL definitions defined in “timeStepping” section - - linearIterations : - Number of linear solver iterations - - updateJacobianFrequency : - Frequency at which the jacobian is updated. - - equationEvalFrequency : - Frequency at which to update the NS equation in loosely-coupled simulations - - maxForceJacUpdatePhysicalSteps : - When which physical steps, the jacobian matrix is updated every pseudo step - - orderOfAccuracy : - Order of accuracy in space - - reconstruction_gradient_limiter : - The strength of gradient limiter used in reconstruction of solution variables at the faces (specified in the - range [0.0, 2.0]). 0.0 corresponds to setting the gradient equal to zero, and 2.0 means no limiting. - - quadratic_constitutive_relation : bool, optional - Use quadratic constitutive relation for turbulence shear stress tensor instead of Boussinesq Approximation - - DDES : bool, optional - Enables Delayed Detached Eddy Simulation. Supported for both SpalartAllmaras and kOmegaSST turbulence models, - with and without AmplificationFactorTransport transition model enabled. - - grid_size_for_LES : Literal['maxEdgeLength', 'meanEdgeLength'], optional - Specifes the length used for the computation of LES length scale. The allowed inputs are "maxEdgeLength" - (default) and "meanEdgeLength" - - modeling_constants : - Here, user can change the default values used for DDES coefficients in the solver: - SpalartAllmaras: "C_DES" (= 0.72), "C_d" (= 8.0) - kOmegaSST: "C_DES1" (= 0.78), "C_DES2" (= 0.61), "C_d1" (= 20.0), "C_d2" (= 3.0) - (values shown in the parentheses are the default values used in Flow360) - An example with kOmegaSST mode would be: {"C_DES1": 0.85, "C_d1": 8.0} - - Returns - ------- - :class:`TurbulenceModelSolver` - An instance of the component class TurbulenceModelSolver. + """:class:`TurbulenceModelSolver` class for setting up turbulence model solver. + For more information on setting up the numerical parameters for the turbulence model solver, + refer to :ref:`the turbulence model solver knowledge base `. Example ------- >>> ts = TurbulenceModelSolver(absolute_tolerance=1e-10) """ - CFL_multiplier: PositiveFloat = pd.Field(2.0) + CFL_multiplier: PositiveFloat = pd.Field( + 2.0, description="Factor to the CFL definitions defined in :code:`time_stepping` section" + ) type_name: str = pd.Field() - absolute_tolerance: PositiveFloat = pd.Field(1e-8) - equation_evaluation_frequency: PositiveInt = pd.Field(4) - DDES: bool = pd.Field(False) - grid_size_for_LES: Literal["maxEdgeLength", "meanEdgeLength"] = pd.Field("maxEdgeLength") - reconstruction_gradient_limiter: pd.confloat(ge=0, le=2) = pd.Field(1.0) - quadratic_constitutive_relation: bool = pd.Field(False) - modeling_constants: Optional[TurbulenceModelConstants] = pd.Field(discriminator="type_name") - update_jacobian_frequency: PositiveInt = pd.Field(4) - max_force_jac_update_physical_steps: NonNegativeInt = pd.Field(0) + absolute_tolerance: PositiveFloat = pd.Field( + 1e-8, + description="Tolerance for the NS residual, below which the solver goes to the next physical step", + ) + equation_evaluation_frequency: PositiveInt = pd.Field( + 4, description="Frequency at which to update the NS equation in loosely-coupled simulations" + ) + DDES: bool = pd.Field( + False, + description="Enables Delayed Detached Eddy Simulation. " + + " Supported for both SpalartAllmaras and kOmegaSST turbulence models, " + + "with and without AmplificationFactorTransport transition model enabled.", + ) + grid_size_for_LES: Literal["maxEdgeLength", "meanEdgeLength"] = pd.Field( + "maxEdgeLength", + description="Specifes the length used for the computation of LES length scale. " + + 'The allowed inputs are "maxEdgeLength" and "meanEdgeLength"', + ) + reconstruction_gradient_limiter: pd.confloat(ge=0, le=2) = pd.Field( + 1.0, + description="The strength of gradient limiter used in reconstruction of solution " + + "variables at the faces (specified in the range [0.0, 2.0]). 0.0 corresponds to " + + "setting the gradient equal to zero, and 2.0 means no limiting.", + ) + quadratic_constitutive_relation: bool = pd.Field( + False, + description="Use quadratic constitutive relation for turbulence shear stress tensor " + + "instead of Boussinesq Approximation", + ) + modeling_constants: Optional[TurbulenceModelConstants] = pd.Field( + discriminator="type_name", + description=" A dictionary containing the DDES coefficients in the solver: **SpalartAllmaras**: " + + ':code:`"C_DES"` (= 0.72), :code:`"C_d"` (= 8.0), **kOmegaSST**: :code:`"C_DES1"` (= 0.78), ' + + ':code:`"C_DES2"` (= 0.61), :code:`"C_d1"` (= 20.0), :code:`"C_d2"` (= 3.0), ' + + "*(values shown in the parentheses are the default values used in Flow360)*", + ) + update_jacobian_frequency: PositiveInt = pd.Field( + 4, description="Frequency at which the jacobian is updated" + ) + max_force_jac_update_physical_steps: NonNegativeInt = pd.Field( + 0, + description="For physical steps less than the input value, the jacobian matrix is " + + "updated every pseudo-step overriding the :code:`updateJacobianFrequency` value", + ) - linear_solver: LinearSolver = pd.Field(LinearSolver(max_iterations=20)) + linear_solver: LinearSolver = pd.Field( + LinearSolver(max_iterations=20), + description="Linear solver settings, see :class:`LinearSolver` documentation.", + ) class KOmegaSST(TurbulenceModelSolver): - """:class:`KOmegaSST` class""" + """:class:`KOmegaSST` class for setting up the turbulence solver based on the SST k-omega model.""" type_name: Literal["kOmegaSST"] = pd.Field("kOmegaSST", frozen=True) modeling_constants: KOmegaSSTModelConstants = pd.Field(KOmegaSSTModelConstants()) class SpalartAllmaras(TurbulenceModelSolver): - """:class:`SpalartAllmaras` class""" + """:class:`SpalartAllmaras` class for setting up the turbulence solver based on the Spalart–Allmaras model""" type_name: Literal["SpalartAllmaras"] = pd.Field("SpalartAllmaras", frozen=True) rotation_correction: bool = pd.Field(False) @@ -307,7 +263,7 @@ class SpalartAllmaras(TurbulenceModelSolver): class NoneSolver(Flow360BaseModel): - """:class:`SolverNone` class""" + """:class:`NoneSolver` class""" type_name: Literal["None"] = pd.Field("None", frozen=True) @@ -318,24 +274,7 @@ class NoneSolver(Flow360BaseModel): class HeatEquationSolver(GenericSolverSettings): - """:class:`HeatEquationSolver` class for setting up heat equation solver. - - - Parameters - ---------- - - equation_evaluation_frequency : PositiveInt, optional - Frequency at which to solve the heat equation in conjugate heat transfer simulations - - - linear_solver_config : LinearSolver, optional - Linear solver settings, see LinearSolver documentation. - - Returns - ------- - :class:`HeatEquationSolver` - An instance of the component class HeatEquationSolver. - + """`HeatEquationSolver` class for setting up heat equation solver. Example ------- @@ -349,27 +288,29 @@ class HeatEquationSolver(GenericSolverSettings): """ type_name: Literal["HeatEquation"] = pd.Field("HeatEquation", frozen=True) - absolute_tolerance: PositiveFloat = pd.Field(1e-9) - equation_evaluation_frequency: PositiveInt = pd.Field(10) - order_of_accuracy: Literal[2] = pd.Field(2) + absolute_tolerance: PositiveFloat = pd.Field( + 1e-9, + description="Absolute residual tolerance that determines the convergence of the heat equation in " + + "conjugate heat transfer. This value should be the same or higher than the absolute tolerance " + + "for the linear solver by a small margin.", + ) + equation_evaluation_frequency: PositiveInt = pd.Field( + 10, + description="Frequency at which to solve the heat equation in conjugate heat transfer simulations", + ) + order_of_accuracy: Literal[2] = pd.Field(2, description="Order of accuracy in space") linear_solver: LinearSolver = pd.Field( - LinearSolver(max_iterations=50, absolute_tolerance=1e-10) + LinearSolver(max_iterations=50, absolute_tolerance=1e-10), + description="Linear solver settings, see :class:`LinearSolver` documentation.", ) class TransitionModelSolver(GenericSolverSettings): - """:class:`TransitionModelSolver` class for setting up transition model solver - - Parameters - ---------- - - (...) + """:class:`TransitionModelSolver` class for setting up transition model solver. + For more information on setting up the numerical parameters for the transition model solver, + refer to :ref:`the transition model solver knowledge base `. - Returns - ------- - :class:`TransitionModelSolver` - An instance of the component class TransitionModelSolver. Example ------- @@ -379,19 +320,45 @@ class TransitionModelSolver(GenericSolverSettings): type_name: Literal["AmplificationFactorTransport"] = pd.Field( "AmplificationFactorTransport", frozen=True ) - CFL_multiplier: PositiveFloat = pd.Field(2.0) - absolute_tolerance: PositiveFloat = pd.Field(1e-7) - equation_evaluation_frequency: PositiveInt = pd.Field(4) - turbulence_intensity_percent: Optional[pd.confloat(ge=0.03, le=2.5)] = pd.Field(None) + CFL_multiplier: PositiveFloat = pd.Field( + 2.0, description="Factor to the CFL definitions defined in :code:`time_stepping` section" + ) + absolute_tolerance: PositiveFloat = pd.Field( + 1e-7, + description="Tolerance for the transition model residual, below which the solver progresses to " + + "the next physical step (unsteady) or completes the simulation (steady)", + ) + equation_evaluation_frequency: PositiveInt = pd.Field( + 4, description="Frequency at which to update the transition equation" + ) + turbulence_intensity_percent: Optional[pd.confloat(ge=0.03, le=2.5)] = pd.Field( + 1.0, + description=":ref:`Turbulence Intensity `, Range from [0.03-2.5]. " + + "Only valid when :code:`Ncrit` is not specified.", + ) # pylint: disable=invalid-name - N_crit: Optional[pd.confloat(ge=1.0, le=11.0)] = pd.Field(None) - update_jacobian_frequency: PositiveInt = pd.Field(4) - max_force_jac_update_physical_steps: NonNegativeInt = pd.Field(0) + N_crit: Optional[pd.confloat(ge=1.0, le=11.0)] = pd.Field( + None, + description=":ref:`Critical Amplification Factor `, Range from [1-11]. " + + "Only valid when :code:`turbulenceIntensityPercent` is not specified.", + ) + update_jacobian_frequency: PositiveInt = pd.Field( + 4, description="Frequency at which the jacobian is updated" + ) + max_force_jac_update_physical_steps: NonNegativeInt = pd.Field( + 0, + description="For physical steps less than the input value, the jacobian matrix " + + "is updated every pseudo-step overriding the :code:`updateJacobianFrequency` value", + ) + reconstruction_gradient_limiter: Optional[pd.confloat(ge=0.0, le=2.0)] = pd.Field(1.0) trip_regions: Optional[EntityList[Box]] = pd.Field(None) - linear_solver: LinearSolver = pd.Field(LinearSolver(max_iterations=20)) + linear_solver: LinearSolver = pd.Field( + LinearSolver(max_iterations=20), + description="Linear solver settings, see :class:`LinearSolver` documentation.", + ) @pd.model_validator(mode="after") def _set_aft_ncrit(self) -> Self: diff --git a/flow360/component/simulation/models/volume_models.py b/flow360/component/simulation/models/volume_models.py index 252f07200..b720860b4 100644 --- a/flow360/component/simulation/models/volume_models.py +++ b/flow360/component/simulation/models/volume_models.py @@ -54,14 +54,16 @@ class AngleExpression(SingleAttributeModel): """Angle expression for Rotation""" type_name: Literal["AngleExpression"] = pd.Field("AngleExpression", frozen=True) - value: StringExpression = pd.Field() + value: StringExpression = pd.Field( + description="The expression defining the rotation angle " + "as a function of time." + ) class AngularVelocity(SingleAttributeModel): """Angular velocity for Rotation""" type_name: Literal["AngularVelocity"] = pd.Field("AngularVelocity", frozen=True) - value: AngularVelocityType = pd.Field() + value: AngularVelocityType = pd.Field(description="The value of the angular velocity.") class FromUserDefinedDynamics(Flow360BaseModel): @@ -71,19 +73,27 @@ class FromUserDefinedDynamics(Flow360BaseModel): class ExpressionInitialConditionBase(Flow360BaseModel): - """:class:`ExpressionInitialCondition` class""" + """:class:`ExpressionInitialCondition` class for specifying the intial conditions of + :class:`~flow360.component.simulation.models.solver_numerics.NavierStokesSolver`.""" type: Literal["expression"] = pd.Field("expression", frozen=True) - constants: Optional[Dict[str, str]] = pd.Field(None) + constants: Optional[Dict[str, str]] = pd.Field( + None, description="The expression for the initial condition." + ) # pylint: disable=missing-class-docstring class NavierStokesInitialCondition(ExpressionInitialConditionBase): - rho: str = pd.Field() - u: str = pd.Field() - v: str = pd.Field() - w: str = pd.Field() - p: str = pd.Field() + """ + :class:`NavierStokesInitialCondition` class for specifying the intial conditions of + :class:`~flow360.component.simulation.models.solver_numerics.NavierStokesSolver`. + """ + + rho: str = pd.Field(description="Density") + u: str = pd.Field(description="X-direction velocity") + v: str = pd.Field(description="Y-direction velocity") + w: str = pd.Field(description="Z-direction velocity") + p: str = pd.Field(description="Pressure") class NavierStokesModifiedRestartSolution(NavierStokesInitialCondition): @@ -91,7 +101,11 @@ class NavierStokesModifiedRestartSolution(NavierStokesInitialCondition): class HeatEquationInitialCondition(ExpressionInitialConditionBase): - temperature: str = pd.Field() + """ + :class:`HeatEquationInitialCondition` class for specifying the intial conditions of heat equation in :class:`Solid`. + """ + + temperature: str = pd.Field(description="The initial temperature value") class PDEModelBase(Flow360BaseModel): @@ -106,19 +120,34 @@ class PDEModelBase(Flow360BaseModel): class Fluid(PDEModelBase): """ - General FluidDynamics volume model that contains all the common fields every fluid dynamics zone should have. + :class:`Fluid` class for setting up the volume model that contains + all the common fields every fluid dynamics zone should have. """ type: Literal["Fluid"] = pd.Field("Fluid", frozen=True) - navier_stokes_solver: NavierStokesSolver = pd.Field(NavierStokesSolver()) - turbulence_model_solver: TurbulenceModelSolverType = pd.Field(SpalartAllmaras()) - transition_model_solver: TransitionModelSolverType = pd.Field(NoneSolver()) + navier_stokes_solver: NavierStokesSolver = pd.Field( + NavierStokesSolver(), + description="Navier-Stokes solver settings, see " + + ":class:`~flow360.component.simulation.models.solver_numerics.NavierStokesSolver` documentation.", + ) + turbulence_model_solver: TurbulenceModelSolverType = pd.Field( + SpalartAllmaras(), + description="Turbulence model solver settings, see " + + ":class:`~flow360.component.simulation.models.solver_numerics.TurbulenceModelSolver` documentation.", + ) + transition_model_solver: TransitionModelSolverType = pd.Field( + NoneSolver(), + description="Transition solver settings, see " + + ":class:`~flow360.component.simulation.models.solver_numerics.TransitionModelSolver` documentation.", + ) - material: FluidMaterialTypes = pd.Field(Air()) + material: FluidMaterialTypes = pd.Field(Air(), description="The material propetry of fluid") initial_condition: Optional[ Union[NavierStokesModifiedRestartSolution, NavierStokesInitialCondition] - ] = pd.Field(None, discriminator="type") + ] = pd.Field( + None, discriminator="type", description="The initial condition of the fluid solver" + ) # pylint: disable=fixme # fixme: Add support for other initial conditions @@ -126,44 +155,38 @@ class Fluid(PDEModelBase): class Solid(PDEModelBase): """ - General HeatTransfer volume model that contains all the common fields every heat transfer zone should have. + :class:`Solid` class for setting up the HeatTransfer volume model that + contains all the common fields every heat transfer zone should have. """ - name: Optional[str] = pd.Field(None) + name: Optional[str] = pd.Field(None, description="Name of the `Solid` model.") type: Literal["Solid"] = pd.Field("Solid", frozen=True) - entities: EntityList[GenericVolume] = pd.Field(alias="volumes") + entities: EntityList[GenericVolume] = pd.Field( + alias="volumes", + description="The list of solid entities on which the heat transfer equation is solved.", + ) - material: SolidMaterialTypes = pd.Field() + material: SolidMaterialTypes = pd.Field(description="The material property of solid") - heat_equation_solver: HeatEquationSolver = pd.Field(HeatEquationSolver()) - volumetric_heat_source: Union[HeatSourceType, pd.StrictStr] = pd.Field(0) + heat_equation_solver: HeatEquationSolver = pd.Field( + HeatEquationSolver(), + description="Heat equation solver settings, see " + + ":class:`~flow360.component.simulation.models.solver_numerics.HeatEquationSolver` documentation. " + + ":class:`~flow360.component.simulation.outputs.outputs.SurfaceIntegralOutput`", + ) + volumetric_heat_source: Union[HeatSourceType, pd.StrictStr] = pd.Field( + 0, description="The volumetric heat source" + ) - initial_condition: Optional[HeatEquationInitialCondition] = pd.Field(None) + initial_condition: Optional[HeatEquationInitialCondition] = pd.Field( + None, description="The initial condition of the heat equation solver" + ) # pylint: disable=duplicate-code class ForcePerArea(Flow360BaseModel): """:class:`ForcePerArea` class for setting up force per area for Actuator Disk - Parameters - ---------- - radius : LengthType.Array - Radius of the sampled locations in grid unit - - thrust : PressureType.Array - Force per area in the axial direction, positive means the axial force follows the same direction as axisThrust. - It is non-dimensional: trustPerArea[SI=N/m2]/rho_inf/C_inf^2 - - circumferential : PressureType.Array - Force per area in the circumferential direction, positive means the circumferential force follows the same - direction as axisThrust with the right hand rule. It is non-dimensional: - circumferentialForcePerArea[SI=N/m2]/rho_inf/C_inf^2 - - Returns - ------- - :class:`ForcePerArea` - An instance of the component class ForcePerArea. - Example ------- >>> fpa = ForcePerArea(radius=[0, 1], thrust=[1, 1], circumferential=[1, 1]) # doctest: +SKIP @@ -171,9 +194,20 @@ class ForcePerArea(Flow360BaseModel): TODO: Use dimensioned values """ - radius: LengthType.Array # pylint: disable=no-member - thrust: PressureType.Array # pylint: disable=no-member - circumferential: PressureType.Array # pylint: disable=no-member + # pylint: disable=no-member + radius: LengthType.Array = pd.Field(description="Radius of the sampled locations in grid unit.") + # pylint: disable=no-member + thrust: PressureType.Array = pd.Field( + description="Force per area in the axial direction, positive means the axial force follows the same " + + "direction as the thrust axis. " + + "It is non-dimensional: :math:`\\frac{\\text{thrustPerArea}(SI=N/m^2)}{\\rho_\\infty C^2_\\infty}`" + ) + # pylint: disable=no-member + circumferential: PressureType.Array = pd.Field( + description="Force per area in the circumferential direction, positive means the circumferential force " + + "follows the same direction as the thrust axis with the right hand rule. It is non-dimensional: " + + ":math:`\\frac{\\text{circumferentialForcePerArea}(SI=N/m^2)}{\\rho_\\infty C^2_\\infty}`" + ) # pylint: disable=no-self-argument, missing-function-docstring @pd.model_validator(mode="before") @@ -194,65 +228,147 @@ def validate_consistent_array_length(cls, values): class ActuatorDisk(Flow360BaseModel): - """Same as Flow360Param ActuatorDisks. + """:class:`ActuatorDisk` class for setting up the inputs for an Actuator Disk. + Please refer to the :ref:`actuator disk knowledge base ` for further information. Note that `center`, `axis_thrust`, `thickness` can be acquired from `entity` so they are not required anymore. """ - entities: EntityList[Cylinder] = pd.Field(alias="volumes") - force_per_area: ForcePerArea = pd.Field() - name: Optional[str] = pd.Field(None) + entities: EntityList[Cylinder] = pd.Field( + alias="volumes", + description="The list of `Cylinder` entities for the ActuatorDisk model", + ) + force_per_area: ForcePerArea = pd.Field( + description="The force per area input for the ActuatorDisk model. " + + "See :class:`ForcePerArea` documentation." + ) + name: Optional[str] = pd.Field(None, description="Name of the `ActuatorDisk` model.") type: Literal["ActuatorDisk"] = pd.Field("ActuatorDisk", frozen=True) class BETDiskTwist(Flow360BaseModel): - """:class:`BETDiskTwist` class""" + """:class:`BETDiskTwist` class for setting up twist for BETDisk""" # TODO: Use dimensioned values, why optional? - radius: Optional[float] = pd.Field(None) - twist: Optional[float] = pd.Field(None) + radius: Optional[float] = pd.Field(None, description="A list of radial locations.") + twist: Optional[float] = pd.Field( + None, + description="The twist in degrees as a function of radial location. " + + "Entries in the list must already be sorted by radius.", + ) class BETDiskChord(Flow360BaseModel): - """:class:`BETDiskChord` class""" + """:class:`BETDiskChord` class for setting up chord for BETDisk""" # TODO: Use dimensioned values, why optional? - radius: Optional[float] = pd.Field(None) - chord: Optional[float] = pd.Field(None) + radius: Optional[float] = pd.Field(None, description="A list of radial locations.") + chord: Optional[float] = pd.Field( + None, + description="The blade chord as a function of the radial location. " + + "Entries in the list must already be sorted by radius.", + ) class BETDiskSectionalPolar(Flow360BaseModel): - """:class:`BETDiskSectionalPolar` class""" + """:class:`BETDiskSectionalPolar` class for setting up sectional polars for BETDisk. + There are two variables, “lift_coeffs” and “drag_coeffs”, + need to be set up as 3D arrays (implemented as nested lists). + The first index of the array corresponds to the :code:`MachNumbers` of the specified polar + data. + The second index of the array corresponds to the :code:`ReynoldsNumbers` of the polar + data. + The third index corresponds to the :code:`alphas`. + The value specifies the lift or drag coefficient, respectively. + """ - lift_coeffs: Optional[List[List[List[float]]]] = pd.Field() - drag_coeffs: Optional[List[List[List[float]]]] = pd.Field() + lift_coeffs: Optional[List[List[List[float]]]] = pd.Field( + description="The 3D arrays specifying the list coefficient." + ) + drag_coeffs: Optional[List[List[List[float]]]] = pd.Field( + description="The 3D arrays specifying the drag coefficient." + ) # pylint: disable=no-member class BETDisk(Flow360BaseModel): - """Same as Flow360Param BETDisk. + """:class:`BETDisk` class for defining the Blade Element Theory (BET) model inputs. + For detailed information on the parameters, please refer to the :ref:`BET knowledge Base `. + To generate the sectional polars the BET translators can be used which are + outlined :ref:`here ` + with best-practices for the sectional polars inputs available :ref:`here `. + A case study of the XV-15 rotor using the steady BET Disk method is available + in :ref:`Case Studies `. + Because a transient BET Line simulation is simply a time-accurate version of a steady-state + BET Disk simulation, most of the parameters below are applicable to both methods. Note that `center_of_rotation`, `axis_of_rotation`, `radius`, `thickness` can be acquired from `entity` so they are not required anymore. """ - name: Optional[str] = pd.Field(None) + name: Optional[str] = pd.Field(None, description="Name of the `BETDisk` model.") type: Literal["BETDisk"] = pd.Field("BETDisk", frozen=True) entities: EntityList[Cylinder] = pd.Field(alias="volumes") - rotation_direction_rule: Literal["leftHand", "rightHand"] = pd.Field("rightHand") - number_of_blades: pd.StrictInt = pd.Field(gt=0, le=10) - omega: AngularVelocityType.NonNegative = pd.Field() - chord_ref: LengthType.Positive = pd.Field() - n_loading_nodes: pd.StrictInt = pd.Field(gt=0, le=1000) - blade_line_chord: LengthType.NonNegative = pd.Field(0) - initial_blade_direction: Optional[Axis] = pd.Field(None) - tip_gap: Union[Literal["inf"], LengthType.NonNegative] = pd.Field("inf") - mach_numbers: List[pd.NonNegativeFloat] = pd.Field() - reynolds_numbers: List[pd.PositiveFloat] = pd.Field() - alphas: List[float] = pd.Field() - twists: List[BETDiskTwist] = pd.Field() - chords: List[BETDiskChord] = pd.Field() - sectional_polars: List[BETDiskSectionalPolar] = pd.Field() - sectional_radiuses: List[float] = pd.Field() + rotation_direction_rule: Literal["leftHand", "rightHand"] = pd.Field( + "rightHand", + description='The rule for rotation direction and thrust direction, "rightHand" or "leftHand".', + ) + number_of_blades: pd.StrictInt = pd.Field(gt=0, le=10, description="Number of blades to model") + omega: AngularVelocityType.NonNegative = pd.Field( + description="Nondimensional rotating speed, radians/nondim-unit-time, " + + "= :math:`\\frac{\\Omega*L_{gridUnit}}{C_\\infty}`" + ) + chord_ref: LengthType.Positive = pd.Field( + description="Nondimensional reference chord used to compute sectional blade loadings" + ) + n_loading_nodes: pd.StrictInt = pd.Field( + gt=0, + le=1000, + description="Number of nodes used to compute the sectional thrust and " + + "torque coefficients :math:`C_t` and :math:`C_q`, defined in :ref:`betDiskLoadingNote`", + ) + blade_line_chord: LengthType.NonNegative = pd.Field( + 0, + description="Nondimensional chord to use if performing an unsteady BET Line simulation. " + + "Default of 0.0 is an indication to run a steady BET Disk simulation.", + ) + initial_blade_direction: Optional[Axis] = pd.Field( + None, + description="Orientation of the first blade in the BET model. " + + "Must be specified if performing an unsteady BET Line simulation.", + ) + tip_gap: Union[Literal["inf"], LengthType.NonNegative] = pd.Field( + "inf", + description="Nondimensional distance between blade tip and solid bodies to " + + "define a :ref:`tip loss factor `.", + ) + mach_numbers: List[pd.NonNegativeFloat] = pd.Field( + description="Mach numbers associated with airfoil polars provided " + + "in :code:`sectionalPolars`" + ) + reynolds_numbers: List[pd.PositiveFloat] = pd.Field( + description="Reynolds numbers associated with the airfoil polars " + + "provided in :code:`sectionalPolars`" + ) + alphas: List[float] = pd.Field( + description="Alphas associated with airfoil polars provided in " + + ":code:`sectionalPolars` in degrees" + ) + twists: List[BETDiskTwist] = pd.Field( + description="A list of :class:`BETDiskTwist` objects specifying the twist in degrees as a " + + "function of radial location." + ) + chords: List[BETDiskChord] = pd.Field( + description="A list of :class:`BETDiskChord` objects specifying the blade chord as a function " + + "of the radial location. " + ) + sectional_polars: List[BETDiskSectionalPolar] = pd.Field( + description="A list of :class:`BETDiskSectionalPolar` objects for every radial location specified in " + + ":attr:`sectional_radiuses`." + ) + sectional_radiuses: List[float] = pd.Field( + description="A list of the radial locations in grid units at which :math:`C_l` " + + "and :math:`C_d` are specified in :code:`sectional_polars`" + ) @pd.model_validator(mode="after") @_validator_append_instance_name @@ -295,20 +411,26 @@ def check_bet_disk_3d_coefficients_in_polars(self): class Rotation(Flow360BaseModel): - """Similar to Flow360Param ReferenceFrame. - Note that `center`, `axis` can be acquired from `entity` so they are not required anymore. - Note: Should use the unit system to convert degree or degree per second to radian and radian per second + """ + :class:`Rotation` class for specifying rotation settings. """ - name: Optional[str] = pd.Field(None) + name: Optional[str] = pd.Field(None, description="Name of the `Rotation` model.") type: Literal["Rotation"] = pd.Field("Rotation", frozen=True) - entities: EntityList[GenericVolume, Cylinder] = pd.Field(alias="volumes") + entities: EntityList[GenericVolume, Cylinder] = pd.Field( + alias="volumes", + description="The entity list for the Rotation model. " + + "The entity should be :class:`Cylinder` or :class:`GenericVolume` type.", + ) # TODO: Add test for each of the spec specification. spec: Union[AngleExpression, FromUserDefinedDynamics, AngularVelocity] = pd.Field( - discriminator="type_name" + discriminator="type_name", + description="The angular velocity or rotation angle as a function of time.", + ) + parent_volume: Optional[Union[GenericVolume, Cylinder]] = pd.Field( + None, description="The parent rotating entity in a nested rotation case." ) - parent_volume: Optional[Union[GenericVolume, Cylinder]] = pd.Field(None) @pd.field_validator("entities", mode="after") @classmethod @@ -328,15 +450,27 @@ def _ensure_entities_have_sufficient_attributes(cls, value: EntityList): class PorousMedium(Flow360BaseModel): - """Constains Flow360Param PorousMediumBox and PorousMediumVolumeZone""" + """ + :class:`PorousMedium` class for specifying porous media settings.`. + For further information please refer to the :ref:`porous media knowledge base ` + """ - name: Optional[str] = pd.Field(None) + name: Optional[str] = pd.Field(None, description="Name of the `PorousMedium` model.") type: Literal["PorousMedium"] = pd.Field("PorousMedium", frozen=True) entities: EntityList[GenericVolume, Box] = pd.Field(alias="volumes") - darcy_coefficient: InverseAreaType.Point = pd.Field() - forchheimer_coefficient: InverseLengthType.Point = pd.Field() - volumetric_heat_source: Optional[Union[HeatSourceType, pd.StrictStr]] = pd.Field(None) + darcy_coefficient: InverseAreaType.Point = pd.Field( + description="Darcy coefficient of the porous media model which determines the scaling of the " + + "viscous loss term. The 3 values define the coefficient for each of the 3 axes defined by " + + "the reference frame of the volume zone." + ) + forchheimer_coefficient: InverseLengthType.Point = pd.Field( + description="Forchheimer coefficient of the porous media model which determines " + + "the scaling of the inertial loss term" + ) + volumetric_heat_source: Optional[Union[HeatSourceType, pd.StrictStr]] = pd.Field( + None, description="The volumetric heat source" + ) # Note: Axes will always come from the entity @pd.field_validator("entities", mode="after") diff --git a/flow360/component/simulation/outputs/outputs.py b/flow360/component/simulation/outputs/outputs.py index 3a3a0e5e0..828ebb315 100644 --- a/flow360/component/simulation/outputs/outputs.py +++ b/flow360/component/simulation/outputs/outputs.py @@ -55,16 +55,24 @@ class _AnimationAndFileFormatSettings(_AnimationSettings): Controls how frequently the output files are generated and the file format. """ - output_format: Literal["paraview", "tecplot", "both"] = pd.Field(default="paraview") + output_format: Literal["paraview", "tecplot", "both"] = pd.Field( + default="paraview", description='"paraview", "tecplot" or "both".' + ) class SurfaceOutput(_AnimationAndFileFormatSettings): - """Surface output settings.""" + """:class:`SurfaceOutput` class for surface output settings.""" # pylint: disable=fixme # TODO: entities is None --> use all surfaces. This is not implemented yet. - name: Optional[str] = pd.Field(None) - entities: EntityList[Surface, GhostSurface] = pd.Field(alias="surfaces") + + name: Optional[str] = pd.Field(None, description="Name of the `SurfaceOutput`.") + entities: EntityList[Surface, GhostSurface] = pd.Field( + alias="surfaces", + description="List of output :class:`~flow360.component.simulation.primitives.Surface`/" + + ":class:`~flow360.component.simulation.primitives.GhostSurface` entities. " + + "These surface names have to be the patch name in the grid file or the alias name specified in case JSON.", + ) write_single_file: bool = pd.Field( default=False, description="Enable writing all surface outputs into a single file instead of one file per surface." @@ -72,12 +80,16 @@ class SurfaceOutput(_AnimationAndFileFormatSettings): + "Will choose the value of the last instance of this option of the same output type" + "(SurfaceOutput or TimeAverageSurfaceOutput) in the `output` list.", ) - output_fields: UniqueItemList[SurfaceFieldNames] = pd.Field() + output_fields: UniqueItemList[SurfaceFieldNames] = pd.Field( + description="List of output variables. Including :ref:`universal output variables` " + + "and :ref:`variables specific to surfaceOutput`. " + ) output_type: Literal["SurfaceOutput"] = pd.Field("SurfaceOutput", frozen=True) class TimeAverageSurfaceOutput(SurfaceOutput): """ + :class:`TimeAverageSurfaceOutput` class for time average surface output settings. Caveats: Solver side only accept exactly the same set of output_fields (is shared) between VolumeOutput and TimeAverageVolumeOutput. @@ -97,15 +109,19 @@ class TimeAverageSurfaceOutput(SurfaceOutput): class VolumeOutput(_AnimationAndFileFormatSettings): - """Volume output settings.""" + """:class:`VolumeOutput` class for volume output settings.""" - name: Optional[str] = pd.Field(None) - output_fields: UniqueItemList[VolumeFieldNames] = pd.Field() + name: Optional[str] = pd.Field(None, description="Name of the `VolumeOutput`.") + output_fields: UniqueItemList[VolumeFieldNames] = pd.Field( + description="List of output variables. Including :ref:`universal output variables`, " + + "and :ref:`variables specific to volumeOutput`." + ) output_type: Literal["VolumeOutput"] = pd.Field("VolumeOutput", frozen=True) class TimeAverageVolumeOutput(VolumeOutput): """ + :class:`TimeAverageVolumeOutput` class for time average volume output settings. Caveats: Solver side only accept exactly the same set of output_fields (is shared) between VolumeOutput and TimeAverageVolumeOutput. @@ -118,7 +134,7 @@ class TimeAverageVolumeOutput(VolumeOutput): """ start_step: Union[pd.NonNegativeInt, Literal[-1]] = pd.Field( - default=-1, description="Physical time step to start calculating averaging" + default=-1, description="Physical time step to start calculating averaging." ) output_type: Literal["TimeAverageVolumeOutput"] = pd.Field( "TimeAverageVolumeOutput", frozen=True @@ -126,16 +142,22 @@ class TimeAverageVolumeOutput(VolumeOutput): class SliceOutput(_AnimationAndFileFormatSettings): - """Slice output settings.""" + """:class:`SliceOutput` class for slice output settings.""" - name: Optional[str] = pd.Field(None) - entities: EntityList[Slice] = pd.Field(alias="slices") - output_fields: UniqueItemList[SliceFieldNames] = pd.Field() + name: Optional[str] = pd.Field(None, description="Name of the `SliceOutput`.") + entities: EntityList[Slice] = pd.Field( + alias="slices", + description="List of output :class:`~flow360.component.simulation.outputs.output_entities.Slice` entities.", + ) + output_fields: UniqueItemList[SliceFieldNames] = pd.Field( + description="List of output variables. Including :ref:`universal output variables` " + + "and :ref:`variables specific to sliceOutput`. " + ) output_type: Literal["SliceOutput"] = pd.Field("SliceOutput", frozen=True) class TimeAverageSliceOutput(SliceOutput): - """TimeAverageSliceOutput output settings.""" + """:class:`TimeAverageSliceOutput` class for time average slice output settings.""" start_step: Union[pd.NonNegativeInt, Literal[-1]] = pd.Field( default=-1, description="Physical time step to start calculating averaging" @@ -144,29 +166,53 @@ class TimeAverageSliceOutput(SliceOutput): class IsosurfaceOutput(_AnimationAndFileFormatSettings): - """Isosurface output settings.""" + """:class:`IsosurfaceOutput` class for isosurface output settings.""" - name: Optional[str] = pd.Field(None) - entities: UniqueItemList[Isosurface] = pd.Field(alias="isosurfaces") - output_fields: UniqueItemList[CommonFieldNames] = pd.Field() + name: Optional[str] = pd.Field(None, description="Name of the `IsosurfaceOutput`.") + entities: UniqueItemList[Isosurface] = pd.Field( + alias="isosurfaces", + description="List of :class:`~flow360.component.simulation.outputs.output_entities.Isosurface` entities.", + ) + output_fields: UniqueItemList[CommonFieldNames] = pd.Field( + description=" Isosurface field variable to be written. One of :code:`p`, :code:`rho`, " + + ":code:`Mach`, :code:`qcriterion`, :code:`s`, :code:`T`, :code:`Cp`, :code:`mut`, :code:`nuHat`." + ) output_type: Literal["IsosurfaceOutput"] = pd.Field("IsosurfaceOutput", frozen=True) class SurfaceIntegralOutput(Flow360BaseModel): - """Surface integral output settings.""" + """:class:`SurfaceIntegralOutput` class for surface integral output settings.""" name: str = pd.Field() - entities: EntityList[Surface, GhostSurface] = pd.Field(alias="surfaces") - output_fields: UniqueItemList[CommonFieldNames] = pd.Field() + + entities: EntityList[Surface, GhostSurface] = pd.Field( + alias="surfaces", + description="List of :class:`~flow360.component.simulation.primitives.Surface`/" + + ":class:`~flow360.component.simulation.primitives.GhostSurface` entities on which " + + "the surface integral will be calculated.", + ) + output_fields: UniqueItemList[CommonFieldNames] = pd.Field( + description="List of output fields which will be added to all monitors within the monitor group," + + " see universal output variables." + ) output_type: Literal["SurfaceIntegralOutput"] = pd.Field("SurfaceIntegralOutput", frozen=True) class ProbeOutput(Flow360BaseModel): - """Probe monitor output settings.""" - - name: str = pd.Field() - entities: EntityList[Point, PointArray] = pd.Field(alias="probe_points") - output_fields: UniqueItemList[CommonFieldNames] = pd.Field() + """:class:`ProbeOutput` class for probe monitor output settings.""" + + name: str = pd.Field(description="Name of the monitor group.") + entities: EntityList[Point, PointArray] = pd.Field( + alias="probe_points", + description="List of monitored :class:`~flow360.component.simulation.outputs.output_entities.Point`/" + + ":class:`~flow360.component.simulation.outputs.output_entities.PointArray` entities belonging to this " + + "monitor group. :class:`~flow360.component.simulation.outputs.output_entities.PointArray` is used to " + + "define monitored points along a line.", + ) + output_fields: UniqueItemList[CommonFieldNames] = pd.Field( + description="List of output fields which will be added to all monitors within the monitor group," + + " see :ref:`universal output variables`" + ) output_type: Literal["ProbeOutput"] = pd.Field("ProbeOutput", frozen=True) def load_point_location_from_file(self, file_path: str): @@ -182,14 +228,23 @@ def check_unique_probe_type(cls, value): class SurfaceProbeOutput(Flow360BaseModel): """ - Probe monitor output settings. + :class:`SurfaceProbeOutput` class for surface probe monitor output settings. The monitor location will be projected to the surface closest to the point. """ - name: str = pd.Field() - entities: EntityList[Point, PointArray] = pd.Field(alias="probe_points") + name: str = pd.Field(description="Name of the surface monitor group.") + entities: EntityList[Point, PointArray] = pd.Field( + alias="probe_points", + description="List of monitored :class:`~flow360.component.simulation.outputs.output_entities.Point`/" + + ":class:`~flow360.component.simulation.outputs.output_entities.PointArray` entities belonging to this " + + "surface monitor group. :class:`~flow360.component.simulation.outputs.output_entities.PointArray` " + + "is used to define monitored points along a line.", + ) # Maybe add preprocess for this and by default add all Surfaces? - target_surfaces: EntityList[Surface] = pd.Field() + target_surfaces: EntityList[Surface] = pd.Field( + description="List of :class:`~flow360.component.simulation.primitives.Surface` " + + "entities belonging to this monitor group." + ) output_fields: UniqueItemList[SurfaceFieldNames] = pd.Field() output_type: Literal["SurfaceProbeOutput"] = pd.Field("SurfaceProbeOutput", frozen=True) @@ -202,13 +257,21 @@ def check_unique_probe_type(cls, value): class AeroAcousticOutput(Flow360BaseModel): - """AeroAcoustic output settings.""" + """:class:`AeroAcousticOutput` class for aeroacoustic output settings.""" - name: Optional[str] = pd.Field(None) + name: Optional[str] = pd.Field(None, description="Name of the `AeroAcousticOutput`.") patch_type: Literal["solid"] = pd.Field("solid", frozen=True) # pylint: disable=no-member - observers: List[LengthType.Point] = pd.Field() - write_per_surface_output: bool = pd.Field(False) + observers: List[LengthType.Point] = pd.Field( + description="List of observer locations at which time history of acoustic pressure signal " + + "is stored in aeroacoustic output file. The observer locations can be outside the simulation domain, " + + "but cannot be on or inside the solid surfaces of the simulation domain." + ) + write_per_surface_output: bool = pd.Field( + False, + description="Enable writing of aeroacoustic results on a per-surface basis, " + + "in addition to results for all wall surfaces combined.", + ) output_type: Literal["AeroAcousticOutput"] = pd.Field("AeroAcousticOutput", frozen=True) From e80912b96cab9193c956b3f81456c6ea4877ff77 Mon Sep 17 00:00:00 2001 From: Ben <106089368+benflexcompute@users.noreply.github.com> Date: Thu, 31 Oct 2024 12:42:19 -0400 Subject: [PATCH 3/8] Grouping V1 python client components so they are not exposed directly to user. (#529) * Grouped V1 unit tests and removed unused fixtures * Added missing files * moved flow360_params folder as v1 folder * added flow360/component/constants.py back * Fixed unit tests * Moved previous root level modules to v1 * Fixed bug in error message * Fixed circular import * Fix lint * Fixed unit tests * Fixed unit test * Fix lint * rm new_simulation_models.py since it is copied as __init__.py * comments addressed * Added back gitignore for mesh files since we do not need them in the repo (they come from cloud) * Fixed linting * Deleting cgns * deleted the new_simulation_models.py which is repalced by __init__.py --- examples/case_from_multiple_files/main.py | 4 +- examples/case_from_yaml.py | 2 +- examples/case_params_with_units.py | 6 +- examples/change_account_and_submit.py | 2 +- .../airplane_simple/airplane_simple.lb8.ugrid | Bin 917244 -> 0 bytes examples/dev/dev_run_case_from_files.py | 2 +- .../dev_run_case_from_files_no_validation.py | 2 +- examples/dev/dev_update_models.py | 2 +- examples/dev/dev_use_unit_system.py | 8 +- examples/dev/dev_validate_params.py | 2 +- examples/dev/dev_webservice_usage.py | 2 +- examples/dev/list_cases_all_params.py | 2 +- examples/display_mesh_info.py | 2 +- ...urface_volume_case_airplane_v1_from_csm.py | 2 +- ...face_volume_case_airplane_v1_from_egads.py | 2 +- examples/list_cases.py | 2 +- .../new_workbench_project_from_geometry.py | 2 +- .../new_workbench_project_from_volume_mesh.py | 2 +- examples/project_from_file_geometry.py | 2 +- ...roject_from_file_geometry_multiple_runs.py | 2 +- examples/project_from_file_volume_mesh.py | 2 +- examples/retrieve_results/actuator_disk.py | 2 +- examples/retrieve_results/alpha_sweep.py | 2 +- examples/retrieve_results/bet_disk.py | 4 +- examples/retrieve_results/convergence.py | 2 +- examples/retrieve_results/forces.py | 2 +- examples/retrieve_results/monitors.py | 2 +- .../retrieve_results/user_defined_dynamics.py | 2 +- .../volumetric_and_surface.py | 2 +- examples/run_case_from_example_mesh.py | 2 +- examples/run_case_from_files.py | 2 +- examples/run_case_from_inputs.py | 2 +- examples/run_case_no_submit_warning.py | 2 +- examples/run_case_unsteady_from_files.py | 2 +- examples/run_case_with_fork.py | 2 +- examples/run_case_with_retry.py | 2 +- examples/show_storage.py | 2 +- examples/submit_case_to_folder.py | 2 +- examples/surface_mesh_airplane_from_files.py | 2 +- examples/surface_mesh_airplane_from_inputs.py | 2 +- examples/surface_mesh_list.py | 2 +- .../volume_mesh_from_surface_mesh_files.py | 2 +- .../volume_mesh_from_surface_mesh_inputs.py | 2 +- flow360/__init__.py | 407 ++++++++---------- .../{component => cloud}/compress_upload.py | 2 +- .../{requests.py => flow360_requests.py} | 43 -- flow360/component/case.py | 4 +- flow360/component/folder.py | 6 +- flow360/component/geometry.py | 6 +- flow360/component/project.py | 6 +- flow360/component/results/case_results.py | 6 +- .../simulation/outputs/output_entities.py | 15 +- .../simulation/outputs/output_fields.py | 153 +++++++ .../component/simulation/outputs/outputs.py | 12 +- .../component/simulation/translator/utils.py | 2 +- .../component/simulation/web/asset_base.py | 2 +- flow360/component/surface_mesh.py | 9 +- flow360/component/v1/__init__.py | 272 ++++++++++++ .../{flow360_params => v1}/boundaries.py | 2 +- .../component/v1/cloud/flow360_requests.py | 49 +++ .../{flow360_params => v1}/conversions.py | 2 +- .../{flow360_params => v1}/exposed_units.py | 0 .../{flow360_params => v1}/flow360_fields.py | 0 .../{flow360_params => v1}/flow360_legacy.py | 7 +- .../{flow360_params => v1}/flow360_output.py | 2 +- .../{flow360_params => v1}/flow360_params.py | 2 +- .../initial_condition.py | 0 .../component/{ => v1}/meshing/__init__.py | 0 flow360/component/{ => v1}/meshing/params.py | 4 +- .../{flow360_params => v1}/params_base.py | 5 +- .../{flow360_params => v1}/params_utils.py | 0 .../physical_properties.py | 2 +- .../{flow360_params => v1}/services.py | 8 +- .../{flow360_params => v1}/solvers.py | 0 .../{flow360_params => v1}/time_stepping.py | 2 +- .../turbulence_quantities.py | 0 .../{flow360_params => v1}/unit_system.py | 5 +- .../component/{flow360_params => v1}/units.py | 2 +- .../{flow360_params => v1}/updater.py | 0 .../{flow360_params => v1}/validations.py | 0 .../{flow360_params => v1}/volume_zones.py | 2 +- flow360/component/validator.py | 8 +- flow360/component/volume_mesh.py | 20 +- flow360/new_simulation_models.py | 207 --------- tests/data/geometry/cylinder.x_t | 66 --- tests/om6wing/Flow360Mesh.json | 6 - tests/simulation/conftest.py | 73 ++++ .../framework/test_base_model_v2.py | 1 - .../framework/test_context_validators.py | 1 - .../simulation/framework/test_unique_list.py | 2 +- ...360.py => test_current_flow360_version.py} | 2 +- tests/test_environment.py | 2 +- tests/test_results.py | 4 +- tests/test_shared_accounts.py | 2 +- tests/test_utils.py | 2 +- ...version.py => test_version_comparisons.py} | 0 tests/utils.py | 69 --- .../flow360_params => tests/v1}/__init__.py | 0 tests/{ => v1}/_test_case.py | 7 +- .../_test_case_submit_solver_version.py | 2 +- tests/{ => v1}/_test_cli.py | 0 tests/v1/_test_cli_tmp.py | 62 +++ tests/{ => v1}/_test_http.py | 0 tests/{ => v1}/_test_validate.py | 2 +- tests/v1/conftest.py | 73 ++++ .../{ => v1}/data/case_params/boundaries.yaml | 0 .../data/case_params/freestream/yaml.yaml | 0 tests/{ => v1}/data/case_params/geometry.yaml | 0 .../{ => v1}/data/case_params/incorrect.json | 0 tests/{ => v1}/data/case_params/outputs.yaml | 0 .../case_params/xv15_bet_line_hover_good.json | 0 tests/{ => v1}/data/cases/case_1.json | 0 tests/{ => v1}/data/cases/case_10.json | 0 tests/{ => v1}/data/cases/case_11.json | 0 tests/{ => v1}/data/cases/case_12.json | 0 tests/{ => v1}/data/cases/case_13.json | 0 tests/{ => v1}/data/cases/case_14_bet.json | 0 tests/{ => v1}/data/cases/case_15.json | 0 tests/{ => v1}/data/cases/case_16.json | 0 tests/{ => v1}/data/cases/case_18.json | 0 tests/{ => v1}/data/cases/case_2.json | 0 tests/{ => v1}/data/cases/case_20.json | 0 tests/{ => v1}/data/cases/case_3.json | 0 tests/{ => v1}/data/cases/case_4.json | 0 tests/{ => v1}/data/cases/case_5.json | 0 tests/{ => v1}/data/cases/case_6.json | 0 tests/{ => v1}/data/cases/case_7.json | 0 tests/{ => v1}/data/cases/case_8.json | 0 tests/{ => v1}/data/cases/case_9.json | 0 .../data/cases/case_HeatTransfer.json | 0 .../data/cases/case_actuatorDisk.json | 0 tests/{ => v1}/data/cases/case_bet.json | 0 tests/{ => v1}/data/cases/case_beta.json | 0 .../{ => v1}/data/cases/case_boundaries.json | 0 .../case_comments_sliding_interfaces.json | 0 .../data/cases/case_customDynamics1.json | 0 .../data/cases/case_customDynamics2.json | 0 .../cases/case_cylinder_incompressible.json | 0 tests/{ => v1}/data/cases/case_emptyDict.json | 0 tests/{ => v1}/data/cases/case_emptyFile.json | 0 tests/{ => v1}/data/cases/case_invalid.json | 0 .../data/cases/case_isothermalWall.json | 0 .../data/cases/case_isothermalWall_miss.json | 0 .../data/cases/case_isothermalWall_miss2.json | 0 .../case_isothermalWall_noTemperature.json | 0 tests/{ => v1}/data/cases/case_plane.json | 0 .../{ => v1}/data/cases/case_porousMedia.json | 0 tests/{ => v1}/data/cases/case_rotor1.json | 0 tests/{ => v1}/data/cases/case_rotor2.json | 0 tests/{ => v1}/data/cases/case_two_rotor.json | 0 tests/{ => v1}/data/cases/case_udd.json | 0 .../{ => v1}/data/cases/case_udd_legacy.json | 0 tests/{ => v1}/data/cases/case_unsteady.json | 0 tests/{ => v1}/data/cases/case_wing1.json | 0 tests/{ => v1}/data/cases/case_wing2.json | 0 tests/{ => v1}/data/cases/params_units.json | 0 .../{ => v1}/data/cases/test_version_b16.json | 0 tests/{ => v1}/data/cases/web/2D_CRM.json | 0 .../data/cases/web/BackStep_Flow360.json | 0 .../{ => v1}/data/cases/web/CRM_Flow360.json | 0 .../{ => v1}/data/cases/web/Flow360 (1).json | 0 .../{ => v1}/data/cases/web/Flow360 (2).json | 0 .../{ => v1}/data/cases/web/Flow360 (3).json | 0 .../{ => v1}/data/cases/web/Flow360 (4).json | 0 tests/{ => v1}/data/cases/web/Flow360.json | 0 .../cases/web/Flow360_Stage1_1stOrd_6Deg.json | 0 .../cases/web/Flow360_Stage2_2ndOrd_6Deg.json | 0 .../data/cases/web/Flow360_hover_pitch0.json | 0 .../data/cases/web/Flow360_hover_pitch3.json | 0 .../data/cases/web/Flow360_hover_pitch5.json | 0 tests/{ => v1}/data/cases/web/Flow360_v2.json | 0 ...2GL4_AOA15_SARC_2ndOrd_CFL100_Flow360.json | 0 .../data/cases/web/NACA4412_Flow360.json | 0 .../{ => v1}/data/cases/web/adaptiveCFL.json | 0 ...mixed-2.5flowthruPerRad-2deg-400steps.json | 0 ...flow360_singleSlidingInterface-steady.json | 0 ...ry_condition_tu_berlin_stator_flow360.json | 0 tests/{ => v1}/data/cases/web/s809Case.json | 0 tests/{ => v1}/data/cylinder.cgns | Bin .../data/examples/release-22.1.2.0gt/keep | 0 .../data/examples/release-22.1.3.0ge/keep | 0 .../data/examples/release-22.1.3.2/keep | 0 .../data/examples/release-22.2.3.0le/keep | 0 .../data/examples/release-22.3.3.0lt/keep | 0 .../data/examples/release-23.1.3.0/keep | 0 .../data/surface_mesh/airplaneGeometry.stl | Bin tests/{ => v1}/data/surface_mesh/test.csm | 0 tests/{ => v1}/data/volume_mesh/cylinder.cgns | Bin .../data/volume_mesh/cylinder_case.json | 0 .../data/volume_mesh/cylinder_mesh.json | 0 .../data/volume_mesh/wing_tetra_mesh.json | 0 tests/{ => v1}/params/test_freestream.py | 6 +- .../{ => v1}/params/test_initial_condition.py | 6 +- tests/{ => v1}/params/test_outputs.py | 74 ++-- tests/{ => v1}/params/test_params_boundary.py | 8 +- tests/{ => v1}/params/test_porous_media.py | 4 +- tests/{ => v1}/params/test_preconditioner.py | 6 +- tests/{ => v1}/params/test_reference_frame.py | 4 +- .../{ => v1}/params/test_rotational_models.py | 4 +- .../params/test_sliding_interfaces.py | 5 +- tests/{ => v1}/params/test_solvers.py | 6 +- tests/{ => v1}/params/test_time_stepping.py | 8 +- .../params/test_user_defined_dynamics.py | 4 +- .../params/test_validator_aeroacoustics.py | 11 +- .../params/test_validator_bet_disks.py | 4 +- .../params/test_validator_boundary.py | 6 +- .../params/test_validator_cht_solver.py | 23 +- ...est_validator_consistency_ddes_unsteady.py | 13 +- .../test_validator_equation_eval_frequency.py | 16 +- .../test_validator_output_consistency.py | 12 +- .../params/test_validator_periodic_mapping.py | 6 +- tests/{ => v1}/params/test_volume_zones.py | 6 +- .../ref/case_params/actuator_disk/json.json | 0 .../ref/case_params/actuator_disk/yaml.yaml | 0 .../ref/case_params/boundaries/json.json | 0 .../ref/case_params/boundaries/yaml.yaml | 0 .../ref/case_params/heat_equation/ref.json | 0 tests/{ => v1}/ref/case_params/params.json | 0 tests/{ => v1}/ref/case_params/params.yaml | 0 .../ref/case_params/params_units.json | 0 .../case_params/params_units_converted.json | 0 .../ref/case_params/params_units_solver.json | 0 .../case_params/sliding_interface/json.json | 0 .../case_params/sliding_interface/yaml.yaml | 0 tests/{ => v1}/ref/flow360mesh/eg1.json | 0 tests/{ => v1}/ref/flow360mesh/eg2.json | 0 tests/{ => v1}/ref/flow360mesh/eg3.json | 0 .../ref/flow360mesh/mesh_boundary/json.json | 0 .../ref/flow360mesh/mesh_boundary/yaml.yaml | 0 tests/{ => v1}/ref/meshing_params/ref.json | 0 tests/{ => v1}/ref/meshing_params/ref.yaml | 0 tests/{ => v1}/test_base_model.py | 2 +- tests/{ => v1}/test_case.py | 2 +- tests/{ => v1}/test_case_webapi.py | 2 +- tests/{ => v1}/test_dev_flow360_params.py | 4 +- tests/{ => v1}/test_examples.py | 5 +- tests/{ => v1}/test_flow360_params.py | 10 +- tests/{ => v1}/test_folders.py | 2 +- .../test_handle_version_and_unit_system.py | 98 ++--- tests/{ => v1}/test_meshing_params.py | 4 +- tests/{ => v1}/test_remote_resource_logs.py | 0 tests/{ => v1}/test_resource_base_model.py | 0 tests/{ => v1}/test_schema_generator.py | 2 +- tests/{ => v1}/test_services_v1.py | 4 +- tests/{ => v1}/test_surface_mesh.py | 2 - tests/{ => v1}/test_types_v1.py | 0 tests/{ => v1}/test_unit_system_v1.py | 8 +- tests/{ => v1}/test_updater.py | 14 +- .../test_validator_valid_output_fields.py | 12 +- tests/{ => v1}/test_volume_mesh.py | 14 +- tests/{ => v1}/test_volume_mesh_webapi.py | 0 tools/integrations/schema_generation.py | 19 +- .../_test_webui_workbench_integration.py | 2 +- tools/integrations/unit_defaults.py | 4 +- 254 files changed, 1192 insertions(+), 998 deletions(-) delete mode 100644 examples/data/airplane_simple/airplane_simple.lb8.ugrid rename flow360/{component => cloud}/compress_upload.py (98%) rename flow360/cloud/{requests.py => flow360_requests.py} (69%) create mode 100644 flow360/component/simulation/outputs/output_fields.py create mode 100644 flow360/component/v1/__init__.py rename flow360/component/{flow360_params => v1}/boundaries.py (99%) create mode 100644 flow360/component/v1/cloud/flow360_requests.py rename flow360/component/{flow360_params => v1}/conversions.py (99%) rename flow360/component/{flow360_params => v1}/exposed_units.py (100%) rename flow360/component/{flow360_params => v1}/flow360_fields.py (100%) rename flow360/component/{flow360_params => v1}/flow360_legacy.py (95%) rename flow360/component/{flow360_params => v1}/flow360_output.py (99%) rename flow360/component/{flow360_params => v1}/flow360_params.py (99%) rename flow360/component/{flow360_params => v1}/initial_condition.py (100%) rename flow360/component/{ => v1}/meshing/__init__.py (100%) rename flow360/component/{ => v1}/meshing/params.py (99%) rename flow360/component/{flow360_params => v1}/params_base.py (99%) rename flow360/component/{flow360_params => v1}/params_utils.py (100%) rename flow360/component/{flow360_params => v1}/physical_properties.py (98%) rename flow360/component/{flow360_params => v1}/services.py (97%) rename flow360/component/{flow360_params => v1}/solvers.py (100%) rename flow360/component/{flow360_params => v1}/time_stepping.py (98%) rename flow360/component/{flow360_params => v1}/turbulence_quantities.py (100%) rename flow360/component/{flow360_params => v1}/unit_system.py (99%) rename flow360/component/{flow360_params => v1}/units.py (95%) rename flow360/component/{flow360_params => v1}/updater.py (100%) rename flow360/component/{flow360_params => v1}/validations.py (100%) rename flow360/component/{flow360_params => v1}/volume_zones.py (99%) delete mode 100644 flow360/new_simulation_models.py delete mode 100644 tests/data/geometry/cylinder.x_t delete mode 100644 tests/om6wing/Flow360Mesh.json rename tests/{test_flow360.py => test_current_flow360_version.py} (56%) rename tests/{test_version.py => test_version_comparisons.py} (100%) rename {flow360/component/flow360_params => tests/v1}/__init__.py (100%) rename tests/{ => v1}/_test_case.py (88%) rename tests/{ => v1}/_test_case_submit_solver_version.py (99%) rename tests/{ => v1}/_test_cli.py (100%) create mode 100644 tests/v1/_test_cli_tmp.py rename tests/{ => v1}/_test_http.py (100%) rename tests/{ => v1}/_test_validate.py (96%) create mode 100644 tests/v1/conftest.py rename tests/{ => v1}/data/case_params/boundaries.yaml (100%) rename tests/{ => v1}/data/case_params/freestream/yaml.yaml (100%) rename tests/{ => v1}/data/case_params/geometry.yaml (100%) rename tests/{ => v1}/data/case_params/incorrect.json (100%) rename tests/{ => v1}/data/case_params/outputs.yaml (100%) rename tests/{ => v1}/data/case_params/xv15_bet_line_hover_good.json (100%) rename tests/{ => v1}/data/cases/case_1.json (100%) rename tests/{ => v1}/data/cases/case_10.json (100%) rename tests/{ => v1}/data/cases/case_11.json (100%) rename tests/{ => v1}/data/cases/case_12.json (100%) rename tests/{ => v1}/data/cases/case_13.json (100%) rename tests/{ => v1}/data/cases/case_14_bet.json (100%) rename tests/{ => v1}/data/cases/case_15.json (100%) rename tests/{ => v1}/data/cases/case_16.json (100%) rename tests/{ => v1}/data/cases/case_18.json (100%) rename tests/{ => v1}/data/cases/case_2.json (100%) rename tests/{ => v1}/data/cases/case_20.json (100%) rename tests/{ => v1}/data/cases/case_3.json (100%) rename tests/{ => v1}/data/cases/case_4.json (100%) rename tests/{ => v1}/data/cases/case_5.json (100%) rename tests/{ => v1}/data/cases/case_6.json (100%) rename tests/{ => v1}/data/cases/case_7.json (100%) rename tests/{ => v1}/data/cases/case_8.json (100%) rename tests/{ => v1}/data/cases/case_9.json (100%) rename tests/{ => v1}/data/cases/case_HeatTransfer.json (100%) rename tests/{ => v1}/data/cases/case_actuatorDisk.json (100%) rename tests/{ => v1}/data/cases/case_bet.json (100%) rename tests/{ => v1}/data/cases/case_beta.json (100%) rename tests/{ => v1}/data/cases/case_boundaries.json (100%) rename tests/{ => v1}/data/cases/case_comments_sliding_interfaces.json (100%) rename tests/{ => v1}/data/cases/case_customDynamics1.json (100%) rename tests/{ => v1}/data/cases/case_customDynamics2.json (100%) rename tests/{ => v1}/data/cases/case_cylinder_incompressible.json (100%) rename tests/{ => v1}/data/cases/case_emptyDict.json (100%) rename tests/{ => v1}/data/cases/case_emptyFile.json (100%) rename tests/{ => v1}/data/cases/case_invalid.json (100%) rename tests/{ => v1}/data/cases/case_isothermalWall.json (100%) rename tests/{ => v1}/data/cases/case_isothermalWall_miss.json (100%) rename tests/{ => v1}/data/cases/case_isothermalWall_miss2.json (100%) rename tests/{ => v1}/data/cases/case_isothermalWall_noTemperature.json (100%) rename tests/{ => v1}/data/cases/case_plane.json (100%) rename tests/{ => v1}/data/cases/case_porousMedia.json (100%) rename tests/{ => v1}/data/cases/case_rotor1.json (100%) rename tests/{ => v1}/data/cases/case_rotor2.json (100%) rename tests/{ => v1}/data/cases/case_two_rotor.json (100%) rename tests/{ => v1}/data/cases/case_udd.json (100%) rename tests/{ => v1}/data/cases/case_udd_legacy.json (100%) rename tests/{ => v1}/data/cases/case_unsteady.json (100%) rename tests/{ => v1}/data/cases/case_wing1.json (100%) rename tests/{ => v1}/data/cases/case_wing2.json (100%) rename tests/{ => v1}/data/cases/params_units.json (100%) rename tests/{ => v1}/data/cases/test_version_b16.json (100%) rename tests/{ => v1}/data/cases/web/2D_CRM.json (100%) rename tests/{ => v1}/data/cases/web/BackStep_Flow360.json (100%) rename tests/{ => v1}/data/cases/web/CRM_Flow360.json (100%) rename tests/{ => v1}/data/cases/web/Flow360 (1).json (100%) rename tests/{ => v1}/data/cases/web/Flow360 (2).json (100%) rename tests/{ => v1}/data/cases/web/Flow360 (3).json (100%) rename tests/{ => v1}/data/cases/web/Flow360 (4).json (100%) rename tests/{ => v1}/data/cases/web/Flow360.json (100%) rename tests/{ => v1}/data/cases/web/Flow360_Stage1_1stOrd_6Deg.json (100%) rename tests/{ => v1}/data/cases/web/Flow360_Stage2_2ndOrd_6Deg.json (100%) rename tests/{ => v1}/data/cases/web/Flow360_hover_pitch0.json (100%) rename tests/{ => v1}/data/cases/web/Flow360_hover_pitch3.json (100%) rename tests/{ => v1}/data/cases/web/Flow360_hover_pitch5.json (100%) rename tests/{ => v1}/data/cases/web/Flow360_v2.json (100%) rename tests/{ => v1}/data/cases/web/NACA0012_FMLY2GL4_AOA15_SARC_2ndOrd_CFL100_Flow360.json (100%) rename tests/{ => v1}/data/cases/web/NACA4412_Flow360.json (100%) rename tests/{ => v1}/data/cases/web/adaptiveCFL.json (100%) rename tests/{ => v1}/data/cases/web/flow360_singleSlidingInterface-mixed-2.5flowthruPerRad-2deg-400steps.json (100%) rename tests/{ => v1}/data/cases/web/flow360_singleSlidingInterface-steady.json (100%) rename tests/{ => v1}/data/cases/web/periodic_boundary_condition_tu_berlin_stator_flow360.json (100%) rename tests/{ => v1}/data/cases/web/s809Case.json (100%) rename tests/{ => v1}/data/cylinder.cgns (100%) rename tests/{ => v1}/data/examples/release-22.1.2.0gt/keep (100%) rename tests/{ => v1}/data/examples/release-22.1.3.0ge/keep (100%) rename tests/{ => v1}/data/examples/release-22.1.3.2/keep (100%) rename tests/{ => v1}/data/examples/release-22.2.3.0le/keep (100%) rename tests/{ => v1}/data/examples/release-22.3.3.0lt/keep (100%) rename tests/{ => v1}/data/examples/release-23.1.3.0/keep (100%) rename tests/{ => v1}/data/surface_mesh/airplaneGeometry.stl (100%) rename tests/{ => v1}/data/surface_mesh/test.csm (100%) rename tests/{ => v1}/data/volume_mesh/cylinder.cgns (100%) rename tests/{ => v1}/data/volume_mesh/cylinder_case.json (100%) rename tests/{ => v1}/data/volume_mesh/cylinder_mesh.json (100%) rename tests/{ => v1}/data/volume_mesh/wing_tetra_mesh.json (100%) rename tests/{ => v1}/params/test_freestream.py (97%) rename tests/{ => v1}/params/test_initial_condition.py (90%) rename tests/{ => v1}/params/test_outputs.py (92%) rename tests/{ => v1}/params/test_params_boundary.py (98%) rename tests/{ => v1}/params/test_porous_media.py (85%) rename tests/{ => v1}/params/test_preconditioner.py (83%) rename tests/{ => v1}/params/test_reference_frame.py (96%) rename tests/{ => v1}/params/test_rotational_models.py (97%) rename tests/{ => v1}/params/test_sliding_interfaces.py (95%) rename tests/{ => v1}/params/test_solvers.py (98%) rename tests/{ => v1}/params/test_time_stepping.py (95%) rename tests/{ => v1}/params/test_user_defined_dynamics.py (95%) rename tests/{ => v1}/params/test_validator_aeroacoustics.py (76%) rename tests/{ => v1}/params/test_validator_bet_disks.py (99%) rename tests/{ => v1}/params/test_validator_boundary.py (88%) rename tests/{ => v1}/params/test_validator_cht_solver.py (94%) rename tests/{ => v1}/params/test_validator_consistency_ddes_unsteady.py (85%) rename tests/{ => v1}/params/test_validator_equation_eval_frequency.py (87%) rename tests/{ => v1}/params/test_validator_output_consistency.py (83%) rename tests/{ => v1}/params/test_validator_periodic_mapping.py (97%) rename tests/{ => v1}/params/test_volume_zones.py (97%) rename tests/{ => v1}/ref/case_params/actuator_disk/json.json (100%) rename tests/{ => v1}/ref/case_params/actuator_disk/yaml.yaml (100%) rename tests/{ => v1}/ref/case_params/boundaries/json.json (100%) rename tests/{ => v1}/ref/case_params/boundaries/yaml.yaml (100%) rename tests/{ => v1}/ref/case_params/heat_equation/ref.json (100%) rename tests/{ => v1}/ref/case_params/params.json (100%) rename tests/{ => v1}/ref/case_params/params.yaml (100%) rename tests/{ => v1}/ref/case_params/params_units.json (100%) rename tests/{ => v1}/ref/case_params/params_units_converted.json (100%) rename tests/{ => v1}/ref/case_params/params_units_solver.json (100%) rename tests/{ => v1}/ref/case_params/sliding_interface/json.json (100%) rename tests/{ => v1}/ref/case_params/sliding_interface/yaml.yaml (100%) rename tests/{ => v1}/ref/flow360mesh/eg1.json (100%) rename tests/{ => v1}/ref/flow360mesh/eg2.json (100%) rename tests/{ => v1}/ref/flow360mesh/eg3.json (100%) rename tests/{ => v1}/ref/flow360mesh/mesh_boundary/json.json (100%) rename tests/{ => v1}/ref/flow360mesh/mesh_boundary/yaml.yaml (100%) rename tests/{ => v1}/ref/meshing_params/ref.json (100%) rename tests/{ => v1}/ref/meshing_params/ref.yaml (100%) rename tests/{ => v1}/test_base_model.py (87%) rename tests/{ => v1}/test_case.py (98%) rename tests/{ => v1}/test_case_webapi.py (94%) rename tests/{ => v1}/test_dev_flow360_params.py (90%) rename tests/{ => v1}/test_examples.py (94%) rename tests/{ => v1}/test_flow360_params.py (98%) rename tests/{ => v1}/test_folders.py (93%) rename tests/{ => v1}/test_handle_version_and_unit_system.py (80%) rename tests/{ => v1}/test_meshing_params.py (98%) rename tests/{ => v1}/test_remote_resource_logs.py (100%) rename tests/{ => v1}/test_resource_base_model.py (100%) rename tests/{ => v1}/test_schema_generator.py (97%) rename tests/{ => v1}/test_services_v1.py (99%) rename tests/{ => v1}/test_surface_mesh.py (83%) rename tests/{ => v1}/test_types_v1.py (100%) rename tests/{ => v1}/test_unit_system_v1.py (98%) rename tests/{ => v1}/test_updater.py (96%) rename tests/{ => v1}/test_validator_valid_output_fields.py (90%) rename tests/{ => v1}/test_volume_mesh.py (95%) rename tests/{ => v1}/test_volume_mesh_webapi.py (100%) diff --git a/examples/case_from_multiple_files/main.py b/examples/case_from_multiple_files/main.py index c22927834..976c9f8b4 100644 --- a/examples/case_from_multiple_files/main.py +++ b/examples/case_from_multiple_files/main.py @@ -1,7 +1,7 @@ import os -import flow360 as fl -import flow360.component.flow360_params.units as u +import flow360.component.v1 as fl +import flow360.component.v1.units as u from flow360.examples import OM6wing here = os.path.dirname(os.path.abspath(__file__)) diff --git a/examples/case_from_yaml.py b/examples/case_from_yaml.py index d9a38ba63..4624409f3 100644 --- a/examples/case_from_yaml.py +++ b/examples/case_from_yaml.py @@ -1,4 +1,4 @@ -import flow360 as fl +import flow360.component.v1 as fl from flow360.examples import OM6wing OM6wing.get_files() diff --git a/examples/case_params_with_units.py b/examples/case_params_with_units.py index bc72aa3c7..5d7b53320 100644 --- a/examples/case_params_with_units.py +++ b/examples/case_params_with_units.py @@ -1,10 +1,10 @@ import json from pprint import pprint -import flow360 as fl +import flow360.component.v1 as fl from flow360 import log -from flow360 import units as u -from flow360.component.flow360_params.services import validate_model +from flow360.component.v1 import units as u +from flow360.component.v1.services import validate_model log.set_logging_level("DEBUG") diff --git a/examples/change_account_and_submit.py b/examples/change_account_and_submit.py index 20cf19897..e2e2f7e2f 100644 --- a/examples/change_account_and_submit.py +++ b/examples/change_account_and_submit.py @@ -1,4 +1,4 @@ -import flow360 as fl +import flow360.component.v1 as fl from flow360.examples import OM6wing fl.Env.dev.active() diff --git a/examples/data/airplane_simple/airplane_simple.lb8.ugrid b/examples/data/airplane_simple/airplane_simple.lb8.ugrid deleted file mode 100644 index 90d0704f6d5441d9050afc9772a7610dccab3c42..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 917244 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�{2>Cx_DdfC1p!TBB3GlV&_cGHFUt1`3IbOhO6@WR0%{Wg zZ}i3LAeYVx?f=303CXB(6MC}@l%RPR_Kl_o9jkNy&YkEOb*9oE-JfpCRe%m8R> zz?(dZ_3?@lKWU^7;ZfG;6E89zM>@H~GFVtfP ztCVW=SIf!J3#ttcHQ$}!!xvT@WSD&!TbOj5BPW2sTFIGLs<+`4vN*l010o>5d0~}= zeecMI42e~Mgt(gf6(wNv^G{DX7?2UbWA}y5JdJCJW&~Ne)wTej$cQsfd5Z^k^&T)a z+>1lPS7!Rfu=OBUsHq;a>%`E3>=>i#NY?fE=i}Hs-+aBG5VpVm7ey(i>2vV(?xOdy4_PP}jynAo- zW+(!W7Btpt(aS_ZUbZ)%!UTDMVD7GuodOG}mfDsuXt9Q-qtS&gG5ws>?7CsC!j8TT zAv+*<(STD{Iy~_Q1mG`RuYO~n8juH+T+)%Ufy@3JCf1#T;K9d5$v^FQAgHOEvdxwR zS067O5nd+(XWqBlTE{pb4FvARZPk8Jpi)IqF&mHjoD*BNZyF?}T4`E&pj_|4S{%ZcFYwT#Rd z76RIG%zxmB-9sqxQB7JE!?*kwO}5;ad{wN1zprt!wO#Rcj!5jK z>!BSCg5b2dG0h+q0X+ygb(&7e8rh{hB`$&&1h!3KKf|#3XdfP`^9H`iefr4T&oTX} zLpZ?!w$DkEyn{*Z{kPpBfsd#1_<_l`4Od<=J4&EiWxH|D4`!6>Q-<#e0GDr}vT=X# zXmD3z2fd{UoVF(7vflB6H;pQhzD+n_L8x}1ptFFZ4@-lG$OXZl()t=(Y=5hh8`a^X zsz}=to*Ov^IKWj}a?|qG4%8AkTIum90Lo{d>R7EB`lMEy zVfS->a_SK!h9|s>J+-8xN=U4a=uM>^UhqY2=Qiy+4tA<~F=`z$myLWMWnh2VCmedD*@F-nr zSqh8rRixJEhMNd>&+RErHp-Y>H2ejxiAiDrVr!PrdJ@A=dK_iNeN0}39~|_8zM3O0X(~;$>jD6wGHpHb zo)XO8+d0bVVgh{`i}beJF@HU>lXMlsAF1$z$;?)NWa3<-&Q}b_WY(Cij3@{|VEr#s z%hMak^lPUoolPQ8_#(LT^(!8gnRjD%DZBw6i*@!bVfNL@FX5=pNI*+zaxQuX1i~|I zbRo`ifl6geqn) zGpD}yM`JiyB0|P|S0n}z3PUm@u)YY6NgLq~K?1szRD9>{w_sSgHv{SXzq@lgJ#P#UbBVmvF2vcdGm0W*-}RUP$uI zRUQ*KV97DjnMwrick$c`*g0><1uLjKCLyIBy{}6?5y7qXCv~bc1oTY*Jr2g`a70#u zbeL321k5wCb+XayC{;LNHnsf*kdF1E(wuuPN zw%fId46&n8B5kK0oi|4I3qC8}!@d{MtZp^uB%nc?QggrfT;SbG9;bI$efFqm+Y44- zEI!5;CxxguLV{&!z5k2=aAIaw^ZJPgApK29;F1Z=_(h6ub0oRhoQ24C_w!5%QzQ@AzZ-KWwP(@ex z$ZMhQ7%QNrN9~BPz65rjpYa*tiGXyOLGwb>*24= zZX4sl36ICm57UMqcdq7<-ykD`ma$NkRvs4cTxlISt7rgESj%?|DG^w?rtLt2tJzg2-4z6JJK*(`9LSYhuz^aJ1AR9YR6mmhMV(1}! zLMbOJjpbu&$joaWE#Sd48(x@0>W+~XrS0@`Qhcjuhpq2b3_QJ)1OCS{5g-2$=)*Kuh{#GeMOOT zPcfd>6!oNluk|^Ch4bx%_B(lCtJG@HGIVDevGp}iOy>Bq?n3XL>{-^&EZ~*ui(>*-8}J>@*5K#a2-smP zKU|9WeO*&dJ8OOd`h=jpJv8nErNp?RoN|ajsyHH?lY@ZfM3yX=J&s1s3C!72R$_hi zzu8=lRN&Fi*U+9gHWR2=#}s)S!wr@bU$s9C;DI-~$FAz<2)iaug_uYSf(t$w57g)h zC?U-+;ZO(GH>LmJjn*R~_#{9vVvgbViRf#dUf)Aujmy}XlbF2zZy%Ztca?)nng-$$ zu{`1}NCX+~J@NXOpX$gKd*!g5i^MLURDMlO1jR=le9XtrkCav%Q=iI4l=^j*r*=LG#)rtGX>$g_pmOZ)%v^XkVlslh&)FmSsjh!^9liqc7nKeq5- zA-&-w<0B22r|eKWw?zaV)0dwoVRGLdmwFr^V1{_N$f)pS6F~!+gbg{SS9@P%)mSQR zkyWx=9;@>h-=nRIW1qyMY(w!fIC~d_tFYUtD3l1M0?%5{Vsf z@PKPPqQ%{PtiY(FsS;?ILI3(yJ|iqXwGs{3d5rm&V?X2gI?s3_uWMd!M_}`wJatW$ z7!Ln_`S$91=AqY75jwgP>_>BILR<}r36tWnGPOM{g^sC`;n;)hp29@{T zo8OH?o`+r4-N*3Ire<^`4D;7c@0d5x>k-JEzfbqYuyfWW6^s7BelPD9ef60;{K#NV zy-JR}Ai#~g?@40!*%uJ_W7pvc@*%{LmLA*3AtjP5iyh;c8V_ZT)%hX=K=bGEZXWPS zVHuP>Wd&36K8%b(dQiI{`Pa%A_8zcp$JV%?4ds$+YhD)jM#{@h+^E(kf(ptN&(GNT z&7>N?{56h&9m(;Vljj9NZDT&}D`uyA@jvsX77iiOtg4ZNSbP`#lKT4t3=fko86KB! zm4oLdob6enh~UZTp|j^{38?a!&pUk_5pdt%x+O`Q0gP!?aN#e_L7Q-YvXPG-NW%cz z&Ci&i}q{aG9qbuYrQhw6G4ZAg0vJve4rkhTVQx6_&i<>w(viTtye5D^^u=xG& zxu$-7On(Ady@neu`5+%}tGzUf#qtad)|PAE7{La+8bjdTZJ4Cu=;m~b9oT+&ta!AT z42>ty;Pw5On*~E6rhYsdIm-uFUli3Y(Nsp2zsPbAV}2GB!^^#sBeSo+I|?>|)2V zm>|&qU2+kG1sH(*L9W*u%w-(AlZb=UJ8aHG1yAxzZ z#NRe0$SM!S+fRDBO+gTt{|FC}#N=}Ost|9nLkOJ7 z{ZxMv%L`G8^m}Py^-0CUjf$BHcOV+$#d1lU2oi8ZIRc;Y=w8HAW(S7^czsr%AIHi8 z6xeA-B(%y^8Hs> z+!XSTMjJ1D4GvsZbRNg_#NryE+BqGMzH2@-pEHnz1pml^5?fgRCwESn(Iy^vD*NAa zt}ur6Lt@bySf1x##e-1s&mXy1>sOu+MZ$=}2M(`@ATKBXRq^qbe~ObIMM>%XufFrfc4PN8QE4SKVRIWIwN8floPuC^G49wpraxVk zcE)>$9>6$;Y{VGjGt3`z_G2*lno&FOBN1GkQ@=%l z`N#E3KR*YOCm}z+eN>sn`uffrHl0nx^s4zsTUptU2t?Ph8tyQL z=qa(a z71Ye|`Q8oRf;Lq4{100rAi9C%}3K z0xtXrR!{e5e^|BrPvJX^ltDH5%CKVD=(3YWcPu z)7$rEK@gU4CPH|St5q>{I^nSU-5AFq&+z=gN2h86utnBIpLaz&9 z;ch`hVEcXhv@;f;=G^f1>>SWXu2>ICox|c;Jwm&57KZ=6E5<$w{7$gPaZ+Uxiw8sE z_sgs?zjm8?^d{H%F_?HFLb?4g7I(j4zLt*Vg-&LDku^S%gFIed*(kzz>`ck&hZC5+ za7Dfi?73-*$jV-vS9*rkTUk}&Zy#Yo!w;H`%U|Ax`)_fVuzE8n*19I@oV)>rvvzo$ z>z(1`35i>MnBHz4G7WCQ&dL6oknEQ62x0hqQXPLv5ZwNv_<0!PMMFE}{B)ENkcRf} zrZtAE?|;(N{#L%7!B;%^eX8cLTe$%eA8I6a{i-1N z_P~C%;TP7&;Ws3;8W;@+*jY!J`~|@D)X({gSUh{X`MoiZp%uazQY&=uPyl4tRrs@F z?}8&f>=n$dyTLwR)Z?__Ql+ne-!c1*ikLKi zIdKK9mE%&@WBEb%L+&3$wjh%Q(_+=vx9Qi{5ml{V7|e~ihXbU%2ecnjSCcNsyh85od~LM z4IlQ1?5M)_9hTNwJy@RNdAWHP^ZVo%JEyQbi3Lsj8{T?3BvaM2?f#koR$r$6vN49m z*W*l2*BAZapw4{4%pEK)V81CGfZ6Xz;`4r*uP#XIRO&+(On($P5AJygVZ24-_iaM0 z2a<$bp6|r+x+{&svwWETPj-3xl(tJjoMIkt-B%(o6aS!f7?YQ0Hdn%rUUzuAAgoHZ z6pIsk6;3>)t#A8El zUB%vUKQno*^<>f>8p-0$Jbf(yKC|AW=TD~qwnpX?q|q$>fDV~6nKD|udL$RJJ>r}C_ld;6ad4v1G1~S z*npqt*Wxdd2hicS#0#%84-tjYivsaUM4;__|GpL0*FRkOM?Q}!3E|W;QoVeL4=hkk zTdVN1fe5lXTE%e>s3HI79jzVq|1QeuNlsY)N^aEbMsQs;l)U6rG=$|{`$`!S*D(J` zGW=x{(W{Hdp4=Nci`kvK=uO8;%L{w6m&I!>FnOP+(E7>z-Z%Ra&Q8H55 z84u^Sip-ErDzjy0rGDr0`+h&4uYaD`>-N0v`+m;3&ULQqeZ8;uk;*7|x`^NB;Po{J z$HRBfWo}3Fhc8&*@BA0uY(-nhF+cxSpo15Z`y_wTnVAh5{8|dhU?w9(-5Eb6vxXpV zKU4OZ8$vL+fjV9a`?s8P6q3a+LeZnj^+A?%LJ({iw0*$)@7H6QnVFszsOt&+_$hrM z_(gl^@;#g{G$`Dz6CJ+~WJDP(7k}dV#c3VO19+Uj$TKcI3e-hsr1!kx#(wE{qbjcy z9?!gY>r{WzEs(XGv1Z4x2+Uu39CZ=L+wYG|lqw6}0-BAxh>{i&I1`s4GC9Z&n?JnV zb=UbeV$wX#+lTu#28VYg?8oDIlEiu1T*VD+dhl`A8HzxwW|oTB1{PvFcv`m3-4I-| zD4Tc2<7vKpU9I{zI{{C|(zhPR`Pvc2Wu0VU$mz2sYVw&Ke#qHte)vx=Q2X|ditZf` z>^=7I%)|SPkiq4O1Y>Z<``G{w|I6!2Mj*y@t;$ny&-$WA}La^SR;7V^+ic+VpUc zd2Yuq#Q@Pu=9Ra38MV*6^1Ub|R-k##?dH99aycKP51(STs(V zsDht+TXHV7)y@r=GkRR%S`vT(7g9Hiu^%`}SLWXz;)N1j{Op}@{~GV(Yd$%D*ddR; z<@k4#Ye;HemBWGn#?zL6m3+i`{rQp&13#W5WT{o>5rgANdH=mf9I!uRuq40SkQ9JI zkJ8n(<2*NCNq6y0A3HQTe&I_ae-sKx$uIkZ^LN>%1X(g34x&>h<@?Cq%Sf&8*MYs* zUkUv={;CDPztqxaP>ziHt*#fD|!M_D}Y2NXt+{Jd}uMPFKZdR|Hhwp?Gx zE5dQCYYnPQHwp*8Ptoqtio|*sH;n6?`8kL|E?sB3hS#Va(`Ec}v z&}(E1WQBfJ;K};V4vL{|e>swL1F>;QiEIhs`aaE9vPO&VNVH_Hp4DqVknv4xiOyCC zGEB<~JK}xqoMU#_6F(bddTsf3gRv0I%S!iO!t2iPZLgY4Llp9SG+#KRCIp?Ir0>3o z--lDHd4Z$z4sy9+XJCIt1owAzHCgY$_5)x>Mq?rX2R9ZBa6Ip1z9f&OH4;<8R?{TPtrn7R=|0%ru95 zm3f6QE)>>Pjq|m%sG8ds7imuvav||D8!f=a% zj^9g-o*?<;ofV8WLMPpVTV|C_>Llb`HF z<(X$6D?G1))u}5w%y>U_3JW>33+Ge1ibsqU%8Y=@)AFYZ?0CJ86&-xD7wcn)8-6); z;vs026HP3~xMg4Fr!!2rF1%SRv%LJ(3z!~klDzGLdGB<;H+wDF2|06*&LYMDwDwGu zB?JjV*_aU~>sof$P|~aIGvJJMOSmS!$YVQyrF$O|e?G_L z9`1W46xiPP|J)zK4e1Q>8cxj95#N8VyDN=`p@G7H+2Gx{&Qi2YCn(DVyF=UGDwP@_ zh1lizVvGZ%zCOPz6tANw-tNyI8N!j{xsnocybp@odwMheVkbIGxo&iyzW}~|%9Gvy zSrBGQ7&pEA#10SU{GO!TG(=-Dwl*q$*sk`O+J0`qykH(?H1s(QC_KIU`#`M-{4RO^ zdiF9q=F8O#$nH)6l#5FHC@?O)&+^(@kOwOyYiSAYYQBOtev2F+VSa^B-Sd5a|5-;b zMf4c0TtJ=xmr1NUC)_`m&T?>yir}MSidVhu4pQwj?fRbzLLqK)gC|dMJj^zEzxTKn zFp!L1HN)ffvQA3wHXgTH8wWl+4OY-lwsN>?OavYYb$Zo={oAT>_?b8PZb1uUF#AaLT@A((Lu>}qv{$OvLDbX-Qk5Ry?gFxe`h9a@7|sEIOT_Cclq+X!|yXW*2b%b z_Y1pS1BbsD83C~jY2DWtH&8v6C+UOz$)E6j;RWv!Ql!Nd-8X-FD2+u3>kiqk1>rbz_`1ZWKw(>S)W6*(-%JP&-+kkK6Wc>= zIMYFC+ho9Uemcx1m=BsP8mUPA7z9BIQ63FDzF<;?UGfmdA1rmRH?84)`QlXL2bWG! zl*8J-*|@27$*XEJt*yl@nqc?%O>RTtDCm2V)dt0lhhaD13 zG==#kNgzePkE0Ry5Asc^rOI!x!=im}O$DrOg2O@z?-z~;L!QD2`aU~$m|Iy}kQ9^$ z#80Rjl&}lH(CcS^T*kUpgUX&$CQMi_NKjFa!yoT!>2iD)IR2^q-{D5BnquvYTk?U%5r7!coWCfEsG(i z&3;OO;XlVIzhHm+h1uD+3FAC^oW1Xy9$Z4K4Z7mV)Vz>REp9sVJ0q;IV~Qgy4nyr{ zS8n#N2*Q?gNz3vpSU)Oor2c*7H_dmf&%-^Doki=2Wd7Jb^~83?W}y1~ zIJPS-sgu5ZhvQKQ--B(55fS+IncmNFY!3#OHro=5K7bt+PkhAqfU4~af#Nte;_A)S zd-=0&fJ|2)`e1+{%-!KXsqM!Old>2e+v2+C^TTbY56lU|-~~V;pJIoCRu+uc2xpY3 zam=p`#b0vaX{*evh<@n*h@gB$F zzPjI=@Ob`y`|#y2LLWWJ5trkN5rVAUR$m73I#s%K?(y#TQAkJQN6ib2&+qIH-R#2t z!LzG5!Bor@M0d?@rF zeYBi&i^@()81f5Ee+gBPVGnErUVpopVKOapLUqr$O%^$VUCUuMd`qFlGYm--lO zam>^3oYsx|j>oNLgWq!OQ3Tj6cAd25AOvMUd!`lQ^&)dibmlCJAEF9&)?r}cf;sj_ zIsWp|!1c+9VOn2Ha8yfExefFEw)D7^f3b5A%5OA(oWA1$^memr{~|bH_~~AX(e6QD z1-Ym7+KW-}k^P)XxPC;HqJ3@%`)xDMX?Gjl%gArHTU0r&<5Y?7dXKPup1rhwHi=vZ zyfXCN(~HL^n7GDTi{GE@Y$Dv#dK0Z4z6_w}q8=sq;H12%EIw?D366ZZoX|1xT-Wj3dcAYRnv%5XZbNC-!$D)`-B~qmNE+n zh7E!G$Dv;nJj+pkqG&b6c_GNLZN?*r?O9~b>XcetC|aM=?&rYsd+SEG-6a0Kidjuh zCkM1Z@4~#I$TY^=U#A|G!g1F#ZRHG|`Ws-nr56M&VqEU-7oLCWl|>H&FI?o(1&zfA6l1Itn#Iptr3A>BK9&rkbsy;U+&S$xJB^okx& z^|{Rrl{&oVIDXMVp)k>s){EDX_m?4J`z|l+&oF})7Ru87r9~ct>+~8Ud8G^# zMA(gPrBnTW=;7|RSJHvPP~y32-y58lJ!xTjzukTpkk@T|sl@(vCM`jC9LKA*ySHdU zyg~un{!an=KSUr0x8M&aJTEtse#Yi!Ib&V82D#rDx4F~%_2WV84;ihFiSCIr0OYKd z?6+|}{Y~YcZgXr`=HYT2fzNG$&CnBN^*9ljyJ)wx*vd+BB zzDGnB#<5?u^U2?Ak3mCwFWkoF51Hp^w>p6RoqjZgpnZRSCx@ zgFR&G^zzq{WzD_;#SkIb&MWfD1M{zVRT^J$8b^ai3l*}Jb{J1S-fz@;jg6?1$QRoQ z4+PN3vhO^`Xa1@NMN{H9Jk{&$BGSGB*fPgIRN~*8e%xH80^grW+Q7c~>~-)?W9W9{ z16=mAh5!ghQ8g=rhH;=!dU1cl;qPI5m5d zGRl|+_NZ;VcDwC^N?RKpro}j+H*_D8R-uCQ)fB7}+HQ#JD32QYi1}~yyj@@Mb2mM_ z^T}HSKvJ6)B3TH)KH{@PDb`mwcJOWb!6TMvE{2_~)kz4xr%pe14cmELlTl$8>s?^^ zH~sf`FrMEust;%JILJDa^_yEIpc7w_X!M{k>}55IyC8-6Cn8V8Ge8n}zzna&v|LrR&n&z)T>07(U#O@w(o>aC73@Zdk^hQfSa@h6F?I^gVrs@rPHrRazJ~ zcJSz9<6gQC-b8R(kYl{A{jk}}?`<|hqVk6v;dTQYJJ}nAYu`Fl4c^cG03?gva@8ULAXX1wA|BaLDls zA9N76(HFt`kT;h1NyrqsqeZg%00(TJO@D7Z`GT@y;q_8ALNc)% zZ~=4XQYx=8{&~J||Gpu7|JUy9?b#A`06zX{5=+SqKY1@+-LspHc%m;*bi~yQFw~R`eJ=#@3k`W1?y5e%%)QwU}S;c^|;TQhu;J#x@^_r*#Gm; zoEwwI`%!1~&hZ!h24J^g(}Vsc5!m+lQ<)xq?w_c)Z?B7)gK*o!gP(q~z=BAt(^kdX z=r=6!s_!YqIfz5&BV+~d`=FXrOs*++gkalw(WYnE9wy#vWgb)v0+o^6 zHKOFakSth4v1f~s$SmJ$_pZeY^$qd)|8B&5NZOfGo{jAA?g{VVnm zC4yZflVd0_FSPpDlR-RRK7rN=FE9?nKu^oSDrN`F6>OO}@&1@+8Sq>U`@I(@vWCd+ zIHAHzi9TatxISy+_4?!>JCV@QwJchd3fME+z}VtT`+51u>*o?@v#ua*kJJfm+fq)XZ1TfT4SUA}7pvad`}Co!Mr zWsLG)9lY*xI!#R^G_rx{>(iI)aNPUC{JG>yypOjK9`$HG43x~Mtoi2f!{{{H<3$;) z(0)Bg<#?YvDp5{Z*7=CzG4+2wS&7nXKBiKEElN&4C!y+1LFlzV=ado754Jjf)MoTM zBkzR^#}L4wEsRy^Z2g?I({zg%~&PIQ5E+MeZY8T^36YiGQZM+f|#b; zTRiXjnXJi)nAa^VDLioFg()hX@-w@P?Zl;0H?JJ$o91tmJO7^71^3NNmo4zTY|9qh zvBtQ^?U>G*p^L}BG?@DU8eKi-f^tY(@T;hOkr^k zWvPm{@~&;QypoS*Qv8}+&j6wr2MLjtb%ZPHD@{fg_tf#zfno<*Upr!jQ>>zIc? z{vy~J*Vl|5RPGTJ%>)sVoYsjQ7>}Cw{XG4EotS7TRUeXeMfG&-KGD{~u=t4C)$(mR zSgC9-ZrNvqlE{)xYQN)sLGeWXJG}0su3vxgGJg-)*Jt_u5&pew2c(Yc;rR2^(?5BQ ziIRXvr26~*8=O$-_3K!_W-2KEvlr5@c%#~dNV^m&5h!<1_?>7CJ6x-V{vQt{qhA$s zYQmZPuaRyt5Oq!O%#91e@ao>d(8ppNgx_JaQ^^xa;G=U)T5`D%T(b34|A_e{ z^3{I|ZOVgy%MCrLS5ZRnM$Uoqd_2xhF3W1h8ufn&bZ)s?AzU(LCfE+An#(|_Ulrt%T4W>^H1F9)>y6lH7gXPiBEF} zvkJqs#5e_Ij2HPCl3iNAbRV(0Dx509yiM&BRI*pmF34Byc-O$$90h$!D}RzM4F71q z5W9f=wv5>In*|<^z!j;hS1#)dLuq{n`VpKbhAp()9bQuJ8ezD*nmV8WulEl#Eg5Tx*#M+xFN|Womg85|o3yx&PyhT=#=SRYprAX*wrM~J z8f7Q0&S2i@Vfzmbi5me(fLpUD1IN$*;`4i^th0oUh5?y zQuK47qHjEFAMk$Bawv@dpSYzU*vy)r9w1uB^F5bd3&ArPH-8+##y~rzCEezKIwMrBA!$GY)MX~cq=;AyBBM*MhuxtKE5Wgp# z-F4c|Dn-QH$n$^?uT%i7eu z6@n*!pCI{T|Fe2PbtPjk5*64{!%$vfSTOpL%OBfet$76lWAs_{kbiLYjJyDp@QYv3L|7I&e%ih*Eyu%oUdY>3)Uo}*!&!v05dU}ZFpov6D# zbbp1`5am?d7Ct|Z`)(HGO*1e)&rmjx<(lpwy3V0PZkRXty62xyb|PixCK-YINyVGV zSz9sg@pk(Bw+>v__+pPj$6gzuNUn#I>T9^Ze_Ha#TRi>=n_O8Z`YxcMvXk~q%EHjw zT4oXA_1HQx6ztFU0LA92`Ui91c%Gj*r~}9Ix129h_GZVS_X3o6jPSbnWYGGD4L`SP z?XPNDfi_so+XNxlJ_qX}9&zDuxO6H*_Pa|Q(DaVu`tk|}{R(E&L(iv@O=cuzH(BRLs3&wc7_-GlpghFIEX%02i-l;mIahkQ{d8BUU-Dd%1kDA5JmP} zi;Ww72FM?@y9ZWb-4(Li^kx2oD5v%SOA_@qRe;9naH!dC zZWwv(-fk}PL1e^cnfLr?4R8z-zi0V`3#!iKv?P8TK-@m3#h*eFaQjn1-JHe=8536v zMo$cbOe4BtN37!~ekx^s{uS1lvEG#X(L8{*7Wfm-nG+!Ex(<^s&ik?qN9#h+0P59K zZK(Hd0Gz|;p7&&NK;`KEI+?Zs6n605H&>%ZQ1!{t`iCgiKmT_1_RgmPuBoX3L+Btd%P}-;2E`m9k;c-j@LEZM zfivweVzc2D@D^+aAN#cmURsO5&+6uT2IyG{XH&h^8QSaM!>0I!A{iF==I_Om?~ack z)WzBONuUWxNuMaD)nS6h3^PimIjczInD0XMJxeqjy5dDhMwl;ObH?%OD7uughu%bp08LYS?PQZNba=fmRMn&oY^nu1 z&)L#L<+s9n{7T0VQ;6YgkXQ|vo&Q`b@4*EFkltg(RvN-Nn_KP!T_oDa%wj5(MGJ#h zx|c5Ujw9+bi2@7`r9kD$I+cb5EzB>e*B#9pM>dI`(MrO3=-hBsA(K1}47eUZt-gO8 zJx;p)=97C4c>T~LUSoh7^9Q!75+%pc%zD#xF0%(9b#>xHMmaS+c2wnU9p+cW_4g7l z6e7Wgh20AI`P5MO!BWH{tm7T>G~D9-7jJNdB`|;8f)Cz5==_}J%OH@x!Oj)3mH>`0 zaL(T)Lf830+`%(7nAdv9IuG-v9L%?XTf=%rr>Q1wa@(^eMky2Nw=U1_Ah777WJ+q6rlM-f2&r=2l;-AO1 zDf7VO@kbqo&P#}@xYFgz-zre{d#FQjh#O8WsdO^+QxjD#!b5_8%Rn7#hx3LbJKWtM z`8Bj?6WuYf)-akQ0TCaw5OYsHxcgv2jBF_*Vb5Od^+Br`tVi4mFWfBvADuoy=f#P2 z;6EN1^uAaEk{AUhLI@5RRZ!ui$MhZ1JGJNhP-z6Rw}O|h*z?2LXR-;+nk+=sE~Li) ztN^sTi?S&^!u+~{(p^UDbVSO0{`>C2LJ$-)t7w?diTmi!CToZ6pv#oLQSG1Wfwbdm zjTwx?lhJ0jbXl?e!xxo0++GL_wdGSD#^d#({9st=%6ByWNv6n#yb73qTsT#&#s?pU zlRdd_wv4Q@yf*h!6oQB?kN4+QIH0R-g%CZ~1H42Y6)YI@5@aSBbMjol`{S!Z#c2vA zBDOx6?6gxp5WCIa`KbZx@U*&8*>+_$gJr)?T){e)OyPYpZ1e=Zq_TaVOex5F-rOd(!~%y&-qgkCXHbWBy`|3XMv%ds zA;YN52HOfVjVz8%qnkVd6z--?;PMBj)r-4@p?~LL!|$dn#6_iDYeuJ^0bkLS3nA`Y zFpoQ8e=yAg@>vn)yo=ZSr3;M9eZhiIP_AtCKrlN|%w%wxWyTaWh%xDMX>dWm3I5Eu zE-E4|=Z*+v&vT$OaO?7%6+hfqC{A~!_>KJ4Zp^pa<^gG5(jt=s3-syZ=B`UwLB#Os zCo;_yAl#CbzB`Z&!i_yWsAUJSud`pE{#6VL)+rZ4S@8Kacd9-ew3$XCW~sx{*iI(y zpOCY{=Y4#Ry>;S1Jq=;-?4-1GTP5&n{#ZD{%M1Nv3oXmPk`aGJmM(X@)c|8R^A4X? zoG(4@nhaQ4K@S{0SiN#?0QVS+j)Z^ZhGyk~)=IB-6C+OL$0Rswz^O&6dUY>+uFAI% z!NUgRgolzP{WkAY5a!LZ9V*WXBX#zqzdQX4U88E}HaTAj!UJbwnm4)O?q1cw(83vH zz~4nypZXe~mn53qT*wEj+O`xwicu02T2-WpoJtVIPT^m8UI2GkKA-;C-&&-Q}2xp1Ri{0 zw6wSmSgxt)MNx+N29;GJ_wOWvRPH>FAl$EAy0z`C;EDlxy;hG{u$=!Z(LGim(ptBV)@=Y40Sk^t-dciWDiIN{ldv)3YIrjQYr zaOuNj0#LNb&_>8(yk?+4q-F0S`VnI@y?w9|7)>s@=TQs7qsMnVoTF$6Psuq6W0@i_ zu#eehM*`ces@jqH$7`sI(IxY$R3)g~f9msv&shJhBD$k?WEnNKSTg~;T3`?xwd>1A zHW+nb&y*|gFSMuKihkd0J=l8=1zx_0^^nienGiAb#M7pNs^0?TAkY*Zc<+h%d6MHk zeTSz|^hW1HEypI1Z=lyFX)XXeJl*^>B6kq~tBd~ETpj@StK0`~DeytfLeW=OPtBtJ z(F-6_IvWIkb5sp96o8Z07^u(L&=JOoW@GMeOF=-Ms4x%Kjr5MWYGE6`jut&U++Sx9 zK#$F)=7k9_ESyvr@| zwIDtZ=w9}_Q+xlQjv=zJ-i>nL`$lc3`w%ard7|PrUAB$3`)_uZ##DhBJ3 zP~O*#zjOoz+Ngb2ngr&izm7^btl-2`#gMd?aHE~t^udbhI&_Yv$7I%R>!UakHf^#K6(yVgCO_>uma0iVkHZ3C=h9BI* zaSZ@58E*=Xazc{y+W951UBp(vEAe{;wIG*4L_(2_89L?VBs*8EA&~-!TTc%sfNP`l zI%Zf`JZ85z^}bU~#JO;mbIngm0ZBVGIh-8p@s6J;YsdPE^E0*#8K%s1JsV-Y6mg0E8udfJrTy0B|SmS`XOywUNJBJaEHhK2*@dm)tsFo{!g&m%XdyJBw zVV-cjB(q&NmtU zI$iw&{AAr>^|0ZAn|_LS+d{~RM*f~q?#WuvlFMv+EfUuk4}@J@-}M`bNe6s>wN?l2 ztBtaZV!q0&G!yqjORU7TJ8z_tLLY(jEO%q(8U~n4u{y(R`W;;wI2yFYSPUkwh--hq zdV24zPql^@d`D9CWxFdlUxKZXaourket7tpqRhG$;!R!1t4^_genLwSaPDw z*F@zn`qTfwJ~6Q#oOw~=KCH+O4WxO3?^4nbmkv)qXsM_Gy8Ye_iI)XneF%Bi^W!W; z>|=?p)8@rM;QNNCBi2{scKki?@%cPb)ks%r9xVrA)(i*FVEy^e^*QpC&7aY3c{Qht zdm2FQ8xcc^bXHiu+LXp3wT1k4seY+;C;^)dS01n6qQdR_+>M=Be{xe@)Td6l08kvA zj~ANdf?2ew-(GC(A~c>$t(RRSfsj}2#wRAYVEoOA$mXvr=)RL2r)&}eum7xlI?~Gz zCHrk#Vwhv;{xgcJ($-GXrT?v3Dr z2v*`)xHo-L<_qw#UT?1(*3)aAOI z$M~RWr^@RhQ)s<@v^h;e|IA zd$lmHN%rrGkTS`fB+1e#8xp!xE+TKKzYtC3)N*Yp(+zV8wL-+}H3->g4T_A}S)usjkFo ztO~dM#iW$_bqc#Vzu@exUfld~Nn01X%C3^79$sfUTVz z%U6>r3FK=fdyFOmcpF;PmoW*$8qdwj^VeC4eN3E&19SPnoo#CT7d}@-@BWAKj&w@m zsEa5C%hhV&mzEG0b%qCS=yUt<1pGms?z91#NhI*>WQ34t9+mVLej>kp@rFE$leGP>PP;R?U?Tskbxt+-MYHz3ohYXI%JRWC(7Oi4Z-iss1p)3C6 zAEF6p=vM2Ch^K}hpO5yoSnIC(op0#VhC{VnWh3C| z$VuwOeQ*<$cFfvXMUB!9afDbB+-t??9+C{Wh zR3CF_tpLN*Oxa9WpEKcH(1yCr7&4mW-#B%k8SHcQisz)}gj!$RPb}-Lq1aRUrac!L z0PkS5L6|-ZT$XXW72-RGf)aY(CtDHVA$fjY+ARU7Ngf{OZ?lP5UizwB!9v0nO9zh^pedvX3k z&rv)pTmf8OEanyB^IYQKhqo+>_spuZ<$t__xrQR!@$i+ffF=nY|AG!xjvzimW zt8zj6_t)4{|E{3c{UHg4sRY>Ha-+ISgcnXWby(13{Y4CF=;ec7)j(9^-Mi0+1)!|7 zcycHIZo;a`GpI?e2=FAoD;{3shU&Aq{h?ytPzJNUs98@H;4^(pq~r5h_VbSXyc11J zoXll4y`xYH#8ky!aC`E?1XnMHu{d(#@l4LDX?-==7+_Z{oxpjeOdmZ3_=UDtBLwSC zl>)(?<#an|c6i<7Yl5=eIyyU$>TVy70O3jTrDhEG-NYZ^i2lG#oOt%->0QoOppv@b zAeld|=S}D9JlC5;N|b|FCm%F|N0-OW>^;T>Im^kdLz{OKz8y^Z%lYMi`>bf}%u8;# z9M%;-B0Y(2>15sxNq!CF$|8K--ZDUwscJSIqa{?)5O-4kaU6(MiQPDNRs>pC9eDyU z@09L-nJ!=XV{m@^3vIKa5d3s@;-#x06){9H8qC}p3cQC6QzO^8VR<1B6)hz#@sLa_ zlH+Iz2wcvoImf{bA1{R*F&CjA;+925kTn2kuE-* z?>8K~qGqDaLb&H^%qW-?0pBha{JY6(~o?R%4XdB1IKB{vK3TvBdLjV%PoAT({R2S_TzVS8P;>T86hesyo%5F zI$#s|hy*g`rcc^0a>JJk5=V>7*HFgGId|!uTClOhy-EIs7x%+pTbNeW0`r!#bQL6<+gml^{P{QIk222YP-De>Weyo2XTxH!e-C0n|a%>STOu@Q~=E zg=(H3NRn1#1B+&YLkibB`&Y64iOri7J%$bRh4jOBH4}mL8^Guwi4E%`@#Q=?x`jfx z$=D)Ts{u#POBZ$AuW@d>Uq5GwinwA+_MA<#96UX8H{QBQ2!0*ry5G~xOz>KeEiudH zfkQ=Sf*vK~^H5l84<{}TBE2-m!9T{XDA})m@WyRc=$N8Sdvb0EJ(&F?p_c3d=&aE& z1J)-u)iqERaHk}`#{7u-=w1bSu2NO(I?4(c)mA0Tt(Q>05AV_0ojP#wXoYGW)`^Yu zE_k(jY6}fNJ}>(ut_DP1W*3%m^ZcKj?=)B4y6>q+({G=a;YH6Arj2Szy2VH&sUWkI7=RJY6$e4l8awPE@<9R zPLy7R1~Nugk8Irgh$I@dXBeZBK(FRAGAaDrmsulUf0=$n*SsQ2ZZ$>#A=^j4#Dke3 zUBO=?g{faCMJqZ@r8^X5=KC+Hsn9}Nv6l%Om#0wWG@buiToPCiuO_#^=g9OXYxtf` z8$yJoX>pH$6UuH1xtbkF1Le#{WA@#eM8wMQ4Bt#9-~x5YXR$7Q!8@fxL86nuT9F5< zY}uifE1HMh4%5Kb3fB&9*W>T|uTP5UdV$wu=Du<=G_WmH@3Z~MNp!K&V=VgDUEtJ{ zk-AdA0xekzN2l*^A@8iP@Cf@LAT~B6&G-kO8yL8^m+99w>Unea*2-IJ^w*X%MLCHE zzT0OpsZaMAf%qd=Lgk}?p0w?JS~b=^5c#_NwUV6(xpFLLz0m=Ysh;yUy>AHqrw&L) z7Q6qErO%ZxaR10?^WjcrtjAj!Ws|xNTGi$6xLOP=vE68H1!8dLg&79ARSlLH}L^c!!^$S}gScY5Zd z*<*ks{bt*q`Eq3NRR0He0VAyQem-(QX9c8D_gA==j41tkfB6M5GA7yGWCU+jXc&!AXJLSgjluzJu9s?$9q;{NpJrSIA|0- zLBj#p>u(A@0p>dgo?ToqCE06<&-E!4A~%+Kb-LObuw4?sUCL)mQfCx!5Fe>P9x{0k zIsIs1hc<`Gm7Pg2=dG6!Yg`0O+msrcB71=KewHKRcWrK-Z9z)6lm=F9J^|q#eUadW z+ay7~IMvI#ZAjYk?j2Tcde}BEsl?kb3MAq$spT~^ftz2IULf}w@GLaHU2N?RX?E&6 zef>rUO0q1ln{^d}tCZAnvRYIGv6ywI@T~=C-1cdBBh3VlX3Fg8zq|_cSnR3kgIz%G z&#()ADc^u$b5?9xUl7ULS()nSz8*AUB}`ZOdmW-eNK}zsvO<;bQF}An(Yl|@;01}wQHD2+^mWK$Z>UHgddaV2Ic2>DmX$cq z9S;sC>3n@P^TDPcpF1O+7IGQucqiEQuhEX9gZUrs$Q_Kr=SaR}%Hk4)3S3b;sk{E7 zBL$BJ3b?J1ZhCzsb^kipTl?hX#qJ2w4bEY{wg(?jtkxU)rcf66p^BS_ZEzFJO0X-> zT#iBW-MOWdF04?ypX*PT-#B>bNG^BaL$UUOr*NAgP`{dp%aj&9Nmkw1M)1KnE{RD9&`k?se4cH+A> zj*O+W0^icmVLrJ}(Ie%1Bxf%BcUNwYqZr@G7yB>J!@w&h;s;OPBZ(eNeG=g^j^*;(6S?*WKp6z@%q~+vJ(A%*!dj`)Hd@- zxGWh@YPa66#%eH%7J0O{)E!viO&N`wl!0+1r=#q-HuWQDaZTUFgdWEOi9x~=pJPcA z*ZD)v9T-7}o=xu~3fN%Eg_5oigILm1E1Pg>@i5ZxWNka6&JG*7`4mbfVn|0vbnmmO z4kMc54#^R?KYZ7is`k1so?m)thJyJa^p0<`mFYItzf*p6zi3|!NsF+>c-Rn|(UXf4eR@BJ{kp3h1LxmcO9 zbX)Esb$1672|FI>biTdwfl4%~mL)a7ta}idEPbfIzs3U}OL}MVS`9d29YYc zG5y~lj3?hSsr+~@nxv{bG9%qTh%N>6JXU%WsZI{DVO9%Mfy01u+47gyM!k#izc9{ChlrX-PQ;YZ@OUtq@)gcKG*J%pNGhdjGj=W3oN?oc9?r*Cf7> zXwsTb&e|%?5F+0{$9AurA6^~5*>EsBnnY`K*8imV5YnhBB1=>efQNP^`gao1Bnzg~ zTvKoe)hvu2p&Ax|e=dIOJTV$gqGH{5Vb~DgN6|jKvS|piKtbzw-`b{ zbRF&dalbbIPm9Ry!Dtd(`Sxm7e+c<6Gipd@3c-*|>@N>Jizbn(b!wY&eDrSoM8XAk zjCV1ZtPIQy0x^c{ZUtR` zoh!MEkWHIdC9}DO#OLYsls;e{SL!$|LuM2yTK3nOOUDP%&*cM~5y!F4XNb-)eN7~( z=`zYqwI4u@W9#W3wS{1^k*}Ng3reEqyz*xv&>XFsbDJ~c^VvxLiD?b)XJ=B}D!ZK)K{Dk#KiG5Q14_xdoH&w=&!H1coK)RMO=#w+vt>-nqOXy& zE;_hh=9bsr(`*;RNzHfanFo&aBi8ixZ8H--_%!IR`KzO22rW4!%D#>R<{w_oOStdl4-pz*OOfFY!7O>%rv?(b2={pZ>}Rie<(smVJg zC5SZ0n|dg0x*HL8nh`geC8k@JT2t&X-$rWc-KyITDSQoQrQRiP8o|qzT-Pe zEBX$khEr#+^0ii>PjxI~S5o*OFO(IEUl>HwlhQ$I`awvP*Xx??Ju&FhV?66rWlbWw zf;eZ3%MhpPfa%Y2F}QQvcsuErIq6aO^O>*bijkZ3=~dAQG58_+D!Y)q38~@(?6w%m z|L=FTyXuBp>+6v^d@iihIOQPw<1uV+*O=h-GV2b7xi!?InzFZf>*oK)m*Vi8+&l{{ zbsVzT;lH!FgwKil|9|4}_u!{E!Nnvr*YM!@1;b2KW!JeWFpc$mSSUW-^Pzy7ryT^J zq+I{+`=Iu^gTZ(vl1k#K+}fA)-}Q>Y^+hI*Y$TH9&;p2<|E@pqc&sGDor5m3Nqjh_ z>xVwEPdr$}I?OjL4Stj|?S}pH^BZxR|95}xDt)~_>^bOR_dfp*eSYBI_srrYQKvIz zqc`w%yTjj@|E`~YaN$CEZzl4xief)@BI&>DQ+87{7HX*|Y3@5$F0NDjd!P8}lvDwf zgv<}=b4>bV{&)Q~@vBfV=`zW_jmbopITQW+{ir&Ta&h`Vlx;*7yt$M8-}nFL|72wU zJN_WA_ITpkNiq2E^*1q-g*nFg;82Fo#u?K8UGLZ}UfFT@70{UYl(Uldf7ivW3*H^V zd<+MdOYSPzestY3=vA18fG4-G=0cnU=xtN~e?+}^IF|4KKW=X_vPW4FA{wG`o+%}j zk`jtkA`xXKAwpzRk&;cy9vR_z+k11{BQjF5SE1ka{T-iouj@aL<2YODxBub8+&%(GtP72DTQ2Ba`48{1~L z)yHaoC8O&ekqvv-#qpH{(z7?C5oovg)4icF?_q&cPdPd0e>n~m6qV&IDK|a3(b3r} z7wahg!~euBUVpLFjZPaWi<~Y4Ii!MHxBDsf=`M}p~u7jZ8X=Roz>->km`4$4aw|da__xWFPs)YWnA2(QP zxTD*HuJ3$2{Yd#g{H&BcXXvpWq&mg+G5eF?zx4+d{^AE>Jt(q%`<^`Fy{0$m$}&3L zjiMS4CjO~*L-SZgz4B0_0D%AwvS0mN~N55e3jGTy(1+SQg`k%(6k5c zfLM&wKLyyU%PP6YoHCH#$?HJM!!gF}KwbqYGMO z#%}R0g6N$!vI5%9nGGVZAX-S{2; zrSdHHsLA)COQRWT{zUyu@qd?lbE~R!X&-vA6qIUD)Z72VFYVvtW6|wL2{BA!*NOW4 zfB3nyq11vO{YXC1U(#{=@1mrLC5qD*LbR+so^|`i0qQCY@*-q+o|KWB0j4XKrXd-e`VS}FbA6_2( zJcdJI0A0Tus@vN{{SW8TF!)sy(2sgt^}oi3QT@XeALVC}+WU}}QDc6w9_2rrulw{` zC{-W&+?d_?R+!=+{<^_8?)1)H^!ZB0tXuWw|GiHrC^9EvpF7L-AomgLkR7E0c=vYa z!e6}L~AC%E>dh3A0 z9n?|1@ZkLX+Q0SaiC?0K02#$dSsus@UHONP9~qri-RMNhceTqC(b7MBk=v1VwXFjk z@Oo9{e3Q6;*mBF1+d4YR`qC{!#1`3qVRUL-o&UF<^}z5u=g4;S_^5d8Gt7=L*S1Gf zS9_6FuFDxgrW%w=YiDI+Gy88nf56Qsp37}WoaY3!uMQ(_;kkHAnly&ee0SgRpo;{G zE3&{r_2b|ARq=hdDwkT&-x-=i%uk7&GOLU^QT9R9Bu+U?8y^lNQ>EI~@QHux`<}G1 zwXrv$aTyj(S^3d_xbNQ0aP{wXC`j#c#LN{2Y?}C2_RX0gbi>-1+q2|7+{imPZ|mCs zZ#|B*)H-v!8cnR+{d;?N$3OgZU+sOS|2KD7gnUJvx_@}H|L>iL1xnG&&ylB#G>QJ) z|6NyC3|=OQ6dQB$G2zRMoDccM zzoS=iB9f~@en=tPK_{N@eR6ubDqrT?4M)SIV^VY(J>(pe(!yaFro3l z)RprQ+~O(OW9=}4a%w8Vw8Cq_Ww(U6_TC4Gb2R?zmicd_I9sC-o`f~LqdeZE8es+eKFaI3jdBfHXhj}(+xgFoYm?FE)`49oj_gJDX z>}NOHr*W8+{^SMvEu<)A71W9hJY#B4A1MQhK9!QQ)`ZWG#255JW(|FI6qwI1=>pF4 z)H6}1?GT5awKv@Xas0#e?3%`vVqlGYtd!<<1Qm;*_(4qY=Z)B&PhKK}-F1eBfkJm! zmMVSJ|L4EDE&@rj9#@G+cEwV5g%*w6TX>l#%V+p#JerTP+RjQFi$k{XLotp!Pp0w0jF`Zi9tlZ4*?gOAZ- z4;f4%&&@jtmBL`hb@M_oI?TIY|A+y7Kg@f{?s>~tftq}lCMio9@m}A;(d^(sr0rOA z@#u?>;5%XTYLi&?sDkHXX5wr zw7Em=nqmx6Svh%Qi!vE>!}_d0*9RcWxBW_SO7!@~)Ewo$tKD!~)>UHUNE^HyxdNj0 z0{HP>l>@0ix<2-W&jB=CXnt1~KU9l#MY<10A-bUeSb_0qE>k zSc;HH09K~B$W;n@Y<#3DtMJMIjH_+!&m7AKo35SxiC*;h*{z4qR0Id%=?_8vq7;6l z{+Z*A=o5OpvL>cw1zs2#{r)Pb3eh2`<7xT9(R~(9RDV0o{7sopTTU=Z&hk}1k z8{XiEhXJ{^9h8R!FuknkV(E!CXsVSc5Atk9JbUbpY?tN7PrC&uzC^XbtHIDD3c6M# zBR;iDHG&6ECA+Fd47b9S!5J?ZhDV%U{(*! zi5cQ^kMt{-@Ez`isfMYSB611I{(jR;Z7? zK3vZ=zRZA=&YL`{TIqroey`Vq#vNcl(|OFxipV#gyej(hZzG&`c(KLg*a5tU*$f4U z+;+046p6{b6(+Bx9t>#iMA@6vL8Eco@cf5Xf#yeTKp!8TdtQc&oaWwTnPxEK+rM%{ zYPdS!BZ=inx)B*g?n$CyCgyPre;fDxWFq#Bx2gWG)Vh!|wXdw0Bp?3#^VERxzE-&K zymI=deH)11QhHx`habzON1ci`ZiDc{ykD}?Ez z6&(?Yylf#&@RmD|hh@^Vf!3eUvMaRY)Cjd^_fFT4t})ZUNckqcvo)4(N`HylQycXSQWyOTsjifCXgxkP7 z>C|acsvbo3*XL%I9TTRPE9R%x?|^w_cO!Y?`;z`*@$nD~4>nwjTSyvcf(ECmu{S^4 z(aE<)?UfG*|ABh8p=IWFFt$6~eOa4~j_(zf6suvwo>WixbsjB4oQ+cx!yR{!p;ZZt z5F>N})VvQh?Wsu;eku>!CZ8X$8r#38b4y04snSwkGGfryq)W)Ncdvmm z{-7YaHW9>&7c~;P!%)M+_U}JcUW4QwNBh#|_h6;!=b$DUg1oeDaQle7g3*w_N*$Nq zp$NK#uf?t+`0@41YSJ@0l5k~Rm^P84w66X1*6e;(oMJZ+R%x_=p3041FAR5rG!=fM zj7=Y;M0>;GM?|PDou|a-E%aco-Lczu|tpCH|OK8GqgZa1~16HwHpEBSl&K1p9vyLu(L>U8u zIZ2-xaN`TAk}R1Kl)2l7f~znF_-f5cA6=or>ZH?g!|R>EpAu9PcfK7t^X+1#C>FwF zLdo|?^=%My_4_5IH?1I-MKAh!Ck@VcfxVxsbij{}X1TMd1KziC&eUGsLW92?nGY4U zL3hQ={pZSCk<^EE+qp-Scur?J@DN=e+_fRYByBX5URKvrRo;Qqs!J_WecGURL|`&g zfRHTgZnsMjnn&+bl$8E#Z-+ySSBO^YOIVry&Td>yfzSN-j25igVXgl1$KvWX(C9>g zorG`LHWv=&3il=m+4DeJe5xG@?96i%yC;Bm=$m9MogIhc39b*a;vx|Fa&nTmpa|Y4 zZE0?--2Wf6%7YfYrUZR%nRHX-tx8MM8EzPZ^{WJS!!Qk(ND8;Aa2jl7(sqJQiZu z`__o?AG3A}G;?bP2brFl#`i6tBkR^Saqu^?T+@D7o7DmulOwYB%B^6hrBN8jMCc_u z9`{73wu1SWl)Lx$wxZfwKQi8$ETaHL&Hki>Cb0UQYRSXghz!jzDD)8dV(Ycv{){$4 zsHvTF?%_scH2O9{O_lJ!4NNX`*Q3t0iGysbeIc@bv> z&n_U_15{`(w+jeWoSDt5>U^|E;E^aHfOp1eRdmI#p-!c+;lL|u-xiv7{ ze`nNUtq($b+Lm)ie<6E4ZBq%eI`9%~;_l|IfkC5oN$$I%_@Vlj_Jsaw*c0gL`mU-T zywmmxRa5*$BDqN%aTR2!90~a3x>OFflR?*|{psfX|@xwc&>| zan7<4nm{@`1|g2>gx~8O-stvJB#)gHBkqb;S-L9UPw1O^n331(>)r!rJ>;7f$KBKXKVLjf`#yC;k0g2`9WlQujvH zAo(LlWFG5N;};%IEr!8Wkm>4}O2O3&*|WR5q8J1)R#-oS>DWp4kAD#4`t<-^sQLWk zps^s94?TTP)04=Z?-rH~FTMcVGsXPU#ze7xeu8vuLltOi5+b$qN;p6^u8XOl!a{l3 zj$WEopt)z2!V7xPwDmn2rz=dj@q@WO8W;y!8|>G|279NG(? zI|Gh-1(&0(GqF2&1+ruN-rAee9ji#5-7kNpIt6957K}@Y?ZCNduMFfEnMhM7!?!2Y zK0pnh)2X$51#tGz>Tca%-RL1nQ0XP*Bj}TP=+D9vk32`w_?rWlOn4aohwv3{yvN{N16B%bg&&D?mGc^nhsM_pbR$8iQs6=- zXe3T1Y4_J6funm%-nRTkl${%)ZbKd5*lFQ5{=FKOcqF}iocOSw!ijJv?ppAx*AH9u z?Sv8kj;*W`e%xN?ZE5{!6~#^_g}ui-H0Bura0c$IHOG56d7fx!<*hj?kI@|Ca=&OPUelb@K+Aya#4A-Z4;^ zuae4jT?nt#@Jd;~-GsoXT(foi=g=QZ)w7=1xQ!+`%70K{D z=knu>u1ug+e@`LRvw~_KG5**bs|B>~q`ZGy8!8X+)}B>cLFU09*H(Dj!N2=1dXiiT z^;0Xn3w#U6@Zi_C`lTe;v!Zg%Fsl{O89%A{5V?fhq&7Cs*mMAeV2-pVWTP<7oX-_X zIY=qYOxrUy3zTWkPaFMs4Ml11UyX(rpw)X5xTDGh-v@!N{&HD8=Jn`7V zVFy<~u*;SG)Zrn)N}+l07*Xe6^Zc@DcC875_o#jpa_WT#U(R_^1#ZV|q6hRYe5?Yx zHcNSt?PQ2~IH2yv)`6H5E>}s&kl^RHK{Wx9Y!J6-uP;wy#D2dOJ@U-S5Y0HeU_ir6nP#gUzK*zGwm#Pk`)S`5zaw;BpZo-DOeQ*E zfbQH_7P%H}^a~x-C*~mcr#AyA?svho0tEgg_W9oM@xsxogl;sPI!Ps~3Iep*doI{@ zA&JbfpHx)au+C50>JO2%!1s{es5G+|c^M?Eu-G!=Q+nKm@3ZURh!>@SjZ+_5r4c?s zA;pO2Ed6HWLfYZ4va{)tHZpQhVd1CkBl^8x>#qAUlfksh&D?XO5e3%!Ny)$ei(Ux4 z*=beY1pLu6+y=`X2vKm+7VTO`YPWYQGssmzmH6%}i5?wD4KwTSIJS;nwVr1mxzR<; zXGhu!0t?VNzh5R5ySZ`8Wz&7erj@X_Op|v*gp4Na=L%oWao}x(7JTlbHK0*+%+kQD z8}aUJe3&#Klf4KD>>-;n88Q4rpa;r22NE0XUn7exFO@$NSYicV9f- z36n1n3zn>dGvt#;7!EPuG>HZg@z;$Y=Vr+G_C+sZ<&qw;o7;hz6DB_B)^tD{dKjxR zRD-MBJ%MjmZ7T`-W}KgpaE{?{6(LO1y*j`!$!hH_;^> zt&8EisBvYVOoLb%aUOiFK9YN<3(_<0(-cl^#~akz{_^?Vh?~`ww8hpYn!N^(elPnXPx339EdF;9c?V1;gI6xZ`0H5}9o0nCj!l<1x_(g~mF;ieA=9 zm$?RgaSqMB|CQK;alD4cOkN?1D2{>3XZb3fE3PU`Z39cdG5-6X!=$S@AlKo7zmTmuveYy1i_nK zij3>aB;JqgtsOg>C!YdohnjWFaW1@P(J-RmTs3_1o(Q`P_*Gv{$jr2Y)gylW%mZTh1<-q~1=N5JmQ=qV zn-2y4)!cDH)YwWpXgaEe@WFU4%z4hf3EhpHFJ?PViGyyKU0gLI_SLaXa`rfJ<`HW@ z%@(->KTg`Kf8uZ>yf`*6`WMQo@Ady8ZxCGT5yz3J8^(z|A z$gVmqT>}ApQC{|{pCPq5DL$)60Q>3mUNZkV3WaZmipM1t!153>;L~d0F z$jE2!xGE`v-)EEJHzsLFm*Q%VHbj^sH&U&gFrl0FDF1Of>?tKlnL;Kk>+#@NIVg ze4gV<1(@$24exv0fkM7g`zq$|#67h~($a-Gp_7J$GADAt-0nVM!Dh?a( zK)m;cXio6b;C)Av&I=JdCy~_elDbk2P-{Ezl7WTL;jy3gx@m$0B3v(WmMo;YQSYTHJ{^#QDT2Dy)In$C%kgvhFlM z*@LiUpVSUizAumI8Zi$&Q8>V`eXa`93a$C9^~lg?_Uu#N8aH;YdQ~Rzz6Sm>-B4#{ z?1GvfziRz;IdD;0`5%juHL(4*dZMIE4`N9%eBLL~#~ z_mu?SJMYt`8B-q&X!83OR*_)zNU!<%uPk_~O>x~^y8$LPr2{K!3BBw#TlHN;o`lq! zeb;xq>3|1&C$&>vHG_AzYg(O;FwSaFjjimZ#CxUhT^RX!2T~X_Idq8rQs;tx4jH#Y za8?f0&nGRY$o%BWM@M?BBp_DS{%rtMAB0q17x)A#;v#$;u@Ok?Mt$Y>kr?2}j01P8t-7#KQIMm7+Q(;Yj_M%v%Y%7$lV@dZvy#8g#1?lcr7LkRHct zo?k2}=<64oo8ODmpxDGny)V)YNR$Fm4V<|sZPZ|2+jKT$H(6c2lWzlF%Ugf>9GS2a zeVI`C)d9rE*P$??MnWskT@xS1ZlR-wA2hg?2)zKSSim;>3@~FnMj^#Yi&N|y`)fC< z!RDO#kte0S$nTT1&MD&j?&%<0yiJa%EBr&g-Quc%qT{h^w+UW{U+>0l0re=fyfnz{ zZyt`6Y}(`fL}_td@Xlu%pU7abUU!bSqZMkK^1c)fQDBRPqjo|}%`l+La!BWw=X0nZPcBCH+V|zYd$57l zevX|Cd_a7jBeFR^BT7K#y06^bC!5Gi*-C}osTOuvi(In#+=-lq2K;2TsKT{gOSB0ZaGPze9EIACpSRRv`ZsYXWzyATsc z98GaOKmJR#_*#_U5&m9n+;>eR0$3g&wH+Y~5x(?Ym+Zp3!Eax?hY(u0GUBFK;7|@H_}`au9m7RC;9`hm zbiH~$=%(0;)3g%4WGZ!!e;#ZHgSu@-TCC;ZdPa3u28$?;T9vU@FCch?Ckz98;K=*Mrf%Frh3YgeNShE}4{)p;+MdF27C^`m%>DFN&W7 zpI3agw7Gi&7)a3!^;<9CQheBkrQbIEXst`XgLM^^u0>5a-*!Y31D%H)2;R=ntEA1G zkUZa6o?Baes5~gL1t9g2mNNgI)t-g!B;Zi;EC*C1b+b?l5-{c{HH%n zf7_i6PxaVe$7c}whhr@1*V0>o-K8JBf>|F|76~-dsk~9x>oPu;Va$X za=#vz6aE`{aZ}B#Th-8gJw+y(x(lE-%%bowF*i&*nae3bh96SX+rop&VTMJNev0rJ z)82i7-1eM{L>=+#MECYbSgjA`_QKVq>fzQAQ5=1A-|m8pTDWv~ z+AUtM45^SL^ais;F@>`8!L5N7@L~o52kkg8h_QR5wVRmt)ud&fiKqq3`QtH^NJ0d{<2{l zU|B|dy;;_zk6vif@_p^PFB3LBJJ`~}J5A_mZB&~h9Z~wz0%ci?ABdWb;b@uH7s&f$ zeZ_2N6Kd*sT zn-}wbkXILq?t%h!E85_*m9W@oq%1-3u3c!1LiH4D;Faxxr*-X}@Gc_G?esh`7psci zf8DRtv&Kb+};Rt_OjyeL1e`0k#=d8iZm4e~U^rR%`+*e44^X#wm%*Y+~&bve8f zsmw{CAcObqD$XSuLHzZVrLGBat_-<9dX>hV41QYtvaZDMS$oyVKKWiKy0xfP+IlVq z)=P$WZSxn$2fHsGTVqav-G4urC0Y~uyXUEw*JZ?T-{dxxWXVdnLZdEjUs47hJG)L( z?h(Rfth;8IIex==W-3$s&;#xsxtg)HCXVwr(!Jd$-aw+ovY6&@6lfXkKNPJbjvvt7 zR8yk*3|n)()~63-BR9D>TuaBr@J!KP->ruL@OJW5mvtr5W}!+|UJ}JUvu7^$+$o3H zp%&(?_G+~KwzP+A3DGAU6TEIe3SgX9aw*ol0iC39v|N5g@MhocZZRkHbcVhSxm8$c zKalkX`EmbhM|f=o zTn_RNaZl?)8M|^z^h8#XOWw+CnkflFqq9tRMs^@GUH`mCkJ&M!w<3A;`#Pf8{eEX= zTF)_M%>b5m*>SWknLlv5s0>JU0v6w@tI*Ja3cS(n@3eP|Tb8GB(| zvOaxL+m?&;LaJ%P@WNfl`C50UTZ<8&ke&6Rd_&AtOP`+K9?=bV1*lz$h&kOR?;)-^ z?k?EepS^vsv=$ic_y1uX_-jg>?^Ou2Q=qi2j&8 z_>0sFJ4r9jq#1DGDO&cYJNMQB70HcXzPAgqEQR`-9u*>ikCu;)hQz{m!%ha?hdD6q z>uSl(#zy#F?x~&SUILoWhnj2o><|~8lS??xi$&|F&z`HQ2G95FjL3&#w7$ELJkShpq)5M+i`vn~Yct_FlkM2{zy0J;Qsr2Hr4^_E2l|B1xwj86P(e++C5aYP8vls1E8+KV8fR7w4HDp9r7N z>zk`KpT=vTLh|y##~v-hAiNMqwAB2fhU4^Z4cxN87JGSc{CYAeu9&zhif z%QM#>4bxH%3=|HbtqHsL)&b>Ft*9lC*(z3SZVXN z*ZFE=;2#rXI(e85m)joB{}$Z8n4k3iCzxu=S49mZQcWmnSG~T_f>#vfgSTXWp1o_Z!xj)S|wmZ zi@QcbWRUGV=&DTkVE5-J#T7+#K+USZ);pUrlv(s7jVj z7F|8ydsqys8OTOw+t$G+;pP+T^+}*n_|)X1#UJENrYS8g>;geq^V?rek`OP8(dZ}N zX*8lJd+fPG1&AkZNXxI)LfUa(4Nn)MKPrUYFSC%}UQ$PuWKy>m$b|B=(0x zbCbl(82b+Ft$3&-maQAAth?mtZWf}0Xa9(253isDQ*Z0ypLRkTzM@QRpNlLvG*Z)u zIYn!Dw6509LFkgDQ)Bda3f*o##h+c$& z#suoQ>yYNX$D$3I0$Bfk()S8OGDOKg&dTW{frsL;iS5MvOQ$%0{RCGJ+V3E<=TypF zSQxZfKIJZePZ*w|=_d8Sz5V$QN<3`gN26x;ycP@ooyoHCA+rR!#&+7@(;EO8we05I z;(Ykg&We;@W?eArXCYSitrDud0_^jB_^}d|ywA%w4iqt6X13PzLl%<^I~eyU&E;X~K$3Qq$L%oSQWN;f`;?CH0Mp`Hq4_b4~H$z2$?#c$>w&Y>hl zt@#hVe|8UD8qmm_bs+Muo0Wfs+I0biX!q&Yay978grAy!p8$S-cH%7XWGOzm~=>Zp!_)lC7qqu*g^E=x~}fi5?iW(uY+XCX+%aRon!W_9#}(k zpL(8(I2FULkY_FjLOMaFBmb`O>7BSVQ0(Ofh z5Iz6$Zi8Q+@O81&Sp2w46g%#;{ra@K9opl1N*1v849j{(+HM*nfl$MQXQ+Dm+Zzufc4>sRT`_%^0lJ6|uQdXe- z_v3nshrXk@zMkilFB*aG)sDh+<3cbx#UjBYOONj`XNgjd4j{FZ#3Os05|M$u5U=9O zCVJ>?nR@Og8RU<3Jadf!WcXU|LH;EsoOYXw*(9M5Jo5Jl(bNtAyS+!s->h*Ip1Qr| zInif%`CEojcPSI9_!^8Gh`B0D;KcV=$vv>PFRVGxw*V#-6Y?$v)8g1r9^uhTZA9O8 zMlr^RjJVi$wwr%p$7h5R9Q(U|!vU)L#jGfIP@5@cqp)Da@_peU>tD!Vogu|=;4`tG zR9f(_{1nA98pbb==QIH2T;G)nt~`{=RUeVhBtqmqUoQHEs)3X)Y+W7S1)ixN@8*v& zVNo4I^YpbFK3r_uTP}TJ*p8ldZ!g6QW@}wSL!8; zV}o$5Z+p=uV*+TOUcB}=hYG9wNxG!3*a7zMOlGG}7d+u; zawBE868_lR`Z)+aESyjwN4fRDO|irNomSPr(tj|vXj?M6FP*~2zvnIZbu+(Zy`6%} z#tz;-VL*+a#J2JGjkdtgl7NZtQe-rkz#4IQj_^~AP@J=#NrIKtmD$C;@1a%5{OrgQ z12(xis%#`Xg!t#SI0AJN!6@5QKUbR--@eHF(KLDiae1omk2w5*@Nw;H3ZW(Z1C1>V z__hYn!>{tf7ednz6}k4Yc7_19+UW0JUL@)+VW(}Uq#l8euuALx1#!YB{P^=*s#l9I zss+o{vn4`x#2=w;)#CVC?Gn`&vk%a4u4=*ZY79i)x_bRn8&PlXy;{YW76ZON<_vnB z6X6M&^k}!I82&YIGOv%W3S_jeekfke1fE#kwcV8B*rV0vfvkQB@TCXZj=jr37OENw z$yf~2P4bw1Dy)Uwr~gVi3Zx?gvcX7aq9{(Mt_;f9Y62QAa+xDt5e&3_x%0+A6jL?( z_gat%o`jI2)~B!ea4v}J9mmfd_=;on4!zn=U^_PKqjI7WqU79Wz7TmR?tk?bI=#s- z(JnvZ<3WNavNK^)1fL{d^w5w0r$^xCZP={E@EpT;qQ7FFKLb4W5cu`N z^>%p*taxMgVzOZw2x(@rrN(x{-khp18D?fY+P|qTdV2_6FwvX(dNTvmpZV8kxYJ{; zal2(FVxD^<=Hkm)pI{`IBX&=4*EXE8=Xh4Ztyeqgyu!^Z)3P z3M>S=YUMlqyIFC-dzmSjm3budYoZyYg`v2khZAq=GhoXE)sg}{j0Su3%eSmzP)`DD z%&XZ|bl#fL!9%+Pf)8`LR5@25q5j};Q5ilWKUXczO^t>0jZNi-r<4bp=yk7=Dd5B- zl3JFF_bEwF+V3s3(mz1)_f2Qm2%qW`MhlnB2%bSg_HI!fi7ptClWjL4_J`;Y`>$e; zYk-36vPdH4@~mS%j29yXG0(4kF>!)(=!V@L!&Cdsz$0oon}?W#47d1pR{7U~9{HH+ z-IZQ6?HZ%xutmI2*_~@Odm11wj9YT(RtNIsEI#koO^-EtR0AXko_R&a#tjFN_wd*u zU$r%kji@KJ-nym@Adlag8ZYW|KolRn^Vp9Qn~sDyyrS-a=)-rG1Maq=?8%u^5HyM8 zH&0en1UEv2#`&u(cQcX2I71p~&jOmdGfe4zt_-Rdo)5GVJgY-#3knaGMX}qTVuS2p z67b7k6WG3^7Hs^Lz3Lh%@qMRid)@9XFl}vL9X2F*e2KM27M}%hVU=LSIW8Tr7%AH zNyhjIk#i^Nc`Ecy2Q)rDeT8$h9I~JI;>me2{KtpQw4gQz=Kmh#%8oCF`35OPSB;%m z_GjWB#$)YpB3{gG*TXs#FmjnK9l_V$hgd+0qxCjs4-oCyuu-E}KLF|eXoAq$R$jF3$gb(MG9I=`F z$VxK#V!x-z;2G*WUEOE;k^`S(NRRxozYf|?A6R;B(G5c>pE??TB_QsE>amjGBuG15 zQZ9|7kr1UBPo2dlw2eLd0_Cm@7+{<;+0W{VjNe>p&kJY7gWB=&ihUz!ji#BUHzWzJ z*#0gm7NWqRqf>AGoaq6HGF`^mgJI3T36HSyG#bxvaM} z_i`uH-Lc%yrCbNXYZ@^BW(`HGRSv&jZUYwSnAu$_b&#umwM`59 zKk63i5Xh)AWL^=$3*iR>dfw8JJb9~KqP1+{>Yln6>+gOcJuiR$%J^oG8olK&t5S+Q zUK`JxPbBh3f)c{ULh8VRA$1icwgQcDdd)jQQEZoLLoUc@g~(*}r3SrnFx`JD=)eJC z+|62I?ifJ4mkTv+3d$A|b~F5$`4&RNQ`Re^m`?CzDMTARZ5q+xd#%)uzEWUV|Dfl4 zs2c|E^D!JJq~7dIqyECHg&4d6Sf@5q=wp56?`1@5*r@rf{@cjeS($1KwG zt@&IbK=6u&URHEHZ6tE8`Pz)-XmRPwAFJ+u1P^)1b@vXUpBj9_?3~#PQT#PhYrK@; zpHsj7qHvHW0=-DT(96Gl8tH~ePX8l6edJJ20uq}PgyK`TSbQH;n%<#|kgR|0?f3X@}h6Mc?F z%jfg6{5V3^Gti}l(CM%pnPg^vgS5Z3)^J`C#~SL<`j)a8z+J1mqw`x1dM~5ac5^}u z_m}%*h`lNT&f(miTIm8L;dza5V2U5-GL#Pg?e2!3)8B;B-}}MhE31+@b}{Vmc30$5 zUITpTD$Vuli}`o{+LZj}p0E%Jd^y_-=6dd-ka7ph*s7hl$;{heD60~b%UODyGuzP6 z;tm5XA|L92u}al)3NhCoUOaMDu?p>%^j7mbCWP7Sj=p*Da0Tphcipd-W9M88h?t3chCE;LxC)GWM{A1|?vz2Tp(fF}{ps;B)_8`F+{}4K*JAI_v82dCeAP5J(q4D_5?$k9uJx1tJT^$|UEuoeF=drXKM6PhWT>s=!Cp^5N-M5Xp z5p5dI^rZT5W7o#fyh8?E5UEF5wYgZ0jGjAWKT&N*7xqq{A9pST<>02NQ!{bU?<>YQ zkWPWO#RyNaSd&4Jw)Sh1Wi9C3@Hems<;59e(npvX3Lsu=#|(+58$O4B$>*&U!ud`q z@10_5K;>NaheNQ3$Ff-$nc@;yDU{b{TrA}eo%I7m3piNB@ zdXgfPNplBwQtGkZr4+?wpyE5rMgs33%j25WgpN=8&*IZNBDlq5&y&M8-Jl_LO!`Su z0SXe+2@cES!*2$L`KclXz=Sq8`*3^=*gmf0IBCU$`7fA1ymx1xuX6{#s%sAuYH}A37Z>UGP3*PEKz<(V@`?tZqcVh0^=;PRWi~u;v#&wl?YwN8T7;Qn*dzqQ=hCT`A0gLx*P9 z)%3dH9@X_LEbBx*tNv9B)c*(lY;w&OoVJIlgGZg4jEQCCZXM&ekijjX>w)Ief7|v8bee*^57ij!@qTuw+61c>o)$*LU zPv%cWlS7-`=+M&mo^L7VQRZ}(-0o50d@;wED04Fr5*ePP)+@h87v*+G$=+hXZ~Oju z*VhapR5;}D`eO`mYQ2>^Lfof7>ExOz;kOd8uU_EVz}ztkf6u?M31awo{_7{(c&lL3 zm$ST=`WgBFdepM)!g!8uJV3T14@47vxH(AOXilB(2yY*elXz^B_UkMO0-kLJQ=e~# zmcrM4&x!xr?0HpkE|D8ey2xaI;(IJ8e_V9jq!Yx(gKtkM(2b)Yw?VD)>F-$V6TCR>jzl4`07B`uvO|@%Itx-|n6OLBZd$q$zmu{7+Sz zjjnuna?Q+ZUbY)n9^Fb_R2Iip6Gz-V*|VX4|2UtzLms#vHBo8awTU9T*Q&Yd@}Z|V zZAYwZH>zG_ycsnog1KwNM%tTlfndQdJ6U#vndmuLiWOl@mHecKqM4c$eM3uG&B_>k zH21z{f1cf$ToOqzT1nN;Js5$yi?#N<-*5FigN`DWH>H67HX*> zj9Dnv%#==Zk!*TDs8F1~P0S14Q1+eOf#-rLc(1(9gE^(MffhRmo%>?s?t_Fc;*mv- z_CmgV=uEi~AXeCg)UJQ0d>u&Sz8%!m=8r8SzP}$Q&Y2TB0>g)U%j1{P@|btem8~yu zzddo~+u07V`xbv`%JeU~l-{vPN6`st@6(d}jhZ0xUBjH&AwtKYYv}oLaR`M6`c3H= zW`m_syUv%j8I;llrjIM@Aer<1iPG*W#Ix>TD(_41Ja?Oe{G}W~%?u|s%HN*g|4TRXbb95zgDlj_;41G^WN2R9xDX7hE87di~e(0Rd<=}0AWmglM37UHN^xokp$HoM5 z?$5bS%~}NT;E>eF>3T?SZ&v@*DvB+R8Z=dWNQao)f0qoVn$Vd4(7u90!|0BIeXPV- zF>tS)m8{~ZfZTU|UwFpn&?P?-tTXWd&m9vj6L?*XP-4z%=tW@CwM)o{0A>mE!{u5uZam2Sp?Mn z8gcU-q}L%~H_ z>U!v2F|_J+*-*>736ILP_wBk+4m4)>xsN<0^rCO(1+`_H@NAlUK%d$GWZb+~e6esD zd?UP$H(3^9snV&aUq5>BiYKM1#ne~O97z{yt7^p3zGiJc_iBN5=al8W(ng@&{5s-f zQHC>_l*gi4--DXX+H#FP1!CuNd3ngL1^-ORTBUh7gge&Ex5m77qyA#4bc@JROlkak zvO8o5dymc5QV|@;6Xzf4JR!zy@Kqs`n}tKTy!0}!zZfUFQ#dZVgNS?(;fZV|Hd`## zWAgT|OAWl0b_qO9^#R|%EcD5$Atz)#|Vgri^9zF=fgDU;$B@rJJL9o%=38Mx{?NVH}<@=p6mywV{;oO zP9=o?*sbAZD#md|!WN`oqG*PXMOsj}9nZf}yQmSDkHwt#BpjsWN00pWwg{`1lexNfjxb!DpvH@xi5Ztfp|ss+vmEE#Js9Qf-j7gHYAjTDI26CHp{ zH-ggcTG67cEgJ(Twh65D!uvqnq7TGR2Zu^qtU@l`vZK?Le7xmy%K7k8ABfN^^xOG^wKlxc$XgQq`?Gc-nFOsj?bB8kltY7c*XqAN)+MR9YPXo9s7ke-#)Jqbb_} zUKs}*M)fViq5xlGll+uuC5{+xbt|4ga#^L25 z-Qx$6LGQ%n8zn6Sx6?}ZO{Z8lmfUDtxvAQVe|;JHJW1pW-=wbFx7TzCJ1;YM`dAfX z?QrGR%cH_5VUCR~l=lNpzh~9kd5_TRntcC#y?_y=dajZg>JaO)HeLN*z5<*OSR{7p znkXVq^Y5I+U05JhZx6Ep3H;s#Nr>(cx!%v5ay$3-;Y)w41&(^>!V2SLo;JY&D-^o% ziE61B(`~hMzepnLZMVr*+9L_>)~TA_S)zXNEa6x?%i(V9PjN7W^E?}}dm&hs<*)`- z=N9(;tIxnXqczz@RP-pQkG8azeFprGTmA0zo={QKayT+}rU$t9oe=RkjPaS|kA;DE z@?a!AYex1m;al%s(vR{e#U9#&&Oog1^J!Emy=&r#B{6GGmFaS&v1NgD$9579+xQ|F zT_TQlqCe2Ia^>Iwd%W=bG|{&@XevuFD~{IM9t}1JB;eZ|JDwxiF?jmr*$g{9F+|~% z9+1A%j7N*<8GAQfpi0r@IuE}%+AG~b>BvIruE!|UJMsP6S_e8ZA*5je<6YMv-g;9P4zZ2_v59U5}%~Q^) z0|zKwjdSJ_MyiSZ^_&&-XtkV`!uQTyd?=A|VtT9-N`=*18bwK%caeqGKs6qs-wpiw z!O~3lF0V#DTKs@_*+TE;w;XKb;&Af;=Omm=ke6H=B<8oOF-vv36rhN7Zd)SqWOr>l zZd4IDdfNKiOte~>xcK7RSlwOBC`h9EUMS;da8mHs8ry|oC}h~`de0d6DQ;k6(K>8n z^NWMJxfD}p#sw~Gi=$Z!%iYt4rPwIpXQ8xG>VM}ZB^j#mTHXXuiqG3Nt9c4LM$c$( z$?+pGn%&0DHp1hweue;RhzUWM1Y?;E}nhEkooc+{>bVa;%S*R9p6USOlBmJK;KE z9fM+MX7eA{s8$V5rxiPv5s>v?-OTIP#t~ZUU|jL+h_>$118kJ?WzP|U_s(5l5%e#A z9Ur~0QfNCzFg6;uqU{nD-9e z-@JF@z2GP$e(i{Vd7uElQF@%N(OrkHI$f3bbEQV%$pLis^x++Fs67@rmBJ1Hg%Jvx})L5Cz& zZW%AUxBu_G9o{SaS1tVwR^9iMkz?pB?lQyPWYa`_iT-AJh3 z-LI@juxP^T?&~dFHibxwE6;J!tw$r$i^TY;FZv@wN%Z$0zvYYb@bnUXqbzIc3|AwSA& zAr)SzuvvTG7e^-1D#1Uo zS>qOk@B8 zano%jA0gCQ^>s=7Jq_v9Jy+2MmK*rCNuLOVf*|@BATU`M-HBxj(f`Lq#!DK>rtv&Mi zSxwIr))M9p9gs1{&(Dim7}SfQKgSxBM9&oC``veyg`SZ>Z|XknU6a5u6f5P@>VVt6+xX*LO z+kYk#tFp*P9{GrIR)ZUFda@823C2zgjr#Omud}Z`tLk2!dh2ID$zs7S{2gm&gF8Z;?2j=2)L)hO_>!>bo z5YSTXSulzbM03iDQp`dWq{;=+m#Vi+@%k(O*Nj3!C}4bt)2z4x^WN6=RMHuO@yzC< z{04$Z^6#QyoBtrLv2YVne_e}{?^UYPTYiF{#WVR$-OYG#w^F{fQ8KRjB<~F21TX6D z%k!kkYRtFmyx#TEN}RFht5T4-5R&~o*DNGRP4aJ{zI*((B|ckWM63N&9QB_+Jy;i< zkIM$v-roF~0YY|Hx|H6Cpo|;$i@CE~acV(}sG(aoOtpNcO5*qo_2w0uLVxS9dN`|K z?hO(s8m`6coDx8C-Fk*Id**PD(lPsCrhCBaq@_PrC63-{zDjLBn}TT*y7e0^Qt=Uz zz1>SWLYKS4Jf!TNhMRVL1*rCv!>;1$sIa)*=$a3yThe+HlN{*72Bpk!Mub#l5s^=H z?GUq4oHQk=lw;ScpIc^tue;W{#)+Ya>DP+iR8`@8$)FXj{A!SSAVjm582?{H-wHKT zk&%8>WR)D(FvWv!c8BVJ7e%J#BTWaY(s87&O#O5I4!k&h>KbJQF;5VDS zK9&2q4+<4^3U?EAHrN-)Y3!ei?U(QDq1GnBr0cCJfzDwNdvsCuu}uxue%j84wi@&vM|O%?mlAq@Wvfj#6M&kU$jkv& zlqgGkFX!?Wblf#}R!|vMc~d9+`SK}#)L3^g@QdyczIi`-F@VUc{rkt##K=YrmFoGQ zx=vY#*K-BO^~ozS^ZMCl-7#?_aog?4YqxY>H(r5@csSfe?k8jQ6wktw z9`wj?hr9C+>sM$e_X{68KB2N(Qi*(z#UN-fG0c|}Ix+jN7TbQL&*-&zOgX9^{3-hWfAe-uf8JK-Vk{^rGCX{2 z7=#s^xIzR>!2%&5qQkuS!TLz41T8^f1XkLGYrHJw0LHeV6|92&sUmFxH@?? z{b8OMq0?4c7B?!y{T6J7;o`OU+uLlzK8&{74K1 zOjSI!*{sLg&)3In?-m1JOTVPIV-<8{O#af(EW~v?k1o7SPJ>nR&wcVP1V7e9>fKa1Yd_E*liT+Fk6Dl*fvu(Xl4X?3KKlotq|jZhfxJMxs-0| zrFazH3Jd-6byfiN_SCIW@h#)vXrcBB#eR)x9+QM6n&mXMjPO@vj zZWlc7P_&67v^Q||=%6>g-p>?xipc%+iL#u`9u!A87WcaJ9n-MgvTy3flL)+{>rorX zD}WZo>7)^-gB$cqN!8;8B;S}zyD zgAar6##?BSlj?Dns67)PQt&t2sUrxBZ>PrMY*A!Q#~gG16`^-E8bAK*SQDg&JRIz; z6GJAnlKQ&(b@;JDPf>!*J1p?v&+g@VVjnB!i$iNt@P>Oz(K3B9+#Uy;l zlQ9V}dOQBU=G|Z{_D|t#$d(w2He*@-z)+59CPjGq-xp&aMY0R#f`Z6ER5Izs>ryN< zH^-KoO6Ur|#m<%!{4q&EIki;cyr*@7uwozZho22U8D-xR^G3wYTikJR_-;B&?cS65 z_)^s&+ml1Yc-Y<7vLcd!8S`wJ?`+>9^c!PqT{*jvZ&!GZaQ`Mw3X$_$4!n(@y4n0? zG2lU(*=g!MJwy(5-Nj;W$@f^%qD0!rjF=x7MzUKBl5my1O1Z+@CV1KyZ1P}O9If*o zC_EgWh@~@11{(d-m4lcTHx3@qW>xSBdrLl-xu_e`*GP z7DA`wk{$=u1@&F?U4#!^##U?V7ddI|>f~u9-*@ntQ)x}KMI4Rnw-rtG%ECv!I-~g) z&d{9P<07B98x1CL{b(}(i+4pFx0(Iw2G7puSv-318H()hFa;b-##Vbm)v2Od;KF+6 zaesoxYpF%)Cwk;9K0cSE-Pu`*^Etxby(I~vN2Uw(TeTFV`$-9BndKF60<)>M?gc^g z>d?XgE27SO_+RVV9=8tcC~{ehfzZ{^|5(N;#J-}~C-VDaen(s{HatciEr6zNSg&wu z{Kl`fgKl=JI>05fznny7HrniB3B5X&fhAuqjFcQw~p`)u)9Ld3NXLo7&XI$AJ2Y64{b?G1h;b zZ(-dkj;!3QtD`IevB-RoX_{>&E=Z|TP)++EPPOby$0u1hzNL`F9hQtk#2mk;#fhT_ zYGhru9fDl6jXeZ`4cLAPWqsd@No zLWLa!F^(_`5OwL0*6_*B$RNCx73-WloQqAD>s44y1kt`#PI1Ab&MTZ z`%0!;jAVYtp*QNX$QYTPtO)3?_Zfkckm>kG|u5kGLmNv8mYN z%9k^bu=4V#x%#v?qF2=`bZ<(-o*TRG?yGnN-<|(%ks`%Vy4lP(LA7M;dnuNVc2@)T zTzQnv&`tDfj@)?@bCU4kP%xjp)R6*GNe{KSmv^Je(>LdPuI=EDf-&S4(oZ0pzjGp6 zjUCw?VlvkzjetbiFXh17#kfq_ywibP0BIjTaN@M(BJQ(8Rzcv6XZKO$aT31l#pFXP zb%gGM%ffAldCUslJs&<0L&=X;m$I6=Nz>T=l-6shX9*Cz{dSnSSPc0@+h42PB;lf( zJF`_LCAhG#+T@U}AS(HOzP0B%IZ48%ry0WU{I`zFoK{MlFN*@7sc{yCJCE?c$X)-e z3dB)ZQ2K+2tGRgblUmg6zOet^zc1Ok-(J}W{MM6ZhSt%C=${QU=@ESjz3=uEV>(4x zXno-4{`Yopv2X`*eGx~wkAD@HehI-G2Q&HB15@CcZy}%6HXl0kc)mfK$itfa#Ij4k z=nZy_mE$2Jc-^Ltz20BXO~V?x>{Bb8zSux$NIi?_#|_mV^pn(#!D5NIN~wKyKrdgo zWt2+HKiWs`XGUaTlZiLOafj1jbXqi^P=_D2YC2w;A@oJzs~XF??|i{o;X;iPvHoTR zB!50btiQi~SE`!gt?=sAaF3P*ab!n5m!$JGADaev@tl`QxPQa2U_a4c_!=)s+p#Ae=r8kyJc|v(%C)OaWbxw2_V^XLWA9S& z(42FnWE@e4`G4gZ{qJ+h4oK$h;Uex{4YGOAU ziG}8x^O#fi|8VIgPD>T=b0xs5Pj^{<7ylnF{WHphyE1%<&_r6`*Cl)T-}fp{Z6K1*Q#&)3k*zN%H<#{Rqum&pfS{`b8!`=8}avbw-iM+Ka=od6711d~F!2(E&acGRlM zM-Y#D&!zs!;lKYSx5mABy7C$5x%>)Gs&s{^AeR@_;k0Ol+mWn`e*)(nsIXz22!j9p zANk^ESz4ssfaTRe$wt$suz&4%?(+m1RAhR;bcx^~4IX&n4*9wN-G8ZC`|{l_4^U*& zVv9R+6ZCZ?KQ4cuL(WE@wqxW!LFUqNp?`~U|J{Gq=-|y8l%5bSQ6-x`bRECYELHUV z!+<7wt|k2Q`U37b#UwK7y#KD3)K||xBI*XV4&QZGJ)Zvey{ZLK zi2k^Kv&oYD?;*IQ#cN=kX^u;;@faJ5@}uTUzH`%eIurX8Q2ewY z^c58)gPfLSL$DOUZ_;hdPNqa#QBUb-W^aTgW{4I;~-MyxG zneBSTxm_ISp%ks|!sIaQ7CdA7g`yaHkolgI=4D5h>ScGUhmXMiE4NB`Y>KhzaV6a} z%!XW@kGQ`fe5w^zyyxx{eg9w6K@^9~iM&GZ(aGc^qwuD(@0auaVoVn1aQzny^nX3UM0%__xV$v# z3L!m*ihXMsQNlasUBM&ckaM8d;>(Ewyi4VlSX$36H1+qDvme_8cxK#ja}>DgTF9ecTO#fgR{4YPgLOO(B7&~CW@ynj#{o~${t4J; z85d-2^9Jja&n{Et)1uCv2G&%9OX-!e*Rg%W9bf&~W+?P+7pfECH;+RbJ7dTNKCi4Mit_c4UU5R67&<^R4gP zO{PVZX*Fvy#PyZk*(W7#PO5AwX&O|O3ZvO!m0M&PjOe*u%K;8DWBe+AUsCJLF7&u; za!*L>1SAz4Vw_~p$1x3aAGP1pBAJi#Oj*QzN|Kz?OJ3Up{k)y%Rw*r#x2-f{k(>aB zMCIkuAU}}pNO<*dis0Y2?QT52cLIzl3v!n9BA`I>6}RGPI>f@mUr=#if|yV8kFw+> zLEO+0qr-gk$RnxaFd1Dj~ z#_jg$UNx|Z9@gJ*WkJ>Z%2Rs?{c>=2-<|JIYr*$GgXx4aD=LpX&G1cP6h@Q(w5ur8 zfnGrDEKfhdbGUw8F@$OY7wJ<+UCA%PnW-ab%nO3(#lIwmGxHoIof)48Vum+xv$NbU zw>&l!y0ELE;^{EV#pg^oT&)M+hS=s6X?FC({WwR%zabEu%H{RER}ZoB=8Rv{*^!HI z359>u5ZLpc8ZOtWhilKvI{)qAKoU;r`)$q*!OMn?Cvi0Opl2F>AT*5wt^6!1B{2*E z_ce-H-^e;(Fg>zdy@wNVH1^iL_&5kZ8l05ksq2WmLVo2mVt$tL+IvTo;J3<7w0zRb zFvk&^fnCFUxd>hNRI3dh1hOnN)nQ!&4O&i%J6T*v!~`*A)(^tp!S0jJ_ek)4e!pU$ zI}aM+N~7^;8pM+VjCu(+mH6p_v?l%E+^Biq9Zu`*L0CVVSvVP24g~O?BF>iweNkNR zR+Ah83)7L3qlZi3>FLanhg7_1`=@1eEb+TC3yp1fduy$RSMT$7zUpG zM5rT72`1Aoy>sF(+|V9Wg(@FSxI&5eNT2>lBQ{v{uYe&>%x)lg*Uias0A?vFv_r1djPF z_)dn0m~StO`0dde2HflvJ;o6SHLLwEehUjDN$pGR8eK#1?1aXk_v$++e6e3vUs((V zo2=1^ertnmtuDxC0Uhq80O-u+i+fAOXz*MBoTlnPo zgb5aH)#&_7^cPIRa&(rx>mW($s<%LaJN{HL!SZIB3{8(ewaCpKff2!AEz2MFSW}2a zkzVR6th_gkiYK*$(y5;=)ZI^TUmwfhmoY*wu3g1b^SK$wvxn1d1f20&#)A{C=7Na7 z#`UJ{iykP1qG%j_`>I9o zyzJ!LKT=%KgR5yj9*c5Q5P7~;j9&;2=!}Zw*-~t2p^Ydq?MUa&|54X z8)fu?^A9lF{1B36fKpk_|XJ%bsI34I-=+LQUpU@WiXwRu@G9 zbij>ggSvYVLS6op4&12*A9DV;0Tr~!_``C$zUer4TlW6BTV4*=WjHV$vER!+m|(dN z#vty|5NoSPW?D%Vz2R8IA)9)QqA&osq^vmb>@LVK^=J+WVG(EFkYEJzT-Y=E5 zrxEjNpj($?+$OQF``X6%{CYpcNx$xOv1q}cRu}5+-q4`5Q=Gq5^hZF@PWSS6r#9^8 zQ@FV%NAR>8hkm@HoPgTwO~DXF8@OR{z`f%y3zENru33E@0dMMdndFoPOn%trV?+uq zY9rD+qo^jJlv3>_rCbVBOC6g(t3%w!a6-}U%Q$2kRrhXJq+znc@0QnU9)kUv5-FBs z55=!5OLu(@z^x1``N4c{pvGRRaqpE2$T<#uN(dzQy=`%U$HTc%QQe{P593|%`Ru$% z7ok5lx8pS7>E}Vb@5n1xDm!86*6F7YkM-iPuQd{1z7qRSyaouQM1}x16X> z<>svFA!?LqXpz6_V}r#csLxkz5%Zpt_S7T)ZWvDTwxJQ~fi&M?3DH>|B)ID#)A2iP z;CAAJZi`DFG@B*G1ia!vmmGt-nY6mWX(2$eg0~NEZl%$kCw!e&4;=rohIhdn!)Y0< z8v~GaoZ&dU=0IzylKq8Zoxt(-;7A;MKhdx02@2m~Lz#0M?CmW*P$bW#Ja?uK{~AQ% znipA7mMFh#;`LtG_sJ_IaG2n5)J-HQRMDfh5QDk};{kAC7|FSGz8}XqxtD(LWkj-v zq0q%|0P@=}Ql%F5VJze6x$u-9t>03ZEY|LUYaC*_8Xn!)P#D z5?b9OLVeJ9vhm<93nKrKIoi~$i115v$Lz~i=mYsMUOoLiOsK$6`<=)N!J!D;KR7ox z2&D<=-7Zfe55;;!bdBIzYTjeeojx@H#ffdb9`ZbB@x5k}x_K9@#*n(|DSNTtH;J_9 zHa_&m(!hp~ya%W+>zA#3=*IIt8O3`DzN@~mhs>yb8?cMMwmMAn9d zSwD&YW5E2nN-?2}x!~Nbmh;oy*9ZL*J4#Jx5Dr`$c2shQ#bC5{Pa-FNXsz8x8^Tsyn4d}XSjF>vVfmi+&MKXl${kqR=29rW0 z=sc&dVcz`~E;XF;*-RnyJFdZE6Q+-#_47!-{5fA}oecBeRp*1t-~Rixzx4%(U75y9 zQ@-$4WM=46Vlcs%!1VO5!=Nne$CHJ{7>H;zpbCBb7F@p#CivS0!NTZyUft?QFbMm} zM@iJrf>|D;u~Az%-+DRV+tXkW>T1bMJ?ez1mx44L*q+18$&Z|#1tBmXQ02bz${jQ> z+d67^#Dd8cP4}AERQULzKW1pSxKFWlH+p#5C^4PBweYU;_P}!9g zlUu#`#l4~!!zMD+6zP!=%1ZQc+0>^t`Fdb&+}qLS>2ILP8~iP;*9*6z6{ALF?6B@5 zdkW(XA;KSVGV$D_PPqR5_{+zhz4*Sv;jrG`El3^WT$}dl0cDpy3y<%eI4(Y`*Pj<25Day%%4j+42M=GlxabGF2L@(odY~_kd4PMV12o3Y(v!)H zpo)=piSiw46)j-bE8?lMcvXp`i8B76l5u6P>^ zqZSaU3}5gg@4~DqI-Zw*twGi>=cm$aVqT)V+|K6E0r$(574b8ITgX1l{FS{M=5Q_Qhr7`)B_$t2d4i|;qEx#2aX*&Y zo}blF7Dee6O#?5|nxW}>>C~l%ZCI(-X3Wi61kp!326m-%gLL;`S_*YL+Wc7>rCFV^)SN(5)n{N?CIND7#zq}UpU=d6kyPl`p*AGXAcw^KXdnTte9 zI&}vmBx|tg`w_Wyej6!#<^v!y70s|j(S(NwovQS^mcS#_IL-KXJ51`_Q0nPw#yS`K zC6lPB(G{-M_Z!>&V1%T8r?>ZlyI_^`8xkvumRl(L^r9QyMcDVYjSWCbP=3|RYjo&Y zm)Ex|yBc8qeCx&YhGU?f(|}Ft>5#F#G~-z`3`j5Sr7n?6l&tsp3gcl>l;_oE^Y}QS z8&l{sw6SgjgR&^JdX^nc*vaRS*hawi9u~f7Q-Q5WC3){weuKeHo}|2hHt1vguHv}a z4D&Jzp*cacNclkCWgejkxTXJI+qY03Q$!tFwD4d@&n}6dKI_#D?Ma6+UUd_k?5mZL zqy1EM8>%7rna-!jle$xrO(4;TtbQT>Cz z#(U1I`@cHhM*F4Wvd_J;9C2gp^rq2-lcOn#_FI_MrV!T<03 z(4bNV?+(eo7N#7B>(vFS=9n5;n>dRIZZ!ZOy4LqYi_i=1SvAS+AxG48fmB&8!*J#P zlZa~dI{5zJ+hQ0G9jZBdAd=zc7zF7_B)7b&$9jp%aw6A7P_(qnpZFeDl>VaacIAaj z*jm{A(bX&l^o@#vRoN258@-eBUY6rVaO`3L}N+j|!_>Akl#9={;Y3${gnV*jqda>etqbf+|MBprJ={Vy0)dVigJ+K~VS zYF=Mkb?m|Nd{@3lBoF!)I=!so+5l1Gk{3<22C(%N%UchPc~PB4MeaTKMmV{4;*`f$ zKaL6VBM7s6$g??JUm~>y#9~j3IdS!4g`M`>Z7M{rbVa(ztQrG)@AX=e#@QI3v(EL~ z%n?MPQ`t>Zw}ya@LtPrZc>f-~82^tjHhzc}}0#&)6F zZ7|Nf9;m$~iXQrP)Tkb7fko!?WYLM0nC{02Z~QAU3RQ{1%*dG*O-u)eC z0*HRo8LLr_((NeV;0Vc+wMc@K3-?Uwh(6tOvDBMys-wWrk#C6VSQ74c>n%D*TyJ1u zondV30nTDB_j1LF{u;|8HttVcXeLEWXeghS^zrC+&7_elJ{oZJC)-PL#P+vtC%P#Y za^k9uI!|Wf)@iRJt%MGNYKHn^%8NK?c5~Lys7c0Q?ek%ZL_bU7qTBaFbT0U01DU0N zMIwa1dp5L8@D`zs`Bm4-4>b;cWp?pX$ zqf%;qu^x7rEi8yw48X6m>>gDMyyz5jDsu|4zKESvUaMK|hhMA0jSJ$O=m}d);3%R( zBew2?FB4w?&8eg7FPh1b{G`1l)xH6c2|oP(fod1Lkjfg6uO&k(lI?*geHch`>Q18$ z6*%Kh_5Gy%gzhu)G*_Q}Csf@L^*OlK3uiye(HgV=0Tt(5tCzC9pxvR@z`IZf(f)hn zS*|i6HKyoUAtJw1>`fZk4-~^r!y8TU)1-( z$LsIEDpPmk&I6l2*(te@>bURoAj=^rH2FxPh^fHl^#$X*Rq2S_`9Zn_qJC?aTEXl^ zmV$4(+b4Nm9E4FFzZz0^4b)$?P&Os_tG)57YVL~MsCFe+Jh8bK^m(p5BIE1C=S|f7 zO=v%XwU9)j`*t0yB~4vbm8^y>i8HUBRT4g+oMOAl!6sl833OTgN1S_HizSZW6?iCl zaB(NJ4-S|9ThVCB#}|8EygjwB0te3ye=Se!gQZKBH-;Y-fTJqE9dG6zI8OX6hI36I zHmNq^c%cXMM2EiTomdA$bV}8}Pf9_^dlUTQGo=Ju5Q?VWc%VC#s|b zr251U@4ZZeI7v#phx#kPIH>x!-p4Ua#q-#+{sA3&UnIUosW1d(C(>i7XM1qsfTHk| zhFwVN%zH8`<01I>O*x~upE&Qwb}*31u^>yAGY5wo8)03EcAkuO6pLuM6{{R(LjyW> z$x3>I(0|~jnZc1x97-Re?YM^(T?-UBk^OERUp*eJvO;?gq;@&5-@MC>oNv4R*)eK@ z&9QF*0b~RCg!G%w)JuG5lYMhy(XbzeeK$9SmYQ)~ud0b73qR_T7k(8$(*%=q_8-oC zC(eVmYp-qB37)fA*2WBLGZd3Txijkfv3{>M+3{xrXl<8wPV7!Uct?Ets!YKWt>%3K{KZsJ+0Agfyj>hb~tYb4A zm-Jv!jqCyWz|8A*Dr|^S&Ms*H`XDmXQkbEm7mm`f&~jumqT7#ItsMgfp;sl`+2l$fQ*QvE&byD{DZ-8KAu4QEFo`im8L-3&eY!}P&~|H>E$X78_Wr)-3<(}Vrr z5ew?+QZrf49R`{m``%*0_gy_kI~Vqo&=0p~=@|3WL#T$1kACX_Y(^J51`zqnm%FTr zD<2Jj9OH;hwsr$9np2HVY~Vz-)lRNvV%>0~c>K)XN4>D|vnuTI7(a58o;|vAVFeIJe+fCnOKZpirntImaKPeVY#@KdFh= z;u^tP>@L+zX(^BaIXAx$dGKMsR5D5q66chMt@!~T2H>Q8Tj~%y6*}Ti{q(PJ59rHq zQ}8qnV1@`sH-5sm;uslsTVi||9^||3UMKW~eW~sb54!Q8-@Z3nJ$U=zAMa19KG$|& zNuH{0YNkfFP=spcjbb>&F%C-RjE>ebY{;7RXJ{K`AM6kY$qaO9nQ~dHiMg6#B15KUKsRsdny^c4uTS4A(SWkKy!3;nSrSR68Th&Pa5FiYvy^K=Y#Ox%g&yo zfB~IQZbY#vrQk@{vA*+l9G@Mecz)WA2Zdf5VvgSIg+^X+RI7L_OR2TvE#E5pt;77Nll4sxrD#7K=7|@nuV{hl8%AGGE)ksh@}WdwohGo8b6KPyf}_#ItGnu-)n zxlyN%u&*4kPcWPLKzYEj3xZVl(g=HUqU^UI|YEq$r;8WbdIwF7)&_dZ&kh>Vt?HT~-rZ z7CfYuuhwL5AX=#BhjG6M5TzE~qT$mqJ$>RU{Mj zFHk+1J{w5Y19>w41kV`dVP-=`*8kyo?p7_X@cQKhZ4t_z46;f1+RZ^)x|2dEPU?c- zp_&1xyf5|RQB(t-3Ewxp@I@H)y8OA>;6DiW1+;f4=ZkQsbe^C}kq~MM_RaJ>H3TFn zoox2VGB~hXkH?R83nZ^K{+2QBhbJcsFY`Ba9<$m`Jx#EZnk0q$eA^WrRZ8em>AFXzw>PY!-tNFt@=Vpkjz7N zvy2*9(rFgao;4wS52BYocZ#AV%Os=d+l{d6*r(~G8$_;GPVB#LC)eP)VDuHGuznZ~ z{uyV=Qv!#aKP8V#h#Hr*nFP{ zqlve|j#LUEHAxW&o=YS zHqmzw-lM-!6%X1v2dR&%1%tYTI(O?G5u`Oob@AY(WR?fnJEu z%{E0(>tXA%xvw{!AUXi$fm9y`fl~~3zKf~B5x3X;-6xIa-G^kO&a8Sd37(NIbYYri}N!{1jf4`7t zMLzl~Q%et;0M%$5W6>S~<5}zHdi1}D_cHpvc(WTmU)QMqB9;#somb^E$yt!&8A%Sd z`7sFLN)U*!Ex|{)Xt?Q`7T^_C`~*F&11awXn)H8dc#b}F;j=LZ8uzEq{z~5nl9RsO z=GlXotx4|M5iO$bWZLiG<6H*Z)l`~2p<|fc;AK_EYid+67s%PnHw?o?x^LbHbrSsV z;L}V@BB-}xfK(CAOtP-OTYFRMD(-Ar)hjms4Vis6+6N`OfmxM>VK-L|2!)&uzeI2w zjOeTHoy{k5;4T_ud+qMVij^7P?ht*GT*0fcb>D|Tm`~xB*+*AgYad^ca77gTJjkEM z|DC8q?#b*^&91}Dr8w zWP0vlCf<0>f1JFM0VpGcPZgt7qY)5&-e5nIMsBLU5y-uJ1P8Y$82q+QjVD#e- zFID|+kT}yFqn^}{nfSlVx)Pk}jwkiLDGFsU52sql9Eu^F^`hTaMY`4WzwG~+n^O5dnKM@2-3MkEfg3lFnHM7{bQep_<sNMOcy--g6#ao*I$9IJOkDb)Pdl+-4pDc4fu{?WkJ#} zE~KWZXh#=V3ohn^;o-!(aOZLWuh$wkx<@K*aWZR!+}d|?J(2@BO>C@Bo0k{ae|c`t z;qw8e{XXR(R}EU)h5&I<^bF?X(he1sl^{Ir+Bz<@}Wy6U${nN2EdD! z>v-Q<9p-=4amw^9k(2vj=s7L_07Tcgi+?8gMRZ5`|5*~g9_2%ivUA?Y1COD=<7mP^ zaaH*pRy-?$!VGlX=nU%NflZ-(LRTNK7w)3>|16Atf0UNhb?yb5QvI_>r`vFsH%Dl~ zI}!AQ%>1Y?Zw-9n&NfiG)Q2_ieB$sU<_9{Z!EV{k8aS2FY4Aopkg6`ucup%hgKclkpy?~P{QZvSF;f6Py?o~ zKmXhvRt|~k1$Hlq-1+ekj+ke|Ww1d`V@}QU0oU(r4;vC({r}z9IU7&@ele2-?WJBl zp+udh-ox%n${GV{l*9ByX_-B=ayVQo_(1r!D$J?;Mo2JQRhF2`-G=`rY!*8aIraZM z5`)sYnn0vek^Bu!Km6fp{FL9k8|{vy&kL4qg0WB1>6gp~;Az%Jg~l2_bXsHYV&R8k z=m{QgRy;=3hay!j-rW#H6^ZN*mWcfYq`0B%lBXacvMzQmo(IvgPG+5`tpoF0XNP|k z55Pi~)AcebCUnnSkfxaHBW%p)dvJ(W!|9?1Q#Nus6mgR0)fuXf5HlU4?IJa)qR_Gy zH+1R`R9F08WW8xPmR;1xjbxtZc}^)IiHfY9&_Jp?ky5FUN(d=qGG!=2B9fUhlzC=f z2$4*gLz1Bkp_G|--|zc8_w(WPWgqS1>f}1lb5Cpi*YCec`uB$#h;`w=W?*3UkKyWd59E4d(M0028n0 zlFc0DpvE+)ujg5fgP40igzw-+47Xi!+*Z4xU~I0p;Uoq3ojpBdu*`{?7x}jhHrK*A z!Ma}O!EQJ!mXYX0IFK_RtwTf#I4A->*PpL`x`r)dNAA*_bD@4SrS;ad4tVoNk*NGy za9j9zfOG&CI@ipymQUgdio5q#C8f8)zVMKgDtbO-@~3h2)X#2U<1}UZER~H<=K5UN z@EZpGl05#DoCa_`keiV8H3=LG463&feYpH`PK4Dl4oYUDD0AfeU3j{Clu5Zt5)oid z;FvPWZ(d;HittE;7cO6DXsmeA^(<=>_sg}=r}aIsqNx*CkF)eq_XwcqoUB82uUOGV z#;{?J9e1#|lHNN(PEq8&%kJyJA0Ob)o~|LyPHH>fiDm4#taL`Ds=S*VS*xeCn--bCp5P z>F#XEpkV9ONtrfynGkyU-Fg=cci7n&xG^HNk0r`ye)Pb;zG^Su8!h-*xC*o6H9oY( zYy0nO((mBRU8*96woZr)Pm(uZ>irj<>XIITJNWGJw(puUe;okxBR zfhE=KuCI5qv3pV23LmLQemiLVk^N6T91|X%Dm3qg!NSYt2DDOW%UFiALmmYt&j#_V zs@CJFwrTlP{~Y*p)!d7XCm!DE$W#A#_7<81?KEW9Tj5Uc2c4ADWuU>0a|0R*aQ%;h z9gIh$kY$u$$hcn(@h`vj_Y%>GwNsYgY~zzcsUcfp-&VbYDf5<@MAvE@cwLO1xOO40 zilbgttOJ0K1ic$q%)>X5+I-kn6V$4W zxP0z<3(4*+rvwNcgEJj+bePgR&NoR0Xi0I-DpZ~i1;ZhIw92EA_o4tw6Qp0sv z8KqDrqac&4;CtAFh6>`z|EqLp&zF;vL=9F4b*ArEL4sU?RZe0nhLF|Q-Q@kTiyBC> z&RxgWk6aU;GAUyj+nlS9%*D{K+iK3T107}DP^N+Ew<8?A-r_K|ZGq^G_Ne4GcEF)h zV=bw1!Z9k+8l5R7{7H0GC3J;~5<6Dl;Yjk))m=#plH`19@`QHF+{P!kB~Z9L-1Pw$ zo5y`hq!U3^p06SwaI}Kf*_QBF;dY$5K6dshIWIh=zrsqn902UOLXK?4ui?b?&D(d~ zD+bZPt4}VB=0Vo@{sfQe=lGAB>z&)?!su6oc~E*_H87eU*dwv83+o+itf7#7NYE5t zlvnl$DC@=-Mg$T6GJ`u?Ohg0_S5j-4gV6wvwk{P@>PyCn%IA2;iB7xDnw3sj;S)6b z?ti#Xr3ovT#tEKI6+n-)_)ZiYE`&H;u?CYZ-PozhqW>Y`=2hvYQ71q*96P1p8s%6B zo2Lt3G=vGGo0oa>tI4|j(q@0rqt#AO<~&2kMkjzoLUWG(!_xsJ^s@q9DGjifS?S96 zKg`I9TlScu{%06_zB(2~{HFZ%{GV$O{;GxU*|%)VJl|0H_mnQPIx%FYh&4|4qN7LCGl7WzRafkI zCw&jOpQkrMH@SM`;d@QZUuhgyfReQJOj~{z2s}+3WH^$CwPh8~@-&fpE=9h2PoIzA z#qopc>eWvmpYn5>Lh}nEzZG!wX4Qf~V!(?by=KhA@Nu6u4HI%-kjcArd>D+Jdcu0! zQt^P;5hWQ@cJ%Y+6SE`5e?hREitTY)ujbiDHf4LgIgq`l+3|h%7hoVx#F4W(2_Fla z*Ey&thHihZyP!KoOYvR%XgF7MiTLAq>aYBU->m-O&yL&Uq9V6?&CK86ksoM!hvXgBkDt_ZAj9zy@8fN^3|Ww_NoN&b z(kx_s%2MTtcEF3Y{L=$|v+%Oown3q}9E3O1%~a?RUi!Y9`ql%}u(L5~(Ei~^V90Zn z57wbTZIFz$@+NA;UM+K(k#JR_rAr!P7rKBmeepeW_d1@V4(eSPv%pGT zt|l7vln?hjJm zRC#~kxnn5Y;B30NFqw=?D@&3!33pMM(f5-C$@d*uv9r9c8jnY}N9}q+cqSJUU3*7o zz3~J+-J7LtDVX`%NHAv&;U>B6iyKkTg3T(m4$T<>xKd_!#yHvEa!@u2WQHc?KjSSw(`)X$oBUVt*{CtQp@Az{g)A zNo3vkMqy*T8IlWP->VVdNsE^>TSJZsASYSf!+o^xAaF*Z-#3QvQDyvZn7^e)ztm3; zz_C^kxuPNE8P);%lia_zTCtw_{NO^3)i1DDop>?2uN?v{ zLNrCT=3%F(p9gK1#~?Axkzv@b31k>PUE_(%goLNuT`50^4`ZT_x@HYKMfHb?b{wrI z@!_K0^ud7x1>DITPx{&iXzl(ry@e8Nzq{4!mxdUka-EQR{9rR>_u9|J9D6(PuzWAW zYRHFLw#xbQlepf-nb?08#jEjY{^#H5EC=E3%O!0+Tnn?$r9xbe zB<6VaAE2BzKEzz>0E{M|!msB1hPjs)L_IIGK_AEM!o5R;Hy@(q_r`V&!aUyvp1R)& zL*-TnevrIwVU&Z={LE(bon_V}-|s#7_py5_t-UzjiMdX?hX>84wqL(lPJFPsEmZN2 zE=)rmF5I&uh>W8RzMB|!L8j$bZKYlcK4biSE-zgKg}PL`%o(-8(CR@w54JWeIym)- zm-u}sTpSg+U{MF5Aq_{D&-K7@tHLKIx_D4u#t=X23!-<*P@>*W=Fb-;zf2f*RKdje z4NH_=1ku^^)1TX3z(2Az#`ir5XNlwUWJXUN7)t4~^C(}2@`yY2j3n=`*Jf>XhUj&@ z>yLiSfA$UwZ3$UtIlzyyZG-77TDr07p@607@Yi_8?h@m3TR!xozWAZ&)ee~Y5-9x4 ziumMiK}PMbNvO ziq*ykx|$eV&RDRk)`Rz>fg6|A@-W*!oDWXmMfm#GzkP|b7PfQ<8jX>2 z;?V>8xw6?A7tAxJgEZ-Yd`hv zCgRAEJ?p%MTMb|%IXYD`j%58)zZ=M|{Q8J+ZcD=+ zi$5O1Xa9I~z8><25BWw%*JnsvD{5sk*LuLfRh>?3WS}V`J1K@vEGXPqebxz=UL{^+-gt+z z#5n85{KQeNJZEa}sZOvxa6oF$Vhv6JeJzO+;``<}bNE$U2k2I1-aD}J9z;NliIPW; z%E}Yiy@UtwoBFLbhbN!IG*@2sRt^c2l1eYa)6)U`yQ@}so2#+mkb3u-IU&?vxcB&j z7p?IA^Q%qir`o_R#MQC?moN&GoG1ADa%z@5X{}b)0*8y8k#0OlF`~)|-pGlWo{slL4 z&cFD0sU7IlyBL_Fy3B%)H^MK?1gM|n(DaG-8Z%k#atF}zPjPy z@-HUz-2T$vKj(hHoJdlF;r=*$$b5@Sj6aE2cRC5S5Iv-e^QW)3ZL8pJly26GQARXu zcv1b9=Q!+K3U+pncflPAcW8VYsL`OL-p<339gz3^5xcWlD{kE+7r*-V8*IL1oc~1O zJ@^_WeyF1=!GohEvH$K%LWd(7R>=Axop@hmAfp7Elnm!3+#&S`srt!PvWdXnGFhKj zm4}hnX?kP!DOkM_u-H~o3`*wTESh!_&iy}icSULVQCid%6Rxa6I6E|24w~I~J~)Q% zRipsIj@t{gY`X}L;n@3@0gQEr4vtuhiJ}|7B9@p*-cBWkrJ}gE8%L;h3ePl%A(jd8 zhjh{PFdE2MM^E&F(`7YHZh^w6|5$JPg`+cg?&sS*)5X?sgKNHr!If}^&Bwbq=8NFf z0-w&!$_`KyE4A_*I?`Wd6yF-s~$~04XtCK`)0p zVanNi^m&E^s%uZ<)c(-`BhxQWrkS_mv(JOBb-PKT)^J8kHP&n>Ga~MgdZfpV6b;laUL0 z>EC(T#*4AdmElje21016Ii%lXoWxy)PTw&YYlSrL*O`5=0ioMEuk*kD1lfCJ%shCS zAz!*8{Sd=nNco1ZOl0LijHs;2ZOsmlo-3a=z5WeO6-J*h6Ke!>M(3+W7O(KUaK81n zvuvo?c`4I+x(T9B#0aK$^kBxIFOy*%zrmXJHiL(43oy6rAFw2G{Xw;ZTJyudAq12s z4tKtR*-|IlKkx|;<5_=0!uL4MgO_vcx?!?wZ&5r=9(LxQO)|YIjLHpVOB*+l@fESK zc%`EqOZ^-eD%fAY^ox4I`=d^?5 zPbOXyZE+Ok_D93(Z97~z7^;2K>?7XEZT?quj0<^%F58d%?1ajo$t`;PjUct)8>=bD zgti~mX-g-5E~oYzc8eM0VgZIfwF+(gXpHB|#?F16kijb8N?%Zm3*r*LSFI54L2<|F z7O4W5?affOz0r-g`McHLUlB!zG(fSIa4)<2uhg{}JK)wqKmUvmQb^;JL93`$37oMR z_L!e6hcn(U+)9@`c+7l{$BMTG!X_&&exH*>w=Nvsb75-{Sew64vuFN* z#V-H(n;tg0@K3Esx`Wo$KC6us9y?=?$DLwS8vUhUBF%lOT8FU8&Q3b8Cb%HGGiuO17pL5~?(A^m7u@=>;on$?p|Ad>)=PeJZo7A3N+r4jt~6Mrj^a?*b6cD&6mB z+Kp{R*dy&zh~E>l>6P1xHL&EJbtcR`2gKNYsPn0$(9}~2GjrJ*fTaD;zB$%{$fAx$ zN4hW?y~{9rlxhy2Gm|l5U$KGZE8z;NN+Rga(Y?EFZlR`#8fLA93PfPD?VMlIcYTGU zkL7vSZ(y5wQGs@(x2T5abu?iYg_Z*g0+Sp{T@E#H2>UjivqEGy8MR)J2;E#aBe4*a7{ zimsLL^B0e;X}@f$sq=3VU%yovR?3E8g865f`kRx(Zd7tJc@1gP}iYS`KhxP zY=ZBqe7P=+MAm&L|6bulUG!NRY7)-)LcV*Rp$p*^8>aBLvG?H8uZJHLYP&Bcq;oy((#YT0Eq$dl8Ca>WJm}I&z=xQ5_VPIhp>NAv z(Ly8Lka+x6(9pGTh_>_Xd$5NJsh1x#l*z4ueEMr6D@xtC`7vMo4AFm99P6C%c-#Zp zI}a|<=UC$|>AHtmL@&C^$msAzb2H^zwBJsN?5D6Ka7XW^r3kvQR2_7g=<#gb%=qr^ zY64s|7GyNC867RQIr+|~A0MHKTIYQd1V98r=RNn1X>J(K%enGxcP)ds=ntj+33d4Gm!j2bDGubm zOLd^;*bo?2>lQJbtcJH2?k-*4l@B@ny&R^mQ(@1gcgu}_Z*cAIj)hd>3!HXNDp(tO z@TG4LUMfGcfvtjakLGQqkluoxOvFGP?DkE)rT-=EzxR23dY(H6g%D1ui{+!+F|aqy z-TFA0Kd0=b8l9iL1nr!ohXmN;!A)CJYnDeE`5DjqWpfw6J#U@PT!SJgzE$Y4Le`y2 z{(C#ARbIozdG&J+6;arAICh7pF5#EXZaVtMr4%kFab~sU`vaAwk%+273Qh`8?Q_=*`|5j;P* zEbWBH8-6giTQH--h}DNq52m3iW^(BwoeNesxKi6VF#&fn&xFy1w!q69QRA;KCgNWl zIxB@_A1PYMvT{MU5`-@-UEw^L0MQG^-!0v$9C|+9Ld!-O_$~hqZDzuwGe6T1b}OhC=xZ8z zPFYik4?;SJ%hVXS-+tF3Vp$B1F}`n>;~VkCo^8LXc5t9EMxM`3k&7VlL+YM%vlpby zxqsQ}B!a$%T9wRBF5;PvTOO0P)*%1AM2B9G138ve@vxp=geT=92bzAk;{+0a`*+7p@siFs=m)g%bNi*2n`rA->~Ef4%P z?Ry3L9^8Iu?fncA{deXWllYA2(ZhcpzD&evsj2boS+_BhS?{-9=@W3T)2QcbQYnaX z_m_#cG{Lu+y7D8@Y^Y(E*- z^neo;7muI1($@{yi?ye8I_q(G(gAy3!r4n{3A}1<5e)lBR3@ihC*j^5+xu>NNuir! z&7}|g3*l1i)x(JR$p3$NM;VlRJci!lVgzW*a0soWKgE8D60e?+@wGQ@-0L8DPqsw( z9%>1_gQGHI<^AfYkj?MW^*4T9KpfUSHJQGL+^rAKM!(&F&povNa9YvWTT_s(}9-oxQEFHL+nubUk+DHBDNu60waHTht1 zf4EnzwHs@F*QvY9D~v)@OfIDtkK>lS<4+rT>~Z!LlQ$oKilD+i_Z9}jHO#N0P;<*v z4#!z7_L%LHM3+1yT{oS{foLW<#oH^y=c;aY(-IXgqBqh6v-Qms%Ij&W6^GmS!@F`m z$|e%$+}ALivBr%oPQ&!;#XHc_<7Rd22jPKh*fBW2qlZqpGD<*~7#? zV!w2>(90ZHqL-0-liLP6ZcmDc*!+amV=LE_2h!ok*xuB0IjvYz`)}=-Djm{uIFZSl z(GOQkZMG`0KLKgo2Xkld3n9WppM5{kjq3tIMw6F z)qXY*ly@-G{BjULGa2R|9;*{6H-ws( z1|-33^p8MJ?tBp72`BrK{SuK47&6|T}gnf>j8G`fG@-l{vG0AS0! ze-2L?W=_fId2&eO)`l%{m zbnZlB{4NS7rF26mj+^5;9;tfYOUd9y!Oc3cBD$L>*N-ur{8aA)eD5_jR7l;&07v`< zhoV|=v;MBtJd=zwbe%n9$-MOOD2MLIa4@)CT})ApPJ(fVO$=_;yvU71YLxv68K>4% z_ZGi)LeDvE_k=(?PV zF|_y9RAxo9%zb)HyXPQEN9<+`=Sxhm6GxcDNIi88&1Ik6zksSqvY$KTF8mbqxfMhF z1!@K#DHCTyXnfr&mCx&&9*I;rwjX0(oBZ^mi_n?u~vrZRFFXUn@S~iUell99@4NsX+!~l1k(4h&~I;!9pt8^Ft zxql($NmAg42R?cG-in|{Dvugf z4hRjv*?4nx=7XVlk9|Swn@{hcTe_6TMl=nsd!HS7QBaJZhwO|R*iAT}Y<(&U+g`&h zm%Tp}y-WVvU$N|Y_?YE|Uiqf4SqrK3&v8k#0=G(=2#OjxF?F<+3t3m12al$b^OV4} z%+UlfbT%m{5?j(!&OGP3w}rt1r^I}COWi>DK7lfY7lL!aR{L+u*o|5&`r_EqqubKR zP{ZXw8Am=yIc*ZMD@=xwn7aYDJ_(~2?fwD`wext8d2LUckqg#uefsI-tT5s!6Fc+P zUdrF0 zZ$b5q`|PFC7#R8XkNmUvH&|;^=Hs2}!f5K+qk|p}^SF#=uU?{kEM%A?(ICQmr|LO; zG`5$4qA@Qe^;-A=ZVHPD{WULz&ZGvs_>r3p7tJhrvsEg=xEJ0p6-pz?#V=Z?PozL< z@B^q4e+Az&Zd^G0Rv6_b9J{&vrwgMSJLbLXDnLWqB1bor@I1?YEjmc&!uan6mHL)g z%oR}4YI3C(?mCPHl#Zu@%Kif<8i)?=+=z1jo4pihmUeNinJt3vv&SWis=RS{hjYwL z(>2J$i=Isx9q^Is>3i85@A0Rqmxs35lf2cahK1tQ1i17xkyo-lANx)VJf2RFKxc{r zZaDaKz}!KtZ_Y1CoMAJzWhe2P_T{L$3p#H>uu}M$mn?>Zmp{rn4@#nvug6~2DV9O+ zWK8lT%Llj_SCRG6LkPtSmpoa2J&n_ErBvjFCj9q){;$qTwd!7Zk->AI6;gjTp-MQ< zqOnWzKhq#4{?fxh*Ao2f%ZKHNBx&?sb+`9(q8oWXP`u{3_7=A32D2*=J@)8lYR6cj zpI5e`Wmd`xho1>5Q#s@uCwPx)+MRs`AD;bv?R1+femLQNaG$*>lKA}G?eiIGG{8qA zwD0n@|Nb7K`2&acqHz2`*F}}?Xc#sPlFZm)Cxs0B6fVEHoDZ+{x{jEgsD(!!8shwH zQfP;t*BvRU576DUv!mzFTiD-ynROed7?M@_q4oX@EoD9;;!^PrGt9NMDR6TIdG7Z^ zlpTj(L3&@T+|Fl-_)+%9TxPpr(EAYGl1{k%*S|mAV&GSW@2|X#;AY}P?vgKq*rry1 zeT%K%P}*aND6=l^v*;l{JV_B1B2_T08dzxIQ4B^a8`TFG8PV07ljk)Z1|Y(+D8u7X zDh}gT%N{24p_f)?j$vF77Mhsdr#F*;eb4T9FN`Ji>30r~NXX6Nr-5JVi)zkb8@a$C zZd(pyV5e($D1QkKU2v2=apn&8B@VYQh~LMXO(yOhq9tIp_CP^bw;LLD&8}GKh@&S3 zjO^YExxmG(AZ>V*aP`=SpKenYMt>A?-HQ0q$Z9rt6@phsOnwf=9Uf0 zu~CmF9ya4_H{0NXd?|FQ^1!KLk6ieCox}AX$!hrf$6qM;3pvO2m>sQ)A?KyGivv5i zk-Tn3c1i}x+YXfVT??X0f=7`}C)}1(vE5>TQxf^Us?~Gz`_P&44mugg_1Hf&kMyCLE+YdBxL@c=#t+2@F)JlhS%5!@6Khy zt}N?!B+d2Te!lWiPGhS`G|relC!jy%g9BXOrD_{;qAUTf7_L)maMO)T$|0#+^TyB# z*7*`)B==6t*ZR^hBreH)rysqtFmZ^;Sn{ciCeXI*E@ho+4-| zGPAE}XAw}?t~|DnB6?@c^rMe(eXIX8p7{GE9Nvmpi9QU;!L)O=JK3X&uS7*O%^Rh+ zkRi<~`TcJ){?0ih^q%P7^wp2PuhHzmc1})9E%Jf?jf;cAOm}IzqsZjdxtBWWDKuE6 z3*4$A^U|K%dFJYG;OQDjOT0P-HicE)s}T%n?ZbrCg^(d!rqQxGG7*Ef?>|%G**gl6 zbhl5rye09s&$YMXaRX3<{}^-}Ap4Ngt+jNe`M|6Co$m!(E_RC%jg8NgLXoPz**w0l z;W~4AEk}6`=Ev!~I-g0Q_7^WHnaLP3&&$C5Ulmx105JJlh0)(goB9EXU)X}%-QaDG z1%BZ>WU+co7+tdq{8RM#2mZm99oV{HiRYg^J!FN2(A@>?kec>xyy_xvkU5zA-}8D} zOMm88ay-5orPD%_<_pz%!U@!5-xal)SC1ob4zH=3yh!Y_z|jvhijR=ZT1 zIQ?7b6@O6zF0agY5< zx&-1ATMHu@h(7kjsm;zm;%dNT?Z=T0MN%(w^`XkA5ph)bE16E>9xEl%f*vPaHHJw3 z-CSQ?rBTp_-En#g`S9(6DUHFOr=aaTi9eBghbQOmgZBGONLHts7Zh#=+V{dzuZS;z z&eD+Y;(9Q=`9ay&;T(WstBn3|EB^HV zJ}mO4yF}4uMfc+8(;K*A%D0sJWJ>iW^(i zKfm~|qD5E^B-Q+iPc_Q=Z#>!=KMA2a7X}|39gcqscnXo}bU`fpq|wNsw$G>ZN?|bn z*3z!oLLwMb5#|=+3Tu+9B;n87?`gd?D_2sS?MWSdw!>A(1GaAYd73<&P^p~MkL38)& z-$7De`l%?=AQhf?QQwi@Ru7F&j4u}G5PkTiYhkX{kubOrnybcH3a=NBMmgntgVkiY z8MpK4usP|i=ir`3{M)%G$*xoc&7t&a!CWqieOK^%FL^h(d2`QzSCAx9U+ud8Iyno5 zluUcuU0Pv-zt*PXqA=QOP+Fq@=r{gEzq@hd`9u6!bz900vhNy7;X?~;@z5c1-%O%{ z0znZU8Vk&%(YU5jqN`gbsXLJP?&Ft->zGDQ=GnZ5FK%lgdw%ACw9qS;InN@HR1?j6 zbBC-WD^>!*O;13-p<~Xsu>jwD5GCb#vI%SlD|u_u;^C-}TQ_ZGCH9Gw9+TWfIN_84 zS(hEpf!|9!`5a9-K6v@Cl9(dN59-{Jaw5-N-SfNu>wI(KD|*UYV7mxn^4UH4JNXYj z_WL|7Yp)!_?EyaK8C)MHZH5omu+1 zCXEhR`@8$r$6;32;C0#E|HtvJ_49fXXzc|LsJ4-#c072`7OJ@s&UTWa1=r(NqBHk6 z?08@KC9E>2tFyZgz;5f&t~=UwAon+Fk>Q_oY#r>`c#FK}+n;RyarEZ~UZTu(Iojys z{5!PwJ)7x}k)>+u&CmT;P29^ytfcRV|RBsCl8j|+6*%K z+ThKxVD^s#Rp4`()-=V_4+eGGrkK2i(ZxF^o_!iW@zamrP7EgNLf`iM@Ij;l>;D?>Wy$e200BR#B<7Jek-3DJ8Rv}JZwRl{~8 z7P|I~SFl^p_2xC_&(Qu;Uh}k69W-Q)-W{=vhN0b#MqxX9pvfd8`|1$!Bkx}+yv`AX zo!Yjq&<;wYmON&Lr}-(ckDsR`Tt5mowC=I}@_-FB+I-v@u=W|W3nLvoEUSozs=*7T zP!cDsWnlQMwGPWa3ceZ&nZwx%mPI)hdX#JV#U{_IANpz26W@gAV@IW3J=F)hps{1K zk8FM-d{q|Te!!>Zzj@$)_s{>^erzflFC%`w8yn|^-uR6`a_LJCmbhzBo21~(bzd0y ze@MQ2dwLpf2_;r2-Lr&A;|}`6)FMdIR?nc0WgY}S`o7(|&jNBH&Lo+Ph@kNv>f7BHI z%JIG4*h}j5+H8)mi!h;cXHG_?XPtv%^GmD?`Qpf?_N&e(e-`vR@vGSmgR}7Tj_9cj z;`94HQg%nqUpB-{xgVW1bp~qhcI{3-A%Xggls26X=0Mx4^L^6WP6LBrWs6)8sY7=! zWNRxTb>wt^qkIET0f%RH&^YliKkjK?>N~)NI-G*vK94Z?pZhF{{=fUnL;QB^*IJ~G z0i$OZt;O|strz!v2uhS zjSS{_T6Y5nB{B6vMYXjd4)o%l-$y?G=F#PMlGHpX;$~X6cbhWYxL>4lfb?^_N6;&i z{wC!h;rL-mIQiRLT$A)iQWjsRlK!=ge}AUcUHvaFY#}~|mg(ai6?5Fk=fqy2!gI&K z{Jd=84iYcjCEvK*HBG+PSolIZyAigg!9Kgmb%a>TBB{xB{vM1=~OKCP6F*o z(5igi!G(@8{%H*_Ho(6f=`L>sNFd4)iP6;@P88T+?*A*|6z2Ne5yegF5RDISTfOW@ z@(kW$uhhSu#+Ry?S;chHN2K6{2U;3Q5R4 z;lB$Xj%a%0uumMBO{`zn5@$kmi(BaJGtOc8dn>e+HDaj$><@v$c6#*G_sPQHDO0Rf zWlP(sCr13r75L;_HzSLd;h-_KOZesAr*BodL=k`6_gnOeo6svy+abQC_vR9+kQxrWc&ojD;xo=c8lR!9MPE{VYm9rx2# zE5C0#%GgNWw};%f6n<%PpaPBgtA}nGVxRX0G-#_RV(aAQ_w?U@LTLlZ0zDyoeniu= zR+AU;$=>)8j;NDuWd*DzH$nx7u<`G{@P%XIIY$T3=Jq$-G(Ix9cn;VpOi!KRBX{Rd+;=^{@({u~XT8fkG_E%RgD%==BxoT9c?}BK2;n zf0DoLS)@kU`oV7^g5_}W?a?O+mx)irT8wkjXgAo!dC(T#4uaM#<;VF6r((&%~9^QMqoWl-%De z$+q_rl$f}_f_388_Mq*l+t1&Cu2oV+4xYh!9OtHsOhu8+sp`bY7AjOYM;l+_CIE&( zQ47-`ZYzSyS!vV-=Z$1PdHD&1Rv{?$>V-aDm8^VZgytWeXvB} zgvJyw35I`qc%)y`<(wKzyC>m|HxDQs+4K{74U#-)HuY=%GRm{8Bk?^;!F!5-XE-Th z$NCiJCoW^PUaMt~W)@`ot!;ko#T+bqo%iBU`>g4}%lT9A04utFUaEh$%P%nbnIiA> zyHB%kDo?O?r!ew*?RtER(RcW)!PXoya}#^)DwF@|&4vWRoJ{&jg-^=F^zFPIeVPl$ zd($;oMA6v{n$SzB>rjyC&-m%1Io4h=PBO?6MspLA>@-=Nl)xSnG2jF_n7Oyj@FRNfc*Gqdl4d*Ta9Gf5m}zv>$J_ zO<0C+U-t+_-RaR}o3$0!q9*Z~N$k$Bc@;Ppj!I22^k}B#W}Ot-!HInS6l&ehTm@Ek zx#{Z8Zp}kR`b(PboQM>FjjqhE!QO-3&(7cO*5svM`e(L7ciCyADgY zrlu~x{vzQg{O`K6O+HBV$=|bBQYH1-?_Cn;2&2ca_iuJe$eir>@Vp^BNBfWacbgs+@^1L^YjKch2d#| zjDOWheC}xa;_OKtl%H%k_cehQ)dlV~&RhMYX);vt@mMMk`lsDBCPIHRVs*`{xbXCo z<_&diuDy#qNYLM3#%^{qx*{c)p{Ddn^D+O8&O2Lqkv!^1pERID@qwDG_x`qPK0SKA zSkHwQ4JH-ZMb6Wq*|fuPdqUea&Fe0kbJp@Ah1i<+Qi1fS!i^{iD^=L{eEtC4U#Fr5Ku1q<@}`?hJio}rc2isM5!N*Q#0 zG#ODwjEMo?jyBEuc{+hNYNBXD;-*Tt5;x_`%u9O>S!dw07m1fs;zu;U_oCBgOlX$> zirl<&tESc4XX~Eo5-1`lr})di#Y?rrN(P2P$*Ep253VuUVB}A9GGi z82v2yx8+1!wbPfTHtICrJaEWSy(orKc-A$JcX6X8nxF=SuP>nEXx_)q1;T`T^KZ+E z_=~b$`j6IXhWYB`U0Wu3vA};@PLwX3I`iv5t!9}#lQYxiL@Y~=Wzvk- z@#7dx-3_vSt;PM@a-jgqp8LYMMw70wYvM$&2r_K`x8*_%rc}1eA~l-KT-xqlJ4DeA zzJFV8v?w;+OKVuIS(G8R&F8i#%6a>5%Z)Y<{$o1us!G#CIa!mjL=>G={kP>t7oPmd zrdg(Fo?HEQzb5+MxMmZ%O68+Z(Y*V^pKC|4{pKT?DP$ zb_i?y5@WDB@mC?3TI@fcEIwKJ51$$= zU~}(?-yq3%Q~%HP9}J%rcfWEQZaD=SH!=R-bt=T}YBq|vfro>5eRw{}BpD39fv1H%- z|8|r8Soy%t`^qFPB`aPxd2Nhva{lM@Q5RlaZ~W{I&Cj+zeD5NFo_2oc)6k|tes}i7 zF%OnOjLb7bW)2~AXkC@ZmGH|83S%bN#fssGf@x!huP}1*Yh!P$WJd2M^U|-z=0ntr zA6YJXgnwJw75-9`8T`Sv@Fmh<2k!qtTg1{wfxO#phftmVE-q&B`FL#S^HG`pgZxOjjZgDR+-4*qW?b>;cOf)t?CIDz#fwZL``#G@{DS;q9#(pylihMH zZZVF;Z)Gcjv&}6xp$B#^!{&2xfhK0EZ&L?1`Z>DCg;{e27?{9FB%&NFr*Eo%7v@I1 zvB_ro>I>je9NNU{QVEU|u_47o|3>tnT^X?qXhHhrx@ArVoQ`MK{7H0x;#(BQxr^qZ za2f#@Cu7r?$>j0^ead0$}jN(FAEO5@=}gcF$K*RD-`U=mZ$)qg*c z3;p!{x&J7!qvq6JTS=BFARwyO<`$(O*TG2dA0>beMYWy|{<8q0rB&4JtH^%H21#x@<56c$#CZ0Z zPNf;yzgazDm)lznODnOjgN2CxUfJo+LjO1@o-v?*yNB@e_D!~!t4W|^F`p|!FK{AF zZu3b4RxkX+QikDd<@OQU&H?BE50tLxzOitUlbR z%Y1z1VPAIB2jQ7wSmsQ>eWacrsc9@r&JKTr-tj5gG1_9F@9Xb4l1F@$7>?}<_)d)s z9*oN9II=s5rQ2+9M zIfQQwR{r`!2#x)W_T;Z(L|c4Y&3wfRVNBVE+2(}^I?K|sS2vLf@lWn=Ss%)QliiP# zs{9BqRQEvhq2WKUoG`k|TUY@`oNu$7rG?P<2!&|oYxX}LLa*c@K2yptU^}-~Ryr28_u{L^fqf9v-EB*r^ z(8+W&fQ8Ke-%tML^EtweICTyy>v$$WyTw|LmzOx=XyGXQc94~#V)<*IM_~ZaI{EnT zxXy?wQ+D4D3m$>Vg{AtTZO@@I=-@leJRuZpx%tEmUx$ zL}NweKb0XQpKKo}HX)9Rj;iNJg|Sk;NjXfvJ!*{OF7P{l8kaymZe@cGHH4>SYtzNB z-42-QugWM-3Zsr7`MB>roajiX0pG)ee(;-rhwgh2Mk>R*j5{moQBO~QiDNL)`yBfE zAfcWIQO64M1X%rrAbHNr&Foc>qlMQcHuItVbuE{)pZzFoM1)X`@e|P|-r6mO z9!Y+={gU`6WPXTJdzBjp3~~Xdcc14$EHlGe{C#6!`qI=^ue=)G9l7f8L{A7=CAf2Y zM=im#hhvuBgx8>$lr3bS#*Kdcp?1ihUWey5Zuk@m=EI{S2F15{L{V$M6}@*Y2Wl;F zy?^NYTL^n$v+LS(5yVy=>KznBgBlqAAEK^1oXhY1+u7@F&v(cyDMZ3K6_ODlD-*RHx}NK~j>kFox##PC-CY3(n=^rS zc(Y=E3^!~Vb3N;_!~nnW1kQ*>W&u;#PdfsF+)#3O>#A<%G8iYnko@so1?WwCX2LJZ z3&&Feq&Lox!YVyysqxFD;CrHt?tlvqlz4Sf!!?l(=3mw zu5K%U%T)H(#)c1IUZ!DZxx)(C{V1lAWk?{yliiLLjPtsdY4N4xy8ujkU6p+20}G6B zEO)v10r$y$8*$MV;D&P5(|0m5so|HhgN&gVU!N9NKY4IO5N6XKrG2r)3iTt?d#5o^ zvB7W35k-4$*j=hC*j~m6H6Aljz9>?A zb9v#Va`O{g{2RF6#limO%_m^6YLdE5jT_RBovCC_CV@h!%HOEo*8=+m9s3wI0Z8Gr z`rGO%BTQ0{d70Sw8qjJtej2;R47byd7rp7300Rf4j0D4)0g;%$volVBQ;J-1>n5a7 zzPbKgFz%a~dMZ;ign1r}#(u4uupNLu<~kFvl)M7M@nt*{U$B3(nm4#CGzP-@S%~u{ zt>Cmy;@UY04k$G2u8{g>A6yz(kvm1eb6(Eues>bV^(^xDp?`%4O%I9+`&dnE5y^eS z&mlOEH{5)btt^ol_LI4b(0N*b`Vp;_6s+fEuCXs2Gg$;ji4FuGN(6%3ZrREHVj7eRBs0rYiRs;=Tv5#}|&)ed2-r6ZMuioG2kBNqc9b zMinsm12kW_W@PuyoZ1v5nhuzas-|xK&~H3e_woh45Sj< zd+yD#K^Fn5bN6G;9i@lEapfv1`UzkpV^OkroDE)et!BL)Gy%4I4F8o# zw}3sip7cF-0jRyHv3I^E9vtwf+_EJL?)ys`e<#(P)c`K}>pkhk`KDO3 zcsAU76cClKwYjb0`NS=A0yhizAiYh*fbKhbc!K|D3yXajAa4_6m`LNs^(o=YqRs0d zQ0K!y4_yTqj?jo-jU~Vr%#n>ZNywp&@f;Q7%_tCIeZ1TJEi07HyJ1c7XdC2F9El+- zssS0Q^sebs40!(6<@~D_iy-^78`WEV-2dn|-`Dk%6Dr=Ucy&aA0zNG#ZL=?^10Ond znqT6%oO@B1lgT|d0n5zAG@X$$P~GVt61c_;rG*s(m~M{(1F`82gmIW^dy*8=c-}E1 zi9ymn&XaLHhzfE`EC8SMv_qTuxnNbnWshW)HNY!a_;yVC4Oom-5&T=v1!p!BlxkWuTdW2h6SECU4%GE;SKpiT^kM6-~stb z(tJ??m}A`eB7~9-UN)R*oLSETLSIt-O|bvQ?{~Wgk0!);0}Xx4-ew^2=Ss}6Y)&{Y zd1n3oJsd~$^G9D>EeHF$Vtc+SobWK`buYb!1t7b9i!y+(0gzRTn)^g7jTZ+bpQhNw`~orwN!n zitt?*R-uA(UQyB`Qp zlp|GH7A^u_k@NSC8MOezai@?GKR!6|SM$OFF3jV2^4y8ux)6{pmBc8}$pxS14c%qG zu?R#@-SYHys|5LT%+*D`d{Bnw`7=+P$Dp)SRMc!P0SQ|C&etIk?yYNN0$@94BE#I*J!kSSWwl zg0zq}J$;mtsuEa{8MD20m&cKK;^M!=EU$BsSwHDJkZl2rN$5!XorXr?woV;{R3-7{G59M}GlybTWh5RtIgr~^-1bn|5~ufpf;#IxBe^MK}w+C^8P7C^DTXDB1h z0ne%*K3y{j`b!boGZyZDsJ>&u1mM z^1H);bT5E0wxR_3~=z7fPxI3H|AT{6R=N&GUnMrPX7o^Iaf>j7Y=KI zwhxniK|k5ypUlMN!0St(-7TZ`3Uf11%^RAp&BgsST)d4+8@r%&OG6NnGy)Il*&3-Z zR@h}v351gVfV-xbt3G00c~e90y}$0bUUSE*!bFD*mPu{S|0*v57MfCGeebaU8GGrs z+$a@n**>ga&sU1=?8-5O>jEwL)fes^V}R*LO);u67u3hfIoUIELwCpUo}*vaL3`GB zJrUJvAS`@hYUvsmWH;weRvefBWod?q6R#=&`R=;GMMXZ?rBL|dCiwx_{8X1pnY9#< z1so7>=3|D}XkVAyX5Iv`8wKjj5lP^0kpd}X=7m0@Crm{#zPtRMx0A$&N>DOQ?)Scf z0P}Mhf8~5!1(MyBOd*&za@E#4+wd6|+zxS`{k25`_fL|Q9qPpTFxQQ*9>>egKfhZ{ zMKeIXvm1=XJf&bzqF!D4HV3qm{rksxZW2)3dRZxs`mQyT+XFh2 zStMH+hjRNw=AC+e4w(P_E%qu`QBcwsEImq*n8@x?Gud0 zTx1I-$!BJTq{{Rm?Lp(9+}eZo>Z{iO`fE>H-{Xe*4YDyhzovow1`wS5QviO|ySaWI zpo0!~#Mt)g=K)ix{Q^@`8p!15JDW#~=SP?8_Y>@YfmWz!FQC)}*l#&YUr^(KUNM(> z&7N<8FY7A{?dO}o_ajYqHxA(YBBR{0+e`*+r~Q_+y6eCoU-6Y6a@?@z^08ly%3DC# zhwRcqST$gF+P`R<#1A9p$6r1!q=W{So*H`Oq=I3>A3mKp4hTb%UTHGpxu%OQe$7(% z0rl@!J7+Mi_3uiqjtq;Q&O}Q&TuIAf=AdY6>z2hl?F_Wh{5N zs>%($9`1FPNA7{+HjYwFDz(5+Wd6QT3m^$oI6DJHzVbgQ5p@K_!3>|Yg zf5jPeNA0q`0A%GzwbZ~k4)KzIJI7w%2a7#j3PBOIl?(KfuUu@VT7Oq+-`M zt`-@H-nn@;C=~xMfBOQc+X~(aL7QSIYW%_f*7?T}E~>~CjXIgPrS$aw_gw!iPZVED zBHEFsX>q0cU;g&m%MVubyvgWeW^=_IEjB1?AO>5KC}4rE7m=~t7A>Xs{m%XOzr1~X zNL0L#+anZ5S}k$D;D34Y1j*(vZVpL^vEKX>mDm5C@820~x-5}^x{GM&ugU*!oudZA z|2mQ*P%DGLk4S8%W}zR49mZ*Fy*GV}d7sggMJr(t=k5PL|E#YUtT|cbi=KTq5nji6 z{{PQ2H(XqZd2!4Yd3(2>F2nVL|KHCWmv-(yD6~Kpx(rXB12(8L)6@RhmjY&=OmJ&G z;)7=~go*yyu%4^ih!n^7FU6K0ku{BZhWW z2$S5fQ^CfjvW5y$h%?_0e3gfGXDH~03kh&;1LYqwUIRk;SGQkqlp)c(y6$cme{MX% z{aJ4i^EGa@DQfw>ME%c$Qfxc1Ip&ddVV(IUb3bVqPzE*Zw){SN0 zb|GqA9M9u+V|FM{#q-vcuDm%KUqK1=yVA_>d*-3#waS)ZAAYFb{bqMTiy7+t_LH<# z%0RCk?jQW_kLUKLM7AkuY=eXAb)L>5x#(1h!ufAFA9(iWj#g?KDg5L4>!tqvEHtvH z)c=DG$5}HR3XEyffWg$)^JPmpYFZ5s|CTKXTMHMhj83w`{k$M+u{X)6`$F_zI%$4* zCh5nm^TE`RvEZ=bWM?YMnwat_yuu7ce`GL2IUK)u=gq{2mmrh5TLTk&?AX4{zmgEz z!T5O}{>*Yfi56-$Onmiv=bb<#tr#CiSb=tnFgOS&i^Z9e}PDw ztvcF;1>oxJfxp}`3~)iAks&xa1#!M+_jAR3hJJ~EE~x0OfxtZp+vd#_^F=11 ztZ>_A^xCny$7oL^NX6HL3z`aq>1|xV{v_WZ#Vv=|==arYfwp*FJm)2)z4iPJ(9R#g zc!;zR)!Zf)%O`NbddG7vdLcAWAhJrru=pjC|3ZEG27@4Ucr1Hp!G{^%@PYkSACggt z<6!VrjH?M6IpaxuhVds~{IA%VrlX+NTVcA%Y_K_)IpoPM35-0t?XlqX8a*NAHfM`* z!4UoUAC%(sFwXtq#hO3is4>0mcho-?czDv^xTa?d&k;LzU0^03b@6n}s8Mmkey<}g z(J!|^G_~WcaJv$uWTiC@Y+<$R9{`I%Rv6v@h|DU)w^Danw zVZ!%3=n;BtNm}$C+sDq*2DpgzbF6F7&$+<_6iFH1b!Lda=z0&Flwg8Af+am-y_qQ1r6IRelNZ9WVK-^50TV;|5`M`2EQ>{?|A90fCsT<7K@Q(NWf^9TuUC;Wsb4! zzG9(b`_bl|%-1e6Bc@C)7@Z-eu9TNC_e<*8est7%31dN=RXQ@v>^DR9uD|{|w_&H59 z2xaBxn|M9thgx@%^A_U?P@*KpT~CINVvCH>g`1ObkIo9pDnc;LOVPe1-B@xotz zO*thS)4=jhNPDV{0}9Q))bkqSPtGqmZtgEkVcyYJDk+;{L?{FNM|@}@nMrH=)|C<9 z^>nvRuC@S?6-Z}z`|?27veCE6*S`bC3FFXxS&WO&GM}G%PYr+F>Q#cLM!-|GD$A|T zOyquon(p`wI(VS4Z-Q)e0;u~N@*SzjN5v6_l=rbdcPPo=3B`7``^7wU1dcm=H5z|i zRi%a(oQw{0vW)J5u>gCwMESHlSBU9J-Z9z zeF#-2&Eiv#NQ6XfGCL2nBHA%&crJnq@`Jq(15?pTE~&&gu2bK3Kx8TW%y81|`9a;} z7wG2=Zi*dtPH1yiFe-op^ScWNjCZmZqKZ5(ZXQ`27yL|;1J||z#a<4MQwkCD_K*Ib zQUdUT`(a7vZ9FIH$(M%0#%Q$aM|z*+7cZ<~D)aulfb(Vztvf|r&(PJ%totN}?9kIh zKqTw<0x*7a{4KeA8H!AZ<-lo(ffvQp^|0b_LL_?0m$hBG?c#|{b+X3-E z;Lz>+93&25D3PAdHgJsxQrYV#t(xwF0S5BF)w*ej$KYDr=}dN5_RS*rUeqse#JXjZ z@yg@0+1x=2XufRQ4o-$3&$Cmq-zWv) z#_cm3`(J3G>d~8f!YBY$KMxO}#d)g!b;?s3C%17P;b7Cjjcn9JDJ{Dt!3>8#HfDra zt%CEKM;i~;zCz4*+5Tx`KCx%jjdr7u97Ydm^0d%_W#DO!mivw3QB~Ke)=)KC+nK zLMh}h?EZSOu0b|ZxvE#`OvZ+BdbV+tTub2VtM6j166I*@?9)}x3rz5-{~X2O!=E6W z|DBW2b~zfC#pr!JFI&EW$z7?B1{y53rd|lnKqnmEl75lkguAU7bx*x0;87~tC>P7u z=qRcDTxT5@o<|_L#NxdNrkS)y6-5isqd^~j;|7dlNo)G06v7P2rlZOq{)|VbRH~G- z4LIS=Pw}7J6qbO6Z=aC*`65&RV$B-u`C!cH+<^;+nc>BryItQgCG#b3%_U_Nm>mHJ}`HzU}0p zBEWjoSBf%yI*mU`pdbcJF{?AjX?MSRa&!R>+(A zlreAK2yb_W3vLJ7AhRyrPV!+kerfhdYq zKpK0d^Wl{&L~xW>+s1Po-tDE+UtL}Y16{hzGu4=%gxS~s_!Dk;*E?d}2>0W1$Vmyy zl!T!Dg7%k&t6cDD%1@3+6H0i-+mgrl{A(0UQdc95`Cz4WLSAMlvBK_~>EB&OpCNM9 z#B{14KKM-f_(Y*TzF(!^>wnc{B41lpIx}ZF_SLwDOWA~ zHo$1={mt&zrRc~x%7%1oXPcf%L`&-lq1FdNQnXpTuq66LoYXCHc;&;> zi!a48kdsXQ^A;r*_?gs*V|a2G(DN-FVODiR+MAaAf(i`qc+5mgh}Hry)1JLlc{CTj z`uX@Dv5_4%RR|WmctZuV8SELkvQp7;ucf#lZ4P+Q#w}$5_YX3kx6?|DDnT^;5q0hu z|7;j!dYz<>6?*A1IbIe_MM+C9Rr%iW!WW$P%1ci$Lf>rP0LhP8=-UmsL&D$rV25eq z{0%3J+qYujI5V7pPHCf~et|4-Ww?7V@ZbWT&v=4P`YrCuD<_RRYsv{X8^Th46AwU1 z5#9Ww>p4i-q2i*)5;weZ-KX}v&N%2Ot=F_>N<@PBhpo8USm9%{{a&Th|A6Vof#2%2 zdFV4|12L7d&%4dQ3qg7u{YYHgH<9!qNok2Fb@H@cw22IvJ5CbWOR{?ZYB446S#bkNYyXL7^u z5#?PO{`Bx99XWYdRwkNisJRv_AP5J9T%7B1UiY+C^ibXPC+N1*OS;orJWw*0Jt~k$ z1^o+)nn0wVSdjB*{qGi z4*nenW(G%;uh5kvj+Zn}Y#0YFzEkf>+Cd3DdUN)fq#h#roZhdJx*U+|`Mypaj$eF> zuH4Vw4Msw0Y&BPUSRvuzs>8m_GVq_?{SC6pkjj@2Z)o3QyFd2p>!r?hAa+-K)ZaD_ zUH;QvyI{@+PycK&_y0f!N5$U@tK?-P0Y@h0!ap2P)ql!gf@>VSU85MKr!GXnW;^og zq+Iavr!VIoTarShf!)eo(IP}k@>%aC&SUgGlDu$8h8A9rsI!y|%t6Pc+m9|y^TX|% z+r9~355Tw)Zf&|xF_`y^zV2ld=3Okle=g`GGjv_Mzq)<;DT?yor<=@WfV3$rNurfvmj9U$z1@V1R?`S@aV`c9`3Q#mWl=!p1!k7WbMOdFN4 zJ}yCAw&Gw zbCK>C|8Ha^tzxzfs7!^N9bb7NDd9SO3Y<6K^L`PRpTz_pc+lRot$B#f^ot6g#Qi%% zs=xA|I?%zRBJ6V2(m7~nkg2p&1jpgozUFrz38dCu>AK6DgQzKQgVk^WxHRT!_^9Ln z^nOa3xO&bLZ4TYbopHkcH1(u@<%^%-uut3bf@c+|_sfm6rtSo z+2@YV@tvUhf%%0-rkK@P9JayQ#Es_y&gn==dn<+UGY1Ta&lle`*#HKXbMaU5OAwvS zygk_&EQf&{I?)#nK&>(_v2%5K=)&9g+28}N5zNjg%5E)Hcl`C@$C zLtP0T^II%1UHa{27>@zyZhf)atAzP{lJ5qvVSWD7{mq0vsTHDK;yKuR2G7r0^K(05 zf$IQ0Q2%v{8B+awA%+Iu3;x2{2O&9(@FAkHILPn<#hE$rJ?X%DU|?5))MW%%EEGnl z@fRY>3WataGJY7J(ELF9_yO3h_DylSCk4@*NmN*<;(-Yhqxrd2%WW2~fJ)GY= zlzu);iEIY!j2hcU#+RY_m7%B&8a8M}ThEfVMGhHXa$jUV9**)4F7Rd2a>40hj@yhE zX&{00Yp}}MY&2IH{?76dKjaIa@s6HhfEU^pn-(|c#! z*x&`Xuj;jr=K)~9D|pep9R0|i?0U5N@klaNLpWeHi(6mFH zozW`m-Z>rJ4b9kj!L%Or>kwL<{Q1M$=^U-nH^m}$)>~QSRO!qJQSx~Z){P$5& zDY8u*uoOOm>nVDik39S-a9`8`Q~hmx?;06ozwvUxZz2`f{mu43LvtLnD%K}17k(tL zaPUL=xs=}PUH?)3yGi@dXQGdac1JAi*L)wCeB7zzA(GcJCa7hcG~ z2yQzvXrxaSDTw=^&mF#RA%t;{A6;VV#(g#b$6pECg|1Sh!Wa=Ty-bAqsz;sQeh zVQ2lCxo!e9`1ML;tvF%E_!v=Jl@zkRWiq*!`88FOIT zf$Oadu>*x-0& zP~?61vJ7?5c#--(!}Usvb%jwEJjcw%l!FtrR>Tke<`>C#f7IR5UM8&$?rYVsHKBNIJm}@A`DC&f+*J z;x|)hT&X=!ZBQS(!bAhP=?`Rc4GaOtmTKFC@hY@3{Db2p6%`CTc}h9ga0um|pq`W$ zF2Q*>~|tk*^q$(Y1ELzk?u)2`#50O9J#LH9fcnLbTcx;{SVcCwC$&8 zMnS;m*D5Irk*H~S`S|bm2jDP;LSWp&FnAUt5v1A_gj&wk4|ZZ655@gMKknPnHdzI9 z3A?IWpzH3$C|7D~sIftI=Mc*<@*F$tHJtSdNoVAhjyljnnw233bGbi&6gkKyZ$~3y zO;~4C95uZ0Ak@7|d>oJ^Rmo>|_@kE;x}ISdiSSL2e{9JymL~D>_L>C8ATSt0ThM7l z4ew3n-1Vo!yr+_V4?IW1k^QUcxodZ5;5)6O=NIw(9j+6vk0oC%2J8nPNX0NSL7N1l zSNowqfOH={fBjB9dQ))Zs_qXOnB{ISKjHNY2u$oZypGC3d3`q}A1(4ji^2bX3D`bI znajI3sdjOvyj9I0LSqvSqs>hMY^XkYx}!81yk&6g+(;(E0X0_Y{$-XX#jK8j>rL|L z+<=`JZy%O#_v2qKyda0((e>Zb+ylXNRZ8WJ4I-R!Olof+XM-|5sX=3!>cG6>X5|5# z=beOZ^+q@!zHFlzqPb<}A{XpZ9dd`QA*ANBz&~*x>Ona{Q2fjstH~v zu)tVX-QE^_s%Z|l!|TTlx1QU^&p+ofj#p1Opt+4&<2gL1vfIS({qqBargc*vKUE1^ zV7>19(w0#G{`L`+OTzE7snHyK)98)NFV|=Y>tTEa*?`qf3O#)2SXttK+70M@J$iYP zQUF%*=|649av~a$ZL^kQi`c3a)aod3J!nwUm>sXvP`x{mRxOIM!V7P@;^$H9EqvMd zeJR>%p8*aF5Zkkwz2!!PrWJ3LsSyFbC9{a57K=qiq-VJMaUDU2-KNkK|G%nPB|?5< zR!DGOk!XVduj>);B^f0fjG#Wgs+@idh$L!cQ{(kBNGU5*@%rh`U#7V}=%E5$PWmtU zIF43amCATa3oG5fju-V-b-|dM|LAR*) zGnUV+@A9jPFJ6GUE7nC!INqliRQ-#76X0&cf&5PXB=CghLhTiNzxEI}-v}>Q96QWI0 zyj0IEfcur&)}yfeOV0mW_VDloUn2;|ys;d#M%C%}V#C9jkYh2wmT-d6{le~yruuDy%h_PYJcRyhdOJYD2Csj89!6i~ z1%%$vl{sw*z>-`gf1VNQrp@!lvr3bf!RbeH`d{#U?@@fypuIzAN=-N9UH3Ks)wihc zn&Eylf#df=RmJc+YA0{o>&F9TL!&9K7r3rxQOTW}Mu2i*YB^4$W}wn8=tLo2=l|=2 zqWk2UJ^2?Ad1LpvKNNVKNQE4$pBQgN9P|CDoQzZx4Z=?yBf^B;r(;jp*`V9}j~hL{ z89;;dxrt#M5pws@xx8jzgVvJ^E3GkMDD3y2pIZbx$2Q-LbP~&tl}spZ#_>WA*c^rw zA_*{lx^{V=fgHYvls981eZevR7)g0*0Z2Gg1dro=*njXxr90s&Dq{0q0|)SP5)N&C z{M;qEq;p#1~CGXwqbP{;P*t_+s zkqf%$-tGJwpJVK+qZ?m_@tlpm*Yk=)4uG&|sm_7@+n|6R{!A)1C|@md!26#cNFT~# z`+&b++&ufpdn~tpnu6?f;x~ZqVUcBNb3XWr|I4Nm z$;_uK3{X?*M8?@7cc59Zv{H%v!{Zl~ev9Gne37iLc_Qx$*q2C~XTkE!Wy0V+f$ObR zmQTaA*L0Ai@QJQ-*+f`FeuZt_4EIU(PJ4#eUPTQCLTpwS1#l1I`-%X(&+OT!3^dw; zkpEkj+vNBh*Jmo(Qnqm&N#}V4!?-?DvlExr#C;#yj58LKxL@E@Tt!WtYyuLoc2UVQ z5rFmHT_+M4+2E^W1=ZU&u^>#Zx;#o;0ETFE@BPMc%xArnWY1M!M8)xl;vl|XZ&d2a zWbyr~2`dzvR5}9o+0FH>8i+7Wp+3Qx9``-<-yW(r@j)hqgMu0O9FP7;ru&HBKaqQK z=JPh@o7Ec3kM$)&dy>B*PkAveK9F`rnbsRMS;T5yz;^K4qyWA5I_~cgju#3GHAkef zcNj_B1R&AbEnMsm0bc6+4*hGMfv3--V+`N2LB}!sl;toSm%S=F8}8zOOz3ZGD;&k& zvuj*9hQB9!t0p#(ISFZMKfBVt$`4Oo>6DMa{-K6)7{wd9V6ZS3_T=7KB5YkPqZSfk zgJd4}H3K>xgAcbBT-vZ)8P!e93}e0Oou&1Uj@}({?yTzG$NE2#G=r1@>pi{_vezj} zE@=K{q3TZt0XSP#d~NeT{i9Fe@QcYGQMo1FeT?y7cVbrLoi!H#Gv7jk>Gxa6P$INK z9oN~f?Jo=nWBcCZ^$M6dS%b?o7R`@vJb0Snzh8{IuM}%4(r;GHNbk*2yUzzB4upKC zyU&W}io~cU&>Nt~c|@kR69O=d)eJ~NN)X&a42UT9e+D1sNOb_$7b>1t%X2q)GvSrPNfQ~}`SZwLBjj90JX z&Az69@2PQ7SkvR?0K}#Ek2hYN2iB(bH5rOC!|`GAj>9=dXg=Ozs~z`=ghunPU)y1A zO4DrHOPuxtTfH^*|M6*zh(DwHk57YSg7De+kqqY1Qi6xA_#tiVf4>A+PIXMbyQ^9C z^-2ziK}7iF#d&TKEdQG-g>4Cz@xZ88+V`;?zF)&K9?AH8rC3r-y8I1+OhWZ4uy|RJ(Mx#r$h=E}!GH0{)Gqwv2CvKmq#CBm{ z`+0R$rZupBd3@@@A`wQa1c>Oh5TMSR77K<2bHHhuyIz6yQs8-=ILN^UIh;SeIdRtp zx!<@wvW@Y{`^OVri{N|Lkv1MDJE4I_56I^(#SW|<6uhYePrq{^6l8;SJ&m86G2Xr_$Y({1AE%D8JpZNmfeLiX^{!~ao)U~&t(pd zPu0gyoa2Ij#Ee^Fo#|mn_iOUB%MswqV?r@4=DV;R9xpqL<>$PixZmAZx4^)nDdi>GsLooA=fQeIe@(OE{;7MQCjUw`XEZ0=2|Vke zvxo8LB12*%AOux~sMW5O5}}aX)v?0Q1Q_>Q`!{%l=W!nvp_=a@!i*b&c@qEmd#6)p zz=!oYSMVSSYR4y91#TLn z}xr191)R}`x1o-2m6RT-U4$z2-zLSRiw5fsLR{!w) zXrG_s9GA=)0(~JZcZEZ+K56}V6bP_E5O*+T-Q#L>J`#P{SZ<-@nG6ma$J8RcdxbJRbR!2WJe5JqHV z(BH%QgpJMM9E)87+Gb&?euew54_e=hc(#lC>$7Z(sRB(wtZ8+qj|~spJ!B^rZ^aBl zn0R!8Upa%ZS@mvG?5C+%=JxX9_aEjTlr`E71%umqJAG%dPWQ^lkxoo~G+0o``n)zcYlp?|>Hm@`lC9qzV4!gcs z838Qj6RkP%KKPC7CvD;NMe}}_QkScvU|03(yKnhmPMUKS2kx60H#bqJ?KcI|A2w|a zah$dN#r2a8-hUcvvf3j4K=eVLt}hScYA&MM6lJV$Q%`T8L(xt>{^#OE-%mLp zN>-L$HO$lHAUgJb#}W5G(eV`>qI?3h1mj|8m+*68G5fJOLX%kWz+#NzEzq-NRO^p< zx|9auYbkNuI$eJ3-b)=nV= zw=>Rpf0z!8(Pz64B%QLmgM0_r3X@_(c+Evk-fZ#LcN4U@8 zS4ZAEybtzE!|r|Zk3k2e=E-cFxAB&!uVr4rcE9|#M^Kd`QZ>BSjPO0}S7jU5!v2Qz zP$L7e?k31SUZ8Or$BAO25emHcywnG%{>3zeq3?IwSp2K_Ax&SOZhs{KdKMn5mKn7G zCWn>na+n3+IqqAEI{5wBQ92uaTQ_jkaM5GsE<1cgF|rc&mkNgZJ*Ik^5Qu=~+V(wc zula>c`DJn3P0>4M{`0vHAd9WPp(~2#bSz|M=8E7sROHJ+G}HDdVWIA;0k)@?sTeP2 z{I~waZ##bPZ=w5VRjQ_)1>k3r8y^p1J0g2KC+taiIJzd}7D~iCNbdyRoLqWOfV5@% zb0anvQ1|Nadsb{;JYdgkH-6u4r9W$Y(im;lQ3MPf5`g!Abv>WM{?)^Zd$cy6!vSe) z{5f_`F|P=a?TC~AvspjDKDN;3u7l%B1)gq2{C|Cs{P311JqdVcxe7{Q zKkeWZ5w(y70_;oc-y$UhBb{k`9t#}Do&Py-gazN<$gN=~U$d>o5;+gz9TowYdyGr{ z9R9n*?2Q$=!?!`Z{NWhmSu8(%g(X5*@BQQGqTM8OM9V$=LZLhdhVQwsr~4{Rju zkNDupgY?bw39Qh-)sS_R$pes=+7*OfB|<5o;W@iW0yIgCxOY+m-*@{UazpG7r@}f+ zh|C5L}tAXS6Cx7eW{6MCI>Q*w=8<%ef*3%qz zLQ9uhY(k$A;pnxoh9&HW)8x|ETaI}FYNo97*?T-t<>hQO?;bN`w0-ZAXl;r5uJ$uP zj7u*K_8U^gdVBTz6(u!h2T<>=SDq3^fR6^Z1wBc~;pAoN^FG~yX!Db|PRUDrF4npA zjv|C6PG!5oMTZDbeUS5!GR|X<%DWyl!txpM$TX$gB^b~jy5>fY z{!v~H+usoihB1Tx&VAwsrLm(ZT6?-Z=5E6eWsYpju3`PKbEbV{klYrDu!Js?Vf%7d zH!bN5)^Aq6ZNp&S8<;}t+PL!q@Z(MCg{Lg|{#u-B`7PlNE=98!z&Dqq27$J ztCiM9$I%$sHXIGy#qkaWUrF>Me6JU!x@UwMj6o@B(@dZY_H))r?quQp?@2u@Jxv`1 zp8dOHb`bMKNxPr7pvQjin;I93ve;k*DP+oYy#B|llb4mCVbzk1wEzBa`Z|K+(9`xV zl34$+&kq@|opeJlM@a}*?hD}hc#dRe7@?_EGdDaS8rRo6>0?%K-Guqh9kB|$e)qZC z{Xd>YfM;GVM*_z9Vd3iiffbBj=C-u|az)A*^hF zzWNnGJ(dUq%2cESvHvqZple7c8wAor1<#dU<%gQu9)J%{=D=eo!4@JcJ}8*{1lJjrG8tT6^9G`bE0akj$Jt^2p0wx> zODfDqsu~wM|;~GGty% z!+;6!Maj-(ok)b^w{Nf)iDEr04DRieJp!qM1+`FyI_4cj%8FlqZ+SqqSK z1h5ALaKcw@u{}>#X`!KLMN%dED}*O&;e% zZc`-B9b$F?ahG0)ZP(%RI&$m{z;z|o5$Ay?VXmOXh@?N%j2%w74$Pb?q=Ia;qlZ(k zd4t2N4m3J=F4D8vxU-p9k1+@(=YA%$L35NksS-Hu^Cd<`xZ{1GZtMNg73U7zI-@H| z<@lj&hdRYfF$p{!XZOU@FaVr#-;nu_PgU$x-|8{^zUd2l^AA))=%S6vyc5ECLOU%> z6|A4%c$4~%*asqxoO=eb?6`lyDrhm4iU4m0{cN?a2m+5vhSN!KevH$T`_2@8|JUUO z%A(#t6sRZU|4)VpH>L;Pnqu5wgbqtI*&B`-Hwf78kSKlKcn_er2(DE$6AHlYzha}=taHNDatjsM@b zygxEc|2$Qg2+YoBRW4a#UZb9>n+9eCsFEj6$4ll5tYh87zu`L3aeba7KkVly z_l2P+ZUN}#!?Y6=(b!K;mwF$7^M1dNx`%yTPXS>*$-3tc3c$RdzokHoEKvwd?KdL8Am-WfrQz#n=b=`t+jUL|>&~oz_q5P6e<>hQ{xU+RQm-#z zdCS%6GtR^E|3R_&@X{AM^wd%Cr5?@~snqVEbS^fyaSzR~JPZbYXQ}T{VS91sc>~D^ z=0}-xXunKupaJ?nhRAga@WFQa+21^vf9Z?wXE(F-YsfP$<_v>^0PMb|lT%kmfZnIY zx%}Th1xF8;O%@&#fUq>QY6{D3h>)5B=YA|W!_}@-Yk~8VoX>xc;Cp>Qv4&DTBLS4| zIXLirBto6;-=Fs=Xb8{i?Ae{=?7((8elPsLyvOvcwgvOC2vDWjUp2N#gmSFK z8m@TXWHd>R7Iqy2V#aP}^eOx>FIE3mz+*gDYW)pgofe)4B>Zl4qmLh^e&Y8}k<}U62Mie6{XBLU9_!TVwxqtg<8-27;5WC=t{r?g5)lpeJ-`BL1bhm|qK`93C+ySIP z0Z|$eK|&g&l~hDJBm_}X1f^SKE+K-1lyrj#0)o>0o6oz}cfEhzweEV>bLY;TIdjfF z=j@H*oen#tFdgLQpChihC~+zZ%e$REd%q9yR2)9*K92MXC;ko{Ezf+7)fr!FzgvU& z-*$v)eE(Z->XZT}-#^7-I?3CZ-l6;&6Yrj}JQH|J*POQPp$SQTP02G^@PUp=GIv|F zf1?JJ*Y0XZ!sD+_zgRHuUPZr+)Ht{C(Ht8Wt~Cu>CfZ%$j*k+X=uXv0Hb zKkzZkx=U@^TqgjsJqIr3AiF*0W}{GdAH^^Fd8=|6ydZvv#H1k&`JXCdjsmsj@J@Ju zw#7W+qb?3R_XPE4wYI97yb1Hf9=~}--qI%ks+c~>)}wg#{lL9>s*6sLr0y{FJC3y&d+a~q2}a#+xJ zv>Y+rSvc*2WzcMzcHiLwnp?e(-EK1gRW*K*!v|K7lK+@^Z#^fNsT_86^`{4Pd}n-o z7#y)r3dVvq?>NCUP29awz5&>LxaAzs9SuDmQIqn*4B)(oz~QAFFF1Vo z=k-{v07!P@dDVu_WxLa@Te-p^7zy_=0_!UQKo^`PX+y$#K**!;9J769vU6}=rN z5ndRF1;z5ZVk*oR)rL@?Dky&2(%-ELM0fKT7il!rx4b zPf%zheC!oP`%RT>tVhB)d-Ama;HOlJtU>;vdiP09WtC{`2>sdI$LM=SWMnT7BfrbF zHSq%HaVPB9o`Av=dWOCsA)WO>e>l7;x1fyhY765>n^%xO;G1z|)wj_d z8jPpfHE{ETPexoPyIxS?1R71cWobi9GNC`sXM+cvzwuM@V2uf1^Vn50%eH`(CJmSC z8PNHnBVFMn%mRLNdF3qM48Z)tgpRo*9^HRwMKq>i2iWf5htwXs`;g0fE`b!`HY=#Q z{Ooc+M#~j?QGqKE*30Wvt#zaNmX6kfb!6Xm4)%#Yblrs)B+S2xIkSK#RNrMi#>l|D zLYneCuNyqmxnM@7#SH|gnP+auG6MZ1WA-SCr`ToD2?jc(Bk#_%Fl>j;quhkn@>|?a z*hi`iV<|?&BUDY)Bp!(Rq@wLF`T4$t_97z5m8kFQwKT!%AZ{{>vGU;+ps0hBD0&{&_jBCl4b$L45e0Mpej9ds`gz zuM*kMi_IxrM)y78k@pt|1c|tT(QMmxAno5=&bZ<_0Dry>5E zBeDTTb`CHn*`)cT4bn~93v#4K&z(?<_7b%9$HulDwUstd{R}GG7(?;GD5A@0+R%Yb zvqe`+(Y)2^C{p;3qP*UR+V~F&PqFbk!MyBa{NOU{_JvgxH<^h_xJ~DzVfAvf+Y+{X z;GxVx;T$@Tf-vWB{In~SVUiR1-7ElDyzn7?)W_p^>Bx`slv=Q>P=lrvyE1^rYg)~p=voMF%(vqpHA{ zA(+FA;-m%|=hBMTKZyLUEr*r&Vah>Roon&UCkP+ADzHUDgyN|Y=`EPc>VYX%G~e$$ zg6ftHGAxggGJ@i|;I+neH!KN-cjs47d=bOPAcKBiS1Y-&%BBj5wO%I^7a{!9F5uY@ zLxiU_$!MSM@q{u^VbCZ^0Qia+k}BFV0Rk26-~^R7CUIgSI1%Bu7v0|QlOVhIgq7&( z?pzEEI4tkTMdxzx;pIsVWcRejQosGy;(#A^tb3!7-{sxB_VGMA7xLTK6>ihr#eDvb z+x%ES@ms@n0{eGz@U4zfYd6RX=Jl*|C?J2V{2azdj{Zk#VJsjnMG-s0DyB}9%>lS8 z8+`ZNkgo0l1<41NLOA(dMeTGt(sSenSNy_OFb)39d6{-A=<#L#9kDeJAo=#+73F7v zGG&-ZBSF^6p1QJ@3v?%K)t4190G;nCY7ad8Vb({u@W&D1Z-x@4RcM|~&koj{T8PI& zv)0H*5I()I%_}%M3 zc1bGx?=Fg`5?0I$z3+u$3}^b1YLMM?VoKmOMt1VXxB32weLhTiNK8Hl*)i#;(S~g_ zKU(5W$xCtm&{?+np=>;&Hi6hLa%A@ii-mW-wkSjO0L#l4CJ?U0BeJO1!wl58RptXR zANWMZYal_|?j=4s02fw#R@%Yt{^*(ei8?*muzxOH;oA8pHh(NzjsaLVl zILC~q-O_TL;Wx#8Nrj#}ri$kC(cg8Sv3|_j{MrKr#J61LEG(F9$p@;hx79)v?+g#F zI*@3*!1Bv`bpp}3z@hBn&W`3`pl4`EML-i1r|zCjM?3>SY-(SzhZ)z*y4jnS;(~2+ z?o~M}@&U09?noTj`CDotqxY(xVqLNs6S1Qx{-xV7e1QBY*$>m$^+9te(tL|_nS~pe zwVVyQ!Gd_?G_}%yj3S&cZu`AH!VOrKFPV^`=Nh#+Dh5*;Vh3DWcSs`m!Si0WO?rmul?ZU^Pw$f|{s~YqcT$Kmg$?)7veU_L+|GpuXp$ zY6=%P>CPsU_YmpGwG-3T@+x6-vJ|-M0~BY))0_37_Yz%tedkYV82l=rK%0sSpuVhF zMi<1x%%fyYzkVzn6JDZIQi?+7tX+qJ;2d5c_r>RZzV9f# z;92v<=vzzt;Dp-Rh6c*lOdsLDX1B4QL~YdO-}!;b zL~`IC6sHfgTYq%ukH_r8DCr_>5xSO)HN%5rPOgz?iP;DcE-pk{}0LcJaC%5kM8D-kCVjKrn9=#tps3dV+Z)m6*!XCe(+uK`QEVNmVng}*m$N(_tG8al zPFqKutcVX7SNI=Vp*->&=|aHkZas{s@Y)mYETl(p>Dm{nEQA+nEnRfCzXdIHwr-So z3IIoPx-V95Q9moyr4Noy7SQ#fD;3)aItTBKn{-*AJmYP0;r-ov*k-!#eDwe?P;XC* zQ$=w~9#bO8y&QX(9}%%;dYKt4j7frHRwO{(jxhAY-xE`faj`4p;|5V%y5EC&P=BQG zpokBX9lT=gE^rZ@U#{|-jG4&(czpPK+5YikOpdztHV+jOV5u$DSJ*kkHtURqL=S_p z+rg#6;ix`5X7ouE3-Y_3?v4k25HN>#zbq&@BR+xMzs#Y%=>BqX$@~skCZ;OfEYXMZ z-LE3NKsnk+!wD?bVTwv{&)ur+&OXw2cxXBHU;U5kQ8J={DS%nnb^F~x`}BYO)lzet z4uLdC|B=X^l@k4bA-s2$3E^gEOv#OmmEfuT z5%r<3DD&>VD?&J7VSr?vnFA*D-PyQ)hMrW~`AS?}qkKXTVYIn+W$#caWYoJg*98 z-AX2NKP<0Vi`B_K*8bv zZeow}Fnw2m>b@ul zr#HWbVXu!d9-1u*fc6UY+;B8+EOPxW9f58b-POA>x1*4LO=j^wnF$J9`Kj*a>`^mJ zr_7v|2Kg_-|wS1YqEp&rq9$v%;zJo^BS55+xv0Xnhu%4{hmukqAh&zuZQBj8$vwb&Ex;B zOdz+t@0D_EBf;@O|8*%8che@vB{`#dR|c6$YOR_m?9Yj-51ecH06yoI{S%#=L4NI% z+6qySwQn@99<6g#v)0Bts6IUXEa?m3f*UYR`~AaB7k=R7bwKWb{FZJNk#T32H`pHk z6fwmrs?S%y9)E3|8T3p)tCQZ-hm7q622XVU=EgjfHUBT};BH+hZ@Z5bvZTc}AiJ%@ zqq_SI*)d*ndvPZNJxn4i+ouz~@BO;1i_GYKBj+0fpZi_GXgfZx5n_>j(@%XXgyJbi zKGwKNvuNnx=Snt&=0Wkop1TrSKN=Cmmfo{x;fqY&vmDu|UoY5;qzV0=ecagK^vr9l zes^8o3*kSFJBKI2`C}heQ9vRSwz8;D~%LveA%qU~3N zkEyUdfU@2G*nrDp_X;%5;ECUII%u3v`8vBi?}}k>kGfWvk0bv|EB!A4z3=wyiB6Fz zXUydT?Sp<~hYM&E*PfvJwF0@J#lDKr*y|!Wj`&5L6?o*F(fK>OQI;!p?FF`&Tc%H2 z!wcG(DoA}kp+0Cc4HoAq1DJO9ABpTgR9B|Y*X4|G3{e}8^+88R3_R{!)IrZJ$Z)bS zL4Is(Rh9ddMR$x`iZbD~H$RvZ`=Gjo`UNy48l%reXJPL+9Pb4q{%RsI^QjwoNFQN! z`Ip8AGf2F0W@>Va8(3Siq>^o-zT3Gn<+>Vc7;xoW;8_EdH{brI{8XPAT&UaUGTb!A zVruAGr&YLtv2jZHfg&TgBux9PeZ&zqvxqQDcA))8HlGh(KKT8xAMFczomQS|*(B_!Ow6hV!i6IL%(3(%{CwMBDC5G)eduL?RBsXQ zhaSTo?<3?tvohG^aD)%u*uLO3ed@?F_oT1zM`vk~a;_FJO6aY7F_?+qxdot=|5a>!9sCr=9>X_;{eCbe$QmZsFu` z=!<~NE+rV&gmC5!@9ozp4)vtc5t_OZi>dI++#k$G{kFU}Ke{14CzbrkZrh*cSj(*j z|7%;QP7I_nzBq>b?Vn28=Hq6V`+I(klL${!#P7+yKz3E$eCKSBz7HM@sSlGOFfWD8jdP<^^y^8-nJA%%yq=j_{ui8+|nqB{f z5Blzpe8k`Wr>oUSf6IF^P8mwlR7+ALzlEyO<7a&$s=pGw$VY1&2J@v{MS@Wrk@Ivk zD;)WgpNCYm*`)7bO|##vco1%{N}aTQ6P*`jlrk}|c*Eg8!56ui2zMIJET+vscxmbm z1;^iEk2taX}!2;KyJHZ8e zDK;`)I*oXB7E+2s5kLG1pHoW(#2T=0#W9i=**$(yr>Yv{pO}%}e|NLrAA77Ps`##( z4;IF|Q%SYU|{-F6x(y*@hgXZ%`_08{djwX5zz2WItU+@;Qr8TvOrLx5wG1jqNG4 zsnKV0fu$`Qlt}K!B96_rJeTx^`47hx4eXHpzpE5X@rD_caSGmMQ+thVDFzcQqxI%e zY)JAR^>bDH-fwfxG{@wXrFLe~bNeTR_AVehc}j);@J6vDJXztNt&Yx%Dv#jBo=j%^ zj?0V0=tVCqf8V0_CaR;bT-!etiN3Gq>nrZMm1^*()eq0{$Na!hYABu-&A;%K)~ZdW z7)%kQsh&Xg{J2=?8yWQf_$il~i`gugrcjN^KT&?*G-x-FFMx2%3+>k*5P8Dh2Iupw ze|SL`t^UVMl5GUDH=5<_D{WjNLTIejb3Foh+IdYid9 z!%G!dYxn$_UMZ@RWT#21TtsJI5JV(#zF&r zM*GU}gVJp4%mQ>?{PjHCoLxb`M@;(C<0wz`vw-O?vJaHPCob3s2EZ^S-PQOhPCzj6 z683MT2hK%V&rN^o!=0~^13L&0kNS7(({41XKlkQaR<84d&AH_QRw!@VSDhX!y3P!u zbLX$N1^dENVLG_nBa{c{?koI-?ti$sZ)2q#2~8M$O_GtW8MR&GWsZ18uz0HUc5{m{ zOjJ$bKZp8s!p0Y>;?Vl+<`NI+`tbnEP2kfQrQ!$7PAcXpD1K@1rD~#NOu|YZKYXKr z@F)^(ZL_FmW;{_m^XiYBJJ7_2%bO0>E2b?<47PbP1Ic-6wq!YNC__5Rn1%8qPlspr z%FsUY+(X)PcQhafdb5>`=HI_W?VSdi|5{n_%mC^Y-cf80%+ZtQD{4#N|60HXTmc{5=CSY}BQy3Sf5_gr!wd3$2sLq_dbW_6 z{82Vl2dH}SP2>RTUpOnBD>H!XDpepqxqN~zYb|&8$~COI zu=(w0gku|)WrcU6^TkzchO0v6B(#|2I?_Ii?5A6)#3yv$pETjoxUM;jt}V>{ufC{c z{`M6PG;clpfiE}Fk#n1JiJtxhD}c$4arV&z*u9pe&vb~#zF50H_b0+{=TwenN}=&o z#jwU!+FQVn`1d((l%G}Su3AZEX2!jGY2R!=vw)K`HkbaOc#T8uxwtEe*IIl0PHq+I zAwKq?fgqIEzMgGHY=iD66|R|1zc7Va+iS^`$lu2EjOA1eoDqX9$9~Mzd7(Ne!T+vIcuGT|fFM~Tq0#9t;63C6 z16L}p$Lvz#)ek?P(P=S+wi^FLbkul(m)3t*X59M(&(2kfdV-(RSBm@3*})S-RmEmn z8l(?cXw2a42;YleTjz~Mx^+?=D|t!>Fh{`W9S6F9Fs*d3%EJRn=Ki}f;W9i&czxy@ z3EjHhMG|4WAkKmJo$+&Kyk=7v_nvUV_OxiRXJXu7bi^;K{Q@IS{e?@h(b^Fvp7n`1 zjdV;FwCcv}1(|V|7HRf8N(U@0jL^%N$PH4X|GP5cFK*r(HoDM6&@ra-rZ->(H>|Ob zQn?g(a;lugSwSC|MlM!mPl|9zs{gLcc)aQMb)xcm!pdFI4n3sH=0nqKYimS}o0N5F zWLkb=_f_1n7$D{wQjQAfSt|gzICIV5pYI@FRRxsnSd_2YB2=1i9zWed;F^swr z;Bqw`t?%GSkJ}hIezB+;sMUXVkr~>n7v(Ayb0nvqWPtI{_r#0)@bpi=Q1L< z+S&=SUvA$t66F9giFv7&rnGqYk-?5o{|>@!6BW{IN_LRj8bhJZNR3B}*T0j^?IZ}_ za{Gm8BYw`}#SY(0Iy~*2dQWFfDC^iLo*KEjfvJ zjX2LuS*qmH;|dqGEZTj(5gK(*wBAB|(X__@T~QzREA?O3yuK2an&YFp{-8XH)f3Ii z0djmXXz7RJh$~ielxkh7gb@^)p6p$2JAlOIx8sdO`U$FM`&+l32!Pwb)_j_g2`5kM zU3oR&k5#;OUifg13p~#F@5+FS-e#t5&u$@jxc+W-*JT8jd+$$-8}CCgqloVzZ~6%_ zYBu~0bzFd4>%S`lp4+BEdGlH`L7b~*v2lV5IPVB|UKalaEhKnD&8nWma#^>}EKM|k zi94Jvk8~MI8^|fT>3G6Ilb7uFh!<|YU07t~`VssK?;4$;X*VI~&0U2|7v#tCjTu~$ zW5iPq)eGpHv|%2>J^b=3X22iyhs)t2DSql}NFT#UFM*EoP+7bV=?U^5M4Jat;YX-G zHzpBx5yW{EGkqZw;871#K72xqi%YaA+yDAO_?A=e`rDw~D0B z-(m-i2lw3#vZ-;|U*kUoZ*~$cLseZ`OBSFL^)jEMgADKQOp^LI*+V!*8lbjwnE}LJ zrMxgdz6C#g*G}0w7$A^&kb+J_q_;?P#P4kd1)gs|Sng5YO=!ClI>gI__#$fA%A`(G z;As?-HzOH(2;y40%iqlCfRJOqq^8?HsI&8Pk)${SdNlpuiBdrE*kSu}5BWaS)xZaZ z1AQP>*N1QNUTmPSNdIN<8YLchJ(~2UUKc^%zA43Bhz-1347<9lO^FNSpDSVh)J5oj zJ}0O08{y6;yPn4MlH!q@UpPd)dI>uXVV%@dtl(NAXBunc5u9w6HuApv(DG z$W;CUWPj_qe!^sgFn?6DRaTJ>sBA}bBzq0Rynn1?*}FL8TTQ&v!h00VvWb6;k@^RZ zu-fe=Q4A9TzR}sRbkG2q2&o*cE6eb@5dN*DXP7|XwOgDeW(P+71ZnQ}en=Yl?1kQX zF5-`JD5*M54aRML6*M}`!Q#=By21q?=z3~Hd4)g&_#>TiEV~z>PSnM!aCd*`$i*OQ zz0C@S1@o&lSB~J=$u!&Ca62r4Db>;_lLejQlJ5!>$nmR6GVTMv95Jcv`q}zqDzHUN zlT70<3s0%(-}62@N*K*mXFMiE1-w`#6oN8m;PV!rwos>0Le#@x?cE4ou==^rR6l|l z-%Oy`h&pYIk*!~=Kcr&=SKNQgF0)hORT9sA`oSaEtT#u-ZG-NIft;~+O1wPr(jBtE zN04^lP%ov95@hSzNTw1^!_)U3bvOFhVgt27VaFdKeiDHhwoKx2sI3uu?St1FI8&c) zLR-!T#wLnX%F_E`+)FN_-R%NM8O%0eQpg54JHmtC8&Tn!t#QuRWSpRK#!E^0ssF~` zCdK9c3)cQ2*?r*e0h4)6hK7(o!x}N!q;|lJ{}9ReHko38eYYVxYKHnag7@<7_E#hQ zg1fTwpIo9~U~#S5Bio}u|9j%YsN`{|LjGt~_)#&WBVn$+Vk-a?sPC3@^D^QOM8(#= zR%ydn-Y|PLR9`Abq8l)~%Zv{@Tq_?Ax`P==_TNuOdMGKm*l8j;RA+Vb*I|;rG2EWO z51AurfuQQ-$uip&m|X2C;aHH2t+pT4x!{0sk2d!K-6>}Lt*qq32W~OYjM4zk)Obx^yqgV zGcNa#46l4+h>iW3k+x)F0~qP-F59Pm*!7Qa>S|jdJnwPw#d}FMaJA^?74V@CW=Xx_ zpF4$P98>1+6;U4<@13AeG<(QDoKWUHSM7i;v%V17-r@yEqov`>wQkj&Xc87CAEW7ep9aUCs)`OEUi-AI?kD59)9~8+q90K=te}F)6PReu z2L!v_@@M`qE&7E|iO`;Ei9A?&+d_XjC{9L2g$JvsAAHDSNVjyH|>@ z+adqfmGxQ=H0QH6Si0gO;tTE%E2^*HbzK1{-Vx{|=zRaM*qK|f7N>fvF{uMBO{8Sf6m#Jo^l#MySq4e$T$J} zbrTF|Ushp7L$n5xV@Rh{OAJJR8^EYPwCwJRl|psZO!fT;K9Ik{fr+=Ex;tWN;Z3_V ztlI10w&WHM@HCgL=*eNiopSG0xl}~KwHE)`rCn+;xjCr7?l%r2r0%>E%FKsv1UIkK zhteS4_Q?i%#wq9*!a87iCm+)2L_GShj(SLO_DRbsGtQvU@*weT4EB}1%yaP*>hsK! zDGuo#fzO(htcj^hpiR*w?(20&0a?nJAf@msEd1Qi(@hl(mEVn&eMsg4*a5o8FmZ-+>7jdjnDQC6fI?CIUaj$VqGUGY~nry>I ziI~)l=3OCAK46e(QiA&Ia2n_1f-^j?vD**x&Z@bgb2$#tMBx4KrW)5(u^%Py*0Dzq z9$3)=_h7Ci{$Hce`h1a*2ja!@j;$oTrlkg(G1d!V*1uqa0E;(2=S$3;)~@W-JT*}H znS5GC<~Ovzot|;-K_bLz3J&WzQGJWS=-zAMb%?vSzY^Lvhf`;#o%yAX0t!}6wKlgA z7`pA5H@#N@o3q7#O(0&6_U85gQSC|C>qJ*GBk%#b&BC+}#N+LHmu`@I^8gz09QrKB zxI$s0r!Vgvp$6fnQ_IPhW?`J&)6}b@@vuHC;^|329zZsvH@_6gh`$yk=P7kf!^)M+ zWM)UX!Pm_kP2x00{QFI(198)rn8cU1nITk1twXK5cGQCzS2mF)s?ATsrnCb#F0`Wa z`UiV^d2>J1c(f89$P*Fg6tKyHWCwP#({pHqV^NHRDdvlmT)QoTp+o#p1sFaxT8`{&{ zuHK1Q@uwQ*^siKa(yK5wCS)9jHtgQyOD)3Q(P-UY_(%ifHZp;9!vY**<+srJlZmOB z`$_S6Av>dRhK}^dG+eQN9qUt+hV8t{s*ece0#C%seuXd7<3siH64POk+ zvQF#2g!1I3y)h1m_w|Utum{-yB+GeczsXS!FUYxx4O~Zk?y;X|QKJUfG<^N=s?$9v zTbb!419-qQ3*n}dI3q4ey*zc&{3X1dCR3V${O|~B-r)A{qcF3$Tl?G95=^|f)a<=E z6<`RxB;}bu4*j@t3pDn#p&tG5)fl96q-1^SM?b{~G$PV^m%3gFN0gb*FOM;Ti*FJ; z9q$Z6!91H<@$wpY=KBNfuP7gFb)DVs9nztTATRJD+>V8x=34XWsThF_(l>UV-Gs3g zwIji?MOY`RFC%vt4LFbuk&2NRfns_EC!K0=Y*sept$qy~5Dqu`Jgd?VPskQ*#blMk z%ZO3=>pa34ik^6wav(g-bMn(?uXsq39{#a63)K@-?2F+1BTC4h@bZALl}(o)BA|l zZ=WHk@id@>)qdTIZ{yDpaVo8+e?riW&6B$4_ zk%#=`S}9a8y-sox;b{7d2fF1WKd=XXMK~S5G-JP&18jMaUqo&`a_J@VH|Wi?y98{X zV^Tk=+zXc&f%(;(ZvtP3;C|2x3Ld#eOm9RfSsU?tU;6s1U+V4jPz!G?5s8ezNwKsO z^g3lQ!eY_d&=%Q4y{98{Cm3;xYsqpP^oiKcMpR%usw=DZR!EA(81SpVRb%}^6JR@! zK+8SUhv@oFuiHDF8JB%~i<9w&KNb;uzT^20$}c);9|}C_ho&Usi7B6|VeICc`fByQ!vQuv1>G46;|ps`S7R$B{2D?C{1-Z0i(AU zPqBUWf{MyoT4$&{1f- z;s(tsH)`B)2AoOkOD-{OHfCJ%SlUdM8kll;S4#O$!m0_48(->+u!IjO6v;X$KBbvY zI=DiK%dh#3cRxwOij1~HY?aV{`O4_3B0dB&{V!7S99BSzcT4P)3v?h$?XS;UrOd#h`NZJ18sBQc(n1K9ipQk%p&QgY5ZTfPbNa6+ZzMl@;pvF zsd5xN&^SHYzOVvKUkdFRjb&lN1;pYnh7g}>Kf{_u$R2#gdwI6wSbec<5J|P^SO?^iFWiu^KWJhk*@jC`9aOWy})O7L~z!URD0!Dw|pDVLz0QpAxtER*3u;;<4Iuj6ixsYNYJk z1k4O0i|0mmhRf+`o{k?S$gOeHpW2&*vDwZ;ltNZ8>g|vHA$u;+`7*5j-h4llOpstX zmlue!T;uzAVt^BDxr8P!Inv=DtjO3F88fkV#(JfYam4G+u1Po>!H5@qu@20ai-8o4 z6lYmW=)tjYwOMR>9d1dEj45knVv-!S{TEkRfi-)cw@~5{+?%I;QRDhcjC|vAiYGTa zXzLg}p|whdcZj_Yv0jP6I&%7QQqLp&-}S|Z0JPs11nk)2$%PsbN-#tA=w#XXF~}K-m4!FI!3bS;QFetapt`Y8I^jtl6xY-i z+DU4F>^&oFA;@pZi9S|#B4HG2+cr6Zch%UreEO29V;o@d+pZ$J94#*DCX;S(;{hD! z{;`-r%nE3qIDEN=;`DGL(%p@#$#6O~`=_`t8#u+MWX5rk5@%GAHevi24Cjnvxu;Mb zbkO!lkD+8Ar1;0<&3Uc~t7OH9`gG~R1xMK`Gs#iNeL3i$gs2`1rx^<|dwdiq5`_m3 zsjt9m!Ezb5u4F+oV$Ii`R!qP^d;9Q=A`!lKnVKY({4J&<$VR^NhY6HN?Bdr72H^O! zAlu!*D%8IwA}@u`S;fMU?%ps`+?~amQ#vIba-IBzTXvxD%hHMHXX$X8@cH{$uktY| z-Jhq=BR$}We+*lzeg}|5{Y##uPa?+Na)=)=Fo55|$``2b4MTsewP=pm3Rrvjp5R&q zCHS}RdQSE96qH%`AS~||hn+YX+?rX8`e3bJ+`E0e4<2WiUdtBxg7Ll<6gPgx2uLbO ziB(gF;Aq#|2nw4rcvO~Q^*`MWm5jZ{ksZ`Ol2TSwuZ^p#gLEa=2Cb0_pE$+7;wJ>Vr??#~#&cwZNC--g(KWK0sWBSHQHs4+6f$%;!}N z(ED$c*;Wc4kPTeu9ie5$Y42LgK0^M$!?R}Ff(SpEHaNqx{ACmlaW7o|w~&w7Cnzn2 zpn7YvmD|~Yq@?(JNWM{`_!je3;`@CO?W2wI+Y=WfcOla@GiUeUTa3kav-)@j9dKCg z_xhVV37>Zpl^r+5F)!A%r~mbZRueJbix(J!w7!2Isp>RfUv6CtUkRZF#~BWM1=ogQ zQe9dZCRc}LZ9Pp|No4>OZ4^?u-zK1-yDrs@h*C&iME#<0lONCvTADZ_JVz$8RU$Pu z9@fmx^))C`f}@{~GzA%s!#BSlbs5yb#Pa!Q z^DC$hFaM#=(91qZ{%?Y7N3s#q@$|g7!Wf-=AF}Dm|23mS^%5O-$X={6 z;U*xkUJ%^+P5i z>jq3uIr7&84J8nnt0aF;Hv#W=Z&FQ6`5_&0Hu;N)2URe~+GK@q6+Sl^kLLRM5z{7? zVIVd@{1FbG8p7ifP@ZV4&Aqc8+uox*_puuBh6H#DhlKUP-ZJM|>+1~|KV96@T%@nW zLls(>{f`D`(;bQkewK;dur=#hRA2!jyHUoDj%2tVg{Ke0L7I-6n7;OJcx$wevbYH1 zE8c0g(yYMb{;T{=d$f;gP92hu)MIs;y7B7W44}{ZR;fhFI@I7T$#&w+gT7jqt!ejp zfL~x=LhX4*{1!!O{*8q?V>D$uTDN2Q>;Wf&`q3< zPVa}IwHE@;Ka|19;KL^-cPW7c)@Q6&I}X=2J!kh@Ucnc)FH@K-F@Z&}GvrrBjE9yG zo}F`x#2RZGU7iOqfnrxn;k1AQSY~Gy{oWu8mRvnJBd?D5O1yLC9-!f2SJ?}Dxv5{eHhf2Q;AQ^&&l!M%@x&AXjKdN)E3&%7dhAEJ#V2*- zpX^L~ik=(phj%U4Hokn$hnZJ?3eckG_DQ8y<65&&%h&Hf=}{?s;c}{gxt1R29R#1* zlOKYe>?9iWR*l%2+cVpWJjCl%M-v!ud>Gyew~mRUFM&yfFGXueUwmvue7h0+g)43Nq$(W2m?qlTAEVDRv zv$AE2SnDWY7Fa5mHAd&@?5o)e37@f8OSzeni}XPBxA(-E)_?F}&A~v6*E_gra&7YT zC8V365R|%noEU$&tQCCZS~@IjLY!GdT;Nf6k7U-zqqu=lS;0}3G`Mz$sjcWbGhiCH znSNnl41RBQNY(h(fLSxS8um3Xfn%2>>f#CgnErm|Tc2lNu;~YJVzH?HJf-2QY3T+t zZr_nUcE>juBe_ufa$KAV>2q1e$e-ASe$P77?dIRZ)6cc#`Q?$0CU7CriTn#c$Ne*t zzWWxdB3qNkc{#x<9lOX8xubXyn_}`cq@y&sY;bUboer!xzwNM;T!p!hV@`bHN`@W6d+Ch$uha*LeCHD2=ctvO6E;W}JdRRC z==@K#t{g`({tAp}eru=M7V#|fkS4N-^us$HCii3s9dO0ZDR1N+Blyg_#$~`g1347_ zP7S%1LT7{H=@kzdfT)H%)8|ub5I20YopT`%o^Tqz|G=9G>_q_jiSj|HQb#murCA22 zLMjH>VvtVQ<-}J-3kdhHgfUjD>6qfXe)?bNJ5J;eJy?447pi|e8CtVb3>ma(5B_i> z967J+u^hz!oG*!2@}q6U22%E$KM&D^pYNCAII{;~-aW6&=QzK@Cl!EqiSZ~{e|Mwg z^ZGFC4)iUOH^kva$lB!l32u-Pxa56Oh8{mP=SVjFIUQ=WFan#U=)g>uL-=q$ z$nhf5@!1IIRBm)Yba3m3k2_d~gX`VCdNWH@p@D)g|O0sLL3(}TaKVA8SB^}OVIjBP7)J+Y7(m}XjW zpQBxXvSX!n)O{uJIqlQUE|i~QcB7CdbDW2Ca&~u>Cy?D{$$Qm|{D&LjuUj=Ld$H=n zNkXB*HyA#z&$1E12*M>vn`_?pLC)W8i@7_k(1!Jk+>r^yS9WGoS~QFfuVG-ey2gqx zsJ?bTIQL#|9tp1gTQ{D^J00p*b=KA+9TQ_I18Pl$8FrX z9&4EE$K18d@2;2R!yuM~$3v(Oh2;M=Y_Q;u?b<^>bv=ZNPNtio8w?;mo6_LhP(NHr zs7ZQA@eMu^;Iuz~pB`vdr#|M~8iY&NSW+KlG+~LAf?BjJh}VYbeDY<11z1FXz9+B0 z9{Vj^P%oE62mH=yP|bA>K}pe-S99Er7>{+(^h`Q02;$wi{=9_}fAjRkV~JB)Sm-dZ zRkR@oc$LQeLv@}CXLucP%z`Qt+VAt+HAFb%%CZ-^^A&nr{lvQa;Geby>Ps<1&cpY|lfDn3d=2G_r}rbo3uLk$B3~p-0!(e(qemv4 zVd<%r{VhKxFnc^`LXv0-_6o6bgtj+ee&$Dqo^CLKFzKaq2?-*6uFgC|?Q141-r9Y3 zh9)el0Y!Aafl4`+eCgZ=e{q+wW&|+(EhRPPD6i~DK@`FUC zvw5G$81PrR^q!yB!r}bs+4SE?$7kT>8lk{u8U}Hz_=Y08XTCK2T}vME1}HqO{8K`O z>&EKYzn;s($j2Eavd%LBT21BtbmnC^tvxq4Ay5KsJq*B{R|W>V<4xW z{s6Z!+h^jD&Ilavuhl^HD)nndN-oZ6F!0n}QC(7Y#3wdeOGHYITU(SaxvDrq1%HkD z)eT8aPslPY%79+}$5$kMb1z8_QkI_d=!b`#oapy#eAg5NXF4YwVaD2H&%XM)G zW?4;k7;!XUKj%uX%{)MSkqO-4t}ScuALV{m0ghw$=={zxYjOgixDz!~RJ8b_SJ>Zo zIr&(l^0K0y5C!`zO~jvYl00py)B=jxM<4&wMG3avX*?O7n1H*CA!*B421adV`@3KW@#@M?MJ!%j zg-j+_?#aaz!}pc4mQ}C#!2@CL+nskA@vQ^yv=hY{m`8!psmmp7pms|2%Id}fbS8Uw zvzMq4*3v4STtU27_B&vO#fu1cbE3A^5Ke)K-E}KxB$zI&lq0L+@eJ71N^vA9i490dw@VAr zk>OGGLS9n4x$tunN$iOWY@iq1t$XtRHzdg7SI+Jg!r7F+Z*Vrm!=Ai?z1{3XdK+Xr zR9RoJlXgkhCsCj3S-0VlZy)+G2UXvrcda2beWM@7ACB~B{_-kayi1A4iJ45^XRW|y zzO^fuJ2C@_`Lm}HnH!wtJ#CnfUWc828lg<{logbQGvwrd_y>Kh-v3!YQw*gd&0KzJ zPy+8fmtXdAqfjuZQ17a12G;C!*!Ve{4OIU7!g|uN8#CbNYwQT31g{!r7>=DEg~RrhUg;_C zu;<2(Y7oUc7b9yQU%#^jncY0p-}KZV9#J@aVw?-*d2<5;r)ls{ecRP0UZvR0mV$4u z*Le^>%Vfwr1tSjPO;T~$e2m^=NzmX8;*He`xcxk675YQn$33}qm_7DYJ^4I4@H${S z=V*NdSMtypdDB*e&GpJ;Wed^+{Y#{m7(Y%xGmltZndlOzOA#rKDKY_Gd7^>i+^bNg zRb82p7RThB6*MoS`Y4&^#ejjMyO7_owSa2u1JpmVH0ajG11!F57qXch!H-eNbv(5B zfU&gvnp|k%1STR)1y3eX9aLHB+&7|P%(a3zlv14^)Rw)Pv>`(Ey+){S+cO7iIlmyr zX37A>9@u8KzW)is!+WR7%u1l#R6JW?F+bw*rlPxsaP^QZA{U>HXsG#nq|jO$@e$Wq z*6*rRV~+9Pze;uVLn_0wUaDIRVCF32dC$O2xH)z=R$dqB8Tt1(J*{Q~DZjF|eeJ1m z$KPCz(IakH%WK^)X)LHe=+fzjnZM~kqW#-0-Z(=zl%xr%RZ#rGkWnIkz7Nw|43T*z z)(j0Alvr;3;Ra4e^(=KY>dDv6)KzqrBr74t9m z%zoNO2j-M-M2Bt;L6L;rYWKQ&OxyZKNwz9KScy3HL9Lw*?^-6Z%Oekms_GkB+pPn`Y~YEX%k@k83-D)c;DG$qT1-UwOwMx}Hjo{9T_>&RFSJd_ z4D}kqF{hQGNJUz7o_c1keENdwphli_zR<@p$qNQ8NBdcTa|->_Mi)}tTh{nim31NZ ze>A;!AeL|3{%`NSH=z`wBnfq%QCe0hp@B$5R3B1QC@HJRUfFwOZ_dk>Bzw<{Wbcvn zJD>0GdH(93{&C;;bzblDeH_Q@ps;-EY?Z(XHDt8OOe_}Bty9N!3m9{d+P^R@VJBW# zI(~$prrN{0l@iTmrXujT;I95O&J(h!KdYm3-$V|V?+9*FWTR&(=_~}!xz{?XXPWOZ z5nJ4_GrBAk@9F7xmR<=#n$y+tvC#~~(!IwjXM1t}cj`b#80J%#T7Ml(0l!huL6_4n zVyi(_Y|X~y4IcQRE6*~@j*5`pIDbRiJ{2u=IpufYJ_5J$eAI_niN^hjJV#jJ&MnrvjLzNYvgnFpqgNx~J^$!1k{5(T z#(w2H7gmD7!BlGZWI9L^K1s&>7ViT$*X7mxS&5Y|5)I}XUs0;8t7|y+ZM&@8@zef6 zN~~L}C0!dxKrOR9k^jT5+<7m>*rkg7S7FY{skpB*>b=U#^V+y~?Gj=4)TbAzX5Vi6 ze5eMjJkU($$9c$q?RO+A-tMEc_20e>DTSb4XO#X{G8a5@q2-Mx#{fFDTZc4XWT1&4 zf8vz{C+yJ~E0wDlML%~HhW=ROpx^|#`U`lE`oxM>>1Y@Yku0(k<{^&q>OGX_f7H&y*b)O;_U ziXhc=GFyL?4fx(fPdIPz!7HW~tiO`z2xpS(>C1VE=+c2=bN&?p7@`S|RHx7pcU})# z>)2$0l?9umo7yz+n!&+ICzTOo<9yQN=)(|@tTZ7bIL{4Lo;rNIGeSwU)<7v<)svy{YBr?a=+w33m+9s2!Ce*~e~8GdUm2{z(obNGkfO_px zHY@xCFJ9aFS&Ui+s~CK;dy&#X{)mDX*awwqe<7KTjo=&MJbq9z5~*b0VSJLy37ezj z8N<9Nh}_fnY@P4s00!9+r-goQ$ZWdS+I?mNd5m>k7i-Qy_B}@DlziBroj=`BqHr%@ zO>VVbr6@!ZJ3%L}Zg4^E(hr~bDXEDH_o%al6$$8JPTr;9U0%r2OrzP{K}p!UekEH> zPC-43{`cjq@LtZLvDS*0iRd^;fevC{Q=h{ci&hUG?y;&dIA2CW_$^=d@9@h3$80sb z3d{wd|52au8<9*zfhu$P8=5DdV;v|L{j@h0=jKhr>ltfjpyvD108Oy zqqBe6^Fv*V!KS}#g)N@9-%(YPvJL!3tfP+XF)H6sthK5H^EY0YYGA>hSG0$2%ukP( zF(sqMkZY&N$5~)lub9k}mn%s1ljUT~QYK2iN~2bTbtM&lZ9xuKGUB+VR)uGM-P5@ zUHFtoPZ1rlqbz=8_fG<%FjFm_KhFc_a#cJ_@V@bCsY%j=bsAbfCTuT{&;O0!E%! zhbS8I3Bbu6pO@syw1kxGyiLlXT)^_Gt5Q#y7oG>-Sk1La3B7u?(2|2`NK#&`E_5C9 z;!gd~zwE>!ZAIG~Q{t?)qZ>nfHy1R2IiyzFK|)kVr#`CuSPl%#Z4JbYc_Ck@x=MHv zEwSGm+)m4yglv+Ji*@5ZdZAsh+rBpRg!4i3)(^$8=*aHFe7ivb$Zrwk&~S{JSXk6I zWls-B`q}OmAFB$(D^GNCL<^Y-Ir`&$Qv$dzhT>t%3pIA=mO3w%Y}E z#$^&izTh0MqU-qc?^vH@mq=x}o{OA4-#X5$al=fTC)bD4X>iL6!Ja-JSBZ7H=9ps-&upj-8%?!BJ7$UrDO zt$3`Z6OVW!Z+OQiF~jup9v|q)CQ&D6;^HT60zCL)@W}=9c9iAi(icB46DKyasYT1e z5UJ|s{ri&qu=)Y{(yl)lQQ&8(7DyY1O4W2F`A>7hbN8bnWX5)pix{^~QhWtq{Mkw; z+0F+I%f)ZMRiY+xknES-^a5b^+2lqi!3pp47aY7hu#ZZ|l3c%9l>>D-{3xFvAV~`Ki5%ztVp6XNI=ijV%{Jf{5%TS zIFm8b6W1J#I-ZK<0~SWv-Fgiks44Q%++dKNxbJzy+9@>{Db)SlJdOEj3hpBJ1251J zK7$8$iDQXKe6GJNFo_GkDvm$xOu2_njH*4ptCxjF)-Ku4V%_KdnNyS!PYcn(lPSBk zhCN`ZqO)c45;x4rrIkFpvV{IKdlloFQx5hvj(;uw%MaDhOdg0Tpe71aboJTN&oV7MAyCFN0)|O8K3xN0n5CJ_Om!&7cOw{_A9>*WN_Ly>TBl@@S5xH37+Z*u*G&OR+=03JjfHhu)Ky$;ENLn$18v()yv|FI6hb_b?EME z9&)1hopj!qW+GZ|pexeh!ThD^6O zSGTp|0EMVRwgt{l=FIIj@7u1Rd!_J@OhgWHx%*?Jhlvf+Y|2UHu5BZ;rc(7?g={d< z^6{mi1uN8G3h??NzJv0W>oT4ueMQphVV*)a*`WCDLhzZze6U}C|D4#JULei(QbJ0E z9X_PAk7PMZMkJ?s_1!AAL4O9RL z`csM;_wgKcoYr<CvP+q211sCSktmO|YlM-ux-wt$-VZYpCrfUC- zY%uBJZ`M2BYe*i~Sgf?g zGZ4Fk?(_xO`WsaOlDyuT3KGl(O?Hnwr@%yf4wGwFn>9kS-5uq1KX_mbi&>*67d^4} zb?cu)O(uBxEdI^rXt6(ynuq!*>Xcna=|sBmv(Gp>~P|%Oz%Mta-yRAo<)zi zAG+gu`CQ=`=DtoUT{n!u?|lzSG3PUJpy{%KXcYdOMO05fvKTT#>%K;je^Wjfll9XP zNX48@bkYo4PLP@h-{)UPtH3!9G1>qAVITg7C!Y%UH_)E_y?~bm1W3%c*H;?BexX*G zLrhP}h|n7uQMpQR{_q2(?^T>S>Sak?KVNSP9$Mn_Qc$* z4YaC@=$+fZJ#L-F&-U_2iKXC8PqK_M&}G`*E=4NzfBj`dtN-)wm4)|#$b|E`9v*IZ z_<@32$u2cvb9(e0_lr0*Y;aI%Y#Z})-K0;`CXx^a2k#rY=w%@5#}k$_^@6Y@#LsEo zgN0~R)YN+66^&BmYDH;q9`%K>PO=y04hkR@5qJ~x4RHq-ve&)lh7SwPntqtj5SRa^ zZRtB?;od`2tLQ!4o8U<4@tm5PU|n4o3${!_cV>;+)P@D&s{>OvPhFrR?6?;syLp0e z?}LyC4esd)`e_mGDAffRM3XmX3hI#SgvqVV6;`+>)tk{$KaSQ@vmcK7=Al!aKUMYd zIeD&h+~#j474cQb^9Pdv?h_v~B~#JhgfBMIJ_jt26Z85zk6MEh(OmswXNCw~_^OrX z@8O4}gdf|3F|F|;@QSS=;mB3210K@KHJoh&biHachwFaKE=oo%=^vX?La_hSYo(0p`2_0kHOw3Oi~S+P)FUdm|M$gE zL)mOG36WNm%u6Zw4aJ0}FbDx=_$6UT_@C4&(z8yk6?_|q3NuTAi7y9COn&fPzIq!a zzNULL=bVK)CVuh#E5ke#-GYbuWdnd)tBEZN>sG_IErU`gX<^>zClK;v7@0p`ovK+# z2Rb~9edqIe;3ML)4|@PTq4>V>>ts_jq9++O?ZD?=Lk7Qs;Z7U6O@v+3ZfyZ?u7}@J zz&wbp-TpMFzl%;>T+FPIDg_z~uV0$rzqjosQ&0ZUZDh``xqD%{3~0aC^R35Rm@8{j zw!BB%5l1eunaI`x^zRjluNv_~jts@g*$pN_;rPiI+5cjZ)lC7@M(o%9!F+-$$Z8D@ zQJ#H6p;!r?Y5x)3IxY<9w%Lo9@%caMu~a45Y>)UH?yEWAoLBOPzM=y|xu{;!-0%$c zP2c_f#~V<_&q-$2oJT}*e5s9 z6PGe)`>Y;hf%0O>iq93?uqt)jIJ;~g<>V0V>|2@W*?DU3-@n-5dTc(kbR7x7E!nd! zZ$tAF0ULIC4y z-AAgQal(R&tB%jM^Uz%5$=|HyT#fLAX7z=y$$T=&&)K)yN@|1 z`xaBW9iLeU&zwW9zt{ZGOkvlQQ3vJ)n0=3o)h8$ZrYMOowj`i;+wFJj&R|{Dv`o@u zZ4lMCozdP=$VVz4yEX=X^T3YZEz;a4@%%%_CFSjqjAluzd-Ugcp`-k?S3>{=@mj>A z_jyeU>ie#)xr6t*`r1LSp%K1Ebf0B(x{(ifeLv^?ox=QFj=9Gs2is8jI}!22rY(S8 z%IvhvHv!ms)583u1J=KCZZs}6WP$9P!zaaa1)%unjU@Xv2BPRahkm494*1Y(HGBo< z{+^XaB$_wwAn!kq?z6g7fcwXt^Pge9^#5{Hh+}`FG(>9cKv!CZ7r?&y{|XxHoVs?v zdL1;7EHOZGuYFf{OgLbp+v+oYEfS)PlR7#`D;>ExOvY)3PHY%@~c|`h$HSdov9l0@hRLSo|%Wsy8{PWh^N~ z59_l!XO9QGE}$jkGW z*yFiB*oD@7GCufTY(>|~11(p7VO{dML!#}!X*3f+^~yGo0RMqwDk<2fQTn*D(ywY5 zNhkWu`I6KC(#ARKLSq_OUU^yeTH6S^p?I;QiY)-Vc|{s_0rQSM53!@C=8MQd0`wfz zr~=D-FeN#S2DaQde%>~25E-W3Ecr2?47e9f-{OL0_|bfdtZ-rwrQdnfUX))A6rbw- ziW6poSLPSb_%r-N$`oGCZzA(SsNRrP>?_<~l5<2^NTnMsE4t5R$X267@0ELb9W*eA zmO1RC)EFx5v>>Z_?TYyRJ8@S6_c)uLarUYrA3=X4D<`#|yg?kcG7;gdxZgA?L(zq* z5a>m8r>vFtpoNdlwx_SM!NhP$8(qi$nTI_B&S>?b#xs;(a^$(8`mw2>!Cz^J&dIgW zvn**KGSjVi9&-tT?}{AgU}PsaNHrDMBOap`mTBRym|t+N^u`S7#R?QqGPujm*MoX~ z6s)K!W8R-=-1^4b0ubCVHoec)1Ek+3e7uM6LFVTBw5L+Hao@J4Wz<{+Fc#g+l`6uY zXPlaTNpBviIIio)Vb_Cn7|u=!-r$BK7tT5;#gh_JC1g)JK4+re)(my_*O_46ZH@mz zy9W^E!v-MP%N`Iyvqey8Mt=8C6W>ivM(rl^$ukyjDu;jDXj8SgQ!3t1^; zx{(n|B|oDU_;bN;rVTT9%x&2Fe-9)(!9T-H+w%4mTK1JZMKZ<&ANg97?=LYWWrXdXnS;hwvGYpaH7BN9UQwsUw~Lk5~u z&5)=s;D=}9CCBGIv7V^fwsbD$D++|O&r`Zsph5Lxny!v9H2hAbn?X7c>4l2Mi&Nu% z-mpiLU#r-N0HaA)DvJO#c1ftTl9LsVmH*IY?OH*OqH>f{HN_ya=8ZtuJmyfz6w4&c zuoB~E_X8~Dv7XND24AXj!y9JjKaBn zBx(oM^9gultkAMG}7rgJp^>l;y2Z9@m zZM=|L;&u14cT|KR`FxmkN)d?Hq`z=im=D^DCccxsyo(a%<$rxANkAOB0`Ft-`A;Wk zz&eNZ$K3Y63*nWua&=! zMteT<7JLBfs&p?;cbZZV>*B*xAAS^qtm2lI+G2hqsOTy!59|y_F3P8-&$FJXk;@ANFDbvEJnOo^&eja*(cS0F{;Na5Gy z`4&!S&R!A|@AwC`C)(CP=WN8twJ^_!_uCJ>>m#)e{X@6ZG(?|qm4i@w@~`Fr+|cX< z`MgIhIbn4>79C7ZM{mqrw8ahxLGu6g=Qs@8kjPbgg0+ei)jU${^Up{P*AS;6taJ1a zY1?EJsD~_!aln79=9J2R(<>ZTVoxhy3*u*e_9V$cv*hxDZr+ zrW~xGQPu@V>6Cidzz&hq|8&0(bD=EBbe(x$>z#*uCn@e&;nS z{H~P!RHE|_ir)B|GdZ1$!un~HGaYf?=h8oGcAP8!XU9PzIiW|D#v|AlsSVoTY zPcps;XQI4o<%-T1vF`b^s+x3&nP}Fx9q71*{Z3(poNf4A{lE9Z$+k}GJ8do?{zm>2 zJFMS*GEFNJ;oU&i?$s1&r?QdQ`vL_ULngR6aPRh~$4ltT{&<04h@p#a~^p5 zBrijB*CvvZX$%%=EdjHGsjBvToRF=Z{;PfyDFJDDV}y*;&`M|Qub^}mXqFqzI=Y8_ zbU(;{qxC&db=M)9*(QY#NQ)B z>gMJ5_zAI_wqJeJ*t))MO520{(P3G@xq2O`D z(A#au2FYEljN6!75YP2cs>}8rAk|(uw6O*2*Q(t?5C4)8uM$#E8viW?tCO4y`?b6< zEhvLs;|~p?ac}wMFa2b6tY6pYo~a--aFN|iC1)XwdJFCyaEw7yYRpCJodQtj+l-f; zF*EU9SM$+D&sbF8C$E*PEC@p`wk=tnV27C$6)a|_U!ZBKl)d}d$9`z#_B+)IR>GJ3 z_I+auKXmIh(+^1CT0GG$7$aQ;~L2k|)^vMDD%U880sNG{FxL7%dy+hJL z2)m>reK!wWc2HVkxJyoioulBrN>vJ|avm1k!W^pm9%g@(X<3OZVual6>^G3xh3LOz z@W54WL4gDNE2t*5*U8vB8C_>OX(!Ue3A20;d^EV#ilTKM2x)b;pcjw+%|u~tkNN13 zU~~~ZF+oeoekC^=6-OP@T*JPmzW9DikIVHaNR731z@isbgkIdaI?e-^lmacegD44i zu49UGs2KdZo|fwUT8B#!`kIHKh#^Dn`3OFAuI_^SmqRu%2XDp zN%#fegn@GxO(-RSBsUvw7eu4+8tw0bm|w=9WX4Z}c9Ctm1fTw|JiuBn-26WrDE~H^({E~UK1)`MR*k$G zR6J8EsIcONFDj*q|EtSlt?WE zUvRoig;wBDn%}!xOMO4d?3dcr9!a|o>jG8tS={Cl8WP-lKq5?NDmpEk9 zL4C!Uk$CZYM_kz}1L$zf&cE|wfw^>LQl{DMsNi*LXu_3tWT`!8-H82f&pGqDrWKp9 zZ%~_s6SkuW+V3*On7`TF+G_aMcnO6@N$SHtg+NR%XTh`>-#5P(D?K(NBm4>#wyO=3 zk#15a>&G=dI83Y9VNOX)gijxRnSQkZ=ofaM8pd40Fjoggv7LETp!1@j$|e_m0-V&} zVwvEN`<4Mu;9unX@Z*q5d=^R-bh~%Lmkl=gFC4u^HiPW>=VOK^bCDjW!)Co6BNU&W z{%u#$j-FEm>*!qX1m)5Xr=!mB!KtS$t&}=sglW>dBiNsVV(wkf_r?B!wPRdnym+oS z;t_Ssr~fu+oLo36j`t@kBytHC&Htg}{<4C;^aK#(f436(6!SoU+s5uDE73w!H#=_`6d#LjU+;7K@|f2?;- z;~^ikc8nP74WT3UENwqN98W}RH?(|9uzv9|MrnWU*$O&Z<6Y?sb6&BywWE=4*0247&RSd(ufWd~IHr@c|aejO~^1GdZkP*|dJ^VEq!5%T6 z76&fOJ&_r0#z;`iNK z3&p8lEJRuAU6NZTGQc1G;<(X+^svfz_OUKmKboEos`qiN2c;r96q#-O(C&_b zQM%VBrmPT$R1=Fo3$(IANn^44sOoN1mFQuRGF=DW{uyhfa>jmxmQyBDTXayrFZiQ2 z?=v*u8&uY2Dhz#>wpE4kedj}$zQ5d~Bp`fa_NR&iFYJ{5A$QJ?l9(hb{;u(?7##Rf zBISg6XlLh(vUmArksa@luU2v;Adfe8UdD4pM|0XCkI5yZ?mT87mY(wluHa%JI7LS8N`?1tWVR|Bmv$HlZ<$3G8{KSxS}er)sf6LW=^9V12@5fDZa%Xg z_X(~lDBe5#ga!U8qAv*)FG5_UDby+?{Xlc&TW&K8Kcu*%BYSI!f_RAHX-_32px3+d zWbH5U`;B1|1j3S({ zDO={d@u?p4?ra9#^pP9{I<fEEq8Z7^l{e2Ymw;A*P!r>US@!cjzP;P%;SZcr%|LTI?_9uhjWqJZBW}1!5%)mYiIO<`V<-6lNJW*` zm>d|f?%8}p>?6V>Y*e#q3#!GrD&H6)J6JAx0zX? z=F(@y-swg35e0`%-N{BOMne4858=7DyN7INXc9fm8#&c~BM-$qxT90~3in+FiZ%9- zETN6knHomwTvQ&}wOWbq?<`4N8jdPE=(3`nO40c;FdY+>Z6}EL^Iop-Grl)PX+%G@ z+Dt}LyNu};n140DukehIVjpo`wsX(@TLx@s{!7a{%muHvHW}rLZK7cLkXdvo8@bK; zy)ePO8#0lq669BCiA5h+V*M`($!!+vf4GZ#f{Od^Fk?Se?};}XDtGYnP9FVu&k5(z zloz)yUHt)aw9h^2eA9s>9{N)i-o)I7`N%tOgjk3!rlN?Z>MT&HHZ?fG&k8GgrVg7l z=b^*h8*E`8`j8o^1&zdM%*$pbqj`R!05yAGkBJlL0mq}Bh2C-HfzQ5VM~AE9{fy_z zsn?WcKqt+9`_z3Nc%VQd^Ur%4BGc{Ao4VI|;0R0aD3ZqcGJenhSRLBX1gGWLJ)E}! z9#Zki*q7eh&!NM`OHR~Ue$kg(NJD1#XaX;_^20CAqXzE}GZ6wpMskXMaj5sieOuiR z!cauum?*y)3*l`t#Jj2z4P2cpwg!~=px4-uC<*LKSECB85;w^QP9`mdDQYax!R)Np z*6}{{$nN5!j`}Jjc$2(*>Mjk;%^}tPbYm19 zZOHj;$L0z;i@weL)Z&CcCDV*7zmX6zpR^wv?34hb8aUg^fP4M;wp8`3Sc&u)i<@=% z;lNZfd*I|9R>=1{nKL&=akz@7P9nm$*|?*gr%kZPVOx`NVJij{n_&@6qfLQDjEBxqWM`Hem)~3Ywn1pjc}cHjETAiBShJG&&rA+qirGLi(A=tI@M6;)dfncDjVxC}10&}&?Z&h8mVcp8h2R*;Z37V@H zWZ42szzQ4tZfrL85j7}VhxhCt=Y}s+QsxLS z6l-J=bfuyoB0n^r|P{s`dF7Pkho!mobp#0dS(sIDEW%lKLATu1gn;P*lY#IslcsXd4m4SmDt5J`1 zF)!kSzk2i8UZk>Kt0yR3g}9DB%54l`gPSV#yz#VkXl}_}M?|d~^tVvhxW)>=@mjO5 zj}34>lq0c>syzk7DlXr!ZQ+4htOMpYzPsp~TES!g)Dlohb;OaA3iF!Yq%nWObNG>% zZ%x9FpCE?QNl~|W@&0H*xolq!`*Ls_=e9#1*qatLIgfvz97;NmE@7T3g>b#kMo$J3 zGp7j^{Du3)>Wb{2{H7qX;_bPOG_nDeRiNGtysuMN*SbX2Scep3nv&(0aZVRae=@Pa zy(5;{N4@>`(X^|bi;rR+SnwzuY$#`gKOGNW^E0ah^wk}tznHpFh~2N5)>IB?dQtgf zlEW0TeseTOMJX4p`U!G;VP=Qg+$U`2Sqo95bLZ#WiXPneS1F!=b751-oWD!-m(j!! zg$K`QHu@tVX!itjDm;Y_3950HqH5+tB;03v!FFSh?k82;|HpP5*4NIVB5i%?_XA~s znqQsdbrXKRhP+03wpWn~)!r@En_0+dWctd-WFAPDyM5d&b_ZSWx0VguOGD~@x3+~X zIN&L-?+S)?&8Xvc1ROSN2T#Hjm?{={V9N+sW-Jdak=&`VG0BgAFP$H})oF#`-z>kB zJ9thuzACF{wPA|>{j6FO?&X1=0Zts#-|_!{$eimtgY&kur#S{#d7wA<_DW|m6=58E z*{t|RA-MP|^G*dmug3o4AiYn|LioMPcw%`m4BeHI@XW{hl;k(EQ_mkQAdO#Xa#A;| zK$fUG^{yx{6fTM(xn4j+aM|UU#2-jTH#sTKeJ^2!|0!wnm<}zW$uEv#{@w@_98`4A zJBIfL5*xcG3K@wSL$qsO9EkQva;9pqzg^0miZ?rb4RvT4H|3~jqexTrxdsaCUlO&c zvEC*n7G;J54JYvL#C2kfT^;*KGZOAj4Pf3&@eEjTP6ti{fkYK^bLByv{}e zbXJdl0B$G}<|i5ELqa6e94$`M`-Z;IcK;p!j|TcxX_uLsjH2%iuBy!zpTUe$@p~Se zqvx<(ImA!h42}-JJ}8*f0d%z+O{N=pAOrnAH%ST!F+wwJ$?z~8c~JG=6POl&=>ZwP zZoXw9=I<*~h(F8%=lsePM)3a4ah-D@H-nmZMPhpS0QO~th(uj{gL~dhb)|~h#+V8I z)0w3#CfVR&;K4GUU=}FyPiG;hVjeAh8KdHSmW`rwXMKEe?m%DO{@?t!9VB3?_UW2L z7W&FBJY~X01Lf-SSghGb&_P6_H%0p%g}-)hznsMfFA!S^V>NU{rgholT=#r%pVMi7 z%Y_r3;D4@o-L(U~Z(UjO9{-MB*aUYZhI7N(-h|y2x4-Du!jbhkoI^=e_utN$!#wb? zdzaLgF@JcyxZI%k0Se*^Pe!Z)Fi7l#f#g*NLQt#nC`oxPU>H=F^TvL&C`0M*E2Qm+ zaZ2I#-LpSY47nu1YRU=a0vqn)-Vyf{Bn>cQg$4$pjQ;Oob85-0;iKV27_G3n*5Ak`^#j0Bc=d z>hpN7)g1TM=0FJrA^o>*ZJ9_z&mLMioWcCkJ7;Sq79_gR-HbDmq5ri5b%7#9NvwCw zhWtBGp|*`^RV*$X!}m?qqNH&ia!#0Wxx%qjryKQ&Ai=$YN+8#pB_NM=pIBDqo9e3D zh@J0)Z9d0a;IK04qN9a-cj_6xcjUJrb~48A<_B89ZR)Sqz8>7ra5B|}wU>%GFmaGR zLNXt`lGxMyFIE_8JmVPmy3ariw4EQU>U{_zrQ;mxF`wjN*yUkM|2;HvXb}r8`2AvF ze6!D(2Yz~chx!p6B|)!o_2XV@8fsMjrYGow=emL6URj@Qq?Bkje{u=G_qBw&8|iuB zljN7LW5cM4Lk^u*4);=!>)HcPLp$7mP(vZahw}*UsDgiTq##gdaUw)1kr}>v_%8M* zDnjj71f+L9^n(#keFN|F)X?jr;fU0se&BcI0f$gX4T`o`?{;@#g69---nHxw0(;@t z9?&ZnogJ&4xW+>V^PkQuOHOwK4ZFY!x3jIFQ~s3<1?CTX`@elN|Km4M&up+&v&lq? zua@%fIWobkaU(H(T$4aPS-M5iBO5Vam7Tqb_u-wVD`pB`tb;;4+6J{1;=NW(h!{Z) zPcN|7mGcjR4cY5Ay8cFhB=Zhsd*S!sAaD20CzIhQciwb3U_cKIT6o`dX{Lse3*0-C z+k>Egr#j`6@dqIKD(qUV1~ptx0?Qw^1`w6eL$;w4(J0u2cW;J)7E&H(GpiOE0AHOc zs!YTyL7k>D^?SUR-sjVM+!j9snA_}66)08%pQN8JdhvYAu)Oajur&l$z4T&A-1AVv z=M~$oThy@9qV0?`#UR)TI_T>8KR$fgZ*F-;@4#JMYYq{OFjV{V$4k!Vc0j&emPUku z5ng{e?&|#C7&w_X^T-wNGwsWz6Mr{TL0Qf$`R`!^s4dg$`Xrv~&Pp|9G+-_PC;iXt zgO&pz(_YvAgmF1C)H+#{v%&(e@$58teVGJvHhYqx>y@DX`%ft$Iy&f_*2f^!(g$8v z&-t&sYe2V-D-SQ=oL%CP3lX}~V}N#{mH7b&HN1W&en)d<0HAS$IY;?GR2yRKs76TxDPnZ;JG=*x zST@UXu}2|jg@#K=$eI==B}MI>IMxSV$0^GB%rt_IujklMdoWrUvmce(es=72`}7jI6cG{kqjuQs}y5=zkPh$q_h0Vm@eA6v^>5PYa{ zLuQc)^0aZcmUu3K*o`Lv!p1ou0aL6;yIJ8CfdRpf%zuHVK1tIftm8o7KBx-q)sqWjP?1SII?RRw`9FXaqD7DUyeHY>1pEuv=17eZaY18e#1Cnol*bD{Vg8G}f!F&ha zqVk2YpZ{G60ThB4xJLdk!OH8-HV$rcAUyr>h*3c%TED0fv4r`nB7~fH^T&O3yLQw= z^`s@R8;Z$ER%C_TTc?;oSRc5~pi<3sHy<@8-)6nlde!OfQkF$W!L4rz|DVQ3%SG0&;xU0V!5Y)*s0%7n6Dxr*~h|n|7r;k zFxb_hFb)UfNs)C)SPx(PCb&_tO9gLpaxOjy!TvuBhdkQxI`Hf1(YKO#4}2^vxi3(1 z5G)lkw0gh&3LMQHY##rmhPyg~pA<14yZ%#H>zsTODp$F()TGSppbUdsQSG|6R^nuUDw3h5`KJ>tbH#f~=iOr&NxT!r;`ABWG9Y!6e^V zr?J&8#1zcE;{22uo}{YQn-&-VY!kCO{3=yoKSPBz3g?u+v{8D}j{X7vW+O%SGjq_M zWyZ%)5k~mp@tK+${5ktSsfo1BsYeXcZy&^4QNZ@|{A}H0eTc-X8XaR-JxaQI=wJb51lr2lBx zc)Yw1eNp(3?S8%z@vns+;Z~)C^{6Un8y&N zOzP`yd;|U3wB>WY!U{to{|S5eEdiRWDLamP*@)zMe@cor&P5KJmR_~#L1vyAS5Gll zfZ;83Hvga0&|TbpjPdXw%Dhmiq3G?00t(tBk}lFfYT18}PQJytm#xx;^_T$^5_9V2 z`~x=lmLYTZ`Qt^fc%s0-aw7-#Vo(XkP&2^`(s`6e)2BiGm6O6A1%<$A)L(V0fCeg; zHPWUQAoPPr+5XD;0bpoS(%q0L0F^t1oDXHP5w)IIb)O{OL!QZ-kKttsNb#3k_n&b; zpuA#MlNpwas074Di#RdQho;uJH~^ zEeiS0tX8CyM9z9AwjGh{T;wbxV}ar8hmQ%w&VtyxxmDKW*@){@@B3W?YWR;a>M6zk z0AROt|9H6RD>`-Ii82}H%@*t&nKYQ|2F*=UybX@;Ky0M4lr0t3A8+jZ4ISwP0ztPd z&XVS%o6gDQ5x+=ak-u5X7H1cT9N#=+hIt)^-;6iD+$M*I9;tEC;9SbHrE5~B^ZJ1F zt)b}+{?;xZxd4k*7baI{_e49*_k_usu7hy;^aj5oe9 z!Qk=Ajw7{;phjcLD3m=FwYN{Y{bHX6ADkEZnxd`k}H~%?hK7iyRG^cAG(8JsT!8MDg-M~-f z(*$`F=2Wa%rc!6nLGda#-K(ElfU@aPwgYB8NZzqwjhrhB@E;vu;5YdMnh&a!a`<51 z>1rop)}n{MnpYeB-qiyyhXjU0dwuA+`}6DFCvfkkQ*hcG-q+KlOUKgDVBKJt(Ukl* zHT)KN{o%FEA@JEx(@22E9)#h)i>X>8R?+fPtII&(hq4?gjZ0Ir}!@lrZdN@?7^oA?mUe zyLsSOKOp}>Ro(c67M2c%>#n-vmls|1VzBD~i0+TctRGJTYKh7}+q1oq$+lf5vP?(H zXSmg@Ua>+|K_2r@No#84IurY~%|xEkd;xXh`N!LW-=o2^YvQsRF+f1K|J&Ok zPvD%~;pZdp1%w|xdT%N^6#V}_3313>oIg*w_Z~!++)B;b|BO<%D{T@<*&wkYlkie+ z5+I|1%rus25LABeoV|HINTE9r#uDKRtm&5T#0upiS`f5Se2fzM(Q6G3eC|P9eYb_J zmVN*e?SGkf7V#V#Xq1vpI|MSYX?3yY3z|=I%wtT>0Bave{Jw_!qLOrWw|&oVz&B;# z5%b_0;Aobv6}Q@v$;M2nQ`9_AJI#?Ez}X7s{>99Cs2YJU8phR)3DmG5 zsO9xdu|W{xwSF-fSs`Q)+Dywq3ptqRyF)q0fm_sq4ZX{IWRo;*dsLnk&Zqq9`*vy! zxQ85#57+#+a)qFbipzngBbgtm&pK3tYai z{_9=xEHLtR->26q2Y2%2hQ9JL!PL8zFC&Kk0vD0kF&^u0Xx385$g-Rnc5hvCsIy!I zIRWA~HWmxPr`yNQ#XQXgm*inXif9&yShJH4D~UxpE43k`w$!lWC0$tx+aNILd(C=W z)&n_3i8Nd}i065K>c4*^3&8gu{kN_M3?Qb)(mv4$DwuF~T19591#oNUK01%@msSaH z!fu|}1Im3b9UcE`1)J{c2j@3i5WCRH>n*>iAn_wH8kDbm^NFIg8d;?wO*uBL{cCb{=2n+K7V)!MIt5La|xE|9HpMG!7+|Gl$Z zMNTw5aqf z=Ih@};{em=%Q;njEbybA1OG#ZWgz87zS$UE0({PhUVe~44HvVcvqkV+s^Iyb$9#}0 z*eeBY=~MJ@Q?=t=&-Yfa+;LR)=Dlw0!#_+`sfxMIQwQw~AKH{L*_c=g`<9}E)1U7Z zR5C$*eSxK(*MGpB;5T3Td&+?N*OGNVoC{_Wo?JIlnE=VGVH`70tHI@i{%o80JdZ4; z4i@0-L4k|B>6g-MQRvj5(`+j>oS|7zudN*ft=_gLCuKhYMN_T;`A5sZCu@_b`)eDj zf7d$w=2j9wQd%e2dZ}PnoWVH5-9AJiI{SL1upX^Ec=XNiDl4?;Qx-HS-a(9$j4$nl zzo2{}%`M)-6>z(hBfQbG9Xt&BoOS!U1d^MXeHE4J2K>YsW8z;1g73u&l;0ovfyZRw z+)?K!VRu^8s7pZ~0v7C>n-Nt&x$x2zS#tusV!x~Lnk@kJFWYfmOfN(MRod78Yo~_Y zd+jW|?}mVnoP+xCDSOnj+H&N^Dm6UwvX(Scasb_37b-Q}u0R`7cgx8naDM@bK?cc{ zAt0@{!XA(wiWqF#BBnE`A!}H^!Ugd`Afx1A_?Pz`p#Geycmng}MStAjClR6~hBR-? z$om@s#W&hFX_IK+#5cs2e!UInagG%=&tkp^rii%GdL4D`-cla=zw?tL*K@BT-xn=kJ#Z(+#S83YSJfpdV%}O#`W0WBL13XX z6R8pM6(yv^#>g*Xf6D<=@iUhffOPVRR(e-9GI%;)BgD@LGrQmH2Ki5ewuaC82H02j z)~hp2IB5@9CK4BFhx1Tq-I2Z8wQe*{d|vYWL+zIIf7j<1F=t*1A>*G?fmy+i|u5+qV zWJ3!&JTk6#a^xMVnh`Vm`Oy!k&d^Z2td2&j5qnie-#-E|8{KYp%DtFX4i%lzTs9CFdCi(aU`6*iNckj zNhyjm&xQgne0YhAKT8nZS+`+r?tb*hR)#%+(-p`OuAy^FpHVAMhen!{KWHPPx+=%H z4rl}4L^S8xSd8hbx_8rk}eJvj^X=@>tj9{LKBsM2WuyOD@2qwZM?)qld=={mBj zIh63DHNbd8!ANS*T_s{hoKA*1ZI_JFKulMsg zb<68+>0=Zbb?jQMCk?z(mT{1d=R7%xQ3LPkF7%?`nK?_=6U?_vj4cEOq7^d#cAD3r zXt{sl5(z$k{mav9NS56Ma*grR%DCSYp|NX8Rf%)s<{U>aFs*~c4CPJ++CuayKqqgz zKNOHU#;ZP)O+n`?rf7t2Jw-c{$83p6K7hV+a=eAO&(sjE7`Mipg1maOyHZY*LdQpB zCuVy)QQ%3*D-1OwsANI9RtE2%wZ2%=-I1;X%*VNgZ+1?AEio;|z(0p!%OS7f?R@+m z=&_nf6OICJe)MOjOEiM})B;^X+F@Wz%H&L9QYEmJ)%ciLLIpiS6u+(X41hXy_r0jW zA)x(ixNQgfKKA2EeE!UiqFaJ&qzke(=64FI~Bu!}*rNMO#W+E3Y`67*~Kn7GKNaTF^00p()vyyg4Jz1~r# zIuCUfi_|(z@L2Al{tJnDKsVEK)zTvq?U(FNRu;A+ApxFy9UUV;`PU%3O+*S(jwZWA zCD8=V(uZC%4yAxmJEuQHrOkpV8R2lR$slytzEm`wnjX@Vp8K9JyaTT71~nEMJVMH- zGI6&0I|!iO=*;D91!9_&$NqX@8D#k_N!|c1!J$$=)bAiTL=r@;Fp}>GDlm zJ4zU!rP@)_P!235d5O63+=&%c`l!6c0XSDzLXqn_gs9#qNEP&%#&#R9!fqwwe<2k@RROZwSUmkxGzwaY-uQpcEWxK{nhoFM+w)?>S%RcF?aStQFynb9*;3&g^s7 zqD?8KZ&zhVAf#mcP9BcE0@JIBLb>BWDU`J!dgTiUetOUBaA+&g1+?^!ua^UAjaSd7 zZxn*h7Dji@jhoe&Y!2O3Vk<(7Rc2>}Rw>|xIlTkrt#05`OUCE9HwxT;cz+vx@CQ`6 zGExXxcO#dp6!(esda+-=Nb)P*zugk!-_u*10%g25yP-+1(R@ILrJ4R;5c6rQ;1n(>&!UzHawvIVnftlTLGY33*n_;ZMAV1|WE6-R5x;-a_o;t>0bglD`Qf+@ zu;G-KKj}Dt^QF_hZ_f6B3gLt6^oDV0TS5Clf@U4Ke(@#E>aQoDK~1UX;p-4k;BV4* zG0y>X9j*TH$~z@&IRpwn zdV&7C17PB;%LBbz6tKmSBfX@11{{oZpR!rq3dzZ?Am7stW6K=nKO(smT>+Urjs zI06m-h(t6Nj5OUFBqOBmqo0$r^Zq}+fQ#n372_V6K!}n1Vvl?K|IV%J*5{gKuZIEQ z#fxlp6j4Z>xUlaP*o`U%MSweOmnI*u$Z2!e(`y`k+N}nc|LktB- zqJ4?0$3QF((e!&>gtV^&WGGn-ffS?8Z9o4cAidz>>@CuW{-W6|Tb)Djm)KfxeODRa zZd%^xNErnWXj^n9zvKanw~1<7X9~gW*r&5up)bKRA-)f9CP|?Af>}^{(hx{$=qcAwL>b;XMq(BVME85BT#+882=Z85C^Nxc-*3-+&ODjNupykFAn~g$ZG|wse_ad_o z-z)R`{(&d-aq2xaw^_9?pwKVJbKy}1VpJ_Zeh_g4 zo?M>);_dYn7!f_4CT6b!CuuC)?uJpq6;?XZ4)RzpN#l(Ga2E4&XIU$iZ$Rl6e7U>ydLW^n<9vPD0-&pg7ycX zzHnEofu#gwc1Fh#)JG9>ErS{jI}!9tJSOYcR)!XByG1%B$B=ZIa^7)EGRQX=%l$SB z&mj{=_~Gg>c-FE*+aOE<8!P&JCK&qgynLGUKkPR!A3Gl{=s^NgIH~(%G$+u+BVF?N z>}W&_zuO;IqJUw?ce%9PCeWZBQKyk)6QUDuf2xy430Ko^KfZOp95F3?ZQuVq3Ct`G zPk%Z?4%2&;IBiTu(bSE+EmO?FHnwCh)!$A4XYy;iSMl?r|K;49(EEw#LYk0IqQb#2rF`VLO1v)}qxKhD1_!99#cAy~%uxtMK zW5n5lmPz_n%-e|J#{1yKFl9VvE@v&KBG3V-o8DHN+8=?O%d}g8>Z5?|-}(I6iXPA# z%@ll=f)VaD#k8Aht$-+g&X?U<_&)!<;Tux22li?6Oo3}B@X64>Z2hz!n4G;Z;fd>7 zOzAxL(h~Z?)7lptMApMdW486@GYty3SmE^LzAjqIt_10{oVwsmfTV% z%XPq{XM>(tvmY!HpI;uPBZdR~M24#BohY*;Sx(t}7|0z}dFZR-2ekF-*7kqI0A9J& zFMRJ`gAq9eQ`PU(kVr%_G2go!SbWtWpmHx7v}#vg%@_uy zD<)P;qK9EvS&+n^;$hJ7d6-t2z8{4L{d;V^#{gLz*E#~Jet^es)=rE{V@}8|=R9H2 zGVt{0?*}Vh#fTLtB%D)^11!lWUZ|Z~1CNKVvK^W4!agU~S;@2}Fi1G1|$~V%|-bB19^NnC}e?sH^tH!0#_0MixJUzKR0|HmlEbt+VW0ByIQ`4W~BGJgVb9Z>Nxu8}`!*`p2f5=?ZqkRAC3#5D9|A=!w0rDIQoSs|! zf$Dtj3^;YiqBmmQ$}XFN&}E^6ie)GnJ*>DiYB-2}kv1u3T=37=k6Lkc1d%{dKIUef zUo2RZIiKM8iW@dCf0G*?#d%B9?^E8h@Bgw~+<^X+Qp=48Y_-zdQSe0Nv$-hD&C? zAcZshJ?c4`fPSFIx-08qNzq95qhd=^WD+7Ip1S)A{~Qjh8zOzGN$9(km{yBR0H_le zkvofdfW2pAgbfA;P~WbCmUS;^HfW+xi06RZ zQ)|B@{*9quc96CIzCCEURX(7Q#sMiCQ!QMj#}Pr!=SV=EHJYaJ%~i?Zg6$bB$`O#f zZd1YUPGf2g@S^`AU;BU)zA8ORmDW3mZVlcLFqCTryR{O$RoOU~Rr^>#J!BYta_M5j zW1J}Rlw=k!{#;pZ+|4%eX&~c-j!&GCH=y&Cw~5CbF#fJe;Y7MoM9%0V^VZS@Oh2|( zdpa%%dF=VVk|u|Py578idtcK*o}^%!&!Qk)AL!pf$J0RX$=*-KPl7?ijy+8_{(hUJr%qM| zD&ik_mZA|LX+S+%W5xyF-fVU?(>YWZ?KWHOx)~1)Xm|C_eiwuS509LPrAh%_<9Bo} z%S9qO7b%D3C)_YM@olWNF;QJc09EV}SqosU7~hbN=aM{o6stR@dQtei)E|DPKA@*3 z`XJ-8AUy7*_DQ8R1BebJf}Modz_qvG<#IkB>?)IO?9wR&Drmp{fvqt8~DEZfB%Flbd{)PQUU)<_H<+XJ+G!`HJV&WLGD8; zKh2iIz(SjCbMT%ZjFS9HIQW-4+m7ITK@OEq}f%a4h$;P5Ig>*e>WG52o6M)tC)|s(sTMX zxxy;C)t2Y<(I53L8_uia=Q^h&%rh)920RXqs!2rgh-F9BLRXp(8cglfzL*zNj z_xHH`-2QB^m6G9 z{gLRnaZTp>vqNWha*!DHp^UAITrly_v5>U2VYD)LVQ|C@;W-FGz5o>;l(?ARWL!B6 zW>v>X_YE@v%kgVRT`LK&jpOuJO7VI0AwHOp>Jh-$Y(D#f zNHPlA1m$0Jc;K-|FPawwO2M`+yGIb_4-}UKg{rXe!}KW52=AC~^ro-R@4=5xfR$8H zD5;Vg&b;a8zg$RMM`nLm>H9--@Oe}``*0Ws9QTQvHyXkGCjIS#ZrdbOb5yQV?4AJh zJeW}z8%YOkhciEU8ML4pebFt3{{MfU5G<=RsCaWgUJ0xG>p|RKpv|k@XdFNntHe!c zk9Pp2U>&Z0Wo|e@ckZW6dl$M;Sk9KNG605^Vr2v|H?{Vsnf#&EcI4fABg|5H5E!rA zQnAb7f%CT7zj!gv*?vc~P=VhBEd)u=^p$eL@1wMBaI7E2>{`5M7VSn4_v+1_)$_v_ z%O4o(ow`6YD0g~oUxsLN`Z&0$1fkif+Qk{BDAZMKc)WQ6fhOSt^~5iNFs}2W>QG3+PdW_>!0O}lj(f1HPfB(cn zq2D|ol=ttCv}x)_-;#z8nfSLM8HL!S(hWYiWt#Ouf4Chy8G11BX`>T~r|iCGZsvjY z_pY`-=@>w2s>UsCk2}zKdBqk#{(ql&*Y7xK+XaSG-dqh-9sp&9ogPXY0?_nj`~~LJ z3}DcgI48Z`j+(wcb@4UjfW9K;Ohnyt=;@UOSGGuB)I+T*b|H!z{yMQqJ%;OTaZ7oZ zrsD6SgLkW)FWLEFlS!fWX`JKF_N^Z1R;mRhbcEv)r#a!RBU(C-hT2eSW_kM3wL!pl zu2|Uc1Lk;~e{HV$q6l57**Kl5Hi(%2oGX1U$peSvJ+6u6egNaKFNRxiJ<+CJmT7TX z5T3ZS^p#sL7AXs8?kdZrf^d1AQZyzAE$_0H+;;XxJL{c&pMAli!hi?9PamX&A*SiRfa{oVcKPgEBEIheur2lSH;Uv~5U6~2)83{Y z9X34tAdwRLtRs~!E13R6_kZY6J}fc=ZEx@G93I@e5%D7*rpC5lQ z{=FdV&`grFlYEEt9;G?_RQ!P0HC+}Y5Fc!z+nQ;%=mqo5wx<3+T2ZkzBAhU_{h?Tm2HQYR{1zS}#~ z)C)*V31Oc_cpw=$i}%sNelTvKl*09~8^m2jO-HD?;O&_6$ubn9NKSU|;|+%lASSU# z6NU3mflASorkVxFBb_6T{KNogwPE+w#2j^*W7nLEog2|nAVF@GF@)H{Eq}PkalxmY zn>(^uJ;?cMc(Q?UKPvg|(sQ^)5cWuqzNSCt2l|FybF;k21-!du%jRr+F!7OKZr_a| z@Qsc5^rBoHFkAH|7SQH}-dcJ+nY>+K-JU%lvb-NSg~jdtdBYED)O(ok+GU|Xm?U5o z+6#z@OlvjLxgp1mN8Yab#C4|c%XKBY?xKlQ2cqv~+;DdM%aqZ{ek3qh=X@RZg7|-O zX)sFwD$%*e&YwsD=6(KhfqG3q=hf3!s#gVI#mI%&w+3nGS)4k(7(*Ls`}u0VmE*SR|qKB zx0>VE1mX8L;ME7aNTk&ILb^{W3Cxqz8h!TQhldzASZ8c|0c{tN$3oEuuw;Iebx(yK zUaxmed32~BTnS9uGf+(ck*o4Dmi2rvTBdh*;7cLs`6f(%f_D)3(^YK?P2qi!Typ~H zXI$SV{_|(eEfbI}u8=B}alu6|uJDxIZj?(oacH)oA6(3i+&#%60NEt7+d_V4f^CVO zW2gB$Kvh9df0Z#0^xy8JlxH4BG6%kql=Mv~=khnvCm2 z!4qc4+$i#GcZw7;JfxEq9`OYANw+3chY2uJy>5~w1m6d7i87>&c_2J(+_-3l2Y#2m zI_`8A_j?;@v#g8_k%rxw7dEt8z(bYl6!32mkRyE4GE=5Ud1r)GKAPj|@AoFu^L6!B_@u~DG=p}W!XUKDyU zDpX>F{VySt|6Q42&&u8PAVPz@1eNo-``WC~s&JifJBtFE#hH_R2(d&u6>T}v860rz z<9}Cr*h-?DbKbR8zQb+9n-u5k#6ADJGQz%tQjdXGjq;`87xfsTv2Vhtgv{|B=6VkP zeDAm53A~9l1=fCZ!3uF5^HXbhUiPEzs}0V_NVMr~!At}jtO@5fsTZe)@LR$?-K`#Z znu5}^MjC9e)%O0ws#Gdy?7x5Nn0l|g;e}9HS?ta6-Z{cNCW1Y#4ZG{2Po4tDxIJF~ zU!3rsQQ25_?*@1ldxP+u0tY?{i~x)9rC|EhrbHIxiWI0 zZ^aC2BjARw%XJ%?N5IHsNBKt+_MD0;UJmy@3~P@Dkbc^IjBadcM7fo*!`eS-l7DQE zK;rPnDoN+N({=eC%M^x{NQ52toZ>SJnH+)qUj&?1IH}-9rKfU3O0T?R#yQd3cpoS`^G3TwiK*_S zzgLfxixDbG8c3PLyp*^vLNxschhU+D+NvVOU8M5I#cj$9a|JKLo?X(zQ0z(+H|r-m zRNMDz<2Tsnv7 z;b8gSAof5z@Pu}M*ja)Vj*9N)ZD9T%B^{;J%i=zHz8L0*H*sz_`MU6Qv1W4eaYNxl4hX&=fGS#U^omruRX%cH8_GM*jtW@^v^~qnZ zr2IIW$O7rTm|Pk!;ePco{U9o{e)-J6@Kim_9}W;drBw9x5VSr*8KvqnET2i#=W!p; zgY&T@?+@>g;{Jb+RA9@1{1?|4IW=}3*z%$3=jdmqI_Y3Dw$D!fsG-C5_P7o978NFh zh}kf~M1N&x+X5rhSWQ@jhp@hd=HQQ(fGb zn)lU%T4?JWm5${Q0je6+i`li0fkqp84H27nC|93sOE?&F&vLdMRKkCOuBKldZ$qrW zgV`iL0C-3)>(SUI@uEZ0hl72rU&lvg3OR4W@7iEA}O4i*R|p}GbpcuVhnqQ z`Jk#_F#9c>M|)33`aI-~K3Xa1Unb=sK#z4lw-e`kr09%?kS+(w~(UQq;w3@1;7( zJw$rt!{md7?!*e zve~haXC)jhrsw0ekJgYlk(yhbvgT*7< zzh+W3#&eEsv)^mN@ILK&WVG=Fe7z&$U5MU4YG-x2=poiGZbW91LH5}%`c zdU9v{Pw~MH$EpQwoF6~2H^Vvg_8thjH^;J&&j#m9--q``k01}V;RgqzIrtDkI3Y$# zfMpjR_R55eplb1g6_&zn9I&* z|MqZliZ2LTJE0yyf~B#PyDT`ugFb0xlS3%((Nq>NE+D8}_|Ve&o+9&PV2I8JdN z$cJC~CVP_yGK>iSs>K|FuPg-T?|~7ZPVSOsP%-uzh!3#EXCH>k=Obm-^{hZ$&>vGP z%+xX(Xlm&^E?mH#yQh-&j~?PVar)td>?S5SOtvw9YbXRIu{k{0n&f~@iSwAMFb9G= zbq`FqoWPCF_j(%V3DE90$xVmI5wMprcO?|hp3Fj8+;Dz^Bs8;j|^k-K$|opwD*sG`*rOQYY%S3AoJ(DXuzywz!SwFvz!Q7PVE-jomGF z_>TuZ`qJ+Pw<)0f-_yU|bs3yl6PPJ)lS1YZ3&?lU6tyoI+~vE$3H!yx z8hxj~ftWxegJ;{8$aMIWwio6LHJP+)^1oXHxVP19K4gKO=9@*IKZoB}z2k?W z%x3W^Hb<1_H)CeMhH3FY@_3mS#92(x zZ(U0D9*!cJI3~OENMT-Lf$h7a8%$9C>9=DoCquw-U&3!$yl>p*-oIgt@6X-R!}0UF zS|C68*$34&c32`QCbc5*q0KiN$N8hc~}R z$NlAn;vOO7%s4kuv3sSHk!eoeSV~_`YZG%0lV_xBab1$hoa&9sRt9pny0v}w2OBJi zk}K*U8U}@35nnZx8o*Oq7P52r{otYT=9ixvBODJA$^J0&9tEUOzAzFc!0=#=!hNR^ zV4zm_NnE}VME>MixMs)(S-2~fekbAk|Ksy#CFVKk_sC4&O=k}HsZP`}0(-r)TQ`&z zCOlA5nokis=EGZEUJ7pt9RcYjEzgQNN)T(ZbfiIbJwVABWsCsDi>F1hFkj0-@FdkGVs@ye z_(aZZW*A)K)f_yZR0Z;+b3EGddYYO)aE3o%42^vF^!MaUJ}Q!p7|Xz(ox-=q#eW#4bhYJ$Q=-ZW);!d(dT8#5NzrWpO`U23)_9@( ztXc&sKLP_;1I4c$(**}somHZ*dEj4~e`%jH$>G%uN5<3i#-PFJMbKMW4w!R8^`W}Z z2pI2C^`puu2X^(8m(1|JJ@K=-yD#C@f+M*lDue=ka^;{;vvgRlzy1trR}d zQ|Jf8=4HarTW+}M$oTzZ8xf4WteFV!-vQ>;)~a1CobbynetNR*HQ*j7v9s4~0Z!E^ zZ4t|G!H=G^@!VWn;FsH;$67h|#>!md>%si+mwdIC*`{|v`T3tZF9Yv_XPVQSYNFgQ z;c~%y-fFzxw!FLh$j}S~o%=iyp~(r&@7tf6^8F4Zi%PvJ=PbdSSBImAz1ZQq?}D=K zZ6j#%@teE%abGb)fQ4g;d<5rHR_*s0=Nx7BJ4_G*0n*Ny|63UZ6>E6xTsWE=Y zOX*#%tRx4l8+sh8jQzqv%!ZC(dclDF@v88#ZQPgX9(UZY!G2~SJgiT6gKRGxbQNJ= zq^)hl`bnJUad-Ui;P5*~aC*O`Z%dvBZgM#^EMafMTD^OOVB|Y=wo9|L^%@6!J4LL_ zCjJFnGq|ihR1pQ13!9^R>NsKRz(({BX$C0s%WhL}IviPEjcaGeoGS^Zh6gVRqri~& z%&`F1OdvY+7;cxc!fVAxk22yM#(6&vtMKPIE`KoK_<@oOicSSfP~-mpMwrH$Fy8Np zZIuKH;Xc|8frT!{aym#&6f*fKITrc76b#tI92IAk_^`79qj+AXZ*?so9c8Zn3mF&Z zhLkj}FPmAI;OmNLJH3O~AXxexl``f+e0ASEcvDIVLwE*Y^vfuukbR7%8t3HoHES+r zVDG12I*0v~u@oxeTA||F;e%nX_iH2mG1bvJNbiNzSpp4MSy9x1IY>o_=wTK;ln*)e zip23f2$SxkxIWAS9UN%Ya&J=9jaE(DI(wRf3okn--B$ zQkTt3vLOywK(8lZmpTI&SbPNUN2`P8579>7Lpk8?-Yb*Rt~oGfso!-=))U24$iCpP zVTE)r-nD;R!}9^6fBtkd#~|*fQB`q|c%=LW*`$0NaUe!`GGu7>= z(t>7U3FrDI=idd1ASrWWigqSc^en3%TbSf^OzB$CqW)n>5;(Im$)e6 z4)*>?yHPM~Pl3R4wk*ZJZ-F6(0`47Sfu}OhJ*Z+PgSraz`nNI@kI z5dJ7xrGjA}>+%D<|KEOk|NP>uagg!JZY|F#1vy4H%~7_nLWhB&QAT!3*mQHv@=kvg z;OcOB#G=Lxbsg)sH{UYCa=L&a#>!;CN9b!#(&vEQ5mjWXvNOOb@!w_cd){bQeNMk0 z_oMsUOO9?f4FN~cpw-mdh(>AW75$7j;AHCgsjt0sP~VN+Qv5|CsIT0RkH;QBlezEt z&Svy*Q|#i**Sbhlw69Y%mcR|0(&;@8lQ6-|(|@#WA0z_mw?3sYP26xUt?kg2GA4+O zi=WVKyQ6b@Au^`Z%rNs>%WAnK8N4#^IGCVIxuEquHd|~oS_CWJhGkqROQ4S z)T#6{jo~uhk6vgr#LOf6xum zSQZ#i+ho}2L=KablEVja&S>n4^MTP(%oS+}XVAd=jna1%6Uq^lplZq3HZYR|Mr&5e zN;QuIk?2LAwP|a_^SJ1Avla(@DXndN`VlRB`Z*|LmMRBCsyANt$DYm7n8P{u>JLMe zafLm@m%%6{>37%|=FHrS%ldlEm z3^bDeF+puY#`MV(%7F8Fooi$!_CkU!bMD1q%n7Z05$sq6QZ|og{_w}^REy*(DSxIq zl93%!wM)imYo#il%7GJxK1=jeBxiuHY=8P%5XFOMy9H-m)wp0@>u1qkj%`r=w2&m~ zv?NM))0vxIWriV7;mC0lGDzNjnIc>|0vVWzn;T3pLbmVU#cRC|K|!e&fhP}fzL=p& zZQ}+9Jbc}YJ4=EdetmI6KJ>63s%l)CJ9~{AUVb=f-;TZ6)tVo(U!05u<Y5kAC8U zX~n1dY(DORT(44At(TJMSba8fInD`7S#|$}vn&ET>7!w9`E*g~l{rG;Iv4yd^MkuJ zeIKM;zjRNO+5!bUxlb>#PJnFV1`iJPVou2A@a~?LNO04p9pl>AVZ!a0F5mUfpttYk z=4qw^K!2)n0`74`!`U8Xg(VU=)UM5Ttw#pEiXm^7S7Lyi6#*7i^!vc+_SwMH@6VCz z#jls*w3y*BdA^>_C!}yh{XXmTbP(vHR(S+A`Tk!XfVobI_KWK@s~NhP_&B`2lK}bG z6wK0SXraQ4#q@f196CqdE?W8y*R{-cWS7E-A^q-?vE<2kz~6A9MFbL{o~>uiy-UL& z%=QHz`dtT(@81rqPhf*2VW4$8d;}2EgC7c2mw`R0khhPuIN@0mvS;mu+hAXHy6_Wk zGVpLZ*|dWDk3$l1B&7u-pcM(OvA7kY(1_%{nq30amt@V$KSKv!wOnm*`yGb1*6ni1 zZ*sz4q(|L96YT)=jHPdWo+0St+z^#s687g#=-b+>tODu%Lu&(kx6$IlcFVsS4k)r* zE#Koi1>Cpuj#g<}p$L_aldHIH|NXEjIl>=lSR^Q7!G z3QY}L2*Bq=lhs{Xc3c-F{V*Ii#}$suir@UxXk>(*G~}6zLWf|^mA_e;3@M2D;G~vz zEH~V6KAzyvNDAr8zSyU)g@90^cjwJ8H%UteZi7dy)EKL0tT z-C5sBARvFZQt)gZ;*?R%i@i0_N7Rqx#IsbvpS(|v&^KqQeg6rO8g|bn4uV~?_ zrL8AmHumct=dtFC_s75;;Tv=N?`pw&*L%5!l|0av_I~S>$`J?zM`5mIFzOTu6}yOiTTIl+ zzhED(1Gkfx51GWGk&{)H6>|i<&L%5{Qx5@g_kn3X=TE>>^iD=U_Fu2DXwYq7-|RP` zRfYsE4A>mRZ~ zC!0OH0p@Av>UN5(iSGg7hM=tF`f!kZ%F+Az3r<+^p6T`$ z=cy#+$EOUn|Emu#SN>a#0i9oS^DbS$yz9nGpK~2(aed1$*VNP!L|*@__S{Er3BPy2b%VSdl0D#l@vnFRDU=giuBDGtcL@{X0PcnBOM zw)3hGHKFIPzj5BN=Y?N6tGZqqjJS7_;=R(tMhL~J4w%sYPQBVMmxwq(BF`AQBgOpXutaE1fhzjcDO4+zlk zopc~o?-3Y#v+>aBnJ5Ita~Z`J3Gk0rms(5K5;()|b}v&U0%aFalqlTihE)IFevlMp zf@~jYSL1X8ktBZIJ2m6F!~@~1AGqI{+U~y@YY;9IUK|S89;{!isUm4Y0~q`PFL96NRUSLJu3P^=o8I(3Oa5+ znB2a^!F7|a?oo`*vGrafRL}m`&=;R`PmGcr>A~;Y9@=cuOX6&9@E7u%_;}eKdwVmBzVm-P3|UjFul?~z15pmPUo-K#@NTQ+ zhR&}!@MciL)I>i8jg#q!&A-O^*ki-f(Pbl`UhDj{(o8adK!kJ=^Y?h%Tw@dTh+$7F z;l_H*TQnccxqdW@3uYgsc*-$H57S+qJpZJVh@#$D?WywfLdq(tZ~p0&u+33M$VOBO zbyU)xC;G?@{n_nndl{La#)N%{=BY50b*PP0h#u!8Cp2Cu%243*u@(oJRtgf(VhCZ* z$6ULKBtpR+1^nvcl$J?{{m9SuFSTJ`K=G&RQBUz440mP** z{g=OfGI@K%Fp>Sm^ugF2G~SbVb*7C2&Ri(1bbmes4ol41$H_FK)iu#$?(eyw-fy~* z#YqNe^Lh@w$%#WnXH>)|X?fup`5#}(co?99+E96iQYNU<{WaS-tab#pQbVJx|;aUOHCseZkau&05#d~0SukJ%ujrQ~%BEp8ZfaSvjIU$>(;L|flhQYeu^tA@QMl{P5@JP%Tdu@(k z9^u>oDBmd+-m=}PdE@@cTi=65U&4=>yw>z90^6m*Dk-fB*O{=p_>Q!{udx4 z`H?{U27%e6-!5B*;vlbcyUW?5#W$AKHt#4(E<^PY->jVdI5+ztp_FMvuU2!M=BH(8qyxfBI9*dtC60`Ki5PKYae3 z8#B7M5e3RpI*|Asd7sZ$<_OTMTJ@MUW0#?dYPJY2GP`B4v?a>w)^r180Ju8)n z?)>ajQ2fURH|dUtrm<4Or_Bp*MvoSOE2b`QS5C0NSKjny`lPtdZ+S?dYPbei)jm)C z{u1ZVHY|?##4yyA>C?Qip4CByy`k*qu47*Mt~x8F=WnnU`E=k7ApvaPJ3;o7juXZ= zih7Uk(m)<1*7n0%A3$%eZw=7lfIZB_eIq3}e;c6S_3Ot+aI$t(P2@ZmbRbEy(2=Bs zFZ70FBd=nwy^-(DGVH(j>_cYqq@Ni3c35%_WnwQw&Hj7K25#u#)2_GHgy&qXb-T`# zhMDtWUmzO9}y6hd!U6Az1))ZO?kvcr$@so$*&#iR&9` z6sB3fM}YovxtyTE6ChYdWx_L!y;qLiH0}XEfK*J9h0*U2Fljs2X$`p{;p>qS>SPjV z6I0~+R5lW*6}!!;IpVr*!tF#?ks+L$9WhTm_=E&UQcO7UbN#R=a&8QJn>|E?nV$a1 z20gz<6vfFoVc4do^@2X`3pkMz-%~9^le?8In(Mq!m!>E#MV20VKYix0yBQ4ptd=<~ zXqlnj-x8x4dLp>lcH#N+-*tFkR7`6ye2a>qk_j#^VQ6cxUQ~pyT2}$19C3z zf9Ek60S@c=0oS-oL2?Y^28SKa1H`7@5$R;8Q*sClW%YDKLo-(oZey>|u1}Y&FA*~& zw}0eS&0_(6_A6X&!hQDPpgf8=t|PECy>pxQe;Lv(I7%)2sD;WR7{TgLv-`(>oKz&}f=7p*^x}5RO zBw~aOl2K<0*8Cg>uk+2VVh<`&s5{%etP|WYTX*hEKRXFr4>lD4_Te>>TP1Y=a^-?v z#iAvqcMd^i&6+fUBZ26GzY$*o=6+jse=)J)riQC@_us!44MD4?Z-3Xv_2E|0$F>Wu z%RuP#@$dNop(t!V{l%}lZ17~nXuosX43G+7s=m3Eh4eM%D0A^SbXBn9j~f0S7Wva; zB}}fO4R_7&BA+Nko0)X@u#Qys%kqT(_u!9{Ovur{3@nMqOhK!@VvX zu;t16#s0i?AT6AK`RdmQG{aE*fWeCZPiF`WFDp<(TE=~6~}vW0fT##?SF88`TGXvKn)rJ=DxYr1xI6$hP>3sJ^Vco{onZo?CHH$@Xj&tF6v@8 zp>$8?gf|z2pPqP14rM9>4(b?E5xty^lYl)l{BXNzd18kMHhtchT0fDA)=Q}BNR`;( z8THB;b*KqW)>$e1 z{WnB6D5y0Wg1_%Nye#lM&he;|!cQ8Q>TcLPbQNIHK-U8VtNckhpa4xdpLP>9^r!T1 z*`Z29#RbMjE_(#1Am4mDO8*N`Pv7wM$8$X^&j%wk@SN1m;%4*Nqcl*@*E`=#ISuW_ z7UnA8-z%bg(x?&t-eW2>V;l?;K#8vQAm$bJYDL=avt9lJ8a5l9PyhNqOr3W)*U|s? z?Y;NjS!JX_M&}q63dzXcB2=OzA|a6($}BTvugX58$jU0Cj0l;9?0KK>@4A2Y_wFCp z)zu|FpZDjS*LXf3&yj|ZV_ji>A6VcE#v{%jOICo&&7}(ki%mc)uk?b~8XIi*aq3(g z!6<09-nf6^TrC)`?EJOZ$pP~_BmWf}lE8VCu$7N}4McG&BW#(t4@p2eswW8GyB(v~ z@-A;s<7u(k@ky*#r!Vknw#1wgv+6HyF8P4$*B{QP=PWQ(b)L^fV+CAIV%5lBEl2%? z0X-BN_(5a{xDOfT1lzUi4n&~1JE18-|6hGVny7pC9J3oZd&_E$#ET!6)2>y=oS}nX`ll=m=DZy9)ZOc@vcj70;l7K)a!Ps;tyuy{fwDU7-w-lNw=?*WEuHyAl zcg#gMbPlgzb>6|g?oV>{p84o>-0sh*CLXANlc8(;86_Ow&LB_?Dg})@_qr43Sm3UJ zX|6i!8mL)6K3#_W%&+-rhOF4xpuBi;*-;51SZ6yCUd)2?H>X-$%J6-Z_T#-g%Mcw5 zw@$n}f4&$*G0SwtDe}RUXaeN%nF-#_=O_4Sm5lZurpNGmu|or^9pwwP{U%CrX#;-i@+`qa$EA`gVjoo0^b<$dD7?}rkt1wbdltA&JY*8ewEH+ z@i+mjc&WsF>aYx`Tqr7X9%6x=m3s1zFU^78vmRZhN*@4%_j4IA7y8UmB%dz33rxHd zs&4o-fa;F1b4^!x;E13|Lfbi7m~5*<`Fbl02^4!c{*GjZvC7}L%N+=yD+l*9{Z={1 zFSy*&k;D!=g#`0IQS1P1H}+sw^%7Ki#*dERIR{L5nD-(uaTO3QJfB$Udk887viA1iu;2EwvAe&Bq=q+cbA z1Ri_9eSo@Ik0>8~`+MPd7oK0eo61_-YFq=19ahI`CQ8Bm^?fLc_574UH=WB@=wYMm z+vQT}3~(B~voL$f3E66nb(BwIPT}C8W#9MrAk#nC;5hc_(9O$P4-DWsfys^F$JsYP zHH)n)ewGa~q<1~kytoYp1yU&Rm=*;3ShbJ-;DNL)!^;+ohk(fPLPd_}W6W6+)2G98 zt*9r)?Yq@LQHWyPg9-WOJdl77f6s(8oj{EV#lo0m&CK+VVg6dLtn|%fl zpmcF!%f|cGSbsy`ZM^@w*`0U!WC0qY8u(`6!3Qk@F%Feo+72v=xi{iQyqqGw#=U(%yF;0F_n$0zRn1g>gSk--j`$Y^N)Bi~aNNc+Q6 z!kM2KcD~)yCTPVuXg~aXe8jootU}BFWB&tiBuv!+%@=_lsR`orZdT~)BTqqJNdjB? z8s`p!%fTh8xTHVdaIQqDL|5Q-3dqCqCHuS>&NVxB*diFt1+kZM^MWQJ3})wEd-%2z zFcGIJrab0?^Z8PRr%P$zhE{p^@8WWhoxjLngU{8TJHVPmg#vohow%b~l?oa^?^BzU za6spdhl=d)X`qju@v$g@7l>ZJz)4&e>r&cvsuJQD;E@3-7On4Dz*C&&%>u4JXHL5< z&&x4G&Ac@IJ74{g4@dcfSS1elr>r~Zz4Zpr&>YUM`&EE^6*R0#CL-Km%j-KCaPVJaM=J2UAm+% z`2SU7v(7i1V1O1rVMPI-(h=wGVCtDM0r>E@JcGbh=Ef&#L3U$Rm%wA+qOJn0$0OUh zR{P!ua~3Aj##YjYIZR2~Ed|vw5uW#{OrX;SPMy z-jLW?a%==uJqs-L57^+V*NzP=OPKSdtDrg?SBUfli^bRv*or(s{@4F~&HN5vTH_V13VRFkbT1yCxz7O|MiL#ev43Mw zs6VS-zYA19bBXlDdEfpl6{ zDRFm0<}NE7eSgv@+JgW_0R0<6)3xBXCHI+DF+R-EH7EQfL=Nc(7rAqTo`EcfZ+A{j zu)~6YrrVExuYkEFz9FTt0_09CK_rNCShCkAlxzd{Krk}}ov7A5G=G1y{5gL9%YzJ> zRMR&B{U&OT(G`H89-t zj%gW6nft>8zTdh~d{cCCdrA6y$vPH!2D1qbfYaOu6Nk z!3!dIBmFQBo&QApjCqO&hUDn~Jo$=uFFgO08Xp{`>`h0PlJ5u{eZ>xU&zLM&%B%n>j$^LjlyzW#NP1i3|9kx@i@RBJ znZ3YkrZi6}dJgz1zB@*IZxvMOc@#g-t^uBVjb41~xG%17jW{#62b45je2JtQK;!1k zyV}d#P;$b(e(fne6yhXMQ)4UxpN}{%_!6)~!C&*mM+P=Pm{JI#nl}RL!fE=}Eu3&< zs4iv8U>`hcbu;g^VU5i2 zLngZ7pfyR2>zss(970+8gjj#1PkzxT3uwMi|LK9}Cq9}Kv!_ndK$^b6Z&{bJ(UW3IW=T4=HvlSbyF=Dbb(r^{Bz+H` zV>>a~#KqziP(@i|M?@FrQJVXt4>)o`QIj!w);dafj`Gzp|5v%F`k1J@Itd#TwJ4#c zHa!ID1^sd-*h*0kixE;fgMEUbXAWaO&_lkl?q$GG2Ar)kiKy}GqwV%-)r22^xXP;> zOtq?k(D-S$Dkl~wC9CGE_F*4$IwDm{Budc2@v$0l4t7Y!ICSZy-xAnMTJTJ}UyOoW zgWuY9alV$C<9uq=ZL&yvuuWf6JG5WT${)xgp{Nk30-Y9phWe^tm8R+ zjy+`h^Fm?@G}~zsF8q!_O}Q0`I)v;n>1lYWo75UuC;OFVC5=FCI|@p``-Om5g_j{k zQ{Z}N^6C1CBs6O3X`rCT2M_<}4>Md8%L?H98i|VM&xW4Gdw-VxNX_?jbntJ`t&awC zWx!Cexah7w56lRje9;w70NqKyo)P_(3O?R=u5*ZWGKJ@IKbzhmhcZYd@(I&>aG$9S z-N5&q@kmRj%L~l4Em4q|T`UEk7jE4Td5ZU&J6VRmAw8r@OTGQ$VkQ!Dy(mM3KVL`u zChs;1Q^5{;5G!>F-;ZM_40G=D!QQIfPhXX3AdBrvc{OnyqUq^fs2Jpid~?71f;EZZ z=if~RtV6|MYdT;n80+^$6hDBrCQ3+WCv2-3TnR$bRDV_aa6tOfSndFuJ+LL?7fYR4 zh*YM3Hoi;5c}&gQ3Povzu;O8D`6a?4lu@c9RVBy+&ou{L?z&5h{ZQ0u_R1ANdQ#Fy zRDuIq&;ET(Q#Ob^W!X*~zQpsKg}HF!IbKM?7W1Zqm<9^IFX^ZMn1sk_ay)n5v%)1& zwL59_2jKOCEbD>P2GBm0`Qk3Zb)Zvg%@fuw@STmm!8kevWv!fF=)rnU&nDJq|87vj z**S13=w&7%sAxBJ2;hYRA})z^v2;*D7u=;ZECsLB)`WA4_~GvmhM8iV)2KasgEpo% z18j<3ZT)MC`2f#Ye-S#Zf;t{y!K$r1a9lFP60)#DMbR6UX=VFho1WPI$FWkhn_eCz zXvhqGy^W7ox9owpAIFP?@;r-Dt1_PkS&B^b1Doc>i0c5~_QZ2+n@~7jrf&1@X9!)oFgl^AI6QnLlq2 zf&1e3V5N)2=pAb_%bL-D?^E}iDmgpOFTnQ`OiJBfS)pWA(Vj;-DO|E?5E(Wq1~2l$ zbwY7or?Ob{eL7zf=p4H*di+5p_%rcMI}Gd0YmfeBwk|jXPV`%`d}g(Pg=WvfD}oKa zF5|5{-cJC(RDCkNccmV@oWA!j1@9foZrwXE&a(sDuaE={dM2XzQ*wV(abNtw;D-D! zzOR5pxN=q^qzxS~tLKK`IqjCco<_zHY2%l=+z9OvE3lgHwD<_?i-umVm%R(7f$Kr5 zarE#tGUpO5kSFDX4ExAfiYFpai8w^oyqmw0I1W`d?G&9gf1Ud4|R&;fL^+3Q%s_iu!}XZ z?ZJl%(Aj(8n(I6VJZ5F(dovL~=KL@HNLl?R0eW zPMG{fdhBQUzvssMMCIs3UVpS^S^1;=9v8ef!$0eO84VjJ;nP+GxwYtEP)UO#CtWI0&?J}(6*jN?7akonoktpOUi zm*Xhxb2J@!T8xjC*mJ|Ih0)b+PZCJ+aX*thEenZ=-Cc9QKhOWxW3BanPAPXi0%x9h z=JcfUK`W8B15wz2kv|_Do3WpY);y_>G6drD-+gp6S`X(*D_MGSx(|YXo{U-Bcd;I6 z^{MaF$9|wgBb>Fg(hevFT=&WxagOZ?$LuEa0U%`V12GK`l|3+0lHlZlz~$eN#$_T% zQ<{9`sq`Cg+5A*y$}%fdUJl*=$4&;r{%X5Xk7gp_(ArQ6d|v5RM!u}d>jNRd0!FOW zU%*H4Y@$fqZzf-XZC7QPf;Y{{Vd7iNI45FyhrO*`{7LmQ17EN zR#WAG?&5k)Ex0dWDo||`CMpG_j(VyKm;(jg`B7sa4YbyKQ9nH$EC zd?OArH~`{fasNdp(iJ#g{O;)I({4d9ovJWdku5H0!r!)t2JO3`USA`gU&)?TD z&!`2NWZvR>k9c8FVUEmtH96)A_}=cj6OVknnH;Zo^26oX_rry~v`}~Lht;fvJE~3$ zSGe4Y{WV0)!|LR;FkojgR;DN&XongN$rE9JP{rGG+%HI=S(%5d1m*=fi@UDb;`3HL z=%vlG zKTva&e#-V{BS`II$#LG`gs%lOSKd6Kg0w85NuK37=#}ZKw5lbnw>h?H!G3BB7!i1o zq_z|xHs5v6-Dcb`Cox?>H4JGW({ER;(c=AB@fQs8@R@YKX=!REh}uB3P2@y zRk{eoe!ZuO!tb#TA=2Uaov6Df5hq*zSyjA;-RtPs=)X%2L%k-8$X&D11d;l-3JccB zgbUS$;k@zXglX=s;DLOCi8oG~+qVTVRfo5nRwi6H5UhmzMu5qcQX z;FeB~=O^v#TKROlfHL$6&$wAOl8gUW^XCm8Ja3&cGA2$37pZkw44*3 z&A#57VMh;#jOrr!MjViNoFaWl0~mjVwq{vA_ou*JUTW zH$X$n^nJdvMsUeskvT^Xa}typzV;prBj45dm&szez*(6EMEvE1FC{2jPqOp@neC?2 zRY$r(GWXpEp+2mOh?ieisonuLr*y+EWE25zrV-5o>m|(9p?u>7%jP~`@!*{y&iw=*{5t-J~Wu_fg zct3VT;KAw=h%`ROe{r}Gyfi=Ex?REx8Q9j_`d@Rm$zWTv zjr$mDK1%*=`RS|JT=qP(msk&Yn!;#B=--PJEH=yD;eMGbYa;qxIU#&qI>zWq`UusWp~|85 z#D0Ilv^TCMj8N{(^J2dRd$1NR$5Sol%gm2INVraIF;ep zlEOA1|D9q-=3a*SSWi=EVjUFS?9f1B0SWy6vm>NyDjzKlr~GD=7-L5`x6Vz}?X*8KPf*IWgCn`UD&NCT(a7I*+Uuu{m{NOb* zu9HvIX61x=hk}nr{m3DC4p}z;BF=Sn%_OQnWPur!xh!m0$F+8zv55Fcg;35d9j(Nv+Tgi?Tz`_Cfcl zn-vK7S)HAC8Uz^)Fv1(p)x*9_q)5iD0yCH9>oy)~sQ#(S8-}|$huZS-Qd8+7&~*~h zv$B5&Xw<*)ZQ%Uq1Lc*Qoo`9tY8{v653)CC#@x6*_=@w1Pq?1E(t6fjWg2W8ak4mbw-_--e=9D> zb4bO*G=Bbnm|vUq#D?Lp8kDP$bGeyu!mXi}Jmr@M;P;~wTfdUuAS(jyZ(5hxp$kDm zjydOBz&|)}C+y-NIL|n5_Lvsur>{miwJa0Cd4BP`YNka<-s;n};CnofbbynT8}IF& z&m4Yk>m5Xa&uUKwYVkk=ZM~gv=5A1)Z`09}-Umdl`w_+A^OnN;bJz{(B@jcN)k*aI04l$oiv~&3-o@1~R zd=pVnJOq)zK(_dwi^H`To z#(u1&gFGKRTw&;G!1eRBONn7pL@aQ5Sd{CF-3{#)L>AwF*p*t!Eb%Mro+R{IB>^V=*)SD8e@0%Nqhyn2S7qRmS3i;`4)@N(K` z&;1o<7-2vzIO-dSeww-ZC-QMX=}vAO5xX+zY8V%cKg;lhRD!)ewpz{>l(4a#d zIGM`0z4@I3_V3v^N#Q*s)o}{%TB;hLRvdpZfeHI_XDXPiUd{r&j^-`L$oGI`)^b$@ z`vnr8yb~O&=mso?F%H99y(nE0-j?~s0+kH&9yb+igCxEC9HJNSyzA`JeQ|2ciMo7G zP-}Y&%#F=IP-f0TbP~4)yfD{-v?le~{Hc9#94)(e`__VsEhBeY9Qfhl^i87KU`ANy zy`gv6GzT!>UrA0k=7zQ7W&71cZ-Js(O}CieAlN$dgf;pnHw=9-nseun9J)Wcer?~O z0-WtKdR!FA1B>NF6Y`4a;V20@)eu<*g#EAHlRV7UyrFPL=Qek#^Ow*o^6Ba&=wYcp}39U&e{)!9cB2hhl z3B?txD;taxG@0E3Yb^SU62@itoR@p{7U#1Qy-fQT;jjltAH83aNxg>mt{YtsFSEf@ zv!C2uAsH++`=!^bT?+i_vkBMivEC@$qVMX>UEptd5o>KqkqD8<9YM?&qQAfMWpTF> z_&SAj{tX%g6uvrF*`!$@+l5DoJoD?|N71dgas0VvN#h(do#KZ=@)m96^$ajXXWQVG zS~5^5cvQS{pB?6__?i|6Z{b{(&|}mWa2}$c#dptWK3L1%c4M2G8VX#r#rYelAbx|y z;SJW?u!Sjp()0ZS0%NX++3EKI>-&x>ex}UO^N1J~jqWx8KD_KD6!qY;^urySf4stU4nDuza@VUWXE-?+DJ;@Jcy+8J{H4S3!3zJE$&}th2O_Qo~LIJ z!CFt{2TaQEfaSMQDHbd2vl!y2$+%yM(o>;$m--;EIpi`W%J&ne_#9s2q0M1KmGVw5jwv3&*?-rH6MZNhn&gEs z3#I1wiy5GKmZYuj#dH)Xu>CcGh6}P-m10TW8YtdPT35Q4j!OK=1_THMVQ#X7=~>+G zL_Q44AkShzTqZ>zObzF)>kDc-MOUKJmmL>d@I9gzEve{%eM2|7NLWR_lEMA!$-lU2 zE5H_5dO;J)4mE#=JZ`&83^n$c`!uiC;+%oUNp`ye(6F0PEFYgsbEgQ#ds-O)#e;$v zqbz2)K-B6?LbnOF9Mls`nHs_P!iVqUH!zPh<;ywiBaBd(_cz7!H&;Lvm(01<1s>S+ zeKYkC`@szzm2a3m&qT8&%!9L%tWd$A?R;S?0c=w~X~rE|gv#ED@#nMReuS~l|8(gf zV5|OjE>tiZ!S6M<{^;?;Kb%`s(|LIQ@cE@p&gn#C+qlrvgMF!Q{>j$YWHG?mhawkq zdD4+?Gq}O2!3{SqDHQxlqlK#0Lk1^=asEttWxT%xD=aH0xo+Y_0+DdLW(Zj}s;*(o z&cA?lO*s=>9G3~8{?g2)T7|cuTl8Rc4EM9YiJrC=754%c`w2@s!5$zh+Lkrq%?)3^ z8GZW8gA^JoWM$9NXCo7*)@LoeoUn67JDJ;=29|d{{p0PFj#`tnQN(pzw~JsWRKYj! zaN=Z+ipocDA}0G!WDxep_TMM37T*C;Cp3LONtB{@Rf5RG2JaUvdO|L7k-_<$-Y%9W z`RMcZaEt=h!QKv-TF%1fOm^VgqmFp5k)V0-M|G7OX4*5?t+G+UnCI_|4_dO3)m)>w z81`}WPUN<~7AJ%MG>sC&3#tH*yK$Wt)(bK4{XL_4f*MNaU1NMbn-9EAJp%2dIN*rK z8KTgTZP5B?m+J~YzJI%n)>L{p;FhDo$j!1!RA(*_HK{xZlICY}Zf|kIuOB|J3E+8` z{V~}$)%f|ZZHOPG8gVEub4a(JoZ;q#QO9+HY}z<66@CuQ-ll3&#(IObH2Wj! z3!E?|?#C$^X zuAZldUnY(0Re4H*bov#}v$+2GlUq-vuSEu%^JmZdH>V(t2n^qE-YsXXSnXY9)0xLP=$`3cHfOf?f)(Im{SXpuU^iiBk_Dz%UsUOS* z%bFtejAWSGb3d1xnG4UK-77k>mnuLDQPQZ5DJyjF`IsJGJp;V#ij-=fH-X=oLDM5M zoUrbkGMC9PIRwSNd1C@^(CqjTi`%&FS~*In@XeJB`b6H$Z1v7Z6xYm$uE=2@9J%}N zYFu9>{~VpxY6wBU(|%lV!ai%++pD%2mM$hQ#{1`vVmFp+9RSwkeBPyKswEPkT)ByUp~hNqk5M; z9v!8JsigY;<|nejXo~;fH3Ke~@y;ojesmCM-QPM-o&5s557_lef6ES4d4nA}Oe>K9 z>8E1{xc*m(cqJ%k$N_&*zfW+)I{!fGCDuyrYQQb)qWlxr136nC8a3?6A!}Vk3Ncq6 zdQiinre%(GU+UjBdfWGa-I-ff->{E^LxZ981Yn0=O($lRaA&>4>`m9TMUP>q> zcie#z-sS!BssGJ8U}H9L!UNCqKYk1M{-f{*@a~*>)=XG|L|18Vc;f!+uZ)aF?8h!3 zQsyCJ@VpQB-g311gXgQXN5Z)~7BF9uuJ(;M$z7DA&vw{S!wsVj?wJ~SkicMlv6sg?1=!`>bNU+}Z4( zM~dkvpx<-zo9U6c$l-Izg#xULZvCB;KCyz&frG9DzVa(LXZ7@kGXA^>Jkjkhu2=(W z8-*u+XH^2hY)NaPHa3_k#r(mpVHxOC{ZPFnj|Esg-=)TIKV@t{d)7yr5ZW8G5IjCr z51i_|dv9Q_)a}ddj*agKA^ohjNZi+IK%}u^Vz|QwUmlMZ7~SXxZM1jG`0d)khV@h9 zhj|>3P<>FsS+5d#9qJous0||NH5ubc3anGIrjKk&BZfxQ#(ig-vQb0c%XH&6-0*Ay z`SLOBn~sgRfAoSz5%34(-)tZAz+4fZPa$0lFiSI2CcUKy2;68-jW=M2OH3n3<^c&* zWu_LTGOY%R{q4WMjq}3g+E2zgV^~ioOX;pjVh=c&Dzzpsx7k{3LrO?t07bbge<%`a zLSY^HRZX5;kl?oaxN$WxEZwtAb%@VJzf-vyjVn2ztGaG`#MBzFCR&eKSEvFZuj1lZ zu>Obr69c_GGtQHxsMehq~3i|J#!lKBJ2Y@wi?Kww~fcUn+FwO?B+}H2p>M^c*$KWTZ0jP z4TCpcg%$$U-i_D9SohLs}PatfZ4e(gSkht7S90SfQ0)f!4X1zhHSZ9LJKC zq0p1}?&V~1LE&q+Kh5&voX|XJ+s^tPFw|IlCdUeMnXZ*YA5`^%=VEuIZ(QsFCr`ah zo56VvHb=SjjP@wuSNdBO$4^#(mvk2G0rsr0;`-S6XuDky6xq>mZle^%yjjY1{fvLF z!?n49x(^_3aB=>f*8nPi5So}7!3&w}809&whk!zOz(cMVPf*U9*)|pKBNo8D+C-f9 zA$?)qu}QQa94Wuxy)%vXj8FXv@~4TQ`kF}Vns^nkmd@iKYT$+$e_w=mtf5jEYgXf3-Q~tHo(DA|t8>#!{U@_}j zasz%H7=I)XMAsbvn?B>;o9{A_ze&^M-lM$mrf*R77BLf4yj1W~T`UE4cv?O9p@DfZ z(BsR6pk1&P_Gq_hwi?J9e~Dd*W`~(Z+crnKDuEaOPR5$%Ac}jXzAb}uE6R&&IGP#1 z0)rwud$05DVC=$n!iA4q@arw=^a%BFkj7baDM8N-P^;WGLAdU{T(ePhhi?$v%2G7> z_`Lxf+o&zK!}=MqXxQb~w*=^^t8^~3zed;0$ww~Yx{>|sjZcC_gFx)^VWfFoF6Q=W zoqk@*4YTQaZg!|u0E-UM*)zF=DBY33UlZR`KZD7By*rO{daJrFtr-@9zv2$B-hIY% zSGgAz#q9&YG0~Z@^KCu)aYToh6Z=CaUi!8qp5FxxkG(h+N;>D#~e*q<@Zy~XKxhRh>R_pKuH%yh94FP^`0FwLI7l(pb-?Kjq+oI&$~u)v;bW_Em{MEwd4- zlUKTxg6l4k-xB#bx?5mDA#Y7$HWv*AYd+V)a|yYOI1h`oL*N!#b=;H*KZn{fCr|3) zy5*0R+r=(M=yiW^Ry3s$Oo1;h2JEa*MP@_Dq<$K7Nj!}V#y(B&*a|VbJT`cb?d-Z7 z?%%hxYKgfP^N?Ginq}Y;C)^)q66q$bM2$7#?16@Zz-auA!zlLCF+6#`aK?}k^O&u~ zt`MZ7g^h!>es5M7Za-oboxN#?xuAtJr^uJ)iQ!>p_eD)kSCn~Ydgx*xCjCb z!yNtu^30#5;D^<%I6>@dYjS-M>|#U%gSKu5W$=~)1sjIikB_*ZjqV#SZk&6M?Baj@ z;><)%KTwvzPfmD(#y9p8=1aHleFaJn2XxJMc zzAcXZm{###1gD2U=OuH6s3$S#=RnXoFFFp`IU2AfDZB=zN2tIg)@^QXsSmkEW3E*4 zRe~SE?ZA_c$!B$`A83Wz=w*N7fqi(~JY!D@LmtTa6*#1$=&_><&!*X+J5_3RSLr^` zeDx_#>U=4p%AD{B#@wMobNk}zN;(*sW%G4vD+6iZ5WBx;xnWPu6rnR;KiIT+S{WhJ zh3=8VrOaJ6XqrUBclRG9q})9;eI4bFj$aYw*s5oPd~!CdtDPk9l}y1quRrgA!0q*( z)Iazf=5-rnIzb7wx_7nyIk=*o^dap7tgB&q{hzPQjY?z$Qz^0^&XO7o#H76wfFF*j z_`b?zg00>Rx7K}a!2$8X!5HS(dDQ>n=}2aR?_N`8AKnc_J`;UhTgL^U>+L*eNQ!fQ z6r#QxmiX@jnyoVm7@<4IfiH-xUg#bVMBmg0E97y`_Hb28_DLsnV~sBCq6IJX-1^T~=En01 z%cs#u(^^(Q>=S=EORKZ5c3yg8n$D(a48XQEn9(+XgIMN;_8YdT0G@BfU%%nrm)+{jhm zuI%$dl<0JK>iJ|wM%`E`QcJD!jUo=)`;P&0Q%vZnQYGk7lTPoSe) z=*0wuBNIjV?l_>|Y;K<^lLcU~2hY4L5fhwq3M#GLx(t4hXL3|wJzE1g_1iA2Z#5ew zI;quq4^1R9S-gEA0N=X}QT8`8H^yF98)G~61pUh;tGf0K>p3ac$uzi0q4IR{8Siax zbeFVzL}gL{YIFPOopNPvoFRXZBjj=k$@VknbtDMD#Hg&J#$1>y^EH>x0_RED3RmkM zlfrwh=08?0Q1mn&T5PsV4f1=<07$3aUfQ8d2Zqe-j7Viwkm2;K^ez0qvu9$AuOl2 zrCh=MtFEDI_vV-zKYr!Xd&202bb?=NSYZyH>YllC>>6`p|*fpL*nGao<}f8sLmld-GPv$(PO6IRqIa(4usFNeV<{0H)T!?)x0Hz#H80b zuOvK1!}eExlP0i2yL_VcWeIY~j;W&R3?3+oU2^j&<_vtg+t>f@ITN(|I=#hPq6fZn zqJT|=eQ!rN*pw;s5}zm;OxMKR`1w!5BM%*4P^IrA$wS5h zgWSoMYbi*e*2?TPA8QX##X)pO_y-?6dF-N*g8(IbRzO+MKj#PB+)UZJ4)K0=@LWZG z8xwSyD4WZ4i9q73`aRnN%#gP1(3Uxl8173ahGM2M;OQ%TnskK~QV<-x5XmBg=2!M4 z=XG3hZlT4uig4@)A$wo8%R&vmYIQ`vFn0xIDTxAZ4>5N={XbusptT$MjfSn}vqMd9 zt-FZ@U{aZa@6Z7q95xA>5#e{o9GeYKo0B-Niu}0-trJ}%k$(9(Eel8V^TMtKC!Qym z?@GmV{$p-DrXMXn{3TiVZ#P7SFHv{`^RCn5pgNU31^Zzf59XY`M9gb1! zH*pV9VCTPno0~K8iqCB-!kkaepHzA;u-<9^N!PC&Y9EyI zu|OgG;J^H$ssNoQq`&o0^1!rbrX9{-IOe3}c@690o>}dEj(Ucas%N`Nv-x1`18x6n z(d00#F*vWC{x&c^G?Fl6!uzI=+K(T*k-(hoB=<{=_JG~(k+?4pFI+AEGa1ay+$bAY z!y)z37X2KW?fZr~dtF|PuajAR00&m;oEc$Pp!nTAw;j)2`(KjRNKH{f$+TH_nV0d1 z-aye|5bv*9%--HR89)c;97R7|3k*hryREIu*#hvN`M@{ob4+ma@3R|!O^lE-b6Md9 zI~F)3$x_FpMFJ&UU6oomuo>^!?DkhKtW#>|@mS(H1Xe@(tyxC)s6of{-b5qjKP*u{ z&b&+sd#}jlme56@({FAJ7OpeHs|Ob>O>n>Vv3r^5(XUukD7W)I9Q)U%!v9?&S0snZ zwmDu;2Le!B2MuxSrU3lP?sJcvh@~<1kK$QHMETVY;ts`B$~8v;8Z5Cu9$ zdf4CqwWaDZ=1!9kf1TVmibW=0^y*8hd0|%d-B6MiA}Bg?=b!YUGmy2gh!^bTh0Jfa z#z(rDp$ki1?xSXVpevehq9cmW6URCYJ~bK`H=RzsIdvbE@IB&V!}nt*-$(|-6mz4{ z+rZnuaf)&4$SV02ymwxxWbaSkWp3ntILo{z?urT*EEWIk3;eGhwQBXEa; zr7-~a5mC{B(m9ay2Xi0o!+2^n0~SN@!K@E8dZr}>knu)~+S%puFN)bQqe1E)*2 zo}lT3oonI=}f1Toyk4M|l3$HN1 zV=Z1!Gm8?y@=D;1Sboe?`Xb3G9Zw7OSwmy82c9FFSvB5mQx@2-=e81dg9K(e=ZM`T zjztf6zDWcYVI9G&vE(^Y+?&$nkl=I4(6$qGc*X+==&f8{;8Ryojy!vhODgt@&4l@Xyz_~e%b$&ls znBX0WzRX7FCx|>ZX{wtK`>YQnEmAR`xi~^E&Ppl{_?(OsbH^Ns6PAoyr$ZRvy=~&g z_#aNdLI^y&au0K@muy;cZOPzK9behQO(+&GXq4=J@;fFJ8(p@-PIC&-a^r#=b40{}D>EH15%ih{!Qop+j$8 zZBnc!yc6w^+IgK6%GN1A8U5sr(lon6gmJ&{HRj-aXBj0l=kOi9pcagN+RN15$2w>A zu@7sEVz|z4ktcYia0`hBFgTRq{R{uingA{QI&iy#Y}PIdz};h0oQyx$^VoH_iT~cf z>ZlXx4lkO#!p_?!$p!rePHH{iXMk376_@450>ShRAm&gi02w+vFN?lng6ZDF#+5ZL z0MniJG<_5m^mRbtp z{p;4Q{0ws>T9=1ask=Ra1sCc1d19Qa_{T%B zqJ|!d$1?w1ag0PiMX34fiCJM{_&?LPo20Nt;NSb{_($k-!|@jDn>Y`SVkkQK8J@#a zow}VlSUasI|LIje~o9%!2mmMk_1bv?vq=tNFq;8=4yGYGp(t!IPFLeGL zu3C)${iG?!A5ULzP#O9wr%_M%yBwON+z6zt@)GD)Kz=)%MUf$tfoI zl;BCUN5~COmK)1c+{_Qt;YXs8N3?J%`&O#teQ%II$hY|ibEt+$Qg^pzso+<^MLNrR zb9BX@m_%t0^U}+jOWpDPm1QihvMsCxYE@iYMKSlAUNdHMtDd=W`Qy=I`hT%VQs+3~ zDJ}uXI>=uwV8#H6Sj>l*5AP#p=XM$*0Y3Ph^pAfQ=Bci}ee+9G-xUSB47$c+-@2>K zPK)1JYFKEveot^G1(=9vJiLH;%i6c41T&Ht;8Ai3zT%EMAZ>X%a7>XC>eR52(=cJZ zMASb!CzWT&zj!}*yb$j(cYjk)j1WQhs2b~dnH%W+9e1(pXnq)bLGIJZFW9#}-YLRN zY6{eai3|wKSupRBh_+UP6t?(!U)qcgMUVakP!LV?!N8_qNviu4(5yC4U0urp{8&7d z9@)kZK{~DA$Gwz5dT^LEKk;5j|XobEE_p-Nv7< z9*Ope3@r)N;}+UL7|0BRx4ZUz)`_6rXOFB>-XK6F(kl+jaK6b=SVM7<5)!UisH~C) zBhl-catDuaJx}YhyAj6NXr=iy`r4E}ilx;HDr)0{g~5a`cfBZ}!p^sXDfhb|BvIR! z!H^$%%e#496QqFxFNsUeQ9c2==`p_4w#=|3O5gV3TOt@SclXBZmjLuG{&9yH&c#qn z$}6tMed0mq)4Gvef3)MEYt$gl4*BvfZU#tF!6o(>8cVGR&{^BIL<3u9LV7!e&$|gGMM&9;hbis6}b8~#+fr*0J4n6YUXb;H@aIF+~;--NAJH{ zE^PR*z^f+$AHJ9-fr@)FKU^dqqs8mna;ex?rDb77zJT*(_HQ!9AN~jdn#XI6Ic2a; zX(PAHe}M#!2$hn*{b&u`#Hp%ZV@~}spCbpNheWX2)phrFP6C+w*4Q_VeG?xNDLbEI zACoYd&Ul($IOyY>3QqdO3QI#;U_&T5luazFocFr{Vz24lGs(fvKS88n4Iqb#6qJj` z4=e#uc~4XouA>}YK^G6qd8P@HR9Z~Af-JsyvJe?#p1Ji^)w^e?Vb#|0C!%34sOxlx ze_SFbTyJ))l8~Z@{p68_%tSZQH5udzNx9&!#w%tuKj|S&%8k~T<4?iHGd2e43SRhi z*!}X%Ln0VfuX%Hi(H8s})3NKudWon%!>Lf z=IR2E&W1!hl5V%#LX!M=?{mz#1K)%7YrpwFJbr;P_^XRIPY6Kvto@>+Y7DU9RXT5| z?=__GGd{Tn`)XNjXGvb)#(vVN_kWX(%z=p~A-Q)uI}9;v@7oNchF9a76)8VG0H2Td zH#?c*I%>VH3=?F&6*P9jNclyd-NBK0rdF|opr zaaxfPhoo?i^(#~vjs*LWohKCW{djq>+VdZ-OXWi@^$dJ7-^IFXjl#>kGqafM zIP~-mPo+DO-&$?*!hR@CTau#!zsX>?>@JT->N6B*XK|RSg?$9S{OPxYNFmL|=FzNC zd%(uzEWe8D=bm*Vp*%~xZ%Y3^L|u10m0$cXd%IkFQ!86`9E9{P& zri=e#g2Fvq5AeJ2!N2nRoDR%w09m(km2GVobWPl!n;M@->)9?VTKGLuiu)7MC9}A>>));dmRr0$GT6`Phpxx7 zeg|4usF10q%jXDWB;11kcwk&;+zsoHVJ29dR2YipFC%5q*ZCV*S0QJDZ$R=Y4SfDK z{HRf(8+s?wNzGh_*Sk68M~_=X(jPclbo$~I@K9xm>`W&IB*mY9sA)?JbKM2z5ko34 z@|&&yhwE>VD`xBKh)61A*0L<_&jH>CbNPFhiEymku$AWvIjkQ)$9Z7X9}%o2g5#*T zVK$wr`4Ox${6d+!Nb0^FsC;2F&w>B1_`O>#_ITWC_uUIOGBgD#%Q05s%R=x`*qKAQVDOz7o`hY*z4qaR*=El6g7dHm?F+(#i z+Jn>TSnuvw|Hl6EB}6YBt7wRI0Pe_NJ)QoY9L9@^?<}}D zgVCEbv&WJI;OSm@1Am+!d9|x(Tw5*&MZj*xAD@GN3ztqh3w<^zR2=6HV=YKzYOO$SRI`IN^N-NAuq z2ah<6hj9`O&>UZ3!FrG)>L}6y@M(^2G2Z2YowJdI>16yoTYvWApC+R?PxBnzR3bcB z(EgidnhfU3>dOy?WT2eo0>_nSLa-^BcD3#kD=FPRiAt^EEQ%!5_Z`Rn5$`z_X9RFu z*Wha>BYw*TTnZJn&$*BFf|5(#J~XFvIlGVA~>-Qs++vcwm&nZE#(^+ zJLZOt2XVlHAx_M1IVX1~jUFy&-8(mbD+x@2i<}2I1|bO zRg3otE{yFWDwq5A!5vpXZ*M`g70#zh;`)vL{UMTs`Sq9hGW|f?A@;TAWx;MK0$jn* z865+WK7M$(y87aiULvWI{>`QLpUjZ9H`|#s?9W^5sVp&r=clgvFCABpbWoQs@5(NqN#z-DM>;R9sM|v^$Fq+Frj%hW-1f%8Gn;hN)oc zVu=wIRVL7X^{Gr7*AEl7t!y*!`8&^Y_ouRVBH&ulvkIT$hal&ngYRR!KYTVD2(nHC zFvbNl!FZr_fb)(Z4FMiYjTd^b?T$o(^x9OgKbQahw2jOFM(Cy>_nhtFRkVJC{m%u0 z0IZv}iRQrl4)58wQqycv$dKW8Y3mg}_~INhZIuNp41X(0tSd_cTyq+ox=olb)17tP z3ZIA6-ICcSV*|k%`=uf#N;U{9nqOa_rht{dB0j#wyrdz&xUFmWTy~__Emy;F4l8kw z=?s%Q%Br9)&Xwkc&Puwzlz3enxqqx!>Ocix%4}AD6i0*+^7%5qX~0}_&rG$DE#rx!P+)?Z5=A3&uA2j4;c+*$L3MY5IyxL;22UES#j+~?HP@Lo^#eJU| zw%KqVj{D$?&R$B2TS~w>vG-ZZ@ z?!^O1Z^y?`E*J-Od$($givVw0+ns*vd;{f=->sJRAwo@>?)$0gWblOK2MU?teDr5^ z^X)-g=TDj(rlnaXk`iM@o{0xUgMi6pDkH3S>TezLJ)e~ol1_jB7}Ml{-nDMUSxE3f zae0cPAOEsIn!)_iXVzI@<$CK@5$=N+Do!q(ETn~=WL@$DR{}ssAs=wVxc7{&nlq1k zKcMUj@~mGva}g;|{Peyp0eJ0vJJWyqx3y^o#V(f}P;NJkiQzaubhzxOK#P6Nj#%_H zjlOaLo)ldQTLOHLrW9Ce3b4YYRAs-RZ3n<}Jm^+#0?xBqYXqgKY2o>9M1I{c1kF|+ zA7c_?heufy#q8E7;nZ|PfvsQ`YBx8cf5|NXA2g>P--)DvFQ&B<{J$z9j@W8)E3Eg( zyJtSLegx;O8H;-+EPh~w%Dr12&sz^-mH35CBI&9ghm23P7r2z?Z~{sQLbD1J)5!0% z(3fwBAI9gYzDZx$U!3nGov28;i}ldBN4{u@j|;+yuV5yU{5PHVG&eAg#VJ1AOq3dSUmhY}0``FC^Et^ztP5IZ+c325NF)($^_27) zJdv~Wmj<&v4md2T`D+j3b9UZQZ|$02L{<+`n0-Cg)ycllL}ft^L6lSKYOW7>LbPY) zufqBdHz&*Ge_%e^oNMDea~Sv>lx?m03D5t~|2~N%xmXcygF2FWm0_u6)E5D0_+x?8 zy-p<6sw7;1tU1V9Idln)vioWnZIU(e=sV;@`lpM0|+)X-S@ z^uWM}XfQcZ7Vrn>zspL3y{}e@(4srygQAxnQrS5CI2p&`CV%w?NJT`_yUy3eY0}xK z|HCKihPP}`Cru|fCyx>qUtRS}u8l-GLq~sZW1L&{J&I0Qf9$iIF8op9O);<#yWv#C z%?0Im*Ve+d=;2Yvie(3ha=@(laWZF}A4-Pnv1{Re)8E6q0&QQs&?Bl%co6f59SSs$ z|F=&{K3_MOHogu#l2SyT;ym=rJB=IQ1(8JQ=-3~BEECWwI!D#eVm&VXe!B#G-kqo! zhzpYnLw~9ezeOVURkz4u>%$bx*%f&i@-Ods#ioL$T-Sg2;0v_jV({mBA zKZ&F&?SHSFsr^Cwn~QT1pM+o@3K2=h{nKzeQIoZy0K{f~E<6{ni&t7$5gMO&FBKW& zRcI}NekoU1(<1>GEF3nFnm`TtdJ}9`6>ZU8rqLnOAtC4$^qz(v$1RqXpANMbC4#m^ z(&5o~0XS^=Zt~h^Dkzp}o2en^0gTTzRyAVXX2vEd7B+7N_-MeZBg)YaX}=?G$bJ=q z97>tGU+{gIXKa>@l_SBi)CYsRRebQ)&$io|6*vz%*;^dO-~-4rZ}@m&{9Z1{WX~w9+)9Xg$dYr8evx zB1(>OB0>0W0#ORbC;wYluP?5D_eaVAZROPI1bMPS^^$w4 zqfaRyGrNeT*UcpGV2|}G^`rp&&dJzyt zOqu*+5q`+dD#XGgg6pg2?^d~x*@1mgW7Dlze;}rQdo}t!3q14w#-S27Pc)m<#nv3h z1_@)AN?RUK!0R_?BhOCffeaM}o)6LdFh%aQp(w6j&CvuFACC`3zb%dbRo=vT8HeP{ zZ~{5xiz~k@`8^tp86EB)55;~@#u6z90`UG&0TqU6L%?Wns*{H#)_-szFLFM>3cV8~ zb{X%7f+=nWcdRT7`4$sCQi{{UW3zO-8aqzl9@8&O-(iE-CO7wgWy1`zgjhv%|@;1{Q}~)NoMDw!A|l0ZrNnvx*P$ z!DotbLvjPSUwUj-Oos6?3Ke{6(un{4<=}Si2ug zp2xW2E|HQL+dOn`uYRzCniI+lsKz5kI@nu5*9$#eL5WmeS|iT;dT6$$!|;3Is}M=8 zBN`%OdN=A!kWVtu(yu|c5mc5|6s!X_qgAVx3Nw#ZEx#egADS5{JQ|fHcCuQj^(T4&u zNI57_Yeb>|yHD9C_^_Xp*r_Zo9s=}bHQjq;>5Z6=|J=v^4ddTp6j+<@F~ik_ME_r| z(I`Y^zUcWH<_mxS%zqQ_hbbbO&gTu!08!+e4O-X8`HO6bn+x&aINcb%@d&S0oy za`?YITIr3;yw*8Gbd%YiV-JsWW$I@tPW*lFYG9ipzdms7TUHOZ!#ql(O)dpF0wkB? z7owHAj+W${I?C`kR0nKKG~oC0Ez~mlw}cKd`L;p-l!p@zc(6Yb7Ndg{eM{#JzeED> z+Sv0qF<;fna=Mw0lO7T-bS->|c1N;j$aOvxV*Zhc(EH0v1n6?(q)2Ue1rUAd)NpQ< z6E?(|s&IayhX+PCZIN*}=r*zM{x`(}$L~<}h5GG*S%x0>vvN@&ab!wW82fjOjb#^{ z7$=ghm5yE(S;_*Q*mLxO6c2PE7Myu2Nq{psgg4nAT)=4C&X2|bjK>&wvtpD;4+ZC} zi2=^l!1ukw(b**-ICJUwg%&&x2UsOpqzqlrT0jXy-&f2l(bNyU{)GviNlU#?K3ocf z_Ew%=K8^j7vMbs{hjAQ|f2vj1H50vX?0P?r$8-46vGH_`k}h7r}@=B2tiA~i&=6}g6URNucfAQylhPJiv(@a2Xd zsuK$i<9>m3KY2}ZM-h0-tQWzlfpsUIsi{TH`2J(X zeX&RREL-oKk;T}W~JBA#!ah6ZN6 zv-;?u1giU*Dp%vUeeslT{>#Dw5W;Ho zE$J^mwEVeW`8xi7!T!@5zN5GwEy4Jcsf7sRmGv{qY{{YUR?A5ig;+o%9PM_x8^bcQ~eh#P(xdColF@!yz_jr&J*l-81(hu58DLgQ!}9?v<)b@qTIO%%YeJsCH{1}V(zCtUh)-}AJmT5p~$ zSfPoS7cgLfi0$`j_**dW$2=4?pxpJ`)pox)NTUd1@%DwlY^A_gqx|DVG zEYT6*)^zT?MW_?#pth|VaTJ7OA+r_9>o_k6vGUozVGqW};!x}~KcxPt&YSd^ND?)& zTYP94i2J7q8To?v@eGD8~2MU_`M z6kG7VM`VsL;b}b$1hUC&iso>CC&D+od5i{TWG|%oCtN@lhF`v>_F?@raj-rb#|+)> z4BoKl2nDUo1>?pT&unJ8u}d^yhQf{J<9CGeQBc&(EwMOGsC0lu>e6*OjElcqUeIw1 zIJoCp)?CAQp0H;NbT9YAXI~?d4&=L|{l(bt{Q>4bItRu1f&HoTil3uISVzrPUIiC$xt=FK*D<|SnL)b{Am&O zd>Nnb-3~Xa?+a(6+wDW$?dABq^HAGIq0CC6puJmP%V>&jOQ|MP<2={t`uP_=}O5VQ6kAP`lfIImobugYWs3h zfEU{Mi;P@SBfw>9$}>%*LPX|}^JnT24~*Zr(8~Of0RI`Jon}w-1iT5EYHb@rPFg(4F!YDm|rD01Z6Q8Ycq74L;{2%EAt1IB$ckd(t)JH=*+ z9u=4EeA4ECUT!w@Txr-JyzQo^x{5VQ+ow^Yd5!~K>B)Ju6ifrf&BmaG>UF@E)RLgy zM1;bs-V9=n_t^q52b!%1KIuGku>Q2qj?D&8mZD$7brrF?|?5fYrSkH6O z@jKVJxeuWGrDz^y#|a;`wJ|Wa(!qUKKYsaf!XIoG8t-i3K5XlT{}o4^KQ`YgI>eh} z4X(0$ycf^G53AY#`y`T*KiHC=OXyP9VCSC}#q&h}@Mh7xEXH;JU9hg3HwF86KbN_r zbHZyHYOKF7t};i#Im}ck7|C7~a;v8yLijSRffD;f|6C^*+6G=b3 zsg9kY(MRhlU+a!)2*TC#X?Bel=-^|zqAOwz_DCmQ#PB8dK^x9#H}!Z#Pg)M;&Y9iv z2N^||$Hj&PA%n83WcV{yxTfrKZsl4ovM5_>E*9Z~rz^EnEE=$X(Bq?l9HeX{%$LM6 ze+QozU*49Zk2rr6Q#Q*9xB)7S*nd85#QImx(O!(|*k6^byjSpU4D#fE&umY^c<=3c z_5!?K>fd{wASh)3JFp$Noh}I7WVRIrF+P?ed9L!@?I(n#Klu4xy?MFhzf&QSh+X_p!)OK6CUN*w`lFL<|g|kK-Z>v+8^sG zf2Gw|o|vM7LZ`@HPqDSFjaTG7|R5kiXfA{p_noq=#qs!^gHt zhkr-b0r{rBJC<}D(4_t0W1(8i_q;Z1(yM(7aCS%)${b;b{nPJUIQ6MuP)T|>VKWw# zXg4!cNMhe-_jWet5zJFq9MQ4IuKX=U#sjyExN+R|K4l>I zzkE}}UeLNZ!wAq^D!cJop9hM^So6{8;y$m$Ui>Q^Kd|uXm~L(XE37zVz~UvpAM+0g z1G6T9s4rp9|Fk(DBqTF2hM#4HSMDD!3z!QA9iN-oWbnTIJmnF^syLA(kl}W4HN*_K zczmGTHeiQCUTH&<=~QrRm(yjuAp+c zT#q_fnRXD@y=?|*#A;`w!25x-A6O6<9Avn-upYt)d(J$!_HXk8$6oVjY<|SJ+?)$H zOe4sl+CO?n^Sw;)lE}uIi1qLdY(*cfeqn`of7!kGM3#+Mvd^;L$M2EQf#BI$TvQlJoXCMY$OT$sUi!i6UCH#cy;))spyt*av! zXxc>@@w^xMzq)~ak6PjSVlZMlvFxaX&skGybCo|ho_xxud-{&PIT%=hg>DpF@I~w` zGM_Pe_{?WVThTlXP+0i`E|9!7OCDs{R zUKYsv_b(QeBH#YgSr{)$=Na6ZiR*j&o~n>bSR;zydfE`IZ&`hWwSQNE2Ac7H**@rz z2_8DuF>imtI=49|l9@3sZh*;F`fK$C#5nO8q~r4|K;5b%*ozuIm@utQ$Sp<8=283% ze{sLe_&hKqXCsB)Q7@KkJPW9lqYYM%2*M$Y2byNPm2Vi!+lYtWBgkK5W zi)z5TiW_x39qJmS@>DpKLA^qJi0b6+9UjF>Ab8y`o$po2IB3xJ08#tJH43ES7 z#l&-}R+=E)g!b=ATnFHyF<0HhIO?{^hcaWYoI#kAb)(bXz1dTxB)y;n+*QpEe7Waq2H0ld;^dne*)KkgH4iY9LF>-w)h z^`T(yZ!Ss>k7xEd!3iy{9hqSZq=T_dS8sha!+6>$>7+D#em(5>470)O+9~SnYl)OI zpq{(mR}%MmH@Zg4hrNj;U*DLs%g3ugbV;(N%m@wM=k-vR_5`X4$TgchR)MSy**22) zuuq~<^%6gR?|s(1TJ;Ui=+S{|90#$^1N*1gTjw*F;5XJond3{h5M{`I)kI-7r~(3Z z=u~lE^=J1ei&!WM{U_8Qn1bu8j@<*%7*`ou5j7+F3HN!|=Gd%oJu@yRBxe`r1+bIm z-stHNaAWDG$&ig8JXd1KHvkz(lM7l#_nhMaUx#YA%{H#XSl-*3{E6ePTrO7jgedf{ zx{vqcQz5viv5V>vX~Rc2{~EGgA!T6w`GL4cIzB(HAz8&I(T8ze zYxj_z)qWf|CQJ7ms)&dIWOv4N+>J2bfJedSKr$Iz7I#W7*^CGDB^RzR8Q}ApcgIfW zDkZG+?cr0rEsgYaow7mf|MO6Ux)197(=P-+ZVaDl_`#2T8ip1Iu)qA}*Zh39?4TrHLobsJp#?@9Q}JztkH1YL|#4RQhBt~!iqYk zaUFo|fb{QnjwB$T!pBY(&J73pecL8hm`H-zysD}_IB!*OKAT7@2tB8p&rf4K&*G@r zkEf@dP{*V9kp+Wn&|x^ciz1s6K1#T#(;ydus2-oGkK!jnLeIi<6C2hcA9xYF>zInN z-H)#fm}33C9`U%XDy*k*oGwPZE(q*!9#_r9^KiROBKabo&)Fxf&p>(>utsrFZ#CW`YkP0}gf#DsLWm#5Rh7+6(j1{27?HF%GkJ;hOzWB`4f;vfmlQ zI720^jz30!BGA?Aq!%pM52Cq4S8(aSz7KVVOowy;u;RSCS4zVT$rt-&BB_`lkCxOq zGWsx}lV3;|{vPuR49GY`m&cG&{?o@-8k3X{EfWGHSpZVI;!1e2;dwqqupfcyi#?%-q z99I|n^{j0_EECoqkAC)Eorl>;z#yL=*3f?BoW^*nbe#fYngVlV)^**d8|MYH;)w~z z7BJ4FE9J0Njur4u-Q)^ChM5!xOy%FcfEZvdoDC zGL`*tzJ_t^Eu;dWXI}OonBjqfIF27KCV0M&#QO}*whUXzo&}hg>1Px?zygoY1)bQ>5_SVq4* z`kEACQ~fl34)0fd@{&TO_AtxZBrUmwg9Bn(_K--{cGzg_OorvS*U1mdn>Dr2Nu6|j8|$S zK>HhxPrb>kz^K!A0aLu*V;dMK4&pw0N6NDFm$_&(K435SdJpR|^@=hn3@|}Y=B0EN z+Az?}d6#-L@UCBdfQ1 z16UtVTdMri0 z!%{j|O^_QX3ug!{p5uerUK7aWB~1*sjTf1CUJ1NkfU>;_M`;9b?`tG`Sbq4#Qn|HGVk6qwgi zA*;d#8wIJSANw;v`XQtG;xAS}==mFUSzUJcipGc#&qf8)@_G}KDGEWn1Jm}^A6ReX zBIRst4huBnQM}G!d<%>Pvc{jp^%=BN`Q9IoXU&+-XKhziM2M5UoFXg;q1oUa$$qRC z*Px-1Rp$aYWn8^Oar_fI$&vX7&%+BR40Y{4X&^rRUyi;le6Z?$)+cYSPo*(;t_qs>c$1p}`fuh2v8-L%kW{+LF^DGwBs{100bazHj4=gpNy8c3(e zuJN+69Jscof1Shq%EheccBq1VMH4@Tnudk|WxbC>3S$_bwqHYG3&*{INmhcn)s|>7 zee4*imJL4mJp9Nsi2`~cm#qcIa$s}HO(v2B>uXUbQ=jBxfUyFX=BG~tVZCiuky|uu zu=d~YB3}Xp#&7E})<-)4`Hp5+DZF0=n(7At{JzviuP{snLu6=5Qc3mUg5f)4VGNxN zkZ9;#Xb>NVrmPQIapL&RXKbTK3IG1v?I>HT(!=1=O-0y2B?JXt>*gKXhsWPb%h0zr z39ys#vp>XmxyMog#!7#2eWrY$1qCq%bhOu4s9}9|!#q*-L2Fv*c;INssdXDr7^in{ z5$obc`-=?R4r76*K1NfwX?vlo3jxe@m-*rQcDjl#9M`G$*c4y^aAZv9PIzp}3*%2s zsjcd=K(`wQhujZEB4$>34OKJTpCV?N|BS-8l)+BLo6=QaY9W~+=QZ|!IjDOgYY_7$ zs0GCVg9q49FA=zVmJNP#Yi0wk;yMee>~8LmI)(9mMu;z3TL#gZ|`x1XvLFHgG- zs)|c&=kU3#@lndv8?Q(1FcD*s*QRK#<;pcSJU-9z970_2c@eB@a7bES4g?NzHfrr+ ze8Og|aeF5n39cnrbc%$dM4Dr74?h)v4U$COZx5)U?cYHPBlcrRDblHqUP1uAi=S%v zhxv5gvJ*dEUJ64|y_(c{_;HQAZlB)k(;)UG%`txq9%wp{ODDdbi4=@~ zFg_MKV;{o=pPdGKQ^{4JYeL_O9I(MX!aPO#WeVtdDyPb?DjLx6)tD&Z{D_iU>XhCn z6?{7CYe#yTi0(~07Ec)oz(oz=4e}KtNr=@~uDUG`953{$Oj_lGC%sH8GgmNwjp4KK zwMZwR)OS8?s!|XpQ7jIa`!YbDuR}gZo!!6{JM?=G-?!z++}hqX3RuAfa`P`cgB9~A zG5ued|3hBay%0?XZ=6>CqorJq4hB*8M<8!~Un! z5~+bV@VaKwI?B-CaT&N6Jbpok->=svHP;P1{)_*{kF0M%WD}J^7VOCf`xng$o7GvM zOAmkSFUH#-^xj-pF|Pl|XeLJezRdzBE99Sgau=Y2o-3!EFi$i7JD_XrV}{;;SKV$u zbwao|A03J7U98U86xIc_nBUr{e*H%YIKnJ%(u3=J%lca-6Ew7N?Muqb)N}F({NUdl z)WLq5vd>=ion(Oyit}m*qOPDLf`|O2EHHj`V?FLV-XETSbe~jzat|cP_R2^t@xfjG z9kn|;EbxAK!+MAFT~Ho3cYbaV>%F8}9Zbf&kLOG>JsB>sC`HaDa#M~67Vdj^+Y$GL z9X@F|&Wkys-uC`4)aGn3Zbj_deXN5$(RX%RM#vlcwy;;Ic5%Q1)e6bz1|k%fdxL@i&F;(aMM4cfmc)j?~y?e|TUbY0Ia*@s(oalZWf#v9KaLp z^oHBbnCENyuT}-~&a6+|eX~JV2pX3L2YKSKpTes+Zf*R2CjyF2+;(?IIritBS+K8` zK;4tB<%=xPu0gD3zOfYiXx*F|$LG$#MO)>1oTpcBfzfhhC(xI9wdEJ)(Wrc&&Pl}j z7>~M7L>LxUfqfzWa>%}8Jc)futiTaU*a{}UXn(qj>Jx?^j+9~C#m6xUuEVUPDVp+^ z`(@9ezm+E~iOpE|V4+*0i<<&Ei-)E3Cx)R#F5j%*c>f7Fn0dbu&;KOj?6F-NZM2iZ ztsrooA5M7He6)B>21lgjm6352(pf7DvGw4BDsKI02J7^2M9#2K;ruNWbnX;E;ONlvGj!o}VY&KG(ZZ z(7>Q~OQdBwc{JMg@7^@l<1z!9_l;XIUclbDT%R=ry&0LH*@yAEx4tYIwp<{RXu37C z!dtviJD1EUhdY8$BBH0F9^>4WZIw+XlTtuJMHqdnoFGhdAU~YQ!w8plTIyat%K=Qn zyo_`6g786?tMnKN$NSm)^&c{3p~BV_otJnV*1CihY4ACi`z%j7l>HP4`W`BfJi`qq z*`(IPZZgBXMrq4inu&-IJFHaG$p?G24Y)As8kWtjQHG_vqSVuOq~7DWu`j!_Q4_C= z@5>B(Zdygimi5Q@6Raaqb5UdS`%OC7`BTb;v9AQ3eHG8#&BzX4hbSxt6R6;wLzd<* z<|2T{gMik!08Z%OJLf|`hu80;&m`wVL+V`KV(qoK9vFJ)dAa^)BFqqz$eFn)isngr zH5nL3aYB$q#thf}l*~eSZx5z{-wjF(1k5*iJ=)9fjs4I~sz%LD+h?Fcc`BdDvpmpB zK=O9HCNq2xSNX-Pvl7<hrXex)yQ)l*8=eQRhZ@FJ4Vk& zdZ}|FGvIhIa4&x$HB!V2_1FyGGZkVUaYMs^X@NWH6Y2HjFvt92rF*1&BNmu-{iyc$ zcUQsKWK9AauMm{K?|0L16!Xnli$xpsvjFSWS+hS0Z1B(5Jhhb%Nr@mZxXKsr|=nqA{)@QcxO>_1-E&-1g&tJav;ujH=W@I3=v`1bgy7J(0X zwwUZ%(zC+QfzRI*b%KD>H&nG!gLzVSEduVHBEZ5W`LE_r3cwGA@caP;bHntqCmaCOb*ULhHkK0bcBXO+))GM3Dw6-4v<1R%ws^MJj*p#c_Di zj8axQUZ{E8~wK`+k^_&w=_@VpF=Yg7!aolAat6BHL0a3JevO4$S`m^EZ>}DlqD5_;E zz2cn#T*e=-r`6+pO$)A*K{`l&|FtMSXB(M)n4aS2&mChqoc2HtWHRzyNyE4u z8rRa;4!rIHhvjd_>IMQZDfVRw&+{?6a~Id~^~Yr&Z(sg#3Q6R%&)ewcK9Tl{u=@e2=(6HJL`s26Y_FxalMfy-N1r~>y46%I|AhQok5*#+o%8ZoUPs! z!%BQ#H{C}b{wZr6jTw2eLwKLjyI1(&C;r~GYxqaI%PADVbyG*Wix)C+&^-Lo$pUA- zy6?}wX@=tIEgpJ?2*PsZ)<{7sddRa@#a}ym2n%8aI6c~y{T>&e!-3Fg~x|Sd>duXgE=z^!=(!X z@DJ5R-WnXwlS;~lPoWHCXY-fHk9iiWFN>$+rwPyi?v&QeW};(iLyXFLf{;a?MT_5` z4pMI4wb!t;0w)<4Li&1zpxsDgL^Hnc3C5GPafWFC)%GQ-;`e+0z^pGL{{DRln^L}& z3-T{^Y*Y~vfZY30m+c_ND>m9tAJEDL)fMe0b;WSpwVb$h&>8EJJ=+nwbnzA{S$z8U z9e$qUoRRI%as9_rP~YZ?@--l$yvg}ImJ60gEFVdxWrWlB?<^gDIH*3FrD?8M#|yPa z?!4K<`%>wT%ayty3O!fu5_~Tr0I$rq><^{JxP407US_guXkjCeW>y*Nwa(w=OT}eIoWE}eTxHwB{EIzbo7O_= zv*^&R>D&ESFJhj9Og@#Cjg;w0RDEzF5{#<`@E73tr{DgXTqy+`DTMB`?#NswSXvZh z;j9sWXF(17h&>Yw3Z?cm*~vkIj`M6R&#>=+!THGZQOs~@s9%Z9-UqSHrLcs5Vue~~ z#3U4|_rr)$FPC72C`9b(8`+O}yYm%EQpZH7U~5cuUE8QTI>R7)lpNy+Y{S)ag>k*w z^ItCCo9J9n%dEKgUxBJY6r@`Bdv7&o=b!PW7s9q<3gywu7U z!obDhU}2SPUYK2S(0as=09D?S-QP_rMj=HTej2MZ@YK5_9H%zMPzk5~;ee%wC`6|v z)!96de1--nFFbGjA3sA0^_H*tfny#SlJi=N(u0OsKjwL9}O zz%v`q#-a;u0RjC3n%~sKbr-Rc!Y!uOQ@l z+`BTBLQ5*z@7wTI)f$D?M}Hol4p%$D=~w1-CbIU^ z0>@b-eo-F9{AP#VYni?=W7Ked)Z`R6dJT*elvyNT9J>s?_~S|u26$AR+3IYg1#)>A z@z39u3$D|7hkZCl58Iz>9eUhXjQTdP<>vs_9a`8P(!=;?&#&zjogO#QX3gj)N?sn= zSO4E90q0?_-Tu7kS4UDqny-SfkJ5fu+AB*`u&#%iDdDIK@G=sP7G4vAix=6%%JBTL z{kPV{t>p&38ZH<$u?WD03o>zksj$9Bn5|6If+uLu-_>b1;Dn|9gOg|S=wQk>{ciU` zcSQ2FaxyW;c*}X&{Qi0-l66m;zJjA2iYCd@j$mCBgQWVo*n32{vTbQwPr`gFv&~v7 zMsC<>Ls2ERj}gXGL@Xw4=Obd@F(1!B7N~NJLIn=(g7F@yDzyY()VTTH^s^{C%&}$* zd#Xo8s_CxZd|Ks%gr`n^cEEXS!LbuWg&bzm{2rlI!^IKwksCywcjJS^z9b@1isry!I#xXC)a_yz}|F=>_OyPp~lzV*fi)eloL6W}HVatr%1W z1J!4y$%iw!;foWdHT-nUB+0|t?wM;*s6oBqsLw%Os6!*Q{e55_gmrZ{pOTINV^hjC zyb(h1OrLkYOcV>rqL8ONQSLl)bl_s(!n%ly(`RWby*GfI`@egl@FH5i{-}}dun@f8 zbn(^hATudu1fB~pHb=4@Ed{~Xv95A{%~V?!1F5s%pKe@PHcGbsM&bHY2r|ejQ`umg z6iLkzaHzQi1&w-eIR0VXU3?LY&KAf#xaW!*MOO>Ij`PB~kU-&? zN2|a@<0`n6b^*oFU0G&4%!~0|0sS0t-$9>2PKemaizrvfF`Lbl56)@5crkcx13U=3 zBlgC_1sS*0rYyX`JVA-P0ELZhkl+|_u1v=niJz-yIjDho;`vS%kM#DzSVqt0KZl%9 zg|-0A4i)Cvb;+FlsPzxHcE7j#(c*+8_kvjCGx%WhMpf&Hs=r|N!qphbQD;<(g1o{j zcrpK~LVMO}8GLvldE}3PD?0O*M>U0;50W2aF!I@31DGWa8h2e#@W~a=zedEB#d6WR1)$YdfV&A<_dGD?b8RsDW>8zjK zKDb_em;d&4?Pc&br2O8)i6Hds+ibz7My%`ZqrRKa6(&MT$SQ53YOVH!Wg4K%bKrj(hW9{$Rv`9;tJC zAR^^UiVU6)9qk57Njy9-wbSYZ*=uG}+fRPB^6CuK+i^nWVHqtHzdrl#^s!kW(fqNP z&n_8cJ^gz7Ng@HJnW_fA-MvE?WNwNE;Ujp2A z8S!DFIKJ)fu1_lY4jvxgh?RBm0nQE^Zb zy=sJu_VD!^%R6;P`$Ey6T>eeGr@wFMm4NI z*Fa3t9M6EtEws3Qk;f zpLlZx)$&x`yNdTcsv4K&k+ZC%c@7C>6J`g%5zKK}U>E!R4i;=cuv zaON*t;6urq?)47=sJv+8#Y_n|bWn@T?rmZsnanE;-LSd^C<4x}vpnO2l6zg5U+1@h z=*N>k>w-P7|Ftpa^nC_+=jSgPo26x7xKcN^6^HrG)_*U}Vt>phA)#Q0hl!*eMrmd= zmVuD=sqzY}OH4jfcZ6Sui6pw0eLHm)>sz|(+V@}NgC5e%Z8xI-f^g@UuGEomAn8PL zKR1LAD(z)We0#nL4k#@3J^So}czk|Nx#9lHq%+;TkQL@F_S9IE-M0WyZjL-AhxuUG zV)_>z{S7c{AqjFRBY-~QjJz^e;tyZehTqS$+%A|$8ipsNpGx!d|Y zka=i7mmQx8%tm|lPImG_3;B0%X!BM3dtlF3zI|Y}XF>)e%TSh4QHz z%09^EYQDSMb3ypti-JJ+nSt~_6rFc8m+u?L&Ft|()`w6Okz}-t`$i;$L?}Y`Dl02n zMnoCONZEU@P&|)sA}UEj*_%Z69>4qd*XJC^InMcbp8LM8_w~MB?*fmFgi|!Pw>ywB@p*!|IX8!&ZpF!==|;&tEMOa_5W_<=OG>C1$;pxqzm`cXcz*4x5czYpp0_4dti z@8eORU+LPH%}~@AcQnWqgfinx7P{s0s|MiQ%U^s2FH!!8Zu&?2k`-XfH}6AwGy-g> zT-6tRPK0_>uYLNS5pd~<3_pwTTiDHaTuE~qXx}#3q4wQ40~`pBzLWag8}pnwJ+FfD zR-WMY8s<9$+~=uB(`Fv>@t!(5FvCg<-u?G>G#UhXv7ZUK#tl_G`1Yygm~pLZQCBC<1!I$4 z+09J3C`Usnm8vS5fV(#6o%FsI2?9;xvVkq)Bi&rLoc_Rw$9#A8iAMTf*q7gAJNxV~ zSCDT0(=-kKY}dvA3H}&Z{l2W=B25e3rypu{KAr)#g4QusPN`r#g-E(&i{=PDzinPI z(&H=JmQ|*l>0s*O;oIH?8d$db)s7$izR>3rgwBx=jDl7y+}Iz@JLH6RLGLzjpXWYB zA^iZWwHir2NJ6=>I~=!Hub}+d-80{fCta{QyE$#Ir-+~S;_X#a0v+zU+mor*=7DK? zNW2#H;ecN%hr`de(&Bg!Lw08*g1(AA_Vm;s!hdgdm|PSH_=y`w%-dH2v2;Vd!N5RT zm}h4BzWetam^43Pvq>2Yey5L%>R52W!M#ReT?->Fn@Q7lUd|fpFix0kMRncsw<(Wt zl)s}R&#}!Xs*9EH-8Y#;`2n>8>G^Yt2SAH0HmS?(HAwvNbYg&-8!Ea)+qRH1;~OTV zzZ-JPUd3rv-#?N?p%;omWNeniVFjG6bAggz({7RoA1bLkULGgl=ijNCnc`01uIye2(FD~GqXCBw#ss{y z_sr!aZ*$Npy7>KU9yg@uJO9;-?>889TS@;Wd=V5j-xdCMp9|)8Qrq_SG2+2d9obVK zT``{U>-Xjb8PNX5^+#=N%b>G8{v(}VCWsI?kQMUcfHjn@hhD#F@%``s>eZUZK=0E< z$Z?Ys4ybW+U(TS1{vWgG#d2LRfATcwqlo6JkJF~eBv^18&b_K0-B951gCS(lnHjRK z6=!S=qx`;CE&4WRUxN?LpR@xJ->my(NRL(x6K*x@9^IG_1Mc+HAZ$RvC%+Hs!*rMGwwy7a;gx{=3~ESvub*-2a1ey#)D3bj zR)Bb)5ZPyU8Q@qV<*PB`3i3%S-0K-Rc05$%gT`qUh&JXyr6lSRWMSi5k zhmd;|`FV_|y45~fVE@DxyZ;s(fxImV1K;`wfkLIoNV4E{%uwwtAJFXpBUP1NDx-(x* z6Dz(O*s%WTxCSU>{Ev5{7Ueyqsmw1<(Bn=Qe>1o#rU15MmM*f#(O!Q#Y44>UOgPy2 zGC&pY3W`(AewFy4`Lva^$ZM2i(rx&7gX%;mrrVsqp@=g=-G7?vYs7UBM@^@Hl`R3d z&W1l`<=}=FnS$@H&@lPP$dZUXI&dRqRb9%*qPwyqaJU90M`L4ht;i-7r z?2c8a?Fpv>Ug+Vl@P$f&1oGM3uM$0T4}?+DZ1N2f;gt)wb3yV7z`r|)NF-Q+D-PV- zJy$tk(*AZvWE3sle>By(>5U685xM&Gcr?m6O>6Tp3fTrp>7ycE;}+o61oI^l#OFCZ znSYrKEf4ApIffr}|U#vwwkyaZ^!msWqT|P^M9deD6wM z#%JZ-3Angz9n~Lae=t&cX5F!j0H<5TC*s~70N1LCwzZ+c4eK10SBInlEE*1u;?_?{(j5yR?`YsIOFz(ZN+yZf&a5z%T!byMuC+QWL`w1K{6~*`j^C2P}2{KI=|8E6Y z_$VJIB-(=N;>CB?vz+kdE46#Z9Sk^|NA;06LvEPoi33Y^#8F}=ampV!KLqNpKQEQ$ zF2tH7oLEn}ARWN0Xrjk~1sA71by=s;1F(6gGf|*E-I{u2b3Ky<|Lf}&NVn?@!uI|M z$1M|KkIF(`eD*4Mo^K%OacB?7gooHkQO?;Jw#6eZiCf@?hC;XczX(88`O<21l^#BG zJU3S{unYu)RVhuL`(PAO@*h}qx#9bgzpTe)nQ`Cqe$FZU;aF7UxXAW3RL{(ooBi@+ z#@8;tek5jm3lnDh-u+)c0nYJ~OV}zO0?hG2N`-$2M(}@reNK%LveNCy3*1=)8&c{m z^j^`xpo)|hc+QY4?e6xY^Ir{~ZM3fhK?_Gw>2`2pH73Bx##67X& zBx7uwm(g5)Zm~2-j2TMpl#nZazlAxNhWxiPg7$5dStXPs&>Z~1@e2p%Y=MB&uP@)e z5MfbZQo>To3P^0}QJ0l>!o=>qwYzc==`G*yz8inL0nVzI48}OP0J&ukM5ZD_=^I$# zO^JEnU0h1L(`pBnt`+g6f9HT=wUefUFX(Weghi5}ngC$+^23KsG><;7pL^qT3O)W* z;Movmha*e?%T*aIH~1I2gTuE=rFZKAbe8C(&TWHJgfGlZga@=hG2wnJRp+ zC$M@P+vVH+u5Z3+;R1csQKaX*U$L6_qVxwunXhgRj|5;B@3dYv|H}-mJK5dp zz94NrL3yYp9VnBvXG$V}h*P4I$!rS)eziCAK=Fws zSh!Th{ZR)!w?eIsx@rXcsjH_+bG1JhE`MV9kPCeeBfmS#&oJV`zF(SrQ(Q2#Xr9(r zKo2i{b?vB9Uj`N7a&HLvo><-9H9Zw0dMNsi=^S3X2*Bf95!6RuwThGb4$5@U#C1sUttCRmd7eXQt!41LJNcD4n=Pi-sl5EnQ=+>V-EDk{IG202bI1oyb!^M^KIx^@rL(94iWC2pz*3ESsl7h@tG7h zt+_vdtC8fu|L_qe$*ki#bdwwU*ExN=gz|BSr&bmo)|q2}!b4eq($hllqhcyhY!(n- zo%%lBa39m^H8t=4p*A=0!Dvr+ z81=22m$|ELG+FQ;Ee@(dQg^ThOyt240yX?8d)g`T+aM6{3HtkCstTwI7xSJn2V9&e^R8u&Vc^8{9P5qMd{F%jc-Q#h-1%d2TeF`V4o99+b4v1;LODL(W#_$ z;Fh_h#o2F(eYC%KiiZx(DIPaCJfUX6`!@!aB7N>-V;{m2z6%f`JKOtJ_R@cVb^k=c z>HS#n{+Q69jylStF$~dM-6P;%^0U^Sn#W?VL&Bc&yC4pK7RBQ-lux>@D@i*&kqi!` zpAs2U7~w)XC7HVTI(V>h!A?!r4NT5Q1VNpTxYtqt;t&Bd?81YL6VLsb zpy3l29sb@8KzAvlSQ$PoLvGaXBw$sMg84m>+tWz znqAO-qf%J)gbkMVdhME7Ey|%Oc^*hpKLzad{GTLSBw|`Oe=J|IVTN@&LK(e=+aS-x zEyJGvIXFLVChhW(4!*H@<8{q-5X5{Ddd`V*FngF|T(+*E`s6N0x-vQslXG9z3}a~+ z%Nl0;?GWvm%uijnR~ZEf>AZ12@8*LD%Vz&(V-DE;B)f)9lNK+pn|pv?PXgE~hpidn z9<+1CE-3oVfNn8|y9sr1z{};j{VY2tG>AOy3hU_bw34fPq*3u0zvH?0?{^R%SaLZv z`!5rIVRMvtV&@_DZV#HbAzyl{T=HtfIa<6csx06LvkNA=tF7tizzDy|&1(1etbv0? zr2~<8E6l3*2K!PN5A2jY-_W|h2SgX+jjQelVu30n=il1%L&tK`f2w>09R9RFYJi7Vr@_E$o8NVRU zF`IFaf1S6{bSM;PHKo<&?ILbfqIBZ^4hzoiYwq`z+Y~6cuV^cw=WyoRt1{tTW}IcS zJKTcO5PW*O{>26Pg3{;yP?AkC(puTEW=bd1Ixk zJv@-1EAvO)4;Gxn_y#FWrZKj0_wI`r#8Y)Y?xMrew+rZkQb^lAIbyaNt6RFx-0)BD zq^6R^G|2k0uR8QH8CVUsuEm7WzAYN5`R!VTg6=y)kC$L&a!UMmyrnnaTA>bBvOja3Q5nzr? z0NvQ$>Y1C*F`XGthKDE*I`}|Pu>S!g&dT7cZ*5%&UI|qOU#~?xH`>vv$sAhz)Yu)`t(F#FEgHbHeUQY(r^Fu zev@3iM+IqobHtCLe*dB0`>vTcK49C;V7PXl024xwJl6et2-JH&boEtxU}VqF*4jH$ zqrF|rC)bk)fy$YIFYM*@Aj7C_+7jt&N1{d6ll^ulnP(mlkr;W>o=rsjw6t56 z152RDngMA!iirp*aIEZ~QB8Vyxd%JTvo;6{Q*>#Km)`^DV}jph z5U1C%$1PSQj2XXsYKCmxHyLZ=)(99lPY-Qp;IFoi6-_xB04RTKMqHjAlyP-Qc+Q0#)=B&koUFh)Y zW~T$;SQiko!MpB+^pg)Pbp_2MAR!ZApkpV9(P!ME?vT{mSq4Wt%i6 zTmS z>3%*WCBm!dNq@0A1^8!aFRN;M0p|0!)iu_LFt_XINt!hRKAv$_bWBYTqtImz^!MO` ziL}3R#Q!ql8_vpNvnNe}=Rw~~i8(4*w%Koxd1?qKduG1X%1yzz;~9*L(rIA1Ys9@X zZqp#Mk>u7GE%HP|`*@1;00rwMb{O!%DI+;}4Jq|5#lX+QQ}n zGR)Mw*LZ2*@D{2AO2vCgOYi*ulNp!gkNr2s)vh3W^vvLEU1q3jPpj5^ zd>f3JkL>M+hGC0^h3V~ej8NJ6<&y_$>tO%zUeznla4h@dYefoqlnWD{fJxLb;Mr6) zwsQdyn3XK;U3QfJ(eI^Jp|?B;j9i2Q zIVSSe80A5n8FCi7^NSWQn*99j=@B<<^Y;MbUNsZ!e$6FrcWo0aXoYJwPCUlSMvZBJkakm zO&w`03!WmDrCKszi%UFDlYa{3ihXgo6)e00 zTySC>yIweUd|}^wHZRCU5D&C;@1vnM3H+4$_Io3v3l@Ki)$I?ehr>x_V@+q)fy#xgrgmW`Fij1Y57y2xlGnaiwg&pD>SP<2d!>yRTD@*k>{h!AqLUo zDxG696r_PzJ8M=vj}ATTRejx}7rF#?$s(8)j)sDBYdaI?9Zg0A1ipMj{kxww{qsy27JQKG`!l9i7m#%K zJa?uP6yG1pa(FZSt$vAFDPVzkdD}4a#?;C-YO70@s74n122C#pJ(|JWM4; zKG@9GV_roEfa2<|M&_FZuFs@~sFbe=?}9GD27$MO2 z0Sk0dc7GEqbO@$4?XGctEdc(LqOAmXdbsdnWi!lf2|#L<^ph7~0{7Gh z09&n?r}S+e=(VCB^X>!-9=#}Rp^+31lVa?IImf*H~Q`X7pWSH1!?{+nl7 zAj+e+)5@GOr^RdYG8xVM!m!nw*0)(Fs9}{keY4db(j{#8X?)J7U_U=lWFUwX)H+3} z^MQv2ZAA#ko4!E0Zol16XK5Z-k(EaNQ4;yqng%BANo=t(VzC9CFAdBWXgr%p90uJQ zx;pwD`B;V=4eiY$YPj3+!#wKtC^+mF5uE#%3GPpjj7gI5!M622*~)r)+}Vq4H=a8g zB$$sUMxlA@$LYj*+EHfQl0)?T!}t`;-h6^ATb}^WIY#~l#2sL&5D+}OSOWH}qsa8p ze8fAOPmaud5C}FdsH5uvWM~AReuwfQYUcW@s;~V4X76g-PF}Ldj@blfvS8>XyzyjL@w2j&`=c)x4j0jHRGO~@0R0eAU6XhNJK^UG-kVQS2{Tr;Z$dxa~O zAg*vHp@s=@`nK|(kxhZmyr+WICn~WVhhu?0j;Jp3`t~|=fgT_KaK8D(S^?-SO&L6o z@4k(kjn=oz|1Gu~i-xQ>X@TKh) zDq7W5@N7bwa5;cv9v)@roU9yGT8u5vTYq=h$oO;v2elTI;wvp zzI^y2orrbJdbs?zzzwrI8#`akje~1ysRqUm9YOiEFGpRhdEhM(9YaPd7Fz1{Uf zE3E0?l9Vg*g?7}ggdHH%k5=L z;B8K))YG(J%u@bp1zR`~;*#<}lja}Dj`gLA-f{#*=ZAGRm8jw1)fKfPRA^q-K4Y*I zQ3{sN{&~OKdISnw;wb%#=3kPs+oEFeFEJa--!@K&XLl?ueqPz;5YULK2s(4xfZTG8 zgr}_xuw^#nA=QIbp!w)e$=+5d@RD`%IhW52b!zPrQxCU*2A50u2aR;hC!){R>oyf^ zPm5%Ji29lz6b-HG#rl{r`^R^;SP`d~UVCM|Y!v9p%PgE(%f$Ysl-y<7p@RF0v7PM9 zLqJSV=-M@seC%n_C%TO<1Sm1j>ik!G3ly~aTp}jd0>?Wl!f(`&ekJ1MAA1$)OK+-R%eQ|EcBcvFRFU*V|P0T(|vib<{9*>t|K=WuRrcaT9uh9Fx)Q9;^8DpaF zuYAsJq=mO-^p6HE{{aEdfBwr`v_rbh-7D0H?^%)m`;#ff5XkJJ{_%0;DTv7O)9^z% zG;(i$i0@n)1@p&+xupq}7;~~PLnL~?8pVSAnoxEV{!y8%;z}Uc;)@-K)un2}BKA;2yF$;Hed2e6uyP7dx7pwXARPnw5*1FN_` zNq?&vj3$4U)AlhByqETU{6)$hsHb~db!IsVB=SP}g|}3&e5k`uyLk{i>3Aw7ajgo} z(uA#(EuwRvIhS?&F99zOP(8=xXbE`3V^3a3x?kpRCoj24R_LxIUHzNV6d0}3*Y@=A zLCqh6yOi=wcvRxaN}j6$*fm1m{^ltfNKg_co{pXbzyB=gfGTgWs`j;&p_dBYXu6_y z4)vR~%@rRpRL6#W#_p1jBApN`<1`;;!B4N8*ifdl1veTtd&5z`NqM9*p>SaYMDDKL zucUc}tqNWF39m6gD$86Qd)F19NhWts<$D;|dT`1vtC+NY>$Hnsbs{#jE7+K zD}X}ii6gd1QEj57_+MW}N zFV`PC=%&ZFdWwbpn{2`G>)_^l5j=2yuY_MFf(7qvo35}b)dpd)ZMWX@Q^VifTmj$E zJvDnj=+uwmV4!2?m4pW!gW*#E{uQOde@4^lcn;pjHVp+oOCo;}^PP^Aad`s1N5W#S zT4DnVQp31UBMvp&ktaB_Q$r7wrn;TJdD5LX`arDMju{wb;zs=UIuaD|tGh$EoE8LAZO zG6Xtf$5jQsl!NWEb3!{Ce6V<5kBfPZ0e{UjrpRD)2RkLs=0u11#qXZ|bg2ql0X|E3 zOTj?~MvI*Ztw6c7lJ6#yJu7K&>vzXr$w-M{!+g(KMlRF9(#q%ji+1C{Y9x2zzhmjx zLRuv~HRA7cW}YCv-mikaWP^l{JH}a>E_PFPtoN6W~I@HjMdd1B&#Xkw0(X zgQ7yOn=nI0ytIt#&mXTRV6OLlo2e%O8Wgwpe?B_~p8UDlt`zeD{2a9W@d^3m=GV-`lH`9E!O$Fb_u#kT`HUxAo3(V3UWMYM7(PT~?tS~KP#*RvC6=2OYY7gI5 zVvg|@8*2<`ZuQ$uHL8maH{D8Np|Fkz&n&a%jlL7%0-xF71-%VG+STZJC+0c0WZiI8 z;|VvUKYc{&WX;>Jj105NhbFr{Z9Sbf@rj-?O*+&^}Ql=_2U}J0!`; zwtHGjgKwYBkUQz`1xEi#hv=fZ(f(m)W`JowV8|HjP~Wh__-*Rgo?hgGv^fq7gwwS6 zMgeC5ZJ`O)^e$4BeT)iOwe{y#s=0ICzrw)3H70sVU}JDzq0QGfX8g1Y$82j{sI}m_;yqMwe zZd%(8c&5$q>+GixOp)uGh-4`p+$(-}*Eweq=*Z}cs34uhd&qe0ohCXr#_xQf)*#@5 z7a7dseC#mB&D%T0Xg}(K;obBkJ9NLWwwW1(#Q|c}EN$OiMo9H!Z{YZaA;2misC4hB4tTN90EgGdbSctkFh&NHR?Q4EYNJ~?sC`deW3fFmdpv8QsBfqmADkZ3PU?J zwm$y9FDo~ptN!mlAVDF;IgPl$Y4nYkT$x5dk>&Kl#Ha~a#6+6Q*s}? zdM+^N%%6o-mNzZAe4KYtg-gW#OBYbsG5?p#~1TLjz^KLwXm%@H5Kljg1e2jmmj*b9?My1xrlB(84mf5^plGb$hW-eQHO zStFrpebc}|KJiq&N;SrQPg>v>`nyGpal_%8%y>fkF?F{q7GRUiC2^;f7T$YVGdH|2 z4&v?pE7p@J!~h@1*55@cXvd={GEhDYrU(<0x96k5lxphGO-U+95|q|+Cbh)bKb0QuFE>dzIg?#y!wGTMK*&PUGffU^e~ca zqIyzbL<{Lf-5-TFI;T+n>(a;tQs!;I|EOEHGcXGq>k|z2aYg%Mi@DpGBEx_mqdMaB zrUtP2_4sq}p`6#d-f$OeksD&wc$s;n7zaG*MA@2pl@|9JT>URkDF`zks*G_)ITTlSMd&No z#=*_Ax2V2iVVI+b@v_KADk$^pYU5h!03f}?!;;wj9|(9MC!nLj09R*EPJS{R1}|RD z_kWYYz@tUSPkj#5Q1OKNHyX83&?I*(K7=t1Ouo|T-JM{B9J)K|T308)Gt~zr&JC5A z)A^4Jg&xeXI{8e%l*A-pSY4QtZm+@^rxl#FEV*E@IK{rmCq~>}NSN(Wo*r;~`6H?7 z7#H&U{gl1J$%s#jiGE|c5r+A(onq??Bfw9!-IR(Z+knRJ0C3jlV|r$y^_OwPm8v0; zR^~^22cJ#9pm!oxPT?9ptV#{VTvushlSe^e!{I9{kytRzNzRX>IbA-RP)-Bw1TYDB zQ}!L@UX>*}dA$>+gBSF9UJAZIbDUq%lKb{0Sk1MUx^7fxZ;po9a-fbLZ+xM4G9w}f zblh5yH*}+d3=D2I|Bj;jk*RkiLC6goEK03;PQwLTb%K@!nHh2R%VmM9LXJT54G;>t zzzT%|v>Y~;*Fce)xMI044k*X=#y-lSdeSD!(+%4Ks+tGn7W-b<%zDv|+BL+hLL=6i zdqY69^StPJlNzuX9P%R267jym|Nn{nrM&%I&n~wp9Bpr;c35MDmpbm%U80`^+V?j; zF$;bGoIy7H%!nVGZqSsEkYu1;<1q`ztSeyf9eosp&Q)p}gXL#J1biz~QhO^k6HpJU z{jC>ggLFSW{1wWY2RggcqA>42aBzJ0zV#9VjM8ds>MNZZ9Dug3@}sCy9!T{wTuT7yZ&}3CpEcWKKwGP_)*D+Y zX!~!f%9efzBv#I4?VnD-ly+ZS|B%H3A9+hiTPtmWDx@Yjn7;#&-O9qMh77QtzQguw z&Jv)wct~;VSw6`BocEV!o)UIlKN{esGYHH+F38VEl>*0w5ZtsKagT)rUuE54#?|{> zYV#D{fDX|du|~uv;^-myXz*$T*q0^bWSZn-DGwyC4w=!ypH!E{zxdAqCDuVN_iS5` zc)>Aq8uk0(ip>A0*@l6JgqH)kcL`7cT_>t2c;V%`heP-V3tkcaDJ}1M0QSYZ-PzKU z2cBsgExPW?f(O@lJQg)|$6n{&_;hmO2qbczcMd^55IV|lRm@`9Se3(mSuLvP13ZV! zwN=-^HR_8mJn2F})y7U-jx9HA2>t`wH~N6>h}cuD(;>kB%?w?oJU3KOiR0AdLC?dF z7ww1Nvq33-_=t)?2d{j3UN2;ebP3|5!~?Zb?2x8pCo+x*?R?Bl-w7>&f|7^h#*q$K z%(U0IO%yj&J6#d*Q+5hG+jRft%Mpgv?$7_3YvO>Mg%))u{pg^ASr)YUdk3osHDojk zrGie}QWEyuLx9&;t=sZ~54Py}Yl*}V*F*$hf6ELNG+$~=n=?&Pz{C}+=s?k5gLz6w~@ z85=9<5MYgw$2ts)BM!NJ(=XDvYe*M03%ZurX zKy*#nRSlhQ-C+)+5$Jq-+!og$An^n+Y3xTeNFeSX*GD|Nmw?|_X8!C8B#RSZHh0pY!s;NSo~^qBeBrTJkTfa-zcOMT^--@5RbgAO!L%-Va= zO@{nATrCk1qDFwZOK-V(o&|!ElPVW-$AMJindZ5g55Vs8_qPg#43JcqvPACGB*+oH zQv6Y?0vj;S6FR2O3Ew0#$GnWE#|K>>e+$5F175c0Zu+itFth8buW`W)2#f=N>FM$? z-PS_JSfmeJNm8Sb`@@RAzQe0ir)+>tV@uM{ucCS>{*hHwC_R2Q)u6_q3H41WK@^w| z%DK3{{5k>T0K&q;L>zO{9zt_Gh5E^F2FA&b83$DEZ1N>v|^N0_XHB|ck zC2<`1nOi?{R2D0E>wg8%YY&fL5}ftAV!~W6nMhIp&P^fEKPedBkmD|IDemccQJa zYv-fR4YF`UhbkrP*L5ab>K?_m-uxTzVP=4n@hKnd`?sa>A1@=`#p=>}CN&7#eye9H zFTe?N6W>u?yg-lldvO2oX!OBoiRopb=zJ5)qH`igeWG-heZAz3Fwk_CK9UqkH0R>bEa@JZL^zG!k5Cax`T*jvX5!%jb0?@FM@ zN$|@N>7SFZ+v}dDpO8MucbeKc^aKecmppD1k&%iW=OTd0bT907cH%^@sHY$dXlszDF6~>hFhfUhvnY)ISRO z>+5$Emj=K;oW7e|sTo99vXn=jpn-P`u2&5m83k&N#o@a{+1R*TQEor-y-SP}vTk1; z0^jq7+TJ`Uz@!Ckyn@FW;fZm2-1x~Tm@eS_@Ie#@S2_vmkI>%7SzgQbjO+8@teRK5 zI=dQ>CM~Ee&zVYZ9uH5qkoYQAWgRRW~2sPw2 zJQ6|Q^ZD2bpRf_|u~=u^(=q|`nfUurPKXcciD#tke4@d9JCEehmY9LZEa${Gqgdg< zt&`x~%pxcUr8}h&RoGYFjgFW`M%Z|2*C{=61t?YLUX3o#!B&2IitM5sdj3K8KSxal z!7$J7q5I7*fyBExzx=0k(D%hFB9G7_IA6M&EfM+>DFySp$Tkl9J%rJdY zk}hs)4p>!P@`gNR5+wZSG^CPw4@BuH!+vd}eCTO?ouQsh;PvWg!jr;KK&cjy-1d$L zrMh$vKkF}p*83%Od~f!fB1kOqY?T?H7NgsLpF>ta6O7Df`00RA*e)oVdNV<8oqO(d z$PZHlL{u&u{SOGNt~q%l9jtHCO4dkl2$bZL42rX61Hb8pk8?6iuwRuPBe<>t!;!#x z_tFwjxYLyW^#&u_Z*uz~O1%O;eY|{rsHX_n_u4<2|4Ix0Qpe54ejEf#MdFPW>Gdd& zHPeF!n!?T>SLSjZ=8DS-fbm=W=UJ>lFuIQHrJn_0(lK%FGDeh2k^VoOxW z#y<|?q*h+^uG@lZ0m)r@DF5jpp<}JNe+_iyw5DO?8pAm2C|@ue@%rcH9v;X1VR(@6pe0pQqP5AedlBOgW`GMO^vK@A+#5Kse-6|HOv5f zdO)u_IE{EK{bA4B_y$3+d=ZGsYX%~w^=-N1+|cO3qZF!|F)T*>G4^oN24pM6TWH@eq(&CT`}Oic-rx_04?Mu)EIR983P;a`WMbWDF@_t6Z$yrP{Z=Zo2dkaQ9$=k zxcR}Qmsn#|)mdR923Yx0>Rv0-Nx+IoapGqTw8{EkmRLpg@X%<|(XL@IyFs<7GZ}?Z zr;bxC5n18=bLuHBuh)T9Jo72)%nEESuk#_zAT6}z$PAHYnE-F(#{d1pD?!@Sk$bIZ zzq_}E#Q&Vp1~|X{OWo0{9OTbZejR$l1Eo)xm=+@c>Rd|*O`CHP2q>#;v`2jAM8?m? z|Mr-19s3}r!c7lswsf~?svGHqBeMI+-{gNZifR;CBo`;bRsz<#Mx_$01U=P)w5GhAQ$Y3Ty&-YG3{2iOUvCQSi%oISANfjq2pnbE-brqz0lxUsS4aD);V|#F z6HZ8+9xK4c#F(u8z|efI_tC+B?IE^tAHX34!~Cq{g1 z>XKH4m^C=p=5XWIZN!%p7O0yW8v_BV6+&O-{{zRqZd3WZKMED`z@o7G$p57$L$dDU zi%r@TJ^p0R26IXZJ$u5(QJyzP(!2Nnfv5fH16HOy&_hFWfYp!%-&4MS;p9y(ET5Pj ze?E~0x{oRUazcJEV_MM@Pr!TdI>3O-f0YIXxi^H|O&bOUM=ke5M+>p&Gj7b)GpIh9 z0J@LESfOGbKaurN16&toRk@1tWqpXp1dQ?qfp*Sv%+0n^aK+q#?FrHi){Hh~tQ!Zx z&gaWiD@$d7($ZNoT96)+$eblDMVtq-W|pJ8eJG#NNFi=3AJt>O-_QOb(BhMe?OV)u zUSr)&k^&~y%uvmoT(-k=8-UIf$s>2ez!$sm_aVE?Q1MXSo`YcvoRUkuoFkQoa(SNb z=QbmL;EyvREe*7|Ym^tomDnt-M?}ht8~OjOo*c9t|MCmC=#m&%YMEfozByhJ8r0C} zv2c?C-xx^IY#^Pd@W3RVH9e&@qk}98uTA4c2SImKC`%vG-!2#P|2L2PJdelCOW#&a z0^O1Ppvzb(w$+?67JZfrlFpx;uD(N$UtM9_SKCO(ZmRHHR~Vy)vJL7lzWf>owRLBj z_w(by5u^J7_t|KmQiVvZy3H8yEGeO=)yV;aOw}QtB$G9*p{8Y+H$O%;kT(i8!_;XtyBLaSB3?|{OZa7ntHniQjJ%fP5+ zpxWhTIQIQX!w=dbZpivX=x9a#ZxCeiKJxXTDaJI}5a)pOkb56hw5y9Iz~@uhiPWzO zvE%BRRjdc7kDix(WgX6f)3@w27+*>QK2FWsI%vN*SO2uJ-p6Th+~WCtLyHE$>r}ok zX2A-DZ&Jwr4qOI-TDm%8j8#~W%t?+ZBx|_~C^QoedzNzyHV|~o*=6bR zuC&KVF{bI@SKO6#c62Tc?yiRFHZKC{QJsx!v=4P8(Py4Bo(~>dv`qFLp~Jt0EgPL! zGsGC`xjLDJso>AnWca8ltp#}MGqY8M{)oC`?f+85q@MS0d2 zqV~RiVaCik}`|@u3A&!bCg@d;*0oPbOb@)%h0xVP|)@o$Yz)M;x*P6`6 z0r^Z(`6rYw5cl_@n%+eg*!{)Y)$aEu80w+>oc6608~^%jKNQAUj;_$Xr0shcW|hx9XUGag1*eZc3*Q8u^Re$va93bNolbmin;u>eRQ_J+ zItHv)%x_VKzDMtqbXBxC56o_5Bzf|E9Xz&7Y~nZ}j0LTjR`ot)gK5%~A96jWfSk_n zjdhR#1q*o!- zvp|Nrhy^Avu-*(;J^=4b*!3l@RDf4sR5u&fIN+TRiNWM$eSq>#?YifFHukYL{m(A~ z4=kkCr#?-M^meCwex0+ zp1pX8MTKryMrNY?lmwIWj-|iA_SaJn%RKC`b-TtJX*dzO-^{%}{Rq{ioAn`K#uF&9dfw{NO2i-#c zUIx-3*&ox4xM;Mxd^CdqEv!{Uy!{U_WucU>KcgRF3F_Zu4(+-BN7Q@A zWBtW_z?2=?>oOurLqsT{bIMK%Wkh8YGD9JoL}V*_uPCxg)VatWg>cz3g-AxWdd~ek z&;7fvKfkZ<>s;r1#%I1i?++Y0ZS?uM$pE;;&h+7d^+Qx6mm}O1M}Wr1c5c)xkdReg zqN3CLrzm`Mzk}!v8mP-rc4kaz46yAK&{y8h0v!@Td!$3Wu$#AlMaZ6s$fHdmw$PV> zs(;TZ8J=W9=Ktgl2+oyM0CiFExZtv4W?;Y!yhPOJlkx4 z=RqYF;*slWccOc9LA8b&l_aiHo-TOY z2=$#07}CW!y5Nm=XC_GbnLIJEVG9Jn?J}Cky9gM|%Pu}(fMbPYHC~e|z(^p(!5n!5 zx<12nwgqY^)oZFCH!%ht%>~>#*Yp^L-w*Uk#d$`xZ%*vnizM(P{T=68y*K#jcw9x? zm;g(Sbgx|3nFS|?b3ZmwMxnatLrY~Un4h7|`}KD49FP(_e|95G70e0?Eae{Lh4juB z^}S-&z-@h>;?8FP`Tb z;JNsm|F_v8*df{W^~1yb+TZz3+X;B4NhpuU?d5Vo339nanYcaJF07;P3JSIUtqJPa6zrZ82)%e@Zd z!HlO2_A7gMAo?yv1250FU(Wq90fIS98!!7=q4x|A%+KA#eOHyPFLQrnf>Kg7kHdAO z(Oa8ozM^z$D4cL>k;sSb?UPOLyk#UvTiRZ%zY29637`(@zf`Bz-g~jadvW3 zppkSX@Obcoj~c*zJfm4Bcj(qW=34It=h)D|@1GKh7oJRlK&xo& zo}+#sNBMn7hCCe{*A2ZmV>=FN{Fql&m&<``^99@FE4Xh|3FT+kE3Cu^e}SB@x(2$H z;CVn>h!;*|+3X&;%s@P#9QOujm4m^txdIj+J?lkZPv(^WF=~2}C(Es-)Sq^ehGojs{<%Mg!1b-EUJ+xYc*-YMB zAp0l-Gafvjv)^8}o#iAa)?C?p&${FRe8nP)QtA0&ob0D-DFGD3_W?}ExWNil-@eK4 zu!RFUP2W3xJA#(Tp_RQ~?xGXwkpbiF+n7&}Y(GQe?tY@!qG|@|#sAHp{px(}!|o(d z)Zp0ArTX;0`TH8$>Rk)=MvkvMskt@NL4ie@!ErXckESJ0Ty9Yk1^tb`_o!sXUe}!O{ z1RZ7Vf)8@=lodC;n)ToRGI1A0K7Abxu4ZlbpSOv@^`t+ijwJHI_FwHMpyEE_9)q2{ z2(8n9?+ZS;MkX)u2s|>pAHI;5jxb#J4C%p+!Rd(Hy$n>RTaaUVt&3QC9MZgS#$ z)IbQ|tOb}Al_D3{!F_frE(gixQ4o8~`nzOT!qMFd!-7l+KFIy%PSg~Mj3{utr|Qd} z`-uK+Sk30P5d1nY@X1R&8(naEE8v#s4#dBN3UuK*yIP(##*To0DAQtx+_d378s?8O zXZPoZ$R)9*=MM?Bf1$O#@0<;)ZU3s~Z3saYamG(aJHkNfA(P_Xu`G0m#}oH;V}>4u z))w|nyC}zAO+q=!37MuA+e0Tl_>IL__>u%UG3x9SS@IGIBr$s?lON~%R+y=;NX~5_ zSJy+a8!8q^V7^}F`Vav=%YVfCW{?ST*eM!<%clSB@7&y7Hjc|lz*+v5_*eSpC`lr~ z(&dj3)Yff(?tKVJ3KO%d&p;{B=Mb zXgqAbCIk!0luB3`ob+ggO<`|juQru_fMB0!h?!O~^LsRCk zJO%ve(Vh^&Vv1xI6)%3m^SA%jw@*vd5BX9ZG>Wn6!Ek#*;M zlsknL*qwHyQpV#8HoF?~kfnp*SAdJK^MCg!|J8+0EIS$K-mQ0ZNt#ZGBR=TjBz~Wd z=e&%gL^g{4bY@*yGY}cHle}Gi2|+ibPfHl zfkTe~hefqmGVbr@u$DGQ%}YTHq2Y;qt}FK6I+wi~KEB}?2%^R3ziV=*{x^<>sV0Hr zqd#ghm>JkzP6GF>M$P8%Ik*1Ic$VEa8r}Nk(Xg?W`QJE2cY^#^#8N=Z=5dGcXK{dx zxhweDMH;AlL%N0iz$ng(+|1*C^yG}8t5}YmyQqUBi>}|n`ueqEGI`-P1h3UEd|KCAIMyc^YMzu8-ta(&8 zT?`{Yk8pHd%8Z4hw-eWRDyL!u2 zsw+b9m@VfIGU(+F<2`zf0Hn%((bcCb+;x+Ry0_hIm|{jV*qjx1YWxH8mb+7>Hf13{6L8 z)wQD;7;qnRhlGB`i?q;P?nW+Uun{ugdlD3g@B5jh`m3i!6OqFUjrB{q8Hn6ad~Ik) z2wt+kz-iGEhc2A3zhftw0q&~hnHiRIz*pKAI5eebi3_t|au2$MBQ6F8h7_!4X*^p! zqq4Gqm^70@Q1xBZH)G6MhR?YY{MmZ`WjxC7r8BGU%>d$^74v5JKK{#o#POmt9d$(t z*Eml+2g_7#5!LwpbCJAbwd6VIw#VX$v)rnvw(RF5z~AMqJ`r-yGYi=`>{C0&6@-Qq z1XlNZ@qHn4C5Nx4bh)P?hCw4!&rsHtK0$tV_J*Ha2 z2OYi|$(tln5VgD{0~}BIp>PWn8a2WJr5L@z(->OfYY{R*1BY;6vOjZK7yoZeZ~Xd> zMiQF0wk+c6NJbabn_hY0`EL+9u0`MULkDw%+y|YqLH;&*sTzLY_PIaf!H}om*~eUo z&m)n<8b+z&;1RSCcTM~=O?e)N{sd7K|jvzWA|Q1ubKU&^wcMjh?RV55!TC6b>8*3YL~UivKr z8Hn?r-&*GaS?$8_wi9;%%S;Zd64qZ!jmb&gwE^fk^Ar1%OWEj5uA{L1Htw_Yz#&Y3 zg%u`ocutY@Z-UitvU+4#KJ?B$rWV!820fRGGMIcq|GU4&Y!Al1Q^ugo@8n|{3je2% zRNCL)n0b_nyt#q2;AqT$_vo0)9cqt+Ocb-u?Qm1*F1RkzKO}mN1KwhrMoR_MMD}B0 z6I~%m=&r|ua{_?^a7$$=>~VcE2Z zU(2azYG=!NXAReHO7dI}$K$xx*Lth{$^w3y&x5l+-$w$r&gVVwx<%i(q8v^ciB_go z%|6U#f%}Z7?oeX6df$y-G5aePYzUTxhXb}>)Mzc z?$%Q~f?ugg()AO3@HsmreY^R7;?^yZVYM+y^mwBnqz|8yD}G)7GHcV(m+vc;;SW=g zwr%G4A!=`cRe_jT8w7;R-D1JNhn%;a#N2!=_ue7w%~4#QyBQmAwD{l%?EwSD#^Mqla)tyi#>Hw^OQ zeOaI?t3PX#4RpJccReVc+}OmrT!OJY0Z{~zc7vunu6R2aX=bUV9% z4f_&{8T`Lp)m(86in&PqGn6MNTB5d-(YHG>FJH@B{tUl$R(RAuu%h9$DKhw8;?<4k z54)c&R~*X*m2Xbxi>2BEgKLkM^1lng!pDC*%D(1;w3#IZ{;f#FG9R^V*Y*K;B@G=* z9nVB<^u{$xik0Bn2}fr&T<>$lx5_Ful!{1|<&hWoHwRpKyZ?;wC@-{jd#$6PMMgZJ zxv#@>pFgtbHtq2j4hE+?#=bERB_a3U^pDLceg8WTtVUNE;~u0TdUL0e%%@iWJ!hjO z$zJD;2FVeD9};%bz+Ev0dE2A>@a~fz?z10AAb@oAs?hfea7mW3JP)o zrNa}B0r&_7aUzAfDRy}GL4OQ$12vIOzy6{-9$!<=iFgFdf!F-EXetd7L8;;IqUTC! zpk!2;SLg5{C}pIqSo4~e*v8KO;Nm+YWK#BJjBZW{j#6da7u}5p`VB~~c{vAI`}%F1 zdy4t)n@!SU%J- zEH*IFWPz~QitrK1Af#(oIZ8o>{cZ`4!qa4bk!EqUftcHA1U@Ca{f^JWPf6i#JVgj)Lgs5-+;16O-f?b zeIQWZO1>HYujG87~_Mb1s;dp z?ng4Z{5{I^D#jStoo zbj0+ykU_IW?dG62*bbyEzPy0X4@E@pjj~cda6tOe@y{QRY%s|-3Bh^%yK{|pJ{f&cYW)Ec6T)qW=f1ZLi3VmN( ztEocwjBTT{*!dt^^EvIm`jkW`Rr-pr-(%52i@cHpp$IgKvPtd{UZFDPqM2!@1Q25K zvOIl82o4;cNpVjPLhK|$W6WqCdh(#A^wg{n)H$r=`@K09!CNmUAHU5(qYHfs*JJr% zDfvaJ3DE&C?S1ge@f$8cnc2TzY8vYc?e8-B#6X}y^CZf|G#^n6eY!mKh##KlljIum zr-C{mJq61HCdhQ=bpG#10>&kJQgtv6AV-lQZoz72P$T|QF+Pa^j{#<9wcjKVa1l7aA@H%Po*&w)`YXxbinT+|YKM>f#CC#LTiqO1U10P4JMNrL zJ@hj;^KlUV-+ZnE$$sBSpcGDQrCm$_YlPQcLE~JIRY8(lzJ`RoE73&R&SG$}{<(@9 z?(3T5xg*swMM7J2uP(JaM}cyUIZ-c+J9YPONNbrTfvkK!5$^VA#1h1|{R986c}N{M z4W8%sW8SKrO@82ctE$_1%=6Y+Aoi7Rh=eYAQ&{FEC88LK3e|<@7{^7U8i8mBP)A9t z%g<_CFvNUdGaP?!P_n`$Z#@5Njakn}dCkDvj#AWy-**q3>e$Bnr6eKHGHPOj?4TZH z3x00>G}Ht?M^AD$cx23MkmK`^p>Lkt(Eh5#)shwxx_P{=tKv@rYU<-Nz4(Fv`v@ud z!e9U$u8ud@PJ!!q9R823<3w3o@HQR_TH^i!5{GHOI+v4>Vct~U zfm^uV?XuGCM*M!m#2r2SK9G24_j~F*p1;V*)nq(>Etwla|Fe&p&fUglkvGBS;mpE* z%wz0)+t+aGBMH@4-F;!RFB`QPM-8Ju0^}IjzP7C}0OaR({cHvw0_pLLgSmJ;r?PYH zkKl2RD%Ck|2|0qz!tXt=jcJi>65!N6 zX67v5hvKw4eTVV)TH8cR%WMpw8w`#G*7bV)K`b``m;TX?PQa}dS_eI^H&f7esQX+3o;!*>P@Bpj+H(Hfl21Op#@~8Rs3<;#(RzIxrE(!RUHTMpf5#W9gm9@H~ zLx8`-!`{H)31FCV$gpwYhFK=dOzRJZQRQU@FXh}^F!nEi{+b0kQqDVACFM zi(}j=1--$AokIf{-_~N#{h}N=28c=UQ4kF!bM0>HVN=gy$K+NeF15sSZs?%=w(_M8EZ3;hOoT9jkc7spa?SDpq*$c0) zCQb~XS*>}C>>xKVQ%5%}vBVBjJ&HCy8dDSZC8~?`vLv7bw7hAp4@cWrRruLQp zaY4CHw#cs=VSeNCW}U4M8|d!pn?!>rR*3O)i?MwI0d};axf0s}Fte$Y*gWe14&Ohg zY@ddoH!sU6PUA~5ygtvZJtX_^`ZS** zqu71#1Y~N;F6`sN^{SliMG^fZq|zt8>duk?d}9KJ8?(5ftUn=Qs*{BI+LQ#`|HY!_ zGLxE6{JnR+CSANaOhSE~Bi9s!GeDrd+fEn8)5^4*ac#rrDrU#w@pEAurz+;R3pL|{ z7uy6mgqQ~qAvK50Q8){|V3|<7oQdn*0*8yvPLM!_qHe-kZYm1ne*KT(9sxSLMobt` z4Jr0C3qXTW#Kl8`69gIj~w!LOm2Vy6GM%=osZr=N2Cg^r+C62^<|k>vohE z>W9k^Bl~Pi8|KM>n0MzY1=dH?aW0pBD`o+$GXZg{$pq*}VIakL2cO%p9)f+LKH8w7 zk(Ep#z{Lvz_kK2$K*P6>3hKA>K*UC7MLXuhG_qBS+o2l(WU0x|>&N|ouYCNM09PzG zL=`)_zK{^}l}66Kr9vjWvuw_O55CPu{FufYKtrCMC7g%cxA$;G7 zUiDUD6X4o~-$TMQnD_o7`<-P&toJR}q9n2Y)w^-|P@i!UNT+?q5sBCH^c}akXe{St zWkgl9PFn-Nm%bIHxDOYF&KCFQ=pX2K*t7f>z#3UJ2Rf+RPyVc0LHj!0XXe8#ktEq>#ywNa_o6jDE6Trs*56icC4aX;GJ!** zp_rHZ7-Z3HJh6aMtC$q6ORUgsxtF)>aoyjG!ecWsA6L=H69?zQf4DDgU!j^x!Z#Fge&o;^*1th=e2z>-_Z)n#@>`dN%48RVG9*h}4Gb9)#B zDv;fcJ(dLWGjEyuWBIeAFRoFJzc+p2_y>lspc)fnC(is{{QUvzmxDVWviMWcPzc3)Sq~oAa&DG`d}R^IEd{U}d)S}={zQjT zEUzvTD@P`=oaAfL;|`K?LtPrK{%yPZ7^qG@xxkG1VWQ5* z#Tm{c%U(k5D5Dn&&3Q6nf%)a~q^zYA+ej$tDW?wgi#T+%-_^gej2o&&>#{OtlhBDy z`(fIp0)T$VfL4rid&tWD-lV4=on@Fa%Hpd50(>thn6aF{JyBP2rC1D`LQryS={Pg4 zcd(^z)i^?$M?$xHP8r?s2CR9aUPTxWIsVQ|jqFc9^1Lo&lcsSLCD)0p(Jq5o`VmG~$)))qDWgN8A5Qf2lnH9vD#Bb0 z@bfbb+XLKib!N=9nr;w?Nx4n#-Ft>2eD3`E6Uqfu10*hYkVrszGeByBIujk{dZxji z#0{U8??_U2lECRz8h*E{ap=rbi#f|v1UOB7_c=f2u`#%5ZhF@?5V5Ov{j`_BcFy?I zT5tJbpr>3Ae|Ilpv)v{Z#Obg8E5!CWa|z|&$P)wTL`ObK zKBoWzIVCH&aUCdX@=+Y|B7rdC>$B3hPMjEe>^Uw0f?oqp@V_${073=685ZWa&r$G) z(rXxh7_~9gQN4=wK5HCjqGu@DTlK&Hm=gEtPRweOreuZtq{Cwlndl-NjR=``a=h=n zYn?hc{ub#}cm9Y#DmwRm<=|i>4`eR*n7SIggpO-V`^96tv|RYgA$E+*&B<1iBb%E> z>2@~_^Ys0}jNZcwW&OAwe6(z?JbMKxlaW6>A9N24+c^H7#C=5-?4ut`;(dHoKgx5i zB^h~`Dtdck`EVuew4fKZuRd1k${I@Apq-F(jwS<6c-&3ndi#xjr0bA5IlDjvQZt|^ z_7pc%QC-sM#eR@a)Ojv4+d?pZtk#eY+k3f+i?SmO1IQprRXgN`ElQRhAN%ge1B*vy z$1AIs(Q~28ihLsBVB~0@VazZOoC!S1DDhzxu}{@c1^snK?O|-{GFX0MJr+a3FaU&~ zo}4^DVS}pPt7U9m#{D9%;0!<#2^|?DEK{CU94Xu*VZiy{BI%2 zlX2V+_hGrc%E{kTIs~ew4%)C?PeJaj!%{!Fa39Q^KkS2If6&9c-roroxNo3ic$2_Q z0^DWnx-FPF2q=qk%q**XP<#QqE7^Oj-{lXC>)cvKN7@w{zOY-Po$TMVA9AprZ!qC6 z{hfqX0qft&!564C;E8>X2j&GOL>oo4l7LsSTdUbdJUY7+d3KhM7alf9Kgn|P4@zj6 zOgTt)1I6BK-qq~khRSZVW@Xq9m0Xf*dhs&_*TE}``Q~y#X$l?}0hNA~5fbrs?K2Uq z{$6-)+2RustS4`3*}?o*<#o+Wt83_(rlGn;od_<%J1GU*tPJ z{Xs!Mh}lEnJ}6YYTVW~14XxwO{#3<&oYS@txvJL-G)>(*|~cgg7Hhj-T}crg!{X#VH!>0#s*J5j-X_X*11 zeEnG%>&L4OzvZK_eE1|)UZ?xs6ZC?D+w@pI1UFh|-(nv{XNn#3q{;liNrtgn<_-dk zK3EpeI5iITG|fJ=iQPp#{^g<`oV>7ZZ1cpJ{~vTT!c)%0;2z>Ni)J^xj`6X^Y~{%t zWN?1|b)tfeEuy${@RxQi4>aZQ@OuAg6{Q`H%TFs027bf^?|E#0W(v&6swmH*Ctv5b z&mD3{XKQlFTGR=UrzJggbbAnee50*G>F1BsOjhi@`Z%GJ!R@<>;v}F3T!!a_t3XTN zHpldVb1vA!+ZSD>KM36P>jJH`vyiIP1(g#mT<{22X_3Ab z2{HH$$S|pt1C3W49XHsyVam^fv%^6HV99DV>f-*F;FfG0Wm5(Z)F|Wh{qlJk&4}%F zd<}6$ioZztgH&9w{9Qv{E4K49=&Sy1gyx`sah2h2mkH3ZPcDWWV~kOLP?7D(8vq#d+6%w_P~D>#@Ku-7sI}8?G07d15S7 zq!QIT=yW~6e1;WmY$7D=hx(4LZyp=Y0c@$))Tphw;m$uF;|lBteY$hEoeSq39Igg7 zDkxyThV#QEk>GVyHhybD?C@PMd(4*J8QUA0#j1jhuSqD}?pl>ZZZR6!b1^d!$NZLk zJEbAzKTvwwn_up7*5JiMu`qUg?=Cd;iiG0(f`Fuhi$WgQE?W2hW55HyZr$&!68(v8 zQ-^yQ%-DcaB43}%7attJUTpUJklr{%!p^dMvGQ|#vo?%rstBO$UsloCxk`G`kUl~xbi zS61PvAJr!YLC`{L(IuvPfKv49+gsTFB!3I|Y%Xo09BsOXXU{)J!hg-8j$qzPlf}{O z2g$z?&5h5~T+CL$yDKnfKfb35oBMAG(+>f?9%nZ!qFF__X0I+%xAnhmqjZ?-XWM4w&OXgkyMyp@)2o&?cI$D}W#@uDp@Qu8M zr`8Esk&8Xs^TvJ?Wuk^Y>j1jy`{L20@_iIGJgdlp{T;s0Qe$)SX~gvW?v7ZSAL@Hg zh)FKtfh`zR={C6uI{aL?HX>^DizGB!Ivim{;yD?Dy%&9`qY34S68Q*u# zdbQ%!QW7HCzS19~&qmJYv|=fSsbLYdL~2Won;eP9aeIf170(qo2qNjfYfDSJqGPe#dw!Tl{b$96=Bg({K=Q-W%clh5kVL$% z&JP^-FiJhxl-yp`v;!p+x-$-A6_mmsH zrD%`!YsWkf>T0~#YqP+hobW}-0Zzyge)7@eXA%n1IQ^*mV=fZoH2x^chU=14g>KJP z4x!5yvZo5#6Tof3;AyGD1ZdwncTmG}0IVI>3YHd#1$Gw)Jg=qjz^+5GRpP8`$Wf4p z3P1Uy!-mIie#h~*Fi*5N)JFoJS>#&`^CD0kv*Jk56>9iQF1#xU8zO0pj@9 z-b#b(GK#tvKb72=M`M~?kG7-rkdMc!cr9!=>HbE}=RX^>mDr=JC*1o+v7bvLxTf?S+l@jiYUOEkZ@?mH@D(HO6PL_G%1^>^ zA-xXrpCNLws5?l&LAr$-z8Spw#uVoZ?xmd(+lq@sMu&{H1+e`u_`xQ28`~8Zgk{d> z(4~Nq2MHgR30yGcf%)fN(g2tuZ#BF&Rt_GXEM4TAMc_K;>Se<_;O7^h8l;t_?Pj95MhCo79~`H(RG^ZfAHgfjHgBa_W9gbNy|rL5T8#qZ15uko9` z0WRaqtadmKaMxw~S=rec!HGiOxk<>FpOJ!1k0} z(wVLSa9zJ*D=;k7N4bS+bsa|Ns@&Ba<+v*M} zpkDQyplme{B(asmoW8w`zPmBJPO-BAO3f|Z(ztKP=}+n!Hi|=tEGlozlp+|&_q?g1 z#(vZOxUiiFiXjlYtf|*YRfPME^c;k?Jn$@eTe>>`FZ9>&X2;>;2Vm0sBYP5#-&%$@ zC6~M*0ndY^jmKg+z^mfpwPV<>>tG5to}DKl(S|{c<#AZt>Y2%RLVh^Zn84gP^9%u;J1D5G3;I)(5D=1Bcn_IH}^7u>B^%%fb}` zN~{6`?EhkaGkh}WS}h4Q|8nj0rq4lp|I*{Gvtoary{0#Ew;z!hi>@E|S`92uPt=`} z!+opS4XXulo~852xP^gB6v{sMn!FMBt)Q{&i(~2diGKU3@2CVka`fuuQtX~xElVaE{svS+Asqck_FI)UFC)c7LVw&zaxQmN99gvm5FkX zQ!)ac1%C2mlH`t&SS=|}I`H>uY(S(9Yz`H2l4j$T~4n5PMphE=M zB(Aptd!?34>_lsY({&cZTRyIu+!(-LVkaXx6xbkUv%$6M4#Pbc!8 z%0xN$8OE=85n##b^jAJVNytJ?`igg=Kj5|CJ+6W4;S;wb`|WW2NBrADsZ0jeWx!|KVUxR&=1EBIz+2Ma=8K{)hsj>NiAJUrb zKYEEsO?=YsMd?su0=ff!Im|inz-Vny6cPFhX;CY+|ITniOI8eZf5>^@a*1wM-ufS8 zr>6W+pA?7MXGIfAr?5Q#JNdbI_$P{gHy!$CJQfruYXlxnNTMxFyY!~Y))H-s-n22S+G67y{%Go@X{)(*0e2?nR5fa=l-y% z;rO{v#}7_Tj88uCBX**IB?KIBbc~!LBf!+va!x^aP-LSil&<22yIn=f zx3A*3dX8;4Ie!J9A3oh%zsUx@e$=OaT%shhRW|6)w%Q=^z=z2xJzQ|gq*{b_iUcSg z@UeT)r6Drnl_5bae>AxH$qva(q39F-a2&#_ZS56~5C7r~Ny6{@Wd3TsqnwKF zF!k; zCi3?$ZoMS|;a<;@g5nJHPR~DLERY*A>RG?>OCf>RQC8no-xUHQ8=ZuQ)7)^1a`07V z(JTSU3*N?F}lhLKYX5Ncq>anGym43hp$zFX0KCPL%4sa&c4p9AckdRbs*E}lB+Aw zKI-~Z5#uo=&yJ5x4s4)5s>h_6burKL-jIm(JU46@FiRR;90FIYijzQH1PTa^a$9_f z@1xupi!Zh}UT-xil7~hk$<+0V|GDq)BA=+-!1rCeXu~3P^fof%x?5Gg%mY157;c%z zY@kPTp<_K5=OB5}8k5g+LD!m{jD1*tb+1u3FNakCDUC-bGdO6Var(0US={$Q^NX^? zTdQi+!&{{HIg}du_#VHNOgV~lL{(L#Pi6t*tAeS4N>~rFG8$`(3<6!vV_oIG`Cz;4 z7fS=q`;+e3@SAt_qXDlryW#J(pzjo?RMJgqxRqO4TSh&K&K*9``Q&#TQb@imTkS** zqpSC6Z#Ik|#mz^PS*&lsHOGc)`8cj?=Px}{hV4K?%A>C8$as(+!+ulwA`d+1R`SP| zdk*Q2n4c&P(nU9{HF|5YTvAs^d$qhaj$RHt{HA192z<}@iYh5{!!IYj=qDHYL1lEX zh9Z`$hWSI+EHU4y&%YPb^W=Nzb@-BI&rS;3-Q(+_ZNu@>7%G{^{v*IN$3(}?G8)D0 zo|sU@aU}T%Z>i)kzUkj=_Zv#bJ77%hy!sH9Gq>xX+imTVQ04(AUh#u2z+39>(v&vN zFPQupcfB};j$T-})YX>&pHyY>|rd)RVQB ze=9d8q5yZ93j-GT{zeTqS??nuI)fkAvzgw5__=?%-Z(FR#O~~cYZCov9+|F;fg zhE@#U#PMNV?gJJB2SHg*JfngLR!gQv+Q(d-)d zULf5qx|v?&^J{r~UAh_BxCZi_zKYkO`1ShX(h;;GDMogW2KOPAXVRVx=7PZsALd_` zVElhQcsfHMMWbmndSs7ia1qT*vMC>@iS5O*iQ!-m{Zhr0TZ-=bib za^5Fo$9w^+qX z)U0^H)E391xGrsEZ+DQulL2PwBbu@3RnvYZF&t-mK;bjXsZRoo*O|wMW-7tl(BD#8 zZ2$aF61sV^X94B0w@%n@+XKdpn~cLj>Ay47V%YbkrPE#GG-2{ zWTMZ#(-NA;abGinA)oOG1r*xJmEcl0MLe|=p;lEqFf6D&w)W~@6dWXR`X6l`&+a8)w9TUh&ikz#Y&aj(C9HQrf(t%%%#M2`NCNkd7dd#8SAoZ+nYCiOIFFfE^*4vF zANc-M93n5O2lL(`Oh;2O?x^@={7S?CO59@>8*xzr2CkRK+qUq&9RJh4J1~yS6rZRw zCq^PRe(P?->s-*wTHkUQ$K^V-o?G+=WusZQIXh`ujO);~;&wRDkD}#aaG7>J^7y^C zXXM5W(+~bIxK%TW1iFs}Do(vXVghnEn2bU;`Y=!U zAGy)-#ThgMKAY_xd4%lZZYYQuV0-&kY)(e%8nRVhbe!fd26chIRo!tOfu>29lr#<3uE4yed3skDSn7e(W6Rq3c`8^*3V-!wb_BgVK$fiQ z8jYUKL@*r`6c0G0kZ%}I{nbG!0<@(|9)tqTq% z{=RbwPPTW6p9p~MS^zQY>KO05KH+YuM*2W@YRG@dpJ!*JQ z$zWI!fA6gI!!fQpdr&W1W?O{gjYnu^J#F?vfjb4FDUV;KEC| zFCnArj8J|D58SM0<;#Dtf^1f9c6`uq26hJ+rZ=3a;kg6qe*##se0E=t6c`LaRG;~d zmSdboV`a|hxb-0TeAo2MD#p(kMt^^+7=+`%HR6K@J64g%Qyv|&s&`;WLfHEx<^$)T z5hDA-HHy}|FC5cL4F%edo7?NKU$d=fwIsJWgN8oR=Z4#bp_cdg#H;i)Fd|Qpe?)K; zbx96i>b1;9^v_fReYtVJW^aYMdvPS($CH6Z(f=i|b-o##s7?*D1pYki+c%01n{J+G zy&De*bvB_RI39SN`&(R(HqNIDJ2%+}RRTJ0!L#4C+2|>LZjynJ2jMy z=8$sT7(p*y8+nO*eg-l*)&@H9`F9M7&L?317dk}hGcx9*SEpLa6_Pn1{c^(_zEijk z>#sqL+?W^GixvqxLB$2nBo|9E9GONGj}}`GHs_&s`sIp1tncUuuB9k)1W;|&Jblt< z3+}79_YPp3zzVsS4z^W7nCk#bHC(3*0}U zD8Eyr=|!<`3pi-8oL}kr>~|91i^E^zTdhTP~3(ceTJr`z}nO&n`^VbY4a#S>h-Xp+E5sxF9zxM+V zA4K;su?C%e|Ld!V6E{rrz$Ft{?Ina zu0gA-|BQr4-oi}qHqFm|4 z5$$j&RqFOhsY~X343u@{5l(!H{kCpOPxXKtBdS= z>}+6VeL2=hpXBQXJ35})I}3kDoM~xmf>F@k&itv5fNf82F7M>ii? zD%h)&9Gk(;bgW5ms-Ur|SA>^|I&GQuSXl_aj%v<)8&B}elPkTut>R&x*`;NpRS4hg z$y|xM-wK2CU*dOaP*C+5pZfwNPpqxrk<4h&EJ%zbuBTb)!h?~z$Ff;M_{(VE>rwK) z2|3s+tDlYoTZ>w;%06LSVZ#6Hn$IA7=)X)ScI+{@KbaIutR?%@WR!WSLK_=e;j8gVT{I#rl)Mk)kDd4JhQ=Mv$1TqgT;)f1cT;XFDpHi`c%NSaFAmp@HdhdQ ziF$fk;L0c*x|FAMg8Bty`KpbJ93s7J`o+Z&gy3^0i190)ct1F68()LH=s{PX9hD2(o*ciD{Oy69y&1+_3z!gpucg-AYx&?|8whIvA`^YG((kNtB{=^ALWyq1BQ zUB!=65gpWp9Y(L10y~V4 z{NRP?eDwFj>m;{OL43lL`upe=q9a{3=iEomtM<=(uWk~)PkDFsF>5jxu{-Ib`@V7L z^~${+@_r&X;q|u24UtKBmQ`It<9rdePKb*Rl6kMK|4>oTbSs1;boyF{7ok%xJ9%yt ziQr_tmsNh+(~xkmrtweICD2utH;^H@&1xZ1)WTm$en{@=K-mX@=uS>Ti>a9iM#qi5 zUzDS!Y}3x@&pDEY_;jVhv&kMu{W^&z3jGF8n|xZ1gaAaxy3(pELU`4a-%|fs5Z$|H z^gC7kOwf_}cru6JGt5pa1?psudZuY}3`f3!BXcPM#bbh)*XsUYK~Ecc8#3|Y;jR>v zsoAMpH7JY~nj%jB7cdW(@~%f5^ZAH=@unxQkiC`Ln^QV{eG*Q_dM(jkiv_*O=RB_x z8E}<&M{tc;4^;V^*jO39MkA7~iT)xC_}o>V?7FUQ@T1<-Dz)|zel@l2{^~%^lZkgv zUT$kg8Nzu(JTo8AyVT_Mw4)@4IkiK^i{Qzz>)MZbdNPsB$^{#-0Z|%pgze`IjL(%i*BN*P+rnbt?i0#-!5B2Zu12@`RRJ1;} z5YnaZvdu^YUm0{eu!rE2)v5Le`IVB;-@E0{sXx+VAD{Rgh7#Q{*T8h;{DlIf#nNSz zyC#Gubo0_a?rcL_UD;FrN#-G^ZTj}6Riq#G2CdoTzBMr3skf7HAP4E(24?w6VJw%X zoWwHKf;O_Z?E0!%f!f;&4!p7##HoS}A#9)9P}!fPL)X52fJI4p_e=YQaMA>)N!3z6 z#8fr@=zfucjK4hL-b#2<_fK?j9#?27j496N+lFEwes>oBep3J+cHgfv5JDP;VLZ_kM z13?D?EFZ`;z%t#4#ymrn|1$qT7aGd-?s=2vs~h`8iQJEtVj5oZN3%dJe!9kSC*jT2 z*ePMphk!Hm)BTR431EKW^7u8f_hp)B{`Xa68ScuyTw(D@Lk^F81PvL4vGxy>Pl4B# zAY=S;gYfrQ2w`K1lw=mcNos@K^L#U~U*hk@;T@5vOh|I**Lz`H+Bpr@RMRl%bLCZL zX)Frk+xz#%fDnPpRCiY$YzO*^H&*@pZ;>{4+{?&a#E+1e-+5#IESQMaZWMQBqXvs# zd~^*AxHVjNuAkf&dM+;Qt`1>PY;R_Cx|ZntNB4B~ zMJBgzvJJ_!*HBoD-M~<5P?vI>;DItGcjayVLGN#c^rcIA$m=!TNq#bijDpti(aUY% zZ$13ocPwQ_zr5T=c(K^O-#bncUreZf>$Se+_h3u0zqzzZc(-?U z)L)5yRea(32iaGFC`C*6CjCJ{Y*Zye7vj`{o;-4%-3BRq2J2bm&s@_xR5JLO~$-G)ReAKNgAC6fG6cHf62*O!J(o>_lw8fpYy@(bGg zfc|QA*U`@+IIW>BR$xpfgtckL}N-v0)bRvh^< zOU}vUy`lM^6*fV2XN$Dn;Y@T;(sqKfl>u8k_P$6v(+vskv7j9g0l_;{s}0D!+TgK8 z+HQ&H7$b#(PD#E)zq8h|4Y!HlMz&IkTBCv{bN-nB4tBzuM|}QzM6MYE z_}zN{v#kNiv&PP={zd7tnc(U}~)u+0aCS0OyFKBf4^ zdpMo2ODd7!FvEaCk^b_eG*?Od$%_q1^7( zu>kEIvPjUG9uFt)iXW2c21d=~{{$QIAXD|zd6_q)r$Cf;B6nL4ygulxeYM8`hE55s z@6Z#$yk@uG3wLC~^Wed}XKx8^r=fkdK}G~KGug5#POXEiv2J#vbSer|RB2jZWWrlg zfwq5V4}23kn7;qvXNabX$$TTkh+~6)Qko3JZKU7tbsgDr6B&a%hFc-cb>#MO^kJV1vC)j=>d*zgg?{?o0NaH{H8y6CYzmMm%cYNj~ zB%3eM=R3wj{v{7q`%Mwd6!2)Guwe}}`m$Y9k3^&IyVy^}ll^)NTePD3|9m~e1qxB^ zzR+zs&7DZjD}&mCd1ab*P-8V{(n>agN;6kCVY27u-PHKo%9R5i2Xkqh3Eysz8?x?C z^ag3-{~cL-zYJBqj-&MwACXz+z>f~XgP)wr;iFssjjlF79x5a;n$=dJ@_oxhS>bW`*e=y z!^U>W$y20XAT9g#iKv6kpq3S^#dM+unXMOG34bbr1-ZkdYv%qzwOT-T@3bYdVccxy zsUSV4XZMDycdh_$dxDth=@?`aG50JuM-X?*Gw*FKYA1PjChZGz(U3`{c{|32%&{%L z$+8?hFk&vVSNl&e$+2XoHz2vS`8QQ%*EhOhL}Ov{&!h)1KA2UFApgf=z11PorUe|h z>t{XQSHg{bhyVEIuAJ1v{r z!wEMrqrsCx_<=WfZ;xyiMBWIwsHa2puqq=xc8o&!X%VgGkJlAwUEJ5~W_Ank&_=%Y zBzS`7znhd8flsZHgy4AM5zd!cfC_2pHB}6Y(ZI>>nYE`0)zJ9{bGxGP(uD z(5KqjlJkMLFFXj7^I>r3868n+d!Q=2W&Dhsx4*o#gdT^rBC*+?`;_KVWXv2AW{g(R zYQnaZ1fg1}Vw{{{7HC4o+r$KON`&x1{r1TH=US1sBzN%MRSJ4&{p7XwWs>*k-dO(M zWx_Z8sLnk4zz9kgHU6w6kY3K;3U1!ye&@)}EfOX@+L2T48~OylrL>%W6&I8VdoK!@ z?<8}6s*_ujPY1!(OU~$}jFv%k(WM0{)QYV11J+J55FDv#c4?Nn9X(!OX|{Oa0+noS zbqb{a;*`dApgqM2g`_xUb7IR zp&VO(l6dr~JM0+|aW8wti^U5=*tJIJC^n{ctW$o0=-QysS?L>`B>yP#!fEooPzr4~ zzn1mm zbSrMGMBV2YTSG;08jxPOu;>NSlaIxJC~y(KiELsn!zvj3aLY9!xNAWjU7_AJ7Mycp z@r=f|abV(3qpgq)LV3P6$7g=AVJZa;v7KAH(a6^ytn!J4U~-U;X?cMUYpO|k?iMBI zww3Mo;LIYpWtFW6^}LvVuZ-BW*;bT)^E8bqcNs8f+&gMK#EtJL1RUGx-;Vr6wjV!{ zUIf((&+A^g@Zs}vUxj~rbwIwyg@bZ^6l8u@6$Zrlabs=cu(ClLVv15!ED_Ix(^NZa zpXhR6!Qqci+LTX!aY(+Y4Tj)qm~h^@ zo;{jAyZPo<2^*f4-YcFqG7X2uWZ2h8j&U&8uJ8AcvteE*W8ahaX5inA%(k~tt}u7# zh3{bMPK+JTl(A_(Wq9zEjoNt+2j>#d4*8R#~ig zcY&IL63sM>n#-H4`jGsa4R$0<`qR(tGzoaRe+FEt?jPBGFbp02vnT1c>Q;>NxOc}t z*@7i4ySw`J^&zOh{Z9QoUYruoA@bagjxi))l2u_Er zkLkL@;Emnbnp8UEr~p&MRE_x{Wr4;a3Nm@w#?s78k?i zaK+)_Ab#w5oTK)jeH&`$tfI`UX2E>LkIQEMTzE{Hx_JM&cI5W@{n5KMBv(h{Y|yHX z81|3Y^8U|PqBG|SeVD;>7wBJ|cod<*iQfjpP({rmw7#+x-TvkSlD>T@c7BruD^1MT z*39>TjlB%ZhEY1uTkB77%W>nU7uQR^=~Gb@gg?y-iCUxLm!WckiY)m2*vgdMzixEJ zn3*C)l?${N=0!?#xpB6B?N>DpYKo5B;<3os5RmFfHE9-O$FaVd58gJ;!d}zK^ok2zgg6&PajP7QOYGM+3-oK zlVdNQ5}v|(Wb!nJ9qH+FH4zIHz-t=pR=>kZ55n8}M;;3y!0}w!iDoAc?u$F2B0NG( zS!%q~5Z=ToKyz(B&@DDVX_3~gb=|;vQ6`e@PohX`a zR3IH2e-G;(qGv0hsj@3>1HE;IXa$3JKsQ(?Xd=!>-X9JQKSp|rwEk3@{M7*HVzUvO zOy|K){|@tyoTH_r()oD(>i2~I5@uffApIaiFB~-)POQMby!&>A*>^zT?FFj+KlyQZ zyL;M1aVz>FRhIm7S1A-rKK^$#oC$N^_D_5u`xmGRc_)5SJW!_N#(%=}M4$!oS3c-U%$ zUp8gKxr2PN<|jGv-D1UwrkW)<&R_JY=!p+J_OFe2G0la|4}~6=O5K1P$uG*_Obp_8 z9W^oj&WVkpOlt04>qK75Ne|blOMsTPtf?@Mjo>E@3OUzi!Bpp$c=}U!^qz@YxbQ3! zj$aGcPSzg)BP1gvUqJLNVLW#=zO&-Fdnq-09(032<5wM-pM~J7A+0=gh8@FyN?PNZ zb5Qzt+EHNC59xo1XjX~lz#;J$#QCkd0B-qHC}xE)wxE(!x5SM@d1;0wCdl*EZ3ts# zum!7I**cx!20&@Pwp^DN1nD_Uwz9gdKQc7e06>9Ja9u$w) zyVr@~y3(dw*XwvFRe|sLe!f&g(%LO{k0QA6#i#tEQdc+N)+;UUCpVlyZ!q`4Y#kRC zM{mMneAXc%<592|dkm=B=j`bl;lZsJ$6vRmQ38E5VI*wXEio2|gLm@N$yTs2awPUp3_6WW%xh_@ow^`{3<4(}!J^8Q{58 z7VaI(jw4>p56#ug!v208CwIjdNRh1Bt{K9PcWK&sAFi8&5YrTPkF9~=694>884n+x zVMtcl5wwM}cy_J!)^rrQ=$x|RI>v+j_C}lR3~vWPzX^jQJF>wsnJS$sO$^%=9qa4* z%tQGYsK6q)a2{?~?3Z-)vk}}k^nR)G$DR66 zx`)GvjhstumW)5HYEe_J{9T)$t@47m{RTUjOSrJ%%#$;xVFQ{O((P)8ydXe~C0`<* z8~adg8D5-dN8XH!mjgEPVP73p^4J3o%qYw4Eijtlk(ejc3)b>PM~t(dDe z$Ehf1cMc@p*y@1RN(MRUNj{a*)`#MrAtVpv?5Is+b~f}lKDZM^dclTc9L8Vn?ScJz zE@>H?X@qCHGQpw3jjvoU)+_X+qWt}p95QwT4M#=Vg;@b z53*r*@uf=%#xtPnUvFo9`5w}a{CY{8UI5SQ=j5Izep~sw=W=%)NCBNI%Wl<4+<1@Y z_KrIm)D)qIO7gcSZ4vWMHEqT>Jh<)Zx0q~NT8fL(${PXAR}iQ*@ph7%2hUENJ^z}_ zt0@vj^c7E_)+klK!VpY>8%DAyvz z`rmV6!_3&su-Bi#Yz!X9*$(vycp$f*nL^$6!npah$}|6tHpCTUw{xF*6hy9t)V){| z#j<4|EIb#uvH4E*qg|S&fQt`2^KRnC3ProiUPn_?#!noLz9iuY%c4`ympz$qL&Box zM1Mbw<~V3PmnA)t{9(@q!bl&G=f#KbF8l@kn>%TLr8>g(M#mtJt6bPp`IA-ajdfsq z<@!S`-3n|T?z=xR#e#Re{4k!MH3=U})y~Vw*rDykj9ToZSI*~>V)U_tAI4?;FY5{;HV}m6)RX z&xG{pc5i%BdDa8|U0;U6JyKzNehO_r`Tw8znbe=ewn5SQu}gI^xp07a%;|g}H|BKO z6Bzca9jV{2X8oB4Ab#}VK#Ku4e*4?`zr5sjuwQq1wfqTy^ymzSxiG`Ng@hMG=i|WnbWHYVHPUEsPrXm(if(b$@5RfL;OBJx`+WIb zIMOQE>2Z<^-#U6vO>S%rhWbW4={2YgeS@E5+H-6j2r{Lh2Yvm{3_psFYYV=twCw7oB z7Wy*L2?fsv5`~v@VE-8luFv9Jxbc13#|)7U((4ht%sWy6b;tL&bder}>YnYghDUlJ z_A@QJ_4d!;I#TgumgKYu$Tdx95xvdM;4f5T`H8S!s(1WW8aqx4e*H6lstb9Z(-nw# zmk(EY!ut~1`SF&eYQH%DHn?-CjVpC`2K0*5jvBgf;Dlkmj8vX(u<+oQQM{TBgZDku z*gvr1MRD^(j{KeAOF5Hs{7x-QwVylQ`-~OO>gA}ZzV1d(&yP;C?kxb#u2;3vOr$sP zQCxWv?Hm--m3KdFbVgOXHy5rbapHHG^_6>KyHM$&$6sQ9kY0ei1L5fhIq?lEwX}>Y zU1&$x^!eKZIq-L}gvK?FANzI8wJ#FBa+?SH4-Ljtu)Xv#J6?|q*Fn?0rYq}kZ`gR| zWU@O1QE~cnl6!xY(XQpJY8Qx^7QP&u%K?McZpT+QS@H1wXB;E%yTIMVTq(}H0?~PQ zG;XQmBR=SOzEP7_V4Gt!1Kx5JVL{p0Zu;wx$A*mLGdGFUwk z-Dl~>hi|XQhSM+6Q!<6*I=1b6igJe(aVB}++NOkGvU#k4Q*Tazn4T5j1&1RqgZc5T zTb8l+hg(rYSNr{EuZq!@;$8t4OFmrDbTg98o9I-dZR~`i@?f!shu4yo3#+^n#D2P+ zNVCBpX~)F^zy`28MTHl?%Bhf&)~BObbMU<~-0BBs>26p(cjCez>Ce1w+JeH3QlvFn z>QKebY5VGFCj9VuhkW7=<3>*qJX|yEw)ls889+NZx@RVV3&-Df5=)v}gR3>l%6-9cNb9wO zU~e-w9&h{SkP|{pIe)3_mrb81$~RnevEIXn>54N9e+`iD^yl-R`Ak_*-gf4nC^a{B zc@@K9P1yv$h%D)oU;K~t(8e{Cw+hv;M3Ck;0*ZEuqX>uADgiLZfP|O&2(gEsAne}T_f5RG4CbYQ5R#xsV<3P*uhF2^Rb8x zEAb8e6jh%E=|-IZZUt{-^i{y2_%jRcNHR`0dfW|LwU{O^d6uA)GbL6+`7HRU%$I!* zsl6c9na3HMln#B_b`=ym9_)2JRlh2ZhN6?^w<6E_n)H;3FpuqE$8Ac)vliBkVm;kd z?H*?l{Or`Y>TWh%MbCRvSZ4+*B2!+a{W5{pTD`ryocOSM7*oxu#x@YG;2UE;mkCD? zxW5n$BsfyE=jT5cI+4TZz?GnfIp7fHbNNmS5B^wp`|gMi4dq2~uN;e35^~a#s0>!; z##+`o!Bb9Dl(<`oS#gy<$SbL{wBZUHzC55kmifCID7TE7E`QAg-D|V$oN2r`e`MUs zg5)0teS0;a^4=cpln*N|(PPGHvrKjEW zq7xjs&Blk<(hlxF%}!4de(Id+J?4tmm{pY|PH^IXmbC_)$x9#?<#OEoLLg$CmE9ku z$%doOPzfInnSqmg4+M&N*n@>^OTvxwyqM16cWnvL_5JBRGE$?L4N1fAT;l$4ti7S%zIW=en9QgOj4ejX@i;&m7@4}3g zKQec^rO7_Rk0HTYG@SSp9`7}#V|teY|EOFCnn)k_>+tKC7nUHngf|&H2R&-1*@CSV)pz}eRb!soT@R=$_?Z%T`uo*6X*;hXY=%Vgc zDGqUAnN8#Lo7+3k-{#v91~LFK&Ta}4hX_AnAAL}FtrPreiaP&Mz92oR5wDL!yqMW> zR5$Gr9fgGwDkwRfh>E}7wFtP#i;v$r^nJjb@XG-Phjf3Gqf?$kzc?2-ano#Va%kf! z9Mn&*oDsDGGiId|83AHA{6Kl)?`~@Rrk*d?|*(h9C>NB5lA1UAFX`!u@!J!lB=71{ub@eJ7l+cln2N34{~Wx zbpu1}m%kA|vtiF{)||2j6TayFao@K5Zs3h}-cXh(1lphPLc4QVF}tc!<$HDFo0}XF z-0{v6dGd$d71rg$RytD#)$#O{M^qfgJ3}4NX|-(v%Ub-nRQgeEfPlJAFFn zK~1*DC_C;NUC3tpJ`cj{1@V`??U4Q5@<~JTKBQ{RF{XvIB5hLAuDiPo1h0Jv80=!l z?|O>WDuO!Ezt*;(r>&Jhua^4#W)LGTJ^$s+5IfELO8;XuL{_{Enzav(l# zc^Rj7i|O} zUORrXnX4hV*_;1<7wh)GqN2C;^4T0%UcUV_!%G0mrNEzyEp5pDq3&ckB!JI5U&E8q zoY+cQlhH(U5yDD$9@teC4J>=;3lrtp@qt!})L&ZNhzYm!y(`WJuCk*~JF0o{t>Qa1 z$1%wVz=f>6b(z3D_2{8R0T0%>nyUKXJ}qT&P*}+5z!SI)W&Gj%yx1e6%gkJsmh$tc zZu}w7k4XB;w<7-i?D*&QN{WGYA7senjGxw|AgTGQJT!}>_ot^!T$1pEe{A$}2RrYe z&Rq|cd+7OaWVLhAsQ4C&%f3jZ6Td#7%q?$HB%d;2$MhAq`6s<_`RJ-+cuP8pR*&hi zCVOSGk}0P+(UHCpt~tl!ZUdBJX@@7gJUB=0@-wPkG?exjIq7t_JK%bXrZUKWE4Cef zmn2(8PdTS{QM!?z?C+7rJ5N@y<3T0I#fiEJxK@_^Zh+}C2zEGdv=e-Qs`~1*!hdAH zo3Y5`FiD4xy*Awo_qeg9Ph+Lr$ffEtiC)Hbawhg z?lT2eob2*9JfE>2y5Ts*>|r75ppFib=Og{X$sv>=*vV7Rs=^3((~=4rK!TRl7mRt+m+pUC|0r(z}^W5|lDStkD|Ql{YS zrBAi=*R9}DY`x7pS8|?=NST_htwUQP?HMDIOMmt0)@+SwZv5!sjV-IMs3?{ByUGLG zk`RMeAsbUFBVMJgK3ShM0Hr}2yDe{6!{&u&QxP}$Ftgz;*{U7%6j9b|6^8C%;6+n! ze)|IlPNjGLbz!j!eV6KtR4~s5S~@moYYuMA6Rzo$9nb-s3X%5fM!7IxlNd1H!-0)? z>gk$u7UAN~i{m^>*1#G2K0Sx@8?EF=9hOn=0JDN&jVk?0s7&M#o?Pd_MMHcEFJfsa z0;kRjWgZAaH%`qPj`#}W^8zwSxkTs5_^#tt#HB}YK>CEuUN=rWX2s5BzT5>zFMs(P zIG+uz?!3w7@?!X)pYcUWYAV799@C{!GlU+ZvJS~7J>Zr#Dq(#+z>>4cu(k37eCVwU zej-Hn&<-@Ur+5|QK=p@;K{yIey!b_b7au-`^!MB(cxJ}7a2*%XOo+C1q;+N>_#tt@0BsTgRncRb|BdXvn8Mj&-$wAFb(uznhvvC(>*GOI zY8!5R#xzAD>R1QKr8HhzxSI<>a?VLTHY9J&GlN%wk^E@W={Jt+w(#|J5*M`*2bR9Z zuHH9C^w{t3?j#5ox&M!Co!iHaPbsFH<-18mv9(eQe7)BYDQHP2>fB|+BGeiW1+0s} zkWs_WNwFI=&uV}Fc8(ppA1T|r>v<<|8I4O8Dpw)D(Yk}5&WhpkU=GHs22>QPxRRGW zB8JHNR2A#O8)ht!dGdJpe}91CLx0|uf{(B*=^q`fEIU3Ot@N+{avwBG2c_Pg$pqy; zJ-Uo!?!}eWXODVPQ2GF$M`>YFw`5evAq(1mbeeQvejGnqGR;`p z2Ck+x`^UDWf#!00ZS@I$>`2XbbT=*Wiw)j6_DHB0Qff}wR~+KOj>sqOA2$spAQ5yb z-i9IenSZUvq2;ZX4Kj@XOwU8A?(+)>Q=Rl{rI#CJdBH$S?AixOleuHd$L19WnWkJrc(9Dw_mlJ(amnALIq z$@ZTO`c}^?k)z3r*H|pSwgl2qB7GGs&#<~9-Y?O^>5*Lc0?($_@}mvVrks4R3*Uh= z9?m1x2g!LGH?`Wg-UTi0{aLb_IlxzPxP$LK3ubuVy^~Y-AIVirydbCI4kwK&&_xk0 zoRGJ6FQu{{ZoISLn*N*(1Dw2Hm5RCWr&~2%iRAC!GJ-Q4hO*&a+hXv)7$&^%LXvJ5 zx!=JkM>O`@TXecdf2{oo;VJeg&5Mw}HdB+&L2n1$fzeno!m5o6pZ&}d<^~-oY#XCe zd{{0thO3WhkbU{ZsdZ~36Ec?$49N&f=MvvcQ<_x~Cmzzj7=BNx6W-=a6nE!VpgsFJ zM9fGYTIplil#sDDwAvD@fJ|JGuqo5z7fZ4aj$0@;a&-Z#xc~4vnSYv7U6OG!H@0=L z+swa2P2tQvCDv zx8Y2-u(EEnWpXIClk8=WsX9Nu_?`zhO24-9dUt^rubk8{Ip>|8OP!S@xc%MNMLC++ zBH$}6E#roJ4h ztWL6GNz=)5G=tqphs`IF=4%!Vw&z_+XyC>(=4v;!VyP*?dErL%>_*5TbD(bF?FuX0X&=TfxnA(~F4X5*hjyQK`2e=H4N&k)Ap+S$#5s7tJG=^QfMWc{~qz{jGGSRWvOEBM7W1w71&;CzW-5JTx zgq|sE-1h(ZHoQ2kbK$9N$Vc=xnSKRFGhx@+ednd@|AMyyU#GC1DcB3!N?5OQ;gXO8 zF0EfSVeob4ru)qoXydKjo(y?{yE>!9E+cx1o}6RvVHOMc8bH%QOK`AAKe6TIxpBBJ z65IT|Is#_1-lT_F@Zw)zT*^NPcY;H>ie92w76{4sOmPAq-tbeK)pzfLcu qxt6 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%0A$>;PS@z}j>p~C2n7{@6gqF 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 diff --git a/examples/dev/dev_run_case_from_files.py b/examples/dev/dev_run_case_from_files.py index 2243a4656..1a923e9a6 100644 --- a/examples/dev/dev_run_case_from_files.py +++ b/examples/dev/dev_run_case_from_files.py @@ -1,4 +1,4 @@ -import flow360 as fl +import flow360.component.v1 as fl from flow360.examples import OM6wing fl.Env.dev.active() diff --git a/examples/dev/dev_run_case_from_files_no_validation.py b/examples/dev/dev_run_case_from_files_no_validation.py index e5e0b2d7c..671206ce9 100644 --- a/examples/dev/dev_run_case_from_files_no_validation.py +++ b/examples/dev/dev_run_case_from_files_no_validation.py @@ -1,6 +1,6 @@ import os -import flow360 as fl +import flow360.component.v1 as fl from flow360.examples import OM6wing fl.UserConfig.disable_validation() diff --git a/examples/dev/dev_update_models.py b/examples/dev/dev_update_models.py index f0858b010..ffa85d8a0 100644 --- a/examples/dev/dev_update_models.py +++ b/examples/dev/dev_update_models.py @@ -1,6 +1,6 @@ import os -from flow360.component.flow360_params.flow360_params import Flow360ParamsLegacy +from flow360.component.v1.flow360_params import Flow360ParamsLegacy here = os.path.dirname(os.path.abspath(__file__)) path = os.path.join(here, "../../flow360/examples/rotatingSpheres/flow360.json") diff --git a/examples/dev/dev_use_unit_system.py b/examples/dev/dev_use_unit_system.py index a52da3cb6..a40df63c3 100644 --- a/examples/dev/dev_use_unit_system.py +++ b/examples/dev/dev_use_unit_system.py @@ -6,10 +6,10 @@ import pydantic.v1 as pd import unyt -import flow360 as fl -from flow360 import Geometry -from flow360 import units as u -from flow360.component.flow360_params.unit_system import ( +import flow360.component.v1 as fl +from flow360.component.v1 import Geometry +from flow360.component.v1 import units as u +from flow360.component.v1.unit_system import ( AngularVelocityType, AreaType, BaseSystemType, diff --git a/examples/dev/dev_validate_params.py b/examples/dev/dev_validate_params.py index 3c9954b1b..4f265133b 100644 --- a/examples/dev/dev_validate_params.py +++ b/examples/dev/dev_validate_params.py @@ -1,7 +1,7 @@ import os import re -from flow360.component.flow360_params.flow360_params import Flow360ParamsLegacy +from flow360.component.v1.flow360_params import Flow360ParamsLegacy rootdir = "../../tests/data/cases/" regex = re.compile(r"(case_.*\.json$)") diff --git a/examples/dev/dev_webservice_usage.py b/examples/dev/dev_webservice_usage.py index e039b2bc0..0ce745b20 100644 --- a/examples/dev/dev_webservice_usage.py +++ b/examples/dev/dev_webservice_usage.py @@ -2,7 +2,7 @@ import os import re -from flow360.component.flow360_params.services import get_default_fork +from flow360.component.v1.services import get_default_fork # Webservice examples diff --git a/examples/dev/list_cases_all_params.py b/examples/dev/list_cases_all_params.py index 1acbd25d9..62bf79927 100644 --- a/examples/dev/list_cases_all_params.py +++ b/examples/dev/list_cases_all_params.py @@ -1,4 +1,4 @@ -import flow360 as fl +import flow360.component.v1 as fl from flow360.exceptions import Flow360ValidationError for case in fl.MyCases(limit=10000): diff --git a/examples/display_mesh_info.py b/examples/display_mesh_info.py index b359d031e..f7cfb0b96 100644 --- a/examples/display_mesh_info.py +++ b/examples/display_mesh_info.py @@ -1,4 +1,4 @@ -import flow360 as fl +import flow360.component.v1 as fl meshes = fl.MyVolumeMeshes() mesh = meshes[0] diff --git a/examples/geometry_id_surface_volume_case_airplane_v1_from_csm.py b/examples/geometry_id_surface_volume_case_airplane_v1_from_csm.py index ac460c705..20e34d494 100644 --- a/examples/geometry_id_surface_volume_case_airplane_v1_from_csm.py +++ b/examples/geometry_id_surface_volume_case_airplane_v1_from_csm.py @@ -1,6 +1,6 @@ import os -import flow360 as fl +import flow360.component.v1 as fl fl.Env.preprod.active() diff --git a/examples/geometry_id_surface_volume_case_airplane_v1_from_egads.py b/examples/geometry_id_surface_volume_case_airplane_v1_from_egads.py index fcdfcbf83..81202e845 100644 --- a/examples/geometry_id_surface_volume_case_airplane_v1_from_egads.py +++ b/examples/geometry_id_surface_volume_case_airplane_v1_from_egads.py @@ -1,6 +1,6 @@ import os -import flow360 as fl +import flow360.component.v1 as fl fl.Env.preprod.active() diff --git a/examples/list_cases.py b/examples/list_cases.py index 182eff90c..ff7f9851c 100644 --- a/examples/list_cases.py +++ b/examples/list_cases.py @@ -1,4 +1,4 @@ -import flow360 as fl +import flow360.component.v1 as fl # get all cases: my_cases = fl.MyCases() diff --git a/examples/new_workbench_project_from_geometry.py b/examples/new_workbench_project_from_geometry.py index 5fb5261a8..1bcf50870 100644 --- a/examples/new_workbench_project_from_geometry.py +++ b/examples/new_workbench_project_from_geometry.py @@ -1,4 +1,4 @@ -import flow360 as fl +import flow360.component.v1 as fl from flow360.component.geometry import Geometry from flow360.examples import Airplane diff --git a/examples/new_workbench_project_from_volume_mesh.py b/examples/new_workbench_project_from_volume_mesh.py index 556e67cbd..a0f02a25e 100644 --- a/examples/new_workbench_project_from_volume_mesh.py +++ b/examples/new_workbench_project_from_volume_mesh.py @@ -1,7 +1,7 @@ import time -import flow360 as fl import flow360.component.simulation.units as u +import flow360.component.v1 as fl from flow360.component.simulation.cloud import run_case from flow360.component.simulation.models.surface_models import ( Freestream, diff --git a/examples/project_from_file_geometry.py b/examples/project_from_file_geometry.py index e3923550c..cfb5700c3 100644 --- a/examples/project_from_file_geometry.py +++ b/examples/project_from_file_geometry.py @@ -1,4 +1,4 @@ -import flow360 as fl +import flow360.component.v1 as fl from flow360.component.project import Project from flow360.component.simulation.meshing_param.params import ( MeshingDefaults, diff --git a/examples/project_from_file_geometry_multiple_runs.py b/examples/project_from_file_geometry_multiple_runs.py index 254136c8b..5dec5b926 100644 --- a/examples/project_from_file_geometry_multiple_runs.py +++ b/examples/project_from_file_geometry_multiple_runs.py @@ -1,4 +1,4 @@ -import flow360 as fl +import flow360.component.v1 as fl from flow360.component.project import Project from flow360.component.simulation.meshing_param.params import ( MeshingDefaults, diff --git a/examples/project_from_file_volume_mesh.py b/examples/project_from_file_volume_mesh.py index 86c4b5089..ef80aed77 100644 --- a/examples/project_from_file_volume_mesh.py +++ b/examples/project_from_file_volume_mesh.py @@ -1,7 +1,7 @@ from matplotlib.pyplot import show -import flow360 as fl import flow360.component.simulation.units as u +import flow360.component.v1 as fl from flow360.component.project import Project from flow360.component.simulation.models.surface_models import ( Freestream, diff --git a/examples/retrieve_results/actuator_disk.py b/examples/retrieve_results/actuator_disk.py index 387529d5b..5f3345a20 100644 --- a/examples/retrieve_results/actuator_disk.py +++ b/examples/retrieve_results/actuator_disk.py @@ -1,6 +1,6 @@ import os -import flow360 as fl +import flow360.component.v1 as fl import flow360.units as u from flow360.examples import ActuatorDisk diff --git a/examples/retrieve_results/alpha_sweep.py b/examples/retrieve_results/alpha_sweep.py index fb65e7ff5..f0c4bbf0a 100644 --- a/examples/retrieve_results/alpha_sweep.py +++ b/examples/retrieve_results/alpha_sweep.py @@ -3,7 +3,7 @@ from pylab import plot, show, xlabel, ylabel -import flow360 as fl +import flow360.component.v1 as fl from flow360.examples import OM6wing OM6wing.get_files() diff --git a/examples/retrieve_results/bet_disk.py b/examples/retrieve_results/bet_disk.py index 8d0518515..8c775e1b3 100644 --- a/examples/retrieve_results/bet_disk.py +++ b/examples/retrieve_results/bet_disk.py @@ -1,7 +1,7 @@ import os -import flow360 as fl -import flow360.component.flow360_params.units as u +import flow360.component.v1 as fl +import flow360.component.v1.units as u from flow360.examples import BETDisk BETDisk.get_files() diff --git a/examples/retrieve_results/convergence.py b/examples/retrieve_results/convergence.py index 31db6ab77..7806e53f6 100644 --- a/examples/retrieve_results/convergence.py +++ b/examples/retrieve_results/convergence.py @@ -1,4 +1,4 @@ -import flow360 as fl +import flow360.component.v1 as fl from flow360.examples import Convergence Convergence.get_files() diff --git a/examples/retrieve_results/forces.py b/examples/retrieve_results/forces.py index 6382237d6..20145dbc3 100644 --- a/examples/retrieve_results/forces.py +++ b/examples/retrieve_results/forces.py @@ -1,4 +1,4 @@ -import flow360 as fl +import flow360.component.v1 as fl from flow360.examples import OM6wing OM6wing.get_files() diff --git a/examples/retrieve_results/monitors.py b/examples/retrieve_results/monitors.py index ccadd3302..055e63f0f 100644 --- a/examples/retrieve_results/monitors.py +++ b/examples/retrieve_results/monitors.py @@ -1,4 +1,4 @@ -import flow360 as fl +import flow360.component.v1 as fl from flow360.examples import MonitorsAndSlices MonitorsAndSlices.get_files() diff --git a/examples/retrieve_results/user_defined_dynamics.py b/examples/retrieve_results/user_defined_dynamics.py index a1dab5ecc..c6bd62717 100644 --- a/examples/retrieve_results/user_defined_dynamics.py +++ b/examples/retrieve_results/user_defined_dynamics.py @@ -1,6 +1,6 @@ from pylab import show -import flow360 as fl +import flow360.component.v1 as fl from flow360.examples import OM6wingUserDefinedDynamics OM6wingUserDefinedDynamics.get_files() diff --git a/examples/retrieve_results/volumetric_and_surface.py b/examples/retrieve_results/volumetric_and_surface.py index b63ef34c1..bda7b7b49 100644 --- a/examples/retrieve_results/volumetric_and_surface.py +++ b/examples/retrieve_results/volumetric_and_surface.py @@ -2,7 +2,7 @@ import tarfile import tempfile -import flow360 as fl +import flow360.component.v1 as fl from flow360.examples import MonitorsAndSlices MonitorsAndSlices.get_files() diff --git a/examples/run_case_from_example_mesh.py b/examples/run_case_from_example_mesh.py index f1cb2a466..44104e850 100644 --- a/examples/run_case_from_example_mesh.py +++ b/examples/run_case_from_example_mesh.py @@ -1,4 +1,4 @@ -import flow360 as fl +import flow360.component.v1 as fl from flow360.examples import OM6wing vm = fl.VolumeMesh.copy_from_example("2ad77a88-1676-4f89-8652-13bd7e34f257") diff --git a/examples/run_case_from_files.py b/examples/run_case_from_files.py index 6b65ba53d..a27099e44 100644 --- a/examples/run_case_from_files.py +++ b/examples/run_case_from_files.py @@ -1,4 +1,4 @@ -import flow360 as fl +import flow360.component.v1 as fl from flow360.examples import OM6wing OM6wing.get_files() diff --git a/examples/run_case_from_inputs.py b/examples/run_case_from_inputs.py index 5420f9adb..794edd04e 100644 --- a/examples/run_case_from_inputs.py +++ b/examples/run_case_from_inputs.py @@ -1,4 +1,4 @@ -import flow360 as fl +import flow360.component.v1 as fl from flow360.examples import OM6wing OM6wing.get_files() diff --git a/examples/run_case_no_submit_warning.py b/examples/run_case_no_submit_warning.py index 822c164d2..102d04cf8 100644 --- a/examples/run_case_no_submit_warning.py +++ b/examples/run_case_no_submit_warning.py @@ -1,4 +1,4 @@ -import flow360 as fl +import flow360.component.v1 as fl from flow360.examples import OM6wing OM6wing.get_files() diff --git a/examples/run_case_unsteady_from_files.py b/examples/run_case_unsteady_from_files.py index 14d4b3a20..a041533d2 100644 --- a/examples/run_case_unsteady_from_files.py +++ b/examples/run_case_unsteady_from_files.py @@ -1,4 +1,4 @@ -import flow360 as fl +import flow360.component.v1 as fl from flow360.examples import Cylinder2D Cylinder2D.get_files() diff --git a/examples/run_case_with_fork.py b/examples/run_case_with_fork.py index e03847042..6527552e7 100644 --- a/examples/run_case_with_fork.py +++ b/examples/run_case_with_fork.py @@ -1,4 +1,4 @@ -import flow360 as fl +import flow360.component.v1 as fl from flow360.examples import OM6wing OM6wing.get_files() diff --git a/examples/run_case_with_retry.py b/examples/run_case_with_retry.py index e9f765fac..bbb92d8db 100644 --- a/examples/run_case_with_retry.py +++ b/examples/run_case_with_retry.py @@ -1,4 +1,4 @@ -import flow360 as fl +import flow360.component.v1 as fl from flow360.examples import OM6wing OM6wing.get_files() diff --git a/examples/show_storage.py b/examples/show_storage.py index 1a9414223..949304f85 100644 --- a/examples/show_storage.py +++ b/examples/show_storage.py @@ -1,4 +1,4 @@ -import flow360 as fl +import flow360.component.v1 as fl fl.Env.preprod.active() diff --git a/examples/submit_case_to_folder.py b/examples/submit_case_to_folder.py index 363349c98..8cfef0bb5 100644 --- a/examples/submit_case_to_folder.py +++ b/examples/submit_case_to_folder.py @@ -1,4 +1,4 @@ -import flow360 as fl +import flow360.component.v1 as fl from flow360.examples import OM6wing # create folder in ROOT level diff --git a/examples/surface_mesh_airplane_from_files.py b/examples/surface_mesh_airplane_from_files.py index 01e474c6e..7447a6851 100644 --- a/examples/surface_mesh_airplane_from_files.py +++ b/examples/surface_mesh_airplane_from_files.py @@ -1,4 +1,4 @@ -import flow360 as fl +import flow360.component.v1 as fl from flow360.examples import Airplane params = fl.SurfaceMeshingParams(Airplane.surface_json) diff --git a/examples/surface_mesh_airplane_from_inputs.py b/examples/surface_mesh_airplane_from_inputs.py index 3b71b52ed..6ae9d4b17 100644 --- a/examples/surface_mesh_airplane_from_inputs.py +++ b/examples/surface_mesh_airplane_from_inputs.py @@ -1,4 +1,4 @@ -import flow360 as fl +import flow360.component.v1 as fl from flow360.examples import Airplane params = fl.SurfaceMeshingParams( diff --git a/examples/surface_mesh_list.py b/examples/surface_mesh_list.py index e71e5bacd..19aae559e 100644 --- a/examples/surface_mesh_list.py +++ b/examples/surface_mesh_list.py @@ -1,4 +1,4 @@ -import flow360 as fl +import flow360.component.v1 as fl my_meshes = fl.MySurfaceMeshes() diff --git a/examples/volume_mesh_from_surface_mesh_files.py b/examples/volume_mesh_from_surface_mesh_files.py index 2b97b2e5e..92a35f460 100644 --- a/examples/volume_mesh_from_surface_mesh_files.py +++ b/examples/volume_mesh_from_surface_mesh_files.py @@ -1,4 +1,4 @@ -import flow360 as fl +import flow360.component.v1 as fl from flow360.examples import Airplane params = fl.SurfaceMeshingParams(Airplane.surface_json) diff --git a/examples/volume_mesh_from_surface_mesh_inputs.py b/examples/volume_mesh_from_surface_mesh_inputs.py index 398f8a3e1..5ebe9f0ca 100644 --- a/examples/volume_mesh_from_surface_mesh_inputs.py +++ b/examples/volume_mesh_from_surface_mesh_inputs.py @@ -1,4 +1,4 @@ -import flow360 as fl +import flow360.component.v1 as fl from flow360.examples import Airplane params = fl.SurfaceMeshingParams( diff --git a/flow360/__init__.py b/flow360/__init__.py index bb647ff0c..85a7d9138 100644 --- a/flow360/__init__.py +++ b/flow360/__init__.py @@ -1,276 +1,205 @@ """ -This module is flow360. +This module is flow360 for simulation based models """ -import os - -from numpy import pi - -from flow360.component.flow360_params.unit_system import ( - CGS_unit_system, - SI_unit_system, - UnitSystem, - flow360_unit_system, - imperial_unit_system, +from flow360.component.simulation import services +from flow360.component.simulation import units as u +from flow360.component.simulation.entity_info import GeometryEntityInfo +from flow360.component.simulation.framework.param_utils import AssetCache +from flow360.component.simulation.meshing_param.edge_params import ( + HeightBasedRefinement, + SurfaceEdgeRefinement, ) - -from . import global_exception_handler -from .accounts_utils import Accounts -from .cli import flow360 -from .cloud.s3_utils import ProgressCallbackInterface -from .component import meshing -from .component.case import Case -from .component.case import CaseList as MyCases -from .component.flow360_params import solvers, units -from .component.flow360_params.boundaries import ( - FreestreamBoundary, - HeatFluxWall, - IsothermalWall, - MassInflow, - MassOutflow, - NoSlipWall, - PressureOutflow, - RiemannInvariant, - RotationallyPeriodic, - SlidingInterfaceBoundary, +from flow360.component.simulation.meshing_param.face_params import SurfaceRefinement +from flow360.component.simulation.meshing_param.params import ( + MeshingDefaults, + MeshingParams, +) +from flow360.component.simulation.meshing_param.volume_params import ( + AutomatedFarfield, + AxisymmetricRefinement, + RotationCylinder, + UniformRefinement, +) +from flow360.component.simulation.models.material import Air, SolidMaterial, Sutherland +from flow360.component.simulation.models.solver_numerics import ( + HeatEquationSolver, + KOmegaSST, + KOmegaSSTModelConstants, + LinearSolver, + NavierStokesSolver, + NoneSolver, + SpalartAllmaras, + SpalartAllmarasModelConstants, + TransitionModelSolver, + TransitionModelSolverType, + TurbulenceModelSolverType, +) +from flow360.component.simulation.models.surface_models import ( + Freestream, + HeatFlux, + Inflow, + Outflow, + Periodic, + Pressure, + Rotational, SlipWall, - SolidAdiabaticWall, - SolidIsothermalWall, - SubsonicInflow, - SubsonicOutflowMach, - SubsonicOutflowPressure, - SupersonicInflow, SymmetryPlane, - TranslationallyPeriodic, - VelocityInflow, - WallFunction, + Temperature, + TotalPressure, + Translational, + Wall, ) -from .component.flow360_params.flow360_output import ( - IsoSurfaceOutput, - IsoSurfaces, - MonitorOutput, - Monitors, - ProbeMonitor, - Slice, - SliceOutput, - Slices, - SurfaceIntegralMonitor, - SurfaceOutput, - Surfaces, +from flow360.component.simulation.models.turbulence_quantities import ( + TurbulenceQuantities, ) -from .component.flow360_params.flow360_params import ( +from flow360.component.simulation.models.volume_models import ( ActuatorDisk, - AeroacousticOutput, - AirDensityTemperature, - AirPressureTemperature, + AngleExpression, + AngularVelocity, BETDisk, BETDiskChord, BETDiskSectionalPolar, BETDiskTwist, - Boundaries, - Flow360MeshParams, - Flow360Params, + Fluid, ForcePerArea, - FreestreamFromMach, - FreestreamFromMachReynolds, - FreestreamFromVelocity, - Geometry, - HeatEquationSolver, - MeshBoundary, - PorousMediumBox, - SlidingInterface, - TransitionModelSolver, - UnvalidatedFlow360Params, - UserDefinedDynamic, - VolumeOutput, - VolumeZones, - ZeroFreestream, - ZeroFreestreamFromVelocity, - air, + FromUserDefinedDynamics, + HeatEquationInitialCondition, + NavierStokesInitialCondition, + PorousMedium, + Rotation, + Solid, ) -from .component.flow360_params.initial_condition import ( - ExpressionInitialCondition, - ModifiedRestartSolution, +from flow360.component.simulation.operating_condition.operating_condition import ( + AerospaceCondition, + GenericReferenceCondition, + ThermalState, ) -from .component.flow360_params.solvers import ( - IncompressibleNavierStokesSolver, - KOmegaSST, - KOmegaSSTModelConstants, - LinearSolver, - NavierStokesSolver, - NoneSolver, - PressureCorrectionSolver, - SpalartAllmaras, - SpalartAllmarasModelConstants, +from flow360.component.simulation.outputs.output_entities import ( + Point, + PointArray, + Slice, +) +from flow360.component.simulation.outputs.outputs import ( + AeroAcousticOutput, + IsosurfaceOutput, + ProbeOutput, + SliceOutput, + SurfaceIntegralOutput, + SurfaceOutput, + SurfaceProbeOutput, + TimeAverageSurfaceOutput, + TimeAverageVolumeOutput, + VolumeOutput, +) +from flow360.component.simulation.primitives import ( + Box, + Cylinder, + Edge, + GenericVolume, + ReferenceGeometry, + Surface, ) -from .component.flow360_params.time_stepping import ( +from flow360.component.simulation.simulation_params import SimulationParams +from flow360.component.simulation.time_stepping.time_stepping import ( AdaptiveCFL, RampCFL, - SteadyTimeStepping, - TimeStepping, - UnsteadyTimeStepping, + Steady, + Unsteady, ) -from .component.flow360_params.turbulence_quantities import TurbulenceQuantities -from .component.flow360_params.volume_zones import ( - FluidDynamicsVolumeZone, - HeatTransferVolumeZone, - InitialConditionHeatTransfer, - PorousMediumVolumeZone, - ReferenceFrame, - ReferenceFrameDynamic, - ReferenceFrameExpression, - ReferenceFrameOmegaDegrees, - ReferenceFrameOmegaRadians, +from flow360.component.simulation.unit_system import ( + SI_unit_system, + imperial_unit_system, ) -from .component.folder import Folder -from .component.meshing.params import ( - Aniso, - BoxRefinement, - CylinderRefinement, - Edges, - Face, - Faces, - Farfield, - ProjectAniso, - RotorDisk, - SurfaceMeshingParams, - UseAdjacent, - Volume, - VolumeMeshingParams, +from flow360.component.simulation.user_defined_dynamics.user_defined_dynamics import ( + UserDefinedDynamic, ) -from .component.surface_mesh import SurfaceMesh -from .component.surface_mesh import SurfaceMeshList as MySurfaceMeshes -from .component.volume_mesh import VolumeMesh -from .component.volume_mesh import VolumeMeshList as MyVolumeMeshes -from .environment import Env -from .flags import Flags -from .user_config import UserConfig -from .version import __solver_version__, __version__ __all__ = [ - "Accounts", - "ActuatorDisk", + "u", + "SimulationParams", + "SI_unit_system", + "imperial_unit_system", + "services", + "MeshingParams", + "MeshingDefaults", + "SurfaceRefinement", + "AutomatedFarfield", + "AxisymmetricRefinement", + "RotationCylinder", + "UniformRefinement", + "SurfaceEdgeRefinement", + "HeightBasedRefinement", + "Surface", + "Edge", + "ReferenceGeometry", + "Cylinder", + "AssetCache", + "GeometryEntityInfo", + "AerospaceCondition", + "ThermalState", + "Steady", + "Unsteady", + "RampCFL", "AdaptiveCFL", - "AeroacousticOutput", - "AirDensityTemperature", - "AirPressureTemperature", - "Aniso", + "Wall", + "Freestream", + "SlipWall", + "Outflow", + "Inflow", + "Periodic", + "SymmetryPlane", + "Fluid", + "Solid", + "ActuatorDisk", + "AngularVelocity", "BETDisk", "BETDiskChord", "BETDiskSectionalPolar", "BETDiskTwist", - "Boundaries", - "BoxRefinement", - "CGS_unit_system", - "Case", - "CylinderRefinement", - "Edges", - "Env", - "ExpressionInitialCondition", - "Face", - "Faces", - "Farfield", - "Flags", - "Flow360MeshParams", - "Flow360Params", - "FluidDynamicsVolumeZone", - "Folder", - "ForcePerArea", - "FreestreamBoundary", - "FreestreamFromMach", - "FreestreamFromMachReynolds", - "FreestreamFromVelocity", - "Geometry", + "Rotation", + "PorousMedium", + "SurfaceOutput", + "TimeAverageSurfaceOutput", + "VolumeOutput", + "TimeAverageVolumeOutput", + "SliceOutput", + "IsosurfaceOutput", + "SurfaceIntegralOutput", + "ProbeOutput", + "SurfaceProbeOutput", + "AeroAcousticOutput", "HeatEquationSolver", - "HeatFluxWall", - "HeatTransferVolumeZone", - "IncompressibleNavierStokesSolver", - "InitialConditionHeatTransfer", - "IsoSurfaceOutput", - "IsoSurfaces", - "IsothermalWall", - "KOmegaSST", - "KOmegaSSTModelConstants", - "LinearSolver", - "MassInflow", - "MassOutflow", - "MeshBoundary", - "ModifiedRestartSolution", - "MonitorOutput", - "Monitors", - "MyCases", - "MySurfaceMeshes", - "MyVolumeMeshes", "NavierStokesSolver", - "NoSlipWall", "NoneSolver", - "PorousMediumBox", - "PorousMediumVolumeZone", - "PressureCorrectionSolver", - "PressureOutflow", - "ProbeMonitor", - "ProgressCallbackInterface", - "ProjectAniso", - "RampCFL", - "ReferenceFrame", - "ReferenceFrameDynamic", - "ReferenceFrameExpression", - "ReferenceFrameOmegaDegrees", - "ReferenceFrameOmegaRadians", - "RiemannInvariant", - "RotationallyPeriodic", - "RotorDisk", - "SI_unit_system", - "Slice", - "SliceOutput", - "Slices", - "SlidingInterface", - "SlidingInterfaceBoundary", - "SlipWall", - "SolidAdiabaticWall", - "SolidIsothermalWall", "SpalartAllmaras", + "KOmegaSST", "SpalartAllmarasModelConstants", - "SteadyTimeStepping", - "SubsonicInflow", - "SubsonicOutflowMach", - "SubsonicOutflowPressure", - "SupersonicInflow", - "SurfaceIntegralMonitor", - "SurfaceMesh", - "SurfaceMeshingParams", - "SurfaceOutput", - "Surfaces", - "SymmetryPlane", - "TimeStepping", - "TransitionModelSolver", - "TranslationallyPeriodic", + "KOmegaSSTModelConstants", + "TransitionModelSolverType", + "TurbulenceModelSolverType", + "LinearSolver", + "ForcePerArea", + "Air", + "Sutherland", + "SolidMaterial", + "Slice", "TurbulenceQuantities", - "UnitSystem", - "UnsteadyTimeStepping", - "UnvalidatedFlow360Params", - "UseAdjacent", - "UserConfig", "UserDefinedDynamic", - "VelocityInflow", - "Volume", - "VolumeMesh", - "VolumeMeshingParams", - "VolumeOutput", - "VolumeZones", - "WallFunction", - "ZeroFreestream", - "ZeroFreestreamFromVelocity", - "__version__", - "__solver_version__", - "air", - "flow360", - "flow360_unit_system", - "global_exception_handler", - "imperial_unit_system", - "meshing", - "os", - "pi", - "solvers", - "units", + "Translational", + "NavierStokesInitialCondition", + "FromUserDefinedDynamics", + "HeatEquationInitialCondition", + "GenericVolume", + "Temperature", + "HeatFlux", + "Point", + "PointArray", + "AngleExpression", + "Box", + "GenericReferenceCondition", + "TransitionModelSolver", + "Pressure", + "TotalPressure", + "Rotational", ] diff --git a/flow360/component/compress_upload.py b/flow360/cloud/compress_upload.py similarity index 98% rename from flow360/component/compress_upload.py rename to flow360/cloud/compress_upload.py index 64548f240..956e96631 100644 --- a/flow360/component/compress_upload.py +++ b/flow360/cloud/compress_upload.py @@ -8,7 +8,7 @@ from flow360.component.resource_base import Flow360Resource -from ..cloud.utils import _get_progress, _S3Action +from .utils import _get_progress, _S3Action # pylint: disable=too-many-arguments, too-many-locals diff --git a/flow360/cloud/requests.py b/flow360/cloud/flow360_requests.py similarity index 69% rename from flow360/cloud/requests.py rename to flow360/cloud/flow360_requests.py index 7402957c3..0d289b14e 100644 --- a/flow360/cloud/requests.py +++ b/flow360/cloud/flow360_requests.py @@ -6,10 +6,6 @@ import pydantic.v1 as pd from typing_extensions import Literal -from flow360.flags import Flags - -from ..component.flow360_params.flow360_params import Flow360MeshParams - LengthUnitType = Literal["m", "mm", "cm", "inch", "ft"] @@ -34,45 +30,6 @@ class Config: # pylint: disable=too-few-public-methods allow_population_by_field_name = True -class NewSurfaceMeshRequest(Flow360Requests): - """request for new surface mesh""" - - name: str = pd.Field() - stem: str = pd.Field() - tags: Optional[List[str]] = pd.Field() - geometry_id: Optional[str] = pd.Field(alias="geometryId") - config: Optional[str] = pd.Field() - mesh_format: Optional[Literal["aflr3", "cgns", "stl"]] = pd.Field(alias="meshFormat") - endianness: Optional[Literal["little", "big"]] = pd.Field(alias="meshEndianness") - compression: Optional[Literal["gz", "bz2", "zst"]] = pd.Field(alias="meshCompression") - solver_version: Optional[str] = pd.Field(alias="solverVersion") - if Flags.beta_features(): - version: Optional[Literal["v1", "v2"]] = pd.Field(default="v1") - - -class NewVolumeMeshRequest(Flow360Requests): - """request for new volume mesh""" - - name: str = pd.Field(alias="meshName") - file_name: str = pd.Field(alias="fileName") - tags: Optional[List[str]] = pd.Field(alias="meshTags") - format: Literal["aflr3", "cgns"] = pd.Field(alias="meshFormat") - endianness: Optional[Literal["little", "big"]] = pd.Field(alias="meshEndianness") - compression: Optional[Literal["gz", "bz2", "zst"]] = pd.Field(alias="meshCompression") - mesh_params: Optional[Flow360MeshParams] = pd.Field(alias="meshParams") - solver_version: Optional[str] = pd.Field(alias="solverVersion") - if Flags.beta_features(): - version: Optional[Literal["v1", "v2"]] = pd.Field(alias="version", default="v1") - - # pylint: disable=no-self-argument - @pd.validator("mesh_params") - def set_mesh_params(cls, value: Union[Flow360MeshParams, None]): - """validate mesh params""" - if value: - return value.flow360_json() - return value - - class CopyExampleVolumeMeshRequest(Flow360Requests): """request for new volume mesh""" diff --git a/flow360/component/case.py b/flow360/component/case.py index 47913ec57..279e50cbd 100644 --- a/flow360/component/case.py +++ b/flow360/component/case.py @@ -11,11 +11,10 @@ import pydantic.v1 as pd from .. import error_messages -from ..cloud.requests import MoveCaseItem, MoveToFolderRequest +from ..cloud.flow360_requests import MoveCaseItem, MoveToFolderRequest from ..cloud.rest_api import RestApi from ..exceptions import Flow360RuntimeError, Flow360ValidationError, Flow360ValueError from ..log import log -from .flow360_params.flow360_params import Flow360Params, UnvalidatedFlow360Params from .folder import Folder from .interfaces import CaseInterface, FolderInterface, VolumeMeshInterface from .resource_base import ( @@ -48,6 +47,7 @@ UserDefinedDynamicsResultModel, ) from .utils import is_valid_uuid, shared_account_confirm_proceed, validate_type +from .v1.flow360_params import Flow360Params, UnvalidatedFlow360Params from .validator import Validator diff --git a/flow360/component/folder.py b/flow360/component/folder.py index 80619bfcc..1f747a6e7 100644 --- a/flow360/component/folder.py +++ b/flow360/component/folder.py @@ -8,7 +8,11 @@ import pydantic.v1 as pd -from ..cloud.requests import MoveFolderItem, MoveToFolderRequest, NewFolderRequest +from ..cloud.flow360_requests import ( + MoveFolderItem, + MoveToFolderRequest, + NewFolderRequest, +) from ..cloud.rest_api import RestApi from ..exceptions import Flow360ValueError from ..log import log diff --git a/flow360/component/geometry.py b/flow360/component/geometry.py index 37c2760d1..e79ddc41f 100644 --- a/flow360/component/geometry.py +++ b/flow360/component/geometry.py @@ -11,8 +11,12 @@ import pydantic as pd +from flow360.cloud.flow360_requests import ( + GeometryFileMeta, + LengthUnitType, + NewGeometryRequest, +) from flow360.cloud.heartbeat import post_upload_heartbeat -from flow360.cloud.requests import GeometryFileMeta, LengthUnitType, NewGeometryRequest from flow360.cloud.rest_api import RestApi from flow360.component.interfaces import GeometryInterface from flow360.component.resource_base import ( diff --git a/flow360/component/project.py b/flow360/component/project.py index 1f4e1a202..908d59609 100644 --- a/flow360/component/project.py +++ b/flow360/component/project.py @@ -9,9 +9,9 @@ import pydantic as pd -from flow360 import Case, SurfaceMesh, __solver_version__ -from flow360.cloud.requests import LengthUnitType +from flow360.cloud.flow360_requests import LengthUnitType from flow360.cloud.rest_api import RestApi +from flow360.component.case import Case from flow360.component.geometry import Geometry from flow360.component.interfaces import ( GeometryInterface, @@ -26,6 +26,7 @@ from flow360.component.simulation.utils import model_attribute_unlock from flow360.component.simulation.web.asset_base import AssetBase from flow360.component.simulation.web.draft import Draft +from flow360.component.surface_mesh import SurfaceMesh from flow360.component.utils import ( SUPPORTED_GEOMETRY_FILE_PATTERNS, MeshNameParser, @@ -34,6 +35,7 @@ ) from flow360.component.volume_mesh import VolumeMeshV2 from flow360.exceptions import Flow360FileError, Flow360ValueError, Flow360WebError +from flow360.version import __solver_version__ AssetOrResource = Union[type[AssetBase], type[Flow360Resource]] RootAsset = Union[Geometry, VolumeMeshV2] diff --git a/flow360/component/results/case_results.py b/flow360/component/results/case_results.py index 84494a438..0efe368c7 100644 --- a/flow360/component/results/case_results.py +++ b/flow360/component/results/case_results.py @@ -13,7 +13,7 @@ import pandas import pydantic.v1 as pd -from flow360.component.flow360_params.unit_system import ( +from flow360.component.v1.unit_system import ( Flow360UnitSystem, ForceType, MomentType, @@ -27,8 +27,8 @@ ) from ...exceptions import Flow360ValueError from ...log import log -from ..flow360_params.conversions import unit_converter -from ..flow360_params.flow360_params import Flow360Params +from ..v1.conversions import unit_converter +from ..v1.flow360_params import Flow360Params # pylint: disable=consider-using-with TMP_DIR = tempfile.TemporaryDirectory() diff --git a/flow360/component/simulation/outputs/output_entities.py b/flow360/component/simulation/outputs/output_entities.py index 77befab19..7056fe1d3 100644 --- a/flow360/component/simulation/outputs/output_entities.py +++ b/flow360/component/simulation/outputs/output_entities.py @@ -5,12 +5,25 @@ import pydantic as pd -from flow360.component.flow360_params.flow360_fields import IsoSurfaceFieldNames from flow360.component.simulation.framework.base_model import Flow360BaseModel from flow360.component.simulation.framework.entity_base import EntityBase from flow360.component.simulation.unit_system import LengthType from flow360.component.types import Axis +# pylint: disable=duplicate-code +# inlined from v1 module to avoid circular import +IsoSurfaceFieldNames = Literal[ + "p", + "rho", + "Mach", + "qcriterion", + "s", + "T", + "Cp", + "mut", + "nuHat", +] + class _OutputItemBase(Flow360BaseModel): name: str = pd.Field() diff --git a/flow360/component/simulation/outputs/output_fields.py b/flow360/component/simulation/outputs/output_fields.py new file mode 100644 index 000000000..78d356f61 --- /dev/null +++ b/flow360/component/simulation/outputs/output_fields.py @@ -0,0 +1,153 @@ +""" +Output field definitions +""" + +# pylint: disable=duplicate-code +from typing import List, Literal, get_args, get_origin + +# Coefficient of pressure +# Gradient of primitive solution +# k and omega +# Mach number +# Turbulent viscosity +# Turbulent viscosity and freestream dynamic viscosity ratio +# Spalart-Almaras variable +# rho, u, v, w, p (density, 3 velocities and pressure) +# Q criterion +# N-S residual +# Transition residual +# Turbulence residual +# Entropy +# N-S solution +# Transition solution +# Turbulence solution +# Temperature +# Vorticity +# Wall distance +# NumericalDissipationFactor sensor +# Heat equation residual +# Velocity with respect to non-inertial frame +# Low-Mach preconditioner factor +CommonFieldNames = Literal[ + "Cp", + "gradW", + "kOmega", + "Mach", + "mut", + "mutRatio", + "nuHat", + "primitiveVars", + "qcriterion", + "residualNavierStokes", + "residualTransition", + "residualTurbulence", + "s", + "solutionNavierStokes", + "solutionTransition", + "solutionTurbulence", + "T", + "vorticity", + "wallDistance", + "numericalDissipationFactor", + "residualHeatSolver", + "VelocityRelative", + "lowMachPreconditionerSensor", +] + +# Skin friction coefficient vector +# Magnitude of CfVec +# Non-dimensional heat flux +# Wall normals +# Spalart-Allmaras variable +# Non-dimensional wall distance +# Wall function metrics +# Surface heat transfer coefficient (static temperature as reference) +# Surface heat transfer coefficient (total temperature as reference) +SurfaceFieldNames = Literal[ + CommonFieldNames, + "CfVec", + "Cf", + "heatFlux", + "nodeNormals", + "nodeForcesPerUnitArea", + "yPlus", + "wallFunctionMetric", + "heatTransferCoefficientStaticTemperature", + "heatTransferCoefficientTotalTemperature", +] + +# BET Metrics +# BET Metrics per Disk +# Coefficient of total pressure +# Linear residual of Navier-Stokes solver +# Linear residual of turbulence solver +# Linear residual of transition solver +# DDES output for Spalart-Allmaras solver +# DDES output for kOmegaSST solver +# Local CFL number +VolumeFieldNames = Literal[ + CommonFieldNames, + "betMetrics", + "betMetricsPerDisk", + "Cpt", + "linearResidualNavierStokes", + "linearResidualTurbulence", + "linearResidualTransition", + "SpalartAllmaras_DDES", + "kOmegaSST_DDES", + "localCFL", +] + +SliceFieldNames = VolumeFieldNames + +# Pressure +# Density +# Mach number +# Q criterion +# Entropy +# Temperature +# Coefficient of pressure +# Turbulent viscosity +# Spalart-Almaras variable +IsoSurfaceFieldNames = Literal[ + "p", + "rho", + "Mach", + "qcriterion", + "s", + "T", + "Cp", + "mut", + "nuHat", +] + +AllFieldNames = Literal[CommonFieldNames, SurfaceFieldNames, VolumeFieldNames, IsoSurfaceFieldNames] + + +def _get_field_values(field_type, names): + for arg in get_args(field_type): + if get_origin(arg) is Literal: + _get_field_values(arg, names) + elif isinstance(arg, str): + names += [arg] + + +def get_field_values(field_type) -> List[str]: + """Retrieve field names from a nested literal type as list of strings""" + values = [] + _get_field_values(field_type, values) + return values + + +def _distribute_shared_output_fields(solver_values: dict, item_names: str): + if "output_fields" not in solver_values or solver_values["output_fields"] is None: + return + shared_fields = solver_values.pop("output_fields") + if solver_values[item_names] is not None: + for name in solver_values[item_names].names(): + item = solver_values[item_names][name] + for field in shared_fields: + if item.output_fields is None: + item.output_fields = [] + if field not in item.output_fields: + item.output_fields.append(field) diff --git a/flow360/component/simulation/outputs/outputs.py b/flow360/component/simulation/outputs/outputs.py index 9c4d70a4b..0b7508060 100644 --- a/flow360/component/simulation/outputs/outputs.py +++ b/flow360/component/simulation/outputs/outputs.py @@ -9,12 +9,6 @@ import pydantic as pd -from flow360.component.flow360_params.flow360_fields import ( - CommonFieldNames, - SliceFieldNames, - SurfaceFieldNames, - VolumeFieldNames, -) from flow360.component.simulation.framework.base_model import Flow360BaseModel from flow360.component.simulation.framework.entity_base import EntityList from flow360.component.simulation.framework.unique_list import UniqueItemList @@ -24,6 +18,12 @@ PointArray, Slice, ) +from flow360.component.simulation.outputs.output_fields import ( + CommonFieldNames, + SliceFieldNames, + SurfaceFieldNames, + VolumeFieldNames, +) from flow360.component.simulation.primitives import GhostSurface, Surface from flow360.component.simulation.unit_system import LengthType from flow360.component.simulation.validation.validation_output import ( diff --git a/flow360/component/simulation/translator/utils.py b/flow360/component/simulation/translator/utils.py index 2aaf6b9da..320d92f59 100644 --- a/flow360/component/simulation/translator/utils.py +++ b/flow360/component/simulation/translator/utils.py @@ -133,7 +133,7 @@ def remove_units_in_dict(input_dict): if isinstance(value, dict) and value.keys() == unit_keys: if value["units"].startswith("flow360_") is False: raise ValueError( - f"[Internal Error] Unit {new_dict['units']} is not non-dimensionalized." + f"[Internal Error] Unit {value['units']} is not non-dimensionalized." ) new_dict[key] = value["value"] else: diff --git a/flow360/component/simulation/web/asset_base.py b/flow360/component/simulation/web/asset_base.py index bfaea579f..427a64eb9 100644 --- a/flow360/component/simulation/web/asset_base.py +++ b/flow360/component/simulation/web/asset_base.py @@ -7,7 +7,7 @@ from abc import ABCMeta from typing import List, Union -from flow360.cloud.requests import LengthUnitType +from flow360.cloud.flow360_requests import LengthUnitType from flow360.cloud.rest_api import RestApi from flow360.component.interfaces import BaseInterface, ProjectInterface from flow360.component.resource_base import ( diff --git a/flow360/component/surface_mesh.py b/flow360/component/surface_mesh.py index fa6339757..41695d8ee 100644 --- a/flow360/component/surface_mesh.py +++ b/flow360/component/surface_mesh.py @@ -10,15 +10,17 @@ import pydantic.v1 as pd +from flow360.component.v1.cloud.flow360_requests import NewSurfaceMeshRequest +from flow360.component.v1.meshing.params import ( + SurfaceMeshingParams, + VolumeMeshingParams, +) from flow360.flags import Flags -from ..cloud.requests import NewSurfaceMeshRequest from ..cloud.rest_api import RestApi from ..exceptions import Flow360FileError, Flow360ValueError from ..log import log -from .flow360_params.params_base import params_generic_validator from .interfaces import SurfaceMeshInterface -from .meshing.params import SurfaceMeshingParams, VolumeMeshingParams from .resource_base import ( AssetMetaBaseModel, Flow360Resource, @@ -35,6 +37,7 @@ validate_type, zstd_compress, ) +from .v1.params_base import params_generic_validator from .validator import Validator from .volume_mesh import VolumeMeshDraft diff --git a/flow360/component/v1/__init__.py b/flow360/component/v1/__init__.py new file mode 100644 index 000000000..1f67643c4 --- /dev/null +++ b/flow360/component/v1/__init__.py @@ -0,0 +1,272 @@ +""" +This module is flow360. +""" + +import os + +from numpy import pi + +from flow360.component.v1.unit_system import ( + CGS_unit_system, + SI_unit_system, + UnitSystem, + flow360_unit_system, + imperial_unit_system, +) + +from ... import global_exception_handler +from ...accounts_utils import Accounts +from ...cli import flow360 +from ...cloud.s3_utils import ProgressCallbackInterface +from ...environment import Env +from ...flags import Flags +from ...user_config import UserConfig +from ...version import __solver_version__, __version__ +from ..case import Case +from ..case import CaseList as MyCases +from ..folder import Folder +from ..surface_mesh import SurfaceMesh +from ..surface_mesh import SurfaceMeshList as MySurfaceMeshes +from ..volume_mesh import VolumeMesh +from ..volume_mesh import VolumeMeshList as MyVolumeMeshes +from . import meshing, solvers, units +from .boundaries import ( + FreestreamBoundary, + HeatFluxWall, + IsothermalWall, + MassInflow, + MassOutflow, + NoSlipWall, + PressureOutflow, + RiemannInvariant, + RotationallyPeriodic, + SlidingInterfaceBoundary, + SlipWall, + SolidAdiabaticWall, + SolidIsothermalWall, + SubsonicInflow, + SubsonicOutflowMach, + SubsonicOutflowPressure, + SupersonicInflow, + SymmetryPlane, + TranslationallyPeriodic, + VelocityInflow, + WallFunction, +) +from .flow360_output import ( + IsoSurfaceOutput, + IsoSurfaces, + MonitorOutput, + Monitors, + ProbeMonitor, + Slice, + SliceOutput, + Slices, + SurfaceIntegralMonitor, + SurfaceOutput, + Surfaces, +) +from .flow360_params import ( + ActuatorDisk, + AeroacousticOutput, + AirDensityTemperature, + AirPressureTemperature, + BETDisk, + BETDiskChord, + BETDiskSectionalPolar, + BETDiskTwist, + Boundaries, + Flow360MeshParams, + Flow360Params, + ForcePerArea, + FreestreamFromMach, + FreestreamFromMachReynolds, + FreestreamFromVelocity, + Geometry, + HeatEquationSolver, + MeshBoundary, + PorousMediumBox, + SlidingInterface, + TransitionModelSolver, + UnvalidatedFlow360Params, + UserDefinedDynamic, + VolumeOutput, + VolumeZones, + ZeroFreestream, + ZeroFreestreamFromVelocity, + air, +) +from .initial_condition import ExpressionInitialCondition, ModifiedRestartSolution +from .meshing.params import ( + Aniso, + BoxRefinement, + CylinderRefinement, + Edges, + Face, + Faces, + Farfield, + ProjectAniso, + RotorDisk, + SurfaceMeshingParams, + UseAdjacent, + Volume, + VolumeMeshingParams, +) +from .solvers import ( + IncompressibleNavierStokesSolver, + KOmegaSST, + KOmegaSSTModelConstants, + LinearSolver, + NavierStokesSolver, + NoneSolver, + PressureCorrectionSolver, + SpalartAllmaras, + SpalartAllmarasModelConstants, +) +from .time_stepping import ( + AdaptiveCFL, + RampCFL, + SteadyTimeStepping, + TimeStepping, + UnsteadyTimeStepping, +) +from .turbulence_quantities import TurbulenceQuantities +from .volume_zones import ( + FluidDynamicsVolumeZone, + HeatTransferVolumeZone, + InitialConditionHeatTransfer, + PorousMediumVolumeZone, + ReferenceFrame, + ReferenceFrameDynamic, + ReferenceFrameExpression, + ReferenceFrameOmegaDegrees, + ReferenceFrameOmegaRadians, +) + +__all__ = [ + "Accounts", + "ActuatorDisk", + "AdaptiveCFL", + "AeroacousticOutput", + "AirDensityTemperature", + "AirPressureTemperature", + "Aniso", + "BETDisk", + "BETDiskChord", + "BETDiskSectionalPolar", + "BETDiskTwist", + "Boundaries", + "BoxRefinement", + "CGS_unit_system", + "Case", + "CylinderRefinement", + "Edges", + "Env", + "ExpressionInitialCondition", + "Face", + "Faces", + "Farfield", + "Flags", + "Flow360MeshParams", + "Flow360Params", + "FluidDynamicsVolumeZone", + "Folder", + "ForcePerArea", + "FreestreamBoundary", + "FreestreamFromMach", + "FreestreamFromMachReynolds", + "FreestreamFromVelocity", + "Geometry", + "HeatEquationSolver", + "HeatFluxWall", + "HeatTransferVolumeZone", + "IncompressibleNavierStokesSolver", + "InitialConditionHeatTransfer", + "IsoSurfaceOutput", + "IsoSurfaces", + "IsothermalWall", + "KOmegaSST", + "KOmegaSSTModelConstants", + "LinearSolver", + "MassInflow", + "MassOutflow", + "MeshBoundary", + "ModifiedRestartSolution", + "MonitorOutput", + "Monitors", + "MyCases", + "MySurfaceMeshes", + "MyVolumeMeshes", + "NavierStokesSolver", + "NoSlipWall", + "NoneSolver", + "PorousMediumBox", + "PorousMediumVolumeZone", + "PressureCorrectionSolver", + "PressureOutflow", + "ProbeMonitor", + "ProgressCallbackInterface", + "ProjectAniso", + "RampCFL", + "ReferenceFrame", + "ReferenceFrameDynamic", + "ReferenceFrameExpression", + "ReferenceFrameOmegaDegrees", + "ReferenceFrameOmegaRadians", + "RiemannInvariant", + "RotationallyPeriodic", + "RotorDisk", + "SI_unit_system", + "Slice", + "SliceOutput", + "Slices", + "SlidingInterface", + "SlidingInterfaceBoundary", + "SlipWall", + "SolidAdiabaticWall", + "SolidIsothermalWall", + "SpalartAllmaras", + "SpalartAllmarasModelConstants", + "SteadyTimeStepping", + "SubsonicInflow", + "SubsonicOutflowMach", + "SubsonicOutflowPressure", + "SupersonicInflow", + "SurfaceIntegralMonitor", + "SurfaceMesh", + "SurfaceMeshingParams", + "SurfaceOutput", + "Surfaces", + "SymmetryPlane", + "TimeStepping", + "TransitionModelSolver", + "TranslationallyPeriodic", + "TurbulenceQuantities", + "UnitSystem", + "UnsteadyTimeStepping", + "UnvalidatedFlow360Params", + "UseAdjacent", + "UserConfig", + "UserDefinedDynamic", + "VelocityInflow", + "Volume", + "VolumeMesh", + "VolumeMeshingParams", + "VolumeOutput", + "VolumeZones", + "WallFunction", + "ZeroFreestream", + "ZeroFreestreamFromVelocity", + "__version__", + "__solver_version__", + "air", + "flow360", + "flow360_unit_system", + "global_exception_handler", + "imperial_unit_system", + "meshing", + "os", + "pi", + "solvers", + "units", +] diff --git a/flow360/component/flow360_params/boundaries.py b/flow360/component/v1/boundaries.py similarity index 99% rename from flow360/component/flow360_params/boundaries.py rename to flow360/component/v1/boundaries.py index afcfb50a0..043e9dcf4 100644 --- a/flow360/component/flow360_params/boundaries.py +++ b/flow360/component/v1/boundaries.py @@ -10,7 +10,7 @@ import pydantic.v1 as pd from pydantic.v1 import StrictStr -from flow360.component.flow360_params.unit_system import PressureType, VelocityType +from flow360.component.v1.unit_system import PressureType, VelocityType from ..types import Axis, Vector from ..utils import process_expressions diff --git a/flow360/component/v1/cloud/flow360_requests.py b/flow360/component/v1/cloud/flow360_requests.py new file mode 100644 index 000000000..d552781e3 --- /dev/null +++ b/flow360/component/v1/cloud/flow360_requests.py @@ -0,0 +1,49 @@ +"""V1 requests for cloud component""" + +from typing import List, Optional, Union + +import pydantic.v1 as pd +from typing_extensions import Literal + +from flow360.cloud.flow360_requests import Flow360Requests +from flow360.component.v1.flow360_params import Flow360MeshParams +from flow360.flags import Flags + + +class NewVolumeMeshRequest(Flow360Requests): + """request for new volume mesh""" + + name: str = pd.Field(alias="meshName") + file_name: str = pd.Field(alias="fileName") + tags: Optional[List[str]] = pd.Field(alias="meshTags") + format: Literal["aflr3", "cgns"] = pd.Field(alias="meshFormat") + endianness: Optional[Literal["little", "big"]] = pd.Field(alias="meshEndianness") + compression: Optional[Literal["gz", "bz2", "zst"]] = pd.Field(alias="meshCompression") + mesh_params: Optional[Flow360MeshParams] = pd.Field(alias="meshParams") + solver_version: Optional[str] = pd.Field(alias="solverVersion") + if Flags.beta_features(): + version: Optional[Literal["v1", "v2"]] = pd.Field(alias="version", default="v1") + + # pylint: disable=no-self-argument + @pd.validator("mesh_params") + def set_mesh_params(cls, value: Union[Flow360MeshParams, None]): + """validate mesh params""" + if value: + return value.flow360_json() + return value + + +class NewSurfaceMeshRequest(Flow360Requests): + """request for new surface mesh""" + + name: str = pd.Field() + stem: str = pd.Field() + tags: Optional[List[str]] = pd.Field() + geometry_id: Optional[str] = pd.Field(alias="geometryId") + config: Optional[str] = pd.Field() + mesh_format: Optional[Literal["aflr3", "cgns", "stl"]] = pd.Field(alias="meshFormat") + endianness: Optional[Literal["little", "big"]] = pd.Field(alias="meshEndianness") + compression: Optional[Literal["gz", "bz2", "zst"]] = pd.Field(alias="meshCompression") + solver_version: Optional[str] = pd.Field(alias="solverVersion") + if Flags.beta_features(): + version: Optional[Literal["v1", "v2"]] = pd.Field(default="v1") diff --git a/flow360/component/flow360_params/conversions.py b/flow360/component/v1/conversions.py similarity index 99% rename from flow360/component/flow360_params/conversions.py rename to flow360/component/v1/conversions.py index 8d992e70f..885bdd9ea 100644 --- a/flow360/component/flow360_params/conversions.py +++ b/flow360/component/v1/conversions.py @@ -8,7 +8,7 @@ import pydantic.v1 as pd -from flow360.component.flow360_params.unit_system import ( +from flow360.component.v1.unit_system import ( flow360_conversion_unit_system, is_flow360_unit, u, diff --git a/flow360/component/flow360_params/exposed_units.py b/flow360/component/v1/exposed_units.py similarity index 100% rename from flow360/component/flow360_params/exposed_units.py rename to flow360/component/v1/exposed_units.py diff --git a/flow360/component/flow360_params/flow360_fields.py b/flow360/component/v1/flow360_fields.py similarity index 100% rename from flow360/component/flow360_params/flow360_fields.py rename to flow360/component/v1/flow360_fields.py diff --git a/flow360/component/flow360_params/flow360_legacy.py b/flow360/component/v1/flow360_legacy.py similarity index 95% rename from flow360/component/flow360_params/flow360_legacy.py rename to flow360/component/v1/flow360_legacy.py index 2b210a252..12305187a 100644 --- a/flow360/component/flow360_params/flow360_legacy.py +++ b/flow360/component/v1/flow360_legacy.py @@ -10,11 +10,8 @@ import pydantic.v1 as pd -from flow360.component.flow360_params.params_base import ( - DeprecatedAlias, - Flow360BaseModel, -) -from flow360.component.flow360_params.unit_system import DimensionedType +from flow360.component.v1.params_base import DeprecatedAlias, Flow360BaseModel +from flow360.component.v1.unit_system import DimensionedType class LegacyModel(Flow360BaseModel, metaclass=ABCMeta): diff --git a/flow360/component/flow360_params/flow360_output.py b/flow360/component/v1/flow360_output.py similarity index 99% rename from flow360/component/flow360_params/flow360_output.py rename to flow360/component/v1/flow360_output.py index 7b9c8eb32..1a4710b0f 100644 --- a/flow360/component/flow360_params/flow360_output.py +++ b/flow360/component/v1/flow360_output.py @@ -10,7 +10,7 @@ import pydantic.v1 as pd from pydantic.v1 import conlist -from flow360.component.flow360_params.unit_system import Flow360UnitSystem, LengthType +from flow360.component.v1.unit_system import Flow360UnitSystem, LengthType from ..types import Axis, Coordinate from ..utils import process_expressions diff --git a/flow360/component/flow360_params/flow360_params.py b/flow360/component/v1/flow360_params.py similarity index 99% rename from flow360/component/flow360_params/flow360_params.py rename to flow360/component/v1/flow360_params.py index 0ed2b5fbf..eafb3dc7d 100644 --- a/flow360/component/flow360_params/flow360_params.py +++ b/flow360/component/v1/flow360_params.py @@ -13,7 +13,7 @@ import pydantic.v1 as pd from typing_extensions import Literal -from flow360.component.flow360_params.unit_system import ( +from flow360.component.v1.unit_system import ( AngularVelocityType, AreaType, DensityType, diff --git a/flow360/component/flow360_params/initial_condition.py b/flow360/component/v1/initial_condition.py similarity index 100% rename from flow360/component/flow360_params/initial_condition.py rename to flow360/component/v1/initial_condition.py diff --git a/flow360/component/meshing/__init__.py b/flow360/component/v1/meshing/__init__.py similarity index 100% rename from flow360/component/meshing/__init__.py rename to flow360/component/v1/meshing/__init__.py diff --git a/flow360/component/meshing/params.py b/flow360/component/v1/meshing/params.py similarity index 99% rename from flow360/component/meshing/params.py rename to flow360/component/v1/meshing/params.py index 0de720269..fbd1245ac 100644 --- a/flow360/component/meshing/params.py +++ b/flow360/component/v1/meshing/params.py @@ -9,13 +9,13 @@ from flow360.flags import Flags -from ..flow360_params.params_base import ( +from ...types import Axis, Coordinate +from ..params_base import ( Flow360BaseModel, Flow360SortableBaseModel, _self_named_property_validator, flow360_json_encoder, ) -from ..types import Axis, Coordinate class Aniso(Flow360BaseModel): diff --git a/flow360/component/flow360_params/params_base.py b/flow360/component/v1/params_base.py similarity index 99% rename from flow360/component/flow360_params/params_base.py rename to flow360/component/v1/params_base.py index 3d72b6f07..5520ce601 100644 --- a/flow360/component/flow360_params/params_base.py +++ b/flow360/component/v1/params_base.py @@ -21,10 +21,7 @@ from pydantic.v1.fields import ModelField from typing_extensions import Literal -from flow360.component.flow360_params.unit_system import ( - DimensionedType, - is_flow360_unit, -) +from flow360.component.v1.unit_system import DimensionedType, is_flow360_unit from ...error_messages import do_not_modify_file_manually_msg from ...exceptions import Flow360FileError, Flow360ValidationError diff --git a/flow360/component/flow360_params/params_utils.py b/flow360/component/v1/params_utils.py similarity index 100% rename from flow360/component/flow360_params/params_utils.py rename to flow360/component/v1/params_utils.py diff --git a/flow360/component/flow360_params/physical_properties.py b/flow360/component/v1/physical_properties.py similarity index 98% rename from flow360/component/flow360_params/physical_properties.py rename to flow360/component/v1/physical_properties.py index e6a235dcb..24d5d3d03 100644 --- a/flow360/component/flow360_params/physical_properties.py +++ b/flow360/component/v1/physical_properties.py @@ -9,7 +9,7 @@ import numpy as np -from flow360.component.flow360_params.unit_system import ( +from flow360.component.v1.unit_system import ( DensityType, PressureType, TemperatureType, diff --git a/flow360/component/flow360_params/services.py b/flow360/component/v1/services.py similarity index 97% rename from flow360/component/flow360_params/services.py rename to flow360/component/v1/services.py index 3165028e5..28fcf726d 100644 --- a/flow360/component/flow360_params/services.py +++ b/flow360/component/v1/services.py @@ -7,19 +7,19 @@ import pydantic.v1 as pd -from flow360.component.flow360_params.flow360_params import ( +from flow360.component.v1.flow360_params import ( Flow360Params, FreestreamFromVelocity, Geometry, ) -from flow360.component.flow360_params.params_base import ( +from flow360.component.v1.params_base import ( Flow360BaseModel, Flow360SortableBaseModel, _schema_optional_toggle_name, flow360_json_encoder, ) -from flow360.component.flow360_params.solvers import NavierStokesSolver, SpalartAllmaras -from flow360.component.flow360_params.unit_system import ( +from flow360.component.v1.solvers import NavierStokesSolver, SpalartAllmaras +from flow360.component.v1.unit_system import ( CGS_unit_system, SI_unit_system, UnitSystem, diff --git a/flow360/component/flow360_params/solvers.py b/flow360/component/v1/solvers.py similarity index 100% rename from flow360/component/flow360_params/solvers.py rename to flow360/component/v1/solvers.py diff --git a/flow360/component/flow360_params/time_stepping.py b/flow360/component/v1/time_stepping.py similarity index 98% rename from flow360/component/flow360_params/time_stepping.py rename to flow360/component/v1/time_stepping.py index 926a23223..55834a4a8 100644 --- a/flow360/component/flow360_params/time_stepping.py +++ b/flow360/component/v1/time_stepping.py @@ -12,7 +12,7 @@ import pydantic.v1 as pd from typing_extensions import Literal -from flow360.component.flow360_params.unit_system import TimeType +from flow360.component.v1.unit_system import TimeType from .params_base import DeprecatedAlias, Flow360BaseModel diff --git a/flow360/component/flow360_params/turbulence_quantities.py b/flow360/component/v1/turbulence_quantities.py similarity index 100% rename from flow360/component/flow360_params/turbulence_quantities.py rename to flow360/component/v1/turbulence_quantities.py diff --git a/flow360/component/flow360_params/unit_system.py b/flow360/component/v1/unit_system.py similarity index 99% rename from flow360/component/flow360_params/unit_system.py rename to flow360/component/v1/unit_system.py index 654e99e05..be9116f1e 100644 --- a/flow360/component/flow360_params/unit_system.py +++ b/flow360/component/v1/unit_system.py @@ -2,7 +2,8 @@ Unit system definitions and utilities """ -# pylint: disable=too-many-lines, duplicate-code +# pylint: disable=too-many-lines, duplicate-code, +# pylint: disable=missing-function-docstring from __future__ import annotations from abc import ABCMeta, abstractmethod @@ -289,7 +290,7 @@ def __modify_schema__(cls, field_schema, field): field_schema["properties"]["units"]["dimension"] = cls.dim_name # Local import to prevent exposing mappings to the user # pylint: disable=import-outside-toplevel - from flow360.component.flow360_params.exposed_units import extra_units + from flow360.component.v1.exposed_units import extra_units units = [ str(_SI_system[cls.dim_name]), diff --git a/flow360/component/flow360_params/units.py b/flow360/component/v1/units.py similarity index 95% rename from flow360/component/flow360_params/units.py rename to flow360/component/v1/units.py index 01ac4f064..12fc3d5ba 100644 --- a/flow360/component/flow360_params/units.py +++ b/flow360/component/v1/units.py @@ -5,7 +5,7 @@ import unyt from unyt import unit_symbols -from flow360.component.flow360_params.unit_system import ( +from flow360.component.v1.unit_system import ( BaseSystemType, CGS_unit_system, SI_unit_system, diff --git a/flow360/component/flow360_params/updater.py b/flow360/component/v1/updater.py similarity index 100% rename from flow360/component/flow360_params/updater.py rename to flow360/component/v1/updater.py diff --git a/flow360/component/flow360_params/validations.py b/flow360/component/v1/validations.py similarity index 100% rename from flow360/component/flow360_params/validations.py rename to flow360/component/v1/validations.py diff --git a/flow360/component/flow360_params/volume_zones.py b/flow360/component/v1/volume_zones.py similarity index 99% rename from flow360/component/flow360_params/volume_zones.py rename to flow360/component/v1/volume_zones.py index 3f6605224..7b57d1c2c 100644 --- a/flow360/component/flow360_params/volume_zones.py +++ b/flow360/component/v1/volume_zones.py @@ -14,7 +14,7 @@ from pydantic.v1 import StrictStr from typing_extensions import Literal -from flow360.component.flow360_params.unit_system import ( +from flow360.component.v1.unit_system import ( AngularVelocityType, HeatSourceType, InverseAreaType, diff --git a/flow360/component/validator.py b/flow360/component/validator.py index 4fa1a178b..57b538909 100644 --- a/flow360/component/validator.py +++ b/flow360/component/validator.py @@ -5,11 +5,15 @@ from enum import Enum from typing import Union +from flow360.component.v1.meshing.params import ( + SurfaceMeshingParams, + VolumeMeshingParams, +) + from ..cloud.rest_api import RestApi from ..exceptions import Flow360ValidationError, Flow360ValueError from ..log import log -from .flow360_params.flow360_params import Flow360Params, UnvalidatedFlow360Params -from .meshing.params import SurfaceMeshingParams, VolumeMeshingParams +from .v1.flow360_params import Flow360Params, UnvalidatedFlow360Params class Validator(Enum): diff --git a/flow360/component/volume_mesh.py b/flow360/component/volume_mesh.py index ec393efcf..b867d2547 100644 --- a/flow360/component/volume_mesh.py +++ b/flow360/component/volume_mesh.py @@ -21,16 +21,17 @@ # structure refactors import pydantic.v1 as pd -from flow360.cloud.heartbeat import post_upload_heartbeat -from flow360.cloud.requests import ( +from flow360.cloud.compress_upload import compress_and_upload_chunks +from flow360.cloud.flow360_requests import ( CopyExampleVolumeMeshRequest, LengthUnitType, - NewVolumeMeshRequest, NewVolumeMeshRequestV2, ) +from flow360.cloud.heartbeat import post_upload_heartbeat from flow360.cloud.rest_api import RestApi from flow360.cloud.s3_utils import get_local_filename_and_create_folders -from flow360.component.compress_upload import compress_and_upload_chunks +from flow360.component.v1.cloud.flow360_requests import NewVolumeMeshRequest +from flow360.component.v1.meshing.params import VolumeMeshingParams from flow360.exceptions import ( Flow360CloudFileError, Flow360FileError, @@ -43,15 +44,7 @@ from flow360.solver_version import Flow360Version from .case import Case, CaseDraft -from .flow360_params.boundaries import NoSlipWall -from .flow360_params.flow360_params import ( - Flow360MeshParams, - Flow360Params, - _GenericBoundaryWrapper, -) -from .flow360_params.params_base import params_generic_validator from .interfaces import VolumeMeshInterface, VolumeMeshInterfaceV2 -from .meshing.params import VolumeMeshingParams from .resource_base import ( AssetMetaBaseModel, AssetMetaBaseModelV2, @@ -73,6 +66,9 @@ validate_type, zstd_compress, ) +from .v1.boundaries import NoSlipWall +from .v1.flow360_params import Flow360MeshParams, Flow360Params, _GenericBoundaryWrapper +from .v1.params_base import params_generic_validator from .validator import Validator try: diff --git a/flow360/new_simulation_models.py b/flow360/new_simulation_models.py deleted file mode 100644 index b870fc535..000000000 --- a/flow360/new_simulation_models.py +++ /dev/null @@ -1,207 +0,0 @@ -""" -This module is flow360 for simulation based models -""" - -from flow360.component.simulation import services -from flow360.component.simulation import units as u -from flow360.component.simulation.entity_info import GeometryEntityInfo -from flow360.component.simulation.framework.param_utils import AssetCache -from flow360.component.simulation.meshing_param.edge_params import ( - HeightBasedRefinement, - SurfaceEdgeRefinement, -) -from flow360.component.simulation.meshing_param.face_params import SurfaceRefinement -from flow360.component.simulation.meshing_param.params import ( - MeshingDefaults, - MeshingParams, -) -from flow360.component.simulation.meshing_param.volume_params import ( - AutomatedFarfield, - AxisymmetricRefinement, - RotationCylinder, - UniformRefinement, -) -from flow360.component.simulation.models.material import Air, SolidMaterial, Sutherland -from flow360.component.simulation.models.solver_numerics import ( - HeatEquationSolver, - KOmegaSST, - KOmegaSSTModelConstants, - LinearSolver, - NavierStokesSolver, - NoneSolver, - SpalartAllmaras, - SpalartAllmarasModelConstants, - TransitionModelSolver, - TransitionModelSolverType, - TurbulenceModelSolverType, -) -from flow360.component.simulation.models.surface_models import ( - Freestream, - HeatFlux, - Inflow, - Outflow, - Periodic, - Pressure, - Rotational, - SlipWall, - SymmetryPlane, - Temperature, - TotalPressure, - Translational, - Wall, -) -from flow360.component.simulation.models.turbulence_quantities import ( - TurbulenceQuantities, -) -from flow360.component.simulation.models.volume_models import ( - ActuatorDisk, - AngleExpression, - AngularVelocity, - BETDisk, - BETDiskChord, - BETDiskSectionalPolar, - BETDiskTwist, - Fluid, - ForcePerArea, - FromUserDefinedDynamics, - HeatEquationInitialCondition, - NavierStokesInitialCondition, - PorousMedium, - Rotation, - Solid, -) -from flow360.component.simulation.operating_condition.operating_condition import ( - AerospaceCondition, - GenericReferenceCondition, - ThermalState, -) -from flow360.component.simulation.outputs.output_entities import ( - Point, - PointArray, - Slice, -) -from flow360.component.simulation.outputs.outputs import ( - AeroAcousticOutput, - IsosurfaceOutput, - ProbeOutput, - SliceOutput, - SurfaceIntegralOutput, - SurfaceOutput, - SurfaceProbeOutput, - SurfaceSliceOutput, - TimeAverageSurfaceOutput, - TimeAverageVolumeOutput, - VolumeOutput, -) -from flow360.component.simulation.primitives import ( - Box, - Cylinder, - Edge, - GenericVolume, - ReferenceGeometry, - Surface, -) -from flow360.component.simulation.simulation_params import SimulationParams -from flow360.component.simulation.time_stepping.time_stepping import ( - AdaptiveCFL, - RampCFL, - Steady, - Unsteady, -) -from flow360.component.simulation.unit_system import ( - SI_unit_system, - imperial_unit_system, -) -from flow360.component.simulation.user_defined_dynamics.user_defined_dynamics import ( - UserDefinedDynamic, -) - -__all__ = [ - "u", - "SimulationParams", - "SI_unit_system", - "imperial_unit_system", - "services", - "MeshingParams", - "MeshingDefaults", - "SurfaceRefinement", - "AutomatedFarfield", - "AxisymmetricRefinement", - "RotationCylinder", - "UniformRefinement", - "SurfaceEdgeRefinement", - "HeightBasedRefinement", - "Surface", - "Edge", - "ReferenceGeometry", - "Cylinder", - "AssetCache", - "GeometryEntityInfo", - "AerospaceCondition", - "ThermalState", - "Steady", - "Unsteady", - "RampCFL", - "AdaptiveCFL", - "Wall", - "Freestream", - "SlipWall", - "Outflow", - "Inflow", - "Periodic", - "SymmetryPlane", - "Fluid", - "Solid", - "ActuatorDisk", - "AngularVelocity", - "BETDisk", - "BETDiskChord", - "BETDiskSectionalPolar", - "BETDiskTwist", - "Rotation", - "PorousMedium", - "SurfaceOutput", - "TimeAverageSurfaceOutput", - "VolumeOutput", - "TimeAverageVolumeOutput", - "SliceOutput", - "IsosurfaceOutput", - "SurfaceIntegralOutput", - "ProbeOutput", - "SurfaceProbeOutput", - "SurfaceSliceOutput", - "AeroAcousticOutput", - "HeatEquationSolver", - "NavierStokesSolver", - "NoneSolver", - "SpalartAllmaras", - "KOmegaSST", - "SpalartAllmarasModelConstants", - "KOmegaSSTModelConstants", - "TransitionModelSolverType", - "TurbulenceModelSolverType", - "LinearSolver", - "ForcePerArea", - "Air", - "Sutherland", - "SolidMaterial", - "Slice", - "TurbulenceQuantities", - "UserDefinedDynamic", - "Translational", - "NavierStokesInitialCondition", - "FromUserDefinedDynamics", - "HeatEquationInitialCondition", - "GenericVolume", - "Temperature", - "HeatFlux", - "Point", - "PointArray", - "AngleExpression", - "Box", - "GenericReferenceCondition", - "TransitionModelSolver", - "Pressure", - "TotalPressure", - "Rotational", -] diff --git a/tests/data/geometry/cylinder.x_t b/tests/data/geometry/cylinder.x_t deleted file mode 100644 index 7e4a7dfa5..000000000 --- a/tests/data/geometry/cylinder.x_t +++ /dev/null @@ -1,66 +0,0 @@ -**ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz************************** -**PARASOLID !"#$%&'()*+,-./:;<=>?@[\]^_`{|}~0123456789************************** -**PART1; -MC=AMD64; -MC_MODEL=AMD64 Family 25 Model 8 Stepping 2, AuthenticAMD; -MC_ID=unknown; -OS=Windows_NT; -OS_RELEASE=unknown; -FRU=Parasolid Version 35.1, build 251, 11- 4-2023; -APPL=SOLIDWORKS 2024-2024016; -SITE=; -USER=unknown; -FORMAT=text; -GUISE=transmit; -KEY=cylinder_v2; -FILE=cylinder_v2.x_t; -DATE=Fri May 17 11:19:49 2024; -**PART2; -SCH=SCH_3501251_35102; -USFLD_SIZE=0; -**PART3; -**END_OF_HEADER***************************************************************** -T51 : TRANSMIT FILE created by modeller version 350125123 SCH_3501251_35102_1300 -6231 0 12 36 CCCI7 lattice222 0 CCCI4 mesh1006 0 I8 polyline1008 0 CCCCCCCDI5 ow -ner1040 0 CCCI16 boundary_lattice222 0 CCCI13 boundary_mesh1006 0 I17 boundary_p -olyline1008 0 CCCA16 index_map_offset0 0 1 dA9 index_map82 0 A17 node_id_index_m -ap82 0 A20 schema_embedding_map82 0 A5 child12 0 A14 lowest_node_id0 0 1 dA16 me -sh_offset_data206 0 Z1 102 2 3 0 0 0 0 0 0 0 1e3 1e-8 0 4 0 1 0 1 1 5 0 6 7 0 0 - 0 8 9 0 0 0 0 0 0 0 0 81 255 2 2 96 10 1 11 0 0 0 0 12 70 11 CI9 list_type0 0 1 - uI10 notransmit0 0 1 lCCCDCCDI12 finger_index0 0 1 dI12 finger_block1012 0 CZ3 - 0 4 T1 0 0 11 20 1 13 13 13 255 5 31 0 1 0 14 0 0 15 0 51 255 6 30 0 14 16 0 0 - -0 0 .01760714246861955 0 0 -1 .01 -1 0 0 31 255 7 25 0 17 18 0 0 +0 0 0 0 0 1 - 1 0 0 .01 19 9 CCCCCCI5 frame230 0 CA5 owner12 0 Z8 9 0 1 15 0 19 0 V0 16 255 9 - 5 0 ?20 0 17 18 0 0 1 17 255 20 0 21 20 20 0 22 9 0 0 +16 17 20 0 ?23 9 0 7 0 0 - 1 31 18 7 0 9 0 7 0 +0 0 .01760714246861955 0 0 1 1 0 0 .01 17 23 0 24 23 23 0 - 25 17 0 0 +15 255 24 28 0 23 14 0 17 25 0 26 25 25 0 23 17 0 0 -15 26 19 0 25 2 -7 0 14 255 27 18 28 ?0 29 26 5 16 -0 0 0 29 19 81 1 28 98 30 27 31 0 0 32 33 14 - 29 1 32 ?27 14 21 5 34 +0 0 27 14 19 50 255 16 24 0 27 34 6 0 +0 0 0 0 0 1 1 0 - 0 13 19 10 0 0 0 0 0 0 8 14 14 14 27 35 ?29 0 36 5 6 -0 0 29 0 19 81 1 35 102 3 -0 14 37 0 32 0 38 15 36 26 0 22 14 24 17 22 0 36 22 22 0 20 9 0 0 -80 7 CCCCCDI1 -2 legal_owners0 16 1 lCZ1 30 39 40 9000 1 1 1 1 1 1 1 1 0 FFFFTFTFFFFFFFFF1 81 3 - 37 101 41 14 42 35 43 0 44 0 0 81 1 32 100 30 29 43 0 28 35 45 82 255 1 38 -946 -798438 81 3 43 99 41 29 46 32 31 37 47 0 0 82 1 45 -948764518 80 3 41 48 49 9000 - 0 0 0 0 3 5 0 0 0 FFFFTFFFFFFFFFFF1 1 1 81 1 46 84 50 29 0 43 42 51 52 81 3 31 - 97 41 27 51 28 0 43 53 0 0 82 6 47 0 -719274033 31107179 0 0 0 81 1 51 85 50 27 - 0 31 46 0 54 82 6 53 0 -719274033 31107179 0 0 0 80 1 50 0 55 8001 0 0 0 0 3 5 - 0 0 0 FFFFTFTFFFFFFFFF2 83 255 3 54 .792156862745098 .819607843137255 .93333333 -3333333 79 255 15 55 SDL/TYSA_COLOUR81 1 42 83 50 14 0 37 0 46 56 83 3 52 .79215 -6862745098 .819607843137255 .933333333333333 83 3 56 .792156862745098 .819607843 -137255 .933333333333333 79 18 49 DOWNSTREAM_FACE_ID82 6 44 0 -719274033 31107179 - 0 0 0 79 14 40 SWEntUnchanged50 34 3 0 29 0 16 0 +0 0 .01760714246861955 0 0 1 - 1 0 0 15 21 4 0 20 29 0 82 1 33 -947060582 19 15 32 0 1 0 8 5 0 S0 74 4 CI16 in -dex_map_offset0 0 1 dCCZ20 13 11 0 0 37 57 58 59 35 60 61 62 11 51 2 0 0 0 0 0 0 - 0 0 0 81 2 57 50 63 1 0 58 0 0 0 64 81 2 58 53 65 1 57 59 0 0 0 66 81 2 59 54 6 -7 1 58 60 0 0 68 0 81 1 60 58 69 1 59 61 0 0 70 81 2 61 64 71 1 60 62 0 0 72 0 8 -1 2 62 68 73 1 61 11 0 0 0 74 81 2 11 74 75 1 62 2 0 0 0 0 80 2 75 76 77 9000 0 - 0 0 0 3 5 0 0 0 FFTFFFFFFFFFFFFF9 1 79 16 77 BODY_RECIPE_200180 2 73 78 79 9000 - 0 0 0 0 3 5 0 0 0 FFTFFFFFFFFFFFFF9 1 82 1 74 1 79 24 79 BODY_IN_LIGHTWEIGHT_PE -RM80 2 71 80 81 8004 0 0 0 0 3 5 0 0 0 FFTFFFFFFFFFFFFF2 3 83 1 72 1 79 16 81 SD -L/TYSA_DENSITY80 1 69 82 83 9000 1 1 1 1 1 1 1 1 0 FFTFFFFFFFFFFFFF1 82 1 70 510 -57 79 10 83 BODY_MATCH80 2 67 84 85 9000 0 0 0 0 3 5 0 0 0 FFTFTTTFFTFFFFFF10 10 - 98 255 13 68 66 111 115 115 45 69 120 116 114 117 100 101 49 79 23 85 SWIMPLICI -TBODYNAME_ID_U80 2 65 86 87 9000 0 0 0 0 3 5 0 0 0 FFTFFFFFFFFFFFFF9 1 82 1 66 3 -3 79 30 87 LAST_BODY_MODIFYING_FEATURE_ID80 2 63 88 89 9000 0 0 0 0 3 5 0 0 0 FF -TFFFFFFFFFFFFF9 1 82 1 64 151 79 19 89 ENT_TIME_STAMP_200180 2 10 90 91 9000 0 0 - 0 0 3 5 0 0 0 FFTFFFFFFFFFFFFF9 1 82 1 12 101 79 12 91 ATOM_ID_20011 0 diff --git a/tests/om6wing/Flow360Mesh.json b/tests/om6wing/Flow360Mesh.json deleted file mode 100644 index cb2ccac2a..000000000 --- a/tests/om6wing/Flow360Mesh.json +++ /dev/null @@ -1,6 +0,0 @@ -{ - "boundaries" : - { - "noSlipWalls" : [1] - } -} diff --git a/tests/simulation/conftest.py b/tests/simulation/conftest.py index 5239c0b14..917ec8e52 100644 --- a/tests/simulation/conftest.py +++ b/tests/simulation/conftest.py @@ -1,5 +1,10 @@ from abc import ABCMeta +import numpy as np +import pytest +import unyt + +from flow360.component.simulation import unit_system from flow360.component.simulation.framework.entity_base import EntityBase from flow360.component.simulation.framework.entity_registry import EntityRegistry @@ -23,3 +28,71 @@ def __getitem__(self, key: str) -> list[EntityBase]: return found_entities[0] return found_entities + + +@pytest.fixture() +def array_equality_override(): + # Save original methods + original_unyt_eq = unyt.unyt_array.__eq__ + original_unyt_ne = unyt.unyt_array.__ne__ + original_flow360_eq = unit_system._Flow360BaseUnit.__eq__ + original_flow360_ne = unit_system._Flow360BaseUnit.__ne__ + + # Overload equality for unyt arrays + def unyt_array_eq(self: unyt.unyt_array, other: unyt.unyt_array): + if isinstance(other, unit_system._Flow360BaseUnit): + return flow360_unit_array_eq(other, self) + if isinstance(self, unyt.unyt_quantity): + return np.ndarray.__eq__(self, other) + elif self.size == other.size: + return all(self[i] == other[i] for i in range(len(self))) + return False + + def unyt_array_ne(self: unyt.unyt_array, other: unyt.unyt_array): + if isinstance(other, unit_system._Flow360BaseUnit): + return flow360_unit_array_ne(other, self) + if isinstance(self, unyt.unyt_quantity): + return np.ndarray.__ne__(self, other) + elif self.size == other.size: + return any(self[i] != other[i] for i in range(len(self))) + return True + + def flow360_unit_array_eq( + self: unit_system._Flow360BaseUnit, other: unit_system._Flow360BaseUnit + ): + if isinstance(other, (unit_system._Flow360BaseUnit, unyt.unyt_array)): + if self.size == other.size: + if str(self.units) == str(other.units): + if self.size == 1: + return np.ndarray.__eq__(self.v, other.v) + if isinstance(other, unyt.unyt_array): + other = unit_system._Flow360BaseUnit.factory(other.v, str(other.units)) + return all(np.ndarray.__eq__(v.v, o.v) for v, o in zip(self, other)) + return False + + def flow360_unit_array_ne( + self: unit_system._Flow360BaseUnit, other: unit_system._Flow360BaseUnit + ): + if isinstance(other, (unit_system._Flow360BaseUnit, unyt.unyt_array)): + if self.size == other.size: + if str(self.units) == str(other.units): + if self.size == 1: + return np.ndarray.__ne__(self.v, other.v) + if isinstance(other, unyt.unyt_array): + other = unit_system._Flow360BaseUnit.factory(other.v, str(other.units)) + return any(np.ndarray.__ne__(v.v, o.v) for v, o in zip(self, other)) + return True + + unyt.unyt_array.__eq__ = unyt_array_eq + unyt.unyt_array.__ne__ = unyt_array_ne + unit_system._Flow360BaseUnit.__eq__ = flow360_unit_array_eq + unit_system._Flow360BaseUnit.__ne__ = flow360_unit_array_ne + + # Yield control to the test + yield + + # Restore original methods + unyt.unyt_array.__eq__ = original_unyt_eq + unyt.unyt_array.__ne__ = original_unyt_ne + unit_system._Flow360BaseUnit.__eq__ = original_flow360_eq + unit_system._Flow360BaseUnit.__ne__ = original_flow360_ne diff --git a/tests/simulation/framework/test_base_model_v2.py b/tests/simulation/framework/test_base_model_v2.py index 48d1f8044..e15237cdf 100644 --- a/tests/simulation/framework/test_base_model_v2.py +++ b/tests/simulation/framework/test_base_model_v2.py @@ -7,7 +7,6 @@ import yaml import flow360.component.simulation.units as u -from flow360.component.flow360_params.flow360_params import Flow360BaseModel from flow360.component.simulation.framework.base_model import Flow360BaseModel from flow360.log import set_logging_level diff --git a/tests/simulation/framework/test_context_validators.py b/tests/simulation/framework/test_context_validators.py index 988d3416b..b99364462 100644 --- a/tests/simulation/framework/test_context_validators.py +++ b/tests/simulation/framework/test_context_validators.py @@ -3,7 +3,6 @@ import pydantic as pd import flow360.component.simulation.units as u -from flow360.component.flow360_params.flow360_params import Flow360BaseModel from flow360.component.simulation.framework.base_model import Flow360BaseModel from flow360.component.simulation.validation import validation_context from flow360.log import set_logging_level diff --git a/tests/simulation/framework/test_unique_list.py b/tests/simulation/framework/test_unique_list.py index 2f6ebf4df..e27ead3c3 100644 --- a/tests/simulation/framework/test_unique_list.py +++ b/tests/simulation/framework/test_unique_list.py @@ -4,12 +4,12 @@ import pydantic as pd import pytest -from flow360.component.flow360_params.flow360_fields import CommonFieldNames from flow360.component.simulation.framework.base_model import Flow360BaseModel from flow360.component.simulation.framework.unique_list import ( UniqueItemList, UniqueStringList, ) +from flow360.component.simulation.outputs.output_fields import CommonFieldNames from flow360.component.simulation.primitives import Surface, SurfacePair diff --git a/tests/test_flow360.py b/tests/test_current_flow360_version.py similarity index 56% rename from tests/test_flow360.py rename to tests/test_current_flow360_version.py index 17fd69823..e7eb64980 100644 --- a/tests/test_flow360.py +++ b/tests/test_current_flow360_version.py @@ -1,4 +1,4 @@ -from flow360 import __version__ +from flow360.component.v1 import __version__ def test_version(): diff --git a/tests/test_environment.py b/tests/test_environment.py index 502d152c3..60a823cc5 100644 --- a/tests/test_environment.py +++ b/tests/test_environment.py @@ -1,4 +1,4 @@ -from flow360 import Env +from flow360.component.v1 import Env def test_version(): diff --git a/tests/test_results.py b/tests/test_results.py index edb9e2f4b..c51a4257a 100644 --- a/tests/test_results.py +++ b/tests/test_results.py @@ -6,8 +6,8 @@ import pandas import pytest -import flow360 as fl -import flow360.component.flow360_params.units as u +import flow360.component.v1 as fl +import flow360.component.v1.units as u from flow360 import log log.set_logging_level("DEBUG") diff --git a/tests/test_shared_accounts.py b/tests/test_shared_accounts.py index c242392a1..c43092473 100644 --- a/tests/test_shared_accounts.py +++ b/tests/test_shared_accounts.py @@ -2,7 +2,7 @@ import pytest -from flow360 import Accounts, Env +from flow360.component.v1 import Accounts, Env def test_shared_account(mock_response, monkeypatch): diff --git a/tests/test_utils.py b/tests/test_utils.py index 6816047fe..3da5c8d9c 100644 --- a/tests/test_utils.py +++ b/tests/test_utils.py @@ -2,7 +2,6 @@ import pytest -from flow360 import Accounts from flow360.cli.dict_utils import merge_overwrite from flow360.component.utils import ( CompressionFormat, @@ -13,6 +12,7 @@ shared_account_confirm_proceed, validate_type, ) +from flow360.component.v1 import Accounts from flow360.component.volume_mesh import VolumeMeshMeta from flow360.exceptions import Flow360TypeError, Flow360ValueError diff --git a/tests/test_version.py b/tests/test_version_comparisons.py similarity index 100% rename from tests/test_version.py rename to tests/test_version_comparisons.py diff --git a/tests/utils.py b/tests/utils.py index 9aeff47e5..78a6ec6d9 100644 --- a/tests/utils.py +++ b/tests/utils.py @@ -11,7 +11,6 @@ from flow360.cloud.rest_api import RestApi from flow360.cloud.s3_utils import S3TransferType, get_local_filename_and_create_folders -from flow360.component.flow360_params import unit_system @pytest.fixture @@ -142,74 +141,6 @@ def compare_to_ref(obj, ref_path, content_only=False): compare_dict_to_ref(a, ref_path) -@pytest.fixture() -def array_equality_override(): - # Save original methods - original_unyt_eq = unyt.unyt_array.__eq__ - original_unyt_ne = unyt.unyt_array.__ne__ - original_flow360_eq = unit_system._Flow360BaseUnit.__eq__ - original_flow360_ne = unit_system._Flow360BaseUnit.__ne__ - - # Overload equality for unyt arrays - def unyt_array_eq(self: unyt.unyt_array, other: unyt.unyt_array): - if isinstance(other, unit_system._Flow360BaseUnit): - return flow360_unit_array_eq(other, self) - if isinstance(self, unyt.unyt_quantity): - return np.ndarray.__eq__(self, other) - elif self.size == other.size: - return all(self[i] == other[i] for i in range(len(self))) - return False - - def unyt_array_ne(self: unyt.unyt_array, other: unyt.unyt_array): - if isinstance(other, unit_system._Flow360BaseUnit): - return flow360_unit_array_ne(other, self) - if isinstance(self, unyt.unyt_quantity): - return np.ndarray.__ne__(self, other) - elif self.size == other.size: - return any(self[i] != other[i] for i in range(len(self))) - return True - - def flow360_unit_array_eq( - self: unit_system._Flow360BaseUnit, other: unit_system._Flow360BaseUnit - ): - if isinstance(other, (unit_system._Flow360BaseUnit, unyt.unyt_array)): - if self.size == other.size: - if str(self.units) == str(other.units): - if self.size == 1: - return np.ndarray.__eq__(self.v, other.v) - if isinstance(other, unyt.unyt_array): - other = unit_system._Flow360BaseUnit.factory(other.v, str(other.units)) - return all(np.ndarray.__eq__(v.v, o.v) for v, o in zip(self, other)) - return False - - def flow360_unit_array_ne( - self: unit_system._Flow360BaseUnit, other: unit_system._Flow360BaseUnit - ): - if isinstance(other, (unit_system._Flow360BaseUnit, unyt.unyt_array)): - if self.size == other.size: - if str(self.units) == str(other.units): - if self.size == 1: - return np.ndarray.__ne__(self.v, other.v) - if isinstance(other, unyt.unyt_array): - other = unit_system._Flow360BaseUnit.factory(other.v, str(other.units)) - return any(np.ndarray.__ne__(v.v, o.v) for v, o in zip(self, other)) - return True - - unyt.unyt_array.__eq__ = unyt_array_eq - unyt.unyt_array.__ne__ = unyt_array_ne - unit_system._Flow360BaseUnit.__eq__ = flow360_unit_array_eq - unit_system._Flow360BaseUnit.__ne__ = flow360_unit_array_ne - - # Yield control to the test - yield - - # Restore original methods - unyt.unyt_array.__eq__ = original_unyt_eq - unyt.unyt_array.__ne__ = original_unyt_ne - unit_system._Flow360BaseUnit.__eq__ = original_flow360_eq - unit_system._Flow360BaseUnit.__ne__ = original_flow360_ne - - @pytest.fixture() def s3_download_override(): def s3_mock_download( diff --git a/flow360/component/flow360_params/__init__.py b/tests/v1/__init__.py similarity index 100% rename from flow360/component/flow360_params/__init__.py rename to tests/v1/__init__.py diff --git a/tests/_test_case.py b/tests/v1/_test_case.py similarity index 88% rename from tests/_test_case.py rename to tests/v1/_test_case.py index 921674bb0..fc9236bce 100644 --- a/tests/_test_case.py +++ b/tests/v1/_test_case.py @@ -1,9 +1,6 @@ -from flow360 import Env from flow360.component.case import Case -from flow360.component.flow360_params.flow360_params import ( - Flow360Params, - UnsteadyTimeStepping, -) +from flow360.component.v1 import Env +from flow360.component.v1.flow360_params import Flow360Params, UnsteadyTimeStepping def test_from_cloud(): diff --git a/tests/_test_case_submit_solver_version.py b/tests/v1/_test_case_submit_solver_version.py similarity index 99% rename from tests/_test_case_submit_solver_version.py rename to tests/v1/_test_case_submit_solver_version.py index 989bb6b60..90e66089e 100644 --- a/tests/_test_case_submit_solver_version.py +++ b/tests/v1/_test_case_submit_solver_version.py @@ -1,6 +1,6 @@ import pytest -import flow360 as fl +import flow360.component.v1 as fl from flow360.examples import OM6wing from flow360.exceptions import Flow360RuntimeError, Flow360ValidationError from flow360.log import set_logging_level diff --git a/tests/_test_cli.py b/tests/v1/_test_cli.py similarity index 100% rename from tests/_test_cli.py rename to tests/v1/_test_cli.py diff --git a/tests/v1/_test_cli_tmp.py b/tests/v1/_test_cli_tmp.py new file mode 100644 index 000000000..a8c62e1da --- /dev/null +++ b/tests/v1/_test_cli_tmp.py @@ -0,0 +1,62 @@ +import os.path +import shutil +from os.path import expanduser + +import pytest +import toml +from click.testing import CliRunner + +home = expanduser("~") + + +@pytest.fixture +def backup_and_restore_file(): + original_file = f"{home}/.flow360/config.toml" + backup_file = f"{home}/.flow360/config.toml.bak" + + # Backup the original file + if os.path.exists(original_file): + shutil.copy2(original_file, backup_file) + print(f"Backup of {original_file} created as {backup_file}") + + yield # This allows the test to run + + # Restore the original file after the test + if os.path.exists(backup_file): + shutil.copy2(backup_file, original_file) + os.remove(backup_file) + print(f"{original_file} restored from backup") + + +# @pytest.fixture(backup_and_restore_file) +def test_no_configure(backup_and_restore_file): + if os.path.exists(f"{home}/.flow360/config.toml"): + print("Deleting existing config file") + os.remove(f"{home}/.flow360/config.toml") + assert not os.path.exists(f"{home}/.flow360/config.toml") + + runner = CliRunner() + + from flow360.cli import flow360 + + result = runner.invoke(flow360, ["configure"], input="apikey") + assert result.exit_code == 0 + assert result.output == "API Key: apikey\ndone.\n" + print(">>> result.output", result.output) + with open(f"{home}/.flow360/config.toml") as f: + config = toml.loads(f.read()) + print(">>> config", config) + assert config.get("default", {}).get("apikey", "") == "apikey" + + +# @pytest.fixture(backup_and_restore_file) +def test_with_existing_configure(backup_and_restore_file): + runner = CliRunner() + from flow360.cli import flow360 + + result = runner.invoke(flow360, ["configure"], input="apikey") + assert result.exit_code == 0 + assert result.output == "API Key[apikey]: apikey\ndone.\n" + with open(f"{home}/.flow360/config.toml") as f: + config = toml.loads(f.read()) + assert config.get("default", {}).get("apikey", "") == "apikey" diff --git a/tests/_test_http.py b/tests/v1/_test_http.py similarity index 100% rename from tests/_test_http.py rename to tests/v1/_test_http.py diff --git a/tests/_test_validate.py b/tests/v1/_test_validate.py similarity index 96% rename from tests/_test_validate.py rename to tests/v1/_test_validate.py index e1e35e12b..08c7a8d07 100644 --- a/tests/_test_validate.py +++ b/tests/v1/_test_validate.py @@ -2,7 +2,7 @@ import pytest -import flow360 as fl +import flow360.component.v1 as fl from flow360.component.validator import Validator assertions = unittest.TestCase("__init__") diff --git a/tests/v1/conftest.py b/tests/v1/conftest.py new file mode 100644 index 000000000..ed5a6693e --- /dev/null +++ b/tests/v1/conftest.py @@ -0,0 +1,73 @@ +import numpy as np +import pytest +import unyt + +from flow360.component.v1 import unit_system + + +@pytest.fixture() +def array_equality_override(): + # Save original methods + original_unyt_eq = unyt.unyt_array.__eq__ + original_unyt_ne = unyt.unyt_array.__ne__ + original_flow360_eq = unit_system._Flow360BaseUnit.__eq__ + original_flow360_ne = unit_system._Flow360BaseUnit.__ne__ + + # Overload equality for unyt arrays + def unyt_array_eq(self: unyt.unyt_array, other: unyt.unyt_array): + if isinstance(other, unit_system._Flow360BaseUnit): + return flow360_unit_array_eq(other, self) + if isinstance(self, unyt.unyt_quantity): + return np.ndarray.__eq__(self, other) + elif self.size == other.size: + return all(self[i] == other[i] for i in range(len(self))) + return False + + def unyt_array_ne(self: unyt.unyt_array, other: unyt.unyt_array): + if isinstance(other, unit_system._Flow360BaseUnit): + return flow360_unit_array_ne(other, self) + if isinstance(self, unyt.unyt_quantity): + return np.ndarray.__ne__(self, other) + elif self.size == other.size: + return any(self[i] != other[i] for i in range(len(self))) + return True + + def flow360_unit_array_eq( + self: unit_system._Flow360BaseUnit, other: unit_system._Flow360BaseUnit + ): + if isinstance(other, (unit_system._Flow360BaseUnit, unyt.unyt_array)): + if self.size == other.size: + if str(self.units) == str(other.units): + if self.size == 1: + return np.ndarray.__eq__(self.v, other.v) + if isinstance(other, unyt.unyt_array): + other = unit_system._Flow360BaseUnit.factory(other.v, str(other.units)) + return all(np.ndarray.__eq__(v.v, o.v) for v, o in zip(self, other)) + return False + + def flow360_unit_array_ne( + self: unit_system._Flow360BaseUnit, other: unit_system._Flow360BaseUnit + ): + if isinstance(other, (unit_system._Flow360BaseUnit, unyt.unyt_array)): + if self.size == other.size: + if str(self.units) == str(other.units): + if self.size == 1: + return np.ndarray.__ne__(self.v, other.v) + if isinstance(other, unyt.unyt_array): + other = unit_system._Flow360BaseUnit.factory(other.v, str(other.units)) + return any(np.ndarray.__ne__(v.v, o.v) for v, o in zip(self, other)) + return True + + unyt.unyt_array.__eq__ = unyt_array_eq + unyt.unyt_array.__ne__ = unyt_array_ne + unit_system._Flow360BaseUnit.__eq__ = flow360_unit_array_eq + unit_system._Flow360BaseUnit.__ne__ = flow360_unit_array_ne + + # Yield control to the test + yield + + # Restore original methods + unyt.unyt_array.__eq__ = original_unyt_eq + unyt.unyt_array.__ne__ = original_unyt_ne + unit_system._Flow360BaseUnit.__eq__ = original_flow360_eq + unit_system._Flow360BaseUnit.__ne__ = original_flow360_ne diff --git a/tests/data/case_params/boundaries.yaml b/tests/v1/data/case_params/boundaries.yaml similarity index 100% rename from tests/data/case_params/boundaries.yaml rename to tests/v1/data/case_params/boundaries.yaml diff --git a/tests/data/case_params/freestream/yaml.yaml b/tests/v1/data/case_params/freestream/yaml.yaml similarity index 100% rename from tests/data/case_params/freestream/yaml.yaml rename to tests/v1/data/case_params/freestream/yaml.yaml diff --git a/tests/data/case_params/geometry.yaml b/tests/v1/data/case_params/geometry.yaml similarity index 100% rename from tests/data/case_params/geometry.yaml rename to tests/v1/data/case_params/geometry.yaml diff --git a/tests/data/case_params/incorrect.json b/tests/v1/data/case_params/incorrect.json similarity index 100% rename from tests/data/case_params/incorrect.json rename to tests/v1/data/case_params/incorrect.json diff --git a/tests/data/case_params/outputs.yaml b/tests/v1/data/case_params/outputs.yaml similarity index 100% rename from tests/data/case_params/outputs.yaml rename to tests/v1/data/case_params/outputs.yaml diff --git a/tests/data/case_params/xv15_bet_line_hover_good.json b/tests/v1/data/case_params/xv15_bet_line_hover_good.json similarity index 100% rename from tests/data/case_params/xv15_bet_line_hover_good.json rename to tests/v1/data/case_params/xv15_bet_line_hover_good.json diff --git a/tests/data/cases/case_1.json b/tests/v1/data/cases/case_1.json similarity index 100% rename from tests/data/cases/case_1.json rename to tests/v1/data/cases/case_1.json diff --git a/tests/data/cases/case_10.json b/tests/v1/data/cases/case_10.json similarity index 100% rename from tests/data/cases/case_10.json rename to tests/v1/data/cases/case_10.json diff --git a/tests/data/cases/case_11.json b/tests/v1/data/cases/case_11.json similarity index 100% rename from tests/data/cases/case_11.json rename to tests/v1/data/cases/case_11.json diff --git a/tests/data/cases/case_12.json b/tests/v1/data/cases/case_12.json similarity index 100% rename from tests/data/cases/case_12.json rename to tests/v1/data/cases/case_12.json diff --git a/tests/data/cases/case_13.json b/tests/v1/data/cases/case_13.json similarity index 100% rename from tests/data/cases/case_13.json rename to tests/v1/data/cases/case_13.json diff --git a/tests/data/cases/case_14_bet.json b/tests/v1/data/cases/case_14_bet.json similarity index 100% rename from tests/data/cases/case_14_bet.json rename to tests/v1/data/cases/case_14_bet.json diff --git a/tests/data/cases/case_15.json b/tests/v1/data/cases/case_15.json similarity index 100% rename from tests/data/cases/case_15.json rename to tests/v1/data/cases/case_15.json diff --git a/tests/data/cases/case_16.json b/tests/v1/data/cases/case_16.json similarity index 100% rename from tests/data/cases/case_16.json rename to tests/v1/data/cases/case_16.json diff --git a/tests/data/cases/case_18.json b/tests/v1/data/cases/case_18.json similarity index 100% rename from tests/data/cases/case_18.json rename to tests/v1/data/cases/case_18.json diff --git a/tests/data/cases/case_2.json b/tests/v1/data/cases/case_2.json similarity index 100% rename from tests/data/cases/case_2.json rename to tests/v1/data/cases/case_2.json diff --git a/tests/data/cases/case_20.json b/tests/v1/data/cases/case_20.json similarity index 100% rename from tests/data/cases/case_20.json rename to tests/v1/data/cases/case_20.json diff --git a/tests/data/cases/case_3.json b/tests/v1/data/cases/case_3.json similarity index 100% rename from tests/data/cases/case_3.json rename to tests/v1/data/cases/case_3.json diff --git a/tests/data/cases/case_4.json b/tests/v1/data/cases/case_4.json similarity index 100% rename from tests/data/cases/case_4.json rename to tests/v1/data/cases/case_4.json diff --git a/tests/data/cases/case_5.json b/tests/v1/data/cases/case_5.json similarity index 100% rename from tests/data/cases/case_5.json rename to tests/v1/data/cases/case_5.json diff --git a/tests/data/cases/case_6.json b/tests/v1/data/cases/case_6.json similarity index 100% rename from tests/data/cases/case_6.json rename to tests/v1/data/cases/case_6.json diff --git a/tests/data/cases/case_7.json b/tests/v1/data/cases/case_7.json similarity index 100% rename from tests/data/cases/case_7.json rename to tests/v1/data/cases/case_7.json diff --git a/tests/data/cases/case_8.json b/tests/v1/data/cases/case_8.json similarity index 100% rename from tests/data/cases/case_8.json rename to tests/v1/data/cases/case_8.json diff --git a/tests/data/cases/case_9.json b/tests/v1/data/cases/case_9.json similarity index 100% rename from tests/data/cases/case_9.json rename to tests/v1/data/cases/case_9.json diff --git a/tests/data/cases/case_HeatTransfer.json b/tests/v1/data/cases/case_HeatTransfer.json similarity index 100% rename from tests/data/cases/case_HeatTransfer.json rename to tests/v1/data/cases/case_HeatTransfer.json diff --git a/tests/data/cases/case_actuatorDisk.json b/tests/v1/data/cases/case_actuatorDisk.json similarity index 100% rename from tests/data/cases/case_actuatorDisk.json rename to tests/v1/data/cases/case_actuatorDisk.json diff --git a/tests/data/cases/case_bet.json b/tests/v1/data/cases/case_bet.json similarity index 100% rename from tests/data/cases/case_bet.json rename to tests/v1/data/cases/case_bet.json diff --git a/tests/data/cases/case_beta.json b/tests/v1/data/cases/case_beta.json similarity index 100% rename from tests/data/cases/case_beta.json rename to tests/v1/data/cases/case_beta.json diff --git a/tests/data/cases/case_boundaries.json b/tests/v1/data/cases/case_boundaries.json similarity index 100% rename from tests/data/cases/case_boundaries.json rename to tests/v1/data/cases/case_boundaries.json diff --git a/tests/data/cases/case_comments_sliding_interfaces.json b/tests/v1/data/cases/case_comments_sliding_interfaces.json similarity index 100% rename from tests/data/cases/case_comments_sliding_interfaces.json rename to tests/v1/data/cases/case_comments_sliding_interfaces.json diff --git a/tests/data/cases/case_customDynamics1.json b/tests/v1/data/cases/case_customDynamics1.json similarity index 100% rename from tests/data/cases/case_customDynamics1.json rename to tests/v1/data/cases/case_customDynamics1.json diff --git a/tests/data/cases/case_customDynamics2.json b/tests/v1/data/cases/case_customDynamics2.json similarity index 100% rename from tests/data/cases/case_customDynamics2.json rename to tests/v1/data/cases/case_customDynamics2.json diff --git a/tests/data/cases/case_cylinder_incompressible.json b/tests/v1/data/cases/case_cylinder_incompressible.json similarity index 100% rename from tests/data/cases/case_cylinder_incompressible.json rename to tests/v1/data/cases/case_cylinder_incompressible.json diff --git a/tests/data/cases/case_emptyDict.json b/tests/v1/data/cases/case_emptyDict.json similarity index 100% rename from tests/data/cases/case_emptyDict.json rename to tests/v1/data/cases/case_emptyDict.json diff --git a/tests/data/cases/case_emptyFile.json b/tests/v1/data/cases/case_emptyFile.json similarity index 100% rename from tests/data/cases/case_emptyFile.json rename to tests/v1/data/cases/case_emptyFile.json diff --git a/tests/data/cases/case_invalid.json b/tests/v1/data/cases/case_invalid.json similarity index 100% rename from tests/data/cases/case_invalid.json rename to tests/v1/data/cases/case_invalid.json diff --git a/tests/data/cases/case_isothermalWall.json b/tests/v1/data/cases/case_isothermalWall.json similarity index 100% rename from tests/data/cases/case_isothermalWall.json rename to tests/v1/data/cases/case_isothermalWall.json diff --git a/tests/data/cases/case_isothermalWall_miss.json b/tests/v1/data/cases/case_isothermalWall_miss.json similarity index 100% rename from tests/data/cases/case_isothermalWall_miss.json rename to tests/v1/data/cases/case_isothermalWall_miss.json diff --git a/tests/data/cases/case_isothermalWall_miss2.json b/tests/v1/data/cases/case_isothermalWall_miss2.json similarity index 100% rename from tests/data/cases/case_isothermalWall_miss2.json rename to tests/v1/data/cases/case_isothermalWall_miss2.json diff --git a/tests/data/cases/case_isothermalWall_noTemperature.json b/tests/v1/data/cases/case_isothermalWall_noTemperature.json similarity index 100% rename from tests/data/cases/case_isothermalWall_noTemperature.json rename to tests/v1/data/cases/case_isothermalWall_noTemperature.json diff --git a/tests/data/cases/case_plane.json b/tests/v1/data/cases/case_plane.json similarity index 100% rename from tests/data/cases/case_plane.json rename to tests/v1/data/cases/case_plane.json diff --git a/tests/data/cases/case_porousMedia.json b/tests/v1/data/cases/case_porousMedia.json similarity index 100% rename from tests/data/cases/case_porousMedia.json rename to tests/v1/data/cases/case_porousMedia.json diff --git a/tests/data/cases/case_rotor1.json b/tests/v1/data/cases/case_rotor1.json similarity index 100% rename from tests/data/cases/case_rotor1.json rename to tests/v1/data/cases/case_rotor1.json diff --git a/tests/data/cases/case_rotor2.json b/tests/v1/data/cases/case_rotor2.json similarity index 100% rename from tests/data/cases/case_rotor2.json rename to tests/v1/data/cases/case_rotor2.json diff --git a/tests/data/cases/case_two_rotor.json b/tests/v1/data/cases/case_two_rotor.json similarity index 100% rename from tests/data/cases/case_two_rotor.json rename to tests/v1/data/cases/case_two_rotor.json diff --git a/tests/data/cases/case_udd.json b/tests/v1/data/cases/case_udd.json similarity index 100% rename from tests/data/cases/case_udd.json rename to tests/v1/data/cases/case_udd.json diff --git a/tests/data/cases/case_udd_legacy.json b/tests/v1/data/cases/case_udd_legacy.json similarity index 100% rename from tests/data/cases/case_udd_legacy.json rename to tests/v1/data/cases/case_udd_legacy.json diff --git a/tests/data/cases/case_unsteady.json b/tests/v1/data/cases/case_unsteady.json similarity index 100% rename from tests/data/cases/case_unsteady.json rename to tests/v1/data/cases/case_unsteady.json diff --git a/tests/data/cases/case_wing1.json b/tests/v1/data/cases/case_wing1.json similarity index 100% rename from tests/data/cases/case_wing1.json rename to tests/v1/data/cases/case_wing1.json diff --git a/tests/data/cases/case_wing2.json b/tests/v1/data/cases/case_wing2.json similarity index 100% rename from tests/data/cases/case_wing2.json rename to tests/v1/data/cases/case_wing2.json diff --git a/tests/data/cases/params_units.json b/tests/v1/data/cases/params_units.json similarity index 100% rename from tests/data/cases/params_units.json rename to tests/v1/data/cases/params_units.json diff --git a/tests/data/cases/test_version_b16.json b/tests/v1/data/cases/test_version_b16.json similarity index 100% rename from tests/data/cases/test_version_b16.json rename to tests/v1/data/cases/test_version_b16.json diff --git a/tests/data/cases/web/2D_CRM.json b/tests/v1/data/cases/web/2D_CRM.json similarity index 100% rename from tests/data/cases/web/2D_CRM.json rename to tests/v1/data/cases/web/2D_CRM.json diff --git a/tests/data/cases/web/BackStep_Flow360.json b/tests/v1/data/cases/web/BackStep_Flow360.json similarity index 100% rename from tests/data/cases/web/BackStep_Flow360.json rename to tests/v1/data/cases/web/BackStep_Flow360.json diff --git a/tests/data/cases/web/CRM_Flow360.json b/tests/v1/data/cases/web/CRM_Flow360.json similarity index 100% rename from tests/data/cases/web/CRM_Flow360.json rename to tests/v1/data/cases/web/CRM_Flow360.json diff --git a/tests/data/cases/web/Flow360 (1).json b/tests/v1/data/cases/web/Flow360 (1).json similarity index 100% rename from tests/data/cases/web/Flow360 (1).json rename to tests/v1/data/cases/web/Flow360 (1).json diff --git a/tests/data/cases/web/Flow360 (2).json b/tests/v1/data/cases/web/Flow360 (2).json similarity index 100% rename from tests/data/cases/web/Flow360 (2).json rename to tests/v1/data/cases/web/Flow360 (2).json diff --git a/tests/data/cases/web/Flow360 (3).json b/tests/v1/data/cases/web/Flow360 (3).json similarity index 100% rename from tests/data/cases/web/Flow360 (3).json rename to tests/v1/data/cases/web/Flow360 (3).json diff --git a/tests/data/cases/web/Flow360 (4).json b/tests/v1/data/cases/web/Flow360 (4).json similarity index 100% rename from tests/data/cases/web/Flow360 (4).json rename to tests/v1/data/cases/web/Flow360 (4).json diff --git a/tests/data/cases/web/Flow360.json b/tests/v1/data/cases/web/Flow360.json similarity index 100% rename from tests/data/cases/web/Flow360.json rename to tests/v1/data/cases/web/Flow360.json diff --git a/tests/data/cases/web/Flow360_Stage1_1stOrd_6Deg.json b/tests/v1/data/cases/web/Flow360_Stage1_1stOrd_6Deg.json similarity index 100% rename from tests/data/cases/web/Flow360_Stage1_1stOrd_6Deg.json rename to tests/v1/data/cases/web/Flow360_Stage1_1stOrd_6Deg.json diff --git a/tests/data/cases/web/Flow360_Stage2_2ndOrd_6Deg.json b/tests/v1/data/cases/web/Flow360_Stage2_2ndOrd_6Deg.json similarity index 100% rename from tests/data/cases/web/Flow360_Stage2_2ndOrd_6Deg.json rename to tests/v1/data/cases/web/Flow360_Stage2_2ndOrd_6Deg.json diff --git a/tests/data/cases/web/Flow360_hover_pitch0.json b/tests/v1/data/cases/web/Flow360_hover_pitch0.json similarity index 100% rename from tests/data/cases/web/Flow360_hover_pitch0.json rename to tests/v1/data/cases/web/Flow360_hover_pitch0.json diff --git a/tests/data/cases/web/Flow360_hover_pitch3.json b/tests/v1/data/cases/web/Flow360_hover_pitch3.json similarity index 100% rename from tests/data/cases/web/Flow360_hover_pitch3.json rename to tests/v1/data/cases/web/Flow360_hover_pitch3.json diff --git a/tests/data/cases/web/Flow360_hover_pitch5.json b/tests/v1/data/cases/web/Flow360_hover_pitch5.json similarity index 100% rename from tests/data/cases/web/Flow360_hover_pitch5.json rename to tests/v1/data/cases/web/Flow360_hover_pitch5.json diff --git a/tests/data/cases/web/Flow360_v2.json b/tests/v1/data/cases/web/Flow360_v2.json similarity index 100% rename from tests/data/cases/web/Flow360_v2.json rename to tests/v1/data/cases/web/Flow360_v2.json diff --git a/tests/data/cases/web/NACA0012_FMLY2GL4_AOA15_SARC_2ndOrd_CFL100_Flow360.json b/tests/v1/data/cases/web/NACA0012_FMLY2GL4_AOA15_SARC_2ndOrd_CFL100_Flow360.json similarity index 100% rename from tests/data/cases/web/NACA0012_FMLY2GL4_AOA15_SARC_2ndOrd_CFL100_Flow360.json rename to tests/v1/data/cases/web/NACA0012_FMLY2GL4_AOA15_SARC_2ndOrd_CFL100_Flow360.json diff --git a/tests/data/cases/web/NACA4412_Flow360.json b/tests/v1/data/cases/web/NACA4412_Flow360.json similarity index 100% rename from tests/data/cases/web/NACA4412_Flow360.json rename to tests/v1/data/cases/web/NACA4412_Flow360.json diff --git a/tests/data/cases/web/adaptiveCFL.json b/tests/v1/data/cases/web/adaptiveCFL.json similarity index 100% rename from tests/data/cases/web/adaptiveCFL.json rename to tests/v1/data/cases/web/adaptiveCFL.json diff --git a/tests/data/cases/web/flow360_singleSlidingInterface-mixed-2.5flowthruPerRad-2deg-400steps.json b/tests/v1/data/cases/web/flow360_singleSlidingInterface-mixed-2.5flowthruPerRad-2deg-400steps.json similarity index 100% rename from tests/data/cases/web/flow360_singleSlidingInterface-mixed-2.5flowthruPerRad-2deg-400steps.json rename to tests/v1/data/cases/web/flow360_singleSlidingInterface-mixed-2.5flowthruPerRad-2deg-400steps.json diff --git a/tests/data/cases/web/flow360_singleSlidingInterface-steady.json b/tests/v1/data/cases/web/flow360_singleSlidingInterface-steady.json similarity index 100% rename from tests/data/cases/web/flow360_singleSlidingInterface-steady.json rename to tests/v1/data/cases/web/flow360_singleSlidingInterface-steady.json diff --git a/tests/data/cases/web/periodic_boundary_condition_tu_berlin_stator_flow360.json b/tests/v1/data/cases/web/periodic_boundary_condition_tu_berlin_stator_flow360.json similarity index 100% rename from tests/data/cases/web/periodic_boundary_condition_tu_berlin_stator_flow360.json rename to tests/v1/data/cases/web/periodic_boundary_condition_tu_berlin_stator_flow360.json diff --git a/tests/data/cases/web/s809Case.json b/tests/v1/data/cases/web/s809Case.json similarity index 100% rename from tests/data/cases/web/s809Case.json rename to tests/v1/data/cases/web/s809Case.json diff --git a/tests/data/cylinder.cgns b/tests/v1/data/cylinder.cgns similarity index 100% rename from tests/data/cylinder.cgns rename to tests/v1/data/cylinder.cgns diff --git a/tests/data/examples/release-22.1.2.0gt/keep b/tests/v1/data/examples/release-22.1.2.0gt/keep similarity index 100% rename from tests/data/examples/release-22.1.2.0gt/keep rename to tests/v1/data/examples/release-22.1.2.0gt/keep diff --git a/tests/data/examples/release-22.1.3.0ge/keep b/tests/v1/data/examples/release-22.1.3.0ge/keep similarity index 100% rename from tests/data/examples/release-22.1.3.0ge/keep rename to tests/v1/data/examples/release-22.1.3.0ge/keep diff --git a/tests/data/examples/release-22.1.3.2/keep b/tests/v1/data/examples/release-22.1.3.2/keep similarity index 100% rename from tests/data/examples/release-22.1.3.2/keep rename to tests/v1/data/examples/release-22.1.3.2/keep diff --git a/tests/data/examples/release-22.2.3.0le/keep b/tests/v1/data/examples/release-22.2.3.0le/keep similarity index 100% rename from tests/data/examples/release-22.2.3.0le/keep rename to tests/v1/data/examples/release-22.2.3.0le/keep diff --git a/tests/data/examples/release-22.3.3.0lt/keep b/tests/v1/data/examples/release-22.3.3.0lt/keep similarity index 100% rename from tests/data/examples/release-22.3.3.0lt/keep rename to tests/v1/data/examples/release-22.3.3.0lt/keep diff --git a/tests/data/examples/release-23.1.3.0/keep b/tests/v1/data/examples/release-23.1.3.0/keep similarity index 100% rename from tests/data/examples/release-23.1.3.0/keep rename to tests/v1/data/examples/release-23.1.3.0/keep diff --git a/tests/data/surface_mesh/airplaneGeometry.stl b/tests/v1/data/surface_mesh/airplaneGeometry.stl similarity index 100% rename from tests/data/surface_mesh/airplaneGeometry.stl rename to tests/v1/data/surface_mesh/airplaneGeometry.stl diff --git a/tests/data/surface_mesh/test.csm b/tests/v1/data/surface_mesh/test.csm similarity index 100% rename from tests/data/surface_mesh/test.csm rename to tests/v1/data/surface_mesh/test.csm diff --git a/tests/data/volume_mesh/cylinder.cgns b/tests/v1/data/volume_mesh/cylinder.cgns similarity index 100% rename from tests/data/volume_mesh/cylinder.cgns rename to tests/v1/data/volume_mesh/cylinder.cgns diff --git a/tests/data/volume_mesh/cylinder_case.json b/tests/v1/data/volume_mesh/cylinder_case.json similarity index 100% rename from tests/data/volume_mesh/cylinder_case.json rename to tests/v1/data/volume_mesh/cylinder_case.json diff --git a/tests/data/volume_mesh/cylinder_mesh.json b/tests/v1/data/volume_mesh/cylinder_mesh.json similarity index 100% rename from tests/data/volume_mesh/cylinder_mesh.json rename to tests/v1/data/volume_mesh/cylinder_mesh.json diff --git a/tests/data/volume_mesh/wing_tetra_mesh.json b/tests/v1/data/volume_mesh/wing_tetra_mesh.json similarity index 100% rename from tests/data/volume_mesh/wing_tetra_mesh.json rename to tests/v1/data/volume_mesh/wing_tetra_mesh.json diff --git a/tests/params/test_freestream.py b/tests/v1/params/test_freestream.py similarity index 97% rename from tests/params/test_freestream.py rename to tests/v1/params/test_freestream.py index bc9319ff0..0d037d98e 100644 --- a/tests/params/test_freestream.py +++ b/tests/v1/params/test_freestream.py @@ -4,9 +4,9 @@ import pydantic.v1 as pd import pytest -import flow360 as fl -from flow360 import units as u -from flow360.component.flow360_params.flow360_params import ( +import flow360.component.v1 as fl +from flow360.component.v1 import units as u +from flow360.component.v1.flow360_params import ( FreestreamFromMach, FreestreamFromMachReynolds, FreestreamFromVelocity, diff --git a/tests/params/test_initial_condition.py b/tests/v1/params/test_initial_condition.py similarity index 90% rename from tests/params/test_initial_condition.py rename to tests/v1/params/test_initial_condition.py index 53c88b02b..4620f16a8 100644 --- a/tests/params/test_initial_condition.py +++ b/tests/v1/params/test_initial_condition.py @@ -2,10 +2,8 @@ import pytest -import flow360 as fl -from flow360.component.flow360_params.initial_condition import ( - ExpressionInitialCondition, -) +import flow360.component.v1 as fl +from flow360.component.v1.initial_condition import ExpressionInitialCondition from tests.utils import to_file_from_file_test assertions = unittest.TestCase("__init__") diff --git a/tests/params/test_outputs.py b/tests/v1/params/test_outputs.py similarity index 92% rename from tests/params/test_outputs.py rename to tests/v1/params/test_outputs.py index 56203f850..8e8eb2bc7 100644 --- a/tests/params/test_outputs.py +++ b/tests/v1/params/test_outputs.py @@ -5,9 +5,9 @@ import pytest import unyt -import flow360 -import flow360.component.flow360_params.units as u -from flow360.component.flow360_params.flow360_output import ( +import flow360.component.v1 as v1 +import flow360.component.v1.units as u +from flow360.component.v1.flow360_output import ( IsoSurface, IsoSurfaceOutput, MonitorOutput, @@ -19,7 +19,7 @@ UserDefinedField, VolumeOutput, ) -from flow360.component.flow360_params.flow360_params import ( +from flow360.component.v1.flow360_params import ( AeroacousticOutput, Flow360Params, FreestreamFromMach, @@ -99,7 +99,7 @@ def test_surface_output(): output_fields=["Cp", "qcriterion"], ) - with flow360.SI_unit_system: + with v1.SI_unit_system: params = Flow360Params( surface_output=SurfaceOutput( output_fields=["Cp"], @@ -107,9 +107,9 @@ def test_surface_output(): output_format="both", ), boundaries={ - "1": flow360.NoSlipWall(name="wing"), - "2": flow360.SlipWall(name="symmetry"), - "3": flow360.FreestreamBoundary(name="freestream"), + "1": v1.NoSlipWall(name="wing"), + "2": v1.SlipWall(name="symmetry"), + "3": v1.FreestreamBoundary(name="freestream"), }, freestream=FreestreamFromMach(Mach=1, temperature=1, mu_ref=1), ) @@ -125,7 +125,7 @@ def test_surface_output(): else: assert surface_item["output_fields"] == ["Cp"] - with flow360.SI_unit_system: + with v1.SI_unit_system: params = Flow360Params( surface_output=SurfaceOutput( output_fields=["Cp", "solutionTurbulence", "nuHat"], @@ -133,9 +133,9 @@ def test_surface_output(): output_format="tecplot", ), boundaries={ - "1": flow360.NoSlipWall(name="wing"), - "2": flow360.SlipWall(name="symmetry"), - "3": flow360.FreestreamBoundary(name="freestream"), + "1": v1.NoSlipWall(name="wing"), + "2": v1.SlipWall(name="symmetry"), + "3": v1.FreestreamBoundary(name="freestream"), }, freestream=FreestreamFromMach(Mach=1, temperature=1, mu_ref=1), ) @@ -163,11 +163,11 @@ def test_slice_output(): output = SliceOutput( output_fields=["Cp", "qcriterion"], slices={ - "sliceName_1": flow360.Slice( + "sliceName_1": v1.Slice( slice_normal=(0, 1, 0), slice_origin=(0, 0.56413, 0) * u.m, ), - "sliceName_2": flow360.Slice( + "sliceName_2": v1.Slice( slice_normal=(0, 0, 1), slice_origin=(0, 0.56413 * u.inch, 0), output_fields=["Mach"], @@ -178,11 +178,11 @@ def test_slice_output(): output = SliceOutput( output_fields=["Cp", "qcriterion"], slices={ - "sliceName_1": flow360.Slice( + "sliceName_1": v1.Slice( slice_normal=(0, 1, 0), slice_origin=(0, 0.56413, 0) * u.m, ), - "sliceName_2": flow360.Slice( + "sliceName_2": v1.Slice( slice_normal=(0, 0, 1), slice_origin=(0, 0.56413, 0) * u.inch, output_fields=["Mach"], @@ -196,7 +196,7 @@ def test_slice_output(): output = SliceOutput( output_fields=["Cp", "qcriterion"], slices={ - "sliceName_1": flow360.Slice( + "sliceName_1": v1.Slice( slice_normal={0, 1}, slice_origin=(0, 0.56413, 0) * u.m, ) @@ -207,7 +207,7 @@ def test_slice_output(): output = SliceOutput( output_fields=["Cp", "qcriterion"], slices={ - "sliceName_1": flow360.Slice( + "sliceName_1": v1.Slice( slice_normal=(0, 1, 0), slice_origin={0, 0.56413} * u.m, ) @@ -217,11 +217,11 @@ def test_slice_output(): output = SliceOutput( output_fields=["Cp", "qcriterion"], slices={ - "sliceName_1": flow360.Slice( + "sliceName_1": v1.Slice( slice_normal=[0, 1, 0], slice_origin=(0, 0.56413, 0) * u.flow360_length_unit, ), - "sliceName_2": flow360.Slice( + "sliceName_2": v1.Slice( slice_normal=(0, 0, 1), slice_origin=(0, 0.56413, 0) * u.inch, output_fields=["Mach"], @@ -234,7 +234,7 @@ def test_slice_output(): to_file_from_file_test(output) output.output_format = "both" - with flow360.SI_unit_system: + with v1.SI_unit_system: params = Flow360Params( slice_output=output, boundaries={}, @@ -251,7 +251,7 @@ def test_slice_output(): else: assert {"Cp", "qcriterion"} == set(slice_item["output_fields"]) - with flow360.SI_unit_system: + with v1.SI_unit_system: params = Flow360Params( slice_output=SliceOutput( output_fields=[ @@ -261,11 +261,11 @@ def test_slice_output(): "solutionTurbulence", ], slices={ - "sliceName_1": flow360.Slice( + "sliceName_1": v1.Slice( slice_normal=[5, 1, 0], slice_origin=(0, 0.56413, 0) * u.flow360_length_unit, ), - "sliceName_2": flow360.Slice( + "sliceName_2": v1.Slice( slice_normal=(0, 1, 1), slice_origin=(0, 0.56413, 0) * u.inch, output_fields=["Mach"], @@ -337,7 +337,7 @@ def test_volume_output(): output.output_format = "both" - with flow360.SI_unit_system: + with v1.SI_unit_system: params = Flow360Params( volume_output=output, boundaries={}, @@ -347,7 +347,7 @@ def test_volume_output(): assert set(solver_params.volume_output.output_fields) == {"Cp", "qcriterion"} - with flow360.SI_unit_system: + with v1.SI_unit_system: """ Test addition of betMetrics/betMetricsPerDisk from slice output field """ @@ -356,11 +356,11 @@ def test_volume_output(): slice_output=SliceOutput( output_fields=["betMetrics"], slices={ - "sliceName_1": flow360.Slice( + "sliceName_1": v1.Slice( slice_normal=(0, 1, 0), slice_origin=(0, 0.56413, 0) * u.m, ), - "sliceName_2": flow360.Slice( + "sliceName_2": v1.Slice( slice_normal=(0, 1, 0), slice_origin=(50, 0.56413, 0) * u.m, output_fields=["betMetricsPerDisk"], @@ -383,7 +383,7 @@ def test_volume_output(): } output.output_fields = ["qcriterion", "Cp", "solutionTurbulence", "kOmega"] - with flow360.SI_unit_system: + with v1.SI_unit_system: """ Test removing duplicate output fields """ @@ -432,7 +432,7 @@ def test_iso_surface_output(): output.output_format = "both" - with flow360.SI_unit_system: + with v1.SI_unit_system: params = Flow360Params( iso_surface_output=output, boundaries={}, @@ -451,7 +451,7 @@ def test_iso_surface_output(): else: assert {"Mach"} == set(iso_surface_item["output_fields"]) - with flow360.SI_unit_system: + with v1.SI_unit_system: params = Flow360Params( iso_surface_output=IsoSurfaceOutput( output_fields=["Mach", "kOmega", "solutionTurbulence"], @@ -505,7 +505,7 @@ def test_monitor_output(): to_file_from_file_test(output) - with flow360.SI_unit_system: + with v1.SI_unit_system: params = Flow360Params( monitor_output=output, boundaries={}, @@ -523,7 +523,7 @@ def test_monitor_output(): else: assert {"Cp", "qcriterion", "Mach"} == set(monitor_item["output_fields"]) - with flow360.SI_unit_system: + with v1.SI_unit_system: params = Flow360Params( monitor_output=MonitorOutput( output_fields=["Cp", "solutionTurbulence", "kOmega"], @@ -548,7 +548,7 @@ def test_monitor_output(): def test_output_fields(): - with flow360.SI_unit_system: + with v1.SI_unit_system: params = Flow360Params( geometry=Geometry(mesh_unit=1), volume_output=VolumeOutput(output_fields=["Cp", "qcriterion", "my_var"]), @@ -556,7 +556,7 @@ def test_output_fields(): slice_output=SliceOutput( output_fields=["primitiveVars", "my_var", "mutRatio"], slices={ - "sliceName_1": flow360.Slice( + "sliceName_1": v1.Slice( slice_normal=[5, 1, 0], slice_origin=(0, 1.56413, 0), output_fields=["Mach"] ), }, @@ -598,7 +598,7 @@ def test_output_fields(): with pytest.raises( pd.ValidationError, match=r"surface_output:, prmitiveVars is not valid output field name." ): - with flow360.SI_unit_system: + with v1.SI_unit_system: Flow360Params( surface_output=SurfaceOutput(output_fields=["prmitiveVars", "my_var"]), boundaries={}, @@ -609,7 +609,7 @@ def test_output_fields(): with pytest.raises( pd.ValidationError, match=r"surface_output->wing:, my__var is not valid output field name." ): - with flow360.SI_unit_system: + with v1.SI_unit_system: Flow360Params( surface_output=SurfaceOutput( output_fields=["primitiveVars", "my__var"], diff --git a/tests/params/test_params_boundary.py b/tests/v1/params/test_params_boundary.py similarity index 98% rename from tests/params/test_params_boundary.py rename to tests/v1/params/test_params_boundary.py index 0b90f988b..0eb87ce50 100644 --- a/tests/params/test_params_boundary.py +++ b/tests/v1/params/test_params_boundary.py @@ -3,8 +3,8 @@ import pydantic.v1 as pd import pytest -import flow360 as fl -from flow360.component.flow360_params.boundaries import ( +import flow360.component.v1 as fl +from flow360.component.v1.boundaries import ( FreestreamBoundary, HeatFluxWall, IsothermalWall, @@ -20,13 +20,13 @@ SubsonicOutflowPressure, WallFunction, ) -from flow360.component.flow360_params.flow360_params import ( +from flow360.component.v1.flow360_params import ( Flow360Params, FreestreamFromMach, MeshBoundary, SteadyTimeStepping, ) -from flow360.component.flow360_params.turbulence_quantities import TurbulenceQuantities +from flow360.component.v1.turbulence_quantities import TurbulenceQuantities from tests.utils import compare_to_ref, to_file_from_file_test assertions = unittest.TestCase("__init__") diff --git a/tests/params/test_porous_media.py b/tests/v1/params/test_porous_media.py similarity index 85% rename from tests/params/test_porous_media.py rename to tests/v1/params/test_porous_media.py index 5605f6cfa..d5fd557b6 100644 --- a/tests/params/test_porous_media.py +++ b/tests/v1/params/test_porous_media.py @@ -2,8 +2,8 @@ import pytest -from flow360 import SI_unit_system -from flow360.component.flow360_params.flow360_params import PorousMediumBox +from flow360.component.v1 import SI_unit_system +from flow360.component.v1.flow360_params import PorousMediumBox from tests.utils import to_file_from_file_test assertions = unittest.TestCase("__init__") diff --git a/tests/params/test_preconditioner.py b/tests/v1/params/test_preconditioner.py similarity index 83% rename from tests/params/test_preconditioner.py rename to tests/v1/params/test_preconditioner.py index a66eb4c62..26f00bd6f 100644 --- a/tests/params/test_preconditioner.py +++ b/tests/v1/params/test_preconditioner.py @@ -4,9 +4,9 @@ import pydantic.v1 as pd import pytest -import flow360 as fl -from flow360 import units as u -from flow360.component.flow360_params.flow360_params import FreestreamFromVelocity +import flow360.component.v1 as fl +from flow360.component.v1 import units as u +from flow360.component.v1.flow360_params import FreestreamFromVelocity assertions = unittest.TestCase("__init__") diff --git a/tests/params/test_reference_frame.py b/tests/v1/params/test_reference_frame.py similarity index 96% rename from tests/params/test_reference_frame.py rename to tests/v1/params/test_reference_frame.py index dd1c4a873..87861a7f2 100644 --- a/tests/params/test_reference_frame.py +++ b/tests/v1/params/test_reference_frame.py @@ -3,8 +3,8 @@ import numpy as np import pytest -import flow360 as fl -from flow360 import units as u +import flow360.component.v1 as fl +from flow360.component.v1 import units as u assertions = unittest.TestCase("__init__") diff --git a/tests/params/test_rotational_models.py b/tests/v1/params/test_rotational_models.py similarity index 97% rename from tests/params/test_rotational_models.py rename to tests/v1/params/test_rotational_models.py index 42e42fa74..3df57b8a2 100644 --- a/tests/params/test_rotational_models.py +++ b/tests/v1/params/test_rotational_models.py @@ -3,8 +3,8 @@ import numpy as np import pytest -import flow360 as fl -from flow360.component.flow360_params.flow360_params import ( +import flow360.component.v1 as fl +from flow360.component.v1.flow360_params import ( ActuatorDisk, BETDisk, BETDiskChord, diff --git a/tests/params/test_sliding_interfaces.py b/tests/v1/params/test_sliding_interfaces.py similarity index 95% rename from tests/params/test_sliding_interfaces.py rename to tests/v1/params/test_sliding_interfaces.py index 816d42bde..b131a3bde 100644 --- a/tests/params/test_sliding_interfaces.py +++ b/tests/v1/params/test_sliding_interfaces.py @@ -2,10 +2,7 @@ import pytest -from flow360.component.flow360_params.flow360_params import ( - MeshSlidingInterface, - SlidingInterface, -) +from flow360.component.v1.flow360_params import MeshSlidingInterface, SlidingInterface from tests.utils import compare_to_ref, to_file_from_file_test assertions = unittest.TestCase("__init__") diff --git a/tests/params/test_solvers.py b/tests/v1/params/test_solvers.py similarity index 98% rename from tests/params/test_solvers.py rename to tests/v1/params/test_solvers.py index 6e3641693..8f30ab59b 100644 --- a/tests/params/test_solvers.py +++ b/tests/v1/params/test_solvers.py @@ -3,13 +3,13 @@ import pydantic.v1 as pd import pytest -import flow360 as fl -from flow360.component.flow360_params.flow360_params import ( +import flow360.component.v1 as fl +from flow360.component.v1.flow360_params import ( Flow360Params, HeatEquationSolver, TransitionModelSolver, ) -from flow360.component.flow360_params.solvers import ( +from flow360.component.v1.solvers import ( HEAT_EQUATION_EVAL_FREQUENCY_STEADY, KOmegaSST, LinearSolver, diff --git a/tests/params/test_time_stepping.py b/tests/v1/params/test_time_stepping.py similarity index 95% rename from tests/params/test_time_stepping.py rename to tests/v1/params/test_time_stepping.py index 1457d2b46..60e493c34 100644 --- a/tests/params/test_time_stepping.py +++ b/tests/v1/params/test_time_stepping.py @@ -4,15 +4,15 @@ import pydantic.v1 as pd import pytest -import flow360 as fl -from flow360 import units as u -from flow360.component.flow360_params.flow360_params import ( +import flow360.component.v1 as fl +from flow360.component.v1 import units as u +from flow360.component.v1.flow360_params import ( Flow360Params, FreestreamFromVelocity, Geometry, SteadyTimeStepping, ) -from flow360.component.flow360_params.time_stepping import UnsteadyTimeStepping +from flow360.component.v1.time_stepping import UnsteadyTimeStepping from tests.utils import to_file_from_file_test assertions = unittest.TestCase("__init__") diff --git a/tests/params/test_user_defined_dynamics.py b/tests/v1/params/test_user_defined_dynamics.py similarity index 95% rename from tests/params/test_user_defined_dynamics.py rename to tests/v1/params/test_user_defined_dynamics.py index 547685ec0..6b201fde8 100644 --- a/tests/params/test_user_defined_dynamics.py +++ b/tests/v1/params/test_user_defined_dynamics.py @@ -2,8 +2,8 @@ import pytest -import flow360 as fl -from flow360.component.flow360_params.flow360_params import UserDefinedDynamic +import flow360.component.v1 as fl +from flow360.component.v1.flow360_params import UserDefinedDynamic from tests.utils import to_file_from_file_test assertions = unittest.TestCase("__init__") diff --git a/tests/params/test_validator_aeroacoustics.py b/tests/v1/params/test_validator_aeroacoustics.py similarity index 76% rename from tests/params/test_validator_aeroacoustics.py rename to tests/v1/params/test_validator_aeroacoustics.py index df1ae082a..845ec0abe 100644 --- a/tests/params/test_validator_aeroacoustics.py +++ b/tests/v1/params/test_validator_aeroacoustics.py @@ -2,13 +2,10 @@ import pytest -import flow360 as fl -from flow360.component.flow360_params.boundaries import ( - NoSlipWall, - TranslationallyPeriodic, -) -from flow360.component.flow360_params.flow360_output import AeroacousticOutput -from flow360.component.flow360_params.flow360_params import Flow360Params +import flow360.component.v1 as fl +from flow360.component.v1.boundaries import NoSlipWall, TranslationallyPeriodic +from flow360.component.v1.flow360_output import AeroacousticOutput +from flow360.component.v1.flow360_params import Flow360Params assertions = unittest.TestCase("__init__") diff --git a/tests/params/test_validator_bet_disks.py b/tests/v1/params/test_validator_bet_disks.py similarity index 99% rename from tests/params/test_validator_bet_disks.py rename to tests/v1/params/test_validator_bet_disks.py index c86bc8209..b5643e9b7 100644 --- a/tests/params/test_validator_bet_disks.py +++ b/tests/v1/params/test_validator_bet_disks.py @@ -3,8 +3,8 @@ import pytest -import flow360 as fl -from flow360.component.flow360_params.flow360_params import ( +import flow360.component.v1 as fl +from flow360.component.v1.flow360_params import ( BETDisk, BETDiskChord, BETDiskSectionalPolar, diff --git a/tests/params/test_validator_boundary.py b/tests/v1/params/test_validator_boundary.py similarity index 88% rename from tests/params/test_validator_boundary.py rename to tests/v1/params/test_validator_boundary.py index 954c79add..4028b3a3d 100644 --- a/tests/params/test_validator_boundary.py +++ b/tests/v1/params/test_validator_boundary.py @@ -2,9 +2,9 @@ import pytest -import flow360 as fl -from flow360.component.flow360_params.boundaries import NoSlipWall -from flow360.component.flow360_params.flow360_params import Flow360Params +import flow360.component.v1 as fl +from flow360.component.v1.boundaries import NoSlipWall +from flow360.component.v1.flow360_params import Flow360Params assertions = unittest.TestCase("__init__") diff --git a/tests/params/test_validator_cht_solver.py b/tests/v1/params/test_validator_cht_solver.py similarity index 94% rename from tests/params/test_validator_cht_solver.py rename to tests/v1/params/test_validator_cht_solver.py index b0dca6272..f0b9c0994 100644 --- a/tests/params/test_validator_cht_solver.py +++ b/tests/v1/params/test_validator_cht_solver.py @@ -2,13 +2,10 @@ import pytest -import flow360 as fl -from flow360 import units as u -from flow360.component.flow360_params.boundaries import ( - SolidAdiabaticWall, - SolidIsothermalWall, -) -from flow360.component.flow360_params.flow360_output import ( +import flow360.component.v1 as fl +from flow360.component.v1 import units as u +from flow360.component.v1.boundaries import SolidAdiabaticWall, SolidIsothermalWall +from flow360.component.v1.flow360_output import ( IsoSurface, IsoSurfaceOutput, MonitorOutput, @@ -16,16 +13,14 @@ SurfaceOutput, VolumeOutput, ) -from flow360.component.flow360_params.flow360_params import Flow360Params -from flow360.component.flow360_params.initial_condition import ( - ExpressionInitialCondition, -) -from flow360.component.flow360_params.solvers import ( +from flow360.component.v1.flow360_params import Flow360Params +from flow360.component.v1.initial_condition import ExpressionInitialCondition +from flow360.component.v1.solvers import ( HeatEquationSolver, IncompressibleNavierStokesSolver, ) -from flow360.component.flow360_params.time_stepping import UnsteadyTimeStepping -from flow360.component.flow360_params.volume_zones import ( +from flow360.component.v1.time_stepping import UnsteadyTimeStepping +from flow360.component.v1.volume_zones import ( FluidDynamicsVolumeZone, HeatTransferVolumeZone, InitialConditionHeatTransfer, diff --git a/tests/params/test_validator_consistency_ddes_unsteady.py b/tests/v1/params/test_validator_consistency_ddes_unsteady.py similarity index 85% rename from tests/params/test_validator_consistency_ddes_unsteady.py rename to tests/v1/params/test_validator_consistency_ddes_unsteady.py index 44c814ab5..d268fcbb0 100644 --- a/tests/params/test_validator_consistency_ddes_unsteady.py +++ b/tests/v1/params/test_validator_consistency_ddes_unsteady.py @@ -2,14 +2,11 @@ import pytest -import flow360 as fl -from flow360 import units as u -from flow360.component.flow360_params.flow360_params import ( - Flow360Params, - SteadyTimeStepping, -) -from flow360.component.flow360_params.solvers import SpalartAllmaras -from flow360.component.flow360_params.time_stepping import UnsteadyTimeStepping +import flow360.component.v1 as fl +from flow360.component.v1 import units as u +from flow360.component.v1.flow360_params import Flow360Params, SteadyTimeStepping +from flow360.component.v1.solvers import SpalartAllmaras +from flow360.component.v1.time_stepping import UnsteadyTimeStepping assertions = unittest.TestCase("__init__") diff --git a/tests/params/test_validator_equation_eval_frequency.py b/tests/v1/params/test_validator_equation_eval_frequency.py similarity index 87% rename from tests/params/test_validator_equation_eval_frequency.py rename to tests/v1/params/test_validator_equation_eval_frequency.py index 25ad3b712..06152ae89 100644 --- a/tests/params/test_validator_equation_eval_frequency.py +++ b/tests/v1/params/test_validator_equation_eval_frequency.py @@ -2,17 +2,11 @@ import pytest -import flow360 as fl -from flow360 import units as u -from flow360.component.flow360_params.flow360_params import ( - Flow360Params, - SteadyTimeStepping, -) -from flow360.component.flow360_params.solvers import ( - SpalartAllmaras, - TransitionModelSolver, -) -from flow360.component.flow360_params.time_stepping import UnsteadyTimeStepping +import flow360.component.v1 as fl +from flow360.component.v1 import units as u +from flow360.component.v1.flow360_params import Flow360Params, SteadyTimeStepping +from flow360.component.v1.solvers import SpalartAllmaras, TransitionModelSolver +from flow360.component.v1.time_stepping import UnsteadyTimeStepping assertions = unittest.TestCase("__init__") diff --git a/tests/params/test_validator_output_consistency.py b/tests/v1/params/test_validator_output_consistency.py similarity index 83% rename from tests/params/test_validator_output_consistency.py rename to tests/v1/params/test_validator_output_consistency.py index 8da85dcbd..57ae0d666 100644 --- a/tests/params/test_validator_output_consistency.py +++ b/tests/v1/params/test_validator_output_consistency.py @@ -2,14 +2,10 @@ import pytest -import flow360 as fl -from flow360.component.flow360_params.boundaries import ( - FreestreamBoundary, - NoSlipWall, - WallFunction, -) -from flow360.component.flow360_params.flow360_output import SurfaceOutput -from flow360.component.flow360_params.flow360_params import Flow360Params +import flow360.component.v1 as fl +from flow360.component.v1.boundaries import FreestreamBoundary, NoSlipWall, WallFunction +from flow360.component.v1.flow360_output import SurfaceOutput +from flow360.component.v1.flow360_params import Flow360Params assertions = unittest.TestCase("__init__") diff --git a/tests/params/test_validator_periodic_mapping.py b/tests/v1/params/test_validator_periodic_mapping.py similarity index 97% rename from tests/params/test_validator_periodic_mapping.py rename to tests/v1/params/test_validator_periodic_mapping.py index eb24f785d..9efdd6472 100644 --- a/tests/params/test_validator_periodic_mapping.py +++ b/tests/v1/params/test_validator_periodic_mapping.py @@ -2,13 +2,13 @@ import pytest -import flow360 as fl -from flow360.component.flow360_params.boundaries import ( +import flow360.component.v1 as fl +from flow360.component.v1.boundaries import ( NoSlipWall, RotationallyPeriodic, TranslationallyPeriodic, ) -from flow360.component.flow360_params.flow360_params import Flow360Params +from flow360.component.v1.flow360_params import Flow360Params assertions = unittest.TestCase("__init__") diff --git a/tests/params/test_volume_zones.py b/tests/v1/params/test_volume_zones.py similarity index 97% rename from tests/params/test_volume_zones.py rename to tests/v1/params/test_volume_zones.py index 1312619cf..ae6c5e129 100644 --- a/tests/params/test_volume_zones.py +++ b/tests/v1/params/test_volume_zones.py @@ -4,9 +4,9 @@ import pydantic.v1 as pd import pytest -import flow360 as fl -from flow360.component.flow360_params.flow360_params import VolumeZones -from flow360.component.flow360_params.volume_zones import ( +import flow360.component.v1 as fl +from flow360.component.v1.flow360_params import VolumeZones +from flow360.component.v1.volume_zones import ( FluidDynamicsVolumeZone, HeatTransferVolumeZone, InitialConditionHeatTransfer, diff --git a/tests/ref/case_params/actuator_disk/json.json b/tests/v1/ref/case_params/actuator_disk/json.json similarity index 100% rename from tests/ref/case_params/actuator_disk/json.json rename to tests/v1/ref/case_params/actuator_disk/json.json diff --git a/tests/ref/case_params/actuator_disk/yaml.yaml b/tests/v1/ref/case_params/actuator_disk/yaml.yaml similarity index 100% rename from tests/ref/case_params/actuator_disk/yaml.yaml rename to tests/v1/ref/case_params/actuator_disk/yaml.yaml diff --git a/tests/ref/case_params/boundaries/json.json b/tests/v1/ref/case_params/boundaries/json.json similarity index 100% rename from tests/ref/case_params/boundaries/json.json rename to tests/v1/ref/case_params/boundaries/json.json diff --git a/tests/ref/case_params/boundaries/yaml.yaml b/tests/v1/ref/case_params/boundaries/yaml.yaml similarity index 100% rename from tests/ref/case_params/boundaries/yaml.yaml rename to tests/v1/ref/case_params/boundaries/yaml.yaml diff --git a/tests/ref/case_params/heat_equation/ref.json b/tests/v1/ref/case_params/heat_equation/ref.json similarity index 100% rename from tests/ref/case_params/heat_equation/ref.json rename to tests/v1/ref/case_params/heat_equation/ref.json diff --git a/tests/ref/case_params/params.json b/tests/v1/ref/case_params/params.json similarity index 100% rename from tests/ref/case_params/params.json rename to tests/v1/ref/case_params/params.json diff --git a/tests/ref/case_params/params.yaml b/tests/v1/ref/case_params/params.yaml similarity index 100% rename from tests/ref/case_params/params.yaml rename to tests/v1/ref/case_params/params.yaml diff --git a/tests/ref/case_params/params_units.json b/tests/v1/ref/case_params/params_units.json similarity index 100% rename from tests/ref/case_params/params_units.json rename to tests/v1/ref/case_params/params_units.json diff --git a/tests/ref/case_params/params_units_converted.json b/tests/v1/ref/case_params/params_units_converted.json similarity index 100% rename from tests/ref/case_params/params_units_converted.json rename to tests/v1/ref/case_params/params_units_converted.json diff --git a/tests/ref/case_params/params_units_solver.json b/tests/v1/ref/case_params/params_units_solver.json similarity index 100% rename from tests/ref/case_params/params_units_solver.json rename to tests/v1/ref/case_params/params_units_solver.json diff --git a/tests/ref/case_params/sliding_interface/json.json b/tests/v1/ref/case_params/sliding_interface/json.json similarity index 100% rename from tests/ref/case_params/sliding_interface/json.json rename to tests/v1/ref/case_params/sliding_interface/json.json diff --git a/tests/ref/case_params/sliding_interface/yaml.yaml b/tests/v1/ref/case_params/sliding_interface/yaml.yaml similarity index 100% rename from tests/ref/case_params/sliding_interface/yaml.yaml rename to tests/v1/ref/case_params/sliding_interface/yaml.yaml diff --git a/tests/ref/flow360mesh/eg1.json b/tests/v1/ref/flow360mesh/eg1.json similarity index 100% rename from tests/ref/flow360mesh/eg1.json rename to tests/v1/ref/flow360mesh/eg1.json diff --git a/tests/ref/flow360mesh/eg2.json b/tests/v1/ref/flow360mesh/eg2.json similarity index 100% rename from tests/ref/flow360mesh/eg2.json rename to tests/v1/ref/flow360mesh/eg2.json diff --git a/tests/ref/flow360mesh/eg3.json b/tests/v1/ref/flow360mesh/eg3.json similarity index 100% rename from tests/ref/flow360mesh/eg3.json rename to tests/v1/ref/flow360mesh/eg3.json diff --git a/tests/ref/flow360mesh/mesh_boundary/json.json b/tests/v1/ref/flow360mesh/mesh_boundary/json.json similarity index 100% rename from tests/ref/flow360mesh/mesh_boundary/json.json rename to tests/v1/ref/flow360mesh/mesh_boundary/json.json diff --git a/tests/ref/flow360mesh/mesh_boundary/yaml.yaml b/tests/v1/ref/flow360mesh/mesh_boundary/yaml.yaml similarity index 100% rename from tests/ref/flow360mesh/mesh_boundary/yaml.yaml rename to tests/v1/ref/flow360mesh/mesh_boundary/yaml.yaml diff --git a/tests/ref/meshing_params/ref.json b/tests/v1/ref/meshing_params/ref.json similarity index 100% rename from tests/ref/meshing_params/ref.json rename to tests/v1/ref/meshing_params/ref.json diff --git a/tests/ref/meshing_params/ref.yaml b/tests/v1/ref/meshing_params/ref.yaml similarity index 100% rename from tests/ref/meshing_params/ref.yaml rename to tests/v1/ref/meshing_params/ref.yaml diff --git a/tests/test_base_model.py b/tests/v1/test_base_model.py similarity index 87% rename from tests/test_base_model.py rename to tests/v1/test_base_model.py index abe0e2d2c..bd8bbfaa9 100644 --- a/tests/test_base_model.py +++ b/tests/v1/test_base_model.py @@ -1,4 +1,4 @@ -from flow360.component.flow360_params.params_base import Flow360BaseModel +from flow360.component.v1.params_base import Flow360BaseModel def test_help(): diff --git a/tests/test_case.py b/tests/v1/test_case.py similarity index 98% rename from tests/test_case.py rename to tests/v1/test_case.py index 55b2c1a04..4b775a6a0 100644 --- a/tests/test_case.py +++ b/tests/v1/test_case.py @@ -1,6 +1,6 @@ import pytest -from flow360 import ( +from flow360.component.v1 import ( Case, Flow360Params, FreestreamFromVelocity, diff --git a/tests/test_case_webapi.py b/tests/v1/test_case_webapi.py similarity index 94% rename from tests/test_case_webapi.py rename to tests/v1/test_case_webapi.py index f2a0f88ab..9e633f4f8 100644 --- a/tests/test_case_webapi.py +++ b/tests/v1/test_case_webapi.py @@ -1,6 +1,6 @@ import pytest -from flow360 import Case +from flow360.component.v1 import Case from flow360.exceptions import Flow360RuntimeError from flow360.log import Logger, log diff --git a/tests/test_dev_flow360_params.py b/tests/v1/test_dev_flow360_params.py similarity index 90% rename from tests/test_dev_flow360_params.py rename to tests/v1/test_dev_flow360_params.py index d3d396279..318212f8c 100644 --- a/tests/test_dev_flow360_params.py +++ b/tests/v1/test_dev_flow360_params.py @@ -2,9 +2,9 @@ import pytest -import flow360 as fl +import flow360.component.v1 as fl -from .utils import compare_to_ref, to_file_from_file_test +from ..utils import compare_to_ref, to_file_from_file_test fl.UserConfig.disable_validation() # fl.Flow360Params = fl.component.flow360_params.flow360_params.UnvalidatedFlow360Params diff --git a/tests/test_examples.py b/tests/v1/test_examples.py similarity index 94% rename from tests/test_examples.py rename to tests/v1/test_examples.py index 338b0bcbf..6082e35fe 100644 --- a/tests/test_examples.py +++ b/tests/v1/test_examples.py @@ -2,8 +2,7 @@ import pytest -import flow360 -from flow360.examples import Airplane, Cylinder2D, OM6wing +from flow360.examples import Airplane, Cylinder2D, OM6wing, base_test_case from flow360.examples.base_test_case import BaseTestCase @@ -52,7 +51,7 @@ class TestCase(BaseTestCase): class url: case_json = "local://flow360.json" - flow360.examples.base_test_case.here = os.path.dirname(os.path.abspath(__file__)) + base_test_case.here = os.path.dirname(os.path.abspath(__file__)) TestCase.set_version("release-23.1.3.0") assert TestCase._get_version_prefix() == "release-23.1.3.0" diff --git a/tests/test_flow360_params.py b/tests/v1/test_flow360_params.py similarity index 98% rename from tests/test_flow360_params.py rename to tests/v1/test_flow360_params.py index 22cd5e1f0..d32535df8 100644 --- a/tests/test_flow360_params.py +++ b/tests/v1/test_flow360_params.py @@ -5,19 +5,19 @@ import pydantic.v1 as pd import pytest -import flow360 as fl -from flow360 import units as u -from flow360.component.flow360_params.flow360_params import ( +import flow360.component.v1 as fl +from flow360.component.v1 import units as u +from flow360.component.v1.flow360_params import ( Flow360MeshParams, Flow360Params, FreestreamFromVelocity, MeshBoundary, PorousMediumBox, ) -from flow360.component.flow360_params.time_stepping import UnsteadyTimeStepping +from flow360.component.v1.time_stepping import UnsteadyTimeStepping from flow360.exceptions import Flow360RuntimeError -from .utils import compare_to_ref, to_file_from_file_test +from ..utils import compare_to_ref, to_file_from_file_test assertions = unittest.TestCase("__init__") diff --git a/tests/test_folders.py b/tests/v1/test_folders.py similarity index 93% rename from tests/test_folders.py rename to tests/v1/test_folders.py index 33b753562..08dea5218 100644 --- a/tests/test_folders.py +++ b/tests/v1/test_folders.py @@ -1,4 +1,4 @@ -from flow360 import Case, Folder +from flow360.component.v1 import Case, Folder from flow360.log import set_logging_level set_logging_level("DEBUG") diff --git a/tests/test_handle_version_and_unit_system.py b/tests/v1/test_handle_version_and_unit_system.py similarity index 80% rename from tests/test_handle_version_and_unit_system.py rename to tests/v1/test_handle_version_and_unit_system.py index f81065e22..92b7d3401 100644 --- a/tests/test_handle_version_and_unit_system.py +++ b/tests/v1/test_handle_version_and_unit_system.py @@ -4,9 +4,9 @@ import pydantic.v1 as pd import pytest -import flow360 -import flow360.component.flow360_params.units as u -from flow360 import Flow360Params +import flow360.component.v1 as v1 +import flow360.component.v1.units as u +from flow360.component.v1 import Flow360Params from flow360.exceptions import Flow360NotImplementedError, Flow360RuntimeError params_old_version = { @@ -106,7 +106,7 @@ def test_import_no_unit_system_with_context(): json.dump(params_no_unit_system, temp_file) with pytest.raises(Flow360RuntimeError): - with flow360.flow360_unit_system: + with v1.flow360_unit_system: Flow360Params(temp_file.name) @@ -116,7 +116,7 @@ def test_import_with_unit_system_no_context(): params = Flow360Params(temp_file.name) assert params - assert params.unit_system == flow360.SI_unit_system + assert params.unit_system == v1.SI_unit_system def test_import_with_unit_system_with_context(): @@ -124,7 +124,7 @@ def test_import_with_unit_system_with_context(): json.dump(params_current_version, temp_file) with pytest.raises(Flow360RuntimeError): - with flow360.SI_unit_system: + with v1.SI_unit_system: Flow360Params(temp_file.name) @@ -150,30 +150,30 @@ def test_copy_with_unit_system_with_context(): assert params # passes, the models are consistent - with flow360.SI_unit_system: + with v1.SI_unit_system: params_copy = params.copy() assert params_copy # fails, the models are inconsistent - with flow360.CGS_unit_system: + with v1.CGS_unit_system: with pytest.raises(Flow360RuntimeError): params_copy = params.copy() def test_create_no_unit_system_no_context(): with pytest.raises(Flow360RuntimeError): - flow360.Flow360Params( - geometry=flow360.Geometry( + v1.Flow360Params( + geometry=v1.Geometry( ref_area=1 * u.m**2, moment_length=(1.47602, 0.801672958512342, 1.47602) * u.inch, moment_center=(1, 2, 3) * u.flow360_length_unit, mesh_unit=u.mm, ), - fluid_properties=flow360.air, - freestream=flow360.FreestreamFromVelocity(velocity=286 * u.m / u.s), - time_stepping=flow360.UnsteadyTimeStepping( + fluid_properties=v1.air, + freestream=v1.FreestreamFromVelocity(velocity=286 * u.m / u.s), + time_stepping=v1.UnsteadyTimeStepping( max_pseudo_steps=500, - CFL=flow360.AdaptiveCFL(), + CFL=v1.AdaptiveCFL(), time_step_size=1.2 * u.s, physical_steps=10, ), @@ -182,40 +182,40 @@ def test_create_no_unit_system_no_context(): def test_create_with_unit_system_no_context(): with pytest.raises(Flow360RuntimeError): - flow360.Flow360Params( - geometry=flow360.Geometry( + v1.Flow360Params( + geometry=v1.Geometry( ref_area=1 * u.m**2, moment_length=(1.47602, 0.801672958512342, 1.47602) * u.inch, moment_center=(1, 2, 3) * u.flow360_length_unit, mesh_unit=u.mm, ), - fluid_properties=flow360.air, - freestream=flow360.FreestreamFromVelocity(velocity=286 * u.m / u.s), - time_stepping=flow360.UnsteadyTimeStepping( + fluid_properties=v1.air, + freestream=v1.FreestreamFromVelocity(velocity=286 * u.m / u.s), + time_stepping=v1.UnsteadyTimeStepping( max_pseudo_steps=500, - CFL=flow360.AdaptiveCFL(), + CFL=v1.AdaptiveCFL(), time_step_size=1.2 * u.s, physical_steps=10, ), - unit_system=flow360.SI_unit_system, + unit_system=v1.SI_unit_system, ) def test_create_no_unit_system_with_context(): - with flow360.SI_unit_system: - flow360.Flow360Params( - geometry=flow360.Geometry( + with v1.SI_unit_system: + v1.Flow360Params( + geometry=v1.Geometry( ref_area=1, moment_length=(1.47602, 0.801672958512342, 1.47602) * u.inch, moment_center=(1, 2, 3) * u.flow360_length_unit, mesh_unit=u.mm, ), boundaries={}, - fluid_properties=flow360.air, - freestream=flow360.FreestreamFromVelocity(velocity=286), - time_stepping=flow360.UnsteadyTimeStepping( + fluid_properties=v1.air, + freestream=v1.FreestreamFromVelocity(velocity=286), + time_stepping=v1.UnsteadyTimeStepping( max_pseudo_steps=500, - CFL=flow360.AdaptiveCFL(), + CFL=v1.AdaptiveCFL(), time_step_size=1.2 * u.s, physical_steps=10, ), @@ -223,50 +223,50 @@ def test_create_no_unit_system_with_context(): def test_create_with_unit_system_with_context(): - with flow360.SI_unit_system: - flow360.Flow360Params( - geometry=flow360.Geometry( + with v1.SI_unit_system: + v1.Flow360Params( + geometry=v1.Geometry( ref_area=1, moment_length=(1.47602, 0.801672958512342, 1.47602) * u.inch, moment_center=(1, 2, 3) * u.flow360_length_unit, mesh_unit=u.mm, ), boundaries={}, - fluid_properties=flow360.air, - freestream=flow360.FreestreamFromVelocity(velocity=286), - time_stepping=flow360.UnsteadyTimeStepping( + fluid_properties=v1.air, + freestream=v1.FreestreamFromVelocity(velocity=286), + time_stepping=v1.UnsteadyTimeStepping( max_pseudo_steps=500, - CFL=flow360.AdaptiveCFL(), + CFL=v1.AdaptiveCFL(), time_step_size=1.2 * u.s, physical_steps=10, ), - unit_system=flow360.SI_unit_system, + unit_system=v1.SI_unit_system, ) with pytest.raises(Flow360RuntimeError): - with flow360.CGS_unit_system: - flow360.Flow360Params( - geometry=flow360.Geometry( + with v1.CGS_unit_system: + v1.Flow360Params( + geometry=v1.Geometry( ref_area=1, moment_length=(1.47602, 0.801672958512342, 1.47602) * u.inch, moment_center=(1, 2, 3) * u.flow360_length_unit, mesh_unit=u.mm, ), boundaries={}, - fluid_properties=flow360.air, - freestream=flow360.FreestreamFromVelocity(velocity=286), - time_stepping=flow360.UnsteadyTimeStepping( + fluid_properties=v1.air, + freestream=v1.FreestreamFromVelocity(velocity=286), + time_stepping=v1.UnsteadyTimeStepping( max_pseudo_steps=500, - CFL=flow360.AdaptiveCFL(), + CFL=v1.AdaptiveCFL(), time_step_size=1.2 * u.s, physical_steps=10, ), - unit_system=flow360.SI_unit_system, + unit_system=v1.SI_unit_system, ) def test_change_version(): - with flow360.SI_unit_system: + with v1.SI_unit_system: params = Flow360Params(**params_no_hash) with pytest.raises(ValueError): params.version = "changed" @@ -277,7 +277,7 @@ def test_parse_with_version(): json.dump(params_no_hash, temp_file) params = Flow360Params(temp_file.name) - assert params.version == flow360.__version__ + assert params.version == v1.__version__ def test_parse_no_version(): @@ -298,12 +298,12 @@ def test_parse_wrong_version(): def test_parse_with_hash(): with pytest.raises(pd.ValidationError): - with flow360.SI_unit_system: + with v1.SI_unit_system: Flow360Params(**params_current_version) def test_parse_no_hash(): - with flow360.SI_unit_system: + with v1.SI_unit_system: params = Flow360Params(**params_no_hash) assert params_no_hash.get("hash") is None assert not hasattr(params, "hash") @@ -311,5 +311,5 @@ def test_parse_no_hash(): def test_parse_wrong_hash(): with pytest.raises(pd.ValidationError): - with flow360.SI_unit_system: + with v1.SI_unit_system: Flow360Params(**params_wrong_hash) diff --git a/tests/test_meshing_params.py b/tests/v1/test_meshing_params.py similarity index 98% rename from tests/test_meshing_params.py rename to tests/v1/test_meshing_params.py index a71bcbf18..a72566987 100644 --- a/tests/test_meshing_params.py +++ b/tests/v1/test_meshing_params.py @@ -1,6 +1,6 @@ import pytest -from flow360.component.meshing.params import ( +from flow360.component.v1.meshing.params import ( Aniso, BoxRefinement, CylinderRefinement, @@ -16,7 +16,7 @@ VolumeMeshingParams, ) -from .utils import compare_to_ref, to_file_from_file_test +from ..utils import compare_to_ref, to_file_from_file_test @pytest.fixture(autouse=True) diff --git a/tests/test_remote_resource_logs.py b/tests/v1/test_remote_resource_logs.py similarity index 100% rename from tests/test_remote_resource_logs.py rename to tests/v1/test_remote_resource_logs.py diff --git a/tests/test_resource_base_model.py b/tests/v1/test_resource_base_model.py similarity index 100% rename from tests/test_resource_base_model.py rename to tests/v1/test_resource_base_model.py diff --git a/tests/test_schema_generator.py b/tests/v1/test_schema_generator.py similarity index 97% rename from tests/test_schema_generator.py rename to tests/v1/test_schema_generator.py index 05711283d..cbee1a825 100644 --- a/tests/test_schema_generator.py +++ b/tests/v1/test_schema_generator.py @@ -1,6 +1,6 @@ import json -import flow360 as fl +import flow360.component.v1 as fl def test_schema_generators(): diff --git a/tests/test_services_v1.py b/tests/v1/test_services_v1.py similarity index 99% rename from tests/test_services_v1.py rename to tests/v1/test_services_v1.py index 5999d3820..38e28cf00 100644 --- a/tests/test_services_v1.py +++ b/tests/v1/test_services_v1.py @@ -3,8 +3,8 @@ import pytest -import flow360 as fl -from flow360.component.flow360_params import services +import flow360.component.v1 as fl +from flow360.component.v1 import services @pytest.fixture(autouse=True) diff --git a/tests/test_surface_mesh.py b/tests/v1/test_surface_mesh.py similarity index 83% rename from tests/test_surface_mesh.py rename to tests/v1/test_surface_mesh.py index b95858036..fe5722c6d 100644 --- a/tests/test_surface_mesh.py +++ b/tests/v1/test_surface_mesh.py @@ -3,9 +3,7 @@ import pytest from flow360 import exceptions as ex -from flow360.component.meshing.params import Face, SurfaceMeshingParams from flow360.component.surface_mesh import SurfaceMesh -from flow360.component.utils import MeshFileFormat assertions = unittest.TestCase("__init__") diff --git a/tests/test_types_v1.py b/tests/v1/test_types_v1.py similarity index 100% rename from tests/test_types_v1.py rename to tests/v1/test_types_v1.py diff --git a/tests/test_unit_system_v1.py b/tests/v1/test_unit_system_v1.py similarity index 98% rename from tests/test_unit_system_v1.py rename to tests/v1/test_unit_system_v1.py index bd6f7a7cf..10b45c987 100644 --- a/tests/test_unit_system_v1.py +++ b/tests/v1/test_unit_system_v1.py @@ -4,10 +4,10 @@ import pydantic.v1 as pd import pytest -import flow360 as fl -from flow360 import units as u -from flow360.component.flow360_params.params_base import Flow360BaseModel -from flow360.component.flow360_params.unit_system import ( +import flow360.component.v1 as fl +from flow360.component.v1 import units as u +from flow360.component.v1.params_base import Flow360BaseModel +from flow360.component.v1.unit_system import ( AngularVelocityType, AreaType, DensityType, diff --git a/tests/test_updater.py b/tests/v1/test_updater.py similarity index 96% rename from tests/test_updater.py rename to tests/v1/test_updater.py index 0bfd43642..1d781b9f2 100644 --- a/tests/test_updater.py +++ b/tests/v1/test_updater.py @@ -3,16 +3,10 @@ import pytest -import flow360 as fl -from flow360.component.flow360_params.flow360_legacy import LinearSolverLegacy -from flow360.component.flow360_params.initial_condition import ( - ExpressionInitialCondition, -) -from flow360.component.flow360_params.updater import ( - UPDATE_MAP, - _find_update_path, - _no_update, -) +import flow360.component.v1 as fl +from flow360.component.v1.flow360_legacy import LinearSolverLegacy +from flow360.component.v1.initial_condition import ExpressionInitialCondition +from flow360.component.v1.updater import UPDATE_MAP, _find_update_path, _no_update from flow360.exceptions import Flow360NotImplementedError diff --git a/tests/test_validator_valid_output_fields.py b/tests/v1/test_validator_valid_output_fields.py similarity index 90% rename from tests/test_validator_valid_output_fields.py rename to tests/v1/test_validator_valid_output_fields.py index bebac9914..4c061874d 100644 --- a/tests/test_validator_valid_output_fields.py +++ b/tests/v1/test_validator_valid_output_fields.py @@ -2,10 +2,10 @@ import pytest -import flow360 as fl -import flow360.component.flow360_params.units as u -from flow360.component.flow360_params.boundaries import FreestreamBoundary, NoSlipWall -from flow360.component.flow360_params.flow360_output import ( +import flow360.component.v1 as fl +import flow360.component.v1.units as u +from flow360.component.v1.boundaries import FreestreamBoundary, NoSlipWall +from flow360.component.v1.flow360_output import ( IsoSurface, IsoSurfaceOutput, MonitorOutput, @@ -17,8 +17,8 @@ SurfaceOutput, VolumeOutput, ) -from flow360.component.flow360_params.flow360_params import Flow360Params -from flow360.component.flow360_params.solvers import NavierStokesSolver +from flow360.component.v1.flow360_params import Flow360Params +from flow360.component.v1.solvers import NavierStokesSolver assertions = unittest.TestCase("__init__") diff --git a/tests/test_volume_mesh.py b/tests/v1/test_volume_mesh.py similarity index 95% rename from tests/test_volume_mesh.py rename to tests/v1/test_volume_mesh.py index 2ccb9e4b9..274a80a95 100644 --- a/tests/test_volume_mesh.py +++ b/tests/v1/test_volume_mesh.py @@ -1,14 +1,14 @@ import pytest -import flow360 -from flow360.component.flow360_params.boundaries import NoSlipWall -from flow360.component.flow360_params.flow360_params import ( +import flow360.component.v1 as v1 +from flow360.component.utils import CompressionFormat, MeshFileFormat, UGRIDEndianness +from flow360.component.v1.boundaries import NoSlipWall +from flow360.component.v1.flow360_params import ( Flow360MeshParams, Flow360Params, FreestreamFromMach, MeshBoundary, ) -from flow360.component.utils import CompressionFormat, MeshFileFormat, UGRIDEndianness from flow360.component.volume_mesh import ( VolumeMesh, VolumeMeshMeta, @@ -19,7 +19,7 @@ from flow360.exceptions import Flow360FileError, Flow360RuntimeError, Flow360ValueError from tests.data.volume_mesh_list import volume_mesh_list_raw -from .utils import compare_to_ref, to_file_from_file_test +from ..utils import compare_to_ref, to_file_from_file_test @pytest.fixture(autouse=True) @@ -47,7 +47,7 @@ def test_get_no_slip_walls(): assert walls assert len(walls) == 3 - with flow360.SI_unit_system: + with v1.SI_unit_system: param = Flow360Params( boundaries={ "fluid/fuselage": NoSlipWall(), @@ -66,7 +66,7 @@ def test_get_no_slip_walls(): def test_validate_cgns(): - with flow360.SI_unit_system: + with v1.SI_unit_system: param = Flow360Params( boundaries={ "fluid/fuselage": NoSlipWall(), diff --git a/tests/test_volume_mesh_webapi.py b/tests/v1/test_volume_mesh_webapi.py similarity index 100% rename from tests/test_volume_mesh_webapi.py rename to tests/v1/test_volume_mesh_webapi.py diff --git a/tools/integrations/schema_generation.py b/tools/integrations/schema_generation.py index ef5b3acd4..75cb2c11b 100644 --- a/tools/integrations/schema_generation.py +++ b/tools/integrations/schema_generation.py @@ -4,26 +4,19 @@ import pydantic.v1 as pd -import flow360 as fl -from flow360.component.flow360_params.flow360_params import ( +import flow360.component.v1 as fl +from flow360.component.v1.flow360_params import ( BETDiskChord, BETDiskSectionalPolar, BETDiskTwist, ) -from flow360.component.flow360_params.initial_condition import ( +from flow360.component.v1.initial_condition import ( ExpressionInitialCondition, ModifiedRestartSolution, ) -from flow360.component.flow360_params.params_base import ( - Flow360BaseModel, - Flow360SortableBaseModel, -) -from flow360.component.flow360_params.unit_system import ( - DensityType, - PressureType, - TemperatureType, -) -from flow360.component.flow360_params.volume_zones import ( +from flow360.component.v1.params_base import Flow360BaseModel, Flow360SortableBaseModel +from flow360.component.v1.unit_system import DensityType, PressureType, TemperatureType +from flow360.component.v1.volume_zones import ( ReferenceFrame, ReferenceFrameDynamic, ReferenceFrameExpression, diff --git a/tools/integrations/tests/_test_webui_workbench_integration.py b/tools/integrations/tests/_test_webui_workbench_integration.py index 256edef93..8cc51c036 100644 --- a/tools/integrations/tests/_test_webui_workbench_integration.py +++ b/tools/integrations/tests/_test_webui_workbench_integration.py @@ -1,7 +1,7 @@ import json import os -import flow360 as fl +import flow360.component.v1 as fl from flow360.component.simulation.meshing_param.face_params import ( BoundaryLayer, SurfaceRefinement, diff --git a/tools/integrations/unit_defaults.py b/tools/integrations/unit_defaults.py index 18e5640ef..8e58f28f7 100644 --- a/tools/integrations/unit_defaults.py +++ b/tools/integrations/unit_defaults.py @@ -3,8 +3,8 @@ import pydantic.v1 as pd -import flow360 as fl -from flow360.component.flow360_params.params_base import Flow360BaseModel +import flow360.component.v1 as fl +from flow360.component.v1.params_base import Flow360BaseModel class UnitDefaults(Flow360BaseModel): From d88af219e40b4373a79808724bc12583fdd836ed Mon Sep 17 00:00:00 2001 From: Ben <106089368+benflexcompute@users.noreply.github.com> Date: Fri, 1 Nov 2024 14:21:56 -0400 Subject: [PATCH 4/8] Rename `__init__.py` from v1 folder as modules.py (#541) * Lint fixed. now need to fix unit system conflict * Fixed unit system conflict by renaming it * Moved modules.py to v1.py * comment addressed --- examples/case_from_multiple_files/main.py | 2 +- examples/case_from_yaml.py | 2 +- examples/case_params_with_units.py | 2 +- examples/change_account_and_submit.py | 2 +- examples/dev/dev_run_case_from_files.py | 2 +- .../dev_run_case_from_files_no_validation.py | 2 +- examples/dev/dev_use_unit_system.py | 4 +- examples/dev/list_cases_all_params.py | 2 +- examples/display_mesh_info.py | 2 +- ...urface_volume_case_airplane_v1_from_csm.py | 56 ----------- ...face_volume_case_airplane_v1_from_egads.py | 56 ----------- examples/list_cases.py | 2 +- .../new_workbench_project_from_geometry.py | 2 +- .../new_workbench_project_from_volume_mesh.py | 2 +- examples/project_from_file_geometry.py | 2 +- ...roject_from_file_geometry_multiple_runs.py | 2 +- examples/project_from_file_volume_mesh.py | 2 +- examples/retrieve_results/actuator_disk.py | 2 +- examples/retrieve_results/alpha_sweep.py | 2 +- examples/retrieve_results/bet_disk.py | 2 +- examples/retrieve_results/convergence.py | 2 +- examples/retrieve_results/forces.py | 2 +- examples/retrieve_results/monitors.py | 2 +- .../retrieve_results/user_defined_dynamics.py | 2 +- .../volumetric_and_surface.py | 2 +- examples/run_case_from_example_mesh.py | 2 +- examples/run_case_from_files.py | 2 +- examples/run_case_from_inputs.py | 2 +- examples/run_case_no_submit_warning.py | 2 +- examples/run_case_unsteady_from_files.py | 2 +- examples/run_case_with_fork.py | 2 +- examples/run_case_with_retry.py | 2 +- examples/show_storage.py | 2 +- examples/submit_case_to_folder.py | 2 +- examples/surface_mesh_airplane_from_files.py | 2 +- examples/surface_mesh_airplane_from_inputs.py | 2 +- examples/surface_mesh_list.py | 2 +- .../volume_mesh_from_surface_mesh_files.py | 2 +- .../volume_mesh_from_surface_mesh_inputs.py | 2 +- flow360/__init__.py | 9 ++ flow360/component/project.py | 2 +- flow360/component/simulation/conversion.py | 2 +- .../simulation/framework/base_model.py | 6 +- flow360/component/simulation/unit_system.py | 2 +- flow360/component/v1/boundaries.py | 9 +- flow360/component/v1/conversions.py | 5 +- flow360/component/v1/flow360_output.py | 13 ++- flow360/component/v1/flow360_params.py | 94 ++++++++++--------- flow360/component/v1/initial_condition.py | 6 +- flow360/component/v1/meshing/params.py | 7 +- flow360/component/v1/params_base.py | 13 ++- flow360/component/v1/services.py | 3 +- flow360/component/v1/solvers.py | 15 +-- flow360/component/v1/time_stepping.py | 3 +- flow360/component/v1/turbulence_quantities.py | 2 +- flow360/component/v1/unit_system.py | 2 +- flow360/component/v1/updater.py | 2 +- flow360/component/v1/validations.py | 16 ++-- flow360/component/v1/volume_zones.py | 9 +- flow360/{component/v1/__init__.py => v1.py} | 71 +++++++------- tests/test_current_flow360_version.py | 2 +- tests/test_environment.py | 2 +- tests/test_results.py | 2 +- tests/test_shared_accounts.py | 3 +- tests/test_utils.py | 2 +- tests/v1/_test_case.py | 2 +- tests/v1/_test_case_submit_solver_version.py | 2 +- tests/v1/_test_validate.py | 2 +- tests/v1/params/test_freestream.py | 2 +- tests/v1/params/test_initial_condition.py | 2 +- tests/v1/params/test_outputs.py | 2 +- tests/v1/params/test_params_boundary.py | 2 +- tests/v1/params/test_porous_media.py | 2 +- tests/v1/params/test_preconditioner.py | 2 +- tests/v1/params/test_reference_frame.py | 2 +- tests/v1/params/test_rotational_models.py | 2 +- tests/v1/params/test_solvers.py | 2 +- tests/v1/params/test_time_stepping.py | 2 +- tests/v1/params/test_user_defined_dynamics.py | 2 +- .../v1/params/test_validator_aeroacoustics.py | 2 +- tests/v1/params/test_validator_bet_disks.py | 2 +- tests/v1/params/test_validator_boundary.py | 2 +- tests/v1/params/test_validator_cht_solver.py | 2 +- ...est_validator_consistency_ddes_unsteady.py | 2 +- .../test_validator_equation_eval_frequency.py | 2 +- .../test_validator_output_consistency.py | 2 +- .../params/test_validator_periodic_mapping.py | 2 +- tests/v1/params/test_volume_zones.py | 2 +- tests/v1/test_case.py | 6 +- tests/v1/test_case_webapi.py | 2 +- tests/v1/test_dev_flow360_params.py | 2 +- tests/v1/test_flow360_params.py | 2 +- tests/v1/test_folders.py | 2 +- .../v1/test_handle_version_and_unit_system.py | 7 +- tests/v1/test_schema_generator.py | 2 +- tests/v1/test_services_v1.py | 2 +- tests/v1/test_unit_system_v1.py | 2 +- tests/v1/test_updater.py | 5 +- .../v1/test_validator_valid_output_fields.py | 2 +- tests/v1/test_volume_mesh.py | 2 +- tools/integrations/schema_generation.py | 2 +- .../_test_webui_workbench_integration.py | 2 +- tools/integrations/unit_defaults.py | 2 +- 103 files changed, 237 insertions(+), 341 deletions(-) delete mode 100644 examples/geometry_id_surface_volume_case_airplane_v1_from_csm.py delete mode 100644 examples/geometry_id_surface_volume_case_airplane_v1_from_egads.py rename flow360/{component/v1/__init__.py => v1.py} (80%) diff --git a/examples/case_from_multiple_files/main.py b/examples/case_from_multiple_files/main.py index 976c9f8b4..d5bd6bf79 100644 --- a/examples/case_from_multiple_files/main.py +++ b/examples/case_from_multiple_files/main.py @@ -1,7 +1,7 @@ import os -import flow360.component.v1 as fl import flow360.component.v1.units as u +import flow360.v1 as fl from flow360.examples import OM6wing here = os.path.dirname(os.path.abspath(__file__)) diff --git a/examples/case_from_yaml.py b/examples/case_from_yaml.py index 4624409f3..e2931473e 100644 --- a/examples/case_from_yaml.py +++ b/examples/case_from_yaml.py @@ -1,4 +1,4 @@ -import flow360.component.v1 as fl +import flow360.v1 as fl from flow360.examples import OM6wing OM6wing.get_files() diff --git a/examples/case_params_with_units.py b/examples/case_params_with_units.py index 5d7b53320..29ace249e 100644 --- a/examples/case_params_with_units.py +++ b/examples/case_params_with_units.py @@ -1,7 +1,7 @@ import json from pprint import pprint -import flow360.component.v1 as fl +import flow360.v1 as fl from flow360 import log from flow360.component.v1 import units as u from flow360.component.v1.services import validate_model diff --git a/examples/change_account_and_submit.py b/examples/change_account_and_submit.py index e2e2f7e2f..319b4312b 100644 --- a/examples/change_account_and_submit.py +++ b/examples/change_account_and_submit.py @@ -1,4 +1,4 @@ -import flow360.component.v1 as fl +import flow360.v1 as fl from flow360.examples import OM6wing fl.Env.dev.active() diff --git a/examples/dev/dev_run_case_from_files.py b/examples/dev/dev_run_case_from_files.py index 1a923e9a6..6cda2fdc4 100644 --- a/examples/dev/dev_run_case_from_files.py +++ b/examples/dev/dev_run_case_from_files.py @@ -1,4 +1,4 @@ -import flow360.component.v1 as fl +import flow360.v1 as fl from flow360.examples import OM6wing fl.Env.dev.active() diff --git a/examples/dev/dev_run_case_from_files_no_validation.py b/examples/dev/dev_run_case_from_files_no_validation.py index 671206ce9..fda7ae454 100644 --- a/examples/dev/dev_run_case_from_files_no_validation.py +++ b/examples/dev/dev_run_case_from_files_no_validation.py @@ -1,6 +1,6 @@ import os -import flow360.component.v1 as fl +import flow360.v1 as fl from flow360.examples import OM6wing fl.UserConfig.disable_validation() diff --git a/examples/dev/dev_use_unit_system.py b/examples/dev/dev_use_unit_system.py index a40df63c3..9e748129c 100644 --- a/examples/dev/dev_use_unit_system.py +++ b/examples/dev/dev_use_unit_system.py @@ -6,8 +6,7 @@ import pydantic.v1 as pd import unyt -import flow360.component.v1 as fl -from flow360.component.v1 import Geometry +import flow360.v1 as fl from flow360.component.v1 import units as u from flow360.component.v1.unit_system import ( AngularVelocityType, @@ -23,6 +22,7 @@ VelocityType, ViscosityType, ) +from flow360.v1 import Geometry class DataWithUnits(pd.BaseModel): diff --git a/examples/dev/list_cases_all_params.py b/examples/dev/list_cases_all_params.py index 62bf79927..67635dd81 100644 --- a/examples/dev/list_cases_all_params.py +++ b/examples/dev/list_cases_all_params.py @@ -1,4 +1,4 @@ -import flow360.component.v1 as fl +import flow360.v1 as fl from flow360.exceptions import Flow360ValidationError for case in fl.MyCases(limit=10000): diff --git a/examples/display_mesh_info.py b/examples/display_mesh_info.py index f7cfb0b96..ba12291ea 100644 --- a/examples/display_mesh_info.py +++ b/examples/display_mesh_info.py @@ -1,4 +1,4 @@ -import flow360.component.v1 as fl +import flow360.v1 as fl meshes = fl.MyVolumeMeshes() mesh = meshes[0] diff --git a/examples/geometry_id_surface_volume_case_airplane_v1_from_csm.py b/examples/geometry_id_surface_volume_case_airplane_v1_from_csm.py deleted file mode 100644 index 20e34d494..000000000 --- a/examples/geometry_id_surface_volume_case_airplane_v1_from_csm.py +++ /dev/null @@ -1,56 +0,0 @@ -import os - -import flow360.component.v1 as fl - -fl.Env.preprod.active() - -from flow360.component.geometry_v1 import Geometry -from flow360.component.meshing.params import Farfield, Volume, VolumeMeshingParams -from flow360.examples import Airplane - -# geometry -geometry_draft = Geometry.from_file(Airplane.geometry, name="testing-airplane-csm-geometry") -geometry = geometry_draft.submit() -print(geometry) - -# surface mesh -params = fl.SurfaceMeshingParams(max_edge_length=0.16) - -surface_mesh_draft = fl.SurfaceMesh.create( - geometry_id=geometry.id, - params=params, - name="airplane-surface-mesh-from-geometry-id-v1", - solver_version="mesher-24.2.2", -) -surface_mesh = surface_mesh_draft.submit() - -print(surface_mesh) - -# volume mesh -params = fl.VolumeMeshingParams( - volume=Volume( - first_layer_thickness=1e-5, - growth_rate=1.2, - ), - farfield=Farfield(type="auto"), -) - -volume_mesh_draft = fl.VolumeMesh.create( - surface_mesh_id=surface_mesh.id, - name="airplane-volume-mesh-from-geometry-id-v1", - params=params, - solver_version="mesher-24.2.2", -) -volume_mesh = volume_mesh_draft.submit() -print(volume_mesh) - -# case -params = fl.Flow360Params(Airplane.case_json) -params.boundaries = { - "fluid/farfield": fl.FreestreamBoundary(), - "fluid/fuselage": fl.NoSlipWall(), - "fluid/leftWing": fl.NoSlipWall(), - "fluid/rightWing": fl.NoSlipWall(), -} -case_draft = volume_mesh.create_case("airplane-case-from-csm-geometry-id-v1", params) -case = case_draft.submit() diff --git a/examples/geometry_id_surface_volume_case_airplane_v1_from_egads.py b/examples/geometry_id_surface_volume_case_airplane_v1_from_egads.py deleted file mode 100644 index 81202e845..000000000 --- a/examples/geometry_id_surface_volume_case_airplane_v1_from_egads.py +++ /dev/null @@ -1,56 +0,0 @@ -import os - -import flow360.component.v1 as fl - -fl.Env.preprod.active() - -from flow360.component.geometry_v1 import Geometry -from flow360.component.meshing.params import Farfield, Volume, VolumeMeshingParams -from flow360.examples import Airplane - -# geometry -geometry_draft = Geometry.from_file( - "data/airplane_geometry.egads", name="testing-airplane-egads-geometry" -) -geometry = geometry_draft.submit() -print(geometry) - -# surface mesh -params = fl.SurfaceMeshingParams(max_edge_length=0.16) - -surface_mesh_draft = fl.SurfaceMesh.create( - geometry_id=geometry.id, - params=params, - name="airplane-surface-mesh-from-geometry-id-v1", -) -surface_mesh = surface_mesh_draft.submit() - -print(surface_mesh) - -# volume mesh -params = fl.VolumeMeshingParams( - volume=Volume( - first_layer_thickness=1e-5, - growth_rate=1.2, - ), - farfield=Farfield(type="auto"), -) - -volume_mesh_draft = fl.VolumeMesh.create( - surface_mesh_id=surface_mesh.id, - name="airplane-volume-mesh-from-geometry-id-v1", - params=params, -) -volume_mesh = volume_mesh_draft.submit() -print(volume_mesh) - -# case -params = fl.Flow360Params(Airplane.case_json) -params.boundaries = { - "fluid/farfield": fl.FreestreamBoundary(), - "fluid/fuselage": fl.NoSlipWall(), - "fluid/leftWing": fl.NoSlipWall(), - "fluid/rightWing": fl.NoSlipWall(), -} -case_draft = volume_mesh.create_case("airplane-case-from-egads-geometry-id-v1", params) -case = case_draft.submit() diff --git a/examples/list_cases.py b/examples/list_cases.py index ff7f9851c..cc5660487 100644 --- a/examples/list_cases.py +++ b/examples/list_cases.py @@ -1,4 +1,4 @@ -import flow360.component.v1 as fl +import flow360.v1 as fl # get all cases: my_cases = fl.MyCases() diff --git a/examples/new_workbench_project_from_geometry.py b/examples/new_workbench_project_from_geometry.py index 1bcf50870..c638b4dc0 100644 --- a/examples/new_workbench_project_from_geometry.py +++ b/examples/new_workbench_project_from_geometry.py @@ -1,4 +1,4 @@ -import flow360.component.v1 as fl +import flow360.v1 as fl from flow360.component.geometry import Geometry from flow360.examples import Airplane diff --git a/examples/new_workbench_project_from_volume_mesh.py b/examples/new_workbench_project_from_volume_mesh.py index a0f02a25e..c4b7a8604 100644 --- a/examples/new_workbench_project_from_volume_mesh.py +++ b/examples/new_workbench_project_from_volume_mesh.py @@ -1,7 +1,7 @@ import time import flow360.component.simulation.units as u -import flow360.component.v1 as fl +import flow360.v1 as fl from flow360.component.simulation.cloud import run_case from flow360.component.simulation.models.surface_models import ( Freestream, diff --git a/examples/project_from_file_geometry.py b/examples/project_from_file_geometry.py index cfb5700c3..2272e8955 100644 --- a/examples/project_from_file_geometry.py +++ b/examples/project_from_file_geometry.py @@ -1,4 +1,4 @@ -import flow360.component.v1 as fl +import flow360.v1 as fl from flow360.component.project import Project from flow360.component.simulation.meshing_param.params import ( MeshingDefaults, diff --git a/examples/project_from_file_geometry_multiple_runs.py b/examples/project_from_file_geometry_multiple_runs.py index 5dec5b926..bec713e1d 100644 --- a/examples/project_from_file_geometry_multiple_runs.py +++ b/examples/project_from_file_geometry_multiple_runs.py @@ -1,4 +1,4 @@ -import flow360.component.v1 as fl +import flow360.v1 as fl from flow360.component.project import Project from flow360.component.simulation.meshing_param.params import ( MeshingDefaults, diff --git a/examples/project_from_file_volume_mesh.py b/examples/project_from_file_volume_mesh.py index ef80aed77..b1afe07af 100644 --- a/examples/project_from_file_volume_mesh.py +++ b/examples/project_from_file_volume_mesh.py @@ -1,7 +1,7 @@ from matplotlib.pyplot import show import flow360.component.simulation.units as u -import flow360.component.v1 as fl +import flow360.v1 as fl from flow360.component.project import Project from flow360.component.simulation.models.surface_models import ( Freestream, diff --git a/examples/retrieve_results/actuator_disk.py b/examples/retrieve_results/actuator_disk.py index 5f3345a20..7ccf1393e 100644 --- a/examples/retrieve_results/actuator_disk.py +++ b/examples/retrieve_results/actuator_disk.py @@ -1,7 +1,7 @@ import os -import flow360.component.v1 as fl import flow360.units as u +import flow360.v1 as fl from flow360.examples import ActuatorDisk ActuatorDisk.get_files() diff --git a/examples/retrieve_results/alpha_sweep.py b/examples/retrieve_results/alpha_sweep.py index f0c4bbf0a..20e79ae9f 100644 --- a/examples/retrieve_results/alpha_sweep.py +++ b/examples/retrieve_results/alpha_sweep.py @@ -3,7 +3,7 @@ from pylab import plot, show, xlabel, ylabel -import flow360.component.v1 as fl +import flow360.v1 as fl from flow360.examples import OM6wing OM6wing.get_files() diff --git a/examples/retrieve_results/bet_disk.py b/examples/retrieve_results/bet_disk.py index 8c775e1b3..e89c343d4 100644 --- a/examples/retrieve_results/bet_disk.py +++ b/examples/retrieve_results/bet_disk.py @@ -1,7 +1,7 @@ import os -import flow360.component.v1 as fl import flow360.component.v1.units as u +import flow360.v1 as fl from flow360.examples import BETDisk BETDisk.get_files() diff --git a/examples/retrieve_results/convergence.py b/examples/retrieve_results/convergence.py index 7806e53f6..302a22b00 100644 --- a/examples/retrieve_results/convergence.py +++ b/examples/retrieve_results/convergence.py @@ -1,4 +1,4 @@ -import flow360.component.v1 as fl +import flow360.v1 as fl from flow360.examples import Convergence Convergence.get_files() diff --git a/examples/retrieve_results/forces.py b/examples/retrieve_results/forces.py index 20145dbc3..b6abcb5a2 100644 --- a/examples/retrieve_results/forces.py +++ b/examples/retrieve_results/forces.py @@ -1,4 +1,4 @@ -import flow360.component.v1 as fl +import flow360.v1 as fl from flow360.examples import OM6wing OM6wing.get_files() diff --git a/examples/retrieve_results/monitors.py b/examples/retrieve_results/monitors.py index 055e63f0f..e12228e78 100644 --- a/examples/retrieve_results/monitors.py +++ b/examples/retrieve_results/monitors.py @@ -1,4 +1,4 @@ -import flow360.component.v1 as fl +import flow360.v1 as fl from flow360.examples import MonitorsAndSlices MonitorsAndSlices.get_files() diff --git a/examples/retrieve_results/user_defined_dynamics.py b/examples/retrieve_results/user_defined_dynamics.py index c6bd62717..08228abdd 100644 --- a/examples/retrieve_results/user_defined_dynamics.py +++ b/examples/retrieve_results/user_defined_dynamics.py @@ -1,6 +1,6 @@ from pylab import show -import flow360.component.v1 as fl +import flow360.v1 as fl from flow360.examples import OM6wingUserDefinedDynamics OM6wingUserDefinedDynamics.get_files() diff --git a/examples/retrieve_results/volumetric_and_surface.py b/examples/retrieve_results/volumetric_and_surface.py index bda7b7b49..f9eeec7c6 100644 --- a/examples/retrieve_results/volumetric_and_surface.py +++ b/examples/retrieve_results/volumetric_and_surface.py @@ -2,7 +2,7 @@ import tarfile import tempfile -import flow360.component.v1 as fl +import flow360.v1 as fl from flow360.examples import MonitorsAndSlices MonitorsAndSlices.get_files() diff --git a/examples/run_case_from_example_mesh.py b/examples/run_case_from_example_mesh.py index 44104e850..c7174d94d 100644 --- a/examples/run_case_from_example_mesh.py +++ b/examples/run_case_from_example_mesh.py @@ -1,4 +1,4 @@ -import flow360.component.v1 as fl +import flow360.v1 as fl from flow360.examples import OM6wing vm = fl.VolumeMesh.copy_from_example("2ad77a88-1676-4f89-8652-13bd7e34f257") diff --git a/examples/run_case_from_files.py b/examples/run_case_from_files.py index a27099e44..fafdc747b 100644 --- a/examples/run_case_from_files.py +++ b/examples/run_case_from_files.py @@ -1,4 +1,4 @@ -import flow360.component.v1 as fl +import flow360.v1 as fl from flow360.examples import OM6wing OM6wing.get_files() diff --git a/examples/run_case_from_inputs.py b/examples/run_case_from_inputs.py index 794edd04e..5455827b6 100644 --- a/examples/run_case_from_inputs.py +++ b/examples/run_case_from_inputs.py @@ -1,4 +1,4 @@ -import flow360.component.v1 as fl +import flow360.v1 as fl from flow360.examples import OM6wing OM6wing.get_files() diff --git a/examples/run_case_no_submit_warning.py b/examples/run_case_no_submit_warning.py index 102d04cf8..6b140a69a 100644 --- a/examples/run_case_no_submit_warning.py +++ b/examples/run_case_no_submit_warning.py @@ -1,4 +1,4 @@ -import flow360.component.v1 as fl +import flow360.v1 as fl from flow360.examples import OM6wing OM6wing.get_files() diff --git a/examples/run_case_unsteady_from_files.py b/examples/run_case_unsteady_from_files.py index a041533d2..8a14bc65b 100644 --- a/examples/run_case_unsteady_from_files.py +++ b/examples/run_case_unsteady_from_files.py @@ -1,4 +1,4 @@ -import flow360.component.v1 as fl +import flow360.v1 as fl from flow360.examples import Cylinder2D Cylinder2D.get_files() diff --git a/examples/run_case_with_fork.py b/examples/run_case_with_fork.py index 6527552e7..299c5072f 100644 --- a/examples/run_case_with_fork.py +++ b/examples/run_case_with_fork.py @@ -1,4 +1,4 @@ -import flow360.component.v1 as fl +import flow360.v1 as fl from flow360.examples import OM6wing OM6wing.get_files() diff --git a/examples/run_case_with_retry.py b/examples/run_case_with_retry.py index bbb92d8db..66d8053e7 100644 --- a/examples/run_case_with_retry.py +++ b/examples/run_case_with_retry.py @@ -1,4 +1,4 @@ -import flow360.component.v1 as fl +import flow360.v1 as fl from flow360.examples import OM6wing OM6wing.get_files() diff --git a/examples/show_storage.py b/examples/show_storage.py index 949304f85..98036432a 100644 --- a/examples/show_storage.py +++ b/examples/show_storage.py @@ -1,4 +1,4 @@ -import flow360.component.v1 as fl +import flow360.v1 as fl fl.Env.preprod.active() diff --git a/examples/submit_case_to_folder.py b/examples/submit_case_to_folder.py index 8cfef0bb5..eccf3c727 100644 --- a/examples/submit_case_to_folder.py +++ b/examples/submit_case_to_folder.py @@ -1,4 +1,4 @@ -import flow360.component.v1 as fl +import flow360.v1 as fl from flow360.examples import OM6wing # create folder in ROOT level diff --git a/examples/surface_mesh_airplane_from_files.py b/examples/surface_mesh_airplane_from_files.py index 7447a6851..2fc538a53 100644 --- a/examples/surface_mesh_airplane_from_files.py +++ b/examples/surface_mesh_airplane_from_files.py @@ -1,4 +1,4 @@ -import flow360.component.v1 as fl +import flow360.v1 as fl from flow360.examples import Airplane params = fl.SurfaceMeshingParams(Airplane.surface_json) diff --git a/examples/surface_mesh_airplane_from_inputs.py b/examples/surface_mesh_airplane_from_inputs.py index 6ae9d4b17..fe1d20f29 100644 --- a/examples/surface_mesh_airplane_from_inputs.py +++ b/examples/surface_mesh_airplane_from_inputs.py @@ -1,4 +1,4 @@ -import flow360.component.v1 as fl +import flow360.v1 as fl from flow360.examples import Airplane params = fl.SurfaceMeshingParams( diff --git a/examples/surface_mesh_list.py b/examples/surface_mesh_list.py index 19aae559e..5e816001d 100644 --- a/examples/surface_mesh_list.py +++ b/examples/surface_mesh_list.py @@ -1,4 +1,4 @@ -import flow360.component.v1 as fl +import flow360.v1 as fl my_meshes = fl.MySurfaceMeshes() diff --git a/examples/volume_mesh_from_surface_mesh_files.py b/examples/volume_mesh_from_surface_mesh_files.py index 92a35f460..44e931dd3 100644 --- a/examples/volume_mesh_from_surface_mesh_files.py +++ b/examples/volume_mesh_from_surface_mesh_files.py @@ -1,4 +1,4 @@ -import flow360.component.v1 as fl +import flow360.v1 as fl from flow360.examples import Airplane params = fl.SurfaceMeshingParams(Airplane.surface_json) diff --git a/examples/volume_mesh_from_surface_mesh_inputs.py b/examples/volume_mesh_from_surface_mesh_inputs.py index 5ebe9f0ca..19427bef6 100644 --- a/examples/volume_mesh_from_surface_mesh_inputs.py +++ b/examples/volume_mesh_from_surface_mesh_inputs.py @@ -1,4 +1,4 @@ -import flow360.component.v1 as fl +import flow360.v1 as fl from flow360.examples import Airplane params = fl.SurfaceMeshingParams( diff --git a/flow360/__init__.py b/flow360/__init__.py index 85a7d9138..1e739ab3d 100644 --- a/flow360/__init__.py +++ b/flow360/__init__.py @@ -2,6 +2,8 @@ This module is flow360 for simulation based models """ +from flow360.accounts_utils import Accounts +from flow360.component.project import Project from flow360.component.simulation import services from flow360.component.simulation import units as u from flow360.component.simulation.entity_info import GeometryEntityInfo @@ -114,8 +116,15 @@ from flow360.component.simulation.user_defined_dynamics.user_defined_dynamics import ( UserDefinedDynamic, ) +from flow360.environment import Env +from flow360.version import __solver_version__, __version__ __all__ = [ + "Env", + "__solver_version__", + "__version__", + "Accounts", + "Project", "u", "SimulationParams", "SI_unit_system", diff --git a/flow360/component/project.py b/flow360/component/project.py index 908d59609..cc9c2912f 100644 --- a/flow360/component/project.py +++ b/flow360/component/project.py @@ -57,7 +57,7 @@ class RootType(Enum): VOLUME_MESH = "VolumeMesh" -class ProjectMeta(pd.BaseModel, extra=pd.Extra.allow): +class ProjectMeta(pd.BaseModel, extra="allow"): """ Metadata class for a project. diff --git a/flow360/component/simulation/conversion.py b/flow360/component/simulation/conversion.py index 79318a05c..448424843 100644 --- a/flow360/component/simulation/conversion.py +++ b/flow360/component/simulation/conversion.py @@ -118,7 +118,7 @@ def unit_converter(dimension, mesh_unit: u.unyt_quantity, params, required_by: L ------- flow360_conversion_unit_system The conversion unit system for the specified dimension. This unit system allows for - .in_base(unit_system="flow360") conversion. + .in_base(unit_system="flow360_v2") conversion. Raises ------ diff --git a/flow360/component/simulation/framework/base_model.py b/flow360/component/simulation/framework/base_model.py index b3f84bf35..f869fe6ef 100644 --- a/flow360/component/simulation/framework/base_model.py +++ b/flow360/component/simulation/framework/base_model.py @@ -676,7 +676,7 @@ def _convert_dimensions_to_solver( ) # pylint: disable=no-member value.units.registry = flow360_conv_system.registry - solver_values[property_name] = value.in_base(unit_system="flow360") + solver_values[property_name] = value.in_base(unit_system="flow360_v2") log.debug(f" converted to: {solver_values[property_name]}") elif isinstance(value, list) and property_name not in exclude: new_value = [] @@ -690,7 +690,7 @@ def _convert_dimensions_to_solver( ) # pylint: disable=no-member item.units.registry = flow360_conv_system.registry - new_value.append(item.in_base(unit_system="flow360")) + new_value.append(item.in_base(unit_system="flow360_v2")) else: new_value.append(item) solver_values[property_name] = new_value @@ -759,6 +759,6 @@ def preprocess( exclude=exclude, ) elif isinstance(item, unyt_quantity): - solver_values[property_name][i] = item.in_base(unit_system="flow360") + solver_values[property_name][i] = item.in_base(unit_system="flow360_v2") return self.__class__(**solver_values) diff --git a/flow360/component/simulation/unit_system.py b/flow360/component/simulation/unit_system.py index e18d85b63..3c8fd0ff4 100644 --- a/flow360/component/simulation/unit_system.py +++ b/flow360/component/simulation/unit_system.py @@ -1512,7 +1512,7 @@ def __init__(self): ) conversion_system = u.UnitSystem( - "flow360", + "flow360_v2", "flow360_length_unit", "flow360_mass_unit", "flow360_time_unit", diff --git a/flow360/component/v1/boundaries.py b/flow360/component/v1/boundaries.py index 043e9dcf4..706b3dec4 100644 --- a/flow360/component/v1/boundaries.py +++ b/flow360/component/v1/boundaries.py @@ -10,13 +10,12 @@ import pydantic.v1 as pd from pydantic.v1 import StrictStr +from flow360.component.types import Axis, Vector +from flow360.component.utils import process_expressions +from flow360.component.v1.params_base import Flow360BaseModel +from flow360.component.v1.turbulence_quantities import TurbulenceQuantitiesType from flow360.component.v1.unit_system import PressureType, VelocityType -from ..types import Axis, Vector -from ..utils import process_expressions -from .params_base import Flow360BaseModel -from .turbulence_quantities import TurbulenceQuantitiesType - BoundaryVelocityType = Union[VelocityType.Vector, Tuple[StrictStr, StrictStr, StrictStr]] BoundaryAxisType = Union[Axis, Tuple[StrictStr, StrictStr, StrictStr]] diff --git a/flow360/component/v1/conversions.py b/flow360/component/v1/conversions.py index 885bdd9ea..756d6f321 100644 --- a/flow360/component/v1/conversions.py +++ b/flow360/component/v1/conversions.py @@ -13,8 +13,7 @@ is_flow360_unit, u, ) - -from ...exceptions import Flow360ConfigurationError +from flow360.exceptions import Flow360ConfigurationError class ExtraDimensionedProperty(pd.BaseModel): @@ -135,7 +134,7 @@ def unit_converter(dimension, params, required_by: List[str] = None): ------- flow360_conversion_unit_system The conversion unit system for the specified dimension. This unit system allows for - .in_base(unit_system="flow360") conversion. + .in_base(unit_system="flow360_v1") conversion. Raises ------ diff --git a/flow360/component/v1/flow360_output.py b/flow360/component/v1/flow360_output.py index 1a4710b0f..0071acb82 100644 --- a/flow360/component/v1/flow360_output.py +++ b/flow360/component/v1/flow360_output.py @@ -10,11 +10,9 @@ import pydantic.v1 as pd from pydantic.v1 import conlist -from flow360.component.v1.unit_system import Flow360UnitSystem, LengthType - -from ..types import Axis, Coordinate -from ..utils import process_expressions -from .flow360_fields import ( +from flow360.component.types import Axis, Coordinate +from flow360.component.utils import process_expressions +from flow360.component.v1.flow360_fields import ( CommonFieldNames, IsoSurfaceFieldNames, SliceFieldNames, @@ -23,12 +21,13 @@ _distribute_shared_output_fields, get_field_values, ) -from .flow360_legacy import LegacyModel, get_output_fields -from .params_base import ( +from flow360.component.v1.flow360_legacy import LegacyModel, get_output_fields +from flow360.component.v1.params_base import ( Flow360BaseModel, Flow360SortableBaseModel, _self_named_property_validator, ) +from flow360.component.v1.unit_system import Flow360UnitSystem, LengthType OutputFormat = Literal[ "paraview", "tecplot", "both", "paraview,tecplot" diff --git a/flow360/component/v1/flow360_params.py b/flow360/component/v1/flow360_params.py index eafb3dc7d..165cc2381 100644 --- a/flow360/component/v1/flow360_params.py +++ b/flow360/component/v1/flow360_params.py @@ -13,40 +13,12 @@ import pydantic.v1 as pd from typing_extensions import Literal -from flow360.component.v1.unit_system import ( - AngularVelocityType, - AreaType, - DensityType, - Flow360UnitSystem, - LengthType, - PressureType, - SIUnitSystem, - TemperatureType, - UnitSystem, - UnitSystemType, - VelocityType, - ViscosityType, - flow360_unit_system, - u, - unit_system_manager, -) -from flow360.flags import Flags - -from ...error_messages import unit_system_inconsistent_msg, use_unit_system_msg -from ...exceptions import ( - Flow360ConfigError, - Flow360NotImplementedError, - Flow360RuntimeError, -) -from ...log import log -from ...user_config import UserConfig -from ...version import __version__ -from ..types import Axis, Coordinate, Vector -from ..utils import convert_legacy_names, process_expressions -from . import units -from .boundaries import BoundaryType -from .conversions import ExtraDimensionedProperty -from .flow360_legacy import ( +from flow360.component.types import Axis, Coordinate, Vector +from flow360.component.utils import convert_legacy_names, process_expressions +from flow360.component.v1 import units +from flow360.component.v1.boundaries import BoundaryType +from flow360.component.v1.conversions import ExtraDimensionedProperty +from flow360.component.v1.flow360_legacy import ( FreestreamInitialConditionLegacy, LegacyModel, try_add_discriminator, @@ -54,7 +26,7 @@ try_set, try_update, ) -from .flow360_output import ( +from flow360.component.v1.flow360_output import ( AeroacousticOutput, IsoSurfaceOutput, IsoSurfaceOutputLegacy, @@ -69,22 +41,22 @@ VolumeOutput, VolumeOutputLegacy, ) -from .initial_condition import ( +from flow360.component.v1.initial_condition import ( ExpressionInitialCondition, ExpressionInitialConditionLegacy, InitialConditions, ModifiedRestartSolution, ModifiedRestartSolutionLegacy, ) -from .params_base import ( +from flow360.component.v1.params_base import ( Conflicts, Flow360BaseModel, Flow360SortableBaseModel, _self_named_property_validator, flow360_json_encoder, ) -from .physical_properties import _AirModel -from .solvers import ( +from flow360.component.v1.physical_properties import _AirModel +from flow360.component.v1.solvers import ( HeatEquationSolver, HeatEquationSolverLegacy, NavierStokesSolver, @@ -95,10 +67,34 @@ TurbulenceModelSolverLegacy, TurbulenceModelSolverType, ) -from .time_stepping import BaseTimeStepping, SteadyTimeStepping, TimeStepping -from .turbulence_quantities import TurbulenceQuantitiesType, TurbulentViscosityRatio -from .updater import updater -from .validations import ( +from flow360.component.v1.time_stepping import ( + BaseTimeStepping, + SteadyTimeStepping, + TimeStepping, +) +from flow360.component.v1.turbulence_quantities import ( + TurbulenceQuantitiesType, + TurbulentViscosityRatio, +) +from flow360.component.v1.unit_system import ( + AngularVelocityType, + AreaType, + DensityType, + Flow360UnitSystem, + LengthType, + PressureType, + SIUnitSystem, + TemperatureType, + UnitSystem, + UnitSystemType, + VelocityType, + ViscosityType, + flow360_unit_system, + u, + unit_system_manager, +) +from flow360.component.v1.updater import updater +from flow360.component.v1.validations import ( _check_aero_acoustics, _check_bet_disks_3d_coefficients_in_polars, _check_bet_disks_alphas_in_order, @@ -120,13 +116,23 @@ _check_tri_quad_boundaries, _ignore_velocity_type_in_boundaries, ) -from .volume_zones import ( +from flow360.component.v1.volume_zones import ( FluidDynamicsVolumeZone, HeatTransferVolumeZone, PorousMediumBase, ReferenceFrameType, VolumeZoneType, ) +from flow360.error_messages import unit_system_inconsistent_msg, use_unit_system_msg +from flow360.exceptions import ( + Flow360ConfigError, + Flow360NotImplementedError, + Flow360RuntimeError, +) +from flow360.flags import Flags +from flow360.log import log +from flow360.user_config import UserConfig +from flow360.version import __version__ # pylint: disable=invalid-name diff --git a/flow360/component/v1/initial_condition.py b/flow360/component/v1/initial_condition.py index 4d95add02..f023e79c8 100644 --- a/flow360/component/v1/initial_condition.py +++ b/flow360/component/v1/initial_condition.py @@ -9,9 +9,9 @@ import pydantic.v1 as pd from typing_extensions import Literal -from ..utils import process_expressions -from .flow360_legacy import LegacyModel -from .params_base import Flow360BaseModel +from flow360.component.utils import process_expressions +from flow360.component.v1.flow360_legacy import LegacyModel +from flow360.component.v1.params_base import Flow360BaseModel class InitialCondition(Flow360BaseModel): diff --git a/flow360/component/v1/meshing/params.py b/flow360/component/v1/meshing/params.py index fbd1245ac..43dc30505 100644 --- a/flow360/component/v1/meshing/params.py +++ b/flow360/component/v1/meshing/params.py @@ -7,15 +7,14 @@ import pydantic.v1 as pd from typing_extensions import Literal -from flow360.flags import Flags - -from ...types import Axis, Coordinate -from ..params_base import ( +from flow360.component.types import Axis, Coordinate +from flow360.component.v1.params_base import ( Flow360BaseModel, Flow360SortableBaseModel, _self_named_property_validator, flow360_json_encoder, ) +from flow360.flags import Flags class Aniso(Flow360BaseModel): diff --git a/flow360/component/v1/params_base.py b/flow360/component/v1/params_base.py index 5520ce601..0502c07b9 100644 --- a/flow360/component/v1/params_base.py +++ b/flow360/component/v1/params_base.py @@ -21,13 +21,12 @@ from pydantic.v1.fields import ModelField from typing_extensions import Literal +from flow360.component.types import COMMENTS, TYPE_TAG_STR +from flow360.component.v1.conversions import need_conversion, require, unit_converter from flow360.component.v1.unit_system import DimensionedType, is_flow360_unit - -from ...error_messages import do_not_modify_file_manually_msg -from ...exceptions import Flow360FileError, Flow360ValidationError -from ...log import log -from ..types import COMMENTS, TYPE_TAG_STR -from .conversions import need_conversion, require, unit_converter +from flow360.error_messages import do_not_modify_file_manually_msg +from flow360.exceptions import Flow360FileError, Flow360ValidationError +from flow360.log import log def json_dumps(value, *args, **kwargs): @@ -710,7 +709,7 @@ def _convert_dimensions_to_solver( ) # pylint: disable=no-member value.units.registry = flow360_conv_system.registry - solver_values[property_name] = value.in_base(unit_system="flow360") + solver_values[property_name] = value.in_base(unit_system="flow360_v1") log.debug(f" converted to: {solver_values[property_name]}") else: solver_values[property_name] = value diff --git a/flow360/component/v1/services.py b/flow360/component/v1/services.py index 28fcf726d..f017a1593 100644 --- a/flow360/component/v1/services.py +++ b/flow360/component/v1/services.py @@ -7,6 +7,7 @@ import pydantic.v1 as pd +from flow360.component.utils import remove_properties_with_prefix from flow360.component.v1.flow360_params import ( Flow360Params, FreestreamFromVelocity, @@ -29,8 +30,6 @@ ) from flow360.exceptions import Flow360ConfigurationError -from ..utils import remove_properties_with_prefix - unit_system_map = { "SI": SI_unit_system, "CGS": CGS_unit_system, diff --git a/flow360/component/v1/solvers.py b/flow360/component/v1/solvers.py index 5a2513b0e..f3070f0bf 100644 --- a/flow360/component/v1/solvers.py +++ b/flow360/component/v1/solvers.py @@ -11,18 +11,21 @@ import pydantic.v1 as pd from typing_extensions import Literal -from flow360.flags import Flags - -from ..types import Coordinate -from .flow360_legacy import ( +from flow360.component.types import Coordinate +from flow360.component.v1.flow360_legacy import ( LegacyModel, LinearSolverLegacy, set_linear_solver_config_if_none, try_set, try_update, ) -from .params_base import Conflicts, DeprecatedAlias, Flow360BaseModel -from .time_stepping import UnsteadyTimeStepping +from flow360.component.v1.params_base import ( + Conflicts, + DeprecatedAlias, + Flow360BaseModel, +) +from flow360.component.v1.time_stepping import UnsteadyTimeStepping +from flow360.flags import Flags HEAT_EQUATION_EVAL_MAX_PER_PSEUDOSTEP_UNSTEADY = 40 HEAT_EQUATION_EVAL_FREQUENCY_STEADY = 10 diff --git a/flow360/component/v1/time_stepping.py b/flow360/component/v1/time_stepping.py index 55834a4a8..57b7b8bb7 100644 --- a/flow360/component/v1/time_stepping.py +++ b/flow360/component/v1/time_stepping.py @@ -12,10 +12,9 @@ import pydantic.v1 as pd from typing_extensions import Literal +from flow360.component.v1.params_base import DeprecatedAlias, Flow360BaseModel from flow360.component.v1.unit_system import TimeType -from .params_base import DeprecatedAlias, Flow360BaseModel - def _apply_default_to_none(original, default): for field_name in original.__fields__: diff --git a/flow360/component/v1/turbulence_quantities.py b/flow360/component/v1/turbulence_quantities.py index 129a56308..115dfb64a 100644 --- a/flow360/component/v1/turbulence_quantities.py +++ b/flow360/component/v1/turbulence_quantities.py @@ -8,7 +8,7 @@ import pydantic.v1 as pd -from .params_base import Flow360BaseModel +from flow360.component.v1.params_base import Flow360BaseModel class TurbulentKineticEnergy(Flow360BaseModel): diff --git a/flow360/component/v1/unit_system.py b/flow360/component/v1/unit_system.py index be9116f1e..e70e4a675 100644 --- a/flow360/component/v1/unit_system.py +++ b/flow360/component/v1/unit_system.py @@ -1224,7 +1224,7 @@ def __init__(self): ) conversion_system = u.UnitSystem( - "flow360", + "flow360_v1", "flow360_length_unit", "flow360_mass_unit", "flow360_time_unit", diff --git a/flow360/component/v1/updater.py b/flow360/component/v1/updater.py index 0539ae948..fb682c851 100644 --- a/flow360/component/v1/updater.py +++ b/flow360/component/v1/updater.py @@ -4,7 +4,7 @@ import re -from ...exceptions import Flow360NotImplementedError, Flow360RuntimeError +from flow360.exceptions import Flow360NotImplementedError, Flow360RuntimeError def _no_update(params_as_dict): diff --git a/flow360/component/v1/validations.py b/flow360/component/v1/validations.py index 86f8a6a4c..a19738a82 100644 --- a/flow360/component/v1/validations.py +++ b/flow360/component/v1/validations.py @@ -5,8 +5,7 @@ from copy import deepcopy from typing import List, Literal, Optional, Tuple, Union, get_args, get_origin -from ...log import log -from .boundaries import ( +from flow360.component.v1.boundaries import ( RotationallyPeriodic, SlipWall, SolidAdiabaticWall, @@ -14,12 +13,13 @@ TranslationallyPeriodic, WallFunction, ) -from .flow360_fields import _distribute_shared_output_fields -from .initial_condition import ExpressionInitialCondition -from .params_utils import get_all_output_fields -from .solvers import IncompressibleNavierStokesSolver -from .time_stepping import SteadyTimeStepping, UnsteadyTimeStepping -from .volume_zones import HeatTransferVolumeZone +from flow360.component.v1.flow360_fields import _distribute_shared_output_fields +from flow360.component.v1.initial_condition import ExpressionInitialCondition +from flow360.component.v1.params_utils import get_all_output_fields +from flow360.component.v1.solvers import IncompressibleNavierStokesSolver +from flow360.component.v1.time_stepping import SteadyTimeStepping, UnsteadyTimeStepping +from flow360.component.v1.volume_zones import HeatTransferVolumeZone +from flow360.log import log def _ignore_velocity_type_in_boundaries(values): diff --git a/flow360/component/v1/volume_zones.py b/flow360/component/v1/volume_zones.py index 7b57d1c2c..6cb0034e2 100644 --- a/flow360/component/v1/volume_zones.py +++ b/flow360/component/v1/volume_zones.py @@ -14,6 +14,10 @@ from pydantic.v1 import StrictStr from typing_extensions import Literal +from flow360.component.constants import NumericalConstants +from flow360.component.types import Axis, List +from flow360.component.utils import process_expressions +from flow360.component.v1.params_base import Flow360BaseModel from flow360.component.v1.unit_system import ( AngularVelocityType, HeatSourceType, @@ -22,11 +26,6 @@ LengthType, ) -from ..constants import NumericalConstants -from ..types import Axis, List -from ..utils import process_expressions -from .params_base import Flow360BaseModel - class ReferenceFrameBase(Flow360BaseModel): """Base reference frame class""" diff --git a/flow360/component/v1/__init__.py b/flow360/v1.py similarity index 80% rename from flow360/component/v1/__init__.py rename to flow360/v1.py index 1f67643c4..74d857616 100644 --- a/flow360/component/v1/__init__.py +++ b/flow360/v1.py @@ -1,36 +1,21 @@ """ -This module is flow360. +Flow360 V1 (legacy) modules. """ import os from numpy import pi -from flow360.component.v1.unit_system import ( - CGS_unit_system, - SI_unit_system, - UnitSystem, - flow360_unit_system, - imperial_unit_system, -) - -from ... import global_exception_handler -from ...accounts_utils import Accounts -from ...cli import flow360 -from ...cloud.s3_utils import ProgressCallbackInterface -from ...environment import Env -from ...flags import Flags -from ...user_config import UserConfig -from ...version import __solver_version__, __version__ -from ..case import Case -from ..case import CaseList as MyCases -from ..folder import Folder -from ..surface_mesh import SurfaceMesh -from ..surface_mesh import SurfaceMeshList as MySurfaceMeshes -from ..volume_mesh import VolumeMesh -from ..volume_mesh import VolumeMeshList as MyVolumeMeshes -from . import meshing, solvers, units -from .boundaries import ( +from flow360 import global_exception_handler +from flow360.cli import flow360 +from flow360.cloud.s3_utils import ProgressCallbackInterface +from flow360.component.case import Case +from flow360.component.case import CaseList as MyCases +from flow360.component.folder import Folder +from flow360.component.surface_mesh import SurfaceMesh +from flow360.component.surface_mesh import SurfaceMeshList as MySurfaceMeshes +from flow360.component.v1 import meshing, solvers, units +from flow360.component.v1.boundaries import ( FreestreamBoundary, HeatFluxWall, IsothermalWall, @@ -53,7 +38,7 @@ VelocityInflow, WallFunction, ) -from .flow360_output import ( +from flow360.component.v1.flow360_output import ( IsoSurfaceOutput, IsoSurfaces, MonitorOutput, @@ -66,7 +51,7 @@ SurfaceOutput, Surfaces, ) -from .flow360_params import ( +from flow360.component.v1.flow360_params import ( ActuatorDisk, AeroacousticOutput, AirDensityTemperature, @@ -96,8 +81,11 @@ ZeroFreestreamFromVelocity, air, ) -from .initial_condition import ExpressionInitialCondition, ModifiedRestartSolution -from .meshing.params import ( +from flow360.component.v1.initial_condition import ( + ExpressionInitialCondition, + ModifiedRestartSolution, +) +from flow360.component.v1.meshing.params import ( Aniso, BoxRefinement, CylinderRefinement, @@ -112,7 +100,7 @@ Volume, VolumeMeshingParams, ) -from .solvers import ( +from flow360.component.v1.solvers import ( IncompressibleNavierStokesSolver, KOmegaSST, KOmegaSSTModelConstants, @@ -123,15 +111,22 @@ SpalartAllmaras, SpalartAllmarasModelConstants, ) -from .time_stepping import ( +from flow360.component.v1.time_stepping import ( AdaptiveCFL, RampCFL, SteadyTimeStepping, TimeStepping, UnsteadyTimeStepping, ) -from .turbulence_quantities import TurbulenceQuantities -from .volume_zones import ( +from flow360.component.v1.turbulence_quantities import TurbulenceQuantities +from flow360.component.v1.unit_system import ( + CGS_unit_system, + SI_unit_system, + UnitSystem, + flow360_unit_system, + imperial_unit_system, +) +from flow360.component.v1.volume_zones import ( FluidDynamicsVolumeZone, HeatTransferVolumeZone, InitialConditionHeatTransfer, @@ -142,9 +137,12 @@ ReferenceFrameOmegaDegrees, ReferenceFrameOmegaRadians, ) +from flow360.component.volume_mesh import VolumeMesh +from flow360.component.volume_mesh import VolumeMeshList as MyVolumeMeshes +from flow360.flags import Flags +from flow360.user_config import UserConfig __all__ = [ - "Accounts", "ActuatorDisk", "AdaptiveCFL", "AeroacousticOutput", @@ -161,7 +159,6 @@ "Case", "CylinderRefinement", "Edges", - "Env", "ExpressionInitialCondition", "Face", "Faces", @@ -257,8 +254,6 @@ "WallFunction", "ZeroFreestream", "ZeroFreestreamFromVelocity", - "__version__", - "__solver_version__", "air", "flow360", "flow360_unit_system", diff --git a/tests/test_current_flow360_version.py b/tests/test_current_flow360_version.py index e7eb64980..93bf5c471 100644 --- a/tests/test_current_flow360_version.py +++ b/tests/test_current_flow360_version.py @@ -1,4 +1,4 @@ -from flow360.component.v1 import __version__ +from flow360.version import __version__ def test_version(): diff --git a/tests/test_environment.py b/tests/test_environment.py index 60a823cc5..502d152c3 100644 --- a/tests/test_environment.py +++ b/tests/test_environment.py @@ -1,4 +1,4 @@ -from flow360.component.v1 import Env +from flow360 import Env def test_version(): diff --git a/tests/test_results.py b/tests/test_results.py index 711601d9e..a2a22c243 100644 --- a/tests/test_results.py +++ b/tests/test_results.py @@ -6,8 +6,8 @@ import pandas import pytest -import flow360.component.v1 as fl import flow360.component.v1.units as u1 +import flow360.v1 as fl from flow360 import log from flow360.component.simulation import units as u2 from flow360.component.simulation.operating_condition.operating_condition import ( diff --git a/tests/test_shared_accounts.py b/tests/test_shared_accounts.py index c43092473..14ab1921a 100644 --- a/tests/test_shared_accounts.py +++ b/tests/test_shared_accounts.py @@ -2,7 +2,8 @@ import pytest -from flow360.component.v1 import Accounts, Env +from flow360.accounts_utils import Accounts +from flow360.environment import Env def test_shared_account(mock_response, monkeypatch): diff --git a/tests/test_utils.py b/tests/test_utils.py index 3da5c8d9c..02febaa65 100644 --- a/tests/test_utils.py +++ b/tests/test_utils.py @@ -2,6 +2,7 @@ import pytest +from flow360.accounts_utils import Accounts from flow360.cli.dict_utils import merge_overwrite from flow360.component.utils import ( CompressionFormat, @@ -12,7 +13,6 @@ shared_account_confirm_proceed, validate_type, ) -from flow360.component.v1 import Accounts from flow360.component.volume_mesh import VolumeMeshMeta from flow360.exceptions import Flow360TypeError, Flow360ValueError diff --git a/tests/v1/_test_case.py b/tests/v1/_test_case.py index fc9236bce..7319d80a9 100644 --- a/tests/v1/_test_case.py +++ b/tests/v1/_test_case.py @@ -1,6 +1,6 @@ from flow360.component.case import Case -from flow360.component.v1 import Env from flow360.component.v1.flow360_params import Flow360Params, UnsteadyTimeStepping +from flow360.v1 import Env def test_from_cloud(): diff --git a/tests/v1/_test_case_submit_solver_version.py b/tests/v1/_test_case_submit_solver_version.py index 90e66089e..9094fd1c7 100644 --- a/tests/v1/_test_case_submit_solver_version.py +++ b/tests/v1/_test_case_submit_solver_version.py @@ -1,6 +1,6 @@ import pytest -import flow360.component.v1 as fl +import flow360.v1 as fl from flow360.examples import OM6wing from flow360.exceptions import Flow360RuntimeError, Flow360ValidationError from flow360.log import set_logging_level diff --git a/tests/v1/_test_validate.py b/tests/v1/_test_validate.py index 08c7a8d07..bb9503b14 100644 --- a/tests/v1/_test_validate.py +++ b/tests/v1/_test_validate.py @@ -2,7 +2,7 @@ import pytest -import flow360.component.v1 as fl +import flow360.v1 as fl from flow360.component.validator import Validator assertions = unittest.TestCase("__init__") diff --git a/tests/v1/params/test_freestream.py b/tests/v1/params/test_freestream.py index 0d037d98e..c74f83035 100644 --- a/tests/v1/params/test_freestream.py +++ b/tests/v1/params/test_freestream.py @@ -4,7 +4,7 @@ import pydantic.v1 as pd import pytest -import flow360.component.v1 as fl +import flow360.v1 as fl from flow360.component.v1 import units as u from flow360.component.v1.flow360_params import ( FreestreamFromMach, diff --git a/tests/v1/params/test_initial_condition.py b/tests/v1/params/test_initial_condition.py index 4620f16a8..745e5bc72 100644 --- a/tests/v1/params/test_initial_condition.py +++ b/tests/v1/params/test_initial_condition.py @@ -2,7 +2,7 @@ import pytest -import flow360.component.v1 as fl +import flow360.v1 as fl from flow360.component.v1.initial_condition import ExpressionInitialCondition from tests.utils import to_file_from_file_test diff --git a/tests/v1/params/test_outputs.py b/tests/v1/params/test_outputs.py index 8e8eb2bc7..3bf0a0caa 100644 --- a/tests/v1/params/test_outputs.py +++ b/tests/v1/params/test_outputs.py @@ -5,8 +5,8 @@ import pytest import unyt -import flow360.component.v1 as v1 import flow360.component.v1.units as u +import flow360.v1 as v1 from flow360.component.v1.flow360_output import ( IsoSurface, IsoSurfaceOutput, diff --git a/tests/v1/params/test_params_boundary.py b/tests/v1/params/test_params_boundary.py index 0eb87ce50..8e08dd705 100644 --- a/tests/v1/params/test_params_boundary.py +++ b/tests/v1/params/test_params_boundary.py @@ -3,7 +3,7 @@ import pydantic.v1 as pd import pytest -import flow360.component.v1 as fl +import flow360.v1 as fl from flow360.component.v1.boundaries import ( FreestreamBoundary, HeatFluxWall, diff --git a/tests/v1/params/test_porous_media.py b/tests/v1/params/test_porous_media.py index d5fd557b6..27f5bcf95 100644 --- a/tests/v1/params/test_porous_media.py +++ b/tests/v1/params/test_porous_media.py @@ -2,8 +2,8 @@ import pytest -from flow360.component.v1 import SI_unit_system from flow360.component.v1.flow360_params import PorousMediumBox +from flow360.v1 import SI_unit_system from tests.utils import to_file_from_file_test assertions = unittest.TestCase("__init__") diff --git a/tests/v1/params/test_preconditioner.py b/tests/v1/params/test_preconditioner.py index 26f00bd6f..618610540 100644 --- a/tests/v1/params/test_preconditioner.py +++ b/tests/v1/params/test_preconditioner.py @@ -4,7 +4,7 @@ import pydantic.v1 as pd import pytest -import flow360.component.v1 as fl +import flow360.v1 as fl from flow360.component.v1 import units as u from flow360.component.v1.flow360_params import FreestreamFromVelocity diff --git a/tests/v1/params/test_reference_frame.py b/tests/v1/params/test_reference_frame.py index 87861a7f2..87c1c47b8 100644 --- a/tests/v1/params/test_reference_frame.py +++ b/tests/v1/params/test_reference_frame.py @@ -3,7 +3,7 @@ import numpy as np import pytest -import flow360.component.v1 as fl +import flow360.v1 as fl from flow360.component.v1 import units as u assertions = unittest.TestCase("__init__") diff --git a/tests/v1/params/test_rotational_models.py b/tests/v1/params/test_rotational_models.py index 3df57b8a2..cbe856433 100644 --- a/tests/v1/params/test_rotational_models.py +++ b/tests/v1/params/test_rotational_models.py @@ -3,7 +3,7 @@ import numpy as np import pytest -import flow360.component.v1 as fl +import flow360.v1 as fl from flow360.component.v1.flow360_params import ( ActuatorDisk, BETDisk, diff --git a/tests/v1/params/test_solvers.py b/tests/v1/params/test_solvers.py index 8f30ab59b..296bd42ca 100644 --- a/tests/v1/params/test_solvers.py +++ b/tests/v1/params/test_solvers.py @@ -3,7 +3,7 @@ import pydantic.v1 as pd import pytest -import flow360.component.v1 as fl +import flow360.v1 as fl from flow360.component.v1.flow360_params import ( Flow360Params, HeatEquationSolver, diff --git a/tests/v1/params/test_time_stepping.py b/tests/v1/params/test_time_stepping.py index 60e493c34..baa1b6aa6 100644 --- a/tests/v1/params/test_time_stepping.py +++ b/tests/v1/params/test_time_stepping.py @@ -4,7 +4,7 @@ import pydantic.v1 as pd import pytest -import flow360.component.v1 as fl +import flow360.v1 as fl from flow360.component.v1 import units as u from flow360.component.v1.flow360_params import ( Flow360Params, diff --git a/tests/v1/params/test_user_defined_dynamics.py b/tests/v1/params/test_user_defined_dynamics.py index 6b201fde8..81a5b9818 100644 --- a/tests/v1/params/test_user_defined_dynamics.py +++ b/tests/v1/params/test_user_defined_dynamics.py @@ -2,7 +2,7 @@ import pytest -import flow360.component.v1 as fl +import flow360.v1 as fl from flow360.component.v1.flow360_params import UserDefinedDynamic from tests.utils import to_file_from_file_test diff --git a/tests/v1/params/test_validator_aeroacoustics.py b/tests/v1/params/test_validator_aeroacoustics.py index 845ec0abe..e01f570ff 100644 --- a/tests/v1/params/test_validator_aeroacoustics.py +++ b/tests/v1/params/test_validator_aeroacoustics.py @@ -2,7 +2,7 @@ import pytest -import flow360.component.v1 as fl +import flow360.v1 as fl from flow360.component.v1.boundaries import NoSlipWall, TranslationallyPeriodic from flow360.component.v1.flow360_output import AeroacousticOutput from flow360.component.v1.flow360_params import Flow360Params diff --git a/tests/v1/params/test_validator_bet_disks.py b/tests/v1/params/test_validator_bet_disks.py index b5643e9b7..6ddae217b 100644 --- a/tests/v1/params/test_validator_bet_disks.py +++ b/tests/v1/params/test_validator_bet_disks.py @@ -3,7 +3,7 @@ import pytest -import flow360.component.v1 as fl +import flow360.v1 as fl from flow360.component.v1.flow360_params import ( BETDisk, BETDiskChord, diff --git a/tests/v1/params/test_validator_boundary.py b/tests/v1/params/test_validator_boundary.py index 4028b3a3d..13c90cbfb 100644 --- a/tests/v1/params/test_validator_boundary.py +++ b/tests/v1/params/test_validator_boundary.py @@ -2,7 +2,7 @@ import pytest -import flow360.component.v1 as fl +import flow360.v1 as fl from flow360.component.v1.boundaries import NoSlipWall from flow360.component.v1.flow360_params import Flow360Params diff --git a/tests/v1/params/test_validator_cht_solver.py b/tests/v1/params/test_validator_cht_solver.py index f0b9c0994..2b7bbc09e 100644 --- a/tests/v1/params/test_validator_cht_solver.py +++ b/tests/v1/params/test_validator_cht_solver.py @@ -2,7 +2,7 @@ import pytest -import flow360.component.v1 as fl +import flow360.v1 as fl from flow360.component.v1 import units as u from flow360.component.v1.boundaries import SolidAdiabaticWall, SolidIsothermalWall from flow360.component.v1.flow360_output import ( diff --git a/tests/v1/params/test_validator_consistency_ddes_unsteady.py b/tests/v1/params/test_validator_consistency_ddes_unsteady.py index d268fcbb0..3e81e6ca2 100644 --- a/tests/v1/params/test_validator_consistency_ddes_unsteady.py +++ b/tests/v1/params/test_validator_consistency_ddes_unsteady.py @@ -2,7 +2,7 @@ import pytest -import flow360.component.v1 as fl +import flow360.v1 as fl from flow360.component.v1 import units as u from flow360.component.v1.flow360_params import Flow360Params, SteadyTimeStepping from flow360.component.v1.solvers import SpalartAllmaras diff --git a/tests/v1/params/test_validator_equation_eval_frequency.py b/tests/v1/params/test_validator_equation_eval_frequency.py index 06152ae89..ef4ea9576 100644 --- a/tests/v1/params/test_validator_equation_eval_frequency.py +++ b/tests/v1/params/test_validator_equation_eval_frequency.py @@ -2,7 +2,7 @@ import pytest -import flow360.component.v1 as fl +import flow360.v1 as fl from flow360.component.v1 import units as u from flow360.component.v1.flow360_params import Flow360Params, SteadyTimeStepping from flow360.component.v1.solvers import SpalartAllmaras, TransitionModelSolver diff --git a/tests/v1/params/test_validator_output_consistency.py b/tests/v1/params/test_validator_output_consistency.py index 57ae0d666..aa42c5dd6 100644 --- a/tests/v1/params/test_validator_output_consistency.py +++ b/tests/v1/params/test_validator_output_consistency.py @@ -2,7 +2,7 @@ import pytest -import flow360.component.v1 as fl +import flow360.v1 as fl from flow360.component.v1.boundaries import FreestreamBoundary, NoSlipWall, WallFunction from flow360.component.v1.flow360_output import SurfaceOutput from flow360.component.v1.flow360_params import Flow360Params diff --git a/tests/v1/params/test_validator_periodic_mapping.py b/tests/v1/params/test_validator_periodic_mapping.py index 9efdd6472..8a6330d65 100644 --- a/tests/v1/params/test_validator_periodic_mapping.py +++ b/tests/v1/params/test_validator_periodic_mapping.py @@ -2,7 +2,7 @@ import pytest -import flow360.component.v1 as fl +import flow360.v1 as fl from flow360.component.v1.boundaries import ( NoSlipWall, RotationallyPeriodic, diff --git a/tests/v1/params/test_volume_zones.py b/tests/v1/params/test_volume_zones.py index ae6c5e129..d67101da6 100644 --- a/tests/v1/params/test_volume_zones.py +++ b/tests/v1/params/test_volume_zones.py @@ -4,7 +4,7 @@ import pydantic.v1 as pd import pytest -import flow360.component.v1 as fl +import flow360.v1 as fl from flow360.component.v1.flow360_params import VolumeZones from flow360.component.v1.volume_zones import ( FluidDynamicsVolumeZone, diff --git a/tests/v1/test_case.py b/tests/v1/test_case.py index 4b775a6a0..2627b6962 100644 --- a/tests/v1/test_case.py +++ b/tests/v1/test_case.py @@ -1,6 +1,8 @@ import pytest -from flow360.component.v1 import ( +from flow360.exceptions import Flow360RuntimeError, Flow360ValueError +from flow360.log import set_logging_level +from flow360.v1 import ( Case, Flow360Params, FreestreamFromVelocity, @@ -9,8 +11,6 @@ VolumeMesh, air, ) -from flow360.exceptions import Flow360RuntimeError, Flow360ValueError -from flow360.log import set_logging_level set_logging_level("DEBUG") diff --git a/tests/v1/test_case_webapi.py b/tests/v1/test_case_webapi.py index 9e633f4f8..b19457b5f 100644 --- a/tests/v1/test_case_webapi.py +++ b/tests/v1/test_case_webapi.py @@ -1,8 +1,8 @@ import pytest -from flow360.component.v1 import Case from flow360.exceptions import Flow360RuntimeError from flow360.log import Logger, log +from flow360.v1 import Case Logger.log_to_file = False diff --git a/tests/v1/test_dev_flow360_params.py b/tests/v1/test_dev_flow360_params.py index 318212f8c..1b55c85de 100644 --- a/tests/v1/test_dev_flow360_params.py +++ b/tests/v1/test_dev_flow360_params.py @@ -2,7 +2,7 @@ import pytest -import flow360.component.v1 as fl +import flow360.v1 as fl from ..utils import compare_to_ref, to_file_from_file_test diff --git a/tests/v1/test_flow360_params.py b/tests/v1/test_flow360_params.py index d32535df8..9858730ce 100644 --- a/tests/v1/test_flow360_params.py +++ b/tests/v1/test_flow360_params.py @@ -5,7 +5,7 @@ import pydantic.v1 as pd import pytest -import flow360.component.v1 as fl +import flow360.v1 as fl from flow360.component.v1 import units as u from flow360.component.v1.flow360_params import ( Flow360MeshParams, diff --git a/tests/v1/test_folders.py b/tests/v1/test_folders.py index 08dea5218..7a60536ce 100644 --- a/tests/v1/test_folders.py +++ b/tests/v1/test_folders.py @@ -1,5 +1,5 @@ -from flow360.component.v1 import Case, Folder from flow360.log import set_logging_level +from flow360.v1 import Case, Folder set_logging_level("DEBUG") diff --git a/tests/v1/test_handle_version_and_unit_system.py b/tests/v1/test_handle_version_and_unit_system.py index 92b7d3401..2144e2633 100644 --- a/tests/v1/test_handle_version_and_unit_system.py +++ b/tests/v1/test_handle_version_and_unit_system.py @@ -4,10 +4,11 @@ import pydantic.v1 as pd import pytest -import flow360.component.v1 as v1 import flow360.component.v1.units as u -from flow360.component.v1 import Flow360Params +import flow360.v1 as v1 from flow360.exceptions import Flow360NotImplementedError, Flow360RuntimeError +from flow360.v1 import Flow360Params +from flow360.version import __version__ params_old_version = { "version": "0.2.0b01", @@ -277,7 +278,7 @@ def test_parse_with_version(): json.dump(params_no_hash, temp_file) params = Flow360Params(temp_file.name) - assert params.version == v1.__version__ + assert params.version == __version__ def test_parse_no_version(): diff --git a/tests/v1/test_schema_generator.py b/tests/v1/test_schema_generator.py index cbee1a825..37bddc50a 100644 --- a/tests/v1/test_schema_generator.py +++ b/tests/v1/test_schema_generator.py @@ -1,6 +1,6 @@ import json -import flow360.component.v1 as fl +import flow360.v1 as fl def test_schema_generators(): diff --git a/tests/v1/test_services_v1.py b/tests/v1/test_services_v1.py index 38e28cf00..1da71c11f 100644 --- a/tests/v1/test_services_v1.py +++ b/tests/v1/test_services_v1.py @@ -3,7 +3,7 @@ import pytest -import flow360.component.v1 as fl +import flow360.v1 as fl from flow360.component.v1 import services diff --git a/tests/v1/test_unit_system_v1.py b/tests/v1/test_unit_system_v1.py index 10b45c987..7a4a00ebe 100644 --- a/tests/v1/test_unit_system_v1.py +++ b/tests/v1/test_unit_system_v1.py @@ -4,7 +4,7 @@ import pydantic.v1 as pd import pytest -import flow360.component.v1 as fl +import flow360.v1 as fl from flow360.component.v1 import units as u from flow360.component.v1.params_base import Flow360BaseModel from flow360.component.v1.unit_system import ( diff --git a/tests/v1/test_updater.py b/tests/v1/test_updater.py index 1d781b9f2..27d5e8946 100644 --- a/tests/v1/test_updater.py +++ b/tests/v1/test_updater.py @@ -3,11 +3,12 @@ import pytest -import flow360.component.v1 as fl +import flow360.v1 as fl from flow360.component.v1.flow360_legacy import LinearSolverLegacy from flow360.component.v1.initial_condition import ExpressionInitialCondition from flow360.component.v1.updater import UPDATE_MAP, _find_update_path, _no_update from flow360.exceptions import Flow360NotImplementedError +from flow360.version import __version__ @pytest.fixture(autouse=True) @@ -265,4 +266,4 @@ def test_updater_map(): assert len(update_path) == 3 update_path = _find_update_path(version_from=UPDATE_MAP[0][0], version_to=UPDATE_MAP[-1][1]) - update_path = _find_update_path(version_from=UPDATE_MAP[0][0], version_to=fl.__version__) + update_path = _find_update_path(version_from=UPDATE_MAP[0][0], version_to=__version__) diff --git a/tests/v1/test_validator_valid_output_fields.py b/tests/v1/test_validator_valid_output_fields.py index 4c061874d..7f97c398f 100644 --- a/tests/v1/test_validator_valid_output_fields.py +++ b/tests/v1/test_validator_valid_output_fields.py @@ -2,8 +2,8 @@ import pytest -import flow360.component.v1 as fl import flow360.component.v1.units as u +import flow360.v1 as fl from flow360.component.v1.boundaries import FreestreamBoundary, NoSlipWall from flow360.component.v1.flow360_output import ( IsoSurface, diff --git a/tests/v1/test_volume_mesh.py b/tests/v1/test_volume_mesh.py index 274a80a95..a937ecee5 100644 --- a/tests/v1/test_volume_mesh.py +++ b/tests/v1/test_volume_mesh.py @@ -1,6 +1,6 @@ import pytest -import flow360.component.v1 as v1 +import flow360.v1 as v1 from flow360.component.utils import CompressionFormat, MeshFileFormat, UGRIDEndianness from flow360.component.v1.boundaries import NoSlipWall from flow360.component.v1.flow360_params import ( diff --git a/tools/integrations/schema_generation.py b/tools/integrations/schema_generation.py index 75cb2c11b..0bb9c922f 100644 --- a/tools/integrations/schema_generation.py +++ b/tools/integrations/schema_generation.py @@ -4,7 +4,7 @@ import pydantic.v1 as pd -import flow360.component.v1 as fl +import flow360.v1 as fl from flow360.component.v1.flow360_params import ( BETDiskChord, BETDiskSectionalPolar, diff --git a/tools/integrations/tests/_test_webui_workbench_integration.py b/tools/integrations/tests/_test_webui_workbench_integration.py index 8cc51c036..d8d383b2a 100644 --- a/tools/integrations/tests/_test_webui_workbench_integration.py +++ b/tools/integrations/tests/_test_webui_workbench_integration.py @@ -1,7 +1,7 @@ import json import os -import flow360.component.v1 as fl +import flow360.v1 as fl from flow360.component.simulation.meshing_param.face_params import ( BoundaryLayer, SurfaceRefinement, diff --git a/tools/integrations/unit_defaults.py b/tools/integrations/unit_defaults.py index 8e58f28f7..8ce5a8de6 100644 --- a/tools/integrations/unit_defaults.py +++ b/tools/integrations/unit_defaults.py @@ -3,7 +3,7 @@ import pydantic.v1 as pd -import flow360.component.v1 as fl +import flow360.v1 as fl from flow360.component.v1.params_base import Flow360BaseModel From 280ff2bb41633a4965b0b34d9dd81b19d39f7ad3 Mon Sep 17 00:00:00 2001 From: angranl-flex Date: Fri, 1 Nov 2024 15:28:53 -0400 Subject: [PATCH 5/8] Add documentation for after reorganization (#543) * Add sphinx params plugins * Add more documentations * Update Flow360 * Update solver_numerics * Fix isort --------- Co-authored-by: Ben <106089368+benflexcompute@users.noreply.github.com> --- flow360/__init__.py | 26 +-- .../simulation/models/solver_numerics.py | 190 +++++++++++------ .../simulation/models/surface_models.py | 198 +++++++++++++----- .../models/turbulence_quantities.py | 50 ++++- .../simulation/models/volume_models.py | 126 ++++++----- .../simulation/outputs/output_entities.py | 26 ++- .../component/simulation/outputs/outputs.py | 73 ++++--- flow360/component/simulation/primitives.py | 33 +-- .../simulation/time_stepping/time_stepping.py | 45 ++-- .../user_defined_dynamics.py | 53 ++++- poetry.lock | 4 +- pyproject.toml | 1 + 12 files changed, 555 insertions(+), 270 deletions(-) diff --git a/flow360/__init__.py b/flow360/__init__.py index 1e739ab3d..a4b6a1d7a 100644 --- a/flow360/__init__.py +++ b/flow360/__init__.py @@ -7,7 +7,6 @@ from flow360.component.simulation import services from flow360.component.simulation import units as u from flow360.component.simulation.entity_info import GeometryEntityInfo -from flow360.component.simulation.framework.param_utils import AssetCache from flow360.component.simulation.meshing_param.edge_params import ( HeightBasedRefinement, SurfaceEdgeRefinement, @@ -34,13 +33,13 @@ SpalartAllmaras, SpalartAllmarasModelConstants, TransitionModelSolver, - TransitionModelSolverType, - TurbulenceModelSolverType, ) from flow360.component.simulation.models.surface_models import ( Freestream, HeatFlux, Inflow, + Mach, + MassFlowRate, Outflow, Periodic, Pressure, @@ -78,6 +77,7 @@ ThermalState, ) from flow360.component.simulation.outputs.output_entities import ( + Isosurface, Point, PointArray, Slice, @@ -90,18 +90,12 @@ SurfaceIntegralOutput, SurfaceOutput, SurfaceProbeOutput, + TimeAverageSliceOutput, TimeAverageSurfaceOutput, TimeAverageVolumeOutput, VolumeOutput, ) -from flow360.component.simulation.primitives import ( - Box, - Cylinder, - Edge, - GenericVolume, - ReferenceGeometry, - Surface, -) +from flow360.component.simulation.primitives import Box, Cylinder, ReferenceGeometry from flow360.component.simulation.simulation_params import SimulationParams from flow360.component.simulation.time_stepping.time_stepping import ( AdaptiveCFL, @@ -139,11 +133,8 @@ "UniformRefinement", "SurfaceEdgeRefinement", "HeightBasedRefinement", - "Surface", - "Edge", "ReferenceGeometry", "Cylinder", - "AssetCache", "GeometryEntityInfo", "AerospaceCondition", "ThermalState", @@ -173,6 +164,7 @@ "VolumeOutput", "TimeAverageVolumeOutput", "SliceOutput", + "TimeAverageSliceOutput", "IsosurfaceOutput", "SurfaceIntegralOutput", "ProbeOutput", @@ -185,21 +177,19 @@ "KOmegaSST", "SpalartAllmarasModelConstants", "KOmegaSSTModelConstants", - "TransitionModelSolverType", - "TurbulenceModelSolverType", "LinearSolver", "ForcePerArea", "Air", "Sutherland", "SolidMaterial", "Slice", + "Isosurface", "TurbulenceQuantities", "UserDefinedDynamic", "Translational", "NavierStokesInitialCondition", "FromUserDefinedDynamics", "HeatEquationInitialCondition", - "GenericVolume", "Temperature", "HeatFlux", "Point", @@ -211,4 +201,6 @@ "Pressure", "TotalPressure", "Rotational", + "Mach", + "MassFlowRate", ] diff --git a/flow360/component/simulation/models/solver_numerics.py b/flow360/component/simulation/models/solver_numerics.py index 6ebdf44cd..cc55b066b 100644 --- a/flow360/component/simulation/models/solver_numerics.py +++ b/flow360/component/simulation/models/solver_numerics.py @@ -31,23 +31,23 @@ class LinearSolver(Flow360BaseModel): - """:class:`LinearSolver` class for setting up linear solver for heat equation + """:class:`LinearSolver` class for setting up the linear solver. Example ------- >>> ls = LinearSolver( - max_iterations=50, - absoluteTolerance=1e-10 - ) + ... max_iterations=50, + ... absoluteTolerance=1e-10 + ... ) """ max_iterations: PositiveInt = pd.Field( - 30, description="Maximum number of linear solver iterations" + 30, description="Maximum number of linear solver iterations." ) absolute_tolerance: Optional[PositiveFloat] = pd.Field( None, description="The linear solver converges when the final residual of the pseudo steps below this value." - + "Either absolute tolerance or relative tolerance can be used to determine convergence", + + "Either absolute tolerance or relative tolerance can be used to determine convergence.", ) relative_tolerance: Optional[PositiveFloat] = pd.Field( None, @@ -70,54 +70,60 @@ class GenericSolverSettings(Flow360BaseModel, metaclass=ABCMeta): + "Relative residual is defined as the ratio of the current pseudoStep's residual to the maximum " + "residual present in the first 10 pseudoSteps within the current physicalStep. " + "NOTE: relativeTolerance is ignored in steady simulations and only absoluteTolerance is " - + "used as the convergence criterion", + + "used as the convergence criterion.", ) - order_of_accuracy: Literal[1, 2] = pd.Field(2, description="Order of accuracy in space") + order_of_accuracy: Literal[1, 2] = pd.Field(2, description="Order of accuracy in space.") equation_evaluation_frequency: PositiveInt = pd.Field( - 1, description="Frequency at which to solve the equation" + 1, description="Frequency at which to solve the equation." ) linear_solver: LinearSolver = pd.Field(LinearSolver()) class NavierStokesSolver(GenericSolverSettings): - """:class:`NavierStokesSolver` class for setting up compressible Navier-Stokes solver. + """:class:`NavierStokesSolver` class for setting up the compressible Navier-Stokes solver. For more information on setting up the numerical parameters for the Navier-Stokes solver, refer to :ref:`Navier-Stokes solver knowledge base `. Example ------- - >>> ns = NavierStokesSolver(absolute_tolerance=1e-10) + >>> ns = navier_stokes_solver=NavierStokesSolver(absolute_tolerance=1e-10, + ... numerical_dissipation_factor=0.01, + ... linear_solver=LinearSolver(max_iterations=50), + ... low_mach_preconditioner=True, + ... ) """ absolute_tolerance: PositiveFloat = pd.Field( 1.0e-10, - description="Tolerance for the NS residual, below which the solver goes to the next physical step", + description="Tolerance for the NS residual, below which the solver goes to the next physical step.", ) CFL_multiplier: PositiveFloat = pd.Field( - 1.0, description="Factor to the CFL definitions defined in :code:`time_stepping` section" + 1.0, + description="Factor to the CFL definitions defined in the " + + ":ref:`Time Stepping ` section.", ) kappa_MUSCL: pd.confloat(ge=-1, le=1) = pd.Field( -1, description="Kappa for the MUSCL scheme, range from [-1, 1], with 1 being unstable. " + "The default value of -1 leads to a 2nd order upwind scheme and is the most stable. " + "A value of 0.33 leads to a blended upwind/central scheme and is recommended for low " - + "subsonic flows leading to reduced dissipation", + + "subsonic flows leading to reduced dissipation.", ) numerical_dissipation_factor: pd.confloat(ge=0.01, le=1) = pd.Field( 1, description="A factor in the range [0.01, 1.0] which exponentially reduces the " + "dissipation of the numerical flux. The recommended starting value for most " - + "low-dissipation runs is 0.2", + + "low-dissipation runs is 0.2.", ) limit_velocity: bool = pd.Field(False, description="Limiter for velocity") - limit_pressure_density: bool = pd.Field(False, description="Limiter for pressure and density") + limit_pressure_density: bool = pd.Field(False, description="Limiter for pressure and density.") type_name: Literal["Compressible"] = pd.Field("Compressible", frozen=True) low_mach_preconditioner: bool = pd.Field( - False, description="Use preconditioning for accelerating low Mach number flows" + False, description="Use preconditioning for accelerating low Mach number flows." ) low_mach_preconditioner_threshold: Optional[NonNegativeFloat] = pd.Field( None, @@ -128,17 +134,25 @@ class NavierStokesSolver(GenericSolverSettings): ) update_jacobian_frequency: PositiveInt = pd.Field( - 4, description="Frequency at which the jacobian is updated" + 4, description="Frequency at which the jacobian is updated." ) max_force_jac_update_physical_steps: NonNegativeInt = pd.Field( 0, description="When physical step is less than this value, the jacobian matrix is " - + "updated every pseudo step", + + "updated every pseudo step.", ) class SpalartAllmarasModelConstants(Flow360BaseModel): - """:class:`SpalartAllmarasModelConstants` class""" + """ + :class:`SpalartAllmarasModelConstants` class specifies the constants of the Spalart-Allmaras model. + + Example + ------- + >>> ts = SpalartAllmaras( + ... modeling_constants = SpalartAllmarasModelConstants(C_w2=2.718) + ... ) + """ type_name: Literal["SpalartAllmarasConsts"] = pd.Field("SpalartAllmarasConsts", frozen=True) C_DES: NonNegativeFloat = pd.Field(0.72) @@ -155,7 +169,15 @@ class SpalartAllmarasModelConstants(Flow360BaseModel): class KOmegaSSTModelConstants(Flow360BaseModel): - """:class:`KOmegaSSTModelConstants` class""" + """ + :class:`KOmegaSSTModelConstants` class specifies the constants of the SST k-omega model. + + Example + ------- + >>> ts = SpalartAllmaras( + ... modeling_constants = KOmegaSSTModelConstants(C_sigma_omega1=2.718) + ... ) + """ type_name: Literal["kOmegaSSTConsts"] = pd.Field("kOmegaSSTConsts", frozen=True) C_DES1: NonNegativeFloat = pd.Field(0.78) @@ -189,26 +211,31 @@ class TurbulenceModelSolver(GenericSolverSettings, metaclass=ABCMeta): """ CFL_multiplier: PositiveFloat = pd.Field( - 2.0, description="Factor to the CFL definitions defined in :code:`time_stepping` section" + 2.0, + description="Factor to the CFL definitions defined in the " + + ":ref:`Time Stepping ` section.", + ) + type_name: str = pd.Field( + description=":code:`SpalartAllmaras`, :code:`kOmegaSST`, or :code:`None`." ) - type_name: str = pd.Field() absolute_tolerance: PositiveFloat = pd.Field( 1e-8, - description="Tolerance for the NS residual, below which the solver goes to the next physical step", + description="Tolerance for the turbulence model residual, below which the solver progresses to the " + + "next physical step (unsteady) or completes the simulation (steady).", ) equation_evaluation_frequency: PositiveInt = pd.Field( - 4, description="Frequency at which to update the NS equation in loosely-coupled simulations" + 4, description="Frequency at which to update the turbulence equation." ) DDES: bool = pd.Field( False, - description="Enables Delayed Detached Eddy Simulation. " - + " Supported for both SpalartAllmaras and kOmegaSST turbulence models, " + description=":code:`True` enables Delayed Detached Eddy Simulation. " + + "Supported for both SpalartAllmaras and kOmegaSST turbulence models, " + "with and without AmplificationFactorTransport transition model enabled.", ) grid_size_for_LES: Literal["maxEdgeLength", "meanEdgeLength"] = pd.Field( "maxEdgeLength", description="Specifes the length used for the computation of LES length scale. " - + 'The allowed inputs are "maxEdgeLength" and "meanEdgeLength"', + + "The allowed inputs are :code:`maxEdgeLength` and :code:`meanEdgeLength`.", ) reconstruction_gradient_limiter: pd.confloat(ge=0, le=2) = pd.Field( 1.0, @@ -219,22 +246,23 @@ class TurbulenceModelSolver(GenericSolverSettings, metaclass=ABCMeta): quadratic_constitutive_relation: bool = pd.Field( False, description="Use quadratic constitutive relation for turbulence shear stress tensor " - + "instead of Boussinesq Approximation", + + "instead of Boussinesq Approximation.", ) modeling_constants: Optional[TurbulenceModelConstants] = pd.Field( discriminator="type_name", - description=" A dictionary containing the DDES coefficients in the solver: **SpalartAllmaras**: " - + ':code:`"C_DES"` (= 0.72), :code:`"C_d"` (= 8.0), **kOmegaSST**: :code:`"C_DES1"` (= 0.78), ' - + ':code:`"C_DES2"` (= 0.61), :code:`"C_d1"` (= 20.0), :code:`"C_d2"` (= 3.0), ' - + "*(values shown in the parentheses are the default values used in Flow360)*", + description=" A :class:`TurbulenceModelConstants` object containing the DDES coefficients " + + "in the solver: **SpalartAllmaras**: :code:`C_DES` (= 0.72), :code:`C_d` (= 8.0)," + + '**kOmegaSST**: :code:`"C_DES1"` (= 0.78), ' + + ":code:`C_DES2` (= 0.61), :code:`C_d1` (= 20.0), :code:`C_d2` (= 3.0), " + + "*(values shown in the parentheses are the default values used in Flow360).*", ) update_jacobian_frequency: PositiveInt = pd.Field( - 4, description="Frequency at which the jacobian is updated" + 4, description="Frequency at which the jacobian is updated." ) max_force_jac_update_physical_steps: NonNegativeInt = pd.Field( 0, description="For physical steps less than the input value, the jacobian matrix is " - + "updated every pseudo-step overriding the :code:`updateJacobianFrequency` value", + + "updated every pseudo-step overriding the :paramref:`update_jacobian_frequency` value.", ) linear_solver: LinearSolver = pd.Field( @@ -244,26 +272,61 @@ class TurbulenceModelSolver(GenericSolverSettings, metaclass=ABCMeta): class KOmegaSST(TurbulenceModelSolver): - """:class:`KOmegaSST` class for setting up the turbulence solver based on the SST k-omega model.""" + """ + :class:`KOmegaSST` class for setting up the turbulence solver based on the SST k-omega model. + + Example + ------- + >>> ts = KOmegaSST( + ... absolute_tolerance=1e-10, + ... linear_solver=LinearSolver(max_iterations=25), + ... update_jacobian_frequency=2, + ... equation_evaluation_frequency=1, + ... ) + """ type_name: Literal["kOmegaSST"] = pd.Field("kOmegaSST", frozen=True) - modeling_constants: KOmegaSSTModelConstants = pd.Field(KOmegaSSTModelConstants()) + modeling_constants: KOmegaSSTModelConstants = pd.Field( + KOmegaSSTModelConstants(), + description="A :class:`KOmegaSSTModelConstants` object containing the coefficients " + + "used in the SST k-omega model. For the default values used in Flow360, " + + "please refer to :class:`KOmegaSSTModelConstants`.", + ) class SpalartAllmaras(TurbulenceModelSolver): - """:class:`SpalartAllmaras` class for setting up the turbulence solver based on the Spalart–Allmaras model""" + """ + :class:`SpalartAllmaras` class for setting up the turbulence solver based on the Spalart-Allmaras model. + + Example + ------- + >>> ts = SpalartAllmaras( + ... absolute_tolerance=1e-10, + ... linear_solver=LinearSolver(max_iterations=25), + ... update_jacobian_frequency=2, + ... equation_evaluation_frequency=1, + ... ) + """ type_name: Literal["SpalartAllmaras"] = pd.Field("SpalartAllmaras", frozen=True) rotation_correction: bool = pd.Field(False) modeling_constants: Optional[SpalartAllmarasModelConstants] = pd.Field( - SpalartAllmarasModelConstants() + SpalartAllmarasModelConstants(), + description="A :class:`SpalartAllmarasModelConstants` object containing the coefficients " + + "used in the Spalart-Allmaras model. For the default values used in Flow360, " + + "please refer to :class:`SpalartAllmarasModelConstants`.", + ) + reconstruction_gradient_limiter: Optional[pd.confloat(ge=0, le=2)] = pd.Field( + 0.5, + description="The strength of gradient limiter used in reconstruction of solution " + + "variables at the faces (specified in the range [0.0, 2.0]). 0.0 corresponds to " + + "setting the gradient equal to zero, and 2.0 means no limiting.", ) - reconstruction_gradient_limiter: Optional[pd.confloat(ge=0, le=2)] = pd.Field(0.5) class NoneSolver(Flow360BaseModel): - """:class:`NoneSolver` class""" + """:class:`NoneSolver` class for disabling the turbulence solver.""" type_name: Literal["None"] = pd.Field("None", frozen=True) @@ -274,17 +337,17 @@ class NoneSolver(Flow360BaseModel): class HeatEquationSolver(GenericSolverSettings): - """`HeatEquationSolver` class for setting up heat equation solver. + """:class:`HeatEquationSolver` class for setting up heat equation solver. Example ------- >>> he = HeatEquationSolver( - equation_evaluation_frequency=10, - linear_solver_config=LinearSolver( - max_iterations=50, - absoluteTolerance=1e-10 - ) - ) + ... equation_evaluation_frequency=10, + ... linear_solver_config=LinearSolver( + ... max_iterations=50, + ... absoluteTolerance=1e-10 + ... ) + ... ) """ type_name: Literal["HeatEquation"] = pd.Field("HeatEquation", frozen=True) @@ -296,9 +359,9 @@ class HeatEquationSolver(GenericSolverSettings): ) equation_evaluation_frequency: PositiveInt = pd.Field( 10, - description="Frequency at which to solve the heat equation in conjugate heat transfer simulations", + description="Frequency at which to solve the heat equation in conjugate heat transfer simulations.", ) - order_of_accuracy: Literal[2] = pd.Field(2, description="Order of accuracy in space") + order_of_accuracy: Literal[2] = pd.Field(2, description="Order of accuracy in space.") linear_solver: LinearSolver = pd.Field( LinearSolver(max_iterations=50, absolute_tolerance=1e-10), @@ -321,39 +384,48 @@ class TransitionModelSolver(GenericSolverSettings): "AmplificationFactorTransport", frozen=True ) CFL_multiplier: PositiveFloat = pd.Field( - 2.0, description="Factor to the CFL definitions defined in :code:`time_stepping` section" + 2.0, + description="Factor to the CFL definitions defined in the " + + ":ref:`Time Stepping ` section.", ) absolute_tolerance: PositiveFloat = pd.Field( 1e-7, description="Tolerance for the transition model residual, below which the solver progresses to " - + "the next physical step (unsteady) or completes the simulation (steady)", + + "the next physical step (unsteady) or completes the simulation (steady).", ) equation_evaluation_frequency: PositiveInt = pd.Field( - 4, description="Frequency at which to update the transition equation" + 4, description="Frequency at which to update the transition equation." ) turbulence_intensity_percent: Optional[pd.confloat(ge=0.03, le=2.5)] = pd.Field( 1.0, description=":ref:`Turbulence Intensity `, Range from [0.03-2.5]. " - + "Only valid when :code:`Ncrit` is not specified.", + + "Only valid when :paramref:`N_crit` is not specified.", ) # pylint: disable=invalid-name N_crit: Optional[pd.confloat(ge=1.0, le=11.0)] = pd.Field( None, description=":ref:`Critical Amplification Factor `, Range from [1-11]. " - + "Only valid when :code:`turbulenceIntensityPercent` is not specified.", + + "Only valid when :paramref:`turbulence_intensity_percent` is not specified.", ) update_jacobian_frequency: PositiveInt = pd.Field( - 4, description="Frequency at which the jacobian is updated" + 4, description="Frequency at which the jacobian is updated." ) max_force_jac_update_physical_steps: NonNegativeInt = pd.Field( 0, description="For physical steps less than the input value, the jacobian matrix " - + "is updated every pseudo-step overriding the :code:`updateJacobianFrequency` value", + + "is updated every pseudo-step overriding the :paramref:`update_jacobian_frequency` value.", ) - reconstruction_gradient_limiter: Optional[pd.confloat(ge=0.0, le=2.0)] = pd.Field(1.0) + reconstruction_gradient_limiter: Optional[pd.confloat(ge=0.0, le=2.0)] = pd.Field( + 1.0, + description="The strength of gradient limiter used in reconstruction of solution " + + "variables at the faces (specified in the range [0.0, 2.0]). 0.0 corresponds to " + + "setting the gradient equal to zero, and 2.0 means no limiting.", + ) - trip_regions: Optional[EntityList[Box]] = pd.Field(None) + trip_regions: Optional[EntityList[Box]] = pd.Field( + None, description="A list of :class:`~flow360.Box` entities defining the trip zones." + ) linear_solver: LinearSolver = pd.Field( LinearSolver(max_iterations=20), diff --git a/flow360/component/simulation/models/surface_models.py b/flow360/component/simulation/models/surface_models.py index 0ca9d5afa..ba35b0c67 100644 --- a/flow360/component/simulation/models/surface_models.py +++ b/flow360/component/simulation/models/surface_models.py @@ -42,63 +42,94 @@ class BoundaryBase(Flow360BaseModel, metaclass=ABCMeta): class BoundaryBaseWithTurbulenceQuantities(BoundaryBase, metaclass=ABCMeta): """Boundary base with turbulence quantities""" - turbulence_quantities: Optional[TurbulenceQuantitiesType] = pd.Field(None) + turbulence_quantities: Optional[TurbulenceQuantitiesType] = pd.Field( + None, + description="The turbulence related quantities definition." + + "See :func:`TurbulenceQuantities` documentation.", + ) class HeatFlux(SingleAttributeModel): - """Heat flux""" + """ + :class:`HeatFlux` class to specify the heat flux for `Wall` boundary condition + via :paramref:`Wall.heat_spec`. + """ type_name: Literal["HeatFlux"] = pd.Field("HeatFlux", frozen=True) - value: Union[HeatFluxType, pd.StrictStr] = pd.Field() + value: Union[HeatFluxType, pd.StrictStr] = pd.Field(description="The heat flux value.") class Temperature(SingleAttributeModel): - """Temperature""" + """ + :class:`Temperature` class to specify the temperature for `Wall` or `Inflow` + boundary condition via :paramref:`Wall.heat_spec`/ + :paramref:`Inflow.spec`. + """ type_name: Literal["Temperature"] = pd.Field("Temperature", frozen=True) # pylint: disable=no-member - value: Union[TemperatureType.Positive, pd.StrictStr] = pd.Field() + value: Union[TemperatureType.Positive, pd.StrictStr] = pd.Field( + description="The temperature value." + ) class TotalPressure(SingleAttributeModel): - """Total pressure""" + """ + :class:`TotalPressure` class to specify the total pressure for `Inflow` + boundary condition via :paramref:`Inflow.spec`. + """ type_name: Literal["TotalPressure"] = pd.Field("TotalPressure", frozen=True) # pylint: disable=no-member - value: PressureType.Positive = pd.Field() + value: PressureType.Positive = pd.Field(description="The total pressure value.") class Pressure(SingleAttributeModel): - """Pressure""" + """ + :class:`Pressure` class to specify the pressure for `Outflow` + boundary condition via :paramref:`Outflow.spec`. + """ type_name: Literal["Pressure"] = pd.Field("Pressure", frozen=True) # pylint: disable=no-member - value: PressureType.Positive = pd.Field() + value: PressureType.Positive = pd.Field(description="The pressure value.") class MassFlowRate(SingleAttributeModel): - """Mass flow rate""" + """ + :class:`MassFlowRate` class to specify the mass flow rate for `Inflow` or `Outflow` + boundary condition via :paramref:`Inflow.spec`/:paramref:`Outflow.spec`. + """ type_name: Literal["MassFlowRate"] = pd.Field("MassFlowRate", frozen=True) # pylint: disable=no-member - value: MassFlowRateType.NonNegative = pd.Field() + value: MassFlowRateType.NonNegative = pd.Field(description="The mass flow rate.") class Mach(SingleAttributeModel): - """Mach""" + """ + :class:`Mach` class to specify Mach number for the `Inflow` + boundary condition via :paramref:`Inflow.spec`. + """ type_name: Literal["Mach"] = pd.Field("Mach", frozen=True) - value: pd.NonNegativeFloat = pd.Field() + value: pd.NonNegativeFloat = pd.Field(description="The Mach number.") class Translational(Flow360BaseModel): - """Translational periodicity""" + """ + :class:`Translational` class to specify translational periodic + boundary condition via :paramref:`Periodic.spec`. + """ type_name: Literal["Translational"] = pd.Field("Translational", frozen=True) class Rotational(Flow360BaseModel): - """Rotational periodicity""" + """ + :class:`Rotational` class to specify rotational periodic + boundary condition via :paramref:`Periodic.spec`. + """ type_name: Literal["Rotational"] = pd.Field("Rotational", frozen=True) # pylint: disable=fixme @@ -112,83 +143,140 @@ class Rotational(Flow360BaseModel): class Wall(BoundaryBase): - """Replace Flow360Param: - - NoSlipWall - - IsothermalWall - - HeatFluxWall - - WallFunction - - SolidIsothermalWall - - SolidAdiabaticWall + """ + :class:`Wall` class defines the Wall boundary conditions below based on the input: + - NoSlipWall + - IsothermalWall + - HeatFluxWall + - WallFunction + - SolidIsothermalWall + - SolidAdiabaticWall """ - name: Optional[str] = pd.Field(None) + name: Optional[str] = pd.Field(None, description="Name of the `Wall` boundary condition.") type: Literal["Wall"] = pd.Field("Wall", frozen=True) - use_wall_function: bool = pd.Field(False) - velocity: Optional[VelocityVectorType] = pd.Field(None) - heat_spec: Optional[Union[HeatFlux, Temperature]] = pd.Field(None, discriminator="type_name") + use_wall_function: bool = pd.Field( + False, + description="Specify if use wall functions to estimate the velocity field " + + "close to the solid boundaries.", + ) + velocity: Optional[VelocityVectorType] = pd.Field( + None, description="Prescribe a tangential velocity on the wall." + ) + heat_spec: Optional[Union[HeatFlux, Temperature]] = pd.Field( + None, + discriminator="type_name", + description="Specify the heat flux or temperature at the `Wall` boundary.", + ) class Freestream(BoundaryBaseWithTurbulenceQuantities): - """Freestream""" + """ + :class:`Freestream` defines the Freestream condition. + """ - name: Optional[str] = pd.Field(None) + name: Optional[str] = pd.Field(None, description="Name of the `Freestream` boundary condition.") type: Literal["Freestream"] = pd.Field("Freestream", frozen=True) - velocity: Optional[VelocityVectorType] = pd.Field(None) - entities: EntityList[Surface, GhostSurface] = pd.Field(alias="surfaces") + velocity: Optional[VelocityVectorType] = pd.Field( + None, + description="The default values are set according to the " + + ":paramref:`AerospaceCondition.alpha` and :paramref:`AerospaceCondition.beta` angles. " + + "Optionally, an expression for each of the velocity components can be specified.", + ) + entities: EntityList[Surface, GhostSurface] = pd.Field( + alias="surfaces", + description="A list of :class:`Surface` entities with " + + "the `Freestream` boundary condition imposed.", + ) class Outflow(BoundaryBase): - """Replace Flow360Param: - - SubsonicOutflowPressure - - SubsonicOutflowMach - - MassOutflow + """ + :class:`Outflow` defines the Outflow boundary conditions below based on the input: + - SubsonicOutflowPressure + - SubsonicOutflowMach + - MassOutflow """ - name: Optional[str] = pd.Field(None) + name: Optional[str] = pd.Field(None, description="Name of the `Outflow` boundary condition.") type: Literal["Outflow"] = pd.Field("Outflow", frozen=True) - spec: Union[Pressure, MassFlowRate, Mach] = pd.Field(discriminator="type_name") + spec: Union[Pressure, MassFlowRate, Mach] = pd.Field( + discriminator="type_name", + description="Specify the static pressure, mass flow rate or Mach number at the `Outflow` boundary.", + ) class Inflow(BoundaryBaseWithTurbulenceQuantities): - """Replace Flow360Param: - - SubsonicInflow - - MassInflow + """ + :class:`Inflow` defines the Inflow boundary condition below based on the input: + - SubsonicInflow + - MassInflow """ - name: Optional[str] = pd.Field(None) + name: Optional[str] = pd.Field(None, description="Name of the `Inflow` boundary condition.") type: Literal["Inflow"] = pd.Field("Inflow", frozen=True) # pylint: disable=no-member - total_temperature: TemperatureType.Positive = pd.Field() - velocity_direction: Optional[Axis] = pd.Field(None) - spec: Union[TotalPressure, MassFlowRate] = pd.Field(discriminator="type_name") + total_temperature: TemperatureType.Positive = pd.Field( + description="Specify the total temperature at the `Inflow` boundary." + ) + velocity_direction: Optional[Axis] = pd.Field( + None, + description=" Direction of the incoming flow. Must be a unit vector pointing " + + "into the volume. If unspecified, the direction will be normal to the surface.", + ) + spec: Union[TotalPressure, MassFlowRate] = pd.Field( + discriminator="type_name", + description="Specify the total pressure or the mass flow rate at the `Inflow` boundary.", + ) class SlipWall(BoundaryBase): - """Slip wall""" + """:class:`SlipWall` class defines the SlipWall boundary condition.""" - name: Optional[str] = pd.Field(None) + name: Optional[str] = pd.Field(None, description="Name of the `SlipWall` boundary condition.") type: Literal["SlipWall"] = pd.Field("SlipWall", frozen=True) - entities: EntityList[Surface, GhostSurface] = pd.Field(alias="surfaces") + entities: EntityList[Surface, GhostSurface] = pd.Field( + alias="surfaces", + description="A list of :class:`Surface` entities with " + + "the `SlipWall` boundary condition imposed.", + ) class SymmetryPlane(BoundaryBase): - """Symmetry plane""" + """ + :class:`SymmetryPlane` defines the `SymmetryPlane` boundary condition. + It is similar to :class:`SlipWall`, but the normal gradient of scalar quantities + are forced to be zero on the symmetry plane. Only planar surfaces are supported. + """ - name: Optional[str] = pd.Field(None) + name: Optional[str] = pd.Field( + None, description="Name of the `SymmetryPlane` boundary condition." + ) type: Literal["SymmetryPlane"] = pd.Field("SymmetryPlane", frozen=True) - entities: EntityList[Surface, GhostSurface] = pd.Field(alias="surfaces") + entities: EntityList[Surface, GhostSurface] = pd.Field( + alias="surfaces", + description="A list of :class:`Surface` entities with " + + "the `SymmetryPlane` boundary condition imposed.", + ) class Periodic(Flow360BaseModel): - """Replace Flow360Param: - - TranslationallyPeriodic - - RotationallyPeriodic + """ + :class:`Periodic` defines the translational or rotational periodic boundary condition. """ - name: Optional[str] = pd.Field(None) + name: Optional[str] = pd.Field(None, description="Name of the `Periodic` boundary condition.") type: Literal["Periodic"] = pd.Field("Periodic", frozen=True) - entity_pairs: UniqueItemList[SurfacePair] = pd.Field(alias="surface_pairs") - spec: Union[Translational, Rotational] = pd.Field(discriminator="type_name") + entity_pairs: UniqueItemList[SurfacePair] = pd.Field( + alias="surface_pairs", + description=" Patch name of the matching pair of a :class:`~flow360.Surface` patch. " + + "Needs to be specified for one side of each of the periodic boundary pairs.", + ) + spec: Union[Translational, Rotational] = pd.Field( + discriminator="type_name", + description="Define the type of periodic boundary condition (translational/rotational) " + + "via :class:`Translational`/:class:`Rotational`.", + ) SurfaceModelTypes = Union[ diff --git a/flow360/component/simulation/models/turbulence_quantities.py b/flow360/component/simulation/models/turbulence_quantities.py index e68abc3fd..2a15d808f 100644 --- a/flow360/component/simulation/models/turbulence_quantities.py +++ b/flow360/component/simulation/models/turbulence_quantities.py @@ -202,7 +202,55 @@ def TurbulenceQuantities( turbulent_length_scale=None, turbulent_intensity=None, ) -> TurbulenceQuantitiesType: - """Return a matching tubulence specification object""" + """ + + :func:`TurbulenceQuantities` function specifies turbulence conditions + for the :class:`~flow360.Inflow` or :class:`~flow360.Freestream` + at boundaries. The turbulence properties that can be + specified are listed below. All values are dimensional. + For valid specifications as well as the default values, + please refer to :ref:`knowledge base`. + + Parameters + ---------- + viscosity_ratio : >= 0 + The ratio between the turbulent viscosity and freestream laminar + viscosity. Applicable to both :class:`~flow360.KOmegaSST` and + `~flow360.SpalartAllmaras`. Its value will be converted to + :paramref:`modifiedTurbulentViscosityRatio` when using + SpalartAllmaras model. + modified_viscosity_ratio : >= 0 + The ratio between the modified turbulent viscosity (in SA model) and + freestream laminar viscosity. + Applicable to :class:`~flow360.SpalartAllmaras`. + modified_viscosity : >=0 + The modified turbulent viscosity, aka nuHat. + Applicable to :class:`~flow360.SpalartAllmaras`. + specific_dissipation_rate : >= 0 + The turbulent specific dissipation rate. Applicable to :class:`~flow360.KOmegaSST`. + turbulent_kinetic_energy : >=0 + The turbulent kinetic energy. Applicable to :class:`~flow360.KOmegaSST`. + turbulent_length_scale : > 0 + The turbulent length scale is an estimation of the size of + the eddies that are modeled/not resolved. + Applicable to :class:`~flow360.KOmegaSST`. + turbulent_intensity : >= 0 + The turbulent intensity is related to the turbulent kinetic energy by + :math:`k = 1.5(U_{ref} * I)^2` where :math:`k` is the dimensional + turbulent kinetic energy, :math:`U_{ref}` is the reference velocity + and :math:`I` is the turbulent intensity. The value represents the + actual magnitude of intensity instead of percentage. Applicable to + :class:`~flow360.KOmegaSST`. + + Returns + ------- + A matching tubulence specification object. + + Raises + ------- + ValueError + If the TurbulenceQuantities inputs do not represent a valid specification. + """ non_none_arg_count = sum(arg is not None for arg in locals().values()) if non_none_arg_count == 0: return None diff --git a/flow360/component/simulation/models/volume_models.py b/flow360/component/simulation/models/volume_models.py index b720860b4..f677576f6 100644 --- a/flow360/component/simulation/models/volume_models.py +++ b/flow360/component/simulation/models/volume_models.py @@ -51,30 +51,39 @@ class AngleExpression(SingleAttributeModel): - """Angle expression for Rotation""" + """ + :class:`AngleExpression` class for define the angle expression for :paramref:`Rotation.spec`. + """ type_name: Literal["AngleExpression"] = pd.Field("AngleExpression", frozen=True) value: StringExpression = pd.Field( - description="The expression defining the rotation angle " + "as a function of time." + description="The expression defining the rotation angle as a function of time." ) class AngularVelocity(SingleAttributeModel): - """Angular velocity for Rotation""" + """ + :class:`AngularVelocity` class to define the angular velocity for :paramref:`Rotation.spec`. + """ type_name: Literal["AngularVelocity"] = pd.Field("AngularVelocity", frozen=True) value: AngularVelocityType = pd.Field(description="The value of the angular velocity.") class FromUserDefinedDynamics(Flow360BaseModel): - """Rotation is controlled by user defined dynamics""" + """ + :class:`FromUserDefinedDynamics` class to define the rotation + controlled by user defined dynamics for :paramref:`Rotation.spec`. + """ type_name: Literal["FromUserDefinedDynamics"] = pd.Field("FromUserDefinedDynamics", frozen=True) class ExpressionInitialConditionBase(Flow360BaseModel): - """:class:`ExpressionInitialCondition` class for specifying the intial conditions of - :class:`~flow360.component.simulation.models.solver_numerics.NavierStokesSolver`.""" + """ + :class:`ExpressionInitialCondition` class for specifying the intial conditions of + :paramref:`Fluid.initial_condition`. + """ type: Literal["expression"] = pd.Field("expression", frozen=True) constants: Optional[Dict[str, str]] = pd.Field( @@ -85,8 +94,9 @@ class ExpressionInitialConditionBase(Flow360BaseModel): # pylint: disable=missing-class-docstring class NavierStokesInitialCondition(ExpressionInitialConditionBase): """ - :class:`NavierStokesInitialCondition` class for specifying the intial conditions of - :class:`~flow360.component.simulation.models.solver_numerics.NavierStokesSolver`. + :class:`NavierStokesInitialCondition` class for specifying the + :paramref:`Fluid.initial_condition`. + """ rho: str = pd.Field(description="Density") @@ -102,7 +112,8 @@ class NavierStokesModifiedRestartSolution(NavierStokesInitialCondition): class HeatEquationInitialCondition(ExpressionInitialConditionBase): """ - :class:`HeatEquationInitialCondition` class for specifying the intial conditions of heat equation in :class:`Solid`. + :class:`HeatEquationInitialCondition` class for specifying the + :paramref:`Solid.initial_condition` of heat equation. """ temperature: str = pd.Field(description="The initial temperature value") @@ -128,25 +139,25 @@ class Fluid(PDEModelBase): navier_stokes_solver: NavierStokesSolver = pd.Field( NavierStokesSolver(), description="Navier-Stokes solver settings, see " - + ":class:`~flow360.component.simulation.models.solver_numerics.NavierStokesSolver` documentation.", + + ":class:`NavierStokesSolver` documentation.", ) turbulence_model_solver: TurbulenceModelSolverType = pd.Field( SpalartAllmaras(), description="Turbulence model solver settings, see " - + ":class:`~flow360.component.simulation.models.solver_numerics.TurbulenceModelSolver` documentation.", + + ":class:`~flow360.TurbulenceModelSolver` documentation.", ) transition_model_solver: TransitionModelSolverType = pd.Field( NoneSolver(), description="Transition solver settings, see " - + ":class:`~flow360.component.simulation.models.solver_numerics.TransitionModelSolver` documentation.", + + ":class:`~flow360.TransitionModelSolver` documentation.", ) - material: FluidMaterialTypes = pd.Field(Air(), description="The material propetry of fluid") + material: FluidMaterialTypes = pd.Field(Air(), description="The material propetry of fluid.") initial_condition: Optional[ Union[NavierStokesModifiedRestartSolution, NavierStokesInitialCondition] ] = pd.Field( - None, discriminator="type", description="The initial condition of the fluid solver" + None, discriminator="type", description="The initial condition of the fluid solver." ) # pylint: disable=fixme @@ -163,29 +174,29 @@ class Solid(PDEModelBase): type: Literal["Solid"] = pd.Field("Solid", frozen=True) entities: EntityList[GenericVolume] = pd.Field( alias="volumes", - description="The list of solid entities on which the heat transfer equation is solved.", + description="The list of :class:`GenericVolume` " + + "entities on which the heat transfer equation is solved.", ) - material: SolidMaterialTypes = pd.Field(description="The material property of solid") + material: SolidMaterialTypes = pd.Field(description="The material property of solid.") heat_equation_solver: HeatEquationSolver = pd.Field( HeatEquationSolver(), description="Heat equation solver settings, see " - + ":class:`~flow360.component.simulation.models.solver_numerics.HeatEquationSolver` documentation. " - + ":class:`~flow360.component.simulation.outputs.outputs.SurfaceIntegralOutput`", + + ":class:`HeatEquationSolver` documentation.", ) volumetric_heat_source: Union[HeatSourceType, pd.StrictStr] = pd.Field( - 0, description="The volumetric heat source" + 0, description="The volumetric heat source." ) initial_condition: Optional[HeatEquationInitialCondition] = pd.Field( - None, description="The initial condition of the heat equation solver" + None, description="The initial condition of the heat equation solver." ) # pylint: disable=duplicate-code class ForcePerArea(Flow360BaseModel): - """:class:`ForcePerArea` class for setting up force per area for Actuator Disk + """:class:`ForcePerArea` class for setting up force per area for Actuator Disk. Example ------- @@ -198,15 +209,13 @@ class ForcePerArea(Flow360BaseModel): radius: LengthType.Array = pd.Field(description="Radius of the sampled locations in grid unit.") # pylint: disable=no-member thrust: PressureType.Array = pd.Field( - description="Force per area in the axial direction, positive means the axial force follows the same " - + "direction as the thrust axis. " - + "It is non-dimensional: :math:`\\frac{\\text{thrustPerArea}(SI=N/m^2)}{\\rho_\\infty C^2_\\infty}`" + description="Dimensional force per area in the axial direction, positive means the axial " + + "force follows the same direction as the thrust axis. " ) # pylint: disable=no-member circumferential: PressureType.Array = pd.Field( - description="Force per area in the circumferential direction, positive means the circumferential force " - + "follows the same direction as the thrust axis with the right hand rule. It is non-dimensional: " - + ":math:`\\frac{\\text{circumferentialForcePerArea}(SI=N/m^2)}{\\rho_\\infty C^2_\\infty}`" + description="Dimensional force per area in the circumferential direction, positive means the " + + "circumferential force follows the same direction as the thrust axis with the right hand rule. " ) # pylint: disable=no-self-argument, missing-function-docstring @@ -235,10 +244,10 @@ class ActuatorDisk(Flow360BaseModel): entities: EntityList[Cylinder] = pd.Field( alias="volumes", - description="The list of `Cylinder` entities for the ActuatorDisk model", + description="The list of :class:`Cylinder` entities for the `ActuatorDisk` model", ) force_per_area: ForcePerArea = pd.Field( - description="The force per area input for the ActuatorDisk model. " + description="The force per area input for the `ActuatorDisk` model. " + "See :class:`ForcePerArea` documentation." ) name: Optional[str] = pd.Field(None, description="Name of the `ActuatorDisk` model.") @@ -246,7 +255,7 @@ class ActuatorDisk(Flow360BaseModel): class BETDiskTwist(Flow360BaseModel): - """:class:`BETDiskTwist` class for setting up twist for BETDisk""" + """:class:`BETDiskTwist` class for setting up the :paramref:`BETDisk.twists`.""" # TODO: Use dimensioned values, why optional? radius: Optional[float] = pd.Field(None, description="A list of radial locations.") @@ -258,7 +267,7 @@ class BETDiskTwist(Flow360BaseModel): class BETDiskChord(Flow360BaseModel): - """:class:`BETDiskChord` class for setting up chord for BETDisk""" + """:class:`BETDiskChord` class for setting up the :paramref:`BETDisk.chords`.""" # TODO: Use dimensioned values, why optional? radius: Optional[float] = pd.Field(None, description="A list of radial locations.") @@ -270,14 +279,14 @@ class BETDiskChord(Flow360BaseModel): class BETDiskSectionalPolar(Flow360BaseModel): - """:class:`BETDiskSectionalPolar` class for setting up sectional polars for BETDisk. - There are two variables, “lift_coeffs” and “drag_coeffs”, + """:class:`BETDiskSectionalPolar` class for setting up :paramref:`BETDisk.sectional_polars` + for :class:`BETDisk`. There are two variables, “lift_coeffs” and “drag_coeffs”, need to be set up as 3D arrays (implemented as nested lists). - The first index of the array corresponds to the :code:`MachNumbers` of the specified polar - data. - The second index of the array corresponds to the :code:`ReynoldsNumbers` of the polar - data. - The third index corresponds to the :code:`alphas`. + The first index of the array corresponds to the :paramref:`BETDisk.mach_numbers` + of the specified polar data. + The second index of the array corresponds to the :paramref:`BETDisk.reynolds_numbers` + of the polar data. + The third index corresponds to the :paramref:`BETDisk.alphas`. The value specifies the lift or drag coefficient, respectively. """ @@ -312,23 +321,20 @@ class BETDisk(Flow360BaseModel): "rightHand", description='The rule for rotation direction and thrust direction, "rightHand" or "leftHand".', ) - number_of_blades: pd.StrictInt = pd.Field(gt=0, le=10, description="Number of blades to model") - omega: AngularVelocityType.NonNegative = pd.Field( - description="Nondimensional rotating speed, radians/nondim-unit-time, " - + "= :math:`\\frac{\\Omega*L_{gridUnit}}{C_\\infty}`" - ) + number_of_blades: pd.StrictInt = pd.Field(gt=0, le=10, description="Number of blades to model.") + omega: AngularVelocityType.NonNegative = pd.Field(description="Rotating speed.") chord_ref: LengthType.Positive = pd.Field( - description="Nondimensional reference chord used to compute sectional blade loadings" + description="Dimensional reference chord used to compute sectional blade loadings." ) n_loading_nodes: pd.StrictInt = pd.Field( gt=0, le=1000, description="Number of nodes used to compute the sectional thrust and " - + "torque coefficients :math:`C_t` and :math:`C_q`, defined in :ref:`betDiskLoadingNote`", + + "torque coefficients :math:`C_t` and :math:`C_q`, defined in :ref:`betDiskLoadingNote`.", ) blade_line_chord: LengthType.NonNegative = pd.Field( 0, - description="Nondimensional chord to use if performing an unsteady BET Line simulation. " + description="Dimensional chord to use if performing an unsteady BET Line simulation. " + "Default of 0.0 is an indication to run a steady BET Disk simulation.", ) initial_blade_direction: Optional[Axis] = pd.Field( @@ -338,20 +344,20 @@ class BETDisk(Flow360BaseModel): ) tip_gap: Union[Literal["inf"], LengthType.NonNegative] = pd.Field( "inf", - description="Nondimensional distance between blade tip and solid bodies to " + description="Dimensional distance between blade tip and solid bodies to " + "define a :ref:`tip loss factor `.", ) mach_numbers: List[pd.NonNegativeFloat] = pd.Field( description="Mach numbers associated with airfoil polars provided " - + "in :code:`sectionalPolars`" + + "in :class:`BETDiskSectionalPolar`." ) reynolds_numbers: List[pd.PositiveFloat] = pd.Field( description="Reynolds numbers associated with the airfoil polars " - + "provided in :code:`sectionalPolars`" + + "provided in :class:`BETDiskSectionalPolar`." ) alphas: List[float] = pd.Field( description="Alphas associated with airfoil polars provided in " - + ":code:`sectionalPolars` in degrees" + + ":class:`BETDiskSectionalPolar` in degrees." ) twists: List[BETDiskTwist] = pd.Field( description="A list of :class:`BETDiskTwist` objects specifying the twist in degrees as a " @@ -363,11 +369,11 @@ class BETDisk(Flow360BaseModel): ) sectional_polars: List[BETDiskSectionalPolar] = pd.Field( description="A list of :class:`BETDiskSectionalPolar` objects for every radial location specified in " - + ":attr:`sectional_radiuses`." + + ":paramref:`sectional_radiuses`." ) sectional_radiuses: List[float] = pd.Field( description="A list of the radial locations in grid units at which :math:`C_l` " - + "and :math:`C_d` are specified in :code:`sectional_polars`" + + "and :math:`C_d` are specified in :class:`BETDiskSectionalPolar`." ) @pd.model_validator(mode="after") @@ -419,7 +425,7 @@ class Rotation(Flow360BaseModel): type: Literal["Rotation"] = pd.Field("Rotation", frozen=True) entities: EntityList[GenericVolume, Cylinder] = pd.Field( alias="volumes", - description="The entity list for the Rotation model. " + description="The entity list for the `Rotation` model. " + "The entity should be :class:`Cylinder` or :class:`GenericVolume` type.", ) @@ -429,7 +435,9 @@ class Rotation(Flow360BaseModel): description="The angular velocity or rotation angle as a function of time.", ) parent_volume: Optional[Union[GenericVolume, Cylinder]] = pd.Field( - None, description="The parent rotating entity in a nested rotation case." + None, + description="The parent rotating entity in a nested rotation case." + + "The entity should be :class:`Cylinder` or :class:`GenericVolume` type.", ) @pd.field_validator("entities", mode="after") @@ -457,7 +465,11 @@ class PorousMedium(Flow360BaseModel): name: Optional[str] = pd.Field(None, description="Name of the `PorousMedium` model.") type: Literal["PorousMedium"] = pd.Field("PorousMedium", frozen=True) - entities: EntityList[GenericVolume, Box] = pd.Field(alias="volumes") + entities: EntityList[GenericVolume, Box] = pd.Field( + alias="volumes", + description="The entity list for the `PorousMedium` model. " + + "The entity should be :class:`Box` type.", + ) darcy_coefficient: InverseAreaType.Point = pd.Field( description="Darcy coefficient of the porous media model which determines the scaling of the " @@ -466,10 +478,10 @@ class PorousMedium(Flow360BaseModel): ) forchheimer_coefficient: InverseLengthType.Point = pd.Field( description="Forchheimer coefficient of the porous media model which determines " - + "the scaling of the inertial loss term" + + "the scaling of the inertial loss term." ) volumetric_heat_source: Optional[Union[HeatSourceType, pd.StrictStr]] = pd.Field( - None, description="The volumetric heat source" + None, description="The volumetric heat source." ) # Note: Axes will always come from the entity diff --git a/flow360/component/simulation/outputs/output_entities.py b/flow360/component/simulation/outputs/output_entities.py index 7056fe1d3..86e9d69fb 100644 --- a/flow360/component/simulation/outputs/output_entities.py +++ b/flow360/component/simulation/outputs/output_entities.py @@ -51,16 +51,16 @@ class _PointEntityBase(EntityBase, metaclass=ABCMeta): class Slice(_SliceEntityBase): - """Slice output item.""" + """:class:`Slice` class for defining a slice for :class:`~flow360.SliceOutput`.""" private_attribute_entity_type_name: Literal["Slice"] = pd.Field("Slice", frozen=True) - normal: Axis = pd.Field() + normal: Axis = pd.Field(description="Normal direction of the slice.") # pylint: disable=no-member - origin: LengthType.Point = pd.Field() + origin: LengthType.Point = pd.Field(description="A single point on the slice.") class Isosurface(_OutputItemBase): - """Isosurface output item.""" + """:class:`Isosurface` class for defining an isosurface for :class:`~flow360.IsosurfaceOutput`.""" field: Literal[IsoSurfaceFieldNames] = pd.Field() # pylint: disable=fixme @@ -69,18 +69,24 @@ class Isosurface(_OutputItemBase): class Point(_PointEntityBase): - """A single point for probe output""" + """ + :class:`Point` class for defining a single point for + :class:`~flow360.ProbeOutput`/:class:`~flow360.SurfaceProbeOutput`. + """ private_attribute_entity_type_name: Literal["Point"] = pd.Field("Point", frozen=True) # pylint: disable=no-member - location: LengthType.Point = pd.Field() + location: LengthType.Point = pd.Field(description="The coordinate of the point.") class PointArray(_PointEntityBase): - """A single point for probe output""" + """ + :class:`PointArray` class for defining a line for + :class:`~flow360.ProbeOutput`/:class:`~flow360.SurfaceProbeOutput`. + """ private_attribute_entity_type_name: Literal["PointArray"] = pd.Field("PointArray", frozen=True) # pylint: disable=no-member - start: LengthType.Point = pd.Field() - end: LengthType.Point = pd.Field() - number_of_points: int = pd.Field(gt=2) + start: LengthType.Point = pd.Field(description="The starting point of the line.") + end: LengthType.Point = pd.Field(description="The end point of the line.") + number_of_points: int = pd.Field(gt=2, description="Number of points along the line.") diff --git a/flow360/component/simulation/outputs/outputs.py b/flow360/component/simulation/outputs/outputs.py index 5fdaa27f2..7e045287c 100644 --- a/flow360/component/simulation/outputs/outputs.py +++ b/flow360/component/simulation/outputs/outputs.py @@ -56,7 +56,7 @@ class _AnimationAndFileFormatSettings(_AnimationSettings): """ output_format: Literal["paraview", "tecplot", "both"] = pd.Field( - default="paraview", description='"paraview", "tecplot" or "both".' + default="paraview", description=":code:`paraview`, :code:`tecplot` or :code:`both`." ) @@ -69,20 +69,19 @@ class SurfaceOutput(_AnimationAndFileFormatSettings): name: Optional[str] = pd.Field(None, description="Name of the `SurfaceOutput`.") entities: EntityList[Surface, GhostSurface] = pd.Field( alias="surfaces", - description="List of output :class:`~flow360.component.simulation.primitives.Surface`/" - + ":class:`~flow360.component.simulation.primitives.GhostSurface` entities. " - + "These surface names have to be the patch name in the grid file or the alias name specified in case JSON.", + description="List of output :class:`~flow360.Surface`/" + + ":class:`~flow360.GhostSurface` entities. ", ) write_single_file: bool = pd.Field( default=False, description="Enable writing all surface outputs into a single file instead of one file per surface." + "This option currently only supports Tecplot output format." - + "Will choose the value of the last instance of this option of the same output type" - + "(SurfaceOutput or TimeAverageSurfaceOutput) in the `output` list.", + + "Will choose the value of the last instance of this option of the same output type " + + "(:class:`SurfaceOutput` or :class:`TimeAverageSurfaceOutput`) in the output list.", ) output_fields: UniqueItemList[SurfaceFieldNames] = pd.Field( - description="List of output variables. Including :ref:`universal output variables` " - + "and :ref:`variables specific to surfaceOutput`. " + description="List of output variables. Including :ref:`universal output variables` " + + "and :ref:`variables specific to SurfaceOutput`. " ) output_type: Literal["SurfaceOutput"] = pd.Field("SurfaceOutput", frozen=True) @@ -101,7 +100,7 @@ class TimeAverageSurfaceOutput(SurfaceOutput): """ start_step: Union[pd.NonNegativeInt, Literal[-1]] = pd.Field( - default=-1, description="Physical time step to start calculating averaging" + default=-1, description="Physical time step to start calculating averaging." ) output_type: Literal["TimeAverageSurfaceOutput"] = pd.Field( "TimeAverageSurfaceOutput", frozen=True @@ -113,8 +112,8 @@ class VolumeOutput(_AnimationAndFileFormatSettings): name: Optional[str] = pd.Field(None, description="Name of the `VolumeOutput`.") output_fields: UniqueItemList[VolumeFieldNames] = pd.Field( - description="List of output variables. Including :ref:`universal output variables`, " - + "and :ref:`variables specific to volumeOutput`." + description="List of output variables. Including :ref:`universal output variables`, " + + "and :ref:`variables specific to VolumeOutput`." ) output_type: Literal["VolumeOutput"] = pd.Field("VolumeOutput", frozen=True) @@ -123,8 +122,8 @@ class TimeAverageVolumeOutput(VolumeOutput): """ :class:`TimeAverageVolumeOutput` class for time average volume output settings. Caveats: - Solver side only accept exactly the same set of output_fields (is shared) - between VolumeOutput and TimeAverageVolumeOutput. + The solver only accepts exactly the same set of :paramref:`output_fields` (is shared) + between :class:`VolumeOutput` and :class:`TimeAverageVolumeOutput`. Also let's not worry about allowing entities here as it is not supported by solver anyway. Notes @@ -147,11 +146,11 @@ class SliceOutput(_AnimationAndFileFormatSettings): name: Optional[str] = pd.Field(None, description="Name of the `SliceOutput`.") entities: EntityList[Slice] = pd.Field( alias="slices", - description="List of output :class:`~flow360.component.simulation.outputs.output_entities.Slice` entities.", + description="List of output :class:`~flow360.Slice` entities.", ) output_fields: UniqueItemList[SliceFieldNames] = pd.Field( - description="List of output variables. Including :ref:`universal output variables` " - + "and :ref:`variables specific to sliceOutput`. " + description="List of output variables. Including :ref:`universal output variables` " + + "and :ref:`variables specific to SliceOutput`. " ) output_type: Literal["SliceOutput"] = pd.Field("SliceOutput", frozen=True) @@ -160,7 +159,7 @@ class TimeAverageSliceOutput(SliceOutput): """:class:`TimeAverageSliceOutput` class for time average slice output settings.""" start_step: Union[pd.NonNegativeInt, Literal[-1]] = pd.Field( - default=-1, description="Physical time step to start calculating averaging" + default=-1, description="Physical time step to start calculating averaging." ) output_type: Literal["TimeAverageSliceOutput"] = pd.Field("TimeAverageSliceOutput", frozen=True) @@ -171,7 +170,7 @@ class IsosurfaceOutput(_AnimationAndFileFormatSettings): name: Optional[str] = pd.Field(None, description="Name of the `IsosurfaceOutput`.") entities: UniqueItemList[Isosurface] = pd.Field( alias="isosurfaces", - description="List of :class:`~flow360.component.simulation.outputs.output_entities.Isosurface` entities.", + description="List of :class:`~flow360.Isosurface` entities.", ) output_fields: UniqueItemList[CommonFieldNames] = pd.Field( description=" Isosurface field variable to be written. One of :code:`p`, :code:`rho`, " @@ -192,8 +191,8 @@ class SurfaceIntegralOutput(Flow360BaseModel): + "the surface integral will be calculated.", ) output_fields: UniqueItemList[CommonFieldNames] = pd.Field( - description="List of output fields which will be added to all monitors within the monitor group," - + " see universal output variables." + description="List of output variables. Including " + + ":ref:`universal output variables`." ) output_type: Literal["SurfaceIntegralOutput"] = pd.Field("SurfaceIntegralOutput", frozen=True) @@ -204,14 +203,14 @@ class ProbeOutput(Flow360BaseModel): name: str = pd.Field(description="Name of the monitor group.") entities: EntityList[Point, PointArray] = pd.Field( alias="probe_points", - description="List of monitored :class:`~flow360.component.simulation.outputs.output_entities.Point`/" - + ":class:`~flow360.component.simulation.outputs.output_entities.PointArray` entities belonging to this " - + "monitor group. :class:`~flow360.component.simulation.outputs.output_entities.PointArray` is used to " + description="List of monitored :class:`~flow360.Point`/" + + ":class:`~flow360.PointArray` entities belonging to this " + + "monitor group. :class:`~flow360.PointArray` is used to " + "define monitored points along a line.", ) output_fields: UniqueItemList[CommonFieldNames] = pd.Field( description="List of output fields which will be added to all monitors within the monitor group," - + " see :ref:`universal output variables`" + + " see :ref:`universal output variables`." ) output_type: Literal["ProbeOutput"] = pd.Field("ProbeOutput", frozen=True) @@ -235,9 +234,9 @@ class SurfaceProbeOutput(Flow360BaseModel): name: str = pd.Field(description="Name of the surface monitor group.") entities: EntityList[Point, PointArray] = pd.Field( alias="probe_points", - description="List of monitored :class:`~flow360.component.simulation.outputs.output_entities.Point`/" - + ":class:`~flow360.component.simulation.outputs.output_entities.PointArray` entities belonging to this " - + "surface monitor group. :class:`~flow360.component.simulation.outputs.output_entities.PointArray` " + description="List of monitored :class:`~flow360.Point`/" + + ":class:`~flow360.PointArray` entities belonging to this " + + "surface monitor group. :class:`~flow360.PointArray` " + "is used to define monitored points along a line.", ) # Maybe add preprocess for this and by default add all Surfaces? @@ -246,7 +245,10 @@ class SurfaceProbeOutput(Flow360BaseModel): + "entities belonging to this monitor group." ) - output_fields: UniqueItemList[SurfaceFieldNames] = pd.Field() + output_fields: UniqueItemList[SurfaceFieldNames] = pd.Field( + description="List of output variables. Including :ref:`universal output variables` " + + "and :ref:`variables specific to SurfaceOutput`. " + ) output_type: Literal["SurfaceProbeOutput"] = pd.Field("SurfaceProbeOutput", frozen=True) @pd.field_validator("entities", mode="after") @@ -261,14 +263,21 @@ class SurfaceSliceOutput(_AnimationAndFileFormatSettings): Surface slice settings. """ - name: str = pd.Field() - entities: EntityList[Slice] = pd.Field(alias="slices") + name: str = pd.Field(description="Name of the `SurfaceSliceOutput`.") + entities: EntityList[Slice] = pd.Field( + alias="slices", description="List of :class:`Slice` entities." + ) # Maybe add preprocess for this and by default add all Surfaces? - target_surfaces: EntityList[Surface] = pd.Field() + target_surfaces: EntityList[Surface] = pd.Field( + description="List of :class:`Surface` entities on which the slice will cut through." + ) output_format: Literal["paraview"] = pd.Field(default="paraview") - output_fields: UniqueItemList[SurfaceFieldNames] = pd.Field() + output_fields: UniqueItemList[SurfaceFieldNames] = pd.Field( + description="List of output variables. Including :ref:`universal output variables` " + + "and :ref:`variables specific to SurfaceOutput`. " + ) output_type: Literal["SurfaceSliceOutput"] = pd.Field("SurfaceSliceOutput", frozen=True) @pd.field_validator("entities", mode="after") diff --git a/flow360/component/simulation/primitives.py b/flow360/component/simulation/primitives.py index e937c7bd2..2812b81f6 100644 --- a/flow360/component/simulation/primitives.py +++ b/flow360/component/simulation/primitives.py @@ -60,18 +60,19 @@ def _check_axis_is_orthogonal(axis_pair: Tuple[Axis, Axis]) -> Tuple[Axis, Axis] class ReferenceGeometry(Flow360BaseModel): """ - Contains all geometrical related refrence values - Note: - - mesh_unit is removed from here and will be a property - TODO: - - Support expression for time-dependent axis etc? - - What about force axis? + :class:`ReferenceGeometry` class contains all geometrical related refrence values. """ # pylint: disable=no-member - moment_center: Optional[LengthType.Point] = pd.Field(None) - moment_length: Optional[Union[LengthType.Positive, LengthType.PositiveVector]] = pd.Field(None) - area: Optional[AreaType.Positive] = pd.Field(None) + moment_center: Optional[LengthType.Point] = pd.Field( + None, description="The x, y, z moment center of the geometry in grid units." + ) + moment_length: Optional[Union[LengthType.Positive, LengthType.PositiveVector]] = pd.Field( + None, description="The x, y, z component-wise moment reference lengths." + ) + area: Optional[AreaType.Positive] = pd.Field( + None, description="The reference area of the geometry." + ) class Transformation(Flow360BaseModel): @@ -184,10 +185,10 @@ class GenericVolume(_VolumeEntityBase): private_attribute_entity_type_name: Literal["GenericVolume"] = pd.Field( "GenericVolume", frozen=True ) - axes: Optional[OrthogonalAxes] = pd.Field(None) # Porous media support + axes: Optional[OrthogonalAxes] = pd.Field(None, description="") # Porous media support axis: Optional[Axis] = pd.Field(None) # Rotation support # pylint: disable=no-member - center: Optional[LengthType.Point] = pd.Field(None) # Rotation support + center: Optional[LengthType.Point] = pd.Field(None, description="") # Rotation support def rotation_matrix_from_axis_and_angle(axis, angle): @@ -222,7 +223,7 @@ class BoxCache(Flow360BaseModel): @final class Box(MultiConstructorBaseModel, _VolumeEntityBase): """ - Represents a box in three-dimensional space. + :class:`Box` class represents a box in three-dimensional space. """ type_name: Literal["Box"] = pd.Field("Box", frozen=True) @@ -232,8 +233,8 @@ class Box(MultiConstructorBaseModel, _VolumeEntityBase): size: LengthType.PositiveVector = pd.Field( description="The dimensions of the box (length, width, height)." ) - axis_of_rotation: Axis = pd.Field(default=(0, 0, 1)) - angle_of_rotation: AngleType = pd.Field(default=0 * u.degree) + axis_of_rotation: Axis = pd.Field(default=(0, 0, 1), description="The rotation axis.") + angle_of_rotation: AngleType = pd.Field(default=0 * u.degree, description="The rotation angle.") private_attribute_input_cache: BoxCache = pd.Field(BoxCache(), frozen=True) # pylint: disable=no-self-argument @@ -307,7 +308,7 @@ def axes(self): @final class Cylinder(_VolumeEntityBase): """ - Represents a cylinder in three-dimensional space. + :class:`Cylinder` class represents a cylinder in three-dimensional space. """ private_attribute_entity_type_name: Literal["Cylinder"] = pd.Field("Cylinder", frozen=True) @@ -332,7 +333,7 @@ def _check_inner_radius_is_less_than_outer_radius(self) -> Self: @final class Surface(_SurfaceEntityBase): """ - Represents a boudary surface in three-dimensional space. + :class:`Surface` represents a boudary surface in three-dimensional space. """ private_attribute_entity_type_name: Literal["Surface"] = pd.Field("Surface", frozen=True) diff --git a/flow360/component/simulation/time_stepping/time_stepping.py b/flow360/component/simulation/time_stepping/time_stepping.py index e01fffd2d..da06153c2 100644 --- a/flow360/component/simulation/time_stepping/time_stepping.py +++ b/flow360/component/simulation/time_stepping/time_stepping.py @@ -18,13 +18,20 @@ def _apply_default_to_none(original, default): class RampCFL(Flow360BaseModel): """ - Ramp CFL for time stepping component + :class:`RampCFL` class for the Ramp CFL setting of time stepping. """ type: Literal["ramp"] = pd.Field("ramp", frozen=True) - initial: Optional[pd.PositiveFloat] = pd.Field(None) - final: Optional[pd.PositiveFloat] = pd.Field(None) - ramp_steps: Optional[pd.PositiveInt] = pd.Field(None) + initial: Optional[pd.PositiveFloat] = pd.Field( + None, description="Initial CFL for solving pseudo time step." + ) + final: Optional[pd.PositiveFloat] = pd.Field( + None, description="Final CFL for solving pseudo time step." + ) + ramp_steps: Optional[pd.PositiveInt] = pd.Field( + None, + description="Number of pseudo steps before reaching :paramref:`RampCFL.final` within 1 physical step.", + ) @classmethod def default_unsteady(cls): @@ -43,14 +50,27 @@ def default_steady(cls): class AdaptiveCFL(Flow360BaseModel): """ - Adaptive CFL for time stepping component + :class:`AdaptiveCFL` class for Adaptive CFL setting of time stepping. """ type: Literal["adaptive"] = pd.Field("adaptive", frozen=True) - min: pd.PositiveFloat = pd.Field(default=0.1) - max: Optional[pd.PositiveFloat] = pd.Field(None) - max_relative_change: Optional[pd.PositiveFloat] = pd.Field(None) - convergence_limiting_factor: Optional[pd.PositiveFloat] = pd.Field(None) + min: pd.PositiveFloat = pd.Field( + default=0.1, description="The minimum allowable value for Adaptive CFL." + ) + max: Optional[pd.PositiveFloat] = pd.Field( + None, description="The maximum allowable value for Adaptive CFL." + ) + max_relative_change: Optional[pd.PositiveFloat] = pd.Field( + None, + description="The maximum allowable relative change of CFL (%) at each pseudo step. " + + "In unsteady simulations, the value of :paramref:`AdaptiveCFL.max_relative_change` " + + "is updated automatically depending on how well the solver converges in each physical step.", + ) + convergence_limiting_factor: Optional[pd.PositiveFloat] = pd.Field( + None, + description="This factor specifies the level of conservativeness when using Adaptive CFL. " + + "Smaller values correspond to a more conservative limitation on the value of CFL.", + ) @classmethod def default_unsteady(cls): @@ -77,14 +97,14 @@ class BaseTimeStepping(Flow360BaseModel, metaclass=ABCMeta): class Steady(BaseTimeStepping): """ - Steady time stepping component + :class:`Steady` class for specifying steady simulation. """ type_name: Literal["Steady"] = pd.Field("Steady", frozen=True) max_steps: int = pd.Field(2000, gt=0, le=100000, description="Maximum number of pseudo steps.") # pylint: disable=duplicate-code CFL: Union[RampCFL, AdaptiveCFL] = pd.Field( - default=AdaptiveCFL.default_steady(), + default=AdaptiveCFL.default_steady(), description="CFL settings." ) @pd.model_validator(mode="before") @@ -105,7 +125,7 @@ def set_default_cfl(cls, values): class Unsteady(BaseTimeStepping): """ - Unsteady time stepping component + :class:`Unsteady` class for specifying unsteady simulation. """ type_name: Literal["Unsteady"] = pd.Field("Unsteady", frozen=True) @@ -118,6 +138,7 @@ class Unsteady(BaseTimeStepping): # pylint: disable=duplicate-code CFL: Union[RampCFL, AdaptiveCFL] = pd.Field( default=AdaptiveCFL.default_unsteady(), + description="CFL settings within each physical step.", ) @pd.model_validator(mode="before") diff --git a/flow360/component/simulation/user_defined_dynamics/user_defined_dynamics.py b/flow360/component/simulation/user_defined_dynamics/user_defined_dynamics.py index 7d4187d27..fb030717f 100644 --- a/flow360/component/simulation/user_defined_dynamics/user_defined_dynamics.py +++ b/flow360/component/simulation/user_defined_dynamics/user_defined_dynamics.py @@ -11,15 +11,50 @@ class UserDefinedDynamic(Flow360BaseModel): - """:class:`UserDefinedDynamic` class""" + """:class:`UserDefinedDynamic` class for defining the user defined dynamics inputs.""" - name: str = pd.Field() - input_vars: List[str] = pd.Field() - constants: Optional[Dict[str, float]] = pd.Field(None) - output_vars: Optional[Dict[str, StringExpression]] = pd.Field(None) - state_vars_initial_value: List[StringExpression] = pd.Field() - update_law: List[StringExpression] = pd.Field() - input_boundary_patches: Optional[EntityList[Surface]] = pd.Field(None) + name: str = pd.Field(description="Name of the dynamics defined by the user.") + input_vars: List[str] = pd.Field( + description="List of the inputs to define the user defined dynamics. For example :code:`CL`, :code:`CD`, " + + ":code:`bet_NUM_torque`, :code:`bet_NUM_thrust`, (NUM is the index of the BET disk starting from 0), " + + ":code:`momentX`, :code:`momentY`, :code:`momentZ` (X/Y/Z moments with respect to :ref:`momentCenter " + + "`), :code:`forceX`, :code:`forceY`, :code:`forceZ`. For a full list of supported " + + "variable, see :ref:`here `." + ) + constants: Optional[Dict[str, float]] = pd.Field( + None, description="A list of constants that can be used in the expressions." + ) + output_vars: Optional[Dict[str, StringExpression]] = pd.Field( + None, + description="Name of the output variables and the expression for the output variables using state " + + "variables. For example :code:`alphaAngle`, :code:`betaAngle`, :code:`bet_NUM_omega` (NUM is the index " + + "of the BET disk starting from 0), :code:`theta`, :code:`omega` and :code:`omegaDot` (rotation angle/" + + "velocity/acceleration in radians for sliding interfaces). For a full list of supported variable, see " + + ":ref:`here `. Please exercise caution when choosing output " + + "variables, as any modifications to their values will be directly mirrored in the solver. Expressions " + + "follows similar guidelines as :ref:`user Defined Expressions`.", + ) + state_vars_initial_value: List[StringExpression] = pd.Field( + description="The initial value of state variables are specified here. The entries could be either values " + + "(in the form of strings, e.g., :code:`0.0`) or expression with constants defined earlier or any input " + + "and output variable. (e.g., :code:`2.0 * alphaAngle + someConstant`). The list entries correspond to " + + "the initial values for :code:`state[0]`, :code:`state[1]`, ..., respectively." + ) + update_law: List[StringExpression] = pd.Field( + "List of expressions for updating state variables. The list entries correspond to the update laws for " + + ":code:`state[0]`, :code:`state[1]`, ..., respectively. These expressions follows similar guidelines as " + + ":ref:`user Defined Expressions`." + ) + input_boundary_patches: Optional[EntityList[Surface]] = pd.Field( + None, + description="The list of :class:`~flow360.Surface` entities to which the input variables belongs. " + + "If multiple boundaries are specified then the summation over the boundaries are used as the input. " + + "For input variables that already specified the source in the name (like bet_NUM_torque) " + + "this entry does not have any effect.", + ) output_target: Optional[Cylinder] = pd.Field( - None + None, + description="The target to which the output variables belong to. For example this can be the rotating " + + "volume zone name. Only one output target is supported per user defined dynamics instance. Only " + + ":class:`~flow360.Cylinder` entity is supported as target for now.", ) # Limited to `Cylinder` for now as we have only tested using UDD to control rotation. diff --git a/poetry.lock b/poetry.lock index 31b7584e3..1f35613ad 100644 --- a/poetry.lock +++ b/poetry.lock @@ -1,4 +1,4 @@ -# This file is automatically @generated by Poetry 1.7.1 and should not be changed by hand. +# This file is automatically @generated by Poetry 1.8.3 and should not be changed by hand. [[package]] name = "accessible-pygments" @@ -5129,4 +5129,4 @@ docs = ["autodoc_pydantic", "cairosvg", "ipython", "jinja2", "jupyter", "myst-pa [metadata] lock-version = "2.0" python-versions = ">=3.9,<3.12" -content-hash = "68e2b0a819ba27869350047433031ea97ab479abe517f1bbbb2d60498b71e6aa" +content-hash = "06a25622fff3a3c4612d1326ada848e08eb1e83c2ddf19c348a1164963090061" diff --git a/pyproject.toml b/pyproject.toml index 6d1ed1e63..c772725ae 100644 --- a/pyproject.toml +++ b/pyproject.toml @@ -99,6 +99,7 @@ docs = [ "sphinx-prompt", "sphinx_design", "sphinx_toolbox", + "sphinx_paramlinks", ] [tool.isort] From 527550be93d94a8df8b6af420fddca54104179e5 Mon Sep 17 00:00:00 2001 From: Ben <106089368+benflexcompute@users.noreply.github.com> Date: Fri, 1 Nov 2024 16:10:37 -0400 Subject: [PATCH 6/8] Ben y/add missing sphinx package (#545) * Added sphinx-paramlinks * Add more dependencies --- poetry.lock | 65 ++++++++++++++++++++++++++++++++++++++------------ pyproject.toml | 3 +++ 2 files changed, 53 insertions(+), 15 deletions(-) diff --git a/poetry.lock b/poetry.lock index 1f35613ad..68082fdf1 100644 --- a/poetry.lock +++ b/poetry.lock @@ -1,4 +1,4 @@ -# This file is automatically @generated by Poetry 1.8.3 and should not be changed by hand. +# This file is automatically @generated by Poetry 1.8.2 and should not be changed by hand. [[package]] name = "accessible-pygments" @@ -22,7 +22,7 @@ tests = ["hypothesis", "pytest"] name = "alabaster" version = "0.7.16" description = "A light, configurable Sphinx theme" -optional = true +optional = false python-versions = ">=3.9" files = [ {file = "alabaster-0.7.16-py3-none-any.whl", hash = "sha256:b46733c07dce03ae4e150330b975c75737fa60f0a7c591b6c8bf4928a28e2c92"}, @@ -1107,7 +1107,7 @@ profile = ["gprof2dot (>=2022.7.29)"] name = "docutils" version = "0.21.2" description = "Docutils -- Python Documentation Utilities" -optional = true +optional = false python-versions = ">=3.9" files = [ {file = "docutils-0.21.2-py3-none-any.whl", hash = "sha256:dafca5b9e384f0e419294eb4d2ff9fa826435bf15f15b7bd45723e8ad76811b2"}, @@ -1466,7 +1466,7 @@ all = ["flake8 (>=7.1.1)", "mypy (>=1.11.2)", "pytest (>=8.3.2)", "ruff (>=0.6.2 name = "imagesize" version = "1.4.1" description = "Getting image size from png/jpeg/jpeg2000/gif file" -optional = true +optional = false python-versions = ">=2.7, !=3.0.*, !=3.1.*, !=3.2.*, !=3.3.*" files = [ {file = "imagesize-1.4.1-py2.py3-none-any.whl", hash = "sha256:0d8d18d08f840c19d0ee7ca1fd82490fdc3729b7ac93f49870406ddde8ef8d8b"}, @@ -2912,6 +2912,27 @@ files = [ {file = "numpy-1.26.0.tar.gz", hash = "sha256:f93fc78fe8bf15afe2b8d6b6499f1c73953169fad1e9a8dd086cdff3190e7fdf"}, ] +[[package]] +name = "numpydoc" +version = "1.8.0" +description = "Sphinx extension to support docstrings in Numpy format" +optional = false +python-versions = ">=3.9" +files = [ + {file = "numpydoc-1.8.0-py3-none-any.whl", hash = "sha256:72024c7fd5e17375dec3608a27c03303e8ad00c81292667955c6fea7a3ccf541"}, + {file = "numpydoc-1.8.0.tar.gz", hash = "sha256:022390ab7464a44f8737f79f8b31ce1d3cfa4b4af79ccaa1aac5e8368db587fb"}, +] + +[package.dependencies] +sphinx = ">=6" +tabulate = ">=0.8.10" +tomli = {version = ">=1.1.0", markers = "python_version < \"3.11\""} + +[package.extras] +developer = ["pre-commit (>=3.3)", "tomli"] +doc = ["intersphinx-registry", "matplotlib (>=3.5)", "numpy (>=1.22)", "pydata-sphinx-theme (>=0.13.3)", "sphinx (>=7)"] +test = ["matplotlib", "pytest", "pytest-cov"] + [[package]] name = "overrides" version = "7.7.0" @@ -4330,7 +4351,7 @@ files = [ name = "snowballstemmer" version = "2.2.0" description = "This package provides 29 stemmers for 28 languages generated from Snowball algorithms." -optional = true +optional = false python-versions = "*" files = [ {file = "snowballstemmer-2.2.0-py2.py3-none-any.whl", hash = "sha256:c8e1716e83cc398ae16824e5572ae04e0d9fc2c6b985fb0f900f5f0c96ecba1a"}, @@ -4352,7 +4373,7 @@ files = [ name = "sphinx" version = "7.4.7" description = "Python documentation generator" -optional = true +optional = false python-versions = ">=3.9" files = [ {file = "sphinx-7.4.7-py3-none-any.whl", hash = "sha256:c2419e2135d11f1951cd994d6eb18a1835bd8fdd8429f9ca375dc1f3281bd239"}, @@ -4518,6 +4539,20 @@ sphinx = ">=5" doc = ["sphinx-autoapi", "sphinx-rtd-theme", "sphinx-tabs", "sphinxemoji"] test = ["tox"] +[[package]] +name = "sphinx-paramlinks" +version = "0.6.0" +description = "Allows param links in Sphinx function/method descriptions to be linkable" +optional = true +python-versions = "*" +files = [ + {file = "sphinx-paramlinks-0.6.0.tar.gz", hash = "sha256:746a0816860aa3fff5d8d746efcbec4deead421f152687411db1d613d29f915e"}, +] + +[package.dependencies] +docutils = "*" +Sphinx = ">=4.0.0" + [[package]] name = "sphinx-prompt" version = "1.8.0" @@ -4609,7 +4644,7 @@ testing = ["coincidence (>=0.4.3)", "pygments (>=2.7.4,<=2.13.0)"] name = "sphinxcontrib-applehelp" version = "2.0.0" description = "sphinxcontrib-applehelp is a Sphinx extension which outputs Apple help books" -optional = true +optional = false python-versions = ">=3.9" files = [ {file = "sphinxcontrib_applehelp-2.0.0-py3-none-any.whl", hash = "sha256:4cd3f0ec4ac5dd9c17ec65e9ab272c9b867ea77425228e68ecf08d6b28ddbdb5"}, @@ -4625,7 +4660,7 @@ test = ["pytest"] name = "sphinxcontrib-devhelp" version = "2.0.0" description = "sphinxcontrib-devhelp is a sphinx extension which outputs Devhelp documents" -optional = true +optional = false python-versions = ">=3.9" files = [ {file = "sphinxcontrib_devhelp-2.0.0-py3-none-any.whl", hash = "sha256:aefb8b83854e4b0998877524d1029fd3e6879210422ee3780459e28a1f03a8a2"}, @@ -4641,7 +4676,7 @@ test = ["pytest"] name = "sphinxcontrib-htmlhelp" version = "2.1.0" description = "sphinxcontrib-htmlhelp is a sphinx extension which renders HTML help files" -optional = true +optional = false python-versions = ">=3.9" files = [ {file = "sphinxcontrib_htmlhelp-2.1.0-py3-none-any.whl", hash = "sha256:166759820b47002d22914d64a075ce08f4c46818e17cfc9470a9786b759b19f8"}, @@ -4657,7 +4692,7 @@ test = ["html5lib", "pytest"] name = "sphinxcontrib-jsmath" version = "1.0.1" description = "A sphinx extension which renders display math in HTML via JavaScript" -optional = true +optional = false python-versions = ">=3.5" files = [ {file = "sphinxcontrib-jsmath-1.0.1.tar.gz", hash = "sha256:a9925e4a4587247ed2191a22df5f6970656cb8ca2bd6284309578f2153e0c4b8"}, @@ -4671,7 +4706,7 @@ test = ["flake8", "mypy", "pytest"] name = "sphinxcontrib-qthelp" version = "2.0.0" description = "sphinxcontrib-qthelp is a sphinx extension which outputs QtHelp documents" -optional = true +optional = false python-versions = ">=3.9" files = [ {file = "sphinxcontrib_qthelp-2.0.0-py3-none-any.whl", hash = "sha256:b18a828cdba941ccd6ee8445dbe72ffa3ef8cbe7505d8cd1fa0d42d3f2d5f3eb"}, @@ -4687,7 +4722,7 @@ test = ["defusedxml (>=0.7.1)", "pytest"] name = "sphinxcontrib-serializinghtml" version = "2.0.0" description = "sphinxcontrib-serializinghtml is a sphinx extension which outputs \"serialized\" HTML files (json and pickle)" -optional = true +optional = false python-versions = ">=3.9" files = [ {file = "sphinxcontrib_serializinghtml-2.0.0-py3-none-any.whl", hash = "sha256:6e2cb0eef194e10c27ec0023bfeb25badbbb5868244cf5bc5bdc04e4464bf331"}, @@ -4770,7 +4805,7 @@ dev = ["hypothesis (>=6.70.0)", "pytest (>=7.1.0)"] name = "tabulate" version = "0.9.0" description = "Pretty-print tabular data" -optional = true +optional = false python-versions = ">=3.7" files = [ {file = "tabulate-0.9.0-py3-none-any.whl", hash = "sha256:024ca478df22e9340661486f85298cff5f6dcdba14f3813e8830015b9ed1948f"}, @@ -5124,9 +5159,9 @@ cffi = {version = ">=1.11", markers = "platform_python_implementation == \"PyPy\ cffi = ["cffi (>=1.11)"] [extras] -docs = ["autodoc_pydantic", "cairosvg", "ipython", "jinja2", "jupyter", "myst-parser", "nbconvert", "nbdime", "nbsphinx", "pydata-sphinx-theme", "readthedocs-sphinx-search", "sphinx", "sphinx-book-theme", "sphinx-copybutton", "sphinx-favicon", "sphinx-notfound-page", "sphinx-prompt", "sphinx-sitemap", "sphinx-tabs", "sphinx_design", "sphinx_toolbox", "sphinxcontrib-svg2pdfconverter", "sphinxemoji"] +docs = ["autodoc_pydantic", "cairosvg", "ipython", "jinja2", "jupyter", "myst-parser", "nbconvert", "nbdime", "nbsphinx", "numpydoc", "pydata-sphinx-theme", "readthedocs-sphinx-search", "sphinx", "sphinx-book-theme", "sphinx-copybutton", "sphinx-favicon", "sphinx-notfound-page", "sphinx-prompt", "sphinx-sitemap", "sphinx-tabs", "sphinx_design", "sphinx_paramlinks", "sphinx_toolbox", "sphinxcontrib-svg2pdfconverter", "sphinxemoji"] [metadata] lock-version = "2.0" python-versions = ">=3.9,<3.12" -content-hash = "06a25622fff3a3c4612d1326ada848e08eb1e83c2ddf19c348a1164963090061" +content-hash = "f98d5ccabd7699df12cdbcda67892f6707f774e22d3680ac424e94f9a40582bd" diff --git a/pyproject.toml b/pyproject.toml index c772725ae..7a548e470 100644 --- a/pyproject.toml +++ b/pyproject.toml @@ -59,6 +59,8 @@ sphinxcontrib-svg2pdfconverter = {version="*", optional = true} sphinx-prompt = {version="*", optional = true} sphinx_design = {version="*", optional = true} sphinx_toolbox = {version="*", optional = true} +sphinx_paramlinks = {version="*", optional = true} +numpydoc = "^1.8.0" [tool.poetry.group.dev.dependencies] @@ -100,6 +102,7 @@ docs = [ "sphinx_design", "sphinx_toolbox", "sphinx_paramlinks", + "numpydoc" ] [tool.isort] From aef7931f4d8c67c43cf7c267c06cf815b4ea1ae0 Mon Sep 17 00:00:00 2001 From: angranl-flex Date: Fri, 1 Nov 2024 16:30:22 -0400 Subject: [PATCH 7/8] Update Isosurface related docs (#546) --- flow360/component/simulation/outputs/output_entities.py | 5 ++++- flow360/component/simulation/outputs/outputs.py | 6 +++--- 2 files changed, 7 insertions(+), 4 deletions(-) diff --git a/flow360/component/simulation/outputs/output_entities.py b/flow360/component/simulation/outputs/output_entities.py index 86e9d69fb..882352d81 100644 --- a/flow360/component/simulation/outputs/output_entities.py +++ b/flow360/component/simulation/outputs/output_entities.py @@ -62,7 +62,10 @@ class Slice(_SliceEntityBase): class Isosurface(_OutputItemBase): """:class:`Isosurface` class for defining an isosurface for :class:`~flow360.IsosurfaceOutput`.""" - field: Literal[IsoSurfaceFieldNames] = pd.Field() + field: Literal[IsoSurfaceFieldNames] = pd.Field( + description="Isosurface field variable. One of :code:`p`, :code:`rho`, " + + ":code:`Mach`, :code:`qcriterion`, :code:`s`, :code:`T`, :code:`Cp`, :code:`mut`, :code:`nuHat`." + ) # pylint: disable=fixme # TODO: Maybe we need some unit helper function to help user figure out what is the value to use here? iso_value: float = pd.Field(description="Expect non-dimensional value.") diff --git a/flow360/component/simulation/outputs/outputs.py b/flow360/component/simulation/outputs/outputs.py index 7e045287c..92663b8b4 100644 --- a/flow360/component/simulation/outputs/outputs.py +++ b/flow360/component/simulation/outputs/outputs.py @@ -173,8 +173,8 @@ class IsosurfaceOutput(_AnimationAndFileFormatSettings): description="List of :class:`~flow360.Isosurface` entities.", ) output_fields: UniqueItemList[CommonFieldNames] = pd.Field( - description=" Isosurface field variable to be written. One of :code:`p`, :code:`rho`, " - + ":code:`Mach`, :code:`qcriterion`, :code:`s`, :code:`T`, :code:`Cp`, :code:`mut`, :code:`nuHat`." + description="List of output variables, see " + + ":ref:`universal output variables`." ) output_type: Literal["IsosurfaceOutput"] = pd.Field("IsosurfaceOutput", frozen=True) @@ -191,7 +191,7 @@ class SurfaceIntegralOutput(Flow360BaseModel): + "the surface integral will be calculated.", ) output_fields: UniqueItemList[CommonFieldNames] = pd.Field( - description="List of output variables. Including " + description="List of output variables, see " + ":ref:`universal output variables`." ) output_type: Literal["SurfaceIntegralOutput"] = pd.Field("SurfaceIntegralOutput", frozen=True) From 3d6e402e864962f7fa603128cebfa011ee449ae3 Mon Sep 17 00:00:00 2001 From: Ben <106089368+benflexcompute@users.noreply.github.com> Date: Sun, 3 Nov 2024 11:48:25 -0500 Subject: [PATCH 8/8] Ben y/add meshing and exmp (#547) * WIP-1 * WIP * Fix lint * Fixed unit test --- flow360/__init__.py | 9 +- .../simulation/meshing_param/edge_params.py | 19 +-- .../simulation/meshing_param/face_params.py | 28 ++-- .../simulation/meshing_param/params.py | 49 +++--- .../simulation/meshing_param/volume_params.py | 80 +++++----- .../component/simulation/models/material.py | 108 ++++++++++++- .../operating_condition.py | 147 +++++++++++++----- flow360/component/simulation/primitives.py | 15 +- 8 files changed, 323 insertions(+), 132 deletions(-) diff --git a/flow360/__init__.py b/flow360/__init__.py index a4b6a1d7a..a96d0c5fa 100644 --- a/flow360/__init__.py +++ b/flow360/__init__.py @@ -8,10 +8,17 @@ from flow360.component.simulation import units as u from flow360.component.simulation.entity_info import GeometryEntityInfo from flow360.component.simulation.meshing_param.edge_params import ( + AngleBasedRefinement, + AspectRatioBasedRefinement, HeightBasedRefinement, + ProjectAnisoSpacing, SurfaceEdgeRefinement, ) -from flow360.component.simulation.meshing_param.face_params import SurfaceRefinement +from flow360.component.simulation.meshing_param.face_params import ( + BoundaryLayer, + PassiveSpacing, + SurfaceRefinement, +) from flow360.component.simulation.meshing_param.params import ( MeshingDefaults, MeshingParams, diff --git a/flow360/component/simulation/meshing_param/edge_params.py b/flow360/component/simulation/meshing_param/edge_params.py index 6bc2b76d0..5308754c8 100644 --- a/flow360/component/simulation/meshing_param/edge_params.py +++ b/flow360/component/simulation/meshing_param/edge_params.py @@ -11,14 +11,14 @@ class AngleBasedRefinement(Flow360BaseModel): - """Surface edge refinement by specifying curvature resolution in degrees""" + """Surface edge refinement by specifying curvature resolution angle.""" type: Literal["angle"] = pd.Field("angle", frozen=True) value: AngleType = pd.Field() class HeightBasedRefinement(Flow360BaseModel): - """Surface edge refinement by specifying first layer height of the anisotropic layers""" + """Surface edge refinement by specifying first layer height of the anisotropic layers.""" type: Literal["height"] = pd.Field("height", frozen=True) # pylint: disable=no-member @@ -26,24 +26,21 @@ class HeightBasedRefinement(Flow360BaseModel): class AspectRatioBasedRefinement(Flow360BaseModel): - """Surface edge refinement by specifying maximum aspect ratio of the anisotropic cells""" + """Surface edge refinement by specifying maximum aspect ratio of the anisotropic cells.""" type: Literal["aspectRatio"] = pd.Field("aspectRatio", frozen=True) value: pd.PositiveFloat = pd.Field() class ProjectAnisoSpacing(Flow360BaseModel): - """Project the anisotropic spacing from neighboring faces to the edge""" + """Project the anisotropic spacing from neighboring faces to the edge.""" type: Literal["projectAnisoSpacing"] = pd.Field("projectAnisoSpacing", frozen=True) class SurfaceEdgeRefinement(Flow360BaseModel): """ - Grow anisotropic layers orthogonal to the edge. - - If `method` is None then it projects the anisotropic spacing from neighboring faces to the edge - (equivalent to `ProjectAniso` in old params). + Setting for growing anisotropic layers orthogonal to the specified `Edge`s. """ name: Optional[str] = pd.Field(None) @@ -56,4 +53,8 @@ class SurfaceEdgeRefinement(Flow360BaseModel): HeightBasedRefinement, AspectRatioBasedRefinement, ProjectAnisoSpacing, - ] = pd.Field(discriminator="type") + ] = pd.Field( + discriminator="type", + description="Method for determining the spacing. See :class:`AngleBasedRefinement`," + " :class:`HeightBasedRefinement`, :class:`AspectRatioBasedRefinement`, :class:`ProjectAnisoSpacing`", + ) diff --git a/flow360/component/simulation/meshing_param/face_params.py b/flow360/component/simulation/meshing_param/face_params.py index 97f53cd46..f5a8e7ae3 100644 --- a/flow360/component/simulation/meshing_param/face_params.py +++ b/flow360/component/simulation/meshing_param/face_params.py @@ -12,15 +12,7 @@ class SurfaceRefinement(Flow360BaseModel): """ - These affects surface meshing. - - Note: - - `None` entities will be expanded (or just ignored and convert to global default, depending on implementation) - before submission. This is supposed to be applied to all the matching entities. We allow this so that we do not - need to have dedicated field for global settings. This is also consistent with the `FluidDynamics` class' design. - - - For `SurfaceRefinement` we may need validation to detect if default has been set or not. This is because we need - these defaults so that the when face name is not present, what config we ues. Depending on how we go down the road. + Setting for refining surface elements for given `Surface`. """ name: Optional[str] = pd.Field(None) @@ -28,25 +20,33 @@ class SurfaceRefinement(Flow360BaseModel): entities: EntityList[Surface] = pd.Field(alias="faces") # pylint: disable=no-member max_edge_length: LengthType.Positive = pd.Field( - description="Local maximum edge length for surface cells." + description="Maximum edge length of surface cells." ) class PassiveSpacing(Flow360BaseModel): """ - Passively control the mesh spacing either through other face's meshing + Passively control the mesh spacing either through adjecent `Surface`'s meshing setting or doing nothing to change existing surface mesh at all. """ name: Optional[str] = pd.Field(None) - type: Literal["projected", "unchanged"] = pd.Field() + type: Literal["projected", "unchanged"] = pd.Field( + description=""" + 1. When set to *projected*, turn off anisotropic layers growing for this `Surface`. + Project the anisotropic spacing from the neighboring volumes to this face. + + 2. When set to *unchanged*, turn off anisotropic layers growing for this `Surface`. + The surface mesh will remain unaltered when populating the volume mesh. + """ + ) refinement_type: Literal["PassiveSpacing"] = pd.Field("PassiveSpacing", frozen=True) entities: EntityList[Surface] = pd.Field(alias="faces") class BoundaryLayer(Flow360BaseModel): """ - These affects volume meshing. + Setting for growing anisotropic layers orthogonal to the specified `Surface`s. """ name: Optional[str] = pd.Field(None) @@ -54,5 +54,5 @@ class BoundaryLayer(Flow360BaseModel): entities: EntityList[Surface] = pd.Field(alias="faces") # pylint: disable=no-member first_layer_thickness: LengthType.Positive = pd.Field( - description="First layer thickness for volumetric anisotropic layers grown from given faces." + description="First layer thickness for volumetric anisotropic layers grown from given `Surface`s." ) diff --git a/flow360/component/simulation/meshing_param/params.py b/flow360/component/simulation/meshing_param/params.py index d47f7f522..73edc7cb7 100644 --- a/flow360/component/simulation/meshing_param/params.py +++ b/flow360/component/simulation/meshing_param/params.py @@ -54,75 +54,78 @@ class MeshingDefaults(Flow360BaseModel): surface_edge_growth_rate: float = ContextField( 1.2, ge=1, - description="Global growth rate of the anisotropic layers grown from the edges.", + description="Growth rate of the anisotropic layers grown from the edges." + "This can not be overridden per edge.", context=SURFACE_MESH, ) ##:: Default boundary layer settings boundary_layer_growth_rate: float = ContextField( 1.2, - description="Default growth rate for volume prism layers.", + description="Default growth rate for volume prism layers." + " This can not be overridden per face.", ge=1, context=VOLUME_MESH, ) # pylint: disable=no-member boundary_layer_first_layer_thickness: Optional[LengthType.Positive] = ConditionalField( None, - description="Default first layer thickness for volumetric anisotropic layers.", + description="Default first layer thickness for volumetric anisotropic layers." + " This can be overridden with :class:`~flow360.BoundaryLayer`.", context=VOLUME_MESH, ) # Truly optional if all BL faces already have first_layer_thickness ##:: Default surface layer settings surface_max_edge_length: Optional[LengthType.Positive] = ConditionalField( None, - description="Default maximum edge length for surface cells.", + description="Default maximum edge length for surface cells." + " This can be overridden with :class:`~flow360.SurfaceRefinement`.", context=SURFACE_MESH, ) curvature_resolution_angle: AngleType.Positive = ContextField( 12 * u.deg, - description="Default maximum angular deviation in degrees. This value will restrict:" - "(1) The angle between a cell’s normal and its underlying surface normal" - "(2) The angle between a line segment’s normal and its underlying curve normal" - "This can not be overridden per face.", + description=( + "Default maximum angular deviation in degrees. This value will restrict:" + " 1. The angle between a cell’s normal and its underlying surface normal." + " 2. The angle between a line segment’s normal and its underlying curve normal." + " This can not be overridden per face." + ), context=SURFACE_MESH, ) class MeshingParams(Flow360BaseModel): """ - Meshing parameters for volume and/or surface mesher. - - In `Simulation` this only contains what the user specifies. `Simulation` can derive and add more items according - to other aspects of simulation. (E.g. BETDisk volume -> ZoneRefinement) - - Meshing related but may and maynot (user specified) need info from `Simulation`: - 1. Add rotational zones. - 2. Add default BETDisk refinement. + Meshing parameters for volume and/or surface mesher. This contains all the meshing related settings. """ refinement_factor: Optional[pd.PositiveFloat] = pd.Field( default=1, - description="If refinementFactor=r is provided all spacings in refinementregions" - + "and first layer thickness will be adjusted to generate r-times finer mesh.", + description="All spacings in refinement regions" + + "and first layer thickness will be adjusted to generate `r`-times" + + " finer mesh where r is the refinement_factor value.", ) gap_treatment_strength: Optional[float] = ContextField( default=0, ge=0, le=1, description="Narrow gap treatment strength used when two surfaces are in close proximity." - "Use a value between 0 and 1, where 0 is no treatment and 1 is the most conservative treatment." - + "This parameter has a global impact where the anisotropic transition into the isotropic mesh." - + "However the impact on regions without close proximity is negligible.", + " Use a value between 0 and 1, where 0 is no treatment and 1 is the most conservative treatment." + " This parameter has a global impact where the anisotropic transition into the isotropic mesh." + " However the impact on regions without close proximity is negligible.", context=VOLUME_MESH, ) defaults: MeshingDefaults = pd.Field( - MeshingDefaults(), description="Default settings for meshing." + MeshingDefaults(), + description="Default settings for meshing." + " In other words the settings specified here will be applied" + " as a default setting for all `Surface` and `Edges`.", ) refinements: List[RefinementTypes] = pd.Field( default=[], - description="Additional fine-tunning for refinements.", + description="Additional fine-tunning for refinements on top of :paramref:`defaults`", ) # Will add more to the Union volume_zones: Optional[List[VolumeZonesTypes]] = pd.Field( diff --git a/flow360/component/simulation/meshing_param/volume_params.py b/flow360/component/simulation/meshing_param/volume_params.py index 62da95473..f04455c3e 100644 --- a/flow360/component/simulation/meshing_param/volume_params.py +++ b/flow360/component/simulation/meshing_param/volume_params.py @@ -20,33 +20,38 @@ class UniformRefinement(Flow360BaseModel): - """Uniform spacing refinement.""" + """Uniform spacing refinement inside specified region of mesh.""" name: Optional[str] = pd.Field(None) refinement_type: Literal["UniformRefinement"] = pd.Field("UniformRefinement", frozen=True) - entities: EntityList[Box, Cylinder] = pd.Field() + entities: EntityList[Box, Cylinder] = pd.Field( + description=":class:`UniformRefinement` can be applied to `Box` and `Cylinder` regions." + ) # pylint: disable=no-member - spacing: LengthType.Positive = pd.Field() + spacing: LengthType.Positive = pd.Field(description="The required refinement spacing.") class CylindricalRefinementBase(Flow360BaseModel, metaclass=ABCMeta): """Base class for all refinements that requires spacing in axia, radial and circumferential directions.""" # pylint: disable=no-member - spacing_axial: LengthType.Positive = pd.Field() - spacing_radial: LengthType.Positive = pd.Field() - spacing_circumferential: LengthType.Positive = pd.Field() + spacing_axial: LengthType.Positive = pd.Field(description="Spacing along the axial direction.") + spacing_radial: LengthType.Positive = pd.Field( + description="Spacing along the radial direction." + ) + spacing_circumferential: LengthType.Positive = pd.Field( + description="Spacing along the circumferential direction." + ) class AxisymmetricRefinement(CylindricalRefinementBase): """ - Note: - - This basically creates the "rotorDisks" type of volume refinement that we used to have. - - - - - We may provide a helper function to automatically determine what is inside the encloeud_objects list based on - the mesh data. But this currently is out of scope due to the estimated efforts. + - The mesh inside the :class:`AxisymmetricRefinement` is semi-structured. + - The :class:`AxisymmetricRefinement` cannot enclose/intersect with other objects. + - Users could create a donut-shape :class:`AxisymmetricRefinement` and place their hub/centerbody in the middle. + - :class:`AxisymmetricRefinement` can be used for resolving the strong flow gradient + along the axial direction for the actuator or BET disks. + - The spacings along the axial, radial and circumferential directions can be adjusted independently. """ name: Optional[str] = pd.Field(None) @@ -58,25 +63,23 @@ class AxisymmetricRefinement(CylindricalRefinementBase): class RotationCylinder(CylindricalRefinementBase): """ - This is the original SlidingInterface. This will create new volume zones - Will add RotationSphere class in the future. - Please refer to - https://www.notion.so/flexcompute/Python-model-design-document- - 78d442233fa944e6af8eed4de9541bb1?pvs=4#c2de0b822b844a12aa2c00349d1f68a3 - - - `enclosed_entities` is actually just a way of specifying the enclosing patches of a volume zone. - Therefore in the future when supporting arbitrary-axisymmetric shaped sliding interface, we may not need this - attribute at all. For example if the new class already has an entry to list all the enclosing patches. + - The mesh on :class:`RotationCylinder` is guaranteed to be concentric. + - The :class:`RotationCylinder` is designed to enclose other objects, but it can’t intersect with other objects. + - Users could create a donut-shape :class:`RotationCylinder` and put their stationary centerbody in the middle. + This type of volume zone can be used to generate volume zone compatible with :class:`~flow360.Rotation` model. """ + # Note: Please refer to + # Note: https://www.notion.so/flexcompute/Python-model-design-document- + # Note: 78d442233fa944e6af8eed4de9541bb1?pvs=4#c2de0b822b844a12aa2c00349d1f68a3 + type: Literal["RotationCylinder"] = pd.Field("RotationCylinder", frozen=True) name: Optional[str] = pd.Field(None, description="Name to display in the GUI.") entities: EntityList[Cylinder] = pd.Field() enclosed_entities: Optional[EntityList[Cylinder, Surface]] = pd.Field( None, - description="Entities enclosed by this sliding interface." - + " Can be faces, boxes and/or other cylinders etc." - + "This helps determining the volume zone boundary.", + description="Entities enclosed by :class:`RotationCylinder`." + " Can be `Surface`s and/or other `Cylinders`.", ) @pd.field_validator("entities", mode="after") @@ -98,24 +101,23 @@ def _validate_single_instance_in_entity_list(cls, values): class AutomatedFarfield(Flow360BaseModel): """ - - auto: The mesher will Sphere or semi-sphere will be generated based on the bounding box of the geometry - - - Full sphere if min{Y} < 0 and max{Y} > 0 - - - +Y semi sphere if min{Y} = 0 and max{Y} > 0 - - - -Y semi sphere if min{Y} < 0 and max{Y} = 0 - - - quasi-3d: Thin disk will be generated for quasi 3D cases. - Both sides of the farfield disk will be treated as “symmetric plane”. - - - user-defined: The farfield shape is provided by the user in ESP. - Note: "user-defined" are left out due to scarce usage and will not be implemented. + Settings for automatic farfield volume zone generation. """ type: Literal["AutomatedFarfield"] = pd.Field("AutomatedFarfield", frozen=True) name: Optional[str] = pd.Field(None) - method: Literal["auto", "quasi-3d"] = pd.Field(default="auto", frozen=True) + method: Literal["auto", "quasi-3d"] = pd.Field( + default="auto", + frozen=True, + description=""" + - auto: The mesher will Sphere or semi-sphere will be generated based on the bounding box of the geometry. + - Full sphere if min{Y} < 0 and max{Y} > 0. + - +Y semi sphere if min{Y} = 0 and max{Y} > 0. + - -Y semi sphere if min{Y} < 0 and max{Y} = 0. + - quasi-3d: Thin disk will be generated for quasi 3D cases. + Both sides of the farfield disk will be treated as “symmetric plane”. + """, + ) private_attribute_entity: GenericVolume = pd.Field( GenericVolume(name="__farfield_zone_name_not_properly_set_yet"), frozen=True, exclude=True ) diff --git a/flow360/component/simulation/models/material.py b/flow360/component/simulation/models/material.py index 59537f72f..4757baec8 100644 --- a/flow360/component/simulation/models/material.py +++ b/flow360/component/simulation/models/material.py @@ -30,19 +30,40 @@ class MaterialBase(Flow360BaseModel): class Sutherland(Flow360BaseModel): """ - Sutherland's law + Represents Sutherland's law for calculating dynamic viscosity. + + This class implements Sutherland's formula to compute the dynamic viscosity of a gas + as a function of temperature. """ # pylint: disable=no-member - reference_viscosity: ViscosityType.NonNegative = pd.Field() - reference_temperature: TemperatureType.Positive = pd.Field() - effective_temperature: TemperatureType.Positive = pd.Field() + reference_viscosity: ViscosityType.NonNegative = pd.Field( + description="The reference dynamic viscosity at the reference temperature." + ) + reference_temperature: TemperatureType.Positive = pd.Field( + description="The reference temperature associated with the reference viscosity." + ) + effective_temperature: TemperatureType.Positive = pd.Field( + description="The effective temperature constant used in Sutherland's formula." + ) @pd.validate_call def get_dynamic_viscosity( self, temperature: TemperatureType.Positive ) -> ViscosityType.NonNegative: - """dynamic viscosity""" + """ + Calculates the dynamic viscosity at a given temperature using Sutherland's law. + + Parameters + ---------- + temperature : TemperatureType.Positive + The temperature at which to calculate the dynamic viscosity. + + Returns + ------- + ViscosityType.NonNegative + The calculated dynamic viscosity at the specified temperature. + """ return self.reference_viscosity * float( pow(temperature / self.reference_temperature, 1.5) * (self.reference_temperature + self.effective_temperature) @@ -53,7 +74,9 @@ def get_dynamic_viscosity( # pylint: disable=no-member, missing-function-docstring class Air(MaterialBase): """ - Material properties for Air + Represents the material properties for air. + This sets specific material properties for air, + including dynamic viscosity, specific heat ratio, gas constant, and Prandtl number. """ type: Literal["air"] = pd.Field("air", frozen=True) @@ -65,35 +88,106 @@ class Air(MaterialBase): # pylint: disable=fixme # TODO: validation error for effective_temperature not equal 110.4 K effective_temperature=110.4 * u.K, - ) + ), + description=( + "The dynamic viscosity model or value for air. Defaults to a `Sutherland` " + "model with standard atmospheric conditions." + ), ) @property def specific_heat_ratio(self) -> pd.PositiveFloat: + """ + Returns the specific heat ratio (gamma) for air. + + Returns + ------- + pd.PositiveFloat + The specific heat ratio, typically 1.4 for air. + """ return 1.4 @property def gas_constant(self) -> SpecificHeatCapacityType.Positive: + """ + Returns the specific gas constant for air. + + Returns + ------- + SpecificHeatCapacityType.Positive + The specific gas constant for air. + """ + return 287.0529 * u.m**2 / u.s**2 / u.K @property def prandtl_number(self) -> pd.PositiveFloat: + """ + Returns the Prandtl number for air. + + Returns + ------- + pd.PositiveFloat + The Prandtl number, typically around 0.72 for air. + """ + return 0.72 @pd.validate_call def get_pressure( self, density: DensityType.Positive, temperature: TemperatureType.Positive ) -> PressureType.Positive: + """ + Calculates the pressure of air using the ideal gas law. + + Parameters + ---------- + density : DensityType.Positive + The density of the air. + temperature : TemperatureType.Positive + The temperature of the air. + + Returns + ------- + PressureType.Positive + The calculated pressure. + """ return density * self.gas_constant * temperature @pd.validate_call def get_speed_of_sound(self, temperature: TemperatureType.Positive) -> VelocityType.Positive: + """ + Calculates the speed of sound in air at a given temperature. + + Parameters + ---------- + temperature : TemperatureType.Positive + The temperature at which to calculate the speed of sound. + + Returns + ------- + VelocityType.Positive + The speed of sound at the specified temperature. + """ return sqrt(self.specific_heat_ratio * self.gas_constant * temperature) @pd.validate_call def get_dynamic_viscosity( self, temperature: TemperatureType.Positive ) -> ViscosityType.NonNegative: + """ + Calculates the dynamic viscosity of air at a given temperature. + + Parameters + ---------- + temperature : TemperatureType.Positive + The temperature at which to calculate the dynamic viscosity. + + Returns + ------- + ViscosityType.NonNegative + The dynamic viscosity at the specified temperature. + """ if isinstance(self.dynamic_viscosity, Sutherland): return self.dynamic_viscosity.get_dynamic_viscosity(temperature) return self.dynamic_viscosity diff --git a/flow360/component/simulation/operating_condition/operating_condition.py b/flow360/component/simulation/operating_condition/operating_condition.py index a29b6381d..f61d5b5db 100644 --- a/flow360/component/simulation/operating_condition/operating_condition.py +++ b/flow360/component/simulation/operating_condition/operating_condition.py @@ -31,6 +31,7 @@ ) from flow360.component.simulation.validation.validation_context import ( CASE, + CaseField, ConditionalField, context_validator, ) @@ -51,26 +52,20 @@ class ThermalStateCache(Flow360BaseModel): class ThermalState(MultiConstructorBaseModel): """ Represents the thermal state of a fluid with specific properties. - - Attributes: - ----------- - temperature : TemperatureType.Positive - The temperature of the fluid, initialized to 288.15 K. This field is frozen and should not be modified after - construction. - density : DensityType.Positive - The density of the fluid, initialized to 1.225 kg/m^3. This field is frozen and should not be modified after - construction. - material : FluidMaterialTypes - The type of fluid material, initialized to Air(). This field is frozen and should not be modified after - construction. """ # pylint: disable=fixme # TODO: romove frozen and throw warning if temperature/density is modified after construction from atmospheric model type_name: Literal["ThermalState"] = pd.Field("ThermalState", frozen=True) - temperature: TemperatureType.Positive = pd.Field(288.15 * u.K, frozen=True) - density: DensityType.Positive = pd.Field(1.225 * u.kg / u.m**3, frozen=True) - material: FluidMaterialTypes = pd.Field(Air(), frozen=True) + temperature: TemperatureType.Positive = pd.Field( + 288.15 * u.K, frozen=True, description="The temperature of the fluid." + ) + density: DensityType.Positive = pd.Field( + 1.225 * u.kg / u.m**3, frozen=True, description="The density of the fluid." + ) + material: FluidMaterialTypes = pd.Field( + Air(), frozen=True, description="The material of the fluid." + ) private_attribute_input_cache: ThermalStateCache = ThermalStateCache() private_attribute_constructor: Literal["from_standard_atmosphere", "default"] = pd.Field( default="default", frozen=True @@ -84,14 +79,49 @@ def from_standard_atmosphere( altitude: LengthType = 0 * u.m, temperature_offset: TemperatureType = 0 * u.K, ): - """Constructs a thermal state from the standard atmosphere model. - - Parameters: - altitude (LengthType): The altitude at which the state is calculated. - temperature_offset (TemperatureType): The offset to be applied to the standard temperature. - - Returns: - ThermalState: The thermal state at the given altitude. + """ + Constructs a :class:`ThermalState` instance from the standard atmosphere model. + + Parameters + ---------- + altitude : LengthType, optional + The altitude at which the thermal state is calculated. Defaults to ``0 * u.m``. + temperature_offset : TemperatureType, optional + The temperature offset to be applied to the standard temperature at the given altitude. + Defaults to ``0 * u.K``. + + Returns + ------- + ThermalState + A thermal state representing the atmospheric conditions at the specified altitude and temperature offset. + + Notes + ----- + - This method uses the :class:`StandardAtmosphereModel` to compute the standard atmospheric + conditions based on the given altitude. + - The ``temperature_offset`` allows for adjustments to the standard temperature, simulating + non-standard atmospheric conditions. + + Examples + -------- + Create a thermal state at an altitude of 10,000 meters: + + >>> thermal_state = ThermalState.from_standard_atmosphere(altitude=10000 * u.m) + >>> thermal_state.temperature + + >>> thermal_state.density + + + Apply a temperature offset of -5 Kelvin at 5,000 meters: + + >>> thermal_state = ThermalState.from_standard_atmosphere( + ... altitude=5000 * u.m, + ... temperature_offset=-5 * u.K + ... ) + >>> thermal_state.temperature + + >>> thermal_state.density + """ standard_atmosphere_model = StandardAtmosphereModel( altitude.in_units(u.m).value, temperature_offset.in_units(u.K).value @@ -182,16 +212,19 @@ class AerospaceConditionCache(Flow360BaseModel): class AerospaceCondition(MultiConstructorBaseModel): - """A specialized GenericReferenceCondition for aerospace applications.""" + """Operating condition for aerospace applications.""" - # pylint: disable=fixme - # TODO: valildate reference_velocity_magnitude defined if velocity_magnitude=0 type_name: Literal["AerospaceCondition"] = pd.Field("AerospaceCondition", frozen=True) - alpha: AngleType = 0 * u.deg - beta: AngleType = 0 * u.deg - velocity_magnitude: Optional[VelocityType.NonNegative] = ConditionalField(context=CASE) + alpha: AngleType = ConditionalField(0 * u.deg, description="The angle of attack.", context=CASE) + beta: AngleType = ConditionalField(0 * u.deg, description="The side slip angle.", context=CASE) + velocity_magnitude: Optional[VelocityType.NonNegative] = ConditionalField( + description="Freestream velocity magnitude.", context=CASE + ) thermal_state: ThermalState = pd.Field(ThermalState(), alias="atmosphere") - reference_velocity_magnitude: Optional[VelocityType.Positive] = None + reference_velocity_magnitude: Optional[VelocityType.Positive] = CaseField( + None, + description="Reference velocity magnitude. Is required when :paramref:`velocity_magnitude` is 0.", + ) private_attribute_input_cache: AerospaceConditionCache = AerospaceConditionCache() # pylint: disable=too-many-arguments, no-self-argument, not-callable @@ -206,11 +239,52 @@ def from_mach( reference_mach: Optional[pd.PositiveFloat] = None, ): """ - Constructs a `AerospaceCondition` from Mach number and thermal state. - - Note: - Decided to move `velocity==0 ref_velocity is not None` check to dedicated validator because user can - still construct by just calling AerospaceCondition() + Constructs an :class:`AerospaceCondition` instance from a Mach number and thermal state. + + Parameters + ---------- + mach : float + The Mach number (non-negative). + alpha : AngleType, optional + The angle of attack. Defaults to ``0 * u.deg``. + beta : AngleType, optional + The side slip angle. Defaults to ``0 * u.deg``. + thermal_state : ThermalState, optional + The atmospheric thermal state. Defaults to a standard :class:`ThermalState`. + reference_mach : float, optional + The reference Mach number (positive). If provided, calculates the reference velocity magnitude. + + Returns + ------- + AerospaceCondition + An instance of :class:`AerospaceCondition` with the calculated velocity magnitude and provided parameters. + + Notes + ----- + - The ``velocity_magnitude`` is calculated as ``mach * thermal_state.speed_of_sound``. + - If ``reference_mach`` is provided, the ``reference_velocity_magnitude`` is calculated as + ``reference_mach * thermal_state.speed_of_sound``. + + Examples + -------- + Create an aerospace condition with a Mach number of 0.85: + + >>> condition = AerospaceCondition.from_mach(mach=0.85) + >>> condition.velocity_magnitude + + + Specify angle of attack and side slip angle: + + >>> condition = AerospaceCondition.from_mach(mach=0.85, alpha=5 * u.deg, beta=2 * u.deg) + + Include a custom thermal state and reference Mach number: + + >>> custom_thermal = ThermalState(temperature=250 * u.K) + >>> condition = AerospaceCondition.from_mach( + ... mach=0.85, + ... thermal_state=custom_thermal, + ... reference_mach=0.8 + ... ) """ velocity_magnitude = mach * thermal_state.speed_of_sound @@ -242,9 +316,6 @@ def mach(self) -> pd.PositiveFloat: """Computes Mach number.""" return self.velocity_magnitude / self.thermal_state.speed_of_sound - # pylint: disable=fixme - # TODO: Add after model validation that reference_velocity_magnitude is set when velocity_magnitude is 0 - # pylint: disable=fixme # TODO: AutomotiveCondition diff --git a/flow360/component/simulation/primitives.py b/flow360/component/simulation/primitives.py index 2812b81f6..a64f7ca63 100644 --- a/flow360/component/simulation/primitives.py +++ b/flow360/component/simulation/primitives.py @@ -61,11 +61,24 @@ def _check_axis_is_orthogonal(axis_pair: Tuple[Axis, Axis]) -> Tuple[Axis, Axis] class ReferenceGeometry(Flow360BaseModel): """ :class:`ReferenceGeometry` class contains all geometrical related refrence values. + + Example + ------- + >>> ReferenceGeometry( + ... moment_center=(1, 2, 1) * u.m, + ... moment_length=(1, 1, 1) * u.m, + ... area=1.5 * u.m**2 + ... ) + >>> ReferenceGeometry( + ... moment_center=(1, 2, 1) * u.m, + ... moment_length=1 * u.m, + ... area=1.5 * u.m**2 + ... ) # Equivalent to above """ # pylint: disable=no-member moment_center: Optional[LengthType.Point] = pd.Field( - None, description="The x, y, z moment center of the geometry in grid units." + None, description="The x, y, z coordinate of moment center." ) moment_length: Optional[Union[LengthType.Positive, LengthType.PositiveVector]] = pd.Field( None, description="The x, y, z component-wise moment reference lengths."