@@ -70,11 +70,13 @@ using namespace mfem;
7070double Conductivity (const Vector &x);
7171double Potential (const Vector &x);
7272int problem = 1 ;
73- double amplitude = -800.0 ;
74- double pseudo_time = 0.0 ;
75- int potential_well_switch = 0 ;
76- Vector bb_min, bb_max;
77- double h_min, h_max, k_min, k_max;
73+
74+ double amplitude = -800.0 ; // amplitude of coefficient fields
75+ double pseudo_time = 0.0 ; // potential parametetr
76+ Vector bb_min, bb_max; // bounding box
77+ double h_min, h_max, k_min, k_max; // mesh size
78+ double L = 1.0 ; // scaling factor
79+ int potential_well_switch = 0 ; // switch for separate training
7880
7981int main (int argc, char *argv[])
8082{
@@ -844,27 +846,36 @@ double Conductivity(const Vector &x)
844846 case 3 :
845847 case 4 :
846848 return 1.0 ;
849+ case 5 :
850+ case 6 :
851+ L = (bb_max[0 ] - bb_min[0 ]) / 18.0 ;
852+ return pow (L, 2.0 );
847853 }
848- return 0 .0 ;
854+ return 1 .0 ;
849855}
850856
851857double Potential (const Vector &x)
852858{
853859 Vector center (x.Size ());
854860 double rho = 0.0 ;
861+ double rho_bg = -5.0 ;
862+ double d_sq, radius_sq;
863+
855864 switch (problem)
856865 {
857866 case 1 :
858867 case 2 :
859868 return 0.0 ;
860869 case 3 :
870+ radius_sq = pow (4.0 * h_max, 2.0 );
861871 // center = (0.5 + t*h, 0.5)
862872 center (0 ) = 0.5 * (bb_min[0 ] + bb_max[0 ]) + pseudo_time * h_max;
863873 for (int i = 1 ; i < x.Size (); i++)
864874 center (i) = 0.5 * (bb_min[i] + bb_max[i]);
865- return amplitude * std::exp (- x.DistanceSquaredTo (center) / pow ( 4.0 * h_max,
866- 2.0 ));
875+ d_sq = x.DistanceSquaredTo (center);
876+ return amplitude * std::exp (-d_sq / ( 2 * radius_sq ));
867877 case 4 :
878+ radius_sq = pow (4.0 * h_max, 2.0 );
868879 if (potential_well_switch == 0 || potential_well_switch == 1 )
869880 {
870881 // add well with first center
@@ -874,8 +885,8 @@ double Potential(const Vector &x)
874885 (bb_min[1 ] + bb_max[1 ]);
875886 for (int i = 2 ; i < x.Size (); i++)
876887 center (i) = 0.25 * (bb_min[i] + bb_max[i]);
877- rho += amplitude * std::exp (- x.DistanceSquaredTo (center) / pow ( 4.0 * h_max,
878- 2.0 ));
888+ d_sq = x.DistanceSquaredTo (center);
889+ rho += amplitude * std::exp (-d_sq / ( 2 * radius_sq ));
879890 }
880891 if (potential_well_switch == 0 || potential_well_switch == 2 )
881892 {
@@ -886,8 +897,84 @@ double Potential(const Vector &x)
886897 (bb_min[1 ] + bb_max[1 ]);
887898 for (int i = 2 ; i < x.Size (); i++)
888899 center (i) = 0.75 * (bb_min[i] + bb_max[i]);
889- rho += amplitude * std::exp (-x.DistanceSquaredTo (center) / pow (4.0 * h_max,
890- 2.0 ));
900+ d_sq = x.DistanceSquaredTo (center);
901+ rho += amplitude * std::exp (-d_sq / (2 * radius_sq));
902+ }
903+ return rho;
904+ case 5 :
905+ L = (bb_max[0 ] - bb_min[0 ]) / 18.0 ;
906+ for (int i = 1 ; i < x.Size (); i++)
907+ center (i) = (bb_min[i] + bb_max[i]) / 2 ;
908+ if (potential_well_switch == 0 || potential_well_switch == 1 )
909+ {
910+ // add well with first center
911+ center (0 ) = (23 * bb_min[0 ] + 13 * bb_max[0 ]) / 36 -
912+ 0.5 * h_max * pseudo_time * (bb_min[0 ] + bb_max[0 ]);
913+ d_sq = x.DistanceSquaredTo (center);
914+ radius_sq = pow (0.28 * L, 2.0 );
915+ rho += -28.9 * std::exp (-d_sq / (2 * radius_sq));
916+ radius_sq = pow (1.08 * L, 2.0 );
917+ rho += -3.6 * std::exp (-d_sq / (2 * radius_sq));
918+ }
919+ if (potential_well_switch == 0 || potential_well_switch == 2 )
920+ {
921+ // add well with second center
922+ center (0 ) = (13 * bb_min[0 ] + 23 * bb_max[0 ]) / 36 +
923+ 0.5 * h_max * pseudo_time * (bb_min[0 ] + bb_max[0 ]);
924+ d_sq = x.DistanceSquaredTo (center);
925+ radius_sq = pow (0.28 * L, 2.0 );
926+ rho += -28.9 * std::exp (-d_sq / (2 * radius_sq));
927+ radius_sq = pow (1.08 * L, 2.0 );
928+ rho += -3.6 * std::exp (-d_sq / (2 * radius_sq));
929+ }
930+ return rho;
931+ case 6 :
932+ L = (bb_max[0 ] - bb_min[0 ]) / 18.0 ;
933+ for (int i = 1 ; i < x.Size (); i++)
934+ center (i) = (bb_min[i] + bb_max[i]) / 2 ;
935+
936+ // coefficients for H
937+ double rloc = 0.4 ;
938+ double c1 = -14.081155 ;
939+ double c2 = 9.626220 ;
940+ double c3 = -1.783616 ;
941+ double c4 = 0.085152 ;
942+ double zion = 3.0 ;
943+
944+ double alpha;
945+ if (potential_well_switch == 0 || potential_well_switch == 1 )
946+ {
947+ // add well with first center
948+ center (0 ) = (23 * bb_min[0 ] + 13 * bb_max[0 ]) / 36 - pseudo_time * h_max;
949+ d_sq = x.DistanceSquaredTo (center);
950+ alpha = d_sq / pow (L * rloc, 2.0 );
951+ rho += exp (-0.5 * alpha) * (c1 + c2 * alpha + c3 * alpha * alpha + c4 * alpha *
952+ alpha * alpha);
953+ if (d_sq > 1 .e -16 )
954+ {
955+ rho -= zion * erf (sqrt (d_sq) / (sqrt (2.0 ) * rloc)) / sqrt (d_sq);
956+ }
957+ else
958+ {
959+ rho -= zion * sqrt (2.0 ) / (sqrt (M_PI ) * rloc);
960+ }
961+ }
962+ if (potential_well_switch == 0 || potential_well_switch == 2 )
963+ {
964+ // add well with second center
965+ center (0 ) = (13 * bb_min[0 ] + 23 * bb_max[0 ]) / 36 + pseudo_time * h_max;
966+ d_sq = x.DistanceSquaredTo (center);
967+ alpha = d_sq / pow (L * rloc, 2.0 );
968+ rho += exp (-0.5 * alpha) * (c1 + c2 * alpha + c3 * alpha * alpha + c4 * alpha *
969+ alpha * alpha);
970+ if (d_sq > 1 .e -16 )
971+ {
972+ rho -= zion * erf (sqrt (d_sq) / (sqrt (2.0 ) * rloc)) / sqrt (d_sq);
973+ }
974+ else
975+ {
976+ rho -= zion * sqrt (2.0 ) / (sqrt (M_PI ) * rloc);
977+ }
891978 }
892979 return rho;
893980 }
0 commit comments