Skip to content

Commit

Permalink
[FEM] fix handling of vacuum permittivity
Browse files Browse the repository at this point in the history
- fix message that permittivity object was not handled
- set an expression, otherwise the user gets only "0.000" for the default of 8.8e-12
- use as unit the common "F/m" (this is also more user-friendly than "s^4*A^2 / (m^3*kg)")
- fix a ToDo
  • Loading branch information
donovaly committed Aug 14, 2022
1 parent e2636b2 commit 9db5dff
Show file tree
Hide file tree
Showing 5 changed files with 22 additions and 16 deletions.
4 changes: 4 additions & 0 deletions src/Base/UnitsSchemaInternal.cpp
Expand Up @@ -435,6 +435,10 @@ QString UnitsSchemaInternal::schemaTranslate(const Quantity &quant, double &fact
factor = 1e6;
}
}
else if (unit == Unit::VacuumPermittivity) {
unitString = QString::fromLatin1("F/m");
factor = 1;

This comment has been minimized.

Copy link
@wwmayer

wwmayer Aug 14, 2022

Contributor

factor=1 is wrong, it must be 1e-9
F/m = A² * s⁴ / (kg * m³). Since 1m = 1000mm and mm is the internal unit for length we get
F/m = A² * s⁴ / (kg * (1000 mm)³) = 1/1000³ * A² * s⁴ / (kg * mm³) = 10⁻⁹ * A² * s⁴ / (kg * mm³)

This comment has been minimized.

Copy link
@donovaly

donovaly Aug 14, 2022

Author Member

I first thought this too, but when I add a vacuum permittivity constraint (FEM WB and there menu Model -> Overwrite Constants
and set there "1.0" I must see "1.000 F/m" as result. And I get the desired result with factor 1:

FreeCAD_H8QV8ZdzOu

If I set the factor to 1e-9, I get this:

FreeCAD_cSsmWQJgmr

This comment has been minimized.

Copy link
@wwmayer

wwmayer Aug 14, 2022

Contributor

Then you have an error somewhere else. In writer.py you have this line permittivity = permittivity * 1e-9 which looks suspicious to me.

This comment has been minimized.

Copy link
@donovaly

donovaly Aug 14, 2022

Author Member

It seems so but I cannot find out where.
It seems that the Python subsystem sets it somewhere. Any idea to fix this is welcome.

This comment has been minimized.

Copy link
@wwmayer

wwmayer Aug 14, 2022

Contributor

Here is a Python snippet that shows that the factor for SI1 and SI2 which explicitly handles it is wrong while for other unit systems that use the generic way it is correct:

vacuum_permittivity = FreeCAD.Units.parseQuantity("1F/m")
vacuum_permittivity.Format = {"NumberFormat":"e"}

t = FreeCAD.Units.schemaTranslate(vacuum_permittivity, FreeCAD.Units.Scheme.Imperial1)
FreeCAD.Units.parseQuantity(t[0]).getValueAs("F/m").Value # must be 1.0

t = FreeCAD.Units.schemaTranslate(vacuum_permittivity, FreeCAD.Units.Scheme.Centimeters)
FreeCAD.Units.parseQuantity(t[0]).getValueAs("F/m").Value # must be 1.0

t = FreeCAD.Units.schemaTranslate(vacuum_permittivity, FreeCAD.Units.Scheme.MmMin)
FreeCAD.Units.parseQuantity(t[0]).getValueAs("F/m").Value # must be 1.0

t = FreeCAD.Units.schemaTranslate(vacuum_permittivity, FreeCAD.Units.Scheme.ImperialDecimal)
FreeCAD.Units.parseQuantity(t[0]).getValueAs("F/m").Value # must be 1.0


t = FreeCAD.Units.schemaTranslate(vacuum_permittivity, FreeCAD.Units.Scheme.SI1)
FreeCAD.Units.parseQuantity(t[0]).getValueAs("F/m").Value # must be 1.0 but is 1e-9

t = FreeCAD.Units.schemaTranslate(vacuum_permittivity, FreeCAD.Units.Scheme.SI2)
FreeCAD.Units.parseQuantity(t[0]).getValueAs("F/m").Value # must be 1.0 but is 1e-9

This comment has been minimized.

Copy link
@donovaly

donovaly Aug 14, 2022

Author Member

Thanks. But I am still stuck. Setting the factor to 1e-9 fixes this but then the set expression in the constraint is wrong.
Can it be that the expression parser misses info? If so where is this added?

This comment has been minimized.

Copy link
@donovaly

donovaly Aug 14, 2022

Author Member

You added now a Unit test. Hmm, better reverting the change I made here. I also don't want to invest too much time in a feature that almost nobody need (overwriting the permittivity of vacuum). The fix also works without the change to "Units*.cpp".
So I will revert now.

This comment has been minimized.

Copy link
@donovaly

donovaly Aug 14, 2022

Author Member

Done now. However, in writer.py I of course still need the factor 1e-9.
But as said, I don't think this is worth the effort. The feature works as it is at least.

This comment has been minimized.

Copy link
@wwmayer

wwmayer Aug 14, 2022

Contributor

So I will revert now.

There is no need to revert that change. Fixing the factor is sufficient.

This comment has been minimized.

Copy link
@donovaly

donovaly Aug 15, 2022

Author Member

OK, there is a general problem with the expression parser for Python objects. I opened a forum thread for this:
https://forum.freecadweb.org/viewtopic.php?f=10&t=71099

}
else if (unit == Unit::Frequency) {
if (UnitValue < 1e3) {
unitString = QString::fromLatin1("Hz");
Expand Down
4 changes: 4 additions & 0 deletions src/Base/UnitsSchemaMKS.cpp
Expand Up @@ -383,6 +383,10 @@ QString UnitsSchemaMKS::schemaTranslate(const Quantity &quant, double &factor, Q
factor = 1e6;
}
}
else if (unit == Unit::VacuumPermittivity) {
unitString = QString::fromLatin1("F/m");
factor = 1;

This comment has been minimized.

Copy link
@wwmayer

wwmayer Aug 14, 2022

Contributor

Same here

}
else if (unit == Unit::Work) {
if (UnitValue < 1.602176634e-10) {
unitString = QString::fromLatin1("eV");
Expand Down
5 changes: 3 additions & 2 deletions src/Mod/Fem/femobjects/constant_vacuumpermittivity.py
Expand Up @@ -45,6 +45,7 @@ def __init__(self, obj):
"App::PropertyVacuumPermittivity",
"VacuumPermittivity",
"Constants",
"Set the permittivity of vacuum"
"Overwrites default permittivity of vacuum"
)
obj.VacuumPermittivity = Units.Quantity(constants.vacuum_permittivity())
# we must set an expression so that the small value can actually be entered
obj.setExpression("VacuumPermittivity", "8.85419e-12")
23 changes: 10 additions & 13 deletions src/Mod/Fem/femsolver/elmer/writer.py
Expand Up @@ -198,13 +198,6 @@ def _handleConstants(self):
"BoltzmannConstant": constants.boltzmann_constant(),
}

def _setConstant(self, name, quantityStr):
# TODO without method directly use self.constsdef[name]
if name == "PermittivityOfVacuum":
theUnit = "s^4*A^2 / (m^3*kg)"
self.constsdef[name] = "{} {}".format(self._convert(quantityStr, theUnit), theUnit)
return True

def _writeMesh(self):
mesh = self._getSingleMember("Fem::FemMeshObject")
unvPath = os.path.join(self.directory, "mesh.unv")
Expand Down Expand Up @@ -300,15 +293,19 @@ def _handleRedifinedConstants(self):
"""
redefine constants in self.constsdef according constant redefine objects
"""
permittivity_objs = self._getMember("Fem::ConstantVacuumPermittivity")
if len(permittivity_objs) == 1:
Console.PrintLog("Constand permittivity overwriting.\n")
self._setConstant("PermittivityOfVacuum", permittivity_objs[0].VacuumPermittivity)
elif len(permittivity_objs) > 1:
objs = self._getMember("Fem::ConstantVacuumPermittivity")
if len(objs) == 1:
permittivity = float(objs[0].VacuumPermittivity.getValueAs("F/m"))
# since the base unit of FC is in mm, we must scale it to get plain SI
permittivity = permittivity * 1e-9
Console.PrintLog("Overwriting vacuum permittivity with: {}\n".format(permittivity))
self.constsdef["PermittivityOfVacuum"] = "{} {}".format(permittivity, "F/m")
self._handled(objs[0])
elif len(objs) > 1:
Console.PrintError(
"More than one permittivity constant overwriting objects ({} objs). "
"The permittivity constant overwriting is ignored.\n"
.format(len(permittivity_objs))
.format(len(objs))
)

def _handleSimulation(self):
Expand Down
2 changes: 1 addition & 1 deletion src/Mod/Fem/femtools/constants.py
Expand Up @@ -45,7 +45,7 @@ def stefan_boltzmann():
def vacuum_permittivity():
# https://forum.freecadweb.org/viewtopic.php?f=18&p=400959#p400959
# https://en.wikipedia.org/wiki/Permittivity#Vacuum_permittivity
return "8.85419e-12 s^4*A^2 / (m^3*kg)"
return "8.85419e-12 F/m"


def boltzmann_constant():
Expand Down

0 comments on commit 9db5dff

Please sign in to comment.