diff --git a/R/ogs6.R b/R/ogs6.R
index c053455f3be05662efc00e3d5c67f012161a0907..e89f978d0bbf2d428062343daa241675c67455b7 100644
--- a/R/ogs6.R
+++ b/R/ogs6.R
@@ -124,6 +124,39 @@ OGS6 <- R6::R6Class("OGS6",
       invisible(self)
     },
 
+    #' @description
+    #' Update a component of the \code{OGS6} object.
+    #' @param cmpts list(sublist, length(sublist) == 2): The first element
+    #' of a sublist is a character that calls an \code{OGS6} component, the
+    #' second one is the corresponding value.
+    #' @examples
+    #' \dontrun{ogs6_obj$update_component(list(
+    #'                    list("ogs6_obj$parameters[[1]]$value", 2.3),
+    #'                    list("ogs6_obj$media[[1]]$properties[[2]]$value",
+    #'                         1.0e-3)))}
+    update_component = function(cmpts){#cmpts=list(list(call_str, value))
+        assertthat::assert_that(is.list(cmpts))
+
+        for (i in seq_along(cmpts)){
+            # check sublists
+            assertthat::assert_that(is.list(cmpts[[i]]))
+            assertthat::assert_that(length(cmpts[[i]])==2)
+            assertthat::assert_that(is.character(cmpts[[i]][[1]]))
+
+            # update component via call
+            call_str <- cmpts[[i]][[1]]
+            value <- cmpts[[i]][[2]]
+            call_str <- gsub("^[A-Za-z_0-9]*\\$", "self$", call_str)
+            assertthat::assert_that(!is.null(eval(parse(text = call_str))),
+                                    msg = paste(call_str,
+                                                "not found in ogs6_obj",
+                                                self$sim_name))
+            set_call <- paste0(call_str, " <- ", value)
+            eval(parse(text = set_call))
+        }
+        invisible(self)
+    },
+
 
     #===== Utility =====
 
diff --git a/tests/testthat/test-cal_utils.R b/tests/testthat/test-cal_utils.R
new file mode 100644
index 0000000000000000000000000000000000000000..4294c0fc98b6f270415c234ae7d3cef5e020526d
--- /dev/null
+++ b/tests/testthat/test-cal_utils.R
@@ -0,0 +1,31 @@
+
+ogs6_obj <- OGS6$new(sim_name = "theis", tmp_dir)
+
+prj_path <- system.file("extdata/benchmarks/AxiSymTheis",
+                        "axisym_theis.prj", package = "r2ogs6")
+
+read_in_prj(ogs6_obj, prj_path)
+
+test_that("Only existing components can be changed", {
+    expect_error(ogs6_obj$update_component(
+        list(list("ogs6_obj$media[[1]]$materials", 0.003))
+        ))
+    expect_error(ogs6_obj$update_component(
+        list(list("ogs6_obj$media[[1]$properties", 0.003))
+    ))
+})
+
+test_that("Only accepts parameters in right format", {
+    expect_error(ogs6_obj$update_component(
+        list("ogs6_obj$media[[1]]$properties", 0.003)
+    ))
+    expect_error(ogs6_obj$update_component(
+        list(c("ogs6_obj$media[[1]]$properties", 0.003),
+        c("ogs6_obj$media[[1]]$phases[[1]]$properties[[1]]$value", 0.03))
+    ))
+
+    expect_silent(ogs6_obj$update_component(
+        list(list("ogs6_obj$media[[1]]$properties", 0.003),
+             list("ogs6_obj$media[[1]]$phases[[1]]$properties[[1]]$value", 0.03))
+    ))
+})