@@ -689,6 +689,37 @@ NB_MODULE(units_llnl_ext, mod)
689689 new (dim) Dimension{def};
690690 },
691691 " dimension" _a)
692+ .def (
693+ " __init__" ,
694+ [](Dimension* dim, const nb::dict &composition) {
695+ units::precise_unit def;
696+
697+ for (const auto & element : composition)
698+ {
699+ nb::handle key_handle = element.first ;
700+ nb::handle value_handle = element.second ;
701+
702+ // Convert the key handle to a std::string
703+ std::string key = nb::cast<std::string>(key_handle);
704+
705+ // Convert the value handle to an int
706+ int value = nb::cast<int >(value_handle);
707+ if (key == " custom" )
708+ {
709+ def=def*units::precise::generate_custom_unit (static_cast <std::uint16_t >(value));
710+ }
711+ else if (key == " custom_count" )
712+ {
713+ def=def*units::precise::generate_custom_count_unit (static_cast <std::uint16_t >(value));
714+ }
715+ else
716+ {
717+ def=def*(units::unit_from_string (key).pow (value));
718+ }
719+ }
720+ new (dim) Dimension{def};
721+ },
722+ " composition" _a)
692723 .def_prop_ro (
693724 " default_unit" ,
694725 [](const Dimension& dim) { return (dim.base ); },
@@ -747,6 +778,92 @@ NB_MODULE(units_llnl_ext, mod)
747778 .def (
748779 " __invert__" ,
749780 [](const Dimension& dim) { return Dimension{dim.base .inv ()}; })
781+ .def (" decompose" ,
782+ [](const Dimension& dim) {
783+ nb::dict dictionary;
784+ auto base_units=dim.base ;
785+ units::detail::unit_data base=base_units.base_units ();
786+ bool custom{false };
787+ if (units::precise::custom::is_custom_unit (base))
788+ {
789+ dictionary[" custom" ]=units::precise::custom::custom_unit_number (base);
790+ if (units::precise::custom::is_custom_unit_inverted (base))
791+ {
792+ dictionary[" inverted" ]=1 ;
793+ }
794+ custom=true ;
795+ }
796+ else if (units::precise::custom::is_custom_count_unit (base))
797+ {
798+ dictionary[" custom_count" ]=units::precise::custom::custom_count_unit_number (base);
799+ if (units::precise::custom::is_custom_count_unit_inverted (base))
800+ {
801+ dictionary[" inverted" ]=1 ;
802+ }
803+ custom=true ;
804+ }
805+ if (!custom)
806+ {
807+ if (base.meter () != 0 )
808+ {
809+ dictionary[" meters" ] = base.meter ();
810+ }
811+ if (base.kg () != 0 )
812+ {
813+ dictionary[" kilogram" ] = base.kg ();
814+ }
815+ if (base.second () != 0 )
816+ {
817+ dictionary[" second" ] = base.second ();
818+ }
819+ if (base.ampere () != 0 )
820+ {
821+ dictionary[" ampere" ] = base.ampere ();
822+ }
823+ if (base.kelvin () != 0 )
824+ {
825+ dictionary[" kelvin" ] = base.kelvin ();
826+ }
827+ if (base.mole () != 0 )
828+ {
829+ dictionary[" mole" ] = base.mole ();
830+ }
831+ if (base.candela () != 0 )
832+ {
833+ dictionary[" candela" ] = base.candela ();
834+ }
835+ if (base.currency () != 0 )
836+ {
837+ dictionary[" currency" ] = base.currency ();
838+ }
839+ if (base.count () != 0 )
840+ {
841+ dictionary[" count" ] = base.count ();
842+ }
843+ if (base.radian () != 0 )
844+ {
845+ dictionary[" radian" ] = base.radian ();
846+ }
847+ if (base.is_per_unit ())
848+ {
849+ dictionary[" per_unit" ] = 1 ;
850+ }
851+ if (base.has_i_flag ())
852+ {
853+ dictionary[" iflag" ] = 1 ;
854+ }
855+ if (base.has_e_flag ())
856+ {
857+ dictionary[" eflag" ] = 1 ;
858+ }
859+
860+ }
861+ if (base.is_equation ())
862+ {
863+ dictionary[" equation" ] = 1 ;
864+ }
865+ return dictionary;
866+ } )
750867 .def (
751868 " __pow__" ,
752869 [](const Dimension& dim, int power) {
0 commit comments