diff --git a/framework/include/vectorpostprocessors/LineMaterialRealSampler.h b/framework/include/vectorpostprocessors/LineMaterialRealSampler.h new file mode 100644 index 000000000000..a7c91f881678 --- /dev/null +++ b/framework/include/vectorpostprocessors/LineMaterialRealSampler.h @@ -0,0 +1,54 @@ +/****************************************************************/ +/* DO NOT MODIFY THIS HEADER */ +/* MOOSE - Multiphysics Object Oriented Simulation Environment */ +/* */ +/* (c) 2010 Battelle Energy Alliance, LLC */ +/* ALL RIGHTS RESERVED */ +/* */ +/* Prepared by Battelle Energy Alliance, LLC */ +/* Under Contract No. DE-AC07-05ID14517 */ +/* With the U. S. Department of Energy */ +/* */ +/* See COPYRIGHT for full restrictions */ +/****************************************************************/ + +#ifndef LINEMATERIALREALSAMPLER_H +#define LINEMATERIALREALSAMPLER_H + +#include "LineMaterialSamplerBase.h" + +//Forward Declarations +class LineMaterialRealSampler; + +template<> +InputParameters validParams(); + +/** + * This class samples Real material properties for the integration points + * in all elements that are intersected by a user-defined line. + */ +class LineMaterialRealSampler : + public LineMaterialSamplerBase +{ +public: + /** + * Class constructor + * Sets up variables for output based on the properties to be output + * @param name The name of the class + * @param parameters The input parameters + */ + LineMaterialRealSampler(const std::string & name, InputParameters parameters); + + virtual ~LineMaterialRealSampler() {} + + /** + * Reduce the material property to a scalar for output + * In this case, the material property is a Real already, so just return it. + * @param property The material property + * @param curr_point The point corresponding to this material property + * @return A scalar value from this material property to be output + */ + virtual Real getScalarFromProperty(Real &property, const Point * /*curr_point*/); +}; + +#endif diff --git a/framework/include/vectorpostprocessors/LineMaterialSamplerBase.h b/framework/include/vectorpostprocessors/LineMaterialSamplerBase.h new file mode 100644 index 000000000000..7ed2942d3e90 --- /dev/null +++ b/framework/include/vectorpostprocessors/LineMaterialSamplerBase.h @@ -0,0 +1,196 @@ +/****************************************************************/ +/* DO NOT MODIFY THIS HEADER */ +/* MOOSE - Multiphysics Object Oriented Simulation Environment */ +/* */ +/* (c) 2010 Battelle Energy Alliance, LLC */ +/* ALL RIGHTS RESERVED */ +/* */ +/* Prepared by Battelle Energy Alliance, LLC */ +/* Under Contract No. DE-AC07-05ID14517 */ +/* With the U. S. Department of Energy */ +/* */ +/* See COPYRIGHT for full restrictions */ +/****************************************************************/ + +#ifndef LINEMATERIALSAMPLERBASE_H +#define LINEMATERIALSAMPLERBASE_H + +#include "GeneralVectorPostprocessor.h" +#include "RayTracing.h" +#include "SamplerBase.h" +#include "FEProblem.h" +#include "InputParameters.h" + +//Forward Declarations +template +class LineMaterialSamplerBase; + +template<> +InputParameters validParams >(); + +/** + * This is a base class for sampling material properties for the integration points + * in all elements that are intersected by a user-defined line. The positions of + * those points are output in x, y, z coordinates, as well as in terms of the projected + * positions of those points along the line. Derived classes can be created to sample + * arbitrary types of material properties. + */ +template +class LineMaterialSamplerBase : + public GeneralVectorPostprocessor, + public SamplerBase +{ +public: + /** + * Class constructor + * Sets up variables for output based on the properties to be output + * @param name The name of the class + * @param parameters The input parameters + */ + LineMaterialSamplerBase(const std::string & name, InputParameters parameters); + + /** + * Class destructor + */ + virtual ~LineMaterialSamplerBase() {} + + /** + * Initialize + * Calls through to base class's initialize() + */ + virtual void initialize(); + + /** + * Finds all elements along the user-defined line, loops through them, and samples their + * material properties. + */ + virtual void execute(); + + /** + * Finalize + * Calls through to base class's finalize() + */ + virtual void finalize(); + + /** + * Thread Join + * Calls through to base class's threadJoin() + * @param sb SamplerBase object to be joint into this object + */ + virtual void threadJoin(const SamplerBase & sb); + + /** + * Reduce the material property to a scalar for output + * @param property The material property + * @param curr_point The point corresponding to this material property + * @return A scalar value from this material property to be output + */ + virtual Real getScalarFromProperty(T & property, const Point * curr_point) = 0; + +protected: + /// The beginning of the line + Point _start; + + /// The end of the line + Point _end; + + /// The material properties to be output + std::vector *> _material_properties; + + /// The mesh + MooseMesh & _mesh; + + /// The quadrature rule + QBase * & _qrule; + + /// The quadrature points + const MooseArray & _q_point; +}; + +template +LineMaterialSamplerBase::LineMaterialSamplerBase(const std::string & name, InputParameters parameters) : + GeneralVectorPostprocessor(name, parameters), + SamplerBase(name, parameters, this, _communicator), + _start(getParam("start")), + _end(getParam("end")), + _mesh(_subproblem.mesh()), + _qrule(_subproblem.assembly(_tid).qRule()), + _q_point(_subproblem.assembly(_tid).qPoints()) +{ + std::vector material_property_names = getParam >("property"); + for (unsigned int i=0; i(material_property_names[i])) + mooseError("In LineMaterialSamplerBase material property: " + material_property_names[i] + " does not exist."); + _material_properties.push_back(&getMaterialProperty(material_property_names[i])); + } + + SamplerBase::setupVariables(material_property_names); +} + +template +void +LineMaterialSamplerBase::initialize() +{ + SamplerBase::initialize(); +} + +template +void +LineMaterialSamplerBase::execute() +{ + std::vector intersected_elems; + Moose::elementsIntersectedByLine(_start, _end, _fe_problem.mesh(), intersected_elems); + + const RealVectorValue line_vec = _end - _start; + const Real line_length(line_vec.size()); + const RealVectorValue line_unit_vec = line_vec / line_length; + std::vector values(_material_properties.size()); + + for (unsigned int i=0; iprocessor_id() != processor_id()) + continue; + + _subproblem.prepare(elem, _tid); + _subproblem.reinitElem(elem, _tid); + _fe_problem.reinitMaterials(elem->subdomain_id(), _tid); + + for (unsigned int qp=0; qp<_qrule->n_points(); ++qp) + { + const RealVectorValue qp_pos(_q_point[qp]); + + const RealVectorValue start_to_qp(qp_pos - _start); + const Real qp_proj_dist_along_line = start_to_qp * line_unit_vec; + + if (qp_proj_dist_along_line < 0 || qp_proj_dist_along_line > line_length) + continue; + + for (unsigned int j=0; j<_material_properties.size(); ++j) + { + values[j] = getScalarFromProperty((*_material_properties[j])[qp], &_q_point[qp]); + } + addSample(_q_point[qp], qp_proj_dist_along_line, values); + } + _fe_problem.swapBackMaterials(_tid); + } +} + +template +void +LineMaterialSamplerBase::finalize() +{ + SamplerBase::finalize(); +} + +template +void +LineMaterialSamplerBase::threadJoin(const SamplerBase & sb) +{ + const LineMaterialSamplerBase & lmsb = static_cast &>(sb); + SamplerBase::threadJoin(sb); +} + +#endif diff --git a/framework/src/base/Moose.C b/framework/src/base/Moose.C index 8f827ecb59f4..0d586481006d 100644 --- a/framework/src/base/Moose.C +++ b/framework/src/base/Moose.C @@ -193,6 +193,7 @@ #include "LineValueSampler.h" #include "VectorOfPostprocessors.h" #include "ElementsAlongLine.h" +#include "LineMaterialRealSampler.h" // user objects #include "LayeredIntegral.h" @@ -553,6 +554,7 @@ registerObjects(Factory & factory) registerVectorPostprocessor(LineValueSampler); registerVectorPostprocessor(VectorOfPostprocessors); registerVectorPostprocessor(ElementsAlongLine); + registerVectorPostprocessor(LineMaterialRealSampler); // user objects registerUserObject(LayeredIntegral); diff --git a/framework/src/vectorpostprocessors/LineMaterialRealSampler.C b/framework/src/vectorpostprocessors/LineMaterialRealSampler.C new file mode 100644 index 000000000000..33ce899f0685 --- /dev/null +++ b/framework/src/vectorpostprocessors/LineMaterialRealSampler.C @@ -0,0 +1,33 @@ +/****************************************************************/ +/* DO NOT MODIFY THIS HEADER */ +/* MOOSE - Multiphysics Object Oriented Simulation Environment */ +/* */ +/* (c) 2010 Battelle Energy Alliance, LLC */ +/* ALL RIGHTS RESERVED */ +/* */ +/* Prepared by Battelle Energy Alliance, LLC */ +/* Under Contract No. DE-AC07-05ID14517 */ +/* With the U. S. Department of Energy */ +/* */ +/* See COPYRIGHT for full restrictions */ +/****************************************************************/ + +#include "LineMaterialRealSampler.h" + +template<> +InputParameters validParams() +{ + InputParameters params = validParams >(); + return params; +} + +LineMaterialRealSampler::LineMaterialRealSampler(const std::string & name, InputParameters parameters) : + LineMaterialSamplerBase(name, parameters) +{ +} + +Real +LineMaterialRealSampler::getScalarFromProperty(Real & property, const Point * /*curr_point*/) +{ + return property; +} diff --git a/framework/src/vectorpostprocessors/LineMaterialSamplerBase.C b/framework/src/vectorpostprocessors/LineMaterialSamplerBase.C new file mode 100644 index 000000000000..fafa3f2c3cf8 --- /dev/null +++ b/framework/src/vectorpostprocessors/LineMaterialSamplerBase.C @@ -0,0 +1,27 @@ +/****************************************************************/ +/* DO NOT MODIFY THIS HEADER */ +/* MOOSE - Multiphysics Object Oriented Simulation Environment */ +/* */ +/* (c) 2010 Battelle Energy Alliance, LLC */ +/* ALL RIGHTS RESERVED */ +/* */ +/* Prepared by Battelle Energy Alliance, LLC */ +/* Under Contract No. DE-AC07-05ID14517 */ +/* With the U. S. Department of Energy */ +/* */ +/* See COPYRIGHT for full restrictions */ +/****************************************************************/ + +#include "LineMaterialSamplerBase.h" + +template<> +InputParameters validParams >() +{ + InputParameters params = validParams(); + params += validParams(); + params.addRequiredParam("start", "The beginning of the line"); + params.addRequiredParam("end", "The end of the line"); + params.addRequiredParam >("property", "Name of the material property to be output along a line"); + + return params; +} diff --git a/modules/solid_mechanics/include/vectorpostprocessors/LineMaterialSymmTensorSampler.h b/modules/solid_mechanics/include/vectorpostprocessors/LineMaterialSymmTensorSampler.h new file mode 100644 index 000000000000..f248972ad8bf --- /dev/null +++ b/modules/solid_mechanics/include/vectorpostprocessors/LineMaterialSymmTensorSampler.h @@ -0,0 +1,58 @@ +/****************************************************************/ +/* DO NOT MODIFY THIS HEADER */ +/* MOOSE - Multiphysics Object Oriented Simulation Environment */ +/* */ +/* (c) 2010 Battelle Energy Alliance, LLC */ +/* ALL RIGHTS RESERVED */ +/* */ +/* Prepared by Battelle Energy Alliance, LLC */ +/* Under Contract No. DE-AC07-05ID14517 */ +/* With the U. S. Department of Energy */ +/* */ +/* See COPYRIGHT for full restrictions */ +/****************************************************************/ + +#ifndef LINEMATERIALTENSORSAMPLER_H +#define LINEMATERIALTENSORSAMPLER_H + +#include "LineMaterialSamplerBase.h" +#include "MaterialTensorCalculator.h" + +//Forward Declarations +class LineMaterialSymmTensorSampler; + +template<> +InputParameters validParams(); + +/** + * This class samples SymmTensor material properties for the integration points + * in all elements that are intersected by a user-defined line. It provides + * access to the full set of options for reducing the SymmTensor to a scalar. + */ +class LineMaterialSymmTensorSampler : + public LineMaterialSamplerBase, + public MaterialTensorCalculator +{ +public: + /** + * Class constructor + * Sets up variables for output based on the properties to be output + * @param name The name of the class + * @param parameters The input parameters + */ + LineMaterialSymmTensorSampler(const std::string & name, InputParameters parameters); + + virtual ~LineMaterialSymmTensorSampler() {} + + /** + * Reduce the material property to a scalar for output + * Call through to getTensorQuantity to access the full set of options for reducing + * the SymmTensor to a scalar quantity. + * @param property The material property + * @param curr_point The point corresponding to this material property + * @return A scalar value from this material property to be output + */ + virtual Real getScalarFromProperty(SymmTensor &property, const Point * curr_point); +}; + +#endif diff --git a/modules/solid_mechanics/src/base/SolidMechanicsApp.C b/modules/solid_mechanics/src/base/SolidMechanicsApp.C index 53dc24fecc75..a6632fa6f5be 100644 --- a/modules/solid_mechanics/src/base/SolidMechanicsApp.C +++ b/modules/solid_mechanics/src/base/SolidMechanicsApp.C @@ -43,6 +43,7 @@ #include "PowerLawCreepModel.h" #include "CavityPressureAction.h" #include "CavityPressurePostprocessor.h" +#include "LineMaterialSymmTensorSampler.h" #include "CavityPressurePPAction.h" #include "CavityPressureUserObject.h" #include "CavityPressureUOAction.h" @@ -157,6 +158,7 @@ SolidMechanicsApp::registerObjects(Factory & factory) registerPostprocessor(TorqueReaction); registerVectorPostprocessor(CrackDataSampler); + registerVectorPostprocessor(LineMaterialSymmTensorSampler); registerUserObject(MaterialTensorOnLine); registerUserObject(CavityPressureUserObject); diff --git a/modules/solid_mechanics/src/vectorpostprocessors/LineMaterialSymmTensorSampler.C b/modules/solid_mechanics/src/vectorpostprocessors/LineMaterialSymmTensorSampler.C new file mode 100644 index 000000000000..9b5185209832 --- /dev/null +++ b/modules/solid_mechanics/src/vectorpostprocessors/LineMaterialSymmTensorSampler.C @@ -0,0 +1,36 @@ +/****************************************************************/ +/* DO NOT MODIFY THIS HEADER */ +/* MOOSE - Multiphysics Object Oriented Simulation Environment */ +/* */ +/* (c) 2010 Battelle Energy Alliance, LLC */ +/* ALL RIGHTS RESERVED */ +/* */ +/* Prepared by Battelle Energy Alliance, LLC */ +/* Under Contract No. DE-AC07-05ID14517 */ +/* With the U. S. Department of Energy */ +/* */ +/* See COPYRIGHT for full restrictions */ +/****************************************************************/ + +#include "LineMaterialSymmTensorSampler.h" + +template<> +InputParameters validParams() +{ + InputParameters params = validParams >(); + params += validParams(); + return params; +} + +LineMaterialSymmTensorSampler::LineMaterialSymmTensorSampler(const std::string & name, InputParameters parameters) : + LineMaterialSamplerBase(name, parameters), + MaterialTensorCalculator(name, parameters) +{ +} + +Real +LineMaterialSymmTensorSampler::getScalarFromProperty(SymmTensor &property, const Point * curr_point) +{ + RealVectorValue direction; + return getTensorQuantity(property, curr_point, direction); +} diff --git a/modules/solid_mechanics/tests/line_material_symm_tensor_sampler/gold/out_vonmises_0010.csv b/modules/solid_mechanics/tests/line_material_symm_tensor_sampler/gold/out_vonmises_0010.csv new file mode 100644 index 000000000000..8c61af53322f --- /dev/null +++ b/modules/solid_mechanics/tests/line_material_symm_tensor_sampler/gold/out_vonmises_0010.csv @@ -0,0 +1,18 @@ +id,stress,x,y,z +0.096191711531604,1.0671942524643,0.2628917115316,0.40377495513506,0.59622504486494 +0.096191711531604,1.0671942524643,0.2628917115316,0.59622504486494,0.59622504486494 +0.096191711531604,1.0515604342991,0.2628917115316,0.40377495513506,0.40377495513506 +0.096191711531604,1.0515604342991,0.2628917115316,0.59622504486494,0.40377495513506 +0.23707495513506,1.0796895299332,0.40377495513506,0.40377495513506,0.59622504486494 +0.23707495513506,1.0427391128508,0.40377495513506,0.59622504486494,0.40377495513506 +0.23707495513506,1.0796895299332,0.40377495513506,0.59622504486494,0.59622504486494 +0.23707495513506,1.0427391128508,0.40377495513506,0.40377495513506,0.40377495513506 +0.42952504486494,1.0427391128508,0.59622504486494,0.40377495513506,0.40377495513506 +0.42952504486494,1.0427391128508,0.59622504486494,0.59622504486494,0.40377495513506 +0.42952504486494,1.0796895299332,0.59622504486494,0.40377495513506,0.59622504486494 +0.42952504486494,1.0796895299332,0.59622504486494,0.59622504486494,0.59622504486494 +0.5704082884684,1.0515604342991,0.7371082884684,0.40377495513506,0.40377495513506 +0.5704082884684,1.0515604342991,0.7371082884684,0.59622504486494,0.40377495513506 +0.5704082884684,1.0671942524643,0.7371082884684,0.40377495513506,0.59622504486494 +0.5704082884684,1.0671942524643,0.7371082884684,0.59622504486494,0.59622504486494 + diff --git a/modules/solid_mechanics/tests/line_material_symm_tensor_sampler/line_material_symm_tensor_sampler.i b/modules/solid_mechanics/tests/line_material_symm_tensor_sampler/line_material_symm_tensor_sampler.i new file mode 100644 index 000000000000..12862c675260 --- /dev/null +++ b/modules/solid_mechanics/tests/line_material_symm_tensor_sampler/line_material_symm_tensor_sampler.i @@ -0,0 +1,148 @@ +[Mesh] + type = GeneratedMesh + dim = 3 + nx = 3 + ny = 3 + nz = 3 + elem_type = HEX +[] + +[Functions] + [./rampConstant] + type = PiecewiseLinear + x = '0. 1.' + y = '0. 1.' + scale_factor = 1e-6 + [../] +[] + +[Variables] + active = 'x_disp y_disp z_disp' + + [./x_disp] + order = FIRST + family = LAGRANGE + [../] + + [./y_disp] + order = FIRST + family = LAGRANGE + [../] + + [./z_disp] + order = FIRST + family = LAGRANGE + [../] +[] + +[AuxVariables] + [./vonmises] + order = CONSTANT + family = MONOMIAL + [../] + [./stress_xx] + order = CONSTANT + family = MONOMIAL + [../] +[] + +[AuxKernels] + [./vonmises] + type = MaterialTensorAux + tensor = stress + variable = vonmises + quantity = vonmises + [../] +[] + +[VectorPostprocessors] + [./vonmises] + type = LineMaterialSymmTensorSampler + start = '0.1667 0.5 0.5' + end = '0.8333 0.5 0.5' + property = stress + quantity = vonmises + sort_by = id + [../] +[] + +[SolidMechanics] + [./solid] + disp_x = x_disp + disp_y = y_disp + disp_z = z_disp + [../] +[] + +[BCs] + + [./front] + type = FunctionDirichletBC + variable = z_disp + boundary = 5 + function = rampConstant + [../] + + [./back_x] + type = DirichletBC + variable = x_disp + boundary = 0 + value = 0.0 + [../] + + [./back_y] + type = DirichletBC + variable = y_disp + boundary = 0 + value = 0.0 + [../] + + [./back_z] + type = DirichletBC + variable = z_disp + boundary = 0 + value = 0.0 + [../] + +[] + +[Materials] + [./constant] + type = LinearIsotropicMaterial + block = 0 + youngs_modulus = 1e6 + poissons_ratio = .3 + disp_x = x_disp + disp_y = y_disp + disp_z = z_disp + [../] +[] + +[Executioner] + type = Transient + + solve_type = PJFNK + + + + l_max_its = 100 + + start_time = 0.0 + num_steps = 99999 + end_time = 1.0 + dt = 0.1 +[] + +[Outputs] + file_base = out + output_initial = true + exodus = true + csv = true + [./console] + type = Console + perf_log = true + linear_residuals = true + [../] +[] + + diff --git a/modules/solid_mechanics/tests/line_material_symm_tensor_sampler/tests b/modules/solid_mechanics/tests/line_material_symm_tensor_sampler/tests new file mode 100644 index 000000000000..9185fc990c52 --- /dev/null +++ b/modules/solid_mechanics/tests/line_material_symm_tensor_sampler/tests @@ -0,0 +1,7 @@ +[Tests] + [./test] + type = 'CSVDiff' + input = 'line_material_symm_tensor_sampler.i' + csvdiff = 'out_vonmises_0010.csv' + [../] +[] diff --git a/test/tests/vectorpostprocessors/line_material_sampler/gold/out_mat_0001.csv b/test/tests/vectorpostprocessors/line_material_sampler/gold/out_mat_0001.csv new file mode 100644 index 000000000000..b5f2fe778d8d --- /dev/null +++ b/test/tests/vectorpostprocessors/line_material_sampler/gold/out_mat_0001.csv @@ -0,0 +1,14 @@ +id,matp,x,y,z +0.072168783648703,1.1971687836487,0.1971687836487,0.3028312163513,0 +0.072168783648703,1.1971687836487,0.1971687836487,0.4471687836487,0 +0.1778312163513,1.3028312163513,0.3028312163513,0.3028312163513,0 +0.1778312163513,1.3028312163513,0.3028312163513,0.4471687836487,0 +0.3221687836487,1.4471687836487,0.4471687836487,0.3028312163513,0 +0.3221687836487,1.4471687836487,0.4471687836487,0.4471687836487,0 +0.4278312163513,1.5528312163513,0.5528312163513,0.3028312163513,0 +0.4278312163513,1.5528312163513,0.5528312163513,0.4471687836487,0 +0.5721687836487,1.6971687836487,0.6971687836487,0.3028312163513,0 +0.5721687836487,1.6971687836487,0.6971687836487,0.4471687836487,0 +0.6778312163513,1.8028312163513,0.8028312163513,0.3028312163513,0 +0.6778312163513,1.8028312163513,0.8028312163513,0.4471687836487,0 + diff --git a/test/tests/vectorpostprocessors/line_material_sampler/line_material_real_sampler.i b/test/tests/vectorpostprocessors/line_material_sampler/line_material_real_sampler.i new file mode 100644 index 000000000000..8af6f3785225 --- /dev/null +++ b/test/tests/vectorpostprocessors/line_material_sampler/line_material_real_sampler.i @@ -0,0 +1,97 @@ +[Mesh] + type = GeneratedMesh + dim = 2 + xmin = 0 + xmax = 1 + ymin = 0 + ymax = 1 + nx = 4 + ny = 4 +[] + +[Variables] + [./u] + order = FIRST + family = LAGRANGE + [../] +[] + +[AuxVariables] + [./mat] + order = CONSTANT + family = MONOMIAL + [../] +[] + +[Kernels] + [./diff] + type = MatDiffusion + variable = u + prop_name = matp + [../] +[] + +[AuxKernels] + [./mat] + type = MaterialRealAux + variable = mat + property = matp + execute_on = timestep_end + [../] +[] + +[VectorPostprocessors] + [./mat] + type = LineMaterialRealSampler + start = '0.125 0.375 0.0' + end = '0.875 0.375 0.0' + property = matp + sort_by = id + [../] +[] + +[BCs] + [./left] + type = DirichletBC + variable = u + boundary = 3 + value = 1 + [../] + + [./right] + type = MTBC + variable = u + boundary = 1 + grad = 8 + prop_name = matp + [../] +[] + +[Materials] + [./mat] + type = MTMaterial + block = 0 + [../] +[] + +[Executioner] + type = Steady + + # Preconditioned JFNK (default) + solve_type = 'PJFNK' +[] + +[Outputs] + file_base = out + output_on = 'initial timestep_end' + csv = true + [./exodus] + type = Exodus + elemental_as_nodal = true + [../] + [./console] + type = Console + perf_log = true + output_on = 'timestep_end failed nonlinear' + [../] +[] diff --git a/test/tests/vectorpostprocessors/line_material_sampler/tests b/test/tests/vectorpostprocessors/line_material_sampler/tests new file mode 100644 index 000000000000..9ab9144145d7 --- /dev/null +++ b/test/tests/vectorpostprocessors/line_material_sampler/tests @@ -0,0 +1,7 @@ +[Tests] + [./test] + type = 'CSVDiff' + input = 'line_material_real_sampler.i' + csvdiff = 'out_mat_0001.csv' + [../] +[]