Showing preview only (2,735K chars total). Download the full file or copy to clipboard to get everything.
Repository: Morpho-lang/morpho
Branch: main
Commit: b9f31986ebfa
Files: 1216
Total size: 2.4 MB
Directory structure:
gitextract_ml0t_fts/
├── .gitattributes
├── .github/
│ ├── ISSUE_TEMPLATE/
│ │ └── bug_report.md
│ └── workflows/
│ ├── build.yml
│ ├── buildandtest.yml
│ ├── buildandtestmultithreaded.yml
│ ├── codeql.yml
│ ├── examples.yml
│ └── nonanboxing.yml
├── .gitignore
├── .readthedocs.yml
├── CMakeLists.txt
├── CODE_OF_CONDUCT.md
├── CONTRIBUTING.md
├── LICENSE
├── README.md
├── examples/
│ ├── catenoid/
│ │ └── catenoid.morpho
│ ├── cholesteric/
│ │ └── cholesteric.morpho
│ ├── cube/
│ │ └── cube.morpho
│ ├── delaunay/
│ │ └── delaunay.morpho
│ ├── dla/
│ │ └── dla.morpho
│ ├── electrostatics/
│ │ └── electrostatics.morpho
│ ├── elementtypes/
│ │ ├── README.md
│ │ ├── electrostaticsCG2.morpho
│ │ └── qtensorCG2.morpho
│ ├── examples.py
│ ├── implicitmesh/
│ │ ├── ellipsoid.morpho
│ │ ├── threesurface.morpho
│ │ └── torus.morpho
│ ├── meshgen/
│ │ ├── disk.morpho
│ │ ├── ellipse.morpho
│ │ ├── ellipsoidsection.morpho
│ │ ├── halfdisk.morpho
│ │ ├── overlappingdisks.morpho
│ │ ├── sphere.morpho
│ │ ├── square.morpho
│ │ ├── superellipse.morpho
│ │ ├── superellipsoid.morpho
│ │ └── weighted.morpho
│ ├── meshslice/
│ │ ├── sphere.mesh
│ │ └── testmeshslice.morpho
│ ├── plot/
│ │ ├── plotfield.morpho
│ │ ├── plotmeshlabels.morpho
│ │ ├── plotselection.morpho
│ │ └── scalebar.morpho
│ ├── povray/
│ │ ├── testCamera.morpho
│ │ ├── testpovray.morpho
│ │ ├── testpovraytext.morpho
│ │ ├── testpovraytransmitfilter.morpho
│ │ └── text.morpho
│ ├── qtensor/
│ │ ├── dense_disk.mesh
│ │ ├── qtensor.morpho
│ │ ├── src.lyx
│ │ └── src.tex
│ ├── tactoid/
│ │ ├── disk.mesh
│ │ ├── tactoid.morpho
│ │ └── tactoid2dmesh.morpho
│ ├── thomson/
│ │ └── thomson.morpho
│ ├── tutorial/
│ │ ├── disk.mesh
│ │ ├── tutorial.morpho
│ │ └── tutorial2.morpho
│ └── wrap/
│ └── wrap.morpho
├── help/
│ ├── Makefile
│ ├── array.md
│ ├── builtin.md
│ ├── classes.md
│ ├── color.md
│ ├── complex.md
│ ├── conf.py
│ ├── constants.md
│ ├── controlflow.md
│ ├── delaunay.md
│ ├── dictionary.md
│ ├── errors.md
│ ├── field.md
│ ├── file.md
│ ├── functionals.md
│ ├── functions.md
│ ├── graphics.md
│ ├── help.md
│ ├── implicitmesh.md
│ ├── index.rst
│ ├── json.md
│ ├── kdtree.md
│ ├── list.md
│ ├── make.bat
│ ├── matrix.md
│ ├── mesh.md
│ ├── meshgen.md
│ ├── meshslice.md
│ ├── meshtools.md
│ ├── modules.md
│ ├── optimize.md
│ ├── plot.md
│ ├── povray.md
│ ├── range.md
│ ├── requirements.txt
│ ├── selection.md
│ ├── sparse.md
│ ├── string.md
│ ├── syntax.md
│ ├── system.md
│ ├── tuple.md
│ ├── values.md
│ ├── variables.md
│ └── vtk.md
├── modules/
│ ├── color.morpho
│ ├── constants.morpho
│ ├── delaunay.morpho
│ ├── functionals.morpho
│ ├── graphics.morpho
│ ├── histogram.morpho
│ ├── implicitmesh.morpho
│ ├── kdtree.morpho
│ ├── meshgen.morpho
│ ├── meshslice.morpho
│ ├── meshtools.morpho
│ ├── optimize.morpho
│ ├── parser.morpho
│ ├── plot.morpho
│ ├── povray.morpho
│ ├── shapeopt.morpho
│ ├── symmetry.morpho
│ └── vtk.morpho
├── releasenotes/
│ ├── version-0.5.1.md
│ ├── version-0.5.2.md
│ ├── version-0.5.3.md
│ ├── version-0.5.4.md
│ ├── version-0.5.5.md
│ ├── version-0.5.6.md
│ ├── version-0.5.7.md
│ ├── version-0.6.0.md
│ ├── version-0.6.1.md
│ ├── version-0.6.2.md
│ └── version-0.6.3.md
├── src/
│ ├── CMakeLists.txt
│ ├── build.h
│ ├── builtin/
│ │ ├── CMakeLists.txt
│ │ ├── builtin.c
│ │ ├── builtin.h
│ │ ├── functiondefs.c
│ │ └── functiondefs.h
│ ├── classes/
│ │ ├── CMakeLists.txt
│ │ ├── array.c
│ │ ├── array.h
│ │ ├── bool.c
│ │ ├── bool.h
│ │ ├── classes.h
│ │ ├── closure.c
│ │ ├── closure.h
│ │ ├── clss.c
│ │ ├── clss.h
│ │ ├── cmplx.c
│ │ ├── cmplx.h
│ │ ├── dict.c
│ │ ├── dict.h
│ │ ├── err.c
│ │ ├── err.h
│ │ ├── file.c
│ │ ├── file.h
│ │ ├── flt.c
│ │ ├── flt.h
│ │ ├── function.c
│ │ ├── function.h
│ │ ├── instance.c
│ │ ├── instance.h
│ │ ├── int.c
│ │ ├── int.h
│ │ ├── invocation.c
│ │ ├── invocation.h
│ │ ├── json.c
│ │ ├── json.h
│ │ ├── list.c
│ │ ├── list.h
│ │ ├── metafunction.c
│ │ ├── metafunction.h
│ │ ├── range.c
│ │ ├── range.h
│ │ ├── strng.c
│ │ ├── strng.h
│ │ ├── system.c
│ │ ├── system.h
│ │ ├── tuple.c
│ │ ├── tuple.h
│ │ ├── upvalue.c
│ │ └── upvalue.h
│ ├── core/
│ │ ├── CMakeLists.txt
│ │ ├── compile.c
│ │ ├── compile.h
│ │ ├── core.h
│ │ ├── gc.c
│ │ ├── gc.h
│ │ ├── opcodes.h
│ │ ├── vm.c
│ │ └── vm.h
│ ├── datastructures/
│ │ ├── CMakeLists.txt
│ │ ├── debugannotation.c
│ │ ├── debugannotation.h
│ │ ├── dictionary.c
│ │ ├── dictionary.h
│ │ ├── error.c
│ │ ├── error.h
│ │ ├── object.c
│ │ ├── object.h
│ │ ├── program.c
│ │ ├── program.h
│ │ ├── signature.c
│ │ ├── signature.h
│ │ ├── syntaxtree.c
│ │ ├── syntaxtree.h
│ │ ├── value.c
│ │ ├── value.h
│ │ ├── varray.c
│ │ ├── varray.h
│ │ ├── version.c
│ │ └── version.h
│ ├── debug/
│ │ ├── CMakeLists.txt
│ │ ├── debug.c
│ │ ├── debug.h
│ │ ├── profile.c
│ │ └── profile.h
│ ├── geometry/
│ │ ├── CMakeLists.txt
│ │ ├── fespace.c
│ │ ├── fespace.h
│ │ ├── field.c
│ │ ├── field.h
│ │ ├── functional.c
│ │ ├── functional.h
│ │ ├── geometry.c
│ │ ├── geometry.h
│ │ ├── integrate.c
│ │ ├── integrate.h
│ │ ├── mesh.c
│ │ ├── mesh.h
│ │ ├── selection.c
│ │ └── selection.h
│ ├── linalg/
│ │ ├── CMakeLists.txt
│ │ ├── matrix.c
│ │ ├── matrix.h
│ │ ├── sparse.c
│ │ └── sparse.h
│ ├── morpho.h
│ └── support/
│ ├── CMakeLists.txt
│ ├── common.c
│ ├── common.h
│ ├── extensions.c
│ ├── extensions.h
│ ├── format.c
│ ├── format.h
│ ├── lex.c
│ ├── lex.h
│ ├── memory.c
│ ├── memory.h
│ ├── parse.c
│ ├── parse.h
│ ├── platform.c
│ ├── platform.h
│ ├── random.c
│ ├── random.h
│ ├── resources.c
│ ├── resources.h
│ ├── threadpool.c
│ └── threadpool.h
└── test/
├── apply/
│ ├── apply.morpho
│ ├── apply_args.morpho
│ ├── apply_builtin.morpho
│ ├── apply_closure.morpho
│ ├── apply_list.morpho
│ ├── apply_method.morpho
│ └── apply_recursion.morpho
├── arithmetic/
│ ├── power.morpho
│ ├── redirection.morpho
│ └── unary_div.morpho
├── array/
│ ├── array.morpho
│ ├── array_assign_beyond_bounds.morpho
│ ├── array_dim_with_initializer.morpho
│ ├── array_enumerate.morpho
│ ├── array_garbage_collect.morpho
│ ├── array_incompatible_initializer.morpho
│ ├── array_initialize_array.morpho
│ ├── array_initialize_incompatible_list.morpho
│ ├── array_initialize_list.morpho
│ ├── array_nonnum_indices.morpho
│ ├── array_print.morpho
│ ├── array_read_beyond_bounds.morpho
│ ├── array_three_dim.morpho
│ ├── array_two_dim.morpho
│ ├── array_veneer.morpho
│ ├── array_wrong_dim.morpho
│ ├── constructor.morpho
│ └── inherited.morpho
├── assignment/
│ ├── associativity.morpho
│ ├── global.morpho
│ ├── grouping.morpho
│ ├── infix_operator.morpho
│ ├── local.morpho
│ ├── prefix_operator.morpho
│ ├── shorthand.morpho
│ ├── syntax.morpho
│ ├── to_self.morpho
│ └── undefined.morpho
├── blank/
│ ├── empty_file.morpho
│ └── shebang.morpho
├── block/
│ ├── empty.morpho
│ ├── scope.morpho
│ └── scope_error.morpho
├── bool/
│ ├── builtin.morpho
│ ├── equality.morpho
│ └── not.morpho
├── break/
│ ├── break_in_if_outside_loop.morpho
│ ├── break_outside_loop.morpho
│ ├── continue_in_if_outside_loop.morpho
│ ├── continue_outside_loop.morpho
│ ├── in_for.morpho
│ ├── in_forin.morpho
│ └── in_while.morpho
├── builtin/
│ ├── apply.morpho
│ ├── bounds.morpho
│ ├── boundsvargs.morpho
│ ├── iscallable.morpho
│ ├── maxargs.morpho
│ ├── minargs.morpho
│ ├── minnumbers.morpho
│ ├── minvargs.morpho
│ ├── mod.morpho
│ └── typecheck.morpho
├── call/
│ ├── bool.morpho
│ ├── call.morpho
│ ├── nil.morpho
│ ├── num.morpho
│ ├── object.morpho
│ └── string.morpho
├── class/
│ ├── apply_class.morpho
│ ├── call_class_in_property.morpho
│ ├── call_on_class.morpho
│ ├── empty.morpho
│ ├── forward_ref_in_method.morpho
│ ├── inherit_self.morpho
│ ├── inherited_method.morpho
│ ├── is.morpho
│ ├── keyword_method.morpho
│ ├── keyword_property.morpho
│ ├── linearization.morpho
│ ├── local_fn_supersedes_method_call.morpho
│ ├── local_inherit_other.morpho
│ ├── local_inherit_self.morpho
│ ├── local_reference_self.morpho
│ ├── method_call_supersedes_global_fn.morpho
│ ├── mixins.morpho
│ ├── nested_class.morpho
│ ├── no_self_for_method_call.morpho
│ ├── prefer_local.morpho
│ ├── reference_self.morpho
│ ├── syntax_error_in_constructor.morpho
│ └── unlinearizable.morpho
├── closure/
│ ├── assign_to_closure.morpho
│ ├── assign_to_shadowed_later.morpho
│ ├── close_over_function_parameter.morpho
│ ├── close_over_later_variable.morpho
│ ├── closed_closure_in_function.morpho
│ ├── closures_in_loop.morpho
│ ├── nested_closure.morpho
│ ├── open_closure_in_function.morpho
│ ├── prioritize_upvalues_over_globals.morpho
│ ├── reference_closure_multiple_times.morpho
│ ├── reuse_closure_slot.morpho
│ ├── shadow_closure_with_local.morpho
│ ├── unused_closure.morpho
│ ├── unused_later_closure.morpho
│ └── veneer.morpho
├── comments/
│ ├── line_at_eof.morpho
│ ├── multline.morpho
│ ├── nested.morpho
│ ├── only_line_comment.morpho
│ ├── only_line_comment_and_line.morpho
│ ├── unicode.morpho
│ └── unterminated.morpho
├── complex/
│ ├── ComplexBuiltin.morpho
│ ├── ComplexTrig.morpho
│ ├── arithmetic.morpho
│ ├── clone.morpho
│ ├── complex_overflow_literal.morpho
│ ├── constructor.morpho
│ ├── constructor_error.morpho
│ ├── inherited.morpho
│ ├── methods.morpho
│ └── powers.morpho
├── constructor/
│ ├── arguments.morpho
│ ├── call_init_early_return.morpho
│ ├── call_init_explicitly.morpho
│ ├── default.morpho
│ ├── default_arguments.morpho
│ ├── early_return.morpho
│ ├── extra_arguments.morpho
│ ├── init_not_method.morpho
│ ├── missing_arguments.morpho
│ ├── return_in_nested_function.morpho
│ └── return_value.morpho
├── dictionary/
│ ├── clear.morpho
│ ├── contains.morpho
│ ├── empty_literal.morpho
│ ├── inherited.morpho
│ ├── key_not_found.morpho
│ ├── literal_from_vars.morpho
│ ├── literal_in_function.morpho
│ ├── literal_in_loop.morpho
│ ├── methods.morpho
│ ├── missing_comma.morpho
│ ├── missing_separator.morpho
│ ├── remove.morpho
│ ├── set_operations.morpho
│ ├── syntax.morpho
│ ├── tombstone.morpho
│ └── unterminated.morpho
├── do/
│ ├── do_in_fn.morpho
│ ├── do_with_break.morpho
│ ├── missingcond.morpho
│ └── syntax.morpho
├── error/
│ ├── error_incorrectly_defined.morpho
│ ├── inherited.morpho
│ ├── stacktrace.morpho
│ ├── throw.morpho
│ ├── throw_on_class.morpho
│ └── throw_on_class_notag.morpho
├── field/
│ ├── assign.morpho
│ ├── assign_matrix.morpho
│ ├── badfnin.morpho
│ ├── bounds.morpho
│ ├── discretizations/
│ │ ├── boundary_line_integrals.morpho
│ │ ├── cg1_area_in_2d_grad.morpho
│ │ ├── cg1_area_in_2d_grad_old.morpho
│ │ ├── cg1_area_in_2d_old.morpho
│ │ ├── cg1_line_in_3d_grad.morpho
│ │ ├── cg2_area_in_2d.morpho
│ │ ├── cg2_area_in_2d_grad.morpho
│ │ ├── cg2_area_in_2d_tensor_grad.morpho
│ │ ├── cg2_area_in_3d_grad.morpho
│ │ ├── cg2_line_in_1d.morpho
│ │ ├── cg2_line_in_2d_grad.morpho
│ │ ├── cg2_line_in_3d_integrate.morpho
│ │ ├── cg2_vol_in_3d.morpho
│ │ └── cg2_vol_in_3d_grad.morpho
│ ├── enumerate.morpho
│ ├── grade.morpho
│ ├── inherited.morpho
│ ├── inner.morpho
│ ├── linearize.morpho
│ ├── matrix.morpho
│ ├── methods.morpho
│ ├── multigrade.morpho
│ ├── neg_nilMesh.morpho
│ ├── negate.morpho
│ ├── op.morpho
│ ├── op_in_loop.morpho
│ ├── scalar.morpho
│ ├── scalarmul.morpho
│ └── square.mesh
├── file/
│ ├── file.morpho
│ ├── file_lines.morpho
│ ├── file_not_found.morpho
│ ├── file_readall.morpho
│ ├── file_write.morpho
│ ├── filename_missing.morpho
│ ├── filename_not_string.morpho
│ ├── folder/
│ │ ├── file1.txt
│ │ ├── file2.txt
│ │ └── file3.txt
│ ├── folder.morpho
│ ├── remote.morpho
│ ├── string.txt
│ ├── test.txt
│ └── testout.txt
├── for/
│ ├── class_in_body.morpho
│ ├── closure_in_body.morpho
│ ├── fn_in_body.morpho
│ ├── return_closure.morpho
│ ├── return_inside.morpho
│ ├── scope.morpho
│ ├── statement_condition.morpho
│ ├── statement_increment.morpho
│ ├── statement_initializer.morpho
│ ├── syntax.morpho
│ └── var_in_body.morpho
├── for_in/
│ ├── forin.morpho
│ ├── forin_custom.morpho
│ ├── forin_in_function.morpho
│ ├── forin_index.morpho
│ └── forin_string.morpho
├── function/
│ ├── anonymous.morpho
│ ├── anonymous_closure.morpho
│ ├── anonymous_closure_assign.morpho
│ ├── anonymous_closure_noparams.morpho
│ ├── anonymous_in_args.morpho
│ ├── anonymous_in_optional_args.morpho
│ ├── body_must_be_block.morpho
│ ├── constant_arg_optional.morpho
│ ├── empty_body.morpho
│ ├── extra_arguments.morpho
│ ├── index_in_arguments.morpho
│ ├── local_recursion.morpho
│ ├── missing_arguments.morpho
│ ├── missing_comma_in_parameters.morpho
│ ├── mutual_recursion/
│ │ ├── duplicate_local_mutual_recursion.morpho
│ │ ├── local_mutual_recursion.morpho
│ │ ├── local_mutual_recursion_out_of_scope.morpho
│ │ ├── mutual_recursion.morpho
│ │ ├── mutual_recursion_in_closure.morpho
│ │ ├── undefined_call_in_global.morpho
│ │ ├── unresolved_forward_ref_in_func.morpho
│ │ └── unresolved_forward_reference.morpho
│ ├── optional.morpho
│ ├── optional_invalid.morpho
│ ├── optional_non_constant_default.morpho
│ ├── optional_too_few_fixed.morpho
│ ├── parameters.morpho
│ ├── print.morpho
│ ├── recursion.morpho
│ ├── stack_overflow.morpho
│ ├── too_many_arguments.morpho
│ ├── too_many_parameters.morpho
│ ├── unknown_optional.morpho
│ ├── variadic.morpho
│ ├── variadic_append.morpho
│ ├── variadic_apply.morpho
│ ├── variadic_in_method.morpho
│ ├── variadic_last.morpho
│ ├── variadic_only.morpho
│ ├── variadic_optional.morpho
│ ├── variadic_too_many.morpho
│ └── veneer.morpho
├── functionals/
│ ├── area/
│ │ ├── area.morpho
│ │ ├── area2.morpho
│ │ ├── area2d.morpho
│ │ ├── area_hessian.morpho
│ │ ├── area_integrandForElement.morpho
│ │ ├── square.mesh
│ │ └── triangle.mesh
│ ├── areaenclosed/
│ │ ├── areaenclosed.morpho
│ │ ├── areaenclosed_hessian.morpho
│ │ └── areaenclosed_integrandForElement.morpho
│ ├── areaintegral/
│ │ ├── areaintegral.morpho
│ │ ├── cg2fieldgradient.morpho
│ │ ├── cgtensor.morpho
│ │ ├── grad.morpho
│ │ ├── grad2.morpho
│ │ ├── gradvector.morpho
│ │ └── normal.morpho
│ ├── cube.mesh
│ ├── cubeout.mesh
│ ├── equielement/
│ │ ├── equielement.morpho
│ │ ├── equielement_gradient.morpho
│ │ ├── equielement_hessian.morpho
│ │ ├── hex.mesh
│ │ └── weight.morpho
│ ├── err_functional_req_mesh.morpho
│ ├── err_integrand.morpho
│ ├── gausscurvature/
│ │ ├── disk.mesh
│ │ ├── gausscurvature.morpho
│ │ ├── geodesiccurvature.morpho
│ │ ├── gradient.morpho
│ │ ├── symm.morpho
│ │ └── torus.morpho
│ ├── gradsq/
│ │ ├── disk.mesh
│ │ ├── gradsq.morpho
│ │ ├── gradsq1d.morpho
│ │ ├── gradsq3d.morpho
│ │ ├── integral.morpho
│ │ ├── tetrahedron.mesh
│ │ └── triangle.mesh
│ ├── hydrogel/
│ │ ├── hydrogel.morpho
│ │ ├── hydrogel1D.morpho
│ │ ├── hydrogel1D_2elements.morpho
│ │ ├── hydrogel2D.morpho
│ │ ├── hydrogel2D_2elements.morpho
│ │ ├── hydrogel3D_2elements.morpho
│ │ ├── hydrogel_field_lacks_grade.morpho
│ │ └── tetrahedron.mesh
│ ├── length/
│ │ ├── length.morpho
│ │ ├── length2d.morpho
│ │ ├── length_hessian.morpho
│ │ ├── length_integrandForElement.morpho
│ │ └── line.mesh
│ ├── linearelasticity/
│ │ ├── linearelasticity.morpho
│ │ ├── relax.morpho
│ │ ├── scalesquare.mesh
│ │ ├── shearsquare.mesh
│ │ ├── square.mesh
│ │ └── stretchsquare.mesh
│ ├── linecurvaturesq/
│ │ ├── gradient.morpho
│ │ ├── gradient_symm.morpho
│ │ ├── hessian.morpho
│ │ ├── linecurvaturesq.morpho
│ │ ├── linecurvaturesq.xmorpho
│ │ ├── linecurvaturesq_integrandForElement.morpho
│ │ ├── linecurvaturesq_symm.morpho
│ │ ├── linecurvaturesq_symm.xmorpho
│ │ └── symmetry.xmorpho
│ ├── lineintegral/
│ │ ├── fields_incorrect_args.morpho
│ │ ├── fields_insufficient_args.morpho
│ │ ├── fields_toomany_args.morpho
│ │ ├── lineintegral.morpho
│ │ ├── lineintegral_fieldgradient.morpho
│ │ ├── lineintegral_hessian.morpho
│ │ ├── selection.morpho
│ │ ├── tangent.morpho
│ │ └── tangent2d.morpho
│ ├── linetorsionsq/
│ │ ├── gradient.morpho
│ │ ├── gradient_symm.morpho
│ │ ├── hessian.morpho
│ │ ├── linetorsionsq.morpho
│ │ ├── linetorsionsq.xmorpho
│ │ └── linetorsionsq_symm.morpho
│ ├── meancurvaturesq/
│ │ ├── gradient.morpho
│ │ ├── gradient_symm.morpho
│ │ ├── meancurvaturesq.morpho
│ │ └── symm.morpho
│ ├── nematic/
│ │ ├── nematic.morpho
│ │ ├── nematic3d.morpho
│ │ ├── nematicdim.morpho
│ │ ├── square.mesh
│ │ └── tetrahedron.mesh
│ ├── nematicelectric/
│ │ └── nematicelectric.morpho
│ ├── normsq/
│ │ ├── normsq.morpho
│ │ └── triangle.mesh
│ ├── numericalderivatives.morpho
│ ├── on_selection.morpho
│ ├── relax.morpho
│ ├── relax2.morpho
│ ├── scalarpotential/
│ │ ├── scalarpotential.morpho
│ │ ├── scalarpotential_hessian.morpho
│ │ ├── scalarpotential_ndiff.morpho
│ │ ├── scalarpotential_notcallable.morpho
│ │ └── tetrahedron.mesh
│ ├── square.mesh
│ ├── triangle.mesh
│ ├── volume/
│ │ ├── tetrahedron.mesh
│ │ ├── volume.morpho
│ │ └── volume_hessian.morpho
│ ├── volumeenclosed/
│ │ ├── tetrahedron.mesh
│ │ ├── volencl.morpho
│ │ ├── volencl_hessian.morpho
│ │ └── volencl_zeroelement.morpho
│ └── volumeintegral/
│ ├── grad.morpho
│ ├── testintegrals.morpho
│ └── volume_integral.morpho
├── help.py
├── if/
│ ├── class_in_else.morpho
│ ├── class_in_then.morpho
│ ├── dangling_else.morpho
│ ├── else.morpho
│ ├── fn_in_else.morpho
│ ├── fn_in_then.morpho
│ ├── if.morpho
│ ├── if_in_method.morpho
│ ├── truth.morpho
│ ├── var_in_else.morpho
│ └── var_in_then.morpho
├── import/
│ ├── as.morpho
│ ├── as_not_imported.morpho
│ ├── file_not_found.morpho
│ ├── for_clause.morpho
│ ├── for_clause_restrict.morpho
│ ├── for_string_after_for.morpho
│ ├── import_class_extends.morpho
│ ├── import_file.morpho
│ ├── import_for_class.morpho
│ ├── import_module.morpho
│ ├── import_underscore.morpho
│ ├── importtest.m
│ ├── module_not_found.morpho
│ ├── multiple.morpho
│ ├── multiple_as.morpho
│ ├── nested_import_in_module.morpho
│ ├── nestedimporttest.m
│ ├── nestedimporttest2.m
│ ├── one_for_per_line.morpho
│ ├── optional.morpho
│ ├── optional_in_module.morpho
│ └── underscoreimporttest.m
├── inheritance/
│ ├── constructor.morpho
│ ├── inherit_from_function.morpho
│ ├── inherit_from_nil.morpho
│ ├── inherit_from_number.morpho
│ ├── inherit_methods.morpho
│ ├── parenthesized_superclass.morpho
│ └── set_fields_from_base_class.morpho
├── integrate/
│ ├── counter.morpho
│ ├── embedding.morpho
│ ├── integrals1d.morpho
│ ├── integrals2d.morpho
│ ├── integrals2d_quantities.morpho
│ ├── integrals3d.morpho
│ ├── method_entry_type.morpho
│ ├── method_not_a_dict.morpho
│ ├── method_rule_not_found.morpho
│ ├── method_rule_unavlb.morpho
│ └── too_many_subdivisions.morpho
├── invocation/
│ ├── invocation.morpho
│ └── invocation_on_class.morpho
├── json/
│ ├── json.morpho
│ ├── testjson.morpho
│ └── tostring.morpho
├── junk/
│ ├── ctrl.morpho
│ ├── makectrl.xmorpho
│ └── oeq0.morpho
├── list/
│ ├── empty_index.morpho
│ ├── index_out_of_bounds.morpho
│ ├── inherited.morpho
│ ├── initializer_with_enumerable.morpho
│ ├── initializer_with_vars.morpho
│ ├── insert.morpho
│ ├── ismember.morpho
│ ├── join.morpho
│ ├── list_from_tuple.morpho
│ ├── nonint_index.mopho
│ ├── order.morpho
│ ├── pop_bounds.morpho
│ ├── pop_index.morpho
│ ├── pop_negative.morpho
│ ├── remove.morpho
│ ├── reverse.morpho
│ ├── roll.morpho
│ ├── sort_with_function.morpho
│ ├── sort_with_function_flt.morpho
│ ├── syntax.morpho
│ └── tuples.morpho
├── logical/
│ ├── and.morpho
│ ├── and_truth.morpho
│ ├── or.morpho
│ └── or_truth.morpho
├── math/
│ ├── isinf_isnan_isfinite.morpho
│ ├── math.morpho
│ └── sign.morpho
├── matrix/
│ ├── Lnorm.morpho
│ ├── arith_scalar.morpho
│ ├── arithmetic.morpho
│ ├── assign.morpho
│ ├── blockmatrix_constructor.morpho
│ ├── concatenate.morpho
│ ├── concatenate_sparse.morpho
│ ├── dimensions.morpho
│ ├── eigensystem.morpho
│ ├── eigenvalues.morpho
│ ├── format.morpho
│ ├── get_column.morpho
│ ├── identity.morpho
│ ├── incompatible_add.morpho
│ ├── incompatible_mul.morpho
│ ├── incompatible_sub.morpho
│ ├── inherited.morpho
│ ├── initializer.morpho
│ ├── inverse.morpho
│ ├── linearsolve.morpho
│ ├── linearsolve3x3.morpho
│ ├── negate.morpho
│ ├── nonnum_indices.morpho
│ ├── nonnum_initializer.morpho
│ ├── norm.morpho
│ ├── outer.morpho
│ ├── reshape.morpho
│ ├── roll.morpho
│ ├── scalar_mul.morpho
│ ├── set_column.morpho
│ ├── trace.morpho
│ └── transpose.morpho
├── mesh/
│ ├── addgradeerror.morpho
│ ├── addgradetwo.morpho
│ ├── addgradezero.morpho
│ ├── clone.morpho
│ ├── connectivity.morpho
│ ├── connectivity_tetrahedron.morpho
│ ├── err_empty_mesh_set_element.morpho
│ ├── err_mesh_con_args.morpho
│ ├── inherited.morpho
│ ├── load.morpho
│ ├── load_missing_coord.morpho
│ ├── load_spurious_vertex_ref.morpho
│ ├── maxgrade.morpho
│ ├── merge.morpho
│ ├── out.mesh
│ ├── removegrade.morpho
│ ├── resetconnectivity.morpho
│ ├── save.morpho
│ ├── sphere.mesh
│ ├── square.mesh
│ ├── square_missingcoord.mesh
│ ├── square_spurious_vertex_ref.mesh
│ ├── tetrahedron.mesh
│ ├── tetrahedron2.mesh
│ └── vertexposition.morpho
├── method/
│ ├── arity.morpho
│ ├── empty_block.morpho
│ ├── extra_arguments.morpho
│ ├── missing_arguments.morpho
│ ├── not_found.morpho
│ ├── optional.morpho
│ ├── optional_indirect.morpho
│ ├── print_bound_method.morpho
│ ├── return_in_method.morpho
│ ├── too_many_arguments.morpho
│ └── too_many_parameters.morpho
├── modules/
│ ├── constants.morpho
│ ├── delaunay/
│ │ └── delaunay.morpho
│ ├── meshgen/
│ │ └── disk.morpho
│ ├── meshslice/
│ │ ├── slice.morpho
│ │ ├── slice_delaunay.morpho
│ │ ├── slice_empty.morpho
│ │ └── tetrahedron.mesh
│ ├── meshtools/
│ │ ├── dimension_inconsistent.morpho
│ │ ├── dimension_unknown.morpho
│ │ ├── merge_duplicates.morpho
│ │ ├── mesh_still_too_large.morpho
│ │ ├── mesh_too_large.morpho
│ │ ├── meshrefine.morpho
│ │ ├── polyhedron.morpho
│ │ ├── testprune.morpho
│ │ ├── testrefine3d.morpho
│ │ ├── testrefineselection.morpho
│ │ ├── tetrahedron.mesh
│ │ ├── tetrahedron.morpho
│ │ ├── tetrahedron2.mesh
│ │ ├── triangle.mesh
│ │ └── triangle.morpho
│ ├── optimize/
│ │ └── cg.morpho
│ └── povray.morpho
├── namespace/
│ ├── function.xmorpho
│ ├── namespace_class.morpho
│ ├── namespace_class_extends.morpho
│ ├── namespace_class_restrict.morpho
│ └── namespace_functioncall.morpho
├── newline/
│ ├── block.morpho
│ ├── classes.morpho
│ ├── for.morpho
│ ├── functions.morpho
│ └── variables.morpho
├── nil/
│ └── literal.morpho
├── number/
│ ├── decimal_point_at_eof.morpho
│ ├── float_negative_overflow.morpho
│ ├── float_overflow.morpho
│ ├── integer_overflow.morpho
│ ├── leading_dot.morpho
│ ├── literals.morpho
│ ├── nan_equality.morpho
│ └── trailing_dot.morpho
├── object/
│ ├── baseclass.morpho
│ ├── builtin_inheritance.morpho
│ ├── class_responds_to.morpho
│ ├── clone.morpho
│ ├── enumerate.morpho
│ ├── has.morpho
│ ├── index.morpho
│ ├── invoke.morpho
│ ├── non_string_index.morpho
│ └── responds_to.morpho
├── operator/
│ ├── add.morpho
│ ├── add_bool_nil.morpho
│ ├── add_bool_num.morpho
│ ├── add_bool_string.morpho
│ ├── add_nil_nil.morpho
│ ├── add_num_nil.morpho
│ ├── add_string_nil.morpho
│ ├── comparison.morpho
│ ├── divide.morpho
│ ├── divide_nonnum_num.morpho
│ ├── divide_num_nonnum.morpho
│ ├── equals.morpho
│ ├── equals_class.morpho
│ ├── equals_method.morpho
│ ├── fpcompare.morpho
│ ├── greater_nonnum_num.morpho
│ ├── greater_num_nonnum.morpho
│ ├── greater_or_equal_nonnum_num.morpho
│ ├── greater_or_equal_num_nonnum.morpho
│ ├── less_nonnum_num.morpho
│ ├── less_num_nonnum.morpho
│ ├── less_or_equal_nonnum_num.morpho
│ ├── less_or_equal_num_nonnum.morpho
│ ├── more_comparison.morpho
│ ├── multiply.morpho
│ ├── multiply_nonnum_num.morpho
│ ├── multiply_num_nonnum.morpho
│ ├── negate.morpho
│ ├── negate_nonnum.morpho
│ ├── not.morpho
│ ├── not_class.morpho
│ ├── not_equals.morpho
│ ├── subtract.morpho
│ ├── subtract_nonnum_num.morpho
│ ├── subtract_num_nonnum.morpho
│ ├── ternary.morpho
│ ├── ternary_in_function.morpho
│ ├── ternary_in_loop.morpho
│ ├── ternary_missing_colon.morpho
│ └── ternary_nested.morpho
├── print/
│ └── missing_argument.morpho
├── programs/
│ ├── delta_blue.morpho
│ ├── fannkuch.morpho
│ ├── fibonacci.morpho
│ ├── histogram.morpho
│ └── integrate.morpho
├── property/
│ ├── call_function_field.morpho
│ ├── call_nonfunction_field.morpho
│ ├── get_on_bool.morpho
│ ├── get_on_class.morpho
│ ├── get_on_function.morpho
│ ├── get_on_nil.morpho
│ ├── get_on_num.morpho
│ ├── get_on_string.morpho
│ ├── index_property_in_args.morpho
│ ├── many.morpho
│ ├── method.morpho
│ ├── method_binds_self.morpho
│ ├── on_instance.morpho
│ ├── property_error_in_index.morpho
│ ├── property_index.morpho
│ ├── set_evaluation_order.morpho
│ ├── set_index_property.morpho
│ ├── set_on_bool.morpho
│ ├── set_on_class.morpho
│ ├── set_on_function.morpho
│ ├── set_on_nil.morpho
│ ├── set_on_num.morpho
│ ├── set_on_string.morpho
│ └── undefined.morpho
├── range/
│ ├── constructor.morpho
│ ├── count_down.morpho
│ ├── exclusive.morpho
│ ├── inclusive.morpho
│ ├── inherited.morpho
│ ├── invalid_constructor_too_few_args.morpho
│ ├── invalid_constructor_too_many_args.morpho
│ ├── invalid_constructor_type.morpho
│ ├── list_constructor.morpho
│ ├── step_too_fine.morpho
│ └── syntax.morpho
├── return/
│ ├── after_else.morpho
│ ├── after_if.morpho
│ ├── after_while.morpho
│ ├── at_top_level.morpho
│ ├── in_for_in.morpho
│ ├── in_function.morpho
│ ├── in_method.morpho
│ └── return_nil_if_no_value.morpho
├── selection/
│ ├── add_grade.morpho
│ ├── boundary.morpho
│ ├── circlesquare.mesh
│ ├── clone.morpho
│ ├── count.morpho
│ ├── get_index.morpho
│ ├── inherited.morpho
│ ├── no_mesh_error.morpho
│ ├── selection.morpho
│ ├── selection_withmatrix.morpho
│ ├── set_index.morpho
│ ├── set_operations.morpho
│ └── square.mesh
├── self/
│ ├── closure.morpho
│ ├── nested_class.morpho
│ ├── nested_closure.morpho
│ ├── self_at_top_level.morpho
│ ├── self_in_method.morpho
│ ├── self_in_top_level_function.morpho
│ └── self_set_prop_index.morpho
├── slice/
│ ├── arraySlicing.morpho
│ ├── listSlicing.morpho
│ └── matrixSlicing.morpho
├── sparse/
│ ├── arithmetic.morpho
│ ├── block_constructor_dimensions.morpho
│ ├── clone.morpho
│ ├── col_indices.morpho
│ ├── column.morpho
│ ├── concatenate.morpho
│ ├── dense_sparse_mul.morpho
│ ├── dimensions.morpho
│ ├── edit_sparse.morpho
│ ├── empty_initializer.morpho
│ ├── enumerate.morpho
│ ├── incompatible_add.morpho
│ ├── incompatible_mul.morpho
│ ├── indices.morpho
│ ├── inherited.morpho
│ ├── initializer.morpho
│ ├── invld_initializer.morpho
│ ├── linearsolve.morpho
│ ├── nonnum.morpho
│ ├── row_indices.morpho
│ ├── scalar_mul.morpho
│ ├── set_row_indices.morpho
│ ├── sparse_dense_mul.morpho
│ ├── sparse_dense_mul_dimensions.morpho
│ ├── sparse_empty.morpho
│ ├── sparse_empty_list.morpho
│ ├── todensematrix.morpho
│ └── transpose.morpho
├── string/
│ ├── ctrl_in_string.morpho
│ ├── empty_interpolation.morpho
│ ├── error_after_multiline.morpho
│ ├── escape.morpho
│ ├── escchar.morpho
│ ├── index.morpho
│ ├── inherited.morpho
│ ├── interpolation.morpho
│ ├── interpolation_keyword.morpho
│ ├── interpolation_propertyindex.morpho
│ ├── interpolation_syntaxerror.morpho
│ ├── interpolation_types.morpho
│ ├── invalid_unicode.morpho
│ ├── literals.morpho
│ ├── multiline.morpho
│ ├── split.morpho
│ ├── split_gc.morpho
│ ├── string_veneer.morpho
│ ├── tonumber.morpho
│ ├── unicode.morpho
│ ├── unterminated.morpho
│ └── utf8.morpho
├── super/
│ ├── bound_method.morpho
│ ├── call_other_method.morpho
│ ├── call_same_method.morpho
│ ├── closure.morpho
│ ├── constructor.morpho
│ ├── extra_arguments.morpho
│ ├── indirectly_inherited.morpho
│ ├── missing_arguments.morpho
│ ├── no_superclass_bind.morpho
│ ├── no_superclass_call.morpho
│ ├── no_superclass_method.morpho
│ ├── parenthesized.morpho
│ ├── reassign_superclass.morpho
│ ├── self_in_superclass_method.morpho
│ ├── super_at_top_level.morpho
│ ├── super_in_closure_in_inherited_method.morpho
│ ├── super_in_inherited_method.morpho
│ ├── super_in_top_level_function.morpho
│ ├── super_without_dot.morpho
│ └── super_without_name.morpho
├── syntax/
│ ├── comments.morpho
│ ├── empty_file.morpho
│ ├── illegal_chars_in_symbol.morpho
│ └── symbols.morpho
├── system/
│ ├── args.morpho
│ ├── args.xmorpho
│ └── system.morpho
├── test.py
├── try/
│ ├── break_in_catch.morpho
│ ├── continue_in_catch.morpho
│ ├── err_stack_overflw.morpho
│ ├── return_in_try.morpho
│ ├── try.morpho
│ ├── try_builtin_err.morpho
│ ├── try_empty_block.morpho
│ ├── try_empty_catch.morpho
│ ├── try_empty_label.morpho
│ ├── try_err_in_function.morpho
│ ├── try_in_function.morpho
│ ├── try_in_loop.morpho
│ ├── try_in_method.morpho
│ ├── try_missing_catch.morpho
│ ├── try_missing_catch_block.morpho
│ ├── try_nested.morpho
│ ├── try_recurse.morpho
│ ├── try_reentrancy.morpho
│ ├── try_reentrancy_uncaught.morpho
│ └── try_var_in_catch.morpho
├── tuple/
│ ├── nested_tuple.morpho
│ ├── single_nested_tuple.morpho
│ ├── tuple.morpho
│ ├── tuple_anonymousfn.morpho
│ ├── tuple_apply.morpho
│ ├── tuple_compare.morpho
│ ├── tuple_enumerate.morpho
│ ├── tuple_getindex.morpho
│ ├── tuple_in_dictionary.morpho
│ ├── tuple_index_out_of_bounds.morpho
│ ├── tuple_ismember.morpho
│ ├── tuple_join.morpho
│ ├── tuple_slice.morpho
│ └── tuple_syntax.morpho
├── type/
│ ├── iscallable.morpho
│ └── typecheck.morpho
├── types/
│ ├── builtin_class_signature.morpho
│ ├── function_signature.morpho
│ ├── multiple_dispatch/
│ │ ├── apply.morpho
│ │ ├── apply_invocation_multiple_dispatch.morpho
│ │ ├── check_args.morpho
│ │ ├── class_multiple_dispatch.morpho
│ │ ├── class_multiple_dispatch_args.morpho
│ │ ├── class_multiple_dispatch_post.morpho
│ │ ├── class_multiple_initializer.morpho
│ │ ├── class_visitor.morpho
│ │ ├── closure.morpho
│ │ ├── deep_nested_closure.morpho
│ │ ├── duplicate.morpho
│ │ ├── duplicate_no_arg.morpho
│ │ ├── duplicate_no_type.morpho
│ │ ├── duplicate_no_type_two.morpho
│ │ ├── duplicate_no_type_two_arguments.morpho
│ │ ├── duplicate_one_arg.morpho
│ │ ├── duplicate_scope.morpho
│ │ ├── free.morpho
│ │ ├── import.morpho
│ │ ├── import_for.morpho
│ │ ├── in_function.morpho
│ │ ├── inheritance.morpho
│ │ ├── inheritance_single.morpho
│ │ ├── instance.morpho
│ │ ├── invocation_multiple_dispatch.morpho
│ │ ├── multi_nested_closure.morpho
│ │ ├── multiple_dispatch.morpho
│ │ ├── namespace.morpho
│ │ ├── namespace.xmorpho
│ │ ├── namespace_for.morpho
│ │ ├── namespace_for_new.morpho
│ │ ├── namespace_for_overwrite.morpho
│ │ ├── nested_closure.morpho
│ │ ├── nparams.morpho
│ │ ├── nparams_varg.morpho
│ │ ├── object_overflow.morpho
│ │ ├── optional.morpho
│ │ ├── optional_invld.morpho
│ │ ├── pets.morpho
│ │ ├── pets.zmorpho
│ │ ├── pets_subclass.morpho
│ │ ├── recursion.morpho
│ │ ├── scope.morpho
│ │ ├── two.morpho
│ │ ├── value.morpho
│ │ ├── varg.morpho
│ │ └── varg_as_backup.morpho
│ ├── type_from_namespace.morpho
│ ├── type_in_function.morpho
│ ├── type_in_function_fake_namespace.morpho
│ ├── type_in_function_namespace.morpho
│ ├── type_in_function_namespace_not_found.morpho
│ ├── type_in_global.morpho
│ ├── type_inheritance.morpho
│ ├── type_instance.morpho
│ ├── type_namespace.xmorpho
│ ├── type_violation_constant.morpho
│ ├── type_violation_dictionary.morpho
│ ├── type_violation_global.morpho
│ ├── type_violation_in_function.morpho
│ ├── type_violation_inheritance.morpho
│ ├── type_violation_instance.morpho
│ ├── type_violation_matrix.morpho
│ ├── type_violation_propagation.morpho
│ └── type_violation_range.morpho
├── valgrind.py
├── variable/
│ ├── duplicate_local.morpho
│ ├── duplicate_parameter.morpho
│ ├── early_bound.morpho
│ ├── in_middle_of_block.morpho
│ ├── in_nested_block.morpho
│ ├── local_from_method.morpho
│ ├── multiple.morpho
│ ├── redeclare_global.morpho
│ ├── redefine_global.morpho
│ ├── scope_reuse_in_different_blocks.morpho
│ ├── shadow_and_local.morpho
│ ├── shadow_global.morpho
│ ├── shadow_local.morpho
│ ├── undefined_global.morpho
│ ├── undefined_local.morpho
│ ├── uninitialized.morpho
│ ├── unreached_undefined.morpho
│ ├── use_false_as_var.morpho
│ ├── use_global_in_initializer.morpho
│ ├── use_nil_as_var.morpho
│ ├── use_self_as_var.morpho
│ └── var_dictionary_as_label.morpho
├── veneer/
│ ├── bool.morpho
│ ├── float.morpho
│ ├── format_args.morpho
│ ├── format_invld_args.morpho
│ ├── int.morpho
│ └── invocation.morpho
├── vtk/
│ ├── ensurevtkfilename.morpho
│ ├── export_and_import_mesh.morpho
│ ├── export_and_import_no_fieldname.morpho
│ ├── export_and_import_scalar.morpho
│ ├── export_and_import_scalar_and_vector.morpho
│ ├── export_and_import_vector.morpho
│ ├── export_and_import_vector_2d.morpho
│ ├── export_import_2d.morpho
│ ├── export_import_3d.morpho
│ ├── export_incorrect_field_4d_vector.morpho
│ ├── export_incorrect_field_grade1.morpho
│ ├── export_incorrect_field_grade2.morpho
│ ├── export_incorrect_field_tensor.morpho
│ ├── import_external_vtk.morpho
│ ├── import_mesh.morpho
│ ├── import_scalar.morpho
│ ├── import_scalar_vector.morpho
│ ├── import_vector.morpho
│ ├── importer_containsfield.morpho
│ ├── importer_fieldlist.morpho
│ ├── importer_incorrect_fieldname.morpho
│ ├── mesh.vtk
│ ├── mesh_scalar.vtk
│ ├── mesh_scalar_vector.vtk
│ ├── mesh_vector.vtk
│ ├── rbc_001.vtk
│ ├── square.mesh
│ ├── tetrahedron.mesh
│ ├── vtk_exporter_addfield_fname_not_str_err.morpho
│ ├── vtk_exporter_fname_not_str_err.morpho
│ ├── vtk_exporter_init_err.morpho
│ └── vtk_exporter_invalid_fname_err.morpho
├── wc
└── while/
├── class_in_body.morpho
├── closure_in_body.morpho
├── fn_in_body.morpho
├── if_in_body.morpho
├── return_closure.morpho
├── return_inside.morpho
├── syntax.morpho
└── var_in_body.morpho
================================================
FILE CONTENTS
================================================
================================================
FILE: .gitattributes
================================================
# Auto detect text files and perform LF normalization
* text=auto
================================================
FILE: .github/ISSUE_TEMPLATE/bug_report.md
================================================
---
name: Bug report
about: Create a report to help us improve
title: "[Bug]"
labels: bug, Needs Priority
assignees: ''
---
**Describe the bug**
A clear and concise description of what the bug is.
**To Reproduce**
Steps to reproduce the behavior:
1. Go to '...'
2. Click on '....'
3. Scroll down to '....'
4. See error
**Expected behavior**
A clear and concise description of what you expected to happen.
**Screenshots**
If applicable, add screenshots to help explain your problem.
**Additional context**
Add any other context about the problem here.
================================================
FILE: .github/workflows/build.yml
================================================
name: Build
on:
push:
branches: [ "main", "dev" ]
pull_request:
branches: [ "main", "dev" ]
jobs:
build:
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@v3
- name: configure
run: |
sudo apt update
sudo apt install libsuitesparse-dev
sudo apt install liblapacke-dev
python -m pip install --upgrade pip
python -m pip install regex colored
- name: make
run: (mkdir build; cd build; cmake ..; sudo make install)
================================================
FILE: .github/workflows/buildandtest.yml
================================================
name: Build and Test
on:
push:
branches: [ "main", "dev" ]
pull_request:
branches: [ "main", "dev" ]
jobs:
build:
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@v3
- name: configure
run: |
sudo apt update
sudo apt install libsuitesparse-dev
sudo apt install liblapacke-dev
sudo apt install libunistring-dev
python -m pip install --upgrade pip
python -m pip install regex colored
- name: make
run: |
mkdir build
cd build
cmake -DCMAKE_BUILD_TYPE=Release ..
sudo make install
sudo mkdir /usr/local/lib/morpho
- name: getcli
run: |
git clone https://github.com/Morpho-lang/morpho-cli.git
cd morpho-cli
mkdir build
cd build
cmake ..
sudo make install
- name: test
run: |
cd test
python3 test.py -c
================================================
FILE: .github/workflows/buildandtestmultithreaded.yml
================================================
name: TestMultiThreaded
on:
push:
branches: [ "main", "dev" ]
pull_request:
branches: [ "main", "dev" ]
jobs:
build:
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@v3
- name: configure
run: |
sudo apt update
sudo apt install libsuitesparse-dev
sudo apt install liblapacke-dev
sudo apt install libunistring-dev
python -m pip install --upgrade pip
python -m pip install regex colored
- name: make
run: |
mkdir build
cd build
cmake -DCMAKE_BUILD_TYPE=Release ..
sudo make install
sudo mkdir /usr/local/lib/morpho
- name: getcli
run: |
git clone https://github.com/Morpho-lang/morpho-cli.git
cd morpho-cli
mkdir build
cd build
cmake ..
sudo make install
- name: test
run: |
cd test
python3 test.py -c -m
================================================
FILE: .github/workflows/codeql.yml
================================================
# For most projects, this workflow file will not need changing; you simply need
# to commit it to your repository.
#
# You may wish to alter this file to override the set of languages analyzed,
# or to provide custom queries or build logic.
#
# ******** NOTE ********
# We have attempted to detect the languages in your repository. Please check
# the `language` matrix defined below to confirm you have the correct set of
# supported CodeQL languages.
#
name: "CodeQL Advanced"
on:
push:
branches: [ "main" ]
pull_request:
branches: [ "main" ]
schedule:
- cron: '24 4 * * 5'
jobs:
analyze:
name: Analyze (${{ matrix.language }})
# Runner size impacts CodeQL analysis time. To learn more, please see:
# - https://gh.io/recommended-hardware-resources-for-running-codeql
# - https://gh.io/supported-runners-and-hardware-resources
# - https://gh.io/using-larger-runners (GitHub.com only)
# Consider using larger runners or machines with greater resources for possible analysis time improvements.
runs-on: ${{ (matrix.language == 'swift' && 'macos-latest') || 'ubuntu-latest' }}
permissions:
# required for all workflows
security-events: write
# required to fetch internal or private CodeQL packs
packages: read
# only required for workflows in private repositories
actions: read
contents: read
strategy:
fail-fast: false
matrix:
include:
- language: c-cpp
build-mode: manual
# CodeQL supports the following values keywords for 'language': 'c-cpp', 'csharp', 'go', 'java-kotlin', 'javascript-typescript', 'python', 'ruby', 'swift'
# Use `c-cpp` to analyze code written in C, C++ or both
# Use 'java-kotlin' to analyze code written in Java, Kotlin or both
# Use 'javascript-typescript' to analyze code written in JavaScript, TypeScript or both
# To learn more about changing the languages that are analyzed or customizing the build mode for your analysis,
# see https://docs.github.com/en/code-security/code-scanning/creating-an-advanced-setup-for-code-scanning/customizing-your-advanced-setup-for-code-scanning.
# If you are analyzing a compiled language, you can modify the 'build-mode' for that language to customize how
# your codebase is analyzed, see https://docs.github.com/en/code-security/code-scanning/creating-an-advanced-setup-for-code-scanning/codeql-code-scanning-for-compiled-languages
steps:
- name: Checkout repository
uses: actions/checkout@v4
# Initializes the CodeQL tools for scanning.
- name: Initialize CodeQL
uses: github/codeql-action/init@v3
with:
languages: ${{ matrix.language }}
build-mode: ${{ matrix.build-mode }}
# If you wish to specify custom queries, you can do so here or in a config file.
# By default, queries listed here will override any specified in a config file.
# Prefix the list here with "+" to use these queries and those in the config file.
# For more details on CodeQL's query packs, refer to: https://docs.github.com/en/code-security/code-scanning/automatically-scanning-your-code-for-vulnerabilities-and-errors/configuring-code-scanning#using-queries-in-ql-packs
# queries: security-extended,security-and-quality
# If the analyze step fails for one of the languages you are analyzing with
# "We were unable to automatically build your code", modify the matrix above
# to set the build mode to "manual" for that language. Then modify this step
# to build your code.
# ℹ️ Command-line programs to run using the OS shell.
# 📚 See https://docs.github.com/en/actions/using-workflows/workflow-syntax-for-github-actions#jobsjob_idstepsrun
- if: matrix.build-mode == 'manual'
shell: bash
run: |
sudo apt update
sudo apt install libsuitesparse-dev
sudo apt install liblapacke-dev
python -m pip install --upgrade pip
python -m pip install regex colored
mkdir build
cd build
cmake ..
sudo make install
- name: Perform CodeQL Analysis
uses: github/codeql-action/analyze@v3
with:
category: "/language:${{matrix.language}}"
================================================
FILE: .github/workflows/examples.yml
================================================
name: Examples
on:
push:
branches: [ "main", "dev" ]
pull_request:
branches: [ "main", "dev" ]
jobs:
build:
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@v3
- name: configure
run: |
sudo apt update
sudo apt install libglfw3-dev
sudo apt install povray
sudo apt install libfreetype6-dev
sudo apt install fonts-freefont-ttf
sudo apt install libsuitesparse-dev
sudo apt install liblapacke-dev
sudo apt install libunistring-dev
python -m pip install --upgrade pip
python -m pip install regex colored
- name: make
run: |
mkdir build
cd build
cmake -DCMAKE_BUILD_TYPE=Release ..
sudo make install
sudo mkdir /usr/local/lib/morpho
- name: getcli
run: |
git clone https://github.com/Morpho-lang/morpho-cli.git
cd morpho-cli
mkdir build
cd build
cmake ..
sudo make install
- name: morphoview
run: |
git clone https://github.com/morpho-lang/morpho-morphoview.git
cd morpho-morphoview
mkdir build
cd build
cmake ..
sudo make install
- name: morphopm
run: |
git clone https://github.com/Morpho-lang/morpho-morphopm.git
cd morpho-morphopm
./morphopm install optimize4
- name: test
run: |
cd examples
python3 examples.py -c
================================================
FILE: .github/workflows/nonanboxing.yml
================================================
name: No NANBoxing
on:
push:
branches: [ "main", "dev" ]
pull_request:
branches: [ "main", "dev" ]
jobs:
build:
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@v3
- name: configure
run: |
sudo apt update
sudo apt install libsuitesparse-dev
sudo apt install liblapacke-dev
sudo apt install libunistring-dev
python -m pip install --upgrade pip
python -m pip install regex colored
- name: make
run: |
mkdir build
cd build
cmake -DMORPHO_DISABLENANBOXING=ON ..
sudo make install
sudo mkdir /usr/local/lib/morpho
- name: getcli
run: |
git clone https://github.com/Morpho-lang/morpho-cli.git
cd morpho-cli
mkdir build
cd build
cmake -DMORPHO_DISABLENANBOXING=ON ..
sudo make install
- name: test
run: |
cd test
python3 test.py -c
================================================
FILE: .gitignore
================================================
# Prerequisites
*.d
# Object files
*.o
*.ko
*.obj
*.elf
# Linker output
*.ilk
*.map
*.exp
# Precompiled Headers
*.gch
*.pch
# Libraries
*.lib
*.a
*.la
*.lo
# Shared objects (inc. Windows DLLs)
*.dll
*.so
*.so.*
*.dylib
# Executables
*.exe
*.out
*.app
*.i*86
*.x86_64
*.hex
# Debug files
*.dSYM/
*.su
*.idb
*.pdb
# POVray files
*.pov
# Kernel Module Compile Results
*.mod*
*.cmd
.tmp_versions/
modules.order
Module.symvers
Mkfile.old
dkms.conf
.DS_Store
.entitlements
.vscode/settings.json
.vscode/
test/FailedTests*.txt
*.png
*.out
manual/src/manual.lyx~
test/vtk/data.case2.vtk
test/vtk/data.case3.0.vtk
examples/qtensor/Qtensor_K_0.01.png
examples/qtensor/Qtensor_K_0.01.png
test/vtk/data.vtk
test/vtk/square.vtk
test/vtk/tetrahedron.vtk
devguide/devguide.lyx~
build/*
build-xcode/*
build-win/*
*.valgrind
/.vs
================================================
FILE: .readthedocs.yml
================================================
# .readthedocs.yaml
# Read the Docs configuration file
# See https://docs.readthedocs.io/en/stable/config-file/v2.html for details
# Required
version: 2
# Set the version of Python and other tools you might need
build:
os: ubuntu-22.04
tools:
python: "3.9"
# Build documentation in the docs/ directory with Sphinx
sphinx:
configuration: help/conf.py
# Optionally set the version of Python and requirements required to build your docs
python:
install:
- requirements: help/requirements.txt
================================================
FILE: CMakeLists.txt
================================================
#-------------------------------------------------------------------------------
# Morpho/CMakeLists.txt
#-------------------------------------------------------------------------------
cmake_minimum_required(VERSION 3.13)
project(morpho-libmorpho)
#-------------------------------------------------------------------------------
# Platform dependent options
#-------------------------------------------------------------------------------
set(CMAKE_WINDOWS_EXPORT_ALL_SYMBOLS ON)
add_library(morpho SHARED "")
#-------------------------------------------------------------------------------
# Options
#-------------------------------------------------------------------------------
option(MORPHO_DISABLENANBOXING "Disables NAN Boxing" OFF)
option(MORPHO_GCSTRESSTEST "Stress tests the garbage collector" OFF)
option(MORPHO_BUILD_LINALG "Builds with linear algebra" ON)
option(MORPHO_BUILD_SPARSE "Builds with sparse matrix support" ON)
option(MORPHO_BUILD_GEOMETRY "Builds with geometry library" ON)
#-------------------------------------------------------------------------------
# Process options
#-------------------------------------------------------------------------------
# Option to disable NAN Boxing
if(MORPHO_DISABLENANBOXING)
target_compile_definitions(morpho PUBLIC _NO_NAN_BOXING)
endif()
# Option to stress test Garbage Collector
if(MORPHO_GCSTRESSTEST)
target_compile_definitions(morpho PUBLIC _DEBUG_STRESSGARBAGECOLLECTOR)
endif()
# Set help directory
if(MORPHO_HELP_BASEDIR)
target_compile_definitions(morpho PUBLIC MORPHO_HELP_BASEDIR=\"${MORPHO_HELP_BASEDIR}\")
endif()
# Set directory for modules supplied with morpho
if(MORPHO_MODULE_BASEDIR)
target_compile_definitions(morpho PUBLIC MORPHO_MODULE_BASEDIR=\"${MORPHO_MODULE_BASEDIR}\")
endif()
# Include geometry as part of the build
if(MORPHO_BUILD_GEOMETRY)
target_compile_definitions(morpho PUBLIC MORPHO_INCLUDE_GEOMETRY)
endif()
#-------------------------------------------------------------------------------
# BLAS and LAPACK
#-------------------------------------------------------------------------------
if (MORPHO_BUILD_LINALG)
message(STATUS "Searching for BLAS and LAPACK")
# Locate a lapack version
# Currently we prefer LAPACKE
# TODO: Fix morpho source to select between lapack and lapacke
find_library(LAPACK_LIBRARY
NAMES lapacke liblapacke lapack liblapack libopenblas
HINTS
"C:\\Program Files\\Morpho\\lib\\"
)
if (LAPACK_LIBRARY)
message(STATUS "Found LAPACK at ${LAPACK_LIBRARY}")
endif()
# Locate cblas
find_library(CBLAS_LIBRARY
NAMES cblas libcblas blas libblas openblas libopenblas
HINTS
"C:\\Program Files\\Morpho\\lib\\"
)
if (CBLAS_LIBRARY)
message(STATUS "Found blas at ${CBLAS_LIBRARY}")
endif()
# Find cblas.h header file
find_path(CBLAS_INCLUDE cblas.h
HINTS
"C:\\Program Files\\Morpho\\include\\lapack")
# Add cblas headers to include folders
target_include_directories(morpho PUBLIC ${CBLAS_INCLUDE})
message(STATUS "Found cblas headers at ${CBLAS_INCLUDE}")
target_link_libraries(morpho ${CBLAS_LIBRARY})
target_link_libraries(morpho ${LAPACK_LIBRARY})
target_compile_definitions(morpho PUBLIC MORPHO_INCLUDE_LINALG)
endif()
#-------------------------------------------------------------------------------
# SuiteSparse
#-------------------------------------------------------------------------------
if (MORPHO_BUILD_SPARSE)
message(STATUS "Searching for Suitesparse")
# Locate suitesparse
find_library(SUITESPARSE_LIBRARY
NAMES cxsparse libcxsparse
HINTS
"C:\\Program Files\\Morpho\\lib\\"
)
if (SUITESPARSE_LIBRARY)
message(STATUS "Found suitesparse at ${SUITESPARSE_LIBRARY}")
endif()
# Find suitesparse cs.h header file
find_file(SUITESPARSE_HEADER cs.h
HINTS
/home/linuxbrew/.linuxbrew/include/suitesparse
/usr/local/include
/usr/local/include/suitesparse
/opt/homebrew/include/suitesparse
/usr/include/suitesparse
"C:\\Program Files\\Morpho\\include\\suitesparse")
# Identify folder that cs.h is located in from SUITESPARSE_HEADER and store in SUITESPARSE_INCLUDE
get_filename_component(SUITESPARSE_INCLUDE ${SUITESPARSE_HEADER} DIRECTORY)
# Add suitesparse headers to include folders
target_include_directories(morpho PUBLIC ${SUITESPARSE_INCLUDE})
message(STATUS "Found cs.h at ${SUITESPARSE_INCLUDE}")
target_compile_definitions(morpho PUBLIC MORPHO_INCLUDE_SPARSE)
target_link_libraries(morpho ${SUITESPARSE_LIBRARY})
endif()
#-------------------------------------------------------------------------------
# Threads
#-------------------------------------------------------------------------------
set(THREADS_PREFER_PTHREAD_FLAG ON)
find_package(Threads REQUIRED)
#-------------------------------------------------------------------------------
# Add morpho sources
#-------------------------------------------------------------------------------
add_subdirectory(src)
# Include morpho header files across the project
target_include_directories(morpho PUBLIC src
src/builtin
src/classes
src/core
src/datastructures
src/debug
src/geometry
src/linalg
src/support )
# Create source groups for IDE
source_group("builtin" REGULAR_EXPRESSION src/builtin/.*\\.[ch])
source_group("classes" REGULAR_EXPRESSION src/classes/.*\\.[ch])
source_group("core" REGULAR_EXPRESSION src/core/.*\\.[ch])
source_group("datastructures" REGULAR_EXPRESSION src/datastructures/.*\\.[ch])
source_group("debug" REGULAR_EXPRESSION src/debug/.*\\.[ch])
source_group("geometry" REGULAR_EXPRESSION src/geometry/.*\\.[ch])
source_group("linalg" REGULAR_EXPRESSION src/linalg/.*\\.[ch])
source_group("support" REGULAR_EXPRESSION src/support/.*\\.[ch])
target_link_libraries(morpho ${CMAKE_DL_LIBS} Threads::Threads)
#-------------------------------------------------------------------------------
# Install
#-------------------------------------------------------------------------------
# Install the resulting library
install(TARGETS morpho)
# Install morpho header files
# The below works in 3.23, which is too recent for Ubuntu
# install(TARGETS morpho
# FILE_SET public_headers
# DESTINATION include/morpho
#)
# So we'll use a hacky way for now
file(GLOB_RECURSE MORPHO_HEADER_FILES "src/*.h")
install(FILES ${MORPHO_HEADER_FILES} DESTINATION include/morpho)
# Similarly install morpho modules
file(GLOB_RECURSE MORPHO_MODULES_FILES "modules/*.morpho")
install(FILES ${MORPHO_MODULES_FILES} DESTINATION share/morpho/modules)
# Similarly install morpho help files
file(GLOB_RECURSE MORPHO_HELP_FILES "help/*.md")
install(FILES ${MORPHO_HELP_FILES} DESTINATION share/morpho/help)
================================================
FILE: CODE_OF_CONDUCT.md
================================================
# Morpho Code of Conduct
## Our Pledge
We as members, contributors, and leaders pledge to make participation in our
community a harassment-free experience for everyone, regardless of age, body
size, visible or invisible disability, ethnicity, sex characteristics, gender
identity and expression, level of experience, education, socio-economic status,
nationality, personal appearance, race, caste, color, religion, or sexual
identity and orientation.
We pledge to act and interact in ways that contribute to an open, welcoming,
diverse, inclusive, and healthy community.
## Our Standards
Examples of behavior that contributes to a positive environment for our
community include:
* Demonstrating empathy and kindness toward other people
* Being respectful of differing opinions, viewpoints, and experiences
* Giving and gracefully accepting constructive feedback
* Accepting responsibility and apologizing to those affected by our mistakes,
and learning from the experience
* Focusing on what is best not just for us as individuals, but for the overall
community
Examples of unacceptable behavior include:
* The use of sexualized language or imagery, and sexual attention or advances of
any kind
* Trolling, insulting or derogatory comments, and personal or political attacks
* Public or private harassment
* Publishing others' private information, such as a physical or email address,
without their explicit permission
* Other conduct which could reasonably be considered inappropriate in a
professional setting
## Enforcement Responsibilities
Community leaders are responsible for clarifying and enforcing our standards of
acceptable behavior and will take appropriate and fair corrective action in
response to any behavior that they deem inappropriate, threatening, offensive,
or harmful.
Community leaders have the right and responsibility to remove, edit, or reject
comments, commits, code, wiki edits, issues, and other contributions that are
not aligned to this Code of Conduct, and will communicate reasons for moderation
decisions when appropriate.
## Scope
This Code of Conduct applies within all community spaces, and also applies when
an individual is officially representing the community in public spaces.
Examples of representing our community include using an official e-mail address,
posting via an official social media account, or acting as an appointed
representative at an online or offline event.
## Enforcement
Instances of abusive, harassing, or otherwise unacceptable behavior may be
reported to the community leaders responsible for enforcement at
timothy.atherton@tufts.edu.
All complaints will be reviewed and investigated promptly and fairly.
All community leaders are obligated to respect the privacy and security of the
reporter of any incident.
## Enforcement Guidelines
Community leaders will follow these Community Impact Guidelines in determining
the consequences for any action they deem in violation of this Code of Conduct:
### 1. Correction
**Community Impact**: Use of inappropriate language or other behavior deemed
unprofessional or unwelcome in the community.
**Consequence**: A private, written warning from community leaders, providing
clarity around the nature of the violation and an explanation of why the
behavior was inappropriate. A public apology may be requested.
### 2. Warning
**Community Impact**: A violation through a single incident or series of
actions.
**Consequence**: A warning with consequences for continued behavior. No
interaction with the people involved, including unsolicited interaction with
those enforcing the Code of Conduct, for a specified period of time. This
includes avoiding interactions in community spaces as well as external channels
like social media. Violating these terms may lead to a temporary or permanent
ban.
### 3. Temporary Ban
**Community Impact**: A serious violation of community standards, including
sustained inappropriate behavior.
**Consequence**: A temporary ban from any sort of interaction or public
communication with the community for a specified period of time. No public or
private interaction with the people involved, including unsolicited interaction
with those enforcing the Code of Conduct, is allowed during this period.
Violating these terms may lead to a permanent ban.
### 4. Permanent Ban
**Community Impact**: Demonstrating a pattern of violation of community
standards, including sustained inappropriate behavior, harassment of an
individual, or aggression toward or disparagement of classes of individuals.
**Consequence**: A permanent ban from any sort of public interaction within the
community.
## Attribution
This Code of Conduct is adapted from the [Contributor Covenant][homepage],
version 2.1, available at
[https://www.contributor-covenant.org/version/2/1/code_of_conduct.html][v2.1].
Community Impact Guidelines were inspired by
[Mozilla's code of conduct enforcement ladder][Mozilla CoC].
For answers to common questions about this code of conduct, see the FAQ at
[https://www.contributor-covenant.org/faq][FAQ]. Translations are available at
[https://www.contributor-covenant.org/translations][translations].
[homepage]: https://www.contributor-covenant.org
[v2.1]: https://www.contributor-covenant.org/version/2/1/code_of_conduct.html
[Mozilla CoC]: https://github.com/mozilla/diversity
[FAQ]: https://www.contributor-covenant.org/faq
[translations]: https://www.contributor-covenant.org/translations
================================================
FILE: CONTRIBUTING.md
================================================
# Contributing to Morpho
Thankyou for your interest in helping to improve Morpho! We welcome contributions from everyone. If you are unsure of anything, feel free to reach out via the Github, submit an issue or make a pull request.
There are many ways you can contribute to Morpho:
* If you have identified a bug, you can report it by [submitting an issue with the `Bug` label](https://github.com/Morpho-lang/morpho/issues/new?assignees=&labels=bug%2C+Needs+Priority&template=bug_report.md&title=%5BBug%5D). If you have solved a bug, first off, that's excellent, and thank you! You can submit your fix as a pull request to the [dev branch](https://github.com/Morpho-lang/morpho/tree/dev) of Morpho. This branch is where the updates are collected before eventually releasing them into a new version in the main branch. All pull requests to `dev` are passed through the automated testing suite. Check [below](#unit-tests) for more on that and about adding your own tests!
* If you want to propose a new feature in Morpho, you can submit an issue with the [`enhancement`](https://github.com/Morpho-lang/morpho/issues?q=is%3Aissue+is%3Aopen+label%3Aenhancement) label.
* Consult our [Roadmap](https://github.com/Morpho-lang/morpho/wiki/Road-Map) to see the features we've identified as priorities for upcoming releases of Morpho. If you're interested in working on one of these, reach out to the development team.
* If you use Morpho but are new to GitHub, or to contributing to Morpho, the issues labeled [`good first issue`](https://github.com/Morpho-lang/morpho/issues?q=is%3Aissue+is%3Aopen+label%3A%22good+first+issue%22) highlight easy-to-fix bugs that will get you started. [Here](https://gist.github.com/Chaser324/ce0505fbed06b947d962) is a guide that explains the best practices for making a pull request.
* Morpho is highly modular and modules providing new features are especially welcome. The [devguide](https://github.com/Morpho-lang/morpho-devguide) explains how to package morpho code into an easily downloadable module. The [morphopm](https://github.com/Morpho-lang/morpho-morphopm) package manager can be used to download and install modules.
* Help with unit tests, additional documentation etc. are also great ways to contribute to the project.
All contributors are expected to follow the [Morpho Code of Conduct](https://github.com/Morpho-lang/morpho/blob/main/CODE_OF_CONDUCT.md).
For further guidance and pointers, a developer's guide is gradually being assembled [devguide](https://github.com/Morpho-lang/morpho-devguide/blob/main/devguide.pdf). We also encourage you to [join our Slack community](https://join.slack.com/t/morphoco/shared_invite/zt-1hiby4iqv-UhqKEeqZih0vSG3k4gEfXQ) or get in touch via email.
## Unit tests
Morpho has an extensive set of unit-tests to make sure any new piece of code doesn't break essential functionality. Moreover, code within any pull requests to `dev` or `main` is automatically put through the test suite. While this will catch failing tests, if any, you can make sure all the tests are passing on your branch beforehand by running the test suite locally:
cd test
python3 test.py
If you have fixed a new bug, chances are the existing unit-tests didn't capture that buggy behavior. In that case, it's a good idea to _add_ new tests to lock down the behavior. You can add tests simply by adding the test file anywhere under the `test/` directory. The files are organized around topic for convenience, but any file therein will get tested.
We highly welcome contributions to the testing suite. Try writing tests that don't overlap with the existing tests, and help us lock down any remaining bugs in Morpho's functionality.
### Formatting a unit test
While a new unit-testing module is [in the works](https://github.com/Morpho-lang/morpho/pull/147), the current unit-test are executed in `python` by looking for the keyword `expect`. For instance, here is an example from the test `power.morpho` that tests the arithmetic power operator:
// Test power operator
print 2^2
// expect: 4
Here, the operation is performed and the output is printed. The special comment that starts with `// expect: ` followed by the expected output is picked up by the python testing file and compared with the output. For multiple `print` statements, the `// expect: ` comments can appear anywhere in the code, as long as they are in the right order. Other comments work as regular comments and can be used to annotate the test.
================================================
FILE: LICENSE
================================================
MIT License
Copyright (c) 2020-21 T J Atherton
Permission is hereby granted, free of charge, to any person obtaining a copy
of this software and associated documentation files (the "Software"), to deal
in the Software without restriction, including without limitation the rights
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
copies of the Software, and to permit persons to whom the Software is
furnished to do so, subject to the following conditions:
The above copyright notice and this permission notice shall be included in all
copies or substantial portions of the Software.
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
SOFTWARE.
================================================
FILE: README.md
================================================

[](https://github.com/Morpho-lang/morpho/actions/workflows/build.yml)
[](https://github.com/Morpho-lang/morpho/actions/workflows/buildandtest.yml)
The Morpho language. Morpho is a programmable environment for shape optimization and scientific computing tasks more generally. Morpho aims to be:
* **Familiar**. Morpho uses syntax similar to other C-family languages. The syntax fits on a postcard, so it's easy to learn.
* **Fast**. Morpho programs run as efficiently as other well-implemented dynamic languages like *wren* or *lua* (Morpho is often significantly faster than Python, for example). Morpho leverages numerical libraries like *BLAS*, *LAPACK* and *SUITESPARSE* to provide high performance.
* **Class-based**. Morpho is highly object-oriented, which simplifies coding and enables reusability.
* **Extendable**. Functionality is easy to add via packages, both in Morpho and in C or other compiled languages. Packages can be downloaded, installed and distributed via the [morphopm](https://github.com/Morpho-lang/morpho-morphopm) package manager.
*Morpho is based upon work supported by the National Science Foundation under grants DMR-1654283 and OAC-2003820.*
In academic publications, please cite morpho as:
* Joshi, C. et al. "A programmable environment for shape optimization and shapeshifting problems", Nat Comput Sci (2024) [doi.org/10.1038/s43588-024-00749-7](https://doi.org/10.1038/s43588-024-00749-7).
A preprint of the paper is also available on the [arXiv preprint server](https://arxiv.org/abs/2208.07859).
## Learn and use morpho
Documentation is available on [readthedocs](https://morpho-lang.readthedocs.io/en/latest/), an extensive [user manual](https://github.com/Morpho-lang/morpho-manual/blob/main/manual.pdf) and a [developer guide](https://github.com/Morpho-lang/morpho-devguide/blob/main/devguide.pdf). A [Slack community](https://join.slack.com/t/morphoco/shared_invite/zt-1o6azavwl-XMtjjFwxW~P6C8rc~YbBlA) is also available for people interested in using morpho and seeking support.
We now have a sequence of tutorial videos on our [Youtube channel](https://www.youtube.com/@Morpho-lang) to help you learn Morpho:
* An [introduction to the Morpho language](https://youtu.be/eVPGWpNDeq4)
* Introduction to [shape optimization with Morpho](https://youtu.be/odCkR0PDKa0)
## Community and Contributions
Morpho is under active development and we welcome contributions! Please see the [Contributor's guide](CONTRIBUTING.md) for more information about how you can get involved in the morpho project. For those interested in extending morpho or working with the source a [Developer guide](https://github.com/Morpho-lang/morpho-devguide) is also provided in a separate repository.
We provide a [Roadmap](https://github.com/Morpho-lang/morpho/wiki/Road-Map) for future development plans that might give you ideas for how you could contribute.
We also welcome bug reports and suggestions: Please feel free to use the *Issues* feature on our github repository to bring these to the developers' attention.
Participation in the morpho community, both as users and developers, is bound by our [Code of Conduct](CODE_OF_CONDUCT.md).
## Installation
Code in this repository builds morpho as a shared library. Morpho also requires two subsidiary programs, a [terminal app](https://github.com/Morpho-lang/morpho-cli), and a [viewer application](https://github.com/Morpho-lang/morpho-morphoview).
For this release, morpho can be installed on all supported platforms using the homebrew package manager. Alternatively, the program can be installed from source as described below. We are continuously working on improving morpho installation, and hope to provide additional mechanisms for installation in upcoming releases.
Morpho packages to extend the program's capability can be downloaded, installed and distributed via the associated [morphopm](https://github.com/Morpho-lang/morpho-morphopm) package manager.
### Installation with homebrew
The simplest way to install morpho is through the [homebrew package manager](https://brew.sh). To do so:
1. If not already installed, install homebrew on your machine as described on the [homebrew website](https://brew.sh)
2. Open a terminal and type:
```
brew update
brew tap morpho-lang/morpho
brew install morpho morpho-cli morpho-morphoview morpho-morphopm
```
If you need to uninstall morpho, simply open a terminal and type `brew uninstall morpho-morphopm morpho-cli morpho-morphoview morpho`. It's very important to uninstall the homebrew morpho in this way before attempting to install from source as below.
### Install from source
The second way to install morpho is by compiling the source code directly. Morpho now leverages the [Cmake](https://cmake.org) build system, which enables platform independent builds. Windows users must first install Windows Subsystem for Linux; some instructions to do so are found below.
#### Gather dependencies
You can use any appropriate package manager to install morpho's dependencies via the terminal.
Using homebrew (preferred on macOS):
```
brew update
brew install cmake glfw suite-sparse freetype povray libgrapheme
```
Using apt (preferred on Ubuntu):
```
sudo apt update
sudo apt upgrade
sudo apt install build-essential cmake
sudo apt install libglfw3-dev libsuitesparse-dev liblapacke-dev povray libfreetype6-dev libunistring-dev
```
#### Build the morpho shared library
You can build the shared library, hosted in this repository.
1. Obtain the source by cloning the repository:
```
git clone https://github.com/Morpho-lang/morpho.git
```
2. Navigate to the morpho folder and build the library:
```
cd morpho
mkdir build
cd build
cmake -DCMAKE_BUILD_TYPE=Release ..
sudo make install
```
3. Navigate back out of the morpho folder:
```
cd ../../
```
#### Build the morpho terminal app
The [terminal app](https://github.com/Morpho-lang/morpho-cli) provides an interactive interface to morpho, and can also run morpho files. To build it:
1. Obtain the source by cloning the github public repository:
```
git clone https://github.com/Morpho-lang/morpho-cli.git
```
2. Navigate to the morpho-cli folder and build the library:
```
cd morpho-cli
mkdir build
cd build
cmake -DCMAKE_BUILD_TYPE=Release ..
sudo make install
```
3. Check it works by typing:
```
morpho6
```
4. Assuming that the morpho terminal app starts correctly, type `quit` to return to the shell and then
```
cd ../../
```
to navigate back out of the morph-cli folder.
#### Build the morphoview viewer application
[Morphoview](https://github.com/Morpho-lang/morpho-morphoview) is a simple viewer application to visualize morpho results.
1. Obtain the source by cloning the github public repository:
```
git clone https://github.com/Morpho-lang/morpho-morphoview.git
```
2. Navigate to the morpho-cli folder and build the library:
```
cd morpho-morphoview
mkdir build
cd build
cmake -DCMAKE_BUILD_TYPE=Release ..
sudo make install
```
3. Check it works by typing:
```
morphoview
```
which should simply run and quit normally. You can then type
```
cd ../../
```
to navigate back out of the morpho-morphoview folder.
### Windows via Windows Subsystem for Linux (WSL2)
Windows support is provided through Windows Subsystem for Linux (WSL), which is an environment that enables windows to run linux applications. We highly recommend using WSL2, which is the most recent version and provides better support for GUI applications; some instructions for WSL1 are provided [in the manual](https://github.com/Morpho-lang/morpho-manual/blob/main/manual.pdf). Detailed information on running GUI applications in WSL2 is found on the [Microsoft WSL support page](https://learn.microsoft.com/en-us/windows/wsl/tutorials/gui-apps).
1. Begin by installing the [Ubuntu App](https://ubuntu.com/desktop/wsl) from the Microsoft store.
2. Once the Ubuntu terminal is working in Windows, you can install morpho either through homebrew or by building from source.
================================================
FILE: examples/catenoid/catenoid.morpho
================================================
// This script computes the shape of a soap film attached to two circular rings separated vertically.
// The surface tension minimizes the area of this film, resulting in a shape called a "catenoid".
// This belongs to the family of "minimal surfaces", which are surfaces that locally minimize their area.
// Showcases: AreaMesh, Area, conjugategradient, fixing boundary in the optimizer.
import meshtools
import plot
import optimize
// Set up geometrical parameters
var r = 1.0 // radius
var ratio = 0.4 // Separation to diameter ratio
var L = 2*r*ratio // Separation
// Generate a tube / cylindrical mesh
var mesh = AreaMesh(fn (u, v) [r*cos(u), v, r*sin(u)],
-Pi...Pi:Pi/10,
-L/2..L/2:L/5,
closed=[true,false]
)
mesh.addgrade(1)
// Select the boundary
var bnd = Selection(mesh, boundary=true)
var g = plotselection(mesh, bnd, grade=1)
g.title = "Before"
Show(g)
// Define the optimizataion problem
var problem = OptimizationProblem(mesh)
// Add the area energy using the built-in Area functional
var area = Area()
problem.addenergy(area)
// Define the optimizer
var opt = ShapeOptimizer(problem, mesh)
// Ask the optimizer to fix the boundary rings
opt.fix(bnd)
// Minimize!
opt.conjugategradient(1000)
g = plotselection(mesh, bnd, grade=1)
g.title = "After"
Show(g)
================================================
FILE: examples/cholesteric/cholesteric.morpho
================================================
// Test cholesteric in a square boundary
import meshtools
import plot
import optimize
var L = 0.5
var dx = 0.1
var m = AreaMesh(fn (u, v) [u, v, 0], -L..L:dx, -L..L:dx)
m.addgrade(1)
var substrate = Selection(m, fn (x,y,z) abs(y-(-0.5))<0.001 || abs(y-(0.5))<0.001)
substrate.addgrade(1)
//Show(plotselection(m, substrate, grade=1))
var nn = Field(m, Matrix([1,0,0]))
var problem = OptimizationProblem(m)
var lnem = Nematic(nn)
problem.addenergy(lnem)
// Impose planar degenerate anchoring by penalizing ny
var lanch = LineIntegral(fn (x, n) n[1]^2, nn)
problem.addenergy(lanch, selection=substrate)
var ln=NormSq(nn)
problem.addlocalconstraint(ln, field=nn, target=1)
lnem.pitch = Pi/2
var opt = FieldOptimizer(problem, nn)
opt.conjugategradient(1000)
// Function to visualize a director field
fn visualize(m, nn, dl) {
var v = m.vertexmatrix()
var nv = v.dimensions()[1]
var g = Graphics()
for (i in 0...nv) {
var x = v.column(i)
g.display(Cylinder(x-nn[i]*dl, x+nn[i]*dl, aspectratio=0.3))
}
return g
}
Show(visualize(m, nn, dx/4))
================================================
FILE: examples/cube/cube.morpho
================================================
/* Minimize the area of a surface at constant enclosed volume. */
import graphics
import meshtools
import plot
import optimize
var Nlevels = 4 // Levels of refinement
var Nsteps = 1000 // Maximum number of steps per refinement level
// Create an initial cube
var m = PolyhedronMesh([ [-0.5, -0.5, -0.5],
[ 0.5, -0.5, -0.5],
[-0.5, 0.5, -0.5],
[ 0.5, 0.5, -0.5],
[-0.5, -0.5, 0.5],
[ 0.5, -0.5, 0.5],
[-0.5, 0.5, 0.5],
[ 0.5, 0.5, 0.5]],
[ [0,1,3,2], [4,5,7,6],
[0,1,5,4], [3,2,6,7],
[0,2,6,4], [1,3,7,5] ])
// Set up the problen
var problem = OptimizationProblem(m)
var la = Area()
problem.addenergy(la)
var lv = VolumeEnclosed()
problem.addconstraint(lv)
// Create the optimizer
var opt = ShapeOptimizer(problem, m)
// Perform the optimization
for (i in 1..Nlevels) {
opt.conjugategradient(Nsteps)
if (i==Nlevels) break
// Refine
var mr=MeshRefiner([m])
var refmap = mr.refine()
for (el in [problem, opt]) el.update(refmap)
m = refmap[m]
}
// Compare with true area of a sphere for the same volume
var V0=lv.total(m)
var Af=la.total(m)
var R=(V0/(4/3*Pi))^(1/3)
var area = 4*Pi*R^2
print "Final area: ${Af} True area: ${area} diff: ${abs(Af-area)}"
var g = plotmesh(m)
g.title="Cube"
Show(g)
================================================
FILE: examples/delaunay/delaunay.morpho
================================================
// Demonstrate use of the Delaunay module
import plot
import delaunay
var N = 100 // Number of points
// Explicitly check that all triangles have the property that no other point is in their circumcircle
fn checkTriangulation(pts, tri, quiet=false) {
var success = true
for (t, k in tri) {
var sph = Circumsphere(pts, t)
for (i in 0...pts.count()) {
if (t.ismember(i)) continue // Skip the vertices of the triangle
if (sph.pointinsphere(pts[i])) {
if (!quiet) print "Point ${i} is in triangle ${k}."
success=false;
}
}
}
return success
}
// 2D random point distribution
var a = []
for (i in 1..N) a.append(Matrix([2*random()-1, 2*(2*random()-1)]))
var del = Delaunay(a)
var tri = del.triangulate() // Returns a list of triangles [ [i, j, k], ... ]
if (checkTriangulation(a, tri)) {
print "2D triangulation passed."
}
// 3D random point distribution
var b = []
for (i in 1..N) b.append(Matrix([2*random()-1, 2*(2*random()-1), 2*random()-1]))
del = Delaunay(b)
tri = del.triangulate()
if (checkTriangulation(b, tri)) {
print "3D triangulation passed."
}
// Directly create meshes
var m2d = DelaunayMesh(a)
m2d.addgrade(1) // Mesh as returned only contains grade 2 elements (triangles) so add the bars
Show(plotmesh(m2d, grade=[0,1]))
var m3d = DelaunayMesh(b)
m3d.addgrade(1) // Mesh as returned only contains grade 2 elements (triangles) so add the bars
Show(plotmesh(m3d, grade=[0,1]))
================================================
FILE: examples/dla/dla.morpho
================================================
// Diffusion Limited Aggregation
import kdtree
import color
import graphics
import povray
var Np = 100 // Number of particles to add
var r = 0.05 // radius of a particle
var R = 3*r // Initial radius of sphere
var delta = r // Size of step to take
var pts = [ Matrix([0,0,0]) ]
var tree = KDTree(pts)
// Generate a random point
fn randompt() {
var x = Matrix([randomnormal(), randomnormal(), randomnormal()])
return R*x/x.norm()
}
for (n in 1..Np) { // Add particles one-by-one
if (mod(n, 10)==0) print "Added particle no. ${n}"
var x = randompt()
while (true) {
// Move current particle
x+=Matrix([delta*randomnormal(), delta*randomnormal(), delta*randomnormal()])
// Check if it collided with another particle
if ((tree.nearest(x).location-x).norm()<2*r) {
tree.insert(x)
pts.append(x)
if (x.norm()>R/2) R = 2*x.norm()
break // Move to next particle
}
// Catch if it wandered out of the boundary
if (x.norm()>2*R) x = randompt()
}
}
// Now visualize the result
var col = Gray(0.5)
var g = Graphics()
g.background = White
for (x in pts) g.display(Sphere(x, r, color=col))
Show(g)
// And raytrace it too
var pov = POVRaytracer(g)
pov.viewangle = 32
pov.light = [Matrix([3,3,10]), Matrix([-3,3,10]), Matrix([0,-3,10])]
pov.render("dla.pov")
================================================
FILE: examples/electrostatics/electrostatics.morpho
================================================
// Solve Laplace's equation on a square domain by minimizing |grad V|^2
import meshtools
import plot
import optimize
var delta=0.25 // Mesh spacing
var L = 1 // Size of domain
// Create the mesh
var mesh = AreaMesh(fn (u,v) [ u, v, 0 ], -L/2..L/2:delta, -L/2..L/2:delta)
mesh.addgrade(1)
// Create boundaries and select edges, building up from selecting vertices
var bnd = Selection(mesh, boundary=true)
var bnd1 = Selection(mesh, fn (x,y,z) abs(x+L/2)<0.01 || abs(y+L/2)<0.01)
var bnd2 = Selection(mesh, fn (x,y,z) abs(x-L/2)<0.01 || abs(y-L/2)<0.01)
for (b in [bnd, bnd1, bnd2]) b.addgrade(1)
bnd1=bnd.intersection(bnd1)
bnd2=bnd.intersection(bnd2)
// Create field
var phi = Field(mesh, fn (x,y,z) 0)
// Set up the problem
var problem = OptimizationProblem(mesh)
var le = GradSq(phi)
problem.addenergy(le)
var v1 = 0, v2 = 1
var lt1 = LineIntegral(fn (x, v) (v-v1)^2, phi)
problem.addenergy(lt1, selection=bnd1, prefactor=100)
var lt2 = LineIntegral(fn (x, v) (v-v2)^2, phi)
problem.addenergy(lt2, selection=bnd2, prefactor=100)
// Create the optimizer and perform optimization
var opt = FieldOptimizer(problem, phi)
opt.conjugategradient(100)
for (i in 1..10) {
// Select elements that have an above average contribution to the energy
var en = le.integrand(phi) // energy in each element
var mean = en.sum()/en.count() // mean energy per element
var srefine = Selection(mesh)
for (id in 0...en.count()) if (en[0,id]>1.5*mean) srefine[2,id]=true // identify large contributions
// Refine
var ref = MeshRefiner([mesh, phi, bnd, bnd1, bnd2])
var refmap = ref.refine(selection=srefine) // perform the refinement
for (el in [problem, opt]) el.update(refmap) // update the problem
mesh = refmap[mesh] // update all our variables
phi = refmap[phi]
bnd = refmap[bnd]
bnd1 = refmap[bnd1]
bnd2 = refmap[bnd2]
equiangulate(mesh)
// Reminimize
opt.conjugategradient(1000)
}
print "Final mesh has ${mesh.count(2)} elements"
Show(plotmesh(mesh, grade=1))
// Display the result
Show(plotfield(phi, style="interpolate"))
================================================
FILE: examples/elementtypes/README.md
================================================
# Finite Element types
This folder contains some examples using finite elements beyond linear Lagrange elements (CG1). These require the new optimization package, optimize4. To install, type:
morphopm install optimize4
in a terminal.
## Examples
* electrostaticsCG2.morpho - Solve Laplace's equation on a square with dirichlet boundary conditions and using CG2 elements. Follows the original example in ../electrostatics
* qtensorCG2.morpho - Solve the liquid crystal q tensor problem on a disk. Follows the original example in ../qtensor.
================================================
FILE: examples/elementtypes/electrostaticsCG2.morpho
================================================
// Solve Laplace's equation on a square domain by minimizing |grad V|^2
// Uses CG2 elements
import meshtools
import plot
import optimize4
var delta=0.25/8 // Mesh spacing
var L = 1 // Size of domain
// Create the mesh
var mesh = AreaMesh(fn (u,v) [ u, v, 0 ], -L/2..L/2:delta, -L/2..L/2:delta)
mesh.addgrade(1)
// Create boundaries and select edges, building up from selecting vertices
var bnd = Selection(mesh, boundary=true)
var bnd1 = Selection(mesh, fn (x,y,z) abs(x+L/2)<0.01 || abs(y+L/2)<0.01)
var bnd2 = Selection(mesh, fn (x,y,z) abs(x-L/2)<0.01 || abs(y-L/2)<0.01)
for (b in [bnd, bnd1, bnd2]) b.addgrade(1)
bnd1=bnd.intersection(bnd1)
bnd2=bnd.intersection(bnd2)
// Create field
var phi = Field(mesh, fn (x,y,z) 0, finiteelementspace=FiniteElementSpace("CG2", grade=2))
// Set up the problem
var problem = OptimizationProblem(mesh)
fn integrand(x, q) {
var dg = grad(q).norm()
return dg*dg
}
var v1 = 0, v2 = 1
var lt1 = LineIntegral(fn (x, v) (v-v1)^2, phi, method={})
problem.addenergy(lt1, selection=bnd1, prefactor=100)
var lt2 = LineIntegral(fn (x, v) (v-v2)^2, phi, method={})
problem.addenergy(lt2, selection=bnd2, prefactor=100)
var le = AreaIntegral(integrand, phi, method={})
problem.addenergy(le)
var adapt = ProblemAdapter(problem, phi)
var control = LBFGSController(adapt)
control.optimize(1000)
// Display the result
Show(plotmesh(mesh, grade=1) + plotfield(phi, style="interpolate"))
================================================
FILE: examples/elementtypes/qtensorCG2.morpho
================================================
// Nematic liquid crystal with Q tensor on a disk
// Solved using CG2 elements
import meshgen
import plot
import povray
import optimize4
class QTensor {
init(K=0.01) {
self.mesh = nil
self.problem = nil
self.rho = 1.3 // Density. rho>1 results in the nematic phase
self.EA = 3 // Anchoring strength
self.K = K // Bending modulus. K=0.01 yields two +1/2 defects, whereas K=1.0 yields a single +1 defect.
self.a2 = (1-self.rho) // Coefficient of Tr(Q^2) in the Free energy
self.a4 = (1+self.rho)/self.rho^2 // Coefficient of (Tr(Q^2))^2 in the Free energy
}
initialMesh() {
var dom = CircularDomain([0,0], 1)
var mg = MeshGen(dom, [-1..1:0.4, -1..1:0.4], quiet=true)
var m = mg.build()
m.addgrade(1)
self.mesh = ChangeMeshDimension(m, 3)
return self.mesh
}
initialField() {
self.q_tensor = Field(self.mesh,
fn(x,y,z) Matrix([0.01*random(1), 0.01*random(1)]),
finiteelementspace=FiniteElementSpace("CG2", grade=2)
)
}
initialSelection() {
self.bnd = Selection(self.mesh, boundary=true)
self.bnd.addgrade(0) // add point elements
}
buildProblem() {
// Specify the problem
self.problem = OptimizationProblem(self.mesh)
// Define bulk free energy functional
fn landau(x, q) {
var qt = q.norm()
var qt2=qt*qt
return self.a2*qt2 + self.a4*qt2*qt2
}
var bulk = AreaIntegral(landau, self.q_tensor, method={})
self.problem.addenergy(bulk)
// Define anchoring energy functional at the boundary
fn anchoring(x, q) {
var t = tangent()
var wxx = t[0]*t[0]-0.5
var wxy = t[0]*t[1]
return (q[0]-wxx)^2+(q[1]-wxy)^2
}
var anchor = LineIntegral(anchoring, self.q_tensor, method={})
self.problem.addenergy(anchor, selection=self.bnd, prefactor = self.EA)
// The elastic energy is the grad-squared of the q-tensor
fn elasticity(x, q) {
var g = grad(q)
return g[0].inner(g[0]) + g[1].inner(g[1])
}
var elastic = AreaIntegral(elasticity, self.q_tensor, method={})
self.problem.addenergy(elastic, prefactor = self.K)
return self.problem
}
buildAdapter() {
self.adapter = ProblemAdapter(self.problem, self.q_tensor)
return self.adapter
}
build() { // Setup the problem and return an Adapter
self.initialMesh()
self.initialField()
self.initialSelection()
self.buildProblem()
return self.buildAdapter()
}
correctMesh() {
for (id in self.bnd.idlistforgrade(0)) {
var x = self.mesh.vertexposition(id)
self.mesh.setvertexposition(id, x/x.norm())
}
}
correctField() {
if (self.maxgrade(self.q_tensor)<1) return
var conn = self.mesh.connectivitymatrix(0, 1)
for (id in 0...self.mesh.count(1)) {
var v=conn.rowindices(id)
self.q_tensor[1,id]=(self.q_tensor[0,v[0]] + self.q_tensor[0,v[1]])/2
}
}
refine(adaptive=true, lambda=1.7) {
var srefine
if (adaptive) {
// Select elements that have a large contribution to the elastic energy
var en = GradSq(self.q_tensor).integrand(self.q_tensor)
var mean = en.sum()/en.count()
srefine = Selection(self.mesh) // Start with an empty selection
for (id in 0...en.count()) if (en[0,id]>lambda*mean) srefine[2,id]=true // Identify high (compared to the mean) energy elements
print "Refining ${srefine.count(2)} elements"
}
// Create a mesh refiner
var mr=MeshRefiner([self.mesh, self.q_tensor, self.bnd])
var refmap = mr.refine(selection=srefine)
// Use the new mesh and field
self.mesh = refmap[self.mesh]
self.q_tensor = refmap[self.q_tensor]
self.bnd = refmap[self.bnd]
self.correctMesh()
self.correctField()
equiangulate(self.mesh)
// Remake the problem and the adapter
self.buildProblem()
return self.buildAdapter()
}
maxgrade(f) { // Finds the maximum grade in a Field
var shape = f.shape()
var maxgrade = 0
for (s, k in shape) if (s>0) maxgrade=k
return maxgrade
}
visualize() {
var mg = self.maxgrade(self.q_tensor)
// Function to get the director (unit vector n) from the Q-tensor
fn qtodirector(q) {
var S = 2*q.norm()
var Q = q/S
var nx = sqrt(Q[0]+0.5)
var ny = abs(Q[1]/nx)
nx = nx*sign(Q[1])
return Matrix([nx,ny,0])
}
// Function to get the scalar order parameter S from the Q-tensor
fn qtoorder(q) {
var S = 2*q.norm()
return S
}
/* Function to visualize a director field
This function returns a `Graphics()` object that has the director field visualized in the form of cylinders. Here,
1. m is the mesh
2. nn is the director field and
3. dl is the half-length of the cylinders to be drawn.
4. aspectratio (optional argument) is the aspect ratio of the cylinders. (default is 0.3 here) */
fn visualize(m, nn, dl, aspectratio=0.3) {
var v = m.vertexmatrix()
var nv = v.dimensions()[1]
var g = Graphics()
for (i in 0...nv) {
var x = v.column(i)
g.display(Cylinder(x-nn[i]*dl, x+nn[i]*dl, aspectratio=aspectratio))
}
if (mg>0) {
var conn = m.connectivitymatrix(0,1)
for (id in 0...m.count(1)) {
var vids = conn.rowindices(id)
var x = (v.column(vids[0])+v.column(vids[1]))/2
g.display(Cylinder(x-nn[1,id]*(2*dl/3), x+nn[1,id]*(2*dl/3), aspectratio=aspectratio/2))
}
}
return g
}
var nn = Field(self.mesh, Matrix([1,0,0]), grade=self.q_tensor.shape()) // Initialize to some vector
for (g in 0..mg) for (i in 0...self.mesh.count(g)) {
nn[g,i]=qtodirector(self.q_tensor[g,i])
}
var S = Field(self.mesh, 0) // Initialize to a scalar
for (i in 0...self.mesh.count()) S[i]=qtoorder(self.q_tensor[i])
var splot = plotfield(S, style="interpolate", colormap = ViridisMap(), scalebar=ScaleBar(posn=[1.2,0,0]))
var gnn=visualize(self.mesh, nn, 0.05)
Show(splot+gnn)
}
}
var example = QTensor()
var adapt = example.build()
for (i in 1..4) {
if (i>1) adapt = example.refine(adaptive=false)
var control = LBFGSController(adapt)
control.optimize(500)
example.visualize()
}
================================================
FILE: examples/examples.py
================================================
#!/usr/bin/env python3
# runexamples.py
# runs all the example for morpho
# reporting any errors found
import os, glob, sys
from queue import Empty
import regex as rx
from functools import reduce
import operator
import colored
from colored import stylize
sys.path.append('../test')
ext = "morpho"
command = 'morpho6'
stk = '@stacktrace'
err = '@error'
def finderror(str):
#return rx.findall(r'\/\/ expect ?(.*) error', str)
#return rx.findall(r'.*[E|e]rror[ :].*?(.*)', str)
return rx.findall(r'@error.*', str)
def simplify_errors(str):
# this monster regex extraxts NAME from error messages of the form error ... 'NAME'
return rx.sub('.*[E|e]rror[ :]*\'([A-z;a-z]*)\'.*', err+'[\\1]', str.rstrip())
# Simplify stacktrace
def simplify_stacktrace(str):
return rx.sub(r'.*at line.*', stk, str.rstrip())
def iserror(str):
#return rx.findall(r'\/\/ expect ?(.*) error', str)
test=rx.findall(r'@error.*', str)
return len(test)>0
def remove_control_characters(str):
return rx.sub(r'\x1b[^m]*m', '', str.rstrip())
def isin(str):
#return rx.findall(r'\/\/ expect ?(.*) error', str)
test=rx.findall(r'.*in .*', str)
return len(test)>0
def getoutput(filepath):
# Load the file
file_object = open(filepath, 'r')
lines = file_object.readlines()
file_object.close()
# remove all control characters
lines = list(map(remove_control_characters, lines))
# Convert errors to our universal error code
lines = list(map(simplify_errors, lines))
# Identify stack trace lines
lines = list(map(simplify_stacktrace, lines))
for i in range(len(lines)-1):
if (iserror(lines[i])):
if (isin(lines[i+1])):
lines[i+1]=stk
# and remove them
return list(filter(lambda x: x!=stk, lines))
def run(file,testLog,CI):
ret = 1
print(file+":", end=" ")
# Create a temporary file in the same directory
tmp = file + '.out'
# Run the test
os.system(command + ' ' +file + ' > ' + tmp)
# If we produced output
if os.path.exists(tmp):
# Get the output
out = getoutput(tmp)
#look for erros
for line in out:
err = finderror(line)
# Was it expected?
if (iserror(line)):
if not CI:
print("Failed") #stylize("Failed",colored.fg("red"))) // Temporarily disable this 6/19/23 due to colored module API change
else:
print("::error file = {",file,"}::{",file," Failed}")
#also print to the test log
print(file+":", end=" ", file = testLog)
print("Failed", end=" ", file = testLog)
print("with error "+ err[0], file = testLog)
print("\n",file = testLog)
ret = 0
break
if (ret ==1):
if not CI:
print(file+":", end=" ")
print("Passed") #stylize("Passed",colored.fg("green")))
# Delete the temporary file
os.system('rm ' + tmp)
return ret
print('--Building Examples---------------------')
# open a test log
# write failures to log
success=0 # number of successful examples
total=0 # total number of examples
# look for a command line arguement that says
# this is being run for continous integration
CI = False
for arg in sys.argv:
if arg == '-c': # if the argument is -c, then we are running in CI mode
CI = True
files=glob.glob('**/**.'+ext, recursive=True)
with open("FailedExamples.txt",'w') as testLog:
for f in files:
success+=run(f,testLog,CI)
total+=1
print('--End testing-----------------------')
print(success, 'out of', total, 'tests passed.')
if CI and success<total:
exit(-1)
================================================
FILE: examples/implicitmesh/ellipsoid.morpho
================================================
import implicitmesh
import plot
// Ellipsoid
var impl = ImplicitMeshBuilder(fn (x,y,z) x^2/3+y^2+z^2-1)
var mesh = impl.build(stepsize=0.25)
mesh.addgrade(1)
Show(plotmesh(mesh, grade=[1,2]))
================================================
FILE: examples/implicitmesh/threesurface.morpho
================================================
import implicitmesh
import plot
// 3-surface
var rx=6
var ry=3.5
var rz=4
var r1=1.2
var x1=3.9
var impl = ImplicitMeshBuilder(fn (x,y,z) rz^4*z^2 - (1-(x/rx)^2-(y/ry)^2)*((x-x1)^2 + y^2 - r1^2)*(x^2+y^2-r1^2)*((x+x1)^2+y^2-r1^2))
var mesh = impl.build(start=Matrix([0,3,0]), stepsize=0.3, maxiterations=4000)
mesh.addgrade(1)
var g=plotmesh(mesh, grade=[1,2])
Show(g)
import color
import povray
g.background = White
var pov = POVRaytracer(g)
pov.light = [Matrix([-3,3,3]), Matrix([3,3,3]), Matrix([0,-3,3])]
pov.viewpoint = Matrix([0,-4,20])
pov.viewangle = 45
pov.render("threesurface.pov")
================================================
FILE: examples/implicitmesh/torus.morpho
================================================
import implicitmesh
import plot
// Torus
var r=1
var a=0.35
var impl = ImplicitMeshBuilder(fn (x,y,z) (x^2+y^2+z^2+r^2-a^2)^2 - 4*r^2*(x^2+y^2))
var mesh = impl.build(start=Matrix([1,0,0.5]), stepsize=0.25, maxiterations=400)
mesh.addgrade(1)
Show(plotmesh(mesh, grade=[1,2]))
================================================
FILE: examples/meshgen/disk.morpho
================================================
// Domain composed of a single disk
import meshgen
import plot
var dom = fn (x) -(x[0]^2+x[1]^2-1)
var mg = MeshGen(dom, [-1..1:0.2, -1..1:0.2], quiet=false)
var m = mg.build()
Show(plotmesh(m, grade=1))
================================================
FILE: examples/meshgen/ellipse.morpho
================================================
// Ellipse domain
import meshgen
import plot
var e0 = Domain(fn (x) -((x[0]/2)^2+x[1]^2-1))
var mg = MeshGen(e0, [-2..2:0.2, -1..1:0.2])
var m = mg.build()
Show(plotmesh(m, grade=1))
================================================
FILE: examples/meshgen/ellipsoidsection.morpho
================================================
// 3D Ellipsoidal shell intersecting with a plane
import meshgen
import plot
var dh = 0.2
var e0 = Domain(fn (x) -((x[0]/2)^2+x[1]^2+x[2]^2-1))
var e1 = Domain(fn (x) -((x[0]/2)^2+x[1]^2+x[2]^2-(0.5)^2))
var e2 = HalfSpaceDomain(Matrix([0.25,0,0]), Matrix([1,0,0]))
var dom = (e0.difference(e1)).intersection(e2)
var mg = MeshGen(dom, [-2..2:dh, -1.2..1.2:dh, -1.2..1.2:dh], quiet=false)
var m = mg.build()
Show(plotmesh(m, grade=1))
================================================
FILE: examples/meshgen/halfdisk.morpho
================================================
// Domain composed of disk with half space removed
import meshgen
import plot
var c = CircularDomain([0,0], 1)
var hs = HalfSpaceDomain(Matrix([0,0]), Matrix([-1,0]))
var dom = c.difference(hs)
var mg = MeshGen(dom, [-1..1:0.2, -1..1:0.2], quiet=false)
var m = mg.build()
Show(plotmesh(m, grade=1))
================================================
FILE: examples/meshgen/overlappingdisks.morpho
================================================
// Domain composed of overlapping disks
import meshgen
import plot
// Create a complicated domain by composing circular disk domains
var a = CircularDomain(Matrix([-0.5,0]), 1)
var b = CircularDomain(Matrix([0.5,0]), 1)
var c = CircularDomain(Matrix([0,0]), 0.3)
var dom = a.union(b).difference(c)
var mg = MeshGen(dom, [-2..2:0.1, -1..1:0.1], quiet=false)
var m = mg.build()
Show(plotmesh(m, grade=1))
================================================
FILE: examples/meshgen/sphere.morpho
================================================
// Sphere
import meshgen
import plot
var dh = 0.2
var dom = Domain(fn (x) -(x[0]^2+x[1]^2+x[2]^2-1))
var mg = MeshGen(dom, [-1..1:dh, -1..1:dh, -1..1:dh], quiet=false)
var m = mg.build()
Show(plotmesh(m, grade=1))
================================================
FILE: examples/meshgen/square.morpho
================================================
// Square domain with a hole
import meshgen
import plot
var e0 = Domain(fn (x) ((x[0])^2+x[1]^2-1))
var mg = MeshGen(e0, [-2..2:0.2, -2..2:0.2], quiet=false)
//mg.maxiterations=10
//mg.ttol=0.5
var m = mg.build()
Show(plotmesh(m, grade=1))
================================================
FILE: examples/meshgen/superellipse.morpho
================================================
// Superellipse domain
import meshgen
import plot
// Superellipse
var e1 = Domain(fn (x) -((x[0]^4+x[1]^4)^(1/4)-1))
var e2 = Domain(fn (x) -((x[0]^4+x[1]^4)^(1/4)-0.5))
var dom = e1.difference(e2)
var mg = MeshGen(dom, [-1..1:0.1, -1..1:0.1], quiet=false)
var m = mg.build()
Show(plotmesh(m, grade=1))
================================================
FILE: examples/meshgen/superellipsoid.morpho
================================================
// 3D Superellipsoid
import meshgen
import plot
var dh = 0.2
var dom = Domain(fn (x) -((x[0]^4+x[1]^4+x[2]^4)^(1/4)-1))
var mg = MeshGen(dom, [-1..1:dh, -1..1:dh, -1..1:dh], quiet=false)
var m = mg.build()
Show(plotmesh(m, grade=1))
================================================
FILE: examples/meshgen/weighted.morpho
================================================
// Circular domain with weight function
import meshgen
import plot
// Weighted element size
var hbar = fn (x) 1+x[0]/2 // larger elements as a function of x
var mg = MeshGen(CircularDomain([0,0], 1), [-1..1:0.1, -1..1:0.1], quiet=false, weight=hbar)
var m = mg.build()
Show(plotmesh(m, grade=1))
================================================
FILE: examples/meshslice/sphere.mesh
================================================
vertices
1 -0.954722 -0.294874 0.0394472
2 -0.945697 0.223319 -0.23619
3 -0.925278 0.166153 0.34096
4 -0.833108 -0.281133 -0.476335
5 -0.754252 0.649972 0.0929536
6 -0.726626 -0.463456 0.507172
7 -0.655019 0.150017 -0.74057
8 -0.653576 -0.753604 0.0701384
9 -0.62521 -0.0106071 0.780384
10 -0.619905 0.631677 -0.465513
11 -0.578222 -0.707421 -0.406466
12 -0.575122 0.516234 0.634616
13 -0.518378 0.0375244 -0.127763
14 -0.515911 -0.135654 -0.241352
15 -0.429096 -0.380847 -0.819044
16 -0.412838 -0.28289 0.292128
17 -0.381693 0.379087 -0.274841
18 -0.354031 0.279163 0.341505
19 -0.331776 0.864488 0.377605
20 -0.305146 -0.437068 0.846084
21 -0.303346 0.947264 -0.103305
22 -0.277188 -0.837024 0.47176
23 -0.236104 -0.437788 -0.22947
24 -0.202726 0.453119 -0.868093
25 -0.195886 -0.977308 -0.0806102
26 -0.192398 0.0179897 -0.981152
27 -0.188778 0.254176 0.948555
28 -0.137553 0.829043 -0.542002
29 -0.136529 -0.0357935 -0.566425
30 -0.0716524 -0.781658 -0.619578
31 -0.0496494 0.547329 -0.0389194
32 -0.0320227 0.00770868 0.00530305
33 -0.0182861 0.67614 0.736546
34 0.0271511 -0.0994216 0.555206
35 0.100401 -0.522318 0.171556
36 0.114494 -0.368786 -0.922436
37 0.114549 -0.164553 0.979694
38 0.151989 0.25377 -0.452691
39 0.160284 0.950495 0.266212
40 0.206156 -0.641845 0.738603
41 0.2128 0.36825 0.354235
42 0.246305 -0.934571 0.25673
43 0.273714 0.15644 -0.949003
44 0.28029 0.935922 -0.213277
45 0.295323 -0.922026 -0.250302
46 0.328752 -0.278382 -0.301566
47 0.328999 0.646195 -0.688616
48 0.386232 0.2875 0.876452
49 0.45546 0.276089 -0.122428
50 0.46643 -0.640892 -0.609673
51 0.4675 -0.115378 0.228313
52 0.499665 0.691483 0.521714
53 0.600301 -0.217826 -0.769539
54 0.622677 -0.217782 0.751561
55 0.64553 -0.641848 0.41391
56 0.678933 0.687521 -0.257614
57 0.68551 0.714488 0.139935
58 0.742604 0.279302 -0.608711
59 0.748985 -0.651382 -0.121334
60 0.829148 0.261101 0.494308
61 0.917857 -0.182455 -0.352489
62 0.952403 -0.220422 0.210575
63 0.960171 0.272899 -0.0599808
volumes
1 8 11 1 14
2 34 40 35 51
3 41 57 52 60
4 49 58 56 63
5 17 29 38 32
6 35 20 16 22
7 38 47 43 24
8 40 42 35 55
9 35 46 45 23
10 41 51 49 60
11 1 4 2 14
12 46 59 50 61
13 18 19 41 31
14 43 47 38 58
15 48 51 41 60
16 38 28 17 31
17 36 29 15 30
18 48 52 41 33
19 5 17 10 21
20 50 53 46 61
21 17 24 10 28
22 49 60 51 63
23 41 19 39 31
24 39 52 41 57
25 40 20 35 22
26 14 16 8 23
27 38 53 43 58
28 46 50 36 53
29 6 16 9 20
30 13 14 7 17
31 38 49 44 31
32 47 49 38 58
33 47 56 49 58
34 17 18 13 32
35 35 23 45 25
36 41 48 34 51
37 7 13 2 14
38 23 25 11 30
39 45 50 46 59
40 6 8 1 16
41 3 6 1 16
42 42 45 35 59
43 34 18 41 32
44 35 40 34 20
45 12 27 18 33
46 1 13 3 16
47 8 16 35 23
48 5 13 2 17
49 41 52 48 60
50 51 54 40 55
51 2 13 7 17
52 35 55 42 59
53 35 51 46 32
54 38 47 44 49
55 45 46 35 59
56 48 54 51 60
57 3 16 13 18
58 44 49 47 56
59 54 55 51 62
60 49 56 44 57
61 35 16 8 22
62 55 59 51 62
63 53 58 46 61
64 43 26 36 29
65 4 7 2 14
66 13 29 17 32
67 38 46 43 53
68 56 57 49 63
69 17 31 18 32
70 7 14 4 15
71 59 61 51 62
72 34 48 37 54
73 34 51 48 54
74 37 40 34 54
75 40 51 34 54
76 35 51 40 55
77 10 17 7 24
78 49 51 46 61
79 2 13 1 14
80 51 60 54 62
81 51 62 61 63
82 38 49 46 58
83 46 53 38 58
84 51 59 46 61
85 46 58 49 61
86 46 51 35 59
87 51 55 35 59
88 51 61 49 63
89 49 61 58 63
90 57 60 49 63
91 49 57 41 60
92 60 62 51 63
93 47 24 38 28
94 34 16 9 18
95 35 22 8 25
96 36 26 15 29
97 41 31 49 32
98 15 26 7 29
99 2 10 5 17
100 41 27 48 33
101 8 16 6 22
102 49 51 41 32
103 8 14 1 16
104 45 23 46 30
105 44 47 38 28
106 9 16 34 20
107 8 23 35 25
108 14 23 15 29
109 46 23 35 32
110 2 3 1 13
111 36 50 46 30
112 45 25 23 30
113 14 17 13 29
114 38 24 17 28
115 34 40 37 20
116 11 15 14 23
117 35 45 42 25
118 1 11 4 14
119 35 42 40 22
120 38 31 17 32
121 2 5 3 13
122 10 21 17 28
123 46 51 49 32
124 13 17 5 18
125 41 52 39 33
126 4 14 11 15
127 46 49 38 32
128 7 10 2 17
129 1 14 13 16
130 37 48 34 27
131 11 23 8 25
132 42 22 35 25
133 17 28 21 31
134 11 14 8 23
135 38 29 46 32
136 39 57 41 31
137 3 9 6 16
138 46 29 36 30
139 12 18 5 19
140 34 51 35 32
141 9 20 34 27
142 16 20 6 22
143 15 23 11 30
144 5 12 3 18
145 3 13 5 18
146 3 12 9 18
147 9 16 3 18
148 17 21 5 31
149 18 31 41 32
150 49 31 38 32
151 46 29 23 32
152 7 17 14 29
153 44 57 39 31
154 5 18 17 31
155 34 16 35 20
156 41 51 34 32
157 39 19 41 33
158 41 19 18 33
159 18 19 12 33
160 19 21 39 31
161 21 28 44 31
162 39 21 44 31
163 44 28 38 31
164 15 29 23 30
165 34 20 37 27
166 46 50 45 30
167 14 15 7 29
168 23 29 46 30
169 41 57 49 31
170 9 18 12 27
171 34 18 9 27
172 34 48 41 27
173 41 18 34 27
174 17 24 38 29
175 43 46 38 29
176 38 24 43 29
177 24 26 43 29
178 7 24 17 29
179 7 26 24 29
180 43 53 46 29
181 46 53 36 29
182 36 53 43 29
183 49 57 44 31
184 18 27 41 33
185 5 19 18 31
186 5 21 19 31
187 35 23 16 32
188 23 29 14 32
189 14 29 13 32
190 35 16 34 32
191 13 18 16 32
192 16 18 34 32
193 13 16 14 32
194 16 23 14 32
================================================
FILE: examples/meshslice/testmeshslice.morpho
================================================
// Example of using the meshslice module
import meshtools
import plot
import meshslice
// We'll create a spherical example mesh
var m = Mesh("sphere.mesh")
m.addgrade(1)
m.addgrade(2)
// And a couple of example fields
var phi = Field(m, fn (x,y,z) x+y+z)
var nn = Field(m, fn (x,y,z) Matrix([x,y,z])/sqrt(x^2+y^2+z^2))
// First create the slicer
var slice = MeshSlicer(m)
// We'll perform a slice
var slc = slice.slice([0,0,0], [1,0,0])
// and then slice the fields
var sphi = slice.slicefield(phi)
var snn = slice.slicefield(nn)
// We'll slice along a couple of other planes too
var slc2 = slice.slice([0,0,0], [0,1,0])
var sphi2 = slice.slicefield(phi)
var slc3 = slice.slice([0,0,0], [0,0,1])
var sphi3 = slice.slicefield(phi)
// Visualization 1: Show the three slices
Show(plotmesh(slc, grade=[0,1,2])+plotmesh(slc2, grade=[0,1,2])+plotmesh(slc3, grade=[0,1,2]))
// Visualization 2: show the original mesh, plus three slices
Show(plotmesh(m, grade=[1])+
plotfield(sphi, style="interpolate")+
plotfield(sphi2, style="interpolate")+
plotfield(sphi3, style="interpolate"))
// Helper function to visualize a unit vector field as cylinders
fn visualizedirector(m, nn, dl) {
var v = m.vertexmatrix()
var g = Graphics()
for (i in 0...m.count()) {
var x = v.column(i)
g.display(Cylinder(x-nn[i]*dl, x+nn[i]*dl, aspectratio=0.3))
}
return g
}
// Visualization 3: Show a sliced mesh, plus the vector field nn
Show(plotmesh(slc, grade=[1,2])+
visualizedirector(slc, snn, 0.1))
================================================
FILE: examples/plot/plotfield.morpho
================================================
// Plot a selection
import plot
import implicitmesh
/* Create a simple mesh for demonstration purposes */
var impl = ImplicitMeshBuilder(fn (x,y,z) x^2+(y/2)^2+z^2-1)
var mesh = impl.build(stepsize=0.2)
// Compute the Mean Curvature Squared and convert to a Field
var lmsq = MeanCurvatureSq()
var msq = lmsq.integrand(mesh)
var f = Field(mesh)
for (id in 0...mesh.count()) f[id]=msq[0,id]
// Visualize the field
Show(plotfield(f, grade=2, style="interpolate", scalebar=ScaleBar(posn=[1.2,0,0])))
// Visualize with custom limits on the colormap
Show(plotfield(f, grade=2, style="interpolate", cmin=0.025, cmax=0.075, scalebar=ScaleBar(posn=[1.2,0,0])))
================================================
FILE: examples/plot/plotmeshlabels.morpho
================================================
// Plot mesh labels
import plot
import meshgen
/* Create a lo-res spherical mesh for demonstration purposes */
var dom = fn (x) -(x[0]^2+x[1]^2+x[2]^2-1)
var mg = MeshGen(dom, [-1..1:0.5, -1..1:0.5, -1..1:0.5], quiet=true)
var m = mg.build()
// By default, we just get vertex labels
fn outward (x) { return 0.1*x }
Show(plotmesh(m, grade=[0,1])+
plotmeshlabels(m, offset=outward)+
plotaxes([1.2,0,0],size=0.5)) // And axes too!
// Show selected labels
var s = Selection(m, fn (x,y,z) x<0)
s.addgrade(1)
Show(plotmesh(m, grade=[0,1])+
plotmeshlabels(m, selection=s, grade=1, offset=outward))
// Show labels for multiple grades at once in different colors
Show(plotmesh(m, grade=[0,1])+
plotmeshlabels(m, grade=[0,1,3],
fontsize=8,
color={0: White, 1: Red, 3: Blue})
)
================================================
FILE: examples/plot/plotselection.morpho
================================================
// Plot a selection
import plot
import meshtools
/* Create a simple mesh for demonstration purposes */
var m = AreaMesh(fn (u,v) [u,v,0], -1..1:0.2, -1..1:0.2)
m.addgrade(1)
// Visualize the boundary
var s = Selection(m, boundary=true)
Show(plotselection(m, s, grade=[0,1,2]))
// Select portions of a mesh by region
var s2 = Selection(m, fn (x,y,z) x<=0)
s2.addgrade(2)
Show(plotselection(m, s2, grade=[0,1,2]))
================================================
FILE: examples/plot/scalebar.morpho
================================================
// Demonstrates drawing a scalebar alongside the output of plotfield
import color
import plot
import meshgen
var m = AreaMesh(fn (u,v) [u, v, 0], -1..1:0.1, -1..1:0.1)
var f = Field(m, fn (x,y,z) sin(2*Pi*x*y))
// Add a scalebar
Show(plotfield(f, style="interpolate", colormap=ViridisMap(), scalebar=ScaleBar(posn=[1.2,0,0])))
// Showcases some of the many options for Scalebar
var sb = ScaleBar(nticks=8, // Maximum number of ticks
length=1, // Length of scalebar
posn=[0,-1.2,0], // Position of scalebar
dirn=[1,0,0], // Direction in which scalebar is to be drawn
tickdirn=[0,-1,0], // Direction in which to draw ticks
textdirn=[1,0,0], // Direction to draw text
textvertical=[0,1,0], // Vertical direction for text
textcolor=White, // Text color
fontsize=10 ) // Font size
Show(plotfield(f, style="interpolate", colormap=InfernoMap(), scalebar=sb))
================================================
FILE: examples/povray/testCamera.morpho
================================================
import meshtools
import implicitmesh
import plot
import povray
var c = Matrix([0.1,0.2,0.3])
var impl = ImplicitMeshBuilder(fn (x,y,z) (x-c[0])^2/(0.5^2)+(y-c[1])^2/(0.75^2)+(z-c[2])^2-1)
var m = impl.build(stepsize=0.25)
var g = plotmesh(m)
var pov = POVRaytracer(g)
pov.render("default.pov")
var camera = Camera(look_at = c)
pov = POVRaytracer(g, camera = camera)
pov.render("centered.pov")
pov.viewpoint = c + Matrix([-5,0,0])
pov.render("centered_xview.pov")
pov.viewpoint = c + Matrix([0,-5,0])
pov.render("centered_yview.pov")
pov.sky = Matrix([1,0,0])
pov.render("centered_yview_fixed_rotated.pov")
================================================
FILE: examples/povray/testpovray.morpho
================================================
// Demonstrate use of the povray module to raytrace graphics
import constants
import color
import plot
import povray
var icos = [[-0.688191, 0, 0.131433], [0.688191,
0, -0.131433], [-0.212663, -0.654508, 0.131433], [-0.212663,
0.654508, 0.131433], [0.556758, -0.404508, 0.131433], [0.556758,
0.404508, 0.131433], [-0.131433, -0.404508, 0.556758], [-0.131433,
0.404508, 0.556758], [-0.344095, -0.25, -0.556758], [-0.344095,
0.25, -0.556758], [0.344095, -0.25, 0.556758], [0.344095, 0.25,
0.556758], [0.425325,
0, -0.556758], [-0.556758, -0.404508, -0.131433], [-0.556758,
0.404508, -0.131433], [-0.425325, 0. ,
0.556758], [0.131433, -0.404508, -0.556758], [0.131433,
0.404508, -0.556758], [0.212663, -0.654508, -0.131433], [0.212663,
0.654508, -0.131433]]
var faces = [[14, 9, 8, 13, 0], [1, 5, 11, 10, 4], [4, 10, 6, 2, 18], [10, 11, 7,
15, 6], [11, 5, 19, 3, 7], [5, 1, 12, 17, 19], [1, 4, 18, 16,
12], [3, 19, 17, 9, 14], [17, 12, 16, 8, 9], [16, 18, 2, 13, 8], [2,
6, 15, 0, 13], [15, 7, 3, 14, 0]]
fn demo() {
var p=PolyhedronMesh(icos, faces)
var f=Field(p, fn (x,y,z) x)
var g = plotfield(f, style="interpolate")
for (i in 0...30) {
var xx = Matrix([2*(random()-1/2), 2*(random()-1/2), 2*(random()-1/2)])
while (xx.norm()<0.7) xx = Matrix([2*(random()-1/2), 2*(random()-1/2), 2*(random()-1/2)])
g.display(Sphere(xx, 0.05*(1+random()), color=Color(random(),random(),random())))
}
g.display(Cylinder([-1,-1,-1],[1,1,1], aspectratio=0.01, color=Gray(0.3)))
g.display(Arrow([-1,-1,-1],[-0.5,-1,-1], aspectratio=0.05, color=Red))
g.display(Arrow([-1,-1,-1],[-1,-0.5,-1], aspectratio=0.05, color=Green))
g.display(Arrow([-1,-1,-1],[-1,-1,-0.5], aspectratio=0.05, color=Blue))
var c = []
for (t in 0...2*Pi:2*Pi/40) c.append([cos(t), sin(t),0])
g.display(Tube(c, 0.05, color=Gray(0.5), closed=true))
g.background = White
return g
}
var g=demo()
var pov = POVRaytracer(g)
pov.viewpoint=Matrix([0,0,5])
pov.viewangle=35
pov.light=[Matrix([10,10,10]), Matrix([-10,-10,10])]
pov.render("out.pov")
Show(g)
================================================
FILE: examples/povray/testpovraytext.morpho
================================================
import plot
import povray
import meshtools
var g = Graphics()
var m = AreaMesh(fn (u,v) [u,v,0], -1..1:0.5, -1..1:0.5)
m.addgrade(1)
g.display(Text("Square mesh", [-0.65,1.1,0], size=20, dirn=[1,0,0], vertical=[0,1,0]))
g = g + plotmesh(m, grade=1)
Show(g)
var pov = POVRaytracer(g)
pov.viewpoint = Matrix([0,0,8])
pov.render("testText.pov")
================================================
FILE: examples/povray/testpovraytransmitfilter.morpho
================================================
// Demonstrate use of the povray module to raytrace graphics.
// Additionally, demonstrate the use of the transmit and filter
// attributes in the Graphics objects. These attributes are used by
// povray to make the graphics transparent.
import constants
import color
import plot
import povray
import meshtools
var transmit = 0.5
var filter = 0.5
fn demo() {
var m1 = AreaMesh(fn (u,v) [u,v,-1], -1..1:0.5, -1..1:0.5)
var m2 = AreaMesh(fn (u,v) [u,1,v], -1..1:0.2, -1..1:0.2)
var gauss = Field(m2, fn(x,y,z) exp(-x^2-z^2))
var g = plotmesh(m1)
g = g + plotfield(gauss, style="interpolate")
// Plot Blue spheres with increasing transmit values
g.display(Sphere(Matrix([-0.45,0.8,-0.8]), 0.1, color=Blue))
g.display(Sphere(Matrix([-0.15,0.8,-0.8]), 0.1, color=Blue, transmit=0.1))
g.display(Sphere(Matrix([0.15,0.8,-0.8]), 0.1, color = Blue, transmit = 0.4))
g.display(Sphere(Matrix([0.45, 0.8, -0.8]), 0.1, color = Blue, transmit = 0.7))
// Plot Blue spheres with increasing filter values.
// Note the difference in the color of the shadow from the transmit ones.
g.display(Sphere(Matrix([-0.45,0.4,-0.8]), 0.1, color=Red))
g.display(Sphere(Matrix([-0.15,0.4,-0.8]), 0.1, color=Red, filter = 0.1))
g.display(Sphere(Matrix([0.15,0.4,-0.8]), 0.1, color = Red, filter = 0.4))
g.display(Sphere(Matrix([0.45, 0.4, -0.8]), 0.1, color = Red, filter = 0.7))
// Test all the other Graphics objects with transmit and filter
g.display(Arrow([-0.5, 0.0, -0.8], [-0.1, 0.0, -0.8], color = Blue, transmit = 0.75))
g.display(Arrow([0.1, 0.0, -0.8], [0.5, 0.0, -0.8], color = Red, filter = 0.75))
g.display(Cylinder([-0.5, -0.4, -0.8], [-0.1, -0.4, -0.8], color = Blue, transmit = 0.75))
g.display(Cylinder([0.1, -0.4, -0.8], [0.5, -0.4, -0.8], color = Red, filter = 0.75))
var pts1 = [[-0.3, -0.75, -0.8], [-0.4, -0.85, -0.8], [-0.2, -0.85, -0.8], [-0.3, -0.75, -0.8]]
var pts2 = [[0.3, -0.75, -0.8], [0.2, -0.85, -0.8], [0.4, -0.85, -0.8], [0.3, -0.75, -0.8]]
g.display(Tube(pts1, 0.02, color=Blue, transmit = 0.75) )
g.display(Tube(pts2, 0.02, color=Red, filter = 0.75) )
g.background = White
return g
}
var g = demo()
var pov = POVRaytracer(g)
pov.viewpoint = Matrix([-1.2, -6, 3.6])
pov.viewangle = 35
// pov.light = [Matrix([10, 10, 10]), Matrix([-10, -10, 10])]
pov.light =[Matrix([-10, -10, 10])]
pov.render("out.pov")
Show(g)
================================================
FILE: examples/povray/text.morpho
================================================
import plot
import povray
var g = Graphics()
g.display(Text("Hello World", [0,0,0]))
var pov = POVRaytracer(g)
pov.render("helloworld.pov")
================================================
FILE: examples/qtensor/dense_disk.mesh
================================================
vertices
1 -1 0 0
2 -0.951057 -0.309017 0
3 -0.951057 0.309017 0
4 -0.809017 -0.587785 0
5 -0.809017 0.587785 0
6 -0.587785 -0.809017 0
7 -0.587785 0.809017 0
8 -0.5 -0.5 0
9 -0.5 0 0
10 -0.5 0.5 0
11 -0.309017 -0.951057 0
12 -0.309017 0.951057 0
13 0 -1 0
14 0 -0.5 0
15 0 0 0
16 0 0.5 0
17 0 1 0
18 0.309017 -0.951057 0
19 0.309017 0.951057 0
20 0.5 -0.5 0
21 0.5 0 0
22 0.5 0.5 0
23 0.587785 -0.809017 0
24 0.587785 0.809017 0
25 0.809017 -0.587785 0
26 0.809017 0.587785 0
27 0.951057 -0.309017 0
28 0.951057 0.309017 0
29 1 0 0
30 -0.725529 -0.404508 0
31 -0.880037 -0.448401 0
32 -0.654508 -0.543893 0
33 -0.698401 -0.698401 0
34 -0.543893 -0.654508 0
35 -0.154508 -0.975529 0
36 0 -0.75 0
37 -0.154508 -0.725529 0
38 -0.5 -0.25 0
39 -0.725529 -0.154508 0
40 -0.25 -0.5 0
41 -0.404508 -0.725529 0
42 0.154508 -0.975529 0
43 0.154508 -0.725529 0
44 -0.448401 -0.880037 0
45 -0.25 -0.25 0
46 -0.725529 0.404508 0
47 -0.654508 0.543893 0
48 -0.880037 0.448401 0
49 -0.725529 0.154508 0
50 -0.975529 0.154508 0
51 -0.75 0 0
52 -0.543893 0.654508 0
53 -0.698401 0.698401 0
54 -0.5 0.25 0
55 -0.25 0 0
56 -0.25 0.25 0
57 -0.448401 0.880037 0
58 -0.404508 0.725529 0
59 -0.25 0.5 0
60 -0.154508 0.725529 0
61 -0.975529 -0.154508 0
62 0 -0.25 0
63 0.25 -0.5 0
64 0.25 -0.25 0
65 0.404508 -0.725529 0
66 0.448401 -0.880037 0
67 0.543893 -0.654508 0
68 0.5 -0.25 0
69 0.25 0 0
70 0.725529 -0.404508 0
71 0.654508 -0.543893 0
72 0.880037 -0.448401 0
73 0.725529 -0.154508 0
74 0.975529 -0.154508 0
75 0.75 0 0
76 0.698401 -0.698401 0
77 0.5 0.25 0
78 0.25 0.25 0
79 0.25 0.5 0
80 0.404508 0.725529 0
81 0.154508 0.725529 0
82 0 0.25 0
83 0.154508 0.975529 0
84 0 0.75 0
85 0.543893 0.654508 0
86 0.448401 0.880037 0
87 -0.154508 0.975529 0
88 0.654508 0.543893 0
89 0.725529 0.404508 0
90 0.880037 0.448401 0
91 0.698401 0.698401 0
92 0.725529 0.154508 0
93 0.975529 0.154508 0
edges
1 2 30
2 2 31
3 4 32
4 4 33
5 6 34
6 11 35
7 13 36
8 11 37
9 8 38
10 2 39
11 8 40
12 8 41
13 13 42
14 14 43
15 6 44
16 9 45
17 3 46
18 5 47
19 3 48
20 3 49
21 1 50
22 1 51
23 7 52
24 5 53
25 9 54
26 9 55
27 10 56
28 7 57
29 10 58
30 10 59
31 12 60
32 1 61
33 14 62
34 14 63
35 15 64
36 18 65
37 18 66
38 20 67
39 20 68
40 15 69
41 20 70
42 20 71
43 25 72
44 21 73
45 27 74
46 21 75
47 23 76
48 21 77
49 15 78
50 16 79
51 19 80
52 16 81
53 15 82
54 17 83
55 16 84
56 22 85
57 19 86
58 12 87
59 22 88
60 22 89
61 26 90
62 24 91
63 21 92
64 28 93
65 8 30
66 4 31
67 8 32
68 6 33
69 8 34
70 13 35
71 14 36
72 14 37
73 9 38
74 9 39
75 14 40
76 11 41
77 18 42
78 18 43
79 11 44
80 14 45
81 10 46
82 10 47
83 5 48
84 9 49
85 3 50
86 9 51
87 10 52
88 7 53
89 10 54
90 15 55
91 15 56
92 12 57
93 12 58
94 16 59
95 16 60
96 2 61
97 15 62
98 20 63
99 20 64
100 20 65
101 23 66
102 23 67
103 21 68
104 21 69
105 27 70
106 25 71
107 27 72
108 27 73
109 29 74
110 29 75
111 25 76
112 22 77
113 22 78
114 22 79
115 22 80
116 19 81
117 16 82
118 19 83
119 17 84
120 24 85
121 24 86
122 17 87
123 26 88
124 28 89
125 28 90
126 26 91
127 28 92
128 29 93
129 30 31
130 30 32
131 31 32
132 32 33
133 32 34
134 33 34
135 35 37
136 35 36
137 36 37
138 30 39
139 30 38
140 38 39
141 37 41
142 37 40
143 40 41
144 36 42
145 36 43
146 42 43
147 34 44
148 34 41
149 41 44
150 38 40
151 38 45
152 40 45
153 46 48
154 46 47
155 47 48
156 49 50
157 49 51
158 50 51
159 47 53
160 47 52
161 52 53
162 54 55
163 54 56
164 55 56
165 52 57
166 52 58
167 57 58
168 58 59
169 58 60
170 59 60
171 46 49
172 46 54
173 49 54
174 39 61
175 39 51
176 51 61
177 45 55
178 45 62
179 55 62
180 62 63
181 62 64
182 63 64
183 43 63
184 43 65
185 63 65
186 65 66
187 65 67
188 66 67
189 64 69
190 64 68
191 68 69
192 70 71
193 70 72
194 71 72
195 73 75
196 73 74
197 74 75
198 68 70
199 68 73
200 70 73
201 67 71
202 67 76
203 71 76
204 69 78
205 69 77
206 77 78
207 79 81
208 79 80
209 80 81
210 78 82
211 78 79
212 79 82
213 81 84
214 81 83
215 83 84
216 80 86
217 80 85
218 85 86
219 60 87
220 60 84
221 84 87
222 88 89
223 88 90
224 89 90
225 85 88
226 85 91
227 88 91
228 77 92
229 77 89
230 89 92
231 75 92
232 75 93
233 92 93
234 56 59
235 56 82
236 59 82
faces
1 2 30 31
2 4 32 33
3 11 35 37
4 2 30 39
5 11 37 41
6 13 36 42
7 6 34 44
8 8 38 40
9 3 46 48
10 3 49 50
11 5 47 53
12 9 54 55
13 7 52 57
14 10 58 59
15 3 46 49
16 2 39 61
17 9 45 55
18 14 62 63
19 14 43 63
20 18 65 66
21 15 64 69
22 20 70 71
23 21 73 75
24 20 68 70
25 20 67 71
26 15 69 78
27 16 79 81
28 15 78 82
29 16 81 84
30 19 80 86
31 12 60 87
32 22 88 89
33 22 85 88
34 21 77 92
35 21 75 92
36 10 56 59
37 8 30 32
38 4 31 32
39 30 31 32
40 8 32 34
41 6 33 34
42 32 33 34
43 13 35 36
44 14 36 37
45 35 36 37
46 8 30 38
47 9 38 39
48 30 38 39
49 14 37 40
50 8 40 41
51 37 40 41
52 14 36 43
53 18 42 43
54 36 42 43
55 8 34 41
56 11 41 44
57 34 41 44
58 9 38 45
59 14 40 45
60 38 40 45
61 10 46 47
62 5 47 48
63 46 47 48
64 9 49 51
65 1 50 51
66 49 50 51
67 10 47 52
68 7 52 53
69 47 52 53
70 10 54 56
71 15 55 56
72 54 55 56
73 10 52 58
74 12 57 58
75 52 57 58
76 12 58 60
77 16 59 60
78 58 59 60
79 10 46 54
80 9 49 54
81 46 49 54
82 9 39 51
83 1 51 61
84 39 51 61
85 14 45 62
86 15 55 62
87 45 55 62
88 15 62 64
89 20 63 64
90 62 63 64
91 18 43 65
92 20 63 65
93 43 63 65
94 20 65 67
95 23 66 67
96 65 66 67
97 20 64 68
98 21 68 69
99 64 68 69
100 27 70 72
101 25 71 72
102 70 71 72
103 27 73 74
104 29 74 75
105 73 74 75
106 21 68 73
107 27 70 73
108 68 70 73
109 23 67 76
110 25 71 76
111 67 71 76
112 21 69 77
113 22 77 78
114 69 77 78
115 22 79 80
116 19 80 81
117 79 80 81
118 22 78 79
119 16 79 82
120 78 79 82
121 19 81 83
122 17 83 84
123 81 83 84
124 22 80 85
125 24 85 86
126 80 85 86
127 16 60 84
128 17 84 87
129 60 84 87
130 26 88 90
131 28 89 90
132 88 89 90
133 24 85 91
134 26 88 91
135 85 88 91
136 22 77 89
137 28 89 92
138 77 89 92
139 29 75 93
140 28 92 93
141 75 92 93
142 15 56 82
143 16 59 82
144 56 59 82
================================================
FILE: examples/qtensor/qtensor.morpho
================================================
/* Problem of a 2D nematic confined to a disk with parallel anchoring boundary condition, modeled by a Q-tensor free energy.
Showcases: AreaIntegral, LineIntegral, MeshRefiner, POVRaytracer, Graphics
This example demonstrates the following features of morpho:
* It uses AreaIntegral to define the polynomial form of free energy.
* It uses mesh refinement to get a better resolution for the solution at the nematic defect locations, where there is more distortion in the field value.
* To visualize the Q-tensor, we need to see both the director (orientations) and the scalar order parameter (degree of order) together. This script shows how that can be done by adding the graphics together.
*/
import meshtools
import optimize
import plot
import povray
// Define parameters that control the script options
/* The flag `refine_adaptively` is set to decide whether to refine our mesh in regions of high elastic energy. In comparison to refining everywhere, this method gives a speed up while still giving an accurate result. When this flag is `true`, the script performs `refine_iters` (defined below) number of steps of successive adaptive refinement and relaxation. While running this script for the first time, it's ideal to set this to `false`. After getting the result, the user can then turn on adaptive refinement and compare.
The flag `visualize_refinement`, when `true`, gives further visual insight into the refinement by displaying the regions it selects for refinement, superimposed with the director. It also displays the refined mesh at each stage.
*/
var refine_adaptively = false // Flag to turn mesh-refinement on/off
var refine_iters = 4 // Number of iterations of refimenent
var visualize_refinement = false // Flag to turn plotting the refinement regions and refined meshes on/off
// Define physical parameters
var rho = 1.3 // Density. rho>1 results in the nematic phase
var EA = 3 // Anchoring strength
var K = 0.01 // Bending modulus. K=0.01 yields two +1/2 defects, whereas K=1.0 yields a single +1 defect.
var a2 = (1-rho) // Coefficient of Tr(Q^2) in the Free energy
var a4 = (1+rho)/rho^2 // Coefficient of (Tr(Q^2))^2 in the Free energy
// Import disk mesh
var m = Mesh("dense_disk.mesh")
// Select boundary
var bnd = Selection(m, boundary=true)
bnd.addgrade(0) // add point elements
// Create director field
/*
Since a 2D Q-tensor for a uniaxial nematic is symmetric and traceless, there are only two independent components, Qxx and Qxy. We thus define the q_tensor to be a 2D vector, with its components being Qxx and Qxy. We initialize it to be zero and add a random noise of 1% strength as a perturbation to start the gradient descent. The Q-tensor usually takes values of order 1, so we can use 0.01*random(1) as the initial 1% noise.
*/
var q_tensor = Field(m, fn(x,y,z) Matrix([0.01*random(1), 0.01*random(1)]))
// Define various components of the energy.
// Since these functions are meant to be arguments to AreaIntegral and LineIntegral, their first input argument has to be the position vector `x`. The field argument (the q-tensor in our case) comes after.
// Define bulk free energy functional
fn landau(x, q) {
var qt = q.norm()
var qt2=qt*qt
return a2*qt2 + a4*qt2*qt2
}
// Define anchoring energy functional at the boundary
fn anchoring(x, q) {
var t = tangent()
var wxx = t[0]*t[0]-0.5
var wxy = t[0]*t[1]
return (q[0]-wxx)^2+(q[1]-wxy)^2
}
// The bulk free energy is now the area-integral of the landau functional with the field input being q_tensor
var bulk = AreaIntegral(landau, q_tensor)
// Similarly, the anchoring free energy is now the line-integral of the anchoring functional with the field input being q_tensor
var anchor = LineIntegral(anchoring, q_tensor)
// The elastic energy is the grad-squared of the q-tensor
var elastic = GradSq(q_tensor)
// Specify the problem
var problem = OptimizationProblem(m)
// Add the energies to the problem
problem.addenergy(bulk)
// The anchoring energy has a prefactor of EA, and is applied only to the boundary
problem.addenergy(anchor, selection=bnd, prefactor = EA)
// The elastic energy has a prefactor of K
problem.addenergy(elastic, prefactor = K)
// Set up the optimizer to optimize this problem wrt the Field values.
var opt = FieldOptimizer(problem, q_tensor)
// `iters` specifies the number of iterations for the linelearch. From emperical observation, iters=500 works well.
var iters = 500
// Minimize the free energy!
opt.conjugategradient(iters)
// Define some helper functions to plot the result
// Function to get the director (unit vector n) from the Q-tensor
fn qtodirector(q) {
var S = 2*q.norm()
var Q = q/S
var nx = sqrt(Q[0]+0.5)
var ny = abs(Q[1]/nx)
nx = nx*sign(Q[1])
return Matrix([nx,ny,0])
}
// Function to get the scalar order parameter S from the Q-tensor
fn qtoorder(q) {
var S = 2*q.norm()
return S
}
/* Function to visualize a director field
This function returns a `Graphics()` object that has the director field visualized in the form of cylinders. Here,
1. m is the mesh
2. nn is the director field and
3. dl is the half-length of the cylinders to be drawn.
4. aspectratio (optional argument) is the aspect ratio of the cylinders. (default is 0.3 here)
*/
fn visualize(m, nn, dl, aspectratio=0.3) {
var v = m.vertexmatrix()
var nv = v.dimensions()[1]
var g = Graphics()
for (i in 0...nv) {
var x = v.column(i)
g.display(Cylinder(x-nn[i]*dl, x+nn[i]*dl, aspectratio=aspectratio))
}
return g
}
/* Adaptive mesh refinement
Here, we refine the mesh based on the elastic energy density and linesearch successively.
*/
if (refine_adaptively){
for (i in 1..refine_iters){
// Select elements that have a large contribution to the elastic energy
var en = elastic.integrand(q_tensor)
var mean = en.sum()/en.count()
var srefine = Selection(m) // Start with an empty selection
for (id in 0...en.count()) if (en[0,id]>1.5*mean) srefine[2,id]=true // Identify high (compared to the mean) energy elements
// Visualize the selected region for refimenemt
if (visualize_refinement){
var gs = plotselection(m, srefine, grade=2)
var nn = Field(m, Matrix([1,0,0])) // Initialize to some vector
for (i in 0...m.count()) nn[i]=qtodirector(q_tensor[i])
var gnn=visualize(m, nn, 0.05)
Show(gs+gnn)
}
// Create a mesh refiner
var mr=MeshRefiner([m, q_tensor, bnd])
// Perform the refinement
var refmap = mr.refine(selection=srefine)
// Now that refinement is done, update the problems and optimizers
for (el in [problem, opt]) el.update(refmap)
// Use the new mesh and field
m = refmap[m]
q_tensor = refmap[q_tensor]
bnd = refmap[bnd]
equiangulate(m)
// Visualize the refined mesh at each stage
if (visualize_refinement) Show(plotmesh(m, grade=1))
opt.conjugategradient(iters)
}
}
// Visualize the result
// Convert the q-tensor to the director and order
var nn = Field(m, Matrix([1,0,0])) // Initialize to some vector
for (i in 0...m.count()) nn[i]=qtodirector(q_tensor[i])
var S = Field(m, 0) // Initialize to a scalar
for (i in 0...m.count()) S[i]=qtoorder(q_tensor[i])
// Plot the scalar order field
var splot = plotfield(S, style="interpolate", colormap = ViridisMap(), scalebar=ScaleBar(posn=[1.2,0,0]))
// Plot the director using the visualize function we wrote above
var gnn=visualize(m, nn, 0.05)
// Both `plotfield` and `visualize` return a Graphics object. We can just add the two to get the final plot
var gdisp = splot+gnn
// Generate a POVRaytracer object using the Graphics() object
var pov = POVRaytracer(gdisp)
// Set the viewing angle in degrees. The larger the angle, the larger the field of view.
pov.viewangle=35
pov.viewpoint = Matrix([0,0,6])
pov.light = [Matrix([3,4,5]), Matrix([-3,-4,5])]
// Render to a .pov file. This also generates a .png image with the same name.
pov.render("Qtensor_K_${K}.pov")
// Open up the viewer application
Show(gdisp)
================================================
FILE: examples/qtensor/src.lyx
================================================
#LyX file created by tex2lyx 2.3
\lyxformat 544
\begin_document
\begin_header
\save_transient_properties true
\origin /Users/timatherton/Documents/Programs/morpho-public/morpho/examples/qtensor/
\textclass article
\begin_preamble
\usepackage{physics}
\usepackage{xcolor}
\definecolor{codegray}{rgb}{0.9,0.9,0.9}
\usepackage{listings}
\newcommand{\morpho}{\textit{morpho}}
\newcommand{\Morpho}{\textit{Morpho}}
\title{Q-tensor model of nematics}
\author{Chaitanya Joshi}
\date{October 2021}
\end_preamble
\use_default_options false
\maintain_unincluded_children false
\language english
\language_package none
\inputencoding utf8
\fontencoding default
\font_roman "default" "default"
\font_sans "default" "default"
\font_typewriter "default" "default"
\font_math "auto" "auto"
\font_default_family default
\use_non_tex_fonts false
\font_sc false
\font_osf false
\font_sf_scale 100 100
\font_tt_scale 100 100
\use_microtype false
\use_dash_ligatures true
\graphics default
\default_output_format default
\output_sync 0
\bibtex_command default
\index_command default
\paperfontsize default
\spacing single
\use_hyperref false
\papersize default
\use_geometry false
\use_package amsmath 1
\use_package amssymb 0
\use_package cancel 0
\use_package esint 1
\use_package mathdots 0
\use_package mathtools 0
\use_package mhchem 0
\use_package stackrel 0
\use_package stmaryrd 0
\use_package undertilde 0
\cite_engine basic
\cite_engine_type default
\biblio_style plain
\use_bibtopic false
\use_indices false
\paperorientation portrait
\suppress_date false
\justification true
\use_refstyle 0
\use_minted 0
\index Index
\shortcut idx
\color #008000
\end_index
\secnumdepth 3
\tocdepth 3
\paragraph_separation indent
\paragraph_indentation default
\is_math_indent 0
\math_numbering_side default
\quotes_style english
\dynamic_quotes 0
\papercolumns 1
\papersides 1
\paperpagestyle default
\tracking_changes false
\output_changes false
\html_math_output 0
\html_css_as_file 0
\html_be_strict false
\end_header
\begin_body
\begin_layout Standard
\begin_inset ERT
status collapsed
\begin_layout Plain Layout
\backslash
lstset
\end_layout
\end_inset
\begin_inset ERT
status collapsed
\begin_layout Plain Layout
{
\end_layout
\end_inset
language=Java, tabsize=4, basicstyle=
\family typewriter
, backgroundcolor=
\begin_inset ERT
status collapsed
\begin_layout Plain Layout
\backslash
color{codegray}
\end_layout
\end_inset
, showstringspaces=false
\begin_inset ERT
status collapsed
\begin_layout Plain Layout
}
\end_layout
\end_inset
\begin_inset ERT
status collapsed
\begin_layout Plain Layout
\backslash
maketitle
\end_layout
\end_inset
\end_layout
\begin_layout Section
Introduction
\end_layout
\begin_layout Standard
In 2D, for a uniaxial nematic, we can define a Q-tensor:
\begin_inset Formula \[
Q_{ij} = S (n_i n_j - 1/2 \delta_{ij})
\]
\end_inset
Here, the
\begin_inset Formula $-1/2 \delta_{ij}$
\end_inset
is added for convenience, to make the matrix traceless:
\begin_inset Formula \[\text{Tr}(\mathbf{Q}) = Q_{ii} = S(n_i n_i - 1/2 \delta_{ii}) = S(1 - 1/2(2)) = 0
\]
\end_inset
Now, the Q-tensor is also symmetric by definition:
\begin_inset Formula \[
Q_{ij} = Q_{ji}
\]
\end_inset
Due to these two reasons we can write the Q-tensor as a function of only
\begin_inset Formula $Q_{xx}$
\end_inset
and
\begin_inset Formula $Q_{xy}$
\end_inset
:
\begin_inset Formula \[
\mathbf{Q} = \begin{bmatrix}Q_{xx} & Q_{xy} \\ Q_{xy} & -Q_{xx} \end{bmatrix}
\]
\end_inset
\end_layout
\begin_layout Subsection
Simple Passive Nematic Model
\end_layout
\begin_layout Standard
The Landau-de Gennes equilibrium free energy for a nematic liquid crystal can be written in terms of the Q-tensor:
\begin_inset Formula \begin{align*}
F_{LDG} = &\int_\Omega d^2{\bf x} \ \left(\frac{a_2}{2} \text{Tr}(\mathbf{Q}^2) + \frac{a_4}{4} (\text{Tr} \mathbf{Q}^2)^2 + \frac{K}{2}(\nabla\mathbf{Q})^2 \right) \\
&+ \oint_{\partial\Omega} d{\bf x} \frac{1}{2}E_A \text{Tr}[(\mathbf{Q}-\mathbf{W})^2]
\end{align*}
\end_inset
where
\begin_inset Formula $a_2 = (\rho-1)$
\end_inset
and
\begin_inset Formula $a_4 = (\rho+1)/\rho^2$
\end_inset
set the isotropic to nematic transition with
\begin_inset Formula $\rho$
\end_inset
being the non-dimensional density. The system is in the isotropic state for
\begin_inset Formula $\rho<1$
\end_inset
and in the nematic phase when
\begin_inset Formula $\rho>1$
\end_inset
. In the nematic phase,
\begin_inset Formula $\ell_n = \sqrt{K/a_2}$
\end_inset
sets the nematic coherence length. Now,
\begin_inset Formula \[
\mathbf{Q}^2 = \begin{bmatrix}Q_{xx} & Q_{xy} \\ Q_{xy} & -Q_{xx} \end{bmatrix} \begin{bmatrix}Q_{xx} & Q_{xy} \\ Q_{xy} & -Q_{xx} \end{bmatrix} = (Q_{xx}^2+Q_{xy}^2) \begin{bmatrix} 1 & 0 \\ 0 & 1 \end{bmatrix}
\]
\end_inset
Hence,
\begin_inset Formula \[
\text{Tr}(\mathbf{Q}^2) = 2(Q_{xx}^2+Q_{xy}^2)
\]
\end_inset
Similarly,
\begin_inset Formula \[
(\nabla \mathbf{Q})^2 = \partial_i Q_{kj}\partial_i Q_{kj} = 2 \{ (\partial_x Q_{xx})^2+(\partial_xQ_{xy})^2 + (\partial_y Q_{xx})^2+(\partial_y Q_{xy})^2 \}
\]
\end_inset
Now, the second term is a boundary integral, with
\begin_inset Formula $E_A$
\end_inset
being the anchoring strength.
\begin_inset Formula $\mathbf{W}$
\end_inset
is the tensor corresponding to the boundary condition. For instance, for parallel anchoring,
\begin_inset Formula \[
W_{ij} = (t_i t_j - 1/2 \delta_{ij})
\]
\end_inset
where
\begin_inset Formula $t_i$
\end_inset
is a component of the tangent vector at the boundary.
\begin_inset Formula $\mathbf{W}$
\end_inset
is also a symmetric traceless tensor with two independent components
\begin_inset Formula $W_{xx}$
\end_inset
and
\begin_inset Formula $W_{xy}$
\end_inset
. The boundary term becomes:
\begin_inset Formula \[ \text{Tr}[(\mathbf{Q}-\mathbf{W})^2] = 2\{ Q_{xx}^2 + Q_{xy}^2 - 2(Q_{xx}W_{xx} + Q_{xy}W_{xy}) + W_{xx}^2 + W_{xy}^2 \}
\]
\end_inset
\end_layout
\begin_layout Section
Vector formulation
\end_layout
\begin_layout Standard
We can formulate all these expressions in terms of vector quantities:
\begin_inset Formula \[\vec{q} \equiv \{ Q_{xx}, Q_{xy}\}\]
\end_inset
\begin_inset Formula \[\vec{w} \equiv \{ w_{xx}, w_{xy}\}\]
\end_inset
Thus,
\begin_inset Formula \[
\text{Tr}(\mathbf{Q}^2) = 2 ||\vec{q}||^2
\]
\end_inset
\end_layout
\begin_layout Standard
\begin_inset Formula \[
(\nabla \mathbf{Q})^2 = 2 ||\nabla \vec{q}||^2
\]
\end_inset
\end_layout
\begin_layout Standard
\begin_inset Formula \[
\text{Tr}[(\mathbf{Q}-\mathbf{W})^2] = 2 ||\vec{q}-\vec{w}||^2
\]
\end_inset
With these, we want to minimize the area-integral of
\begin_inset Formula \[
F = \int_\Omega d^2{\bf x} \ \left( a_2 ||\vec{q}||^2 + a_4 ||\vec{q}||^4 + K||\nabla\vec{q}||^2 \right)
\]
\end_inset
together with the line-integral energy
\begin_inset Formula \[
\oint_{\partial\Omega} d{\bf x} \ E_A ||\vec{q}-\vec{w}||^2
\]
\end_inset
\end_layout
\begin_layout Section
\begin_inset ERT
status collapsed
\begin_layout Plain Layout
\backslash
Morpho
\end_layout
\end_inset
\begin_inset space \space{}
\end_inset
implementation
\end_layout
\begin_layout Standard
This free energy is readily set up in
\begin_inset ERT
status collapsed
\begin_layout Plain Layout
\backslash
morpho
\end_layout
\end_inset
. For this problem, we will consider a 2D disk geometry with unit radius. We use
\begin_inset Formula $\rho=1.3$
\end_inset
, so that we are deep in the nematic regime. We fix
\begin_inset Formula $E_{\text{A}}=3$
\end_inset
, which sets strong anchoring at the boundary. With this strong tangential anchoring, we get a topological charge of
\begin_inset Formula $+1$
\end_inset
at the boundary, and this acts as a constraint. When the nematic coherence length is comparable to the disk diameter (
\begin_inset Formula $\ell_n \sim R$
\end_inset
), the
\begin_inset Formula $+1$
\end_inset
charge penetrates throughout the disk, whereas if (
\begin_inset Formula $\ell_n \ll R$
\end_inset
), then a formation with 2
\begin_inset Formula $+1/2$
\end_inset
defects is more stable. To test this, we use two different values of
\begin_inset Formula $K$
\end_inset
:, 0.01 and 1.0.
\end_layout
\begin_layout Standard
We first define all our parameters and import
\begin_inset Formula $\texttt{disk.mesh}$
\end_inset
from the tactoid example:
\begin_inset listings
inline false
status open
\begin_layout Plain Layout
var rho = 1.3 // Deep in the nematic phase
\end_layout
\begin_layout Plain Layout
var EA = 3 // Anchoring strength
\end_layout
\begin_layout Plain Layout
var K = 0.01 // Bending modulus
\end_layout
\begin_layout Plain Layout
\end_layout
\begin_layout Plain Layout
var a2 = (1-rho)
\end_layout
\begin_layout Plain Layout
var a4 = (1+rho)/rho^2
\end_layout
\begin_layout Plain Layout
\end_layout
\begin_layout Plain Layout
var m = Mesh("disk.mesh")
\end_layout
\begin_layout Plain Layout
var m = refinemesh(m) // Refining for a better result
\end_layout
\begin_layout Plain Layout
var bnd = Selection(m, boundary=true)
\end_layout
\begin_layout Plain Layout
bnd.addgrade(0) // add point elements
\end_layout
\begin_layout Plain Layout
\end_layout
\end_inset
We define the Q-tensor in its vector form as discussed above, initializing it to small random values:
\begin_inset listings
inline false
status open
\begin_layout Plain Layout
var q_tensor = Field(m, fn(x,y,z)
\end_layout
\begin_layout Plain Layout
Matrix([0.01*random(1), 0.01*random(1)]))
\end_layout
\end_inset
Note that this incidentally makes the director parallel to a 45 degree line. We now define the bulk energy, the anchoring energy and the distortion free energy as follows:
\begin_inset listings
inline false
status open
\begin_layout Plain Layout
// Define bulk free energy
\end_layout
\begin_layout Plain Layout
fn landau(x, q) {
\end_layout
\begin_layout Plain Layout
var qt = q.norm()
\end_layout
\begin_layout Plain Layout
var qt2=qt*qt
\end_layout
\begin_layout Plain Layout
return a2*qt2 + a4*qt2*qt2
\end_layout
\begin_layout Plain Layout
}
\end_layout
\begin_layout Plain Layout
// Define anchoring energy at the boundary
\end_layout
\begin_layout Plain Layout
fn anchoring(x, q) {
\end_layout
\begin_layout Plain Layout
var t = tangent()
\end_layout
\begin_layout Plain Layout
var wxx = t[0]*t[0]-0.5
\end_layout
\begin_layout Plain Layout
var wxy = t[0]*t[1]
\end_layout
\begin_layout Plain Layout
return (q[0]-wxx)^2+(q[1]-wxy)^2
\end_layout
\begin_layout Plain Layout
}
\end_layout
\begin_layout Plain Layout
\end_layout
\begin_layout Plain Layout
var bulk = AreaIntegral(landau, q_tensor)
\end_layout
\begin_layout Plain Layout
var anchor = LineIntegral(anchoring, q_tensor)
\end_layout
\begin_layout Plain Layout
var elastic = GradSq(q_tensor)
\end_layout
\end_inset
Equipped with the energies, we define the
\family typewriter
OptimizationProblem
\family default
:
\begin_inset listings
inline false
status open
\begin_layout Plain Layout
var problem = OptimizationProblem(m)
\end_layout
\begin_layout Plain Layout
problem.addenergy(bulk)
\end_layout
\begin_layout Plain Layout
problem.addenergy(elastic, prefactor = K)
\end_layout
\begin_layout Plain Layout
problem.addenergy(anchor, selection=bnd, prefactor=EA)
\end_layout
\end_inset
To minimize the energy with respect to the field, we define the
\family typewriter
FieldOptimizer
\family default
and perform a
\family typewriter
linesearch
\family default
:
\begin_inset listings
inline false
status open
\begin_layout Plain Layout
var opt = FieldOptimizer(problem, q_tensor)
\end_layout
\begin_layout Plain Layout
opt.linesearch(500)
\end_layout
\end_inset
\end_layout
\begin_layout Section
Visualizing the result
\end_layout
\begin_layout Standard
For visualizing the final configuration, we use the same piece of code we used for the tactoid example, and define some additional helper functions to extract the director and the order from the Q-tensor.
\begin_inset listings
inline false
status open
\begin_layout Plain Layout
fn sign(x) {
\end_layout
\begin_layout Plain Layout
if (x<0.0) return -1.0
\end_layout
\begin_layout Plain Layout
else if (x>0.0) return 1.0
\end_layout
\begin_layout Plain Layout
return 0.0
\end_layout
\begin_layout Plain Layout
}
\end_layout
\end_inset
\begin_inset listings
inline false
status open
\begin_layout Plain Layout
fn qtodirector(q) {
\end_layout
\begin_layout Plain Layout
var S = 2*q.norm()
\end_layout
\begin_layout Plain Layout
var Q = q/S
\end_layout
\begin_layout Plain Layout
var nx = sqrt(Q[0]+0.5)
\end_layout
\begin_layout Plain Layout
var ny = abs(Q[1]/nx)
\end_layout
\begin_layout Plain Layout
nx*=sign(Q[1])
\end_layout
\begin_layout Plain Layout
return Matrix([nx,ny,0])
\end_layout
\begin_layout Plain Layout
}
\end_layout
\end_inset
\begin_inset listings
inline false
status open
\begin_layout Plain Layout
fn qtoorder(q) {
\end_layout
\begin_layout Plain Layout
var S = 2*q.norm()
\end_layout
\begin_layout Plain Layout
return S
\end_layout
\begin_layout Plain Layout
}
\end_layout
\end_inset
\begin_inset listings
inline false
status open
\begin_layout Plain Layout
// Convert the q-tensor to the director and order
\end_layout
\begin_layout Plain Layout
var nn = Field(m, Matrix([1,0,0]))
\end_layout
\begin_layout Plain Layout
for (i in 0...m.count()) nn[i]=qtodirector(q_tensor[i])
\end_layout
\begin_layout Plain Layout
var S = Field(m, 0)
\end_layout
\begin_layout Plain Layout
for (i in 0...m.count()) S[i]=qtoorder(q_tensor[i])
\end_layout
\end_inset
\begin_inset listings
inline false
status open
\begin_layout Plain Layout
// Function to visualize a director field
\end_layout
\begin_layout Plain Layout
fn visualize(m, nn, dl) {
\end_layout
\begin_layout Plain Layout
var v = m.vertexmatrix()
\end_layout
\begin_layout Plain Layout
var nv = v.dimensions()[1]
\end_layout
\begin_layout Plain Layout
var g = Graphics()
\end_layout
\begin_layout Plain Layout
for (i in 0...nv) {
\end_layout
\begin_layout Plain Layout
var x = v.column(i)
\end_layout
\begin_layout Plain Layout
g.display(Cylinder(x-nn[i]*dl, x+nn[i]*dl,
\end_layout
\begin_layout Plain Layout
aspectratio=0.3))
\end_layout
\begin_layout Plain Layout
}
\end_layout
\begin_layout Plain Layout
return g
\end_layout
\begin_layout Plain Layout
}
\end_layout
\begin_layout Plain Layout
\end_layout
\begin_layout Plain Layout
// Visualize the result
\end_layout
\begin_layout Plain Layout
// var g=plotmesh(m, grade=1)
\end_layout
\begin_layout Plain Layout
var splot = plotfield(S, style="interpolate")
\end_layout
\begin_layout Plain Layout
var gnn=visualize(m, nn, 0.05)
\end_layout
\begin_layout Plain Layout
var gdisp = splot+gnn
\end_layout
\begin_layout Plain Layout
Show(gdisp)
\end_layout
\end_inset
We can go further and use the
\family typewriter
povray
\family default
module to render a
\family typewriter
.png
\family default
output:
\begin_inset listings
inline false
status open
\begin_layout Plain Layout
var pov = POVRaytracer(gdisp)
\end_layout
\begin_layout Plain Layout
pov.viewangle=35
\end_layout
\begin_layout Plain Layout
pov.render("Qtensor_K_${K}.pov")
\end_layout
\end_inset
\begin_inset Float figure
wide false
sideways false
status open
\begin_layout Standard
\begin_inset ERT
status collapsed
\begin_layout Plain Layout
\backslash
centering
\end_layout
\end_inset
\begin_inset Graphics
filename Qtensor_K_1.png
width 45line%
\end_inset
\begin_inset Graphics
filename Qtensor_K_0.01.png
width 45line%
\end_inset
\begin_inset Caption Standard
\begin_layout Plain Layout
Final configuration of the director and order for (left)
\begin_inset Formula $K=1$
\end_inset
and (right)
\begin_inset Formula $K=0.01$
\end_inset
. The cylinders indicate the nematic director whereas the color indicates the scalar order parameter. Note how the
\begin_inset Formula $K=1$
\end_inset
case has a single
\begin_inset Formula $+1$
\end_inset
defect at the center whereas the
\begin_inset Formula $K=0.01$
\end_inset
case has two
\begin_inset Formula $+1/2$
\end_inset
defects.
\end_layout
\end_inset
\begin_inset CommandInset label
LatexCommand label
name "fig:qtensor"
\end_inset
\end_layout
\end_inset
\end_layout
\begin_layout Standard
This creates beautiful plots of the nematic, as seen in the example Figure
\begin_inset CommandInset ref
LatexCommand ref
reference "fig:qtensor"
plural "false"
caps "false"
noprefix "false"
\end_inset
. Like the tactoid example, we can do adaptive mesh refinement based on the elastic energy density as well. The full code, along with the optional adaptive refinement can be found under
\family typewriter
examples/qtensor/qtensor.morpho
\family default
.
\end_layout
\end_body
\end_document
================================================
FILE: examples/qtensor/src.tex
================================================
\documentclass{article}
\usepackage[utf8]{inputenc}
\usepackage{physics}
\usepackage{xcolor}
\usepackage{graphicx}
\definecolor{codegray}{rgb}{0.9,0.9,0.9}
\usepackage{listings}
\newcommand{\morpho}{\textit{morpho}}
\newcommand{\Morpho}{\textit{Morpho}}
\title{Q-tensor model of nematics}
\author{Chaitanya Joshi}
\date{October 2021}
\begin{document}
\lstset{
language=Java,
tabsize=4,
basicstyle=\ttfamily,
backgroundcolor=\color{codegray},
showstringspaces=false
}
\maketitle
\section{Introduction}
In 2D, for a uniaxial nematic, we can define a Q-tensor:
\[
Q_{ij} = S (n_i n_j - 1/2 \delta_{ij})
\]
Here, the $-1/2 \delta_{ij}$ is added for convenience, to make the matrix traceless:
\[\text{Tr}(\mathbf{Q}) = Q_{ii} = S(n_i n_i - 1/2 \delta_{ii}) = S(1 - 1/2(2)) = 0
\]
Now, the Q-tensor is also symmetric by definition:
\[
Q_{ij} = Q_{ji}
\]
Due to these two reasons we can write the Q-tensor as a function of only $Q_{xx}$ and $Q_{xy}$:
\[
\mathbf{Q} = \begin{bmatrix}Q_{xx} & Q_{xy} \\ Q_{xy} & -Q_{xx} \end{bmatrix}
\]
\subsection{Simple Passive Nematic Model}
The Landau-de Gennes equilibrium free energy for a nematic liquid crystal can be written in terms of the Q-tensor:
\begin{align*}
F_{LDG} = &\int_\Omega d^2{\bf x} \ \left(\frac{a_2}{2} \text{Tr}(\mathbf{Q}^2) + \frac{a_4}{4} (\text{Tr} \mathbf{Q}^2)^2 + \frac{K}{2}(\nabla\mathbf{Q})^2 \right) \\
&+ \oint_{\partial\Omega} d{\bf x} \frac{1}{2}E_A \text{Tr}[(\mathbf{Q}-\mathbf{W})^2]
\end{align*}
where $a_2 = (\rho-1)$ and $a_4 = (\rho+1)/\rho^2$
set the isotropic to nematic transition with $\rho$ being the non-dimensional density. The system is in the isotropic state for $\rho<1$ and in the nematic phase when $\rho>1$. In the nematic phase, $\ell_n = \sqrt{K/a_2}$ sets the nematic coherence length. Now,
\[
\mathbf{Q}^2 = \begin{bmatrix}Q_{xx} & Q_{xy} \\ Q_{xy} & -Q_{xx} \end{bmatrix} \begin{bmatrix}Q_{xx} & Q_{xy} \\ Q_{xy} & -Q_{xx} \end{bmatrix} = (Q_{xx}^2+Q_{xy}^2) \begin{bmatrix} 1 & 0 \\ 0 & 1 \end{bmatrix}
\]
Hence,
\[
\text{Tr}(\mathbf{Q}^2) = 2(Q_{xx}^2+Q_{xy}^2)
\]
Similarly,
\[
(\nabla \mathbf{Q})^2 = \partial_i Q_{kj}\partial_i Q_{kj} = 2 \{ (\partial_x Q_{xx})^2+(\partial_xQ_{xy})^2 + (\partial_y Q_{xx})^2+(\partial_y Q_{xy})^2 \}
\]
Now, the second term is a boundary integral, with $E_A$ being the anchoring strength. $\mathbf{W}$ is the tensor corresponding to the boundary condition. For instance, for parallel anchoring,
\[
W_{ij} = (t_i t_j - 1/2 \delta_{ij})
\]
where $t_i$ is a component of the tangent vector at the boundary.
$\mathbf{W}$ is also a symmetric traceless tensor with two independent components $W_{xx}$ and $W_{xy}$.
The boundary term becomes:
\[ \text{Tr}[(\mathbf{Q}-\mathbf{W})^2] = 2\{ Q_{xx}^2 + Q_{xy}^2 - 2(Q_{xx}W_{xx} + Q_{xy}W_{xy}) + W_{xx}^2 + W_{xy}^2 \}
\]
\section{Vector formulation}
We can formulate all these expressions in terms of vector quantities:
\[\vec{q} \equiv \{ Q_{xx}, Q_{xy}\}\]
\[\vec{w} \equiv \{ w_{xx}, w_{xy}\}\]
Thus,
\[
\text{Tr}(\mathbf{Q}^2) = 2 ||\vec{q}||^2
\]
\[
(\nabla \mathbf{Q})^2 = 2 ||\nabla \vec{q}||^2
\]
\[
\text{Tr}[(\mathbf{Q}-\mathbf{W})^2] = 2 ||\vec{q}-\vec{w}||^2
\]
With these, we want to minimize the area-integral of
\[
F = \int_\Omega d^2{\bf x} \ \left( a_2 ||\vec{q}||^2 + a_4 ||\vec{q}||^4 + K||\nabla\vec{q}||^2 \right)
\]
together with the line-integral energy
\[
\oint_{\partial\Omega} d{\bf x} \ E_A ||\vec{q}-\vec{w}||^2
\]
\section{\Morpho \ implementation}
This free energy is readily set up in \morpho. For this problem, we will consider a 2D disk geometry with unit radius. We use $\rho=1.3$, so that we are deep in the nematic regime. We fix $E_{\text{A}}=3$, which sets strong anchoring at the boundary. With this strong tangential anchoring, we get a topological charge of $+1$ at the boundary, and this acts as a constraint. When the nematic coherence length is comparable to the disk diameter ($\ell_n \sim R$), the $+1$ charge penetrates throughout the disk, whereas if ($\ell_n \ll R$), then a formation with 2 $+1/2$ defects is more stable. To test this, we use two different values of $K$:, 0.01 and 1.0.
We first define all our parameters and import $\texttt{disk.mesh}$ from the tactoid example:
\begin{lstlisting}
var rho = 1.3 // Deep in the nematic phase
var EA = 3 // Anchoring strength
var K = 0.01 // Bending modulus
var a2 = (1-rho)
var a4 = (1+rho)/rho^2
var m = Mesh("disk.mesh")
var m = refinemesh(m) // Refining for a better result
var bnd = Selection(m, boundary=true)
bnd.addgrade(0) // add point elements
\end{lstlisting}
We define the Q-tensor in its vector form as discussed above, initializing it to small random values:
\begin{lstlisting}
var q_tensor = Field(m, fn(x,y,z)
Matrix([0.01*random(1), 0.01*random(1)]))
\end{lstlisting}
Note that this incidentally makes the director parallel to a 45 degree line.
We now define the bulk energy, the anchoring energy and the distortion free energy as follows:
\begin{lstlisting}
// Define bulk free energy
fn landau(x, q) {
var qt = q.norm()
var qt2=qt*qt
return a2*qt2 + a4*qt2*qt2
}
// Define anchoring energy at the boundary
fn anchoring(x, q) {
var t = tangent()
var wxx = t[0]*t[0]-0.5
var wxy = t[0]*t[1]
return (q[0]-wxx)^2+(q[1]-wxy)^2
}
var bulk = AreaIntegral(landau, q_tensor)
var anchor = LineIntegral(anchoring, q_tensor)
var elastic = GradSq(q_tensor)
\end{lstlisting}
Equipped with the energies, we define the \texttt{OptimizationProblem}:
\begin{lstlisting}
var problem = OptimizationProblem(m)
problem.addenergy(bulk)
problem.addenergy(elastic, prefactor = K)
problem.addenergy(anchor, selection=bnd, prefactor=EA)
\end{lstlisting}
To minimize the energy with respect to the field, we define the \texttt{FieldOptimizer} and perform a \texttt{linesearch}:
\begin{lstlisting}
var opt = FieldOptimizer(problem, q_tensor)
opt.linesearch(500)
\end{lstlisting}
\section{Visualizing the result}
For visualizing the final configuration, we use the same piece of code we used for the tactoid example, and define some additional helper functions to extract the director and the order from the Q-tensor.
\begin{lstlisting}
fn sign(x) {
if (x<0.0) return -1.0
else if (x>0.0) return 1.0
return 0.0
}
\end{lstlisting}
\begin{lstlisting}
fn qtodirector(q) {
var S = 2*q.norm()
var Q = q/S
var nx = sqrt(Q[0]+0.5)
var ny = abs(Q[1]/nx)
nx*=sign(Q[1])
return Matrix([nx,ny,0])
}
\end{lstlisting}
\begin{lstlisting}
fn qtoorder(q) {
var S = 2*q.norm()
return S
}
\end{lstlisting}
\begin{lstlisting}
// Convert the q-tensor to the director and order
var nn = Field(m, Matrix([1,0,0]))
for (i in 0...m.count()) nn[i]=qtodirector(q_tensor[i])
var S = Field(m, 0)
for (i in 0...m.count()) S[i]=qtoorder(q_tensor[i])
\end{lstlisting}
\begin{lstlisting}
// Function to visualize a director field
fn visualize(m, nn, dl) {
var v = m.vertexmatrix()
var nv = v.dimensions()[1]
var g = Graphics()
for (i in 0...nv) {
var x = v.column(i)
g.display(Cylinder(x-nn[i]*dl, x+nn[i]*dl,
aspectratio=0.3))
}
return g
}
// Visualize the result
// var g=plotmesh(m, grade=1)
var splot = plotfield(S, style="interpolate")
var gnn=visualize(m, nn, 0.05)
var gdisp = splot+gnn
Show(gdisp)
\end{lstlisting}
We can go further and use the \texttt{povray} module to render a \texttt{.png} output:
\begin{lstlisting}
var pov = POVRaytracer(gdisp)
pov.viewangle=35
pov.render("Qtensor_K_${K}.pov")
\end{lstlisting}
\begin{figure}
\centering
\includegraphics[width=0.45\linewidth]{Qtensor_K_1.png}
\includegraphics[width=0.45\linewidth]{Qtensor_K_0.01.png}
\caption{Final configuration of the director and order for (left) $K=1$ and (right) $K=0.01$. The cylinders indicate the nematic director whereas the color indicates the scalar order parameter. Note how the $K=1$ case has a single $+1$ defect at the center whereas the $K=0.01$ case has two $+1/2$ defects.}
\label{fig:qtensor}
\end{figure}
This creates beautiful plots of the nematic, as seen in the example Figure \ref{fig:qtensor}.
Like the tactoid example, we can do adaptive mesh refinement based on the elastic energy density as well. The full code, along with the optional adaptive refinement can be found under \texttt{examples/qtensor/qtensor.morpho}.
\end{document}
================================================
FILE: examples/tactoid/disk.mesh
================================================
vertices
1 -1. 0. 0
2 -0.951057 -0.309017 0
3 -0.951057 0.309017 0
4 -0.809017 -0.587785 0
5 -0.809017 0.587785 0
6 -0.587785 -0.809017 0
7 -0.587785 0.809017 0
8 -0.5 -0.5 0
9 -0.5 0. 0
10 -0.5 0.5 0
11 -0.309017 -0.951057 0
12 -0.309017 0.951057 0
13 0. -1. 0
14 0. -0.5 0
15 0. 0. 0
16 0. 0.5 0
17 0. 1. 0
18 0.309017 -0.951057 0
19 0.309017 0.951057 0
20 0.5 -0.5 0
21 0.5 0. 0
22 0.5 0.5 0
23 0.587785 -0.809017 0
24 0.587785 0.809017 0
25 0.809017 -0.587785 0
26 0.809017 0.587785 0
27 0.951057 -0.309017 0
28 0.951057 0.309017 0
29 1. 0. 0
edges
1 8 2
2 2 4
3 4 8
4 4 6
5 6 8
6 11 13
7 13 14
8 14 11
9 8 9
10 9 2
11 14 8
12 8 11
13 13 18
14 18 14
15 6 11
16 14 9
17 3 10
18 10 5
19 5 3
20 9 3
21 3 1
22 1 9
23 10 7
24 7 5
25 10 9
26 9 15
27 15 10
28 12 7
29 10 12
30 10 16
31 16 12
32 1 2
33 14 15
34 14 20
35 20 15
36 18 20
37 18 23
38 23 20
39 20 21
40 21 15
41 27 20
42 20 25
43 25 27
44 21 27
45 27 29
46 29 21
47 23 25
48 21 22
49 22 15
50 16 22
51 22 19
52 19 16
53 16 15
54 19 17
55 17 16
56 22 24
57 24 19
58 17 12
59 26 22
60 22 28
61 28 26
62 26 24
63 21 28
64 29 28
faces
1 8 2 4
2 8 4 6
3 11 13 14
4 2 8 9
5 14 8 11
6 13 18 14
7 11 8 6
8 9 8 14
9 3 10 5
10 9 3 1
11 10 7 5
12 10 9 15
13 12 7 10
14 10 16 12
15 10 3 9
16 1 2 9
17 15 9 14
18 14 20 15
19 20 14 18
20 20 18 23
21 15 20 21
22 27 20 25
23 21 27 29
24 21 20 27
25 25 20 23
26 15 21 22
27 16 22 19
28 16 15 22
29 19 17 16
30 22 24 19
31 16 17 12
32 26 22 28
33 24 22 26
34 22 21 28
35 29 28 21
36 15 16 10
================================================
FILE: examples/tactoid/tactoid.morpho
================================================
import meshtools
import optimize
import plot
import povray
// Create mesh and director field
var m = Mesh("disk.mesh")
var nn = Field(m, Matrix([1,0,0]))
// Create functionals
var lf=Nematic(nn, kbend=1)
var ln=NormSq(nn)
var la=LineIntegral(fn (x, n) n.inner(tangent())^2, nn)
var lt=Length()
var laa=Area()
var leq=EquiElement()
// Initial boundary selection
var bnd=Selection(m, boundary=true)
bnd.addgrade(0)
// Material parameters
var sigma=5.0*0.04 // Surface tension
var W=3.0 // Anchoring
var itermax = 4
// Set up the optimization problem
var problem = OptimizationProblem(m)
problem.addenergy(lf)
problem.addenergy(la, selection=bnd, prefactor=-W/2)
problem.addenergy(lt, selection=bnd, prefactor=sigma+W)
problem.addconstraint(laa)
problem.addlocalconstraint(ln, field=nn, target=1)
// Set up a regularization problem
var reg = OptimizationProblem(m)
reg.addenergy(leq)
// Create shape and field optimizers
var sopt = ShapeOptimizer(problem, m)
var fopt = FieldOptimizer(problem, nn)
var ropt = ShapeOptimizer(reg, m)
ropt.fix(bnd)
// Set up initial stepsize
sopt.stepsize=0.05
sopt.steplimit=0.1
var mr, refmap // Refinement
// A function we'll use to check each contribution to the energy
fn checkenergy(problem, opt) {
print "--Contributions to energy"
for (en in problem.energies) {
print en.functional.clss()
print opt.total(en)
}
}
// Main optimization loop
for (iter in 1..itermax) {
for (i in 1..10) {
if (iter<itermax) {
print "-Regularize"
leq.weight=lf.integrand(nn)
ropt.stepsize=0.0001/iter
ropt.steplimit=0.0001/iter
ropt.linesearch(2)
equiangulate(m)
}
print "-Field"
fopt.conjugategradient(200)
print "-Shape"
sopt.conjugategradient(50)
}
// Check each contribution to the energy
checkenergy(problem, sopt)
// Refine if necessary
if (iter<itermax) {
// Select elements that have a large contribution to the energy
var en = lf.integrand(nn)
var mean = en.sum()/en.count()
var srefine = Selection(m)
for (id in 0...en.count()) if (en[0,id]>1.5*mean) srefine[2,id]=true
// Create a mesh refiner
mr=MeshRefiner([m, nn, bnd])
if (srefine.count(2)>0) {
refmap = mr.refine(selection=srefine)
} else {
refmap = mr.refine()
}
// Now refinement is done update the problems and optimizers
for (el in [problem, reg, sopt, fopt, ropt]) el.update(refmap)
// Use the new mesh and field
m = refmap[m]
nn = refmap[nn]
bnd = refmap[bnd]
// Must ensure boundary remains correctly fixed
ropt.fixed=[]
ropt.fix(Selection(m, boundary=true))
// Equiangulate
equiangulate(m)
}
// Reduce stepsize
sopt.stepsize=0.05/iter
sopt.steplimit=0.1/iter
}
// Function to visualize a director field
// m - the mesh
// nn - the director Field to visualize
// dl - scale the director
fn visualize(m, nn, dl) {
var v = m.vertexmatrix()
var nv = m.count()
var g = Graphics()
for (i in 0...nv) {
var x = v.column(i)
g.display(Cylinder(x-nn[i]*dl, x+nn[i]*dl, aspectratio=0.3))
}
return g
}
// Visualize the result
var g=plotmesh(m, grade=1)
var gnn=visualize(m, nn, 0.2/itermax)
var gdisp = g+gnn
Show(gdisp)
// Visualize the elastic energy density
var fe = lf.integrand(nn)
var ff = Field(m, grade=2)
for (i in 0...m.count(2)) {
ff[2,i]=fe[0,i]
}
var sb = ScaleBar(nticks=3, // Maximum number of ticks
length=1, // Length of scalebar
posn=[0,-1,0], // Position of scalebar
dirn=[1,0,0], // Direction in which scalebar is to be drawn
tickdirn=[0,-1,0], // Direction in which to draw ticks
textdirn=[1,0,0], // Direction to draw text
textvertical=[0,1,0], // Vertical direction for text
textcolor=White, // Text color
fontsize=6 ) // Font size
Show(plotfield(ff, colormap=GrayMap(), scalebar=sb))
gdisp.background = White
var pov = POVRaytracer(gdisp)
pov.viewpoint = Matrix([0,0,10])
pov.background = White
pov.light=[Matrix([10,10,10]), Matrix([-10,-10,10])]
pov.render("out.pov")
================================================
FILE: examples/tactoid/tactoid2dmesh.morpho
================================================
import meshtools
import optimize
import plot
import povray
import meshgen
// Create mesh and director field
var dom = fn (x) -(x[0]^2+x[1]^2-1)
var mg = MeshGen(dom, [-1..1:0.2, -1..1:0.2])
var m = mg.build()
var nn = Field(m, Matrix([1,0,0]))
// Create functionals
var lf=Nematic(nn, kbend=1)
var ln=NormSq(nn)
fn integrand(x, n) {
var t = tangent()
return (n[0]*t[0]+n[1]*t[1])^2
}
var la=LineIntegral(integrand, nn)
var lt=Length()
var laa=Area()
var leq=EquiElement()
// Initial boundary selection
var bnd=Selection(m, boundary=true)
bnd.addgrade(0)
// Material parameters
var sigma=5.0*0.04 // Surface tension
var W=3.0 // Anchoring
var itermax = 4
// Set up the optimization problem
var problem = OptimizationProblem(m)
problem.addenergy(lf)
problem.addenergy(la, selection=bnd, prefactor=-W/2)
problem.addenergy(lt, selection=bnd, prefactor=sigma+W)
problem.addconstraint(laa)
problem.addlocalconstraint(ln, field=nn, target=1)
// Set up a regularization problem
var reg = OptimizationProblem(m)
reg.addenergy(leq)
// Create shape and field optimizers
var sopt = ShapeOptimizer(problem, m)
var fopt = FieldOptimizer(problem, nn)
var ropt = ShapeOptimizer(reg, m)
ropt.fix(bnd)
// Set up initial stepsize
sopt.stepsize=0.05
sopt.steplimit=0.1
var mr, refmap // Refinement
// A function we'll use to check each contribution to the energy
fn checkenergy(problem, opt) {
print "--Contributions to energy"
for (en in problem.energies) {
print en.functional.clss()
print opt.total(en)
}
}
// Main optimization loop
for (iter in 1..itermax) {
for (i in 1..10) {
if (iter<itermax) {
print "-Regularize"
leq.weight=lf.integrand(nn)
ropt.stepsize=0.0001/iter
ropt.steplimit=0.0001/iter
ropt.linesearch(2)
equiangulate(m)
}
print "-Field"
fopt.conjugategradient(200)
print "-Shape"
sopt.conjugategradient(50)
}
// Check each contribution to the energy
checkenergy(problem, sopt)
// Refine if necessary
if (iter<itermax) {
// Select elements that have a large contribution to the energy
var en = lf.integrand(nn)
var mean = en.sum()/en.count()
var srefine = Selection(m)
for (id in 0...en.count()) if (en[0,id]>1.5*mean) srefine[2,id]=true
// Create a mesh refiner
mr=MeshRefiner([m, nn, bnd])
if (srefine.count(2)>0) {
refmap = mr.refine(selection=srefine)
} else {
refmap = mr.refine()
}
// Now refinement is done update the problems and optimizers
for (el in [problem, reg, sopt, fopt, ropt]) el.update(refmap)
// Use the new mesh and field
m = refmap[m]
nn = refmap[nn]
bnd = refmap[bnd]
// Must ensure boundary remains correctly fixed
ropt.fixed=[]
ropt.fix(Selection(m, boundary=true))
// Equiangulate
equiangulate(m)
}
// Reduce stepsize
sopt.stepsize=0.05/iter
sopt.steplimit=0.1/iter
}
// Function to visualize a director field
// m - the mesh
// nn - the director Field to visualize
// dl - scale the director
fn visualize(m, nn, dl) {
var v = m.vertexmatrix()
var nv = m.count()
var g = Graphics()
for (i in 0...nv) {
var x = v.column(i)
var y = Matrix([x[0], x[1], 0])
g.display(Cylinder(y-nn[i]*dl, y+nn[i]*dl, aspectratio=0.3))
}
return g
}
//System.exit()
// Visualize the result
var g=plotmesh(m, grade=1)
var gnn=visualize(m, nn, 0.2/itermax)
var gdisp = g+gnn
Show(gdisp)
// Visualize the elastic energy density
var fe = lf.integrand(nn)
var ff = Field(m, grade=2)
for (i in 0...m.count(2)) {
ff[2,i]=fe[0,i]
}
var sb = ScaleBar(nticks=3, // Maximum number of ticks
length=1, // Length of scalebar
posn=[0,-1,0], // Position of scalebar
dirn=[1,0,0], // Direction in which scalebar is to be drawn
tickdirn=[0,-1,0], // Direction in which to draw ticks
textdirn=[1,0,0], // Direction to draw text
textvertical=[0,1,0], // Vertical direction for text
textcolor=White, // Text color
fontsize=6 ) // Font size
Show(plotfield(ff, colormap=GrayMap(), scalebar=sb))
gdisp.background = White
var pov = POVRaytracer(gdisp)
pov.viewpoint = Matrix([0,0,10])
pov.background = White
pov.light=[Matrix([10,10,10]), Matrix([-10,-10,10])]
pov.render("out.pov")
================================================
FILE: examples/thomson/thomson.morpho
================================================
// Thomson problem of arranging charges on a sphere
// to minimize the electrostatic energy
// Showcases: MeshBuilder, PairwisePotential, ScalarPotential
import meshtools
import plot
import optimize
import functionals
var Np = 100 // Number of particles
// Create the mesh, which consists of Np random points each representing
// a charge on the unit sphere.
var build = MeshBuilder()
for (i in 1..Np) {
var x = Matrix([2*random()-1, 2*random()-1, 2*random()-1])
x/=x.norm() // Project onto unit sphere
build.addvertex(x)
}
var mesh = build.build() // Tell the MeshBuilder to build the mesh
// Specify the problem
var problem = OptimizationProblem(mesh)
// The particle repel one another by a Coulomb potential.
// We supply the potential and it's derivative wrt r as anonymous functions.
var lv = PairwisePotential(fn (r) 1/r, fn (r) -1/r^2)
problem.addenergy(lv)
// Constrain the particles on the unit sphere via a level set constraint.
// The level set function and its gradient are supplied as anonymous functions.
var lsph = ScalarPotential(fn (x,y,z) x^2+y^2+z^2-1, fn (x,y,z) Matrix([2*x, 2*y, 2*z]))
problem.addlocalconstraint(lsph)
// Set up the optimizer to optimize this problem wrt the mesh vertex positions.
var opt = ShapeOptimizer(problem, mesh)
// Choose a stepsize
opt.stepsize=0.01/sqrt(Np)
// Do a few iterations at fixed stepsize to move away from the initally random
// condition. [This helps condition the problem]
opt.relax(5)
// Now perform gradient descent
opt.conjugategradient(1000) // Perform up to 1000 iterations of direct gradient descent
// Visualize the results
var g = Graphics()
for (i in 0...mesh.count()) {
// Display each particle as a sphere
g.display(Sphere(mesh.vertexposition(i),1/sqrt(Np)))
}
Show(g) // Open up the viewer application
================================================
FILE: examples/tutorial/disk.mesh
================================================
vertices
1 -1. 0. 0
2 -0.951057 -0.309017 0
3 -0.951057 0.309017 0
4 -0.809017 -0.587785 0
5 -0.809017 0.587785 0
6 -0.587785 -0.809017 0
7 -0.587785 0.809017 0
8 -0.5 -0.5 0
9 -0.5 0. 0
10 -0.5 0.5 0
11 -0.309017 -0.951057 0
12 -0.309017 0.951057 0
13 0. -1. 0
14 0. -0.5 0
15 0. 0. 0
16 0. 0.5 0
17 0. 1. 0
18 0.309017 -0.951057 0
19 0.309017 0.951057 0
20 0.5 -0.5 0
21 0.5 0. 0
22 0.5 0.5 0
23 0.587785 -0.809017 0
24 0.587785 0.809017 0
25 0.809017 -0.587785 0
26 0.809017 0.587785 0
27 0.951057 -0.309017 0
28 0.951057 0.309017 0
29 1. 0. 0
edges
1 8 2
2 2 4
3 4 8
4 4 6
5 6 8
6 11 13
7 13 14
8 14 11
9 8 9
10 9 2
11 14 8
12 8 11
13 13 18
14 18 14
15 6 11
16 14 9
17 3 10
18 10 5
19 5 3
20 9 3
21 3 1
22 1 9
23 10 7
24 7 5
25 10 9
26 9 15
27 15 10
28 12 7
29 10 12
30 10 16
31 16 12
32 1 2
33 14 15
34 14 20
35 20 15
36 18 20
37 18 23
38 23 20
39 20 21
40 21 15
41 27 20
42 20 25
43 25 27
44 21 27
45 27 29
46 29 21
47 23 25
48 21 22
49 22 15
50 16 22
51 22 19
52 19 16
53 16 15
54 19 17
55 17 16
56 22 24
57 24 19
58 17 12
59 26 22
60 22 28
61 28 26
62 26 24
63 21 28
64 29 28
faces
1 8 2 4
2 8 4 6
3 11 13 14
4 2 8 9
5 14 8 11
6 13 18 14
7 11 8 6
8 9 8 14
9 3 10 5
10 9 3 1
11 10 7 5
12 10 9 15
13 12 7 10
14 10 16 12
15 10 3 9
16 1 2 9
17 15 9 14
18 14 20 15
19 20 14 18
20 20 18 23
21 15 20 21
22 27 20 25
23 21 27 29
24 21 20 27
25 25 20 23
26 15 21 22
27 16 22 19
28 16 15 22
29 19 17 16
30 22 24 19
31 16 17 12
32 26 22 28
33 24 22 26
34 22 21 28
35 29 28 21
36 15 16 10
================================================
FILE: examples/tutorial/tutorial.morpho
================================================
// Morpho tutorial example
import meshtools
import optimize
import plot
var m = Mesh("disk.mesh")
// Initial boundary selection
var bnd=Selection(m, boundary=true)
bnd.addgrade(0)
//Show(plotselection(m, bnd, grade=1))
var nn = Field(m, Matrix([1,0,0]))
// Define functionals
var lf=Nematic(nn)
var lt=Length()
var la=LineIntegral(fn (x, n) n.inner(tangent())^2, nn)
var ln=NormSq(nn)
var laa=Area()
// Set up the optimization problem
var W = 1
var sigma = 1
var problem = OptimizationProblem(m)
problem.addenergy(lf)
problem.addenergy(la, selection=bnd, prefactor=-W/2)
problem.addenergy(lt, selection=bnd, prefactor=sigma)
problem.addconstraint(laa)
problem.addlocalconstraint(ln, field=nn, target=1)
// Create shape and field optimizers
var sopt = ShapeOptimizer(problem, m)
var fopt = FieldOptimizer(problem, nn)
// Optimization loop
for (i in 1..100) {
fopt.linesearch(20)
sopt.linesearch(20)
}
// Visualize results
var g=plotmesh(m, grade=1)
// Function to visualize a director field
// m - the mesh
// nn - the director Field to visualize
// dl - scale the director
fn visualize(m, nn, dl) {
var v = m.vertexmatrix()
var nv = m.count() // Number of vertices
var g = Graphics() // Create a graphics object
for (i in 0...nv) {
var x = v.column(i) // Get the ith vertex
// Draw a cylinder aligned with nn at this vertex
g.display(Cylinder(x-nn[i]*dl, x+nn[i]*dl, aspectratio=0.3))
}
return g
}
var gnn=visualize(m, nn, 0.2)
var gdisp = g+gnn
Show(gdisp)
================================================
FILE: examples/tutorial/tutorial2.morpho
================================================
// Morpho tutorial example
import meshtools
import optimize
import plot
var m = Mesh("disk.mesh")
// Initial boundary selection
var bnd=Selection(m, boundary=true)
bnd.addgrade(0)
//Show(plotselection(m, bnd, grade=1))
var nn = Field(m, Matrix([1,0,0]))
// Define functionals
var lf=Nematic(nn)
var lt=Length()
var la=LineIntegral(fn (x, n) n.inner(tangent())^2, nn)
var ln=NormSq(nn)
var laa=Area()
// Set up the optimization problem
var W = 1
var sigma = 1
var problem = OptimizationProblem(m)
problem.addenergy(lf)
problem.addenergy(la, selection=bnd, prefactor=-W/2)
problem.addenergy(lt, selection=bnd, prefactor=sigma)
problem.addconstraint(laa)
problem.addlocalconstraint(ln, field=nn, target=1)
// Create shape and field optimizers
var sopt = ShapeOptimizer(problem, m)
var fopt = FieldOptimizer(problem, nn)
// Optimization loop
var refmax = 3
for (refiter in 1..refmax) {
print "===Refinement level ${refiter}==="
for (i in 1..100) {
fopt.linesearch(20)
sopt.linesearch(20)
}
// Refinement
if (refiter==refmax) break
var mr=MeshRefiner([m, nn, bnd]) // Set the refiner up
var refmap=mr.refine() // Perform the refinement
for (el in [problem, sopt, fopt]) el.update(refmap) // Update the problem
m=refmap[m]; nn=refmap[nn]; bnd=refmap[bnd] // Update variables
}
// Visualize results
var g=plotmesh(m, grade=1)
// Function to visualize a director field
// m - the mesh
// nn - the director Field to visualize
// dl - scale the director
fn visualize(m, nn, dl) {
var v = m.vertexmatrix()
var nv = m.count() // Number of vertices
var g = Graphics() // Create a graphics object
for (i in 0...nv) {
var x = v.column(i) // Get the ith vertex
// Draw a cylinder aligned with nn at this vertex
g.display(Cylinder(x-nn[i]*dl, x+nn[i]*dl, aspectratio=0.3))
}
return g
}
var gnn=visualize(m, nn, 0.2/refmax)
var gdisp = g+gnn
Show(gdisp)
================================================
FILE: examples/wrap/wrap.morpho
================================================
/* Finds a minimal surface that connects two ellipsoids.
This models a fluid interface between two colloidal particles, for example */
import graphics
import meshtools
import plot
import optimize
// Create a initial cube
var L = 2
var cube = [[-L, -L, -L], [-L, -L, L], [-L, L, -L],
[-L, L, L], [L, -L, -L], [L, -L, L],
[L, L, -L], [L, L, L]]
var faces = [[7, 3, 1, 5], [7, 5, 4, 6], [7, 6, 2, 3], [3, 2, 0, 1], [0, 2, 6,
4], [1, 0, 4, 5]]
var m=PolyhedronMesh(cube, faces)
m=refinemesh(m)
// Make a class to manufacture axis aligned ellipsoids.
// To create one, call Ellipsoid(origin, principalradii)
class Ellipsoid {
init(x, r) {
self.origin = x
self.principalradii = r
}
// Returns a level set function for this Ellipsoid
levelset() {
fn phi (x,y,z) {
var x0 = self.origin, rr = self.principalradii
return ((x-x0[0])/rr[0])^2 + ((y-x0[1])/rr[1])^2 + ((z-x0[2])/rr[2])^2 - 1
}
return phi
}
// Returns the a function that returns the gradient
// of the level set function for this Ellipsoid
gradient() {
fn dphi (x,y,z) {
var x0 = self.origin, rr = self.principalradii
return Matrix([2*(x-x0[0])/rr[0]^2,
2*(y-x0[1])/rr[1]^2,
2*(z-x0[2])/rr[2]^2])
}
return dphi
}
}
// Now use this to manufacture some Ellipsoids
var ell1 = Ellipsoid([0,1/2,0],[1/2,1/2,1])
var ell2 = Ellipsoid([0,-1/2,0],[1,1/2,1/2])
// We want to minimize the area
var la = Area()
// Subject to level set constraints
var ls1 = ScalarPotential( ell1.levelset(), ell1.gradient() )
var ls2 = ScalarPotential( ell2.levelset(), ell2.gradient() )
var leq = EquiElement()
var problem = OptimizationProblem(m)
problem.addenergy(la)
problem.addlocalconstraint(ls1, onesided=true)
problem.addlocalconstraint(ls2, onesided=true)
var reg = OptimizationProblem(m)
reg.addenergy(leq)
reg.addlocalconstraint(ls1, onesided=true)
reg.addlocalconstraint(ls2, onesided=true)
var sopt = ShapeOptimizer(problem, m)
var ropt = ShapeOptimizer(reg, m)
sopt.stepsize=0.025
sopt.steplimit=0.1
sopt.ctol = 1e-9
sopt.maxconstraintsteps = 100
ropt.stepsize=0.01
ropt.steplimit=0.2
for (refine in 1..3) {
for (i in 1..100) {
sopt.relax(5)
ropt.conjugategradient(5)
equiangulate(m)
}
var mr=MeshRefiner([m])
var refmap = mr.refine()
for (el in [problem, reg, sopt, ropt]) el.update(refmap)
m = refmap[m]
}
Show(plotmesh(m, grade=2))
================================================
FILE: help/Makefile
================================================
# Minimal makefile for Sphinx documentation
#
# You can set these variables from the command line, and also
# from the environment for the first two.
SPHINXOPTS ?=
SPHINXBUILD ?= sphinx-build
SOURCEDIR = .
BUILDDIR = _build
# Put it first so that "make" without argument is like "make help".
help:
@$(SPHINXBUILD) -M help "$(SOURCEDIR)" "$(BUILDDIR)" $(SPHINXOPTS) $(O)
.PHONY: help Makefile
# Catch-all target: route all unknown targets to Sphinx using the new
# "make mode" option. $(O) is meant as a shortcut for $(SPHINXOPTS).
%: Makefile
@$(SPHINXBUILD) -M $@ "$(SOURCEDIR)" "$(BUILDDIR)" $(SPHINXOPTS) $(O)
================================================
FILE: help/array.md
================================================
[comment]: # (Array class help)
[version]: # (0.5)
# Array
[tagarray]: # (Array)
Arrays are collection objects that can have any number of indices. Their size is set when they are created:
var a[5]
var b[2,2]
var c[nv,nv,nv]
Values can be retrieved with appropriate indices:
print a[0,0]
Arrays can be indexed with slices:
print a[[0,2,4],2]
print a[1,0..2]
Any morpho value can be stored in an array element
a[0,0] = [1,2,3]
[showsubtopics]: # (subtopics)
## Dimensions
[tagdimensions]: # (Dimensions)
Get the dimensions of an Array object:
var a[2,2]
print a.dimensions() // expect: [ 2, 2 ]
================================================
FILE: help/builtin.md
================================================
[comment]: # (Builtin function help)
[version]: # (0.5)
# Builtin functions
[tagbuiltin]: # (builtin)
Morpho provides a number of built-in functions.
[showsubtopics]: # (subtopics)
## Random
[tagrandom]: # (random)
[tagrand]: # (rand)
The `random` function generates a random number from a uniform distribution on the interval [0,1].
print random()
See also `randomnormal` and `randomint`.
## Randomnormal
[tagrandomnormal]: # (randomnormal)
The `randomnormal` function generates a random number from a normal (gaussian) distribution with unit variance and zero offset.
print randomnormal()
See also `random` and `randomint`.
## Randomint
[tagrandomint]: # (randomint)
The `randomint` function generates a random integer with a specified maximum value.
print randomint(10) // Generates a random integer [0,10)
## isnil
[tagisnil]: # (isnil)
Returns `true` if a value is `nil` or `false` otherwise.
## isint
[tagisint]: # (isint)
Returns `true` if a value is an integer or `false` otherwise.
## isfloat
[tagisfloat]: # (isfloat)
Returns `true` if a value is a floating point number or `false` otherwise.
## isbool
[tagisbool]: # (isbool)
Returns `true` if a value is a boolean or `false` otherwise.
## isobject
[tagisobject]: # (isobject)
Returns `true` if a value is an object or `false` otherwise.
## isstring
[tagisstring]: # (isstring)
Returns `true` if a value is a string or `false` otherwise.
## isclass
[tagisclass]: # (isclass)
Returns `true` if a value is a class or `false` otherwise.
## isrange
[tagisrange]: # (isrange)
Returns `true` if a value is a range or `false` otherwise.
## isdictionary
[tagisdictionary]: # (isdictionary)
Returns `true` if a value is a dictionary or `false` otherwise.
## islist
[tagislist]: # (islist)
Returns `true` if a value is a list or `false` otherwise.
## isarray
[tagisarray]: # (isarray)
Returns `true` if a value is an array or `false` otherwise.
## ismatrix
[tagismatrix]: # (ismatrix)
Returns `true` if a value is a matrix or `false` otherwise.
## issparse
[tagissparse]: # (issparse)
Returns `true` if a value is a sparse matrix or `false` otherwise.
## isinf
[tagisinf]: # (isinf)
Returns `true` if a value is infinite or `false` otherwise.
## isnan
[tagisnan]: # (isnan)
Returns `true` if a value is a Not a Number or `false` otherwise.
## iscallable
[tagiscallable]: # (iscallable)
Returns `true` if a value is callable or `false` otherwise.
## isfinite
[tagisfinite]: # (isfinite)
Returns `true` if a value is finite or `false` otherwise.
print isfinite(1) // expect: true
print isfinite(1/0) // expect: false
## isnumber
[tagisnumber]: # (isnumber)
Returns `true` if a value is a real number, or `false` otherwise.
print isnumber(1) // expect: true
print isnumber(Object()) // expect: false
## ismesh
[tagismesh]: # (ismesh)
Returns `true` if a value is a `Mesh`, or `false` otherwise.
## isselection
[tagisselection]: # (isselection)
Returns `true` if a value is a `Selection`, or `false` otherwise.
## isfield
[tagisfield]: # (isfield)
Returns `true` if a value is a `Field`, or `false` otherwise.
## Apply
[tagapply]: # (apply)
Apply calls a function with the arguments provided as a list:
apply(f, [0.5, 0.5]) // calls f(0.5, 0.5)
It's often useful where a function or method and/or the number of parameters isn't known ahead of time. The first parameter to apply can be any callable object, including a method invocation or a closure.
You may also instead omit the list and use apply with multiple arguments:
apply(f, 0.5, 0.5) // calls f(0.5, 0.5)
There is one edge case that occurs when you want to call a function that accepts a single list as a parameter. In this case, enclose the list in another list:
apply(f, [[1,2]]) // equivalent to f([1,2])
## Abs
[tagabs]: # (abs)
Returns the absolute value of a number:
print abs(-10) // prints 10
## Sign
[tagsign]: # (sign)
Gives the sign of a number:
print sign(4) // expect: 1
print sign(-10.0) // expect: -1
print sign(0) // expect: 0
## Arctan
[tagarctan]: # (arctan)
Returns the arctangent of an input value that lies from `-Inf` to `Inf`. You can use one argument:
print arctan(0) // expect: 0
or use two arguments to return the angle in the correct quadrant:
print arctan(x, y)
Note the order `x`, `y` differs from some other languages.
## Exp
[tagexp]: # (exp)
Exponential function `e^x`. Inverse of `log`.
print exp(0) // expect: 1
print exp(Pi*im) // expect: -1 + 0im
## Log
[taglog]: # (log)
Natural logarithm function. Inverse of `exp`.
print log(1) // expect: 0
## Log10
[taglog10]: # (log10)
Base 10 logarithm function.
print log10(10) // expect: 1
## Sin
[tagsin]: # (sin)
Sine trigonometric function.
print sin(0) // expect: 0
## Sinh
[tagsinh]: # (sinh)
Hyperbolic sine trigonometric function.
print sinh(0) // expect: 0
## Cos
[tagcos]: # (cos)
Cosine trigonometric function.
print cos(0) // expect: 1
## Cosh
[tagcosh]: # (cosh)
Hyperbolic cosine trigonometric function.
print cosh(0) // expect: 1
## Tan
[tagtan]: # (tan)
Tangent trigonometric function.
print tan(0) // expect: 0
## Tanh
[tagtanh]: # (tanh)
Hyperbolic tangent trigonometric function.
print tanh(0) // expect: 0
## Asin
[tagasin]: # (asin)
Inverse sine trigonometric function. Returns a value on the interval `[-Pi/2,Pi/2]`.
print asin(0) // expect: 0
## Acos
[tagacos]: # (acos)
Inverse cosine trigonometric function. Returns a value on the interval `[-Pi/2,Pi/2]`.
print acos(1) // expect: 0
## Sqrt
[tagsqrt]: # (sqrt)
Square root function.
print sqrt(4) // expect: 2
## Min
[tagmin]: # (min)
Finds the minimum value of its arguments. If any of the arguments are Objects and are enumerable, (e.g. a `List`), `min` will search inside them for a minimum value. Accepts any number of arguments.
print min(3,2,1) // expect: 1
print min([3,2,1]) // expect: 1
print min([3,2,1],[0,-1,2]) // expect: -2
## Max
[tagmax]: # (max)
Finds the maximum value of its arguments. If any of the arguments are Objects and are enumerable, (e.g. a `List`), `max` will search inside them for a maximum value. Accepts any number of arguments.
print min(3,2,1) // expect: 3
print min([3,2,1]) // expect: 3
print min([3,2,1],[0,-1,2]) // expect: 3
## Bounds
[tagbounds]: # (bounds)
Returns both the results of `min` and `max` as a list, Providing a set of bounds for its arguments and any enumerable objects within them.
print bounds(1,2,3) // expect: [1,3]
print bounds([3,2,1],[0,-1,2]) // expect: [-1,3]
================================================
FILE: help/classes.md
================================================
[comment]: # (Morpho classes help file)
[version]: # (0.5)
[toplevel]: #
# Classes
[tagclass]: # (class)
[tagmethod]: # (method)
Classes are defined using the `class` keyword followed by the name of the class.
The definition includes methods that the class responds to. The special `init` method
is called whenever an object is created.
class Cake {
init(type) {
self.type = type
}
eat() {
print "A delicious "+self.type+" cake"
}
}
Objects are created by calling the class as if it was a function:
var c = Cake("carrot")
Note that all objects in Morpho inherit from a base `Object` class, which provides a set of standard methods.
See also `Object`.
[showsubtopics]: # (subtopics)
## Methods
[tagmethods]: # (methods)
Classes in morpho can define *methods* to manipulate the objects defined by the class. Like functions, multiple implementations can be defined that accept different parameter types [see also topic: `signature`]:
class Foo {
a(List x) { print "A list!" }
a(String x) { print "A string!" }
a(Matrix x) { print "A matrix!" }
}
Having created an object with the class,
var x = Foo()
the correct implementation is selected at runtime:
x.a([1,2]) // expect: A list!
x.a("Hello") // expect: A string!
## Is
[tagis]: # (is)
The `is` keyword is used to specify a class's superclass:
class A is B {
}
All methods defined by the superclass `B` are copied into the new class `A`, *before* any methods specified in the class definition. Hence, you can replace methods from the superclass simply by defining a method with the same name.
## With
[tagwith]: # (with)
[tagmixin]: # (mixin)
The `with` keyword is used together with `is` to insert additional methods into a class definition *without* making them the superclass. These are often called `mixins`. These methods are inserted after the superclass's methods. Multiple classes can be specified after `with`; they are added in the order specified.
class A is B with C, D {
}
Here `B` is the superclass of `A`, but methods defined by `C` and `D` are also available to `A`. If `B`, `C` and `D` define methods with the same name, those in `C` take precedence over any in `B` and those in `D` take precedence over `B` and `C`.
## Self
[tagself]: # (self)
The `self` keyword is used to access an object's properties and methods from within its definition.
class Vehicle {
init (type) { self.type = type }
drive () { print "Driving my ${self.type}." }
}
## Super
[tagsuper]: # (super)
The keyword `super` allows you to access methods provided by an object's superclass rather than its own. This is particularly useful when the programmer wants a class to extend the functionality of a parent class, but needs to make sure the old behavior is still maintained.
For example, consider the following pair of classes:
class Lunch {
init(type) { self.type=type }
}
class Soup is Lunch {
init(type) {
print "Delicious soup!"
super.init(type)
}
}
The subclass Soup uses `super` to call the original initializer.
# Objects
[tagobject]: # (object)
[tagobjects]: # (objects)
[tagproperty]: # (property)
[tagproperties]: # (properties)
Objects in Morpho are created by calling a constructor function, which usually has the same name as the class of the object:
var a = Color(0.5,0.5,0.5) // 50% gray
You can store information in an object by assigning to its properties:
a.prop = "Foo"
and you can read from them similarly:
print a.prop
An object's `class` determines the methods that can be used on the object. You call them using the . operator:
print a.clone()
See also `class`.
[showsubtopics]: # (subtopics)
## Has
[taghas]: # (has)
The `has` method is used to test if an object has a particular property:
print a.has("foo")
If you call `has` with no parameters,
print a.has()
it returns a list of all property labels that an object has.
## Respondsto
[tagrespondsto]: # (respondsto)
The `respondsto` method is used to test if an object provides a particular method:
print a.respondsto("foo")
If you call `respondsto` with no parameters,
print a.respondsto()
it returns a list of all methods that an object has available.
## Invoke
[taginvoke]: # (invoke)
The `invoke` method is used to invoke a method from its label and a list of parameters:
print a.invoke("has", "foo")
is equivalent to:
print a.has("foo")
## Clss
[tagclss]: # (clss)
The `clss` method is used to get the class to which an object belongs.
print a.clss()
================================================
FILE: help/color.md
================================================
[comment]: # (Color module help)
[version]: # (0.5)
# Color
[tagcolor]: # (color)
The `color` module provides support for working with color. Colors are represented in morpho by `Color` objects. The module predefines some colors including `Red`, `Green`, `Blue`, `Black`, `White`.
To use the module, use import as usual:
import color
Create a Color object from an RGB pair:
var col = Color(0.5,0.5,0.5) // A 50% gray
The `color` module also provides `ColorMap`s, which are give a sequence of colors as a function of a parameter; these are useful for plotting the values of a `Field` for example.
[showsubtopics]: # (subtopics)
## RGB
[tagrgb]: # (rgb)
Gets the rgb components of a `Color` or `ColorMap` object as a list. Takes a single argument in the range 0 to 1, although the result will only depend on this argument if the object is a `ColorMap`.
var col = Color(0.1,0.5,0.7)
print col.rgb(0)
## Red
[tagred]: # (red)
Built in `Color` object for use with the `graphics` and `plot` modules.
## Green
[taggreen]: # (green)
Built in `Color` object for use with the `graphics` and `plot` modules.
## Blue
[tagblue]: # (blue)
Built in `Color` object for use with the `graphics` and `plot` modules.
## White
[tagwhite]: # (white)
Built in `Color` object for use with the `graphics` and `plot` modules.
## Black
[tagblack]: # (black)
Built in `Color` object for use with the `graphics` and `plot` modules.
## Cyan
[tagcyan]: # (cyan)
Built in `Color` object for use with the `graphics` and `plot` modules.
## Magenta
[tagmagenta]: # (magenta)
Built in `Color` object for use with the `graphics` and `plot` modules.
## Yellow
[tagyellow]: # (yellow)
Built in `Color` object for use with the `graphics` and `plot` modules.
## Brown
[tagbrown]: # (brown)
Built in `Color` object for use with the `graphics` and `plot` modules.
## Orange
[tagorange]: # (orange)
Built in `Color` object for use with the `graphics` and `plot` modules.
## Pink
[tagpink]: # (pink)
Built in `Color` object for use with the `graphics` and `plot` modules.
## Purple
[tagpurple]: # (purple)
Built in `Color` object for use with the `graphics` and `plot` modules.
## Colormap
[tagcolormap]: # (colormap)
The `color` module provides `ColorMap`s which are subclasses of `Color` that map a single parameter in the range 0 to 1 onto a continuum of colors. `Color`s and `Colormap`s have the same interface.
Get the red, green or blue components of a color or colormap:
var col = HueMap()
print col.red(0.5) // argument can be in range 0 to 1
Get all three components as a list:
col.rgb(0)
Create a grayscale:
var c = Gray(0.2) // 20% gray
Available ColorMaps: `GradientMap`, `GrayMap`, `HueMap`, `ViridisMap`, `MagmaMap`, `InfernoMap` and `PlasmaMap`.
## GradientMap
[taggradientmap]: # (gradientmap)
`GradientMap` is a `Colormap` that displays a white-green-purple sequence.
## GrayMap
[taggraymap]: # (graymap)
`GrayMap` is a `Colormap` that displays grayscales.
## HueMap
[taghuemap]: # (huemap)
`HueMap` is a `Colormap` that displays vivid colors. It is periodic on the interval 0 to 1.
## ViridisMap
[tagviridismap]: # (viridismap)
`ViridisMap` is a `Colormap` that displays a purple-green-yellow sequence.
It is perceptually uniform and intended to be improve the accessibility of visualizations for viewers with color vision deficiency.
## MagmaMap
[tagmagmamap]: # (magmamap)
`MagmaMap` is a `Colormap` that displays a black-red-yellow sequence.
It is perceptually uniform and intended to be improve the accessibility of visualizations for viewers with color vision deficiency.
## InfernoMap
[taginfernomap]: # (infernomap)
`InfernoMap` is a `Colormap` that displays a black-red-yellow sequence.
It is perceptually uniform and intended to be improve the accessibility of visualizations for viewers with color vision deficiency.
## PlasmaMap
[tagplasmamap]: # (plasmamap)
`InfernoMap` is a `Colormap` that displays a blue-red-yellow sequence. It is perceptually uniform and intended to be improve the accessibility of visualizations for viewers with color vision deficiency.
================================================
FILE: help/complex.md
================================================
[comment]: # (Complex help)
[version]: # (0.5)
# Complex
[tagcomplex]: # (complex)
[tagim]: # (im)
Morpho provides complex numbers. The keyword `im` is used to denote the imaginary part of a complex number:
var a=1+5im
print a*a
Print values on the unit circle in the complex plane:
import constants
for (phi in 0..Pi:Pi/5) print exp(im*phi)
Get the real and imaginary parts of a complex number:
print real(a)
print imag(a)
or alternatively:
print a.real()
print a.imag()
[showsubtopics]: # (subtopics)
## Angle
[tagangle]: # (angle)
Returns the angle `phi` associated with the polar representation of a complex number `r*exp(im*phi)`:
print z.angle()
## Conj
[tagconjugate]: # (conjugate)
[tagconj]: # (conj)
Returns the complex conjugate of a number:
print z.conj()
================================================
FILE: help/conf.py
================================================
# Configuration file for the Sphinx documentation builder.
#
# This file only contains a selection of the most common options. For a full
# list see the documentation:
# https://www.sphinx-doc.org/en/master/usage/configuration.html
# -- Path setup --------------------------------------------------------------
# If extensions (or modules to document with autodoc) are in another directory,
# add these directories to sys.path here. If the directory is relative to the
# documentation root, use os.path.abspath to make it absolute, like shown here.
#
# import os
# import sys
# sys.path.insert(0, os.path.abspath('.'))
# -- Project information -----------------------------------------------------
project = 'morpho'
copyright = '2020-2024, T J Atherton'
author = 'T J Atherton'
# The full version, including alpha/beta/rc tags
release = '0.6.0'
# -- General configuration ---------------------------------------------------
# Add any Sphinx extension module names here, as strings. They can be
# extensions coming with Sphinx (named 'sphinx.ext.*') or your custom
# ones.
extensions = ['myst_parser']
# Add any paths that contain templates here, relative to this directory.
templates_path = ['_templates']
# List of patterns, relative to source directory, that match files and
# directories to ignore when looking for source files.
# This pattern also affects html_static_path and html_extra_path.
exclude_patterns = ['_build', 'Thumbs.db', '.DS_Store']
# Use recommonmark to parse md files
from recommonmark.parser import CommonMarkParser
source_parsers = {'.md': CommonMarkParser}
source_suffix = ['.rst', '.md']
# -- Options for HTML output -------------------------------------------------
# The theme to use for HTML and HTML Help pages. See the documentation for
# a list of builtin themes.
#
html_theme = 'sphinx_rtd_theme'
# Add any paths that contain custom static files (such as style sheets) here,
# relative to this directory. They are copied after the builtin static files,
# so a file named "default.css" will overwrite the builtin "default.css".
html_static_path = ['_static']
latex_engine = 'xelatex'
================================================
FILE: help/constants.md
================================================
[comment]: # (Constants module help)
[version]: # (0.5)
# Constants
[tagconstants]: # (constants)
The constants module contains a number of useful mathematical constants. Import it like any other module:
import constants
Available constants:
* `E` the base of natural logarithms.
* `Pi` ratio of the perimeter of a circle to its diameter.
================================================
FILE: help/controlflow.md
================================================
[comment]: # (Morpho control flow help file)
[version]: # (0.5)
[toplevel]: #
# Control Flow
[tagcontrol]: # (control)
Control flow statements are used to determine whether and how many times a selected piece of code is executed. These include:
* `if` - Selectively execute a piece of code if a condition is met.
* `else` - Execute a different block of code if the test in an `if` statement fails.
* `for` - Repeatedly execute a section of code with a counter
* `while` - Repeatedly execute a section of code while a condition is true.
## If
[tagif]: # (if)
[tagelse]: # (else)
`If` allows you to selectively execute a section of code depending on whether a condition is met. The simplest version looks like this:
if (x<1) print x
where the body of the loop, `print x`, is only executed if x is less than 1. The body can be a code block to accommodate longer sections of code:
if (x<1) {
... // do something
}
If you want to choose between two alternatives, use `else`:
if (a==b) {
// do something
} else {
// this code is executed only if the condition is false
}
You can even chain multiple tests together like this:
if (a==b) {
// option 1
} else if (a==c) {
// option 2
} else {
// something else
}
## While
[tagwhile]: # (while)
While loops repeat a section of code while a condition is true. For example,
var k=1
while (k <= 4) { print k; k+=1 }
^cond ^body
prints the numbers 1 to 4. The loop has two sections: `cond` is the condition to be executed and `body` is the section of code to be repeated.
Simple loops like the above example, especially those that involve counting out a sequence of numbers, are more conveniently written using a `for` loop,
for (k in 1..4) print k
Where `while` loops can be very useful is where the state of an object is being changed in the loop, e.g.
var a = List(1,2,3,4)
while (a.count()>0) print a.pop()
which prints 4,3,2,1.
## Do
[tagdo]: # (do)
A `do`...`while` loop repeats code while a condition is true---similar to a `while` loop---but the test happens at the end:
var k=1
do {
print k;
k+=1
} while (k<5)
which prints 1,2,3,4
Hence this type of loop executes at least one interation
## For
[tagfor]: # (for)
[tagin]: # (in)
For loops allow you to repeatedly execute a section of code. They come in two versions: the simpler version looks like this,
for (var i in 1..5) print i
which prints the numbers 1 to 5 in turn. The variable `i` is the *loop variable*, which takes on a different value each iteration. `1..5` is a range, which denotes a sequence of numbers. The *body* of the loop, `print i`, is the code to be repeatedly executed.
Morpho will implicitly insert a `var` before the loop variable if it's missing, so this works too:
for (i in 1..5) print i
If you want your loop variable to count in increments other than 1, you can specify a stepsize in the range:
for (i in 1..5:2) print i
^step
Ranges need not be integer:
for (i in 0.1..0.5:0.1) print i
You can also replace the range with other kinds of collection object to loop over their contents:
var a = Matrix([1,2,3,4])
for (x in a) print x
Morpho iterates over the collection object using an integer *counter variable* that's normally hidden. If you want to know the current value of the counter (e.g. to get the index of an element as well as its value), you can use the following:
var a = [1, 2, 3]
for (x, i in a) print "${i}: ${x}"
Morpho also provides a second form of `for` loop similar to that in C:
for (var i=0; i<5; i+=1) { print i }
^start ^test ^inc. ^body
which is executed as follows:
start: the variable `i` is declared and initially set to zero.
test: before each iteration, the test is evaluated. If the test is `false`, the loop terminates.
body: the body of the loop is executed.
inc: the variable `i` is increased by 1.
You can include any code that you like in each of the sections.
## Break
[tagbreak]: # (break)
`Break` is used inside loops to finish the loop early. For example
for (i in 1..5) {
if (i>3) break // --.
print i // | (Once i>3)
} // |
... // <-'
would only print 1, 2 and 3. Once the condition `i>3` is true, the `break` statement causes execution to continue after the loop body.
Both `for` and `while` loops support break.
## Continue
[tagcontinue]: # (continue)
`Continue` is used inside loops to skip over the rest of an iteration. For example
for (i in 1..5) { // <-.
print "Hello" |
if (i>3) continue // --'
print i
}
prints "Hello" five times but only prints 1, 2 and 3. Once the condition `i>3` is true, the `continue` statement causes execution to transfer to the start of the loop body.
Traditional `for` loops also support `continue`:
// v increment
for (var i=0; i<5; i+=1) {
if (i==2) continue
print i
}
Since `continue` causes control to be transferred *to the increment section* in this kind of loop, here the program prints 0..4 but the number 2 is skipped.
Use of `continue` with `while` loops is possible but isn't recommended as it can easily produce an infinite loop!
var i=0
while (i<5) {
if (i==2) continue
print i
i+=1
}
In this example, when the condition `i==2` is `true`, execution skips back to the start, but `i` *isn't* incremented. The loop gets stuck in the iteration `i==2`.
## Try
[tagtry]: # (try)
[tagcatch]: # (catch)
A `try` and `catch` statement allow you handle errors. For example
try {
// Do something
} catch {
"Tag" : // Handle the error
}
Code within the block after the `try` keyword is executed. If an error is generated then Morpho looks to see if the tag associated with the error matches any of the labels in the `catch` block. If it does, the code after the matching label is executed. If no error occurs, the catch block is skipped entirely.
================================================
FILE: help/delaunay.md
================================================
[comment]: # (Delaunay module help)
[version]: # (0.5)
# Delaunay
[tagdelaunay]: # (delaunay)
The `delaunay` module creates Delaunay triangulations from point clouds. It is dimensionally independent, so generates tetrahedra in 3D and higher order simplices beyond.
To use the module, first import it:
import delaunay
To create a Delaunary triangulation from a list of points:
var pts = []
for (i in 0...100) pts.append(Matrix([random(), random()]))
var del=Delaunay(pts)
print del.triangulate()
The module also provides `DelaunayMesh` to directly create meshes from Delaunay triangulations.
[showsubtopics]: # (subtopics)
## Triangulate
[tagtriangulate]: # (triangulate)
The `triangulate` method performs the delaunay triangulation. To use it, first construct a `Delaunay` object with the point cloud of interest:
var del=Delaunay(pts)
Then call `triangulate`:
var tri = del.triangulate()
This returns a list of triangles `[ [i, j, k], ... ]`.
## Circumsphere
[tagcircumsphere]: # (circumsphere)
The `Circumsphere` class calculates the circumsphere of a set of points, i.e. a sphere such that all the points are on the surface of the sphere. It is used internally by the `delaunay` module.
Create a `Circumsphere` from a list of points and a triangle specified by indices into that list:
var sph = Circumsphere(pts, [i,j,k])
Test if an arbitrary point is inside the `Circumsphere` or not:
print sph.pointinsphere(pt)
================================================
FILE: help/dictionary.md
================================================
[comment]: # (Dictionary help)
[version]: # (0.5)
# Dictionary
[tag]: # (Dictionary)
Dictionaries are collection objects that associate a unique *key* with a particular *value*. Keys can be any kind of morpho value, including numbers, strings and objects.
An example dictionary mapping states to capitals:
var dict = { "Massachusetts" : "Boston",
"New York" : "Albany",
"Vermont" : "Montpelier" }
Look up values by a given key with index notation:
print dict["Vermont"]
You can change the value associated with a key, or add new elements to the dictionary like this:
dict["Maine"]="Augusta"
Create an empty dictionary using the `Dictionary` constructor function:
var d = Dictionary()
Loop over keys in a dictionary:
for (k in dict) print k
The `keys` method returns a Morpho List of the keys.
var keys = dict.keys() // will return ["Massachusetts", "New York", "Vermont"]
The `contains` method returns a Bool value for whether the Dictionary
contains a given key.
print dict.contains("Vermont") // true
print dict.contains("New Hampshire") // false
The `remove` method removes a given key from the Dictionary.
dict.remove("Vermont")
print dict // { New York : Albany, Massachusetts : Boston }
The `clear` method removes all the (key, value) pairs fromt the
dictionary, resulting in an empty dictionary.
dict.clear()
print dict // { }
================================================
FILE: help/errors.md
================================================
[comment]: # (Errors help file)
[version]: # (0.5)
# Errors
[tagerror]: # (error)
[tagerrors]: # (errors)
[tagerrors]: # (throw)
[tagerrors]: # (warning)
When an error occurs in running a morpho program, an error message is displayed together with an explanation of where in the program that the error happened.
You can make your own custom errors using the `Error` class:
var myerr = Error("Tag", "A message")
Use the `throw` method to raise the error, interrupting execution unless the error is caught:
myerr.throw()
or
myerr.throw("A custom message")
You can also use the `warning` method to alert the user of a potential issue that doesn't need the program to be interrupted.
myerr.warning()
[showsubtopics]: # (subtopics)
## Alloc
[tagalloc]: # (alloc)
This error may occur when creating new objects or resizing them. It typically indicates that the computer is under memory pressure.
## Intrnl
[tagintrnl]: # (intrnl)
This error indicates an internal problem with morpho. Please contact the developers for support.
## InvldOp
[taginvldop]: # (invldop)
This error occurs when an operator like `+` or `-` is given operands that it doesn't understand. For example,
print "Hello" * "Goodbye" // Causes 'InvldOp'
causes this error because the multiplication operator doesn't know how to multiply strings.
If the operands are objects, this means that the objects don't provide a method for the requested operation, e.g. for
print object1 / object2
`object1` would need to provide a `div()` method that can successfully handle `object2`.
## CnctFld
[tagcnctfld]: # (cnctfld)
This error occurs when concatenation of strings or other objects fails, typically because of low memory.
## Uncallable
[taguncallable]: # (uncallable)
This error occurs when you try to call something that isn't a method or a function. Here, we initialize a variable with a string and call it:
var f = "Not a function"
f() // Causes 'Uncallable'
## GlblRtrn
[tagglblrtrn]: # (glblrtrn)
This error occurs when morpho encounters a `return` keyword outside of a function or method definition.
## InstFail
[taginstfail]: # (instfail)
This error occurs when morpho tried to create a new object, but something went wrong.
## NotAnObj
[tagnotanobj]: # (notanobj)
This error occurs if you try to access a property of something that isn't an object:
var a = 1
a.size = 5
## ObjLcksPrp
[tagobjlcksprp]: # (objlcksprp)
This error occurs if you try to access a property or method that hasn't been defined for an object:
var a = Object()
print a.pifflepaffle
or
print a.foo()
## NoInit
[tagnoinit]: # (noinit)
This error can occur if you try to create a new object from a class that doesn't have an `init` method:
class Foo { }
var a = Foo(0.3)
Here, the argument to `Foo` causes the `NoInit` error because no `init` method is available to process it.
## NotAnInst
[tagnotaninst]: # (notaninst)
This error occurs if you try to invoke a method on something that isn't an object:
var a = 4
print a.foo()
## ClssLcksMthd
[tagclsslcksmthd]: # (clsslcksmthd)
This error occurs if you try to invoke a method on a class that doesn't exist:
class Foo { }
print Foo.foo()
## InvldArgs
[taginvldargs]: # (invldargs)
This error occurs if you call a function with the wrong number of arguments:
fn f(x) { return x }
f(1,2)
## NotIndxbl
[tagnotindxbl]: # (notindxbl)
This error occurs if you try to index something that isn't a collection:
var a = 0.3
print a[1]
## IndxBnds
[tagindxbnds]: # (indxbnds)
This error can occur when selecting an entry from a collection object (such as a list) if the index supplied is bigger than the number of entries:
var a = [1,2,3]
print a[10]
## NonNmIndx
[tagnonnmindx]: # (nonnmindx)
This error occurs if you try to index an array with a non-numerical index:
var a[2,2]
print a["foo","bar"]
## ArrayDim
[tagarraydim]: # arraydim
This error occurs if you try to index an array with the wrong number of indices:
var a[2,2]
print a[1]
## DbgQuit
[tagdbgquit]: # (dbgquit)
This notification is generated after selecting `Quit` within the debugger. Execution of the program is halted and control returns to the user.
## SymblUndf
[tagsymblundf]: # (symblundf)
This error occurs if you refer to something that has not been previously declared, for example trying to use a variable of call a function that doesn't exist. It's possible that the symbol is spelt incorrectly, or that the capitalization doesn't match the definition (*morpho* symbols are case-sensitive).
A common problem is to try to assign to a variable that hasn't yet been declared:
a = 5
To fix this, prefix with `var`:
var a = 5
## MtrxIncmptbl
[tagmtrxincmptbl]: # (mtrxincmptbl)
This error occurs when an arithmetic operation is performed on two 'incompatible' matrices. For example, two matrices must have the same dimensions, i.e. the same number of rows and columns, to be added or subtracted,
var a = Matrix([[1,2],[3,4]])
var b = Matrix([[1]])
print a+b // generates a `MtrxIncmptbl` error.
Or to be multiplied together, the number of columns of the left hand matrix must equal the number of rows of the right hand matrix.
var a = Matrix([[1,2],[3,4]])
var b = Matrix([1,2])
print a*b // ok
print b*a // generates a `MtrxIncmptbl` error.
================================================
FILE: help/field.md
================================================
[comment]: # (Field class help)
[version]: # (0.5)
# Field
[tagfield]: # (Field)
Fields are used to store information, including numbers or matrices, associated with the elements of a `Mesh` object.
You can create a `Field` by applying a function to each of the vertices,
var f = Field(mesh, fn (x, y, z) x+y+z)
or by supplying a single constant value,
var f = Field(mesh, Matrix([1,0,0]))
Fields can then be added and subtracted using the `+` and `-` operators.
To access elements of a `Field`, use index notation:
print f[grade, element, index]
where
* `grade` is the grade to select
* `element` is the element id
* `index` is the element index
As a shorthand, it's possible to omit the grade and index; these are then both assumed to be `0`:
print f[2]
[showsubtopics]: # (subtopics)
## Mesh
[tagmesh]: # (mesh)
Returns the Mesh associated with a Field object:
var f.mesh()
## Grade
[taggrade]: # (grade)
To create fields that include grades other than just vertices, use the `grade` option to `Field`. This can be just a grade index,
var f = Field(mesh, 0, grade=2)
which creates an empty field with `0` for each of the facets of the mesh `mesh`.
You can store more than one item per element by supplying a list to the `grade` option indicating how many items you want to store on each grade. For example,
var f = Field(mesh, 1.0, grade=[0,2,1])
stores two numbers on the line (grade 1) elements and one number on the facets (grade 2) elements. Each number in the field is initialized to the value `1.0`.
## Shape
[tagshape]: # (shape)
The `shape` method returns a list indicating the number of items stored on each element of a particular grade. This has the same format as the list you supply to the `grade` option of the `Field` constructor. For example,
[1,0,2]
would indicate one item stored on each vertex and two items stored on each facet.
## Op
[tagop]: # (op)
The `op` method applies a function to every item stored in a `Field`, returning the result as elements of a new `Field` object. For example,
f.op(fn (x) x.norm())
calls the `norm` method on each element stored in `f`.
Additional `Field` objects may be supplied as extra arguments to `op`. These must have the same shape (the same number of items stored on each grade). The function supplied to `op` will now be called with the corresponding element from each field as arguments. For example,
f.op(fn (x,y) x.inner(y), g)
calculates an elementwise inner product between the elements of Fields `f` and `g`.
================================================
FILE: help/file.md
================================================
[comment]: # (File class help)
[version]: # (0.5)
# File
[tagfile]: # (File)
The `File` class provides the capability to read from and write to files, or to obtain the contents of a file in convenient formats.
To open a file, create a File object with the filename as the argument
var f = File("myfile.txt")
which opens `"myfile.txt"` for *reading*. To open a file for writing or appending, you need to provide a mode selector
var g = File("myfile.txt", "write")
or
var g = File("myfile.txt", "append")
Once the file is open, you can then read or write by calling appropriate methods:
f.lines() // reads the contents of the file into an array of lines.
f.readline() // reads a single line
f.readchar() // reads a single character.
f.write(string) // writes the arguments to the file.
After you're done with the file, close it with
f.close()
[show]: # (subtopics)
## lines
[taglines]: # (lines)
Returns the contents of a file as an array of strings; each element corresponds to a single line.
Read in the contents of a file and print line by line:
var f = File("input.txt")
var s = f.lines()
for (i in s) print i
f.close()
## readline
[tagreadline]: # (readline)
Reads a single line from a file; returns the result as a string.
Read in the contents of a file and print each line:
var f = File("input.txt")
while (!f.eof()) {
print f.readline()
}
f.close()
## readchar
[tagreadchar]: # (readchar)
Reads a single character from a file; returns the result as a string.
## write
[tagwrite]: # (write)
Writes to a file.
Write the contents of a list to a file:
var f = File("output.txt", "w")
for (k, i in list) f.write("${i}: ${k}")
f.close()
## close
[tagclose]: # (close)
Closes an open file.
## eof
[tageof]: # (eof)
Returns true if at the end of the file; false otherwise
# Folder
[tagfolder]: # (Folder)
The `Folder` class enables you to find whether a filepath refers to a folder, and find the contents of that folder.
Find whether a path refers to a folder:
print Folder.isfolder("path/folder")
Get a list of a folder's contents:
print Folder.contents("path/folder")
================================================
FILE: help/functionals.md
================================================
[comment]: # (Functionals help)
[version]: # (0.5)
# Functionals
[tagfunctionals]: # (functionals)
A number of `functionals` are available in Morpho. Each of these represents an integral over some `Mesh` and `Field` objects (on a particular `Selection`) and are used to define energies and constraints in an `OptimizationProblem` provided by the `optimize` module.
Many functionals are built in. Additional functionals are available by importing the `functionals` module:
import functionals
Functionals provide a number of standard methods:
* `total`(mesh) - returns the value of the integral with a provided mesh, selection and fields
* `integrand`(mesh) - returns the contribution to the integral from each element
* `gradient`(mesh) - returns the gradient of the functional with respect to vertex motions.
* `fieldgradient`(mesh, field) - returns the gradient of the functional with respect to components of the field
Each of these may be called with a mesh, a field and a selection.
[showsubtopics]: # (subtopics)
## Length
[taglength]: # (length)
A `Length` functional calculates the length of a line element in a mesh.
Evaluate the length of a circular loop:
import constants
import meshtools
var m = LineMesh(fn (t) [cos(t), sin(t), 0], 0...2*Pi:Pi/20, closed=true)
var le = Length()
print le.total(m)
See the `Functionals` entry for general information about functionals.
## AreaEnclosed
[tagareaenclosed]: # (areaenclosed)
An `AreaEnclosed` functional calculates the area enclosed by a loop of line elements.
var la = AreaEnclosed()
Evaluate the area enclosed of a circular loop:
import constants
import meshtools
var m = LineMesh(fn (t) [cos(t), sin(t), 0], 0...2*Pi:Pi/20, closed=true)
var larea = AreaEnclosed()
print larea.total(m)
See the `Functionals` entry for general information about functionals.
## Area
[tagarea]: # (area)
An `Area` functional calculates the area of the area elements in a mesh:
var la = Area()
print la.total(mesh)
See the `Functionals` entry for general information about functionals.
## VolumeEnclosed
[tagvolumeenclosed]: # (volumeenclosed)
A `VolumeEnclosed` functional is used to calculate the volume enclosed by a surface. Note that this estimate may become inaccurate for highly deformed surfaces.
var lv = VolumeEnclosed()
print lv.total(mesh)
See the `Functionals` entry for general information about functionals.
## Volume
[tagvolume]: # (volume)
A `Volume` functional calculates the volume of volume elements.
var lv = Volume()
See the `Functionals` entry for general information about functionals.
## ScalarPotential
[tagscalarpotential]: # (scalarpotential)
The `ScalarPotential` functional is applied to point elements.
var ls = ScalarPotential(potential)
You must supply a function (which may be anonymous) that returns the potential. You may optionally provide a function that returns the gradient as well at initialization:
var ls = ScalarPotential(potential, gradient)
This functional is often used to constrain the mesh to the level set of a function. For example, to confine a set of points to a sphere:
import optimize
fn sphere(x,y,z) { return x^2+y^2+z^2-1 }
fn grad(x,y,z) { return Matrix([2*x, 2*y, 2*z]) }
var lsph = ScalarPotential(sphere, grad)
problem.addlocalconstraint(lsph)
See the thomson example for use of this technique.
See the `Functionals` entry for general information about functionals.
## LinearElasticity
[taglinearelasticity]: # (linearelasticity)
The `LinearElasticity` functional measures the linear elastic energy away from a reference state.
You must initialize with a reference mesh:
var le = LinearElasticity(mref)
Manually set the poisson's ratio and grade to operate on:
le.poissonratio = 0.2
le.grade = 2
The energy for each element in the Mesh is computed as follows: First the Gram matrix `S` is computed for the element as well as the Gram matrix `F` for the corresponding element in the reference Mesh. These quantities are used to compute the Cauchy-Green strain tensor:
C = (F S^-1 - I)/2
The energy density is then:
mu*Tr(C^2) + 1/2*lambda*Tr(C)^2
where mu and lambda are the Lamé parameters. The total energy is found by multiplying the energy density by the volume or area of the element as appropriate.
See the `Functionals` entry for general information about functionals.
## EquiElement
[tagequielement]: # (equielement)
The `EquiElement` functional measures the discrepency between the size of elements adjacent to each vertex. It can be used to equalize elements for regularization purposes.
See the `Functionals` entry for general information about functionals.
## LineCurvatureSq
[taglinecurvaturesq]: # (linecurvaturesq)
The `LineCurvatureSq` functional measures the integrated curvature squared of a sequence of line elements.
Compute the total squared curvature of a loop:
import constants
import meshtools
var m = LineMesh(fn (t) [cos(t), sin(t), 0], 0...2*Pi:Pi/20, closed=true)
var larea = LineCurvatureSq()
print larea.total(m)
See the `Functionals` entry for general information about functionals.
## LineTorsionSq
[taglinetorsionsq]: # (linetorsionsq)
The `LineTorsionSq` functional measures the integrated torsion squared of a sequence of line elements.
Compute the total squared torsion of a helix:
import constants
import meshtools
var m = LineMesh(fn (t) [cos(t), sin(t), t], 0...2*Pi:Pi/20, closed=true)
var larea = LineTorsionSq()
print larea.total(m)
See the `Functionals` entry for general information about functionals.
## MeanCurvatureSq
[tagmeancurvsq]: # (meancurvaturesq)
The `MeanCurvatureSq` functional computes the integrated mean curvature over a surface.
Compute the integrated mean squared curvature of the unit sphere:
import implicitmesh
var impl = ImplicitMeshBuilder(fn (x,y,z) x^2+y^2+z^2-1)
var mesh = impl.build(stepsize=0.25)
var lmsq = MeanCurvatureSq()
print lmsq.total(mesh)
See the `Functionals` entry for general information about functionals.
## GaussCurvature
[taggausscurv]: # (gausscurvature)
The `GaussCurvature` computes the integrated gaussian curvature over a surface.
Note that for surfaces with a boundary, the integrand is correct only for the interior points. To compute the geodesic curvature of the boundary in that case, you can set the optional flag `geodesic` to `true` and compute the total on the boundary selection.
Here is an example for a 2D disk mesh.
var mesh = Mesh("disk.mesh")
mesh.addgrade(1)
var whole = Selection(mesh, fn(x,y,z) true)
var bnd = Selection(mesh, boundary=true)
var interior = whole.difference(bnd)
var gauss = GaussCurvature()
print gauss.total(mesh, selection=interior) // expect: 0
gauss.geodesic = true
print gauss.total(mesh, selection=bnd) // expect: 2*Pi
See the `Functionals` entry for general information about functionals.
## GradSq
[taggradsq]: # (gradsq)
The `GradSq` functional measures the integral of the gradient squared of a field. The field can be a scalar, vector or matrix function.
Initialize with the required field:
var le=GradSq(phi)
Compute the integral of GradSq(phi):
print le.total(mesh)
See the `Functionals` entry for general information about functionals.
## Nematic
[tagnematic]: # (nematic)
The `Nematic` functional measures the elastic energy of a nematic liquid crystal.
var lf=Nematic(nn)
There are a number of optional parameters that can be used to set the splay, twist and bend constants:
var lf=Nematic(nn, ksplay=1, ktwist=0.5, kbend=1.5, pitch=0.1)
These are stored as properties of the object and can be retrieved as follows:
print lf.ksplay
See the `Functionals` entry for general information about functionals.
## NematicElectric
[tagnematic]: # (nematic)
The `NematicElectric` functional measures the integral of a nematic and electric coupling term integral((n.E)^2) where the electric field E may be computed from a scalar potential or supplied as a vector.
Initialize with a director field `nn` and a scalar potential `phi`:
var lne = NematicElectric(nn, phi)
See the `Functionals` entry for general information about functionals.
## NormSq
[tagnormsq]: # (normsq)
The `NormSq` functional measures the elementwise L2 norm squared of a field.
See the `Functionals` entry for general information about functionals.
## LineIntegral
[taglineintegral]: # (lineintegral)
The `LineIntegral` functional computes the line integral of a function. You supply an integrand function that takes a position matrix as an argument.
To compute `integral(x^2+y^2)` over a line element:
var la=LineIntegral(fn (x) x[0]^2+x[1]^2)
The function `tangent()` returns a unit vector tangent to the current element:
var la=LineIntegral(fn (x) x.inner(tangent()))
You can also integrate functions that involve fields:
var la=LineIntegral(fn (x, n) n.inner(tangent()), n)
where `n` is a vector field. The local interpolated value of this field is passed to your integrand function. More than one field can be used; they are passed as arguments to the integrand function in the order you supply them to `LineIntegral`.
The gradient of a field is available within an integrand function using the `gradient()` function.
See the `Functionals` entry for general information about functionals.
## AreaIntegral
[tagareaintegral]: # (areaintegral)
The `AreaIntegral` functional computes the area integral of a function. You supply an integrand function that takes a position matrix as an argument.
To compute integral(x*y) over an area element:
var la=AreaIntegral(fn (x) x[0]*x[1])
You can also integrate functions that involve fields:
var la=AreaIntegral(fn (x, phi) phi^2, phi)
The local facet normal can be accessed in an integrand using the `normal()` function:
var la=AreaIntegral(fn (x) x.inner(normal())^2)
More than one field can be used; they are passed as arguments to the integrand function in the order you supply them to `AreaIntegral`.
The gradient of a field is available within an integrand function using the `gradient()` function.
See the `Functionals` entry for general information about functionals.
## VolumeIntegral
[tagvolumeintegral]: # (volumeintegral)
The `VolumeIntegral` functional computes the volume integral of a function. You supply an integrand function that takes a position matrix as an argument.
To compute integral(x*y*z) over an volume element:
var la=VolumeIntegral(fn (x) x[0]*x[1]*x[2])
You can also integrate functions that involve fields:
var la=VolumeIntegral(fn (x, phi) phi^2, phi)
More than one field can be used; they are passed as arguments to the integrand function in the order you supply them to `VolumeIntegral`.
The gradient of a field is available within an integrand function using the `gradient()` function.
See the `Functionals` entry for general information about functionals.
## Hydrogel
[taghydrogel]: # (hydrogel)
The `Hydrogel` functional computes the Flory-Rehner energy over an element:
(a*phi*log(phi) + b*(1-phi)+log(1-phi) + c*phi*(1-phi))*V +
d*(log(phiref/phi)/3 - (phiref/phi)^(2/3) + 1)*V0
The first three terms come from the Flory-Huggins mixing energy, whereas
the fourth term proportional to d comes from the Flory-Rehner elastic
energy.
The value of phi is calculated from a reference mesh
that you provide on initializing the Functional:
var lfh = Hydrogel(mref)
Here, a, b, c, d and phiref are parameters you can supply (they are `nil`
by default), V is the current volume and V0 is the reference volume of a
given element. You also need to supply the initial value of phi, labeled
as phi0, which is assumed to be the same for all the elements.
Manually set the coefficients and grade to operate on:
lfh.a = 1; lfh.b = 1; lfh.c = 1; lfh.d = 1;
lfh.grade = 2, lfh.phi0 = 0.5, lfh.phiref = 0.1
See the `Functionals` entry for general information about functionals.
================================================
FILE: help/functions.md
================================================
[comment]: # (Morpho functions help file)
[version]: # (0.5)
[toplevel]: #
# Functions
[tagfn]: # (fn)
[tagfun]: # (fun)
[tagfunction]: # (function)
A function in morpho is defined with the `fn` keyword, followed by the function's name, a list of parameters enclosed in parentheses, and the body of the function in curly braces. This example computes the square of a number:
fn sqr(x) {
return x*x
}
Once a function has been defined you can evaluate it like any other morpho function.
print sqr(2)
Functions can accept optional parameters:
fn fun(x, quiet=true ) { if (!quiet) print "Loud!" }
Morpho functions can also be defined to restrict the type of accepted parameters:
fn f(List x) { print "A list!" }
Multiple implementations can be defined that accept different numbers of parameters and parameter types:
fn f() { print "No parameters!" }
fn f(String x) { print "A string!" }
fn f(Tuple x) { print "A tuple!" }
The correct implementation is then selected at runtime:
f("Hello World!") // expect: A string!
[show]: # (subtopics)
## Variadic
[tagvariadic]: # (variadic)
As well as regular parameters, functions can also be defined with *variadic* parameters:
fn func(x, ...v) {
for (a in v) print a
}
This function can then be called with 1 or more arguments:
func(1)
func(1, 2)
func(1, 2, 3) // All valid!
The variadic parameter `v` captures all the extra arguments supplied. Functions cannot be defined with more than one variadic parameter.
You can mix regular, variadic and optional parameters. Variadic parameters come before optional parameters:
fn func(x, ...v, optional=true) {
//
}
## Optional
[tagoptional]: # (optional)
Functions can also be defined with *optional* parameters:
fn func(a=1) {
print a
}
Each optional parameter must be defined with a default value (here `1`). The function can then be called either with o
gitextract_ml0t_fts/
├── .gitattributes
├── .github/
│ ├── ISSUE_TEMPLATE/
│ │ └── bug_report.md
│ └── workflows/
│ ├── build.yml
│ ├── buildandtest.yml
│ ├── buildandtestmultithreaded.yml
│ ├── codeql.yml
│ ├── examples.yml
│ └── nonanboxing.yml
├── .gitignore
├── .readthedocs.yml
├── CMakeLists.txt
├── CODE_OF_CONDUCT.md
├── CONTRIBUTING.md
├── LICENSE
├── README.md
├── examples/
│ ├── catenoid/
│ │ └── catenoid.morpho
│ ├── cholesteric/
│ │ └── cholesteric.morpho
│ ├── cube/
│ │ └── cube.morpho
│ ├── delaunay/
│ │ └── delaunay.morpho
│ ├── dla/
│ │ └── dla.morpho
│ ├── electrostatics/
│ │ └── electrostatics.morpho
│ ├── elementtypes/
│ │ ├── README.md
│ │ ├── electrostaticsCG2.morpho
│ │ └── qtensorCG2.morpho
│ ├── examples.py
│ ├── implicitmesh/
│ │ ├── ellipsoid.morpho
│ │ ├── threesurface.morpho
│ │ └── torus.morpho
│ ├── meshgen/
│ │ ├── disk.morpho
│ │ ├── ellipse.morpho
│ │ ├── ellipsoidsection.morpho
│ │ ├── halfdisk.morpho
│ │ ├── overlappingdisks.morpho
│ │ ├── sphere.morpho
│ │ ├── square.morpho
│ │ ├── superellipse.morpho
│ │ ├── superellipsoid.morpho
│ │ └── weighted.morpho
│ ├── meshslice/
│ │ ├── sphere.mesh
│ │ └── testmeshslice.morpho
│ ├── plot/
│ │ ├── plotfield.morpho
│ │ ├── plotmeshlabels.morpho
│ │ ├── plotselection.morpho
│ │ └── scalebar.morpho
│ ├── povray/
│ │ ├── testCamera.morpho
│ │ ├── testpovray.morpho
│ │ ├── testpovraytext.morpho
│ │ ├── testpovraytransmitfilter.morpho
│ │ └── text.morpho
│ ├── qtensor/
│ │ ├── dense_disk.mesh
│ │ ├── qtensor.morpho
│ │ ├── src.lyx
│ │ └── src.tex
│ ├── tactoid/
│ │ ├── disk.mesh
│ │ ├── tactoid.morpho
│ │ └── tactoid2dmesh.morpho
│ ├── thomson/
│ │ └── thomson.morpho
│ ├── tutorial/
│ │ ├── disk.mesh
│ │ ├── tutorial.morpho
│ │ └── tutorial2.morpho
│ └── wrap/
│ └── wrap.morpho
├── help/
│ ├── Makefile
│ ├── array.md
│ ├── builtin.md
│ ├── classes.md
│ ├── color.md
│ ├── complex.md
│ ├── conf.py
│ ├── constants.md
│ ├── controlflow.md
│ ├── delaunay.md
│ ├── dictionary.md
│ ├── errors.md
│ ├── field.md
│ ├── file.md
│ ├── functionals.md
│ ├── functions.md
│ ├── graphics.md
│ ├── help.md
│ ├── implicitmesh.md
│ ├── index.rst
│ ├── json.md
│ ├── kdtree.md
│ ├── list.md
│ ├── make.bat
│ ├── matrix.md
│ ├── mesh.md
│ ├── meshgen.md
│ ├── meshslice.md
│ ├── meshtools.md
│ ├── modules.md
│ ├── optimize.md
│ ├── plot.md
│ ├── povray.md
│ ├── range.md
│ ├── requirements.txt
│ ├── selection.md
│ ├── sparse.md
│ ├── string.md
│ ├── syntax.md
│ ├── system.md
│ ├── tuple.md
│ ├── values.md
│ ├── variables.md
│ └── vtk.md
├── modules/
│ ├── color.morpho
│ ├── constants.morpho
│ ├── delaunay.morpho
│ ├── functionals.morpho
│ ├── graphics.morpho
│ ├── histogram.morpho
│ ├── implicitmesh.morpho
│ ├── kdtree.morpho
│ ├── meshgen.morpho
│ ├── meshslice.morpho
│ ├── meshtools.morpho
│ ├── optimize.morpho
│ ├── parser.morpho
│ ├── plot.morpho
│ ├── povray.morpho
│ ├── shapeopt.morpho
│ ├── symmetry.morpho
│ └── vtk.morpho
├── releasenotes/
│ ├── version-0.5.1.md
│ ├── version-0.5.2.md
│ ├── version-0.5.3.md
│ ├── version-0.5.4.md
│ ├── version-0.5.5.md
│ ├── version-0.5.6.md
│ ├── version-0.5.7.md
│ ├── version-0.6.0.md
│ ├── version-0.6.1.md
│ ├── version-0.6.2.md
│ └── version-0.6.3.md
├── src/
│ ├── CMakeLists.txt
│ ├── build.h
│ ├── builtin/
│ │ ├── CMakeLists.txt
│ │ ├── builtin.c
│ │ ├── builtin.h
│ │ ├── functiondefs.c
│ │ └── functiondefs.h
│ ├── classes/
│ │ ├── CMakeLists.txt
│ │ ├── array.c
│ │ ├── array.h
│ │ ├── bool.c
│ │ ├── bool.h
│ │ ├── classes.h
│ │ ├── closure.c
│ │ ├── closure.h
│ │ ├── clss.c
│ │ ├── clss.h
│ │ ├── cmplx.c
│ │ ├── cmplx.h
│ │ ├── dict.c
│ │ ├── dict.h
│ │ ├── err.c
│ │ ├── err.h
│ │ ├── file.c
│ │ ├── file.h
│ │ ├── flt.c
│ │ ├── flt.h
│ │ ├── function.c
│ │ ├── function.h
│ │ ├── instance.c
│ │ ├── instance.h
│ │ ├── int.c
│ │ ├── int.h
│ │ ├── invocation.c
│ │ ├── invocation.h
│ │ ├── json.c
│ │ ├── json.h
│ │ ├── list.c
│ │ ├── list.h
│ │ ├── metafunction.c
│ │ ├── metafunction.h
│ │ ├── range.c
│ │ ├── range.h
│ │ ├── strng.c
│ │ ├── strng.h
│ │ ├── system.c
│ │ ├── system.h
│ │ ├── tuple.c
│ │ ├── tuple.h
│ │ ├── upvalue.c
│ │ └── upvalue.h
│ ├── core/
│ │ ├── CMakeLists.txt
│ │ ├── compile.c
│ │ ├── compile.h
│ │ ├── core.h
│ │ ├── gc.c
│ │ ├── gc.h
│ │ ├── opcodes.h
│ │ ├── vm.c
│ │ └── vm.h
│ ├── datastructures/
│ │ ├── CMakeLists.txt
│ │ ├── debugannotation.c
│ │ ├── debugannotation.h
│ │ ├── dictionary.c
│ │ ├── dictionary.h
│ │ ├── error.c
│ │ ├── error.h
│ │ ├── object.c
│ │ ├── object.h
│ │ ├── program.c
│ │ ├── program.h
│ │ ├── signature.c
│ │ ├── signature.h
│ │ ├── syntaxtree.c
│ │ ├── syntaxtree.h
│ │ ├── value.c
│ │ ├── value.h
│ │ ├── varray.c
│ │ ├── varray.h
│ │ ├── version.c
│ │ └── version.h
│ ├── debug/
│ │ ├── CMakeLists.txt
│ │ ├── debug.c
│ │ ├── debug.h
│ │ ├── profile.c
│ │ └── profile.h
│ ├── geometry/
│ │ ├── CMakeLists.txt
│ │ ├── fespace.c
│ │ ├── fespace.h
│ │ ├── field.c
│ │ ├── field.h
│ │ ├── functional.c
│ │ ├── functional.h
│ │ ├── geometry.c
│ │ ├── geometry.h
│ │ ├── integrate.c
│ │ ├── integrate.h
│ │ ├── mesh.c
│ │ ├── mesh.h
│ │ ├── selection.c
│ │ └── selection.h
│ ├── linalg/
│ │ ├── CMakeLists.txt
│ │ ├── matrix.c
│ │ ├── matrix.h
│ │ ├── sparse.c
│ │ └── sparse.h
│ ├── morpho.h
│ └── support/
│ ├── CMakeLists.txt
│ ├── common.c
│ ├── common.h
│ ├── extensions.c
│ ├── extensions.h
│ ├── format.c
│ ├── format.h
│ ├── lex.c
│ ├── lex.h
│ ├── memory.c
│ ├── memory.h
│ ├── parse.c
│ ├── parse.h
│ ├── platform.c
│ ├── platform.h
│ ├── random.c
│ ├── random.h
│ ├── resources.c
│ ├── resources.h
│ ├── threadpool.c
│ └── threadpool.h
└── test/
├── apply/
│ ├── apply.morpho
│ ├── apply_args.morpho
│ ├── apply_builtin.morpho
│ ├── apply_closure.morpho
│ ├── apply_list.morpho
│ ├── apply_method.morpho
│ └── apply_recursion.morpho
├── arithmetic/
│ ├── power.morpho
│ ├── redirection.morpho
│ └── unary_div.morpho
├── array/
│ ├── array.morpho
│ ├── array_assign_beyond_bounds.morpho
│ ├── array_dim_with_initializer.morpho
│ ├── array_enumerate.morpho
│ ├── array_garbage_collect.morpho
│ ├── array_incompatible_initializer.morpho
│ ├── array_initialize_array.morpho
│ ├── array_initialize_incompatible_list.morpho
│ ├── array_initialize_list.morpho
│ ├── array_nonnum_indices.morpho
│ ├── array_print.morpho
│ ├── array_read_beyond_bounds.morpho
│ ├── array_three_dim.morpho
│ ├── array_two_dim.morpho
│ ├── array_veneer.morpho
│ ├── array_wrong_dim.morpho
│ ├── constructor.morpho
│ └── inherited.morpho
├── assignment/
│ ├── associativity.morpho
│ ├── global.morpho
│ ├── grouping.morpho
│ ├── infix_operator.morpho
│ ├── local.morpho
│ ├── prefix_operator.morpho
│ ├── shorthand.morpho
│ ├── syntax.morpho
│ ├── to_self.morpho
│ └── undefined.morpho
├── blank/
│ ├── empty_file.morpho
│ └── shebang.morpho
├── block/
│ ├── empty.morpho
│ ├── scope.morpho
│ └── scope_error.morpho
├── bool/
│ ├── builtin.morpho
│ ├── equality.morpho
│ └── not.morpho
├── break/
│ ├── break_in_if_outside_loop.morpho
│ ├── break_outside_loop.morpho
│ ├── continue_in_if_outside_loop.morpho
│ ├── continue_outside_loop.morpho
│ ├── in_for.morpho
│ ├── in_forin.morpho
│ └── in_while.morpho
├── builtin/
│ ├── apply.morpho
│ ├── bounds.morpho
│ ├── boundsvargs.morpho
│ ├── iscallable.morpho
│ ├── maxargs.morpho
│ ├── minargs.morpho
│ ├── minnumbers.morpho
│ ├── minvargs.morpho
│ ├── mod.morpho
│ └── typecheck.morpho
├── call/
│ ├── bool.morpho
│ ├── call.morpho
│ ├── nil.morpho
│ ├── num.morpho
│ ├── object.morpho
│ └── string.morpho
├── class/
│ ├── apply_class.morpho
│ ├── call_class_in_property.morpho
│ ├── call_on_class.morpho
│ ├── empty.morpho
│ ├── forward_ref_in_method.morpho
│ ├── inherit_self.morpho
│ ├── inherited_method.morpho
│ ├── is.morpho
│ ├── keyword_method.morpho
│ ├── keyword_property.morpho
│ ├── linearization.morpho
│ ├── local_fn_supersedes_method_call.morpho
│ ├── local_inherit_other.morpho
│ ├── local_inherit_self.morpho
│ ├── local_reference_self.morpho
│ ├── method_call_supersedes_global_fn.morpho
│ ├── mixins.morpho
│ ├── nested_class.morpho
│ ├── no_self_for_method_call.morpho
│ ├── prefer_local.morpho
│ ├── reference_self.morpho
│ ├── syntax_error_in_constructor.morpho
│ └── unlinearizable.morpho
├── closure/
│ ├── assign_to_closure.morpho
│ ├── assign_to_shadowed_later.morpho
│ ├── close_over_function_parameter.morpho
│ ├── close_over_later_variable.morpho
│ ├── closed_closure_in_function.morpho
│ ├── closures_in_loop.morpho
│ ├── nested_closure.morpho
│ ├── open_closure_in_function.morpho
│ ├── prioritize_upvalues_over_globals.morpho
│ ├── reference_closure_multiple_times.morpho
│ ├── reuse_closure_slot.morpho
│ ├── shadow_closure_with_local.morpho
│ ├── unused_closure.morpho
│ ├── unused_later_closure.morpho
│ └── veneer.morpho
├── comments/
│ ├── line_at_eof.morpho
│ ├── multline.morpho
│ ├── nested.morpho
│ ├── only_line_comment.morpho
│ ├── only_line_comment_and_line.morpho
│ ├── unicode.morpho
│ └── unterminated.morpho
├── complex/
│ ├── ComplexBuiltin.morpho
│ ├── ComplexTrig.morpho
│ ├── arithmetic.morpho
│ ├── clone.morpho
│ ├── complex_overflow_literal.morpho
│ ├── constructor.morpho
│ ├── constructor_error.morpho
│ ├── inherited.morpho
│ ├── methods.morpho
│ └── powers.morpho
├── constructor/
│ ├── arguments.morpho
│ ├── call_init_early_return.morpho
│ ├── call_init_explicitly.morpho
│ ├── default.morpho
│ ├── default_arguments.morpho
│ ├── early_return.morpho
│ ├── extra_arguments.morpho
│ ├── init_not_method.morpho
│ ├── missing_arguments.morpho
│ ├── return_in_nested_function.morpho
│ └── return_value.morpho
├── dictionary/
│ ├── clear.morpho
│ ├── contains.morpho
│ ├── empty_literal.morpho
│ ├── inherited.morpho
│ ├── key_not_found.morpho
│ ├── literal_from_vars.morpho
│ ├── literal_in_function.morpho
│ ├── literal_in_loop.morpho
│ ├── methods.morpho
│ ├── missing_comma.morpho
│ ├── missing_separator.morpho
│ ├── remove.morpho
│ ├── set_operations.morpho
│ ├── syntax.morpho
│ ├── tombstone.morpho
│ └── unterminated.morpho
├── do/
│ ├── do_in_fn.morpho
│ ├── do_with_break.morpho
│ ├── missingcond.morpho
│ └── syntax.morpho
├── error/
│ ├── error_incorrectly_defined.morpho
│ ├── inherited.morpho
│ ├── stacktrace.morpho
│ ├── throw.morpho
│ ├── throw_on_class.morpho
│ └── throw_on_class_notag.morpho
├── field/
│ ├── assign.morpho
│ ├── assign_matrix.morpho
│ ├── badfnin.morpho
│ ├── bounds.morpho
│ ├── discretizations/
│ │ ├── boundary_line_integrals.morpho
│ │ ├── cg1_area_in_2d_grad.morpho
│ │ ├── cg1_area_in_2d_grad_old.morpho
│ │ ├── cg1_area_in_2d_old.morpho
│ │ ├── cg1_line_in_3d_grad.morpho
│ │ ├── cg2_area_in_2d.morpho
│ │ ├── cg2_area_in_2d_grad.morpho
│ │ ├── cg2_area_in_2d_tensor_grad.morpho
│ │ ├── cg2_area_in_3d_grad.morpho
│ │ ├── cg2_line_in_1d.morpho
│ │ ├── cg2_line_in_2d_grad.morpho
│ │ ├── cg2_line_in_3d_integrate.morpho
│ │ ├── cg2_vol_in_3d.morpho
│ │ └── cg2_vol_in_3d_grad.morpho
│ ├── enumerate.morpho
│ ├── grade.morpho
│ ├── inherited.morpho
│ ├── inner.morpho
│ ├── linearize.morpho
│ ├── matrix.morpho
│ ├── methods.morpho
│ ├── multigrade.morpho
│ ├── neg_nilMesh.morpho
│ ├── negate.morpho
│ ├── op.morpho
│ ├── op_in_loop.morpho
│ ├── scalar.morpho
│ ├── scalarmul.morpho
│ └── square.mesh
├── file/
│ ├── file.morpho
│ ├── file_lines.morpho
│ ├── file_not_found.morpho
│ ├── file_readall.morpho
│ ├── file_write.morpho
│ ├── filename_missing.morpho
│ ├── filename_not_string.morpho
│ ├── folder/
│ │ ├── file1.txt
│ │ ├── file2.txt
│ │ └── file3.txt
│ ├── folder.morpho
│ ├── remote.morpho
│ ├── string.txt
│ ├── test.txt
│ └── testout.txt
├── for/
│ ├── class_in_body.morpho
│ ├── closure_in_body.morpho
│ ├── fn_in_body.morpho
│ ├── return_closure.morpho
│ ├── return_inside.morpho
│ ├── scope.morpho
│ ├── statement_condition.morpho
│ ├── statement_increment.morpho
│ ├── statement_initializer.morpho
│ ├── syntax.morpho
│ └── var_in_body.morpho
├── for_in/
│ ├── forin.morpho
│ ├── forin_custom.morpho
│ ├── forin_in_function.morpho
│ ├── forin_index.morpho
│ └── forin_string.morpho
├── function/
│ ├── anonymous.morpho
│ ├── anonymous_closure.morpho
│ ├── anonymous_closure_assign.morpho
│ ├── anonymous_closure_noparams.morpho
│ ├── anonymous_in_args.morpho
│ ├── anonymous_in_optional_args.morpho
│ ├── body_must_be_block.morpho
│ ├── constant_arg_optional.morpho
│ ├── empty_body.morpho
│ ├── extra_arguments.morpho
│ ├── index_in_arguments.morpho
│ ├── local_recursion.morpho
│ ├── missing_arguments.morpho
│ ├── missing_comma_in_parameters.morpho
│ ├── mutual_recursion/
│ │ ├── duplicate_local_mutual_recursion.morpho
│ │ ├── local_mutual_recursion.morpho
│ │ ├── local_mutual_recursion_out_of_scope.morpho
│ │ ├── mutual_recursion.morpho
│ │ ├── mutual_recursion_in_closure.morpho
│ │ ├── undefined_call_in_global.morpho
│ │ ├── unresolved_forward_ref_in_func.morpho
│ │ └── unresolved_forward_reference.morpho
│ ├── optional.morpho
│ ├── optional_invalid.morpho
│ ├── optional_non_constant_default.morpho
│ ├── optional_too_few_fixed.morpho
│ ├── parameters.morpho
│ ├── print.morpho
│ ├── recursion.morpho
│ ├── stack_overflow.morpho
│ ├── too_many_arguments.morpho
│ ├── too_many_parameters.morpho
│ ├── unknown_optional.morpho
│ ├── variadic.morpho
│ ├── variadic_append.morpho
│ ├── variadic_apply.morpho
│ ├── variadic_in_method.morpho
│ ├── variadic_last.morpho
│ ├── variadic_only.morpho
│ ├── variadic_optional.morpho
│ ├── variadic_too_many.morpho
│ └── veneer.morpho
├── functionals/
│ ├── area/
│ │ ├── area.morpho
│ │ ├── area2.morpho
│ │ ├── area2d.morpho
│ │ ├── area_hessian.morpho
│ │ ├── area_integrandForElement.morpho
│ │ ├── square.mesh
│ │ └── triangle.mesh
│ ├── areaenclosed/
│ │ ├── areaenclosed.morpho
│ │ ├── areaenclosed_hessian.morpho
│ │ └── areaenclosed_integrandForElement.morpho
│ ├── areaintegral/
│ │ ├── areaintegral.morpho
│ │ ├── cg2fieldgradient.morpho
│ │ ├── cgtensor.morpho
│ │ ├── grad.morpho
│ │ ├── grad2.morpho
│ │ ├── gradvector.morpho
│ │ └── normal.morpho
│ ├── cube.mesh
│ ├── cubeout.mesh
│ ├── equielement/
│ │ ├── equielement.morpho
│ │ ├── equielement_gradient.morpho
│ │ ├── equielement_hessian.morpho
│ │ ├── hex.mesh
│ │ └── weight.morpho
│ ├── err_functional_req_mesh.morpho
│ ├── err_integrand.morpho
│ ├── gausscurvature/
│ │ ├── disk.mesh
│ │ ├── gausscurvature.morpho
│ │ ├── geodesiccurvature.morpho
│ │ ├── gradient.morpho
│ │ ├── symm.morpho
│ │ └── torus.morpho
│ ├── gradsq/
│ │ ├── disk.mesh
│ │ ├── gradsq.morpho
│ │ ├── gradsq1d.morpho
│ │ ├── gradsq3d.morpho
│ │ ├── integral.morpho
│ │ ├── tetrahedron.mesh
│ │ └── triangle.mesh
│ ├── hydrogel/
│ │ ├── hydrogel.morpho
│ │ ├── hydrogel1D.morpho
│ │ ├── hydrogel1D_2elements.morpho
│ │ ├── hydrogel2D.morpho
│ │ ├── hydrogel2D_2elements.morpho
│ │ ├── hydrogel3D_2elements.morpho
│ │ ├── hydrogel_field_lacks_grade.morpho
│ │ └── tetrahedron.mesh
│ ├── length/
│ │ ├── length.morpho
│ │ ├── length2d.morpho
│ │ ├── length_hessian.morpho
│ │ ├── length_integrandForElement.morpho
│ │ └── line.mesh
│ ├── linearelasticity/
│ │ ├── linearelasticity.morpho
│ │ ├── relax.morpho
│ │ ├── scalesquare.mesh
│ │ ├── shearsquare.mesh
│ │ ├── square.mesh
│ │ └── stretchsquare.mesh
│ ├── linecurvaturesq/
│ │ ├── gradient.morpho
│ │ ├── gradient_symm.morpho
│ │ ├── hessian.morpho
│ │ ├── linecurvaturesq.morpho
│ │ ├── linecurvaturesq.xmorpho
│ │ ├── linecurvaturesq_integrandForElement.morpho
│ │ ├── linecurvaturesq_symm.morpho
│ │ ├── linecurvaturesq_symm.xmorpho
│ │ └── symmetry.xmorpho
│ ├── lineintegral/
│ │ ├── fields_incorrect_args.morpho
│ │ ├── fields_insufficient_args.morpho
│ │ ├── fields_toomany_args.morpho
│ │ ├── lineintegral.morpho
│ │ ├── lineintegral_fieldgradient.morpho
│ │ ├── lineintegral_hessian.morpho
│ │ ├── selection.morpho
│ │ ├── tangent.morpho
│ │ └── tangent2d.morpho
│ ├── linetorsionsq/
│ │ ├── gradient.morpho
│ │ ├── gradient_symm.morpho
│ │ ├── hessian.morpho
│ │ ├── linetorsionsq.morpho
│ │ ├── linetorsionsq.xmorpho
│ │ └── linetorsionsq_symm.morpho
│ ├── meancurvaturesq/
│ │ ├── gradient.morpho
│ │ ├── gradient_symm.morpho
│ │ ├── meancurvaturesq.morpho
│ │ └── symm.morpho
│ ├── nematic/
│ │ ├── nematic.morpho
│ │ ├── nematic3d.morpho
│ │ ├── nematicdim.morpho
│ │ ├── square.mesh
│ │ └── tetrahedron.mesh
│ ├── nematicelectric/
│ │ └── nematicelectric.morpho
│ ├── normsq/
│ │ ├── normsq.morpho
│ │ └── triangle.mesh
│ ├── numericalderivatives.morpho
│ ├── on_selection.morpho
│ ├── relax.morpho
│ ├── relax2.morpho
│ ├── scalarpotential/
│ │ ├── scalarpotential.morpho
│ │ ├── scalarpotential_hessian.morpho
│ │ ├── scalarpotential_ndiff.morpho
│ │ ├── scalarpotential_notcallable.morpho
│ │ └── tetrahedron.mesh
│ ├── square.mesh
│ ├── triangle.mesh
│ ├── volume/
│ │ ├── tetrahedron.mesh
│ │ ├── volume.morpho
│ │ └── volume_hessian.morpho
│ ├── volumeenclosed/
│ │ ├── tetrahedron.mesh
│ │ ├── volencl.morpho
│ │ ├── volencl_hessian.morpho
│ │ └── volencl_zeroelement.morpho
│ └── volumeintegral/
│ ├── grad.morpho
│ ├── testintegrals.morpho
│ └── volume_integral.morpho
├── help.py
├── if/
│ ├── class_in_else.morpho
│ ├── class_in_then.morpho
│ ├── dangling_else.morpho
│ ├── else.morpho
│ ├── fn_in_else.morpho
│ ├── fn_in_then.morpho
│ ├── if.morpho
│ ├── if_in_method.morpho
│ ├── truth.morpho
│ ├── var_in_else.morpho
│ └── var_in_then.morpho
├── import/
│ ├── as.morpho
│ ├── as_not_imported.morpho
│ ├── file_not_found.morpho
│ ├── for_clause.morpho
│ ├── for_clause_restrict.morpho
│ ├── for_string_after_for.morpho
│ ├── import_class_extends.morpho
│ ├── import_file.morpho
│ ├── import_for_class.morpho
│ ├── import_module.morpho
│ ├── import_underscore.morpho
│ ├── importtest.m
│ ├── module_not_found.morpho
│ ├── multiple.morpho
│ ├── multiple_as.morpho
│ ├── nested_import_in_module.morpho
│ ├── nestedimporttest.m
│ ├── nestedimporttest2.m
│ ├── one_for_per_line.morpho
│ ├── optional.morpho
│ ├── optional_in_module.morpho
│ └── underscoreimporttest.m
├── inheritance/
│ ├── constructor.morpho
│ ├── inherit_from_function.morpho
│ ├── inherit_from_nil.morpho
│ ├── inherit_from_number.morpho
│ ├── inherit_methods.morpho
│ ├── parenthesized_superclass.morpho
│ └── set_fields_from_base_class.morpho
├── integrate/
│ ├── counter.morpho
│ ├── embedding.morpho
│ ├── integrals1d.morpho
│ ├── integrals2d.morpho
│ ├── integrals2d_quantities.morpho
│ ├── integrals3d.morpho
│ ├── method_entry_type.morpho
│ ├── method_not_a_dict.morpho
│ ├── method_rule_not_found.morpho
│ ├── method_rule_unavlb.morpho
│ └── too_many_subdivisions.morpho
├── invocation/
│ ├── invocation.morpho
│ └── invocation_on_class.morpho
├── json/
│ ├── json.morpho
│ ├── testjson.morpho
│ └── tostring.morpho
├── junk/
│ ├── ctrl.morpho
│ ├── makectrl.xmorpho
│ └── oeq0.morpho
├── list/
│ ├── empty_index.morpho
│ ├── index_out_of_bounds.morpho
│ ├── inherited.morpho
│ ├── initializer_with_enumerable.morpho
│ ├── initializer_with_vars.morpho
│ ├── insert.morpho
│ ├── ismember.morpho
│ ├── join.morpho
│ ├── list_from_tuple.morpho
│ ├── nonint_index.mopho
│ ├── order.morpho
│ ├── pop_bounds.morpho
│ ├── pop_index.morpho
│ ├── pop_negative.morpho
│ ├── remove.morpho
│ ├── reverse.morpho
│ ├── roll.morpho
│ ├── sort_with_function.morpho
│ ├── sort_with_function_flt.morpho
│ ├── syntax.morpho
│ └── tuples.morpho
├── logical/
│ ├── and.morpho
│ ├── and_truth.morpho
│ ├── or.morpho
│ └── or_truth.morpho
├── math/
│ ├── isinf_isnan_isfinite.morpho
│ ├── math.morpho
│ └── sign.morpho
├── matrix/
│ ├── Lnorm.morpho
│ ├── arith_scalar.morpho
│ ├── arithmetic.morpho
│ ├── assign.morpho
│ ├── blockmatrix_constructor.morpho
│ ├── concatenate.morpho
│ ├── concatenate_sparse.morpho
│ ├── dimensions.morpho
│ ├── eigensystem.morpho
│ ├── eigenvalues.morpho
│ ├── format.morpho
│ ├── get_column.morpho
│ ├── identity.morpho
│ ├── incompatible_add.morpho
│ ├── incompatible_mul.morpho
│ ├── incompatible_sub.morpho
│ ├── inherited.morpho
│ ├── initializer.morpho
│ ├── inverse.morpho
│ ├── linearsolve.morpho
│ ├── linearsolve3x3.morpho
│ ├── negate.morpho
│ ├── nonnum_indices.morpho
│ ├── nonnum_initializer.morpho
│ ├── norm.morpho
│ ├── outer.morpho
│ ├── reshape.morpho
│ ├── roll.morpho
│ ├── scalar_mul.morpho
│ ├── set_column.morpho
│ ├── trace.morpho
│ └── transpose.morpho
├── mesh/
│ ├── addgradeerror.morpho
│ ├── addgradetwo.morpho
│ ├── addgradezero.morpho
│ ├── clone.morpho
│ ├── connectivity.morpho
│ ├── connectivity_tetrahedron.morpho
│ ├── err_empty_mesh_set_element.morpho
│ ├── err_mesh_con_args.morpho
│ ├── inherited.morpho
│ ├── load.morpho
│ ├── load_missing_coord.morpho
│ ├── load_spurious_vertex_ref.morpho
│ ├── maxgrade.morpho
│ ├── merge.morpho
│ ├── out.mesh
│ ├── removegrade.morpho
│ ├── resetconnectivity.morpho
│ ├── save.morpho
│ ├── sphere.mesh
│ ├── square.mesh
│ ├── square_missingcoord.mesh
│ ├── square_spurious_vertex_ref.mesh
│ ├── tetrahedron.mesh
│ ├── tetrahedron2.mesh
│ └── vertexposition.morpho
├── method/
│ ├── arity.morpho
│ ├── empty_block.morpho
│ ├── extra_arguments.morpho
│ ├── missing_arguments.morpho
│ ├── not_found.morpho
│ ├── optional.morpho
│ ├── optional_indirect.morpho
│ ├── print_bound_method.morpho
│ ├── return_in_method.morpho
│ ├── too_many_arguments.morpho
│ └── too_many_parameters.morpho
├── modules/
│ ├── constants.morpho
│ ├── delaunay/
│ │ └── delaunay.morpho
│ ├── meshgen/
│ │ └── disk.morpho
│ ├── meshslice/
│ │ ├── slice.morpho
│ │ ├── slice_delaunay.morpho
│ │ ├── slice_empty.morpho
│ │ └── tetrahedron.mesh
│ ├── meshtools/
│ │ ├── dimension_inconsistent.morpho
│ │ ├── dimension_unknown.morpho
│ │ ├── merge_duplicates.morpho
│ │ ├── mesh_still_too_large.morpho
│ │ ├── mesh_too_large.morpho
│ │ ├── meshrefine.morpho
│ │ ├── polyhedron.morpho
│ │ ├── testprune.morpho
│ │ ├── testrefine3d.morpho
│ │ ├── testrefineselection.morpho
│ │ ├── tetrahedron.mesh
│ │ ├── tetrahedron.morpho
│ │ ├── tetrahedron2.mesh
│ │ ├── triangle.mesh
│ │ └── triangle.morpho
│ ├── optimize/
│ │ └── cg.morpho
│ └── povray.morpho
├── namespace/
│ ├── function.xmorpho
│ ├── namespace_class.morpho
│ ├── namespace_class_extends.morpho
│ ├── namespace_class_restrict.morpho
│ └── namespace_functioncall.morpho
├── newline/
│ ├── block.morpho
│ ├── classes.morpho
│ ├── for.morpho
│ ├── functions.morpho
│ └── variables.morpho
├── nil/
│ └── literal.morpho
├── number/
│ ├── decimal_point_at_eof.morpho
│ ├── float_negative_overflow.morpho
│ ├── float_overflow.morpho
│ ├── integer_overflow.morpho
│ ├── leading_dot.morpho
│ ├── literals.morpho
│ ├── nan_equality.morpho
│ └── trailing_dot.morpho
├── object/
│ ├── baseclass.morpho
│ ├── builtin_inheritance.morpho
│ ├── class_responds_to.morpho
│ ├── clone.morpho
│ ├── enumerate.morpho
│ ├── has.morpho
│ ├── index.morpho
│ ├── invoke.morpho
│ ├── non_string_index.morpho
│ └── responds_to.morpho
├── operator/
│ ├── add.morpho
│ ├── add_bool_nil.morpho
│ ├── add_bool_num.morpho
│ ├── add_bool_string.morpho
│ ├── add_nil_nil.morpho
│ ├── add_num_nil.morpho
│ ├── add_string_nil.morpho
│ ├── comparison.morpho
│ ├── divide.morpho
│ ├── divide_nonnum_num.morpho
│ ├── divide_num_nonnum.morpho
│ ├── equals.morpho
│ ├── equals_class.morpho
│ ├── equals_method.morpho
│ ├── fpcompare.morpho
│ ├── greater_nonnum_num.morpho
│ ├── greater_num_nonnum.morpho
│ ├── greater_or_equal_nonnum_num.morpho
│ ├── greater_or_equal_num_nonnum.morpho
│ ├── less_nonnum_num.morpho
│ ├── less_num_nonnum.morpho
│ ├── less_or_equal_nonnum_num.morpho
│ ├── less_or_equal_num_nonnum.morpho
│ ├── more_comparison.morpho
│ ├── multiply.morpho
│ ├── multiply_nonnum_num.morpho
│ ├── multiply_num_nonnum.morpho
│ ├── negate.morpho
│ ├── negate_nonnum.morpho
│ ├── not.morpho
│ ├── not_class.morpho
│ ├── not_equals.morpho
│ ├── subtract.morpho
│ ├── subtract_nonnum_num.morpho
│ ├── subtract_num_nonnum.morpho
│ ├── ternary.morpho
│ ├── ternary_in_function.morpho
│ ├── ternary_in_loop.morpho
│ ├── ternary_missing_colon.morpho
│ └── ternary_nested.morpho
├── print/
│ └── missing_argument.morpho
├── programs/
│ ├── delta_blue.morpho
│ ├── fannkuch.morpho
│ ├── fibonacci.morpho
│ ├── histogram.morpho
│ └── integrate.morpho
├── property/
│ ├── call_function_field.morpho
│ ├── call_nonfunction_field.morpho
│ ├── get_on_bool.morpho
│ ├── get_on_class.morpho
│ ├── get_on_function.morpho
│ ├── get_on_nil.morpho
│ ├── get_on_num.morpho
│ ├── get_on_string.morpho
│ ├── index_property_in_args.morpho
│ ├── many.morpho
│ ├── method.morpho
│ ├── method_binds_self.morpho
│ ├── on_instance.morpho
│ ├── property_error_in_index.morpho
│ ├── property_index.morpho
│ ├── set_evaluation_order.morpho
│ ├── set_index_property.morpho
│ ├── set_on_bool.morpho
│ ├── set_on_class.morpho
│ ├── set_on_function.morpho
│ ├── set_on_nil.morpho
│ ├── set_on_num.morpho
│ ├── set_on_string.morpho
│ └── undefined.morpho
├── range/
│ ├── constructor.morpho
│ ├── count_down.morpho
│ ├── exclusive.morpho
│ ├── inclusive.morpho
│ ├── inherited.morpho
│ ├── invalid_constructor_too_few_args.morpho
│ ├── invalid_constructor_too_many_args.morpho
│ ├── invalid_constructor_type.morpho
│ ├── list_constructor.morpho
│ ├── step_too_fine.morpho
│ └── syntax.morpho
├── return/
│ ├── after_else.morpho
│ ├── after_if.morpho
│ ├── after_while.morpho
│ ├── at_top_level.morpho
│ ├── in_for_in.morpho
│ ├── in_function.morpho
│ ├── in_method.morpho
│ └── return_nil_if_no_value.morpho
├── selection/
│ ├── add_grade.morpho
│ ├── boundary.morpho
│ ├── circlesquare.mesh
│ ├── clone.morpho
│ ├── count.morpho
│ ├── get_index.morpho
│ ├── inherited.morpho
│ ├── no_mesh_error.morpho
│ ├── selection.morpho
│ ├── selection_withmatrix.morpho
│ ├── set_index.morpho
│ ├── set_operations.morpho
│ └── square.mesh
├── self/
│ ├── closure.morpho
│ ├── nested_class.morpho
│ ├── nested_closure.morpho
│ ├── self_at_top_level.morpho
│ ├── self_in_method.morpho
│ ├── self_in_top_level_function.morpho
│ └── self_set_prop_index.morpho
├── slice/
│ ├── arraySlicing.morpho
│ ├── listSlicing.morpho
│ └── matrixSlicing.morpho
├── sparse/
│ ├── arithmetic.morpho
│ ├── block_constructor_dimensions.morpho
│ ├── clone.morpho
│ ├── col_indices.morpho
│ ├── column.morpho
│ ├── concatenate.morpho
│ ├── dense_sparse_mul.morpho
│ ├── dimensions.morpho
│ ├── edit_sparse.morpho
│ ├── empty_initializer.morpho
│ ├── enumerate.morpho
│ ├── incompatible_add.morpho
│ ├── incompatible_mul.morpho
│ ├── indices.morpho
│ ├── inherited.morpho
│ ├── initializer.morpho
│ ├── invld_initializer.morpho
│ ├── linearsolve.morpho
│ ├── nonnum.morpho
│ ├── row_indices.morpho
│ ├── scalar_mul.morpho
│ ├── set_row_indices.morpho
│ ├── sparse_dense_mul.morpho
│ ├── sparse_dense_mul_dimensions.morpho
│ ├── sparse_empty.morpho
│ ├── sparse_empty_list.morpho
│ ├── todensematrix.morpho
│ └── transpose.morpho
├── string/
│ ├── ctrl_in_string.morpho
│ ├── empty_interpolation.morpho
│ ├── error_after_multiline.morpho
│ ├── escape.morpho
│ ├── escchar.morpho
│ ├── index.morpho
│ ├── inherited.morpho
│ ├── interpolation.morpho
│ ├── interpolation_keyword.morpho
│ ├── interpolation_propertyindex.morpho
│ ├── interpolation_syntaxerror.morpho
│ ├── interpolation_types.morpho
│ ├── invalid_unicode.morpho
│ ├── literals.morpho
│ ├── multiline.morpho
│ ├── split.morpho
│ ├── split_gc.morpho
│ ├── string_veneer.morpho
│ ├── tonumber.morpho
│ ├── unicode.morpho
│ ├── unterminated.morpho
│ └── utf8.morpho
├── super/
│ ├── bound_method.morpho
│ ├── call_other_method.morpho
│ ├── call_same_method.morpho
│ ├── closure.morpho
│ ├── constructor.morpho
│ ├── extra_arguments.morpho
│ ├── indirectly_inherited.morpho
│ ├── missing_arguments.morpho
│ ├── no_superclass_bind.morpho
│ ├── no_superclass_call.morpho
│ ├── no_superclass_method.morpho
│ ├── parenthesized.morpho
│ ├── reassign_superclass.morpho
│ ├── self_in_superclass_method.morpho
│ ├── super_at_top_level.morpho
│ ├── super_in_closure_in_inherited_method.morpho
│ ├── super_in_inherited_method.morpho
│ ├── super_in_top_level_function.morpho
│ ├── super_without_dot.morpho
│ └── super_without_name.morpho
├── syntax/
│ ├── comments.morpho
│ ├── empty_file.morpho
│ ├── illegal_chars_in_symbol.morpho
│ └── symbols.morpho
├── system/
│ ├── args.morpho
│ ├── args.xmorpho
│ └── system.morpho
├── test.py
├── try/
│ ├── break_in_catch.morpho
│ ├── continue_in_catch.morpho
│ ├── err_stack_overflw.morpho
│ ├── return_in_try.morpho
│ ├── try.morpho
│ ├── try_builtin_err.morpho
│ ├── try_empty_block.morpho
│ ├── try_empty_catch.morpho
│ ├── try_empty_label.morpho
│ ├── try_err_in_function.morpho
│ ├── try_in_function.morpho
│ ├── try_in_loop.morpho
│ ├── try_in_method.morpho
│ ├── try_missing_catch.morpho
│ ├── try_missing_catch_block.morpho
│ ├── try_nested.morpho
│ ├── try_recurse.morpho
│ ├── try_reentrancy.morpho
│ ├── try_reentrancy_uncaught.morpho
│ └── try_var_in_catch.morpho
├── tuple/
│ ├── nested_tuple.morpho
│ ├── single_nested_tuple.morpho
│ ├── tuple.morpho
│ ├── tuple_anonymousfn.morpho
│ ├── tuple_apply.morpho
│ ├── tuple_compare.morpho
│ ├── tuple_enumerate.morpho
│ ├── tuple_getindex.morpho
│ ├── tuple_in_dictionary.morpho
│ ├── tuple_index_out_of_bounds.morpho
│ ├── tuple_ismember.morpho
│ ├── tuple_join.morpho
│ ├── tuple_slice.morpho
│ └── tuple_syntax.morpho
├── type/
│ ├── iscallable.morpho
│ └── typecheck.morpho
├── types/
│ ├── builtin_class_signature.morpho
│ ├── function_signature.morpho
│ ├── multiple_dispatch/
│ │ ├── apply.morpho
│ │ ├── apply_invocation_multiple_dispatch.morpho
│ │ ├── check_args.morpho
│ │ ├── class_multiple_dispatch.morpho
│ │ ├── class_multiple_dispatch_args.morpho
│ │ ├── class_multiple_dispatch_post.morpho
│ │ ├── class_multiple_initializer.morpho
│ │ ├── class_visitor.morpho
│ │ ├── closure.morpho
│ │ ├── deep_nested_closure.morpho
│ │ ├── duplicate.morpho
│ │ ├── duplicate_no_arg.morpho
│ │ ├── duplicate_no_type.morpho
│ │ ├── duplicate_no_type_two.morpho
│ │ ├── duplicate_no_type_two_arguments.morpho
│ │ ├── duplicate_one_arg.morpho
│ │ ├── duplicate_scope.morpho
│ │ ├── free.morpho
│ │ ├── import.morpho
│ │ ├── import_for.morpho
│ │ ├── in_function.morpho
│ │ ├── inheritance.morpho
│ │ ├── inheritance_single.morpho
│ │ ├── instance.morpho
│ │ ├── invocation_multiple_dispatch.morpho
│ │ ├── multi_nested_closure.morpho
│ │ ├── multiple_dispatch.morpho
│ │ ├── namespace.morpho
│ │ ├── namespace.xmorpho
│ │ ├── namespace_for.morpho
│ │ ├── namespace_for_new.morpho
│ │ ├── namespace_for_overwrite.morpho
│ │ ├── nested_closure.morpho
│ │ ├── nparams.morpho
│ │ ├── nparams_varg.morpho
│ │ ├── object_overflow.morpho
│ │ ├── optional.morpho
│ │ ├── optional_invld.morpho
│ │ ├── pets.morpho
│ │ ├── pets.zmorpho
│ │ ├── pets_subclass.morpho
│ │ ├── recursion.morpho
│ │ ├── scope.morpho
│ │ ├── two.morpho
│ │ ├── value.morpho
│ │ ├── varg.morpho
│ │ └── varg_as_backup.morpho
│ ├── type_from_namespace.morpho
│ ├── type_in_function.morpho
│ ├── type_in_function_fake_namespace.morpho
│ ├── type_in_function_namespace.morpho
│ ├── type_in_function_namespace_not_found.morpho
│ ├── type_in_global.morpho
│ ├── type_inheritance.morpho
│ ├── type_instance.morpho
│ ├── type_namespace.xmorpho
│ ├── type_violation_constant.morpho
│ ├── type_violation_dictionary.morpho
│ ├── type_violation_global.morpho
│ ├── type_violation_in_function.morpho
│ ├── type_violation_inheritance.morpho
│ ├── type_violation_instance.morpho
│ ├── type_violation_matrix.morpho
│ ├── type_violation_propagation.morpho
│ └── type_violation_range.morpho
├── valgrind.py
├── variable/
│ ├── duplicate_local.morpho
│ ├── duplicate_parameter.morpho
│ ├── early_bound.morpho
│ ├── in_middle_of_block.morpho
│ ├── in_nested_block.morpho
│ ├── local_from_method.morpho
│ ├── multiple.morpho
│ ├── redeclare_global.morpho
│ ├── redefine_global.morpho
│ ├── scope_reuse_in_different_blocks.morpho
│ ├── shadow_and_local.morpho
│ ├── shadow_global.morpho
│ ├── shadow_local.morpho
│ ├── undefined_global.morpho
│ ├── undefined_local.morpho
│ ├── uninitialized.morpho
│ ├── unreached_undefined.morpho
│ ├── use_false_as_var.morpho
│ ├── use_global_in_initializer.morpho
│ ├── use_nil_as_var.morpho
│ ├── use_self_as_var.morpho
│ └── var_dictionary_as_label.morpho
├── veneer/
│ ├── bool.morpho
│ ├── float.morpho
│ ├── format_args.morpho
│ ├── format_invld_args.morpho
│ ├── int.morpho
│ └── invocation.morpho
├── vtk/
│ ├── ensurevtkfilename.morpho
│ ├── export_and_import_mesh.morpho
│ ├── export_and_import_no_fieldname.morpho
│ ├── export_and_import_scalar.morpho
│ ├── export_and_import_scalar_and_vector.morpho
│ ├── export_and_import_vector.morpho
│ ├── export_and_import_vector_2d.morpho
│ ├── export_import_2d.morpho
│ ├── export_import_3d.morpho
│ ├── export_incorrect_field_4d_vector.morpho
│ ├── export_incorrect_field_grade1.morpho
│ ├── export_incorrect_field_grade2.morpho
│ ├── export_incorrect_field_tensor.morpho
│ ├── import_external_vtk.morpho
│ ├── import_mesh.morpho
│ ├── import_scalar.morpho
│ ├── import_scalar_vector.morpho
│ ├── import_vector.morpho
│ ├── importer_containsfield.morpho
│ ├── importer_fieldlist.morpho
│ ├── importer_incorrect_fieldname.morpho
│ ├── mesh.vtk
│ ├── mesh_scalar.vtk
│ ├── mesh_scalar_vector.vtk
│ ├── mesh_vector.vtk
│ ├── rbc_001.vtk
│ ├── square.mesh
│ ├── tetrahedron.mesh
│ ├── vtk_exporter_addfield_fname_not_str_err.morpho
│ ├── vtk_exporter_fname_not_str_err.morpho
│ ├── vtk_exporter_init_err.morpho
│ └── vtk_exporter_invalid_fname_err.morpho
├── wc
└── while/
├── class_in_body.morpho
├── closure_in_body.morpho
├── fn_in_body.morpho
├── if_in_body.morpho
├── return_closure.morpho
├── return_inside.morpho
├── syntax.morpho
└── var_in_body.morpho
SYMBOL INDEX (1851 symbols across 100 files)
FILE: examples/examples.py
function finderror (line 21) | def finderror(str):
function simplify_errors (line 27) | def simplify_errors(str):
function simplify_stacktrace (line 32) | def simplify_stacktrace(str):
function iserror (line 35) | def iserror(str):
function remove_control_characters (line 39) | def remove_control_characters(str):
function isin (line 42) | def isin(str):
function getoutput (line 49) | def getoutput(filepath):
function run (line 67) | def run(file,testLog,CI):
FILE: src/builtin/builtin.c
function builtin_init (line 43) | void builtin_init(objectbuiltinfunction *func) {
function builtin_clear (line 52) | void builtin_clear(objectbuiltinfunction *func) {
function builtin_enumerateloop (line 64) | bool builtin_enumerateloop(vm *v, value obj, builtin_loopfunction fn, vo...
function builtin_bindobject (line 85) | void builtin_bindobject(object *obj) {
function builtin_options (line 102) | bool builtin_options(vm *v, int nargs, value *args, int *nfixed, int nop...
function builtin_iscallable (line 128) | bool builtin_iscallable(value val) {
function objectbuiltinfunction_printfn (line 141) | void objectbuiltinfunction_printfn(object *obj, void *v) {
function objectbuiltinfunction_freefn (line 146) | void objectbuiltinfunction_freefn(object *obj) {
function objectbuiltinfunction_sizefn (line 150) | size_t objectbuiltinfunction_sizefn(object *obj) {
function dictionary (line 168) | dictionary *builtin_getfunctiontable(void) {
function builtin_setfunctiontable (line 173) | void builtin_setfunctiontable(dictionary *dict) {
function dictionary (line 178) | dictionary *builtin_getclasstable(void) {
function builtin_setclasstable (line 183) | void builtin_setclasstable(dictionary *dict) {
function value (line 192) | value builtin_addfunction(char *name, builtinfunction func, builtinfunct...
function value (line 199) | value builtin_findfunction(value name) {
function objectclass (line 205) | objectclass *builtin_getparentclass(value fn) {
function builtin_addfunctiontodict (line 220) | bool builtin_addfunctiontodict(dictionary *dict, value name, value fn, v...
function morpho_addfunction (line 253) | bool morpho_addfunction(char *name, char *signature, builtinfunction fun...
function value (line 300) | value builtin_addclass(char *name, builtinclassentry desc[], value super...
function value (line 347) | value builtin_findclass(value name) {
function builtin_copysymboltable (line 354) | void builtin_copysymboltable(dictionary *out) {
function value (line 359) | value builtin_internsymbol(value symbol) {
function value (line 364) | value builtin_internsymbolascstring(char *symbol) {
function builtin_checksymbol (line 372) | bool builtin_checksymbol(value symbol) {
function builtin_initialize (line 386) | void builtin_initialize(void) {
function builtin_finalize (line 446) | void builtin_finalize(void) {
FILE: src/builtin/builtin.h
type builtinfunctionflags (line 24) | typedef unsigned int builtinfunctionflags;
type value (line 35) | typedef value (*builtinfunction) (vm *v, int nargs, value *args);
type objectbuiltinfunction (line 42) | typedef struct {
type builtinclassentry (line 62) | typedef struct {
FILE: src/builtin/functiondefs.c
function value (line 102) | value builtin_sqrt(vm *v, int nargs, value *args) {
function value (line 125) | value builtin_arctan(vm *v, int nargs, value *args) {
function value (line 163) | value builtin_real(vm *v, int nargs, value *args) {
function value (line 179) | value builtin_imag(vm *v, int nargs, value *args) {
function value (line 195) | value builtin_angle(vm *v, int nargs, value *args) {
function value (line 216) | value builtin_conj(vm *v, int nargs, value *args) {
function value (line 242) | value builtin_random(vm *v, int nargs, value *args) {
function value (line 247) | value builtin_randomnormal(vm *v, int nargs, value *args) {
function value (line 262) | value builtin_randomint(vm *v, int nargs, value *args) {
function value (line 339) | value builtin_iscallablefunction(vm *v, int nargs, value *args) {
function value (line 347) | value builtin_int(vm *v, int nargs, value *args) {
function value (line 366) | value builtin_float(vm *v, int nargs, value *args) {
function value (line 385) | value builtin_bool(vm *v, int nargs, value *args) {
function value (line 394) | value builtin_mod(vm *v, int nargs, value *args) {
type minmaxstruct (line 415) | typedef struct {
function minmaxfn (line 420) | static bool minmaxfn(vm *v, indx i, value val, void *ref) {
function builtin_minmax (line 431) | static bool builtin_minmax(vm *v, value obj, value *min, value *max) {
function builtin_minmaxargs (line 445) | bool builtin_minmaxargs(vm *v, int nargs, value *args, value *min, value...
function value (line 462) | static value builtin_bounds(vm *v, int nargs, value *args) {
function value (line 485) | static value builtin_min(vm *v, int nargs, value *args) {
function value (line 498) | static value builtin_max(vm *v, int nargs, value *args) {
function value (line 511) | static value builtin_sign(vm *v, int nargs, value *args){
function value (line 545) | value builtin_apply(vm *v, int nargs, value *args) {
function value (line 578) | value builtin_system(vm *v, int nargs, value *args) {
function value (line 589) | value builtin_clock(vm *v, int nargs, value *args) {
function functiondefs_initialize (line 604) | void functiondefs_initialize(void) {
FILE: src/classes/array.c
function objectarray_printfn (line 16) | void objectarray_printfn(object *obj, void *v) {
function objectarray_markfn (line 20) | void objectarray_markfn(object *obj, void *v) {
function objectarray_sizefn (line 27) | size_t objectarray_sizefn(object *obj) {
function object_arrayinit (line 42) | void object_arrayinit(objectarray *array, unsigned int ndim, unsigned in...
function objectarray (line 82) | objectarray *object_newarray(unsigned int ndim, unsigned int *dim) {
function array_valuelisttoindices (line 100) | bool array_valuelisttoindices(unsigned int ndim, value *in, unsigned int...
function objectarray (line 112) | objectarray *object_arrayfromvaluelist(unsigned int n, value *v) {
function objectarray (line 121) | objectarray *object_arrayfromvarrayvalue(varray_value *v) {
function objectarray (line 126) | objectarray *object_arrayfromvalueindices(unsigned int ndim, value *dim) {
function objectarray (line 135) | objectarray *object_clonearray(objectarray *array) {
function array_print_recurse (line 144) | bool array_print_recurse(vm *v, objectarray *a, unsigned int *indx, unsi...
function array_print (line 166) | void array_print(vm *v, objectarray *a) {
function errorid (line 180) | errorid array_error(objectarrayerror err) {
function errorid (line 193) | errorid array_to_matrix_error(objectarrayerror err) {
function errorid (line 210) | errorid array_to_list_error(objectarrayerror err) {
function objectarrayerror (line 223) | objectarrayerror array_getelement(objectarray *a, unsigned int ndim, uns...
function objectarrayerror (line 246) | objectarrayerror getslice(value *a, bool dimFcn(value *, unsigned int),
function objectarrayerror (line 294) | objectarrayerror setslicerecursive(value* a, value* out,objectarrayerror...
function objectarrayerror (line 344) | objectarrayerror array_setelement(objectarray *a, unsigned int ndim, uns...
function list_nestingdepth (line 369) | unsigned int list_nestingdepth(objectlist *list, unsigned int *out) {
function array_copyfromnestedlistrecurse (line 383) | static void array_copyfromnestedlistrecurse(objectlist *list, unsigned i...
function array_copyfromnestedlist (line 393) | void array_copyfromnestedlist(objectlist *in, objectarray *out) {
function objectarray (line 400) | objectarray *array_constructfromlist(unsigned int ndim, unsigned int *di...
function objectarray (line 419) | objectarray *array_constructfromarray(unsigned int ndim, unsigned int *d...
function value (line 431) | value array_constructor(vm *v, int nargs, value *args) {
function array_slicedim (line 474) | bool array_slicedim(value * a, unsigned int ndim){
function array_sliceconstructor (line 481) | void array_sliceconstructor(unsigned int *slicesize,unsigned int ndim,va...
function objectarrayerror (line 486) | objectarrayerror array_slicecopy(value * a,value * out, unsigned int ndi...
function value (line 502) | value Array_getindex(vm *v, int nargs, value *args) {
function value (line 524) | value Array_setindex(vm *v, int nargs, value *args) {
function value (line 537) | value Array_print(vm *v, int nargs, value *args) {
function value (line 547) | value Array_count(vm *v, int nargs, value *args) {
function value (line 554) | value Array_dimensions(vm *v, int nargs, value *args) {
function value (line 568) | value Array_enumerate(vm *v, int nargs, value *args) {
function value (line 586) | value Array_clone(vm *v, int nargs, value *args) {
function array_initialize (line 615) | void array_initialize(void) {
FILE: src/classes/array.h
type objectarray (line 19) | typedef struct {
type objectarrayerror (line 73) | typedef enum { ARRAY_OK, ARRAY_WRONGDIM, ARRAY_OUTOFBOUNDS, ARRAY_NONINT...
FILE: src/classes/closure.c
function objectclosure_printfn (line 15) | void objectclosure_printfn(object *obj, void *v) {
function objectclosure_markfn (line 22) | void objectclosure_markfn(object *obj, void *v) {
function objectclosure_sizefn (line 30) | size_t objectclosure_sizefn(object *obj) {
function object_closureinit (line 44) | void object_closureinit(objectclosure *c) {
function objectclosure (line 52) | objectclosure *object_newclosure(objectfunction *sf, objectfunction *fun...
function value (line 83) | value Closure_tostring(vm *v, int nargs, value *args) {
function closure_initialize (line 116) | void closure_initialize(void) {
FILE: src/classes/closure.h
type objectclosure (line 19) | typedef struct {
FILE: src/classes/clss.c
function objectclass_printfn (line 15) | void objectclass_printfn(object *obj, void *v) {
function objectclass_markfn (line 19) | void objectclass_markfn(object *obj, void *v) {
function objectclass_freefn (line 27) | void objectclass_freefn(object *obj) {
function objectclass_sizefn (line 36) | size_t objectclass_sizefn(object *obj) {
function objectclass (line 49) | objectclass *object_newclass(value name) {
function _print (line 79) | void _print(varray_value *list) {
function _intail (line 89) | bool _intail(varray_value *list, value v) {
function _remove (line 97) | void _remove(varray_value *list, value v) {
function _inanytail (line 107) | bool _inanytail(int n, varray_value *in, value v) {
function _done (line 115) | bool _done(int n, varray_value *in) {
function _merge (line 121) | bool _merge(int n, varray_value *in, varray_value *out) {
function _init (line 136) | static void _init(objectclass *parent, varray_value *out) {
function _linearize (line 141) | bool _linearize(objectclass *klass, varray_value *out) {
function class_linearize (line 165) | bool class_linearize(objectclass *klass) {
function class_initialize (line 187) | void class_initialize(void) {
FILE: src/classes/clss.h
type objectclass (line 19) | typedef struct sobjectclass {
FILE: src/classes/cmplx.c
function objectcomplex_sizefn (line 21) | size_t objectcomplex_sizefn(object *obj) {
function objectcomplex_printfn (line 25) | void objectcomplex_printfn(object *obj, void *v) {
function objectcomplex_cmpfn (line 29) | int objectcomplex_cmpfn(object *a, object *b) {
function objectcomplex (line 45) | objectcomplex *object_newcomplex(double real,double imag) {
function objectcomplex (line 60) | objectcomplex *object_complexfromfloat(double val) {
function objectcomplex (line 66) | objectcomplex *object_complexfromcomplex(MorphoComplex val) {
function objectcomplex (line 72) | objectcomplex *object_clonecomplex(objectcomplex *in) {
function value (line 78) | value object_clonecomplexvalue(value val) {
function complex_getreal (line 92) | void complex_getreal(objectcomplex *c, double *value) {
function complex_getimag (line 97) | void complex_getimag(objectcomplex *c, double *value) {
function complex_isequal (line 102) | bool complex_isequal(objectcomplex *a, objectcomplex *b) {
function complex_isequaltonumber (line 107) | bool complex_isequaltonumber(objectcomplex *a, value b) {
function complex_print (line 117) | void complex_print(vm *v, objectcomplex *a) {
function complex_add (line 136) | void complex_add(objectcomplex *a, objectcomplex *b, objectcomplex *out){
function complex_add_real (line 141) | void complex_add_real(objectcomplex *a, double b, objectcomplex *out){
function complex_sub (line 146) | void complex_sub(objectcomplex *a, objectcomplex *b, objectcomplex *out) {
function complex_mul (line 151) | void complex_mul(objectcomplex *a, objectcomplex *b, objectcomplex *out){
function complex_mul_real (line 156) | void complex_mul_real(objectcomplex *a, double b, objectcomplex *out){
function complex_copy (line 161) | void complex_copy(objectcomplex *a, objectcomplex *out) {
function complex_power (line 166) | void complex_power(objectcomplex *a, double exponent, objectcomplex *out){
function complex_cpower (line 171) | void complex_cpower(objectcomplex *a, objectcomplex *b, objectcomplex *o...
function complex_div (line 176) | void complex_div(objectcomplex *a, objectcomplex *b, objectcomplex *out){
function complex_invert (line 181) | void complex_invert(objectcomplex *a, objectcomplex *out){
function complex_conj (line 186) | void complex_conj(objectcomplex *a, objectcomplex *out) {
function complex_angle (line 191) | void complex_angle(objectcomplex *a, double *out){
function complex_abs (line 195) | void complex_abs(objectcomplex *a, double *out) {
function value (line 225) | value complex_builtinfabs(vm * v, objectcomplex *c) {
function value (line 233) | value complex_builtinlog10(vm * v, objectcomplex *c) {
function value (line 252) | value complex_builtinfloor(vm * v, objectcomplex *c) {
function value (line 259) | value complex_builtinceil(vm * v, objectcomplex *c) {
function value (line 363) | value Complex_getreal(vm *v, int nargs, value *args) {
function value (line 379) | value Complex_getimag(vm *v, int nargs, value *args) {
function value (line 395) | value Complex_print(vm *v, int nargs, value *args) {
function value (line 405) | value Complex_add(vm *v, int nargs, value *args) {
function value (line 434) | value Complex_sub(vm *v, int nargs, value *args) {
function value (line 463) | value Complex_subr(vm *v, int nargs, value *args) {
function value (line 486) | value Complex_mul(vm *v, int nargs, value *args) {
function value (line 515) | value Complex_div(vm *v, int nargs, value *args) {
function value (line 544) | value Complex_divr(vm *v, int nargs, value *args) {
function value (line 568) | value Complex_power(vm *v, int nargs, value *args) {
function value (line 599) | value Complex_powerr(vm *v, int nargs, value *args) {
function value (line 631) | value Complex_angle(vm *v, int nargs, value *args) {
function value (line 637) | value Complex_abs(vm *v, int nargs, value *args) {
function value (line 645) | value Complex_conjugate(vm *v, int nargs, value *args) {
function value (line 660) | value Complex_clone(vm *v, int nargs, value *args) {
FILE: src/classes/cmplx.h
type objectcomplex (line 22) | typedef struct {
FILE: src/classes/dict.c
function objectdictionary_printfn (line 15) | void objectdictionary_printfn(object *obj, void *v) {
function objectdictionary_freefn (line 19) | void objectdictionary_freefn(object *obj) {
function objectdictionary_markfn (line 24) | void objectdictionary_markfn(object *obj, void *v) {
function objectdictionary_sizefn (line 29) | size_t objectdictionary_sizefn(object *obj) {
function objectdictionary (line 43) | objectdictionary *object_newdictionary(void) {
function dictionary (line 56) | dictionary *object_dictionary(objectdictionary *dict) {
function value (line 61) | value dictionary_iterate(objectdictionary *dict, unsigned int n) {
function value (line 77) | value dictionary_constructor(vm *v, int nargs, value *args) {
function value (line 95) | value Dictionary_getindex(vm *v, int nargs, value *args) {
function value (line 109) | value Dictionary_setindex(vm *v, int nargs, value *args) {
function value (line 124) | value Dictionary_contains(vm *v, int nargs, value *args) {
function value (line 136) | value Dictionary_remove(vm *v, int nargs, value *args) {
function value (line 147) | value Dictionary_clear(vm *v, int nargs, value *args) {
function value (line 156) | value Dictionary_print(vm *v, int nargs, value *args) {
function value (line 179) | value Dictionary_count(vm *v, int nargs, value *args) {
function value (line 186) | value Dictionary_enumerate(vm *v, int nargs, value *args) {
function value (line 201) | value Dictionary_keys(vm *v, int nargs, value *args) {
function value (line 220) | value Dictionary_clone(vm *v, int nargs, value *args) {
FILE: src/classes/dict.h
type objectdictionary (line 20) | typedef struct {
FILE: src/classes/err.c
function value (line 22) | value Error_init(vm *v, int nargs, value *args) {
function _err_extract (line 37) | bool _err_extract(vm *v, int nargs, value *args, value *tag, value *msg) {
function value (line 58) | value Error_throw(vm *v, int nargs, value *args) {
function value (line 73) | value Error_warning(vm *v, int nargs, value *args) {
function value (line 88) | value Error_print(vm *v, int nargs, value *args) {
FILE: src/classes/file.c
function objectfile_sizefn (line 25) | size_t objectfile_sizefn(object *obj) {
function objectfile_markfn (line 29) | void objectfile_markfn(object *obj, void *v) {
function objectfile_freefn (line 34) | void objectfile_freefn(object *obj) {
function objectfile_printfn (line 39) | void objectfile_printfn(object *obj, void *v) {
function objectfile (line 56) | objectfile *object_newfile(value filename, FILE *f) {
function file_getsize (line 74) | bool file_getsize(FILE *f, size_t *s) {
function FILE (line 85) | FILE *file_getfile(value obj) {
function file_setfile (line 91) | void file_setfile(value obj, FILE *f) {
function file_setworkingdirectory (line 97) | void file_setworkingdirectory(const char *path) {
function file_relativepath (line 114) | void file_relativepath(const char *fname, varray_char *name) {
function FILE (line 130) | FILE *file_openrelative(const char *fname, const char *mode) {
function file_readlineintovarray (line 144) | int file_readlineintovarray(FILE *f, varray_char *string) {
function file_readintovarray (line 159) | bool file_readintovarray(FILE *f, varray_char *string) {
function value (line 174) | value file_readlineusingvarray(FILE *f, varray_char *string) {
function value (line 192) | value file_constructor(vm *v, int nargs, value *args) {
function value (line 235) | value File_close(vm *v, int nargs, value *args) {
function value (line 246) | value File_lines(vm *v, int nargs, value *args) {
function value (line 276) | value File_readall(vm *v, int nargs, value *args) {
function value (line 293) | value File_readline(vm *v, int nargs, value *args) {
function value (line 309) | value File_readchar(vm *v, int nargs, value *args) {
function value (line 324) | value File_write(vm *v, int nargs, value *args) {
function value (line 340) | value File_relativepath(vm *v, int nargs, value *args) {
function value (line 358) | value File_filename(vm *v, int nargs, value *args) {
function value (line 363) | value File_eof(vm *v, int nargs, value *args) {
function value (line 402) | value Folder_contents(vm *v, int nargs, value *args) {
function file_finalize (line 477) | void file_finalize(void) {
FILE: src/classes/file.h
type objectfile (line 21) | typedef struct {
FILE: src/classes/flt.c
function value (line 11) | value Value_format(vm *v, int nargs, value *args) {
FILE: src/classes/function.c
function objectfunction_freefn (line 15) | void objectfunction_freefn(object *obj) {
function objectfunction_markfn (line 23) | void objectfunction_markfn(object *obj, void *v) {
function objectfunction_sizefn (line 29) | size_t objectfunction_sizefn(object *obj) {
function objectfunction_printfn (line 33) | void objectfunction_printfn(object *obj, void *v) {
function object_functioninit (line 52) | void object_functioninit(objectfunction *func) {
function object_functionclear (line 66) | void object_functionclear(objectfunction *func) {
function objectfunction (line 77) | objectfunction *object_newfunction(indx entry, value name, objectfunctio...
function objectfunction (line 95) | objectfunction *object_getfunctionparent(objectfunction *func) {
function value (line 100) | value object_getfunctionname(objectfunction *func) {
function varray_value (line 105) | varray_value *object_functiongetconstanttable(objectfunction *func) {
function object_functionaddprototype (line 118) | bool object_functionaddprototype(objectfunction *func, varray_upvalue *v...
function function_countpositionalargs (line 129) | int function_countpositionalargs(objectfunction *func) {
function function_countoptionalargs (line 134) | int function_countoptionalargs(objectfunction *func) {
function function_hasvargs (line 139) | bool function_hasvargs(objectfunction *func) {
function function_setvarg (line 144) | void function_setvarg(objectfunction *func, int varg) {
function function_setclosure (line 149) | void function_setclosure(objectfunction *func, int creg) {
function function_isclosure (line 154) | bool function_isclosure(objectfunction *func) {
function function_setsignature (line 161) | void function_setsignature(objectfunction *func, value *signature) {
function function_hastypedparameters (line 166) | bool function_hastypedparameters(objectfunction *func) {
function value (line 174) | value Function_tostring(vm *v, int nargs, value *args) {
function function_initialize (line 205) | void function_initialize(void) {
FILE: src/classes/function.h
type optionalparam (line 20) | typedef struct {
type objectfunction (line 29) | typedef struct sobjectfunction {
FILE: src/classes/instance.c
function objectinstance_printfn (line 15) | void objectinstance_printfn(object *obj, void *v) {
function objectinstance_markfn (line 19) | void objectinstance_markfn(object *obj, void *v) {
function objectinstance_freefn (line 24) | void objectinstance_freefn(object *obj) {
function objectinstance_sizefn (line 29) | size_t objectinstance_sizefn(object *obj) {
function objectinstance (line 43) | objectinstance *object_newinstance(objectclass *klass) {
function objectinstance_setproperty (line 64) | bool objectinstance_setproperty(objectinstance *obj, value key, value va...
function objectinstance_getproperty (line 73) | bool objectinstance_getproperty(objectinstance *obj, value key, value *v...
function objectinstance_getpropertyinterned (line 83) | bool objectinstance_getpropertyinterned(objectinstance *obj, value key, ...
function value (line 92) | value Object_getindex(vm *v, int nargs, value *args) {
function value (line 109) | value Object_setindex(vm *v, int nargs, value *args) {
function value (line 123) | value Object_class(vm *v, int nargs, value *args) {
function value (line 134) | value Object_super(vm *v, int nargs, value *args) {
function value (line 143) | value Object_respondsto(vm *v, int nargs, value *args) {
function value (line 172) | value Object_has(vm *v, int nargs, value *args) {
function value (line 202) | value Object_invoke(vm *v, int nargs, value *args) {
function value (line 220) | value Object_print(vm *v, int nargs, value *args) {
function value (line 236) | value Object_count(vm *v, int nargs, value *args) {
function value (line 250) | value Object_enumerate(vm *v, int nargs, value *args) {
function value (line 280) | value Object_serialize(vm *v, int nargs, value *args) {
function value (line 285) | value Object_clone(vm *v, int nargs, value *args) {
function value (line 304) | value Object_linearization(vm *v, int nargs, value *args) {
function instance_initialize (line 345) | void instance_initialize(void) {
FILE: src/classes/instance.h
type objectinstance (line 19) | typedef struct {
FILE: src/classes/invocation.c
function objectinvocation_printfn (line 16) | void objectinvocation_printfn(object *obj, void *v) {
function objectinvocation_markfn (line 23) | void objectinvocation_markfn(object *obj, void *v) {
function objectinvocation_sizefn (line 29) | size_t objectinvocation_sizefn(object *obj) {
function objectinvocation (line 47) | objectinvocation *object_newinvocation(value receiver, value method) {
function value (line 63) | value invocation_constructor(vm *v, int nargs, value *args) {
function value (line 94) | value Invocation_tostring(vm *v, int nargs, value *args) {
function value (line 115) | value Invocation_clone(vm *v, int nargs, value *args) {
function invocation_initialize (line 143) | void invocation_initialize(void) {
FILE: src/classes/invocation.h
type objectinvocation (line 28) | typedef struct {
FILE: src/classes/json.c
function json_lexwhitespace (line 63) | bool json_lexwhitespace(lexer *l, token *tok, error *err) {
function json_lexstring (line 83) | bool json_lexstring(lexer *l, token *tok, error *err) {
function json_lexnumber (line 102) | bool json_lexnumber(lexer *l, token *tok, error *err) {
function json_lexpreprocess (line 149) | bool json_lexpreprocess(lexer *l, token *tok, error *err) {
function json_initializelexer (line 159) | void json_initializelexer(lexer *l, char *src) {
type jsonoutput (line 176) | typedef struct {
function json_setoutput (line 182) | void json_setoutput(void *out, value v) {
function value (line 189) | value json_getoutput(jsonoutput *out) {
function json_outputinit (line 195) | void json_outputinit(jsonoutput *out, varray_value *output) {
function json_parsestring (line 208) | bool json_parsestring(parser *p, void *out) {
function json_parsenumber (line 260) | bool json_parsenumber(parser *p, void *out) {
function json_parsefloat (line 270) | bool json_parsefloat(parser *p, void *out) {
function json_parsetrue (line 280) | bool json_parsetrue(parser *p, void *out) {
function json_parsefalse (line 286) | bool json_parsefalse(parser *p, void *out) {
function json_parsenull (line 292) | bool json_parsenull(parser *p, void *out) {
function json_parseobject (line 298) | bool json_parseobject(parser *p, void *out) {
function json_parsearray (line 341) | bool json_parsearray(parser *p, void *out) {
function json_parsevalue (line 374) | bool json_parsevalue(parser *p, void *out) {
function json_parseelement (line 384) | bool json_parseelement(parser *p, void *out) {
function json_initializeparser (line 417) | void json_initializeparser(parser *p, lexer *l, error *err, void *out) {
function json_parse (line 434) | bool json_parse(char *in, error *err, value *out, varray_value *objects) {
function json_valuetovarraychar (line 468) | bool json_valuetovarraychar(vm *v, value in, varray_char *out) {
function json_tostring (line 544) | bool json_tostring(vm *v, value in, value *out) {
function value (line 567) | value JSON_parse(vm *v, int nargs, value *args) {
function value (line 587) | value JSON_tostring(vm *v, int nargs, value *args) {
FILE: src/classes/list.c
function objectlist_printfn (line 15) | void objectlist_printfn(object *obj, void *v) {
function objectlist_freefn (line 19) | void objectlist_freefn(object *obj) {
function objectlist_markfn (line 24) | void objectlist_markfn(object *obj, void *v) {
function objectlist_sizefn (line 29) | size_t objectlist_sizefn(object *obj) {
function objectlist (line 44) | objectlist *object_newlist(unsigned int nval, value *val) {
function list_resize (line 63) | bool list_resize(objectlist *list, int size) {
function list_append (line 68) | void list_append(objectlist *list, value v) {
function list_length (line 73) | unsigned int list_length(objectlist *list) {
function list_insert (line 83) | bool list_insert(objectlist *list, int indx, int nval, value *vals) {
function list_remove (line 101) | bool list_remove(objectlist *list, value val) {
function list_getelement (line 119) | bool list_getelement(objectlist *list, int i, value *out) {
function list_sortfunction (line 127) | int list_sortfunction(const void *a, const void *b) {
function list_sort (line 133) | void list_sort(objectlist *list) {
function list_sortfunctionwfn (line 142) | int list_sortfunctionwfn(const void *a, const void *b) {
function list_sortwithfn (line 156) | bool list_sortwithfn(vm *v, value fn, objectlist *list) {
type listorderstruct (line 165) | typedef struct {
function list_orderfunction (line 171) | int list_orderfunction(const void *a, const void *b) {
function objectlist (line 176) | objectlist *list_order(objectlist *list) {
function list_reverse (line 201) | void list_reverse(objectlist *list) {
function list_ismember (line 212) | bool list_ismember(objectlist *list, value v) {
function objectlist (line 220) | objectlist *list_clone(objectlist *list) {
function objectlist (line 225) | objectlist *list_concatenate(objectlist *a, objectlist *b) {
function objectlist (line 240) | objectlist *list_roll(objectlist *a, int nplaces) {
function list_enumerableinitializer (line 263) | static bool list_enumerableinitializer(vm *v, indx i, value val, void *r...
function list_sliceconstructor (line 270) | void list_sliceconstructor(unsigned int *slicesize, unsigned int ndim, v...
function list_slicedim (line 277) | bool list_slicedim(value * a, unsigned int ndim){
function objectarrayerror (line 283) | objectarrayerror list_slicecopy(value * a,value * out, unsigned int ndim...
function value (line 294) | value list_generatetuples(vm *v, objectlist *list, unsigned int n, tuple...
function value (line 336) | value list_constructor(vm *v, int nargs, value *args) {
function value (line 366) | value List_append(vm *v, int nargs, value *args) {
function value (line 379) | value List_remove(vm *v, int nargs, value *args) {
function value (line 390) | value List_insert(vm *v, int nargs, value *args) {
function value (line 404) | value List_pop(vm *v, int nargs, value *args) {
function value (line 430) | value List_getindex(vm *v, int nargs, value *args) {
function value (line 455) | value List_setindex(vm *v, int nargs, value *args) {
function value (line 470) | value List_print(vm *v, int nargs, value *args) {
function value (line 487) | value List_tostring(vm *v, int nargs, value *args) {
function value (line 511) | value List_enumerate(vm *v, int nargs, value *args) {
function value (line 531) | value List_count(vm *v, int nargs, value *args) {
function value (line 538) | value List_tuples(vm *v, int nargs, value *args) {
function value (line 551) | value List_sets(vm *v, int nargs, value *args) {
function value (line 565) | value List_clone(vm *v, int nargs, value *args) {
function value (line 575) | value List_join(vm *v, int nargs, value *args) {
function value (line 594) | value List_roll(vm *v, int nargs, value *args) {
function value (line 616) | value XList_sort(vm *v, int nargs, value *args) {
function value (line 631) | value List_sort(vm *v, int nargs, value *args) {
function value (line 636) | value List_sort_fn(vm *v, int nargs, value *args) {
function value (line 645) | value List_order(vm *v, int nargs, value *args) {
function value (line 659) | value List_reverse(vm *v, int nargs, value *args) {
function value (line 668) | value List_ismember(vm *v, int nargs, value *args) {
function list_initialize (line 709) | void list_initialize(void) {
FILE: src/classes/list.h
type objectlist (line 19) | typedef struct {
FILE: src/classes/metafunction.c
function objectmetafunction_freefn (line 36) | void objectmetafunction_freefn(object *obj) {
function objectmetafunction_markfn (line 43) | void objectmetafunction_markfn(object *obj, void *v) {
function objectmetafunction_sizefn (line 53) | size_t objectmetafunction_sizefn(object *obj) {
function objectmetafunction_printfn (line 58) | void objectmetafunction_printfn(object *obj, void *v) {
function objectmetafunction (line 77) | objectmetafunction *object_newmetafunction(value name) {
function objectmetafunction (line 92) | objectmetafunction *metafunction_clone(objectmetafunction *f) {
function metafunction_wrap (line 103) | bool metafunction_wrap(value name, value fn, value *out) {
function metafunction_add (line 116) | bool metafunction_add(objectmetafunction *f, value fn) {
function metafunction_typefromvalue (line 121) | bool metafunction_typefromvalue(value v, value *out) {
function metafunction_matchtype (line 135) | bool metafunction_matchtype(value type, value val) {
function metafunction_setclass (line 146) | void metafunction_setclass(objectmetafunction *f, objectclass *klass) {
function objectclass (line 151) | objectclass *metafunction_class(objectmetafunction *f) {
function metafunction_matchfn (line 156) | bool metafunction_matchfn(objectmetafunction *fn, value f) {
function metafunction_matchset (line 162) | bool metafunction_matchset(objectmetafunction *fn, int n, value *fns) {
function signature (line 169) | signature *metafunction_getsignature(value fn) {
function value (line 180) | value _getname(value fn) {
type mfresult (line 208) | typedef struct {
type mfset (line 214) | typedef struct {
type mfcompiler (line 225) | typedef struct {
function mfcompiler_init (line 232) | void mfcompiler_init(mfcompiler *c, objectmetafunction *fn) {
function mfcompiler_clear (line 239) | void mfcompiler_clear(mfcompiler *c, objectmetafunction *fn) {
function mfcompiler_error (line 245) | void mfcompiler_error(mfcompiler *c, errorid id) {
function mfcompiler_pushcheck (line 250) | void mfcompiler_pushcheck(mfcompiler *c, int i) {
function mfcompiler_popcheck (line 255) | int mfcompiler_popcheck(mfcompiler *c) {
function mfcompiler_ischecked (line 261) | bool mfcompiler_ischecked(mfcompiler *c, int i) {
function _mfcompiler_disassemblebranchtable (line 266) | void _mfcompiler_disassemblebranchtable(mfinstruction *instr, mfindx i) {
function mfcompiler_disassemble (line 273) | void mfcompiler_disassemble(mfcompiler *c) {
function mfcompile_countparams (line 349) | void mfcompile_countparams(mfcompiler *c, mfset *set, int *min, int *max) {
function mfcompile_outcomes (line 362) | bool mfcompile_outcomes(mfcompiler *c, mfset *set, int i, dictionary *ou...
function mfcompile_countoutcomes (line 372) | bool mfcompile_countoutcomes(mfcompiler *c, mfset *set, int *best) {
function mfindx (line 402) | mfindx mfcompile_insertinstruction(mfcompiler *c, mfinstruction instr) {
function mfindx (line 406) | mfindx mfcompile_currentinstruction(mfcompiler *c) {
function mfindx (line 410) | mfindx mfcompile_nextinstruction(mfcompiler *c) {
function mfcompile_setbranch (line 414) | void mfcompile_setbranch(mfcompiler *c, mfindx i, mfindx branch) {
function mfcompile_replaceinstruction (line 419) | void mfcompile_replaceinstruction(mfcompiler *c, mfindx i, mfinstruction...
function _detecttype (line 432) | int _detecttype(value type, int *tindx) {
function mfindx (line 454) | mfindx mfcompile_fail(mfcompiler *c) {
function mfindx (line 460) | mfindx mfcompile_check(mfcompiler *c, int i, value type) {
function mfindx (line 472) | mfindx mfcompile_resolve(mfcompiler *c, mfresult *res) {
function mfcompile_branchtable (line 498) | void mfcompile_branchtable(mfcompiler *c, mfset *set, mfindx bindx, varr...
function _insertchildren (line 518) | void _insertchildren(dictionary *dict, value v) {
function _resolve (line 527) | bool _resolve(objectclass *klass, dictionary *types, value *out) {
function _maxindx (line 537) | int _maxindx(dictionary *dict) {
function _mfresultsortfn (line 546) | int _mfresultsortfn (const void *a, const void *b) {
function mfindx (line 557) | mfindx mfcompile_dispatchtable(mfcompiler *c, mfset *set, int i, int oty...
function mfindx (line 610) | mfindx mfcompile_dispatchveneerobj(mfcompiler *c, mfset *set, int i) {
function mfindx (line 615) | mfindx mfcompile_dispatchveneervalue(mfcompiler *c, mfset *set, int i) {
function mfindx (line 620) | mfindx mfcompile_dispatchinstance(mfcompiler *c, mfset *set, int i) {
function mfindx (line 625) | mfindx mfcompile_dispatchany(mfcompiler *c, mfset *set, int i) {
function mfcompile_fixfallthrough (line 647) | void mfcompile_fixfallthrough(mfcompiler *c, mfindx i, mfindx branchto) {
type mfindx (line 652) | typedef mfindx (mfcompile_dispatchfn) (mfcompiler *c, mfset *set, int i);
function mfindx (line 655) | mfindx mfcompile_dispatchonparam(mfcompiler *c, mfset *set, int i) {
function mfindx (line 693) | mfindx mfcompile_checknarg(mfcompiler *c, mfresult *res) {
function mfindx (line 703) | mfindx mfcompile_dispatchonnarg(mfcompiler *c, mfset *set, int min, int ...
function mfindx (line 750) | mfindx mfcompile_set(mfcompiler *c, mfset *set) {
function metafunction_clearinstructions (line 772) | void metafunction_clearinstructions(objectmetafunction *fn) {
function metafunction_compile (line 781) | bool metafunction_compile(objectmetafunction *fn, error *err) {
function _finduidinlinearization (line 808) | bool _finduidinlinearization(objectclass *klass, int uid) {
function metafunction_resolve (line 822) | bool metafunction_resolve(objectmetafunction *fn, int nargs, value *args...
function value (line 906) | value metafunction_constructor(vm *v, int nargs, value *args) {
function value (line 933) | value Metafunction_count(vm *v, int nargs, value *args) {
function MORPHO_METHOD (line 939) | MORPHO_BEGINCLASS(Metafunction)
FILE: src/classes/metafunction.h
type mfindx (line 20) | typedef int mfindx;
type mfinstruction (line 23) | typedef struct {
type objectmetafunction (line 37) | typedef struct sobjectmetafunction {
FILE: src/classes/range.c
function objectrange_printfn (line 17) | void objectrange_printfn(object *obj, void *v) {
function objectrange_sizefn (line 28) | size_t objectrange_sizefn(object *obj) {
function _range_count (line 42) | bool _range_count(objectrange *range) {
function objectrange (line 77) | objectrange *object_newrange(value start, value end, value step, bool in...
function range_count (line 108) | int range_count(objectrange *range) {
function value (line 113) | value range_iterate(objectrange *range, unsigned int i) {
function value (line 127) | static value _rangeconstructor(vm *v, int nargs, value *args, bool inclu...
function value (line 145) | value range_constructor(vm *v, int nargs, value *args) {
function value (line 149) | value range_inclusiveconstructor(vm *v, int nargs, value *args) {
function value (line 154) | value range_invldconstructor(vm *v, int nargs, value *args) {
function value (line 160) | value Range_getindex(vm *v, int nargs, value *args) {
function value (line 174) | value Range_enumerate(vm *v, int nargs, value *args) {
function value (line 189) | value Range_count(vm *v, int nargs, value *args) {
function value (line 196) | value Range_clone(vm *v, int nargs, value *args) {
function range_initialize (line 224) | void range_initialize(void) {
FILE: src/classes/range.h
type objectrange (line 19) | typedef struct {
FILE: src/classes/strng.c
function objectstring_printfn (line 19) | void objectstring_printfn(object *obj, void *v) {
function objectstring_sizefn (line 23) | size_t objectstring_sizefn(object *obj) {
function hash (line 27) | hash objectstring_hashfn(object *obj) {
function objectstring_cmpfn (line 32) | int objectstring_cmpfn(object *a, object *b) {
function value (line 53) | value object_stringfromcstring(const char *in, size_t length) {
function objectstring (line 74) | objectstring *object_stringwithsize(size_t length) {
function value (line 90) | value object_stringfromvarraychar(varray_char *in) {
function value (line 96) | value object_clonestring(value val) {
function value (line 109) | value object_concatenatestring(value a, value b) {
function string_tonumber (line 134) | bool string_tonumber(objectstring *string, value *out) {
function string_countchars (line 168) | int string_countchars(objectstring *s) {
function value (line 193) | value string_constructor(vm *v, int nargs, value *args) {
function value (line 200) | value String_count(vm *v, int nargs, value *args) {
function value (line 207) | value String_print(vm *v, int nargs, value *args) {
function value (line 214) | value String_clone(vm *v, int nargs, value *args) {
function value (line 223) | value String_enumerate(vm *v, int nargs, value *args) {
function value (line 245) | value String_isnumber(vm *v, int nargs, value *args) {
function value (line 255) | value String_split(vm *v, int nargs, value *args) {
function string_initialize (line 308) | void string_initialize(void) {
FILE: src/classes/strng.h
type objectstring (line 21) | typedef struct {
FILE: src/classes/system.c
function morpho_setargs (line 22) | void morpho_setargs(int argc, const char * argv[]) {
function system_freeargs (line 32) | void system_freeargs(void) {
function value (line 49) | value System_platform(vm *v, int nargs, value *args) {
function value (line 62) | value System_version(vm *v, int nargs, value *args) {
function value (line 70) | value System_clock(vm *v, int nargs, value *args) {
function value (line 75) | value System_print(vm *v, int nargs, value *args) {
function value (line 81) | value System_sleep(vm *v, int nargs, value *args) {
function value (line 93) | value System_readline(vm *v, int nargs, value *args) {
function value (line 109) | value System_arguments(vm *v, int nargs, value *args) {
function value (line 114) | value System_exit(vm *v, int nargs, value *args) {
function value (line 120) | value System_setworkingfolder(vm *v, int nargs, value *args) {
function value (line 132) | value System_workingfolder(vm *v, int nargs, value *args) {
function value (line 149) | value System_homefolder(vm *v, int nargs, value *args) {
function system_finalize (line 200) | void system_finalize(void) {
FILE: src/classes/tuple.c
function objecttuple_printfn (line 15) | void objecttuple_printfn(object *obj, void *v) {
function objecttuple_markfn (line 25) | void objecttuple_markfn(object *obj, void *v) {
function objecttuple_sizefn (line 30) | size_t objecttuple_sizefn(object *obj) {
function hash (line 34) | hash objecttuple_hashfn(object *obj) {
function objecttuple_cmpfn (line 39) | int objecttuple_cmpfn(object *a, object *b) {
function objecttuple (line 66) | objecttuple *object_newtuple(unsigned int length, value *in) {
function tuple_length (line 83) | unsigned int tuple_length(objecttuple *tuple) {
function tuple_getelement (line 88) | bool tuple_getelement(objecttuple *tuple, int i, value *out) {
function tuple_ismember (line 96) | bool tuple_ismember(objecttuple *tuple, value v) {
function objecttuple (line 104) | objecttuple *tuple_concatenate(objecttuple *a, objecttuple *b) {
function tuple_sliceconstructor (line 122) | void tuple_sliceconstructor(unsigned int *slicesize, unsigned int ndim, ...
function tuple_slicedim (line 128) | bool tuple_slicedim(value *a, unsigned int ndim){
function objectarrayerror (line 134) | objectarrayerror tuple_slicecopy(value *a,value *out, unsigned int ndim,...
function errorid (line 145) | errorid array_to_tuple_error(objectarrayerror err) {
function value (line 162) | value tuple_constructor(vm *v, int nargs, value *args) {
function value (line 173) | value Tuple_count(vm *v, int nargs, value *args) {
function value (line 180) | value Tuple_clone(vm *v, int nargs, value *args) {
function value (line 194) | value Tuple_getindex(vm *v, int nargs, value *args) {
function value (line 216) | value Tuple_setindex(vm *v, int nargs, value *args) {
function value (line 222) | value Tuple_enumerate(vm *v, int nargs, value *args) {
function value (line 242) | value Tuple_join(vm *v, int nargs, value *args) {
function value (line 261) | value Tuple_ismember(vm *v, int nargs, value *args) {
function tuple_initialize (line 289) | void tuple_initialize(void) {
FILE: src/classes/tuple.h
type objecttuple (line 20) | typedef struct {
FILE: src/classes/upvalue.c
function objectupvalue_printfn (line 15) | void objectupvalue_printfn(object *obj, void *v) {
function objectupvalue_markfn (line 19) | void objectupvalue_markfn(object *obj, void *v) {
function objectupvalue_sizefn (line 23) | size_t objectupvalue_sizefn(object *obj) {
function object_upvalueinit (line 38) | void object_upvalueinit(objectupvalue *c) {
function objectupvalue (line 50) | objectupvalue *object_newupvalue(value *reg) {
function upvalue_initialize (line 70) | void upvalue_initialize(void) {
FILE: src/classes/upvalue.h
type upvalue (line 19) | typedef struct {
type objectupvalue (line 36) | typedef struct sobjectupvalue {
FILE: src/core/compile.c
function compiler_haserror (line 32) | static bool compiler_haserror(compiler *c) {
function compiler_error (line 41) | static void compiler_error(compiler *c, syntaxtreenode *node, errorid id...
function compiler_checkerror (line 55) | static bool compiler_checkerror(compiler *c) {
function compiler_catch (line 64) | static bool compiler_catch(compiler *c, errorid id) {
function syntaxtreenode (line 73) | static inline syntaxtreenode *compiler_getnode(compiler *c, syntaxtreein...
function syntaxtree (line 79) | static inline syntaxtree *compiler_getsyntaxtree(compiler *c) {
function instructionindx (line 84) | static instructionindx compiler_addinstruction(compiler *c, instruction ...
function instructionindx (line 90) | static instructionindx compiler_currentinstructionindex(compiler *c) {
function compiler_setinstruction (line 95) | static void compiler_setinstruction(compiler *c, instructionindx indx, ...
function compiler_functionstateinit (line 107) | static void compiler_functionstateinit(functionstate *state) {
function compiler_functionstateclear (line 122) | static void compiler_functionstateclear(functionstate *state) {
function compiler_fstackinit (line 134) | void compiler_fstackinit(compiler *c) {
function compiler_fstackclear (line 142) | void compiler_fstackclear(compiler *c) {
function functionstate (line 150) | static inline functionstate *compiler_currentfunctionstate(compiler *c) {
function functionstate (line 155) | static inline functionstate *compiler_parentfunctionstate(compiler *c) {
function compiler_ininitializer (line 161) | static inline bool compiler_ininitializer(compiler *c) {
function compiler_beginfunction (line 172) | void compiler_beginfunction(compiler *c, objectfunction *func, functiont...
function compiler_setfunctionregistercount (line 181) | void compiler_setfunctionregistercount(compiler *c) {
function compiler_endfunction (line 187) | void compiler_endfunction(compiler *c) {
function objectfunction (line 197) | objectfunction *compiler_getcurrentfunction(compiler *c) {
function varray_value (line 202) | varray_value *compiler_getcurrentconstanttable(compiler *c) {
function value (line 212) | value compiler_getconstant(compiler *c, unsigned int i) {
function objectfunction (line 220) | objectfunction *compiler_getpreviousfunction(compiler *c) {
function compiler_beginargs (line 235) | static inline void compiler_beginargs(compiler *c) {
function compiler_endargs (line 243) | static inline void compiler_endargs(compiler *c) {
function compiler_inargs (line 249) | static inline bool compiler_inargs(compiler *c) {
function compiler_beginclass (line 258) | static inline void compiler_beginclass(compiler *c, objectclass *klass) {
function compiler_endclass (line 266) | static inline void compiler_endclass(compiler *c) {
function objectclass (line 275) | static objectclass *compiler_getcurrentclass(compiler *c) {
function compiler_addclass (line 280) | void compiler_addclass(compiler *c, objectclass *klass) {
function objectclass (line 287) | objectclass *compiler_findclass(compiler *c, value name) {
function compiler_addparent (line 298) | void compiler_addparent(compiler *c, objectclass *klass, objectclass *pa...
function compiler_findtype (line 308) | bool compiler_findtype(compiler *c, value label, value *out) {
function compiler_findtypefromcstring (line 322) | bool compiler_findtypefromcstring(compiler *c, char *label, value *out) {
function compiler_typefromvalue (line 328) | bool compiler_typefromvalue(compiler *c, value v, value *out) {
function compiler_findtypeinparent (line 333) | bool compiler_findtypeinparent(compiler *c, objectclass *type, value mat...
function compiler_checktype (line 342) | bool compiler_checktype(compiler *c, value type, value match) {
function compiler_getconstanttype (line 353) | bool compiler_getconstanttype(compiler *c, unsigned int i, value *type) {
function compiler_setmodule (line 363) | static void compiler_setmodule(compiler *c, value module) {
function value (line 368) | static value compiler_getmodule(compiler *c) {
function compiler_fixloop (line 392) | static void compiler_fixloop(compiler *c, instructionindx start, instruc...
function compiler_beginloop (line 406) | static void compiler_beginloop(compiler *c) {
function compiler_endloop (line 412) | static void compiler_endloop(compiler *c) {
function compiler_inloop (line 418) | static bool compiler_inloop(compiler *c) {
function registerindx (line 428) | static registerindx compiler_regallocwithstate(compiler *c, functionstat...
function registerindx (line 464) | static registerindx compiler_regalloc(compiler *c, value symbol) {
function compiler_regsetsymbol (line 471) | static void compiler_regsetsymbol(compiler *c, registerindx reg, value s...
function registerindx (line 480) | static registerindx compiler_regalloctop(compiler *c) {
function registerindx (line 504) | static registerindx compiler_regtemp(compiler *c, registerindx reqreg) {
function registerindx (line 509) | static registerindx compiler_regtempwithindx(compiler *c, registerindx r...
function compiler_regfree (line 527) | static void compiler_regfree(compiler *c, functionstate *f, registerindx...
function compiler_regfreetemp (line 542) | static void compiler_regfreetemp(compiler *c, registerindx reg) {
function compiler_regfreetoend (line 553) | static void compiler_regfreetoend(compiler *c, registerindx reg) {
function compiler_releaseoperand (line 562) | static void compiler_releaseoperand(compiler *c, codeinfo info) {
function compiler_regfreeatscope (line 569) | static void compiler_regfreeatscope(compiler *c, unsigned int scopedepth) {
function compiler_regsettype (line 580) | void compiler_regsettype(compiler *c, registerindx reg, value type) {
function compiler_regtype (line 587) | bool compiler_regtype(compiler *c, registerindx reg, value *type) {
function compiler_typeviolation (line 595) | void compiler_typeviolation(compiler *c, syntaxtreenode *node, value typ...
function compiler_regsetcurrenttype (line 607) | bool compiler_regsetcurrenttype(compiler *c, syntaxtreenode *node, regis...
function compiler_regcurrenttype (line 622) | bool compiler_regcurrenttype(compiler *c, registerindx reg, value *type) {
function registerindx (line 631) | static registerindx compiler_findsymbol(functionstate *f, value symbol) {
function registerindx (line 645) | static registerindx compiler_findsymbolwithscope(functionstate *f, value...
function registerindx (line 660) | static registerindx compiler_regtop(compiler *c) {
function compiler_isregtemp (line 670) | static bool compiler_isregtemp(compiler *c, registerindx indx) {
function compiler_isregalloc (line 678) | static bool compiler_isregalloc(compiler *c, registerindx indx) {
function compiler_regsetoptionalarg (line 685) | void compiler_regsetoptionalarg(compiler *c, registerindx reg) {
function compiler_isregoptionalarg (line 692) | static bool compiler_isregoptionalarg(compiler *c, registerindx indx) {
function compiler_regcountargs (line 699) | void compiler_regcountargs(compiler *c, registerindx start, registerindx...
function compiler_getregscope (line 718) | static bool compiler_getregscope(compiler *c, registerindx indx, unsigne...
function compiler_iscodeinfotop (line 735) | static bool compiler_iscodeinfotop(compiler *c, codeinfo func) {
function compiler_regshow (line 742) | static void compiler_regshow(compiler *c) {
function compiler_beginscope (line 782) | void compiler_beginscope(compiler *c) {
function compiler_endscope (line 790) | void compiler_endscope(compiler *c) {
function compiler_currentscope (line 798) | unsigned int compiler_currentscope(compiler *c) {
function registerindx (line 814) | static registerindx compiler_addconstant(compiler *c, syntaxtreenode *no...
function registerindx (line 866) | static registerindx compiler_addsymbol(compiler *c, syntaxtreenode *node...
function codeinfo (line 879) | codeinfo compiler_findbuiltin(compiler *c, syntaxtreenode *node, char *n...
function registerindx (line 912) | static registerindx compiler_addlocal(compiler *c, syntaxtreenode *node,...
function registerindx (line 933) | static registerindx compiler_getlocal(compiler *c, value symbol) {
function codeinfo (line 959) | static codeinfo compiler_movetoregister(compiler *c, syntaxtreenode *nod...
function codeinfo (line 1009) | codeinfo compiler_addsymbolwithsizecheck(compiler *c, syntaxtreenode *no...
function registerindx (line 1023) | static inline registerindx compiler_addpositionalarg(compiler *c, syntax...
function compiler_addoptionalarg (line 1038) | static inline void compiler_addoptionalarg(compiler *c, syntaxtreenode *...
function compiler_addvariadicarg (line 1055) | static inline void compiler_addvariadicarg(compiler *c, syntaxtreenode *...
function compiler_checkglobal (line 1076) | bool compiler_checkglobal(compiler *c) {
function globalindx (line 1081) | globalindx compiler_findglobal(compiler *c, value symbol, bool recurse) {
function globalindx (line 1095) | globalindx compiler_addglobal(compiler *c, syntaxtreenode *node, value s...
function compiler_setglobaltype (line 1111) | void compiler_setglobaltype(compiler *c, globalindx indx, value type) {
function compiler_checkglobaltype (line 1116) | bool compiler_checkglobaltype(compiler *c, syntaxtreenode *node, globali...
function compiler_globalshow (line 1132) | void compiler_globalshow(compiler *c) {
function codeinfo (line 1150) | codeinfo compiler_movetoglobal(compiler *c, syntaxtreenode *node, codein...
function codeinfo (line 1175) | codeinfo compiler_addvariable(compiler *c, syntaxtreenode *node, value s...
function registerindx (line 1194) | registerindx compiler_addupvalue(functionstate *f, bool islocal, indx ix) {
function registerindx (line 1216) | registerindx compiler_propagateupvalues(compiler *c, functionstate *star...
function registerindx (line 1228) | static registerindx compiler_resolveupvalue(compiler *c, value symbol) {
function codeinfo (line 1250) | static codeinfo compiler_movetoupvalue(compiler *c, syntaxtreenode *node...
function indx (line 1272) | indx compiler_closure(compiler *c, syntaxtreenode *node, registerindx re...
function compiler_addfunctionref (line 1290) | int compiler_addfunctionref(compiler *c, objectfunction *func) {
function compiler_functionreffreeatscope (line 1297) | void compiler_functionreffreeatscope(compiler *c, unsigned int scope) {
function _addmatchingfunctionref (line 1303) | void _addmatchingfunctionref(compiler *c, value symbol, value fn, value ...
function compiler_findmetafunction (line 1322) | bool compiler_findmetafunction(compiler *c, value symbol, int n, value *...
function _findclosure (line 1339) | void _findclosure(compiler *c, objectfunction *closure, codeinfo *out) {
function codeinfo (line 1361) | codeinfo compiler_metafunction(compiler *c, syntaxtreenode *node, int n,...
function _checkduplicateref (line 1387) | static bool _checkduplicateref(varray_functionref *refs, functionref *ma...
function _findfunctionref (line 1400) | static void _findfunctionref(compiler *c, value symbol, bool *hasclosure...
function compiler_resolvefunctionref (line 1429) | bool compiler_resolvefunctionref(compiler *c, syntaxtreenode *node, valu...
function codeinfo (line 1472) | codeinfo compiler_movefromregister(compiler *c, syntaxtreenode *node, co...
function registerindx (line 1495) | static registerindx compiler_resolveself(compiler *c) {
function codeinfo (line 1522) | static codeinfo compiler_addforwardreference(compiler *c, syntaxtreenode...
function compiler_resolveforwardreference (line 1548) | static bool compiler_resolveforwardreference(compiler *c, value symbol, ...
function compiler_checkoutstandingforwardreference (line 1567) | bool compiler_checkoutstandingforwardreference(compiler *c) {
function namespc (line 1585) | namespc *compiler_addnamespace(compiler *c, value symbol) {
function namespc (line 1601) | namespc *compiler_isnamespace(compiler *c, value label) {
function compiler_findsymbolwithnamespace (line 1609) | bool compiler_findsymbolwithnamespace(compiler *c, syntaxtreenode *node,...
function compiler_findclasswithnamespace (line 1624) | bool compiler_findclasswithnamespace(compiler *c, syntaxtreenode *node, ...
function compiler_clearnamespacelist (line 1639) | void compiler_clearnamespacelist(compiler *c) {
function compilenoderule (line 1785) | static compilenoderule *compiler_getrule(syntaxtreenodetype type) {
function codeinfo (line 1790) | static codeinfo compiler_constant(compiler *c, syntaxtreenode *node, reg...
function codeinfo (line 1796) | static codeinfo compiler_list(compiler *c, syntaxtreenode *node, registe...
function codeinfo (line 1841) | static codeinfo compiler_dictionary(compiler *c, syntaxtreenode *node, r...
function codeinfo (line 1887) | static codeinfo compiler_range(compiler *c, syntaxtreenode *node, regist...
function codeinfo (line 1940) | codeinfo compiler_compileindexlist(compiler *c, syntaxtreenode *indxnode...
function codeinfo (line 1962) | static codeinfo compiler_index(compiler *c, syntaxtreenode *node, regist...
function codeinfo (line 2002) | static codeinfo compiler_negate(compiler *c, syntaxtreenode *node, regis...
function codeinfo (line 2037) | static codeinfo compiler_not(compiler *c, syntaxtreenode *node, register...
function codeinfo (line 2056) | static codeinfo compiler_binary(compiler *c, syntaxtreenode *node, regis...
function codeinfo (line 2132) | static codeinfo compiler_ternary(compiler *c, syntaxtreenode *node, regi...
function codeinfo (line 2188) | static codeinfo compiler_grouping(compiler *c, syntaxtreenode *node, reg...
function codeinfo (line 2198) | static codeinfo compiler_sequence(compiler *c, syntaxtreenode *node, reg...
function codeinfo (line 2215) | static codeinfo compiler_interpolation(compiler *c, syntaxtreenode *node...
function codeinfo (line 2259) | static codeinfo compiler_closeupvaluesforscope(compiler *c, syntaxtreeno...
function codeinfo (line 2283) | static codeinfo compiler_scope(compiler *c, syntaxtreenode *node, regist...
function codeinfo (line 2297) | static codeinfo compiler_print(compiler *c, syntaxtreenode *node, regist...
function codeinfo (line 2341) | static codeinfo compiler_if(compiler *c, syntaxtreenode *node, registeri...
function codeinfo (line 2432) | static codeinfo compiler_while(compiler *c, syntaxtreenode *node, regist...
function codeinfo (line 2540) | static codeinfo compiler_for(compiler *c, syntaxtreenode *node, register...
function codeinfo (line 2682) | static codeinfo compiler_do(compiler *c, syntaxtreenode *node, registeri...
function codeinfo (line 2731) | static codeinfo compiler_break(compiler *c, syntaxtreenode *node, regist...
function compiler_fixcatch (line 2747) | static void compiler_fixcatch(compiler *c, instructionindx start, instru...
function codeinfo (line 2758) | static codeinfo compiler_try(compiler *c, syntaxtreenode *node, register...
function codeinfo (line 2846) | static codeinfo compiler_logical(compiler *c, syntaxtreenode *node, regi...
function codeinfo (line 2886) | static codeinfo compiler_declaration(compiler *c, syntaxtreenode *node, ...
function registerindx (line 2998) | static registerindx compiler_functionparameters(compiler *c, syntaxtreei...
function codeinfo (line 3076) | static codeinfo compiler_function(compiler *c, syntaxtreenode *node, reg...
function codeinfo (line 3208) | static codeinfo compiler_arglist(compiler *c, syntaxtreenode *node, regi...
function _islocalfunction (line 3269) | bool _islocalfunction(compiler *c, value symbol) {
function compiler_isinvocation (line 3284) | static bool compiler_isinvocation(compiler *c, syntaxtreenode *call) {
function codeinfo (line 3313) | static codeinfo compiler_call(compiler *c, syntaxtreenode *node, registe...
function codeinfo (line 3405) | static codeinfo compiler_invoke(compiler *c, syntaxtreenode *node, regis...
function codeinfo (line 3502) | static codeinfo compiler_return(compiler *c, syntaxtreenode *node, regis...
function compiler_overridemethod (line 3538) | void compiler_overridemethod(compiler *c, syntaxtreenode *node, objectfu...
function codeinfo (line 3591) | static codeinfo compiler_classbody(compiler *c, syntaxtreeindx startindx...
function codeinfo (line 3649) | static codeinfo compiler_class(compiler *c, syntaxtreenode *node, regist...
function codeinfo (line 3766) | static codeinfo compiler_self(compiler *c, syntaxtreenode *node, registe...
function codeinfo (line 3790) | static codeinfo compiler_super(compiler *c, syntaxtreenode *node, regist...
function codeinfo (line 3810) | static codeinfo compiler_symbol(compiler *c, syntaxtreenode *node, regis...
function codeinfo (line 3870) | static codeinfo compiler_assign(compiler *c, syntaxtreenode *node, regis...
function codeinfo (line 3995) | static codeinfo compiler_property(compiler *c, syntaxtreenode *node, reg...
function codeinfo (line 4029) | static codeinfo compiler_dot(compiler *c, syntaxtreenode *node, register...
function codeinfo (line 4055) | static codeinfo compiler_movetoproperty(compiler *c, syntaxtreenode *nod...
function codeinfo (line 4095) | static codeinfo compiler_nodetobytecode(compiler *c, syntaxtreeindx indx...
function compiler_tobytecode (line 4126) | static bool compiler_tobytecode(compiler *c, program *out) {
function compiler_stripend (line 4146) | void compiler_stripend(compiler *c) {
function compiler_copysymbols (line 4160) | void compiler_copysymbols(dictionary *src, dictionary *dest, dictionary ...
function compiler_copyfunctionref (line 4175) | void compiler_copyfunctionref(compiler *src, compiler *dest, dictionary ...
function compiler_copyfunctionreftonamespace (line 4190) | void compiler_copyfunctionreftonamespace(compiler *src, namespc *dest, d...
function compiler_findmodule (line 4214) | bool compiler_findmodule(char *name, varray_char *fname) {
function codeinfo (line 4231) | static codeinfo compiler_import(compiler *c, syntaxtreenode *node, regis...
function codeinfo (line 4367) | static codeinfo compiler_breakpoint(compiler *c, syntaxtreenode *node, r...
function compiler_init (line 4389) | void compiler_init(const char *source, program *out, compiler *c) {
function compiler_clear (line 4411) | void compiler_clear(compiler *c) {
function morpho_compile (line 4434) | bool morpho_compile(char *in, compiler *c, bool opt, error *err) {
function compiler (line 4484) | compiler *morpho_newcompiler(program *out) {
function morpho_freecompiler (line 4493) | void morpho_freecompiler(compiler *c) {
function morpho_setbaseclass (line 4502) | void morpho_setbaseclass(value klss) {
function morpho_setoptimizer (line 4506) | void morpho_setoptimizer(optimizerfn *opt) {
function compile_initialize (line 4511) | void compile_initialize(void) {
function compile_finalize (line 4560) | void compile_finalize(void) {
FILE: src/core/compile.h
type registerindx (line 142) | typedef int registerindx;
type registeralloc (line 149) | typedef struct {
type returntype (line 167) | typedef enum {
type codeinfo (line 176) | typedef struct {
type forwardreference (line 195) | typedef struct {
type functionref (line 209) | typedef struct {
type functiontype (line 223) | typedef enum {
type functionstate (line 234) | typedef struct {
type compilerlist (line 255) | typedef struct scompilerlist {
type namespc (line 264) | typedef struct _namespc {
type compiler (line 277) | typedef struct scompiler {
type codeinfo (line 328) | typedef codeinfo (*compiler_nodefn) (compiler *c, syntaxtreenode *node, ...
type compilenoderule (line 332) | typedef struct {
FILE: src/core/core.h
type vm (line 13) | typedef struct svm vm;
type callframe (line 112) | typedef struct {
type errorhandler (line 130) | typedef struct {
type debugger (line 139) | typedef struct {
type profiler (line 160) | typedef struct {
type graylist (line 176) | typedef struct {
type svm (line 189) | struct svm {
FILE: src/core/gc.c
function vm_graylistinit (line 24) | void vm_graylistinit(graylist *g) {
function vm_graylistclear (line 31) | void vm_graylistclear(graylist *g) {
function vm_graylistadd (line 37) | void vm_graylistadd(graylist *g, object *obj) {
function vm_gcrecalculatesize (line 55) | size_t vm_gcrecalculatesize(vm *v) {
function vm_gcmarkobject (line 64) | void vm_gcmarkobject(vm *v, object *obj) {
function vm_gcmarkvalue (line 78) | void vm_gcmarkvalue(vm *v, value val) {
function vm_gcmarkdictionary (line 85) | void vm_gcmarkdictionary(vm *v, dictionary *dict) {
function vm_gcmarkarray (line 95) | void vm_gcmarkarray(vm *v, varray_value *array) {
function morpho_markobject (line 102) | void morpho_markobject(void *v, object *obj) {
function morpho_markvalue (line 106) | void morpho_markvalue(void *v, value val) {
function morpho_markdictionary (line 110) | void morpho_markdictionary(void *v, dictionary *dict) {
function morpho_markvarrayvalue (line 114) | void morpho_markvarrayvalue(void *v, varray_value *array) {
function vm_gcmarkroots (line 119) | void vm_gcmarkroots(vm *v) {
function vm_gcmarkretainobject (line 179) | void vm_gcmarkretainobject(vm *v, object *obj) {
function morpho_searchunmanagedobject (line 190) | void morpho_searchunmanagedobject(void *v, object *obj) {
function vm_gctrace (line 195) | void vm_gctrace(vm *v) {
function vm_gcsweep (line 204) | void vm_gcsweep(vm *v) {
function vm_collectgarbage (line 244) | void vm_collectgarbage(vm *v) {
FILE: src/core/vm.c
function vm_init (line 48) | static void vm_init(vm *v) {
function vm_clear (line 87) | static void vm_clear(vm *v) {
function vm_start (line 107) | bool vm_start(vm *v, program *p) {
function vm_freeobjects (line 139) | void vm_freeobjects(vm *v) {
function vm_unbindobject (line 163) | void vm_unbindobject(vm *v, value obj) {
function vm_bindobject (line 184) | static void vm_bindobject(vm *v, value obj) {
function vm_bindobjectwithoutcollect (line 208) | static void vm_bindobjectwithoutcollect(vm *v, value obj) {
function vm_runtimeerror (line 229) | void vm_runtimeerror(vm *v, ptrdiff_t iindx, errorid id, ...) {
function vm_throwOpError (line 246) | void vm_throwOpError(vm *v, ptrdiff_t iindx, errorid id, char* op, value...
function objectupvalue (line 275) | static inline objectupvalue *vm_captureupvalue(vm *v, value *reg) {
function vm_closeupvalues (line 308) | static inline void vm_closeupvalues(vm *v, value *reg) {
function vm_shouldbreakatpc (line 320) | bool vm_shouldbreakatpc(vm *v, instruction *pc) {
function instructionindx (line 329) | instructionindx vm_previnstruction(vm *v) {
function instructionindx (line 335) | instructionindx vm_currentinstruction(vm *v) {
function debugger (line 340) | debugger *vm_getdebugger(vm *v) {
function vm_expandstack (line 348) | static inline void vm_expandstack(vm *v, value **reg, unsigned int n) {
function vm_optargs (line 386) | bool vm_optargs(vm *v, ptrdiff_t iindx, objectfunction *func, unsigned i...
function vm_vargs (line 421) | static inline bool vm_vargs(vm *v, ptrdiff_t iindx, objectfunction *func...
function vm_call (line 464) | static inline bool vm_call(vm *v, value fn, unsigned int regcall, unsign...
function vm_invoke (line 554) | static inline bool vm_invoke(vm *v, value obj, value method, int nargs, ...
function vm_getoptionalargs (line 588) | int vm_getoptionalargs(vm *v) {
function morpho_interpret (line 597) | bool morpho_interpret(vm *v, value *rstart, instructionindx istart) {
function vm (line 1599) | vm *morpho_newvm(void) {
function morpho_freevm (line 1608) | void morpho_freevm(vm *v) {
function morpho_setinputfn (line 1614) | void morpho_setinputfn(vm *v, morphoinputfn inputfn, void *ref) {
function morpho_setprintfn (line 1620) | void morpho_setprintfn(vm *v, morphoprintfn printfn, void *ref) {
function morpho_setwarningfn (line 1626) | void morpho_setwarningfn(vm *v, morphowarningfn warningfn, void *ref) {
function morpho_setdebuggerfn (line 1632) | void morpho_setdebuggerfn(vm *v, morphodebuggerfn debuggerfn, void *ref) {
function error (line 1638) | error *morpho_geterror(vm *v) {
function morpho_error (line 1645) | void morpho_error(vm *v, error *err) {
function morpho_warning (line 1652) | void morpho_warning(vm *v, error *err) {
function morpho_runtimeerror (line 1664) | void morpho_runtimeerror(vm *v, errorid id, ...) {
function morpho_runtimewarning (line 1678) | void morpho_runtimewarning(vm *v, errorid id, ...) {
function morpho_bindobjects (line 1695) | void morpho_bindobjects(vm *v, int nobj, value *obj) {
function value (line 1728) | value morpho_wrapandbind(vm *v, object *obj) {
function morpho_retainobjects (line 1742) | int morpho_retainobjects(vm *v, int nobj, value *obj) {
function morpho_releaseobjects (line 1751) | void morpho_releaseobjects(vm *v, int handle) {
function morpho_resizeobject (line 1761) | void morpho_resizeobject(vm *v, object *obj, size_t oldsize, size_t news...
function morpho_ismanagedobject (line 1775) | bool morpho_ismanagedobject(object *obj) {
function morpho_run (line 1783) | bool morpho_run(vm *v, program *p) {
function morpho_call (line 1817) | bool morpho_call(vm *v, value f, int nargs, value *args, value *ret) {
function objectclass (line 1901) | objectclass *morpho_lookupclass(value v) {
function morpho_lookupmethod (line 1911) | bool morpho_lookupmethod(value obj, value label, value *method) {
function morpho_invoke (line 1926) | bool morpho_invoke(vm *v, value obj, value method, int nargs, value *arg...
function morpho_printf (line 1940) | int morpho_printf(vm *v, char *format, ...) {
function morpho_readline (line 1969) | int morpho_readline(vm *v, varray_char *buffer) {
function vm_subkernels (line 1990) | bool vm_subkernels(vm *v, int nkernels, vm **subkernels) {
function vm_releasesubkernel (line 2019) | void vm_releasesubkernel(vm *subkernel) {
function vm_cleansubkernel (line 2053) | void vm_cleansubkernel(vm *subkernel) {
function vm_addtlvar (line 2070) | int vm_addtlvar(void) {
function vm_inittlvars (line 2077) | bool vm_inittlvars(vm *v) {
function vm_settlvar (line 2087) | bool vm_settlvar(vm *v, int handle, value val) {
function vm_gettlvar (line 2098) | bool vm_gettlvar(vm *v, int handle, value *out) {
function morpho_addfinalizefn (line 2114) | void morpho_addfinalizefn(morpho_finalizefn finalizefn) {
function morpho_initialize (line 2123) | void morpho_initialize(void) {
function morpho_finalize (line 2200) | void morpho_finalize(void) {
FILE: src/datastructures/debugannotation.c
function debugannotation (line 16) | debugannotation *debugannotation_last(varray_debugannotation *list) {
function debugannotation_add (line 22) | void debugannotation_add(varray_debugannotation *list, debugannotation *...
function debugannotation_stripend (line 27) | void debugannotation_stripend(varray_debugannotation *list) {
function debugannotation_setfunction (line 32) | void debugannotation_setfunction(varray_debugannotation *list, objectfun...
function debugannotation_setclass (line 38) | void debugannotation_setclass(varray_debugannotation *list, objectclass ...
function debugannotation_setmodule (line 44) | void debugannotation_setmodule(varray_debugannotation *list, value modul...
function debugannotation_setreg (line 50) | void debugannotation_setreg(varray_debugannotation *list, indx reg, valu...
function debugannotation_setglobal (line 58) | void debugannotation_setglobal(varray_debugannotation *list, indx gindx,...
function debugannotation_pusherr (line 66) | void debugannotation_pusherr(varray_debugannotation *list, objectdiction...
function debugannotation_poperr (line 72) | void debugannotation_poperr(varray_debugannotation *list) {
function debugannotation_addnode (line 78) | void debugannotation_addnode(varray_debugannotation *list, syntaxtreenod...
function debugannotation_clear (line 92) | void debugannotation_clear(varray_debugannotation *list) {
function debugannotation_showannotations (line 114) | void debugannotation_showannotations(varray_debugannotation *list) {
FILE: src/datastructures/debugannotation.h
type debugannotation (line 19) | typedef struct {
FILE: src/datastructures/dictionary.c
function hash (line 77) | hash dictionary_hashint( uint32_t a) {
function hash (line 89) | hash dictionary_hashint(uint32_t hash) {
function hash (line 94) | hash dictionary_hashpointer(void *hash) {
function hash (line 106) | hash dictionary_hashcstring(const char* key, size_t length) {
function hash (line 118) | hash dictionary_hashvaluelist(size_t length, value *key) {
function hash (line 137) | hash dictionary_hash(value key, bool intern) {
function hash (line 149) | hash dictionary_hashvalue(value key) {
function dictionary_init (line 155) | void dictionary_init(dictionary *dict) {
function dictionary_clear (line 164) | void dictionary_clear(dictionary *dict) {
function dictionary_freecontents (line 173) | void dictionary_freecontents(dictionary *dict, bool freekeys, bool freev...
function dictionary_resize (line 190) | bool dictionary_resize(dictionary *dict, unsigned int size) {
function dictionary_find (line 235) | static bool dictionary_find(dictionary *dict, value key, bool intern, di...
function _dictionary_insert (line 292) | static inline bool _dictionary_insert(dictionary *dict, value key, value...
function dictionary_insert (line 330) | bool dictionary_insert(dictionary *dict, value key, value val) {
function dictionary_insertintern (line 341) | bool dictionary_insertintern(dictionary *dict, value key, value val) {
function value (line 352) | value dictionary_intern(dictionary *dict, value key) {
function _dictionary_get (line 377) | static inline bool _dictionary_get(dictionary *dict, value key, bool int...
function dictionary_get (line 394) | bool dictionary_get(dictionary *dict, value key, value *val) {
function dictionary_getintern (line 405) | bool dictionary_getintern(dictionary *dict, value key, value *val) {
function dictionary_remove (line 414) | bool dictionary_remove(dictionary *dict, value key) {
function dictionary_copy (line 436) | bool dictionary_copy(dictionary *src, dictionary *dest) {
function dictionary_union (line 457) | bool dictionary_union(dictionary *a, dictionary *b, dictionary *out) {
function dictionary_intersection (line 469) | bool dictionary_intersection(dictionary *a, dictionary *b, dictionary *o...
function dictionary_difference (line 490) | bool dictionary_difference(dictionary *a, dictionary *b, dictionary *out) {
FILE: src/datastructures/dictionary.h
type hash (line 16) | typedef uint32_t hash;
type dictionaryentry (line 24) | typedef struct {
type dictionary (line 34) | typedef struct {
FILE: src/datastructures/error.c
function error_printf (line 35) | static void error_printf(error *err, errorcategory cat, char *file, int ...
function error_clear (line 48) | void error_clear(error *err) {
function error_init (line 57) | void error_init(error *err) {
function morpho_getdefinitionfromid (line 65) | bool morpho_getdefinitionfromid(errorid id, errordefinition **def) {
function morpho_writeerrorwithidvalist (line 88) | void morpho_writeerrorwithidvalist(error *err, errorid id, char *file, i...
function morpho_writeerrorwithid (line 108) | void morpho_writeerrorwithid(error *err, errorid id, char *file, int lin...
function error_writewithid (line 119) | void error_writewithid(error *err, errorid id, ... ) {
function morpho_writeusererror (line 130) | void morpho_writeusererror(error *err, errorid id, char *message) {
function morpho_defineerror (line 145) | void morpho_defineerror(errorid id, errorcategory cat, char *message) {
function errorid (line 161) | errorid morpho_geterrorid(error *err) {
function morpho_matcherror (line 167) | bool morpho_matcherror(error *err, errorid id) {
function morpho_checkerror (line 173) | bool morpho_checkerror(error *err) {
function morpho_unreachable (line 182) | void morpho_unreachable(const char *explanation) {
function error_initialize (line 193) | void error_initialize(void) {
function error_finalize (line 201) | void error_finalize(void) {
FILE: src/datastructures/error.h
type errorcategory (line 26) | typedef enum {
type errorcategory (line 62) | typedef errorcategory morphoerror;
type error (line 65) | typedef struct {
type errordefinition (line 81) | typedef struct {
FILE: src/datastructures/object.c
function objecttype (line 23) | objecttype object_addtype(objecttypedefn *def) {
function objecttypedefn (line 40) | objecttypedefn *object_getdefn(object *obj) {
function object_init (line 51) | void object_init(object *obj, objecttype type) {
function object_free (line 59) | void object_free(object *obj) {
function object_freeifunmanaged (line 72) | void object_freeifunmanaged(object *obj) {
function object_print (line 77) | void object_print(void *v, value val) {
function object_size (line 83) | size_t object_size(object *obj) {
function hash (line 88) | hash object_hash(object *obj) {
function object_cmp (line 96) | int object_cmp(object *a, object *b) {
function object (line 107) | object *object_new(size_t size, objecttype type) {
function object_istype (line 120) | bool object_istype(value val, objecttype type) {
function morpho_freeobject (line 125) | void morpho_freeobject(value val) {
function object_setveneerclass (line 134) | void object_setveneerclass(objecttype type, value class) {
function objectclass (line 142) | objectclass *object_getveneerclass(objecttype type) {
function object_veneerclasstotype (line 147) | bool object_veneerclasstotype(objectclass *clss, objecttype *type) {
function object_initialize (line 161) | void object_initialize(void) {
function object_finalize (line 167) | void object_finalize(void) {
FILE: src/datastructures/object.h
type objecttype (line 22) | typedef int objecttype;
type sobject (line 25) | struct sobject {
type hash (line 74) | typedef hash (*objecthashfn) (object *obj);
type objecttypedefn (line 85) | typedef struct {
type indx (line 122) | typedef ptrdiff_t indx;
FILE: src/datastructures/program.c
function program_init (line 22) | void program_init(program *p) {
function program_clear (line 33) | void program_clear(program *p) {
function program (line 57) | program *morpho_newprogram(void) {
function morpho_freeprogram (line 66) | void morpho_freeprogram(program *p) {
function program_setentry (line 72) | void program_setentry(program *p, instructionindx entry) {
function instructionindx (line 77) | instructionindx program_getentry(program *p) {
function program_bindobject (line 85) | void program_bindobject(program *p, object *obj) {
function value (line 98) | value program_internsymbol(program *p, value symbol) {
function globalindx (line 122) | globalindx program_addglobal(program *p, value symbol) {
function program_globalsettype (line 129) | void program_globalsettype(program *p, globalindx indx, value type) {
function program_globaltype (line 136) | bool program_globaltype(program *p, globalindx indx, value *type) {
function program_globalsymbol (line 143) | bool program_globalsymbol(program *p, globalindx indx, value *symbol) {
function program_countglobals (line 150) | int program_countglobals(program *p) {
function program_addclass (line 155) | int program_addclass(program *p, value klass) {
function program_countclasses (line 160) | int program_countclasses(program *p, value klass) {
FILE: src/datastructures/program.h
type instruction (line 21) | typedef unsigned int instruction;
type indx (line 25) | typedef indx instructionindx;
type globalindx (line 32) | typedef int globalindx;
type globalinfo (line 35) | typedef struct {
type program (line 47) | typedef struct {
FILE: src/datastructures/signature.c
function signature_init (line 16) | void signature_init(signature *s) {
function signature_clear (line 22) | void signature_clear(signature *s) {
function signature_set (line 30) | void signature_set(signature *s, int nparam, value *types) {
function signature_setvarg (line 36) | void signature_setvarg(signature *s, bool varg) {
function signature_isvarg (line 41) | bool signature_isvarg(signature *s) {
function signature_istyped (line 46) | bool signature_istyped(signature *s) {
function signature_isequal (line 52) | bool signature_isequal(signature *a, signature *b) {
function signature_paramlist (line 59) | bool signature_paramlist(signature *s, int *nparams, value **ptypes) {
function signature_getparamtype (line 66) | bool signature_getparamtype(signature *s, int i, value *type) {
function value (line 73) | value signature_getreturntype(signature *s) {
function signature_countparams (line 78) | int signature_countparams(signature *s) {
function signature_initializelexer (line 104) | void signature_initializelexer(lexer *l, char *signature) {
function signature_parsetype (line 112) | bool signature_parsetype(parser *p, value *type) {
function signature_parsesymbol (line 123) | bool signature_parsesymbol(parser *p, void *out) {
function signature_parsevarg (line 138) | bool signature_parsevarg(parser *p, void *out) {
function signature_parsesignature (line 149) | bool signature_parsesignature(parser *p, void *out) {
function signature_parse (line 176) | bool signature_parse(char *sig, signature *out) {
function signature_print (line 197) | void signature_print(signature *s) {
FILE: src/datastructures/signature.h
type signature (line 13) | typedef struct {
FILE: src/datastructures/syntaxtree.c
function syntaxtree_init (line 15) | void syntaxtree_init(syntaxtree *tree) {
function syntaxtree_wipe (line 21) | void syntaxtree_wipe(syntaxtree *tree) {
function syntaxtree_clear (line 26) | void syntaxtree_clear(syntaxtree *tree) {
function syntaxtree_printnode (line 132) | void syntaxtree_printnode(syntaxtreenode *base, syntaxtreeindx i, unsign...
function syntaxtree_print (line 173) | void syntaxtree_print(syntaxtree *tree) {
function syntaxtree_addnode (line 185) | bool syntaxtree_addnode(syntaxtree *tree, syntaxtreenodetype type, value...
function syntaxtreenode (line 195) | syntaxtreenode *syntaxtree_nodefromindx(syntaxtree *tree, syntaxtreeindx...
function syntaxtree_flatten (line 205) | void syntaxtree_flatten(syntaxtree *tree, syntaxtreeindx indx, unsigned ...
FILE: src/datastructures/syntaxtree.h
type syntaxtreenodetype (line 22) | typedef int syntaxtreenodetype;
type syntaxtreeindx (line 25) | typedef ptrdiff_t syntaxtreeindx;
type syntaxtreenode (line 28) | typedef struct _syntaxtreenode {
type syntaxtree (line 50) | typedef struct {
function syntaxtree_istype (line 147) | static inline bool syntaxtree_istype(syntaxtreenodetype type, syntaxtree...
FILE: src/datastructures/value.c
function morpho_issame (line 21) | bool morpho_issame(value a, value b) {
function morpho_doubleeqtest (line 48) | bool morpho_doubleeqtest(double a, double b) {
function morpho_comparevalue (line 61) | int morpho_comparevalue(value a, value b) {
function morpho_extendedcomparevalue (line 97) | int morpho_extendedcomparevalue(value a, value b) {
function morpho_isnumber (line 131) | bool morpho_isnumber(value a) {
function morpho_isfalse (line 136) | bool morpho_isfalse(value a) {
function morpho_valuetoint (line 141) | bool morpho_valuetoint(value v, int *out) {
function morpho_valuetofloat (line 148) | bool morpho_valuetofloat(value v, double *out) {
function value_promotenumberlist (line 162) | bool value_promotenumberlist(unsigned int nv, value *v) {
function value_minmax (line 178) | bool value_minmax(unsigned int nval, value *list, value *min, value *max) {
function varray_valuefind (line 210) | bool varray_valuefind(varray_value *varray, value v, unsigned int *out) {
function varray_valuefindsame (line 225) | bool varray_valuefindsame(varray_value *varray, value v, unsigned int *o...
function value_setveneerclass (line 242) | void value_setveneerclass(value type, value clss) {
function objectclass (line 258) | objectclass *value_getveneerclass(value type) {
function objectclass (line 268) | objectclass *value_veneerclassfromtype(int type) {
function value_veneerclasstotype (line 275) | bool value_veneerclasstotype(objectclass *clss, int *type) {
function value_initialize (line 289) | void value_initialize(void) {
FILE: src/datastructures/value.h
type object (line 18) | typedef struct sobject object;
type value (line 41) | typedef uint64_t value;
type doubleunion (line 72) | typedef union {
function value (line 78) | static inline value doubletovalue(double num) {
function valuetodouble (line 85) | static inline double valuetodouble(value v) {
function morpho_ofsametype (line 115) | static inline bool morpho_ofsametype(value a, value b) {
function _getorderedtype (line 128) | static inline int _getorderedtype(value x) {
type valuetype (line 145) | typedef int valuetype;
type value (line 148) | typedef struct {
function morpho_ofsametype (line 189) | static inline bool morpho_ofsametype(value a, value b) {
FILE: src/datastructures/varray.c
function varray_powerof2ceiling (line 22) | unsigned int varray_powerof2ceiling(unsigned int n) {
FILE: src/datastructures/version.c
function version_init (line 17) | void version_init(version *v, int major, int minor, int patch) {
function version_cmp (line 24) | int version_cmp(version *a, version *b) {
function version_check (line 36) | bool version_check(version *v, version *min, version *max) {
function version_tostring (line 47) | void version_tostring(version *v, size_t size, char *str) {
function morpho_version (line 52) | void morpho_version(version *v) {
FILE: src/datastructures/version.h
type version (line 14) | typedef struct {
FILE: src/debug/debug.c
function debug_infofromindx (line 27) | bool debug_infofromindx(program *code, instructionindx indx, value *modu...
function debug_indxfromline (line 56) | bool debug_indxfromline(program *code, value file, int line, instruction...
function debug_indxfromfunction (line 81) | bool debug_indxfromfunction(program *code, value klassname, value fname,...
function debug_symbolsforfunction (line 111) | bool debug_symbolsforfunction(program *code, objectfunction *func, instr...
function debug_findsymbol (line 146) | bool debug_findsymbol(vm *v, value matchstr, callframe **frame, value *s...
function debug_symbolforglobal (line 182) | bool debug_symbolforglobal(program *p, indx id, value *symbol) {
function morpho_stacktrace (line 199) | void morpho_stacktrace(vm *v) {
function debugger_init (line 232) | void debugger_init(debugger *d, program *p) {
function debugger_clear (line 251) | void debugger_clear(debugger *d) {
function vm (line 256) | vm *debugger_currentvm(debugger *d) {
function program (line 261) | program *debugger_currentprogram(debugger *d) {
function debugger_seterror (line 266) | void debugger_seterror(debugger *d, error *err) {
function debugger_error (line 274) | void debugger_error(debugger *debug, errorid id, ... ) {
function debugger_setsinglestep (line 283) | void debugger_setsinglestep(debugger *d, bool singlestep) {
function debugger_insinglestep (line 288) | bool debugger_insinglestep(debugger *d) {
function debugger_setbreakpoint (line 293) | bool debugger_setbreakpoint(debugger *d, instructionindx indx) {
function debugger_clearbreakpoint (line 301) | bool debugger_clearbreakpoint(debugger *d, instructionindx indx) {
function debugger_shouldbreakat (line 309) | bool debugger_shouldbreakat(debugger *d, instructionindx indx) {
function debugger_isactive (line 315) | bool debugger_isactive(debugger *d) {
type assemblyrule (line 324) | typedef struct {
function assemblyrule (line 385) | assemblyrule *debugger_getassemblyrule(unsigned int op) {
type debugcontents (line 390) | typedef enum { DBG_CONTENTS_NONE, DBG_CONTENTS_REG, DBG_CONTENTS_CONST} ...
function debugger_showcontents (line 393) | bool debugger_showcontents(vm *v, debugcontents b, int i, value *konst, ...
function debugger_disassembleinstruction (line 412) | void debugger_disassembleinstruction(vm *v, instruction instruction, ins...
function debugger_errorlabel (line 461) | void debugger_errorlabel(vm *v, varray_value *errorstack, instructionind...
function debugger_disassemble (line 480) | void debugger_disassemble(vm *v, program *code, int *matchline) {
function morpho_disassemble (line 556) | void morpho_disassemble(vm *v, program *code, int *matchline) {
function debugger_garbagecollect (line 564) | void debugger_garbagecollect(debugger *debug) {
function debugger_quit (line 570) | void debugger_quit(debugger *debug) {
function debugger_breakatinstruction (line 578) | bool debugger_breakatinstruction(debugger *debug, bool set, instructioni...
function debugger_breakatline (line 589) | bool debugger_breakatline(debugger *debug, bool set, value file, int lin...
function debugger_breakatfunction (line 596) | bool debugger_breakatfunction(debugger *debug, bool set, value klass, va...
function debugger_showlocation (line 607) | void debugger_showlocation(debugger *debug, instructionindx indx) {
function debugger_showaddress (line 636) | bool debugger_showaddress(debugger *debug, indx rindx) {
function debugger_showbreakpoints (line 650) | void debugger_showbreakpoints(debugger *debug) {
function debugger_showglobal (line 667) | bool debugger_showglobal(debugger *debug, indx id) {
function debugger_showglobals (line 686) | void debugger_showglobals(debugger *debug) {
function debugger_showregisters (line 693) | void debugger_showregisters(debugger *debug) {
function debugger_showstack (line 717) | void debugger_showstack(debugger *debug) {
function debugger_showsymbol (line 746) | bool debugger_showsymbol(debugger *debug, value match) {
function debugger_showsymbols (line 761) | void debugger_showsymbols(debugger *debug) {
function debugger_showproperty (line 787) | bool debugger_showproperty(debugger *debug, value matchobj, value matchp...
function debugger_setregister (line 818) | bool debugger_setregister(debugger *debug, indx reg, value val) {
function debugger_setsymbol (line 831) | bool debugger_setsymbol(debugger *debug, value symbol, value val) {
function debugger_setproperty (line 842) | bool debugger_setproperty(debugger *debug, value symbol, value property,...
function debugger_enter (line 863) | bool debugger_enter(debugger *debug, vm *v) {
function morpho_debug (line 896) | bool morpho_debug(vm *v, program *p) {
function debugger_initialize (line 914) | void debugger_initialize(void) {
FILE: src/debug/profile.c
function profiler_sample (line 27) | void profiler_sample(profiler *profile, value func) {
function MorphoThreadFnReturnType (line 38) | MorphoThreadFnReturnType profiler_thread(void *arg) {
function profiler_init (line 68) | void profiler_init(profiler *profile, program *p) {
function profiler_clear (line 76) | void profiler_clear(profiler *profile) {
function profiler_kill (line 82) | void profiler_kill(profiler *profile) {
function profiler_sort (line 91) | int profiler_sort(const void *a, const void *b) {
function profiler_getname (line 98) | bool profiler_getname(value func, value *name, value *klass) {
function profiler_calculatelength (line 120) | size_t profiler_calculatelength(profiler *p, value func) {
function profiler_display (line 141) | void profiler_display(profiler *p, value func, vm *v) {
function profiler_report (line 161) | void profiler_report(profiler *profile, vm *v) {
function morpho_profile (line 203) | bool morpho_profile(vm *v, program *p) {
function morpho_profile (line 228) | bool morpho_profile(vm *v, program *p) {
FILE: src/geometry/fespace.c
function objectfespace_printfn (line 16) | void objectfespace_printfn(object *obj, void *v) {
function objectfespace_sizefn (line 21) | size_t objectfespace_sizefn(object *obj) {
function objectfespace (line 34) | objectfespace *objectfespace_new(fespace *disc) {
function cg1_1dinterpolate (line 62) | void cg1_1dinterpolate(double *lambda, double *wts) {
function cg1_1dgrad (line 67) | void cg1_1dgrad(double *lambda, double *grad) {
function cg2_1dinterpolate (line 106) | void cg2_1dinterpolate(double *lambda, double *wts) {
function cg2_1dgrad (line 113) | void cg2_1dgrad(double *lambda, double *grad) {
function cg3_1dinterpolate (line 157) | void cg3_1dinterpolate(double *lambda, double *wts) {
function cg1_2dinterpolate (line 200) | void cg1_2dinterpolate(double *lambda, double *wts) {
function cg1_2dgrad (line 206) | void cg1_2dgrad(double *lambda, double *grad) {
function cg2_2dinterpolate (line 257) | void cg2_2dinterpolate(double *lambda, double *wts) {
function cg2_2dgrad (line 266) | void cg2_2dgrad(double *lambda, double *grad) {
function cg1_3dinterpolate (line 327) | void cg1_3dinterpolate(double *lambda, double *wts) {
function cg1_3dgrad (line 334) | void cg1_3dgrad(double *lambda, double *grad) {
function cg2_3dinterpolate (line 390) | void cg2_3dinterpolate(double *lambda, double *wts) {
function cg2_3dgrad (line 403) | void cg2_3dgrad(double *lambda, double *grad) { // TODO: FIX
function fespace (line 495) | fespace *fespace_find(char *name, grade g) {
function fespace (line 504) | fespace *fespace_findlinear(grade g) {
function fespace_doftofieldindx (line 514) | bool fespace_doftofieldindx(objectfield *field, fespace *disc, int nv, i...
function fespace_lower (line 550) | bool fespace_lower(fespace *disc, grade target, fespace **out) {
function fespace_layout (line 561) | bool fespace_layout(objectfield *field, fespace *disc, objectsparse **ou...
function fespace_gradient (line 595) | void fespace_gradient(fespace *disc, double *lambda, objectmatrix *grad) {
function value (line 612) | value fespace_constructor(vm *v, int nargs, value *args) {
function value (line 640) | value FiniteElementSpace_layout(vm *v, int nargs, value *args) {
function MORPHO_METHOD (line 655) | MORPHO_BEGINCLASS(FiniteElementSpace)
FILE: src/geometry/fespace.h
type eldefninstruction (line 20) | typedef int eldefninstruction;
type fespace (line 23) | typedef struct sfespace {
type objectfespace (line 44) | typedef struct {
FILE: src/geometry/field.c
function objectfield_printfn (line 28) | void objectfield_printfn(object *obj, void *v) {
function objectfield_markfn (line 32) | void objectfield_markfn(object *obj, void *v) {
function objectfield_freefn (line 39) | void objectfield_freefn(object *obj) {
function objectfield_sizefn (line 47) | size_t objectfield_sizefn(object *obj) {
function field_checkprototype (line 65) | bool field_checkprototype(value v) {
function field_sizeprototype (line 69) | unsigned int field_sizeprototype(value prototype) {
function field_size (line 87) | unsigned int field_size(objectmesh *mesh, value prototype, unsigned int ...
function objectfield (line 111) | objectfield *object_newfield(objectmesh *mesh, value prototype, value fn...
function field_applyfunctiontovertices (line 181) | bool field_applyfunctiontovertices(vm *v, objectmesh *mesh, value fn, ob...
function field_applyfunctiontoelements (line 202) | bool field_applyfunctiontoelements(vm *v, objectmesh *mesh, value fn, va...
function objectfield (line 264) | objectfield *field_newwithfunction(vm *v, objectmesh *mesh, value fn, va...
function field_zero (line 296) | void field_zero(objectfield *f) {
function field_addpool (line 301) | bool field_addpool(objectfield *f) {
function objectfield (line 321) | objectfield *field_clone(objectfield *f) {
function field_getelement (line 338) | bool field_getelement(objectfield *field, grade grade, elementid el, int...
function field_getelementwithindex (line 361) | bool field_getelementwithindex(objectfield *field, int indx, value *out) {
function field_getindex (line 383) | bool field_getindex(objectfield *field, grade grade, elementid el, int i...
function field_getelementaslist (line 399) | bool field_getelementaslist(objectfield *field, grade grade, elementid e...
function field_setelement (line 423) | bool field_setelement(objectfield *field, grade grade, elementid el, int...
function field_setelementwithindex (line 449) | bool field_setelementwithindex(objectfield *field, int ix, value val) {
function field_compareshape (line 470) | bool field_compareshape(objectfield *a, objectfield *b) {
function field_dofforgrade (line 482) | unsigned int field_dofforgrade(objectfield *f, grade g) {
function field_add (line 487) | bool field_add(objectfield *left, objectfield *right, objectfield *out) {
function field_sub (line 492) | bool field_sub(objectfield *left, objectfield *right, objectfield *out) {
function field_accumulate (line 497) | bool field_accumulate(objectfield *left, double lambda, objectfield *rig...
function field_inner (line 501) | bool field_inner(objectfield *left, objectfield *right, double *out) {
function field_op (line 506) | bool field_op(vm *v, value fn, objectfield *f, int nargs, objectfield **...
function value (line 545) | value field_constructor(vm *v, int nargs, value *args) {
function value (line 602) | value Field_getindex(vm *v, int nargs, value *args) {
function value (line 622) | value Field_setindex(vm *v, int nargs, value *args) {
function value (line 648) | value Field_enumerate(vm *v, int nargs, value *args) {
function value (line 669) | value Field_count(vm *v, int nargs, value *args) {
function value (line 676) | value Field_assign(vm *v, int nargs, value *args) {
function value (line 695) | value Field_add(vm *v, int nargs, value *args) {
function value (line 717) | value Field_addr(vm *v, int nargs, value *args) {
function value (line 735) | value Field_sub(vm *v, int nargs, value *args) {
function value (line 757) | value Field_subr(vm *v, int nargs, value *args) {
function value (line 779) | value Field_acc(vm *v, int nargs, value *args) {
function value (line 797) | value Field_mul(vm *v, int nargs, value *args) {
function value (line 817) | value Field_div(vm *v, int nargs, value *args) {
function value (line 840) | value Field_inner(vm *v, int nargs, value *args) {
function value (line 857) | value Field_op(vm *v, int nargs, value *args) {
function value (line 879) | value Field_print(vm *v, int nargs, value *args) {
function value (line 890) | value Field_clone(vm *v, int nargs, value *args) {
function value (line 902) | value Field_shape(vm *v, int nargs, value *args) {
function value (line 921) | value Field_fnspace(vm *v, int nargs, value *args) {
function value (line 928) | value Field_prototype(vm *v, int nargs, value *args) {
function value (line 935) | value Field_mesh(vm *v, int nargs, value *args) {
function value (line 942) | value Field_linearize(vm *v, int nargs, value *args) {
function value (line 957) | value Field_unsafelinearize(vm *v, int nargs, value *args) {
FILE: src/geometry/field.h
type objectfield (line 25) | typedef struct {
type fieldindx (line 56) | typedef struct {
FILE: src/geometry/functional.c
function functional_fdstepsize (line 40) | double functional_fdstepsize(double x, int order) {
function functional_clearmapinfo (line 54) | static void functional_clearmapinfo(functional_mapinfo *info) {
function functional_validateargs (line 74) | bool functional_validateargs(vm *v, int nargs, value *args, functional_m...
function functional_countelements (line 102) | static bool functional_countelements(vm *v, objectmesh *mesh, grade g, i...
function functional_symmetryimagelistfn (line 118) | static int functional_symmetryimagelistfn(const void *a, const void *b) {
function functional_symmetryimagelist (line 128) | void functional_symmetryimagelist(objectmesh *mesh, grade g, bool sort, ...
function functional_symmetrysumforces (line 148) | bool functional_symmetrysumforces(objectmesh *mesh, objectmatrix *frc) {
function functional_inlist (line 170) | bool functional_inlist(varray_elementid *list, elementid id) {
function functional_containsvertex (line 175) | bool functional_containsvertex(int nv, int *vid, elementid id) {
function functional_sumintegrandX (line 189) | bool functional_sumintegrandX(vm *v, functional_mapinfo *info, value *ou...
function functional_mapintegrandX (line 261) | bool functional_mapintegrandX(vm *v, functional_mapinfo *info, value *ou...
function functional_mapgradientX (line 343) | bool functional_mapgradientX(vm *v, functional_mapinfo *info, value *out) {
function functional_mapfieldgradientX (line 410) | bool functional_mapfieldgradientX(vm *v, functional_mapinfo *info, value...
function functional_numericalgradient (line 474) | bool functional_numericalgradient(vm *v, objectmesh *mesh, elementid i, ...
function functional_numericalremotegradient (line 499) | static bool functional_numericalremotegradient(vm *v, functional_mapinfo...
function functional_sumlist (line 522) | double functional_sumlist(double *list, unsigned int nel) {
function functional_mapnumericalgradientX (line 544) | bool functional_mapnumericalgradientX(vm *v, functional_mapinfo *info, v...
function functional_mapnumericalfieldgradientX (line 640) | bool functional_mapnumericalfieldgradientX(vm *v, functional_mapinfo *in...
type functional_task (line 727) | typedef struct {
function functionaltask_init (line 753) | void functionaltask_init(functional_task *task, elementid start, element...
function functional_checkskip (line 779) | bool functional_checkskip(functional_task *task) {
function functional_mapfn_elements (line 790) | bool functional_mapfn_elements(void *arg) {
function functional_parallelmap (line 832) | bool functional_parallelmap(int ntasks, functional_task *tasks) {
function functional_binbounds (line 850) | void functional_binbounds(int nel, int nbins, int *binbounds) {
function functional_preparetasks (line 874) | int functional_preparetasks(vm *v, functional_mapinfo *info, int ntask, ...
function functional_cleanuptasks (line 919) | void functional_cleanuptasks(vm *v, int ntask, functional_task *task) {
type functional_sumintermediate (line 930) | typedef struct {
function functional_sumintegrandprocessfn (line 938) | bool functional_sumintegrandprocessfn(void *arg) {
function functional_sumintegrand (line 949) | bool functional_sumintegrand(vm *v, functional_mapinfo *info, value *out) {
function functional_mapintegrandforelement (line 994) | bool functional_mapintegrandforelement(vm *v, functional_mapinfo *info, ...
function functional_mapintegrandprocessfn (line 1028) | bool functional_mapintegrandprocessfn(void *arg) {
function functional_mapintegrand (line 1036) | bool functional_mapintegrand(vm *v, functional_mapinfo *info, value *out) {
function functional_mapgradient (line 1079) | bool functional_mapgradient(vm *v, functional_mapinfo *info, value *out) {
function functional_numericalgrad (line 1129) | bool functional_numericalgrad(vm *v, objectmesh *mesh, elementid eid, el...
function functional_numericalgradientmapfn (line 1152) | bool functional_numericalgradientmapfn(vm *v, objectmesh *mesh, elementi...
function functional_mapnumericalgradient (line 1180) | bool functional_mapnumericalgradient(vm *v, functional_mapinfo *info, va...
function functional_mapfieldgradient (line 1241) | bool functional_mapfieldgradient(vm *v, functional_mapinfo *info, value ...
function functional_numericalfieldgrad (line 1292) | bool functional_numericalfieldgrad(vm *v, objectmesh *mesh, elementid ei...
type functional_numericalfieldgradientref (line 1317) | typedef struct {
function functional_numericalfieldgradientmapfn (line 1325) | bool functional_numericalfieldgradientmapfn(vm *v, objectmesh *mesh, ele...
function functional_mapnumericalfieldgradient (line 1348) | bool functional_mapnumericalfieldgradient(vm *v, functional_mapinfo *inf...
function functional_sparseaccumulate (line 1428) | bool functional_sparseaccumulate(objectsparse *A, int i, int j, double v...
function functional_numericalhess (line 1440) | bool functional_numericalhess(vm *v, objectmesh *mesh, elementid eid, el...
function functional_numericalhessianmapfn (line 1496) | bool functional_numericalhessianmapfn(vm *v, objectmesh *mesh, elementid...
function _sparsecmp (line 1529) | static int _sparsecmp(const void *a, const void *b) {
function functional_mapnumericalhessian (line 1536) | bool functional_mapnumericalhessian(vm *v, functional_mapinfo *info, val...
function functional_vecadd (line 1625) | void functional_vecadd(unsigned int n, double *a, double *b, double *out) {
function functional_vecaddscale (line 1630) | void functional_vecaddscale(unsigned int n, double *a, double lambda, do...
function functional_vecsub (line 1635) | void functional_vecsub(unsigned int n, double *a, double *b, double *out) {
function functional_vecscale (line 1640) | void functional_vecscale(unsigned int n, double lambda, double *a, doubl...
function functional_vecnorm (line 1645) | double functional_vecnorm(unsigned int n, double *a) {
function functional_vecdot (line 1650) | double functional_vecdot(unsigned int n, double *a, double *b) {
function functional_veccross (line 1655) | void functional_veccross(double *a, double *b, double *out) {
function functional_veccross2d (line 1662) | void functional_veccross2d(double *a, double *b, double *out) {
function functional_elementsize (line 1671) | bool functional_elementsize(vm *v, objectmesh *mesh, grade g, elementid ...
function functional_elementgradient_scale (line 1689) | bool functional_elementgradient_scale(vm *v, objectmesh *mesh, grade g, ...
function functional_elementgradient (line 1699) | bool functional_elementgradient(vm *v, objectmesh *mesh, grade g, elemen...
function length_integrand (line 1713) | bool length_integrand(vm *v, objectmesh *mesh, elementid id, int nv, int...
function length_gradient_scale (line 1725) | bool length_gradient_scale(vm *v, objectmesh *mesh, elementid id, int nv...
function length_gradient (line 1740) | bool length_gradient(vm *v, objectmesh *mesh, elementid id, int nv, int ...
function areaenclosed_gradient (line 1783) | bool areaenclosed_gradient(vm *v, objectmesh *mesh, elementid id, int nv...
function area_gradient_scale (line 1844) | bool area_gradient_scale(vm *v, objectmesh *mesh, elementid id, int nv, ...
function area_gradient (line 1871) | bool area_gradient(vm *v, objectmesh *mesh, elementid id, int nv, int *v...
function volumeenclosed_gradient (line 1907) | bool volumeenclosed_gradient(vm *v, objectmesh *mesh, elementid id, int ...
function volume_gradient_scale (line 1965) | bool volume_gradient_scale(vm *v, objectmesh *mesh, elementid id, int nv...
function volume_gradient (line 1995) | bool volume_gradient(vm *v, objectmesh *mesh, elementid id, int nv, int ...
type scalarpotentialref (line 2020) | typedef struct {
function scalarpotential_prepareref (line 2024) | bool scalarpotential_prepareref(objectinstance *self, objectmesh *mesh, ...
function scalarpotential_integrand (line 2031) | bool scalarpotential_integrand(vm *v, objectmesh *mesh, elementid id, in...
function scalarpotential_gradient (line 2048) | bool scalarpotential_gradient(vm *v, objectmesh *mesh, elementid id, int...
function value (line 2071) | value ScalarPotential_init(vm *v, int nargs, value *args) {
function value (line 2097) | value ScalarPotential_gradient(vm *v, int nargs, value *args) {
type linearelasticityref (line 2147) | typedef struct {
function linearelasticity_calculategram (line 2155) | void linearelasticity_calculategram(objectmatrix *vert, int dim, int nv,...
function linearelasticity_integrand (line 2167) | bool linearelasticity_integrand(vm *v, objectmesh *mesh, elementid id, i...
function linearelasticity_prepareref (line 2204) | bool linearelasticity_prepareref(objectinstance *self, linearelasticityr...
function value (line 2227) | value LinearElasticity_init(vm *v, int nargs, value *args) {
function value (line 2251) | value LinearElasticity_integrand(vm *v, int nargs, value *args) {
function value (line 2269) | value LinearElasticity_total(vm *v, int nargs, value *args) {
function value (line 2286) | value LinearElasticity_gradient(vm *v, int nargs, value *args) {
type hydrogelref (line 2322) | typedef struct {
function hydrogel_prepareref (line 2330) | bool hydrogel_prepareref(objectinstance *self, objectmesh *mesh, grade g...
function hydrogel_integrand (line 2368) | bool hydrogel_integrand(vm *v, objectmesh *mesh, elementid id, int nv, i...
function hydrogel_gradient (line 2414) | bool hydrogel_gradient(vm *v, objectmesh *mesh, elementid id, int nv, in...
function value (line 2462) | value Hydrogel_gradient(vm *v, int nargs, value *args) {
function value (line 2482) | value Hydrogel_init(vm *v, int nargs, value *args) {
type equielementref (line 2530) | typedef struct {
function equielement_prepareref (line 2539) | bool equielement_prepareref(objectinstance *self, objectmesh *mesh, grad...
function equielement_contains (line 2571) | bool equielement_contains(varray_elementid *nbrs, elementid id) {
function equielement_dependencies (line 2579) | bool equielement_dependencies(functional_mapinfo *info, elementid id, va...
function equielement_integrand (line 2609) | bool equielement_integrand(vm *v, objectmesh *mesh, elementid id, int nv...
function value (line 2656) | value EquiElement_init(vm *v, int nargs, value *args) {
type curvatureref (line 2696) | typedef struct {
function curvature_prepareref (line 2702) | bool curvature_prepareref(objectinstance *self, objectmesh *mesh, grade ...
function linecurvsq_dependencies (line 2726) | bool linecurvsq_dependencies(functional_mapinfo *info, elementid id, var...
function linecurvsq_integrand (line 2754) | bool linecurvsq_integrand(vm *v, objectmesh *mesh, elementid id, int nv,...
function linetorsionsq_integrand (line 2857) | bool linetorsionsq_integrand(vm *v, objectmesh *mesh, elementid id, int ...
type areacurvatureref (line 2969) | typedef struct {
function areacurvature_prepareref (line 2976) | bool areacurvature_prepareref(objectinstance *self, objectmesh *mesh, gr...
function meancurvaturesq_dependencies (line 3004) | bool meancurvaturesq_dependencies(functional_mapinfo *info, elementid id...
function curvature_ordervertices (line 3039) | bool curvature_ordervertices(varray_elementid *synid, int nv, int *vids) {
function meancurvaturesq_integrand (line 3054) | bool meancurvaturesq_integrand(vm *v, objectmesh *mesh, elementid id, in...
function gradsq_computeperpendicular (line 3208) | bool gradsq_computeperpendicular(unsigned int n, double *s1, double *s2,...
function gradsq_evaluategradient (line 3234) | bool gradsq_evaluategradient(objectmesh *mesh, objectfield *field, int n...
function gradsq_evaluategradient1d (line 3273) | bool gradsq_evaluategradient1d(objectmesh *mesh, objectfield *field, int...
function gradsq_evaluategradient3d (line 3307) | bool gradsq_evaluategradient3d(objectmesh *mesh, objectfield *field, int...
function gradsq_prepareref (line 3348) | bool gradsq_prepareref(objectinstance *self, objectmesh *mesh, grade g, ...
function gradsq_integrand (line 3382) | bool gradsq_integrand(vm *v, objectmesh *mesh, elementid id, int nv, int...
function value (line 3404) | value GradSq_init(vm *v, int nargs, value *args) {
function value (line 3430) | value GradSq_fieldgradient(vm *v, int nargs, value *args) {
type nematicref (line 3467) | typedef struct {
function nematic_prepareref (line 3475) | bool nematic_prepareref(objectinstance *self, objectmesh *mesh, grade g,...
function nematic_bcint (line 3525) | double nematic_bcint(double *f, double *g) {
function nematic_bcint1 (line 3530) | double nematic_bcint1(double *f) {
function nematic_bcintf (line 3536) | double nematic_bcintf(unsigned int n, double *f) {
function nematic_bcintfg (line 3545) | double nematic_bcintfg(unsigned int n, double *f, double *g) {
function nematic_integrand (line 3555) | bool nematic_integrand(vm *v, objectmesh *mesh, elementid id, int nv, in...
function value (line 3644) | value Nematic_init(vm *v, int nargs, value *args) {
function value (line 3677) | value Nematic_fieldgradient(vm *v, int nargs, value *args) {
function nematicelectric_prepareref (line 3714) | bool nematicelectric_prepareref(objectinstance *self, objectmesh *mesh, ...
function nematicelectric_integrand (line 3759) | bool nematicelectric_integrand(vm *v, objectmesh *mesh, elementid id, in...
function value (line 3801) | value NematicElectric_init(vm *v, int nargs, value *args) {
function value (line 3823) | value NematicElectric_fieldgradient(vm *v, int nargs, value *args) {
function value (line 3873) | value NormSq_fieldgradient(vm *v, int nargs, value *args) {
type objectintegralelementref (line 3928) | typedef struct {
function objectintegralelementref_sizefn (line 3953) | size_t objectintegralelementref_sizefn(object *obj) {
function objectintegralelementref_printfn (line 3957) | void objectintegralelementref_printfn(object *obj, void *v) {
function objectintegralelementref (line 3985) | objectintegralelementref *integral_getelementref(vm *v) {
function integral_evaluatetangent (line 4000) | void integral_evaluatetangent(vm *v, value *out) {
function value (line 4021) | static value integral_tangent(vm *v, int nargs, value *args) {
function integral_evaluatenormal (line 4037) | void integral_evaluatenormal(vm *v, value *out) {
function value (line 4060) | static value integral_normal(vm *v, int nargs, value *args) {
function integral_prepareinvjacobian (line 4080) | bool integral_prepareinvjacobian(unsigned int dim, grade g, double **x, ...
function integral_gradalloc (line 4118) | bool integral_gradalloc(int dim, value prototype, value *out) {
function integral_gradsuminit (line 4132) | bool integral_gradsuminit(int i, value prototype, value dest, value *sum) {
function integral_gradsumcopy (line 4151) | bool integral_gradsumcopy(int i, value sum, value dest) {
function integral_oldgradcopy (line 4158) | bool integral_oldgradcopy(int dim, int ndof, double *grad, value prototy...
function integral_evaluategradient (line 4185) | bool integral_evaluategradient(vm *v, value q, value *out) {
function value (line 4280) | static value integral_gradfn(vm *v, int nargs, value *args) {
function integral_evaluatecg (line 4296) | void integral_evaluatecg(vm *v, value *out) {
function value (line 4328) | static value integral_cgfn(vm *v, int nargs, value *args) {
function integral_cleartlvars (line 4342) | void integral_cleartlvars(vm *v) {
function integral_freetlvars (line 4350) | void integral_freetlvars(vm *v) {
function integral_prepareref (line 4369) | bool integral_prepareref(objectinstance *self, objectmesh *mesh, grade g...
function integral_freeref (line 4438) | void integral_freeref(void *ref) {
function integral_clearelref (line 4445) | void integral_clearelref(objectintegralelementref *elref) {
function integral_preparequantities (line 4450) | bool integral_preparequantities(integralref *iref, int nv, int *vid, qua...
function integral_clearquantities (line 4488) | void integral_clearquantities(int nq, quantity *quantities) {
function integral_integrandfn (line 4494) | bool integral_integrandfn(unsigned int dim, double *t, double *x, unsign...
function lineintegral_integrand (line 4523) | bool lineintegral_integrand(vm *v, objectmesh *mesh, elementid id, int n...
function value (line 4594) | value LineIntegral_init(vm *v, int nargs, value *args) {
function value (line 4657) | value LineIntegral_fieldgradient(vm *v, int nargs, value *args) {
function value (line 4765) | value AreaIntegral_fieldgradient(vm *v, int nargs, value *args) {
function value (line 4867) | value VolumeIntegral_fieldgradient(vm *v, int nargs, value *args) {
function functional_finalize (line 4997) | void functional_finalize(void) {
FILE: src/geometry/functional.h
type symmetrybhvr (line 167) | typedef enum {
type s_functional_mapinfo (line 181) | struct s_functional_mapinfo
type s_functional_mapinfo (line 190) | struct s_functional_mapinfo
type functional_mapinfo (line 192) | typedef struct s_functional_mapinfo {
FILE: src/geometry/geometry.c
function geometry_initialize (line 9) | void geometry_initialize(void) {
FILE: src/geometry/integrate.c
function integrate_recognizequantities (line 21) | bool integrate_recognizequantities(unsigned int nquantity, value *quanti...
function integrate_interpolatepositionline (line 64) | void integrate_interpolatepositionline(unsigned int dim, double *x[3], d...
function integrate_interpolatequantitiesline (line 73) | void integrate_interpolatequantitiesline(unsigned int dim, double t, uns...
function integrate_lineint (line 108) | bool integrate_lineint(integrandfunction *function, unsigned int dim, do...
function integrate_interpolatepositiontri (line 245) | void integrate_interpolatepositiontri(unsigned int dim, double *x[3], do...
function integrate_interpolatequantitiestri (line 253) | void integrate_interpolatequantitiestri(unsigned int dim, double *lambda...
function integrate_areaint (line 290) | bool integrate_areaint(integrandfunction *function, unsigned int dim, do...
function integrate_interpolatepositionvol (line 582) | void integrate_interpolatepositionvol(unsigned int dim, double *x[4], do...
function integrate_interpolatequantitiesvol (line 590) | void integrate_interpolatequantitiesvol(unsigned int dim, double *lambda...
function integrate_integratevol (line 630) | bool integrate_integratevol(integrandfunction *function, unsigned int ns...
function integrate_volint (line 677) | bool integrate_volint(integrandfunction *function, unsigned int dim, dou...
function integrate_integrate (line 769) | bool integrate_integrate(integrandfunction *integrand, unsigned int dim,...
function integrator_init (line 2168) | void integrator_init(integrator *integrate) {
function integrator_clear (line 2197) | void integrator_clear(integrator *integrate) {
function integrator_addvertex (line 2204) | int integrator_addvertex(integrator *integrate, int ndof, double *v) {
function integrator_addelement (line 2211) | int integrator_addelement(integrator *integrate, int *vids) {
function integrator_initializequantities (line 2218) | void integrator_initializequantities(integrator *integrate, int nq, quan...
function integrator_finalizequantities (line 2238) | void integrator_finalizequantities(integrator *integrate) {
function integrator_getvertices (line 2244) | void integrator_getvertices(integrator *integrate, int elementid, double...
function integrator_getelement (line 2252) | void integrator_getelement(integrator *integrate, int elementid, int *vi...
function integrator_pushworkitem (line 2260) | bool integrator_pushworkitem(integrator *integrate, quadratureworkitem *...
function integrator_popworkitem (line 2276) | bool integrator_popworkitem(integrator *integrate, quadratureworkitem *w...
function integrator_estimate (line 2307) | void integrator_estimate(integrator *integrate) {
function integrator_preparevertices (line 2336) | void integrator_preparevertices(integrator *integrate, double **vref, do...
function integrator_prepareinterpolation (line 2355) | void integrator_prepareinterpolation(integrator *integrate, int elementi...
function integrator_sumlistweighted (line 2362) | double integrator_sumlistweighted(unsigned int nel, double *list, double...
function integrator_transformtorefelement (line 2367) | void integrator_transformtorefelement(integrator *integrate, double *rma...
function integrator_interpolatecoordinates (line 2378) | void integrator_interpolatecoordinates(integrator *integrate, double *la...
function integrator_sumquantityweighted (line 2388) | bool integrator_sumquantityweighted(int n, double *wts, value *q, value ...
function integrator_interpolatequantities (line 2406) | void integrator_interpolatequantities(integrator *integrate, double *bar...
function integrator_evalfn (line 2425) | bool integrator_evalfn(integrator *integrate, quadraturerule *rule, int ...
function integrator_quadrature (line 2440) | bool integrator_quadrature(integrator *integrate, quadraturerule *rule, ...
function integrator_subdivide (line 2502) | bool integrator_subdivide(integrator *integrate, quadratureworkitem *wor...
function integrator_sharpenerrorestimate (line 2552) | void integrator_sharpenerrorestimate(integrator *integrate, quadraturewo...
function integrator_update (line 2569) | void integrator_update(integrator *integrate, quadratureworkitem *work, ...
function integrator_matchrulebyname (line 2587) | bool integrator_matchrulebyname(int grade, char *name, quadraturerule **...
function integrator_matchrulebyextension (line 2600) | bool integrator_matchrulebyextension(quadraturerule *rule, quadraturerul...
function integrator_matchrulebyorder (line 2611) | bool integrator_matchrulebyorder(int grade, int minorder, int maxorder, ...
function integrator_matchrulebygrade (line 2629) | bool integrator_matchrulebygrade(int grade, quadraturerule **out) {
function integrator_configure (line 2647) | bool integrator_configure(integrator *integrate, error *err, bool adapt,...
function integrator_configurewithdictionary (line 2701) | bool integrator_configurewithdictionary(integrator *integrate, error *er...
function integrator_integrate (line 2754) | bool integrator_integrate(integrator *integrate, integrandfunction *inte...
function integrate (line 2842) | bool integrate(integrandfunction *integrand, objectdictionary *method, e...
function integrate_initialize (line 2864) | void integrate_initialize(void) {
FILE: src/geometry/integrate.h
type quadraturerule (line 50) | typedef struct quadraturerule_s quadraturerule;
type quadraturerule_s (line 57) | struct quadraturerule_s {
type subdivisionrule (line 78) | typedef struct subdivisionrule_struct subdivisionrule;
type subdivisionrule_struct (line 80) | struct subdivisionrule_struct {
type quadratureworkitem (line 94) | typedef struct {
type quantity (line 109) | typedef struct {
type integrator (line 120) | typedef struct {
FILE: src/geometry/mesh.c
function objectmesh_printfn (line 35) | void objectmesh_printfn(object *obj, void *v) {
function objectmesh_markfn (line 39) | void objectmesh_markfn(object *obj, void *v) {
function objectmesh_freefn (line 45) | void objectmesh_freefn(object *obj) {
function objectmesh_sizefn (line 57) | size_t objectmesh_sizefn(object *obj) {
function objectmesh (line 74) | objectmesh *object_newmesh(unsigned int dim, unsigned int nv, double *v) {
function mesh_link (line 96) | void mesh_link(objectmesh *mesh, object *obj) {
function mesh_delink (line 106) | void mesh_delink(objectmesh *mesh, object *obj) {
function mesh_getvertexcoordinates (line 130) | bool mesh_getvertexcoordinates(objectmesh *mesh, elementid id, double *o...
function mesh_getvertexcoordinatesaslist (line 140) | bool mesh_getvertexcoordinatesaslist(objectmesh *mesh, elementid id, dou...
function mesh_setvertexcoordinates (line 149) | bool mesh_setvertexcoordinates(objectmesh *mesh, elementid id, double *x...
function mesh_getvertexcoordinatesasvalues (line 154) | bool mesh_getvertexcoordinatesasvalues(objectmesh *mesh, elementid id, v...
function mesh_nearestvertex (line 172) | bool mesh_nearestvertex(objectmesh *mesh, double *x, elementid *id, doub...
function mesh_checkconnectivity (line 194) | bool mesh_checkconnectivity(objectmesh *mesh) {
function mesh_freezeconnectivity (line 203) | void mesh_freezeconnectivity(objectmesh *mesh) {
function objectsparse (line 215) | objectsparse *mesh_newconnectivityelement(objectmesh *mesh, unsigned int...
function mesh_setconnectivityelement (line 228) | bool mesh_setconnectivityelement(objectmesh *mesh, unsigned int row, uns...
function objectsparse (line 251) | objectsparse *mesh_getconnectivityelement(objectmesh *mesh, unsigned int...
function elementid (line 265) | elementid mesh_nvertices(objectmesh *mesh) {
function elementid (line 272) | elementid mesh_nelements(objectsparse *conn) {
function elementid (line 277) | elementid mesh_nelementsforgrade(objectmesh *mesh, grade g) {
function grade (line 289) | grade mesh_maxgrade(objectmesh *mesh) {
function mesh_getconnectivity (line 303) | bool mesh_getconnectivity(objectsparse *conn, elementid id, int *nentrie...
type ntuplelist (line 320) | typedef struct {
function ntuplelist_init (line 328) | void ntuplelist_init(ntuplelist *list, int n, elementid maxval) {
function ntuplelist_clear (line 337) | void ntuplelist_clear(ntuplelist *list) {
function ntuplelist_add (line 343) | void ntuplelist_add(ntuplelist *list, elementid *tuple) {
function ntuplelist_compare (line 354) | bool ntuplelist_compare(int n, elementid *t1, elementid *t2) {
function ntuplelist_find (line 360) | bool ntuplelist_find(ntuplelist *list, elementid *tuple) {
function objectsparse (line 374) | objectsparse *mesh_addgrade(objectmesh *mesh, grade g) {
function mesh_removegrade (line 446) | void mesh_removegrade(objectmesh *mesh, grade g) {
function objectsparse (line 458) | objectsparse *mesh_addgradeold(objectmesh *mesh, grade g) {
function mesh_compareid (line 526) | static int mesh_compareid(const void *a, const void *b) {
function mesh_matchelements (line 539) | bool mesh_matchelements(objectsparse *vmatrix, grade g, int nids, int *i...
function objectsparse (line 576) | static objectsparse *mesh_addlowermatrix(objectmesh *mesh, unsigned int ...
function objectsparse (line 618) | objectsparse *mesh_addconnectivityelement(objectmesh *mesh, unsigned int...
function mesh_addelementwithvertices (line 647) | bool mesh_addelementwithvertices(objectmesh *mesh, grade g, elementid *v) {
function mesh_resetconnectivity (line 665) | void mesh_resetconnectivity(objectmesh *m) {
function objectmesh (line 680) | objectmesh *mesh_clone(objectmesh *mesh) {
function mesh_addsymmetry (line 710) | bool mesh_addsymmetry(vm *v, objectmesh *mesh, value symmetry, objectsel...
function mesh_getsynonyms (line 757) | bool mesh_getsynonyms(objectmesh *mesh, grade g, elementid id, varray_el...
function varray_elementidwriteunique (line 772) | void varray_elementidwriteunique(varray_elementid *list, elementid id) {
function mesh_insertidsforelement (line 782) | void mesh_insertidsforelement(objectsparse *conn, elementid id, bool ign...
function mesh_findneighbors (line 793) | int mesh_findneighbors(objectmesh *mesh, grade g, elementid id, grade ta...
function mesh_checksection (line 852) | static bool mesh_checksection(char *line, grade *g) {
function objectmesh (line 865) | objectmesh *mesh_load(vm *v, char *file) {
function mesh_save (line 992) | bool mesh_save(objectmesh *m, char *file) {
function value (line 1042) | value mesh_constructor(vm *v, int nargs, value *args) {
function value (line 1065) | value Mesh_save(vm *v, int nargs, value *args) {
function value (line 1076) | value Mesh_print(vm *v, int nargs, value *args) {
function value (line 1088) | value Mesh_vertexmatrix(vm *v, int nargs, value *args) {
function value (line 1100) | value Mesh_setvertexmatrix(vm *v, int nargs, value *args) {
function value (line 1118) | value Mesh_vertexposition(vm *v, int nargs, value *args) {
function value (line 1140) | value Mesh_setvertexposition(vm *v, int nargs, value *args) {
function value (line 1155) | value Mesh_connectivitymatrix(vm *v, int nargs, value *args) {
function value (line 1177) | value Mesh_resetconnectivity(vm *v, int nargs, value *args) {
function value (line 1186) | value Mesh_addgrade(vm *v, int nargs, value *args) {
function value (line 1216) | value Mesh_removegrade(vm *v, int nargs, value *args) {
function value (line 1230) | value Mesh_addsymmetry(vm *v, int nargs, value *args) {
function value (line 1253) | value Mesh_maxgrade(vm *v, int nargs, value *args) {
function value (line 1260) | value Mesh_count(vm *v, int nargs, value *args) {
function value (line 1280) | value Mesh_clone(vm *v, int nargs, value *args) {
FILE: src/geometry/mesh.h
type objectmesh (line 25) | typedef struct {
type grade (line 68) | typedef int grade;
type elementid (line 69) | typedef int elementid;
FILE: src/geometry/selection.c
function objectselection_printfn (line 26) | void objectselection_printfn(object *obj, void *v) {
function objectselection_freefn (line 30) | void objectselection_freefn(object *obj) {
function objectselection_sizefn (line 35) | size_t objectselection_sizefn(object *obj) {
function objectselection (line 53) | objectselection *object_newselection(objectmesh *mesh) {
function objectselection (line 68) | objectselection *selection_clone(objectselection *sel) {
function selection_clear (line 80) | void selection_clear(objectselection *s) {
function selection_removegrade (line 87) | void selection_removegrade(objectselection *sel, grade g) {
function selection_selectelement (line 92) | bool selection_selectelement(objectselection *sel, grade g, elementid id) {
function selection_addgraderaise (line 104) | bool selection_addgraderaise(objectselection *sel, grade g, bool include...
function selection_addgradelower (line 129) | bool selection_addgradelower(objectselection *sel, grade g) {
function selection_selectwithfunction (line 160) | void selection_selectwithfunction(vm *v, objectselection *sel, value fn) {
function selection_selectwithmatrix (line 182) | void selection_selectwithmatrix(vm *v, objectselection *sel, value fn, o...
function selection_selectboundary (line 213) | void selection_selectboundary(vm *v, objectselection *sel) {
function selection_selectwithid (line 236) | void selection_selectwithid(objectselection *sel, grade g, elementid id,...
function selection_isselected (line 258) | bool selection_isselected(objectselection *sel, grade g, elementid id) {
function grade (line 269) | grade selection_maxgrade(objectselection *sel) {
function objectlist (line 282) | objectlist *selection_idlistforgrade(objectselection *sel, grade g) {
function objectselection (line 311) | objectselection *selection_union(objectselection *a, objectselection *b) {
function objectselection (line 327) | objectselection *selection_intersection(objectselection *a, objectselect...
function objectselection (line 343) | objectselection *selection_difference(objectselection *a, objectselectio...
function value (line 368) | value selection_constructor(vm *v, int nargs, value *args) {
function value (line 416) | value Selection_setindex(vm *v, int nargs, value *args) {
function value (line 430) | value Selection_isselected(vm *v, int nargs, value *args) {
function value (line 445) | value Selection_idlistforgrade(vm *v, int nargs, value *args) {
function value (line 461) | value Selection_addgrade(vm *v, int nargs, value *args) {
function value (line 482) | value Selection_removegrade(vm *v, int nargs, value *args) {
function value (line 493) | value Selection_print(vm *v, int nargs, value *args) {
function value (line 501) | value Selection_count(vm *v, int nargs, value *args) {
function value (line 514) | value Selection_clone(vm *v, int nargs, value *args) {
FILE: src/geometry/selection.h
type objectselection (line 22) | typedef struct {
FILE: src/linalg/matrix.c
function objectmatrix_sizefn (line 25) | size_t objectmatrix_sizefn(object *obj) {
function objectmatrix_printfn (line 31) | void objectmatrix_printfn(object *obj, void *v) {
function objectmatrix (line 45) | objectmatrix *object_newmatrix(unsigned int nrows, unsigned int ncols, b...
function matrix_raiseerror (line 69) | void matrix_raiseerror(vm *v, objectmatrixerror err) {
function matrix_getarraydimensions (line 87) | bool matrix_getarraydimensions(objectarray *array, unsigned int dim[], u...
function value (line 107) | value matrix_getarrayelement(objectarray *array, unsigned int ndim, unsi...
function objectmatrix (line 122) | objectmatrix *object_matrixfromarray(objectarray *array) {
function matrix_getlistdimensions (line 156) | bool matrix_getlistdimensions(objectlist *list, unsigned int dim[], unsi...
function matrix_getlistelement (line 175) | bool matrix_getlistelement(objectlist *list, unsigned int ndim, unsigned...
function objectmatrix (line 189) | objectmatrix *object_matrixfromlist(objectlist *list) {
function objectmatrix (line 219) | objectmatrix *object_matrixfromfloats(unsigned int nrows, unsigned int n...
function objectmatrix (line 233) | objectmatrix *object_clonematrix(objectmatrix *in) {
function matrix_setelement (line 249) | bool matrix_setelement(objectmatrix *matrix, unsigned int row, unsigned ...
function matrix_getelement (line 259) | bool matrix_getelement(objectmatrix *matrix, unsigned int row, unsigned ...
function matrix_getcolumn (line 272) | bool matrix_getcolumn(objectmatrix *matrix, unsigned int col, double **v) {
function matrix_setcolumn (line 285) | bool matrix_setcolumn(objectmatrix *matrix, unsigned int col, double *v) {
function matrix_addtocolumn (line 299) | bool matrix_addtocolumn(objectmatrix *m, unsigned int col, double alpha,...
function matrix_countdof (line 312) | unsigned int matrix_countdof(objectmatrix *a) {
function objectmatrixerror (line 317) | objectmatrixerror matrix_copy(objectmatrix *a, objectmatrix *out) {
function objectmatrixerror (line 326) | objectmatrixerror matrix_copyat(objectmatrix *a, objectmatrix *out, int ...
function objectmatrixerror (line 342) | objectmatrixerror matrix_add(objectmatrix *a, objectmatrix *b, objectmat...
function objectmatrixerror (line 353) | objectmatrixerror matrix_addscalar(objectmatrix *a, double lambda, doubl...
function objectmatrixerror (line 365) | objectmatrixerror matrix_accumulate(objectmatrix *a, double lambda, obje...
function objectmatrixerror (line 374) | objectmatrixerror matrix_sub(objectmatrix *a, objectmatrix *b, objectmat...
function objectmatrixerror (line 385) | objectmatrixerror matrix_mul(objectmatrix *a, objectmatrix *b, objectmat...
function objectmatrixerror (line 394) | objectmatrixerror matrix_inner(objectmatrix *a, objectmatrix *b, double ...
function objectmatrixerror (line 403) | objectmatrixerror matrix_outer(objectmatrix *a, objectmatrix *b, objectm...
function objectmatrixerror (line 420) | static objectmatrixerror matrix_div(objectmatrix *a, objectmatrix *b, ob...
function objectmatrixerror (line 436) | objectmatrixerror matrix_divs(objectmatrix *a, objectmatrix *b, objectma...
function objectmatrixerror (line 447) | objectmatrixerror matrix_divl(objectmatrix *a, objectmatrix *b, objectma...
function objectmatrixerror (line 467) | objectmatrixerror matrix_inverse(objectmatrix *a, objectmatrix *out) {
function objectmatrixerror (line 498) | objectmatrixerror matrix_eigensystem(objectmatrix *a, double *wr, double...
function matrix_sum (line 525) | double matrix_sum(objectmatrix *a) {
function matrix_norm (line 541) | double matrix_norm(objectmatrix *a) {
function matrix_L1norm (line 547) | double matrix_L1norm(objectmatrix *a) {
function matrix_Lnnorm (line 561) | double matrix_Lnnorm(objectmatrix *a, double n) {
function matrix_Linfnorm (line 575) | double matrix_Linfnorm(objectmatrix *a) {
function objectmatrixerror (line 587) | objectmatrixerror matrix_transpose(objectmatrix *a, objectmatrix *out) {
function objectmatrixerror (line 598) | objectmatrixerror matrix_trace(objectmatrix *a, double *out) {
function objectmatrixerror (line 607) | objectmatrixerror matrix_scale(objectmatrix *a, double scale) {
function objectmatrixerror (line 614) | objectmatrixerror matrix_identity(objectmatrix *a) {
function objectmatrixerror (line 622) | objectmatrixerror matrix_zero(objectmatrix *a) {
function matrix_print (line 629) | void matrix_print(vm *v, objectmatrix *m) {
function matrix_printtobuffer (line 642) | bool matrix_printtobuffer(objectmatrix *m, char *format, varray_char *ou...
function matrix_eigen (line 659) | bool matrix_eigen(vm *v, objectmatrix *a, value *evals, value *evecs) {
function value (line 721) | value matrix_constructor(vm *v, int nargs, value *args) {
function value (line 774) | value matrix_identityconstructor(vm *v, int nargs, value *args) {
function matrix_slicedim (line 797) | bool matrix_slicedim(value * a, unsigned int ndim){
function matrix_sliceconstructor (line 803) | void matrix_sliceconstructor(unsigned int *slicesize,unsigned int ndim,v...
function objectarrayerror (line 811) | objectarrayerror matrix_slicecopy(value * a,value * out, unsigned int nd...
function matrix_rollflat (line 829) | void matrix_rollflat(objectmatrix *a, objectmatrix *b, int nplaces) {
function matrix_copyrow (line 845) | void matrix_copyrow(objectmatrix *a, int arow, objectmatrix *b, int brow) {
function objectmatrix (line 850) | objectmatrix *matrix_roll(objectmatrix *a, int nplaces, int axis) {
function value (line 871) | value Matrix_getindex(vm *v, int nargs, value *args) {
function value (line 898) | value Matrix_setindex(vm *v, int nargs, value *args) {
function value (line 916) | value Matrix_setcolumn(vm *v, int nargs, value *args) {
function value (line 936) | value Matrix_getcolumn(vm *v, int nargs, value *args) {
function value (line 960) | value Matrix_print(vm *v, int nargs, value *args) {
function value (line 970) | value Matrix_format(vm *v, int nargs, value *args) {
function value (line 994) | value Matrix_assign(vm *v, int nargs, value *args) {
function value (line 1009) | value Matrix_add(vm *v, int nargs, value *args) {
function value (line 1040) | value Matrix_addr(vm *v, int nargs, value *args) {
function value (line 1065) | value Matrix_sub(vm *v, int nargs, value *args) {
function value (line 1096) | value Matrix_subr(vm *v, int nargs, value *args) {
function value (line 1135) | value Matrix_mul(vm *v, int nargs, value *args) {
function value (line 1170) | value Matrix_mulr(vm *v, int nargs, value *args) {
function value (line 1190) | value Matrix_div(vm *v, int nargs, value *args) {
function value (line 1240) | value Matrix_acc(vm *v, int nargs, value *args) {
function value (line 1260) | value Matrix_inner(vm *v, int nargs, value *args) {
function value (line 1277) | value Matrix_outer(vm *v, int nargs, value *args) {
function value (line 1296) | value Matrix_sum(vm *v, int nargs, value *args) {
function value (line 1302) | value Matrix_roll(vm *v, int nargs, value *args) {
function value (line 1326) | value Matrix_norm(vm *v, int nargs, value *args) {
function value (line 1356) | value Matrix_eigenvalues(vm *v, int nargs, value *args) {
function value (line 1371) | value Matrix_eigensystem(vm *v, int nargs, value *args) {
function value (line 1398) | value Matrix_inverse(vm *v, int nargs, value *args) {
function value (line 1417) | value Matrix_transpose(vm *v, int nargs, value *args) {
function value (line 1432) | value Matrix_reshape(vm *v, int nargs, value *args) {
function value (line 1451) | value Matrix_trace(vm *v, int nargs, value *args) {
function value (line 1466) | value Matrix_enumerate(vm *v, int nargs, value *args) {
function value (line 1484) | value Matrix_count(vm *v, int nargs, value *args) {
function value (line 1491) | value Matrix_dimensions(vm *v, int nargs, value *args) {
function value (line 1509) | value Matrix_clone(vm *v, int nargs, value *args) {
FILE: src/linalg/matrix.h
type objectmatrix (line 48) | typedef struct {
type objectmatrixerror (line 153) | typedef enum { MATRIX_OK, MATRIX_INCMPTBLDIM, MATRIX_SING, MATRIX_INVLD,...
FILE: src/linalg/sparse.c
function sparse_ccstocsparse (line 28) | void sparse_ccstocsparse(sparseccs *s, cs *out) {
function sparse_csparsetoccs (line 39) | void sparse_csparsetoccs(cs *in, sparseccs *out) {
function objectdokkey_printfn (line 56) | void objectdokkey_printfn(object *obj, void *v) {
function objectdokkey_sizefn (line 60) | size_t objectdokkey_sizefn(object *obj) {
function hash (line 65) | hash objectdokkey_hashfn(object *obj) {
function objectdokkey_cmpfn (line 72) | int objectdokkey_cmpfn(object *a, object *b) {
function sparsedok_init (line 92) | void sparsedok_init(sparsedok *dok) {
function sparsedok_clear (line 100) | void sparsedok_clear(sparsedok *dok) {
function objectdokkey (line 111) | static objectdokkey *sparsedok_newkey(sparsedok *dok, int i, int j) {
function objectdokkey (line 124) | static objectdokkey *sparsedok_addkey(sparsedok *dok, int i, int j) {
function sparsedok_insert (line 137) | bool sparsedok_insert(sparsedok *dok, int i, int j, value val) {
function sparsedok_get (line 155) | bool sparsedok_get(sparsedok *dok, int i, int j, value *val) {
function sparsedok_remove (line 163) | bool sparsedok_remove(sparsedok *dok, int i, int j, value *val) {
function sparsedok_setdimensions (line 171) | bool sparsedok_setdimensions(sparsedok *dok, int nrows, int ncols) {
function sparsedok_expanddimensions (line 181) | bool sparsedok_expanddimensions(sparsedok *dok, int nrows, int ncols) {
function sparsedok_print (line 188) | void sparsedok_print(vm *v, sparsedok *dok) {
function sparsedok_count (line 205) | unsigned int sparsedok_count(sparsedok *dok) {
function sparsedok_loop (line 222) | bool sparsedok_loop(sparsedok *dok, void **cntr, int *i, int *j) {
function sparsedok_copy (line 237) | bool sparsedok_copy(sparsedok *src, sparsedok *dest) {
function sparsedok_copyat (line 254) | bool sparsedok_copyat(sparsedok *src, sparsedok *dest, int row0, int col...
function sparsedok_copymatrixat (line 269) | bool sparsedok_copymatrixat(objectmatrix *src, sparsedok *dest, int row0...
function sparsedok_copytomatrix (line 282) | bool sparsedok_copytomatrix(sparsedok *src, objectmatrix *dest, int row0...
function sparseccs_init (line 303) | void sparseccs_init(sparseccs *ccs) {
function _ccsfree (line 313) | static void _ccsfree(void *p) {
function sparseccs_clear (line 331) | void sparseccs_clear(sparseccs *ccs) {
function sparseccs_resize (line 339) | bool sparseccs_resize(sparseccs *ccs, int nrows, int ncols, unsigned int...
function sparseccs_getrowindiceswithvalues (line 367) | bool sparseccs_getrowindiceswithvalues(sparseccs *ccs, int col, int *nen...
function sparseccs_getrowindices (line 376) | bool sparseccs_getrowindices(sparseccs *ccs, int col, int *nentries, int...
function sparseccs_setrowindices (line 386) | bool sparseccs_setrowindices(sparseccs *ccs, int col, int nentries, int ...
function sparseccs_getcolindices (line 400) | bool sparseccs_getcolindices(sparseccs *ccs, int maxentries, int *nentri...
function sparseccs_getcolindicesforrow (line 420) | bool sparseccs_getcolindicesforrow(sparseccs *ccs, int row, int maxentri...
function sparseccs_set (line 437) | bool sparseccs_set(sparseccs *ccs, int i, int j, double val) {
function sparseccs_get (line 450) | bool sparseccs_get(sparseccs *ccs, int i, int j, double *val) {
function sparseccs_compareuint (line 462) | static int sparseccs_compareuint(const void * a, const void * b) {
function sparseccs_doktoccs (line 468) | bool sparseccs_doktoccs(sparsedok *in, sparseccs *out, bool copyvals) {
function sparseccs_print (line 532) | void sparseccs_print(vm *v, sparseccs *ccs) {
function sparseccs_count (line 545) | unsigned int sparseccs_count(sparseccs *ccs) {
function sparseccs_copy (line 550) | bool sparseccs_copy(sparseccs *src, sparseccs *dest) {
function sparseccs_copytodok (line 562) | bool sparseccs_copytodok(sparseccs *src, sparsedok *dest, int row0, int ...
function sparseccs_copytomatrix (line 579) | bool sparseccs_copytomatrix(sparseccs *src, objectmatrix *dest, int row0...
function sparse_checkformat (line 604) | bool sparse_checkformat(objectsparse *sparse, objectsparseformat format,...
function sparse_removeformat (line 619) | void sparse_removeformat(objectsparse *s, objectsparseformat format) {
function objectsparse_printfn (line 634) | void objectsparse_printfn(object *obj, void *v) {
function objectsparse_markfn (line 638) | void objectsparse_markfn(object *obj, void *v) {
function objectsparse_freefn (line 642) | void objectsparse_freefn(object *obj) {
function objectsparse_sizefn (line 647) | size_t objectsparse_sizefn(object *obj) {
function objectsparse (line 667) | objectsparse *object_newsparse(int *nrows, int *ncols) {
function sparse_checkupdatedimension (line 684) | bool sparse_checkupdatedimension(int check, int *dim) {
function objectsparseerror (line 691) | objectsparseerror sparse_catcheckdimensions(objectlist *in, int ndim, un...
function sparse_catcopysparsetosparseat (line 723) | bool sparse_catcopysparsetosparseat(objectsparse *src, int row0, int col...
function sparse_catcopysparsetomatrixat (line 733) | bool sparse_catcopysparsetomatrixat(objectsparse *src, int row0, int col...
function sparse_catcopyentry (line 743) | bool sparse_catcopyentry(void *out, value val, int irow, int icol) {
function matrix_catcopyentry (line 759) | bool matrix_catcopyentry(void *out, value val, int irow, int icol) {
function objectsparseerror (line 776) | objectsparseerror sparse_docat(objectlist *in, void *dest, sparse_catcop...
function objectsparseerror (line 820) | objectsparseerror sparse_cat(objectlist *in, objectsparse *dest) {
function objectsparseerror (line 825) | objectsparseerror sparse_catmatrix(objectlist *in, objectmatrix **out) {
function objectsparse (line 848) | objectsparse *object_sparsefromarray(objectarray *array) {
function objectsparseerror (line 874) | objectsparseerror object_sparsefromlist(objectlist *list, objectsparse *...
function objectsparseerror (line 918) | objectsparseerror sparse_tomatrix(objectsparse *in, objectmatrix **out) {
function objectsparse (line 941) | objectsparse *sparse_clone(objectsparse *s) {
function sparse_getdimensions (line 953) | void sparse_getdimensions(objectsparse *s, int *nrows, int *ncols) {
function sparse_setelement (line 964) | bool sparse_setelement(objectsparse *s, int row, int col, value val) {
function sparse_getelement (line 979) | bool sparse_getelement(objectsparse *s, int row, int col, value *val) {
function sparse_enumerate (line 992) | bool sparse_enumerate(objectsparse *s, int i, value *out) {
function objectsparseerror (line 1015) | objectsparseerror sparse_add(objectsparse *a, objectsparse *b, double al...
function objectsparseerror (line 1040) | objectsparseerror sparse_mul(objectsparse *a, objectsparse *b, objectspa...
function objectsparseerror (line 1065) | objectsparseerror sparse_mulsxd(objectsparse *a, objectmatrix *b, object...
function objectsparseerror (line 1085) | objectsparseerror sparse_muldxs(objectmatrix *a, objectsparse *b, object...
function objectsparseerror (line 1114) | objectsparseerror sparse_scale(objectsparse *src, double scale, objectsp...
function objectsparseerror (line 1130) | objectsparseerror sparse_div(objectsparse *a, objectmatrix *b, objectmat...
function objectsparseerror (line 1155) | objectsparseerror sparse_transpose(objectsparse *a, objectsparse *out) {
function sparse_clear (line 1174) | void sparse_clear(objectsparse *a) {
function sparse_size (line 1180) | size_t sparse_size(objectsparse *a) {
function sparse_raiseerror (line 1192) | void sparse_raiseerror(vm *v, objectsparseerror err) {
function value (line 1203) | value sparse_constructor(vm *v, int nargs, value *args) {
function value (line 1243) | value Sparse_getindex(vm *v, int nargs, value *args) {
function value (line 1256) | value Sparse_setindex(vm *v, int nargs, value *args) {
function value (line 1275) | value Sparse_enumerate(vm *v, int nargs, value *args) {
function value (line 1291) | value Sparse_print(vm *v, int nargs, value *args) {
function value (line 1307) | value Sparse_add(vm *v, int nargs, value *args) {
function value (line 1337) | value Sparse_sub(vm *v, int nargs, value *args) {
function value (line 1366) | value Sparse_mul(vm *v, int nargs, value *args) {
function value (line 1419) | value Sparse_mulr(vm *v, int nargs, value *args) {
function value (line 1451) | value Sparse_div(vm *v, int nargs, value *args) {
function value (line 1456) | value Sparse_divr(vm *v, int nargs, value *args) {
function value (line 1482) | value Sparse_transpose(vm *v, int nargs, value *args) {
function value (line 1504) | value Sparse_clone(vm *v, int nargs, value *args) {
function value (line 1518) | value Sparse_count(vm *v, int nargs, value *args) {
function value (line 1532) | value Sparse_dimensions(vm *v, int nargs, value *args) {
function value (line 1552) | value Sparse_getcolumn(vm *v, int nargs, value *args) {
function value (line 1596) | value Sparse_rowindices(vm *v, int nargs, value *args) {
function value (line 1623) | value Sparse_setrowindices(vm *v, int nargs, value *args) {
function value (line 1658) | value Sparse_colindices(vm *v, int nargs, value *args) {
function value (line 1687) | value Sparse_indices(vm *v, int nargs, value *args) {
FILE: src/linalg/sparse.h
type objectdokkey (line 27) | typedef struct {
type sparsedok (line 51) | typedef struct {
type sparseccs (line 58) | typedef struct {
type objectsparse (line 70) | typedef struct {
type objectsparseformat (line 161) | typedef enum { SPARSE_DOK, SPARSE_CCS } objectsparseformat;
type objectsparseerror (line 163) | typedef enum { SPARSE_OK, SPARSE_INCMPTBLDIM, SPARSE_INVLDINIT, SPARSE_C...
FILE: src/morpho.h
type vm (line 21) | typedef void vm;
type program (line 22) | typedef void program;
type compiler (line 23) | typedef void compiler;
FILE: src/support/common.c
function morpho_printvalue (line 21) | void morpho_printvalue(vm *v, value val) {
function morpho_printtobuffer (line 47) | bool morpho_printtobuffer(vm *v, value val, varray_char *buffer) {
function value (line 101) | value morpho_concatenate(vm *v, int nval, value *val) {
function morpho_utf8numberofbytes (line 133) | int morpho_utf8numberofbytes(const char *string) {
function morpho_utf8toint (line 146) | int morpho_utf8toint(const char *c) {
function morpho_encodeutf8 (line 164) | int morpho_encodeutf8(int c, char *out) {
function morpho_powerof2ceiling (line 195) | unsigned int morpho_powerof2ceiling(unsigned int n) {
function morpho_countparameters (line 211) | bool morpho_countparameters(value f, int *nparams) {
function morpho_tuplesinit (line 241) | void morpho_tuplesinit(unsigned int nval, unsigned int n, unsigned int *...
function morpho_tuples (line 256) | bool morpho_tuples(unsigned int nval, value *list, unsigned int n, unsig...
FILE: src/support/common.h
type morphoinputmode (line 25) | typedef enum {
function morpho_iscallable (line 64) | static inline bool morpho_iscallable(value a) {
type tuplemode (line 90) | typedef enum {
FILE: src/support/extensions.c
type extension (line 26) | typedef struct {
function extension_dlopen (line 44) | bool extension_dlopen(extension *e) {
function extension_dlclose (line 51) | void extension_dlclose(extension *e) {
function extension_init (line 57) | void extension_init(extension *e) {
function extension_clear (line 66) | void extension_clear(extension *e) {
function extension_initwithname (line 79) | bool extension_initwithname(extension *e, char *name, char *path) {
function extension_call (line 102) | bool extension_call(extension *e, const char *name, const char *fn) {
function extension_find (line 116) | bool extension_find(char *name, value *path) {
function extension_isloaded (line 121) | bool extension_isloaded(value path, extension *out) {
function extension_initialize (line 134) | bool extension_initialize(extension *e) {
function extension_finalize (line 150) | bool extension_finalize(extension *e) {
function extension_load (line 155) | bool extension_load(char *name, dictionary **functiontable, dictionary *...
function extensions_initialize (line 186) | void extensions_initialize(void) {
function extensions_finalize (line 192) | void extensions_finalize(void) {
FILE: src/support/format.c
type format (line 24) | typedef struct fformat {
function _format_parse (line 33) | bool _format_parse(char *formatstring, char *validtypes, char **endptr, ...
function _format_printtobuffer (line 64) | bool _format_printtobuffer(value v, format *f, varray_char *out) {
function format_printtobuffer (line 92) | bool format_printtobuffer(value v, char *formatstring, varray_char *out) {
FILE: src/support/lex.c
function _lex_tokndefncmp (line 24) | int _lex_tokndefncmp(const void *ldefn, const void *rdefn) {
function _lex_tokendefnwithstringcmp (line 32) | int _lex_tokendefnwithstringcmp(const void *lstr, const void *rdefn) {
function _lex_tokendefnwithtokencmp (line 40) | int _lex_tokendefnwithtokencmp(const void *ltok, const void *rdefn) {
function _lex_tokendefnwithtokenfirstcharcmp (line 54) | int _lex_tokendefnwithtokenfirstcharcmp(const void *l, const void *rdefn) {
function lex_recordtoken (line 72) | void lex_recordtoken(lexer *l, tokentype type, token *tok) {
function lex_advance (line 81) | char lex_advance(lexer *l) {
function lex_advanceby (line 89) | char lex_advanceby(lexer *l, size_t n) {
function lex_back (line 96) | bool lex_back(lexer *l) {
function lex_isatend (line 104) | bool lex_isatend(lexer *l) {
function lex_isalpha (line 109) | bool lex_isalpha(char c) {
function lex_isdigit (line 114) | bool lex_isdigit(char c) {
function lex_isspace (line 120) | bool lex_isspace(char c) {
function lex_peek (line 125) | char lex_peek(lexer *l) {
function lex_peekahead (line 130) | char lex_peekahead(lexer *l, int n) {
function lex_peekprevious (line 135) | char lex_peekprevious(lexer *l) {
function lex_newline (line 141) | void lex_newline(lexer *l) {
function lex_matchtoken (line 149) | bool lex_matchtoken(lexer *l, tokendefn **defn) {
function lex_identifytoken (line 164) | bool lex_identifytoken(lexer *l, tokendefn **defn) {
function lex_skipmultilinecomment (line 283) | bool lex_skipmultilinecomment(lexer *l, token *tok, error *err) {
function lex_skipcomment (line 324) | bool lex_skipcomment(lexer *l, token *tok, error *err) {
function lex_skipshebang (line 340) | bool lex_skipshebang(lexer *l) {
function lex_skipwhitespace (line 352) | bool lex_skipwhitespace(lexer *l, token *tok, error *err) {
function lex_string (line 375) | bool lex_string(lexer *l, token *tok, error *err) {
function lex_number (line 419) | bool lex_number(lexer *l, token *tok, error *err) {
function tokentype (line 464) | tokentype lex_checksymbol(lexer *l, int start, int length, char *match, ...
function tokentype (line 475) | tokentype lex_typeforsymboltoken(lexer *l) {
function lex_symbol (line 489) | bool lex_symbol(lexer *l, token *tok, error *err) {
function lex_preprocess (line 505) | bool lex_preprocess(lexer *l, token *tok, error *err) {
function lex_processnewline (line 513) | bool lex_processnewline(lexer *l, token *tok, error *err) {
function lex_processinterpolation (line 519) | bool lex_processinterpolation(lexer *l, token *tok, error *err) {
function lex_init (line 534) | void lex_init(lexer *l, const char *start, int line) {
function lex_clear (line 555) | void lex_clear(lexer *l) {
function lex_settokendefns (line 571) | void lex_settokendefns(lexer *l, tokendefn *defns) {
function lex_seteof (line 585) | void lex_seteof(lexer *l, tokentype eoftype) {
function tokentype (line 590) | tokentype lex_eof(lexer *l) {
function lex_setnumbertype (line 595) | void lex_setnumbertype(lexer *l, tokentype inttype, tokentype flttype, t...
function lex_setsymboltype (line 602) | void lex_setsymboltype(lexer *l, tokentype symboltype) {
function tokentype (line 607) | tokentype lex_symboltype(lexer *l) {
function lex_setstringinterpolation (line 612) | void lex_setstringinterpolation(lexer *l, bool interpolation) {
function lex_setmatchkeywords (line 617) | void lex_setmatchkeywords(lexer *l, bool match) {
function lex_matchkeywords (line 622) | bool lex_matchkeywords(lexer *l) {
function lex_setwhitespacefn (line 627) | void lex_setwhitespacefn(lexer *l, processtokenfn whitespacefn) {
function lex_setprefn (line 632) | void lex_setprefn(lexer *l, processtokenfn prefn) {
function lex_tokeniskeyword (line 641) | bool lex_tokeniskeyword(lexer *l, token *tok) {
function lex (line 651) | bool lex(lexer *l, token *tok, error *err) {
function lex_initialize (line 694) | void lex_initialize(void) {
FILE: src/support/lex.h
type lexer (line 16) | typedef struct slexer lexer;
type tokentype (line 25) | typedef int tokentype;
type token (line 28) | typedef struct {
type tokendefn (line 51) | typedef struct {
type slexer (line 64) | struct slexer {
FILE: src/support/parse.c
function parse_error (line 33) | void parse_error(parser *p, bool use_prev, errorid id, ... ) {
function parse_advance (line 48) | bool parse_advance(parser *p) {
function parse_savestate (line 68) | void parse_savestate(parser *p, parser *op, lexer *ol) {
function parse_restorestate (line 75) | void parse_restorestate(parser *op, lexer *ol, parser *out) {
function parse_precedence (line 84) | bool parse_precedence(parser *p, precedence prec, void *out) {
function parse_checktoken (line 119) | bool parse_checktoken(parser *p, tokentype type) {
function parse_checktokenmulti (line 124) | bool parse_checktokenmulti(parser *p, int n, tokentype *type) {
function parse_checktokenadvance (line 133) | bool parse_checktokenadvance(parser *p, tokentype type) {
function parse_checktokeniskeywordadvance (line 140) | bool parse_checktokeniskeywordadvance(parser *p) {
function parse_checkrequiredtoken (line 151) | bool parse_checkrequiredtoken(parser *p, tokentype type, errorid id) {
function parse_checkdisallowedtoken (line 166) | bool parse_checkdisallowedtoken(parser *p, tokentype type, errorid id) {
function parse_codepointfromhex (line 181) | bool parse_codepointfromhex(parser *p, const char *codestr, int nhex, bo...
function parse_stringfromtoken (line 211) | bool parse_stringfromtoken(parser *p, unsigned int start, unsigned int l...
function value (line 267) | value parse_tokenasstring(parser *p) {
function parse_tokenassymbol (line 275) | bool parse_tokenassymbol(parser *p) {
function parse_addnode (line 286) | bool parse_addnode(parser *p, syntaxtreenodetype type, value content, to...
function syntaxtreenode (line 300) | syntaxtreenode *parse_lookupnode(parser *p, syntaxtreeindx i) {
function parse_validatestrtol (line 305) | bool parse_validatestrtol(parser *p, long f) {
function parse_validatestrtod (line 315) | bool parse_validatestrtod(parser *p, double f) {
function parse_tokentointeger (line 324) | bool parse_tokentointeger(parser *p, long *i) {
function parse_tokentodouble (line 330) | bool parse_tokentodouble(parser *p, double *x) {
function parse_incrementrecursiondepth (line 336) | bool parse_incrementrecursiondepth(parser *p) {
function parse_decrementrecursiondepth (line 347) | bool parse_decrementrecursiondepth(parser *p) {
function parse_addobject (line 353) | void parse_addobject(parser *p, value obj) {
function parse_freeobjects (line 358) | void parse_freeobjects(parser *p) {
function parse_clearobjects (line 363) | void parse_clearobjects(parser *p) {
function parse_expressionlist (line 387) | bool parse_expressionlist(parser *p, tokentype rightdelimiter, unsigned ...
function parse_arglist (line 417) | bool parse_arglist(parser *p, tokentype rightdelimiter, unsigned int *na...
function parse_variable (line 483) | bool parse_variable(parser *p, errorid id, void *out) {
function parse_reference (line 489) | bool parse_reference(parser *p, errorid errid, void *out) {
function parse_statementterminator (line 510) | bool parse_statementterminator(parser *p) {
function parse_checkstatementterminator (line 523) | bool parse_checkstatementterminator(parser *p) {
function parse_synchronize (line 533) | bool parse_synchronize(parser *p) {
function parse_nil (line 567) | bool parse_nil(parser *p, void *out) {
function parse_integer (line 573) | bool parse_integer(parser *p, void *out) {
function parse_number (line 581) | bool parse_number(parser *p, void *out) {
function parse_complex (line 589) | bool parse_complex(parser *p, void *out) {
function parse_bool (line 602) | bool parse_bool(parser *p, void *out) {
function parse_self (line 608) | bool parse_self(parser *p, void *out) {
function parse_super (line 613) | bool parse_super(parser *p, void *out) {
function parse_symbol (line 623) | bool parse_symbol(parser *p, void *out) {
function parse_string (line 635) | bool parse_string(parser *p, void *out) {
function parse_dictionary (line 645) | bool parse_dictionary(parser *p, void *out) {
function parse_interpolation (line 678) | bool parse_interpolation(parser *p, void *out) {
function parse_tuple (line 711) | bool parse_tuple(parser *p, token *start, syntaxtreeindx first, void *ou...
function parse_grouping (line 730) | bool parse_grouping(parser *p, void *out) {
function parse_unary (line 751) | bool parse_unary(parser *p, void *out) {
function parse_binary (line 771) | bool parse_binary(parser *p, void *out) {
function parse_ternary (line 832) | bool parse_ternary(parser *p, void *out) {
function parse_assignby (line 845) | bool parse_assignby(parser *p, void *out) {
function parse_range (line 878) | bool parse_range(parser *p, void *out) {
function parse_call (line 901) | bool parse_call(parser *p, void *out) {
function parse_index (line 918) | bool parse_index(parser *p, void *out) {
function parse_list (line 931) | bool parse_list(parser *p, void *out) {
function parse_anonymousfunction (line 941) | bool parse_anonymousfunction(parser *p, void *out) {
function parse_switch (line 964) | bool parse_switch(parser *p, void *out) {
function parse_vardeclaration (line 994) | bool parse_vardeclaration(parser *p, void *out) {
function parse_typedvardeclaration (line 1027) | bool parse_typedvardeclaration(parser *p, void *out) {
function parse_functiondeclaration (line 1069) | bool parse_functiondeclaration(parser *p, void *out) {
function parse_classdeclaration (line 1098) | bool parse_classdeclaration(parser *p, void *out) {
function parse_importqualifierlist (line 1148) | bool parse_importqualifierlist(parser *p, void *out) {
function parse_importdeclaration (line 1197) | bool parse_importdeclaration(parser *p, void *out) {
function parse_printstatement (line 1235) | bool parse_printstatement(parser *p, void *out) {
function parse_expressionstatement (line 1244) | bool parse_expressionstatement(parser *p, void *out) {
function parse_blockstatement (line 1258) | bool parse_blockstatement(parser *p, void *out) {
function parse_ifstatement (line 1275) | bool parse_ifstatement(parser *p, void *out) {
function parse_whilestatement (line 1300) | bool parse_whilestatement(parser *p, void *out) {
function parse_forstatement (line 1314) | bool parse_forstatement(parser *p, void *out) {
function parse_dostatement (line 1396) | bool parse_dostatement(parser *p, void *out) {
function parse_breakstatement (line 1417) | bool parse_breakstatement(parser *p, void *out) {
function parse_returnstatement (line 1426) | bool parse_returnstatement(parser *p, void *out) {
function parse_trystatement (line 1443) | bool parse_trystatement(parser *p, void *out) {
function parse_breakpointstatement (line 1464) | bool parse_breakpointstatement(parser *p, void *out) {
function parse_expression (line 1479) | bool parse_expression(parser *p, void *out) {
function parse_pseudoexpression (line 1484) | bool parse_pseudoexpression(parser *p, void *out) {
function parse_statement (line 1494) | bool parse_statement(parser *p, void *out) {
function parse_declaration (line 1526) | bool parse_declaration(parser *p, void *out) {
function parse_declarationmulti (line 1550) | bool parse_declarationmulti(parser *p, int n, tokentype *end, void *out) {
function parse_program (line 1571) | bool parse_program(parser *p, void *out) {
function _parse_parserulecmp (line 1670) | int _parse_parserulecmp(const void *l, const void *r) {
function parserule (line 1677) | parserule *parse_getrule(parser *p, tokentype type) {
function parse_setparsetable (line 1690) | bool parse_setparsetable(parser *p, parserule *rules) {
function parse_setbaseparsefn (line 1704) | void parse_setbaseparsefn(parser *p, parsefunction fn) {
function parse_setskipnewline (line 1709) | void parse_setskipnewline(parser *p, bool skip, tokentype toknewline) {
function parse_setmaxrecursiondepth (line 1716) | void parse_setmaxrecursiondepth(parser *p, int maxdepth) {
function parse_init (line 1730) | void parse_init(parser *p, lexer *lex, error *err, void *out) {
function parse_clear (line 1750) | void parse_clear(parser *p) {
function parse (line 1760) | bool parse(parser *p) {
function morpho_parse (line 1769) | bool morpho_parse(parser *p) {
function parse_stringtovaluearray (line 1789) | bool parse_stringtovaluearray(char *string, unsigned int nmax, value *v,...
function parse_value (line 1830) | bool parse_value(const char *in, value *out) {
function parse_initialize (line 1857) | void parse_initialize(void) {
FILE: src/support/parse.h
type parser (line 20) | typedef struct sparser parser;
type precedence (line 48) | typedef int precedence;
type parserule (line 56) | typedef struct {
type sparser (line 81) | struct sparser {
FILE: src/support/platform.c
function platform_randombytes (line 58) | bool platform_randombytes(char *buffer, size_t nbytes) {
function MorphoComplex (line 85) | MorphoComplex MCAdd(MorphoComplex a, MorphoComplex b) {
function MorphoComplex (line 89) | MorphoComplex MCSub(MorphoComplex a, MorphoComplex b) {
function MorphoComplex (line 93) | MorphoComplex MCDiv(MorphoComplex a, MorphoComplex b) {
function MCSame (line 97) | bool MCSame(MorphoComplex a, MorphoComplex b) {
function MCEq (line 103) | bool MCEq(MorphoComplex a, MorphoComplex b) {
function platform_isdirectory (line 115) | bool platform_isdirectory(const char *path) {
function platform_maxpathsize (line 129) | size_t platform_maxpathsize(void) {
function platform_setcurrentdirectory (line 138) | bool platform_setcurrentdirectory(const char *path) {
function platform_getcurrentdirectory (line 147) | bool platform_getcurrentdirectory(char *buffer, size_t size) {
function platform_gethomedirectory (line 156) | bool platform_gethomedirectory(char *buffer, size_t size) {
function platform_directorycontentsinit (line 173) | bool platform_directorycontentsinit(MorphoDirContents *contents, const c...
function platform_directorycontentsclear (line 195) | void platform_directorycontentsclear(MorphoDirContents *contents) {
function platform_directorycontents (line 204) | bool platform_directorycontents(MorphoDirContents *contents, char *buffe...
function MorphoDLHandle (line 237) | MorphoDLHandle platform_dlopen(const char *path) {
function platform_dlclose (line 246) | void platform_dlclose(MorphoDLHandle handle) {
function MorphoThread_create (line 270) | bool MorphoThread_create(MorphoThread *thread, MorphoThreadFn threadfn, ...
function MorphoThread_join (line 286) | void MorphoThread_join(MorphoThread thread) {
function MorphoThread_clear (line 295) | void MorphoThread_clear(MorphoThread thread) {
function MorphoThread_exit (line 302) | void MorphoThread_exit(void) {
function MorphoMutex_init (line 311) | bool MorphoMutex_init(MorphoMutex *mutex) {
function MorphoMutex_clear (line 321) | void MorphoMutex_clear(MorphoMutex *mutex) {
function MorphoMutex_lock (line 330) | void MorphoMutex_lock(MorphoMutex *mutex) {
function MorphoMutex_unlock (line 339) | void MorphoMutex_unlock(MorphoMutex *mutex) {
function MorphoCond_init (line 348) | bool MorphoCond_init(MorphoCond *cond) {
function MorphoCond_clear (line 358) | void MorphoCond_clear(MorphoCond *cond) {
function MorphoCond_signal (line 367) | void MorphoCond_signal(MorphoCond *cond) {
function MorphoCond_broadcast (line 376) | void MorphoCond_broadcast(MorphoCond *cond) {
function MorphoCond_wait (line 385) | void MorphoCond_wait(MorphoCond *cond, MorphoMutex *mutex) {
function platform_clock (line 398) | double platform_clock(void) {
function platform_sleep (line 415) | void platform_sleep(int msecs) {
FILE: src/support/platform.h
type _Dcomplex (line 50) | typedef _Dcomplex MorphoComplex;
type MorphoComplex (line 60) | typedef double complex MorphoComplex;
type MorphoDirContents (line 83) | typedef struct {
type HMODULE (line 102) | typedef HMODULE MorphoDLHandle;
type HANDLE (line 118) | typedef HANDLE MorphoThread;
type CRITICAL_SECTION (line 119) | typedef CRITICAL_SECTION MorphoMutex;
type CONDITION_VARIABLE (line 120) | typedef CONDITION_VARIABLE MorphoCond;
type DWORD (line 121) | typedef DWORD MorphoThreadFnReturnType;
type DWORD (line 122) | typedef DWORD (*MorphoThreadFn)(void *);
type pthread_t (line 124) | typedef pthread_t MorphoThread;
type pthread_mutex_t (line 125) | typedef pthread_mutex_t MorphoMutex;
type pthread_cond_t (line 126) | typedef pthread_cond_t MorphoCond;
FILE: src/support/random.c
function splitmix64_next (line 32) | static inline uint64_t splitmix64_next(void) {
function splitmix64_seed (line 40) | void splitmix64_seed(uint64_t seed) {
function xoshiro256pp_rotl (line 67) | static inline uint64_t xoshiro256pp_rotl(const uint64_t x, int k) {
function next (line 73) | static inline uint64_t next(void) {
function xoshiro256pp_jump (line 94) | void xoshiro256pp_jump(void) {
function xoshiro256pp_longjump (line 123) | void xoshiro256pp_longjump(void) {
function xoshiro256p_rotl (line 175) | static inline uint64_t xoshiro256p_rotl(const uint64_t x, int k) {
function xoshiro256p_next (line 182) | static inline uint64_t xoshiro256p_next(void) {
function xoshiro256p_jump (line 204) | void xoshiro256p_jump(void) {
function xoshiro256p_longjump (line 234) | void xoshiro256p_longjump(void) {
function random_double (line 263) | double random_double(void) {
function random_int (line 270) | unsigned int random_int(void) {
function random_initialize (line 277) | void random_initialize(void) {
FILE: src/support/resources.c
type resourceenumerator (line 21) | typedef struct {
function resources_matchbasefolder (line 66) | void resources_matchbasefolder(resourceenumerator *en, char *path) {
function resources_basefolders (line 85) | void resources_basefolders(resourceenumerator *en) {
function resources_matchfile (line 104) | bool resources_matchfile(resourceenumerator *en, char *file) {
function resources_searchfolder (line 131) | void resources_searchfolder(resourceenumerator *en, char *path) {
function resourceenumerator_init (line 168) | void resourceenumerator_init(resourceenumerator *en, char *folder, char ...
function resourceenumerator_clear (line 179) | void resourceenumerator_clear(resourceenumerator *en) {
function resourceenumerator_enumerate (line 187) | bool resourceenumerator_enumerate(resourceenumerator *en, value *out) {
function resourceenumerator_defaultfolder (line 203) | void resourceenumerator_defaultfolder(resourceenumerator *en, morphoreso...
function morpho_findresource (line 215) | bool morpho_findresource(morphoresourcetype type, char *fname, value *ou...
function morpho_listresources (line 231) | bool morpho_listresources(morphoresourcetype type, varray_value *out) {
function resources_loadpackagelist (line 247) | void resources_loadpackagelist(void) {
function resources_initialize (line 276) | void resources_initialize(void) {
function resources_finalize (line 284) | void resources_finalize(void) {
FILE: src/support/resources.h
type morphoresourcetype (line 18) | typedef enum {
FILE: src/support/threadpool.c
function morpho_setthreadnumber (line 18) | void morpho_setthreadnumber(int nthreads) {
function morpho_threadnumber (line 23) | int morpho_threadnumber(void) {
function MorphoThreadFnReturnType (line 30) | MorphoThreadFnReturnType threadpool_worker(void *ref) {
function threadpool_init (line 66) | bool threadpool_init(threadpool *pool, int nworkers) {
function threadpool_clear (line 90) | void threadpool_clear(threadpool *pool) {
function threadpool_add_task (line 109) | bool threadpool_add_task(threadpool *pool, workfn func, void *arg) {
function threadpool_fence (line 122) | void threadpool_fence(threadpool *pool) {
FILE: src/support/threadpool.h
type task (line 24) | typedef struct {
type threadpool (line 35) | typedef struct {
FILE: test/help.py
function morphoHelp (line 13) | def morphoHelp(query):
function checkResult (line 18) | def checkResult(result):
function morphoMethods (line 22) | def morphoMethods(clss):
FILE: test/test.py
function remove_control_characters (line 31) | def remove_control_characters(str):
function simplify_errors (line 35) | def simplify_errors(str):
function simplify_stacktrace (line 40) | def simplify_stacktrace(str):
function findvalue (line 44) | def findvalue(str):
function finderror (line 48) | def finderror(str):
function iserror (line 53) | def iserror(str):
function isin (line 59) | def isin(str):
function remove (line 65) | def remove(list, remove_list):
function findexpected (line 75) | def findexpected(str):
function getexpect (line 84) | def getexpect(filepath):
function getoutput (line 98) | def getoutput(filepath):
function test (line 117) | def test(file,testLog,CI):
FILE: test/valgrind.py
function checkvalgrindlog (line 22) | def checkvalgrindlog(filepath):
function test (line 32) | def test(file, CI):
Condensed preview — 1216 files, each showing path, character count, and a content snippet. Download the .json file or copy for the full structured content (2,685K chars).
[
{
"path": ".gitattributes",
"chars": 66,
"preview": "# Auto detect text files and perform LF normalization\n* text=auto\n"
},
{
"path": ".github/ISSUE_TEMPLATE/bug_report.md",
"chars": 557,
"preview": "---\nname: Bug report\nabout: Create a report to help us improve\ntitle: \"[Bug]\"\nlabels: bug, Needs Priority\nassignees: ''\n"
},
{
"path": ".github/workflows/build.yml",
"chars": 506,
"preview": "name: Build\n\non:\n push:\n branches: [ \"main\", \"dev\" ]\n pull_request:\n branches: [ \"main\", \"dev\" ]\n\njobs:\n build:"
},
{
"path": ".github/workflows/buildandtest.yml",
"chars": 927,
"preview": "name: Build and Test\n\non:\n push:\n branches: [ \"main\", \"dev\" ]\n pull_request:\n branches: [ \"main\", \"dev\" ]\n\njobs:"
},
{
"path": ".github/workflows/buildandtestmultithreaded.yml",
"chars": 933,
"preview": "name: TestMultiThreaded\n\non:\n push:\n branches: [ \"main\", \"dev\" ]\n pull_request:\n branches: [ \"main\", \"dev\" ]\n\njo"
},
{
"path": ".github/workflows/codeql.yml",
"chars": 4296,
"preview": "# For most projects, this workflow file will not need changing; you simply need\n# to commit it to your repository.\n#\n# Y"
},
{
"path": ".github/workflows/examples.yml",
"chars": 1472,
"preview": "name: Examples\n\non:\n push:\n branches: [ \"main\", \"dev\" ]\n pull_request:\n branches: [ \"main\", \"dev\" ]\n\njobs:\n bui"
},
{
"path": ".github/workflows/nonanboxing.yml",
"chars": 956,
"preview": "name: No NANBoxing\n\non:\n push:\n branches: [ \"main\", \"dev\" ]\n pull_request:\n branches: [ \"main\", \"dev\" ]\n\njobs:\n "
},
{
"path": ".gitignore",
"chars": 824,
"preview": "# Prerequisites\n*.d\n\n# Object files\n*.o\n*.ko\n*.obj\n*.elf\n\n# Linker output\n*.ilk\n*.map\n*.exp\n\n# Precompiled Headers\n*.gch"
},
{
"path": ".readthedocs.yml",
"chars": 510,
"preview": "# .readthedocs.yaml\n# Read the Docs configuration file\n# See https://docs.readthedocs.io/en/stable/config-file/v2.html f"
},
{
"path": "CMakeLists.txt",
"chars": 6972,
"preview": "#-------------------------------------------------------------------------------\n# Morpho/CMakeLists.txt\n#--------------"
},
{
"path": "CODE_OF_CONDUCT.md",
"chars": 5476,
"preview": "# Morpho Code of Conduct\n\n## Our Pledge\n\nWe as members, contributors, and leaders pledge to make participation in our\nco"
},
{
"path": "CONTRIBUTING.md",
"chars": 4502,
"preview": "# Contributing to Morpho\n\nThankyou for your interest in helping to improve Morpho! We welcome contributions from everyon"
},
{
"path": "LICENSE",
"chars": 1072,
"preview": "MIT License\n\nCopyright (c) 2020-21 T J Atherton\n\nPermission is hereby granted, free of charge, to any person obtaining a"
},
{
"path": "README.md",
"chars": 8410,
"preview": "![Mo"
},
{
"path": "examples/catenoid/catenoid.morpho",
"chars": 1344,
"preview": "// This script computes the shape of a soap film attached to two circular rings separated vertically.\n// The surface ten"
},
{
"path": "examples/cholesteric/cholesteric.morpho",
"chars": 1066,
"preview": "// Test cholesteric in a square boundary\nimport meshtools\nimport plot\nimport optimize\n\nvar L = 0.5\nvar dx = 0.1\n\nvar m ="
},
{
"path": "examples/cube/cube.morpho",
"chars": 1473,
"preview": "/* Minimize the area of a surface at constant enclosed volume. */\n\nimport graphics\nimport meshtools\nimport plot\nimport o"
},
{
"path": "examples/delaunay/delaunay.morpho",
"chars": 1520,
"preview": "// Demonstrate use of the Delaunay module\n\nimport plot\nimport delaunay\n\nvar N = 100 // Number of points \n\n// Explicitly "
},
{
"path": "examples/dla/dla.morpho",
"chars": 1313,
"preview": "// Diffusion Limited Aggregation\n\nimport kdtree\nimport color\nimport graphics\nimport povray\n\nvar Np = 100 // Number of pa"
},
{
"path": "examples/electrostatics/electrostatics.morpho",
"chars": 2058,
"preview": "// Solve Laplace's equation on a square domain by minimizing |grad V|^2\nimport meshtools\nimport plot\nimport optimize\n\nva"
},
{
"path": "examples/elementtypes/README.md",
"chars": 554,
"preview": "# Finite Element types\n\nThis folder contains some examples using finite elements beyond linear Lagrange elements (CG1). "
},
{
"path": "examples/elementtypes/electrostaticsCG2.morpho",
"chars": 1429,
"preview": "// Solve Laplace's equation on a square domain by minimizing |grad V|^2\n// Uses CG2 elements\n\nimport meshtools\nimport pl"
},
{
"path": "examples/elementtypes/qtensorCG2.morpho",
"chars": 6331,
"preview": "// Nematic liquid crystal with Q tensor on a disk\n// Solved using CG2 elements\n\nimport meshgen\nimport plot\nimport povray"
},
{
"path": "examples/examples.py",
"chars": 3796,
"preview": "#!/usr/bin/env python3\n# runexamples.py\n# runs all the example for morpho\n# reporting any errors found\n\nimport os, glob,"
},
{
"path": "examples/implicitmesh/ellipsoid.morpho",
"chars": 195,
"preview": "\nimport implicitmesh\nimport plot\n\n// Ellipsoid\nvar impl = ImplicitMeshBuilder(fn (x,y,z) x^2/3+y^2+z^2-1)\nvar mesh = imp"
},
{
"path": "examples/implicitmesh/threesurface.morpho",
"chars": 600,
"preview": "\nimport implicitmesh\nimport plot\n\n// 3-surface\nvar rx=6\nvar ry=3.5\nvar rz=4\nvar r1=1.2\nvar x1=3.9\n\nvar impl = ImplicitMe"
},
{
"path": "examples/implicitmesh/torus.morpho",
"chars": 281,
"preview": "\nimport implicitmesh\nimport plot\n\n// Torus\nvar r=1\nvar a=0.35\n\nvar impl = ImplicitMeshBuilder(fn (x,y,z) (x^2+y^2+z^2+r^"
},
{
"path": "examples/meshgen/disk.morpho",
"chars": 206,
"preview": "// Domain composed of a single disk\nimport meshgen\nimport plot\n\nvar dom = fn (x) -(x[0]^2+x[1]^2-1)\nvar mg = MeshGen(dom"
},
{
"path": "examples/meshgen/ellipse.morpho",
"chars": 184,
"preview": "// Ellipse domain\nimport meshgen\nimport plot\n\nvar e0 = Domain(fn (x) -((x[0]/2)^2+x[1]^2-1))\nvar mg = MeshGen(e0, [-2..2"
},
{
"path": "examples/meshgen/ellipsoidsection.morpho",
"chars": 436,
"preview": "// 3D Ellipsoidal shell intersecting with a plane\nimport meshgen\nimport plot\n\nvar dh = 0.2\nvar e0 = Domain(fn (x) -((x[0"
},
{
"path": "examples/meshgen/halfdisk.morpho",
"chars": 302,
"preview": "// Domain composed of disk with half space removed\nimport meshgen\nimport plot\n\nvar c = CircularDomain([0,0], 1)\nvar hs ="
},
{
"path": "examples/meshgen/overlappingdisks.morpho",
"chars": 406,
"preview": "// Domain composed of overlapping disks\nimport meshgen\nimport plot\n\n// Create a complicated domain by composing circular"
},
{
"path": "examples/meshgen/sphere.morpho",
"chars": 215,
"preview": "// Sphere\nimport meshgen\nimport plot\n\nvar dh = 0.2\nvar dom = Domain(fn (x) -(x[0]^2+x[1]^2+x[2]^2-1))\nvar mg = MeshGen(d"
},
{
"path": "examples/meshgen/square.morpho",
"chars": 243,
"preview": "// Square domain with a hole \nimport meshgen\nimport plot\n\nvar e0 = Domain(fn (x) ((x[0])^2+x[1]^2-1))\nvar mg = MeshGen(e"
},
{
"path": "examples/meshgen/superellipse.morpho",
"chars": 306,
"preview": "// Superellipse domain\nimport meshgen\nimport plot\n\n// Superellipse\nvar e1 = Domain(fn (x) -((x[0]^4+x[1]^4)^(1/4)-1))\nva"
},
{
"path": "examples/meshgen/superellipsoid.morpho",
"chars": 235,
"preview": "// 3D Superellipsoid\nimport meshgen\nimport plot\n\nvar dh = 0.2\n\nvar dom = Domain(fn (x) -((x[0]^4+x[1]^4+x[2]^4)^(1/4)-1)"
},
{
"path": "examples/meshgen/weighted.morpho",
"chars": 298,
"preview": "// Circular domain with weight function\nimport meshgen\nimport plot\n\n// Weighted element size\nvar hbar = fn (x) 1+x[0]/2 "
},
{
"path": "examples/meshslice/sphere.mesh",
"chars": 4904,
"preview": "vertices\n\n1 -0.954722 -0.294874 0.0394472\n2 -0.945697 0.223319 -0.23619\n3 -0.925278 0.166153 0.34096\n4 -0.833108 -0.2811"
},
{
"path": "examples/meshslice/testmeshslice.morpho",
"chars": 1538,
"preview": "// Example of using the meshslice module \n\nimport meshtools\nimport plot\nimport meshslice\n\n// We'll create a spherical ex"
},
{
"path": "examples/plot/plotfield.morpho",
"chars": 658,
"preview": "// Plot a selection \nimport plot\nimport implicitmesh\n\n/* Create a simple mesh for demonstration purposes */\nvar impl = I"
},
{
"path": "examples/plot/plotmeshlabels.morpho",
"chars": 851,
"preview": "// Plot mesh labels \nimport plot\nimport meshgen \n\n/* Create a lo-res spherical mesh for demonstration purposes */\nvar do"
},
{
"path": "examples/plot/plotselection.morpho",
"chars": 417,
"preview": "// Plot a selection \nimport plot\nimport meshtools\n\n/* Create a simple mesh for demonstration purposes */\nvar m = AreaMes"
},
{
"path": "examples/plot/scalebar.morpho",
"chars": 1045,
"preview": "// Demonstrates drawing a scalebar alongside the output of plotfield \n\nimport color\nimport plot\nimport meshgen \n\nvar m ="
},
{
"path": "examples/povray/testCamera.morpho",
"chars": 621,
"preview": "import meshtools\nimport implicitmesh\nimport plot\nimport povray \n\nvar c = Matrix([0.1,0.2,0.3])\nvar impl = ImplicitMeshBu"
},
{
"path": "examples/povray/testpovray.morpho",
"chars": 2112,
"preview": "// Demonstrate use of the povray module to raytrace graphics\nimport constants\nimport color\nimport plot\nimport povray\n\nva"
},
{
"path": "examples/povray/testpovraytext.morpho",
"chars": 348,
"preview": "import plot \nimport povray \nimport meshtools\nvar g = Graphics()\n\nvar m = AreaMesh(fn (u,v) [u,v,0], -1..1:0.5, -1..1:0.5"
},
{
"path": "examples/povray/testpovraytransmitfilter.morpho",
"chars": 2459,
"preview": "// Demonstrate use of the povray module to raytrace graphics.\n// Additionally, demonstrate the use of the transmit and f"
},
{
"path": "examples/povray/text.morpho",
"chars": 146,
"preview": "import plot \nimport povray \n\nvar g = Graphics()\n\ng.display(Text(\"Hello World\", [0,0,0]))\n\nvar pov = POVRaytracer(g)\n\npov"
},
{
"path": "examples/qtensor/dense_disk.mesh",
"chars": 6313,
"preview": "vertices\n\n1 -1 0 0 \n2 -0.951057 -0.309017 0 \n3 -0.951057 0.309017 0 \n4 -0.809017 -0.587785 0 \n5 -0.809017 0.587785 0 \n6 "
},
{
"path": "examples/qtensor/qtensor.morpho",
"chars": 8032,
"preview": "/* Problem of a 2D nematic confined to a disk with parallel anchoring boundary condition, modeled by a Q-tensor free ene"
},
{
"path": "examples/qtensor/src.lyx",
"chars": 16930,
"preview": "#LyX file created by tex2lyx 2.3\n\\lyxformat 544\n\\begin_document\n\\begin_header\n\\save_transient_properties true\n\\origin /U"
},
{
"path": "examples/qtensor/src.tex",
"chars": 8284,
"preview": "\\documentclass{article}\n\\usepackage[utf8]{inputenc}\n\\usepackage{physics}\n\\usepackage{xcolor}\n\\usepackage{graphicx}\n\\defi"
},
{
"path": "examples/tactoid/disk.mesh",
"chars": 1489,
"preview": "vertices\n\n1 -1. 0. 0\n2 -0.951057 -0.309017 0\n3 -0.951057 0.309017 0\n4 -0.809017 -0.587785 0\n5 -0.809017 0.587785 0\n6 -0."
},
{
"path": "examples/tactoid/tactoid.morpho",
"chars": 4216,
"preview": "import meshtools\nimport optimize\nimport plot\nimport povray\n\n// Create mesh and director field\nvar m = Mesh(\"disk.mesh\")\n"
},
{
"path": "examples/tactoid/tactoid2dmesh.morpho",
"chars": 4418,
"preview": "import meshtools\nimport optimize\nimport plot\nimport povray\nimport meshgen\n\n// Create mesh and director field\nvar dom = f"
},
{
"path": "examples/thomson/thomson.morpho",
"chars": 1797,
"preview": "// Thomson problem of arranging charges on a sphere\n// to minimize the electrostatic energy\n// Showcases: MeshBuilder, P"
},
{
"path": "examples/tutorial/disk.mesh",
"chars": 1489,
"preview": "vertices\n\n1 -1. 0. 0\n2 -0.951057 -0.309017 0\n3 -0.951057 0.309017 0\n4 -0.809017 -0.587785 0\n5 -0.809017 0.587785 0\n6 -0."
},
{
"path": "examples/tutorial/tutorial.morpho",
"chars": 1495,
"preview": "// Morpho tutorial example\nimport meshtools\nimport optimize\nimport plot\n\nvar m = Mesh(\"disk.mesh\")\n\n// Initial boundary "
},
{
"path": "examples/tutorial/tutorial2.morpho",
"chars": 1896,
"preview": "// Morpho tutorial example\nimport meshtools\nimport optimize\nimport plot\n\nvar m = Mesh(\"disk.mesh\")\n\n// Initial boundary "
},
{
"path": "examples/wrap/wrap.morpho",
"chars": 2460,
"preview": "/* Finds a minimal surface that connects two ellipsoids.\nThis models a fluid interface between two colloidal particles, "
},
{
"path": "help/Makefile",
"chars": 634,
"preview": "# Minimal makefile for Sphinx documentation\n#\n\n# You can set these variables from the command line, and also\n# from the "
},
{
"path": "help/array.md",
"chars": 637,
"preview": "[comment]: # (Array class help)\n[version]: # (0.5)\n\n# Array\n[tagarray]: # (Array)\n\nArrays are collection objects that ca"
},
{
"path": "help/builtin.md",
"chars": 6692,
"preview": "[comment]: # (Builtin function help)\n[version]: # (0.5)\n\n# Builtin functions\n[tagbuiltin]: # (builtin)\n\nMorpho provides "
},
{
"path": "help/classes.md",
"chars": 4716,
"preview": "[comment]: # (Morpho classes help file)\n[version]: # (0.5)\n\n[toplevel]: #\n\n# Classes\n[tagclass]: # (class)\n[tagmethod]: "
},
{
"path": "help/color.md",
"chars": 4124,
"preview": "[comment]: # (Color module help)\n[version]: # (0.5)\n\n# Color\n[tagcolor]: # (color)\n\nThe `color` module provides support "
},
{
"path": "help/complex.md",
"chars": 831,
"preview": "[comment]: # (Complex help)\n[version]: # (0.5)\n\n# Complex\n[tagcomplex]: # (complex)\n[tagim]: # (im)\n\nMorpho provides com"
},
{
"path": "help/conf.py",
"chars": 2135,
"preview": "# Configuration file for the Sphinx documentation builder.\n#\n# This file only contains a selection of the most common op"
},
{
"path": "help/constants.md",
"chars": 348,
"preview": "[comment]: # (Constants module help)\n[version]: # (0.5)\n\n# Constants\n[tagconstants]: # (constants)\n\nThe constants module"
},
{
"path": "help/controlflow.md",
"chars": 6174,
"preview": "[comment]: # (Morpho control flow help file)\n[version]: # (0.5)\n\n[toplevel]: #\n\n# Control Flow\n[tagcontrol]: # (control)"
},
{
"path": "help/delaunay.md",
"chars": 1476,
"preview": "[comment]: # (Delaunay module help)\n[version]: # (0.5)\n\n# Delaunay\n[tagdelaunay]: # (delaunay)\n\nThe `delaunay` module cr"
},
{
"path": "help/dictionary.md",
"chars": 1439,
"preview": "[comment]: # (Dictionary help)\n[version]: # (0.5)\n\n# Dictionary\n[tag]: # (Dictionary)\n\nDictionaries are collection objec"
},
{
"path": "help/errors.md",
"chars": 5434,
"preview": "[comment]: # (Errors help file)\n[version]: # (0.5)\n\n# Errors\n[tagerror]: # (error)\n[tagerrors]: # (errors)\n[tagerrors]: "
},
{
"path": "help/field.md",
"chars": 2554,
"preview": "[comment]: # (Field class help)\n[version]: # (0.5)\n\n# Field\n[tagfield]: # (Field)\n\nFields are used to store information,"
},
{
"path": "help/file.md",
"chars": 2232,
"preview": "[comment]: # (File class help)\n[version]: # (0.5)\n\n# File\n[tagfile]: # (File)\n\nThe `File` class provides the capability "
},
{
"path": "help/functionals.md",
"chars": 12081,
"preview": "[comment]: # (Functionals help)\n[version]: # (0.5)\n\n# Functionals\n[tagfunctionals]: # (functionals)\n\nA number of `functi"
},
{
"path": "help/functions.md",
"chars": 4789,
"preview": "[comment]: # (Morpho functions help file)\n[version]: # (0.5)\n\n[toplevel]: #\n\n# Functions\n[tagfn]: # (fn)\n[tagfun]: # (fu"
},
{
"path": "help/graphics.md",
"chars": 7227,
"preview": "[comment]: # (Graphics module help)\n[version]: # (0.5)\n\n# Graphics\n[taggraphics]: # (graphics)\n\nThe `graphics` module pr"
},
{
"path": "help/help.md",
"chars": 956,
"preview": "[comment]: # (Morpho language help file)\n[version]: # (0.5)\n\n# Help\n[tag]: # (help)\n\nMorpho provides an online help syst"
},
{
"path": "help/implicitmesh.md",
"chars": 980,
"preview": "[comment]: # (Implicitmesh module help)\n[version]: # (0.5)\n\n# ImplicitMesh\n[tagimplicitmesh]: # (implicitmesh)\n\nThe `imp"
},
{
"path": "help/index.rst",
"chars": 767,
"preview": "Morpho\n======\n\n.. toctree::\n :caption: Language\n :maxdepth: 1\n\n syntax\n values\n variables\n controlflow\n fu"
},
{
"path": "help/json.md",
"chars": 740,
"preview": "[comment]: # (Morpho json help file)\n[version]: # (0.5)\n\n[toplevel]: #\n\n# JSON\n[tagjson]: # (json)\n\nThe `JSON` class pro"
},
{
"path": "help/kdtree.md",
"chars": 2173,
"preview": "[comment]: # (KDTree module help)\n[version]: # (0.5)\n\n# KDTree\n[tagkdtree]: # (kdtree)\n\nThe `kdtree` module implements a"
},
{
"path": "help/list.md",
"chars": 2700,
"preview": "[comment]: # (List class help)\n[version]: # (0.5)\n\n# List\n[taglist]: # (List)\n\nLists are collection objects that contain"
},
{
"path": "help/make.bat",
"chars": 760,
"preview": "@ECHO OFF\n\npushd %~dp0\n\nREM Command file for Sphinx documentation\n\nif \"%SPHINXBUILD%\" == \"\" (\n\tset SPHINXBUILD=sphinx-bu"
},
{
"path": "help/matrix.md",
"chars": 4186,
"preview": "[comment]: # (Matrix class help)\n[version]: # (0.5)\n\n# Matrix\n[tagmatrix]: # (Matrix)\n\nThe Matrix class provides support"
},
{
"path": "help/mesh.md",
"chars": 1831,
"preview": "[comment]: # (Mesh class help)\n[version]: # (0.5)\n\n# Mesh\n[tagmesh]: # (Mesh)\n\nThe `Mesh` class provides support for mes"
},
{
"path": "help/meshgen.md",
"chars": 4387,
"preview": "[comment]: # (Meshgen module help)\n[version]: # (0.5)\n\n# Meshgen\n[tagmeshgen]: # (meshgen)\n\nThe `meshgen` module is used"
},
{
"path": "help/meshslice.md",
"chars": 1669,
"preview": "[comment]: # (Meshslice module help)\n[version]: # (0.5)\n\n# Meshslice\n[tagmeshslice]: # (meshslice)\n\nThe `meshslice` modu"
},
{
"path": "help/meshtools.md",
"chars": 7705,
"preview": "[comment]: # (Morpho meshtools help file)\n[version]: # (0.5)\n\n# Meshtools\n[tagmeshtools]: # (meshtools)\n\nThe Meshtools p"
},
{
"path": "help/modules.md",
"chars": 2356,
"preview": "[comment]: # (Morpho modules help file)\n[version]: # (0.5)\n\n[toplevel]: #\n\n# Modules\n[tagmodules]: # (modules)\n\nMorpho i"
},
{
"path": "help/optimize.md",
"chars": 2615,
"preview": "[comment]: # (Morpho optimize help file)\n[version]: # (0.5)\n\n# Optimize\n[tagoptimize]: # (optimize)\n\nThe `optimize` pack"
},
{
"path": "help/plot.md",
"chars": 3644,
"preview": "[comment]: # (Plot module help)\n[version]: # (0.5.4)\n\n# Plot\n[tagplot]: # (plot)\n\nThe `plot` module provides visualizati"
},
{
"path": "help/povray.md",
"chars": 2952,
"preview": "[comment]: # (Povray module help)\n[version]: # (0.5)\n\n# POVRay\n[tagpovray]: # (povray)\n\nThe `povray` module provides int"
},
{
"path": "help/range.md",
"chars": 869,
"preview": "[comment]: # (Morpho range help file)\n[version]: # (0.5)\n\n# Range\n[tagrange]: # (range)\n\nRanges represent a sequence of "
},
{
"path": "help/requirements.txt",
"chars": 176,
"preview": "# File: docs/requirements.txt\n\n# Defining the exact version will make sure things don't break\nsphinx>=5.0.0\nsphinx_rtd_t"
},
{
"path": "help/selection.md",
"chars": 2040,
"preview": "[comment]: # (Morpho selection class help file)\n[version]: # (0.5)\n\n# Selection\n[tagselection]: # (selection)\n\nThe Selec"
},
{
"path": "help/sparse.md",
"chars": 578,
"preview": "[comment]: # (Sparse class help)\n[version]: # (0.5)\n\n# Sparse\n[tagsparse]: # (Sparse)\n\nThe Sparse class provides support"
},
{
"path": "help/string.md",
"chars": 1144,
"preview": "[comment]: # (String class help)\n[version]: # (0.5)\n\n# String\n[tagstring]: # (String)\n\nStrings represent textual informa"
},
{
"path": "help/syntax.md",
"chars": 4107,
"preview": "[comment]: # (Morpho syntax help file)\n[version]: # (0.5)\n\n[toplevel]: #\n\n# Syntax\n[tagsyntax]: # (syntax)\n\nMorpho provi"
},
{
"path": "help/system.md",
"chars": 1627,
"preview": "[comment]: # (System help)\n[version]: # (0.5)\n\n# System\n[tagsystem]: # (system)\n\nThe `System` class provides information"
},
{
"path": "help/tuple.md",
"chars": 786,
"preview": "[comment]: # (Tuple class help)\n[version]: # (0.6.0)\n\n# Tuple\n[tagtuple]: # (Tuple)\n\nTuples are collection objects that "
},
{
"path": "help/values.md",
"chars": 1572,
"preview": "[comment]: # (Values help)\n[version]: # (0.5)\n\n# Values\n[tagvalues]: # (values)\n\nValues are the basic unit of informatio"
},
{
"path": "help/variables.md",
"chars": 1659,
"preview": "[comment]: # (Morpho variables help file)\n[version]: # (0.5)\n\n[toplevel]: #\n\n# Variables\n[tagvariables]: # (variables)\n["
},
{
"path": "help/vtk.md",
"chars": 2960,
"preview": "[comment]: # (Morpho vtk module help file)\n[version]: # (0.5)\n\n# VTK\n[tagvtk]: # (vtk)\n\nThe vtk module contains classes "
},
{
"path": "modules/color.morpho",
"chars": 5220,
"preview": "/* Color module */\n\nimport constants\n\nclass Color {\n init(r,g,b) {\n self.r = r\n self.g = g\n self.b = b\n }\n r"
},
{
"path": "modules/constants.morpho",
"chars": 131,
"preview": "/*\n * Constants\n * Various mathematical and Physical constants\n */\n\nvar Pi = 3.14159265358979323846\nvar E = exp(1)\n\nvar "
},
{
"path": "modules/delaunay.morpho",
"chars": 5478,
"preview": "/* Delaunay - Generates Delaunay simplices of a point set\n * Using a sweepline algorithm */\n\n// Compute the Circumsphere"
},
{
"path": "modules/functionals.morpho",
"chars": 3150,
"preview": "/* ***************************************************************\n * Functionals\n * ===========\n * This module provides"
},
{
"path": "modules/graphics.morpho",
"chars": 22001,
"preview": "/* Graphics */\n\nimport constants\nimport meshtools\nimport color\n\nvar _eps = 1e-15\nvar _fntntfnd = Error(\"FntNtFnd\", \"Font"
},
{
"path": "modules/histogram.morpho",
"chars": 743,
"preview": "/*\n * Histogram\n * Simple command line histograms.\n */\n\n// Find the minimum of an enumerable object\nfn hmin(x) {\n var m"
},
{
"path": "modules/implicitmesh.morpho",
"chars": 8601,
"preview": "/* Create meshes that are level sets of an implicit function\n Marching method for implicit surfaces\n E. Hartmann, The "
},
{
"path": "modules/kdtree.morpho",
"chars": 5124,
"preview": "/* ***************************************************************\n * KDTree\n * ======\n * This module implements the KDT"
},
{
"path": "modules/meshgen.morpho",
"chars": 11768,
"preview": "/* Meshgen - a simple morpho mesh generator\n *\n * Inspired by the distmesh algorithm presented in:\n * A Simple Mesh Ge"
},
{
"path": "modules/meshslice.morpho",
"chars": 6818,
"preview": "/* Meshslice - Slices a Mesh along a plane */\n\nimport meshtools\nimport delaunay\n\nvar _errSlcEmpty = Error(\"SlcEmpty\", \"N"
},
{
"path": "modules/meshtools.morpho",
"chars": 33702,
"preview": "/* *********************************************************\n * Meshtools \n * A module that provides various mesh creati"
},
{
"path": "modules/optimize.morpho",
"chars": 21103,
"preview": "/* ************************************\n * Optimization\n ************************************** */\n\n// Minimize a 1-d fu"
},
{
"path": "modules/parser.morpho",
"chars": 1149,
"preview": "// Basic tokenizer\n\nclass StringStream {\n init(str) {\n self.str = str\n self.len = str.count() \n self.n = 0\n }"
},
{
"path": "modules/plot.morpho",
"chars": 15287,
"preview": "/* Plotting and visualization */\n\nimport graphics\nimport color\nimport meshtools\n\nvar _pltmshcolerr = Error(\"PltMshCl\", \""
},
{
"path": "modules/povray.morpho",
"chars": 7185,
"preview": "\nimport graphics \n\nclass Camera {\n init(antialias = true, width = 2048, height = 1536, viewangle = 24, viewpoint = ni"
},
{
"path": "modules/shapeopt.morpho",
"chars": 13687,
"preview": "/* ************************************\n * Shape optimization\n ************************************** */\n\n// Minimize a "
},
{
"path": "modules/symmetry.morpho",
"chars": 296,
"preview": "// Symmetries\n\n/** Translations by a constant vector */\nclass Translate {\n init (vec) { // Store the translation vector"
},
{
"path": "modules/vtk.morpho",
"chars": 16622,
"preview": "/* The VTK Module for Morpho (https://github.com/Morpho-lang/morpho) \n\nThis module provides support for I/O of Meshes an"
},
{
"path": "releasenotes/version-0.5.1.md",
"chars": 378,
"preview": "# Release notes for 0.5.1\n\nWe're pleased to announce morpho 0.5.1, which contains: \n\n* Improvements to error handling:\n "
},
{
"path": "releasenotes/version-0.5.2.md",
"chars": 535,
"preview": "# Release notes for 0.5.2\n\nWe're pleased to announce morpho 0.5.2, which contains: \n\n* New `meshgen` module to create me"
},
{
"path": "releasenotes/version-0.5.3.md",
"chars": 294,
"preview": "# Release notes for 0.5.3\n\nWe're pleased to announce morpho 0.5.3, which contains: \n\n* Support for complex numbers via a"
},
{
"path": "releasenotes/version-0.5.4.md",
"chars": 1933,
"preview": "# Release notes for 0.5.4\n\nWe're pleased to announce morpho 0.5.4, which contains many improvements. This is a large upd"
},
{
"path": "releasenotes/version-0.5.5.md",
"chars": 2193,
"preview": "# Release notes for 0.5.5\n\nWe're pleased to announce morpho 0.5.5, which contains a number of important improvements, an"
},
{
"path": "releasenotes/version-0.5.6.md",
"chars": 1804,
"preview": "# Release notes for 0.5.6\n\nWe're pleased to announce morpho 0.5.6, which contains a number of improvements, particularly"
},
{
"path": "releasenotes/version-0.5.7.md",
"chars": 1356,
"preview": "# Release notes for 0.5.7\n\nWe're pleased to announce morpho 0.5.7, which is the final release in the 0.5 series. This re"
},
{
"path": "releasenotes/version-0.6.0.md",
"chars": 2916,
"preview": "# Release notes for 0.6.0\n\nWe're pleased to announce Morpho 0.6.0, which represents a great deal of behind-the-scenes wo"
},
{
"path": "releasenotes/version-0.6.1.md",
"chars": 1690,
"preview": "# Release notes for 0.6.1\n\nWe're pleased to announce Morpho 0.6.1, which incorporates very important new language featur"
},
{
"path": "releasenotes/version-0.6.2.md",
"chars": 1479,
"preview": "# Release notes for 0.6.2\n\nWe're pleased to announce Morpho 0.6.2, which is primarily a maintenance release and incorpor"
},
{
"path": "releasenotes/version-0.6.3.md",
"chars": 1636,
"preview": "# Release notes for 0.6.3\n\nWe're pleased to announce Morpho 0.6.3, which contains a number of improvements and represent"
},
{
"path": "src/CMakeLists.txt",
"chars": 391,
"preview": "target_sources(morpho\n PRIVATE\n morpho.h build.h\n)\n\ntarget_sources(morpho\n INTERFACE\n FILE_SET public_he"
},
{
"path": "src/build.h",
"chars": 6322,
"preview": "/** @file build.h\n * @author T J Atherton\n *\n * @brief Define constants that choose how Morpho is built\n */\n\n#include "
},
{
"path": "src/builtin/CMakeLists.txt",
"chars": 241,
"preview": "target_sources(morpho\n PRIVATE\n builtin.c builtin.h \n functiondefs.c functiondefs.h\n)\n\ntarge"
},
{
"path": "src/builtin/builtin.c",
"chars": 15334,
"preview": "/** @file builtin.c\n * @author T J Atherton\n *\n * @brief Morpho built in functions and classes\n*/\n\n#include \"builtin.h"
},
{
"path": "src/builtin/builtin.h",
"chars": 5753,
"preview": "/** @file builtin.h\n * @author T J Atherton\n *\n * @brief Morpho built in functions and classes\n*/\n\n#ifndef builtin_h\n#"
},
{
"path": "src/builtin/functiondefs.c",
"chars": 21548,
"preview": "/** @file functiondefs.c\n * @author T J Atherton\n *\n * @brief Built in function definitions\n */\n\n#include <time.h>\n#in"
},
{
"path": "src/builtin/functiondefs.h",
"chars": 2535,
"preview": "/** @file functiondefs.h\n * @author T J Atherton\n *\n * @brief Built in function definitions\n */\n\n#ifndef functiondefs_"
},
{
"path": "src/classes/CMakeLists.txt",
"chars": 1139,
"preview": "target_sources(morpho\n PRIVATE\n classes.h\n array.c array.h\n bool.c bool.h \n "
},
{
"path": "src/classes/array.c",
"chars": 23987,
"preview": "/** @file array.c\n * @author T J Atherton\n *\n * @brief Defines array object type and Array class\n */\n\n#include \"morpho"
},
{
"path": "src/classes/array.h",
"chars": 3858,
"preview": "/** @file array.h\n * @author T J Atherton\n *\n * @brief Defines array object type and Array class\n */\n\n#ifndef array_h\n"
},
{
"path": "src/classes/bool.c",
"chars": 1038,
"preview": "/** @file bool.c\n * @author T J Atherton\n *\n * @brief Veneer class for bool values\n */\n\n#include \"morpho.h\"\n#include \""
},
{
"path": "src/classes/bool.h",
"chars": 616,
"preview": "/** @file bool.h\n * @author T J Atherton\n *\n * @brief Veneer class for bool values\n */\n\n#ifndef bool_h\n#define bool_h\n"
},
{
"path": "src/classes/classes.h",
"chars": 617,
"preview": "/** @file classes.h\n * @author T J Atherton\n *\n * @brief List of classes and object types\n */\n\n#ifndef classes_h\n#defi"
},
{
"path": "src/classes/closure.c",
"chars": 4006,
"preview": "/** @file closure.c\n * @author T J Atherton\n *\n * @brief Defines closure object type and Closure class\n */\n\n#include \""
},
{
"path": "src/classes/closure.h",
"chars": 1478,
"preview": "/** @file closure.h\n * @author T J Atherton\n *\n * @brief Defines closure object type and Closure class\n */\n\n#ifndef cl"
},
{
"path": "src/classes/clss.c",
"chars": 7010,
"preview": "/** @file clss.c\n * @author T J Atherton\n *\n * @brief Defines class object type\n */\n\n#include \"morpho.h\"\n#include \"cla"
},
{
"path": "src/classes/clss.h",
"chars": 1883,
"preview": "/** @file clss.h\n * @author T J Atherton\n *\n * @brief Defines class object type\n */\n\n#ifndef clss_h\n#define clss_h\n\n#i"
},
{
"path": "src/classes/cmplx.c",
"chars": 22110,
"preview": "/** @file complex.c\n * @author D Hellstein and T J Atherton\n *\n * @brief Complex number type\n */\n\n#include <string.h>\n"
},
{
"path": "src/classes/cmplx.h",
"chars": 4985,
"preview": "/** @file cmplx.h\n * @author D Hellstein and T J Atherton\n *\n * @brief Veneer class over the objectcomplex type\n */\n\n#"
},
{
"path": "src/classes/dict.c",
"chars": 10143,
"preview": "/** @file dict.c\n * @author T J Atherton\n *\n * @brief Defines dictionary object type and Dictionary veneer class\n */\n\n"
},
{
"path": "src/classes/dict.h",
"chars": 2009,
"preview": "/** @file dict.h\n * @author T J Atherton\n *\n * @brief Defines dictionary object type and Dictionary veneer class\n */\n\n"
},
{
"path": "src/classes/err.c",
"chars": 3912,
"preview": "/** @file err.c\n * @author T J Atherton\n *\n * @brief Implements the Error class\n */\n\n#include \"morpho.h\"\n#include \"cla"
},
{
"path": "src/classes/err.h",
"chars": 915,
"preview": "/** @file err.h\n * @author T J Atherton\n *\n * @brief Defines Error veneer class\n */\n\n#ifndef err_h\n#define err_h\n\n#inc"
},
{
"path": "src/classes/file.c",
"chars": 14872,
"preview": "/** @file file.c\n * @author T J Atherton\n *\n * @brief Defines file object type as well as File and Folder classes\n */\n"
},
{
"path": "src/classes/file.h",
"chars": 3272,
"preview": "/** @file file.h\n * @author T J Atherton\n *\n * @brief Defines file object type as well as File and Folder classes\n */\n"
},
{
"path": "src/classes/flt.c",
"chars": 1997,
"preview": "/** @file flt.c\n * @author T J Atherton\n *\n * @brief Veneer class for float values\n */\n\n#include \"morpho.h\"\n#include \""
},
{
"path": "src/classes/flt.h",
"chars": 984,
"preview": "/** @file flt.h\n * @author T J Atherton\n *\n * @brief Veneer class for float values\n */\n\n#ifndef float_h\n#define float_"
},
{
"path": "src/classes/function.c",
"chars": 6891,
"preview": "/** @file function.c\n * @author T J Atherton\n *\n * @brief Implement objectfunctions and the Function veneer class\n */\n"
},
{
"path": "src/classes/function.h",
"chars": 2925,
"preview": "/** @file function.h\n * @author T J Atherton\n *\n * @brief Defines function object type and Function veneer class\n */\n\n"
},
{
"path": "src/classes/instance.c",
"chars": 12701,
"preview": "/** @file instance.c\n * @author T J Atherton\n *\n * @brief Implements objectinstance and the Object base class\n */\n\n#in"
},
{
"path": "src/classes/instance.h",
"chars": 3115,
"preview": "/** @file instance.h\n * @author T J Atherton\n *\n * @brief Defines instance object type and Object base class\n */\n\n#ifn"
},
{
"path": "src/classes/int.c",
"chars": 1284,
"preview": "/** @file int.c\n * @author T J Atherton\n *\n * @brief Veneer class for float values\n */\n\n#include \"morpho.h\"\n#include \""
},
{
"path": "src/classes/int.h",
"chars": 610,
"preview": "/** @file int.h\n * @author T J Atherton\n *\n * @brief Veneer class for integer values\n */\n\n#ifndef int_h\n#define int_h\n"
},
{
"path": "src/classes/invocation.c",
"chars": 5228,
"preview": "/** @file invocation.c\n * @author T J Atherton\n *\n * @brief Implements the Invocation class\n */\n\n#include \"morpho.h\"\n#"
},
{
"path": "src/classes/invocation.h",
"chars": 1963,
"preview": "/** @file invocation.h\n * @author T J Atherton\n *\n * @brief Defines invocation object type and Invocation class\n */\n\n/"
},
{
"path": "src/classes/json.c",
"chars": 20398,
"preview": "/** @file json.c\n * @author T J Atherton\n *\n * @brief JSON class\n * @details Aims to be compliant with RFC 8259, test"
},
{
"path": "src/classes/json.h",
"chars": 1510,
"preview": "/** @file json.h\n * @author T J Atherton\n *\n * @brief JSON parser\n */\n\n#ifndef json_h\n#define json_h\n\n#include \"object"
},
{
"path": "src/classes/list.c",
"chars": 23415,
"preview": "/** @file list.c\n * @author T J Atherton\n *\n * @brief Implements the List class\n */\n\n#include \"morpho.h\"\n#include \"cla"
},
{
"path": "src/classes/list.h",
"chars": 2902,
"preview": "/** @file list.h\n * @author T J Atherton\n *\n * @brief Defines list object type and List class\n */\n\n#ifndef list_h\n#def"
},
{
"path": "src/classes/metafunction.c",
"chars": 33557,
"preview": "/** @file metafunction.c\n * @author T J Atherton\n *\n * @brief Implement objectmetafunctions and the Metafunction venee"
},
{
"path": "src/classes/metafunction.h",
"chars": 2846,
"preview": "/** @file metafunction.h\n * @author T J Atherton\n *\n * @brief Defines metafunction object type and Metafunction veneer"
},
{
"path": "src/classes/range.c",
"chars": 8768,
"preview": "/** @file range.c\n * @author T J Atherton\n *\n * @brief Implements the Range class\n */\n\n#include <float.h>\n#include <li"
},
{
"path": "src/classes/range.h",
"chars": 1828,
"preview": "/** @file range.h\n * @author T J Atherton\n *\n * @brief Defines range object type and Range class\n */\n\n#ifndef range_h\n"
},
{
"path": "src/classes/strng.c",
"chars": 10795,
"preview": "/** @file strng.c\n * @author T J Atherton\n *\n * @brief Defines string object type and String class\n */\n\n#include <stdi"
},
{
"path": "src/classes/strng.h",
"chars": 2832,
"preview": "/** @file strng.h\n * @author T J Atherton\n *\n * @brief Defines string object type and String class\n */\n\n#ifndef strng_"
},
{
"path": "src/classes/system.c",
"chars": 6422,
"preview": "/** @file system.c\n * @author T J Atherton\n *\n * @brief Defines System class to provide access to the runtime and syst"
},
{
"path": "src/classes/system.h",
"chars": 1521,
"preview": "/** @file system.h\n * @author T J Atherton\n *\n * @brief Defines System class to provide access to the runtime and syst"
},
{
"path": "src/classes/tuple.c",
"chars": 10358,
"preview": "/** @file tuple.c\n * @author T J Atherton\n *\n * @brief Defines tuple object type and Tuple class\n */\n\n#include \"morpho"
},
{
"path": "src/classes/tuple.h",
"chars": 2237,
"preview": "/** @file tuple.h\n * @author T J Atherton\n *\n * @brief Defines tuple object type and Tuple class\n */\n\n#ifndef tuple_h\n"
},
{
"path": "src/classes/upvalue.c",
"chars": 1946,
"preview": "/** @file upvalue.c\n * @author T J Atherton\n *\n * @brief Implements upvalue object type\n */\n\n#include \"morpho.h\"\n#incl"
},
{
"path": "src/classes/upvalue.h",
"chars": 1851,
"preview": "/** @file upvalue.h\n * @author T J Atherton\n *\n * @brief Defines upvalue object type\n */\n\n#ifndef upvalue_h\n#define up"
},
{
"path": "src/core/CMakeLists.txt",
"chars": 342,
"preview": "target_sources(morpho\n PRIVATE\n compile.c compile.h\n gc.c gc.h\n vm.c vm.h\n "
},
{
"path": "src/core/compile.c",
"chars": 173778,
"preview": "/** @file compile.c\n * @author T J Atherton\n *\n * @brief Compiles raw input to Morpho instructions\n */\n\n#include <stda"
},
{
"path": "src/core/compile.h",
"chars": 12486,
"preview": "/** @file compile.h\n * @author T J Atherton\n *\n * @brief Compiles raw input to Morpho instructions\n*/\n\n#ifndef compile"
},
{
"path": "src/core/core.h",
"chars": 8048,
"preview": "/** @file core.h\n * @author T J Atherton\n *\n * @brief Data types for core Morpho components\n*/\n\n#ifndef core_h\n#define"
},
{
"path": "src/core/gc.c",
"chars": 7937,
"preview": "/** @file gc.c\n * @author T J Atherton\n *\n * @brief Morpho garbage collector\n */\n\n#include \"vm.h\"\n#include \"gc.h\"\n\next"
},
{
"path": "src/core/gc.h",
"chars": 511,
"preview": "/** @file gc.h\n * @author T J Atherton\n *\n * @brief Morpho garbage collector\n */\n\n#ifndef gc_h\n#define gc_h\n\n/* ******"
},
{
"path": "src/core/opcodes.h",
"chars": 1674,
"preview": "/** @file opcodes.h\n * @author T J Atherton\n *\n * @brief Morpho opcodes\n */\n\n#ifdef OPCODE\n\n/** No operation */\nOPCODE"
},
{
"path": "src/core/vm.c",
"chars": 80414,
"preview": "/** @file vm.c\n * @author T J Atherton\n *\n * @brief Morpho virtual machine\n */\n\n#include <stdarg.h>\n#include <time.h>\n"
},
{
"path": "src/core/vm.h",
"chars": 546,
"preview": "/** @file vm.h\n * @author T J Atherton\n *\n * @brief The Morpho virtual machine\n */\n\n#ifndef vm_h\n#define vm_h\n\n#define"
},
{
"path": "src/datastructures/CMakeLists.txt",
"chars": 710,
"preview": "target_sources(morpho\n PRIVATE\n dictionary.c dictionary.h\n debugannotation.c debugannotation.h"
},
{
"path": "src/datastructures/debugannotation.c",
"chars": 6200,
"preview": "/** @file debugannotation.c\n* @author T J Atherton\n*\n* @brief Debugging annotations for programs\n*/\n\n#include \"debugan"
},
{
"path": "src/datastructures/debugannotation.h",
"chars": 2765,
"preview": "/** @file debugannotation.h\n * @author T J Atherton\n *\n * @brief Debugging annotations for programs\n*/\n\n#ifndef debuga"
},
{
"path": "src/datastructures/dictionary.c",
"chars": 17787,
"preview": "/** @file dictionary.h\n * @author T J Atherton\n *\n * @brief Dictionary (hashtable) data structure\n */\n\n#include <stdio"
},
{
"path": "src/datastructures/dictionary.h",
"chars": 2464,
"preview": "/** @file dictionary.h\n * @author T J Atherton\n *\n * @brief Dictionary (hashtable) data structure\n */\n\n#ifndef diction"
},
{
"path": "src/datastructures/error.c",
"chars": 6943,
"preview": "/** @file error.c\n* @author T J Atherton\n*\n* @brief Morpho error data structure and handling\n*/\n\n#include <stdio.h>\n#i"
}
]
// ... and 1016 more files (download for full content)
About this extraction
This page contains the full source code of the Morpho-lang/morpho GitHub repository, extracted and formatted as plain text for AI agents and large language models (LLMs). The extraction includes 1216 files (2.4 MB), approximately 686.7k tokens, and a symbol index with 1851 extracted functions, classes, methods, constants, and types. Use this with OpenClaw, Claude, ChatGPT, Cursor, Windsurf, or any other AI tool that accepts text input. You can copy the full output to your clipboard or download it as a .txt file.
Extracted by GitExtract — free GitHub repo to text converter for AI. Built by Nikandr Surkov.