Commit 588fb07c authored by Christophe Geuzaine's avatar Christophe Geuzaine

rework interactive templates - now cleanly seperating interactive/non-interactive parts

parent 85790276
Pipeline #1447 passed with stage
in 10 minutes 16 seconds
......@@ -5,7 +5,7 @@
*/
Include "magnet_data.pro";
Include "../templates/MaterialDatabase.pro";
Include "../templates/Lib_Materials.pro";
Group {
// AIR, AIR_INF, etc. are variables defined in core.txt, and correspond to the
......@@ -15,11 +15,8 @@ Group {
Core = Region[ CORE ];
AirGap = Region[ AIR_GAP ];
Magnet = Region[ MAGNET ];
// These are the generic group names that are used in "Magnetostatics.pro"
Domain_S = Region[ {} ] ;
Domain_Inf = Region[ AirInf ] ;
Domain_M = Region[ Magnet ] ;
Dirichlet_a_0 = Region[ LINE_INF ] ;
Dirichlet_phi_0 = Region[ {LINE_X, LINE_INF} ] ;
// This defines a constant ('Flag_NL') with a default value (0), and a way to
// change it from outside getdp with ONELAB, using the given parameter name
......@@ -28,19 +25,19 @@ Group {
Flag_NL = { 0, Choices{0,1}, Name "Parameters/Materials/1Nonlinear BH-curve"}
];
Domain_NL = Region[ {} ] ;
// These are the generic group names that are used in "Magnetostatics.pro"
Vol_Inf_Mag = Region[ AirInf ] ;
Vol_M_Mag = Region[ Magnet ] ;
Vol_L_Mag = Region[ {Air, AirInf, AirGap} ] ;
Vol_NL_Mag = Region[ {} ] ;
If(Flag_NL)
Domain_NL += Region[ {Core} ] ;
Vol_NL_Mag += Region[ {Core} ] ;
Else
Vol_L_Mag += Region[ {Core} ] ;
EndIf
Domain_Mag = Region[ {Air, AirInf, Core, AirGap} ] ;
Dirichlet_a_0 = Region[ LINE_INF ] ;
Dirichlet_phi_0 = Region[ {LINE_X, LINE_INF} ] ;
}
Function {
mu0 = 4.e-7 * Pi ;
// Another parameter that can be changed interactively; but is only visible
// when it makes sense (if we don't perform a nonlinear analysis)
DefineConstant[ murCore = {200., Min 1, Max 1000, Step 10, Visible !Flag_NL,
......@@ -80,24 +77,24 @@ Constraint {
}
modelPath = CurrentDirectory;
Include "../templates/Magnetostatics.pro"
Include "../templates/Lib_MagSta_a_phi.pro"
eps = 1.e-5;
PostOperation {
{ Name phi ; NameOfPostProcessing MagSta_phi;
Operation {
Print[ phi, OnElementsOf Domain, File "phi.pos" ] ;
Print[ hc, OnElementsOf Domain, File "hc.pos" ] ;
Print[ b, OnElementsOf Domain, File "b_phi.pos" ] ;
Print[ phi, OnElementsOf Vol_Mag, File "phi.pos" ] ;
Print[ hc, OnElementsOf Vol_Mag, File "hc.pos" ] ;
Print[ b, OnElementsOf Vol_Mag, File "b_phi.pos" ] ;
Print[ b, OnLine {{-0.07,eps,0}{0.09,eps,0}} {500}, File "b_phi.txt", Format Table ] ;
}
}
{ Name a ; NameOfPostProcessing MagSta_a;
Operation {
Print[ az, OnElementsOf Domain, File "az.pos"] ;
Print[ b, OnElementsOf Domain, File "b_a.pos" ] ;
Print[ h, OnElementsOf Domain, File "h_a.pos" ] ;
Print[ az, OnElementsOf Vol_Mag, File "az.pos"] ;
Print[ b, OnElementsOf Vol_Mag, File "b_a.pos" ] ;
Print[ h, OnElementsOf Vol_Mag, File "h_a.pos" ] ;
Print[ b, OnLine {{-0.07,eps,0}{0.09,eps,0}} {500}, File "b_a.txt" , Format Table ] ;
}
}
......
This diff is collapsed.
// Lib_EleSta_v.pro
//
// Template library for electrostatics using a scalar electric potential (v)
// formulation, with floating potentials
DefineConstant[
modelPath = GetString["Gmsh/Model absolute path"],
resPath = StrCat[modelPath, "res/"],
eps0 = 8.854187818e-12,
interactive = 0
];
Group {
DefineGroup[
Vol_Ele, // dielectric domain
Vol_Q_Ele, // domain with imposed volume charge density
Vol_Inf_Ele, // infinite region
Sur_Neu_Ele, // Non-homogeneous Neumann boundary conditions (n.d)
Sur_C_Ele // boundary of conductors
];
}
Function{
DefineFunction[
epsr, // relative permittivity
rho, // charge density in Vol_Q_Ele
dn // normal displacement on Sur_Neu_Ele
];
}
CallTest(interactive) Lib_EleSta_v_interactive;
DefineConstant[
Val_Rint = {1, Visible NbrRegions[Vol_Inf_Ele],
Name "Parameters/Geometry/1Internal shell radius"},
Val_Rext = {2, Visible NbrRegions[Vol_Inf_Ele],
Name "Parameters/Geometry/2External shell radius"},
Val_Cx = 0,
Val_Cy = 0,
Val_Cz = 0
];
Jacobian {
{ Name Vol;
Case {
{ Region Vol_Inf_Ele;
Jacobian VolSphShell{Val_Rint, Val_Rext, Val_Cx, Val_Cy, Val_Cz}; }
{ Region All; Jacobian Vol; }
}
}
{ Name Sur;
Case {
{ Region All; Jacobian Sur; }
}
}
}
Integration {
{ Name GradGrad;
Case {
{ Type Gauss;
Case {
{ GeoElement Point; NumberOfPoints 1; }
{ GeoElement Line; NumberOfPoints 3; }
{ GeoElement Triangle; NumberOfPoints 3; }
{ GeoElement Quadrangle; NumberOfPoints 4; }
{ GeoElement Tetrahedron; NumberOfPoints 4; }
{ GeoElement Hexahedron; NumberOfPoints 6; }
{ GeoElement Prism; NumberOfPoints 9; }
{ GeoElement Pyramid; NumberOfPoints 8; }
}
}
}
}
}
FunctionSpace {
{ Name Hgrad_vf_Ele; Type Form0;
BasisFunction {
// v = v s + v s
// n n c,k c,k
{ Name sn; NameOfCoef vn; Function BF_Node;
Support Region[{Vol_Ele, Sur_Neu_Ele}]; Entity NodesOf[ All, Not Sur_C_Ele ]; }
{ Name sck; NameOfCoef vck; Function BF_GroupOfNodes;
Support Vol_Ele; Entity GroupsOfNodesOf[ Sur_C_Ele ]; }
}
SubSpace { // only for a PostOperation
{ Name vf; NameOfBasisFunction sck; }
}
GlobalQuantity {
{ Name GlobalElectricPotential; Type AliasOf; NameOfCoef vck; }
{ Name GlobalElectricCharge; Type AssociatedWith; NameOfCoef vck; }
}
Constraint {
{ NameOfCoef vn;
EntityType NodesOf; NameOfConstraint ElectricScalarPotential; }
{ NameOfCoef GlobalElectricPotential;
EntityType GroupsOfNodesOf; NameOfConstraint GlobalElectricPotential; }
{ NameOfCoef GlobalElectricCharge;
EntityType GroupsOfNodesOf; NameOfConstraint GlobalElectricCharge; }
}
}
}
Formulation {
{ Name Electrostatics_vf; Type FemEquation;
Quantity {
{ Name v; Type Local; NameOfSpace Hgrad_vf_Ele; }
{ Name Q; Type Global;
NameOfSpace Hgrad_vf_Ele [GlobalElectricCharge]; }
{ Name V; Type Global;
NameOfSpace Hgrad_vf_Ele [GlobalElectricPotential]; }
// only for a PostOperation
{ Name vf; Type Local; NameOfSpace Hgrad_vf_Ele [vf]; }
}
Equation {
Integral { [ epsr[] * eps0 * Dof{Grad v} , {Grad v} ];
In Vol_Ele; Jacobian Vol; Integration GradGrad; }
Integral { [ - rho[], {v} ];
In Vol_Q_Ele; Jacobian Vol; Integration GradGrad; }
Integral { [ dn[] , {v} ];
In Sur_Neu_Ele; Jacobian Sur; Integration GradGrad; }
GlobalTerm { [ - Dof{Q}, {V} ]; In Sur_C_Ele; }
}
}
}
Resolution {
{ Name EleSta_v;
System {
{ Name Sys_Ele; NameOfFormulation Electrostatics_vf; }
}
Operation {
Generate[Sys_Ele]; Solve[Sys_Ele]; SaveSolution[Sys_Ele];
}
}
}
PostProcessing {
{ Name EleSta_v; NameOfFormulation Electrostatics_vf;
PostQuantity {
{ Name v; Value {
Term { [ {v} ]; In Vol_Ele; Jacobian Vol; }
}
}
{ Name e; Value {
Term { [ -{d v} ]; In Vol_Ele; Jacobian Vol; }
}
}
{ Name d; Value {
Term { [ -eps0*epsr[] * {d v} ]; In Vol_Ele; Jacobian Vol; }
}
}
{ Name Q; Value {
Term { [ {Q} ]; In Sur_C_Ele; }
}
}
{ Name V; Value {
Term { [ {V} ]; In Sur_C_Ele; }
}
}
{ Name C; Value {
Term { [ {Q}/{V} ]; In Sur_C_Ele; }
}
}
{ Name vf; Value {
Term { [ {vf} ]; In Vol_Ele; Jacobian Vol; }
}
}
{ Name force; Value {
Integral { [ eps0*epsr[] / 2. * VirtualWork[{Grad v}] ];
//In Vol_Ele; // restrict support to speed-up search
In ElementsOf[Vol_Ele, OnOneSideOf Sur_C_Ele];
Jacobian Vol; Integration GradGrad;
}
}
}
{ Name energy; Value {
Integral { [ eps0*epsr[] / 2. * SquNorm[{Grad v}] ];
In Vol_Ele; Jacobian Vol; Integration GradGrad;
}
}
}
}
}
}
PostOperation {
{ Name EleSta_v; NameOfPostProcessing EleSta_v;
Operation {
CreateDir[resPath];
Print[ e, OnElementsOf Vol_Ele, File StrCat[resPath, "EleSta_v_e.pos"] ];
Print[ v, OnElementsOf Vol_Ele, File StrCat[resPath, "EleSta_v_v.pos"] ];
If(NbrRegions[Sur_C_Ele])
Print[ Q, OnRegion Sur_C_Ele, File StrCat[resPath, "EleSta_v_q.txt"],
Format Table, SendToServer "}Output/Floating charge [C]" ];
Print[ V, OnRegion Sur_C_Ele, File StrCat[resPath, "EleSta_v_q.txt"],
Format Table, SendToServer "}Output/Floating potential [V]" ];
EndIf
}
}
}
// Lib_MagSta_a_phi.pro
//
// Template library for magnetostatics using a scalar (phi) or a vector (a)
// potential formulation
DefineConstant[
modelPath = GetString["Gmsh/Model absolute path"],
resPath = StrCat[modelPath, "res/"],
exportFile = StrCat[modelPath, "export.pro"],
mu0 = 4*Pi*1e-7,
modelDim = 2,
interactive = 0
];
Group {
DefineGroup[
Vol_M_Mag, // magnets
Vol_S0_Mag, // imposed current density
Vol_Inf_Mag, // infinite domains
Vol_NL_Mag, // nonlinear magnetic materials
Vol_L_Mag, // linear magnetic materials
Sur_Dir_Mag // Dirichlet boundary conditions
Sur_Neu_Mag // Non-homogeneous Neumann boundary conditions
];
}
Function{
DefineFunction[
mu, // magnetic permeability
nu, // magnetic reluctivity (= 1/nu)
hc, // coercive magnetic field (in magnets)
js, // source current density
dhdb_NL, dbdh_NL // nonlinear parts of the Jacobian
];
}
CallTest(interactive) Lib_MagSta_a_phi_interactive;
DefineConstant[
Val_Rint = {1, Visible NbrRegions[Vol_Inf_Mag],
Name "Parameters/Geometry/1Internal shell radius"},
Val_Rext = {2, Visible NbrRegions[Vol_Inf_Mag],
Name "Parameters/Geometry/2External shell radius"},
Val_Cx, Val_Cy, Val_Cz,
Nb_max_iter = {30, Visible NbrRegions[Vol_NL_Mag],
Name "Parameters/Nonlinear solver/Maximum number of iterations"},
relaxation_factor = 1,
stop_criterion = {1e-5, Visible NbrRegions[Vol_NL_Mag],
Name "Parameters/Nonlinear solver/Tolerance"}
];
Group{
Vol_Mag = Region[{Vol_L_Mag, Vol_NL_Mag, Vol_M_Mag, Vol_S0_Mag, Vol_Inf_Mag}];
}
Jacobian {
{ Name JVol;
Case {
{ Region Vol_Inf_Mag;
Jacobian VolSphShell{Val_Rint, Val_Rext, Val_Cx, Val_Cy, Val_Cz}; }
{ Region All; Jacobian Vol; }
}
}
}
Integration {
{ Name I1;
Case {
{ Type Gauss;
Case {
{ GeoElement Point; NumberOfPoints 1; }
{ GeoElement Line; NumberOfPoints 3; }
{ GeoElement Triangle; NumberOfPoints 3; }
{ GeoElement Quadrangle; NumberOfPoints 4; }
{ GeoElement Tetrahedron; NumberOfPoints 4; }
{ GeoElement Hexahedron; NumberOfPoints 6; }
{ GeoElement Prism; NumberOfPoints 9; }
{ GeoElement Pyramid; NumberOfPoints 8; }
}
}
}
}
}
Constraint {
{ Name GaugeCondition_a ; Type Assign ;
Case {
{ Region Vol_Mag ; SubRegion Sur_Dir_Mag ; Value 0. ; }
}
}
}
FunctionSpace {
{ Name Hgrad_phi; Type Form0;
BasisFunction {
{ Name sn; NameOfCoef phin; Function BF_Node;
Support Vol_Mag; Entity NodesOf[ All ]; }
}
Constraint {
{ NameOfCoef phin; EntityType NodesOf; NameOfConstraint phi; }
}
}
If(modelDim == 3)
{ Name Hcurl_a; Type Form1;
BasisFunction {
{ Name se; NameOfCoef ae; Function BF_Edge; Support Vol_Mag ;
Entity EdgesOf[ All ]; }
}
Constraint {
{ NameOfCoef ae; EntityType EdgesOf; NameOfConstraint a; }
{ NameOfCoef ae; EntityType EdgesOfTreeIn; EntitySubType StartingOn;
NameOfConstraint GaugeCondition_a ; }
}
}
Else
{ Name Hcurl_a; Type Form1P;
BasisFunction {
{ Name se; NameOfCoef ae; Function BF_PerpendicularEdge;
Support Vol_Mag; Entity NodesOf[ All ]; }
}
Constraint {
{ NameOfCoef ae; EntityType NodesOf; NameOfConstraint a; }
}
}
EndIf
}
Formulation {
{ Name MagSta_phi; Type FemEquation;
Quantity {
{ Name phi; Type Local; NameOfSpace Hgrad_phi; }
}
Equation {
Integral { [ - mu[-{d phi}] * Dof{d phi} , {d phi} ];
In Vol_Mag; Jacobian JVol; Integration I1; }
Integral { JacNL [ - dbdh_NL[-{d phi}] * Dof{d phi} , {d phi} ];
In Vol_NL_Mag; Jacobian JVol; Integration I1; }
Integral { [ - mu[] * hc[] , {d phi} ];
In Vol_M_Mag; Jacobian JVol; Integration I1; }
}
}
{ Name MagSta_a; Type FemEquation;
Quantity {
{ Name a; Type Local; NameOfSpace Hcurl_a; }
}
Equation {
Integral { [ nu[{d a}] * Dof{d a} , {d a} ];
In Vol_Mag; Jacobian JVol; Integration I1; }
Integral { JacNL [ dhdb_NL[{d a}] * Dof{d a} , {d a} ];
In Vol_NL_Mag; Jacobian JVol; Integration I1; }
Integral { [ hc[] , {d a} ];
In Vol_M_Mag; Jacobian JVol; Integration I1; }
Integral { [ -js[] , {a} ];
In Vol_S0_Mag; Jacobian JVol; Integration I1; }
}
}
}
Resolution {
{ Name MagSta_phi;
System {
{ Name A; NameOfFormulation MagSta_phi; }
}
Operation {
If(!NbrRegions[Vol_NL_Mag])
Generate[A]; Solve[A];
Else
IterativeLoop[Nb_max_iter, stop_criterion, relaxation_factor]{
GenerateJac[A]; SolveJac[A];
}
EndIf
SaveSolution[A];
}
}
{ Name MagSta_a;
System {
{ Name A; NameOfFormulation MagSta_a; }
}
Operation {
If(!NbrRegions[Vol_NL_Mag])
Generate[A]; Solve[A];
Else
IterativeLoop[Nb_max_iter, stop_criterion, relaxation_factor]{
GenerateJac[A]; SolveJac[A];
}
EndIf
SaveSolution[A];
}
}
}
PostProcessing {
{ Name MagSta_phi; NameOfFormulation MagSta_phi;
Quantity {
{ Name b; Value {
Term { [ - mu[-{d phi}] * {d phi} ]; In Vol_Mag; Jacobian JVol; }
Term { [ - mu[] * hc[] ]; In Vol_M_Mag; Jacobian JVol; }
}
}
{ Name h; Value {
Term { [ - {d phi} ]; In Vol_Mag; Jacobian JVol; }
}
}
{ Name hc; Value {
Term { [ hc[] ]; In Vol_M_Mag; Jacobian JVol; }
}
}
{ Name phi; Value {
Term { [ {phi} ]; In Vol_Mag; Jacobian JVol; }
}
}
}
}
{ Name MagSta_a; NameOfFormulation MagSta_a;
Quantity {
{ Name az; Value {
Local { [ CompZ[{a}] ]; In Vol_Mag; Jacobian JVol; }
}
}
{ Name b; Value {
Term { [ {d a} ]; In Vol_Mag; Jacobian JVol; }
}
}
{ Name a; Value {
Term { [ {a} ]; In Vol_Mag; Jacobian JVol; }
}
}
{ Name h; Value {
Term { [ nu[{d a}] * {d a} ]; In Vol_Mag; Jacobian JVol; }
Term { [ hc[] ]; In Vol_M_Mag; Jacobian JVol; }
}
}
{ Name hc; Value {
Term { [ hc[] ]; In Vol_M_Mag; Jacobian JVol; }
}
}
{ Name js; Value {
Term { [ js[] ]; In Vol_S0_Mag; Jacobian JVol; }
}
}
}
}
}
PostOperation {
{ Name MagSta_phi; NameOfPostProcessing MagSta_phi;
Operation {
CreateDir[resPath];
Print[ hc, OnElementsOf Vol_M_Mag, File StrCat[resPath, "MagSta_phi_hc.pos"] ];
Print[ phi, OnElementsOf Vol_Mag, File StrCat[resPath, "MagSta_phi_phi.pos"] ];
Print[ h, OnElementsOf Vol_Mag, File StrCat[resPath, "MagSta_phi_h.pos"] ];
Print[ b, OnElementsOf Vol_Mag, File StrCat[resPath, "MagSta_phi_b.pos"] ];
}
}
{ Name MagSta_a; NameOfPostProcessing MagSta_a;
Operation {
CreateDir[resPath];
Print[ hc, OnElementsOf Vol_M_Mag, File StrCat[resPath, "MagSta_a_hc.pos"] ];
Print[ js, OnElementsOf Vol_S0_Mag, File StrCat[resPath, "MagSta_a_js.pos"] ];
If(modelDim == 2)
Print[ az, OnElementsOf Vol_Mag, File StrCat[resPath, "MagSta_a_az.pos"] ];
EndIf
Print[ h, OnElementsOf Vol_Mag, File StrCat[resPath, "MagSta_a_h.pos"] ];
Print[ b, OnElementsOf Vol_Mag, File StrCat[resPath, "MagSta_a_b.pos"] ];
}
}
}
......@@ -81,7 +81,84 @@ Function{
// Create all the functions required by the formulations for each material
Include "MaterialMacros.pro";
Macro DefineMaterialFunctions
n = Str[_MaterialName_];
// --------------------------------------------------------------
// Linear magnetic materials
// --------------------------------------------------------------
If(Exists[StringToName[StrCat[n, "_mur"]]])
If(Exists[linearMagneticMaterials] && !StrFind[n, "UserMaterial"])
linearMagneticMaterials() += Str[n];
EndIf
EndIf
// --------------------------------------------------------------
// Nonlinear magnetic materials
// --------------------------------------------------------------
// create intermediate lists and functions for interpolation of point data
If(Exists[StringToName[StrCat[n, "_b_list"]]] &&
Exists[StringToName[StrCat[n, "_h_list"]]])
Parse[ StrCat[
n, "_b2_list() = ", n, "_b_list()^2;",
n, "_h2_list() = ", n, "_h_list()^2;",
n, "_nu_list() = ", n, "_h_list() / ", n, "_b_list();",
n, "_nu_list(0) = ", n, "_nu_list(1);",
n, "_mu_list() = ", n, "_b_list() / ", n, "_h_list();",
n, "_mu_list(0) = ", n, "_mu_list(1);",
n, "_nu_b2_list() = ListAlt[", n, "_b2_list(),", n, "_nu_list()];",
n, "_mu_h2_list() = ListAlt[", n, "_h2_list(),", n, "_mu_list()];",
n, "_nu[] = InterpolationLinear[SquNorm[$1]]{", n, "_nu_b2_list()};",
n, "_dnudb2[] = dInterpolationLinear[SquNorm[$1]]{", n, "_nu_b2_list()};",
n, "_mu[] = InterpolationLinear[SquNorm[$1]]{", n, "_mu_h2_list()};",
n, "_dmudh2[] = dInterpolationLinear[SquNorm[$1]]{", n, "_mu_h2_list()};"
] ];
EndIf
// create h[], dhdb[], dhdb_NL[], b[], dbdh[] and dbdh_NL[] functions
If(Exists[StringToName[StrCat[n, "_nu"]][]] &&
Exists[StringToName[StrCat[n, "_dnudb2"]][]] &&
Exists[StringToName[StrCat[n, "_mu"]][]] &&
Exists[StringToName[StrCat[n, "_dmudh2"]][]])
Parse[ StrCat[
n, "_h[] = ", n, "_nu[$1] * $1;",
n, "_dhdb[] = TensorDiag[1,1,1] * ", n, "_nu[$1#1] + 2 * ", n,
"_dnudb2[#1] * SquDyadicProduct[#1];",
n, "_dhdb_NL[] = 2 * ", n, "_dnudb2[$1#1] * SquDyadicProduct[#1];",
n, "_b[] = ", n, "_mu[$1] * $1;",
n, "_dbdh[] = TensorDiag[1,1,1] * ", n, "_mu[$1#1] + 2 * ", n,
"_dmudh2[#1] * SquDyadicProduct[#1];",
n, "_dbdh_NL[] = 2 * ", n, "_dmudh2[$1#1] * SquDyadicProduct[#1];"
] ];
If(Exists[nonlinearMagneticMaterials] && !StrFind[n, "UserMaterial"])
nonlinearMagneticMaterials() += Str[n];
EndIf
EndIf
// --------------------------------------------------------------
// Permanent magnets
// --------------------------------------------------------------
If(Exists[StringToName[StrCat[n, "_hc"]]])
If(Exists[permanentMagnetMaterials] && !StrFind[n, "UserMaterial"])
permanentMagnetMaterials() += Str[n];
EndIf
EndIf
// --------------------------------------------------------------
// Linear dielectric materials
// --------------------------------------------------------------
If(Exists[StringToName[StrCat[n, "_epsilonr"]]])
If(Exists[linearDielectricMaterials] && !StrFind[n, "UserMaterial"])
linearDielectricMaterials() += Str[n];
EndIf
EndIf
Return
Function{
linearMagneticMaterials() = Str["Constant", "Function"];
......
This diff is collapsed.
Macro DefineMaterialFunctions
n = Str[_MaterialName_];
// --------------------------------------------------------------
// Linear magnetic materials
// --------------------------------------------------------------
If(Exists[StringToName[StrCat[n, "_mur"]]])
If(Exists[linearMagneticMaterials] && !StrFind[n, "UserMaterial"])
linearMagneticMaterials() += Str[n];
EndIf
EndIf
// --------------------------------------------------------------
// Nonlinear magnetic materials
// --------------------------------------------------------------
// create intermediate lists and functions for interpolation of point data
If(Exists[StringToName[StrCat[n, "_b_list"]]] &&
Exists[StringToName[StrCat[n, "_h_list"]]])
Parse[ StrCat[
n, "_b2_list() = ", n, "_b_list()^2;",
n, "_h2_list() = ", n, "_h_list()^2;",
n, "_nu_list() = ", n, "_h_list() / ", n, "_b_list();",
n, "_nu_list(0) = ", n, "_nu_list(1);",
n, "_mu_list() = ", n, "_b_list() / ", n, "_h_list();",
n, "_mu_list(0) = ", n, "_mu_list(1);",
n, "_nu_b2_list() = ListAlt[", n, "_b2_list(),", n, "_nu_list()];",
n, "_mu_h2_list() = ListAlt[", n, "_h2_list(),", n, "_mu_list()];",
n, "_nu[] = InterpolationLinear[SquNorm[$1]]{", n, "_nu_b2_list()};",
n, "_dnudb2[] = dInterpolationLinear[SquNorm[$1]]{", n, "_nu_b2_list()};",
n, "_mu[] = InterpolationLinear[SquNorm[$1]]{", n, "_mu_h2_list()};",
n, "_dmudh2[] = dInterpolationLinear[SquNorm[$1]]{", n, "_mu_h2_list()};"
] ];
EndIf
// create h[], dhdb[], dhdb_NL[], b[], dbdh[] and dbdh_NL[] functions
If(Exists[StringToName[StrCat[n, "_nu"]][]] &&
Exists[StringToName[StrCat[n, "_dnudb2"]][]] &&
Exists[StringToName[StrCat[n, "_mu"]][]] &&
Exists[StringToName[StrCat[n, "_dmudh2"]][]])
Parse[ StrCat[
n, "_h[] = ", n, "_nu[$1] * $1;",
n, "_dhdb[] = TensorDiag[1,1,1] * ", n, "_nu[$1#1] + 2 * ", n,
"_dnudb2[#1] * SquDyadicProduct[#1];",
n, "_dhdb_NL[] = 2 * ", n, "_dnudb2[$1#1] * SquDyadicProduct[#1];",
n, "_b[] = ", n, "_mu[$1] * $1;",
n, "_dbdh[] = TensorDiag[1,1,1] * ", n, "_mu[$1#1] + 2 * ", n,
"_dmudh2[#1] * SquDyadicProduct[#1];",
n, "_dbdh_NL[] = 2 * ", n, "_dmudh2[$1#1] * SquDyadicProduct[#1];"
] ];
If(Exists[nonlinearMagneticMaterials] && !StrFind[n, "UserMaterial"])
nonlinearMagneticMaterials() += Str[n];
EndIf
EndIf
// --------------------------------------------------------------
// Permanent magnets
// --------------------------------------------------------------
If(Exists[StringToName[StrCat[n, "_hc"]]])
If(Exists[permanentMagnetMaterials] && !StrFind[n, "UserMaterial"])
permanentMagnetMaterials() += Str[n];
EndIf
EndIf
// --------------------------------------------------------------
// Linear dielectric materials
// -----------