@@ -211,6 +211,24 @@ void box2_current(const xdouble *x, xdouble *J)
211211 J[2 ] = 6 * y;
212212}
213213
214+ template <typename xdouble = double >
215+ xdouble box1_current2D (const xdouble *x)
216+ {
217+ auto y = x[1 ] - .5 ;
218+
219+ // J[2] = -current_density*6*y*(1/(M_PI*4e-7)); // for real scaled problem
220+ return -6 * y;
221+ }
222+
223+ template <typename xdouble = double >
224+ xdouble box2_current2D (const xdouble *x)
225+ {
226+ auto y = x[1 ] - .5 ;
227+
228+ // J[2] = current_density*6*y*(1/(M_PI*4e-7)); // for real scaled problem
229+ return 6 * y;
230+ }
231+
214232// / function to get the sign of a number
215233template <typename T>
216234int sgn (T val)
@@ -536,6 +554,66 @@ void box2CurrentSourceRevDiff(adept::Stack &diff_stack,
536554 source_jac.MultTranspose (V_bar, x_bar);
537555}
538556
557+ double box1CurrentSource2D (const mfem::Vector &x)
558+ {
559+ return box1_current2D (x.GetData ());
560+ }
561+
562+ // / TODO: this is how Adept should be used here, eventually
563+ // / should update the rest of the use cases to match this
564+ // / (it's more efficient)
565+ void box1CurrentSource2DRevDiff (adept::Stack &diff_stack,
566+ const mfem::Vector &x,
567+ double J_bar,
568+ mfem::Vector &x_bar)
569+ {
570+ std::array<adouble, 2 > x_a;
571+ // copy data from mfem::Vector
572+ adept::set_values (x_a.data (), x.Size (), x.GetData ());
573+
574+ // start recording
575+ diff_stack.new_recording ();
576+
577+ // the depedent variable must be declared after the recording
578+ auto J_a = box1_current2D<adouble>(x_a.data ());
579+
580+ J_a.set_gradient (J_bar);
581+ diff_stack.compute_adjoint ();
582+
583+ // calculate the vector jacobian product w.r.t position
584+ adept::get_gradients (x_a.data (), x.Size (), x_bar.GetData ());
585+ }
586+
587+ double box2CurrentSource2D (const mfem::Vector &x)
588+ {
589+ return box2_current2D (x.GetData ());
590+ }
591+
592+ // / TODO: this is how Adept should be used here, eventually
593+ // / should update the rest of the use cases to match this
594+ // / (it's more efficient)
595+ void box2CurrentSource2DRevDiff (adept::Stack &diff_stack,
596+ const mfem::Vector &x,
597+ double J_bar,
598+ mfem::Vector &x_bar)
599+ {
600+ std::array<adouble, 2 > x_a;
601+ // copy data from mfem::Vector
602+ adept::set_values (x_a.data (), x.Size (), x.GetData ());
603+
604+ // start recording
605+ diff_stack.new_recording ();
606+
607+ // the depedent variable must be declared after the recording
608+ auto J_a = box2_current2D<adouble>(x_a.data ());
609+
610+ J_a.set_gradient (J_bar);
611+ diff_stack.compute_adjoint ();
612+
613+ // calculate the vector jacobian product w.r.t position
614+ adept::get_gradients (x_a.data (), x.Size (), x_bar.GetData ());
615+ }
616+
539617void team13CurrentSource (const mfem::Vector &x, mfem::Vector &J)
540618{
541619 team13_current (x.GetData (), J.GetData ());
@@ -566,7 +644,7 @@ void team13CurrentSourceRevDiff(adept::Stack &diff_stack,
566644
567645} // anonymous namespace
568646
569- namespace mach
647+ namespace miso
570648{
571649void CurrentDensityCoefficient::cacheCurrentDensity ()
572650{
@@ -592,7 +670,7 @@ void CurrentDensityCoefficient::resetCurrentDensityFromCache()
592670 }
593671}
594672
595- bool setInputs (CurrentDensityCoefficient ¤t, const MachInputs &inputs)
673+ bool setInputs (CurrentDensityCoefficient ¤t, const MISOInputs &inputs)
596674{
597675 bool updated = false ;
598676 for (auto &[group, coeff] : current.group_map )
@@ -654,7 +732,7 @@ CurrentDensityCoefficient::CurrentDensityCoefficient(
654732 auto n_slots = cached_inputs.at (" n_slots" );
655733 cached_inputs.emplace (" stack_length" , 0.345 );
656734 auto stack_length = cached_inputs.at (" stack_length" );
657- for (auto &attr : attrs)
735+ for (const auto &attr : attrs)
658736 {
659737 source_coeffs.emplace (
660738 attr,
@@ -689,7 +767,7 @@ CurrentDensityCoefficient::CurrentDensityCoefficient(
689767 auto n_slots = cached_inputs.at (" n_slots" );
690768 cached_inputs.emplace (" stack_length" , 0.345 );
691769 auto stack_length = cached_inputs.at (" stack_length" );
692- for (auto &attr : attrs)
770+ for (const auto &attr : attrs)
693771 {
694772 source_coeffs.emplace (
695773 attr,
@@ -720,7 +798,7 @@ CurrentDensityCoefficient::CurrentDensityCoefficient(
720798 }
721799 else if (source == " x" )
722800 {
723- for (auto &attr : attrs)
801+ for (const auto &attr : attrs)
724802 {
725803 source_coeffs.emplace (
726804 attr,
@@ -743,7 +821,7 @@ CurrentDensityCoefficient::CurrentDensityCoefficient(
743821 }
744822 else if (source == " y" )
745823 {
746- for (auto &attr : attrs)
824+ for (const auto &attr : attrs)
747825 {
748826 source_coeffs.emplace (
749827 attr,
@@ -766,7 +844,7 @@ CurrentDensityCoefficient::CurrentDensityCoefficient(
766844 }
767845 else if (source == " z" )
768846 {
769- for (auto &attr : attrs)
847+ for (const auto &attr : attrs)
770848 {
771849 source_coeffs.emplace (
772850 attr,
@@ -789,7 +867,7 @@ CurrentDensityCoefficient::CurrentDensityCoefficient(
789867 }
790868 else if (source == " -z" )
791869 {
792- for (auto &attr : attrs)
870+ for (const auto &attr : attrs)
793871 {
794872 source_coeffs.emplace (
795873 attr,
@@ -812,7 +890,7 @@ CurrentDensityCoefficient::CurrentDensityCoefficient(
812890 }
813891 else if (source == " ring" )
814892 {
815- for (auto &attr : attrs)
893+ for (const auto &attr : attrs)
816894 {
817895 source_coeffs.emplace (
818896 attr,
@@ -834,7 +912,7 @@ CurrentDensityCoefficient::CurrentDensityCoefficient(
834912 }
835913 else if (source == " box1" )
836914 {
837- for (auto &attr : attrs)
915+ for (const auto &attr : attrs)
838916 {
839917 source_coeffs.emplace (
840918 attr,
@@ -856,7 +934,7 @@ CurrentDensityCoefficient::CurrentDensityCoefficient(
856934 }
857935 else if (source == " box2" )
858936 {
859- for (auto &attr : attrs)
937+ for (const auto &attr : attrs)
860938 {
861939 source_coeffs.emplace (
862940 attr,
@@ -878,7 +956,7 @@ CurrentDensityCoefficient::CurrentDensityCoefficient(
878956 }
879957 else if (source == " team13" )
880958 {
881- for (auto &attr : attrs)
959+ for (const auto &attr : attrs)
882960 {
883961 source_coeffs.emplace (
884962 attr,
@@ -903,4 +981,168 @@ CurrentDensityCoefficient::CurrentDensityCoefficient(
903981 }
904982}
905983
906- } // namespace mach
984+ void CurrentDensityCoefficient2D::cacheCurrentDensity ()
985+ {
986+ for (auto &[group, coeff] : group_map)
987+ {
988+ cached_inputs.at (group) = coeff.constant ;
989+ }
990+ }
991+
992+ void CurrentDensityCoefficient2D::zeroCurrentDensity ()
993+ {
994+ for (auto &[group, coeff] : group_map)
995+ {
996+ coeff.constant = 0.0 ;
997+ }
998+ }
999+
1000+ void CurrentDensityCoefficient2D::resetCurrentDensityFromCache ()
1001+ {
1002+ for (auto &[group, value] : cached_inputs)
1003+ {
1004+ group_map.at (group).constant = value;
1005+ }
1006+ }
1007+
1008+ bool setInputs (CurrentDensityCoefficient2D ¤t, const MISOInputs &inputs)
1009+ {
1010+ bool updated = false ;
1011+ for (auto &[group, coeff] : current.group_map )
1012+ {
1013+ auto old_const = coeff.constant ;
1014+ std::string cd_group_id = " current_density:" + group;
1015+ setValueFromInputs (inputs, cd_group_id, coeff.constant );
1016+ if (coeff.constant != old_const)
1017+ {
1018+ updated = true ;
1019+ }
1020+ }
1021+
1022+ for (auto &[input, value] : current.cached_inputs )
1023+ {
1024+ auto old_value = value;
1025+ setValueFromInputs (inputs, input, value);
1026+ if (value != old_value)
1027+ {
1028+ updated = true ;
1029+ }
1030+ }
1031+ return updated;
1032+ }
1033+
1034+ double CurrentDensityCoefficient2D::Eval (mfem::ElementTransformation &trans,
1035+ const mfem::IntegrationPoint &ip)
1036+ {
1037+ return -1.0 * current_coeff.Eval (trans, ip);
1038+ }
1039+
1040+ void CurrentDensityCoefficient2D::EvalRevDiff (
1041+ double Q_bar,
1042+ mfem::ElementTransformation &trans,
1043+ const mfem::IntegrationPoint &ip,
1044+ mfem::DenseMatrix &PointMat_bar)
1045+ {
1046+ Q_bar *= -1.0 ;
1047+ current_coeff.EvalRevDiff (Q_bar, trans, ip, PointMat_bar);
1048+ }
1049+
1050+ CurrentDensityCoefficient2D::CurrentDensityCoefficient2D (
1051+ adept::Stack &diff_stack,
1052+ const nlohmann::json ¤t_options)
1053+ {
1054+ for (auto &[group, group_details] : current_options.items ())
1055+ {
1056+ group_map.emplace (group, mfem::ConstantCoefficient{1.0 });
1057+ auto &group_coeff = group_map.at (group);
1058+
1059+ cached_inputs.emplace (group, 0.0 );
1060+
1061+ for (auto &[source, attrs] : group_details.items ())
1062+ {
1063+ if (source == " z" )
1064+ {
1065+ for (const auto &attr : attrs)
1066+ {
1067+ source_coeffs.emplace (
1068+ attr,
1069+ mfem::FunctionCoefficient ([](const mfem::Vector &x)
1070+ { return 1.0 ; },
1071+ [](const mfem::Vector &x,
1072+ const double Q_bar,
1073+ mfem::Vector &x_bar) {}));
1074+ auto &source_coeff = source_coeffs.at (attr);
1075+
1076+ current_coeff.addCoefficient (
1077+ attr,
1078+ std::make_unique<mfem::ProductCoefficient>(group_coeff,
1079+ source_coeff));
1080+ }
1081+ }
1082+ else if (source == " -z" )
1083+ {
1084+ for (const auto &attr : attrs)
1085+ {
1086+ // source_coeffs.emplace(attr, mfem::FunctionCoefficient(-1.0));
1087+ source_coeffs.emplace (
1088+ attr,
1089+ mfem::FunctionCoefficient ([](const mfem::Vector &)
1090+ { return -1.0 ; },
1091+ [](const mfem::Vector &x,
1092+ const double Q_bar,
1093+ mfem::Vector &x_bar) {}));
1094+ auto &source_coeff = source_coeffs.at (attr);
1095+
1096+ current_coeff.addCoefficient (
1097+ attr,
1098+ std::make_unique<mfem::ProductCoefficient>(group_coeff,
1099+ source_coeff));
1100+ }
1101+ }
1102+ else if (source == " box1" )
1103+ {
1104+ for (const auto &attr : attrs)
1105+ {
1106+ source_coeffs.emplace (attr,
1107+ mfem::FunctionCoefficient (
1108+ box1CurrentSource2D,
1109+ [&diff_stack](const mfem::Vector &x,
1110+ const double &J_bar,
1111+ mfem::Vector &x_bar) {
1112+ box1CurrentSource2DRevDiff (
1113+ diff_stack, x, J_bar, x_bar);
1114+ }));
1115+ auto &source_coeff = source_coeffs.at (attr);
1116+
1117+ current_coeff.addCoefficient (
1118+ attr,
1119+ std::make_unique<mfem::ProductCoefficient>(group_coeff,
1120+ source_coeff));
1121+ }
1122+ }
1123+ else if (source == " box2" )
1124+ {
1125+ for (const auto &attr : attrs)
1126+ {
1127+ source_coeffs.emplace (attr,
1128+ mfem::FunctionCoefficient (
1129+ box2CurrentSource2D,
1130+ [&diff_stack](const mfem::Vector &x,
1131+ const double &J_bar,
1132+ mfem::Vector &x_bar) {
1133+ box2CurrentSource2DRevDiff (
1134+ diff_stack, x, J_bar, x_bar);
1135+ }));
1136+ auto &source_coeff = source_coeffs.at (attr);
1137+
1138+ current_coeff.addCoefficient (
1139+ attr,
1140+ std::make_unique<mfem::ProductCoefficient>(group_coeff,
1141+ source_coeff));
1142+ }
1143+ }
1144+ }
1145+ }
1146+ }
1147+
1148+ } // namespace miso
0 commit comments