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.

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 test

  • Options: Describing the different parameters to be passed, if applicable

  • Results: 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:

_images/cylinder-rdplot.svg

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
_images/cylinder-disp.png

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.