B2000++ System Tests
b2testrunner [1] manages the execution of the|b2k| test case suite. It scans the test case directory tree, launches the required B2000++ programs, and checks the results. Based on the required level of output, b2testrunner generates a test report.
The tests managed by b2testrunner can be divided into different categories:
Example and verification problems demonstrating and testing the capabilities of B2000++. Results are compared to solutions obtained from other sources (literature, other FE programs, analytical solutions).
Basic tests consisting of element tests, function tests etc.
All B2000++ users can access the test cases and add their own tests. The verification suite as well as the example cases are installed in <prefix>/share/b2000++/b2000pp_data and documented in the B2000++ Examples and B2000++ Verification documentations.
Try out one of the examples cases, such as the Scordelis-Lo roof example case.
Running Test Cases
Using the b2testrunner Program
b2testrunner executes all or selected test cases of the B2000++ test suite and it is launched from a terminal. Example:
b2testrunner .
The output produced by can be rather lengthy, so it might be useful to redirect the output to a file for later inspection. This can be done as follows:
b2testrunner . 2>&1 | tee out.txt
This writes the output to the terminal and to the file out.txt
.
The -j
option launches several test cases in parallel, this
feature being useful if the CPU supports several cores. Example:
b2testrunner -j 4 .
will launch 4 test cases in parallel. Another useful option is the
-t
option. It will save all files and databases of all test cases
involved under a common directory. Example:
b2testrunner -t toto $B2VERIFICATION/solid_mechanics/static
will save all test data of the solid mechanics tests under the
directory toto
. Each test case under toto
then
contains all files and databases of the test. Specifically, the
following files can be found:
view.py
visualizes the computed solution with the baspl++ post-processor. Note this script is not available for all tests.One single test can contain several MDL input files
*.mdl
. The file with name starting with two underscores (__
) is always the MDL input file that is actually used, with all parameter values defined.The file
b2ip++.out
contains the output of the B2000++ input processor. Any errors and warnings encountered during pre-processing are found here.The file
b2000++.out
contains the output of the B2000++ solver. Logging information, any errors, and any warnings encountered during the analysis are found here.The database
*.b2m
contains the FE model and the results. It can be viewed with the baspl++ viewer and inspected with the b2browser application or, on data manager level, with the b2mcbrowser b2mcbrowser application (requires knowledge about the database).
Test Failures
A test case can fail for several reasons. The most likely one is the introduction of a bug in the B2000++ Finite Element code (or in the test!).
Bugs can be introduced and fixed by source code users themselves in a
new branch to be committed. For debugging a test case from the B2000++
test suite, copy the input file(s) to a temporary directory and add
the parameters, as found in the corresponding Python test script
(__init__.py
, see :ref:b2test.scripts) to the input file. Use
then this input file for debugging purposes. When bugs are found and
fixed, please commit them in a new branch to the B2000++ GIT server when
necessary and notify SMR.
Creating New Test Cases
With the Python-based test module for B2000++, creating and executing of new tests has been simplified. Test comparisons can range from simple one-number comparisons (like the displacement of a node) to complex post-processing of data, like the computation of energies or integration of path-dependent variables.
Note
System tests should never generate files, such as images, in the
test source directories tests/system_tests
. If you want to
keep files, such as images, for documentation purposes, place them
in a subdirectory images
.
Writing the Input File
The input file for the test is a standard B2000++ MDL input file or
a Nastran bulk data deck file to be converted with
b2convert_from_nas
. A parametrised model can be used to test
different parameters, like increasing geometrical complexity
(e.g. skew or twisted elements) or different element types.
The Python Test Script
Each test case directory contains one or more input files, a Python
program controlling the test and comparing the results (called
__init__.py
) and, optionally, a documentation file
(description.rst
). Notice the compulsory naming convention for
the Python __init__.py
file.
The Python test script always has the following literal set-up (text between square brackets, [], indicates optional text or programs):
"""Test case title"""
import b2test
class test(b2test.TestCase):
def test_[name](self):
"""Specific test name"""
input_files = [ ... ]
self.b2ip(input=. ...)
self.b2000pp()
self.[comparison_function]()
Different test functions have to be specified for each change in input parameters.
Applications and Their Arguments
Applications can be launched indirectly through the submit
functions of the b2test.py
script. The most common method is
launching them directly as shown in the example above.
Converters
The Nastran BDF to MDL converter b2convert_from_nas
can be executed
as follows:
self.b2nas('inputfile.bdf', 'inputfile.mdl')
The B2000++ Input Processing Launcher
Th b2ip++ input processing application requires the name of the input file and optional parameters. These parameters have to be placed into a Python dictionary for parsing. This also allows for changes in the MDL file without modification of the test case function.
params = {
'etype': 'Q4.S.MITC.E4',
'imat': 1,
'iskew': 1,
'iwarp': 1
}
self.b2ip(params=params, input='inputfile.mdl')
The B2000++ Launcher
The b2000++
application is executed by means of the
TestCase.b2000pp()
method. The optional parameter adir
can be
used to specify analysis directives:
adir = {
'analysis': 'linear',
'gradients': 1,
}
self.b2000pp(adir=adir)
Testing Numerical Results
The actual values to be compared are test-case dependent. A test function should raise an exception if the expected condition has not been met by calling
raise self.failureException
This call is issued when required by a set of functions available in
b2test.py
. These functions should be used when writing test
functions.
Test for Failure Functions
The Python module b2test contains the following functions for data
extraction and comparison. New, common used functions, can be added to
b2test.py
. Only the most commonly-used functions are listed here.
The arguments are self-descriptive.
failUnlessNearEqual(value, reference_value, tol=None, diff=None, msg=None)
Fail if the two objects are unequal as determined by their difference rounded to the given tolerance. This function is used by the comparison functions below. When writing specific test functions with unique data comparison this function can be used for final value comparison.
failIfNearEqual(value, reference_value, tol=None, diff=None, msg=None)
Fail if the two objects are almost equal as determined by their difference rounded to the given tolerance. When writing specific test functions with unique data comparison this function can be used for final value comparison when failure is to be expected.
get_node_field_value(name, node, comp=None, branch=None, cycle=None, subcycle=None, case=None, mode=None, model=None, db=None)
Return a node field value.
compare_node_field(value, name, node, comp=None, branch=None, cycle=None, subcycle=None, case=None, mode=None, model=None, db=None, tol=None, diff=None)
Compare a node field value with a given value. A failure is reported if the error is larger than the given tolerance.
def get_ncycle(case, model=None, db=None)
Return the number of computational cycles. This is useful for nonlinear analyses.
get_desc_value(name, key, comp=1, branch=None, cycle=None, subcycle=None, case=None, mode=None, model=None, db=None)
Return a descriptor field value.
get_table_value(name, key, comp=1, branch=None, cycle=None, subcycle=None, case=None, mode=None, model=None, db=None)
Return a relational table field value.
get_gradient_value(comp, point, layer, element, branch=None, cycle=None, case=1, model='b2test' )
Return a value of the gradient database.
make_set_name(model, db, name, branch, cycle, subcycle, case, mode)
Return the Memcom set name from a B2000++ database entry name.
has_set(name, branch=None, cycle=None, subcycle=None, case=None, mode=None, model=None, db=None)
Check if the data base contains the specified test.
get_db_set(name, model=None, db=None)
Return the Memcom data set
name
from the B2000++ data base.
Documenting the Test Case
Documentation always tends to come last - or not at all. Each test
case directory can (and should!) contain a documentation file, called
description.rst
. When ready to be published, the file can be
included in the relevant b2verification rst file. Have a look at the
$B2EXAMPLES
or $B2VERIFICATION
directories.
The following sections can be included in the documentation:
Description
: Providing a description of the model and the aim of the testOptions
: Describing the different parameters to be passed, if applicableResults
: Describing the comparison values for comparison as well as the numerical results for the different parameters.
Other optional sections are:
Numerical model
: With, among others, the following possible sections:Geometry
Material properties
Boundary conditions`
Conclusion
Remarks
Images included in the test case documentation must be placed in a
sub-directory named images
in the test case directory. This way the
images are automatically included in the B2000++ distribution. As a
guideline, pixel-based images should be in PNG format and be around 1500
pixels wide.
The following conventions are recommended for processing with baspl++:
Output plot format png or svg.
Use a Scene width (1500 pixels).
Use step-texture mapping for scalar fields.
If possible, apply a light source.
When combining multiple images or displaying them next to one another, generate the images separately, combine them into one single file with a width of a multiple of 1200 pixels and use the scaling capabilities (interpolation method cubic!) of gimp to scale the image to a width of 600pt. This image is to be included in the documentation.
It is recommended to add the full original part images to the git repository as well.
When making vector graphics, preferably with inkscape, the following conventions are recommended:
Image width 12-15cm.
Text in sans or non-proportial font, 12 pt.
Drawings preferably in B/W or grey scale.
Examples
The B2000++ test environment allows for a flexible implementation of tests and result checking. Some examples of launching a test and checking the results are explained below. See also the test case directories.
Comparing to an Expected Value
In normal cases one would check one or more values, like the displacements of a predefined node to a reference value. This value can be analytical, predefined through a numerical simulation, or compared to a previous run.
The basic one-element tests compare the numerical results of different
element types with an analytical solution. As an example, we use
$B2VERIFICATION/basic/shell/case1/
. For the 4-node MITC
element, the (linear) tension test should give a solution close to the
analytical values. This is in line with the element theory. The input
file for this test case is parametrized, and the following parameters
must be specified to b2ip++
:
etype |
element type specification and specific options |
mattype |
1=isotropic, 2=laminate |
loadcase |
loading conditions (1, 2, 3, or 4) |
nnodes |
number of nodes per element (4, 8, or 9) |
maxdof |
max. nr. of dofs per node (5 or 6 for shell elements) |
The nnodes
and maxdof
parameters are used in the definition of
the essential boundary conditions in the input file: Since it is an
in-plane test, all out-of-plane and rotational degrees-of-freedom must
be locked. But the test works also for 2D elements, where maxdof
should be set to 2.
Comparing a Non-Linear Solution
The following example __init__.py
is the examples case
$B2EXAMPLES/buckling/cylinder_cutout
.
If a test case contains several tests, it is recommended to write a
single check()
function and call it from each test_xxx()
function. This eliminates unnecessary redundancy (see example below).
# -*- coding: utf-8 -*-
"""Clamped cylinder with cutout under uniform end shortening"""
Results:
B. 0. ALMROTH and A. M. C. HOLMES: 'BUCKLING OF SHELLS WITH
CUTOUTS, EXPERIMENT AND ANALYSIS', International Journal Solids and
Structures, Vol 8, pp 1057-1071, 1972
experimental values (lb) for hole cyl.: 2740 2540 2050
-> for quarter cylinder (lb): 685 635 512.5
Norman F. Knight, Jr. and Charles C. Rankin: 'STAGS Example Problems
Manual', March 2006, chapter 'Cylinder with Cutouts', page 10
0.3911*P_0 = 722.5 lb 4-node quadrilateral
0.3748*P_0 = 692.4
from Mesh 3 19x33 E480 page 10 (total page 90)
Test prepared by Stephan Kuenzli, August 2010
Updated by Silvio Merazzi, November 2010
Updated by Thomas Ludwig, December 2010
Adapted to python 3 and Simples by Silvio Merazzi, 2019, 2020, 2022
The comparison is made against a very fine mesh of Q4.S.MITC.E4, since
the STAGS reference solution (mesh-3) is too coarse. The Q8.S.MITC
and Q9.S.MITC meshes have the same number of elements (18x32) as the
Q4.S.MITC.E4. To reproduce results similar to those from STAGS, use 9x16
Q9.S.MITC elements.
"""
import b2test
import simples as si
# Define comparison curve values from STAGS
stags_dx = [0.00891496, 0.0137947, 0.0204575, 0.0290596, 0.0404457,
0.0551476, 0.0731026, 0.0914018]
stags_load = [0.086217, 0.104633, 0.119883, 0.137595, 0.162698,
0.205865, 0.277067, 0.365396]
class test(b2test.TestCase):
"""Clamped cylinder with cutout under uniform end shortening"""
level = b2test.TestCase.medium
input_files = ["cutout.mdl", "view.py"]
def check(self, eltype, ne1, ne2, tolx, toly):
"""The check function"""
assert ne1 % 3 == 0
assert ne2 % 4 == 0
# Run b2ip++
self.b2ip(input="cutout.mdl",
params={"eltype": eltype, "ne1": ne1, "ne2": ne2})
# Run B2000++ solver
self.b2000pp()
# Open model with Simples for pp
model = si.Model("b2test", 'or')
# Get epatch point p3
point = model.get_node_set("EPATCH-1-P")[2]
E = 1e7
t = 0.014
P0 = 0.25 * 1.2 * 3.14159 * E * t ** 2
lf = model.get_steps(case=1)
rforce = model.get_reaction_force_of_steps(case=1, scale=1.0 / P0)
dofy = model.get_dof_value_of_steps("displacements", point, 1,
case=1, system="nl")
model.close()
# Extract solutions only if stroke < 0.095
xvalues = []
yvalues = []
for x, y in zip(dofy, rforce):
if x < 0.095:
xvalues.append(x)
yvalues.append(y)
# Compare both curves. The function also creates the graph of
# the curve in file rdplot.svg (note: You will find it only if
# you run b2testrunner -t <dirname>)
status = si.util.compare_curve1(
10, xvalues, yvalues, stags_dx, stags_load, tolx, toly,
graph="rdplot.svg", axes_label_x="Radial displacement",
axes_label_y="Reaction force", pos=(0.2, 0.6))
# Report failure if curves diifer too much.
if not status[0]:
self.fail(f"""Curve differs: tolx={tolx}, Ux={status[1]}, tol={toly}""")
def test_q4mitc(self):
"""Clamped cylinder with cutout, Q4.S.MITC.E4"""
self.check("Q4.S.MITC.E4", 18, 32, 0.03, 0.07)
def test_q8mitc(self):
"""Clamped cylinder with cutout, Q8.S.MITC"""
self.check("Q8.S.MITC", 18, 32, 0.03, 0.07)
def test_q9mitc(self):
"""Clamped cylinder with cutout, Q9.S.MITC"""
self.check("Q9.S.MITC", 18, 32, 0.03, 0.07)
Run the test with
cd $B2EXAMPLES/buckling/cylinder_cutout
b2testrunnner -j 4 -t toto .
cylinder_cutout.py: test.test_q4mitc: ... Q4.S.MITC.E4 ... ok
cylinder_cutout.py: test.test_q9mitc: ... Q9.S.MITC ... ok
cylinder_cutout.py: test.test_q8mitc: ... Q8.S.MITC ... ok
The test directory toto/cylinder_cutout.test.test_q4mitc
then
contains, among others, the graph rdplot.svg
comparing the
computed curve vs the expected on:
cylinder_cutout test case: Load-reaction force curve.
and you could obtain the deformation plot by executing baspl++ in
the test directory toto/cylinder_cutout.test.test_q4mitc
(the
baspl++ script has been copied there by b2test):
cd toto/cylinder_cutout.test.test_q4mitc
baspl++ view.py

cylinder_cutout test case: Load-reaction force curve.
Expected Failures
Some test cases are known to fail. For instance, the formulation of
a particular element Q4.X
may not give a correct response in the
membrane test. In this case, the known_to_fail
attribute should be
added to the test method. The value of the attribute (here it is a
string) is of no importance to the test. This way, the test is marked as
one that will fail.
def test_q4_x_membrane(self):
"""1 element membrane test (x-dir) Q4.X"""
params = {
'etype': 'type Q4.X',
'mattype': 1,
'loadcase': 1,
'nnodes': 4,
'maxdof': 2,
}
self.b2ip(params=params)
self.b2000pp()
self.compare_node_field(
name='DISP',
branch=1,
case=1,
node=2,
comp=1,
value=self.delta_x,
tol=1.e-2)
self.test_q4_x_membrane.known_to_fail = 'Due to element formulation'
Like all applications, the b2ip++ and B2000++ applications return an exit status of 0 when they terminate successfully; otherwise, a non-zero exit status is returned. All functions in the b2test module that call external commands and raise an exception if a non-zero exit status is returned.
For instance, when a nonlinear test case does not converge within the specified number of load steps, the B2000++ applications will return a non-zero exit status, and the B2000++ function will raise an exception.
If this behavior is expected, then the argument exit_status
should
be specified:
def test_q4_x_nonlin(self):
"""1 element test (x-dir) Q4.X - nonlin"""
params = {
'etype': 'type Q4.X',
'mattype': 1,
'loadcase': 1,
'nnodes': 4,
'maxdof': 2,
}
self.b2ip(params=params)
# Raise an exception only if exit status is not 0
self.b2000pp(adir={'analysis':'nonlinear'}, exit_status=-1)
b2test Python Module
TestCase Class
TestCase
is the B2000++ system tests base
class. Instances of this class are single test cases. A test case will
lauch all testes specified as def test_xxx
method.
Unless otherwise specified, all methods of this class will raise an exception if an error occurs. This to ensure that tests pass correctly.
If B2000++ solvers (b2000++,
b2ip++) are launched by means of one of the
TestCase launcher methods, a reference to the associated MemCom
database handle can be obtained with the
b2test.TestCase.get_db()
method.
- class TestCase(methodName='runTest')
TestCase is the B2000++ system tests base class.
- submit(cmd, exit_status=0)
Submit a command to the shell.
- Parameters:
cmdstring (str) – Shell command string to be submitted.
exit_status (int) – Termination status to be specified if the shell submit command should fail but does not. If set to -1, an exception is produced if submit terminates normally but failure was expected. Any other value will compare the exist status with the return value of the submit command and produce an exception if they do not match.
- ossystem(cmd, fail=True)
Submit command to shell with os.system.
- Parameters:
cmd (str) – Command string.
fail (bool) – If set to True (default), this function will trigger an exception. I set to False, status is returned.
- Returns:
Status (if fail=False). 0 means ok, > 0 means failed.
- Return type:
bool
- Raise:
Exception if Fail=True and submitted shell command did fail.
- get_db(model=None, db=None, mode='rw')
Get MemCom database object. Without any parameters specified the function returns the current object.
- Parameters:
model (str) – B2000+ model database name (without .b2m suffix).
- get_db_set(name, model=None, db=None, mode='r')
Get a MemCom database set “name”.
- Returns:
A memcom.db reference to the dataset.
- get_set(model=None, db=None, name=None, branch=None, cycle=None, subcycle=None, case=None, mode=None, subcase=None)
Get a MemCom database set, given the components of a dataset ‘name’
- Returns:
A memcom.db reference to the dataset.
- make_set_name(name, branch, cycle, subcycle, case, mode, subcase)
Compose a B2000++ dataset
name.branch[.cycle[.subcycle[.case[.subcase|mode]]]]
- Returns:
String containing dataset name.
- failUnlessNearEqual(value, reference_value, tol=None, diff=None, msg=None)
Fail if the two objects are unequal as determined by their difference rounded to the given tolerance. Float version.
- Parameters:
value (float) – Value to be compared.
reference_value (float) – Reference value.
tol (float) – Tolerance (0.01).
diff (float) – Maximum difference.
- failIfNearEqual(value, reference_value, tol=None, diff=None, msg=None)
Fail if the two objects are almost equal as determined by their difference rounded to the given tolerance. Float version.
- Parameters:
value (float) – Value to be compared.
reference_value (float) – Reference value.
tol (float) – Tolerance (0.01).
diff (float) – Maximum difference.
- failed(msg=None)
Raise exception. :param str msg: Message to be printed.
- compare_curve1(u, xvalues, yvalues, xrefvalues, yrefvalues, tolx, toly, graph=None, axes_label_x=None, axes_label_y=None, graph_sx=160.0, graph_sy=120.0, pos='center')
Given a curve and a reference curve, both defined by points, the function compares the 2 curves. The function compares both curves at discrete stations and, based on a maximum x and y tolerance, decides if the curves match or not.
- Parameters:
u (array) – Array of floats defining evaluation stations.
xvalues (array) – Array of x values of curve.
xvalues – Array of y values of curve.
xrefvalues (array) – Array of x reference values of curve.
yrefvalues (array) – Array of y reference values of curve.
tolx (float) – Tolerance in x.
toly (float) – Tolerance in y.
graph (Graph) – If defined, generate a graph of the curves.
axes_label_x (str) – Graph x axis label.
axes_label_y (str) – Graph y axis label.
graph_sx (float) – Graph x size [mm].
graph_sy (float) – Graph y size [mm].
pos (str) – Graph legen position.
- Returns:
Atuple (ok, dx, dy), where ok is True/False, and dx and dy are the max.difference to the reference curve.
- has_set(name, branch=None, cycle=None, subcycle=None, case=None, mode=None, subcase=None, model=None, db=None)
Check if a dataset on the database exists.
- Returns:
True or False.
- get_node_field_value(name, node, comp=None, branch=None, cycle=None, subcycle=None, case=None, mode=None, subcase=None, model=None, db=None, internal_node=True)
Return a node (DOF) field value.
- Parameters:
node (int) – Node identifier (internal by default, starting at 0).
comp (int) – Component (or column). Components start at 1.
internal_node (bool) – True means that node identifier is external. False means that node identifier is internal (default).
- compare_node_field(value, name, node, comp=None, branch=None, cycle=None, subcycle=None, case=None, mode=None, model=None, db=None, tol=None, diff=None, internal_node=True)
Compare a node field value to a reference value.
- Parameters:
fvalue (float) – Reference value.
node (int) – Node identifier (internal by default, starting at 0).
comp (int) – Component (or column). Components start at 1. :param float tol: Tolerance (0.01).
diff (float) – Maximum difference.
internal_node (bool) – True means that node identifier is external. False means that node identifier is internal (default).
- get_ncycle(case=1, model=None, db=None)
Returns the number of cycles (steps) of a nonliear analysis.
- Raise:
Exception.
- get_desc_value(name, key, comp=1, branch=None, cycle=None, subcycle=None, case=None, mode=None, subcase=None, model=None, db=None)
Return a single value of a key of a descriptor to a dataset
name.branch.cycle.subcycle.case.subcase|mode
:- Parameters:
key (str) – Dictionary key.
comp (int) – Component index of value array. Starts at 1!
- compare_desc(value, name, key, comp=1, branch=None, cycle=None, subcycle=None, case=None, subcase=None, mode=None, model=None, db=None, tol=None, diff=None)
Compare a given value with a value of a dataset descriptor of a datsaset
name.branch.cycle.subcycle.case.subcase|mode
.- Parameters:
value (float) – Value to be compared to descriptor value.
key (str) – Dictionary key.
comp (int) – Component index of value array. Starts at 1!
- get_table_value(name, key, comp=1, branch=None, cycle=None, subcycle=None, case=None, mode=None, subcase=None, model=None, db=None)
Return a single value of a relational table
name.branch.cycle.subcycle.case.subcase|mode
:- Parameters:
key (str) – Dictionary key.
comp (int) – Component index of value array. Starts at 1!
- compare_table_value(value, name, key, comp=1, branch=None, cycle=None, subcycle=None, case=None, mode=None, model=None, db=None, tol=None, diff=None)
- Compare a value to the value of the key of a relational table dataset
name.branch.cycle.subcycle.case.subcase|mode
:
- Parameters:
key (str) – Dictionary key.
comp (int) – Component index of value array. Starts at 1!
tol (float) – Tolerance (0.01).
diff (float) – Maximum difference.
- get_sampling_point_field_value(element, layer=None, point=None, comp=None, name=None, branch=None, cycle=None, subcycle=None, case=None, mode=None, subcase=None, model=None, db=None)
Get a sampling point field value of a dataset
name.branch.cycle.subcycle.case.subcase|mode
: :param int element: Element identifier (external). :param int point: Integration point number (starts at 1). :param int comp: Component number to be extracted (starts at 1).
- get_gradient_value(element, point=None, layer=None, comp=None, name='STRS', branch=None, cycle=None, subcycle=None, case=None, mode=None, subcase=None, schema=None, model='b2test', db=None)
Return a gradient value. Same as get_sampling_point_field_value.
- compare_gradient(value, element, point=None, schema=None, layer=None, comp=None, name='STRS', branch=None, cycle=None, subcycle=None, case=1, mode=None, model='b2test', db=None, tol=None, diff=None)
Compare a gradient value of an internal element id with a given value. Alternatively, a list of gradient components, a list of values, and a list of differences may be specified.
- b2nas(nas_file, mdl_file)
Launches b2nas with arguments.
- b2ip(**args)
Launches b2ip++ with arguments.
- b2000pp(opendb=None, output=None, exit_status=0, adir={}, log=[], **args)
Launch B2000++ solver. :param str opendb: Open database “opendb” if specified
- Parameters:
output – Write output to filename “output”. Default is b2000++.out”
exit_status (int) – Termination status to be specified if the shell submit command should fail but does not. If set to -1, an exception is produced if submit terminates normally but failure was expected. Any other value will compare the exist status with the return value of the submit command and produce an exception if they do not match.
adir (dict) – Optional directives to solver.
log (list) – List of logging directive strings.
- b2heat_grad(**args)
Run linear analysis and compute gradients.